]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
RP overlay/mouse event updates.
authorToni Wilen <twilen@winuae.net>
Sun, 4 Nov 2018 14:22:25 +0000 (16:22 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 4 Nov 2018 14:22:25 +0000 (16:22 +0200)
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/direct3d11.cpp
od-win32/rp.cpp
od-win32/rp.h
od-win32/win32.cpp

index 1260ae5c7ac89106f3da7eb3c98193fed4b8facd..2dcfc7ded196ae708fabf25158b276d610567cc4 100644 (file)
@@ -2162,6 +2162,8 @@ static void handle_rawinput_2 (RAWINPUT *raw, LPARAM lParam)
 
                if (num == num_mouse)
                        return;
+               if (rp_ismouseevent())
+                       return;
 
                if (isfocus () > 0 || istest) {
                        static int lastx[MAX_INPUT_DEVICES], lasty[MAX_INPUT_DEVICES];
index 6285ca21e1cf89e327c280b7390cc6abf845da1f..66c92c5ee2f68861f369747eed5be996c0dc6c93 100644 (file)
@@ -130,6 +130,8 @@ struct shaderdata
 
 struct d3d9overlay
 {
+       struct d3d9overlay *next;
+       int id;
        int x, y;
        LPDIRECT3DTEXTURE9 tex;
 };
@@ -161,7 +163,7 @@ struct d3dstruct
        float mask2texture_wwx, mask2texture_hhx, mask2texture_minusx, mask2texture_minusy;
        float mask2texture_multx, mask2texture_multy, mask2texture_offsetw;
        LPDIRECT3DTEXTURE9 cursorsurfaced3d;
-       struct d3d9overlay extoverlays[EXTOVERLAYS];
+       struct d3d9overlay *extoverlays;
        IDirect3DVertexBuffer9 *vertexBuffer;
        ID3DXSprite *sprite;
        HWND d3dhwnd;
@@ -2424,13 +2426,15 @@ static void invalidatedeviceobjects (struct d3dstruct *d3d)
                d3d->cursorsurfaced3d->Release ();
                d3d->cursorsurfaced3d = NULL;
        }
-       for (int i = 0; i < EXTOVERLAYS; i++) {
-               struct d3d9overlay *o = &d3d->extoverlays[i];
-               if (o->tex) {
-                       o->tex->Release();
-                       o->tex = NULL;
-               }
+       struct d3d9overlay *ov = d3d->extoverlays;
+       while (ov) {
+               struct d3d9overlay *next = ov->next;
+               if (ov->tex)
+                       ov->tex->Release();
+               xfree(ov);
+               ov = next;
        }
+       d3d->extoverlays = NULL;
        for (int i = 0; i < MAX_SHADERS; i++) {
                if (d3d->shaders[i].pEffect) {
                        d3d->shaders[i].pEffect->Release ();
@@ -3710,14 +3714,15 @@ static void D3D_render2(struct d3dstruct *d3d, int mode)
                        v.z = 0;
                        d3d->sprite->Draw(d3d->ledtexture, NULL, NULL, &v, 0xffffffff);
                }
-               for (int i = 0; i < EXTOVERLAYS; i++) {
-                       struct d3d9overlay *o = &d3d->extoverlays[i];
-                       if (o->tex) {
-                               v.x = o->x;
-                               v.y = o->y;
+               struct d3d9overlay *ov = d3d->extoverlays;
+               while (ov) {
+                       if (ov->tex) {
+                               v.x = ov->x;
+                               v.y = ov->y;
                                v.z = 0;
-                               d3d->sprite->Draw(o->tex, NULL, NULL, &v, 0xffffffff);
+                               d3d->sprite->Draw(ov->tex, NULL, NULL, &v, 0xffffffff);
                        }
+                       ov = ov->next;
                }
                d3d->sprite->End();
        }
@@ -4139,52 +4144,86 @@ static bool xD3D_run(int monid)
 static bool xD3D_extoverlay(struct extoverlay *ext)
 {
        struct d3dstruct *d3d = &d3ddata[0];
+       struct d3d9overlay *ov, *ovprev, *ov2;
+       LPDIRECT3DTEXTURE9 s;
        D3DLOCKED_RECT locked;
        HRESULT hr;
 
-       if (ext->idx >= EXTOVERLAYS)
-               return false;
-
-       write_log(_T("extoverlay %d: x=%d y=%d %d*%d\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height);
+       s = NULL;
+       ov = d3d->extoverlays;
+       ovprev = NULL;
+       while (ov) {
+               if (ov->id == ext->idx) {
+                       s = ov->tex;
+                       break;
+               }
+               ovprev = ov;
+               ov = ov->next;
+       }
 
-       struct d3d9overlay *s = &d3d->extoverlays[ext->idx];
+       write_log(_T("extoverlay %d: x=%d y=%d %d*%d data=%p ovl=%p\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height, ext->data, ov);
 
-       if (!s->tex && (ext->width <= 0 || ext->height <= 0))
+       if (!s && (ext->width <= 0 || ext->height <= 0))
                return false;
 
-       if (!ext->data && s->tex && (ext->width == 0 || ext->height == 0)) {
-               s->x = ext->xpos;
-               s->y = ext->ypos;
+       if (!ext->data && s && (ext->width == 0 || ext->height == 0)) {
+               ov->x = ext->xpos;
+               ov->y = ext->ypos;
                return true;
        }
 
-       if (s->tex) {
-               s->tex->Release();
-               s->tex = NULL;
+       if (ov && s) {
+               if (ovprev) {
+                       ovprev->next = ov->next;
+               } else {
+                       d3d->extoverlays = ov->next;
+               }
+               s->Release();
+               xfree(ov);
+               if (ext->width <= 0 || ext->height <= 0)
+                       return true;
        }
 
        if (ext->width <= 0 || ext->height <= 0)
-               return true;
-
-       s->tex = createtext(d3d, ext->width, ext->height, D3DFMT_A8R8G8B8);
+               return false;
 
-       if (!s->tex)
+       ov = xcalloc(d3d9overlay, 1);
+       s = createtext(d3d, ext->width, ext->height, D3DFMT_A8R8G8B8);
+       if (!s) {
+               xfree(ov);
                return false;
+       }
 
-       s->x = ext->xpos;
-       s->y = ext->ypos;
+       ov->tex = s;
+       ov->id = ext->idx;
 
-       hr = s->tex->LockRect(0, &locked, NULL, 0);
-       if (FAILED(hr)) {
-               write_log(_T("extoverlay LockRect failed %08x\n"), hr);
-               s->tex->Release();
-               s->tex = NULL;
-               return false;
+       ov2 = d3d->extoverlays;
+       ovprev = NULL;
+       for (;;) {
+               if (ov2 == NULL || ov2->id >= ov->id) {
+                       if (ov2 == d3d->extoverlays) {
+                               d3d->extoverlays = ov;
+                               ov->next = ov2;
+                       } else {
+                               ov->next = ovprev->next;
+                               ovprev->next = ov;
+                       }
+                       break;
+               }
+               ovprev = ov2;
+               ov2 = ov2->next;
        }
-       for (int y = 0; y < ext->height; y++) {
-               memcpy((uae_u8*)locked.pBits + y * locked.Pitch, ext->data + y * ext->width * 4, ext->width * 4);
+
+       ov->x = ext->xpos;
+       ov->y = ext->ypos;
+
+       hr = s->LockRect(0, &locked, NULL, 0);
+       if (SUCCEEDED(hr)) {
+               for (int y = 0; y < ext->height; y++) {
+                       memcpy((uae_u8*)locked.pBits + y * locked.Pitch, ext->data + y * ext->width * 4, ext->width * 4);
+               }
+               s->UnlockRect(0);
        }
-       s->tex->UnlockRect(0);
 
        return true;
 }
index 3d2dafa993b7c2f24d79d4cb0144635bde7b1355..9f4ce5e042a15dfd4a40f9efb522167f47ba95c3 100644 (file)
@@ -1,5 +1,4 @@
 
-#define EXTOVERLAYS 4
 struct extoverlay
 {
        int idx;
index dd7bd5da1c56722d8838eac4be0b34789042d774..74221773eda18831ccd53baa84e0a206918c834b 100644 (file)
@@ -193,6 +193,13 @@ struct d3d11sprite
        bool bilinear;
 };
 
+struct d3doverlay
+{
+       struct d3doverlay *next;
+       int id;
+       struct d3d11sprite s;
+};
+
 struct d3d11struct
 {
        IDXGISwapChain1 *m_swapChain;
@@ -273,7 +280,7 @@ struct d3d11struct
        int mask2textureledoffsets[9 * 2];
        struct d3d11sprite blanksprite;
 
-       struct d3d11sprite extoverlays[EXTOVERLAYS];
+       struct d3doverlay *extoverlays;
 
        float mask2texture_w, mask2texture_h, mask2texture_ww, mask2texture_wh;
        float mask2texture_wwx, mask2texture_hhx, mask2texture_minusx, mask2texture_minusy;
@@ -1657,6 +1664,8 @@ static void FreeTexture2D(ID3D11Texture2D **t, ID3D11ShaderResourceView **v)
 
 static void freesprite(struct d3d11sprite *s)
 {
+       if (!s)
+               return;
        FreeTexture2D(&s->texture, &s->texturerv);
 
        if (s->pixelshader)
@@ -1732,10 +1741,14 @@ static void FreeTextures(struct d3d11struct *d3d)
        }
        freesprite(&d3d->mask2textureled_power_dim);
        freesprite(&d3d->blanksprite);
-       for (int i = 0; i < EXTOVERLAYS; i++) {
-               freesprite(&d3d->extoverlays[i]);
-       }
-
+       struct d3doverlay *ov = d3d->extoverlays;
+       while (ov) {
+               struct d3doverlay *next = ov->next;
+               freesprite(&ov->s);
+               xfree(ov);
+               ov = next;
+       }
+       d3d->extoverlays = NULL;
        for (int i = 0; i < MAX_SHADERS; i++) {
                freeshaderdata(&d3d->shaders[i]);
        }
@@ -4238,9 +4251,10 @@ static bool TextureShaderClass_Render(struct d3d11struct *d3d)
 
        RenderSprite(d3d, &d3d->osd);
 
-       for (int i = 0; i < EXTOVERLAYS; i++) {
-               if (d3d->extoverlays[i].enabled)
-                       RenderSprite(d3d, &d3d->extoverlays[i]);
+       struct d3doverlay *ov = d3d->extoverlays;
+       while (ov) {
+               RenderSprite(d3d, &ov->s);
+               ov = ov->next;
        }
 
        return true;
@@ -5016,50 +5030,88 @@ static bool xD3D11_run(int monid)
 static bool xD3D11_extoverlay(struct extoverlay *ext)
 {
        struct d3d11struct *d3d = &d3d11data[0];
+       struct d3doverlay *ov, *ovprev, *ov2;
+       struct d3d11sprite *s;
        D3D11_MAPPED_SUBRESOURCE map;
        HRESULT hr;
 
-       if (ext->idx >= EXTOVERLAYS)
-               return false;
-
-       write_log(_T("extoverlay %d: x=%d y=%d %d*%d data=%p\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height, ext->data);
+       s = NULL;
+       ov = d3d->extoverlays;
+       ovprev = NULL;
+       while (ov) {
+               if (ov->id == ext->idx) {
+                       s = &ov->s;
+                       break;
+               }
+               ovprev = ov;
+               ov = ov->next;
+       }
 
-       struct d3d11sprite *s = &d3d->extoverlays[ext->idx];
+       write_log(_T("extoverlay %d: x=%d y=%d %d*%d data=%p ovl=%p\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height, ext->data, ov);
 
-       if (!s->enabled && (ext->width <= 0 || ext->height <= 0))
+       if (!s && (ext->width <= 0 || ext->height <= 0))
                return false;
 
-       if (!ext->data && s->enabled && (ext->width == 0 || ext->height == 0)) {
+       if (!ext->data && s && (ext->width == 0 || ext->height == 0)) {
                s->x = ext->xpos;
                s->y = ext->ypos;
                return true;
        }
 
-       freesprite(s);
+       if (ov && s) {
+               if (ovprev) {
+                       ovprev->next = ov->next;
+               } else {
+                       d3d->extoverlays = ov->next;
+               }
+               freesprite(s);
+               xfree(ov);
+               if (ext->width <= 0 || ext->height <= 0)
+                       return true;
+       }
 
        if (ext->width <= 0 || ext->height <= 0)
-               return true;
+               return false;
+
+       ov = xcalloc(d3doverlay, 1);
+       s = &ov->s;
 
-       if (!allocsprite(d3d, s, ext->width, ext->height, true))
+       if (!allocsprite(d3d, s, ext->width, ext->height, true)) {
+               xfree(ov);
                return false;
+       }
+
+       ov->id = ext->idx;
+
+       ov2 = d3d->extoverlays;
+       ovprev = NULL;
+       for(;;) {
+               if (ov2 == NULL || ov2->id >= ov->id) {
+                       if (ov2 == d3d->extoverlays) {
+                               d3d->extoverlays = ov;
+                               ov->next = ov2;
+                       } else {
+                               ov->next = ovprev->next;
+                               ovprev->next = ov;
+                       }
+                       break;
+               }
+               ovprev = ov2;
+               ov2 = ov2->next;
+       }
 
        s->enabled = true;
        s->x = ext->xpos;
        s->y = ext->ypos;
 
        hr = d3d->m_deviceContext->Map(s->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
-       if (FAILED(hr)) {
-               write_log(_T("extoverlay Map failed %08x\n"), hr);
-               freesprite(s);
-               return false;
-       }
-
-       for (int y = 0; y < s->height; y++) {
-               memcpy((uae_u8*)map.pData + y * map.RowPitch, ext->data + y * ext->width * 4, ext->width * 4);
+       if (SUCCEEDED(hr)) {
+               for (int y = 0; y < s->height; y++) {
+                       memcpy((uae_u8*)map.pData + y * map.RowPitch, ext->data + y * ext->width * 4, ext->width * 4);
+               }
+               d3d->m_deviceContext->Unmap(s->texture, 0);
        }
 
-       d3d->m_deviceContext->Unmap(s->texture, 0);
-
        return true;
 }
 
index 9a3e61b1ed84589d007f3c529b1d9080dbb8215e..4e3187a74d665b8a702bbf1984cb86236e2f159f 100644 (file)
@@ -1619,7 +1619,9 @@ static void sendfeatures (void)
 
        feat = RP_FEATURE_POWERLED | RP_FEATURE_SCREEN1X | RP_FEATURE_FULLSCREEN;
        feat |= RP_FEATURE_PAUSE | RP_FEATURE_TURBO_CPU | RP_FEATURE_TURBO_FLOPPY | RP_FEATURE_VOLUME | RP_FEATURE_SCREENCAPTURE;
-       feat |= RP_FEATURE_STATE | RP_FEATURE_DEVICEREADWRITE | RP_FEATURE_SCREENOVERLAY;
+       feat |= RP_FEATURE_STATE | RP_FEATURE_DEVICEREADWRITE;
+       if (currprefs.gfx_api)
+               feat |= RP_FEATURE_SCREENOVERLAY;
        if (WIN32GFX_IsPicassoScreen(mon)) {
                if (currprefs.gfx_api)
                        feat |= RP_FEATURE_SCREEN2X | RP_FEATURE_SCREEN3X | RP_FEATURE_SCREEN4X;
@@ -2188,8 +2190,55 @@ USHORT rp_rawbuttons(LPARAM lParam, USHORT usButtonFlags)
        return usButtonFlags;
 }
 
+bool rp_ismouseevent(void)
+{
+       return sendmouseevents != 0;
+}
+
 bool rp_mouseevent(int x, int y, int buttons, int buttonmask)
 {
+#if 0
+       uae_u8 *data;
+       static int ovl_idx = 10;
+       static int ovl_add;
+       if (buttons > 0 && (buttons & 1)) {
+               data = xcalloc(uae_u8, 10 * 10 * 4);
+               for (int i = 0; i < 10 * 10; i++) {
+                       data[i * 4 + 0] = 0xff;
+                       data[i * 4 + 1] = 0xff;
+                       data[i * 4 + 2] = 0x00;
+                       data[i * 4 + 3] = 0xff;
+               }
+
+               struct extoverlay eo = { 0 };
+               eo.idx = ovl_idx;
+               eo.xpos = 100 + ovl_idx * 50;
+               eo.ypos = 100;
+               eo.width = 10;
+               eo.height = 10;
+               eo.data = data;
+               int ret = D3D_extoverlay(&eo);
+               ovl_idx--;
+       }
+       if (buttons > 0 && (buttons & 2)) {
+               struct extoverlay eo = { 0 };
+               ovl_idx++;
+               eo.idx = ovl_idx;
+               eo.width = -1;
+               eo.height = -1;
+               int ret = D3D_extoverlay(&eo);
+       }
+
+       for (int i = 0; i < ovl_idx; i++) {
+               struct extoverlay eo = { 0 };
+               eo.idx = i;
+               eo.xpos = 100 + i * 50;
+               eo.ypos = 100 + ovl_add * (i + 1);
+               int ret = D3D_extoverlay(&eo);
+       }
+       ovl_add++;
+#endif
+
        if (!sendmouseevents) {
                if (x > -30000 && y > -30000) {
                        mouseevent_x = x;
index d1a532c9166c7d95c152019f35f6fd9e4d5fa177..987976a9f5d51421596fdd4c6dfc53910cc21fd0 100644 (file)
@@ -21,6 +21,7 @@ extern void rp_screenmode_changed (void);
 extern void rp_keymap(TrapContext*, uaecptr, uae_u32);
 extern USHORT rp_rawbuttons(LPARAM lParam, USHORT usButtonFlags);
 extern bool rp_mouseevent(int x, int y, int buttons, int buttonmask);
+extern bool rp_ismouseevent(void);
 
 extern TCHAR *rp_param;
 extern int rp_rpescapekey;
index 6fabcef66c78c770ef1548781844ff5c9167a506..34ad3855a26521bd6109ea22397be5a5b6f7d378 100644 (file)
@@ -1880,77 +1880,83 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam,
                return 0;
 
        case WM_LBUTTONUP:
-               rp_mouseevent(-32768, -32768, 0, 1);
-               if (dinput_winmouse() >= 0 && isfocus()) {
-                       if (log_winmouse)
-                               write_log(_T("WM_LBUTTONUP\n"));
-                       setmousebuttonstate(dinput_winmouse(), 0, 0);
+               if (!rp_mouseevent(-32768, -32768, 0, 1)) {
+                       if (dinput_winmouse() >= 0 && isfocus()) {
+                               if (log_winmouse)
+                                       write_log(_T("WM_LBUTTONUP\n"));
+                               setmousebuttonstate(dinput_winmouse(), 0, 0);
+                       }
                }
                return 0;
        case WM_LBUTTONDOWN:
        case WM_LBUTTONDBLCLK:
-               rp_mouseevent(-32768, -32768, 1, 1);
-               if (!mouseactive && !gui_active && (!mousehack_alive() || currprefs.input_tablet != TABLET_MOUSEHACK || (currprefs.input_tablet == TABLET_MOUSEHACK && !(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) || isfullscreen() > 0)) {
-                       // borderless = do not capture with single-click
-                       if (ignorelbutton) {
-                               ignorelbutton = 0;
-                               if (currprefs.win32_borderless)
+               if (!rp_mouseevent(-32768, -32768, 1, 1)) {
+                       if (!mouseactive && !gui_active && (!mousehack_alive() || currprefs.input_tablet != TABLET_MOUSEHACK || (currprefs.input_tablet == TABLET_MOUSEHACK && !(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) || isfullscreen() > 0)) {
+                               // borderless = do not capture with single-click
+                               if (ignorelbutton) {
+                                       ignorelbutton = 0;
+                                       if (currprefs.win32_borderless)
+                                               return 0;
+                               }
+                               if (message == WM_LBUTTONDOWN && isfullscreen() == 0 && currprefs.win32_borderless && !rp_isactive()) {
+                                       // full-window drag
+                                       SendMessage(mon->hAmigaWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
                                        return 0;
+                               }
+                               if (!pause_emulation || currprefs.win32_active_nocapture_pause)
+                                       setmouseactive(mon->monitor_id, (message == WM_LBUTTONDBLCLK || isfullscreen() > 0) ? 2 : 1);
+                       } else if (dinput_winmouse() >= 0 && isfocus()) {
+                               if (log_winmouse)
+                                       write_log(_T("WM_LBUTTONDOWN\n"));
+                               setmousebuttonstate(dinput_winmouse(), 0, 1);
                        }
-                       if (message == WM_LBUTTONDOWN && isfullscreen() == 0 && currprefs.win32_borderless && !rp_isactive()) {
-                               // full-window drag
-                               SendMessage(mon->hAmigaWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
-                               return 0;
-                       }
-                       if (!pause_emulation || currprefs.win32_active_nocapture_pause)
-                               setmouseactive(mon->monitor_id, (message == WM_LBUTTONDBLCLK || isfullscreen() > 0) ? 2 : 1);
-               } else if (dinput_winmouse() >= 0 && isfocus()) {
-                       if (log_winmouse)
-                               write_log(_T("WM_LBUTTONDOWN\n"));
-                       setmousebuttonstate(dinput_winmouse(), 0, 1);
                }
                return 0;
        case WM_RBUTTONUP:
-               rp_mouseevent(-32768, -32768, 0, 2);
-               if (dinput_winmouse() >= 0 && isfocus()) {
-                       if (log_winmouse)
-                               write_log(_T("WM_RBUTTONUP\n"));
-                       setmousebuttonstate(dinput_winmouse(), 1, 0);
+               if (!rp_mouseevent(-32768, -32768, 0, 2)) {
+                       if (dinput_winmouse() >= 0 && isfocus()) {
+                               if (log_winmouse)
+                                       write_log(_T("WM_RBUTTONUP\n"));
+                               setmousebuttonstate(dinput_winmouse(), 1, 0);
+                       }
                }
                return 0;
        case WM_RBUTTONDOWN:
        case WM_RBUTTONDBLCLK:
-               rp_mouseevent(-32768, -32768, 2, 2);
-               if (dinput_winmouse() >= 0 && isfocus() > 0) {
-                       if (log_winmouse)
-                               write_log(_T("WM_RBUTTONDOWN\n"));
-                       setmousebuttonstate(dinput_winmouse(), 1, 1);
+               if (!rp_mouseevent(-32768, -32768, 2, 2)) {
+                       if (dinput_winmouse() >= 0 && isfocus() > 0) {
+                               if (log_winmouse)
+                                       write_log(_T("WM_RBUTTONDOWN\n"));
+                               setmousebuttonstate(dinput_winmouse(), 1, 1);
+                       }
                }
                return 0;
        case WM_MBUTTONUP:
-               rp_mouseevent(-32768, -32768, 0, 4);
-               if (!(currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON)) {
-                       if (log_winmouse)
-                               write_log(_T("WM_MBUTTONUP\n"));
-                       if (dinput_winmouse() >= 0 && isfocus())
-                               setmousebuttonstate(dinput_winmouse(), 2, 0);
+               if (!rp_mouseevent(-32768, -32768, 0, 4)) {
+                       if (!(currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON)) {
+                               if (log_winmouse)
+                                       write_log(_T("WM_MBUTTONUP\n"));
+                               if (dinput_winmouse() >= 0 && isfocus())
+                                       setmousebuttonstate(dinput_winmouse(), 2, 0);
+                       }
                }
                return 0;
        case WM_MBUTTONDOWN:
        case WM_MBUTTONDBLCLK:
-               rp_mouseevent(-32768, -32768, 4, 4);
-               if (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) {
-                       activationtoggle(mon->monitor_id, true);
-               } else {
-                       if (dinput_winmouse() >= 0 && isfocus() > 0) {
-                               if (log_winmouse)
-                                       write_log(_T("WM_MBUTTONDOWN\n"));
-                               setmousebuttonstate(dinput_winmouse(), 2, 1);
+               if (!rp_mouseevent(-32768, -32768, 4, 4)) {
+                       if (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) {
+                               activationtoggle(mon->monitor_id, true);
+                       } else {
+                               if (dinput_winmouse() >= 0 && isfocus() > 0) {
+                                       if (log_winmouse)
+                                               write_log(_T("WM_MBUTTONDOWN\n"));
+                                       setmousebuttonstate(dinput_winmouse(), 2, 1);
+                               }
                        }
                }
                return 0;
        case WM_XBUTTONUP:
-               if (dinput_winmouse() >= 0 && isfocus()) {
+               if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus()) {
                        if (log_winmouse)
                                write_log(_T("WM_XBUTTONUP %08x\n"), wParam);
                        handleXbutton(wParam, 0);
@@ -1959,7 +1965,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam,
                return 0;
        case WM_XBUTTONDOWN:
        case WM_XBUTTONDBLCLK:
-               if (dinput_winmouse() >= 0 && isfocus() > 0) {
+               if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus() > 0) {
                        if (log_winmouse)
                                write_log(_T("WM_XBUTTONDOWN %08x\n"), wParam);
                        handleXbutton(wParam, 1);
@@ -1967,7 +1973,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam,
                }
                return 0;
        case WM_MOUSEWHEEL:
-               if (dinput_winmouse() >= 0 && isfocus() > 0) {
+               if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus() > 0) {
                        int val = ((short)HIWORD(wParam));
                        if (log_winmouse)
                                write_log(_T("WM_MOUSEWHEEL %08x\n"), wParam);
@@ -1980,7 +1986,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam,
                }
                return 0;
        case WM_MOUSEHWHEEL:
-               if (dinput_winmouse() >= 0 && isfocus() > 0) {
+               if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus() > 0) {
                        int val = ((short)HIWORD(wParam));
                        if (log_winmouse)
                                write_log(_T("WM_MOUSEHWHEEL %08x\n"), wParam);