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-2016 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 /* 41 Include declarations. 42 */ 43 #include "MagickCore/studio.h" 44 #if defined(MAGICKCORE_WINGDI32_DELEGATE) 45 # if defined(__CYGWIN__) 46 # include <windows.h> 47 # else 48 /* All MinGW needs ... */ 49 # include "MagickCore/nt-base-private.h" 50 # include <wingdi.h> 51 # ifndef DISPLAY_DEVICE_ACTIVE 52 # define DISPLAY_DEVICE_ACTIVE 0x00000001 53 # endif 54 # endif 55 #endif 56 #include "MagickCore/blob.h" 57 #include "MagickCore/blob-private.h" 58 #include "MagickCore/cache.h" 59 #include "MagickCore/exception.h" 60 #include "MagickCore/exception-private.h" 61 #include "MagickCore/image.h" 62 #include "MagickCore/image-private.h" 63 #include "MagickCore/list.h" 64 #include "MagickCore/magick.h" 65 #include "MagickCore/memory_.h" 66 #include "MagickCore/module.h" 67 #include "MagickCore/nt-feature.h" 68 #include "MagickCore/option.h" 69 #include "MagickCore/pixel-accessor.h" 70 #include "MagickCore/quantum-private.h" 71 #include "MagickCore/static.h" 72 #include "MagickCore/string_.h" 73 #include "MagickCore/token.h" 74 #include "MagickCore/utility.h" 75 #include "MagickCore/xwindow.h" 76 #include "MagickCore/xwindow-private.h" 77 78 /* 80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 % % 82 % % 83 % % 84 % R e a d S C R E E N S H O T I m a g e % 85 % % 86 % % 87 % % 88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89 % 90 % ReadSCREENSHOTImage() Takes a screenshot from the monitor(s). 91 % 92 % The format of the ReadSCREENSHOTImage method is: 93 % 94 % Image *ReadXImage(const ImageInfo *image_info,ExceptionInfo *exception) 95 % 96 % A description of each parameter follows: 97 % 98 % o image_info: the image info. 99 % 100 % o exception: return any errors or warnings in this structure. 101 % 102 */ 103 static Image *ReadSCREENSHOTImage(const ImageInfo *image_info, 104 ExceptionInfo *exception) 105 { 106 Image 107 *image; 108 109 assert(image_info->signature == MagickCoreSignature); 110 if (image_info->debug != MagickFalse) 111 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 112 image_info->filename); 113 assert(exception != (ExceptionInfo *) NULL); 114 assert(exception->signature == MagickCoreSignature); 115 image=(Image *) NULL; 116 #if defined(MAGICKCORE_WINGDI32_DELEGATE) 117 { 118 BITMAPINFO 119 bmi; 120 121 DISPLAY_DEVICE 122 device; 123 124 HBITMAP 125 bitmap, 126 bitmapOld; 127 128 HDC 129 bitmapDC, 130 hDC; 131 132 Image 133 *screen; 134 135 int 136 i; 137 138 MagickBooleanType 139 status; 140 141 register Quantum 142 *q; 143 144 register ssize_t 145 x; 146 147 RGBTRIPLE 148 *p; 149 150 ssize_t 151 y; 152 153 assert(image_info != (const ImageInfo *) NULL); 154 i=0; 155 device.cb = sizeof(device); 156 image=(Image *) NULL; 157 while(EnumDisplayDevices(NULL,i,&device,0) && ++i) 158 { 159 if ((device.StateFlags & DISPLAY_DEVICE_ACTIVE) != DISPLAY_DEVICE_ACTIVE) 160 continue; 161 162 hDC=CreateDC(device.DeviceName,device.DeviceName,NULL,NULL); 163 if (hDC == (HDC) NULL) 164 ThrowReaderException(CoderError,"UnableToCreateDC"); 165 166 screen=AcquireImage(image_info,exception); 167 screen->columns=(size_t) GetDeviceCaps(hDC,HORZRES); 168 screen->rows=(size_t) GetDeviceCaps(hDC,VERTRES); 169 screen->storage_class=DirectClass; 170 status=SetImageExtent(screen,screen->columns,screen->rows,exception); 171 if (status == MagickFalse) 172 return(DestroyImageList(image)); 173 if (image == (Image *) NULL) 174 image=screen; 175 else 176 AppendImageToList(&image,screen); 177 178 bitmapDC=CreateCompatibleDC(hDC); 179 if (bitmapDC == (HDC) NULL) 180 { 181 DeleteDC(hDC); 182 ThrowReaderException(CoderError,"UnableToCreateDC"); 183 } 184 (void) ResetMagickMemory(&bmi,0,sizeof(BITMAPINFO)); 185 bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 186 bmi.bmiHeader.biWidth=(LONG) screen->columns; 187 bmi.bmiHeader.biHeight=(-1)*(LONG) screen->rows; 188 bmi.bmiHeader.biPlanes=1; 189 bmi.bmiHeader.biBitCount=24; 190 bmi.bmiHeader.biCompression=BI_RGB; 191 bitmap=CreateDIBSection(hDC,&bmi,DIB_RGB_COLORS,(void **) &p,NULL,0); 192 if (bitmap == (HBITMAP) NULL) 193 { 194 DeleteDC(hDC); 195 DeleteDC(bitmapDC); 196 ThrowReaderException(CoderError,"UnableToCreateBitmap"); 197 } 198 bitmapOld=(HBITMAP) SelectObject(bitmapDC,bitmap); 199 if (bitmapOld == (HBITMAP) NULL) 200 { 201 DeleteDC(hDC); 202 DeleteDC(bitmapDC); 203 DeleteObject(bitmap); 204 ThrowReaderException(CoderError,"UnableToCreateBitmap"); 205 } 206 BitBlt(bitmapDC,0,0,(int) screen->columns,(int) screen->rows,hDC,0,0, 207 SRCCOPY); 208 (void) SelectObject(bitmapDC,bitmapOld); 209 210 for (y=0; y < (ssize_t) screen->rows; y++) 211 { 212 q=QueueAuthenticPixels(screen,0,y,screen->columns,1,exception); 213 if (q == (Quantum *) NULL) 214 break; 215 for (x=0; x < (ssize_t) screen->columns; x++) 216 { 217 SetPixelRed(image,ScaleCharToQuantum(p->rgbtRed),q); 218 SetPixelGreen(image,ScaleCharToQuantum(p->rgbtGreen),q); 219 SetPixelBlue(image,ScaleCharToQuantum(p->rgbtBlue),q); 220 SetPixelAlpha(image,OpaqueAlpha,q); 221 p++; 222 q+=GetPixelChannels(image); 223 } 224 if (SyncAuthenticPixels(screen,exception) == MagickFalse) 225 break; 226 } 227 228 DeleteDC(hDC); 229 DeleteDC(bitmapDC); 230 DeleteObject(bitmap); 231 } 232 } 233 #elif defined(MAGICKCORE_X11_DELEGATE) 234 { 235 const char 236 *option; 237 238 XImportInfo 239 ximage_info; 240 241 XGetImportInfo(&ximage_info); 242 option=GetImageOption(image_info,"x:screen"); 243 if (option != (const char *) NULL) 244 ximage_info.screen=IsStringTrue(option); 245 option=GetImageOption(image_info,"x:silent"); 246 if (option != (const char *) NULL) 247 ximage_info.silent=IsStringTrue(option); 248 image=XImportImage(image_info,&ximage_info,exception); 249 } 250 #endif 251 return(image); 252 } 253 254 /* 256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 257 % % 258 % % 259 % % 260 % R e g i s t e r S C R E E N S H O T I m a g e % 261 % % 262 % % 263 % % 264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 265 % 266 % RegisterSCREENSHOTImage() adds attributes for the screen shot format to 267 % the list of supported formats. The attributes include the image format 268 % tag, a method to read and/or write the format, whether the format 269 % supports the saving of more than one frame to the same file or blob, 270 % whether the format supports native in-memory I/O, and a brief 271 % description of the format. 272 % 273 % The format of the RegisterScreenShotImage method is: 274 % 275 % size_t RegisterScreenShotImage(void) 276 % 277 */ 278 ModuleExport size_t RegisterSCREENSHOTImage(void) 279 { 280 MagickInfo 281 *entry; 282 283 entry=AcquireMagickInfo("SCREENSHOT","SCREENSHOT","Screen shot"); 284 entry->decoder=(DecodeImageHandler *) ReadSCREENSHOTImage; 285 entry->format_type=ImplicitFormatType; 286 (void) RegisterMagickInfo(entry); 287 return(MagickImageCoderSignature); 288 } 289 290 /* 292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 293 % % 294 % % 295 % % 296 % 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 % 297 % % 298 % % 299 % % 300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 301 % 302 % UnregisterScreenShotImage() removes format registrations made by the 303 % screen shot module from the list of supported formats. 304 % 305 % The format of the UnregisterSCREENSHOTImage method is: 306 % 307 % UnregisterSCREENSHOTImage(void) 308 % 309 */ 310 ModuleExport void UnregisterSCREENSHOTImage(void) 311 { 312 (void) UnregisterMagickInfo("SCREENSHOT"); 313 } 314