static gboolean idle_refresh (gpointer data) { GstV4l2Object *v4l2object = GST_V4L2_OBJECT (data); GstV4l2Xv *v4l2xv = v4l2object->xv; GST_LOG_OBJECT (v4l2object->element, "idle refresh"); if (v4l2xv) { g_mutex_lock (v4l2xv->mutex); update_geometry (v4l2object); v4l2xv->idle_id = 0; g_mutex_unlock (v4l2xv->mutex); } /* once */ return FALSE; }
static gboolean idle_refresh (gpointer data) { GstV4l2Object *v4l2object = GST_V4L2_OBJECT (data); GstV4l2Xv *v4l2xv = v4l2object->xv; XWindowAttributes attr; if (v4l2xv) { g_mutex_lock (v4l2xv->mutex); XGetWindowAttributes (v4l2xv->dpy, v4l2object->xwindow_id, &attr); XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id, DefaultGC (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)), 0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height); v4l2xv->idle_id = 0; g_mutex_unlock (v4l2xv->mutex); } /* once */ return FALSE; }
static gboolean event_refresh (gpointer data) { GstV4l2Object *v4l2object = GST_V4L2_OBJECT (data); GstV4l2Xv *v4l2xv = v4l2object->xv; GST_LOG_OBJECT (v4l2object->element, "event refresh"); if (v4l2xv) { XEvent e; g_mutex_lock (v4l2xv->mutex); /* If the element supports navigation, collect the relavent input * events and push them upstream as navigation events */ if (GST_IS_NAVIGATION (v4l2object->element)) { guint pointer_x = 0, pointer_y = 0; gboolean pointer_moved = FALSE; /* We get all pointer motion events, only the last position is * interesting. */ while (XCheckWindowEvent (v4l2xv->dpy, v4l2object->xwindow_id, PointerMotionMask, &e)) { switch (e.type) { case MotionNotify: pointer_x = e.xmotion.x; pointer_y = e.xmotion.y; pointer_moved = TRUE; break; default: break; } } if (pointer_moved) { GST_DEBUG_OBJECT (v4l2object->element, "pointer moved over window at %d,%d", pointer_x, pointer_y); g_mutex_unlock (v4l2xv->mutex); gst_navigation_send_mouse_event (GST_NAVIGATION (v4l2object->element), "mouse-move", 0, e.xbutton.x, e.xbutton.y); g_mutex_lock (v4l2xv->mutex); } /* We get all events on our window to throw them upstream */ while (XCheckWindowEvent (v4l2xv->dpy, v4l2object->xwindow_id, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask, &e)) { KeySym keysym; const char *key_str = NULL; g_mutex_unlock (v4l2xv->mutex); switch (e.type) { case ButtonPress: GST_DEBUG_OBJECT (v4l2object->element, "button %d pressed over window at %d,%d", e.xbutton.button, e.xbutton.x, e.xbutton.y); gst_navigation_send_mouse_event (GST_NAVIGATION (v4l2object->element), "mouse-button-press", e.xbutton.button, e.xbutton.x, e.xbutton.y); break; case ButtonRelease: GST_DEBUG_OBJECT (v4l2object->element, "button %d released over window at %d,%d", e.xbutton.button, e.xbutton.x, e.xbutton.y); gst_navigation_send_mouse_event (GST_NAVIGATION (v4l2object->element), "mouse-button-release", e.xbutton.button, e.xbutton.x, e.xbutton.y); break; case KeyPress: case KeyRelease: g_mutex_lock (v4l2xv->mutex); keysym = XkbKeycodeToKeysym (v4l2xv->dpy, e.xkey.keycode, 0, 0); if (keysym != NoSymbol) { key_str = XKeysymToString (keysym); } else { key_str = "unknown"; } g_mutex_unlock (v4l2xv->mutex); GST_DEBUG_OBJECT (v4l2object->element, "key %d pressed over window at %d,%d (%s)", e.xkey.keycode, e.xkey.x, e.xkey.y, key_str); gst_navigation_send_key_event (GST_NAVIGATION (v4l2object->element), e.type == KeyPress ? "key-press" : "key-release", key_str); break; default: GST_DEBUG_OBJECT (v4l2object->element, "unhandled X event (%d)", e.type); } g_mutex_lock (v4l2xv->mutex); } } /* Handle ConfigureNotify */ while (XCheckWindowEvent (v4l2xv->dpy, v4l2object->xwindow_id, StructureNotifyMask, &e)) { switch (e.type) { case ConfigureNotify: update_geometry (v4l2object); break; default: break; } } g_mutex_unlock (v4l2xv->mutex); } /* repeat */ return TRUE; }