Mercurial > sdl-ios-xcode
annotate src/cdrom/qnx/SDL_syscdrom.c @ 320:66f815c147ed
Date: Thu, 28 Mar 2002 09:20:03 +0200
From: "Mike Gorchak" <mike@malva.ua>
Subject: New QNX patch.
Hi !
1. Removed warning (possible bug) with invalid type, passing to the function
in ph_WarpedMotion.
2. Rewritten handler of Ph_WM_RESIZE message, now works, but buggy (old
handler doesn't work at all).
3. Added stub handler for Ph_WM_MAX (maximize) message.
4. Added more #ifdef HAVE_OPENGL to disable OpenGL stuff when it not needed.
5. Added support for SDL_NOFRAME and SDL_RESIZABLE flags (in OpenGL windows
too).
6. Added cosmetic changes, if no SDL_RESIZABLE flag defined, disable resize
handlers in window border and maximize button at caption.
7. Fixed my bug with invalid arguments count passed to PtCreateWidget call.
8. Fixed some palette problems.
9. Updated README.QNX file.
And I changed testgl.c test application:
10. Added in testgl.c application support for SDL_NOFRAME flag and
option -noframe.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 28 Mar 2002 16:20:10 +0000 |
parents | f6ffac90895c |
children | 8e3ce997621c |
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:
0
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 #include <sys/cdrom.h> | |
40 #include <sys/dcmd_cam.h> | |
41 | |
42 | |
43 #include "SDL_error.h" | |
44 #include "SDL_cdrom.h" | |
45 #include "SDL_syscdrom.h" | |
46 | |
47 | |
48 /* The maximum number of CD-ROM drives we'll detect */ | |
49 #define MAX_DRIVES 16 | |
50 | |
51 /* A list of available CD-ROM drives */ | |
52 static char *SDL_cdlist[MAX_DRIVES]; | |
53 static dev_t SDL_cdmode[MAX_DRIVES]; | |
54 | |
55 /* The system-dependent CD control functions */ | |
56 static const char *SDL_SYS_CDName(int drive); | |
57 static int SDL_SYS_CDOpen(int drive); | |
58 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
59 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
60 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
61 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
62 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
63 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
64 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
65 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
66 | |
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 */ | |
72 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) | |
73 { | |
74 int is_cd, cdfd; | |
75 cdrom_subch_data_t info; | |
76 | |
77 /* If it doesn't exist, return -1 */ | |
78 if ( stat(drive, stbuf) < 0 ) { | |
79 return(-1); | |
80 } | |
81 | |
82 /* If it does exist, verify that it's an available CD-ROM */ | |
83 is_cd = 0; | |
84 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { | |
85 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); | |
86 if ( cdfd >= 0 ) { | |
87 info.subch_command.data_format = CDROM_MSF; | |
88 /* Under Linux, EIO occurs when a disk is not present. | |
89 */ | |
90 if ((devctl(cdfd,DCMD_CAM_CDROMSUBCHNL,&info,sizeof(info),0) == 0) || | |
91 ERRNO_TRAYEMPTY(errno) ) | |
92 { | |
93 is_cd = 1; | |
94 } | |
95 close(cdfd); | |
96 } | |
97 } | |
98 return(is_cd); | |
99 } | |
100 | |
101 /* Add a CD-ROM drive to our list of valid drives */ | |
102 static void AddDrive(char *drive, struct stat *stbuf) | |
103 { | |
104 int i; | |
105 | |
106 if ( SDL_numcds < MAX_DRIVES ) { | |
107 /* Check to make sure it's not already in our list. | |
108 This can happen when we see a drive via symbolic link. | |
109 */ | |
110 for ( i=0; i<SDL_numcds; ++i ) { | |
111 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | |
112 #ifdef DEBUG_CDROM | |
113 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | |
114 #endif | |
115 return; | |
116 } | |
117 } | |
118 | |
119 /* Add this drive to our list */ | |
120 i = SDL_numcds; | |
121 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | |
122 if ( SDL_cdlist[i] == NULL ) { | |
123 SDL_OutOfMemory(); | |
124 return; | |
125 } | |
126 strcpy(SDL_cdlist[i], drive); | |
127 SDL_cdmode[i] = stbuf->st_rdev; | |
128 ++SDL_numcds; | |
129 #ifdef DEBUG_CDROM | |
130 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
131 #endif | |
132 } | |
133 } | |
134 | |
135 int SDL_SYS_CDInit(void) | |
136 { | |
137 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ | |
138 static char *checklist[] = { | |
139 "cdrom", "?0 cd?", "?1 cd?", "?a hd?", "?0 scd?", "?0 sr?", NULL | |
140 }; | |
141 char *SDLcdrom; | |
142 int i, j, exists; | |
143 char drive[32]; | |
144 struct stat stbuf; | |
145 | |
146 /* Fill in our driver capabilities */ | |
147 SDL_CDcaps.Name = SDL_SYS_CDName; | |
148 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
149 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
150 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
151 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
152 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
153 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
154 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
155 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
156 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
157 | |
158 /* Look in the environment for our CD-ROM drive list */ | |
159 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ | |
160 if ( SDLcdrom != NULL ) { | |
161 char *cdpath, *delim; | |
162 cdpath = malloc(strlen(SDLcdrom)+1); | |
163 if ( cdpath != NULL ) { | |
164 strcpy(cdpath, SDLcdrom); | |
165 SDLcdrom = cdpath; | |
166 do { | |
167 delim = strchr(SDLcdrom, ':'); | |
168 if ( delim ) { | |
169 *delim++ = '\0'; | |
170 } | |
171 #ifdef DEBUG_CDROM | |
172 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); | |
173 #endif | |
174 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { | |
175 AddDrive(SDLcdrom, &stbuf); | |
176 } | |
177 if ( delim ) { | |
178 SDLcdrom = delim; | |
179 } else { | |
180 SDLcdrom = NULL; | |
181 } | |
182 } while ( SDLcdrom ); | |
183 free(cdpath); | |
184 } | |
185 | |
186 /* If we found our drives, there's nothing left to do */ | |
187 if ( SDL_numcds > 0 ) { | |
188 return(0); | |
189 } | |
190 } | |
191 | |
192 /* Scan the system for CD-ROM drives */ | |
193 for ( i=0; checklist[i]; ++i ) { | |
194 if ( checklist[i][0] == '?' ) { | |
195 char *insert; | |
196 exists = 1; | |
197 for ( j=checklist[i][1]; exists; ++j ) { | |
198 sprintf(drive, "/dev/%s", &checklist[i][3]); | |
199 insert = strchr(drive, '?'); | |
200 if ( insert != NULL ) { | |
201 *insert = j; | |
202 } | |
203 #ifdef DEBUG_CDROM | |
204 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
205 #endif | |
206 switch (CheckDrive(drive, NULL, &stbuf)) { | |
207 /* Drive exists and is a CD-ROM */ | |
208 case 1: | |
209 AddDrive(drive, &stbuf); | |
210 break; | |
211 /* Drive exists, but isn't a CD-ROM */ | |
212 case 0: | |
213 break; | |
214 /* Drive doesn't exist */ | |
215 case -1: | |
216 exists = 0; | |
217 break; | |
218 } | |
219 } | |
220 } else { | |
221 sprintf(drive, "/dev/%s", checklist[i]); | |
222 #ifdef DEBUG_CDROM | |
223 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
224 #endif | |
225 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { | |
226 AddDrive(drive, &stbuf); | |
227 } | |
228 } | |
229 } | |
230 return(0); | |
231 } | |
232 | |
233 static const char *SDL_SYS_CDName(int drive) | |
234 { | |
235 return(SDL_cdlist[drive]); | |
236 } | |
237 | |
238 static int SDL_SYS_CDOpen(int drive) | |
239 { | |
240 return(open(SDL_cdlist[drive], (O_RDONLY|O_EXCL|O_NONBLOCK), 0)); | |
241 } | |
242 | |
243 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
244 { | |
245 cdrom_read_toc_t toc; | |
246 int i, okay; | |
247 | |
248 okay = 0; | |
249 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0) == 0) { | |
250 cdrom->numtracks = toc.last_track - toc.first_track + 1; | |
251 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
252 cdrom->numtracks = SDL_MAX_TRACKS; | |
253 } | |
254 /* Read all the track TOC entries */ | |
255 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
256 if ( i == cdrom->numtracks ) { | |
257 cdrom->track[i].id = CDROM_LEADOUT; | |
258 } else { | |
259 #if 0 /* Sam 11/6/00 - an obsolete field? */ | |
260 cdrom->track[i].id = toc.cdth_trk0+i; | |
261 #else | |
262 cdrom->track[i].id = toc.first_track+i; | |
263 #endif | |
264 } | |
265 cdrom->track[i].type = toc.toc_entry[i].control_adr; | |
266 cdrom->track[i].offset = MSF_TO_FRAMES( | |
267 toc.toc_entry[i].addr.msf.minute, | |
268 toc.toc_entry[i].addr.msf.second, | |
269 toc.toc_entry[i].addr.msf.frame); | |
270 cdrom->track[i].length = 0; | |
271 if ( i > 0 ) { | |
272 cdrom->track[i-1].length = | |
273 cdrom->track[i].offset- | |
274 cdrom->track[i-1].offset; | |
275 } | |
276 } | |
277 if ( i == (cdrom->numtracks+1) ) { | |
278 okay = 1; | |
279 } | |
280 } | |
281 return(okay ? 0 : -1); | |
282 } | |
283 | |
284 /* Get CD-ROM status */ | |
285 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
286 { | |
287 CDstatus status; | |
288 cdrom_read_toc_t toc; | |
289 subch_current_position_t info; | |
290 | |
291 #if 0 /* Sam 11/6/00 - an obsolete field? */ | |
292 info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; | |
293 info.subch_command.track_number = 0; | |
294 #else | |
295 info.data_format = CDROM_SUBCH_CURRENT_POSITION; | |
296 info.track_number = 0; | |
297 #endif | |
298 if (devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), 0) != 0) { | |
299 if ( ERRNO_TRAYEMPTY(errno) ) { | |
300 status = CD_TRAYEMPTY; | |
301 } else { | |
302 status = CD_ERROR; | |
303 } | |
304 } else { | |
305 switch (info.header.audio_status) { | |
306 case CDROM_AUDIO_INVALID: | |
307 case CDROM_AUDIO_NO_STATUS: | |
308 /* Try to determine if there's a CD available */ | |
309 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0)==0) | |
310 status = CD_STOPPED; | |
311 else | |
312 status = CD_TRAYEMPTY; | |
313 break; | |
314 case CDROM_AUDIO_COMPLETED: | |
315 status = CD_STOPPED; | |
316 break; | |
317 case CDROM_AUDIO_PLAY: | |
318 status = CD_PLAYING; | |
319 break; | |
320 case CDROM_AUDIO_PAUSED: | |
321 /* Workaround buggy CD-ROM drive */ | |
322 if ( info.data_format == CDROM_LEADOUT ) { | |
323 status = CD_STOPPED; | |
324 } else { | |
325 status = CD_PAUSED; | |
326 } | |
327 break; | |
328 default: | |
329 status = CD_ERROR; | |
330 break; | |
331 } | |
332 } | |
333 if ( position ) { | |
334 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
335 *position = MSF_TO_FRAMES( | |
336 info.addr.msf.minute, | |
337 info.addr.msf.second, | |
338 info.addr.msf.frame); | |
339 } else { | |
340 *position = 0; | |
341 } | |
342 } | |
343 return(status); | |
344 } | |
345 | |
346 /* Start play */ | |
347 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
348 { | |
349 cdrom_playmsf_t playtime; | |
350 | |
351 FRAMES_TO_MSF(start, | |
352 &playtime.start_minute, &playtime.start_second, &playtime.start_frame); | |
353 FRAMES_TO_MSF(start+length, | |
354 &playtime.end_minute, &playtime.end_second, &playtime.end_frame); | |
355 #ifdef DEBUG_CDROM | |
356 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
357 playtime.start_minute, playtime.start_second, playtime.start_frame, | |
358 playtime.end_minute, playtime.end_second, playtime.end_frame); | |
359 #endif | |
360 return(devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), 0)); | |
361 } | |
362 | |
363 /* Pause play */ | |
364 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
365 { | |
366 return(devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, 0)); | |
367 } | |
368 | |
369 /* Resume play */ | |
370 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
371 { | |
372 return(devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, 0)); | |
373 } | |
374 | |
375 /* Stop play */ | |
376 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
377 { | |
378 return(devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, 0)); | |
379 } | |
380 | |
381 /* Eject the CD-ROM */ | |
382 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
383 { | |
384 return(devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, 0)); | |
385 } | |
386 | |
387 /* Close the CD-ROM handle */ | |
388 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
389 { | |
390 close(cdrom->id); | |
391 } | |
392 | |
393 void SDL_SYS_CDQuit(void) | |
394 { | |
395 int i; | |
396 | |
397 if ( SDL_numcds > 0 ) { | |
398 for ( i=0; i<SDL_numcds; ++i ) { | |
399 free(SDL_cdlist[i]); | |
400 } | |
401 SDL_numcds = 0; | |
402 } | |
403 } | |
404 |