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