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