Index: Makefile =================================================================== --- Makefile (revision 19538) +++ Makefile (working copy) @@ -63,6 +63,7 @@ mixer.c \ parser-mpcmd.c \ subopt-helper.c \ + event.c \ OBJS_MENCODER = $(SRCS_MENCODER:.c=.o) OBJS_MPLAYER = $(SRCS_MPLAYER:.c=.o) Index: event.c =================================================================== --- event.c (revision 0) +++ event.c (revision 0) @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2006 Benjamin Zores + * Set of helper routines for event notification. + * Very useful for frontends to retrieve information and player state. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mp_msg.h" +#include "help_mp.h" +#include "m_config.h" +#include "m_option.h" +#include "event.h" + +typedef struct m_event_str { + m_event_t type; + char *name; +} m_event_str_t; + +static char *out_file = NULL; +static int out_file_fd = -1; + +static m_option_t event_conf[] = { + { "file", &out_file, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, + { NULL, NULL, 0, 0, 0, 0, NULL} +}; + +static m_option_t mp_event_opts[] = { + { "event", &event_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + { NULL, NULL, 0, 0, 0, 0, NULL} +}; + +static m_event_str_t m_event_table[] = { + /* unknown event */ + { MP_EVENT_UNKNOWN, "MP_EVENT_UNKNOWN" }, + + /* playback events */ + { MP_EVENT_PLAYBACK_START, "MP_EVENT_PLAYBACK_START" }, + { MP_EVENT_PLAYBACK_PAUSE, "MP_EVENT_PLAYBACK_PAUSE" }, + { MP_EVENT_PLAYBACK_FINISH, "MP_EVENT_PLAYBACK_FINISH" }, + + /* player events */ + { MP_EVENT_PROGRESS, "MP_EVENT_PROGRESS" }, + { MP_EVENT_QUIT, "MP_EVENT_QUIT" }, + { MP_EVENT_UI_MESSAGE, "MP_EVENT_UI_MESSAGE" }, + + /* max number of events */ + { MP_EVENT_MAX_SIZE, "MP_EVENT_MAX_SIZE"} +}; + +static char *mp_event_type_to_str (m_event_t type) { + m_event_str_t es; + int i; + + for (i = 0; i < MP_EVENT_MAX_SIZE; i++) + { + es = m_event_table[i]; + if (es.type == type) + return strdup (es.name); + } + + return NULL; +} + +void mp_event_notify (m_event_t type, char *data_type, char *data) { + char *str, *msg = NULL, *notification; + int len; + + if (!out_file_fd) + return; + + if (type == MP_EVENT_UNKNOWN || type >= MP_EVENT_MAX_SIZE) + return; + + str = mp_event_type_to_str (type); + + if (data_type || data) + { + len = 6; + if (data_type) + len += strlen (data_type); + if (data) + len += strlen (data); + msg = (char *) malloc (len); + sprintf (msg, "[%s='%s']", data_type ? data_type : "", data ? data : ""); + } + + len = strlen (str) + 3; + if (msg) + len += strlen (msg); + notification = (char *) malloc (len); + len = sprintf (notification, "[%s]%s\n", str, msg ? msg : ""); + + mp_msg (MSGT_EVENT, MSGL_INFO, notification); + write (out_file_fd, notification, len); + + free (str); + if (msg) + free (msg); + free (notification); +} + +void mp_event_init (void) { + struct stat st; + + if (!out_file) + return; + + mp_msg (MSGT_EVENT, MSGL_INFO, MSGTR_EVENT_OUTPUT_OpenFile, out_file); + + if (stat (out_file, &st)) + mp_msg (MSGT_EVENT, MSGL_ERR, + MSGTR_EVENT_OUTPUT_ErrCantStatFile, out_file, strerror (errno)); + else + { + out_file_fd = open (out_file, S_ISFIFO (st.st_mode) ? O_RDWR : O_WRONLY); + if (out_file_fd < 0) + mp_msg (MSGT_EVENT, MSGL_ERR, + MSGTR_EVENT_OUTPUT_ErrCantOpenFile, out_file, strerror (errno)); + } +} + +void mp_event_uninit (void) { + if (out_file_fd) + close (out_file_fd); +} + +void mp_event_register_options (m_config_t* cfg) { + m_config_register_options (cfg, mp_event_opts); +} Index: event.h =================================================================== --- event.h (revision 0) +++ event.h (revision 0) @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2006 Benjamin Zores + * Set of helper routines for event notification. + * Very useful for frontends to retrieve information and player state. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _MP_EVENT_H_ +#define _MP_EVENT_H_ + +typedef enum m_event_s m_event_t; +enum m_event_s { + /* unknown event */ + MP_EVENT_UNKNOWN = 0, + + /* playback events */ + MP_EVENT_PLAYBACK_START, /* stream start */ + MP_EVENT_PLAYBACK_PAUSE, /* stream pause/restart */ + MP_EVENT_PLAYBACK_FINISH, /* stream ended */ + + /* player events */ + MP_EVENT_PROGRESS, /* loading (index creation, net connection ...) */ + MP_EVENT_QUIT, /* shutdown of MPlayer */ + MP_EVENT_UI_MESSAGE, /* frontend messages */ + + /* max number of events */ + MP_EVENT_MAX_SIZE +}; + +void mp_event_init (void); +void mp_event_uninit (void); +void mp_event_register_options (m_config_t* cfg); +void mp_event_notify (m_event_t type, char *data_type, char *data); + +#endif /* _MP_EVENT_H_ */ Index: mplayer.c =================================================================== --- mplayer.c (revision 19539) +++ mplayer.c (working copy) @@ -50,6 +50,8 @@ #include "cfg-mplayer-def.h" +#include "event.h" + #ifdef USE_SUB #include "subreader.h" #endif @@ -422,6 +424,7 @@ #define INITED_DEMUXER 512 #define INITED_ACODEC 1024 #define INITED_VCODEC 2048 +#define INITED_EVENT 4096 #define INITED_ALL 0xFFFF #include "metadata.h" @@ -679,6 +682,13 @@ mp_input_uninit(); } + if(mask&INITED_EVENT){ + inited_flags&=~INITED_EVENT; + current_module="uninit_event"; + mp_event_notify (MP_EVENT_QUIT, NULL, NULL); + mp_event_uninit(); + } + current_module=NULL; } @@ -2809,6 +2819,7 @@ m_config_register_options(mconfig,mplayer_opts); // TODO : add something to let modules register their options mp_input_register_options(mconfig); + mp_event_register_options(mconfig); parse_cfgfiles(mconfig); #ifdef HAVE_NEW_GUI @@ -3058,6 +3069,13 @@ if ( !use_gui ) load_termcap(NULL); // load key-codes #endif +// ========== Init event notification layer ============ +current_module = "init_event"; +mp_event_init(); + +inited_flags|=INITED_EVENT; +current_module = NULL; + // ========== Init keyboard FIFO (connection to libvo) ============ // Init input system @@ -4943,97 +4961,99 @@ } break; case MP_CMD_GET_FILENAME : { - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_FILENAME='%s'\n", get_metadata (META_NAME)); + char *inf = get_metadata (META_NAME); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_FILENAME", inf); + free (inf); } break; case MP_CMD_GET_VIDEO_CODEC : { char *inf = get_metadata (META_VIDEO_CODEC); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_VIDEO_CODEC='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_VIDEO_CODEC", inf); free (inf); } break; case MP_CMD_GET_VIDEO_BITRATE : { char *inf = get_metadata (META_VIDEO_BITRATE); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_VIDEO_BITRATE='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_VIDEO_BITRATE", inf); free (inf); } break; case MP_CMD_GET_VIDEO_RESOLUTION : { char *inf = get_metadata (META_VIDEO_RESOLUTION); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_VIDEO_RESOLUTION='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_VIDEO_RESOLUTION", inf); free (inf); } break; case MP_CMD_GET_AUDIO_CODEC : { char *inf = get_metadata (META_AUDIO_CODEC); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_AUDIO_CODEC='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_AUDIO_CODEC", inf); free (inf); } break; case MP_CMD_GET_AUDIO_BITRATE : { char *inf = get_metadata (META_AUDIO_BITRATE); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_AUDIO_BITRATE='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_AUDIO_BITRATE", inf); free (inf); } break; case MP_CMD_GET_AUDIO_SAMPLES : { char *inf = get_metadata (META_AUDIO_SAMPLES); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_AUDIO_SAMPLES='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_AUDIO_SAMPLES", inf); free (inf); } break; case MP_CMD_GET_META_TITLE : { char *inf = get_metadata (META_INFO_TITLE); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_TITLE='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_TITLE", inf); free (inf); } break; case MP_CMD_GET_META_ARTIST : { char *inf = get_metadata (META_INFO_ARTIST); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_ARTIST='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_ARTIST", inf); free (inf); } break; case MP_CMD_GET_META_ALBUM : { char *inf = get_metadata (META_INFO_ALBUM); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_ALBUM='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_ALBUM", inf); free (inf); } break; case MP_CMD_GET_META_YEAR : { char *inf = get_metadata (META_INFO_YEAR); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_YEAR='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_YEAR", inf); free (inf); } break; case MP_CMD_GET_META_COMMENT : { char *inf = get_metadata (META_INFO_COMMENT); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_COMMENT='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_COMMENT", inf); free (inf); } break; case MP_CMD_GET_META_TRACK : { char *inf = get_metadata (META_INFO_TRACK); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_TRACK='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_TRACK", inf); free (inf); } break; case MP_CMD_GET_META_GENRE : { char *inf = get_metadata (META_INFO_GENRE); if (!inf) inf = strdup (""); - mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_META_GENRE='%s'\n", inf); + mp_event_notify(MP_EVENT_UI_MESSAGE, "ANS_META_GENRE", inf); free (inf); } break; Index: help/help_mp-en.h =================================================================== --- help/help_mp-en.h (revision 19538) +++ help/help_mp-en.h (working copy) @@ -1223,6 +1223,14 @@ #define MSGTR_INPUT_INPUT_ErrCantStatFile "Can't stat %s: %s\n" #define MSGTR_INPUT_INPUT_ErrCantOpenFile "Can't open %s: %s\n" +// ========================== EVENT ========================================= + +// event.c + +#define MSGTR_EVENT_OUTPUT_OpenFile "Using %s for event output\n" +#define MSGTR_EVENT_OUTPUT_ErrCantStatFile "Can't stat %s: %s\n" +#define MSGTR_EVENT_OUTPUT_ErrCantOpenFile "Can't open %s: %s\n" + // ========================== LIBMPDEMUX =================================== // url.c Index: mp_msg.h =================================================================== --- mp_msg.h (revision 19538) +++ mp_msg.h (working copy) @@ -97,6 +97,8 @@ #define MSGT_IDENTIFY 41 // -identify output +#define MSGT_EVENT 42 // events notifier + #define MSGT_MAX 64 void mp_msg_init(void);