Mercurial > sdl-ios-xcode
annotate src/cdrom/mint/SDL_syscdrom.c @ 816:428f688f2ad2
Date: Fri, 13 Feb 2004 17:03:16 +0100
From: Max Horn
Subject: Modifier key fix
The internal modifier state can get out of sync with reality. To
trigger this, do for example this:
1) Launch an SDL app
2) Alt-click on the desktop (this will hide the SDL app).
3) Bring the SDL app back to the front
4) SDL will still think alt is pressed (and as such will treat left
clicks like middle clicks). If you press and release alt, it'll be fine
again.
The attached patch cures this by rechecking the modifier state whenever
we process an event.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 13 Feb 2004 17:57:16 +0000 |
parents | b8d311d90021 |
children | 604d73db6802 |
rev | line source |
---|---|
724 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
727
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
724 | 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 | |
20 slouken@libsdl.org | |
21 */ | |
22 | |
23 /* | |
24 Atari MetaDOS CD-ROM functions | |
25 | |
26 Patrice Mandin | |
27 */ | |
28 | |
29 #include <errno.h> | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 | |
34 #include <cdromio.h> | |
35 #include <metados.h> | |
36 | |
37 #include "SDL_error.h" | |
38 #include "SDL_cdrom.h" | |
39 #include "SDL_syscdrom.h" | |
40 | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
41 /* Some ioctl() errno values which occur when the tray is empty */ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
42 #ifndef ENOMEDIUM |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
43 #define ENOMEDIUM ENOENT |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
44 #endif |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
45 #define ERRNO_TRAYEMPTY(errno) \ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
46 ((errno == EIO) || (errno == ENOENT) || \ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
47 (errno == EINVAL) || (errno == ENOMEDIUM)) |
724 | 48 |
49 /* The maximum number of CD-ROM drives we'll detect */ | |
50 #define MAX_DRIVES 32 | |
51 | |
52 typedef struct { | |
53 unsigned char device[3]; /* Physical device letter + ':' + '\0' */ | |
54 metaopen_t metaopen; /* Infos on opened drive */ | |
55 } metados_drive_t; | |
56 | |
57 static metados_drive_t metados_drives[MAX_DRIVES]; | |
58 | |
59 /* The system-dependent CD control functions */ | |
60 static const char *SDL_SYS_CDName(int drive); | |
61 static int SDL_SYS_CDOpen(int drive); | |
62 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
63 static int SDL_SYS_CDioctl(int id, int command, void *arg); | |
64 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
65 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
66 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
67 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
68 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
69 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
70 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
71 | |
72 int SDL_SYS_CDInit(void) | |
73 { | |
74 metainit_t metainit={0,0,0,0}; | |
75 metaopen_t metaopen; | |
76 int i, handle; | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
77 struct cdrom_subchnl info; |
724 | 78 |
79 Metainit(&metainit); | |
80 if (metainit.version == NULL) { | |
81 #ifdef DEBUG_CDROM | |
82 fprintf(stderr, "MetaDOS not installed\n"); | |
83 #endif | |
84 return -1; | |
85 } | |
86 | |
87 if (metainit.drives_map == 0) { | |
88 #ifdef DEBUG_CDROM | |
89 fprintf(stderr, "No MetaDOS devices present\n"); | |
90 #endif | |
91 return -1; | |
92 } | |
93 | |
94 SDL_numcds = 0; | |
95 | |
96 for (i='A'; i<='Z'; i++) { | |
97 metados_drives[SDL_numcds].device[0] = 0; | |
98 metados_drives[SDL_numcds].device[1] = ':'; | |
99 metados_drives[SDL_numcds].device[2] = 0; | |
100 | |
101 if (metainit.drives_map & (1<<(i-'A'))) { | |
102 handle = Metaopen(i, &metaopen); | |
103 if (handle == 0) { | |
104 | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
105 info.cdsc_format = CDROM_MSF; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
106 if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) { |
724 | 107 metados_drives[SDL_numcds].device[0] = i; |
108 ++SDL_numcds; | |
109 } | |
110 | |
111 Metaclose(i); | |
112 } | |
113 } | |
114 } | |
115 | |
116 /* Fill in our driver capabilities */ | |
117 SDL_CDcaps.Name = SDL_SYS_CDName; | |
118 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
119 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
120 | |
121 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
122 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
123 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
124 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
125 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
126 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
127 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
128 | |
129 return 0; | |
130 } | |
131 | |
132 void SDL_SYS_CDQuit(void) | |
133 { | |
134 SDL_numcds = 0; | |
135 } | |
136 | |
137 static const char *SDL_SYS_CDName(int drive) | |
138 { | |
139 return(metados_drives[drive].device); | |
140 } | |
141 | |
142 static int SDL_SYS_CDOpen(int drive) | |
143 { | |
144 int handle; | |
145 | |
146 handle = Metaopen(metados_drives[drive].device[0], &(metados_drives[drive].metaopen)); | |
147 if (handle == 0) { | |
148 return drive; | |
149 } | |
150 | |
151 return -1; | |
152 } | |
153 | |
154 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
155 { | |
156 Metaclose(metados_drives[cdrom->id].device[0]); | |
157 } | |
158 | |
159 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
160 { | |
161 int retval; | |
162 | |
163 retval = Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, arg); | |
164 if ( retval < 0 ) { | |
165 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
166 } | |
167 return(retval); | |
168 } | |
169 | |
170 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
171 { | |
172 int i,okay; | |
173 struct cdrom_tochdr toc; | |
174 struct cdrom_tocentry entry; | |
175 | |
176 /* Use standard ioctl() */ | |
177 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) { | |
178 return -1; | |
179 } | |
180 | |
181 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; | |
182 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
183 cdrom->numtracks = SDL_MAX_TRACKS; | |
184 } | |
185 | |
186 /* Read all the track TOC entries */ | |
187 okay=1; | |
188 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
189 if ( i == cdrom->numtracks ) { | |
190 cdrom->track[i].id = CDROM_LEADOUT; | |
191 } else { | |
192 cdrom->track[i].id = toc.cdth_trk0+i; | |
193 } | |
194 entry.cdte_track = cdrom->track[i].id; | |
195 entry.cdte_format = CDROM_MSF; | |
196 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0 ) { | |
197 okay=0; | |
198 break; | |
199 } else { | |
200 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { | |
201 cdrom->track[i].type = SDL_DATA_TRACK; | |
202 } else { | |
203 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
204 } | |
205 cdrom->track[i].offset = MSF_TO_FRAMES( | |
206 entry.cdte_addr.msf.minute, | |
207 entry.cdte_addr.msf.second, | |
208 entry.cdte_addr.msf.frame); | |
209 cdrom->track[i].length = 0; | |
210 if ( i > 0 ) { | |
211 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset; | |
212 } | |
213 } | |
214 } | |
215 | |
216 return(okay ? 0 : -1); | |
217 } | |
218 | |
219 /* Get CD-ROM status */ | |
220 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
221 { | |
222 CDstatus status; | |
223 struct cdrom_tochdr toc; | |
224 struct cdrom_subchnl info; | |
225 | |
226 info.cdsc_format = CDROM_MSF; | |
227 if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
228 if ( ERRNO_TRAYEMPTY(errno) ) { |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
229 status = CD_TRAYEMPTY; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
230 } else { |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
231 status = CD_ERROR; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
232 } |
724 | 233 } else { |
234 switch (info.cdsc_audiostatus) { | |
235 case CDROM_AUDIO_INVALID: | |
236 case CDROM_AUDIO_NO_STATUS: | |
237 /* Try to determine if there's a CD available */ | |
238 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) { | |
239 status = CD_STOPPED; | |
240 } else { | |
241 status = CD_TRAYEMPTY; | |
242 } | |
243 break; | |
244 case CDROM_AUDIO_COMPLETED: | |
245 status = CD_STOPPED; | |
246 break; | |
247 case CDROM_AUDIO_PLAY: | |
248 status = CD_PLAYING; | |
249 break; | |
250 case CDROM_AUDIO_PAUSED: | |
251 /* Workaround buggy CD-ROM drive */ | |
252 if ( info.cdsc_trk == CDROM_LEADOUT ) { | |
253 status = CD_STOPPED; | |
254 } else { | |
255 status = CD_PAUSED; | |
256 } | |
257 break; | |
258 default: | |
259 status = CD_ERROR; | |
260 break; | |
261 } | |
262 } | |
263 if ( position ) { | |
264 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
265 *position = MSF_TO_FRAMES( | |
266 info.cdsc_absaddr.msf.minute, | |
267 info.cdsc_absaddr.msf.second, | |
268 info.cdsc_absaddr.msf.frame); | |
269 } else { | |
270 *position = 0; | |
271 } | |
272 } | |
273 return(status); | |
274 } | |
275 | |
276 /* Start play */ | |
277 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
278 { | |
279 struct cdrom_msf playtime; | |
280 | |
281 FRAMES_TO_MSF(start, | |
282 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
283 FRAMES_TO_MSF(start+length, | |
284 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
285 #ifdef DEBUG_CDROM | |
286 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
287 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
288 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
289 #endif | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
290 |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
291 return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime); |
724 | 292 } |
293 | |
294 /* Pause play */ | |
295 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
296 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
297 return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0); |
724 | 298 } |
299 | |
300 /* Resume play */ | |
301 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
302 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
303 return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0); |
724 | 304 } |
305 | |
306 /* Stop play */ | |
307 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
308 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
309 return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0); |
724 | 310 } |
311 | |
312 /* Eject the CD-ROM */ | |
313 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
314 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
315 return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0); |
724 | 316 } |