Browse Source

libvlc: allow user to report mouse events when using libvlc_video_set_output_callbacks

when using libvlc_video_set_output_callbacks, VLC has no native surface to
intercept mouse events (unlike libvlc_media_player_set_xwindow/xid/...). This
patch allows user to send these events manually to VLC. This is useful when
dealing with interactive medias (DVD menus).
pull/162/head
Pierre Lamot 3 years ago
committed by Jean-Baptiste Kempf
parent
commit
60078ca975
  1. 7
      doc/libvlc/d3d11_player.cpp
  2. 11
      doc/libvlc/d3d9_player.c
  3. 78
      include/vlc/libvlc_media_player.h
  4. 6
      lib/media_player.c
  5. 35
      modules/video_output/wextern.c

7
doc/libvlc/d3d11_player.cpp

@ -498,8 +498,11 @@ static void CleanupDevice_cb( void *opaque )
}
// receive the libvlc callback to call when we want to change the libvlc output size
static void SetResize_cb( void *opaque,
static void SetReport_cb( void *opaque,
libvlc_video_output_resize_cb report_size_change,
libvlc_video_output_mouse_move_cb report_mouse_move,
libvlc_video_output_mouse_press_cb report_mouse_press,
libvlc_video_output_mouse_release_cb report_mouse_release,
void *report_opaque )
{
struct render_context *ctx = static_cast<struct render_context *>( opaque );
@ -681,7 +684,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
/* Tell VLC to render into our D3D11 environment */
libvlc_video_set_output_callbacks( Context.p_mp, libvlc_video_engine_d3d11,
SetupDevice_cb, CleanupDevice_cb, SetResize_cb,
SetupDevice_cb, CleanupDevice_cb, SetReport_cb,
UpdateOutput_cb, Swap_cb, StartRendering_cb,
nullptr, nullptr, SelectPlane_cb,
&Context );

11
doc/libvlc/d3d9_player.c

@ -222,9 +222,12 @@ static void CleanupDevice_cb( void *opaque )
}
}
static void SetResize_cb( void *opaque,
libvlc_video_output_resize_cb report_size_change,
void *report_opaque )
static void SetReport_cb( void *opaque,
libvlc_video_output_resize_cb report_size_change,
libvlc_video_output_mouse_move_cb report_mouse_move,
libvlc_video_output_mouse_press_cb report_mouse_press,
libvlc_video_output_mouse_release_cb report_mouse_release,
void *report_opaque )
{
struct render_context *ctx = opaque;
EnterCriticalSection(&ctx->sizeLock);
@ -416,7 +419,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
/* Tell VLC to render into our D3D9 environment */
libvlc_video_set_output_callbacks( Context.p_mp, libvlc_video_engine_d3d9,
SetupDevice_cb, CleanupDevice_cb, SetResize_cb,
SetupDevice_cb, CleanupDevice_cb, SetReport_cb,
UpdateOutput_cb, Swap_cb, StartRendering_cb,
NULL, NULL, NULL,
&Context );

78
include/vlc/libvlc_media_player.h

@ -717,32 +717,92 @@ typedef enum libvlc_video_engine_t {
/** Callback type that can be called to request a render size changes.
*
* libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_resize_cb.
*
* \param report_opaque parameter passed to \ref libvlc_video_output_set_resize_cb. [IN]
*
* libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
*
* \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
* \param width new rendering width requested. [IN]
* \param height new rendering height requested. [IN]
*/
typedef void( *libvlc_video_output_resize_cb )( void *report_opaque, unsigned width, unsigned height );
/**
* Enumeration of the different mouse buttons that can be reported for user interaction
* can be passed to \ref libvlc_video_output_mouse_press_cb and \ref libvlc_video_output_mouse_release_cb.
*/
typedef enum libvlc_video_output_mouse_button_t {
libvlc_video_output_mouse_button_left = 0,
libvlc_video_output_mouse_button_middle = 1,
libvlc_video_output_mouse_button_right = 2
} libvlc_video_output_mouse_button_t;
/** Callback type that can be called to notify the mouse position when hovering the render surface.
*
* libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
*
* The position (0,0) denotes the top left corner, bottom right corner position
* is (width,height) as reported by \ref libvlc_video_output_resize_cb.
*
* \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
* \param x horizontal mouse positon in \ref libvlc_video_output_resize_cb coordinates. [IN]
* \param y vertical mouse positon in \ref libvlc_video_output_resize_cb coordinates. [IN]
*/
typedef void (*libvlc_video_output_mouse_move_cb)(void *opaque, int x, int y);
/** Callback type that can be called to notify when a mouse button is pressed in the rendering surface.
*
* libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
*
* The button event will be reported at the last position provided by \ref libvlc_video_output_mouse_move_cb
*
* \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
* \param button represent the button pressed, see \ref libvlc_video_output_mouse_button_t for available buttons. [IN]
*/
typedef void (*libvlc_video_output_mouse_press_cb)(void *opaque, libvlc_video_output_mouse_button_t button);
/** Callback type that can be called to notify when a mouse button is released in the rendering surface.
*
* libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
*
* The button event will be reported at the last position provided by \ref libvlc_video_output_mouse_move_cb.
*
* \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
* \param button represent the button released, see \ref libvlc_video_output_mouse_button_t for available buttons. [IN]
*/
typedef void (*libvlc_video_output_mouse_release_cb)(void *opaque, libvlc_video_output_mouse_button_t button);
/** Set the callback to call when the host app resizes the rendering area.
*
* This allows text rendering and aspect ratio to be handled properly when the host
* rendering size changes.
* rendering size changes and to provide mouse.
*
* It may be called before the \ref libvlc_video_output_setup_cb callback.
*
* \warning These callbacks cannot be called concurently, the caller is responsible for serialization
*
* \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
* \param[in] report_size_change callback which must be called when the host size changes.
* The callback is valid until another call to \ref libvlc_video_output_set_resize_cb
* is done. This may be called from any thread.
* \param[in] report_mouse_move callback which must be called when the mouse position change on the video surface.
* The coordinates are relative to the size reported through the report_size_change.
* This may be called from any thread.
* \param[in] report_mouse_pressed callback which must be called when a mouse button is pressed on the video surface,
* The position of the event is the last position reported by the report_mouse_move callback. This may be
* called from any thread.
* \param[in] report_mouse_released callback which must be called when a mouse button is released on the video surface,
* The position of the event is the last position reported by the report_mouse_move callback. This may be
* called from any thread.
* \param[in] report_opaque private pointer to pass to the \ref report_size_change callback.
*/
typedef void( *libvlc_video_output_set_resize_cb )( void *opaque,
libvlc_video_output_resize_cb report_size_change,
void *report_opaque );
typedef void( *libvlc_video_output_set_window_cb )( void *opaque,
libvlc_video_output_resize_cb report_size_change,
libvlc_video_output_mouse_move_cb report_mouse_move,
libvlc_video_output_mouse_press_cb report_mouse_pressed,
libvlc_video_output_mouse_release_cb report_mouse_released,
void *report_opaque );
/** Tell the host the rendering for the given plane is about to start
*
@ -801,7 +861,7 @@ bool libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
libvlc_video_engine_t engine,
libvlc_video_output_setup_cb setup_cb,
libvlc_video_output_cleanup_cb cleanup_cb,
libvlc_video_output_set_resize_cb resize_cb,
libvlc_video_output_set_window_cb window_cb,
libvlc_video_update_output_cb update_output_cb,
libvlc_video_swap_cb swap_cb,
libvlc_video_makeCurrent_cb makeCurrent_cb,

6
lib/media_player.c

@ -634,7 +634,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
var_Create( mp, "vout-cb-opaque", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-setup", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-cleanup", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-resize-cb", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-window-cb", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-update-output", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-swap", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-get-proc-address", VLC_VAR_ADDRESS );
@ -1062,7 +1062,7 @@ bool libvlc_video_set_output_callbacks(libvlc_media_player_t *mp,
libvlc_video_engine_t engine,
libvlc_video_output_setup_cb setup_cb,
libvlc_video_output_cleanup_cb cleanup_cb,
libvlc_video_output_set_resize_cb resize_cb,
libvlc_video_output_set_window_cb set_window_cb,
libvlc_video_update_output_cb update_output_cb,
libvlc_video_swap_cb swap_cb,
libvlc_video_makeCurrent_cb makeCurrent_cb,
@ -1108,7 +1108,7 @@ bool libvlc_video_set_output_callbacks(libvlc_media_player_t *mp,
var_SetAddress( mp, "vout-cb-opaque", opaque );
var_SetAddress( mp, "vout-cb-setup", setup_cb );
var_SetAddress( mp, "vout-cb-cleanup", cleanup_cb );
var_SetAddress( mp, "vout-cb-resize-cb", resize_cb );
var_SetAddress( mp, "vout-cb-window-cb", set_window_cb );
var_SetAddress( mp, "vout-cb-update-output", update_output_cb );
var_SetAddress( mp, "vout-cb-swap", swap_cb );
var_SetAddress( mp, "vout-cb-get-proc-address", getProcAddress_cb );

35
modules/video_output/wextern.c

@ -48,7 +48,7 @@ vlc_module_end()
typedef struct {
void *opaque;
libvlc_video_output_set_resize_cb setResizeCb;
libvlc_video_output_set_window_cb setWindowCb;
} wextern_t;
static void WindowResize(void *opaque, unsigned width, unsigned height)
@ -57,13 +57,34 @@ static void WindowResize(void *opaque, unsigned width, unsigned height)
vlc_window_ReportSize(window, width, height);
}
static void WindowMouseMoved(void *opaque, int x, int y)
{
vlc_window_t *window = opaque;
vlc_window_ReportMouseMoved(window, x, y);
}
static void WindowMousePress(void *opaque, libvlc_video_output_mouse_button_t button)
{
vlc_window_t *window = opaque;
vlc_window_ReportMousePressed(window, button);
}
static void WindowMouseRelease(void *opaque, libvlc_video_output_mouse_button_t button)
{
vlc_window_t *window = opaque;
vlc_window_ReportMouseReleased(window, button);
}
static int Enable(struct vlc_window *wnd, const vlc_window_cfg_t *wcfg)
{
wextern_t *sys = wnd->sys;
if ( sys->setResizeCb != NULL )
if ( sys->setWindowCb != NULL )
/* bypass the size handling as the window doesn't handle the size */
sys->setResizeCb( sys->opaque, WindowResize, wnd );
sys->setWindowCb( sys->opaque,
WindowResize,
WindowMouseMoved, WindowMousePress, WindowMouseRelease,
wnd );
(void) wcfg;
return VLC_SUCCESS;
@ -73,8 +94,8 @@ static void Disable(struct vlc_window *wnd)
{
wextern_t *sys = wnd->sys;
if ( sys->setResizeCb != NULL )
sys->setResizeCb( sys->opaque, NULL, NULL );
if ( sys->setWindowCb != NULL )
sys->setWindowCb( sys->opaque, NULL, NULL, NULL, NULL, NULL );
}
static const struct vlc_window_operations ops = {
@ -89,11 +110,13 @@ static int Open(vlc_window_t *wnd)
wextern_t *sys = vlc_obj_malloc(VLC_OBJECT(wnd), sizeof(*sys));
if (unlikely(sys==NULL))
return VLC_ENOMEM;
sys->opaque = var_InheritAddress( wnd, "vout-cb-opaque" );
sys->setResizeCb = var_InheritAddress( wnd, "vout-cb-resize-cb" );
sys->setWindowCb = var_InheritAddress( wnd, "vout-cb-window-cb" );
wnd->sys = sys;
wnd->type = VLC_WINDOW_TYPE_DUMMY;
wnd->ops = &ops;
wnd->info.has_double_click = false;
return VLC_SUCCESS;
}

Loading…
Cancel
Save