1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "x11.h"
5 #include "x11-athena.h"
6
7 #include <X11/Xaw/XawInit.h>
8 #include <X11/Xaw/Label.h>
9 #include <X11/Xaw/Box.h>
10 #include <X11/Xaw/MenuButton.h>
11 #include <X11/Xaw/SimpleMenu.h>
12 #include <X11/Xaw/SmeBSB.h>
13 #include <X11/Xaw/SmeLine.h>
14 #include <X11/Xaw/AsciiText.h>
15
16 #include "util.h"
17
18 #include "Game.h"
19 #include "UI.h"
20
21 static Widget base, menubar, field;
22 static Widget dialogs[DIALOG_MAX + 1];
23 static Widget pausebutton;
24
25 static void
x11_athena_popup_dialog(int index)26 x11_athena_popup_dialog(int index) {
27 x11_popup(dialogs[index]);
28 }
29
30 static void
popup(Widget w,XtPointer client_data,XtPointer call_data)31 popup(Widget w, XtPointer client_data, XtPointer call_data) {
32 UNUSED(w);
33 UNUSED(call_data);
34 x11_athena_popup_dialog((int)client_data);
35 }
36
37 static Widget
new_menu_item(Widget pshell,int dialog)38 new_menu_item(Widget pshell, int dialog) {
39 Widget menu_item = XtCreateManagedWidget(UI_menu_string(dialog),
40 smeBSBObjectClass,
41 pshell, NULL, 0);
42 XtAddCallback(menu_item, XtNcallback, popup, (void *) dialog);
43 return menu_item;
44 }
45
46 static Widget
CreateMenuBar(const char * name,Widget parent)47 CreateMenuBar(const char *name, Widget parent) {
48 Widget menubar, pshell;
49 Widget game_menu, info_menu;
50
51 menubar = XtVaCreateManagedWidget(name, boxWidgetClass, parent,
52 XtNborderWidth, 0,
53 XtNorientation, XtEhorizontal, NULL);
54
55 game_menu = XtCreateManagedWidget("Game", menuButtonWidgetClass,
56 menubar, NULL, 0);
57 pshell = XtCreatePopupShell("menu", simpleMenuWidgetClass,
58 game_menu, NULL, 0);
59
60 new_menu_item(pshell, DIALOG_NEWGAME);
61 pausebutton = new_menu_item(pshell, DIALOG_PAUSEGAME);
62 new_menu_item(pshell, DIALOG_WARPLEVEL);
63 new_menu_item(pshell, DIALOG_HIGHSCORE);
64 new_menu_item(pshell, DIALOG_QUITGAME);
65
66 info_menu = XtCreateManagedWidget("Info", menuButtonWidgetClass,
67 menubar, NULL, 0);
68 pshell = XtCreatePopupShell("menu", simpleMenuWidgetClass,
69 info_menu, NULL, 0);
70
71 new_menu_item(pshell, DIALOG_STORY);
72 new_menu_item(pshell, DIALOG_RULES);
73 new_menu_item(pshell, DIALOG_ABOUT);
74
75 return menubar;
76 }
77
78 static void
close_window(Widget w,XtPointer client_data,XtPointer call_data)79 close_window (Widget w, XtPointer client_data, XtPointer call_data) {
80 UNUSED(client_data);
81 UNUSED(call_data);
82 XtPopdown(XtParent(XtParent(w)));
83 }
84
85 static Widget
CreateRowCol(const char * name,Widget parent)86 CreateRowCol(const char *name, Widget parent) {
87 return XtCreateManagedWidget(name, boxWidgetClass, parent, NULL, 0);
88 }
89
90 static void
CreatePixmapBox(int index,Widget parent,Pixmap logo,Pixmap pixmap)91 CreatePixmapBox(int index, Widget parent, Pixmap logo, Pixmap pixmap) {
92 Widget base, pshell, button;
93 const char *text = UI_dialog_string(index);
94
95 pshell = XtCreatePopupShell(UI_menu_string(index),
96 transientShellWidgetClass, parent, NULL, 0);
97
98 base = CreateRowCol("", pshell);
99
100 XtVaCreateManagedWidget("", labelWidgetClass, base,
101 XtNbitmap, logo, XtNborderWidth, 0, NULL);
102
103 if (pixmap)
104 XtVaCreateManagedWidget("", labelWidgetClass, base,
105 XtNbitmap, pixmap, XtNborderWidth,
106 0, NULL);
107 if (text != NULL)
108 XtVaCreateManagedWidget("", labelWidgetClass, base,
109 XtNlabel, text, XtNborderWidth, 0, NULL);
110
111 button = XtVaCreateManagedWidget("OK", commandWidgetClass, base, NULL);
112 XtAddCallback(button, XtNcallback, close_window, NULL);
113 dialogs[index] = base;
114 }
115
116 static void
CreateEnterText(int index,Widget parent,XtCallbackProc callback)117 CreateEnterText(int index, Widget parent, XtCallbackProc callback) {
118 Widget base, pshell, button, textfield;
119 pshell = XtCreatePopupShell(UI_menu_string(index),
120 transientShellWidgetClass, parent, NULL, 0);
121 base = CreateRowCol("", pshell);
122 XtVaCreateManagedWidget("", labelWidgetClass, base,
123 XtNlabel, UI_dialog_string(index), XtNborderWidth, 0, NULL);
124
125 textfield = XtVaCreateManagedWidget("", asciiTextWidgetClass, base,
126 XtNeditType, XawtextEdit, XtNstring, "", XtNwidth, 200, NULL);
127
128 button = XtVaCreateManagedWidget("OK", commandWidgetClass, base, NULL);
129 XtAddCallback(button, XtNcallback, callback, textfield);
130 XtAddCallback(button, XtNcallback, close_window, NULL);
131 button = XtVaCreateManagedWidget("Cancel", commandWidgetClass, base,
132 NULL);
133 XtAddCallback(button, XtNcallback, close_window, NULL);
134 dialogs[index] = base;
135 }
136
137 static void
CreateDialog(int index,Widget parent,int hascancel,Pixmap icon,const char * buttonlabel,XtCallbackProc callback)138 CreateDialog(int index, Widget parent, int hascancel, Pixmap icon,
139 const char *buttonlabel, XtCallbackProc callback)
140 {
141 Widget base, pshell, button;
142 const char *text = UI_dialog_string(index);
143 char ttext[16];
144
145 pshell = XtCreatePopupShell(UI_menu_string(index),
146 transientShellWidgetClass, parent, NULL, 0);
147 base = CreateRowCol("base", pshell);
148 if (icon)
149 XtVaCreateManagedWidget("", labelWidgetClass, base,
150 XtNbitmap, icon,
151 XtNborderWidth, 0, NULL);
152 if (text != NULL && strlen(text) < sizeof(ttext)) {
153 sprintf(ttext, "%-*s", (int)sizeof(ttext) - 1, text);
154 text = ttext;
155 }
156 XtVaCreateManagedWidget("label", labelWidgetClass, base,
157 XtNlabel, text, XtNborderWidth, 0, NULL);
158
159 if (!buttonlabel)
160 buttonlabel="OK";
161 button = XtVaCreateManagedWidget(buttonlabel, commandWidgetClass,
162 base, NULL);
163 if (callback)
164 XtAddCallback(button, XtNcallback, callback, NULL);
165 XtAddCallback(button, XtNcallback, close_window, NULL);
166
167 if (hascancel) {
168 button = XtVaCreateManagedWidget("Cancel", commandWidgetClass,
169 base, NULL);
170 XtAddCallback(button, XtNcallback, close_window, NULL);
171 }
172 dialogs[index] = base;
173 }
174
175 static Widget
CreateDrawingArea(const char * name,Widget parent,int width,int height)176 CreateDrawingArea(const char *name, Widget parent, int width, int height) {
177 return XtVaCreateManagedWidget(name, coreWidgetClass, parent, XtNwidth,
178 width, XtNheight, height, NULL);
179 }
180
181 static void
x11_athena_update_dialog(int index,const char * str)182 x11_athena_update_dialog(int index, const char *str) {
183 WidgetList t;
184 XtVaGetValues(dialogs[index], XtNchildren, &t, NULL);
185 XtVaSetValues(t[0], XtNlabel, str, NULL);
186 }
187
188 static void
x11_athena_make_main_window(int size)189 x11_athena_make_main_window(int size) {
190 x11_setup_resources();
191 base = XtVaCreateManagedWidget("base", boxWidgetClass, x11_toplevel(),
192 XtNhSpace, 0, XtNvSpace, 0, NULL);
193 menubar = CreateMenuBar("menubar", base);
194 field = CreateDrawingArea("field", base, size, size);
195 x11_setup();
196 x11_set_drawingarea(field, size);
197 x11_add_event_handlers(field);
198 }
199
200 static void
new_game(Widget w,XtPointer client_data,XtPointer call_data)201 new_game(Widget w, XtPointer client_data, XtPointer call_data) {
202 UNUSED(w);
203 UNUSED(client_data);
204 UNUSED(call_data);
205 Game_start(1);
206 }
207
208 static void
quit_game(Widget w,XtPointer client_data,XtPointer call_data)209 quit_game(Widget w, XtPointer client_data, XtPointer call_data) {
210 UNUSED(w);
211 UNUSED(client_data);
212 UNUSED(call_data);
213 Game_quit();
214 }
215
216 static void
warp_apply(Widget w,XtPointer client_data,XtPointer call_data)217 warp_apply(Widget w, XtPointer client_data, XtPointer call_data) {
218 char *str;
219 char *endp;
220 int newlevel;
221 Widget text = (Widget) client_data;
222
223 UNUSED(w);
224 UNUSED(call_data);
225
226 XtVaGetValues(text, XtNstring, &str, NULL);
227 newlevel = strtol(str, &endp, 10);
228 if (*endp != '\0')
229 return;
230 Game_warp_to_level(newlevel);
231 }
232
233 static void
enter_name(Widget w,XtPointer client_data,XtPointer call_data)234 enter_name(Widget w, XtPointer client_data, XtPointer call_data) {
235 char *str;
236 Widget text = (Widget) client_data;
237
238 UNUSED(w);
239 UNUSED(call_data);
240
241 XtVaGetValues(text, XtNstring, &str, NULL);
242 Game_add_high_score(str);
243 }
244
245 static void
x11_athena_create_dialogs(Picture * logo,Picture * icon,Picture * about)246 x11_athena_create_dialogs(Picture *logo, Picture *icon, Picture *about) {
247 CreateDialog(DIALOG_NEWGAME, base, 1, (Pixmap)NULL, NULL, new_game);
248 CreateDialog(DIALOG_PAUSEGAME, base, 0, icon->pix, "Continue", NULL);
249 CreateEnterText(DIALOG_WARPLEVEL, base, warp_apply);
250 CreateDialog(DIALOG_HIGHSCORE, base, 0, (Pixmap)NULL, NULL, NULL);
251 CreateDialog(DIALOG_QUITGAME, base, 1, (Pixmap)NULL, NULL, quit_game);
252
253 CreatePixmapBox(DIALOG_STORY, base, logo->pix, (Pixmap)NULL);
254 CreatePixmapBox(DIALOG_RULES, base, logo->pix, (Pixmap)NULL);
255 CreatePixmapBox(DIALOG_ABOUT, base, logo->pix, about->pix);
256
257 CreateDialog(DIALOG_SCORE, base, 0, (Pixmap)NULL, NULL, NULL);
258 CreateDialog(DIALOG_ENDGAME, base, 0, (Pixmap)NULL, "Nuts!", NULL);
259 CreateEnterText(DIALOG_ENTERNAME, base, enter_name);
260 }
261
262 static void
x11_athena_set_pausebutton(int active)263 x11_athena_set_pausebutton(int active) {
264 if (pausebutton != NULL)
265 XtSetSensitive(pausebutton, active);
266 }
267
268 static struct UI_methods x11_athena_methods = {
269 x11_set_cursor,
270 x11_load_cursor,
271 x11_load_picture,
272 x11_set_icon,
273 x11_picture_width,
274 x11_picture_height,
275 x11_graphics_init,
276 x11_clear_window,
277 x11_refresh_window,
278 x11_draw_image,
279 x11_draw_line,
280 x11_draw_string,
281 x11_start_timer,
282 x11_stop_timer,
283 x11_timer_active,
284 x11_athena_popup_dialog,
285 x11_main_loop,
286 x11_initialize,
287 x11_athena_make_main_window,
288 x11_athena_create_dialogs,
289 x11_athena_set_pausebutton,
290 x11_athena_update_dialog,
291 };
292
293 void
x11_athena_setmethods(UI_methods ** methodsp)294 x11_athena_setmethods(UI_methods **methodsp) {
295 *methodsp = &x11_athena_methods;
296 }
297