nkeynes@342 | 1 |
|
nkeynes@138 | 2 | /**
|
nkeynes@561 | 3 | * $Id$
|
nkeynes@138 | 4 | *
|
nkeynes@138 | 5 | * GD-Rom access functions.
|
nkeynes@138 | 6 | *
|
nkeynes@138 | 7 | * Copyright (c) 2005 Nathan Keynes.
|
nkeynes@138 | 8 | *
|
nkeynes@138 | 9 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@138 | 10 | * it under the terms of the GNU General Public License as published by
|
nkeynes@138 | 11 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@138 | 12 | * (at your option) any later version.
|
nkeynes@138 | 13 | *
|
nkeynes@138 | 14 | * This program is distributed in the hope that it will be useful,
|
nkeynes@138 | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@138 | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@138 | 17 | * GNU General Public License for more details.
|
nkeynes@138 | 18 | */
|
nkeynes@138 | 19 |
|
nkeynes@138 | 20 | #include <stdio.h>
|
nkeynes@237 | 21 | #include <fcntl.h>
|
nkeynes@168 | 22 | #include <errno.h>
|
nkeynes@678 | 23 | #include <glib/gutils.h>
|
nkeynes@138 | 24 | #include "gdrom/ide.h"
|
nkeynes@138 | 25 | #include "gdrom/gdrom.h"
|
nkeynes@678 | 26 | #include "gdrom/gddriver.h"
|
nkeynes@143 | 27 | #include "gdrom/packet.h"
|
nkeynes@138 | 28 | #include "dream.h"
|
nkeynes@138 | 29 |
|
nkeynes@342 | 30 | extern gdrom_disc_t gdrom_disc;
|
nkeynes@138 | 31 |
|
nkeynes@678 | 32 | DEFINE_HOOK( gdrom_disc_change_hook, gdrom_disc_change_hook_t )
|
nkeynes@678 | 33 |
|
nkeynes@678 | 34 | gdrom_fire_disc_changed( gdrom_disc_t disc )
|
nkeynes@678 | 35 | {
|
nkeynes@678 | 36 | CALL_HOOKS( gdrom_disc_change_hook, disc, disc == NULL ? NULL : disc->name );
|
nkeynes@678 | 37 | }
|
nkeynes@678 | 38 |
|
nkeynes@492 | 39 | gdrom_image_class_t gdrom_image_classes[] = { &cdrom_device_class,
|
nkeynes@492 | 40 | &nrg_image_class,
|
nkeynes@492 | 41 | &cdi_image_class,
|
nkeynes@492 | 42 | &gdi_image_class,
|
nkeynes@492 | 43 | NULL };
|
nkeynes@138 | 44 |
|
nkeynes@644 | 45 | char *gdrom_mode_names[] = { "Mode 0", "Mode 1", "Mode 2", "Mode 2 Form 1", "Mode 2 Form 2", "Audio",
|
nkeynes@644 | 46 | "Mode 2 semiraw", "XA Raw", "Non-XA Raw" };
|
nkeynes@644 | 47 | uint32_t gdrom_sector_size[] = { 0, 2048, 2336, 2048, 2324, 2352, 2336, 2352, 2352 };
|
nkeynes@138 | 48 |
|
nkeynes@709 | 49 | gdrom_disc_t gdrom_image_open( const gchar *inFilename )
|
nkeynes@138 | 50 | {
|
nkeynes@709 | 51 | const gchar *filename = inFilename;
|
nkeynes@168 | 52 | const gchar *ext = strrchr(filename, '.');
|
nkeynes@168 | 53 | gdrom_disc_t disc = NULL;
|
nkeynes@709 | 54 | int fd;
|
nkeynes@237 | 55 | FILE *f;
|
nkeynes@422 | 56 | int i;
|
nkeynes@168 | 57 | gdrom_image_class_t extclz = NULL;
|
nkeynes@168 | 58 |
|
nkeynes@709 | 59 | // Check for a url-style filename.
|
nkeynes@709 | 60 | char *lizard_lips = strstr( filename, "://" );
|
nkeynes@709 | 61 | if( lizard_lips != NULL ) {
|
nkeynes@709 | 62 | gchar *path = lizard_lips + 3;
|
nkeynes@709 | 63 | int method_len = (lizard_lips-filename);
|
nkeynes@709 | 64 | gchar method[method_len + 1];
|
nkeynes@709 | 65 | memcpy( method, filename, method_len );
|
nkeynes@709 | 66 | method[method_len] = '\0';
|
nkeynes@709 | 67 |
|
nkeynes@709 | 68 | if( strcasecmp( method, "file" ) == 0 ) {
|
nkeynes@709 | 69 | filename = path;
|
nkeynes@709 | 70 | } else if( strcasecmp( method, "dvd" ) == 0 ||
|
nkeynes@709 | 71 | strcasecmp( method, "cd" ) == 0 ||
|
nkeynes@709 | 72 | strcasecmp( method, "cdrom" ) ) {
|
nkeynes@709 | 73 | return cdrom_open_device( method, path );
|
nkeynes@709 | 74 | } else {
|
nkeynes@709 | 75 | ERROR( "Unrecognized URL method '%s' in filename '%s'", method, filename );
|
nkeynes@709 | 76 | return NULL;
|
nkeynes@709 | 77 | }
|
nkeynes@709 | 78 | }
|
nkeynes@709 | 79 |
|
nkeynes@709 | 80 | fd = open( filename, O_RDONLY | O_NONBLOCK );
|
nkeynes@237 | 81 | if( fd == -1 ) {
|
nkeynes@709 | 82 | return NULL;
|
nkeynes@168 | 83 | }
|
nkeynes@168 | 84 |
|
nkeynes@237 | 85 | f = fdopen(fd, "ro");
|
nkeynes@237 | 86 |
|
nkeynes@237 | 87 |
|
nkeynes@168 | 88 | /* try extensions */
|
nkeynes@168 | 89 | if( ext != NULL ) {
|
nkeynes@168 | 90 | ext++; /* Skip the '.' */
|
nkeynes@168 | 91 | for( i=0; gdrom_image_classes[i] != NULL; i++ ) {
|
nkeynes@237 | 92 | if( gdrom_image_classes[i]->extension != NULL &&
|
nkeynes@237 | 93 | strcasecmp( gdrom_image_classes[i]->extension, ext ) == 0 ) {
|
nkeynes@168 | 94 | extclz = gdrom_image_classes[i];
|
nkeynes@168 | 95 | if( extclz->is_valid_file(f) ) {
|
nkeynes@168 | 96 | disc = extclz->open_image_file(filename, f);
|
nkeynes@168 | 97 | if( disc != NULL )
|
nkeynes@168 | 98 | return disc;
|
nkeynes@168 | 99 | }
|
nkeynes@168 | 100 | break;
|
nkeynes@168 | 101 | }
|
nkeynes@168 | 102 | }
|
nkeynes@168 | 103 | }
|
nkeynes@168 | 104 |
|
nkeynes@168 | 105 | /* Okay, fall back to magic */
|
nkeynes@237 | 106 | gboolean recognized = FALSE;
|
nkeynes@168 | 107 | for( i=0; gdrom_image_classes[i] != NULL; i++ ) {
|
nkeynes@168 | 108 | if( gdrom_image_classes[i] != extclz &&
|
nkeynes@168 | 109 | gdrom_image_classes[i]->is_valid_file(f) ) {
|
nkeynes@237 | 110 | recognized = TRUE;
|
nkeynes@168 | 111 | disc = gdrom_image_classes[i]->open_image_file(filename, f);
|
nkeynes@168 | 112 | if( disc != NULL )
|
nkeynes@168 | 113 | return disc;
|
nkeynes@168 | 114 | }
|
nkeynes@168 | 115 | }
|
nkeynes@168 | 116 |
|
nkeynes@168 | 117 | fclose(f);
|
nkeynes@168 | 118 | return NULL;
|
nkeynes@138 | 119 | }
|
nkeynes@138 | 120 |
|
nkeynes@138 | 121 | void gdrom_mount_disc( gdrom_disc_t disc )
|
nkeynes@138 | 122 | {
|
nkeynes@678 | 123 | if( disc != gdrom_disc ) {
|
nkeynes@695 | 124 | if( gdrom_disc != NULL ) {
|
nkeynes@695 | 125 | gdrom_disc->close(gdrom_disc);
|
nkeynes@695 | 126 | }
|
nkeynes@678 | 127 | gdrom_disc = disc;
|
nkeynes@678 | 128 | gdrom_image_dump_info( disc );
|
nkeynes@678 | 129 | gdrom_fire_disc_changed( disc );
|
nkeynes@678 | 130 | }
|
nkeynes@138 | 131 | }
|
nkeynes@138 | 132 |
|
nkeynes@433 | 133 | gboolean gdrom_mount_image( const gchar *filename )
|
nkeynes@138 | 134 | {
|
nkeynes@138 | 135 | gdrom_disc_t disc = gdrom_image_open(filename);
|
nkeynes@695 | 136 | if( disc != NULL ) {
|
nkeynes@678 | 137 | gdrom_mount_disc( disc );
|
nkeynes@678 | 138 | return TRUE;
|
nkeynes@433 | 139 | }
|
nkeynes@433 | 140 | return FALSE;
|
nkeynes@138 | 141 | }
|
nkeynes@138 | 142 |
|
nkeynes@138 | 143 | void gdrom_unmount_disc( )
|
nkeynes@138 | 144 | {
|
nkeynes@138 | 145 | if( gdrom_disc != NULL ) {
|
nkeynes@678 | 146 | gdrom_disc->close(gdrom_disc);
|
nkeynes@678 | 147 | gdrom_fire_disc_changed(NULL);
|
nkeynes@691 | 148 | gdrom_disc = NULL;
|
nkeynes@138 | 149 | }
|
nkeynes@138 | 150 | }
|
nkeynes@138 | 151 |
|
nkeynes@464 | 152 | gdrom_disc_t gdrom_get_current_disc()
|
nkeynes@464 | 153 | {
|
nkeynes@464 | 154 | return gdrom_disc;
|
nkeynes@464 | 155 | }
|
nkeynes@613 | 156 |
|
nkeynes@678 | 157 | const gchar *gdrom_get_current_disc_name()
|
nkeynes@678 | 158 | {
|
nkeynes@678 | 159 | if( gdrom_disc == NULL ) {
|
nkeynes@678 | 160 | return NULL;
|
nkeynes@678 | 161 | } else {
|
nkeynes@678 | 162 | return gdrom_disc->name;
|
nkeynes@678 | 163 | }
|
nkeynes@678 | 164 | }
|
nkeynes@678 | 165 |
|
nkeynes@613 | 166 | gchar *gdrom_get_relative_filename( const gchar *base_name, const gchar *rel_name )
|
nkeynes@613 | 167 | {
|
nkeynes@613 | 168 | gchar *dirname = g_path_get_dirname(base_name);
|
nkeynes@613 | 169 | gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, rel_name );
|
nkeynes@613 | 170 | g_free(dirname);
|
nkeynes@613 | 171 | return pathname;
|
nkeynes@613 | 172 | }
|