mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 13:32:29 +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>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
gst_ximagesink_renegotiate_size (GstXImageSink *ximagesink,
|
||||
guint width, guint height)
|
||||
{
|
||||
XEvent e;
|
||||
|
||||
g_return_if_fail (ximagesink != NULL);
|
||||
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
||||
|
||||
/* We get all events on our window to throw them upstream */
|
||||
g_mutex_lock (ximagesink->x_lock);
|
||||
while (XCheckWindowEvent (ximagesink->xcontext->disp,
|
||||
ximagesink->xwindow->win,
|
||||
ExposureMask | StructureNotifyMask |
|
||||
PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask | ButtonPressMask |
|
||||
ButtonReleaseMask, &e))
|
||||
{
|
||||
KeySym keysym;
|
||||
/* 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. */
|
||||
|
||||
/* We lock only for the X function call */
|
||||
g_mutex_unlock (ximagesink->x_lock);
|
||||
|
||||
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) )
|
||||
if ( (ximagesink->xwindow->width != width) ||
|
||||
(ximagesink->xwindow->height != height) )
|
||||
{
|
||||
GstPadLinkReturn r;
|
||||
ximagesink->xwindow->width = e.xconfigure.width;
|
||||
ximagesink->xwindow->height = e.xconfigure.height;
|
||||
ximagesink->xwindow->width = width;
|
||||
ximagesink->xwindow->height = height;
|
||||
|
||||
r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
|
||||
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,
|
||||
"green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
|
||||
"blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
|
||||
"width", G_TYPE_INT, e.xconfigure.width,
|
||||
"height", G_TYPE_INT, e.xconfigure.height,
|
||||
"width", G_TYPE_INT, width,
|
||||
"height", G_TYPE_INT, height,
|
||||
"framerate", G_TYPE_DOUBLE, ximagesink->framerate,
|
||||
NULL));
|
||||
|
||||
if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
|
||||
{
|
||||
GST_VIDEOSINK_WIDTH (ximagesink) = e.xconfigure.width;
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink) = e.xconfigure.height;
|
||||
GST_VIDEOSINK_WIDTH (ximagesink) = width;
|
||||
GST_VIDEOSINK_HEIGHT (ximagesink) = height;
|
||||
|
||||
if ( (ximagesink->ximage) &&
|
||||
( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
|
||||
(GST_VIDEOSINK_HEIGHT (ximagesink) != ximagesink->ximage->height) ) )
|
||||
{
|
||||
/* We renew our ximage only if size changed */
|
||||
gst_ximagesink_ximage_destroy (ximagesink,
|
||||
ximagesink->ximage);
|
||||
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
|
||||
|
||||
ximagesink->ximage = gst_ximagesink_ximage_new (
|
||||
ximagesink,
|
||||
ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
|
||||
GST_VIDEOSINK_WIDTH (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;
|
||||
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:
|
||||
/* Mouse pointer moved over our window. We send upstream
|
||||
events for interactivity/navigation */
|
||||
GST_DEBUG ("ximagesink pointer moved over window at %d,%d",
|
||||
e.xmotion.x, e.xmotion.y);
|
||||
gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
|
||||
"mouse-move", 0,
|
||||
e.xmotion.x, e.xmotion.y);
|
||||
pointer_x = e.xmotion.x;
|
||||
pointer_y = e.xmotion.y;
|
||||
pointer_moved = TRUE;
|
||||
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:
|
||||
/* Mouse button pressed/released over our window. We send upstream
|
||||
events for interactivity/navigation */
|
||||
|
|
|
@ -474,16 +474,49 @@ static void
|
|||
gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
|
||||
{
|
||||
XEvent e;
|
||||
guint pointer_x = 0, pointer_y = 0;
|
||||
gboolean pointer_moved = FALSE;
|
||||
|
||||
g_return_if_fail (xvimagesink != NULL);
|
||||
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 */
|
||||
g_mutex_lock (xvimagesink->x_lock);
|
||||
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
|
||||
xvimagesink->xwindow->win,
|
||||
ExposureMask | StructureNotifyMask |
|
||||
PointerMotionMask | KeyPressMask |
|
||||
StructureNotifyMask | KeyPressMask |
|
||||
KeyReleaseMask | ButtonPressMask |
|
||||
ButtonReleaseMask, &e))
|
||||
{
|
||||
|
@ -502,15 +535,6 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
|
|||
xvimagesink->xwindow->width = e.xconfigure.width;
|
||||
xvimagesink->xwindow->height = e.xconfigure.height;
|
||||
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:
|
||||
/* Mouse button pressed over our window. We send upstream
|
||||
events for interactivity/navigation */
|
||||
|
|
Loading…
Reference in a new issue