filename | src/drivers/cdrom/drive.c |
changeset | 1097:d4807997e450 |
next | 1099:566cdeb157ec |
author | nkeynes |
date | Sun Jan 31 18:35:06 2010 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Refactor CDROM host support - Completely separate GDROM hardware (in gdrom/gdrom.c) from generic CDROM support (now in drivers/cdrom) - Add concept of 'sector sources' that can be mixed and matched to create cdrom discs (makes support of arbitrary disc types much simpler) |
file | annotate | diff | log | raw |
nkeynes@1097 | 1 | /** |
nkeynes@1097 | 2 | * $Id$ |
nkeynes@1097 | 3 | * |
nkeynes@1097 | 4 | * Host CD/DVD drive support. |
nkeynes@1097 | 5 | * |
nkeynes@1097 | 6 | * Copyright (c) 2009 Nathan Keynes. |
nkeynes@1097 | 7 | * |
nkeynes@1097 | 8 | * This program is free software; you can redistribute it and/or modify |
nkeynes@1097 | 9 | * it under the terms of the GNU General Public License as published by |
nkeynes@1097 | 10 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@1097 | 11 | * (at your option) any later version. |
nkeynes@1097 | 12 | * |
nkeynes@1097 | 13 | * This program is distributed in the hope that it will be useful, |
nkeynes@1097 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@1097 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@1097 | 16 | * GNU General Public License for more details. |
nkeynes@1097 | 17 | */ |
nkeynes@1097 | 18 | |
nkeynes@1097 | 19 | #include <stdlib.h> |
nkeynes@1097 | 20 | #include <glib/gstrfuncs.h> |
nkeynes@1097 | 21 | #include <glib/gmem.h> |
nkeynes@1097 | 22 | #include "drivers/cdrom/drive.h" |
nkeynes@1097 | 23 | #include "drivers/cdrom/cdimpl.h" |
nkeynes@1097 | 24 | |
nkeynes@1097 | 25 | static GList *cdrom_drive_list; |
nkeynes@1097 | 26 | |
nkeynes@1097 | 27 | static cdrom_drive_t cdrom_drive_new( const char *name, const char *display_name, cdrom_drive_open_fn_t open_fn ) |
nkeynes@1097 | 28 | { |
nkeynes@1097 | 29 | cdrom_drive_t drive = g_malloc0( sizeof(struct cdrom_drive) ); |
nkeynes@1097 | 30 | drive->name = g_strdup(name); |
nkeynes@1097 | 31 | drive->display_name = g_strdup(display_name); |
nkeynes@1097 | 32 | drive->open = open_fn; |
nkeynes@1097 | 33 | return drive; |
nkeynes@1097 | 34 | } |
nkeynes@1097 | 35 | |
nkeynes@1097 | 36 | static void cdrom_drive_destroy( cdrom_drive_t drive ) |
nkeynes@1097 | 37 | { |
nkeynes@1097 | 38 | g_free( (char *)drive->name ); |
nkeynes@1097 | 39 | drive->name = NULL; |
nkeynes@1097 | 40 | g_free( (char *)drive->display_name ); |
nkeynes@1097 | 41 | drive->display_name = NULL; |
nkeynes@1097 | 42 | g_free( drive ); |
nkeynes@1097 | 43 | } |
nkeynes@1097 | 44 | |
nkeynes@1097 | 45 | GList *cdrom_drive_get_list() |
nkeynes@1097 | 46 | { |
nkeynes@1097 | 47 | return cdrom_drive_list; |
nkeynes@1097 | 48 | } |
nkeynes@1097 | 49 | |
nkeynes@1097 | 50 | cdrom_drive_t cdrom_drive_add( const char *name, const char *display_name, cdrom_drive_open_fn_t open_fn ) |
nkeynes@1097 | 51 | { |
nkeynes@1097 | 52 | for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) { |
nkeynes@1097 | 53 | cdrom_drive_t it = (cdrom_drive_t)ptr->data; |
nkeynes@1097 | 54 | if( strcmp(it->name, name) == 0 ) { |
nkeynes@1097 | 55 | return it; |
nkeynes@1097 | 56 | } |
nkeynes@1097 | 57 | } |
nkeynes@1097 | 58 | |
nkeynes@1097 | 59 | cdrom_drive_t new_drive = cdrom_drive_new(name,display_name,open_fn); |
nkeynes@1097 | 60 | cdrom_drive_list = g_list_append( cdrom_drive_list, new_drive ); |
nkeynes@1097 | 61 | return new_drive; |
nkeynes@1097 | 62 | } |
nkeynes@1097 | 63 | |
nkeynes@1097 | 64 | gboolean cdrom_drive_remove( const char *name ) |
nkeynes@1097 | 65 | { |
nkeynes@1097 | 66 | for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) { |
nkeynes@1097 | 67 | cdrom_drive_t it = (cdrom_drive_t)ptr->data; |
nkeynes@1097 | 68 | if( strcmp(it->name, name) == 0 ) { |
nkeynes@1097 | 69 | cdrom_drive_list = g_list_delete_link( cdrom_drive_list, ptr ); |
nkeynes@1097 | 70 | cdrom_drive_destroy(it); |
nkeynes@1097 | 71 | return TRUE; |
nkeynes@1097 | 72 | } |
nkeynes@1097 | 73 | } |
nkeynes@1097 | 74 | return FALSE; |
nkeynes@1097 | 75 | } |
nkeynes@1097 | 76 | |
nkeynes@1097 | 77 | void cdrom_drive_remove_all() |
nkeynes@1097 | 78 | { |
nkeynes@1097 | 79 | for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) { |
nkeynes@1097 | 80 | cdrom_drive_destroy( (cdrom_drive_t)ptr->data ); |
nkeynes@1097 | 81 | } |
nkeynes@1097 | 82 | g_list_free(cdrom_drive_list); |
nkeynes@1097 | 83 | cdrom_drive_list = NULL; |
nkeynes@1097 | 84 | } |
nkeynes@1097 | 85 | |
nkeynes@1097 | 86 | cdrom_drive_t cdrom_drive_get_index( unsigned int index ) |
nkeynes@1097 | 87 | { |
nkeynes@1097 | 88 | return (cdrom_drive_t)g_list_nth_data(cdrom_drive_list, index); |
nkeynes@1097 | 89 | } |
nkeynes@1097 | 90 | |
nkeynes@1097 | 91 | cdrom_disc_t cdrom_drive_open( cdrom_drive_t drive, ERROR *err ) |
nkeynes@1097 | 92 | { |
nkeynes@1097 | 93 | return drive->open(drive, err); |
nkeynes@1097 | 94 | } |
nkeynes@1097 | 95 | |
nkeynes@1097 | 96 | cdrom_drive_t cdrom_drive_find( const char *name ) |
nkeynes@1097 | 97 | { |
nkeynes@1097 | 98 | const char *id = name; |
nkeynes@1097 | 99 | |
nkeynes@1097 | 100 | /* If we have no drives, just return NULL without looking, to save time */ |
nkeynes@1097 | 101 | if( cdrom_drive_list == NULL ) |
nkeynes@1097 | 102 | return NULL; |
nkeynes@1097 | 103 | |
nkeynes@1097 | 104 | /* Check for a url-style name */ |
nkeynes@1097 | 105 | const char *lizard_lips = strstr( name, "://" ); |
nkeynes@1097 | 106 | if( lizard_lips != NULL ) { |
nkeynes@1097 | 107 | id = lizard_lips + 3; |
nkeynes@1097 | 108 | int method_len = (lizard_lips-name); |
nkeynes@1097 | 109 | if( method_len > 8 ) |
nkeynes@1097 | 110 | return NULL; |
nkeynes@1097 | 111 | |
nkeynes@1097 | 112 | char method[method_len + 1]; |
nkeynes@1097 | 113 | memcpy( method, name, method_len ); |
nkeynes@1097 | 114 | method[method_len] = '\0'; |
nkeynes@1097 | 115 | |
nkeynes@1097 | 116 | if( strcasecmp( method, "file" ) != 0 && |
nkeynes@1097 | 117 | strcasecmp( method, "dvd" ) != 0 && |
nkeynes@1097 | 118 | strcasecmp( method, "cd" ) != 0 && |
nkeynes@1097 | 119 | strcasecmp( method, "cdrom" ) ) { |
nkeynes@1097 | 120 | /* Anything else we don't try to recognize */ |
nkeynes@1097 | 121 | return NULL; |
nkeynes@1097 | 122 | } |
nkeynes@1097 | 123 | |
nkeynes@1097 | 124 | if( *id == '\0' ) { |
nkeynes@1097 | 125 | /* Accept eg 'dvd://' as meaning 'the first cd/dvd device */ |
nkeynes@1097 | 126 | return cdrom_drive_list->data; |
nkeynes@1097 | 127 | } |
nkeynes@1097 | 128 | |
nkeynes@1097 | 129 | char *endp = NULL; |
nkeynes@1097 | 130 | unsigned long index = strtoul( id, &endp, 10 ); |
nkeynes@1097 | 131 | if( endp != NULL && *endp == '\0' ) { |
nkeynes@1097 | 132 | /* Accept eg 'dvd://2' as meaning 'the second cd/dvd device */ |
nkeynes@1097 | 133 | return cdrom_drive_get_index(index); |
nkeynes@1097 | 134 | } |
nkeynes@1097 | 135 | |
nkeynes@1097 | 136 | /* Otherwise it must be a drive identifier, so treat it as if it didn't |
nkeynes@1097 | 137 | * have the url prefix. (fallthrough) |
nkeynes@1097 | 138 | */ |
nkeynes@1097 | 139 | } |
nkeynes@1097 | 140 | |
nkeynes@1097 | 141 | for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) { |
nkeynes@1097 | 142 | cdrom_drive_t drive = (cdrom_drive_t)ptr->data; |
nkeynes@1097 | 143 | if( strcmp(drive->name, id) == 0 ) |
nkeynes@1097 | 144 | return drive; |
nkeynes@1097 | 145 | } |
nkeynes@1097 | 146 | |
nkeynes@1097 | 147 | return NULL; |
nkeynes@1097 | 148 | } |
.