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 #include <stdarg.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <X11/Intrinsic.h>
23 #include <X11/StringDefs.h>
24 #include <X11/Xaw/AsciiText.h>
25 #include <X11/Xaw/Command.h>
26 #include <X11/Xaw/Form.h>
27 #include <X11/Xaw/Label.h>
28 #include <X11/Xaw/List.h>
29 #include <X11/Xaw/MenuButton.h>
30 #include <X11/Xaw/SimpleMenu.h>
31 #include <X11/Xaw/SmeBSB.h>
32 #include <X11/Xaw/Toggle.h>
33 #include <X11/Xaw/Viewport.h> /* for racesdlg */
34
35 /* utility */
36 #include "bitvector.h"
37 #include "fcintl.h"
38 #include "log.h"
39 #include "mem.h"
40 #include "rand.h"
41 #include "support.h"
42
43 /* common */
44 #include "game.h"
45 #include "government.h"
46 #include "map.h"
47 #include "packets.h"
48 #include "player.h"
49 #include "unitlist.h"
50
51 /* client */
52 #include "chatline.h"
53 #include "cityrep.h" /* city_report_dialog_popdown() */
54 #include "client_main.h"
55 #include "climisc.h"
56 #include "control.h" /* request_xxx and unit_focus_set */
57 #include "graphics.h"
58 #include "gui_main.h"
59 #include "gui_stuff.h"
60 #include "mapctrl.h"
61 #include "mapctrl_common.h"
62 #include "mapview.h"
63 #include "messagewin.h" /* meswin_dialog_popdown() */
64 #include "options.h"
65 #include "packhand.h"
66 #include "plrdlg.h" /* for popdown_players_dialog */
67 #include "repodlgs.h" /* for popdown_xxx_dialog */
68 #include "text.h"
69 #include "tilespec.h"
70
71 #include "dialogs.h"
72
73 /******************************************************************/
74 void popdown_notify_dialog(void);
75 static Widget notify_dialog_shell;
76
77 /******************************************************************/
78 static Widget races_dialog_shell=NULL;
79 static Widget races_form, races_toggles_form, races_label;
80 static Widget races_toggles_viewport;
81 static Widget *races_toggles=NULL;
82 static struct nation_type **races_toggles_to_nations = NULL;
83 static int *nation_idx_to_race_toggle = NULL;
84 struct player *races_player;
85 static Widget races_leader_form, races_leader;
86 static Widget races_leader_pick_popupmenu, races_leader_pick_menubutton;
87 static Widget races_sex_toggles[2], races_sex_form, races_sex_label;
88 static Widget races_style_form, races_style_label;
89 static Widget *races_style_toggles=NULL;
90 static Widget races_action_form;
91 static Widget races_ok_command, races_random_command, races_quit_command;
92
93
94 /******************************************************************/
95 #define MAX_SELECT_UNITS 100
96 static Widget unit_select_dialog_shell;
97 static Widget unit_select_form;
98 static Widget unit_select_commands[MAX_SELECT_UNITS];
99 static Widget unit_select_labels[MAX_SELECT_UNITS];
100 static Pixmap unit_select_pixmaps[MAX_SELECT_UNITS];
101 static int unit_select_ids[MAX_SELECT_UNITS];
102 static int unit_select_no;
103
104 void about_button_callback(Widget w, XtPointer client_data,
105 XtPointer call_data);
106
107 void help_button_callback(Widget w, XtPointer client_data,
108 XtPointer call_data);
109
110 void create_rates_dialog(void);
111 void create_about_dialog(void);
112 void create_help_dialog(Widget *shell);
113
114
115 /******************************************************************/
116 static void create_races_dialog(struct player *pplayer);
117 static void races_leader_set_values(struct nation_type *race, int lead);
118 static int races_buttons_get_current(void);
119 static int races_sex_buttons_get_current(void);
120 static int races_style_buttons_get_current(void);
121 static void races_sex_buttons_set_current(int i);
122
123 static int races_indirect_compare(const void *first, const void *second);
124
125 static void races_toggles_callback(Widget w, XtPointer client_data,
126 XtPointer call_data);
127 static void races_leader_pick_callback(Widget w, XtPointer client_data,
128 XtPointer call_data);
129 static void races_ok_command_callback(Widget w, XtPointer client_data,
130 XtPointer call_data);
131 static void races_random_command_callback(Widget w, XtPointer client_data,
132 XtPointer call_data);
133 static void races_quit_command_callback(Widget w, XtPointer client_data,
134 XtPointer call_data);
135
136 /******************************************************************/
137 void unit_select_callback(Widget w, XtPointer client_data,
138 XtPointer call_data);
139 void unit_select_all_callback(Widget w, XtPointer client_data,
140 XtPointer call_data);
141
142
143 /******************************************************************/
144 static int city_style_idx[64]; /* translation table basic style->city_style */
145 static int city_style_ridx[64]; /* translation table the other way */
146 /* they in fact limit the num of styles to 64 */
147
148 /******************************************************************/
149
150 int is_showing_pillage_dialog = FALSE;
151 int unit_to_use_to_pillage;
152
153 /****************************************************************
154 ...
155 *****************************************************************/
notify_command_callback(Widget w,XtPointer client_data,XtPointer call_data)156 static void notify_command_callback(Widget w, XtPointer client_data,
157 XtPointer call_data)
158 {
159 popdown_notify_dialog();
160 }
161
162 /****************************************************************
163 ...
164 *****************************************************************/
select_random_race(void)165 static void select_random_race(void)
166 {
167 /* try to find a free nation */
168 /* FIXME: this code should be done another way. -ev */
169 while (1) {
170 unsigned int race_toggle_index = fc_rand(nation_count());
171 const struct nation_type *pnation =
172 races_toggles_to_nations[race_toggle_index];
173
174 if (!pnation
175 || !is_nation_playable(pnation)
176 || !is_nation_pickable(pnation)
177 || pnation->player) {
178 continue;
179 }
180 if (XtIsSensitive(races_toggles[race_toggle_index])) {
181 x_simulate_button_click(races_toggles[race_toggle_index]);
182 break;
183 }
184 }
185 }
186
187 /**************************************************************************
188 Popup a generic dialog to display some generic information.
189 **************************************************************************/
popup_notify_dialog(const char * caption,const char * headline,const char * lines)190 void popup_notify_dialog(const char *caption, const char *headline,
191 const char *lines)
192 {
193 Widget notify_form, notify_command;
194 Widget notify_headline, notify_label;
195 Dimension width, width2;
196
197 notify_dialog_shell = XtCreatePopupShell(caption,
198 transientShellWidgetClass,
199 toplevel, NULL, 0);
200
201 notify_form = XtVaCreateManagedWidget("notifyform",
202 formWidgetClass,
203 notify_dialog_shell, NULL);
204
205 notify_headline=XtVaCreateManagedWidget("notifyheadline",
206 labelWidgetClass, notify_form,
207 XtNlabel, headline,
208 NULL);
209
210
211 notify_label=XtVaCreateManagedWidget("notifylabel",
212 labelWidgetClass, notify_form,
213 XtNlabel, lines,
214 NULL);
215
216 notify_command =
217 I_L(XtVaCreateManagedWidget("notifycommand",
218 commandWidgetClass,
219 notify_form,
220 NULL));
221
222 XtVaGetValues(notify_label, XtNwidth, &width, NULL);
223 XtVaGetValues(notify_headline, XtNwidth, &width2, NULL);
224 if(width>width2)
225 XtVaSetValues(notify_headline, XtNwidth, width, NULL);
226
227 XtAddCallback(notify_command, XtNcallback, notify_command_callback, NULL);
228
229 xaw_set_relative_position(toplevel, notify_dialog_shell, 25, 5);
230 XtPopup(notify_dialog_shell, XtGrabNone);
231 XtSetSensitive(toplevel, FALSE);
232 }
233
234 /****************************************************************
235 Closes the notification dialog.
236 *****************************************************************/
popdown_notify_dialog(void)237 void popdown_notify_dialog(void)
238 {
239 if (notify_dialog_shell) {
240 XtDestroyWidget(notify_dialog_shell);
241 XtSetSensitive(toplevel, TRUE);
242 notify_dialog_shell = 0;
243 }
244 }
245
246 /****************************************************************
247 ...
248 *****************************************************************/
249
250 /* surely this should use genlists?? --dwp */
251 struct widget_list {
252 Widget w;
253 struct tile *tile;
254 struct widget_list *next;
255 };
256 static struct widget_list *notify_goto_widget_list = NULL;
257
notify_goto_widget_remove(Widget w)258 static void notify_goto_widget_remove(Widget w)
259 {
260 struct widget_list *cur, *tmp;
261 cur=notify_goto_widget_list;
262 if (!cur)
263 return;
264 if (cur && cur->w == w) {
265 cur = cur->next;
266 free(notify_goto_widget_list);
267 notify_goto_widget_list = cur;
268 return;
269 }
270 for (; cur->next && cur->next->w!= w; cur=cur->next);
271 if (cur->next) {
272 tmp = cur->next;
273 cur->next = cur->next->next;
274 free(tmp);
275 }
276 }
277
notify_goto_find_widget(Widget w)278 static struct tile *notify_goto_find_widget(Widget w)
279 {
280 struct widget_list *cur;
281
282 for (cur = notify_goto_widget_list; cur && cur->w !=w; cur = cur->next) {
283 /* Nothing. */
284 }
285
286 if (cur) {
287 return cur->tile;
288 } else {
289 return NULL;
290 }
291 }
292
notify_goto_add_widget_tile(Widget w,struct tile * ptile)293 static void notify_goto_add_widget_tile(Widget w, struct tile *ptile)
294 {
295 struct widget_list *newwidget;
296
297 newwidget = fc_malloc(sizeof(*newwidget));
298 newwidget->w = w;
299 newwidget->tile = ptile;
300 newwidget->next = notify_goto_widget_list;
301 notify_goto_widget_list = newwidget;
302 }
303
notify_goto_command_callback(Widget w,XtPointer client_data,XtPointer call_data)304 static void notify_goto_command_callback(Widget w, XtPointer client_data,
305 XtPointer call_data)
306 {
307 struct tile *ptile = notify_goto_find_widget(w);
308
309 center_tile_mapcanvas(ptile);
310 notify_goto_widget_remove(w);
311
312 XtDestroyWidget(XtParent(XtParent(w)));
313 XtSetSensitive(toplevel, TRUE);
314 }
315
notify_no_goto_command_callback(Widget w,XtPointer client_data,XtPointer call_data)316 static void notify_no_goto_command_callback(Widget w, XtPointer client_data,
317 XtPointer call_data)
318 {
319 notify_goto_widget_remove(w);
320 XtDestroyWidget(XtParent(XtParent(w)));
321 XtSetSensitive(toplevel, TRUE);
322 }
323
324
325 /**************************************************************************
326 Popup a dialog to display information about an event that has a
327 specific location. The user should be given the option to goto that
328 location.
329 **************************************************************************/
popup_notify_goto_dialog(const char * headline,const char * lines,const struct text_tag_list * tags,struct tile * ptile)330 void popup_notify_goto_dialog(const char *headline, const char *lines,
331 const struct text_tag_list *tags,
332 struct tile *ptile)
333 {
334 Widget notify_gdialog_shell, notify_form, notify_command, notify_goto_command;
335 Widget notify_headline, notify_label;
336 Dimension width, width2, width_1, width_2;
337
338 if (!ptile) {
339 popup_notify_dialog("Message:", headline, lines);
340 return;
341 }
342 notify_gdialog_shell = XtCreatePopupShell("Message:",
343 transientShellWidgetClass,
344 toplevel, NULL, 0);
345
346 notify_form = XtVaCreateManagedWidget("notifyform",
347 formWidgetClass,
348 notify_gdialog_shell, NULL);
349
350 notify_headline=XtVaCreateManagedWidget("notifyheadline",
351 labelWidgetClass, notify_form,
352 XtNlabel, headline,
353 NULL);
354
355
356 notify_label=XtVaCreateManagedWidget("notifylabel",
357 labelWidgetClass, notify_form,
358 XtNlabel, lines,
359 NULL);
360
361 notify_command =
362 I_L(XtVaCreateManagedWidget("notifycommand",
363 commandWidgetClass,
364 notify_form,
365 NULL));
366
367 notify_goto_command =
368 I_L(XtVaCreateManagedWidget("notifygotocommand",
369 commandWidgetClass,
370 notify_form,
371 NULL));
372
373 XtVaGetValues(notify_label, XtNwidth, &width, NULL);
374 XtVaGetValues(notify_headline, XtNwidth, &width2, NULL);
375 XtVaGetValues(notify_command, XtNwidth, &width_1, NULL);
376 XtVaGetValues(notify_goto_command, XtNwidth, &width_2, NULL);
377 if (width_1 + width_2 > width) width = width_1 + width_2;
378 if(width>width2)
379 XtVaSetValues(notify_headline, XtNwidth, width, NULL);
380
381 XtAddCallback(notify_command, XtNcallback, notify_no_goto_command_callback, NULL);
382 XtAddCallback(notify_goto_command, XtNcallback, notify_goto_command_callback, NULL);
383 notify_goto_add_widget_tile(notify_goto_command, ptile);
384 xaw_set_relative_position(toplevel, notify_gdialog_shell, 25, 5);
385 XtPopup(notify_gdialog_shell, XtGrabNone);
386 /* XtSetSensitive(toplevel, FALSE); */
387 }
388
389 /**************************************************************************
390 Popup a dialog to display connection message from server.
391 **************************************************************************/
popup_connect_msg(const char * headline,const char * message)392 void popup_connect_msg(const char *headline, const char *message)
393 {
394 /* FIXME: Needs proper implementation.
395 * Now just puts to chat window so message is not completely lost. */
396
397 output_window_append(ftc_client, message);
398 }
399
400 /****************************************************************
401 ...
402 *****************************************************************/
revolution_callback_yes(Widget w,XtPointer client_data,XtPointer call_data)403 static void revolution_callback_yes(Widget w, XtPointer client_data,
404 XtPointer call_data)
405 {
406 struct government *pgovernment = client_data;
407
408 if (!pgovernment) {
409 start_revolution();
410 } else {
411 /* Player have choosed government */
412 set_government_choice(pgovernment);
413 }
414 destroy_message_dialog(w);
415 }
416
417 /****************************************************************
418 ...
419 *****************************************************************/
revolution_callback_no(Widget w,XtPointer client_data,XtPointer call_data)420 static void revolution_callback_no(Widget w, XtPointer client_data,
421 XtPointer call_data)
422 {
423 destroy_message_dialog(w);
424 }
425
426
427
428 /****************************************************************
429 ...
430 *****************************************************************/
popup_revolution_dialog(struct government * pgovernment)431 void popup_revolution_dialog(struct government *pgovernment)
432 {
433 popup_message_dialog(toplevel, "revolutiondialog",
434 _("You say you wanna revolution?"),
435 revolution_callback_yes, pgovernment, 0,
436 revolution_callback_no, 0, 0,
437 NULL);
438 }
439
440 /**************************************************************************
441 User requested closing of pillage dialog.
442 **************************************************************************/
pillage_callback(Widget w,XtPointer client_data,XtPointer call_data)443 static void pillage_callback(Widget w, XtPointer client_data,
444 XtPointer call_data)
445 {
446 if (!is_showing_pillage_dialog) {
447 destroy_message_dialog (w);
448 return;
449 }
450
451 if (client_data) {
452 struct unit *punit = game_unit_by_number(unit_to_use_to_pillage);
453 if (punit) {
454 struct extra_type *target;
455 int what = XTPOINTER_TO_INT(client_data);
456
457 target = extra_by_number(what);
458
459 request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE,
460 target);
461 }
462 }
463
464 destroy_message_dialog (w);
465 is_showing_pillage_dialog = FALSE;
466 }
467
468 /**************************************************************************
469 Popup a dialog asking the unit which improvement they would like to
470 pillage.
471 **************************************************************************/
popup_pillage_dialog(struct unit * punit,bv_extras extras)472 void popup_pillage_dialog(struct unit *punit, bv_extras extras)
473 {
474 Widget shell, form, dlabel, button, prev;
475 struct extra_type *tgt;
476
477 if (is_showing_pillage_dialog) {
478 return;
479 }
480 is_showing_pillage_dialog = TRUE;
481 unit_to_use_to_pillage = punit->id;
482
483 XtSetSensitive (toplevel, FALSE);
484
485 shell = I_T(XtCreatePopupShell("pillagedialog", transientShellWidgetClass,
486 toplevel, NULL, 0));
487 form = XtVaCreateManagedWidget ("form", formWidgetClass, shell, NULL);
488 dlabel = I_L(XtVaCreateManagedWidget("dlabel", labelWidgetClass, form, NULL));
489
490 prev = dlabel;
491 while ((tgt = get_preferred_pillage(extras))) {
492 int what;
493
494 what = extra_index(tgt);
495
496 BV_CLR(extras, what);
497
498 button =
499 XtVaCreateManagedWidget ("button", commandWidgetClass, form,
500 XtNfromVert, prev,
501 XtNlabel,
502 (XtArgVal)(extra_name_translation(tgt)),
503 NULL);
504 XtAddCallback(button, XtNcallback, pillage_callback,
505 INT_TO_XTPOINTER(what));
506
507 prev = button;
508 }
509 button =
510 I_L(XtVaCreateManagedWidget("closebutton", commandWidgetClass, form,
511 XtNfromVert, prev,
512 NULL));
513 XtAddCallback (button, XtNcallback, pillage_callback, NULL);
514
515 xaw_set_relative_position (toplevel, shell, 10, 0);
516 XtPopup (shell, XtGrabNone);
517 }
518
519 /****************************************************************
520 ...
521 *****************************************************************/
unitdisband_callback_yes(Widget w,XtPointer client_data,XtPointer call_data)522 static void unitdisband_callback_yes(Widget w, XtPointer client_data, XtPointer call_data)
523 {
524 struct unit_list *punits = client_data;
525
526 /* Is it right place for breaking? -ev */
527 if (!can_client_issue_orders()) {
528 unit_list_destroy(punits);
529 return;
530 }
531
532 unit_list_iterate(punits, punit) {
533 if (!unit_has_type_flag(punit, UTYF_UNDISBANDABLE)) {
534 request_unit_disband(punit);
535 }
536 } unit_list_iterate_end;
537
538 unit_list_destroy(punits);
539 destroy_message_dialog(w);
540 }
541
542
543 /****************************************************************
544 ...
545 *****************************************************************/
unitdisband_callback_no(Widget w,XtPointer client_data,XtPointer call_data)546 static void unitdisband_callback_no(Widget w, XtPointer client_data, XtPointer call_data)
547 {
548 destroy_message_dialog(w);
549 }
550
551
552 /****************************************************************
553 ...
554 *****************************************************************/
popup_disband_dialog(struct unit_list * punits)555 void popup_disband_dialog(struct unit_list *punits)
556 {
557 char buf[512];
558
559 if (get_units_disband_info(buf, sizeof(buf), punits)) {
560 struct unit_list *punits2 = unit_list_copy(punits);
561 popup_message_dialog(toplevel, "disbanddialog", buf,
562 unitdisband_callback_yes,
563 punits2, 0,
564 unitdisband_callback_no, 0, 0, NULL);
565 } else {
566 popup_message_dialog(toplevel, "disbandnodialog", buf,
567 unitdisband_callback_no, 0, 0,
568 NULL);
569 }
570 }
571
572
573 /****************************************************************
574 Parameters after named parameters should be in triplets:
575 - callback, callback_data, fixed_width
576 *****************************************************************/
popup_message_dialog(Widget parent,const char * dialogname,const char * text,...)577 Widget popup_message_dialog(Widget parent, const char *dialogname,
578 const char *text, ...)
579 {
580 va_list args;
581 Widget dshell, dform, button;
582 Position x, y;
583 Dimension width, height;
584 void (*fcb)(Widget, XtPointer, XtPointer);
585 XtPointer client_data;
586 char button_name[512];
587 int i, fixed_width;
588
589 XtSetSensitive(parent, FALSE);
590
591 I_T(dshell=XtCreatePopupShell(dialogname, transientShellWidgetClass,
592 parent, NULL, 0));
593
594 dform=XtVaCreateManagedWidget("dform", formWidgetClass, dshell, NULL);
595
596 /* caller should i18n text as desired */
597 XtVaCreateManagedWidget("dlabel", labelWidgetClass, dform,
598 XtNlabel, (XtArgVal)text,
599 NULL);
600
601 i=0;
602 va_start(args, text);
603
604 while((fcb=((void(*)(Widget, XtPointer, XtPointer))(va_arg(args, void *))))) {
605 client_data=va_arg(args, XtPointer);
606 fixed_width=va_arg(args, int);
607 fc_snprintf(button_name, sizeof(button_name), "button%d", i++);
608
609 button=XtVaCreateManagedWidget(button_name, commandWidgetClass,
610 dform, NULL);
611 if (fixed_width) {
612 I_LW(button);
613 } else {
614 I_L(button);
615 }
616 XtAddCallback(button, XtNcallback, fcb, client_data);
617 }
618
619 va_end(args);
620
621 XtVaGetValues(parent, XtNwidth, &width, XtNheight, &height, NULL);
622 XtTranslateCoords(parent, (Position) width/10, (Position) height/10,
623 &x, &y);
624 XtVaSetValues(dshell, XtNx, x, XtNy, y, NULL);
625
626 XtPopup(dshell, XtGrabNone);
627
628 return dshell;
629 }
630
631 /****************************************************************
632 ...
633 *****************************************************************/
destroy_message_dialog(Widget button)634 void destroy_message_dialog(Widget button)
635 {
636 XtSetSensitive(XtParent(XtParent(XtParent(button))), TRUE);
637
638 XtDestroyWidget(XtParent(XtParent(button)));
639 }
640
number_of_columns(int n)641 static int number_of_columns(int n)
642 {
643 #if 0
644 /* This would require libm, which isn't worth it for this one little
645 * function. Since MAX_SELECT_UNITS is 100 already, the ifs
646 * work fine. */
647 double sqrt(); double ceil();
648 return ceil(sqrt((double)n/5.0));
649 #else
650 fc_assert(MAX_SELECT_UNITS == 100);
651 if(n<=5) return 1;
652 else if(n<=20) return 2;
653 else if(n<=45) return 3;
654 else if(n<=80) return 4;
655 else return 5;
656 #endif
657 }
number_of_rows(int n)658 static int number_of_rows(int n)
659 {
660 int c=number_of_columns(n);
661 return (n+c-1)/c;
662 }
663
664 /****************************************************************
665 popup the dialog 10% inside the main-window
666 *****************************************************************/
unit_select_dialog_popup(struct tile * ptile)667 void unit_select_dialog_popup(struct tile *ptile)
668 {
669 int i,n,r;
670 char buffer[512];
671 Arg args[4];
672 int nargs;
673 Widget unit_select_all_command, unit_select_close_command;
674 Widget firstcolumn=0,column=0;
675 Pixel bg;
676 struct unit *unit_list[unit_list_size(ptile->units)];
677
678 XtSetSensitive(main_form, FALSE);
679
680 unit_select_dialog_shell =
681 I_T(XtCreatePopupShell("unitselectdialogshell",
682 transientShellWidgetClass,
683 toplevel, NULL, 0));
684
685 unit_select_form = XtVaCreateManagedWidget("unitselectform",
686 formWidgetClass,
687 unit_select_dialog_shell, NULL);
688
689 XtVaGetValues(unit_select_form, XtNbackground, &bg, NULL);
690 XSetForeground(display, fill_bg_gc, bg);
691
692 n = MIN(MAX_SELECT_UNITS, unit_list_size(ptile->units));
693 r = number_of_rows(n);
694
695 fill_tile_unit_list(ptile, unit_list);
696
697 for (i = 0; i < n; i++) {
698 struct unit *punit = unit_list[i];
699 struct unit_type *punittemp = unit_type_get(punit);
700 struct city *pcity;
701 struct canvas store;
702
703 if (!(i % r)) {
704 nargs = 0;
705 if ( i ) {
706 XtSetArg(args[nargs], XtNfromHoriz, column);
707 nargs++;
708 }
709 column = XtCreateManagedWidget("column", formWidgetClass,
710 unit_select_form,
711 args, nargs);
712 if (!i) {
713 firstcolumn = column;
714 }
715 }
716
717 unit_select_ids[i]=punit->id;
718
719 pcity = player_city_by_number(client_player(), punit->homecity);
720
721 fc_snprintf(buffer, sizeof(buffer), "%s(%s)\n%s",
722 utype_name_translation(punittemp),
723 pcity ? city_name_get(pcity) : "",
724 unit_activity_text(punit));
725
726 unit_select_pixmaps[i]=XCreatePixmap(display, XtWindow(map_canvas),
727 tileset_full_tile_width(tileset), tileset_full_tile_height(tileset),
728 display_depth);
729
730 XFillRectangle(display, unit_select_pixmaps[i], fill_bg_gc,
731 0, 0, tileset_full_tile_width(tileset), tileset_full_tile_height(tileset));
732 store.pixmap = unit_select_pixmaps[i];
733 put_unit(punit, &store, 1.0, 0, 0);
734
735 nargs=0;
736 XtSetArg(args[nargs], XtNbitmap, (XtArgVal)unit_select_pixmaps[i]);nargs++;
737 XtSetArg(args[nargs], XtNsensitive,
738 can_unit_do_activity(punit, ACTIVITY_IDLE));nargs++;
739 if(i%r) {
740 XtSetArg(args[nargs], XtNfromVert, unit_select_commands[i-1]); nargs++;
741 }
742 unit_select_commands[i]=XtCreateManagedWidget("unitselectcommands",
743 commandWidgetClass,
744 column, args, nargs);
745
746 nargs=0;
747 XtSetArg(args[nargs], XtNlabel, (XtArgVal)buffer); nargs++;
748 XtSetArg(args[nargs], XtNfromHoriz, unit_select_commands[i]); nargs++;
749 if(i%r) {
750 XtSetArg(args[nargs], XtNfromVert, unit_select_commands[i-1]); nargs++;
751 }
752 unit_select_labels[i]=XtCreateManagedWidget("unitselectlabels",
753 labelWidgetClass,
754 column, args, nargs);
755
756 XtAddCallback(unit_select_commands[i],
757 XtNdestroyCallback,free_bitmap_destroy_callback, NULL);
758 XtAddCallback(unit_select_commands[i],
759 XtNcallback, unit_select_callback, NULL);
760 }
761
762 unit_select_no=i;
763
764 unit_select_close_command =
765 I_L(XtVaCreateManagedWidget("unitselectclosecommand",
766 commandWidgetClass,
767 unit_select_form,
768 XtNfromVert, firstcolumn,
769 NULL));
770
771 unit_select_all_command =
772 I_L(XtVaCreateManagedWidget("unitselectallcommand",
773 commandWidgetClass,
774 unit_select_form,
775 XtNfromVert, firstcolumn,
776 NULL));
777
778 XtAddCallback(unit_select_close_command, XtNcallback, unit_select_callback, NULL);
779 XtAddCallback(unit_select_all_command, XtNcallback, unit_select_all_callback, NULL);
780
781 xaw_set_relative_position(toplevel, unit_select_dialog_shell, 15, 10);
782 XtPopup(unit_select_dialog_shell, XtGrabNone);
783 }
784
785 /**************************************************************************
786 Update the dialog window to select units on a particular tile.
787 **************************************************************************/
unit_select_dialog_update_real(void * unused)788 void unit_select_dialog_update_real(void *unused)
789 {
790 /* PORTME */
791 }
792
793 /**************************************************************************
794 ...
795 **************************************************************************/
unit_select_all_callback(Widget w,XtPointer client_data,XtPointer call_data)796 void unit_select_all_callback(Widget w, XtPointer client_data,
797 XtPointer call_data)
798 {
799 int i;
800
801 XtSetSensitive(main_form, TRUE);
802 XtDestroyWidget(unit_select_dialog_shell);
803
804 for(i=0; i<unit_select_no; i++) {
805 struct unit *punit = player_unit_by_number(client_player(),
806 unit_select_ids[i]);
807 if(punit) {
808 unit_focus_set(punit);
809 }
810 }
811 }
812
813 /**************************************************************************
814 ...
815 **************************************************************************/
unit_select_callback(Widget w,XtPointer client_data,XtPointer call_data)816 void unit_select_callback(Widget w, XtPointer client_data,
817 XtPointer call_data)
818 {
819 int i;
820
821 XtSetSensitive(main_form, TRUE);
822 XtDestroyWidget(unit_select_dialog_shell);
823
824 for(i=0; i<unit_select_no; i++) {
825
826 if(unit_select_commands[i]==w) {
827 struct unit *punit = player_unit_by_number(client_player(),
828 unit_select_ids[i]);
829 if(punit) {
830 unit_focus_set(punit);
831 }
832 return;
833 }
834 }
835 }
836
837
838 /****************************************************************
839 popup the dialog 5% inside the main-window
840 *****************************************************************/
popup_races_dialog(struct player * pplayer)841 void popup_races_dialog(struct player *pplayer)
842 {
843 Position x, y;
844 Dimension width, height;
845
846 XtSetSensitive(main_form, FALSE);
847
848 if (!races_dialog_shell) {
849 create_races_dialog(pplayer);
850 }
851
852 XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
853
854 XtTranslateCoords(toplevel, (Position) width/20, (Position) height/20,
855 &x, &y);
856 XtVaSetValues(races_dialog_shell, XtNx, x, XtNy, y, NULL);
857
858 XtPopup(races_dialog_shell, XtGrabNone);
859 XtSetKeyboardFocus(toplevel, races_dialog_shell);
860 }
861
862 /****************************************************************
863 ...
864 *****************************************************************/
popdown_races_dialog(void)865 void popdown_races_dialog(void)
866 {
867 if (races_dialog_shell) {
868 XtSetSensitive(main_form, TRUE);
869 XtDestroyWidget(races_dialog_shell);
870 races_dialog_shell = NULL;
871 } /* else there is no dialog shell to destroy */
872 }
873
874 /****************************************************************
875 ...
876 *****************************************************************/
create_races_dialog(struct player * pplayer)877 void create_races_dialog(struct player *pplayer)
878 {
879 int per_row = 5;
880 int i, j, len, maxracelen, index, nat_count;
881 char maxracename[MAX_LEN_NAME];
882 char namebuf[64];
883 int space;
884 XtWidgetGeometry geom;
885
886 races_player = pplayer;
887 maxracelen = 0;
888 nations_iterate(pnation) {
889 if (is_nation_playable(pnation) && is_nation_pickable(pnation)) {
890 len = strlen(nation_adjective_translation(pnation));
891 maxracelen = MAX(maxracelen, len);
892 }
893 } nations_iterate_end;
894 maxracelen = MIN(maxracelen, MAX_LEN_NAME-1);
895 fc_snprintf(maxracename, sizeof(maxracename), "%*s", maxracelen+2, "W");
896
897 races_dialog_shell = I_T(XtCreatePopupShell("racespopup",
898 transientShellWidgetClass,
899 toplevel, NULL, 0));
900
901 races_form = XtVaCreateManagedWidget("racesform",
902 formWidgetClass,
903 races_dialog_shell, NULL);
904
905 races_label = I_L(XtVaCreateManagedWidget("raceslabel",
906 labelWidgetClass,
907 races_form, NULL));
908
909 races_toggles_viewport =
910 XtVaCreateManagedWidget("racestogglesviewport",
911 viewportWidgetClass,
912 races_form,
913 XtNfromVert, races_label,
914 NULL);
915
916 races_toggles_form =
917 XtVaCreateManagedWidget("racestogglesform",
918 formWidgetClass,
919 races_toggles_viewport,
920 NULL);
921
922 free(races_toggles);
923 races_toggles = fc_calloc(nation_count(), sizeof(Widget));
924 free(races_toggles_to_nations);
925 races_toggles_to_nations = fc_calloc(nation_count(),
926 sizeof(struct nation_type *));
927
928 i = 0;
929 j = 0;
930 index = 0;
931 nations_iterate(pnation) {
932 if (!is_nation_playable(pnation) || !is_nation_pickable(pnation)) {
933 continue;
934 }
935
936 if (j == 0) {
937 index = i * per_row;
938 fc_snprintf(namebuf, sizeof(namebuf), "racestoggle%d", index);
939 if (i == 0) {
940 races_toggles[index] =
941 XtVaCreateManagedWidget(namebuf,
942 toggleWidgetClass,
943 races_toggles_form,
944 XtNlabel, maxracename,
945 NULL);
946 } else {
947 races_toggles[index] =
948 XtVaCreateManagedWidget(namebuf,
949 toggleWidgetClass,
950 races_toggles_form,
951 XtNradioGroup,
952 races_toggles[index - 1],
953 XtNfromVert,
954 races_toggles[index - per_row],
955 XtNlabel, maxracename,
956 NULL);
957 }
958 } else {
959 index = i * per_row + j;
960 fc_snprintf(namebuf, sizeof(namebuf), "racestoggle%d", index);
961 if (i == 0) {
962 races_toggles[index] =
963 XtVaCreateManagedWidget(namebuf,
964 toggleWidgetClass,
965 races_toggles_form,
966 XtNradioGroup,
967 races_toggles[index - 1],
968 XtNfromHoriz,
969 races_toggles[index - 1],
970 XtNlabel, maxracename,
971 NULL);
972 } else {
973 races_toggles[index] =
974 XtVaCreateManagedWidget(namebuf,
975 toggleWidgetClass,
976 races_toggles_form,
977 XtNradioGroup,
978 races_toggles[index - 1],
979 XtNfromVert,
980 races_toggles[index - per_row],
981 XtNfromHoriz,
982 races_toggles[index - 1],
983 XtNlabel, maxracename,
984 NULL);
985 }
986 }
987
988 races_toggles_to_nations[index] = pnation;
989
990 j++;
991 if (j >= per_row) {
992 j = 0;
993 i++;
994 }
995 } nations_iterate_end;
996 nat_count = index + 1;
997
998 races_leader_form =
999 XtVaCreateManagedWidget("racesleaderform",
1000 formWidgetClass,
1001 races_form,
1002 XtNfromVert, races_toggles_viewport,
1003 /* XtNfromHoriz, races_toggles_viewport,*/
1004 NULL);
1005
1006 XtVaGetValues(races_leader_form, XtNdefaultDistance, &space, NULL);
1007 XtQueryGeometry(races_toggles[0], NULL, &geom);
1008 races_leader =
1009 XtVaCreateManagedWidget("racesleader",
1010 asciiTextWidgetClass,
1011 races_leader_form,
1012 XtNeditType, XawtextEdit,
1013 XtNwidth,
1014 space + 2*(geom.width + geom.border_width),
1015 XtNstring, "",
1016 NULL);
1017
1018 races_leader_pick_popupmenu = 0;
1019
1020 races_leader_pick_menubutton =
1021 I_L(XtVaCreateManagedWidget("racesleaderpickmenubutton",
1022 menuButtonWidgetClass,
1023 races_leader_form,
1024 /* XtNfromVert, races_leader,*/
1025 XtNfromHoriz, races_leader,
1026 NULL));
1027
1028 races_sex_label = I_L(XtVaCreateManagedWidget("racessexlabel",
1029 labelWidgetClass,
1030 races_form,
1031 XtNfromVert, races_leader_form,
1032 NULL));
1033
1034 races_sex_form = XtVaCreateManagedWidget("racessexform",
1035 formWidgetClass,
1036 races_form,
1037 XtNfromVert, races_sex_label,
1038 NULL);
1039
1040 races_sex_toggles[0] =
1041 I_L(XtVaCreateManagedWidget("racessextoggle0",
1042 toggleWidgetClass,
1043 races_sex_form,
1044 NULL));
1045
1046 races_sex_toggles[1] =
1047 I_L(XtVaCreateManagedWidget("racessextoggle1",
1048 toggleWidgetClass,
1049 races_sex_form,
1050 XtNfromHoriz,
1051 (XtArgVal)races_sex_toggles[0],
1052 XtNradioGroup,
1053 races_sex_toggles[0],
1054 NULL));
1055
1056 /* find out styles that can be used at the game beginning */
1057 /* Limit of 64 city_styles should be deleted. -ev */
1058 styles_iterate(pstyle) {
1059 i = basic_city_style_for_style(pstyle);
1060
1061 if (i >= 0) {
1062 int sn = style_number(pstyle);
1063
1064 city_style_idx[sn] = i;
1065 city_style_ridx[i] = sn;
1066 }
1067 } styles_iterate_end;
1068
1069 races_style_label =
1070 I_L(XtVaCreateManagedWidget("racesstylelabel",
1071 labelWidgetClass,
1072 races_form,
1073 XtNfromVert, races_sex_form,
1074 /* XtNfromHoriz, races_toggles_viewport,*/
1075 NULL));
1076
1077 races_style_form =
1078 XtVaCreateManagedWidget("racesstyleform",
1079 formWidgetClass,
1080 races_form,
1081 XtNfromVert, races_style_label,
1082 /* XtNfromHoriz, races_toggles_viewport,*/
1083 NULL);
1084
1085 free(races_style_toggles);
1086 races_style_toggles = fc_calloc(game.control.num_styles, sizeof(Widget));
1087
1088 for (i = 0; i < ((game.control.num_styles - 1) / per_row) + 1; i++) {
1089 index = i * per_row;
1090 fc_snprintf(namebuf, sizeof(namebuf), "racesstyle%d", index);
1091
1092 if (i == 0) {
1093 races_style_toggles[index] =
1094 XtVaCreateManagedWidget(namebuf,
1095 toggleWidgetClass,
1096 races_style_form,
1097 XtNlabel, maxracename,
1098 NULL);
1099 } else {
1100 races_style_toggles[index] =
1101 XtVaCreateManagedWidget(namebuf,
1102 toggleWidgetClass,
1103 races_style_form,
1104 XtNradioGroup,
1105 races_style_toggles[index-1],
1106 XtNfromVert,
1107 races_style_toggles[index-per_row],
1108 XtNlabel, maxracename,
1109 NULL);
1110 }
1111
1112 for( j = 1; j < per_row; j++) {
1113 index = i * per_row + j;
1114 if (index >= game.control.num_styles) {
1115 break;
1116 }
1117 fc_snprintf(namebuf, sizeof(namebuf), "racesstyle%d", index);
1118 if (i == 0) {
1119 races_style_toggles[index] =
1120 XtVaCreateManagedWidget(namebuf,
1121 toggleWidgetClass,
1122 races_style_form,
1123 XtNradioGroup,
1124 races_style_toggles[index-1],
1125 XtNfromHoriz,
1126 races_style_toggles[index-1],
1127 XtNlabel, maxracename,
1128 NULL);
1129 } else {
1130 races_style_toggles[index] =
1131 XtVaCreateManagedWidget(namebuf,
1132 toggleWidgetClass,
1133 races_style_form,
1134 XtNradioGroup,
1135 races_style_toggles[index-1],
1136 XtNfromVert,
1137 races_style_toggles[index-per_row],
1138 XtNfromHoriz,
1139 races_style_toggles[index-1],
1140 XtNlabel, maxracename,
1141 NULL);
1142 }
1143 }
1144 }
1145
1146 races_action_form = XtVaCreateManagedWidget("racesactionform",
1147 formWidgetClass,
1148 races_form,
1149 XtNfromVert, races_style_form,
1150 NULL);
1151
1152 races_ok_command =
1153 I_L(XtVaCreateManagedWidget("racesokcommand",
1154 commandWidgetClass,
1155 races_action_form,
1156 NULL));
1157
1158 races_random_command =
1159 I_L(XtVaCreateManagedWidget("racesdisconnectcommand",
1160 commandWidgetClass,
1161 races_action_form,
1162 XtNfromHoriz, races_ok_command,
1163 NULL));
1164
1165 races_quit_command =
1166 I_L(XtVaCreateManagedWidget("racesquitcommand",
1167 commandWidgetClass,
1168 races_action_form,
1169 XtNfromHoriz, races_random_command,
1170 NULL));
1171
1172 XtAddCallback(races_random_command, XtNcallback,
1173 races_random_command_callback, NULL);
1174 XtAddCallback(races_quit_command, XtNcallback,
1175 races_quit_command_callback, NULL);
1176
1177
1178 for (i = 0; i < nation_count(); i++) {
1179 if (races_toggles[i]) {
1180 XtAddCallback(races_toggles[i], XtNcallback,
1181 races_toggles_callback, INT_TO_XTPOINTER(i));
1182 }
1183 }
1184
1185
1186 XtAddCallback(races_ok_command, XtNcallback,
1187 races_ok_command_callback, NULL);
1188
1189
1190 XtSetKeyboardFocus(races_form, races_leader);
1191
1192 XtRealizeWidget(races_dialog_shell);
1193
1194 /* for(i=0; i<game.control.playable_nation_count; i++) {
1195 races_toggles_to_nations[i] = i;
1196 }
1197 */
1198 qsort(races_toggles_to_nations, nat_count,
1199 sizeof(struct nation_type *), races_indirect_compare);
1200
1201 /* Build nation_to_race_toggle */
1202 free(nation_idx_to_race_toggle);
1203 nation_idx_to_race_toggle =
1204 fc_calloc(nation_count(), sizeof(int));
1205 for (i = 0; i < nation_count(); i++) {
1206 nation_idx_to_race_toggle[i] = -1;
1207 }
1208 for (i = 0; i < nation_count(); i++) {
1209 if (races_toggles_to_nations[i]) {
1210 nation_idx_to_race_toggle[nation_index(races_toggles_to_nations[i])] = i;
1211 }
1212 }
1213
1214 for (i = 0; i < nation_count(); i++) {
1215 if (races_toggles[i]) {
1216 XtVaSetValues(races_toggles[i],
1217 XtNlabel,
1218 (XtArgVal)nation_adjective_translation(races_toggles_to_nations[i]),
1219 NULL);
1220 }
1221 }
1222
1223 for (i = 0; i < game.control.num_styles; i++) {
1224 XtVaSetValues(races_style_toggles[i], XtNlabel,
1225 (XtArgVal)city_style_name_translation(city_style_idx[i]), NULL);
1226 }
1227
1228 select_random_race();
1229 }
1230
1231 /****************************************************************
1232 ...
1233 *****************************************************************/
racesdlg_key_ok(Widget w)1234 void racesdlg_key_ok(Widget w)
1235 {
1236 Widget ok = XtNameToWidget(XtParent(XtParent(w)), "*racesokcommand");
1237 if (ok)
1238 x_simulate_button_click(ok);
1239 }
1240
1241 /**************************************************************************
1242 The server has changed the set of selectable nations.
1243 **************************************************************************/
races_update_pickable(bool nationset_change)1244 void races_update_pickable(bool nationset_change)
1245 {
1246 /* FIXME handle this properly */
1247 popdown_races_dialog();
1248 }
1249
1250 /**************************************************************************
1251 ...
1252 **************************************************************************/
races_toggles_set_sensitive(void)1253 void races_toggles_set_sensitive(void)
1254 {
1255 int i;
1256
1257 if (!races_dialog_shell) {
1258 return;
1259 }
1260 for (i = 0; i < nation_count(); i++) {
1261 if (nation_idx_to_race_toggle[i] > -1) {
1262 XtSetSensitive(races_toggles[nation_idx_to_race_toggle[i]], TRUE);
1263 }
1264 }
1265
1266 nations_iterate(nation) {
1267 int selected_nation = -1;
1268 int this_index = nation_index(nation);
1269
1270 if (!is_nation_playable(nation)) {
1271 continue;
1272 }
1273
1274 if (is_nation_pickable(nation) && !nation->player) {
1275 continue;
1276 }
1277
1278 if (races_buttons_get_current() != -1) {
1279 selected_nation =
1280 nation_index(races_toggles_to_nations[races_buttons_get_current()]);
1281 }
1282
1283 log_debug(" [%d]: %d = %s", selected_nation,
1284 nation_number(nation), nation_rule_name(nation));
1285
1286 if (this_index == selected_nation) {
1287 XawToggleUnsetCurrent(races_toggles[0]);
1288 XtSetSensitive(races_toggles[nation_idx_to_race_toggle[this_index]], FALSE);
1289 select_random_race();
1290 } else {
1291 XtSetSensitive(races_toggles[nation_idx_to_race_toggle[this_index]], FALSE);
1292 }
1293 } nations_iterate_end;
1294 }
1295
1296 /* We store this value locally in case it changes globally. */
1297 static int local_nation_count;
1298
1299 /**************************************************************************
1300 ...
1301 **************************************************************************/
races_toggles_callback(Widget w,XtPointer client_data,XtPointer call_data)1302 void races_toggles_callback(Widget w, XtPointer client_data,
1303 XtPointer call_data)
1304 {
1305 int index = XTPOINTER_TO_INT(client_data);
1306 struct nation_type *race = races_toggles_to_nations[index];
1307 int j;
1308 Widget entry;
1309
1310 if(races_leader_pick_popupmenu)
1311 XtDestroyWidget(races_leader_pick_popupmenu);
1312
1313 races_leader_pick_popupmenu =
1314 XtVaCreatePopupShell("menu",
1315 simpleMenuWidgetClass,
1316 races_leader_pick_menubutton,
1317 NULL);
1318
1319 local_nation_count = nation_count();
1320
1321 j = 0;
1322 nation_leader_list_iterate(nation_leaders(race), pleader) {
1323 entry =
1324 XtVaCreateManagedWidget(nation_leader_name(pleader),
1325 smeBSBObjectClass,
1326 races_leader_pick_popupmenu,
1327 NULL);
1328 XtAddCallback(entry, XtNcallback, races_leader_pick_callback,
1329 INT_TO_XTPOINTER(local_nation_count * j
1330 + nation_index(race)));
1331 j++;
1332 } nation_leader_list_iterate_end;
1333
1334 races_leader_set_values(race, fc_rand(j));
1335
1336 x_simulate_button_click
1337 (
1338 races_style_toggles[city_style_ridx[style_number(style_of_nation(race))]]
1339 );
1340 }
1341
1342 /**************************************************************************
1343 ...
1344 **************************************************************************/
races_leader_pick_callback(Widget w,XtPointer client_data,XtPointer call_data)1345 void races_leader_pick_callback(Widget w, XtPointer client_data,
1346 XtPointer call_data)
1347 {
1348 int lead = XTPOINTER_TO_INT(client_data) / local_nation_count;
1349 int race = XTPOINTER_TO_INT(client_data) - (local_nation_count * lead);
1350
1351 races_leader_set_values(nation_by_number(race), lead);
1352 }
1353
1354 /**************************************************************************
1355 ...
1356 **************************************************************************/
races_leader_set_values(struct nation_type * race,int lead)1357 void races_leader_set_values(struct nation_type *race, int lead)
1358 {
1359 const struct nation_leader *pleader =
1360 nation_leader_list_get(nation_leaders(race), lead);
1361
1362 XtVaSetValues(races_leader, XtNstring, nation_leader_name(pleader), NULL);
1363 XawTextSetInsertionPoint(races_leader,
1364 strlen(nation_leader_name(pleader)));
1365
1366 races_sex_buttons_set_current(!nation_leader_is_male(pleader));
1367 }
1368
1369 /**************************************************************************
1370 ...
1371 **************************************************************************/
races_buttons_get_current(void)1372 int races_buttons_get_current(void)
1373 {
1374 int i;
1375 XtPointer dp, yadp;
1376
1377 if (nation_count() == 1) {
1378 return 0;
1379 }
1380
1381 if(!(dp=XawToggleGetCurrent(races_toggles[0])))
1382 return -1;
1383
1384 for(i = 0; i < nation_count(); i++) {
1385 if (races_toggles[i]) {
1386 XtVaGetValues(races_toggles[i], XtNradioData, &yadp, NULL);
1387 if(dp==yadp)
1388 return i;
1389 }
1390 }
1391
1392 return -1;
1393 }
1394
1395 /**************************************************************************
1396 ...
1397 **************************************************************************/
races_sex_buttons_get_current(void)1398 int races_sex_buttons_get_current(void)
1399 {
1400 int i;
1401 XtPointer dp, yadp;
1402
1403 if(!(dp=XawToggleGetCurrent(races_sex_toggles[0])))
1404 return -1;
1405
1406 for(i=0; i<2; i++) {
1407 XtVaGetValues(races_sex_toggles[i], XtNradioData, &yadp, NULL);
1408 if(dp==yadp)
1409 return i;
1410 }
1411
1412 return -1;
1413 }
1414
1415 /**************************************************************************
1416 ...
1417 **************************************************************************/
races_style_buttons_get_current(void)1418 int races_style_buttons_get_current(void)
1419 {
1420 int i;
1421 XtPointer dp, yadp;
1422
1423 if (game.control.num_styles == 1) {
1424 return 0;
1425 }
1426
1427 if(!(dp=XawToggleGetCurrent(races_style_toggles[0])))
1428 return -1;
1429
1430 for (i = 0; i < game.control.num_styles; i++) {
1431 XtVaGetValues(races_style_toggles[i], XtNradioData, &yadp, NULL);
1432 if (dp == yadp) {
1433 return i;
1434 }
1435 }
1436
1437 return -1;
1438 }
1439
1440 /**************************************************************************
1441 ...
1442 **************************************************************************/
races_sex_buttons_set_current(int i)1443 void races_sex_buttons_set_current(int i)
1444 {
1445 XtPointer dp;
1446
1447 XtVaGetValues(races_sex_toggles[i], XtNradioData, &dp, NULL);
1448
1449 XawToggleSetCurrent(races_sex_toggles[0], dp);
1450 }
1451
1452 /**************************************************************************
1453 ...
1454 **************************************************************************/
races_indirect_compare(const void * first,const void * second)1455 int races_indirect_compare(const void *first, const void *second)
1456 {
1457 const char *first_string;
1458 const char *second_string;
1459
1460 struct nation_type *first_nation = *(struct nation_type **)first;
1461 struct nation_type *second_nation = *(struct nation_type **)second;
1462
1463 first_string = nation_adjective_translation(first_nation);
1464 second_string = nation_adjective_translation(second_nation);
1465
1466 return fc_strcasecmp(first_string, second_string);
1467 }
1468
1469 /**************************************************************************
1470 ...
1471 **************************************************************************/
races_ok_command_callback(Widget w,XtPointer client_data,XtPointer call_data)1472 void races_ok_command_callback(Widget w, XtPointer client_data,
1473 XtPointer call_data)
1474 {
1475 int selected_index, selected_sex, selected_style;
1476 XtPointer dp;
1477
1478 if((selected_index=races_buttons_get_current())==-1) {
1479 output_window_append(ftc_client, _("You must select a nation."));
1480 return;
1481 }
1482
1483 if((selected_sex=races_sex_buttons_get_current())==-1) {
1484 output_window_append(ftc_client, _("You must select your sex."));
1485 return;
1486 }
1487
1488 if ((selected_style = races_style_buttons_get_current()) == -1) {
1489 output_window_append(ftc_client, _("You must select your style."));
1490 return;
1491 }
1492
1493 XtVaGetValues(races_leader, XtNstring, &dp, NULL);
1494
1495 /* perform a minimum of sanity test on the name */
1496 if (strlen(dp) == 0) {
1497 output_window_append(ftc_client, _("You must type a legal name."));
1498 return;
1499 }
1500
1501 dsend_packet_nation_select_req(&client.conn,
1502 player_number(races_player),
1503 nation_index(races_toggles_to_nations[selected_index]),
1504 selected_sex ? FALSE : TRUE,
1505 dp,
1506 city_style_idx[selected_style]);
1507 popdown_races_dialog();
1508 }
1509
1510 /**************************************************************************
1511 ...
1512 **************************************************************************/
races_random_command_callback(Widget w,XtPointer client_data,XtPointer call_data)1513 void races_random_command_callback(Widget w, XtPointer client_data,
1514 XtPointer call_data)
1515 {
1516 popdown_races_dialog();
1517 /* disconnect_from_server();*/
1518 }
1519
1520 /**************************************************************************
1521 ...
1522 **************************************************************************/
races_quit_command_callback(Widget w,XtPointer client_data,XtPointer call_data)1523 void races_quit_command_callback(Widget w, XtPointer client_data,
1524 XtPointer call_data)
1525 {
1526 client_exit();
1527 }
1528
1529 /**************************************************************************
1530 Frees a bitmap associated with a Widget when it is destroyed
1531 **************************************************************************/
free_bitmap_destroy_callback(Widget w,XtPointer client_data,XtPointer call_data)1532 void free_bitmap_destroy_callback(Widget w, XtPointer client_data,
1533 XtPointer call_data)
1534 {
1535 Pixmap pm;
1536
1537 XtVaGetValues(w,XtNbitmap,&pm,NULL);
1538 if(pm) XFreePixmap(XtDisplay(w),pm);
1539 }
1540
1541 /**************************************************************************
1542 Destroys its widget. Usefull for a popdown callback on pop-ups that
1543 won't get resused.
1544 **************************************************************************/
destroy_me_callback(Widget w,XtPointer client_data,XtPointer call_data)1545 void destroy_me_callback(Widget w, XtPointer client_data,
1546 XtPointer call_data)
1547 {
1548 XtDestroyWidget(w);
1549 }
1550
1551 /**************************************************************************
1552 Adjust tax rates from main window
1553 **************************************************************************/
taxrates_callback(Widget w,XtPointer client_data,XtPointer call_data)1554 void taxrates_callback(Widget w, XtPointer client_data, XtPointer call_data)
1555 {
1556 common_taxrates_callback((size_t) client_data);
1557 }
1558
1559 /**************************************************************************
1560 Ruleset (modpack) has suggested loading certain tileset. Confirm from
1561 user and load.
1562 **************************************************************************/
popup_tileset_suggestion_dialog(void)1563 void popup_tileset_suggestion_dialog(void)
1564 {
1565 }
1566
1567 /****************************************************************
1568 Ruleset (modpack) has suggested loading certain soundset. Confirm from
1569 user and load.
1570 *****************************************************************/
popup_soundset_suggestion_dialog(void)1571 void popup_soundset_suggestion_dialog(void)
1572 {
1573 }
1574
1575 /****************************************************************
1576 Ruleset (modpack) has suggested loading certain musicset. Confirm from
1577 user and load.
1578 *****************************************************************/
popup_musicset_suggestion_dialog(void)1579 void popup_musicset_suggestion_dialog(void)
1580 {
1581 }
1582
1583 /**************************************************************************
1584 Tileset (modpack) has suggested loading certain theme. Confirm from
1585 user and load.
1586 **************************************************************************/
popup_theme_suggestion_dialog(const char * theme_name)1587 bool popup_theme_suggestion_dialog(const char *theme_name)
1588 {
1589 /* Don't load */
1590 return FALSE;
1591 }
1592
1593 /**********************************************************************
1594 This function is called when the client disconnects or the game is
1595 over. It should close all dialog windows for that game.
1596 ***********************************************************************/
popdown_all_game_dialogs(void)1597 void popdown_all_game_dialogs(void)
1598 {
1599 city_report_dialog_popdown();
1600 meswin_dialog_popdown();
1601 science_report_dialog_popdown();
1602 economy_report_dialog_popdown();
1603 units_report_dialog_popdown();
1604 popdown_players_dialog();
1605 popdown_notify_dialog();
1606 }
1607
1608 /****************************************************************
1609 Player has gained a new tech.
1610 *****************************************************************/
show_tech_gained_dialog(Tech_type_id tech)1611 void show_tech_gained_dialog(Tech_type_id tech)
1612 {
1613 /* PORTME */
1614 }
1615
1616 /****************************************************************
1617 Show tileset error dialog.
1618 *****************************************************************/
show_tileset_error(const char * msg)1619 void show_tileset_error(const char *msg)
1620 {
1621 /* PORTME */
1622 }
1623
1624 /****************************************************************
1625 Give a warning when user is about to edit scenario with manually
1626 set properties.
1627 *****************************************************************/
handmade_scenario_warning(void)1628 bool handmade_scenario_warning(void)
1629 {
1630 /* Just tell the client common code to handle this. */
1631 return FALSE;
1632 }
1633
1634 /****************************************************************
1635 Unit wants to get into some transport on given tile.
1636 *****************************************************************/
request_transport(struct unit * pcargo,struct tile * ptile)1637 bool request_transport(struct unit *pcargo, struct tile *ptile)
1638 {
1639 return FALSE; /* Unit was not handled here. */
1640 }
1641
1642 /***************************************************************************
1643 Popup detailed information about battle or save information for
1644 some kind of statistics
1645 ***************************************************************************/
popup_combat_info(int attacker_unit_id,int defender_unit_id,int attacker_hp,int defender_hp,bool make_winner_veteran)1646 void popup_combat_info(int attacker_unit_id, int defender_unit_id,
1647 int attacker_hp, int defender_hp,
1648 bool make_winner_veteran)
1649 {
1650 }
1651