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)
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
}
.