static void gst_sdlvideosink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (navigation); GstEvent *event; GstVideoRectangle dst = { 0, }; GstVideoRectangle src = { 0, }; GstVideoRectangle result; double x, y, old_x, old_y; GstPad *pad = NULL; src.w = GST_VIDEO_SINK_WIDTH (sdlvideosink); src.h = GST_VIDEO_SINK_HEIGHT (sdlvideosink); dst.w = sdlvideosink->width; dst.h = sdlvideosink->height; gst_video_sink_center_rect (src, dst, &result, FALSE); event = gst_event_new_navigation (structure); /* Our coordinates can be wrong here if we centered the video */ /* Converting pointer coordinates to the non scaled geometry */ if (gst_structure_get_double (structure, "pointer_x", &old_x)) { x = old_x; if (x >= result.x && x <= (result.x + result.w)) { x -= result.x; x *= sdlvideosink->width; x /= result.w; } else { x = 0; } GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event x " "coordinate from %f to %f", old_x, x); gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL); } if (gst_structure_get_double (structure, "pointer_y", &old_y)) { y = old_y; if (y >= result.y && y <= (result.y + result.h)) { y -= result.y; y *= sdlvideosink->height; y /= result.h; } else { y = 0; } GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event y " "coordinate from %f to %f", old_y, y); gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL); } pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sdlvideosink)); if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) { gst_pad_send_event (pad, event); gst_object_unref (pad); } }
static VALUE navigation_initialize(VALUE self, VALUE structure) { GstEvent *event; event = gst_event_new_navigation(RVAL2GST_STRUCT(structure)); G_INITIALIZE(self, event); return Qnil; }
static void nav_send_event (GstNavigation * navigation, GstStructure * structure) { GstEvent *event = gst_event_new_navigation (structure); GstNavigationEventType etype = gst_navigation_event_get_type (event); TestElement *self = (TestElement *) (navigation); fail_if (etype == GST_NAVIGATION_EVENT_INVALID, "Received navigation event could not be parsed"); fail_unless (etype == self->sent_type, "Received navigation event did not match sent"); switch (etype) { case GST_NAVIGATION_EVENT_KEY_PRESS: case GST_NAVIGATION_EVENT_KEY_RELEASE:{ const gchar *key; fail_unless (gst_navigation_event_parse_key_event (event, &key)); fail_unless (strcmp (key, self->sent_key) == 0); break; } case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS: case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:{ gint button; gdouble x, y; fail_unless (gst_navigation_event_parse_mouse_button_event (event, &button, &x, &y)); fail_unless (button == self->sent_button); fail_unless (x == self->sent_x); fail_unless (y == self->sent_y); break; } case GST_NAVIGATION_EVENT_MOUSE_MOVE:{ gdouble x, y; fail_unless (gst_navigation_event_parse_mouse_move_event (event, &x, &y)); fail_unless (x == self->sent_x); fail_unless (y == self->sent_y); break; } case GST_NAVIGATION_EVENT_COMMAND:{ GstNavigationCommand cmd; fail_unless (gst_navigation_event_parse_command (event, &cmd)); fail_unless (cmd == self->sent_command); } default: break; } gst_event_unref (event); }
static void gst_vdp_sink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { VdpSink *vdp_sink = GST_VDP_SINK (navigation); GstEvent *event; gint x_offset, y_offset; gdouble x, y; GstPad *pad = NULL; event = gst_event_new_navigation (structure); /* We are not converting the pointer coordinates as there's no hardware scaling done here. The only possible scaling is done by videoscale and videoscale will have to catch those events and tranform the coordinates to match the applied scaling. So here we just add the offset if the image is centered in the window. */ /* We take the flow_lock while we look at the window */ g_mutex_lock (vdp_sink->flow_lock); if (!vdp_sink->window) { g_mutex_unlock (vdp_sink->flow_lock); return; } x_offset = vdp_sink->window->width - GST_VIDEO_SINK_WIDTH (vdp_sink); y_offset = vdp_sink->window->height - GST_VIDEO_SINK_HEIGHT (vdp_sink); g_mutex_unlock (vdp_sink->flow_lock); if (x_offset > 0 && gst_structure_get_double (structure, "pointer_x", &x)) { x -= x_offset / 2; gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL); } if (y_offset > 0 && gst_structure_get_double (structure, "pointer_y", &y)) { y -= y_offset / 2; gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL); } pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (vdp_sink)); if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) { gst_pad_send_event (pad, event); gst_object_unref (pad); } }
static gboolean gst_video_crop_src_event (GstBaseTransform * trans, GstEvent * event) { GstEvent *new_event; GstStructure *new_structure; const GstStructure *structure; const gchar *event_name; double pointer_x; double pointer_y; GstVideoCrop *vcrop = GST_VIDEO_CROP (trans); new_event = NULL; GST_OBJECT_LOCK (vcrop); if (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION && (vcrop->crop_left != 0 || vcrop->crop_top != 0)) { structure = gst_event_get_structure (event); event_name = gst_structure_get_string (structure, "event"); if (event_name && (strcmp (event_name, "mouse-move") == 0 || strcmp (event_name, "mouse-button-press") == 0 || strcmp (event_name, "mouse-button-release") == 0)) { if (gst_structure_get_double (structure, "pointer_x", &pointer_x) && gst_structure_get_double (structure, "pointer_y", &pointer_y)) { new_structure = gst_structure_copy (structure); gst_structure_set (new_structure, "pointer_x", G_TYPE_DOUBLE, (double) (pointer_x + vcrop->crop_left), "pointer_y", G_TYPE_DOUBLE, (double) (pointer_y + vcrop->crop_top), NULL); new_event = gst_event_new_navigation (new_structure); gst_event_unref (event); } else { GST_WARNING_OBJECT (vcrop, "Failed to read navigation event"); } } } GST_OBJECT_UNLOCK (vcrop); return GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, (new_event ? new_event : event)); }
static void gst_gl_sink_bin_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstGLSinkBin *self = GST_GL_SINK_BIN (navigation); GstElement *nav = gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_NAVIGATION); if (nav) { gst_navigation_send_event (GST_NAVIGATION (nav), structure); structure = NULL; gst_object_unref (nav); } else { GstEvent *event = gst_event_new_navigation (structure); structure = NULL; gst_element_send_event (GST_ELEMENT (self), event); } }
static void gst_v4l2sink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstV4l2Sink *v4l2sink = GST_V4L2SINK (navigation); GstV4l2Xv *xv = v4l2sink->v4l2object->xv; GstPad *peer; if (!xv) return; if ((peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (v4l2sink)))) { GstVideoRectangle rect; gdouble x, y, xscale = 1.0, yscale = 1.0; gst_v4l2_video_overlay_get_render_rect (v4l2sink->v4l2object, &rect); /* We calculate scaling using the original video frames geometry to * include pixel aspect ratio scaling. */ xscale = (gdouble) v4l2sink->video_width / rect.w; yscale = (gdouble) v4l2sink->video_height / rect.h; /* Converting pointer coordinates to the non scaled geometry */ if (gst_structure_get_double (structure, "pointer_x", &x)) { x = MIN (x, rect.x + rect.w); x = MAX (x - rect.x, 0); gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, (gdouble) x * xscale, NULL); } if (gst_structure_get_double (structure, "pointer_y", &y)) { y = MIN (y, rect.y + rect.h); y = MAX (y - rect.y, 0); gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, (gdouble) y * yscale, NULL); } gst_pad_send_event (peer, gst_event_new_navigation (structure)); gst_object_unref (peer); } }
static void gst_glimage_sink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstGLImageSink *sink = GST_GLIMAGE_SINK (navigation); GstEvent *event = NULL; GstPad *pad = NULL; GstGLWindow *window = gst_gl_context_get_window (sink->context); guint width, height; gdouble x, y, xscale, yscale; g_return_if_fail (GST_GL_IS_WINDOW (window)); width = GST_VIDEO_SINK_WIDTH (sink); height = GST_VIDEO_SINK_HEIGHT (sink); gst_gl_window_get_surface_dimensions (window, &width, &height); event = gst_event_new_navigation (structure); pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)); /* Converting pointer coordinates to the non scaled geometry */ if (width != GST_VIDEO_SINK_WIDTH (sink) && width != 0 && gst_structure_get_double (structure, "pointer_x", &x)) { xscale = (gdouble) GST_VIDEO_SINK_WIDTH (sink) / width; gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, (gdouble) x * xscale, NULL); } if (height != GST_VIDEO_SINK_HEIGHT (sink) && height != 0 && gst_structure_get_double (structure, "pointer_y", &y)) { yscale = (gdouble) GST_VIDEO_SINK_HEIGHT (sink) / height; gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, (gdouble) y * yscale, NULL); } if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) gst_pad_send_event (pad, event); gst_object_unref (pad); gst_object_unref (window); }
bool mmsGstSendAxisMotion(GstElement *pipeline, int posx, int posy) { if (!pipeline) return false; // construct event GstStructure *structure = gst_structure_new( "application/x-gst-navigation", "event", G_TYPE_STRING, "mouse-move", "button", G_TYPE_INT, 0, "pointer_x",G_TYPE_DOUBLE, (double)posx, "pointer_y",G_TYPE_DOUBLE, (double)posy, NULL); if (!structure) return false; GstEvent *event = gst_event_new_navigation(structure); if (!event) return false; // send event return gst_element_send_event(pipeline, event); }
static void gst_d3dvideosink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstD3DVideoSink *sink = GST_D3DVIDEOSINK (navigation); GstEvent *e; if ((e = gst_event_new_navigation (structure))) { GstPad *pad; if ((pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)))) { if (!gst_pad_send_event (pad, gst_event_ref (e))) { /* If upstream didn't handle the event we'll post a message with it * for the application in case it wants to do something with it */ gst_element_post_message (GST_ELEMENT_CAST (sink), gst_navigation_message_new_event (GST_OBJECT_CAST (sink), e)); } gst_event_unref (e); gst_object_unref (pad); } } }
bool mmsGstSendKeyRelease(GstElement *pipeline, MMSKeySymbol key) { if (!pipeline) return false; // if keysym string is empty, do nothing but return success const char *ks = convertMMSKeySymbolToXKeysymString(key); if (!*ks) return true; // construct event GstStructure *structure = gst_structure_new( "application/x-gst-navigation", "event", G_TYPE_STRING, "key-release", "key", G_TYPE_STRING, ks, NULL); if (!structure) return false; GstEvent *event = gst_event_new_navigation(structure); if (!event) return false; // send event return gst_element_send_event(pipeline, event); }
static void gst_gtk_base_sink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstGtkBaseSink *sink = GST_GTK_BASE_SINK (navigation); GstEvent *event; GstPad *pad; event = gst_event_new_navigation (structure); pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)); GST_TRACE_OBJECT (sink, "navigation event %" GST_PTR_FORMAT, structure); if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) { if (!gst_pad_send_event (pad, gst_event_ref (event))) { /* If upstream didn't handle the event we'll post a message with it * for the application in case it wants to do something with it */ gst_element_post_message (GST_ELEMENT_CAST (sink), gst_navigation_message_new_event (GST_OBJECT_CAST (sink), event)); } gst_event_unref (event); gst_object_unref (pad); } }