1 /* $Id: win.c,v 1.9 2002/03/02 21:02:21 sverrehu Exp $ */
2 /**************************************************************************
3  *
4  *  FILE            win.c
5  *  MODULE OF       Card game.
6  *
7  *  WRITTEN BY      Sverre H. Huseby <shh@thathost.com>
8  *
9  **************************************************************************/
10 
11 #include <stdlib.h>
12 #include <time.h>
13 
14 #include <X11/Xlib.h>
15 #include <X11/Intrinsic.h>
16 #include <X11/StringDefs.h>
17 #include <X11/Core.h>
18 #include <X11/Xaw/Command.h>
19 #include <X11/Xaw/Label.h>
20 #include <X11/Xaw/Form.h>
21 
22 #include <shhmsg.h>
23 #include <shhcards.h>
24 
25 #include "game.h"
26 #include "score.h"
27 #include "board.h"
28 #include "options.h"
29 #include "about.h"
30 #include "highscores.h"
31 #include "readme.h"
32 #include "win.h"
33 
34 /* undo capabilities are not yet written. */
35 #undef UNDO
36 
37 /* put menu buttons at bottom instead of at top? */
38 #define BUTTONS_AT_BOTTOM
39 
40 /**************************************************************************
41  *                                                                        *
42  *                       P R I V A T E    D A T A                         *
43  *                                                                        *
44  **************************************************************************/
45 
46 #define SCORE_STAT_DELAY 30000
47 
48 #ifdef UNDO
49 static Widget undoWidget;
50 #endif
51 static XtIntervalId timerId;
52 static XtIntervalId scoreTimerId;
53 static int timerRunning = 0;
54 
55 
56 
57 /**************************************************************************
58  *                                                                        *
59  *                        P U B L I C    D A T A                          *
60  *                                                                        *
61  **************************************************************************/
62 
63 Display *winDisplay;
64 
65 XtAppContext winAppContext;
66 Widget winTopLevel;
67 Widget winMainWindow;
68 Widget boardWidget;
69 Widget timeWidget;
70 Widget aboutButton;
71 Widget highscoresButton;
72 Widget readmeButton;
73 
74 
75 
76 /**************************************************************************
77  *                                                                        *
78  *                   P R I V A T E    F U N C T I O N S                   *
79  *                                                                        *
80  **************************************************************************/
81 
82 static void
winGetAndHandleEvent(void)83 winGetAndHandleEvent(void)
84 {
85     XEvent e;
86 
87     XtAppNextEvent(winAppContext, &e);
88     if (e.xany.window == boardWin)
89 	boardHandleEvent(&e);
90     else if (e.xany.window == boardPopup)
91 	boardHandlePopupEvent(&e);
92     else
93 	XtDispatchEvent(&e);
94 }
95 
96 static void
callbackQuit(Widget w,XtPointer clientData,XtPointer callData)97 callbackQuit(Widget w, XtPointer clientData, XtPointer callData)
98 {
99     gameExit = 1;
100 }
101 
102 static void
callbackNewGame(Widget w,XtPointer clientData,XtPointer callData)103 callbackNewGame(Widget w, XtPointer clientData, XtPointer callData)
104 {
105     gameFinishGame();
106     gameInitGame();
107 }
108 
109 static void
callbackOptions(Widget w,XtPointer clientData,XtPointer callData)110 callbackOptions(Widget w, XtPointer clientData, XtPointer callData)
111 {
112     optionsPopup();
113 }
114 
115 #ifdef UNDO
116 static void
callbackUndo(Widget w,XtPointer clientData,XtPointer callData)117 callbackUndo(Widget w, XtPointer clientData, XtPointer callData)
118 {
119 }
120 #endif
121 
122 static void
timerProc(XtPointer foo,XtIntervalId * bar)123 timerProc(XtPointer foo, XtIntervalId *bar)
124 {
125     if (gameRunning && timerRunning)
126 	timerId = XtAppAddTimeOut(winAppContext, 1000, timerProc, 0);
127     gameUpdateTime();
128 }
129 
130 static void
scoreTimerProc(XtPointer foo,XtIntervalId * bar)131 scoreTimerProc(XtPointer foo, XtIntervalId *bar)
132 {
133     scoreTimerId = XtAppAddTimeOut(winAppContext, SCORE_STAT_DELAY,
134 				   scoreTimerProc, 0);
135     scoreStatHighscoreFile();
136 }
137 
138 static void
callbackAbout(Widget w,XtPointer clientData,XtPointer callData)139 callbackAbout(Widget w, XtPointer clientData, XtPointer callData)
140 {
141     aboutPopup();
142 }
143 
144 static void
callbackHighscores(Widget w,XtPointer clientData,XtPointer callData)145 callbackHighscores(Widget w, XtPointer clientData, XtPointer callData)
146 {
147     highscoresPopup();
148 }
149 
150 static void
callbackReadme(Widget w,XtPointer clientData,XtPointer callData)151 callbackReadme(Widget w, XtPointer clientData, XtPointer callData)
152 {
153     readmePopup();
154 }
155 
156 
157 
158 /**************************************************************************
159  *                                                                        *
160  *                    P U B L I C    F U N C T I O N S                    *
161  *                                                                        *
162  **************************************************************************/
163 
164 void
winParseOptions(int * argc,char * argv[])165 winParseOptions(int *argc, char *argv[])
166 {
167     static String resources[] = {
168 	"*board.background: " BOARD_BACKGROUND_COLOR,
169 	"*board.foreground: magenta",
170 	"*font: 9x15bold",
171 	"*copyright*font: 6x10",
172 	"*status*font: 6x10",
173 	"*highscores*font: 6x10",
174 	"*readme*font: 6x10",
175 	NULL
176     };
177 
178     winTopLevel = XtVaAppInitialize(&winAppContext, "Sol",
179                                     NULL, 0, argc, argv, resources, NULL);
180     winDisplay = XtDisplay(winTopLevel);
181 }
182 
183 void
winInit(void)184 winInit(void)
185 {
186     Widget quitWidget, newWidget, optWidget;
187 
188     optionsInit(winTopLevel);
189     aboutInit(winTopLevel);
190     highscoresInit(winTopLevel);
191     readmeInit(winTopLevel);
192     winMainWindow
193 	= XtVaCreateManagedWidget("mainWindow",
194 				  formWidgetClass, winTopLevel,
195 				  NULL);
196 #ifdef BUTTONS_AT_BOTTOM
197     /* otherwise, board is set up last. see below. */
198     boardWidget
199 	= XtVaCreateManagedWidget("board",
200 				  coreWidgetClass, winMainWindow,
201 				  XtNwidth, boardWidth,
202 				  XtNheight, boardHeight,
203 				  XtNborderWidth, 1,
204 				  NULL);
205 #endif
206     quitWidget
207 	= XtVaCreateManagedWidget("quit",
208 				  commandWidgetClass, winMainWindow,
209 				  XtNlabel, "Quit",
210 #ifdef BUTTONS_AT_BOTTOM
211 				  XtNfromVert, boardWidget,
212 #endif
213 				  NULL);
214     newWidget
215 	= XtVaCreateManagedWidget("new",
216 				  commandWidgetClass, winMainWindow,
217 				  XtNlabel, "New game",
218 				  XtNfromHoriz, quitWidget,
219 #ifdef BUTTONS_AT_BOTTOM
220 				  XtNfromVert, boardWidget,
221 #endif
222 				  NULL);
223     optWidget
224 	= XtVaCreateManagedWidget("options",
225 				  commandWidgetClass, winMainWindow,
226 				  XtNlabel, "Options",
227 				  XtNfromHoriz, newWidget,
228 #ifdef BUTTONS_AT_BOTTOM
229 				  XtNfromVert, boardWidget,
230 #endif
231 				  NULL);
232 #ifdef UNDO
233     undoWidget
234 	= XtVaCreateManagedWidget("undo",
235 				  commandWidgetClass, winMainWindow,
236 				  XtNlabel, "Undo",
237 				  XtNsensitive, 0,
238 				  XtNfromHoriz, optWidget,
239 #ifdef BUTTONS_AT_BOTTOM
240 				  XtNfromVert, boardWidget,
241 #endif
242 				  NULL);
243 #endif
244     highscoresButton
245 	= XtVaCreateManagedWidget("highscoresButton",
246 				  commandWidgetClass, winMainWindow,
247 				  XtNlabel, "Highscores",
248 #ifdef UNDO
249 				  XtNfromHoriz, undoWidget,
250 #else
251 				  XtNfromHoriz, optWidget,
252 #endif
253 #ifdef BUTTONS_AT_BOTTOM
254 				  XtNfromVert, boardWidget,
255 #endif
256 				  NULL);
257     aboutButton
258 	= XtVaCreateManagedWidget("aboutButton",
259 				  commandWidgetClass, winMainWindow,
260 				  XtNlabel, "About",
261 				  XtNfromHoriz, highscoresButton,
262 #ifdef BUTTONS_AT_BOTTOM
263 				  XtNfromVert, boardWidget,
264 #endif
265 				  NULL);
266     readmeButton
267 	= XtVaCreateManagedWidget("readmeButton",
268 				  commandWidgetClass, winMainWindow,
269 				  XtNlabel, "Help",
270 				  XtNfromHoriz, aboutButton,
271 #ifdef BUTTONS_AT_BOTTOM
272 				  XtNfromVert, boardWidget,
273 #endif
274 				  NULL);
275     timeWidget
276 	= XtVaCreateManagedWidget("time",
277 				  labelWidgetClass, winMainWindow,
278 				  XtNlabel, "Time:   0:00",
279 				  XtNfromHoriz, readmeButton,
280 				  XtNsensitive, 0,
281 #ifdef BUTTONS_AT_BOTTOM
282 				  XtNfromVert, boardWidget,
283 #endif
284 				  NULL);
285 #ifndef BUTTONS_AT_BOTTOM
286     /* otherwise, board is set up first. see above. */
287     boardWidget
288 	= XtVaCreateManagedWidget("board",
289 				  coreWidgetClass, winMainWindow,
290 				  XtNwidth, boardWidth,
291 				  XtNheight, boardHeight,
292 				  XtNfromVert, quitWidget,
293 				  XtNborderWidth, 1,
294 				  NULL);
295 #endif
296 
297     XtAddCallback(quitWidget, XtNcallback, callbackQuit, 0);
298     XtAddCallback(newWidget, XtNcallback, callbackNewGame, 0);
299     XtAddCallback(optWidget, XtNcallback, callbackOptions, 0);
300 #ifdef UNDO
301     XtAddCallback(undoWidget, XtNcallback, callbackUndo, 0);
302 #endif
303     XtAddCallback(aboutButton, XtNcallback, callbackAbout, 0);
304     XtAddCallback(highscoresButton, XtNcallback, callbackHighscores, 0);
305     XtAddCallback(readmeButton, XtNcallback, callbackReadme, 0);
306 
307     XtRealizeWidget(winTopLevel);
308 
309     boardWin = XtWindowOfObject(boardWidget);
310     scoreTimerId = XtAppAddTimeOut(winAppContext, SCORE_STAT_DELAY,
311 				   scoreTimerProc, 0);
312 }
313 
314 void
winFinish(void)315 winFinish(void)
316 {
317     readmeFinish();
318     highscoresFinish();
319     aboutFinish();
320     optionsFinish();
321 }
322 
323 void
winInitGame(void)324 winInitGame(void)
325 {
326     if (gameDoTiming)
327 	XtSetSensitive(timeWidget, 1);
328     winShowTime();
329     XtRemoveTimeOut(scoreTimerId);
330     scoreTimerId = XtAppAddTimeOut(winAppContext, SCORE_STAT_DELAY,
331 				   scoreTimerProc, 0);
332 }
333 
334 void
winFinishGame(void)335 winFinishGame(void)
336 {
337     if (timerRunning) {
338 	XtRemoveTimeOut(timerId);
339 	timerRunning = 0;
340     }
341 #ifdef UNDO
342     XtSetSensitive(undoWidget, 0);
343 #endif
344     XtSetSensitive(timeWidget, 0);
345 }
346 
347 void
winMainLoop(void)348 winMainLoop(void)
349 {
350     while (!gameExit)
351 	winGetAndHandleEvent();
352 }
353 
354 void
winFlush(void)355 winFlush(void)
356 {
357     XFlush(winDisplay);
358 }
359 
360 void
winShowTime(void)361 winShowTime(void)
362 {
363     char text[40];
364 
365     if (!gameDoTiming)
366 	return;
367     sprintf(text, "Time: %6.6s", gameTimeToStr(gameTime));
368     XtVaSetValues(timeWidget, XtNlabel, text, NULL);
369     winFlush();
370 }
371 
372 void
winStartTiming(void)373 winStartTiming(void)
374 {
375     if (timerRunning)
376 	return;
377     timerId = XtAppAddTimeOut(winAppContext, 1000, timerProc, 0);
378     timerRunning = 1;
379 }
380