⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_syscdrom.c

📁 jpeg and mpeg 编解码技术源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    AIX audio module for SDL (Simple DirectMedia Layer)
    Copyright (C) 2000 Carsten Griwodz

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Carsten Griwodz
    griff@kom.tu-darmstadt.de

    based on linux/SDL_syscdrom.c by Sam Lantinga
*/

#ifdef SAVE_RCSID
static char rcsid =
 "@(#) $Id: SDL_syscdrom.c,v 1.2 2002/04/22 21:38:02 wmay Exp $";
#endif

/* Functions for system-level CD-ROM audio control */

#define DEBUG_CDROM 1

#include <sys/types.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/devinfo.h>
#include <sys/mntctl.h>
#include <sys/statfs.h>
#include <sys/vmount.h>
#include <fstab.h>
#include <sys/scdisk.h>

#include "SDL_error.h"
#include "SDL_cdrom.h"
#include "SDL_syscdrom.h"

/* The maximum number of CD-ROM drives we'll detect */
#define MAX_DRIVES	16	

/* A list of available CD-ROM drives */
static char *SDL_cdlist[MAX_DRIVES];
static dev_t SDL_cdmode[MAX_DRIVES];

/* The system-dependent CD control functions */
static const char *SDL_SYS_CDName(int drive);
static int         SDL_SYS_CDOpen(int drive);
static int         SDL_SYS_CDGetTOC(SDL_CD *cdrom);
static CDstatus    SDL_SYS_CDStatus(SDL_CD *cdrom, int *position);
static int         SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length);
static int         SDL_SYS_CDPause(SDL_CD *cdrom);
static int         SDL_SYS_CDResume(SDL_CD *cdrom);
static int         SDL_SYS_CDStop(SDL_CD *cdrom);
static int         SDL_SYS_CDEject(SDL_CD *cdrom);
static void        SDL_SYS_CDClose(SDL_CD *cdrom);
static int         SDL_SYS_CDioctl(int id, int command, void *arg);

/* Check a drive to see if it is a CD-ROM */
static int CheckDrive(char *drive, struct stat *stbuf)
{
    int is_cd;
    int cdfd;
    int ret;
    struct devinfo info;

    /* If it doesn't exist, return -1 */
    if ( stat(drive, stbuf) < 0 ) {
        return -1;
    }

    /* If it does exist, verify that it's an available CD-ROM */
    is_cd = 0;
    if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) {
        cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0);
        if ( cdfd >= 0 ) {
            ret = SDL_SYS_CDioctl( cdfd, IOCINFO, &info );
	    if ( ret < 0 ) {
		/* Some kind of error */
		is_cd = 0;
	    } else {
		if ( info.devtype == DD_CDROM ) {
		    is_cd = 1;
		} else {
		    is_cd = 0;
		}
	    }
            close(cdfd);
	}
#ifdef DEBUG_CDROM
	else
	{
            fprintf(stderr, "Could not open drive %s (%s)\n", drive, strerror(errno));
	}
#endif
    }
    return is_cd;
}

/* Add a CD-ROM drive to our list of valid drives */
static void AddDrive(char *drive, struct stat *stbuf)
{
	int i;

	if ( SDL_numcds < MAX_DRIVES ) {
		/* Check to make sure it's not already in our list.
	 	   This can happen when we see a drive via symbolic link.
		 */
		for ( i=0; i<SDL_numcds; ++i ) {
			if ( stbuf->st_rdev == SDL_cdmode[i] ) {
#ifdef DEBUG_CDROM
  fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]);
#endif
				return;
			}
		}

		/* Add this drive to our list */
		i = SDL_numcds;
		SDL_cdlist[i] = (char *)malloc(strlen(drive)+1);
		if ( SDL_cdlist[i] == NULL ) {
			SDL_OutOfMemory();
			return;
		}
		strcpy(SDL_cdlist[i], drive);
		SDL_cdmode[i] = stbuf->st_rdev;
		++SDL_numcds;
#ifdef DEBUG_CDROM
  fprintf(stderr, "Added CD-ROM drive: %s\n", drive);
#endif
	}
}

