1 /*
2  * src/lsetup.c, part of Complete Goban (game program)
3  * Copyright (C) 1995-1996 William Shubert
4  * See "configure.h.in" for more copyright information.
5  */
6 
7 
8 #include <wms.h>
9 #include <but/but.h>
10 #include <but/plain.h>
11 #include <but/menu.h>
12 #include <but/text.h>
13 #include <but/textin.h>
14 #include <but/ctext.h>
15 #include <abut/msg.h>
16 #include <wms/clp.h>
17 #include <wms/str.h>
18 #include "cgoban.h"
19 #include "gameSetup.h"
20 #include "msg.h"
21 #include "help.h"
22 
23 
24 /**********************************************************************
25  * Forward Declarations
26  **********************************************************************/
27 static ButOut  resize(ButWin *win);
28 static ButOut  destroy(ButWin *win);
29 static ButOut  newRules(But *but, int newVal);
30 static ButOut  newSize(But *but, const char *value);
31 static ButOut  newHcap(But *but, const char *value);
32 static ButOut  newKomi(But *but, const char *value);
33 static ButOut  newName(But *but, const char *value);
34 static ButOut  okPressed(But *but);
35 static ButOut  cancelPressed(But *but);
36 static ButOut  newTimeType(But *but, int newVal);
37 static ButOut  newMainTime(But *but, const char *value);
38 static ButOut  newBYTime(But *but, const char *value);
39 static ButOut  newAuxTime(But *but, const char *value);
40 
41 
42 /**********************************************************************
43  * Functions
44  **********************************************************************/
gameSetup_create(Cgoban * cg,void (* callback)(void * packet,GameSetup * gs),void * packet)45 GameSetup  *gameSetup_create(Cgoban *cg,
46 			     void (*callback)(void *packet, GameSetup *gs),
47 			     void *packet)  {
48   GameSetup *ls;
49   int  w, h;
50   char  curText[10];
51 
52   assert(MAGIC(cg));
53   ls = wms_malloc(sizeof(GameSetup));
54   MAGIC_SET(ls);
55   ls->callback = callback;
56   ls->packet = packet;
57   ls->cg = cg;
58   h = cg->fontH * 22 + butEnv_stdBw(cg->env) * 20;
59   w = h * 1.618034 + 0.5;
60   ls->win = butWin_create(ls, cg->env, "Game Setup", w,h,
61 			  NULL, NULL, resize, destroy);
62   butWin_activate(ls->win);
63   ls->bg = butBoxFilled_create(ls->win, 0, BUT_DRAWABLE);
64   butBoxFilled_setPixmaps(ls->bg, cg->bgLitPixmap, cg->bgShadPixmap,
65 			  cg->bgPixmap);
66   ls->title = butText_create(ls->win, 1, BUT_DRAWABLE, msg_gSetup,
67 			     butText_center);
68   butText_setFont(ls->title, 2);
69 
70   ls->namesBox = butBox_create(ls->win, 1, BUT_DRAWABLE);
71   butBox_setPixmaps(ls->namesBox, cg->bgLitPixmap, cg->bgShadPixmap);
72   ls->wStr = butText_create(ls->win, 1, BUT_DRAWABLE,
73 			    msg_wName, butText_left);
74   ls->wIn = butTextin_create(newName, ls, ls->win, 1,
75 			     BUT_PRESSABLE|BUT_DRAWABLE,
76 			     clp_getStr(cg->clp, "local.wName"), 30);
77   ls->bStr = butText_create(ls->win, 1, BUT_DRAWABLE,
78 			    msg_bName, butText_left);
79   ls->bIn = butTextin_create(newName, ls, ls->win, 1,
80 			     BUT_PRESSABLE|BUT_DRAWABLE,
81 			     clp_getStr(cg->clp, "local.bName"), 30);
82 
83   ls->rules = (GoRules)clp_getInt(cg->clp, "game.rules");
84   ls->size = clp_getInt(cg->clp, "game.size");
85   ls->hcap = clp_getInt(cg->clp, "game.handicap");
86   ls->komi = clp_getDouble(cg->clp, "game.komi");
87   ls->sizeSet = FALSE;
88   ls->hcapSet = FALSE;
89   ls->komiSet = FALSE;
90   ls->rulesBox = butBox_create(ls->win, 1, BUT_DRAWABLE);
91   butBox_setPixmaps(ls->rulesBox, cg->bgLitPixmap, cg->bgShadPixmap);
92   ls->rulesMenu = butMenu_downCreate(newRules, ls, ls->win, 1, 2,
93 				     BUT_PRESSABLE|BUT_DRAWABLE,
94 				     msg_ruleSet,
95 				     msg_ruleNames,
96 				     ls->rules);
97   butMenu_setFlags(ls->rulesMenu, (int)goRules_tibetan, BUTMENU_DISABLED);
98   ls->sizeStr = butText_create(ls->win, 1, BUT_DRAWABLE,
99 			       msg_boardSize, butText_center);
100   sprintf(curText, "%d", ls->size);
101   ls->sizeIn = butTextin_create(newSize, ls, ls->win, 1,
102 				BUT_PRESSABLE|BUT_DRAWABLE, curText, 10);
103   ls->hcapStr = butText_create(ls->win, 1, BUT_DRAWABLE,
104 			       msg_handicap, butText_center);
105   sprintf(curText, "%d", ls->hcap);
106   ls->hcapIn = butTextin_create(newHcap, ls, ls->win, 1,
107 				BUT_PRESSABLE|BUT_DRAWABLE, curText, 10);
108   ls->komiStr = butText_create(ls->win, 1, BUT_DRAWABLE,
109 			       msg_komi, butText_center);
110   sprintf(curText, "%g", ls->komi);
111   ls->komiIn = butTextin_create(newKomi, ls, ls->win, 1,
112 				BUT_PRESSABLE|BUT_DRAWABLE, curText, 10);
113 
114   ls->timeBox = butBox_create(ls->win, 1, BUT_DRAWABLE);
115   butBox_setPixmaps(ls->timeBox, cg->bgLitPixmap, cg->bgShadPixmap);
116   ls->timeType = 2;
117   ls->numTimeArgs = 3;
118   ls->timeMenu = butMenu_downCreate(newTimeType, ls, ls->win, 1, 2,
119 				    BUT_PRESSABLE|BUT_DRAWABLE,
120 				    msg_timeSystem,
121 				    msg_timeSystems,
122 				    clp_getInt(cg->clp, "setup.timeType"));
123   ls->mainStr = butText_create(ls->win, 1, BUT_DRAWABLE,
124 			       msg_primaryTime, butText_center);
125   ls->mainIn = butTextin_create(newMainTime, ls, ls->win, 1,
126 				BUT_PRESSABLE|BUT_DRAWABLE,
127 				clp_getStr(cg->clp, "setup.mainTime"), 10);
128   ls->byStr = butText_create(ls->win, 1, BUT_DRAWABLE,
129 			     msg_byoYomi, butText_center);
130   ls->byIn = butTextin_create(newBYTime, ls, ls->win, 1,
131 			      BUT_PRESSABLE|BUT_DRAWABLE,
132 			      clp_getStr(cg->clp, "setup.igsBYTime"), 10);
133   ls->auxStr = butText_create(ls->win, 1, BUT_DRAWABLE,
134 			      msg_byoYomiStones, butText_center);
135   ls->auxIn = butTextin_create(newAuxTime, ls, ls->win, 1,
136 			       BUT_PRESSABLE|BUT_DRAWABLE,
137 			       clp_getStr(cg->clp, "setup.igsBYStones"), 10);
138   ls->timeType = goTime_canadian;
139   ls->mainTime = goTime_parseChars(butTextin_get(ls->mainIn), FALSE, NULL);
140   ls->byTime = goTime_parseChars(butTextin_get(ls->byIn), FALSE, NULL);
141   ls->aux = wms_atoi(butTextin_get(ls->auxIn), NULL);
142   newTimeType(ls->timeMenu, butMenu_get(ls->timeMenu));
143 
144   ls->help = butCt_create(cgoban_createHelpWindow,
145 			  &help_gameSetup, ls->win, 1,
146 			  BUT_DRAWABLE|BUT_PRESSABLE, msg_help);
147   ls->ok = butCt_create(okPressed, ls, ls->win, 1,
148 			BUT_DRAWABLE|BUT_PRESSABLE, msg_ok);
149   ls->cancel = butCt_create(cancelPressed, ls, ls->win, 1,
150 			    BUT_DRAWABLE|BUT_PRESSABLE, msg_cancel);
151   return(ls);
152 }
153 
154 
gameSetup_destroy(GameSetup * ls)155 void  gameSetup_destroy(GameSetup *ls)  {
156   assert(MAGIC(ls));
157   if (ls->callback)  {
158     ls->callback(ls->packet, NULL);
159     ls->callback = NULL;
160   }
161   if (ls->win)
162     butWin_destroy(ls->win);
163   MAGIC_UNSET(ls);
164   wms_free(ls);
165 }
166 
167 
168 
resize(ButWin * win)169 static ButOut  resize(ButWin *win)  {
170   GameSetup  *ls = butWin_packet(win);
171   Cgoban  *cg;
172   int  w, butW, h, x, y;
173   int  bw, fh;
174   ButEnv  *env;
175   int  wStrSize, bStrSize;
176 
177   assert(MAGIC(ls));
178   cg = ls->cg;
179   assert(MAGIC(cg));
180   env = cg->env;
181   bw = butEnv_stdBw(env);
182   fh = cg->fontH;
183   w = butWin_w(win);
184   h = butWin_h(win);
185   butW = w/2-5*bw;
186 
187   but_resize(ls->bg, 0,0, w,h);
188   butText_resize(ls->title, w/2,bw*2, fh*2);
189 
190   but_resize(ls->namesBox, bw,bw*3+fh*2, w-bw*2,bw*4+fh*2);
191   wStrSize = butText_resize(ls->wStr, bw*3, bw*5+fh*2, fh*2);
192   bStrSize = butText_resize(ls->bStr, w/2+bw*2, bw*5+fh*2, fh*2);
193   if (bStrSize > wStrSize)
194     wStrSize = bStrSize;
195   but_resize(ls->wIn, bw*4+wStrSize, bw*5+fh*2,
196 	     w/2 - (bw*6+wStrSize), fh*2);
197   but_resize(ls->bIn, w/2+bw*3+wStrSize, bw*5+fh*2,
198 	     w - (w/2+bw*6+wStrSize), fh*2);
199 
200   y = bw*7+fh*4;
201   but_resize(ls->rulesBox, bw,y, w/2-bw,fh*16+bw*10);
202   but_resize(ls->rulesMenu, bw*3,y+bw*2+fh*0, butW,fh*4);
203 
204   but_resize(ls->sizeStr, bw*3,y+bw*3+fh*4, butW,fh*2);
205   but_resize(ls->sizeIn, bw*3,y+bw*4+fh*6, butW,fh*2);
206 
207   but_resize(ls->hcapStr, bw*3,y+bw*5+fh*8, butW,fh*2);
208   but_resize(ls->hcapIn, bw*3,y+bw*6+fh*10, butW,fh*2);
209 
210   but_resize(ls->komiStr, bw*3,y+bw*7+fh*12, butW,fh*2);
211   but_resize(ls->komiIn, bw*3,y+bw*8+fh*14, butW,fh*2);
212 
213   but_resize(ls->timeBox, w/2,y, w-bw-w/2,fh*16+bw*10);
214   x = w/2 + bw*2;
215   butW = w-x-bw*3;
216   but_resize(ls->timeMenu, x,y+bw*2+fh*0, butW,fh*4);
217 
218   but_resize(ls->mainStr, x,y+bw*3+fh*4, butW,fh*2);
219   but_resize(ls->mainIn, x,y+bw*4+fh*6, butW,fh*2);
220 
221   but_resize(ls->byStr, x,y+bw*5+fh*8, butW,fh*2);
222   but_resize(ls->byIn, x,y+bw*6+fh*10, butW,fh*2);
223 
224   but_resize(ls->auxStr, x,y+bw*7+fh*12, butW,fh*2);
225   but_resize(ls->auxIn, x,y+bw*8+fh*14, butW,fh*2);
226 
227   but_resize(ls->help, bw*2,y+bw*11+fh*16, (w-bw*6+1)/3,fh*2);
228   but_resize(ls->cancel, bw*3+(w-bw*6+1)/3,y+bw*11+fh*16,
229 	     w-2*(bw*3+(w-bw*6+1)/3),fh*2);
230   but_resize(ls->ok, w-(bw*2+(w-bw*6+1)/3),y+bw*11+fh*16,
231 	     (w-bw*6+1)/3,fh*2);
232 
233   return(0);
234 }
235 
236 
destroy(ButWin * win)237 static ButOut  destroy(ButWin *win)  {
238   GameSetup  *ls = butWin_packet(win);
239 
240   assert(MAGIC(ls));
241   ls->win = NULL;  /* It's dead already. */
242   gameSetup_destroy(ls);
243   return(0);
244 }
245 
246 
newRules(But * but,int newVal)247 static ButOut  newRules(But *but, int newVal)  {
248   GameSetup  *ls = but_packet(but);
249 
250   assert(MAGIC(ls));
251   clp_setInt(ls->cg->clp, "game.rules", newVal);
252   if (!ls->sizeSet)  {
253     if (newVal != goRules_tibetan)  {
254       if ((ls->size != 9) && (ls->size != 13) && (ls->size != 19))  {
255 	butTextin_set(ls->sizeIn, "19", FALSE);
256 	clp_setInt(ls->cg->clp, "game.size", 19);
257 	ls->size = 19;
258       }
259     } else  {
260       butTextin_set(ls->sizeIn, "17", FALSE);
261       clp_setInt(ls->cg->clp, "game.size", 17);
262       ls->size = 17;
263     }
264   }
265   if (!ls->komiSet && (ls->hcap == 0) &&
266       (((ls->rules == goRules_ing) && (ls->komi == 8.0)) ||
267        ((ls->rules != goRules_ing) && (ls->komi == 5.5))))  {
268     if (newVal != goRules_ing)  {
269       butTextin_set(ls->komiIn, "5.5", FALSE);
270       clp_setDouble(ls->cg->clp, "game.komi", 5.5);
271       ls->komi = 5.5;
272     } else  {
273       butTextin_set(ls->komiIn, "8", FALSE);
274       clp_setDouble(ls->cg->clp, "game.komi", 8.0);
275       ls->komi = 8.0;
276     }
277   }
278   if (!ls->komiSet && (ls->hcap != 0) &&
279       (((ls->rules == goRules_ing) && (ls->komi == 0.0)) ||
280        ((ls->rules != goRules_ing) && (ls->komi == 0.5))))  {
281     if (newVal != goRules_ing)  {
282       butTextin_set(ls->komiIn, "0.5", FALSE);
283       clp_setDouble(ls->cg->clp, "game.komi", 0.5);
284       ls->komi = 0.5;
285     } else  {
286       butTextin_set(ls->komiIn, "0", FALSE);
287       clp_setDouble(ls->cg->clp, "game.komi", 0.0);
288       ls->komi = 0.0;
289     }
290   }
291   ls->rules = newVal;
292   return(0);
293 }
294 
295 
newSize(But * but,const char * value)296 static ButOut  newSize(But *but, const char *value)  {
297   GameSetup  *ls = but_packet(but);
298   int  newSize;
299   char  curValue[200];
300 
301   assert(MAGIC(ls));
302   newSize = atoi(value);
303   if (!clp_setStr(ls->cg->clp, "game.size", value))  {
304     sprintf(curValue, msg_badSize, value, GOBOARD_MAXSIZE);
305     cgoban_createMsgWindow(ls->cg, "Cgoban Error", curValue);
306     sprintf(curValue, "%d", ls->size);
307     butTextin_set(but, curValue, FALSE);
308     return(BUTOUT_ERR);
309   }
310   ls->sizeSet = TRUE;
311   ls->size = newSize;
312   but_setFlags(ls->hcapIn, BUT_KEYED);
313   return(0);
314 }
315 
316 
newHcap(But * but,const char * value)317 static ButOut  newHcap(But *but, const char *value)  {
318   GameSetup  *ls = but_packet(but);
319   int  newVal = atoi(value);
320   Str  curValue;
321 
322   assert(MAGIC(ls));
323   if (!clp_setStr(ls->cg->clp, "game.handicap", value))  {
324     str_init(&curValue);
325     str_print(&curValue, msg_badHcap, value, 27);
326     cgoban_createMsgWindow(ls->cg, "Cgoban Error", str_chars(&curValue));
327     str_print(&curValue, "%d", ls->hcap);
328     butTextin_set(but, str_chars(&curValue), FALSE);
329     str_deinit(&curValue);
330     return(BUTOUT_ERR);
331   }
332   ls->hcapSet = TRUE;
333   if ((newVal == 1) ||
334       (!ls->komiSet && (ls->hcap == 0) && (newVal != 0) &&
335        (((ls->rules == goRules_ing) && (ls->komi == 8.0)) ||
336 	((ls->rules != goRules_ing) && (ls->komi == 5.5)))))  {
337     ls->komiSet = FALSE;
338     if (ls->rules == goRules_ing)  {
339       butTextin_set(ls->komiIn, "0", FALSE);
340       clp_setDouble(ls->cg->clp, "game.komi", 0.0);
341       ls->komi = 0.0;
342     } else  {
343       butTextin_set(ls->komiIn, "0.5", FALSE);
344       clp_setDouble(ls->cg->clp, "game.komi", 0.5);
345       ls->komi = 0.5;
346     }
347   }
348   if (!ls->komiSet && (ls->hcap > 0) && (newVal == 0) &&
349       ((ls->komi == 0.0) || (ls->komi == 0.5)))  {
350     if (ls->rules == goRules_ing)  {
351       butTextin_set(ls->komiIn, "8", FALSE);
352       clp_setDouble(ls->cg->clp, "game.komi", 8.0);
353       ls->komi = 8.0;
354     } else  {
355       butTextin_set(ls->komiIn, "5.5", FALSE);
356       clp_setDouble(ls->cg->clp, "game.komi", 5.5);
357       ls->komi = 5.5;
358     }
359   }
360   ls->hcap = newVal;
361   but_setFlags(ls->komiIn, BUT_KEYED);
362   return(0);
363 }
364 
365 
366 
newKomi(But * but,const char * value)367 static ButOut  newKomi(But *but, const char *value)  {
368   GameSetup  *ls = but_packet(but);
369   char  curValue[200];
370   bool  komiErr;
371   double  newKomi;
372 
373   assert(MAGIC(ls));
374   newKomi = wms_atof(value, &komiErr);
375   if (!clp_setStr(ls->cg->clp, "game.komi", value))  {
376     sprintf(curValue, msg_badKomi, value);
377     cgoban_createMsgWindow(ls->cg, "Cgoban Error", curValue);
378     sprintf(curValue, "%g", ls->komi);
379     butTextin_set(but, curValue, FALSE);
380     return(BUTOUT_ERR);
381   }
382   ls->komiSet = TRUE;
383   ls->komi = newKomi;
384   but_setFlags(ls->komiIn, BUT_NOKEY);
385   return(0);
386 }
387 
388 
389 
okPressed(But * but)390 static ButOut  okPressed(But *but)  {
391   GameSetup  *ls = but_packet(but);
392   Clp  *clp = ls->cg->clp;
393 
394   assert(MAGIC(ls));
395   if (newSize(ls->sizeIn, butTextin_get(ls->sizeIn)) & BUTOUT_ERR)
396     return(BUTOUT_ERR);
397   if (newHcap(ls->hcapIn, butTextin_get(ls->hcapIn)) & BUTOUT_ERR)
398     return(BUTOUT_ERR);
399   if (newKomi(ls->komiIn, butTextin_get(ls->komiIn)) & BUTOUT_ERR)
400     return(BUTOUT_ERR);
401   if (ls->numTimeArgs >= 1)
402     if (newMainTime(ls->mainIn, butTextin_get(ls->mainIn)) & BUTOUT_ERR)
403       return(BUTOUT_ERR);
404   if (ls->numTimeArgs >= 2)
405     if (newBYTime(ls->byIn, butTextin_get(ls->byIn)) & BUTOUT_ERR)
406       return(BUTOUT_ERR);
407   if (ls->numTimeArgs >= 3)
408     if (newAuxTime(ls->auxIn, butTextin_get(ls->auxIn)) & BUTOUT_ERR)
409       return(BUTOUT_ERR);
410   clp_setInt(clp, "game.size", ls->size);
411   clp_setInt(clp, "game.handicap", ls->hcap);
412   clp_setDouble(clp, "game.komi", ls->komi);
413   clp_setStr(clp, "local.wName", butTextin_get(ls->wIn));
414   clp_setStr(clp, "local.bName", butTextin_get(ls->bIn));
415 
416   if (ls->callback)  {
417     ls->callback(ls->packet, ls);
418     ls->callback = NULL;
419   }
420   butWin_destroy(but_win(but));
421   return(0);
422 }
423 
424 
425 
cancelPressed(But * but)426 static ButOut  cancelPressed(But *but)  {
427   GameSetup  *gs = but_packet(but);
428 
429   assert(MAGIC(gs));
430   if (gs->callback)  {
431     gs->callback(gs->packet, NULL);
432     gs->callback = NULL;
433   }
434   butWin_destroy(but_win(but));
435   return(0);
436 }
437 
438 
newName(But * but,const char * value)439 static ButOut  newName(But *but, const char *value)  {
440   GameSetup  *ls = but_packet(but);
441 
442   assert(MAGIC(ls));
443   if (but == ls->wIn)  {
444     clp_setStr(ls->cg->clp, "local.wName", value);
445     but_setFlags(ls->bIn, BUT_KEYED);
446   } else  {
447     assert(but == ls->bIn);
448     but_setFlags(but, BUT_NOKEY);
449     clp_setStr(ls->cg->clp, "local.bName", value);
450   }
451   return(0);
452 }
453 
454 
newTimeType(But * but,int newVal)455 static ButOut  newTimeType(But *but, int newVal)  {
456   GameSetup  *ls = but_packet(but);
457   GoTimeType  newTime = (GoTimeType)newVal;
458   int  nargs = 0;
459 
460   assert(MAGIC(ls));
461   if (newTime == ls->timeType)
462     return(0);
463   switch(ls->timeType = newTime)  {
464   case goTime_none:
465     nargs = ls->numTimeArgs = 0;
466     break;
467   case goTime_absolute:
468     nargs = ls->numTimeArgs = 1;
469     ls->byTime = 0;  /* Just to make things clear. */
470     break;
471   case goTime_canadian:
472     nargs = ls->numTimeArgs = 3;
473     butTextin_set(ls->byIn, clp_getStr(ls->cg->clp, "setup.igsBYTime"), FALSE);
474     butText_set(ls->auxStr, msg_byoYomiStones);
475     butTextin_set(ls->auxIn, clp_getStr(ls->cg->clp, "setup.igsBYStones"),
476 		  FALSE);
477     break;
478   case goTime_ing:
479     nargs = ls->numTimeArgs = 3;
480     butTextin_set(ls->byIn, clp_getStr(ls->cg->clp, "setup.ingBYTime"), FALSE);
481     butText_set(ls->auxStr, msg_byoYomiCount);
482     butTextin_set(ls->auxIn, clp_getStr(ls->cg->clp, "setup.ingBYPeriods"),
483 		  FALSE);
484     break;
485   case goTime_japanese:
486     nargs = ls->numTimeArgs = 3;
487     butTextin_set(ls->byIn, clp_getStr(ls->cg->clp, "setup.jBYTime"), FALSE);
488     butText_set(ls->auxStr, msg_byoYomiCount);
489     butTextin_set(ls->auxIn, clp_getStr(ls->cg->clp, "setup.jBYPeriods"),
490 		  FALSE);
491   }
492   if (nargs >= 1)  {
493     butText_setColor(ls->mainStr, BUT_FG, FALSE);
494     but_setFlags(ls->mainIn, BUT_PRESSABLE);
495     if (nargs >= 2)  {
496       butText_setColor(ls->byStr, BUT_FG, FALSE);
497       but_setFlags(ls->byIn, BUT_PRESSABLE);
498       if (nargs >= 3)  {
499 	butText_setColor(ls->auxStr, BUT_FG, FALSE);
500 	but_setFlags(ls->auxIn, BUT_PRESSABLE);
501       }
502     }
503   }
504   if (nargs < 3)  {
505     butText_setColor(ls->auxStr, BUT_FG, TRUE);
506     but_setFlags(ls->auxIn, BUT_NOPRESS|BUT_NOKEY);
507     if (nargs < 2)  {
508       butText_setColor(ls->byStr, BUT_FG, TRUE);
509       but_setFlags(ls->byIn, BUT_NOPRESS|BUT_NOKEY);
510       if (nargs < 1)  {
511 	butText_setColor(ls->mainStr, BUT_FG, TRUE);
512 	but_setFlags(ls->mainIn, BUT_NOPRESS|BUT_NOKEY);
513       }
514     }
515   }
516   clp_setInt(ls->cg->clp, "setup.timeType", newVal);
517   return(0);
518 }
519 
520 
newMainTime(But * but,const char * value)521 static ButOut  newMainTime(But *but, const char *value)  {
522   GameSetup  *ls = but_packet(but);
523   Str  errMsg;
524 
525   if (!clp_setStr(ls->cg->clp, "setup.mainTime", value))  {
526     str_init(&errMsg);
527     str_print(&errMsg, msg_badTime, value);
528     cgoban_createMsgWindow(ls->cg, "Cgoban Error", str_chars(&errMsg));
529     goTime_str(ls->mainTime, &errMsg);
530     butTextin_set(but, str_chars(&errMsg), FALSE);
531     str_deinit(&errMsg);
532     return(BUTOUT_ERR);
533   }
534   ls->mainTime = goTime_parseChars(value, FALSE, NULL);
535   if (but_getFlags(ls->byIn) & BUT_PRESSABLE)
536     but_setFlags(ls->byIn, BUT_KEYED);
537   else
538     but_setFlags(but, BUT_NOKEY);
539   return(0);
540 }
541 
542 
newBYTime(But * but,const char * value)543 static ButOut  newBYTime(But *but, const char *value)  {
544   GameSetup  *ls = but_packet(but);
545   Str  errMsg;
546 
547   if (!clp_setStr(ls->cg->clp, "setup.igsBYTime", value))  {
548     str_init(&errMsg);
549     str_print(&errMsg, msg_badTime, value);
550     cgoban_createMsgWindow(ls->cg, "Cgoban Error", str_chars(&errMsg));
551     goTime_str(ls->byTime, &errMsg);
552     butTextin_set(but, str_chars(&errMsg), FALSE);
553     str_deinit(&errMsg);
554     return(BUTOUT_ERR);
555   }
556   ls->byTime = goTime_parseChars(value, FALSE, NULL);
557   but_setFlags(but, BUT_NOKEY);
558   if (but_getFlags(ls->auxIn) & BUT_PRESSABLE)
559     but_setFlags(ls->auxIn, BUT_KEYED);
560   else
561     but_setFlags(but, BUT_NOKEY);
562   return(0);
563 }
564 
565 
newAuxTime(But * but,const char * value)566 static ButOut  newAuxTime(But *but, const char *value)  {
567   GameSetup  *ls = but_packet(but);
568   Str  errMsg;
569 
570   if (!clp_setStr(ls->cg->clp, "setup.igsBYStones", value))  {
571     str_init(&errMsg);
572     if (ls->timeType == goTime_ing)
573       str_print(&errMsg, msg_badBYCount, value);
574     else
575       str_print(&errMsg, msg_badBYStones, value);
576     cgoban_createMsgWindow(ls->cg, "Cgoban Error", str_chars(&errMsg));
577     str_print(&errMsg, "%d", ls->aux);
578     butTextin_set(but, str_chars(&errMsg), FALSE);
579     str_deinit(&errMsg);
580     return(BUTOUT_ERR);
581   }
582   ls->aux = wms_atoi(value, NULL);
583   but_setFlags(but, BUT_NOKEY);
584   return(0);
585 }
586