Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release
[gecko.git] / testing / tools / screenshot / win32-screenshot.cpp
blob29cc1fb5e816c61dec3f6807b7b0eeab956fbdf2
1 /*
2 * Copyright (c) 2009, The Mozilla Foundation
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the Mozilla Foundation nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY The Mozilla Foundation ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL The Mozilla Foundation BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * Contributors:
28 * Ted Mielczarek <ted.mielczarek@gmail.com>
31 * win32-screenshot.cpp: Save a screenshot of the Windows desktop in .png
32 * format. If a filename is specified as the first argument on the commandline,
33 * then the image will be saved to that filename. Otherwise, the image will
34 * be saved as "screenshot.png" in the current working directory.
37 // VS2015: Platform SDK 8.1's GdiplusTypes.h uses the min macro
38 #undef NOMINMAX
39 #undef WIN32_LEAN_AND_MEAN
40 #include <windows.h>
41 #include <gdiplus.h>
43 // Link w/ subsystem windows so we don't get a console when executing
44 // this binary.
45 #ifndef __MINGW32__
46 # pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup")
47 #endif
49 using namespace Gdiplus;
51 // From http://msdn.microsoft.com/en-us/library/ms533843%28VS.85%29.aspx
52 static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
53 UINT num = 0; // number of image encoders
54 UINT size = 0; // size of the image encoder array in bytes
56 ImageCodecInfo* pImageCodecInfo = nullptr;
58 GetImageEncodersSize(&num, &size);
59 if (size == 0) return -1; // Failure
61 pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
62 if (pImageCodecInfo == nullptr) return -1; // Failure
64 GetImageEncoders(num, size, pImageCodecInfo);
66 for (UINT j = 0; j < num; ++j) {
67 if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) {
68 *pClsid = pImageCodecInfo[j].Clsid;
69 free(pImageCodecInfo);
70 return j; // Success
74 free(pImageCodecInfo);
75 return -1; // Failure
78 #ifdef __MINGW32__
79 extern "C"
80 #endif
81 int
82 wmain(int argc, wchar_t** argv) {
83 GdiplusStartupInput gdiplusStartupInput;
84 ULONG_PTR gdiplusToken;
85 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
87 HWND desktop = GetDesktopWindow();
88 HDC desktopdc = GetDC(desktop);
89 HDC mydc = CreateCompatibleDC(desktopdc);
90 int width = GetSystemMetrics(SM_CXSCREEN);
91 int height = GetSystemMetrics(SM_CYSCREEN);
92 HBITMAP mybmp = CreateCompatibleBitmap(desktopdc, width, height);
93 HBITMAP oldbmp = (HBITMAP)SelectObject(mydc, mybmp);
94 BitBlt(mydc, 0, 0, width, height, desktopdc, 0, 0, SRCCOPY | CAPTUREBLT);
95 SelectObject(mydc, oldbmp);
97 const wchar_t* filename = (argc > 1) ? argv[1] : L"screenshot.png";
98 Bitmap* b = Bitmap::FromHBITMAP(mybmp, nullptr);
99 CLSID encoderClsid;
100 Status stat = GenericError;
101 if (b && GetEncoderClsid(L"image/png", &encoderClsid) != -1) {
102 stat = b->Save(filename, &encoderClsid, nullptr);
104 if (b) delete b;
106 // cleanup
107 GdiplusShutdown(gdiplusToken);
108 ReleaseDC(desktop, desktopdc);
109 DeleteObject(mybmp);
110 DeleteDC(mydc);
111 return stat == Ok ? 0 : 1;