mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
sys/ximage/ximagesink.c: Better X events handling, only take the latest events for configure and motion.
Original commit message from CVS: 2004-02-02 Julien MOUTTE <julien@moutte.net> * sys/ximage/ximagesink.c: (gst_ximagesink_renegotiate_size), (gst_ximagesink_handle_xevents): Better X events handling, only take the latest events for configure and motion. * sys/xvimage/xvimagesink.c: (gst_xvimagesink_handle_xevents): same.
This commit is contained in:
parent
75a75904aa
commit
2c8ea20b8f
3 changed files with 159 additions and 73 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2004-02-02 Julien MOUTTE <julien@moutte.net>
|
||||||
|
|
||||||
|
* sys/ximage/ximagesink.c: (gst_ximagesink_renegotiate_size),
|
||||||
|
(gst_ximagesink_handle_xevents): Better X events handling, only take
|
||||||
|
the latest events for configure and motion.
|
||||||
|
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_handle_xevents): same.
|
||||||
|
|
||||||
2004-02-02 Jon Trowbridge <trow@gnu.org>
|
2004-02-02 Jon Trowbridge <trow@gnu.org>
|
||||||
|
|
||||||
reviewed by: David Schleef <ds@schleef.org>
|
reviewed by: David Schleef <ds@schleef.org>
|
||||||
|
|
|
@ -373,47 +373,22 @@ gst_ximagesink_xwindow_resize (GstXImageSink *ximagesink, GstXWindow *xwindow,
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function handles XEvents that might be in the queue. It generates
|
|
||||||
GstEvent that will be sent upstream in the pipeline to handle interactivity
|
|
||||||
and navigation. It will also listen for configure events on the window to
|
|
||||||
trigger caps renegotiation so on the fly software scaling can work. */
|
|
||||||
static void
|
static void
|
||||||
gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
|
gst_ximagesink_renegotiate_size (GstXImageSink *ximagesink,
|
||||||
|
guint width, guint height)
|
||||||
{
|
{
|
||||||
XEvent e;
|
|
||||||
|
|
||||||
g_return_if_fail (ximagesink != NULL);
|
g_return_if_fail (ximagesink != NULL);
|
||||||
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
||||||
|
|
||||||
/* We get all events on our window to throw them upstream */
|
/* Window got resized or moved. We do caps negotiation again to get video
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
scaler to fit that new size only if size of the window changed. */
|
||||||
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
|
||||||
ximagesink->xwindow->win,
|
|
||||||
ExposureMask | StructureNotifyMask |
|
|
||||||
PointerMotionMask | KeyPressMask |
|
|
||||||
KeyReleaseMask | ButtonPressMask |
|
|
||||||
ButtonReleaseMask, &e))
|
|
||||||
{
|
|
||||||
KeySym keysym;
|
|
||||||
|
|
||||||
/* We lock only for the X function call */
|
if ( (ximagesink->xwindow->width != width) ||
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
(ximagesink->xwindow->height != height) )
|
||||||
|
|
||||||
switch (e.type)
|
|
||||||
{
|
|
||||||
case ConfigureNotify:
|
|
||||||
/* Window got resized or moved. We do caps negotiation
|
|
||||||
again to get video scaler to fit that new size only if size
|
|
||||||
of the window changed. */
|
|
||||||
GST_DEBUG ("ximagesink window is at %d, %d with geometry : %d,%d",
|
|
||||||
e.xconfigure.x, e.xconfigure.y,
|
|
||||||
e.xconfigure.width, e.xconfigure.height);
|
|
||||||
if ( (ximagesink->xwindow->width != e.xconfigure.width) ||
|
|
||||||
(ximagesink->xwindow->height != e.xconfigure.height) )
|
|
||||||
{
|
{
|
||||||
GstPadLinkReturn r;
|
GstPadLinkReturn r;
|
||||||
ximagesink->xwindow->width = e.xconfigure.width;
|
ximagesink->xwindow->width = width;
|
||||||
ximagesink->xwindow->height = e.xconfigure.height;
|
ximagesink->xwindow->height = height;
|
||||||
|
|
||||||
r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
|
r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
|
||||||
gst_caps_new_simple ("video/x-raw-rgb",
|
gst_caps_new_simple ("video/x-raw-rgb",
|
||||||
|
@ -423,41 +398,121 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
|
||||||
"red_mask", G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
|
"red_mask", G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
|
||||||
"green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
|
"green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
|
||||||
"blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
|
"blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
|
||||||
"width", G_TYPE_INT, e.xconfigure.width,
|
"width", G_TYPE_INT, width,
|
||||||
"height", G_TYPE_INT, e.xconfigure.height,
|
"height", G_TYPE_INT, height,
|
||||||
"framerate", G_TYPE_DOUBLE, ximagesink->framerate,
|
"framerate", G_TYPE_DOUBLE, ximagesink->framerate,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
|
if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
|
||||||
{
|
{
|
||||||
GST_VIDEOSINK_WIDTH (ximagesink) = e.xconfigure.width;
|
GST_VIDEOSINK_WIDTH (ximagesink) = width;
|
||||||
GST_VIDEOSINK_HEIGHT (ximagesink) = e.xconfigure.height;
|
GST_VIDEOSINK_HEIGHT (ximagesink) = height;
|
||||||
|
|
||||||
if ( (ximagesink->ximage) &&
|
if ( (ximagesink->ximage) &&
|
||||||
( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
|
( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
|
||||||
(GST_VIDEOSINK_HEIGHT (ximagesink) != ximagesink->ximage->height) ) )
|
(GST_VIDEOSINK_HEIGHT (ximagesink) != ximagesink->ximage->height) ) )
|
||||||
{
|
{
|
||||||
/* We renew our ximage only if size changed */
|
/* We renew our ximage only if size changed */
|
||||||
gst_ximagesink_ximage_destroy (ximagesink,
|
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
|
||||||
ximagesink->ximage);
|
|
||||||
|
|
||||||
ximagesink->ximage = gst_ximagesink_ximage_new (
|
ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
|
||||||
ximagesink,
|
|
||||||
GST_VIDEOSINK_WIDTH (ximagesink),
|
GST_VIDEOSINK_WIDTH (ximagesink),
|
||||||
GST_VIDEOSINK_HEIGHT (ximagesink));
|
GST_VIDEOSINK_HEIGHT (ximagesink));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function handles XEvents that might be in the queue. It generates
|
||||||
|
GstEvent that will be sent upstream in the pipeline to handle interactivity
|
||||||
|
and navigation. It will also listen for configure events on the window to
|
||||||
|
trigger caps renegotiation so on the fly software scaling can work. */
|
||||||
|
static void
|
||||||
|
gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
|
||||||
|
{
|
||||||
|
XEvent e;
|
||||||
|
guint new_width = 0, new_height = 0, pointer_x = 0, pointer_y = 0;
|
||||||
|
gboolean pointer_moved = FALSE;
|
||||||
|
|
||||||
|
g_return_if_fail (ximagesink != NULL);
|
||||||
|
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
||||||
|
|
||||||
|
/* First we get all structure modification events. Only the last one is
|
||||||
|
interesting */
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||||
|
ximagesink->xwindow->win,
|
||||||
|
StructureNotifyMask, &e))
|
||||||
|
{
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
switch (e.type)
|
||||||
|
{
|
||||||
|
case ConfigureNotify:
|
||||||
|
new_width = e.xconfigure.width;
|
||||||
|
new_height = e.xconfigure.height;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
if ( (new_width != 0) && (new_height != 0) )
|
||||||
|
{
|
||||||
|
GST_DEBUG ("ximagesink window geometry is : %d,%d",
|
||||||
|
new_width, new_height);
|
||||||
|
gst_ximagesink_renegotiate_size (ximagesink, new_width, new_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then we get all pointer motion events, only the last position is
|
||||||
|
interesting. */
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||||
|
ximagesink->xwindow->win,
|
||||||
|
PointerMotionMask, &e))
|
||||||
|
{
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
switch (e.type)
|
||||||
|
{
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
/* Mouse pointer moved over our window. We send upstream
|
pointer_x = e.xmotion.x;
|
||||||
events for interactivity/navigation */
|
pointer_y = e.xmotion.y;
|
||||||
GST_DEBUG ("ximagesink pointer moved over window at %d,%d",
|
pointer_moved = TRUE;
|
||||||
e.xmotion.x, e.xmotion.y);
|
|
||||||
gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
|
|
||||||
"mouse-move", 0,
|
|
||||||
e.xmotion.x, e.xmotion.y);
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
if (pointer_moved)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We get all remaining events on our window to throw them upstream */
|
||||||
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||||
|
ximagesink->xwindow->win,
|
||||||
|
KeyPressMask | KeyReleaseMask |
|
||||||
|
ButtonPressMask | ButtonReleaseMask, &e))
|
||||||
|
{
|
||||||
|
KeySym keysym;
|
||||||
|
|
||||||
|
/* We lock only for the X function call */
|
||||||
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
switch (e.type)
|
||||||
|
{
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
/* Mouse button pressed/released over our window. We send upstream
|
/* Mouse button pressed/released over our window. We send upstream
|
||||||
events for interactivity/navigation */
|
events for interactivity/navigation */
|
||||||
|
|
|
@ -474,16 +474,49 @@ static void
|
||||||
gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
|
gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
|
||||||
{
|
{
|
||||||
XEvent e;
|
XEvent e;
|
||||||
|
guint pointer_x = 0, pointer_y = 0;
|
||||||
|
gboolean pointer_moved = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (xvimagesink != NULL);
|
g_return_if_fail (xvimagesink != NULL);
|
||||||
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
||||||
|
|
||||||
|
/* We get all pointer motion events, only the last position is
|
||||||
|
interesting. */
|
||||||
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
|
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
||||||
|
xvimagesink->xwindow->win,
|
||||||
|
PointerMotionMask, &e))
|
||||||
|
{
|
||||||
|
g_mutex_unlock (xvimagesink->x_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 (xvimagesink->x_lock);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (xvimagesink->x_lock);
|
||||||
|
|
||||||
|
if (pointer_moved)
|
||||||
|
{
|
||||||
|
GST_DEBUG ("xvimagesink pointer moved over window at %d,%d",
|
||||||
|
pointer_x, pointer_y);
|
||||||
|
gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
|
||||||
|
"mouse-move", 0, pointer_x, pointer_y);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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->x_lock);
|
g_mutex_lock (xvimagesink->x_lock);
|
||||||
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
||||||
xvimagesink->xwindow->win,
|
xvimagesink->xwindow->win,
|
||||||
ExposureMask | StructureNotifyMask |
|
StructureNotifyMask | KeyPressMask |
|
||||||
PointerMotionMask | KeyPressMask |
|
|
||||||
KeyReleaseMask | ButtonPressMask |
|
KeyReleaseMask | ButtonPressMask |
|
||||||
ButtonReleaseMask, &e))
|
ButtonReleaseMask, &e))
|
||||||
{
|
{
|
||||||
|
@ -502,15 +535,6 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
|
||||||
xvimagesink->xwindow->width = e.xconfigure.width;
|
xvimagesink->xwindow->width = e.xconfigure.width;
|
||||||
xvimagesink->xwindow->height = e.xconfigure.height;
|
xvimagesink->xwindow->height = e.xconfigure.height;
|
||||||
break;
|
break;
|
||||||
case MotionNotify:
|
|
||||||
/* Mouse pointer moved over our window. We send upstream
|
|
||||||
events for interactivity/navigation */
|
|
||||||
GST_DEBUG ("xvimagesink pointer moved over window at %d,%d",
|
|
||||||
e.xmotion.x, e.xmotion.y);
|
|
||||||
gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
|
|
||||||
"mouse-move", 0,
|
|
||||||
e.xmotion.x, e.xmotion.y);
|
|
||||||
break;
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
/* Mouse button pressed over our window. We send upstream
|
/* Mouse button pressed over our window. We send upstream
|
||||||
events for interactivity/navigation */
|
events for interactivity/navigation */
|
||||||
|
|
Loading…
Reference in a new issue