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 #include <X11/Xaw/Viewport.h>
29 #include <X11/Xaw/AsciiText.h>
30 #include <X11/IntrinsicP.h>
31
32 #include "canvas.h"
33 #include "pixcomm.h"
34
35 /* utility */
36 #include "fcintl.h"
37 #include "log.h"
38 #include "mem.h"
39 #include "shared.h"
40 #include "support.h"
41
42 /* common */
43 #include "game.h"
44 #include "map.h"
45 #include "packets.h"
46 #include "player.h"
47 #include "spaceship.h"
48 #include "victory.h"
49
50 /* client */
51 #include "client_main.h"
52 #include "climisc.h"
53 #include "colors.h"
54 #include "dialogs.h"
55 #include "graphics.h"
56 #include "gui_main.h"
57 #include "gui_stuff.h"
58 #include "helpdlg.h"
59 #include "inputdlg.h"
60 #include "mapctrl.h"
61 #include "mapview.h"
62 #include "repodlgs.h"
63 #include "text.h"
64 #include "tilespec.h"
65
66 #include "spaceshipdlg.h"
67
68 struct spaceship_dialog {
69 struct player *pplayer;
70 Widget shell;
71 Widget main_form;
72 Widget player_label;
73 Widget info_label;
74 Widget image_canvas;
75 Widget launch_command;
76 Widget close_command;
77 };
78
79 #define SPECLIST_TAG dialog
80 #define SPECLIST_TYPE struct spaceship_dialog
81 #include "speclist.h"
82
83 #define dialog_list_iterate(dialoglist, pdialog) \
84 TYPED_LIST_ITERATE(struct spaceship_dialog, dialoglist, pdialog)
85 #define dialog_list_iterate_end LIST_ITERATE_END
86
87 static struct dialog_list *dialog_list = NULL;
88 static bool dialog_list_has_been_initialised = FALSE;
89
90 struct spaceship_dialog *get_spaceship_dialog(struct player *pplayer);
91 struct spaceship_dialog *create_spaceship_dialog(struct player *pplayer);
92 void close_spaceship_dialog(struct spaceship_dialog *pdialog);
93
94 void spaceship_dialog_update_image(struct spaceship_dialog *pdialog);
95 void spaceship_dialog_update_info(struct spaceship_dialog *pdialog);
96
97 void spaceship_close_callback(Widget w, XtPointer client_data, XtPointer call_data);
98 void spaceship_launch_callback(Widget w, XtPointer client_data, XtPointer call_data);
99
100 /****************************************************************
101 ...
102 *****************************************************************/
get_spaceship_dialog(struct player * pplayer)103 struct spaceship_dialog *get_spaceship_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 Refresh (update) the spaceship dialog for the given player.
121 *****************************************************************/
refresh_spaceship_dialog(struct player * pplayer)122 void refresh_spaceship_dialog(struct player *pplayer)
123 {
124 struct spaceship_dialog *pdialog;
125 struct player_spaceship *pship;
126
127 if (!(pdialog = get_spaceship_dialog(pplayer))) {
128 return;
129 }
130
131 pship = &(pdialog->pplayer->spaceship);
132
133 if (victory_enabled(VC_SPACERACE)
134 && pplayer == client.conn.playing
135 && pship->state == SSHIP_STARTED
136 && pship->success_rate > 0) {
137 XtSetSensitive(pdialog->launch_command, TRUE);
138 } else {
139 XtSetSensitive(pdialog->launch_command, FALSE);
140 }
141
142 spaceship_dialog_update_info(pdialog);
143 spaceship_dialog_update_image(pdialog);
144 }
145
146 /****************************************************************
147 popup the dialog 10% inside the main-window
148 *****************************************************************/
popup_spaceship_dialog(struct player * pplayer)149 void popup_spaceship_dialog(struct player *pplayer)
150 {
151 struct spaceship_dialog *pdialog;
152
153 if(!(pdialog=get_spaceship_dialog(pplayer)))
154 pdialog=create_spaceship_dialog(pplayer);
155
156 xaw_set_relative_position(toplevel, pdialog->shell, 10, 10);
157 XtPopup(pdialog->shell, XtGrabNone);
158 }
159
160 /****************************************************************
161 popdown the dialog
162 *****************************************************************/
popdown_spaceship_dialog(struct player * pplayer)163 void popdown_spaceship_dialog(struct player *pplayer)
164 {
165 struct spaceship_dialog *pdialog;
166
167 if((pdialog=get_spaceship_dialog(pplayer)))
168 close_spaceship_dialog(pdialog);
169 }
170
171
172
173 /****************************************************************
174 ...
175 *****************************************************************/
spaceship_image_canvas_expose(Widget w,XEvent * event,Region exposed,void * client_data)176 static void spaceship_image_canvas_expose(Widget w, XEvent *event,
177 Region exposed, void *client_data)
178 {
179 struct spaceship_dialog *pdialog;
180
181 pdialog=(struct spaceship_dialog *)client_data;
182 spaceship_dialog_update_image(pdialog);
183 }
184
185
186 /****************************************************************
187 ...
188 *****************************************************************/
create_spaceship_dialog(struct player * pplayer)189 struct spaceship_dialog *create_spaceship_dialog(struct player *pplayer)
190 {
191 struct spaceship_dialog *pdialog;
192 int ss_w, ss_h;
193
194 pdialog=fc_malloc(sizeof(struct spaceship_dialog));
195 pdialog->pplayer=pplayer;
196
197 pdialog->shell=XtVaCreatePopupShell(player_name(pplayer),
198 topLevelShellWidgetClass,
199 toplevel,
200 XtNallowShellResize, True,
201 NULL);
202
203 pdialog->main_form=
204 XtVaCreateManagedWidget("spaceshipmainform",
205 formWidgetClass,
206 pdialog->shell,
207 NULL);
208 pdialog->player_label=
209 XtVaCreateManagedWidget("spaceshipplayerlabel",
210 labelWidgetClass,
211 pdialog->main_form,
212 NULL);
213
214 XtVaSetValues(pdialog->player_label, XtNlabel, (XtArgVal)player_name(pplayer), NULL);
215
216 get_spaceship_dimensions(&ss_w, &ss_h);
217 pdialog->image_canvas=
218 XtVaCreateManagedWidget("spaceshipimagecanvas",
219 xfwfcanvasWidgetClass,
220 pdialog->main_form,
221 "exposeProc", (XtArgVal)spaceship_image_canvas_expose,
222 "exposeProcData", (XtArgVal)pdialog,
223 XtNwidth, ss_w,
224 XtNheight, ss_h,
225 NULL);
226
227 pdialog->info_label=
228 XtVaCreateManagedWidget("spaceshipinfolabel",
229 labelWidgetClass,
230 pdialog->main_form,
231 NULL);
232
233
234 pdialog->close_command=
235 I_L(XtVaCreateManagedWidget("spaceshipclosecommand", commandWidgetClass,
236 pdialog->main_form, NULL));
237
238 pdialog->launch_command=
239 I_L(XtVaCreateManagedWidget("spaceshiplaunchcommand", commandWidgetClass,
240 pdialog->main_form, NULL));
241
242 XtAddCallback(pdialog->launch_command, XtNcallback, spaceship_launch_callback,
243 (XtPointer)pdialog);
244
245 XtAddCallback(pdialog->close_command, XtNcallback, spaceship_close_callback,
246 (XtPointer)pdialog);
247
248 dialog_list_prepend(dialog_list, pdialog);
249
250 XtRealizeWidget(pdialog->shell);
251
252 refresh_spaceship_dialog(pdialog->pplayer);
253
254 XSetWMProtocols(display, XtWindow(pdialog->shell), &wm_delete_window, 1);
255 XtOverrideTranslations(pdialog->shell,
256 XtParseTranslationTable ("<Message>WM_PROTOCOLS: msg-close-spaceship()"));
257
258 XtSetKeyboardFocus(pdialog->shell, pdialog->close_command);
259
260 return pdialog;
261 }
262
263 /****************************************************************
264 ...
265 *****************************************************************/
spaceship_dialog_update_info(struct spaceship_dialog * pdialog)266 void spaceship_dialog_update_info(struct spaceship_dialog *pdialog)
267 {
268 xaw_set_label(pdialog->info_label,
269 get_spaceship_descr(&pdialog->pplayer->spaceship));
270 }
271
272 /****************************************************************
273 ...
274 Should also check connectedness, and show non-connected
275 parts differently.
276 *****************************************************************/
spaceship_dialog_update_image(struct spaceship_dialog * pdialog)277 void spaceship_dialog_update_image(struct spaceship_dialog *pdialog)
278 {
279 struct canvas canvas = {.pixmap = XtWindow(pdialog->image_canvas)};
280
281 put_spaceship(&canvas, 0, 0, pdialog->pplayer);
282 }
283
284
285 /****************************************************************
286 ...
287 *****************************************************************/
close_spaceship_dialog(struct spaceship_dialog * pdialog)288 void close_spaceship_dialog(struct spaceship_dialog *pdialog)
289 {
290 XtDestroyWidget(pdialog->shell);
291 dialog_list_remove(dialog_list, pdialog);
292
293 free(pdialog);
294 }
295
296 /****************************************************************
297 ...
298 *****************************************************************/
spaceshipdlg_key_close(Widget w)299 void spaceshipdlg_key_close(Widget w)
300 {
301 spaceshipdlg_msg_close(XtParent(XtParent(w)));
302 }
303
304 /****************************************************************
305 ...
306 *****************************************************************/
spaceshipdlg_msg_close(Widget w)307 void spaceshipdlg_msg_close(Widget w)
308 {
309 dialog_list_iterate(dialog_list, pdialog) {
310 if (pdialog->shell == w) {
311 close_spaceship_dialog(pdialog);
312 return;
313 }
314 } dialog_list_iterate_end;
315 }
316
317
318 /****************************************************************
319 ...
320 *****************************************************************/
spaceship_close_callback(Widget w,XtPointer client_data,XtPointer call_data)321 void spaceship_close_callback(Widget w, XtPointer client_data, XtPointer call_data)
322 {
323 close_spaceship_dialog((struct spaceship_dialog *)client_data);
324 }
325
326
327 /****************************************************************
328 ...
329 *****************************************************************/
spaceship_launch_callback(Widget w,XtPointer client_data,XtPointer call_data)330 void spaceship_launch_callback(Widget w, XtPointer client_data,
331 XtPointer call_data)
332 {
333 send_packet_spaceship_launch(&client.conn);
334 /* close_spaceship_dialog((struct spaceship_dialog *)client_data); */
335 }
336