⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voutagl.m

📁 VLC Player Source Code
💻 M
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * voutagl.c: MacOS X agl OpenGL provider (used by webbrowser.plugin) ***************************************************************************** * Copyright (C) 2001-2007 the VideoLAN team * $Id$ * * Authors: Colin Delacroix <colin@zoy.org> *          Florian G. Pflug <fgp@phlo.org> *          Jon Lech Johansen <jon-vl@nanocrew.net> *          Derk-Jan Hartman <hartman at videolan dot org> *          Eric Petit <titer@m0k.org> *          Benjamin Pracht <bigben at videolan dot org> *          Damien Fouilleul <damienf at videolan dot org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#include "intf.h"#include "voutgl.h"#include "voutagl.h"/***************************************************************************** * embedded AGL context implementation *****************************************************************************/static void aglSetViewport( vout_thread_t *p_vout, Rect viewBounds, Rect clipBounds );static void aglReshape( vout_thread_t * p_vout );static OSStatus WindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);int aglInit( vout_thread_t * p_vout ){    vlc_value_t val;    Rect viewBounds;    Rect clipBounds;    static const GLint ATTRIBUTES[] = {        AGL_WINDOW,        AGL_RGBA,        AGL_NO_RECOVERY,        AGL_ACCELERATED,        AGL_DOUBLEBUFFER,        AGL_RED_SIZE,   8,        AGL_GREEN_SIZE, 8,        AGL_BLUE_SIZE,  8,        AGL_ALPHA_SIZE, 8,        AGL_DEPTH_SIZE, 24,        AGL_NONE };    AGLPixelFormat pixFormat;    p_vout->p_sys->b_embedded = true;    pixFormat = aglChoosePixelFormat(NULL, 0, ATTRIBUTES);    if( NULL == pixFormat )    {        msg_Err( p_vout, "No screen renderer available for required attributes." );        return VLC_EGENERIC;    }     p_vout->p_sys->agl_ctx = aglCreateContext(pixFormat, NULL);    aglDestroyPixelFormat(pixFormat);    if( NULL == p_vout->p_sys->agl_ctx )    {        msg_Err( p_vout, "Cannot create AGL context." );        return VLC_EGENERIC;    }    else {        // tell opengl not to sync buffer swap with vertical retrace (too inefficient)        GLint param = 0;        aglSetInteger(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL, &param);        aglEnable(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL);    }    var_Get( p_vout->p_libvlc, "drawable", &val );    p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int;    aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);    var_Get( p_vout->p_libvlc, "drawable-view-top", &val );    viewBounds.top = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-view-left", &val );    viewBounds.left = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-view-bottom", &val );    viewBounds.bottom = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-view-right", &val );    viewBounds.right = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-clip-top", &val );    clipBounds.top = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-clip-left", &val );    clipBounds.left = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-clip-bottom", &val );    clipBounds.bottom = val.i_int;    var_Get( p_vout->p_libvlc, "drawable-clip-right", &val );    clipBounds.right = val.i_int;    p_vout->p_sys->b_clipped_out = (clipBounds.top == clipBounds.bottom)                                 || (clipBounds.left == clipBounds.right);    if( ! p_vout->p_sys->b_clipped_out )    {        aglLock(p_vout);        aglSetViewport(p_vout, viewBounds, clipBounds);        aglReshape(p_vout);        aglUnlock(p_vout);    }    p_vout->p_sys->clipBounds = clipBounds;    p_vout->p_sys->viewBounds = viewBounds;    return VLC_SUCCESS;}void aglEnd( vout_thread_t * p_vout ){    aglSetCurrentContext(NULL);    if( p_vout->p_sys->theWindow ) DisposeWindow( p_vout->p_sys->theWindow );    aglDestroyContext(p_vout->p_sys->agl_ctx);}void aglReshape( vout_thread_t * p_vout ){    unsigned int x, y;    unsigned int i_height = p_vout->p_sys->i_height;    unsigned int i_width  = p_vout->p_sys->i_width;    vout_PlacePicture(p_vout, i_width, i_height, &x, &y, &i_width, &i_height);    glViewport( p_vout->p_sys->i_offx + x, p_vout->p_sys->i_offy + y, i_width, i_height );    if( p_vout->p_sys->b_got_frame )    {        /* Ask the opengl module to redraw */        vout_thread_t * p_parent;        p_parent = (vout_thread_t *) p_vout->p_parent;        if( p_parent && p_parent->pf_display )        {            p_parent->pf_display( p_parent, NULL );        }    }    else    {        glClear( GL_COLOR_BUFFER_BIT );    }}/* private event class */enum{    kEventClassVLCPlugin = 'vlcp',};/* private event kinds */enum{    kEventVLCPluginShowFullscreen = 32768,    kEventVLCPluginHideFullscreen,};static void sendEventToMainThread(EventTargetRef target, UInt32 class, UInt32 kind){    EventRef myEvent;    if( noErr == CreateEvent(NULL, class, kind, 0, kEventAttributeNone, &myEvent) )    {        if( noErr == SetEventParameter(myEvent, kEventParamPostTarget, typeEventTargetRef, sizeof(EventTargetRef), &target) )        {            PostEventToQueue(GetMainEventQueue(), myEvent, kEventPriorityStandard);        }        ReleaseEvent(myEvent);    }}int aglManage( vout_thread_t * p_vout ){    if( p_vout->i_changes & VOUT_ASPECT_CHANGE )    {        aglLock( p_vout );        aglReshape(p_vout);        aglUnlock( p_vout );        p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;    }    if( p_vout->i_changes & VOUT_CROP_CHANGE )    {        aglLock( p_vout );        aglReshape(p_vout);        aglUnlock( p_vout );        p_vout->i_changes &= ~VOUT_CROP_CHANGE;    }    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )    {        aglSetDrawable(p_vout->p_sys->agl_ctx, NULL);        aglLock( p_vout );        if( p_vout->b_fullscreen )        {            /* Close the fullscreen window and resume normal drawing */            vlc_value_t val;            Rect viewBounds;            Rect clipBounds;            var_Get( p_vout->p_libvlc, "drawable", &val );            p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int;            aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);            var_Get( p_vout->p_libvlc, "drawable-view-top", &val );            viewBounds.top = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-view-left", &val );            viewBounds.left = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-view-bottom", &val );            viewBounds.bottom = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-view-right", &val );            viewBounds.right = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-clip-top", &val );            clipBounds.top = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-clip-left", &val );            clipBounds.left = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-clip-bottom", &val );            clipBounds.bottom = val.i_int;            var_Get( p_vout->p_libvlc, "drawable-clip-right", &val );            clipBounds.right = val.i_int;            aglSetCurrentContext(p_vout->p_sys->agl_ctx);            aglSetViewport(p_vout, viewBounds, clipBounds);            /* Most Carbon APIs are not thread-safe, therefore delagate some GUI visibilty update to the main thread */            sendEventToMainThread(GetWindowEventTarget(p_vout->p_sys->theWindow), kEventClassVLCPlugin, kEventVLCPluginHideFullscreen);        }        else        {            Rect deviceRect;             GDHandle deviceHdl = GetMainDevice();            deviceRect = (*deviceHdl)->gdRect;             if( !p_vout->p_sys->theWindow )            {                /* Create a window */                WindowAttributes    windowAttrs;                windowAttrs = kWindowStandardDocumentAttributes                            | kWindowStandardHandlerAttribute                            | kWindowLiveResizeAttribute                            | kWindowNoShadowAttribute;                 windowAttrs &= (~kWindowResizableAttribute);                CreateNewWindow(kDocumentWindowClass, windowAttrs, &deviceRect, &p_vout->p_sys->theWindow);                if( !p_vout->p_sys->winGroup )                {                    CreateWindowGroup(0, &p_vout->p_sys->winGroup);                    SetWindowGroup(p_vout->p_sys->theWindow, p_vout->p_sys->winGroup);                    SetWindowGroupParent( p_vout->p_sys->winGroup, GetWindowGroupOfClass(kDocumentWindowClass) ) ;                }                 // Window title                CFStringRef titleKey    = CFSTR("Fullscreen VLC media plugin");                CFStringRef windowTitle = CFCopyLocalizedString(titleKey, NULL);                SetWindowTitleWithCFString(p_vout->p_sys->theWindow, windowTitle);                CFRelease(titleKey);                CFRelease(windowTitle);                 //Install event handler                static const EventTypeSpec win_events[] = {                    { kEventClassMouse, kEventMouseDown },                    { kEventClassMouse, kEventMouseMoved },                    { kEventClassMouse, kEventMouseUp },                    { kEventClassWindow, kEventWindowClosed },                    { kEventClassWindow, kEventWindowBoundsChanged },                    { kEventClassCommand, kEventCommandProcess },                    { kEventClassVLCPlugin, kEventVLCPluginShowFullscreen },                    { kEventClassVLCPlugin, kEventVLCPluginHideFullscreen },                };                InstallWindowEventHandler (p_vout->p_sys->theWindow, NewEventHandlerUPP (WindowEventHandler), GetEventTypeCount(win_events), win_events, p_vout, NULL);            }            else            {                /* just in case device resolution changed */                SetWindowBounds(p_vout->p_sys->theWindow, kWindowContentRgn, &deviceRect);            }            glClear( GL_COLOR_BUFFER_BIT );            p_vout->p_sys->agl_drawable = (AGLDrawable)GetWindowPort(p_vout->p_sys->theWindow);            aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);            aglSetCurrentContext(p_vout->p_sys->agl_ctx);            aglSetViewport(p_vout, deviceRect, deviceRect);            //aglSetFullScreen(p_vout->p_sys->agl_ctx, device_width, device_height, 0, 0);            /* Most Carbon APIs are not thread-safe, therefore delagate some GUI visibilty update to the main thread */            sendEventToMainThread(GetWindowEventTarget(p_vout->p_sys->theWindow), kEventClassVLCPlugin, kEventVLCPluginShowFullscreen);        }        aglReshape(p_vout);        aglUnlock( p_vout );        p_vout->b_fullscreen = !p_vout->b_fullscreen;        p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;    }    return VLC_SUCCESS;}int aglControl( vout_thread_t *p_vout, int i_query, va_list args ){    switch( i_query )    {        case VOUT_SET_VIEWPORT:        {            Rect viewBounds, clipBounds;            viewBounds.top = va_arg( args, int);            viewBounds.left = va_arg( args, int);            viewBounds.bottom = va_arg( args, int);            viewBounds.right = va_arg( args, int);            clipBounds.top = va_arg( args, int);            clipBounds.left = va_arg( args, int);            clipBounds.bottom = va_arg( args, int);            clipBounds.right = va_arg( args, int);             if( !p_vout->b_fullscreen )            {                /*                ** check that the clip rect is not empty, as this is used                ** by Firefox to prevent a plugin from displaying during                ** a scrolling event. In this case we just prevent buffers                ** from being swapped and ignore clipping as this is less                ** disruptive than a GL geometry change                */                p_vout->p_sys->b_clipped_out = (clipBounds.top == clipBounds.bottom)                                             || (clipBounds.left == clipBounds.right);                if( ! p_vout->p_sys->b_clipped_out )                {                    /* ignore consecutive viewport update with identical parameters */                    if( memcmp(&clipBounds, &(p_vout->p_sys->clipBounds), sizeof(clipBounds) )                     && memcmp(&viewBounds, &(p_vout->p_sys->viewBounds), sizeof(viewBounds)) )                    {                        aglLock( p_vout );                        aglSetViewport(p_vout, viewBounds, clipBounds);                        aglReshape( p_vout );                        aglUnlock( p_vout );                        p_vout->p_sys->clipBounds = clipBounds;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -