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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * mac.c: Screen capture module for the Mac.
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: x11.c 8290 2004-07-26 20:29:24Z gbazin $
  6.  *
  7.  * Authors: Derk-Jan Hartman <hartman at videolan dot org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>
  27. #include <vlc/vlc.h>
  28. #include <vlc/input.h>
  29. #include <Carbon/Carbon.h>
  30. #include <ApplicationServices/ApplicationServices.h>
  31. typedef int CGSConnectionRef;
  32. extern CGError CGSNewConnection(void* unknown, CGSConnectionRef* newConnection);
  33. extern CGError CGSReleaseConnection(CGSConnectionRef connection);
  34. #include "screen.h"
  35. struct screen_data_t
  36. {
  37.     RGBColor          oldForeColor, oldBackColor;
  38.     PenState          oldState;
  39.     CGDirectDisplayID displayID;
  40.     CGSConnectionRef  gConnection;
  41.     GDHandle          gMainDevice;
  42.     char              gDeviceState;
  43.     PixMapHandle      gDevicePix;
  44.     GWorldPtr         LocalBufferGW;
  45.     PixMapHandle      LocalBufferPix;
  46. };
  47. int screen_InitCapture( demux_t *p_demux )
  48. {
  49.     demux_sys_t   *p_sys = p_demux->p_sys;
  50.     screen_data_t *p_data;
  51.     int            i_chroma, i_bbp, i_offset;
  52.     i_chroma = i_bbp = i_offset = 0;
  53.     p_sys->p_data = p_data =
  54.         (screen_data_t *)malloc( sizeof( screen_data_t ) );
  55.     p_data->gConnection = NULL;
  56.     p_data->gMainDevice = NULL;
  57.     p_data->gDevicePix = NULL;
  58.     p_data->gDeviceState = NULL;
  59.     p_data->LocalBufferGW = NULL;
  60.     p_data->LocalBufferPix = NULL;
  61.     p_data->displayID = CGMainDisplayID();
  62.     (void) GetMainDevice();
  63.     if( CGDisplaySamplesPerPixel(p_data->displayID) != 3 )
  64.     {
  65.         msg_Err( p_demux, "screenformat not supported" );
  66.     } 
  67.     
  68.     switch( CGDisplaySamplesPerPixel(p_data->displayID) * CGDisplayBitsPerSample(p_data->displayID) )
  69.     {
  70.     /* TODO figure out 256 colors (who uses it anyways) */
  71.     case 15: /* TODO this is not RV16, but BGR16 */
  72.         i_chroma = VLC_FOURCC('R','V','1','6');
  73.         i_bbp = 16;
  74.         i_offset = 8;
  75.         break;
  76.     case 24:
  77.     case 32:
  78.         i_chroma = VLC_FOURCC('R','V','3','2');
  79.         i_bbp = 32;
  80.         i_offset = 4;
  81.         break;
  82.     default:
  83.         msg_Err( p_demux, "unknown screen depth: %d", CGDisplaySamplesPerPixel(p_data->displayID) * CGDisplayBitsPerSample(p_data->displayID) );
  84.         return VLC_EGENERIC;
  85.     }
  86.     GetBackColor(&p_data->oldBackColor);
  87.     GetPenState(&p_data->oldState);
  88.     ForeColor(blackColor);
  89.     BackColor(whiteColor);
  90.     
  91.     p_data->gMainDevice = GetMainDevice();
  92.     p_data->gDeviceState = HGetState((Handle)p_data->gMainDevice);
  93.     HLock((Handle)p_data->gMainDevice);
  94.     p_data->gDevicePix = (**p_data->gMainDevice).gdPMap;
  95.     NewGWorld(&p_data->LocalBufferGW, (**p_data->gDevicePix).pixelSize, &(**p_data->gDevicePix).bounds, (**p_data->gDevicePix).pmTable, NULL, 0);
  96.     p_data->LocalBufferPix = GetGWorldPixMap(p_data->LocalBufferGW);
  97.     LockPixels(p_data->LocalBufferPix);
  98.     
  99.     es_format_Init( &p_sys->fmt, VIDEO_ES, i_chroma );
  100.     p_sys->fmt.video.i_width  = CGDisplayPixelsWide(p_data->displayID) + i_offset;
  101.     p_sys->fmt.video.i_visible_width  = CGDisplayPixelsWide(p_data->displayID);
  102.     p_sys->fmt.video.i_height = CGDisplayPixelsHigh(p_data->displayID);
  103.     p_sys->fmt.video.i_bits_per_pixel = i_bbp;
  104.     GetForeColor(&p_data->oldForeColor);
  105.     HSetState( (Handle)p_data->gMainDevice, p_data->gDeviceState );
  106.     SetPenState( &p_data->oldState);
  107.     RGBForeColor( &p_data->oldForeColor );
  108.     RGBBackColor( &p_data->oldBackColor );
  109.     return VLC_SUCCESS;
  110. }
  111. int screen_CloseCapture( demux_t *p_demux )
  112. {
  113.     screen_data_t *p_data = (screen_data_t *)p_demux->p_sys->p_data;
  114.     if(p_data->LocalBufferPix) UnlockPixels(p_data->LocalBufferPix); p_data->LocalBufferPix = NULL;
  115.     if(p_data->LocalBufferGW) DisposeGWorld(p_data->LocalBufferGW); p_data->LocalBufferGW = NULL;
  116.     return VLC_SUCCESS;
  117. }
  118. block_t *screen_Capture( demux_t *p_demux )
  119. {
  120.     demux_sys_t *p_sys = p_demux->p_sys;
  121.     screen_data_t *p_data = (screen_data_t *)p_sys->p_data;
  122.     block_t *p_block;
  123.     int i_size;
  124.  
  125.     i_size = p_sys->fmt.video.i_height * p_sys->fmt.video.i_width * 32 / 8; 
  126.     if( !( p_block = block_New( p_demux, i_size ) ) )
  127.     {
  128.         msg_Warn( p_demux, "cannot get block" );
  129.         return 0;
  130.     }
  131.     GetForeColor(&p_data->oldForeColor);
  132.     GetBackColor(&p_data->oldBackColor);
  133.     GetPenState(&p_data->oldState);
  134.     ForeColor(blackColor);
  135.     BackColor(whiteColor);
  136.     assert(CGSNewConnection(NULL, &p_data->gConnection) == kCGErrorSuccess);
  137.     p_data->gMainDevice = GetMainDevice();
  138.     p_data->gDeviceState = HGetState((Handle)p_data->gMainDevice);
  139.     HLock((Handle)p_data->gMainDevice);
  140.     p_data->gDevicePix = (**p_data->gMainDevice).gdPMap;
  141.     CopyBits(( BitMap*)*p_data->gDevicePix, (BitMap*)*p_data->LocalBufferPix,
  142.              &(**p_data->gDevicePix).bounds, &(**p_data->gDevicePix).bounds,
  143.              srcCopy, NULL );
  144.     HSetState( (Handle)p_data->gMainDevice, p_data->gDeviceState );
  145.     SetPenState( &p_data->oldState );
  146.     RGBForeColor( &p_data->oldForeColor );
  147.     RGBBackColor( &p_data->oldBackColor );
  148.     assert(CGSReleaseConnection(p_data->gConnection) == kCGErrorSuccess);
  149.     memcpy( p_block->p_buffer, (**p_data->LocalBufferPix).baseAddr, i_size );
  150.     return p_block;
  151. }