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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mac.c: Screen capture module for the Mac.
  3.  *****************************************************************************
  4.  * Copyright (C) 2004, 2008 the VideoLAN team
  5.  * $Id: 5b14fdd610773963176644ee76abcd8d5e1d8590 $
  6.  *
  7.  * Authors: Derk-Jan Hartman <hartman at videolan dot org>
  8.  *          arai <arai_a@mac.com>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # import "config.h"
  29. #endif
  30. #import <vlc_common.h>
  31. #import <ApplicationServices/ApplicationServices.h>
  32. #import <OpenGL/OpenGL.h>
  33. #import <OpenGL/gl.h>
  34. #import <stdlib.h>
  35. typedef int CGSConnectionRef;
  36. extern CGError CGSNewConnection( void *, CGSConnectionRef * );
  37. extern CGError CGSReleaseConnection( CGSConnectionRef );
  38. extern CGError CGSGetGlobalCursorDataSize( CGSConnectionRef, int * );
  39. extern CGError CGSGetGlobalCursorData( CGSConnectionRef, unsigned char *,
  40.                                        int *, int *, CGRect *, CGPoint *,
  41.                                        int *, int *, int * );
  42. extern CGError CGSGetCurrentCursorLocation( CGSConnectionRef, CGPoint * );
  43. #import "screen.h"
  44. struct screen_data_t
  45. {
  46.   CGLContextObj screen;
  47.   
  48.   CGLContextObj scaled;
  49.   char *scaled_image;
  50.   
  51.   GLuint texture;
  52.   char *texture_image;
  53.   
  54.   GLuint cursor_texture;
  55.   
  56.   int left;
  57.   int top;
  58.   int src_width;
  59.   int src_height;
  60.   
  61.   int dest_width;
  62.   int dest_height;
  63.   
  64.   int screen_width;
  65.   int screen_height;
  66.   
  67.   CGSConnectionRef connection;
  68. };
  69. int screen_InitCapture( demux_t *p_demux )
  70. {
  71.     demux_sys_t   *p_sys = p_demux->p_sys;
  72.     screen_data_t *p_data;
  73.     CGLPixelFormatAttribute attribs[4];
  74.     CGLPixelFormatObj pix;
  75.     GLint npix;
  76.     GLint viewport[4];
  77.     
  78.     p_sys->p_data = p_data =
  79.         ( screen_data_t * )malloc( sizeof( screen_data_t ) );
  80.     
  81.     attribs[0] = kCGLPFAFullScreen;
  82.     attribs[1] = kCGLPFADisplayMask;
  83.     attribs[2] = CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() );
  84.     attribs[3] = 0;
  85.     
  86.     CGLChoosePixelFormat( attribs, &pix, &npix );
  87.     CGLCreateContext( pix, NULL, &( p_data->screen ) );
  88.     CGLDestroyPixelFormat( pix );
  89.     CGLSetCurrentContext( p_data->screen );
  90.     CGLSetFullScreen( p_data->screen );
  91.     
  92.     glGetIntegerv( GL_VIEWPORT, viewport );
  93.     
  94.     p_data->screen_width = viewport[2];
  95.     p_data->screen_height = viewport[3];
  96.     
  97.     p_data->left = p_sys->i_left;
  98.     p_data->top = p_sys->i_top;
  99.     p_data->src_width = var_CreateGetInteger( p_demux, "screen-width" );
  100.     p_data->src_height = var_CreateGetInteger( p_demux, "screen-height" );
  101.     if (p_data->src_width <= 0 || p_data->src_height <= 0) {
  102.       p_data->src_width = p_data->screen_width;
  103.       p_data->src_height = p_data->screen_height;
  104.     }
  105.     p_data->dest_width = p_data->src_width;
  106.     p_data->dest_height = p_data->src_height;
  107.     
  108.     attribs [0] = kCGLPFAOffScreen;
  109.     attribs [1] = kCGLPFAColorSize;
  110.     attribs [2] = 32;
  111.     attribs [3] = 0;
  112.     
  113.     CGLChoosePixelFormat( attribs, &pix, &npix );
  114.     CGLCreateContext( pix, NULL, &( p_data->scaled ) );
  115.     CGLDestroyPixelFormat( pix );
  116.     CGLSetCurrentContext( p_data->scaled );
  117.     p_data->scaled_image = ( char * )malloc( p_data->dest_width
  118.                                           * p_data->dest_height * 4 );
  119.     CGLSetOffScreen( p_data->scaled, p_data->dest_width, p_data->dest_height,
  120.                      p_data->dest_width * 4, p_data->scaled_image );
  121.     
  122.     es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_FOURCC( 'R','V','3','2' ) );
  123.     
  124.     /* p_sys->fmt.video.i_* must set to screen size, not subscreen size */
  125.     p_sys->fmt.video.i_width = p_data->screen_width;
  126.     p_sys->fmt.video.i_visible_width = p_data->screen_width;
  127.     p_sys->fmt.video.i_height = p_data->screen_height;
  128.     p_sys->fmt.video.i_bits_per_pixel = 32;
  129.     
  130.     glGenTextures( 1, &( p_data->texture ) );
  131.     glBindTexture( GL_TEXTURE_2D, p_data->texture );
  132.     
  133.     p_data->texture_image
  134.       = ( char * )malloc( p_data->src_width * p_data->src_height * 4 );
  135.     
  136.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  137.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  138.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  139.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  140.     glGenTextures( 1, &( p_data->cursor_texture ) );
  141.     glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture );
  142.     
  143.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  144.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  145.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  146.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  147.     
  148.     CGSNewConnection( NULL, &( p_data->connection ) );
  149.     
  150.     return VLC_SUCCESS;
  151. }
  152. int screen_CloseCapture( demux_t *p_demux )
  153. {
  154.     screen_data_t *p_data = ( screen_data_t * )p_demux->p_sys->p_data;
  155.     
  156.     CGSReleaseConnection( p_data->connection );
  157.     
  158.     CGLSetCurrentContext( NULL );
  159.     CGLClearDrawable( p_data->screen );
  160.     CGLDestroyContext( p_data->screen );
  161.     
  162.     return VLC_SUCCESS;
  163. }
  164. block_t *screen_Capture( demux_t *p_demux )
  165. {
  166.     demux_sys_t *p_sys = p_demux->p_sys;
  167.     screen_data_t *p_data = ( screen_data_t * )p_sys->p_data;
  168.     block_t *p_block;
  169.     int i_size;
  170.     
  171.     i_size = p_sys->fmt.video.i_height * p_sys->fmt.video.i_width * 4; 
  172.     
  173.     if( !( p_block = block_New( p_demux, i_size ) ) )
  174.     {
  175.         msg_Warn( p_demux, "cannot get block" );
  176.         return NULL;
  177.     }
  178.     
  179.     CGPoint cursor_pos;
  180.     CGError cursor_result;
  181.     
  182.     cursor_pos.x = 0;
  183.     cursor_pos.y = 0;
  184.     
  185.     cursor_result
  186.       = CGSGetCurrentCursorLocation( p_data->connection, &cursor_pos );
  187.     
  188.     if( p_sys->b_follow_mouse
  189.         && cursor_result == kCGErrorSuccess )
  190.     {
  191.         FollowMouse( p_sys, cursor_pos.x, cursor_pos.y );
  192.         p_data->left = p_sys->i_left;
  193.         p_data->top = p_sys->i_top;
  194.     }
  195.     
  196.     CGLSetCurrentContext( p_data->screen );
  197.     glReadPixels( p_data->left,
  198.                   p_data->screen_height - p_data->top - p_data->src_height,
  199.                   p_data->src_width,
  200.                   p_data->src_height,
  201.                   GL_RGBA, GL_UNSIGNED_BYTE,
  202.                   p_data->texture_image );
  203.     
  204.     CGLSetCurrentContext( p_data->scaled );
  205.     glEnable( GL_TEXTURE_2D );
  206.     glBindTexture( GL_TEXTURE_2D, p_data->texture );
  207.     glTexImage2D( GL_TEXTURE_2D, 0,
  208.                   GL_RGBA8, p_data->src_width, p_data->src_height, 0,
  209.                   GL_RGBA, GL_UNSIGNED_BYTE, p_data->texture_image );
  210.     
  211.     glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
  212.     glClear( GL_COLOR_BUFFER_BIT );
  213.     glColor3f( 1.0f, 1.0f, 1.0f );
  214.     glEnable( GL_TEXTURE_2D );
  215.     glBindTexture( GL_TEXTURE_2D, p_data->texture );
  216.     glBegin( GL_POLYGON );
  217.     glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, -1.0 );
  218.     glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, -1.0 );
  219.     glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, 1.0 );
  220.     glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, 1.0 );
  221.     glEnd();
  222.     glDisable( GL_TEXTURE_2D );
  223.     
  224.     int size;
  225.     int tmp1, tmp2, tmp3, tmp4;
  226.     unsigned char *cursor_image;
  227.     CGRect cursor_rect;
  228.     CGPoint cursor_hot;
  229.     
  230.     if( cursor_result == kCGErrorSuccess
  231.         && CGSGetGlobalCursorDataSize( p_data->connection, &size )
  232.         == kCGErrorSuccess )
  233.     {
  234.         cursor_image = ( unsigned char* )malloc( size );
  235.         if( CGSGetGlobalCursorData( p_data->connection,
  236.                                     cursor_image, &size,
  237.                                     &tmp1,
  238.                                     &cursor_rect, &cursor_hot,
  239.                                     &tmp2, &tmp3, &tmp4 )
  240.             == kCGErrorSuccess )
  241.         {
  242.             glEnable( GL_TEXTURE_2D );
  243.             glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture );
  244.             glTexImage2D( GL_TEXTURE_2D, 0,
  245.                           GL_RGBA8,
  246.                           ( int )( cursor_rect.size.width ),
  247.                           ( int )( cursor_rect.size.height ), 0,
  248.                           GL_RGBA, GL_UNSIGNED_BYTE,
  249.                           ( char * )cursor_image );
  250.             
  251.             cursor_rect.origin.x = cursor_pos.x - p_data->left - cursor_hot.x;
  252.             cursor_rect.origin.y = cursor_pos.y - p_data->top - cursor_hot.y;
  253.             
  254.             cursor_rect.origin.x
  255.               = 2.0 * cursor_rect.origin.x / p_data->src_width - 1.0;
  256.             cursor_rect.origin.y
  257.               = 2.0 * cursor_rect.origin.y / p_data->src_height - 1.0;
  258.             cursor_rect.size.width
  259.               = 2.0 * cursor_rect.size.width / p_data->src_width;
  260.             cursor_rect.size.height
  261.               = 2.0 * cursor_rect.size.height / p_data->src_height;
  262.             
  263.             glColor3f( 1.0f, 1.0f, 1.0f );
  264.             glEnable( GL_TEXTURE_2D );
  265.             glEnable( GL_BLEND );
  266.             glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  267.             glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture );
  268.             glBegin( GL_POLYGON );
  269.             glTexCoord2f( 0.0, 0.0 ); glVertex2f( cursor_rect.origin.x,
  270.                                                   cursor_rect.origin.y );
  271.             glTexCoord2f( 1.0, 0.0 ); glVertex2f( cursor_rect.origin.x
  272.                                                   + cursor_rect.size.width,
  273.                                                   cursor_rect.origin.y );
  274.             glTexCoord2f( 1.0, 1.0 ); glVertex2f( cursor_rect.origin.x
  275.                                                   + cursor_rect.size.width,
  276.                                                   cursor_rect.origin.y
  277.                                                   + cursor_rect.size.height );
  278.             glTexCoord2f( 0.0, 1.0 ); glVertex2f( cursor_rect.origin.x,
  279.                                                   cursor_rect.origin.y
  280.                                                   + cursor_rect.size.height );
  281.             glEnd();
  282.             glDisable( GL_BLEND );
  283.             glDisable( GL_TEXTURE_2D );
  284.         }
  285.         free( cursor_image );
  286.     }
  287.     
  288.     glReadPixels( 0, 0, 
  289.                   p_data->dest_width,
  290.                   p_data->dest_height,
  291.                   GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
  292.                   p_block->p_buffer );
  293.     
  294.     return p_block;
  295. }