Freeciv-3.2
Loading...
Searching...
No Matches
gui_main.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#ifdef AUDIO_SDL2
19/* Though it would happily compile without this include,
20 * it is needed for sound to work.
21 * It defines "main" macro to rename our main() so that
22 * it can install SDL's own. */
23#ifdef SDL2_PLAIN_INCLUDE
24#include <SDL.h>
25#else /* PLAIN_INCLUDE */
26#include <SDL2/SDL.h>
27#endif /* PLAIN_INCLUDE */
28#endif /* AUDIO_SDL2 */
29
30#ifdef HAVE_LOCALE_H
31#include <locale.h>
32#endif
33#include <stdarg.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <time.h>
38
39#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
42
43#include <gtk/gtk.h>
44#include <gdk/gdk.h>
45
46/* utility */
47#include "fc_cmdline.h"
48#include "fciconv.h"
49#include "fcintl.h"
50#include "log.h"
51#include "mem.h"
52#include "support.h"
53
54/* common */
55#include "dataio.h"
56#include "featured_text.h"
57#include "game.h"
58#include "government.h"
59#include "map.h"
60#include "unitlist.h"
61#include "version.h"
62
63/* client */
64#include "audio.h"
65#include "client_main.h"
66#include "climisc.h"
67#include "clinet.h"
68#include "colors.h"
69#include "connectdlg_common.h"
70#include "control.h"
71#include "editor.h"
72#include "options.h"
73#include "text.h"
74#include "tilespec.h"
75#include "zoom.h"
76
77/* client/gui-gtk-4.0 */
78#include "chatline.h"
79#include "citizensinfo.h"
80#include "connectdlg.h"
81#include "cma_fe.h"
82#include "dialogs.h"
83#include "diplodlg.h"
84#include "editgui.h"
85#include "gotodlg.h"
86#include "graphics.h"
87#include "gui_stuff.h"
88#include "happiness.h"
89#include "helpdlg.h"
90#include "inteldlg.h"
91#include "mapctrl.h"
92#include "mapview.h"
93#include "menu.h"
94#include "messagewin.h"
95#include "optiondlg.h"
96#include "pages.h"
97#include "plrdlg.h"
98#include "luaconsole.h"
99#include "spaceshipdlg.h"
100#include "repodlgs.h"
101#include "voteinfo_bar.h"
102
103#include "gui_main.h"
104
106
107GtkWidget *map_canvas; /* GtkDrawingArea */
110
111GtkWidget *overview_canvas; /* GtkDrawingArea */
112GtkWidget *overview_scrolled_window; /* GtkScrolledWindow */
113/* The two values below define the width and height of the map overview. The
114 * first set of values (2*62, 2*46) define the size for a netbook display. For
115 * bigger displays the values are doubled (default). */
116#define OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK (2 * 64)
117#define OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK (2 * 46)
118#define OVERVIEW_CANVAS_STORE_WIDTH \
119 (2 * OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK)
120#define OVERVIEW_CANVAS_STORE_HEIGHT \
121 (2 * OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK)
124
130
134
137
140
148
152
154
155const char *const gui_character_encoding = "UTF-8";
157
164
165static int unit_id_top;
166static int unit_ids[MAX_NUM_UNITS_BELOW]; /* ids of the units icons in
167 * information display: (or 0) */
171
175
176static bool gui_up = FALSE;
177
178static bool audio_paused = FALSE;
179static bool client_focus = TRUE;
180
182
183static struct video_mode vmode = { -1, -1 };
184
185static void set_g_log_callbacks(void);
186
188 double x, double y, gpointer data);
189
190static void end_turn_callback(GtkWidget *w, gpointer data);
192 gpointer data);
193static void set_wait_for_writable_socket(struct connection *pc,
194 bool socket_writable);
195
196static void print_usage(void);
197static void activate_gui(GtkApplication *app, gpointer data);
198static bool parse_options(int argc, char **argv);
202 GdkModifierType state,
203 gpointer data);
205 gdouble dx, gdouble dy,
206 gpointer data);
207
208static void tearoff_callback(GtkWidget *b, gpointer data);
209static GtkWidget *detached_widget_new(void);
211
213 double x, double y, gpointer data);
215 double x, double y, gpointer data);
216static gboolean quit_dialog_callback(void);
217
219 gpointer user_data);
220
221static void free_unit_table(void);
222
223static void adjust_default_options(void);
224
227 gpointer user_data);
228
229static float zoom_steps_custom[] = {
230 -1.0, 0.13, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, -1.0
231};
232
233/**********************************************************************/
236static void log_callback_utf8(enum log_level level, const char *message,
237 bool file_too)
238{
239 if (!file_too || level <= LOG_FATAL) {
240 fc_fprintf(stderr, "%d: %s\n", level, message);
241 }
242}
243
244/**********************************************************************/
249{
250 double seconds = real_timer_callback();
251
253 if (!audio_paused && !client_focus) {
254 audio_pause();
256 } else if (audio_paused && client_focus) {
257 audio_resume();
259 }
260 }
261
263
264 return FALSE;
265}
266
267/**********************************************************************/
271static void print_usage(void)
272{
273 /* add client-specific usage information here */
275 _("gtk4-client gui-specific options are:\n"));
276
278 _("-r, --resolution WIDTHxHEIGHT\tAssume given resolution "
279 "screen\n"));
281 /* TRANS: Keep word 'default' untranslated */
282 _("-z, --zoom LEVEL\tSet zoom level; use value 'default' "
283 "to reset\n\n"));
284
285 /* TRANS: No full stop after the URL, could cause confusion. */
286 fc_fprintf(stderr, _("Report bugs at %s\n"), BUG_URL);
287}
288
289/**********************************************************************/
292static bool parse_options(int argc, char **argv)
293{
294 int i = 1;
295
296 while (i < argc) {
297 char *option = NULL;
298
299 if (is_option("--help", argv[i])) {
300 print_usage();
301
302 return FALSE;
303 } else if ((option = get_option_malloc("--zoom", argv, &i, argc, FALSE))) {
304 char *endptr;
305
306 if (strcmp("default", option)) {
309 } else {
311 }
312 free(option);
313 } else if ((option = get_option_malloc("--resolution", argv, &i, argc, FALSE))) {
315 fc_fprintf(stderr, _("Illegal video mode '%s'\n"), option);
317 }
318 free(option);
319 } else {
320 fc_fprintf(stderr, _("Unknown command-line option \"%s\".\n"),
321 argv[i]);
323 }
324
325 i++;
326 }
327
328 return TRUE;
329}
330
331/**********************************************************************/
335 gpointer data)
336{
337 switch (arg) {
340
341 if (!gtk_widget_get_can_focus(w)) {
342 return;
343 }
344
345 if (!gtk_widget_is_focus(w)) {
347 return;
348 }
349 break;
350
351 default:
352 break;
353 }
354}
355
356/**********************************************************************/
362{
364 static int old_width = -1, old_height = -1;
367
368 if (width != old_width
369 || height != old_height || height == 0) {
370 /* XXX: At starts, we have a race condition with the chatline content
371 * recovery. It might consider that the bottom line is the first one,
372 * probably because gtk_widget_get_* calls returns 0. If you scroll up
373 * you will see the past content displayed.
374 */
378 }
379 }
380}
381
382/**********************************************************************/
393
394/**********************************************************************/
398{
399 if ((state & GDK_SHIFT_MASK)) {
400 switch (keyval) {
401
402 case GDK_KEY_Left:
404 return TRUE;
405
406 case GDK_KEY_Right:
408 return TRUE;
409
410 case GDK_KEY_Up:
412 return TRUE;
413
414 case GDK_KEY_Down:
416 return TRUE;
417
418 case GDK_KEY_Home:
420 return TRUE;
421
422 case GDK_KEY_Page_Up:
425 return TRUE;
426
430 return TRUE;
431
432 default:
433 break;
434 }
435 } else if (!(state & GDK_CONTROL_MASK)) {
436 switch (keyval) {
437 default:
438 break;
439 }
440 }
441
442 if (state & GDK_SHIFT_MASK) {
443 bool volchange = FALSE;
444
445 switch (keyval) {
446 case GDK_KEY_plus:
447 case GDK_KEY_KP_Add:
449 volchange = TRUE;
450 break;
451
452 case GDK_KEY_minus:
455 volchange = TRUE;
456 break;
457
458 default:
459 break;
460 }
461
462 if (volchange) {
464 "sound_effects_volume");
465
468 100);
470
471 return TRUE;
472 }
473 } else if (!(state & GDK_CONTROL_MASK)) {
474 switch (keyval) {
475 case GDK_KEY_plus:
476 case GDK_KEY_KP_Add:
477 zoom_step_up();
478 return TRUE;
479
480 case GDK_KEY_minus:
483 return TRUE;
484
485 default:
486 break;
487 }
488 }
489
490 /* Return here if observer */
491 if (client_is_observer()) {
492 return FALSE;
493 }
494
495 switch (keyval) {
496
497 case GDK_KEY_KP_Up:
498 case GDK_KEY_KP_8:
499 case GDK_KEY_Up:
500 case GDK_KEY_8:
502 return TRUE;
503
505 case GDK_KEY_KP_9:
506 case GDK_KEY_Page_Up:
507 case GDK_KEY_9:
509 return TRUE;
510
511 case GDK_KEY_KP_Right:
512 case GDK_KEY_KP_6:
513 case GDK_KEY_Right:
514 case GDK_KEY_6:
516 return TRUE;
517
519 case GDK_KEY_KP_3:
521 case GDK_KEY_3:
523 return TRUE;
524
525 case GDK_KEY_KP_Down:
526 case GDK_KEY_KP_2:
527 case GDK_KEY_Down:
528 case GDK_KEY_2:
530 return TRUE;
531
532 case GDK_KEY_KP_End:
533 case GDK_KEY_KP_1:
534 case GDK_KEY_End:
535 case GDK_KEY_1:
537 return TRUE;
538
539 case GDK_KEY_KP_Left:
540 case GDK_KEY_KP_4:
541 case GDK_KEY_Left:
542 case GDK_KEY_4:
544 return TRUE;
545
546 case GDK_KEY_KP_Home:
547 case GDK_KEY_KP_7:
548 case GDK_KEY_Home:
549 case GDK_KEY_7:
551 return TRUE;
552
553 case GDK_KEY_KP_Begin:
554 case GDK_KEY_KP_5:
555 case GDK_KEY_5:
557 return TRUE;
558
559 case GDK_KEY_Escape:
561 return TRUE;
562
563 case GDK_KEY_b:
566 return TRUE;
567 }
568 break;
569
570 default:
571 break;
572 };
573
574 return FALSE;
575}
576
577/**********************************************************************/
583 GdkModifierType state,
584 gpointer data)
585{
586 if (inputline_has_focus()) {
587 return FALSE;
588 }
589
590 if (keyval == GDK_KEY_apostrophe) {
591 /* Allow this even if not in main map view; chatline is present on
592 * some other pages too */
593
594 /* Make the chatline visible if it's not currently.
595 * FIXME: should find the correct window, even when detached, from any
596 * other window; should scroll to the bottom automatically showing the
597 * latest text from other players; MUST NOT make spurious text windows
598 * at the bottom of other dialogs. */
600 /* The main game view is visible. May need to switch notebook. */
603 } else {
605 }
606 }
607
608 /* If the chatline is (now) visible, focus it. */
609 if (inputline_is_visible()) {
611 return TRUE;
612 }
613 }
614
617 return FALSE;
618 }
619
620 if (editor_is_active()) {
621 if (handle_edit_key_press(keyval, state)) {
622 return TRUE;
623 }
624 }
625
626 if (state & GDK_SHIFT_MASK) {
627 switch (keyval) {
628
629 case GDK_KEY_Return:
630 case GDK_KEY_KP_Enter:
631 key_end_turn();
632 return TRUE;
633
634 default:
635 break;
636 }
637 }
638
640 /* 0 means the map view is focused. */
641 return key_press_map_canvas(keyval, state);
642 }
643
644#if 0
645 /* We are focused some other dialog, tab, or widget. */
646 if ((state & GDK_CONTROL_MASK)) {
647 } else if ((state & GDK_SHIFT_MASK)) {
648 } else {
649 switch (keyval) {
650
651 case GDK_KEY_F4:
653 return TRUE;
654
655 default:
656 break;
657 };
658 }
659#endif /* 0 */
660
661 return FALSE;
662}
663
664/**********************************************************************/
710
711/**********************************************************************/
717{
718 g_object_ref(wdg); /* Make sure reference count stays above 0
719 * during the transition to new parent. */
720
721 if (GTK_IS_PANED(old_wdg)) {
723 } else if (GTK_IS_WINDOW(old_wdg)) {
725 } else {
727
729 }
730
731 if (GTK_IS_PANED(new_wdg)) {
733 } else if (GTK_IS_WINDOW(new_wdg)) {
735 } else {
737
739 }
740
742}
743
744/**********************************************************************/
754
755/**********************************************************************/
765
766/**********************************************************************/
770{
772
773 aparent = g_object_get_data(G_OBJECT(box), "aparent");
775
776 if (aparent != cparent) {
778
780 }
781}
782
783/**********************************************************************/
786static void tearoff_close(GtkWidget *w, gpointer data)
787{
789}
790
791/**********************************************************************/
796{
797 GtkWidget *box = GTK_WIDGET(data);
799
801 GtkWidget *w;
803
804 w = gtk_window_new();
806 gtk_widget_set_name(w, "Freeciv");
807 gtk_window_set_title(GTK_WINDOW(w), _("Freeciv"));
808 g_signal_connect(w, "close-request", G_CALLBACK(tearoff_close), box);
809
810 g_object_set_data(G_OBJECT(box), "aparent", gtk_widget_get_parent(box));
811
812 temp_hide = g_object_get_data(G_OBJECT(box), "hide-over-reparent");
813 if (temp_hide != NULL) {
815 }
816
818
820
821 if (temp_hide != NULL) {
823 }
824 } else {
825 tearoff_reattach(box);
826 }
827}
828
829/**********************************************************************/
833{
835
836 return hbox;
837}
838
839/**********************************************************************/
844{
845 GtkWidget *b, *fillbox;
847
850
851 /* These toggle buttons run vertically down the side of many UI
852 * elements, so they need to be thin horizontally. */
854 ".detach_button {\n"
855 " padding: 0px 0px 0px 0px;\n"
856 " min-width: 6px;\n"
857 "}",
858 -1);
859 }
860
866 gtk_widget_add_css_class(b, "detach_button");
867 gtk_widget_set_tooltip_text(b, _("Detach/Attach the pane."));
868
871
873
875
876 return fillbox;
877}
878
879/**********************************************************************/
886static void populate_unit_pic_table(void)
887{
888 int i, width;
890 GdkPixbuf *pix;
891 int ttw;
893
894 /* Get width of the overview window */
898
900
902 /* We want arrow to appear if there is other units in addition
903 to active one in tile. Active unit is not counted, so there
904 can be 0 other units to not to display arrow. */
905 num_units_below = 1 - 1;
906 } else {
909 }
910
911 /* Top row: the active unit. */
912 /* Note, we ref this and other widgets here so that we can unref them
913 * in reset_unit_table. */
917 gtk_grid_attach(GTK_GRID(table), unit_pic, 0, 0, 1, 1);
918
920 g_signal_connect(controller, "pressed",
922 GINT_TO_POINTER(-1));
924
926 /* Bottom row: other units in the same tile. */
927 for (i = 0; i < num_units_below; i++) {
931
933 g_signal_connect(controller, "pressed",
937
939 i, 1, 1, 1);
940 }
941 }
942
943 /* Create arrow (popup for all units on the selected tile) */
947
949 g_signal_connect(controller, "pressed",
951 NULL);
953
954 /* An extra layer so that we can hide the clickable button but keep
955 * an explicit size request to avoid the layout jumping around */
962 gdk_pixbuf_get_width(pix), -1);
964
966 /* Display on bottom row. */
968 num_units_below, 1, 1, 1);
969 } else {
970 /* Display on top row (there is no bottom row). */
972 1, 0, 1, 1);
973 }
974
976}
977
978/**********************************************************************/
1001
1002/**********************************************************************/
1006{
1007 /* Unreference all of the widgets that we're about to reallocate, thus
1008 * avoiding a memory leak. Remove them from the container first, just
1009 * to be safe. Note, the widgets are ref'd in
1010 * populate_unit_pic_table(). */
1012
1014
1015 /* We have to force a redraw of the units. And we explicitly have
1016 * to force a redraw of the focus unit, which is normally only
1017 * redrawn when the focus changes. We also have to force the 'more'
1018 * arrow to go away, both by explicitly hiding it and telling it to
1019 * do so (this will be reset immediately afterwards if necessary,
1020 * but we have to make the *internal* state consistent). */
1023 if (get_num_units_in_focus() == 1) {
1025 } else {
1026 set_unit_icon(-1, NULL);
1027 }
1029}
1030
1031/**********************************************************************/
1034#if 0
1036{
1041}
1042#endif
1043
1044/**********************************************************************/
1052
1053/**********************************************************************/
1057{
1058 struct option *opt = optset_option_by_name(server_optset, "fixedlength");
1059
1060 if (opt != NULL && option_bool_get(opt)) {
1062 _("Fixed length turns"));
1063 } else {
1064 char buf[256];
1065
1066 fc_snprintf(buf, sizeof(buf), "%s:\n%s",
1067 _("Turn Done"), _("Shift+Return"));
1069 }
1070}
1071
1072/**********************************************************************/
1075static void setup_widgets(void)
1076{
1077 GtkWidget *page, *hgrid, *hgrid2, *label;
1078 GtkWidget *frame, *table, *table2, *paned, *sw, *text;
1079 GtkWidget *button, *view, *mainbox, *vbox, *right_vbox = NULL;
1080 int i;
1081 GtkWidget *notebook, *statusbar;
1083 struct sprite *spr;
1084 int right_row = 0;
1085 int top_row = 0;
1086 int grid_col = 0;
1087 int grid2_col = 0;
1090 GtkWidget *ebar;
1091
1093
1094 notebook = gtk_notebook_new();
1095
1096 toplevel_tabs = notebook;
1101 gtk_box_append(GTK_BOX(mainbox), notebook);
1104
1115
1117
1123
1124 /* *** Everything in the top *** */
1125
1126 page = gtk_scrolled_window_new();
1131 TRUE);
1132 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, NULL);
1133
1138 hgrid = gtk_grid_new();
1139
1141 /* The window is divided into two horizontal panels: overview +
1142 * civinfo + unitinfo, main view + message window. */
1144 right_row = 0;
1148
1154
1155 /* Overview size designed for small displays (netbooks). */
1158 } else {
1159 /* The window is divided into two vertical panes: overview +
1160 * + civinfo + unitinfo + main view, message window. */
1165
1166 /* Overview size designed for big displays (desktops). */
1169 }
1170
1171 /* This holds the overview canvas, production info, etc. */
1173 /* Put vbox to the left of anything else in hgrid -- right_vbox is either
1174 * the chat/messages pane, or NULL which is OK */
1176 GTK_POS_LEFT, 1, 1);
1177 grid_col++;
1178
1179 /* Overview canvas */
1185
1193
1203
1205
1208
1211
1226
1227 /* The rest */
1234
1235 /* Info on player's civilization, when game is running. */
1236 frame = gtk_frame_new("");
1237 gtk_box_append(GTK_BOX(avbox), frame);
1238
1239 main_frame_civ_name = frame;
1240
1244
1245 label = gtk_label_new(NULL);
1249 gtk_widget_set_margin_end(label, 2);
1250 gtk_widget_set_margin_top(label, 2);
1252
1255 G_CALLBACK(show_info_popup), frame);
1258 main_label_info = label;
1259
1260 /* Production status */
1261 table = gtk_grid_new();
1265
1266 /* Citizens for taxrates */
1267 table2 = gtk_grid_new();
1268 gtk_grid_attach(GTK_GRID(table), table2, 0, 0, 10, 1);
1270
1271 for (i = 0; i < 10; i++) {
1273
1276
1279 g_signal_connect(controller, "pressed",
1285 g_signal_connect(controller, "pressed",
1289 }
1290
1291 /* Science, environmental, govt, timeout */
1293 if (spr != NULL) {
1295 } else {
1297 }
1298
1300 if (spr != NULL) {
1302 } else {
1304 }
1305
1307 if (spr != NULL) {
1309 } else {
1311 }
1312
1314 if (spr != NULL) {
1316 } else {
1318 }
1319
1320 for (i = 0; i < 4; i++) {
1321 GtkWidget *w;
1322
1323 switch (i) {
1324 case 0:
1325 w = bulb_label;
1326 break;
1327 case 1:
1328 w = sun_label;
1329 break;
1330 case 2:
1331 w = flake_label;
1332 break;
1333 default:
1334 case 3:
1335 w = government_label;
1336 break;
1337 }
1338
1345 gtk_grid_attach(GTK_GRID(table), w, i, 1, 1, 1);
1346 }
1347
1349
1350 frame = gtk_frame_new(NULL);
1351 gtk_grid_attach(GTK_GRID(table), frame, 4, 1, 6, 1);
1353
1354
1355 /* Turn done */
1357
1359
1363
1364 /* Selected unit status */
1365
1366 /* If you turn this to something else than GtkBox, also adjust
1367 * editgui.c replace_widget() code that removes and adds widgets from it. */
1371
1372 /* In edit mode the unit_info_box widget is replaced by the
1373 * editinfobox, so we need to add a ref here so that it is
1374 * not destroyed when removed from its container.
1375 * See editinfobox_refresh() call to replace_widget() */
1377
1380
1386
1387 label = gtk_label_new(NULL);
1392 gtk_widget_set_margin_end(label, 2);
1393 gtk_widget_set_margin_top(label, 2);
1396 unit_info_label = label;
1397
1398 hgrid2 = gtk_grid_new();
1400
1401 table = gtk_grid_new();
1407
1410
1412
1413 /* Map canvas, editor toolbar, and scrollbars */
1414
1415 /* The top notebook containing the map view and dialogs. */
1416
1420
1421
1426 right_row = 0;
1429
1433 } else {
1435 }
1436
1438
1441
1448
1449 label = gtk_label_new(Q_("?noun:View"));
1451
1452 frame = gtk_frame_new(NULL);
1453 gtk_grid_attach(GTK_GRID(map_widget), frame, 0, 0, 1, 1);
1454
1460
1462
1463#if 0
1472#endif /* 0 */
1473
1475
1479
1483
1485 NULL, NULL);
1486
1490 g_signal_connect(mc_controller, "released",
1498 g_signal_connect(mc_controller, "released",
1517
1518 g_signal_connect(map_canvas, "resize",
1520
1521 /* Synchronize animation updates with the tick (improve performances) */
1523
1525 g_signal_connect(mc_controller, "key-pressed",
1528
1529 /* *** The message window -- this is a detachable widget *** */
1530
1533 } else {
1535
1539
1543 }
1545
1548 } else {
1550 }
1556
1561
1568 }
1569 }
1570
1572
1575 TRUE);
1580
1581 label = gtk_label_new(_("Chat"));
1583
1590
1591 gtk_widget_set_name(text, "chatline");
1592
1594 gtk_widget_realize(text);
1596
1598 if (dtach_lowbox != NULL) {
1600 }
1601
1603
1604 /* The chat line */
1611
1612 button = gtk_check_button_new_with_label(_("Allies Only"));
1616 g_signal_connect(button, "toggled",
1620
1621 button = gtk_button_new_with_label(_("Clear links"));
1622 g_signal_connect(button, "clicked",
1625
1626 /* These two signals doesn't seems to be triggered for now */
1627 g_signal_connect(main_message_area, "notify::default-width",
1629 g_signal_connect(main_message_area, "notify::default-height",
1631
1632 /* Use parent resize to triggers properly the resize */
1633 g_signal_connect(map_canvas, "resize",
1635
1636 /* Other things to take care of */
1637
1639 TRUE);
1640
1643 }
1644
1647
1651 }
1652}
1653
1654/**********************************************************************/
1659 const gchar *message,
1660 gpointer user_data)
1661{
1662 enum log_level fllvl = LOG_ERROR;
1663
1664 switch (log_level) {
1665 case G_LOG_LEVEL_DEBUG:
1666 fllvl = LOG_DEBUG;
1667 break;
1669 fllvl = LOG_WARN;
1670 break;
1671 default:
1672 break;
1673 }
1674
1675 if (log_domain != NULL) {
1676 log_base(fllvl, "%s: %s", log_domain, message);
1677 } else {
1678 log_base(fllvl, "%s", message);
1679 }
1680}
1681
1682/**********************************************************************/
1686 const GLogField *fields,
1688 gpointer user_data)
1689{
1690 /* No need to have formatter of our own - let's use glib's default one. */
1692
1694
1695 return G_LOG_WRITER_HANDLED;
1696}
1697
1698/**********************************************************************/
1709
1710/**********************************************************************/
1713static void set_g_log_callbacks(void)
1714{
1715 /* Old API, still used by many log producers */
1717
1721
1722 /* glib >= 2.50 API */
1724}
1725
1726/**********************************************************************/
1737
1738/**********************************************************************/
1741int main(int argc, char **argv)
1742{
1743 return client_main(argc, argv, FALSE);
1744}
1745
1746/**********************************************************************/
1750{
1751 log_normal(_("Migrating options from gtk2 to gtk3 client"));
1752
1753#define MIGRATE_OPTION(opt) gui_options.gui_gtk3_##opt = gui_options.gui_gtk2_##opt;
1754#define MIGRATE_STR_OPTION(opt) \
1755 strncpy(gui_options.gui_gtk3_##opt, gui_options.gui_gtk2_##opt, \
1756 sizeof(gui_options.gui_gtk3_##opt));
1757
1758 /* Default theme name is never migrated */
1759 /* 'fullscreen', 'small_display_layout', and 'message_chat_location'
1760 * not migrated, as (unlike Gtk2), Gtk3-client tries to pick better
1761 * defaults for these in fresh installations based on screen size (see
1762 * adjust_default_options()); so user is probably better served by
1763 * getting these adaptive defaults than whatever they had for Gtk2.
1764 * Since 'fullscreen' isn't migrated, we don't need to worry about
1765 * preserving gui_gtk2_migrated_from_2_5 either. */
1779 MIGRATE_OPTION(popup_tech_help);
1780
1794
1795#undef MIGRATE_OPTION
1796#undef MIGRATE_STR_OPTION
1797
1799}
1800
1801/**********************************************************************/
1805{
1806 log_normal(_("Migrating options from gtk3 to gtk3.22 client"));
1807
1808#define MIGRATE_OPTION(opt) gui_options.gui_gtk3_22_##opt = gui_options.gui_gtk3_##opt;
1809#define MIGRATE_STR_OPTION(opt) \
1810 strncpy(gui_options.gui_gtk3_22_##opt, gui_options.gui_gtk3_##opt, \
1811 sizeof(gui_options.gui_gtk3_22_##opt));
1812
1813 /* Default theme name is never migrated */
1814
1815 /* Simulate gui-gtk3's migrate_options_from_2_5() */
1817 log_normal(_("Migrating gtk3-client options from freeciv-2.5 options."));
1820 }
1821
1838 MIGRATE_OPTION(popup_tech_help);
1839
1853
1854#undef MIGRATE_OPTION
1855#undef MIGRATE_STR_OPTION
1856
1858}
1859
1860/**********************************************************************/
1864{
1865 log_normal(_("Migrating options from gtk3.22 to gtk4 client"));
1866
1867#define MIGRATE_OPTION(opt) GUI_GTK_OPTION(opt) = gui_options.gui_gtk3_22_##opt;
1868#define MIGRATE_STR_OPTION(opt) \
1869 strncpy(GUI_GTK_OPTION(opt), gui_options.gui_gtk3_22_##opt, \
1870 sizeof(GUI_GTK_OPTION(opt)));
1871
1872 /* Default theme name is never migrated */
1889 MIGRATE_OPTION(popup_tech_help);
1890
1904
1905#undef MIGRATE_OPTION
1906#undef MIGRATE_STR_OPTION
1907
1909}
1910
1911/**********************************************************************/
1914int ui_main(int argc, char **argv)
1915{
1916 if (parse_options(argc, argv)) {
1917 /* The locale has already been set in init_nls() and the windows-specific
1918 * locale logic in gtk_init() causes problems with zh_CN (see PR#39475) */
1920
1921 if (!gtk_init_check()) {
1922 log_fatal(_("Failed to open graphical mode."));
1923 return EXIT_FAILURE;
1924 }
1925
1927
1928 gui_up = TRUE;
1932 gui_up = FALSE;
1933
1942 cma_fe_done();
1944
1945 /* We have extra ref for unit_info_box that has protected
1946 * it from getting destroyed when editinfobox_refresh()
1947 * moves widgets around. Free that extra ref here. */
1949 if (empty_unit_paintable != NULL) {
1951 }
1952
1953 editgui_free();
1955 message_buffer = NULL; /* Result of destruction of everything */
1957 }
1958
1959 return EXIT_SUCCESS;
1960}
1961
1962/**********************************************************************/
1966{
1968 guint sig;
1970 char window_name[1024];
1971
1973 if (vmode.width > 0 && vmode.height > 0) {
1976 }
1977
1984
1986 gtk_widget_set_name(toplevel, "Freeciv");
1987
1989
1991
1992 if (gui_options.first_boot) {
1994 /* We're using fresh defaults for this version of this client,
1995 * so prevent any future migrations from other clients / versions */
1997 /* Avoid also marking previous Gtk clients as migrated, so that
1998 * they can have their own run of their adjust_default_options() if
1999 * they are ever run (as a side effect of Gtk2->Gtk3 migration). */
2000 } else {
2005 /* We want a fresh look at screen-size-related options after Gtk2 */
2007 /* We don't ever want to consider pre-2.6 fullscreen option again
2008 * (even for gui-gtk3) */
2010 }
2012 }
2014 }
2015 }
2016
2019 }
2020
2021 fc_snprintf(window_name, sizeof(window_name), _("Freeciv (%s)"), GUI_NAME_SHORT);
2023
2024 g_signal_connect(toplevel, "close-request",
2026
2027 /* Disable GTK cursor key focus movement */
2028 sig = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
2030 0, 0, 0, 0);
2032
2034 if (OT_FONT == option_type(poption)) {
2035 /* Force to call the appropriate callback. */
2037 }
2039
2042
2043 if (NULL == city_names_style) {
2045 log_error("city_names_style should have been set by options.");
2046 }
2049 log_error("city_productions_style should have been set by options.");
2050 }
2051 if (NULL == reqtree_text_style) {
2053 log_error("reqtree_text_style should have been set by options.");
2054 }
2055
2058
2059 /* keep the icon of the executable on Windows (see PR#36491) */
2060#ifndef FREECIV_MSWINDOWS
2061 {
2062 /* Only call this after tileset_load_tiles is called. */
2064 }
2065#endif /* FREECIV_MSWINDOWS */
2066
2067 setup_widgets();
2068 load_cursors();
2069 cma_fe_init();
2076 chatline_init();
2078
2080
2082
2083 /* Assumes toplevel showing */
2085
2086 /* Assumes client_state is set */
2088}
2089
2090/**********************************************************************/
2093bool is_gui_up(void)
2094{
2095 return gui_up;
2096}
2097
2098/**********************************************************************/
2101void ui_exit(void)
2102{
2103 if (message_buffer != NULL) {
2106 }
2107}
2108
2109/**********************************************************************/
2112enum gui_type get_gui_type(void)
2113{
2114 return GUI_GTK4;
2115}
2116
2117/**********************************************************************/
2124
2125/**********************************************************************/
2131void set_unit_icon(int idx, struct unit *punit)
2132{
2133 GtkWidget *w;
2134
2135 fc_assert_ret(idx >= -1 && idx < num_units_below);
2136
2137 if (idx == -1) {
2138 w = unit_pic;
2139 unit_id_top = punit ? punit->id : 0;
2140 } else {
2141 w = unit_below_pic[idx];
2142 unit_ids[idx] = punit ? punit->id : 0;
2143 }
2144
2145 if (!w) {
2146 return;
2147 }
2148
2149 if (punit) {
2151 } else {
2152 if (empty_unit_paintable == NULL) {
2153 /* FIXME: Use proper icon height instead of hardcoded 50 */
2155
2156 /* Add ref to avoid it getting destroyed along any single parent widget. */
2158 }
2160 }
2161}
2162
2163/**********************************************************************/
2169{
2170 static bool showing = FALSE;
2171
2172 if (more_arrow == NULL) {
2173 return;
2174 }
2175
2176 if (onoff && !showing) {
2178 showing = TRUE;
2179 } else if (!onoff && showing) {
2181 showing = FALSE;
2182 }
2183}
2184
2185/**********************************************************************/
2195
2196/**********************************************************************/
2201 double x, double y, gpointer data)
2202{
2203 int i = GPOINTER_TO_INT(data);
2204 struct unit *punit;
2205
2206 if (i == -1) {
2208 if (punit && unit_is_in_focus(punit)) {
2209 /* Clicking on the currently selected unit will center it. */
2211 }
2212 return TRUE;
2213 }
2214
2215 if (unit_ids[i] == 0) { /* No unit displayed at this place */
2216 return TRUE;
2217 }
2218
2220 if (NULL != punit && unit_owner(punit) == client_player()) {
2221 /* Unit shouldn't be NULL but may be owned by an ally. */
2223 }
2224
2225 return TRUE;
2226}
2227
2228/**********************************************************************/
2233 double x, double y, gpointer data)
2234{
2236
2237 if (punit) {
2239 }
2240
2241 return TRUE;
2242}
2243
2244/**********************************************************************/
2248{
2250}
2251
2252/**********************************************************************/
2256 double x, double y, gpointer data)
2257{
2258 GtkWidget *p;
2259 GtkWidget *child;
2260 GtkWidget *frame = GTK_WIDGET(data);
2261
2262 p = gtk_popover_new();
2263
2264 gtk_widget_set_parent(p, frame);
2267 g_signal_connect(p, "closed",
2270
2271 return TRUE;
2272}
2273
2274/**********************************************************************/
2278{
2279 /* Button going insensitive is going to lose focus. Keep focus at least
2280 * within the window */
2282
2285}
2286
2287/**********************************************************************/
2291 gpointer data)
2292{
2294
2295 return TRUE;
2296}
2297
2298/**********************************************************************/
2302 bool socket_writable)
2303{
2304 static bool previous_state = FALSE;
2305
2307
2309 return;
2310
2311 log_debug("set_wait_for_writable_socket(%d)", socket_writable);
2312
2317 NULL);
2318
2320}
2321
2322/**********************************************************************/
2326void add_net_input(int sock)
2327{
2328#ifdef FREECIV_MSWINDOWS
2330#else
2332#endif
2334 G_IO_IN | G_IO_ERR,
2336 NULL);
2338}
2339
2340/**********************************************************************/
2350
2351/**********************************************************************/
2355static void quit_dialog_response(GtkWidget *dialog, gint response)
2356{
2358 if (response == GTK_RESPONSE_YES) {
2360 if (client.conn.used) {
2362 }
2363 quit_gtk_main();
2364 }
2365}
2366
2367/**********************************************************************/
2371{
2372 /* Quit gtk main loop. After this it will return to finish
2373 * ui_main() */
2374
2376}
2377
2378/**********************************************************************/
2383{
2384 static GtkWidget *dialog;
2385
2386 if (!dialog) {
2388 0,
2391 _("Are you sure you want to quit?"));
2392 setup_dialog(dialog, toplevel);
2393
2394 g_signal_connect(dialog, "response",
2396 g_signal_connect(dialog, "destroy",
2397 G_CALLBACK(widget_destroyed), &dialog);
2398 }
2399
2401}
2402
2403/**********************************************************************/
2407{
2409 /* Stop emission of event. */
2410 return TRUE;
2411}
2412
2413struct callback {
2414 void (*callback)(void *data);
2415 void *data;
2416};
2417
2418/**********************************************************************/
2422{
2423 struct callback *cb = data;
2424
2425 (cb->callback)(cb->data);
2426 free(cb);
2427
2428 return FALSE;
2429}
2430
2431/**********************************************************************/
2436void add_idle_callback(void (callback)(void *), void *data)
2437{
2438 struct callback *cb = fc_malloc(sizeof(*cb));
2439
2440 cb->callback = callback;
2441 cb->data = data;
2443}
2444
2445/**********************************************************************/
2450 gpointer user_data)
2451{
2454 }
2455 return G_SOURCE_CONTINUE; /* keep animation call back running */
2456}
2457
2458/**********************************************************************/
2463{
2464 GtkWidget *button;
2465
2467 fc_assert_ret(button != NULL);
2469
2472}
2473
2474/**********************************************************************/
2485
2486/**********************************************************************/
2496
2497/**********************************************************************/
2507
2508/**********************************************************************/
2518
2519/**********************************************************************/
2524{
2525
2526 struct option *poption;
2527
2528#define option_var_set_callback(var, callback) \
2529 if ((poption = optset_option_by_name(client_optset, \
2530 GUI_GTK_OPTION_STR(var)))) { \
2531 option_set_changed_callback(poption, callback); \
2532 } else { \
2533 log_error("Didn't find option %s!", GUI_GTK_OPTION_STR(var)); \
2534 }
2535
2540
2547#undef option_var_set_callback
2548}
2549
2550/**********************************************************************/
2555{
2556 GtkWidget *button;
2557
2559 fc_assert_ret(button != NULL);
2561
2562 /* Hide the "Allies Only" button for local games. */
2563 if (is_server_running()) {
2565 } else {
2569 }
2570}
2571
2572/**********************************************************************/
2580
2581/**********************************************************************/
2585{
2586 cat_snprintf(outbuf, outlen, _("\nBuilt against gtk %d.%d.%d, using %d.%d.%d"
2587 "\nBuilt against glib %d.%d.%d, using %d.%d.%d"),
2592}
2593
2594/**********************************************************************/
2599{
2602
2604 if (!display) {
2605 return FALSE;
2606 }
2607
2609
2610 if (!monitor) {
2611 return FALSE;
2612 }
2613
2615
2616 return TRUE;
2617}
2618
2619/**********************************************************************/
2623{
2624 GdkRectangle rect;
2625
2626 if (vmode.width > 0) {
2627 return vmode.width;
2628 }
2629
2630 if (monitor_size(&rect)) {
2631 return rect.width;
2632 } else {
2633 return 0;
2634 }
2635}
2636
2637/**********************************************************************/
2641{
2642 GdkRectangle rect;
2643
2644 if (vmode.height > 0) {
2645 return vmode.height;
2646 }
2647
2648 if (monitor_size(&rect)) {
2649 return rect.height;
2650 } else {
2651 return 0;
2652 }
2653}
2654
2655/**********************************************************************/
2659{
2660 if (vmode.width > 0 && vmode.height > 0) {
2661 return &vmode;
2662 }
2663
2664 return NULL;
2665}
2666
2667/**********************************************************************/
2670static void adjust_default_options(void)
2671{
2672 int scr_height = screen_height();
2673
2674 if (scr_height > 0) {
2675 /* Adjust these options only if we do know the screen height. */
2676
2677 if (scr_height <= 480) {
2678 /* Freeciv is practically unusable outside fullscreen mode in so
2679 * small display */
2680 log_verbose("Changing default to fullscreen due to very small screen");
2682 }
2683 if (scr_height < 1024) {
2684 /* This is a small display */
2685 log_verbose("Defaulting to small widget layout due to small screen");
2687 log_verbose("Defaulting to merged messages/chat due to small screen");
2689 }
2690 }
2691}
2692
2693/**********************************************************************/
2697{
2698 return fc_app;
2699}
void audio_pause(void)
Definition audio.c:607
void audio_resume(void)
Definition audio.c:615
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
void chat_welcome_message(bool gui_has_copying_mitem)
static struct ai_type * self
Definition classicai.c:45
bool client_is_observer(void)
double real_timer_callback(void)
int client_main(int argc, char *argv[], bool postpone_tileset)
void user_ended_turn(void)
struct civclient client
void start_quitting(void)
void set_client_state(enum client_states newstate)
bool can_client_change_view(void)
#define client_player()
#define TIMER_INTERVAL
Definition client_main.h:30
@ C_S_DISCONNECTED
Definition client_main.h:45
void buy_production_in_selected_cities(void)
Definition climisc.c:1316
struct sprite * client_warming_sprite(void)
Definition climisc.c:377
struct sprite * client_cooling_sprite(void)
Definition climisc.c:394
struct sprite * client_research_sprite(void)
Definition climisc.c:354
struct sprite * client_government_sprite(void)
Definition climisc.c:412
void disconnect_from_server(bool leaving_sound)
Definition clinet.c:306
void input_from_server(int fd)
Definition clinet.c:411
struct color * get_color(const struct tileset *t, enum color_std stdcolor)
char * incite_cost
Definition comments.c:75
bool is_server_running(void)
void key_recall_previous_focus_unit(void)
Definition control.c:3332
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:388
void key_cancel_action(void)
Definition control.c:3270
int num_units_below
Definition control.c:76
void unit_focus_set(struct unit *punit)
Definition control.c:518
struct unit_list * get_units_in_focus(void)
Definition control.c:177
void key_end_turn(void)
Definition control.c:3324
void update_unit_pix_label(struct unit_list *punitlist)
Definition control.c:997
void key_unit_move(enum direction8 gui_dir)
Definition control.c:3353
enum cursor_hover_state hover_state
Definition control.c:89
struct unit * head_of_units_in_focus(void)
Definition control.c:410
int get_num_units_in_focus(void)
Definition control.c:185
void control_mouse_cursor(struct tile *ptile)
Definition control.c:1227
void key_center_capital(void)
Definition control.c:3307
#define MAX_NUM_UNITS_BELOW
Definition control.h:296
@ HOVER_NONE
Definition control.h:26
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
bool editor_is_active(void)
Definition editor.c:347
bool is_option(const char *option_name, char *option)
Definition fc_cmdline.c:112
char * get_option_malloc(const char *option_name, char **argv, int *i, int argc, bool gc)
Definition fc_cmdline.c:50
@ O_SCIENCE
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
void fc_fprintf(FILE *stream, const char *format,...) fc__attribute((__format__(__printf__
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
struct unit * game_unit_by_number(int id)
Definition game.c:116
bool inputline_has_focus(void)
Definition chatline.c:71
void inputline_toolkit_view_append_button(GtkWidget *toolkit_view, GtkWidget *button)
Definition chatline.c:1292
GtkWidget * inputline_toolkit_view_new(void)
Definition chatline.c:1270
void set_message_buffer_view_link_handlers(GtkWidget *view)
Definition chatline.c:744
bool inputline_is_visible(void)
Definition chatline.c:87
void chatline_init(void)
Definition chatline.c:1302
void inputline_grab_focus(void)
Definition chatline.c:79
void chatline_scroll_to_bottom(bool delayed)
Definition chatline.c:1006
void citizens_dialog_init(void)
void citizens_dialog_done(void)
void cma_fe_init(void)
Definition cma_fe.c:88
void cma_fe_done(void)
Definition cma_fe.c:96
void unit_select_dialog_popup(struct tile *ptile)
Definition dialogs.c:377
gboolean taxrates_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition dialogs.c:1425
void diplomacy_dialog_init(void)
Definition diplodlg.c:1206
void diplomacy_dialog_done(void)
Definition diplodlg.c:1215
gboolean handle_edit_key_press(GdkEventKey *ev)
Definition editgui.c:1663
void editgui_create_widgets(void)
Definition editgui.c:1824
struct editbar * editgui_get_editbar(void)
Definition editgui.c:1790
void editgui_free(void)
Definition editgui.c:1837
void goto_dialog_focus_units_changed(void)
Definition gotodlg.c:541
static GtkWidget * source
Definition gotodlg.c:58
void load_cursors(void)
Definition graphics.c:78
GtkWidget * map_vertical_scrollbar
Definition gui_main.c:109
int ui_main(int argc, char **argv)
Definition gui_main.c:1882
const char * client_string
Definition gui_main.c:105
GtkTextBuffer * message_buffer
Definition gui_main.c:177
static void quit_dialog_response(GtkWidget *dialog, gint response)
Definition gui_main.c:2319
void real_focus_units_changed(void)
Definition gui_main.c:2146
void set_unit_icons_more_arrow(bool onoff)
Definition gui_main.c:2123
static void print_usage(void)
Definition gui_main.c:263
#define OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK
Definition gui_main.c:116
#define option_var_set_callback(var, callback)
static gboolean quit_dialog_callback(void)
Definition gui_main.c:2372
static GIOChannel * srv_channel
Definition gui_main.c:180
GtkWidget * main_label_info
Definition gui_main.c:137
static bool monitor_size(GdkRectangle *rect_p)
Definition gui_main.c:2550
GtkWidget * bottom_notebook
Definition gui_main.c:129
GtkWidget * unit_info_label
Definition gui_main.c:150
static gboolean timer_callback(gpointer data)
Definition gui_main.c:240
struct video_mode * resolution_request_get(void)
Definition gui_main.c:2608
void set_unit_icon(int idx, struct unit *punit)
Definition gui_main.c:2093
static int unit_ids[MAX_NUM_UNITS_BELOW]
Definition gui_main.c:174
GtkWidget * timeout_label
Definition gui_main.c:147
static bool gui_up
Definition gui_main.c:184
static guint srv_id
Definition gui_main.c:181
static gboolean mouse_scroll_mapcanvas(GtkWidget *w, GdkEventScroll *ev)
Definition gui_main.c:680
PangoFontDescription * city_productions_style
Definition gui_main.c:133
GtkWidget * overview_scrolled_window
Definition gui_main.c:112
static GtkWidget * detached_widget_fill(GtkWidget *tearbox)
Definition gui_main.c:842
GtkWidget * top_notebook
Definition gui_main.c:129
#define MIGRATE_STR_OPTION(opt)
GtkWidget * unit_info_box
Definition gui_main.c:151
gboolean fc_lost_focus(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition gui_main.c:732
void ui_exit(void)
Definition gui_main.c:2063
enum gui_type get_gui_type(void)
Definition gui_main.c:2074
static GtkWidget * detached_widget_new(void)
Definition gui_main.c:831
gint cur_y
Definition gui_main.c:182
int main(int argc, char **argv)
Definition gui_main.c:1760
void fullscreen_opt_refresh(struct option *poption)
Definition gui_main.c:2430
void ui_init(void)
Definition gui_main.c:1750
static void free_unit_table(void)
Definition gui_main.c:992
static gboolean idle_callback_wrapper(gpointer data)
Definition gui_main.c:2387
static void apply_city_names_font(struct option *poption)
Definition gui_main.c:2442
static void apply_city_productions_font(struct option *poption)
Definition gui_main.c:2453
gboolean fc_gained_focus(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition gui_main.c:742
GtkWidget * government_label
Definition gui_main.c:146
GtkWidget * sun_label
Definition gui_main.c:144
PangoFontDescription * city_names_style
Definition gui_main.c:132
void refresh_chat_buttons(void)
Definition gui_main.c:2506
gboolean map_canvas_focus(void)
Definition gui_main.c:357
GtkWidget * turn_done_button
Definition gui_main.c:148
int screen_width(void)
Definition gui_main.c:2572
GtkWidget * scroll_panel
Definition gui_main.c:140
static void end_turn_callback(GtkWidget *w, gpointer data)
Definition gui_main.c:2245
#define OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK
Definition gui_main.c:117
static void log_callback_utf8(enum log_level level, const char *message, bool file_too)
Definition gui_main.c:228
void add_idle_callback(void(callback)(void *), void *data)
Definition gui_main.c:2402
static gboolean show_info_popup(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition gui_main.c:2214
static void set_g_log_callbacks(void)
Definition gui_main.c:1734
void reset_unit_table(void)
Definition gui_main.c:1020
static gboolean key_press_map_canvas(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition gui_main.c:398
GtkWidget * unit_info_frame
Definition gui_main.c:152
void options_extra_init(void)
Definition gui_main.c:2476
GtkWidget * top_vbox
Definition gui_main.c:128
static void allied_chat_only_callback(struct option *poption)
Definition gui_main.c:2415
static void adjust_default_options(void)
Definition gui_main.c:2620
static void set_wait_for_writable_socket(struct connection *pc, bool socket_writable)
Definition gui_main.c:2265
GtkWidget * ahbox
Definition gui_main.c:139
static void apply_reqtree_text_font(struct option *poption)
Definition gui_main.c:2464
bool is_gui_up(void)
Definition gui_main.c:2055
static gboolean toplevel_focus(GtkWidget *w, GtkDirectionType arg)
Definition gui_main.c:313
PangoFontDescription * reqtree_text_style
Definition gui_main.c:134
GtkWidget * flake_label
Definition gui_main.c:145
static void g_log_to_freelog_cb(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
Definition gui_main.c:1678
GtkWidget * avbox
Definition gui_main.c:139
gint cur_x
Definition gui_main.c:182
void insert_client_build_info(char *outbuf, size_t outlen)
Definition gui_main.c:2536
static void set_g_log_callback_domain(const char *domain)
Definition gui_main.c:1722
GtkWidget * bulb_label
Definition gui_main.c:143
GtkWidget * overview_canvas
Definition gui_main.c:111
GtkWidget * toplevel
Definition gui_main.c:125
static void setup_widgets(void)
Definition gui_main.c:1124
#define OVERVIEW_CANVAS_STORE_WIDTH
Definition gui_main.c:118
void remove_net_input(void)
Definition gui_main.c:2308
GtkWidget * map_horizontal_scrollbar
Definition gui_main.c:108
GtkWidget * map_canvas
Definition gui_main.c:107
static gboolean toplevel_key_press_handler(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition gui_main.c:596
void sound_bell(void)
Definition gui_main.c:2082
static void migrate_options_from_gtk2(void)
Definition gui_main.c:1768
GtkWidget * econ_label[10]
Definition gui_main.c:142
void popup_quit_dialog(void)
Definition gui_main.c:2346
static void migrate_options_from_gtk3(void)
Definition gui_main.c:1823
const char *const gui_character_encoding
Definition gui_main.c:160
static int unit_id_top
Definition gui_main.c:173
static gboolean get_net_input(GIOChannel *source, GIOCondition condition, gpointer data)
Definition gui_main.c:2254
static bool audio_paused
Definition gui_main.c:186
GtkWidget * map_widget
Definition gui_main.c:130
static bool client_focus
Definition gui_main.c:187
GtkWidget * right_notebook
Definition gui_main.c:129
void quit_gtk_main(void)
Definition gui_main.c:2334
static void allied_chat_button_toggled(GtkToggleButton *button, gpointer user_data)
Definition gui_main.c:2527
static struct video_mode vmode
Definition gui_main.c:189
void add_net_input(int sock)
Definition gui_main.c:2290
static GLogWriterOutput g_log_writer_to_freelog_cb(GLogLevelFlags log_level, const GLogField *fields, gsize n_fields, gpointer user_data)
Definition gui_main.c:1706
GtkWidget * toplevel_tabs
Definition gui_main.c:127
static GtkWidget * allied_chat_toggle_button
Definition gui_main.c:178
int overview_canvas_store_width
Definition gui_main.c:122
void update_turn_done_tooltip(void)
Definition gui_main.c:1105
static void tearoff_callback(GtkWidget *b, gpointer data)
Definition gui_main.c:786
GtkTextView * main_message_area
Definition gui_main.c:176
int overview_canvas_store_height
Definition gui_main.c:123
int screen_height(void)
Definition gui_main.c:2590
static bool parse_options(int argc, char **argv)
Definition gui_main.c:284
GtkWidget * conn_box
Definition gui_main.c:139
#define OVERVIEW_CANVAS_STORE_HEIGHT
Definition gui_main.c:120
GtkWidget * main_frame_civ_name
Definition gui_main.c:136
#define MIGRATE_OPTION(opt)
const bool gui_use_transliteration
Definition gui_main.c:161
#define GUI_NAME_FULL
Definition gui_main.h:29
#define GUI_NAME_SHORT
Definition gui_main.h:30
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:32
void dlg_tab_provider_prepare(void)
Definition gui_stuff.c:1155
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
void gui_update_font_full(const char *font_name, const char *font_value, PangoFontDescription **font_desc)
Definition gui_stuff.c:1073
void happiness_dialog_init(void)
Definition happiness.c:86
void happiness_dialog_done(void)
Definition happiness.c:94
void help_system_init(void)
Definition helpdlg.c:158
void intel_dialog_done(void)
Definition inteldlg.c:128
void intel_dialog_init(void)
Definition inteldlg.c:119
void luaconsole_dialog_init(void)
Definition luaconsole.c:83
void luaconsole_dialog_done(void)
Definition luaconsole.c:101
gboolean move_overviewcanvas(GtkWidget *w, GdkEventMotion *ev, gpointer data)
Definition mapctrl.c:463
gboolean move_mapcanvas(GtkWidget *w, GdkEventMotion *ev, gpointer data)
Definition mapctrl.c:406
gboolean leave_mapcanvas(GtkWidget *widget, GdkEventCrossing *event)
Definition mapctrl.c:435
void update_city_descriptions(void)
Definition mapview.c:488
gboolean map_canvas_draw(GtkWidget *w, cairo_t *cr, gpointer data)
Definition mapview.c:424
gboolean overview_canvas_draw(GtkWidget *w, cairo_t *cr, gpointer data)
Definition mapview.c:356
void meswin_dialog_popup(bool raise)
Definition messagewin.c:417
GtkWidget * create_start_page(void)
Definition pages.c:2623
GtkWidget * create_network_page(void)
Definition pages.c:1201
GtkWidget * create_scenario_page(void)
Definition pages.c:3185
static GtkWidget * statusbar
Definition pages.c:89
enum client_pages get_current_client_page(void)
Definition pages.c:3345
void destroy_server_scans(void)
Definition pages.c:768
GtkWidget * create_load_page(void)
Definition pages.c:2904
GtkWidget * create_statusbar(void)
Definition pages.c:909
GtkWidget * create_main_page(void)
Definition pages.c:231
void science_report_dialog_redraw(void)
Definition repodlgs.c:761
void spaceship_dialog_init(void)
void spaceship_dialog_done(void)
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
GtkWidget * ingame_votebar
GtkWidget * voteinfo_bar_new(bool split_bar)
gboolean reverse_taxrates_callback(GtkGestureClick *gesture, int n_press, double x, double y)
Definition dialogs.c:1460
static GdkPaintable * empty_unit_paintable
Definition gui_main.c:158
static void tearoff_close(GtkWidget *w, gpointer data)
Definition gui_main.c:786
static void tearoff_reattach(GtkWidget *box)
Definition gui_main.c:769
gboolean terminate_signal_processing(GtkEventControllerFocus *controller, gpointer data)
Definition gui_main.c:1047
static GtkWidget * more_arrow_container
Definition gui_main.c:163
static GtkWidget * unit_pic
Definition gui_main.c:160
static gboolean animation_tick_cb(GtkWidget *widget, GdkFrameClock *frame_clock, gpointer user_data)
Definition gui_main.c:2448
static gboolean select_more_arrow_callback(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition gui_main.c:2232
GtkWidget * econ_widget
Definition gui_main.c:153
static GtkApplication * fc_app
Definition gui_main.c:181
GtkApplication * gui_app(void)
Definition gui_main.c:2696
static GtkWidget * more_arrow
Definition gui_main.c:162
static float zoom_steps_custom[]
Definition gui_main.c:229
static void migrate_options_from_gtk3_22(void)
Definition gui_main.c:1863
static void activate_gui(GtkApplication *app, gpointer data)
Definition gui_main.c:1965
static void populate_unit_pic_table(void)
Definition gui_main.c:886
static void info_popup_closed(GtkWidget *self, gpointer data)
Definition gui_main.c:2247
static void move_from_container_to_container(GtkWidget *wdg, GtkWidget *old_wdg, GtkWidget *new_wdg)
Definition gui_main.c:714
static gboolean select_unit_pic_callback(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition gui_main.c:2200
static GtkWidget * unit_pic_table
Definition gui_main.c:159
static GtkWidget * unit_below_pic[MAX_NUM_UNITS_BELOW]
Definition gui_main.c:161
void main_message_area_resize(void *data)
Definition gui_main.c:361
void widget_destroyed(GtkWidget *wdg, void *data)
Definition gui_stuff.c:1157
gboolean right_butt_down_overviewcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:501
gboolean left_butt_up_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:166
gboolean right_butt_up_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:183
gboolean left_butt_down_overviewcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:476
gboolean left_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:208
gboolean right_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:263
gboolean middle_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:332
void map_canvas_resize(GtkWidget *w, int width, int height, gpointer data)
Definition mapview.c:407
void put_unit_picture(struct unit *punit, GtkPicture *p, int height)
Definition mapview.c:493
void menus_set_initial_toggle_values(void)
Definition menu.c:2989
GtkWidget * picture_new_from_surface(cairo_surface_t *surf)
Definition sprite.c:526
log_callback_fn log_set_callback(log_callback_fn callback)
Definition log.c:298
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define log_fatal(message,...)
Definition log.h:100
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_base(level, message,...)
Definition log.h:94
log_level
Definition log.h:28
@ LOG_ERROR
Definition log.h:30
@ LOG_DEBUG
Definition log.h:34
@ LOG_FATAL
Definition log.h:29
@ LOG_WARN
Definition log.h:31
#define log_error(message,...)
Definition log.h:103
void update_line(int canvas_x, int canvas_y)
void maybe_activate_keyboardless_goto(int canvas_x, int canvas_y)
bool rbutton_down
bool tiles_hilited_cities
void scroll_mapview(enum direction8 gui_dir)
bool keyboardless_goto_button_down
void update_selection_rectangle(float canvas_x, float canvas_y)
void init_mapcanvas_and_overview(void)
struct tile * canvas_pos_to_tile(float canvas_x, float canvas_y, float zoom)
void free_mapcanvas_and_overview(void)
void get_mapview_scroll_pos(int *scroll_x, int *scroll_y)
void get_mapview_scroll_step(int *xstep, int *ystep)
void set_mapview_scroll_pos(int scroll_x, int scroll_y, float zoom)
void center_tile_mapcanvas(const struct tile *ptile)
void update_animation(void)
void set_frame_by_frame_animation(void)
void link_marks_clear_all(void)
#define fc_malloc(sz)
Definition mem.h:34
void option_changed(struct option *poption)
Definition options.c:752
const struct option_set * server_optset
Definition options.c:4020
const struct option_set * client_optset
Definition options.c:1284
bool option_bool_get(const struct option *poption)
Definition options.c:801
enum option_type option_type(const struct option *poption)
Definition options.c:662
const char * option_font_target(const struct option *poption)
Definition options.c:1167
bool string_to_video_mode(const char *buf, struct video_mode *mode)
Definition options.c:6564
struct client_options gui_options
Definition options.c:72
const char * option_font_get(const struct option *poption)
Definition options.c:1145
struct option * optset_option_by_name(const struct option_set *poptset, const char *name)
Definition options.c:435
#define GUI_GTK_OVERVIEW_MIN_XSIZE
Definition options.h:600
#define options_iterate(poptset, poption)
Definition options.h:553
@ GUI_GTK_MSGCHAT_MERGED
Definition options.h:69
@ GUI_GTK_MSGCHAT_SPLIT
Definition options.h:67
#define options_iterate_end
Definition options.h:558
const char * get_info_label_text_popup(void)
Definition text.c:975
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
#define CLIP(lower, current, upper)
Definition shared.h:57
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
void * data
Definition gui_main.c:2381
void(* callback)(void *data)
Definition gui_main.c:2380
struct connection conn
Definition client_main.h:96
bool silent_when_not_in_focus
Definition options.h:191
bool gui_gtk3_22_migrated_from_gtk3
Definition options.h:134
bool gui_gtk3_migrated_from_2_5
Definition options.h:139
int sound_effects_volume
Definition options.h:190
bool first_boot
Definition options.h:128
float zoom_default_level
Definition options.h:231
bool gui_gtk3_fullscreen
Definition options.h:266
bool migrate_fullscreen
Definition options.h:145
bool gui_gtk3_migrated_from_gtk2
Definition options.h:133
Definition colors.h:21
void(* notify_of_writable_data)(struct connection *pc, bool data_available_and_socket_full)
Definition connection.h:181
GtkWidget * widget
Definition editgui.h:26
Definition unit.h:137
int id
Definition unit.h:144
int height
Definition options.h:48
int width
Definition options.h:47
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
void tileset_load_tiles(struct tileset *t)
Definition tilespec.c:3628
void tileset_free_tiles(struct tileset *t)
Definition tilespec.c:6615
void tileset_use_preferred_theme(const struct tileset *t)
Definition tilespec.c:7080
void tileset_init(struct tileset *t)
Definition tilespec.c:7137
struct sprite * get_arrow_sprite(const struct tileset *t, enum arrow_type arrow)
Definition tilespec.c:6879
struct sprite * get_tax_sprite(const struct tileset *t, Output_type_id otype)
Definition tilespec.c:6890
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:753
@ ARROW_RIGHT
Definition tilespec.h:201
#define unit_tile(_pu)
Definition unit.h:396
#define unit_owner(_pu)
Definition unit.h:395
float mouse_zoom
Definition zoom.c:28
void zoom_phase_set(bool individual_tiles)
Definition zoom.c:93
void zoom_set_steps(float *steps)
Definition zoom.c:80
void zoom_step_down(void)
Definition zoom.c:130
void zoom_step_up(void)
Definition zoom.c:106