1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6
7 #include <gtk/gtk.h>
8
9 #include "util.h"
10
11 #include "gtk.h"
12
13 #include "Game.h"
14 #include "UI.h"
15
16 struct MCursor {
17 GdkCursor *cursor;
18 };
19
20 struct Picture {
21 gint width, height;
22 GdkPixmap *pix;
23 GdkBitmap *mask;
24 GdkGC *gc;
25 };
26
27 static const char *pictdir;
28
29 static GtkWidget *toplevel, *base, *menubar, *field;
30 static GtkWidget *dialogs[DIALOG_MAX + 1];
31 static GtkWidget *pausebutton;
32 static guint timer;
33 static GdkGC *stdgc;
34 static GdkPixmap *offscreen;
35 static GdkFont *font;
36 static GdkColor white, black;
37 static int screensize;
38
39 /*
40 * Callback functions
41 */
42
43 static void
gtk_ui_popup_dialog(int index)44 gtk_ui_popup_dialog(int index) {
45 GtkWidget *popup;
46 int tx, ty, tw, th;
47 int px, py, pw, ph;
48
49 popup = dialogs[index];
50
51 gdk_window_get_origin(toplevel->window, &tx, &ty);
52 gdk_window_get_size(toplevel->window, &tw, &th);
53 gdk_window_get_size(popup->window, &pw, &ph);
54 px = tx + (tw - pw) / 2;
55 py = ty + (th - ph) / 2;
56 gtk_window_set_position(GTK_WINDOW(popup), GTK_WIN_POS_NONE);
57 gtk_widget_set_uposition(popup, px, py);
58 gtk_widget_show_all(popup);
59 gtk_main();
60 }
61
62 static void
popdown(void)63 popdown(void) {
64 gtk_main_quit();
65 }
66
67 static void
new_game(void)68 new_game(void) {
69 Game_start(1);
70 }
71
72 static void
quit_game(void)73 quit_game(void) {
74 Game_quit();
75 }
76
77 static void
warp_apply(GtkWidget * text)78 warp_apply(GtkWidget *text) {
79 char *str;
80 char *endp;
81 int newlevel;
82
83 str = gtk_entry_get_text(GTK_ENTRY(text));
84 newlevel = strtol(str, &endp, 10);
85 if (*endp != '\0')
86 return;
87 Game_warp_to_level(newlevel);
88 }
89
90 static void
enter_name(GtkWidget * text)91 enter_name(GtkWidget *text) {
92 char *str;
93
94 str = gtk_entry_get_text(GTK_ENTRY(text));
95 Game_add_high_score(str);
96 }
97
98 /*
99 * Event handlers
100 */
101
102 static gboolean
leave_window(GtkWidget * widget,GdkEvent * event,gpointer user_data)103 leave_window(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
104 UNUSED(widget);
105 UNUSED(event);
106 UNUSED(user_data);
107
108 UI_pause_game();
109 return FALSE;
110 }
111
112 static gboolean
enter_window(GtkWidget * widget,GdkEvent * event,gpointer user_data)113 enter_window(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
114 UNUSED(widget);
115 UNUSED(event);
116 UNUSED(user_data);
117
118 UI_resume_game();
119 return FALSE;
120 }
121
122 static gboolean
redraw_window(GtkWidget * widget,GdkEvent * event,gpointer user_data)123 redraw_window(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
124 UNUSED(widget);
125 UNUSED(event);
126 UNUSED(user_data);
127
128 UI_refresh();
129 return FALSE;
130 }
131
132 static gboolean
button_press(GtkWidget * widget,GdkEvent * event,gpointer user_data)133 button_press(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
134 GdkEventButton *buttonevent = (GdkEventButton *) event;
135
136 UNUSED(widget);
137 UNUSED(user_data);
138
139 Game_button_press((int)buttonevent->x, (int)buttonevent->y);
140 return FALSE;
141 }
142
143 static gboolean
button_release(GtkWidget * widget,GdkEvent * event,gpointer user_data)144 button_release(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
145 GdkEventButton *buttonevent = (GdkEventButton *) event;
146
147 UNUSED(widget);
148 UNUSED(user_data);
149
150 Game_button_release((int)buttonevent->x, (int)buttonevent->y);
151 return FALSE;
152 }
153
154 static int
timer_tick(gpointer arg)155 timer_tick(gpointer arg) {
156 UNUSED(arg);
157
158 UI_restart_timer();
159 Game_update();
160 return TRUE;
161 }
162
163 /*
164 * Cursor handling
165 */
166
167 #include "bitmaps/initfail.xbm"
168 #include "bitmaps/arch.xbm"
169 #include "bitmaps/bsd.xbm"
170 #include "bitmaps/centos.xbm"
171 #include "bitmaps/debian.xbm"
172 #include "bitmaps/gentoo.xbm"
173 #include "bitmaps/mandriva.xbm"
174 #include "bitmaps/openbsd.xbm"
175 #include "bitmaps/slackware.xbm"
176 #include "bitmaps/suse.xbm"
177 #include "bitmaps/ubuntu.xbm"
178 #include "bitmaps/bucket.xbm"
179 #include "bitmaps/hand_down.xbm"
180 #include "bitmaps/hand_down_mask.xbm"
181 #include "bitmaps/hand_up.xbm"
182 #include "bitmaps/hand_up_mask.xbm"
183
184 typedef struct cursormap {
185 const char *name;
186 int width, height;
187 const char *data, *maskdata;
188 } cursormap;
189
190 #define CURSOR_ADD(x) \
191 {#x, x ## _width, x ## _height, x ## _bits, NULL}
192
193 #define CURSOR_ADD_MASKED(x) \
194 {#x, x ## _width, x ## _height, x ## _bits, x ## _mask_bits}
195
196 static cursormap cursors[] = {
197 CURSOR_ADD(arch), CURSOR_ADD( bsd), CURSOR_ADD(centos),
198 CURSOR_ADD(debian), CURSOR_ADD(gentoo), CURSOR_ADD(mandriva),
199 CURSOR_ADD(openbsd), CURSOR_ADD(slackware), CURSOR_ADD(suse),
200 CURSOR_ADD(ubuntu), CURSOR_ADD(bucket),
201 CURSOR_ADD_MASKED(hand_up), CURSOR_ADD_MASKED(hand_down),
202 {NULL, 0, 0, NULL, NULL},
203 };
204
205 static void
gtk_ui_set_cursor(MCursor * cursor)206 gtk_ui_set_cursor(MCursor *cursor) {
207 gdk_window_set_cursor(field->window, cursor->cursor);
208 }
209
210 static void
gtk_ui_load_cursor(const char * name,int masked,MCursor ** cursorp)211 gtk_ui_load_cursor(const char *name, int masked, MCursor **cursorp) {
212 MCursor *cursor;
213 GdkBitmap *bitmap, *mask;
214 cursormap *c;
215
216 cursor = xalloc(sizeof *cursor);
217
218 for (c = cursors; c->name != NULL; c++)
219 if (strcmp(name, c->name) == 0)
220 break;
221 if (c->name == NULL)
222 fatal("couldn't load cursor: %s", name);
223 bitmap = gdk_bitmap_create_from_data(field->window, c->data,
224 c->width, c->height);
225
226 if (masked == CURSOR_SEP_MASK)
227 mask = gdk_bitmap_create_from_data(field->window, c->maskdata,
228 c->width, c->height);
229 else
230 mask = bitmap;
231 cursor->cursor = gdk_cursor_new_from_pixmap(bitmap, mask,
232 &black, &white,
233 c->width/2, c->height/2);
234 *cursorp = cursor;
235 }
236
237 /*
238 * Pixmap handling
239 */
240
241 static void
gtk_ui_load_picture(const char * name,int trans,Picture ** pictp)242 gtk_ui_load_picture(const char *name, int trans, Picture **pictp) {
243 Picture *pict;
244 char file[255];
245 GdkBitmap *mask;
246
247 UNUSED(trans);
248
249 pict = xalloc(sizeof *pict);
250
251 sprintf(file, "%s/pixmaps/%s.xpm", pictdir, name);
252 pict->pix = gdk_pixmap_create_from_xpm(toplevel->window, &mask,
253 NULL, file);
254 if (pict->pix == NULL)
255 fatal("error reading %s", file);
256 pict->mask = mask;
257 pict->gc = gdk_gc_new(toplevel->window);
258 gdk_gc_set_exposures(pict->gc, FALSE);
259 gdk_gc_set_clip_mask(pict->gc, mask);
260 gdk_window_get_size(pict->pix, &pict->width, &pict->height);
261
262 *pictp = pict;
263 }
264
265 static void
gtk_ui_set_icon(Picture * icon)266 gtk_ui_set_icon(Picture *icon) {
267 gdk_window_set_icon(toplevel->window, NULL, icon->pix, icon->mask);
268 }
269
270 static int
gtk_ui_picture_width(Picture * pict)271 gtk_ui_picture_width(Picture *pict) {
272 return (pict->width);
273 }
274
275 static int
gtk_ui_picture_height(Picture * pict)276 gtk_ui_picture_height(Picture *pict) {
277 return (pict->height);
278 }
279
280 /*
281 * Graphics operations
282 */
283
284 static void
gtk_ui_clear_window(void)285 gtk_ui_clear_window(void) {
286 gdk_draw_rectangle(offscreen, field->style->white_gc, TRUE, 0, 0,
287 screensize, screensize);
288 }
289
290 static void
gtk_ui_refresh_window(void)291 gtk_ui_refresh_window(void) {
292 gdk_draw_pixmap(field->window, stdgc, offscreen, 0, 0, 0, 0,
293 screensize, screensize);
294 }
295
296 static void
gtk_ui_draw_image(Picture * pict,int x,int y)297 gtk_ui_draw_image(Picture *pict, int x, int y) {
298 gdk_gc_set_clip_origin(pict->gc, x, y);
299 gdk_draw_pixmap(offscreen, pict->gc, pict->pix, 0, 0, x, y,
300 pict->width, pict->height);
301 }
302
303 static void
gtk_ui_draw_line(int x1,int y1,int x2,int y2)304 gtk_ui_draw_line(int x1, int y1, int x2, int y2) {
305 gdk_draw_line(offscreen, stdgc, x1, y1, x2, y2);
306 }
307
308 static void
gtk_ui_draw_string(const char * str,int x,int y)309 gtk_ui_draw_string(const char *str, int x, int y) {
310 gdk_draw_string(offscreen, font, stdgc, x, y, str);
311 }
312
313 /*
314 * Timer operations
315 */
316
317 static void
gtk_ui_start_timer(int ms)318 gtk_ui_start_timer(int ms) {
319 if (timer == 0)
320 timer = gtk_timeout_add(ms, timer_tick, NULL);
321 }
322
323 static void
gtk_ui_stop_timer(void)324 gtk_ui_stop_timer(void) {
325 if (timer != 0)
326 gtk_timeout_remove(timer);
327 timer = 0;
328 }
329
330 static int
gtk_ui_timer_active(void)331 gtk_ui_timer_active(void) {
332 return (!!timer);
333 }
334
335 /*
336 * Main Loop
337 */
338 static void
gtk_ui_main_loop(void)339 gtk_ui_main_loop(void) {
340 gtk_main();
341 }
342
343 /*
344 * Initialization
345 */
346 static void
gtk_ui_initialize(int * argc,char ** argv)347 gtk_ui_initialize(int *argc, char **argv) {
348 struct stat stats;
349
350 gtk_init(argc, &argv);
351 toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
352
353 timer = 0;
354 gtk_window_set_title(GTK_WINDOW(toplevel), "XLennart - An XBill Modification");
355
356 gtk_signal_connect(GTK_OBJECT(toplevel), "delete_event",
357 GTK_SIGNAL_FUNC(quit_game), NULL);
358
359 if (stat(IMAGES, &stats) == 0)
360 pictdir = IMAGES;
361 else
362 pictdir = ".";
363 }
364
365 static GtkWidget *
new_menu_item(GtkWidget * menu,int dialog)366 new_menu_item(GtkWidget *menu, int dialog) {
367 GtkWidget *menu_item;
368
369 menu_item = gtk_menu_item_new_with_label(UI_menu_string(dialog));
370 gtk_menu_append(GTK_MENU(menu), menu_item);
371 gtk_signal_connect_object(GTK_OBJECT(menu_item), "activate",
372 gtk_ui_popup_dialog, (gpointer) dialog);
373 return (menu_item);
374 }
375
376 static GtkWidget *
CreateMenuBar(void)377 CreateMenuBar(void) {
378 GtkWidget *menubar;
379 GtkWidget *game_item, *game_menu;
380 GtkWidget *info_item, *info_menu;
381 GtkWidget *tearoff;
382
383 menubar = gtk_menu_bar_new();
384
385 game_item = gtk_menu_item_new_with_label("Game");
386 game_menu = gtk_menu_new();
387
388 tearoff = gtk_tearoff_menu_item_new();
389 gtk_menu_append(GTK_MENU(game_menu), tearoff);
390
391 new_menu_item(game_menu, DIALOG_NEWGAME);
392 pausebutton = new_menu_item(game_menu, DIALOG_PAUSEGAME);
393 new_menu_item(game_menu, DIALOG_WARPLEVEL);
394 new_menu_item(game_menu, DIALOG_HIGHSCORE);
395 new_menu_item(game_menu, DIALOG_QUITGAME);
396
397 gtk_menu_bar_append(GTK_MENU_BAR(menubar), game_item);
398 gtk_menu_item_set_submenu(GTK_MENU_ITEM(game_item), game_menu);
399
400 info_item = gtk_menu_item_new_with_label("Info");
401 info_menu = gtk_menu_new();
402
403 tearoff = gtk_tearoff_menu_item_new();
404 gtk_menu_append(GTK_MENU(info_menu), tearoff);
405
406 new_menu_item(info_menu, DIALOG_STORY);
407 new_menu_item(info_menu, DIALOG_RULES);
408 new_menu_item(info_menu, DIALOG_ABOUT);
409
410 gtk_menu_bar_append(GTK_MENU_BAR(menubar), info_item);
411 gtk_menu_item_set_submenu(GTK_MENU_ITEM(info_item), info_menu);
412
413 return menubar;
414 }
415
416 static GtkWidget *
CreateDrawingArea(int width,int height)417 CreateDrawingArea(int width, int height) {
418 GtkWidget *w = gtk_drawing_area_new();
419 gtk_drawing_area_size(GTK_DRAWING_AREA(w), width, height);
420 return w;
421 }
422
423 static void
gtk_ui_make_main_window(int size)424 gtk_ui_make_main_window(int size) {
425 GdkWindowHints flags;
426 GdkGeometry geom;
427 gint winwidth, winheight;
428
429 screensize = size;
430
431 base = gtk_vbox_new(FALSE, 0);
432 gtk_container_add(GTK_CONTAINER(toplevel), base);
433
434 menubar = CreateMenuBar();
435 gtk_box_pack_start(GTK_BOX(base), menubar, FALSE, FALSE, 0);
436
437 field = CreateDrawingArea(size, size);
438 gtk_box_pack_start(GTK_BOX(base), field, FALSE, FALSE, 0);
439
440 gtk_signal_connect(GTK_OBJECT(field), "button-press-event",
441 GTK_SIGNAL_FUNC(button_press), NULL);
442 gtk_signal_connect(GTK_OBJECT(field), "button-release-event",
443 GTK_SIGNAL_FUNC(button_release), NULL);
444 gtk_signal_connect(GTK_OBJECT(field), "enter-notify-event",
445 GTK_SIGNAL_FUNC(enter_window), NULL);
446 gtk_signal_connect(GTK_OBJECT(field), "leave-notify-event",
447 GTK_SIGNAL_FUNC(leave_window), NULL);
448 gtk_signal_connect(GTK_OBJECT(field), "expose-event",
449 GTK_SIGNAL_FUNC(redraw_window), NULL);
450 gtk_widget_set_events(field, GDK_BUTTON_PRESS_MASK |
451 GDK_BUTTON_RELEASE_MASK |
452 GDK_ENTER_NOTIFY_MASK |
453 GDK_LEAVE_NOTIFY_MASK |
454 GDK_EXPOSURE_MASK);
455
456 gtk_widget_show_all(toplevel);
457
458 gdk_window_get_size(toplevel->window, &winwidth, &winheight);
459 geom.min_width = geom.max_width = geom.base_width = winwidth;
460 geom.min_height = geom.max_height = geom.base_height = winheight;
461 geom.width_inc = geom.height_inc = 0;
462 flags = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_BASE_SIZE |
463 GDK_HINT_RESIZE_INC;
464 gdk_window_set_geometry_hints(toplevel->window, &geom, flags);
465
466 gdk_color_parse("white", &white);
467 gdk_color_parse("black", &black);
468 }
469
470 static void
gtk_ui_graphics_init(void)471 gtk_ui_graphics_init(void) {
472 offscreen = gdk_pixmap_new(field->window, screensize, screensize, -1);
473 stdgc = gdk_gc_new(offscreen);
474 gdk_gc_set_exposures(stdgc, FALSE);
475 gdk_gc_set_line_attributes(stdgc, 2, GDK_LINE_SOLID, GDK_CAP_ROUND,
476 GDK_JOIN_MITER);
477 font = gdk_font_load("fixed");
478 }
479
480 static GtkWidget *
new_button(GtkWidget * dialog,const char * text,GtkSignalFunc func,GtkObject * obj)481 new_button(GtkWidget *dialog, const char *text, GtkSignalFunc func,
482 GtkObject *obj)
483 {
484 GtkWidget *button = gtk_button_new_with_label(text);
485 if (func != NULL)
486 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
487 func, obj);
488 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
489 GTK_SIGNAL_FUNC(gtk_widget_hide),
490 GTK_OBJECT(dialog));
491 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
492 GTK_SIGNAL_FUNC(popdown), NULL);
493 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
494 button);
495 gtk_widget_show(button);
496 return button;
497 }
498
499 static void
CreateDialog(int index,int hascancel,Picture * icon,const char * buttonlabel,GtkSignalFunc func)500 CreateDialog(int index, int hascancel, Picture *icon,
501 const char *buttonlabel, GtkSignalFunc func)
502 {
503 GtkWidget *dialog, *pixmap, *label, *hbox;
504
505 dialog = gtk_dialog_new();
506 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
507
508 hbox = gtk_hbox_new(FALSE, 0);
509
510 if (icon != NULL) {
511 pixmap = gtk_pixmap_new(icon->pix, icon->mask);
512 gtk_container_add(GTK_CONTAINER(hbox), pixmap);
513 }
514
515 label = gtk_label_new(UI_dialog_string(index));
516 gtk_container_add(GTK_CONTAINER(hbox), label);
517
518 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
519 gtk_widget_show_all(hbox);
520
521 if (buttonlabel == NULL)
522 buttonlabel = "OK";
523 new_button(dialog, buttonlabel, func, NULL);
524
525 if (hascancel)
526 new_button(dialog, "Cancel", NULL, NULL);
527
528 gtk_widget_realize(dialog);
529 dialogs[index] = dialog;
530 }
531
532 static void
CreateEnterText(int index,GtkSignalFunc func)533 CreateEnterText(int index, GtkSignalFunc func) {
534 GtkWidget *dialog, *label, *entry;
535
536 dialog = gtk_dialog_new();
537 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
538
539 label = gtk_label_new(UI_dialog_string(index));
540 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
541 gtk_widget_show(label);
542
543 entry = gtk_entry_new_with_max_length(20);
544 gtk_signal_connect_object(GTK_OBJECT(entry), "activate",
545 func, GTK_OBJECT(entry));
546 gtk_signal_connect_object(GTK_OBJECT(entry), "activate",
547 GTK_SIGNAL_FUNC(gtk_widget_hide),
548 GTK_OBJECT(dialog));
549 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), entry);
550 gtk_widget_show(entry);
551
552 new_button(dialog, "OK", func, GTK_OBJECT(entry));
553
554 gtk_widget_realize(dialog);
555 dialogs[index] = dialog;
556 }
557
558 static void
CreatePixmapBox(int index,Picture * logo,Picture * pix)559 CreatePixmapBox(int index, Picture *logo, Picture *pix) {
560 GtkWidget *dialog, *pixmap, *label;
561 const char *text = UI_dialog_string(index);
562
563 dialog = gtk_dialog_new();
564 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
565
566 pixmap = gtk_pixmap_new(logo->pix, logo->mask);
567 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), pixmap);
568 gtk_widget_show(pixmap);
569
570 if (pix != NULL) {
571 pixmap = gtk_pixmap_new(pix->pix, pix->mask);
572 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
573 pixmap);
574 gtk_widget_show(pixmap);
575 }
576
577 if (text != NULL) {
578 label = gtk_label_new(text);
579 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
580 label);
581 gtk_widget_show(label);
582 }
583
584 new_button(dialog, "OK", NULL, NULL);
585
586 gtk_widget_realize(dialog);
587 dialogs[index] = dialog;
588 }
589
590 static void
gtk_ui_create_dialogs(Picture * logo,Picture * icon,Picture * about)591 gtk_ui_create_dialogs(Picture *logo, Picture *icon, Picture *about) {
592 CreateDialog(DIALOG_NEWGAME, 1, NULL, NULL, new_game);
593 CreateDialog(DIALOG_PAUSEGAME, 0, icon, "Continue", NULL);
594 CreateEnterText(DIALOG_WARPLEVEL, warp_apply);
595 CreateDialog(DIALOG_HIGHSCORE, 0, NULL, NULL, NULL);
596 CreateDialog(DIALOG_QUITGAME, 1, NULL, NULL, quit_game);
597
598 CreatePixmapBox(DIALOG_STORY, logo, NULL);
599 CreatePixmapBox(DIALOG_RULES, logo, NULL);
600 CreatePixmapBox(DIALOG_ABOUT, logo, about);
601
602 CreateDialog(DIALOG_SCORE, 0, NULL, NULL, NULL);
603 CreateDialog(DIALOG_ENDGAME, 0, NULL, "Nuts!", NULL);
604 CreateEnterText(DIALOG_ENTERNAME, enter_name);
605 }
606
607 static void
set_label(GtkWidget * dialog,const char * str)608 set_label(GtkWidget *dialog, const char *str) {
609 GList *list;
610 GtkWidget *hbox = NULL;
611
612 list = gtk_container_children(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox));
613 while (list != NULL) {
614 GtkWidget *w = (GtkWidget *) list->data;
615 list = g_list_next(list);
616 if (GTK_IS_HBOX(w)) {
617 hbox = w;
618 break;
619 }
620 }
621 if (hbox == NULL)
622 return;
623 list = gtk_container_children(GTK_CONTAINER(hbox));
624 while (list != NULL) {
625 GtkWidget *w = (GtkWidget *) list->data;
626 list = g_list_next(list);
627 if (GTK_IS_LABEL(w)) {
628 gtk_label_set_text(GTK_LABEL(w), str);
629 return;
630 }
631 }
632 }
633
634 static void
gtk_ui_update_dialog(int index,const char * str)635 gtk_ui_update_dialog(int index, const char *str) {
636 set_label(dialogs[index], str);
637 }
638
639 static void
gtk_ui_set_pausebutton(int active)640 gtk_ui_set_pausebutton(int active) {
641 if (pausebutton != NULL)
642 gtk_widget_set_sensitive(pausebutton, active);
643 }
644
645 static struct UI_methods gtk_methods = {
646 gtk_ui_set_cursor,
647 gtk_ui_load_cursor,
648 gtk_ui_load_picture,
649 gtk_ui_set_icon,
650 gtk_ui_picture_width,
651 gtk_ui_picture_height,
652 gtk_ui_graphics_init,
653 gtk_ui_clear_window,
654 gtk_ui_refresh_window,
655 gtk_ui_draw_image,
656 gtk_ui_draw_line,
657 gtk_ui_draw_string,
658 gtk_ui_start_timer,
659 gtk_ui_stop_timer,
660 gtk_ui_timer_active,
661 gtk_ui_popup_dialog,
662 gtk_ui_main_loop,
663 gtk_ui_initialize,
664 gtk_ui_make_main_window,
665 gtk_ui_create_dialogs,
666 gtk_ui_set_pausebutton,
667 gtk_ui_update_dialog,
668 };
669
670 void
gtk_ui_setmethods(UI_methods ** methodsp)671 gtk_ui_setmethods(UI_methods **methodsp) {
672 *methodsp = >k_methods;
673 }
674