src/cdrom/qnx/SDL_syscdrom.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 08 Mar 2006 01:55:32 +0000
changeset 1482 141528317f4f
parent 1402 d910939febfa
child 1635 92947e3a18db
permissions -rw-r--r--
QNX changes from Mike Gorchak
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* Functions for system-level CD-ROM audio control */
slouken@0
    25
slouken@0
    26
#include <sys/types.h>
slouken@0
    27
#include <sys/stat.h>
slouken@0
    28
#include <sys/ioctl.h>
slouken@0
    29
#include <fcntl.h>
slouken@571
    30
#include <errno.h>
slouken@0
    31
#include <unistd.h>
slouken@0
    32
#include <sys/cdrom.h>
slouken@0
    33
#include <sys/dcmd_cam.h>
slouken@0
    34
slouken@1358
    35
#include "SDL_timer.h"
slouken@0
    36
#include "SDL_cdrom.h"
slouken@1361
    37
#include "../SDL_syscdrom.h"
slouken@0
    38
slouken@571
    39
/* The maximum number of CD-ROM drives we'll detect */
slouken@571
    40
#define MAX_DRIVES 16
slouken@0
    41
slouken@571
    42
#define QNX_CD_OPENMODE O_RDONLY | O_EXCL
slouken@0
    43
slouken@0
    44
/* A list of available CD-ROM drives */
slouken@0
    45
static char *SDL_cdlist[MAX_DRIVES];
slouken@0
    46
static dev_t SDL_cdmode[MAX_DRIVES];
slouken@571
    47
static int   SDL_cdopen[MAX_DRIVES];
slouken@0
    48
slouken@0
    49
/* The system-dependent CD control functions */
slouken@0
    50
static const char *SDL_SYS_CDName(int drive);
slouken@0
    51
static int SDL_SYS_CDOpen(int drive);
slouken@0
    52
static int SDL_SYS_CDGetTOC(SDL_CD *cdrom);
slouken@0
    53
static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position);
slouken@0
    54
static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length);
slouken@0
    55
static int SDL_SYS_CDPause(SDL_CD *cdrom);
slouken@0
    56
static int SDL_SYS_CDResume(SDL_CD *cdrom);
slouken@0
    57
static int SDL_SYS_CDStop(SDL_CD *cdrom);
slouken@0
    58
static int SDL_SYS_CDEject(SDL_CD *cdrom);
slouken@0
    59
static void SDL_SYS_CDClose(SDL_CD *cdrom);
slouken@0
    60
slouken@571
    61
/* Check a drive to see if it is a CD-ROM */
slouken@571
    62
static int CheckDrive(char *drive, struct stat *stbuf)
slouken@571
    63
{
slouken@571
    64
    int is_cd, cdfd;
slouken@571
    65
    cam_devinfo_t dinfo;
slouken@571
    66
    int devctlret=0;
slouken@0
    67
slouken@571
    68
    int atapi;
slouken@571
    69
    int removable;
slouken@571
    70
    int cdb10;
slouken@0
    71
slouken@571
    72
    /* If it doesn't exist, return -1 */
slouken@571
    73
    if (stat(drive, stbuf) < 0)
slouken@571
    74
    {
slouken@571
    75
        return(-1);
slouken@571
    76
    }
slouken@0
    77
slouken@571
    78
    /* If it does exist, verify that it's an available CD-ROM */
slouken@571
    79
    is_cd = 0;
slouken@571
    80
slouken@571
    81
    if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode))
slouken@571
    82
    {
slouken@571
    83
        cdfd = open(drive, QNX_CD_OPENMODE);
slouken@571
    84
        if ( cdfd >= 0 )
slouken@571
    85
        {
slouken@571
    86
            devctlret=devctl(cdfd, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL);
slouken@571
    87
slouken@571
    88
            if (devctlret==EOK)
slouken@571
    89
            {
slouken@571
    90
               atapi=dinfo.flags & DEV_ATAPI;
slouken@571
    91
               removable=dinfo.flags & DEV_REMOVABLE;
slouken@571
    92
               cdb10=dinfo.flags & DEV_CDB_10; /* I'm not sure about that flag */
slouken@571
    93
slouken@571
    94
               /* in the near future need to add more checks for splitting cdroms from other devices */
slouken@571
    95
               if ((atapi)&&(removable))
slouken@571
    96
               {
slouken@571
    97
                   is_cd = 1;
slouken@571
    98
               }
slouken@571
    99
            }
slouken@571
   100
slouken@571
   101
            close(cdfd);
slouken@571
   102
        }
slouken@571
   103
    }
