Mercurial > sdl-ios-xcode
annotate src/cdrom/linux/SDL_syscdrom.c @ 1135:cf6133247d34
Mac Classic and CodeWarrior patches.
--ryan.
From: =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb@algonet.se>
Subject: Re: [SDL] Updated Mac patch
Date: Tue, 6 Sep 2005 15:21:27 +0200
To: A list for developers using the SDL library <sdl@libsdl.org>
Earlier, I wrote:
> Updated the previous Mac patch to disable Carbon by default.
> Also "fixed" the SDL.spec again, so that it builds on Darwin.
>
> http://www.algonet.se/~afb/SDL-1.2.9-mac.patch
> Also applied fine to SDL12 CVS, when I tried it.
>
> Haven't completed any new packaging or projects for Xcode/PB,
> but it seems to build and install fine here (in development).
Tested the new patch to build with old CodeWarrior and MPW,
and it seems it needed some hacks with those old headers...
Just in case you want to support the archeological versions -
here is a small add-on to the above patch, to fix those...
http://www.algonet.se/~afb/SDL-1.2.9-classic.patch
I couldn't get the old CW5 projects to build without a few
modifications - such as deleting the stray old header in:
"CWprojects/Support/Carbon/Include/ConditionalMacros.h" ?
But I updated both projects to CW6 too and built for Carbon,
and it ran all of the Mac test projects without any problems.
The MPW file seems to have compiled, with a small order change.
As long as you're still shipping the CWProjects and MPWmake
with the download, they should probably be updated/fixed ?
(another "solution" would of course be to just delete them)
I'll post my new projects along with the new Xcode projects
later on, along with XML exports of the various .mcp files.
(CW5 builds for Classic / "PPC", and CW6 builds for Carbon)
It'll be packaged as a part of the next SpriteWorld X release...
http://spriteworldx.sourceforge.net/ [Classic/Carbon/Win/X11]
--anders
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 08 Sep 2005 06:34:28 +0000 |
parents | 3e637850c02b |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
396
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
247
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Functions for system-level CD-ROM audio control */ | |
29 | |
30 #include <sys/types.h> | |
31 #include <stdlib.h> | |
32 #include <sys/stat.h> | |
33 #include <sys/ioctl.h> | |
34 #include <fcntl.h> | |
35 #include <stdio.h> | |
36 #include <string.h> | |
37 #include <errno.h> | |
38 #include <unistd.h> | |
39 #ifdef __linux__ | |
1062
3e637850c02b
Date: Tue, 22 Mar 2005 23:50:20 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
1051
diff
changeset
|
40 #ifdef HAVE_LINUX_VERSION_H |
998
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
41 /* linux 2.6.9 workaround */ |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
42 #include <linux/version.h> |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
43 #if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9) |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
44 #include <asm/types.h> |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
45 #define __le64 __u64 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
46 #define __le32 __u32 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
47 #define __le16 __u16 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
48 #define __be64 __u64 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
49 #define __be32 __u32 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
50 #define __be16 __u16 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
51 #endif /* linux 2.6.9 workaround */ |
1062
3e637850c02b
Date: Tue, 22 Mar 2005 23:50:20 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
1051
diff
changeset
|
52 #endif /* HAVE_LINUX_VERSION_H */ |
0 | 53 #include <linux/cdrom.h> |
54 #endif | |
55 #ifdef __SVR4 | |
56 #include <sys/cdio.h> | |
57 #endif | |
58 | |
59 /* Define this to use the alternative getmntent() code */ | |
60 #ifndef __SVR4 | |
61 #define USE_MNTENT | |
62 #endif | |
63 | |
64 #ifdef USE_MNTENT | |
65 #if defined(__USLC__) | |
66 #include <sys/mntent.h> | |
67 #else | |
68 #include <mntent.h> | |
69 #endif | |
70 | |
71 #ifndef _PATH_MNTTAB | |
72 #ifdef MNTTAB | |
73 #define _PATH_MNTTAB MNTTAB | |
74 #else | |
75 #define _PATH_MNTTAB "/etc/fstab" | |
76 #endif | |
77 #endif /* !_PATH_MNTTAB */ | |
78 | |
79 #ifndef _PATH_MOUNTED | |
80 #define _PATH_MOUNTED "/etc/mtab" | |
81 #endif /* !_PATH_MOUNTED */ | |
82 | |
83 #ifndef MNTTYPE_CDROM | |
84 #define MNTTYPE_CDROM "iso9660" | |
85 #endif | |
86 #ifndef MNTTYPE_SUPER | |
87 #define MNTTYPE_SUPER "supermount" | |
88 #endif | |
89 #endif /* USE_MNTENT */ | |
90 | |
91 #include "SDL_error.h" | |
92 #include "SDL_cdrom.h" | |
93 #include "SDL_syscdrom.h" | |
94 | |
95 | |
96 /* The maximum number of CD-ROM drives we'll detect */ | |
97 #define MAX_DRIVES 16 | |
98 | |
99 /* A list of available CD-ROM drives */ | |
100 static char *SDL_cdlist[MAX_DRIVES]; | |
101 static dev_t SDL_cdmode[MAX_DRIVES]; | |
102 | |
103 /* The system-dependent CD control functions */ | |
104 static const char *SDL_SYS_CDName(int drive); | |
105 static int SDL_SYS_CDOpen(int drive); | |
106 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
107 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
108 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
109 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
110 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
111 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
112 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
113 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
114 | |
115 /* Some ioctl() errno values which occur when the tray is empty */ | |
396
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
116 #ifndef ENOMEDIUM |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
117 #define ENOMEDIUM ENOENT |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
118 #endif |
0 | 119 #define ERRNO_TRAYEMPTY(errno) \ |
396
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
120 ((errno == EIO) || (errno == ENOENT) || \ |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
121 (errno == EINVAL) || (errno == ENOMEDIUM)) |
0 | 122 |
123 /* Check a drive to see if it is a CD-ROM */ | |
124 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) | |
125 { | |
126 int is_cd, cdfd; | |
127 struct cdrom_subchnl info; | |
128 | |
129 /* If it doesn't exist, return -1 */ | |
130 if ( stat(drive, stbuf) < 0 ) { | |
131 return(-1); | |
132 } | |
133 | |
134 /* If it does exist, verify that it's an available CD-ROM */ | |
135 is_cd = 0; | |
136 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { | |
1051
091350827e08
SDL_CDOpen() fails on Linux if data track on disc is mounted in the
Ryan C. Gordon <icculus@icculus.org>
parents:
998
diff
changeset
|
137 cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0); |
0 | 138 if ( cdfd >= 0 ) { |
139 info.cdsc_format = CDROM_MSF; | |
140 /* Under Linux, EIO occurs when a disk is not present. | |
141 */ | |
142 if ( (ioctl(cdfd, CDROMSUBCHNL, &info) == 0) || | |
143 ERRNO_TRAYEMPTY(errno) ) { | |
144 is_cd = 1; | |
145 } | |
146 close(cdfd); | |
147 } | |
148 #ifdef USE_MNTENT | |
149 /* Even if we can't read it, it might be mounted */ | |
150 else if ( mnttype && (strcmp(mnttype, MNTTYPE_CDROM) == 0) ) { | |
151 is_cd = 1; | |
152 } | |
153 #endif | |
154 } | |
155 return(is_cd); | |
156 } | |
157 | |
158 /* Add a CD-ROM drive to our list of valid drives */ | |
159 static void AddDrive(char *drive, struct stat *stbuf) | |
160 { | |
161 int i; | |
162 | |
163 if ( SDL_numcds < MAX_DRIVES ) { | |
164 /* Check to make sure it's not already in our list. | |
165 This can happen when we see a drive via symbolic link. | |
166 */ | |
167 for ( i=0; i<SDL_numcds; ++i ) { | |
168 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | |
169 #ifdef DEBUG_CDROM | |
170 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | |
171 #endif | |
172 return; | |
173 } | |
174 } | |
175 | |
176 /* Add this drive to our list */ | |
177 i = SDL_numcds; | |
178 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | |
179 if ( SDL_cdlist[i] == NULL ) { | |
180 SDL_OutOfMemory(); | |
181 return; | |
182 } | |
183 strcpy(SDL_cdlist[i], drive); | |
184 SDL_cdmode[i] = stbuf->st_rdev; | |
185 ++SDL_numcds; | |
186 #ifdef DEBUG_CDROM | |
187 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
188 #endif | |
189 } | |
190 } | |
191 | |
192 #ifdef USE_MNTENT | |
193 static void CheckMounts(const char *mtab) | |
194 { | |
195 FILE *mntfp; | |
196 struct mntent *mntent; | |
197 struct stat stbuf; | |
198 | |
199 mntfp = setmntent(mtab, "r"); | |
200 if ( mntfp != NULL ) { | |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
201 char *tmp; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
202 char *mnt_type; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
203 char *mnt_dev; |
0 | 204 |
205 while ( (mntent=getmntent(mntfp)) != NULL ) { | |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
206 mnt_type = malloc(strlen(mntent->mnt_type) + 1); |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
207 if (mnt_type == NULL) |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
208 continue; /* maybe you'll get lucky next time. */ |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
209 |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
210 mnt_dev = malloc(strlen(mntent->mnt_fsname) + 1); |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
211 if (mnt_dev == NULL) { |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
212 free(mnt_type); |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
213 continue; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
214 } |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
215 |
0 | 216 strcpy(mnt_type, mntent->mnt_type); |
217 strcpy(mnt_dev, mntent->mnt_fsname); | |
218 | |
219 /* Handle "supermount" filesystem mounts */ | |
220 if ( strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) { | |
221 tmp = strstr(mntent->mnt_opts, "fs="); | |
222 if ( tmp ) { | |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
223 free(mnt_type); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
224 mnt_type = strdup(tmp + strlen("fs=")); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
225 if ( mnt_type ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
226 tmp = strchr(mnt_type, ','); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
227 if ( tmp ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
228 *tmp = '\0'; |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
229 } |
0 | 230 } |
231 } | |
232 tmp = strstr(mntent->mnt_opts, "dev="); | |
233 if ( tmp ) { | |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
234 free(mnt_dev); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
235 mnt_dev = strdup(tmp + strlen("dev=")); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
236 if ( mnt_dev ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
237 tmp = strchr(mnt_dev, ','); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
238 if ( tmp ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
239 *tmp = '\0'; |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
240 } |
0 | 241 } |
242 } | |
243 } | |
244 if ( strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) { | |
245 #ifdef DEBUG_CDROM | |
246 fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n", | |
247 mtab, mnt_dev, mntent->mnt_dir, mnt_type); | |
248 #endif | |
249 if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) { | |
250 AddDrive(mnt_dev, &stbuf); | |
251 } | |
252 } | |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
253 free(mnt_dev); |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
254 free(mnt_type); |
0 | 255 } |
256 endmntent(mntfp); | |
257 } | |
258 } | |
259 #endif /* USE_MNTENT */ | |
260 | |
261 int SDL_SYS_CDInit(void) | |
262 { | |
263 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ | |
264 static char *checklist[] = { | |
265 "cdrom", "?a hd?", "?0 scd?", "?0 sr?", NULL | |
266 }; | |
267 char *SDLcdrom; | |
268 int i, j, exists; | |
269 char drive[32]; | |
270 struct stat stbuf; | |
271 | |
272 /* Fill in our driver capabilities */ | |
273 SDL_CDcaps.Name = SDL_SYS_CDName; | |
274 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
275 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
276 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
277 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
278 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
279 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
280 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
281 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
282 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
283 | |
284 /* Look in the environment for our CD-ROM drive list */ | |
285 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ | |
286 if ( SDLcdrom != NULL ) { | |
287 char *cdpath, *delim; | |
288 cdpath = malloc(strlen(SDLcdrom)+1); | |
289 if ( cdpath != NULL ) { | |
290 strcpy(cdpath, SDLcdrom); | |
291 SDLcdrom = cdpath; | |
292 do { | |
293 delim = strchr(SDLcdrom, ':'); | |
294 if ( delim ) { | |
295 *delim++ = '\0'; | |
296 } | |
297 #ifdef DEBUG_CDROM | |
298 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); | |
299 #endif | |
300 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { | |
301 AddDrive(SDLcdrom, &stbuf); | |
302 } | |
303 if ( delim ) { | |
304 SDLcdrom = delim; | |
305 } else { | |
306 SDLcdrom = NULL; | |
307 } | |
308 } while ( SDLcdrom ); | |
309 free(cdpath); | |
310 } | |
311 | |
312 /* If we found our drives, there's nothing left to do */ | |
313 if ( SDL_numcds > 0 ) { | |
314 return(0); | |
315 } | |
316 } | |
317 | |
318 #ifdef USE_MNTENT | |
319 /* Check /dev/cdrom first :-) */ | |
320 if (CheckDrive("/dev/cdrom", NULL, &stbuf) > 0) { | |
321 AddDrive("/dev/cdrom", &stbuf); | |
322 } | |
323 | |
324 /* Now check the currently mounted CD drives */ | |
325 CheckMounts(_PATH_MOUNTED); | |
326 | |
327 /* Finally check possible mountable drives in /etc/fstab */ | |
328 CheckMounts(_PATH_MNTTAB); | |
329 | |
330 /* If we found our drives, there's nothing left to do */ | |
331 if ( SDL_numcds > 0 ) { | |
332 return(0); | |
333 } | |
334 #endif /* USE_MNTENT */ | |
335 | |
336 /* Scan the system for CD-ROM drives. | |
337 Not always 100% reliable, so use the USE_MNTENT code above first. | |
338 */ | |
339 for ( i=0; checklist[i]; ++i ) { | |
340 if ( checklist[i][0] == '?' ) { | |
341 char *insert; | |
342 exists = 1; | |
343 for ( j=checklist[i][1]; exists; ++j ) { | |
344 sprintf(drive, "/dev/%s", &checklist[i][3]); | |
345 insert = strchr(drive, '?'); | |
346 if ( insert != NULL ) { | |
347 *insert = j; | |
348 } | |
349 #ifdef DEBUG_CDROM | |
350 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
351 #endif | |
352 switch (CheckDrive(drive, NULL, &stbuf)) { | |
353 /* Drive exists and is a CD-ROM */ | |
354 case 1: | |
355 AddDrive(drive, &stbuf); | |
356 break; | |
357 /* Drive exists, but isn't a CD-ROM */ | |
358 case 0: | |
359 break; | |
360 /* Drive doesn't exist */ | |
361 case -1: | |
362 exists = 0; | |
363 break; | |
364 } | |
365 } | |
366 } else { | |
367 sprintf(drive, "/dev/%s", checklist[i]); | |
368 #ifdef DEBUG_CDROM | |
369 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
370 #endif | |
371 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { | |
372 AddDrive(drive, &stbuf); | |
373 } | |
374 } | |
375 } | |
376 return(0); | |
377 } | |
378 | |
379 /* General ioctl() CD-ROM command function */ | |
380 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
381 { | |
382 int retval; | |
383 | |
384 retval = ioctl(id, command, arg); | |
385 if ( retval < 0 ) { | |
386 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
387 } | |
388 return(retval); | |
389 } | |
390 | |
391 static const char *SDL_SYS_CDName(int drive) | |
392 { | |
393 return(SDL_cdlist[drive]); | |
394 } | |
395 | |
396 static int SDL_SYS_CDOpen(int drive) | |
397 { | |
1051
091350827e08
SDL_CDOpen() fails on Linux if data track on disc is mounted in the
Ryan C. Gordon <icculus@icculus.org>
parents:
998
diff
changeset
|
398 return(open(SDL_cdlist[drive], (O_RDONLY|O_NONBLOCK), 0)); |
0 | 399 } |
400 | |
401 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
402 { | |
403 struct cdrom_tochdr toc; | |
404 int i, okay; | |
405 struct cdrom_tocentry entry; | |
406 | |
407 okay = 0; | |
408 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0 ) { | |
409 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; | |
410 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
411 cdrom->numtracks = SDL_MAX_TRACKS; | |
412 } | |
413 /* Read all the track TOC entries */ | |
414 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
415 if ( i == cdrom->numtracks ) { | |
416 cdrom->track[i].id = CDROM_LEADOUT; | |
417 } else { | |
418 cdrom->track[i].id = toc.cdth_trk0+i; | |
419 } | |
420 entry.cdte_track = cdrom->track[i].id; | |
421 entry.cdte_format = CDROM_MSF; | |
422 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, | |
423 &entry) < 0 ) { | |
424 break; | |
425 } else { | |
426 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { | |
427 cdrom->track[i].type = SDL_DATA_TRACK; | |
428 } else { | |
429 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
430 } | |
431 cdrom->track[i].offset = MSF_TO_FRAMES( | |
432 entry.cdte_addr.msf.minute, | |
433 entry.cdte_addr.msf.second, | |
434 entry.cdte_addr.msf.frame); | |
435 cdrom->track[i].length = 0; | |
436 if ( i > 0 ) { | |
437 cdrom->track[i-1].length = | |
438 cdrom->track[i].offset- | |
439 cdrom->track[i-1].offset; | |
440 } | |
441 } | |
442 } | |
443 if ( i == (cdrom->numtracks+1) ) { | |
444 okay = 1; | |
445 } | |
446 } | |
447 return(okay ? 0 : -1); | |
448 } | |
449 | |
450 /* Get CD-ROM status */ | |
451 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
452 { | |
453 CDstatus status; | |
454 struct cdrom_tochdr toc; | |
455 struct cdrom_subchnl info; | |
456 | |
457 info.cdsc_format = CDROM_MSF; | |
458 if ( ioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { | |
459 if ( ERRNO_TRAYEMPTY(errno) ) { | |
460 status = CD_TRAYEMPTY; | |
461 } else { | |
462 status = CD_ERROR; | |
463 } | |
464 } else { | |
465 switch (info.cdsc_audiostatus) { | |
466 case CDROM_AUDIO_INVALID: | |
467 case CDROM_AUDIO_NO_STATUS: | |
468 /* Try to determine if there's a CD available */ | |
469 if (ioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) | |
470 status = CD_STOPPED; | |
471 else | |
472 status = CD_TRAYEMPTY; | |
473 break; | |
474 case CDROM_AUDIO_COMPLETED: | |
475 status = CD_STOPPED; | |
476 break; | |
477 case CDROM_AUDIO_PLAY: | |
478 status = CD_PLAYING; | |
479 break; | |
480 case CDROM_AUDIO_PAUSED: | |
481 /* Workaround buggy CD-ROM drive */ | |
482 if ( info.cdsc_trk == CDROM_LEADOUT ) { | |
483 status = CD_STOPPED; | |
484 } else { | |
485 status = CD_PAUSED; | |
486 } | |
487 break; | |
488 default: | |
489 status = CD_ERROR; | |
490 break; | |
491 } | |
492 } | |
493 if ( position ) { | |
494 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
495 *position = MSF_TO_FRAMES( | |
496 info.cdsc_absaddr.msf.minute, | |
497 info.cdsc_absaddr.msf.second, | |
498 info.cdsc_absaddr.msf.frame); | |
499 } else { | |
500 *position = 0; | |
501 } | |
502 } | |
503 return(status); | |
504 } | |
505 | |
506 /* Start play */ | |
507 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
508 { | |
509 struct cdrom_msf playtime; | |
510 | |
511 FRAMES_TO_MSF(start, | |
512 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
513 FRAMES_TO_MSF(start+length, | |
514 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
515 #ifdef DEBUG_CDROM | |
516 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
517 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
518 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
519 #endif | |
520 return(SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime)); | |
521 } | |
522 | |
523 /* Pause play */ | |
524 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
525 { | |
526 return(SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0)); | |
527 } | |
528 | |
529 /* Resume play */ | |
530 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
531 { | |
532 return(SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0)); | |
533 } | |
534 | |
535 /* Stop play */ | |
536 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
537 { | |
538 return(SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0)); | |
539 } | |
540 | |
541 /* Eject the CD-ROM */ | |
542 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
543 { | |
544 return(SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0)); | |
545 } | |
546 | |
547 /* Close the CD-ROM handle */ | |
548 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
549 { | |
550 close(cdrom->id); | |
551 } | |
552 | |
553 void SDL_SYS_CDQuit(void) | |
554 { | |
555 int i; | |
556 | |
557 if ( SDL_numcds > 0 ) { | |
558 for ( i=0; i<SDL_numcds; ++i ) { | |
559 free(SDL_cdlist[i]); | |
560 } | |
561 SDL_numcds = 0; | |
562 } | |
563 } | |
564 |