[gimp/gimp-attributes-wip: 16/16] plug-ins: convert win-snap to screenshot works as win-snap, lots of optimizing work to be done.
- From: Hartmut Kuhse <hartmutkuhse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-attributes-wip: 16/16] plug-ins: convert win-snap to screenshot works as win-snap, lots of optimizing work to be done.
- Date: Sun, 1 May 2016 17:02:58 +0000 (UTC)
commit 64ee853bf594a7baaa37ae326820e30d80a686a4
Author: Hartmut Kuhse <hk_priv gmx de>
Date: Sun May 1 19:02:05 2016 +0200
plug-ins: convert win-snap to screenshot
works as win-snap, lots of optimizing work to be done.
plug-ins/screenshot/Makefile.am | 19 +-
plug-ins/screenshot/resource.h | 26 +
plug-ins/screenshot/screenshot-win32.c | 864 +++++++++++++++++++++++++++++-
plug-ins/screenshot/screenshot-win32.h | 8 +
plug-ins/screenshot/screenshot-win32.ico | Bin 0 -> 1590 bytes
plug-ins/screenshot/screenshot-win32.rc | 189 +++++++
plug-ins/screenshot/select.cur | Bin 0 -> 326 bytes
plug-ins/screenshot/small.ico | Bin 0 -> 318 bytes
8 files changed, 1100 insertions(+), 6 deletions(-)
---
diff --git a/plug-ins/screenshot/Makefile.am b/plug-ins/screenshot/Makefile.am
index 75015ae..91b8ea8 100644
--- a/plug-ins/screenshot/Makefile.am
+++ b/plug-ins/screenshot/Makefile.am
@@ -10,11 +10,7 @@ libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
if OS_WIN32
mwindows = -mwindows
-endif
-
-if HAVE_WINDRES
-include $(top_srcdir)/build/windows/gimprc-plug-ins.rule
-screenshot_RC = screenshot.rc.o
+screenshot_RC = screenshot-win32res.o
endif
AM_LDFLAGS = $(mwindows)
@@ -57,5 +53,18 @@ screenshot_SOURCES = \
screenshot-osx.h \
screenshot-x11.c \
screenshot-x11.h \
+ screenshot-win32.rc \
screenshot-win32.c \
screenshot-win32.h
+
+if OS_WIN32
+EXTRA_DIST = \
+ resource.h \
+ select.cur \
+ small.ico \
+ screenshot-win32.ico \
+ screenshot-win32.rc
+
+screenshot-win32res.o: screenshot-win32.rc select.cur small.ico screenshot-win32.ico
+ $(WINDRES) $(srcdir)/screenshot-win32.rc screenshot-win32res.o
+endif
diff --git a/plug-ins/screenshot/resource.h b/plug-ins/screenshot/resource.h
new file mode 100644
index 0000000..57b6ec2
--- /dev/null
+++ b/plug-ins/screenshot/resource.h
@@ -0,0 +1,26 @@
+/* {{NO_DEPENDENCIES}}
+ Microsoft Developer Studio generated include file.
+ Used by snappy.rc
+*/
+#define IDM_CAPTURE 100
+#define IDM_EXIT 101
+
+#define IDC_SELECT 102
+#define IDD_SELECT 103
+#define IDC_TEXT 1000
+#define IDC_GROUP 1001
+#define IDM_CAPTUREFULL 40003
+#define IDM_HOOK 40004
+#define IDM_UNHOOK 40005
+
+/* Next default values for new objects */
+
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40006
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plug-ins/screenshot/screenshot-win32.c b/plug-ins/screenshot/screenshot-win32.c
index dd832ed..e15f7a1 100644
--- a/plug-ins/screenshot/screenshot-win32.c
+++ b/plug-ins/screenshot/screenshot-win32.c
@@ -36,12 +36,100 @@
#include "screenshot.h"
#include "screenshot-win32.h"
+#include "resource.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+/*
+ * Application definitions
+ */
+#define SELECT_FRAME 0
+#define SELECT_CLIENT 1
+#define SELECT_WINDOW 2
+
+#define SHOW_WINDOW FALSE
+#define APP_NAME "plug_in_screenshot_win"
+#define WM_DOCAPTURE (WM_USER + 100)
+
+/* Prototypes */
+void setCaptureType(int capType);
+BOOL InitApplication(HINSTANCE hInstance);
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
+int winsnapWinMain(void);
+
+/* File variables */
+static int captureType;
+static char buffer[512];
+static guchar *capBytes = NULL;
+static HWND mainHwnd = NULL;
+static HINSTANCE hInst = NULL;
+static HCURSOR selectCursor = 0;
+static ICONINFO iconInfo;
+
+static gint32 *image_id;
+
+static void sendBMPToGimp(HBITMAP hBMP, HDC hDC, RECT rect);
+static void doWindowCapture(void);
+static int doCapture(HWND selectedHwnd);
+
+BOOL CALLBACK dialogProc(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+
+/* Data structure holding data between runs */
+typedef struct {
+ gint root;
+ guint delay;
+ gint decor;
+} WinSnapValues;
+
+/* Default WinSnap values */
+static WinSnapValues winsnapvals =
+{
+ FALSE,
+ 0,
+ TRUE,
+};
+
+/* The dialog information */
+typedef struct {
+#ifdef CAN_SET_DECOR
+ GtkWidget *decor_button;
+#endif
+ GtkWidget *single_button;
+ GtkWidget *root_button;
+ GtkWidget *delay_spinner;
+} WinSnapInterface;
+
+/* The dialog data */
+static WinSnapInterface winsnapintf =
+{
+#ifdef CAN_SET_DECOR
+ NULL,
+#endif
+ NULL,
+ NULL,
+ NULL
+};
+
+/* We create a DIB section to hold the grabbed area. The scanlines in
+ * DIB sections are aligned ona LONG (four byte) boundary. Its pixel
+ * data is in RGB (BGR actually) format, three bytes per pixel.
+ *
+ * GIMP uses no alignment for its pixel regions. The GIMP image we
+ * create is of type RGB, i.e. three bytes per pixel, too. Thus in
+ * order to be able to quickly transfer all of the image at a time, we
+ * must use a DIB section and pixel region the scanline width in
+ * bytes of which is evenly divisible with both 3 and 4. I.e. it must
+ * be a multiple of 12 bytes, or in pixels, a multiple of four pixels.
+ */
+
+#define ROUND4(width) (((width-1)/4+1)*4)
gboolean
screenshot_win32_available (void)
{
- return FALSE;
+ return TRUE;
}
ScreenshotCapabilities
@@ -57,7 +145,781 @@ screenshot_win32_shoot (ScreenshotValues *shootvals,
gint32 *image_ID,
GError **error)
{
+ image_id = image_ID;
+
+ winsnapvals.delay = shootvals->select_delay;
+
+ if (shootvals->shoot_type == SHOOT_ROOT)
+ {
+ doCapture(0);
+ return GIMP_PDB_SUCCESS;
+ }
+ else if (shootvals->shoot_type == SHOOT_WINDOW)
+ {
+ doWindowCapture();
+ return GIMP_PDB_SUCCESS;
+ }
+ else if (shootvals->shoot_type == SHOOT_REGION)
+ return GIMP_PDB_EXECUTION_ERROR;
+
return GIMP_PDB_EXECUTION_ERROR;
}
+
+
+
+
+/******************************************************************
+ * GIMP format and transfer functions
+ ******************************************************************/
+
+/*
+ * flipRedAndBlueBytes
+ *
+ * Microsoft has chosen to provide us a very nice (not!)
+ * interface for retrieving bitmap bits. DIBSections have
+ * RGB information as BGR instead. So, we have to swap
+ * the silly red and blue bytes before sending to the
+ * GIMP.
+ */
+static void
+flipRedAndBlueBytes(int width, int height)
+{
+ int i, j;
+ guchar *bufp;
+ guchar temp;
+
+ j = 0;
+ while (j < height) {
+ i = width;
+ bufp = capBytes + j*ROUND4(width)*3;
+ while (i--) {
+ temp = bufp[2];
+ bufp[2] = bufp[0];
+ bufp[0] = temp;
+ bufp += 3;
+ }
+ j++;
+ }
+}
+
+/*
+ * sendBMPToGIMP
+ *
+ * Take the captured data and send it across
+ * to GIMP.
+ */
+static void
+sendBMPToGimp(HBITMAP hBMP, HDC hDC, RECT rect)
+{
+ int width, height;
+ int imageType, layerType;
+ gint32 new_image_id;
+ gint32 layer_id;
+ GimpPixelRgn pixel_rgn;
+ GimpDrawable *drawable;
+
+ /* Our width and height */
+ width = (rect.right - rect.left);
+ height = (rect.bottom - rect.top);
+
+ /* Check that we got the memory */
+ if (!capBytes)
+ {
+ g_message (_("No data captured"));
+ return;
+ }
+
+ /* Flip the red and blue bytes */
+ flipRedAndBlueBytes(width, height);
+
+ /* Set up the image and layer types */
+ imageType = GIMP_RGB;
+ layerType = GIMP_RGB_IMAGE;
+
+ /* Create the GIMP image and layers */
+ new_image_id = gimp_image_new(width, height, imageType);
+ layer_id = gimp_layer_new(new_image_id, _("Background"),
+ ROUND4(width), height,
+ layerType, 100, GIMP_NORMAL_MODE);
+ gimp_image_insert_layer(new_image_id, layer_id, -1, 0);
+
+ /* Get our drawable */
+ drawable = gimp_drawable_get(layer_id);
+
+ gimp_tile_cache_size(ROUND4(width) * gimp_tile_height() * 3);
+
+ /* Initialize a pixel region for writing to the image */
+ gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0,
+ ROUND4(width), height, TRUE, FALSE);
+
+ gimp_pixel_rgn_set_rect(&pixel_rgn, (guchar *) capBytes,
+ 0, 0, ROUND4(width), height);
+
+ /* HB: update data BEFORE size change */
+ gimp_drawable_flush(drawable);
+ /* Now resize the layer down to the correct size if necessary. */
+ if (width != ROUND4(width)) {
+ gimp_layer_resize (layer_id, width, height, 0, 0);
+ gimp_image_resize (new_image_id, width, height, 0, 0);
+ }
+ /* Finish up */
+
+ *image_id = new_image_id;
+
+ return;
+}
+
+/*
+ * doNonRootWindowCapture
+ *
+ * Capture a selected window.
+ * ENTRY POINT FOR WINSNAP NONROOT
+ *
+ */
+static void
+doWindowCapture(void)
+{
+ /* Start up a standard Win32
+ * message handling loop for
+ * selection of the window
+ * to be captured
+ */
+ winsnapWinMain();
+}
+
+/*
+ * doRootWindowCapture
+ *
+ * Capture the root window
+ * ENTRY POINT FOR WINSNAP ROOT
+ */
+static void
+doRootWindowCapture(void)
+{
+ /* Do the window capture */
+ doCapture(0);
+}
+
+/******************************************************************
+ * Debug stuff
+ ******************************************************************/
+
+/*
+ * formatWindowsError
+ *
+ * Format the latest Windows error message into
+ * a readable string. Store in the provided
+ * buffer.
+ */
+static void
+formatWindowsError(char *buffer, int buf_size)
+{
+ LPVOID lpMsgBuf;
+
+ /* Format the message */
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL );
+
+ /* Copy to the buffer */
+ strncpy(buffer, lpMsgBuf, buf_size - 1);
+
+ LocalFree(lpMsgBuf);
+}
+
+/******************************************************************
+ * Bitmap capture and handling
+ ******************************************************************/
+
+/*
+ * primDoWindowCapture
+ *
+ * The primitive window capture functionality. Accepts
+ * the two device contexts and the rectangle to be
+ * captured.
+ */
+static HBITMAP
+primDoWindowCapture(HDC hdcWindow, HDC hdcCompat, RECT rect)
+{
+ HBITMAP hbmCopy;
+ HGDIOBJ oldObject;
+ BITMAPINFO bmi;
+
+ int width = (rect.right - rect.left);
+ int height = (rect.bottom - rect.top);
+
+ /* Create the bitmap info header */
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = ROUND4(width);
+ bmi.bmiHeader.biHeight = -height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 24;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = 0;
+ bmi.bmiHeader.biXPelsPerMeter =
+ bmi.bmiHeader.biYPelsPerMeter = 0;
+ bmi.bmiHeader.biClrUsed = 0;
+ bmi.bmiHeader.biClrImportant = 0;
+
+ /* Create the bitmap storage space */
+ hbmCopy = CreateDIBSection(hdcCompat,
+ (BITMAPINFO *) &bmi,
+ DIB_RGB_COLORS,
+ (void **)&capBytes, NULL, 0);
+ if (!hbmCopy) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error creating DIB section: %s", buffer);
+ return NULL;
+ }
+
+ /* Select the bitmap into the compatible DC. */
+ oldObject = SelectObject(hdcCompat, hbmCopy);
+ if (!oldObject) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error selecting object: %s", buffer);
+ return NULL;
+ }
+
+ /* Copy the data from the application to the bitmap. Even if we did
+ * round up the width, BitBlt only the actual data.
+ */
+ if (!BitBlt(hdcCompat, 0,0,
+ width, height,
+ hdcWindow, 0,0,
+ SRCCOPY)) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error copying bitmap: %s", buffer);
+ return NULL;
+ }
+
+ /* Restore the original object */
+ SelectObject(hdcCompat, oldObject);
+
+ return hbmCopy;
+}
+
+/*
+ * doCapture
+ *
+ * Do the capture. Accepts the window
+ * handle to be captured or the NULL value
+ * to specify the root window.
+ */
+static int
+doCapture(HWND selectedHwnd)
+{
+ HDC hdcSrc;
+ HDC hdcCompat;
+ HRGN capRegion;
+ HWND oldForeground;
+ RECT rect;
+ HBITMAP hbm;
+
+ /* Try and get everything out of the way before the
+ * capture.
+ */
+ Sleep(500 + winsnapvals.delay * 1000);
+
+ /* Are we capturing a window or the whole screen */
+ if (selectedHwnd) {
+
+ /* Set to foreground window */
+ oldForeground = GetForegroundWindow();
+ SetForegroundWindow(selectedHwnd);
+ BringWindowToTop(selectedHwnd);
+
+ Sleep(500);
+
+ /* Build a region for the capture */
+ GetWindowRect(selectedHwnd, &rect);
+ capRegion = CreateRectRgn(rect.left, rect.top,
+ rect.right, rect.bottom);
+ if (!capRegion) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error creating region: %s", buffer);
+ return FALSE;
+ }
+
+ /* Get the device context for the selected
+ * window. Create a memory DC to use for the
+ * Bit copy.
+ */
+ hdcSrc = GetDCEx(selectedHwnd, capRegion,
+ DCX_WINDOW | DCX_PARENTCLIP | DCX_INTERSECTRGN);
+ } else {
+ /* Get the device context for the whole screen */
+ hdcSrc = CreateDC("DISPLAY", NULL, NULL, NULL);
+
+ /* Get the screen's rectangle */
+ rect.top = 0;
+ rect.bottom = GetDeviceCaps(hdcSrc, VERTRES);
+ rect.left = 0;
+ rect.right = GetDeviceCaps(hdcSrc, HORZRES);
+ }
+
+ if (!hdcSrc) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error getting device context: %s", buffer);
+ return FALSE;
+ }
+ hdcCompat = CreateCompatibleDC(hdcSrc);
+ if (!hdcCompat) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error getting compat device context: %s", buffer);
+ return FALSE;
+ }
+
+ /* Do the window capture */
+ hbm = primDoWindowCapture(hdcSrc, hdcCompat, rect);
+ if (!hbm)
+ return FALSE;
+
+ /* Release the device context */
+ ReleaseDC(selectedHwnd, hdcSrc);
+
+ /* Replace the previous foreground window */
+ if (selectedHwnd && oldForeground)
+ SetForegroundWindow(oldForeground);
+
+ /* Send the bitmap
+ * TODO: Change this
+ */
+ if (hbm != NULL) {
+ sendBMPToGimp(hbm, hdcCompat, rect);
+ }
+
+ return TRUE;
+}
+
+/******************************************************************
+ * Win32 entry point and setup...
+ ******************************************************************/
+
+#define DINV 3
+
+/*
+ * highlightWindowFrame
+ *
+ * Highlight (or unhighlight) the specified
+ * window handle's frame.
+ */
+static void
+highlightWindowFrame(HWND hWnd)
+{
+ HDC hdc;
+ RECT rc;
+
+ if (!IsWindow(hWnd))
+ return;
+
+ hdc = GetWindowDC(hWnd);
+ GetWindowRect(hWnd, &rc);
+ OffsetRect(&rc, -rc.left, -rc.top);
+
+ if (!IsRectEmpty(&rc)) {
+ PatBlt(hdc, rc.left, rc.top, rc.right-rc.left, DINV, DSTINVERT);
+ PatBlt(hdc, rc.left, rc.bottom-DINV, DINV, -(rc.bottom-rc.top-2*DINV),
+ DSTINVERT);
+ PatBlt(hdc, rc.right-DINV, rc.top+DINV, DINV, rc.bottom-rc.top-2*DINV,
+ DSTINVERT);
+ PatBlt(hdc, rc.right, rc.bottom-DINV, -(rc.right-rc.left), DINV,
+ DSTINVERT);
+ }
+
+ ReleaseDC(hWnd, hdc);
+ UpdateWindow(hWnd);
+}
+
+/*
+ * setCaptureType
+ *
+ * Set the capture type. Should be one of:
+ * SELECT_FRAME
+ * SELECT_CLIENT
+ * SELECT_WINDOW
+ */
+void
+setCaptureType(int capType)
+{
+ captureType = capType;
+}
+
+/*
+ * myWindowFromPoint
+ *
+ * Map to the appropriate window from the
+ * specified point. The chosen window is
+ * based on the current capture type.
+ */
+static HWND
+myWindowFromPoint(POINT pt)
+{
+ HWND myHwnd;
+ HWND nextHwnd;
+
+ switch (captureType) {
+ case SELECT_FRAME:
+ case SELECT_CLIENT:
+ nextHwnd = WindowFromPoint(pt);
+
+ do {
+ myHwnd = nextHwnd;
+ nextHwnd = GetParent(myHwnd);
+ } while (nextHwnd);
+
+ return myHwnd;
+ break;
+
+ case SELECT_WINDOW:
+ return WindowFromPoint(pt);
+ break;
+ }
+
+ return WindowFromPoint(pt);
+}
+
+/*
+ * dialogProc
+ *
+ * The window procedure for the window
+ * selection dialog box.
+ */
+BOOL CALLBACK
+dialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int mouseCaptured;
+ static int buttonDown;
+ static HCURSOR oldCursor;
+ static RECT bitmapRect;
+ static HWND highlightedHwnd = NULL;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ int nonclientHeight;
+ HWND hwndGroup;
+ RECT dlgRect;
+ RECT clientRect;
+ RECT groupRect;
+ BITMAP bm;
+
+ /* Set the mouse capture flag */
+ buttonDown = 0;
+ mouseCaptured = 0;
+
+ /* Calculate the bitmap dimensions */
+ GetObject(iconInfo.hbmMask, sizeof(BITMAP), (VOID *)&bm);
+
+ /* Calculate the dialog window dimensions */
+ GetWindowRect(hwndDlg, &dlgRect);
+
+ /* Calculate the group box dimensions */
+ hwndGroup = GetDlgItem(hwndDlg, IDC_GROUP);
+ GetWindowRect(hwndGroup, &groupRect);
+ OffsetRect(&groupRect, -dlgRect.left, -dlgRect.top);
+
+ /* The client's rectangle */
+ GetClientRect(hwndDlg, &clientRect);
+
+ /* The non-client height */
+ nonclientHeight = (dlgRect.bottom - dlgRect.top) -
+ (clientRect.bottom - clientRect.top);
+
+ /* Calculate the bitmap rectangle */
+ bitmapRect.top = ((groupRect.top + groupRect.bottom) / 2) -
+ (bm.bmHeight / 2);
+ bitmapRect.top -= nonclientHeight;
+ bitmapRect.bottom = bitmapRect.top + bm.bmHeight;
+ bitmapRect.left = ((groupRect.left + groupRect.right) / 2) - (bm.bmWidth / 2);
+ bitmapRect.right = bitmapRect.left + bm.bmWidth;
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ /* Track the button down state */
+ buttonDown = 1;
+ break;
+
+ case WM_LBUTTONUP:
+ buttonDown = 0;
+
+ /* If we have mouse captured
+ * we do this stuff.
+ */
+ if (mouseCaptured) {
+ HWND selectedHwnd;
+ POINT cursorPos;
+
+ /* Release the capture */
+ mouseCaptured = 0;
+ SetCursor(oldCursor);
+ ReleaseCapture();
+
+ /* Remove the highlight */
+ if (highlightedHwnd)
+ highlightWindowFrame(highlightedHwnd);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
+
+ /* Return the selected window */
+ GetCursorPos(&cursorPos);
+ selectedHwnd = myWindowFromPoint(cursorPos);
+ EndDialog(hwndDlg, (INT_PTR) selectedHwnd);
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ /* If the mouse is captured, show
+ * the window which is tracking
+ * under the mouse position.
+ */
+ if (mouseCaptured) {
+ HWND currentHwnd;
+ POINT cursorPos;
+
+ /* Get the window */
+ GetCursorPos(&cursorPos);
+ currentHwnd = myWindowFromPoint(cursorPos);
+
+ /* Do the highlighting */
+ if (highlightedHwnd != currentHwnd) {
+ if (highlightedHwnd)
+ highlightWindowFrame(highlightedHwnd);
+ if (currentHwnd)
+ highlightWindowFrame(currentHwnd);
+ highlightedHwnd = currentHwnd;
+ }
+ /* If the mouse has not been captured,
+ * try to figure out if we should capture
+ * the mouse.
+ */
+ } else if (buttonDown) {
+ POINT cursorPos;
+
+ /* Get the current client position */
+ GetCursorPos(&cursorPos);
+ ScreenToClient(hwndDlg, &cursorPos);
+
+ /* Check if within the rectangle formed
+ * by the bitmap
+ */
+ if (PtInRect(&bitmapRect, cursorPos)) {
+ mouseCaptured = 1;
+ oldCursor = SetCursor(selectCursor);
+ SetCapture(hwndDlg);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_ERASE);
+ }
+ }
+
+ break;
+
+ case WM_PAINT:
+ {
+ HDC hDC;
+ PAINTSTRUCT ps;
+
+ /* If the mouse is not captured draw
+ * the cursor image
+ */
+ if (!mouseCaptured) {
+ hDC = BeginPaint(hwndDlg, &ps);
+ DrawIconEx(hDC, bitmapRect.left, bitmapRect.top, selectCursor,
+ 0, 0, 0, NULL, DI_NORMAL);
+ EndPaint(hwndDlg, &ps);
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ /* Handle the cancel button */
+ switch (LOWORD(wParam)) {
+ case IDCANCEL:
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+ break;
+ }
+
+ }
+
+ return FALSE;
+}
+
+///* Don't use the normal WinMain from gimp.h */
+//#define WinMain WinMain_no_thanks
+//MAIN()
+//#undef WinMain
+
+/*
+ * WinMain
+ *
+ * The standard gimp plug-in WinMain won't quite cut it for
+ * this plug-in.
+ */
+//int APIENTRY
+//WinMain(HINSTANCE hInstance,
+// HINSTANCE hPrevInstance,
+// LPSTR lpCmdLine,
+// int nCmdShow)
+//{
+// /*
+// * Normally, we would do all of the Windows-ish set up of
+// * the window classes and stuff here in WinMain. But,
+// * the only time we really need the window and message
+// * queues is during the plug-in run. So, all of that will
+// * be done during run(). This avoids all of the Windows
+// * setup stuff for the query(). Stash the instance handle now
+// * so it is available from the run() procedure.
+// */
+// hInst = hInstance;
+//
+// /*
+// * Now, call gimp_main... This is what the normal WinMain()
+// * would do.
+// */
+//// return gimp_main(&PLUG_IN_INFO, __argc, __argv);
+//}
+
+/*
+ * InitApplication
+ *
+ * Initialize window data and register the window class
+ */
+BOOL
+InitApplication(HINSTANCE hInstance)
+{
+ WNDCLASS wc;
+ BOOL retValue;
+
+ /* Get some resources */
+#ifdef _MSC_VER
+ /* For some reason this works only with MSVC */
+ selectCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_SELECT));
+#else
+ selectCursor = LoadCursor(NULL, IDC_CROSS);
+#endif
+ GetIconInfo(selectCursor, &iconInfo);
+
+ /*
+ * Fill in window class structure with parameters to describe
+ * the main window.
+ */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = (WNDPROC) WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
+ wc.lpszClassName = APP_NAME;
+ wc.lpszMenuName = NULL;
+
+ /* Register the window class and stash success/failure code. */
+ retValue = RegisterClass(&wc);
+
+ /* Log error */
+ if (!retValue) {
+ formatWindowsError(buffer, sizeof buffer);
+ g_error("Error registering class: %s", buffer);
+ return retValue;
+ }
+
+ return retValue;
+}
+
+/*
+ * InitInstance
+ *
+ * Create the main window for the application.
+ */
+BOOL
+InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+ /* Create our window */
+ mainHwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ NULL, NULL, hInstance, NULL);
+
+ if (!mainHwnd) {
+ return (FALSE);
+ }
+
+ ShowWindow(mainHwnd, nCmdShow);
+ UpdateWindow(mainHwnd);
+
+ return TRUE;
+}
+
+/*
+ * winsnapWinMain
+ *
+ * This is the function that represents the code that
+ * would normally reside in WinMain (see above). This
+ * function will get called during run() in order to set
+ * up the windowing environment necessary for WinSnap to
+ * operate.
+ */
+int
+winsnapWinMain(void)
+{
+ MSG msg;
+
+ /* Perform instance initialization */
+ if (!InitApplication(hInst))
+ return (FALSE);
+
+ /* Perform application initialization */
+ if (!InitInstance(hInst, SHOW_WINDOW))
+ return (FALSE);
+
+ /* Main message loop */
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return (msg.wParam);
+}
+
+/*
+ * WndProc
+ *
+ * Process window message for the main window.
+ */
+LRESULT CALLBACK
+WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HWND selectedHwnd;
+
+ switch (message) {
+
+ case WM_CREATE:
+ /* The window is created... Send the capture message */
+ PostMessage(hwnd, WM_DOCAPTURE, 0, 0);
+ break;
+
+ case WM_DOCAPTURE:
+ /* Get the selected window handle */
+ selectedHwnd = (HWND) DialogBox(hInst, MAKEINTRESOURCE(IDD_SELECT),
+ hwnd, (DLGPROC) dialogProc);
+ if (selectedHwnd)
+ doCapture(selectedHwnd);
+
+ PostQuitMessage(0);
+
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return (DefWindowProc(hwnd, message, wParam, lParam));
+ }
+
+ return 0;
+}
+
#endif /* G_OS_WIN32 */
diff --git a/plug-ins/screenshot/screenshot-win32.h b/plug-ins/screenshot/screenshot-win32.h
index 66adf27..2e80c0d 100644
--- a/plug-ins/screenshot/screenshot-win32.h
+++ b/plug-ins/screenshot/screenshot-win32.h
@@ -21,6 +21,14 @@
#ifdef G_OS_WIN32
+#define IDC_STATIC -1
+
+#define IDS_APP_TITLE 500
+#define IDS_DISPLAYCHANGED 501
+#define IDS_VER_INFO_LANG 502
+#define IDS_VERSION_ERROR 503
+#define IDS_NO_HELP 504
+
gboolean screenshot_win32_available (void);
ScreenshotCapabilities screenshot_win32_get_capabilities (void);
diff --git a/plug-ins/screenshot/screenshot-win32.ico b/plug-ins/screenshot/screenshot-win32.ico
new file mode 100644
index 0000000..35ea973
Binary files /dev/null and b/plug-ins/screenshot/screenshot-win32.ico differ
diff --git a/plug-ins/screenshot/screenshot-win32.rc b/plug-ins/screenshot/screenshot-win32.rc
new file mode 100644
index 0000000..5146652
--- /dev/null
+++ b/plug-ins/screenshot/screenshot-win32.rc
@@ -0,0 +1,189 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "screenshot-win32.h"
+#include "winver.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+SNAPPY ICON DISCARDABLE "screenshot-win32.ico"
+SMALL ICON DISCARDABLE "small.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+SNAPPY MENU DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Capture", IDM_CAPTURE
+ MENUITEM "Capture Fullscreen", IDM_CAPTUREFULL
+ MENUITEM SEPARATOR
+ MENUITEM "Begin Hook", IDM_HOOK
+ MENUITEM "End Hook", IDM_UNHOOK
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", IDM_EXIT
+ END
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""screenshot-win32.h""\r\n"
+ "#include ""winver.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Cursor
+//
+
+IDC_SELECT CURSOR DISCARDABLE "select.cur"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "SeteraSoft\0"
+ VALUE "FileDescription", "snappy\0"
+ VALUE "FileVersion", "1, 0, 0, 1\0"
+ VALUE "InternalName", "snappy\0"
+ VALUE "LegalCopyright", "Copyright � 1999\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "snappy.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "SeteraSoft snappy\0"
+ VALUE "ProductVersion", "1, 0, 0, 1\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SELECT DIALOG DISCARDABLE 0, 0, 141, 95
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Select Window"
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "Cancel",IDCANCEL,44,74,50,14
+ CTEXT "Drag crosshair to select window",IDC_TEXT,7,7,127,8
+ GROUPBOX "",IDC_GROUP,51,25,37,37,NOT WS_VISIBLE
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_SELECT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 134
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plug-ins/screenshot/select.cur b/plug-ins/screenshot/select.cur
new file mode 100644
index 0000000..2357f84
Binary files /dev/null and b/plug-ins/screenshot/select.cur differ
diff --git a/plug-ins/screenshot/small.ico b/plug-ins/screenshot/small.ico
new file mode 100644
index 0000000..33f9a51
Binary files /dev/null and b/plug-ins/screenshot/small.ico differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]