1 #include "xrisk.h"
2 #include "xriskex.h"
3 #include "risklibex.h"
4 #include "xrisklibex.h"
5 #include "cursors.h"
6 #include "cardex.h"
7 #include "actions_menu_but.h"
8 #include "fontsex.h"
9 
10 /* Initialze place-armies */
p_a_where_init(player)11 int p_a_where_init(player)
12      playerp player;
13 {
14   if (player->num_cards >= 5)
15     {
16       write_msg_arg(player, "#060_You have %d cards and have to exchange !!",
17 		    player->num_cards,LAST_ARG);
18       return(0);
19     }
20 
21   if (player->pstat->armies_left >= 2) write_msg_arg
22     (player,"#058_You have %d armies left to place",
23      player->pstat->armies_left,LAST_ARG);
24   else write_msg(player,"#062_You have 1 army left to place");
25 
26   return(0);
27 }
28 
29 /* Written when your not in turn */
wait_msg(player)30 int wait_msg(player)
31      playerp player;
32 {
33   write_msg(player,"#066_Wait for your turn");
34   return(0);
35 }
36 
37 /* What to do when a player press left button in the scroll-window */
scroll_func(player)38 int scroll_func(player)
39      playerp player;
40 {
41   if (player->state->all_actions->next_state != DUMMY_FUNC)
42     new_state(player,player->state->all_actions->next_state);
43   return(0);
44 }
45 
46 /* Return 0 */
none(player)47 int none(player)
48      playerp player;
49 {
50   return(0);
51 }
52 
53 /* Just testing */
test(player)54 int test(player)
55      playerp player;
56 {
57   return(0);
58 }
59 
60 /* Jump to next function */
next(player)61 int next(player)
62      playerp player;
63 {
64   return(1);
65 }
66 
67 /* Initialize find attacking land */
f_a_where_init(player)68 int f_a_where_init(player)
69      playerp player;
70 {
71   write_msg(player,"#025_Choose a country from which to attack");
72   return(0);
73 }
74 
75 /* We have allready allocated player, defined states
76    and distributed countries */
init_player(player)77 int init_player(player)
78      playerp player;
79 {
80   int t;
81 
82   for(t=0;t<MAX_PLAYERS;t++) player->colors[t] = &colors[t];
83 
84   player->card[0]             = NULL;
85   player->offensiv            = 0;
86   player->pstat               = (pstatp)malloc(sizeof(struct PStat));
87   player->pstat->spec_win     = (Window)NULL;
88   player->pstat->country      = (countryp)NULL;
89   player->pstat->return_state = NUM_STATES;
90   player->pstat->exit_press   = 0;
91   *(player->pstat->string[1]  = (char *)malloc(MAXLEN_MISC+1)) = 0;
92   *(player->pstat->string[2]  = (char *)malloc(MAXLEN_MISC+1)) = 0;
93   player->attr.attr_game      = 0;
94   player->attr.attack_armies  = 3;
95   return(1);
96 }
97 
98 /* Initialize mapwindow */
init_mapwin(player)99 int init_mapwin(player)
100      playerp player;
101 {
102   int            t,bwidth=2;
103   xconp          xinfo;
104   XSizeHints     s_h;
105   XGCValues      values;
106   XVisualInfo    vinfo_return;
107   char          *win_name,*name;
108   char          *mmap;
109 
110   xinfo = (xconp)malloc(sizeof(struct Xcon));
111   if (!(xinfo->disp=XOpenDisplay(player->client)))
112     risk_exit("Could not open display %s\n",player->client,LAST_ARG);
113   player->xcon                     = xinfo;
114   xinfo->scr                       = DefaultScreen(xinfo->disp);
115   xinfo->depth                     = DefaultDepth(xinfo->disp,xinfo->scr);
116   xinfo->root                      = RootWindow(xinfo->disp,xinfo->scr);
117   xinfo->screen                    = XScreenOfDisplay(xinfo->disp,xinfo->scr);
118   xinfo->cmap                      = DefaultColormapOfScreen(xinfo->screen);
119   xinfo->attr.backing_store        = Always;
120   xinfo->attr.event_mask           = ButtonPressMask|KeyPressMask;
121   xinfo->attrmask                  = CWBackingStore|CWEventMask;
122   xinfo->indexs                    = player->indexs;
123   xinfo->gc                        = DefaultGC(xinfo->disp,xinfo->scr);
124   values.subwindow_mode = ClipByChildren;
125   values.line_style     = LineSolid;
126   values.line_width     = 1;
127   values.fill_style     = FillSolid;
128   XChangeGC(xinfo->disp, xinfo->gc,
129 	    GCSubwindowMode|GCLineStyle|GCLineWidth|GCFillStyle, &values);
130 
131 
132   xinfo->visual = XDefaultVisual(xinfo->disp,xinfo->scr);
133   if (xinfo->depth < 6 || !XMatchVisualInfo
134       (xinfo->disp, xinfo->scr, xinfo->depth, PseudoColor, &vinfo_return))
135     {
136       xinfo->depth=32;
137       do xinfo->depth--;
138       while(xinfo->depth && !XMatchVisualInfo
139 	    (xinfo->disp,xinfo->scr,xinfo->depth,PseudoColor,&vinfo_return));
140     }
141 
142   xinfo->visual = vinfo_return.visual;
143   if (xinfo->depth < 6) risk_exit
144     ("Could not get more than %d bitplanes on client %s, need 6\n"
145      ,xinfo->depth, player->client);
146 
147   if (!DoesBackingStore(xinfo->screen)) xinfo->attr.event_mask |= ExposureMask;
148   assign_font(player);
149 
150   for(t=0;t<NUMB_CURSORS;t++)
151     {
152       if (cursor_table[t].index != t) risk_exit
153 	("Mistake in cursor_table[%d] in functions.h",t);
154       xinfo->cursors[t] = XCreateFontCursor(xinfo->disp,cursor_table[t].shape);
155     }
156   mmap     = (char *)malloc(XSIZE*YSIZE*sizeof(char));
157   win_name = (char*)(malloc(MAXLEN_MISC+1));
158   name     = (char*)(malloc(MAXLEN_NMISC+1));
159   gethostname(name,MAXLEN_NMISC);
160   sprintf(win_name,"%s @ %s",mappet(WINNAME),name);
161 
162   s_h.x          = 0;
163   s_h.y          = 0;
164   s_h.width      = XSIZE;
165   s_h.height     = YSIZE;
166   s_h.max_width  = XSIZE;
167   s_h.max_height = YSIZE;
168   s_h.min_width  = XSIZE;
169   s_h.min_height = YSIZE;
170   s_h.flags      = PSize|PMinSize|PMaxSize;
171 
172   xinfo = player->xcon;
173 
174   xinfo->win = XCreateWindow
175     (xinfo->disp,xinfo->root,s_h.x,s_h.y,s_h.width,s_h.height,bwidth,
176      xinfo->depth,InputOutput,xinfo->visual,
177      xinfo->attrmask,&(xinfo->attr));
178 
179   XSetStandardProperties
180     (xinfo->disp,xinfo->win,win_name,win_name,None,NULL,0,&s_h);
181 
182   /* Allocat colormap */
183 
184   if (!XAllocColorCells
185       (xinfo->disp,xinfo->cmap,False,0,0,xinfo->pixm,NUM_COLORS))
186     {
187       xinfo->cmap = XCreateColormap
188 	(xinfo->disp,xinfo->win,xinfo->visual,AllocNone);
189       if (!XAllocColorCells
190 	  (xinfo->disp,xinfo->cmap,False,0,0,xinfo->pixm,NUM_COLORS)) risk_exit
191 	    ("Do not know how to allocate colors on client %s\n",player->client);
192     }
193   XSetWindowColormap(xinfo->disp,xinfo->win,xinfo->cmap);
194   update_colors(player);
195   XSetBackground(xinfo->disp,xinfo->gc,xinfo->black);
196   for(t=0;t<YSIZE*XSIZE;t++) mmap[t]=xinfo->pixm[(int)map[t]];
197 
198   xinfo->ximage = XCreateImage(xinfo->disp,xinfo->visual,xinfo->depth,
199 			       ZPixmap,0,mmap,XSIZE,YSIZE,32,0);
200   for(t=0;t<MENU_NUMB;t++)
201     {
202       xinfo->menu_butt[t] = XCreateSimpleWindow
203 	(xinfo->disp,xinfo->win,(t/3)*MENU_B,(t%3)*MENU_H,
204 	 MENU_B-2,MENU_H-2,2,xinfo->white,xinfo->black);
205       XSelectInput(xinfo->disp,xinfo->menu_butt[t],xinfo->attr.event_mask);
206       XChangeWindowAttributes
207 	(xinfo->disp,xinfo->menu_butt[t],CWBackingStore,&(xinfo->attr));
208       if (actions_menu_but[t].index != t) risk_exit
209 	("Wrong index in actions_menu_but[%d] in file actions_menu_but.h\n",t);
210       do_action(player,&(actions_menu_but[t].button_actions.action_mB2));
211     }
212   xinfo->scrollwin = XCreateSimpleWindow
213     (xinfo->disp,xinfo->win,SCWINX,SCWINY,SCWINL,SCWINH,SCWINR,
214      xinfo->white,xinfo->black);
215   XChangeWindowAttributes
216     (xinfo->disp,xinfo->scrollwin,CWBackingStore,&(xinfo->attr));
217   XSelectInput(xinfo->disp,xinfo->scrollwin,xinfo->attr.event_mask);
218   return(1);
219 }
220 
221 /* Set up the mapwindow on the screen */
set_up_mapwin(player)222 int set_up_mapwin(player)
223      playerp player;
224 {
225   xconp xinfo;
226   int   t;
227 
228   xinfo = player->xcon;
229   XMapWindow(xinfo->disp,xinfo->win);
230   XMapWindow(xinfo->disp,xinfo->scrollwin);
231   for(t=0;t<MENU_NUMB;t++) XMapWindow(xinfo->disp,xinfo->menu_butt[t]);
232   update_mapwin(player);
233   XFlush(xinfo->disp);
234   return(1);
235 }
236 
237 /* We only have to create some images once */
start_unit_image(player)238 void start_unit_image(player)
239      playerp player;
240 {
241   char      *temp,*temp1;
242   xconp      xinfo;
243   card_winp  cardwin;
244   int        t,t1;
245 
246   xinfo   = player->xcon;
247   cardwin = player->card_win;
248 
249   /* Pictures representing 3 units are read */
250   for(t1=0;t1<3;t1++)
251     {
252       temp1 = unitp[t1];
253       temp  = (char *)malloc(UNITX*UNITY);
254 
255       for(t=0;t<UNITX*UNITY;t++)
256         if (temp1[t]) temp[t] = (xinfo->white & 255);
257         else          temp[t] = (xinfo->black & 255);
258 
259       cardwin->aimage[t1]=XCreateImage(xinfo->disp,xinfo->visual,xinfo->depth,
260 				       ZPixmap,0,temp,UNITX,UNITY,8,0);
261     }
262 }
263 
264 /* Initialize cardwindow */
init_cardwin(player)265 int init_cardwin(player)
266      playerp player;
267 {
268   card_winp   cardwin;
269   xconp       xinfo;
270   XSizeHints *s_h,*k_h[CARDS_MAX_SHOWN],*b_h[CARDS_MAX_SHOWN];
271   int         t;
272 
273   s_h = (XSizeHints *)malloc(sizeof(XSizeHints));
274 
275   s_h->x      = 0;
276   s_h->y      = 0;
277   s_h->height = 5*C_SPACE+2*CF_BUTTONH+2*CF_HEIGHT;
278   s_h->width  = 6*C_SPACE+5*CF_WIDTH;
279 
280   s_h->min_width  = s_h->width;
281   s_h->max_width  = s_h->width;
282   s_h->min_height = s_h->height;
283   s_h->max_height = s_h->height;
284   s_h->flags      = PSize|PMinSize|PMaxSize;
285 
286   for(t=0;t<CARDS_MAX_SHOWN;t++)
287     {
288       k_h[t]=(XSizeHints *)malloc(sizeof(XSizeHints));
289       b_h[t]=(XSizeHints *)malloc(sizeof(XSizeHints));
290 
291       k_h[t]->x      = C_SPACE+C_FRAME+(CF_WIDTH+C_SPACE)*(t%CARDS_ROW);
292       k_h[t]->y      = 2*C_SPACE+CF_BUTTONH+C_FRAME+
293 	(C_SPACE+CF_HEIGHT)*(t/CARDS_ROW);
294       k_h[t]->height = C_HEIGHT;
295       k_h[t]->width  = C_WIDTH;
296       k_h[t]->flags  = PPosition|PSize;
297 
298       b_h[t]->x      = k_h[t]->x;
299       b_h[t]->y      = C_SPACE+C_FRAME+
300 	(CF_BUTTONH+2*CF_HEIGHT+3*C_SPACE)*(t/CARDS_ROW);
301       b_h[t]->height = C_BUTTONH;
302       b_h[t]->width  = C_BUTTONW;
303       b_h[t]->flags  = PPosition|PSize;
304     }
305 
306   cardwin            = (card_winp)malloc(sizeof(struct Card_Win));
307   player->card_win   = cardwin;
308   cardwin->player    = player;
309   cardwin->card      = player->card;
310   xinfo              = player->xcon;
311 
312   cardwin->attr.event_mask           = ButtonPressMask|KeyPressMask;
313   cardwin->attr.backing_store        = Always;
314   cardwin->attr.background_pixel     = xinfo->black;
315   cardwin->attr.border_pixel         = xinfo->white;
316   cardwin->attrmask                  = CWBackingStore|CWBackPixel;
317   cardwin->attrmask                 |= CWBorderPixel|CWEventMask;
318   cardwin->s_h                       = s_h;
319   cardwin->chosen                    = 0;
320   cardwin->exchange                  = 0;
321   cardwin->allow_ch                  = 0;
322   if (!DoesBackingStore(xinfo->screen))
323     cardwin->attr.event_mask        |= ExposureMask;
324 
325   start_unit_image(player);
326 
327   cardwin->win=XCreateWindow
328     (xinfo->disp,xinfo->root,s_h->x,s_h->y,s_h->width,s_h->height,1,
329      xinfo->depth,InputOutput,xinfo->visual,
330      cardwin->attrmask,&(cardwin->attr));
331 
332   XSetWindowColormap(xinfo->disp,cardwin->win,xinfo->cmap);
333 
334   XSetStandardProperties
335     (xinfo->disp,cardwin->win,mappet(CARD_WIN_NAME),
336      mappet(CARD_WIN_NAME),None,(char**)NULL,(int)0,s_h);
337 
338   for(t=0;t<CARDS_MAX_SHOWN;t++)
339     {
340       cardwin->k_h[t] = k_h[t];
341       cardwin->b_h[t] = b_h[t];
342 
343       cardwin->cards[t]  = XCreateSimpleWindow
344 	(xinfo->disp,cardwin->win,
345 	 k_h[t]->x,k_h[t]->y,k_h[t]->width,k_h[t]->height,1,
346 	 xinfo->white,xinfo->black);
347       cardwin->buttons[t] = XCreateSimpleWindow
348 	(xinfo->disp,cardwin->win,
349 	 b_h[t]->x,b_h[t]->y,b_h[t]->width,b_h[t]->height,1,
350 	 xinfo->white,xinfo->black);
351 
352       XChangeWindowAttributes(xinfo->disp,cardwin->cards[t],
353 			      CWBackingStore,&(cardwin->attr));
354       XChangeWindowAttributes(xinfo->disp,cardwin->buttons[t],
355 			      CWBackingStore,&(cardwin->attr));
356       XSelectInput(xinfo->disp, cardwin->cards[t],
357 		   cardwin->attr.event_mask & ExposureMask);
358       XSelectInput(xinfo->disp, cardwin->buttons[t],
359 		   cardwin->attr.event_mask & ExposureMask);
360     }
361   return(1);
362 }
363 
364 /* Map the cardwin on screen */
set_up_cardwin(player)365 int set_up_cardwin(player)
366      playerp player;
367 {
368   int        t;
369   xconp      xinfo;
370   card_winp  cardwin;
371 
372   xinfo   = player->xcon;
373   cardwin = player->card_win;
374 
375   XMapWindow(xinfo->disp,cardwin->win);
376   for(t=0;t<CARDS_MAX_SHOWN;t++)
377     {
378       XMapWindow(xinfo->disp,cardwin->cards[t]);
379       XMapWindow(xinfo->disp,cardwin->buttons[t]);
380     }
381   return(1);
382 }
383 
384 /* Initialize the info-window */
init_infowin(player)385 int init_infowin(player)
386      playerp player;
387 {
388   int         t;
389   info_winp   infowin;
390   xconp       xinfo;
391   XSizeHints *s_h,*u_h,*l_h;
392   XWMHints   *wmh;
393 
394   u_h              = (XSizeHints *)malloc(sizeof(XSizeHints));
395   l_h              = (XSizeHints *)malloc(sizeof(XSizeHints));
396   s_h              = (XSizeHints *)malloc(sizeof(XSizeHints));
397 
398   u_h->width       = HEIGHT_ROWS*MAX_PLAYERS+SPACE;
399   l_h->width       = u_h->width;
400   s_h->width       = u_h->width+2;
401   u_h->height      = HEIGHT_ROWS+SPACE;
402   l_h->height      = HEIGHT_ROWS*num_players+SPACE;
403   s_h->height      = u_h->height+l_h->height+4;
404 
405   s_h->min_width   = s_h->width;
406   s_h->max_width   = s_h->width;
407   s_h->min_height  = s_h->height;
408   s_h->max_height  = s_h->height;
409 
410   s_h->x           = 0;
411   s_h->y           = 0;
412   u_h->x           = 0;
413   u_h->y           = 0;
414   l_h->x           = 0;
415   l_h->y           = u_h->height+2;
416 
417   s_h->flags       = PSize|PMinSize|PMaxSize;
418   u_h->flags       = PPosition|PSize;
419   l_h->flags       = u_h->flags;
420 
421   wmh          = XAllocWMHints();
422   wmh->input   = True;
423   wmh->flags   = InputHint;
424 
425   infowin          = (info_winp)malloc(sizeof(struct Info_Win));
426   player->info_win = infowin;
427   xinfo            = player->xcon;
428 
429   infowin->attr.event_mask       = ButtonPressMask|KeyPressMask;
430   infowin->attr.backing_store    = Always;
431   infowin->attr.background_pixel = xinfo->black;
432   infowin->attr.border_pixel     = xinfo->white;
433   infowin->attrmask              = CWBackingStore|CWBackPixel;
434   infowin->attrmask             |= CWBorderPixel;
435   infowin->s_h                   = s_h;
436   infowin->u_h                   = u_h;
437   infowin->l_h                   = l_h;
438   infowin->wmh                   = wmh;
439 
440   if (!DoesBackingStore(xinfo->screen))
441     infowin->attr.event_mask |= ExposureMask;
442 
443   infowin->win=XCreateWindow
444     (xinfo->disp,xinfo->root,s_h->x,s_h->y,s_h->width,s_h->height,1,
445      xinfo->depth,InputOutput,xinfo->visual,
446      infowin->attrmask,&(xinfo->attr));
447 
448   XSetWindowColormap(xinfo->disp,infowin->win,xinfo->cmap);
449 
450   XSetStandardProperties
451     (xinfo->disp,infowin->win,mappet(INFO_WIN_NAME),
452      mappet(INFO_WIN_NAME),None,(char **)NULL,(int)0,s_h);
453   XSetWMHints(player->xcon->disp, player->info_win->win, infowin->wmh);
454 
455   infowin->upper=XCreateSimpleWindow
456     (xinfo->disp,infowin->win,u_h->x,u_h->y,u_h->width,u_h->height,1,
457      xinfo->white,xinfo->black);
458   infowin->lower=XCreateSimpleWindow
459     (xinfo->disp,infowin->win,l_h->x,l_h->y,l_h->width,l_h->height,1,
460      xinfo->white,xinfo->black);
461 
462   XSetWindowColormap(xinfo->disp,infowin->win,xinfo->cmap);
463   XSetWindowColormap(xinfo->disp,infowin->upper,xinfo->cmap);
464   XSetWindowColormap(xinfo->disp,infowin->lower,xinfo->cmap);
465 
466   XChangeWindowAttributes
467     (xinfo->disp,infowin->upper,CWBackingStore,&(infowin->attr));
468   XChangeWindowAttributes
469     (xinfo->disp,infowin->lower,CWBackingStore,&(infowin->attr));
470 
471   for(t=0;t<MAX_PLAYERS;t++) infowin->child[t]=XCreateSimpleWindow
472     (xinfo->disp,infowin->upper,t*(SPACE+2*FRAME+WIDTH_BUTT)+SPACE,
473      SPACE,WIDTH_BUTT,WIDTH_BUTT,FRAME,xinfo->white,xinfo->pixm[t+50]);
474   XFlush(xinfo->disp);
475 
476   /* Used after player has chosen color and name */
477   u_h->width     = WIDTH_COL*NUM_COL+WIDTH_BUTT+2*(FRAME+SPACE);
478   l_h->width     = u_h->width;
479   s_h->width     = u_h->width+2;
480   s_h->min_width = s_h->width;
481   s_h->max_width = s_h->width;
482   return(0);
483 }
484 
set_up_infowin(player)485 int set_up_infowin(player)
486      playerp player;
487 {
488   int        t;
489   xconp      xinfo;
490   info_winp  infowin;
491 
492   xinfo   = player->xcon;
493   infowin = player->info_win;
494 
495   XMapWindow(xinfo->disp,infowin->win);
496   XMapWindow(xinfo->disp,infowin->upper);
497   XMapWindow(xinfo->disp,infowin->lower);
498   for(t=0;t<MAX_PLAYERS;t++) XMapWindow(xinfo->disp,infowin->child[t]);
499   return(1);
500 }
501 
get_col_init(player)502 int get_col_init(player)
503      playerp player;
504 {
505   player->pstat->spec_win = player->info_win->upper;
506   XSelectInput(player->xcon->disp, player->info_win->upper,
507 	       player->info_win->attr.event_mask);
508   return(0);
509 }
510 
get_col_exit(player)511 int get_col_exit(player)
512      playerp player;
513 {
514   player->pstat->spec_win = (Window)NULL;
515   XSelectInput(player->xcon->disp,player->info_win->upper,
516 	       player->info_win->attr.event_mask & ExposureMask);
517   XSelectInput(player->xcon->disp,player->info_win->lower,
518 	       player->info_win->attr.event_mask & ExposureMask);
519   return(0);
520 }
521 
522 /* Get the color a player wants */
get_col_equal(player)523 int get_col_equal(player)
524      playerp player;
525 {
526   xconp       xinfo;
527   XEvent     *evp;
528   info_winp   infowin;
529   int         t,chosen;
530   static int  totchosen=0;
531 
532   xinfo   = player->xcon;
533   infowin = player->info_win;
534   evp     = GetEventp(player);
535 
536   for(chosen=0;(infowin->child[chosen]!=evp->xbutton.subwindow)
537       &&(chosen<MAX_PLAYERS);chosen++);
538   if (chosen==MAX_PLAYERS) return(0);
539   Choose(totchosen,chosen);
540 
541   XSetNormalHints(xinfo->disp,infowin->win,infowin->s_h);
542   XSetNormalHints(xinfo->disp,infowin->upper,infowin->u_h);
543   XSetNormalHints(xinfo->disp,infowin->lower,infowin->l_h);
544 
545   XResizeWindow
546     (xinfo->disp,infowin->win,infowin->s_h->width,infowin->s_h->height);
547   XResizeWindow
548     (xinfo->disp,infowin->upper,infowin->u_h->width,infowin->u_h->height);
549   XResizeWindow
550     (xinfo->disp,infowin->lower,infowin->l_h->width,infowin->l_h->height);
551 
552   settopp_infowin(player);
553   player->colors[player->indexs]=player->colors[chosen];
554 
555   for(t=0;t<MAX_PLAYERS;t++) if (!Chosen(totchosen,t))
556     XDestroyWindow(xinfo->disp,infowin->child[t]);
557   infowin->button=XCreateSimpleWindow
558     (xinfo->disp,infowin->upper,SPACE,SPACE,WIDTH_BUTT,WIDTH_BUTT,FRAME,
559      xinfo->white,xinfo->pixm[50+chosen]);
560 
561   XMapWindow(xinfo->disp,infowin->button);
562   XFlush(xinfo->disp);
563 
564   Do_each_player(t)
565     {
566       xinfo   = players[t]->xcon;
567       infowin = players[t]->info_win;
568       if (players[t]->state->state <= PRESS_BUTTON)
569 	XDestroyWindow(xinfo->disp,infowin->child[chosen]);
570       infowin->child[chosen]=XCreateSimpleWindow
571 	(xinfo->disp,infowin->lower,SPACE,
572 	 SPACE+player->indexs*(SPACE+2*FRAME+WIDTH_BUTT), WIDTH_BUTT,
573 	 WIDTH_BUTT,FRAME,xinfo->white,xinfo->pixm[50+chosen]);
574       XMapWindow(xinfo->disp,infowin->child[chosen]);
575       XFlush(xinfo->disp);
576     }
577   return(1);
578 }
579 
580 /* Initialize the action of getting a name */
get_name_init(player)581 int get_name_init(player)
582      playerp player;
583 {
584   pstatp  pstat;
585 
586   pstat                      = player->pstat;
587   pstat->string[0]           = player->name;
588   pstat->strlen              = strlen(player->name);
589   pstat->win                 = player->info_win->lower;
590   pstat->spec_win            = player->info_win->win;
591   pstat->flags               = CENTER|CLR;
592   pstat->clear_field         = 0;
593   pstat->fc                  = player->xcon->white;
594   pstat->bc                  = player->xcon->black;
595   pstat->x                   = START_TEXT_X;
596   pstat->y                   = START_TEXT_Y + player->indexs * HEIGHT_ROWS;
597   pstat->dx                  = DX_KOL;
598   pstat->dy                  = -1;
599   pstat->strmax              = MAXLEN_NPLAYER;
600   pstat->strmin              = MINLEN_NPLAYER;
601   XSelectInput(player->xcon->disp,player->info_win->win,
602 	       player->info_win->attr.event_mask);
603   return(0);
604 }
605 
get_name_exit(player)606 int get_name_exit(player)
607      playerp player;
608 {
609   player->pstat->spec_win = (Window)0;
610   return(0);
611 }
612 
613 /* Get a string from aa window */
get_string(player)614 int get_string(player)
615      playerp player;
616 {
617   XEvent        *pev;
618   int            length;
619   KeySym         tegn;
620   XComposeStatus compose;
621   pstatp         pstat;
622   char          *string;
623   char           buffer[10];
624   xconp          xinfo;
625 
626   pstat  = player->pstat;
627   pev    = GetEventp(player);
628   length = pstat->strlen;
629   string = pstat->string[0];
630   xinfo  = player->xcon;
631 
632   XLookupString(&(pev->xkey),buffer,10,&tegn,&compose);
633   if ( ((tegn==XK_Return)||(tegn==XK_Linefeed))
634       && (length>=player->pstat->strmin))
635     {
636       if (player->pstat->clear_field) write_line
637 	(xinfo,player->pstat->win,player->pstat->fc,
638 	 player->pstat->bc,player->pstat->x,player->pstat->y,
639 	 player->pstat->dx,player->pstat->dy,"",player->pstat->flags);
640       return(1);
641     }
642 
643   if ((tegn>=XK_space)&&(tegn<=XK_asciitilde))
644     if(length!=player->pstat->strmax) string[length++]=buffer[0];
645 
646   if ((tegn==XK_Delete)||(tegn==XK_BackSpace))
647     if (length) length--;
648 
649   string[length] = 0;
650   pstat->strlen  = length;
651 
652   write_line(xinfo,player->pstat->win,player->pstat->fc,
653 	     player->pstat->bc,player->pstat->x,player->pstat->y,
654 	     player->pstat->dx,player->pstat->dy,string,player->pstat->flags);
655   return(0);
656 }
657 
658 /* Clear the place where player-messages appear */
clear_string(player)659 int clear_string(player)
660      playerp player;
661 {
662   write_line(player->xcon,player->pstat->win,player->pstat->fc,
663 	     player->pstat->bc,player->pstat->x,player->pstat->y,
664 	     player->pstat->dx,player->pstat->dy,"",player->pstat->flags);
665   return(0);
666 }
667 
668 /* Don't let to players have the same name */
check_name(player)669 int check_name(player)
670      playerp player;
671 {
672   int t;
673   char *s;
674   for(s=player->name;isspace(*s);s++);
675   for(t=0;(player->name[t]= *s);t++,s++);
676   if (t) for(s= &player->name[t-1];isspace(*s)&&s!=player->name;*(s--)=0);
677   if (strlen(player->name) < MINLEN_NPLAYER)    return(1);
678   Do_each_player(t) if(players[t]->state->state > CHECK_NAME)
679     if (!strcmp(player->name,players[t]->name)) return(1);
680   return(0);
681 }
682 
683 /* Let all who have chosen their color know your name */
export_name(player)684 int export_name(player)
685      playerp player;
686 {
687   int        t,i;
688   xconp      xinfo;
689   info_winp  infowin;
690 
691   i = player->indexs;
692   Do_each_player(t) if(players[t]->state->state > PRESS_BUTTON )
693     {
694       xinfo   = players[t]->xcon;
695       infowin = players[t]->info_win;
696       write_line(xinfo,infowin->lower,-1,-1,START_TEXT_X,
697 		 START_TEXT_Y+i*HEIGHT_ROWS,DX_KOL,-1,player->name,CENTER|CLR);
698     }
699   return(1);
700 }
701 
702 /* Some fixing now that we know the players name */
mission_fix(player)703 int mission_fix(player)
704      playerp player;
705 {
706   if ((player->mission)&&(player->mission->victim)) sprintf
707     (player->mission->sentence,mappet("#095_Kill %s"),
708      player->mission->victim->name);
709   return(0);
710 }
711 
712 /* Initialize the statistics */
init_pl_stat(player)713 int init_pl_stat(player)
714      playerp player;
715 {
716   int t,country,armies,continenter;
717 
718   for(country=0,armies=0;player->conquests[country];country++)
719     armies+=player->conquests[country]->number;
720   for(t=0,continenter=0;t<NUM_CONTINENTS;t++)
721     if (conquered_continent(player,&continents[t])) continenter++;
722 
723   player->num_conquests     = 0;
724   player->num_continents    = 0;
725   player->num_armies        = 0;
726   player->num_armies_gained = 0;
727   player->num_cards         = 0;
728   player->armies_lost       = 0;
729   player->armies_killed     = 0;
730 
731   update_infowin(player,country    ,U_COUNTRIES);
732   update_infowin(player,continenter,U_CONTINENTS);
733   update_infowin(player,armies     ,U_ARMIES);
734   update_infowin(player,armies     ,U_ARMIES_GAINED);
735   update_infowin(player,0          ,U_CARDS);
736   update_infowin(player,0          ,U_ARMIES_LOST);
737   update_infowin(player,0          ,U_ARMIES_KILLED);
738   return(1);
739 }
740 
741 /* Initialise the first setting of armies */
i_init_armies(player)742 int i_init_armies(player)
743      playerp player;
744 {
745   pstatp pstat;
746 
747   pstat              = player->pstat;
748   pstat->armies_left = game_options.armies_start;
749   pstat->strmax      = 1;
750   pstat->strmin      = 1;
751   pstat->from        = (countryp)NULL;
752   pstat->target      = (countryp)NULL;
753   write_msg_arg(player,"#059_You have %d armies to place",
754 		ARMIES_START,LAST_ARG);
755   return(1);
756 }
757 
758 /* Initialize free moves */
free_move_init(player)759 int free_move_init(player)
760      playerp player;
761 {
762   pstatp pstat;
763   pstat              = player->pstat;
764   pstat->armies_left = FREE_MOVES;
765   pstat->strmax      = 10;
766   pstat->strmin      = 1;
767   pstat->from        = (countryp)NULL;
768   pstat->target      = (countryp)NULL;
769   write_msg(player,"");
770   if (!op_move_armies(player)) return(2);
771   return(1);
772 }
773 
774 /* Tell player how many free moves he has got left */
free_move_left(player)775 int free_move_left(player)
776      playerp player;
777 {
778   if (player->pstat->armies_left)
779     write_msg_arg(player,"#067_You have %d free moves",
780 		  player->pstat->armies_left,LAST_ARG);
781   else return(1);
782   return(0);
783 }
784 
785 /* Where to place your first armies */
i_a_where(player)786 int i_a_where(player)
787      playerp player;
788 {
789   if ( !(player->pstat->country) || (player->pstat->country->occupant!=player)
790       || (player->pstat->country->number >= game_options.max_armies_start ))
791     {
792       if(player->pstat->country)
793 	write_msg_arg(player,"#056_You can not place armies in %s"
794 		      ,player->pstat->country->name);
795       return(0);
796     }
797 
798   player->pstat->target     = player->pstat->country;
799   player->pstat->from       = (countryp)NULL;
800   player->pstat->armies_min = 0;
801   player->pstat->armies_max = Min
802     (player->pstat->armies_left,
803      game_options.max_armies_start - player->pstat->target->number);
804   return(1);
805 }
806 
807 /* Update every player's color-table (Only done once) */
fix_colors(player)808 int fix_colors(player)
809      playerp player;
810 {
811   int t;
812 
813   Do_each_player(t) player->colors[t]=players[t]->colors[t];
814   return(0);
815 }
816 
817 /* Check where your pointer are */
update_pointer(player)818 int update_pointer(player)
819      playerp player;
820 {
821   Window       rr,cr;
822   int          xr,yr,x,y;
823   unsigned int mr;
824   xconp        xinfo;
825 
826   xinfo=player->xcon;
827   if(XQueryPointer(xinfo->disp,xinfo->win,&rr,&cr,&xr,&yr,&x,&y,&mr))
828     player->pstat->country = find_country_coord(x,y);
829   else player->pstat->country = NULL;
830 
831   if (xinfo->win) write_country(xinfo,player->pstat->country);
832   return(0);
833 }
834 
835 /* Initialize a new turn. Maybe even give you a hint */
init_turn(player)836 int init_turn(player)
837      playerp player;
838 {
839 
840   int nye=0;
841 
842   nye                        += new_armies(player);
843   player->pstat->armies_left  = nye;
844   player->offensiv            = 0;
845   player->card_win->allow_ch  = 1;
846   XBell(player->xcon->disp,100);
847   XBell(player->xcon->disp,100);
848   XBell(player->xcon->disp,100);
849   write_msg_all_arg("#003_%s begins their turn with %d armies",
850 		    player->name,nye,LAST_ARG);
851   exchange_card(player);
852   return(1);
853 }
854 
855 /* No more changing of cards */
disable_ca_ch(player)856 int disable_ca_ch(player)
857      playerp player;
858 {
859   if (player->pstat->armies_left) return(0);
860   player->card_win->allow_ch = 0;
861   return(0);
862 }
863 
864 /* Where to place armies */
p_a_where(player)865 int p_a_where(player)
866      playerp player;
867 {
868   if (!(player->pstat->country) || (player->pstat->country->occupant != player)
869       || (!player->pstat->armies_left)) return(0);
870 
871   player->pstat->target     = player->pstat->country;
872   player->pstat->from       = (countryp)NULL;
873   player->pstat->armies_min = 0;
874   player->pstat->armies_max = player->pstat->armies_left;
875 
876   if (player->pstat->armies_left == 1)
877     {
878       player->pstat->armies_move = 1;
879       return(2);
880     }
881   return(1);
882 }
883 
884 /* Where to attack from */
f_a_where(player)885 int f_a_where(player)
886      playerp player;
887 {
888   if ( !(player->pstat->country)||(player->pstat->country->occupant != player)
889       ||(player->pstat->country->number == 1) )
890     {
891       if (player->pstat->country)
892 	write_msg_arg(player,"#052_You can not attack from %s !!",
893 		      player->pstat->country->name,LAST_ARG);
894       return(0);
895     }
896 
897   player->pstat->from = player->pstat->country;
898   write_msg_arg(player,"#051_You attack from %s",
899 		player->pstat->country->name,LAST_ARG);
900   write_msg_all_arg("#002_%s attacks from %s",player->name,
901 		    player->pstat->country->name,LAST_ARG);
902   return(1);
903 }
904 
905 /* Where to "free-move" from */
f_m_where(player)906 int f_m_where(player)
907      playerp player;
908 {
909   if ( !(player->pstat->country) || (player->pstat->country->occupant!=player)
910       ||(player->pstat->country->number == 1))
911     {
912       if (player->pstat->country)
913 	write_msg_arg(player,"#054_You can not move any armies from %s !!",
914 		      player->pstat->country->name,LAST_ARG);
915       return(0);
916     }
917 
918   player->pstat->from       = player->pstat->country;
919   player->pstat->armies_min = 0;
920   player->pstat->armies_max = Min(player->pstat->from->number-1
921 				  ,player->pstat->armies_left);
922   write_msg_arg(player,"#064_You move your armies from %s",
923 		player->pstat->country->name,LAST_ARG);
924   return(1);
925 }
926 
927 /* Place/move your armies */
p_a_place(player)928 int p_a_place(player)
929      playerp player;
930 {
931   if (   (player->pstat->from && player->pstat->from->occupant != player)
932       || player->pstat->target->occupant != player) return(1);
933 
934   move_armies(player->pstat->from,player->pstat->target,
935 	      player->pstat->armies_move);
936 
937   if ( !player->pstat->armies_left
938       ||(player->pstat->armies_left -= player->pstat->armies_move) ) return(1);
939 
940   if (!player->pstat->from)
941     write_msg(player,"#065_Your last army has been placed");
942   return(2);
943 }
944 
945 /* Mouse-button1 is supposed to return max */
number_m1(player)946 int number_m1(player)
947      playerp player;
948 {
949   player->pstat->armies_move = player->pstat->armies_max;
950   return(1);
951 }
952 
953 /* Mouse-button2 returns 1 or min */
number_m2(player)954 int number_m2(player)
955      playerp player;
956 {
957   player->pstat->armies_move =
958     Min(player->pstat->armies_max,Max(player->pstat->armies_min,1));
959   return(1);
960 }
961 
962 /* And mouse-botton3 will return min */
number_m3(player)963 int number_m3(player)
964      playerp player;
965 {
966   if ((player->pstat->armies_move = player->pstat->armies_min)) return(1);
967   return(2);
968 }
969 
970 /* End of a turn */
end_turn(player)971 int end_turn(player)
972      playerp player;
973 {
974   if (player->offensiv) give_player_card(player);
975   write_msg(player,"");
976   return(1);
977 }
978 
979 /* Free moves to where ?? */
free_move_to(player)980 int free_move_to(player)
981      playerp player;
982 {
983   if (   (!player->pstat->country)
984       || (!neighbours(player->pstat->from,player->pstat->country))
985       || (player->pstat->country->occupant!=player)
986       || (player->pstat->from->occupant   !=player) )
987     {
988       if (player->pstat->target) write_msg_arg
989 	(player,"#055_You can not move any armies from %s to %s !!"
990 	 ,player->pstat->from->name,player->pstat->target->name,LAST_ARG);
991       return(0);
992     }
993   player->pstat->target = player->pstat->country;
994   return(1);
995 }
996 
997 /* Attack a country */
attack_country(player)998 int attack_country(player)
999      playerp player;
1000 {
1001   countryp from,target;
1002   int      minmove;
1003 
1004   target = player->pstat->country;
1005   from   = player->pstat->from;
1006 
1007   if ( (!target) || (!neighbours(from,target)) || target->occupant==player )
1008     return(0);
1009 
1010   if ( from->occupant!=player || from->number==1 )
1011     return(1);
1012 
1013   player->pstat->target = target;
1014   write_msg_arg(player,"#050_You attack from %s to %s",
1015 		from->name,target->name,LAST_ARG);
1016   write_msg_all_arg("#001_%s attacks from %s to %s",
1017 		    player->name,from->name,target->name,LAST_ARG);
1018 
1019   minmove = attack(from,target);
1020   if (!target->number)
1021     {
1022       player->offensiv++;
1023       if (minmove==1) write_msg_all_arg
1024 	("#007_%s conquered %s with 1 army",
1025 	 player->name,target->name,LAST_ARG);
1026       else write_msg_all_arg
1027 	("#006_%s conquered %s with %d armies",
1028 	 player->name,target->name,minmove,LAST_ARG);
1029 
1030       sub_country(target->occupant->conquests,target);
1031       if (!target->occupant->conquests[0])
1032 	player_killed(from->occupant,target->occupant);
1033 
1034       target->occupant=from->occupant;
1035       set_color((playerp)NULL,target);
1036       add_country(from->occupant->conquests,target);
1037 
1038       sub_armies(from,NULL,minmove,NO_UPDATE);
1039       add_armies(target,minmove,NO_UPDATE);
1040 
1041       player->pstat->armies_min  = 0;
1042       player->pstat->armies_left = 0;
1043       player->pstat->armies_max  = from->number-1;
1044 
1045       if (from->number > 1) return(2);
1046       return(1);
1047     }
1048   if (from->number == 1) return(1);
1049   return(0);
1050 }
1051 
1052 /* Initialize to get a number when moving armies */
p_a_get_num_i(player)1053 int p_a_get_num_i(player)
1054      playerp player;
1055 {
1056   pstatp pstat;
1057 
1058   pstat                      = player->pstat;
1059   pstat->string[0]           = pstat->genstring;
1060   pstat->strlen              = 0;
1061   pstat->win                 = player->xcon->win;
1062   pstat->flags               = CENTER|CLR;
1063   pstat->fc                  = -1;
1064   pstat->bc                  = -1;
1065   pstat->x                   = MSGX;
1066   pstat->y                   = MSGY+20;
1067   pstat->dx                  = MSGLEN;
1068   pstat->dy                  = -1;
1069   pstat->strmax              = 30;
1070   pstat->strmin              = 1;
1071   pstat->clear_field         = 1;
1072 
1073   if (player->pstat->from) write_msg_arg
1074     (player,
1075      "#034_How many armies do you want to move from %s to %s (%d - %d)?",
1076      player->pstat->from->name,player->pstat->target->name,
1077      player->pstat->armies_min,player->pstat->armies_max,LAST_ARG);
1078   else write_msg_arg
1079     (player,
1080      "#035_How many armies do you want to place in %s (%d - %d)?",
1081      player->pstat->target->name,
1082      player->pstat->armies_min,player->pstat->armies_max,LAST_ARG);
1083   return(0);
1084 }
1085 
1086 /* Is this a number we can accept ?? */
p_a_number(player)1087 int p_a_number(player)
1088      playerp player;
1089 {
1090   player->pstat->armies_move = atoi(player->pstat->genstring);
1091   if (  (player->pstat->armies_move > player->pstat->armies_max)
1092       ||(player->pstat->armies_move < player->pstat->armies_min))
1093     return(2);
1094   return(1);
1095 }
1096 
1097 /* What to do when we choose a card */
card_handler(player)1098 int card_handler(player)
1099      playerp player;
1100 {
1101   int        t;
1102   xconp      xinfo;
1103   card_winp  cardwin;
1104   XEvent    *eventp;
1105 
1106   xinfo   = player->xcon;
1107   cardwin = player->card_win;
1108   eventp  = GetEventp(player);
1109 
1110   for(t=0;((cardwin->card[t])&&(eventp->xbutton.subwindow!=cardwin->cards[t])
1111            &&(eventp->xbutton.subwindow!=cardwin->buttons[t]));t++);
1112   if ((t==CARDS_MAX_SHOWN)||(!cardwin->card[t])) return(0);
1113 
1114   Choose(cardwin->chosen,t);
1115   show_chosen_card(xinfo,cardwin,t);
1116   value_of_card(cardwin);
1117   if (cardwin->allow_ch == 1) exchange_card(player);
1118   if ((cardwin->allow_ch == 2)&&(cardwin->player->num_cards>=5))
1119     exchange_card(player);
1120   return(0);
1121 }
1122 
1123 /* End of game */
end_game(player)1124 int end_game(player)
1125      playerp player;
1126 {
1127   write_msg(player,"");
1128   return(0);
1129 }
1130 
1131 /* Really end of game */
close_game(player)1132 int close_game(player)
1133      playerp player;
1134 {
1135   free_player(player);
1136   return(0);
1137 }
1138