sys/: When we create our own window, indicate that we handle the
Original commit message from CVS: * sys/ximage/ximagesink.c: (gst_ximagesink_ximage_put), (gst_ximagesink_xwindow_new), (gst_ximagesink_handle_xevents), (gst_ximagesink_show_frame): * sys/xvimage/xvimagesink.c: (gst_xvimagesink_xvimage_put), (gst_xvimagesink_xwindow_new), (gst_xvimagesink_handle_xevents), (gst_xvimagesink_show_frame): When we create our own window, indicate that we handle the WM_DELETE client message from the window manager, so that it won't kill our window (and our app) along with it. Handle ClientMessage, post an error on the bus, and close the window. Further buffers arriving will result in a FlowError because the window has been destroyed. Fixes: #393975 Clean up the X event handling loop and make them the same for both xvimagesink and ximagesink while I'm at it.
This commit is contained in:
parent
a18a10e81f
commit
cbc95dfb3d
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
|||||||
|
2007-05-17 Jan Schmidt <thaytan@mad.scientist.com>
|
||||||
|
|
||||||
|
* sys/ximage/ximagesink.c: (gst_ximagesink_ximage_put),
|
||||||
|
(gst_ximagesink_xwindow_new), (gst_ximagesink_handle_xevents),
|
||||||
|
(gst_ximagesink_show_frame):
|
||||||
|
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_xvimage_put),
|
||||||
|
(gst_xvimagesink_xwindow_new), (gst_xvimagesink_handle_xevents),
|
||||||
|
(gst_xvimagesink_show_frame):
|
||||||
|
When we create our own window, indicate that we handle the
|
||||||
|
WM_DELETE client message from the window manager, so that it won't
|
||||||
|
kill our window (and our app) along with it. Handle ClientMessage,
|
||||||
|
post an error on the bus, and close the window. Further buffers
|
||||||
|
arriving will result in a FlowError because the window has been
|
||||||
|
destroyed.
|
||||||
|
|
||||||
|
Fixes: #393975
|
||||||
|
|
||||||
|
Clean up the X event handling loop and make them the same for
|
||||||
|
both xvimagesink and ximagesink while I'm at it.
|
||||||
|
|
||||||
2007-05-17 Wim Taymans <wim@fluendo.com>
|
2007-05-17 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/playback/gstdecodebin2.c: (gst_decode_bin_factory_filter):
|
* gst/playback/gstdecodebin2.c: (gst_decode_bin_factory_filter):
|
||||||
|
@ -668,13 +668,13 @@ gst_ximagesink_xwindow_draw_borders (GstXImageSink * ximagesink,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function puts a GstXImageBuffer on a GstXImageSink's window */
|
/* This function puts a GstXImageBuffer on a GstXImageSink's window */
|
||||||
static void
|
static gboolean
|
||||||
gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
|
gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstVideoRectangle src, dst, result;
|
GstVideoRectangle src, dst, result;
|
||||||
gboolean draw_border = FALSE;
|
gboolean draw_border = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), FALSE);
|
||||||
|
|
||||||
/* We take the flow_lock. If expose is in there we don't want to run
|
/* We take the flow_lock. If expose is in there we don't want to run
|
||||||
concurrently from the data flow thread */
|
concurrently from the data flow thread */
|
||||||
@ -682,7 +682,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
|
|||||||
|
|
||||||
if (G_UNLIKELY (ximagesink->xwindow == NULL)) {
|
if (G_UNLIKELY (ximagesink->xwindow == NULL)) {
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw borders when displaying the first frame. After this
|
/* Draw borders when displaying the first frame. After this
|
||||||
@ -709,7 +709,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
|
|||||||
ximage = ximagesink->cur_image;
|
ximage = ximagesink->cur_image;
|
||||||
} else {
|
} else {
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,6 +754,8 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
|
|||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -818,9 +820,18 @@ gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height)
|
|||||||
XSetWindowBackgroundPixmap (ximagesink->xcontext->disp, xwindow->win, None);
|
XSetWindowBackgroundPixmap (ximagesink->xcontext->disp, xwindow->win, None);
|
||||||
|
|
||||||
if (ximagesink->handle_events) {
|
if (ximagesink->handle_events) {
|
||||||
|
Atom wm_delete;
|
||||||
|
|
||||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||||
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||||
|
|
||||||
|
/* Tell the window manager we'd like delete client messages instead of
|
||||||
|
* being killed */
|
||||||
|
wm_delete = XInternAtom (ximagesink->xcontext->disp,
|
||||||
|
"WM_DELETE_WINDOW", False);
|
||||||
|
(void) XSetWMProtocols (ximagesink->xcontext->disp, xwindow->win,
|
||||||
|
&wm_delete, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->win,
|
xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->win,
|
||||||
@ -911,48 +922,48 @@ static void
|
|||||||
gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
|
gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
|
||||||
{
|
{
|
||||||
XEvent e;
|
XEvent e;
|
||||||
|
guint pointer_x = 0, pointer_y = 0;
|
||||||
|
gboolean pointer_moved = FALSE;
|
||||||
|
gboolean exposed = FALSE, configured = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
||||||
|
|
||||||
{
|
/* Then we get all pointer motion events, only the last position is
|
||||||
guint pointer_x = 0, pointer_y = 0;
|
interesting. */
|
||||||
gboolean pointer_moved = FALSE;
|
g_mutex_lock (ximagesink->flow_lock);
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
/* Then we get all pointer motion events, only the last position is
|
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||||
interesting. */
|
ximagesink->xwindow->win, PointerMotionMask, &e)) {
|
||||||
g_mutex_lock (ximagesink->flow_lock);
|
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
|
||||||
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
|
||||||
ximagesink->xwindow->win, PointerMotionMask, &e)) {
|
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
|
||||||
|
|
||||||
switch (e.type) {
|
|
||||||
case MotionNotify:
|
|
||||||
pointer_x = e.xmotion.x;
|
|
||||||
pointer_y = e.xmotion.y;
|
|
||||||
pointer_moved = TRUE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
g_mutex_lock (ximagesink->flow_lock);
|
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
|
||||||
}
|
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
|
|
||||||
if (pointer_moved) {
|
switch (e.type) {
|
||||||
GST_DEBUG ("ximagesink pointer moved over window at %d,%d",
|
case MotionNotify:
|
||||||
pointer_x, pointer_y);
|
pointer_x = e.xmotion.x;
|
||||||
gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
|
pointer_y = e.xmotion.y;
|
||||||
"mouse-move", 0, pointer_x, pointer_y);
|
pointer_moved = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
g_mutex_lock (ximagesink->flow_lock);
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointer_moved) {
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
|
|
||||||
|
GST_DEBUG ("ximagesink pointer moved over window at %d,%d",
|
||||||
|
pointer_x, pointer_y);
|
||||||
|
gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
|
||||||
|
"mouse-move", 0, pointer_x, pointer_y);
|
||||||
|
|
||||||
|
g_mutex_lock (ximagesink->flow_lock);
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We get all remaining events on our window to throw them upstream */
|
/* We get all remaining events on our window to throw them upstream */
|
||||||
g_mutex_lock (ximagesink->flow_lock);
|
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
|
||||||
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||||
ximagesink->xwindow->win,
|
ximagesink->xwindow->win,
|
||||||
KeyPressMask | KeyReleaseMask |
|
KeyPressMask | KeyReleaseMask |
|
||||||
@ -1009,36 +1020,60 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
|
|||||||
g_mutex_lock (ximagesink->flow_lock);
|
g_mutex_lock (ximagesink->flow_lock);
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
}
|
}
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
|
||||||
|
|
||||||
{
|
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||||
gboolean exposed = FALSE;
|
ximagesink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) {
|
||||||
|
switch (e.type) {
|
||||||
g_mutex_lock (ximagesink->flow_lock);
|
case Expose:
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
exposed = TRUE;
|
||||||
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
break;
|
||||||
ximagesink->xwindow->win, ExposureMask, &e)) {
|
case ConfigureNotify:
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
configured = TRUE;
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
break;
|
||||||
|
default:
|
||||||
switch (e.type) {
|
break;
|
||||||
case Expose:
|
|
||||||
exposed = TRUE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
g_mutex_lock (ximagesink->flow_lock);
|
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exposed || configured) {
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
g_mutex_unlock (ximagesink->flow_lock);
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
|
|
||||||
if (exposed) {
|
gst_ximagesink_expose (GST_X_OVERLAY (ximagesink));
|
||||||
gst_ximagesink_expose (GST_X_OVERLAY (ximagesink));
|
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
g_mutex_lock (ximagesink->flow_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle Display events */
|
||||||
|
while (XPending (ximagesink->xcontext->disp)) {
|
||||||
|
XNextEvent (ximagesink->xcontext->disp, &e);
|
||||||
|
|
||||||
|
switch (e.type) {
|
||||||
|
case ClientMessage:{
|
||||||
|
Atom wm_delete;
|
||||||
|
|
||||||
|
wm_delete = XInternAtom (ximagesink->xcontext->disp,
|
||||||
|
"WM_DELETE_WINDOW", False);
|
||||||
|
if (wm_delete == (Atom) e.xclient.data.l[0]) {
|
||||||
|
/* Handle window deletion by posting an error on the bus */
|
||||||
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, NOT_FOUND,
|
||||||
|
("Output window was closed"), (NULL));
|
||||||
|
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
|
||||||
|
ximagesink->xwindow = NULL;
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
g_mutex_unlock (ximagesink->flow_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
@ -1543,7 +1578,8 @@ gst_ximagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
|
|||||||
put the ximage which is in the PRIVATE pointer */
|
put the ximage which is in the PRIVATE pointer */
|
||||||
if (GST_IS_XIMAGE_BUFFER (buf)) {
|
if (GST_IS_XIMAGE_BUFFER (buf)) {
|
||||||
GST_LOG_OBJECT (ximagesink, "buffer from our pool, writing directly");
|
GST_LOG_OBJECT (ximagesink, "buffer from our pool, writing directly");
|
||||||
gst_ximagesink_ximage_put (ximagesink, GST_XIMAGE_BUFFER (buf));
|
if (!gst_ximagesink_ximage_put (ximagesink, GST_XIMAGE_BUFFER (buf)))
|
||||||
|
goto no_window;
|
||||||
} else {
|
} else {
|
||||||
/* Else we have to copy the data into our private image, */
|
/* Else we have to copy the data into our private image, */
|
||||||
/* if we have one... */
|
/* if we have one... */
|
||||||
@ -1569,7 +1605,8 @@ gst_ximagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
|
|||||||
}
|
}
|
||||||
memcpy (GST_BUFFER_DATA (ximagesink->ximage), GST_BUFFER_DATA (buf),
|
memcpy (GST_BUFFER_DATA (ximagesink->ximage), GST_BUFFER_DATA (buf),
|
||||||
MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size));
|
MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size));
|
||||||
gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage);
|
if (!gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage))
|
||||||
|
goto no_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
@ -1581,6 +1618,12 @@ no_ximage:
|
|||||||
GST_DEBUG ("could not create image");
|
GST_DEBUG ("could not create image");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
no_window:
|
||||||
|
{
|
||||||
|
/* No Window available to put our image into */
|
||||||
|
GST_WARNING_OBJECT (ximagesink, "could not output image - no window");
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buffer management
|
/* Buffer management
|
||||||
|
@ -719,15 +719,16 @@ gst_xvimagesink_xwindow_draw_borders (GstXvImageSink * xvimagesink,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function puts a GstXvImage on a GstXvImageSink's window */
|
/* This function puts a GstXvImage on a GstXvImageSink's window. Returns FALSE
|
||||||
static void
|
* if no window was available */
|
||||||
|
static gboolean
|
||||||
gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
|
gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
|
||||||
GstXvImageBuffer * xvimage)
|
GstXvImageBuffer * xvimage)
|
||||||
{
|
{
|
||||||
GstVideoRectangle src, dst, result;
|
GstVideoRectangle src, dst, result;
|
||||||
gboolean draw_border = FALSE;
|
gboolean draw_border = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), FALSE);
|
||||||
|
|
||||||
/* We take the flow_lock. If expose is in there we don't want to run
|
/* We take the flow_lock. If expose is in there we don't want to run
|
||||||
concurrently from the data flow thread */
|
concurrently from the data flow thread */
|
||||||
@ -735,7 +736,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
|
|||||||
|
|
||||||
if (G_UNLIKELY (xvimagesink->xwindow == NULL)) {
|
if (G_UNLIKELY (xvimagesink->xwindow == NULL)) {
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
g_mutex_unlock (xvimagesink->flow_lock);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw borders when displaying the first frame. After this
|
/* Draw borders when displaying the first frame. After this
|
||||||
@ -762,7 +763,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
|
|||||||
xvimage = xvimagesink->cur_image;
|
xvimage = xvimagesink->cur_image;
|
||||||
} else {
|
} else {
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
g_mutex_unlock (xvimagesink->flow_lock);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -821,6 +822,8 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
|
|||||||
g_mutex_unlock (xvimagesink->x_lock);
|
g_mutex_unlock (xvimagesink->x_lock);
|
||||||
|
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
g_mutex_unlock (xvimagesink->flow_lock);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -888,9 +891,18 @@ gst_xvimagesink_xwindow_new (GstXvImageSink * xvimagesink,
|
|||||||
XSetWindowBackgroundPixmap (xvimagesink->xcontext->disp, xwindow->win, None);
|
XSetWindowBackgroundPixmap (xvimagesink->xcontext->disp, xwindow->win, None);
|
||||||
|
|
||||||
if (xvimagesink->handle_events) {
|
if (xvimagesink->handle_events) {
|
||||||
|
Atom wm_delete;
|
||||||
|
|
||||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||||
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||||
|
|
||||||
|
/* Tell the window manager we'd like delete client messages instead of
|
||||||
|
* being killed */
|
||||||
|
wm_delete = XInternAtom (xvimagesink->xcontext->disp,
|
||||||
|
"WM_DELETE_WINDOW", False);
|
||||||
|
(void) XSetWMProtocols (xvimagesink->xcontext->disp, xwindow->win,
|
||||||
|
&wm_delete, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
|
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
|
||||||
@ -1048,6 +1060,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
|
|||||||
XEvent e;
|
XEvent e;
|
||||||
guint pointer_x = 0, pointer_y = 0;
|
guint pointer_x = 0, pointer_y = 0;
|
||||||
gboolean pointer_moved = FALSE;
|
gboolean pointer_moved = FALSE;
|
||||||
|
gboolean exposed = FALSE, configured = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
||||||
|
|
||||||
@ -1072,19 +1085,20 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
|
|||||||
g_mutex_lock (xvimagesink->flow_lock);
|
g_mutex_lock (xvimagesink->flow_lock);
|
||||||
g_mutex_lock (xvimagesink->x_lock);
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
}
|
}
|
||||||
g_mutex_unlock (xvimagesink->x_lock);
|
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
|
||||||
|
|
||||||
if (pointer_moved) {
|
if (pointer_moved) {
|
||||||
|
g_mutex_unlock (xvimagesink->x_lock);
|
||||||
|
g_mutex_unlock (xvimagesink->flow_lock);
|
||||||
|
|
||||||
GST_DEBUG ("xvimagesink pointer moved over window at %d,%d",
|
GST_DEBUG ("xvimagesink pointer moved over window at %d,%d",
|
||||||
pointer_x, pointer_y);
|
pointer_x, pointer_y);
|
||||||
gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
|
gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
|
||||||
"mouse-move", 0, e.xbutton.x, e.xbutton.y);
|
"mouse-move", 0, e.xbutton.x, e.xbutton.y);
|
||||||
|
|
||||||
|
g_mutex_lock (xvimagesink->flow_lock);
|
||||||
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We get all events on our window to throw them upstream */
|
/* We get all events on our window to throw them upstream */
|
||||||
g_mutex_lock (xvimagesink->flow_lock);
|
|
||||||
g_mutex_lock (xvimagesink->x_lock);
|
|
||||||
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
||||||
xvimagesink->xwindow->win,
|
xvimagesink->xwindow->win,
|
||||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask,
|
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask,
|
||||||
@ -1141,40 +1155,61 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
|
|||||||
g_mutex_lock (xvimagesink->flow_lock);
|
g_mutex_lock (xvimagesink->flow_lock);
|
||||||
g_mutex_lock (xvimagesink->x_lock);
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
}
|
}
|
||||||
g_mutex_unlock (xvimagesink->x_lock);
|
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
|
||||||
|
|
||||||
/* Handle Expose */
|
/* Handle Expose */
|
||||||
{
|
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
||||||
gboolean exposed = FALSE, configured = FALSE;
|
xvimagesink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) {
|
||||||
|
switch (e.type) {
|
||||||
g_mutex_lock (xvimagesink->flow_lock);
|
case Expose:
|
||||||
g_mutex_lock (xvimagesink->x_lock);
|
exposed = TRUE;
|
||||||
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
break;
|
||||||
xvimagesink->xwindow->win, ExposureMask | StructureNotifyMask,
|
case ConfigureNotify:
|
||||||
&e)) {
|
configured = TRUE;
|
||||||
g_mutex_unlock (xvimagesink->x_lock);
|
break;
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
default:
|
||||||
|
break;
|
||||||
switch (e.type) {
|
|
||||||
case Expose:
|
|
||||||
exposed = TRUE;
|
|
||||||
break;
|
|
||||||
case ConfigureNotify:
|
|
||||||
configured = TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
g_mutex_lock (xvimagesink->flow_lock);
|
|
||||||
g_mutex_lock (xvimagesink->x_lock);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exposed || configured) {
|
||||||
g_mutex_unlock (xvimagesink->x_lock);
|
g_mutex_unlock (xvimagesink->x_lock);
|
||||||
g_mutex_unlock (xvimagesink->flow_lock);
|
g_mutex_unlock (xvimagesink->flow_lock);
|
||||||
|
|
||||||
if (exposed || configured) {
|
gst_xvimagesink_expose (GST_X_OVERLAY (xvimagesink));
|
||||||
gst_xvimagesink_expose (GST_X_OVERLAY (xvimagesink));
|
|
||||||
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
|
g_mutex_lock (xvimagesink->flow_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle Display events */
|
||||||
|
while (XPending (xvimagesink->xcontext->disp)) {
|
||||||
|
XNextEvent (xvimagesink->xcontext->disp, &e);
|
||||||
|
|
||||||
|
switch (e.type) {
|
||||||
|
case ClientMessage:{
|
||||||
|
Atom wm_delete;
|
||||||
|
|
||||||
|
wm_delete = XInternAtom (xvimagesink->xcontext->disp,
|
||||||
|
"WM_DELETE_WINDOW", False);
|
||||||
|
if (wm_delete == (Atom) e.xclient.data.l[0]) {
|
||||||
|
/* Handle window deletion by posting an error on the bus */
|
||||||
|
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, NOT_FOUND,
|
||||||
|
("Output window was closed"), (NULL));
|
||||||
|
|
||||||
|
g_mutex_unlock (xvimagesink->x_lock);
|
||||||
|
gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
|
||||||
|
xvimagesink->xwindow = NULL;
|
||||||
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (xvimagesink->x_lock);
|
||||||
|
g_mutex_unlock (xvimagesink->flow_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2114,7 +2149,8 @@ gst_xvimagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
|
|||||||
put the ximage which is in the PRIVATE pointer */
|
put the ximage which is in the PRIVATE pointer */
|
||||||
if (GST_IS_XVIMAGE_BUFFER (buf)) {
|
if (GST_IS_XVIMAGE_BUFFER (buf)) {
|
||||||
GST_LOG_OBJECT (xvimagesink, "fast put of bufferpool buffer");
|
GST_LOG_OBJECT (xvimagesink, "fast put of bufferpool buffer");
|
||||||
gst_xvimagesink_xvimage_put (xvimagesink, GST_XVIMAGE_BUFFER (buf));
|
if (!gst_xvimagesink_xvimage_put (xvimagesink, GST_XVIMAGE_BUFFER (buf)))
|
||||||
|
goto no_window;
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (xvimagesink, "slow copy into bufferpool buffer");
|
GST_LOG_OBJECT (xvimagesink, "slow copy into bufferpool buffer");
|
||||||
/* Else we have to copy the data into our private image, */
|
/* Else we have to copy the data into our private image, */
|
||||||
@ -2145,7 +2181,8 @@ gst_xvimagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
|
|||||||
GST_BUFFER_DATA (buf),
|
GST_BUFFER_DATA (buf),
|
||||||
MIN (GST_BUFFER_SIZE (buf), xvimagesink->xvimage->size));
|
MIN (GST_BUFFER_SIZE (buf), xvimagesink->xvimage->size));
|
||||||
|
|
||||||
gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage);
|
if (!gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage))
|
||||||
|
goto no_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
@ -2157,6 +2194,12 @@ no_image:
|
|||||||
GST_WARNING_OBJECT (xvimagesink, "could not create image");
|
GST_WARNING_OBJECT (xvimagesink, "could not create image");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
no_window:
|
||||||
|
{
|
||||||
|
/* No Window available to put our image into */
|
||||||
|
GST_WARNING_OBJECT (xvimagesink, "could not output image - no window");
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buffer management */
|
/* Buffer management */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user