Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

mac.c

00001 /*****************************************************************************
00002  * mac.c: Screen capture module for the Mac.
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: x11.c 8290 2004-07-26 20:29:24Z gbazin $
00006  *
00007  * Authors: Derk-Jan Hartman <hartman at videolan dot org>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <stdlib.h>
00028 
00029 #include <vlc/vlc.h>
00030 #include <vlc/input.h>
00031 
00032 #include <Carbon/Carbon.h>
00033 #include <ApplicationServices/ApplicationServices.h>
00034 
00035 typedef int CGSConnectionRef;
00036 extern CGError CGSNewConnection(void* unknown, CGSConnectionRef* newConnection);
00037 extern CGError CGSReleaseConnection(CGSConnectionRef connection);
00038 
00039 #include "screen.h"
00040 
00041 struct screen_data_t
00042 {
00043     RGBColor          oldForeColor, oldBackColor;
00044     PenState          oldState;
00045     CGDirectDisplayID displayID;
00046     CGSConnectionRef  gConnection;
00047     GDHandle          gMainDevice;
00048     char              gDeviceState;
00049     PixMapHandle      gDevicePix;
00050     GWorldPtr         LocalBufferGW;
00051     PixMapHandle      LocalBufferPix;
00052 };
00053 
00054 int screen_InitCapture( demux_t *p_demux )
00055 {
00056     demux_sys_t   *p_sys = p_demux->p_sys;
00057     screen_data_t *p_data;
00058     int            i_chroma, i_bbp, i_offset;
00059 
00060     i_chroma = i_bbp = i_offset = 0;
00061 
00062     p_sys->p_data = p_data =
00063         (screen_data_t *)malloc( sizeof( screen_data_t ) );
00064 
00065     p_data->gConnection = NULL;
00066     p_data->gMainDevice = NULL;
00067     p_data->gDevicePix = NULL;
00068     p_data->gDeviceState = NULL;
00069     p_data->LocalBufferGW = NULL;
00070     p_data->LocalBufferPix = NULL;
00071 
00072     p_data->displayID = CGMainDisplayID();
00073     (void) GetMainDevice();
00074 
00075     if( CGDisplaySamplesPerPixel(p_data->displayID) != 3 )
00076     {
00077         msg_Err( p_demux, "screenformat not supported" );
00078     } 
00079     
00080     switch( CGDisplaySamplesPerPixel(p_data->displayID) * CGDisplayBitsPerSample(p_data->displayID) )
00081     {
00082     /* TODO figure out 256 colors (who uses it anyways) */
00083     case 15: /* TODO this is not RV16, but BGR16 */
00084         i_chroma = VLC_FOURCC('R','V','1','6');
00085         i_bbp = 16;
00086         i_offset = 8;
00087         break;
00088     case 24:
00089     case 32:
00090         i_chroma = VLC_FOURCC('R','V','3','2');
00091         i_bbp = 32;
00092         i_offset = 4;
00093         break;
00094     default:
00095         msg_Err( p_demux, "unknown screen depth: %d", CGDisplaySamplesPerPixel(p_data->displayID) * CGDisplayBitsPerSample(p_data->displayID) );
00096         return VLC_EGENERIC;
00097     }
00098 
00099     GetBackColor(&p_data->oldBackColor);
00100     GetPenState(&p_data->oldState);
00101     ForeColor(blackColor);
00102     BackColor(whiteColor);
00103     
00104     p_data->gMainDevice = GetMainDevice();
00105     p_data->gDeviceState = HGetState((Handle)p_data->gMainDevice);
00106     HLock((Handle)p_data->gMainDevice);
00107     p_data->gDevicePix = (**p_data->gMainDevice).gdPMap;
00108 
00109     NewGWorld(&p_data->LocalBufferGW, (**p_data->gDevicePix).pixelSize, &(**p_data->gDevicePix).bounds, (**p_data->gDevicePix).pmTable, NULL, 0);
00110     p_data->LocalBufferPix = GetGWorldPixMap(p_data->LocalBufferGW);
00111     LockPixels(p_data->LocalBufferPix);
00112     
00113     es_format_Init( &p_sys->fmt, VIDEO_ES, i_chroma );
00114     p_sys->fmt.video.i_width  = CGDisplayPixelsWide(p_data->displayID) + i_offset;
00115     p_sys->fmt.video.i_visible_width  = CGDisplayPixelsWide(p_data->displayID);
00116     p_sys->fmt.video.i_height = CGDisplayPixelsHigh(p_data->displayID);
00117     p_sys->fmt.video.i_bits_per_pixel = i_bbp;
00118 
00119     GetForeColor(&p_data->oldForeColor);
00120 
00121     HSetState( (Handle)p_data->gMainDevice, p_data->gDeviceState );
00122     SetPenState( &p_data->oldState);
00123     RGBForeColor( &p_data->oldForeColor );
00124     RGBBackColor( &p_data->oldBackColor );
00125 
00126     return VLC_SUCCESS;
00127 }
00128 
00129 int screen_CloseCapture( demux_t *p_demux )
00130 {
00131     screen_data_t *p_data = (screen_data_t *)p_demux->p_sys->p_data;
00132 
00133     if(p_data->LocalBufferPix) UnlockPixels(p_data->LocalBufferPix); p_data->LocalBufferPix = NULL;
00134     if(p_data->LocalBufferGW) DisposeGWorld(p_data->LocalBufferGW); p_data->LocalBufferGW = NULL;
00135 
00136     return VLC_SUCCESS;
00137 }
00138 
00139 block_t *screen_Capture( demux_t *p_demux )
00140 {
00141     demux_sys_t *p_sys = p_demux->p_sys;
00142     screen_data_t *p_data = (screen_data_t *)p_sys->p_data;
00143     block_t *p_block;
00144     int i_size;
00145  
00146     i_size = p_sys->fmt.video.i_height * p_sys->fmt.video.i_width * 32 / 8; 
00147 
00148     if( !( p_block = block_New( p_demux, i_size ) ) )
00149     {
00150         msg_Warn( p_demux, "cannot get block" );
00151         return 0;
00152     }
00153 
00154     GetForeColor(&p_data->oldForeColor);
00155     GetBackColor(&p_data->oldBackColor);
00156     GetPenState(&p_data->oldState);
00157     ForeColor(blackColor);
00158     BackColor(whiteColor);
00159 
00160     assert(CGSNewConnection(NULL, &p_data->gConnection) == kCGErrorSuccess);
00161     p_data->gMainDevice = GetMainDevice();
00162     p_data->gDeviceState = HGetState((Handle)p_data->gMainDevice);
00163     HLock((Handle)p_data->gMainDevice);
00164     p_data->gDevicePix = (**p_data->gMainDevice).gdPMap;
00165 
00166     CopyBits(( BitMap*)*p_data->gDevicePix, (BitMap*)*p_data->LocalBufferPix,
00167              &(**p_data->gDevicePix).bounds, &(**p_data->gDevicePix).bounds,
00168              srcCopy, NULL );
00169 
00170     HSetState( (Handle)p_data->gMainDevice, p_data->gDeviceState );
00171     SetPenState( &p_data->oldState );
00172     RGBForeColor( &p_data->oldForeColor );
00173     RGBBackColor( &p_data->oldBackColor );
00174 
00175     assert(CGSReleaseConnection(p_data->gConnection) == kCGErrorSuccess);
00176     memcpy( p_block->p_buffer, (**p_data->LocalBufferPix).baseAddr, i_size );
00177 
00178     return p_block;
00179 }
00180 

Generated on Tue Dec 20 10:14:26 2005 for vlc-0.8.4a by  doxygen 1.4.2