Commit e8534473 authored by Laurent Aimar's avatar Laurent Aimar

Converted vout xcb to "vout display" API.

parent c48d9cfc
...@@ -34,11 +34,27 @@ ...@@ -34,11 +34,27 @@
#include <xcb/shm.h> #include <xcb/shm.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_vout.h> #include <vlc_vout_display.h>
#include <vlc_vout_window.h>
#include "xcb_vlc.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. * Connect to the X server.
*/ */
...@@ -62,7 +78,7 @@ xcb_connection_t *Connect (vlc_object_t *obj) ...@@ -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, * Create a VLC video X window object, find the corresponding X server screen,
* and probe the MIT-SHM extension. * 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, xcb_connection_t *conn,
const xcb_screen_t **restrict pscreen, const xcb_screen_t **restrict pscreen,
bool *restrict pshm) bool *restrict pshm)
...@@ -73,14 +89,13 @@ vout_window_t *GetWindow (vout_thread_t *obj, ...@@ -73,14 +89,13 @@ vout_window_t *GetWindow (vout_thread_t *obj,
memset( &wnd_cfg, 0, sizeof(wnd_cfg) ); memset( &wnd_cfg, 0, sizeof(wnd_cfg) );
wnd_cfg.type = VOUT_WINDOW_TYPE_XID; wnd_cfg.type = VOUT_WINDOW_TYPE_XID;
wnd_cfg.width = obj->i_window_width; wnd_cfg.width = vd->cfg->display.width;
wnd_cfg.height = obj->i_window_height; wnd_cfg.height = vd->cfg->display.height;
vout_window_t *wnd = vout_window_New (VLC_OBJECT(obj), NULL, &wnd_cfg);
vout_window_t *wnd = vout_display_NewWindow (vd, &wnd_cfg);
if (wnd == NULL) if (wnd == NULL)
{ {
msg_Err (obj, "parent window not available"); msg_Err (vd, "parent window not available");
return NULL; return NULL;
} }
else else
...@@ -92,7 +107,7 @@ vout_window_t *GetWindow (vout_thread_t *obj, ...@@ -92,7 +107,7 @@ vout_window_t *GetWindow (vout_thread_t *obj,
geo = xcb_get_geometry_reply (conn, ck, NULL); geo = xcb_get_geometry_reply (conn, ck, NULL);
if (geo == NULL) if (geo == NULL)
{ {
msg_Err (obj, "parent window not valid"); msg_Err (vd, "parent window not valid");
goto error; goto error;
} }
root = geo->root; root = geo->root;
...@@ -116,13 +131,13 @@ vout_window_t *GetWindow (vout_thread_t *obj, ...@@ -116,13 +131,13 @@ vout_window_t *GetWindow (vout_thread_t *obj,
if (screen == NULL) if (screen == NULL)
{ {
msg_Err (obj, "parent window screen not found"); msg_Err (vd, "parent window screen not found");
goto error; goto error;
} }
msg_Dbg (obj, "using screen 0x%"PRIx32, root); msg_Dbg (vd, "using screen 0x%"PRIx32, root);
/* Check MIT-SHM shared memory support */ /* Check MIT-SHM shared memory support */
bool shm = var_CreateGetBool (obj, "x11-shm") > 0; bool shm = var_CreateGetBool (vd, "x11-shm") > 0;
if (shm) if (shm)
{ {
xcb_shm_query_version_cookie_t ck; xcb_shm_query_version_cookie_t ck;
...@@ -132,8 +147,8 @@ vout_window_t *GetWindow (vout_thread_t *obj, ...@@ -132,8 +147,8 @@ vout_window_t *GetWindow (vout_thread_t *obj,
r = xcb_shm_query_version_reply (conn, ck, NULL); r = xcb_shm_query_version_reply (conn, ck, NULL);
if (!r) if (!r)
{ {
msg_Err (obj, "shared memory (MIT-SHM) not available"); msg_Err (vd, "shared memory (MIT-SHM) not available");
msg_Warn (obj, "display will be slow"); msg_Warn (vd, "display will be slow");
shm = false; shm = false;
} }
free (r); free (r);
...@@ -144,7 +159,7 @@ vout_window_t *GetWindow (vout_thread_t *obj, ...@@ -144,7 +159,7 @@ vout_window_t *GetWindow (vout_thread_t *obj,
return wnd; return wnd;
error: error:
vout_window_Delete (wnd); vout_display_DeleteWindow (vd, wnd);
return NULL; return NULL;
} }
...@@ -168,19 +183,22 @@ int GetWindowSize (struct vout_window_t *wnd, xcb_connection_t *conn, ...@@ -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 * 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). * the X server (MIT-SHM extension).
*/ */
int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size, int PictureResourceAlloc (vout_display_t *vd, picture_resource_t *res, size_t size,
xcb_connection_t *conn) 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 */ /* Allocate shared memory segment */
int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700); int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700);
if (id == -1) 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; return VLC_EGENERIC;
} }
...@@ -188,13 +206,14 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size, ...@@ -188,13 +206,14 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
void *shm = shmat (id, NULL, 0 /* read/write */); void *shm = shmat (id, NULL, 0 /* read/write */);
if (-1 == (intptr_t)shm) 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); shmctl (id, IPC_RMID, 0);
free (res->p_sys);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
xcb_shm_seg_t segment; xcb_shm_seg_t segment;
if (conn != NULL) if (attach)
{ {
/* Attach the segment to X */ /* Attach the segment to X */
xcb_void_cookie_t ck; xcb_void_cookie_t ck;
...@@ -202,9 +221,9 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size, ...@@ -202,9 +221,9 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
segment = xcb_generate_id (conn); segment = xcb_generate_id (conn);
ck = xcb_shm_attach_checked (conn, segment, id, 1); 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; segment = 0;
} }
} }
...@@ -212,67 +231,23 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size, ...@@ -212,67 +231,23 @@ int PictureAlloc (vout_thread_t *vout, picture_t *pic, size_t size,
segment = 0; segment = 0;
shmctl (id, IPC_RMID, 0); shmctl (id, IPC_RMID, 0);
pic->p_sys = (void *)(uintptr_t)segment; res->p_sys->segment = segment;
pic->p->p_pixels = shm; res->p->p_pixels = shm;
pic->i_status = DESTROYED_PICTURE;
pic->i_type = DIRECT_PICTURE;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/** /**
* Release picture private data: detach the shared memory segment. * 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) if (segment != 0)
{ {
assert (conn != NULL); assert (conn != NULL);
xcb_shm_detach (conn, segment); 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 @@ ...@@ -30,7 +30,7 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_vout.h> #include <vlc_vout_display.h>
#include "xcb_vlc.h" #include "xcb_vlc.h"
...@@ -39,76 +39,67 @@ ...@@ -39,76 +39,67 @@
* Otherwise, we'd var_OrInteger() and var_NandInteger() functions... * 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) xcb_button_press_event_t *ev)
{ {
unsigned buttons = var_GetInteger (vout, "mouse-button-down"); vout_display_SendEventMousePressed (vd, ev->detail - 1);
buttons |= (1 << (ev->detail - 1));
var_SetInteger (vout, "mouse-button-down", buttons);
} }
static void HandleButtonRelease (vout_thread_t *vout, static void HandleButtonRelease (vout_display_t *vd,
xcb_button_release_event_t *ev) xcb_button_release_event_t *ev)
{ {
unsigned buttons = var_GetInteger (vout, "mouse-button-down"); vout_display_SendEventMouseReleased (vd, ev->detail - 1);
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;
}
} }
static void HandleMotionNotify (vout_thread_t *vout, static void HandleMotionNotify (vout_display_t *vd,
xcb_motion_notify_event_t *ev) xcb_motion_notify_event_t *ev)
{ {
unsigned x, y, width, height; vout_display_place_t place;
int v;
/* TODO it could be saved */
vout_PlacePicture (vout, vout->output.i_width, vout->output.i_height, vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
&x, &y, &width, &height);
v = vout->fmt_in.i_x_offset if (place.width <= 0 || place.height <= 0)
+ ((ev->event_x - x) * vout->fmt_in.i_visible_width / width); return;
if (v < 0)
v = 0; /* to the left of the picture */ const int x = vd->source.i_x_offset +
else if ((unsigned)v > vout->fmt_in.i_width) (int64_t)(ev->event_x -0*place.x) * vd->source.i_visible_width / place.width;
v = vout->fmt_in.i_width; /* to the right of the picture */ const int y = vd->source.i_y_offset +
var_SetInteger (vout, "mouse-x", v); (int64_t)(ev->event_y -0*place.y) * vd->source.i_visible_height/ place.height;
v = vout->fmt_in.i_y_offset /* TODO show the cursor ? */
+ ((ev->event_y - y) * vout->fmt_in.i_visible_height / height); if (x >= vd->source.i_x_offset && x < vd->source.i_x_offset + vd->source.i_visible_width &&
if (v < 0) y >= vd->source.i_y_offset && y < vd->source.i_y_offset + vd->source.i_visible_height)
v = 0; /* above the picture */ vout_display_SendEventMouseMoved (vd, x, y);
else if ((unsigned)v > vout->fmt_in.i_height) }
v = vout->fmt_in.i_height; /* below the picture */
var_SetInteger (vout, "mouse-y", v); 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. * Process an X11 event.
*/ */
int ProcessEvent (vout_thread_t *vout, xcb_connection_t *conn, static int ProcessEvent (vout_display_t *vd,
xcb_window_t window, xcb_generic_event_t *ev) xcb_window_t window, xcb_generic_event_t *ev)
{ {
switch (ev->response_type & 0x7f) switch (ev->response_type & 0x7f)
{ {
case XCB_BUTTON_PRESS: case XCB_BUTTON_PRESS:
HandleButtonPress (vout, (xcb_button_press_event_t *)ev); HandleButtonPress (vd, (xcb_button_press_event_t *)ev);
break; break;
case XCB_BUTTON_RELEASE: case XCB_BUTTON_RELEASE:
HandleButtonRelease (vout, (xcb_button_release_event_t *)ev); HandleButtonRelease (vd, (xcb_button_release_event_t *)ev);
break; break;
case XCB_MOTION_NOTIFY: case XCB_MOTION_NOTIFY:
HandleMotionNotify (vout, (xcb_motion_notify_event_t *)ev); HandleMotionNotify (vd, (xcb_motion_notify_event_t *)ev);
break; break;
case XCB_CONFIGURE_NOTIFY: case XCB_CONFIGURE_NOTIFY:
...@@ -117,14 +108,41 @@ int ProcessEvent (vout_thread_t *vout, xcb_connection_t *conn, ...@@ -117,14 +108,41 @@ int ProcessEvent (vout_thread_t *vout, xcb_connection_t *conn,
(xcb_configure_notify_event_t *)ev; (xcb_configure_notify_event_t *)ev;
assert (cn->window != window); assert (cn->window != window);
HandleParentStructure (vout, conn, window, cn); HandleParentStructure (vd, cn);
break; break;
} }
/* FIXME I am not sure it is the right one */
case XCB_DESTROY_NOTIFY:
vout_display_SendEventClose (vd);
break;
default: default:
msg_Dbg (vout, "unhandled event %"PRIu8, ev->response_type); msg_Dbg (vd, "unhandled event %"PRIu8, ev->response_type);
} }
free (ev); free (ev);
return VLC_SUCCESS; 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 @@ ...@@ -26,12 +26,10 @@
# define ORDER XCB_IMAGE_ORDER_LSB_FIRST # define ORDER XCB_IMAGE_ORDER_LSB_FIRST
#endif #endif
int CheckError (vout_thread_t *, const char *str, xcb_void_cookie_t); #include <vlc_picture.h>
int ProcessEvent (vout_thread_t *, xcb_connection_t *, xcb_window_t, #include <vlc_vout_display.h>
xcb_generic_event_t *);
void HandleParentStructure (vout_thread_t *vout, xcb_connection_t *conn,
xcb_window_t xid, xcb_configure_notify_event_t *ev);
int ManageEvent (vout_display_t *vd, xcb_connection_t *conn, xcb_window_t window);
/* keys.c */ /* keys.c */
typedef struct key_handler_t key_handler_t; typedef struct key_handler_t key_handler_t;
...@@ -40,15 +38,25 @@ void DestroyKeyHandler (key_handler_t *); ...@@ -40,15 +38,25 @@ void DestroyKeyHandler (key_handler_t *);
int ProcessKeyEvent (key_handler_t *, xcb_generic_event_t *); int ProcessKeyEvent (key_handler_t *, xcb_generic_event_t *);
/* common.c */ /* common.c */
struct vout_window_t;
xcb_connection_t *Connect (vlc_object_t *obj); 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, xcb_connection_t *pconn,
const xcb_screen_t **restrict pscreen, const xcb_screen_t **restrict pscreen,
bool *restrict pshm); bool *restrict pshm);
int GetWindowSize (struct vout_window_t *wnd, xcb_connection_t *conn, int GetWindowSize (struct vout_window_t *wnd, xcb_connection_t *conn,
unsigned *restrict width, unsigned *restrict height); 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); int CheckError (vout_display_t *, xcb_connection_t *conn,
void CommonManage (vout_thread_t *); 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