nkeynes@464: /** nkeynes@508: * $Id: gdrom_menu.c,v 1.5 2007-11-10 04:45:29 nkeynes Exp $ nkeynes@464: * nkeynes@464: * Creates and manages the GD-Rom attachment menu. nkeynes@464: * nkeynes@464: * Copyright (c) 2005 Nathan Keynes. nkeynes@464: * nkeynes@464: * This program is free software; you can redistribute it and/or modify nkeynes@464: * it under the terms of the GNU General Public License as published by nkeynes@464: * the Free Software Foundation; either version 2 of the License, or nkeynes@464: * (at your option) any later version. nkeynes@464: * nkeynes@464: * This program is distributed in the hope that it will be useful, nkeynes@464: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@464: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@464: * GNU General Public License for more details. nkeynes@464: */ nkeynes@464: nkeynes@464: #include nkeynes@464: #include nkeynes@508: #include nkeynes@464: nkeynes@464: #include "dream.h" nkeynes@464: #include "dreamcast.h" nkeynes@464: #include "config.h" nkeynes@464: #include "gdrom/gdrom.h" nkeynes@464: #include "gui/gtkui.h" nkeynes@464: nkeynes@464: #define MAX_RECENT_ITEMS 5 nkeynes@464: nkeynes@464: static GList *gdrom_menu_list = NULL; nkeynes@464: static gboolean gdrom_menu_adjusting = FALSE; nkeynes@464: static GList *gdrom_device_list = NULL; nkeynes@464: static GList *gdrom_recent_list = NULL; nkeynes@464: nkeynes@464: void gdrom_menu_rebuild_all(); nkeynes@464: nkeynes@464: nkeynes@464: gint gdrom_menu_find_item( const gchar *name ) nkeynes@464: { nkeynes@464: gint posn = 0; nkeynes@464: GList *ptr; nkeynes@464: nkeynes@464: for( ptr = gdrom_device_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@464: gchar *device = (gchar *)ptr->data; nkeynes@464: posn++; nkeynes@464: if( strcmp(device, name) == 0 ) { nkeynes@464: return posn; nkeynes@464: } nkeynes@464: } nkeynes@464: posn++; nkeynes@464: for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@464: gchar *file = (gchar *)ptr->data; nkeynes@464: posn++; nkeynes@464: if( strcmp(file, name) == 0 ) { nkeynes@464: return posn; nkeynes@464: } nkeynes@464: } nkeynes@464: return -1; nkeynes@464: } nkeynes@464: nkeynes@464: gint gdrom_menu_add_recent_item( const gchar *name ) nkeynes@464: { nkeynes@464: gdrom_recent_list = g_list_prepend( gdrom_recent_list, g_strdup(name) ); nkeynes@464: if( g_list_length(gdrom_recent_list) > MAX_RECENT_ITEMS ) { nkeynes@464: GList *ptr = g_list_nth( gdrom_recent_list, MAX_RECENT_ITEMS ); nkeynes@464: g_free( ptr->data ); nkeynes@464: gdrom_recent_list = g_list_remove( gdrom_recent_list, ptr->data ); nkeynes@464: } nkeynes@470: nkeynes@470: GList *ptr; nkeynes@479: int size = 0; nkeynes@470: for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@470: size += strlen( (gchar *)ptr->data ) + 1; nkeynes@470: } nkeynes@470: char buf[size]; nkeynes@470: strcpy( buf, (gchar *)gdrom_recent_list->data ); nkeynes@470: ptr = g_list_next(gdrom_recent_list); nkeynes@470: while( ptr != NULL ) { nkeynes@470: strcat( buf, ":" ); nkeynes@470: strcat( buf, (gchar *)ptr->data ); nkeynes@470: ptr = g_list_next(ptr); nkeynes@470: } nkeynes@470: lxdream_set_global_config_value( CONFIG_RECENT, buf ); nkeynes@470: lxdream_save_config(); nkeynes@470: nkeynes@464: return g_list_length( gdrom_device_list ) + 2; // menu posn of new item nkeynes@464: } nkeynes@464: nkeynes@464: void gdrom_menu_update_all() nkeynes@464: { nkeynes@464: gdrom_disc_t disc = gdrom_get_current_disc(); nkeynes@464: gint posn = 0; nkeynes@464: GList *ptr; nkeynes@464: nkeynes@464: gdrom_menu_adjusting = TRUE; nkeynes@464: nkeynes@464: if( disc != NULL ) { nkeynes@464: posn = gdrom_menu_find_item( disc->name ); nkeynes@464: if( posn == -1 ) { nkeynes@464: posn = gdrom_menu_add_recent_item( disc->name ); nkeynes@464: gdrom_menu_rebuild_all(); nkeynes@464: } nkeynes@464: } nkeynes@464: nkeynes@464: for( ptr = gdrom_menu_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@464: GtkWidget *menu = GTK_WIDGET(ptr->data); nkeynes@464: GList *children = gtk_container_get_children( GTK_CONTAINER(menu) ); nkeynes@464: GList *item = g_list_nth( children, posn ); nkeynes@464: assert( item != NULL ); nkeynes@464: gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item->data), TRUE ); nkeynes@464: g_list_free(children); nkeynes@464: } nkeynes@464: nkeynes@464: gdrom_menu_adjusting = FALSE; nkeynes@464: } nkeynes@464: nkeynes@464: void gdrom_menu_empty_callback( GtkWidget *widget, gpointer user_data ) nkeynes@464: { nkeynes@464: if( !gdrom_menu_adjusting ) { nkeynes@464: gdrom_unmount_disc(); nkeynes@464: gdrom_menu_update_all(); nkeynes@470: lxdream_set_global_config_value( CONFIG_GDROM, NULL ); nkeynes@470: lxdream_save_config(); nkeynes@464: } nkeynes@464: } nkeynes@464: nkeynes@469: gboolean gdrom_menu_open_file( const char *filename ) nkeynes@464: { nkeynes@469: gboolean result = FALSE; nkeynes@464: if( filename != NULL ) { nkeynes@469: result = gdrom_mount_image(filename); nkeynes@464: } nkeynes@469: if( result ) { nkeynes@469: gdrom_menu_update_all(); nkeynes@470: lxdream_set_global_config_value( CONFIG_GDROM, filename ); nkeynes@470: lxdream_save_config(); nkeynes@469: } nkeynes@469: return result; nkeynes@464: } nkeynes@464: nkeynes@464: void gdrom_menu_open_image_callback( GtkWidget *widget, gpointer user_data ) nkeynes@464: { nkeynes@464: if( !gdrom_menu_adjusting ) { nkeynes@464: const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH); nkeynes@508: open_file_dialog( _("Open..."), gdrom_menu_open_file, NULL, NULL, dir ); nkeynes@464: } nkeynes@464: } nkeynes@464: nkeynes@464: nkeynes@464: void gdrom_menu_open_specified_callback( GtkWidget *widget, gpointer user_data ) nkeynes@464: { nkeynes@464: if( !gdrom_menu_adjusting ) { nkeynes@464: gdrom_menu_open_file( (gchar *)user_data ); nkeynes@464: } nkeynes@464: } nkeynes@464: nkeynes@464: void gdrom_menu_build( GtkWidget *menu ) nkeynes@464: { nkeynes@464: GSList *group = NULL; nkeynes@508: GtkWidget *empty = gtk_radio_menu_item_new_with_label( group, _("Empty") ); nkeynes@464: group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(empty) ); nkeynes@464: g_signal_connect_after( empty, "activate", G_CALLBACK(gdrom_menu_empty_callback), NULL ); nkeynes@464: gtk_menu_shell_append( GTK_MENU_SHELL(menu), empty ); nkeynes@464: nkeynes@464: GList *ptr; nkeynes@464: for( ptr = gdrom_device_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@464: gchar *name = (gchar *)ptr->data; nkeynes@464: GtkWidget *item = gtk_radio_menu_item_new_with_label( group, name); nkeynes@464: gtk_widget_set_name( item, name ); nkeynes@464: group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) ); nkeynes@464: g_signal_connect_after( item, "activate", G_CALLBACK(gdrom_menu_open_specified_callback), nkeynes@464: name ); nkeynes@464: gtk_menu_shell_append( GTK_MENU_SHELL(menu), item ); nkeynes@464: } nkeynes@464: nkeynes@464: if( gdrom_recent_list != NULL ) { nkeynes@464: gtk_menu_shell_append( GTK_MENU_SHELL(menu), gtk_separator_menu_item_new() ); nkeynes@464: for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@464: gchar *path = (gchar *)ptr->data; nkeynes@464: gchar *name = basename(path); nkeynes@464: GtkWidget *item = gtk_radio_menu_item_new_with_label( group, name ); nkeynes@464: gtk_widget_set_name( item, path ); nkeynes@464: group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) ); nkeynes@464: g_signal_connect_after( item, "activate", G_CALLBACK(gdrom_menu_open_specified_callback), nkeynes@464: path ); nkeynes@464: gtk_menu_shell_append( GTK_MENU_SHELL(menu), item ); nkeynes@464: nkeynes@464: } nkeynes@464: } nkeynes@464: gtk_menu_shell_append( GTK_MENU_SHELL(menu), gtk_separator_menu_item_new() ); nkeynes@508: GtkWidget *open = gtk_image_menu_item_new_with_label( _("Open image file...") ); nkeynes@464: g_signal_connect_after( open, "activate", G_CALLBACK(gdrom_menu_open_image_callback), NULL ); nkeynes@464: gtk_menu_shell_append( GTK_MENU_SHELL(menu), open ); nkeynes@464: gtk_widget_show_all(menu); nkeynes@464: } nkeynes@464: nkeynes@464: GtkWidget *gdrom_menu_new() nkeynes@464: { nkeynes@464: GtkWidget *menu = gtk_menu_new(); nkeynes@508: gtk_menu_set_title( GTK_MENU(menu), _("GD-Rom Settings") ); nkeynes@464: nkeynes@464: gdrom_menu_build(menu); nkeynes@464: nkeynes@464: gdrom_menu_list = g_list_append(gdrom_menu_list, menu); nkeynes@464: gtk_widget_show_all(menu); nkeynes@464: gdrom_menu_update_all(); nkeynes@464: return menu; nkeynes@464: } nkeynes@464: nkeynes@464: void gdrom_menu_rebuild_all() nkeynes@464: { nkeynes@464: GList *ptr; nkeynes@464: nkeynes@464: for( ptr = gdrom_menu_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@464: GtkWidget *menu = GTK_WIDGET(ptr->data); nkeynes@464: GList *children = gtk_container_get_children( GTK_CONTAINER(menu) ); nkeynes@464: GList *listptr; nkeynes@464: for( listptr = children; listptr != NULL; listptr = g_list_next(listptr) ) { nkeynes@464: gtk_widget_destroy( GTK_WIDGET(listptr->data) ); nkeynes@464: } nkeynes@464: g_list_free(children); nkeynes@464: gdrom_menu_build(menu); nkeynes@464: } nkeynes@464: gdrom_menu_update_all(); nkeynes@464: } nkeynes@470: nkeynes@470: void gdrom_menu_init() nkeynes@470: { nkeynes@470: const gchar *recent = lxdream_get_config_value( CONFIG_RECENT ); nkeynes@470: gdrom_device_list = gdrom_get_native_devices(); nkeynes@470: if( recent != NULL ) { nkeynes@470: gchar **list = g_strsplit(recent, ":", 5); nkeynes@470: int i; nkeynes@470: for( i=0; list[i] != NULL; i++ ) { nkeynes@470: gdrom_recent_list = g_list_append( gdrom_recent_list, g_strdup(list[i]) ); nkeynes@470: } nkeynes@470: g_strfreev(list); nkeynes@470: } nkeynes@470: }