From 114b922fa7bbe06f4acfcc3d7af9c47ef534b1a2 Mon Sep 17 00:00:00 2001 From: Jean-Paul Saman Date: Fri, 5 Feb 2010 14:13:29 +0100 Subject: [PATCH] libvlc: add mouse events as libvlc_MediaPlayerEvents The following events have been added: - MouseButton : mouse button pressed events - MouseClick : mouse button click event - MouseMoved : mouse movement event (x,y) absolute against vlc video output window - MouseObject : object of interest under mouse button for use by video filters (like: logo) --- include/vlc/libvlc_events.h | 35 +++++- src/control/media_player.c | 158 +++++++++++++++++++++++++++- src/control/media_player_internal.h | 4 +- src/video_output/video_output.c | 2 + src/video_output/vout_intf.c | 1 + 5 files changed, 195 insertions(+), 5 deletions(-) diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h index e6af9b25da..94968395a2 100644 --- a/include/vlc/libvlc_events.h +++ b/include/vlc/libvlc_events.h @@ -1,7 +1,7 @@ /***************************************************************************** * libvlc_events.h: libvlc_events external API structure ***************************************************************************** - * Copyright (C) 1998-2008 the VideoLAN team + * Copyright (C) 1998-2010 the VideoLAN team * $Id $ * * Authors: Filippo Carone @@ -103,6 +103,12 @@ extern "C" { DEF( VlmMediaInstanceStatusError ), \ \ DEF( MediaPlayerMediaChanged ), \ + \ + DEF( MediaPlayerMouseMoved ), \ + DEF( MediaPlayerMouseButton ), \ + DEF( MediaPlayerMouseClick ), \ + DEF( MediaPlayerMouseObject ), \ + \ /* New event types HERE */ #ifdef __cplusplus @@ -234,6 +240,33 @@ struct libvlc_event_t { libvlc_media_t * new_media; } media_player_media_changed; + + /* Mouse events */ + struct + { + int x; + int y; + } media_player_mouse_moved; + + struct + { + int mb_left; + int mb_center; + int mb_right; + int mb_wheel_up; + int mb_wheel_down; + } media_player_mouse_button; + + struct + { + int clicked; + } media_player_mouse_clicked; + + struct + { + int moved; + } media_player_mouse_object; + } u; }; diff --git a/src/control/media_player.c b/src/control/media_player.c index 678aab8e9e..ba2c1890f7 100644 --- a/src/control/media_player.c +++ b/src/control/media_player.c @@ -58,6 +58,21 @@ static int snapshot_was_taken( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ); +/* Mouse events */ +static int +mouse_moved( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ); +static int +mouse_button( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ); +static int +mouse_clicked( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ); +static int +mouse_object( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ); + +/* */ static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi ); /* @@ -139,6 +154,50 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi ) return p_input_thread; } +/* + * Get vout thread from current input + * + * Object lock is NOT held. + */ +static vout_thread_t *get_vout_thread( libvlc_media_player_t *p_mi ) +{ + vout_thread_t *p_vout_thread; + + p_vout_thread = input_GetVout( p_mi->p_input_thread ); + if( p_vout_thread ) + { + var_AddCallback( p_vout_thread, "mouse-button-down", mouse_button, p_mi ); + var_AddCallback( p_vout_thread, "mouse-moved", mouse_moved, p_mi ); + var_AddCallback( p_vout_thread, "mouse-clicked", mouse_clicked, p_mi ); + var_AddCallback( p_vout_thread, "mouse-object", mouse_object, p_mi ); + } + + return p_vout_thread; +} + +/* + * Release the associated vout thread. + * + * Object lock is NOT held. + */ +static void release_vout_thread( libvlc_media_player_t *p_mi ) +{ + vout_thread_t *p_vout_thread; + + if( !p_mi || !p_mi->p_vout_thread ) + return; + + p_vout_thread = p_mi->p_vout_thread; + + var_DelCallback( p_vout_thread, "mouse-button-down", mouse_button, p_mi ); + var_DelCallback( p_vout_thread, "mouse-moved", mouse_moved, p_mi ); + var_DelCallback( p_vout_thread, "mouse-clicked", mouse_clicked, p_mi ); + var_DelCallback( p_vout_thread, "mouse-object", mouse_object, p_mi ); + + vlc_object_release( p_vout_thread ); + p_mi->p_vout_thread = NULL; +} + /* * Set the internal state of the media_player. (media player Internal) * @@ -150,14 +209,16 @@ static void set_state( libvlc_media_player_t *p_mi, libvlc_state_t state, if(!b_locked) lock(p_mi); p_mi->state = state; + libvlc_media_t *media = p_mi->p_md; if (media) libvlc_media_retain(media); + if(!b_locked) unlock(p_mi); - - if (media) { + if (media) + { // Also set the state of the corresponding media // This is strictly for convenience. libvlc_media_set_state(media, state); @@ -284,6 +345,16 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd, from_mtime(var_GetTime( p_input, "length" )); libvlc_event_send( p_mi->p_event_manager, &event ); } + else if( newval.i_int == INPUT_EVENT_VOUT ) + { + lock( p_mi ); + /* release old vout */ + if( p_mi->p_vout_thread ) + release_vout_thread( p_mi ); + /* remember new vout */ + p_mi->p_vout_thread = get_vout_thread( p_mi ); + unlock( p_mi ); + } return VLC_SUCCESS; @@ -308,7 +379,78 @@ static int snapshot_was_taken(vlc_object_t *p_this, char const *psz_cmd, return VLC_SUCCESS; } +/************************************************************************** + * Mouse Events. + *************************************************************************/ + +static int +mouse_moved( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) +{ + VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(newval); + + libvlc_media_player_t *mp = p_data; + libvlc_event_t event; + event.type = libvlc_MediaPlayerMouseMoved; + event.u.media_player_mouse_moved.x = var_GetInteger( mp->p_vout_thread, "mouse-x" ); + event.u.media_player_mouse_moved.y = var_GetInteger( mp->p_vout_thread, "mouse-y" ); + libvlc_event_send(mp->p_event_manager, &event); + + return VLC_SUCCESS; +} + +static int +mouse_button( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) +{ + VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_this); + + libvlc_media_player_t *mp = p_data; + libvlc_event_t event; + int pressed = newval.i_int; + + event.type = libvlc_MediaPlayerMouseButton; + event.u.media_player_mouse_button.mb_left = (pressed & (1<p_event_manager, &event); + return VLC_SUCCESS; +} + +static int +mouse_clicked( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) +{ + VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_this); + + libvlc_media_player_t *mp = p_data; + libvlc_event_t event; + event.type = libvlc_MediaPlayerMouseClick; + event.u.media_player_mouse_clicked.clicked = newval.b_bool ? 1 : 0; + libvlc_event_send(mp->p_event_manager, &event); + + return VLC_SUCCESS; +} + +static int +mouse_object( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) +{ + VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_this); + + libvlc_media_player_t *mp = p_data; + libvlc_event_t event; + event.type = libvlc_MediaPlayerMouseObject; + event.u.media_player_mouse_object.moved = (newval.b_bool ? 1 : 0); + libvlc_event_send(mp->p_event_manager, &event); + + return VLC_SUCCESS; +} + +/* */ static void libvlc_media_player_destroy( libvlc_media_player_t * ); @@ -394,6 +536,7 @@ libvlc_media_player_new( libvlc_instance_t *instance ) mp->p_libvlc_instance = instance; mp->p_input_thread = NULL; mp->p_input_resource = NULL; + mp->p_vout_thread = NULL; mp->i_refcount = 1; mp->p_event_manager = libvlc_event_manager_new(mp, instance); if (unlikely(mp->p_event_manager == NULL)) @@ -426,6 +569,12 @@ libvlc_media_player_new( libvlc_instance_t *instance ) register_event(mp, MediaChanged); + /* mouse events */ + register_event(mp, MouseMoved); + register_event(mp, MouseButton); + register_event(mp, MouseClick); + register_event(mp, MouseObject); + /* Attach a var callback to the global object to provide the glue between * vout_thread that generates the event and media_player that re-emits it * with its own event manager @@ -475,7 +624,10 @@ static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi ) assert(!p_mi->p_input_thread); /* Fallback for those who don't use NDEBUG */ - if (p_mi->p_input_thread) + if( p_mi->p_vout_thread ) + release_vout_thread( p_mi ); + + if(p_mi->p_input_thread ) release_input_thread(p_mi, true); if( p_mi->p_input_resource ) diff --git a/src/control/media_player_internal.h b/src/control/media_player_internal.h index 5d23ba2197..987c559a38 100644 --- a/src/control/media_player_internal.h +++ b/src/control/media_player_internal.h @@ -33,6 +33,7 @@ #include #include #include +#include struct libvlc_media_player_t { @@ -41,7 +42,8 @@ struct libvlc_media_player_t int i_refcount; vlc_mutex_t object_lock; input_thread_t * p_input_thread; - input_resource_t * p_input_resource; + input_resource_t * p_input_resource; + vout_thread_t * p_vout_thread; struct libvlc_instance_t * p_libvlc_instance; /* Parent instance */ libvlc_media_t * p_md; /* current media descriptor */ libvlc_event_manager_t * p_event_manager; diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index a9e1326417..58ce6603ad 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -407,6 +407,8 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) var_Create( p_vout, "mouse-button-down", VLC_VAR_INTEGER ); var_Create( p_vout, "mouse-moved", VLC_VAR_BOOL ); var_Create( p_vout, "mouse-clicked", VLC_VAR_BOOL ); + /* Mouse object (area of interest in a video filter) */ + var_Create( p_vout, "mouse-object", VLC_VAR_BOOL ); /* Initialize subpicture unit */ p_vout->p_spu = spu_Create( p_vout ); diff --git a/src/video_output/vout_intf.c b/src/video_output/vout_intf.c index 32115eb491..fc8369ebbd 100644 --- a/src/video_output/vout_intf.c +++ b/src/video_output/vout_intf.c @@ -368,6 +368,7 @@ void vout_IntfInit( vout_thread_t *p_vout ) var_Create( p_vout, "mouse-button-down", VLC_VAR_INTEGER ); var_Create( p_vout, "mouse-moved", VLC_VAR_BOOL ); var_Create( p_vout, "mouse-clicked", VLC_VAR_BOOL ); + var_Create( p_vout, "mouse-object", VLC_VAR_BOOL ); var_Create( p_vout, "intf-change", VLC_VAR_BOOL ); var_SetBool( p_vout, "intf-change", true ); -- 2.39.2