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/List.h>
27 #include <X11/Xaw/SimpleMenu.h>
28 #include <X11/Xaw/MenuButton.h>
29 #include <X11/Xaw/SmeBSB.h>
30 #include <X11/Xaw/SmeLine.h>
31 #include <X11/Xaw/AsciiText.h>
32 #include <X11/Xaw/Viewport.h>
33
34 /* utility */
35 #include "fcintl.h"
36 #include "log.h"
37 #include "mem.h"
38 #include "shared.h"
39 #include "support.h"
40
41 /* common */
42 #include "diptreaty.h"
43 #include "game.h"
44 #include "government.h"
45 #include "map.h"
46 #include "packets.h"
47 #include "player.h"
48 #include "research.h"
49
50 /* client */
51 #include "client_main.h"
52 #include "climisc.h"
53
54 /* gui-xaw */
55 #include "chatline.h"
56 #include "gui_main.h"
57 #include "gui_stuff.h"
58 #include "mapview.h"
59
60 #include "diplodlg.h"
61
62 #define MAX_NUM_CLAUSES 64
63
64 struct Diplomacy_dialog {
65 struct Treaty treaty;
66
67 Widget dip_dialog_shell;
68 Widget dip_form, dip_main_form, dip_form0, dip_formm, dip_form1;
69 Widget dip_view;
70
71 Widget dip_headline0;
72 Widget dip_headlinem;
73 Widget dip_headline1;
74
75 Widget dip_map_menubutton0;
76 Widget dip_map_menubutton1;
77 Widget dip_tech_menubutton0;
78 Widget dip_tech_menubutton1;
79 Widget dip_city_menubutton0;
80 Widget dip_city_menubutton1;
81 Widget dip_gold_label0;
82 Widget dip_gold_label1;
83 Widget dip_gold_input0;
84 Widget dip_gold_input1;
85 Widget dip_vision_button0;
86 Widget dip_vision_button1;
87 Widget dip_pact_menubutton;
88
89 Widget dip_label;
90 Widget dip_clauselabel;
91 Widget dip_clauselist;
92 Widget dip_acceptlabel0;
93 Widget dip_acceptthumb0;
94 Widget dip_acceptlabel1;
95 Widget dip_acceptthumb1;
96
97 Widget dip_accept_command;
98 Widget dip_close_command;
99
100 Widget dip_erase_clause_command;
101
102 char clauselist_strings[MAX_NUM_CLAUSES+1][128];
103 CONST_FOR_XAW_LIST_CHANGE char *clauselist_strings_ptrs[MAX_NUM_CLAUSES + 1];
104 };
105
106 static char *dummy_clause_list_strings[]
107 = { "\n", "\n", "\n", "\n", "\n", "\n", 0 };
108
109 #define SPECLIST_TAG dialog
110 #define SPECLIST_TYPE struct Diplomacy_dialog
111 #include "speclist.h"
112
113 #define dialog_list_iterate(dialoglist, pdialog) \
114 TYPED_LIST_ITERATE(struct Diplomacy_dialog, dialoglist, pdialog)
115 #define dialog_list_iterate_end LIST_ITERATE_END
116
117 static struct dialog_list *dialog_list = NULL;
118 static bool dialog_list_list_has_been_initialised = FALSE;
119
120 struct Diplomacy_dialog *create_diplomacy_dialog(struct player *plr0,
121 struct player *plr1);
122
123 static struct Diplomacy_dialog *find_diplomacy_dialog(int other_player_id);
124 static void popup_diplomacy_dialog(int other_player_id);
125 void diplomacy_dialog_close_callback(Widget w, XtPointer client_data,
126 XtPointer call_data);
127 void diplomacy_dialog_map_callback(Widget w, XtPointer client_data,
128 XtPointer call_data);
129 void diplomacy_dialog_seamap_callback(Widget w, XtPointer client_data,
130 XtPointer call_data);
131 void diplomacy_dialog_erase_clause_callback(Widget w, XtPointer client_data,
132 XtPointer call_data);
133 void diplomacy_dialog_accept_callback(Widget w, XtPointer client_data,
134 XtPointer call_data);
135 void diplomacy_dialog_tech_callback(Widget w, XtPointer client_data,
136 XtPointer call_data);
137 void diplomacy_dialog_city_callback(Widget w, XtPointer client_data,
138 XtPointer call_data);
139 void diplomacy_dialog_ceasefire_callback(Widget w, XtPointer client_data,
140 XtPointer call_data);
141 void diplomacy_dialog_peace_callback(Widget w, XtPointer client_data,
142 XtPointer call_data);
143 void diplomacy_dialog_alliance_callback(Widget w, XtPointer client_data,
144 XtPointer call_data);
145 void diplomacy_dialog_vision_callback(Widget w, XtPointer client_data,
146 XtPointer call_data);
147 void close_diplomacy_dialog(struct Diplomacy_dialog *pdialog);
148 void update_diplomacy_dialog(struct Diplomacy_dialog *pdialog);
149
150
151 /****************************************************************
152 ...
153 *****************************************************************/
handle_diplomacy_accept_treaty(int counterpart,bool I_accepted,bool other_accepted)154 void handle_diplomacy_accept_treaty(int counterpart, bool I_accepted,
155 bool other_accepted)
156 {
157 struct Diplomacy_dialog *pdialog = find_diplomacy_dialog(counterpart);
158
159 if (!pdialog) {
160 return;
161 }
162
163 pdialog->treaty.accept0 = I_accepted;
164 pdialog->treaty.accept1 = other_accepted;
165
166 update_diplomacy_dialog(pdialog);
167 }
168
169 /****************************************************************
170 ...
171 *****************************************************************/
handle_diplomacy_init_meeting(int counterpart,int initiated_from)172 void handle_diplomacy_init_meeting(int counterpart, int initiated_from)
173 {
174 popup_diplomacy_dialog(counterpart);
175 }
176
177 /****************************************************************
178 ...
179 *****************************************************************/
handle_diplomacy_cancel_meeting(int counterpart,int initiated_from)180 void handle_diplomacy_cancel_meeting(int counterpart, int initiated_from)
181 {
182 struct Diplomacy_dialog *pdialog = find_diplomacy_dialog(counterpart);
183
184 if (!pdialog) {
185 return;
186 }
187
188 close_diplomacy_dialog(pdialog);
189 }
190
191 /****************************************************************
192 ...
193 *****************************************************************/
handle_diplomacy_create_clause(int counterpart,int giver,enum clause_type type,int value)194 void handle_diplomacy_create_clause(int counterpart, int giver,
195 enum clause_type type, int value)
196 {
197 struct Diplomacy_dialog *pdialog = find_diplomacy_dialog(counterpart);
198
199 if (!pdialog) {
200 return;
201 }
202
203 add_clause(&pdialog->treaty, player_by_number(giver), type, value);
204 update_diplomacy_dialog(pdialog);
205 }
206
207 /****************************************************************
208 ...
209 *****************************************************************/
handle_diplomacy_remove_clause(int counterpart,int giver,enum clause_type type,int value)210 void handle_diplomacy_remove_clause(int counterpart, int giver,
211 enum clause_type type, int value)
212 {
213 struct Diplomacy_dialog *pdialog = find_diplomacy_dialog(counterpart);
214
215 if (!pdialog) {
216 return;
217 }
218
219 remove_clause(&pdialog->treaty, player_by_number(giver), type, value);
220 update_diplomacy_dialog(pdialog);
221 }
222
223 /****************************************************************
224 popup the dialog 10% inside the main-window
225 *****************************************************************/
popup_diplomacy_dialog(int other_player_id)226 static void popup_diplomacy_dialog(int other_player_id)
227 {
228 struct Diplomacy_dialog *pdialog = find_diplomacy_dialog(other_player_id);
229
230 if (NULL == client.conn.playing || client.conn.playing->ai_controlled) {
231 return; /* Don't show if we are AI controlled. */
232 }
233
234 if (!pdialog) {
235 Position x, y;
236 Dimension width, height;
237
238 pdialog = create_diplomacy_dialog(client.conn.playing,
239 player_by_number(other_player_id));
240 XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
241 XtTranslateCoords(toplevel, (Position) width / 10,
242 (Position) height / 10, &x, &y);
243 XtVaSetValues(pdialog->dip_dialog_shell, XtNx, x, XtNy, y, NULL);
244 }
245
246 XtPopup(pdialog->dip_dialog_shell, XtGrabNone);
247 }
248
249
250 /****************************************************************
251 ...
252 *****************************************************************/
fill_diplomacy_tech_menu(Widget popupmenu,struct player * plr0,struct player * plr1)253 static int fill_diplomacy_tech_menu(Widget popupmenu,
254 struct player *plr0, struct player *plr1)
255 {
256 const struct research *presearch0, *presearch1;
257 int flag = 0;
258
259 if (!game.info.trading_tech) {
260 /* Trading advances deactivated. */
261 return 0;
262 }
263
264 presearch0 = research_get(plr0);
265 presearch1 = research_get(plr1);
266 advance_index_iterate(A_FIRST, i) {
267 if (research_invention_state(presearch0, i) == TECH_KNOWN
268 && research_invention_gettable(presearch1, i,
269 game.info.tech_trade_allow_holes)
270 && research_invention_state(presearch1, i) != TECH_KNOWN) {
271 Widget entry=
272 XtVaCreateManagedWidget(advance_name_translation(advance_by_number(i)),
273 smeBSBObjectClass,
274 popupmenu,
275 NULL);
276 XtAddCallback(entry, XtNcallback, diplomacy_dialog_tech_callback,
277 INT_TO_XTPOINTER((player_number(plr0) << 24) |
278 (player_number(plr1) << 16) |
279 i));
280 flag=1;
281 }
282 } advance_index_iterate_end;
283 return flag;
284 }
285
286 /****************************************************************
287 Creates a sorted list of plr0's cities, excluding the capital and
288 any cities not visible to plr1. This means that you can only trade
289 cities visible to requesting player.
290
291 - Kris Bubendorfer
292 *****************************************************************/
fill_diplomacy_city_menu(Widget popupmenu,struct player * plr0,struct player * plr1)293 static int fill_diplomacy_city_menu(Widget popupmenu,
294 struct player *plr0, struct player *plr1)
295 {
296 int i = 0, j = 0, n = city_list_size(plr0->cities);
297
298 if (game.info.trading_city) {
299 /* Trading cities deactivated. */
300 return 0;
301 }
302
303 struct city **city_list_ptrs;
304 if (n>0) {
305 city_list_ptrs = fc_malloc(sizeof(struct city*)*n);
306 } else {
307 city_list_ptrs = NULL;
308 }
309
310 city_list_iterate(plr0->cities, pcity) {
311 if (!is_capital(pcity)) {
312 city_list_ptrs[i] = pcity;
313 i++;
314 }
315 } city_list_iterate_end;
316
317 qsort(city_list_ptrs, i, sizeof(struct city*), city_name_compare);
318
319 for (j = 0; j < i; j++) {
320 Widget entry =
321 XtVaCreateManagedWidget(city_name_get(city_list_ptrs[j]), smeBSBObjectClass,
322 popupmenu, NULL);
323 XtAddCallback(entry, XtNcallback, diplomacy_dialog_city_callback,
324 INT_TO_XTPOINTER((player_number(plr0) << 24) |
325 (player_number(plr1) << 16) |
326 city_list_ptrs[j]->id));
327 }
328 free(city_list_ptrs);
329
330 return i;
331 }
332
333 /****************************************************************
334 ...
335 *****************************************************************/
create_diplomacy_dialog(struct player * plr0,struct player * plr1)336 struct Diplomacy_dialog *create_diplomacy_dialog(struct player *plr0,
337 struct player *plr1)
338 {
339 char plr0_buf[4 * MAX_LEN_NAME], plr1_buf[4 * MAX_LEN_NAME];
340 char buf[512], *pheadlinem;
341 struct Diplomacy_dialog *pdialog;
342 Dimension width, height, maxwidth;
343 Widget popupmenu;
344 Widget entry;
345
346 pdialog=fc_malloc(sizeof(struct Diplomacy_dialog));
347 dialog_list_prepend(dialog_list, pdialog);
348
349 init_treaty(&pdialog->treaty, plr0, plr1);
350
351 pdialog->dip_dialog_shell =
352 I_T(XtCreatePopupShell("dippopupshell", topLevelShellWidgetClass,
353 toplevel, NULL, 0));
354
355 pdialog->dip_form = XtVaCreateManagedWidget("dipform",
356 formWidgetClass,
357 pdialog->dip_dialog_shell,
358 NULL);
359
360 pdialog->dip_main_form = XtVaCreateManagedWidget("dipmainform",
361 formWidgetClass,
362 pdialog->dip_form,
363 NULL);
364
365 pdialog->dip_form0 = XtVaCreateManagedWidget("dipform0",
366 formWidgetClass,
367 pdialog->dip_main_form,
368 NULL);
369
370 pdialog->dip_formm = XtVaCreateManagedWidget("dipformm",
371 formWidgetClass,
372 pdialog->dip_main_form,
373 NULL);
374
375 pdialog->dip_form1 = XtVaCreateManagedWidget("dipform1",
376 formWidgetClass,
377 pdialog->dip_main_form,
378 NULL);
379
380 fc_snprintf(buf, sizeof(buf), _("The %s offerings"),
381 nation_adjective_for_player(plr0));
382 pdialog->dip_headline0=XtVaCreateManagedWidget("dipheadline0",
383 labelWidgetClass,
384 pdialog->dip_form0,
385 XtNlabel, buf,
386 NULL);
387
388 fc_snprintf(buf, sizeof(buf), _("The %s offerings"),
389 nation_adjective_for_player(plr1));
390 pdialog->dip_headline1=XtVaCreateManagedWidget("dipheadline1",
391 labelWidgetClass,
392 pdialog->dip_form1,
393 XtNlabel, buf,
394 NULL);
395
396
397 pdialog->dip_map_menubutton0 =
398 I_L(XtVaCreateManagedWidget("dipmapmenubutton0",
399 menuButtonWidgetClass,
400 pdialog->dip_form0,
401 NULL));
402 popupmenu=XtVaCreatePopupShell("menu",
403 simpleMenuWidgetClass,
404 pdialog->dip_map_menubutton0,
405 NULL);
406
407 entry=XtVaCreateManagedWidget(_("World-map"), smeBSBObjectClass,
408 popupmenu, NULL);
409 XtAddCallback(entry, XtNcallback, diplomacy_dialog_map_callback,
410 (XtPointer)pdialog);
411 entry=XtVaCreateManagedWidget(_("Sea-map"), smeBSBObjectClass,
412 popupmenu, NULL);
413 XtAddCallback(entry, XtNcallback, diplomacy_dialog_seamap_callback,
414 (XtPointer)pdialog);
415
416 pdialog->dip_map_menubutton1 =
417 I_L(XtVaCreateManagedWidget("dipmapmenubutton1",
418 menuButtonWidgetClass,
419 pdialog->dip_form1,
420 NULL));
421 popupmenu=XtVaCreatePopupShell("menu",
422 simpleMenuWidgetClass,
423 pdialog->dip_map_menubutton1,
424 NULL);
425 entry=XtVaCreateManagedWidget(_("World-map"), smeBSBObjectClass,
426 popupmenu, NULL);
427 XtAddCallback(entry, XtNcallback, diplomacy_dialog_map_callback,
428 (XtPointer)pdialog);
429 entry=XtVaCreateManagedWidget(_("Sea-map"), smeBSBObjectClass,
430 popupmenu, NULL);
431 XtAddCallback(entry, XtNcallback, diplomacy_dialog_seamap_callback,
432 (XtPointer)pdialog);
433
434
435 pdialog->dip_tech_menubutton0 =
436 I_L(XtVaCreateManagedWidget("diptechmenubutton0",
437 menuButtonWidgetClass,
438 pdialog->dip_form0,
439 NULL));
440 popupmenu=XtVaCreatePopupShell("menu",
441 simpleMenuWidgetClass,
442 pdialog->dip_tech_menubutton0,
443 NULL);
444
445 if(!fill_diplomacy_tech_menu(popupmenu, plr0, plr1))
446 XtSetSensitive(pdialog->dip_tech_menubutton0, FALSE);
447
448
449 pdialog->dip_tech_menubutton1 =
450 I_L(XtVaCreateManagedWidget("diptechmenubutton1",
451 menuButtonWidgetClass,
452 pdialog->dip_form1,
453 NULL));
454 popupmenu=XtVaCreatePopupShell("menu",
455 simpleMenuWidgetClass,
456 pdialog->dip_tech_menubutton1,
457 NULL);
458 if(!fill_diplomacy_tech_menu(popupmenu, plr1, plr0))
459 XtSetSensitive(pdialog->dip_tech_menubutton1, FALSE);
460
461 /* Start of trade city code - Kris Bubendorfer */
462
463 pdialog->dip_city_menubutton0 =
464 I_L(XtVaCreateManagedWidget("dipcitymenubutton0",
465 menuButtonWidgetClass,
466 pdialog->dip_form0,
467 NULL));
468 popupmenu=XtVaCreatePopupShell("menu",
469 simpleMenuWidgetClass,
470 pdialog->dip_city_menubutton0,
471 NULL);
472
473 XtSetSensitive(pdialog->dip_city_menubutton0,
474 fill_diplomacy_city_menu(popupmenu, plr0, plr1));
475
476
477 pdialog->dip_city_menubutton1 =
478 I_L(XtVaCreateManagedWidget("dipcitymenubutton1",
479 menuButtonWidgetClass,
480 pdialog->dip_form1,
481 NULL));
482 popupmenu=XtVaCreatePopupShell("menu",
483 simpleMenuWidgetClass,
484 pdialog->dip_city_menubutton1,
485 NULL);
486
487 XtSetSensitive(pdialog->dip_city_menubutton1,
488 fill_diplomacy_city_menu(popupmenu, plr1, plr0));
489
490 /* End of trade city code */
491
492 /* Trading gold */
493 if (game.info.trading_gold) {
494 pdialog->dip_gold_input0 = XtVaCreateManagedWidget("dipgoldinput0",
495 asciiTextWidgetClass,
496 pdialog->dip_form0, NULL);
497 fc_snprintf(buf, sizeof(buf), _("Gold(max %d)"), plr0->economic.gold);
498 pdialog->dip_gold_label0 = XtVaCreateManagedWidget("dipgoldlabel0",
499 labelWidgetClass,
500 pdialog->dip_form0,
501 XtNlabel, buf, NULL);
502
503
504 pdialog->dip_gold_input1 = XtVaCreateManagedWidget("dipgoldinput1",
505 asciiTextWidgetClass,
506 pdialog->dip_form1, NULL);
507 fc_snprintf(buf, sizeof(buf), _("Gold(max %d)"), plr1->economic.gold);
508 pdialog->dip_gold_label1 = XtVaCreateManagedWidget("dipgoldlabel1",
509 labelWidgetClass,
510 pdialog->dip_form1,
511 XtNlabel, buf, NULL);
512 } else {
513 pdialog->dip_gold_input0 = NULL;
514 pdialog->dip_gold_input1 = NULL;
515 pdialog->dip_gold_label0 = NULL;
516 pdialog->dip_gold_label1 = NULL;
517 }
518
519 pdialog->dip_vision_button0 =
520 I_L(XtVaCreateManagedWidget("dipvisionbutton0",
521 commandWidgetClass,
522 pdialog->dip_form0,
523 NULL));
524 if (gives_shared_vision(plr0, plr1))
525 XtSetSensitive(pdialog->dip_vision_button0, FALSE);
526
527 pdialog->dip_vision_button1 =
528 I_L(XtVaCreateManagedWidget("dipvisionbutton1",
529 commandWidgetClass,
530 pdialog->dip_form1,
531 NULL));
532 if (gives_shared_vision(plr1, plr0))
533 XtSetSensitive(pdialog->dip_vision_button1, FALSE);
534
535 XtAddCallback(pdialog->dip_vision_button0, XtNcallback,
536 diplomacy_dialog_vision_callback, (XtPointer)pdialog);
537 XtAddCallback(pdialog->dip_vision_button1, XtNcallback,
538 diplomacy_dialog_vision_callback, (XtPointer)pdialog);
539
540
541 pdialog->dip_pact_menubutton=
542 I_L(XtVaCreateManagedWidget("dippactmenubutton",
543 menuButtonWidgetClass,
544 pdialog->dip_form0,
545 NULL));
546 popupmenu=XtVaCreatePopupShell("menu",
547 simpleMenuWidgetClass,
548 pdialog->dip_pact_menubutton,
549 NULL);
550 entry=XtVaCreateManagedWidget(Q_("?diplomatic_state:Cease-fire"),
551 smeBSBObjectClass, popupmenu, NULL);
552 XtAddCallback(entry, XtNcallback, diplomacy_dialog_ceasefire_callback,
553 (XtPointer)pdialog);
554 entry=XtVaCreateManagedWidget(Q_("?diplomatic_state:Peace"),
555 smeBSBObjectClass, popupmenu, NULL);
556 XtAddCallback(entry, XtNcallback, diplomacy_dialog_peace_callback,
557 (XtPointer)pdialog);
558 entry=XtVaCreateManagedWidget(Q_("?diplomatic_state:Alliance"),
559 smeBSBObjectClass, popupmenu, NULL);
560 XtAddCallback(entry, XtNcallback, diplomacy_dialog_alliance_callback,
561 (XtPointer)pdialog);
562
563 fc_snprintf(buf, sizeof(buf),
564 /* TRANS: The <nation adjective> <ruler-title + player-name>
565 * E.g. "The Czech President Vaclav Havel". */
566 _("This Eternal Treaty\n"
567 "marks the results of the diplomatic work between\n"
568 "The %s %s\nand\nThe %s %s"),
569 nation_adjective_for_player(plr0),
570 ruler_title_for_player(plr0, plr0_buf, sizeof(plr0_buf)),
571 nation_adjective_for_player(plr1),
572 ruler_title_for_player(plr1, plr1_buf, sizeof(plr1_buf)));
573
574 pheadlinem=create_centered_string(buf);
575 pdialog->dip_headline1=XtVaCreateManagedWidget("dipheadlinem",
576 labelWidgetClass,
577 pdialog->dip_formm,
578 XtNlabel, pheadlinem,
579 NULL);
580
581 pdialog->dip_clauselabel =
582 I_L(XtVaCreateManagedWidget("dipclauselabel",
583 labelWidgetClass,
584 pdialog->dip_formm,
585 NULL));
586
587 pdialog->dip_view = XtVaCreateManagedWidget("dipview",
588 viewportWidgetClass,
589 pdialog->dip_formm,
590 NULL);
591
592
593 pdialog->dip_clauselist = XtVaCreateManagedWidget("dipclauselist",
594 listWidgetClass,
595 pdialog->dip_view,
596 XtNlist,
597 (XtArgVal)dummy_clause_list_strings,
598 NULL);
599
600 XtVaGetValues(pdialog->dip_headline1, XtNwidth, &width, NULL);
601 XtVaSetValues(pdialog->dip_view, XtNwidth, width, NULL);
602 XtVaSetValues(pdialog->dip_clauselist, XtNwidth, width, NULL);
603
604 fc_snprintf(buf, sizeof(buf), _("%s view:"),
605 nation_adjective_for_player(plr0));
606 pdialog->dip_acceptlabel0=XtVaCreateManagedWidget("dipacceptlabel0",
607 labelWidgetClass,
608 pdialog->dip_formm,
609 XtNlabel, buf,
610 NULL);
611 pdialog->dip_acceptthumb0=XtVaCreateManagedWidget("dipacceptthumb0",
612 labelWidgetClass,
613 pdialog->dip_formm,
614 XtNbitmap, get_thumb_pixmap(0),
615 NULL);
616 fc_snprintf(buf, sizeof(buf), _("%s view:"),
617 nation_adjective_for_player(plr1));
618 pdialog->dip_acceptlabel1=XtVaCreateManagedWidget("dipacceptlabel1",
619 labelWidgetClass,
620 pdialog->dip_formm,
621 XtNlabel, buf,
622 NULL);
623 pdialog->dip_acceptthumb1=XtVaCreateManagedWidget("dipacceptthumb1",
624 labelWidgetClass,
625 pdialog->dip_formm,
626 NULL);
627
628
629 pdialog->dip_erase_clause_command =
630 I_L(XtVaCreateManagedWidget("diperaseclausecommand",
631 commandWidgetClass,
632 pdialog->dip_main_form,
633 NULL));
634
635 pdialog->dip_accept_command =
636 I_L(XtVaCreateManagedWidget("dipacceptcommand",
637 commandWidgetClass,
638 pdialog->dip_form,
639 NULL));
640
641 pdialog->dip_close_command =
642 I_L(XtVaCreateManagedWidget("dipclosecommand",
643 commandWidgetClass,
644 pdialog->dip_form,
645 NULL));
646
647 XtAddCallback(pdialog->dip_close_command, XtNcallback,
648 diplomacy_dialog_close_callback, (XtPointer)pdialog);
649 XtAddCallback(pdialog->dip_erase_clause_command, XtNcallback,
650 diplomacy_dialog_erase_clause_callback, (XtPointer)pdialog);
651 XtAddCallback(pdialog->dip_accept_command, XtNcallback,
652 diplomacy_dialog_accept_callback, (XtPointer)pdialog);
653
654
655 XtRealizeWidget(pdialog->dip_dialog_shell);
656
657
658 XtVaGetValues(pdialog->dip_map_menubutton0, XtNwidth, &maxwidth, NULL);
659 XtVaGetValues(pdialog->dip_tech_menubutton0, XtNwidth, &width, NULL);
660 XtVaGetValues(pdialog->dip_city_menubutton0, XtNwidth, &width, NULL);
661 maxwidth=MAX(width, maxwidth);
662 if (pdialog->dip_gold_input0) {
663 XtVaGetValues(pdialog->dip_gold_input0, XtNwidth, &width, NULL);
664 }
665 maxwidth=MAX(width, maxwidth);
666 XtVaSetValues(pdialog->dip_map_menubutton0, XtNwidth, maxwidth, NULL);
667 XtVaSetValues(pdialog->dip_tech_menubutton0, XtNwidth, maxwidth, NULL);
668 XtVaSetValues(pdialog->dip_city_menubutton0, XtNwidth, maxwidth, NULL);
669 if (pdialog->dip_gold_input0) {
670 XtVaSetValues(pdialog->dip_gold_input0, XtNwidth, maxwidth, NULL);
671 }
672
673 XtVaGetValues(pdialog->dip_formm, XtNheight, &height, NULL);
674 XtVaSetValues(pdialog->dip_form0, XtNheight, height, NULL);
675 XtVaSetValues(pdialog->dip_form1, XtNheight, height, NULL);
676
677
678 free(pheadlinem);
679
680 update_diplomacy_dialog(pdialog);
681
682 return pdialog;
683 }
684
685
686 /**************************************************************************
687 ...
688 **************************************************************************/
update_diplomacy_dialog(struct Diplomacy_dialog * pdialog)689 void update_diplomacy_dialog(struct Diplomacy_dialog *pdialog)
690 {
691 int i = 0;
692 const int n = sizeof(pdialog->clauselist_strings[0]);
693
694 clause_list_iterate(pdialog->treaty.clauses, pclause) {
695 client_diplomacy_clause_string(pdialog->clauselist_strings[i], n, pclause);
696 pdialog->clauselist_strings_ptrs[i]=pdialog->clauselist_strings[i];
697 i++;
698 } clause_list_iterate_end;
699
700 pdialog->clauselist_strings_ptrs[i]=0;
701 XawListChange(pdialog->dip_clauselist, pdialog->clauselist_strings_ptrs,
702 0, 0, False);
703
704 /* force refresh of viewport so that scrollbar is added
705 sun seems to need this */
706 XtVaSetValues(pdialog->dip_view, XtNforceBars, False, NULL);
707 XtVaSetValues(pdialog->dip_view, XtNforceBars, True, NULL);
708
709 xaw_set_bitmap(pdialog->dip_acceptthumb0,
710 get_thumb_pixmap(pdialog->treaty.accept0));
711 xaw_set_bitmap(pdialog->dip_acceptthumb1,
712 get_thumb_pixmap(pdialog->treaty.accept1));
713 }
714
715 /****************************************************************
716 Callback for trading techs
717 *****************************************************************/
diplomacy_dialog_tech_callback(Widget w,XtPointer client_data,XtPointer call_data)718 void diplomacy_dialog_tech_callback(Widget w, XtPointer client_data,
719 XtPointer call_data)
720 {
721 size_t choice = (size_t) client_data;
722 int giver = (choice >> 24) & 0xff, dest = (choice >> 16) & 0xff, other;
723 int tech = choice & 0xffff;
724
725 if (player_by_number(giver) == client.conn.playing) {
726 other = dest;
727 } else {
728 other = giver;
729 }
730
731 dsend_packet_diplomacy_create_clause_req(&client.conn, other, giver,
732 CLAUSE_ADVANCE, tech);
733 }
734
735 /****************************************************************
736 Callback for trading cities
737 - Kris Bubendorfer
738 *****************************************************************/
diplomacy_dialog_city_callback(Widget w,XtPointer client_data,XtPointer call_data)739 void diplomacy_dialog_city_callback(Widget w, XtPointer client_data,
740 XtPointer call_data)
741 {
742 size_t choice = (size_t) client_data;
743 int giver = (choice >> 24) & 0xff, dest = (choice >> 16) & 0xff, other;
744 int city = choice & 0xffff;
745
746 if (player_by_number(giver) == client.conn.playing) {
747 other = dest;
748 } else {
749 other = giver;
750 }
751
752 dsend_packet_diplomacy_create_clause_req(&client.conn, other, giver,
753 CLAUSE_CITY, city);
754 }
755
756 /****************************************************************
757 ...
758 *****************************************************************/
diplomacy_dialog_erase_clause_callback(Widget w,XtPointer client_data,XtPointer call_data)759 void diplomacy_dialog_erase_clause_callback(Widget w, XtPointer client_data,
760 XtPointer call_data)
761 {
762 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
763 XawListReturnStruct *ret = XawListShowCurrent(pdialog->dip_clauselist);
764
765 if (ret->list_index != XAW_LIST_NONE) {
766 int i = 0;
767
768 clause_list_iterate(pdialog->treaty.clauses, pclause) {
769 if (i == ret->list_index) {
770 dsend_packet_diplomacy_remove_clause_req(&client.conn,
771 player_number(pdialog->treaty.plr1),
772 player_number(pclause->from),
773 pclause->type,
774 pclause->value);
775 return;
776 }
777 i++;
778 } clause_list_iterate_end;
779 }
780 }
781
782 /****************************************************************
783 Callback for trading map
784 *****************************************************************/
diplomacy_dialog_map_callback(Widget w,XtPointer client_data,XtPointer call_data)785 void diplomacy_dialog_map_callback(Widget w, XtPointer client_data,
786 XtPointer call_data)
787 {
788 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
789 struct player *pgiver =
790 (XtParent(XtParent(w)) ==
791 pdialog->dip_map_menubutton0) ? pdialog->treaty.plr0 : pdialog->
792 treaty.plr1;
793
794 dsend_packet_diplomacy_create_clause_req(&client.conn,
795 player_number(pdialog->treaty.plr1),
796 player_number(pgiver), CLAUSE_MAP, 0);
797 }
798
799 /****************************************************************
800 Callback for trading seamap
801 *****************************************************************/
diplomacy_dialog_seamap_callback(Widget w,XtPointer client_data,XtPointer call_data)802 void diplomacy_dialog_seamap_callback(Widget w, XtPointer client_data,
803 XtPointer call_data)
804 {
805 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
806 struct player *pgiver =
807 (XtParent(XtParent(w)) ==
808 pdialog->dip_map_menubutton0) ? pdialog->treaty.plr0 : pdialog->
809 treaty.plr1;
810
811 dsend_packet_diplomacy_create_clause_req(&client.conn,
812 player_number(pdialog->treaty.plr1),
813 player_number(pgiver), CLAUSE_SEAMAP,
814 0);
815 }
816
817 /****************************************************************
818 ...
819 *****************************************************************/
diplomacy_dialog_vision_callback(Widget w,XtPointer client_data,XtPointer call_data)820 void diplomacy_dialog_vision_callback(Widget w, XtPointer client_data,
821 XtPointer call_data)
822 {
823 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
824 struct player *pgiver = (w == pdialog->dip_vision_button0) ?
825 pdialog->treaty.plr0 : pdialog->treaty.plr1;
826
827 dsend_packet_diplomacy_create_clause_req(&client.conn,
828 player_number(pdialog->treaty.plr1),
829 player_number(pgiver), CLAUSE_VISION,
830 0);
831 }
832
833 /****************************************************************
834 Generic add-a-clause function for adding pact types
835 *****************************************************************/
diplomacy_dialog_add_pact_clause(Widget w,XtPointer client_data,XtPointer call_data,int type)836 static void diplomacy_dialog_add_pact_clause(Widget w, XtPointer client_data,
837 XtPointer call_data, int type)
838 {
839 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
840 struct player *pgiver = (w == pdialog->dip_vision_button0) ?
841 pdialog->treaty.plr0 : pdialog->treaty.plr1;
842
843 dsend_packet_diplomacy_create_clause_req(&client.conn,
844 player_number(pdialog->treaty.plr1),
845 player_number(pgiver), type, 0);
846 }
847
848 /****************************************************************
849 The cease-fire widget was selected; add a cease-fire to the
850 clauses
851 *****************************************************************/
diplomacy_dialog_ceasefire_callback(Widget w,XtPointer client_data,XtPointer call_data)852 void diplomacy_dialog_ceasefire_callback(Widget w, XtPointer client_data,
853 XtPointer call_data)
854 {
855 diplomacy_dialog_add_pact_clause(w, client_data, call_data,
856 CLAUSE_CEASEFIRE);
857 }
858
859 /****************************************************************
860 The peace widget was selected; add a peace treaty to the
861 clauses
862 *****************************************************************/
diplomacy_dialog_peace_callback(Widget w,XtPointer client_data,XtPointer call_data)863 void diplomacy_dialog_peace_callback(Widget w, XtPointer client_data,
864 XtPointer call_data)
865 {
866 diplomacy_dialog_add_pact_clause(w, client_data, call_data,
867 CLAUSE_PEACE);
868 }
869
870 /****************************************************************
871 The alliance widget was selected; add an alliance to the
872 clauses
873 *****************************************************************/
diplomacy_dialog_alliance_callback(Widget w,XtPointer client_data,XtPointer call_data)874 void diplomacy_dialog_alliance_callback(Widget w, XtPointer client_data,
875 XtPointer call_data)
876 {
877 diplomacy_dialog_add_pact_clause(w, client_data, call_data,
878 CLAUSE_ALLIANCE);
879 }
880
881
882 /****************************************************************
883 ...
884 *****************************************************************/
diplomacy_dialog_close_callback(Widget w,XtPointer client_data,XtPointer call_data)885 void diplomacy_dialog_close_callback(Widget w, XtPointer client_data,
886 XtPointer call_data)
887 {
888 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
889
890 dsend_packet_diplomacy_cancel_meeting_req(&client.conn,
891 player_number(pdialog->treaty.plr1));
892 close_diplomacy_dialog(pdialog);
893 }
894
895
896 /****************************************************************
897 ...
898 *****************************************************************/
diplomacy_dialog_accept_callback(Widget w,XtPointer client_data,XtPointer call_data)899 void diplomacy_dialog_accept_callback(Widget w, XtPointer client_data,
900 XtPointer call_data)
901 {
902 struct Diplomacy_dialog *pdialog = (struct Diplomacy_dialog *) client_data;
903
904 dsend_packet_diplomacy_accept_treaty_req(&client.conn,
905 player_number(pdialog->treaty.plr1));
906 }
907
908
909 /*****************************************************************
910 ...
911 *****************************************************************/
close_diplomacy_dialog(struct Diplomacy_dialog * pdialog)912 void close_diplomacy_dialog(struct Diplomacy_dialog *pdialog)
913 {
914 XtDestroyWidget(pdialog->dip_dialog_shell);
915
916 dialog_list_remove(dialog_list, pdialog);
917 free(pdialog);
918 }
919
920 /*****************************************************************
921 ...
922 *****************************************************************/
find_diplomacy_dialog(int other_player_id)923 static struct Diplomacy_dialog *find_diplomacy_dialog(int other_player_id)
924 {
925 struct player *plr0 = client.conn.playing;
926 struct player *plr1 = player_by_number(other_player_id);
927
928 if (!dialog_list_list_has_been_initialised) {
929 dialog_list = dialog_list_new();
930 dialog_list_list_has_been_initialised = TRUE;
931 }
932
933 dialog_list_iterate(dialog_list, pdialog) {
934 if ((pdialog->treaty.plr0 == plr0 && pdialog->treaty.plr1 == plr1) ||
935 (pdialog->treaty.plr0 == plr1 && pdialog->treaty.plr1 == plr0)) {
936 return pdialog;
937 }
938 } dialog_list_iterate_end;
939
940 return NULL;
941 }
942
943 /*****************************************************************
944 ...
945 *****************************************************************/
find_diplomacy_by_input(Widget w)946 static struct Diplomacy_dialog *find_diplomacy_by_input(Widget w)
947 {
948 dialog_list_iterate(dialog_list, pdialog) {
949 if ((pdialog->dip_gold_input0 == w) || (pdialog->dip_gold_input1 == w)) {
950 return pdialog;
951 }
952 } dialog_list_iterate_end;
953
954 return NULL;
955 }
956
957 /*****************************************************************
958 ...
959 *****************************************************************/
diplodlg_key_gold(Widget w)960 void diplodlg_key_gold(Widget w)
961 {
962 struct Diplomacy_dialog *pdialog = find_diplomacy_by_input(w);
963
964 if (pdialog) {
965 struct player *pgiver = (w == pdialog->dip_gold_input0) ?
966 pdialog->treaty.plr0 : pdialog->treaty.plr1;
967 XtPointer dp;
968 int amount;
969
970 XtVaGetValues(w, XtNstring, &dp, NULL);
971 if (str_to_int(dp, &amount) && 0 <= amount
972 && amount <= pgiver->economic.gold) {
973 dsend_packet_diplomacy_create_clause_req(&client.conn,
974 player_number(pdialog->treaty.plr1),
975 player_number(pgiver),
976 CLAUSE_GOLD, amount);
977 XtVaSetValues(w, XtNstring, "", NULL);
978 } else {
979 output_window_append(ftc_client,
980 _("Invalid amount of gold specified."));
981 }
982 }
983 }
984
985 /*****************************************************************
986 Close all dialogs, for when client disconnects from game.
987 *****************************************************************/
close_all_diplomacy_dialogs(void)988 void close_all_diplomacy_dialogs(void)
989 {
990 if (!dialog_list_list_has_been_initialised) {
991 return;
992 }
993
994 while (dialog_list_size(dialog_list) > 0) {
995 close_diplomacy_dialog(dialog_list_get(dialog_list, 0));
996 }
997 }
998