slouken@571
   104
    return(is_cd);
slouken@0
   105
}
slouken@0
   106
slouken@0
   107
/* Add a CD-ROM drive to our list of valid drives */
slouken@0
   108
static void AddDrive(char *drive, struct stat *stbuf)
slouken@0
   109
{
slouken@571
   110
    int i;
slouken@0
   111
slouken@571
   112
    if (SDL_numcds < MAX_DRIVES)
slouken@571
   113
    {
slouken@571
   114
        /* Check to make sure it's not already in our list.
slouken@571
   115
        This can happen when we see a drive via symbolic link. */
slouken@0
   116
slouken@571
   117
        for (i=0; i<SDL_numcds; ++i)
slouken@571
   118
        {
slouken@571
   119
            if (stbuf->st_rdev == SDL_cdmode[i])
slouken@571
   120
            {
slouken@571
   121
                return;
slouken@571
   122
            }
slouken@571
   123
        }
slouken@571
   124
slouken@571
   125
        /* Add this drive to our list */
slouken@571
   126
slouken@571
   127
        i = SDL_numcds;
slouken@1379
   128
        SDL_cdlist[i] = SDL_strdup(drive);
slouken@571
   129
        if (SDL_cdlist[i] == NULL)
slouken@571
   130
        {
slouken@571
   131
            SDL_OutOfMemory();
slouken@571
   132
            return;
slouken@571
   133
        }
slouken@571
   134
        SDL_cdmode[i] = stbuf->st_rdev;
slouken@571
   135
        ++SDL_numcds;
slouken@571
   136
    }
slouken@0
   137
}
slouken@0
   138
slouken@571
   139
