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 /* setup.c - gets setup details from user */
16 
17 #include "scrab.h"
18 #include "globals.h"
19 #include "slate_green.xpm"
20 
21 #define TIME_INTS 7
22 #define HILIGHT "yellow"
23 #define NORMAL "green"
24 
25 static char * helpstring =
26 "Copyright 1992, \n\
27 Dan R. Greening, Didier Tallot, Phill Everson, and Martyn Shortley.\n\
28 \n";
29 
30 void ShowHelp();
31 void Mode();
32 void Start();
33 void Quit();
34 void Tog_vis();
35 void Cycle();
36 
37 char app_def_file[256]="XScrabble";
38 
39 XtAppContext app_context;
40 
41 Widget topLevel,setup,num_ply,levels,curr_entry,
42        lang_sel,bell_vol,help,help_frame,start,quit,sload,
43        title,timetitle,nametitle,disptitle,typetitle,
44        langtitle,belltitle,help_text,
45        name[MAXPLAYERS],tog[MAXPLAYERS],disp[MAXPLAYERS],wtype[MAXPLAYERS],
46        timet[TIME_INTS],help_item[8];
47 
48 Pixmap bgxpm;
49 XtTranslations storedt;
50 
51 int  timevalue[TIME_INTS];
52 char cycle_text[NUM_TYPES+1][25];
53 char help_line[20][80];
54 
55 static String curr_trans = "#override\n\
56 	<Key>Tab: Move(t)\n\
57 	<Key>Return: Move(r)\n\
58 	Ctrl<Key>R: no-op()\n\
59 	Ctrl<Key>S:	no-op()\n\
60 	Meta<Key>I:	no-op()";
61 static String other_trans = "#override\n\
62 		<Key>: KeyRedirect()";
63 
64 char lang_str[80] = "";
65 
Quit()66 void Quit()
67 {
68     XtDestroyApplicationContext(app_context);
69     exit(0);
70 }
71 
72 /* application data structure */
73 struct sAppData {
74         int version;
75 } sapp_data;
76 
77 /* option types and default values */
78 static XtResource resources[] =
79 {
80 	{"version","Version",XtRInt,sizeof(int),XtOffsetOf(struct sAppData,version),
81 		XtRImmediate,(XtPointer) 0},
82 };
83 
Tog2Int()84 int Tog2Int()
85 {
86 	/* get selected toggle, and convert to int */
87 	char sw[5];
88 
89 	strcpy(sw,XawToggleGetCurrent(tog[0]));
90 	return (sw[3] - '0'+1);
91 }
92 
MakeNotCurrent()93 void MakeNotCurrent()
94 {
95 	XtVaSetValues(curr_entry,XtNtranslations,
96 		XtParseTranslationTable(other_trans),SETBG(NORMAL),NULL);
97 	XawTextDisplayCaret(curr_entry,False);
98 }
99 
MakeCurrent()100 void MakeCurrent()
101 {
102 	XtVaSetValues(curr_entry,XtNtranslations,storedt,SETBG(HILIGHT),NULL);
103 	XawTextDisplayCaret(curr_entry,True);
104 }
105 
KeyRedirect(Widget w,XEvent * event,String * params,Cardinal num_params)106 void KeyRedirect(Widget w, XEvent *event,String *params,Cardinal num_params)
107 {
108  	if (w!=curr_entry)
109  	{
110 	    event->xany.window = XtWindow(curr_entry);
111 	    XtDispatchEvent(event);
112 	}
113 }
114 
Move(Widget w,XEvent * event,String * params,Cardinal num_params)115 void Move(Widget w, XEvent *event,String *params,Cardinal num_params)
116 {
117 	int wnum=0,i,isname=True;
118 	Boolean istab = (params[0][0] == 't');
119 
120 	for (i=0; i<MAXPLAYERS; i++)
121 		if (w==name[i])
122 			wnum=i;
123 	for (i=0; i<MAXPLAYERS; i++)
124 		if (w==disp[i])
125 		{
126 			wnum=i;
127 			isname=False;
128 		}
129 	MakeNotCurrent();
130 	if (istab)
131 		if (isname)
132 			curr_entry = disp[wnum];
133 		else
134 			curr_entry = name[(wnum+1) % Tog2Int()];
135 	else
136 		if (isname)
137 			if ((wnum+1)==Tog2Int())
138 				curr_entry = disp[0];
139 			else
140 				curr_entry = name[wnum+1];
141 		else
142 			if ((wnum+1)==Tog2Int())
143 				curr_entry = name[0];
144 			else
145 				curr_entry = disp[wnum+1];
146 	MakeCurrent();
147 }
148 
HandleMouse(Widget w,XtPointer unused,register XEvent * event,Boolean * cont)149 void HandleMouse(Widget w,XtPointer unused,register XEvent *event,Boolean *cont)
150 {
151 	if (w!=curr_entry)
152 	{
153 		MakeNotCurrent();
154 		curr_entry=w;
155 		MakeCurrent();
156 	}
157 }
158 
main(int argc,char ** argv)159 int main(int argc,char **argv)
160 {
161         Dimension width;
162 	int ply,tn,ind,i,j;
163 	char wname[12];
164         char entry[8];
165         String time_str,level_str,help_str;
166 
167 	static XtActionsRec actions[] = {
168 		{"KeyRedirect", (XtActionProc) KeyRedirect},
169 		{"Move", (XtActionProc) Move},
170 	};
171 	/* to set radio toggles to "exactly one of many" mode */
172 	static String togtrans = "#override\n\
173 		<EnterWindow>:	highlight(Always)\n\
174 		<LeaveWindow>:	unhighlight()\n\
175 		<Btn1Down>,<Btn1Up>:	set() notify()";
176 
177         for(i=0;i<argc-1;i++)
178         {
179             if(strncmp(argv[i],"-language",5)==0)
180                {
181                strcat(app_def_file,"_");
182                strcat(app_def_file,argv[i+1]);
183                strcpy(lang_str,argv[i+1]);
184 	       }
185 	}
186 
187 	topLevel = XtVaAppInitialize(&app_context,app_def_file,NULL,0,
188 		&argc,argv,NULL,NULL);
189 
190 	XtVaGetApplicationResources(topLevel,&sapp_data,resources,
191 		XtNumber(resources),NULL);
192 
193 	if (sapp_data.version == 0)
194 	{
195 		fprintf(stderr,"Couldn't find resource file %s.\n",app_def_file);
196 		exit(1);
197 	} else
198 	if (sapp_data.version != VERSION)
199 	{
200 		fprintf(stderr,
201  "Incompatible app-defaults %s file: v%1.2f versus v%1.2f program!\n",
202          app_def_file, (float)sapp_data.version/100, (float)VERSION/100);
203 		exit(1);
204 	}
205 
206 	setup = XtVaCreateManagedWidget("setup", formWidgetClass,topLevel,
207 			XtNtranslations,XtParseTranslationTable(other_trans),
208 			NULL);
209 
210 	title = XtVaCreateManagedWidget("title", labelWidgetClass, setup,
211 			NULL);
212 	num_ply = XtVaCreateManagedWidget("num_ply", labelWidgetClass, setup,
213 			NULL);
214 
215 	for (tn=0; tn<MAXPLAYERS; tn++)
216 	{
217 		sprintf(wname,"tog%d",tn);
218 		tog[tn]= XtVaCreateManagedWidget(wname, toggleWidgetClass, setup,
219 			XtNtranslations,XtParseTranslationTable(togtrans),NULL);
220 	}
221 
222 	timetitle = XtVaCreateManagedWidget("timetitle", labelWidgetClass, setup,
223 			NULL);
224 
225 	for (tn=0; tn<TIME_INTS; tn++)
226 	{
227 		sprintf(wname,"timet%d",tn);
228 		timet[tn]= XtVaCreateManagedWidget(wname, toggleWidgetClass, setup,
229 			XtNtranslations,XtParseTranslationTable(togtrans),NULL);
230                 XtVaGetValues(timet[tn],XtNlabel,&time_str,NULL);
231                 if(tn==0) timevalue[tn]=0; else timevalue[tn] = atoi(time_str);
232 	}
233 
234 	nametitle = XtVaCreateManagedWidget("nametitle", labelWidgetClass, setup,
235 			NULL);
236 	disptitle = XtVaCreateManagedWidget("disptitle", labelWidgetClass, setup,
237 			NULL);
238 	typetitle = XtVaCreateManagedWidget("typetitle", labelWidgetClass, setup,
239 			NULL);
240 
241         levels = XtVaCreateManagedWidget("levels", labelWidgetClass, setup, NULL);
242         XtVaSetValues(levels,XtNmappedWhenManaged,False,NULL);
243         XtVaSetValues(levels,XtNwidth,1,NULL);
244         XtVaGetValues(levels,XtNlabel,&level_str,NULL);
245 
246         i=0; j=0;
247         for (ind=0;ind<strlen(level_str);ind++)
248 	{
249 	    if(level_str[ind]!='\n')
250 	    {
251                     cycle_text[i][j]=level_str[ind];
252                     j++;
253 	    } else
254 	    {
255                     cycle_text[i][j]='\0';
256                     if(i<NUM_TYPES) i++;
257                     j=0;
258 	    }
259 	}
260 
261         strcpy(level_str,cycle_text[1]);
262 
263         for(i=1;i<NUM_TYPES;i++)
264           sprintf(cycle_text[i],"%s(%d) %s", level_str, i, cycle_text[i+1]);
265 
266 	for (ply=0; ply<MAXPLAYERS; ply++)
267 	{
268 		sprintf(wname,"name%d",ply);
269 		name[ply] = XtVaCreateManagedWidget(wname,
270                         asciiTextWidgetClass, setup,XtNtranslations,
271 			XtParseTranslationTable((ply==0) ? curr_trans : other_trans),NULL);
272 		if (ply==0)
273 			XtVaSetValues(name[ply],SETBG(HILIGHT),NULL);
274 		else
275 			XawTextDisplayCaret(name[ply],False);
276 		sprintf(wname,"disp%d",ply);
277 		disp[ply] = XtVaCreateManagedWidget(wname, asciiTextWidgetClass, setup,
278 			XtNtranslations,XtParseTranslationTable(other_trans),
279 			XtNfromHoriz,name[ply],XtNstring,":0.0",NULL);
280 		XawTextDisplayCaret(disp[ply],False);
281 		sprintf(wname,"type%d",ply);
282 		wtype[ply] = XtVaCreateManagedWidget(wname, commandWidgetClass, setup,
283 			XtNfromHoriz,disp[ply],XtNlabel,cycle_text[0],NULL);
284 		XtAddEventHandler(name[ply],ButtonPressMask,False,HandleMouse,NULL);
285 		XtAddEventHandler(disp[ply],ButtonPressMask,False,HandleMouse,NULL);
286 	}
287 	curr_entry=name[0];
288 
289 	langtitle = XtVaCreateManagedWidget("langtitle", labelWidgetClass, setup, NULL);
290 	belltitle = XtVaCreateManagedWidget("belltitle", labelWidgetClass, setup, NULL);
291 
292 	help = XtVaCreateManagedWidget("help", menuButtonWidgetClass, setup, NULL);
293 
294 	help_frame = XtVaCreatePopupShell("menu", simpleMenuWidgetClass,
295                                      help, NULL );
296 
297         XtVaGetValues(help,XtNlabel,&help_str,XtNwidth,&width,NULL);
298 
299         i=0; j=0;
300 
301         for (ind=0; ind<strlen(help_str); ind++)
302 	{
303 	    if (help_str[ind]=='\n')
304 	    {
305                     help_line[i][j]='\0';
306                     i++;
307                     j=0;
308 	    } else
309 	    {
310                     help_line[i][j]=help_str[ind];
311                     j++;
312 	    }
313 	}
314 
315         XtVaSetValues(help,XtNlabel,help_line[0],XtNwidth,width,NULL);
316 
317         for(j=0; j<i; j++)
318 	{
319 		sprintf(entry,"entry%d",j);
320 		help_item[j] = XtVaCreateManagedWidget(entry,smeBSBObjectClass,help_frame,NULL);
321                 XtVaSetValues(help_item[j],XtNlabel,help_line[j+1],NULL);
322 	}
323 
324 	lang_sel = XtVaCreateManagedWidget("lang_sel", asciiTextWidgetClass, setup, NULL);
325         XtVaSetValues(lang_sel,XtNstring,lang_str,NULL);
326 
327 	XtAddEventHandler(lang_sel,ButtonPressMask,False,HandleMouse,NULL);
328 
329 	bell_vol = XtVaCreateManagedWidget("bell", asciiTextWidgetClass, setup, NULL);
330 	XtVaSetValues(bell_vol,XtNstring,"50",NULL);
331 
332 	XtAddEventHandler(bell_vol,ButtonPressMask,False,HandleMouse,NULL);
333 
334 	start = XtVaCreateManagedWidget("start", commandWidgetClass, setup, NULL);
335 	sload = XtVaCreateManagedWidget("load", commandWidgetClass, setup, NULL);
336 	quit = XtVaCreateManagedWidget("quit", commandWidgetClass, setup, NULL);
337 	XtAddCallback(help,XtNcallback,ShowHelp,topLevel);
338 	XtAddCallback(start,XtNcallback,Start,topLevel);
339 	XtAddCallback(sload,XtNcallback,Start,topLevel);
340 	XtAddCallback(quit,XtNcallback,Quit,topLevel);
341 
342 	for (ply=0; ply<MAXPLAYERS; ply++)
343 	{
344 		XtAddCallback(tog[ply],XtNcallback,Tog_vis,setup);
345 		XtAddCallback(wtype[ply],XtNcallback,Cycle,setup);
346 	}
347 
348 	load_data_pixmap(slate_green_xpm,&bgxpm,topLevel);
349 	bg_pixmap(setup);
350 	bg_pixmap(title);
351 	bg_pixmap(nametitle);
352 	bg_pixmap(disptitle);
353 	bg_pixmap(typetitle);
354 	bg_pixmap(num_ply);
355 	bg_pixmap(timetitle);
356         bg_pixmap(langtitle);
357         bg_pixmap(belltitle);
358 
359 	XtAppAddActions(app_context,actions,XtNumber(actions));
360 	XtRealizeWidget(topLevel);
361 
362 	XtVaGetValues(name[0],XtNtranslations,&storedt,NULL);
363 
364 	XtAppMainLoop(app_context);
365         return 0;
366 }
367 
Cycle(Widget w,XtPointer client_data,XtPointer csetup_data)368 void Cycle(Widget w, XtPointer client_data, XtPointer csetup_data)
369 {
370 	String ctext;
371 	int i,curr=0;
372 
373 	XtVaGetValues(w,XtNlabel,&ctext,NULL);
374 	for (i=0; i<NUM_TYPES; i++)
375 	    if (!strcmp(cycle_text[i],ctext))
376 		curr=i+1;
377 
378 	XtVaSetValues(w,XtNlabel,cycle_text[(curr<NUM_TYPES) ? curr : 0],NULL);
379 }
380 
Tog_vis(Widget w,XtPointer client_data,XtPointer csetup_data)381 void Tog_vis(Widget w, XtPointer client_data, XtPointer csetup_data)
382 {
383 	int i,num;
384 	Boolean st;
385 
386 	/* if toggle is now selected */
387 	XtVaGetValues(w,XtNstate,&st,NULL);
388 	if (st==True)
389 	{
390 		num = Tog2Int();
391 		for (i=0; i<num; i++)
392 		{
393 			XtVaSetValues(name[i],XtNmappedWhenManaged,True,NULL);
394 			XtVaSetValues(disp[i],XtNmappedWhenManaged,True,NULL);
395 			XtVaSetValues(wtype[i],XtNmappedWhenManaged,True,NULL);
396 		}
397 		for (i=num; i<MAXPLAYERS; i++)
398 		{
399 			XtVaSetValues(name[i],XtNmappedWhenManaged,False,NULL);
400 			XtVaSetValues(disp[i],XtNmappedWhenManaged,False,NULL);
401 			XtVaSetValues(wtype[i],XtNmappedWhenManaged,False,NULL);
402 
403 			/* check if selected entry box has been unmanaged */
404 			if ((name[i]==curr_entry) || (disp[i]==curr_entry))
405 			{
406 				/* make first entry the current one */
407 				MakeNotCurrent();
408 				curr_entry = name[0];
409 				MakeCurrent();
410 			}
411 		}
412 	}
413 }
414 
ShowHelp(Widget w,XtPointer client_data,XtPointer csetup_data)415 void ShowHelp(Widget w, XtPointer client_data, XtPointer csetup_data)
416 {
417 
418         help_text = XtVaCreateManagedWidget( "helptext", asciiTextWidgetClass, help_frame,
419                                        XtNstring, (XtArgVal)helpstring,
420                                        XtNlength, (XtArgVal)(strlen(helpstring\
421 )+1),
422                                        NULL );
423 
424 }
425 
Start(Widget w,XtPointer client_data,XtPointer csetup_data)426 void Start(Widget w, XtPointer client_data, XtPointer csetup_data)
427 {
428 	char sw[12],com[512];
429 	String ply_name,disp_name,type_name,lang_name,bell_answer;
430 	int i,j,num_players,time_val,time_lim,curr=0;
431         long int bell_level;
432         char **ptr;
433         Boolean st;
434 
435 	strcpy(com,"xscrab");
436 	num_players=Tog2Int();
437 	sprintf(&com[strlen(com)]," -players %d",num_players);
438 
439 	strcpy(sw,XawToggleGetCurrent(timet[0]));
440 	time_val=sw[5] - '0';
441 	time_lim=timevalue[time_val];
442 	sprintf(&com[strlen(com)]," -time %d",time_lim);
443 
444 	/* get names and displays */
445 	for (i=0; i<num_players; i++)
446 	{
447 		XtVaGetValues(name[i],XtNstring,&ply_name,NULL);
448 		XtVaGetValues(disp[i],XtNstring,&disp_name,NULL);
449 		XtVaGetValues(wtype[i],XtNlabel,&type_name,NULL);
450 
451 		if (strlen(ply_name)>0)
452 			sprintf(&com[strlen(com)]," -n%d \"%.14s\"",i+1,ply_name);
453 		if (strlen(disp_name)>0)
454 			sprintf(&com[strlen(com)]," -d%d %s",i+1,disp_name);
455 		for (j=0; j<NUM_TYPES; j++)
456 			if (!strcmp(cycle_text[j],type_name))
457 				curr=j;
458 		sprintf(&com[strlen(com)]," -t%d %d",i+1,curr);
459 	}
460 
461 	XtVaGetValues(lang_sel,XtNstring,&lang_name,NULL);
462 	XtVaGetValues(bell_vol,XtNstring,&bell_answer,NULL);
463 
464         if (strlen(lang_name)>0) {
465           sprintf(&com[strlen(com)]," -language %s",lang_name);
466 	}
467 
468         if (strlen(bell_answer)>0) {
469           ptr=malloc(16);
470           bell_level=strtol(bell_answer,ptr,10);
471           if (**ptr==0)
472 	  	{
473                 if (bell_level<0) bell_level=0;
474                 if (bell_level>100) bell_level=100;
475           	sprintf(&com[strlen(com)]," -bell %d",bell_level);
476 	  	}
477 	}
478 
479 	if (w==sload)
480 		strcat(com," -load");
481 
482 	strcat(com," &");
483 	printf("%s\n",com);
484 	system(com);
485 	/* XtDestroyWidget(topLevel);
486 	exit(0); */
487 }
488 
load_pixmap(char * fname,Pixmap * xpm,Widget top)489 void load_pixmap(char *fname, Pixmap *xpm,Widget top)
490 {
491 	int status;
492 	XpmAttributes attr;
493 	Pixmap mask;
494 
495 	attr.valuemask = XpmReturnPixels | XpmCloseness;
496 	status = XpmReadFileToPixmap(XtDisplay(top),
497              DefaultRootWindow(XtDisplay(top)),fname,xpm,&mask,&attr);
498 	if (status != XpmSuccess)
499 	{
500 			fprintf(stderr,"Pixmap error: %s\n",XpmGetErrorString(status));
501 			exit(0);
502  	}
503 }
504 
bg_pixmap(Widget w)505 void bg_pixmap(Widget w)
506 {
507 	XtVaSetValues(w,XtNbackgroundPixmap, (XtArgVal)bgxpm, NULL);
508 }
509