nkeynes@691: /** nkeynes@691: * $Id$ nkeynes@691: * nkeynes@691: * GD-Rom list manager - maintains the list of recently accessed images and nkeynes@691: * available devices for the UI + config. nkeynes@691: * nkeynes@691: * Copyright (c) 2005 Nathan Keynes. nkeynes@691: * nkeynes@691: * This program is free software; you can redistribute it and/or modify nkeynes@691: * it under the terms of the GNU General Public License as published by nkeynes@691: * the Free Software Foundation; either version 2 of the License, or nkeynes@691: * (at your option) any later version. nkeynes@691: * nkeynes@691: * This program is distributed in the hope that it will be useful, nkeynes@691: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@691: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@691: * GNU General Public License for more details. nkeynes@691: */ nkeynes@691: nkeynes@691: #include nkeynes@691: #include nkeynes@691: #include nkeynes@691: #include nkeynes@755: #include "gettext.h" nkeynes@691: #include "gdrom/gdrom.h" nkeynes@1097: #include "drivers/cdrom/drive.h" nkeynes@691: #include "gdlist.h" nkeynes@691: #include "lxdream.h" nkeynes@691: #include "config.h" nkeynes@691: nkeynes@691: #define MAX_RECENT_ITEMS 5 nkeynes@691: nkeynes@691: #define FIRST_RECENT_INDEX (gdrom_device_count+2) nkeynes@691: nkeynes@691: DEFINE_HOOK(gdrom_list_change_hook, gdrom_list_change_hook_t); nkeynes@691: nkeynes@691: static GList *gdrom_device_list = NULL; nkeynes@691: static GList *gdrom_recent_list = NULL; nkeynes@691: static unsigned int gdrom_device_count = 0, gdrom_recent_count = 0; nkeynes@691: nkeynes@691: gint gdrom_list_find( const gchar *name ) nkeynes@691: { nkeynes@691: gint posn = 0; nkeynes@691: GList *ptr; nkeynes@691: nkeynes@691: for( ptr = gdrom_device_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@1097: cdrom_drive_t device = (cdrom_drive_t)ptr->data; nkeynes@691: posn++; nkeynes@709: if( strcmp(device->name, name) == 0 ) { nkeynes@691: return posn; nkeynes@691: } nkeynes@691: } nkeynes@691: posn++; nkeynes@691: for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@691: gchar *file = (gchar *)ptr->data; nkeynes@691: posn++; nkeynes@691: if( strcmp(file, name) == 0 ) { nkeynes@691: return posn; nkeynes@691: } nkeynes@691: } nkeynes@691: return -1; nkeynes@691: } nkeynes@691: nkeynes@691: /** nkeynes@691: * Update the recent list in the lxdream config (but does not save) nkeynes@691: */ nkeynes@691: void gdrom_list_update_config() nkeynes@691: { nkeynes@1034: lxdream_set_global_config_list_value( CONFIG_RECENT, gdrom_recent_list ); nkeynes@691: } nkeynes@691: nkeynes@691: nkeynes@691: void gdrom_list_add_recent_item( const gchar *name ) nkeynes@691: { nkeynes@691: gdrom_recent_list = g_list_prepend( gdrom_recent_list, g_strdup(name) ); nkeynes@691: if( g_list_length(gdrom_recent_list) > MAX_RECENT_ITEMS ) { nkeynes@691: GList *ptr = g_list_nth( gdrom_recent_list, MAX_RECENT_ITEMS ); nkeynes@691: g_free( ptr->data ); nkeynes@691: gdrom_recent_list = g_list_remove( gdrom_recent_list, ptr->data ); nkeynes@691: } else { nkeynes@691: gdrom_recent_count ++; nkeynes@691: } nkeynes@691: gdrom_list_update_config(); nkeynes@691: } nkeynes@691: nkeynes@691: void gdrom_list_move_to_front( const gchar *name ) nkeynes@691: { nkeynes@691: GList *ptr; nkeynes@691: for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) { nkeynes@691: gchar *file = (gchar *)ptr->data; nkeynes@691: if( strcmp(file, name) == 0 ) { nkeynes@691: gdrom_recent_list = g_list_delete_link( gdrom_recent_list, ptr ); nkeynes@691: gdrom_recent_list = g_list_prepend( gdrom_recent_list, file ); nkeynes@691: gdrom_list_update_config(); nkeynes@691: return; nkeynes@691: } nkeynes@691: } nkeynes@691: } nkeynes@691: nkeynes@691: /** nkeynes@691: * Disc-changed callback from the GD-Rom driver. Updates the list accordingly. nkeynes@691: */ nkeynes@1097: gboolean gdrom_list_disc_changed( cdrom_disc_t disc, const gchar *disc_name, void *user_data ) nkeynes@691: { nkeynes@691: gboolean list_changed = FALSE; nkeynes@691: int posn = 0; nkeynes@691: if( disc != NULL ) { nkeynes@691: posn = gdrom_list_find( disc_name ); nkeynes@691: if( posn == -1 ) { nkeynes@691: gdrom_list_add_recent_item( disc_name ); nkeynes@691: posn = FIRST_RECENT_INDEX; nkeynes@691: list_changed = TRUE; nkeynes@691: } else if( posn > FIRST_RECENT_INDEX ) { nkeynes@691: gdrom_list_move_to_front( disc_name ); nkeynes@691: posn = FIRST_RECENT_INDEX; nkeynes@691: list_changed = TRUE; nkeynes@691: } nkeynes@691: } nkeynes@736: nkeynes@1036: lxdream_set_global_config_path_value( CONFIG_GDROM, disc_name ); nkeynes@691: lxdream_save_config(); nkeynes@691: nkeynes@691: CALL_HOOKS( gdrom_list_change_hook, list_changed, posn ); nkeynes@691: return TRUE; nkeynes@691: } nkeynes@691: nkeynes@691: /** nkeynes@691: * Drives-changed callback from the host CD-Rom drivers. Probably not likely to nkeynes@691: * happen too often unless you're adding/removing external drives... nkeynes@691: */ nkeynes@691: void gdrom_list_drives_changed( GList *device_list ) nkeynes@691: { nkeynes@691: } nkeynes@691: nkeynes@691: /************ Public interface ***********/ nkeynes@691: nkeynes@691: void gdrom_list_init() nkeynes@691: { nkeynes@1034: gdrom_recent_list = lxdream_get_global_config_list_value( CONFIG_RECENT ); nkeynes@691: register_gdrom_disc_change_hook( gdrom_list_disc_changed, NULL ); nkeynes@1097: cdrom_drive_scan(); nkeynes@1097: gdrom_device_list = cdrom_drive_get_list(); nkeynes@691: gdrom_device_count = g_list_length(gdrom_device_list); nkeynes@691: gdrom_recent_count = g_list_length(gdrom_recent_list); nkeynes@736: nkeynes@691: // Run the hooks in case anyone registered before the list was initialized nkeynes@691: CALL_HOOKS( gdrom_list_change_hook, TRUE, gdrom_list_get_selection() ); nkeynes@691: } nkeynes@691: nkeynes@1109: gboolean gdrom_list_set_selection( int posn, ERROR *err ) nkeynes@691: { nkeynes@691: if( posn == 0 ) { // Always 'Empty' nkeynes@691: gdrom_unmount_disc(); nkeynes@691: return TRUE; nkeynes@691: } nkeynes@736: nkeynes@691: if( posn <= gdrom_device_count ) { nkeynes@1097: cdrom_drive_t device = g_list_nth_data(gdrom_device_list, posn-1); nkeynes@1109: return gdrom_mount_image(device->name, err); nkeynes@691: } nkeynes@736: nkeynes@691: posn -= FIRST_RECENT_INDEX; nkeynes@691: if( posn >= 0 && posn < gdrom_recent_count ) { nkeynes@691: gchar *entry = g_list_nth_data(gdrom_recent_list, posn); nkeynes@1109: return gdrom_mount_image(entry, err); nkeynes@691: } nkeynes@736: nkeynes@1109: /* Should never happen */ nkeynes@1109: SET_ERROR( err, LX_ERR_BUG, "Invalid selection: This is probably a bug" ); nkeynes@691: return FALSE; nkeynes@691: } nkeynes@691: nkeynes@691: gint gdrom_list_get_selection( ) nkeynes@691: { nkeynes@691: const char *name = gdrom_get_current_disc_name(); nkeynes@691: if( name == NULL ) { nkeynes@691: return 0; nkeynes@691: } else { nkeynes@691: return gdrom_list_find(name); nkeynes@691: } nkeynes@691: } nkeynes@691: nkeynes@691: int gdrom_list_size() nkeynes@691: { nkeynes@691: return gdrom_device_count + gdrom_recent_count + 2; nkeynes@691: } nkeynes@691: nkeynes@691: const gchar *gdrom_list_get_display_name( int posn ) nkeynes@691: { nkeynes@691: if( posn == 0 ) { nkeynes@691: return _("Empty"); nkeynes@691: } nkeynes@736: nkeynes@691: if( posn <= gdrom_device_count ) { nkeynes@1097: cdrom_drive_t device = g_list_nth_data(gdrom_device_list, posn-1); nkeynes@1097: return device->display_name; nkeynes@691: } nkeynes@736: nkeynes@691: if( posn == gdrom_device_count + 1) { nkeynes@691: return ""; nkeynes@691: } nkeynes@736: nkeynes@691: if( posn < 0 || posn > gdrom_list_size() ) { nkeynes@691: return NULL; nkeynes@691: } nkeynes@691: nkeynes@691: gchar *entry = g_list_nth_data(gdrom_recent_list, posn-FIRST_RECENT_INDEX); nkeynes@691: return basename(entry); nkeynes@691: } nkeynes@696: nkeynes@696: const gchar *gdrom_list_get_filename( int posn ) nkeynes@696: { nkeynes@736: if( posn == 0 ) { nkeynes@736: return _("Empty"); nkeynes@736: } nkeynes@696: nkeynes@736: if( posn <= gdrom_device_count ) { nkeynes@1097: cdrom_drive_t device = g_list_nth_data(gdrom_device_list, posn-1); nkeynes@736: return device->name; nkeynes@736: } nkeynes@736: nkeynes@736: if( posn == gdrom_device_count + 1) { nkeynes@736: return ""; nkeynes@736: } nkeynes@736: nkeynes@736: if( posn < 0 || posn > gdrom_list_size() ) { nkeynes@736: return NULL; nkeynes@736: } nkeynes@736: nkeynes@736: return g_list_nth_data(gdrom_recent_list, posn-FIRST_RECENT_INDEX); nkeynes@696: }