int SDL_SYS_CDInit(void)
slouken@0
   140
{
slouken@571
   141
    /* checklist: /dev/cdrom, /dev/cd?, /dev/scd? */
slouken@571
   142
    static char *checklist[]={"cdrom", "?0 cd?", "?1 cd?", "?0 scd?", NULL};
slouken@0
   143
slouken@571
   144
    char *SDLcdrom;
slouken@571
   145
    int i, j, exists;
slouken@571
   146
    char drive[32];
slouken@571
   147
    struct stat stbuf;
slouken@0
   148
slouken@571
   149
    /* Fill in our driver capabilities */
slouken@571
   150
    SDL_CDcaps.Name = SDL_SYS_CDName;
slouken@571
   151
    SDL_CDcaps.Open = SDL_SYS_CDOpen;
slouken@571
   152
    SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
slouken@571
   153
    SDL_CDcaps.Status = SDL_SYS_CDStatus;
slouken@571
   154
    SDL_CDcaps.Play = SDL_SYS_CDPlay;
slouken@571
   155
    SDL_CDcaps.Pause = SDL_SYS_CDPause;
slouken@571
   156
    SDL_CDcaps.Resume = SDL_SYS_CDResume;
slouken@571
   157
    SDL_CDcaps.Stop = SDL_SYS_CDStop;
slouken@571
   158
    SDL_CDcaps.Eject = SDL_SYS_CDEject;
slouken@571
   159
    SDL_CDcaps.Close = SDL_SYS_CDClose;
slouken@0
   160
slouken@571
   161
    /* clearing device open status */
slouken@571
   162
    for (i=0; i<MAX_DRIVES; i++)
slouken@571
   163
    {
slouken@571
   164
       SDL_cdopen[i]=0;
slouken@571
   165
    }
slouken@0
   166
slouken@571
   167
    /* Look in the environment for our CD-ROM drive list */
slouken@1336
   168
    SDLcdrom = SDL_getenv("SDL_CDROM");	/* ':' separated list of devices */
slouken@571
   169
    if ( SDLcdrom != NULL )
slouken@571
   170
    {
slouken@571
   171
        char *cdpath, *delim;
slouken@1379
   172
	size_t len = SDL_strlen(SDLcdrom)+1;
slouken@1482
   173
        cdpath = SDL_stack_alloc(char, len);
slouken@571
   174
        if (cdpath != NULL)
slouken@571
   175
        {
slouken@1379
   176
            SDL_strlcpy(cdpath, SDLcdrom, len);
slouken@571
   177
            SDLcdrom = cdpath;
slouken@571
   178
            do {
slouken@1336
   179
                delim = SDL_strchr(SDLcdrom, ':');
slouken@571
   180
                if (delim)
slouken@571
   181
                {
slouken@571
   182
                    *delim++ = '\0';
slouken@571
   183
                }
slouken@571
   184
                if (CheckDrive(SDLcdrom, &stbuf) > 0)
slouken@571
   185
                {
slouken@571
   186
                    AddDrive(SDLcdrom, &stbuf);
slouken@571
   187
                }
slouken@571
   188
                if (delim)
slouken@571
   189
                {
slouken@571
   190
                    SDLcdrom = delim;
slouken@571
   191
                }
slouken@571
   192
                else
slouken@571
   193
                {
slouken@571
   194
                    SDLcdrom = NULL;
slouken@571
   195
                }
slouken@571
   196
            } while (SDLcdrom);
slouken@1379
   197
            SDL_stack_free(cdpath);
slouken@571
   198
        }
slouken@571
   199
slouken@571
   200
        /* If we found our drives, there's nothing left to do */
slouken@571
   201
        if (SDL_numcds > 0)
slouken@571
   202
        {
slouken@571
   203
            return(0);
slouken@571
   204
        }
slouken@571
   205
    }
slouken@571
   206
slouken@571
   207
    /* Scan the system for CD-ROM drives */
slouken@571
   208
    for ( i=0; checklist[i]; ++i )
slouken@571
   209
    {
slouken@571
   210
        if (checklist[i][0] == '?')
slouken@571
   211
        {
slouken@571
   212
            char* insert;
slouken@571
   213
            exists = 1;
slouken@571
   214
slouken@571
   215
            for ( j=checklist[i][1]; exists; ++j )
slouken@571
   216
            {
slouken@1338
   217
                SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", &checklist[i][3]);
slouken@1336
   218
                insert = SDL_strchr(drive, '?');
slouken@571
   219
                if (insert != NULL)
slouken@571
   220
                {
slouken@571
   221
                    *insert = j;
slouken@571
   222
                }
slouken@571
   223
                switch (CheckDrive(drive, &stbuf))
slouken@571
   224
                {
slouken@571
   225
                    /* Drive exists and is a CD-ROM */
slouken@571
   226
                    case 1:
slouken@571
   227
                             AddDrive(drive, &stbuf);
slouken@571
   228
                             break;
slouken@571
   229
                    /* Drive exists, but isn't a CD-ROM */
slouken@571
   230
                    case 0:
slouken@571
   231
                             break;
slouken@571
   232
                    /* Drive doesn't exist */
slouken@571
   233
                    case -1:
slouken@571
   234
                             exists = 0;
slouken@571
   235
                             break;
slouken@571
   236
                }
slouken@571
   237
            }
slouken@571
   238
        }
slouken@571
   239
        else
slouken@571
   240
        {
slouken@1338
   241
            SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", checklist[i]);
slouken@571
   242
            if (CheckDrive(drive, &stbuf) > 0)
slouken@571
   243
            {
slouken@571
   244
                AddDrive(drive, &stbuf);
slouken@571
   245
            }
slouken@571
   246
        }
slouken@571
   247
    }
slouken@571
   248
    return(0);
slouken@0
   249
}
slouken@0
   250
slouken@0
   251
static const char *SDL_SYS_CDName(int drive)
slouken@0
   252
{
slouken@571
   253
    return(SDL_cdlist[drive]);
slouken@0
   254
}
slouken@0
   255
slouken@0
   256
static int SDL_SYS_CDOpen(int drive)
slouken@0
   257
{
slouken@571
   258
    int handle;
slouken@571
   259
slouken@571
   260
    handle=open(SDL_cdlist[drive], QNX_CD_OPENMODE);
slouken@571
   261
slouken@571
   262
    if (handle>0)
slouken@571
   263
    {
slouken@571
   264
        SDL_cdopen[drive]=handle;
slouken@571
   265
    }
slouken@571
   266
slouken@571
   267
    return (handle);
slouken@0
   268
}
slouken@0
   269
slouken@0
   270
static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
slouken@0
   271
{
slouken@571
   272
    cdrom_read_toc_t toc;
slouken@571
   273
    int i, okay;
slouken@0
   274
slouken@571
   275
    okay = 0;
slouken@571
   276
    if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL) == 0)
slouken@571
   277
    {
slouken@571
   278
        cdrom->numtracks = toc.last_track - toc.first_track + 1;
slouken@571
   279
        if (cdrom->numtracks > SDL_MAX_TRACKS)
slouken@571
   280
        {
slouken@571
   281
            cdrom->numtracks = SDL_MAX_TRACKS;
slouken@571
   282
        }
slouken@571
   283
        /* Read all the track TOC entries */
slouken@571
   284
        for (i=0; i<=cdrom->numtracks; ++i)
slouken@571
   285
        {
slouken@571
   286
            if (i == cdrom->numtracks)
slouken@571
   287
            {
slouken@571
   288
                cdrom->track[i].id = CDROM_LEADOUT;
slouken@571
   289
            }
slouken@571
   290
            else
slouken@571
   291
            {
slouken@571
   292
                cdrom->track[i].id = toc.first_track+i;
slouken@571
   293
            }
slouken@571
   294
slouken@571
   295
            cdrom->track[i].type = toc.toc_entry[i].control_adr & 0x0F;
slouken@571
   296
            cdrom->track[i].offset = toc.toc_entry[i].addr.lba;
slouken@571
   297
            cdrom->track[i].length = 0;
slouken@571
   298
slouken@571
   299
            if (i > 0)
slouken@571
   300
            {
slouken@571
   301
                 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset;
slouken@571
   302
            }
slouken@571
   303
        }
slouken@571
   304
        if (i == (cdrom->numtracks+1))
slouken@571
   305
        {
slouken@571
   306
            okay = 1;
slouken@571
   307
        }
slouken@571
   308
    }
slouken@571
   309
    return (okay ? 0 : -1);
slouken@0
   310
}
slouken@0
   311
slouken@0
   312
/* Get CD-ROM status */
slouken@0
   313
static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
slouken@0
   314
{
slouken@571
   315
    CDstatus status;
slouken@0
   316
slouken@571
   317
    cdrom_read_toc_t toc;
slouken@571
   318
    cdrom_subch_data_t info;
slouken@571
   319
    cam_devinfo_t dinfo;
slouken@571
   320
slouken@571
   321
    int devctlret=0;
slouken@571
   322
    int drive=-1;
slouken@571
   323
    int i;
slouken@571
   324
    int eagaincnt=0;
slouken@571
   325
slouken@571
   326
    /* check media presence before read subchannel call, some cdroms can lockups */
slouken@571
   327
    /* if no media, while calling read subchannel functions.                     */
slouken@571
   328
    devctlret=devctl(cdrom->id, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL);
slouken@571
   329
slouken@571
   330
    if (devctlret==EOK)
slouken@571
   331
    {
slouken@571
   332
        if ((dinfo.flags & DEV_NO_MEDIA)!=0)
slouken@571
   333
        {
slouken@571
   334
            status = CD_TRAYEMPTY;
slouken@571
   335
            if (position)
slouken@571
   336
            {
slouken@571
   337
                *position = 0;
slouken@571
   338
            }
slouken@571
   339
            return (status);
slouken@571
   340
        }
slouken@571
   341
    }
slouken@571
   342
slouken@571
   343
    /* if media exists, then do other stuff */
slouken@571
   344
slouken@1336
   345
    SDL_memset(&info, 0x00, sizeof(info));
slouken@571
   346
    info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION;
slouken@571
   347
slouken@571
   348
    do {
slouken@571
   349
        devctlret=devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), NULL);
slouken@571
   350
        if (devctlret==EIO)
slouken@571
   351
        {
slouken@571
   352
            /* big workaround for media change, handle is unusable after that,
slouken@571
   353
               that bug was found in QNX 6.2, 6.2.1 is not released yet.    */
slouken@571
   354
slouken@571
   355
            for (i=0; i<MAX_DRIVES; i++)
slouken@571
   356
            {
slouken@571
   357
                if (SDL_cdopen[i]==cdrom->id)
slouken@571
   358
                {
slouken@571
   359
                    drive=i;
slouken@571
   360
                    break;
slouken@571
   361
                }
slouken@571
   362
            }
slouken@571
   363
            if (drive==-1)
slouken@571
   364
            {
slouken@571
   365
               /* that cannot happen, but ... */
slouken@571
   366
               break;
slouken@571
   367
            }
slouken@571
   368
            close(cdrom->id);
slouken@571
   369
            cdrom->id=open(SDL_cdlist[drive], QNX_CD_OPENMODE);
slouken@571
   370
            devctlret=EAGAIN;
slouken@571
   371
        }
slouken@571
   372
        if (devctlret==EAGAIN)
slouken@571
   373
        {
slouken@571
   374
            eagaincnt++;
slouken@571
   375
        }
slouken@571
   376
        if (eagaincnt==2)
slouken@571
   377
        {
slouken@571
   378
            /* workaround for broken cdroms, which can return always EAGAIN when its not ready, */
slouken@571
   379
            /* that mean errornous media or just no media avail                                 */
slouken@571
   380
            devctlret=ENXIO;
slouken@571
   381
            break;
slouken@571
   382
        }
slouken@571
   383
    } while ((devctlret==EAGAIN)||(devctlret==ESTALE));
slouken@571
   384
slouken@571
   385
    if (devctlret != 0)
slouken@571
   386
    {
slouken@571
   387
        if (devctlret==ENXIO)
slouken@571
   388
        {
slouken@571
   389
            status = CD_TRAYEMPTY;
slouken@571
   390
        }
slouken@571
   391
        else
slouken@571
   392
        {
slouken@571
   393
            status = CD_ERROR;
slouken@571
   394
        }
slouken@571
   395
    }
slouken@571
   396
    else
slouken@571
   397
    {
slouken@571
   398
        switch (info.current_position.header.audio_status)
slouken@571
   399
        {
slouken@571
   400
            case CDROM_AUDIO_INVALID:
slouken@571
   401
            case CDROM_AUDIO_NO_STATUS:
slouken@571
   402
                 /* Try to determine if there's a CD available */
slouken@571
   403
                 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL)==0)
slouken@571
   404
                     status = CD_STOPPED;
slouken@571
   405
                 else
slouken@571
   406
                     status = CD_TRAYEMPTY;
slouken@571
   407
                 break;
slouken@571
   408
            case CDROM_AUDIO_COMPLETED:
slouken@571
   409
                 status = CD_STOPPED;
slouken@571
   410
                 break;
slouken@571
   411
            case CDROM_AUDIO_PLAY:
slouken@571
   412
                 status = CD_PLAYING;
slouken@571
   413
                 break;
slouken@571
   414
            case CDROM_AUDIO_PAUSED:
slouken@571
   415
                 /* Workaround buggy CD-ROM drive */
slouken@571
   416
                 if (info.current_position.data_format == CDROM_LEADOUT)
slouken@571
   417
                 {
slouken@571
   418
                     status = CD_STOPPED;
slouken@571
   419
                 }
slouken@571
   420
                 else
slouken@571
   421
                 {
slouken@571
   422
                     status = CD_PAUSED;
slouken@571
   423
                 }
slouken@571
   424
                 break;
slouken@571
   425
            default:
slouken@571
   426
                 status = CD_ERROR;
slouken@571
   427
                 break;
slouken@571
   428
        }
slouken@571
   429
    }
slouken@571
   430
slouken@571
   431
    if (position)
slouken@571
   432
    {
slouken@571
   433
       if (status==CD_PLAYING || (status==CD_PAUSED))
slouken@571
   434
       {
slouken@571
   435
           *position = MSF_TO_FRAMES(info.current_position.addr.msf.minute,
slouken@571
   436
                                     info.current_position.addr.msf.second,
slouken@571
   437
                                     info.current_position.addr.msf.frame);
slouken@571
   438
       }
slouken@571
   439
       else
slouken@571
   440
       {
slouken@571
   441
           *position = 0;
slouken@571
   442
       }
slouken@571
   443
    }
slouken@571
   444
slouken@571
   445
    return (status);
slouken@0
   446
}
slouken@0
   447
slouken@0
   448
/* Start play */
slouken@0
   449
static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
slouken@0
   450
{
slouken@571
   451
    cdrom_playmsf_t playtime;
slouken@0
   452
slouken@571
   453
    FRAMES_TO_MSF(start, &playtime.start_minute, &playtime.start_second, &playtime.start_frame);
slouken@571
   454
    FRAMES_TO_MSF(start+length, &playtime.end_minute, &playtime.end_second, &playtime.end_frame);
slouken@571
   455
slouken@571
   456
    if (devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), NULL) != 0)
slouken@571
   457
    {
slouken@571
   458
       return -1;
slouken@571
   459
    }
slouken@571
   460
    else
slouken@571
   461
    {
slouken@571
   462
       return 0;
slouken@571
   463
    }
slouken@0
   464
}
slouken@0
   465
slouken@0
   466
/* Pause play */
slouken@0
   467
static int SDL_SYS_CDPause(SDL_CD *cdrom)
slouken@0
   468
{
slouken@571
   469
    if (devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, NULL)!=0)
slouken@571
   470
    {
slouken@571
   471
       return -1;
slouken@571
   472
    }
slouken@571
   473
    else
slouken@571
   474
    {
slouken@571
   475
       return 0;
slouken@571
   476
    }
slouken@0
   477
}
slouken@0
   478
slouken@0
   479
/* Resume play */
slouken@0
   480
static int SDL_SYS_CDResume(SDL_CD *cdrom)
slouken@0
   481
{
slouken@571
   482
    if (devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, NULL)!=0)
slouken@571
   483
    {
slouken@571
   484
       return -1;
slouken@571
   485
    }
slouken@571
   486
    else
slouken@571
   487
    {
slouken@571
   488
       return 0;
slouken@571
   489
    }
slouken@0
   490
}
slouken@0
   491
slouken@0
   492
/* Stop play */
slouken@0
   493
static int SDL_SYS_CDStop(SDL_CD *cdrom)
slouken@0
   494
{
slouken@571
   495
    if (devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, NULL)!=0)
slouken@571
   496
    {
slouken@571
   497
       return -1;
slouken@571
   498
    }
slouken@571
   499
    else
slouken@571
   500
    {
slouken@571
   501
       return 0;
slouken@571
   502
    }
slouken@0
   503
}
slouken@0
   504
slouken@0
   505
/* Eject the CD-ROM */
slouken@0
   506
static int SDL_SYS_CDEject(SDL_CD *cdrom)
slouken@0
   507
{
slouken@571
   508
    if (devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, NULL)!=0)
slouken@571
   509
    {
slouken@571
   510
       return -1;
slouken@571
   511
    }
slouken@571
   512
    else
slouken@571
   513
    {
slouken@571
   514
       return 0;
slouken@571
   515
    }
slouken@0
   516
}
slouken@0
   517
slouken@0
   518
/* Close the CD-ROM handle */
slouken@0
   519
static void SDL_SYS_CDClose(SDL_CD *cdrom)
slouken@0
   520
{
slouken@571
   521
    int i;
slouken@571
   522
slouken@571
   523
    for (i=0; i<MAX_DRIVES; i++)
slouken@571
   524
    {
slouken@571
   525
       if (SDL_cdopen[i]==cdrom->id)
slouken@571
   526
       {
slouken@571
   527
           SDL_cdopen[i]=0;
slouken@571
   528
           break;
slouken@571
   529
       }
slouken@571
   530
    }
slouken@571
   531
slouken@571
   532
    close(cdrom->id);
slouken@0
   533
}
slouken@0
   534
slouken@0
   535
void SDL_SYS_CDQuit(void)
slouken@0
   536
{
slouken@571
   537
    int i;
slouken@0
   538
slouken@571
   539
    if (SDL_numcds > 0)
slouken@571
   540
    {
slouken@571
   541
        for (i=0; i<SDL_numcds; ++i)
slouken@571
   542
        {
slouken@1336
   543
            SDL_free(SDL_cdlist[i]);
slouken@571
   544
        }
slouken@571
   545
        SDL_numcds = 0;
slouken@571
   546
    }
slouken@0
   547
}