diff options
| -rw-r--r-- | boards/base/Win32/example/Makefile | 4 | ||||
| -rw-r--r-- | docs/releases.txt | 7 | ||||
| -rw-r--r-- | drivers/gdisp/QImage/driver.mk | 2 | ||||
| -rw-r--r-- | drivers/gdisp/QImage/gdisp_lld_config.h | 21 | ||||
| -rw-r--r-- | drivers/gdisp/QImage/gdisp_lld_driver.c | 64 | ||||
| -rw-r--r-- | drivers/gdisp/QImage/gdisp_lld_qimage.cpp | 38 | ||||
| -rw-r--r-- | drivers/gdisp/QImage/gdisp_lld_qimage.h | 15 | ||||
| -rw-r--r-- | drivers/gdisp/readme.txt | 1 | ||||
| -rw-r--r-- | drivers/multiple/Win32/gdisp_lld_Win32.c | 65 | ||||
| -rw-r--r-- | drivers/multiple/Win32/gdisp_lld_config.h | 48 | ||||
| -rw-r--r-- | gfxconf.example.h | 1 | ||||
| -rw-r--r-- | src/gdisp/gdisp.h | 2 | ||||
| -rw-r--r-- | src/gos/gos.h | 6 | ||||
| -rw-r--r-- | src/gos/gos_options.h | 7 | ||||
| -rw-r--r-- | src/gos/gos_qt.cpp | 222 | ||||
| -rw-r--r-- | src/gos/gos_qt.h | 78 | ||||
| -rw-r--r-- | src/gos/gos_rules.h | 4 | ||||
| -rw-r--r-- | src/gwin/gwin_button.c | 4 | ||||
| -rw-r--r-- | src/gwin/gwin_wm.c | 31 |
19 files changed, 585 insertions, 35 deletions
diff --git a/boards/base/Win32/example/Makefile b/boards/base/Win32/example/Makefile index 0087ca90..5c3f3157 100644 --- a/boards/base/Win32/example/Makefile +++ b/boards/base/Win32/example/Makefile @@ -8,7 +8,7 @@ # See $(GFXLIB)/tools/gmake_scripts/readme.txt for the list of variables # For Win32 this variable can be set to "win32" (native win32 api) or "win32.chibios" (ChibiOS simulator). OPT_OS = win32 - OPT_LINK_OPTIMIZE = yes + OPT_LINK_OPTIMIZE = no # uGFX settings # See $(GFXLIB)/tools/gmake_scripts/library_ugfx.mk for the list of variables @@ -29,7 +29,7 @@ endif # Set these for your project # -ARCH = i686-pc-mingw32- +ARCH = i686-w64-mingw32- SRCFLAGS = -ggdb -O0 CFLAGS = CXXFLAGS = diff --git a/docs/releases.txt b/docs/releases.txt index 11d2549c..3849afa6 100644 --- a/docs/releases.txt +++ b/docs/releases.txt @@ -10,6 +10,13 @@ FIX: Fixing issue in STM32F746G-Discovery board file that resulted in bad color 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 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 +FIX: Fixing issue where children of (nested) containers were not properly handled when callin gwinRaise() *** Release 2.5 *** diff --git a/drivers/gdisp/QImage/driver.mk b/drivers/gdisp/QImage/driver.mk new file mode 100644 index 00000000..dbf3a2b3 --- /dev/null +++ b/drivers/gdisp/QImage/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/gdisp/QImage +GFXSRC += $(GFXLIB)/drivers/gdisp/QImage/gdisp_lld_QImage.c diff --git a/drivers/gdisp/QImage/gdisp_lld_config.h b/drivers/gdisp/QImage/gdisp_lld_config.h new file mode 100644 index 00000000..ae97cfcb --- /dev/null +++ b/drivers/gdisp/QImage/gdisp_lld_config.h @@ -0,0 +1,21 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#pragma once + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE + +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 + +#endif /* GFX_USE_GDISP */ diff --git a/drivers/gdisp/QImage/gdisp_lld_driver.c b/drivers/gdisp/QImage/gdisp_lld_driver.c new file mode 100644 index 00000000..dbd7c279 --- /dev/null +++ b/drivers/gdisp/QImage/gdisp_lld_driver.c @@ -0,0 +1,64 @@ +/*b + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "../../../gfx.h" + +#if GFX_USE_GDISP + +#define GDISP_DRIVER_VMT GDISPVMT_QImage +#include "gdisp_lld_config.h" +#include "../../../src/gdisp/gdisp_driver.h" +#include "gdisp_lld_qimage.h" + +#ifndef GDISP_SCREEN_HEIGHT + #define GDISP_SCREEN_HEIGHT 512 +#endif +#ifndef GDISP_SCREEN_WIDTH + #define GDISP_SCREEN_WIDTH 512 +#endif +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 50 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) +{ + /* No board interface and no private driver area */ + g->priv = g->board = 0; + + if (!qimage_init(g, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT)) { + return FALSE; + } + + /* Initialise the GDISP structure */ + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + + return TRUE; +} + +#if GDISP_HARDWARE_DRAWPIXEL + void gdisp_lld_draw_pixel(GDisplay *g) + { + qimage_setPixel(g); + } +#endif + +#if GDISP_HARDWARE_PIXELREAD + color_t gdisp_lld_get_pixel_color(GDisplay *g) + { + return qimage_getPixel(g); + } +#endif + +#endif /* GFX_USE_GDISP */ diff --git a/drivers/gdisp/QImage/gdisp_lld_qimage.cpp b/drivers/gdisp/QImage/gdisp_lld_qimage.cpp new file mode 100644 index 00000000..a133dfb4 --- /dev/null +++ b/drivers/gdisp/QImage/gdisp_lld_qimage.cpp @@ -0,0 +1,38 @@ +#include <QImage> +#include "../../../gfx.h" +#include "../../../src/gdisp/gdisp_driver.h" +#include "gdisp_lld_qimage.h" + +bool_t qimage_init(GDisplay* g, coord_t width, coord_t height) +{ + QImage* qimage = new QImage(width, height, QImage::Format_RGB888); + if (!qimage) { + return FALSE; + } + qimage->fill(Qt::gray); + + g->priv = qimage; + + return TRUE; +} + +void qimage_setPixel(GDisplay* g) +{ + QImage* qimage = static_cast<QImage*>(g->priv); + if (!qimage) { + return; + } + + QRgb rgbVal = qRgb(RED_OF(g->p.color), GREEN_OF(g->p.color), BLUE_OF(g->p.color)); + qimage->setPixel(g->p.x, g->p.y, rgbVal); +} + +color_t qimage_getPixel(GDisplay* g) +{ + const QImage* qimage = static_cast<const QImage*>(g->priv); + if (!qimage) { + return 0; + } + + return static_cast<color_t>(qimage->pixel(g->p.x, g->p.y)); +} diff --git a/drivers/gdisp/QImage/gdisp_lld_qimage.h b/drivers/gdisp/QImage/gdisp_lld_qimage.h new file mode 100644 index 00000000..9e855f08 --- /dev/null +++ b/drivers/gdisp/QImage/gdisp_lld_qimage.h @@ -0,0 +1,15 @@ +#pragma once + +#include "../../../gfx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool_t qimage_init(GDisplay* g, coord_t width, coord_t height); +void qimage_setPixel(GDisplay* g); +color_t qimage_getPixel(GDisplay* g); + +#ifdef __cplusplus +} +#endif diff --git a/drivers/gdisp/readme.txt b/drivers/gdisp/readme.txt index c7c8b137..a898066b 100644 --- a/drivers/gdisp/readme.txt +++ b/drivers/gdisp/readme.txt @@ -29,6 +29,7 @@ ST7565 - Small monochrome LCD STM32LTDC - STM32 ART graphics STM32F4 and STM32F7 series CPU's TestStub - NULL driver just to test compile TLS8204 - Small monochrome LCD +QImage - Driver that allows rendering into a QImage object (of the Qt framework) uGFXnet - Remote Network display (in drivers/multiple/uGFXnet directory) Win32 - Microsoft Windows (in drivers/multiple/Win32 directory) X - X Windows (Xlib) (in drivers/multiple/X directory) diff --git a/drivers/multiple/Win32/gdisp_lld_Win32.c b/drivers/multiple/Win32/gdisp_lld_Win32.c index 557e4ad0..15a80cd3 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->mousebuttons = 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 */ diff --git a/gfxconf.example.h b/gfxconf.example.h index 37094a62..79ca89b2 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -39,6 +39,7 @@ //#define GFX_USE_OS_CMSIS FALSE //#define GFX_USE_OS_RAW32 FALSE //#define GFX_USE_OS_NIOS FALSE +//#define GFX_USE_OS_QT FALSE // #define INTERRUPTS_OFF() optional_code // #define INTERRUPTS_ON() optional_code diff --git a/src/gdisp/gdisp.h b/src/gdisp/gdisp.h index 64b55c6f..5cb91896 100644 --- a/src/gdisp/gdisp.h +++ b/src/gdisp/gdisp.h @@ -117,7 +117,7 @@ typedef struct GDisplay GDisplay; /** * @brief The default screen to use for the gdispXXXX calls. * @note This is set by default to the first display in the system. You can change - * it by calling @p gdispGSetDisplay(). + * it by calling @p gdispSetDisplay(). */ extern GDisplay *GDISP; diff --git a/src/gos/gos.h b/src/gos/gos.h index f29c2ac9..09b278bc 100644 --- a/src/gos/gos.h +++ b/src/gos/gos.h @@ -494,9 +494,11 @@ #elif GFX_USE_OS_CMSIS #include "gos_cmsis.h" #elif GFX_USE_OS_KEIL - #include "gos_keil.h" + #include "gos_keil.h" #elif GFX_USE_OS_NIOS - #include "gos_nios.h" + #include "gos_nios.h" +#elif GFX_USE_OS_QT + #include "gos_qt.h" #else #error "Your operating system is not supported yet" #endif diff --git a/src/gos/gos_options.h b/src/gos/gos_options.h index 5c051fea..2d3b0d29 100644 --- a/src/gos/gos_options.h +++ b/src/gos/gos_options.h @@ -104,6 +104,13 @@ #ifndef GFX_USE_OS_NIOS #define GFX_USE_OS_NIOS FALSE #endif + /** + * @brief Use Qt + * @details Defaults to FALSE + */ + #ifndef GFX_USE_OS_QT + #define GFX_USE_OS_QT FALSE + #endif /** * @} * diff --git a/src/gos/gos_qt.cpp b/src/gos/gos_qt.cpp new file mode 100644 index 00000000..1708a478 --- /dev/null +++ b/src/gos/gos_qt.cpp @@ -0,0 +1,222 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "../../gfx.h" + +#include <QMutex> +#include <QSemaphore> +#include <QThread> +#include <QElapsedTimer> + +#if GFX_USE_OS_QT + +class Thread : public QThread +{ +public: + typedef threadreturn_t (*fptr)(void* param); + + void setFunction(fptr function, void* param) + { + _function = function; + _param = param; + } + + threadreturn_t returnValue() + { + return _returnValue; + } + + virtual void run() override + { + if (!_function) { + return; + } + + _returnValue = _function(_param); + } + +private: + fptr _function; + void* _param; + threadreturn_t _returnValue; +}; + +static QElapsedTimer _systickTimer; +static QMutex _systemMutex; + +void _gosInit(void) +{ + _systickTimer.start(); +} + +void _gosDeinit(void) +{ +} + +void gfxHalt(const char *msg) +{ + volatile uint32_t dummy; + + (void)msg; + + while(1) { + dummy++; + } +} + +void gfxExit(void) +{ + volatile uint32_t dummy; + + while(1) { + dummy++; + } +} + +void* gfxAlloc(size_t sz) +{ + return malloc(sz); +} + +void gfxFree(void* ptr) +{ + free(ptr); +} + +void gfxYield(void) +{ + QThread::msleep(0); +} + +void gfxSleepMilliseconds(delaytime_t ms) +{ + QThread::msleep(ms); +} + +void gfxSleepMicroseconds(delaytime_t us) +{ + QThread::usleep(us); +} + +systemticks_t gfxSystemTicks(void) +{ + return _systickTimer.elapsed(); +} + +systemticks_t gfxMillisecondsToTicks(delaytime_t ms) +{ + return ms; +} + +void gfxSystemLock(void) +{ + _systemMutex.lock(); +} + +void gfxSystemUnlock(void) +{ + _systemMutex.unlock(); +} + +void gfxMutexInit(gfxMutex *pmutex) +{ + *pmutex = new QMutex; +} + +void gfxMutexDestroy(gfxMutex *pmutex) +{ + delete static_cast<QMutex*>(*pmutex); +} + +void gfxMutexEnter(gfxMutex *pmutex) +{ + static_cast<QMutex*>(*pmutex)->lock(); +} + +void gfxMutexExit(gfxMutex *pmutex) +{ + static_cast<QMutex*>(*pmutex)->unlock(); +} + +void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit) +{ + *psem = new QSemaphore(limit); + + static_cast<QSemaphore*>(*psem)->release(val); +} + +void gfxSemDestroy(gfxSem *psem) +{ + delete static_cast<QSemaphore*>(*psem); +} + +bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) +{ + return static_cast<QSemaphore*>(*psem)->tryAcquire(1, ms); +} + +bool_t gfxSemWaitI(gfxSem *psem) +{ + return static_cast<QSemaphore*>(*psem)->tryAcquire(1); +} + +void gfxSemSignal(gfxSem *psem) +{ + static_cast<QSemaphore*>(*psem)->release(1); +} + +void gfxSemSignalI(gfxSem *psem) +{ + static_cast<QSemaphore*>(*psem)->release(1); +} + +semcount_t gfxSemCounter(gfxSem *psem) +{ + return static_cast<QSemaphore*>(*psem)->available(); +} + +semcount_t gfxSemCounterI(gfxSem *psem) +{ + return static_cast<QSemaphore*>(*psem)->available(); +} + +gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) +{ + Q_UNUSED(stackarea) + + Thread* thread = new Thread; + thread->setFunction(fn, param); + if (stacksz > 0) { + thread->setStackSize(stacksz); + } + thread->start(static_cast<QThread::Priority>(prio)); + + return static_cast<gfxThreadHandle>(thread); +} + +threadreturn_t gfxThreadWait(gfxThreadHandle thread) +{ + Thread* t = static_cast<Thread*>(thread); + + threadreturn_t returnValue = t->returnValue(); + t->wait(); + t->exit(); + + return returnValue; +} + +gfxThreadHandle gfxThreadMe(void) +{ + return static_cast<Thread*>(QThread::currentThread()); +} + +void gfxThreadClose(gfxThreadHandle thread) +{ + static_cast<Thread*>(thread)->exit(); +} + +#endif /* GFX_USE_OS_QT */ diff --git a/src/gos/gos_qt.h b/src/gos/gos_qt.h new file mode 100644 index 00000000..9986d7f2 --- /dev/null +++ b/src/gos/gos_qt.h @@ -0,0 +1,78 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GOS_QT_H +#define _GOS_QT_H + +#if GFX_USE_OS_QT + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param) +#define DECLARE_THREAD_STACK(name, sz) uint8_t name[0] +#define THREAD_RETURN(retval) return retval + +#define TIME_IMMEDIATE 0 +#define TIME_INFINITE ((delaytime_t)-1) +#define MAX_SEMAPHORE_COUNT ((semcount_t)(((unsigned long)((semcount_t)(-1))) >> 1)) +#define LOW_PRIORITY 2 +#define NORMAL_PRIORITY 3 +#define HIGH_PRIORITY 4 + +typedef bool bool_t; +typedef int systemticks_t; +typedef int delaytime_t; +typedef void* gfxMutex; +typedef void* gfxSem; +typedef int semcount_t; +typedef int threadreturn_t; +typedef int threadpriority_t; +typedef void* gfxThreadHandle; + +#ifdef __cplusplus +extern "C" { +#endif + +void _gosInit(); +void _gosDeinit(); + +void gfxHalt(const char* msg); +void gfxExit(void); +void* gfxAlloc(size_t sz); +void gfxFree(void* ptr); +void gfxYield(void); +void gfxSleepMilliseconds(delaytime_t ms); +void gfxSleepMicroseconds(delaytime_t us); +systemticks_t gfxSystemTicks(void); +systemticks_t gfxMillisecondsToTicks(delaytime_t ms); +void gfxSystemLock(void); +void gfxSystemUnlock(void); +void gfxMutexInit(gfxMutex *pmutex); +void gfxMutexDestroy(gfxMutex *pmutex); +void gfxMutexEnter(gfxMutex *pmutex); +void gfxMutexExit(gfxMutex *pmutex); +void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit); +void gfxSemDestroy(gfxSem *psem); +bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); +bool_t gfxSemWaitI(gfxSem *psem); +void gfxSemSignal(gfxSem *psem); +void gfxSemSignalI(gfxSem *psem); +semcount_t gfxSemCounter(gfxSem *psem); +semcount_t gfxSemCounterI(gfxSem *psem); +gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); +threadreturn_t gfxThreadWait(gfxThreadHandle thread); +gfxThreadHandle gfxThreadMe(void); +void gfxThreadClose(gfxThreadHandle thread); + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_OS_QT */ +#endif /* _GOS_QT_H */ diff --git a/src/gos/gos_rules.h b/src/gos/gos_rules.h index 1a0cf760..b4b8e445 100644 --- a/src/gos/gos_rules.h +++ b/src/gos/gos_rules.h @@ -16,11 +16,11 @@ #ifndef _GOS_RULES_H #define _GOS_RULES_H -#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS && !GFX_USE_OS_ECOS && !GFX_USE_OS_RAWRTOS && !GFX_USE_OS_ARDUINO && !GFX_USE_OS_CMSIS && !GFX_USE_OS_KEIL && !GFX_USE_OS_NIOS +#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS && !GFX_USE_OS_ECOS && !GFX_USE_OS_RAWRTOS && !GFX_USE_OS_ARDUINO && !GFX_USE_OS_CMSIS && !GFX_USE_OS_KEIL && !GFX_USE_OS_NIOS && !GFX_USE_OS_QT #error "GOS: No operating system has been defined." #endif -#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS + GFX_USE_OS_ECOS + GFX_USE_OS_RAWRTOS + GFX_USE_OS_ARDUINO + GFX_USE_OS_CMSIS + GFX_USE_OS_KEIL + GFX_USE_OS_NIOS != 1 * TRUE +#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS + GFX_USE_OS_ECOS + GFX_USE_OS_RAWRTOS + GFX_USE_OS_ARDUINO + GFX_USE_OS_CMSIS + GFX_USE_OS_KEIL + GFX_USE_OS_NIOS + GFX_USE_OS_QT != 1 * TRUE #error "GOS: More than one operation system has been defined as TRUE." #endif diff --git a/src/gwin/gwin_button.c b/src/gwin/gwin_button.c index c96d3cdd..41c736e6 100644 --- a/src/gwin/gwin_button.c +++ b/src/gwin/gwin_button.c @@ -238,9 +238,9 @@ static const GColorSet *getButtonColors(GWidgetObject *gw) { pcol = getButtonColors(gw); gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background); - gdispGFillEllipse(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->fill); + gdispGFillEllipse(gw->g.display, gw->g.x+gw->g.width/2, gw->g.y+gw->g.height/2, gw->g.width/2-2, gw->g.height/2-2, pcol->fill); gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); - gdispGDrawEllipse(gw->g.display, gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->edge); + gdispGDrawEllipse(gw->g.display, gw->g.x+gw->g.width/2, gw->g.y+gw->g.height/2, gw->g.width/2-1, gw->g.height/2-1, pcol->edge); } #endif diff --git a/src/gwin/gwin_wm.c b/src/gwin/gwin_wm.c index 6bc5013b..9f5010b2 100644 --- a/src/gwin/gwin_wm.c +++ b/src/gwin/gwin_wm.c @@ -988,6 +988,37 @@ static void WM_Raise(GHandle gh) { gfxQueueASyncRemove(&_GWINList, &gh->wmq); gfxQueueASyncPut(&_GWINList, &gh->wmq); + #if GWIN_NEED_CONTAINERS + // Any children need to be raised too + if ((gh->flags & GWIN_FLG_CONTAINER)) { + GHandle gx = gh; + GHandle child; + bool_t restart; + + // Raise the children too + // Note: Children can also have their own children so after each move we have to start again. + for (gx = gwinGetNextWindow(0); gx; gx = gwinGetNextWindow(gx)) { + if ((gx->flags & GWIN_FLG_CONTAINER)) { + restart = FALSE; + for (child = gwinGetNextWindow(0); child && child != gx; child = gwinGetNextWindow(child)) { + if (child->parent == gx) { + // Oops - this child is behind its parent. Move it to the front. + gfxQueueASyncRemove(&_GWINList, &child->wmq); + gfxQueueASyncPut(&_GWINList, &child->wmq); + + // Restart at the front of the list for this parent container as we have moved this child + // to the end of the list. We also need to restart everything once this container is done. + child = 0; + restart = TRUE; + } + } + if (restart) + gx = 0; + } + } + } + #endif + // Redraw the window _gwinUpdate(gh); } |
