📄 dvdcontrol.c
字号:
/* Ogle - A video player * Copyright (C) 2000, 2001 Bj鰎n Englund, H錵an Hjort * * This program 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. * * This program 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 */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/msg.h>#include <string.h>#include <errno.h>#include "dvd.h"#include "dvdevents.h"#include "msgevents.h"#include "dvdbookmarks.h"#include "dvdcontrol.h"#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif/** @file * DVD navigator interface. * This file contains the functions that form the interface to * the DVD navigator. These are the functions a user interface * should use to control DVD playback. *//** * Internally seen type for the handle to a DVD navigator */struct DVDNav_s { MsgEventClient_t client; MsgEventClient_t voclient; MsgEventQ_t *msgq; int32_t serial;};#define DVD_SETSERIAL(nav, event) event.any.serial = nav->serial++/** * Get the id of the DVD navigator client. */static MsgEventClient_t get_nav_client(MsgEventQ_t *msq){ MsgEvent_t ev; ev.type = MsgEventQReqCapability; ev.reqcapability.capability = DECODE_DVD_NAV; if(MsgSendEvent(msq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) { fprintf(stderr, "dvdcontrol: get_nav_client\n"); return -1; } while(ev.type != MsgEventQGntCapability) { if(MsgNextEvent(msq, &ev) == -1) { fprintf(stderr, "dvdcontrol: get_nav_client\n"); return -1; } } return ev.gntcapability.capclient;}/** * Get the id of the VideoOutput client. */static MsgEventClient_t get_vo_client(MsgEventQ_t *msq){ MsgEvent_t ev; ev.type = MsgEventQReqCapability; ev.reqcapability.capability = VIDEO_OUTPUT; if(MsgSendEvent(msq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) { fprintf(stderr, "dvdcontrol: get_vo_client\n"); return -1; } while(ev.type != MsgEventQGntCapability) { if(MsgNextEvent(msq, &ev) == -1) { fprintf(stderr, "dvdcontrol: get_vo_client\n"); return -1; } } return ev.gntcapability.capclient;}/** @defgroup dvdnav DVD navigator functions * These functions are used for controlling playback of a DVD. * * The functions are divided into two groups, * the @link dvdinfo DVD information functions @endlink and the * the @link dvdctrl DVD control functions @endlink. * * Before using any of these, a connection to the DVD navigator * must be created by using the DVDOpenNav() function. * * When the connection is not needed anymore the * DVDCloseNav() function should be used. * * The return values from these functions may be used as * an argument to DVDPerror() to generate * human readable error messages. * @{ *//** * Get a connection to the DVD navigator * @todo something */DVDResult_t DVDOpenNav(DVDNav_t **nav, int msgqid) { MsgEvent_t ev; *nav = (DVDNav_t *)malloc(sizeof(DVDNav_t)); if(*nav == NULL) { return DVD_E_NOMEM; } (*nav)->serial = 0; if(((*nav)->msgq = MsgOpen(msgqid)) == NULL) { free(*nav); return DVD_E_Unspecified; } ev.type = MsgEventQRegister; ev.registercaps.capabilities = UI_DVD_GUI; if(MsgSendEvent((*nav)->msgq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) { free(*nav); return DVD_E_FailedToSend; } (*nav)->client = get_nav_client((*nav)->msgq); switch((*nav)->client) { case -1: free(*nav); return DVD_E_Unspecified; case CLIENT_NONE: free(*nav); return DVD_E_Unspecified; default: break; } (*nav)->voclient = CLIENT_NONE; return DVD_E_Ok;}/** * Close the connection to the DVD navigator. * @todo something */DVDResult_t DVDCloseNav(DVDNav_t *nav) { if(nav->msgq == NULL) { fprintf(stderr, "dvdcontrol: already closed\n"); return DVD_E_Unspecified; } MsgClose(nav->msgq); nav = NULL; return DVD_E_Ok;}static const char DVD_E_Ok_STR[] = "OK";static const char DVD_E_Unspecified_STR[] = "Unspecified";static const char DVD_E_NotImplemented_STR[] = "Not Implemented";static const char DVD_E_NoSuchError_STR[] = "No such error code";static const char DVD_E_RootNotSet_STR[] = "Root not set";static const char DVD_E_FailedToSend_STR[] = "Failed to send request";static const char DVD_E_NOMEM_STR[] = "Out of memory";/** * Print DVD error messages */void DVDPerror(const char *str, DVDResult_t ErrCode){ const char *errstr; switch(ErrCode) { case DVD_E_Ok: errstr = DVD_E_Ok_STR; break; case DVD_E_Unspecified: errstr = DVD_E_Unspecified_STR; break; case DVD_E_NotImplemented: errstr = DVD_E_NotImplemented_STR; break; case DVD_E_RootNotSet: errstr = DVD_E_RootNotSet_STR; break; case DVD_E_FailedToSend: errstr = DVD_E_FailedToSend_STR; break; case DVD_E_NOMEM: errstr = DVD_E_NOMEM_STR; break; default: errstr = DVD_E_NoSuchError_STR; break; } fprintf(stderr, "%s%s %s\n", (str == NULL ? "" : str), (str == NULL ? "" : ":"), errstr);}/** @defgroup dvdinfo DVD information functions * These functions are used for getting information from * the DVD navigator. * * These functions send queries to the DVD navigator which * then returns the requested information about the * state of the DVD navigator or attributes of the DVD. * The @link dvdctrl DVD control functions @endlink provides the functions * for controlling the DVD navigator. * @{ *//** * Get the contents of all General Parameters * @todo implement function */DVDResult_t DVDGetAllGPRMs(DVDNav_t *nav, DVDGPRMArray_t *const Registers){ return DVD_E_NotImplemented;}/** * Get the contents of all System Parameters * @todo implement function */DVDResult_t DVDGetAllSPRMs(DVDNav_t *nav, DVDSPRMArray_t *const Registers){ return DVD_E_NotImplemented;}/** * Get the current allowed user operations * @todo handle more return events. * @todo more return values. * * @param nav Specifies the connection to the DVD navigator. * @param uop Points to where the user operations will be written * * @return If successful DVD_E_Ok is returned. Otherwise an error code * is returned. * * @retval DVD_E_Ok Success. * @retval DVD_E_FailedToSend Failed to send the request. */DVDResult_t DVDGetCurrentUOPS(DVDNav_t *nav, DVDUOP_t *const uop){ MsgEvent_t ev; int32_t serial; ev.type = MsgEventQDVDCtrl; DVD_SETSERIAL(nav, ev.dvdctrl.cmd); serial = ev.dvdctrl.cmd.any.serial; ev.dvdctrl.cmd.currentuops.type = DVDCtrlGetCurrentUOPS; if(MsgSendEvent(nav->msgq, nav->client, &ev, 0) == -1) { return DVD_E_FailedToSend; } while(1) { if(MsgNextEvent(nav->msgq, &ev) == -1) { return DVD_E_Unspecified; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlRetVal) && (ev.dvdctrl.cmd.retval.serial == serial)) { return ev.dvdctrl.cmd.retval.val; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlCurrentUOPS)) { *uop = ev.dvdctrl.cmd.currentuops.uops; return DVD_E_Ok; } }}/** * Get the attributes of the specified audio stream. * @todo handle other return events. * @todo add more return values. * * @param nav Specifies the connection to the DVD navigator. * @param StreamNr Specifies the audio stream which attributes * will be retrieved. * @param Attr Points to where the attributes of the specified * audio stream will be written. * * @return If successful DVD_E_Ok is returned and the attributes * pointed to by Attr have been updated. Otherwise an error code * is returned. * * @retval DVD_E_Ok Success. * @retval DVD_E_FailedToSend Failed to send the request. */DVDResult_t DVDGetAudioAttributes(DVDNav_t *nav, DVDAudioStream_t StreamNr, DVDAudioAttributes_t *const Attr){ MsgEvent_t ev; int32_t serial; DVD_SETSERIAL(nav, ev.dvdctrl.cmd); serial = ev.dvdctrl.cmd.any.serial; ev.type = MsgEventQDVDCtrl; ev.dvdctrl.cmd.type = DVDCtrlGetAudioAttributes; ev.dvdctrl.cmd.audioattributes.streamnr = StreamNr; if(MsgSendEvent(nav->msgq, nav->client, &ev, 0) == -1) { return DVD_E_FailedToSend; } while(1) { if(MsgNextEvent(nav->msgq, &ev) == -1) { return DVD_E_Unspecified; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlRetVal) && (ev.dvdctrl.cmd.retval.serial == serial)) { return ev.dvdctrl.cmd.retval.val; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlAudioAttributes)) { if(ev.dvdctrl.cmd.audioattributes.streamnr == StreamNr) { memcpy((void *)Attr, (void *)&(ev.dvdctrl.cmd.audioattributes.attr), sizeof(DVDAudioAttributes_t)); return DVD_E_Ok; } } } }/** * Get the language of an audio stream. * @todo Implement function. * * @param nav Specifies the connection to the DVD navigator. * @param StreamNr Specifies the audio stream which laguage code * will be retrieved. * @param Language Points to where the language code of the * specified audio stream will be written. * * @return If successful DVD_E_Ok is returned. Otherwise an error code * is returned. * * @retval DVD_E_Ok Success. * @retval DVD_E_NotImplemented The function is not implemented. */DVDResult_t DVDGetAudioLanguage(DVDNav_t *nav, DVDAudioStream_t StreamNr, DVDLangID_t *const Language){ return DVD_E_NotImplemented;}/** * Get the number of available audio streams and the current * @todo handle more return events. * @todo more return values. * * @param nav Specifies the connection to the DVD navigator. * @param StreamsAvailable Points to where the number of available * streams will be written. * @param CurrentStream Points to where the current stream will be written. * * @return If successful DVD_E_Ok is returned. Otherwise an error code * is returned. * * @retval DVD_E_Ok Success. * @retval DVD_E_FailedToSend Failed to send the request. */DVDResult_t DVDGetCurrentAudio(DVDNav_t *nav, int *const StreamsAvailable, DVDAudioStream_t *const CurrentStream){ MsgEvent_t ev; int32_t serial; ev.type = MsgEventQDVDCtrl; DVD_SETSERIAL(nav, ev.dvdctrl.cmd); serial = ev.dvdctrl.cmd.any.serial; ev.dvdctrl.cmd.type = DVDCtrlGetCurrentAudio; if(MsgSendEvent(nav->msgq, nav->client, &ev, 0) == -1) { return DVD_E_FailedToSend; } while(1) { if(MsgNextEvent(nav->msgq, &ev) == -1) { return DVD_E_Unspecified; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlRetVal) && (ev.dvdctrl.cmd.retval.serial == serial)) { return ev.dvdctrl.cmd.retval.val; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlCurrentAudio)) { *StreamsAvailable = ev.dvdctrl.cmd.currentaudio.nrofstreams; *CurrentStream = ev.dvdctrl.cmd.currentaudio.currentstream; return DVD_E_Ok; } } }/** * Check if an audio stream is enabled * @todo Handle other return events * @todo more return values * * @param nav Specifies the connection to the DVD navigator. * @param StreamNr Specify the audio stream to retrieve information about. * @param Enabled Specifies if the audio stream is enabled or disabled. * * @return If successful DVD_E_Ok is returned. Otherwise an error code * is returned. * * @retval DVD_E_Ok Success. * @retval DVD_E_FailedToSend Failed to send the request. */DVDResult_t DVDIsAudioStreamEnabled(DVDNav_t *nav, DVDAudioStream_t StreamNr, DVDBool_t *const Enabled){ MsgEvent_t ev; int32_t serial; ev.type = MsgEventQDVDCtrl; DVD_SETSERIAL(nav, ev.dvdctrl.cmd); serial = ev.dvdctrl.cmd.any.serial; ev.dvdctrl.cmd.type = DVDCtrlIsAudioStreamEnabled; ev.dvdctrl.cmd.audiostreamenabled.streamnr = StreamNr; if(MsgSendEvent(nav->msgq, nav->client, &ev, 0) == -1) { return DVD_E_FailedToSend; } while(1) { if(MsgNextEvent(nav->msgq, &ev) == -1) { return DVD_E_Unspecified; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlRetVal) && (ev.dvdctrl.cmd.retval.serial == serial)) { return ev.dvdctrl.cmd.retval.val; } if((ev.type == MsgEventQDVDCtrl) && (ev.dvdctrl.cmd.type == DVDCtrlAudioStreamEnabled)) { if(ev.dvdctrl.cmd.audiostreamenabled.streamnr == StreamNr) { *Enabled = ev.dvdctrl.cmd.audiostreamenabled.enabled; return DVD_E_Ok; } } } }/** * @todo Implement function. * * @param nav Specifies the connection to the DVD navigator. * * @return If successful DVD_E_Ok is returned. Otherwise an error code * is returned. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -