X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fmacosx.m;h=5bacb08ceffc521ca371efb05a65dea1515ddb01;hb=818e9afa5d316a43d7dd75531670ec47d76f9d8c;hp=fe508fe9d5af84ab45546a791c81027653cd5e71;hpb=12a36253521fbd28b624c11681517009e49f346b;p=vlc diff --git a/modules/video_output/macosx.m b/modules/video_output/macosx.m index fe508fe9d5..5bacb08cef 100644 --- a/modules/video_output/macosx.m +++ b/modules/video_output/macosx.m @@ -72,8 +72,7 @@ vlc_module_begin () set_capability("vout display", 300) set_callbacks(Open, Close) - add_shortcut("macosx") - add_shortcut("vout_macosx") + add_shortcut("macosx", "vout_macosx") vlc_module_end () /** @@ -99,6 +98,7 @@ struct vout_display_sys_t VLCOpenGLVideoView *glView; id container; + vout_window_t *embed; vout_opengl_t gl; vout_display_opengl_t vgl; @@ -119,13 +119,34 @@ static int Open(vlc_object_t *this) vd->sys = sys; sys->pool = NULL; sys->gl.sys = NULL; + sys->embed = NULL; /* Get the drawable object */ id container = var_CreateGetAddress(vd, "drawable-nsobject"); - if (!container) + if (container) { - msg_Dbg(vd, "No drawable-nsobject, passing over."); - goto error; + vout_display_DeleteWindow(vd, NULL); + } + else + { + vout_window_cfg_t wnd_cfg; + + memset (&wnd_cfg, 0, sizeof (wnd_cfg)); + wnd_cfg.type = VOUT_WINDOW_TYPE_NSOBJECT; + wnd_cfg.x = var_InheritInteger (vd, "video-x"); + wnd_cfg.y = var_InheritInteger (vd, "video-y"); + wnd_cfg.width = vd->cfg->display.width; + wnd_cfg.height = vd->cfg->display.height; + + sys->embed = vout_display_NewWindow (vd, &wnd_cfg); + if (sys->embed) + container = sys->embed->handle.nsobject; + + if (!container) + { + msg_Dbg(vd, "No drawable-nsobject nor vout_window_t found, passing over."); + goto error; + } } /* This will be released in Close(), on @@ -144,7 +165,21 @@ static int Open(vlc_object_t *this) /* We don't wait, that means that we'll have to be careful about releasing * container. * That's why we'll release on main thread in Close(). */ - [(id)container performSelectorOnMainThread:@selector(addVoutSubview:) withObject:sys->glView waitUntilDone:NO]; + if ([(id)container respondsToSelector:@selector(addVoutSubview:)]) + [(id)container performSelectorOnMainThread:@selector(addVoutSubview:) withObject:sys->glView waitUntilDone:NO]; + else if ([container isKindOfClass:[NSView class]]) + { + NSView *parentView = container; + [parentView performSelectorOnMainThread:@selector(addSubview:) withObject:sys->glView waitUntilDone:NO]; + [sys->glView performSelectorOnMainThread:@selector(setFrameWithValue:) withObject:[NSValue valueWithRect:[parentView bounds]] waitUntilDone:NO]; + } + else + { + msg_Err(vd, "Invalid drawable-nsobject object. drawable-nsobject must either be an NSView or comply to the @protocol VLCOpenGLVideoViewEmbedding."); + goto error; + } + + [nsPool release]; nsPool = nil; @@ -192,8 +227,11 @@ void Close(vlc_object_t *this) [sys->glView setVoutDisplay:nil]; var_Destroy(vd, "drawable-nsobject"); - /* This will retain sys->glView */ - [(id)sys->container performSelectorOnMainThread:@selector(removeVoutSubview:) withObject:sys->glView waitUntilDone:NO]; + if ([(id)sys->container respondsToSelector:@selector(removeVoutSubview:)]) + { + /* This will retain sys->glView */ + [(id)sys->container performSelectorOnMainThread:@selector(removeVoutSubview:) withObject:sys->glView waitUntilDone:NO]; + } /* release on main thread as explained in Open() */ [(id)sys->container performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO]; [sys->glView performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:NO]; @@ -203,6 +241,8 @@ void Close(vlc_object_t *this) if (sys->gl.sys != NULL) vout_display_opengl_Clean(&sys->vgl); + if (sys->embed) + vout_display_DeleteWindow(vd, sys->embed); free (sys); } @@ -353,9 +393,18 @@ static void OpenglSwap(vout_opengl_t *gl) GLint params[] = { 1 }; CGLSetParameter([[self openGLContext] CGLContextObj], kCGLCPSwapInterval, params); + [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; return self; } +/** + * Gets called by the Open() method. + */ +- setFrameWithValue:(NSValue *)value +{ + [self setFrame:[value rectValue]]; +} + /** * Gets called by the Close and Open methods. * (Non main thread). @@ -401,7 +450,10 @@ static void OpenglSwap(vout_opengl_t *gl) - (BOOL)lockgl { VLCAssertMainThread(); - CGLError err = CGLLockContext([[self openGLContext] CGLContextObj]); + NSOpenGLContext *context = [self openGLContext]; + CGLError err = CGLLockContext([context CGLContextObj]); + if (err == kCGLNoError) + [context makeCurrentContext]; return err == kCGLNoError; } @@ -475,21 +527,21 @@ static void OpenglSwap(vout_opengl_t *gl) } } - [self lockgl]; + if ([self lockgl]) { + glViewport((width - x) / 2, (height - y) / 2, x, y); - glViewport((width - x) / 2, (height - y) / 2, x, y); - - @synchronized(self) { - // This may be cleared before -drawRect is being called, - // in this case we'll skip the rendering. - // This will save us for rendering two frames (or more) for nothing - // (one by the vout, one (or more) by drawRect) - _hasPendingReshape = YES; - } + @synchronized(self) { + // This may be cleared before -drawRect is being called, + // in this case we'll skip the rendering. + // This will save us for rendering two frames (or more) for nothing + // (one by the vout, one (or more) by drawRect) + _hasPendingReshape = YES; + } - [self unlockgl]; + [self unlockgl]; - [super reshape]; + [super reshape]; + } } /**