Mercurial > sdl-ios-xcode
comparison src/cdrom/qnx/SDL_syscdrom.c @ 571:8e3ce997621c
Date: Thu, 16 Jan 2003 13:48:31 +0200
From: "Mike Gorchak"
Subject: All QNX patches
whole patches concerning QNX. Almost all code has been rewritten by Julian
and me. Added initial support for hw overlays in QNX and many many others
fixes.
P.S. This patches has been reviewed by Dave Rempel from QSSL and included in
SDL 1.2.5 distribution, which coming on 3rd party CD for newest 6.2.1
version of QNX, which will be available soon.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 20 Jan 2003 01:38:37 +0000 |
parents | f6ffac90895c |
children | b8d311d90021 |
comparison
equal
deleted
inserted
replaced
570:04d6411da49d | 571:8e3ce997621c |
---|---|
31 #include <stdlib.h> | 31 #include <stdlib.h> |
32 #include <sys/stat.h> | 32 #include <sys/stat.h> |
33 #include <sys/ioctl.h> | 33 #include <sys/ioctl.h> |
34 #include <fcntl.h> | 34 #include <fcntl.h> |
35 #include <stdio.h> | 35 #include <stdio.h> |
36 #include <errno.h> | |
36 #include <string.h> | 37 #include <string.h> |
37 #include <errno.h> | |
38 #include <unistd.h> | 38 #include <unistd.h> |
39 #include <sys/cdrom.h> | 39 #include <sys/cdrom.h> |
40 #include <sys/dcmd_cam.h> | 40 #include <sys/dcmd_cam.h> |
41 | 41 |
42 | |
43 #include "SDL_error.h" | 42 #include "SDL_error.h" |
44 #include "SDL_cdrom.h" | 43 #include "SDL_cdrom.h" |
44 #include "SDL_timer.h" | |
45 #include "SDL_syscdrom.h" | 45 #include "SDL_syscdrom.h" |
46 | 46 |
47 | |
48 /* The maximum number of CD-ROM drives we'll detect */ | 47 /* The maximum number of CD-ROM drives we'll detect */ |
49 #define MAX_DRIVES 16 | 48 #define MAX_DRIVES 16 |
49 | |
50 #define QNX_CD_OPENMODE O_RDONLY | O_EXCL | |
50 | 51 |
51 /* A list of available CD-ROM drives */ | 52 /* A list of available CD-ROM drives */ |
52 static char *SDL_cdlist[MAX_DRIVES]; | 53 static char *SDL_cdlist[MAX_DRIVES]; |
53 static dev_t SDL_cdmode[MAX_DRIVES]; | 54 static dev_t SDL_cdmode[MAX_DRIVES]; |
55 static int SDL_cdopen[MAX_DRIVES]; | |
54 | 56 |
55 /* The system-dependent CD control functions */ | 57 /* The system-dependent CD control functions */ |
56 static const char *SDL_SYS_CDName(int drive); | 58 static const char *SDL_SYS_CDName(int drive); |
57 static int SDL_SYS_CDOpen(int drive); | 59 static int SDL_SYS_CDOpen(int drive); |
58 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | 60 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); |
62 static int SDL_SYS_CDResume(SDL_CD *cdrom); | 64 static int SDL_SYS_CDResume(SDL_CD *cdrom); |
63 static int SDL_SYS_CDStop(SDL_CD *cdrom); | 65 static int SDL_SYS_CDStop(SDL_CD *cdrom); |
64 static int SDL_SYS_CDEject(SDL_CD *cdrom); | 66 static int SDL_SYS_CDEject(SDL_CD *cdrom); |
65 static void SDL_SYS_CDClose(SDL_CD *cdrom); | 67 static void SDL_SYS_CDClose(SDL_CD *cdrom); |
66 | 68 |
67 /* Some ioctl() errno values which occur when the tray is empty */ | |
68 #define ERRNO_TRAYEMPTY(errno) \ | |
69 ((errno == EIO) || (errno == ENOENT) || (errno == EINVAL)) | |
70 | |
71 /* Check a drive to see if it is a CD-ROM */ | 69 /* Check a drive to see if it is a CD-ROM */ |
72 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) | 70 static int CheckDrive(char *drive, struct stat *stbuf) |
73 { | 71 { |
74 int is_cd, cdfd; | 72 int is_cd, cdfd; |
75 cdrom_subch_data_t info; | 73 cam_devinfo_t dinfo; |
76 | 74 int devctlret=0; |
77 /* If it doesn't exist, return -1 */ | 75 |
78 if ( stat(drive, stbuf) < 0 ) { | 76 int atapi; |
79 return(-1); | 77 int removable; |
80 } | 78 int cdb10; |
81 | 79 |
82 /* If it does exist, verify that it's an available CD-ROM */ | 80 /* If it doesn't exist, return -1 */ |
83 is_cd = 0; | 81 if (stat(drive, stbuf) < 0) |
84 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { | 82 { |
85 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); | 83 return(-1); |
86 if ( cdfd >= 0 ) { | 84 } |
87 info.subch_command.data_format = CDROM_MSF; | 85 |
88 /* Under Linux, EIO occurs when a disk is not present. | 86 /* If it does exist, verify that it's an available CD-ROM */ |
89 */ | 87 is_cd = 0; |
90 if ((devctl(cdfd,DCMD_CAM_CDROMSUBCHNL,&info,sizeof(info),0) == 0) || | 88 |
91 ERRNO_TRAYEMPTY(errno) ) | 89 if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) |
92 { | 90 { |
93 is_cd = 1; | 91 cdfd = open(drive, QNX_CD_OPENMODE); |
94 } | 92 if ( cdfd >= 0 ) |
95 close(cdfd); | 93 { |
96 } | 94 devctlret=devctl(cdfd, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL); |
97 } | 95 |
98 return(is_cd); | 96 if (devctlret==EOK) |
97 { | |
98 atapi=dinfo.flags & DEV_ATAPI; | |
99 removable=dinfo.flags & DEV_REMOVABLE; | |
100 cdb10=dinfo.flags & DEV_CDB_10; /* I'm not sure about that flag */ | |
101 | |
102 /* in the near future need to add more checks for splitting cdroms from other devices */ | |
103 if ((atapi)&&(removable)) | |
104 { | |
105 is_cd = 1; | |
106 } | |
107 } | |
108 | |
109 close(cdfd); | |
110 } | |
111 } | |
112 return(is_cd); | |
99 } | 113 } |
100 | 114 |
101 /* Add a CD-ROM drive to our list of valid drives */ | 115 /* Add a CD-ROM drive to our list of valid drives */ |
102 static void AddDrive(char *drive, struct stat *stbuf) | 116 static void AddDrive(char *drive, struct stat *stbuf) |
103 { | 117 { |
104 int i; | 118 int i; |
105 | 119 |
106 if ( SDL_numcds < MAX_DRIVES ) { | 120 if (SDL_numcds < MAX_DRIVES) |
107 /* Check to make sure it's not already in our list. | 121 { |
108 This can happen when we see a drive via symbolic link. | 122 /* Check to make sure it's not already in our list. |
109 */ | 123 This can happen when we see a drive via symbolic link. */ |
110 for ( i=0; i<SDL_numcds; ++i ) { | 124 |
111 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | 125 for (i=0; i<SDL_numcds; ++i) |
112 #ifdef DEBUG_CDROM | 126 { |
113 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | 127 if (stbuf->st_rdev == SDL_cdmode[i]) |
114 #endif | 128 { |
115 return; | 129 return; |
116 } | 130 } |
117 } | 131 } |
118 | 132 |
119 /* Add this drive to our list */ | 133 /* Add this drive to our list */ |
120 i = SDL_numcds; | 134 |
121 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | 135 i = SDL_numcds; |
122 if ( SDL_cdlist[i] == NULL ) { | 136 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); |
123 SDL_OutOfMemory(); | 137 if (SDL_cdlist[i] == NULL) |
124 return; | 138 { |
125 } | 139 SDL_OutOfMemory(); |
126 strcpy(SDL_cdlist[i], drive); | 140 return; |
127 SDL_cdmode[i] = stbuf->st_rdev; | 141 } |
128 ++SDL_numcds; | 142 strcpy(SDL_cdlist[i], drive); |
129 #ifdef DEBUG_CDROM | 143 SDL_cdmode[i] = stbuf->st_rdev; |
130 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | 144 ++SDL_numcds; |
131 #endif | 145 } |
132 } | 146 } |
133 } | 147 |
134 | 148 int SDL_SYS_CDInit(void) |
135 int SDL_SYS_CDInit(void) | 149 { |
136 { | 150 /* checklist: /dev/cdrom, /dev/cd?, /dev/scd? */ |
137 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ | 151 static char *checklist[]={"cdrom", "?0 cd?", "?1 cd?", "?0 scd?", NULL}; |
138 static char *checklist[] = { | 152 |
139 "cdrom", "?0 cd?", "?1 cd?", "?a hd?", "?0 scd?", "?0 sr?", NULL | 153 char *SDLcdrom; |
140 }; | 154 int i, j, exists; |
141 char *SDLcdrom; | 155 char drive[32]; |
142 int i, j, exists; | 156 struct stat stbuf; |
143 char drive[32]; | 157 |
144 struct stat stbuf; | 158 /* Fill in our driver capabilities */ |
145 | 159 SDL_CDcaps.Name = SDL_SYS_CDName; |
146 /* Fill in our driver capabilities */ | 160 SDL_CDcaps.Open = SDL_SYS_CDOpen; |
147 SDL_CDcaps.Name = SDL_SYS_CDName; | 161 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; |
148 SDL_CDcaps.Open = SDL_SYS_CDOpen; | 162 SDL_CDcaps.Status = SDL_SYS_CDStatus; |
149 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | 163 SDL_CDcaps.Play = SDL_SYS_CDPlay; |
150 SDL_CDcaps.Status = SDL_SYS_CDStatus; | 164 SDL_CDcaps.Pause = SDL_SYS_CDPause; |
151 SDL_CDcaps.Play = SDL_SYS_CDPlay; | 165 SDL_CDcaps.Resume = SDL_SYS_CDResume; |
152 SDL_CDcaps.Pause = SDL_SYS_CDPause; | 166 SDL_CDcaps.Stop = SDL_SYS_CDStop; |
153 SDL_CDcaps.Resume = SDL_SYS_CDResume; | 167 SDL_CDcaps.Eject = SDL_SYS_CDEject; |
154 SDL_CDcaps.Stop = SDL_SYS_CDStop; | 168 SDL_CDcaps.Close = SDL_SYS_CDClose; |
155 SDL_CDcaps.Eject = SDL_SYS_CDEject; | 169 |
156 SDL_CDcaps.Close = SDL_SYS_CDClose; | 170 /* clearing device open status */ |
157 | 171 for (i=0; i<MAX_DRIVES; i++) |
158 /* Look in the environment for our CD-ROM drive list */ | 172 { |
159 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ | 173 SDL_cdopen[i]=0; |
160 if ( SDLcdrom != NULL ) { | 174 } |
161 char *cdpath, *delim; | 175 |
162 cdpath = malloc(strlen(SDLcdrom)+1); | 176 /* Look in the environment for our CD-ROM drive list */ |
163 if ( cdpath != NULL ) { | 177 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ |
164 strcpy(cdpath, SDLcdrom); | 178 if ( SDLcdrom != NULL ) |
165 SDLcdrom = cdpath; | 179 { |
166 do { | 180 char *cdpath, *delim; |
167 delim = strchr(SDLcdrom, ':'); | 181 |
168 if ( delim ) { | 182 cdpath = malloc(strlen(SDLcdrom)+1); |
169 *delim++ = '\0'; | 183 if (cdpath != NULL) |
170 } | 184 { |
171 #ifdef DEBUG_CDROM | 185 strcpy(cdpath, SDLcdrom); |
172 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); | 186 SDLcdrom = cdpath; |
173 #endif | 187 do { |
174 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { | 188 delim = strchr(SDLcdrom, ':'); |
175 AddDrive(SDLcdrom, &stbuf); | 189 if (delim) |
176 } | 190 { |
177 if ( delim ) { | 191 *delim++ = '\0'; |
178 SDLcdrom = delim; | 192 } |
179 } else { | 193 if (CheckDrive(SDLcdrom, &stbuf) > 0) |
180 SDLcdrom = NULL; | 194 { |
181 } | 195 AddDrive(SDLcdrom, &stbuf); |
182 } while ( SDLcdrom ); | 196 } |
183 free(cdpath); | 197 if (delim) |
184 } | 198 { |
185 | 199 SDLcdrom = delim; |
186 /* If we found our drives, there's nothing left to do */ | 200 } |
187 if ( SDL_numcds > 0 ) { | 201 else |
188 return(0); | 202 { |
189 } | 203 SDLcdrom = NULL; |
190 } | 204 } |
191 | 205 } while (SDLcdrom); |
192 /* Scan the system for CD-ROM drives */ | 206 free(cdpath); |
193 for ( i=0; checklist[i]; ++i ) { | 207 } |
194 if ( checklist[i][0] == '?' ) { | 208 |
195 char *insert; | 209 /* If we found our drives, there's nothing left to do */ |
196 exists = 1; | 210 if (SDL_numcds > 0) |
197 for ( j=checklist[i][1]; exists; ++j ) { | 211 { |
198 sprintf(drive, "/dev/%s", &checklist[i][3]); | 212 return(0); |
199 insert = strchr(drive, '?'); | 213 } |
200 if ( insert != NULL ) { | 214 } |
201 *insert = j; | 215 |
202 } | 216 /* Scan the system for CD-ROM drives */ |
203 #ifdef DEBUG_CDROM | 217 for ( i=0; checklist[i]; ++i ) |
204 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | 218 { |
205 #endif | 219 if (checklist[i][0] == '?') |
206 switch (CheckDrive(drive, NULL, &stbuf)) { | 220 { |
207 /* Drive exists and is a CD-ROM */ | 221 char* insert; |
208 case 1: | 222 exists = 1; |
209 AddDrive(drive, &stbuf); | 223 |
210 break; | 224 for ( j=checklist[i][1]; exists; ++j ) |
211 /* Drive exists, but isn't a CD-ROM */ | 225 { |
212 case 0: | 226 sprintf(drive, "/dev/%s", &checklist[i][3]); |
213 break; | 227 insert = strchr(drive, '?'); |
214 /* Drive doesn't exist */ | 228 if (insert != NULL) |
215 case -1: | 229 { |
216 exists = 0; | 230 *insert = j; |
217 break; | 231 } |
218 } | 232 switch (CheckDrive(drive, &stbuf)) |
219 } | 233 { |
220 } else { | 234 /* Drive exists and is a CD-ROM */ |
221 sprintf(drive, "/dev/%s", checklist[i]); | 235 case 1: |
222 #ifdef DEBUG_CDROM | 236 AddDrive(drive, &stbuf); |
223 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | 237 break; |
224 #endif | 238 /* Drive exists, but isn't a CD-ROM */ |
225 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { | 239 case 0: |
226 AddDrive(drive, &stbuf); | 240 break; |
227 } | 241 /* Drive doesn't exist */ |
228 } | 242 case -1: |
229 } | 243 exists = 0; |
230 return(0); | 244 break; |
245 } | |
246 } | |
247 } | |
248 else | |
249 { | |
250 sprintf(drive, "/dev/%s", checklist[i]); | |
251 if (CheckDrive(drive, &stbuf) > 0) | |
252 { | |
253 AddDrive(drive, &stbuf); | |
254 } | |
255 } | |
256 } | |
257 return(0); | |
231 } | 258 } |
232 | 259 |
233 static const char *SDL_SYS_CDName(int drive) | 260 static const char *SDL_SYS_CDName(int drive) |
234 { | 261 { |
235 return(SDL_cdlist[drive]); | 262 return(SDL_cdlist[drive]); |
236 } | 263 } |
237 | 264 |
238 static int SDL_SYS_CDOpen(int drive) | 265 static int SDL_SYS_CDOpen(int drive) |
239 { | 266 { |
240 return(open(SDL_cdlist[drive], (O_RDONLY|O_EXCL|O_NONBLOCK), 0)); | 267 int handle; |
268 | |
269 handle=open(SDL_cdlist[drive], QNX_CD_OPENMODE); | |
270 | |
271 if (handle>0) | |
272 { | |
273 SDL_cdopen[drive]=handle; | |
274 } | |
275 | |
276 return (handle); | |
241 } | 277 } |
242 | 278 |
243 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | 279 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) |
244 { | 280 { |
245 cdrom_read_toc_t toc; | 281 cdrom_read_toc_t toc; |
246 int i, okay; | 282 int i, okay; |
247 | 283 |
248 okay = 0; | 284 okay = 0; |
249 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0) == 0) { | 285 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL) == 0) |
250 cdrom->numtracks = toc.last_track - toc.first_track + 1; | 286 { |
251 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | 287 cdrom->numtracks = toc.last_track - toc.first_track + 1; |
252 cdrom->numtracks = SDL_MAX_TRACKS; | 288 if (cdrom->numtracks > SDL_MAX_TRACKS) |
253 } | 289 { |
254 /* Read all the track TOC entries */ | 290 cdrom->numtracks = SDL_MAX_TRACKS; |
255 for ( i=0; i<=cdrom->numtracks; ++i ) { | 291 } |
256 if ( i == cdrom->numtracks ) { | 292 /* Read all the track TOC entries */ |
257 cdrom->track[i].id = CDROM_LEADOUT; | 293 for (i=0; i<=cdrom->numtracks; ++i) |
258 } else { | 294 { |
259 #if 0 /* Sam 11/6/00 - an obsolete field? */ | 295 if (i == cdrom->numtracks) |
260 cdrom->track[i].id = toc.cdth_trk0+i; | 296 { |
261 #else | 297 cdrom->track[i].id = CDROM_LEADOUT; |
262 cdrom->track[i].id = toc.first_track+i; | 298 } |
263 #endif | 299 else |
264 } | 300 { |
265 cdrom->track[i].type = toc.toc_entry[i].control_adr; | 301 cdrom->track[i].id = toc.first_track+i; |
266 cdrom->track[i].offset = MSF_TO_FRAMES( | 302 } |
267 toc.toc_entry[i].addr.msf.minute, | 303 |
268 toc.toc_entry[i].addr.msf.second, | 304 cdrom->track[i].type = toc.toc_entry[i].control_adr & 0x0F; |
269 toc.toc_entry[i].addr.msf.frame); | 305 cdrom->track[i].offset = toc.toc_entry[i].addr.lba; |
270 cdrom->track[i].length = 0; | 306 cdrom->track[i].length = 0; |
271 if ( i > 0 ) { | 307 |
272 cdrom->track[i-1].length = | 308 if (i > 0) |
273 cdrom->track[i].offset- | 309 { |
274 cdrom->track[i-1].offset; | 310 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset; |
275 } | 311 } |
276 } | 312 } |
277 if ( i == (cdrom->numtracks+1) ) { | 313 if (i == (cdrom->numtracks+1)) |
278 okay = 1; | 314 { |
279 } | 315 okay = 1; |
280 } | 316 } |
281 return(okay ? 0 : -1); | 317 } |
318 return (okay ? 0 : -1); | |
282 } | 319 } |
283 | 320 |
284 /* Get CD-ROM status */ | 321 /* Get CD-ROM status */ |
285 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | 322 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) |
286 { | 323 { |
287 CDstatus status; | 324 CDstatus status; |
288 cdrom_read_toc_t toc; | 325 |
289 subch_current_position_t info; | 326 cdrom_read_toc_t toc; |
290 | 327 cdrom_subch_data_t info; |
291 #if 0 /* Sam 11/6/00 - an obsolete field? */ | 328 cam_devinfo_t dinfo; |
292 info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; | 329 |
293 info.subch_command.track_number = 0; | 330 int devctlret=0; |
294 #else | 331 int drive=-1; |
295 info.data_format = CDROM_SUBCH_CURRENT_POSITION; | 332 int i; |
296 info.track_number = 0; | 333 int eagaincnt=0; |
297 #endif | 334 |
298 if (devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), 0) != 0) { | 335 /* check media presence before read subchannel call, some cdroms can lockups */ |
299 if ( ERRNO_TRAYEMPTY(errno) ) { | 336 /* if no media, while calling read subchannel functions. */ |
300 status = CD_TRAYEMPTY; | 337 devctlret=devctl(cdrom->id, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL); |
301 } else { | 338 |
302 status = CD_ERROR; | 339 if (devctlret==EOK) |
303 } | 340 { |
304 } else { | 341 if ((dinfo.flags & DEV_NO_MEDIA)!=0) |
305 switch (info.header.audio_status) { | 342 { |
306 case CDROM_AUDIO_INVALID: | 343 status = CD_TRAYEMPTY; |
307 case CDROM_AUDIO_NO_STATUS: | 344 if (position) |
308 /* Try to determine if there's a CD available */ | 345 { |
309 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0)==0) | 346 *position = 0; |
310 status = CD_STOPPED; | 347 } |
311 else | 348 return (status); |
312 status = CD_TRAYEMPTY; | 349 } |
313 break; | 350 } |
314 case CDROM_AUDIO_COMPLETED: | 351 |
315 status = CD_STOPPED; | 352 /* if media exists, then do other stuff */ |
316 break; | 353 |
317 case CDROM_AUDIO_PLAY: | 354 memset(&info, 0x00, sizeof(info)); |
318 status = CD_PLAYING; | 355 info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; |
319 break; | 356 |
320 case CDROM_AUDIO_PAUSED: | 357 do { |
321 /* Workaround buggy CD-ROM drive */ | 358 devctlret=devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), NULL); |
322 if ( info.data_format == CDROM_LEADOUT ) { | 359 if (devctlret==EIO) |
323 status = CD_STOPPED; | 360 { |
324 } else { | 361 /* big workaround for media change, handle is unusable after that, |
325 status = CD_PAUSED; | 362 that bug was found in QNX 6.2, 6.2.1 is not released yet. */ |
326 } | 363 |
327 break; | 364 for (i=0; i<MAX_DRIVES; i++) |
328 default: | 365 { |
329 status = CD_ERROR; | 366 if (SDL_cdopen[i]==cdrom->id) |
330 break; | 367 { |
331 } | 368 drive=i; |
332 } | 369 break; |
333 if ( position ) { | 370 } |
334 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | 371 } |
335 *position = MSF_TO_FRAMES( | 372 if (drive==-1) |
336 info.addr.msf.minute, | 373 { |
337 info.addr.msf.second, | 374 /* that cannot happen, but ... */ |
338 info.addr.msf.frame); | 375 break; |
339 } else { | 376 } |
340 *position = 0; | 377 close(cdrom->id); |
341 } | 378 cdrom->id=open(SDL_cdlist[drive], QNX_CD_OPENMODE); |
342 } | 379 devctlret=EAGAIN; |
343 return(status); | 380 } |
381 if (devctlret==EAGAIN) | |
382 { | |
383 eagaincnt++; | |
384 } | |
385 if (eagaincnt==2) | |
386 { | |
387 /* workaround for broken cdroms, which can return always EAGAIN when its not ready, */ | |
388 /* that mean errornous media or just no media avail */ | |
389 devctlret=ENXIO; | |
390 break; | |
391 } | |
392 } while ((devctlret==EAGAIN)||(devctlret==ESTALE)); | |
393 | |
394 if (devctlret != 0) | |
395 { | |
396 if (devctlret==ENXIO) | |
397 { | |
398 status = CD_TRAYEMPTY; | |
399 } | |
400 else | |
401 { | |
402 status = CD_ERROR; | |
403 } | |
404 } | |
405 else | |
406 { | |
407 switch (info.current_position.header.audio_status) | |
408 { | |
409 case CDROM_AUDIO_INVALID: | |
410 case CDROM_AUDIO_NO_STATUS: | |
411 /* Try to determine if there's a CD available */ | |
412 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL)==0) | |
413 status = CD_STOPPED; | |
414 else | |
415 status = CD_TRAYEMPTY; | |
416 break; | |
417 case CDROM_AUDIO_COMPLETED: | |
418 status = CD_STOPPED; | |
419 break; | |
420 case CDROM_AUDIO_PLAY: | |
421 status = CD_PLAYING; | |
422 break; | |
423 case CDROM_AUDIO_PAUSED: | |
424 /* Workaround buggy CD-ROM drive */ | |
425 if (info.current_position.data_format == CDROM_LEADOUT) | |
426 { | |
427 status = CD_STOPPED; | |
428 } | |
429 else | |
430 { | |
431 status = CD_PAUSED; | |
432 } | |
433 break; | |
434 default: | |
435 status = CD_ERROR; | |
436 break; | |
437 } | |
438 } | |
439 | |
440 if (position) | |
441 { | |
442 if (status==CD_PLAYING || (status==CD_PAUSED)) | |
443 { | |
444 *position = MSF_TO_FRAMES(info.current_position.addr.msf.minute, | |
445 info.current_position.addr.msf.second, | |
446 info.current_position.addr.msf.frame); | |
447 } | |
448 else | |
449 { | |
450 *position = 0; | |
451 } | |
452 } | |
453 | |
454 return (status); | |
344 } | 455 } |
345 | 456 |
346 /* Start play */ | 457 /* Start play */ |
347 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | 458 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) |
348 { | 459 { |
349 cdrom_playmsf_t playtime; | 460 cdrom_playmsf_t playtime; |
350 | 461 |
351 FRAMES_TO_MSF(start, | 462 FRAMES_TO_MSF(start, &playtime.start_minute, &playtime.start_second, &playtime.start_frame); |
352 &playtime.start_minute, &playtime.start_second, &playtime.start_frame); | 463 FRAMES_TO_MSF(start+length, &playtime.end_minute, &playtime.end_second, &playtime.end_frame); |
353 FRAMES_TO_MSF(start+length, | 464 |
354 &playtime.end_minute, &playtime.end_second, &playtime.end_frame); | 465 if (devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), NULL) != 0) |
355 #ifdef DEBUG_CDROM | 466 { |
356 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | 467 return -1; |
357 playtime.start_minute, playtime.start_second, playtime.start_frame, | 468 } |
358 playtime.end_minute, playtime.end_second, playtime.end_frame); | 469 else |
359 #endif | 470 { |
360 return(devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), 0)); | 471 return 0; |
472 } | |
361 } | 473 } |
362 | 474 |
363 /* Pause play */ | 475 /* Pause play */ |
364 static int SDL_SYS_CDPause(SDL_CD *cdrom) | 476 static int SDL_SYS_CDPause(SDL_CD *cdrom) |
365 { | 477 { |
366 return(devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, 0)); | 478 if (devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, NULL)!=0) |
479 { | |
480 return -1; | |
481 } | |
482 else | |
483 { | |
484 return 0; | |
485 } | |
367 } | 486 } |
368 | 487 |
369 /* Resume play */ | 488 /* Resume play */ |
370 static int SDL_SYS_CDResume(SDL_CD *cdrom) | 489 static int SDL_SYS_CDResume(SDL_CD *cdrom) |
371 { | 490 { |
372 return(devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, 0)); | 491 if (devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, NULL)!=0) |
492 { | |
493 return -1; | |
494 } | |
495 else | |
496 { | |
497 return 0; | |
498 } | |
373 } | 499 } |
374 | 500 |
375 /* Stop play */ | 501 /* Stop play */ |
376 static int SDL_SYS_CDStop(SDL_CD *cdrom) | 502 static int SDL_SYS_CDStop(SDL_CD *cdrom) |
377 { | 503 { |
378 return(devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, 0)); | 504 if (devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, NULL)!=0) |
505 { | |
506 return -1; | |
507 } | |
508 else | |
509 { | |
510 return 0; | |
511 } | |
379 } | 512 } |
380 | 513 |
381 /* Eject the CD-ROM */ | 514 /* Eject the CD-ROM */ |
382 static int SDL_SYS_CDEject(SDL_CD *cdrom) | 515 static int SDL_SYS_CDEject(SDL_CD *cdrom) |
383 { | 516 { |
384 return(devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, 0)); | 517 if (devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, NULL)!=0) |
518 { | |
519 return -1; | |
520 } | |
521 else | |
522 { | |
523 return 0; | |
524 } | |
385 } | 525 } |
386 | 526 |
387 /* Close the CD-ROM handle */ | 527 /* Close the CD-ROM handle */ |
388 static void SDL_SYS_CDClose(SDL_CD *cdrom) | 528 static void SDL_SYS_CDClose(SDL_CD *cdrom) |
389 { | 529 { |
390 close(cdrom->id); | 530 int i; |
531 | |
532 for (i=0; i<MAX_DRIVES; i++) | |
533 { | |
534 if (SDL_cdopen[i]==cdrom->id) | |
535 { | |
536 SDL_cdopen[i]=0; | |
537 break; | |
538 } | |
539 } | |
540 | |
541 close(cdrom->id); | |
391 } | 542 } |
392 | 543 |
393 void SDL_SYS_CDQuit(void) | 544 void SDL_SYS_CDQuit(void) |
394 { | 545 { |
395 int i; | 546 int i; |
396 | 547 |
397 if ( SDL_numcds > 0 ) { | 548 if (SDL_numcds > 0) |
398 for ( i=0; i<SDL_numcds; ++i ) { | 549 { |
399 free(SDL_cdlist[i]); | 550 for (i=0; i<SDL_numcds; ++i) |
400 } | 551 { |
401 SDL_numcds = 0; | 552 free(SDL_cdlist[i]); |
402 } | 553 } |
403 } | 554 SDL_numcds = 0; |
404 | 555 } |
556 } |