00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00083 case 15:
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