1 /*
2  * GQradio
3  * (C) 2003 John Ellis
4  *
5  * Author: John Ellis
6  *
7  * This software is released under the GNU General Public License (GNU GPL).
8  * Please read the included file COPYING for more information.
9  * This software comes with no warranty of any kind, use at your own risk!
10  */
11 
12 #include "gqradio.h"
13 #include "window.h"
14 
15 #include "display.h"
16 #include "io_radio.h"
17 #include "preferences.h"
18 #include "skin.h"
19 #include "ui_fileops.h"
20 #include "ui_menu.h"
21 #include "ui2_display.h"
22 #include "ui2_editor.h"
23 #include "ui2_main.h"
24 #include "ui2_menu.h"
25 #include "ui2_parse.h"
26 
27 #include <gdk/gdkkeysyms.h> /* for key values */
28 
29 
30 /*
31  *----------------
32  * the callbacks
33  *----------------
34  */
35 
menu_mute_cb(GtkWidget * widget,gpointer data)36 static void menu_mute_cb(GtkWidget *widget, gpointer data)
37 {
38 	mute_toggle();
39 }
40 
menu_mixer_cb(GtkWidget * widget,gpointer data)41 static void menu_mixer_cb(GtkWidget *widget, gpointer data)
42 {
43 	mixer_run();
44 }
45 
menu_prefs_cb(GtkWidget * widget,gpointer data)46 static void menu_prefs_cb(GtkWidget *widget, gpointer data)
47 {
48 	config_window_show(0);
49 }
50 
menu_editor_cb(GtkWidget * widget,gpointer data)51 static void menu_editor_cb(GtkWidget *widget, gpointer data)
52 {
53 	UIData *ui = data;
54 
55 	edit_window(ui);
56 }
57 
menu_help_cb(GtkWidget * widget,gpointer data)58 static void menu_help_cb(GtkWidget *widget, gpointer data)
59 {
60 	help_window_show("documentation");
61 }
62 
menu_about_cb(GtkWidget * widget,gpointer data)63 static void menu_about_cb(GtkWidget *widget, gpointer data)
64 {
65 	show_about();
66 }
67 
menu_iconify_cb(GtkWidget * widget,gpointer data)68 static void menu_iconify_cb(GtkWidget *widget, gpointer data)
69 {
70 	ui_iconify(main_window);
71 }
72 
menu_close_cb(GtkWidget * widget,gpointer data)73 static void menu_close_cb(GtkWidget *widget, gpointer data)
74 {
75 	UIData *ui = data;
76 
77 	ui_close(ui);
78 }
79 
menu_exit_no_mute_cb(GtkWidget * widget,gpointer data)80 static void menu_exit_no_mute_cb(GtkWidget *widget, gpointer data)
81 {
82 	gqradio_exit(FALSE);
83 }
84 
menu_exit_cb(GtkWidget * widget,gpointer data)85 static void menu_exit_cb(GtkWidget *widget, gpointer data)
86 {
87 	gqradio_exit(TRUE);
88 }
89 
menu_preset_edit_cb(GtkWidget * widget,gpointer data)90 static void menu_preset_edit_cb(GtkWidget *widget, gpointer data)
91 {
92 	config_window_show(2);
93 }
94 
menu_preset_clear_cb(GtkWidget * widget,gpointer data)95 static void menu_preset_clear_cb(GtkWidget *widget, gpointer data)
96 {
97 	preset_clear_one(preset);
98 }
99 
menu_preset_clear_all_cb(GtkWidget * widget,gpointer data)100 static void menu_preset_clear_all_cb(GtkWidget *widget, gpointer data)
101 {
102 	preset_clear_all();
103 }
104 
menu_preset_auto_set_cb(GtkWidget * widget,gpointer data)105 static void menu_preset_auto_set_cb(GtkWidget *widget, gpointer data)
106 {
107 	preset_auto_scan_click();
108 }
109 
menu_seek_manual_cb(GtkWidget * widget,gpointer data)110 static void menu_seek_manual_cb(GtkWidget *widget, gpointer data)
111 {
112 	mode_set(SEEK_MODE_MANUAL);
113 }
114 
menu_seek_preset_cb(GtkWidget * widget,gpointer data)115 static void menu_seek_preset_cb(GtkWidget *widget, gpointer data)
116 {
117 	mode_set(SEEK_MODE_PRESET);
118 }
119 
menu_seek_auto_cb(GtkWidget * widget,gpointer data)120 static void menu_seek_auto_cb(GtkWidget *widget, gpointer data)
121 {
122 	mode_set(SEEK_MODE_AUTO);
123 }
124 
125 /*
126  *----------------
127  * the menus
128  *----------------
129  */
130 
menu_main(UIData * ui)131 static GtkWidget *menu_main(UIData *ui)
132 {
133 	GtkWidget *menu;
134 	GtkWidget *preset_menu;
135 	GtkWidget *seek_menu;
136 	GtkWidget *submenu;
137 
138 	menu = popup_menu_short_lived();
139 
140 	preset_menu = menu_item_add_stock(menu, _("_Presets"), GTK_STOCK_INDEX, NULL, NULL);
141 	seek_menu = menu_item_add(menu, _("_Seek Mode"), NULL, NULL);
142 	menu_item_add_stock(menu, _("Pre_ferences..."), GTK_STOCK_PREFERENCES,
143 		G_CALLBACK(menu_prefs_cb), NULL);
144 	menu_item_add_divider(menu);
145 	menu_item_add_check(menu, _("_Mute"), muted,
146 		G_CALLBACK(menu_mute_cb), NULL);
147 	menu_item_add_stock(menu, _("_Run Mixer..."), GTK_STOCK_EXECUTE,
148 		G_CALLBACK(menu_mixer_cb), NULL);
149 	menu_item_add_divider(menu);
150 	menu_item_add(menu, _("Skin _Editor..."),
151 		G_CALLBACK(menu_editor_cb), ui);
152 	menu_item_add_stock(menu, _("_Help..."), GTK_STOCK_HELP,
153 		G_CALLBACK(menu_help_cb), NULL);
154 	menu_item_add(menu, _("_About..."),
155 		G_CALLBACK(menu_about_cb), NULL);
156 	menu_item_add_divider(menu);
157 	menu_item_add(menu, _("_Iconify"),
158 		G_CALLBACK(menu_iconify_cb), NULL);
159 	if (ui != main_window)
160 		{
161 		menu_item_add_stock(menu, _("Close _Window"), GTK_STOCK_CLOSE,
162 			G_CALLBACK(menu_close_cb), ui);
163 		}
164 	menu_item_add(menu, _("Exit (no mute)"),
165 		G_CALLBACK(menu_exit_no_mute_cb), NULL);
166 	menu_item_add_stock(menu, _("E_xit"), GTK_STOCK_QUIT,
167 		G_CALLBACK(menu_exit_cb), NULL);
168 
169 	submenu = gtk_menu_new();
170 	menu_item_add(submenu, _("_Edit..."),
171 		G_CALLBACK(menu_preset_edit_cb), NULL);
172 	menu_item_add_divider(submenu);
173 
174 	menu_item_add_stock_sensitive(submenu, _("Clear _current"), GTK_STOCK_REMOVE, (preset >= 0),
175 		G_CALLBACK(menu_preset_clear_cb), NULL);
176 
177 	menu_item_add_stock(submenu, _("Clear _all"), GTK_STOCK_CLEAR,
178 		G_CALLBACK(menu_preset_clear_all_cb), NULL);
179 	menu_item_add_divider(submenu);
180 	menu_item_add(submenu, _("Auto _set"),
181 		G_CALLBACK(menu_preset_auto_set_cb), NULL);
182 
183 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(preset_menu), submenu);
184 
185 	submenu = gtk_menu_new();
186 	menu_item_add_check(submenu, _("_Manual"), (seek_mode == SEEK_MODE_MANUAL),
187 		G_CALLBACK(menu_seek_manual_cb), NULL);
188 	menu_item_add_check(submenu, _("_Preset"), (seek_mode == SEEK_MODE_PRESET),
189 		G_CALLBACK(menu_seek_preset_cb), NULL);
190 	menu_item_add_check(submenu, _("_Auto"), (seek_mode == SEEK_MODE_AUTO),
191 		G_CALLBACK(menu_seek_auto_cb), NULL);
192 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(seek_menu), submenu);
193 
194 	return menu;
195 }
196 
197 /*
198  *----------------
199  * the skinned menu
200  *----------------
201  */
202 
menu_skin_mute_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)203 static void menu_skin_mute_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
204 {
205 	mute_toggle();
206 }
207 
menu_skin_mixer_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)208 static void menu_skin_mixer_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
209 {
210 	mixer_run();
211 }
212 
menu_skin_prefs_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)213 static void menu_skin_prefs_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
214 {
215 	config_window_show(0);
216 }
217 
menu_skin_editor_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)218 static void menu_skin_editor_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
219 {
220 	UIData *ui = data;
221 
222 	edit_window(ui);
223 }
224 
menu_skin_help_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)225 static void menu_skin_help_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
226 {
227 	help_window_show("documentation");
228 }
229 
menu_skin_about_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)230 static void menu_skin_about_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
231 {
232 	show_about();
233 }
234 
menu_skin_iconify_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)235 static void menu_skin_iconify_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
236 {
237 	ui_iconify(main_window);
238 }
239 
menu_skin_close_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)240 static void menu_skin_close_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
241 {
242 	UIData *ui = data;
243 
244 	ui_close(ui);
245 }
246 
menu_skin_exit_no_mute_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)247 static void menu_skin_exit_no_mute_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
248 {
249 	gqradio_exit(FALSE);
250 }
251 
menu_skin_exit_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)252 static void menu_skin_exit_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
253 {
254 	gqradio_exit(TRUE);
255 }
256 
menu_skin_preset_edit_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)257 static void menu_skin_preset_edit_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
258 {
259 	config_window_show(2);
260 }
261 
menu_skin_preset_clear_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)262 static void menu_skin_preset_clear_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
263 {
264 	preset_clear_one(preset);
265 }
266 
menu_skin_preset_clear_all_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)267 static void menu_skin_preset_clear_all_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
268 {
269 	preset_clear_all();
270 }
271 
menu_skin_preset_auto_set_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)272 static void menu_skin_preset_auto_set_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
273 {
274 	preset_auto_scan_click();
275 }
276 
menu_skin_seek_manual_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)277 static void menu_skin_seek_manual_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
278 {
279 	mode_set(SEEK_MODE_MANUAL);
280 }
281 
menu_skin_seek_preset_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)282 static void menu_skin_seek_preset_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
283 {
284 	mode_set(SEEK_MODE_PRESET);
285 }
286 
menu_skin_seek_auto_cb(UIMenuData * md,const gchar * path,gint id,gpointer data)287 static void menu_skin_seek_auto_cb(UIMenuData *md, const gchar *path, gint id, gpointer data)
288 {
289 	mode_set(SEEK_MODE_AUTO);
290 }
291 
292 #define DIVIDER_TEXT " ------"
293 
menu_main_skinned(gint button,guint32 event_time,UIData * ui)294 static gint menu_main_skinned(gint button, guint32 event_time, UIData *ui)
295 {
296 	UIMenuData *md;
297 	SkinData *skin;
298 	const gchar *path;
299 	gchar *datafile;
300 
301 	if (!skinned_menus_enable) return FALSE;
302 
303 	if (main_window->skin_path)
304 		{
305 		path = main_window->skin_path;
306 		}
307 	else
308 		{
309 		path = GQRADIO_SKIN_DEFAULT;
310 		}
311 
312 	datafile = g_strconcat(path, "/", "skindata_menu", NULL);
313 	/* must check file existance first, so that skins without
314 	 * menu support do not print an error message (this is not really an error)
315 	 */
316 	if (isfile(datafile))
317 		{
318 		skin = skin_parse(path, datafile, FALSE);
319 		}
320 	else
321 		{
322 		skin = NULL;
323 		}
324 	g_free(datafile);
325 
326 	if (!skin) return FALSE;
327 
328 	md = ui_menu_new("GQradio", "main_menu");
329 	ui_group_set_child(main_window, md->ui);
330 
331 	ui_menu_item_add(md, _("Presets"), "/presets", 0,
332 			 NULL, NULL);
333 	ui_menu_item_add(md, _("Seek Mode"), "/seek_mode", 0,
334 			 NULL, NULL);
335 	ui_menu_item_add(md, _("Preferences..."), "/prefs", 0,
336 			 menu_skin_prefs_cb, NULL);
337 	ui_menu_item_add_sensitive(md, DIVIDER_TEXT, "/div1", 0, FALSE,
338 			 NULL, NULL);
339 	ui_menu_item_add(md, (muted) ? _("UnMute") : _("Mute"), "/mute", 0,
340 			 menu_skin_mute_cb, NULL);
341 	ui_menu_item_add(md, _("Run Mixer..."), "/mixer", 0,
342 			 menu_skin_mixer_cb, NULL);
343 	ui_menu_item_add_sensitive(md, DIVIDER_TEXT, "/div2", 0, FALSE,
344 			 NULL, NULL);
345 	ui_menu_item_add(md, _("Skin Editor..."), "/editor", 0,
346 			 menu_skin_editor_cb, ui);
347 	ui_menu_item_add(md, _("Help..."), "/help", 0,
348 			 menu_skin_help_cb, NULL);
349 	ui_menu_item_add(md, _("About..."), "/about", 0,
350 			 menu_skin_about_cb, NULL);
351 	ui_menu_item_add_sensitive(md, DIVIDER_TEXT, "/div3", 0, FALSE,
352 			 NULL, NULL);
353 	ui_menu_item_add(md, _("Iconify"), "/iconify", 0,
354 			 menu_skin_iconify_cb, NULL);
355 	if (ui != main_window)
356 		{
357 		ui_menu_item_add(md, _("Close Window"), "close/", 0,
358 				 menu_skin_close_cb, NULL);
359 		}
360 	ui_menu_item_add(md, _("Exit (no mute)"), "/exit_no_mute", 0,
361 			 menu_skin_exit_no_mute_cb, NULL);
362 	ui_menu_item_add(md, _("Exit"), "/exit", 0,
363 			 menu_skin_exit_cb, NULL);
364 
365 	ui_menu_item_add(md, _("Edit..."), "/presets/edit", 0,
366 			 menu_skin_preset_edit_cb, NULL);
367 	ui_menu_item_add_sensitive(md, DIVIDER_TEXT, "/presets/div1", 0, FALSE,
368 			 NULL, NULL);
369 	ui_menu_item_add_sensitive(md, _("Clear current"), "/presets/clear_current", 0, (preset >= 0),
370 			 menu_skin_preset_clear_cb, NULL);
371 	ui_menu_item_add(md, _("Clear all"), "/presets/clear_all", 0,
372 			 menu_skin_preset_clear_all_cb, NULL);
373 	ui_menu_item_add_sensitive(md, DIVIDER_TEXT, "/presets/div2", 0, FALSE,
374 			 NULL, NULL);
375 	ui_menu_item_add(md, _("Auto set"), "/presets/auto_set", 0,
376 			 menu_skin_preset_auto_set_cb, NULL);
377 
378 	ui_menu_item_add_check(md, _("Manual"), "/seek_mode/manual", 0, (seek_mode == SEEK_MODE_MANUAL),
379 			 menu_skin_seek_manual_cb, NULL);
380 	ui_menu_item_add_check(md, _("Preset"), "/seek_mode/preset", 0, (seek_mode == SEEK_MODE_PRESET),
381 			 menu_skin_seek_preset_cb, NULL);
382 	ui_menu_item_add_check(md, _("Auto"), "/seek_mode/auto", 0, (seek_mode == SEEK_MODE_AUTO),
383 			 menu_skin_seek_auto_cb, NULL);
384 
385 	ui_skin_set(md->ui, skin, path, "skindata_menu");
386 	ui_menu_show(md, -1, -1, button, event_time);
387 
388 	return TRUE;
389 }
390 
391 /*
392  *----------------
393  * the window
394  *----------------
395  */
396 
397 
edit_window(UIData * ui)398 void edit_window(UIData *ui)
399 {
400 	EditData *ed;
401 
402 	if (!ui) ui = main_window;
403 
404 	ed = ui_edit_new(ui, "slik_test", "skin_editor", NULL);
405 
406 	/* ed is NULL if an edit window is already active for the ui */
407 	if (!ed) return;
408 	ui_edit_set_help_path(ed, GQRADIO_SLIK_HELP_PATH);
409 }
410 
411 static gchar *number_press_buffer = NULL;
412 static gint number_press_id = -1;
413 
number_buffer_do(gint ignore)414 static void number_buffer_do(gint ignore)
415 {
416 	if (number_press_buffer && !ignore)
417 		{
418 
419 		if (number_press_buffer[0] == '0')
420 			{
421 			/* leading 0 indicates a preset */
422 			preset_select(atoi(number_press_buffer + 1) - 1);
423 			}
424 		else
425 			{
426 			guint32 freq;
427 
428 			freq = radio_freq_from_text(number_press_buffer);
429 			if (freq >= radio_limit_get_lower() &&
430 			    freq <= radio_limit_get_upper())
431 				{
432 				seek_to_freq(freq);
433 				}
434 			}
435 		}
436 
437 	if (number_press_buffer)
438 		{
439 		display_set_frequency(frequency);
440 		display_set_description(NULL);
441 		display_hide_minor_digits(FALSE);
442 		}
443 
444 	g_free(number_press_buffer);
445 	number_press_buffer = NULL;
446 }
447 
number_buffer_cb(gpointer data)448 static gint number_buffer_cb(gpointer data)
449 {
450 	number_buffer_do(FALSE);
451 	number_press_id = -1;
452 	return FALSE;
453 }
454 
number_buffer_add(gint keyval)455 static void number_buffer_add(gint keyval)
456 {
457 	gchar *tmp;
458 	gchar *buf;
459 	gchar *ptr;
460 
461 	tmp = number_press_buffer;
462 	number_press_buffer = g_strdup_printf("%s%c", (tmp) ? tmp : "", (char)keyval);
463 	g_free(tmp);
464 
465 	if (number_press_id != -1) g_source_remove(number_press_id);
466 	number_press_id = -1;
467 
468 	ptr = number_press_buffer;
469 
470 	if (*ptr == '0')
471 		{
472 		if (strlen(number_press_buffer) >= 3)
473 			{
474 			number_buffer_do(FALSE);
475 			return;
476 			}
477 		display_hide_minor_digits(TRUE);
478 
479 		buf = g_strdup_printf(_("Preset: %s"), number_press_buffer + 1);
480 		display_set_description(buf);
481 		g_free(buf);
482 		}
483 	else
484 		{
485 		while (*ptr != '.' && *ptr != '\0') ptr++;
486 		if (*ptr == '.')
487 			{
488 			ptr++;
489 			if (ptr[0] != '\0' && ptr[1] != '\0')
490 				{
491 				number_buffer_do(FALSE);
492 				return;
493 				}
494 			}
495 		buf = g_strdup_printf(_("Jump: %s"), number_press_buffer);
496 		display_set_description(buf);
497 		g_free(buf);
498 		}
499 
500 	display_set_frequency(radio_freq_from_text(number_press_buffer));
501 
502 	number_press_id = g_timeout_add(1500, number_buffer_cb, NULL);
503 }
504 
key_pressed(GtkWidget * widget,GdkEventKey * event,gpointer data)505 static gint key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
506 {
507 	UIData *ui = data;
508 	gint was_number = FALSE;
509 
510 	if (debug_mode) printf("key pressed: %d\n", event->keyval);
511 
512 	if (event->state & GDK_CONTROL_MASK)
513 		{
514 		switch (event->keyval)
515 			{
516 			case 'O': case 'o':
517 				config_window_show(0);
518 				break;
519 			case 'E': case 'e':
520 			case 'P': case 'p':
521 				config_window_show(2);
522 				break;
523 			case GDK_Delete: case GDK_KP_Delete:
524 				preset_clear_all();
525 				break;
526 			case '-':
527 			case GDK_KP_Subtract:
528 				btn_balance_left_pressed();
529 				btn_balance_released();
530 				break;
531 			case '+': case '=':
532 			case GDK_KP_Add:
533 				btn_balance_right_pressed();
534 				btn_balance_released();
535 				break;
536 			default:
537 				break;
538 			}
539 		}
540 	else
541 		{
542 		switch (event->keyval)
543 			{
544 			case GDK_Escape:
545 				if (preset_mode_get())
546 					{
547 					preset_cancel();
548 					}
549 				break;
550 			case 'n': case 'N':
551 			case GDK_space:
552 				seek_start(TRUE);
553 				seek_stop();
554 				break;
555 			case 'b': case 'B':
556 			case GDK_BackSpace:
557 				seek_start(FALSE);
558 				seek_stop();
559 				break;
560 			case GDK_Right: case GDK_KP_Right:
561 				mode_set(SEEK_MODE_MANUAL);
562 				seek_start(TRUE);
563 				seek_stop();
564 				break;
565 			case GDK_Left: case GDK_KP_Left:
566 				mode_set(SEEK_MODE_MANUAL);
567 				seek_start(FALSE);
568 				seek_stop();
569 				break;
570 			case GDK_Up: case GDK_KP_Up:
571 				mode_set(SEEK_MODE_AUTO);
572 				seek_start(TRUE);
573 				seek_stop();
574 				break;
575 			case GDK_Down: case GDK_KP_Down:
576 				mode_set(SEEK_MODE_AUTO);
577 				seek_start(FALSE);
578 				seek_stop();
579 				break;
580 			case GDK_Page_Down: case GDK_KP_Page_Down:
581 				preset_prev();
582 				break;
583 			case GDK_Page_Up: case GDK_KP_Page_Up:
584 				preset_next();
585 				break;
586 			case 'M': case 'm':
587 				mute_toggle();
588 				break;
589 			case '-':
590 			case GDK_KP_Subtract:
591 				btn_volume_down_pressed();
592 				btn_volume_released();
593 				break;
594 			case '+': case '=':
595 			case GDK_KP_Add:
596 				btn_volume_up_pressed();
597 				btn_volume_released();
598 				break;
599 			case GDK_Return:
600 				mode_toggle();
601 				break;
602 			case GDK_Delete: case GDK_KP_Delete:
603 				preset_clear_one(preset);
604 				break;
605 			case 'O': case 'o':
606 				config_window_show(0);
607 				break;
608 			case 'E': case 'e':
609 				config_window_show(2);
610 				break;
611 			case 'P': case 'p':
612 				preset_button_click();
613 				break;
614 			case 'I': case 'i':
615 				ui_iconify(main_window);
616 				break;
617 			case 'Q': case 'q':
618 				gqradio_exit(!(event->state & GDK_SHIFT_MASK));
619 				break;
620 			case '!':
621 				ui_debug_print_all_keys(main_window);
622 				break;
623 			case '~': case '`':
624 				edit_window(ui);
625 				break;
626 			case '0':
627 			case '1':
628 			case '2':
629 			case '3':
630 			case '4':
631 			case '5':
632 			case '6':
633 			case '7':
634 			case '8':
635 			case '9':
636 			case '.':
637 				was_number = TRUE;
638 				number_buffer_add(event->keyval);
639 				break;
640 		/* sorry, keypad numbers got ugly */
641 			case GDK_KP_0:
642 				was_number = TRUE;
643 				number_buffer_add('0');
644 				break;
645 			case GDK_KP_1:
646 				was_number = TRUE;
647 				number_buffer_add('1');
648 				break;
649 			case GDK_KP_2:
650 				was_number = TRUE;
651 				number_buffer_add('2');
652 				break;
653 			case GDK_KP_3:
654 				was_number = TRUE;
655 				number_buffer_add('3');
656 				break;
657 			case GDK_KP_4:
658 				was_number = TRUE;
659 				number_buffer_add('4');
660 				break;
661 			case GDK_KP_5:
662 				was_number = TRUE;
663 				number_buffer_add('5');
664 				break;
665 			case GDK_KP_6:
666 				was_number = TRUE;
667 				number_buffer_add('6');
668 				break;
669 			case GDK_KP_7:
670 				was_number = TRUE;
671 				number_buffer_add('7');
672 				break;
673 			case GDK_KP_8:
674 				was_number = TRUE;
675 				number_buffer_add('8');
676 				break;
677 			case GDK_KP_9:
678 				was_number = TRUE;
679 				number_buffer_add('9');
680 				break;
681 			case GDK_KP_Decimal:
682 				was_number = TRUE;
683 				number_buffer_add('.');
684 				break;
685 			case '[':
686 				display_scroll_preset_list(TRUE);
687 				break;
688 			case ']':
689 				display_scroll_preset_list(FALSE);
690 				break;
691 			default:
692 				break;
693 			}
694 		}
695 
696 	if (!was_number) number_buffer_do(TRUE);
697 
698 	return FALSE;
699 }
700 
window_delete_cb(GtkWidget * widget,GdkEventAny * event,gpointer data)701 static gint window_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data)
702 {
703 	gqradio_exit(TRUE);
704 
705 	return TRUE;
706 }
707 
window_main_set_title(const gchar * title)708 void window_main_set_title(const gchar *title)
709 {
710 	if (main_window)
711 		{
712 		gchar *buf;
713 
714 		if (title)
715 			{
716 			buf = g_strconcat(title, " - GQradio", NULL);
717 			}
718 		else
719 			{
720 			buf = g_strdup("GQradio");
721 			}
722 
723 		ui_title_set(main_window, buf);
724 		g_free(buf);
725 		}
726 }
727 
window_main_mouse_cb(UIData * ui,gint button,guint32 time,gpointer data)728 static void window_main_mouse_cb(UIData *ui, gint button, guint32 time, gpointer data)
729 {
730 	if (button == 3)
731 		{
732 		if (!menu_main_skinned(button, time, ui))
733 			{
734 			GtkWidget *menu;
735 
736 			menu = menu_main(ui);
737 			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, time);
738 			}
739 		}
740 	else if (button == 4)
741 		{
742 		btn_volume_up_pressed();
743 		btn_volume_released();
744 		}
745 	else if (button == 5)
746 		{
747 		btn_volume_down_pressed();
748 		btn_volume_released();
749 		}
750 }
751 
window_subwindow_delete_cb(GtkWidget * widget,GdkEventAny * event,gpointer data)752 static gint window_subwindow_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data)
753 {
754 	UIData *ui = data;
755 
756 	ui_close(ui);
757 	return TRUE;
758 }
759 
window_subwindow_cb(UIData * child,const gchar * key,gpointer data)760 static void window_subwindow_cb(UIData *child, const gchar *key, gpointer data)
761 {
762 	g_signal_connect(G_OBJECT(child->window), "delete_event",
763 			 G_CALLBACK(window_subwindow_delete_cb), child);
764 	g_signal_connect(G_OBJECT(child->display), "key_press_event",
765 			 G_CALLBACK(key_pressed), child);
766 
767 	ui_set_icon(child, gqradio_logo_xpm, NULL, NULL);
768 	ui_title_set(child, _("GQradio"));
769 }
770 
window_main_new(const gchar * skin_path)771 UIData *window_main_new(const gchar *skin_path)
772 {
773 	UIData *ui;
774 
775 	ui = ui_new("GQradio", "main", wm_decorations, "GQradio");
776 	ui_set_icon(ui, gqradio_logo_xpm, NULL, NULL);
777 
778 	ui_set_skin_callback(ui, skin_load_default_cb, NULL);
779 
780 	g_signal_connect(G_OBJECT(ui->window), "delete_event",
781 			 G_CALLBACK(window_delete_cb), ui);
782 	g_signal_connect(G_OBJECT(ui->window), "key_press_event",
783 			 G_CALLBACK(key_pressed), ui);
784 
785 	ui_set_mouse_callback(ui, window_main_mouse_cb, ui);
786 	ui_set_new_window_callback(ui, window_subwindow_cb, NULL);
787 
788 	/* register the right stuff */
789 	display_register_widgets(ui);
790 
791 	if (skin_path)
792 		{
793 		printf(_("loading skin..\n"));
794 		if (!ui_skin_load(ui, skin_path, NULL))
795 			{
796 			if (skin_default_path)
797 				{
798 				if (!ui_skin_load(ui, skin_default_path, skin_mode_key))
799 					{
800 					printf(_("Default skin not loaded, using built-in default\n"));
801 					ui_skin_load(ui, NULL, NULL);
802 					}
803 				}
804 			else
805 				{
806 				printf(_("Skin not loaded, using built-in default\n"));
807 				ui_skin_load(ui, NULL, NULL);
808 				}
809 			}
810 		}
811 	else if (skin_default_path)
812 		{
813 		if (!ui_skin_load(ui, skin_default_path, skin_mode_key))
814 			{
815 			printf(_("Skin in config file not loaded, using built-in default\n"));
816 			ui_skin_load(ui, NULL, NULL);
817 			}
818 		}
819 	else
820 		{
821 		ui_skin_load(ui, NULL, skin_mode_key);
822 		}
823 
824 	return ui;
825 }
826