From 911c5a973f0ad0c89c3bf34e7157502adf2b581a Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 29 Apr 2018 14:42:20 +0300 Subject: [PATCH] Take screenshot from window that has focus (if multiple windows). --- inputdevice.cpp | 8 +++--- od-win32/avioutput.cpp | 27 ++++++++++---------- od-win32/rp.cpp | 6 ++--- od-win32/screenshot.cpp | 56 +++++++++++++++++++++++------------------ od-win32/win32.cpp | 8 ++++++ od-win32/win32.h | 5 ++-- od-win32/win32gfx.cpp | 8 +++--- od-win32/win32gfx.h | 10 ++++---- od-win32/win32gui.cpp | 4 +-- 9 files changed, 74 insertions(+), 58 deletions(-) diff --git a/inputdevice.cpp b/inputdevice.cpp index 0177383e..9dc2b733 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -4269,7 +4269,7 @@ static bool inputdevice_handle_inputcode2(int monid, int code, int state, const { case AKS_SCREENSHOT_FILE: // stop multiscreenshot - screenshot(0, 4, 1); + screenshot(-1, 4, 1); break; } return false; @@ -4283,13 +4283,13 @@ static bool inputdevice_handle_inputcode2(int monid, int code, int state, const break; case AKS_SCREENSHOT_FILE: if (state > 1) { - screenshot(0, 3, 1); + screenshot(-1, 3, 1); } else { - screenshot(0, 1, 1); + screenshot(-1, 1, 1); } break; case AKS_SCREENSHOT_CLIPBOARD: - screenshot(0, 0, 1); + screenshot(-1, 0, 1); break; #ifdef AVIOUTPUT case AKS_VIDEORECORD: diff --git a/od-win32/avioutput.cpp b/od-win32/avioutput.cpp index 4a6564bb..b3e55ded 100644 --- a/od-win32/avioutput.cpp +++ b/od-win32/avioutput.cpp @@ -93,6 +93,7 @@ struct avientry { uae_u8 *lpAudio; int sndsize; int expectedsize; + int monid; }; #define AVIENTRY_MAX 10 @@ -1035,7 +1036,7 @@ static int getFromRenderTarget(struct avientry *avie) return ok; } -static int getFromDC (struct avientry *avie) +static int getFromDC(struct avientry *avie) { HDC hdc; HBITMAP hbitmap = NULL; @@ -1043,25 +1044,25 @@ static int getFromDC (struct avientry *avie) HDC hdcMem = NULL; int ok = 1; - hdc = gethdc (); + hdc = gethdc(avie->monid); if (!hdc) return 0; // create a memory device context compatible with the application's current screen - hdcMem = CreateCompatibleDC (hdc); - hbitmap = CreateCompatibleBitmap (hdc, avioutput_width, avioutput_height); - hbitmapOld = (HBITMAP)SelectObject (hdcMem, hbitmap); + hdcMem = CreateCompatibleDC(hdc); + hbitmap = CreateCompatibleBitmap(hdc, avioutput_width, avioutput_height); + hbitmapOld = (HBITMAP)SelectObject(hdcMem, hbitmap); // probably not the best idea to use slow GDI functions for this, // locking the surfaces and copying them by hand would be more efficient perhaps // draw centered in frame - BitBlt (hdcMem, 0, 0, avioutput_width, avioutput_height, hdc, 0, 0, SRCCOPY); - SelectObject (hdcMem, hbitmapOld); - if (GetDIBits (hdc, hbitmap, 0, avioutput_height, avie->lpVideo, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0) { - gui_message (_T("GetDIBits() FAILED (%X)\n"), GetLastError ()); + BitBlt(hdcMem, 0, 0, avioutput_width, avioutput_height, hdc, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbitmapOld); + if (GetDIBits(hdc, hbitmap, 0, avioutput_height, avie->lpVideo, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0) { + gui_message(_T("GetDIBits() FAILED (%X)\n"), GetLastError()); ok = 0; } - DeleteObject (hbitmap); - DeleteDC (hdcMem); - releasehdc (hdc); + DeleteObject(hbitmap); + DeleteDC(hdcMem); + releasehdc(avie->monid, hdc); return ok; } @@ -1750,7 +1751,7 @@ bool frame_drawn (void) start_if_requested(); if (screenshot_multi) { - screenshot(0, 1, 1); + screenshot(-1, 1, 1); if (screenshot_multi > 0) screenshot_multi--; } diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index 549c6028..b93759ad 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -1275,7 +1275,7 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM } case RP_IPC_TO_GUEST_SCREENCAPTURE: { - extern int screenshotf (const TCHAR *spath, int mode, int doprepare, int imagemode, struct vidbuffer *vb); + extern int screenshotf(int monid, const TCHAR *spath, int mode, int doprepare, int imagemode, struct vidbuffer *vb); extern int screenshotmode; struct RPScreenCapture *rpsc = (struct RPScreenCapture*)pData; if (rpsc->szScreenFiltered[0] || rpsc->szScreenRaw[0]) { @@ -1286,7 +1286,7 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM if (log_rp & 2) write_log (_T("'%s' '%s'\n"), rpsc->szScreenFiltered, rpsc->szScreenRaw); if (rpsc->szScreenFiltered[0]) - ok = screenshotf (rpsc->szScreenFiltered, 1, 1, 0, NULL); + ok = screenshotf(0, rpsc->szScreenFiltered, 1, 1, 0, NULL); if (rpsc->szScreenRaw[0]) { struct vidbuf_description *avidinfo = &adisplays[0].gfxvidinfo; struct vidbuffer vb; @@ -1301,7 +1301,7 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM allocvidbuffer (0, &vb, w, h, avidinfo->drawbuffer.pixbytes * 8); set_custom_limits (-1, -1, -1, -1); draw_frame (&vb); - ok |= screenshotf (rpsc->szScreenRaw, 1, 1, 1, &vb); + ok |= screenshotf(0, rpsc->szScreenRaw, 1, 1, 1, &vb); if (log_rp & 2) write_log (_T("Rawscreenshot %dx%d\n"), w, h); //ok |= screenshotf (_T("c:\\temp\\1.bmp"), 1, 1, 1, &vb); diff --git a/od-win32/screenshot.cpp b/od-win32/screenshot.cpp index 8da2ad7f..e08c9eaf 100644 --- a/od-win32/screenshot.cpp +++ b/od-win32/screenshot.cpp @@ -82,16 +82,17 @@ static int toclipboard (BITMAPINFO *bi, void *bmp) } static HDC surface_dc, offscreen_dc; +static int surface_dc_monid; static BITMAPINFO *bi; // bitmap info static LPVOID lpvBits = NULL; // pointer to bitmap bits array static HBITMAP offscreen_bitmap; static int screenshot_prepared; static int screenshot_multi_start; -void screenshot_free (void) +void screenshot_free(void) { if (surface_dc) - releasehdc (surface_dc); + releasehdc(surface_dc_monid, surface_dc); surface_dc = NULL; if(offscreen_dc) DeleteDC(offscreen_dc); @@ -107,9 +108,9 @@ void screenshot_free (void) static int rgb_rb, rgb_gb, rgb_bb, rgb_rs, rgb_gs, rgb_bs, rgb_ab, rgb_as; -static int screenshot_prepare (int imagemode, struct vidbuffer *vb) +static int screenshot_prepare(int monid, int imagemode, struct vidbuffer *vb) { - struct AmigaMonitor *mon = &AMonitors[0]; + struct AmigaMonitor *mon = &AMonitors[monid]; int width, height; HGDIOBJ hgdiobj; int bits; @@ -134,7 +135,7 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) int screenshot_xoffset = -1, screenshot_yoffset = -1; if (WIN32GFX_IsPicassoScreen(mon)) { - src = mem = getrtgbuffer(0, &width, &height, &spitch, &bits, pal); + src = mem = getrtgbuffer(monid, &width, &height, &spitch, &bits, pal); needfree = true; rgb_bb2 = 8; rgb_gb2 = 8; @@ -159,7 +160,7 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) rgb_rs2 = rgb_rs; rgb_as2 = rgb_as; } else { - src = mem = getfilterbuffer(0, &width, &height, &spitch, &bits); + src = mem = getfilterbuffer(monid, &width, &height, &spitch, &bits); needfree = true; rgb_bb2 = rgb_bb; rgb_gb2 = rgb_gb; @@ -272,9 +273,9 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) if (!(lpvBits = xmalloc(uae_u8, bi->bmiHeader.biSizeImage))) { if (needfree) { if (WIN32GFX_IsPicassoScreen(mon)) - freertgbuffer(0, mem); + freertgbuffer(monid, mem); else - freefilterbuffer(0, mem); + freefilterbuffer(monid, mem); } goto oops; } @@ -392,9 +393,9 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) } if (needfree) { if (WIN32GFX_IsPicassoScreen(mon)) - freertgbuffer(0, mem); + freertgbuffer(monid, mem); else - freefilterbuffer(0, mem); + freefilterbuffer(monid, mem); } } else { @@ -406,7 +407,7 @@ donormal: if (D3D_isenabled(0) == 2) { int w, h, pitch, bits = 32; void *data; - bool got = D3D11_capture(0, &data, &w, &h, &pitch); + bool got = D3D11_capture(monid, &data, &w, &h, &pitch); int dpitch = (((w * depth + 31) & ~31) / 8); lpvBits = xmalloc(uae_u8, dpitch * h); @@ -443,14 +444,14 @@ donormal: } } if (got) - D3D11_capture(0, NULL, NULL, NULL, NULL); + D3D11_capture(monid, NULL, NULL, NULL, NULL); d3dcaptured = true; } else if (D3D_isenabled(0) == 1) { int w, h, bits; HRESULT hr; D3DLOCKED_RECT l; - LPDIRECT3DSURFACE9 s = D3D_capture(0, &w, &h, &bits); + LPDIRECT3DSURFACE9 s = D3D_capture(monid, &w, &h, &bits); if (s) { hr = s->LockRect(&l, NULL, D3DLOCK_READONLY); if (SUCCEEDED(hr)) { @@ -517,7 +518,8 @@ donormal: } if (!d3dcaptured) { - surface_dc = gethdc (); + surface_dc = gethdc(monid); + surface_dc_monid = monid; if (surface_dc == NULL) goto oops; @@ -560,7 +562,7 @@ donormal: if (!GetDIBits (offscreen_dc, offscreen_bitmap, 0, bi->bmiHeader.biHeight, lpvBits, bi, DIB_RGB_COLORS)) goto oops; // GetDIBits FAILED - releasehdc (surface_dc); + releasehdc(monid, surface_dc); surface_dc = NULL; } @@ -575,17 +577,17 @@ oops: return 0; } -int screenshot_prepare (struct vidbuffer *vb) +static int screenshot_prepare(int monid, struct vidbuffer *vb) { - return screenshot_prepare (1, vb); + return screenshot_prepare(monid, 1, vb); } -int screenshot_prepare (int imagemode) +int screenshot_prepare(int monid, int imagemode) { - return screenshot_prepare (imagemode, NULL); + return screenshot_prepare(monid, imagemode, NULL); } -int screenshot_prepare (void) +int screenshot_prepare(int monid) { - return screenshot_prepare (-1); + return screenshot_prepare(monid, -1); } void Screenshot_RGBinfo (int rb, int gb, int bb, int ab, int rs, int gs, int bs, int as) @@ -698,7 +700,7 @@ static int dirnumber = 1; /* Captures the Amiga display (DirectDraw, D3D or OpenGL) surface and saves it to file as a 24bit bitmap. */ -int screenshotf (const TCHAR *spath, int mode, int doprepare, int imagemode, struct vidbuffer *vb) +int screenshotf(int monid, const TCHAR *spath, int mode, int doprepare, int imagemode, struct vidbuffer *vb) { static int recursive; FILE *fp = NULL; @@ -716,10 +718,10 @@ int screenshotf (const TCHAR *spath, int mode, int doprepare, int imagemode, str recursive++; if (vb) { - if (!screenshot_prepare (vb)) + if (!screenshot_prepare(monid, vb)) goto oops; } else if (!screenshot_prepared || doprepare) { - if (!screenshot_prepare (imagemode)) + if (!screenshot_prepare(monid, imagemode)) goto oops; } @@ -835,6 +837,10 @@ oops: void screenshot(int monid, int mode, int doprepare) { + if (monid < 0) { + monid = getfocusedmonitor(); + } + if (mode == 2) { screenshot_multi = 10; screenshot_prepare_multi(); @@ -845,7 +851,7 @@ void screenshot(int monid, int mode, int doprepare) screenshot_multi = 0; filenumber = 0; } else { - screenshotf(NULL, mode, doprepare, -1, NULL); + screenshotf(monid, NULL, mode, doprepare, -1, NULL); } #if 0 diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index ed774d03..753b9d3f 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -938,6 +938,14 @@ void target_inputdevice_acquire(void) tablet = open_tablet(mon->hAmigaWnd); } +int getfocusedmonitor(void) +{ + if (focus > 0) { + return focus - 1; + } + return 0; +} + static void setmouseactive2(struct AmigaMonitor *mon, int active, bool allowpause) { #ifdef RETROPLATFORM diff --git a/od-win32/win32.h b/od-win32/win32.h index 2866201e..18e5170b 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -80,6 +80,7 @@ extern bool resumepaused (int priority); extern bool setpaused (int priority); extern void unsetminimized (int monid); extern void setminimized(int monid); +extern int getfocusedmonitor(void); void finishjob (void); void init_colors(int monid); @@ -153,8 +154,8 @@ void associate_file_extensions (void); HMODULE WIN32_LoadLibrary (const TCHAR *); int isdllversion (const TCHAR *name, int version, int revision, int subver, int subrev); -extern int screenshot_prepare (void); -extern int screenshot_prepare (int); +extern int screenshot_prepare(int); +extern int screenshot_prepare(int, int); extern void screenshot_free(void); extern void screenshot_reset(void); diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index e72679ca..9891880c 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -4348,24 +4348,24 @@ void toggle_fullscreen(int monid, int mode) updatewinfsmode(monid, &changed_prefs); } -HDC gethdc(void) +HDC gethdc(int monid) { HDC hdc = 0; #ifdef D3D if (D3D_isenabled(0)) - return D3D_getDC(0, 0); + return D3D_getDC(monid, 0); #endif if(FAILED(DirectDraw_GetDC(&hdc))) hdc = 0; return hdc; } -void releasehdc (HDC hdc) +void releasehdc(int monid, HDC hdc) { #ifdef D3D if (D3D_isenabled(0)) { - D3D_getDC(0, hdc); + D3D_getDC(monid, hdc); return; } #endif diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index 50acf809..a194e8f3 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -28,13 +28,13 @@ extern int window_led_hd, window_led_hd_end; extern int window_led_joys, window_led_joys_end, window_led_joy_start; extern int window_led_msg, window_led_msg_end, window_led_msg_start; -extern HDC gethdc (void); -extern void releasehdc (HDC hdc); +extern HDC gethdc(int monid); +extern void releasehdc(int monid, HDC hdc); extern void close_windows(struct AmigaMonitor*); extern void updatewinfsmode(int monid, struct uae_prefs *p); -extern int is3dmode (void); -extern void gfx_lock (void); -extern void gfx_unlock (void); +extern int is3dmode(void); +extern void gfx_lock(void); +extern void gfx_unlock(void); extern bool lockscr3d(struct vidbuffer *vb); extern void unlockscr3d(struct vidbuffer *vb); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index e72db743..780960bc 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -2250,7 +2250,7 @@ void gui_display (int shortcut) gui_active++; if (isfullscreen() > 0 && currprefs.gfx_api != 1) - screenshot_prepare(); + screenshot_prepare(getfocusedmonitor()); flipgui(1); if (setpaused (7)) { @@ -19204,7 +19204,7 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP AVIOutput_Toggle (!avioutput_requested, false); break; case IDC_SCREENSHOT: - screenshot(0, 1, 0); + screenshot(-1, 1, 0); break; case IDC_AVIOUTPUT_AUDIO: { -- 2.47.3