Commit c3c376c3 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

window: pass mouse state directly from window to filters

Avoid a pointless round-trip to the display.
parent 07e804d8
......@@ -24,7 +24,6 @@
#ifndef LIBVLC_VOUT_INTERNAL_CONTROL_H
#define LIBVLC_VOUT_INTERNAL_CONTROL_H
#include <vlc_vout_window.h>
#include <vlc_viewpoint.h>
/* */
......@@ -54,7 +53,7 @@ enum {
VOUT_CONTROL_FULLSCREEN, /* bool */
VOUT_CONTROL_WINDOW_STATE, /* unsigned */
VOUT_CONTROL_WINDOW_MOUSE, /* window_mouse */
VOUT_CONTROL_MOUSE_STATE, /* vlc_mouse_t */
VOUT_CONTROL_DISPLAY_FILLED, /* bool */
VOUT_CONTROL_ZOOM, /* pair */
......@@ -98,7 +97,7 @@ typedef struct {
unsigned width;
unsigned height;
} window;
vout_window_mouse_event_t window_mouse;
vlc_mouse_t mouse;
const vout_configuration_t *cfg;
subpicture_t *subpicture;
vlc_viewpoint_t viewpoint;
......
......@@ -359,13 +359,12 @@ void vout_DisplayTitle(vout_thread_t *vout, const char *title)
vout_control_PushString(&vout->p->control, VOUT_CONTROL_OSD_TITLE, title);
}
void vout_WindowMouseEvent(vout_thread_t *vout,
const vout_window_mouse_event_t *mouse)
void vout_MouseState(vout_thread_t *vout, const vlc_mouse_t *mouse)
{
assert(mouse);
vout_control_cmd_t cmd;
vout_control_cmd_Init(&cmd, VOUT_CONTROL_WINDOW_MOUSE);
cmd.u.window_mouse = *mouse;
vout_control_cmd_Init(&cmd, VOUT_CONTROL_MOUSE_STATE);
cmd.u.mouse = *mouse;
vout_control_Push(&vout->p->control, &cmd);
}
......@@ -1390,43 +1389,31 @@ static void ThreadChangeWindowState(vout_thread_t *vout, unsigned state)
#endif
}
static void ThreadChangeWindowMouse(vout_thread_t *vout,
const vout_window_mouse_event_t *mouse)
static void ThreadTranslateMouseState(vout_thread_t *vout,
const vlc_mouse_t *win_mouse)
{
vout_display_t *vd = vout->p->display.vd;
switch (mouse->type)
{
case VOUT_WINDOW_MOUSE_MOVED:
{
vout_display_place_t place;
vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
vlc_mouse_t vid_mouse;
vout_display_place_t place;
if (place.width <= 0 || place.height <= 0)
return;
/* Translate window coordinates to video coordinates */
vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
const int x = vd->source.i_x_offset +
(int64_t)(mouse->x - place.x) *
vd->source.i_visible_width / place.width;
const int y = vd->source.i_y_offset +
(int64_t)(mouse->y - place.y) *
vd->source.i_visible_height/ place.height;
if (place.width <= 0 || place.height <= 0)
return;
vout_display_SendEventMouseMoved(vd, x, y);
break;
}
case VOUT_WINDOW_MOUSE_PRESSED:
vout_display_SendEventMousePressed(vd, mouse->button_mask);
break;
case VOUT_WINDOW_MOUSE_RELEASED:
vout_display_SendEventMouseReleased(vd, mouse->button_mask);
break;
case VOUT_WINDOW_MOUSE_DOUBLE_CLICK:
if (mouse->button_mask == 0)
vout_display_SendEventMouseDoubleClick(vd);
break;
default: vlc_assert_unreachable();
break;
}
const int x = vd->source.i_x_offset
+ (int64_t)(win_mouse->i_x - place.x)
* vd->source.i_visible_width / place.width;
const int y = vd->source.i_y_offset
+ (int64_t)(win_mouse->i_y - place.y)
* vd->source.i_visible_height / place.height;
vid_mouse = *win_mouse;
vlc_mouse_SetPosition(&vid_mouse, x, y);
/* Then pass up the filter chains. */
vout_SendDisplayEventMouse(vout, &vid_mouse);
}
static void ThreadChangeDisplayFilled(vout_thread_t *vout, bool is_filled)
......@@ -1740,8 +1727,8 @@ static int ThreadControl(vout_thread_t *vout, vout_control_cmd_t cmd)
case VOUT_CONTROL_WINDOW_STATE:
ThreadChangeWindowState(vout, cmd.u.integer);
break;
case VOUT_CONTROL_WINDOW_MOUSE:
ThreadChangeWindowMouse(vout, &cmd.u.window_mouse);
case VOUT_CONTROL_MOUSE_STATE:
ThreadTranslateMouseState(vout, &cmd.u.mouse);
break;
case VOUT_CONTROL_DISPLAY_FILLED:
ThreadChangeDisplayFilled(vout, cmd.u.boolean);
......
......@@ -218,14 +218,17 @@ int spu_ProcessMouse(spu_t *, const vlc_mouse_t *, const video_format_t *);
void spu_Attach( spu_t *, vlc_object_t *input, bool );
void spu_ChangeMargin(spu_t *, int);
typedef struct vout_window_mouse_event_t vout_window_mouse_event_t;
/**
* This function will (un)pause the display of pictures.
* It is thread safe
*/
void vout_ChangePause( vout_thread_t *, bool b_paused, mtime_t i_date );
/**
* Updates the pointing device state.
*/
void vout_MouseState(vout_thread_t *, const vlc_mouse_t *);
/**
* This function will apply an offset on subtitle subpicture.
*/
......@@ -259,9 +262,6 @@ void vout_NextPicture( vout_thread_t *p_vout, mtime_t *pi_duration );
*/
void vout_DisplayTitle( vout_thread_t *p_vout, const char *psz_title );
void vout_WindowMouseEvent( vout_thread_t *p_vout,
const vout_window_mouse_event_t *mouse );
/**
* This function will return true if no more pictures are to be displayed.
*/
......
......@@ -125,11 +125,15 @@ void vout_window_SetInhibition(vout_window_t *window, bool enabled)
#include "window.h"
#include "event.h"
#define DOUBLE_CLICK_TIME (3 * CLOCK_FREQ / 10)
typedef struct vout_display_window
{
vout_display_t *vd;
unsigned width;
unsigned height;
vlc_mouse_t mouse;
mtime_t last_left_press;
vlc_mutex_t lock;
} vout_display_window_t;
......@@ -157,10 +161,55 @@ static void vout_display_window_CloseNotify(vout_window_t *window)
}
static void vout_display_window_MouseEvent(vout_window_t *window,
const vout_window_mouse_event_t *mouse)
const vout_window_mouse_event_t *ev)
{
vout_display_window_t *state = window->owner.sys;
vout_thread_t *vout = (vout_thread_t *)window->obj.parent;
vout_WindowMouseEvent(vout, mouse);
vlc_mouse_t *m = &state->mouse;
m->b_double_click = false;
switch (ev->type)
{
case VOUT_WINDOW_MOUSE_MOVED:
vlc_mouse_SetPosition(m, ev->x, ev->y);
state->last_left_press = INT64_MIN;
break;
case VOUT_WINDOW_MOUSE_PRESSED:
if (!window->info.has_double_click
&& ev->button_mask == MOUSE_BUTTON_LEFT
&& !vlc_mouse_IsLeftPressed(m))
{
const mtime_t now = mdate();
if (state->last_left_press != INT64_MIN
&& now - state->last_left_press < DOUBLE_CLICK_TIME)
{
m->b_double_click = true;
state->last_left_press = INT64_MIN;
}
else
state->last_left_press = now;
}
vlc_mouse_SetPressed(m, ev->button_mask);
break;
case VOUT_WINDOW_MOUSE_RELEASED:
vlc_mouse_SetReleased(m, ev->button_mask);
break;
case VOUT_WINDOW_MOUSE_DOUBLE_CLICK:
assert(window->info.has_double_click);
m->b_double_click = true;
break;
default:
vlc_assert_unreachable();
}
vout_MouseState(vout, m);
}
static void vout_display_window_KeyboardEvent(vout_window_t *window,
......@@ -191,6 +240,8 @@ vout_window_t *vout_display_window_New(vout_thread_t *vout,
state->vd = NULL;
state->width = cfg->width;
state->height = cfg->height;
vlc_mouse_Init(&state->mouse);
state->last_left_press = INT64_MIN;
vlc_mutex_init(&state->lock);
char *modlist = var_InheritString(vout, "window");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment