nkeynes@691 | 1 | /**
|
nkeynes@691 | 2 | * $Id$
|
nkeynes@691 | 3 | *
|
nkeynes@691 | 4 | * GD-Rom list manager - maintains the list of recently accessed images and
|
nkeynes@691 | 5 | * available devices for the UI + config.
|
nkeynes@691 | 6 | *
|
nkeynes@691 | 7 | * Copyright (c) 2005 Nathan Keynes.
|
nkeynes@691 | 8 | *
|
nkeynes@691 | 9 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@691 | 10 | * it under the terms of the GNU General Public License as published by
|
nkeynes@691 | 11 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@691 | 12 | * (at your option) any later version.
|
nkeynes@691 | 13 | *
|
nkeynes@691 | 14 | * This program is distributed in the hope that it will be useful,
|
nkeynes@691 | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@691 | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@691 | 17 | * GNU General Public License for more details.
|
nkeynes@691 | 18 | */
|
nkeynes@691 | 19 |
|
nkeynes@691 | 20 | #include <string.h>
|
nkeynes@691 | 21 | #include <stdlib.h>
|
nkeynes@691 | 22 | #include <glib/gstrfuncs.h>
|
nkeynes@691 | 23 | #include <libgen.h>
|
nkeynes@755 | 24 | #include "gettext.h"
|
nkeynes@691 | 25 | #include "gdrom/gdrom.h"
|
nkeynes@691 | 26 | #include "gdlist.h"
|
nkeynes@691 | 27 | #include "lxdream.h"
|
nkeynes@691 | 28 | #include "config.h"
|
nkeynes@691 | 29 |
|
nkeynes@691 | 30 | #define MAX_RECENT_ITEMS 5
|
nkeynes@691 | 31 |
|
nkeynes@691 | 32 | #define FIRST_RECENT_INDEX (gdrom_device_count+2)
|
nkeynes@691 | 33 |
|
nkeynes@691 | 34 | DEFINE_HOOK(gdrom_list_change_hook, gdrom_list_change_hook_t);
|
nkeynes@691 | 35 |
|
nkeynes@691 | 36 | static GList *gdrom_device_list = NULL;
|
nkeynes@691 | 37 | static GList *gdrom_recent_list = NULL;
|
nkeynes@691 | 38 | static unsigned int gdrom_device_count = 0, gdrom_recent_count = 0;
|
nkeynes@691 | 39 |
|
nkeynes@691 | 40 | gint gdrom_list_find( const gchar *name )
|
nkeynes@691 | 41 | {
|
nkeynes@691 | 42 | gint posn = 0;
|
nkeynes@691 | 43 | GList *ptr;
|
nkeynes@691 | 44 |
|
nkeynes@691 | 45 | for( ptr = gdrom_device_list; ptr != NULL; ptr = g_list_next(ptr) ) {
|
nkeynes@709 | 46 | gdrom_device_t device = (gdrom_device_t)ptr->data;
|
nkeynes@691 | 47 | posn++;
|
nkeynes@709 | 48 | if( strcmp(device->name, name) == 0 ) {
|
nkeynes@691 | 49 | return posn;
|
nkeynes@691 | 50 | }
|
nkeynes@691 | 51 | }
|
nkeynes@691 | 52 | posn++;
|
nkeynes@691 | 53 | for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) {
|
nkeynes@691 | 54 | gchar *file = (gchar *)ptr->data;
|
nkeynes@691 | 55 | posn++;
|
nkeynes@691 | 56 | if( strcmp(file, name) == 0 ) {
|
nkeynes@691 | 57 | return posn;
|
nkeynes@691 | 58 | }
|
nkeynes@691 | 59 | }
|
nkeynes@691 | 60 | return -1;
|
nkeynes@691 | 61 | }
|
nkeynes@691 | 62 |
|
nkeynes@691 | 63 | /**
|
nkeynes@691 | 64 | * Update the recent list in the lxdream config (but does not save)
|
nkeynes@691 | 65 | */
|
nkeynes@691 | 66 | void gdrom_list_update_config()
|
nkeynes@691 | 67 | {
|
nkeynes@691 | 68 | GList *ptr;
|
nkeynes@691 | 69 | int size = 0;
|
nkeynes@691 | 70 | for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) {
|
nkeynes@691 | 71 | size += strlen( (gchar *)ptr->data ) + 1;
|
nkeynes@691 | 72 | }
|
nkeynes@691 | 73 | char buf[size];
|
nkeynes@691 | 74 | strcpy( buf, (gchar *)gdrom_recent_list->data );
|
nkeynes@691 | 75 | for( ptr = g_list_next(gdrom_recent_list); ptr != NULL; ptr = g_list_next(ptr) ) {
|
nkeynes@691 | 76 | strcat( buf, ":" );
|
nkeynes@691 | 77 | strcat( buf, (gchar *)ptr->data );
|
nkeynes@691 | 78 | }
|
nkeynes@691 | 79 | lxdream_set_global_config_value( CONFIG_RECENT, buf );
|
nkeynes@691 | 80 | }
|
nkeynes@691 | 81 |
|
nkeynes@691 | 82 |
|
nkeynes@691 | 83 | void gdrom_list_add_recent_item( const gchar *name )
|
nkeynes@691 | 84 | {
|
nkeynes@691 | 85 | gdrom_recent_list = g_list_prepend( gdrom_recent_list, g_strdup(name) );
|
nkeynes@691 | 86 | if( g_list_length(gdrom_recent_list) > MAX_RECENT_ITEMS ) {
|
nkeynes@691 | 87 | GList *ptr = g_list_nth( gdrom_recent_list, MAX_RECENT_ITEMS );
|
nkeynes@691 | 88 | g_free( ptr->data );
|
nkeynes@691 | 89 | gdrom_recent_list = g_list_remove( gdrom_recent_list, ptr->data );
|
nkeynes@691 | 90 | } else {
|
nkeynes@691 | 91 | gdrom_recent_count ++;
|
nkeynes@691 | 92 | }
|
nkeynes@691 | 93 | gdrom_list_update_config();
|
nkeynes@691 | 94 | }
|
nkeynes@691 | 95 |
|
nkeynes@691 | 96 | void gdrom_list_move_to_front( const gchar *name )
|
nkeynes@691 | 97 | {
|
nkeynes@691 | 98 | GList *ptr;
|
nkeynes@691 | 99 | for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) {
|
nkeynes@691 | 100 | gchar *file = (gchar *)ptr->data;
|
nkeynes@691 | 101 | if( strcmp(file, name) == 0 ) {
|
nkeynes@691 | 102 | gdrom_recent_list = g_list_delete_link( gdrom_recent_list, ptr );
|
nkeynes@691 | 103 | gdrom_recent_list = g_list_prepend( gdrom_recent_list, file );
|
nkeynes@691 | 104 | gdrom_list_update_config();
|
nkeynes@691 | 105 | return;
|
nkeynes@691 | 106 | }
|
nkeynes@691 | 107 | }
|
nkeynes@691 | 108 | }
|
nkeynes@691 | 109 |
|
nkeynes@691 | 110 | /**
|
nkeynes@691 | 111 | * Disc-changed callback from the GD-Rom driver. Updates the list accordingly.
|
nkeynes@691 | 112 | */
|
nkeynes@691 | 113 | gboolean gdrom_list_disc_changed( gdrom_disc_t disc, const gchar *disc_name, void *user_data )
|
nkeynes@691 | 114 | {
|
nkeynes@691 | 115 | gboolean list_changed = FALSE;
|
nkeynes@691 | 116 | int posn = 0;
|
nkeynes@691 | 117 | if( disc != NULL ) {
|
nkeynes@691 | 118 | posn = gdrom_list_find( disc_name );
|
nkeynes@691 | 119 | if( posn == -1 ) {
|
nkeynes@691 | 120 | gdrom_list_add_recent_item( disc_name );
|
nkeynes@691 | 121 | posn = FIRST_RECENT_INDEX;
|
nkeynes@691 | 122 | list_changed = TRUE;
|
nkeynes@691 | 123 | } else if( posn > FIRST_RECENT_INDEX ) {
|
nkeynes@691 | 124 | gdrom_list_move_to_front( disc_name );
|
nkeynes@691 | 125 | posn = FIRST_RECENT_INDEX;
|
nkeynes@691 | 126 | list_changed = TRUE;
|
nkeynes@691 | 127 | }
|
nkeynes@691 | 128 | }
|
nkeynes@736 | 129 |
|
nkeynes@691 | 130 | lxdream_set_global_config_value( CONFIG_GDROM, disc_name );
|
nkeynes@691 | 131 | lxdream_save_config();
|
nkeynes@691 | 132 |
|
nkeynes@691 | 133 | CALL_HOOKS( gdrom_list_change_hook, list_changed, posn );
|
nkeynes@691 | 134 | return TRUE;
|
nkeynes@691 | 135 | }
|
nkeynes@691 | 136 |
|
nkeynes@691 | 137 | /**
|
nkeynes@691 | 138 | * Drives-changed callback from the host CD-Rom drivers. Probably not likely to
|
nkeynes@691 | 139 | * happen too often unless you're adding/removing external drives...
|
nkeynes@691 | 140 | */
|
nkeynes@691 | 141 | void gdrom_list_drives_changed( GList *device_list )
|
nkeynes@691 | 142 | {
|
nkeynes@691 | 143 | }
|
nkeynes@691 | 144 |
|
nkeynes@691 | 145 | /************ Public interface ***********/
|
nkeynes@691 | 146 |
|
nkeynes@691 | 147 | void gdrom_list_init()
|
nkeynes@691 | 148 | {
|
nkeynes@691 | 149 | const gchar *recent = lxdream_get_config_value( CONFIG_RECENT );
|
nkeynes@691 | 150 | register_gdrom_disc_change_hook( gdrom_list_disc_changed, NULL );
|
nkeynes@709 | 151 | gdrom_device_list = cdrom_get_native_devices();
|
nkeynes@691 | 152 | if( recent != NULL ) {
|
nkeynes@691 | 153 | gchar **list = g_strsplit(recent, ":", MAX_RECENT_ITEMS);
|
nkeynes@691 | 154 | int i;
|
nkeynes@691 | 155 | for( i=0; list[i] != NULL; i++ ) {
|
nkeynes@691 | 156 | gdrom_recent_list = g_list_append( gdrom_recent_list, g_strdup(list[i]) );
|
nkeynes@691 | 157 | }
|
nkeynes@691 | 158 | g_strfreev(list);
|
nkeynes@691 | 159 | }
|
nkeynes@691 | 160 | gdrom_device_count = g_list_length(gdrom_device_list);
|
nkeynes@691 | 161 | gdrom_recent_count = g_list_length(gdrom_recent_list);
|
nkeynes@736 | 162 |
|
nkeynes@691 | 163 | // Run the hooks in case anyone registered before the list was initialized
|
nkeynes@691 | 164 | CALL_HOOKS( gdrom_list_change_hook, TRUE, gdrom_list_get_selection() );
|
nkeynes@691 | 165 | }
|
nkeynes@691 | 166 |
|
nkeynes@691 | 167 | gboolean gdrom_list_set_selection( int posn )
|
nkeynes@691 | 168 | {
|
nkeynes@691 | 169 | if( posn == 0 ) { // Always 'Empty'
|
nkeynes@691 | 170 | gdrom_unmount_disc();
|
nkeynes@691 | 171 | return TRUE;
|
nkeynes@691 | 172 | }
|
nkeynes@736 | 173 |
|
nkeynes@691 | 174 | if( posn <= gdrom_device_count ) {
|
nkeynes@709 | 175 | gdrom_device_t device = g_list_nth_data(gdrom_device_list, posn-1);
|
nkeynes@709 | 176 | return gdrom_mount_image(device->name);
|
nkeynes@691 | 177 | }
|
nkeynes@736 | 178 |
|
nkeynes@691 | 179 | posn -= FIRST_RECENT_INDEX;
|
nkeynes@691 | 180 | if( posn >= 0 && posn < gdrom_recent_count ) {
|
nkeynes@691 | 181 | gchar *entry = g_list_nth_data(gdrom_recent_list, posn);
|
nkeynes@696 | 182 | return gdrom_mount_image(entry);
|
nkeynes@691 | 183 | }
|
nkeynes@736 | 184 |
|
nkeynes@691 | 185 | return FALSE;
|
nkeynes@691 | 186 | }
|
nkeynes@691 | 187 |
|
nkeynes@691 | 188 | gint gdrom_list_get_selection( )
|
nkeynes@691 | 189 | {
|
nkeynes@691 | 190 | const char *name = gdrom_get_current_disc_name();
|
nkeynes@691 | 191 | if( name == NULL ) {
|
nkeynes@691 | 192 | return 0;
|
nkeynes@691 | 193 | } else {
|
nkeynes@691 | 194 | return gdrom_list_find(name);
|
nkeynes@691 | 195 | }
|
nkeynes@691 | 196 | }
|
nkeynes@691 | 197 |
|
nkeynes@691 | 198 | int gdrom_list_size()
|
nkeynes@691 | 199 | {
|
nkeynes@691 | 200 | return gdrom_device_count + gdrom_recent_count + 2;
|
nkeynes@691 | 201 | }
|
nkeynes@691 | 202 |
|
nkeynes@691 | 203 | const gchar *gdrom_list_get_display_name( int posn )
|
nkeynes@691 | 204 | {
|
nkeynes@691 | 205 | if( posn == 0 ) {
|
nkeynes@691 | 206 | return _("Empty");
|
nkeynes@691 | 207 | }
|
nkeynes@736 | 208 |
|
nkeynes@691 | 209 | if( posn <= gdrom_device_count ) {
|
nkeynes@709 | 210 | gdrom_device_t device = g_list_nth_data(gdrom_device_list, posn-1);
|
nkeynes@709 | 211 | return device->device_name;
|
nkeynes@691 | 212 | }
|
nkeynes@736 | 213 |
|
nkeynes@691 | 214 | if( posn == gdrom_device_count + 1) {
|
nkeynes@691 | 215 | return "";
|
nkeynes@691 | 216 | }
|
nkeynes@736 | 217 |
|
nkeynes@691 | 218 | if( posn < 0 || posn > gdrom_list_size() ) {
|
nkeynes@691 | 219 | return NULL;
|
nkeynes@691 | 220 | }
|
nkeynes@691 | 221 |
|
nkeynes@691 | 222 | gchar *entry = g_list_nth_data(gdrom_recent_list, posn-FIRST_RECENT_INDEX);
|
nkeynes@691 | 223 | return basename(entry);
|
nkeynes@691 | 224 | }
|
nkeynes@696 | 225 |
|
nkeynes@696 | 226 | const gchar *gdrom_list_get_filename( int posn )
|
nkeynes@696 | 227 | {
|
nkeynes@736 | 228 | if( posn == 0 ) {
|
nkeynes@736 | 229 | return _("Empty");
|
nkeynes@736 | 230 | }
|
nkeynes@696 | 231 |
|
nkeynes@736 | 232 | if( posn <= gdrom_device_count ) {
|
nkeynes@736 | 233 | gdrom_device_t device = g_list_nth_data(gdrom_device_list, posn-1);
|
nkeynes@736 | 234 | return device->name;
|
nkeynes@736 | 235 | }
|
nkeynes@736 | 236 |
|
nkeynes@736 | 237 | if( posn == gdrom_device_count + 1) {
|
nkeynes@736 | 238 | return "";
|
nkeynes@736 | 239 | }
|
nkeynes@736 | 240 |
|
nkeynes@736 | 241 | if( posn < 0 || posn > gdrom_list_size() ) {
|
nkeynes@736 | 242 | return NULL;
|
nkeynes@736 | 243 | }
|
nkeynes@736 | 244 |
|
nkeynes@736 | 245 | return g_list_nth_data(gdrom_recent_list, posn-FIRST_RECENT_INDEX);
|
nkeynes@696 | 246 | }
|