[self setAcceptsMouseMovedEvents:YES];
}
-- (void) sendEvent:(NSEvent *) event {
- BOOL taken = NO;
-
- GST_DEBUG ("event %p type:%d", event,(gint)[event type]);
-
- if ([event type] == NSKeyDown) {
- }
- /*taken = [gstview keyDown:event]; */
-
- if (!taken) {
- [super sendEvent:event];
- }
-}
-
-
@end
GST_LOG ("Width: %d Height: %d", width, height);
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options: (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow)
+ owner:self
+ userInfo:nil];
+
+ [self addTrackingArea:trackingArea];
+
[self initTextures];
return self;
}
[super dealloc];
}
+
+- (void)updateTrackingAreas {
+ [self removeTrackingArea:trackingArea];
+ [trackingArea release];
+ trackingArea = [[NSTrackingArea alloc] initWithRect: [self bounds]
+ options: (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow)
+ owner:self userInfo:nil];
+ [self addTrackingArea:trackingArea];
+}
+
+- (BOOL)acceptsFirstResponder {
+ return YES;
+}
+
+- (void) setNavigation:(GstNavigation *)nav
+{
+ navigation = nav;
+}
+
+- (void)sendMouseEvent:(NSEvent *)event: (const char *)event_name
+{
+ NSPoint location;
+ NSRect bounds;
+ gint button;
+ gint view_width, view_height;
+ gdouble x, y;
+
+ if (!navigation)
+ return;
+
+ switch ([event type]) {
+ case NSMouseMoved:
+ button = 0;
+ break;
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ button = 1;
+ break;
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ button = 2;
+ break;
+ default:
+ button = 3;
+ break;
+ }
+
+ location = [self convertPoint:[event locationInWindow] fromView:nil];
+
+ /* scale X and Y locations to the frame size */
+ bounds = [self bounds];
+ view_width = bounds.size.width;
+ view_height = bounds.size.height;
+
+ x = ((gdouble) location.x / view_width) * width;
+ y = ((gdouble) location.y / view_height) * height;
+
+ /* invert Y */
+ y = (1 - y / height) * height;
+
+ gst_navigation_send_mouse_event (navigation, event_name, button,
+ x, y);
+}
+
+- (void)sendKeyEvent:(NSEvent *)event: (const char *)event_name
+{
+ NSString *keyCharStr = [event charactersIgnoringModifiers];
+ gchar * key_str;
+
+ if (!navigation)
+ return;
+
+ if ( [keyCharStr length] == 0 )
+ return;
+
+ if ( [keyCharStr length] == 1 ) {
+ key_str = g_strdup_printf("%c", [keyCharStr characterAtIndex:0]);
+ gst_navigation_send_key_event(navigation, event_name, (const gchar *) key_str);
+ g_free(key_str);
+ }
+}
+
+- (void)keyDown:(NSEvent *) event;
+{
+ [self sendKeyEvent: event: "key-press"];
+}
+
+- (void)keyUp:(NSEvent *) event;
+{
+ [self sendKeyEvent: event: "key-release"];
+}
+
+- (void)mouseDown:(NSEvent *) event;
+{
+ [self sendMouseEvent:event: "mouse-button-press"];
+}
+
+- (void)mouseUp:(NSEvent *) event;
+{
+ [self sendMouseEvent:event: "mouse-button-release"];
+}
+
+- (void)mouseMoved:(NSEvent *)event;
+{
+ [self sendMouseEvent:event: "mouse-move"];
+}
+
+- (void)mouseEntered:(NSEvent *)event;
+{
+}
+
+- (void)mouseExited:(NSEvent *)event;
+{
+}
+
@end
GST_INFO_OBJECT (osxvideosink, "no superview");
}
}
+ [osxwindow->gstview setNavigation: GST_NAVIGATION(osxvideosink)];
[pool release];
static gboolean
gst_osx_video_sink_interface_supported (GstImplementsInterface * iface, GType type)
{
- g_assert (type == GST_TYPE_X_OVERLAY);
+ g_assert (type == GST_TYPE_X_OVERLAY || type == GST_TYPE_NAVIGATION);
return TRUE;
}
}
static void
+gst_osx_video_sink_navigation_send_event (GstNavigation * navigation,
+ GstStructure * structure)
+{
+ GstOSXVideoSink *osxvideosink = GST_OSX_VIDEO_SINK (navigation);
+ GstPad *peer;
+ GstEvent *event;
+ GstVideoRectangle src, dst, result;
+ gdouble x, y, xscale = 1.0, yscale = 1.0;
+
+ peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (osxvideosink));
+
+ if (!peer || !osxvideosink->osxwindow)
+ return;
+
+ event = gst_event_new_navigation (structure);
+
+ /* FIXME: Use this when this sink is capable of keeping the display
+ * aspect ratio */
+ if (0) { //(osxvideosink->keep_aspect) {
+ /* We get the frame position using the calculated geometry from _setcaps
+ that respect pixel aspect ratios */
+ src.w = GST_VIDEO_SINK_WIDTH (osxvideosink);
+ src.h = GST_VIDEO_SINK_HEIGHT (osxvideosink);
+ //dst.w = osxvideosink->osxwindow->gstview->width;
+ //dst.w = osxvideosink->osxwindow->gstview->height;
+
+ gst_video_sink_center_rect (src, dst, &result, TRUE);
+ //result.x += osxvideosink->gstview->x;
+ //result.y += osxvideosink->gstview->y;
+ } else {
+ result.x = 0;
+ result.y = 0;
+ result.w = osxvideosink->osxwindow->width;
+ result.h = osxvideosink->osxwindow->height;
+ }
+
+ /* We calculate scaling using the original video frames geometry to include
+ pixel aspect ratio scaling. */
+ xscale = (gdouble) osxvideosink->osxwindow->width / result.w;
+ yscale = (gdouble) osxvideosink->osxwindow->height / result.h;
+
+ /* Converting pointer coordinates to the non scaled geometry */
+ if (gst_structure_get_double (structure, "pointer_x", &x)) {
+ x = MIN (x, result.x + result.w);
+ x = MAX (x - result.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, result.y + result.h);
+ y = MAX (y - result.y, 0);
+ gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
+ (gdouble) y * yscale, NULL);
+ }
+
+ gst_pad_send_event (peer, event);
+ gst_object_unref (peer);
+}
+
+static void
+gst_osx_video_sink_navigation_init (GstNavigationInterface * iface)
+{
+ iface->send_event = gst_osx_video_sink_navigation_send_event;
+}
+
+static void
gst_osx_video_sink_set_window_handle (GstXOverlay * overlay, guintptr handle_id)
{
GstOSXVideoSink *osxvideosink = GST_OSX_VIDEO_SINK (overlay);
NULL,
};
+ static const GInterfaceInfo navigation_info = {
+ (GInterfaceInitFunc) gst_osx_video_sink_navigation_init,
+ NULL,
+ NULL,
+ };
osxvideosink_type = g_type_register_static (GST_TYPE_VIDEO_SINK,
"GstOSXVideoSink", &osxvideosink_info, 0);