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 <stdio.h>
19 #include <stdlib.h>
20
21 #include <X11/Intrinsic.h>
22 #include <X11/StringDefs.h>
23 #include <X11/Xaw/Form.h>
24 #include <X11/Xaw/Label.h>
25 #include <X11/Xaw/Command.h>
26 #include <X11/Xaw/SimpleMenu.h>
27 #include <X11/Xaw/List.h>
28
29 /* utility */
30 #include "fcintl.h"
31 #include "log.h"
32 #include "shared.h"
33 #include "support.h"
34
35 /* common */
36 #include "government.h"
37 #include "packets.h"
38 #include "player.h"
39 #include "research.h"
40
41 /* client */
42 #include "client_main.h"
43
44 /* gui-xaw */
45 #include "gui_main.h"
46 #include "gui_stuff.h"
47 #include "mapview.h"
48 #include "optiondlg.h"
49
50 #include "inteldlg.h"
51
52 /******************************************************************/
53 struct intel_dialog {
54 struct player *pplayer;
55
56 Widget intel_dialog_shell;
57 Widget intel_form;
58 Widget intel_label;
59 Widget intel_close_command;
60 Widget intel_diplo_command;
61 bool intel_dialog_shell_is_raised;
62
63 Widget intel_diplo_dialog_shell;
64 Widget intel_diplo_form;
65 Widget intel_diplo_label;
66 Widget intel_diplo_list;
67 Widget intel_diplo_close_command;
68 bool intel_diplo_dialog_shell_is_raised;
69 };
70
71 #define SPECLIST_TAG dialog
72 #define SPECLIST_TYPE struct intel_dialog
73 #include "speclist.h"
74
75 #define dialog_list_iterate(dialoglist, pdialog) \
76 TYPED_LIST_ITERATE(struct intel_dialog, dialoglist, pdialog)
77 #define dialog_list_iterate_end LIST_ITERATE_END
78
79 static struct dialog_list *dialog_list = NULL;
80 static bool dialog_list_has_been_initialised = FALSE;
81
82 /******************************************************************/
83
84 struct intel_dialog *get_intel_dialog(struct player *pplayer);
85 void popdown_intel_dialog(struct intel_dialog *pdialog);
86 void create_intel_dialog(struct intel_dialog *pdialog, bool raise);
87
88 void intel_close_callback(Widget w, XtPointer client_data,
89 XtPointer call_data);
90 void intel_diplo_callback(Widget w, XtPointer client_data,
91 XtPointer call_data);
92
93 void popup_intel_diplo_dialog(struct player *pplayer, bool raise);
94 void popdown_intel_diplo_dialog(struct intel_dialog *pdialog);
95 void create_intel_diplo_dialog(struct intel_dialog *pdialog, bool raise);
96 void update_intel_diplo_dialog(struct intel_dialog *pdialog);
97 void intel_diplo_close_callback(Widget w, XtPointer client_data,
98 XtPointer call_data);
99
100 /****************************************************************
101 Get an intelligence dialog for the given player.
102 *****************************************************************/
get_intel_dialog(struct player * pplayer)103 struct intel_dialog *get_intel_dialog(struct player *pplayer)
104 {
105 if (!dialog_list_has_been_initialised) {
106 dialog_list = dialog_list_new();
107 dialog_list_has_been_initialised = TRUE;
108 }
109
110 dialog_list_iterate(dialog_list, pdialog) {
111 if (pdialog->pplayer == pplayer) {
112 return pdialog;
113 }
114 } dialog_list_iterate_end;
115
116 return NULL;
117 }
118
119 /****************************************************************
120 Popup an intelligence dialog for the given player.
121 *****************************************************************/
popup_intel_dialog(struct player * pplayer)122 void popup_intel_dialog(struct player *pplayer)
123 {
124 struct intel_dialog *pdialog;
125 bool raise = FALSE; /* Drop when we'll have raise-parametered popup */
126
127 if (!(pdialog = get_intel_dialog(pplayer))) {
128 pdialog = fc_malloc(sizeof(struct intel_dialog));
129 pdialog->pplayer = pplayer;
130 pdialog->intel_dialog_shell = 0;
131 pdialog->intel_diplo_dialog_shell = 0;
132 dialog_list_prepend(dialog_list, pdialog);
133 }
134
135 if (!(pdialog->intel_dialog_shell)) {
136 create_intel_dialog(pdialog, raise);
137 }
138
139 xaw_set_relative_position(toplevel, pdialog->intel_dialog_shell, 25, 25);
140 XtPopup(pdialog->intel_dialog_shell, XtGrabNone);
141 if (pdialog->intel_dialog_shell_is_raised) {
142 XtSetSensitive(main_form, FALSE);
143 }
144 }
145
146 /****************************************************************
147 Close an intelligence dialog.
148 *****************************************************************/
popdown_intel_dialog(struct intel_dialog * pdialog)149 void popdown_intel_dialog(struct intel_dialog *pdialog)
150 {
151 if (pdialog->intel_dialog_shell_is_raised) {
152 XtSetSensitive(main_form, TRUE);
153 }
154 XtDestroyWidget(pdialog->intel_dialog_shell);
155 pdialog->intel_dialog_shell = 0;
156
157 if (!(pdialog->intel_diplo_dialog_shell)) {
158 dialog_list_remove(dialog_list, pdialog);
159 free(pdialog);
160 }
161 }
162
163 /**************************************************************************
164 Close an intelligence dialog for the given player.
165 **************************************************************************/
close_intel_dialog(struct player * p)166 void close_intel_dialog(struct player *p)
167 {
168 struct intel_dialog *pdialog = get_intel_dialog(p);
169 popdown_intel_dialog(pdialog);
170 }
171
172 /****************************************************************
173 ...
174 *****************************************************************/
create_intel_dialog(struct intel_dialog * pdialog,bool raise)175 void create_intel_dialog(struct intel_dialog *pdialog, bool raise)
176 {
177 char buf[4 * MAX_LEN_NAME], plr_buf[4 * MAX_LEN_NAME];
178 struct city *pcity;
179 const struct research *presearch = research_get(pdialog->pplayer);
180
181 static char *tech_list_names_ptrs[A_LAST+1];
182 static char tech_list_names[A_LAST+1][200];
183 int j = 0;
184
185 pdialog->intel_dialog_shell_is_raised = raise;
186
187 I_T(pdialog->intel_dialog_shell =
188 XtCreatePopupShell("intelpopup",
189 raise ? transientShellWidgetClass
190 : topLevelShellWidgetClass,
191 toplevel, NULL, 0));
192
193 pdialog->intel_form = XtVaCreateManagedWidget("intelform",
194 formWidgetClass,
195 pdialog->intel_dialog_shell,
196 NULL);
197
198 fc_snprintf(buf, sizeof(buf),
199 _("Intelligence Information for the %s Empire"),
200 nation_adjective_for_player(pdialog->pplayer));
201
202 pdialog->intel_label = I_L(XtVaCreateManagedWidget("inteltitlelabel",
203 labelWidgetClass,
204 pdialog->intel_form,
205 XtNlabel, buf,
206 NULL));
207
208 fc_snprintf(buf, sizeof(buf), _("Ruler: %s"),
209 ruler_title_for_player(pdialog->pplayer,
210 plr_buf, sizeof(plr_buf)));
211 XtVaCreateManagedWidget("intelnamelabel",
212 labelWidgetClass,
213 pdialog->intel_form,
214 XtNlabel, buf,
215 NULL);
216
217 fc_snprintf(buf, sizeof(buf), _("Government: %s"),
218 government_name_for_player(pdialog->pplayer));
219 XtVaCreateManagedWidget("intelgovlabel",
220 labelWidgetClass,
221 pdialog->intel_form,
222 XtNlabel, buf,
223 NULL);
224
225 fc_snprintf(buf, sizeof(buf), _("Gold: %d"),
226 pdialog->pplayer->economic.gold);
227 XtVaCreateManagedWidget("intelgoldlabel",
228 labelWidgetClass,
229 pdialog->intel_form,
230 XtNlabel, buf,
231 NULL);
232
233 fc_snprintf(buf, sizeof(buf), _("Tax: %d%%"),
234 pdialog->pplayer->economic.tax);
235 XtVaCreateManagedWidget("inteltaxlabel",
236 labelWidgetClass,
237 pdialog->intel_form,
238 XtNlabel, buf,
239 NULL);
240
241 fc_snprintf(buf, sizeof(buf), _("Science: %d%%"),
242 pdialog->pplayer->economic.science);
243 XtVaCreateManagedWidget("intelscilabel",
244 labelWidgetClass,
245 pdialog->intel_form,
246 XtNlabel, buf,
247 NULL);
248
249 fc_snprintf(buf, sizeof(buf), _("Luxury: %d%%"),
250 pdialog->pplayer->economic.luxury);
251 XtVaCreateManagedWidget("intelluxlabel",
252 labelWidgetClass,
253 pdialog->intel_form,
254 XtNlabel, buf,
255 NULL);
256
257 switch (presearch->researching) {
258 case A_UNKNOWN:
259 fc_snprintf(buf, sizeof(buf), _("Researching: (Unknown)"));
260 break;
261 case A_UNSET:
262 fc_snprintf(buf, sizeof(buf), _("Researching: Unknown(%d/-)"),
263 presearch->bulbs_researched);
264 break;
265 default:
266 fc_snprintf(buf, sizeof(buf), _("Researching: %s(%d/%d)"),
267 research_advance_name_translation(presearch,
268 presearch->researching),
269 presearch->bulbs_researched,
270 presearch->client.researching_cost);
271 break;
272 };
273
274 XtVaCreateManagedWidget("intelreslabel",
275 labelWidgetClass,
276 pdialog->intel_form,
277 XtNlabel, buf,
278 NULL);
279
280 pcity = player_capital(pdialog->pplayer);
281 fc_snprintf(buf, sizeof(buf), _("Capital: %s"),
282 /* TRANS: "unknown" location */
283 (!pcity) ? _("(unknown)") : city_name_get(pcity));
284 XtVaCreateManagedWidget("intelcapitallabel",
285 labelWidgetClass,
286 pdialog->intel_form,
287 XtNlabel, buf,
288 NULL);
289
290 advance_index_iterate(A_FIRST, i) {
291 if (research_invention_state(presearch, i)
292 == TECH_KNOWN) {
293 if (research_invention_state(research_get(client_player()), i)
294 == TECH_KNOWN) {
295 sz_strlcpy(tech_list_names[j], advance_name_translation(advance_by_number(i)));
296 } else {
297 fc_snprintf(tech_list_names[j], sizeof(tech_list_names[j]),
298 "%s*", advance_name_translation(advance_by_number(i)));
299 }
300 tech_list_names_ptrs[j]=tech_list_names[j];
301 j++;
302 }
303 } advance_index_iterate_end;
304 tech_list_names_ptrs[j]=0;
305
306 XtVaCreateManagedWidget("inteltechlist",
307 listWidgetClass,
308 pdialog->intel_form,
309 XtNlist, tech_list_names_ptrs,
310 NULL);
311
312 pdialog->intel_close_command =
313 I_L(XtVaCreateManagedWidget("intelclosecommand",
314 commandWidgetClass,
315 pdialog->intel_form, NULL));
316
317 pdialog->intel_diplo_command =
318 I_L(XtVaCreateManagedWidget("inteldiplocommand",
319 commandWidgetClass,
320 pdialog->intel_form, NULL));
321
322 XtAddCallback(pdialog->intel_close_command, XtNcallback,
323 intel_close_callback, (XtPointer)pdialog);
324 XtAddCallback(pdialog->intel_diplo_command, XtNcallback,
325 intel_diplo_callback,
326 INT_TO_XTPOINTER(player_number(pdialog->pplayer)));
327 XtRealizeWidget(pdialog->intel_dialog_shell);
328
329 xaw_horiz_center(pdialog->intel_label);
330
331 XSetWMProtocols(display, XtWindow(pdialog->intel_dialog_shell),
332 &wm_delete_window, 1);
333 XtOverrideTranslations(pdialog->intel_dialog_shell,
334 XtParseTranslationTable("<Message>WM_PROTOCOLS: msg-close-intel()"));
335 }
336
337 /****************************************************************************
338 Update the intelligence dialog for the given player. This is called by
339 the core client code when that player's information changes.
340 ****************************************************************************/
update_intel_dialog(struct player * p)341 void update_intel_dialog(struct player *p)
342 {
343 /* PORTME */
344 }
345
346 /**************************************************************************
347 ...
348 **************************************************************************/
intel_close_callback(Widget w,XtPointer client_data,XtPointer call_data)349 void intel_close_callback(Widget w, XtPointer client_data,
350 XtPointer call_data)
351 {
352 popdown_intel_dialog((struct intel_dialog *)client_data);
353 }
354
355 /**************************************************************************
356 ...
357 **************************************************************************/
intel_diplo_callback(Widget w,XtPointer client_data,XtPointer call_data)358 void intel_diplo_callback(Widget w, XtPointer client_data,
359 XtPointer call_data)
360 {
361 popup_intel_diplo_dialog(player_by_number(XTPOINTER_TO_INT(client_data)),
362 FALSE);
363 }
364
365 /**************************************************************************
366 ...
367 **************************************************************************/
intel_dialog_msg_close(Widget w)368 void intel_dialog_msg_close(Widget w)
369 {
370 dialog_list_iterate(dialog_list, pdialog) {
371 if (pdialog->intel_dialog_shell == w) {
372 popdown_intel_dialog(pdialog);
373 return;
374 }
375 } dialog_list_iterate_end;
376 }
377
378 /****************************************************************
379 Popup a player's relations dialog for the given player.
380 *****************************************************************/
popup_intel_diplo_dialog(struct player * pplayer,bool raise)381 void popup_intel_diplo_dialog(struct player *pplayer, bool raise)
382 {
383 struct intel_dialog *pdialog;
384
385 if (!(pdialog = get_intel_dialog(pplayer))) {
386 pdialog = fc_malloc(sizeof(struct intel_dialog));
387 pdialog->pplayer = pplayer;
388 pdialog->intel_dialog_shell = 0;
389 pdialog->intel_diplo_dialog_shell = 0;
390 dialog_list_prepend(dialog_list, pdialog);
391 }
392
393 if (!(pdialog->intel_diplo_dialog_shell)) {
394 create_intel_diplo_dialog(pdialog, raise);
395 }
396
397 xaw_set_relative_position(toplevel,
398 pdialog->intel_diplo_dialog_shell, 25, 25);
399 XtPopup(pdialog->intel_diplo_dialog_shell, XtGrabNone);
400 if (pdialog->intel_diplo_dialog_shell_is_raised) {
401 XtSetSensitive(main_form, FALSE);
402 }
403 }
404
405 /****************************************************************
406 Close a player's relations dialog.
407 *****************************************************************/
popdown_intel_diplo_dialog(struct intel_dialog * pdialog)408 void popdown_intel_diplo_dialog(struct intel_dialog *pdialog)
409 {
410 if (pdialog->intel_diplo_dialog_shell_is_raised) {
411 XtSetSensitive(main_form, TRUE);
412 }
413 XtDestroyWidget(pdialog->intel_diplo_dialog_shell);
414 pdialog->intel_diplo_dialog_shell = 0;
415
416 if (!(pdialog->intel_dialog_shell)) {
417 dialog_list_remove(dialog_list, pdialog);
418 free(pdialog);
419 }
420 }
421
422 /****************************************************************
423 Create a player's relations dialog for the given player.
424 *****************************************************************/
create_intel_diplo_dialog(struct intel_dialog * pdialog,bool raise)425 void create_intel_diplo_dialog(struct intel_dialog *pdialog, bool raise)
426 {
427 char buf[4 * MAX_LEN_NAME], plr_buf[4 * MAX_LEN_NAME];
428
429 pdialog->intel_diplo_dialog_shell_is_raised = raise;
430
431 pdialog->intel_diplo_dialog_shell =
432 I_IN(I_T(XtCreatePopupShell("inteldiplopopup",
433 raise ? transientShellWidgetClass
434 : topLevelShellWidgetClass,
435 toplevel, NULL, 0)));
436
437 pdialog->intel_diplo_form =
438 XtVaCreateManagedWidget("inteldiploform",
439 formWidgetClass,
440 pdialog->intel_diplo_dialog_shell,
441 NULL);
442
443 fc_snprintf(buf, sizeof(buf),
444 _("Intelligence Diplomacy Information for the %s Empire"),
445 nation_adjective_for_player(pdialog->pplayer));
446
447 pdialog->intel_diplo_label =
448 I_L(XtVaCreateManagedWidget("inteldiplolabel",
449 labelWidgetClass,
450 pdialog->intel_diplo_form,
451 XtNlabel, buf,
452 NULL));
453
454 fc_snprintf(buf, sizeof(buf), _("Ruler: %s"),
455 ruler_title_for_player(pdialog->pplayer,
456 plr_buf, sizeof(plr_buf)));
457 XtVaCreateManagedWidget("inteldiplonamelabel",
458 labelWidgetClass,
459 pdialog->intel_diplo_form,
460 XtNlabel, buf,
461 NULL);
462
463 pdialog->intel_diplo_list =
464 XtVaCreateManagedWidget("inteldiplolist",
465 listWidgetClass,
466 pdialog->intel_diplo_form,
467 NULL);
468
469 pdialog->intel_diplo_close_command =
470 I_L(XtVaCreateManagedWidget("inteldiploclosecommand",
471 commandWidgetClass,
472 pdialog->intel_diplo_form,
473 NULL));
474
475 XtAddCallback(pdialog->intel_diplo_close_command, XtNcallback,
476 intel_diplo_close_callback, (XtPointer)pdialog);
477
478 update_intel_diplo_dialog(pdialog);
479
480 XtRealizeWidget(pdialog->intel_diplo_dialog_shell);
481
482 XSetWMProtocols(display, XtWindow(pdialog->intel_diplo_dialog_shell),
483 &wm_delete_window, 1);
484 XtOverrideTranslations(pdialog->intel_diplo_dialog_shell,
485 XtParseTranslationTable("<Message>WM_PROTOCOLS: msg-close-intel-diplo()"));
486 }
487
488 /****************************************************************
489 Update a player's relations dialog for the given player.
490 *****************************************************************/
update_intel_diplo_dialog(struct intel_dialog * pdialog)491 void update_intel_diplo_dialog(struct intel_dialog *pdialog)
492 {
493 int i;
494 Dimension width;
495 static CONST_FOR_XAW_LIST_CHANGE char *namelist_ptrs[MAX_NUM_PLAYERS];
496 static char namelist_text[MAX_NUM_PLAYERS][72];
497 const struct player_diplstate *state;
498
499 if (pdialog->intel_diplo_dialog_shell) {
500 i = 0;
501 players_iterate(other) {
502 if (other == pdialog->pplayer) {
503 continue;
504 }
505 state = player_diplstate_get(pdialog->pplayer, other);
506 fc_snprintf(namelist_text[i], sizeof(namelist_text[i]),
507 "%-32s %-16s %-16s",
508 player_name(other),
509 nation_adjective_for_player(other),
510 diplstate_type_translated_name(state->type));
511 namelist_ptrs[i] = namelist_text[i];
512 i++;
513 } players_iterate_end;
514
515 XawListChange(pdialog->intel_diplo_list, namelist_ptrs, i, 0, True);
516
517 XtVaGetValues(pdialog->intel_diplo_list, XtNwidth, &width, NULL);
518 XtVaSetValues(pdialog->intel_diplo_label, XtNwidth, width, NULL);
519 }
520 }
521
522 /**************************************************************************
523 ...
524 **************************************************************************/
intel_diplo_close_callback(Widget w,XtPointer client_data,XtPointer call_data)525 void intel_diplo_close_callback(Widget w, XtPointer client_data,
526 XtPointer call_data)
527 {
528 popdown_intel_diplo_dialog((struct intel_dialog *)client_data);
529 }
530
531 /**************************************************************************
532 ...
533 **************************************************************************/
intel_diplo_dialog_msg_close(Widget w)534 void intel_diplo_dialog_msg_close(Widget w)
535 {
536 dialog_list_iterate(dialog_list, pdialog) {
537 if (pdialog->intel_diplo_dialog_shell == w) {
538 popdown_intel_diplo_dialog(pdialog);
539 return;
540 }
541 } dialog_list_iterate_end;
542 }
543