summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/cdrom/Makefile.am2
-rw-r--r--sys/cdrom/gstcdplayer.c85
-rw-r--r--sys/cdrom/gstcdplayer.h6
-rw-r--r--sys/cdrom/gstcdplayer_ioctl.c168
-rw-r--r--sys/cdrom/gstcdplayer_ioctl.h18
-rw-r--r--sys/cdrom/gstcdplayer_ioctl_bsd.h338
-rw-r--r--sys/cdrom/gstcdplayer_ioctl_irix.h109
-rw-r--r--sys/cdrom/gstcdplayer_ioctl_solaris.h204
8 files changed, 807 insertions, 123 deletions
diff --git a/sys/cdrom/Makefile.am b/sys/cdrom/Makefile.am
index a43c1dcb..c3d0600d 100644
--- a/sys/cdrom/Makefile.am
+++ b/sys/cdrom/Makefile.am
@@ -7,4 +7,4 @@ libgstcdplayer_la_CFLAGS = $(GST_CFLAGS)
libgstcdplayer_la_LIBADD =
libgstcdplayer_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-noinst_HEADERS = gstcdplayer.h gstcdplayer_ioctl.h
+noinst_HEADERS = gstcdplayer.h gstcdplayer_ioctl.h gstcdplayer_ioctl_solaris.h gstcdplayer_ioctl_bsd.h
diff --git a/sys/cdrom/gstcdplayer.c b/sys/cdrom/gstcdplayer.c
index 2bbbddb2..7852276f 100644
--- a/sys/cdrom/gstcdplayer.c
+++ b/sys/cdrom/gstcdplayer.c
@@ -17,8 +17,9 @@
* Boston, MA 02111-1307, USA.
*/
+/* #define GST_DEBUG_ENABLED */
+
#include "gstcdplayer.h"
-#include "gstcdplayer_ioctl.h"
/* props */
enum {
@@ -26,10 +27,14 @@ enum {
ARG_DEVICE,
ARG_NUM_TRACKS,
ARG_START_TRACK,
+ ARG_END_TRACK,
+ ARG_CURRENT_TRACK,
+ ARG_CDDB_DISCID,
};
/* signals */
enum {
+ TRACK_CHANGE,
LAST_SIGNAL,
};
@@ -38,6 +43,7 @@ static void cdplayer_init(CDPlayer *cdp);
static void cdplayer_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *spec);
static void cdplayer_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *spec);
static void cdplayer_dispose(GObject *object);
+static gboolean cdplayer_iterate(GstBin *bin);
static GstElementStateReturn cdplayer_change_state(GstElement *element);
static gboolean plugin_init(GModule *module,GstPlugin *plugin);
@@ -45,7 +51,7 @@ static gboolean plugin_init(GModule *module,GstPlugin *plugin);
static GstElementClass *parent_class;
-/* static guint cdplayer_signals[LAST_SIGNAL] = {0}; */
+ static guint cdplayer_signals[LAST_SIGNAL] = {0};
static GstElementDetails cdplayer_details = {
@@ -87,19 +93,27 @@ static void cdplayer_class_init(CDPlayerClass *klass)
{
GObjectClass *gobject_klass;
GstElementClass *gstelement_klass;
+ GstBinClass *gstbin_klass;
gobject_klass = (GObjectClass *)klass;
gstelement_klass = (GstElementClass *)klass;
+ gstbin_klass = (GstBinClass *)klass;
parent_class = g_type_class_ref(gst_bin_get_type());
gobject_klass->dispose = GST_DEBUG_FUNCPTR(cdplayer_dispose);
gstelement_klass->change_state = GST_DEBUG_FUNCPTR(cdplayer_change_state);
+ gstbin_klass->iterate = GST_DEBUG_FUNCPTR(cdplayer_iterate);
g_object_class_install_property(gobject_klass,ARG_DEVICE,g_param_spec_string("device","device","CDROM device",NULL,G_PARAM_READWRITE));
g_object_class_install_property(gobject_klass,ARG_NUM_TRACKS,g_param_spec_int("num_tracks","num_tracks","Number of Tracks",G_MININT,G_MAXINT,0,G_PARAM_READABLE));
- g_object_class_install_property(gobject_klass,ARG_START_TRACK,g_param_spec_int("start_track","start_track","Track to start playback on",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READABLE));
+ g_object_class_install_property(gobject_klass,ARG_START_TRACK,g_param_spec_int("start_track","start_track","Track to start playback on",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_klass,ARG_END_TRACK,g_param_spec_int("end_track","end_track","Track to end playback on",0,CDPLAYER_MAX_TRACKS-1,0,G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_klass,ARG_CURRENT_TRACK,g_param_spec_int("current_track","current_track","Current track playing",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READABLE));
+ g_object_class_install_property(gobject_klass,ARG_CDDB_DISCID,g_param_spec_uint("cddb_discid","cddb_discid","CDDB Disc ID",0,G_MAXUINT,1,G_PARAM_READABLE));
+
+ cdplayer_signals[TRACK_CHANGE] = g_signal_new("track_change",G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,G_STRUCT_OFFSET(CDPlayerClass,track_change),NULL,NULL,gst_marshal_VOID__INT,G_TYPE_NONE,1,G_TYPE_INT);
gobject_klass->set_property = cdplayer_set_property;
gobject_klass->get_property = cdplayer_get_property;
@@ -112,11 +126,12 @@ static void cdplayer_init(CDPlayer *cdp)
cdp->device = g_strdup("/dev/cdrom");
cdp->num_tracks = -1;
cdp->start_track = 1;
+ cdp->end_track = 0;
+ cdp->current_track = 1;
cdp->paused = FALSE;
- GST_FLAG_SET(cdp,GST_BIN_FLAG_MANAGER);
- GST_FLAG_SET(cdp,GST_BIN_SELF_SCHEDULABLE);
+// GST_FLAG_SET(cdp,GST_BIN_FLAG_MANAGER);
return;
}
@@ -140,7 +155,12 @@ static void cdplayer_set_property(GObject *object,guint prop_id,const GValue *va
break;
case ARG_START_TRACK:
// FIXME prolly should uhh.. restart play, i guess... or something whatever
- cdp->start_track = g_value_get_int(value);
+// FIXME we should only set current_track if its not playing...
+ cdp->current_track = cdp->start_track = g_value_get_int(value);
+ break;
+ case ARG_END_TRACK:
+// FIXME prolly should restart play, maybe, or try to set it without interrupt..
+ cdp->end_track = g_value_get_int(value);
break;
default:
break;
@@ -168,6 +188,13 @@ static void cdplayer_get_property(GObject *object,guint prop_id,GValue *value,GP
case ARG_START_TRACK:
g_value_set_int(value,cdp->start_track);
break;
+ case ARG_END_TRACK:
+ g_value_set_int(value,cdp->end_track);
+ case ARG_CURRENT_TRACK:
+ g_value_set_int(value,cdp->current_track);
+ break;
+ case ARG_CDDB_DISCID:
+ g_value_set_uint(value,cdp->cddb_discid);
default:
break;
}
@@ -182,20 +209,49 @@ static void cdplayer_dispose(GObject *object)
g_return_if_fail(GST_IS_CDPLAYER(object));
cdp = CDPLAYER(object);
-
- G_OBJECT_CLASS(parent_class)->dispose(object);
-
g_free(cdp->device);
- if (GST_ELEMENT_SCHED(cdp)) {
- gst_scheduler_reset(GST_ELEMENT_SCHED(cdp));
- gst_object_unref(GST_OBJECT(GST_ELEMENT_SCHED(cdp)));
- GST_ELEMENT_SCHED(cdp) = NULL;
+ if (G_OBJECT_CLASS(parent_class)->dispose) {
+ G_OBJECT_CLASS(parent_class)->dispose(object);
}
return;
}
+static gboolean cdplayer_iterate(GstBin *bin)
+{
+ CDPlayer *cdp = CDPLAYER(bin);
+ gint current_track;
+
+ switch (cd_status(CDPLAYER_CD(cdp))) {
+ case CD_PLAYING:
+ current_track = cd_current_track(CDPLAYER_CD(cdp));
+ if (current_track > cdp->end_track && cdp->end_track != 0) {
+ return FALSE;
+ }
+
+ if (current_track != -1 && current_track != cdp->current_track) {
+ cdp->current_track = current_track;
+ g_signal_emit(G_OBJECT(cdp),cdplayer_signals[TRACK_CHANGE],0,cdp->current_track);
+ }
+
+ return TRUE;
+ break;
+ case CD_ERROR:
+ gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PAUSED);
+ return FALSE;
+ break;
+ case CD_COMPLETED:
+ gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PAUSED);
+ gst_element_set_eos(GST_ELEMENT(bin));
+ return FALSE;
+ break;
+ }
+
+ return FALSE;
+}
+
+
static GstElementStateReturn cdplayer_change_state(GstElement *element)
{
CDPlayer *cdp;
@@ -213,6 +269,7 @@ static GstElementStateReturn cdplayer_change_state(GstElement *element)
return GST_STATE_FAILURE;
}
cdp->num_tracks = cdp->cd.num_tracks;
+ cdp->cddb_discid = cd_cddb_discid(CDPLAYER_CD(cdp));
}
break;
case GST_STATE_PAUSED:
@@ -234,7 +291,7 @@ static GstElementStateReturn cdplayer_change_state(GstElement *element)
cdp->paused = FALSE;
} else {
- if (cd_start(CDPLAYER_CD(cdp),cdp->start_track) == FALSE) {
+ if (cd_start(CDPLAYER_CD(cdp),cdp->start_track,cdp->end_track) == FALSE) {
return GST_STATE_FAILURE;
}
}
diff --git a/sys/cdrom/gstcdplayer.h b/sys/cdrom/gstcdplayer.h
index 5da5527d..39aaaf43 100644
--- a/sys/cdrom/gstcdplayer.h
+++ b/sys/cdrom/gstcdplayer.h
@@ -45,7 +45,10 @@ struct _CDPlayer {
/* properties */
gchar *device;
gint num_tracks;
- guint start_track;
+ gint start_track;
+ gint end_track;
+ gint current_track;
+ guint32 cddb_discid;
/* private */
struct cd cd;
@@ -56,6 +59,7 @@ struct _CDPlayerClass {
GstBinClass parent_class;
/* signal callbacks */
+ void (*track_change) (GstElement *element,guint track);
};
GType cdplayer_get_type(void);
diff --git a/sys/cdrom/gstcdplayer_ioctl.c b/sys/cdrom/gstcdplayer_ioctl.c
index 2da746a2..532d9fc1 100644
--- a/sys/cdrom/gstcdplayer_ioctl.c
+++ b/sys/cdrom/gstcdplayer_ioctl.c
@@ -29,137 +29,97 @@
#include <sys/ioctl.h>
#include <errno.h>
-#include <linux/cdrom.h>
-
-
-gboolean cd_init(struct cd *cd,const gchar *device)
-{
- struct cdrom_tochdr toc_header;
- struct cdrom_tocentry toc_entry;
- guint i;
-
- cd->fd = open(device,O_RDONLY | O_NONBLOCK);
-
- if (cd->fd == -1) {
- return FALSE;
- }
-
- /* get the toc header information */
- if (ioctl(cd->fd,CDROMREADTOCHDR,&toc_header) != 0) {
- return FALSE;
- }
-
- /* read each entry in the toc header */
- for (i = 1; i < toc_header.cdth_trk1; i++) {
- toc_entry.cdte_format = CDROM_MSF;
- toc_entry.cdte_track = i;
- if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) {
- return FALSE;
- }
+/* private functions */
+static void cd_fix_track_range(struct cd *cd,gint *start_track,gint *end_track);
+static gint cddb_sum(gint n);
- cd->tracks[i].minute = toc_entry.cdte_addr.msf.minute;
- cd->tracks[i].second = toc_entry.cdte_addr.msf.second;
- cd->tracks[i].frame = toc_entry.cdte_addr.msf.frame;
- cd->tracks[i].data_track = (toc_entry.cdte_ctrl == CDROM_DATA_TRACK);
- }
-
- /* read the leadout */
- toc_entry.cdte_track = CDROM_LEADOUT;
- toc_entry.cdte_format = CDROM_MSF;
- if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) {
- return FALSE;
- }
- cd->tracks[LEADOUT].minute = toc_entry.cdte_addr.msf.minute;
- cd->tracks[LEADOUT].second = toc_entry.cdte_addr.msf.second;
- cd->tracks[LEADOUT].frame = toc_entry.cdte_addr.msf.frame;
- cd->num_tracks = toc_header.cdth_trk1;
- return TRUE;
-}
-
-gboolean cd_start(struct cd *cd,guint start_track)
+#ifdef HAVE_LINUX_CDROM_H
+#include <linux/cdrom.h>
+#elif define HAVE_SYS_CDIO_H
+#include <sys/cdio.h>
+/*
+irix cdaudio works quite a bit differently than ioctl(), so its not ready
+#elif define HAVE_DMEDIA_CDAUDIO_H
+#include <dmedia/cdaudio.h>
+*/
+#endif
+
+/* these headers define low level functions:
+ gboolean cd_init(struct cd *cd,const gchar *device);
+ gboolean cd_start(struct cd *cd,gint start_track,gint end_track);
+ gboolean cd_pause(struct cd *cd);
+ gboolean cd_resume(struct cd *cd);
+ gboolean cd_stop(struct cd *cd);
+ CDStatus cd_status(struct cd *cd);
+ gint cd_current_track(struct cd *cd);
+ gboolean cd_close(struct cd *cd);
+*/
+#ifdef HAVE_CDROM_SOLARIS
+#include "gstcdplayer_ioctl_solaris.h"
+#elif defined HAVE_CDROM_BSD
+#include "gstcdplayer_ioctl_bsd.h"
+/*
+#elif define HAVE_CDROM_IRIX
+#include "gstcdplayer_ioctl_irix.h"
+*/
+#endif
+
+static void cd_fix_track_range(struct cd *cd,gint *start_track,gint *end_track)
{
- struct cdrom_msf msf;
-
- if (cd->fd == -1) {
- return FALSE;
+ if (*start_track <= 0) {
+ *start_track = 1;
}
- if (start_track <= 0) {
- start_track = 1;
+ if (*start_track > cd->num_tracks) {
+ *start_track = cd->num_tracks;
}
- if (start_track > cd->num_tracks) {
- start_track = cd->num_tracks;
+ if (*end_track < *start_track && *end_track != LEADOUT) {
+ *end_track = *start_track;
}
- msf.cdmsf_min0 = cd->tracks[start_track].minute;
- msf.cdmsf_sec0 = cd->tracks[start_track].second;
- msf.cdmsf_frame0 = cd->tracks[start_track].frame;
-
- msf.cdmsf_min1 = cd->tracks[LEADOUT].minute;
- msf.cdmsf_sec1 = cd->tracks[LEADOUT].second;
- msf.cdmsf_frame1 = cd->tracks[LEADOUT].frame;
-
- if (ioctl(cd->fd,CDROMPLAYMSF,&msf) != 0) {
- return FALSE;
+ if (*end_track > cd->num_tracks || *end_track + 1 > cd->num_tracks) {
+ *end_track = LEADOUT;
}
- return TRUE;
+ return;
}
-gboolean cd_pause(struct cd *cd)
-{
- if (cd->fd == -1) {
- return FALSE;
- }
- if (ioctl(cd->fd,CDROMPAUSE,NULL) != 0) {
- return FALSE;
- }
+/* this cddb info is from
+ http://www.freedb.org/modules.php?name=Sections&sop=viewarticle&artid=6
- return TRUE;
-}
-
-gboolean cd_resume(struct cd *cd)
+ this will probably be of interest to anyone wishing to actually use the discid
+ http://www.freedb.org/modules.php?name=Sections&sop=viewarticle&artid=28
+*/
+static gint cddb_sum(gint n)
{
- if (cd->fd == -1) {
- return FALSE;
- }
+ gint ret = 0;
- if (ioctl(cd->fd,CDROMRESUME,NULL) != 0) {
- return FALSE;
+ while (n > 0) {
+ ret += n % 10;
+ n /= 10;
}
- return TRUE;
+ return ret;
}
-gboolean cd_stop(struct cd *cd)
+guint32 cd_cddb_discid(struct cd *cd)
{
- if (cd->fd == -1) {
- return FALSE;
- }
-
- if (ioctl(cd->fd,CDROMSTOP,NULL) != 0) {
- return FALSE;
- }
-
- return TRUE;
-}
-
+ guint i;
+ guint n = 0;
+ guint t;
-gboolean cd_close(struct cd *cd)
-{
- if (cd->fd == -1) {
- return TRUE;
+ for (i = 1; i <= cd->num_tracks; i++) {
+ n += cddb_sum(cd->tracks[i].minute * 60 + cd->tracks[i].second);
}
- if (close(cd->fd) != 0) {
- return FALSE;
- }
+ t = (cd->tracks[LEADOUT].minute * 60 + cd->tracks[LEADOUT].second) - (cd->tracks[1].minute * 60 + cd->tracks[1].second);
- return TRUE;
+ return ((n % 0xff) << 24 | t << 8 | (cd->num_tracks));
}
+
diff --git a/sys/cdrom/gstcdplayer_ioctl.h b/sys/cdrom/gstcdplayer_ioctl.h
index 7d96925c..e9fa1a63 100644
--- a/sys/cdrom/gstcdplayer_ioctl.h
+++ b/sys/cdrom/gstcdplayer_ioctl.h
@@ -17,8 +17,8 @@
* Boston, MA 02111-1307, USA.
*/
-#ifndef __CDPLAYER_IOCTL_H__
-#define __CDPLAYER_IOCTL_H__
+#ifndef __CDPLAYER_LL_H__
+#define __CDPLAYER_LL_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -32,6 +32,12 @@
#define CDPLAYER_MAX_TRACKS 128
+typedef enum {
+ CD_PLAYING,
+ CD_COMPLETED,
+ CD_ERROR
+} CDStatus;
+
struct cd_msf {
guint8 minute;
guint8 second;
@@ -46,13 +52,19 @@ struct cd {
struct cd_msf tracks[CDPLAYER_MAX_TRACKS];
};
+
+/* these are defined by the different cdrom type header files */
gboolean cd_init(struct cd *cd,const gchar *device);
-gboolean cd_start(struct cd *cd,guint start_track);
+gboolean cd_start(struct cd *cd,gint start_track,gint end_track);
gboolean cd_pause(struct cd *cd);
gboolean cd_resume(struct cd *cd);
gboolean cd_stop(struct cd *cd);
+CDStatus cd_status(struct cd *cd);
+gint cd_current_track(struct cd *cd);
gboolean cd_close(struct cd *cd);
+guint32 cd_cddb_discid(struct cd *cd);
+
#endif
diff --git a/sys/cdrom/gstcdplayer_ioctl_bsd.h b/sys/cdrom/gstcdplayer_ioctl_bsd.h
new file mode 100644
index 00000000..371c1300
--- /dev/null
+++ b/sys/cdrom/gstcdplayer_ioctl_bsd.h
@@ -0,0 +1,338 @@
+/* gstcdplay
+ * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.edu>
+
+ * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CDROM_BSD_NETBSD /* net & open */
+gboolean cd_init(struct cd *cd,const gchar *device)
+{
+ struct ioc_toc_header toc_header;
+ struct ioc_read_toc_entry toc_entry;
+ struct cd_toc_entry toc_entry_data;
+ guint i;
+
+ cd->fd = open(device,O_RDONLY | O_NONBLOCK);
+
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ /* get the toc header information */
+ if (ioctl(cd->fd,CDIOREADTOCHDR,&toc_header) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ /* read each entry in the toc header */
+ for (i = 1; i <= toc_header.ending_track; i++) {
+ toc_entry.address_format = CD_MSF_FORMAT;
+ toc_entry.starting_track = i;
+ toc_entry.data = &toc_entry_data;
+ toc_entry.data_len = sizeof(toc_entry_data);
+
+ if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[i].minute = toc_entry.data->addr.msf.minute;
+ cd->tracks[i].second = toc_entry.data->addr.msf.second;
+ cd->tracks[i].frame = toc_entry.data->addr.msf.frame;
+ cd->tracks[i].data_track = (toc_entry.data->control & 4) == 4;
+ }
+
+ /* read the leadout */
+ toc_entry.address_format = CD_MSF_FORMAT;
+ toc_entry.starting_track = 0xAA; /* leadout */
+ toc_entry.data = &toc_entry_data;
+ toc_entry.data_len = sizeof(toc_entry_data);
+
+ if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[LEADOUT].minute = toc_entry.data->addr.msf.minute;
+ cd->tracks[LEADOUT].second = toc_entry.data->addr.msf.second;
+ cd->tracks[LEADOUT].frame = toc_entry.data->addr.msf.frame;
+
+ cd->num_tracks = toc_header.ending_track;
+
+ return TRUE;
+}
+#elif defined HAVE_CDROM_BSD_DARWIN
+gboolean cd_init(struct cd *cd,const gchar *device)
+{
+ struct ioc_toc_header toc_header;
+ struct ioc_read_toc_entry toc_entry;
+ guint i;
+
+ cd->fd = open(device,O_RDONLY | O_NONBLOCK);
+
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ /* get the toc header information */
+ if (ioctl(cd->fd,CDIOREADTOCHDR,&toc_header) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ /* read each entry in the toc header */
+ for (i = 1; i <= toc_header.ending_track; i++) {
+ toc_entry.address_format = CD_MSF_FORMAT;
+ toc_entry.starting_track = i;
+
+ if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[i].minute = toc_entry.data->addr[1];
+ cd->tracks[i].second = toc_entry.data->addr[2];
+ cd->tracks[i].frame = toc_entry.data->addr[3];
+ cd->tracks[i].data_track = (toc_entry.data->control & 4) == 4;
+ }
+
+ /* read the leadout */
+ toc_entry.address_format = CD_MSF_FORMAT;
+ toc_entry.starting_track = 0xAA; /* leadout */
+ toc_entry.data = &toc_entry_data;
+ toc_entry.data_len = sizeof(toc_entry_data);
+
+ if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[LEADOUT].minute = toc_entry.data->addr[1];
+ cd->tracks[LEADOUT].second = toc_entry.data->addr[2];
+ cd->tracks[LEADOUT].frame = toc_entry.data->addr[3];
+
+ cd->num_tracks = toc_header.ending_track;
+
+ return TRUE;
+}
+#else /* free */
+gboolean cd_init(struct cd *cd,const gchar *device)
+{
+ struct ioc_toc_header toc_header;
+ struct ioc_read_toc_entry toc_entry;
+ guint i;
+
+ cd->fd = open(device,O_RDONLY | O_NONBLOCK);
+
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ /* get the toc header information */
+ if (ioctl(cd->fd,CDIOREADTOCHDR,&toc_header) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ /* read each entry in the toc header */
+ for (i = 1; i <= toc_header.ending_track; i++) {
+ toc_entry.address_format = CD_MSF_FORMAT;
+ toc_entry.starting_track = i;
+
+ if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[i].minute = toc_entry.entry.addr.msf.minute;
+ cd->tracks[i].second = toc_entry.entry.addr.msf.second;
+ cd->tracks[i].frame = toc_entry.entry.addr.msf.frame;
+ cd->tracks[i].data_track = (toc_entry.data->control & 4) == 4;
+ }
+
+ /* read the leadout */
+ toc_entry.address_format = CD_MSF_FORMAT;
+ toc_entry.starting_track = 0xAA; /* leadout */
+ toc_entry.data = &toc_entry_data;
+ toc_entry.data_len = sizeof(toc_entry_data);
+
+ if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[LEADOUT].minute = toc_entry.entry.addr.msf.minute;
+ cd->tracks[LEADOUT].second = toc_entry.entry.addr.msf.second;
+ cd->tracks[LEADOUT].frame = toc_entry.entry.addr.msf.frame;
+
+ cd->num_tracks = toc_header.ending_track;
+
+ return TRUE;
+}
+#endif
+
+gboolean cd_start(struct cd *cd,gint start_track,gint end_track)
+{
+ struct ioc_play_msf msf;
+
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ cd_fix_track_range(cd,&start_track,&end_track);
+
+ msf.start_m = cd->tracks[start_track].minute;
+ msf.start_s = cd->tracks[start_track].second;
+ msf.start_f = cd->tracks[start_track].frame;
+
+ if (end_track == LEADOUT) {
+ msf.end_m = cd->tracks[end_track].minute;
+ msf.end_s = cd->tracks[end_track].second;
+ msf.end_f = cd->tracks[end_track].frame;
+ } else {
+ msf.end_m = cd->tracks[end_track+1].minute;
+ msf.end_s = cd->tracks[end_track+1].second;
+ msf.end_f = cd->tracks[end_track+1].frame;
+ }
+
+ if (ioctl(cd->fd,CDIOCPLAYMSF,&msf) != 0) {
+ return FALSE;
+ }
+
+}
+
+gboolean cd_pause(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ if (ioctl(cd->fd,CDIOCPAUSE,NULL) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean cd_resume(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ if (ioctl(cd->fd,CDIOCRESUME,NULL) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean cd_stop(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ if (ioctl(cd->fd,CDIOCSTOP,NULL) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -1 for error, 0 for not playing, 1 for playing */
+CDStatus cd_status(struct cd *cd)
+{
+ struct ioc_read_subchannel sub_channel;
+ struct cd_sub_channel_info sub_channel_info;
+
+ if (cd->fd == -1) {
+ return -1;
+ }
+
+ sub_channel.address_format = CD_MSF_FORMAT;
+ sub_channel.data_format = CD_CURRENT_POSITION;
+ sub_channel.track = 0;
+ sub_channel.data = &sub_channel_info;
+ sub_channel.data_len = sizeof(sub_channel_info);
+
+ if (ioctl(cd->fd,CDIOCREADSUBCHANNEL,&sub_channel) != 0) {
+ return FALSE;
+ }
+
+ switch (sub_channel.data->header.audio_status) {
+ case CD_AS_PLAY_IN_PROGRESS:
+ case CD_AS_PLAY_PAUSED:
+ return CD_PLAYING;
+ break;
+ case CD_AS_PLAY_COMPLETED:
+ return CD_COMPLETED;
+ break;
+ case CD_AS_AUDIO_INVALID:
+ case CD_AS_PLAY_ERROR:
+ default:
+ return CD_ERROR;
+ break;
+
+ }
+}
+
+gint cd_current_track(struct cd *cd)
+{
+ struct ioc_read_subchannel sub_channel;
+ struct cd_sub_channel_info sub_channel_info;
+
+ if (cd->fd == -1) {
+ return -1;
+ }
+
+ sub_channel.address_format = CD_MSF_FORMAT;
+ sub_channel.data_format = CD_TRACK_INFO;
+ sub_channel.track = 0;
+ sub_channel.data = &sub_channel_info;
+ sub_channel.data_len = sizeof(sub_channel_info);
+
+ if (ioctl(cd->fd,CDIOCREADSUBCHANNEL,&sub_channel) != 0) {
+ return -1;
+ }
+
+ return sub_channel.data->track_number;
+}
+
+gboolean cd_close(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return TRUE;
+ }
+
+ if (close(cd->fd) != 0) {
+ return FALSE;
+ }
+
+ cd->fd = -1;
+
+ return TRUE;
+}
+
diff --git a/sys/cdrom/gstcdplayer_ioctl_irix.h b/sys/cdrom/gstcdplayer_ioctl_irix.h
new file mode 100644
index 00000000..2f6be35c
--- /dev/null
+++ b/sys/cdrom/gstcdplayer_ioctl_irix.h
@@ -0,0 +1,109 @@
+/* gstcdplay
+ * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.edu>
+
+ * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* THIS DOES NOT WORK YET */
+
+#define CDPLAYER(x) ((CDPlayer *)x)
+#define FD(x) ((int)x)
+
+gboolean cd_init(struct cd *cd,const gchar *device)
+{
+ CDPLAYER *cdplayer;
+ CDSTATUS status;
+ CDTRACKINFO info;
+ guint i;
+
+ cdplayer = CDOpen(device,"r");
+
+ if (cdplayer == NULL) {
+ return FALSE;
+ }
+
+ cd->fd = FD(cdplayer);
+
+ if (CDgetstatus(cdplayer,&status) == 0) {
+ CDclose(cdplayer);
+ cd->fd = 0;
+ return FALSE;
+ }
+
+ for (i = 1; i < status.last; i++) {
+ if (CDgettrackinfo(cdplayer,i,&info) == 0) {
+ CDclose(cdplayer);
+ cd->fd = 0;
+ return FALSE;
+ }
+
+ cd->tracks[i].minute = info.start_min;
+ cd->tracks[i].second = info.start_sec;
+ cd->tracks[i].frame = info.start_frame;
+
+ }
+
+ /* there is no leadout information */
+
+
+ cd->num_tracks = status.last;
+
+ return TRUE;
+}
+
+gboolean cd_start(struct cd *cd,gint start_track,gint end_track)
+{
+ if (cd->fd == 0) {
+ return FALSE;
+ }
+
+ cd_fix_track_range(cd,&start_track,&end_track);
+
+
+
+}
+
+gboolean cd_pause(struct cd *cd)
+{
+
+}
+
+gboolean cd_resume(struct cd *cd)
+{
+
+}
+
+gboolean cd_stop(struct cd *cd)
+{
+
+}
+
+/* -1 for error, 0 for not playing, 1 for playing */
+CDStatus cd_status(struct cd *cd)
+{
+
+}
+
+gint cd_current_track(struct cd *cd)
+{
+
+}
+
+gboolean cd_close(struct cd *cd)
+{
+
+}
+
diff --git a/sys/cdrom/gstcdplayer_ioctl_solaris.h b/sys/cdrom/gstcdplayer_ioctl_solaris.h
new file mode 100644
index 00000000..868fb251
--- /dev/null
+++ b/sys/cdrom/gstcdplayer_ioctl_solaris.h
@@ -0,0 +1,204 @@
+/* gstcdplay
+ * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.edu>
+
+ * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+gboolean cd_init(struct cd *cd,const gchar *device)
+{
+ struct cdrom_tochdr toc_header;
+ struct cdrom_tocentry toc_entry;
+ guint i;
+
+ cd->fd = open(device,O_RDONLY | O_NONBLOCK);
+
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ /* get the toc header information */
+ if (ioctl(cd->fd,CDROMREADTOCHDR,&toc_header) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ /* read each entry in the toc header */
+ for (i = 1; i <= toc_header.cdth_trk1; i++) {
+ toc_entry.cdte_format = CDROM_MSF;
+ toc_entry.cdte_track = i;
+
+ if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+
+ cd->tracks[i].minute = toc_entry.cdte_addr.msf.minute;
+ cd->tracks[i].second = toc_entry.cdte_addr.msf.second;
+ cd->tracks[i].frame = toc_entry.cdte_addr.msf.frame;
+ cd->tracks[i].data_track = (toc_entry.cdte_ctrl == CDROM_DATA_TRACK);
+ }
+
+ /* read the leadout */
+ toc_entry.cdte_track = CDROM_LEADOUT;
+ toc_entry.cdte_format = CDROM_MSF;
+ if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) {
+ close(cd->fd);
+ cd->fd = -1;
+ return FALSE;
+ }
+ cd->tracks[LEADOUT].minute = toc_entry.cdte_addr.msf.minute;
+ cd->tracks[LEADOUT].second = toc_entry.cdte_addr.msf.second;
+ cd->tracks[LEADOUT].frame = toc_entry.cdte_addr.msf.frame;
+
+ cd->num_tracks = toc_header.cdth_trk1;
+
+ return TRUE;
+}
+
+gboolean cd_start(struct cd *cd,gint start_track,gint end_track)
+{
+ struct cdrom_msf msf;
+
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ cd_fix_track_range(cd,&start_track,&end_track);
+
+ msf.cdmsf_min0 = cd->tracks[start_track].minute;
+ msf.cdmsf_sec0 = cd->tracks[start_track].second;
+ msf.cdmsf_frame0 = cd->tracks[start_track].frame;
+
+ if (end_track == LEADOUT) {
+ msf.cdmsf_min1 = cd->tracks[end_track].minute;
+ msf.cdmsf_sec1 = cd->tracks[end_track].second;
+ msf.cdmsf_frame1 = cd->tracks[end_track].frame;
+ } else {
+ msf.cdmsf_min1 = cd->tracks[end_track+1].minute;
+ msf.cdmsf_sec1 = cd->tracks[end_track+1].second;
+ msf.cdmsf_frame1 = cd->tracks[end_track+1].frame;
+ }
+
+ if (ioctl(cd->fd,CDROMPLAYMSF,&msf) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean cd_pause(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ if (ioctl(cd->fd,CDROMPAUSE,NULL) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean cd_resume(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ if (ioctl(cd->fd,CDROMRESUME,NULL) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean cd_stop(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return FALSE;
+ }
+
+ if (ioctl(cd->fd,CDROMSTOP,NULL) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* -1 for error, 0 for not playing, 1 for playing */
+CDStatus cd_status(struct cd *cd)
+{
+ struct cdrom_subchnl sub_channel;
+
+ if (cd->fd == -1) {
+ return -1;
+ }
+
+ sub_channel.cdsc_format = CDROM_MSF;
+
+ if (ioctl(cd->fd,CDROMSUBCHNL,&sub_channel) != 0) {
+ return -1;
+ }
+
+ switch (sub_channel.cdsc_audiostatus) {
+ case CDROM_AUDIO_COMPLETED:
+ return CD_COMPLETED;
+ break;
+ case CDROM_AUDIO_PLAY:
+ case CDROM_AUDIO_PAUSED:
+ return CD_PLAYING;
+ break;
+ case CDROM_AUDIO_ERROR:
+ default:
+ return CD_ERROR;
+ }
+}
+
+gint cd_current_track(struct cd *cd)
+{
+ struct cdrom_subchnl sub_channel;
+
+ if (cd->fd == -1) {
+ return -1;
+ }
+
+ sub_channel.cdsc_format = CDROM_MSF;
+
+ if (ioctl(cd->fd,CDROMSUBCHNL,&sub_channel) != 0) {
+ return -1;
+ }
+
+
+ return sub_channel.cdsc_trk;
+}
+
+gboolean cd_close(struct cd *cd)
+{
+ if (cd->fd == -1) {
+ return TRUE;
+ }
+
+ if (close(cd->fd) != 0) {
+ return FALSE;
+ }
+
+ cd->fd = -1;
+
+ return TRUE;
+}
+