vout.m
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:15k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * vout.m: MacOS X video output module
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2003 VideoLAN
  5.  * $Id: vout.m 8608 2004-08-31 20:21:54Z hartman $
  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.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  * 
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  26.  *****************************************************************************/
  27. /*****************************************************************************
  28.  * Preamble
  29.  *****************************************************************************/
  30. #include <errno.h>                                                 /* ENOMEM */
  31. #include <stdlib.h>                                                /* free() */
  32. #include <string.h>                                            /* strerror() */
  33. /* BeginFullScreen, EndFullScreen */
  34. #include <QuickTime/QuickTime.h>
  35. #include <vlc_keys.h>
  36. #include "intf.h"
  37. #include "vout.h"
  38. /*****************************************************************************
  39.  * VLCWindow implementation
  40.  *****************************************************************************/
  41. @implementation VLCWindow
  42. - (id)initWithVout:(vout_thread_t *)_p_vout frame:(NSRect *)s_frame
  43. {
  44.     [self setReleasedWhenClosed: YES];
  45.     p_vout = _p_vout;
  46.     p_fullscreen_state = NULL;
  47.     i_time_mouse_last_moved = mdate();
  48.     NSScreen * o_screen;
  49.     vlc_bool_t b_main_screen;
  50.     /* Find out on which screen to open the window */
  51.     int i_device = var_GetInteger( p_vout, "video-device" );
  52.     if( i_device < 0 )
  53.     {
  54.          /* No preference specified. Use the main screen */
  55.         o_screen = [NSScreen mainScreen];
  56.         b_main_screen = 1;
  57.     }
  58.     else
  59.     {
  60.         NSArray *o_screens = [NSScreen screens];
  61.         
  62.         if( [o_screens count] < (unsigned) i_device )
  63.         {
  64.             o_screen = [NSScreen mainScreen];
  65.             b_main_screen = 1;
  66.         }
  67.         else
  68.         {
  69.             i_device--;
  70.             o_screen = [o_screens objectAtIndex: i_device];
  71.             var_SetInteger( p_vout, "macosx-vdev", i_device );
  72.             b_main_screen = ( i_device == 0 );
  73.         }
  74.     }
  75.     NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
  76.     if( p_vout->b_fullscreen )
  77.     {
  78.         NSRect screen_rect = [o_screen frame];
  79.         screen_rect.origin.x = screen_rect.origin.y = 0;
  80.         /* Creates a window with size: screen_rect on o_screen */
  81.         [self initWithContentRect: screen_rect
  82.               styleMask: NSBorderlessWindowMask
  83.               backing: NSBackingStoreBuffered
  84.               defer: YES screen: o_screen];
  85.         if( b_main_screen )
  86.         {
  87.             BeginFullScreen( &p_fullscreen_state, NULL, 0, 0,
  88.                              NULL, NULL, fullScreenAllowEvents );
  89.         }
  90.     }
  91.     else
  92.     {
  93.         unsigned int i_stylemask = NSTitledWindowMask |
  94.                                    NSMiniaturizableWindowMask |
  95.                                    NSClosableWindowMask |
  96.                                    NSResizableWindowMask;
  97.         NSRect s_rect;
  98.         if( !s_frame )
  99.         {
  100.             s_rect.size.width  = p_vout->i_window_width;
  101.             s_rect.size.height = p_vout->i_window_height;
  102.         }
  103.         else
  104.         {
  105.             s_rect = *s_frame;
  106.         }
  107.        
  108.         [self initWithContentRect: s_rect
  109.               styleMask: i_stylemask
  110.               backing: NSBackingStoreBuffered
  111.               defer: YES screen: o_screen];
  112.         [self setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
  113.         if( var_GetBool( p_vout, "video-on-top" ) )
  114.         {
  115.             [self setLevel: NSStatusWindowLevel];
  116.         }
  117.         if( !s_frame )
  118.         {
  119.             [self center];
  120.         }
  121.     }
  122.     [self updateTitle];
  123.     [self makeKeyAndOrderFront: nil];
  124.     /* We'll catch mouse events */
  125.     [self setAcceptsMouseMovedEvents: YES];
  126.     [self makeFirstResponder: self];
  127.     
  128.     [o_pool release];
  129.     return self;
  130. }
  131. - (void)close
  132. {
  133.     if( p_fullscreen_state )
  134.     {
  135.         EndFullScreen( p_fullscreen_state, NULL );
  136.     }
  137.     [super close];
  138. }
  139. - (void)setOnTop:(bool)b_on_top
  140. {
  141.     if( b_on_top )
  142.     {
  143.         [self setLevel: NSStatusWindowLevel];
  144.     }
  145.     else
  146.     {
  147.         [self setLevel: NSNormalWindowLevel];
  148.     }
  149. }
  150. - (void)hideMouse:(bool)b_hide
  151. {
  152.     BOOL b_inside;
  153.     NSPoint ml;
  154.     NSView *o_contents = [self contentView];
  155.     
  156.     ml = [self convertScreenToBase:[NSEvent mouseLocation]];
  157.     ml = [o_contents convertPoint:ml fromView:nil];
  158.     b_inside = [o_contents mouse: ml inRect: [o_contents bounds]];
  159.     
  160.     if( b_hide && b_inside )
  161.     {
  162.         [NSCursor setHiddenUntilMouseMoves: YES];
  163.     }
  164.     else if( !b_hide )
  165.     {
  166.         [NSCursor setHiddenUntilMouseMoves: NO];
  167.     }
  168. }
  169. - (void)manage
  170. {
  171.     if( p_fullscreen_state )
  172.     {
  173.         if( mdate() - i_time_mouse_last_moved > 3000000 )
  174.         {
  175.             [self hideMouse: YES];
  176.         }
  177.     }
  178.     else
  179.     {
  180.         [self hideMouse: NO];
  181.     }
  182.     /* Disable screensaver */
  183.     UpdateSystemActivity( UsrActivity );
  184. }
  185. - (void)scaleWindowWithFactor: (float)factor
  186. {
  187.     NSSize newsize;
  188.     int i_corrected_height, i_corrected_width;
  189.     NSPoint topleftbase;
  190.     NSPoint topleftscreen;
  191.     
  192.     if ( !p_vout->b_fullscreen )
  193.     {
  194.         topleftbase.x = 0;
  195.         topleftbase.y = [self frame].size.height;
  196.         topleftscreen = [self convertBaseToScreen: topleftbase];
  197.         
  198.         if( p_vout->render.i_height * p_vout->render.i_aspect > 
  199.                         p_vout->render.i_width * VOUT_ASPECT_FACTOR )
  200.         {
  201.             i_corrected_width = p_vout->render.i_height * p_vout->render.i_aspect /
  202.                                             VOUT_ASPECT_FACTOR;
  203.             newsize.width = (int) ( i_corrected_width * factor );
  204.             newsize.height = (int) ( p_vout->render.i_height * factor );
  205.         }
  206.         else
  207.         {
  208.             i_corrected_height = p_vout->render.i_width * VOUT_ASPECT_FACTOR /
  209.                                             p_vout->render.i_aspect;
  210.             newsize.width = (int) ( p_vout->render.i_width * factor );
  211.             newsize.height = (int) ( i_corrected_height * factor );
  212.         }
  213.     
  214.         [self setContentSize: newsize];
  215.         
  216.         [self setFrameTopLeftPoint: topleftscreen];
  217.         p_vout->i_changes |= VOUT_SIZE_CHANGE;
  218.     }
  219. }
  220. - (void)toggleFloatOnTop
  221. {
  222.     vlc_value_t val;
  223.     if( var_Get( p_vout, "video-on-top", &val )>=0 && val.b_bool)
  224.     {
  225.         val.b_bool = VLC_FALSE;
  226.         var_Set( p_vout, "video-on-top", val );
  227.     }
  228.     else
  229.     {
  230.         val.b_bool = VLC_TRUE;
  231.         var_Set( p_vout, "video-on-top", val );
  232.     }
  233. }
  234. - (void)toggleFullscreen
  235. {
  236.     vlc_value_t val;
  237.     val.b_bool = !p_vout->b_fullscreen;
  238.     var_Set( p_vout, "fullscreen", val );
  239. }
  240. - (BOOL)isFullscreen
  241. {
  242.     return( p_vout->b_fullscreen );
  243. }
  244. - (BOOL)canBecomeKeyWindow
  245. {
  246.     return YES;
  247. }
  248. /* Sometimes crashes VLC....
  249. - (BOOL)performKeyEquivalent:(NSEvent *)o_event
  250. {
  251.         return [[VLCMain sharedInstance] hasDefinedShortcutKey:o_event];
  252. }*/
  253. - (void)keyDown:(NSEvent *)o_event
  254. {
  255.     unichar key = 0;
  256.     vlc_value_t val;
  257.     unsigned int i_pressed_modifiers = 0;
  258.     val.i_int = 0;
  259.     
  260.     i_pressed_modifiers = [o_event modifierFlags];
  261.     if( i_pressed_modifiers & NSShiftKeyMask )
  262.         val.i_int |= KEY_MODIFIER_SHIFT;
  263.     if( i_pressed_modifiers & NSControlKeyMask )
  264.         val.i_int |= KEY_MODIFIER_CTRL;
  265.     if( i_pressed_modifiers & NSAlternateKeyMask )
  266.         val.i_int |= KEY_MODIFIER_ALT;
  267.     if( i_pressed_modifiers & NSCommandKeyMask )
  268.         val.i_int |= KEY_MODIFIER_COMMAND;
  269.     key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
  270.     if( key )
  271.     {
  272.         /* Escape should always get you out of fullscreen */
  273.         if( key == (unichar) 0x1b )
  274.         {
  275.              if( [self isFullscreen] )
  276.              {
  277.                  [self toggleFullscreen];
  278.              }
  279.         }
  280.         else if ( key == ' ' )
  281.         {
  282.             vlc_value_t val;
  283.             val.i_int = config_GetInt( p_vout, "key-play-pause" );
  284.             var_Set( p_vout->p_vlc, "key-pressed", val );
  285.         }
  286.         else
  287.         {
  288.             val.i_int |= CocoaKeyToVLC( key );
  289.             var_Set( p_vout->p_vlc, "key-pressed", val );
  290.         }
  291.     }
  292.     else
  293.     {
  294.         [super keyDown: o_event];
  295.     }
  296. }
  297. - (void)updateTitle
  298. {
  299.     NSMutableString * o_title;
  300.     playlist_t * p_playlist;
  301.     
  302.     if( p_vout == NULL )
  303.     {
  304.         return;
  305.     }
  306.     
  307.     p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
  308.                                                 FIND_ANYWHERE );
  309.     
  310.     if( p_playlist == NULL )
  311.     {
  312.         return;
  313.     }
  314.     vlc_mutex_lock( &p_playlist->object_lock );
  315.     o_title = [NSMutableString stringWithUTF8String: 
  316.         p_playlist->pp_items[p_playlist->i_index]->input.psz_uri]; 
  317.     vlc_mutex_unlock( &p_playlist->object_lock );
  318.     vlc_object_release( p_playlist );
  319.     if( o_title != nil )
  320.     {
  321.         NSRange prefix_range = [o_title rangeOfString: @"file:"];
  322.         if( prefix_range.location != NSNotFound )
  323.         {
  324.             [o_title deleteCharactersInRange: prefix_range];
  325.         }
  326.         [self setTitleWithRepresentedFilename: o_title];
  327.     }
  328.     else
  329.     {
  330.         [self setTitle: [NSString stringWithCString: VOUT_TITLE]];
  331.     }
  332. }
  333. /* This is actually the same as VLCControls::stop. */
  334. - (BOOL)windowShouldClose:(id)sender
  335. {
  336.     playlist_t * p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
  337.                                                        FIND_ANYWHERE );
  338.     if( p_playlist == NULL )      
  339.     {
  340.         return NO;
  341.     }
  342.     playlist_Stop( p_playlist );
  343.     vlc_object_release( p_playlist );
  344.     /* The window will be closed by the intf later. */
  345.     return NO;
  346. }
  347. - (BOOL)acceptsFirstResponder
  348. {
  349.     return YES;
  350. }
  351. - (BOOL)becomeFirstResponder
  352. {
  353.     return YES;
  354. }
  355. - (BOOL)resignFirstResponder
  356. {
  357.     /* We need to stay the first responder or we'll miss some
  358.        events */
  359.     return NO;
  360. }
  361. - (void)mouseDown:(NSEvent *)o_event
  362. {
  363.     vlc_value_t val;
  364.     switch( [o_event type] )
  365.     {
  366.         case NSLeftMouseDown:
  367.         {
  368.             var_Get( p_vout, "mouse-button-down", &val );
  369.             val.i_int |= 1;
  370.             var_Set( p_vout, "mouse-button-down", val );
  371.         }
  372.         break;
  373.         default:
  374.             [super mouseDown: o_event];
  375.         break;
  376.     }
  377. }
  378. - (void)otherMouseDown:(NSEvent *)o_event
  379. {
  380.     vlc_value_t val;
  381.     switch( [o_event type] )
  382.     {
  383.         case NSOtherMouseDown:
  384.         {
  385.             var_Get( p_vout, "mouse-button-down", &val );
  386.             val.i_int |= 2;
  387.             var_Set( p_vout, "mouse-button-down", val );
  388.         }
  389.         break;
  390.         default:
  391.             [super mouseDown: o_event];
  392.         break;
  393.     }
  394. }
  395. - (void)rightMouseDown:(NSEvent *)o_event
  396. {
  397.     vlc_value_t val;
  398.     switch( [o_event type] )
  399.     {
  400.         case NSRightMouseDown:
  401.         {
  402.             var_Get( p_vout, "mouse-button-down", &val );
  403.             val.i_int |= 4;
  404.             var_Set( p_vout, "mouse-button-down", val );
  405.         }
  406.         break;
  407.         default:
  408.             [super mouseDown: o_event];
  409.         break;
  410.     }
  411. }
  412. - (void)mouseUp:(NSEvent *)o_event
  413. {
  414.     vlc_value_t val;
  415.     switch( [o_event type] )
  416.     {
  417.         case NSLeftMouseUp:
  418.         {
  419.             vlc_value_t b_val;
  420.             b_val.b_bool = VLC_TRUE;
  421.             var_Set( p_vout, "mouse-clicked", b_val );
  422.             var_Get( p_vout, "mouse-button-down", &val );
  423.             val.i_int &= ~1;
  424.             var_Set( p_vout, "mouse-button-down", val );
  425.         }
  426.         break;
  427.         default:
  428.             [super mouseUp: o_event];
  429.         break;
  430.     }
  431. }
  432. - (void)otherMouseUp:(NSEvent *)o_event
  433. {
  434.     vlc_value_t val;
  435.     switch( [o_event type] )
  436.     {
  437.         case NSOtherMouseUp:
  438.         {
  439.             var_Get( p_vout, "mouse-button-down", &val );
  440.             val.i_int &= ~2;
  441.             var_Set( p_vout, "mouse-button-down", val );
  442.         }
  443.         break;
  444.         default:
  445.             [super mouseUp: o_event];
  446.         break;
  447.     }
  448. }
  449. - (void)rightMouseUp:(NSEvent *)o_event
  450. {
  451.     vlc_value_t val;
  452.     switch( [o_event type] )
  453.     {
  454.         case NSRightMouseUp:
  455.         {
  456.             var_Get( p_vout, "mouse-button-down", &val );
  457.             val.i_int &= ~4;
  458.             var_Set( p_vout, "mouse-button-down", val );
  459.         }
  460.         break;
  461.         default:
  462.             [super mouseUp: o_event];
  463.         break;
  464.     }
  465. }
  466. - (void)mouseDragged:(NSEvent *)o_event
  467. {
  468.     [self mouseMoved: o_event];
  469. }
  470. - (void)otherMouseDragged:(NSEvent *)o_event
  471. {
  472.     [self mouseMoved: o_event];
  473. }
  474. - (void)rightMouseDragged:(NSEvent *)o_event
  475. {
  476.     [self mouseMoved: o_event];
  477. }
  478. - (void)mouseMoved:(NSEvent *)o_event
  479. {   
  480.     NSPoint ml;
  481.     NSRect s_rect;
  482.     BOOL b_inside;
  483.     NSView * o_view;
  484.     i_time_mouse_last_moved = mdate();
  485.     o_view = [self contentView];
  486.     s_rect = [o_view bounds];
  487.     ml = [o_view convertPoint: [o_event locationInWindow] fromView: nil];
  488.     b_inside = [o_view mouse: ml inRect: s_rect];
  489.     if( b_inside )
  490.     {
  491.         vlc_value_t val;
  492.         int i_width, i_height, i_x, i_y;
  493.         vout_PlacePicture( p_vout, (unsigned int)s_rect.size.width,
  494.                                    (unsigned int)s_rect.size.height,
  495.                                    &i_x, &i_y, &i_width, &i_height );
  496.         val.i_int = ( ((int)ml.x) - i_x ) *  
  497.                     p_vout->render.i_width / i_width;
  498.         var_Set( p_vout, "mouse-x", val );
  499.         if( [[o_view className] isEqualToString: @"VLCGLView"] )
  500.         {
  501.             val.i_int = ( ((int)(s_rect.size.height - ml.y)) - i_y ) *
  502.                         p_vout->render.i_height / i_height;
  503.         }
  504.         else
  505.         {
  506.             val.i_int = ( ((int)ml.y) - i_y ) * 
  507.                         p_vout->render.i_height / i_height;
  508.         }
  509.         var_Set( p_vout, "mouse-y", val );
  510.             
  511.         val.b_bool = VLC_TRUE;
  512.         var_Set( p_vout, "mouse-moved", val ); 
  513.     }
  514.     [super mouseMoved: o_event];
  515. }
  516. @end