Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
d4926497
Commit
d4926497
authored
Feb 02, 1999
by
Eric Pouech
Committed by
Alexandre Julliard
Feb 02, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed tracks indexing in mcicda.c
Make use of new Wine internal CD ROM interface.
parent
a3e27393
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
238 additions
and
630 deletions
+238
-630
mcicda.c
multimedia/mcicda.c
+238
-630
No files found.
multimedia/mcicda.c
View file @
d4926497
...
...
@@ -2,48 +2,17 @@
/*
* Sample MCI CDAUDIO Wine Driver for Linux
*
* Copyright 1994 Martin Ayotte
* Copyright 1994 Martin Ayotte
* Copyright 1998-99 Eric Pouech
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "windows.h"
#include "wine/winuser16.h"
#include "user.h"
#include "driver.h"
#include "multimedia.h"
#include "debug.h"
#include "cdrom.h"
#ifdef HAVE_LINUX_CDROM_H
# include <linux/cdrom.h>
#endif
#ifdef HAVE_LINUX_UCDROM_H
# include <linux/ucdrom.h>
#endif
#ifdef HAVE_SYS_CDIO_H
# include <sys/cdio.h>
#endif
#if defined(__NetBSD__)
# define CDAUDIO_DEV "/dev/rcd0d"
#elif defined(__FreeBSD__)
# define CDAUDIO_DEV "/dev/rcd0c"
#else
# define CDAUDIO_DEV "/dev/cdrom"
#endif
#define MAX_CDAUDIODRV (1)
#define MAX_CDAUDIO_TRACKS 256
#define CDFRAMES_PERSEC 75
#define CDFRAMES_PERMIN 4500
#define SECONDS_PERMIN 60
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
typedef
struct
{
int
nUseCount
;
/* Incremented for each shared open */
BOOL16
fShareable
;
/* TRUE if first open was shareable */
...
...
@@ -51,199 +20,77 @@ typedef struct {
HANDLE16
hCallback
;
/* Callback handle for pending notification */
MCI_OPEN_PARMS16
openParms
;
DWORD
dwTimeFormat
;
int
unixdev
;
#ifdef linux
struct
cdrom_subchnl
sc
;
#else
struct
cd_sub_channel_info
sc
;
#endif
int
cdMode
;
WINE_CDAUDIO
wcda
;
int
mciMode
;
UINT16
nCurTrack
;
DWORD
dwCurFrame
;
UINT16
nTracks
;
DWORD
dwTotalLen
;
LPDWORD
lpdwTrackLen
;
LPDWORD
lpdwTrackPos
;
LPBYTE
lpbTrackFlags
;
DWORD
dwFirstOffset
;
}
WINE_CDAUDIO
;
}
WINE_MCICDAUDIO
;
static
WINE_CDAUDIO
CDADev
[
MAX_CDAUDIODRV
];
#endif
#ifndef CDROM_DATA_TRACK
#define CDROM_DATA_TRACK 0x04
#endif
#define MAX_CDAUDIODRV (1)
static
WINE_MCICDAUDIO
CDADev
[
MAX_CDAUDIODRV
];
/*-----------------------------------------------------------------------*/
/**************************************************************************
* CDAUDIO_mciGetOpenDrv [internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
WINE_CDAUDIO
*
CDAUDIO_mciGetOpenDrv
(
UINT16
wDevID
)
static
WINE_MCICDAUDIO
*
CDAUDIO_mciGetOpenDrv
(
UINT16
wDevID
)
{
if
(
wDevID
>=
MAX_CDAUDIODRV
||
CDADev
[
wDevID
].
nUseCount
==
0
||
CDADev
[
wDevID
].
unixdev
=
=
0
)
{
CDADev
[
wDevID
].
wcda
.
unixdev
<
=
0
)
{
WARN
(
cdaudio
,
"Invalid wDevID=%u
\n
"
,
wDevID
);
return
0
;
}
return
&
CDADev
[
wDevID
];
}
#endif
/**************************************************************************
* CDAUDIO_
GetNumberOfTracks
[internal]
* CDAUDIO_
mciMode
[internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
UINT16
CDAUDIO_GetNumberOfTracks
(
WINE_CDAUDIO
*
wcda
)
static
int
CDAUDIO_mciMode
(
int
wcdaMode
)
{
#ifdef linux
struct
cdrom_tochdr
hdr
;
#else
struct
ioc_toc_header
hdr
;
#endif
if
(
wcda
->
nTracks
==
0
)
{
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMREADTOCHDR
,
&
hdr
))
{
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOREADTOCHEADER
,
&
hdr
))
{
#endif
WARN
(
cdaudio
,
"(%p) -- Error occured (%d)!
\n
"
,
wcda
,
errno
);
return
(
WORD
)
-
1
;
}
#ifdef linux
wcda
->
nTracks
=
hdr
.
cdth_trk1
;
#else
wcda
->
nTracks
=
hdr
.
ending_track
-
hdr
.
starting_track
+
1
;
#endif
switch
(
wcdaMode
)
{
case
WINE_CDA_DONTKNOW
:
return
MCI_MODE_STOP
;
case
WINE_CDA_NOTREADY
:
return
MCI_MODE_STOP
;
case
WINE_CDA_OPEN
:
return
MCI_MODE_OPEN
;
case
WINE_CDA_PLAY
:
return
MCI_MODE_PLAY
;
case
WINE_CDA_STOP
:
return
MCI_MODE_STOP
;
case
WINE_CDA_PAUSE
:
return
MCI_MODE_PAUSE
;
default:
FIXME
(
cdaudio
,
"Unknown mode %04x
\n
"
,
wcdaMode
);
}
return
wcda
->
nTracks
;
return
MCI_MODE_STOP
;
}
#endif
/**************************************************************************
* CDAUDIO_
GetTracksInfo
[internal]
* CDAUDIO_
mciGetError
[internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
BOOL32
CDAUDIO_GetTracksInfo
(
WINE_CDAUDIO
*
wcda
)
static
int
CDAUDIO_mciGetError
(
WINE_MCICDAUDIO
*
wmcda
)
{
int
i
,
length
;
int
start
,
last_start
=
0
;
int
total_length
=
0
;
#ifdef linux
struct
cdrom_tocentry
entry
;
#else
struct
ioc_read_toc_entry
entry
;
struct
cd_toc_entry
toc_buffer
;
#endif
if
(
wcda
->
nTracks
==
0
)
{
if
(
CDAUDIO_GetNumberOfTracks
(
wcda
)
==
(
WORD
)
-
1
)
return
FALSE
;
}
TRACE
(
cdaudio
,
"nTracks=%u
\n
"
,
wcda
->
nTracks
);
if
(
wcda
->
lpdwTrackLen
!=
NULL
)
free
(
wcda
->
lpdwTrackLen
);
wcda
->
lpdwTrackLen
=
(
LPDWORD
)
malloc
((
wcda
->
nTracks
+
1
)
*
sizeof
(
DWORD
));
if
(
wcda
->
lpdwTrackPos
!=
NULL
)
free
(
wcda
->
lpdwTrackPos
);
wcda
->
lpdwTrackPos
=
(
LPDWORD
)
malloc
((
wcda
->
nTracks
+
1
)
*
sizeof
(
DWORD
));
if
(
wcda
->
lpbTrackFlags
!=
NULL
)
free
(
wcda
->
lpbTrackFlags
);
wcda
->
lpbTrackFlags
=
(
LPBYTE
)
malloc
((
wcda
->
nTracks
+
1
)
*
sizeof
(
BYTE
));
if
(
wcda
->
lpdwTrackLen
==
NULL
||
wcda
->
lpdwTrackPos
==
NULL
||
wcda
->
lpbTrackFlags
==
NULL
)
{
WARN
(
cdaudio
,
"error allocating track table !
\n
"
);
return
FALSE
;
}
memset
(
wcda
->
lpdwTrackLen
,
0
,
(
wcda
->
nTracks
+
1
)
*
sizeof
(
DWORD
));
memset
(
wcda
->
lpdwTrackPos
,
0
,
(
wcda
->
nTracks
+
1
)
*
sizeof
(
DWORD
));
memset
(
wcda
->
lpbTrackFlags
,
0
,
(
wcda
->
nTracks
+
1
)
*
sizeof
(
BYTE
));
for
(
i
=
0
;
i
<=
wcda
->
nTracks
;
i
++
)
{
if
(
i
==
wcda
->
nTracks
)
#ifdef linux
entry
.
cdte_track
=
CDROM_LEADOUT
;
#else
#define LEADOUT 0xaa
entry
.
starting_track
=
LEADOUT
;
/* XXX */
#endif
else
#ifdef linux
entry
.
cdte_track
=
i
+
1
;
#else
entry
.
starting_track
=
i
+
1
;
#endif
#ifdef linux
entry
.
cdte_format
=
CDROM_MSF
;
#else
bzero
((
char
*
)
&
toc_buffer
,
sizeof
(
toc_buffer
));
entry
.
address_format
=
CD_MSF_FORMAT
;
entry
.
data_len
=
sizeof
(
toc_buffer
);
entry
.
data
=
&
toc_buffer
;
#endif
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMREADTOCENTRY
,
&
entry
))
{
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOREADTOCENTRYS
,
&
entry
))
{
#endif
WARN
(
cdaudio
,
"error read entry (%d)
\n
"
,
errno
);
return
FALSE
;
}
#ifdef linux
start
=
CDFRAMES_PERSEC
*
(
SECONDS_PERMIN
*
entry
.
cdte_addr
.
msf
.
minute
+
entry
.
cdte_addr
.
msf
.
second
)
+
entry
.
cdte_addr
.
msf
.
frame
;
#else
start
=
CDFRAMES_PERSEC
*
(
SECONDS_PERMIN
*
toc_buffer
.
addr
.
msf
.
minute
+
toc_buffer
.
addr
.
msf
.
second
)
+
toc_buffer
.
addr
.
msf
.
frame
;
#endif
if
(
i
==
0
)
{
last_start
=
start
;
wcda
->
dwFirstOffset
=
start
;
TRACE
(
cdaudio
,
"dwFirstOffset=%u
\n
"
,
start
);
}
else
{
length
=
start
-
last_start
;
last_start
=
start
;
start
=
last_start
-
length
;
total_length
+=
length
;
wcda
->
lpdwTrackLen
[
i
-
1
]
=
length
;
wcda
->
lpdwTrackPos
[
i
-
1
]
=
start
;
TRACE
(
cdaudio
,
"track #%u start=%u len=%u
\n
"
,
i
,
start
,
length
);
}
#ifdef linux
wcda
->
lpbTrackFlags
[
i
]
=
(
entry
.
cdte_adr
<<
4
)
|
(
entry
.
cdte_ctrl
&
0x0f
);
#else
wcda
->
lpbTrackFlags
[
i
]
=
(
toc_buffer
.
addr_type
<<
4
)
|
(
toc_buffer
.
control
&
0x0f
);
#endif
TRACE
(
cdaudio
,
"track #%u flags=%02x
\n
"
,
i
+
1
,
wcda
->
lpbTrackFlags
[
i
]);
switch
(
wmcda
->
wcda
.
cdaMode
)
{
case
WINE_CDA_DONTKNOW
:
case
WINE_CDA_NOTREADY
:
return
MCIERR_DEVICE_NOT_READY
;
case
WINE_CDA_OPEN
:
return
MCIERR_DEVICE_OPEN
;
case
WINE_CDA_PLAY
:
case
WINE_CDA_STOP
:
case
WINE_CDA_PAUSE
:
break
;
default:
FIXME
(
cdaudio
,
"Unknown mode %04x
\n
"
,
wmcda
->
wcda
.
cdaMode
);
}
wcda
->
dwTotalLen
=
total_length
;
TRACE
(
cdaudio
,
"total_len=%u
\n
"
,
total_length
);
return
TRUE
;
return
MCIERR_DRIVER_INTERNAL
;
}
#endif
/**************************************************************************
>>>>>>> 1.9
* CDAUDIO_CalcFrame [internal]
* CDAUDIO_CalcFrame [internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
DWORD
CDAUDIO_CalcFrame
(
WINE_CDAUDIO
*
wcda
,
DWORD
dwTime
)
static
DWORD
CDAUDIO_CalcFrame
(
WINE_MCICDAUDIO
*
wmcda
,
DWORD
dwTime
)
{
DWORD
dwFrame
=
0
;
UINT16
wTrack
;
TRACE
(
cdaudio
,
"(%p, %08lX, %lu);
\n
"
,
w
cda
,
w
cda
->
dwTimeFormat
,
dwTime
);
TRACE
(
cdaudio
,
"(%p, %08lX, %lu);
\n
"
,
w
mcda
,
wm
cda
->
dwTimeFormat
,
dwTime
);
switch
(
wcda
->
dwTimeFormat
)
{
switch
(
w
m
cda
->
dwTimeFormat
)
{
case
MCI_FORMAT_MILLISECONDS
:
dwFrame
=
dwTime
*
CDFRAMES_PERSEC
/
1000
;
dwFrame
=
(
dwTime
*
CDFRAMES_PERSEC
)
/
1000
;
TRACE
(
cdaudio
,
"MILLISECONDS %lu
\n
"
,
dwFrame
);
break
;
case
MCI_FORMAT_MSF
:
...
...
@@ -261,8 +108,8 @@ static DWORD CDAUDIO_CalcFrame(WINE_CDAUDIO* wcda, DWORD dwTime)
MCI_TMSF_TRACK
(
dwTime
),
MCI_TMSF_MINUTE
(
dwTime
),
MCI_TMSF_SECOND
(
dwTime
),
MCI_TMSF_FRAME
(
dwTime
));
TRACE
(
cdaudio
,
"TMSF trackpos[%u]=%lu
\n
"
,
wTrack
,
w
cda
->
lpdwTrackPos
[
wTrack
-
1
]);
dwFrame
=
w
cda
->
lpdwTrackPos
[
wTrack
-
1
];
wTrack
,
w
mcda
->
wcda
.
lpdwTrackPos
[
wTrack
-
1
]);
dwFrame
=
w
mcda
->
wcda
.
lpdwTrackPos
[
wTrack
-
1
];
dwFrame
+=
CDFRAMES_PERMIN
*
MCI_TMSF_MINUTE
(
dwTime
);
dwFrame
+=
CDFRAMES_PERSEC
*
MCI_TMSF_SECOND
(
dwTime
);
dwFrame
+=
MCI_TMSF_FRAME
(
dwTime
);
...
...
@@ -270,125 +117,11 @@ static DWORD CDAUDIO_CalcFrame(WINE_CDAUDIO* wcda, DWORD dwTime)
}
return
dwFrame
;
}
#endif
/**************************************************************************
* CDAUDIO_GetCDStatus [internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
BOOL32
CDAUDIO_GetCDStatus
(
WINE_CDAUDIO
*
wcda
)
{
int
oldmode
=
wcda
->
cdMode
;
#ifdef linux
wcda
->
sc
.
cdsc_format
=
CDROM_MSF
;
#else
struct
ioc_read_subchannel
read_sc
;
read_sc
.
address_format
=
CD_MSF_FORMAT
;
read_sc
.
data_format
=
CD_CURRENT_POSITION
;
read_sc
.
track
=
0
;
read_sc
.
data_len
=
sizeof
(
wcda
->
sc
);
read_sc
.
data
=
(
struct
cd_sub_channel_info
*
)
&
wcda
->
sc
;
#endif
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMSUBCHNL
,
&
wcda
->
sc
))
{
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCREADSUBCHANNEL
,
&
read_sc
))
{
#endif
TRACE
(
cdaudio
,
"opened or no_media (%d)!
\n
"
,
errno
);
wcda
->
cdMode
=
MCI_MODE_OPEN
;
/* was NOT_READY */
return
TRUE
;
}
switch
(
#ifdef linux
wcda
->
sc
.
cdsc_audiostatus
#else
wcda
->
sc
.
header
.
audio_status
#endif
)
{
#ifdef linux
case
CDROM_AUDIO_INVALID
:
#else
case
CD_AS_AUDIO_INVALID
:
#endif
WARN
(
cdaudio
,
"device doesn't support status, using MCI status.
\n
"
);
wcda
->
cdMode
=
0
;
break
;
#ifdef linux
case
CDROM_AUDIO_NO_STATUS
:
#else
case
CD_AS_NO_STATUS
:
#endif
wcda
->
cdMode
=
MCI_MODE_STOP
;
TRACE
(
cdaudio
,
"MCI_MODE_STOP !
\n
"
);
break
;
#ifdef linux
case
CDROM_AUDIO_PLAY
:
#else
case
CD_AS_PLAY_IN_PROGRESS
:
#endif
wcda
->
cdMode
=
MCI_MODE_PLAY
;
TRACE
(
cdaudio
,
"MCI_MODE_PLAY !
\n
"
);
break
;
#ifdef linux
case
CDROM_AUDIO_PAUSED
:
#else
case
CD_AS_PLAY_PAUSED
:
#endif
wcda
->
cdMode
=
MCI_MODE_PAUSE
;
TRACE
(
cdaudio
,
"MCI_MODE_PAUSE !
\n
"
);
break
;
default:
#ifdef linux
TRACE
(
cdaudio
,
"status=%02X !
\n
"
,
wcda
->
sc
.
cdsc_audiostatus
);
#else
TRACE
(
cdaudio
,
"status=%02X !
\n
"
,
wcda
->
sc
.
header
.
audio_status
);
#endif
}
#ifdef linux
wcda
->
nCurTrack
=
wcda
->
sc
.
cdsc_trk
;
wcda
->
dwCurFrame
=
CDFRAMES_PERMIN
*
wcda
->
sc
.
cdsc_absaddr
.
msf
.
minute
+
CDFRAMES_PERSEC
*
wcda
->
sc
.
cdsc_absaddr
.
msf
.
second
+
wcda
->
sc
.
cdsc_absaddr
.
msf
.
frame
;
#else
wcda
->
nCurTrack
=
wcda
->
sc
.
what
.
position
.
track_number
;
wcda
->
dwCurFrame
=
CDFRAMES_PERMIN
*
wcda
->
sc
.
what
.
position
.
absaddr
.
msf
.
minute
+
CDFRAMES_PERSEC
*
wcda
->
sc
.
what
.
position
.
absaddr
.
msf
.
second
+
wcda
->
sc
.
what
.
position
.
absaddr
.
msf
.
frame
;
#endif
#ifdef linux
TRACE
(
cdaudio
,
"%02u-%02u:%02u:%02u
\n
"
,
wcda
->
sc
.
cdsc_trk
,
wcda
->
sc
.
cdsc_absaddr
.
msf
.
minute
,
wcda
->
sc
.
cdsc_absaddr
.
msf
.
second
,
wcda
->
sc
.
cdsc_absaddr
.
msf
.
frame
);
#else
TRACE
(
cdaudio
,
"%02u-%02u:%02u:%02u
\n
"
,
wcda
->
sc
.
what
.
position
.
track_number
,
wcda
->
sc
.
what
.
position
.
absaddr
.
msf
.
minute
,
wcda
->
sc
.
what
.
position
.
absaddr
.
msf
.
second
,
wcda
->
sc
.
what
.
position
.
absaddr
.
msf
.
frame
);
#endif
if
(
oldmode
!=
wcda
->
cdMode
&&
oldmode
==
MCI_MODE_OPEN
)
{
if
(
!
CDAUDIO_GetTracksInfo
(
wcda
))
{
WARN
(
cdaudio
,
"error updating TracksInfo !
\n
"
);
return
FALSE
;
}
}
return
TRUE
;
}
#endif
/**************************************************************************
*
CDAUDIO_CalcTime [internal]
* CDAUDIO_CalcTime [internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
DWORD
CDAUDIO_CalcTime
(
WINE_CDAUDIO
*
wcda
,
DWORD
dwFrame
)
static
DWORD
CDAUDIO_CalcTime
(
WINE_MCICDAUDIO
*
wmcda
,
DWORD
dwFrame
)
{
DWORD
dwTime
=
0
;
UINT16
wTrack
;
...
...
@@ -396,11 +129,11 @@ static DWORD CDAUDIO_CalcTime(WINE_CDAUDIO* wcda, DWORD dwFrame)
UINT16
wSeconds
;
UINT16
wFrames
;
TRACE
(
cdaudio
,
"(%p, %08lX, %lu);
\n
"
,
w
cda
,
w
cda
->
dwTimeFormat
,
dwFrame
);
TRACE
(
cdaudio
,
"(%p, %08lX, %lu);
\n
"
,
w
mcda
,
wm
cda
->
dwTimeFormat
,
dwFrame
);
switch
(
wcda
->
dwTimeFormat
)
{
switch
(
w
m
cda
->
dwTimeFormat
)
{
case
MCI_FORMAT_MILLISECONDS
:
dwTime
=
dwFrame
/
CDFRAMES_PERSEC
*
1000
;
dwTime
=
(
dwFrame
*
1000
)
/
CDFRAMES_PERSEC
;
TRACE
(
cdaudio
,
"MILLISECONDS %lu
\n
"
,
dwTime
);
break
;
case
MCI_FORMAT_MSF
:
...
...
@@ -413,11 +146,11 @@ static DWORD CDAUDIO_CalcTime(WINE_CDAUDIO* wcda, DWORD dwFrame)
case
MCI_FORMAT_TMSF
:
default:
/* unknown format ! force TMSF ! ... */
for
(
wTrack
=
0
;
wTrack
<
w
cda
->
nTracks
;
wTrack
++
)
{
/* dwTime += wcda->lpdwTrackLen[wTrack - 1];
for
(
wTrack
=
0
;
wTrack
<
w
mcda
->
wcda
.
nTracks
;
wTrack
++
)
{
/* dwTime += w
m
cda->lpdwTrackLen[wTrack - 1];
TRACE(cdaudio, "Adding trk#%u curpos=%u \n", dwTime);
if (dwTime >= dwFrame) break; */
if
(
w
cda
->
lpdwTrackPos
[
wTrack
-
1
]
>=
dwFrame
)
break
;
if
(
w
mcda
->
wcda
.
lpdwTrackPos
[
wTrack
-
1
]
>=
dwFrame
)
break
;
}
wMinutes
=
dwFrame
/
CDFRAMES_PERMIN
;
wSeconds
=
(
dwFrame
-
CDFRAMES_PERMIN
*
wMinutes
)
/
CDFRAMES_PERSEC
;
...
...
@@ -428,7 +161,6 @@ static DWORD CDAUDIO_CalcTime(WINE_CDAUDIO* wcda, DWORD dwFrame)
}
return
dwTime
;
}
#endif
static
DWORD
CDAUDIO_mciSeek
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_SEEK_PARMS
lpParms
);
static
DWORD
CDAUDIO_mciStop
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_GENERIC_PARMS
lpParms
);
...
...
@@ -438,9 +170,8 @@ static DWORD CDAUDIO_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS l
*/
static
DWORD
CDAUDIO_mciOpen
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_OPEN_PARMS32A
lpOpenParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
DWORD
dwDeviceID
;
WINE_
CDAUDIO
*
w
cda
;
WINE_
MCICDAUDIO
*
wm
cda
;
MCI_SEEK_PARMS
seekParms
;
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpOpenParms
);
...
...
@@ -450,50 +181,40 @@ static DWORD CDAUDIO_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS32A l
dwDeviceID
=
lpOpenParms
->
wDeviceID
;
wcda
=
&
CDADev
[
wDevID
];
w
m
cda
=
&
CDADev
[
wDevID
];
if
(
wcda
->
nUseCount
>
0
)
{
/* The driver already open on this channel */
if
(
w
m
cda
->
nUseCount
>
0
)
{
/* The driver
is
already open on this channel */
/* If the driver was opened shareable before and this open specifies */
/* shareable then increment the use count */
if
(
wcda
->
fShareable
&&
(
dwFlags
&
MCI_OPEN_SHAREABLE
))
++
wcda
->
nUseCount
;
if
(
w
m
cda
->
fShareable
&&
(
dwFlags
&
MCI_OPEN_SHAREABLE
))
++
w
m
cda
->
nUseCount
;
else
return
MCIERR_MUST_USE_SHAREABLE
;
}
else
{
wcda
->
nUseCount
=
1
;
wcda
->
fShareable
=
dwFlags
&
MCI_OPEN_SHAREABLE
;
w
m
cda
->
nUseCount
=
1
;
w
m
cda
->
fShareable
=
dwFlags
&
MCI_OPEN_SHAREABLE
;
}
if
(
dwFlags
&
MCI_OPEN_ELEMENT
)
{
TRACE
(
cdaudio
,
"MCI_OPEN_ELEMENT !
\n
"
);
/* return MCIERR_NO_ELEMENT_ALLOWED; */
}
wcda
->
openParms
.
dwCallback
=
lpOpenParms
->
dwCallback
;
wcda
->
openParms
.
wDeviceID
=
(
WORD
)
lpOpenParms
->
wDeviceID
;
wcda
->
openParms
.
wReserved0
=
0
;
/*????*/
wcda
->
openParms
.
lpstrDeviceType
=
lpOpenParms
->
lpstrDeviceType
;
wcda
->
openParms
.
lpstrElementName
=
lpOpenParms
->
lpstrElementName
;
wcda
->
openParms
.
lpstrAlias
=
lpOpenParms
->
lpstrAlias
;
w
m
cda
->
openParms
.
dwCallback
=
lpOpenParms
->
dwCallback
;
w
m
cda
->
openParms
.
wDeviceID
=
(
WORD
)
lpOpenParms
->
wDeviceID
;
w
m
cda
->
openParms
.
wReserved0
=
0
;
/*????*/
w
m
cda
->
openParms
.
lpstrDeviceType
=
lpOpenParms
->
lpstrDeviceType
;
w
m
cda
->
openParms
.
lpstrElementName
=
lpOpenParms
->
lpstrElementName
;
w
m
cda
->
openParms
.
lpstrAlias
=
lpOpenParms
->
lpstrAlias
;
wcda
->
wNotifyDeviceID
=
dwDeviceID
;
wcda
->
unixdev
=
open
(
CDAUDIO_DEV
,
O_RDONLY
,
0
);
if
(
wcda
->
unixdev
==
-
1
)
{
WARN
(
cdaudio
,
"can't open '%s'!. errno=%d
\n
"
,
CDAUDIO_DEV
,
errno
);
perror
(
"can't open
\n
"
);
wmcda
->
wNotifyDeviceID
=
dwDeviceID
;
if
(
CDAUDIO_Open
(
&
wmcda
->
wcda
)
==
-
1
)
{
--
wmcda
->
nUseCount
;
return
MCIERR_HARDWARE
;
}
wcda
->
cdMode
=
0
;
wcda
->
mciMode
=
MCI_MODE_STOP
;
wcda
->
dwTimeFormat
=
MCI_FORMAT_TMSF
;
wcda
->
nCurTrack
=
0
;
wcda
->
nTracks
=
0
;
wcda
->
dwTotalLen
=
0
;
wcda
->
dwFirstOffset
=
0
;
wcda
->
lpdwTrackLen
=
NULL
;
wcda
->
lpdwTrackPos
=
NULL
;
wcda
->
lpbTrackFlags
=
NULL
;
if
(
!
CDAUDIO_GetTracksInfo
(
&
CDADev
[
wDevID
]))
{
wmcda
->
mciMode
=
MCI_MODE_STOP
;
wmcda
->
dwTimeFormat
=
MCI_FORMAT_TMSF
;
if
(
!
CDAUDIO_GetTracksInfo
(
&
wmcda
->
wcda
))
{
WARN
(
cdaudio
,
"error reading TracksInfo !
\n
"
);
/* return MCIERR_INTERNAL; */
}
...
...
@@ -501,9 +222,6 @@ static DWORD CDAUDIO_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS32A l
CDAUDIO_mciSeek
(
wDevID
,
MCI_SEEK_TO_START
,
&
seekParms
);
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -511,33 +229,26 @@ static DWORD CDAUDIO_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS32A l
*/
static
DWORD
CDAUDIO_mciClose
(
UINT16
wDevID
,
DWORD
dwParam
,
LPMCI_GENERIC_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwParam
,
lpParms
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
w
m
cda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
wcda
->
nUseCount
==
1
)
{
if
(
w
m
cda
->
nUseCount
==
1
)
{
CDAUDIO_mciStop
(
wDevID
,
0
,
NULL
);
if
(
wcda
->
lpdwTrackLen
!=
NULL
)
free
(
wcda
->
lpdwTrackLen
);
if
(
wcda
->
lpdwTrackPos
!=
NULL
)
free
(
wcda
->
lpdwTrackPos
);
if
(
wcda
->
lpbTrackFlags
!=
NULL
)
free
(
wcda
->
lpbTrackFlags
);
close
(
wcda
->
unixdev
);
CDAUDIO_Close
(
&
wmcda
->
wcda
);
}
wcda
->
nUseCount
--
;
#endif
wmcda
->
nUseCount
--
;
return
0
;
}
/**************************************************************************
* CDAUDIO_mciGetDevCaps [internal]
* CDAUDIO_mciGetDevCaps
[internal]
*/
static
DWORD
CDAUDIO_mciGetDevCaps
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_GETDEVCAPS_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
lpParms
==
NULL
)
return
MCIERR_NULL_PARAMETER_BLOCK
;
...
...
@@ -579,9 +290,6 @@ static DWORD CDAUDIO_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,
}
TRACE
(
cdaudio
,
"lpParms->dwReturn=%08lX;
\n
"
,
lpParms
->
dwReturn
);
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -589,39 +297,35 @@ static DWORD CDAUDIO_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,
*/
static
DWORD
CDAUDIO_mciInfo
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_INFO_PARMS16
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
DWORD
ret
=
0
;
LPSTR
str
=
0
;
WINE_
CDAUDIO
*
w
cda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_
MCICDAUDIO
*
wm
cda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
lpParms
==
NULL
||
lpParms
->
lpstrReturn
==
NULL
)
{
ret
=
MCIERR_NULL_PARAMETER_BLOCK
;
}
else
if
(
wcda
==
NULL
)
{
}
else
if
(
w
m
cda
==
NULL
)
{
ret
=
MCIERR_INVALID_DEVICE_ID
;
}
else
{
TRACE
(
cdaudio
,
"buf=%p, len=%lu
\n
"
,
lpParms
->
lpstrReturn
,
lpParms
->
dwRetSize
);
switch
(
dwFlags
)
{
case
MCI_INFO_PRODUCT
:
switch
(
dwFlags
)
{
case
MCI_INFO_PRODUCT
:
str
=
"Wine's audio CD"
;
break
;
default:
break
;
default:
WARN
(
cdaudio
,
"Don't know this info command (%lu)
\n
"
,
dwFlags
);
ret
=
MCIERR_UNRECOGNIZED_COMMAND
;
}
}
}
if
(
str
)
{
ret
=
MCI_WriteString
(
lpParms
->
lpstrReturn
,
lpParms
->
dwRetSize
,
str
);
}
else
{
lpParms
->
lpstrReturn
[
0
]
=
0
;
}
return
ret
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -629,106 +333,110 @@ static DWORD CDAUDIO_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lp
*/
static
DWORD
CDAUDIO_mciStatus
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_STATUS_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
DWORD
ret
=
0
;
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
lpParms
==
NULL
)
{
ret
=
MCIERR_NULL_PARAMETER_BLOCK
;
}
else
if
(
wcda
==
NULL
)
{
}
else
if
(
w
m
cda
==
NULL
)
{
ret
=
MCIERR_INVALID_DEVICE_ID
;
}
else
{
if
(
dwFlags
&
MCI_NOTIFY
)
{
if
(
dwFlags
&
MCI_NOTIFY
)
{
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
mciDriverNotify16
((
HWND16
)
LOWORD
(
lpParms
->
dwCallback
),
wcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
if
(
dwFlags
&
MCI_STATUS_ITEM
)
{
switch
(
lpParms
->
dwItem
)
{
case
MCI_STATUS_CURRENT_TRACK
:
if
(
!
CDAUDIO_GetCDStatus
(
wcda
))
return
MCIERR_DRIVER_INTERNAL
;
lpParms
->
dwReturn
=
wcda
->
nCurTrack
;
TRACE
(
cdaudio
,
"CURRENT_TRACK=%lu!
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_LENGTH
:
if
(
wcda
->
nTracks
==
0
)
{
if
(
!
CDAUDIO_GetTracksInfo
(
wcda
))
{
WARN
(
cdaudio
,
"error reading TracksInfo !
\n
"
);
return
MCIERR_DRIVER_INTERNAL
;
wmcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
if
(
dwFlags
&
MCI_STATUS_ITEM
)
{
switch
(
lpParms
->
dwItem
)
{
case
MCI_STATUS_CURRENT_TRACK
:
if
(
!
CDAUDIO_GetCDStatus
(
&
wmcda
->
wcda
))
{
return
CDAUDIO_mciGetError
(
wmcda
);
}
}
if
(
dwFlags
&
MCI_TRACK
)
{
lpParms
->
dwReturn
=
wmcda
->
wcda
.
nCurTrack
;
TRACE
(
cdaudio
,
"CURRENT_TRACK=%lu!
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_LENGTH
:
if
(
wmcda
->
wcda
.
nTracks
==
0
)
{
if
(
!
CDAUDIO_GetTracksInfo
(
&
wmcda
->
wcda
))
{
WARN
(
cdaudio
,
"error reading TracksInfo !
\n
"
);
return
CDAUDIO_mciGetError
(
wmcda
);
}
}
if
(
dwFlags
&
MCI_TRACK
)
{
TRACE
(
cdaudio
,
"MCI_TRACK #%lu LENGTH=??? !
\n
"
,
lpParms
->
dwTrack
);
if
(
lpParms
->
dwTrack
>
w
cda
->
nTracks
)
return
MCIERR_OUTOFRANGE
;
lpParms
->
dwReturn
=
w
cda
->
lpdwTrackLen
[
lpParms
->
dwTrack
-
1
];
if
(
lpParms
->
dwTrack
>
w
mcda
->
wcda
.
nTracks
||
lpParms
->
dwTrack
==
0
)
return
MCIERR_OUTOFRANGE
;
lpParms
->
dwReturn
=
w
mcda
->
wcda
.
lpdwTrackLen
[
lpParms
->
dwTrack
-
1
];
}
else
{
lpParms
->
dwReturn
=
wcda
->
dwTotalLen
;
}
lpParms
->
dwReturn
=
CDAUDIO_CalcTime
(
wcda
,
lpParms
->
dwReturn
);
TRACE
(
cdaudio
,
"LENGTH=%lu !
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_MODE
:
if
(
!
CDAUDIO_GetCDStatus
(
wcda
))
return
MCIERR_DRIVER_INTERNAL
;
lpParms
->
dwReturn
=
wcda
->
cdMode
;
if
(
!
lpParms
->
dwReturn
)
lpParms
->
dwReturn
=
wcda
->
mciMode
;
lpParms
->
dwReturn
=
wmcda
->
wcda
.
dwTotalLen
;
}
lpParms
->
dwReturn
=
CDAUDIO_CalcTime
(
wmcda
,
lpParms
->
dwReturn
);
TRACE
(
cdaudio
,
"LENGTH=%lu !
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_MODE
:
if
(
!
CDAUDIO_GetCDStatus
(
&
wmcda
->
wcda
))
return
CDAUDIO_mciGetError
(
wmcda
);
lpParms
->
dwReturn
=
CDAUDIO_mciMode
(
wmcda
->
wcda
.
cdaMode
);
if
(
!
lpParms
->
dwReturn
)
lpParms
->
dwReturn
=
wmcda
->
mciMode
;
TRACE
(
cdaudio
,
"MCI_STATUS_MODE=%08lX !
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_MEDIA_PRESENT
:
if
(
!
CDAUDIO_GetCDStatus
(
wcda
))
return
MCIERR_DRIVER_INTERNAL
;
lpParms
->
dwReturn
=
(
wcda
->
nTracks
>
0
)
?
TRUE
:
FALSE
;
return
0
;
case
MCI_STATUS_MEDIA_PRESENT
:
if
(
!
CDAUDIO_GetCDStatus
(
&
wmcda
->
wcda
))
return
CDAUDIO_mciGetError
(
wmcda
);
lpParms
->
dwReturn
=
(
wmcda
->
wcda
.
nTracks
>
0
)
?
TRUE
:
FALSE
;
TRACE
(
cdaudio
,
"MCI_STATUS_MEDIA_PRESENT =%s!
\n
"
,
lpParms
->
dwReturn
?
"Y"
:
"N"
);
return
0
;
case
MCI_STATUS_NUMBER_OF_TRACKS
:
lpParms
->
dwReturn
=
CDAUDIO_GetNumberOfTracks
(
wcda
);
return
0
;
case
MCI_STATUS_NUMBER_OF_TRACKS
:
lpParms
->
dwReturn
=
CDAUDIO_GetNumberOfTracks
(
&
wmcda
->
wcda
);
TRACE
(
cdaudio
,
"MCI_STATUS_NUMBER_OF_TRACKS = %lu !
\n
"
,
lpParms
->
dwReturn
);
if
(
lpParms
->
dwReturn
==
(
WORD
)
-
1
)
return
MCIERR_DRIVER_INTERNAL
;
return
0
;
case
MCI_STATUS_POSITION
:
if
(
!
CDAUDIO_GetCDStatus
(
wcda
))
return
MCIERR_DRIVER_INTERNAL
;
lpParms
->
dwReturn
=
wcda
->
dwCurFrame
;
if
(
dwFlags
&
MCI_STATUS_START
)
{
lpParms
->
dwReturn
=
wcda
->
dwFirstOffset
;
TRACE
(
cdaudio
,
"get MCI_STATUS_START !
\n
"
);
}
if
(
dwFlags
&
MCI_TRACK
)
{
if
(
lpParms
->
dwTrack
>
wcda
->
nTracks
)
return
MCIERR_OUTOFRANGE
;
lpParms
->
dwReturn
=
wcda
->
lpdwTrackPos
[
lpParms
->
dwTrack
-
1
];
TRACE
(
cdaudio
,
"get MCI_TRACK #%lu !
\n
"
,
lpParms
->
dwTrack
);
}
lpParms
->
dwReturn
=
CDAUDIO_CalcTime
(
wcda
,
lpParms
->
dwReturn
);
if
(
lpParms
->
dwReturn
==
(
WORD
)
-
1
)
return
CDAUDIO_mciGetError
(
wmcda
);
return
0
;
case
MCI_STATUS_POSITION
:
if
(
!
CDAUDIO_GetCDStatus
(
&
wmcda
->
wcda
))
return
CDAUDIO_mciGetError
(
wmcda
);
lpParms
->
dwReturn
=
wmcda
->
wcda
.
dwCurFrame
;
if
(
dwFlags
&
MCI_STATUS_START
)
{
lpParms
->
dwReturn
=
wmcda
->
wcda
.
dwFirstOffset
;
TRACE
(
cdaudio
,
"get MCI_STATUS_START !
\n
"
);
}
if
(
dwFlags
&
MCI_TRACK
)
{
if
(
lpParms
->
dwTrack
>
wmcda
->
wcda
.
nTracks
||
lpParms
->
dwTrack
==
0
)
return
MCIERR_OUTOFRANGE
;
lpParms
->
dwReturn
=
wmcda
->
wcda
.
lpdwTrackPos
[
lpParms
->
dwTrack
-
1
];
TRACE
(
cdaudio
,
"get MCI_TRACK #%lu !
\n
"
,
lpParms
->
dwTrack
);
}
lpParms
->
dwReturn
=
CDAUDIO_CalcTime
(
wmcda
,
lpParms
->
dwReturn
);
TRACE
(
cdaudio
,
"MCI_STATUS_POSITION=%08lX !
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_READY
:
TRACE
(
cdaudio
,
"MCI_STATUS_READY !
\n
"
);
lpParms
->
dwReturn
=
TRUE
;
return
0
;
case
MCI_STATUS_TIME_FORMAT
:
lpParms
->
dwReturn
=
wcda
->
dwTimeFormat
;
return
0
;
case
MCI_STATUS_READY
:
TRACE
(
cdaudio
,
"MCI_STATUS_READY !
\n
"
);
lpParms
->
dwReturn
=
(
wmcda
->
wcda
.
cdaMode
!=
WINE_CDA_DONTKNOW
&&
wmcda
->
wcda
.
cdaMode
!=
WINE_CDA_NOTREADY
);
TRACE
(
cdaudio
,
"MCI_STATUS_READY=%ld!
\n
"
,
lpParms
->
dwReturn
);
return
0
;
case
MCI_STATUS_TIME_FORMAT
:
lpParms
->
dwReturn
=
wmcda
->
dwTimeFormat
;
TRACE
(
cdaudio
,
"MCI_STATUS_TIME_FORMAT =%08lx!
\n
"
,
lpParms
->
dwReturn
);
return
0
;
/* FIXME: the constant used here are not defined in mmsystem.h */
/* MCI_CDA_STATUS_TYPE_TRACK is very likely to be 0x00004001 */
case
MCI_CDA_STATUS_TYPE_TRACK
:
if
(
!
(
dwFlags
&
MCI_TRACK
))
return
MCIERR_MISSING_PARAMETER
;
lpParms
->
dwReturn
=
(
wcda
->
lpbTrackFlags
[
lpParms
->
dwTrack
-
1
]
&
CDROM_DATA_TRACK
)
?
MCI_CDA_TRACK_OTHER
:
MCI_CDA_TRACK_AUDIO
;
if
(
!
(
dwFlags
&
MCI_TRACK
))
return
MCIERR_MISSING_PARAMETER
;
if
(
lpParms
->
dwTrack
>
wmcda
->
wcda
.
nTracks
||
lpParms
->
dwTrack
==
0
)
return
MCIERR_OUTOFRANGE
;
lpParms
->
dwReturn
=
(
wmcda
->
wcda
.
lpbTrackFlags
[
lpParms
->
dwTrack
-
1
]
&
CDROM_DATA_TRACK
)
?
MCI_CDA_TRACK_OTHER
:
MCI_CDA_TRACK_AUDIO
;
TRACE
(
cdaudio
,
"MCI_CDA_STATUS_TYPE_TRACK[%ld]=%08lx
\n
"
,
lpParms
->
dwTrack
,
lpParms
->
dwReturn
);
return
0
;
default:
WARN
(
cdaudio
,
"unknown command %08lX !
\n
"
,
lpParms
->
dwItem
);
return
MCIERR_UNRECOGNIZED_COMMAND
;
return
0
;
default:
WARN
(
cdaudio
,
"unknown command %08lX !
\n
"
,
lpParms
->
dwItem
);
return
MCIERR_UNRECOGNIZED_COMMAND
;
}
}
}
}
WARN
(
cdaudio
,
"not MCI_STATUS_ITEM !
\n
"
);
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -736,97 +444,50 @@ static DWORD CDAUDIO_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS
*/
static
DWORD
CDAUDIO_mciPlay
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_PLAY_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int
start
,
end
;
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
int
start
,
end
;
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
DWORD
ret
=
0
;
#ifdef linux
struct
cdrom_msf
msf
;
#else
struct
ioc_play_msf
msf
;
#endif
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
lpParms
==
NULL
)
{
ret
=
MCIERR_NULL_PARAMETER_BLOCK
;
}
else
if
(
wcda
==
NULL
)
{
}
else
if
(
w
m
cda
==
NULL
)
{
ret
=
MCIERR_INVALID_DEVICE_ID
;
}
else
{
if
(
w
cda
->
nTracks
==
0
)
{
if
(
!
CDAUDIO_GetTracksInfo
(
wcda
))
{
if
(
w
mcda
->
wcda
.
nTracks
==
0
)
{
if
(
!
CDAUDIO_GetTracksInfo
(
&
wmcda
->
wcda
))
{
WARN
(
cdaudio
,
"error reading TracksInfo !
\n
"
);
return
MCIERR_DRIVER_INTERNAL
;
}
}
end
=
w
cda
->
dwTotalLen
;
w
cda
->
nCurTrack
=
1
;
if
(
dwFlags
&
MCI_FROM
)
{
start
=
CDAUDIO_CalcFrame
(
wcda
,
lpParms
->
dwFrom
);
end
=
w
mcda
->
wcda
.
dwTotalLen
;
w
mcda
->
wcda
.
nCurTrack
=
1
;
if
(
dwFlags
&
MCI_FROM
)
{
start
=
CDAUDIO_CalcFrame
(
w
m
cda
,
lpParms
->
dwFrom
);
TRACE
(
cdaudio
,
"MCI_FROM=%08lX -> %u
\n
"
,
lpParms
->
dwFrom
,
start
);
}
else
{
if
(
!
CDAUDIO_GetCDStatus
(
wcda
))
return
MCIERR_DRIVER_INTERNAL
;
start
=
w
cda
->
dwCurFrame
;
}
if
(
dwFlags
&
MCI_TO
)
{
end
=
CDAUDIO_CalcFrame
(
wcda
,
lpParms
->
dwTo
);
if
(
!
CDAUDIO_GetCDStatus
(
&
wmcda
->
wcda
))
return
MCIERR_DRIVER_INTERNAL
;
start
=
w
mcda
->
wcda
.
dwCurFrame
;
}
if
(
dwFlags
&
MCI_TO
)
{
end
=
CDAUDIO_CalcFrame
(
w
m
cda
,
lpParms
->
dwTo
);
TRACE
(
cdaudio
,
"MCI_TO=%08lX -> %u
\n
"
,
lpParms
->
dwTo
,
end
);
}
end
+=
wcda
->
dwFirstOffset
;
#ifdef linux
msf
.
cdmsf_min0
=
start
/
CDFRAMES_PERMIN
;
msf
.
cdmsf_sec0
=
(
start
%
CDFRAMES_PERMIN
)
/
CDFRAMES_PERSEC
;
msf
.
cdmsf_frame0
=
start
%
CDFRAMES_PERSEC
;
msf
.
cdmsf_min1
=
end
/
CDFRAMES_PERMIN
;
msf
.
cdmsf_sec1
=
(
end
%
CDFRAMES_PERMIN
)
/
CDFRAMES_PERSEC
;
msf
.
cdmsf_frame1
=
end
%
CDFRAMES_PERSEC
;
#else
msf
.
start_m
=
start
/
CDFRAMES_PERMIN
;
msf
.
start_s
=
(
start
%
CDFRAMES_PERMIN
)
/
CDFRAMES_PERSEC
;
msf
.
start_f
=
start
%
CDFRAMES_PERSEC
;
msf
.
end_m
=
end
/
CDFRAMES_PERMIN
;
msf
.
end_s
=
(
end
%
CDFRAMES_PERMIN
)
/
CDFRAMES_PERSEC
;
msf
.
end_f
=
end
%
CDFRAMES_PERSEC
;
#endif
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMSTART
))
{
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCSTART
,
NULL
))
{
#endif
WARN
(
cdaudio
,
"motor doesn't start !
\n
"
);
return
MCIERR_HARDWARE
;
}
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMPLAYMSF
,
&
msf
))
{
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCPLAYMSF
,
&
msf
))
{
#endif
WARN
(
cdaudio
,
"device doesn't play !
\n
"
);
return
MCIERR_HARDWARE
;
}
#ifdef linux
TRACE
(
cdaudio
,
"msf = %d:%d:%d %d:%d:%d
\n
"
,
msf
.
cdmsf_min0
,
msf
.
cdmsf_sec0
,
msf
.
cdmsf_frame0
,
msf
.
cdmsf_min1
,
msf
.
cdmsf_sec1
,
msf
.
cdmsf_frame1
);
#else
TRACE
(
cdaudio
,
"msf = %d:%d:%d %d:%d:%d
\n
"
,
msf
.
start_m
,
msf
.
start_s
,
msf
.
start_f
,
msf
.
end_m
,
msf
.
end_s
,
msf
.
end_f
);
#endif
wcda
->
mciMode
=
MCI_MODE_PLAY
;
if
(
dwFlags
&
MCI_NOTIFY
)
{
}
end
+=
wmcda
->
wcda
.
dwFirstOffset
;
if
(
CDAUDIO_Play
(
&
wmcda
->
wcda
,
start
,
end
)
==
-
1
)
return
MCIERR_HARDWARE
;
wmcda
->
mciMode
=
MCI_MODE_PLAY
;
if
(
dwFlags
&
MCI_NOTIFY
)
{
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
/*
mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
wcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
*/
}
/*
mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
w
m
cda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
*/
}
}
return
ret
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -834,29 +495,21 @@ static DWORD CDAUDIO_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpPa
*/
static
DWORD
CDAUDIO_mciStop
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_GENERIC_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMSTOP
))
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCSTOP
,
NULL
))
#endif
if
(
wmcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
CDAUDIO_Stop
(
&
wmcda
->
wcda
)
==
-
1
)
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_STOP
;
w
m
cda
->
mciMode
=
MCI_MODE_STOP
;
if
(
lpParms
&&
(
dwFlags
&
MCI_NOTIFY
))
{
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
mciDriverNotify16
((
HWND16
)
LOWORD
(
lpParms
->
dwCallback
),
wcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
w
m
cda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -864,29 +517,21 @@ static DWORD CDAUDIO_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS l
*/
static
DWORD
CDAUDIO_mciPause
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_GENERIC_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMPAUSE
))
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCPAUSE
,
NULL
))
#endif
if
(
wmcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
CDAUDIO_Pause
(
&
wmcda
->
wcda
,
1
)
==
-
1
)
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_PAUSE
;
w
m
cda
->
mciMode
=
MCI_MODE_PAUSE
;
if
(
lpParms
&&
(
dwFlags
&
MCI_NOTIFY
))
{
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
mciDriverNotify16
((
HWND16
)
LOWORD
(
lpParms
->
dwCallback
),
wcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
w
m
cda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
...
...
@@ -894,48 +539,39 @@ static DWORD CDAUDIO_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS
*/
static
DWORD
CDAUDIO_mciResume
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_GENERIC_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
#ifdef linux
if
(
ioctl
(
wcda
->
unixdev
,
CDROMRESUME
))
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCRESUME
,
NULL
))
#endif
if
(
wmcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
CDAUDIO_Pause
(
&
wmcda
->
wcda
,
0
)
==
-
1
)
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_STOP
;
w
m
cda
->
mciMode
=
MCI_MODE_STOP
;
if
(
lpParms
&&
(
dwFlags
&
MCI_NOTIFY
))
{
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
mciDriverNotify16
((
HWND16
)
LOWORD
(
lpParms
->
dwCallback
),
wcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
w
m
cda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
* CDAUDIO_mciSeek [internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
DWORD
CDAUDIO_mciSeek
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_SEEK_PARMS
lpParms
)
{
DWORD
dwRet
;
MCI_PLAY_PARMS
playParms
;
WINE_
CDAUDIO
*
w
cda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_
MCICDAUDIO
*
wm
cda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
w
m
cda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
lpParms
==
NULL
)
return
MCIERR_NULL_PARAMETER_BLOCK
;
wcda
->
mciMode
=
MCI_MODE_SEEK
;
w
m
cda
->
mciMode
=
MCI_MODE_SEEK
;
switch
(
dwFlags
&
~
(
MCI_NOTIFY
|
MCI_WAIT
))
{
case
MCI_SEEK_TO_START
:
TRACE
(
cdaudio
,
"Seeking to start
\n
"
);
...
...
@@ -943,7 +579,7 @@ static DWORD CDAUDIO_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpPa
break
;
case
MCI_SEEK_TO_END
:
TRACE
(
cdaudio
,
"Seeking to end
\n
"
);
playParms
.
dwFrom
=
w
cda
->
dwTotalLen
;
playParms
.
dwFrom
=
w
mcda
->
wcda
.
dwTotalLen
;
break
;
case
MCI_TO
:
TRACE
(
cdaudio
,
"Seeking to %lu
\n
"
,
lpParms
->
dwTo
);
...
...
@@ -959,59 +595,38 @@ static DWORD CDAUDIO_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpPa
if
(
dwFlags
&
MCI_NOTIFY
)
{
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
mciDriverNotify16
((
HWND16
)
LOWORD
(
lpParms
->
dwCallback
),
wcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
w
m
cda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
return
dwRet
;
}
#endif
/**************************************************************************
* CDAUDIO_mciSetDoor [internal]
*/
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
static
DWORD
CDAUDIO_mciSetDoor
(
UINT16
wDevID
,
int
open
)
{
WINE_
CDAUDIO
*
w
cda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_
MCICDAUDIO
*
wm
cda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04x, %s) !
\n
"
,
wDevID
,
(
open
)
?
"OPEN"
:
"CLOSE"
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
#ifdef linux
if
(
open
)
{
if
(
ioctl
(
wcda
->
unixdev
,
CDROMEJECT
))
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_OPEN
;
}
else
{
if
(
ioctl
(
wcda
->
unixdev
,
CDROMEJECT
,
1
))
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_STOP
;
}
#else
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCALLOW
,
NULL
))
return
MCIERR_HARDWARE
;
if
(
open
)
{
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCEJECT
,
NULL
))
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_OPEN
;
}
else
{
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCCLOSE
,
NULL
))
return
MCIERR_HARDWARE
;
wcda
->
mciMode
=
MCI_MODE_STOP
;
}
if
(
ioctl
(
wcda
->
unixdev
,
CDIOCPREVENT
,
NULL
))
return
MCIERR_HARDWARE
;
#endif
wcda
->
nTracks
=
0
;
if
(
wmcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
CDAUDIO_SetDoor
(
&
wmcda
->
wcda
,
open
)
==
-
1
)
return
MCIERR_HARDWARE
;
wmcda
->
mciMode
=
(
open
)
?
MCI_MODE_OPEN
:
MCI_MODE_STOP
;
return
0
;
}
#endif
/**************************************************************************
* CDAUDIO_mciSet [internal]
*/
static
DWORD
CDAUDIO_mciSet
(
UINT16
wDevID
,
DWORD
dwFlags
,
LPMCI_SET_PARMS
lpParms
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
WINE_CDAUDIO
*
wcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
WINE_MCICDAUDIO
*
wmcda
=
CDAUDIO_mciGetOpenDrv
(
wDevID
);
TRACE
(
cdaudio
,
"(%04X, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
wcda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
w
m
cda
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
lpParms
==
NULL
)
return
MCIERR_NULL_PARAMETER_BLOCK
;;
/*
TRACE(cdaudio,"dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
...
...
@@ -1032,7 +647,7 @@ static DWORD CDAUDIO_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParm
WARN
(
cdaudio
,
"bad time format !
\n
"
);
return
MCIERR_BAD_TIME_FORMAT
;
}
wcda
->
dwTimeFormat
=
lpParms
->
dwTimeFormat
;
w
m
cda
->
dwTimeFormat
=
lpParms
->
dwTimeFormat
;
}
if
(
dwFlags
&
MCI_SET_DOOR_OPEN
)
{
CDAUDIO_mciSetDoor
(
wDevID
,
TRUE
);
...
...
@@ -1047,21 +662,17 @@ static DWORD CDAUDIO_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParm
TRACE
(
cdaudio
,
"MCI_NOTIFY_SUCCESSFUL %08lX !
\n
"
,
lpParms
->
dwCallback
);
mciDriverNotify16
((
HWND16
)
LOWORD
(
lpParms
->
dwCallback
),
wcda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
w
m
cda
->
wNotifyDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
return
0
;
#else
return
MCIERR_HARDWARE
;
#endif
}
/**************************************************************************
* MCICDAUDIO_DriverProc32 [sample driver]
*/
LONG
MCICDAUDIO_DriverProc32
(
DWORD
dwDevID
,
HDRVR16
hDriv
,
DWORD
wMsg
,
DWORD
dwParam1
,
DWORD
dwParam2
)
DWORD
dwParam1
,
DWORD
dwParam2
)
{
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
switch
(
wMsg
)
{
case
DRV_LOAD
:
return
1
;
case
DRV_FREE
:
return
1
;
...
...
@@ -1070,10 +681,10 @@ LONG MCICDAUDIO_DriverProc32(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
case
DRV_ENABLE
:
return
1
;
case
DRV_DISABLE
:
return
1
;
case
DRV_QUERYCONFIGURE
:
return
1
;
case
DRV_CONFIGURE
:
MessageBox
16
(
0
,
"Sample MultiM
edia Linux Driver !"
,
"MMLinux Driver"
,
MB_OK
);
return
1
;
case
DRV_CONFIGURE
:
MessageBox
32A
(
0
,
"Sample Multim
edia Linux Driver !"
,
"MMLinux Driver"
,
MB_OK
);
return
1
;
case
DRV_INSTALL
:
return
DRVCNF_RESTART
;
case
DRV_REMOVE
:
return
DRVCNF_RESTART
;
case
MCI_OPEN_DRIVER
:
return
CDAUDIO_mciOpen
(
dwDevID
,
dwParam1
,
(
LPMCI_OPEN_PARMS32A
)
dwParam2
);
case
MCI_CLOSE_DRIVER
:
return
CDAUDIO_mciClose
(
dwDevID
,
dwParam1
,
(
LPMCI_GENERIC_PARMS
)
dwParam2
);
case
MCI_GETDEVCAPS
:
return
CDAUDIO_mciGetDevCaps
(
dwDevID
,
dwParam1
,
(
LPMCI_GETDEVCAPS_PARMS
)
dwParam2
);
...
...
@@ -1085,7 +696,7 @@ LONG MCICDAUDIO_DriverProc32(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
case
MCI_PAUSE
:
return
CDAUDIO_mciPause
(
dwDevID
,
dwParam1
,
(
LPMCI_GENERIC_PARMS
)
dwParam2
);
case
MCI_RESUME
:
return
CDAUDIO_mciResume
(
dwDevID
,
dwParam1
,
(
LPMCI_GENERIC_PARMS
)
dwParam2
);
case
MCI_SEEK
:
return
CDAUDIO_mciSeek
(
dwDevID
,
dwParam1
,
(
LPMCI_SEEK_PARMS
)
dwParam2
);
/* FIXME: I wonder if those two next items are really called ? */
/* FIXME: I wonder if those two next items are really called ? */
case
MCI_SET_DOOR_OPEN
:
return
CDAUDIO_mciSetDoor
(
dwDevID
,
TRUE
);
case
MCI_SET_DOOR_CLOSED
:
return
CDAUDIO_mciSetDoor
(
dwDevID
,
FALSE
);
case
MCI_LOAD
:
...
...
@@ -1115,9 +726,6 @@ LONG MCICDAUDIO_DriverProc32(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
return
DefDriverProc32
(
dwDevID
,
hDriv
,
wMsg
,
dwParam1
,
dwParam2
);
}
return
MCIERR_UNRECOGNIZED_COMMAND
;
#else
return
MCIERR_UNRECOGNIZED_COMMAND
;
#endif
}
/*-----------------------------------------------------------------------*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment