diff options
author | Tim Champagne <tchamp@users.sourceforge.net> | 2003-05-20 01:23:56 +0000 |
---|---|---|
committer | Tim Champagne <tchamp@users.sourceforge.net> | 2003-05-20 01:23:56 +0000 |
commit | abf8ed42ccb75f06ceefbea9619aa6b1e53a57d7 (patch) | |
tree | dd121df491c853abc9df87152d87f14ffa2b7808 | |
parent | 20215a9d747aa844d8b4cfa3ab9878c901d6a93e (diff) | |
download | xine-lib-abf8ed42ccb75f06ceefbea9619aa6b1e53a57d7.tar.gz xine-lib-abf8ed42ccb75f06ceefbea9619aa6b1e53a57d7.tar.bz2 |
This adds cdda support for Win32. Also fixed the demuxer mpeg block build for Win32. Lastly fixed and issue with launching xineui from a Cygwin shell. There is one small problem known with cdda under Windows and it appears that some songs can start approx 1 second early or late.
CVS patchset: 4880
CVS date: 2003/05/20 01:23:56
-rw-r--r-- | src/demuxers/demux_mpeg_block.c | 6 | ||||
-rw-r--r-- | src/input/input_cdda.c | 848 | ||||
-rw-r--r-- | win32/source/main.cpp | 387 | ||||
-rw-r--r-- | win32/source/resource.aps | bin | 246259 -> 0 bytes |
4 files changed, 933 insertions, 308 deletions
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index c4a33d101..e0384b7b2 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpeg_block.c,v 1.188 2003/05/18 17:41:37 jcdutton Exp $ + * $Id: demux_mpeg_block.c,v 1.189 2003/05/20 01:23:56 tchamp Exp $ * * demultiplexer for mpeg 1/2 program streams * used with fixed blocksize devices (like dvd/vcd) @@ -32,7 +32,11 @@ #include <fcntl.h> #include <unistd.h> #include <string.h> + +#ifndef WIN32 #include <stdlib.h> +#endif /* WIN32 */ + #include <assert.h> #include "xine_internal.h" diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c index 9f573244e..cd6c86d95 100644 --- a/src/input/input_cdda.c +++ b/src/input/input_cdda.c @@ -20,7 +20,7 @@ * Compact Disc Digital Audio (CDDA) Input Plugin * by Mike Melanson (melanson@pcisys.net) * - * $Id: input_cdda.c,v 1.22 2003/05/16 19:08:59 tchamp Exp $ + * $Id: input_cdda.c,v 1.23 2003/05/20 01:23:56 tchamp Exp $ */ #ifdef HAVE_CONFIG_H @@ -53,8 +53,18 @@ #include "input_plugin.h" #include "media_helper.h" +#ifdef WIN32 +#include <winioctl.h> +#endif + +/* +#define LOG 1 +*/ + #if defined(__sun) #define DEFAULT_CDDA_DEVICE "/vol/dev/aliases/cdrom0" +#elif defined(WIN32) +#define DEFAULT_CDDA_DEVICE "d:\\" #else #define DEFAULT_CDDA_DEVICE "/dev/cdrom" #endif @@ -86,6 +96,265 @@ typedef struct _cdrom_toc { cdrom_toc_entry leadout_track; /* need to know where last track ends */ } cdrom_toc; +/************************************************************************** + * xine interface functions + *************************************************************************/ + +#define MAX_TRACKS 99 +#define CACHED_FRAMES 100 + +typedef struct { + int start; + char *title; +} trackinfo_t; + +typedef struct { + input_plugin_t input_plugin; + + xine_stream_t *stream; + + struct { + int enabled; + char *server; + int port; + char *cache_dir; + + char *cdiscid; + char *disc_title; + char *disc_year; + char *disc_artist; + char *disc_category; + + int fd; + unsigned long disc_id; + + int disc_length; + trackinfo_t *track; + int num_tracks; + int have_cddb_info; + } cddb; + + int fd; + int net_fd; + int track; + char *mrl; + int first_frame; + int current_frame; + int last_frame; + + char *cdda_device; + + unsigned char cache[CACHED_FRAMES][CD_RAW_FRAME_SIZE]; + int cache_first; + int cache_last; + +#ifdef WIN32 + HANDLE h_device_handle; /* vcd device descriptor */ + long hASPI; + short i_sid; + long (*lpSendCommand)( void* ); +#endif + +} cdda_input_plugin_t; + +typedef struct { + + input_class_t input_class; + + xine_t *xine; + config_values_t *config; + + char *cdda_device; + + cdda_input_plugin_t *ip; + + int show_hidden_files; + char *origin_path; + + int mrls_allocated_entries; + xine_mrl_t **mrls; + + char *autoplaylist[MAX_TRACKS]; + +} cdda_input_class_t; + + +#ifdef WIN32 + +/* size of a CD sector */ +#define CD_SECTOR_SIZE 2048 + +/* Win32 DeviceIoControl specifics */ +typedef struct _TRACK_DATA { + UCHAR Reserved; + UCHAR Control : 4; + UCHAR Adr : 4; + UCHAR TrackNumber; + UCHAR Reserved1; + UCHAR Address[4]; +} TRACK_DATA, *PTRACK_DATA; +typedef struct _CDROM_TOC { + UCHAR Length[2]; + UCHAR FirstTrack; + UCHAR LastTrack; + TRACK_DATA TrackData[MAX_TRACKS+1]; +} CDROM_TOC, *PCDROM_TOC; +typedef enum _TRACK_MODE_TYPE { + YellowMode2, + XAForm2, + CDDA +} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; +typedef struct __RAW_READ_INFO { + LARGE_INTEGER DiskOffset; + ULONG SectorCount; + TRACK_MODE_TYPE TrackMode; +} RAW_READ_INFO, *PRAW_READ_INFO; + +#ifndef IOCTL_CDROM_BASE +# define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM +#endif +#ifndef IOCTL_CDROM_READ_TOC +# define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, \ + METHOD_BUFFERED, FILE_READ_ACCESS) +#endif +#ifndef IOCTL_CDROM_RAW_READ +#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, \ + METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#endif + +/* Win32 aspi specific */ +#define WIN_NT ( GetVersion() < 0x80000000 ) +#define ASPI_HAID 0 +#define ASPI_TARGET 0 +#define DTYPE_CDROM 0x05 + +#define SENSE_LEN 0x0E +#define SC_GET_DEV_TYPE 0x01 +#define SC_EXEC_SCSI_CMD 0x02 +#define SC_GET_DISK_INFO 0x06 +#define SS_COMP 0x01 +#define SS_PENDING 0x00 +#define SS_NO_ADAPTERS 0xE8 +#define SRB_DIR_IN 0x08 +#define SRB_DIR_OUT 0x10 +#define SRB_EVENT_NOTIFY 0x40 + +#define READ_CD 0xbe +#define SECTOR_TYPE_MODE2 0x14 +#define READ_CD_USERDATA_MODE2 0x10 + +#define READ_TOC 0x43 +#define READ_TOC_FORMAT_TOC 0x0 + +#pragma pack(1) + +struct SRB_GetDiskInfo +{ + unsigned char SRB_Cmd; + unsigned char SRB_Status; + unsigned char SRB_HaId; + unsigned char SRB_Flags; + unsigned long SRB_Hdr_Rsvd; + unsigned char SRB_Target; + unsigned char SRB_Lun; + unsigned char SRB_DriveFlags; + unsigned char SRB_Int13HDriveInfo; + unsigned char SRB_Heads; + unsigned char SRB_Sectors; + unsigned char SRB_Rsvd1[22]; +}; + +struct SRB_GDEVBlock +{ + unsigned char SRB_Cmd; + unsigned char SRB_Status; + unsigned char SRB_HaId; + unsigned char SRB_Flags; + unsigned long SRB_Hdr_Rsvd; + unsigned char SRB_Target; + unsigned char SRB_Lun; + unsigned char SRB_DeviceType; + unsigned char SRB_Rsvd1; +}; + +struct SRB_ExecSCSICmd +{ + unsigned char SRB_Cmd; + unsigned char SRB_Status; + unsigned char SRB_HaId; + unsigned char SRB_Flags; + unsigned long SRB_Hdr_Rsvd; + unsigned char SRB_Target; + unsigned char SRB_Lun; + unsigned short SRB_Rsvd1; + unsigned long SRB_BufLen; + unsigned char *SRB_BufPointer; + unsigned char SRB_SenseLen; + unsigned char SRB_CDBLen; + unsigned char SRB_HaStat; + unsigned char SRB_TargStat; + unsigned long *SRB_PostProc; + unsigned char SRB_Rsvd2[20]; + unsigned char CDBByte[16]; + unsigned char SenseArea[SENSE_LEN+2]; +}; + +#pragma pack() + +#endif /* WIN32 */ + + +static void print_cdrom_toc(cdrom_toc *toc) { + + int i; + int time1; + int time2; + int timediff; + + printf("\ntoc:\n"); + printf("\tfirst track = %d\n", toc->first_track); + printf("\tlast track = %d\n", toc->last_track); + printf("\ttotal tracks = %d\n", toc->total_tracks); + printf("\ntoc entries:\n"); + + + printf("leadout track: Control: %d MSF: %02d:%02d:%04d, first frame = %d\n", + toc->leadout_track.track_mode, + toc->leadout_track.first_frame_minute, + toc->leadout_track.first_frame_second, + toc->leadout_track.first_frame_frame, + toc->leadout_track.first_frame); + + /* fetch each toc entry */ + if (toc->first_track > 0) { + for (i = toc->first_track; i <= toc->last_track; i++) { + printf("\ttrack mode = %d", toc->toc_entries[i-1].track_mode); + printf("\ttrack %d, audio, MSF: %02d:%02d:%02d, first frame = %d\n", + i, + toc->toc_entries[i-1].first_frame_minute, + toc->toc_entries[i-1].first_frame_second, + toc->toc_entries[i-1].first_frame_frame, + toc->toc_entries[i-1].first_frame); + + time1 = ((toc->toc_entries[i-1].first_frame_minute * 60) + + toc->toc_entries[i-1].first_frame_second); + + if (i == toc->last_track) { + time2 = ((toc->leadout_track.first_frame_minute * 60) + + toc->leadout_track.first_frame_second); + } + else { + time2 = ((toc->toc_entries[i].first_frame_minute * 60) + + toc->toc_entries[i].first_frame_second); + } + + timediff = time2 - time1; + + printf("\t time: %02d:%02d\n", timediff/60, timediff%60); + } + } +} + void init_cdrom_toc(cdrom_toc *toc) { toc->first_track = toc->last_track = toc->total_tracks = 0; @@ -170,9 +439,10 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { return 0; } -static int read_cdrom_frames(int fd, int frame, int num_frames, +static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { + int fd = this_gen->fd; struct cdrom_msf msf; while( num_frames ) { @@ -274,9 +544,10 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { return 0; } -static int read_cdrom_frames(int fd, int frame, int num_frames, +static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { + int fd = this_gen->fd; struct cdrom_cdda cdda; while( num_frames ) { @@ -370,9 +641,10 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { return 0; } -static int read_cdrom_frames(int fd, int frame, int num_frames, +static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { + int fd = this_gen->fd; struct ioc_read_audio cdda; while( num_frames ) { @@ -396,6 +668,136 @@ static int read_cdrom_frames(int fd, int frame, int num_frames, return 0; } +#elif defined(WIN32) + +static int read_cdrom_toc(cdda_input_plugin_t *this_gen, cdrom_toc *toc) { + + if( this_gen->hASPI ) + { + /* This is for ASPI which obviously isn't supported! */ +#ifdef LOG + printf("Windows ASPI support is not complete yet!\n"); +#endif + return -1; + + } + else + { + DWORD dwBytesReturned; + DWORD dw; + CDROM_TOC cdrom_toc; + int i; + + if( DeviceIoControl( this_gen->h_device_handle, + IOCTL_CDROM_READ_TOC, + NULL, 0, &cdrom_toc, sizeof(CDROM_TOC), + &dwBytesReturned, NULL ) == 0 ) + { +#ifdef LOG + printf( "xineplug_inp_cdda : could not read TOCHDR\n" ); + dw = GetLastError(); + printf("GetLastError returned %u\n", dw); + +#endif + return -1; + } + + toc->first_track = cdrom_toc.FirstTrack; + toc->last_track = cdrom_toc.LastTrack; + toc->total_tracks = toc->last_track - toc->first_track + 1; + + + /* allocate space for the toc entries */ + toc->toc_entries = + (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry)); + if (!toc->toc_entries) { + perror("malloc"); + return -1; + } + + + /* fetch each toc entry */ + for (i = toc->first_track; i <= toc->last_track; i++) { + + toc->toc_entries[i-1].track_mode = (cdrom_toc.TrackData[i-1].Control & 0x04) ? 1 : 0; + toc->toc_entries[i-1].first_frame_minute = cdrom_toc.TrackData[i-1].Address[1]; + toc->toc_entries[i-1].first_frame_second = cdrom_toc.TrackData[i-1].Address[2]; + toc->toc_entries[i-1].first_frame_frame = cdrom_toc.TrackData[i-1].Address[3]; + + toc->toc_entries[i-1].first_frame = + (toc->toc_entries[i-1].first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + + (toc->toc_entries[i-1].first_frame_second * CD_FRAMES_PER_SECOND) + + toc->toc_entries[i-1].first_frame_frame; + } + + /* Grab the leadout track too! (I think that this is correct?) */ + i = toc->total_tracks; + toc->leadout_track.track_mode = (cdrom_toc.TrackData[i].Control & 0x04) ? 1 : 0; + toc->leadout_track.first_frame_minute = cdrom_toc.TrackData[i].Address[1]; + toc->leadout_track.first_frame_second = cdrom_toc.TrackData[i].Address[2]; + toc->leadout_track.first_frame_frame = cdrom_toc.TrackData[i].Address[3]; + toc->leadout_track.first_frame = + (toc->leadout_track.first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + + (toc->leadout_track.first_frame_second * CD_FRAMES_PER_SECOND) + + toc->leadout_track.first_frame_frame; + } + + return 0; +} + + +static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, + unsigned char *data) { + + DWORD dw; + DWORD dwBytesReturned; + RAW_READ_INFO raw_read_info; + + if( this_gen->hASPI ) + { + /* This is for ASPI which obviously isn't supported! */ +#ifdef LOG + printf("Windows ASPI support is not complete yet!\n"); +#endif + return -1; + + } + else + { + memset(data, 0, CD_RAW_FRAME_SIZE * num_frames); + + while( num_frames ) { + +#ifdef LOG + /*printf("\t Raw read frame %d\n", frame);*/ +#endif + raw_read_info.DiskOffset.QuadPart = frame * CD_SECTOR_SIZE; + raw_read_info.SectorCount = 1; + raw_read_info.TrackMode = CDDA; + + /* read a frame */ + if( DeviceIoControl( this_gen->h_device_handle, + IOCTL_CDROM_RAW_READ, + &raw_read_info, sizeof(RAW_READ_INFO), data, + CD_RAW_FRAME_SIZE, + &dwBytesReturned, NULL ) == 0 ) + { +#ifdef LOG + printf( "xineplug_inp_cdda : could not read frame\n" ); + dw = GetLastError(); + printf("GetLastError returned %u\n", dw); +#endif + return -1; + } + + data += CD_RAW_FRAME_SIZE; + frame++; + num_frames--; + } + } + return 0; +} + #else @@ -405,7 +807,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { } -static int read_cdrom_frames(int fd, int frame, int num_frames, +static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { return -1; } @@ -775,7 +1177,6 @@ static int network_read_cdrom_toc(int fd, cdrom_toc *toc) { &toc->leadout_track.first_frame_minute, &toc->leadout_track.first_frame_second, &toc->leadout_track.first_frame_frame); - toc->leadout_track.first_frame = (toc->leadout_track.first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (toc->leadout_track.first_frame_second * CD_FRAMES_PER_SECOND) + @@ -791,81 +1192,6 @@ static int network_read_cdrom_frames(int fd, int first_frame, int num_frames, } -/************************************************************************** - * xine interface functions - *************************************************************************/ - -#define MAX_TRACKS 99 -#define CACHED_FRAMES 100 - -typedef struct { - int start; - char *title; -} trackinfo_t; - -typedef struct { - input_plugin_t input_plugin; - - xine_stream_t *stream; - - struct { - int enabled; - char *server; - int port; - char *cache_dir; - - char *cdiscid; - char *disc_title; - char *disc_year; - char *disc_artist; - char *disc_category; - - int fd; - unsigned long disc_id; - - int disc_length; - trackinfo_t *track; - int num_tracks; - int have_cddb_info; - } cddb; - - int fd; - int net_fd; - int track; - char *mrl; - int first_frame; - int current_frame; - int last_frame; - - char *cdda_device; - - unsigned char cache[CACHED_FRAMES][CD_RAW_FRAME_SIZE]; - int cache_first; - int cache_last; - -} cdda_input_plugin_t; - -typedef struct { - - input_class_t input_class; - - xine_t *xine; - config_values_t *config; - - char *cdda_device; - - cdda_input_plugin_t *ip; - - int show_hidden_files; - char *origin_path; - - int mrls_allocated_entries; - xine_mrl_t **mrls; - - char *autoplaylist[MAX_TRACKS]; - -} cdda_input_class_t; - /* * **************** CDDB ********************* @@ -953,24 +1279,50 @@ static int _cdda_is_cd_changed(cdda_input_plugin_t *this) { * create a directory, in safe mode */ static void _cdda_mkdir_safe(char *path) { - struct stat pstat; if(path == NULL) return; - if((lstat(path, &pstat)) < 0) { - /* file or directory no exist, create it */ - if(mkdir(path, 0755) < 0) { - fprintf(stderr, "input_cdda: mkdir(%s) failed: %s\n", path, strerror(errno)); - return; - } +#ifndef WIN32 + { + struct stat pstat; + + if((lstat(path, &pstat)) < 0) { + /* file or directory no exist, create it */ + if(mkdir(path, 0755) < 0) { + fprintf(stderr, "input_cdda: mkdir(%s) failed: %s\n", path, strerror(errno)); + return; + } + } + else { + /* Check of found file is a directory file */ + if(!S_ISDIR(pstat.st_mode)) { + fprintf(stderr, "input_cdda: %s is not a directory.\n", path); + } + } } - else { - /* Check of found file is a directory file */ - if(!S_ISDIR(pstat.st_mode)) { - fprintf(stderr, "input_cdda: %s is not a directory.\n", path); - } +#else + { + HANDLE hList; + TCHAR szDir[MAX_PATH+1]; + WIN32_FIND_DATA FileData; + + // Get the proper directory path + sprintf(szDir, "%s\\*", path); + + // Get the first file + hList = FindFirstFile(szDir, &FileData); + if (hList == INVALID_HANDLE_VALUE) + { + if(_mkdir(path) != 0) { + fprintf(stderr, "input_cdda: mkdir(%s) failed\n", path); + return; + } + } + + FindClose(hList); } +#endif /* WIN32 */ } /* @@ -991,7 +1343,21 @@ static void _cdda_mkdir_recursive_safe(char *path) { pp = buf; while((p = xine_strsep(&pp, "/")) != NULL) { if(p && strlen(p)) { + +#ifdef WIN32 + if (*buf2 != '\0') { +#endif + sprintf(buf2, "%s/%s", buf2, p); + +#ifdef WIN32 + } + else { + sprintf(buf2, "%s", p); + } + +#endif /* WIN32 */ + _cdda_mkdir_safe(buf2); } } @@ -1556,6 +1922,204 @@ static void _cdda_free_cddb_info(cdda_input_plugin_t *this) { * ********** END OF CDDB *************** */ +static int cdda_open(cdda_input_plugin_t *this_gen, + char *cdda_device, cdrom_toc *toc) { + + int fd = -1; + + if ( !cdda_device ) return -1; + +#ifndef WIN32 + + this_gen->fd = -1; + + fd = open (cdda_device, O_RDONLY); + if (fd == -1) { + return -1; + } + this_gen>fd = fd; + +#else /* WIN32 */ + + this_gen->fd = -1; + this_gen->h_device_handle = NULL; + this_gen->i_sid = 0; + this_gen->hASPI = 0; + this_gen->lpSendCommand = 0; + + + /* We are going to assume that we are opening a + * device and not a file! + */ + if( WIN_NT ) + { + char psz_win32_drive[7]; + +#ifdef LOG + printf( "xineplug_inp_cdda : using winNT/2K/XP ioctl layer" ); +#endif + + sprintf( psz_win32_drive, "\\\\.\\%c:", cdda_device[0] ); + + this_gen->h_device_handle = CreateFile( psz_win32_drive, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING | + FILE_FLAG_RANDOM_ACCESS, NULL ); + return (this_gen->h_device_handle == NULL) ? -1 : 0; + } + else + { + HMODULE hASPI = NULL; + long (*lpGetSupport)( void ) = NULL; + long (*lpSendCommand)( void* ) = NULL; + DWORD dwSupportInfo; + int i, j, i_hostadapters; + char c_drive = cdda_device[0]; + + hASPI = LoadLibrary( "wnaspi32.dll" ); + if( hASPI != NULL ) + { + (FARPROC) lpGetSupport = GetProcAddress( hASPI, + "GetASPI32SupportInfo" ); + (FARPROC) lpSendCommand = GetProcAddress( hASPI, + "SendASPI32Command" ); + } + + if( hASPI == NULL || lpGetSupport == NULL || lpSendCommand == NULL ) + { +#ifdef LOG + printf( "xineplug_inp_cdda : unable to load aspi or get aspi function pointers" ); +#endif + + if( hASPI ) FreeLibrary( hASPI ); + return -1; + } + + /* ASPI support seems to be there */ + + dwSupportInfo = lpGetSupport(); + + if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS ) + { +#ifdef LOG + printf( "xineplug_inp_cdda : no host adapters found (aspi)" ); +#endif + FreeLibrary( hASPI ); + return -1; + } + + if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP ) + { +#ifdef LOG + printf( "xineplug_inp_cdda : unable to initalize aspi layer" ); +#endif + FreeLibrary( hASPI ); + return -1; + } + + i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) ); + if( i_hostadapters == 0 ) + { + FreeLibrary( hASPI ); + return -1; + } + + c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A'; + + for( i = 0; i < i_hostadapters; i++ ) + { + for( j = 0; j < 15; j++ ) + { + struct SRB_GetDiskInfo srbDiskInfo; + + srbDiskInfo.SRB_Cmd = SC_GET_DISK_INFO; + srbDiskInfo.SRB_HaId = i; + srbDiskInfo.SRB_Flags = 0; + srbDiskInfo.SRB_Hdr_Rsvd = 0; + srbDiskInfo.SRB_Target = j; + srbDiskInfo.SRB_Lun = 0; + + lpSendCommand( (void*) &srbDiskInfo ); + + if( (srbDiskInfo.SRB_Status == SS_COMP) && + (srbDiskInfo.SRB_Int13HDriveInfo == c_drive) ) + { + /* Make sure this is a cdrom device */ + struct SRB_GDEVBlock srbGDEVBlock; + + memset( &srbGDEVBlock, 0, sizeof(struct SRB_GDEVBlock) ); + srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE; + srbGDEVBlock.SRB_HaId = i; + srbGDEVBlock.SRB_Target = j; + + lpSendCommand( (void*) &srbGDEVBlock ); + + if( ( srbGDEVBlock.SRB_Status == SS_COMP ) && + ( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) ) + { + this_gen->i_sid = MAKEWORD( i, j ); + this_gen->hASPI = (long)hASPI; + this_gen->lpSendCommand = lpSendCommand; + +#ifdef LOG + printf( "xineplug_inp_cdda : using aspi layer" ); +#endif + + return 0; + } + else + { + FreeLibrary( hASPI ); +#ifdef LOG + printf( "xineplug_inp_cdda : %s: is not a cdrom drive", + cdda_device[0] ); +#endif + return -1; + } + } + } + } + + FreeLibrary( hASPI ); + +#ifdef LOG + printf( "xineplug_inp_cdda : unable to get haid and target (aspi)" ); +#endif + + } + + return -1; + + + +#endif /* WIN32 */ + +} + +static int cdda_close(cdda_input_plugin_t *this_gen) { + + if( this_gen->fd != -1 ) + close(this_gen->fd); + this_gen->fd = -1; + + if (this_gen->net_fd != -1) + close(this_gen->net_fd); + this_gen->net_fd = -1; + +#ifdef WIN32 + if( this_gen->h_device_handle ) + CloseHandle( this_gen->h_device_handle ); + this_gen->h_device_handle = NULL; + if( this_gen->hASPI ) + FreeLibrary( (HMODULE)this_gen->hASPI ); + this_gen->hASPI = NULL; +#endif /* WIN32 */ + + return 0; +} + + static uint32_t cdda_plugin_get_capabilities (input_plugin_t *this_gen) { return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK; @@ -1593,8 +2157,13 @@ static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buf if( this->cache_last > this->last_frame ) this->cache_last = this->last_frame; - if( this->fd != -1 ) - err = read_cdrom_frames(this->fd, this->cache_first, +#ifndef WIN32 + if ( this->fd != -1 ) +#else + if ( this->h_device_handle ) +#endif /* WIN32 */ + + err = read_cdrom_frames(this, this->cache_first, this->cache_last - this->cache_first + 1, this->cache[0]); else if ( this->net_fd != -1 ) @@ -1670,11 +2239,7 @@ static void cdda_plugin_dispose (input_plugin_t *this_gen ) { _cdda_free_cddb_info(this); - if (this->fd != -1) - close(this->fd); - - if (this->net_fd != -1) - close(this->net_fd); + cdda_close(this); free(this->mrl); @@ -1684,11 +2249,12 @@ static void cdda_plugin_dispose (input_plugin_t *this_gen ) { free(this); } + static int cdda_plugin_open (input_plugin_t *this_gen ) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; cdda_input_class_t *class = (cdda_input_class_t *) this_gen->input_class; cdrom_toc toc; - int fd; + int fd = -1; char *cdda_device; int err = -1; @@ -1703,7 +2269,8 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) { cdda_device = this->cdda_device; else cdda_device = class->cdda_device; - + +#ifndef WIN32 if( strchr(cdda_device,':') ) { fd = network_connect(cdda_device); if( fd != -1 ) { @@ -1712,29 +2279,32 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) { err = network_read_cdrom_toc(this->net_fd, &toc); } } +#endif if( this->net_fd == -1 ) { - fd = open (cdda_device, O_RDONLY); - if (fd == -1) { + + if (cdda_open(this, cdda_device, &toc) == -1) { free_cdrom_toc(&toc); return 0; - } - this->fd = fd; - + } + +#ifndef WIN32 err = read_cdrom_toc(this->fd, &toc); +#else + err = read_cdrom_toc(this, &toc); +#endif + +#ifdef LOG + print_cdrom_toc(&toc); +#endif + } if ( (err < 0) || (toc.first_track > (this->track + 1)) || (toc.last_track < (this->track + 1))) { - if( this->fd != -1 ) - close(this->fd); - this->fd = -1; - - if( this->net_fd != -1 ) - close(this->net_fd); - this->net_fd = -1; + cdda_close(this); free_cdrom_toc(&toc); return 0; @@ -1783,30 +2353,50 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) { _cdda_cddb_grab_infos(this); if(this->cddb.disc_title) { +#ifdef LOG + printf("Disc Title: %s\n", this->cddb.disc_title); +#endif + if(this->stream->meta_info[XINE_META_INFO_ALBUM]) free(this->stream->meta_info[XINE_META_INFO_ALBUM]); this->stream->meta_info[XINE_META_INFO_ALBUM] = strdup(this->cddb.disc_title); } if(this->cddb.track[this->track].title) { +#ifdef LOG + printf("Track %d Title: %s\n", this->track+1, this->cddb.track[this->track].title); +#endif + if(this->stream->meta_info[XINE_META_INFO_TITLE]) free(this->stream->meta_info[XINE_META_INFO_TITLE]); this->stream->meta_info[XINE_META_INFO_TITLE] = strdup(this->cddb.track[this->track].title); } if(this->cddb.disc_artist) { +#ifdef LOG + printf("Disc Artist: %s\n", this->cddb.disc_artist); +#endif + if(this->stream->meta_info[XINE_META_INFO_ARTIST]) free(this->stream->meta_info[XINE_META_INFO_ARTIST]); this->stream->meta_info[XINE_META_INFO_ARTIST] = strdup(this->cddb.disc_artist); } if(this->cddb.disc_category) { +#ifdef LOG + printf("Disc Category: %s\n", this->cddb.disc_category); +#endif + if(this->stream->meta_info[XINE_META_INFO_GENRE]) free(this->stream->meta_info[XINE_META_INFO_GENRE]); this->stream->meta_info[XINE_META_INFO_GENRE] = strdup(this->cddb.disc_category); } if(this->cddb.disc_year) { +#ifdef LOG + printf("Disc Year: %s\n", this->cddb.disc_year); +#endif + if(this->stream->meta_info[XINE_META_INFO_YEAR]) free(this->stream->meta_info[XINE_META_INFO_YEAR]); this->stream->meta_info[XINE_META_INFO_YEAR] = strdup(this->cddb.disc_year); @@ -1820,6 +2410,7 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { cdda_input_class_t *this = (cdda_input_class_t *) this_gen; + cdda_input_plugin_t *ip = this->ip; cdrom_toc toc; char trackmrl[20]; int fd, i, err = -1; @@ -1834,28 +2425,39 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen, init_cdrom_toc(&toc); fd = -1; + +#ifndef WIN32 if( strchr(this->cdda_device,':') ) { fd = network_connect(this->cdda_device); if( fd != -1 ) { err = network_read_cdrom_toc(fd, &toc); } } +#endif - if( fd == -1 ) { - fd = open (this->cdda_device, O_RDONLY); - if (fd == -1) { + if (fd == -1) { + if (cdda_open(ip, ip->cdda_device, &toc) == -1) { return NULL; - } + } + } + +#ifndef WIN32 err = read_cdrom_toc(fd, &toc); - } - - close(fd); +#else + err = read_cdrom_toc(ip, &toc); +#endif /* WIN32 */ + +#ifdef LOG + print_cdrom_toc(&toc); +#endif + + cdda_close(ip); - if( err < 0 ) + if ( err < 0 ) return NULL; - for( i = 0; i <= toc.last_track - toc.first_track; i++ ) { + for ( i = 0; i <= toc.last_track - toc.first_track; i++ ) { sprintf(trackmrl,"cdda:/%d",i+toc.first_track); this->autoplaylist[i] = strdup(trackmrl); } diff --git a/win32/source/main.cpp b/win32/source/main.cpp index f57cc2713..c53175a97 100644 --- a/win32/source/main.cpp +++ b/win32/source/main.cpp @@ -1,184 +1,203 @@ -/*
- * Copyright (C) 2000-2001 the xine project
- *
- * This file is part of xine for win32 video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * Xine win32 UI
- * by Matthew Grooms <elon@altavista.com>
- */
-
-#include "xineui.h"
-#include "common.h"
-
-#include <fcntl.h>
-#include <io.h>
-
-#define MAX_CONSOLE_LINES 1000
-
-gGui_t *gGui;
-
-void RedirectIOToConsole()
-{
- int hConHandle;
- long lStdHandle;
- CONSOLE_SCREEN_BUFFER_INFO coninfo;
- FILE *fp;
-
- // allocate a console for this app
- AllocConsole();
-
- // set the screen buffer to be big enough to let us scroll text
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
- &coninfo);
- coninfo.dwSize.Y = MAX_CONSOLE_LINES;
- SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
- coninfo.dwSize);
-
- // redirect unbuffered STDOUT to the console
- lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
- hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
- fp = _fdopen( hConHandle, "w" );
- *stdout = *fp;
- setvbuf( stdout, NULL, _IONBF, 0 );
-
- // redirect unbuffered STDIN to the console
- lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
- hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
- fp = _fdopen( hConHandle, "r" );
- *stdin = *fp;
- setvbuf( stdin, NULL, _IONBF, 0 );
-
- // redirect unbuffered STDERR to the console
- lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
- hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
- fp = _fdopen( hConHandle, "w" );
- *stderr = *fp;
- setvbuf( stderr, NULL, _IONBF, 0 );
-
- // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
- // point to console as well
- /*ios::sync_with_stdio();*/
-}
-
-int WINAPI WinMain( HINSTANCE hinst, HINSTANCE hprevinst, LPSTR cmdline, int ncmdshow )
-{
- XINE_UI xine_ui;
-
-
-#if !defined (__MINGW32__)
- /* We only need the output window for MSVC */
- RedirectIOToConsole();
-#endif
-
- // prepair our mrl(s) and add them
- // to our playlist
-
- char * next_mrl = cmdline;
- while( next_mrl )
- {
- char temp_mrl[ 1024 ];
- memset( temp_mrl, 0, sizeof( temp_mrl ) );
-
- if( *next_mrl == 0 )
- break;
-
- if( *next_mrl == ' ' )
- {
- next_mrl++;
- continue;
- }
-
- if( *next_mrl == '\"' )
- {
- strcpy( temp_mrl, next_mrl + 1 );
-
- char * end_mrl = strchr( temp_mrl, '\"' );
- if( end_mrl )
- {
- *end_mrl = 0;
- next_mrl = end_mrl + 1;
- }
- else
- next_mrl = 0;
- }
- else
- {
- strcpy( temp_mrl, next_mrl );
-
- char * end_mrl = strchr( temp_mrl, ' ' );
- if( end_mrl )
- {
- *end_mrl = 0;
- next_mrl = end_mrl + 1;
- }
- else
- next_mrl = 0;
- }
-
- char * back_slash = strrchr( temp_mrl, '\\' );
- char * fore_slash = strrchr( temp_mrl, '/' );
- char * last_slash = 0;
-
- if( back_slash > temp_mrl )
- if( *( back_slash - 1 ) == ':' )
- back_slash = 0;
-
- if( back_slash > fore_slash )
- last_slash = back_slash;
- else
- last_slash = fore_slash;
-
- if( last_slash )
- xine_ui.PlaylistAdd( last_slash + 1, temp_mrl, 0 );
- else
- xine_ui.PlaylistAdd( temp_mrl, temp_mrl, 0 );
- }
-
- // initialize common control tools
-
- InitCommonControls();
-
- // init gui
-
- if( !xine_ui.InitGui( hinst ) )
- return 1;
-
- // init libxine
-
- if( !xine_ui.InitXine() )
- return 1;
-
- // start playback
-
- if( xine_ui.playcount )
- xine_ui.Play( 0 );
-
-
- // start the message loop.
-
- MSG msg;
-
- while( GetMessage( &msg, ( HWND ) NULL, 0, 0 ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
-
- // return the exit code to Windows.
-
- return msg.wParam;
-}
+/* + * Copyright (C) 2000-2001 the xine project + * + * This file is part of xine for win32 video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Xine win32 UI + * by Matthew Grooms <elon@altavista.com> + */ + +#include "xineui.h" +#include "common.h" + +#include <fcntl.h> +#include <io.h> + +#define MAX_CONSOLE_LINES 1000 + +gGui_t *gGui; + +void RedirectIOToConsole() +{ + int hConHandle; + long lStdHandle; + CONSOLE_SCREEN_BUFFER_INFO coninfo; + FILE *fp; + + // allocate a console for this app + AllocConsole(); + + // set the screen buffer to be big enough to let us scroll text + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), + &coninfo); + coninfo.dwSize.Y = MAX_CONSOLE_LINES; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), + coninfo.dwSize); + + // redirect unbuffered STDOUT to the console + lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + + /* This was happening when launched from a Cygwin shell */ + if (hConHandle == -1) { + FreeConsole(); + return; + } + + fp = _fdopen( hConHandle, "w" ); + *stdout = *fp; + setvbuf( stdout, NULL, _IONBF, 0 ); + + // redirect unbuffered STDIN to the console + lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + + if (hConHandle == -1) { + FreeConsole(); + return; + } + + fp = _fdopen( hConHandle, "r" ); + *stdin = *fp; + setvbuf( stdin, NULL, _IONBF, 0 ); + + // redirect unbuffered STDERR to the console + lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + + if (hConHandle == -1) { + FreeConsole(); + return; + } + + fp = _fdopen( hConHandle, "w" ); + *stderr = *fp; + setvbuf( stderr, NULL, _IONBF, 0 ); + + // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog + // point to console as well + /*ios::sync_with_stdio();*/ +} + +int WINAPI WinMain( HINSTANCE hinst, HINSTANCE hprevinst, LPSTR cmdline, int ncmdshow ) +{ + XINE_UI xine_ui; + + +#if !defined (__MINGW32__) + /* We only need the output window for MSVC */ + RedirectIOToConsole(); +#endif + + // prepair our mrl(s) and add them + // to our playlist + + char * next_mrl = cmdline; + while( next_mrl ) + { + char temp_mrl[ 1024 ]; + memset( temp_mrl, 0, sizeof( temp_mrl ) ); + + if( *next_mrl == 0 ) + break; + + if( *next_mrl == ' ' ) + { + next_mrl++; + continue; + } + + if( *next_mrl == '\"' ) + { + strcpy( temp_mrl, next_mrl + 1 ); + + char * end_mrl = strchr( temp_mrl, '\"' ); + if( end_mrl ) + { + *end_mrl = 0; + next_mrl = end_mrl + 1; + } + else + next_mrl = 0; + } + else + { + strcpy( temp_mrl, next_mrl ); + + char * end_mrl = strchr( temp_mrl, ' ' ); + if( end_mrl ) + { + *end_mrl = 0; + next_mrl = end_mrl + 1; + } + else + next_mrl = 0; + } + + char * back_slash = strrchr( temp_mrl, '\\' ); + char * fore_slash = strrchr( temp_mrl, '/' ); + char * last_slash = 0; + + if( back_slash > temp_mrl ) + if( *( back_slash - 1 ) == ':' ) + back_slash = 0; + + if( back_slash > fore_slash ) + last_slash = back_slash; + else + last_slash = fore_slash; + + if( last_slash ) + xine_ui.PlaylistAdd( last_slash + 1, temp_mrl, 0 ); + else + xine_ui.PlaylistAdd( temp_mrl, temp_mrl, 0 ); + } + + // initialize common control tools + + InitCommonControls(); + + // init gui + + if( !xine_ui.InitGui( hinst ) ) + return 1; + + // init libxine + + if( !xine_ui.InitXine() ) + return 1; + + // start playback + + if( xine_ui.playcount ) + xine_ui.Play( 0 ); + + + // start the message loop. + + MSG msg; + + while( GetMessage( &msg, ( HWND ) NULL, 0, 0 ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + // return the exit code to Windows. + + return msg.wParam; +} diff --git a/win32/source/resource.aps b/win32/source/resource.aps Binary files differdeleted file mode 100644 index 7663c0e79..000000000 --- a/win32/source/resource.aps +++ /dev/null |