screenshot.c revision b03e4c067776790d7df85fc970fed19acae876ee
1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% SSSSS CCCC RRRR EEEEE EEEEE N N SSSSS H H OOO TTTTT % 7% SS C R R E E NN N SS H H O O T % 8% SSS C RRRR EEE EEE N N N SSS HHHHH O O T % 9% SS C R R E E N NN SS H H O O T % 10% SSSSS CCCC R R EEEEE EEEEE N N SSSSS H H OOO T % 11% % 12% % 13% Takes a screenshot from the monitor(s). % 14% % 15% Software Design % 16% Dirk Lemstra % 17% April 2014 % 18% % 19% % 20% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 28% Unless required by applicable law or agreed to in writing, software % 29% distributed under the License is distributed on an "AS IS" BASIS, % 30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31% See the License for the specific language governing permissions and % 32% limitations under the License. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% 37*/ 38 39/* 40 Include declarations. 41*/ 42#include "MagickCore/studio.h" 43#if defined(MAGICKCORE_WINGDI32_DELEGATE) 44# if defined(__CYGWIN__) 45# include <windows.h> 46# else 47 /* All MinGW needs ... */ 48# include "magick/nt-base-private.h" 49# include <wingdi.h> 50# endif 51#endif 52#include "MagickCore/blob.h" 53#include "MagickCore/blob-private.h" 54#include "MagickCore/cache.h" 55#include "MagickCore/exception.h" 56#include "MagickCore/exception-private.h" 57#include "MagickCore/image.h" 58#include "MagickCore/image-private.h" 59#include "MagickCore/list.h" 60#include "MagickCore/magick.h" 61#include "MagickCore/memory_.h" 62#include "MagickCore/module.h" 63#include "MagickCore/nt-feature.h" 64#include "MagickCore/option.h" 65#include "MagickCore/pixel-accessor.h" 66#include "MagickCore/quantum-private.h" 67#include "MagickCore/static.h" 68#include "MagickCore/string_.h" 69#include "MagickCore/token.h" 70#include "MagickCore/utility.h" 71#include "MagickCore/xwindow.h" 72#include "MagickCore/xwindow-private.h" 73 74/* 75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 76% % 77% % 78% % 79% R e a d S C R E E N S H O T I m a g e % 80% % 81% % 82% % 83%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 84% 85% ReadSCREENSHOTImage() Takes a screenshot from the monitor(s). 86% 87% The format of the ReadSCREENSHOTImage method is: 88% 89% Image *ReadXImage(const ImageInfo *image_info,ExceptionInfo *exception) 90% 91% A description of each parameter follows: 92% 93% o image_info: the image info. 94% 95% o exception: return any errors or warnings in this structure. 96% 97*/ 98static Image *ReadSCREENSHOTImage(const ImageInfo *image_info, 99 ExceptionInfo *exception) 100{ 101 Image 102 *image; 103 104 assert(image_info->signature == MagickSignature); 105 if (image_info->debug != MagickFalse) 106 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 107 image_info->filename); 108 assert(exception != (ExceptionInfo *) NULL); 109 assert(exception->signature == MagickSignature); 110 image=(Image *) NULL; 111#if defined(MAGICKCORE_WINGDI32_DELEGATE) 112 { 113 BITMAPINFO 114 bmi; 115 116 DISPLAY_DEVICE 117 device; 118 119 HBITMAP 120 bitmap, 121 bitmapOld; 122 123 HDC 124 bitmapDC, 125 hDC; 126 127 Image 128 *image, 129 *screen; 130 131 int 132 i; 133 134 register PixelPacket 135 *q; 136 137 register ssize_t 138 x; 139 140 RGBTRIPLE 141 *p; 142 143 ssize_t 144 y; 145 146 assert(image_info != (const ImageInfo *) NULL); 147 i=0; 148 device.cb = sizeof(device); 149 image=(Image *) NULL; 150 while(EnumDisplayDevices(NULL,i,&device,0) && ++i) 151 { 152 if ((device.StateFlags & DISPLAY_DEVICE_ACTIVE) != DISPLAY_DEVICE_ACTIVE) 153 continue; 154 155 hDC=CreateDC(device.DeviceName,device.DeviceName,NULL,NULL); 156 if (hDC == (HDC) NULL) 157 ThrowReaderException(CoderError,"UnableToCreateDC"); 158 159 screen=AcquireImage(image_info); 160 screen->columns=(size_t) GetDeviceCaps(hDC,HORZRES); 161 screen->rows=(size_t) GetDeviceCaps(hDC,VERTRES); 162 screen->storage_class=DirectClass; 163 164 if (image == (Image *) NULL) 165 image=screen; 166 else 167 AppendImageToList(&image,screen); 168 169 bitmapDC=CreateCompatibleDC(hDC); 170 if (bitmapDC == (HDC) NULL) 171 { 172 DeleteDC(hDC); 173 ThrowReaderException(CoderError,"UnableToCreateDC"); 174 } 175 (void) ResetMagickMemory(&bmi,0,sizeof(BITMAPINFO)); 176 bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 177 bmi.bmiHeader.biWidth=(LONG) screen->columns; 178 bmi.bmiHeader.biHeight=(-1)*(LONG) screen->rows; 179 bmi.bmiHeader.biPlanes=1; 180 bmi.bmiHeader.biBitCount=24; 181 bmi.bmiHeader.biCompression=BI_RGB; 182 bitmap=CreateDIBSection(hDC,&bmi,DIB_RGB_COLORS,(void **) &p,NULL,0); 183 if (bitmap == (HBITMAP) NULL) 184 { 185 DeleteDC(hDC); 186 DeleteDC(bitmapDC); 187 ThrowReaderException(CoderError,"UnableToCreateBitmap"); 188 } 189 bitmapOld=(HBITMAP) SelectObject(bitmapDC,bitmap); 190 if (bitmapOld == (HBITMAP) NULL) 191 { 192 DeleteDC(hDC); 193 DeleteDC(bitmapDC); 194 DeleteObject(bitmap); 195 ThrowReaderException(CoderError,"UnableToCreateBitmap"); 196 } 197 BitBlt(bitmapDC,0,0,(int) screen->columns,(int) screen->rows,hDC,0,0, 198 SRCCOPY); 199 (void) SelectObject(bitmapDC,bitmapOld); 200 201 for (y=0; y < (ssize_t) screen->rows; y++) 202 { 203 q=QueueAuthenticPixels(screen,0,y,screen->columns,1,exception); 204 if (q == (PixelPacket *) NULL) 205 break; 206 for (x=0; x < (ssize_t) screen->columns; x++) 207 { 208 SetPixelRed(q,ScaleCharToQuantum(p->rgbtRed)); 209 SetPixelGreen(q,ScaleCharToQuantum(p->rgbtGreen)); 210 SetPixelBlue(q,ScaleCharToQuantum(p->rgbtBlue)); 211 SetPixelOpacity(q,OpaqueOpacity); 212 p++; 213 q++; 214 } 215 if (SyncAuthenticPixels(screen,exception) == MagickFalse) 216 break; 217 } 218 219 DeleteDC(hDC); 220 DeleteDC(bitmapDC); 221 DeleteObject(bitmap); 222 } 223 } 224#elif defined(MAGICKCORE_X11_DELEGATE) 225 { 226 const char 227 *option; 228 229 XImportInfo 230 ximage_info; 231 232 XGetImportInfo(&ximage_info); 233 option=GetImageOption(image_info,"x:screen"); 234 if (option != (const char *) NULL) 235 ximage_info.screen=IsStringTrue(option); 236 option=GetImageOption(image_info,"x:silent"); 237 if (option != (const char *) NULL) 238 ximage_info.silent=IsStringTrue(option); 239 image=XImportImage(image_info,&ximage_info,exception); 240 } 241#endif 242 return(image); 243} 244 245/* 246%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 247% % 248% % 249% % 250% R e g i s t e r S C R E E N S H O T I m a g e % 251% % 252% % 253% % 254%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 255% 256% RegisterSCREENSHOTImage() adds attributes for the screen shot format to 257% the list of supported formats. The attributes include the image format 258% tag, a method to read and/or write the format, whether the format 259% supports the saving of more than one frame to the same file or blob, 260% whether the format supports native in-memory I/O, and a brief 261% description of the format. 262% 263% The format of the RegisterScreenShotImage method is: 264% 265% size_t RegisterScreenShotImage(void) 266% 267*/ 268ModuleExport size_t RegisterSCREENSHOTImage(void) 269{ 270 MagickInfo 271 *entry; 272 273 entry=SetMagickInfo("SCREENSHOT"); 274 entry->decoder=(DecodeImageHandler *) ReadSCREENSHOTImage; 275 entry->format_type=ImplicitFormatType; 276 entry->description=ConstantString("Screen shot"); 277 entry->module=ConstantString("SCREENSHOT"); 278 (void) RegisterMagickInfo(entry); 279 return(MagickImageCoderSignature); 280} 281 282/* 283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 284% % 285% % 286% % 287% U n r e g i s t e r S C R E E N S H O T I m a g e % 288% % 289% % 290% % 291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 292% 293% UnregisterScreenShotImage() removes format registrations made by the 294% screen shot module from the list of supported formats. 295% 296% The format of the UnregisterSCREENSHOTImage method is: 297% 298% UnregisterSCREENSHOTImage(void) 299% 300*/ 301ModuleExport void UnregisterSCREENSHOTImage(void) 302{ 303 (void) UnregisterMagickInfo("SCREENSHOT"); 304} 305