diff --git a/docs/releases.txt b/docs/releases.txt index 648c9901..1fd4bb01 100644 --- a/docs/releases.txt +++ b/docs/releases.txt @@ -11,7 +11,11 @@ FEATURE: Added gwinPrintg() FIX: Fix sprintg and related functions handling of NULL pointers. FIX: Fixing width calculation of gdispGDrawString() and gdispGFillString(). FEATURE: Added QImage display driver. -FEATURE: Added support for Qt platform +FEATURE: Added support for Qt as a GOS platform +FEATURE: Add ability to set a parent for a win32 ugfx emulator window +FEATURE: Add ability to inject mouse events for a Win32 ugfx emulator window +FEATURE: Add ability to turn on and off mouse processing for a win32 ugfx emulator window +FEATURE: Add ability to capture mouse events on the win32 ugfx emaultor window *** Release 2.5 *** diff --git a/drivers/multiple/Win32/gdisp_lld_Win32.c b/drivers/multiple/Win32/gdisp_lld_Win32.c index 557e4ad0..6ad952a5 100644 --- a/drivers/multiple/Win32/gdisp_lld_Win32.c +++ b/drivers/multiple/Win32/gdisp_lld_Win32.c @@ -416,6 +416,7 @@ static DWORD winThreadId; static volatile bool_t QReady; static HANDLE drawMutex; +static HWND hWndParent = 0; /*===========================================================================*/ /* Driver local routines . */ @@ -438,6 +439,8 @@ typedef struct winPriv { coord_t mousex, mousey; uint16_t mousebuttons; GMouse *mouse; + bool_t mouseenabled; + void (*capfn)(HWND hWnd, GDisplay *g, uint16_t buttons, coord_t x, coord_t y); #endif #if GINPUT_NEED_TOGGLE uint8_t toggles; @@ -448,6 +451,28 @@ typedef struct winPriv { #endif } winPriv; +void gfxEmulatorSetParentWindow(HWND hwnd) { + hWndParent = hwnd; +} + +#if GINPUT_NEED_MOUSE + void gfxEmulatorMouseInject(GDisplay *g, uint16_t buttons, coord_t x, coord_t y) { + winPriv * priv; + + priv = (winPriv *)g->priv; + priv->mouseubttons = buttons; + priv->mousex = x; + priv->mousey = y; + if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE + _gmouseWakeup(priv->mouse); + } + void gfxEmulatorMouseEnable(GDisplay *g, bool_t enabled) { + ((winPriv *)g->priv)->mouseenabled = enabled; + } + void gfxEmulatorMouseCapture(GDisplay *g, void (*capfn)(HWND hWnd, GDisplay *g, uint16_t buttons, coord_t x, coord_t y)) { + ((winPriv *)g->priv)->capfn = capfn; + } +#endif static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { @@ -455,6 +480,9 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) PAINTSTRUCT ps; GDisplay * g; winPriv * priv; + #if GINPUT_NEED_MOUSE + uint16_t btns; + #endif #if GINPUT_NEED_TOGGLE HBRUSH hbrOn, hbrOff; HPEN pen; @@ -493,7 +521,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) // Handle mouse down on the window #if GINPUT_NEED_MOUSE if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { - priv->mousebuttons |= GINPUT_MOUSE_BTN_LEFT; + btns = priv->mousebuttons; + btns |= GINPUT_MOUSE_BTN_LEFT; goto mousemove; } #endif @@ -542,7 +571,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) // Handle mouse up on the window #if GINPUT_NEED_MOUSE if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { - priv->mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT; + btns = priv->mousebuttons; + btns &= ~GINPUT_MOUSE_BTN_LEFT; goto mousemove; } #endif @@ -554,7 +584,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { - priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE; + btns = priv->mousebuttons; + btns |= GINPUT_MOUSE_BTN_MIDDLE; goto mousemove; } break; @@ -562,7 +593,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { - priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE; + btns = priv->mousebuttons; + btns &= ~GINPUT_MOUSE_BTN_MIDDLE; goto mousemove; } break; @@ -570,7 +602,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { - priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT; + btns = priv->mousebuttons; + btns |= GINPUT_MOUSE_BTN_RIGHT; goto mousemove; } break; @@ -578,7 +611,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { - priv->mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT; + btns = priv->mousebuttons; + btns &= ~GINPUT_MOUSE_BTN_RIGHT; goto mousemove; } break; @@ -587,11 +621,18 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT) break; + btns = priv->mousebuttons; + mousemove: - priv->mousex = (coord_t)LOWORD(lParam); - priv->mousey = (coord_t)HIWORD(lParam); - if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE - _gmouseWakeup(priv->mouse); + if (priv->capfn) + priv->capfn(hWnd, g, btns, (coord_t)LOWORD(lParam), (coord_t)HIWORD(lParam)) + if (priv->mouseenabled) { + priv->mousebuttons = btns; + priv->mousex = (coord_t)LOWORD(lParam); + priv->mousey = (coord_t)HIWORD(lParam); + if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE + _gmouseWakeup(priv->mouse); + } break; #endif @@ -758,7 +799,8 @@ static DWORD WINAPI WindowThread(void *param) { // Create the window msg.hwnd = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_BORDER, msg.wParam*DISPLAY_X_OFFSET, msg.wParam*DISPLAY_Y_OFFSET, - rect.right-rect.left, rect.bottom-rect.top, 0, 0, + rect.right-rect.left, rect.bottom-rect.top, + hWndParent, 0, GetModuleHandle(0), g); assert(msg.hwnd != 0); @@ -836,6 +878,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { // Create the associated mouse #if GINPUT_NEED_MOUSE + priv->mouseenabled = hwndParent ? FALSE : TRUE; priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g); #endif diff --git a/drivers/multiple/Win32/gdisp_lld_config.h b/drivers/multiple/Win32/gdisp_lld_config.h index 659dfb77..91891290 100644 --- a/drivers/multiple/Win32/gdisp_lld_config.h +++ b/drivers/multiple/Win32/gdisp_lld_config.h @@ -3,16 +3,16 @@ * the license was not distributed with this file, you can obtain one at: * * http://ugfx.org/license.html - */ - -#ifndef _GDISP_LLD_CONFIG_H -#define _GDISP_LLD_CONFIG_H - -#if GFX_USE_GDISP - -/*===========================================================================*/ -/* Driver hardware support. */ -/*===========================================================================*/ + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ // Calling gdispGFlush() is optional for this driver but can be used by the // application to force a display update. eg after streaming. @@ -24,7 +24,7 @@ #ifdef GDISP_WIN32_STREAMING_TEST // These streaming routines are here only to debug the high level gdisp // code for streaming controllers. They are slow, inefficient and have - // lots of debugging turned on. + // lots of debugging turned on. #define GDISP_HARDWARE_STREAM_WRITE TRUE #define GDISP_HARDWARE_STREAM_READ TRUE #define GDISP_HARDWARE_STREAM_POS TRUE @@ -46,7 +46,25 @@ #endif #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_BGR888 - -#endif /* GFX_USE_GDISP */ - -#endif /* _GDISP_LLD_CONFIG_H */ + +// This function allows you to specify the parent window for any ugfx display windows created. +// Passing a NULL will reset window creation to creating top level windows. +// Note: In order to affect any static displays it must be called BEFORE gfxInit(). +// Note: Creating a window under a parent causes the Mouse to be disabled by default (rather than enabled as for a top window) +void gfxEmulatorSetParentWindow(HWND hwnd); + +#if GINPUT_NEED_MOUSE + // This function allows you to inject mouse events into the ugfx mouse driver + void gfxEmulatorMouseInject(GDisplay *g, uint16_t buttons, coord_t x, coord_t y); + + // This function enables you to turn on/off normal mouse functions on a ugfx Win32 display window. + void gfxEmulatorMouseEnable(GDisplay *g, bool_t enabled); + + // This function enables you to capture mouse events on a ugfx Win32 display window. + // Passing NULL turns off the capture + void gfxEmulatorMouseCapture(GDisplay *g, void (*capfn)(HWND hWnd, GDisplay *g, uint16_t buttons, coord_t x, coord_t y)); +#endif + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */