Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/gui-gtk-4.0/gui_main.c Source File

Freeciv-3.1

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_SDL
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_SDL */
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/gdkkeysyms.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 "client_main.h"
65#include "climisc.h"
66#include "clinet.h"
67#include "colors.h"
68#include "connectdlg_common.h"
69#include "control.h"
70#include "editor.h"
71#include "options.h"
72#include "text.h"
73#include "tilespec.h"
74#include "zoom.h"
75
76/* client/gui-gtk-4.0 */
77#include "chatline.h"
78#include "citizensinfo.h"
79#include "connectdlg.h"
80#include "cma_fe.h"
81#include "dialogs.h"
82#include "diplodlg.h"
83#include "editgui.h"
84#include "gotodlg.h"
85#include "graphics.h"
86#include "gui_stuff.h"
87#include "happiness.h"
88#include "helpdlg.h"
89#include "inteldlg.h"
90#include "mapctrl.h"
91#include "mapview.h"
92#include "menu.h"
93#include "messagewin.h"
94#include "optiondlg.h"
95#include "pages.h"
96#include "plrdlg.h"
97#include "luaconsole.h"
98#include "spaceshipdlg.h"
99#include "repodlgs.h"
100#include "voteinfo_bar.h"
101
102#include "gui_main.h"
103
104 const char *client_string = GUI_NAME_FULL;
105
106GtkWidget *map_canvas; /* GtkDrawingArea */
107GtkWidget *map_horizontal_scrollbar;
108GtkWidget *map_vertical_scrollbar;
109
110GtkWidget *overview_canvas; /* GtkDrawingArea */
111GtkWidget *overview_scrolled_window; /* GtkScrolledWindow */
112/* The two values below define the width and height of the map overview. The
113 * first set of values (2*62, 2*46) define the size for a netbook display. For
114 * bigger displays the values are doubled (default). */
115#define OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK (2 * 64)
116#define OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK (2 * 46)
117#define OVERVIEW_CANVAS_STORE_WIDTH \
118 (2 * OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK)
119#define OVERVIEW_CANVAS_STORE_HEIGHT \
120 (2 * OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK)
121 int overview_canvas_store_width = OVERVIEW_CANVAS_STORE_WIDTH;
122 int overview_canvas_store_height = OVERVIEW_CANVAS_STORE_HEIGHT;
123
124GtkWidget *toplevel;
125GtkWidget *toplevel_tabs;
126GtkWidget *top_vbox;
127GtkWidget *top_notebook, *bottom_notebook, *right_notebook;
128GtkWidget *map_widget;
129 static GtkWidget *bottom_hpaned;
130
131PangoFontDescription *city_names_style = NULL;
132PangoFontDescription *city_productions_style = NULL;
133PangoFontDescription *reqtree_text_style = NULL;
134
135GtkWidget *main_frame_civ_name;
136GtkWidget *main_label_info;
137
138GtkWidget *avbox, *ahbox, *conn_box;
139GtkWidget* scroll_panel;
140
141GtkWidget *econ_label[10];
142GtkWidget *bulb_label;
143GtkWidget *sun_label;
144GtkWidget *flake_label;
145GtkWidget *government_label;
146GtkWidget *timeout_label;
147GtkWidget *turn_done_button;
148
149GtkWidget *unit_info_label;
150GtkWidget *unit_info_box;
151GtkWidget *unit_info_frame;
152
153GtkWidget *econ_widget;
154
155 const char *const gui_character_encoding = "UTF-8";
156 const bool gui_use_transliteration = FALSE;
157
158 static GdkPaintable *empty_unit_paintable = NULL;
159 static GtkWidget *unit_pic_table;
160 static GtkWidget *unit_pic;
161 static GtkWidget *unit_below_pic[MAX_NUM_UNITS_BELOW];
162 static GtkWidget *more_arrow;
163 static GtkWidget *more_arrow_container;
164
165 static int unit_id_top;
166 static int unit_ids[MAX_NUM_UNITS_BELOW]; /* ids of the units icons in
167 * information display: (or 0) */
168GtkTextView *main_message_area;
169GtkTextBuffer *message_buffer = NULL;
170 static GtkWidget *allied_chat_toggle_button;
171
172 static gint timer_id; /* Ditto */
173 static GIOChannel *srv_channel;
174 static guint srv_id;
175gint cur_x, cur_y;
176
177 static bool gui_up = FALSE;
178
179 static GtkApplication *fc_app;
180
181 static struct video_mode vmode = { -1, -1 };
182
183static void set_g_log_callbacks(void);
184
185static gboolean show_info_popup(GtkGestureClick *gesture, int n_press,
186 double x, double y, gpointer data);
187
188static void end_turn_callback(GtkWidget *w, gpointer data);
189static gboolean get_net_input(GIOChannel *source, GIOCondition condition,
190 gpointer data);
191static void set_wait_for_writable_socket(struct connection *pc,
192 bool socket_writable);
193
194static void print_usage(void);
195static void activate_gui(GtkApplication *app, gpointer data);
196static bool parse_options(int argc, char **argv);
197static gboolean toplevel_key_press_handler(GtkEventControllerKey *controller,
198 guint keyval,
199 guint keycode,
200 GdkModifierType state,
201 gpointer data);
202static gboolean mouse_scroll_mapcanvas(GtkEventControllerScroll *controller,
203 gdouble dx, gdouble dy,
204 gpointer data);
205
206static void tearoff_callback(GtkWidget *b, gpointer data);
207static GtkWidget *detached_widget_new(void);
208static GtkWidget *detached_widget_fill(GtkWidget *tearbox);
209
210static gboolean select_unit_pic_callback(GtkGestureClick *gesture, int n_press,
211 double x, double y, gpointer data);
212static gboolean select_more_arrow_callback(GtkGestureClick *gesture, int n_press,
213 double x, double y, gpointer data);
214static gboolean quit_dialog_callback(void);
215
216static void allied_chat_button_toggled(GtkToggleButton *button,
217 gpointer user_data);
218
219static void free_unit_table(void);
220
221static void adjust_default_options(void);
222
223 static float zoom_steps_custom[] = {
224 -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
225};
226
227/**********************************************************************/
230 static void log_callback_utf8(enum log_level level, const char *message,
231 bool file_too)
232{
233 if (!file_too || level <= LOG_FATAL) {
234 fc_fprintf(stderr, "%d: %s\n", level, message);
235 }
236}
237
238/**********************************************************************/
242 static gboolean timer_callback(gpointer data)
243{
244 double seconds = real_timer_callback();
245
246 timer_id = g_timeout_add(seconds * 1000, timer_callback, NULL);
247
248 return FALSE;
249}
250
251/**********************************************************************/
255 static void print_usage(void)
256{
257 /* add client-specific usage information here */
258 fc_fprintf(stderr,
259 _("gtk4-client gui-specific options are:\n"));
260
261 fc_fprintf(stderr,
262 _("-r, --resolution WIDTHxHEIGHT\tAssume given resolution "
263 "screen\n"));
264
265 fc_fprintf(stderr, "\n");
266
267 /* TRANS: No full stop after the URL, could cause confusion. */
268 fc_fprintf(stderr, _("Report bugs at %s\n"), BUG_URL);
269}
270
271/**********************************************************************/
274 static bool parse_options(int argc, char **argv)
275{
276 int i = 1;
277
278 while (i < argc) {
279 char *option = NULL;
280
281 if (is_option("--help", argv[i])) {
282 print_usage();
283
284 return FALSE;
285 } else if ((option = get_option_malloc("--resolution", argv, &i, argc,
286 FALSE))) {
287 if (!string_to_video_mode(option, &vmode)) {
288 fc_fprintf(stderr, _("Illegal video mode '%s'\n"), option);
289 exit(EXIT_FAILURE);
290 }
291 free(option);
292 } else {
293 fc_fprintf(stderr, _("Unknown command-line option \"%s\".\n"),
294 argv[i]);
295 exit(EXIT_FAILURE);
296 }
297
298 i++;
299 }
300
301 return TRUE;
302}
303
304/**********************************************************************/
307 static void toplevel_focus(GtkWidget *w, GtkDirectionType arg,
308 gpointer data)
309{
310 switch (arg) {
311 case GTK_DIR_TAB_FORWARD:
312 case GTK_DIR_TAB_BACKWARD:
313
314 if (!gtk_widget_get_can_focus(w)) {
315 return;
316 }
317
318 if (!gtk_widget_is_focus(w)) {
319 gtk_widget_grab_focus(w);
320 return;
321 }
322 break;
323
324 default:
325 break;
326 }
327}
328
329/**********************************************************************/
334 void main_message_area_resize(void *data)
335{
336 if (get_current_client_page() == PAGE_GAME) {
337 static int old_width = 0, old_height = 0;
338 int width = gtk_widget_get_width(GTK_WIDGET(main_message_area));
339 int height = gtk_widget_get_height(GTK_WIDGET(main_message_area));
340
341 if (width != old_width
342 || height != old_height) {
343 chatline_scroll_to_bottom(TRUE);
344 old_width = width;
345 old_height = height;
346 }
347
348 add_idle_callback(main_message_area_resize, NULL);
349 }
350}
351
352/**********************************************************************/
355gboolean map_canvas_focus(void)
356{
357 gtk_window_present(GTK_WINDOW(toplevel));
358 gtk_notebook_set_current_page(GTK_NOTEBOOK(top_notebook), 0);
359 gtk_widget_grab_focus(map_canvas);
360
361 return TRUE;
362}
363
364/**********************************************************************/
367 static gboolean key_press_map_canvas(guint keyval, GdkModifierType state)
368{
369 if ((state & GDK_SHIFT_MASK)) {
370 switch (keyval) {
371
372 case GDK_KEY_Left:
373 scroll_mapview(DIR8_WEST);
374 return TRUE;
375
376 case GDK_KEY_Right:
377 scroll_mapview(DIR8_EAST);
378 return TRUE;
379
380 case GDK_KEY_Up:
381 scroll_mapview(DIR8_NORTH);
382 return TRUE;
383
384 case GDK_KEY_Down:
385 scroll_mapview(DIR8_SOUTH);
386 return TRUE;
387
388 case GDK_KEY_Home:
389 key_center_capital();
390 return TRUE;
391
392 case GDK_KEY_Page_Up:
393 g_signal_emit_by_name(main_message_area, "move_cursor",
394 GTK_MOVEMENT_PAGES, -1, FALSE);
395 return TRUE;
396
397 case GDK_KEY_Page_Down:
398 g_signal_emit_by_name(main_message_area, "move_cursor",
399 GTK_MOVEMENT_PAGES, 1, FALSE);
400 return TRUE;
401
402 default:
403 break;
404 }
405 } else if (!(state & GDK_CONTROL_MASK)) {
406 switch (keyval) {
407 default:
408 break;
409 }
410 }
411
412 if (state & GDK_SHIFT_MASK) {
413 bool volchange = FALSE;
414
415 switch (keyval) {
416 case GDK_KEY_plus:
417 case GDK_KEY_KP_Add:
418 gui_options.sound_effects_volume += 10;
419 volchange = TRUE;
420 break;
421
422 case GDK_KEY_minus:
423 case GDK_KEY_KP_Subtract:
424 gui_options.sound_effects_volume -= 10;
425 volchange = TRUE;
426 break;
427
428 default:
429 break;
430 }
431
432 if (volchange) {
433 struct option *poption = optset_option_by_name(client_optset,
434 "sound_effects_volume");
435
436 gui_options.sound_effects_volume = CLIP(0,
437 gui_options.sound_effects_volume,
438 100);
439 option_changed(poption);
440
441 return TRUE;
442 }
443 } else if (!(state & GDK_CONTROL_MASK)) {
444 switch (keyval) {
445 case GDK_KEY_plus:
446 case GDK_KEY_KP_Add:
447 zoom_step_up();
448 return TRUE;
449
450 case GDK_KEY_minus:
451 case GDK_KEY_KP_Subtract:
452 zoom_step_down();
453 return TRUE;
454
455 default:
456 break;
457 }
458 }
459
460 /* Return here if observer */
461 if (client_is_observer()) {
462 return FALSE;
463 }
464
465 switch (keyval) {
466
467 case GDK_KEY_KP_Up:
468 case GDK_KEY_KP_8:
469 case GDK_KEY_Up:
470 case GDK_KEY_8:
471 key_unit_move(DIR8_NORTH);
472 return TRUE;
473
474 case GDK_KEY_KP_Page_Up:
475 case GDK_KEY_KP_9:
476 case GDK_KEY_Page_Up:
477 case GDK_KEY_9:
478 key_unit_move(DIR8_NORTHEAST);
479 return TRUE;
480
481 case GDK_KEY_KP_Right:
482 case GDK_KEY_KP_6:
483 case GDK_KEY_Right:
484 case GDK_KEY_6:
485 key_unit_move(DIR8_EAST);
486 return TRUE;
487
488 case GDK_KEY_KP_Page_Down:
489 case GDK_KEY_KP_3:
490 case GDK_KEY_Page_Down:
491 case GDK_KEY_3:
492 key_unit_move(DIR8_SOUTHEAST);
493 return TRUE;
494
495 case GDK_KEY_KP_Down:
496 case GDK_KEY_KP_2:
497 case GDK_KEY_Down:
498 case GDK_KEY_2:
499 key_unit_move(DIR8_SOUTH);
500 return TRUE;
501
502 case GDK_KEY_KP_End:
503 case GDK_KEY_KP_1:
504 case GDK_KEY_End:
505 case GDK_KEY_1:
506 key_unit_move(DIR8_SOUTHWEST);
507 return TRUE;
508
509 case GDK_KEY_KP_Left:
510 case GDK_KEY_KP_4:
511 case GDK_KEY_Left:
512 case GDK_KEY_4:
513 key_unit_move(DIR8_WEST);
514 return TRUE;
515
516 case GDK_KEY_KP_Home:
517 case GDK_KEY_KP_7:
518 case GDK_KEY_Home:
519 case GDK_KEY_7:
520 key_unit_move(DIR8_NORTHWEST);
521 return TRUE;
522
523 case GDK_KEY_KP_Begin:
524 case GDK_KEY_KP_5:
525 case GDK_KEY_5:
526 key_recall_previous_focus_unit();
527 return TRUE;
528
529 case GDK_KEY_Escape:
530 key_cancel_action();
531 return TRUE;
532
533 case GDK_KEY_b:
534 if (tiles_hilited_cities) {
535 buy_production_in_selected_cities();
536 return TRUE;
537 }
538 break;
539
540 default:
541 break;
542 };
543
544 return FALSE;
545}
546
547/**********************************************************************/
550 static gboolean toplevel_key_press_handler(GtkEventControllerKey *controller,
551 guint keyval,
552 guint keycode,
553 GdkModifierType state,
554 gpointer data)
555{
556 if (inputline_has_focus()) {
557 return FALSE;
558 }
559
560 if (keyval == GDK_KEY_apostrophe) {
561 /* Allow this even if not in main map view; chatline is present on
562 * some other pages too */
563
564 /* Make the chatline visible if it's not currently.
565 * FIXME: should find the correct window, even when detached, from any
566 * other window; should scroll to the bottom automatically showing the
567 * latest text from other players; MUST NOT make spurious text windows
568 * at the bottom of other dialogs. */
569 if (gtk_widget_get_mapped(top_vbox)) {
570 /* The main game view is visible. May need to switch notebook. */
571 if (GUI_GTK_OPTION(message_chat_location) == GUI_GTK_MSGCHAT_MERGED) {
572 gtk_notebook_set_current_page(GTK_NOTEBOOK(top_notebook), 1);
573 } else {
574 gtk_notebook_set_current_page(GTK_NOTEBOOK(bottom_notebook), 0);
575 }
576 }
577
578 /* If the chatline is (now) visible, focus it. */
579 if (inputline_is_visible()) {
580 inputline_grab_focus();
581 return TRUE;
582 }
583 }
584
585 if (!gtk_widget_get_mapped(top_vbox)
586 || !can_client_change_view()) {
587 return FALSE;
588 }
589
590 if (editor_is_active()) {
591 if (handle_edit_key_press(keyval, state)) {
592 return TRUE;
593 }
594 }
595
596 if (state & GDK_SHIFT_MASK) {
597 switch (keyval) {
598
599 case GDK_KEY_Return:
600 case GDK_KEY_KP_Enter:
601 key_end_turn();
602 return TRUE;
603
604 default:
605 break;
606 }
607 }
608
609 if (0 == gtk_notebook_get_current_page(GTK_NOTEBOOK(top_notebook))) {
610 /* 0 means the map view is focused. */
611 return key_press_map_canvas(keyval, state);
612 }
613
614#if 0
615 /* We are focused some other dialog, tab, or widget. */
616 if ((state & GDK_CONTROL_MASK)) {
617 } else if ((state & GDK_SHIFT_MASK)) {
618 } else {
619 switch (keyval) {
620
621 case GDK_KEY_F4:
622 map_canvas_focus();
623 return TRUE;
624
625 default:
626 break;
627 };
628 }
629#endif /* 0 */
630
631 return FALSE;
632}
633
634/**********************************************************************/
637 static gboolean mouse_scroll_mapcanvas(GtkEventControllerScroll *controller,
638 gdouble dx, gdouble dy,
639 gpointer data)
640{
641 int scroll_x, scroll_y, xstep, ystep;
642 gdouble e_x, e_y;
643 GdkModifierType state;
644
645 if (!can_client_change_view()) {
646 return FALSE;
647 }
648
649 get_mapview_scroll_pos(&scroll_x, &scroll_y);
650 get_mapview_scroll_step(&xstep, &ystep);
651
652 scroll_y += ystep * dy;
653 scroll_x += xstep * dx;
654
655 set_mapview_scroll_pos(scroll_x, scroll_y, mouse_zoom);
656
657 /* Emulating mouse move now */
658 if (!gtk_widget_has_focus(map_canvas)) {
659 gtk_widget_grab_focus(map_canvas);
660 }
661
662 gdk_event_get_position(gtk_event_controller_get_current_event(
663 GTK_EVENT_CONTROLLER(controller)),
664 &e_x, &e_y);
665 update_line(e_x, e_y);
666 state = gtk_event_controller_get_current_event_state(
667 GTK_EVENT_CONTROLLER(controller));
668 if (rbutton_down && (state & GDK_BUTTON3_MASK)) {
669 update_selection_rectangle(e_x, e_y);
670 }
671
672 if (keyboardless_goto_button_down && hover_state == HOVER_NONE) {
673 maybe_activate_keyboardless_goto(cur_x, cur_y);
674 }
675
676 control_mouse_cursor(canvas_pos_to_tile(cur_x, cur_y, mouse_zoom));
677
678 return TRUE;
679}
680
681/**********************************************************************/
684 static void move_from_container_to_container(GtkWidget *wdg,
685 GtkWidget *old_wdg,
686 GtkWidget *new_wdg)
687{
688 g_object_ref(wdg); /* Make sure reference count stays above 0
689 * during the transition to new parent. */
690
691 if (GTK_IS_PANED(old_wdg)) {
692 gtk_paned_set_end_child(GTK_PANED(old_wdg), NULL);
693 } else if (GTK_IS_WINDOW(old_wdg)) {
694 gtk_window_set_child(GTK_WINDOW(old_wdg), NULL);
695 } else {
696 fc_assert(GTK_IS_BOX(old_wdg));
697
698 gtk_box_remove(GTK_BOX(old_wdg), wdg);
699 }
700
701 if (GTK_IS_PANED(new_wdg)) {
702 gtk_paned_set_end_child(GTK_PANED(new_wdg), wdg);
703 } else if (GTK_IS_WINDOW(new_wdg)) {
704 gtk_window_set_child(GTK_WINDOW(new_wdg), wdg);
705 } else {
706 fc_assert(GTK_IS_BOX(new_wdg));
707
708 gtk_box_append(GTK_BOX(new_wdg), wdg);
709 }
710
711 g_object_unref(wdg);
712}
713
714/**********************************************************************/
717 static void tearoff_reattach(GtkWidget *box)
718{
719 GtkWidget *aparent, *cparent;
720
721 aparent = g_object_get_data(G_OBJECT(box), "aparent");
722 cparent = gtk_widget_get_parent(box);
723
724 if (aparent != cparent) {
725 move_from_container_to_container(box, cparent, aparent);
726
727 gtk_window_destroy(GTK_WINDOW(cparent));
728 }
729}
730
731/**********************************************************************/
734 static void tearoff_close(GtkWidget *w, gpointer data)
735{
736 tearoff_reattach(GTK_WIDGET(data));
737}
738
739/**********************************************************************/
743 static void tearoff_callback(GtkWidget *b, gpointer data)
744{
745 GtkWidget *box = GTK_WIDGET(data);
746 GtkWidget *old_parent = gtk_widget_get_parent(box);
747
748 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b))) {
749 GtkWidget *w;
750 GtkWidget *temp_hide;
751
752 w = gtk_window_new();
753 setup_dialog(w, toplevel);
754 gtk_widget_set_name(w, "Freeciv");
755 gtk_window_set_title(GTK_WINDOW(w), _("Freeciv"));
756 g_signal_connect(w, "close-request", G_CALLBACK(tearoff_close), box);
757
758 g_object_set_data(G_OBJECT(box), "aparent", gtk_widget_get_parent(box));
759
760 temp_hide = g_object_get_data(G_OBJECT(box), "hide-over-reparent");
761 if (temp_hide != NULL) {
762 gtk_widget_hide(temp_hide);
763 }
764
765 move_from_container_to_container(box, old_parent, w);
766
767 gtk_widget_show(w);
768
769 if (temp_hide != NULL) {
770 gtk_widget_show(temp_hide);
771 }
772 } else {
773 tearoff_reattach(box);
774 }
775}
776
777/**********************************************************************/
780 static GtkWidget *detached_widget_new(void)
781{
782 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
783
784 return hbox;
785}
786
787/**********************************************************************/
791 static GtkWidget *detached_widget_fill(GtkWidget *tearbox)
792{
793 GtkWidget *b, *fillbox;
794 static GtkCssProvider *detach_button_provider = NULL;
795
796 if (detach_button_provider == NULL) {
797 detach_button_provider = gtk_css_provider_new();
798
799 /* These toggle buttons run vertically down the side of many UI
800 * elements, so they need to be thin horizontally. */
801 gtk_css_provider_load_from_data(detach_button_provider,
802 ".detach_button {\n"
803 " padding: 0px 0px 0px 0px;\n"
804 " min-width: 6px;\n"
805 "}",
806 -1);
807 }
808
809 b = gtk_toggle_button_new();
810 gtk_style_context_add_provider_for_display(
811 gtk_widget_get_display(toplevel),
812 GTK_STYLE_PROVIDER(detach_button_provider),
813 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
814 gtk_widget_add_css_class(b, "detach_button");
815 gtk_widget_set_tooltip_text(b, _("Detach/Attach the pane."));
816
817 gtk_box_append(GTK_BOX(tearbox), b);
818 g_signal_connect(b, "toggled", G_CALLBACK(tearoff_callback), tearbox);
819
820 fillbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
821
822 gtk_box_append(GTK_BOX(tearbox), fillbox);
823
824 return fillbox;
825}
826
827/**********************************************************************/
834 static void populate_unit_pic_table(void)
835{
836 int i, width;
837 GtkWidget *table = unit_pic_table;
838 GdkPixbuf *pix;
839 int ttw;
840 GtkEventController *controller;
841
842 /* Get width of the overview window */
843 width = (overview_canvas_store_width > GUI_GTK_OVERVIEW_MIN_XSIZE)
844 ? overview_canvas_store_width
845 : GUI_GTK_OVERVIEW_MIN_XSIZE;
846
847 ttw = tileset_tile_width(tileset);
848
849 if (GUI_GTK_OPTION(small_display_layout)) {
850 /* We want arrow to appear if there is other units in addition
851 to active one in tile. Active unit is not counted, so there
852 can be 0 other units to not to display arrow. */
853 num_units_below = 1 - 1;
854 } else {
855 num_units_below = width / ttw;
856 num_units_below = CLIP(1, num_units_below, MAX_NUM_UNITS_BELOW);
857 }
858
859 /* Top row: the active unit. */
860 /* Note, we ref this and other widgets here so that we can unref them
861 * in reset_unit_table. */
862 unit_pic = gtk_picture_new();
863 g_object_ref(unit_pic);
864 gtk_widget_set_size_request(unit_pic, ttw, -1);
865 gtk_grid_attach(GTK_GRID(table), unit_pic, 0, 0, 1, 1);
866
867 controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
868 g_signal_connect(controller, "pressed",
869 G_CALLBACK(select_unit_pic_callback),
870 GINT_TO_POINTER(-1));
871 gtk_widget_add_controller(unit_pic, controller);
872
873 if (!GUI_GTK_OPTION(small_display_layout)) {
874 /* Bottom row: other units in the same tile. */
875 for (i = 0; i < num_units_below; i++) {
876 unit_below_pic[i] = gtk_picture_new();
877 g_object_ref(unit_below_pic[i]);
878 gtk_widget_set_size_request(unit_below_pic[i], ttw, -1);
879
880 controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
881 g_signal_connect(controller, "pressed",
882 G_CALLBACK(select_unit_pic_callback),
883 GINT_TO_POINTER(i));
884 gtk_widget_add_controller(unit_below_pic[i], controller);
885
886 gtk_grid_attach(GTK_GRID(table), unit_below_pic[i],
887 i, 1, 1, 1);
888 }
889 }
890
891 /* Create arrow (popup for all units on the selected tile) */
892 pix = sprite_get_pixbuf(get_arrow_sprite(tileset, ARROW_RIGHT));
893 more_arrow = gtk_image_new_from_pixbuf(pix);
894 g_object_ref(more_arrow);
895
896 controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
897 g_signal_connect(controller, "pressed",
898 G_CALLBACK(select_more_arrow_callback),
899 NULL);
900 gtk_widget_add_controller(more_arrow, controller);
901
902 /* An extra layer so that we can hide the clickable button but keep
903 * an explicit size request to avoid the layout jumping around */
904 more_arrow_container = gtk_frame_new(NULL);
905 gtk_widget_set_halign(more_arrow_container, GTK_ALIGN_CENTER);
906 gtk_widget_set_valign(more_arrow_container, GTK_ALIGN_CENTER);
907 g_object_ref(more_arrow_container);
908 gtk_frame_set_child(GTK_FRAME(more_arrow_container), more_arrow);
909 gtk_widget_set_size_request(more_arrow_container,
910 gdk_pixbuf_get_width(pix), -1);
911 g_object_unref(G_OBJECT(pix));
912
913 if (!GUI_GTK_OPTION(small_display_layout)) {
914 /* Display on bottom row. */
915 gtk_grid_attach(GTK_GRID(table), more_arrow_container,
916 num_units_below, 1, 1, 1);
917 } else {
918 /* Display on top row (there is no bottom row). */
919 gtk_grid_attach(GTK_GRID(table), more_arrow_container,
920 1, 0, 1, 1);
921 }
922
923 gtk_widget_show(table);
924}
925
926/**********************************************************************/
929 static void free_unit_table(void)
930{
931 if (unit_pic != NULL) {
932 gtk_grid_remove(GTK_GRID(unit_pic_table), unit_pic);
933 g_object_unref(unit_pic);
934 if (!GUI_GTK_OPTION(small_display_layout)) {
935 int i;
936
937 for (i = 0; i < num_units_below; i++) {
938 gtk_grid_remove(GTK_GRID(unit_pic_table),
939 unit_below_pic[i]);
940 g_object_unref(unit_below_pic[i]);
941 }
942 }
943 gtk_grid_remove(GTK_GRID(unit_pic_table),
944 more_arrow_container);
945 g_object_unref(more_arrow);
946 g_object_unref(more_arrow_container);
947 }
948}
949
950/**********************************************************************/
953 void reset_unit_table(void)
954{
955 /* Unreference all of the widgets that we're about to reallocate, thus
956 * avoiding a memory leak. Remove them from the container first, just
957 * to be safe. Note, the widgets are ref'd in
958 * populate_unit_pic_table(). */
959 free_unit_table();
960
961 populate_unit_pic_table();
962
963 /* We have to force a redraw of the units. And we explicitly have
964 * to force a redraw of the focus unit, which is normally only
965 * redrawn when the focus changes. We also have to force the 'more'
966 * arrow to go away, both by expicitly hiding it and telling it to
967 * do so (this will be reset immediately afterwards if necessary,
968 * but we have to make the *internal* state consistent). */
969 gtk_widget_hide(more_arrow);
970 set_unit_icons_more_arrow(FALSE);
971 if (get_num_units_in_focus() == 1) {
972 set_unit_icon(-1, head_of_units_in_focus());
973 } else {
974 set_unit_icon(-1, NULL);
975 }
976 update_unit_pix_label(get_units_in_focus());
977}
978
979/**********************************************************************/
982#if 0
983static void setup_canvas_color_for_state(GtkStateFlags state)
984{
985 gtk_widget_override_background_color(GTK_WIDGET(overview_canvas), state,
986 &get_color(tileset, COLOR_OVERVIEW_UNKNOWN)->color);
987 gtk_widget_override_background_color(GTK_WIDGET(map_canvas), state,
988 &get_color(tileset, COLOR_OVERVIEW_UNKNOWN)->color);
989}
990#endif
991
992/**********************************************************************/
995gboolean terminate_signal_processing(GtkEventControllerFocus *controller,
996 gpointer data)
997{
998 return TRUE;
999}
1000
1001/**********************************************************************/
1004 void update_turn_done_tooltip(void)
1005{
1006 struct option *opt = optset_option_by_name(server_optset, "fixedlength");
1007
1008 if (opt != NULL && option_bool_get(opt)) {
1009 gtk_widget_set_tooltip_text(turn_done_button,
1010 _("Fixed length turns"));
1011 } else {
1012 char buf[256];
1013
1014 fc_snprintf(buf, sizeof(buf), "%s:\n%s",
1015 _("Turn Done"), _("Shift+Return"));
1016 gtk_widget_set_tooltip_text(turn_done_button, buf);
1017 }
1018}
1019
1020/**********************************************************************/
1023 static void setup_widgets(void)
1024{
1025 GtkWidget *page, *hgrid, *hgrid2, *label;
1026 GtkWidget *frame, *table, *table2, *paned, *sw, *text;
1027 GtkWidget *button, *view, *mainbox, *vbox, *right_vbox = NULL;
1028 int i;
1029 GtkWidget *notebook, *statusbar;
1030 GtkWidget *dtach_lowbox = NULL;
1031 struct sprite *spr;
1032 int right_row = 0;
1033 int top_row = 0;
1034 int grid_col = 0;
1035 int grid2_col = 0;
1036 GtkGesture *mc_gesture;
1037 GtkEventController *mc_controller;
1038 GtkWidget *ebar;
1039
1040 message_buffer = gtk_text_buffer_new(NULL);
1041
1042 notebook = gtk_notebook_new();
1043
1044 toplevel_tabs = notebook;
1045 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
1046 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
1047 mainbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
1048 gtk_window_set_child(GTK_WINDOW(toplevel), mainbox);
1049 gtk_box_append(GTK_BOX(mainbox), notebook);
1050 statusbar = create_statusbar();
1051 gtk_box_append(GTK_BOX(mainbox), statusbar);
1052
1053 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1054 create_main_page(), NULL);
1055 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1056 create_start_page(), NULL);
1057 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1058 create_scenario_page(), NULL);
1059 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1060 create_load_page(), NULL);
1061 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1062 create_network_page(), NULL);
1063
1064 editgui_create_widgets();
1065
1066 ingame_votebar = voteinfo_bar_new(FALSE);
1067 gtk_widget_set_margin_bottom(ingame_votebar, 2);
1068 gtk_widget_set_margin_end(ingame_votebar, 2);
1069 gtk_widget_set_margin_start(ingame_votebar, 2);
1070 gtk_widget_set_margin_top(ingame_votebar, 2);
1071
1072 /* *** Everything in the top *** */
1073
1074 page = gtk_scrolled_window_new();
1075 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(page),
1076 GTK_POLICY_AUTOMATIC,
1077 GTK_POLICY_AUTOMATIC);
1078 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(page),
1079 TRUE);
1080 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, NULL);
1081
1082 top_vbox = gtk_grid_new();
1083 gtk_orientable_set_orientation(GTK_ORIENTABLE(top_vbox),
1084 GTK_ORIENTATION_VERTICAL);
1085 gtk_grid_set_row_spacing(GTK_GRID(top_vbox), 5);
1086 hgrid = gtk_grid_new();
1087
1088 if (GUI_GTK_OPTION(small_display_layout)) {
1089 /* The window is divided into two horizontal panels: overview +
1090 * civinfo + unitinfo, main view + message window. */
1091 right_vbox = gtk_grid_new();
1092 right_row = 0;
1093 gtk_orientable_set_orientation(GTK_ORIENTABLE(right_vbox),
1094 GTK_ORIENTATION_VERTICAL);
1095 gtk_grid_attach(GTK_GRID(hgrid), right_vbox, grid_col++, 0, 1, 1);
1096
1097 paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
1098 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(page), top_vbox);
1099 gtk_grid_attach(GTK_GRID(top_vbox), hgrid, 0, top_row++, 1, 1);
1100 gtk_grid_attach(GTK_GRID(right_vbox), paned, 0, right_row++, 1, 1);
1101 gtk_grid_attach(GTK_GRID(right_vbox), ingame_votebar, 0, right_row++, 1, 1);
1102
1103 /* Overview size designed for small displays (netbooks). */
1104 overview_canvas_store_width = OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK;
1105 overview_canvas_store_height = OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK;
1106 } else {
1107 /* The window is divided into two vertical panes: overview +
1108 * + civinfo + unitinfo + main view, message window. */
1109 paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
1110 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(page), paned);
1111 gtk_paned_set_start_child(GTK_PANED(paned), top_vbox);
1112 gtk_grid_attach(GTK_GRID(top_vbox), hgrid, 0, top_row++, 1, 1);
1113
1114 /* Overview size designed for big displays (desktops). */
1115 overview_canvas_store_width = OVERVIEW_CANVAS_STORE_WIDTH;
1116 overview_canvas_store_height = OVERVIEW_CANVAS_STORE_HEIGHT;
1117 }
1118
1119 /* This holds the overview canvas, production info, etc. */
1120 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
1121 /* Put vbox to the left of anything else in hgrid -- right_vbox is either
1122 * the chat/messages pane, or NULL which is OK */
1123 gtk_grid_attach_next_to(GTK_GRID(hgrid), vbox, right_vbox,
1124 GTK_POS_LEFT, 1, 1);
1125 grid_col++;
1126
1127 /* Overview canvas */
1128 ahbox = detached_widget_new();
1129 gtk_widget_set_hexpand(ahbox, FALSE);
1130 gtk_widget_set_vexpand(ahbox, FALSE);
1131 gtk_box_append(GTK_BOX(vbox), ahbox);
1132 avbox = detached_widget_fill(ahbox);
1133
1134 overview_scrolled_window = gtk_scrolled_window_new();
1135 gtk_widget_set_margin_start(overview_scrolled_window, 1);
1136 gtk_widget_set_margin_end(overview_scrolled_window, 1);
1137 gtk_widget_set_margin_top(overview_scrolled_window, 1);
1138 gtk_widget_set_margin_bottom(overview_scrolled_window, 1);
1139 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (overview_scrolled_window),
1140 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1141
1142 overview_canvas = gtk_drawing_area_new();
1143 gtk_widget_set_halign(overview_canvas, GTK_ALIGN_CENTER);
1144 gtk_widget_set_valign(overview_canvas, GTK_ALIGN_CENTER);
1145 gtk_widget_set_size_request(overview_canvas, overview_canvas_store_width,
1146 overview_canvas_store_height);
1147 gtk_widget_set_size_request(overview_scrolled_window, overview_canvas_store_width,
1148 overview_canvas_store_height);
1149 gtk_widget_set_hexpand(overview_canvas, TRUE);
1150 gtk_widget_set_vexpand(overview_canvas, TRUE);
1151
1152 gtk_box_append(GTK_BOX(avbox), overview_scrolled_window);
1153
1154 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(overview_scrolled_window),
1155 overview_canvas);
1156
1157 gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(overview_canvas),
1158 overview_canvas_draw, NULL, NULL);
1159
1160 mc_controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
1161 g_signal_connect(mc_controller, "pressed",
1162 G_CALLBACK(left_butt_down_overviewcanvas), NULL);
1163 gtk_widget_add_controller(overview_canvas, mc_controller);
1164 mc_gesture = gtk_gesture_click_new();
1165 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(mc_gesture), 3);
1166 mc_controller = GTK_EVENT_CONTROLLER(mc_gesture);
1167 g_signal_connect(mc_controller, "pressed",
1168 G_CALLBACK(right_butt_down_overviewcanvas), NULL);
1169 gtk_widget_add_controller(overview_canvas, mc_controller);
1170 mc_controller = gtk_event_controller_motion_new();
1171 g_signal_connect(mc_controller, "motion",
1172 G_CALLBACK(move_overviewcanvas), NULL);
1173 gtk_widget_add_controller(overview_canvas, mc_controller);
1174
1175 /* The rest */
1176 ahbox = detached_widget_new();
1177 gtk_box_append(GTK_BOX(vbox), ahbox);
1178 gtk_widget_set_hexpand(ahbox, FALSE);
1179 avbox = detached_widget_fill(ahbox);
1180 gtk_widget_set_vexpand(avbox, TRUE);
1181 gtk_widget_set_valign(avbox, GTK_ALIGN_FILL);
1182
1183 /* Info on player's civilization, when game is running. */
1184 frame = gtk_frame_new("");
1185 gtk_box_append(GTK_BOX(avbox), frame);
1186
1187 main_frame_civ_name = frame;
1188
1189 mainbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
1190 gtk_frame_set_child(GTK_FRAME(frame), mainbox);
1191 gtk_widget_set_hexpand(mainbox, TRUE);
1192
1193 label = gtk_label_new(NULL);
1194 gtk_widget_set_halign(label, GTK_ALIGN_START);
1195 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
1196 gtk_widget_set_margin_start(label, 2);
1197 gtk_widget_set_margin_end(label, 2);
1198 gtk_widget_set_margin_top(label, 2);
1199 gtk_widget_set_margin_bottom(label, 2);
1200
1201 mc_controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
1202 g_signal_connect(mc_controller, "pressed",
1203 G_CALLBACK(show_info_popup), frame);
1204 gtk_widget_add_controller(label, mc_controller);
1205 gtk_box_append(GTK_BOX(mainbox), label);
1206 main_label_info = label;
1207
1208 /* Production status */
1209 table = gtk_grid_new();
1210 gtk_widget_set_halign(table, GTK_ALIGN_CENTER);
1211 gtk_grid_set_column_homogeneous(GTK_GRID(table), TRUE);
1212 gtk_box_append(GTK_BOX(avbox), table);
1213
1214 /* Citizens for taxrates */
1215 table2 = gtk_grid_new();
1216 gtk_grid_attach(GTK_GRID(table), table2, 0, 0, 10, 1);
1217 econ_widget = table2;
1218
1219 for (i = 0; i < 10; i++) {
1220 GtkEventController *controller;
1221
1222 spr = i < 5 ? get_tax_sprite(tileset, O_SCIENCE) : get_tax_sprite(tileset, O_GOLD);
1223 econ_label[i] = picture_new_from_surface(spr->surface);
1224
1225 g_object_set_data(G_OBJECT(econ_label[i]), "rate_button", GUINT_TO_POINTER(i));
1226 controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
1227 g_signal_connect(controller, "pressed",
1228 G_CALLBACK(taxrates_callback), NULL);
1229 gtk_widget_add_controller(econ_label[i], controller);
1230 mc_gesture = gtk_gesture_click_new();
1231 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(mc_gesture), 3);
1232 controller = GTK_EVENT_CONTROLLER(mc_gesture);
1233 g_signal_connect(controller, "pressed",
1234 G_CALLBACK(reverse_taxrates_callback), NULL);
1235 gtk_widget_add_controller(econ_label[i], controller);
1236 gtk_grid_attach(GTK_GRID(table2), econ_label[i], i, 0, 1, 1);
1237 }
1238
1239 /* Science, environmental, govt, timeout */
1240 spr = client_research_sprite();
1241 if (spr != NULL) {
1242 bulb_label = picture_new_from_surface(spr->surface);
1243 } else {
1244 bulb_label = gtk_picture_new();
1245 }
1246
1247 spr = client_warming_sprite();
1248 if (spr != NULL) {
1249 sun_label = picture_new_from_surface(spr->surface);
1250 } else {
1251 sun_label = gtk_picture_new();
1252 }
1253
1254 spr = client_cooling_sprite();
1255 if (spr != NULL) {
1256 flake_label = picture_new_from_surface(spr->surface);
1257 } else {
1258 flake_label = gtk_picture_new();
1259 }
1260
1261 spr = client_government_sprite();
1262 if (spr != NULL) {
1263 government_label = picture_new_from_surface(spr->surface);
1264 } else {
1265 government_label = gtk_picture_new();
1266 }
1267
1268 for (i = 0; i < 4; i++) {
1269 GtkWidget *w;
1270
1271 switch (i) {
1272 case 0:
1273 w = bulb_label;
1274 break;
1275 case 1:
1276 w = sun_label;
1277 break;
1278 case 2:
1279 w = flake_label;
1280 break;
1281 default:
1282 case 3:
1283 w = government_label;
1284 break;
1285 }
1286
1287 gtk_widget_set_halign(w, GTK_ALIGN_START);
1288 gtk_widget_set_valign(w, GTK_ALIGN_START);
1289 gtk_widget_set_margin_start(w, 0);
1290 gtk_widget_set_margin_end(w, 0);
1291 gtk_widget_set_margin_top(w, 0);
1292 gtk_widget_set_margin_bottom(w, 0);
1293 gtk_grid_attach(GTK_GRID(table), w, i, 1, 1, 1);
1294 }
1295
1296 timeout_label = gtk_label_new("");
1297
1298 frame = gtk_frame_new(NULL);
1299 gtk_grid_attach(GTK_GRID(table), frame, 4, 1, 6, 1);
1300 gtk_frame_set_child(GTK_FRAME(frame), timeout_label);
1301
1302
1303 /* Turn done */
1304 turn_done_button = gtk_button_new_with_label(_("Turn Done"));
1305
1306 gtk_grid_attach(GTK_GRID(table), turn_done_button, 0, 2, 10, 1);
1307
1308 g_signal_connect(turn_done_button, "clicked",
1309 G_CALLBACK(end_turn_callback), NULL);
1310 update_turn_done_tooltip();
1311
1312 /* Selected unit status */
1313
1314 /* If you turn this to something else than GtkBox, also adjust
1315 * editgui.c replace_widget() code that removes and adds widgets from it. */
1316 unit_info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
1317 gtk_widget_set_hexpand(unit_info_box, FALSE);
1318 gtk_box_append(GTK_BOX(avbox), unit_info_box);
1319
1320 /* In edit mode the unit_info_box widget is replaced by the
1321 * editinfobox, so we need to add a ref here so that it is
1322 * not destroyed when removed from its container.
1323 * See editinfobox_refresh() call to replace_widget() */
1324 g_object_ref(unit_info_box);
1325
1326 unit_info_frame = gtk_frame_new("");
1327 gtk_box_append(GTK_BOX(unit_info_box), unit_info_frame);
1328
1329 sw = gtk_scrolled_window_new();
1330 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
1331 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1332 GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
1333 gtk_frame_set_child(GTK_FRAME(unit_info_frame), sw);
1334
1335 label = gtk_label_new(NULL);
1336 gtk_widget_set_hexpand(label, TRUE);
1337 gtk_widget_set_halign(label, GTK_ALIGN_START);
1338 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
1339 gtk_widget_set_margin_start(label, 2);
1340 gtk_widget_set_margin_end(label, 2);
1341 gtk_widget_set_margin_top(label, 2);
1342 gtk_widget_set_margin_bottom(label, 2);
1343 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), label);
1344 unit_info_label = label;
1345
1346 hgrid2 = gtk_grid_new();
1347 gtk_box_append(GTK_BOX(unit_info_box), hgrid2);
1348
1349 table = gtk_grid_new();
1350 gtk_widget_set_margin_bottom(table, 5);
1351 gtk_widget_set_margin_end(table, 5);
1352 gtk_widget_set_margin_start(table, 5);
1353 gtk_widget_set_margin_top(table, 5);
1354 gtk_grid_attach(GTK_GRID(hgrid2), table, grid2_col++, 0, 1, 1);
1355
1356 gtk_grid_set_row_spacing(GTK_GRID(table), 2);
1357 gtk_grid_set_column_spacing(GTK_GRID(table), 2);
1358
1359 unit_pic_table = table;
1360
1361 /* Map canvas, editor toolbar, and scrollbars */
1362
1363 /* The top notebook containing the map view and dialogs. */
1364
1365 top_notebook = gtk_notebook_new();
1366 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(top_notebook), GTK_POS_BOTTOM);
1367 gtk_notebook_set_scrollable(GTK_NOTEBOOK(top_notebook), TRUE);
1368
1369
1370 if (GUI_GTK_OPTION(small_display_layout)) {
1371 gtk_paned_set_start_child(GTK_PANED(paned), top_notebook);
1372 } else if (GUI_GTK_OPTION(message_chat_location) == GUI_GTK_MSGCHAT_MERGED) {
1373 right_vbox = gtk_grid_new();
1374 right_row = 0;
1375 gtk_orientable_set_orientation(GTK_ORIENTABLE(right_vbox),
1376 GTK_ORIENTATION_VERTICAL);
1377
1378 gtk_grid_attach(GTK_GRID(right_vbox), top_notebook, 0, right_row++, 1, 1);
1379 gtk_grid_attach(GTK_GRID(right_vbox), ingame_votebar, 0, right_row++, 1, 1);
1380 gtk_grid_attach(GTK_GRID(hgrid), right_vbox, grid_col++, 0, 1, 1);
1381 } else {
1382 gtk_grid_attach(GTK_GRID(hgrid), top_notebook, grid_col++, 0, 1, 1);
1383 }
1384
1385 map_widget = gtk_grid_new();
1386
1387 mainbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
1388 gtk_box_append(GTK_BOX(mainbox), map_widget);
1389
1390 gtk_box_append(GTK_BOX(mainbox), editgui_get_editbar()->widget);
1391 ebar = editgui_get_editbar()->widget;
1392 gtk_widget_set_margin_bottom(ebar, 4);
1393 gtk_widget_set_margin_end(ebar, 4);
1394 gtk_widget_set_margin_start(ebar, 4);
1395 gtk_widget_set_margin_top(ebar, 4);
1396
1397 label = gtk_label_new(Q_("?noun:View"));
1398 gtk_notebook_append_page(GTK_NOTEBOOK(top_notebook), mainbox, label);
1399
1400 frame = gtk_frame_new(NULL);
1401 gtk_grid_attach(GTK_GRID(map_widget), frame, 0, 0, 1, 1);
1402
1403 map_canvas = gtk_drawing_area_new();
1404 gtk_widget_set_hexpand(map_canvas, TRUE);
1405 gtk_widget_set_vexpand(map_canvas, TRUE);
1406 gtk_widget_set_size_request(map_canvas, 300, 300);
1407 gtk_widget_set_can_focus(map_canvas, TRUE);
1408
1409 gtk_widget_set_focusable(map_canvas, TRUE);
1410
1411#if 0
1412 setup_canvas_color_for_state(GTK_STATE_FLAG_NORMAL);
1413 setup_canvas_color_for_state(GTK_STATE_FLAG_ACTIVE);
1414 setup_canvas_color_for_state(GTK_STATE_FLAG_PRELIGHT);
1415 setup_canvas_color_for_state(GTK_STATE_FLAG_SELECTED);
1416 setup_canvas_color_for_state(GTK_STATE_FLAG_INSENSITIVE);
1417 setup_canvas_color_for_state(GTK_STATE_FLAG_INCONSISTENT);
1418 setup_canvas_color_for_state(GTK_STATE_FLAG_FOCUSED);
1419 setup_canvas_color_for_state(GTK_STATE_FLAG_BACKDROP);
1420#endif /* 0 */
1421
1422 gtk_frame_set_child(GTK_FRAME(frame), map_canvas);
1423
1424 map_horizontal_scrollbar =
1425 gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
1426 gtk_grid_attach(GTK_GRID(map_widget), map_horizontal_scrollbar, 0, 1, 1, 1);
1427
1428 map_vertical_scrollbar =
1429 gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
1430 gtk_grid_attach(GTK_GRID(map_widget), map_vertical_scrollbar, 1, 0, 1, 1);
1431
1432 gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(map_canvas), map_canvas_draw,
1433 NULL, NULL);
1434
1435 mc_controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
1436 g_signal_connect(mc_controller, "pressed",
1437 G_CALLBACK(left_butt_down_mapcanvas), NULL);
1438 g_signal_connect(mc_controller, "released",
1439 G_CALLBACK(left_butt_up_mapcanvas), NULL);
1440 gtk_widget_add_controller(map_canvas, mc_controller);
1441 mc_gesture = gtk_gesture_click_new();
1442 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(mc_gesture), 3);
1443 mc_controller = GTK_EVENT_CONTROLLER(mc_gesture);
1444 g_signal_connect(mc_controller, "pressed",
1445 G_CALLBACK(right_butt_down_mapcanvas), NULL);
1446 g_signal_connect(mc_controller, "released",
1447 G_CALLBACK(right_butt_up_mapcanvas), NULL);
1448 gtk_widget_add_controller(map_canvas, mc_controller);
1449 mc_gesture = gtk_gesture_click_new();
1450 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(mc_gesture), 2);
1451 mc_controller = GTK_EVENT_CONTROLLER(mc_gesture);
1452 g_signal_connect(mc_controller, "pressed",
1453 G_CALLBACK(middle_butt_down_mapcanvas), NULL);
1454 gtk_widget_add_controller(map_canvas, mc_controller);
1455 mc_controller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
1456 g_signal_connect(mc_controller, "scroll",
1457 G_CALLBACK(mouse_scroll_mapcanvas), NULL);
1458 gtk_widget_add_controller(map_canvas, mc_controller);
1459 mc_controller = gtk_event_controller_motion_new();
1460 g_signal_connect(mc_controller, "motion",
1461 G_CALLBACK(move_mapcanvas), NULL);
1462 g_signal_connect(mc_controller, "leave",
1463 G_CALLBACK(leave_mapcanvas), NULL);
1464 gtk_widget_add_controller(map_canvas, mc_controller);
1465
1466 g_signal_connect(map_canvas, "resize",
1467 G_CALLBACK(map_canvas_resize), NULL);
1468
1469 mc_controller = gtk_event_controller_key_new();
1470 g_signal_connect(mc_controller, "key-pressed",
1471 G_CALLBACK(toplevel_key_press_handler), NULL);
1472 gtk_widget_add_controller(toplevel, mc_controller);
1473
1474 /* *** The message window -- this is a detachable widget *** */
1475
1476 if (GUI_GTK_OPTION(message_chat_location) == GUI_GTK_MSGCHAT_MERGED) {
1477 bottom_hpaned = paned;
1478 right_notebook = bottom_notebook = top_notebook;
1479 } else {
1480 GtkWidget *hpaned;
1481
1482 dtach_lowbox = detached_widget_new();
1483 gtk_paned_set_end_child(GTK_PANED(paned), dtach_lowbox);
1484 avbox = detached_widget_fill(dtach_lowbox);
1485
1486 mainbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
1487 if (!GUI_GTK_OPTION(small_display_layout)) {
1488 gtk_box_append(GTK_BOX(mainbox), ingame_votebar);
1489 }
1490 gtk_box_append(GTK_BOX(avbox), mainbox);
1491
1492 if (GUI_GTK_OPTION(small_display_layout)) {
1493 hpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
1494 } else {
1495 hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
1496 }
1497 gtk_box_append(GTK_BOX(mainbox), hpaned);
1498 gtk_widget_set_margin_bottom(hpaned, 4);
1499 gtk_widget_set_margin_end(hpaned, 4);
1500 gtk_widget_set_margin_start(hpaned, 4);
1501 gtk_widget_set_margin_top(hpaned, 4);
1502 bottom_hpaned = hpaned;
1503
1504 bottom_notebook = gtk_notebook_new();
1505 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(bottom_notebook), GTK_POS_TOP);
1506 gtk_notebook_set_scrollable(GTK_NOTEBOOK(bottom_notebook), TRUE);
1507 gtk_paned_set_start_child(GTK_PANED(hpaned), bottom_notebook);
1508
1509 right_notebook = gtk_notebook_new();
1510 g_object_ref(right_notebook);
1511 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(right_notebook), GTK_POS_TOP);
1512 gtk_notebook_set_scrollable(GTK_NOTEBOOK(right_notebook), TRUE);
1513 if (GUI_GTK_OPTION(message_chat_location) == GUI_GTK_MSGCHAT_SPLIT) {
1514 gtk_paned_set_end_child(GTK_PANED(hpaned), right_notebook);
1515 }
1516 }
1517
1518 mainbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
1519
1520 sw = gtk_scrolled_window_new();
1521 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw),
1522 TRUE);
1523 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1524 GTK_POLICY_AUTOMATIC,
1525 GTK_POLICY_ALWAYS);
1526 gtk_box_append(GTK_BOX(mainbox), sw);
1527
1528 label = gtk_label_new(_("Chat"));
1529 gtk_notebook_append_page(GTK_NOTEBOOK(bottom_notebook), mainbox, label);
1530
1531 text = gtk_text_view_new_with_buffer(message_buffer);
1532 gtk_widget_set_hexpand(text, TRUE);
1533 gtk_widget_set_vexpand(text, TRUE);
1534 set_message_buffer_view_link_handlers(text);
1535 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
1536 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), text);
1537
1538 gtk_widget_set_name(text, "chatline");
1539
1540 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
1541 gtk_widget_realize(text);
1542 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 5);
1543
1544 main_message_area = GTK_TEXT_VIEW(text);
1545 if (dtach_lowbox != NULL) {
1546 g_object_set_data(G_OBJECT(dtach_lowbox), "hide-over-reparent", main_message_area);
1547 }
1548
1549 chat_welcome_message(TRUE);
1550
1551 /* The chat line */
1552 view = inputline_toolkit_view_new();
1553 gtk_box_append(GTK_BOX(mainbox), view);
1554 gtk_widget_set_margin_bottom(view, 3);
1555 gtk_widget_set_margin_end(view, 3);
1556 gtk_widget_set_margin_start(view, 3);
1557 gtk_widget_set_margin_top(view, 3);
1558
1559 button = gtk_check_button_new_with_label(_("Allies Only"));
1560 gtk_widget_set_focus_on_click(button, FALSE);
1561 gtk_check_button_set_active(GTK_CHECK_BUTTON(button),
1562 GUI_GTK_OPTION(allied_chat_only));
1563 g_signal_connect(button, "toggled",
1564 G_CALLBACK(allied_chat_button_toggled), NULL);
1565 inputline_toolkit_view_append_button(view, button);
1566 allied_chat_toggle_button = button;
1567
1568 button = gtk_button_new_with_label(_("Clear links"));
1569 g_signal_connect(button, "clicked",
1570 G_CALLBACK(link_marks_clear_all), NULL);
1571 inputline_toolkit_view_append_button(view, button);
1572
1573 /* Other things to take care of */
1574
1575 gtk_widget_show(gtk_window_get_child(GTK_WINDOW(toplevel)));
1576
1577 if (GUI_GTK_OPTION(enable_tabs)) {
1578 meswin_dialog_popup(FALSE);
1579 }
1580
1581 gtk_notebook_set_current_page(GTK_NOTEBOOK(top_notebook), 0);
1582 gtk_notebook_set_current_page(GTK_NOTEBOOK(bottom_notebook), 0);
1583
1584 if (!GUI_GTK_OPTION(map_scrollbars)) {
1585 gtk_widget_hide(map_horizontal_scrollbar);
1586 gtk_widget_hide(map_vertical_scrollbar);
1587 }
1588}
1589
1590/**********************************************************************/
1593 static void g_log_to_freelog_cb(const gchar *log_domain,
1594 GLogLevelFlags log_level,
1595 const gchar *message,
1596 gpointer user_data)
1597{
1598 enum log_level fllvl = LOG_ERROR;
1599
1600 switch (log_level) {
1601 case G_LOG_LEVEL_DEBUG:
1602 fllvl = LOG_DEBUG;
1603 break;
1604 case G_LOG_LEVEL_WARNING:
1605 fllvl = LOG_WARN;
1606 break;
1607 default:
1608 break;
1609 }
1610
1611 if (log_domain != NULL) {
1612 log_base(fllvl, "%s: %s", log_domain, message);
1613 } else {
1614 log_base(fllvl, "%s", message);
1615 }
1616}
1617
1618/**********************************************************************/
1621 static GLogWriterOutput g_log_writer_to_freelog_cb(GLogLevelFlags log_level,
1622 const GLogField *fields,
1623 gsize n_fields,
1624 gpointer user_data)
1625{
1626 /* No need to have formatter of our own - let's use glib's default one. */
1627 gchar *out = g_log_writer_format_fields(log_level, fields, n_fields, FALSE);
1628
1629 g_log_to_freelog_cb(NULL, log_level, out, NULL);
1630
1631 return G_LOG_WRITER_HANDLED;
1632}
1633
1634/**********************************************************************/
1637 static void set_g_log_callback_domain(const char *domain)
1638{
1639 g_log_set_handler(domain,
1640 G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING
1641 | G_LOG_LEVEL_MASK
1642 | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
1643 g_log_to_freelog_cb, NULL);
1644}
1645
1646/**********************************************************************/
1649 static void set_g_log_callbacks(void)
1650{
1651 /* Old API, still used by many log producers */
1652 g_log_set_default_handler(g_log_to_freelog_cb, NULL);
1653
1654 set_g_log_callback_domain("Gtk");
1655 set_g_log_callback_domain("Gdk");
1656 set_g_log_callback_domain("Glib");
1657
1658 /* glib >= 2.50 API */
1659 g_log_set_writer_func(g_log_writer_to_freelog_cb, NULL, NULL);
1660}
1661
1662/**********************************************************************/
1665 void ui_init(void)
1666{
1667 log_set_callback(log_callback_utf8);
1668 set_g_log_callbacks();
1669 set_frame_by_frame_animation();
1670 zoom_phase_set(FALSE);
1671 zoom_set_steps(zoom_steps_custom);
1672}
1673
1674/**********************************************************************/
1677 int main(int argc, char **argv)
1678{
1679 return client_main(argc, argv, FALSE);
1680}
1681
1682/**********************************************************************/
1685 static void migrate_options_from_gtk2(void)
1686{
1687 log_normal(_("Migrating options from gtk2 to gtk3 client"));
1688
1689#define MIGRATE_OPTION(opt) gui_options.gui_gtk3_##opt = gui_options.gui_gtk2_##opt;
1690#define MIGRATE_STR_OPTION(opt) \
1691 strncpy(gui_options.gui_gtk3_##opt, gui_options.gui_gtk2_##opt, \
1692 sizeof(gui_options.gui_gtk3_##opt));
1693
1694 /* Default theme name is never migrated */
1695 /* 'fullscreen', 'small_display_layout', and 'message_chat_location'
1696 * not migrated, as (unlike Gtk2), Gtk3-client tries to pick better
1697 * defaults for these in fresh installations based on screen size (see
1698 * adjust_default_options()); so user is probably better served by
1699 * getting these adaptive defaults than whatever they had for Gtk2.
1700 * Since 'fullscreen' isn't migrated, we don't need to worry about
1701 * preserving gui_gtk2_migrated_from_2_5 either. */
1702 MIGRATE_OPTION(map_scrollbars);
1703 MIGRATE_OPTION(dialogs_on_top);
1704 MIGRATE_OPTION(show_task_icons);
1705 MIGRATE_OPTION(enable_tabs);
1706 MIGRATE_OPTION(show_chat_message_time);
1707 MIGRATE_OPTION(new_messages_go_to_top);
1708 MIGRATE_OPTION(show_message_window_buttons);
1709 MIGRATE_OPTION(metaserver_tab_first);
1710 MIGRATE_OPTION(allied_chat_only);
1711 MIGRATE_OPTION(mouse_over_map_focus);
1712 MIGRATE_OPTION(chatline_autocompletion);
1713 MIGRATE_OPTION(citydlg_xsize);
1714 MIGRATE_OPTION(citydlg_ysize);
1715 MIGRATE_OPTION(popup_tech_help);
1716
1717 MIGRATE_STR_OPTION(font_city_label);
1718 MIGRATE_STR_OPTION(font_notify_label);
1719 MIGRATE_STR_OPTION(font_spaceship_label);
1720 MIGRATE_STR_OPTION(font_help_label);
1721 MIGRATE_STR_OPTION(font_help_link);
1722 MIGRATE_STR_OPTION(font_help_text);
1723 MIGRATE_STR_OPTION(font_chatline);
1724 MIGRATE_STR_OPTION(font_beta_label);
1725 MIGRATE_STR_OPTION(font_small);
1726 MIGRATE_STR_OPTION(font_comment_label);
1727 MIGRATE_STR_OPTION(font_city_names);
1728 MIGRATE_STR_OPTION(font_city_productions);
1729 MIGRATE_STR_OPTION(font_reqtree_text);
1730
1731#undef MIGRATE_OPTION
1732#undef MIGRATE_STR_OPTION
1733
1734 gui_options.gui_gtk3_migrated_from_gtk2 = TRUE;
1735}
1736
1737/**********************************************************************/
1740 static void migrate_options_from_gtk3(void)
1741{
1742 log_normal(_("Migrating options from gtk3 to gtk3.22 client"));
1743
1744#define MIGRATE_OPTION(opt) gui_options.gui_gtk3_22_##opt = gui_options.gui_gtk3_##opt;
1745#define MIGRATE_STR_OPTION(opt) \
1746 strncpy(gui_options.gui_gtk3_22_##opt, gui_options.gui_gtk3_##opt, \
1747 sizeof(gui_options.gui_gtk3_22_##opt));
1748
1749 /* Default theme name is never migrated */
1750
1751 /* Simulate gui-gtk3's migrate_options_from_2_5() */
1752 if (!gui_options.gui_gtk3_migrated_from_2_5) {
1753 log_normal(_("Migrating gtk3-client options from freeciv-2.5 options."));
1754 gui_options.gui_gtk3_fullscreen = gui_options.migrate_fullscreen;
1755 gui_options.gui_gtk3_migrated_from_2_5 = TRUE;
1756 }
1757
1758 MIGRATE_OPTION(fullscreen);
1759 MIGRATE_OPTION(map_scrollbars);
1760 MIGRATE_OPTION(dialogs_on_top);
1761 MIGRATE_OPTION(show_task_icons);
1762 MIGRATE_OPTION(enable_tabs);
1763 MIGRATE_OPTION(show_chat_message_time);
1764 MIGRATE_OPTION(new_messages_go_to_top);
1765 MIGRATE_OPTION(show_message_window_buttons);
1766 MIGRATE_OPTION(metaserver_tab_first);
1767 MIGRATE_OPTION(allied_chat_only);
1768 MIGRATE_OPTION(message_chat_location);
1769 MIGRATE_OPTION(small_display_layout);
1770 MIGRATE_OPTION(mouse_over_map_focus);
1771 MIGRATE_OPTION(chatline_autocompletion);
1772 MIGRATE_OPTION(citydlg_xsize);
1773 MIGRATE_OPTION(citydlg_ysize);
1774 MIGRATE_OPTION(popup_tech_help);
1775
1776 MIGRATE_STR_OPTION(font_city_label);
1777 MIGRATE_STR_OPTION(font_notify_label);
1778 MIGRATE_STR_OPTION(font_spaceship_label);
1779 MIGRATE_STR_OPTION(font_help_label);
1780 MIGRATE_STR_OPTION(font_help_link);
1781 MIGRATE_STR_OPTION(font_help_text);
1782 MIGRATE_STR_OPTION(font_chatline);
1783 MIGRATE_STR_OPTION(font_beta_label);
1784 MIGRATE_STR_OPTION(font_small);
1785 MIGRATE_STR_OPTION(font_comment_label);
1786 MIGRATE_STR_OPTION(font_city_names);
1787 MIGRATE_STR_OPTION(font_city_productions);
1788 MIGRATE_STR_OPTION(font_reqtree_text);
1789
1790#undef MIGRATE_OPTION
1791#undef MIGRATE_STR_OPTION
1792
1793 gui_options.gui_gtk3_22_migrated_from_gtk3 = TRUE;
1794}
1795
1796/**********************************************************************/
1799 static void migrate_options_from_gtk3_22(void)
1800{
1801 log_normal(_("Migrating options from gtk3.22 to gtk4 client"));
1802
1803#define MIGRATE_OPTION(opt) GUI_GTK_OPTION(opt) = gui_options.gui_gtk3_22_##opt;
1804#define MIGRATE_STR_OPTION(opt) \
1805 strncpy(GUI_GTK_OPTION(opt), gui_options.gui_gtk3_22_##opt, \
1806 sizeof(GUI_GTK_OPTION(opt)));
1807
1808 /* Default theme name is never migrated */
1809 MIGRATE_OPTION(fullscreen);
1810 MIGRATE_OPTION(map_scrollbars);
1811 MIGRATE_OPTION(dialogs_on_top);
1812 MIGRATE_OPTION(show_task_icons);
1813 MIGRATE_OPTION(enable_tabs);
1814 MIGRATE_OPTION(show_chat_message_time);
1815 MIGRATE_OPTION(new_messages_go_to_top);
1816 MIGRATE_OPTION(show_message_window_buttons);
1817 MIGRATE_OPTION(metaserver_tab_first);
1818 MIGRATE_OPTION(allied_chat_only);
1819 MIGRATE_OPTION(message_chat_location);
1820 MIGRATE_OPTION(small_display_layout);
1821 MIGRATE_OPTION(mouse_over_map_focus);
1822 MIGRATE_OPTION(chatline_autocompletion);
1823 MIGRATE_OPTION(citydlg_xsize);
1824 MIGRATE_OPTION(citydlg_ysize);
1825 MIGRATE_OPTION(popup_tech_help);
1826
1827 MIGRATE_STR_OPTION(font_city_label);
1828 MIGRATE_STR_OPTION(font_notify_label);
1829 MIGRATE_STR_OPTION(font_spaceship_label);
1830 MIGRATE_STR_OPTION(font_help_label);
1831 MIGRATE_STR_OPTION(font_help_link);
1832 MIGRATE_STR_OPTION(font_help_text);
1833 MIGRATE_STR_OPTION(font_chatline);
1834 MIGRATE_STR_OPTION(font_beta_label);
1835 MIGRATE_STR_OPTION(font_small);
1836 MIGRATE_STR_OPTION(font_comment_label);
1837 MIGRATE_STR_OPTION(font_city_names);
1838 MIGRATE_STR_OPTION(font_city_productions);
1839 MIGRATE_STR_OPTION(font_reqtree_text);
1840
1841#undef MIGRATE_OPTION
1842#undef MIGRATE_STR_OPTION
1843
1844 GUI_GTK_OPTION(migrated_from_gtk3_22) = TRUE;
1845}
1846
1847/**********************************************************************/
1850 int ui_main(int argc, char **argv)
1851{
1852 if (parse_options(argc, argv)) {
1853 /* The locale has already been set in init_nls() and the windows-specific
1854 * locale logic in gtk_init() causes problems with zh_CN (see PR#39475) */
1855 gtk_disable_setlocale();
1856
1857 if (!gtk_init_check()) {
1858 log_fatal(_("Failed to open graphical mode."));
1859 return EXIT_FAILURE;
1860 }
1861
1862 menus_set_initial_toggle_values();
1863
1864 gui_up = TRUE;
1865 fc_app = gtk_application_new(NULL, 0);
1866 g_signal_connect(fc_app, "activate", G_CALLBACK(activate_gui), NULL);
1867 g_application_run(G_APPLICATION(fc_app), 0, NULL);
1868 gui_up = FALSE;
1869
1870 destroy_server_scans();
1871 free_mapcanvas_and_overview();
1872 spaceship_dialog_done();
1873 intel_dialog_done();
1874 citizens_dialog_done();
1875 luaconsole_dialog_done();
1876 happiness_dialog_done();
1877 diplomacy_dialog_done();
1878 cma_fe_done();
1879 free_unit_table();
1880
1881 /* We have extra ref for unit_info_box that has protected
1882 * it from getting destroyed when editinfobox_refresh()
1883 * moves widgets around. Free that extra ref here. */
1884 g_object_unref(unit_info_box);
1885 if (empty_unit_paintable != NULL) {
1886 g_object_unref(empty_unit_paintable);
1887 }
1888
1889 editgui_free();
1890 gtk_window_destroy(GTK_WINDOW(toplevel));
1891 message_buffer = NULL; /* Result of destruction of everything */
1892 tileset_free_tiles(tileset);
1893 }
1894
1895 return EXIT_SUCCESS;
1896}
1897
1898/**********************************************************************/
1901 static void activate_gui(GtkApplication *app, gpointer data)
1902{
1903 PangoFontDescription *toplevel_font_name;
1904 guint sig;
1905 char window_name[1024];
1906
1907 toplevel = gtk_application_window_new(app);
1908 if (vmode.width > 0 && vmode.height > 0) {
1909 gtk_window_set_default_size(GTK_WINDOW(toplevel),
1910 vmode.width, vmode.height);
1911 }
1912
1913 gtk_widget_realize(toplevel);
1914 gtk_widget_set_name(toplevel, "Freeciv");
1915
1916 help_system_init();
1917
1918 dlg_tab_provider_prepare();
1919
1920 if (gui_options.first_boot) {
1921 adjust_default_options();
1922 /* We're using fresh defaults for this version of this client,
1923 * so prevent any future migrations from other clients / versions */
1924 GUI_GTK_OPTION(migrated_from_gtk3_22) = TRUE;
1925 /* Avoid also marking previous Gtk clients as migrated, so that
1926 * they can have their own run of their adjust_default_options() if
1927 * they are ever run (as a side effect of Gtk2->Gtk3 migration). */
1928 } else {
1929 if (!GUI_GTK_OPTION(migrated_from_gtk3_22)) {
1930 if (!gui_options.gui_gtk3_22_migrated_from_gtk3) {
1931 if (!gui_options.gui_gtk3_migrated_from_gtk2) {
1932 migrate_options_from_gtk2();
1933 /* We want a fresh look at screen-size-related options after Gtk2 */
1934 adjust_default_options();
1935 /* We don't ever want to consider pre-2.6 fullscreen option again
1936 * (even for gui-gtk3) */
1937 gui_options.gui_gtk3_migrated_from_2_5 = TRUE;
1938 }
1939 migrate_options_from_gtk3();
1940 }
1941 migrate_options_from_gtk3_22();
1942 }
1943 }
1944
1945 if (GUI_GTK_OPTION(fullscreen)) {
1946 gtk_window_fullscreen(GTK_WINDOW(toplevel));
1947 }
1948
1949 fc_snprintf(window_name, sizeof(window_name), _("Freeciv (%s)"), GUI_NAME_SHORT);
1950 gtk_window_set_title(GTK_WINDOW(toplevel), window_name);
1951
1952 g_signal_connect(toplevel, "close-request",
1953 G_CALLBACK(quit_dialog_callback), NULL);
1954
1955 /* Disable GTK cursor key focus movement */
1956 sig = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
1957 g_signal_handlers_disconnect_matched(toplevel, G_SIGNAL_MATCH_ID, sig,
1958 0, 0, 0, 0);
1959 g_signal_connect(toplevel, "move-focus", G_CALLBACK(toplevel_focus), NULL);
1960
1961 options_iterate(client_optset, poption) {
1962 if (OT_FONT == option_type(poption)) {
1963 /* Force to call the appropriate callback. */
1964 option_changed(poption);
1965 }
1966 } options_iterate_end;
1967
1968 toplevel_font_name = pango_context_get_font_description(
1969 gtk_widget_get_pango_context(toplevel));
1970
1971 if (NULL == city_names_style) {
1972 city_names_style = pango_font_description_copy(toplevel_font_name);
1973 log_error("city_names_style should have been set by options.");
1974 }
1975 if (NULL == city_productions_style) {
1976 city_productions_style = pango_font_description_copy(toplevel_font_name);
1977 log_error("city_productions_style should have been set by options.");
1978 }
1979 if (NULL == reqtree_text_style) {
1980 reqtree_text_style = pango_font_description_copy(toplevel_font_name);
1981 log_error("reqtree_text_style should have been set by options.");
1982 }
1983
1984 tileset_init(tileset);
1985 tileset_load_tiles(tileset);
1986
1987 /* keep the icon of the executable on Windows (see PR#36491) */
1988#ifndef FREECIV_MSWINDOWS
1989 {
1990 /* Only call this after tileset_load_tiles is called. */
1991 gtk_window_set_icon_name(GTK_WINDOW(toplevel), "freeciv");
1992 }
1993#endif /* FREECIV_MSWINDOWS */
1994
1995 setup_widgets();
1996 load_cursors();
1997 cma_fe_init();
1998 diplomacy_dialog_init();
1999 luaconsole_dialog_init();
2000 happiness_dialog_init();
2001 citizens_dialog_init();
2002 intel_dialog_init();
2003 spaceship_dialog_init();
2004 chatline_init();
2005 init_mapcanvas_and_overview();
2006
2007 tileset_use_preferred_theme(tileset);
2008
2009 gtk_widget_show(toplevel);
2010
2011 /* assumes toplevel showing */
2012 set_client_state(C_S_DISCONNECTED);
2013
2014 /* assumes client_state is set */
2015 timer_id = g_timeout_add(TIMER_INTERVAL, timer_callback, NULL);
2016}
2017
2018/**********************************************************************/
2021 bool is_gui_up(void)
2022{
2023 return gui_up;
2024}
2025
2026/**********************************************************************/
2029 void ui_exit(void)
2030{
2031 if (message_buffer != NULL) {
2032 g_object_unref(message_buffer);
2033 message_buffer = NULL;
2034 }
2035}
2036
2037/**********************************************************************/
2040 enum gui_type get_gui_type(void)
2041{
2042 return GUI_GTK4;
2043}
2044
2045/**********************************************************************/
2048 void sound_bell(void)
2049{
2050 gdk_display_beep(gdk_display_get_default());
2051}
2052
2053/**********************************************************************/
2059 void set_unit_icon(int idx, struct unit *punit)
2060{
2061 GtkWidget *w;
2062
2063 fc_assert_ret(idx >= -1 && idx < num_units_below);
2064
2065 if (idx == -1) {
2066 w = unit_pic;
2067 unit_id_top = punit ? punit->id : 0;
2068 } else {
2069 w = unit_below_pic[idx];
2070 unit_ids[idx] = punit ? punit->id : 0;
2071 }
2072
2073 if (!w) {
2074 return;
2075 }
2076
2077 if (punit) {
2078 put_unit_picture(punit, GTK_PICTURE(w), -1);
2079 } else {
2080 if (empty_unit_paintable == NULL) {
2081 /* FIXME: Use proper icon height instead of hardcoded 50 */
2082 empty_unit_paintable = gdk_paintable_new_empty(tileset_tile_width(tileset), 50);
2083
2084 /* Add ref to avoid it getting destroyed along any single parent widget. */
2085 g_object_ref(empty_unit_paintable);
2086 }
2087 gtk_picture_set_paintable(GTK_PICTURE(w), empty_unit_paintable);
2088 }
2089}
2090
2091/**********************************************************************/
2096 void set_unit_icons_more_arrow(bool onoff)
2097{
2098 static bool showing = FALSE;
2099
2100 if (!more_arrow) {
2101 return;
2102 }
2103
2104 if (onoff && !showing) {
2105 gtk_widget_show(more_arrow);
2106 showing = TRUE;
2107 } else if (!onoff && showing) {
2108 gtk_widget_hide(more_arrow);
2109 showing = FALSE;
2110 }
2111}
2112
2113/**********************************************************************/
2119 void real_focus_units_changed(void)
2120{
2121 goto_dialog_focus_units_changed();
2122}
2123
2124/**********************************************************************/
2128 static gboolean select_unit_pic_callback(GtkGestureClick *gesture, int n_press,
2129 double x, double y, gpointer data)
2130{
2131 int i = GPOINTER_TO_INT(data);
2132 struct unit *punit;
2133
2134 if (i == -1) {
2135 punit = game_unit_by_number(unit_id_top);
2136 if (punit && unit_is_in_focus(punit)) {
2137 /* Clicking on the currently selected unit will center it. */
2138 center_tile_mapcanvas(unit_tile(punit));
2139 }
2140 return TRUE;
2141 }
2142
2143 if (unit_ids[i] == 0) { /* No unit displayed at this place */
2144 return TRUE;
2145 }
2146
2147 punit = game_unit_by_number(unit_ids[i]);
2148 if (NULL != punit && unit_owner(punit) == client_player()) {
2149 /* Unit shouldn't be NULL but may be owned by an ally. */
2150 unit_focus_set(punit);
2151 }
2152
2153 return TRUE;
2154}
2155
2156/**********************************************************************/
2160 static gboolean select_more_arrow_callback(GtkGestureClick *gesture, int n_press,
2161 double x, double y, gpointer data)
2162{
2163 struct unit *punit = game_unit_by_number(unit_id_top);
2164
2165 if (punit) {
2166 unit_select_dialog_popup(unit_tile(punit));
2167 }
2168
2169 return TRUE;
2170}
2171
2172/**********************************************************************/
2175 static void info_popup_closed(GtkWidget *self, gpointer data)
2176{
2177 gtk_widget_unparent(self);
2178}
2179
2180/**********************************************************************/
2183 static gboolean show_info_popup(GtkGestureClick *gesture, int n_press,
2184 double x, double y, gpointer data)
2185{
2186 GtkWidget *p;
2187 GtkWidget *child;
2188 GtkWidget *frame = GTK_WIDGET(data);
2189
2190 p = gtk_popover_new();
2191
2192 gtk_widget_set_parent(p, frame);
2193 child = gtk_label_new(get_info_label_text_popup());
2194 gtk_popover_set_child(GTK_POPOVER(p), child);
2195 g_signal_connect(p, "closed",
2196 G_CALLBACK(info_popup_closed), NULL);
2197 gtk_popover_popup(GTK_POPOVER(p));
2198
2199 return TRUE;
2200}
2201
2202/**********************************************************************/
2205 static void end_turn_callback(GtkWidget *w, gpointer data)
2206{
2207 gtk_widget_set_sensitive(turn_done_button, FALSE);
2208 user_ended_turn();
2209}
2210
2211/**********************************************************************/
2214 static gboolean get_net_input(GIOChannel *source, GIOCondition condition,
2215 gpointer data)
2216{
2217 input_from_server(g_io_channel_unix_get_fd(source));
2218
2219 return TRUE;
2220}
2221
2222/**********************************************************************/
2225 static void set_wait_for_writable_socket(struct connection *pc,
2226 bool socket_writable)
2227{
2228 static bool previous_state = FALSE;
2229
2230 fc_assert_ret(pc == &client.conn);
2231
2232 if (previous_state == socket_writable)
2233 return;
2234
2235 log_debug("set_wait_for_writable_socket(%d)", socket_writable);
2236
2237 g_source_remove(srv_id);
2238 srv_id = g_io_add_watch(srv_channel,
2239 G_IO_IN | (socket_writable ? G_IO_OUT : 0) | G_IO_ERR,
2240 get_net_input,
2241 NULL);
2242
2243 previous_state = socket_writable;
2244}
2245
2246/**********************************************************************/
2250 void add_net_input(int sock)
2251{
2252#ifdef FREECIV_MSWINDOWS
2253 srv_channel = g_io_channel_win32_new_socket(sock);
2254#else
2255 srv_channel = g_io_channel_unix_new(sock);
2256#endif
2257 srv_id = g_io_add_watch(srv_channel,
2258 G_IO_IN | G_IO_ERR,
2259 get_net_input,
2260 NULL);
2261 client.conn.notify_of_writable_data = set_wait_for_writable_socket;
2262}
2263
2264/**********************************************************************/
2268 void remove_net_input(void)
2269{
2270 g_source_remove(srv_id);
2271 g_io_channel_unref(srv_channel);
2272 gtk_widget_set_cursor(toplevel, NULL);
2273}
2274
2275/**********************************************************************/
2279 static void quit_dialog_response(GtkWidget *dialog, gint response)
2280{
2281 gtk_window_destroy(GTK_WINDOW(dialog));
2282 if (response == GTK_RESPONSE_YES) {
2283 start_quitting();
2284 if (client.conn.used) {
2285 disconnect_from_server();
2286 }
2287 quit_gtk_main();
2288 }
2289}
2290
2291/**********************************************************************/
2294 void quit_gtk_main(void)
2295{
2296 /* Quit gtk main loop. After this it will return to finish
2297 * ui_main() */
2298
2299 g_application_quit(G_APPLICATION(fc_app));
2300}
2301
2302/**********************************************************************/
2306 void popup_quit_dialog(void)
2307{
2308 static GtkWidget *dialog;
2309
2310 if (!dialog) {
2311 dialog = gtk_message_dialog_new(NULL,
2312 0,
2313 GTK_MESSAGE_WARNING,
2314 GTK_BUTTONS_YES_NO,
2315 _("Are you sure you want to quit?"));
2316 setup_dialog(dialog, toplevel);
2317
2318 g_signal_connect(dialog, "response",
2319 G_CALLBACK(quit_dialog_response), NULL);
2320 g_signal_connect(dialog, "destroy",
2321 G_CALLBACK(widget_destroyed), &dialog);
2322 }
2323
2324 gtk_window_present(GTK_WINDOW(dialog));
2325}
2326
2327/**********************************************************************/
2330 static gboolean quit_dialog_callback(void)
2331{
2332 popup_quit_dialog();
2333 /* Stop emission of event. */
2334 return TRUE;
2335}
2336
2337struct callback {
2338 void (*callback)(void *data);
2339 void *data;
2340};
2341
2342/**********************************************************************/
2345 static gboolean idle_callback_wrapper(gpointer data)
2346{
2347 struct callback *cb = data;
2348
2349 (cb->callback)(cb->data);
2350 free(cb);
2351
2352 return FALSE;
2353}
2354
2355/**********************************************************************/
2360 void add_idle_callback(void (callback)(void *), void *data)
2361{
2362 struct callback *cb = fc_malloc(sizeof(*cb));
2363
2364 cb->callback = callback;
2365 cb->data = data;
2366 g_idle_add(idle_callback_wrapper, cb);
2367}
2368
2369/**********************************************************************/
2372 void animation_idle_cb(void *data)
2373{
2374 if (get_current_client_page() == PAGE_GAME) {
2375 update_animation();
2376 add_idle_callback(animation_idle_cb, NULL);
2377 }
2378}
2379
2380/**********************************************************************/
2384 static void allied_chat_only_callback(struct option *poption)
2385{
2386 GtkWidget *button;
2387
2388 button = allied_chat_toggle_button;
2389 fc_assert_ret(button != NULL);
2390 fc_assert_ret(GTK_IS_CHECK_BUTTON(button));
2391
2392 gtk_check_button_set_active(GTK_CHECK_BUTTON(button),
2393 option_bool_get(poption));
2394}
2395
2396/**********************************************************************/
2399 void fullscreen_opt_refresh(struct option *poption)
2400{
2401 if (GUI_GTK_OPTION(fullscreen)) {
2402 gtk_window_fullscreen(GTK_WINDOW(toplevel));
2403 } else {
2404 gtk_window_unfullscreen(GTK_WINDOW(toplevel));
2405 }
2406}
2407
2408/**********************************************************************/
2411 static void apply_city_names_font(struct option *poption)
2412{
2413 gui_update_font_full(option_font_target(poption),
2414 option_font_get(poption),
2415 &city_names_style);
2416 update_city_descriptions();
2417}
2418
2419/**********************************************************************/
2422 static void apply_city_productions_font(struct option *poption)
2423{
2424 gui_update_font_full(option_font_target(poption),
2425 option_font_get(poption),
2426 &city_productions_style);
2427 update_city_descriptions();
2428}
2429
2430/**********************************************************************/
2433 static void apply_reqtree_text_font(struct option *poption)
2434{
2435 gui_update_font_full(option_font_target(poption),
2436 option_font_get(poption),
2437 &reqtree_text_style);
2438 science_report_dialog_redraw();
2439}
2440
2441/**********************************************************************/
2445 void options_extra_init(void)
2446{
2447
2448 struct option *poption;
2449
2450#define option_var_set_callback(var, callback) \
2451 if ((poption = optset_option_by_name(client_optset, GUI_GTK_OPTION_STR(var)))) { \
2452 option_set_changed_callback(poption, callback); \
2453 } else { \
2454 log_error("Didn't find option %s!", GUI_GTK_OPTION_STR(var)); \
2455 }
2456
2457 option_var_set_callback(allied_chat_only,
2458 allied_chat_only_callback);
2459 option_var_set_callback(fullscreen,
2460 fullscreen_opt_refresh);
2461
2462 option_var_set_callback(font_city_names,
2463 apply_city_names_font);
2464 option_var_set_callback(font_city_productions,
2465 apply_city_productions_font);
2466 option_var_set_callback(font_reqtree_text,
2467 apply_reqtree_text_font);
2468#undef option_var_set_callback
2469}
2470
2471/**********************************************************************/
2475 void refresh_chat_buttons(void)
2476{
2477 GtkWidget *button;
2478
2479 button = allied_chat_toggle_button;
2480 fc_assert_ret(button != NULL);
2481 fc_assert_ret(GTK_IS_CHECK_BUTTON(button));
2482
2483 /* Hide the "Allies Only" button for local games. */
2484 if (is_server_running()) {
2485 gtk_widget_hide(button);
2486 } else {
2487 gtk_widget_show(button);
2488 gtk_check_button_set_active(GTK_CHECK_BUTTON(button),
2489 GUI_GTK_OPTION(allied_chat_only));
2490 }
2491}
2492
2493/**********************************************************************/
2496 static void allied_chat_button_toggled(GtkToggleButton *button,
2497 gpointer user_data)
2498{
2499 GUI_GTK_OPTION(allied_chat_only) = gtk_toggle_button_get_active(button);
2500}
2501
2502/**********************************************************************/
2505 void insert_client_build_info(char *outbuf, size_t outlen)
2506{
2507 cat_snprintf(outbuf, outlen, _("\nBuilt against gtk %d.%d.%d, using %d.%d.%d"
2508 "\nBuilt against glib %d.%d.%d, using %d.%d.%d"),
2509 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION,
2510 gtk_get_major_version(), gtk_get_minor_version(), gtk_get_micro_version(),
2511 GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
2512 glib_major_version, glib_minor_version, glib_micro_version);
2513}
2514
2515/**********************************************************************/
2519 static bool monitor_size(GdkRectangle *rect_p)
2520{
2521 GdkDisplay *display;
2522 GdkMonitor *monitor;
2523
2524 display = gdk_display_get_default();
2525 if (!display) {
2526 return FALSE;
2527 }
2528
2529 monitor = g_list_model_get_item(gdk_display_get_monitors(display), 0);
2530
2531 if (!monitor) {
2532 return FALSE;
2533 }
2534
2535 gdk_monitor_get_geometry(monitor, rect_p);
2536
2537 return TRUE;
2538}
2539
2540/**********************************************************************/
2543 int screen_width(void)
2544{
2545 GdkRectangle rect;
2546
2547 if (vmode.width > 0) {
2548 return vmode.width;
2549 }
2550
2551 if (monitor_size(&rect)) {
2552 return rect.width;
2553 } else {
2554 return 0;
2555 }
2556}
2557
2558/**********************************************************************/
2561 int screen_height(void)
2562{
2563 GdkRectangle rect;
2564
2565 if (vmode.height > 0) {
2566 return vmode.height;
2567 }
2568
2569 if (monitor_size(&rect)) {
2570 return rect.height;
2571 } else {
2572 return 0;
2573 }
2574}
2575
2576/**********************************************************************/
2579 struct video_mode *resolution_request_get(void)
2580{
2581 if (vmode.width > 0 && vmode.height > 0) {
2582 return &vmode;
2583 }
2584
2585 return NULL;
2586}
2587
2588/**********************************************************************/
2591 static void adjust_default_options(void)
2592{
2593 int scr_height = screen_height();
2594
2595 if (scr_height > 0) {
2596 /* Adjust these options only if we do know the screen height. */
2597
2598 if (scr_height <= 480) {
2599 /* Freeciv is practically unusable outside fullscreen mode in so
2600 * small display */
2601 log_verbose("Changing default to fullscreen due to very small screen");
2602 GUI_GTK_OPTION(fullscreen) = TRUE;
2603 }
2604 if (scr_height < 1024) {
2605 /* This is a small display */
2606 log_verbose("Defaulting to small widget layout due to small screen");
2607 GUI_GTK_OPTION(small_display_layout) = TRUE;
2608 log_verbose("Defaulting to merged messages/chat due to small screen");
2609 GUI_GTK_OPTION(message_chat_location) = GUI_GTK_MSGCHAT_MERGED;
2610 }
2611 }
2612}
2613
2614/**********************************************************************/
2617GtkApplication *gui_app(void)
2618{
2619 return fc_app;
2620}
height
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
width
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
chat_welcome_message
void chat_welcome_message(bool gui_has_copying_mitem)
Definition chatline_common.c:177
self
static struct ai_type * self
Definition classicai.c:46
client_is_observer
bool client_is_observer(void)
Definition client_main.c:1086
real_timer_callback
double real_timer_callback(void)
Definition client_main.c:1183
client_main
int client_main(int argc, char *argv[], bool postpone_tileset)
Definition client_main.c:344
user_ended_turn
void user_ended_turn(void)
Definition client_main.c:801
client
struct civclient client
Definition client_main.c:149
start_quitting
void start_quitting(void)
Definition client_main.c:1645
set_client_state
void set_client_state(enum client_states newstate)
Definition client_main.c:847
can_client_change_view
bool can_client_change_view(void)
Definition client_main.c:1313
client_main.h
client_player
#define client_player()
Definition client_main.h:106
TIMER_INTERVAL
#define TIMER_INTERVAL
Definition client_main.h:30
C_S_DISCONNECTED
@ C_S_DISCONNECTED
Definition client_main.h:45
buy_production_in_selected_cities
void buy_production_in_selected_cities(void)
Definition climisc.c:1299
client_warming_sprite
struct sprite * client_warming_sprite(void)
Definition climisc.c:371
client_cooling_sprite
struct sprite * client_cooling_sprite(void)
Definition climisc.c:388
client_research_sprite
struct sprite * client_research_sprite(void)
Definition climisc.c:348
client_government_sprite
struct sprite * client_government_sprite(void)
Definition climisc.c:406
climisc.h
input_from_server
void input_from_server(int fd)
Definition clinet.c:406
disconnect_from_server
void disconnect_from_server(void)
Definition clinet.c:305
clinet.h
get_color
struct color * get_color(const struct tileset *t, enum color_std stdcolor)
Definition colors_common.c:100
is_server_running
bool is_server_running(void)
Definition connectdlg_common.c:124
connectdlg_common.h
key_recall_previous_focus_unit
void key_recall_previous_focus_unit(void)
Definition control.c:3134
unit_is_in_focus
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:384
key_cancel_action
void key_cancel_action(void)
Definition control.c:3073
num_units_below
int num_units_below
Definition control.c:76
unit_focus_set
void unit_focus_set(struct unit *punit)
Definition control.c:502
get_units_in_focus
struct unit_list * get_units_in_focus(void)
Definition control.c:177
key_end_turn
void key_end_turn(void)
Definition control.c:3126
update_unit_pix_label
void update_unit_pix_label(struct unit_list *punitlist)
Definition control.c:966
key_unit_move
void key_unit_move(enum direction8 gui_dir)
Definition control.c:3155
hover_state
enum cursor_hover_state hover_state
Definition control.c:89
head_of_units_in_focus
struct unit * head_of_units_in_focus(void)
Definition control.c:406
get_num_units_in_focus
int get_num_units_in_focus(void)
Definition control.c:185
control_mouse_cursor
void control_mouse_cursor(struct tile *ptile)
Definition control.c:1188
key_center_capital
void key_center_capital(void)
Definition control.c:3109
control.h
MAX_NUM_UNITS_BELOW
#define MAX_NUM_UNITS_BELOW
Definition control.h:285
HOVER_NONE
@ HOVER_NONE
Definition control.h:26
dataio.h
punit
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
editor_is_active
bool editor_is_active(void)
Definition editor.c:346
editor.h
is_option
bool is_option(const char *option_name, char *option)
Definition fc_cmdline.c:112
get_option_malloc
char * get_option_malloc(const char *option_name, char **argv, int *i, int argc, bool gc)
Definition fc_cmdline.c:50
fc_cmdline.h
O_SCIENCE
@ O_SCIENCE
Definition fc_types.h:91
O_GOLD
@ O_GOLD
Definition fc_types.h:91
fciconv.h
fc_fprintf
void fc_fprintf(FILE *stream, const char *format,...) fc__attribute((__format__(__printf__
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
_
#define _(String)
Definition fcintl.h:67
featured_text.h
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:111
game.h
government.h
inputline_has_focus
bool inputline_has_focus(void)
Definition chatline.c:71
inputline_toolkit_view_append_button
void inputline_toolkit_view_append_button(GtkWidget *toolkit_view, GtkWidget *button)
Definition chatline.c:1288
inputline_toolkit_view_new
GtkWidget * inputline_toolkit_view_new(void)
Definition chatline.c:1266
set_message_buffer_view_link_handlers
void set_message_buffer_view_link_handlers(GtkWidget *view)
Definition chatline.c:744
inputline_is_visible
bool inputline_is_visible(void)
Definition chatline.c:87
chatline_init
void chatline_init(void)
Definition chatline.c:1298
inputline_grab_focus
void inputline_grab_focus(void)
Definition chatline.c:79
chatline_scroll_to_bottom
void chatline_scroll_to_bottom(bool delayed)
Definition chatline.c:1006
citizens_dialog_init
void citizens_dialog_init(void)
Definition citizensinfo.c:267
citizens_dialog_done
void citizens_dialog_done(void)
Definition citizensinfo.c:275
cma_fe_init
void cma_fe_init(void)
Definition cma_fe.c:88
cma_fe_done
void cma_fe_done(void)
Definition cma_fe.c:96
unit_select_dialog_popup
void unit_select_dialog_popup(struct tile *ptile)
Definition dialogs.c:382
taxrates_callback
gboolean taxrates_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition dialogs.c:1434
diplomacy_dialog_init
void diplomacy_dialog_init(void)
Definition diplodlg.c:1173
diplomacy_dialog_done
void diplomacy_dialog_done(void)
Definition diplodlg.c:1182
handle_edit_key_press
gboolean handle_edit_key_press(GdkEventKey *ev)
Definition editgui.c:1661
editgui_create_widgets
void editgui_create_widgets(void)
Definition editgui.c:1821
editgui_get_editbar
struct editbar * editgui_get_editbar(void)
Definition editgui.c:1787
editgui_free
void editgui_free(void)
Definition editgui.c:1834
goto_dialog_focus_units_changed
void goto_dialog_focus_units_changed(void)
Definition gotodlg.c:540
source
static GtkWidget * source
Definition gotodlg.c:58
load_cursors
void load_cursors(void)
Definition graphics.c:78
map_vertical_scrollbar
GtkWidget * map_vertical_scrollbar
Definition gui_main.c:108
ui_main
int ui_main(int argc, char **argv)
Definition gui_main.c:1702
client_string
const char * client_string
Definition gui_main.c:104
message_buffer
GtkTextBuffer * message_buffer
Definition gui_main.c:177
quit_dialog_response
static void quit_dialog_response(GtkWidget *dialog, gint response)
Definition gui_main.c:2127
real_focus_units_changed
void real_focus_units_changed(void)
Definition gui_main.c:1955
set_unit_icons_more_arrow
void set_unit_icons_more_arrow(bool onoff)
Definition gui_main.c:1932
print_usage
static void print_usage(void)
Definition gui_main.c:249
OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK
#define OVERVIEW_CANVAS_STORE_WIDTH_NETBOOK
Definition gui_main.c:115
option_var_set_callback
#define option_var_set_callback(var, callback)
quit_dialog_callback
static gboolean quit_dialog_callback(void)
Definition gui_main.c:2180
srv_channel
static GIOChannel * srv_channel
Definition gui_main.c:181
main_label_info
GtkWidget * main_label_info
Definition gui_main.c:137
bottom_notebook
GtkWidget * bottom_notebook
Definition gui_main.c:128
unit_info_label
GtkWidget * unit_info_label
Definition gui_main.c:150
timer_callback
static gboolean timer_callback(gpointer data)
Definition gui_main.c:236
resolution_request_get
struct video_mode * resolution_request_get(void)
Definition gui_main.c:2396
set_unit_icon
void set_unit_icon(int idx, struct unit *punit)
Definition gui_main.c:1902
unit_ids
static int unit_ids[MAX_NUM_UNITS_BELOW]
Definition gui_main.c:174
timeout_label
GtkWidget * timeout_label
Definition gui_main.c:147
gui_up
static bool gui_up
Definition gui_main.c:185
srv_id
static guint srv_id
Definition gui_main.c:182
mouse_scroll_mapcanvas
static gboolean mouse_scroll_mapcanvas(GtkWidget *w, GdkEventScroll *ev)
Definition gui_main.c:690
city_productions_style
PangoFontDescription * city_productions_style
Definition gui_main.c:133
overview_scrolled_window
GtkWidget * overview_scrolled_window
Definition gui_main.c:111
detached_widget_fill
static GtkWidget * detached_widget_fill(GtkWidget *tearbox)
Definition gui_main.c:817
top_notebook
GtkWidget * top_notebook
Definition gui_main.c:128
MIGRATE_STR_OPTION
#define MIGRATE_STR_OPTION(opt)
unit_info_box
GtkWidget * unit_info_box
Definition gui_main.c:151
ui_exit
void ui_exit(void)
Definition gui_main.c:1872
get_gui_type
enum gui_type get_gui_type(void)
Definition gui_main.c:1883
detached_widget_new
static GtkWidget * detached_widget_new(void)
Definition gui_main.c:805
cur_y
gint cur_y
Definition gui_main.c:183
main
int main(int argc, char **argv)
Definition gui_main.c:1627
fullscreen_opt_refresh
void fullscreen_opt_refresh(struct option *poption)
Definition gui_main.c:2238
ui_init
void ui_init(void)
Definition gui_main.c:1618
free_unit_table
static void free_unit_table(void)
Definition gui_main.c:944
idle_callback_wrapper
static gboolean idle_callback_wrapper(gpointer data)
Definition gui_main.c:2195
apply_city_names_font
static void apply_city_names_font(struct option *poption)
Definition gui_main.c:2250
apply_city_productions_font
static void apply_city_productions_font(struct option *poption)
Definition gui_main.c:2261
government_label
GtkWidget * government_label
Definition gui_main.c:146
sun_label
GtkWidget * sun_label
Definition gui_main.c:144
city_names_style
PangoFontDescription * city_names_style
Definition gui_main.c:132
refresh_chat_buttons
void refresh_chat_buttons(void)
Definition gui_main.c:2313
map_canvas_focus
gboolean map_canvas_focus(void)
Definition gui_main.c:366
turn_done_button
GtkWidget * turn_done_button
Definition gui_main.c:148
bottom_hpaned
static GtkWidget * bottom_hpaned
Definition gui_main.c:130
timer_id
static gint timer_id
Definition gui_main.c:180
screen_width
int screen_width(void)
Definition gui_main.c:2356
scroll_panel
GtkWidget * scroll_panel
Definition gui_main.c:140
end_turn_callback
static void end_turn_callback(GtkWidget *w, gpointer data)
Definition gui_main.c:2052
OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK
#define OVERVIEW_CANVAS_STORE_HEIGHT_NETBOOK
Definition gui_main.c:116
log_callback_utf8
static void log_callback_utf8(enum log_level level, const char *message, bool file_too)
Definition gui_main.c:224
add_idle_callback
void add_idle_callback(void(callback)(void *), void *data)
Definition gui_main.c:2210
show_info_popup
static gboolean show_info_popup(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition gui_main.c:2021
reset_unit_table
void reset_unit_table(void)
Definition gui_main.c:972
key_press_map_canvas
static gboolean key_press_map_canvas(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition gui_main.c:407
unit_info_frame
GtkWidget * unit_info_frame
Definition gui_main.c:152
options_extra_init
void options_extra_init(void)
Definition gui_main.c:2284
top_vbox
GtkWidget * top_vbox
Definition gui_main.c:127
allied_chat_only_callback
static void allied_chat_only_callback(struct option *poption)
Definition gui_main.c:2223
adjust_default_options
static void adjust_default_options(void)
Definition gui_main.c:2408
set_wait_for_writable_socket
static void set_wait_for_writable_socket(struct connection *pc, bool socket_writable)
Definition gui_main.c:2072
ahbox
GtkWidget * ahbox
Definition gui_main.c:139
apply_reqtree_text_font
static void apply_reqtree_text_font(struct option *poption)
Definition gui_main.c:2272
is_gui_up
bool is_gui_up(void)
Definition gui_main.c:1864
toplevel_focus
static gboolean toplevel_focus(GtkWidget *w, GtkDirectionType arg)
Definition gui_main.c:322
reqtree_text_style
PangoFontDescription * reqtree_text_style
Definition gui_main.c:134
flake_label
GtkWidget * flake_label
Definition gui_main.c:145
avbox
GtkWidget * avbox
Definition gui_main.c:139
cur_x
gint cur_x
Definition gui_main.c:183
insert_client_build_info
void insert_client_build_info(char *outbuf, size_t outlen)
Definition gui_main.c:2343
bulb_label
GtkWidget * bulb_label
Definition gui_main.c:143
overview_canvas
GtkWidget * overview_canvas
Definition gui_main.c:110
toplevel
GtkWidget * toplevel
Definition gui_main.c:124
setup_widgets
static void setup_widgets(void)
Definition gui_main.c:1074
OVERVIEW_CANVAS_STORE_WIDTH
#define OVERVIEW_CANVAS_STORE_WIDTH
Definition gui_main.c:117
remove_net_input
void remove_net_input(void)
Definition gui_main.c:2116
map_horizontal_scrollbar
GtkWidget * map_horizontal_scrollbar
Definition gui_main.c:107
setup_canvas_color_for_state
static void setup_canvas_color_for_state(GtkStateFlags state)
Definition gui_main.c:1044
map_canvas
GtkWidget * map_canvas
Definition gui_main.c:106
toplevel_key_press_handler
static gboolean toplevel_key_press_handler(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition gui_main.c:606
sound_bell
void sound_bell(void)
Definition gui_main.c:1891
migrate_options_from_gtk2
static void migrate_options_from_gtk2(void)
Definition gui_main.c:1635
econ_label
GtkWidget * econ_label[10]
Definition gui_main.c:142
popup_quit_dialog
void popup_quit_dialog(void)
Definition gui_main.c:2154
gui_character_encoding
const char *const gui_character_encoding
Definition gui_main.c:160
unit_id_top
static int unit_id_top
Definition gui_main.c:173
get_net_input
static gboolean get_net_input(GIOChannel *source, GIOCondition condition, gpointer data)
Definition gui_main.c:2061
map_widget
GtkWidget * map_widget
Definition gui_main.c:129
right_notebook
GtkWidget * right_notebook
Definition gui_main.c:128
quit_gtk_main
void quit_gtk_main(void)
Definition gui_main.c:2142
allied_chat_button_toggled
static void allied_chat_button_toggled(GtkToggleButton *button, gpointer user_data)
Definition gui_main.c:2334
vmode
static struct video_mode vmode
Definition gui_main.c:187
add_net_input
void add_net_input(int sock)
Definition gui_main.c:2098
toplevel_tabs
GtkWidget * toplevel_tabs
Definition gui_main.c:126
allied_chat_toggle_button
static GtkWidget * allied_chat_toggle_button
Definition gui_main.c:178
overview_canvas_store_width
int overview_canvas_store_width
Definition gui_main.c:121
update_turn_done_tooltip
void update_turn_done_tooltip(void)
Definition gui_main.c:1055
tearoff_callback
static void tearoff_callback(GtkWidget *b, gpointer data)
Definition gui_main.c:769
main_message_area
GtkTextView * main_message_area
Definition gui_main.c:176
overview_canvas_store_height
int overview_canvas_store_height
Definition gui_main.c:122
screen_height
int screen_height(void)
Definition gui_main.c:2376
parse_options
static bool parse_options(int argc, char **argv)
Definition gui_main.c:286
conn_box
GtkWidget * conn_box
Definition gui_main.c:139
OVERVIEW_CANVAS_STORE_HEIGHT
#define OVERVIEW_CANVAS_STORE_HEIGHT
Definition gui_main.c:119
main_frame_civ_name
GtkWidget * main_frame_civ_name
Definition gui_main.c:136
MIGRATE_OPTION
#define MIGRATE_OPTION(opt)
gui_use_transliteration
const bool gui_use_transliteration
Definition gui_main.c:161
GUI_NAME_FULL
#define GUI_NAME_FULL
Definition gui_main.h:22
GUI_NAME_SHORT
#define GUI_NAME_SHORT
Definition gui_main.h:23
GUI_GTK_OPTION
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:25
setup_dialog
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:281
gui_update_font_full
void gui_update_font_full(const char *font_name, const char *font_value, PangoFontDescription **font_desc)
Definition gui_stuff.c:1070
happiness_dialog_init
void happiness_dialog_init(void)
Definition happiness.c:86
happiness_dialog_done
void happiness_dialog_done(void)
Definition happiness.c:94
help_system_init
void help_system_init(void)
Definition helpdlg.c:156
intel_dialog_done
void intel_dialog_done(void)
Definition inteldlg.c:127
intel_dialog_init
void intel_dialog_init(void)
Definition inteldlg.c:118
luaconsole_dialog_init
void luaconsole_dialog_init(void)
Definition luaconsole.c:83
luaconsole_dialog_done
void luaconsole_dialog_done(void)
Definition luaconsole.c:101
move_overviewcanvas
gboolean move_overviewcanvas(GtkWidget *w, GdkEventMotion *ev, gpointer data)
Definition mapctrl.c:458
move_mapcanvas
gboolean move_mapcanvas(GtkWidget *w, GdkEventMotion *ev, gpointer data)
Definition mapctrl.c:400
leave_mapcanvas
gboolean leave_mapcanvas(GtkWidget *widget, GdkEventCrossing *event)
Definition mapctrl.c:429
update_city_descriptions
void update_city_descriptions(void)
Definition mapview.c:470
map_canvas_draw
gboolean map_canvas_draw(GtkWidget *w, cairo_t *cr, gpointer data)
Definition mapview.c:407
overview_canvas_draw
gboolean overview_canvas_draw(GtkWidget *w, cairo_t *cr, gpointer data)
Definition mapview.c:339
meswin_dialog_popup
void meswin_dialog_popup(bool raise)
Definition messagewin.c:416
create_start_page
GtkWidget * create_start_page(void)
Definition pages.c:2619
create_network_page
GtkWidget * create_network_page(void)
Definition pages.c:1197
create_scenario_page
GtkWidget * create_scenario_page(void)
Definition pages.c:3182
statusbar
static GtkWidget * statusbar
Definition pages.c:89
get_current_client_page
enum client_pages get_current_client_page(void)
Definition pages.c:3343
destroy_server_scans
void destroy_server_scans(void)
Definition pages.c:765
create_load_page
GtkWidget * create_load_page(void)
Definition pages.c:2900
create_statusbar
GtkWidget * create_statusbar(void)
Definition pages.c:906
create_main_page
GtkWidget * create_main_page(void)
Definition pages.c:229
science_report_dialog_redraw
void science_report_dialog_redraw(void)
Definition repodlgs.c:761
spaceship_dialog_init
void spaceship_dialog_init(void)
Definition spaceshipdlg.c:87
spaceship_dialog_done
void spaceship_dialog_done(void)
Definition spaceshipdlg.c:95
sprite_get_pixbuf
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
ingame_votebar
GtkWidget * ingame_votebar
Definition voteinfo_bar.c:50
voteinfo_bar_new
GtkWidget * voteinfo_bar_new(bool split_bar)
Definition voteinfo_bar.c:92
monitor_size
static bool monitor_size(GdkRectangle *rect_p)
Definition gui_main.c:2516
set_g_log_callbacks
static void set_g_log_callbacks(void)
Definition gui_main.c:1707
g_log_to_freelog_cb
static void g_log_to_freelog_cb(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
Definition gui_main.c:1651
set_g_log_callback_domain
static void set_g_log_callback_domain(const char *domain)
Definition gui_main.c:1695
migrate_options_from_gtk3
static void migrate_options_from_gtk3(void)
Definition gui_main.c:1796
g_log_writer_to_freelog_cb
static GLogWriterOutput g_log_writer_to_freelog_cb(GLogLevelFlags log_level, const GLogField *fields, gsize n_fields, gpointer user_data)
Definition gui_main.c:1679
dlg_tab_provider_prepare
void dlg_tab_provider_prepare(void)
Definition gui_stuff.c:1151
citizensinfo.h
reverse_taxrates_callback
gboolean reverse_taxrates_callback(GtkGestureClick *gesture, int n_press, double x, double y)
Definition dialogs.c:1454
editgui.h
empty_unit_paintable
static GdkPaintable * empty_unit_paintable
Definition gui_main.c:158
tearoff_close
static void tearoff_close(GtkWidget *w, gpointer data)
Definition gui_main.c:734
tearoff_reattach
static void tearoff_reattach(GtkWidget *box)
Definition gui_main.c:717
terminate_signal_processing
gboolean terminate_signal_processing(GtkEventControllerFocus *controller, gpointer data)
Definition gui_main.c:995
more_arrow_container
static GtkWidget * more_arrow_container
Definition gui_main.c:163
unit_pic
static GtkWidget * unit_pic
Definition gui_main.c:160
select_more_arrow_callback
static gboolean select_more_arrow_callback(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition gui_main.c:2160
econ_widget
GtkWidget * econ_widget
Definition gui_main.c:153
fc_app
static GtkApplication * fc_app
Definition gui_main.c:179
gui_app
GtkApplication * gui_app(void)
Definition gui_main.c:2617
more_arrow
static GtkWidget * more_arrow
Definition gui_main.c:162
zoom_steps_custom
static float zoom_steps_custom[]
Definition gui_main.c:223
migrate_options_from_gtk3_22
static void migrate_options_from_gtk3_22(void)
Definition gui_main.c:1799
animation_idle_cb
void animation_idle_cb(void *data)
Definition gui_main.c:2372
activate_gui
static void activate_gui(GtkApplication *app, gpointer data)
Definition gui_main.c:1901
populate_unit_pic_table
static void populate_unit_pic_table(void)
Definition gui_main.c:834
info_popup_closed
static void info_popup_closed(GtkWidget *self, gpointer data)
Definition gui_main.c:2175
move_from_container_to_container
static void move_from_container_to_container(GtkWidget *wdg, GtkWidget *old_wdg, GtkWidget *new_wdg)
Definition gui_main.c:684
select_unit_pic_callback
static gboolean select_unit_pic_callback(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition gui_main.c:2128
unit_pic_table
static GtkWidget * unit_pic_table
Definition gui_main.c:159
unit_below_pic
static GtkWidget * unit_below_pic[MAX_NUM_UNITS_BELOW]
Definition gui_main.c:161
main_message_area_resize
void main_message_area_resize(void *data)
Definition gui_main.c:334
widget_destroyed
void widget_destroyed(GtkWidget *wdg, void *data)
Definition gui_stuff.c:1145
gui_stuff.h
happiness.h
right_butt_down_overviewcanvas
gboolean right_butt_down_overviewcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:499
left_butt_up_mapcanvas
gboolean left_butt_up_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:164
right_butt_up_mapcanvas
gboolean right_butt_up_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:181
left_butt_down_overviewcanvas
gboolean left_butt_down_overviewcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:474
left_butt_down_mapcanvas
gboolean left_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:206
right_butt_down_mapcanvas
gboolean right_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:261
middle_butt_down_mapcanvas
gboolean middle_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data)
Definition mapctrl.c:330
map_canvas_resize
void map_canvas_resize(GtkWidget *w, int width, int height, gpointer data)
Definition mapview.c:406
put_unit_picture
void put_unit_picture(struct unit *punit, GtkPicture *p, int height)
Definition mapview.c:492
menus_set_initial_toggle_values
void menus_set_initial_toggle_values(void)
Definition menu.c:2907
picture_new_from_surface
GtkWidget * picture_new_from_surface(cairo_surface_t *surf)
Definition sprite.c:526
cma_fe.h
chatline.h
colors.h
connectdlg.h
dialogs.h
diplodlg.h
gotodlg.h
graphics.h
gui_main.h
helpdlg.h
inteldlg.h
luaconsole.h
mapctrl.h
mapview.h
menu.h
messagewin.h
optiondlg.h
pages.h
plrdlg.h
repodlgs.h
spaceshipdlg.h
voteinfo_bar.h
log_set_callback
log_callback_fn log_set_callback(log_callback_fn callback)
Definition log.c:290
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert
#define fc_assert(condition)
Definition log.h:176
log_fatal
#define log_fatal(message,...)
Definition log.h:100
log_debug
#define log_debug(message,...)
Definition log.h:115
log_normal
#define log_normal(message,...)
Definition log.h:107
log_base
#define log_base(level, message,...)
Definition log.h:94
log_level
log_level
Definition log.h:28
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
LOG_FATAL
@ LOG_FATAL
Definition log.h:29
LOG_WARN
@ LOG_WARN
Definition log.h:31
log_error
#define log_error(message,...)
Definition log.h:103
map.h
update_line
void update_line(int canvas_x, int canvas_y)
Definition mapctrl_common.c:662
maybe_activate_keyboardless_goto
void maybe_activate_keyboardless_goto(int canvas_x, int canvas_y)
Definition mapctrl_common.c:504
rbutton_down
bool rbutton_down
Definition mapctrl_common.c:55
tiles_hilited_cities
bool tiles_hilited_cities
Definition mapctrl_common.c:60
scroll_mapview
void scroll_mapview(enum direction8 gui_dir)
Definition mapctrl_common.c:549
keyboardless_goto_button_down
bool keyboardless_goto_button_down
Definition mapctrl_common.c:69
update_selection_rectangle
void update_selection_rectangle(float canvas_x, float canvas_y)
Definition mapctrl_common.c:201
init_mapcanvas_and_overview
void init_mapcanvas_and_overview(void)
Definition mapview_common.c:3684
canvas_pos_to_tile
struct tile * canvas_pos_to_tile(float canvas_x, float canvas_y, float zoom)
Definition mapview_common.c:751
free_mapcanvas_and_overview
void free_mapcanvas_and_overview(void)
Definition mapview_common.c:3693
get_mapview_scroll_pos
void get_mapview_scroll_pos(int *scroll_x, int *scroll_y)
Definition mapview_common.c:1191
get_mapview_scroll_step
void get_mapview_scroll_step(int *xstep, int *ystep)
Definition mapview_common.c:1177
set_mapview_scroll_pos
void set_mapview_scroll_pos(int scroll_x, int scroll_y, float zoom)
Definition mapview_common.c:1200
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1222
update_animation
void update_animation(void)
Definition mapview_common.c:428
set_frame_by_frame_animation
void set_frame_by_frame_animation(void)
Definition mapview_common.c:4082
link_marks_clear_all
void link_marks_clear_all(void)
Definition mapview_common.c:3953
mem.h
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
option_changed
void option_changed(struct option *poption)
Definition options.c:723
server_optset
const struct option_set * server_optset
Definition options.c:4009
client_optset
const struct option_set * client_optset
Definition options.c:1255
option_bool_get
bool option_bool_get(const struct option *poption)
Definition options.c:772
option_type
enum option_type option_type(const struct option *poption)
Definition options.c:633
option_font_target
const char * option_font_target(const struct option *poption)
Definition options.c:1138
string_to_video_mode
bool string_to_video_mode(const char *buf, struct video_mode *mode)
Definition options.c:6453
gui_options
struct client_options gui_options
Definition options.c:71
option_font_get
const char * option_font_get(const struct option *poption)
Definition options.c:1116
optset_option_by_name
struct option * optset_option_by_name(const struct option_set *poptset, const char *name)
Definition options.c:406
options.h
GUI_GTK_OVERVIEW_MIN_XSIZE
#define GUI_GTK_OVERVIEW_MIN_XSIZE
Definition options.h:574
options_iterate
#define options_iterate(poptset, poption)
Definition options.h:527
GUI_GTK_MSGCHAT_MERGED
@ GUI_GTK_MSGCHAT_MERGED
Definition options.h:68
GUI_GTK_MSGCHAT_SPLIT
@ GUI_GTK_MSGCHAT_SPLIT
Definition options.h:66
options_iterate_end
#define options_iterate_end
Definition options.h:532
get_info_label_text_popup
const char * get_info_label_text_popup(void)
Definition text.c:1002
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
callback
Definition gui_main.c:2187
callback::data
void * data
Definition gui_main.c:2189
callback::callback
void(* callback)(void *data)
Definition gui_main.c:2188
civclient::conn
struct connection conn
Definition client_main.h:96
client_options::gui_gtk3_22_migrated_from_gtk3
bool gui_gtk3_22_migrated_from_gtk3
Definition options.h:130
client_options::gui_gtk3_migrated_from_2_5
bool gui_gtk3_migrated_from_2_5
Definition options.h:134
client_options::sound_effects_volume
int sound_effects_volume
Definition options.h:183
client_options::first_boot
bool first_boot
Definition options.h:124
client_options::gui_gtk3_fullscreen
bool gui_gtk3_fullscreen
Definition options.h:261
client_options::migrate_fullscreen
bool migrate_fullscreen
Definition options.h:138
client_options::gui_gtk3_migrated_from_gtk2
bool gui_gtk3_migrated_from_gtk2
Definition options.h:129
color
Definition colors.h:20
connection
Definition connection.h:141
connection::notify_of_writable_data
void(* notify_of_writable_data)(struct connection *pc, bool data_available_and_socket_full)
Definition connection.h:186
connection::used
bool used
Definition connection.h:144
editbar::widget
GtkWidget * widget
Definition editgui.h:26
message
Definition messagewin_common.h:29
option
Definition options.c:454
sprite
Definition sprite.h:22
sprite::surface
cairo_surface_t * surface
Definition sprite.h:23
tileset
Definition tilespec.c:459
unit
Definition unit.h:138
unit::id
int id
Definition unit.h:145
video_mode
Definition options.h:45
video_mode::height
int height
Definition options.h:47
video_mode::width
int width
Definition options.h:46
view
Definition mapview_common.h:36
widget
Definition widget.h:112
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:995
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
text.h
tileset_load_tiles
void tileset_load_tiles(struct tileset *t)
Definition tilespec.c:3452
tileset_free_tiles
void tileset_free_tiles(struct tileset *t)
Definition tilespec.c:6346
tileset_use_preferred_theme
void tileset_use_preferred_theme(const struct tileset *t)
Definition tilespec.c:6768
tileset_init
void tileset_init(struct tileset *t)
Definition tilespec.c:6827
get_arrow_sprite
struct sprite * get_arrow_sprite(const struct tileset *t, enum arrow_type arrow)
Definition tilespec.c:6568
get_tax_sprite
struct sprite * get_tax_sprite(const struct tileset *t, Output_type_id otype)
Definition tilespec.c:6579
tileset_tile_width
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:716
tilespec.h
ARROW_RIGHT
@ ARROW_RIGHT
Definition tilespec.h:199
unit_tile
#define unit_tile(_pu)
Definition unit.h:388
unit_owner
#define unit_owner(_pu)
Definition unit.h:387
unitlist.h
version.h
mouse_zoom
float mouse_zoom
Definition zoom.c:28
zoom_phase_set
void zoom_phase_set(bool individual_tiles)
Definition zoom.c:93
zoom_set_steps
void zoom_set_steps(float *steps)
Definition zoom.c:80
zoom_step_down
void zoom_step_down(void)
Definition zoom.c:130
zoom_step_up
void zoom_step_up(void)
Definition zoom.c:106
zoom.h