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)
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 ***********************************************************************/
16 #include <fc_config.h>
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
26 #include <SDL_mixer.h>
30 #else /* AUDIO_SDL1_2 */
33 #endif /* AUDIO_SDL1_2 */
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>
57 #include "fc_cmdline.h"
65 #include "government.h"
71 #include "chatline_common.h"
72 #include "client_main.h"
76 #include "editgui_g.h"
82 #include "xaw_actions.h"
86 #include "gui_stuff.h" /* I_SW() */
89 #include "optiondlg.h"
91 #include "resources.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
},
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
},
140 /**************************************************************************
142 **************************************************************************/
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" }*/
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 /**************************************************************************/
178 int researchedpoints
;
180 int tax
, luxurary
, research
;
183 /**************************************************************************/
188 enum Display_color_type display_color_type
;
189 XtAppContext app_context
;
191 /* this GC will be the default one all thru freeciv */
194 /* This is for drawing border lines */
197 /* and this one is used for filling with the bg color */
200 Pixmap gray50
,gray25
;
202 /* overall font GC */
204 XFontSet main_font_set
;
205 /* productions font GC */
207 XFontSet prod_font_set
;
209 Widget toplevel
, main_form
, menu_form
, below_menu_form
, left_column_form
;
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
;
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
];
224 Pixmap unit_below_pixmap
[MAX_NUM_UNITS_BELOW
];
225 Widget more_arrow_label
;
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.");
244 /**************************************************************************
246 **************************************************************************/
247 /* This is used below in ui_main(), in commented out code. */
248 static int myerr(Display
*p
, XErrorEvent
*e
)
255 /**************************************************************************
256 Print extra usage information, including one line help on each option,
258 **************************************************************************/
259 static void print_usage(void)
261 /* add client-specific usage information here */
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
)
279 if (is_option("--help", argv
[i
])) {
283 fc_fprintf(stderr
, _("Unrecognized option: \"%s\"\n"), argv
[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
);
303 /**************************************************************************
305 **************************************************************************/
311 /****************************************************************************
312 Extra initializers for client options.
313 ****************************************************************************/
314 void options_extra_init(void)
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
[])
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 */
345 cmd_options
, XtNumber(cmd_options
),
349 /* command line option list */
350 &argc
, argv
, /* command line args */
351 &fallback_resources
[1], /* for missing app-defaults file */
352 XtNallowShellResize
, True
,
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."));
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"));
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); */
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
,
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."));
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
,
428 prod_font_set
= XCreateFontSet(display
, city_productions_font_name
,
429 &missing_charset_list_return
,
430 &missing_charset_count_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."));
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
,
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
,
462 values
.fill_style
= FillStippled
;
463 fill_tile_gc
= XCreateGC(display
, root_window
,
464 GCForeground
|GCBackground
|GCFillStyle
|GCGraphicsExposures
,
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)
484 tileset_init(tileset
);
485 tileset_load_tiles(tileset
);
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
) {
538 fc_snprintf(buffer
, sizeof(buffer
), _("Commit: %s"), rev_ver
);
539 output_window_append(ftc_client
, buffer
);
542 XtAppMainLoop(app_context
);
547 /**************************************************************************
548 Do any necessary UI-specific cleanup
549 **************************************************************************/
554 /**************************************************************************
556 **************************************************************************/
557 enum gui_type
get_gui_type(void)
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
,
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 */
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)
592 int econ_label_count
=10, econ_label_space
=1;
594 main_form
= XtVaCreateManagedWidget("mainform", formWidgetClass
,
598 menu_form
= XtVaCreateManagedWidget("menuform", formWidgetClass
,
601 setup_menus(menu_form
);
604 main_vpane= XtVaCreateManagedWidget("mainvpane",
609 below_menu_form = XtVaCreateManagedWidget("belowmenuform",
614 below_menu_form
= XtVaCreateManagedWidget("belowmenuform",
619 left_column_form
= XtVaCreateManagedWidget("leftcolumnform",
624 map_form
= XtVaCreateManagedWidget("mapform",
629 bottom_form
= XtVaCreateManagedWidget("bottomform",
631 /*main_vpane,*/ main_form
,
634 overview_canvas
= XtVaCreateManagedWidget("overviewcanvas",
635 xfwfcanvasWidgetClass
,
638 (XtArgVal
)overview_canvas_expose
,
643 info_command
= XtVaCreateManagedWidget("infocommand",
647 (XtArgVal
)overview_canvas
,
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",
656 XtNwidth
, tileset_small_sprite_width(tileset
),
657 XtNheight
, tileset_small_sprite_height(tileset
),
659 i
?econ_label
[i
-1]:NULL
,
660 XtNhorizDistance
, econ_label_space
,
664 bulb_label
= XtVaCreateManagedWidget("bulblabel",
669 sun_label
= XtVaCreateManagedWidget("sunlabel",
674 flake_label
= XtVaCreateManagedWidget("flakelabel",
679 government_label
= XtVaCreateManagedWidget("governmentlabel",
684 timeout_label
= XtVaCreateManagedWidget("timeoutlabel",
691 I_LW(XtVaCreateManagedWidget("turndonebutton",
694 XtNwidth
, econ_label_count
*
695 (tileset_small_sprite_width(tileset
)+econ_label_space
),
699 unit_info_label
= XtVaCreateManagedWidget("unitinfolabel",
704 unit_pix_canvas
= XtVaCreateManagedWidget("unitpixcanvas",
707 XtNwidth
, tileset_full_tile_width(tileset
),
708 XtNheight
, tileset_full_tile_height(tileset
),
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
,
719 tileset_full_tile_width(tileset
),
721 tileset_full_tile_height(tileset
),
723 XtAddCallback(unit_below_canvas
[i
], XtNcallback
, unit_icon_callback
,
728 XtVaCreateManagedWidget("morearrowlabel",
732 (XtArgVal
)unit_below_canvas
[num_units_below
-1],
735 map_vertical_scrollbar
= XtVaCreateManagedWidget("mapvertiscrbar",
736 scrollbarWidgetClass
,
740 map_canvas
= XtVaCreateManagedWidget("mapcanvas",
741 xfwfcanvasWidgetClass
,
744 (XtArgVal
)map_canvas_expose
,
749 map_horizontal_scrollbar
= XtVaCreateManagedWidget("maphorizscrbar",
750 scrollbarWidgetClass
,
756 outputwindow_text
= I_SW(XtVaCreateManagedWidget("outputwindowtext",
757 asciiTextWidgetClass
,
762 inputline_text
= XtVaCreateManagedWidget("inputlinetext",
763 asciiTextWidgetClass
,
769 /**************************************************************************
771 **************************************************************************/
772 void xaw_ui_exit(void)
774 free_mapcanvas_and_overview();
775 tileset_free_tiles(tileset
);
779 /**************************************************************************
781 **************************************************************************/
782 void main_show_info_popup(XEvent
*event
)
784 XButtonEvent
*ev
= (XButtonEvent
*)event
;
786 if (ev
->button
== Button1
) {
791 p
= XtCreatePopupShell("popupinfo",
792 overrideShellWidgetClass
,
793 info_command
, NULL
, 0);
795 XtAddCallback(p
, XtNpopdownCallback
, destroy_me_callback
, NULL
);
797 XtVaCreateManagedWidget("fullinfopopuplabel",
800 XtNlabel
, get_info_label_text_popup(),
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)
821 /**************************************************************************
823 **************************************************************************/
824 void sound_bell(void)
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
)
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
|
852 XtInputWriteMask
: 0) |
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
|
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
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
);
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
)
912 fc_assert_ret(idx
>= -1 && idx
< num_units_below
);
916 w
= unit_below_canvas
[idx
];
917 unit_ids
[idx
] = punit
? punit
->id
: 0;
922 struct canvas store
= {XawPixcommPixmap(w
)};
924 put_unit(punit
, &store
, 1.0, 0, 0);
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
);
944 else if(!onoff
&& showing
) {
945 xaw_set_bitmap(more_arrow_label
, None
);
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)
961 void (*callback
)(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
);
974 /* return True if we want to remove WorkProc */
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
982 ****************************************************************************/
983 void add_idle_callback(void (callback
)(void *), void *data
)
985 struct callback
*cb
= fc_malloc(sizeof(*cb
));
987 cb
->callback
= callback
;
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)
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
,
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)
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),
1028 */ unit_below_pixmap
[i
] = XCreatePixmap(display
, XtWindow(overview_canvas
),
1029 tileset_full_tile_width(tileset
),
1030 tileset_full_tile_height(tileset
),
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)
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());
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()) {
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
);
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
)
1145 /**************************************************************************
1146 Insert build information to help
1147 **************************************************************************/
1148 void insert_client_build_info(char *outbuf
, size_t outlen
)
1153 /**************************************************************************
1154 Make dynamic adjustments to first-launch default options.
1155 **************************************************************************/
1156 void adjust_default_options(void)
1158 /* Nothing in case of this gui */