Mercurial > sdl-ios-xcode
annotate src/cdrom/linux/SDL_syscdrom.c @ 1554:0ca607a5d173
Fixed bug #84
Date: Sun, 23 Oct 2005 16:39:03 +0200
From: "A. Schmid" <sahib@phreaker.net>
Subject: [SDL] no software surfaces with svgalib driver?
Hi,
I noticed that the SDL (1.2.9) svgalib driver only makes use of linear
addressable (framebuffer) video modes. On older systems (like one of
mine), linear addressable modes are often not available.
Especially for cards with VESA VBE < 2.0 the svgalib vesa driver is
unusable, since VESA only supports framebuffering for VBE 2.0 and later.
The changes necessary to add support for software surfaces seem to be
relatively small. I only had to hack src/video/svga/SDL_svgavideo.c (see
attached patch). The code worked fine for me, but it is no more than a
proof of concept and should be reviewed (probably has a memory leak when
switching modes). It also uses the vgagl library (included in the
svgalib package) and needs to be linked against it.
-Alex
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 19 Mar 2006 12:04:40 +0000 |
parents | d910939febfa |
children | 92947e3a18db |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
0 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 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 | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1062
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 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 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1379
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 /* Functions for system-level CD-ROM audio control */ | |
25 | |
1341
d02b552e5304
Configure dynamically generates SDL_config.h
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
26 #include <string.h> /* For strerror() */ |
0 | 27 #include <sys/types.h> |
28 #include <sys/stat.h> | |
29 #include <sys/ioctl.h> | |
30 #include <fcntl.h> | |
31 #include <errno.h> | |
32 #include <unistd.h> | |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1379
diff
changeset
|
33 #ifdef __LINUX__ |
1062
3e637850c02b
Date: Tue, 22 Mar 2005 23:50:20 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
1051
diff
changeset
|
34 #ifdef HAVE_LINUX_VERSION_H |
998
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
35 /* linux 2.6.9 workaround */ |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
36 #include <linux/version.h> |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
37 #if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9) |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
38 #include <asm/types.h> |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
39 #define __le64 __u64 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
40 #define __le32 __u32 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
41 #define __le16 __u16 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
42 #define __be64 __u64 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
43 #define __be32 __u32 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
44 #define __be16 __u16 |
0e6627072f7a
Date: Wed, 24 Nov 2004 01:25:48 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
45 #endif /* linux 2.6.9 workaround */ |
1062
3e637850c02b
Date: Tue, 22 Mar 2005 23:50:20 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
1051
diff
changeset
|
46 #endif /* HAVE_LINUX_VERSION_H */ |
0 | 47 #include <linux/cdrom.h> |
48 #endif | |
49 #ifdef __SVR4 | |
50 #include <sys/cdio.h> | |
51 #endif | |
52 | |
53 /* Define this to use the alternative getmntent() code */ | |
54 #ifndef __SVR4 | |
55 #define USE_MNTENT | |
56 #endif | |
57 | |
58 #ifdef USE_MNTENT | |
59 #if defined(__USLC__) | |
60 #include <sys/mntent.h> | |
61 #else | |
62 #include <mntent.h> | |
63 #endif | |
64 | |
65 #ifndef _PATH_MNTTAB | |
66 #ifdef MNTTAB | |
67 #define _PATH_MNTTAB MNTTAB | |
68 #else | |
69 #define _PATH_MNTTAB "/etc/fstab" | |
70 #endif | |
71 #endif /* !_PATH_MNTTAB */ | |
72 | |
73 #ifndef _PATH_MOUNTED | |
74 #define _PATH_MOUNTED "/etc/mtab" | |
75 #endif /* !_PATH_MOUNTED */ | |
76 | |
77 #ifndef MNTTYPE_CDROM | |
78 #define MNTTYPE_CDROM "iso9660" | |
79 #endif | |
80 #ifndef MNTTYPE_SUPER | |
81 #define MNTTYPE_SUPER "supermount" | |
82 #endif | |
83 #endif /* USE_MNTENT */ | |
84 | |
85 #include "SDL_cdrom.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
86 #include "../SDL_syscdrom.h" |
0 | 87 |
88 | |
89 /* The maximum number of CD-ROM drives we'll detect */ | |
90 #define MAX_DRIVES 16 | |
91 | |
92 /* A list of available CD-ROM drives */ | |
93 static char *SDL_cdlist[MAX_DRIVES]; | |
94 static dev_t SDL_cdmode[MAX_DRIVES]; | |
95 | |
96 /* The system-dependent CD control functions */ | |
97 static const char *SDL_SYS_CDName(int drive); | |
98 static int SDL_SYS_CDOpen(int drive); | |
99 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
100 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
101 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
102 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
103 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
104 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
105 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
106 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
107 | |
108 /* 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
|
109 #ifndef ENOMEDIUM |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
110 #define ENOMEDIUM ENOENT |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
111 #endif |
0 | 112 #define ERRNO_TRAYEMPTY(errno) \ |
396
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
113 ((errno == EIO) || (errno == ENOENT) || \ |
11d6eed68dba
Added check for ENOMEDIUM to the Linux CDROM code
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
114 (errno == EINVAL) || (errno == ENOMEDIUM)) |
0 | 115 |
116 /* Check a drive to see if it is a CD-ROM */ | |
117 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) | |
118 { | |
119 int is_cd, cdfd; | |
120 struct cdrom_subchnl info; | |
121 | |
122 /* If it doesn't exist, return -1 */ | |
123 if ( stat(drive, stbuf) < 0 ) { | |
124 return(-1); | |
125 } | |
126 | |
127 /* If it does exist, verify that it's an available CD-ROM */ | |
128 is_cd = 0; | |
129 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { | |
1051
091350827e08
SDL_CDOpen() fails on Linux if data track on disc is mounted in the
Ryan C. Gordon <icculus@icculus.org>
parents:
998
diff
changeset
|
130 cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0); |
0 | 131 if ( cdfd >= 0 ) { |
132 info.cdsc_format = CDROM_MSF; | |
133 /* Under Linux, EIO occurs when a disk is not present. | |
134 */ | |
135 if ( (ioctl(cdfd, CDROMSUBCHNL, &info) == 0) || | |
136 ERRNO_TRAYEMPTY(errno) ) { | |
137 is_cd = 1; | |
138 } | |
139 close(cdfd); | |
140 } | |
141 #ifdef USE_MNTENT | |
142 /* Even if we can't read it, it might be mounted */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
143 else if ( mnttype && (SDL_strcmp(mnttype, MNTTYPE_CDROM) == 0) ) { |
0 | 144 is_cd = 1; |
145 } | |
146 #endif | |
147 } | |
148 return(is_cd); | |
149 } | |
150 | |
151 /* Add a CD-ROM drive to our list of valid drives */ | |
152 static void AddDrive(char *drive, struct stat *stbuf) | |
153 { | |
154 int i; | |
155 | |
156 if ( SDL_numcds < MAX_DRIVES ) { | |
157 /* Check to make sure it's not already in our list. | |
158 This can happen when we see a drive via symbolic link. | |
159 */ | |
160 for ( i=0; i<SDL_numcds; ++i ) { | |
161 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | |
162 #ifdef DEBUG_CDROM | |
163 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | |
164 #endif | |
165 return; | |
166 } | |
167 } | |
168 | |
169 /* Add this drive to our list */ | |
170 i = SDL_numcds; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
171 SDL_cdlist[i] = SDL_strdup(drive); |
0 | 172 if ( SDL_cdlist[i] == NULL ) { |
173 SDL_OutOfMemory(); | |
174 return; | |
175 } | |
176 SDL_cdmode[i] = stbuf->st_rdev; | |
177 ++SDL_numcds; | |
178 #ifdef DEBUG_CDROM | |
179 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
180 #endif | |
181 } | |
182 } | |
183 | |
184 #ifdef USE_MNTENT | |
185 static void CheckMounts(const char *mtab) | |
186 { | |
187 FILE *mntfp; | |
188 struct mntent *mntent; | |
189 struct stat stbuf; | |
190 | |
191 mntfp = setmntent(mtab, "r"); | |
192 if ( mntfp != NULL ) { | |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
193 char *tmp; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
194 char *mnt_type; |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
195 size_t mnt_type_len; |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
196 char *mnt_dev; |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
197 size_t mnt_dev_len; |
0 | 198 |
199 while ( (mntent=getmntent(mntfp)) != NULL ) { | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
200 mnt_type_len = SDL_strlen(mntent->mnt_type) + 1; |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
201 mnt_type = SDL_stack_alloc(char, mnt_type_len); |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
202 if (mnt_type == NULL) |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
203 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
|
204 |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
205 mnt_dev_len = SDL_strlen(mntent->mnt_fsname) + 1; |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
206 mnt_dev = SDL_stack_alloc(char, mnt_dev_len); |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
207 if (mnt_dev == NULL) { |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
208 SDL_stack_free(mnt_type); |
139
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
209 continue; |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
210 } |
ef23a1bf1244
Fixed potential buffer overflow in Linux CD code (thanks Ryan!)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
211 |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
212 SDL_strlcpy(mnt_type, mntent->mnt_type, mnt_type_len); |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
213 SDL_strlcpy(mnt_dev, mntent->mnt_fsname, mnt_dev_len); |
0 | 214 |
215 /* Handle "supermount" filesystem mounts */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
216 if ( SDL_strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
217 tmp = SDL_strstr(mntent->mnt_opts, "fs="); |
0 | 218 if ( tmp ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
219 SDL_free(mnt_type); |
1341
d02b552e5304
Configure dynamically generates SDL_config.h
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
220 mnt_type = SDL_strdup(tmp + SDL_strlen("fs=")); |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
221 if ( mnt_type ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
222 tmp = SDL_strchr(mnt_type, ','); |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
223 if ( tmp ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
224 *tmp = '\0'; |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
225 } |
0 | 226 } |
227 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
228 tmp = SDL_strstr(mntent->mnt_opts, "dev="); |
0 | 229 if ( tmp ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
230 SDL_free(mnt_dev); |
1341
d02b552e5304
Configure dynamically generates SDL_config.h
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
231 mnt_dev = SDL_strdup(tmp + SDL_strlen("dev=")); |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
232 if ( mnt_dev ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
233 tmp = SDL_strchr(mnt_dev, ','); |
247
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
234 if ( tmp ) { |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
235 *tmp = '\0'; |
b0f09f86378d
Fix crash with Linux supermount fstab entries (thanks Erno!)
Sam Lantinga <slouken@libsdl.org>
parents:
139
diff
changeset
|
236 } |
0 | 237 } |
238 } | |
239 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
240 if ( SDL_strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) { |
0 | 241 #ifdef DEBUG_CDROM |
242 fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n", | |
243 mtab, mnt_dev, mntent->mnt_dir, mnt_type); | |
244 #endif | |
245 if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) { | |
246 AddDrive(mnt_dev, &stbuf); | |
247 } | |
248 } | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
249 SDL_stack_free(mnt_dev); |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
250 SDL_stack_free(mnt_type); |
0 | 251 } |
252 endmntent(mntfp); | |
253 } | |
254 } | |
255 #endif /* USE_MNTENT */ | |
256 | |
257 int SDL_SYS_CDInit(void) | |
258 { | |
259 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ | |
260 static char *checklist[] = { | |
261 "cdrom", "?a hd?", "?0 scd?", "?0 sr?", NULL | |
262 }; | |
263 char *SDLcdrom; | |
264 int i, j, exists; | |
265 char drive[32]; | |
266 struct stat stbuf; | |
267 | |
268 /* Fill in our driver capabilities */ | |
269 SDL_CDcaps.Name = SDL_SYS_CDName; | |
270 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
271 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
272 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
273 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
274 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
275 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
276 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
277 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
278 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
279 | |
280 /* Look in the environment for our CD-ROM drive list */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
281 SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ |
0 | 282 if ( SDLcdrom != NULL ) { |
283 char *cdpath, *delim; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
284 size_t len = SDL_strlen(SDLcdrom)+1; |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
285 cdpath = SDL_stack_alloc(char, len); |
0 | 286 if ( cdpath != NULL ) { |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
287 SDL_strlcpy(cdpath, SDLcdrom, len); |
0 | 288 SDLcdrom = cdpath; |
289 do { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
290 delim = SDL_strchr(SDLcdrom, ':'); |
0 | 291 if ( delim ) { |
292 *delim++ = '\0'; | |
293 } | |
294 #ifdef DEBUG_CDROM | |
295 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); | |
296 #endif | |
297 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { | |
298 AddDrive(SDLcdrom, &stbuf); | |
299 } | |
300 if ( delim ) { | |
301 SDLcdrom = delim; | |
302 } else { | |
303 SDLcdrom = NULL; | |
304 } | |
305 } while ( SDLcdrom ); | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
306 SDL_stack_free(cdpath); |
0 | 307 } |
308 | |
309 /* If we found our drives, there's nothing left to do */ | |
310 if ( SDL_numcds > 0 ) { | |
311 return(0); | |
312 } | |
313 } | |
314 | |
315 #ifdef USE_MNTENT | |
316 /* Check /dev/cdrom first :-) */ | |
317 if (CheckDrive("/dev/cdrom", NULL, &stbuf) > 0) { | |
318 AddDrive("/dev/cdrom", &stbuf); | |
319 } | |
320 | |
321 /* Now check the currently mounted CD drives */ | |
322 CheckMounts(_PATH_MOUNTED); | |
323 | |
324 /* Finally check possible mountable drives in /etc/fstab */ | |
325 CheckMounts(_PATH_MNTTAB); | |
326 | |
327 /* If we found our drives, there's nothing left to do */ | |
328 if ( SDL_numcds > 0 ) { | |
329 return(0); | |
330 } | |
331 #endif /* USE_MNTENT */ | |
332 | |
333 /* Scan the system for CD-ROM drives. | |
334 Not always 100% reliable, so use the USE_MNTENT code above first. | |
335 */ | |
336 for ( i=0; checklist[i]; ++i ) { | |
337 if ( checklist[i][0] == '?' ) { | |
338 char *insert; | |
339 exists = 1; | |
340 for ( j=checklist[i][1]; exists; ++j ) { | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
341 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", &checklist[i][3]); |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
342 insert = SDL_strchr(drive, '?'); |
0 | 343 if ( insert != NULL ) { |
344 *insert = j; | |
345 } | |
346 #ifdef DEBUG_CDROM | |
347 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
348 #endif | |
349 switch (CheckDrive(drive, NULL, &stbuf)) { | |
350 /* Drive exists and is a CD-ROM */ | |
351 case 1: | |
352 AddDrive(drive, &stbuf); | |
353 break; | |
354 /* Drive exists, but isn't a CD-ROM */ | |
355 case 0: | |
356 break; | |
357 /* Drive doesn't exist */ | |
358 case -1: | |
359 exists = 0; | |
360 break; | |
361 } | |
362 } | |
363 } else { | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
364 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", checklist[i]); |
0 | 365 #ifdef DEBUG_CDROM |
366 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); | |
367 #endif | |
368 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { | |
369 AddDrive(drive, &stbuf); | |
370 } | |
371 } | |
372 } | |
373 return(0); | |
374 } | |
375 | |
376 /* General ioctl() CD-ROM command function */ | |
377 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
378 { | |
379 int retval; | |
380 | |
381 retval = ioctl(id, command, arg); | |
382 if ( retval < 0 ) { | |
383 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
384 } | |
385 return(retval); | |
386 } | |
387 | |
388 static const char *SDL_SYS_CDName(int drive) | |
389 { | |
390 return(SDL_cdlist[drive]); | |
391 } | |
392 | |
393 static int SDL_SYS_CDOpen(int drive) | |
394 { | |
1051
091350827e08
SDL_CDOpen() fails on Linux if data track on disc is mounted in the
Ryan C. Gordon <icculus@icculus.org>
parents:
998
diff
changeset
|
395 return(open(SDL_cdlist[drive], (O_RDONLY|O_NONBLOCK), 0)); |
0 | 396 } |
397 | |
398 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
399 { | |
400 struct cdrom_tochdr toc; | |
401 int i, okay; | |
402 struct cdrom_tocentry entry; | |
403 | |
404 okay = 0; | |
405 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0 ) { | |
406 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; | |
407 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
408 cdrom->numtracks = SDL_MAX_TRACKS; | |
409 } | |
410 /* Read all the track TOC entries */ | |
411 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
412 if ( i == cdrom->numtracks ) { | |
413 cdrom->track[i].id = CDROM_LEADOUT; | |
414 } else { | |
415 cdrom->track[i].id = toc.cdth_trk0+i; | |
416 } | |
417 entry.cdte_track = cdrom->track[i].id; | |
418 entry.cdte_format = CDROM_MSF; | |
419 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, | |
420 &entry) < 0 ) { | |
421 break; | |
422 } else { | |
423 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { | |
424 cdrom->track[i].type = SDL_DATA_TRACK; | |
425 } else { | |
426 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
427 } | |
428 cdrom->track[i].offset = MSF_TO_FRAMES( | |
429 entry.cdte_addr.msf.minute, | |
430 entry.cdte_addr.msf.second, | |
431 entry.cdte_addr.msf.frame); | |
432 cdrom->track[i].length = 0; | |
433 if ( i > 0 ) { | |
434 cdrom->track[i-1].length = | |
435 cdrom->track[i].offset- | |
436 cdrom->track[i-1].offset; | |
437 } | |
438 } | |
439 } | |
440 if ( i == (cdrom->numtracks+1) ) { | |
441 okay = 1; | |
442 } | |
443 } | |
444 return(okay ? 0 : -1); | |
445 } | |
446 | |
447 /* Get CD-ROM status */ | |
448 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
449 { | |
450 CDstatus status; | |
451 struct cdrom_tochdr toc; | |
452 struct cdrom_subchnl info; | |
453 | |
454 info.cdsc_format = CDROM_MSF; | |
455 if ( ioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { | |
456 if ( ERRNO_TRAYEMPTY(errno) ) { | |
457 status = CD_TRAYEMPTY; | |
458 } else { | |
459 status = CD_ERROR; | |
460 } | |
461 } else { | |
462 switch (info.cdsc_audiostatus) { | |
463 case CDROM_AUDIO_INVALID: | |
464 case CDROM_AUDIO_NO_STATUS: | |
465 /* Try to determine if there's a CD available */ | |
466 if (ioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) | |
467 status = CD_STOPPED; | |
468 else | |
469 status = CD_TRAYEMPTY; | |
470 break; | |
471 case CDROM_AUDIO_COMPLETED: | |
472 status = CD_STOPPED; | |
473 break; | |
474 case CDROM_AUDIO_PLAY: | |
475 status = CD_PLAYING; | |
476 break; | |
477 case CDROM_AUDIO_PAUSED: | |
478 /* Workaround buggy CD-ROM drive */ | |
479 if ( info.cdsc_trk == CDROM_LEADOUT ) { | |
480 status = CD_STOPPED; | |
481 } else { | |
482 status = CD_PAUSED; | |
483 } | |
484 break; | |
485 default: | |
486 status = CD_ERROR; | |
487 break; | |
488 } | |
489 } | |
490 if ( position ) { | |
491 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
492 *position = MSF_TO_FRAMES( | |
493 info.cdsc_absaddr.msf.minute, | |
494 info.cdsc_absaddr.msf.second, | |
495 info.cdsc_absaddr.msf.frame); | |
496 } else { | |
497 *position = 0; | |
498 } | |
499 } | |
500 return(status); | |
501 } | |
502 | |
503 /* Start play */ | |
504 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
505 { | |
506 struct cdrom_msf playtime; | |
507 | |
508 FRAMES_TO_MSF(start, | |
509 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
510 FRAMES_TO_MSF(start+length, | |
511 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
512 #ifdef DEBUG_CDROM | |
513 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
514 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
515 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
516 #endif | |
517 return(SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime)); | |
518 } | |
519 | |
520 /* Pause play */ | |
521 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
522 { | |
523 return(SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0)); | |
524 } | |
525 | |
526 /* Resume play */ | |
527 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
528 { | |
529 return(SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0)); | |
530 } | |
531 | |
532 /* Stop play */ | |
533 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
534 { | |
535 return(SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0)); | |
536 } | |
537 | |
538 /* Eject the CD-ROM */ | |
539 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
540 { | |
541 return(SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0)); | |
542 } | |
543 | |
544 /* Close the CD-ROM handle */ | |
545 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
546 { | |
547 close(cdrom->id); | |
548 } | |
549 | |
550 void SDL_SYS_CDQuit(void) | |
551 { | |
552 int i; | |
553 | |
554 if ( SDL_numcds > 0 ) { | |
555 for ( i=0; i<SDL_numcds; ++i ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
556 SDL_free(SDL_cdlist[i]); |
0 | 557 } |
558 SDL_numcds = 0; | |
559 } | |
560 } | |
561 |