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