2 * Sample MCI CDAUDIO Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
7 static char Copyright
[] = "Copyright Martin Ayotte, 1994";
20 #include <sys/ioctl.h>
21 #include <linux/soundcard.h>
22 #include <linux/cdrom.h>
24 #define SOUND_DEV "/dev/dsp"
25 #define CDAUDIO_DEV "/dev/sbpcd"
28 #define IOCTL(a,b,c) ioctl(a,b,&c)
30 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
33 #define MAX_CDAUDIODRV 2
34 #define MAX_CDAUDIO_TRACKS 256
36 #define CDFRAMES_PERSEC 75
37 #define CDFRAMES_PERMIN 4500
38 #define SECONDS_PERMIN 60
41 int nUseCount
; /* Incremented for each shared open */
42 BOOL fShareable
; /* TRUE if first open was shareable */
43 WORD wNotifyDeviceID
; /* MCI device ID with a pending notification */
44 HANDLE hCallback
; /* Callback handle for pending notification */
45 MCI_OPEN_PARMS openParms
;
48 struct cdrom_subchnl sc
;
59 static LINUX_CDAUDIO CDADev
[MAX_CDAUDIODRV
];
61 UINT
CDAUDIO_GetNumberOfTracks(UINT wDevID
);
62 BOOL
CDAUDIO_GetTracksInfo(UINT wDevID
);
63 BOOL
CDAUDIO_GetCDStatus(UINT wDevID
);
64 DWORD
CDAUDIO_CalcTime(UINT wDevID
, DWORD dwFormatType
, DWORD dwFrame
);
67 /*-----------------------------------------------------------------------*/
70 /**************************************************************************
71 * CDAUDIO_mciOpen [internal]
73 DWORD
CDAUDIO_mciOpen(DWORD dwFlags
, LPMCI_OPEN_PARMS lpParms
)
78 printf("CDAUDIO_mciOpen(%08X, %08X);\n", dwFlags
, lpParms
);
80 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
81 wDevID
= lpParms
->wDeviceID
;
82 if (CDADev
[wDevID
].nUseCount
> 0) {
83 /* The driver already open on this channel */
84 /* If the driver was% op, ened shareable before and this open specifies */
85 /* shareable then increment the use count */
86 if (CDADev
[wDevID
].fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
87 ++CDADev
[wDevID
].nUseCount
;
89 return MCIERR_MUST_USE_SHAREABLE
;
92 CDADev
[wDevID
].nUseCount
= 1;
93 CDADev
[wDevID
].fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
95 if (dwFlags
& MCI_OPEN_ELEMENT
) {
96 printf("CDAUDIO_mciOpen // MCI_OPEN_ELEMENT !\n");
97 /* return MCIERR_NO_ELEMENT_ALLOWED; */
99 memcpy(&CDADev
[wDevID
].openParms
, lpParms
, sizeof(MCI_OPEN_PARMS
));
100 CDADev
[wDevID
].wNotifyDeviceID
= lpParms
->wDeviceID
;
101 CDADev
[wDevID
].unixdev
= open (CDAUDIO_DEV
, O_RDONLY
, 0);
102 if (CDADev
[wDevID
].unixdev
== -1) {
103 printf("CDAUDIO_mciOpen // can't open '%s' !\n", CDAUDIO_DEV
);
104 return MCIERR_HARDWARE
;
106 CDADev
[wDevID
].mode
= 0;
107 CDADev
[wDevID
].dwTimeFormat
= MCI_FORMAT_TMSF
;
108 CDADev
[wDevID
].nCurTrack
= 0;
109 CDADev
[wDevID
].nTracks
= 0;
110 CDADev
[wDevID
].dwTotalLen
= 0;
111 CDADev
[wDevID
].dwFirstOffset
= 0;
112 CDADev
[wDevID
].lpdwTrackLen
= NULL
;
113 CDADev
[wDevID
].lpdwTrackPos
= NULL
;
114 if (!CDAUDIO_GetTracksInfo(wDevID
)) {
115 printf("CDAUDIO_mciOpen // error reading TracksInfo !\n");
116 /* return MCIERR_INTERNAL; */
118 if (dwFlags
& MCI_NOTIFY
) {
119 printf("CDAUDIO_mciOpen // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
120 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
121 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
126 /**************************************************************************
127 * CDAUDIO_mciClose [internal]
129 DWORD
CDAUDIO_mciClose(UINT wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
132 printf("CDAUDIO_mciClose(%u, %08X, %08X);\n", wDevID
, dwParam
, lpParms
);
134 if (CDADev
[wDevID
].lpdwTrackLen
!= NULL
) free(CDADev
[wDevID
].lpdwTrackLen
);
135 if (CDADev
[wDevID
].lpdwTrackPos
!= NULL
) free(CDADev
[wDevID
].lpdwTrackPos
);
136 close(CDADev
[wDevID
].unixdev
);
139 /**************************************************************************
140 * CDAUDIO_mciGetDevCaps [internal]
142 DWORD
CDAUDIO_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
,
143 LPMCI_GETDEVCAPS_PARMS lpParms
)
146 printf("CDAUDIO_mciGetDevCaps(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
148 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
149 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
150 printf("CDAUDIO_mciGetDevCaps // MCI_GETDEVCAPS_ITEM dwItem=%08X);\n",
152 switch(lpParms
->dwItem
) {
153 case MCI_GETDEVCAPS_CAN_RECORD
:
154 lpParms
->dwReturn
= FALSE
;
156 case MCI_GETDEVCAPS_HAS_AUDIO
:
157 lpParms
->dwReturn
= TRUE
;
159 case MCI_GETDEVCAPS_HAS_VIDEO
:
160 lpParms
->dwReturn
= FALSE
;
162 case MCI_GETDEVCAPS_DEVICE_TYPE
:
163 lpParms
->dwReturn
= MCI_DEVTYPE_CD_AUDIO
;
165 case MCI_GETDEVCAPS_USES_FILES
:
166 lpParms
->dwReturn
= FALSE
;
168 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
169 lpParms
->dwReturn
= FALSE
;
171 case MCI_GETDEVCAPS_CAN_EJECT
:
172 lpParms
->dwReturn
= TRUE
;
174 case MCI_GETDEVCAPS_CAN_PLAY
:
175 lpParms
->dwReturn
= TRUE
;
177 case MCI_GETDEVCAPS_CAN_SAVE
:
178 lpParms
->dwReturn
= FALSE
;
181 return MCIERR_UNRECOGNIZED_COMMAND
;
184 printf("CDAUDIO_mciGetDevCaps // lpParms->dwReturn=%08X);\n", lpParms
->dwReturn
);
188 /**************************************************************************
189 * CDAUDIO_mciInfo [internal]
191 DWORD
CDAUDIO_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
)
194 printf("CDAUDIO_mciInfo(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
196 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
197 lpParms
->lpstrReturn
= NULL
;
199 case MCI_INFO_PRODUCT
:
200 lpParms
->lpstrReturn
= "Linux CDROM 0.5";
203 return MCIERR_UNRECOGNIZED_COMMAND
;
205 if (lpParms
->lpstrReturn
!= NULL
)
206 lpParms
->dwRetSize
= strlen(lpParms
->lpstrReturn
);
208 lpParms
->dwRetSize
= 0;
212 /**************************************************************************
213 * CDAUDIO_mciStatus [internal]
215 DWORD
CDAUDIO_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
218 printf("CDAUDIO_mciStatus(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
220 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
221 if (CDADev
[wDevID
].unixdev
== 0) return MMSYSERR_NOTENABLED
;
222 if (dwFlags
& MCI_NOTIFY
) {
224 printf("CDAUDIO_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
226 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
227 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
229 if (dwFlags
& MCI_STATUS_ITEM
) {
230 switch(lpParms
->dwItem
) {
231 case MCI_STATUS_CURRENT_TRACK
:
232 if (!CDAUDIO_GetCDStatus(wDevID
)) return MCIERR_INTERNAL
;
233 lpParms
->dwReturn
= CDADev
[wDevID
].nCurTrack
;
235 printf("CDAUDIO_mciStatus // CURRENT_TRACK=%u!\n", lpParms
->dwReturn
);
238 case MCI_STATUS_LENGTH
:
239 if (CDADev
[wDevID
].nTracks
== 0) {
240 if (!CDAUDIO_GetTracksInfo(wDevID
)) {
241 printf("CDAUDIO_mciStatus // error reading TracksInfo !\n");
242 return MCIERR_INTERNAL
;
245 if (dwFlags
& MCI_TRACK
) {
246 printf("CDAUDIO_mciStatus // MCI_TRACK #%u LENGTH=??? !\n",
248 if (lpParms
->dwTrack
> CDADev
[wDevID
].nTracks
)
249 return MCIERR_OUTOFRANGE
;
250 lpParms
->dwReturn
= CDADev
[wDevID
].lpdwTrackLen
[lpParms
->dwTrack
];
253 lpParms
->dwReturn
= CDADev
[wDevID
].dwTotalLen
;
254 lpParms
->dwReturn
= CDAUDIO_CalcTime(wDevID
,
255 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwReturn
);
256 printf("CDAUDIO_mciStatus // LENGTH=%u !\n", lpParms
->dwReturn
);
258 case MCI_STATUS_MODE
:
259 if (!CDAUDIO_GetCDStatus(wDevID
)) return MCIERR_INTERNAL
;
260 lpParms
->dwReturn
= CDADev
[wDevID
].mode
;
262 printf("CDAUDIO_mciStatus // MCI_STATUS_MODE=%08X !\n",
266 case MCI_STATUS_MEDIA_PRESENT
:
267 lpParms
->dwReturn
= (CDADev
[wDevID
].nTracks
> 0) ? TRUE
: FALSE
;
268 if (lpParms
->dwReturn
== FALSE
)
269 printf("CDAUDIO_mciStatus // MEDIA_NOT_PRESENT !\n");
271 printf("CDAUDIO_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
273 case MCI_STATUS_NUMBER_OF_TRACKS
:
274 lpParms
->dwReturn
= CDAUDIO_GetNumberOfTracks(wDevID
);
275 printf("CDAUDIO_mciStatus // MCI_STATUS_NUMBER_OF_TRACKS = %u !\n",
277 if (lpParms
->dwReturn
== (WORD
)-1) return MCIERR_INTERNAL
;
279 case MCI_STATUS_POSITION
:
280 if (!CDAUDIO_GetCDStatus(wDevID
)) return MCIERR_INTERNAL
;
281 lpParms
->dwReturn
= CDADev
[wDevID
].dwCurFrame
;
282 if (dwFlags
& MCI_STATUS_START
) {
283 lpParms
->dwReturn
= CDADev
[wDevID
].dwFirstOffset
;
285 printf("CDAUDIO_mciStatus // get MCI_STATUS_START !\n");
288 if (dwFlags
& MCI_TRACK
) {
289 if (lpParms
->dwTrack
> CDADev
[wDevID
].nTracks
)
290 return MCIERR_OUTOFRANGE
;
291 lpParms
->dwReturn
= CDADev
[wDevID
].lpdwTrackPos
[lpParms
->dwTrack
- 1];
293 printf("CDAUDIO_mciStatus // get MCI_TRACK #%u !\n", lpParms
->dwTrack
);
296 lpParms
->dwReturn
= CDAUDIO_CalcTime(wDevID
,
297 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwReturn
);
299 printf("CDAUDIO_mciStatus // MCI_STATUS_POSITION=%08X !\n",
303 case MCI_STATUS_READY
:
304 printf("CDAUDIO_mciStatus // MCI_STATUS_READY !\n");
305 lpParms
->dwReturn
= TRUE
;
307 case MCI_STATUS_TIME_FORMAT
:
308 printf("CDAUDIO_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
309 lpParms
->dwReturn
= MCI_FORMAT_MILLISECONDS
;
312 printf("CDAUDIO_mciStatus // unknowm command %04X !\n", lpParms
->dwItem
);
313 return MCIERR_UNRECOGNIZED_COMMAND
;
316 printf("CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
321 /**************************************************************************
322 * CDAUDIO_CalcTime [internal]
324 DWORD
CDAUDIO_CalcTime(UINT wDevID
, DWORD dwFormatType
, DWORD dwFrame
)
332 printf("CDAUDIO_CalcTime(%u, %08X, %lu);\n", wDevID
, dwFormatType
, dwFrame
);
335 switch (dwFormatType
) {
336 case MCI_FORMAT_MILLISECONDS
:
337 dwTime
= dwFrame
/ CDFRAMES_PERSEC
* 1000;
339 printf("CDAUDIO_CalcTime // MILLISECONDS %u\n", dwTime
);
343 wMinutes
= dwFrame
/ CDFRAMES_PERMIN
;
344 wSeconds
= (dwFrame
- CDFRAMES_PERMIN
* wMinutes
) / CDFRAMES_PERSEC
;
345 wFrames
= dwFrame
- CDFRAMES_PERMIN
* wMinutes
-
346 CDFRAMES_PERSEC
* wSeconds
;
347 dwTime
= MCI_MAKE_MSF(wMinutes
, wSeconds
, wFrames
);
349 printf("CDAUDIO_CalcTime // MSF %02u:%02u:%02u -> dwTime=%u\n",
350 wMinutes
, wSeconds
, wFrames
, dwTime
);
353 case MCI_FORMAT_TMSF
:
354 for (wTrack
= 0; wTrack
< CDADev
[wDevID
].nTracks
; wTrack
++) {
355 /* dwTime += CDADev[wDevID].lpdwTrackLen[wTrack - 1];
356 printf("Adding trk#%u curpos=%u \n", dwTime);
357 if (dwTime >= dwFrame) break; */
358 if (CDADev
[wDevID
].lpdwTrackPos
[wTrack
- 1] >= dwFrame
) break;
360 wMinutes
= dwFrame
/ CDFRAMES_PERMIN
;
361 wSeconds
= (dwFrame
- CDFRAMES_PERMIN
* wMinutes
) / CDFRAMES_PERSEC
;
362 wFrames
= dwFrame
- CDFRAMES_PERMIN
* wMinutes
-
363 CDFRAMES_PERSEC
* wSeconds
;
364 dwTime
= MCI_MAKE_TMSF(wTrack
, wMinutes
, wSeconds
, wFrames
);
366 printf("CDAUDIO_CalcTime // %02u-%02u:%02u:%02u\n",
367 wTrack
, wMinutes
, wSeconds
, wFrames
);
371 /* unknown format ! force TMSF ! ... */
372 dwFormatType
= MCI_FORMAT_TMSF
;
379 /**************************************************************************
380 * CDAUDIO_CalcFrame [internal]
382 DWORD
CDAUDIO_CalcFrame(UINT wDevID
, DWORD dwFormatType
, DWORD dwTime
)
387 printf("CDAUDIO_CalcFrame(%u, %08X, %lu);\n", wDevID
, dwFormatType
, dwTime
);
390 switch (dwFormatType
) {
391 case MCI_FORMAT_MILLISECONDS
:
392 dwFrame
= dwTime
* CDFRAMES_PERSEC
/ 1000;
394 printf("CDAUDIO_CalcFrame // MILLISECONDS %u\n", dwFrame
);
399 printf("CDAUDIO_CalcFrame // MSF %02u:%02u:%02u\n",
400 MCI_MSF_MINUTE(dwTime
), MCI_MSF_SECOND(dwTime
),
401 MCI_MSF_FRAME(dwTime
));
403 dwFrame
+= CDFRAMES_PERMIN
* MCI_MSF_MINUTE(dwTime
);
404 dwFrame
+= CDFRAMES_PERSEC
* MCI_MSF_SECOND(dwTime
);
405 dwFrame
+= MCI_MSF_FRAME(dwTime
);
407 case MCI_FORMAT_TMSF
:
408 wTrack
= MCI_TMSF_TRACK(dwTime
);
410 printf("CDAUDIO_CalcFrame // TMSF %02u-%02u:%02u:%02u\n",
411 MCI_TMSF_TRACK(dwTime
), MCI_TMSF_MINUTE(dwTime
),
412 MCI_TMSF_SECOND(dwTime
), MCI_TMSF_FRAME(dwTime
));
413 printf("CDAUDIO_CalcFrame // TMSF trackpos[%u]=%u\n",
414 wTrack
, CDADev
[wDevID
].lpdwTrackPos
[wTrack
- 1]);
416 dwFrame
= CDADev
[wDevID
].lpdwTrackPos
[wTrack
- 1];
417 dwFrame
+= CDFRAMES_PERMIN
* MCI_TMSF_MINUTE(dwTime
);
418 dwFrame
+= CDFRAMES_PERSEC
* MCI_TMSF_SECOND(dwTime
);
419 dwFrame
+= MCI_TMSF_FRAME(dwTime
);
422 /* unknown format ! force TMSF ! ... */
423 dwFormatType
= MCI_FORMAT_TMSF
;
430 /**************************************************************************
431 * CDAUDIO_GetNumberOfTracks [internal]
433 UINT
CDAUDIO_GetNumberOfTracks(UINT wDevID
)
435 struct cdrom_tochdr hdr
;
436 if (CDADev
[wDevID
].nTracks
== 0) {
437 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMREADTOCHDR
, &hdr
)) {
438 printf("GetNumberOfTracks(%u) // Error occured !\n", wDevID
);
441 CDADev
[wDevID
].nTracks
= hdr
.cdth_trk1
;
443 return CDADev
[wDevID
].nTracks
;
446 /**************************************************************************
447 * CDAUDIO_GetNumberOfTracks [internal]
449 BOOL
CDAUDIO_GetTracksInfo(UINT wDevID
)
452 int start
, last_start
;
453 int total_length
= 0;
454 struct cdrom_tocentry entry
;
455 if (CDADev
[wDevID
].nTracks
== 0) {
456 if (CDAUDIO_GetNumberOfTracks(wDevID
) == (WORD
)-1) return FALSE
;
458 if (CDADev
[wDevID
].lpdwTrackLen
!= NULL
)
459 free(CDADev
[wDevID
].lpdwTrackLen
);
460 CDADev
[wDevID
].lpdwTrackLen
= (LPDWORD
)malloc(
461 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
462 if (CDADev
[wDevID
].lpdwTrackPos
!= NULL
)
463 free(CDADev
[wDevID
].lpdwTrackPos
);
464 CDADev
[wDevID
].lpdwTrackPos
= (LPDWORD
)malloc(
465 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
466 if (CDADev
[wDevID
].lpdwTrackLen
== NULL
||
467 CDADev
[wDevID
].lpdwTrackPos
== NULL
) {
468 printf("CDAUDIO_GetTracksInfo // error allocating track table !\n");
471 memset(CDADev
[wDevID
].lpdwTrackLen
, 0,
472 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
473 memset(CDADev
[wDevID
].lpdwTrackPos
, 0,
474 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
475 for (i
= 0; i
<= CDADev
[wDevID
].nTracks
; i
++) {
476 if (i
== CDADev
[wDevID
].nTracks
)
477 entry
.cdte_track
= CDROM_LEADOUT
;
479 entry
.cdte_track
= i
+ 1;
480 entry
.cdte_format
= CDROM_MSF
;
481 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMREADTOCENTRY
, &entry
)) {
482 printf("CDAUDIO_GetTracksInfo // error read entry\n");
485 start
= CDFRAMES_PERSEC
* (SECONDS_PERMIN
*
486 entry
.cdte_addr
.msf
.minute
+ entry
.cdte_addr
.msf
.second
) +
487 entry
.cdte_addr
.msf
.frame
;
489 CDADev
[wDevID
].dwFirstOffset
= last_start
= start
;
490 printf("CDAUDIO_GetTracksInfo // dwFirstOffset=%u\n", start
);
493 length
= start
- last_start
;
495 start
= last_start
- length
;
496 total_length
+= length
;
497 CDADev
[wDevID
].lpdwTrackLen
[i
- 1] = length
;
498 CDADev
[wDevID
].lpdwTrackPos
[i
- 1] = start
;
499 printf("CDAUDIO_GetTracksInfo // track #%u start=%u len=%u\n",
503 CDADev
[wDevID
].dwTotalLen
= total_length
;
504 printf("CDAUDIO_GetTracksInfo // total_len=%u\n", total_length
);
509 /**************************************************************************
510 * CDAUDIO_GetNumberOfTracks [internal]
512 BOOL
CDAUDIO_GetCDStatus(UINT wDevID
)
514 int oldmode
= CDADev
[wDevID
].mode
;
515 CDADev
[wDevID
].sc
.cdsc_format
= CDROM_MSF
;
516 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMSUBCHNL
, &CDADev
[wDevID
].sc
)) {
518 printf("CDAUDIO_GetCDStatus // opened or no_media !\n");
520 CDADev
[wDevID
].mode
= MCI_MODE_OPEN
;
523 switch (CDADev
[wDevID
].sc
.cdsc_audiostatus
) {
524 case CDROM_AUDIO_INVALID
:
525 printf("CDAUDIO_GetCDStatus // device doesn't support status !\n");
527 case CDROM_AUDIO_NO_STATUS
:
528 CDADev
[wDevID
].mode
= MCI_MODE_STOP
;
530 printf("CDAUDIO_GetCDStatus // MCI_MODE_STOP !\n");
533 case CDROM_AUDIO_PLAY
:
534 CDADev
[wDevID
].mode
= MCI_MODE_PLAY
;
536 printf("CDAUDIO_GetCDStatus // MCI_MODE_PLAY !\n");
539 case CDROM_AUDIO_PAUSED
:
540 CDADev
[wDevID
].mode
= MCI_MODE_PAUSE
;
542 printf("CDAUDIO_GetCDStatus // MCI_MODE_PAUSE !\n");
546 printf("CDAUDIO_GetCDStatus // status=%02X !\n",
547 CDADev
[wDevID
].sc
.cdsc_audiostatus
);
549 CDADev
[wDevID
].nCurTrack
= CDADev
[wDevID
].sc
.cdsc_trk
;
550 CDADev
[wDevID
].dwCurFrame
=
551 CDFRAMES_PERMIN
* CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.minute
+
552 CDFRAMES_PERSEC
* CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.second
+
553 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.frame
;
555 printf("CDAUDIO_GetCDStatus // %02u-%02u:%02u:%02u \n",
556 CDADev
[wDevID
].sc
.cdsc_trk
,
557 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.minute
,
558 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.second
,
559 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.frame
);
561 if (oldmode
!= CDADev
[wDevID
].mode
&& oldmode
== MCI_MODE_OPEN
) {
562 if (!CDAUDIO_GetTracksInfo(wDevID
)) {
563 printf("CDAUDIO_GetCDStatus // error updating TracksInfo !\n");
564 return MCIERR_INTERNAL
;
570 /**************************************************************************
571 * CDAUDIO_mciPlay [internal]
573 DWORD
CDAUDIO_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
576 struct cdrom_msf msf
;
578 printf("CDAUDIO_mciPlay(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
580 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
581 if (CDADev
[wDevID
].unixdev
== 0) return MMSYSERR_NOTENABLED
;
582 start
= 0; end
= CDADev
[wDevID
].dwTotalLen
;
583 CDADev
[wDevID
].nCurTrack
= 1;
584 if (dwFlags
& MCI_FROM
) {
585 start
= CDAUDIO_CalcFrame(wDevID
,
586 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwFrom
);
588 printf("CDAUDIO_mciPlay // MCI_FROM=%08X -> %u \n",
589 lpParms
->dwFrom
, start
);
592 if (dwFlags
& MCI_TO
) {
593 end
= CDAUDIO_CalcFrame(wDevID
,
594 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwTo
);
596 printf("CDAUDIO_mciPlay // MCI_TO=%08X -> %u \n",
600 start
+= CDADev
[wDevID
].dwFirstOffset
;
601 end
+= CDADev
[wDevID
].dwFirstOffset
;
602 msf
.cdmsf_min0
= start
/ CDFRAMES_PERMIN
;
603 msf
.cdmsf_sec0
= (start
% CDFRAMES_PERMIN
) / CDFRAMES_PERSEC
;
604 msf
.cdmsf_frame0
= start
% CDFRAMES_PERSEC
;
605 msf
.cdmsf_min1
= end
/ CDFRAMES_PERMIN
;
606 msf
.cdmsf_sec1
= (end
% CDFRAMES_PERMIN
) / CDFRAMES_PERSEC
;
607 msf
.cdmsf_frame1
= end
% CDFRAMES_PERSEC
;
608 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMSTART
)) {
609 printf("CDAUDIO_mciPlay // motor doesn't start !\n");
610 return MCIERR_HARDWARE
;
612 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMPLAYMSF
, &msf
)) {
613 printf("CDAUDIO_mciPlay // device doesn't play !\n");
614 return MCIERR_HARDWARE
;
617 printf("CDAUDIO_mciPlay // msf = %d:%d:%d %d:%d:%d\n",
618 msf
.cdmsf_min0
, msf
.cdmsf_sec0
, msf
.cdmsf_frame0
,
619 msf
.cdmsf_min1
, msf
.cdmsf_sec1
, msf
.cdmsf_frame1
);
621 CDADev
[wDevID
].mode
= MCI_MODE_PLAY
;
622 if (dwFlags
& MCI_NOTIFY
) {
623 printf("CDAUDIO_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
624 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
625 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
630 /**************************************************************************
631 * CDAUDIO_mciStop [internal]
633 DWORD
CDAUDIO_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
636 printf("CDAUDIO_mciStop(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
638 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
639 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMSTOP
)) return MCIERR_HARDWARE
;
640 CDADev
[wDevID
].mode
= MCI_MODE_STOP
;
641 if (dwFlags
& MCI_NOTIFY
) {
642 printf("CDAUDIO_mciStop // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
643 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
644 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
649 /**************************************************************************
650 * CDAUDIO_mciPause [internal]
652 DWORD
CDAUDIO_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
655 printf("CDAUDIO_mciPause(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
657 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
658 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMPAUSE
)) return MCIERR_HARDWARE
;
659 CDADev
[wDevID
].mode
= MCI_MODE_PAUSE
;
660 if (dwFlags
& MCI_NOTIFY
) {
661 printf("CDAUDIO_mciPause // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
662 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
663 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
668 /**************************************************************************
669 * CDAUDIO_mciResume [internal]
671 DWORD
CDAUDIO_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
674 printf("CDAUDIO_mciResume(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
676 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
677 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMRESUME
)) return MCIERR_HARDWARE
;
678 CDADev
[wDevID
].mode
= MCI_MODE_STOP
;
679 if (dwFlags
& MCI_NOTIFY
) {
680 printf("CDAUDIO_mciResume // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
681 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
682 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
687 /**************************************************************************
688 * CDAUDIO_mciSeek [internal]
690 DWORD
CDAUDIO_mciSeek(UINT wDevID
, DWORD dwFlags
, LPMCI_SEEK_PARMS lpParms
)
693 MCI_PLAY_PARMS PlayParms
;
695 printf("CDAUDIO_mciSeek(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
697 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
698 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMRESUME
)) return MCIERR_HARDWARE
;
699 CDADev
[wDevID
].mode
= MCI_MODE_SEEK
;
701 case MCI_SEEK_TO_START
:
702 PlayParms
.dwFrom
= 0;
704 case MCI_SEEK_TO_END
:
705 PlayParms
.dwFrom
= CDADev
[wDevID
].dwTotalLen
;
708 PlayParms
.dwFrom
= lpParms
->dwTo
;
711 dwRet
= CDAUDIO_mciPlay(wDevID
, MCI_WAIT
| MCI_FROM
, &PlayParms
);
712 if (dwRet
!= 0) return dwRet
;
713 dwRet
= CDAUDIO_mciStop(wDevID
, MCI_WAIT
, (LPMCI_GENERIC_PARMS
)&PlayParms
);
714 if (dwFlags
& MCI_NOTIFY
) {
715 printf("CDAUDIO_mciSeek // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
716 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
717 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
723 /**************************************************************************
724 * CDAUDIO_mciSet [internal]
726 DWORD
CDAUDIO_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
729 printf("CDAUDIO_mciSet(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
731 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
733 printf("CDAUDIO_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
734 printf("CDAUDIO_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
736 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
737 switch (lpParms
->dwTimeFormat
) {
738 case MCI_FORMAT_MILLISECONDS
:
740 printf("CDAUDIO_mciSet // MCI_FORMAT_MILLISECONDS !\n");
745 printf("CDAUDIO_mciSet // MCI_FORMAT_MSF !\n");
748 case MCI_FORMAT_TMSF
:
750 printf("CDAUDIO_mciSet // MCI_FORMAT_TMSF !\n");
754 printf("CDAUDIO_mciSet // bad time format !\n");
755 return MCIERR_BAD_TIME_FORMAT
;
757 CDADev
[wDevID
].dwTimeFormat
= lpParms
->dwTimeFormat
;
759 if (dwFlags
& MCI_SET_DOOR_OPEN
) {
760 printf("CDAUDIO_mciSet // MCI_SET_DOOR_OPEN !\n");
761 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMEJECT
)) return MCIERR_HARDWARE
;
762 CDADev
[wDevID
].nTracks
= 0;
764 if (dwFlags
& MCI_SET_DOOR_CLOSED
) {
765 printf("CDAUDIO_mciSet // MCI_SET_DOOR_CLOSED !\n");
766 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMEJECT
)) return MCIERR_HARDWARE
;
767 CDADev
[wDevID
].nTracks
= 0;
769 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
770 if (dwFlags
& MCI_SET_ON
) return MCIERR_UNSUPPORTED_FUNCTION
;
771 if (dwFlags
& MCI_SET_OFF
) return MCIERR_UNSUPPORTED_FUNCTION
;
772 if (dwFlags
& MCI_NOTIFY
) {
773 printf("CDAUDIO_mciSet // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
774 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
775 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
781 /**************************************************************************
782 * CDAUDIO_DriverProc [sample driver]
784 LRESULT
CDAUDIO_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
785 DWORD dwParam1
, DWORD dwParam2
)
793 case MCI_OPEN_DRIVER
:
795 return CDAUDIO_mciOpen(dwParam1
, (LPMCI_OPEN_PARMS
)dwParam2
);
797 case MCI_CLOSE_DRIVER
:
799 return CDAUDIO_mciClose(dwDevID
, dwParam1
,
800 (LPMCI_GENERIC_PARMS
)dwParam2
);
805 case DRV_QUERYCONFIGURE
:
808 MessageBox((HWND
)NULL
, "Sample MultiMedia Linux Driver !",
809 "MMLinux Driver", MB_OK
);
812 return (LRESULT
)DRVCNF_RESTART
;
814 return (LRESULT
)DRVCNF_RESTART
;
816 return CDAUDIO_mciGetDevCaps(dwDevID
, dwParam1
,
817 (LPMCI_GETDEVCAPS_PARMS
)dwParam2
);
819 return CDAUDIO_mciInfo(dwDevID
, dwParam1
,
820 (LPMCI_INFO_PARMS
)dwParam2
);
822 return CDAUDIO_mciStatus(dwDevID
, dwParam1
,
823 (LPMCI_STATUS_PARMS
)dwParam2
);
825 return CDAUDIO_mciSet(dwDevID
, dwParam1
,
826 (LPMCI_SET_PARMS
)dwParam2
);
828 return CDAUDIO_mciPlay(dwDevID
, dwParam1
,
829 (LPMCI_PLAY_PARMS
)dwParam2
);
831 return CDAUDIO_mciStop(dwDevID
, dwParam1
,
832 (LPMCI_GENERIC_PARMS
)dwParam2
);
834 return CDAUDIO_mciPause(dwDevID
, dwParam1
,
835 (LPMCI_GENERIC_PARMS
)dwParam2
);
837 return CDAUDIO_mciResume(dwDevID
, dwParam1
,
838 (LPMCI_GENERIC_PARMS
)dwParam2
);
840 return CDAUDIO_mciSeek(dwDevID
, dwParam1
,
841 (LPMCI_SEEK_PARMS
)dwParam2
);
842 case MCI_SET_DOOR_OPEN
:
843 printf("CDAUDIO_DriverProc // MCI_SET_DOOR_OPEN !\n");
844 if (ioctl(CDADev
[dwDevID
].unixdev
, CDROMEJECT
)) return MCIERR_HARDWARE
;
845 CDADev
[dwDevID
].nTracks
= 0;
847 case MCI_SET_DOOR_CLOSED
:
848 printf("CDAUDIO_DriverProc // MCI_SET_DOOR_CLOSED !\n");
849 if (ioctl(CDADev
[dwDevID
].unixdev
, CDROMEJECT
, 1)) return MCIERR_HARDWARE
;
850 CDADev
[dwDevID
].nTracks
= 0;
853 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
858 /*-----------------------------------------------------------------------*/