Mercurial > sdl-ios-xcode
annotate src/cdrom/openbsd/SDL_syscdrom.c @ 883:50f5a29c6a17
Date: Sat, 10 Apr 2004 02:25:33 -0400
From: Glenn Maynard
To: sdl@libsdl.org
Subject: [SDL] SDL_SetVideoMode() failing and not setting an error (patch)
Running an OpenGL SDL application off 1.2.7, at SDL_InitSubSystem(SDL_INIT_VIDEO) time:
Warning: Unable to initialize AAlib mouseUsing AAlib driver: Slang driver 1.0 (slang)
SDL_SetVideoMode then fails; SDL_GetError() returns "".
The installation problem is straightforward: X (the higher priority
driver) isn't running, so SDL is falling back on aalib. However,
no error is being set when aalib fails to initialize. This also
happens with the svgalib driver.
SDL_video.c line ~653 sets mode to NULL, since aalib didn't return an
OpenGL surface. Line ~711 ("failed setting a video mode") returns NULL.
The attached patch sets an error. It's a horrible, useless error
message--it should really say eg. "aalib does not support OpenGL"; this
should probably be done earlier in the individual drivers, too.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 11 Apr 2004 19:54:40 +0000 |
parents | b8d311d90021 |
children | 0f3aa6ab3341 |
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:
297
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:
25
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 <sys/ioctl.h> | |
32 #include <stdlib.h> | |
33 #include <sys/stat.h> | |
34 #include <fcntl.h> | |
35 #include <stdio.h> | |
36 #include <string.h> | |
37 #include <errno.h> | |
38 #include <unistd.h> | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
39 #include <sys/ioctl.h> |
0 | 40 #include <sys/cdio.h> |
41 | |
42 #include "SDL_error.h" | |
43 #include "SDL_cdrom.h" | |
44 #include "SDL_syscdrom.h" | |
45 | |
46 | |
47 /* The maximum number of CD-ROM drives we'll detect */ | |
48 #define MAX_DRIVES 16 | |
49 | |
50 /* A list of available CD-ROM drives */ | |
51 static char *SDL_cdlist[MAX_DRIVES]; | |
52 static dev_t SDL_cdmode[MAX_DRIVES]; | |
53 | |
54 /* The system-dependent CD control functions */ | |
55 static const char *SDL_SYS_CDName(int drive); | |
56 static int SDL_SYS_CDOpen(int drive); | |
57 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
58 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
59 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
60 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
61 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
62 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
63 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
64 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
65 | |
66 /* Some ioctl() errno values which occur when the tray is empty */ | |
67 #define ERRNO_TRAYEMPTY(errno) \ | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
68 ((errno == EIO) || (errno == ENOENT) || (errno == EINVAL) || \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
69 (errno == ENODEV)) |
0 | 70 |
71 /* Check a drive to see if it is a CD-ROM */ | |
72 static int CheckDrive(char *drive, struct stat *stbuf) | |
73 { | |
74 int is_cd, cdfd; | |
75 struct ioc_read_subchannel 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.address_format = CD_MSF_FORMAT; | |
88 info.data_format = CD_CURRENT_POSITION; | |
89 info.data_len = 0; | |
90 info.data = NULL; | |
91 /* Under Linux, EIO occurs when a disk is not present. | |
92 This isn't 100% reliable, so we use the USE_MNTENT | |
93 code above instead. | |
94 */ | |
95 if ( (ioctl(cdfd, CDIOCREADSUBCHANNEL, &info) == 0) || | |
96 ERRNO_TRAYEMPTY(errno) ) { | |
97 is_cd = 1; | |
98 } | |
99 close(cdfd); | |
100 } | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
101 else if (ERRNO_TRAYEMPTY(errno)) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
102 is_cd = 1; |
0 | 103 } |
104 return(is_cd); | |
105 } | |
106 | |
107 /* Add a CD-ROM drive to our list of valid drives */ | |
108 static void AddDrive(char *drive, struct stat *stbuf) | |
109 { | |
110 int i; | |
111 | |
112 if ( SDL_numcds < MAX_DRIVES ) { | |
113 /* Check to make sure it's not already in our list. | |
114 This can happen when we see a drive via symbolic link. | |
115 */ | |
116 for ( i=0; i<SDL_numcds; ++i ) { | |
117 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | |
118 #ifdef DEBUG_CDROM | |
119 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | |
120 #endif | |
121 return; | |
122 } | |
123 } | |
124 | |
125 /* Add this drive to our list */ | |
126 i = SDL_numcds; | |
127 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | |
128 if ( SDL_cdlist[i] == NULL ) { | |
129 SDL_OutOfMemory(); | |
130 return; | |
131 } | |
132 strcpy(SDL_cdlist[i], drive); | |
133 SDL_cdmode[i] = stbuf->st_rdev; | |
134 ++SDL_numcds; | |
135 #ifdef DEBUG_CDROM | |
136 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
137 #endif | |
138 } | |
139 } | |
140 | |
141 int SDL_SYS_CDInit(void) | |
142 { | |
143 static char *checklist[] = { | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
144 #ifdef __OpenBSD__ |
25
3fbf86244fd2
Date: Wed, 9 May 2001 18:03:20 -0600
Sam Lantinga <slouken@lokigames.com>
parents:
1
diff
changeset
|
145 "?0 cd?c", "cdrom", NULL |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
146 #else |
0 | 147 "?0 cd?c", "?0 acd?c", "cdrom", NULL |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
148 #endif |
0 | 149 }; |
150 char *SDLcdrom; | |
151 int i, j, exists; | |
152 char drive[32]; | |
153 struct stat stbuf; | |
154 | |
155 /* Fill in our driver capabilities */ | |
156 SDL_CDcaps.Name = SDL_SYS_CDName; | |
157 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
158 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
159 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
160 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
161 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
162 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
163 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
164 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
165 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
166 | |
167 /* Look in the environment for our CD-ROM drive list */ | |
168 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ | |
169 if ( SDLcdrom != NULL ) { | |
170 char *cdpath, *delim; | |
171 cdpath = malloc(strlen(SDLcdrom)+1); | |
172 if ( cdpath != NULL ) { | |
173 strcpy(cdpath, SDLcdrom); | |
174 SDLcdrom = cdpath; | |
175 do { | |
176 delim = strchr(SDLcdrom, ':'); | |
177 if ( delim ) { | |
178 *delim++ = '\0'; | |
179 } | |
180 if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) { | |
181 AddDrive(SDLcdrom, &stbuf); | |
182 } | |
183 if ( delim ) { | |
184 SDLcdrom = delim; | |
185 } else { | |
186 SDLcdrom = NULL; | |
187 } | |
188 } while ( SDLcdrom ); | |
189 free(cdpath); | |
190 } | |
191 | |
192 /* If we found our drives, there's nothing left to do */ | |
193 if ( SDL_numcds > 0 ) { | |
194 return(0); | |
195 } | |
196 } | |
197 | |
198 /* Scan the system for CD-ROM drives */ | |
199 for ( i=0; checklist[i]; ++i ) { | |
200 if ( checklist[i][0] == '?' ) { | |
201 char *insert; | |
202 exists = 1; | |
203 for ( j=checklist[i][1]; exists; ++j ) { | |
204 sprintf(drive, "/dev/%s", &checklist[i][3]); | |
205 insert = strchr(drive, '?'); | |
206 if ( insert != NULL ) { | |
207 *insert = j; | |
208 } | |
209 switch (CheckDrive(drive, &stbuf)) { | |
210 /* Drive exists and is a CD-ROM */ | |
211 case 1: | |
212 AddDrive(drive, &stbuf); | |
213 break; | |
214 /* Drive exists, but isn't a CD-ROM */ | |
215 case 0: | |
216 break; | |
217 /* Drive doesn't exist */ | |
218 case -1: | |
219 exists = 0; | |
220 break; | |
221 } | |
222 } | |
223 } else { | |
224 sprintf(drive, "/dev/%s", checklist[i]); | |
225 if ( CheckDrive(drive, &stbuf) > 0 ) { | |
226 AddDrive(drive, &stbuf); | |
227 } | |
228 } | |
229 } | |
230 return(0); | |
231 } | |
232 | |
233 /* General ioctl() CD-ROM command function */ | |
234 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
235 { | |
236 int retval; | |
237 | |
238 retval = ioctl(id, command, arg); | |
239 if ( retval < 0 ) { | |
240 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
241 } | |
242 return(retval); | |
243 } | |
244 | |
245 static const char *SDL_SYS_CDName(int drive) | |
246 { | |
247 return(SDL_cdlist[drive]); | |
248 } | |
249 | |
250 static int SDL_SYS_CDOpen(int drive) | |
251 { | |
252 return(open(SDL_cdlist[drive], (O_RDONLY|O_EXCL|O_NONBLOCK), 0)); | |
253 } | |
254 | |
255 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
256 { | |
257 struct ioc_toc_header toc; | |
258 int i, okay; | |
259 struct ioc_read_toc_entry entry; | |
260 struct cd_toc_entry data; | |
261 | |
262 okay = 0; | |
263 if ( SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0 ) { | |
264 cdrom->numtracks = toc.ending_track-toc.starting_track+1; | |
265 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
266 cdrom->numtracks = SDL_MAX_TRACKS; | |
267 } | |
268 /* Read all the track TOC entries */ | |
269 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
270 if ( i == cdrom->numtracks ) { | |
271 cdrom->track[i].id = 0xAA; /* CDROM_LEADOUT */ | |
272 } else { | |
273 cdrom->track[i].id = toc.starting_track+i; | |
274 } | |
275 entry.starting_track = cdrom->track[i].id; | |
276 entry.address_format = CD_MSF_FORMAT; | |
277 entry.data_len = sizeof(data); | |
278 entry.data = &data; | |
279 if ( SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCENTRYS, | |
280 &entry) < 0 ) { | |
281 break; | |
282 } else { | |
283 cdrom->track[i].type = data.control; | |
284 cdrom->track[i].offset = MSF_TO_FRAMES( | |
285 data.addr.msf.minute, | |
286 data.addr.msf.second, | |
287 data.addr.msf.frame); | |
288 cdrom->track[i].length = 0; | |
289 if ( i > 0 ) { | |
290 cdrom->track[i-1].length = | |
291 cdrom->track[i].offset- | |
292 cdrom->track[i-1].offset; | |
293 } | |
294 } | |
295 } | |
296 if ( i == (cdrom->numtracks+1) ) { | |
297 okay = 1; | |
298 } | |
299 } | |
300 return(okay ? 0 : -1); | |
301 } | |
302 | |
303 /* Get CD-ROM status */ | |
304 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
305 { | |
306 CDstatus status; | |
307 struct ioc_toc_header toc; | |
308 struct ioc_read_subchannel info; | |
309 struct cd_sub_channel_info data; | |
310 | |
311 info.address_format = CD_MSF_FORMAT; | |
312 info.data_format = CD_CURRENT_POSITION; | |
313 info.track = 0; | |
314 info.data_len = sizeof(data); | |
315 info.data = &data; | |
316 if ( ioctl(cdrom->id, CDIOCREADSUBCHANNEL, &info) < 0 ) { | |
317 if ( ERRNO_TRAYEMPTY(errno) ) { | |
318 status = CD_TRAYEMPTY; | |
319 } else { | |
320 status = CD_ERROR; | |
321 } | |
322 } else { | |
323 switch (data.header.audio_status) { | |
324 case CD_AS_AUDIO_INVALID: | |
325 case CD_AS_NO_STATUS: | |
326 /* Try to determine if there's a CD available */ | |
327 if (ioctl(cdrom->id,CDIOREADTOCHEADER,&toc)==0) | |
328 status = CD_STOPPED; | |
329 else | |
330 status = CD_TRAYEMPTY; | |
331 break; | |
332 case CD_AS_PLAY_COMPLETED: | |
333 status = CD_STOPPED; | |
334 break; | |
335 case CD_AS_PLAY_IN_PROGRESS: | |
336 status = CD_PLAYING; | |
337 break; | |
338 case CD_AS_PLAY_PAUSED: | |
339 status = CD_PAUSED; | |
340 break; | |
341 default: | |
342 status = CD_ERROR; | |
343 break; | |
344 } | |
345 } | |
346 if ( position ) { | |
347 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
348 *position = MSF_TO_FRAMES( | |
349 data.what.position.absaddr.msf.minute, | |
350 data.what.position.absaddr.msf.second, | |
351 data.what.position.absaddr.msf.frame); | |
352 } else { | |
353 *position = 0; | |
354 } | |
355 } | |
356 return(status); | |
357 } | |
358 | |
359 /* Start play */ | |
360 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
361 { | |
362 struct ioc_play_msf playtime; | |
363 | |
364 FRAMES_TO_MSF(start, | |
365 &playtime.start_m, &playtime.start_s, &playtime.start_f); | |
366 FRAMES_TO_MSF(start+length, | |
367 &playtime.end_m, &playtime.end_s, &playtime.end_f); | |
368 #ifdef DEBUG_CDROM | |
369 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
370 playtime.start_m, playtime.start_s, playtime.start_f, | |
371 playtime.end_m, playtime.end_s, playtime.end_f); | |
372 #endif | |
373 ioctl(cdrom->id, CDIOCSTART, 0); | |
374 return(SDL_SYS_CDioctl(cdrom->id, CDIOCPLAYMSF, &playtime)); | |
375 } | |
376 | |
377 /* Pause play */ | |
378 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
379 { | |
380 return(SDL_SYS_CDioctl(cdrom->id, CDIOCPAUSE, 0)); | |
381 } | |
382 | |
383 /* Resume play */ | |
384 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
385 { | |
386 return(SDL_SYS_CDioctl(cdrom->id, CDIOCRESUME, 0)); | |
387 } | |
388 | |
389 /* Stop play */ | |
390 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
391 { | |
392 return(SDL_SYS_CDioctl(cdrom->id, CDIOCSTOP, 0)); | |
393 } | |
394 | |
395 /* Eject the CD-ROM */ | |
396 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
397 { | |
398 return(SDL_SYS_CDioctl(cdrom->id, CDIOCEJECT, 0)); | |
399 } | |
400 | |
401 /* Close the CD-ROM handle */ | |
402 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
403 { | |
404 close(cdrom->id); | |
405 } | |
406 | |
407 void SDL_SYS_CDQuit(void) | |
408 { | |
409 int i; | |
410 | |
411 if ( SDL_numcds > 0 ) { | |
412 for ( i=0; i<SDL_numcds; ++i ) { | |
413 free(SDL_cdlist[i]); | |
414 } | |
415 SDL_numcds = 0; | |
416 } | |
417 } | |
418 |