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

📄 msgevents.c

📁 基于linux的DVD播放器程序
💻 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 <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <errno.h>#include "dvd.h"#include "dvdevents.h"#include "msgevents.h"#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if (defined(BSD) && (BSD >= 199306))#include <unistd.h>#endif//#define DEBUG#ifdef DEBUGstatic char *MsgEventType_str[] = {  "MsgEventQNone",  "Reserved",  "MsgEventQInitReq",  "MsgEventQInitGnt",    "MsgEventQRegister",  "MsgEventQNotify",  "MsgEventQReqCapability",  "MsgEventQGntCapability",  "MsgEventQPlayCtrl",  "MsgEventQChangeFile",  "MsgEventQReqStreamBuf", // 10  "MsgEventQGntStreamBuf",  "MsgEventQDecodeStreamBuf",  "MsgEventQReqBuf",  "MsgEventQGntBuf",  "MsgEventQCtrlData",  "MsgEventQReqPicBuf",  "MsgEventQGntPicBuf",  "MsgEventQAttachQ",  "MsgEventQSPUPalette",  "MsgEventQSPUHighlight", // 20  "MsgEventQSpeed",  "MsgEventQDVDCtrl",  "MsgEventQFlow",  "MsgEventQFlushData",  "MsgEventQDemuxStream",  "MsgEventQDemuxStreamChange",  "MsgEventQDemuxDefault",  "MsgEventQDVDCtrlLong",  "MsgEventQDemuxDVD", // 29  "MsgEventQDemuxDVDRoot",  "MsgEventQSetAspectModeSrc",  "MsgEventQSetSrcAspect",  "MsgEventQSetZoom",  "MsgEventQReqInput",  "MsgEventQInputButtonPress",  "MsgEventQInputButtonRelease",  "MsgEventQInputPointerMotion",  "MsgEventQInputKeyPress",  "MsgEventQInputKeyRelease",  "MsgEventQDestroyBuf",  "MsgEventQAppendQ",  "MsgEventQDetachQ",  "MsgEventQQDetached",  "MsgEventQDestroyQ",  "MsgEventQDemuxStreamChange2",  "MsgEventQSaveScreenshot",  NULL};void PrintMsgEventType(MsgEventType_t type){  fprintf(stderr, MsgEventType_str[type]);}#endif#ifdef SOCKIPCMsgEventQ_t *MsgOpen(MsgEventQType_t type, char *name, int namelen){  MsgEventQ_t *ret = NULL;  msg_t msg;  MsgQInitReqEvent_t initreq;  MsgQInitGntEvent_t initgnt;    msg.mtype = CLIENT_RESOURCE_MANAGER; // the recipient of this message  initreq.type = MsgEventQInitReq;   // we want a handle  memcpy(msg.event_data, &initreq, sizeof(MsgQInitReqEvent_t));    switch(type) {  case MsgEventQType_msgq:    {      int msqid = atoi(name);            if(msgsnd(msqid, (void *)&msg, sizeof(MsgQInitReqEvent_t), 0) == -1) {	perror("MsgOpen, snd");	return NULL;	      } else {	if(msgrcv(msqid, (void *)&msg, sizeof(MsgEvent_t),		  CLIENT_UNINITIALIZED, 0) == -1) {	  perror("MsgOpen, rcv");	  return NULL;	} else {	  ret = (MsgEventQ_t *)malloc(sizeof(MsgEventQ_t));	  	  ret->msg.type = MsgEventQType_msgq;	  ret->msq.msqid = msqid;       // which msq to wait for messages on	  memcpy(&initgnt, msg.event_data, sizeof(MsgQInitGntEvent_t));	  ret->msg.mtype = initgnt.newclientid; // mtype to wait for	  	}      }    }    break;  case MsgEventQType_socket:    {      int sd;      struct sockaddr_un unix_addr = { 0 };            if((sd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) {	perror("socket");	return NULL;      }      unix_addr.sun_family = AF_UNIX;            if(strlen(name) >= sizeof(unix_addr.sun_path)) {	return NULL;      }            strcpy(unix_addr.sun_path, name);            if(connect(sd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) == -1) {	perror("connect");	return NULL;      }            if(msgsnd(msqid, (void *)&msg, sizeof(MsgQInitReqEvent_t), 0) == -1) {	perror("MsgOpen, snd");	return NULL;	      } else {	if(msgrcv(msqid, (void *)&msg, sizeof(MsgEvent_t),		  CLIENT_UNINITIALIZED, 0) == -1) {	  perror("MsgOpen, rcv");	  return NULL;	} else {	  ret = (MsgEventQ_t *)malloc(sizeof(MsgEventQ_t));	  	  ret->msg.type = MsgEventQType_msgq;	  ret->msq.msqid = msqid;       // which msq to wait for messages on	  memcpy(&initgnt, msg.event_data, sizeof(MsgQInitGntEvent_t));	  ret->msg.mtype = initgnt.newclientid; // mtype to wait for	  	}      }                }    break;  case MsgEventQType_pipe:    break;  }    return ret;  }#elseMsgEventQ_t *MsgOpen(int msqid){  MsgEventQ_t *ret = NULL;  msg_t msg;  MsgQInitReqEvent_t initreq;  MsgQInitGntEvent_t initgnt;    msg.mtype = CLIENT_RESOURCE_MANAGER; // the recipient of this message  initreq.type = MsgEventQInitReq;   // we want a handle  memcpy(msg.event_data, &initreq, sizeof(MsgQInitReqEvent_t));    if(msgsnd(msqid, (void *)&msg, sizeof(MsgQInitReqEvent_t), 0) == -1) {    perror("MsgOpen, snd");    return NULL;      } else {    if(msgrcv(msqid, (void *)&msg, sizeof(MsgEvent_t),             CLIENT_UNINITIALIZED, 0) == -1) {      perror("MsgOpen, rcv");      return NULL;    } else {      ret = (MsgEventQ_t *)malloc(sizeof(MsgEventQ_t));            ret->msqid = msqid;       // which msq to wait for messages on      memcpy(&initgnt, msg.event_data, sizeof(MsgQInitGntEvent_t));      ret->mtype = initgnt.newclientid; // mtype to wait for        }  }    return ret;  }#endif/** * Close the message connection. * TODO: tell resource manager that there isn't anyone listening * for messages here any more.  */void MsgClose(MsgEventQ_t *q){  fprintf(stderr, "msg close FIX\n");      // just in case someone tries to access this pointer after close  q->msqid = 0;  q->mtype = 0;    free(q);  }static int MsgNextEvent_internal(MsgEventQ_t *q, MsgEvent_t *event_return, int interruptible){  msg_t msg;    while(1) {    if(msgrcv(q->msqid, (void *)&msg, sizeof(MsgEvent_t),	      q->mtype, 0) == -1) {      switch(errno) {      case EINTR:  // syscall interrupted 	if(!interruptible) {	  continue;	}	break;      default:	perror("MsgNextEvent");	break;      }      return -1;    } else {            memcpy(event_return, msg.event_data, sizeof(MsgEvent_t));      return 0;    }  }    }int MsgNextEvent(MsgEventQ_t *q, MsgEvent_t *event_return) {  return MsgNextEvent_internal(q, event_return, 0);}int MsgNextEventInterruptible(MsgEventQ_t *q, MsgEvent_t *event_return) {  return MsgNextEvent_internal(q, event_return, 1);}#if (defined(BSD) && (BSD >= 199306))int MsgNextEventNonBlocking(MsgEventQ_t *q, MsgEvent_t *event_return){  msg_t msg;    while (1) {    if(msgrcv(q->msqid, (void *)&msg, sizeof(MsgEvent_t),             q->mtype, IPC_NOWAIT) == -1) {      switch(errno) {#ifdef ENOMSG      case ENOMSG:#endif      case EAGAIN:      case EINTR:     // interrupted by system call/signal, try again       usleep(10000);       continue;       break;      default:       perror("MsgNextEvent");       break;      }      return -1;    } else {            memcpy(event_return, msg.event_data, sizeof(MsgEvent_t));      return 0;    }  }}#endifint MsgCheckEvent(MsgEventQ_t *q, MsgEvent_t *event_return){  msg_t msg;    while (1) {    if(msgrcv(q->msqid, (void *)&msg, sizeof(MsgEvent_t),	      q->mtype, IPC_NOWAIT) == -1) {      switch(errno) {#ifdef ENOMSG      case ENOMSG:#endif      case EAGAIN:	break;      case EINTR:     // interrupted by system call/signal, try again	continue;	break;      default:	perror("MsgNextEvent");	break;      }      return -1;    } else {            memcpy(event_return, msg.event_data, sizeof(MsgEvent_t));      return 0;    }  }}int MsgSendEvent(MsgEventQ_t *q, MsgEventClient_t client,		 MsgEvent_t *event_send, int msgflg){  msg_t msg;  int size = 0;  msg.mtype = client; // the recipient of this message  event_send->any.client = q->mtype; // the sender    switch(event_send->type) {  case MsgEventQInitReq:    size = sizeof(MsgQInitReqEvent_t);    break;  case MsgEventQInitGnt:      size = sizeof(MsgQInitGntEvent_t);    break;  case MsgEventQRegister:    size = sizeof(MsgQRegisterCapsEvent_t);    break;  case MsgEventQNotify:    size = sizeof(MsgQNotifyEvent_t);    break;  case MsgEventQReqCapability:    size = sizeof(MsgQReqCapabilityEvent_t);    break;  case MsgEventQGntCapability:    size = sizeof(MsgQGntCapabilityEvent_t);    break;  case MsgEventQPlayCtrl:    size = sizeof(MsgQPlayCtrlEvent_t);    break;  case MsgEventQChangeFile:    size = sizeof(MsgQAnyEvent_t)+strlen(event_send->changefile.filename)+1;    break;  case MsgEventQReqStreamBuf:    size = sizeof(MsgQReqStreamBufEvent_t);    break;  case MsgEventQGntStreamBuf:    size = sizeof(MsgQGntStreamBufEvent_t);    break;  case MsgEventQDecodeStreamBuf:    size = sizeof(MsgQDecodeStreamBufEvent_t);    break;  case MsgEventQReqBuf:    size = sizeof(MsgQReqBufEvent_t);    break;  case MsgEventQGntBuf:    size = sizeof(MsgQGntBufEvent_t);    break;  case MsgEventQDestroyBuf:    size = sizeof(MsgQDestroyBufEvent_t);    break;  case MsgEventQCtrlData:    size = sizeof(MsgQCtrlDataEvent_t);    break;  case MsgEventQReqPicBuf:    size = sizeof(MsgQReqPicBufEvent_t);    break;  case MsgEventQGntPicBuf:    size = sizeof(MsgQGntPicBufEvent_t);    break;  case MsgEventQAttachQ:  case MsgEventQAppendQ:    size = sizeof(MsgQAttachQEvent_t);    break;  case MsgEventQDetachQ:  case MsgEventQQDetached:  case MsgEventQDestroyQ:    size = sizeof(MsgQDetachQEvent_t);    break;  case MsgEventQSPUPalette:    size = sizeof(MsgQSPUPaletteEvent_t);    break;  case MsgEventQSPUHighlight:    size = sizeof(MsgQSPUHighlightEvent_t);    break;  case MsgEventQSpeed:    size = sizeof(MsgQSpeedEvent_t);    break;  case MsgEventQDVDCtrl:    size = sizeof(MsgQDVDCtrlEvent_t);    break;  case MsgEventQFlow:    size = sizeof(MsgQFlowEvent_t);    break;  case MsgEventQFlushData:    size = sizeof(MsgQFlushDataEvent_t);    break;  case MsgEventQDemuxStream:    size = sizeof(MsgQDemuxStreamEvent_t);    break;  case MsgEventQDemuxStreamChange:    size = sizeof(MsgQDemuxStreamChangeEvent_t);    break;  case MsgEventQDemuxStreamChange2:    size = sizeof(MsgQDemuxStreamChange2Event_t);    break;  case MsgEventQDemuxDefault:    size = sizeof(MsgQDemuxDefaultEvent_t);    break;  case MsgEventQDVDCtrlLong:    switch(event_send->dvdctrllong.cmd.type) {    case DVDCtrlLongSetDVDRoot:      size = sizeof(MsgQAnyEvent_t) + sizeof(DVDCtrlLongAnyEvent_t)	+ strlen(event_send->dvdctrllong.cmd.dvdroot.path)+1;      break;    case DVDCtrlLongSetState:      size = sizeof(MsgQAnyEvent_t) + sizeof(DVDCtrlLongAnyEvent_t)	+ strlen(event_send->dvdctrllong.cmd.state.xmlstr)+1;      break;    case DVDCtrlLongVolIds:      size = sizeof(MsgQAnyEvent_t) + sizeof(DVDCtrlLongVolIdsEvent_t);      break;    default:      size = sizeof(MsgQDVDCtrlLongEvent_t);      break;    }    break;  case MsgEventQDemuxDVD:    size = sizeof(MsgQDemuxDVDEvent_t);    break;  case MsgEventQDemuxDVDRoot:    size = sizeof(MsgQAnyEvent_t)+strlen(event_send->demuxdvdroot.path)+1;    break;  case MsgEventQSetAspectModeSrc:    size = sizeof(MsgQSetAspectModeSrcEvent_t);    break;  case MsgEventQSetSrcAspect:    size = sizeof(MsgQSetSrcAspectEvent_t);    break;  case MsgEventQSetZoomMode:    size = sizeof(MsgQSetZoomModeEvent_t);    break;  case MsgEventQReqInput:    size = sizeof(MsgQReqInputEvent_t);    break;  case MsgEventQInputButtonPress:  case MsgEventQInputButtonRelease:  case MsgEventQInputPointerMotion:  case MsgEventQInputKeyPress:  case MsgEventQInputKeyRelease:    size = sizeof(MsgQInputEvent_t);    break;  case MsgEventQSaveScreenshot:    size = sizeof(MsgQAnyEvent_t) + sizeof(ScreenshotMode_t) +       strlen(event_send->savescreenshot.formatstr)+1;    break;  default:    fprintf(stderr, "MsgSendEvent: Unknown event: %d\n", event_send->type);    return -1;  }  memcpy(msg.event_data, event_send, size);#ifdef DEBUG  fprintf(stderr, "Sending '%s' from: %ld to: %ld\n",	  MsgEventType_str[msg.event.type],	  msg.event.any.client,	  msg.mtype);#endif    while(1) {    if(msgsnd(q->msqid, (void *)&msg, size, msgflg) == -1) {      switch(errno) {      case EINTR: //interrupted by syscall/signal, try again	continue;	break;      default:	perror("MsgSendEvent");	break;      }      return -1;    } else {      return 0;    }  }  }  /*    1 semaphore for each msg queue receiver    one msgarray for each receiver  msgsnd(msgqid, msg, size, nowait/wait) {    semwait(msgqsem[msgqid]);  qnr = qnrs[msgqid];  qnrs[msgqid]++;  sempost(msgqsem[msgqid]);  fill   }    if(msgsnd(q->msqid, (void *)&msg, size, 0) == -1) {    perror("MsgSendEvent");    return -1;  } */

⌨️ 快捷键说明

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