comparison src/cdrom/linux/SDL_syscdrom.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents 92947e3a18db
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
23 23
24 #ifdef SDL_CDROM_LINUX 24 #ifdef SDL_CDROM_LINUX
25 25
26 /* Functions for system-level CD-ROM audio control */ 26 /* Functions for system-level CD-ROM audio control */
27 27
28 #include <string.h> /* For strerror() */ 28 #include <string.h> /* For strerror() */
29 #include <sys/types.h> 29 #include <sys/types.h>
30 #include <sys/stat.h> 30 #include <sys/stat.h>
31 #include <sys/ioctl.h> 31 #include <sys/ioctl.h>
32 #include <fcntl.h> 32 #include <fcntl.h>
33 #include <errno.h> 33 #include <errno.h>
87 #include "SDL_cdrom.h" 87 #include "SDL_cdrom.h"
88 #include "../SDL_syscdrom.h" 88 #include "../SDL_syscdrom.h"
89 89
90 90
91 /* The maximum number of CD-ROM drives we'll detect */ 91 /* The maximum number of CD-ROM drives we'll detect */
92 #define MAX_DRIVES 16 92 #define MAX_DRIVES 16
93 93
94 /* A list of available CD-ROM drives */ 94 /* A list of available CD-ROM drives */
95 static char *SDL_cdlist[MAX_DRIVES]; 95 static char *SDL_cdlist[MAX_DRIVES];
96 static dev_t SDL_cdmode[MAX_DRIVES]; 96 static dev_t SDL_cdmode[MAX_DRIVES];
97 97
98 /* The system-dependent CD control functions */ 98 /* The system-dependent CD control functions */
99 static const char *SDL_SYS_CDName(int drive); 99 static const char *SDL_SYS_CDName (int drive);
100 static int SDL_SYS_CDOpen(int drive); 100 static int SDL_SYS_CDOpen (int drive);
101 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 101 static int SDL_SYS_CDGetTOC (SDL_CD * cdrom);
102 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); 102 static CDstatus SDL_SYS_CDStatus (SDL_CD * cdrom, int *position);
103 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); 103 static int SDL_SYS_CDPlay (SDL_CD * cdrom, int start, int length);
104 static int SDL_SYS_CDPause(SDL_CD *cdrom); 104 static int SDL_SYS_CDPause (SDL_CD * cdrom);
105 static int SDL_SYS_CDResume(SDL_CD *cdrom); 105 static int SDL_SYS_CDResume (SDL_CD * cdrom);
106 static int SDL_SYS_CDStop(SDL_CD *cdrom); 106 static int SDL_SYS_CDStop (SDL_CD * cdrom);
107 static int SDL_SYS_CDEject(SDL_CD *cdrom); 107 static int SDL_SYS_CDEject (SDL_CD * cdrom);
108 static void SDL_SYS_CDClose(SDL_CD *cdrom); 108 static void SDL_SYS_CDClose (SDL_CD * cdrom);
109 109
110 /* Some ioctl() errno values which occur when the tray is empty */ 110 /* Some ioctl() errno values which occur when the tray is empty */
111 #ifndef ENOMEDIUM 111 #ifndef ENOMEDIUM
112 #define ENOMEDIUM ENOENT 112 #define ENOMEDIUM ENOENT
113 #endif 113 #endif
114 #define ERRNO_TRAYEMPTY(errno) \ 114 #define ERRNO_TRAYEMPTY(errno) \
115 ((errno == EIO) || (errno == ENOENT) || \ 115 ((errno == EIO) || (errno == ENOENT) || \
116 (errno == EINVAL) || (errno == ENOMEDIUM)) 116 (errno == EINVAL) || (errno == ENOMEDIUM))
117 117
118 /* Check a drive to see if it is a CD-ROM */ 118 /* Check a drive to see if it is a CD-ROM */
119 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) 119 static int
120 { 120 CheckDrive (char *drive, char *mnttype, struct stat *stbuf)
121 int is_cd, cdfd; 121 {
122 struct cdrom_subchnl info; 122 int is_cd, cdfd;
123 123 struct cdrom_subchnl info;
124 /* If it doesn't exist, return -1 */ 124
125 if ( stat(drive, stbuf) < 0 ) { 125 /* If it doesn't exist, return -1 */
126 return(-1); 126 if (stat (drive, stbuf) < 0) {
127 } 127 return (-1);
128 128 }
129 /* If it does exist, verify that it's an available CD-ROM */ 129
130 is_cd = 0; 130 /* If it does exist, verify that it's an available CD-ROM */
131 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { 131 is_cd = 0;
132 cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0); 132 if (S_ISCHR (stbuf->st_mode) || S_ISBLK (stbuf->st_mode)) {
133 if ( cdfd >= 0 ) { 133 cdfd = open (drive, (O_RDONLY | O_NONBLOCK), 0);
134 info.cdsc_format = CDROM_MSF; 134 if (cdfd >= 0) {
135 /* Under Linux, EIO occurs when a disk is not present. 135 info.cdsc_format = CDROM_MSF;
136 */ 136 /* Under Linux, EIO occurs when a disk is not present.
137 if ( (ioctl(cdfd, CDROMSUBCHNL, &info) == 0) || 137 */
138 ERRNO_TRAYEMPTY(errno) ) { 138 if ((ioctl (cdfd, CDROMSUBCHNL, &info) == 0) ||
139 is_cd = 1; 139 ERRNO_TRAYEMPTY (errno)) {
140 } 140 is_cd = 1;
141 close(cdfd); 141 }
142 } 142 close (cdfd);
143 }
143 #ifdef USE_MNTENT 144 #ifdef USE_MNTENT
144 /* Even if we can't read it, it might be mounted */ 145 /* Even if we can't read it, it might be mounted */
145 else if ( mnttype && (SDL_strcmp(mnttype, MNTTYPE_CDROM) == 0) ) { 146 else if (mnttype && (SDL_strcmp (mnttype, MNTTYPE_CDROM) == 0)) {
146 is_cd = 1; 147 is_cd = 1;
147 } 148 }
148 #endif 149 #endif
149 } 150 }
150 return(is_cd); 151 return (is_cd);
151 } 152 }
152 153
153 /* Add a CD-ROM drive to our list of valid drives */ 154 /* Add a CD-ROM drive to our list of valid drives */
154 static void AddDrive(char *drive, struct stat *stbuf) 155 static void
155 { 156 AddDrive (char *drive, struct stat *stbuf)
156 int i; 157 {
157 158 int i;
158 if ( SDL_numcds < MAX_DRIVES ) { 159
159 /* Check to make sure it's not already in our list. 160 if (SDL_numcds < MAX_DRIVES) {
160 This can happen when we see a drive via symbolic link. 161 /* Check to make sure it's not already in our list.
161 */ 162 This can happen when we see a drive via symbolic link.
162 for ( i=0; i<SDL_numcds; ++i ) { 163 */
163 if ( stbuf->st_rdev == SDL_cdmode[i] ) { 164 for (i = 0; i < SDL_numcds; ++i) {
164 #ifdef DEBUG_CDROM 165 if (stbuf->st_rdev == SDL_cdmode[i]) {
165 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); 166 #ifdef DEBUG_CDROM
166 #endif 167 fprintf (stderr, "Duplicate drive detected: %s == %s\n",
167 return; 168 drive, SDL_cdlist[i]);
168 } 169 #endif
169 } 170 return;
170 171 }
171 /* Add this drive to our list */ 172 }
172 i = SDL_numcds; 173
173 SDL_cdlist[i] = SDL_strdup(drive); 174 /* Add this drive to our list */
174 if ( SDL_cdlist[i] == NULL ) { 175 i = SDL_numcds;
175 SDL_OutOfMemory(); 176 SDL_cdlist[i] = SDL_strdup (drive);
176 return; 177 if (SDL_cdlist[i] == NULL) {
177 } 178 SDL_OutOfMemory ();
178 SDL_cdmode[i] = stbuf->st_rdev; 179 return;
179 ++SDL_numcds; 180 }
180 #ifdef DEBUG_CDROM 181 SDL_cdmode[i] = stbuf->st_rdev;
181 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); 182 ++SDL_numcds;
182 #endif 183 #ifdef DEBUG_CDROM
183 } 184 fprintf (stderr, "Added CD-ROM drive: %s\n", drive);
185 #endif
186 }
184 } 187 }
185 188
186 #ifdef USE_MNTENT 189 #ifdef USE_MNTENT
187 static void CheckMounts(const char *mtab) 190 static void
188 { 191 CheckMounts (const char *mtab)
189 FILE *mntfp; 192 {
190 struct mntent *mntent; 193 FILE *mntfp;
191 struct stat stbuf; 194 struct mntent *mntent;
192 195 struct stat stbuf;
193 mntfp = setmntent(mtab, "r"); 196
194 if ( mntfp != NULL ) { 197 mntfp = setmntent (mtab, "r");
195 char *tmp; 198 if (mntfp != NULL) {
196 char *mnt_type; 199 char *tmp;
197 size_t mnt_type_len; 200 char *mnt_type;
198 char *mnt_dev; 201 size_t mnt_type_len;
199 size_t mnt_dev_len; 202 char *mnt_dev;
200 203 size_t mnt_dev_len;
201 while ( (mntent=getmntent(mntfp)) != NULL ) { 204
202 mnt_type_len = SDL_strlen(mntent->mnt_type) + 1; 205 while ((mntent = getmntent (mntfp)) != NULL) {
203 mnt_type = SDL_stack_alloc(char, mnt_type_len); 206 mnt_type_len = SDL_strlen (mntent->mnt_type) + 1;
204 if (mnt_type == NULL) 207 mnt_type = SDL_stack_alloc (char, mnt_type_len);
205 continue; /* maybe you'll get lucky next time. */ 208 if (mnt_type == NULL)
206 209 continue; /* maybe you'll get lucky next time. */
207 mnt_dev_len = SDL_strlen(mntent->mnt_fsname) + 1; 210
208 mnt_dev = SDL_stack_alloc(char, mnt_dev_len); 211 mnt_dev_len = SDL_strlen (mntent->mnt_fsname) + 1;
209 if (mnt_dev == NULL) { 212 mnt_dev = SDL_stack_alloc (char, mnt_dev_len);
210 SDL_stack_free(mnt_type); 213 if (mnt_dev == NULL) {
211 continue; 214 SDL_stack_free (mnt_type);
212 } 215 continue;
213 216 }
214 SDL_strlcpy(mnt_type, mntent->mnt_type, mnt_type_len); 217
215 SDL_strlcpy(mnt_dev, mntent->mnt_fsname, mnt_dev_len); 218 SDL_strlcpy (mnt_type, mntent->mnt_type, mnt_type_len);
216 219 SDL_strlcpy (mnt_dev, mntent->mnt_fsname, mnt_dev_len);
217 /* Handle "supermount" filesystem mounts */ 220
218 if ( SDL_strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) { 221 /* Handle "supermount" filesystem mounts */
219 tmp = SDL_strstr(mntent->mnt_opts, "fs="); 222 if (SDL_strcmp (mnt_type, MNTTYPE_SUPER) == 0) {
220 if ( tmp ) { 223 tmp = SDL_strstr (mntent->mnt_opts, "fs=");
221 SDL_free(mnt_type); 224 if (tmp) {
222 mnt_type = SDL_strdup(tmp + SDL_strlen("fs=")); 225 SDL_free (mnt_type);
223 if ( mnt_type ) { 226 mnt_type = SDL_strdup (tmp + SDL_strlen ("fs="));
224 tmp = SDL_strchr(mnt_type, ','); 227 if (mnt_type) {
225 if ( tmp ) { 228 tmp = SDL_strchr (mnt_type, ',');
226 *tmp = '\0'; 229 if (tmp) {
227 } 230 *tmp = '\0';
228 } 231 }
229 } 232 }
230 tmp = SDL_strstr(mntent->mnt_opts, "dev="); 233 }
231 if ( tmp ) { 234 tmp = SDL_strstr (mntent->mnt_opts, "dev=");
232 SDL_free(mnt_dev); 235 if (tmp) {
233 mnt_dev = SDL_strdup(tmp + SDL_strlen("dev=")); 236 SDL_free (mnt_dev);
234 if ( mnt_dev ) { 237 mnt_dev = SDL_strdup (tmp + SDL_strlen ("dev="));
235 tmp = SDL_strchr(mnt_dev, ','); 238 if (mnt_dev) {
236 if ( tmp ) { 239 tmp = SDL_strchr (mnt_dev, ',');
237 *tmp = '\0'; 240 if (tmp) {
238 } 241 *tmp = '\0';
239 } 242 }
240 } 243 }
241 } 244 }
242 if ( SDL_strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) { 245 }
243 #ifdef DEBUG_CDROM 246 if (SDL_strcmp (mnt_type, MNTTYPE_CDROM) == 0) {
244 fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n", 247 #ifdef DEBUG_CDROM
245 mtab, mnt_dev, mntent->mnt_dir, mnt_type); 248 fprintf (stderr,
246 #endif 249 "Checking mount path from %s: %s mounted on %s of %s\n",
247 if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) { 250 mtab, mnt_dev, mntent->mnt_dir, mnt_type);
248 AddDrive(mnt_dev, &stbuf); 251 #endif
249 } 252 if (CheckDrive (mnt_dev, mnt_type, &stbuf) > 0) {
250 } 253 AddDrive (mnt_dev, &stbuf);
251 SDL_stack_free(mnt_dev); 254 }
252 SDL_stack_free(mnt_type); 255 }
253 } 256 SDL_stack_free (mnt_dev);
254 endmntent(mntfp); 257 SDL_stack_free (mnt_type);
255 } 258 }
259 endmntent (mntfp);
260 }
256 } 261 }
257 #endif /* USE_MNTENT */ 262 #endif /* USE_MNTENT */
258 263
259 int SDL_SYS_CDInit(void) 264 int
260 { 265 SDL_SYS_CDInit (void)
261 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ 266 {
262 static char *checklist[] = { 267 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */
263 "cdrom", "?a hd?", "?0 scd?", "?0 sr?", NULL 268 static char *checklist[] = {
264 }; 269 "cdrom", "?a hd?", "?0 scd?", "?0 sr?", NULL
265 char *SDLcdrom; 270 };
266 int i, j, exists; 271 char *SDLcdrom;
267 char drive[32]; 272 int i, j, exists;
268 struct stat stbuf; 273 char drive[32];
269 274 struct stat stbuf;
270 /* Fill in our driver capabilities */ 275
271 SDL_CDcaps.Name = SDL_SYS_CDName; 276 /* Fill in our driver capabilities */
272 SDL_CDcaps.Open = SDL_SYS_CDOpen; 277 SDL_CDcaps.Name = SDL_SYS_CDName;
273 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 278 SDL_CDcaps.Open = SDL_SYS_CDOpen;
274 SDL_CDcaps.Status = SDL_SYS_CDStatus; 279 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
275 SDL_CDcaps.Play = SDL_SYS_CDPlay; 280 SDL_CDcaps.Status = SDL_SYS_CDStatus;
276 SDL_CDcaps.Pause = SDL_SYS_CDPause; 281 SDL_CDcaps.Play = SDL_SYS_CDPlay;
277 SDL_CDcaps.Resume = SDL_SYS_CDResume; 282 SDL_CDcaps.Pause = SDL_SYS_CDPause;
278 SDL_CDcaps.Stop = SDL_SYS_CDStop; 283 SDL_CDcaps.Resume = SDL_SYS_CDResume;
279 SDL_CDcaps.Eject = SDL_SYS_CDEject; 284 SDL_CDcaps.Stop = SDL_SYS_CDStop;
280 SDL_CDcaps.Close = SDL_SYS_CDClose; 285 SDL_CDcaps.Eject = SDL_SYS_CDEject;
281 286 SDL_CDcaps.Close = SDL_SYS_CDClose;
282 /* Look in the environment for our CD-ROM drive list */ 287
283 SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ 288 /* Look in the environment for our CD-ROM drive list */
284 if ( SDLcdrom != NULL ) { 289 SDLcdrom = SDL_getenv ("SDL_CDROM"); /* ':' separated list of devices */
285 char *cdpath, *delim; 290 if (SDLcdrom != NULL) {
286 size_t len = SDL_strlen(SDLcdrom)+1; 291 char *cdpath, *delim;
287 cdpath = SDL_stack_alloc(char, len); 292 size_t len = SDL_strlen (SDLcdrom) + 1;
288 if ( cdpath != NULL ) { 293 cdpath = SDL_stack_alloc (char, len);
289 SDL_strlcpy(cdpath, SDLcdrom, len); 294 if (cdpath != NULL) {
290 SDLcdrom = cdpath; 295 SDL_strlcpy (cdpath, SDLcdrom, len);
291 do { 296 SDLcdrom = cdpath;
292 delim = SDL_strchr(SDLcdrom, ':'); 297 do {
293 if ( delim ) { 298 delim = SDL_strchr (SDLcdrom, ':');
294 *delim++ = '\0'; 299 if (delim) {
295 } 300 *delim++ = '\0';
296 #ifdef DEBUG_CDROM 301 }
297 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); 302 #ifdef DEBUG_CDROM
298 #endif 303 fprintf (stderr,
299 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { 304 "Checking CD-ROM drive from SDL_CDROM: %s\n",
300 AddDrive(SDLcdrom, &stbuf); 305 SDLcdrom);
301 } 306 #endif
302 if ( delim ) { 307 if (CheckDrive (SDLcdrom, NULL, &stbuf) > 0) {
303 SDLcdrom = delim; 308 AddDrive (SDLcdrom, &stbuf);
304 } else { 309 }
305 SDLcdrom = NULL; 310 if (delim) {
306 } 311 SDLcdrom = delim;
307 } while ( SDLcdrom ); 312 } else {
308 SDL_stack_free(cdpath); 313 SDLcdrom = NULL;
309 } 314 }
310 315 }
311 /* If we found our drives, there's nothing left to do */ 316 while (SDLcdrom);
312 if ( SDL_numcds > 0 ) { 317 SDL_stack_free (cdpath);
313 return(0); 318 }
314 } 319
315 } 320 /* If we found our drives, there's nothing left to do */
316 321 if (SDL_numcds > 0) {
322 return (0);
323 }
324 }
317 #ifdef USE_MNTENT 325 #ifdef USE_MNTENT
318 /* Check /dev/cdrom first :-) */ 326 /* Check /dev/cdrom first :-) */
319 if (CheckDrive("/dev/cdrom", NULL, &stbuf) > 0) { 327 if (CheckDrive ("/dev/cdrom", NULL, &stbuf) > 0) {
320 AddDrive("/dev/cdrom", &stbuf); 328 AddDrive ("/dev/cdrom", &stbuf);
321 } 329 }
322 330
323 /* Now check the currently mounted CD drives */ 331 /* Now check the currently mounted CD drives */
324 CheckMounts(_PATH_MOUNTED); 332 CheckMounts (_PATH_MOUNTED);
325 333
326 /* Finally check possible mountable drives in /etc/fstab */ 334 /* Finally check possible mountable drives in /etc/fstab */
327 CheckMounts(_PATH_MNTTAB); 335 CheckMounts (_PATH_MNTTAB);
328 336
329 /* If we found our drives, there's nothing left to do */ 337 /* If we found our drives, there's nothing left to do */
330 if ( SDL_numcds > 0 ) { 338 if (SDL_numcds > 0) {
331 return(0); 339 return (0);
332 } 340 }
333 #endif /* USE_MNTENT */ 341 #endif /* USE_MNTENT */
334 342
335 /* Scan the system for CD-ROM drives. 343 /* Scan the system for CD-ROM drives.
336 Not always 100% reliable, so use the USE_MNTENT code above first. 344 Not always 100% reliable, so use the USE_MNTENT code above first.
337 */ 345 */
338 for ( i=0; checklist[i]; ++i ) { 346 for (i = 0; checklist[i]; ++i) {
339 if ( checklist[i][0] == '?' ) { 347 if (checklist[i][0] == '?') {
340 char *insert; 348 char *insert;
341 exists = 1; 349 exists = 1;
342 for ( j=checklist[i][1]; exists; ++j ) { 350 for (j = checklist[i][1]; exists; ++j) {
343 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", &checklist[i][3]); 351 SDL_snprintf (drive, SDL_arraysize (drive), "/dev/%s",
344 insert = SDL_strchr(drive, '?'); 352 &checklist[i][3]);
345 if ( insert != NULL ) { 353 insert = SDL_strchr (drive, '?');
346 *insert = j; 354 if (insert != NULL) {
347 } 355 *insert = j;
348 #ifdef DEBUG_CDROM 356 }
349 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); 357 #ifdef DEBUG_CDROM
350 #endif 358 fprintf (stderr, "Checking possible CD-ROM drive: %s\n",
351 switch (CheckDrive(drive, NULL, &stbuf)) { 359 drive);
352 /* Drive exists and is a CD-ROM */ 360 #endif
353 case 1: 361 switch (CheckDrive (drive, NULL, &stbuf)) {
354 AddDrive(drive, &stbuf); 362 /* Drive exists and is a CD-ROM */
355 break; 363 case 1:
356 /* Drive exists, but isn't a CD-ROM */ 364 AddDrive (drive, &stbuf);
357 case 0: 365 break;
358 break; 366 /* Drive exists, but isn't a CD-ROM */
359 /* Drive doesn't exist */ 367 case 0:
360 case -1: 368 break;
361 exists = 0; 369 /* Drive doesn't exist */
362 break; 370 case -1:
363 } 371 exists = 0;
364 } 372 break;
365 } else { 373 }
366 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", checklist[i]); 374 }
367 #ifdef DEBUG_CDROM 375 } else {
368 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); 376 SDL_snprintf (drive, SDL_arraysize (drive), "/dev/%s",
369 #endif 377 checklist[i]);
370 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { 378 #ifdef DEBUG_CDROM
371 AddDrive(drive, &stbuf); 379 fprintf (stderr, "Checking possible CD-ROM drive: %s\n", drive);
372 } 380 #endif
373 } 381 if (CheckDrive (drive, NULL, &stbuf) > 0) {
374 } 382 AddDrive (drive, &stbuf);
375 return(0); 383 }
384 }
385 }
386 return (0);
376 } 387 }
377 388
378 /* General ioctl() CD-ROM command function */ 389 /* General ioctl() CD-ROM command function */
379 static int SDL_SYS_CDioctl(int id, int command, void *arg) 390 static int
380 { 391 SDL_SYS_CDioctl (int id, int command, void *arg)
381 int retval; 392 {
382 393 int retval;
383 retval = ioctl(id, command, arg); 394
384 if ( retval < 0 ) { 395 retval = ioctl (id, command, arg);
385 SDL_SetError("ioctl() error: %s", strerror(errno)); 396 if (retval < 0) {
386 } 397 SDL_SetError ("ioctl() error: %s", strerror (errno));
387 return(retval); 398 }
388 } 399 return (retval);
389 400 }
390 static const char *SDL_SYS_CDName(int drive) 401
391 { 402 static const char *
392 return(SDL_cdlist[drive]); 403 SDL_SYS_CDName (int drive)
393 } 404 {
394 405 return (SDL_cdlist[drive]);
395 static int SDL_SYS_CDOpen(int drive) 406 }
396 { 407
397 return(open(SDL_cdlist[drive], (O_RDONLY|O_NONBLOCK), 0)); 408 static int
398 } 409 SDL_SYS_CDOpen (int drive)
399 410 {
400 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 411 return (open (SDL_cdlist[drive], (O_RDONLY | O_NONBLOCK), 0));
401 { 412 }
402 struct cdrom_tochdr toc; 413
403 int i, okay; 414 static int
404 struct cdrom_tocentry entry; 415 SDL_SYS_CDGetTOC (SDL_CD * cdrom)
405 416 {
406 okay = 0; 417 struct cdrom_tochdr toc;
407 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0 ) { 418 int i, okay;
408 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; 419 struct cdrom_tocentry entry;
409 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { 420
410 cdrom->numtracks = SDL_MAX_TRACKS; 421 okay = 0;
411 } 422 if (SDL_SYS_CDioctl (cdrom->id, CDROMREADTOCHDR, &toc) == 0) {
412 /* Read all the track TOC entries */ 423 cdrom->numtracks = toc.cdth_trk1 - toc.cdth_trk0 + 1;
413 for ( i=0; i<=cdrom->numtracks; ++i ) { 424 if (cdrom->numtracks > SDL_MAX_TRACKS) {
414 if ( i == cdrom->numtracks ) { 425 cdrom->numtracks = SDL_MAX_TRACKS;
415 cdrom->track[i].id = CDROM_LEADOUT; 426 }
416 } else { 427 /* Read all the track TOC entries */
417 cdrom->track[i].id = toc.cdth_trk0+i; 428 for (i = 0; i <= cdrom->numtracks; ++i) {
418 } 429 if (i == cdrom->numtracks) {
419 entry.cdte_track = cdrom->track[i].id; 430 cdrom->track[i].id = CDROM_LEADOUT;
420 entry.cdte_format = CDROM_MSF; 431 } else {
421 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, 432 cdrom->track[i].id = toc.cdth_trk0 + i;
422 &entry) < 0 ) { 433 }
423 break; 434 entry.cdte_track = cdrom->track[i].id;
424 } else { 435 entry.cdte_format = CDROM_MSF;
425 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { 436 if (SDL_SYS_CDioctl (cdrom->id, CDROMREADTOCENTRY, &entry) < 0) {
426 cdrom->track[i].type = SDL_DATA_TRACK; 437 break;
427 } else { 438 } else {
428 cdrom->track[i].type = SDL_AUDIO_TRACK; 439 if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
429 } 440 cdrom->track[i].type = SDL_DATA_TRACK;
430 cdrom->track[i].offset = MSF_TO_FRAMES( 441 } else {
431 entry.cdte_addr.msf.minute, 442 cdrom->track[i].type = SDL_AUDIO_TRACK;
432 entry.cdte_addr.msf.second, 443 }
433 entry.cdte_addr.msf.frame); 444 cdrom->track[i].offset =
434 cdrom->track[i].length = 0; 445 MSF_TO_FRAMES (entry.cdte_addr.msf.minute,
435 if ( i > 0 ) { 446 entry.cdte_addr.msf.second,
436 cdrom->track[i-1].length = 447 entry.cdte_addr.msf.frame);
437 cdrom->track[i].offset- 448 cdrom->track[i].length = 0;
438 cdrom->track[i-1].offset; 449 if (i > 0) {
439 } 450 cdrom->track[i - 1].length =
440 } 451 cdrom->track[i].offset - cdrom->track[i - 1].offset;
441 } 452 }
442 if ( i == (cdrom->numtracks+1) ) { 453 }
443 okay = 1; 454 }
444 } 455 if (i == (cdrom->numtracks + 1)) {
445 } 456 okay = 1;
446 return(okay ? 0 : -1); 457 }
458 }
459 return (okay ? 0 : -1);
447 } 460 }
448 461
449 /* Get CD-ROM status */ 462 /* Get CD-ROM status */
450 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 463 static CDstatus
451 { 464 SDL_SYS_CDStatus (SDL_CD * cdrom, int *position)
452 CDstatus status; 465 {
453 struct cdrom_tochdr toc; 466 CDstatus status;
454 struct cdrom_subchnl info; 467 struct cdrom_tochdr toc;
455 468 struct cdrom_subchnl info;
456 info.cdsc_format = CDROM_MSF; 469
457 if ( ioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { 470 info.cdsc_format = CDROM_MSF;
458 if ( ERRNO_TRAYEMPTY(errno) ) { 471 if (ioctl (cdrom->id, CDROMSUBCHNL, &info) < 0) {
459 status = CD_TRAYEMPTY; 472 if (ERRNO_TRAYEMPTY (errno)) {
460 } else { 473 status = CD_TRAYEMPTY;
461 status = CD_ERROR; 474 } else {
462 } 475 status = CD_ERROR;
463 } else { 476 }
464 switch (info.cdsc_audiostatus) { 477 } else {
465 case CDROM_AUDIO_INVALID: 478 switch (info.cdsc_audiostatus) {
466 case CDROM_AUDIO_NO_STATUS: 479 case CDROM_AUDIO_INVALID:
467 /* Try to determine if there's a CD available */ 480 case CDROM_AUDIO_NO_STATUS:
468 if (ioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) 481 /* Try to determine if there's a CD available */
469 status = CD_STOPPED; 482 if (ioctl (cdrom->id, CDROMREADTOCHDR, &toc) == 0)
470 else 483 status = CD_STOPPED;
471 status = CD_TRAYEMPTY; 484 else
472 break; 485 status = CD_TRAYEMPTY;
473 case CDROM_AUDIO_COMPLETED: 486 break;
474 status = CD_STOPPED; 487 case CDROM_AUDIO_COMPLETED:
475 break; 488 status = CD_STOPPED;
476 case CDROM_AUDIO_PLAY: 489 break;
477 status = CD_PLAYING; 490 case CDROM_AUDIO_PLAY:
478 break; 491 status = CD_PLAYING;
479 case CDROM_AUDIO_PAUSED: 492 break;
480 /* Workaround buggy CD-ROM drive */ 493 case CDROM_AUDIO_PAUSED:
481 if ( info.cdsc_trk == CDROM_LEADOUT ) { 494 /* Workaround buggy CD-ROM drive */
482 status = CD_STOPPED; 495 if (info.cdsc_trk == CDROM_LEADOUT) {
483 } else { 496 status = CD_STOPPED;
484 status = CD_PAUSED; 497 } else {
485 } 498 status = CD_PAUSED;
486 break; 499 }
487 default: 500 break;
488 status = CD_ERROR; 501 default:
489 break; 502 status = CD_ERROR;
490 } 503 break;
491 } 504 }
492 if ( position ) { 505 }
493 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { 506 if (position) {
494 *position = MSF_TO_FRAMES( 507 if (status == CD_PLAYING || (status == CD_PAUSED)) {
495 info.cdsc_absaddr.msf.minute, 508 *position = MSF_TO_FRAMES (info.cdsc_absaddr.msf.minute,
496 info.cdsc_absaddr.msf.second, 509 info.cdsc_absaddr.msf.second,
497 info.cdsc_absaddr.msf.frame); 510 info.cdsc_absaddr.msf.frame);
498 } else { 511 } else {
499 *position = 0; 512 *position = 0;
500 } 513 }
501 } 514 }
502 return(status); 515 return (status);
503 } 516 }
504 517
505 /* Start play */ 518 /* Start play */
506 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 519 static int
507 { 520 SDL_SYS_CDPlay (SDL_CD * cdrom, int start, int length)
508 struct cdrom_msf playtime; 521 {
509 522 struct cdrom_msf playtime;
510 FRAMES_TO_MSF(start, 523
511 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); 524 FRAMES_TO_MSF (start,
512 FRAMES_TO_MSF(start+length, 525 &playtime.cdmsf_min0, &playtime.cdmsf_sec0,
513 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); 526 &playtime.cdmsf_frame0);
514 #ifdef DEBUG_CDROM 527 FRAMES_TO_MSF (start + length, &playtime.cdmsf_min1, &playtime.cdmsf_sec1,
515 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", 528 &playtime.cdmsf_frame1);
516 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, 529 #ifdef DEBUG_CDROM
517 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); 530 fprintf (stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n",
518 #endif 531 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0,
519 return(SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime)); 532 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1);
533 #endif
534 return (SDL_SYS_CDioctl (cdrom->id, CDROMPLAYMSF, &playtime));
520 } 535 }
521 536
522 /* Pause play */ 537 /* Pause play */
523 static int SDL_SYS_CDPause(SDL_CD *cdrom) 538 static int
524 { 539 SDL_SYS_CDPause (SDL_CD * cdrom)
525 return(SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0)); 540 {
541 return (SDL_SYS_CDioctl (cdrom->id, CDROMPAUSE, 0));
526 } 542 }
527 543
528 /* Resume play */ 544 /* Resume play */
529 static int SDL_SYS_CDResume(SDL_CD *cdrom) 545 static int
530 { 546 SDL_SYS_CDResume (SDL_CD * cdrom)
531 return(SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0)); 547 {
548 return (SDL_SYS_CDioctl (cdrom->id, CDROMRESUME, 0));
532 } 549 }
533 550
534 /* Stop play */ 551 /* Stop play */
535 static int SDL_SYS_CDStop(SDL_CD *cdrom) 552 static int
536 { 553 SDL_SYS_CDStop (SDL_CD * cdrom)
537 return(SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0)); 554 {
555 return (SDL_SYS_CDioctl (cdrom->id, CDROMSTOP, 0));
538 } 556 }
539 557
540 /* Eject the CD-ROM */ 558 /* Eject the CD-ROM */
541 static int SDL_SYS_CDEject(SDL_CD *cdrom) 559 static int
542 { 560 SDL_SYS_CDEject (SDL_CD * cdrom)
543 return(SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0)); 561 {
562 return (SDL_SYS_CDioctl (cdrom->id, CDROMEJECT, 0));
544 } 563 }
545 564
546 /* Close the CD-ROM handle */ 565 /* Close the CD-ROM handle */
547 static void SDL_SYS_CDClose(SDL_CD *cdrom) 566 static void
548 { 567 SDL_SYS_CDClose (SDL_CD * cdrom)
549 close(cdrom->id); 568 {
550 } 569 close (cdrom->id);
551 570 }
552 void SDL_SYS_CDQuit(void) 571
553 { 572 void
554 int i; 573 SDL_SYS_CDQuit (void)
555 574 {
556 if ( SDL_numcds > 0 ) { 575 int i;
557 for ( i=0; i<SDL_numcds; ++i ) { 576
558 SDL_free(SDL_cdlist[i]); 577 if (SDL_numcds > 0) {
559 } 578 for (i = 0; i < SDL_numcds; ++i) {
560 SDL_numcds = 0; 579 SDL_free (SDL_cdlist[i]);
561 } 580 }
581 SDL_numcds = 0;
582 }
562 } 583 }
563 584
564 #endif /* SDL_CDROM_LINUX */ 585 #endif /* SDL_CDROM_LINUX */
586 /* vi: set ts=4 sw=4 expandtab: */