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/apple.xbm"
168 #include "bitmaps/bsd.xbm"
169 #include "bitmaps/hurd.xbm"
170 #include "bitmaps/linux.xbm"
171 #include "bitmaps/next.xbm"
172 #include "bitmaps/os2.xbm"
173 #include "bitmaps/palm.xbm"
174 #include "bitmaps/redhat.xbm"
175 #include "bitmaps/sgi.xbm"
176 #include "bitmaps/sun.xbm"
177 #include "bitmaps/bucket.xbm"
178 #include "bitmaps/hand_down.xbm"
179 #include "bitmaps/hand_down_mask.xbm"
180 #include "bitmaps/hand_up.xbm"
181 #include "bitmaps/hand_up_mask.xbm"
182
183 typedef struct cursormap {
184 const char *name;
185 int width, height;
186 const char *data, *maskdata;
187 } cursormap;
188
189 #define CURSOR_ADD(x) \
190 {#x, x ## _width, x ## _height, x ## _bits, NULL}
191
192 #define CURSOR_ADD_MASKED(x) \
193 {#x, x ## _width, x ## _height, x ## _bits, x ## _mask_bits}
194
195 static cursormap cursors[] = {
196 CURSOR_ADD(apple), CURSOR_ADD(bsd), CURSOR_ADD(hurd),
197 CURSOR_ADD(linux), CURSOR_ADD(next), CURSOR_ADD(os2), CURSOR_ADD(palm),
198 CURSOR_ADD(redhat), CURSOR_ADD(sgi), CURSOR_ADD(sun),
199 CURSOR_ADD(bucket),
200 CURSOR_ADD_MASKED(hand_up), CURSOR_ADD_MASKED(hand_down),
201 {NULL, 0, 0, NULL, NULL},
202 };
203
204 static void
gtk_ui_set_cursor(MCursor * cursor)205 gtk_ui_set_cursor(MCursor *cursor) {
206 gdk_window_set_cursor(field->window, cursor->cursor);
207 }
208
209 static void
gtk_ui_load_cursor(const char * name,int masked,MCursor ** cursorp)210 gtk_ui_load_cursor(const char *name, int masked, MCursor **cursorp) {
211 MCursor *cursor;
212 GdkBitmap *bitmap, *mask;
213 cursormap *c;
214
215 cursor = xalloc(sizeof *cursor);
216
217 for (c = cursors; c->name != NULL; c++)
218 if (strcmp(name, c->name) == 0)
219 break;
220 if (c->name == NULL)
221 fatal("couldn't load cursor: %s", name);
222 bitmap = gdk_bitmap_create_from_data(field->window, c->data,
223 c->width, c->height);
224
225 if (masked == CURSOR_SEP_MASK)
226 mask = gdk_bitmap_create_from_data(field->window, c->maskdata,
227 c->width, c->height);
228 else
229 mask = bitmap;
230 cursor->cursor = gdk_cursor_new_from_pixmap(bitmap, mask,
231 &black, &white,
232 c->width/2, c->height/2);
233 *cursorp = cursor;
234 }
235
236 /*
237 * Pixmap handling
238 */
239
240 static void
gtk_ui_load_picture(const char * name,int trans,Picture ** pictp)241 gtk_ui_load_picture(const char *name, int trans, Picture **pictp) {
242 Picture *pict;
243 char file[255];
244 GdkBitmap *mask;
245
246 UNUSED(trans);
247
248 pict = xalloc(sizeof *pict);
249
250 sprintf(file, "%s/pixmaps/%s.xpm", pictdir, name);
251 pict->pix = gdk_pixmap_create_from_xpm(toplevel->window, &mask,
252 NULL, file);
253 if (pict->pix == NULL)
254 fatal("error reading %s", file);
255 pict->mask = mask;
256 pict->gc = gdk_gc_new(toplevel->window);
257 gdk_gc_set_exposures(pict->gc, FALSE);
258 gdk_gc_set_clip_mask(pict->gc, mask);
259 gdk_window_get_size(pict->pix, &pict->width, &pict->height);
260
261 *pictp = pict;
262 }
263
264 static void
gtk_ui_set_icon(Picture * icon)265 gtk_ui_set_icon(Picture *icon) {
266 gdk_window_set_icon(toplevel->window, NULL, icon->pix, icon->mask);
267 }
268
269 static int
gtk_ui_picture_width(Picture * pict)270 gtk_ui_picture_width(Picture *pict) {
271 return (pict->width);
272 }
273
274 static int
gtk_ui_picture_height(Picture * pict)275 gtk_ui_picture_height(Picture *pict) {
276 return (pict->height);
277 }
278
279 /*
280 * Graphics operations
281 */
282
283 static void
gtk_ui_clear_window(void)284 gtk_ui_clear_window(void) {
285 gdk_draw_rectangle(offscreen, field->style->white_gc, TRUE, 0, 0,
286 screensize, screensize);
287 }
288
289 static void
gtk_ui_refresh_window(void)290 gtk_ui_refresh_window(void) {
291 gdk_draw_pixmap(field->window, stdgc, offscreen, 0, 0, 0, 0,
292 screensize, screensize);
293 }
294
295 static void
gtk_ui_draw_image(Picture * pict,int x,int y)296 gtk_ui_draw_image(Picture *pict, int x, int y) {
297 gdk_gc_set_clip_origin(pict->gc, x, y);
298 gdk_draw_pixmap(offscreen, pict->gc, pict->pix, 0, 0, x, y,
299 pict->width, pict->height);
300 }
301
302 static void
gtk_ui_draw_line(int x1,int y1,int x2,int y2)303 gtk_ui_draw_line(int x1, int y1, int x2, int y2) {
304 gdk_draw_line(offscreen, stdgc, x1, y1, x2, y2);
305 }
306
307 static void
gtk_ui_draw_string(const char * str,int x,int y)308 gtk_ui_draw_string(const char *str, int x, int y) {
309 gdk_draw_string(offscreen, font, stdgc, x, y, str);
310 }
311
312 /*
313 * Timer operations
314 */
315
316 static void
gtk_ui_start_timer(int ms)317 gtk_ui_start_timer(int ms) {
318 if (timer == 0)
319 timer = gtk_timeout_add(ms, timer_tick, NULL);
320 }
321
322 static void
gtk_ui_stop_timer(void)323 gtk_ui_stop_timer(void) {
324 if (timer != 0)
325 gtk_timeout_remove(timer);
326 timer = 0;
327 }
328
329 static int
gtk_ui_timer_active(void)330 gtk_ui_timer_active(void) {
331 return (!!timer);
332 }
333
334 /*
335 * Main Loop
336 */
337 static void
gtk_ui_main_loop(void)338 gtk_ui_main_loop(void) {
339 gtk_main();
340 }
341
342 /*
343 * Initialization
344 */
345 static void
gtk_ui_initialize(int * argc,char ** argv)346 gtk_ui_initialize(int *argc, char **argv) {
347 struct stat stats;
348
349 gtk_init(argc, &argv);
350 toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
351
352 timer = 0;
353 gtk_window_set_title(GTK_WINDOW(toplevel), "XBill");
354
355 gtk_signal_connect(GTK_OBJECT(toplevel), "delete_event",
356 GTK_SIGNAL_FUNC(quit_game), NULL);
357
358 if (stat(IMAGES, &stats) == 0)
359 pictdir = IMAGES;
360 else
361 pictdir = ".";
362 }
363
364 static GtkWidget *
new_menu_item(GtkWidget * menu,int dialog)365 new_menu_item(GtkWidget *menu, int dialog) {
366 GtkWidget *menu_item;
367
368 menu_item = gtk_menu_item_new_with_label(UI_menu_string(dialog));
369 gtk_menu_append(GTK_MENU(menu), menu_item);
370 gtk_signal_connect_object(GTK_OBJECT(menu_item), "activate",
371 gtk_ui_popup_dialog, (gpointer) dialog);
372 return (menu_item);
373 }
374
375 static GtkWidget *
CreateMenuBar(void)376 CreateMenuBar(void) {
377 GtkWidget *menubar;
378 GtkWidget *game_item, *game_menu;
379 GtkWidget *info_item, *info_menu;
380 GtkWidget *tearoff;
381
382 menubar = gtk_menu_bar_new();
383
384 game_item = gtk_menu_item_new_with_label("Game");
385 game_menu = gtk_menu_new();
386
387 tearoff = gtk_tearoff_menu_item_new();
388 gtk_menu_append(GTK_MENU(game_menu), tearoff);
389
390 new_menu_item(game_menu, DIALOG_NEWGAME);
391 pausebutton = new_menu_item(game_menu, DIALOG_PAUSEGAME);
392 new_menu_item(game_menu, DIALOG_WARPLEVEL);
393 new_menu_item(game_menu, DIALOG_HIGHSCORE);
394 new_menu_item(game_menu, DIALOG_QUITGAME);
395
396 gtk_menu_bar_append(GTK_MENU_BAR(menubar), game_item);
397 gtk_menu_item_set_submenu(GTK_MENU_ITEM(game_item), game_menu);
398
399 info_item = gtk_menu_item_new_with_label("Info");
400 info_menu = gtk_menu_new();
401
402 tearoff = gtk_tearoff_menu_item_new();
403 gtk_menu_append(GTK_MENU(info_menu), tearoff);
404
405 new_menu_item(info_menu, DIALOG_STORY);
406 new_menu_item(info_menu, DIALOG_RULES);
407 new_menu_item(info_menu, DIALOG_ABOUT);
408
409 gtk_menu_bar_append(GTK_MENU_BAR(menubar), info_item);
410 gtk_menu_item_set_submenu(GTK_MENU_ITEM(info_item), info_menu);
411
412 return menubar;
413 }
414
415 static GtkWidget *
CreateDrawingArea(int width,int height)416 CreateDrawingArea(int width, int height) {
417 GtkWidget *w = gtk_drawing_area_new();
418 gtk_drawing_area_size(GTK_DRAWING_AREA(w), width, height);
419 return w;
420 }
421
422 static void
gtk_ui_make_main_window(int size)423 gtk_ui_make_main_window(int size) {
424 GdkWindowHints flags;
425 GdkGeometry geom;
426 gint winwidth, winheight;
427
428 screensize = size;
429
430 base = gtk_vbox_new(FALSE, 0);
431 gtk_container_add(GTK_CONTAINER(toplevel), base);
432
433 menubar = CreateMenuBar();
434 gtk_box_pack_start(GTK_BOX(base), menubar, FALSE, FALSE, 0);
435
436 field = CreateDrawingArea(size, size);
437 gtk_box_pack_start(GTK_BOX(base), field, FALSE, FALSE, 0);
438
439 gtk_signal_connect(GTK_OBJECT(field), "button-press-event",
440 GTK_SIGNAL_FUNC(button_press), NULL);
441 gtk_signal_connect(GTK_OBJECT(field), "button-release-event",
442 GTK_SIGNAL_FUNC(button_release), NULL);
443 gtk_signal_connect(GTK_OBJECT(field), "enter-notify-event",
444 GTK_SIGNAL_FUNC(enter_window), NULL);
445 gtk_signal_connect(GTK_OBJECT(field), "leave-notify-event",
446 GTK_SIGNAL_FUNC(leave_window), NULL);
447 gtk_signal_connect(GTK_OBJECT(field), "expose-event",
448 GTK_SIGNAL_FUNC(redraw_window), NULL);
449 gtk_widget_set_events(field, GDK_BUTTON_PRESS_MASK |
450 GDK_BUTTON_RELEASE_MASK |
451 GDK_ENTER_NOTIFY_MASK |
452 GDK_LEAVE_NOTIFY_MASK |
453 GDK_EXPOSURE_MASK);
454
455 gtk_widget_show_all(toplevel);
456
457 gdk_window_get_size(toplevel->window, &winwidth, &winheight);
458 geom.min_width = geom.max_width = geom.base_width = winwidth;
459 geom.min_height = geom.max_height = geom.base_height = winheight;
460 geom.width_inc = geom.height_inc = 0;
461 flags = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_BASE_SIZE |
462 GDK_HINT_RESIZE_INC;
463 gdk_window_set_geometry_hints(toplevel->window, &geom, flags);
464
465 gdk_color_parse("white", &white);
466 gdk_color_parse("black", &black);
467 }
468
469 static void
gtk_ui_graphics_init(void)470 gtk_ui_graphics_init(void) {
471 offscreen = gdk_pixmap_new(field->window, screensize, screensize, -1);
472 stdgc = gdk_gc_new(offscreen);
473 gdk_gc_set_exposures(stdgc, FALSE);
474 gdk_gc_set_line_attributes(stdgc, 2, GDK_LINE_SOLID, GDK_CAP_ROUND,
475 GDK_JOIN_MITER);
476 font = gdk_font_load("fixed");
477 }
478
479 static GtkWidget *
new_button(GtkWidget * dialog,const char * text,GtkSignalFunc func,GtkObject * obj)480 new_button(GtkWidget *dialog, const char *text, GtkSignalFunc func,
481 GtkObject *obj)
482 {
483 GtkWidget *button = gtk_button_new_with_label(text);
484 if (func != NULL)
485 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
486 func, obj);
487 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
488 GTK_SIGNAL_FUNC(gtk_widget_hide),
489 GTK_OBJECT(dialog));
490 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
491 GTK_SIGNAL_FUNC(popdown), NULL);
492 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
493 button);
494 gtk_widget_show(button);
495 return button;
496 }
497
498 static void
CreateDialog(int index,int hascancel,Picture * icon,const char * buttonlabel,GtkSignalFunc func)499 CreateDialog(int index, int hascancel, Picture *icon,
500 const char *buttonlabel, GtkSignalFunc func)
501 {
502 GtkWidget *dialog, *pixmap, *label, *hbox;
503
504 dialog = gtk_dialog_new();
505 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
506
507 hbox = gtk_hbox_new(FALSE, 0);
508
509 if (icon != NULL) {
510 pixmap = gtk_pixmap_new(icon->pix, icon->mask);
511 gtk_container_add(GTK_CONTAINER(hbox), pixmap);
512 }
513
514 label = gtk_label_new(UI_dialog_string(index));
515 gtk_container_add(GTK_CONTAINER(hbox), label);
516
517 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
518 gtk_widget_show_all(hbox);
519
520 if (buttonlabel == NULL)
521 buttonlabel = "OK";
522 new_button(dialog, buttonlabel, func, NULL);
523
524 if (hascancel)
525 new_button(dialog, "Cancel", NULL, NULL);
526
527 gtk_widget_realize(dialog);
528 dialogs[index] = dialog;
529 }
530
531 static void
CreateEnterText(int index,GtkSignalFunc func)532 CreateEnterText(int index, GtkSignalFunc func) {
533 GtkWidget *dialog, *label, *entry;
534
535 dialog = gtk_dialog_new();
536 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
537
538 label = gtk_label_new(UI_dialog_string(index));
539 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
540 gtk_widget_show(label);
541
542 entry = gtk_entry_new_with_max_length(20);
543 gtk_signal_connect_object(GTK_OBJECT(entry), "activate",
544 func, GTK_OBJECT(entry));
545 gtk_signal_connect_object(GTK_OBJECT(entry), "activate",
546 GTK_SIGNAL_FUNC(gtk_widget_hide),
547 GTK_OBJECT(dialog));
548 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), entry);
549 gtk_widget_show(entry);
550
551 new_button(dialog, "OK", func, GTK_OBJECT(entry));
552
553 gtk_widget_realize(dialog);
554 dialogs[index] = dialog;
555 }
556
557 static void
CreatePixmapBox(int index,Picture * logo,Picture * pix)558 CreatePixmapBox(int index, Picture *logo, Picture *pix) {
559 GtkWidget *dialog, *pixmap, *label;
560 const char *text = UI_dialog_string(index);
561
562 dialog = gtk_dialog_new();
563 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
564
565 pixmap = gtk_pixmap_new(logo->pix, logo->mask);
566 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), pixmap);
567 gtk_widget_show(pixmap);
568
569 if (pix != NULL) {
570 pixmap = gtk_pixmap_new(pix->pix, pix->mask);
571 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
572 pixmap);
573 gtk_widget_show(pixmap);
574 }
575
576 if (text != NULL) {
577 label = gtk_label_new(text);
578 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
579 label);
580 gtk_widget_show(label);
581 }
582
583 new_button(dialog, "OK", NULL, NULL);
584
585 gtk_widget_realize(dialog);
586 dialogs[index] = dialog;
587 }
588
589 static void
gtk_ui_create_dialogs(Picture * logo,Picture * icon,Picture * about)590 gtk_ui_create_dialogs(Picture *logo, Picture *icon, Picture *about) {
591 CreateDialog(DIALOG_NEWGAME, 1, NULL, NULL, new_game);
592 CreateDialog(DIALOG_PAUSEGAME, 0, icon, "Continue", NULL);
593 CreateEnterText(DIALOG_WARPLEVEL, warp_apply);
594 CreateDialog(DIALOG_HIGHSCORE, 0, NULL, NULL, NULL);
595 CreateDialog(DIALOG_QUITGAME, 1, NULL, NULL, quit_game);
596
597 CreatePixmapBox(DIALOG_STORY, logo, NULL);
598 CreatePixmapBox(DIALOG_RULES, logo, NULL);
599 CreatePixmapBox(DIALOG_ABOUT, logo, about);
600
601 CreateDialog(DIALOG_SCORE, 0, NULL, NULL, NULL);
602 CreateDialog(DIALOG_ENDGAME, 0, NULL, "Nuts!", NULL);
603 CreateEnterText(DIALOG_ENTERNAME, enter_name);
604 }
605
606 static void
set_label(GtkWidget * dialog,const char * str)607 set_label(GtkWidget *dialog, const char *str) {
608 GList *list;
609 GtkWidget *hbox = NULL;
610
611 list = gtk_container_children(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox));
612 while (list != NULL) {
613 GtkWidget *w = (GtkWidget *) list->data;
614 list = g_list_next(list);
615 if (GTK_IS_HBOX(w)) {
616 hbox = w;
617 break;
618 }
619 }
620 if (hbox == NULL)
621 return;
622 list = gtk_container_children(GTK_CONTAINER(hbox));
623 while (list != NULL) {
624 GtkWidget *w = (GtkWidget *) list->data;
625 list = g_list_next(list);
626 if (GTK_IS_LABEL(w)) {
627 gtk_label_set_text(GTK_LABEL(w), str);
628 return;
629 }
630 }
631 }
632
633 static void
gtk_ui_update_dialog(int index,const char * str)634 gtk_ui_update_dialog(int index, const char *str) {
635 set_label(dialogs[index], str);
636 }
637
638 static void
gtk_ui_set_pausebutton(int active)639 gtk_ui_set_pausebutton(int active) {
640 if (pausebutton != NULL)
641 gtk_widget_set_sensitive(pausebutton, active);
642 }
643
644 static struct UI_methods gtk_methods = {
645 gtk_ui_set_cursor,
646 gtk_ui_load_cursor,
647 gtk_ui_load_picture,
648 gtk_ui_set_icon,
649 gtk_ui_picture_width,
650 gtk_ui_picture_height,
651 gtk_ui_graphics_init,
652 gtk_ui_clear_window,
653 gtk_ui_refresh_window,
654 gtk_ui_draw_image,
655 gtk_ui_draw_line,
656 gtk_ui_draw_string,
657 gtk_ui_start_timer,
658 gtk_ui_stop_timer,
659 gtk_ui_timer_active,
660 gtk_ui_popup_dialog,
661 gtk_ui_main_loop,
662 gtk_ui_initialize,
663 gtk_ui_make_main_window,
664 gtk_ui_create_dialogs,
665 gtk_ui_set_pausebutton,
666 gtk_ui_update_dialog,
667 };
668
669 void
gtk_ui_setmethods(UI_methods ** methodsp)670 gtk_ui_setmethods(UI_methods **methodsp) {
671 *methodsp = >k_methods;
672 }
673