static void CheckMounts()
{
    char*          buffer;
    int            bufsz;
    struct vmount* ptr;
    int            ret;

    buffer = (char*)malloc(10);
    bufsz  = 10;
    if ( buffer==NULL )
    {
        fprintf(stderr, "Could not allocate 10 bytes in aix/SDL_syscdrom.c:CheckMounts\n" );
	exit ( -10 );
    }

    do
    {
	/* mntctrl() returns an array of all mounted filesystems */
        ret = mntctl ( MCTL_QUERY, bufsz, buffer );
        if ( ret == 0 )
        {
				   /* Buffer was too small, realloc.    */
            bufsz = *(int*)buffer; /* Required size is in first word.   */
				   /* (whatever a word is in AIX 4.3.3) */
				   /* int seems to be OK in 32bit mode. */
            free(buffer);
            buffer = (char*)malloc(bufsz);
            if ( buffer==NULL )
            {
                fprintf(stderr,
			"Could not allocate %d bytes in aix/SDL_syscdrom.c:CheckMounts\n",
			bufsz );
	        exit ( -10 );
            }
        }
	else if ( ret < 0 )
	{
#ifdef DEBUG_CDROM
            fprintf(stderr, "Error reading vmount structures\n");
#endif
	    return;
	}
    }
    while ( ret == 0 );

#ifdef DEBUG_CDROM
    fprintf ( stderr, "Read %d vmount structures\n",ret );
#endif
    ptr = (struct vmount*)buffer;
    do
    {
            switch(ptr->vmt_gfstype)
            {
            case MNT_CDROM :
                {
		    struct stat stbuf;
		    char*       text;

		    text = (char*)ptr + ptr->vmt_data[VMT_OBJECT].vmt_off;
#ifdef DEBUG_CDROM
  fprintf(stderr, "Checking mount path: %s mounted on %s\n",
	text, (char*)ptr + ptr->vmt_data[VMT_STUB].vmt_off );
#endif
		    if ( CheckDrive( text, &stbuf) > 0)
		    {
		        AddDrive( text, &stbuf);
		    }
                }
                break;
            default :
                break;
            }
            ptr = (struct vmount*)((char*)ptr + ptr->vmt_length);
            ret--;
    }
    while ( ret > 0 );

    free ( buffer );
}

static int CheckNonmounts()
{
#ifdef _THREAD_SAFE
    AFILE_t      fsFile = NULL;
    int          passNo = 0;
    int          ret;
    struct fstab entry;
    struct stat  stbuf;

    ret = setfsent_r( &fsFile, &passNo );
    if ( ret != 0 ) return -1;
    do
    {
        ret = getfsent_r ( &entry, &fsFile, &passNo );
        if ( ret == 0 ) {
            char* l = strrchr(entry.fs_spec,'/');
            if ( l != NULL ) {
                if ( !strncmp("cd",++l,2) ) {
#ifdef DEBUG_CDROM
                    fprintf(stderr,
			    "Found unmounted CD ROM drive with device name %s\n",
			    entry.fs_spec);
#endif
		    if ( CheckDrive( entry.fs_spec, &stbuf) > 0)
		    {
		        AddDrive( entry.fs_spec, &stbuf);
		    }
                }
            }
        }
    }
    while ( ret == 0 );
    ret = endfsent_r ( &fsFile );
    if ( ret != 0 ) return -1;
    return 0;
#else
    struct fstab* entry;
    struct stat  stbuf;

    setfsent();
    do
    {
        entry = getfsent();
        if ( entry != NULL ) {
            char* l = strrchr(entry->fs_spec,'/');
            if ( l != NULL ) {
                if ( !strncmp("cd",++l,2) ) {
#ifdef DEBUG_CDROM
                    fprintf(stderr,"Found unmounted CD ROM drive with device name %s", entry->fs_spec);
#endif
		    if ( CheckDrive( entry->fs_spec, &stbuf) > 0)
		    {
		        AddDrive( entry->fs_spec, &stbuf);
		    }
                }
            }
        }
    }
    while ( entry != NULL );
    endfsent();
#endif
}

int  SDL_SYS_CDInit(void)
{
	char *SDLcdrom;
	struct stat stbuf;

	/* Fill in our driver capabilities */
	SDL_CDcaps.Name = SDL_SYS_CDName;
	SDL_CDcaps.Open = SDL_SYS_CDOpen;
	SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
	SDL_CDcaps.Status = SDL_SYS_CDStatus;
	SDL_CDcaps.Play = SDL_SYS_CDPlay;
	SDL_CDcaps.Pause = SDL_SYS_CDPause;
	SDL_CDcaps.Resume = SDL_SYS_CDResume;
	SDL_CDcaps.Stop = SDL_SYS_CDStop;
	SDL_CDcaps.Eject = SDL_SYS_CDEject;
	SDL_CDcaps.Close = SDL_SYS_CDClose;

	/* Look in the environment for our CD-ROM drive list */
	SDLcdrom = getenv("SDL_CDROM");	/* ':' separated list of devices */
	if ( SDLcdrom != NULL ) {
		char *cdpath, *delim;
		cdpath = malloc(strlen(SDLcdrom)+1);
		if ( cdpath != NULL ) {
			strcpy(cdpath, SDLcdrom);
			SDLcdrom = cdpath;
			do {
				delim = strchr(SDLcdrom, ':');
				if ( delim ) {
					*delim++ = '\0';
				}
#ifdef DEBUG_CDROM
  fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom);
#endif
				if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) {
					AddDrive(SDLcdrom, &stbuf);
				}
				if ( delim ) {
					SDLcdrom = delim;
				} else {
					SDLcdrom = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -