/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#ifdef SDL_CDROM_OPENBSD

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

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/cdio.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);

/* Some ioctl() errno values which occur when the tray is empty */
#define ERRNO_TRAYEMPTY(errno)	\
	((errno == EIO) || (errno == ENOENT) || (errno == EINVAL) || \
	 (errno == ENODEV))

/* Check a drive to see if it is a CD-ROM */
static int
CheckDrive(char *drive, struct stat *stbuf)
{
    int is_cd, cdfd;
    struct ioc_read_subchannel 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) {
            info.address_format = CD_MSF_FORMAT;
            info.data_format = CD_CURRENT_POSITION;
            info.data_len = 0;
            info.data = NULL;
            /* Under Linux, EIO occurs when a disk is not present.
               This isn't 100% reliable, so we use the USE_MNTENT
               code above instead.
             */
            if ((ioctl(cdfd, CDIOCREADSUBCHANNEL, &info) == 0) ||
                ERRNO_TRAYEMPTY(errno)) {
                is_cd = 1;
            }
            close(cdfd);
        } else if (ERRNO_TRAYEMPTY(errno))
            is_cd = 1;
    }
    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] = SDL_strdup(drive);
        if (SDL_cdlist[i] == NULL) {
            SDL_OutOfMemory();
            return;
        }
        SDL_cdmode[i] = stbuf->st_rdev;
        ++SDL_numcds;
#ifdef DEBUG_CDROM
        fprintf(stderr, "Added CD-ROM drive: %s\n", drive);
#endif
    }
}

int
SDL_SYS_CDInit(void)
{
    static char *checklist[] = {
#if defined(__OPENBSD__)
        "?0 cd?c", "cdrom", NULL
#elif defined(__NETBSD__)
        "?0 cd?d", "?0 cd?c", "cdrom", NULL
#else
        "?0 cd?c", "?0 acd?c", "cdrom", NULL
#endif
    };
    char *SDLcdrom;
    int i, j, exists;
    char drive[32];
    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 = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */
    if (SDLcdrom != NULL) {
        char *cdpath, *delim;
        size_t len = SDL_strlen(SDLcdrom) + 1;
        cdpath = SDL_stack_alloc(char, len);
        if (cdpath != NULL) {
            SDL_strlcpy(cdpath, SDLcdrom, len);
            SDLcdrom = cdpath;
            do {
                delim = SDL_strchr(SDLcdrom, ':');
                if (delim) {
                    *delim++ = '\0';
                }
                if (CheckDrive(SDLcdrom, &stbuf) > 0) {
                    AddDrive(SDLcdrom, &stbuf);
                }
                if (delim) {
                    SDLcdrom = delim;
                } else {
                    SDLcdrom = NULL;
                }
            } while (SDLcdrom);
            SDL_stack_free(cdpath);
        }

        /* If we found our drives, there's nothing left to do */
        if (SDL_numcds > 0) {
            return (0);
        }
    }

    /* Scan the system for CD-ROM drives */
    for (i = 0; checklist[i]; ++i) {
        if (checklist[i][0] == '?') {
            char *insert;
            exists = 1;
            for (j = checklist[i][1]; exists; ++j) {
                SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s",
                             &checklist[i][3]);
                insert = SDL_strchr(drive, '?');
                if (insert != NULL) {
                    *insert = j;
                }
                switch (CheckDrive(drive, &stbuf)) {
                    /* Drive exists and is a CD-ROM */
                case 1:
                    AddDrive(drive, &stbuf);
                    break;
                    /* Drive exists, but isn't a CD-ROM */
                case 0:
                    break;
                    /* Drive doesn't exist */
                case -1:
                    exists = 0;
                    break;
                }
            }
        } else {
            SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s",
                         checklist[i]);
            if (CheckDrive(drive, &stbuf) > 0) {
                AddDrive(drive, &stbuf);
            }
        }
    }
    return (0);
}

/* General ioctl() CD-ROM command function */
static int
SDL_SYS_CDioctl(int id, int command, void *arg)
{
    int retval;

    retval = ioctl(id, command, arg);
    if (retval < 0) {
        SDL_SetError("ioctl() error: %s", strerror(errno));
    }
    return (retval);
}

static const char *
SDL_SYS_CDName(int drive)
{
    return (SDL_cdlist[drive]);
}

static int
SDL_SYS_CDOpen(int drive)
{
    return (open(SDL_cdlist[drive], (O_RDONLY | O_EXCL | O_NONBLOCK), 0));
}

static int
SDL_SYS_CDGetTOC(SDL_CD * cdrom)
{
    struct ioc_toc_header toc;
    int i, okay;
    struct ioc_read_toc_entry entry;
    struct cd_toc_entry data;

    okay = 0;
    if (SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0) {
        cdrom->numtracks = toc.ending_track - toc.starting_track + 1;
        if (cdrom->numtracks > SDL_MAX_TRACKS) {
            cdrom->numtracks = SDL_MAX_TRACKS;
        }
        /* Read all the track TOC entries */
        for (i = 0; i <= cdrom->numtracks; ++i) {
            if (i == cdrom->numtracks) {
                cdrom->track[i].id = 0xAA;      /* CDROM_LEADOUT */
            } else {
                cdrom->track[i].id = toc.starting_track + i;
            }
            entry.starting_track = cdrom->track[i].id;
            entry.address_format = CD_MSF_FORMAT;
            entry.data_len = sizeof(data);
            entry.data = &data;
            if (SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCENTRYS, &entry) < 0) {
                break;
            } else {
                cdrom->track[i].type = data.control;
                cdrom->track[i].offset =
                    MSF_TO_FRAMES(data.addr.msf.minute,
                                  data.addr.msf.second, data.addr.msf.frame);
                cdrom->track[i].length = 0;
                if (i > 0) {
                    cdrom->track[i - 1].length =
                        cdrom->track[i].offset - cdrom->track[i - 1].offset;
                }
            }
        }
        if (i == (cdrom->numtracks + 1)) {
            okay = 1;
        }
    }
    return (okay ? 0 : -1);
}

/* Get CD-ROM status */
static CDstatus
SDL_SYS_CDStatus(SDL_CD * cdrom, int *position)
{
    CDstatus status;
    struct ioc_toc_header toc;
    struct ioc_read_subchannel info;
    struct cd_sub_channel_info data;

    info.address_format = CD_MSF_FORMAT;
    info.data_format = CD_CURRENT_POSITION;
    info.track = 0;
    info.data_len = sizeof(data);
    info.data = &data;
    if (ioctl(cdrom->id, CDIOCREADSUBCHANNEL, &info) < 0) {
        if (ERRNO_TRAYEMPTY(errno)) {
            status = CD_TRAYEMPTY;
        } else {
            status = CD_ERROR;
        }
    } else {
        switch (data.header.audio_status) {
        case CD_AS_AUDIO_INVALID:
        case CD_AS_NO_STATUS:
            /* Try to determine if there's a CD available */
            if (ioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0)
                status = CD_STOPPED;
            else
                status = CD_TRAYEMPTY;
            break;
        case CD_AS_PLAY_COMPLETED:
            status = CD_STOPPED;
            break;
        case CD_AS_PLAY_IN_PROGRESS:
            status = CD_PLAYING;
            break;
        case CD_AS_PLAY_PAUSED:
            status = CD_PAUSED;
            break;
        default:
            status = CD_ERROR;
            break;
        }
    }
    if (position) {
        if (status == CD_PLAYING || (status == CD_PAUSED)) {
            *position =
                MSF_TO_FRAMES(data.what.position.absaddr.msf.minute,
                              data.what.position.absaddr.msf.second,
                              data.what.position.absaddr.msf.frame);
        } else {
            *position = 0;
        }
    }
    return (status);
}

/* Start play */
static int
SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length)
{
    struct ioc_play_msf playtime;

    FRAMES_TO_MSF(start,
                  &playtime.start_m, &playtime.start_s, &playtime.start_f);
    FRAMES_TO_MSF(start + length,
                  &playtime.end_m, &playtime.end_s, &playtime.end_f);
#ifdef DEBUG_CDROM
    fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n",
            playtime.start_m, playtime.start_s, playtime.start_f,
            playtime.end_m, playtime.end_s, playtime.end_f);
#endif
    ioctl(cdrom->id, CDIOCSTART, 0);
    return (SDL_SYS_CDioctl(cdrom->id, CDIOCPLAYMSF, &playtime));
}

/* Pause play */
static int
SDL_SYS_CDPause(SDL_CD * cdrom)
{
    return (SDL_SYS_CDioctl(cdrom->id, CDIOCPAUSE, 0));
}

/* Resume play */
static int
SDL_SYS_CDResume(SDL_CD * cdrom)
{
    return (SDL_SYS_CDioctl(cdrom->id, CDIOCRESUME, 0));
}

/* Stop play */
static int
SDL_SYS_CDStop(SDL_CD * cdrom)
{
    return (SDL_SYS_CDioctl(cdrom->id, CDIOCSTOP, 0));
}

/* Eject the CD-ROM */
static int
SDL_SYS_CDEject(SDL_CD * cdrom)
{
    return (SDL_SYS_CDioctl(cdrom->id, CDIOCEJECT, 0));
}

/* Close the CD-ROM handle */
static void
SDL_SYS_CDClose(SDL_CD * cdrom)
{
    close(cdrom->id);
}

void
SDL_SYS_CDQuit(void)
{
    int i;

    if (SDL_numcds > 0) {
        for (i = 0; i < SDL_numcds; ++i) {
            SDL_free(SDL_cdlist[i]);
        }
        SDL_numcds = 0;
    }
}

#endif /* SDL_CDROM_OPENBSD */
/* vi: set ts=4 sw=4 expandtab: */
