voutagl.m
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:24k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * voutagl.c: MacOS X agl OpenGL provider (used by webbrowser.plugin)
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2007 the VideoLAN team
  5.  * $Id: 80425c2bd606099e48d2a6177ca2f31e507dae75 $
  6.  *
  7.  * Authors: Colin Delacroix <colin@zoy.org>
  8.  *          Florian G. Pflug <fgp@phlo.org>
  9.  *          Jon Lech Johansen <jon-vl@nanocrew.net>
  10.  *          Derk-Jan Hartman <hartman at videolan dot org>
  11.  *          Eric Petit <titer@m0k.org>
  12.  *          Benjamin Pracht <bigben at videolan dot org>
  13.  *          Damien Fouilleul <damienf at videolan dot org>
  14.  *
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2 of the License, or
  18.  * (at your option) any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; if not, write to the Free Software
  27.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  28.  *****************************************************************************/
  29. #include "intf.h"
  30. #include "voutgl.h"
  31. #include "voutagl.h"
  32. /*****************************************************************************
  33.  * embedded AGL context implementation (not 64bit compatible)
  34.  *****************************************************************************/
  35. #ifndef __x86_64__
  36. static void aglSetViewport( vout_thread_t *p_vout, Rect viewBounds, Rect clipBounds );
  37. static void aglReshape( vout_thread_t * p_vout );
  38. static OSStatus WindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
  39. int aglInit( vout_thread_t * p_vout )
  40. {
  41.     vlc_value_t val;
  42.     Rect viewBounds;
  43.     Rect clipBounds;
  44.     static const GLint ATTRIBUTES[] = {
  45.         AGL_WINDOW,
  46.         AGL_RGBA,
  47.         AGL_NO_RECOVERY,
  48.         AGL_ACCELERATED,
  49.         AGL_DOUBLEBUFFER,
  50.         AGL_RED_SIZE,   8,
  51.         AGL_GREEN_SIZE, 8,
  52.         AGL_BLUE_SIZE,  8,
  53.         AGL_ALPHA_SIZE, 8,
  54.         AGL_DEPTH_SIZE, 24,
  55.         AGL_NONE };
  56.     AGLPixelFormat pixFormat;
  57.     p_vout->p_sys->b_embedded = true;
  58.     pixFormat = aglChoosePixelFormat(NULL, 0, ATTRIBUTES);
  59.     if( NULL == pixFormat )
  60.     {
  61.         msg_Err( p_vout, "No screen renderer available for required attributes." );
  62.         return VLC_EGENERIC;
  63.     }
  64.  
  65.     p_vout->p_sys->agl_ctx = aglCreateContext(pixFormat, NULL);
  66.     aglDestroyPixelFormat(pixFormat);
  67.     if( NULL == p_vout->p_sys->agl_ctx )
  68.     {
  69.         msg_Err( p_vout, "Cannot create AGL context." );
  70.         return VLC_EGENERIC;
  71.     }
  72.     else
  73.     {
  74.         // tell opengl not to sync buffer swap with vertical retrace (too inefficient)
  75.         GLint param = 0;
  76.         aglSetInteger(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL, &param);
  77.         aglEnable(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL);
  78.     }
  79.     var_Get( p_vout->p_libvlc, "drawable-agl", &val );
  80.     p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int;
  81.     aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);
  82.     var_Get( p_vout->p_libvlc, "drawable-view-top", &val );
  83.     viewBounds.top = val.i_int;
  84.     var_Get( p_vout->p_libvlc, "drawable-view-left", &val );
  85.     viewBounds.left = val.i_int;
  86.     var_Get( p_vout->p_libvlc, "drawable-view-bottom", &val );
  87.     viewBounds.bottom = val.i_int;
  88.     var_Get( p_vout->p_libvlc, "drawable-view-right", &val );
  89.     viewBounds.right = val.i_int;
  90.     var_Get( p_vout->p_libvlc, "drawable-clip-top", &val );
  91.     clipBounds.top = val.i_int;
  92.     var_Get( p_vout->p_libvlc, "drawable-clip-left", &val );
  93.     clipBounds.left = val.i_int;
  94.     var_Get( p_vout->p_libvlc, "drawable-clip-bottom", &val );
  95.     clipBounds.bottom = val.i_int;
  96.     var_Get( p_vout->p_libvlc, "drawable-clip-right", &val );
  97.     clipBounds.right = val.i_int;
  98.     p_vout->p_sys->b_clipped_out = (clipBounds.top == clipBounds.bottom)
  99.                                  || (clipBounds.left == clipBounds.right);
  100.     if( ! p_vout->p_sys->b_clipped_out )
  101.     {
  102.         aglLock(p_vout);
  103.         aglSetViewport(p_vout, viewBounds, clipBounds);
  104.         aglReshape(p_vout);
  105.         aglUnlock(p_vout);
  106.     }
  107.     p_vout->p_sys->clipBounds = clipBounds;
  108.     p_vout->p_sys->viewBounds = viewBounds;
  109.     return VLC_SUCCESS;
  110. }
  111. void aglEnd( vout_thread_t * p_vout )
  112. {
  113.     aglSetCurrentContext(NULL);
  114.     if( p_vout->p_sys->theWindow )
  115.         DisposeWindow( p_vout->p_sys->theWindow );
  116.     aglDestroyContext(p_vout->p_sys->agl_ctx);
  117. }
  118. void aglReshape( vout_thread_t * p_vout )
  119. {
  120.     unsigned int x, y;
  121.     unsigned int i_height = p_vout->p_sys->i_height;
  122.     unsigned int i_width  = p_vout->p_sys->i_width;
  123.     vout_PlacePicture(p_vout, i_width, i_height, &x, &y, &i_width, &i_height);
  124.     glViewport( p_vout->p_sys->i_offx + x, p_vout->p_sys->i_offy + y, i_width, i_height );
  125.     if( p_vout->p_sys->b_got_frame )
  126.     {
  127.         /* Ask the opengl module to redraw */
  128.         vout_thread_t * p_parent;
  129.         p_parent = (vout_thread_t *) p_vout->p_parent;
  130.         if( p_parent && p_parent->pf_display )
  131.         {
  132.             p_parent->pf_display( p_parent, NULL );
  133.         }
  134.     }
  135.     else
  136.     {
  137.         glClear( GL_COLOR_BUFFER_BIT );
  138.     }
  139. }
  140. /* private event class */
  141. enum
  142. {
  143.     kEventClassVLCPlugin = 'vlcp',
  144. };
  145. /* private event kinds */
  146. enum
  147. {
  148.     kEventVLCPluginShowFullscreen = 32768,
  149.     kEventVLCPluginHideFullscreen,
  150. };
  151. static void sendEventToMainThread(EventTargetRef target, UInt32 class, UInt32 kind)
  152. {
  153.     EventRef myEvent;
  154.     if( noErr == CreateEvent(NULL, class, kind, 0, kEventAttributeNone, &myEvent) )
  155.     {
  156.         if( noErr == SetEventParameter(myEvent, kEventParamPostTarget, typeEventTargetRef, sizeof(EventTargetRef), &target) )
  157.         {
  158.             PostEventToQueue(GetMainEventQueue(), myEvent, kEventPriorityStandard);
  159.         }
  160.         ReleaseEvent(myEvent);
  161.     }
  162. }
  163. int aglManage( vout_thread_t * p_vout )
  164. {
  165.     if( p_vout->i_changes & VOUT_ASPECT_CHANGE )
  166.     {
  167.         aglLock( p_vout );
  168.         aglReshape(p_vout);
  169.         aglUnlock( p_vout );
  170.         p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
  171.     }
  172.     if( p_vout->i_changes & VOUT_CROP_CHANGE )
  173.     {
  174.         aglLock( p_vout );
  175.         aglReshape(p_vout);
  176.         aglUnlock( p_vout );
  177.         p_vout->i_changes &= ~VOUT_CROP_CHANGE;
  178.     }
  179.     if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
  180.     {
  181.         aglSetDrawable(p_vout->p_sys->agl_ctx, NULL);
  182.         aglLock( p_vout );
  183.         if( p_vout->b_fullscreen )
  184.         {
  185.             /* Close the fullscreen window and resume normal drawing */
  186.             vlc_value_t val;
  187.             Rect viewBounds;
  188.             Rect clipBounds;
  189.             var_Get( p_vout->p_libvlc, "drawable-agl", &val );
  190.             p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int;
  191.             aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);
  192.             var_Get( p_vout->p_libvlc, "drawable-view-top", &val );
  193.             viewBounds.top = val.i_int;
  194.             var_Get( p_vout->p_libvlc, "drawable-view-left", &val );
  195.             viewBounds.left = val.i_int;
  196.             var_Get( p_vout->p_libvlc, "drawable-view-bottom", &val );
  197.             viewBounds.bottom = val.i_int;
  198.             var_Get( p_vout->p_libvlc, "drawable-view-right", &val );
  199.             viewBounds.right = val.i_int;
  200.             var_Get( p_vout->p_libvlc, "drawable-clip-top", &val );
  201.             clipBounds.top = val.i_int;
  202.             var_Get( p_vout->p_libvlc, "drawable-clip-left", &val );
  203.             clipBounds.left = val.i_int;
  204.             var_Get( p_vout->p_libvlc, "drawable-clip-bottom", &val );
  205.             clipBounds.bottom = val.i_int;
  206.             var_Get( p_vout->p_libvlc, "drawable-clip-right", &val );
  207.             clipBounds.right = val.i_int;
  208.             aglSetCurrentContext(p_vout->p_sys->agl_ctx);
  209.             aglSetViewport(p_vout, viewBounds, clipBounds);
  210.             /* Most Carbon APIs are not thread-safe, therefore delagate some GUI visibilty update to the main thread */
  211.             if( p_vout->p_sys->theWindow )
  212.                 sendEventToMainThread(GetWindowEventTarget(p_vout->p_sys->theWindow), kEventClassVLCPlugin, kEventVLCPluginHideFullscreen);
  213.         }
  214.         else
  215.         {
  216.             Rect deviceRect;
  217.  
  218.             GDHandle deviceHdl = GetMainDevice();
  219.             deviceRect = (*deviceHdl)->gdRect;
  220.  
  221.             if( !p_vout->p_sys->theWindow )
  222.             {
  223.                 /* Create a window */
  224.                 WindowAttributes    windowAttrs;
  225.                 windowAttrs = kWindowStandardDocumentAttributes
  226.                             | kWindowStandardHandlerAttribute
  227.                             | kWindowLiveResizeAttribute
  228.                             | kWindowNoShadowAttribute;
  229.  
  230.                 windowAttrs &= (~kWindowResizableAttribute);
  231.                 CreateNewWindow(kDocumentWindowClass, windowAttrs, &deviceRect, &p_vout->p_sys->theWindow);
  232.                 if( !p_vout->p_sys->winGroup )
  233.                 {
  234.                     CreateWindowGroup(0, &p_vout->p_sys->winGroup);
  235.                     SetWindowGroup(p_vout->p_sys->theWindow, p_vout->p_sys->winGroup);
  236.                     SetWindowGroupParent( p_vout->p_sys->winGroup, GetWindowGroupOfClass(kDocumentWindowClass) ) ;
  237.                 }
  238.  
  239.                 // Window title
  240.                 CFStringRef titleKey    = CFSTR("Fullscreen VLC media plugin");
  241.                 CFStringRef windowTitle = CFCopyLocalizedString(titleKey, NULL);
  242.                 SetWindowTitleWithCFString(p_vout->p_sys->theWindow, windowTitle);
  243.                 CFRelease(titleKey);
  244.                 CFRelease(windowTitle);
  245.  
  246.                 //Install event handler
  247.                 static const EventTypeSpec win_events[] = {
  248.                     { kEventClassMouse, kEventMouseDown },
  249.                     { kEventClassMouse, kEventMouseMoved },
  250.                     { kEventClassMouse, kEventMouseUp },
  251.                     { kEventClassWindow, kEventWindowClosed },
  252.                     { kEventClassWindow, kEventWindowBoundsChanged },
  253.                     { kEventClassCommand, kEventCommandProcess },
  254.                     { kEventClassVLCPlugin, kEventVLCPluginShowFullscreen },
  255.                     { kEventClassVLCPlugin, kEventVLCPluginHideFullscreen },
  256.                 };
  257.                 InstallWindowEventHandler (p_vout->p_sys->theWindow, NewEventHandlerUPP (WindowEventHandler), GetEventTypeCount(win_events), win_events, p_vout, NULL);
  258.             }
  259.             else
  260.             {
  261.                 /* just in case device resolution changed */
  262.                 SetWindowBounds(p_vout->p_sys->theWindow, kWindowContentRgn, &deviceRect);
  263.             }
  264.             glClear( GL_COLOR_BUFFER_BIT );
  265.             p_vout->p_sys->agl_drawable = (AGLDrawable)GetWindowPort(p_vout->p_sys->theWindow);
  266.             aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);
  267.             aglSetCurrentContext(p_vout->p_sys->agl_ctx);
  268.             aglSetViewport(p_vout, deviceRect, deviceRect);
  269.             //aglSetFullScreen(p_vout->p_sys->agl_ctx, device_width, device_height, 0, 0);
  270.             /* Most Carbon APIs are not thread-safe, therefore delagate some GUI visibilty update to the main thread */
  271.             sendEventToMainThread(GetWindowEventTarget(p_vout->p_sys->theWindow), kEventClassVLCPlugin, kEventVLCPluginShowFullscreen);
  272.         }
  273.         aglReshape(p_vout);
  274.         aglUnlock( p_vout );
  275.         p_vout->b_fullscreen = !p_vout->b_fullscreen;
  276.         p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
  277.     }
  278.     return VLC_SUCCESS;
  279. }
  280. int aglControl( vout_thread_t *p_vout, int i_query, va_list args )
  281. {
  282.     switch( i_query )
  283.     {
  284.         case VOUT_SET_VIEWPORT:
  285.         {
  286.             Rect viewBounds, clipBounds;
  287.             viewBounds.top = va_arg( args, int);
  288.             viewBounds.left = va_arg( args, int);
  289.             viewBounds.bottom = va_arg( args, int);
  290.             viewBounds.right = va_arg( args, int);
  291.             clipBounds.top = va_arg( args, int);
  292.             clipBounds.left = va_arg( args, int);
  293.             clipBounds.bottom = va_arg( args, int);
  294.             clipBounds.right = va_arg( args, int);
  295.  
  296.             if( !p_vout->b_fullscreen )
  297.             {
  298.                 /*
  299.                 ** check that the clip rect is not empty, as this is used
  300.                 ** by Firefox to prevent a plugin from displaying during
  301.                 ** a scrolling event. In this case we just prevent buffers
  302.                 ** from being swapped and ignore clipping as this is less
  303.                 ** disruptive than a GL geometry change
  304.                 */
  305.                 p_vout->p_sys->b_clipped_out = (clipBounds.top == clipBounds.bottom)
  306.                                              || (clipBounds.left == clipBounds.right);
  307.                 if( ! p_vout->p_sys->b_clipped_out )
  308.                 {
  309.                     /* ignore consecutive viewport update with identical parameters */
  310.                     if( memcmp(&clipBounds, &(p_vout->p_sys->clipBounds), sizeof(clipBounds) )
  311.                      && memcmp(&viewBounds, &(p_vout->p_sys->viewBounds), sizeof(viewBounds)) )
  312.                     {
  313.                         aglLock( p_vout );
  314.                         aglSetViewport(p_vout, viewBounds, clipBounds);
  315.                         aglReshape( p_vout );
  316.                         aglUnlock( p_vout );
  317.                         p_vout->p_sys->clipBounds = clipBounds;
  318.                         p_vout->p_sys->viewBounds = viewBounds;
  319.                     }
  320.                 }
  321.             }
  322.             return VLC_SUCCESS;
  323.         }
  324.         case VOUT_REDRAW_RECT:
  325.         {
  326.             vout_thread_t * p_parent;
  327.             Rect areaBounds;
  328.             areaBounds.top = va_arg( args, int);
  329.             areaBounds.left = va_arg( args, int);
  330.             areaBounds.bottom = va_arg( args, int);
  331.             areaBounds.right = va_arg( args, int);
  332.             /* Ask the opengl module to redraw */
  333.             p_parent = (vout_thread_t *) p_vout->p_parent;
  334.             if( p_parent && p_parent->pf_display )
  335.             {
  336.                 p_parent->pf_display( p_parent, NULL );
  337.             }
  338.             return VLC_SUCCESS;
  339.         }
  340.         default:
  341.             return VLC_EGENERIC;
  342.     }
  343. }
  344. void aglSwap( vout_thread_t * p_vout )
  345. {
  346.     if( ! p_vout->p_sys->b_clipped_out )
  347.     {
  348.         p_vout->p_sys->b_got_frame = true;
  349.         aglSwapBuffers(p_vout->p_sys->agl_ctx);
  350.     }
  351.     else
  352.     {
  353.         /* drop frame */
  354.         glFlush();
  355.     }
  356. }
  357. /* Enter this function with the p_vout locked */
  358. static void aglSetViewport( vout_thread_t *p_vout, Rect viewBounds, Rect clipBounds )
  359. {
  360.     // mozilla plugin provides coordinates based on port bounds
  361.     // however AGL coordinates are based on window structure region
  362.     // and are vertically flipped
  363.     GLint rect[4];
  364.     CGrafPtr port = (CGrafPtr)p_vout->p_sys->agl_drawable;
  365.     Rect winBounds, clientBounds;
  366.     GetWindowBounds(GetWindowFromPort(port),
  367.         kWindowStructureRgn, &winBounds);
  368.     GetWindowBounds(GetWindowFromPort(port),
  369.         kWindowContentRgn, &clientBounds);
  370.     /* update video clipping bounds in drawable */
  371.     rect[0] = (clientBounds.left-winBounds.left)
  372.             + clipBounds.left;                  // from window left edge
  373.     rect[1] = (winBounds.bottom-winBounds.top)
  374.             - (clientBounds.top-winBounds.top)
  375.             - clipBounds.bottom;                // from window bottom edge
  376.     rect[2] = clipBounds.right-clipBounds.left; // width
  377.     rect[3] = clipBounds.bottom-clipBounds.top; // height
  378.     aglSetInteger(p_vout->p_sys->agl_ctx, AGL_BUFFER_RECT, rect);
  379.     aglEnable(p_vout->p_sys->agl_ctx, AGL_BUFFER_RECT);
  380.     /* update video internal bounds in drawable */
  381.     p_vout->p_sys->i_width  = viewBounds.right-viewBounds.left;
  382.     p_vout->p_sys->i_height = viewBounds.bottom-viewBounds.top;
  383.     p_vout->p_sys->i_offx   = -clipBounds.left - viewBounds.left;
  384.     p_vout->p_sys->i_offy   = clipBounds.bottom + viewBounds.top
  385.                             - p_vout->p_sys->i_height;
  386.     aglUpdateContext(p_vout->p_sys->agl_ctx);
  387. }
  388. //default window event handler
  389. static pascal OSStatus WindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
  390. {
  391.     OSStatus result = noErr;
  392.     UInt32 class = GetEventClass (event);
  393.     UInt32 kind = GetEventKind (event);
  394.     vout_thread_t *p_vout = (vout_thread_t *)userData;
  395.     result = CallNextEventHandler(nextHandler, event);
  396.     if(class == kEventClassCommand)
  397.     {
  398.         HICommand theHICommand;
  399.         GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof( HICommand ), NULL, &theHICommand );
  400.  
  401.         switch ( theHICommand.commandID )
  402.         {
  403.             default:
  404.                 result = eventNotHandledErr;
  405.         }
  406.     }
  407.     else if(class == kEventClassWindow)
  408.     {
  409.         WindowRef     window;
  410.         Rect          rectPort = {0,0,0,0};
  411.  
  412.         GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window);
  413.         if(window)
  414.         {
  415.             GetPortBounds(GetWindowPort(window), &rectPort);
  416.         }
  417.         switch (kind)
  418.         {
  419.             case kEventWindowClosed:
  420.             case kEventWindowZoomed:
  421.             case kEventWindowBoundsChanged:
  422.                 break;
  423.  
  424.             default:
  425.                 result = eventNotHandledErr;
  426.         }
  427.     }
  428.     else if(class == kEventClassMouse)
  429.     {
  430.         switch (kind)
  431.         {
  432.             case kEventMouseDown:
  433.             {
  434.                 UInt16     button;
  435.  
  436.                 GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
  437.                 switch (button)
  438.                 {
  439.                     case kEventMouseButtonPrimary:
  440.                     {
  441.                         vlc_value_t val;
  442.                         var_Get( p_vout, "mouse-button-down", &val );
  443.                         val.i_int |= 1;
  444.                         var_Set( p_vout, "mouse-button-down", val );
  445.                         break;
  446.                     }
  447.                     case kEventMouseButtonSecondary:
  448.                     {
  449.                         vlc_value_t val;
  450.                         var_Get( p_vout, "mouse-button-down", &val );
  451.                         val.i_int |= 2;
  452.                         var_Set( p_vout, "mouse-button-down", val );
  453.                         break;
  454.                     }
  455.                     case kEventMouseButtonTertiary:
  456.                     {
  457.                         vlc_value_t val;
  458.                         var_Get( p_vout, "mouse-button-down", &val );
  459.                         val.i_int |= 4;
  460.                         var_Set( p_vout, "mouse-button-down", val );
  461.                         break;
  462.                     }
  463.                     default:
  464.                         result = eventNotHandledErr;
  465.                 }
  466.                 break;
  467.             }
  468.             case kEventMouseUp:
  469.             {
  470.                 UInt16     button;
  471.  
  472.                 GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
  473.                 switch (button)
  474.                 {
  475.                     case kEventMouseButtonPrimary:
  476.                     {
  477.                         UInt32 clickCount = 0;
  478.                         GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL, sizeof(clickCount), NULL, &clickCount);
  479.                         if( clickCount > 1 )
  480.                         {
  481.                             vlc_value_t val;
  482.                             val.b_bool = false;
  483.                             var_Set((vout_thread_t *) p_vout->p_parent, "fullscreen", val);
  484.                         }
  485.                         else
  486.                         {
  487.                             vlc_value_t val;
  488.                             var_SetBool( p_vout, "mouse-clicked", true );
  489.                             var_Get( p_vout, "mouse-button-down", &val );
  490.                             val.i_int &= ~1;
  491.                             var_Set( p_vout, "mouse-button-down", val );
  492.                         }
  493.                         break;
  494.                     }
  495.                     case kEventMouseButtonSecondary:
  496.                     {
  497.                         vlc_value_t val;
  498.                         var_Get( p_vout, "mouse-button-down", &val );
  499.                         val.i_int &= ~2;
  500.                         var_Set( p_vout, "mouse-button-down", val );
  501.                         break;
  502.                     }
  503.                     case kEventMouseButtonTertiary:
  504.                     {
  505.                         vlc_value_t val;
  506.                         var_Get( p_vout, "mouse-button-down", &val );
  507.                         val.i_int &= ~2;
  508.                         var_Set( p_vout, "mouse-button-down", val );
  509.                         break;
  510.                     }
  511.                     default:
  512.                         result = eventNotHandledErr;
  513.                 }
  514.                 break;
  515.             }
  516.             case kEventMouseMoved:
  517.             {
  518.                 Point ml;
  519.                 vlc_value_t val;
  520.                 unsigned int i_x, i_y;
  521.                 unsigned int i_height = p_vout->p_sys->i_height;
  522.                 unsigned int i_width  = p_vout->p_sys->i_width;
  523.                 vout_PlacePicture(p_vout, i_width, i_height, &i_x, &i_y, &i_width, &i_height);
  524.                 GetEventParameter(event, kEventParamWindowMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &ml);
  525.  
  526.                 val.i_int = ( ((int)ml.h) - i_x ) *
  527.                             p_vout->render.i_width / i_width;
  528.                 var_Set( p_vout, "mouse-x", val );
  529.                 val.i_int = ( ((int)ml.v) - i_y ) *
  530.                             p_vout->render.i_height / i_height;
  531.                 var_Set( p_vout, "mouse-y", val );
  532.                 val.b_bool = true;
  533.                 var_Set( p_vout, "mouse-moved", val );
  534.                 break;
  535.             }
  536.  
  537.             default:
  538.                 result = eventNotHandledErr;
  539.         }
  540.     }
  541.     else if(class == kEventClassTextInput)
  542.     {
  543.         switch (kind)
  544.         {
  545.             case kEventTextInputUnicodeForKeyEvent:
  546.             {
  547.                 break;
  548.             }
  549.             default:
  550.                 result = eventNotHandledErr;
  551.         }
  552.     }
  553.     else if(class == kEventClassVLCPlugin)
  554.     {
  555.         switch (kind)
  556.         {
  557.             case kEventVLCPluginShowFullscreen:
  558.                 ShowWindow (p_vout->p_sys->theWindow);
  559.                 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
  560.                 //CGDisplayHideCursor(kCGDirectMainDisplay);
  561.                 break;
  562.             case kEventVLCPluginHideFullscreen:
  563.                 HideWindow (p_vout->p_sys->theWindow);
  564.                 SetSystemUIMode( kUIModeNormal, 0);
  565.                 CGDisplayShowCursor(kCGDirectMainDisplay);
  566.                 break;
  567.             default:
  568.                 result = eventNotHandledErr;
  569.                 break;
  570.         }
  571.     }
  572.     return result;
  573. }
  574. int aglLock( vout_thread_t * p_vout )
  575. {
  576. #ifdef __ppc__
  577.     /*
  578.      * before 10.4, we set the AGL context as current and
  579.      * then we retrieve and use the matching CGL context
  580.      */
  581.     aglSetCurrentContext(p_vout->p_sys->agl_ctx);
  582.     return kCGLNoError != CGLLockContext( CGLGetCurrentContext() );
  583. #else
  584.     /* since 10.4, this is the safe way to get the underlying CGL context */
  585.     CGLContextObj cglContext;
  586.     if( aglGetCGLContext(p_vout->p_sys->agl_ctx, (void**)&cglContext) )
  587.     {
  588.         if( kCGLNoError == CGLLockContext( cglContext ) )
  589.         {
  590.             aglSetCurrentContext(p_vout->p_sys->agl_ctx);
  591.             return 0;
  592.         }
  593.     }
  594.     return 1;
  595. #endif
  596. }
  597. void aglUnlock( vout_thread_t * p_vout )
  598. {
  599. #ifdef __ppc__
  600.     /*
  601.      * before 10.4, we assume that the AGL context is current.
  602.      * therefore, we use the current CGL context
  603.      */
  604.     CGLUnlockContext( CGLGetCurrentContext() );
  605. #else
  606.     /* since 10.4, this is the safe way to get the underlying CGL context */
  607.     CGLContextObj cglContext;
  608.     if( aglGetCGLContext(p_vout->p_sys->agl_ctx, (void**)&cglContext) )
  609.     {
  610.         CGLUnlockContext( cglContext );
  611.     }
  612. #endif
  613. }
  614. #endif