Mercurial > sdl-ios-xcode
annotate src/cdrom/linux/SDL_syscdrom.c @ 753:b14fdadd8311
Date: Thu, 4 Dec 2003 07:48:40 +0200
From: "Mike Gorchak"
Subject: SDL/QNX6 new patch
Here in attachment my patch for the SDL/QNX6 again :) It contain non-crtitical/cosmetic fixes:
1. Fixed window centering at other than the first consoles.
2. Fixed window centering algorithm in case when window height or width are greater than the desktop resolution.
3. Fixed window positioning on other than the first consoles.
4. Fixed occasional input focus lost when switching to fullscreen.
5. Removed the Photon's default chroma color for the overlays, added RGB(12, 6, 12) color instead (very dark pink).
6. Added more checks to the YUV overlay code (fixed crashes during resolution mode switches).
7. Added support for Enter/Backspace keys in unicode mode (used by Maelstrom and by other games).
8. Fixed window restore/maximize function. It works, finally.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 10 Dec 2003 12:35:56 +0000 |
parents | 11d6eed68dba |
children | b8d311d90021 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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__ | |
40 #include <linux/cdrom.h> | |
41 #endif | |
42 #ifdef __SVR4 | |
43 #include <sys/cdio.h> | |
44 #endif | |
45 | |
46 /* Define this to use the alternative getmntent() code */ | |
47 #ifndef __SVR4 | |
48 #define USE_MNTENT | |
49 #endif | |
50 | |
51 #ifdef USE_MNTENT | |
52 #if defined(__USLC__) | |
53 #include <sys/mntent.h> | |
54 #else | |
55 #include <mntent.h> | |
56 #endif | |
57 | |
58 #ifndef _PATH_MNTTAB | |
59 #ifdef MNTTAB | |
60 #define _PATH_MNTTAB MNTTAB | |
61 #else | |
62 #define _PATH_MNTTAB "/etc/fstab" | |
63 #endif | |
64 #endif /* !_PATH_MNTTAB */ | |
65 | |
66 #ifndef _PATH_MOUNTED | |
67 #define _PATH_MOUNTED "/etc/mtab" | |
68 #endif /* !_PATH_MOUNTED */ | |
69 | |
70 #ifndef MNTTYPE_CDROM | |
71 #define MNTTYPE_CDROM "iso9660" | |
72 #endif | |
73 #ifndef MNTTYPE_SUPER | |
74 #define MNTTYPE_SUPER "supermount" | |
75 #endif | |
76 #endif /* USE_MNTENT */ | |
77 | |
78 #include "SDL_error.h" | |
79 #include "SDL_cdrom.h" | |
80 #include "SDL_syscdrom.h" | |
81 | |
82 | |
83 /* The maximum number of CD-ROM drives we'll detect */ | |
84 #define MAX_DRIVES 16 | |
85 | |
86 /* A list of available CD-ROM drives */ | |
87 static char *SDL_cdlist[MAX_DRIVES]; | |
88 static dev_t SDL_cdmode[MAX_DRIVES]; | |
89 | |
90 /* The system-dependent CD control functions */ | |
91 static const char *SDL_SYS_CDName(int drive); | |
92 static int SDL_SYS_CDOpen(int drive); | |
93 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
94 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
95 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
96 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
97 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
98 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
99 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
100 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
101 | |
102 /* 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
|
103 #ifndef ENOMEDIUM |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
104 #define ENOMEDIUM ENOENT |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
105 #endif |
0 | 106 #define ERRNO_TRAYEMPTY(errno) \ |
396
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
107 ((errno == EIO) || (errno == ENOENT) || \ |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
108 (errno == EINVAL) || (errno == ENOMEDIUM)) |
0 | 109 |
110 /* Check a drive to see if it is a CD-ROM */ | |
111 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) | |
112 { | |
113 int is_cd, cdfd; | |
114 struct cdrom_subchnl info; | |
115 | |
116 /* If it doesn't exist, return -1 */ | |
117 if ( stat(drive, stbuf) < 0 ) { | |
118 return(-1); | |
119 } | |
120 | |
121 /* If it does exist, verify that it's an available CD-ROM */ | |
122 is_cd = 0; | |
123 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { | |
124 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); | |
125 if ( cdfd >= 0 ) { | |
126 info.cdsc_format = CDROM_MSF; | |
127 /* Under Linux, EIO occurs when a disk is not present. | |
128 */ | |
129 if ( (ioctl(cdfd, CDROMSUBCHNL, &info) == 0) || | |
130 ERRNO_TRAYEMPTY(errno) ) { | |
131 is_cd = 1; | |
132 } | |
133 close(cdfd); | |
134 } | |
135 #ifdef USE_MNTENT | |
136 /* Even if we can't read it, it might be mounted */ | |
137 else if ( mnttype && (strcmp(mnttype, MNTTYPE_CDROM) == 0) ) { | |
138 is_cd = 1; | |
139 } | |
140 #endif | |
141 } | |
142 return(is_cd); | |
143 } | |
144 | |
145 /* Add a CD-ROM drive to our list of valid drives */ | |
146 static void AddDrive(char *drive, struct stat *stbuf) | |
147 { | |
148 int i; | |
149 | |
150 if ( SDL_numcds < MAX_DRIVES ) { | |
151 /* Check to make sure it's not already in our list. | |
152 This can happen when we see a drive via symbolic link. | |
153 */ | |
154 for ( i=0; i<SDL_numcds; ++i ) { | |
155 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | |
156 #ifdef DEBUG_CDROM | |
157 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | |
158 #endif | |
159 return; | |
160 } | |
161 } | |
162 | |
163 /* Add this drive to our list */ | |
164 i = SDL_numcds; | |
165 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | |
166 if ( SDL_cdlist[i] == NULL ) { | |
167 SDL_OutOfMemory(); | |
168 return; | |
169 } | |
170 strcpy(SDL_cdlist[i], drive); | |
171 SDL_cdmode[i] = stbuf->st_rdev; | |
172 ++SDL_numcds; | |
173 #ifdef DEBUG_CDROM | |
174 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
175 #endif | |
176 } | |
177 } | |
178 | |
179 #ifdef USE_MNTENT | |
180 static void CheckMounts(const char *mtab) | |
181 { | |
182 FILE *mntfp; | |
183 struct mntent *mntent; | |
184 struct stat stbuf; | |
185 | |
186 mntfp = setmntent(mtab, "r"); | |
187 if ( mntfp != NULL ) { | |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
188 char *tmp; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
189 char *mnt_type; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
190 char *mnt_dev; |
0 | 191 |
192 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
|
193 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
|
194 if (mnt_type == NULL) |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
195 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
|
196 |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
197 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
|
198 if (mnt_dev == NULL) { |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
199 free(mnt_type); |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
200 continue; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
201 } |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
202 |
0 | 203 strcpy(mnt_type, mntent->mnt_type); |
204 strcpy(mnt_dev, mntent->mnt_fsname); | |
205 | |
206 /* Handle "supermount" filesystem mounts */ | |
207 if ( strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) { | |
208 tmp = strstr(mntent->mnt_opts, "fs="); | |
209 if ( tmp ) { | |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
210 free(mnt_type); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
211 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
|
212 if ( mnt_type ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
213 tmp = strchr(mnt_type, ','); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
214 if ( tmp ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
215 *tmp = '\0'; |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
216 } |
0 | 217 } |
218 } | |
219 tmp = strstr(mntent->mnt_opts, "dev="); | |
220 if ( tmp ) { | |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
221 free(mnt_dev); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
222 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
|
223 if ( mnt_dev ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
224 tmp = strchr(mnt_dev, ','); |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
225 if ( tmp ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
226 *tmp = '\0'; |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
227 } |
0 | 228 } |
229 } | |
230 } | |
231 if ( strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) { | |
232 #ifdef DEBUG_CDROM | |
233 fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n", | |
234 mtab, mnt_dev, mntent->mnt_dir, mnt_type); | |
235 #endif | |
236 if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) { | |
237 AddDrive(mnt_dev, &stbuf); | |
238 } | |
239 } | |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
240 free(mnt_dev); |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
241 free(mnt_type); |
0 | 242 } |
243 endmntent(mntfp); | |
244 } | |
245 } | |
246 #endif /* USE_MNTENT */ | |
247 | |
248 int SDL_SYS_CDInit(void) | |
249 { | |
250 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ | |
251 static char *checklist[] = { | |
252 "cdrom", "?a hd?", "?0 scd?", "?0 sr?", NULL | |
253 }; | |
254 char *SDLcdrom; | |
255 int i, j, exists; | |
256 char drive[32]; | |
257 struct stat stbuf; | |
258 | |
259 /* Fill in our driver capabilities */ | |
260 SDL_CDcaps.Name = SDL_SYS_CDName; | |
261 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
262 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
263 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
264 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
265 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
266 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
267 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
268 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
269 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
270 | |
271 /* Look in the environment for our CD-ROM drive list */ | |
272 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ | |
273 if ( SDLcdrom != NULL ) { | |
274 char *cdpath, *delim; | |
275 cdpath = malloc(strlen(SDLcdrom)+1); | |
276 if ( cdpath != NULL ) { | |
277 strcpy(cdpath, SDLcdrom); | |
278 SDLcdrom = cdpath; | |
279 do { | |
280 delim = strchr(SDLcdrom, ':'); | |
281 if ( delim ) { | |
282 *delim++ = '\0'; | |
283 } | |
284 #ifdef DEBUG_CDROM | |
285 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); | |
286 #endif | |
287 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { | |
288 AddDrive(SDLcdrom, &stbuf); | |
289 } | |
290 if ( delim ) { | |
291 SDLcdrom = delim; | |
292 } else { | |
293 SDLcdrom = NULL; | |
294 } | |
295 } while ( SDLcdrom ); | |
296 free(cdpath); | |
297 } | |
298 | |
299 /* If we found our drives, there's nothing left to do */ | |
300 if ( SDL_numcds > 0 ) { | |
301 return(0); | |
302 } | |
303 } | |
304 | |
305 #ifdef USE_MNTENT | |
306 /* Check /dev/cdrom first :-) */ | |
307 if (CheckDrive("/dev/cdrom", NULL, &stbuf) > 0) { | |
308 AddDrive("/dev/cdrom", &stbuf); | |
309 } | |
310 | |
311 /* Now check the currently mounted CD drives */ | |
312 CheckMounts(_PATH_MOUNTED); | |
313 | |
314 /* Finally check possible mountable drives in /etc/fstab */ | |
315 CheckMounts(_PATH_MNTTAB); | |
316 | |
317 /* If we found our drives, there's nothing left to do */ | |
318 if ( SDL_numcds > 0 ) { | |
319 return(0); | |
320 } | |
321 #endif /* USE_MNTENT */ | |
322 | |
323 /* Scan the system for CD-ROM drives. | |
324 Not always 100% reliable, so use the USE_MNTENT code above first. | |
325 */ | |
326 for ( i=0; checklist[i]; ++i ) { | |
327 if ( checklist[i][0] == '?' ) { | |
328 char *insert; | |
329 exists = 1; | |
330 for ( j=checklist[i][1]; exists; ++j ) { | |
331 sprintf(drive, "/dev/%s", &checklist[i][3]); | |
332 insert = strchr(drive, '?'); | |
333 if ( insert != NULL ) { | |
334 *insert = j; | |
335 } | |
336 #ifdef DEBUG_CDROM | |
337 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
338 #endif | |
339 switch (CheckDrive(drive, NULL, &stbuf)) { | |
340 /* Drive exists and is a CD-ROM */ | |
341 case 1: | |
342 AddDrive(drive, &stbuf); | |
343 break; | |
344 /* Drive exists, but isn't a CD-ROM */ | |
345 case 0: | |
346 break; | |
347 /* Drive doesn't exist */ | |
348 case -1: | |
349 exists = 0; | |
350 break; | |
351 } | |
352 } | |
353 } else { | |
354 sprintf(drive, "/dev/%s", checklist[i]); | |
355 #ifdef DEBUG_CDROM | |
356 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
357 #endif | |
358 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { | |
359 AddDrive(drive, &stbuf); | |
360 } | |
361 } | |
362 } | |
363 return(0); | |
364 } | |
365 | |
366 /* General ioctl() CD-ROM command function */ | |
367 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
368 { | |
369 int retval; | |
370 | |
371 retval = ioctl(id, command, arg); | |
372 if ( retval < 0 ) { | |
373 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
374 } | |
375 return(retval); | |
376 } | |
377 | |
378 static const char *SDL_SYS_CDName(int drive) | |
379 { | |
380 return(SDL_cdlist[drive]); | |
381 } | |
382 | |
383 static int SDL_SYS_CDOpen(int drive) | |
384 { | |
385 return(open(SDL_cdlist[drive], (O_RDONLY|O_EXCL|O_NONBLOCK), 0)); | |
386 } | |
387 | |
388 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
389 { | |
390 struct cdrom_tochdr toc; | |
391 int i, okay; | |
392 struct cdrom_tocentry entry; | |
393 | |
394 okay = 0; | |
395 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0 ) { | |
396 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; | |
397 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
398 cdrom->numtracks = SDL_MAX_TRACKS; | |
399 } | |
400 /* Read all the track TOC entries */ | |
401 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
402 if ( i == cdrom->numtracks ) { | |
403 cdrom->track[i].id = CDROM_LEADOUT; | |
404 } else { | |
405 cdrom->track[i].id = toc.cdth_trk0+i; | |
406 } | |
407 entry.cdte_track = cdrom->track[i].id; | |
408 entry.cdte_format = CDROM_MSF; | |
409 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, | |
410 &entry) < 0 ) { | |
411 break; | |
412 } else { | |
413 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { | |
414 cdrom->track[i].type = SDL_DATA_TRACK; | |
415 } else { | |
416 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
417 } | |
418 cdrom->track[i].offset = MSF_TO_FRAMES( | |
419 entry.cdte_addr.msf.minute, | |
420 entry.cdte_addr.msf.second, | |
421 entry.cdte_addr.msf.frame); | |
422 cdrom->track[i].length = 0; | |
423 if ( i > 0 ) { | |
424 cdrom->track[i-1].length = | |
425 cdrom->track[i].offset- | |
426 cdrom->track[i-1].offset; | |
427 } | |
428 } | |
429 } | |
430 if ( i == (cdrom->numtracks+1) ) { | |
431 okay = 1; | |
432 } | |
433 } | |
434 return(okay ? 0 : -1); | |
435 } | |
436 | |
437 /* Get CD-ROM status */ | |
438 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
439 { | |
440 CDstatus status; | |
441 struct cdrom_tochdr toc; | |
442 struct cdrom_subchnl info; | |
443 | |
444 info.cdsc_format = CDROM_MSF; | |
445 if ( ioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { | |
446 if ( ERRNO_TRAYEMPTY(errno) ) { | |
447 status = CD_TRAYEMPTY; | |
448 } else { | |
449 status = CD_ERROR; | |
450 } | |
451 } else { | |
452 switch (info.cdsc_audiostatus) { | |
453 case CDROM_AUDIO_INVALID: | |
454 case CDROM_AUDIO_NO_STATUS: | |
455 /* Try to determine if there's a CD available */ | |
456 if (ioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) | |
457 status = CD_STOPPED; | |
458 else | |
459 status = CD_TRAYEMPTY; | |
460 break; | |
461 case CDROM_AUDIO_COMPLETED: | |
462 status = CD_STOPPED; | |
463 break; | |
464 case CDROM_AUDIO_PLAY: | |
465 status = CD_PLAYING; | |
466 break; | |
467 case CDROM_AUDIO_PAUSED: | |
468 /* Workaround buggy CD-ROM drive */ | |
469 if ( info.cdsc_trk == CDROM_LEADOUT ) { | |
470 status = CD_STOPPED; | |
471 } else { | |
472 status = CD_PAUSED; | |
473 } | |
474 break; | |
475 default: | |
476 status = CD_ERROR; | |
477 break; | |
478 } | |
479 } | |
480 if ( position ) { | |
481 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
482 *position = MSF_TO_FRAMES( | |
483 info.cdsc_absaddr.msf.minute, | |
484 info.cdsc_absaddr.msf.second, | |
485 info.cdsc_absaddr.msf.frame); | |
486 } else { | |
487 *position = 0; | |
488 } | |
489 } | |
490 return(status); | |
491 } | |
492 | |
493 /* Start play */ | |
494 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
495 { | |
496 struct cdrom_msf playtime; | |
497 | |
498 FRAMES_TO_MSF(start, | |
499 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
500 FRAMES_TO_MSF(start+length, | |
501 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
502 #ifdef DEBUG_CDROM | |
503 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
504 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
505 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
506 #endif | |
507 return(SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime)); | |
508 } | |
509 | |
510 /* Pause play */ | |
511 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
512 { | |
513 return(SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0)); | |
514 } | |
515 | |
516 /* Resume play */ | |
517 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
518 { | |
519 return(SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0)); | |
520 } | |
521 | |
522 /* Stop play */ | |
523 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
524 { | |
525 return(SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0)); | |
526 } | |
527 | |
528 /* Eject the CD-ROM */ | |
529 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
530 { | |
531 return(SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0)); | |
532 } | |
533 | |
534 /* Close the CD-ROM handle */ | |
535 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
536 { | |
537 close(cdrom->id); | |
538 } | |
539 | |
540 void SDL_SYS_CDQuit(void) | |
541 { | |
542 int i; | |
543 | |
544 if ( SDL_numcds > 0 ) { | |
545 for ( i=0; i<SDL_numcds; ++i ) { | |
546 free(SDL_cdlist[i]); | |
547 } | |
548 SDL_numcds = 0; | |
549 } | |
550 } | |
551 |