aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--boards/base/Win32/example/Makefile4
-rw-r--r--docs/releases.txt7
-rw-r--r--drivers/gdisp/QImage/driver.mk2
-rw-r--r--drivers/gdisp/QImage/gdisp_lld_config.h21
-rw-r--r--drivers/gdisp/QImage/gdisp_lld_driver.c64
-rw-r--r--drivers/gdisp/QImage/gdisp_lld_qimage.cpp38
-rw-r--r--drivers/gdisp/QImage/gdisp_lld_qimage.h15
-rw-r--r--drivers/gdisp/readme.txt1
-rw-r--r--drivers/multiple/Win32/gdisp_lld_Win32.c65
-rw-r--r--drivers/multiple/Win32/gdisp_lld_config.h48
-rw-r--r--gfxconf.example.h1
-rw-r--r--src/gdisp/gdisp.h2
-rw-r--r--src/gos/gos.h6
-rw-r--r--src/gos/gos_options.h7
-rw-r--r--src/gos/gos_qt.cpp222
-rw-r--r--src/gos/gos_qt.h78
-rw-r--r--src/gos/gos_rules.h4
-rw-r--r--src/gwin/gwin_button.c4
-rw-r--r--src/gwin/gwin_wm.c31
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);
}