mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
Add a method to the XOverlay interface to allow disabling of event handling in x[v]imagesink elements. This will let ...
Original commit message from CVS: 2007-01-04 Julien MOUTTE <julien@moutte.net> * gst-libs/gst/interfaces/xoverlay.c: (gst_x_overlay_handle_events): * gst-libs/gst/interfaces/xoverlay.h: * sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_new), (gst_ximagesink_set_xwindow_id), (gst_ximagesink_set_event_handling), (gst_ximagesink_xoverlay_init), (gst_ximagesink_set_property), (gst_ximagesink_get_property), (gst_ximagesink_init), (gst_ximagesink_class_init): * sys/ximage/ximagesink.h: * sys/xvimage/xvimagesink.c: (gst_xvimagesink_xwindow_new), (gst_xvimagesink_set_xwindow_id), (gst_xvimagesink_set_event_handling), (gst_xvimagesink_xoverlay_init), (gst_xvimagesink_set_property), (gst_xvimagesink_get_property), (gst_xvimagesink_init), (gst_xvimagesink_class_init): * sys/xvimage/xvimagesink.h: * tests/icles/stress-xoverlay.c: (toggle_events), (create_window): Add a method to the XOverlay interface to allow disabling of event handling in x[v]imagesink elements. This will let X events propagate to parent windows which can be usefull in some cases. Be carefull that the application is then responsible of pushing navigation events and expose events to the video sink. Fixes: #387138.
This commit is contained in:
parent
5c14969645
commit
163ec9ecf9
8 changed files with 196 additions and 16 deletions
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2007-01-04 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* gst-libs/gst/interfaces/xoverlay.c:
|
||||
(gst_x_overlay_handle_events):
|
||||
* gst-libs/gst/interfaces/xoverlay.h:
|
||||
* sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_new),
|
||||
(gst_ximagesink_set_xwindow_id),
|
||||
(gst_ximagesink_set_event_handling),
|
||||
(gst_ximagesink_xoverlay_init), (gst_ximagesink_set_property),
|
||||
(gst_ximagesink_get_property), (gst_ximagesink_init),
|
||||
(gst_ximagesink_class_init):
|
||||
* sys/ximage/ximagesink.h:
|
||||
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_xwindow_new),
|
||||
(gst_xvimagesink_set_xwindow_id),
|
||||
(gst_xvimagesink_set_event_handling),
|
||||
(gst_xvimagesink_xoverlay_init), (gst_xvimagesink_set_property),
|
||||
(gst_xvimagesink_get_property), (gst_xvimagesink_init),
|
||||
(gst_xvimagesink_class_init):
|
||||
* sys/xvimage/xvimagesink.h:
|
||||
* tests/icles/stress-xoverlay.c: (toggle_events), (create_window):
|
||||
Add a method to the XOverlay interface to allow disabling of
|
||||
event handling in x[v]imagesink elements. This will let X events
|
||||
propagate to parent windows which can be usefull in some cases.
|
||||
Be carefull that the application is then responsible of pushing
|
||||
navigation events and expose events to the video sink.
|
||||
Fixes: #387138.
|
||||
|
||||
2007-01-03 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst-libs/gst/tag/gstvorbistag.c:
|
||||
|
|
|
@ -239,3 +239,28 @@ gst_x_overlay_expose (GstXOverlay * overlay)
|
|||
klass->expose (overlay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_x_overlay_handle_events:
|
||||
* @overlay: a #GstXOverlay to expose.
|
||||
* @handle_events: a #gboolean indicating if events should be handled or not.
|
||||
*
|
||||
* Tell an overlay that it should handle events from the window system. These
|
||||
* events are forwared upstream as navigation events. In some window system,
|
||||
* events are not propagated in the window hierarchy if a client is listening
|
||||
* for them. This method allows you to disable events handling completely
|
||||
* from the XOverlay.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_handle_events (GstXOverlay * overlay, gboolean handle_events)
|
||||
{
|
||||
GstXOverlayClass *klass;
|
||||
|
||||
g_return_if_fail (overlay != NULL);
|
||||
|
||||
klass = GST_X_OVERLAY_GET_CLASS (overlay);
|
||||
|
||||
if (klass->handle_events) {
|
||||
klass->handle_events (overlay, handle_events);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,9 +51,12 @@ typedef struct _GstXOverlayClass {
|
|||
gulong xwindow_id);
|
||||
|
||||
void (* expose) (GstXOverlay *overlay);
|
||||
|
||||
void (* handle_events) (GstXOverlay *overlay,
|
||||
gboolean handle_events);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
gpointer _gst_reserved[GST_PADDING - 1];
|
||||
} GstXOverlayClass;
|
||||
|
||||
GType gst_x_overlay_get_type (void);
|
||||
|
@ -63,6 +66,9 @@ void gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id);
|
|||
|
||||
void gst_x_overlay_expose (GstXOverlay *overlay);
|
||||
|
||||
void gst_x_overlay_handle_events (GstXOverlay *overlay,
|
||||
gboolean handle_events);
|
||||
|
||||
/* public methods to dispatch bus messages */
|
||||
void gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id);
|
||||
|
||||
|
|
|
@ -164,7 +164,8 @@ enum
|
|||
PROP_DISPLAY,
|
||||
PROP_SYNCHRONOUS,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
PROP_FORCE_ASPECT_RATIO
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_HANDLE_EVENTS
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
|
@ -771,9 +772,11 @@ gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height)
|
|||
ConfigureNotify. This takes away flickering of video when resizing. */
|
||||
XSetWindowBackgroundPixmap (ximagesink->xcontext->disp, xwindow->win, None);
|
||||
|
||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||
if (ximagesink->handle_events) {
|
||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||
}
|
||||
|
||||
xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->win,
|
||||
0, &values);
|
||||
|
@ -1817,9 +1820,11 @@ gst_ximagesink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
|
|||
xwindow->width = attr.width;
|
||||
xwindow->height = attr.height;
|
||||
xwindow->internal = FALSE;
|
||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
if (ximagesink->handle_events) {
|
||||
XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
}
|
||||
|
||||
xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->win, 0, NULL);
|
||||
g_mutex_unlock (ximagesink->x_lock);
|
||||
|
@ -1842,11 +1847,42 @@ gst_ximagesink_expose (GstXOverlay * overlay)
|
|||
gst_ximagesink_ximage_put (ximagesink, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ximagesink_set_event_handling (GstXOverlay * overlay,
|
||||
gboolean handle_events)
|
||||
{
|
||||
GstXImageSink *ximagesink = GST_XIMAGESINK (overlay);
|
||||
|
||||
ximagesink->handle_events = handle_events;
|
||||
|
||||
if (!ximagesink->xwindow)
|
||||
return;
|
||||
|
||||
g_mutex_lock (ximagesink->x_lock);
|
||||
|
||||
if (handle_events) {
|
||||
if (ximagesink->xwindow->internal) {
|
||||
XSelectInput (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
||||
ExposureMask | StructureNotifyMask | PointerMotionMask |
|
||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||
} else {
|
||||
XSelectInput (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
||||
ExposureMask | StructureNotifyMask | PointerMotionMask |
|
||||
KeyPressMask | KeyReleaseMask);
|
||||
}
|
||||
} else {
|
||||
XSelectInput (ximagesink->xcontext->disp, ximagesink->xwindow->win, 0);
|
||||
}
|
||||
|
||||
g_mutex_unlock (ximagesink->x_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ximagesink_xoverlay_init (GstXOverlayClass * iface)
|
||||
{
|
||||
iface->set_xwindow_id = gst_ximagesink_set_xwindow_id;
|
||||
iface->expose = gst_ximagesink_expose;
|
||||
iface->handle_events = gst_ximagesink_set_event_handling;
|
||||
}
|
||||
|
||||
/* =========================================== */
|
||||
|
@ -1902,6 +1938,10 @@ gst_ximagesink_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PROP_HANDLE_EVENTS:
|
||||
gst_ximagesink_set_event_handling (GST_X_OVERLAY (ximagesink),
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1932,6 +1972,9 @@ gst_ximagesink_get_property (GObject * object, guint prop_id,
|
|||
if (ximagesink->par)
|
||||
g_value_transform (ximagesink->par, value);
|
||||
break;
|
||||
case PROP_HANDLE_EVENTS:
|
||||
g_value_set_boolean (value, ximagesink->handle_events);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1994,6 +2037,7 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
|
|||
|
||||
ximagesink->synchronous = FALSE;
|
||||
ximagesink->keep_aspect = FALSE;
|
||||
ximagesink->handle_events = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2038,6 +2082,10 @@ gst_ximagesink_class_init (GstXImageSinkClass * klass)
|
|||
g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
|
||||
g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", "1/1", G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class, PROP_HANDLE_EVENTS,
|
||||
g_param_spec_boolean ("handle-events", "Handle XEvents",
|
||||
"When enabled, XEvents will be selected and handled", TRUE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
gstelement_class->change_state = gst_ximagesink_change_state;
|
||||
|
||||
|
|
|
@ -179,6 +179,7 @@ struct _GstXImageBuffer {
|
|||
* debugging purpose only)
|
||||
* @keep_aspect: used to remember if reverse negotiation scaling should respect
|
||||
* aspect ratio
|
||||
* @handle_events: used to know if we should handle select XEvents or not
|
||||
*
|
||||
* The #GstXImageSink data structure.
|
||||
*/
|
||||
|
@ -211,6 +212,7 @@ struct _GstXImageSink {
|
|||
|
||||
gboolean synchronous;
|
||||
gboolean keep_aspect;
|
||||
gboolean handle_events;
|
||||
};
|
||||
|
||||
struct _GstXImageSinkClass {
|
||||
|
|
|
@ -188,7 +188,8 @@ enum
|
|||
ARG_DISPLAY,
|
||||
ARG_SYNCHRONOUS,
|
||||
ARG_PIXEL_ASPECT_RATIO,
|
||||
ARG_FORCE_ASPECT_RATIO
|
||||
ARG_FORCE_ASPECT_RATIO,
|
||||
ARG_HANDLE_EVENTS
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
|
@ -829,9 +830,11 @@ gst_xvimagesink_xwindow_new (GstXvImageSink * xvimagesink,
|
|||
* ConfigureNotify. This takes away flickering of video when resizing. */
|
||||
XSetWindowBackgroundPixmap (xvimagesink->xcontext->disp, xwindow->win, None);
|
||||
|
||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||
if (xvimagesink->handle_events) {
|
||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||
}
|
||||
|
||||
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
|
||||
xwindow->win, 0, &values);
|
||||
|
@ -2374,9 +2377,11 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
|
|||
xwindow->width = attr.width;
|
||||
xwindow->height = attr.height;
|
||||
xwindow->internal = FALSE;
|
||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
if (xvimagesink->handle_events) {
|
||||
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
|
||||
StructureNotifyMask | PointerMotionMask | KeyPressMask |
|
||||
KeyReleaseMask);
|
||||
}
|
||||
|
||||
xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
|
||||
xwindow->win, 0, NULL);
|
||||
|
@ -2400,11 +2405,42 @@ gst_xvimagesink_expose (GstXOverlay * overlay)
|
|||
gst_xvimagesink_xvimage_put (xvimagesink, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xvimagesink_set_event_handling (GstXOverlay * overlay,
|
||||
gboolean handle_events)
|
||||
{
|
||||
GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay);
|
||||
|
||||
xvimagesink->handle_events = handle_events;
|
||||
|
||||
if (!xvimagesink->xwindow)
|
||||
return;
|
||||
|
||||
g_mutex_lock (xvimagesink->x_lock);
|
||||
|
||||
if (handle_events) {
|
||||
if (xvimagesink->xwindow->internal) {
|
||||
XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xwindow->win,
|
||||
ExposureMask | StructureNotifyMask | PointerMotionMask |
|
||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
|
||||
} else {
|
||||
XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xwindow->win,
|
||||
ExposureMask | StructureNotifyMask | PointerMotionMask |
|
||||
KeyPressMask | KeyReleaseMask);
|
||||
}
|
||||
} else {
|
||||
XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xwindow->win, 0);
|
||||
}
|
||||
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xvimagesink_xoverlay_init (GstXOverlayClass * iface)
|
||||
{
|
||||
iface->set_xwindow_id = gst_xvimagesink_set_xwindow_id;
|
||||
iface->expose = gst_xvimagesink_expose;
|
||||
iface->handle_events = gst_xvimagesink_set_event_handling;
|
||||
}
|
||||
|
||||
static const GList *
|
||||
|
@ -2552,6 +2588,10 @@ gst_xvimagesink_set_property (GObject * object, guint prop_id,
|
|||
case ARG_FORCE_ASPECT_RATIO:
|
||||
xvimagesink->keep_aspect = g_value_get_boolean (value);
|
||||
break;
|
||||
case ARG_HANDLE_EVENTS:
|
||||
gst_xvimagesink_set_event_handling (GST_X_OVERLAY (xvimagesink),
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -2594,6 +2634,9 @@ gst_xvimagesink_get_property (GObject * object, guint prop_id,
|
|||
case ARG_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, xvimagesink->keep_aspect);
|
||||
break;
|
||||
case ARG_HANDLE_EVENTS:
|
||||
g_value_set_boolean (value, xvimagesink->handle_events);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -2662,6 +2705,7 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink)
|
|||
xvimagesink->synchronous = FALSE;
|
||||
xvimagesink->running = FALSE;
|
||||
xvimagesink->keep_aspect = FALSE;
|
||||
xvimagesink->handle_events = TRUE;
|
||||
xvimagesink->par = NULL;
|
||||
}
|
||||
|
||||
|
@ -2719,6 +2763,10 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass)
|
|||
g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
|
||||
"When enabled, scaling will respect original aspect ratio", FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class, ARG_HANDLE_EVENTS,
|
||||
g_param_spec_boolean ("handle-events", "Handle XEvents",
|
||||
"When enabled, XEvents will be selected and handled", TRUE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->finalize = gst_xvimagesink_finalize;
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ struct _GstXvImageBuffer {
|
|||
* debugging purpose only)
|
||||
* @keep_aspect: used to remember if reverse negotiation scaling should respect
|
||||
* aspect ratio
|
||||
* @handle_events: used to know if we should handle select XEvents or not
|
||||
* @brightness: used to store the user settings for color balance brightness
|
||||
* @contrast: used to store the user settings for color balance contrast
|
||||
* @hue: used to store the user settings for color balance hue
|
||||
|
@ -247,6 +248,7 @@ struct _GstXvImageSink {
|
|||
|
||||
gboolean synchronous;
|
||||
gboolean keep_aspect;
|
||||
gboolean handle_events;
|
||||
|
||||
gint brightness;
|
||||
gint contrast;
|
||||
|
|
|
@ -93,17 +93,38 @@ move_window (GstPipeline * pipeline)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toggle_events (GstXOverlay * ov)
|
||||
{
|
||||
static gboolean events_toggled;
|
||||
|
||||
gst_x_overlay_handle_events (ov, events_toggled);
|
||||
|
||||
if (events_toggled) {
|
||||
g_print ("Events are handled\n");
|
||||
events_toggled = FALSE;
|
||||
} else {
|
||||
g_print ("Events are NOT handled\n");
|
||||
events_toggled = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstBusSyncReply
|
||||
create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
XGCValues values;
|
||||
const GstStructure *s;
|
||||
GstXOverlay *ov = NULL;
|
||||
|
||||
s = gst_message_get_structure (message);
|
||||
if (!gst_structure_has_name (s, "prepare-xwindow-id")) {
|
||||
return GST_BUS_PASS;
|
||||
}
|
||||
|
||||
ov = GST_X_OVERLAY (GST_MESSAGE_SRC (message));
|
||||
|
||||
g_print ("Creating our own window\n");
|
||||
|
||||
win = XCreateSimpleWindow (disp, root, 0, 0, width, height, 0, 0, 0);
|
||||
|
@ -116,10 +137,11 @@ create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
|||
|
||||
XSync (disp, FALSE);
|
||||
|
||||
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)), win);
|
||||
gst_x_overlay_set_xwindow_id (ov, win);
|
||||
|
||||
g_timeout_add (50, (GSourceFunc) resize_window, pipeline);
|
||||
g_timeout_add (50, (GSourceFunc) move_window, pipeline);
|
||||
g_timeout_add (2000, (GSourceFunc) toggle_events, ov);
|
||||
|
||||
return GST_BUS_DROP;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue