mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-08 15:32:32 +00:00
osxvideosink: implement the navigation interface
This commit is contained in:
parent
088bc6b056
commit
ba5d55dd69
3 changed files with 199 additions and 16 deletions
|
@ -29,6 +29,7 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <QuickTime/QuickTime.h>
|
#import <QuickTime/QuickTime.h>
|
||||||
#import <glib.h>
|
#import <glib.h>
|
||||||
|
#import <gst/interfaces/navigation.h>
|
||||||
|
|
||||||
struct _GstOSXImage;
|
struct _GstOSXImage;
|
||||||
|
|
||||||
|
@ -44,6 +45,8 @@ struct _GstOSXImage;
|
||||||
BOOL fullscreen;
|
BOOL fullscreen;
|
||||||
NSOpenGLContext* fullScreenContext;
|
NSOpenGLContext* fullScreenContext;
|
||||||
NSOpenGLContext* actualContext;
|
NSOpenGLContext* actualContext;
|
||||||
|
NSTrackingArea *trackingArea;
|
||||||
|
GstNavigation *navigation;
|
||||||
}
|
}
|
||||||
- (void) drawQuad;
|
- (void) drawQuad;
|
||||||
- (void) drawRect: (NSRect) rect;
|
- (void) drawRect: (NSRect) rect;
|
||||||
|
@ -60,6 +63,7 @@ struct _GstOSXImage;
|
||||||
- (void) haveSuperviewReal: (NSMutableArray *)closure;
|
- (void) haveSuperviewReal: (NSMutableArray *)closure;
|
||||||
- (void) addToSuperview: (NSView *)superview;
|
- (void) addToSuperview: (NSView *)superview;
|
||||||
- (void) removeFromSuperview: (id)unused;
|
- (void) removeFromSuperview: (id)unused;
|
||||||
|
- (void) setNavigation: (GstNavigation *) nav;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -82,21 +82,6 @@
|
||||||
[self setAcceptsMouseMovedEvents:YES];
|
[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
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,6 +129,13 @@
|
||||||
|
|
||||||
GST_LOG ("Width: %d Height: %d", width, height);
|
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];
|
[self initTextures];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -429,4 +421,119 @@
|
||||||
|
|
||||||
[super dealloc];
|
[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
|
@end
|
||||||
|
|
|
@ -148,6 +148,7 @@ gst_osx_video_sink_osxwindow_create (GstOSXVideoSink * osxvideosink, gint width,
|
||||||
GST_INFO_OBJECT (osxvideosink, "no superview");
|
GST_INFO_OBJECT (osxvideosink, "no superview");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[osxwindow->gstview setNavigation: GST_NAVIGATION(osxvideosink)];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
|
@ -416,7 +417,7 @@ gst_osx_video_sink_class_init (GstOSXVideoSinkClass * klass)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_osx_video_sink_interface_supported (GstImplementsInterface * iface, GType type)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +427,72 @@ gst_osx_video_sink_interface_init (GstImplementsInterfaceClass * klass)
|
||||||
klass->supported = gst_osx_video_sink_interface_supported;
|
klass->supported = gst_osx_video_sink_interface_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
gst_osx_video_sink_set_window_handle (GstXOverlay * overlay, guintptr handle_id)
|
gst_osx_video_sink_set_window_handle (GstXOverlay * overlay, guintptr handle_id)
|
||||||
{
|
{
|
||||||
|
@ -500,6 +567,11 @@ gst_osx_video_sink_get_type (void)
|
||||||
NULL,
|
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,
|
osxvideosink_type = g_type_register_static (GST_TYPE_VIDEO_SINK,
|
||||||
"GstOSXVideoSink", &osxvideosink_info, 0);
|
"GstOSXVideoSink", &osxvideosink_info, 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue