1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
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>
42 #include "diptreaty.h"
44 #include "government.h"
51 #include "client_main.h"
57 #include "gui_stuff.h"
62 #define MAX_NUM_CLAUSES 64
64 struct Diplomacy_dialog
{
67 Widget dip_dialog_shell
;
68 Widget dip_form
, dip_main_form
, dip_form0
, dip_formm
, dip_form1
;
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
;
90 Widget dip_clauselabel
;
91 Widget dip_clauselist
;
92 Widget dip_acceptlabel0
;
93 Widget dip_acceptthumb0
;
94 Widget dip_acceptlabel1
;
95 Widget dip_acceptthumb1
;
97 Widget dip_accept_command
;
98 Widget dip_close_command
;
100 Widget dip_erase_clause_command
;
102 char clauselist_strings
[MAX_NUM_CLAUSES
+1][128];
103 char *clauselist_strings_ptrs
[MAX_NUM_CLAUSES
+1];
106 static char *dummy_clause_list_strings
[]
107 = { "\n", "\n", "\n", "\n", "\n", "\n", 0 };
109 #define SPECLIST_TAG dialog
110 #define SPECLIST_TYPE struct Diplomacy_dialog
111 #include "speclist.h"
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
117 static struct dialog_list
*dialog_list
= NULL
;
118 static bool dialog_list_list_has_been_initialised
= FALSE
;
120 struct Diplomacy_dialog
*create_diplomacy_dialog(struct player
*plr0
,
121 struct player
*plr1
);
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
);
151 /****************************************************************
153 *****************************************************************/
154 void handle_diplomacy_accept_treaty(int counterpart
, bool I_accepted
,
157 struct Diplomacy_dialog
*pdialog
= find_diplomacy_dialog(counterpart
);
163 pdialog
->treaty
.accept0
= I_accepted
;
164 pdialog
->treaty
.accept1
= other_accepted
;
166 update_diplomacy_dialog(pdialog
);
169 /****************************************************************
171 *****************************************************************/
172 void handle_diplomacy_init_meeting(int counterpart
, int initiated_from
)
174 popup_diplomacy_dialog(counterpart
);
177 /****************************************************************
179 *****************************************************************/
180 void handle_diplomacy_cancel_meeting(int counterpart
, int initiated_from
)
182 struct Diplomacy_dialog
*pdialog
= find_diplomacy_dialog(counterpart
);
188 close_diplomacy_dialog(pdialog
);
191 /****************************************************************
193 *****************************************************************/
194 void handle_diplomacy_create_clause(int counterpart
, int giver
,
195 enum clause_type type
, int value
)
197 struct Diplomacy_dialog
*pdialog
= find_diplomacy_dialog(counterpart
);
203 add_clause(&pdialog
->treaty
, player_by_number(giver
), type
, value
);
204 update_diplomacy_dialog(pdialog
);
207 /****************************************************************
209 *****************************************************************/
210 void handle_diplomacy_remove_clause(int counterpart
, int giver
,
211 enum clause_type type
, int value
)
213 struct Diplomacy_dialog
*pdialog
= find_diplomacy_dialog(counterpart
);
219 remove_clause(&pdialog
->treaty
, player_by_number(giver
), type
, value
);
220 update_diplomacy_dialog(pdialog
);
223 /****************************************************************
224 popup the dialog 10% inside the main-window
225 *****************************************************************/
226 static void popup_diplomacy_dialog(int other_player_id
)
228 struct Diplomacy_dialog
*pdialog
= find_diplomacy_dialog(other_player_id
);
230 if (NULL
== client
.conn
.playing
|| client
.conn
.playing
->ai_controlled
) {
231 return; /* Don't show if we are AI controlled. */
236 Dimension width
, height
;
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
);
246 XtPopup(pdialog
->dip_dialog_shell
, XtGrabNone
);
250 /****************************************************************
252 *****************************************************************/
253 static int fill_diplomacy_tech_menu(Widget popupmenu
,
254 struct player
*plr0
, struct player
*plr1
)
256 const struct research
*presearch0
, *presearch1
;
259 if (!game
.info
.trading_tech
) {
260 /* Trading advances deactivated. */
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
) {
272 XtVaCreateManagedWidget(advance_name_translation(advance_by_number(i
)),
276 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_tech_callback
,
277 INT_TO_XTPOINTER((player_number(plr0
) << 24) |
278 (player_number(plr1
) << 16) |
282 } advance_index_iterate_end
;
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.
292 *****************************************************************/
293 static int fill_diplomacy_city_menu(Widget popupmenu
,
294 struct player
*plr0
, struct player
*plr1
)
296 int i
= 0, j
= 0, n
= city_list_size(plr0
->cities
);
298 if (game
.info
.trading_city
) {
299 /* Trading cities deactivated. */
303 struct city
**city_list_ptrs
;
305 city_list_ptrs
= fc_malloc(sizeof(struct city
*)*n
);
307 city_list_ptrs
= NULL
;
310 city_list_iterate(plr0
->cities
, pcity
) {
311 if (!is_capital(pcity
)) {
312 city_list_ptrs
[i
] = pcity
;
315 } city_list_iterate_end
;
317 qsort(city_list_ptrs
, i
, sizeof(struct city
*), city_name_compare
);
319 for (j
= 0; j
< i
; j
++) {
321 XtVaCreateManagedWidget(city_name_get(city_list_ptrs
[j
]), smeBSBObjectClass
,
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
));
328 free(city_list_ptrs
);
333 /****************************************************************
335 *****************************************************************/
336 struct Diplomacy_dialog
*create_diplomacy_dialog(struct player
*plr0
,
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
;
346 pdialog
=fc_malloc(sizeof(struct Diplomacy_dialog
));
347 dialog_list_prepend(dialog_list
, pdialog
);
349 init_treaty(&pdialog
->treaty
, plr0
, plr1
);
351 pdialog
->dip_dialog_shell
=
352 I_T(XtCreatePopupShell("dippopupshell", topLevelShellWidgetClass
,
355 pdialog
->dip_form
= XtVaCreateManagedWidget("dipform",
357 pdialog
->dip_dialog_shell
,
360 pdialog
->dip_main_form
= XtVaCreateManagedWidget("dipmainform",
365 pdialog
->dip_form0
= XtVaCreateManagedWidget("dipform0",
367 pdialog
->dip_main_form
,
370 pdialog
->dip_formm
= XtVaCreateManagedWidget("dipformm",
372 pdialog
->dip_main_form
,
375 pdialog
->dip_form1
= XtVaCreateManagedWidget("dipform1",
377 pdialog
->dip_main_form
,
380 fc_snprintf(buf
, sizeof(buf
), _("The %s offerings"),
381 nation_adjective_for_player(plr0
));
382 pdialog
->dip_headline0
=XtVaCreateManagedWidget("dipheadline0",
388 fc_snprintf(buf
, sizeof(buf
), _("The %s offerings"),
389 nation_adjective_for_player(plr1
));
390 pdialog
->dip_headline1
=XtVaCreateManagedWidget("dipheadline1",
397 pdialog
->dip_map_menubutton0
=
398 I_L(XtVaCreateManagedWidget("dipmapmenubutton0",
399 menuButtonWidgetClass
,
402 popupmenu
=XtVaCreatePopupShell("menu",
403 simpleMenuWidgetClass
,
404 pdialog
->dip_map_menubutton0
,
407 entry
=XtVaCreateManagedWidget(_("World-map"), smeBSBObjectClass
,
409 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_map_callback
,
411 entry
=XtVaCreateManagedWidget(_("Sea-map"), smeBSBObjectClass
,
413 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_seamap_callback
,
416 pdialog
->dip_map_menubutton1
=
417 I_L(XtVaCreateManagedWidget("dipmapmenubutton1",
418 menuButtonWidgetClass
,
421 popupmenu
=XtVaCreatePopupShell("menu",
422 simpleMenuWidgetClass
,
423 pdialog
->dip_map_menubutton1
,
425 entry
=XtVaCreateManagedWidget(_("World-map"), smeBSBObjectClass
,
427 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_map_callback
,
429 entry
=XtVaCreateManagedWidget(_("Sea-map"), smeBSBObjectClass
,
431 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_seamap_callback
,
435 pdialog
->dip_tech_menubutton0
=
436 I_L(XtVaCreateManagedWidget("diptechmenubutton0",
437 menuButtonWidgetClass
,
440 popupmenu
=XtVaCreatePopupShell("menu",
441 simpleMenuWidgetClass
,
442 pdialog
->dip_tech_menubutton0
,
445 if(!fill_diplomacy_tech_menu(popupmenu
, plr0
, plr1
))
446 XtSetSensitive(pdialog
->dip_tech_menubutton0
, FALSE
);
449 pdialog
->dip_tech_menubutton1
=
450 I_L(XtVaCreateManagedWidget("diptechmenubutton1",
451 menuButtonWidgetClass
,
454 popupmenu
=XtVaCreatePopupShell("menu",
455 simpleMenuWidgetClass
,
456 pdialog
->dip_tech_menubutton1
,
458 if(!fill_diplomacy_tech_menu(popupmenu
, plr1
, plr0
))
459 XtSetSensitive(pdialog
->dip_tech_menubutton1
, FALSE
);
461 /* Start of trade city code - Kris Bubendorfer */
463 pdialog
->dip_city_menubutton0
=
464 I_L(XtVaCreateManagedWidget("dipcitymenubutton0",
465 menuButtonWidgetClass
,
468 popupmenu
=XtVaCreatePopupShell("menu",
469 simpleMenuWidgetClass
,
470 pdialog
->dip_city_menubutton0
,
473 XtSetSensitive(pdialog
->dip_city_menubutton0
,
474 fill_diplomacy_city_menu(popupmenu
, plr0
, plr1
));
477 pdialog
->dip_city_menubutton1
=
478 I_L(XtVaCreateManagedWidget("dipcitymenubutton1",
479 menuButtonWidgetClass
,
482 popupmenu
=XtVaCreatePopupShell("menu",
483 simpleMenuWidgetClass
,
484 pdialog
->dip_city_menubutton1
,
487 XtSetSensitive(pdialog
->dip_city_menubutton1
,
488 fill_diplomacy_city_menu(popupmenu
, plr1
, plr0
));
490 /* End of trade city code */
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",
501 XtNlabel
, buf
, NULL
);
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",
511 XtNlabel
, buf
, NULL
);
513 pdialog
->dip_gold_input0
= NULL
;
514 pdialog
->dip_gold_input1
= NULL
;
515 pdialog
->dip_gold_label0
= NULL
;
516 pdialog
->dip_gold_label1
= NULL
;
519 pdialog
->dip_vision_button0
=
520 I_L(XtVaCreateManagedWidget("dipvisionbutton0",
524 if (gives_shared_vision(plr0
, plr1
))
525 XtSetSensitive(pdialog
->dip_vision_button0
, FALSE
);
527 pdialog
->dip_vision_button1
=
528 I_L(XtVaCreateManagedWidget("dipvisionbutton1",
532 if (gives_shared_vision(plr1
, plr0
))
533 XtSetSensitive(pdialog
->dip_vision_button1
, FALSE
);
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
);
541 pdialog
->dip_pact_menubutton
=
542 I_L(XtVaCreateManagedWidget("dippactmenubutton",
543 menuButtonWidgetClass
,
546 popupmenu
=XtVaCreatePopupShell("menu",
547 simpleMenuWidgetClass
,
548 pdialog
->dip_pact_menubutton
,
550 entry
=XtVaCreateManagedWidget(Q_("?diplomatic_state:Cease-fire"),
551 smeBSBObjectClass
, popupmenu
, NULL
);
552 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_ceasefire_callback
,
554 entry
=XtVaCreateManagedWidget(Q_("?diplomatic_state:Peace"),
555 smeBSBObjectClass
, popupmenu
, NULL
);
556 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_peace_callback
,
558 entry
=XtVaCreateManagedWidget(Q_("?diplomatic_state:Alliance"),
559 smeBSBObjectClass
, popupmenu
, NULL
);
560 XtAddCallback(entry
, XtNcallback
, diplomacy_dialog_alliance_callback
,
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
)));
574 pheadlinem
=create_centered_string(buf
);
575 pdialog
->dip_headline1
=XtVaCreateManagedWidget("dipheadlinem",
578 XtNlabel
, pheadlinem
,
581 pdialog
->dip_clauselabel
=
582 I_L(XtVaCreateManagedWidget("dipclauselabel",
587 pdialog
->dip_view
= XtVaCreateManagedWidget("dipview",
593 pdialog
->dip_clauselist
= XtVaCreateManagedWidget("dipclauselist",
597 (XtArgVal
)dummy_clause_list_strings
,
600 XtVaGetValues(pdialog
->dip_headline1
, XtNwidth
, &width
, NULL
);
601 XtVaSetValues(pdialog
->dip_view
, XtNwidth
, width
, NULL
);
602 XtVaSetValues(pdialog
->dip_clauselist
, XtNwidth
, width
, NULL
);
604 fc_snprintf(buf
, sizeof(buf
), _("%s view:"),
605 nation_adjective_for_player(plr0
));
606 pdialog
->dip_acceptlabel0
=XtVaCreateManagedWidget("dipacceptlabel0",
611 pdialog
->dip_acceptthumb0
=XtVaCreateManagedWidget("dipacceptthumb0",
614 XtNbitmap
, get_thumb_pixmap(0),
616 fc_snprintf(buf
, sizeof(buf
), _("%s view:"),
617 nation_adjective_for_player(plr1
));
618 pdialog
->dip_acceptlabel1
=XtVaCreateManagedWidget("dipacceptlabel1",
623 pdialog
->dip_acceptthumb1
=XtVaCreateManagedWidget("dipacceptthumb1",
629 pdialog
->dip_erase_clause_command
=
630 I_L(XtVaCreateManagedWidget("diperaseclausecommand",
632 pdialog
->dip_main_form
,
635 pdialog
->dip_accept_command
=
636 I_L(XtVaCreateManagedWidget("dipacceptcommand",
641 pdialog
->dip_close_command
=
642 I_L(XtVaCreateManagedWidget("dipclosecommand",
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
);
655 XtRealizeWidget(pdialog
->dip_dialog_shell
);
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
);
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
);
673 XtVaGetValues(pdialog
->dip_formm
, XtNheight
, &height
, NULL
);
674 XtVaSetValues(pdialog
->dip_form0
, XtNheight
, height
, NULL
);
675 XtVaSetValues(pdialog
->dip_form1
, XtNheight
, height
, NULL
);
680 update_diplomacy_dialog(pdialog
);
686 /**************************************************************************
688 **************************************************************************/
689 void update_diplomacy_dialog(struct Diplomacy_dialog
*pdialog
)
692 const int n
= sizeof(pdialog
->clauselist_strings
[0]);
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
];
698 } clause_list_iterate_end
;
700 pdialog
->clauselist_strings_ptrs
[i
]=0;
701 XawListChange(pdialog
->dip_clauselist
, pdialog
->clauselist_strings_ptrs
,
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
);
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
));
715 /****************************************************************
716 Callback for trading techs
717 *****************************************************************/
718 void diplomacy_dialog_tech_callback(Widget w
, XtPointer client_data
,
721 size_t choice
= (size_t) client_data
;
722 int giver
= (choice
>> 24) & 0xff, dest
= (choice
>> 16) & 0xff, other
;
723 int tech
= choice
& 0xffff;
725 if (player_by_number(giver
) == client
.conn
.playing
) {
731 dsend_packet_diplomacy_create_clause_req(&client
.conn
, other
, giver
,
732 CLAUSE_ADVANCE
, tech
);
735 /****************************************************************
736 Callback for trading cities
738 *****************************************************************/
739 void diplomacy_dialog_city_callback(Widget w
, XtPointer client_data
,
742 size_t choice
= (size_t) client_data
;
743 int giver
= (choice
>> 24) & 0xff, dest
= (choice
>> 16) & 0xff, other
;
744 int city
= choice
& 0xffff;
746 if (player_by_number(giver
) == client
.conn
.playing
) {
752 dsend_packet_diplomacy_create_clause_req(&client
.conn
, other
, giver
,
756 /****************************************************************
758 *****************************************************************/
759 void diplomacy_dialog_erase_clause_callback(Widget w
, XtPointer client_data
,
762 struct Diplomacy_dialog
*pdialog
= (struct Diplomacy_dialog
*) client_data
;
763 XawListReturnStruct
*ret
= XawListShowCurrent(pdialog
->dip_clauselist
);
765 if (ret
->list_index
!= XAW_LIST_NONE
) {
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
),
778 } clause_list_iterate_end
;
782 /****************************************************************
783 Callback for trading map
784 *****************************************************************/
785 void diplomacy_dialog_map_callback(Widget w
, XtPointer client_data
,
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
->
794 dsend_packet_diplomacy_create_clause_req(&client
.conn
,
795 player_number(pdialog
->treaty
.plr1
),
796 player_number(pgiver
), CLAUSE_MAP
, 0);
799 /****************************************************************
800 Callback for trading seamap
801 *****************************************************************/
802 void diplomacy_dialog_seamap_callback(Widget w
, XtPointer client_data
,
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
->
811 dsend_packet_diplomacy_create_clause_req(&client
.conn
,
812 player_number(pdialog
->treaty
.plr1
),
813 player_number(pgiver
), CLAUSE_SEAMAP
,
817 /****************************************************************
819 *****************************************************************/
820 void diplomacy_dialog_vision_callback(Widget w
, XtPointer client_data
,
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
;
827 dsend_packet_diplomacy_create_clause_req(&client
.conn
,
828 player_number(pdialog
->treaty
.plr1
),
829 player_number(pgiver
), CLAUSE_VISION
,
833 /****************************************************************
834 Generic add-a-clause function for adding pact types
835 *****************************************************************/
836 static void diplomacy_dialog_add_pact_clause(Widget w
, XtPointer client_data
,
837 XtPointer call_data
, int type
)
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
;
843 dsend_packet_diplomacy_create_clause_req(&client
.conn
,
844 player_number(pdialog
->treaty
.plr1
),
845 player_number(pgiver
), type
, 0);
848 /****************************************************************
849 The cease-fire widget was selected; add a cease-fire to the
851 *****************************************************************/
852 void diplomacy_dialog_ceasefire_callback(Widget w
, XtPointer client_data
,
855 diplomacy_dialog_add_pact_clause(w
, client_data
, call_data
,
859 /****************************************************************
860 The peace widget was selected; add a peace treaty to the
862 *****************************************************************/
863 void diplomacy_dialog_peace_callback(Widget w
, XtPointer client_data
,
866 diplomacy_dialog_add_pact_clause(w
, client_data
, call_data
,
870 /****************************************************************
871 The alliance widget was selected; add an alliance to the
873 *****************************************************************/
874 void diplomacy_dialog_alliance_callback(Widget w
, XtPointer client_data
,
877 diplomacy_dialog_add_pact_clause(w
, client_data
, call_data
,
882 /****************************************************************
884 *****************************************************************/
885 void diplomacy_dialog_close_callback(Widget w
, XtPointer client_data
,
888 struct Diplomacy_dialog
*pdialog
= (struct Diplomacy_dialog
*) client_data
;
890 dsend_packet_diplomacy_cancel_meeting_req(&client
.conn
,
891 player_number(pdialog
->treaty
.plr1
));
892 close_diplomacy_dialog(pdialog
);
896 /****************************************************************
898 *****************************************************************/
899 void diplomacy_dialog_accept_callback(Widget w
, XtPointer client_data
,
902 struct Diplomacy_dialog
*pdialog
= (struct Diplomacy_dialog
*) client_data
;
904 dsend_packet_diplomacy_accept_treaty_req(&client
.conn
,
905 player_number(pdialog
->treaty
.plr1
));
909 /*****************************************************************
911 *****************************************************************/
912 void close_diplomacy_dialog(struct Diplomacy_dialog
*pdialog
)
914 XtDestroyWidget(pdialog
->dip_dialog_shell
);
916 dialog_list_remove(dialog_list
, pdialog
);
920 /*****************************************************************
922 *****************************************************************/
923 static struct Diplomacy_dialog
*find_diplomacy_dialog(int other_player_id
)
925 struct player
*plr0
= client
.conn
.playing
;
926 struct player
*plr1
= player_by_number(other_player_id
);
928 if (!dialog_list_list_has_been_initialised
) {
929 dialog_list
= dialog_list_new();
930 dialog_list_list_has_been_initialised
= TRUE
;
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
)) {
938 } dialog_list_iterate_end
;
943 /*****************************************************************
945 *****************************************************************/
946 static struct Diplomacy_dialog
*find_diplomacy_by_input(Widget w
)
948 dialog_list_iterate(dialog_list
, pdialog
) {
949 if ((pdialog
->dip_gold_input0
== w
) || (pdialog
->dip_gold_input1
== w
)) {
952 } dialog_list_iterate_end
;
957 /*****************************************************************
959 *****************************************************************/
960 void diplodlg_key_gold(Widget w
)
962 struct Diplomacy_dialog
*pdialog
= find_diplomacy_by_input(w
);
965 struct player
*pgiver
= (w
== pdialog
->dip_gold_input0
) ?
966 pdialog
->treaty
.plr0
: pdialog
->treaty
.plr1
;
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
);
979 output_window_append(ftc_client
,
980 _("Invalid amount of gold specified."));
985 /*****************************************************************
986 Close all dialogs, for when client disconnects from game.
987 *****************************************************************/
988 void close_all_diplomacy_dialogs(void)
990 if (!dialog_list_list_has_been_initialised
) {
994 while (dialog_list_size(dialog_list
) > 0) {
995 close_diplomacy_dialog(dialog_list_get(dialog_list
, 0));