Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / client / gui-xaw / gui_main.c
blobc08d19e3cdc5e8f8088175502dfaca45d390bdf0
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.
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.
13 ***********************************************************************/
15 #ifdef HAVE_CONFIG_H
16 #include <fc_config.h>
17 #endif
19 #ifdef AUDIO_SDL
20 /* Though it would happily compile without this include,
21 * it is needed for sound to work.
22 * It defines "main" macro to rename our main() so that
23 * it can install SDL's own. */
24 #ifdef SDL2_PLAIN_INCLUDE
25 #include <SDL.h>
26 #include <SDL_mixer.h>
27 #elif AUDIO_SDL1_2
28 /* SDL */
29 #include <SDL/SDL.h>
30 #else /* AUDIO_SDL1_2 */
31 /* SDL2 */
32 #include <SDL2/SDL.h>
33 #endif /* AUDIO_SDL1_2 */
34 #endif
36 #include <stdio.h>
37 #include <stdlib.h>
39 #include <X11/Intrinsic.h>
40 #include <X11/StringDefs.h>
42 #include <X11/Xaw/Command.h>
43 #include <X11/Xaw/Form.h>
44 #include <X11/Xaw/Box.h>
45 #include <X11/Xaw/Label.h>
46 #include <X11/Xaw/AsciiText.h>
47 #include <X11/Xaw/Scrollbar.h>
48 #include <X11/Xaw/MenuButton.h>
49 #include <X11/Xaw/SimpleMenu.h>
50 #include <X11/Xaw/Paned.h>
51 #include <X11/Xatom.h>
53 #include "canvas.h"
54 #include "pixcomm.h"
56 /* utility */
57 #include "fc_cmdline.h"
58 #include "fciconv.h"
59 #include "fcintl.h"
60 #include "log.h"
61 #include "support.h"
63 /* common */
64 #include "game.h"
65 #include "government.h"
66 #include "map.h"
67 #include "unitlist.h"
68 #include "version.h"
70 /* client */
71 #include "chatline_common.h"
72 #include "client_main.h"
73 #include "climisc.h"
74 #include "clinet.h"
75 #include "control.h"
76 #include "editgui_g.h"
77 #include "options.h"
78 #include "text.h"
79 #include "tilespec.h"
81 /* gui-xaw */
82 #include "xaw_actions.h"
83 #include "colors.h"
84 #include "dialogs.h"
85 #include "graphics.h"
86 #include "gui_stuff.h" /* I_SW() */
87 #include "mapview.h"
88 #include "menu.h"
89 #include "optiondlg.h"
90 #include "pages.h"
91 #include "resources.h"
93 #include "gui_main.h"
95 const char *client_string = "gui-xaw";
97 const char * const gui_character_encoding = NULL;
98 const bool gui_use_transliteration = TRUE;
100 static AppResources appResources;
102 /* ids of the units icons in information display: (or 0) */
103 static int unit_ids[MAX_NUM_UNITS_BELOW];
105 static void setup_widgets(void);
107 void fill_econ_label_pixmaps(void);
108 void fill_unit_below_pixmaps(void);
110 /**************************************************************************
112 **************************************************************************/
113 XtResource resources[] = {
114 { "GotAppDefFile", "gotAppDefFile", XtRBoolean, sizeof(Boolean),
115 XtOffset(AppResources *,gotAppDefFile), XtRImmediate, (XtPointer)False},
116 { "version", "Version", XtRString, sizeof(String),
117 XtOffset(AppResources *,version), XtRImmediate, (XtPointer)False},
118 #ifdef UNUSED
119 { "log", "Log", XtRString, sizeof(String),
120 XtOffset(AppResources *,logfile), XtRImmediate, (XtPointer)False},
121 { "name", "name", XtRString, sizeof(String),
122 XtOffset(AppResources *,name), XtRImmediate, (XtPointer)False},
123 { "port", "Port", XtRInt, sizeof(int),
124 XtOffset(AppResources *,port), XtRImmediate, (XtPointer)False},
125 { "server", "Server", XtRString, sizeof(String),
126 XtOffset(AppResources *,server), XtRImmediate, (XtPointer)False},
127 { "metaserver", "Metaserver", XtRString, sizeof(String),
128 XtOffset(AppResources *,metaserver), XtRImmediate, (XtPointer)False},
129 { "logLevel", "LogLevel", XtRString, sizeof(String),
130 XtOffset(AppResources *,loglevel_str), XtRImmediate, (XtPointer)False},
131 { "showHelp", "ShowHelp", XtRBoolean, sizeof(Boolean),
132 XtOffset(AppResources *,showHelp), XtRImmediate, (XtPointer)False},
133 { "showVersion", "ShowVersion", XtRBoolean, sizeof(Boolean),
134 XtOffset(AppResources *,showVersion), XtRImmediate, (XtPointer)False},
135 { "tileset", "TileSet", XtRString, sizeof(String),
136 XtOffset(AppResources *,tileset), XtRImmediate, (XtPointer)False},
137 #endif
140 /**************************************************************************
142 **************************************************************************/
143 #ifdef UNUSED
144 static XrmOptionDescRec cmd_options[] = {
145 /* { "-help", ".showHelp", XrmoptionNoArg, (XPointer)"True" },*/
146 { "-log", ".log", XrmoptionSepArg, (XPointer)"True" },
147 { "-name", ".name", XrmoptionSepArg, (XPointer)"True" },
148 { "-port", ".port", XrmoptionSepArg, (XPointer)"True" },
149 { "-server", ".server", XrmoptionSepArg, (XPointer)"True" },
150 { "-metaserver",".metaserver",XrmoptionSepArg, (XPointer)"True" },
151 { "-debug", ".logLevel", XrmoptionSepArg, (XPointer)"True" },
152 { "-tiles", ".tileset", XrmoptionSepArg, (XPointer)"True" },
153 /* { "-version", ".showVersion", XrmoptionNoArg, (XPointer)"True" },*/
154 /* { "--help", ".showHelp", XrmoptionNoArg, (XPointer)"True" },*/
155 { "--log", ".log", XrmoptionSepArg, (XPointer)"True" },
156 { "--name", ".name", XrmoptionSepArg, (XPointer)"True" },
157 { "--port", ".port", XrmoptionSepArg, (XPointer)"True" },
158 { "--debug", ".logLevel", XrmoptionSepArg, (XPointer)"True" },
159 { "--server", ".server", XrmoptionSepArg, (XPointer)"True" },
160 { "--metaserver",".metaserver",XrmoptionSepArg, (XPointer)"True" },
161 { "--tiles", ".tileset", XrmoptionSepArg, (XPointer)"True" }
162 /* { "--version", ".showVersion", XrmoptionNoArg, (XPointer)"True" }*/
164 #endif
166 /**************************************************************************/
168 static void end_turn_callback(Widget w, XtPointer client_data,
169 XtPointer call_data);
171 static void timer_callback(XtPointer client_data, XtIntervalId *id);
173 /**************************************************************************/
175 struct game_data {
176 int year;
177 int population;
178 int researchedpoints;
179 int money;
180 int tax, luxurary, research;
183 /**************************************************************************/
185 Display *display;
186 int display_depth;
187 int screen_number;
188 enum Display_color_type display_color_type;
189 XtAppContext app_context;
191 /* this GC will be the default one all thru freeciv */
192 GC civ_gc;
194 /* This is for drawing border lines */
195 GC border_line_gc;
197 /* and this one is used for filling with the bg color */
198 GC fill_bg_gc;
199 GC fill_tile_gc;
200 Pixmap gray50,gray25;
202 /* overall font GC */
203 GC font_gc;
204 XFontSet main_font_set;
205 /* productions font GC */
206 GC prod_font_gc;
207 XFontSet prod_font_set;
209 Widget toplevel, main_form, menu_form, below_menu_form, left_column_form;
210 Widget bottom_form;
211 Widget map_form;
212 Widget map_canvas;
213 Widget overview_canvas;
214 Widget map_vertical_scrollbar, map_horizontal_scrollbar;
215 Widget inputline_text, outputwindow_text;
216 Widget econ_label[10];
217 Widget turn_done_button;
218 Widget info_command;
219 Widget bulb_label, sun_label, flake_label, government_label, timeout_label;
220 Widget unit_info_label;
221 Widget unit_pix_canvas;
222 Widget unit_below_canvas[MAX_NUM_UNITS_BELOW];
223 Widget main_vpane;
224 Pixmap unit_below_pixmap[MAX_NUM_UNITS_BELOW];
225 Widget more_arrow_label;
226 Window root_window;
228 XtInputId x_input_id;
229 XtIntervalId x_interval_id;
230 Atom wm_delete_window;
232 /****************************************************************************
233 Called by the tileset code to set the font size that should be used to
234 draw the city names and productions.
235 ****************************************************************************/
236 void set_city_names_font_sizes(int my_city_names_font_size,
237 int my_city_productions_font_size)
239 log_error("Unimplemented set_city_names_font_sizes.");
240 /* PORTME */
243 #ifdef UNUSED
244 /**************************************************************************
246 **************************************************************************/
247 /* This is used below in ui_main(), in commented out code. */
248 static int myerr(Display *p, XErrorEvent *e)
250 puts("error");
251 return 0;
253 #endif
255 /**************************************************************************
256 Print extra usage information, including one line help on each option,
257 to stderr.
258 **************************************************************************/
259 static void print_usage(void)
261 /* add client-specific usage information here */
262 fc_fprintf(stderr,
263 _("This client accepts the standard X toolkit command-line options\n"
264 "after '--'. See the X(7) man page.\n\n"));
267 /* TRANS: No full stop after the URL, could cause confusion. */
268 fc_fprintf(stderr, _("Report bugs at %s\n"), BUG_URL);
271 /**************************************************************************
272 Handle commandline options specific to this gui
273 **************************************************************************/
274 static void parse_options(int argc, char **argv)
276 int i = 1;
278 while (i < argc) {
279 if (is_option("--help", argv[i])) {
280 print_usage();
281 exit(EXIT_SUCCESS);
282 } else {
283 fc_fprintf(stderr, _("Unrecognized option: \"%s\"\n"), argv[i]);
284 exit(EXIT_FAILURE);
287 i++;
291 /**************************************************************************
293 **************************************************************************/
294 static Boolean toplevel_work_proc(XtPointer client_data)
296 /* This will cause the connect dialog to pop-up.
297 We do it here so that the main window exists when that happens,
298 so that the connect dialog can position itself relative to it. */
299 set_client_state(C_S_DISCONNECTED);
300 return (True);
303 /**************************************************************************
305 **************************************************************************/
306 void ui_init(void)
311 /****************************************************************************
312 Extra initializers for client options.
313 ****************************************************************************/
314 void options_extra_init(void)
316 /* Nothing to do. */
319 /**************************************************************************
320 Entry point for whole freeciv client program.
321 **************************************************************************/
322 int main(int argc, char **argv)
324 return client_main(argc, argv);
327 /**************************************************************************
328 Entry point for GUI specific portion. Called from client_main()
329 **************************************************************************/
330 void ui_main(int argc, char *argv[])
332 int i;
333 struct sprite *icon;
334 const char *rev_ver;
336 parse_options(argc, argv);
338 /* include later - pain to see the warning at every run */
339 XtSetLanguageProc(NULL, NULL, NULL);
341 toplevel = XtVaAppInitialize(
342 &app_context, /* Application context */
343 "Freeciv", /* application class name */
344 #ifdef UNUSED
345 cmd_options, XtNumber(cmd_options),
346 #else
347 NULL, 0,
348 #endif
349 /* command line option list */
350 &argc, argv, /* command line args */
351 &fallback_resources[1], /* for missing app-defaults file */
352 XtNallowShellResize, True,
353 NULL);
355 XtGetApplicationResources(toplevel, &appResources, resources,
356 XtNumber(resources), NULL, 0);
358 /* XSynchronize(display, 1);
359 XSetErrorHandler(myerr);*/
361 if (appResources.version == NULL) {
362 log_fatal(_("No version number in resources."));
363 log_fatal(_("You probably have an old (circa V1.0)"
364 " Freeciv resource file somewhere."));
365 exit(EXIT_FAILURE);
368 /* TODO: Use capabilities here instead of version numbers */
369 if (0 != strncmp(appResources.version, VERSION_STRING,
370 strlen(appResources.version))) {
371 log_fatal(_("Game version does not match Resource version."));
372 log_fatal(_("Game version: %s - Resource version: %s"),
373 VERSION_STRING, appResources.version);
374 log_fatal(_("You might have an old Freeciv resourcefile"
375 " in /usr/lib/X11/app-defaults"));
376 exit(EXIT_FAILURE);
379 if (!appResources.gotAppDefFile) {
380 log_normal(_("Using fallback resources - which is OK"));
383 display = XtDisplay(toplevel);
384 screen_number = XScreenNumberOfScreen(XtScreen(toplevel));
385 display_depth = DefaultDepth(display, screen_number);
386 root_window = DefaultRootWindow(display);
388 display_color_type = get_visual();
390 if (display_color_type != COLOR_DISPLAY) {
391 log_fatal(_("Only color displays are supported for now..."));
392 /* exit(EXIT_FAILURE); */
396 XGCValues values;
397 char **missing_charset_list_return;
398 int missing_charset_count_return;
399 char *def_string_return;
400 char *city_names_font, *city_productions_font_name;
402 values.graphics_exposures = False;
403 civ_gc = XCreateGC(display, root_window, GCGraphicsExposures, &values);
405 city_names_font = fc_strdup("-*-*-*-*-*-*-14-*");
407 city_productions_font_name = fc_strdup("-*-*-*-*-*-*-14-*");
409 main_font_set = XCreateFontSet(display, city_names_font,
410 &missing_charset_list_return,
411 &missing_charset_count_return,
412 &def_string_return);
413 if (!main_font_set) {
414 log_fatal(_("Unable to open fontset: %s"), city_names_font);
415 log_fatal(_("Doing 'xset fp rehash' may temporarily solve a problem."));
416 exit(EXIT_FAILURE);
418 for (i = 0; i < missing_charset_count_return; i++) {
419 log_error(_("Font for charset %s is lacking"),
420 missing_charset_list_return[i]);
422 values.foreground = get_color(tileset, COLOR_MAPVIEW_CITYTEXT)->color.pixel;
423 values.background = get_color(tileset, COLOR_MAPVIEW_UNKNOWN)->color.pixel;
424 font_gc= XCreateGC(display, root_window,
425 GCForeground|GCBackground|GCGraphicsExposures,
426 &values);
428 prod_font_set = XCreateFontSet(display, city_productions_font_name,
429 &missing_charset_list_return,
430 &missing_charset_count_return,
431 &def_string_return);
432 if (!prod_font_set) {
433 log_fatal(_("Unable to open fontset: %s"), city_productions_font_name);
434 log_fatal(_("Doing 'xset fp rehash' may temporarily solve a problem."));
435 exit(EXIT_FAILURE);
437 for (i = 0; i < missing_charset_count_return; i++) {
438 log_error(_("Font for charset %s is lacking"),
439 missing_charset_list_return[i]);
441 values.foreground = get_color(tileset, COLOR_MAPVIEW_CITYTEXT)->color.pixel;
442 values.background = get_color(tileset, COLOR_MAPVIEW_UNKNOWN)->color.pixel;
443 prod_font_gc= XCreateGC(display, root_window,
444 GCForeground|GCBackground|GCGraphicsExposures,
445 &values);
447 values.line_width = BORDER_WIDTH;
448 values.line_style = LineOnOffDash;
449 values.cap_style = CapNotLast;
450 values.join_style = JoinMiter;
451 values.fill_style = FillSolid;
452 border_line_gc = XCreateGC(display, root_window,
453 GCGraphicsExposures|GCLineWidth|GCLineStyle
454 |GCCapStyle|GCJoinStyle|GCFillStyle, &values);
456 values.foreground = 0;
457 values.background = 0;
458 fill_bg_gc= XCreateGC(display, root_window,
459 GCForeground|GCBackground|GCGraphicsExposures,
460 &values);
462 values.fill_style = FillStippled;
463 fill_tile_gc = XCreateGC(display, root_window,
464 GCForeground|GCBackground|GCFillStyle|GCGraphicsExposures,
465 &values);
469 char d1[] = {0x03,0x0c,0x03,0x0c};
470 char d2[] = {0x08,0x02,0x08,0x02};
471 gray50 = XCreateBitmapFromData(display, root_window, d1, 4, 4);
472 gray25 = XCreateBitmapFromData(display, root_window, d2, 4, 4);
475 /* 135 below is rough value (could be more intelligent) --dwp */
476 num_units_below = 135 / tileset_full_tile_width(tileset);
477 num_units_below = MIN(num_units_below, MAX_NUM_UNITS_BELOW);
478 num_units_below = MAX(num_units_below, 1);
480 /* do setup_widgets before loading the rest of graphics to ensure that
481 setup_widgets() has enough colors available: (on 256-colour systems)
483 setup_widgets();
484 tileset_init(tileset);
485 tileset_load_tiles(tileset);
486 load_intro_gfx();
487 load_cursors();
489 /* FIXME: what about the mask? */
490 icon = get_icon_sprite(tileset, ICON_FREECIV);
491 XtVaSetValues(toplevel, XtNiconPixmap, icon->pixmap, NULL);
493 XtSetKeyboardFocus(bottom_form, inputline_text);
494 XtSetKeyboardFocus(below_menu_form, map_canvas);
496 InitializeActions(app_context);
498 /* Do this outside setup_widgets() so after tiles are loaded */
499 fill_econ_label_pixmaps();
501 XtAddCallback(map_horizontal_scrollbar, XtNjumpProc,
502 scrollbar_jump_callback, NULL);
503 XtAddCallback(map_vertical_scrollbar, XtNjumpProc,
504 scrollbar_jump_callback, NULL);
505 XtAddCallback(map_horizontal_scrollbar, XtNscrollProc,
506 scrollbar_scroll_callback, NULL);
507 XtAddCallback(map_vertical_scrollbar, XtNscrollProc,
508 scrollbar_scroll_callback, NULL);
509 XtAddCallback(turn_done_button, XtNcallback, end_turn_callback, NULL);
511 XtAppAddWorkProc(app_context, toplevel_work_proc, NULL);
513 XtRealizeWidget(toplevel);
515 x_interval_id = XtAppAddTimeOut(app_context, TIMER_INTERVAL,
516 timer_callback, NULL);
518 init_mapcanvas_and_overview();
520 fill_unit_below_pixmaps();
522 set_indicator_icons(client_research_sprite(),
523 client_warming_sprite(),
524 client_cooling_sprite(),
525 client_government_sprite());
527 wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW", 0);
528 XSetWMProtocols(display, XtWindow(toplevel), &wm_delete_window, 1);
529 XtOverrideTranslations(toplevel,
530 XtParseTranslationTable ("<Message>WM_PROTOCOLS: msg-quit-freeciv()"));
532 XtSetSensitive(toplevel, FALSE);
534 rev_ver = fc_git_revision();
535 if (rev_ver != NULL) {
536 char buffer[512];
538 fc_snprintf(buffer, sizeof(buffer), _("Commit: %s"), rev_ver);
539 output_window_append(ftc_client, buffer);
542 XtAppMainLoop(app_context);
544 start_quitting();
547 /**************************************************************************
548 Do any necessary UI-specific cleanup
549 **************************************************************************/
550 void ui_exit()
554 /**************************************************************************
555 Return our GUI type
556 **************************************************************************/
557 enum gui_type get_gui_type(void)
559 return GUI_XAW;
562 /**************************************************************************
563 Callack for when user clicks one of the unit icons on left hand side
564 (units on same square as current unit). Use unit_ids[] data and change
565 focus to clicked unit.
566 **************************************************************************/
567 static void unit_icon_callback(Widget w, XtPointer client_data,
568 XtPointer call_data)
570 struct unit *punit;
571 int i = (size_t)client_data;
573 fc_assert_ret(i >= 0 && i < num_units_below);
574 if (unit_ids[i] == 0) { /* no unit displayed at this place */
575 return;
577 punit = game_unit_by_number(unit_ids[i]);
578 if (punit) { /* should always be true at this point */
579 if (unit_owner(punit) == client.conn.playing) {
580 /* may be non-true if alliance */
581 unit_focus_set(punit);
586 /**************************************************************************
588 **************************************************************************/
589 void setup_widgets(void)
591 long i;
592 int econ_label_count=10, econ_label_space=1;
594 main_form = XtVaCreateManagedWidget("mainform", formWidgetClass,
595 toplevel,
596 NULL);
598 menu_form = XtVaCreateManagedWidget("menuform", formWidgetClass,
599 main_form,
600 NULL);
601 setup_menus(menu_form);
604 main_vpane= XtVaCreateManagedWidget("mainvpane",
605 panedWidgetClass,
606 main_form,
607 NULL);
609 below_menu_form = XtVaCreateManagedWidget("belowmenuform",
610 formWidgetClass,
611 main_vpane,
612 NULL);
614 below_menu_form = XtVaCreateManagedWidget("belowmenuform",
615 formWidgetClass,
616 main_form,
617 NULL);
619 left_column_form = XtVaCreateManagedWidget("leftcolumnform",
620 formWidgetClass,
621 below_menu_form,
622 NULL);
624 map_form = XtVaCreateManagedWidget("mapform",
625 formWidgetClass,
626 below_menu_form,
627 NULL);
629 bottom_form = XtVaCreateManagedWidget("bottomform",
630 formWidgetClass,
631 /*main_vpane,*/ main_form,
632 NULL);
634 overview_canvas = XtVaCreateManagedWidget("overviewcanvas",
635 xfwfcanvasWidgetClass,
636 left_column_form,
637 "exposeProc",
638 (XtArgVal)overview_canvas_expose,
639 "exposeProcData",
640 (XtArgVal)NULL,
641 NULL);
643 info_command = XtVaCreateManagedWidget("infocommand",
644 commandWidgetClass,
645 left_column_form,
646 XtNfromVert,
647 (XtArgVal)overview_canvas,
648 NULL);
651 /* Don't put the citizens in here yet because not loaded yet */
652 for(i=0;i<econ_label_count;i++) {
653 econ_label[i] = XtVaCreateManagedWidget("econlabels",
654 commandWidgetClass,
655 left_column_form,
656 XtNwidth, tileset_small_sprite_width(tileset),
657 XtNheight, tileset_small_sprite_height(tileset),
658 i?XtNfromHoriz:NULL,
659 i?econ_label[i-1]:NULL,
660 XtNhorizDistance, econ_label_space,
661 NULL);
664 bulb_label = XtVaCreateManagedWidget("bulblabel",
665 labelWidgetClass,
666 left_column_form,
667 NULL);
669 sun_label = XtVaCreateManagedWidget("sunlabel",
670 labelWidgetClass,
671 left_column_form,
672 NULL);
674 flake_label = XtVaCreateManagedWidget("flakelabel",
675 labelWidgetClass,
676 left_column_form,
677 NULL);
679 government_label = XtVaCreateManagedWidget("governmentlabel",
680 labelWidgetClass,
681 left_column_form,
682 NULL);
684 timeout_label = XtVaCreateManagedWidget("timeoutlabel",
685 labelWidgetClass,
686 left_column_form,
687 NULL);
690 turn_done_button =
691 I_LW(XtVaCreateManagedWidget("turndonebutton",
692 commandWidgetClass,
693 left_column_form,
694 XtNwidth, econ_label_count*
695 (tileset_small_sprite_width(tileset)+econ_label_space),
696 NULL));
699 unit_info_label = XtVaCreateManagedWidget("unitinfolabel",
700 labelWidgetClass,
701 left_column_form,
702 NULL);
704 unit_pix_canvas = XtVaCreateManagedWidget("unitpixcanvas",
705 pixcommWidgetClass,
706 left_column_form,
707 XtNwidth, tileset_full_tile_width(tileset),
708 XtNheight, tileset_full_tile_height(tileset),
709 NULL);
711 for(i=0; i<num_units_below; i++) {
712 char unit_below_name[32];
713 fc_snprintf(unit_below_name, sizeof(unit_below_name),
714 "unitbelowcanvas%ld", i);
715 unit_below_canvas[i] = XtVaCreateManagedWidget(unit_below_name,
716 pixcommWidgetClass,
717 left_column_form,
718 XtNwidth,
719 tileset_full_tile_width(tileset),
720 XtNheight,
721 tileset_full_tile_height(tileset),
722 NULL);
723 XtAddCallback(unit_below_canvas[i], XtNcallback, unit_icon_callback,
724 (XtPointer)i);
727 more_arrow_label =
728 XtVaCreateManagedWidget("morearrowlabel",
729 labelWidgetClass,
730 left_column_form,
731 XtNfromHoriz,
732 (XtArgVal)unit_below_canvas[num_units_below-1],
733 NULL);
735 map_vertical_scrollbar = XtVaCreateManagedWidget("mapvertiscrbar",
736 scrollbarWidgetClass,
737 map_form,
738 NULL);
740 map_canvas = XtVaCreateManagedWidget("mapcanvas",
741 xfwfcanvasWidgetClass,
742 map_form,
743 "exposeProc",
744 (XtArgVal)map_canvas_expose,
745 "exposeProcData",
746 (XtArgVal)NULL,
747 NULL);
749 map_horizontal_scrollbar = XtVaCreateManagedWidget("maphorizscrbar",
750 scrollbarWidgetClass,
751 map_form,
752 NULL);
756 outputwindow_text = I_SW(XtVaCreateManagedWidget("outputwindowtext",
757 asciiTextWidgetClass,
758 bottom_form,
759 NULL));
762 inputline_text= XtVaCreateManagedWidget("inputlinetext",
763 asciiTextWidgetClass,
764 bottom_form,
765 NULL);
769 /**************************************************************************
771 **************************************************************************/
772 void xaw_ui_exit(void)
774 free_mapcanvas_and_overview();
775 tileset_free_tiles(tileset);
776 client_exit();
779 /**************************************************************************
781 **************************************************************************/
782 void main_show_info_popup(XEvent *event)
784 XButtonEvent *ev = (XButtonEvent *)event;
786 if (ev->button == Button1) {
787 Widget p;
788 Position x, y;
789 Dimension w, h;
791 p = XtCreatePopupShell("popupinfo",
792 overrideShellWidgetClass,
793 info_command, NULL, 0);
795 XtAddCallback(p, XtNpopdownCallback, destroy_me_callback, NULL);
797 XtVaCreateManagedWidget("fullinfopopuplabel",
798 labelWidgetClass,
800 XtNlabel, get_info_label_text_popup(),
801 NULL);
803 XtRealizeWidget(p);
805 XtVaGetValues(p, XtNwidth, &w, XtNheight, &h, NULL);
806 XtTranslateCoords(info_command, ev->x, ev->y, &x, &y);
807 XtVaSetValues(p, XtNx, MAX(0, x - w / 2), XtNy, MAX(0, y - h / 2), NULL);
808 XtPopupSpringLoaded(p);
812 /**************************************************************************
813 Update the connected users list at pregame state.
814 **************************************************************************/
815 void real_conn_list_dialog_update(void)
817 /* PORTME */
818 update_start_page();
821 /**************************************************************************
823 **************************************************************************/
824 void sound_bell(void)
826 XBell(display, 100);
829 /**************************************************************************
831 **************************************************************************/
832 static void get_net_input(XtPointer client_data, int *fid, XtInputId *id)
834 input_from_server(*fid);
837 /**************************************************************************
839 **************************************************************************/
840 static void set_wait_for_writable_socket(struct connection *pc,
841 bool socket_writable)
843 static bool previous_state = FALSE;
845 if (previous_state == socket_writable)
846 return;
847 log_debug("set_wait_for_writable_socket(%d)", socket_writable);
848 XtRemoveInput(x_input_id);
849 x_input_id = XtAppAddInput(app_context, client.conn.sock,
850 (XtPointer) (XtInputReadMask |
851 (socket_writable ?
852 XtInputWriteMask : 0) |
853 XtInputExceptMask),
854 (XtInputCallbackProc) get_net_input, NULL);
855 previous_state = socket_writable;
858 /**************************************************************************
859 This function is called after the client succesfully
860 has connected to the server
861 **************************************************************************/
862 void add_net_input(int sock)
864 x_input_id = XtAppAddInput(app_context, sock,
865 (XtPointer) (XtInputReadMask |
866 XtInputExceptMask),
867 (XtInputCallbackProc) get_net_input, NULL);
868 client.conn.notify_of_writable_data = set_wait_for_writable_socket;
871 /**************************************************************************
872 This function is called if the client disconnects
873 from the server
874 **************************************************************************/
875 void remove_net_input(void)
877 XtRemoveInput(x_input_id);
878 XUndefineCursor(display, XtWindow(map_canvas));
881 /**************************************************************************
883 **************************************************************************/
884 void end_turn_callback(Widget w, XtPointer client_data, XtPointer call_data)
886 XtSetSensitive(turn_done_button, FALSE);
888 user_ended_turn();
891 /**************************************************************************
893 **************************************************************************/
894 void timer_callback(XtPointer client_data, XtIntervalId * id)
896 int msec = real_timer_callback() * 1000;
898 x_interval_id = XtAppAddTimeOut(app_context, msec,
899 timer_callback, NULL);
902 /**************************************************************************
903 Set one of the unit icons in information area based on punit.
904 Use punit==NULL to clear icon.
905 Index 'idx' is -1 for "active unit", or 0 to (num_units_below-1) for
906 units below. Also updates unit_ids[idx] for idx>=0.
907 **************************************************************************/
908 void set_unit_icon(int idx, struct unit *punit)
910 Widget w;
912 fc_assert_ret(idx >= -1 && idx < num_units_below);
913 if (idx == -1) {
914 w = unit_pix_canvas;
915 } else {
916 w = unit_below_canvas[idx];
917 unit_ids[idx] = punit ? punit->id : 0;
920 XawPixcommClear(w);
921 if (punit) {
922 struct canvas store = {XawPixcommPixmap(w)};
924 put_unit(punit, &store, 1.0, 0, 0);
925 xaw_expose_now(w);
929 /**************************************************************************
930 Set the "more arrow" for the unit icons to on(1) or off(0).
931 Maintains a static record of current state to avoid unnecessary redraws.
932 Note initial state should match initial gui setup (off).
933 **************************************************************************/
934 void set_unit_icons_more_arrow(bool onoff)
936 static bool showing = FALSE;
938 if (onoff && !showing) {
939 /* FIXME: what about the mask? */
940 xaw_set_bitmap(more_arrow_label,
941 get_arrow_sprite(tileset, ARROW_RIGHT)->pixmap);
942 showing = TRUE;
944 else if(!onoff && showing) {
945 xaw_set_bitmap(more_arrow_label, None);
946 showing = FALSE;
950 /****************************************************************************
951 Called when the set of units in focus (get_units_in_focus()) changes.
952 Standard updates like update_unit_info_label() are handled in the platform-
953 independent code, so some clients will not need to do anything here.
954 ****************************************************************************/
955 void real_focus_units_changed(void)
957 /* Nothing to do */
960 struct callback {
961 void (*callback)(void *data);
962 void *data;
965 /****************************************************************************
966 A wrapper for the callback called through add_idle_callback.
967 ****************************************************************************/
968 static Boolean idle_callback_wrapper(XtPointer data)
970 struct callback *cb = data;
972 (cb->callback)(cb->data);
973 free(cb);
974 /* return True if we want to remove WorkProc */
975 return True;
978 /****************************************************************************
979 Enqueue a callback to be called during an idle moment. The 'callback'
980 function should be called sometimes soon, and passed the 'data' pointer
981 as its data.
982 ****************************************************************************/
983 void add_idle_callback(void (callback)(void *), void *data)
985 struct callback *cb = fc_malloc(sizeof(*cb));
987 cb->callback = callback;
988 cb->data = data;
989 XtAppAddWorkProc(app_context, idle_callback_wrapper, cb);
992 /**************************************************************************
993 Called to fill econ_label pixmaps (showing tax/lux/sci rates).
995 It may be called again if the tileset changes.
996 **************************************************************************/
997 void fill_econ_label_pixmaps(void)
999 int i;
1000 int econ_label_count = 10;
1002 for(i = 0; i < econ_label_count; i++) {
1003 struct sprite *s = i < 5 ? get_tax_sprite(tileset, O_SCIENCE)
1004 : get_tax_sprite(tileset, O_GOLD);
1006 XtVaSetValues(econ_label[i], XtNbitmap,
1007 s->pixmap, NULL);
1008 XtAddCallback(econ_label[i], XtNcallback, taxrates_callback,
1009 INT_TO_XTPOINTER(i));
1013 /**************************************************************************
1014 Called to fill unit_below pixmaps. They are on the left of the
1015 screen that shows all of the inactive units in the current tile.
1017 It may be called again if the tileset changes.
1018 **************************************************************************/
1019 void fill_unit_below_pixmaps(void)
1021 long i;
1023 for (i = 0; i < num_units_below; i++) {
1024 /* XtVaSetValues(unit_below_canvas[i],
1025 XtNwidth, tileset_full_tile_width(tileset),
1026 XtNheight, tileset_full_tile_height(tileset),
1027 NULL);
1028 */ unit_below_pixmap[i] = XCreatePixmap(display, XtWindow(overview_canvas),
1029 tileset_full_tile_width(tileset),
1030 tileset_full_tile_height(tileset),
1031 display_depth);
1035 /**************************************************************************
1036 Called when the tileset is changed to reset indicators pixmaps.
1037 **************************************************************************/
1038 void reset_econ_label_pixmaps(void)
1040 fill_econ_label_pixmaps();
1043 /**************************************************************************
1044 Called when the tileset is changed to reset unit pixmaps.
1045 **************************************************************************/
1046 void reset_unit_below_pixmaps(void)
1048 long i;
1050 for (i = 0; i < num_units_below; i++) {
1051 XFreePixmap(display, unit_below_pixmap[i]);
1053 xaw_set_bitmap(more_arrow_label, None);
1054 fill_unit_below_pixmaps();
1056 set_unit_icons_more_arrow(FALSE);
1057 if (get_num_units_in_focus() == 1) {
1058 set_unit_icon(-1, head_of_units_in_focus());
1059 } else {
1060 set_unit_icon(-1, NULL);
1062 update_unit_pix_label(get_units_in_focus());
1065 /****************************************************************************
1066 Assigns focus units to given battlegroup.
1067 ****************************************************************************/
1068 void assign_battlegroup(int battlegroup)
1070 key_unit_assign_battlegroup(battlegroup, FALSE);
1073 /****************************************************************************
1074 Brings given battlegroup into focus.
1075 ****************************************************************************/
1076 void select_battlegroup(int battlegroup)
1078 key_unit_select_battlegroup(battlegroup, FALSE);
1081 /****************************************************************************
1082 Adds focus units to given battlegroup
1083 (or removes unit from battlegoup if battlegroup is the same that unit has).
1084 ****************************************************************************/
1085 void add_unit_to_battlegroup(int battlegroup)
1087 if (NULL != client.conn.playing && can_client_issue_orders()) {
1088 struct unit *punit;
1090 punit = head_of_units_in_focus();
1091 if (punit && punit->battlegroup == battlegroup) {
1092 /* If top unit already in the same battlegroup, detach it */
1093 unit_change_battlegroup(punit, BATTLEGROUP_NONE);
1094 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
1095 } else {
1096 key_unit_assign_battlegroup(battlegroup, TRUE);
1101 /****************************************************************************
1102 Stub for editor function
1103 ****************************************************************************/
1104 void editgui_tileset_changed(void)
1107 /****************************************************************************
1108 Stub for editor function
1109 ****************************************************************************/
1110 void editgui_refresh(void)
1113 /****************************************************************************
1114 Stub for editor function
1115 ****************************************************************************/
1116 void editgui_popup_properties(const struct tile_list *tiles, int objtype)
1119 /****************************************************************************
1120 Stub for editor function
1121 ****************************************************************************/
1122 void editgui_popdown_all(void)
1125 /****************************************************************************
1126 Stub for editor function
1127 ****************************************************************************/
1128 void editgui_notify_object_changed(int objtype, int object_id, bool removal)
1131 /****************************************************************************
1132 Stub for editor function
1133 ****************************************************************************/
1134 void editgui_notify_object_created(int tag, int id)
1137 /**************************************************************************
1138 Updates a gui font style.
1139 **************************************************************************/
1140 void gui_update_font(const char *font_name, const char *font_value)
1142 /* PORTME */
1145 /**************************************************************************
1146 Insert build information to help
1147 **************************************************************************/
1148 void insert_client_build_info(char *outbuf, size_t outlen)
1150 /* PORTME */
1153 /**************************************************************************
1154 Make dynamic adjustments to first-launch default options.
1155 **************************************************************************/
1156 void adjust_default_options(void)
1158 /* Nothing in case of this gui */