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 
24 #include <X11/Xaw/Scrollbar.h>
25 #include <X11/Xaw/Form.h>
26 #include <X11/Xaw/Label.h>
27 #include <X11/Xaw/SimpleMenu.h>
28 #include <X11/Xaw/Command.h>
29 #include <X11/Xaw/AsciiText.h>
30 #include <X11/Xaw/SmeBSB.h>
31 #include <X11/Xaw/SmeLine.h>
32 
33 /* common & utility */
34 #include "climap.h"
35 #include "fcintl.h"
36 #include "game.h"
37 #include "map.h"
38 #include "city.h"
39 #include "player.h"
40 #include "support.h"
41 #include "unit.h"
42 
43 /* client */
44 #include "chatline.h"
45 #include "citydlg.h"
46 #include "client_main.h"
47 #include "colors.h"
48 #include "control.h"
49 #include "dialogs.h"
50 #include "goto.h"
51 #include "graphics.h"
52 #include "gui_main.h"
53 #include "gui_stuff.h"
54 #include "inputdlg.h"
55 #include "mapview.h"
56 #include "menu.h"
57 #include "overview_common.h"
58 #include "text.h"
59 #include "tilespec.h"
60 
61 #include "mapctrl.h"
62 
63 static void popupinfo_popdown_callback(Widget w, XtPointer client_data, XtPointer call_data);
64 
65 /**************************************************************************
66 ...
67 **************************************************************************/
name_new_city_callback(Widget w,XtPointer client_data,XtPointer call_data)68 static void name_new_city_callback(Widget w, XtPointer client_data,
69 				   XtPointer call_data)
70 {
71   int idx = XTPOINTER_TO_INT(client_data);
72 
73   if (idx < 0) {
74     cancel_city(index_to_tile(-idx-1));
75   } else {
76     finish_city(index_to_tile(idx), input_dialog_get_input(w));
77   }
78 
79   input_dialog_destroy(w);
80 }
81 
82 /**************************************************************************
83  Popup dialog where the user choose the name of the new city
84  punit = (settler) unit which builds the city
85  suggestname = suggetion of the new city's name
86 **************************************************************************/
popup_newcity_dialog(struct unit * punit,const char * suggestname)87 void popup_newcity_dialog(struct unit *punit, const char *suggestname)
88 {
89   input_dialog_create(toplevel, "shellnewcityname",
90 		      _("What should we call our new city?"), suggestname,
91 		      name_new_city_callback,
92                       INT_TO_XTPOINTER(tile_index(unit_tile(punit))),
93                       name_new_city_callback,
94                       INT_TO_XTPOINTER(-tile_index(unit_tile(punit)) - 1));
95 }
96 
97 /**************************************************************************
98 ...
99 **************************************************************************/
popit(int xin,int yin,struct tile * ptile)100 static void popit(int xin, int yin, struct tile *ptile)
101 {
102   Position x, y;
103   int dw, dh;
104   Dimension w, h, b;
105   static struct tile *cross_list[2+1];
106   struct tile **cross_head = cross_list;
107   int i;
108   struct unit *punit;
109   char *content;
110   static bool is_orders;
111 
112   if (TILE_UNKNOWN != client_tile_get_known(ptile)) {
113     Widget p=XtCreatePopupShell("popupinfo", simpleMenuWidgetClass,
114 				map_canvas, NULL, 0);
115     content = (char *) popup_info_text(ptile);
116     /* content is provided to us as a single string with multiple lines,
117        but xaw doens't support multi-line labels.  So we break it up.
118        We mangle it in the process, but who cares?  It's never going to be
119        used again anyway. */
120     while (1) {
121       char *end = strchr(content, '\n');
122       if (end) {
123 	*end='\0';
124       }
125       XtCreateManagedWidget(content, smeBSBObjectClass, p, NULL, 0);
126       if (end) {
127 	content = end+1;
128       } else {
129 	break;
130       }
131     }
132 
133     punit = find_visible_unit(ptile);
134     is_orders = show_unit_orders(punit);
135     if (punit && punit->goto_tile) {
136       *cross_head = punit->goto_tile;
137       cross_head++;
138     }
139     *cross_head = ptile;
140     cross_head++;
141 
142     xin /= tileset_tile_width(tileset);
143     xin *= tileset_tile_width(tileset);
144     yin /= tileset_tile_height(tileset);
145     yin *= tileset_tile_height(tileset);
146     xin += (tileset_tile_width(tileset) / 2);
147     XtTranslateCoords(map_canvas, xin, yin, &x, &y);
148     dw = XDisplayWidth (display, screen_number);
149     dh = XDisplayHeight (display, screen_number);
150     XtRealizeWidget(p);
151     XtVaGetValues(p, XtNwidth, &w, XtNheight, &h, XtNborderWidth, &b, NULL);
152     w += (2 * b);
153     h += (2 * b);
154     x -= (w / 2);
155     y -= h;
156     if ((x + w) > dw) x = dw - w;
157     if (x < 0) x = 0;
158     if ((y + h) > dh) y = dh - h;
159     if (y < 0) y = 0;
160     XtVaSetValues(p, XtNx, x, XtNy, y, NULL);
161 
162     *cross_head = NULL;
163     for (i = 0; cross_list[i]; i++) {
164       put_cross_overlay_tile(cross_list[i]);
165     }
166     XtAddCallback(p,XtNpopdownCallback,popupinfo_popdown_callback,
167 		  (XtPointer)&is_orders);
168 
169     XtPopupSpringLoaded(p);
170   }
171 
172 }
173 
174 /**************************************************************************
175 ...
176 **************************************************************************/
popupinfo_popdown_callback(Widget w,XtPointer client_data,XtPointer call_data)177 void popupinfo_popdown_callback(Widget w, XtPointer client_data,
178         XtPointer call_data)
179 {
180   bool *full = client_data;
181 
182   if (*full) {
183     update_map_canvas_visible();
184   } else {
185     dirty_all();
186   }
187 
188   XtDestroyWidget(w);
189 }
190 
191 /**************************************************************************
192 (RP:) wake up my own sentried units on the tile that was clicked
193 **************************************************************************/
mapctrl_btn_wakeup(XEvent * event)194 void mapctrl_btn_wakeup(XEvent *event)
195 {
196   wakeup_button_pressed(event->xbutton.x, event->xbutton.y);
197 }
198 
199 /**************************************************************************
200 ...
201 **************************************************************************/
mapctrl_btn_mapcanvas(XEvent * event)202 void mapctrl_btn_mapcanvas(XEvent *event)
203 {
204   XButtonEvent *ev=&event->xbutton;
205   struct tile *ptile = canvas_pos_to_tile(ev->x, ev->y);
206 
207   if (!can_client_change_view()) {
208     return;
209   }
210 
211   if (ev->button == Button1 && (ev->state & ControlMask)) {
212     action_button_pressed(ev->x, ev->y, SELECT_SEA);
213   } else if (ev->button == Button1) {
214     action_button_pressed(ev->x, ev->y, SELECT_POPUP);
215   } else if (ev->button == Button2 && ptile) {
216     popit(ev->x, ev->y, ptile);
217   } else if (ev->button == Button3 && (ev->state & ControlMask)) {
218     action_button_pressed(ev->x, ev->y, SELECT_LAND);
219   } else if (ev->button == Button3) {
220     recenter_button_pressed(ev->x, ev->y);
221   }
222 }
223 
224 /**************************************************************************
225   Update goto line so that destination is at current mouse pointer location.
226 **************************************************************************/
create_line_at_mouse_pos(void)227 void create_line_at_mouse_pos(void)
228 {
229   Bool on_same_screen;
230   Window root, child;
231   int rx, ry, x, y;
232   unsigned int mask;
233 
234   on_same_screen =
235     XQueryPointer(display, XtWindow(map_canvas),
236                   &root, &child,
237                   &rx, &ry,
238                   &x, &y,
239                   &mask);
240 
241   if (on_same_screen) {
242     update_line(x, y);
243   }
244 }
245 
246 /**************************************************************************
247  The Area Selection rectangle. Called by center_tile_mapcanvas() and
248  when the mouse pointer moves.
249 **************************************************************************/
update_rect_at_mouse_pos(void)250 void update_rect_at_mouse_pos(void)
251 {
252   /* PORTME */
253 }
254 
255 /**************************************************************************
256   Draws the on the map the tiles the given city is using
257 **************************************************************************/
mapctrl_key_city_workers(XEvent * event)258 void mapctrl_key_city_workers(XEvent *event)
259 {
260   key_city_overlay(event->xbutton.x, event->xbutton.y);
261 }
262 
263 /**************************************************************************
264 ...
265 **************************************************************************/
mapctrl_btn_overviewcanvas(XEvent * event)266 void mapctrl_btn_overviewcanvas(XEvent *event)
267 {
268   int map_x, map_y;
269   struct tile *ptile;
270   XButtonEvent *ev = &event->xbutton;
271 
272   if (!can_client_change_view()) {
273     return;
274   }
275 
276   overview_to_map_pos(&map_x, &map_y, event->xbutton.x, event->xbutton.y);
277   ptile = map_pos_to_tile(map_x, map_y);
278   if (!ptile) {
279     return;
280   }
281 
282   if(ev->button==Button1)
283     do_map_click(ptile, SELECT_POPUP);
284   else if(ev->button==Button3)
285     center_tile_mapcanvas(ptile);
286 }
287 
288 /**************************************************************************
289 ...
290 **************************************************************************/
center_on_unit(void)291 void center_on_unit(void)
292 {
293   request_center_focus_unit();
294 }
295 
296 /**************************************************************************
297  Enable or disable the turn done button.
298  Should probably some where else.
299 **************************************************************************/
set_turn_done_button_state(bool state)300 void set_turn_done_button_state(bool state)
301 {
302   XtSetSensitive(turn_done_button, state);
303 }
304