Add support for reparenting, capture and control of Win32 Emulator windows.

ugfx_release_2.6
Andrew Hannam 2016-07-19 18:54:17 +10:00
parent e5f69dbcf4
commit 19e54c88ec
3 changed files with 92 additions and 27 deletions

View File

@ -11,7 +11,11 @@ FEATURE: Added gwinPrintg()
FIX: Fix sprintg and related functions handling of NULL pointers. FIX: Fix sprintg and related functions handling of NULL pointers.
FIX: Fixing width calculation of gdispGDrawString() and gdispGFillString(). FIX: Fixing width calculation of gdispGDrawString() and gdispGFillString().
FEATURE: Added QImage display driver. 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 *** *** Release 2.5 ***

View File

@ -416,6 +416,7 @@
static DWORD winThreadId; static DWORD winThreadId;
static volatile bool_t QReady; static volatile bool_t QReady;
static HANDLE drawMutex; static HANDLE drawMutex;
static HWND hWndParent = 0;
/*===========================================================================*/ /*===========================================================================*/
/* Driver local routines . */ /* Driver local routines . */
@ -438,6 +439,8 @@ typedef struct winPriv {
coord_t mousex, mousey; coord_t mousex, mousey;
uint16_t mousebuttons; uint16_t mousebuttons;
GMouse *mouse; GMouse *mouse;
bool_t mouseenabled;
void (*capfn)(HWND hWnd, GDisplay *g, uint16_t buttons, coord_t x, coord_t y);
#endif #endif
#if GINPUT_NEED_TOGGLE #if GINPUT_NEED_TOGGLE
uint8_t toggles; uint8_t toggles;
@ -448,6 +451,28 @@ typedef struct winPriv {
#endif #endif
} winPriv; } 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) 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; PAINTSTRUCT ps;
GDisplay * g; GDisplay * g;
winPriv * priv; winPriv * priv;
#if GINPUT_NEED_MOUSE
uint16_t btns;
#endif
#if GINPUT_NEED_TOGGLE #if GINPUT_NEED_TOGGLE
HBRUSH hbrOn, hbrOff; HBRUSH hbrOn, hbrOff;
HPEN pen; HPEN pen;
@ -493,7 +521,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
// Handle mouse down on the window // Handle mouse down on the window
#if GINPUT_NEED_MOUSE #if GINPUT_NEED_MOUSE
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
priv->mousebuttons |= GINPUT_MOUSE_BTN_LEFT; btns = priv->mousebuttons;
btns |= GINPUT_MOUSE_BTN_LEFT;
goto mousemove; goto mousemove;
} }
#endif #endif
@ -542,7 +571,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
// Handle mouse up on the window // Handle mouse up on the window
#if GINPUT_NEED_MOUSE #if GINPUT_NEED_MOUSE
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
priv->mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT; btns = priv->mousebuttons;
btns &= ~GINPUT_MOUSE_BTN_LEFT;
goto mousemove; goto mousemove;
} }
#endif #endif
@ -554,7 +584,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
priv = (winPriv *)g->priv; priv = (winPriv *)g->priv;
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE; btns = priv->mousebuttons;
btns |= GINPUT_MOUSE_BTN_MIDDLE;
goto mousemove; goto mousemove;
} }
break; break;
@ -562,7 +593,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
priv = (winPriv *)g->priv; priv = (winPriv *)g->priv;
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE; btns = priv->mousebuttons;
btns &= ~GINPUT_MOUSE_BTN_MIDDLE;
goto mousemove; goto mousemove;
} }
break; break;
@ -570,7 +602,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
priv = (winPriv *)g->priv; priv = (winPriv *)g->priv;
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT; btns = priv->mousebuttons;
btns |= GINPUT_MOUSE_BTN_RIGHT;
goto mousemove; goto mousemove;
} }
break; break;
@ -578,7 +611,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
priv = (winPriv *)g->priv; priv = (winPriv *)g->priv;
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
priv->mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT; btns = priv->mousebuttons;
btns &= ~GINPUT_MOUSE_BTN_RIGHT;
goto mousemove; goto mousemove;
} }
break; break;
@ -587,11 +621,18 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
priv = (winPriv *)g->priv; priv = (winPriv *)g->priv;
if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT) if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT)
break; break;
btns = priv->mousebuttons;
mousemove: mousemove:
priv->mousex = (coord_t)LOWORD(lParam); if (priv->capfn)
priv->mousey = (coord_t)HIWORD(lParam); priv->capfn(hWnd, g, btns, (coord_t)LOWORD(lParam), (coord_t)HIWORD(lParam))
if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE if (priv->mouseenabled) {
_gmouseWakeup(priv->mouse); 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; break;
#endif #endif
@ -758,7 +799,8 @@ static DWORD WINAPI WindowThread(void *param) {
// Create the window // 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, 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); GetModuleHandle(0), g);
assert(msg.hwnd != 0); assert(msg.hwnd != 0);
@ -836,6 +878,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
// Create the associated mouse // Create the associated mouse
#if GINPUT_NEED_MOUSE #if GINPUT_NEED_MOUSE
priv->mouseenabled = hwndParent ? FALSE : TRUE;
priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g); priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g);
#endif #endif

View File

@ -3,16 +3,16 @@
* the license was not distributed with this file, you can obtain one at: * the license was not distributed with this file, you can obtain one at:
* *
* http://ugfx.org/license.html * http://ugfx.org/license.html
*/ */
#ifndef _GDISP_LLD_CONFIG_H #ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H #define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP #if GFX_USE_GDISP
/*===========================================================================*/ /*===========================================================================*/
/* Driver hardware support. */ /* Driver hardware support. */
/*===========================================================================*/ /*===========================================================================*/
// Calling gdispGFlush() is optional for this driver but can be used by the // Calling gdispGFlush() is optional for this driver but can be used by the
// application to force a display update. eg after streaming. // application to force a display update. eg after streaming.
@ -24,7 +24,7 @@
#ifdef GDISP_WIN32_STREAMING_TEST #ifdef GDISP_WIN32_STREAMING_TEST
// These streaming routines are here only to debug the high level gdisp // These streaming routines are here only to debug the high level gdisp
// code for streaming controllers. They are slow, inefficient and have // 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_WRITE TRUE
#define GDISP_HARDWARE_STREAM_READ TRUE #define GDISP_HARDWARE_STREAM_READ TRUE
#define GDISP_HARDWARE_STREAM_POS TRUE #define GDISP_HARDWARE_STREAM_POS TRUE
@ -46,7 +46,25 @@
#endif #endif
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_BGR888 #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_BGR888
#endif /* GFX_USE_GDISP */ // 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.
#endif /* _GDISP_LLD_CONFIG_H */ // 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 */