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 = &gtk_methods;
673 }
674