1 /*
2 * XScrabble - X version of the popular board game, for 1 to 4 players.
3 *
4 * This software comes with NO warranty whatsoever. I therefore take no
5 * responsibility for any damages, losses or problems caused through use
6 * or misuse of this program.
7 *
8 * I hereby grant permission for this program to be freely copied and
9 * distributed by any means, provided no charge is made for it.
10 *
11 * Matthew Chapman, csuoq@csv.warwick.ac.uk
12 * Oct 1994.
13 */
14
15 /* widgets.c - define widgets */
16
17 #include "scrab.h"
18 #include "globals.h"
19
20 #include "dot.xbm"
21
set_board(Widget top,int dnum)22 void set_board(Widget top,int dnum)
23 {
24 Dimension width;
25 int ac,dn,bn,i,j,ind;
26 char wname[6],lett[3];
27
28 Widget sur[BOARDSIZE*2],edg[BOARDSIZE*2];
29 Widget boardw;
30 String modestr, startstr;
31
32 all = XtVaCreateManagedWidget("all", formWidgetClass,top, NULL);
33 title = XtVaCreateManagedWidget("title", labelWidgetClass, all, NULL);
34
35 boardw = XtVaCreateManagedWidget("board", formWidgetClass, all, NULL);
36
37
38 SetupHelp(all,dnum);
39 SetupMenu(all,dnum);
40
41 /* board surround */
42 for (ac=0; ac<BOARDSIZE; ac++)
43 {
44 sprintf(lett,"%c",ac+'A');
45 sur[ac]=XtVaCreateManagedWidget("surr",labelWidgetClass,boardw,XtNlabel,
46 lett,NULL);
47 if (ac>0)
48 XtVaSetValues(sur[ac],XtNfromHoriz,sur[ac-1],
49 XtNhorizDistance,0,NULL);
50 /* else
51 XtVaSetValues(sur[ac],XtNhorizDistance,30,NULL); */
52 }
53
54
55 /* squares on board */
56 for (dn=0; dn<BOARDSIZE; dn++)
57 {
58 sprintf(lett,"%d",dn);
59 edg[dn]=XtVaCreateManagedWidget("edg",labelWidgetClass,boardw,
60 XtNlabel,lett,NULL);
61 if (dn>0)
62 XtVaSetValues(edg[dn],XtNfromVert,edg[dn-1],NULL);
63 else
64 XtVaSetValues(edg[dn],XtNfromVert,sur[0],NULL);
65
66 for (ac=0; ac<BOARDSIZE; ac++)
67 {
68 sprintf(wname,"%d-%d",ac,dn);
69 sq[dnum][ac][dn]=XtVaCreateManagedWidget(wname,commandWidgetClass,
70 boardw, XtNlabel," ", NULL);
71 if (ac>0)
72 XtVaSetValues(sq[dnum][ac][dn],XtNfromHoriz,sq[dnum][ac-1][dn],NULL);
73 else
74 XtVaSetValues(sq[dnum][ac][dn],XtNfromHoriz,edg[dn],NULL);
75
76 if (dn>0)
77 XtVaSetValues(sq[dnum][ac][dn],XtNfromVert,sq[dnum][ac][dn-1],NULL);
78 else
79 XtVaSetValues(sq[dnum][ac][dn],XtNfromVert,sur[ac],NULL);
80
81 }
82 edg[dn+BOARDSIZE]=XtVaCreateManagedWidget("edg",labelWidgetClass,boardw,
83 XtNlabel,lett,XtNfromHoriz,sq[dnum][BOARDSIZE-1][dn],NULL);
84 if (dn>0)
85 XtVaSetValues(edg[dn+BOARDSIZE],XtNfromVert,edg[dn+BOARDSIZE-1],NULL);
86 else
87 XtVaSetValues(edg[dn+BOARDSIZE],XtNfromVert,sur[0],NULL);
88 }
89
90 /* board surround */
91 for (ac=0; ac<BOARDSIZE; ac++)
92 {
93 sprintf(lett,"%c",ac+'A');
94 sur[ac+BOARDSIZE]=XtVaCreateManagedWidget("surr",labelWidgetClass,
95 boardw,XtNlabel,lett,XtNfromVert,sq[dnum][ac][BOARDSIZE-1],NULL);
96 if (ac>0)
97 XtVaSetValues(sur[ac+BOARDSIZE],XtNfromHoriz,sur[ac+BOARDSIZE-1],
98 XtNhorizDistance,0,NULL);
99 /* else
100 XtVaSetValues(sur[ac+BOARDSIZE],XtNhorizDistance,30,NULL); */
101 }
102
103 scoretitle = XtVaCreateManagedWidget("scoretitle", labelWidgetClass, all,
104 NULL);
105 scorebox[dnum] = XtVaCreateManagedWidget("scorebox", labelWidgetClass, all, NULL);
106
107 tilesleft[dnum] = XtVaCreateManagedWidget("tilesleft", labelWidgetClass, all, NULL);
108
109
110 barw[dnum] = XtVaCreateManagedWidget("bar", formWidgetClass, all, NULL);
111 message[dnum] = XtVaCreateManagedWidget("message", labelWidgetClass, all, NULL);
112
113 /* squares in bar */
114 for (bn=0; bn<LONGBAR; bn++)
115 {
116 bar[dnum][bn]=' ';
117 sprintf(wname,"bar%d",bn);
118 br[dnum][bn]=XtVaCreateManagedWidget(wname,commandWidgetClass,
119 barw[dnum], XtNlabel, " ", NULL);
120 if (bn>0)
121 XtVaSetValues(br[dnum][bn],XtNfromHoriz,br[dnum][bn-1],NULL);
122
123 }
124
125 exitButton[dnum] = XtVaCreateManagedWidget("exit",commandWidgetClass,
126 all,NULL);
127
128 XtAddCallback(exitButton[dnum],XtNcallback,Quit,all);
129
130 /* set square colours */
131 for (dn=0; dn<BOARDSIZE; dn++)
132 for (ac=0; ac<BOARDSIZE; ac++)
133 XtVaSetValues(sq[dnum][ac][dn],SETBG(colours[sq_col[ac][dn]]),NULL);
134
135 pauseButton[dnum] = XtVaCreateManagedWidget("pause",
136 toggleWidgetClass, all, NULL);
137
138 XtVaGetValues(pauseButton[dnum],XtNlabel,&modestr,NULL);
139 XtVaGetValues(pauseButton[dnum],XtNwidth,&width,NULL);
140 strcpy(modestart,modestr);
141 ind = strlen(modestart); j = 1;
142 for (i=0; (i<ind) && (modestart[i]!='/'); i++) j++;
143 for (i=j; i<ind; i++)
144 modepause[i-j]=modestart[i];
145 modestart[ind-j]='\0';
146 modepause[j-1]='\0';
147 XtVaSetValues(pauseButton[dnum],XtNlabel,modestart,XtNwidth,width,
148 XtNstate,True,NULL);
149 XtAddCallback(pauseButton[dnum],XtNcallback,StartPauseToggle,all);
150
151 if (type[dnum]==0) /* human player */
152 {
153 /* for moving tiles */
154 for (dn=0; dn<BOARDSIZE; dn++)
155 for (ac=0; ac<BOARDSIZE; ac++)
156 XtAddCallback(sq[dnum][ac][dn],XtNcallback,Select_sq,top);
157 for (ac=0; ac<LONGBAR; ac++)
158 XtAddCallback(br[dnum][ac],XtNcallback,Select_sq,top);
159
160 /* timer widget */
161 if (time_limit>0)
162 timeleft[dnum] = XtVaCreateManagedWidget("timeleft",
163 xfwfCircularPercentageWidgetClass,all,NULL);
164
165 /* move buttons */
166 finish[dnum] = XtVaCreateManagedWidget("finish", commandWidgetClass,all,
167 XtNsensitive,False,NULL);
168 change[dnum] = XtVaCreateManagedWidget("change", commandWidgetClass,all,
169 XtNsensitive,False,NULL);
170 pass[dnum] = XtVaCreateManagedWidget("pass", commandWidgetClass,all,
171 XtNsensitive,False,NULL);
172 evaluate[dnum] = XtVaCreateManagedWidget("evaluate", commandWidgetClass,all,
173 XtNsensitive,False,NULL);
174
175 /* extra buttons */
176 revert[dnum] = XtVaCreateManagedWidget("revert",commandWidgetClass,all,XtNsensitive,False,NULL);
177 juggle[dnum] = XtVaCreateManagedWidget("juggle",commandWidgetClass,all,XtNsensitive,False,NULL);
178
179 /* for buttons around board */
180
181 XtAddCallback(finish[dnum],XtNcallback,FinishGo,top);
182 XtAddCallback(evaluate[dnum],XtNcallback,FinishGo,top);
183 XtAddCallback(change[dnum],XtNcallback,ChangePopup,top);
184 XtAddCallback(pass[dnum],XtNcallback,PassGo,top);
185 XtAddCallback(revert[dnum],XtNcallback,RevertToBar,top);
186 XtAddCallback(juggle[dnum],XtNcallback,Juggle,top);
187 } else /* computer player */
188 {
189 /* if (time_limit>0)
190 XtVaSetValues(timeleft[dnum],XtNmappedWhenManaged,False,NULL);
191 XtVaSetValues(finish[dnum],XtNmappedWhenManaged,False,NULL);
192 XtVaSetValues(evaluate[dnum],XtNmappedWhenManaged,False,NULL);
193 XtVaSetValues(change[dnum],XtNmappedWhenManaged,False,NULL);
194 XtVaSetValues(pass[dnum],XtNmappedWhenManaged,False,NULL);
195 XtVaSetValues(revert[dnum],XtNmappedWhenManaged,False,NULL);
196 XtVaSetValues(juggle[dnum],XtNmappedWhenManaged,False,NULL); */
197 XtVaSetValues(barw[dnum],XtNmappedWhenManaged,False,NULL);
198
199 compw[dnum] = XtVaCreateManagedWidget("compthink",xcBarGraphWidgetClass,all,NULL);
200 compshowbar[dnum] = XtVaCreateManagedWidget("showbar",commandWidgetClass,all,NULL);
201 comphidebar[dnum] = XtVaCreateManagedWidget("hidebar",commandWidgetClass,all,NULL);
202 XtAddCallback(compshowbar[dnum],XtNcallback,CompShowBar,top);
203 XtAddCallback(comphidebar[dnum],XtNcallback,CompHideBar,top);
204 }
205
206 bg_pixmap(all);
207 bg_pixmap(title);
208
209 CreateLettValuesPopup(dnum);
210 CreateRulesPopup(dnum);
211 CreateHiScoresPopup(dnum);
212 CreateBestgoPopup(dnum);
213 CreateAboutPopup(dnum);
214 CreateKeyPopup(dnum);
215 CreateMess(dnum);
216
217 CreateSelectBagPopup(dnum);
218 CreateShowBagPopup(dnum);
219 CreateCheckwordPopup(dnum);
220 CreatePlacewordPopup(dnum);
221 CreateListwordPopup(dnum);
222 CreateSuggestionPopup(dnum);
223 }
224
SetupHelp(Widget top,int dnum)225 void SetupHelp(Widget top, int dnum)
226 {
227 char entry[8];
228 int i;
229
230 markhelp[dnum] = XCreateBitmapFromData(XtDisplay(top),RootWindowOfScreen(XtScreen(top)),
231 (char *)dot_bits,dot_width,dot_height);
232
233 helpgameButton[dnum] = XtVaCreateManagedWidget("helpButton",menuButtonWidgetClass,
234 top,NULL);
235
236 helpgame[dnum] = XtVaCreatePopupShell("menu",simpleMenuWidgetClass,
237 helpgameButton[dnum],NULL);
238
239 for (i=0; i<HELP_ITEMS; i++)
240 {
241 helpgame_status[dnum][i]=False;
242 sprintf(entry,"help%d",i);
243 helpgame_item[dnum][i] = XtVaCreateManagedWidget(entry,smeBSBObjectClass,
244 helpgame[dnum],NULL);
245 XtAddCallback(helpgame_item[dnum][i],XtNcallback,ProcessHelp,top);
246 }
247 }
248
ProcessHelp(Widget w,XtPointer client_data,XtPointer call_data)249 void ProcessHelp(Widget w, XtPointer client_data, XtPointer call_data)
250 {
251 char *name = XtName(w);
252 int sel = name[4] - '0';
253 int i,dnum=0;
254
255 for (i=0; i<num_players; i++)
256 if (w==helpgame_item[i][sel])
257 dnum=i;
258 if (helpgame_status[dnum][sel]==False)
259 XtVaSetValues(w,XtNleftBitmap,markhelp[dnum],NULL);
260 else
261 XtVaSetValues(w,XtNleftBitmap,None,NULL);
262
263 helpgame_status[dnum][sel]= !helpgame_status[dnum][sel];
264
265 switch (sel)
266 {
267 case MANUAL:
268 SelectBagPopup(dnum);
269 break;
270 case BAG:
271 ShowBagPopup(dnum);
272 break;
273 case CHECK:
274 CheckwordPopup(dnum);
275 break;
276 case PLACE:
277 PlacewordPopup(dnum);
278 break;
279 case LIST:
280 ListwordPopup(dnum);
281 break;
282 case SUGGESTION:
283 SuggestionPopup(dnum);
284 break;
285 default: break;
286 }
287 }
288
SetupMenu(Widget top,int dnum)289 void SetupMenu(Widget top,int dnum)
290 {
291 char entry[8];
292 int i;
293
294 markmenu[dnum] = XCreateBitmapFromData(XtDisplay(top),RootWindowOfScreen(XtScreen(top)),
295 (char *)dot_bits,dot_width,dot_height);
296
297 menuButton[dnum] = XtVaCreateManagedWidget("menuButton",menuButtonWidgetClass,
298 top,NULL);
299
300 menu[dnum] = XtVaCreatePopupShell("menu",simpleMenuWidgetClass,
301 menuButton[dnum],NULL);
302
303 for (i=0; i<MENU_ITEMS; i++)
304 {
305 menu_status[dnum][i]=False;
306 sprintf(entry,"entry%d",i);
307 menu_item[dnum][i] = XtVaCreateManagedWidget(entry,smeBSBObjectClass,
308 menu[dnum],NULL);
309 XtAddCallback(menu_item[dnum][i],XtNcallback,ProcessMenu,top);
310 }
311 }
312
ProcessMenu(Widget w,XtPointer client_data,XtPointer call_data)313 void ProcessMenu(Widget w, XtPointer client_data, XtPointer call_data)
314 {
315 char *name = XtName(w);
316 int sel = name[5] - '0';
317 int i,dnum=0;
318
319 for (i=0; i<num_players; i++)
320 if (w==menu_item[i][sel])
321 dnum=i;
322 if (menu_status[dnum][sel]==False)
323 XtVaSetValues(w,XtNleftBitmap,markmenu[dnum],NULL);
324 else
325 XtVaSetValues(w,XtNleftBitmap,None,NULL);
326 menu_status[dnum][sel]= !menu_status[dnum][sel];
327
328 switch (sel)
329 {
330 case KEY: KeyPopup(dnum);
331 break;
332 case LETTVAL: LettValuesPopup(dnum);
333 break;
334 case RULES: RulesPopup(dnum);
335 break;
336 case HISCORES: HiScoresPopup(dnum);
337 break;
338 case BESTGOES: BestgoPopup(dnum);
339 break;
340 case MESSAGE: MessPopup(dnum);
341 case ABOUT: AboutPopup(dnum);
342 break;
343 default: break;
344 }
345 }
346
ChangePopup()347 void ChangePopup()
348 {
349 Position x, y;
350 int i;
351 char chlet[3];
352
353 waiting_for_change=True;
354 changeshell=XtVaCreatePopupShell("changeshell",transientShellWidgetClass,
355 topl[curr_player],NULL);
356
357 changef=XtVaCreateManagedWidget("changef",formWidgetClass,changeshell,
358 NULL);
359 changetitle=XtVaCreateManagedWidget("changetitle",labelWidgetClass,changef,
360 NULL);
361
362 for (i=0; i<BARLEN; i++)
363 {
364 sprintf(chlet,"%c",player[curr_player].bar[i]);
365 changeletts[i]=XtVaCreateManagedWidget("cl",toggleWidgetClass,changef,
366 XtNfromVert,changetitle,XtNlabel,chlet,NULL);
367 if (player[curr_player].bar[i] != ' ')
368 XtVaSetValues(changeletts[i],SETBG(app_data.tilecolor),NULL);
369 if (i>0)
370 XtVaSetValues(changeletts[i],XtNfromHoriz,changeletts[i-1],NULL);
371 }
372
373 changeconfirm=XtVaCreateManagedWidget("changeconfirm",commandWidgetClass,
374 changef,XtNfromVert,changeletts[0],NULL);
375 changecancel=XtVaCreateManagedWidget("changecancel",commandWidgetClass,
376 changef,XtNfromVert,changeletts[0],XtNfromHoriz,changeconfirm,NULL);
377
378 XtTranslateCoords(change[curr_player],(Position) -10,(Position) -10, &x, &y);
379 XtVaSetValues(changeshell, XtNx, x, XtNy, y, NULL);
380 /* bg_pixmap(changef);*/
381
382 XtPopup(changeshell,XtGrabNonexclusive);
383
384 XtAddCallback(changeconfirm,XtNcallback,ChangePopdown,topLevel);
385 XtAddCallback(changecancel,XtNcallback,ChangePopdown,topLevel);
386 }
387
BlankPopup()388 void BlankPopup()
389 {
390 Position x, y;
391 int i;
392 char chlet[3];
393
394 waiting_for_blank=True;
395 blankshell=XtVaCreatePopupShell("blankshell",transientShellWidgetClass,
396 topl[curr_player],NULL);
397
398 blankf=XtVaCreateManagedWidget("blankf",formWidgetClass,blankshell,
399 NULL);
400 blanktitle=XtVaCreateManagedWidget("blanktitle",labelWidgetClass,blankf,NULL);
401
402 for (i=0; i<NUMLETTERS; i++)
403 {
404 sprintf(chlet,"%c",i+'A');
405 a2z[i]=XtVaCreateManagedWidget("az",commandWidgetClass,blankf,
406 XtNfromVert,blanktitle,XtNlabel,chlet,SETBG(app_data.tilecolor),NULL);
407 if ((i!=0) && (i!=(NUMLETTERS/2)))
408 XtVaSetValues(a2z[i],XtNfromHoriz,a2z[i-1],NULL);
409 if (i>(NUMLETTERS/2)-1)
410 XtVaSetValues(a2z[i],XtNfromVert,a2z[i-(NUMLETTERS/2)],NULL);
411 }
412
413 XtTranslateCoords(finish[curr_player],(Position) -10,(Position) -10, &x, &y);
414 XtVaSetValues(blankshell, XtNx, x, XtNy, y, NULL);
415 /* bg_pixmap(blankf);*/
416
417 XtPopup(blankshell,XtGrabNonexclusive);
418
419 for (i=0; i<NUMLETTERS; i++)
420 XtAddCallback(a2z[i],XtNcallback,BlankPopdown,topLevel);
421 }
422
423
424
425
bg_pixmap(Widget w)426 void bg_pixmap(Widget w)
427 {
428 XtVaSetValues(w,XtNbackgroundPixmap, (XtArgVal)bgxpm, NULL);
429 }
430
431 /* called on receipt of delete signal */
432
InitGame()433 void InitGame()
434 {
435 int i;
436
437 pauseflag = 1;
438 curr_player = (curr_player + num_players -1) % num_players;
439
440 for (i=0; i<num_players; i++)
441 {
442 takeletters(BARLEN,player[i].bar);
443 ShowBar(i);
444 if (type[i]==0)
445 {
446 XtVaSetValues(revert[i], XtNsensitive, True, NULL);
447 XtVaSetValues(juggle[i], XtNsensitive, True, NULL);
448 }
449 if ((time_limit==0) || (type[i]>0))
450 {
451 XtVaSetValues(pauseButton[i], XtNmappedWhenManaged, False, NULL);
452 } else
453 {
454 XtVaSetValues(pauseButton[i], XtNlabel, modepause, XtNmappedWhenManaged, True, XtNsensitive, False, XtNstate, False, NULL);
455 }
456 }
457 TilesLeft();
458 ShowScores();
459 GotoNextPlayer();
460 ShowTiles();
461 ShowBoard(False);
462 }
463
StartPauseToggle(Widget w,XtPointer client_data,XtPointer call_data)464 void StartPauseToggle(Widget w, XtPointer client_data, XtPointer call_data)
465 {
466 char mess[256];
467 int i,j;
468
469 if(pauseflag==2)
470 {
471 j = curr_player;
472 for (i=0; i<num_players; i++) if (w==pauseButton[i]) curr_player=i;
473 if (j!=curr_player)
474 {
475 sprintf(mess,PROMPT[OK_HE_STARTS],player[curr_player].name);
476 MessageAll(mess);
477 } else MessageAll(PROMPT[STARTING_GAME]);
478 InitGame();
479 return;
480 }
481
482 pauseflag=!pauseflag;
483 sprintf(mess, PROMPT[START_PAUSE+pauseflag], player[curr_player].name);
484 MessageAll(mess);
485 }
486
Quit(void)487 void Quit(void)
488 {
489 XtDestroyApplicationContext(app_context);
490 exit(0);
491 }
492