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