Commit e8534473 authored by Laurent Aimar's avatar Laurent Aimar

Converted vout xcb to "vout display" API.

parent c48d9cfc
......@@ -34,11 +34,27 @@
#include <xcb/shm.h>
#include <vlc_common.h>
#include <vlc_vout.h>
#include <vlc_vout_window.h>
#include <vlc_vout_display.h>
#include "xcb_vlc.h"
/**
* Check for an error
*/
int CheckError (vout_display_t *vd, xcb_connection_t *conn,
const char *str, xcb_void_cookie_t ck)
{
xcb_generic_error_t *err;
err = xcb_request_check (conn, ck);
if (err)
{
msg_Err (vd, "%s: X11 error %d", str, err->error_code);
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
/**
* Connect to the X server.
*/
......@@ -62,7 +78,7 @@ xcb_connection_t *Connect (vlc_object_t *obj)
* Create a VLC video X window object, find the corresponding X server screen,
* and probe the MIT-SHM extension.
*/
vout_window_t *GetWindow (vout_thread_t *obj,
vout_window_t *GetWindow (vout_display_t *vd,
xcb_connection_t *conn,
const xcb_screen_t **restrict pscreen,
bool *restrict pshm)
......@@ -73,14 +89,13 @@ vout_window_t *GetWindow (vout_thread_t *obj,
memset( &wnd_cfg, 0, sizeof(wnd_cfg) );
wnd_cfg.type = VOUT_WINDOW_TYPE_XID;
wnd_cfg.width = obj->i_window_width;
wnd_cfg.height = obj->i_window_height;
vout_window_t *wnd = vout_window_New (VLC_OBJECT(obj), NULL, &wnd_cfg);
wnd_cfg.width = vd->cfg->display.width;
wnd_cfg.height = vd->cfg->display.height;
vout_window_t *wnd = vout_display_NewWindow (vd, &wnd_cfg);
if (wnd == NULL)
{
msg_Err (obj, "parent window not available");
msg_Err (vd, "parent window not available");
return NULL;
}
else
......@@ -92,7 +107,7 @@ vout_window_t *GetWindow (vout_thread_t *obj,
geo = xcb_get_geometry_reply (conn, ck, NULL);
if (geo == NULL)
{
msg_Err (obj, "parent window not valid");
msg_Err (vd, "parent window not valid");
goto error;
}
root = geo->root;
......@@ -116,13 +131,13 @@ vout_window_t *GetWindow (vout_thread_t *obj,
if (screen == NULL)
{
msg_Err (obj, "parent window screen not found");
msg_Err (vd, "parent window screen not found");
goto error;
}
msg_Dbg (obj, "using screen 0x%"PRIx32, root);
msg_Dbg (vd, "using screen 0x%"PRIx32, root);
/* Check MIT-SHM shared memory support */
bool shm = var_CreateGetBool (obj, "x11-shm") > 0;
bool shm = var_CreateGetBool (vd, "x11-shm") > 0;
if (shm)
{
xcb_shm_query_version_cookie_t ck;
......@@ -132,8 +147,8 @@ vout_window_t *GetWindow (vout_thread_t *obj,
r = xcb_shm_query_version_reply (conn, ck, NULL);
if (!r)
{
msg_Err (obj, "shared memory (MIT-SHM) not available");
msg_Warn (obj, "display will be slow");
msg_Err (vd, "shared memory (MIT-SHM) not available");
msg_Warn (vd, "display will be slow");
shm = false;
}
free (r);
......@@ -144,7 +159,7 @@ vout_window_t *GetWindow (vout_thread_t *obj,
return wnd;
error:
vout_window_Delete (wnd);
vout_display_DeleteWindow (vd, wnd);
return NULL;
}
......@@ -168,19 +183,22 @@ int GetWindowSize (struct vout_window_t *wnd, xcb_connection_t *conn,
/**
* Initialize a picture buffer as shared memory, according to the video output
* format. If a XCB connection pointer is supplied, the segment is attached to
* format. If a attach is true, the segment is attached to
* the X server (MIT-SHM extension).
*/
int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
xcb_connection_t *conn)
int PictureResourceAlloc (vout_display_t *vd, picture_resource_t *res, size_t size,
xcb_connection_t *conn, bool attach)
{
assert (pic->i_status == FREE_PICTURE);
res->p_sys = malloc (sizeof(*res->p_sys));
if (!res->p_sys)
return VLC_EGENERIC;
/* Allocate shared memory segment */
int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700);
if (id == -1)
{
msg_Err (vout, "shared memory allocation error: %m");
msg_Err (vd, "shared memory allocation error: %m");
free (res->p_sys);
return VLC_EGENERIC;
}
......@@ -188,13 +206,14 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
void *shm = shmat (id, NULL, 0 /* read/write */);
if (-1 == (intptr_t)shm)
{
msg_Err (vout, "shared memory attachment error: %m");
msg_Err (vd, "shared memory attachment error: %m");
shmctl (id, IPC_RMID, 0);
free (res->p_sys);
return VLC_EGENERIC;
}
xcb_shm_seg_t segment;
if (conn != NULL)
if (attach)
{
/* Attach the segment to X */
xcb_void_cookie_t ck;
......@@ -202,9 +221,9 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
segment = xcb_generate_id (conn);
ck = xcb_shm_attach_checked (conn, segment, id, 1);
if (CheckError (vout, "shared memory server-side error", ck))
if (CheckError (vd, conn, "shared memory server-side error", ck))
{
msg_Info (vout, "using buggy X11 server - SSH proxying?");
msg_Info (vd, "using buggy X11 server - SSH proxying?");
segment = 0;
}
}
......@@ -212,67 +231,23 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
segment = 0;
shmctl (id, IPC_RMID, 0);
pic->p_sys = (void *)(uintptr_t)segment;
pic->p->p_pixels = shm;
pic->i_status = DESTROYED_PICTURE;
pic->i_type = DIRECT_PICTURE;
res->p_sys->segment = segment;
res->p->p_pixels = shm;
return VLC_SUCCESS;
}
/**
* Release picture private data: detach the shared memory segment.
*/
void PictureFree (picture_t *pic, xcb_connection_t *conn)
void PictureResourceFree (picture_resource_t *res, xcb_connection_t *conn)
{
xcb_shm_seg_t segment = (uintptr_t)pic->p_sys;
xcb_shm_seg_t segment = res->p_sys->segment;
if (segment != 0)
{
assert (conn != NULL);
xcb_shm_detach (conn, segment);
}
shmdt (pic->p->p_pixels);
shmdt (res->p->p_pixels);
}
/**
* Video output thread management stuff.
* FIXME: Much of this should move to core
*/
void CommonManage (vout_thread_t *vout)
{
if (vout->i_changes & VOUT_SCALE_CHANGE)
{
vout->b_autoscale = var_GetBool (vout, "autoscale");
vout->i_zoom = ZOOM_FP_FACTOR;
vout->i_changes &= ~VOUT_SCALE_CHANGE;
vout->i_changes |= VOUT_SIZE_CHANGE;
}
if (vout->i_changes & VOUT_ZOOM_CHANGE)
{
vout->b_autoscale = false;
vout->i_zoom = var_GetFloat (vout, "scale") * ZOOM_FP_FACTOR;
vout->i_changes &= ~VOUT_ZOOM_CHANGE;
vout->i_changes |= VOUT_SIZE_CHANGE;
}
if (vout->i_changes & VOUT_CROP_CHANGE)
{
vout->fmt_out.i_x_offset = vout->fmt_in.i_x_offset;
vout->fmt_out.i_y_offset = vout->fmt_in.i_y_offset;
vout->fmt_out.i_visible_width = vout->fmt_in.i_visible_width;
vout->fmt_out.i_visible_height = vout->fmt_in.i_visible_height;
vout->i_changes &= ~VOUT_CROP_CHANGE;
vout->i_changes |= VOUT_SIZE_CHANGE;
}
if (vout->i_changes & VOUT_ASPECT_CHANGE)
{
vout->fmt_out.i_aspect = vout->fmt_in.i_aspect;
vout->fmt_out.i_sar_num = vout->fmt_in.i_sar_num;
vout->fmt_out.i_sar_den = vout->fmt_in.i_sar_den;
vout->output.i_aspect = vout->fmt_in.i_aspect;
vout->i_changes &= ~VOUT_ASPECT_CHANGE;
vout->i_changes |= VOUT_SIZE_CHANGE;
}
}
......@@ -30,7 +30,7 @@
#include <xcb/xcb.h>
#include <vlc_common.h>
#include <vlc_vout.h>
#include <vlc_vout_display.h>
#include "xcb_vlc.h"
......@@ -39,76 +39,67 @@
* Otherwise, we'd var_OrInteger() and var_NandInteger() functions...
*/
static void HandleButtonPress (vout_thread_t *vout,
/* FIXME we assume direct mapping between XCB and VLC */
static void HandleButtonPress (vout_display_t *vd,
xcb_button_press_event_t *ev)
{
unsigned buttons = var_GetInteger (vout, "mouse-button-down");
buttons |= (1 << (ev->detail - 1));
var_SetInteger (vout, "mouse-button-down", buttons);
vout_display_SendEventMousePressed (vd, ev->detail - 1);
}
static void HandleButtonRelease (vout_thread_t *vout,
static void HandleButtonRelease (vout_display_t *vd,
xcb_button_release_event_t *ev)
{
unsigned buttons = var_GetInteger (vout, "mouse-button-down");
buttons &= ~(1 << (ev->detail - 1));
var_SetInteger (vout, "mouse-button-down", buttons);
switch (ev->detail)
{
case 1: /* left mouse button */
var_SetBool (vout, "mouse-clicked", true);
var_SetBool (vout->p_libvlc, "intf-popupmenu", false);
break;
case 3:
var_SetBool (vout->p_libvlc, "intf-popupmenu", true);
break;
}
vout_display_SendEventMouseReleased (vd, ev->detail - 1);
}
static void HandleMotionNotify (vout_thread_t *vout,
static void HandleMotionNotify (vout_display_t *vd,
xcb_motion_notify_event_t *ev)
{
unsigned x, y, width, height;
int v;
vout_PlacePicture (vout, vout->output.i_width, vout->output.i_height,
&x, &y, &width, &height);
v = vout->fmt_in.i_x_offset
+ ((ev->event_x - x) * vout->fmt_in.i_visible_width / width);
if (v < 0)
v = 0; /* to the left of the picture */
else if ((unsigned)v > vout->fmt_in.i_width)
v = vout->fmt_in.i_width; /* to the right of the picture */
var_SetInteger (vout, "mouse-x", v);
v = vout->fmt_in.i_y_offset
+ ((ev->event_y - y) * vout->fmt_in.i_visible_height / height);
if (v < 0)
v = 0; /* above the picture */
else if ((unsigned)v > vout->fmt_in.i_height)
v = vout->fmt_in.i_height; /* below the picture */
var_SetInteger (vout, "mouse-y", v);
vout_display_place_t place;
/* TODO it could be saved */
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
if (place.width <= 0 || place.height <= 0)
return;
const int x = vd->source.i_x_offset +
(int64_t)(ev->event_x -0*place.x) * vd->source.i_visible_width / place.width;
const int y = vd->source.i_y_offset +
(int64_t)(ev->event_y -0*place.y) * vd->source.i_visible_height/ place.height;
/* TODO show the cursor ? */
if (x >= vd->source.i_x_offset && x < vd->source.i_x_offset + vd->source.i_visible_width &&
y >= vd->source.i_y_offset && y < vd->source.i_y_offset + vd->source.i_visible_height)
vout_display_SendEventMouseMoved (vd, x, y);
}
static void
HandleParentStructure (vout_display_t *vd, xcb_configure_notify_event_t *ev)
{
if (ev->width != vd->cfg->display.width ||
ev->height != vd->cfg->display.height)
vout_display_SendEventDisplaySize (vd, ev->width, ev->height);
}
/**
* Process an X11 event.
*/
int ProcessEvent (vout_thread_t *vout, xcb_connection_t *conn,
xcb_window_t window, xcb_generic_event_t *ev)
static int ProcessEvent (vout_display_t *vd,
xcb_window_t window, xcb_generic_event_t *ev)
{
switch (ev->response_type & 0x7f)
{
case XCB_BUTTON_PRESS:
HandleButtonPress (vout, (xcb_button_press_event_t *)ev);
HandleButtonPress (vd, (xcb_button_press_event_t *)ev);
break;
case XCB_BUTTON_RELEASE:
HandleButtonRelease (vout, (xcb_button_release_event_t *)ev);
HandleButtonRelease (vd, (xcb_button_release_event_t *)ev);
break;
case XCB_MOTION_NOTIFY:
HandleMotionNotify (vout, (xcb_motion_notify_event_t *)ev);
HandleMotionNotify (vd, (xcb_motion_notify_event_t *)ev);
break;
case XCB_CONFIGURE_NOTIFY:
......@@ -117,14 +108,41 @@ int ProcessEvent (vout_thread_t *vout, xcb_connection_t *conn,
(xcb_configure_notify_event_t *)ev;
assert (cn->window != window);
HandleParentStructure (vout, conn, window, cn);
HandleParentStructure (vd, cn);
break;
}
/* FIXME I am not sure it is the right one */
case XCB_DESTROY_NOTIFY:
vout_display_SendEventClose (vd);
break;
default:
msg_Dbg (vout, "unhandled event %"PRIu8, ev->response_type);
msg_Dbg (vd, "unhandled event %"PRIu8, ev->response_type);
}
free (ev);
return VLC_SUCCESS;
}
/**
* Process incoming X events.
*/
int ManageEvent (vout_display_t *vd, xcb_connection_t *conn, xcb_window_t window)
{
xcb_generic_event_t *ev;
while ((ev = xcb_poll_for_event (conn)) != NULL)
ProcessEvent (vd, window, ev);
if (xcb_connection_has_error (conn))
{
msg_Err (vd, "X server failure");
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
This diff is collapsed.
......@@ -26,12 +26,10 @@
# define ORDER XCB_IMAGE_ORDER_LSB_FIRST
#endif
int CheckError (vout_thread_t *, const char *str, xcb_void_cookie_t);
int ProcessEvent (vout_thread_t *, xcb_connection_t *, xcb_window_t,
xcb_generic_event_t *);
void HandleParentStructure (vout_thread_t *vout, xcb_connection_t *conn,
xcb_window_t xid, xcb_configure_notify_event_t *ev);
#include <vlc_picture.h>
#include <vlc_vout_display.h>
int ManageEvent (vout_display_t *vd, xcb_connection_t *conn, xcb_window_t window);
/* keys.c */
typedef struct key_handler_t key_handler_t;
......@@ -40,15 +38,25 @@ void DestroyKeyHandler (key_handler_t *);
int ProcessKeyEvent (key_handler_t *, xcb_generic_event_t *);
/* common.c */
struct vout_window_t;
xcb_connection_t *Connect (vlc_object_t *obj);
struct vout_window_t *GetWindow (vout_thread_t *obj,
struct vout_window_t *GetWindow (vout_display_t *obj,
xcb_connection_t *pconn,
const xcb_screen_t **restrict pscreen,
bool *restrict pshm);
int GetWindowSize (struct vout_window_t *wnd, xcb_connection_t *conn,
unsigned *restrict width, unsigned *restrict height);
int PictureAlloc (vout_thread_t *, picture_t *, size_t, xcb_connection_t *);
void PictureFree (picture_t *pic, xcb_connection_t *conn);
void CommonManage (vout_thread_t *);
int CheckError (vout_display_t *, xcb_connection_t *conn,
const char *str, xcb_void_cookie_t);
/* FIXME
* maybe it would be better to split this header in 2 */
#include <xcb/shm.h>
struct picture_sys_t
{
xcb_shm_seg_t segment;
};
int PictureResourceAlloc (vout_display_t *vd, picture_resource_t *res, size_t size,
xcb_connection_t *conn, bool attach);
void PictureResourceFree (picture_resource_t *res, xcb_connection_t *conn);
This diff is collapsed.
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