aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gadc/driver.h190
-rw-r--r--src/gadc/gadc.c2
-rw-r--r--src/gadc/sys_defs.h270
-rw-r--r--src/gadc/sys_make.mk (renamed from src/gadc/gadc.mk)2
-rw-r--r--src/gadc/sys_options.h42
-rw-r--r--src/gadc/sys_rules.h30
-rw-r--r--src/gaudin/driver.h102
-rw-r--r--src/gaudin/gaudin.c2
-rw-r--r--src/gaudin/sys_defs.h174
-rw-r--r--src/gaudin/sys_make.mk (renamed from src/gaudin/gaudin.mk)2
-rw-r--r--src/gaudin/sys_options.h32
-rw-r--r--src/gaudin/sys_rules.h30
-rw-r--r--src/gaudout/sys_defs.h45
-rw-r--r--src/gaudout/sys_make.mk (renamed from src/gaudout/gaudout.mk)2
-rw-r--r--src/gaudout/sys_options.h32
-rw-r--r--src/gaudout/sys_rules.h23
-rw-r--r--src/gdisp/colors.h377
-rw-r--r--src/gdisp/driver.h873
-rw-r--r--src/gdisp/fonts/build_fonts.sh2
-rw-r--r--src/gdisp/fonts/fonts.h34
-rw-r--r--src/gdisp/gdisp.c2
-rw-r--r--src/gdisp/image.h307
-rw-r--r--src/gdisp/mcufont/mf_config.h4
-rw-r--r--src/gdisp/sys_defs.h994
-rw-r--r--src/gdisp/sys_make.mk (renamed from src/gdisp/gdisp.mk)0
-rw-r--r--src/gdisp/sys_options.h381
-rw-r--r--src/gdisp/sys_rules.h85
-rw-r--r--src/gevent/sys_defs.h234
-rw-r--r--src/gevent/sys_make.mk (renamed from src/gevent/gevent.mk)2
-rw-r--r--src/gevent/sys_options.h55
-rw-r--r--src/gevent/sys_rules.h23
-rw-r--r--src/gfile/gfile.c12
-rw-r--r--src/gfile/sys_defs.h169
-rw-r--r--src/gfile/sys_make.mk (renamed from src/gfile/gfile.mk)0
-rw-r--r--src/gfile/sys_options.h158
-rw-r--r--src/gfile/sys_rules.h23
-rw-r--r--src/ginput/dial.c2
-rw-r--r--src/ginput/dial.h111
-rw-r--r--src/ginput/driver_dial.h45
-rw-r--r--src/ginput/driver_mouse.h178
-rw-r--r--src/ginput/driver_toggle.h61
-rw-r--r--src/ginput/keyboard.h128
-rw-r--r--src/ginput/mouse.c2
-rw-r--r--src/ginput/mouse.h181
-rw-r--r--src/ginput/sys_defs.h50
-rw-r--r--src/ginput/sys_make.mk (renamed from src/ginput/ginput.mk)10
-rw-r--r--src/ginput/sys_options.h114
-rw-r--r--src/ginput/sys_rules.h37
-rw-r--r--src/ginput/toggle.c2
-rw-r--r--src/ginput/toggle.h100
-rw-r--r--src/gmisc/sys_defs.h212
-rw-r--r--src/gmisc/sys_make.mk (renamed from src/gmisc/gmisc.mk)6
-rw-r--r--src/gmisc/sys_options.h85
-rw-r--r--src/gmisc/sys_rules.h23
-rw-r--r--src/gos/chibios.h100
-rw-r--r--src/gos/linux.h94
-rw-r--r--src/gos/osx.h94
-rw-r--r--src/gos/raw32.h125
-rw-r--r--src/gos/sys_defs.h445
-rw-r--r--src/gos/sys_make.mk (renamed from src/gos/gos.mk)0
-rw-r--r--src/gos/sys_options.h67
-rw-r--r--src/gos/sys_rules.h31
-rw-r--r--src/gos/win32.h106
-rw-r--r--src/gqueue/sys_defs.h264
-rw-r--r--src/gqueue/sys_make.mk (renamed from src/gqueue/gqueue.mk)0
-rw-r--r--src/gqueue/sys_options.h53
-rw-r--r--src/gqueue/sys_rules.h23
-rw-r--r--src/gtimer/sys_defs.h180
-rw-r--r--src/gtimer/sys_make.mk (renamed from src/gtimer/gtimer.mk)2
-rw-r--r--src/gtimer/sys_options.h46
-rw-r--r--src/gtimer/sys_rules.h29
-rw-r--r--src/gwin/button.c2
-rw-r--r--src/gwin/button.h138
-rw-r--r--src/gwin/checkbox.c2
-rw-r--r--src/gwin/checkbox.h116
-rw-r--r--src/gwin/class_gwin.h216
-rw-r--r--src/gwin/console.c2
-rw-r--r--src/gwin/console.h172
-rw-r--r--src/gwin/gimage.c2
-rw-r--r--src/gwin/graph.c2
-rw-r--r--src/gwin/graph.h186
-rw-r--r--src/gwin/gwidget.c2
-rw-r--r--src/gwin/gwidget.h308
-rw-r--r--src/gwin/gwin.c2
-rw-r--r--src/gwin/gwm.c2
-rw-r--r--src/gwin/image.h127
-rw-r--r--src/gwin/label.c2
-rw-r--r--src/gwin/label.h72
-rw-r--r--src/gwin/list.c2
-rw-r--r--src/gwin/list.h287
-rw-r--r--src/gwin/progressbar.c2
-rw-r--r--src/gwin/progressbar.h190
-rw-r--r--src/gwin/radio.c2
-rw-r--r--src/gwin/radio.h142
-rw-r--r--src/gwin/slider.c2
-rw-r--r--src/gwin/slider.h155
-rw-r--r--src/gwin/sys_defs.h863
-rw-r--r--src/gwin/sys_make.mk (renamed from src/gwin/gwin.mk)0
-rw-r--r--src/gwin/sys_options.h185
-rw-r--r--src/gwin/sys_rules.h99
100 files changed, 10945 insertions, 58 deletions
diff --git a/src/gadc/driver.h b/src/gadc/driver.h
new file mode 100644
index 00000000..4427f4f0
--- /dev/null
+++ b/src/gadc/driver.h
@@ -0,0 +1,190 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gadc/driver.h
+ * @brief GADC - Periodic ADC driver header file.
+ *
+ * @defgroup Driver Driver
+ * @ingroup GADC
+ * @{
+ */
+
+#ifndef _GADC_LLD_H
+#define _GADC_LLD_H
+
+#include "gfx.h"
+
+#if GFX_USE_GADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/**
+ * @brief The structure passed to start a timer conversion
+ * @note We use the structure instead of parameters purely to save
+ * interrupt stack space which is very limited in some platforms.
+ * @{
+ */
+typedef struct GadcLldTimerData_t {
+ uint32_t physdev; /* @< A value passed to describe which physical ADC devices/channels to use. */
+ adcsample_t *buffer; /* @< The static buffer to put the ADC samples into. */
+ size_t count; /* @< The number of conversions to do before doing a callback and stopping the ADC. */
+ bool_t now; /* @< Trigger the first conversion now rather than waiting for the first timer interrupt (if possible) */
+ } GadcLldTimerData;
+/* @} */
+
+/**
+ * @brief The structure passed to start a non-timer conversion
+ * @note We use the structure instead of parameters purely to save
+ * interrupt stack space which is very limited in some platforms.
+ * @{
+ */
+typedef struct GadcLldNonTimerData_t {
+ uint32_t physdev; /* @< A value passed to describe which physical ADC devices/channels to use. */
+ adcsample_t *buffer; /* @< The static buffer to put the ADC samples into. */
+ } GadcLldNonTimerData;
+/* @} */
+
+/**
+ * @brief These routines are the callbacks that the driver uses.
+ * @details Defined in the high level GADC code.
+ *
+ * @notapi
+ * @{
+ */
+
+/**
+ * @param[in] adcp The ADC driver
+ * @param[in] buffer The sample buffer
+ * @param[in] n The amount of samples
+ */
+extern void GADC_ISR_CompleteI(ADCDriver *adcp, adcsample_t *buffer, size_t n);
+
+/**
+ * @param[in] adcp The ADC driver
+ * @param[in] err ADC error
+ */
+extern void GADC_ISR_ErrorI(ADCDriver *adcp, adcerror_t err);
+/**
+ * @}
+ */
+
+/**
+ * @brief This can be incremented by the low level driver if a timer interrupt is missed.
+ * @details Defined in the high level GADC code.
+ *
+ * @notapi
+ */
+extern volatile bool_t GADC_Timer_Missed;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise the driver
+ *
+ * @api
+ */
+void gadc_lld_init(void);
+
+/**
+ * @brief Get the number of samples in a conversion.
+ * @details Calculates and returns the number of samples per conversion for the specified physdev.
+ *
+ * @note A physdev describing a mono device would return 1, a stereo device would return 2.
+ * For most ADC's physdev is a bitmap so it is only a matter of counting the bits.
+ *
+ * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
+ *
+ * @return Number of samples of the convesion
+ * @api
+ */
+size_t gadc_lld_samples_per_conversion(uint32_t physdev);
+
+/**
+ * @brief Start a periodic timer for high frequency conversions.
+ *
+ * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
+ * @param[in] frequency The frequency to create ADC conversions
+ *
+ * @note The exact meaning of physdev is hardware dependent. It describes the channels
+ * the will be used later on when a "timer" conversion is actually scheduled.
+ * @note It is assumed that the timer is capable of free-running even when the ADC
+ * is stopped or doing something else.
+ * @details When a timer interrupt occurs a conversion should start if these is a "timer" conversion
+ * active.
+ * @note If the ADC is stopped, doesn't have a "timer" conversion active or is currently executing
+ * a non-timer conversion then the interrupt can be ignored other than (optionally) incrementing
+ * the GADC_Timer_Missed variable.
+ *
+ * @api
+ */
+void gadc_lld_start_timer(uint32_t physdev, uint32_t frequency);
+
+/**
+ * @brief Stop the periodic timer for high frequency conversions.
+ * @details Also stops any current "timer" conversion (but not a current "non-timer" conversion).
+ *
+ * @param[in] physdev A value passed to describe which physical ADC devices/channels in use.
+ *
+ * @note The exact meaning of physdev is hardware dependent.
+ *
+ * @api
+ */
+void gadc_lld_stop_timer(uint32_t physdev);
+
+/**
+ * @brief Start a "timer" conversion.
+ * @details Starts a series of conversions triggered by the timer.
+ *
+ * @param[in] pgtd Contains the parameters for the timer conversion.
+ *
+ * @note The exact meaning of physdev is hardware dependent. It is likely described in the
+ * drivers gadc_lld_config.h
+ * @note Some versions of ChibiOS actually call the callback function more than once, once
+ * at the half-way point and once on completion. The high level code handles this.
+ * @note The driver should call @p GADC_ISR_CompleteI() when it completes the operation
+ * (or at the half-way point), or @p GAD_ISR_ErrorI() on an error.
+ * @note The high level code ensures that this is not called while a non-timer conversion is in
+ * progress
+ *
+ * @iclass
+ */
+void gadc_lld_adc_timerI(GadcLldTimerData *pgtd);
+
+/**
+ * @brief Start a "non-timer" conversion.
+ * @details Starts a single conversion now.
+ *
+ * @param[in] pgntd Contains the parameters for the non-timer conversion.
+ *
+ * @note The exact meaning of physdev is hardware dependent. It is likely described in the
+ * drivers gadc_lld_config.h
+ * @note The driver should call @p GADC_ISR_CompleteI() when it completes the operation
+ * or @p GAD_ISR_ErrorI() on an error.
+ * @note The high level code ensures that this is not called while a timer conversion is in
+ * progress
+ *
+ * @iclass
+ */
+void gadc_lld_adc_nontimerI(GadcLldNonTimerData *pgntd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GADC */
+
+#endif /* _GADC_LLD_H */
+/** @} */
diff --git a/src/gadc/gadc.c b/src/gadc/gadc.c
index c9a4a31b..8ae431b0 100644
--- a/src/gadc/gadc.c
+++ b/src/gadc/gadc.c
@@ -17,7 +17,7 @@
#if GFX_USE_GADC
/* Include the driver defines */
-#include "gadc/lld/gadc_lld.h"
+#include "src/gadc/driver.h"
#if GADC_MAX_HIGH_SPEED_SAMPLERATE > GADC_MAX_SAMPLE_FREQUENCY/2
#error "GADC: GADC_MAX_HIGH_SPEED_SAMPLERATE has been set too high. It must be less than half the maximum CPU rate"
diff --git a/src/gadc/sys_defs.h b/src/gadc/sys_defs.h
new file mode 100644
index 00000000..f6349dfe
--- /dev/null
+++ b/src/gadc/sys_defs.h
@@ -0,0 +1,270 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gadc/sys_defs.h
+ *
+ * @addtogroup GADC
+ *
+ * @brief Module to abstract the very variable ADC interfaces of the underlying systems
+ *
+ * @details The reason why ChibiOS/GFX has it's own ADC abstraction is because
+ * the Chibi-OS drivers are very CPU specific and do not
+ * provide a way across all hardware platforms to create periodic
+ * ADC conversions. There are also issues with devices with different
+ * characteristics or periodic requirements on the same ADC
+ * device (but different channels). This layer attempts to solve these
+ * problems to provide a architecture neutral API. It also provides extra
+ * features such as multi-buffer chaining for high speed ADC sources.
+ * It provides one high speed virtual ADC device (eg a microphone) and
+ * numerous low speed (less than 100Hz) virtual ADC devices (eg dials,
+ * temperature sensors etc). The high speed device has timer based polling
+ * to ensure exact conversion periods and a buffer management system.
+ * The low speed devices are assumed to be non-critical timing devices
+ * and do not have any buffer management.
+ * Note that while only one high speed device has been provided it can
+ * be used to read multiple physical ADC channels on the one physical
+ * ADC device.
+ * All callback routines are thread based unlike the Chibi-OS interrupt based
+ * routines.
+ *
+ * @{
+ */
+
+#ifndef _GADC_H
+#define _GADC_H
+
+#include "gfx.h"
+
+#if GFX_USE_GADC || defined(__DOXYGEN__)
+
+/* Include the driver defines */
+#include "gadc_lld_config.h"
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+// Event types for GADC
+#define GEVENT_ADC (GEVENT_GADC_FIRST+0)
+
+/**
+ * @brief The High Speed ADC event structure.
+ * @{
+ */
+typedef struct GEventADC_t {
+ #if GFX_USE_GEVENT || defined(__DOXYGEN__)
+ /**
+ * @brief The type of this event (GEVENT_ADC)
+ */
+ GEventType type;
+ #endif
+
+ /**
+ * @brief The event flags
+ */
+ uint16_t flags;
+ /**
+ * @brief The event flag values.
+ * @{
+ */
+ #define GADC_HSADC_LOSTEVENT 0x0001 /**< @brief The last GEVENT_HSDADC event was lost */
+ /** @} */
+ /**
+ * @brief The number of conversions in the buffer
+ */
+ size_t count;
+ /**
+ * @brief The buffer containing the conversion samples
+ */
+ adcsample_t *buffer;
+} GEventADC;
+/** @} */
+
+/**
+ * @brief A callback function (executed in a thread context) for a low speed conversion
+ */
+typedef void (*GADCCallbackFunction)(adcsample_t *buffer, void *param);
+
+/**
+ * @brief A callback function (executed in an ISR context) for a high speed conversion
+ */
+typedef void (*GADCISRCallbackFunction)(adcsample_t *buffer, size_t size);
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise the high speed ADC.
+ * @details Initialises but does not start the conversions.
+ *
+ * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
+ * @param[in] frequency The frequency to create ADC conversions
+ * @param[in] buffer The static buffer to put the ADC samples into.
+ * @param[in] bufcount The total number of conversions that will fit in the buffer.
+ * @param[in] samplesPerEvent The number of conversions to do before returning an event.
+ *
+ * @note If the high speed ADC is running it will be stopped. The Event subsystem is
+ * disconnected from the high speed ADC and any binary semaphore event is forgotten.
+ * @note bufcount must be greater than countPerEvent (usually 2 or more times) otherwise
+ * the buffer will be overwritten with new data while the application is still trying
+ * to process the old data.
+ * @note Due to a bug/feature in Chibi-OS countPerEvent must be even. If bufcount is not
+ * evenly divisable by countPerEvent, the remainder must also be even.
+ * @note The physdev parameter may be used to turn on more than one ADC channel.
+ * Each channel is then interleaved into the provided buffer. Note 'bufcount'
+ * and 'countPerEvent' parameters describe the number of conversions not the
+ * number of samples.
+ * As an example, if physdev turns on 2 devices then the buffer contains
+ * alternate device samples and the buffer must contain 2 * bufcount samples.
+ * The exact meaning of physdev is hardware dependent.
+ * @note The buffer is circular. When the end of the buffer is reached it will start
+ * putting data into the beginning of the buffer again.
+ * @note The event listener must process the event (and the data in it) before the
+ * next event occurs. If not, the following event will be lost.
+ * @note If bufcount is evenly divisable by countPerEvent, then every event will return
+ * countPerEvent conversions. If bufcount is not evenly divisable, it will return
+ * a block of samples containing less than countPerEvent samples when it reaches the
+ * end of the buffer.
+ * @note While the high speed ADC is running, low speed conversions can only occur at
+ * the frequency of the high speed events. Thus if high speed events are
+ * being created at 50Hz (eg countPerEvent = 100, frequency = 5kHz) then the maximum
+ * frequency for low speed conversions will be 50Hz.
+ *
+ * @api
+ */
+void gadcHighSpeedInit(uint32_t physdev, uint32_t frequency, adcsample_t *buffer, size_t bufcount, size_t samplesPerEvent);
+
+#if GFX_USE_GEVENT || defined(__DOXYGEN__)
+ /**
+ * @brief Turn on sending results to the GEVENT sub-system.
+ * @details Returns a GSourceHandle to listen for GEVENT_ADC events.
+ *
+ * @note The high speed ADC will not use the GEVENT system unless this is
+ * called first. This saves processing time if the application does
+ * not want to use the GEVENT sub-system for the high speed ADC.
+ * Once turned on it can only be turned off by calling @p gadcHighSpeedInit() again.
+ * @note The high speed ADC is capable of signalling via this method, an ISR callback and a
+ * binary semaphore at the same time.
+ *
+ * @return The GSourceHandle
+ *
+ * @api
+ */
+ GSourceHandle gadcHighSpeedGetSource(void);
+#endif
+
+/**
+ * @brief Allow retrieving of results from the high speed ADC using an ISR callback.
+ *
+ * @param[in] isrfn The callback function (called in an ISR context).
+ *
+ * @note Passing a NULL for isrfn will turn off signalling via this method as will calling
+ * @p gadcHighSpeedInit().
+ * @note The high speed ADC is capable of signalling via this method, a binary semaphore and the GEVENT
+ * sub-system at the same time.
+ *
+ * @api
+ */
+void gadcHighSpeedSetISRCallback(GADCISRCallbackFunction isrfn);
+
+/**
+ * @brief Allow retrieving of results from the high speed ADC using a Binary Semaphore and a static event buffer.
+ *
+ * @param[in] pbsem The semaphore is signaled when data is available.
+ * @param[in] pEvent The static event buffer to place the result information.
+ *
+ * @note Passing a NULL for pbsem or pEvent will turn off signalling via this method as will calling
+ * @p gadcHighSpeedInit().
+ * @note The high speed ADC is capable of signalling via this method, an ISR callback and the GEVENT
+ * sub-system at the same time.
+ *
+ * @api
+ */
+void gadcHighSpeedSetBSem(gfxSem *pbsem, GEventADC *pEvent);
+
+/**
+ * @brief Start the high speed ADC conversions.
+ * @pre It must have been initialised first with @p gadcHighSpeedInit()
+ *
+ * @api
+ */
+void gadcHighSpeedStart(void);
+
+/**
+ * @brief Stop the high speed ADC conversions.
+ *
+ * @api
+ */
+void gadcHighSpeedStop(void);
+
+/**
+ * @brief Perform a single low speed ADC conversion
+ * @details Blocks until the conversion is complete
+ * @pre This should not be called from within a GTimer callback as this routine
+ * blocks until the conversion is ready.
+ *
+ * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
+ * @param[in] buffer The static buffer to put the ADC samples into.
+ *
+ * @note This may take a while to complete if the high speed ADC is running as the
+ * conversion is interleaved with the high speed ADC conversions on a buffer
+ * completion.
+ * @note The result buffer must be large enough to store one sample per device
+ * described by the 'physdev' parameter.
+ * @note If calling this routine would exceed @p GADC_MAX_LOWSPEED_DEVICES simultaneous low
+ * speed devices, the routine will wait for an available slot to complete the
+ * conversion.
+ * @note Specifying more than one device in physdev is possible but discouraged as the
+ * calculations to ensure the high speed ADC correctness will be incorrect. Symptoms
+ * from over-running the high speed ADC include high speed samples being lost.
+ *
+ * @api
+ */
+void gadcLowSpeedGet(uint32_t physdev, adcsample_t *buffer);
+
+/**
+ * @brief Perform a low speed ADC conversion with callback (in a thread context)
+ * @details Returns FALSE if there are no free low speed ADC slots. See @p GADC_MAX_LOWSPEED_DEVICES for details.
+ *
+ * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
+ * @param[in] buffer The static buffer to put the ADC samples into.
+ * @param[in] fn The callback function to call when the conversion is complete.
+ * @param[in] param A parameter to pass to the callback function.
+ *
+ * @return FALSE if no free low speed ADC slots.
+ *
+ * @note This may be safely called from within a GTimer callback.
+ * @note The callback may take a while to occur if the high speed ADC is running as the
+ * conversion is interleaved with the high speed ADC conversions on a buffer
+ * completion.
+ * @note The result buffer must be large enough to store one sample per device
+ * described by the 'physdev' parameter.
+ * @note As this routine uses a low speed ADC, it asserts if you try to run more than @p GADC_MAX_LOWSPEED_DEVICES
+ * at the same time.
+ * @note Specifying more than one device in physdev is possible but discouraged as the
+ * calculations to ensure the high speed ADC correctness will be incorrect. Symptoms
+ * from over-running the high speed ADC include high speed samples being lost.
+ *
+ * @api
+ */
+bool_t gadcLowSpeedStart(uint32_t physdev, adcsample_t *buffer, GADCCallbackFunction fn, void *param);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GADC */
+
+#endif /* _GADC_H */
+/** @} */
+
diff --git a/src/gadc/gadc.mk b/src/gadc/sys_make.mk
index cfe04177..05b1e9cc 100644
--- a/src/gadc/gadc.mk
+++ b/src/gadc/sys_make.mk
@@ -1 +1 @@
-GFXSRC += $(GFXLIB)/src/gadc/gadc.c
+GFXSRC += $(GFXLIB)/src/gadc/gadc.c
diff --git a/src/gadc/sys_options.h b/src/gadc/sys_options.h
new file mode 100644
index 00000000..d9519c39
--- /dev/null
+++ b/src/gadc/sys_options.h
@@ -0,0 +1,42 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gadc/sys_options.h
+ * @brief GADC - Periodic ADC subsystem options header file.
+ *
+ * @addtogroup GADC
+ * @{
+ */
+
+#ifndef _GADC_OPTIONS_H
+#define _GADC_OPTIONS_H
+
+/**
+ * @name GADC Functionality to be included
+ * @{
+ */
+/**
+ * @}
+ *
+ * @name GADC Optional Sizing Parameters
+ * @{
+ */
+ /**
+ * @brief The maximum GADC sample rate
+ * @details Defaults to 44000
+ * @note This value must be less than half the maximum sample rate allowed by the CPU.
+ * This is to ensure there is time between high speed samples to perform low
+ * speed device sampling.
+ */
+ #ifndef GADC_MAX_HIGH_SPEED_SAMPLERATE
+ #define GADC_MAX_HIGH_SPEED_SAMPLERATE 44000
+ #endif
+/** @} */
+
+#endif /* _GADC_OPTIONS_H */
+/** @} */
diff --git a/src/gadc/sys_rules.h b/src/gadc/sys_rules.h
new file mode 100644
index 00000000..7272337e
--- /dev/null
+++ b/src/gadc/sys_rules.h
@@ -0,0 +1,30 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gadc/sys_rules.h
+ * @brief GADC safety rules header file.
+ *
+ * @addtogroup GADC
+ * @{
+ */
+
+#ifndef _GADC_RULES_H
+#define _GADC_RULES_H
+
+#if GFX_USE_GADC
+ #if !GFX_USE_GTIMER
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GADC: GFX_USE_GTIMER is required if GFX_USE_GADC is TRUE. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GTIMER
+ #define GFX_USE_GTIMER TRUE
+ #endif
+#endif
+
+#endif /* _GADC_RULES_H */
+/** @} */
diff --git a/src/gaudin/driver.h b/src/gaudin/driver.h
new file mode 100644
index 00000000..bd04858a
--- /dev/null
+++ b/src/gaudin/driver.h
@@ -0,0 +1,102 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudin/driver.h
+ * @brief GAUDIN - Audio Input driver header file.
+ *
+ * @defgroup Driver Driver
+ * @ingroup GAUDIN
+ * @{
+ */
+
+#ifndef _GAUDIN_LLD_H
+#define _GAUDIN_LLD_H
+
+#include "gfx.h"
+
+#if GFX_USE_GAUDIN || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/**
+ * @brief The structure passed to start a audio conversion
+ * @note We use the structure instead of parameters purely to save
+ * interrupt stack space which is very limited in some platforms.
+ * @{
+ */
+typedef struct gaudin_params_t {
+ uint16_t channel;
+ uint32_t frequency;
+ audin_sample_t *buffer;
+ size_t bufcount;
+ size_t samplesPerEvent;
+ } gaudin_params;
+/** @} */
+
+/**
+ * @brief These routines are the callbacks that the driver uses.
+ * @details Defined in the high level GAUDIN code.
+ *
+ * @iclass
+ * @notapi
+ *
+ * @{
+ */
+
+/**
+ * @param[in] buffer The buffer
+ * @param[in] n The amount of samples
+ * */
+extern void GAUDIN_ISR_CompleteI(audin_sample_t *buffer, size_t n);
+
+extern void GAUDIN_ISR_ErrorI(void);
+/**
+ * @}
+ */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise the driver
+ *
+ * @param[in] paud Initialisation parameters
+ *
+ * @api
+ */
+void gaudin_lld_init(const gaudin_params *paud);
+
+/**
+ * @brief Start the audio input sampling
+ *
+ * @api
+ */
+void gadc_lld_start(void);
+
+/**
+ * @brief Stop the audio input sampling
+ *
+ * @api
+ */
+void gadc_lld_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GADC */
+
+#endif /* _GADC_LLD_H */
+/** @} */
diff --git a/src/gaudin/gaudin.c b/src/gaudin/gaudin.c
index 8a425a10..c9ed1c7f 100644
--- a/src/gaudin/gaudin.c
+++ b/src/gaudin/gaudin.c
@@ -17,7 +17,7 @@
#if GFX_USE_GAUDIN
/* Include the driver defines */
-#include "gaudin/lld/gaudin_lld.h"
+#include "src/gaudin/driver.h"
static gaudin_params aud;
static gfxSem *paudSem;
diff --git a/src/gaudin/sys_defs.h b/src/gaudin/sys_defs.h
new file mode 100644
index 00000000..3f06fa6e
--- /dev/null
+++ b/src/gaudin/sys_defs.h
@@ -0,0 +1,174 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudin/sys_defs.h
+ *
+ * @addtogroup GAUDIN
+ *
+ * @brief Module to read audio inputs
+ *
+ * @{
+ */
+
+#ifndef _GAUDIN_H
+#define _GAUDIN_H
+
+#include "gfx.h"
+
+#if GFX_USE_GAUDIN || defined(__DOXYGEN__)
+
+/* Include the driver defines */
+#include "gaudin_lld_config.h"
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+// Event types for GAUDIN
+#define GEVENT_AUDIO_IN (GEVENT_GAUDIN_FIRST+0)
+
+/**
+ * @brief The Audio Input event structure.
+ * @{
+ */
+typedef struct GEventAudioIn_t {
+ #if GFX_USE_GEVENT || defined(__DOXYGEN__)
+ /**
+ * @brief The type of this event (GEVENT_AUDIO_IN)
+ */
+ GEventType type;
+ #endif
+ /**
+ * @brief The current channel
+ */
+ uint16_t channel;
+ /**
+ * @brief The event flags
+ */
+ uint16_t flags;
+ /**
+ * @brief The event flag values.
+ * @{
+ */
+ #define GADC_AUDIO_IN_LOSTEVENT 0x0001 /**< @brief The last GEVENT_AUDIO_IN event was lost */
+ /** @} */
+ /**
+ * @brief The number of audio samples in the buffer
+ */
+ size_t count;
+ /**
+ * @brief The buffer containing the audio samples
+ */
+ audin_sample_t *buffer;
+} GEventAudioIn;
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise (but not start) the Audio Input Subsystem.
+ * @details Returns FALSE for an invalid channel or other invalid parameter.
+ *
+ * @param[in] channel The channel to convert. Can be set from 0 to GAUDIN_NUM_CHANNELS - 1.
+ * @param[in] frequency The sample frequency
+ * @param[in] buffer The static buffer to put the samples into.
+ * @param[in] bufcount The total number of conversions that will fit in the buffer.
+ * @param[in] samplesPerEvent The number of conversions to do before returning an event.
+ *
+ * @note Only one channel is active at a time. If an audio input is running it will be stopped.
+ * The Event subsystem is disconnected from the audio subsystem and any binary semaphore
+ * event is forgotten.
+ * @note Some channels may be stereo channels which return twice as much sample data with
+ * the left and right channel data interleaved. Other channels may be mono channels.
+ * Where stereo channels exist it would be common for the low level driver to also
+ * offer the left and right channels separately.
+ * @note Due to a bug in Chibi-OS countPerEvent must be even if using the GADC low level audio driver.
+ * If bufcount is not evenly divisable by countPerEvent, the remainder must also be even.
+ * This requirement may not apply to other GAUDIN drivers.
+ * @note The number of samples for stereo devices will be double the number of conversions.
+ * Make sure you allocate your buffers large enough. Each channel is then interleaved
+ * into the provided buffer. Note 'bufcount' and 'countPerEvent' parameters describe the
+ * number of conversions not the number of samples.
+ * @note The buffer is circular. When the end of the buffer is reached it will start
+ * putting data into the beginning of the buffer again.
+ * @note The event listener must process the event (and the data in it) before the
+ * next event occurs. If not, the following event will be lost.
+ * @note If bufcount is evenly divisable by countPerEvent, then every event will return
+ * countPerEvent conversions. If bufcount is not evenly divisable, it will return
+ * a block of samples containing less than countPerEvent samples when it reaches the
+ * end of the buffer.
+ *
+ * @return FALSE if invalid channel or parameter
+ *
+ * @api
+ */
+bool_t gaudinInit(uint16_t channel, uint32_t frequency, audin_sample_t *buffer, size_t bufcount, size_t samplesPerEvent);
+
+#if GFX_USE_GEVENT || defined(__DOXYGEN__)
+ /**
+ * @brief Turn on sending results to the GEVENT sub-system.
+ * @details Returns a GSourceHandle to listen for GEVENT_AUDIO_IN events.
+ *
+ * @note The audio input will not use the GEVENT system unless this is
+ * called first. This saves processing time if the application does
+ * not want to use the GEVENT sub-system for audio input.
+ * Once turned on it can only be turned off by calling @p gadcHighSpeedInit() again.
+ * @note The audio input is capable of signalling via this method and a binary semaphore
+ * at the same time.
+ *
+ * @return The GSourceHandle
+ *
+ * @api
+ */
+ GSourceHandle gaudinGetSource(void);
+#endif
+
+/**
+ * @brief Allow retrieving of results from the audio input using a Binary Semaphore and a static event buffer.
+ *
+ * @param[in] pbsem The semaphore is signaled when data is available.
+ * @param[in] pEvent The static event buffer to place the result information.
+ *
+ * @note Passing a NULL for pbsem or pEvent will turn off signalling via this method.
+ * @note The audio input is capable of signalling via this method and the GEVENT
+ * sub-system at the same time.
+ *
+ * @api
+ */
+void gaudinSetBSem(gfxSem *pbsem, GEventAudioIn *pEvent);
+
+/**
+ * @brief Start the audio input conversions.
+ * @pre It must have been initialised first with @p gaudinInit()
+ *
+ * @api
+ */
+void gaudinStart(void);
+
+/**
+ * @brief Stop the audio input conversions.
+ *
+ * @api
+ */
+void gaudinStop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GAUDIN */
+
+#endif /* _GAUDIN_H */
+/** @} */
+
diff --git a/src/gaudin/gaudin.mk b/src/gaudin/sys_make.mk
index f134d264..16bb33b7 100644
--- a/src/gaudin/gaudin.mk
+++ b/src/gaudin/sys_make.mk
@@ -1 +1 @@
-GFXSRC += $(GFXLIB)/src/gaudin/gaudin.c
+GFXSRC += $(GFXLIB)/src/gaudin/gaudin.c
diff --git a/src/gaudin/sys_options.h b/src/gaudin/sys_options.h
new file mode 100644
index 00000000..305a6f8d
--- /dev/null
+++ b/src/gaudin/sys_options.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudin/sys_options.h
+ * @brief GAUDIN - Audio Input subsystem options header file.
+ *
+ * @addtogroup GAUDIN
+ * @{
+ */
+
+#ifndef _GAUDIN_OPTIONS_H
+#define _GAUDIN_OPTIONS_H
+
+/**
+ * @name GAUDIN Functionality to be included
+ * @{
+ */
+/**
+ * @}
+ *
+ * @name GAUDIN Optional Sizing Parameters
+ * @{
+ */
+/** @} */
+
+#endif /* _GAUDIN_OPTIONS_H */
+/** @} */
diff --git a/src/gaudin/sys_rules.h b/src/gaudin/sys_rules.h
new file mode 100644
index 00000000..21d2552f
--- /dev/null
+++ b/src/gaudin/sys_rules.h
@@ -0,0 +1,30 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudin/sys_rules.h
+ * @brief GAUDIN safety rules header file.
+ *
+ * @addtogroup GAUDIN
+ * @{
+ */
+
+#ifndef _GAUDIN_RULES_H
+#define _GAUDIN_RULES_H
+
+#if GFX_USE_GAUDIN
+ #if GFX_USE_GEVENT && !GFX_USE_GTIMER
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GAUDIN: GFX_USE_GTIMER is required if GFX_USE_GAUDIN and GFX_USE_GEVENT are TRUE. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GTIMER
+ #define GFX_USE_GTIMER TRUE
+ #endif
+#endif
+
+#endif /* _GAUDIN_RULES_H */
+/** @} */
diff --git a/src/gaudout/sys_defs.h b/src/gaudout/sys_defs.h
new file mode 100644
index 00000000..f22d269c
--- /dev/null
+++ b/src/gaudout/sys_defs.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudout/sys_defs.h
+ *
+ * @addtogroup GAUDOUT
+ *
+ * @brief Module to output audio data (under development)
+ *
+ * @{
+ */
+
+#ifndef _GAUDOUT_H
+#define _GAUDOUT_H
+
+#include "gfx.h"
+
+#if GFX_USE_GAUDOUT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GAUDOUT */
+
+#endif /* _GAUDOUT_H */
+/** @} */
+
diff --git a/src/gaudout/gaudout.mk b/src/gaudout/sys_make.mk
index 004306bc..14f5bac3 100644
--- a/src/gaudout/gaudout.mk
+++ b/src/gaudout/sys_make.mk
@@ -1 +1 @@
-GFXSRC += $(GFXLIB)/src/gaudout/gaudout.c
+GFXSRC += $(GFXLIB)/src/gaudout/gaudout.c
diff --git a/src/gaudout/sys_options.h b/src/gaudout/sys_options.h
new file mode 100644
index 00000000..929bb42a
--- /dev/null
+++ b/src/gaudout/sys_options.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudout/sys_options.h
+ * @brief GAUDOUT - Audio Output subsystem options header file.
+ *
+ * @addtogroup GAUDOUT
+ * @{
+ */
+
+#ifndef _GAUDOUT_OPTIONS_H
+#define _GAUDOUT_OPTIONS_H
+
+/**
+ * @name GAUDOUT Functionality to be included
+ * @{
+ */
+/**
+ * @}
+ *
+ * @name GAUDOUT Optional Sizing Parameters
+ * @{
+ */
+/** @} */
+
+#endif /* _GAUDOUT_OPTIONS_H */
+/** @} */
diff --git a/src/gaudout/sys_rules.h b/src/gaudout/sys_rules.h
new file mode 100644
index 00000000..50b9a442
--- /dev/null
+++ b/src/gaudout/sys_rules.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gaudout/sys_rules.h
+ * @brief GAUDOUT safety rules header file.
+ *
+ * @addtogroup GAUDOUT
+ * @{
+ */
+
+#ifndef _GAUDOUT_RULES_H
+#define _GAUDOUT_RULES_H
+
+#if GFX_USE_GAUDOUT
+#endif
+
+#endif /* _GAUDOUT_RULES_H */
+/** @} */
diff --git a/src/gdisp/colors.h b/src/gdisp/colors.h
new file mode 100644
index 00000000..efd7076c
--- /dev/null
+++ b/src/gdisp/colors.h
@@ -0,0 +1,377 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gdisp/colors.h
+ * @brief GDISP color definitions header file.
+ *
+ * @defgroup Colors Colors
+ * @ingroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_COLORS_H
+#define _GDISP_COLORS_H
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP || defined(__DOXYGEN__)
+
+/**
+ * For pixel formats we do some assignment of codes to enable
+ * format auto-calculation. (Undocumented).
+ * 0x2RGB TRUECOLOR RGB format, R = red bits, G = green bits, B = blue bits
+ * 0x3RGB TRUECOLOR BGR format, R = red bits, G = green bits, B = blue bits
+ * 0x40XX GRAYSCALE XX = bits
+ * 0x60XX PALLETTE XX = bits
+ * 0x8XXX CUSTOM format.
+ */
+#define GDISP_COLORSYSTEM_MASK 0xF000
+#define GDISP_COLORSYSTEM_RGB 0x2000
+#define GDISP_COLORSYSTEM_BGR 0x3000
+
+/**
+ * @brief Color Type Constants
+ * @{
+ */
+#define GDISP_COLORSYSTEM_TRUECOLOR 0x2000
+#define GDISP_COLORSYSTEM_GRAYSCALE 0x4000
+#define GDISP_COLORSYSTEM_PALETTE 0x6000
+/** @} */
+
+/**
+ * @brief Pixel Format Constants
+ * @{
+ */
+#define GDISP_PIXELFORMAT_MONO (GDISP_COLORSYSTEM_GRAYSCALE|0x0001)
+#define GDISP_PIXELFORMAT_GRAY4 (GDISP_COLORSYSTEM_GRAYSCALE|0x0002)
+#define GDISP_PIXELFORMAT_GRAY16 (GDISP_COLORSYSTEM_GRAYSCALE|0x0004)
+#define GDISP_PIXELFORMAT_GRAY256 (GDISP_COLORSYSTEM_GRAYSCALE|0x0008)
+#define GDISP_PIXELFORMAT_RGB565 (GDISP_COLORSYSTEM_RGB|0x0565)
+#define GDISP_PIXELFORMAT_BGR565 (GDISP_COLORSYSTEM_BGR|0x0565)
+#define GDISP_PIXELFORMAT_RGB888 (GDISP_COLORSYSTEM_RGB|0x0888)
+#define GDISP_PIXELFORMAT_BGR888 (GDISP_COLORSYSTEM_BGR|0x0888)
+#define GDISP_PIXELFORMAT_RGB444 (GDISP_COLORSYSTEM_RGB|0x0444)
+#define GDISP_PIXELFORMAT_BGR444 (GDISP_COLORSYSTEM_BGR|0x0444)
+#define GDISP_PIXELFORMAT_RGB332 (GDISP_COLORSYSTEM_RGB|0x0332)
+#define GDISP_PIXELFORMAT_BGR332 (GDISP_COLORSYSTEM_BGR|0x0332)
+#define GDISP_PIXELFORMAT_RGB666 (GDISP_COLORSYSTEM_RGB|0x0666)
+#define GDISP_PIXELFORMAT_BGR666 (GDISP_COLORSYSTEM_BGR|0x0666)
+#define GDISP_PIXELFORMAT_ERROR 0x0000
+/** @} */
+
+/**
+ * @name Some basic colors
+ * @{
+ */
+#define White HTML2COLOR(0xFFFFFF)
+#define Black HTML2COLOR(0x000000)
+#define Gray HTML2COLOR(0x808080)
+#define Grey Gray
+#define Blue HTML2COLOR(0x0000FF)
+#define Red HTML2COLOR(0xFF0000)
+#define Fuchsia HTML2COLOR(0xFF00FF)
+#define Magenta Fuchsia
+#define Green HTML2COLOR(0x008000)
+#define Yellow HTML2COLOR(0xFFFF00)
+#define Aqua HTML2COLOR(0x00FFFF)
+#define Cyan Aqua
+#define Lime HTML2COLOR(0x00FF00)
+#define Maroon HTML2COLOR(0x800000)
+#define Navy HTML2COLOR(0x000080)
+#define Olive HTML2COLOR(0x808000)
+#define Purple HTML2COLOR(0x800080)
+#define Silver HTML2COLOR(0xC0C0C0)
+#define Teal HTML2COLOR(0x008080)
+#define Orange HTML2COLOR(0xFFA500)
+#define Pink HTML2COLOR(0xFFC0CB)
+#define SkyBlue HTML2COLOR(0x87CEEB)
+/** @} */
+
+#if defined(__DOXYGEN__)
+ /**
+ * @brief The color system (grayscale, palette or truecolor)
+ */
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+ /**
+ * @brief The number of bits in a color value
+ */
+ #define COLOR_BITS 16
+ /**
+ * @brief The number of bits for each of red, green and blue
+ * @{
+ */
+ #define COLOR_BITS_R 5
+ #define COLOR_BITS_G 6
+ #define COLOR_BITS_B 5
+ /** @} */
+ /**
+ * @brief The number of bits to shift each of red, green and blue to put it in the correct place in the color
+ * @{
+ */
+ #define COLOR_SHIFT_R 11
+ #define COLOR_SHIFT_G 5
+ #define COLOR_SHIFT_B 0
+ /** @} */
+ /**
+ * @brief Does the color need masking to remove invalid bits
+ */
+ #define COLOR_NEEDS_MASK FALSE
+ /**
+ * @brief If the color needs masking to remove invalid bits, this is the mask
+ */
+ #define COLOR_MASK 0xFFFF
+ /**
+ * @brief The color type
+ * @{
+ */
+ #define COLOR_TYPE uint16_t
+ /** @} */
+ /**
+ * @brief The number of bits in the color type (not necessarily the same as COLOR_BITS).
+ */
+ #define COLOR_TYPE_BITS 16
+ /**
+ * @brief Convert a luminance (0 to 255) into a color value.
+ * @note The word "Luma" is used instead of grey or gray due to the spelling ambiguities of the word grey
+ * @note This is not a weighted luminance conversion in the color tv style.
+ * @note @p LUMA2COLOR() uses a linear conversion (0.33R + 0.33G + 0.33B). Note this is different to color
+ * tv luminance (0.26126R + 0.7152G + 0.0722B), digital tv luminance of (0.299R + 0.587G + 0.114B), or
+ * @p LUMA_OF() which uses (0.25R + 0.5G + 0.25B).
+ */
+ #define LUMA2COLOR(l) ((color_t)((((l) & 0xF8)<<8) | (((l) & 0xFC)<<3) | (((l) & 0xF8)>>3)))
+ /**
+ * @brief Convert red, green, blue (each 0 to 255) into a color value.
+ */
+ #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
+ /**
+ * @brief Convert a 6 digit HTML code (hex) into a color value.
+ */
+ #define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
+ /**
+ * @brief Extract the luma/red/green/blue component (0 to 255) of a color value.
+ * @note This uses quick and dirty bit shifting. If you want more exact colors
+ * use @p EXACT_RED_OF() etc which uses multiplies and divides. For constant
+ * colors using @p EXACT_RED_OF() is no more expensive because the compiler
+ * evaluates the arithmetic.
+ * @note @p LUMA_OF() returns a roughly weighted luminance (0.25R + 0.5G + 0.25B). Note this is
+ * different to @p LUMA2COLOR() which uses a linear conversion (0.33R + 0.33G + 0.33B) and
+ * color tv luminance of (0.26126R + 0.7152G + 0.0722B) and digital tv luminance of (0.299R + 0.587G + 0.114B).
+ * @note A 5 bit color component maximum value (0x1F) converts to 0xF8 (slightly off-color)
+ * @{
+ */
+ #define LUMA_OF(c) ((RED_OF(c)+((uint16_t)GREEN_OF(c)<<1)+BLUE_OF(c))>>2)
+ #define RED_OF(c) (((c) & 0xF800)>>8)
+ #define GREEN_OF(c) (((c)&0x007E)>>3)
+ #define BLUE_OF(c) (((c)&0x001F)<<3)
+ /** @} */
+ /**
+ * @brief Extract the exact luma/red/green/blue component (0 to 255) of a color value.
+ * @note This uses multiplies and divides rather than bit shifting.
+ * This gives exact equivalent colors at the expense of more cpu intensive
+ * operations. Note for constants this is no more expensive than @p REF_OF()
+ * because the compiler evaluates the arithmetic.
+ * @note @p EXACT_LUMA_OF() returns a roughly weighted luminance (0.25R + 0.5G + 0.25B). Note this is
+ * different to @p LUMA2COLOR() which uses a linear conversion (0.33R + 0.33G + 0.33B) and
+ * color tv luminance of (0.26126R + 0.7152G + 0.0722B) and digital tv luminance of (0.299R + 0.587G + 0.114B).
+ * @note A 5 bit color component maximum value (0x1F) converts to 0xFF (the true equivalent color)
+ * @{
+ */
+ #define EXACT_LUMA_OF(c) ((EXACT_RED_OF(c)+((uint16_t)EXACT_GREEN_OF(c)<<1)+EXACT_BLUE_OF(c))>>2)
+ #define EXACT_RED_OF(c) (((((c)>>11)&0x1F)*255)/31)
+ #define EXACT_GREEN_OF(c) (((((c)>>5)&0x3F)*255)/63)
+ #define EXACT_BLUE_OF(c) (((((c)>>0)&0x1F)*255)/31)
+ /** @} */
+#endif
+
+/*
+ * We use this big mess of macros to calculate all the components
+ * to prevent user errors in the color definitions. It greatly simplifies
+ * the above definitions and ensures a consistent implementation.
+ */
+
+//-------------------------
+// True-Color color system
+//-------------------------
+#if GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+
+ // Calculate the number of bits
+ #define COLOR_BITS_R ((GDISP_PIXELFORMAT>>8) & 0x0F)
+ #define COLOR_BITS_G ((GDISP_PIXELFORMAT>>4) & 0x0F)
+ #define COLOR_BITS_B ((GDISP_PIXELFORMAT>>0) & 0x0F)
+ #define COLOR_BITS (COLOR_BITS_R + COLOR_BITS_G + COLOR_BITS_B)
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if COLOR_BITS <= 8
+ #define COLOR_TYPE uint8_t
+ #define COLOR_TYPE_BITS 8
+ #elif COLOR_BITS <= 16
+ #define COLOR_TYPE uint16_t
+ #define COLOR_TYPE_BITS 16
+ #elif COLOR_BITS <= 32
+ #define COLOR_TYPE uint32_t
+ #define COLOR_TYPE_BITS 32
+ #else
+ #error "GDISP: Cannot define color types with more than 32 bits"
+ #endif
+ #if COLOR_TYPE_BITS == COLOR_BITS
+ #define COLOR_NEEDS_MASK FALSE
+ #else
+ #define COLOR_NEEDS_MASK TRUE
+ #endif
+ #define COLOR_MASK() ((1 << COLOR_BITS)-1)
+
+ // Calculate the component bit shifts
+ #if (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
+ #define COLOR_SHIFT_R (COLOR_BITS_B+COLOR_BITS_G)
+ #define COLOR_SHIFT_G COLOR_BITS_B
+ #define COLOR_SHIFT_B 0
+ #else
+ #define COLOR_SHIFT_B (COLOR_BITS_R+COLOR_BITS_G)
+ #define COLOR_SHIFT_G COLOR_BITS_R
+ #define COLOR_SHIFT_R 0
+ #endif
+
+ // Calculate RED_OF, GREEN_OF, BLUE_OF and RGB2COLOR
+ #if COLOR_BITS_R + COLOR_SHIFT_R == 8
+ #define RED_OF(c) ((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R))
+ #define RGB2COLOR_R(r) ((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1))))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 8
+ #define RED_OF(c) (((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) >> (COLOR_BITS_R+COLOR_SHIFT_R-8))
+ #define RGB2COLOR_R(r) (((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) << (COLOR_BITS_R+COLOR_SHIFT_R-8))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 8
+ #define RED_OF(c) (((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) << (8-(COLOR_BITS_R+COLOR_SHIFT_R)))
+ #define RGB2COLOR_R(r) (((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) >> (8-(COLOR_BITS_R+COLOR_SHIFT_R)))
+ #endif
+ #if COLOR_BITS_G + COLOR_SHIFT_G == 8
+ #define GREEN_OF(c) ((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G))
+ #define RGB2COLOR_G(g) ((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1))))
+ #elif COLOR_BITS_G + COLOR_SHIFT_G > 8
+ #define GREEN_OF(c) (((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) >> (COLOR_BITS_G+COLOR_SHIFT_G-8))
+ #define RGB2COLOR_G(g) (((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) << (COLOR_BITS_G+COLOR_SHIFT_G-8))
+ #else // COLOR_BITS_G + COLOR_SHIFT_G < 8
+ #define GREEN_OF(c) (((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) << (8-(COLOR_BITS_G+COLOR_SHIFT_G)))
+ #define RGB2COLOR_G(g) (((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) >> (8-(COLOR_BITS_G+COLOR_SHIFT_G)))
+ #endif
+ #if COLOR_BITS_B + COLOR_SHIFT_B == 8
+ #define BLUE_OF(c) ((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B))
+ #define RGB2COLOR_B(b) ((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))))
+ #elif COLOR_BITS_B + COLOR_SHIFT_B > 8
+ #define BLUE_OF(c) (((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) >> (COLOR_BITS_B+COLOR_SHIFT_B-8))
+ #define RGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) << (COLOR_BITS_B+COLOR_SHIFT_B-8))
+ #else // COLOR_BITS_B + COLOR_SHIFT_B < 8
+ #define BLUE_OF(c) (((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) << (8-(COLOR_BITS_B+COLOR_SHIFT_B)))
+ #define RGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) >> (8-(COLOR_BITS_B+COLOR_SHIFT_B)))
+ #endif
+ #define LUMA_OF(c) ((RED_OF(c)+((uint16_t)GREEN_OF(c)<<1)+BLUE_OF(c))>>2)
+ #define EXACT_RED_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_R)&((1<<COLOR_BITS_R)-1))*255)/((1<<COLOR_BITS_R)-1))
+ #define EXACT_GREEN_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_G)&((1<<COLOR_BITS_G)-1))*255)/((1<<COLOR_BITS_G)-1))
+ #define EXACT_BLUE_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_B)&((1<<COLOR_BITS_B)-1))*255)/((1<<COLOR_BITS_B)-1))
+ #define EXACT_LUMA_OF(c) ((EXACT_RED_OF(c)+((uint16_t)EXACT_GREEN_OF(c)<<1)+EXACT_BLUE_OF(c))>>2)
+ #define LUMA2COLOR(l) (RGB2COLOR_R(l) | RGB2COLOR_G(l) | RGB2COLOR_B(l))
+ #define RGB2COLOR(r,g,b) (RGB2COLOR_R(r) | RGB2COLOR_G(g) | RGB2COLOR_B(b))
+
+ // Calculate HTML2COLOR
+ #if COLOR_BITS_R + COLOR_SHIFT_R == 24
+ #define HTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
+ #define HTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) << (COLOR_BITS_R+COLOR_SHIFT_R-24))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
+ #define HTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) >> (24-(COLOR_BITS_R+COLOR_SHIFT_R)))
+ #endif
+ #if COLOR_BITS_G + COLOR_SHIFT_G == 16
+ #define HTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8))
+ #elif COLOR_BITS_G + COLOR_SHIFT_G > 16
+ #define HTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) << (COLOR_BITS_G+COLOR_SHIFT_G-16))
+ #else // COLOR_BITS_G + COLOR_SHIFT_G < 16
+ #define HTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) >> (16-(COLOR_BITS_G+COLOR_SHIFT_G)))
+ #endif
+ #if COLOR_BITS_B + COLOR_SHIFT_B == 8
+ #define HTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))
+ #elif COLOR_BITS_B + COLOR_SHIFT_B > 8
+ #define HTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) << (COLOR_BITS_B+COLOR_SHIFT_B-8))
+ #else // COLOR_BITS_B + COLOR_SHIFT_B < 8
+ #define HTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) >> (8-(COLOR_BITS_B+COLOR_SHIFT_B)))
+ #endif
+ #define HTML2COLOR(h) ((COLOR_TYPE)(HTML2COLOR_R(h) | HTML2COLOR_G(h) | HTML2COLOR_B(h)))
+
+//-------------------------
+// Gray-scale color system
+//-------------------------
+#elif (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
+
+ // Calculate the number of bits and shifts
+ #define COLOR_BITS (GDISP_PIXELFORMAT & 0xFF)
+ #define COLOR_BITS_R COLOR_BITS
+ #define COLOR_BITS_G COLOR_BITS
+ #define COLOR_BITS_B COLOR_BITS
+ #define COLOR_SHIFT_R 0
+ #define COLOR_SHIFT_G 0
+ #define COLOR_SHIFT_B 0
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if COLOR_BITS <= 8
+ #define COLOR_TYPE uint8_t
+ #define COLOR_TYPE_BITS 8
+ #else
+ #error "GDISP: Cannot define gray-scale color types with more than 8 bits"
+ #endif
+ #if COLOR_TYPE_BITS == COLOR_BITS
+ #define COLOR_NEEDS_MASK FALSE
+ #else
+ #define COLOR_NEEDS_MASK TRUE
+ #endif
+ #define COLOR_MASK() ((1 << COLOR_BITS)-1)
+
+ #if COLOR_BITS == 1
+ #define RGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
+ #define LUMA2COLOR(l) ((l) ? 1 : 0)
+ #define HTML2COLOR(h) ((h) ? 1 : 0)
+ #define LUMA_OF(c) ((c) ? 255 : 0)
+ #define EXACT_LUMA_OF(c) LUMA_OF(c)
+ #else
+ // They eye is more sensitive to green
+ #define RGB2COLOR(r,g,b) ((COLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-COLOR_BITS)))
+ #define LUMA2COLOR(l) ((COLOR_TYPE)((l)>>(8-COLOR_BITS)))
+ #define HTML2COLOR(h) ((COLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-COLOR_BITS)))
+ #define LUMA_OF(c) (((c) & ((1<<COLOR_BITS)-1)) << (8-COLOR_BITS))
+ #define EXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<COLOR_BITS)-1))*255)/((1<<COLOR_BITS)-1))
+ #endif
+
+ #define RED_OF(c) LUMA_OF(c)
+ #define GREEN_OF(c) LUMA_OF(c)
+ #define BLUE_OF(c) LUMA_OF(c)
+ #define EXACT_RED_OF(c) EXACT_LUMA_OF(c)
+ #define EXACT_GREEN_OF(c) EXACT_LUMA_OF(c)
+ #define EXACT_BLUE_OF(c) EXACT_LUMA_OF(c)
+
+//-------------------------
+// Palette color system
+//-------------------------
+#elif (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
+
+ #error "GDISP: A palette color system is not currently supported"
+
+//-------------------------
+// Some other color system
+//-------------------------
+#else
+ #error "GDISP: Unsupported color system"
+#endif
+
+/**
+ * @brief The color type definition
+ */
+typedef COLOR_TYPE color_t;
+
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_COLORS_H */
+/** @} */
diff --git a/src/gdisp/driver.h b/src/gdisp/driver.h
new file mode 100644
index 00000000..f45b3f87
--- /dev/null
+++ b/src/gdisp/driver.h
@@ -0,0 +1,873 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gdisp/driver.h
+ * @brief GDISP Graphic Driver subsystem low level driver header.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_H
+#define _GDISP_LLD_H
+
+#if GFX_USE_GDISP // || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Error checks. */
+/*===========================================================================*/
+
+#if GDISP_TOTAL_CONTROLLERS > 1 && !defined(GDISP_DRIVER_VMT)
+ #define HARDWARE_AUTODETECT 2
+ #define HARDWARE_DEFAULT HARDWARE_AUTODETECT
+#else
+ #define HARDWARE_AUTODETECT 2
+ #define HARDWARE_DEFAULT FALSE
+#endif
+
+/**
+ * @name GDISP hardware accelerated support
+ * @{
+ */
+ /**
+ * @brief The display hardware can benefit from being flushed.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note Some controllers ** require ** the application to flush
+ */
+ #ifndef GDISP_HARDWARE_FLUSH
+ #define GDISP_HARDWARE_FLUSH HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware streaming writing is supported.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by each driver
+ */
+ #ifndef GDISP_HARDWARE_STREAM_WRITE
+ #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware streaming reading of the display surface is supported.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ *
+ */
+ #ifndef GDISP_HARDWARE_STREAM_READ
+ #define GDISP_HARDWARE_STREAM_READ HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware supports setting the cursor position within the stream window.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note This is used to optimise setting of individual pixels within a stream window.
+ * It should therefore not be implemented unless it is cheaper than just setting
+ * a new window.
+ */
+ #ifndef GDISP_HARDWARE_STREAM_POS
+ #define GDISP_HARDWARE_STREAM_POS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated draw pixel.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
+ */
+ #ifndef GDISP_HARDWARE_DRAWPIXEL
+ #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated screen clears.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note This clears the entire display surface regardless of the clipping area currently set
+ */
+ #ifndef GDISP_HARDWARE_CLEARS
+ #define GDISP_HARDWARE_CLEARS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated rectangular fills.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ */
+ #ifndef GDISP_HARDWARE_FILLS
+ #define GDISP_HARDWARE_FILLS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated fills from an image.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ */
+ #ifndef GDISP_HARDWARE_BITFILLS
+ #define GDISP_HARDWARE_BITFILLS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated scrolling.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ */
+ #ifndef GDISP_HARDWARE_SCROLL
+ #define GDISP_HARDWARE_SCROLL HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Reading back of pixel values.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ */
+ #ifndef GDISP_HARDWARE_PIXELREAD
+ #define GDISP_HARDWARE_PIXELREAD HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The driver supports one or more control commands.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ */
+ #ifndef GDISP_HARDWARE_CONTROL
+ #define GDISP_HARDWARE_CONTROL HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The driver supports a non-standard query.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ */
+ #ifndef GDISP_HARDWARE_QUERY
+ #define GDISP_HARDWARE_QUERY HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The driver supports a clipping in hardware.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note If this is defined the driver must perform its own clipping on all calls to
+ * the driver and respond appropriately if a parameter is outside the display area.
+ * @note If this is not defined then the software ensures that all calls to the
+ * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION
+ * has been set).
+ */
+ #ifndef GDISP_HARDWARE_CLIP
+ #define GDISP_HARDWARE_CLIP HARDWARE_DEFAULT
+ #endif
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+struct GDisplay {
+ // The public GDISP stuff - must be the first element
+ GDISPControl g;
+
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ const struct GDISPVMT const * vmt; // The Virtual Method Table
+ #endif
+
+ void * priv; // A private area just for the drivers use.
+ void * board; // A private area just for the board interfaces use.
+
+ uint8_t systemdisplay;
+ uint8_t controllerdisplay;
+ uint16_t flags;
+ #define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation
+ #define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen
+ #define GDISP_FLG_DRIVER 0x0004 // This flags and above are for use by the driver
+
+ // Multithread Mutex
+ #if GDISP_NEED_MULTITHREAD
+ gfxMutex mutex;
+ #endif
+
+ // Software clipping
+ #if GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ coord_t clipx0, clipy0;
+ coord_t clipx1, clipy1; /* not inclusive */
+ #endif
+
+ // Driver call parameters
+ struct {
+ coord_t x, y;
+ coord_t cx, cy;
+ coord_t x1, y1;
+ coord_t x2, y2;
+ color_t color;
+ void *ptr;
+ } p;
+
+ // In call working buffers
+
+ #if GDISP_NEED_TEXT
+ // Text rendering parameters
+ struct {
+ font_t font;
+ color_t color;
+ color_t bgcolor;
+ coord_t clipx0, clipy0;
+ coord_t clipx1, clipy1;
+ } t;
+ #endif
+ #if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM_WRITE && GDISP_HARDWARE_BITFILLS))
+ // A pixel line buffer
+ color_t linebuf[GDISP_LINEBUF_SIZE];
+ #endif
+
+};
+
+#if GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT) || defined(__DOXYGEN__)
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ #define LLDSPEC static
+ #else
+ #define LLDSPEC
+ #endif
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /**
+ * @brief Initialize the driver.
+ * @return TRUE if successful.
+ * @param[in] g The driver structure
+ * @param[out] g->g The driver must fill in the GDISPControl structure
+ */
+ LLDSPEC bool_t gdisp_lld_init(GDisplay *g);
+
+ #if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__)
+ /**
+ * @brief Flush the current drawing operations to the display
+ * @pre GDISP_HARDWARE_FLUSH is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_flush(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_WRITE || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streamed write operation
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note g->p.x,g->p.y The window position
+ * @note g->p.cx,g->p.cy The window size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note Streaming operations that wrap the defined window have
+ * undefined results.
+ * @note This must be followed by a call to @p gdisp_lld_write_pos() if GDISP_HARDWARE_STREAM_POS is TRUE.
+ */
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g);
+
+ /**
+ * @brief Send a pixel to the current streaming position and then increment that position
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note g->p.color The color to display at the curent position
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g);
+
+ /**
+ * @brief End the current streaming write operation
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g);
+
+ #if GDISP_HARDWARE_STREAM_POS || defined(__DOXYGEN__)
+ /**
+ * @brief Change the current position within the current streaming window
+ * @pre GDISP_HARDWARE_STREAM_POS is TRUE and GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The new position (which will always be within the existing stream window)
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g);
+ #endif
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streamed read operation
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The window position
+ * @param[in] g->p.cx,g->p.cy The window size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note Streaming operations that wrap the defined window have
+ * undefined results.
+ */
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g);
+
+ /**
+ * @brief Read a pixel from the current streaming position and then increment that position
+ * @return The color at the current position
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g);
+
+ /**
+ * @brief End the current streaming operation
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a pixel
+ * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The pixel position
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
+ /**
+ * @brief Clear the screen using the defined color
+ * @pre GDISP_HARDWARE_CLEARS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_clear(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
+ /**
+ * @brief Fill an area with a single color
+ * @pre GDISP_HARDWARE_FILLS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
+ /**
+ * @brief Fill an area using a bitmap
+ * @pre GDISP_HARDWARE_BITFILLS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.x1,g->p.y1 The starting position in the bitmap
+ * @param[in] g->p.x2 The width of a bitmap line
+ * @param[in] g->p.ptr The pointer to the bitmap
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__)
+ /**
+ * @brief Read a pixel from the display
+ * @return The color at the defined position
+ * @pre GDISP_HARDWARE_PIXELREAD is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The pixel position
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g);
+ #endif
+
+ #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__)
+ /**
+ * @brief Scroll an area of the screen
+ * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.y1 The number of lines to scroll (positive or negative)
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note This can be easily implemented if the hardware supports
+ * display area to display area copying.
+ * @note Clearing the exposed area on the scroll operation is not
+ * needed as the high level code handles this.
+ */
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g);
+ #endif
+
+ #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
+ /**
+ * @brief Control some feature of the hardware
+ * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x The operation to perform
+ * @param[in] g->p.ptr The operation parameter
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_control(GDisplay *g);
+ #endif
+
+ #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__)
+ /**
+ * @brief Query some feature of the hardware
+ * @return The information requested (typecast as void *)
+ * @pre GDISP_HARDWARE_QUERY is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x What to query
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void *gdisp_lld_query(GDisplay *g); // Uses p.x (=what);
+ #endif
+
+ #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__)
+ /**
+ * @brief Set the hardware clipping area
+ * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_set_clip(GDisplay *g);
+ #endif
+
+ #ifdef __cplusplus
+ }
+ #endif
+#endif // GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT)
+
+
+#if GDISP_TOTAL_CONTROLLERS > 1
+
+ typedef struct GDISPVMT {
+ bool_t (*init)(GDisplay *g);
+ void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*writepos)(GDisplay *g); // Uses p.x,p.y
+ void (*writecolor)(GDisplay *g); // Uses p.color
+ void (*writestop)(GDisplay *g); // Uses no parameters
+ void (*readstart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ color_t (*readcolor)(GDisplay *g); // Uses no parameters
+ void (*readstop)(GDisplay *g); // Uses no parameters
+ void (*pixel)(GDisplay *g); // Uses p.x,p.y p.color
+ void (*clear)(GDisplay *g); // Uses p.color
+ void (*fill)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.color
+ void (*blit)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
+ color_t (*get)(GDisplay *g); // Uses p.x,p.y
+ void (*vscroll)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color
+ void (*control)(GDisplay *g); // Uses p.x (=what) p.ptr (=value)
+ void *(*query)(GDisplay *g); // Uses p.x (=what);
+ void (*setclip)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*flush)(GDisplay *g); // Uses no parameters
+ } GDISPVMT;
+
+ #if defined(GDISP_DRIVER_VMT)
+ #if !GDISP_HARDWARE_STREAM_WRITE && !GDISP_HARDWARE_DRAWPIXEL
+ #error "GDISP Driver: Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be TRUE"
+ #endif
+ const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
+ gdisp_lld_init,
+ #if GDISP_HARDWARE_FLUSH
+ gdisp_lld_flush,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_STREAM_WRITE
+ gdisp_lld_write_start,
+ #if GDISP_HARDWARE_STREAM_POS
+ gdisp_lld_write_pos,
+ #else
+ 0,
+ #endif
+ gdisp_lld_write_color,
+ gdisp_lld_write_stop,
+ #else
+ 0, 0, 0, 0,
+ #endif
+ #if GDISP_HARDWARE_STREAM_READ
+ gdisp_lld_read_start,
+ gdisp_lld_read_color,
+ gdisp_lld_read_stop,
+ #else
+ 0, 0, 0,
+ #endif
+ #if GDISP_HARDWARE_DRAWPIXEL
+ gdisp_lld_draw_pixel,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CLEARS
+ gdisp_lld_clear,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_FILLS
+ gdisp_lld_fill_area,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_BITFILLS
+ gdisp_lld_blit_area,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_PIXELREAD
+ gdisp_lld_get_pixel_color,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL
+ gdisp_lld_vertical_scroll,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL
+ gdisp_lld_control,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY
+ gdisp_lld_query,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ gdisp_lld_set_clip,
+ #else
+ 0,
+ #endif
+ }};
+
+ #else
+ #define gdisp_lld_init(g) g->vmt->init(g)
+ #define gdisp_lld_flush(g) g->vmt->flush(g)
+ #define gdisp_lld_write_start(g) g->vmt->writestart(g)
+ #define gdisp_lld_write_pos(g) g->vmt->writepos(g)
+ #define gdisp_lld_write_color(g) g->vmt->writecolor(g)
+ #define gdisp_lld_write_stop(g) g->vmt->writestop(g)
+ #define gdisp_lld_read_start(g) g->vmt->readstart(g)
+ #define gdisp_lld_read_color(g) g->vmt->readcolor(g)
+ #define gdisp_lld_read_stop(g) g->vmt->readstop(g)
+ #define gdisp_lld_draw_pixel(g) g->vmt->pixel(g)
+ #define gdisp_lld_clear(g) g->vmt->clear(g)
+ #define gdisp_lld_fill_area(g) g->vmt->fill(g)
+ #define gdisp_lld_blit_area(g) g->vmt->blit(g)
+ #define gdisp_lld_get_pixel_color(g) g->vmt->get(g)
+ #define gdisp_lld_vertical_scroll(g) g->vmt->vscroll(g)
+ #define gdisp_lld_control(g) g->vmt->control(g)
+ #define gdisp_lld_query(g) g->vmt->query(g)
+ #define gdisp_lld_set_clip(g) g->vmt->setclip(g)
+ #endif // GDISP_LLD_DECLARATIONS
+
+#endif // GDISP_TOTAL_CONTROLLERS > 1
+
+/* Verify information for packed pixels and define a non-packed pixel macro */
+#if !GDISP_PACKED_PIXELS
+ #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); }
+#elif !GDISP_HARDWARE_BITFILLS
+ #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers."
+#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \
+ && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \
+ && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \
+ && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
+ #error "GDISP: A packed pixel format has been specified for an unsupported pixel format."
+#endif
+
+/* Support routine for packed pixel formats */
+#if !defined(gdispPackPixels) || defined(__DOXYGEN__)
+ /**
+ * @brief Pack a pixel into a pixel buffer.
+ * @note This function performs no buffer boundary checking
+ * regardless of whether GDISP_NEED_CLIP has been specified.
+ *
+ * @param[in] buf The buffer to put the pixel in
+ * @param[in] cx The width of a pixel line
+ * @param[in] x, y The location of the pixel to place
+ * @param[in] color The color to put into the buffer
+ *
+ * @api
+ */
+ void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color);
+#endif
+
+/* Low level driver pixel format information */
+//-------------------------
+// True-Color color system
+//-------------------------
+#if GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+
+ // Calculate the number of bits
+ #define LLDCOLOR_BITS_R ((GDISP_LLD_PIXELFORMAT>>8) & 0x0F)
+ #define LLDCOLOR_BITS_G ((GDISP_LLD_PIXELFORMAT>>4) & 0x0F)
+ #define LLDCOLOR_BITS_B ((GDISP_LLD_PIXELFORMAT>>0) & 0x0F)
+ #define LLDCOLOR_BITS (LLDCOLOR_BITS_R + LLDCOLOR_BITS_G + LLDCOLOR_BITS_B)
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if LLDCOLOR_BITS <= 8
+ #define LLDCOLOR_TYPE uint8_t
+ #define LLDCOLOR_TYPE_BITS 8
+ #elif LLDCOLOR_BITS <= 16
+ #define LLDCOLOR_TYPE uint16_t
+ #define LLDCOLOR_TYPE_BITS 16
+ #elif LLDCOLOR_BITS <= 32
+ #define LLDCOLOR_TYPE uint32_t
+ #define LLDCOLOR_TYPE_BITS 32
+ #else
+ #error "GDISP: Cannot define low level driver color types with more than 32 bits"
+ #endif
+ #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
+ #define LLDCOLOR_NEEDS_MASK FALSE
+ #else
+ #define LLDCOLOR_NEEDS_MASK TRUE
+ #endif
+ #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
+
+ // Calculate the component bit shifts
+ #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
+ #define LLDCOLOR_SHIFT_R (LLDCOLOR_BITS_B+LLDCOLOR_BITS_G)
+ #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_B
+ #define LLDCOLOR_SHIFT_B 0
+ #else
+ #define LLDCOLOR_SHIFT_B (LLDCOLOR_BITS_R+LLDCOLOR_BITS_G)
+ #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_R
+ #define LLDCOLOR_SHIFT_R 0
+ #endif
+
+ // Calculate LLDRED_OF, LLDGREEN_OF, LLDBLUE_OF and LLDRGB2COLOR
+ #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 8
+ #define LLDRED_OF(c) ((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R))
+ #define LLDRGB2COLOR_R(r) ((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))))
+ #elif LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R > 8
+ #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) >> (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
+ #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
+ #else // LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R < 8
+ #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) << (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) >> (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #endif
+ #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 8
+ #define LLDGREEN_OF(c) ((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G))
+ #define LLDRGB2COLOR_G(g) ((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))))
+ #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 8
+ #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) >> (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
+ #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
+ #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 8
+ #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) << (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
+ #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) >> (8-(LLDCOLOR_BITS_LLDG+COLOR_SHIFT_G)))
+ #endif
+ #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
+ #define LLDBLUE_OF(c) ((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B))
+ #define LLDRGB2COLOR_B(b) ((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))))
+ #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
+ #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) >> (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
+ #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) << (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #define LLDRGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #endif
+ #define LLDLUMA_OF(c) ((LLDRED_OF(c)+((uint16_t)LLDGREEN_OF(c)<<1)+LLDBLUE_OF(c))>>2)
+ #define LLDEXACT_RED_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_R)&((1<<LLDCOLOR_BITS_R)-1))*255)/((1<<LLDCOLOR_BITS_R)-1))
+ #define LLDEXACT_GREEN_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_G)&((1<<LLDCOLOR_BITS_G)-1))*255)/((1<<LLDCOLOR_BITS_G)-1))
+ #define LLDEXACT_BLUE_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_B)&((1<<LLDCOLOR_BITS_B)-1))*255)/((1<<LLDCOLOR_BITS_B)-1))
+ #define LLDEXACT_LUMA_OF(c) ((LLDEXACT_RED_OF(c)+((uint16_t)LLDEXACT_GREEN_OF(c)<<1)+LLDEXACT_BLUE_OF(c))>>2)
+ #define LLDLUMA2COLOR(l) (LLDRGB2COLOR_R(l) | LLDRGB2COLOR_G(l) | LLDRGB2COLOR_B(l))
+ #define LLDRGB2COLOR(r,g,b) (LLDRGB2COLOR_R(r) | LLDRGB2COLOR_G(g) | LLDRGB2COLOR_B(b))
+
+ // Calculate LLDHTML2COLOR
+ #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 24
+ #define LLDHTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
+ #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-24))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
+ #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) >> (24-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #endif
+ #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 16
+ #define LLDHTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8))
+ #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 16
+ #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-16))
+ #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 16
+ #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) >> (16-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
+ #endif
+ #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
+ #define LLDHTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))
+ #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
+ #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
+ #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #endif
+ #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(LLDHTML2COLOR_R(h) | LLDHTML2COLOR_G(h) | LLDHTML2COLOR_B(h)))
+
+//-------------------------
+// Gray-scale color system
+//-------------------------
+#elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
+
+ // Calculate the number of bits and shifts
+ #define LLDCOLOR_BITS (GDISP_LLD_PIXELFORMAT & 0xFF)
+ #define LLDCOLOR_BITS_R LLDCOLOR_BITS
+ #define LLDCOLOR_BITS_G LLDCOLOR_BITS
+ #define LLDCOLOR_BITS_B LLDCOLOR_BITS
+ #define LLDCOLOR_SHIFT_R 0
+ #define LLDCOLOR_SHIFT_G 0
+ #define LLDCOLOR_SHIFT_B 0
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if LLDCOLOR_BITS <= 8
+ #define LLDCOLOR_TYPE uint8_t
+ #define LLDCOLOR_TYPE_BITS 8
+ #else
+ #error "GDISP: Cannot define gray-scale low level driver color types with more than 8 bits"
+ #endif
+ #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
+ #define LLDCOLOR_NEEDS_MASK FALSE
+ #else
+ #define LLDCOLOR_NEEDS_MASK TRUE
+ #endif
+ #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
+
+ #if COLOR_BITS == 1
+ #define LLDRGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
+ #define LLDLUMA2COLOR(l) ((l) ? 1 : 0)
+ #define LLDHTML2COLOR(h) ((h) ? 1 : 0)
+ #define LLDLUMA_OF(c) ((c) ? 255 : 0)
+ #define LLDEXACT_LUMA_OF(c) LLDLUMA_OF(c)
+ #else
+ // They eye is more sensitive to green
+ #define LLDRGB2COLOR(r,g,b) ((LLDCOLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-LLDCOLOR_BITS)))
+ #define LLDLUMA2COLOR(l) ((LLDCOLOR_TYPE)((l)>>(8-LLDCOLOR_BITS)))
+ #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-LLDCOLOR_BITS)))
+ #define LLDLUMA_OF(c) (((c) & ((1<<LLDCOLOR_BITS)-1)) << (8-LLDCOLOR_BITS))
+ #define LLDEXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<LLDCOLOR_BITS)-1))*255)/((1<<LLDCOLOR_BITS)-1))
+ #endif
+
+ #define LLDRED_OF(c) LLDLUMA_OF(c)
+ #define LLDGREEN_OF(c) LLDLUMA_OF(c)
+ #define LLDBLUE_OF(c) LLDLUMA_OF(c)
+ #define LLDEXACT_RED_OF(c) LLDEXACT_LUMA_OF(c)
+ #define LLDEXACT_GREEN_OF(c) LLDEXACT_LUMA_OF(c)
+ #define LLDEXACT_BLUE_OF(c) LLDEXACT_LUMA_OF(c)
+
+//-------------------------
+// Palette color system
+//-------------------------
+#elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
+
+ #error "GDISP: A palette color system for low level drivers is not currently supported"
+
+//-------------------------
+// Some other color system
+//-------------------------
+#else
+ #error "GDISP: Unsupported color system for low level drivers"
+#endif
+
+/* Which is the larger color type */
+#if COLOR_BITS > LLDCOLOR_BITS
+ #define LARGER_COLOR_BITS COLOR_BITS
+ #define LARGER_COLOR_TYPE COLOR_TYPE
+#else
+ #define LARGER_COLOR_BITS LLDCOLOR_BITS
+ #define LARGER_COLOR_TYPE LLDCOLOR_TYPE
+#endif
+
+/**
+ * @brief Controls color conversion accuracy for a low level driver
+ * @details Should higher precision be used when converting colors.
+ * @note Color conversion is only necessary if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
+ * @note It only makes sense to turn this on if you have a high bit depth display but
+ * are running the application in low bit depths.
+ * @note To achieve higher color accuracy bit shifting is replaced with multiplies and divides.
+ */
+#ifndef GDISP_HARDWARE_USE_EXACT_COLOR
+ #if LLDCOLOR_BITS_R - COLOR_BITS_R >= LLDCOLOR_BITS_R/2 || LLDCOLOR_BITS_G - COLOR_BITS_G >= LLDCOLOR_BITS_G/2 || LLDCOLOR_BITS_B - COLOR_BITS_B >= LLDCOLOR_BITS_B/2
+ #define GDISP_HARDWARE_USE_EXACT_COLOR TRUE
+ #else
+ #define GDISP_HARDWARE_USE_EXACT_COLOR FALSE
+ #endif
+#endif
+
+/* Low level driver pixel format conversion functions */
+#if GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT || defined(__DOXYGEN__)
+ /**
+ * @brief Convert from a standard color format to the low level driver pixel format
+ * @note For use only by low level drivers
+ */
+ #define gdispColor2Native(c) (c)
+ /**
+ * @brief Convert from a low level driver pixel format to the standard color format
+ * @note For use only by low level drivers
+ */
+ #define gdispNative2Color(c) (c)
+#else
+ LLDCOLOR_TYPE gdispColor2Native(color_t c);
+ color_t gdispNative2Color(LLDCOLOR_TYPE c);
+#endif
+
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_LLD_H */
+/** @} */
diff --git a/src/gdisp/fonts/build_fonts.sh b/src/gdisp/fonts/build_fonts.sh
index b6c26602..4ce93a40 100644
--- a/src/gdisp/fonts/build_fonts.sh
+++ b/src/gdisp/fonts/build_fonts.sh
@@ -72,7 +72,7 @@ for file in *.c; do
defname='GDISP_INCLUDE_FONT_'$upper
echo '#if defined('$defname') && '$defname >> fonts.h
echo '#define GDISP_FONT_FOUND' >> fonts.h
- echo '#include "../src/gdisp/fonts/'$file'"' >> fonts.h
+ echo '#include "src/gdisp/fonts/'$file'"' >> fonts.h
echo '#endif' >> fonts.h
done
diff --git a/src/gdisp/fonts/fonts.h b/src/gdisp/fonts/fonts.h
index 7d696044..af851dbd 100644
--- a/src/gdisp/fonts/fonts.h
+++ b/src/gdisp/fonts/fonts.h
@@ -3,87 +3,87 @@
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS10) && GDISP_INCLUDE_FONT_DEJAVUSANS10
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans10.c"
+#include "src/gdisp/fonts/DejaVuSans10.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS12_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS12_AA
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans12_aa.c"
+#include "src/gdisp/fonts/DejaVuSans12_aa.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS12) && GDISP_INCLUDE_FONT_DEJAVUSANS12
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans12.c"
+#include "src/gdisp/fonts/DejaVuSans12.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS16_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS16_AA
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans16_aa.c"
+#include "src/gdisp/fonts/DejaVuSans16_aa.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS16) && GDISP_INCLUDE_FONT_DEJAVUSANS16
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans16.c"
+#include "src/gdisp/fonts/DejaVuSans16.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS24_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS24_AA
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans24_aa.c"
+#include "src/gdisp/fonts/DejaVuSans24_aa.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS24) && GDISP_INCLUDE_FONT_DEJAVUSANS24
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans24.c"
+#include "src/gdisp/fonts/DejaVuSans24.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS32_AA) && GDISP_INCLUDE_FONT_DEJAVUSANS32_AA
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans32_aa.c"
+#include "src/gdisp/fonts/DejaVuSans32_aa.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANS32) && GDISP_INCLUDE_FONT_DEJAVUSANS32
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSans32.c"
+#include "src/gdisp/fonts/DejaVuSans32.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA) && GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSansBold12_aa.c"
+#include "src/gdisp/fonts/DejaVuSansBold12_aa.c"
#endif
#if defined(GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12) && GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/DejaVuSansBold12.c"
+#include "src/gdisp/fonts/DejaVuSansBold12.c"
#endif
#if defined(GDISP_INCLUDE_FONT_FIXED_10X20) && GDISP_INCLUDE_FONT_FIXED_10X20
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/fixed_10x20.c"
+#include "src/gdisp/fonts/fixed_10x20.c"
#endif
#if defined(GDISP_INCLUDE_FONT_FIXED_5X8) && GDISP_INCLUDE_FONT_FIXED_5X8
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/fixed_5x8.c"
+#include "src/gdisp/fonts/fixed_5x8.c"
#endif
#if defined(GDISP_INCLUDE_FONT_FIXED_7X14) && GDISP_INCLUDE_FONT_FIXED_7X14
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/fixed_7x14.c"
+#include "src/gdisp/fonts/fixed_7x14.c"
#endif
#if defined(GDISP_INCLUDE_FONT_LARGENUMBERS) && GDISP_INCLUDE_FONT_LARGENUMBERS
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/LargeNumbers.c"
+#include "src/gdisp/fonts/LargeNumbers.c"
#endif
#if defined(GDISP_INCLUDE_FONT_UI1) && GDISP_INCLUDE_FONT_UI1
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/UI1.c"
+#include "src/gdisp/fonts/UI1.c"
#endif
#if defined(GDISP_INCLUDE_FONT_UI2) && GDISP_INCLUDE_FONT_UI2
#define GDISP_FONT_FOUND
-#include "../src/gdisp/fonts/UI2.c"
+#include "src/gdisp/fonts/UI2.c"
#endif
#if defined(GDISP_INCLUDE_USER_FONTS) && GDISP_INCLUDE_USER_FONTS
diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c
index 949bedaf..2ac55f1b 100644
--- a/src/gdisp/gdisp.c
+++ b/src/gdisp/gdisp.c
@@ -17,7 +17,7 @@
#if GFX_USE_GDISP
/* Include the low level driver information */
-#include "gdisp/lld/gdisp_lld.h"
+#include "src/gdisp/driver.h"
#if 1
#undef INLINE
diff --git a/src/gdisp/image.h b/src/gdisp/image.h
new file mode 100644
index 00000000..607f1007
--- /dev/null
+++ b/src/gdisp/image.h
@@ -0,0 +1,307 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gdisp/image.h
+ * @brief GDISP image header file.
+ *
+ * @defgroup Image Image
+ * @ingroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_IMAGE_H
+#define _GDISP_IMAGE_H
+#if (GFX_USE_GDISP && GDISP_NEED_IMAGE) || defined(__DOXYGEN__)
+
+/**
+ * @brief The type of image
+ */
+typedef uint16_t gdispImageType;
+ #define GDISP_IMAGE_TYPE_UNKNOWN 0
+ #define GDISP_IMAGE_TYPE_NATIVE 1
+ #define GDISP_IMAGE_TYPE_GIF 2
+ #define GDISP_IMAGE_TYPE_BMP 3
+ #define GDISP_IMAGE_TYPE_JPG 4
+ #define GDISP_IMAGE_TYPE_PNG 5
+
+/**
+ * @brief An image error code
+ */
+typedef uint16_t gdispImageError;
+ #define GDISP_IMAGE_ERR_OK 0
+ #define GDISP_IMAGE_ERR_UNRECOVERABLE 0x8000
+ #define GDISP_IMAGE_ERR_BADFORMAT (GDISP_IMAGE_ERR_UNRECOVERABLE+1)
+ #define GDISP_IMAGE_ERR_BADDATA (GDISP_IMAGE_ERR_UNRECOVERABLE+2)
+ #define GDISP_IMAGE_ERR_UNSUPPORTED (GDISP_IMAGE_ERR_UNRECOVERABLE+3)
+ #define GDISP_IMAGE_ERR_UNSUPPORTED_OK 3
+ #define GDISP_IMAGE_ERR_NOMEMORY (GDISP_IMAGE_ERR_UNRECOVERABLE+4)
+ #define GDISP_IMAGE_ERR_NOSUCHFILE (GDISP_IMAGE_ERR_UNRECOVERABLE+5)
+
+/**
+ * @brief Image flags
+ */
+typedef uint16_t gdispImageFlags;
+ #define GDISP_IMAGE_FLG_TRANSPARENT 0x0001 /* The image has transparency */
+ #define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */
+ #define GDISP_IMAGE_FLG_MULTIPAGE 0x0004 /* The image has multiple pages */
+
+struct gdispImageIO;
+
+/**
+ * @brief An image IO close function
+ *
+ * @param[in] pio Pointer to the io structure
+ * @param[in] desc The descriptor. A filename or an image structure pointer.
+ *
+ */
+typedef void (*gdispImageIOCloseFn)(struct gdispImageIO *pio);
+
+/**
+ * @brief An image IO read function
+ * @returns The number of bytes actually read or 0 on error
+ *
+ * @param[in] pio Pointer to the io structure
+ * @param[in] buf Where the results should be placed
+ * @param[in] len The number of bytes to read
+ *
+ */
+typedef size_t (*gdispImageIOReadFn)(struct gdispImageIO *pio, void *buf, size_t len);
+
+/**
+ * @brief An image IO seek function
+ *
+ * @param[in] pio Pointer to the io structure
+ * @param[in] pos Which byte to seek to relative to the start of the "file".
+ *
+ */
+typedef void (*gdispImageIOSeekFn)(struct gdispImageIO *pio, size_t pos);
+
+typedef struct gdispImageIOFunctions {
+ gdispImageIOReadFn read; /* @< The function to read input */
+ gdispImageIOSeekFn seek; /* @< The function to seek input */
+ gdispImageIOCloseFn close; /* @< The function to close input */
+ } gdispImageIOFunctions;
+
+/**
+ * @brief The structure defining the IO routines for image handling
+ */
+typedef struct gdispImageIO {
+ const void * fd; /* @< The "file" descriptor */
+ size_t pos; /* @< The current "file" position */
+ const gdispImageIOFunctions *fns; /* @< The current "file" functions */
+} gdispImageIO;
+
+/**
+ * @brief The structure for an image
+ */
+typedef struct gdispImage {
+ gdispImageType type; /* @< The image type */
+ gdispImageFlags flags; /* @< The image flags */
+ color_t bgcolor; /* @< The default background color */
+ coord_t width, height; /* @< The image dimensions */
+ GFILE * f; /* @< The underlying GFILE */
+ #if GDISP_NEED_IMAGE_ACCOUNTING
+ uint32_t memused; /* @< How much RAM is currently allocated */
+ uint32_t maxmemused; /* @< How much RAM has been allocated (maximum) */
+ #endif
+ const struct gdispImageHandlers * fns; /* @< Don't mess with this! */
+ struct gdispImagePrivate * priv; /* @< Don't mess with this! */
+} gdispImage;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Deprecated Functions.
+ */
+ gdispImageError DEPRECATED("Use gdispImageOpenGFile() instead") gdispImageOpen(gdispImage *img);
+ bool_t DEPRECATED("Use gdispImageOpenMemory() instead") gdispImageSetMemoryReader(gdispImage *img, const void *memimage);
+ #if GFX_USE_OS_CHIBIOS
+ bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr);
+ #endif
+ #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX
+ bool_t DEPRECATED("Please use gdispImageOpenFile() instead") gdispImageSetFileReader(gdispImage *img, const char *filename);
+ #define gdispImageSetSimulFileReader(img, fname) gdispImageSetFileReader(img, fname)
+ #endif
+
+ /**
+ * @brief Open an image using an open GFILE and get it ready for drawing
+ * @details Determine the image format and get ready to decode the first image frame
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] img The image structure
+ * @param[in] f The open GFILE stream.
+ *
+ * @pre The GFILE must be open for reading.
+ *
+ * @note This determines which decoder to use and then initialises all other fields
+ * in the gdispImage structure.
+ * @note The image background color is set to White.
+ * @note There are three types of return - everything OK, partial success and unrecoverable
+ * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can
+ * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE
+ * bit in the error code.
+ * A partial success return code means an image can still be drawn but perhaps with
+ * reduced functionality eg only the first page of a multi-page image.
+ * @note @p gdispImageClose() should be called when finished with the image. This will close
+ * the image and its underlying GFILE file. Note that images opened with partial success
+ * (eg GDISP_IMAGE_ERR_UNSUPPORTED_OK)
+ * still need to be closed when you are finished with them.
+ */
+ gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *f);
+
+ /**
+ * @brief Open an image in a file and get it ready for drawing
+ * @details Determine the image format and get ready to decode the first image frame
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @pre You must have included the file-system support into GFILE that you want to use.
+ *
+ * @param[in] img The image structure
+ * @param[in] filename The filename to open
+ *
+ * @note This function just opens the GFILE using the filename and passes it to @p gdispImageOpenGFile().
+ */
+ #define gdispImageOpenFile(img, filename) gdispImageOpenGFile((img), gfileOpen((filename), "rb"))
+
+ /**
+ * @brief Open an image in a ChibiOS basefilestream and get it ready for drawing
+ * @details Determine the image format and get ready to decode the first image frame
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @pre GFILE_NEED_CHIBIOSFS and GFX_USE_OS_CHIBIOS must be TRUE. This only makes sense on the ChibiOS
+ * operating system.
+ *
+ * @param[in] img The image structure
+ * @param[in] BaseFileStreamPtr A pointer to an open BaseFileStream
+ *
+ * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile().
+ */
+ #define gdispImageOpenBaseFileStream(img, BaseFileStreamPtr) gdispImageOpenGFile((img), gfileOpenBaseFileStream((BaseFileStreamPtr), "rb"))
+
+ /**
+ * @brief Open an image in memory and get it ready for drawing
+ * @details Determine the image format and get ready to decode the first image frame
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @pre GFILE_NEED_MEMFS must be TRUE
+ *
+ * @param[in] img The image structure
+ * @param[in] ptr A pointer to the image bytes in memory
+ *
+ * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile().
+ */
+ #define gdispImageOpenMemory(img, ptr) gdispImageOpenGFile((img), gfileOpenMemory((void *)(ptr), "rb"))
+
+ /**
+ * @brief Close an image and release any dynamically allocated working storage.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre gdispImageOpenFile() must have returned successfully.
+ *
+ * @note Also calls the IO close function (if it hasn't already been called).
+ */
+ void gdispImageClose(gdispImage *img);
+
+ /**
+ * @brief Is an image open.
+ * @return TRUE if the image is currently open.
+ *
+ * @param[in] img The image structure
+ *
+ * @note Be careful with calling this on an uninitialized image structure as the image
+ * will contain random data which may be interpreted as meaning the image
+ * is open. Clearing the Image structure to 0's will guarantee the image
+ * is seen as being closed.
+ */
+ bool_t gdispImageIsOpen(gdispImage *img);
+
+ /**
+ * @brief Set the background color of the image.
+ *
+ * @param[in] img The image structure
+ * @param[in] bgcolor The background color to use
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note This color is only used when an image has to restore part of the background before
+ * continuing with drawing that includes transparency eg some GIF animations.
+ */
+ void gdispImageSetBgColor(gdispImage *img, color_t bgcolor);
+
+ /**
+ * @brief Cache the image
+ * @details Decodes and caches the current frame into RAM.
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note This can use a LOT of RAM!
+ * @note The decoder may choose to ignore the request for caching. If it does so it will
+ * return GDISP_IMAGE_ERR_UNSUPPORTED_OK.
+ * @note A fatal error here does not necessarily mean that drawing the image will fail. For
+ * example, a GDISP_IMAGE_ERR_NOMEMORY error simply means there isn't enough RAM to
+ * cache the image.
+ */
+ gdispImageError gdispImageCache(gdispImage *img);
+
+ /**
+ * @brief Draw the image
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] g The display to draw on
+ * @param[in] img The image structure
+ * @param[in] x,y The screen location to draw the image
+ * @param[in] cx,cy The area on the screen to draw
+ * @param[in] sx,sy The image position to start drawing at
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image
+ * is simply not drawn.
+ * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a
+ * fast blit from the cached frame. If not, it reads the input and decodes it as it
+ * is drawing. This may be significantly slower than if the image has been cached (but
+ * uses a lot less RAM)
+ */
+ gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ #define gdispImageDraw(img,x,y,cx,cy,sx,sy) gdispGImageDraw(GDISP,img,x,y,cx,cy,sx,sy)
+
+ /**
+ * @brief Prepare for the next frame/page in the image file.
+ * @return A time in milliseconds to keep displaying the current frame before trying to draw
+ * the next frame. Watch out for the special values TIME_IMMEDIATE and TIME_INFINITE.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note It will return TIME_IMMEDIATE if the first frame/page hasn't been drawn or if the next frame
+ * should be drawn immediately.
+ * @note It will return TIME_INFINITE if another image frame doesn't exist or an error has occurred.
+ * @note Images that support multiple pages (eg TIFF files) will return TIME_IMMEDIATE between pages
+ * and then TIME_INFINITE when there are no more pages.
+ * @note An image that displays a looped animation will never return TIME_INFINITE unless it
+ * gets an error.
+ * @note Calling gdispImageDraw() after getting a TIME_INFINITE will go back to drawing the first
+ * frame/page.
+ */
+ delaytime_t gdispImageNext(gdispImage *img);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */
+#endif /* _GDISP_IMAGE_H */
+/** @} */
+
diff --git a/src/gdisp/mcufont/mf_config.h b/src/gdisp/mcufont/mf_config.h
index 36268c6b..88838c1d 100644
--- a/src/gdisp/mcufont/mf_config.h
+++ b/src/gdisp/mcufont/mf_config.h
@@ -14,7 +14,7 @@
* Configuration settings related to GFX *
*******************************************************/
-#include <gfx.h>
+#include "gfx.h"
#if !GFX_USE_GDISP || !GDISP_NEED_TEXT
#define MF_NO_COMPILE // Don't compile any font code
@@ -31,7 +31,7 @@
#endif
#define MF_USE_KERNING GDISP_NEED_TEXT_KERNING
-#define MF_FONT_FILE_NAME "../src/gdisp/fonts/fonts.h"
+#define MF_FONT_FILE_NAME "src/gdisp/fonts/fonts.h"
/* These are not used for now */
#define MF_USE_ADVANCED_WORDWRAP 0
diff --git a/src/gdisp/sys_defs.h b/src/gdisp/sys_defs.h
new file mode 100644
index 00000000..a40d6e80
--- /dev/null
+++ b/src/gdisp/sys_defs.h
@@ -0,0 +1,994 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gdisp/sys_defs.h
+ * @brief GDISP Graphic Driver subsystem header file.
+ *
+ * @addtogroup GDISP
+ *
+ * @brief Module to interface graphic / pixel oriented displays
+ *
+ * @details The GDISP module provides high level abstraction to interface pixel oriented graphic displays.
+ *
+ * @pre GFX_USE_GDISP must be set to TRUE in gfxconf.h
+ *
+ * @note Each drawing routine supports a gispXXXX and a gdispGXXXX function. The difference is that the
+ * gdispXXXX function does not require a display to be specified. Note there is a slight anomoly
+ * in the naming with gdispGBlitArea() vs gdispBlitAreaEx() and gdispBlitArea(), the later of
+ * which is now deprecated.
+ * @{
+ */
+
+#ifndef _GDISP_H
+#define _GDISP_H
+
+#include "gfx.h"
+
+/* This type definition is defined here as it gets used in other gfx sub-systems even
+ * if GFX_USE_GDISP is FALSE.
+ */
+
+/**
+ * @brief The type for a coordinate or length on the screen.
+ */
+typedef int16_t coord_t;
+
+#if GFX_USE_GDISP || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/**
+ * @brief Type for a 2D point on the screen.
+ */
+typedef struct point { coord_t x, y; } point, point_t;
+/**
+ * @brief Type for the text justification.
+ */
+typedef enum justify { justifyLeft=0, justifyCenter=1, justifyRight=2 } justify_t;
+/**
+ * @brief Type for the font metric.
+ */
+typedef enum fontmetric { fontHeight, fontDescendersHeight, fontLineSpacing, fontCharPadding, fontMinWidth, fontMaxWidth } fontmetric_t;
+/**
+ * @brief The type of a font.
+ */
+typedef const struct mf_font_s* font_t;
+/**
+ * @brief Type for the screen orientation.
+ * @note GDISP_ROTATE_LANDSCAPE and GDISP_ROTATE_PORTRAIT are internally converted to the
+ * most appropriate other orientation.
+ */
+typedef enum orientation { GDISP_ROTATE_0=0, GDISP_ROTATE_90=90, GDISP_ROTATE_180=180, GDISP_ROTATE_270=270, GDISP_ROTATE_PORTRAIT=1000, GDISP_ROTATE_LANDSCAPE=1001 } orientation_t;
+/**
+ * @brief Type for the available power modes for the screen.
+ */
+typedef enum powermode { powerOff, powerSleep, powerDeepSleep, powerOn } powermode_t;
+
+/*
+ * This is not documented in Doxygen as it is meant to be a black-box.
+ * Applications should always use the routines and macros defined
+ * below to access it in case the implementation ever changed.
+ */
+typedef struct GDISPControl {
+ coord_t Width;
+ coord_t Height;
+ orientation_t Orientation;
+ powermode_t Powermode;
+ uint8_t Backlight;
+ uint8_t Contrast;
+} GDISPControl;
+
+/*
+ * Our black box display structure. We know only one thing about it...
+ * The first member is a GDISPControl structure.
+ */
+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().
+ */
+extern GDisplay *GDISP;
+
+/*===========================================================================*/
+/* Constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver Control Constants
+ * @details Unsupported control codes are ignored.
+ * @note The value parameter should always be typecast to (void *).
+ * @note There are some predefined and some specific to the low level driver.
+ * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
+ * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
+ * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
+ * that only supports off/on anything other
+ * than zero is on.
+ * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
+ * GDISP_CONTROL_LLD - Low level driver control constants start at
+ * this value.
+ */
+#define GDISP_CONTROL_POWER 0
+#define GDISP_CONTROL_ORIENTATION 1
+#define GDISP_CONTROL_BACKLIGHT 2
+#define GDISP_CONTROL_CONTRAST 3
+#define GDISP_CONTROL_LLD 1000
+
+/*===========================================================================*/
+/* Defines relating to the display hardware */
+/*===========================================================================*/
+
+#if !defined(GDISP_TOTAL_CONTROLLERS) || GDISP_TOTAL_CONTROLLERS == 1
+ // Pull in the default hardware configuration for a single controller.
+ // If we have multiple controllers the settings must be set in the
+ // users gfxconf.h file.
+ #include "gdisp_lld_config.h"
+
+ // Unless the user has specified a specific pixel format, use
+ // the native format for the controller.
+ #if !defined(GDISP_PIXELFORMAT) && defined(GDISP_LLD_PIXELFORMAT)
+ #define GDISP_PIXELFORMAT GDISP_LLD_PIXELFORMAT
+ #endif
+#endif
+
+/**
+ * @name GDISP pixel format choices
+ * @{
+ */
+ /**
+ * @brief The pixel format.
+ * @details It generally defaults to the hardware pixel format.
+ * @note This doesn't need to match the hardware pixel format.
+ * It is definitely more efficient when it does.
+ * @note When GDISP_TOTAL_CONTROLLERS > 1, this must
+ * be explicitly defined and should ensure the best match
+ * with your hardware across all devices.
+ */
+ #ifndef GDISP_PIXELFORMAT
+ #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
+ #endif
+ /**
+ * @brief Do pixels require packing for a blit
+ * @note Is only valid for a pixel format that doesn't fill it's datatype. eg formats:
+ * GDISP_PIXELFORMAT_RGB888
+ * GDISP_PIXELFORMAT_RGB444
+ * GDISP_PIXELFORMAT_RGB666
+ * GDISP_PIXELFORMAT_CUSTOM
+ * @note Very few cases should actually require packed pixels as the low
+ * level driver can also pack on the fly as it is sending it
+ * to the graphics device.
+ * @note Packed pixels are not really supported at this point.
+ */
+ #ifndef GDISP_PACKED_PIXELS
+ #define GDISP_PACKED_PIXELS FALSE
+ #endif
+
+ /**
+ * @brief Do lines of pixels require packing for a blit
+ * @note Ignored if GDISP_PACKED_PIXELS is FALSE
+ */
+ #ifndef GDISP_PACKED_LINES
+ #define GDISP_PACKED_LINES FALSE
+ #endif
+/** @} */
+
+/*===========================================================================*/
+/* Defines related to the pixel format */
+/*===========================================================================*/
+
+/* Load our color definitions and pixel formats */
+#include "colors.h"
+
+/**
+ * @brief The type of a pixel.
+ */
+typedef color_t pixel_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Base Functions */
+
+/**
+ * @brief Blend 2 colors according to the alpha
+ * @return The combined color
+ *
+ * @param[in] fg The foreground color
+ * @param[in] bg The background color
+ * @param[in] alpha The alpha value (0-255). 0 is all background, 255 is all foreground.
+ *
+ * @api
+ */
+color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
+
+/**
+ * @brief Get the specified display
+ * @return The pointer to the display or NULL if the display doesn't exist
+ * @note The GDISP variable contains the display used by the gdispXxxx routines
+ * as opposed to the gdispGXxxx routines which take an explicit display
+ * parameter.
+ * @note Displays are numbered from 0 to GDISP_TOTAL_DISPLAYS - 1
+ *
+ * @param[in] display The display number (0..n)
+ *
+ * @api
+ */
+GDisplay *gdispGetDisplay(unsigned display);
+
+/**
+ * @brief Set the current default display to the specified display
+ * @note The default display is used for the gdispXxxx functions.
+ * @note The default display is contained in the variable GDISP. Using
+ * this function to set it protects against it being set to a NULL
+ * value.
+ * @note If a NULL is passed for the dispay this call is ignored.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+void gdispSetDisplay(GDisplay *g);
+
+/* Drawing Functions */
+
+/**
+ * @brief Flush current drawing operations to the display
+ * @note Some low level drivers do not update the display until
+ * the display is flushed. For others it is optional but can
+ * help prevent tearing effects. For some it is ignored.
+ * Calling it at the end of a logic set of drawing operations
+ * in your application will ensure controller portability. If you
+ * know your controller does not need to be flushed there is no
+ * need to call it (which is in reality most controllers).
+ * @note Even for displays that require flushing, there is no need to
+ * call this function if GDISP_NEED_AUTOFLUSH is TRUE.
+ * Calling it again won't hurt though.
+ *
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+void gdispGFlush(GDisplay *g);
+#define gdispFlush() gdispGFlush(GDISP)
+
+/**
+ * @brief Clear the display to the specified color.
+ *
+ * @param[in] g The display to use
+ * @param[in] color The color to use when clearing the screen
+ *
+ * @api
+ */
+void gdispGClear(GDisplay *g, color_t color);
+#define gdispClear(c) gdispGClear(GDISP, c)
+
+/**
+ * @brief Set a pixel in the specified color.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position to set the pixel.
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color);
+#define gdispDrawPixel(x,y,c) gdispGDrawPixel(GDISP,x,y,c)
+
+/**
+ * @brief Draw a line.
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The start position
+ * @param[in] x1,y1 The end position
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+#define gdispDrawLine(x0,y0,x1,y1,c) gdispGDrawLine(GDISP,x0,y0,x1,y1,c)
+
+/**
+ * @brief Fill an area with a color.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#define gdispFillArea(x,y,cx,cy,c) gdispGFillArea(GDISP,x,y,cx,cy,c)
+
+/**
+ * @brief Fill an area using the supplied bitmap.
+ * @details The bitmap is in the pixel format specified by the low level driver
+ * @note If a packed pixel format is used and the width doesn't
+ * match a whole number of bytes, the next line will start on a
+ * non-byte boundary (no end-of-line padding).
+ * @note If GDISP_NEED_ASYNC is defined then the buffer must be static
+ * or at least retained until this call has finished the blit. You can
+ * tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the filled area
+ * @param[in] srcx,srcy The bitmap position to start the fill form
+ * @param[in] srccx The width of a line in the bitmap
+ * @param[in] buffer The bitmap in the driver's pixel format
+ *
+ * @api
+ */
+void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer);
+#define gdispBlitAreaEx(x,y,cx,cy,sx,sy,rx,b) gdispGBlitArea(GDISP,x,y,cx,cy,sx,sy,rx,b)
+
+/**
+ * @brief Draw a rectangular box.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#define gdispDrawBox(x,y,cx,cy,c) gdispGDrawBox(GDISP,x,y,cx,cy,c)
+
+/* Streaming Functions */
+
+#if GDISP_NEED_STREAMING || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streaming operation.
+ * @details Stream data to a window on the display sequentially and very fast.
+ * @note While streaming is in operation - no other calls to GDISP functions
+ * can be made (with the exception of @p gdispBlendColor() and streaming
+ * functions). If a call is made (eg in a multi-threaded application) the other
+ * call is blocked waiting for the streaming operation to finish.
+ * @note @p gdispStreamStop() must be called to finish the streaming operation.
+ * @note If more data is written than the defined area then the results are unspecified.
+ * Some drivers may wrap back to the beginning of the area, others may just
+ * ignore subsequent data.
+ * @note Unlike most operations that clip the defined area to the display to generate
+ * a smaller active area, this call will just silently fail if any of the stream
+ * region lies outside the current clipping area.
+ * @note A streaming operation may be terminated early (without writing to every location
+ * in the stream area) by calling @p gdispStreamStop().
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the streamable area
+ *
+ * @api
+ */
+ void gdispGStreamStart(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy);
+ #define gdispStreamStart(x,y,cx,cy) gdispGStreamStart(GDISP,x,y,cx,cy)
+
+ /**
+ * @brief Send pixel data to the stream.
+ * @details Write a pixel to the next position in the streamed area and increment the position
+ * @pre @p gdispStreamStart() has been called.
+ * @note If the gdispStreamStart() has not been called (or failed due to clipping), the
+ * data provided here is simply thrown away.
+ *
+ * @param[in] g The display to use
+ * @param[in] color The color of the pixel to write
+ *
+ * @api
+ */
+ void gdispGStreamColor(GDisplay *g, color_t color);
+ #define gdispStreamColor(c) gdispGStreamColor(GDISP,c)
+
+ /**
+ * @brief Finish the current streaming operation.
+ * @details Completes the current streaming operation and allows other GDISP calls to operate again.
+ * @pre @p gdispStreamStart() has been called.
+ * @note If the gdispStreamStart() has not been called (or failed due to clipping), this
+ * call is simply ignored.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+ void gdispGStreamStop(GDisplay *g);
+ #define gdispStreamStop() gdispGStreamStop(GDISP)
+#endif
+
+/* Clipping Functions */
+
+#if GDISP_NEED_CLIP || defined(__DOXYGEN__)
+ /**
+ * @brief Clip all drawing to the defined area.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the clip area
+ *
+ * @api
+ */
+ void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy);
+ #define gdispSetClip(x,y,cx,cy) gdispGSetClip(GDISP,x,y,cx,cy)
+#endif
+
+/* Circle Functions */
+
+#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a circle.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the circle
+ * @param[in] radius The radius of the circle
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGDrawCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color);
+ #define gdispDrawCircle(x,y,r,c) gdispGDrawCircle(GDISP,x,y,r,c)
+
+ /**
+ * @brief Draw a filled circle.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the circle
+ * @param[in] radius The radius of the circle
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGFillCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color);
+ #define gdispFillCircle(x,y,r,c) gdispGFillCircle(GDISP,x,y,r,c)
+#endif
+
+/* Ellipse Functions */
+
+#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
+ /**
+ * @brief Draw an ellipse.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #define gdispDrawEllipse(x,y,a,b,c) gdispGDrawEllipse(GDISP,x,y,a,b,c)
+
+ /**
+ * @brief Draw a filled ellipse.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #define gdispFillEllipse(x,y,a,b,c) gdispGFillEllipse(GDISP,x,y,a,b,c)
+#endif
+
+/* Arc Functions */
+
+#if GDISP_NEED_ARC || defined(__DOXYGEN__)
+ /*
+ * @brief Draw an arc.
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The center point
+ * @param[in] radius The radius of the arc
+ * @param[in] start The start angle (0 to 360)
+ * @param[in] end The end angle (0 to 360)
+ * @param[in] color The color of the arc
+ *
+ * @api
+ */
+ void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #define gdispDrawArc(x,y,r,s,e,c) gdispGDrawArc(GDISP,x,y,r,s,e,c)
+
+ /*
+ * @brief Draw a filled arc.
+ * @note Not very efficient currently - does lots of overdrawing
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The center point
+ * @param[in] radius The radius of the arc
+ * @param[in] start The start angle (0 to 360)
+ * @param[in] end The end angle (0 to 360)
+ * @param[in] color The color of the arc
+ *
+ * @api
+ */
+ void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #define gdispFillArc(x,y,r,s,e,c) gdispGFillArc(GDISP,x,y,r,s,e,c)
+#endif
+
+/* Read a pixel Function */
+
+#if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__)
+ /**
+ * @brief Get the color of a pixel.
+ * @return The color of the pixel.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position of the pixel
+ *
+ * @api
+ */
+ color_t gdispGGetPixelColor(GDisplay *g, coord_t x, coord_t y);
+ #define gdispGetPixelColor(x,y) gdispGGetPixelColor(GDISP,x,y)
+#endif
+
+/* Scrolling Function - clears the area scrolled out */
+
+#if GDISP_NEED_SCROLL || defined(__DOXYGEN__)
+ /**
+ * @brief Scroll vertically a section of the screen.
+ * @pre GDISP_NEED_SCROLL must be set to TRUE in gfxconf.h
+ * @note Optional.
+ * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
+ *
+ * @param[in] g The display to use
+ * @param[in] x, y The start of the area to be scrolled
+ * @param[in] cx, cy The size of the area to be scrolled
+ * @param[in] lines The number of lines to scroll (Can be positive or negative)
+ * @param[in] bgcolor The color to fill the newly exposed area.
+ *
+ * @api
+ */
+ void gdispGVerticalScroll(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
+ #define gdispVerticalScroll(x,y,cx,cy,l,b) gdispGVerticalScroll(GDISP,x,y,cx,cy,l,b)
+#endif
+
+/* Set driver specific control */
+
+#if GDISP_NEED_CONTROL || defined(__DOXYGEN__)
+ /**
+ * @brief Control hardware specific parts of the display. eg powermodes, backlight etc
+ * @note Depending on the hardware implementation this function may not
+ * support some codes. They will be ignored.
+ *
+ * @param[in] g The display to use
+ * @param[in] what what you want to control
+ * @param[in] value The value to be assigned
+ *
+ * @api
+ */
+ void gdispGControl(GDisplay *g, unsigned what, void *value);
+ #define gdispControl(w,v) gdispGControl(GDISP,w,v)
+#endif
+
+/* Query driver specific data */
+
+#if GDISP_NEED_QUERY || defined(__DOXYGEN__)
+ /**
+ * @brief Query a property of the display.
+ * @note The result must be typecast to the correct type.
+ * @note An unsupported query will return (void *)-1.
+ *
+ * @param[in] g The display to use
+ * @param[in] what What to query
+ *
+ * @api
+ */
+ void *gdispGQuery(GDisplay *g, unsigned what);
+ #define gdispQuery(w) gdispGQuery(GDISP,w)
+#endif
+
+#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
+ /**
+ * @brief Draw an enclosed polygon (convex, non-convex or complex).
+ *
+ * @param[in] g The display to use
+ * @param[in] tx, ty Transform all points in pntarray by tx, ty
+ * @param[in] pntarray An array of points
+ * @param[in] cnt The number of points in the array
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGDrawPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ #define gdispDrawPoly(x,y,p,i,c) gdispGDrawPoly(GDISP,x,y,p,i,c)
+
+ /**
+ * @brief Fill a convex polygon
+ * @details Doesn't handle non-convex or complex polygons.
+ *
+ * @param[in] g The display to use
+ * @param[in] tx, ty Transform all points in pntarray by tx, ty
+ * @param[in] pntarray An array of points
+ * @param[in] cnt The number of points in the array
+ * @param[in] color The color to use
+ *
+ * @note Convex polygons are those that have no internal angles. That is;
+ * you can draw a line from any point on the polygon to any other point
+ * on the polygon without it going outside the polygon. In our case we generalise
+ * this a little by saying that an infinite horizontal line (at any y value) will cross
+ * no more than two edges on the polygon. Some non-convex polygons do fit this criteria
+ * and can therefore be drawn.
+ * @note This routine is designed to be very efficient with even simple display hardware.
+ *
+ * @api
+ */
+ void gdispGFillConvexPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ #define gdispFillConvexPoly(x,y,p,i,c) gdispGFillConvexPoly(GDISP,x,y,p,i,c)
+
+ /**
+ * @brief Draw a line with a specified thickness
+ * @details The line thickness is specified in pixels. The line ends can
+ * be selected to be either flat or round.
+ * @note Uses gdispGFillConvexPoly() internally to perform the drawing.
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The start position
+ * @param[in] x1,y1 The end position
+ * @param[in] color The color to use
+ * @param[in] width The width of the line
+ * @param[in] round Use round ends for the line
+ *
+ * @api
+ */
+ void gdispGDrawThickLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color, coord_t width, bool_t round);
+ #define gdispDrawThickLine(x0,y0,x1,y1,c,w,r) gdispGDrawThickLine(GDISP,x0,y0,x1,y1,c,w,r)
+#endif
+
+/* Text Functions */
+
+#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a text character.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position for the text
+ * @param[in] c The character to draw
+ * @param[in] font The font to use
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGDrawChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
+ #define gdispDrawChar(x,y,s,f,c) gdispGDrawChar(GDISP,x,y,s,f,c)
+
+ /**
+ * @brief Draw a text character with a filled background.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position for the text
+ * @param[in] c The character to draw
+ * @param[in] font The font to use
+ * @param[in] color The color to use
+ * @param[in] bgcolor The background color to use
+ *
+ * @api
+ */
+ void gdispGFillChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ #define gdispFillChar(x,y,s,f,c,b) gdispGFillChar(GDISP,x,y,s,f,c,b)
+
+ /**
+ * @brief Draw a text string.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position for the text
+ * @param[in] str The string to draw
+ * @param[in] font The font to use
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGDrawString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color);
+ #define gdispDrawString(x,y,s,f,c) gdispGDrawString(GDISP,x,y,s,f,c)
+
+ /**
+ * @brief Draw a text string.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position for the text
+ * @param[in] str The string to draw
+ * @param[in] font The font to use
+ * @param[in] color The color to use
+ * @param[in] bgcolor The background color to use
+ *
+ * @api
+ */
+ void gdispGFillString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
+ #define gdispFillString(x,y,s,f,c,b) gdispGFillString(GDISP,x,y,s,f,c,b)
+
+ /**
+ * @brief Draw a text string vertically centered within the specified box.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position for the text (need to define top-right or base-line - check code)
+ * @param[in] cx,cy The width and height of the box
+ * @param[in] str The string to draw
+ * @param[in] font The font to use
+ * @param[in] color The color to use
+ * @param[in] justify Justify the text left, center or right within the box
+ *
+ * @api
+ */
+ void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
+ #define gdispDrawStringBox(x,y,cx,cy,s,f,c,j) gdispGDrawStringBox(GDISP,x,y,cx,cy,s,f,c,j)
+
+ /**
+ * @brief Draw a text string vertically centered within the specified box. The box background is filled with the specified background color.
+ * @note The entire box is filled
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position for the text (need to define top-right or base-line - check code)
+ * @param[in] cx,cy The width and height of the box
+ * @param[in] str The string to draw
+ * @param[in] font The font to use
+ * @param[in] color The color to use
+ * @param[in] bgColor The background color to use
+ * @param[in] justify Justify the text left, center or right within the box
+ *
+ * @api
+ */
+ void gdispGFillStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify);
+ #define gdispFillStringBox(x,y,cx,cy,s,f,c,b,j) gdispGFillStringBox(GDISP,x,y,cx,cy,s,f,c,b,j)
+
+ /**
+ * @brief Get a metric of a font.
+ * @return The metric requested in pixels.
+ *
+ * @param[in] font The font to test
+ * @param[in] metric The metric to measure
+ *
+ * @api
+ */
+ coord_t gdispGetFontMetric(font_t font, fontmetric_t metric);
+
+ /**
+ * @brief Get the pixel width of a character.
+ * @return The width of the character in pixels. Does not include any between character padding.
+ *
+ * @param[in] c The character to draw
+ * @param[in] font The font to use
+ *
+ * @api
+ */
+ coord_t gdispGetCharWidth(char c, font_t font);
+
+ /**
+ * @brief Get the pixel width of a string.
+ * @return The width of the string in pixels.
+ *
+ * @param[in] str The string to measure
+ * @param[in] font The font to use
+ *
+ * @api
+ */
+ coord_t gdispGetStringWidth(const char* str, font_t font);
+
+ /**
+ * @brief Find a font and return it.
+ * @details The supplied name is matched against the font name. A '*' will replace 0 or more characters.
+ * @return Returns a font or NULL if no matching font could be found.
+ *
+ * @param[in] name The font name to find.
+ *
+ * @note Wildcard matching will match the shortest possible match.
+ *
+ * @api
+ */
+ font_t gdispOpenFont(const char *name);
+
+ /**
+ * @brief Release a font after use.
+ *
+ * @param[in] font The font to release.
+ *
+ * @api
+ */
+ void gdispCloseFont(font_t font);
+
+ /**
+ * @brief Make a scaled copy of an existing font.
+ * @details Allocates memory for new font metadata using gfxAlloc, remember to close font after use!
+ * @return A new font or NULL if out of memory.
+ *
+ * @param[in] font The base font to use.
+ * @param[in] scale_x The scale factor in horizontal direction.
+ * @param[in] scale_y The scale factor in vertical direction.
+ */
+ font_t gdispScaleFont(font_t font, uint8_t scale_x, uint8_t scale_y);
+
+ /**
+ * @brief Get the name of the specified font.
+ * @returns The name of the font.
+ *
+ * @param[in] font The font to get the name for.
+ *
+ * @api
+ */
+ const char *gdispGetFontName(font_t font);
+#endif
+
+/* Extra Arc Functions */
+
+#if GDISP_NEED_ARC || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a rectangular box with rounded corners
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] radius The radius of the rounded corners
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ #define gdispDrawRoundedBox(x,y,cx,cy,r,c) gdispGDrawRoundedBox(GDISP,x,y,cx,cy,r,c)
+
+ /**
+ * @brief Draw a filled rectangular box with rounded corners
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] radius The radius of the rounded corners
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+ void gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ #define gdispFillRoundedBox(x,y,cx,cy,r,c) gdispGFillRoundedBox(GDISP,x,y,cx,cy,r,c)
+#endif
+
+/*
+ * Macro definitions
+ */
+
+/* Now obsolete functions */
+#define gdispBlitArea(x, y, cx, cy, buffer) gdispGBlitArea(GDISP, x, y, cx, cy, 0, 0, cx, buffer)
+
+/* Macro definitions for common gets and sets */
+
+/**
+ * @brief Set the display power mode.
+ * @note Ignored if not supported by the display.
+ *
+ * @param[in] g The display to use
+ * @param[in] powerMode The new power mode
+ *
+ * @api
+ */
+#define gdispGSetPowerMode(g, powerMode) gdispGControl((g), GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+#define gdispSetPowerMode(powerMode) gdispGControl(GDISP, GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+
+/**
+ * @brief Set the display orientation.
+ * @note Ignored if not supported by the display.
+ *
+ * @param[in] g The display to use
+ * @param[in] newOrientation The new orientation
+ *
+ * @api
+ */
+#define gdispGSetOrientation(g, newOrientation) gdispGControl((g), GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+#define gdispSetOrientation(newOrientation) gdispGControl(GDISP, GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+
+/**
+ * @brief Set the display backlight.
+ * @note Ignored if not supported by the display.
+ *
+ * @param[in] g The display to use
+ * @param[in] percent The new brightness (0 - 100%)
+ *
+ * @note For displays that only support backlight off and on,
+ * 0 = off, anything else = on
+ *
+ * @api
+ */
+#define gdispGSetBacklight(g, percent) gdispGControl((g), GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+#define gdispSetBacklight(percent) gdispGControl(GDISP, GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+
+/**
+ * @brief Set the display contrast.
+ * @note Ignored if not supported by the display.
+ *
+ * @param[in] g The display to use
+ * @param[in] percent The new contrast (0 - 100%)
+ *
+ * @api
+ */
+#define gdispGSetContrast(g, percent) gdispGControl((g), GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+#define gdispSetContrast(percent) gdispGControl(GDISP, GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+
+/**
+ * @brief Get the display width in pixels.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGGetWidth(g) (((GDISPControl *)(g))->Width)
+#define gdispGetWidth() gdispGGetWidth(GDISP)
+
+/**
+ * @brief Get the display height in pixels.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGGetHeight(g) (((GDISPControl *)(g))->Height)
+#define gdispGetHeight() gdispGGetHeight(GDISP)
+
+/**
+ * @brief Get the current display power mode.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGGetPowerMode(g) (((GDISPControl *)(g))->Powermode)
+#define gdispGetPowerMode() gdispGGetPowerMode(GDISP)
+
+/**
+ * @brief Get the current display orientation.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGGetOrientation(g) (((GDISPControl *)(g))->Orientation)
+#define gdispGetOrientation() gdispGGetOrientation(GDISP)
+
+/**
+ * @brief Get the current display backlight brightness.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGGetBacklight(g) (((GDISPControl *)(g))->Backlight)
+#define gdispGetBacklight() gdispGGetBacklight(GDISP)
+
+/**
+ * @brief Get the current display contrast.
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGGetContrast(g) (((GDISPControl *)(g))->Contrast)
+#define gdispGetContrast() gdispGGetContrast(GDISP)
+
+/* More interesting macro's */
+
+/**
+ * @brief Reset the clip area to the full screen
+ *
+ * @param[in] g The display to use
+ *
+ * @api
+ */
+#define gdispGUnsetClip(g) gdispGSetClip((g),0,0,gdispGGetWidth(g),gdispGGetHeight(g))
+#define gdispUnsetClip() gdispGUnsetClip(GDISP)
+
+#ifdef __cplusplus
+}
+#endif
+
+#if GDISP_NEED_IMAGE || defined(__DOXYGEN__)
+ #include "src/gdisp/image.h"
+#endif
+
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_H */
+/** @} */
diff --git a/src/gdisp/gdisp.mk b/src/gdisp/sys_make.mk
index a133ce37..a133ce37 100644
--- a/src/gdisp/gdisp.mk
+++ b/src/gdisp/sys_make.mk
diff --git a/src/gdisp/sys_options.h b/src/gdisp/sys_options.h
new file mode 100644
index 00000000..a38e4c6f
--- /dev/null
+++ b/src/gdisp/sys_options.h
@@ -0,0 +1,381 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gdisp/sys_options.h
+ * @brief GDISP sub-system options header file.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_OPTIONS_H
+#define _GDISP_OPTIONS_H
+
+/**
+ * @name GDISP Functionality to be included
+ * @{
+ */
+ /**
+ * @brief Should the startup logo be displayed
+ *
+ * @details Defaults to TRUE
+ */
+ #ifndef GDISP_NEED_STARTUP_LOGO
+ #define GDISP_NEED_STARTUP_LOGO TRUE
+ #endif
+ /**
+ * @brief Should drawing operations be automatically flushed.
+ * @details Defaults to FALSE
+ * @note If set to FALSE and the controller requires flushing
+ * then the application must manually call @p gdispGFlush().
+ * Setting this to TRUE causes GDISP to automatically flush
+ * after each drawing operation. Note this may be slow but enables
+ * an application to avoid having to manually call the flush routine.
+ * @note If TRUE and GDISP_NEED_TIMERFLUSH is also TRUE, this takes precedence.
+ * @note Most controllers don't need flushing which is why this is set to
+ * FALSE by default.
+ */
+ #ifndef GDISP_NEED_AUTOFLUSH
+ #define GDISP_NEED_AUTOFLUSH FALSE
+ #endif
+ /**
+ * @brief Should drawing operations be automatically flushed on a timer.
+ * @details Defaults to FALSE, Can be set to FALSE or a timer period in milliseconds.
+ * @note The period should not be set too short or it will consume all your CPU. A
+ * value between 250 and 500 milliseconds would probably be suitable.
+ * @note If TRUE and GDISP_NEED_AUTOFLUSH is also TRUE, this is ineffective.
+ * @note Most controllers don't need flushing which is why this is set to
+ * FALSE by default.
+ */
+ #ifndef GDISP_NEED_TIMERFLUSH
+ #define GDISP_NEED_TIMERFLUSH FALSE
+ #endif
+ /**
+ * @brief Should all operations be clipped to the screen and colors validated.
+ * @details Defaults to TRUE.
+ * @note If this is FALSE, any operations that extend beyond the
+ * edge of the screen will have undefined results. Any
+ * out-of-range colors will produce undefined results.
+ * @note This should always be left as the default (TRUE) unless you
+ * are a maniac for speed and you have thoroughly tested your code
+ * and it never overwrites the edges of the screen.
+ * @note Setting GDISP_NEED_CLIP to TRUE internally uses the same mechanism
+ * as this validation. There is no advantage in setting this FALSE if
+ * GDISP_NEED_CLIP is TRUE.
+ */
+ #ifndef GDISP_NEED_VALIDATION
+ #define GDISP_NEED_VALIDATION TRUE
+ #endif
+ /**
+ * @brief Are clipping functions needed.
+ * @details Defaults to TRUE
+ */
+ #ifndef GDISP_NEED_CLIP
+ #define GDISP_NEED_CLIP TRUE
+ #endif
+ /**
+ * @brief Streaming functions are needed
+ * @details Defaults to FALSE.
+ */
+ #ifndef GDISP_NEED_STREAMING
+ #define GDISP_NEED_STREAMING FALSE
+ #endif
+ /**
+ * @brief Are text functions needed.
+ * @details Defaults to FALSE
+ * @note You must also define at least one font.
+ */
+ #ifndef GDISP_NEED_TEXT
+ #define GDISP_NEED_TEXT FALSE
+ #endif
+ /**
+ * @brief Are circle functions needed.
+ * @details Defaults to FALSE
+ * @note Uses integer algorithms only. It does not use any trig or floating point.
+ */
+ #ifndef GDISP_NEED_CIRCLE
+ #define GDISP_NEED_CIRCLE FALSE
+ #endif
+ /**
+ * @brief Are ellipse functions needed.
+ * @details Defaults to FALSE
+ * @note Uses integer algorithms only. It does not use any trig or floating point.
+ */
+ #ifndef GDISP_NEED_ELLIPSE
+ #define GDISP_NEED_ELLIPSE FALSE
+ #endif
+ /**
+ * @brief Are arc functions needed.
+ * @details Defaults to FALSE
+ * @note This can be compiled using fully integer mathematics by
+ * defining GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG as TRUE.
+ * @note This can be compiled to use floating point but no trig functions
+ * by defining GFX_USE_GMISC and GMISC_NEED_FASTTRIG as TRUE.
+ * @note If neither of the above are defined it requires the maths library
+ * to be included in the link to provide floating point and trig support.
+ * ie include -lm in your compiler flags.
+ */
+ #ifndef GDISP_NEED_ARC
+ #define GDISP_NEED_ARC FALSE
+ #endif
+ /**
+ * @brief Are convex polygon functions needed.
+ * @details Defaults to FALSE
+ * @note Convex polygons are those that have no internal angles. That is;
+ * you can draw a line from any point on the polygon to any other point
+ * on the polygon without it going outside the polygon.
+ */
+ #ifndef GDISP_NEED_CONVEX_POLYGON
+ #define GDISP_NEED_CONVEX_POLYGON FALSE
+ #endif
+ /**
+ * @brief Are scrolling functions needed.
+ * @details Defaults to FALSE
+ * @note This function must be supported by the low level GDISP driver
+ * you have included in your project. If it isn't, defining this
+ * option will cause a compile error.
+ */
+ #ifndef GDISP_NEED_SCROLL
+ #define GDISP_NEED_SCROLL FALSE
+ #endif
+ /**
+ * @brief Is the capability to read pixels back needed.
+ * @details Defaults to FALSE
+ * @note This function must be supported by the low level GDISP driver
+ * you have included in your project. If it isn't, defining this
+ * option will cause a compile error.
+ */
+ #ifndef GDISP_NEED_PIXELREAD
+ #define GDISP_NEED_PIXELREAD FALSE
+ #endif
+ /**
+ * @brief Control some aspect of the hardware operation.
+ * @details Defaults to FALSE
+ * @note This allows control of hardware specific features such as
+ * screen rotation, backlight levels, contrast etc
+ */
+ #ifndef GDISP_NEED_CONTROL
+ #define GDISP_NEED_CONTROL FALSE
+ #endif
+ /**
+ * @brief Query some aspect of the hardware operation.
+ * @details Defaults to FALSE
+ * @note This allows query of hardware specific features
+ */
+ #ifndef GDISP_NEED_QUERY
+ #define GDISP_NEED_QUERY FALSE
+ #endif
+ /**
+ * @brief Is the image interface required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE
+ #define GDISP_NEED_IMAGE FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GDISP Multiple Display Support
+ * @{
+ */
+ /**
+ * @brief The total number of displays.
+ * @note This can be on just one type of controller or spread across several different controllers
+ */
+ #ifndef GDISP_TOTAL_DISPLAYS
+ #define GDISP_TOTAL_DISPLAYS 1
+ #endif
+ /**
+ * @brief The total number of controllers.
+ * @note If this is greater than one, all the hardware acceleration options below
+ * and the pixel format must be manually specified in your gfxconf.h along with
+ * @p GDISP_CONTROLLER_LIST. See the gdisp_lld_config.h in each driver to get a list
+ * of hardware capabilities for each driver in order to work out the common set across
+ * all the controllers you want to use.
+ */
+ #ifndef GDISP_TOTAL_CONTROLLERS
+ #define GDISP_TOTAL_CONTROLLERS 1
+ #endif
+
+ #if defined(__DOXYGEN__)
+ /**
+ * @brief The list of controllers.
+ * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one.
+ * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS.
+ * @note See the gdisp_lld.c in each driver (near the top) to get the name of the VMT for a driver.
+ * @note Replace this example with your own definition in your gfxconf.h file.
+ */
+ #define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_SSD1963
+ /**
+ * @brief The number of displays for each controller.
+ * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one.
+ * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS.
+ * @note The sum of all the display counts must equal @p GDISP_TOTAL_DISPLAYS (3 for this example)
+ * or bad things will happen.
+ * @note Replace this example with your own definition in your gfxconf.h file.
+ */
+ #define GDISP_CONTROLLER_DISPLAYS 2, 1
+ #endif
+/**
+ * @}
+ *
+ * @name GDISP Image Options
+ * @pre GDISP_NEED_IMAGE must be TRUE
+ * @{
+ */
+ /**
+ * @brief Is native image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_NATIVE
+ #define GDISP_NEED_IMAGE_NATIVE FALSE
+ #endif
+ /**
+ * @brief Is GIF image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_GIF
+ #define GDISP_NEED_IMAGE_GIF FALSE
+ #endif
+ /**
+ * @brief Is BMP image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_BMP
+ #define GDISP_NEED_IMAGE_BMP FALSE
+ #endif
+ /**
+ * @brief Is JPG image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_JPG
+ #define GDISP_NEED_IMAGE_JPG FALSE
+ #endif
+ /**
+ * @brief Is PNG image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_PNG
+ #define GDISP_NEED_IMAGE_PNG FALSE
+ #endif
+ /**
+ * @brief Is memory accounting required during image decoding.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_ACCOUNTING
+ #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GDISP Text Rendering Options
+ * @{
+ */
+ /**
+ * @brief Enable UTF-8 support for text rendering.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_UTF8
+ #define GDISP_NEED_UTF8 FALSE
+ #endif
+
+ /**
+ * @brief Enable kerning for font rendering (improves character placement).
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_TEXT_KERNING
+ #define GDISP_NEED_TEXT_KERNING FALSE
+ #endif
+
+ /**
+ * @brief Enable antialiased font support
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_ANTIALIAS
+ #define GDISP_NEED_ANTIALIAS FALSE
+ #endif
+
+/**
+ * @}
+ *
+ * @name GDISP Multi-Threading Options
+ * @{
+ */
+ /**
+ * @brief Do the drawing functions need to be thread-safe.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_MULTITHREAD
+ #define GDISP_NEED_MULTITHREAD FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GDISP Fonts
+ * @{
+ */
+ /**
+ * @brief Predefined built in fonts
+ * @note Turning off the ones you are not using can save program size.
+ */
+
+/**
+ * @}
+ *
+ * @name GDISP Optional Sizing Parameters
+ * @{
+ */
+ /**
+ * @brief The size of pixel buffer (in pixels) used for optimization.
+ * @details Set to zero to guarantee disabling of the buffer.
+ * @note Depending on the driver and what operations the application
+ * needs, this buffer may never be allocated.
+ * @note Setting the size to zero may cause some operations to not
+ * compile eg. Scrolling if there is no hardware scroll support.
+ * @note Increasing the size will speedup certain operations
+ * at the expense of RAM.
+ * @note Currently only used to support scrolling on hardware without
+ * scrolling support, and to increase the speed of streaming
+ * operations on non-streaming hardware where there is a
+ * hardware supported bit-blit.
+ */
+ #ifndef GDISP_LINEBUF_SIZE
+ #define GDISP_LINEBUF_SIZE 128
+ #endif
+/**
+ * @}
+ *
+ * @name GDISP Optional Low Level Driver Defines
+ * @{
+ */
+ /**
+ * @brief Define the default orientation for all displays in the system.
+ * @note GDISP_NEED_CONTROL must also be set (and the hardware must support it)
+ */
+ // #define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE
+ /**
+ * @brief Set the screen height and width.
+ * @note Ignored by some low level GDISP drivers, optional for others.
+ * @note Where these values are allowed, a default is always provided be the low level driver.
+ * @note The list of GDISP low level drivers that allow these to be set are...
+ * WIN32, SSD1289, SSD1963, TestStub
+ */
+ /* #define GDISP_SCREEN_WIDTH nnnn */
+ /* #define GDISP_SCREEN_HEIGHT nnnn */
+ /**
+ * @brief Define which bus interface to use.
+ * @details Only required by the SSD1963 driver.
+ * @note This will be replaced eventually by board definition files
+ */
+ // #define GDISP_USE_FSMC
+ // #define GDISP_USE_GPIO
+/** @} */
+
+#endif /* _GDISP_OPTIONS_H */
+/** @} */
+
diff --git a/src/gdisp/sys_rules.h b/src/gdisp/sys_rules.h
new file mode 100644
index 00000000..83c95216
--- /dev/null
+++ b/src/gdisp/sys_rules.h
@@ -0,0 +1,85 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gdisp/sys_rules.h
+ * @brief GDISP safety rules header file.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_RULES_H
+#define _GDISP_RULES_H
+
+#if GFX_USE_GDISP
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ #ifndef GDISP_CONTROLLER_LIST
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_LIST"
+ #endif
+ #ifndef GDISP_CONTROLLER_DISPLAYS
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_DISPLAYS"
+ #endif
+ #ifndef GDISP_PIXELFORMAT
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_PIXELFORMAT"
+ #endif
+ #endif
+ #if GDISP_NEED_AUTOFLUSH && GDISP_NEED_TIMERFLUSH
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: Both GDISP_NEED_AUTOFLUSH and GDISP_NEED_TIMERFLUSH has been set. GDISP_NEED_TIMERFLUSH has disabled for you."
+ #endif
+ #undef GDISP_NEED_TIMERFLUSH
+ #define GDISP_NEED_TIMERFLUSH FALSE
+ #endif
+ #if GDISP_NEED_TIMERFLUSH
+ #if GDISP_NEED_TIMERFLUSH < 50 || GDISP_NEED_TIMERFLUSH > 1200
+ #error "GDISP: GDISP_NEED_TIMERFLUSH has been set to an invalid value (FALSE, 50-1200)."
+ #endif
+ #if !GFX_USE_GTIMER
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: GDISP_NEED_TIMERFLUSH has been set but GFX_USE_GTIMER has not been set. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GTIMER
+ #define GFX_USE_GTIMER TRUE
+ #undef GDISP_NEED_MULTITHREAD
+ #define GDISP_NEED_MULTITHREAD TRUE
+ #endif
+ #endif
+ #if GDISP_NEED_ANTIALIAS && !GDISP_NEED_PIXELREAD
+ #if GDISP_HARDWARE_PIXELREAD
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: GDISP_NEED_ANTIALIAS has been set but GDISP_NEED_PIXELREAD has not. It has been turned on for you."
+ #endif
+ #undef GDISP_NEED_PIXELREAD
+ #define GDISP_NEED_PIXELREAD TRUE
+ #else
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: GDISP_NEED_ANTIALIAS has been set but your hardware does not support reading back pixels. Anti-aliasing will only occur for filled characters."
+ #endif
+ #endif
+ #endif
+ #if (defined(GDISP_INCLUDE_FONT_SMALL) && GDISP_INCLUDE_FONT_SMALL) || (defined(GDISP_INCLUDE_FONT_LARGER) && GDISP_INCLUDE_FONT_LARGER)
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: An old font (Small or Larger) has been defined. A single default font of UI2 has been added instead."
+ #warning "GDISP: Please see <$(GFXLIB)/include/gdisp/fonts/fonts.h> for a list of available font names."
+ #endif
+ #undef GDISP_INCLUDE_FONT_UI2
+ #define GDISP_INCLUDE_FONT_UI2 TRUE
+ #endif
+ #if GDISP_NEED_IMAGE
+ #if !GFX_USE_GFILE
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: GFX_USE_GFILE is required when GDISP_NEED_IMAGE is TRUE. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GFILE
+ #define GFX_USE_GFILE TRUE
+ #endif
+ #endif
+#endif
+
+#endif /* _GDISP_RULES_H */
+/** @} */
diff --git a/src/gevent/sys_defs.h b/src/gevent/sys_defs.h
new file mode 100644
index 00000000..0e656145
--- /dev/null
+++ b/src/gevent/sys_defs.h
@@ -0,0 +1,234 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gevent/sys_defs.h
+ *
+ * @addtogroup GEVENT
+ *
+ * @brief Module to build a complete many-to-many event system
+ *
+ * @details GEVENT provides a simple to use but yet powerful event
+ * system.
+ *
+ * @pre GFX_USE_GEVENT must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+#ifndef _GEVENT_H
+#define _GEVENT_H
+
+#include "gfx.h"
+
+#if GFX_USE_GEVENT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+typedef uint16_t GEventType;
+ #define GEVENT_NULL 0x0000 // Null Event - Do nothing
+ #define GEVENT_EXIT 0x0001 // The listener is being forced to exit (someone is destroying the listener)
+
+ /* Other event types are allocated in ranges in their respective include files */
+ #define GEVENT_GINPUT_FIRST 0x0100 // GINPUT events range from 0x0100 to 0x01FF
+ #define GEVENT_GWIN_FIRST 0x0200 // GWIN events range from 0x0200 to 0x02FF
+ #define GEVENT_GADC_FIRST 0x0300 // GADC events range from 0x0300 to 0x033F
+ #define GEVENT_GAUDIN_FIRST 0x0340 // GAUDIN events range from 0x0340 to 0x037F
+ #define GEVENT_GAUDOUT_FIRST 0x0380 // GAUDOUT events range from 0x0380 to 0x03BF
+ #define GEVENT_USER_FIRST 0x8000 // Any application defined events start at 0x8000
+
+// This object can be typecast to any GEventXxxxx type to allow any sub-system (or the application) to create events.
+// The prerequisite is that the new status structure type starts with a field named 'type' of type 'GEventType'.
+// The total status structure also must not exceed GEVENT_MAXIMUM_SIZE bytes.
+// For example, this is used by GWIN button events, GINPUT data streams etc.
+typedef union GEvent_u {
+ GEventType type; // The type of this event
+ char pad[GEVENT_MAXIMUM_SIZE]; // This is here to allow static initialisation of GEventObject's in the application.
+} GEvent;
+
+// A special callback function
+typedef void (*GEventCallbackFn)(void *param, GEvent *pe);
+
+// The Listener Object
+typedef struct GListener {
+ gfxSem waitqueue; // Private: Semaphore for the listener to wait on.
+ gfxSem eventlock; // Private: Protect against more than one sources trying to use this event lock at the same time
+ GEventCallbackFn callback; // Private: Call back Function
+ void *param; // Private: Parameter for the callback function.
+ GEvent event; // Public: The event object into which the event information is stored.
+ } GListener;
+
+// The Source Object
+typedef struct GSource_t GSource, *GSourceHandle;
+
+// This structure is passed to a source to describe a contender listener for sending the current event.
+typedef struct GSourceListener_t {
+ GListener *pListener; // The listener
+ GSource *pSource; // The source
+ unsigned listenflags; // The flags the listener passed when the source was assigned to it.
+ unsigned srcflags; // For the source's exclusive use. Initialised as 0 for a new listener source assignment.
+ } GSourceListener;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* How to listen for events (act as a Listener)...
+ 1. Get handles for all the event sources you are interested in.
+ 2. Initialise a listener
+ 3. Attach sources to your listener.
+ - Sources can be attached or detached from a listener at any time.
+ - A source can be attached to more than one listener.
+ 4. Loop on getting listener events
+ 5. When finished detach all sources from the listener
+
+ How to create events (act as a Source)...
+ 1. Provide a funtion to the application that returns a GSourceHandle (which can be a pointer to whatever the source wants)
+ 2. Whenever a possible event occurs call geventGetSourceListener to get a pointer to a GSourceListener.
+ This will return NULL when there are no more listeners.
+ For each listener - check the flags to see if an event should be sent.
+ - use geventGetEvent() to get the event buffer supplied by the listener
+ and then call geventSendEvent to send the event.
+ - Note: geventGetEvent() may return FALSE to indicate the listener is currently not listening and
+ therefore no event should be sent. This situation enables the source to (optionally) flag
+ to the listener on its next wait that there have been missed events.
+ - Note: The GSourceListener pointer (and the GEvent buffer) are only valid between
+ the geventGetSourceListener call and either the geventSendEvent call or the next
+ geventGetSourceListener call.
+ - Note: All listeners must be processed for this event before anything else is processed.
+*/
+
+/*---------- Listener Functions --------------------------------------------*/
+
+/**
+ * @brief Create a Listener
+ * @details If insufficient resources are available it will either assert or return NULL
+ * depending on the value of GEVENT_ASSERT_NO_RESOURCE.
+ *
+ * @param[in] pl A listener
+ */
+void geventListenerInit(GListener *pl);
+
+/**
+ * @brief Attach a source to a listener
+ * @details Flags are interpreted by the source when generating events for each listener.
+ * If this source is already assigned to the listener it will update the flags.
+ * If insufficient resources are available it will either assert or return FALSE
+ * depending on the value of GEVENT_ASSERT_NO_RESOURCE.
+ *
+ * @param[in] pl The listener
+ * @param[in] gsh The source which has to be attached to the listener
+ * @param[in] flags The flags
+ *
+ * @return TRUE if succeeded, FALSE otherwise
+ */
+bool_t geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags);
+
+/**
+ * @brief Detach a source from a listener
+ * @details If gsh is NULL detach all sources from this listener and if there is still
+ * a thread waiting for events on this listener, it is sent the exit event.
+ *
+ * @param[in] pl The listener
+ * @param[in] gsh The source
+ */
+void geventDetachSource(GListener *pl, GSourceHandle gsh);
+
+/**
+ * @brief Wait for an event on a listener from an assigned source.
+ * @details The type of the event should be checked (pevent->type) and then pevent should
+ * be typecast to the actual event type if it needs to be processed.
+ * timeout specifies the time to wait in system ticks.
+ * TIME_INFINITE means no timeout - wait forever for an event.
+ * TIME_IMMEDIATE means return immediately
+ * @note The GEvent buffer is staticly allocated within the GListener so the event does not
+ * need to be dynamicly freed however it will get overwritten by the next call to
+ * this routine.
+ *
+ * @param[in] pl The listener
+ * @param[in] timeout The timeout
+ *
+ * @return NULL on timeout
+ */
+GEvent *geventEventWait(GListener *pl, delaytime_t timeout);
+
+/* @brief Register a callback for an event on a listener from an assigned source.
+ * @details The type of the event should be checked (pevent->type) and then pevent should be typecast to the
+ * actual event type if it needs to be processed.
+ *
+ * @params[in] pl The Listener
+ * @params[in] fn The function to call back
+ * @params[in] param A parameter to pass the callback function
+ *
+ * @note The GEvent buffer is valid only during the time of the callback. The callback MUST NOT save
+ * a pointer to the buffer for use outside the callback.
+ * @note An existing callback function is de-registered by passing a NULL for 'fn'. Any existing
+ * callback function is replaced. Any thread currently waiting using geventEventWait will be sent the exit event.
+ * @note Callbacks occur in a thread context but stack space must be kept to a minumum and
+ * the callback must process quickly as all other events are performed on a single thread.
+ * @note In the callback function you should never call ANY event functions using your own GListener handle
+ * as it WILL create a deadlock and lock the system up.
+ * @note Applications should not use this call - geventEventWait() is the preferred mechanism for an
+ * application. This call is provided for GUI objects that may not have their own thread.
+ */
+void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param);
+
+/*---------- Source Functions --------------------------------------------*/
+
+/**
+ * @brief Called by a source with a possible event to get a listener record.
+ * @details @p lastlr should be NULL on the first call and thereafter the result of the previous call.
+ *
+ * @param[in] gsh The source handler
+ * @param[in] lastlr The source listener
+ *
+ * @return NULL when there are no more listeners for this source
+ */
+GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr);
+
+/**
+ * @brief Get the event buffer from the GSourceListener.
+ * @details A NULL return allows the source to record (perhaps in glr->scrflags) that the listener
+ * has missed events. This can then be notified as part of the next event for the listener.
+ * The buffer can only be accessed untill the next call to geventGetSourceListener
+ * or geventSendEvent
+ *
+ * @param[in] psl The source listener
+ *
+ * @return NULL if the listener is not currently listening.
+ */
+GEvent *geventGetEventBuffer(GSourceListener *psl);
+
+/**
+ * @brief Called by a source to indicate the listener's event buffer has been filled.
+ * @details After calling this function the source must not reference in fields in the GSourceListener or the event buffer.
+ *
+ * @param[in] psl The source listener
+ */
+void geventSendEvent(GSourceListener *psl);
+
+/**
+ * @brief Detach any listener that has this source attached
+ *
+ * @param[in] gsh The source handle
+ */
+void geventDetachSourceListeners(GSourceHandle gsh);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GEVENT */
+
+#endif /* _GEVENT_H */
+/** @} */
+
diff --git a/src/gevent/gevent.mk b/src/gevent/sys_make.mk
index 59226318..5744ae46 100644
--- a/src/gevent/gevent.mk
+++ b/src/gevent/sys_make.mk
@@ -1 +1 @@
-GFXSRC += $(GFXLIB)/src/gevent/gevent.c
+GFXSRC += $(GFXLIB)/src/gevent/gevent.c
diff --git a/src/gevent/sys_options.h b/src/gevent/sys_options.h
new file mode 100644
index 00000000..6a58103f
--- /dev/null
+++ b/src/gevent/sys_options.h
@@ -0,0 +1,55 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gevent/sys_options.h
+ * @brief GEVENT sub-system options header file.
+ *
+ * @addtogroup GEVENT
+ * @{
+ */
+
+#ifndef _GEVENT_OPTIONS_H
+#define _GEVENT_OPTIONS_H
+
+/**
+ * @name GEVENT Functionality to be included
+ * @{
+ */
+ /**
+ * @brief Should routines assert() if they run out of resources.
+ * @details Defaults to FALSE.
+ * @details If FALSE the application must be prepared to handle these
+ * failures.
+ */
+ #ifndef GEVENT_ASSERT_NO_RESOURCE
+ #define GEVENT_ASSERT_NO_RESOURCE FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GEVENT Optional Sizing Parameters
+ * @{
+ */
+ /**
+ * @brief Defines the maximum size of an event status variable.
+ * @details Defaults to 32 bytes
+ */
+ #ifndef GEVENT_MAXIMUM_SIZE
+ #define GEVENT_MAXIMUM_SIZE 32
+ #endif
+ /**
+ * @brief Defines the maximum Source/Listener pairs in the system.
+ * @details Defaults to 32
+ */
+ #ifndef GEVENT_MAX_SOURCE_LISTENERS
+ #define GEVENT_MAX_SOURCE_LISTENERS 32
+ #endif
+/** @} */
+
+#endif /* _GEVENT_OPTIONS_H */
+/** @} */
diff --git a/src/gevent/sys_rules.h b/src/gevent/sys_rules.h
new file mode 100644
index 00000000..8cf7e9b4
--- /dev/null
+++ b/src/gevent/sys_rules.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gevent/sys_rules.h
+ * @brief GEVENT safety rules header file.
+ *
+ * @addtogroup GEVENT
+ * @{
+ */
+
+#ifndef _GEVENT_RULES_H
+#define _GEVENT_RULES_H
+
+#if GFX_USE_GEVENT
+#endif
+
+#endif /* _GEVENT_RULES_H */
+/** @} */
diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c
index 9edafea4..8a3abf9c 100644
--- a/src/gfile/gfile.c
+++ b/src/gfile/gfile.c
@@ -77,42 +77,42 @@ GFILE *gfileStdErr;
* The ChibiOS BaseFileStream VMT
********************************************************/
#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
- #include "../src/gfile/inc_chibiosfs.c"
+ #include "src/gfile/inc_chibiosfs.c"
#endif
/********************************************************
* The Memory Pointer VMT
********************************************************/
#if GFILE_NEED_MEMFS
- #include "../src/gfile/inc_memfs.c"
+ #include "src/gfile/inc_memfs.c"
#endif
/********************************************************
* The RAM file-system VMT
********************************************************/
#if GFILE_NEED_RAMFS
- #include "../src/gfile/inc_ramfs.c"
+ #include "src/gfile/inc_ramfs.c"
#endif
/********************************************************
* The FAT file-system VMT
********************************************************/
#ifndef GFILE_NEED_FATFS
- #include "../src/gfile/inc_fatfs.c"
+ #include "src/gfile/inc_fatfs.c"
#endif
/********************************************************
* The native file-system
********************************************************/
#if GFILE_NEED_NATIVEFS
- #include "../src/gfile/inc_nativefs.c"
+ #include "src/gfile/inc_nativefs.c"
#endif
/********************************************************
* The ROM file-system VMT
********************************************************/
#if GFILE_NEED_ROMFS
- #include "../src/gfile/inc_romfs.c"
+ #include "src/gfile/inc_romfs.c"
#endif
/********************************************************
diff --git a/src/gfile/sys_defs.h b/src/gfile/sys_defs.h
new file mode 100644
index 00000000..675bc4b1
--- /dev/null
+++ b/src/gfile/sys_defs.h
@@ -0,0 +1,169 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gfile/sys_defs.h
+ * @brief GFILE - File IO Routines header file.
+ *
+ * @addtogroup GFILE
+ *
+ * @brief Module which contains Operating system independent FILEIO
+ *
+ * @{
+ */
+
+#ifndef _GFILE_H
+#define _GFILE_H
+
+#include "gfx.h"
+
+#if GFX_USE_GFILE || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/**
+ * @brief A file pointer
+ */
+
+#ifndef GFILE_IMPLEMENTATION
+ typedef void GFILE;
+#else
+ typedef struct GFILE GFILE;
+#endif
+
+extern GFILE *gfileStdIn;
+extern GFILE *gfileStdErr;
+extern GFILE *gfileStdOut;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ bool_t gfileExists(const char *fname);
+ bool_t gfileDelete(const char *fname);
+ long int gfileGetFilesize(const char *fname);
+ bool_t gfileRename(const char *oldname, const char *newname);
+ GFILE * gfileOpen(const char *fname, const char *mode);
+ void gfileClose(GFILE *f);
+ size_t gfileRead(GFILE *f, void *buf, size_t len);
+ size_t gfileWrite(GFILE *f, const void *buf, size_t len);
+ long int gfileGetPos(GFILE *f);
+ bool_t gfileSetPos(GFILE *f, long int pos);
+ long int gfileGetSize(GFILE *f);
+ bool_t gfileEOF(GFILE *f);
+
+ #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
+ GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode);
+ #endif
+ #if GFILE_NEED_MEMFS
+ GFILE * gfileOpenMemory(void *memptr, const char *mode);
+ #endif
+
+ #if GFILE_NEED_PRINTG
+ int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg);
+ int fnprintg(GFILE *f, int maxlen, const char *fmt, ...);
+ #define vfprintg(f,m,a) vfnprintg(f,0,m,a)
+ #define fprintg(f,m,...) fnprintg(f,0,m,...)
+ #define vprintg(m,a) vfnprintg(gfileStdOut,0,m,a)
+ #define printg(m,...) fnprintg(gfileStdOut,0,m,...)
+
+ #if GFILE_NEED_STRINGS
+ int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg);
+ int snprintg(char *buf, int maxlen, const char *fmt, ...);
+ #define vsprintg(s,m,a) vsnprintg(s,0,m,a)
+ #define sprintg(s,m,...) snprintg(s,0,m,...)
+ #endif
+ #endif
+
+ #if GFILE_NEED_SCANG
+ int vfscang(GFILE *f, const char *fmt, va_list arg);
+ int fscang(GFILE *f, const char *fmt, ...);
+ #define vscang(f,a) vfscang(gfileStdIn,f,a)
+ #define scang(f,...) fscang(gfileStdIn,f,...)
+
+ #if GFILE_NEED_STRINGS
+ int vsscang(const char *buf, const char *fmt, va_list arg);
+ int sscang(const char *buf, const char *fmt, ...);
+ #endif
+ #endif
+
+ #if GFILE_NEED_STDIO && !defined(GFILE_IMPLEMENTATION)
+ #define stdin gfileStdIn
+ #define stdout gfileStdOut
+ #define stderr gfileStdErr
+ #define FILENAME_MAX 256 // Use a relatively small number for an embedded platform
+ #define L_tmpnam FILENAME_MAX
+ #define FOPEN_MAX GFILE_MAX_GFILES
+ #define TMP_MAX GFILE_MAX_GFILES
+ #define P_tmpdir "/tmp/"
+ #define FILE GFILE
+ #define fopen(n,m) gfileOpen(n,m)
+ #define fclose(f) gfileClose(f)
+ size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f);
+ size_t gstdioWrite(const void * ptr, size_t size, size_t count, FILE *f);
+ #define fread(p,sz,cnt,f) gstdioRead(p,sz,cnt,f)
+ #define fwrite(p,sz,cnt,f) gstdioWrite(p,sz,cnt,f)
+ int gstdioSeek(FILE *f, size_t offset, int origin);
+ #define fseek(f,ofs,org) gstdioSeek(f,ofs,org)
+ #define SEEK_SET 0
+ #define SEEK_CUR 1
+ #define SEEK_END 2
+ #define remove(n) (!gfileDelete(n))
+ #define rename(o,n) (!gfileRename(o,n))
+ #define fflush(f) (0)
+ #define ftell(f) gfileGetPos(f)
+ #define fpos_t long int
+ int gstdioGetpos(FILE *f, long int *pos);
+ #define fgetpos(f,pos) gstdioGetpos(f,pos)
+ #define fsetpos(f, pos) (!gfileSetPos(f, *pos))
+ #define rewind(f) gfileSetPos(f, 0);
+ #define feof(f) gfileEOF(f)
+
+ #define vfprintf(f,m,a) vfnprintg(f,0,m,a)
+ #define fprintf(f,m,...) fnprintg(f,0,m,...)
+ #define vprintf(m,a) vfnprintg(gfileStdOut,0,m,a)
+ #define printf(m,...) fnprintg(gfileStdOut,0,m,...)
+ #define vsnprintf(s,n,m,a) vsnprintg(s,n,m,a)
+ #define snprintf(s,n,m,...) snprintg(s,n,m,...)
+ #define vsprintf(s,m,a) vsnprintg(s,0,m,a)
+ #define sprintf(s,m,...) snprintg(s,0,m,...)
+ //TODO
+ //void clearerr ( FILE * stream );
+ //int ferror ( FILE * stream );
+ //FILE * tmpfile ( void ); // Auto-deleting
+ //char * tmpnam ( char * str );
+ //char * mktemp (char *template);
+ //FILE * freopen ( const char * filename, const char * mode, FILE * stream );
+ //setbuf
+ //setvbuf
+ //fflush
+ //fgetc
+ //fgets
+ //fputc
+ //fputs
+ //getc
+ //getchar
+ //puts
+ //ungetc
+ //void perror (const char * str);
+ #endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GFILE */
+
+#endif /* _GFILE_H */
+/** @} */
+
diff --git a/src/gfile/gfile.mk b/src/gfile/sys_make.mk
index 381bd6f6..381bd6f6 100644
--- a/src/gfile/gfile.mk
+++ b/src/gfile/sys_make.mk
diff --git a/src/gfile/sys_options.h b/src/gfile/sys_options.h
new file mode 100644
index 00000000..6e36e6b7
--- /dev/null
+++ b/src/gfile/sys_options.h
@@ -0,0 +1,158 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gfile/sys_options.h
+ * @brief GFILE - File IO options header file.
+ *
+ * @addtogroup GFILE
+ * @{
+ */
+
+#ifndef _GFILE_OPTIONS_H
+#define _GFILE_OPTIONS_H
+
+/**
+ * @name GFILE Functionality to be included
+ * @{
+ */
+ /**
+ * @brief Include printg, fprintg etc functions
+ * @details Defaults to FALSE
+ */
+ #ifndef GFILE_NEED_PRINTG
+ #define GFILE_NEED_PRINTG FALSE
+ #endif
+ /**
+ * @brief Include scang, fscang etc functions
+ * @details Defaults to FALSE
+ */
+ #ifndef GFILE_NEED_SCANG
+ #define GFILE_NEED_SCANG FALSE
+ #endif
+ /**
+ * @brief Include the string sprintg/sscang functions
+ * @details Defaults to FALSE
+ * @pre To get sprintg functions you also need to define @p GFILE_NEED_PRINTG
+ * @pre To get sscang functions you also need to define @p GFILE_NEED_SCANG
+ */
+ #ifndef GFILE_NEED_STRINGS
+ #define GFILE_NEED_STRINGS FALSE
+ #endif
+ /**
+ * @brief Map many stdio functions to their GFILE equivalent
+ * @details Defaults to FALSE
+ * @note This replaces the functions in stdio.h with equivalents
+ * - Do not include stdio.h as it has different conflicting definitions.
+ */
+ #ifndef GFILE_NEED_STDIO
+ #define GFILE_NEED_STDIO FALSE
+ #endif
+ /**
+ * @brief Include the ROM file system
+ * @details Defaults to FALSE
+ * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
+ * opening a file on the ROM file system by prefixing
+ * its name with "S|" (the letter 'S', followed by a vertical bar).
+ * @note This requires a file called romfs_files.h to be in the
+ * users project include path. This file should include all the files
+ * converted to .h files using the file2c utility (using flags "-dbcs").
+ */
+ #ifndef GFILE_NEED_ROMFS
+ #define GFILE_NEED_ROMFS FALSE
+ #endif
+ /**
+ * @brief Include the RAM file system
+ * @details Defaults to FALSE
+ * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
+ * opening a file on the RAM file system by prefixing
+ * its name with "R|" (the letter 'R', followed by a vertical bar).
+ * @note You must also define GFILE_RAMFS_SIZE with the size of the file system
+ * to be allocated in RAM.
+ */
+ #ifndef GFILE_NEED_RAMFS
+ #define GFILE_NEED_RAMFS FALSE
+ #endif
+ /**
+ * @brief Include the FAT file system driver
+ * @details Defaults to FALSE
+ * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
+ * opening a file on the FAT file system by prefixing
+ * its name with "F|" (the letter 'F', followed by a vertical bar).
+ * @note You must separately include the FATFS library and code.
+ */
+ #ifndef GFILE_NEED_FATFS
+ #define GFILE_NEED_FATFS FALSE
+ #endif
+ /**
+ * @brief Include the operating system's native file system
+ * @details Defaults to FALSE
+ * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
+ * opening a file on the native file system by prefixing
+ * its name with "N|" (the letter 'N', followed by a vertical bar).
+ * @note If defined then the gfileStdOut and gfileStdErr handles
+ * use the operating system equivalent stdio and stderr.
+ * If it is not defined the gfileStdOut and gfileStdErr io is discarded.
+ */
+ #ifndef GFILE_NEED_NATIVEFS
+ #define GFILE_NEED_NATIVEFS FALSE
+ #endif
+ /**
+ * @brief Include ChibiOS BaseFileStream support
+ * @details Defaults to FALSE
+ * @pre This is only relevant on the ChibiOS operating system.
+ * @note Use the @p gfileOpenBaseFileStream() call to open a GFILE based on a
+ * BaseFileStream. The BaseFileStream must already be open.
+ * @note A GFile of this type cannot be opened by filename. The BaseFileStream
+ * must be pre-opened using the operating system.
+ */
+ #ifndef GFILE_NEED_CHIBIOSFS
+ #define GFILE_NEED_CHIBIOSFS FALSE
+ #endif
+ /**
+ * @brief Include raw memory pointer support
+ * @details Defaults to FALSE
+ * @note Use the @p gfileOpenMemory() call to open a GFILE based on a
+ * memory pointer. The GFILE opened appears to be of unlimited size.
+ * @note A GFile of this type cannot be opened by filename.
+ */
+ #ifndef GFILE_NEED_MEMFS
+ #define GFILE_NEED_MEMFS FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GFILE Optional Parameters
+ * @{
+ */
+ /**
+ * @brief Add floating point support to printg/scang etc.
+ */
+ #ifndef GFILE_ALLOW_FLOATS
+ #define GFILE_ALLOW_FLOATS
+ #endif
+ /**
+ * @brief Can the device be specified as part of the file name.
+ * @note If this is on then a device letter and a vertical bar can be
+ * prefixed on a file name to specify that it must be on a
+ * specific device.
+ */
+ #ifndef GFILE_ALLOW_DEVICESPECIFIC
+ #define GFILE_ALLOW_DEVICESPECIFIC FALSE
+ #endif
+ /**
+ * @brief The maximum number of open files
+ * @note This count excludes gfileStdIn, gfileStdOut and gfileStdErr
+ * (if open by default).
+ */
+ #ifndef GFILE_MAX_GFILES
+ #define GFILE_MAX_GFILES 3
+ #endif
+/** @} */
+
+#endif /* _GFILE_OPTIONS_H */
+/** @} */
diff --git a/src/gfile/sys_rules.h b/src/gfile/sys_rules.h
new file mode 100644
index 00000000..8d07144d
--- /dev/null
+++ b/src/gfile/sys_rules.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gfile/sys_rules.h
+ * @brief GFILE safety rules header file.
+ *
+ * @addtogroup GFILE
+ * @{
+ */
+
+#ifndef _GFILE_RULES_H
+#define _GFILE_RULES_H
+
+#if GFX_USE_GFILE
+#endif
+
+#endif /* _GFILE_RULES_H */
+/** @} */
diff --git a/src/ginput/dial.c b/src/ginput/dial.c
index a9d1858c..410efc1a 100644
--- a/src/ginput/dial.c
+++ b/src/ginput/dial.c
@@ -17,7 +17,7 @@
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
-#include "ginput/lld/dial.h"
+#include "src/ginput/driver_dial.h"
static GTIMER_DECL(DialTimer);
static struct DialStatus_t {
diff --git a/src/ginput/dial.h b/src/ginput/dial.h
new file mode 100644
index 00000000..a90b5e46
--- /dev/null
+++ b/src/ginput/dial.h
@@ -0,0 +1,111 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/ginput/dial.h
+ * @brief GINPUT GFX User Input subsystem header file.
+ *
+ * @defgroup Dial Dial
+ * @ingroup GINPUT
+ *
+ * @details A dial provides a powerful way to navigate through menus
+ * on a display.
+ *
+ * @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h
+ * @pre GINPUT_NEED_DIAL must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+#ifndef _GINPUT_DIAL_H
+#define _GINPUT_DIAL_H
+
+#if GINPUT_NEED_DIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+// Event types for various ginput sources
+#define GEVENT_DIAL (GEVENT_GINPUT_FIRST+4)
+
+typedef struct GEventDial_t {
+ GEventType type; // The type of this event (GEVENT_DIAL)
+ uint16_t instance; // The dial instance
+ uint16_t value; // The dial value
+ uint16_t maxvalue; // The maximum dial value
+ } GEventDial;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @brief Create a dial input instance
+ *
+ * @param[in] instance The ID of the dial input instance (from 0 to 9999)
+ *
+ * @return The soure handle of the created dial instance
+ */
+ GSourceHandle ginputGetDial(uint16_t instance);
+
+ /**
+ * @brief Reset the value back to the hardware default
+ *
+ * @param[in] instance The ID of the dial input instance
+ */
+ void ginputResetDialRange(uint16_t instance);
+
+ /**
+ * @brief Get the maximum value
+ * @details The readings are scaled to be 0 ... max.
+ *
+ * @param[in] instance The ID of the dial input instance
+ *
+ * @return The maximum value
+ */
+ uint16_t ginputGetDialRange(uint16_t instance);
+
+ /**
+ * @brief Set the maximum value
+ * @details The readings are scaled to be 0 ... max.
+ *
+ * @param[in] instance The ID of the dial input instance
+ * @param[in] max The maximum value to be set
+ */
+ void ginputSetDialRange(uint16_t instance, uint16_t max);
+
+ /**
+ * @brief Set the level change required before a dial even is generated (threshold)
+ * @note This is done after range scaling
+ *
+ * @param[in] instance The ID of the dial input instance
+ * @param[in] diff The amount of level changes
+ */
+ void ginputSetDialSensitivity(uint16_t instance, uint16_t diff);
+
+ /**
+ * @brief Get the current dial status
+ *
+ * @param[in] instance The ID of the dial input instance
+ * @param[in] pdial The dial event struct
+ *
+ * @return Returns FALSE on an error (eg invalid instance)
+ */
+ bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GINPUT_NEED_DIAL */
+
+#endif /* _GINPUT_DIAL_H */
+/** @} */
diff --git a/src/ginput/driver_dial.h b/src/ginput/driver_dial.h
new file mode 100644
index 00000000..bf01da20
--- /dev/null
+++ b/src/ginput/driver_dial.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/ginput/driver_dial.h
+ * @brief GINPUT header file for dial drivers.
+ *
+ * @defgroup Dial Dial
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _LLD_GINPUT_DIAL_H
+#define _LLD_GINPUT_DIAL_H
+
+#if GINPUT_NEED_DIAL || defined(__DOXYGEN__)
+
+#include "ginput_lld_dial_config.h"
+
+typedef void (*DialCallbackFn)(uint16_t instance, uint16_t rawvalue);
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ void ginput_lld_dial_init(void);
+ void ginput_lld_dial_poll(DialCallbackFn fn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */
+
+#endif /* _LLD_GINPUT_TOGGLE_H */
+/** @} */
+
diff --git a/src/ginput/driver_mouse.h b/src/ginput/driver_mouse.h
new file mode 100644
index 00000000..21d87dac
--- /dev/null
+++ b/src/ginput/driver_mouse.h
@@ -0,0 +1,178 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/ginput/driver_mouse.h
+ * @brief GINPUT LLD header file for mouse/touch drivers.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _LLD_GINPUT_MOUSE_H
+#define _LLD_GINPUT_MOUSE_H
+
+#if GINPUT_NEED_MOUSE || defined(__DOXYGEN__)
+
+#include "ginput_lld_mouse_config.h"
+
+// GEVENT_MOUSE or GEVENT_TOUCH - What type of device is this.
+#ifndef GINPUT_MOUSE_EVENT_TYPE
+ #define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
+#endif
+
+// TRUE/FALSE - Does the mouse/touch driver require calibration?
+#ifndef GINPUT_MOUSE_NEED_CALIBRATION
+ #define GINPUT_MOUSE_NEED_CALIBRATION FALSE
+#endif
+
+// TRUE/FALSE - Should the calibration happen at the extremes of the panel?
+#ifndef GINPUT_MOUSE_CALIBRATE_EXTREMES
+ #define GINPUT_MOUSE_CALIBRATE_EXTREMES FALSE
+#endif
+
+// TRUE/FALSE - Can the mouse/touch driver itself save calibration data?
+#ifndef GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
+ #define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
+#endif
+
+// n or -1 - n means to test calibration result (+/- pixels), -1 means not to.
+#ifndef GINPUT_MOUSE_MAX_CALIBRATION_ERROR
+ #define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
+#endif
+
+// n - How many times to read (and average) per poll
+#ifndef GINPUT_MOUSE_READ_CYCLES
+ #define GINPUT_MOUSE_READ_CYCLES 1
+#endif
+
+// n - Millisecs between poll's
+#ifndef GINPUT_MOUSE_POLL_PERIOD
+ #define GINPUT_MOUSE_POLL_PERIOD 25
+#endif
+
+// n - Movement allowed without discarding the CLICK or CLICKCXT event (+/- pixels)
+#ifndef GINPUT_MOUSE_MAX_CLICK_JITTER
+ #define GINPUT_MOUSE_MAX_CLICK_JITTER 1
+#endif
+
+// n - Movement allowed without discarding the MOVE event (+/- pixels)
+#ifndef GINPUT_MOUSE_MAX_MOVE_JITTER
+ #define GINPUT_MOUSE_MAX_MOVE_JITTER 0
+#endif
+
+// ms - Millisecs seperating a CLICK from a CXTCLICK
+#ifndef GINPUT_MOUSE_CLICK_TIME
+ #define GINPUT_MOUSE_CLICK_TIME 700
+#endif
+
+// true/false - Whether the mouse driver internally handles screen rotation
+#ifndef GINPUT_MOUSE_NO_ROTATION
+ #define GINPUT_MOUSE_NO_ROTATION FALSE
+#endif
+
+typedef struct MouseReading_t {
+ coord_t x, y, z;
+ uint16_t buttons;
+ } MouseReading;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @brief Initialise the mouse/touch.
+ *
+ * @notapi
+ */
+ void ginput_lld_mouse_init(void);
+
+ /**
+ * @brief Read the mouse/touch position.
+ *
+ * @param[in] pt A pointer to the structure to fill
+ *
+ * @note For drivers that don't support returning a position
+ * when the touch is up (most touch devices), it should
+ * return the previous position with the new Z value.
+ * The z value is the pressure for those touch devices
+ * that support it (-100 to 100 where > 0 is touched)
+ * or, 0 or 100 for those drivers that don't.
+ *
+ * @notapi
+ */
+ void ginput_lld_mouse_get_reading(MouseReading *pt);
+
+ #if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
+ /**
+ * @brief Load calibration data from a storage area on the touch controller.
+ *
+ * @param[in] instance The mouse instance number
+ *
+ * @note The instance parameter is currently always 0 as we only support
+ * one mouse/touch device at a time.
+ * @note This routine should only be provided if the driver has its own
+ * storage area where calibration data can be stored. The drivers
+ * option.h file should define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE = TRUE
+ * if it supports this.
+ *
+ * @notapi
+ */
+ const char *ginput_lld_mouse_calibration_load(uint16_t instance);
+ /**
+ * @brief Save calibration data to a storage area on the touch controller.
+ *
+ * @param[in] instance The mouse instance number
+ * @param[in] calbuf The calibration data to be saved
+ * @param[in] sz The size of the calibration data
+ *
+ * @note The instance parameter is currently always 0 as we only support
+ * one mouse/touch device at a time.
+ * @note This routine should only be provided if the driver has its own
+ * storage area where calibration data can be stored. The drivers
+ * option.h file should define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE = TRUE
+ * if it supports this.
+ *
+ * @notapi
+ */
+ void ginput_lld_mouse_calibration_save(uint16_t instance, const uint8_t *calbuf, size_t sz);
+ #endif
+
+ /**
+ * @brief Wakeup the high level code so that it attempts another read
+ *
+ * @note This routine is provided to low level drivers by the high level code
+ * @note Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
+ *
+ * @notapi
+ */
+ void ginputMouseWakeup(void);
+
+ /**
+ * @brief Wakeup the high level code so that it attempts another read
+ *
+ * @note This routine is provided to low level drivers by the high level code
+ * @note Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
+ *
+ * @iclass
+ * @notapi
+ */
+ void ginputMouseWakeupI(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GINPUT_NEED_MOUSE || GINPUT_NEED_TOUCH */
+
+#endif /* _LLD_GINPUT_MOUSE_H */
+/** @} */
diff --git a/src/ginput/driver_toggle.h b/src/ginput/driver_toggle.h
new file mode 100644
index 00000000..6d672c91
--- /dev/null
+++ b/src/ginput/driver_toggle.h
@@ -0,0 +1,61 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/ginput/driver_toggle.h
+ * @brief GINPUT header file for toggle drivers.
+ *
+ * @defgroup Toggle Toggle
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _LLD_GINPUT_TOGGLE_H
+#define _LLD_GINPUT_TOGGLE_H
+
+#if GINPUT_NEED_TOGGLE || defined(__DOXYGEN__)
+
+// Describes how the toggle bits are obtained
+typedef struct GToggleConfig_t {
+ void *id;
+ unsigned mask;
+ unsigned invert;
+ unsigned mode;
+} GToggleConfig;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES];
+
+ void ginput_lld_toggle_init(const GToggleConfig *ptc);
+ unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc);
+
+ /* This routine is provided to low level drivers to wakeup a value read from a thread context.
+ * Particularly useful if GINPUT_TOGGLE_POLL_PERIOD = TIME_INFINITE
+ */
+ void ginputToggleWakeup(void);
+
+ /* This routine is provided to low level drivers to wakeup a value read from an ISR
+ * Particularly useful if GINPUT_TOGGLE_POLL_PERIOD = TIME_INFINITE
+ */
+ void ginputToggleWakeupI(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */
+
+#endif /* _LLD_GINPUT_TOGGLE_H */
+/** @} */
+
diff --git a/src/ginput/keyboard.h b/src/ginput/keyboard.h
new file mode 100644
index 00000000..d2bebeb8
--- /dev/null
+++ b/src/ginput/keyboard.h
@@ -0,0 +1,128 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/ginput/keyboard.h
+ * @brief GINPUT GFX User Input subsystem header file.
+ *
+ * @defgroup Keyboard Keyboard
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _GINPUT_KEYBOARD_H
+#define _GINPUT_KEYBOARD_H
+
+#if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+#define GINPUT_KEYBOARD_NUM_PORTS 1 // The total number of keyboard inputs
+
+// Event types for various ginput sources
+#define GEVENT_KEYBOARD (GEVENT_GINPUT_FIRST+2)
+
+typedef struct GEventKeyboard_t {
+ GEventType type; // The type of this event (GEVENT_KEYBOARD)
+ uint16_t instance; // The keyboard instance
+ char c; // The Ascii code for the current key press.
+ // The only possible values are 0(NUL), 8(BS), 9(TAB), 13(CR), 27(ESC), 32(SPACE) to 126(~), 127(DEL)
+ // 0 indicates an extended only key.
+ uint16_t code; // An extended keyboard code. Codes less than 128 match their ascii equivelent.
+ #define GKEY_NULL 0
+ #define GKEY_BACKSPACE 8
+ #define GKEY_TAB 9
+ #define GKEY_CR 13
+ #define GKEY_ESC 27
+ #define GKEY_SPACE 32
+ #define GKEY_DEL 127
+ #define GKEY_UP 0x0101
+ #define GKEY_DOWN 0x0102
+ #define GKEY_LEFT 0x0103
+ #define GKEY_RIGHT 0x0104
+ #define GKEY_HOME 0x0105
+ #define GKEY_END 0x0106
+ #define GKEY_PAGEUP 0x0107
+ #define GKEY_PAGEDOWN 0x0108
+ #define GKEY_INSERT 0x0109
+ #define GKEY_DELETE 0x010A
+ #define GKEY_SHIFT 0x0201
+ #define GKEY_CNTRL 0x0202
+ #define GKEY_ALT 0x0203
+ #define GKEY_WINKEY 0x0204
+ #define GKEY_RCLKEY 0x0205
+ #define GKEY_FNKEY 0x0206
+ #define GKEY_FN1 0x0301
+ #define GKEY_FN2 0x0302
+ #define GKEY_FN3 0x0303
+ #define GKEY_FN4 0x0304
+ #define GKEY_FN5 0x0305
+ #define GKEY_FN6 0x0306
+ #define GKEY_FN7 0x0307
+ #define GKEY_FN8 0x0308
+ #define GKEY_FN9 0x0309
+ #define GKEY_FN10 0x030A
+ #define GKEY_FN11 0x030B
+ #define GKEY_FN12 0x030C
+ uint16_t current_buttons; // A bit is set to indicate various meta status.
+ #define GMETA_KEY_DOWN 0x0001
+ #define GMETA_KEY_SHIFT 0x0002
+ #define GMETA_KEY_CNTRL 0x0004
+ #define GMETA_KEY_ALT 0x0008
+ #define GMETA_KEY_WINKEY 0x0010
+ #define GMETA_KEY_RCLKKEY 0x0020
+ #define GMETA_KEY_FN 0x0040
+ #define GMETA_KEY_MISSED_EVENT 0x8000
+ uint16_t last_buttons; // The value of current_buttons on the last event
+} GEventKeyboard;
+
+// Keyboard Listen Flags - passed to geventAddSourceToListener()
+#define GLISTEN_KEYREPEATS 0x0001 // Return key repeats (where the key is held down to get a repeat character)
+#define GLISTEN_KEYCODES 0x0002 // Return all key presses including extended code key presses (not just ascii codes)
+#define GLISTEN_KEYALL 0x0004 // Return keyup's, keydown's and everything in between (but not repeats unless GLISTEN_KEYREPEATS is set).
+#define GLISTEN_KEYSINGLE 0x8000 // Return only when one particular extended code key is pressed or released. The particular extended code is OR'd into this value
+ // eg. (GLISTEN_KEYSINGLE | GKEY_CR)
+ // No other flags may be set with this flag.
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @brief Create a keyboard input instance
+ *
+ * @param[in] instance The ID of the keyboard input instance (from 0 to 9999)
+ *
+ * @return The source handle of the created input instance
+ */
+ GSourceHandle ginputGetKeyboard(uint16_t instance);
+
+ /**
+ * @brief Get the current keyboard status
+ *
+ * @param[in] instance The ID of the keyboard input instance
+ * @param[in] pkeyboard The keyboard event struct
+ *
+ * @return Returns FALSE on an error (eg invalid instance)
+ */
+ bool_t ginputGetKeyboardStatus(uint16_t instance, GEventKeyboard *pkeyboard);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GINPUT_NEED_KEYBOARD */
+
+#endif /* _GINPUT_KEYBOARD_H */
+/** @} */
+
diff --git a/src/ginput/mouse.c b/src/ginput/mouse.c
index aad6119a..c7a20ec1 100644
--- a/src/ginput/mouse.c
+++ b/src/ginput/mouse.c
@@ -17,7 +17,7 @@
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) || defined(__DOXYGEN__)
-#include "ginput/lld/mouse.h"
+#include "src/ginput/driver_mouse.h"
#if GINPUT_MOUSE_NEED_CALIBRATION
#if !defined(GFX_USE_GDISP) || !GFX_USE_GDISP
diff --git a/src/ginput/mouse.h b/src/ginput/mouse.h
new file mode 100644
index 00000000..669eaec6
--- /dev/null
+++ b/src/ginput/mouse.h
@@ -0,0 +1,181 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/ginput/mouse.h
+ * @brief GINPUT GFX User Input subsystem header file for mouse and touch.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ *
+ * @details GINPUT allows it to easily interface touchscreens and mices to
+ * your application.
+ *
+ * @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h
+ * @pre GINPUT_NEED_MOUSE must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GINPUT_MOUSE_H
+#define _GINPUT_MOUSE_H
+
+#if GINPUT_NEED_MOUSE || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/* This type definition is also used by touch */
+typedef struct GEventMouse_t {
+ GEventType type; // The type of this event (GEVENT_MOUSE or GEVENT_TOUCH)
+ uint16_t instance; // The mouse/touch instance
+ coord_t x, y, z; // The position of the mouse.
+ // - For touch devices, Z is the current pressure if supported (otherwise 0)
+ // - For mice, Z is the 3rd dimension if supported (otherwise 0)
+ uint16_t current_buttons; // A bit is set if the button is down.
+ // - For touch only bit 0 is relevant
+ // - For mice the order of the buttons is (from 0 to n) left, right, middle, any other buttons
+ // - Bit 15 being set indicates that an important mouse event has been missed.
+ #define GINPUT_MOUSE_BTN_LEFT 0x0001
+ #define GINPUT_MOUSE_BTN_RIGHT 0x0002
+ #define GINPUT_MOUSE_BTN_MIDDLE 0x0004
+ #define GINPUT_MOUSE_BTN_4 0x0008
+ #define GINPUT_MISSED_MOUSE_EVENT 0x8000
+ #define GINPUT_TOUCH_PRESSED GINPUT_MOUSE_BTN_LEFT
+ uint16_t last_buttons; // The value of current_buttons on the last event
+ enum GMouseMeta_e {
+ GMETA_NONE = 0, // There is no meta event currently happening
+ GMETA_MOUSE_DOWN = 1, // Button 0 has just gone down
+ GMETA_MOUSE_UP = 2, // Button 0 has just gone up
+ GMETA_MOUSE_CLICK = 4, // Button 0 has just gone through a short down - up cycle
+ GMETA_MOUSE_CXTCLICK = 8 // For mice - The right button has just been depressed
+ // For touch - a long press has just occurred
+ } meta;
+ GDisplay * display; // The display this mouse is currently associated with.
+ } GEventMouse;
+
+// Mouse/Touch Listen Flags - passed to geventAddSourceToListener()
+#define GLISTEN_MOUSEMETA 0x0001 // Create events for meta events such as CLICK and CXTCLICK
+#define GLISTEN_MOUSEDOWNMOVES 0x0002 // Creates mouse move events when the primary mouse button is down (touch is on the surface)
+#define GLISTEN_MOUSEUPMOVES 0x0004 // Creates mouse move events when the primary mouse button is up (touch is off the surface - if the hardware allows).
+#define GLISTEN_MOUSENOFILTER 0x0008 // Don't filter out mouse moves where the position hasn't changed.
+#define GLISTEN_TOUCHMETA GLISTEN_MOUSEMETA
+#define GLISTEN_TOUCHDOWNMOVES GLISTEN_MOUSEDOWNMOVES
+#define GLISTEN_TOUCHUPMOVES GLISTEN_MOUSEUPMOVES
+#define GLISTEN_TOUCHNOFILTER GLISTEN_MOUSENOFILTER
+
+#define GINPUT_MOUSE_NUM_PORTS 1 // The total number of mouse/touch inputs supported
+
+// Event types for the mouse ginput source
+#define GEVENT_MOUSE (GEVENT_GINPUT_FIRST+0)
+#define GEVENT_TOUCH (GEVENT_GINPUT_FIRST+1)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @brief Creates an instance of a mouse and returns the Source handler
+ * @note HACK: if the instance is 9999, it is treated as instance 0 except
+ * that no calibration will be performed!
+ *
+ * @param[in] instance The ID of the mouse input instance (from 0 to 9999)
+ *
+ * @return The source handle of the created instance
+ */
+ GSourceHandle ginputGetMouse(uint16_t instance);
+
+ /**
+ * @brief Assign the display associated with the mouse
+ * @note This only needs to be called if the mouse is associated with a display
+ * other than the current default display. It must be called before
+ * @p ginputGetMouse() if the new display is to be used during the calibration
+ * process. Other than calibration the display is used for range checking,
+ * and may also be used to display a mouse pointer.
+ *
+ * @param[in] instance The ID of the mouse input instance
+ * @param[in] g The GDisplay to which this mouse belongs
+ */
+ void ginputSetMouseDisplay(uint16_t instance, GDisplay *g);
+
+ /**
+ * @brief Get the display currently associated with the mouse
+ * @return A pointer to the display
+ *
+ * @param[in] instance The ID of the mouse input instance
+ */
+ GDisplay *ginputGetMouseDisplay(uint16_t instance);
+
+ /**
+ * @brief Get the current mouse position and button status
+ * @note Unlinke a listener event, this status cannot record meta events such as
+ * "CLICK".
+ *
+ * @param[in] instance The ID of the mouse input instance
+ * @param[in] pmouse The mouse event
+ *
+ * @return FALSE on an error (eg. invalid instance)
+ */
+ bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pmouse);
+
+ /**
+ * @brief Performs a calibration
+ *
+ * @param[in] instance The ID of the mouse input instance
+ *
+ * @return FALSE if the driver dosen't support a calibration of if the handle is invalid
+ */
+ bool_t ginputCalibrateMouse(uint16_t instance);
+
+ /* Set the routines to save and fetch calibration data.
+ * This function should be called before first calling ginputGetMouse() for a particular instance
+ * as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
+ * If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
+ * The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
+ */
+ typedef void (*GMouseCalibrationSaveRoutine)(uint16_t instance, const uint8_t *calbuf, size_t sz); // Save calibration data
+ typedef const char * (*GMouseCalibrationLoadRoutine)(uint16_t instance); // Load calibration data (returns NULL if not data saved)
+
+ /**
+ * @brief Set the routines to store and restore calibration data
+ *
+ * @details This function should be called before first calling ginputGetMouse() for a particular instance
+ * as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
+ * If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the
+ * data is has already obtained.
+ *
+ * @param[in] instance The ID of the mouse input instance
+ * @param[in] fnsave The routine to save the data
+ * @param[in] fnload The routine to restore the data
+ * @param[in] requireFree TRUE if the buffer returned by the load function must be freed by the mouse code.
+ */
+ void ginputSetMouseCalibrationRoutines(uint16_t instance, GMouseCalibrationSaveRoutine fnsave, GMouseCalibrationLoadRoutine fnload, bool_t requireFree);
+
+ /**
+ * @brief Test if a particular mouse/touch instance requires routines to save it's alibration data
+ * @note Not implemented yet
+ *
+ * @param[in] instance The ID of the mouse input instance
+ *
+ * @return TRUE if needed
+ */
+ bool_t ginputRequireMouseCalibrationStorage(uint16_t instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GINPUT_NEED_MOUSE */
+
+#endif /* _GINPUT_MOUSE_H */
+/** @} */
+
diff --git a/src/ginput/sys_defs.h b/src/ginput/sys_defs.h
new file mode 100644
index 00000000..33259da4
--- /dev/null
+++ b/src/ginput/sys_defs.h
@@ -0,0 +1,50 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/ginput/sys_defs.h
+ *
+ * @addtogroup GINPUT
+ *
+ * @brief Module to interface different hardware input sources such as touchscreens
+ *
+ * @details GINPUT provides an easy and common interface to use different input devices
+ * such as touchscreens and mices.
+ *
+ * @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+#ifndef _GINPUT_H
+#define _GINPUT_H
+
+#include "gfx.h"
+
+#if GFX_USE_GINPUT || defined(__DOXYGEN__)
+
+/* How to use...
+
+ 1. Get source handles for all the inputs you are interested in.
+ - Attempting to get a handle for one instance of an input more than once will return the same handle
+ 2. Create a listener
+ 3. Assign inputs to your listener.
+ - Inputs can be assigned or released from a listener at any time.
+ - An input can be assigned to more than one listener.
+ 4. Loop on getting listener events
+ 5. When complete destroy the listener
+*/
+
+// Include various ginput types
+#include "src/ginput/mouse.h"
+#include "src/ginput/keyboard.h"
+#include "src/ginput/toggle.h"
+#include "src/ginput/dial.h"
+
+#endif /* GFX_USE_GINPUT */
+
+#endif /* _GINPUT_H */
+/** @} */
diff --git a/src/ginput/ginput.mk b/src/ginput/sys_make.mk
index ed34d46d..34ac4a55 100644
--- a/src/ginput/ginput.mk
+++ b/src/ginput/sys_make.mk
@@ -1,5 +1,5 @@
-GFXSRC += $(GFXLIB)/src/ginput/ginput.c \
- $(GFXLIB)/src/ginput/mouse.c \
- $(GFXLIB)/src/ginput/keyboard.c \
- $(GFXLIB)/src/ginput/toggle.c \
- $(GFXLIB)/src/ginput/dial.c
+GFXSRC += $(GFXLIB)/src/ginput/ginput.c \
+ $(GFXLIB)/src/ginput/mouse.c \
+ $(GFXLIB)/src/ginput/keyboard.c \
+ $(GFXLIB)/src/ginput/toggle.c \
+ $(GFXLIB)/src/ginput/dial.c
diff --git a/src/ginput/sys_options.h b/src/ginput/sys_options.h
new file mode 100644
index 00000000..c606262b
--- /dev/null
+++ b/src/ginput/sys_options.h
@@ -0,0 +1,114 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/ginput/sys_options.h
+ * @brief GINPUT sub-system options header file.
+ *
+ * @addtogroup GINPUT
+ * @{
+ */
+
+#ifndef _GINPUT_OPTIONS_H
+#define _GINPUT_OPTIONS_H
+
+/**
+ * @name GINPUT Functionality to be included
+ * @{
+ */
+ /**
+ * @brief Should mouse/touch functions be included.
+ * @details Defaults to FALSE
+ * @note Also add the a mouse/touch hardware driver to your makefile.
+ * Eg.
+ * include $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld.mk
+ */
+ #ifndef GINPUT_NEED_MOUSE
+ #define GINPUT_NEED_MOUSE FALSE
+ #endif
+ /**
+ * @brief Should keyboard functions be included.
+ * @details Defaults to FALSE
+ * @note Also add the a keyboard hardware driver to your makefile.
+ * Eg.
+ * include $(GFXLIB)/drivers/ginput/keyboard/XXXX/ginput_lld.mk
+ */
+ #ifndef GINPUT_NEED_KEYBOARD
+ #define GINPUT_NEED_KEYBOARD FALSE
+ #endif
+ /**
+ * @brief Should hardware toggle/switch/button functions be included.
+ * @details Defaults to FALSE
+ * @note Also add the a toggle hardware driver to your makefile.
+ * Eg.
+ * include $(GFXLIB)/drivers/ginput/toggle/Pal/ginput_lld.mk
+ */
+ #ifndef GINPUT_NEED_TOGGLE
+ #define GINPUT_NEED_TOGGLE FALSE
+ #endif
+ /**
+ * @brief Should analog dial functions be included.
+ * @details Defaults to FALSE
+ * @note Also add the a dial hardware driver to your makefile.
+ * Eg.
+ * include $(GFXLIB)/drivers/ginput/dial/analog/ginput_lld.mk
+ */
+ #ifndef GINPUT_NEED_DIAL
+ #define GINPUT_NEED_DIAL FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GINPUT Optional Sizing Parameters
+ * @{
+ */
+/**
+ * @}
+ *
+ * @name GINPUT Optional Low Level Driver Defines
+ * @{
+ */
+ /**
+ * @brief Use a custom board definition for the mouse/touch driver even if a board definition exists.
+ * @details Defaults to FALSE
+ * @details If TRUE, add ginput_lld_mouse_board.h to your project directory and customise it.
+ * @note Not all GINPUT mouse/touch low level drivers use board definition files.
+ */
+ #ifndef GINPUT_MOUSE_USE_CUSTOM_BOARD
+ #define GINPUT_MOUSE_USE_CUSTOM_BOARD FALSE
+ #endif
+ /**
+ * @brief Use a custom board definition for the keyboard driver even if a board definition exists.
+ * @details Defaults to FALSE
+ * @details If TRUE, add ginput_lld_keyboard_board.h to your project directory and customise it.
+ * @note Not all GINPUT keyboard low level drivers use board definition files.
+ */
+ #ifndef GINPUT_KEYBOARD_USE_CUSTOM_BOARD
+ #define GINPUT_KEYBOARD_USE_CUSTOM_BOARD FALSE
+ #endif
+ /**
+ * @brief Use a custom board definition for the toggle driver even if a board definition exists.
+ * @details Defaults to FALSE
+ * @details If TRUE, add ginput_lld_toggle_board.h to your project directory and customise it.
+ * @note Not all GINPUT toggle low level drivers use board definition files.
+ */
+ #ifndef GINPUT_TOGGLE_USE_CUSTOM_BOARD
+ #define GINPUT_TOGGLE_USE_CUSTOM_BOARD FALSE
+ #endif
+ /**
+ * @brief Use a custom board definition for the dial driver even if a board definition exists.
+ * @details Defaults to FALSE
+ * @details If TRUE, add ginput_lld_dial_board.h to your project directory and customise it.
+ * @note Not all GINPUT dial low level drivers use board definition files.
+ */
+ #ifndef GINPUT_DIAL_USE_CUSTOM_BOARD
+ #define GINPUT_DIAL_USE_CUSTOM_BOARD FALSE
+ #endif
+/** @} */
+
+#endif /* _GINPUT_OPTIONS_H */
+/** @} */
diff --git a/src/ginput/sys_rules.h b/src/ginput/sys_rules.h
new file mode 100644
index 00000000..f98cc469
--- /dev/null
+++ b/src/ginput/sys_rules.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/ginput/sys_rules.h
+ * @brief GINPUT safety rules header file.
+ *
+ * @addtogroup GINPUT
+ * @{
+ */
+
+#ifndef _GINPUT_RULES_H
+#define _GINPUT_RULES_H
+
+#if GFX_USE_GINPUT
+ #if !GFX_USE_GEVENT
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GINPUT: GFX_USE_GEVENT is required if GFX_USE_GINPUT is TRUE. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GEVENT
+ #define GFX_USE_GEVENT TRUE
+ #endif
+ #if !GFX_USE_GTIMER
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GINPUT: GFX_USE_GTIMER is required if GFX_USE_GINPUT is TRUE. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GTIMER
+ #define GFX_USE_GTIMER TRUE
+ #endif
+#endif
+
+#endif /* _GINPUT_RULES_H */
+/** @} */
diff --git a/src/ginput/toggle.c b/src/ginput/toggle.c
index ec089ecb..aad9c862 100644
--- a/src/ginput/toggle.c
+++ b/src/ginput/toggle.c
@@ -17,7 +17,7 @@
#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) || defined(__DOXYGEN__)
-#include "ginput/lld/toggle.h"
+#include "src/ginput/driver_toggle.h"
#define GINPUT_TOGGLE_ISON 0x01
#define GINPUT_TOGGLE_INVERT 0x02
diff --git a/src/ginput/toggle.h b/src/ginput/toggle.h
new file mode 100644
index 00000000..73cf1e27
--- /dev/null
+++ b/src/ginput/toggle.h
@@ -0,0 +1,100 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/ginput/toggle.h
+ * @brief GINPUT GFX User Input subsystem header file.
+ *
+ * @defgroup Toggle Toggle
+ * @ingroup GINPUT
+ *
+ * @details GINPUT allows it to interface toggle buttons easily to your
+ * application.
+ *
+ * @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h
+ * @pre GINPUT_NEED_TOGGLE must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GINPUT_TOGGLE_H
+#define _GINPUT_TOGGLE_H
+
+#if GINPUT_NEED_TOGGLE || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Low Level Driver details and error checks. */
+/*===========================================================================*/
+
+// Get the hardware definitions - Number of instances etc.
+#include "ginput_lld_toggle_config.h"
+
+#ifndef GINPUT_TOGGLE_POLL_PERIOD
+ #define GINPUT_TOGGLE_POLL_PERIOD 200
+#endif
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+// Event types for various ginput sources
+#define GEVENT_TOGGLE (GEVENT_GINPUT_FIRST+3)
+
+typedef struct GEventToggle_t {
+ GEventType type; // The type of this event (GEVENT_TOGGLE)
+ uint16_t instance; // The toggle instance
+ bool_t on; // True if the toggle/button is on
+ } GEventToggle;
+
+// Toggle Listen Flags - passed to geventAddSourceToListener()
+#define GLISTEN_TOGGLE_ON 0x0001 // Return an event when the toggle turns on
+#define GLISTEN_TOGGLE_OFF 0x0002 // Return an event when the toggle turns off
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @brief Create a toggle input instance
+ *
+ * @param[in] instance The ID of the toggle input instance (from 0 to 9999)
+ *
+ * @return The source handle of the created instance
+ */
+ GSourceHandle ginputGetToggle(uint16_t instance);
+
+ /**
+ * @brief Can be used to invert the sense of a toggle
+ *
+ * @param[in] instance The ID of the toggle input instance
+ * @param[in] invert If TRUE, will be inverted
+ */
+ void ginputInvertToggle(uint16_t instance, bool_t invert);
+
+ /**
+ * @brief Get the current toggle status
+ *
+ * @param[in] instance The ID of the toggle input instance
+ * @param[in] ptoggle The toggle event struct
+ *
+ * @return Returns FALSE on an error (eg invalid instance)
+ */
+ bool_t ginputGetToggleStatus(uint16_t instance, GEventToggle *ptoggle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GINPUT_NEED_TOGGLE */
+
+#endif /* _GINPUT_TOGGLE_H */
+/** @} */
+
diff --git a/src/gmisc/sys_defs.h b/src/gmisc/sys_defs.h
new file mode 100644
index 00000000..cbb0111b
--- /dev/null
+++ b/src/gmisc/sys_defs.h
@@ -0,0 +1,212 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gmisc/sys_defs.h
+ * @brief GMISC - Miscellaneous Routines header file.
+ *
+ * @addtogroup GMISC
+ *
+ * @brief Module which contains different features such as array conversions
+ *
+ * @{
+ */
+
+#ifndef _GMISC_H
+#define _GMISC_H
+
+#include "gfx.h"
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/**
+ * @brief Sample data formats
+ * @note These are defined regardless of whether you use the GMISC module
+ * or not as they are used in lots of places.
+ */
+typedef enum ArrayDataFormat_e {
+ ARRAY_DATA_4BITUNSIGNED = 4, ARRAY_DATA_4BITSIGNED = 5,
+ ARRAY_DATA_8BITUNSIGNED = 8, ARRAY_DATA_8BITSIGNED = 9,
+ ARRAY_DATA_10BITUNSIGNED = 10, ARRAY_DATA_10BITSIGNED = 11,
+ ARRAY_DATA_12BITUNSIGNED = 12, ARRAY_DATA_12BITSIGNED = 13,
+ ARRAY_DATA_14BITUNSIGNED = 14, ARRAY_DATA_14BITSIGNED = 15,
+ ARRAY_DATA_16BITUNSIGNED = 16, ARRAY_DATA_16BITSIGNED = 17,
+ } ArrayDataFormat;
+
+/**
+ * @brief The type for a fixed point type.
+ * @details The top 16 bits are the integer component, the bottom 16 bits are the real component.
+ */
+typedef int32_t fixed;
+
+/**
+ * @brief Macros to convert to and from a fixed point.
+ * @{
+ */
+#define FIXED(x) ((fixed)(x)<<16) /* @< integer to fixed */
+#define NONFIXED(x) ((x)>>16) /* @< fixed to integer */
+#define FIXED0_5 32768 /* @< 0.5 as a fixed (used for rounding) */
+#define FP2FIXED(x) ((fixed)((x)*65536.0)) /* @< floating point to fixed */
+#define FIXED2FP(x) ((double)(x)/65536.0) /* @< fixed to floating point */
+/* @} */
+
+/**
+ * @brief The famous number pi
+ */
+#define PI 3.1415926535897932384626433832795028841971693993751
+
+/**
+ * @brief pi as a fixed point
+ */
+#define FIXED_PI FP2FIXED(PI)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if GFX_USE_GMISC || defined(__DOXYGEN__)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if GMISC_NEED_ARRAYOPS || defined(__DOXYGEN__)
+ /**
+ * @brief Convert from one array format to another array format.
+ *
+ * @param[in] srcfmt The format of the source array
+ * @param[in] src The source array
+ * @param[in] dstfmt The format of the destination array
+ * @param[in] dst The dstination array
+ * @param[in] cnt The number of array elements to convert
+ *
+ * @note Assumes the destination buffer is large enough for the resultant data.
+ * @note This routine is optimised to perform as fast as possible.
+ * @note No type checking is performed on the source format. It is assumed to
+ * have only valid values eg. ARRAY_DATA_4BITSIGNED will have values
+ * 0000 -> 0111 for positive numbers and 1111 -> 1000 for negative numbers
+ * Bits 5 -> 8 in the storage byte are treated in an undefined manner.
+ * @note If srcfmt or dstfmt is an unknown format, this routine does nothing
+ * with no warning that something is wrong
+ *
+ * @api
+ */
+ void gmiscArrayConvert(ArrayDataFormat srcfmt, void *src, ArrayDataFormat dstfmt, void *dst, size_t cnt);
+
+ #if 0
+ void gmiscArrayTranslate(ArrayDataFormat fmt, void *src, void *dst, size_t cnt, int trans);
+
+ void gmiscArrayMultiply(ArrayDataFormat fmt, void *src, void *dst, size_t cnt, int mult);
+
+ void gmiscArrayDivide(ArrayDataFormat fmt, void *src, void *dst, size_t cnt, int mdiv);
+
+ void gmiscArrayMultDiv(ArrayDataFormat fmt, void *src, void *dst, size_t cnt, int mult, int div);
+
+ void gmiscArrayAdd(ArrayDataFormat fmt, void *src1, void *src2, void *dst, size_t cnt);
+
+ void gmiscArrayAddNoOverflow(ArrayDataFormat fmt, void *src1, void *src2, void *dst, size_t cnt);
+ #endif
+#endif
+
+#if GMISC_NEED_FASTTRIG || defined(__DOXYGEN__)
+ extern const double sintabledouble[];
+
+ /**
+ * @brief Fast Table Based Trig functions
+ * @return A double in the range -1.0 .. 0.0 .. 1.0
+ *
+ * @param[in] degrees The angle in degrees (not radians)
+ *
+ * @note These functions use degrees rather than radians to describe the angle.
+ *
+ * @api
+ * @{
+ */
+ double fsin(int degrees);
+ double fcos(int degrees);
+ /** @}
+ *
+ * @brief Fast Table Based Trig functions
+ * @return A double in the range -1.0 .. 0.0 .. 1.0
+ *
+ * @param[in] degrees The angle in degrees 0 .. 359
+ *
+ * @note These functions use degrees rather than radians to describe the angle.
+ * @note These functions are super fast but require the parameter to be in range.
+ * Use the lowercase functions if the parameter may not be in range or if a
+ * required trig function is not supported in this form.
+ *
+ * @api
+ * @{
+ */
+ #define FSIN(degrees) sintabledouble[degrees];
+ /** @} */
+#endif
+
+#if GMISC_NEED_FIXEDTRIG || defined(__DOXYGEN__)
+ extern const fixed sintablefixed[];
+
+ /**
+ * @brief Fast Table Based Trig functions
+ * @return A fixed point in the range -1.0 .. 0.0 .. 1.0
+ *
+ * @param[in] degrees The angle in degrees (not radians)
+ *
+ * @note These functions use degrees rather than radians to describe the angle.
+ *
+ * @api
+ * @{
+ */
+ fixed ffsin(int degrees);
+ fixed ffcos(int degrees);
+ /** @}
+ *
+ * @brief Fast Table Based Trig functions
+ * @return A fixed point in the range -1.0 .. 0.0 .. 1.0
+ *
+ * @param[in] degrees The angle in degrees 0 .. 359
+ *
+ * @note These functions use degrees rather than radians to describe the angle.
+ * @note These functions are super fast but require the parameter to be in range.
+ * Use the lowercase functions if the parameter may not be in range or if a
+ * required trig function is not supported in this form.
+ *
+ * @api
+ * @{
+ */
+ #define FFSIN(degrees) sintablefixed[degrees];
+ /** @} */
+#endif
+
+#if GMISC_NEED_INVSQRT
+ /**
+ * @brief Fast inverse square root function (x^-1/2)
+ * @return The approximate inverse square root
+ *
+ * @param[in] n The number to find the inverse square root of
+ *
+ * @note This function generates an approximate result. Higher accuracy (at the expense
+ * of speed) can be obtained by modifying the source code (the necessary line
+ * is already there - just commented out).
+ * @note This function relies on the internal machine format of a float and a long.
+ * If your machine architecture is very unusual this function may not work.
+ *
+ * @api
+ */
+ float invsqrt(float n);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_MISC */
+
+#endif /* _GMISC_H */
+/** @} */
+
diff --git a/src/gmisc/gmisc.mk b/src/gmisc/sys_make.mk
index 73280699..66d19ab0 100644
--- a/src/gmisc/gmisc.mk
+++ b/src/gmisc/sys_make.mk
@@ -1,3 +1,3 @@
-GFXSRC += $(GFXLIB)/src/gmisc/gmisc.c \
- $(GFXLIB)/src/gmisc/arrayops.c \
- $(GFXLIB)/src/gmisc/trig.c
+GFXSRC += $(GFXLIB)/src/gmisc/gmisc.c \
+ $(GFXLIB)/src/gmisc/arrayops.c \
+ $(GFXLIB)/src/gmisc/trig.c
diff --git a/src/gmisc/sys_options.h b/src/gmisc/sys_options.h
new file mode 100644
index 00000000..9cdf37f6
--- /dev/null
+++ b/src/gmisc/sys_options.h
@@ -0,0 +1,85 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gmisc/sys_options.h
+ * @brief GMISC - Miscellaneous Routines options header file.
+ *
+ * @addtogroup GMISC
+ * @{
+ */
+
+#ifndef _GMISC_OPTIONS_H
+#define _GMISC_OPTIONS_H
+
+/**
+ * @name GMISC Functionality to be included
+ * @{
+ */
+ /**
+ * @brief Include array operation functions
+ * @details Defaults to FALSE
+ */
+ #ifndef GMISC_NEED_ARRAYOPS
+ #define GMISC_NEED_ARRAYOPS FALSE
+ #endif
+ /**
+ * @brief Include fast floating point trig functions (fsin, fcos)
+ * @details Defaults to FALSE
+ */
+ #ifndef GMISC_NEED_FASTTRIG
+ #define GMISC_NEED_FASTTRIG FALSE
+ #endif
+ /**
+ * @brief Include fast fixed point trig functions (ffsin, ffcos)
+ * @details Defaults to FALSE
+ */
+ #ifndef GMISC_NEED_FIXEDTRIG
+ #define GMISC_NEED_FIXEDTRIG FALSE
+ #endif
+ /**
+ * @brief Include fast inverse square root (x^-1/2)
+ * @details Defaults to FALSE
+ */
+ #ifndef GMISC_NEED_INVSQRT
+ #define GMISC_NEED_INVSQRT FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GMISC Optional Parameters
+ * @{
+ */
+ /**
+ * @brief Modifies the @p invsqrt() function to assume a different integer to floating point endianness.
+ * @note Normally the floating point format and the integer format have
+ * the same endianness. Unfortunately there are some strange
+ * processors that don't eg. some very early ARM devices.
+ * For those where the endianness doesn't match you can fix it by
+ * defining GMISC_INVSQRT_MIXED_ENDIAN.
+ * @note This still assumes the processor is using an ieee floating point format.
+ *
+ * If you have a software floating point that uses a non-standard
+ * floating point format (or very strange hardware) then define
+ * GMISC_INVSQRT_REAL_SLOW and it will do it the hard way.
+ */
+ #ifndef GMISC_INVSQRT_MIXED_ENDIAN
+ #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
+ #endif
+ /**
+ * @brief Modifies the @p invsqrt() function to do things the long slow way.
+ * @note This causes the @p invsqrt() function to work regardless of the
+ * processor floating point format.
+ * @note This makes the @p invsqrt() function very slow.
+ */
+ #ifndef GMISC_INVSQRT_REAL_SLOW
+ #define GMISC_INVSQRT_REAL_SLOW FALSE
+ #endif
+/** @} */
+
+#endif /* _GMISC_OPTIONS_H */
+/** @} */
diff --git a/src/gmisc/sys_rules.h b/src/gmisc/sys_rules.h
new file mode 100644
index 00000000..6c66907a
--- /dev/null
+++ b/src/gmisc/sys_rules.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gmisc/sys_rules.h
+ * @brief GMISC safety rules header file.
+ *
+ * @addtogroup GMISC
+ * @{
+ */
+
+#ifndef _GMISC_RULES_H
+#define _GMISC_RULES_H
+
+#if GFX_USE_GMISC
+#endif
+
+#endif /* _GMISC_RULES_H */
+/** @} */
diff --git a/src/gos/chibios.h b/src/gos/chibios.h
new file mode 100644
index 00000000..6373aa43
--- /dev/null
+++ b/src/gos/chibios.h
@@ -0,0 +1,100 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gos/chibios.h
+ * @brief GOS - Operating System Support header file for ChibiOS.
+ */
+
+#ifndef _GOS_CHIBIOS_H
+#define _GOS_CHIBIOS_H
+
+#if GFX_USE_OS_CHIBIOS
+
+#include "ch.h"
+#include "hal.h"
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/**
+ * bool_t,
+ * int8_t, uint8_t,
+ * int16_t, uint16_t,
+ * int32_t, uint32_t,
+ * size_t
+ * TRUE, FALSE
+ * TIME_IMMEDIATE, TIME_INFINITE
+ * are already defined by ChibiOS
+ */
+
+typedef systime_t delaytime_t;
+typedef systime_t systemticks_t;
+typedef cnt_t semcount_t;
+typedef msg_t threadreturn_t;
+typedef tprio_t threadpriority_t;
+
+#define MAX_SEMAPHORE_COUNT ((semcount_t)(((unsigned long)((semcount_t)(-1))) >> 1))
+#define LOW_PRIORITY LOWPRIO
+#define NORMAL_PRIORITY NORMALPRIO
+#define HIGH_PRIORITY HIGHPRIO
+
+#define DECLARE_THREAD_STACK(name, sz) WORKING_AREA(name, sz)
+#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param)
+
+typedef struct {
+ Semaphore sem;
+ semcount_t limit;
+ } gfxSem;
+
+typedef Mutex gfxMutex;
+typedef Thread * gfxThreadHandle;
+
+/*===========================================================================*/
+/* Function declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define gfxHalt(msg) { chDbgPanic(msg); chSysHalt(); }
+#define gfxExit() chSysHalt()
+#define gfxAlloc(sz) chHeapAlloc(0, sz)
+#define gfxFree(ptr) chHeapFree(ptr)
+#define gfxYield() chThdYield()
+#define gfxSystemTicks() chTimeNow()
+#define gfxMillisecondsToTicks(ms) MS2ST(ms)
+#define gfxSystemLock() chSysLock()
+#define gfxSystemUnlock() chSysUnlock()
+#define gfxMutexInit(pmutex) chMtxInit(pmutex)
+#define gfxMutexDestroy(pmutex) (void)pmutex
+#define gfxMutexEnter(pmutex) chMtxLock(pmutex)
+#define gfxMutexExit(pmutex) chMtxUnlock()
+void *gfxRealloc(void *ptr, size_t oldsz, size_t newsz);
+void gfxSleepMilliseconds(delaytime_t ms);
+void gfxSleepMicroseconds(delaytime_t ms);
+void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);
+void gfxSemDestroy(gfxSem *psem);
+bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
+void gfxSemSignal(gfxSem *psem);
+void gfxSemSignalI(gfxSem *psem);
+#define gfxSemCounterI(psem) ((psem)->sem.s_cnt)
+#define gfxSemCounter(psem) ((psem)->sem.s_cnt)
+gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
+#define gfxThreadWait(thread) chThdWait(thread)
+#define gfxThreadMe() chThdSelf()
+#define gfxThreadClose(thread) (void)thread
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_OS_CHIBIOS */
+#endif /* _GOS_CHIBIOS_H */
+
diff --git a/src/gos/linux.h b/src/gos/linux.h
new file mode 100644
index 00000000..f8b049e9
--- /dev/null
+++ b/src/gos/linux.h
@@ -0,0 +1,94 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gos/linux.h
+ * @brief GOS - Operating System Support header file for LINUX.
+ */
+
+#ifndef _GOS_LINUX_H
+#define _GOS_LINUX_H
+
+#if GFX_USE_OS_LINUX
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <pthread.h>
+
+/* Already defined int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, size_t */
+
+typedef int8_t bool_t;
+typedef unsigned long systemticks_t;
+typedef void * threadreturn_t;
+typedef unsigned long delaytime_t;
+typedef pthread_t gfxThreadHandle;
+typedef int threadpriority_t;
+typedef uint32_t semcount_t;
+typedef pthread_mutex_t gfxMutex;
+
+#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param)
+#define DECLARE_THREAD_STACK(name, sz) uint8_t name[0];
+
+#define gfxExit() exit(0)
+#define gfxAlloc(sz) malloc(sz)
+#define gfxRealloc(p,osz,nsz) realloc(p, nsz)
+#define gfxFree(ptr) free(ptr)
+#define gfxMillisecondsToTicks(ms) (ms)
+#define gfxYield() pthread_yield()
+#define gfxThreadMe() pthread_self()
+#define gfxThreadClose(th) (void)th
+#define gfxMutexInit(pmtx) pthread_mutex_init(pmtx, 0)
+#define gfxMutexDestroy(pmtx) pthread_mutex_destroy(pmtx)
+#define gfxMutexEnter(pmtx) pthread_mutex_lock(pmtx)
+#define gfxMutexExit(pmtx) pthread_mutex_unlock(pmtx)
+#define gfxSemSignalI(psem) gfxSemSignal(psem)
+#define gfxSemCounterI(pSem) ((pSem)->cnt)
+
+#define TIME_IMMEDIATE 0
+#define TIME_INFINITE ((delaytime_t)-1)
+#define MAX_SEMAPHORE_COUNT ((semcount_t)-1)
+#define LOW_PRIORITY 10
+#define NORMAL_PRIORITY 0
+#define HIGH_PRIORITY -10
+
+typedef struct gfxSem {
+ pthread_mutex_t mtx;
+ pthread_cond_t cond;
+ semcount_t cnt;
+ semcount_t max;
+} gfxSem;
+
+/*===========================================================================*/
+/* Function declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gfxHalt(const char *msg);
+void gfxSleepMilliseconds(delaytime_t ms);
+void gfxSleepMicroseconds(delaytime_t ms);
+systemticks_t gfxSystemTicks(void);
+void gfxSystemLock(void);
+void gfxSystemUnlock(void);
+void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);
+void gfxSemDestroy(gfxSem *psem);
+bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
+void gfxSemSignal(gfxSem *psem);
+semcount_t gfxSemCounter(gfxSem *pSem);
+gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
+threadreturn_t gfxThreadWait(gfxThreadHandle thread);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_OS_LINUX */
+
+#endif /* _GOS_LINUX_H */
diff --git a/src/gos/osx.h b/src/gos/osx.h
new file mode 100644
index 00000000..56e0551e
--- /dev/null
+++ b/src/gos/osx.h
@@ -0,0 +1,94 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gos/osx.h
+ * @brief GOS - Operating System Support header file for Mac OS-X.
+ */
+
+#ifndef _GOS_OSX_H
+#define _GOS_OSX_H
+
+#if GFX_USE_OS_OSX
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <pthread.h>
+
+/* Already defined int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, size_t */
+
+typedef int8_t bool_t;
+typedef unsigned long systemticks_t;
+typedef void * threadreturn_t;
+typedef unsigned long delaytime_t;
+typedef pthread_t gfxThreadHandle;
+typedef int threadpriority_t;
+typedef uint32_t semcount_t;
+typedef pthread_mutex_t gfxMutex;
+
+#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param)
+#define DECLARE_THREAD_STACK(name, sz) uint8_t name[0];
+
+#define gfxExit() exit(0)
+#define gfxAlloc(sz) malloc(sz)
+#define gfxRealloc(p,osz,nsz) realloc(p, nsz)
+#define gfxFree(ptr) free(ptr)
+#define gfxMillisecondsToTicks(ms) (ms)
+#define gfxYield() sched_yield()
+#define gfxThreadMe() pthread_self()
+#define gfxThreadClose(th) (void)th
+#define gfxMutexInit(pmtx) pthread_mutex_init(pmtx, 0)
+#define gfxMutexDestroy(pmtx) pthread_mutex_destroy(pmtx)
+#define gfxMutexEnter(pmtx) pthread_mutex_lock(pmtx)
+#define gfxMutexExit(pmtx) pthread_mutex_unlock(pmtx)
+#define gfxSemSignalI(psem) gfxSemSignal(psem)
+#define gfxSemCounterI(pSem) ((pSem)->cnt)
+
+#define TIME_IMMEDIATE 0
+#define TIME_INFINITE ((delaytime_t)-1)
+#define MAX_SEMAPHORE_COUNT ((semcount_t)-1)
+#define LOW_PRIORITY 10
+#define NORMAL_PRIORITY 0
+#define HIGH_PRIORITY -10
+
+typedef struct gfxSem {
+ pthread_mutex_t mtx;
+ pthread_cond_t cond;
+ semcount_t cnt;
+ semcount_t max;
+} gfxSem;
+
+/*===========================================================================*/
+/* Function declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gfxHalt(const char *msg);
+void gfxSleepMilliseconds(delaytime_t ms);
+void gfxSleepMicroseconds(delaytime_t ms);
+systemticks_t gfxSystemTicks(void);
+void gfxSystemLock(void);
+void gfxSystemUnlock(void);
+void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);
+void gfxSemDestroy(gfxSem *psem);
+bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
+void gfxSemSignal(gfxSem *psem);
+semcount_t gfxSemCounter(gfxSem *pSem);
+gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
+threadreturn_t gfxThreadWait(gfxThreadHandle thread);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_OS_OSX */
+
+#endif /* _GOS_OSX_H */
+
diff --git a/src/gos/raw32.h b/src/gos/raw32.h
new file mode 100644
index 00000000..eb5b5e18
--- /dev/null
+++ b/src/gos/raw32.h
@@ -0,0 +1,125 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gos/raw32.h
+ * @brief GOS - Operating System Support header file for any 32 bit processor in bare-metal mode
+ */
+
+/**
+ * The raw32 GOS implementation supports any 32 bit processor with or without an
+ * underlying operating system. It uses cooperative multi-tasking. Be careful
+ * when writing device drivers not to disturb the assumptions this creates by performing
+ * call-backs to uGFX code unless you define the INTERRUPTS_OFF() and INTERRUPTS_ON() macros.
+ * It still requires some C runtime library support...
+ * enough startup to initialise the stack, interrupts, static data etc and call main().
+ * setjmp() and longjmp() - for threading
+ * memcpy() - for heap and threading
+ * malloc(), realloc and free() - if GOS_RAW_HEAP_SIZE == 0
+ *
+ * You must also define the following routines in your own code so that timing functions will work...
+ * systemticks_t gfxSystemTicks(void);
+ * systemticks_t gfxMillisecondsToTicks(delaytime_t ms);
+ */
+#ifndef _GOS_RAW32_H
+#define _GOS_RAW32_H
+
+#if GFX_USE_OS_RAW32
+
+/*===========================================================================*/
+/* Special Macros just for a Raw implementation */
+/*===========================================================================*/
+
+/**
+ * @brief Set the maximum size of the heap.
+ * @note If set to 0 then the C runtime library malloc() and free() are used.
+ */
+#ifndef GOS_RAW_HEAP_SIZE
+ #define GOS_RAW_HEAP_SIZE 0
+#endif
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+typedef unsigned char bool_t;
+typedef char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+
+typedef uint32_t size_t;
+typedef uint32_t delaytime_t;
+typedef uint32_t systemticks_t;
+typedef short semcount_t;
+typedef int threadreturn_t;
+typedef int threadpriority_t;
+
+#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param)
+#define DECLARE_THREAD_STACK(name, sz) uint8_t name[sz];
+
+#define TIME_IMMEDIATE 0
+#define TIME_INFINITE ((delaytime_t)-1)
+#define MAX_SEMAPHORE_COUNT 0x7FFF
+#define LOW_PRIORITY 0
+#define NORMAL_PRIORITY 1
+#define HIGH_PRIORITY 2
+
+typedef struct {
+ semcount_t cnt;
+ semcount_t limit;
+} gfxSem;
+
+typedef uint32_t gfxMutex;
+typedef void * gfxThreadHandle;
+
+#define gfxThreadClose(thread)
+#define gfxMutexDestroy(pmutex)
+#define gfxSemDestroy(psem)
+#define gfxSemCounter(psem) ((psem)->cnt)
+#define gfxSemCounterI(psem) ((psem)->cnt)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ #if GOS_RAW_HEAP_SIZE != 0
+ void gfxAddHeapBlock(void *ptr, size_t sz);
+ #endif
+
+ void gfxHalt(const char *msg);
+ void gfxExit(void);
+ void *gfxAlloc(size_t sz);
+ void *gfxRealloc(void *ptr, size_t oldsz, size_t newsz);
+ void gfxFree(void *ptr);
+ void gfxYield(void);
+ void gfxSleepMilliseconds(delaytime_t ms);
+ void gfxSleepMicroseconds(delaytime_t ms);
+ systemticks_t gfxSystemTicks(void);
+ systemticks_t gfxMillisecondsToTicks(delaytime_t ms);
+ void gfxSystemLock(void);
+ void gfxSystemUnlock(void);
+ void gfxMutexInit(gfxMutex *pmutex);
+ void gfxMutexEnter(gfxMutex *pmutex);
+ void gfxMutexExit(gfxMutex *pmutex);
+ void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);
+ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
+ void gfxSemSignal(gfxSem *psem);
+ void gfxSemSignalI(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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_OS_RAW32 */
+#endif /* _GOS_RAW32_H */
+
diff --git a/src/gos/sys_defs.h b/src/gos/sys_defs.h
new file mode 100644
index 00000000..b913fb66
--- /dev/null
+++ b/src/gos/sys_defs.h
@@ -0,0 +1,445 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gos/sys_defs.h
+ * @brief GOS - Operating System Support header file
+ *
+ * @addtogroup GOS
+ *
+ * @brief Module to build a uniform abstraction layer between uGFX and the underlying system
+ *
+ * @note Some of the routines specified below may be implemented simply as
+ * a macro to the real operating system call.
+ * @{
+ */
+
+#ifndef _GOS_H
+#define _GOS_H
+
+#if defined(__DOXYGEN__)
+ /*===========================================================================*/
+ /* Type definitions */
+ /*===========================================================================*/
+
+ /**
+ * @brief Various integer sizes
+ * @note Your platform may use slightly different definitions to these
+ * @{
+ */
+ typedef unsigned char bool_t;
+ typedef char int8_t;
+ typedef unsigned char uint8_t;
+ typedef short int16_t;
+ typedef unsigned short uint16_t;
+ typedef long int32_t;
+ typedef unsigned long uint32_t;
+ /**
+ * @}
+ *
+ * @brief Various platform (and operating system) dependent types
+ * @note Your platform may use slightly different definitions to these
+ * @{
+ */
+ typedef unsigned long size_t;
+ typedef unsigned long delaytime_t;
+ typedef unsigned long systemticks_t;
+ typedef short semcount_t;
+ typedef int threadreturn_t;
+ typedef int threadpriority_t;
+
+ /**
+ * @brief Declare a thread stack and function
+ * @{
+ */
+ #define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param)
+ #define DECLARE_THREAD_STACK(name, sz) uint8_t name[sz];
+ /* @} */
+
+ /**
+ * @}
+ *
+ * @brief Various platform (and operating system) constants
+ * @note Your platform may use slightly different definitions to these
+ * @{
+ */
+ #define FALSE 0
+ #define TRUE 1
+ #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 0
+ #define NORMAL_PRIORITY 1
+ #define HIGH_PRIORITY 2
+ /* @} */
+
+ /**
+ * @brief A semaphore
+ * @note Your operating system will have a proper definition for this structure
+ */
+ typedef struct {} gfxSem;
+
+ /**
+ * @brief A mutex
+ * @note Your operating system will have a proper definition for this structure
+ */
+ typedef struct {} gfxMutex;
+
+ /**
+ * @brief A thread handle
+ * @note Your operating system will have a proper definition for this.
+ */
+ typedef void * gfxThreadHandle;
+
+ /*===========================================================================*/
+ /* Function declarations. */
+ /*===========================================================================*/
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /**
+ * @brief Halt the GFX application due to an error.
+ *
+ * @param[in] msg An optional debug message to show (Can be NULL)
+ *
+ * @api
+ */
+ void gfxHalt(const char *msg);
+
+ /**
+ * @brief Exit the GFX application.
+ *
+ * @api
+ */
+ void gfxExit(void);
+
+ /**
+ * @brief Allocate memory
+ * @return A pointer to the memory allocated or NULL if there is no more memory available
+ *
+ * @param[in] sz The size in bytes of the area to allocate
+ *
+ * @api
+ */
+ void *gfxAlloc(size_t sz);
+
+ /**
+ * @brief Re-allocate memory
+ * @return A pointer to the new memory area or NULL if there is no more memory available
+ *
+ * @param[in] ptr The old memory area to be increased/decreased in size
+ * @param[in] oldsz The size in bytes of the old memory area
+ * @param[in] newsz The size in bytes of the new memory area
+ *
+ * @note Some operating systems don't use the oldsz parameter as they implicitly know the size of
+ * old memory area. The parameter must always be supplied however for API compatibility.
+ * @note gfxRealloc() can make the area smaller or larger but may have to return a different pointer.
+ * If this occurs the new area contains a copy of the data from the old area. The old memory
+ * pointer should not be used after this routine as the original area may have been freed.
+ * @note If there is insufficient memory to create the new memory region, NULL is returned and the
+ * old memory area is left unchanged.
+ *
+ * @api
+ */
+ void *gfxRealloc(void *ptr, size_t oldsz, size_t newsz);
+
+ /**
+ * @brief Free memory
+ *
+ * @param[in] ptr The memory to free
+ *
+ * @api
+ */
+ void gfxFree(void *ptr);
+
+ /**
+ * @brief Yield the current thread
+ * @details Give up the rest of the current time slice for this thread in order to give other threads
+ * a chance to run.
+ *
+ * @api
+ */
+ void gfxYield(void);
+
+ /**
+ * @brief Put the current thread to sleep for the specified period in milliseconds
+ *
+ * @param[in] ms The number milliseconds to sleep
+ *
+ * @note Specifying TIME_IMMEDIATE will yield the current thread but return
+ * on the next time slice.
+ * @note Specifying TIME_INFINITE will sleep forever.
+ *
+ * @api
+ */
+ void gfxSleepMilliseconds(delaytime_t ms);
+
+ /**
+ * @brief Put the current thread to sleep for the specified period in microseconds
+ *
+ * @param[in] ms The number microseconds to sleep
+ *
+ * @note Specifying TIME_IMMEDIATE will return immediately (no sleeping)
+ * @note Specifying TIME_INFINITE will sleep forever.
+ *
+ * @api
+ */
+ void gfxSleepMicroseconds(delaytime_t ms);
+
+ /**
+ * @brief Get the current operating system tick time
+ * @return The current tick time
+ *
+ * @note A "tick" is an arbitrary period of time that the operating
+ * system uses to mark time.
+ * @note The absolute value of this call is relatively meaningless. Its usefulness
+ * is in calculating periods between two calls to this function.
+ * @note As the value from this function can wrap it is important that any periods are calculated
+ * as t2 - t1 and then compared to the desired period rather than comparing
+ * t1 + period to t2
+ *
+ * @api
+ */
+ systemticks_t gfxSystemTicks(void);
+
+ /**
+ * @brief Convert a given number of millseconds to a number of operating system ticks
+ * @return The period in system ticks.
+ *
+ * @note A "tick" is an arbitrary period of time that the operating
+ * system uses to mark time.
+ *
+ * @param[in] ms The number of millseconds
+ *
+ * @api
+ */
+ systemticks_t gfxMillisecondsToTicks(delaytime_t ms);
+
+ /**
+ * @brief Lock the operating system to protect a sequence of code
+ *
+ * @note Calling this will lock out all other threads from executing even at interrupt level
+ * within the GFX system. On hardware this may be implemented as a disabling of interrupts,
+ * however in an operating system which hides real interrupt level code it may simply use a
+ * mutex lock.
+ * @note The thread MUST NOT block whilst the system is locked. It must execute in this state for
+ * as short a period as possible as this can seriously affect interrupt latency on some
+ * platforms.
+ * @note While locked only interrupt level (iclass) GFX routines may be called.
+ *
+ * @api
+ */
+ void gfxSystemLock(void);
+
+ /**
+ * @brief Unlock the operating system previous locked by gfxSystemLock()
+ *
+ * @api
+ */
+ void gfxSystemUnlock(void);
+
+ /**
+ * @brief Initialise a mutex to protect a region of code from other threads.
+ *
+ * @param[in] pmutex A pointer to the mutex
+ *
+ * @note Whilst a counting semaphore with a limit of 1 can be used for similiar purposes
+ * on many operating systems using a seperate mutex structure is more efficient.
+ *
+ * @api
+ */
+ void gfxMutexInit(gfxMutex *pmutex);
+
+ /**
+ * @brief Destroy a Mutex.
+ *
+ * @param[in] pmutex A pointer to the mutex
+ *
+ * @api
+ */
+ void gfxMutexDestroy(gfxMutex *pmutex);
+
+ /**
+ * @brief Enter the critical code region protected by the mutex.
+ * @details Blocks until there is no other thread in the critical region.
+ *
+ * @param[in] pmutex A pointer to the mutex
+ *
+ * @api
+ */
+ void gfxMutexEnter(gfxMutex *pmutex);
+
+ /**
+ * @brief Exit the critical code region protected by the mutex.
+ * @details May cause another thread waiting on the mutex to now be placed into the run queue.
+ *
+ * @param[in] pmutex A pointer to the mutex
+ *
+ * @api
+ */
+ void gfxMutexExit(gfxMutex *pmutex);
+
+ /**
+ * @brief Initialise a Counted Semaphore
+ *
+ * @param[in] psem A pointer to the semaphore
+ * @param[in] val The initial value of the semaphore
+ * @param[in] limit The maxmimum value of the semaphore
+ *
+ * @note Operations defined for counted semaphores:
+ * Signal: The semaphore counter is increased and if the result is non-positive then a waiting thread
+ * is queued for execution. Note that once the thread reaches "limit", further signals are
+ * ignored.
+ * Wait: The semaphore counter is decreased and if the result becomes negative the thread is queued
+ * in the semaphore and suspended.
+ *
+ * @api
+ */
+ void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);
+
+ /**
+ * @brief Destroy a Counted Semaphore
+ *
+ * @param[in] psem A pointer to the semaphore
+ *
+ * @note Any threads waiting on the semaphore will be released
+ *
+ * @api
+ */
+ void gfxSemDestroy(gfxSem *psem);
+
+ /**
+ * @brief Wait on a semaphore
+ * @details The semaphore counter is decreased and if the result becomes negative the thread waits for it to become
+ * non-negative again
+ * @return FALSE if the wait timeout occurred otherwise TRUE
+ *
+ * @param[in] psem A pointer to the semaphore
+ * @param[in] ms The maximum time to wait for the semaphore
+ *
+ * @api
+ */
+ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
+
+ /**
+ * @brief Signal a semaphore
+ * @details The semaphore counter is increased and if the result is non-positive then a waiting thread
+ * is queued for execution. Note that once the thread reaches "limit", further signals are
+ * ignored.
+ *
+ * @param[in] psem A pointer to the semaphore
+ *
+ * @api
+ */
+ void gfxSemSignal(gfxSem *psem);
+
+ /**
+ * @brief Signal a semaphore
+ * @details The semaphore counter is increased and if the result is non-positive then a waiting thread
+ * is queued for execution. Note that once the thread reaches "limit", further signals are
+ * ignored.
+ *
+ * @param[in] psem A pointer to the semaphore
+ *
+ * @iclass
+ * @api
+ */
+ void gfxSemSignalI(gfxSem *psem);
+
+ /**
+ * @brief Get the current semaphore count
+ * @return The current semaphore count
+ *
+ * @param[in] psem A pointer to the semaphore
+ *
+ * @api
+ */
+ semcount_t gfxSemCounter(gfxSem *psem);
+
+ /**
+ * @brief Get the current semaphore count
+ * @return The current semaphore count
+ *
+ * @param[in] psem A pointer to the semaphore
+ *
+ * @iclass
+ * @api
+ */
+ semcount_t gfxSemCounterI(gfxSem *psem);
+
+ /**
+ * @brief Start a new thread.
+ * @return Returns a thread handle if the thread was started, NULL on an error
+ *
+ * @param[in] stackarea A pointer to the area for the new threads stack or NULL to dynamically allocate it
+ * @param[in] stacksz The size of the thread stack. 0 means the default operating system size although this
+ * is only valid when stackarea is dynamically allocated.
+ * @param[in] prio The priority of the new thread
+ * @param[in] fn The function the new thread will run
+ * @param[in] param A parameter to pass the thread function.
+ *
+ * @api
+ */
+ gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
+
+ /**
+ * @brief Wait for a thread to finish.
+ * @return Returns the thread exit code.
+ *
+ * @param[in] thread The Thread Handle
+ *
+ * @note This will also close the thread handle as it is no longer useful
+ * once the thread has ended.
+ * @api
+ */
+ threadreturn_t gfxThreadWait(gfxThreadHandle thread);
+
+ /**
+ * @brief Get the current thread handle.
+ * @return A thread handle
+ *
+ * @api
+ */
+ gfxThreadHandle gfxThreadMe(void);
+
+ /**
+ * @brief Close the thread handle.
+ *
+ * @param[in] thread The Thread Handle
+ *
+ * @note This does not affect the thread, it just closes our handle to the thread.
+ *
+ * @api
+ */
+ void gfxThreadClose(gfxThreadHandle thread);
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+/**
+ * All the above was just for the doxygen documentation. All the implementation of the above
+ * (without any of the documentation overheads) is in the files below.
+ */
+#elif GFX_USE_OS_CHIBIOS
+ #include "src/gos/chibios.h"
+#elif GFX_USE_OS_WIN32
+ #include "src/gos/win32.h"
+#elif GFX_USE_OS_LINUX
+ #include "src/gos/linux.h"
+#elif GFX_USE_OS_OSX
+ #include "src/gos/osx.h"
+#elif GFX_USE_OS_RAW32
+ #include "src/gos/raw32.h"
+#else
+ #error "Your operating system is not supported yet"
+#endif
+
+#endif /* _GOS_H */
+/** @} */
diff --git a/src/gos/gos.mk b/src/gos/sys_make.mk
index 9db29fe2..9db29fe2 100644
--- a/src/gos/gos.mk
+++ b/src/gos/sys_make.mk
diff --git a/src/gos/sys_options.h b/src/gos/sys_options.h
new file mode 100644
index 00000000..ae9916ad
--- /dev/null
+++ b/src/gos/sys_options.h
@@ -0,0 +1,67 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gos/sys_options.h
+ * @brief GOS - Operating System options header file.
+ *
+ * @addtogroup GOS
+ * @{
+ */
+
+#ifndef _GOS_OPTIONS_H
+#define _GOS_OPTIONS_H
+
+/**
+ * @name GOS The operating system to use. One (and only one) of these must be defined.
+ * @{
+ */
+ /**
+ * @brief Use ChibiOS
+ * @details Defaults to FALSE
+ */
+ #ifndef GFX_USE_OS_CHIBIOS
+ #define GFX_USE_OS_CHIBIOS FALSE
+ #endif
+ /**
+ * @brief Use Win32
+ * @details Defaults to FALSE
+ */
+ #ifndef GFX_USE_OS_WIN32
+ #define GFX_USE_OS_WIN32 FALSE
+ #endif
+ /**
+ * @brief Use a linux based system running X11
+ * @details Defaults to FALSE
+ */
+ #ifndef GFX_USE_OS_LINUX
+ #define GFX_USE_OS_LINUX FALSE
+ #endif
+ /**
+ * @brief Use a Mac OS-X based system
+ * @details Defaults to FALSE
+ */
+ #ifndef GFX_USE_OS_OSX
+ #define GFX_USE_OS_OSX FALSE
+ #endif
+ /**
+ * @brief Use a Raw 32 bit CPU based system
+ * @details Defaults to FALSE
+ */
+ #ifndef GFX_USE_OS_RAW32
+ #define GFX_USE_OS_RAW32 FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GOS Optional Sizing Parameters
+ * @{
+ */
+/** @} */
+
+#endif /* _GOS_OPTIONS_H */
+/** @} */
diff --git a/src/gos/sys_rules.h b/src/gos/sys_rules.h
new file mode 100644
index 00000000..390e8116
--- /dev/null
+++ b/src/gos/sys_rules.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gos/sys_rules.h
+ * @brief GOS safety rules header file.
+ *
+ * @addtogroup GOS
+ * @{
+ */
+
+#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
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GOS: No Operating System has been defined. ChibiOS (GFX_USE_OS_CHIBIOS) has been turned on for you."
+ #endif
+ #undef GFX_USE_OS_CHIBIOS
+ #define GFX_USE_OS_CHIBIOS TRUE
+#endif
+#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 != 1 * TRUE
+ #error "GOS: More than one operation system has been defined as TRUE."
+#endif
+
+#endif /* _GOS_RULES_H */
+/** @} */
diff --git a/src/gos/win32.h b/src/gos/win32.h
new file mode 100644
index 00000000..c704a288
--- /dev/null
+++ b/src/gos/win32.h
@@ -0,0 +1,106 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gos/win32.h
+ * @brief GOS - Operating System Support header file for WIN32.
+ */
+
+#ifndef _GOS_WIN32_H
+#define _GOS_WIN32_H
+
+#if GFX_USE_OS_WIN32
+
+#ifndef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0501 // Windows XP and up
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <malloc.h>
+
+/* Stop cygwin from defining these types */
+#define __int8_t_defined
+
+/**
+ * size_t
+ * TRUE, FALSE
+ * are already defined by Win32
+ */
+typedef __int8 bool_t;
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef DWORD delaytime_t;
+typedef DWORD systemticks_t;
+typedef LONG semcount_t;
+typedef DWORD threadreturn_t;
+typedef int threadpriority_t;
+
+#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t WINAPI fnName(void *param)
+#define DECLARE_THREAD_STACK(name, sz) uint8_t name[0];
+
+#define TIME_IMMEDIATE 0
+#define TIME_INFINITE INFINITE
+#define MAX_SEMAPHORE_COUNT ((semcount_t)(((unsigned long)((semcount_t)(-1))) >> 1))
+#define LOW_PRIORITY THREAD_PRIORITY_BELOW_NORMAL
+#define NORMAL_PRIORITY THREAD_PRIORITY_NORMAL
+#define HIGH_PRIORITY THREAD_PRIORITY_ABOVE_NORMAL
+
+typedef HANDLE gfxSem;
+typedef HANDLE gfxMutex;
+typedef HANDLE gfxThreadHandle;
+
+#define gfxExit() ExitProcess(0)
+#define gfxAlloc(sz) malloc(sz)
+#define gfxRealloc(p,osz,nsz) realloc(p, nsz)
+#define gfxFree(ptr) free(ptr)
+#define gfxSleepMilliseconds(ms) Sleep(ms)
+#define gfxYield() Sleep(0)
+#define gfxSystemTicks() GetTickCount()
+#define gfxMillisecondsToTicks(ms) (ms)
+#define gfxMutexInit(pmutex) *(pmutex) = CreateMutex(0, FALSE, 0)
+#define gfxMutexDestroy(pmutex) CloseHandle(*(pmutex))
+#define gfxMutexEnter(pmutex) WaitForSingleObject(*(pmutex), INFINITE)
+#define gfxMutexExit(pmutex) ReleaseMutex(*(pmutex))
+#define gfxSemInit(psem, val, limit) *(psem) = CreateSemaphore(0, val, limit, 0)
+#define gfxSemDestroy(psem) CloseHandle(*(psem))
+#define gfxSemSignal(psem) ReleaseSemaphore(*(psem), 1, 0)
+#define gfxSemSignalI(psem) ReleaseSemaphore(*(psem), 1, 0)
+#define gfxSemCounterI(psem) gfxSemCounter(psem)
+#define gfxThreadMe() GetCurrentThread()
+#define gfxThreadClose(thread) CloseHandle(thread)
+
+/*===========================================================================*/
+/* Function declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gfxHalt(const char *msg);
+void gfxSleepMicroseconds(delaytime_t ms);
+bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
+semcount_t gfxSemCounter(gfxSem *pSem);
+void gfxSystemLock(void);
+void gfxSystemUnlock(void);
+gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
+threadreturn_t gfxThreadWait(gfxThreadHandle thread);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_OS_WIN32 */
+#endif /* _GOS_WIN32_H */
+
diff --git a/src/gqueue/sys_defs.h b/src/gqueue/sys_defs.h
new file mode 100644
index 00000000..447ea5be
--- /dev/null
+++ b/src/gqueue/sys_defs.h
@@ -0,0 +1,264 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gqueue/sys_defs.h
+ * @brief GQUEUE header file.
+ *
+ * @addtogroup GQUEUE
+ *
+ * @brief Module which provides queue management (only internally used)
+ *
+ * @details There are 3 types of queues:
+ * <ul><li><b>Asynchronous Queues (ASync) </b> - Queue operations never block</li>
+ * <li><b>Get Synchronous Queues (GSync) </b> - Queue Get operations block until something is placed in the Queue</li>
+ * <li><b>Put Synchronous Queues (PSync)</b> - Queue Put operations block until the element is removed from the Queue</li>
+ * <li><b>Fully Synchronous Queues (FSync)</b> - Queue GET and Put operations block</li>
+ * </ul>
+ * We need 4 types of queues even though fully synchronous queues support all operations including asynchronous
+ * operations because fully synchronous queues have the highest storage requirements. The other queue types are
+ * optimizations. Efficiency IS important to use (particularly RAM efficiency).
+ * In practice we only implement ASync, GSync and FSync queues as PSync queues are of dubious value.
+ * @{
+ */
+
+#ifndef _GQUEUE_H
+#define _GQUEUE_H
+
+#if GFX_USE_GQUEUE || defined(__DOXYGEN__)
+
+/**
+ * @brief A queue
+ * @{
+ */
+typedef struct gfxQueueASync {
+ struct gfxQueueASyncItem *head;
+ struct gfxQueueASyncItem *tail;
+} gfxQueueASync;
+
+typedef struct gfxQueueGSync {
+ struct gfxQueueGSyncItem *head;
+ struct gfxQueueGSyncItem *tail;
+ gfxSem sem;
+} gfxQueueGSync;
+
+typedef struct gfxQueueFSync {
+ struct gfxQueueFSyncItem *head;
+ struct gfxQueueFSyncItem *tail;
+ gfxSem sem;
+} gfxQueueFSync;
+/* @} */
+
+/**
+ * @brief A queue item
+ * @{
+ */
+typedef struct gfxQueueASyncItem {
+ struct gfxQueueASyncItem *next;
+} gfxQueueASyncItem;
+
+typedef struct gfxQueueGSyncItem {
+ struct gfxQueueGSyncItem *next;
+} gfxQueueGSyncItem;
+
+typedef struct gfxQueueFSyncItem {
+ struct gfxQueueFSyncItem *next;
+ gfxSem sem;
+} gfxQueueFSyncItem;
+/* @} */
+
+
+/*===========================================================================*/
+/* Function declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise a queue.
+ *
+ * @param[in] pqueue A pointer to the queue
+ *
+ * @note Whilst queues are normally FIFO, a GFX queue also supports push and pop operations.
+ * A pop operation is the same as normal get from the queue but a push places the item
+ * at the head of the queue instead of the tail (as a put would).
+ *
+ * @api
+ * @{
+ */
+void gfxQueueASyncInit(gfxQueueASync *pqueue);
+void gfxQueueGSyncInit(gfxQueueGSync *pqueue);
+void gfxQueueFSyncInit(gfxQueueFSync *pqueue);
+/* @} */
+
+/**
+ * @brief Get an item from the head of the queue (and remove it from the queue).
+ * @return NULL if the timeout expires before an item is available
+ *
+ * @param[in] pqueue A pointer to the queue
+ * @param[in] ms The maxmimum time to wait for an item. For ASync queues this parameter is
+ * not specified as TIME_IMMEDIATE is assumed.
+ *
+ * @api
+ * @{
+ */
+gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue);
+gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms);
+gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms);
+/* @} */
+
+/**
+ * @brief Put an item on the end of the queue.
+ * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE
+ *
+ * @param[in] pqueue A pointer to the queue
+ * @param[in] pitem A pointer to the queue item
+ * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues)
+ *
+ * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the
+ * item is removed from the queue. Note that even if the timeout occurs - the item
+ * remains in the queue.
+ *
+ * @api
+ * @{
+ */
+void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
+void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
+bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms);
+/* @} */
+
+/**
+ * @brief Pop an item from the head of the queue (and remove it from the queue).
+ * @details This is exactly the same as the Get operation above.
+ *
+ * @api
+ * @{
+ */
+#define gfxQueueASyncPop(pqueue) gfxQueueASyncGet(pqueue)
+#define gfxQueueGSyncPop(pqueue, ms) gfxQueueGSyncGet(pqueue, ms)
+#define gfxQueueFSyncPop(pqueue, ms) gfxQueueFSyncGet(pqueue, ms)
+/* @} */
+
+/**
+ * @brief Push an item into the start of the queue.
+ * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE
+ *
+ * @param[in] pqueue A pointer to the queue
+ * @param[in] pitem A pointer to the queue item
+ * @param[in] ms The maxmimum time to wait for an item to be popped (only for FSync queues)
+ *
+ * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the
+ * item is removed from the queue. Note that even if the timeout occurs - the item
+ * remains in the queue.
+ *
+ * @api
+ * @{
+ */
+void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
+void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
+bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms);
+/* @} */
+
+/**
+ * @brief Remove an item from the queue.
+ * @note Removes the specified item from the queue where-ever it is in the queue
+ *
+ * @param[in] pqueue A pointer to the queue
+ * @param[in] pitem A pointer to the queue item
+ *
+ * @note If the item isn't in the queue the routine just returns.
+ * @note If a process is waiting on the Put/Push operation for the item, that process
+ * will be signaled.
+ *
+ * @api
+ * @{
+ */
+void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
+void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
+void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem);
+/* @} */
+
+/**
+ * @brief Is the queue empty?
+ * @return TRUE if the queue is empty
+ *
+ * @param[in] pqueue A pointer to the queue
+ *
+ * @api
+ * @{
+ */
+bool_t gfxQueueASyncIsEmpty(gfxQueueASync *pqueue);
+bool_t gfxQueueGSyncIsEmpty(gfxQueueGSync *pqueue);
+bool_t gfxQueueFSyncIsEmpty(gfxQueueFSync *pqueue);
+/* @} */
+
+/**
+ * @brief Is an item in the queue?
+ * @return TRUE if the item is in the queue?
+ *
+ * @param[in] pqueue A pointer to the queue
+ * @param[in] pitem A pointer to the queue item
+ *
+ * @note This operation may be expensive.
+ *
+ * @api
+ * @{
+ */
+bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem);
+bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem);
+bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem);
+/* @} */
+
+/**
+ * @brief Get the first item from the head of the queue but do not remove it from the queue.
+ * @return NULL if no item is available.
+ *
+ * @param[in] pqueue A pointer to the queue
+ *
+ * @note This call does not block.
+ * @note This can be used as the first call to iterate all the elements in the queue.
+ * @note As that item is still on the queue, it should be treated as read-only. It could
+ * also be removed from the queue at any time by another thread (thereby altering the
+ * queue item).
+ *
+ * @api
+ * @{
+ */
+#define gfxQueueASyncPeek(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head))
+#define gfxQueueGSyncPeek(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head))
+#define gfxQueueFSyncPeek(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head))
+/* @} */
+
+/**
+ * @brief Get the next item in the queue (but do not remove it from the queue).
+ * @return NULL if no item is available.
+ *
+ * @param[in] pitem The previous item in the queue
+ *
+ * @note This call does not block.
+ * @note This can be used as subsequent calls to iterate all the elements in the queue.
+ * @note As that item is still on the queue, it should be treated as read-only. It could
+ * also be removed from the queue at any time by another thread (thereby altering the
+ * queue item).
+ *
+ * @api
+ * @{
+ */
+#define gfxQueueASyncNext(pitem) ((const gfxQueueASyncItem *)((pitem)->next))
+#define gfxQueueGSyncNext(pitem) ((const gfxQueueGSyncItem *)((pitem)->next))
+#define gfxQueueFSyncNext(pitem) ((const gfxQueueFSyncItem *)((pitem)->next))
+/* @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GQUEUE */
+#endif /* _GQUEUE_H */
+/** @} */
diff --git a/src/gqueue/gqueue.mk b/src/gqueue/sys_make.mk
index ab8a0423..ab8a0423 100644
--- a/src/gqueue/gqueue.mk
+++ b/src/gqueue/sys_make.mk
diff --git a/src/gqueue/sys_options.h b/src/gqueue/sys_options.h
new file mode 100644
index 00000000..7c8627ce
--- /dev/null
+++ b/src/gqueue/sys_options.h
@@ -0,0 +1,53 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gqueue/sys_options.h
+ * @brief GQUEUE - Queue options header file.
+ *
+ * @addtogroup GQUEUE
+ * @{
+ */
+
+#ifndef _GQUEUE_OPTIONS_H
+#define _GQUEUE_OPTIONS_H
+
+/**
+ * @name GQUEUE Functions to include.
+ * @{
+ */
+ /**
+ * @brief Enable Asynchronous Queues
+ * @details Defaults to FALSE
+ */
+ #ifndef GQUEUE_NEED_ASYNC
+ #define GQUEUE_NEED_ASYNC FALSE
+ #endif
+ /**
+ * @brief Enable Get-Synchronous Queues
+ * @details Defaults to FALSE
+ */
+ #ifndef GQUEUE_NEED_GSYNC
+ #define GQUEUE_NEED_GSYNC FALSE
+ #endif
+ /**
+ * @brief Enable Fully Synchronous Queues
+ * @details Defaults to FALSE
+ */
+ #ifndef GQUEUE_NEED_FSYNC
+ #define GQUEUE_NEED_FSYNC FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GQUEUE Optional Sizing Parameters
+ * @{
+ */
+/** @} */
+
+#endif /* _GQUEUE_OPTIONS_H */
+/** @} */
diff --git a/src/gqueue/sys_rules.h b/src/gqueue/sys_rules.h
new file mode 100644
index 00000000..baeb073d
--- /dev/null
+++ b/src/gqueue/sys_rules.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gqueue/sys_rules.h
+ * @brief GQUEUE safety rules header file.
+ *
+ * @addtogroup GQUEUE
+ * @{
+ */
+
+#ifndef _GQUEUE_RULES_H
+#define _GQUEUE_RULES_H
+
+#if GFX_USE_GQUEUE
+#endif
+
+#endif /* _GQUEUE_RULES_H */
+/** @} */
diff --git a/src/gtimer/sys_defs.h b/src/gtimer/sys_defs.h
new file mode 100644
index 00000000..45b12162
--- /dev/null
+++ b/src/gtimer/sys_defs.h
@@ -0,0 +1,180 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gtimer/sys_defs.h
+ *
+ * @addtogroup GTIMER
+ *
+ * @brief Module which provides software based timers for user-space applications
+ *
+ * @details The reason why ChibiOS/GFX has it's own timer abstraction is because
+ * virtual timers provided by ChibiOS/RT are interrupt context only.
+ * While great for what they are designed for, they make coding of the input
+ * drivers much more complex.
+ * For non-performance critical drivers like these input drivers, it would also
+ * hog an in-ordinate amount of critical (interrupt locked) system time.
+ * This contrary to the goals of a real-time operating system. So a user-land
+ * (thread based) timer mechanism is also required.
+ *
+ * @pre GFX_USE_GTIMER must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GTIMER_H
+#define _GTIMER_H
+
+#include "gfx.h"
+
+#if GFX_USE_GTIMER || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+/* Data part of a static GTimer initialiser */
+#define _GTIMER_DATA() {0,0,0,0,0,0,0}
+
+/* Static GTimer initialiser */
+#define GTIMER_DECL(name) GTimer name = _GTIMER_DATA()
+
+/* A callback function (executed in a thread context) */
+typedef void (*GTimerFunction)(void *param);
+
+/**
+ * @brief A GTimer structure
+ */
+typedef struct GTimer_t {
+ GTimerFunction fn;
+ void *param;
+ systemticks_t when;
+ systemticks_t period;
+ uint16_t flags;
+ struct GTimer_t *next;
+ struct GTimer_t *prev;
+} GTimer;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise a timer
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ *
+ * @api
+ */
+void gtimerInit(GTimer* pt);
+
+/**
+ * @brief Deinitialise a timer
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ *
+ * @api
+ */
+void gtimerDeinit(GTimer* pt);
+
+/**
+ * @brief Set a timer going or alter its properties if it is already going.
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ * @param[in] fn The callback function
+ * @param[in] param The parameter to pass to the callback function
+ * @param[in] periodic Is the timer a periodic timer? FALSE is a once-only timer.
+ * @param[in] millisec The timer period. The following special values are allowed:
+ * TIME_IMMEDIATE causes the callback function to be called asap.
+ * A periodic timer with this value will fire once only.
+ * TIME_INFINITE never timeout (unless triggered by gtimerJab or gtimerJabI)
+ *
+ * @note If the timer is already active its properties are updated with the new parameters.
+ * The current period will be immediately canceled (without the callback function being
+ * called) and the timer will be restart with the new timer properties.
+ * @note The callback function should be careful not to over-run the thread stack.
+ * Define a new value for the macro GTIME_THREAD_STACK_SIZE if you want to
+ * change the default size.
+ * @note The callback function should return as quickly as possible as all
+ * timer callbacks are performed by a single thread. If a callback function
+ * takes too long it could affect the timer response for other timers.
+ * @note A timer callback function is not a replacement for a dedicated thread if the
+ * function wants to perform computationally expensive stuff.
+ * @note As the callback function is called on GTIMER's thread, the function must make sure it uses
+ * appropriate synchronisation controls such as semaphores or mutexes around any data
+ * structures it shares with other threads such as the main application thread.
+ *
+ * @api
+ */
+void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, delaytime_t millisec);
+
+/**
+ * @brief Stop a timer (periodic or otherwise)
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ *
+ * @note If the timer is not active this does nothing.
+ *
+ * @api
+ */
+void gtimerStop(GTimer *pt);
+
+/**
+ * @brief Test if a timer is currently active
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ *
+ * @return TRUE if active, FALSE otherwise
+ *
+ * @api
+ */
+bool_t gtimerIsActive(GTimer *pt);
+
+/**
+ * @brief Jab a timer causing the current period to immediate expire
+ * @details The callback function will be called as soon as possible.
+ *
+ * @pre Use from a normal thread context.
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ *
+ * @note If the timer is not active this does nothing.
+ * @note Repeated Jabs before the callback function actually happens are ignored.
+ *
+ * @api
+ */
+void gtimerJab(GTimer *pt);
+
+/**
+ * @brief Jab a timer causing the current period to immediate expire
+ * @details The callback function will be called as soon as possible.
+ *
+ * @pre Use from an interrupt routine context.
+ *
+ * @param[in] pt Pointer to a GTimer structure
+ *
+ * @note If the timer is not active this does nothing.
+ * @note Repeated Jabs before the callback function actually happens are ignored.
+ *
+ * @iclass
+ * @api
+ */
+void gtimerJabI(GTimer *pt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GTIMER */
+
+#endif /* _GTIMER_H */
+/** @} */
+
diff --git a/src/gtimer/gtimer.mk b/src/gtimer/sys_make.mk
index e6c2b588..801c31a6 100644
--- a/src/gtimer/gtimer.mk
+++ b/src/gtimer/sys_make.mk
@@ -1 +1 @@
-GFXSRC += $(GFXLIB)/src/gtimer/gtimer.c
+GFXSRC += $(GFXLIB)/src/gtimer/gtimer.c
diff --git a/src/gtimer/sys_options.h b/src/gtimer/sys_options.h
new file mode 100644
index 00000000..8dca0b82
--- /dev/null
+++ b/src/gtimer/sys_options.h
@@ -0,0 +1,46 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gtimer/sys_options.h
+ * @brief GTIMER sub-system options header file.
+ *
+ * @addtogroup GTIMER
+ * @{
+ */
+
+#ifndef _GTIMER_OPTIONS_H
+#define _GTIMER_OPTIONS_H
+
+/**
+ * @name GTIMER Functionality to be included
+ * @{
+ */
+/**
+ * @}
+ *
+ * @name GTIMER Optional Sizing Parameters
+ * @{
+ */
+ /**
+ * @brief Defines the GTIMER thread priority
+ * @details Defaults to HIGH_PRIORITY
+ */
+ #ifndef GTIMER_THREAD_PRIORITY
+ #define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
+ #endif
+ /**
+ * @brief Defines the size of the timer threads work area (stack+structures).
+ * @details Defaults to 2048 bytes
+ */
+ #ifndef GTIMER_THREAD_WORKAREA_SIZE
+ #define GTIMER_THREAD_WORKAREA_SIZE 2048
+ #endif
+/** @} */
+
+#endif /* _GTIMER_OPTIONS_H */
+/** @} */
diff --git a/src/gtimer/sys_rules.h b/src/gtimer/sys_rules.h
new file mode 100644
index 00000000..6f277965
--- /dev/null
+++ b/src/gtimer/sys_rules.h
@@ -0,0 +1,29 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gtimer/sys_rules.h
+ * @brief GTIMER safety rules header file.
+ *
+ * @addtogroup GTIMER
+ * @{
+ */
+
+#ifndef _GTIMER_RULES_H
+#define _GTIMER_RULES_H
+
+#if GFX_USE_GTIMER
+ #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GTIMER: GDISP_NEED_MULTITHREAD has not been specified."
+ #warning "GTIMER: Make sure you are not performing any GDISP/GWIN drawing operations in the timer callback!"
+ #endif
+ #endif
+#endif
+
+#endif /* _GTIMER_RULES_H */
+/** @} */
diff --git a/src/gwin/button.c b/src/gwin/button.c
index b0fd973a..72d75225 100644
--- a/src/gwin/button.c
+++ b/src/gwin/button.c
@@ -19,7 +19,7 @@
#if GFX_USE_GWIN && GWIN_NEED_BUTTON
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
// Parameters for various shapes
#define RND_CNR_SIZE 5 // Rounded corner size for rounded buttons
diff --git a/src/gwin/button.h b/src/gwin/button.h
new file mode 100644
index 00000000..d11764d6
--- /dev/null
+++ b/src/gwin/button.h
@@ -0,0 +1,138 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/button.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup Button Button
+ * @ingroup GWIN
+ *
+ * @details GWIN allows it to easily create buttons with different styles
+ * and check for different meta states such as: PRESSED, CLICKED,
+ * RELEASED etc.
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_BUTTON must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+#ifndef _GWIN_BUTTON_H
+#define _GWIN_BUTTON_H
+
+/* This file is included within "gwin/gwidget.h" */
+
+/**
+ * @brief The Event Type for a Button Event
+ */
+#define GEVENT_GWIN_BUTTON (GEVENT_GWIN_FIRST+0)
+
+/**
+ * @brief A Button Event
+ * @note There are currently no GEventGWinButton listening flags - use 0 as the flags to @p gwinAttachListener()
+ */
+typedef struct GEventGWinButton {
+ GEventType type; // The type of this event (GEVENT_GWIN_BUTTON)
+ GHandle button; // The button that has been depressed (actually triggered on release)
+} GEventGWinButton;
+
+/**
+ * @brief The button widget structure
+ * @note Do not use the members directly - treat it as a black-box.
+ */
+typedef struct GButtonObject {
+ GWidgetObject w;
+ #if GINPUT_NEED_TOGGLE
+ uint16_t toggle;
+ #endif
+} GButtonObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a button widget.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gb The GButtonObject structure to initialise. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit The initialisation parameters
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note A button remembers its normal drawing state. If there is a window manager then it is automatically
+ * redrawn if the window is moved or its visibility state is changed.
+ * @note A button supports mouse and a toggle input.
+ * @note When assigning a toggle, only one toggle is supported. If you try to assign more than one toggle it will
+ * forget the previous toggle. When assigning a toggle the role parameter must be 0.
+ *
+ * @api
+ */
+GHandle gwinGButtonCreate(GDisplay *g, GButtonObject *gb, const GWidgetInit *pInit);
+#define gwinButtonCreate(gb, pInit) gwinGButtonCreate(GDISP, gb, pInit)
+
+/**
+ * @brief Is the button current pressed
+ * @return TRUE if the button is depressed
+ *
+ * @param[in] gh The window handle (must be a button widget)
+ *
+ * @api
+ */
+bool_t gwinButtonIsPressed(GHandle gh);
+
+/**
+ * @brief Some custom button drawing routines
+ * @details These function may be passed to @p gwinSetCustomDraw() to get different button drawing styles
+ *
+ * @param[in] gw The widget object (in this case a button)
+ * @param[in] param A parameter passed in from the user
+ *
+ * @note In your custom button drawing function you may optionally call these
+ * standard functions and then draw your extra details on top.
+ * @note The standard functions below ignore the param parameter except for @p gwinButtonDraw_Image().
+ * @note The image custom draw function @p gwinButtonDraw_Image() uses param to pass in the gdispImage pointer.
+ * The image must be already opened before calling @p gwinSetCustomDraw(). The image should be 3
+ * times the height of the button. The button image is repeated 3 times vertically, the first (top) for
+ * the "up" image, the 2nd for the "down" image, and the third (bottom) image for the disabled state. If
+ * the disabled state is never going to be used then the image can be just 2 times the button height.
+ * No checking is done to compare the size of the button to the size of the image.
+ * Note text is drawn on top of the image.
+ * @note These custom drawing routines don't have to worry about setting clipping as the framework
+ * sets clipping to the object window prior to calling these routines.
+ *
+ * @api
+ * @{
+ */
+void gwinButtonDraw_3D(GWidgetObject *gw, void *param); // @< A standard 3D button
+#if GDISP_NEED_ARC || defined(__DOXYGEN__)
+ void gwinButtonDraw_Rounded(GWidgetObject *gw, void *param); // @< A rounded rectangle button
+#endif
+#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
+ void gwinButtonDraw_Ellipse(GWidgetObject *gw, void *param); // @< A circular button
+#endif
+#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
+ void gwinButtonDraw_ArrowUp(GWidgetObject *gw, void *param); // @< An up arrow button
+ void gwinButtonDraw_ArrowDown(GWidgetObject *gw, void *param); // @< A down arrow button
+ void gwinButtonDraw_ArrowLeft(GWidgetObject *gw, void *param); // @< A left arrow button
+ void gwinButtonDraw_ArrowRight(GWidgetObject *gw, void *param); // @< A right arrow button
+#endif
+#if GDISP_NEED_IMAGE || defined(__DOXYGEN__)
+ void gwinButtonDraw_Image(GWidgetObject *gw, void *param); // @< An image button - see the notes above on the param.
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GWIN_BUTTON_H */
+/** @} */
+
diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c
index 13730d50..8cdd51d9 100644
--- a/src/gwin/checkbox.c
+++ b/src/gwin/checkbox.c
@@ -19,7 +19,7 @@
#if (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) || defined(__DOXYGEN__)
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
// Our checked state
#define GCHECKBOX_FLG_CHECKED (GWIN_FIRST_CONTROL_FLAG<<0)
diff --git a/src/gwin/checkbox.h b/src/gwin/checkbox.h
new file mode 100644
index 00000000..946f7e4a
--- /dev/null
+++ b/src/gwin/checkbox.h
@@ -0,0 +1,116 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/checkbox.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup Checkbox Checkbox
+ * @ingroup GWIN
+ *
+ * @details GWIN allows it to easily create a group of checkbox buttons.
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_CHECKBOX must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+#ifndef _GWIN_CHECKBOX_H
+#define _GWIN_CHECKBOX_H
+
+/* This file is included within "gwin/gwidget.h" */
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define GEVENT_GWIN_CHECKBOX (GEVENT_GWIN_FIRST+2)
+
+/*===========================================================================*/
+/* Type definitions */
+/*===========================================================================*/
+
+typedef struct GEventGWinCheckbox {
+ GEventType type; // The type of this event (GEVENT_GWIN_CHECKBOX)
+ GHandle checkbox; // The checkbox that has been depressed (actually triggered on release)
+ bool_t isChecked; // Is the checkbox currently checked or unchecked?
+} GEventGWinCheckbox;
+
+/* A Checkbox window */
+typedef struct GCheckboxObject {
+ GWidgetObject w;
+ #if GINPUT_NEED_TOGGLE
+ uint16_t toggle;
+ #endif
+} GCheckboxObject;
+
+/**
+ * @brief Create a checkbox window.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gb The GCheckboxObject structure to initialise. If this is NULL, the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note A checkbox remembers its normal drawing state. If there is a window manager then it is automatically
+ * redrawn if the window is moved or its visibility state is changed.
+ * @note A checkbox supports mouse and a toggle input.
+ * @note When assigning a toggle, only one toggle is supported. If you try to assign more than one toggle it will
+ * forget the previous toggle. When assigning a toggle the role parameter must be 0.
+ *
+ * @api
+ */
+GHandle gwinGCheckboxCreate(GDisplay *g, GCheckboxObject *gb, const GWidgetInit *pInit);
+#define gwinCheckboxCreate(gb, pInit) gwinGCheckboxCreate(GDISP, gb, pInit)
+
+/**
+ * @brief Set the state of a checkbox
+ *
+ * @param[in] gh The window handle (must be a checkbox window)
+ * @param[in] isChecked TRUE to set the check, FALSE to uncheck.
+ *
+ * @api
+ */
+void gwinCheckboxCheck(GHandle gh, bool_t isChecked);
+
+/**
+ * @brief Get the state of a checkbox
+ * @return TRUE if the checkbox is currently checked
+ *
+ * @param[in] gh The window handle (must be a checkbox window)
+ *
+ * @api
+ */
+bool_t gwinCheckboxIsChecked(GHandle gh);
+
+/**
+ * @brief Some custom checkbox drawing routines
+ * @details These function may be passed to @p gwinSetCustomDraw() to get different checkbox drawing styles
+ *
+ * @param[in] gw The widget (which must be a checkbox)
+ * @param[in] param A parameter passed in from the user
+ *
+ * @note In your custom checkbox drawing function you may optionally call this
+ * standard functions and then draw your extra details on top.
+ * @note The standard functions below ignore the param parameter.
+ * @note These custom drawing routines don't have to worry about setting clipping as the framework
+ * sets clipping to the object window prior to calling these routines.
+ *
+ * @api
+ * @{
+ */
+void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param);
+void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param);
+/* @} */
+
+#endif /* _GWIN_CHECKBOX_H */
+/** @} */
+
diff --git a/src/gwin/class_gwin.h b/src/gwin/class_gwin.h
new file mode 100644
index 00000000..ae5ac756
--- /dev/null
+++ b/src/gwin/class_gwin.h
@@ -0,0 +1,216 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/class_gwin.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup Internal Internal
+ * @ingroup GWIN
+ *
+ * @note These definitions are normally not used by an application program. They are useful
+ * only if you want to create your own custom GWIN window or widget.
+ * @note To access these definitions you must include "gwin/class_gwin.h" in your source file.
+ *
+ * @{
+ */
+#ifndef _CLASS_GWIN_H
+#define _CLASS_GWIN_H
+
+#if GFX_USE_GWIN || defined(__DOXYGEN__)
+
+/**
+ * @brief The predefined flags for a Window
+ * @{
+ */
+#define GWIN_FLG_DYNAMIC 0x0001 // @< The GWIN structure is allocated
+#define GWIN_FLG_VISIBLE 0x0002 // @< The window is visible
+#define GWIN_FLG_MINIMIZED 0x0004 // @< The window is minimized
+#define GWIN_FLG_MAXIMIZED 0x0008 // @< The window is maximized
+#define GWIN_FLG_ENABLED 0x0010 // @< The window is enabled
+#define GWIN_FLG_WIDGET 0x0020 // @< This is a widget
+#define GWIN_FLG_ALLOCTXT 0x0040 // @< The widget text is allocated
+#define GWIN_FLG_MOUSECAPTURE 0x0080 // @< The widget has captured the mouse
+#define GWIN_FIRST_WM_FLAG 0x0100 // @< 4 bits free for the window manager to use
+#define GWIN_FIRST_CONTROL_FLAG 0x1000 // @< 4 bits free for Windows and Widgets to use
+/* @} */
+
+/**
+ * @brief The Virtual Method Table for a GWIN window
+ * @{
+ */
+typedef struct gwinVMT {
+ const char * classname; // @< The GWIN classname (mandatory)
+ size_t size; // @< The size of the class object
+ void (*Destroy) (GWindowObject *gh); // @< The GWIN destroy function (optional)
+ void (*Redraw) (GWindowObject *gh); // @< The GWIN redraw routine (optional)
+ void (*AfterClear) (GWindowObject *gh); // @< The GWIN after-clear function (optional)
+} gwinVMT;
+/* @} */
+
+#if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
+
+ /**
+ * @brief An toggle/dial instance is not being used
+ */
+ #define GWIDGET_NO_INSTANCE ((uint16_t)-1)
+
+ /**
+ * @brief The source handle that widgets use when sending events
+ */
+ #define GWIDGET_SOURCE ((GSourceHandle)(void *)_gwidgetCreate)
+
+ /**
+ * @brief The Virtual Method Table for a widget
+ * @note A widget must have a destroy function. Either use @p _gwidgetDestroy() or use your own function
+ * which internally calls @p _gwidgetDestroy().
+ * @note A widget must have a redraw function. Use @p _gwidgetRedraw().
+ * @note If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.
+ * @note If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.
+ * @{
+ */
+ typedef struct gwidgetVMT {
+ struct gwinVMT g; // @< This is still a GWIN
+ void (*DefaultDraw) (GWidgetObject *gw, void *param); // @< The default drawing routine (mandatory)
+ #if GINPUT_NEED_MOUSE
+ struct {
+ void (*MouseDown) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse down events (optional)
+ void (*MouseUp) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse up events (optional)
+ void (*MouseMove) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse move events (optional)
+ };
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ struct {
+ uint16_t toggleroles; // @< The roles supported for toggles (0->toggleroles-1)
+ void (*ToggleAssign) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Assign a toggle to a role (optional)
+ uint16_t (*ToggleGet) (GWidgetObject *gw, uint16_t role); // @< Return the instance for a particular role (optional)
+ void (*ToggleOff) (GWidgetObject *gw, uint16_t role); // @< Process toggle off events (optional)
+ void (*ToggleOn) (GWidgetObject *gw, uint16_t role); // @< Process toggle on events (optional)
+ };
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ struct {
+ uint16_t dialroles; // @< The roles supported for dials (0->dialroles-1)
+ void (*DialAssign) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Test the role and save the dial instance handle (optional)
+ uint16_t (*DialGet) (GWidgetObject *gw, uint16_t role); // @< Return the instance for a particular role (optional)
+ void (*DialMove) (GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max); // @< Process dial move events (optional)
+ };
+ #endif
+ } gwidgetVMT;
+ /* @} */
+#endif
+
+// These flags are needed whether or not we are running a window manager.
+/**
+ * @brief Flags for redrawing after a visibility change
+ * @{
+ */
+#define GWIN_WMFLG_PRESERVE 0x0001 // @< Preserve whatever existing contents possible if a window can't redraw
+#define GWIN_WMFLG_NOBGCLEAR 0x0002 // @< Don't clear the area if the window is not visible
+#define GWIN_WMFLG_NOZORDER 0x0004 // @< Don't redraw higher z-order windows that overlap
+/* @} */
+
+#if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__)
+ #if 1 // When we know that wmq is the first element of the GWindowObject structure
+ #define QItem2GWindow(qi) ((GHandle)qi)
+ #else
+ #define QItem2GWindow(qi) ((GHandle)(((char *)(qi)) - (size_t)(&(((GWindowObject *)0)->wmq))))
+ #endif
+
+ // @note There is only ever one instance of each GWindowManager type
+ typedef struct GWindowManager {
+ const struct gwmVMT *vmt;
+ } GWindowManager;
+
+ /**
+ * @brief The Virtual Method Table for a window manager
+ * @{
+ */
+ typedef struct gwmVMT {
+ void (*Init) (void); // @< The window manager has just been set as the current window manager
+ void (*DeInit) (void); // @< The window manager has just been removed as the current window manager
+ bool_t (*Add) (GHandle gh, const GWindowInit *pInit); // @< A window has been added
+ void (*Delete) (GHandle gh); // @< A window has been deleted
+ void (*Redraw) (GHandle gh, int visflags); // @< A window needs to be redraw (or undrawn)
+ void (*Redim) (GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h); // @< A window wants to be moved or resized
+ void (*Raise) (GHandle gh); // @< A window wants to be on top
+ void (*MinMax) (GHandle gh, GWindowMinMax minmax); // @< A window wants to be minimized/maximised
+ } gwmVMT;
+ /* @} */
+
+ /**
+ * @brief The list of all windows in the system
+ */
+ extern gfxQueueASync _GWINList;
+
+ /**
+ * @brief The current window manager
+ */
+ extern GWindowManager * _GWINwm;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialise (and allocate if necessary) the base GWIN object
+ *
+ * @param[in] g The GDisplay to use for this window
+ * @param[in] pgw The GWindowObject structure. If NULL one is allocated from the heap
+ * @param[in] pInit The user initialization parameters
+ * @param[in] vmt The virtual method table for the GWIN object
+ * @param[in] flags The default flags to use
+ *
+ * @return The GHandle of the created window
+ *
+ * @notapi
+ */
+GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags);
+
+#if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
+ /**
+ * @brief Initialise (and allocate if necessary) the base Widget object
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] pgw The GWidgetObject structure. If NULL one is allocated from the heap
+ * @param[in] pInit The user initialization parameters
+ * @param[in] vmt The virtual method table for the Widget object
+ *
+ * @return The GHandle of the created widget
+ *
+ * @notapi
+ */
+ GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt);
+
+ /**
+ * @brief Destroy the Widget object
+ *
+ * @param[in] gh The widget to destroy
+ *
+ * @notapi
+ */
+ void _gwidgetDestroy(GHandle gh);
+
+ /**
+ * @brief Redraw the Widget object
+ *
+ * @param[in] gh The widget to redraw
+ *
+ * @notapi
+ */
+ void _gwidgetRedraw(GHandle gh);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GWIN */
+
+#endif /* _CLASS_GWIN_H */
+/** @} */
diff --git a/src/gwin/console.c b/src/gwin/console.c
index 623404be..0fe4b722 100644
--- a/src/gwin/console.c
+++ b/src/gwin/console.c
@@ -16,7 +16,7 @@
#include <string.h>
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
#define GWIN_CONSOLE_USE_CLEAR_LINES TRUE // Clear each line before using it
#define GWIN_CONSOLE_USE_FILLED_CHARS FALSE // Use filled characters instead of drawn characters
diff --git a/src/gwin/console.h b/src/gwin/console.h
new file mode 100644
index 00000000..252b627e
--- /dev/null
+++ b/src/gwin/console.h
@@ -0,0 +1,172 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/console.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup Console Console
+ * @ingroup GWIN
+ *
+ * @details GWIN allows it to create a console/terminal like window.
+ * You can simply use chprintf() to print to the terminal.
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_CONSOLE must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GWIN_CONSOLE_H
+#define _GWIN_CONSOLE_H
+
+/* This file is included within "gwin/gwin.h" */
+
+// A console window. Supports wrapped text writing and a cursor.
+typedef struct GConsoleObject {
+ GWindowObject g;
+ coord_t cx, cy; // Cursor position
+
+ #if GWIN_CONSOLE_USE_HISTORY
+ char * buffer; // buffer to store console content
+ size_t bufsize; // size of buffer
+ size_t bufpos; // the position of the next char
+ #endif
+
+ #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
+ struct GConsoleWindowStream_t {
+ const struct GConsoleWindowVMT_t *vmt;
+ _base_asynchronous_channel_data
+ } stream;
+ #endif
+
+} GConsoleObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a console window.
+ * @details A console window allows text to be written.
+ * @note Text in a console window supports newlines and will wrap text as required.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gc The GConsoleObject structure to initialise. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note On creation even if the window is visible it is not automatically cleared.
+ * You may do that by calling @p gwinClear() (possibly after changing your background color)
+ * @note A console does not save the drawing state. It is not automatically redrawn if the window is moved or
+ * its visibility state is changed.
+ *
+ * @api
+ */
+GHandle gwinGConsoleCreate(GDisplay *g, GConsoleObject *gc, const GWindowInit *pInit);
+#define gwinConsoleCreate(gc, pInit) gwinGConsoleCreate(GDISP, gc, pInit)
+
+#if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
+ /**
+ * @brief Get a stream from a console window suitable for use with chprintf().
+ * @return The stream handle or NULL if this is not a console window.
+ *
+ * @param[in] gh The window handle (must be a console window)
+ *
+ * @note Only useful in ChibiOS
+ *
+ * @api
+ */
+ BaseSequentialStream *gwinConsoleGetStream(GHandle gh);
+#endif
+
+#if GWIN_CONSOLE_USE_HISTORY
+ /**
+ * @brief Assign a buffer to keep track of the content while the widget is invisible.
+ * @pre GWIN_CONSOLE_USE_HISTORY must be set to TRUE in your gfxconf.h
+ *
+ * @param[in] gh The window handle (must be a console window)
+ * @param[in] onoff If TRUE a buffer is allocated to maintain console text
+ * when the console is obscured or invisible. If FALSE, then
+ * any existing buffer is deallocated.
+ * @note When the history buffer is turned on, scrolling is implemented using the
+ * history buffer.
+ *
+ * @return TRUE if the history buffer is now turned on.
+ */
+ bool_t gwinConsoleSetBuffer(GHandle gh, bool_t onoff);
+#endif
+
+/**
+ * @brief Put a character at the cursor position in the window.
+ * @note Uses the current foreground color to draw the character and fills the background using the background drawing color
+ *
+ * @param[in] gh The window handle (must be a console window)
+ * @param[in] c The character to draw
+ *
+ * @api
+ */
+void gwinPutChar(GHandle gh, char c);
+
+/**
+ * @brief Put a string at the cursor position in the window. It will wrap lines as required.
+ * @note Uses the current foreground color to draw the string and fills the background using the background drawing color
+ *
+ * @param[in] gh The window handle (must be a console window)
+ * @param[in] str The string to draw
+ *
+ * @api
+ */
+void gwinPutString(GHandle gh, const char *str);
+
+/**
+ * @brief Put the character array at the cursor position in the window. It will wrap lines as required.
+ * @note Uses the current foreground color to draw the string and fills the background using the background drawing color
+ *
+ * @param[in] gh The window handle (must be a console window)
+ * @param[in] str The string to draw
+ * @param[in] n The number of characters to draw
+ *
+ * @api
+ */
+void gwinPutCharArray(GHandle gh, const char *str, size_t n);
+
+/**
+ * @brief Print a formatted string at the cursor position in the window. It will wrap lines as required.
+ * @details This function implements a minimal printf() like functionality
+ * The general parameters format is: %[-][width|*][.precision|*][l|L]p.
+ * The following parameter types (p) are supported:
+ * - <b>x</b> hexadecimal integer.
+ * - <b>X</b> hexadecimal long.
+ * - <b>o</b> octal integer.
+ * - <b>O</b> octal long.
+ * - <b>d</b> decimal signed integer.
+ * - <b>D</b> decimal signed long.
+ * - <b>u</b> decimal unsigned integer.
+ * - <b>U</b> decimal unsigned long.
+ * - <b>c</b> character.
+ * - <b>s</b> string.
+ * @note Uses the current foreground color to draw the string and fills the background using the background drawing color
+ *
+ * @param[in] gh The window handle (must be a console window)
+ * @param[in] fmt The format string (as per printf)
+ * @param[in] ... The format string arguments.
+ *
+ * @api
+ */
+void gwinPrintf(GHandle gh, const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GWIN_CONSOLE_H */
+/** @} */
diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c
index e4032b96..953aefc3 100644
--- a/src/gwin/gimage.c
+++ b/src/gwin/gimage.c
@@ -14,7 +14,7 @@
#if GFX_USE_GWIN && GWIN_NEED_IMAGE
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
#define widget(gh) ((GImageObject *)gh)
diff --git a/src/gwin/graph.c b/src/gwin/graph.c
index 1d513290..c06639fe 100644
--- a/src/gwin/graph.c
+++ b/src/gwin/graph.c
@@ -14,7 +14,7 @@
#if GFX_USE_GWIN && GWIN_NEED_GRAPH
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
#define GGRAPH_FLG_CONNECTPOINTS (GWIN_FIRST_CONTROL_FLAG<<0)
#define GGRAPH_ARROW_SIZE 5
diff --git a/src/gwin/graph.h b/src/gwin/graph.h
new file mode 100644
index 00000000..65a64126
--- /dev/null
+++ b/src/gwin/graph.h
@@ -0,0 +1,186 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/graph.h
+ * @brief GWIN GRAPH module header file.
+ *
+ * @defgroup Graph Graph
+ * @ingroup GWIN
+ *
+ * @details GWIN allows it to easily draw graphs.
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_GRAPH must be set to TRUE in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GWIN_GRAPH_H
+#define _GWIN_GRAPH_H
+
+/* This file is included within "gwin/gwin.h" */
+
+typedef enum GGraphPointType_e {
+ GGRAPH_POINT_NONE, GGRAPH_POINT_DOT, GGRAPH_POINT_SQUARE, GGRAPH_POINT_CIRCLE
+ } GGraphPointType;
+
+typedef struct GGraphPointStyle_t {
+ GGraphPointType type;
+ coord_t size;
+ color_t color;
+ } GGraphPointStyle;
+
+typedef enum GGraphLineType_e {
+ GGRAPH_LINE_NONE, GGRAPH_LINE_SOLID, GGRAPH_LINE_DOT, GGRAPH_LINE_DASH
+ } GGraphLineType;
+
+typedef struct GGraphLineStyle_t {
+ GGraphLineType type;
+ coord_t size;
+ color_t color;
+ } GGraphLineStyle;
+
+typedef struct GGraphGridStyle_t {
+ GGraphLineType type;
+ coord_t size;
+ color_t color;
+ coord_t spacing;
+ } GGraphGridStyle;
+
+typedef struct GGraphStyle_t {
+ GGraphPointStyle point;
+ GGraphLineStyle line;
+ GGraphLineStyle xaxis;
+ GGraphLineStyle yaxis;
+ GGraphGridStyle xgrid;
+ GGraphGridStyle ygrid;
+ uint16_t flags;
+ #define GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS 0x0001
+ #define GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS 0x0002
+ #define GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS 0x0004
+ #define GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS 0x0008
+ #define GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS)
+ #define GWIN_GRAPH_STYLE_NEGATIVE_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS)
+ #define GWIN_GRAPH_STYLE_XAXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_XAXIS_NEGATIVE_ARROWS)
+ #define GWIN_GRAPH_STYLE_YAXIS_ARROWS (GWIN_GRAPH_STYLE_YAXIS_POSITIVE_ARROWS|GWIN_GRAPH_STYLE_YAXIS_NEGATIVE_ARROWS)
+ #define GWIN_GRAPH_STYLE_ALL_AXIS_ARROWS (GWIN_GRAPH_STYLE_XAXIS_ARROWS|GWIN_GRAPH_STYLE_YAXIS_ARROWS)
+} GGraphStyle;
+
+// A graph window
+typedef struct GGraphObject {
+ GWindowObject g;
+ GGraphStyle style;
+ coord_t xorigin, yorigin;
+ coord_t lastx, lasty;
+ } GGraphObject;
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a graph window.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gg The GGraphObject structure to initialise. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note The dimensions and position may be changed to fit on the real screen.
+ * @note A graph does not save the drawing state. It is not automatically redrawn if the window is moved or
+ * its visibility state is changed.
+ * @note The coordinate system within the window for graphing operations (but not for any other drawing
+ * operation) is relative to the bottom left corner and then shifted right and up by the specified
+ * graphing x and y origin. Note that this system is inverted in the y direction relative to the display.
+ * This gives the best graphing arrangement ie. increasing y values are closer to the top of the display.
+ *
+ * @api
+ */
+GHandle gwinGGraphCreate(GDisplay *g, GGraphObject *gg, const GWindowInit *pInit);
+#define gwinGraphCreate(gg, pInit) gwinGGraphCreate(GDISP, gg, pInit)
+
+/**
+ * @brief Set the style of the graphing operations.
+ *
+ * @param[in] gh The window handle (must be a graph window)
+ * @param[in] pstyle The graph style to set.
+ * @note The graph is not automatically redrawn. The new style will apply to any new drawing operations.
+ *
+ * @api
+ */
+void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle);
+
+/**
+ * @brief Set the origin for graphing operations.
+ *
+ * @param[in] gh The window handle (must be a graph window)
+ * @param[in] x, y The new origin for the graph (in graph coordinates relative to the bottom left corner).
+ * @note The graph is not automatically redrawn. The new origin will apply to any new drawing operations.
+ *
+ * @api
+ */
+void gwinGraphSetOrigin(GHandle gh, coord_t x, coord_t y);
+
+/**
+ * @brief Draw the axis and the background grid.
+ *
+ * @param[in] gh The window handle (must be a graph window)
+ * @note The graph is not automatically cleared. You must do that first by calling gwinClear().
+ *
+ * @api
+ */
+void gwinGraphDrawAxis(GHandle gh);
+
+/**
+ * @brief Start a new set of graphing data.
+ * @details This prevents a line being drawn from the last data point to the next point to be drawn.
+ *
+ * @param[in] gh The window handle (must be a graph window)
+ *
+ * @api
+ */
+void gwinGraphStartSet(GHandle gh);
+
+/**
+ * @brief Draw a graph point.
+ * @details A graph point and a line connecting to the previous point will be drawn.
+ *
+ * @param[in] gh The window handle (must be a graph window)
+ * @param[in] x, y The new point for the graph.
+ *
+ * @api
+ */
+void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y);
+
+/**
+ * @brief Draw multiple graph points.
+ * @details A graph point and a line connecting to each previous point will be drawn.
+ *
+ * @param[in] gh The window handle (must be a graph window)
+ * @param[in] points The array of points for the graph.
+ * @param[in] count The number of points in the array.
+ * @note This is slightly more efficient than calling gwinGraphDrawPoint() repeatedly.
+ *
+ * @api
+ */
+void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GWIN_GRAPH_H */
+/** @} */
+
diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c
index 75a69667..ad2b7b20 100644
--- a/src/gwin/gwidget.c
+++ b/src/gwin/gwidget.c
@@ -11,7 +11,7 @@
#include <string.h>
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
/* Our listener for events for widgets */
static GListener gl;
diff --git a/src/gwin/gwidget.h b/src/gwin/gwidget.h
new file mode 100644
index 00000000..4eaf6c81
--- /dev/null
+++ b/src/gwin/gwidget.h
@@ -0,0 +1,308 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/gwidget.h
+ * @brief GWIN Widgets header file.
+ */
+
+#ifndef _GWIDGET_H
+#define _GWIDGET_H
+
+/* This file is included within "gwin/gwin.h" */
+
+/**
+ * @defgroup Widget Widget
+ * @ingroup GWIN
+ *
+ * @details A Widget is a GWindow that supports interacting with the user
+ * via an input device such as a mouse or toggle buttons. It is the
+ * base class for widgets such as buttons and sliders.
+ *
+ * @pre GFX_USE_GWIN and GWIN_NEED_WIDGET must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+// Forward definition
+struct GWidgetObject;
+
+/**
+ * @brief The GColorSet structure
+ * @{
+ */
+typedef struct GColorSet {
+ color_t text; // @< The text color
+ color_t edge; // @< The edge color
+ color_t fill; // @< The fill color
+ color_t progress; // @< The color of progress bars
+} GColorSet;
+/* @} */
+
+/**
+ * @brief The GWidgetStyle structure
+ * @details A GWidgetStyle is a set of colors that together form a "style".
+ * These colors should not be confused with the GWindow foreground
+ * and background colors which are used for drawing operations.
+ * @{
+ */
+typedef struct GWidgetStyle {
+ color_t background; // @< The window background color
+ GColorSet enabled; // @< The colors when enabled
+ GColorSet disabled; // @< The colors when disabled
+ GColorSet pressed; // @< The colors when pressed
+} GWidgetStyle;
+/* @} */
+
+/**
+ * @brief We define a couple of GWidgetStyle's that you can use in your
+ * application. The Black style is the default style if you don't
+ * specify one.
+ * @note BlackWidgetStyle means that it is designed for a Black background.
+ * Similarly WhiteWidgetStyle is designed for a White background.
+ * @{
+ */
+extern const GWidgetStyle BlackWidgetStyle;
+extern const GWidgetStyle WhiteWidgetStyle;
+/* @} */
+
+/**
+ * @brief Defines a custom drawing function for a widget
+ */
+typedef void (*CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param);
+
+/**
+ * @brief The structure to initialise a widget.
+ *
+ * @note Some widgets may have extra parameters.
+ * @note The text element must be static string (not stack allocated). If you want to use
+ * a dynamic string (eg a stack allocated string) use NULL for this member and then call
+ * @p gwinSetText() with useAlloc set to TRUE.
+ *
+ * @{
+ */
+typedef struct GWidgetInit {
+ GWindowInit g; // @< The GWIN initializer
+ const char * text; // @< The initial text
+ CustomWidgetDrawFunction customDraw; // @< A custom draw function - use NULL for the standard
+ void * customParam; // @< A parameter for the custom draw function (default = NULL)
+ const GWidgetStyle * customStyle; // @< A custom style to use - use NULL for the default style
+} GWidgetInit;
+/* @} */
+
+/**
+ * @brief The GWIN Widget structure
+ * @note A widget is a GWIN window that accepts user input.
+ * It also has a number of other properties such as its ability
+ * to redraw itself (a widget maintains drawing state).
+ * @note Do not access the members directly. Treat it as a black-box and use the method functions.
+ *
+ * @{
+ */
+typedef struct GWidgetObject {
+ GWindowObject g; // @< This is still a GWIN
+ const char * text; // @< The widget text
+ CustomWidgetDrawFunction fnDraw; // @< The current draw function
+ void * fnParam; // @< A parameter for the current draw function
+ const GWidgetStyle * pstyle; // @< The current widget style colors
+} GWidgetObject;
+/* @} */
+
+/**
+ * A comment/rant on the above structure:
+ * We would really like the GWindowObject member to be anonymous. While this is
+ * allowed under the C11, C99, GNU and various other standards which have been
+ * around forever - compiler support often requires special flags e.g
+ * gcc requires the -fms-extensions flag (no wonder the language and compilers have
+ * not really progressed in 30 years). As portability is a key requirement
+ * we unfortunately won't use this useful feature in case we get a compiler that
+ * won't support it even with special flags.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Set the default style for widgets created hereafter.
+ *
+ * @param[in] pstyle The default style. Passing NULL uses the system compiled style.
+ * @param[in] updateAll If TRUE then all existing widgets that are using the current default style
+ * will be updated to use this new style. Widgets that have custom styles different
+ * from the default style will not be updated.
+ *
+ * @note The style must be allocated statically (not on the stack) as only the pointer is stored.
+ *
+ * @api
+ */
+void gwinSetDefaultStyle(const GWidgetStyle *pstyle, bool_t updateAll);
+
+/**
+ * @brief Get the current default style.
+ *
+ * @return The current default style.
+ *
+ * @api
+ */
+const GWidgetStyle *gwinGetDefaultStyle(void);
+
+/**
+ * @brief Set the text of a widget.
+ *
+ * @param[in] gh The widget handle
+ * @param[in] text The text to set. This must be a constant string unless useAlloc is set.
+ * @param[in] useAlloc If TRUE the string specified will be copied into dynamically allocated memory.
+ *
+ * @note The widget is automatically redrawn
+ * @note Non-widgets will ignore this call.
+ *
+ * @api
+ */
+void gwinSetText(GHandle gh, const char *text, bool_t useAlloc);
+
+/**
+ * @brief Get the text of a widget.
+ * @return The widget text or NULL if it isn't a widget
+ *
+ * @param[in] gh The widget handle
+ *
+ * @api
+ */
+const char *gwinGetText(GHandle gh);
+
+/**
+ * @brief Set the style of a widget.
+ *
+ * @param[in] gh The widget handle
+ * @param[in] pstyle The style to set. This must be a static structure (not allocated on a transient stack).
+ * Use NULL to reset to the default style.
+ *
+ * @note The widget is automatically redrawn
+ * @note Non-widgets will ignore this call.
+ *
+ * @api
+ */
+void gwinSetStyle(GHandle gh, const GWidgetStyle *pstyle);
+
+/**
+ * @brief Get the style of a widget.
+ * @return The widget style or NULL if it isn't a widget
+ *
+ * @param[in] gh The widget handle
+ *
+ * @api
+ */
+const GWidgetStyle *gwinGetStyle(GHandle gh);
+
+/**
+ * @brief Set the routine to perform a custom widget drawing.
+ *
+ * @param[in] gh The widget handle
+ * @param[in] fn The function to use to draw the widget
+ * @param[in] param A parameter to pass to the widget drawing function
+ *
+ * @note The widget is not automatically redrawn. Call @p gwinDraw() to redraw the widget.
+ * @note Non-widgets will ignore this call.
+ *
+ * @api
+ */
+void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param);
+
+/**
+ * @brief Attach a Listener to listen for widget events
+ * @return TRUE on success
+ *
+ * @param[in] pl The listener
+ *
+ * @api
+ */
+bool_t gwinAttachListener(GListener *pl);
+
+#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
+ /**
+ * @brief Set the mouse to be used to control the widgets
+ * @return TRUE on success
+ *
+ * @param[in] instance The mouse instance
+ *
+ * @note Every widget uses the same mouse.
+ *
+ * @api
+ */
+ bool_t gwinAttachMouse(uint16_t instance);
+#endif
+
+#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
+ /**
+ * @brief Attach a toggle to a widget
+ * @return TRUE on success
+ *
+ * @param[in] gh The widget handle
+ * @param[in] role The function the toggle will perform for the widget
+ * @param[in] instance The toggle instance
+ *
+ * @note See the documentation on the specific widget to see the possible
+ * values for the role parameter. If it is out of range, this function
+ * will return FALSE
+ *
+ * @api
+ */
+ bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance);
+#endif
+
+#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
+ /**
+ * @brief Attach a toggle to a widget
+ * @return TRUE on success
+ *
+ * @param[in] gh The widget handle
+ * @param[in] role The function the dial will perform for the widget
+ * @param[in] instance The dial instance
+ *
+ * @note See the documentation on the specific widget to see the possible
+ * values for the role parameter. If it is out of range, this function
+ * will return FALSE
+ *
+ * @api
+ */
+ bool_t gwinAttachDial(GHandle gh, uint16_t role, uint16_t instance);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Include extra widget types */
+#if GWIN_NEED_BUTTON || defined(__DOXYGEN__)
+ #include "src/gwin/button.h"
+#endif
+
+#if GWIN_NEED_SLIDER || defined(__DOXYGEN__)
+ #include "src/gwin/slider.h"
+#endif
+
+#if GWIN_NEED_CHECKBOX || defined(__DOXYGEN__)
+ #include "src/gwin/checkbox.h"
+#endif
+
+#if GWIN_NEED_RADIO || defined(__DOXYGEN__)
+ #include "src/gwin/radio.h"
+#endif
+
+#if GWIN_NEED_LABEL || defined(__DOXYGEN__)
+ #include "src/gwin/label.h"
+#endif
+
+#if GWIN_NEED_LIST || defined(__DOXYGEN__)
+ #include "src/gwin/list.h"
+#endif
+
+#if GWIN_NEED_PROGRESSBAR || defined(__DOXYGEN__)
+ #include "src/gwin/progressbar.h"
+#endif
+
+#endif /* _GWIDGET_H */
+/** @} */
diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c
index 485ccaaa..54f42077 100644
--- a/src/gwin/gwin.c
+++ b/src/gwin/gwin.c
@@ -9,7 +9,7 @@
#if GFX_USE_GWIN
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
// Needed if there is no window manager
#define MIN_WIN_WIDTH 1
diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c
index e7a71737..9c158f68 100644
--- a/src/gwin/gwm.c
+++ b/src/gwin/gwm.c
@@ -17,7 +17,7 @@
#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
/*-----------------------------------------------
* Data
diff --git a/src/gwin/image.h b/src/gwin/image.h
new file mode 100644
index 00000000..66aba3d1
--- /dev/null
+++ b/src/gwin/image.h
@@ -0,0 +1,127 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/image.h
+ * @brief GWIN image widget header file.
+ *
+ * @defgroup Image Image
+ * @ingroup GWIN
+ *
+ * @details GWIN allos it to create an image widget. The widget
+ * takes no user input.
+ *
+ * @pre GFX_USE_GDISP must be set to TRUE in your gfxconf.h
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GDISP_NEED_IMAGE must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_IMAGE must be set to TRUE in your gfxconf.h
+ * @pre At least one image type must be enabled in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GWIN_IMAGE_H
+#define _GWIN_IMAGE_H
+
+// This file is included within "gwin/gwin.h"
+
+// An image window
+typedef struct GImageObject {
+ GWindowObject g;
+ gdispImage image; // The image itself
+ #if GWIN_NEED_IMAGE_ANIMATION
+ GTimer timer; // Timer used for animated images
+ #endif
+} GImageObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create an image widget.
+ * @details Display's a picture.
+ * @return NULL if there is no resultant drawing area, otherwise the widget handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] widget The image widget structure to initialise. If this is NULL, the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use.
+ *
+ * @note The default background color gets set to the current default one.
+ * @note An image window knows how to redraw.
+ *
+ * @api
+ */
+GHandle gwinGImageCreate(GDisplay *g, GImageObject *widget, GWindowInit *pInit);
+#define gwinImageCreate(w, pInit) gwinGImageCreate(GDISP, w, pInit)
+
+/**
+ * @brief Opens the image using a GFILE
+ * @return TRUE if the image can be opened
+ *
+ * @param[in] gh The widget (must be an image widget)
+ * @param[in] f The open (for reading) GFILE to use
+ *
+ * @api
+ */
+bool_t gwinImageOpenGFile(GHandle gh, GFILE *f);
+
+/**
+ * @brief Opens the image using the specified filename
+ * @return TRUE if the open succeeds
+ *
+ * @param[in] gh The widget (must be an image widget)
+ * @param[in] filename The filename to open
+ *
+ * @api
+ */
+#define gwinImageOpenFile(gh, filename) gwinImageOpenGFile((gh), gfileOpen((filename), "rb"))
+
+ /**
+ * @brief Sets the input routines that support reading the image from memory
+ * in RAM or flash.
+ * @pre GFILE_NEED_MEMFS must be TRUE
+ * @return TRUE if the IO open function succeeds
+ *
+ * @param[in] gh The widget (must be an image widget)
+ * @param[in] ptr A pointer to the image in RAM or Flash
+ *
+ * @api
+ */
+#define gwinImageOpenMemory(gh, ptr) gwinImageOpenGFile((gh), gfileOpenMemory((void *)(ptr), "rb"))
+
+/**
+ * @brief Sets the input routines that support reading the image from a BaseFileStream (eg. an SD-Card).
+ * @return TRUE if the IO open function succeeds
+ * @pre GFILE_NEED_CHIBIOSFS and GFX_USE_OS_CHIBIOS must be TRUE
+ *
+ * @param[in] gh The widget (must be an image widget)
+ * @param[in] streamPtr A pointer to the (open) BaseFileStream object.
+ *
+ * @api
+ */
+#define gwinImageOpenStream(gh, streamPtr) gwinImageOpenGFile((gh), gfileOpenBaseFIleStream((streamPtr), "rb"))
+
+/**
+ * @brief Cache the image.
+ * @details Decodes and caches the current frame into RAM.
+ *
+ * @param[in] gh The widget (must be an image widget)
+ *
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @api
+ */
+gdispImageError gwinImageCache(GHandle gh);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _GWIN_IMAGE_H
+/** @} */
+
diff --git a/src/gwin/label.c b/src/gwin/label.c
index 5619761a..97588a27 100644
--- a/src/gwin/label.c
+++ b/src/gwin/label.c
@@ -19,7 +19,7 @@
#if GFX_USE_GWIN && GWIN_NEED_LABEL
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
// macros to assist in data type conversions
#define gh2obj ((GLabelObject *)gh)
diff --git a/src/gwin/label.h b/src/gwin/label.h
new file mode 100644
index 00000000..3fe0f3d7
--- /dev/null
+++ b/src/gwin/label.h
@@ -0,0 +1,72 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/label.h
+ * @brief GWIN label widget header file.
+ *
+ * @defgroup Label Label
+ * @ingroup GWIN
+ *
+ * @details GWIN allos it to create an label widget. The widget
+ * takes no user input.
+ *
+ * @pre GFX_USE_GDISP must be set to TRUE in your gfxconf.h
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GDISP_NEED_TEXT must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_LABEL must be set to TRUE in your gfxconf.h
+ * @pre The fonts you want to use must be enabled in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GWIN_LABEL_H
+#define _GWIN_LABEL_H
+
+// This file is included within "gwin/gwin.h"
+
+// An label window
+typedef struct GLabelObject {
+ GWidgetObject w;
+} GLabelObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a label widget.
+ * @details A label widget is a simple window which has a static text.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] widget The label structure to initialise. If this is NULL, the structure is dynamically allocated.
+ * @param[in] pInit The initialisation parameters to use.
+ *
+ * @return NULL if there is no resultat drawing area, otherwise the widget handle.
+ *
+ * @api
+ */
+GHandle gwinGLabelCreate(GDisplay *g, GLabelObject *widget, GWidgetInit *pInit);
+#define gwinLabelCreate(w, pInit) gwinGLabelCreate(GDISP, w, pInit)
+
+/**
+ * @brief Border settings for the default rendering routine
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] border Shall a border be rendered?
+ *
+ * @api
+ */
+void gwinLabelSetBorder(GHandle gh, bool_t border);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _GWIN_LABEL_H
+/** @} */
+
diff --git a/src/gwin/list.c b/src/gwin/list.c
index 08e6a96d..5b49811c 100644
--- a/src/gwin/list.c
+++ b/src/gwin/list.c
@@ -19,7 +19,7 @@
#if GFX_USE_GWIN && GWIN_NEED_LIST
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
#include <string.h>
#include <stdlib.h>
diff --git a/src/gwin/list.h b/src/gwin/list.h
new file mode 100644
index 00000000..cfe6aeb2
--- /dev/null
+++ b/src/gwin/list.h
@@ -0,0 +1,287 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/list.h
+ * @brief GWIN list widget header file
+ *
+ * @defgroup List List
+ * @ingroup GWIN
+ *
+ * @details GWIN allows it to create a list widget.
+ *
+ * @pre GFX_USE_GDISP must be set to TRUE in your gfxconf.h
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GDISP_NEED_TEXT must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_LIST must be set to TRUE in your gfxconf.h
+ * @pre The font you want to use must be enabled in your gfxconf.h
+ *
+ * @{
+ */
+
+#ifndef _GWIN_LIST_H
+#define _GWIN_LIST_H
+
+// This file is included within "gwin/gwin.h"
+
+/**
+ * @brief The event type for a list event
+ */
+#define GEVENT_GWIN_LIST (GEVENT_GWIN_FIRST+4)
+
+/**
+ * @brief A list event
+ */
+typedef struct GEventGWinList {
+ GEventType type; // The type of this event (GEVENT_GWIN_LIST)
+ GHandle list; // The list
+ int item; // The item that has been selected (or unselected in a multi-select listbox)
+} GEventGWinList;
+
+// A list window
+typedef struct GListObject {
+ GWidgetObject w;
+
+ #if GINPUT_NEED_MOUSE
+ coord_t start_mouse_x;
+ coord_t start_mouse_y;
+ coord_t last_mouse_y;
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ uint16_t t_up;
+ uint16_t t_dn;
+ #endif
+
+ int cnt; // Number of items currently in the list (quicker than counting each time)
+ int top; // Viewing offset in pixels from the top of the list
+ gfxQueueASync list_head; // The list of items
+} GListObject;
+
+/**
+ * @brief Enum to change the behaviour of the scroll bar
+ *
+ * @note Used with @p gwinListSetScroll()
+ * @note @p scrollAlways always show the scrollbar
+ * @note @p scrollAuto show the scrollbar when there are more items on the list then fit on the screen
+ * @note @p scrollSmooth enable touch screen smooth scrolling
+ */
+typedef enum scroll_t { scrollAlways, scrollAuto, scrollSmooth } scroll_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a list widget
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are Black and White.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then
+ * there is no default font and text drawing operations will not display anything.
+ * @note A list remembers its normal drawing state. If there is a window manager then it is automatically
+ * redrawn if the window is moved or its visibility state is changed.
+ * @note The list contains no elements after creation.
+ * @note A slider supports mouse, toggle. Note: toggle only works correctly for single-select lists.
+ * @note When assigning a toggle, only one toggle is supported per role. If you try to assign more than
+ * one toggle to a role, it will forget the previous toggle. Two roles are supported:
+ * Role 0 = toggle for down, role 1 = toggle for up
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] widget The GListObject structure to initialize. If this is NULL, the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use
+ * @param[in] multiselect If TRUE the list is multi-select instead of single-select.
+ *
+ * @return NULL if there is no resulting drawing area, otherwise a window handle.
+ *
+ * @api
+ */
+GHandle gwinGListCreate(GDisplay *g, GListObject *widget, GWidgetInit *pInit, bool_t multiselect);
+#define gwinListCreate(w, pInit, m) gwinGListCreate(GDISP, w, pInit, m)
+
+/**
+ * @brief Change the behaviour of the scroll bar
+ *
+ * @note Current possible values: @p scrollAlways, @p scrollAuto and @p scrollSmooth
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] flag The behaviour to be set
+ *
+ * @api
+ */
+void gwinListSetScroll(GHandle gh, scroll_t flag);
+
+/**
+ * @brief Add an item to the list
+ *
+ * @note The ID you get returned is not static. If items get removed from the list, the list items get
+ * reordered.
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The string which shall be displayed in the list afterwards
+ * @param[in] useAlloc If set to TRUE, the string will be dynamically allocated. A static buffer must be passed otherwise
+ *
+ * @return The current ID of the item. The ID might change if you remove items from the middle of the list
+ *
+ * @api
+ */
+int gwinListAddItem(GHandle gh, const char* item, bool_t useAlloc);
+
+/**
+ * @brief Get the name behind an item with a given ID
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The item ID
+ *
+ * @return The string of the list item or NULL on error
+ *
+ * @api
+ */
+const char* gwinListItemGetText(GHandle gh, int item);
+
+/**
+ * @brief Get the ID of an item with a given name
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] text The item name
+ *
+ * @return The id of the list item or -1 on error
+ *
+ * @api
+ */
+int gwinListFindText(GHandle gh, const char* text);
+
+/**
+ * @brief Set the custom parameter of an item with a given ID
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The item ID
+ * @param[in] param The parameter to be set
+ *
+ * @api
+ */
+void gwinListItemSetParam(GHandle gh, int item, uint16_t param);
+
+/**
+ * @brief Get the custom parameter of an item with a given ID
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The item ID
+ *
+ * @return The parameter
+ *
+ * @api
+ */
+uint16_t gwinListItemGetParam(GHandle gh, int item);
+
+/**
+ * @brief Delete all the items of the list
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ *
+ * @api
+ */
+void gwinListDeleteAll(GHandle gh);
+
+/**
+ * @brief Delete an item from the list
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The item ID
+ *
+ * @api
+ */
+void gwinListItemDelete(GHandle gh, int item);
+
+/**
+ * @brief Get the amount of items within the list
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ *
+ * @return The amount of items in the list
+ *
+ * @api
+ */
+int gwinListItemCount(GHandle gh);
+
+/**
+ * @brief Check if an item with a given ID is selected
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The item ID
+ *
+ * @return TRUE if the item is selected, FALSE otherwise
+ *
+ * @api
+ */
+bool_t gwinListItemIsSelected(GHandle gh, int item);
+
+/**
+ * @brief Get the ID of the selected item
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ *
+ * @return The ID of the selected list item for a single-select list.
+ *
+ * @note It always returns -1 (nothing selected) for a multi-select list.
+ * Instead use @p gwinListItemIsSelected() to get the selection status
+ * for a multi-select list.
+ *
+ * @api
+ */
+int gwinListGetSelected(GHandle gh);
+
+/**
+ * @brief Get the text of the selected item
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ *
+ * @return The test of the selected list item for a single-select list.
+ *
+ * @note It always returns NULL (nothing selected) for a multi-select list.
+ *
+ * @api
+ */
+const char* gwinListGetSelectedText(GHandle gh);
+
+#if GWIN_NEED_LIST_IMAGES || defined(__DOXYGEN__)
+ /**
+ * @brief Set the image for a list item
+ *
+ * @pre GWIN_NEED_LIST_IMAGES must be set to true in your gfxconf.h
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] item The item ID
+ * @param[in] pimg The image to be displayed or NULL to turn off the image for this list item.
+ *
+ * @note The image should be up to 4 x (the font height) and a width of (the font height).
+ * The 1st (top) part of the image is displayed for a selected item.
+ * The 2nd part of the image is displayed for an unselected item.
+ * The 3rd part of the image is displayed for a disabled selected item.
+ * The 4th part of the image is displayed for a disabled unselected item.
+ * If the image is less than 4 times the font height then the image use is collapsed
+ * into the available height. For example, an image that equals the font height will use
+ * the same image for all four states.
+ * @note The image is only displayed while it is open. It is up to the application to open
+ * the image.
+ * @note The same image can be used on more than one list item.
+ * @note Images are aligned with the top (not the baseline) of the list item.
+ * @note When any item in the list has an image attached, space is allocated to display
+ * the images even if the image is closed or has been removed by calling @p gwinListItemSetImage()
+ * with a NULL image or by calling @p gwinListItemDelete(). The only way to turn-off the image area
+ * for this list is to call gwinListDeleteAll().
+ *
+ */
+ void gwinListItemSetImage(GHandle gh, int item, gdispImage *pimg);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _GWIN_LIST_H
+/** @} */
+
diff --git a/src/gwin/progressbar.c b/src/gwin/progressbar.c
index a2364d9f..37bad3c8 100644
--- a/src/gwin/progressbar.c
+++ b/src/gwin/progressbar.c
@@ -19,7 +19,7 @@
#if (GFX_USE_GWIN && GWIN_NEED_PROGRESSBAR) || defined(__DOXYGEN__)
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
// Reset the display position back to the value predicted by the saved progressbar position
static void ResetDisplayPos(GProgressbarObject *gsw) {
diff --git a/src/gwin/progressbar.h b/src/gwin/progressbar.h
new file mode 100644
index 00000000..c9efe46b
--- /dev/null
+++ b/src/gwin/progressbar.h
@@ -0,0 +1,190 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/progressbar.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup Progressbar Progressbar
+ * @ingroup GWIN
+ *
+ * @details Create progressbars with different styles
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_PROGRESSBAR must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+#ifndef _GWIN_PROGRESSBAR_H
+#define _GWIN_PROGRESSBAR_H
+
+// A progressbar window
+typedef struct GProgressbarObject {
+ GWidgetObject w;
+ coord_t dpos;
+ int min;
+ int max;
+ int res;
+ int pos;
+ #if GFX_USE_GTIMER
+ GTimer gt;
+ delaytime_t delay;
+ #endif
+} GProgressbarObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a progressbar window.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gb The GProgressbarObject structure to initialise. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note A progressbar remembers its normal drawing state. If there is a window manager then it is automatically
+ * redrawn if the window is moved or its visibility state is changed.
+ * @note The initial progressbar range is from 0 to 100 with an initial position of 0.
+ * @note A progressbar does not take any GINPUT inputs.
+ *
+ * @api
+ */
+GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gb, const GWidgetInit *pInit);
+#define gwinProgressbarCreate(w, pInit) gwinGProgressbarCreate(GDISP, w, pInit)
+
+/**
+ * @brief Set the progressbar range.
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ * @param[in] min The minimum value
+ * @param[in] max The maximum value
+ *
+ * @note The defaults are 0 and 100
+ * @note Sets the position to the minimum value.
+ * @note The progressbar is not automatically drawn. Call gwinProgressbarDraw() after changing the range.
+ *
+ * @api
+ */
+void gwinProgressbarSetRange(GHandle gh, int min, int max);
+
+/**
+ * @brief Set the progressbar position.
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ * @param[in] pos The new position
+ *
+ * @note If the new position is outside the progressbar range then the position
+ * is set to the closest end of the range.
+ * @note The progressbar is not automatically drawn. Call gwinProgressbarDraw() after changing the position.
+ *
+ * @api
+ */
+void gwinProgressbarSetPosition(GHandle gh, int pos);
+
+/**
+ * @brief Set the resolution for the incrementation and decrementation of the progressbar
+ *
+ * @note Default is set to 1
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ * @param[in] res The resolution to be set
+ *
+ * @api
+ */
+void gwinProgressbarSetResolution(GHandle gh, int res);
+
+/**
+ * @brief Increment the progressbar value
+ *
+ * @details Increments by the resolution set through gwinProgressbarSetResolution()
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ *
+ * @api
+ */
+void gwinProgressbarIncrement(GHandle gh);
+
+/**
+ * @brief Decrement the progressbar value
+ *
+ * @details Decrements by the resolution set through gwinProgressbarSetResolution()
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ *
+ * @api
+ */
+void gwinProgressbarDecrement(GHandle gh);
+
+/**
+ * @brief Get the current progressbar position.
+ * @return The progressbar position
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ *
+ * @note The use of a listener to get the progressbar position is recommended if you
+ * want continuous updates on the progressbar position.
+ *
+ * @api
+ */
+#define gwinProgressbarGetPosition(gh) (((GProgressbarObject *)(gh))->pos)
+
+/**
+ * @brief Automatically increments the progress bar
+ *
+ * @note The delay is generated using the GTIMER module which is based on software/virtual timer.
+ * Therefore, the delay is totally unprecise.
+ *
+ * @note The progressbar incrementation starts at the current level. It is not reset to the minimum value.
+ *
+ * @note An event is generated once the maximum value has been reached (ToDo)
+ *
+ * @param[in] gh The window handle (must be a progressbar window)
+ * @param[in] delay The incrementation delay (in milliseconds)
+ *
+ * @api
+ */
+void gwinProgressbarStart(GHandle gh, delaytime_t delay);
+
+/**
+ * @brief Some custom progressbar drawing routines
+ * @details These function may be passed to @p gwinSetCustomDraw() to get different progressbar drawing styles
+ *
+ * @param[in] gw The widget (which must be a progressbar)
+ * @param[in] param A parameter passed in from the user
+ *
+ * @note In your custom progressbar drawing function you may optionally call this
+ * standard functions and then draw your extra details on top.
+ * @note The standard functions below ignore the param parameter except for @p gwinProgressbarDraw_Image().
+ * @note The image custom draw function @p gwinProgressbarDraw_Image() uses param to pass in the gdispImage pointer.
+ * The image must be already opened before calling @p gwinSetCustomDraw(). The image is tiled to fill
+ * the active area of the progressbar. The normal colors apply to the border and inactive area and the dividing line
+ * between the active and inactive areas.
+ * No checking is done to compare the dimensions of the progressbar to the size of the image.
+ * Note text is drawn on top of the image.
+ * @note These custom drawing routines don't have to worry about setting clipping as the framework
+ * sets clipping to the object window prior to calling these routines.
+ *
+ * @api
+ * @{
+ */
+void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param);
+void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param);
+/* @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GWIN_PROGRESSBAR_H */
+/** @} */
+
diff --git a/src/gwin/radio.c b/src/gwin/radio.c
index 7507634c..f50ffe9b 100644
--- a/src/gwin/radio.c
+++ b/src/gwin/radio.c
@@ -19,7 +19,7 @@
#if GFX_USE_GWIN && GWIN_NEED_RADIO
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
// Our pressed state
#define GRADIO_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0)
diff --git a/src/gwin/radio.h b/src/gwin/radio.h
new file mode 100644
index 00000000..3ee2918f
--- /dev/null
+++ b/src/gwin/radio.h
@@ -0,0 +1,142 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/radio.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup RadioButton RadioButton
+ * @ingroup GWIN
+ *
+ * @details GWIN allows it to easily create radio buttons with different styles.
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_RADIO must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+#ifndef _GWIN_RADIO_H
+#define _GWIN_RADIO_H
+
+/* This file is included within "gwin/gwidget.h" */
+
+/**
+ * @brief The Event Type for a Radio Event
+ */
+#define GEVENT_GWIN_RADIO (GEVENT_GWIN_FIRST+3)
+
+/**
+ * @brief A Button Event
+ * @note There are currently no GEventGWinRadio listening flags - use 0 as the flags to @p gwinAttachListener()
+ */
+typedef struct GEventGWinRadio {
+ GEventType type; // The type of this event (GEVENT_GWIN_RADIO)
+ GHandle radio; // The radio button that has been depressed
+ uint16_t group; // The group for this radio button
+} GEventGWinRadio;
+
+/**
+ * @brief The radio button widget structure
+ * @note Do not use the members directly - treat it as a black-box.
+ */
+typedef struct GRadioObject {
+ GWidgetObject w;
+ #if GINPUT_NEED_TOGGLE
+ uint16_t toggle;
+ #endif
+ uint16_t group;
+} GRadioObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a radio widget.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gb The GRadioObject structure to initialise. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit The initialisation parameters
+ * @param[in] group The group of radio buttons this radio button belongs to.
+ *
+ * @note Only one radio button in any group is ever pressed at one time. Pressing one radio button will
+ * release all others in the group.
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note A radio button remembers its normal drawing state. If there is a window manager then it is automatically
+ * redrawn if the window is moved or its visibility state is changed.
+ * @note A radio button supports mouse and a toggle input.
+ * @note When assigning a toggle, only one toggle is supported. If you try to assign more than one toggle it will
+ * forget the previous toggle. When assigning a toggle the role parameter must be 0.
+ *
+ * @api
+ */
+GHandle gwinGRadioCreate(GDisplay *g, GRadioObject *gb, const GWidgetInit *pInit, uint16_t group);
+#define gwinRadioCreate(w, pInit, gr) gwinGRadioCreate(GDISP, w, pInit, gr)
+
+/**
+ * @brief Press this radio button (and by definition unset any others in the group)
+ *
+ * @param[in] gh The window handle (must be a radio widget)
+ *
+ * @api
+ */
+void gwinRadioPress(GHandle gh);
+
+/**
+ * @brief Is the radio button currently pressed
+ * @return TRUE if the button is pressed
+ *
+ * @param[in] gh The window handle (must be a radio widget)
+ *
+ * @api
+ */
+bool_t gwinRadioIsPressed(GHandle gh);
+
+/**
+ * @brief Find the currently pressed radio button in the specified group
+ * @return The handle of the pressed radio button or NULL if none are pressed
+ *
+ * @param[in] group The radio button group to be examined
+ *
+ * @return The handle of the currently pressed radio button
+ *
+ * @api
+ */
+GHandle gwinRadioGetActive(uint16_t group);
+
+/**
+ * @brief Some custom radio button drawing routines
+ * @details These function may be passed to @p gwinSetCustomDraw() to get different radio button drawing styles
+ *
+ * @param[in] gw The widget object (in this case a radio button)
+ * @param[in] param A parameter passed in from the user
+ *
+ * @note In your custom radio drawing function you may optionally call these
+ * standard functions and then draw your extra details on top.
+ * @note The standard functions below ignore the param parameter.
+ * @note These custom drawing routines don't have to worry about setting clipping as the framework
+ * sets clipping to the object window prior to calling these routines.
+ *
+ * @api
+ * @{
+ */
+void gwinRadioDraw_Radio(GWidgetObject *gw, void *param); // @< A standard radio button
+void gwinRadioDraw_Button(GWidgetObject *gw, void *param); // @< Draw as a button
+void gwinRadioDraw_Tab(GWidgetObject *gw, void *param); // @< Draw as a tab
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GWIN_RADIO_H */
+/** @} */
+
diff --git a/src/gwin/slider.c b/src/gwin/slider.c
index 5d6a5ec0..4c91ede6 100644
--- a/src/gwin/slider.c
+++ b/src/gwin/slider.c
@@ -19,7 +19,7 @@
#if (GFX_USE_GWIN && GWIN_NEED_SLIDER) || defined(__DOXYGEN__)
-#include "gwin/class_gwin.h"
+#include "src/gwin/class_gwin.h"
#ifndef GWIN_SLIDER_DEAD_BAND
#define GWIN_SLIDER_DEAD_BAND 5
diff --git a/src/gwin/slider.h b/src/gwin/slider.h
new file mode 100644
index 00000000..8f87745c
--- /dev/null
+++ b/src/gwin/slider.h
@@ -0,0 +1,155 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/slider.h
+ * @brief GWIN Graphic window subsystem header file.
+ *
+ * @defgroup Slider Slider
+ * @ingroup GWIN
+ *
+ * @details Create sliders with different styles
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @pre GWIN_NEED_SLIDER must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+#ifndef _GWIN_SLIDER_H
+#define _GWIN_SLIDER_H
+
+/* This file is included within "gwin/gwidget.h" */
+
+#define GEVENT_GWIN_SLIDER (GEVENT_GWIN_FIRST+1)
+
+typedef struct GEventGWinSlider {
+ GEventType type; // The type of this event (GEVENT_GWIN_BUTTON)
+ GHandle slider; // The slider that is returning results
+ int position;
+} GEventGWinSlider;
+
+// There are currently no GEventGWinSlider listening flags - use 0
+
+// A slider window
+typedef struct GSliderObject {
+ GWidgetObject w;
+ #if GINPUT_NEED_TOGGLE
+ uint16_t t_dn;
+ uint16_t t_up;
+ #endif
+ #if GINPUT_NEED_DIAL
+ uint16_t dial;
+ #endif
+ coord_t dpos;
+ int min;
+ int max;
+ int pos;
+} GSliderObject;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a slider window.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] gb The GSliderObject structure to initialise. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit The initialization parameters to use
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note A slider remembers its normal drawing state. If there is a window manager then it is automatically
+ * redrawn if the window is moved or its visibility state is changed.
+ * @note The initial slider range is from 0 to 100 with an initial position of 0.
+ * @note A slider supports mouse, toggle and dial input.
+ * @note When assigning a toggle, only one toggle is supported per role. If you try to assign more than
+ * one toggle to a role it will forget the previous toggle. Two roles are supported:
+ * Role 0 = toggle for down, Role 1 = toggle for up.
+ * @note When assigning a dial, only one dial is supported. If you try to assign more than one dial
+ * it will forget the previous dial. Only dial role 0 is supported.
+ *
+ * @api
+ */
+GHandle gwinGSliderCreate(GDisplay *g, GSliderObject *gb, const GWidgetInit *pInit);
+#define gwinSliderCreate(w, pInit) gwinGSliderCreate(GDISP, w, pInit)
+
+/**
+ * @brief Set the slider range.
+ *
+ * @param[in] gh The window handle (must be a slider window)
+ * @param[in] min The minimum value
+ * @param[in] max The maximum value
+ * @note Sets the position to the minimum value.
+ * @note The slider is not automatically drawn. Call gwinSliderDraw() after changing the range.
+ *
+ * @api
+ */
+void gwinSliderSetRange(GHandle gh, int min, int max);
+
+/**
+ * @brief Set the slider position.
+ *
+ * @param[in] gh The window handle (must be a slider window)
+ * @param[in] pos The new position
+ * @note If the new position is outside the slider range then the position
+ * is set to the closest end of the range.
+ * @note The slider is not automatically drawn. Call gwinSliderDraw() after changing the position.
+ *
+ * @api
+ */
+void gwinSliderSetPosition(GHandle gh, int pos);
+
+/**
+ * @brief Get the current slider position.
+ * @return The slider position
+ *
+ * @param[in] gh The window handle (must be a slider window)
+ *
+ * @note The use of a listener to get the slider position is recommended if you
+ * want continuous updates on the slider position.
+ *
+ * @api
+ */
+#define gwinSliderGetPosition(gh) (((GSliderObject *)(gh))->pos)
+
+/**
+ * @brief Some custom slider drawing routines
+ * @details These function may be passed to @p gwinSetCustomDraw() to get different slider drawing styles
+ *
+ * @param[in] gw The widget (which must be a slider)
+ * @param[in] param A parameter passed in from the user
+ *
+ * @note In your custom slider drawing function you may optionally call this
+ * standard functions and then draw your extra details on top.
+ * @note The standard functions below ignore the param parameter except for @p gwinSliderDraw_Image().
+ * @note The image custom draw function @p gwinSliderDraw_Image() uses param to pass in the gdispImage pointer.
+ * The image must be already opened before calling @p gwinSetCustomDraw(). The image is tiled to fill
+ * the active area of the slider. The normal colors apply to the border and inactive area and the dividing line
+ * between the active and inactive areas.
+ * No checking is done to compare the dimensions of the slider to the size of the image.
+ * Note text is drawn on top of the image.
+ * @note These custom drawing routines don't have to worry about setting clipping as the framework
+ * sets clipping to the object window prior to calling these routines.
+ *
+ * @api
+ * @{
+ */
+void gwinSliderDraw_Std(GWidgetObject *gw, void *param);
+void gwinSliderDraw_Image(GWidgetObject *gw, void *param);
+/* @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GWIN_SLIDER_H */
+/** @} */
+
diff --git a/src/gwin/sys_defs.h b/src/gwin/sys_defs.h
new file mode 100644
index 00000000..10b5b564
--- /dev/null
+++ b/src/gwin/sys_defs.h
@@ -0,0 +1,863 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gwin/sys_defs.h
+ *
+ * @defgroup Window Window
+ * @ingroup GWIN
+ *
+ * @details GWIN provides a basic window manager which allows it to easily
+ * create and destroy different windows at runtime. Each window
+ * will have it's own properties such as colors as well as
+ * it's own drawing origin.
+ *
+ * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
+ * @{
+ */
+
+#ifndef _GWIN_H
+#define _GWIN_H
+
+#include "gfx.h"
+
+#if GFX_USE_GWIN || defined(__DOXYGEN__)
+
+/**
+ * @brief A window object structure
+ * @note Do not access the members directly. Treat it as a black-box and use the method functions.
+ * @{
+ */
+typedef struct GWindowObject {
+ #if GWIN_NEED_WINDOWMANAGER
+ // This MUST be the first member of the struct
+ gfxQueueASyncItem wmq; // @< The next window (for the window manager)
+ #endif
+ const struct gwinVMT *vmt; // @< The VMT for this GWIN
+ GDisplay * display; // @< The display this window is on.
+ coord_t x, y; // @< Screen relative position
+ coord_t width, height; // @< Dimensions of this window
+ color_t color, bgcolor; // @< The current drawing colors
+ uint32_t flags; // @< Window flags (the meaning is private to the GWIN class)
+ #if GDISP_NEED_TEXT
+ font_t font; // @< The current font
+ #endif
+} GWindowObject, * GHandle;
+/* @} */
+
+/**
+ * @brief The structure to initialise a GWIN.
+ *
+ * @note Some gwin's will need extra parameters.
+ * @note The dimensions and position may be changed to fit on the real screen.
+ *
+ * @{
+ */
+typedef struct GWindowInit {
+ coord_t x, y; // @< The initial screen position
+ coord_t width, height; // @< The initial dimension
+ bool_t show; // @< Should the window be visible initially
+} GWindowInit;
+/* @} */
+
+/**
+ * @brief A window's minimized, maximized or normal size
+ */
+typedef enum { GWIN_NORMAL, GWIN_MAXIMIZE, GWIN_MINIMIZE } GWindowMinMax;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------------------------------------
+ * Window Manager functions
+ *-------------------------------------------------*/
+
+#if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__)
+ // Forward definition
+ struct GWindowManager;
+
+ /**
+ * @brief Set the window manager for the GWIN system.
+ *
+ * @param[in] gwm The window manager to use. Can be NULL to turn off the existing window manager.
+ *
+ * @note A window manager is responsible for handling when window visibility is changed or
+ * a window is resized for moved. Note that only saved window states will be redrawn. Each
+ * window type can save different information (or none at all). See the documentation on each window
+ * type to see which information it saves (and can therefore be automatically redrawn).
+ * For window types that do not save any state information, the window manager determines what to do.
+ * Generally it will just clear the window to its background color.
+ *
+ * @api
+ */
+ void gwinSetWindowManager(struct GWindowManager *gwm);
+#endif
+
+/*-------------------------------------------------
+ * Functions that affect all windows
+ *-------------------------------------------------*/
+
+ /**
+ * @brief Set the default foreground color for all new GWIN windows
+ *
+ * @param[in] clr The color to be set
+ *
+ * @api
+ */
+ void gwinSetDefaultColor(color_t clr);
+
+ /**
+ * @brief Get the default foreground color for all new GWIN windows
+ *
+ * @return The current default color for all new GWIN windows
+ *
+ * @api
+ */
+ color_t gwinGetDefaultColor(void);
+
+ /**
+ * @brief Set the default background color for all new GWIN windows
+ *
+ * @param[in] bgclr The background color
+ *
+ * @api
+ */
+ void gwinSetDefaultBgColor(color_t bgclr);
+
+ /**
+ * @brief Get the default background color for all new GWIN windows
+ *
+ * @return The current default background color for all new GWIN windows
+ *
+ * @api
+ */
+ color_t gwinGetDefaultBgColor(void);
+
+ #if GDISP_NEED_TEXT || defined(__DOXYGEN__)
+ /**
+ * @brief Set the default font for all new GWIN windows
+ *
+ * @param[in] font The new font to be set
+ *
+ * @api
+ */
+ void gwinSetDefaultFont(font_t font);
+
+ /**
+ * @brief Get the current default font
+ *
+ * @return The current default font
+ *
+ * @api
+ */
+ font_t gwinGetDefaultFont(void);
+ #endif
+
+/*-------------------------------------------------
+ * Base functions
+ *-------------------------------------------------*/
+
+ /**
+ * @brief Create a basic window.
+ * @return NULL if there is no resultant drawing area, otherwise a window handle.
+ *
+ * @param[in] g The GDisplay to display this window on
+ * @param[in] pgw The window structure to initialize. If this is NULL the structure is dynamically allocated.
+ * @param[in] pInit How to initialise the window
+ *
+ * @note The drawing color and the background color get set to the current defaults. If you haven't called
+ * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
+ * @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
+ * is no default font and text drawing operations will no nothing.
+ * @note A basic window does not save the drawing state. It is not automatically redrawn if the window is moved or
+ * its visibility state is changed.
+ *
+ * @api
+ */
+ GHandle gwinGWindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit);
+ #define gwinWindowCreate(pgw, pInit) gwinGWindowCreate(GDISP, pgw, pInit);
+
+ /**
+ * @brief Destroy a window (of any type). Releases any dynamically allocated memory.
+ *
+ * @param[in] gh The window handle
+ *
+ * @api
+ */
+ void gwinDestroy(GHandle gh);
+
+ /**
+ * @brief Get the real class name of the GHandle
+ * @details Returns a string describing the object class.
+ *
+ * @param[in] gh The window
+ *
+ * @return A string describing the object class.
+ *
+ * @api
+ */
+ const char* gwinGetClassName(GHandle gh);
+
+ /**
+ * @brief Get an ID that uniquely describes the class of the GHandle
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetClassID(gh) ((void *)((gh)->vmt))
+
+ /**
+ * @brief Get the X coordinate of the window
+ * @details Returns the X coordinate of the origin of the window.
+ * The coordinate is relative to the physical screen zero point.
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetScreenX(gh) ((gh)->x)
+
+ /**
+ * @brief Get the Y coordinate of the window
+ * @details Returns the Y coordinate of the origin of the window.
+ * The coordinate is relative to the physical screen zero point.
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetScreenY(gh) ((gh)->y)
+
+ /**
+ * @brief Get the width of the window
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetWidth(gh) ((gh)->width)
+
+ /**
+ * @brief Get the height of the window
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetHeight(gh) ((gh)->height)
+
+ /**
+ * @brief Set foreground color
+ * @details Set the color which will be used to draw
+ *
+ * @param[in] gh The window
+ * @param[in] clr The color to be set
+ *
+ * @api
+ */
+ #define gwinSetColor(gh, clr) (gh)->color = (clr)
+
+ /**
+ * @brief Set background color
+ * @details Set the color which will be used as background
+ * @note gwinClear() must be called to set the background color
+ *
+ * @param[in] gh The window
+ * @param[in] bgclr The background color
+ *
+ * @api
+ */
+ #define gwinSetBgColor(gh, bgclr) (gh)->bgcolor = (bgclr)
+
+ /**
+ * @brief Get the foreground color of a window
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetColor(gh) (gh)->color
+
+ /**
+ * @brief Get the background color of a window
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ #define gwinGetBgColor(gh) (gh)->bgcolor
+
+ /**
+ * @brief Sets whether a window is visible or not
+ *
+ * @param[in] gh The window
+ * @param[in] visible Whether the window should be visible or not
+ *
+ * @note When a window is marked as not visible, drawing operations
+ * on the window do nothing.
+ * @note When a window is marked as visible, it is not automatically
+ * redrawn as many window types don't remember their drawing state.
+ * Widgets such as Buttons, Sliders etc will be redrawn.
+ * @note If there is no window manager in use, when a window is marked
+ * as not visible, nothing is done to remove the window from the screen.
+ * When there is a window manager, it is up to the window manager to
+ * handle what happens.
+ *
+ * @api
+ */
+ void gwinSetVisible(GHandle gh, bool_t visible);
+
+ /**
+ * @brief Gets the visibility of a window
+ * @return TRUE if visible
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ bool_t gwinGetVisible(GHandle gh);
+
+ /**
+ * @brief Enable or disable a window
+ *
+ * @param[in] gh The window handle
+ * @param[in] enabled Enable or disable the window
+ *
+ * @note The window is automatically redrawn if it
+ * supports self-redrawing.
+ *
+ * @api
+ */
+ void gwinSetEnabled(GHandle gh, bool_t enabled);
+
+ /**
+ * @brief Gets the enabled state of a window
+ * @return TRUE if enabled
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ bool_t gwinGetEnabled(GHandle gh);
+
+ /**
+ * @brief Move a window
+ *
+ * @param[in] gh The window
+ * @param[in] x, y The new position (screen relative) for this window
+ *
+ * @note The final window position may not be the requested position. Windows
+ * are clipped to the screen area and the window manager may also affect the position.
+ * @note The window is redrawn if it is visible. See the comments in @p gwinSetVisible()
+ * with regard to what can be redrawn and what can't.
+ * @note It is up to the window manager to determine what happens with the screen area
+ * uncovered by moving the window. When there is no window manager, nothing
+ * is done with the uncovered area.
+ *
+ * @api
+ */
+ void gwinMove(GHandle gh, coord_t x, coord_t y);
+
+ /**
+ * @brief Resize a window
+ *
+ * @param[in] gh The window
+ * @param[in] width, height The new size of the window
+ *
+ * @note The final window size may not be the requested size. Windows
+ * are clipped to the screen area and the window manager may also affect the size.
+ * @note The window is redrawn if it is visible. See the comments in @p gwinSetVisible()
+ * with regard to what can be redrawn and what can't.
+ * @note It is up to the window manager to determine what happens with any screen area
+ * uncovered by resizing the window. When there is no window manager, nothing
+ * is done with the uncovered area.
+ *
+ * @api
+ */
+ void gwinResize(GHandle gh, coord_t width, coord_t height);
+
+ /**
+ * @brief Redraw a window
+ *
+ * @param[in] gh The window
+ *
+ * @note This is normally never required as windows and widgets will redraw as required.
+ * Note that some windows are incapable of redrawing themselves as they don't save
+ * their drawing state.
+ *
+ * @api
+ */
+ void gwinRedraw(GHandle gh);
+
+ #if GWIN_NEED_WINDOWMANAGER || defined (__DOXYGEN__)
+ /**
+ * @brief Redraw a window
+ *
+ * @param[in] g The display to redraw. Passing NULL will redraw all displays.
+ * @param[in] preserve Should the redraw try to preserve existing screen data for those
+ * windows that can't redraw themselves?
+ *
+ * @note This is normally never required as windows and widgets will redraw as required.
+ * @note Some windows are incapable of redrawing themselves as they don't save
+ * their drawing state.
+ * @note This does not clear the background - just redraws the gwin windows (where possible)
+ *
+ * @api
+ */
+ void gwinRedrawDisplay(GDisplay *g, bool_t preserve);
+
+ /**
+ * @brief Minimize, Maximize or Restore a window
+ * @pre GWIN_NEED_WINDOWMANAGER must be TRUE
+ *
+ * @param[in] gh The window
+ * @param[in] minmax The new minimized/maximized state
+ *
+ * @note The final window state may not be the requested state. Window Managers
+ * do not need to implement changing the minmax state. If there is no
+ * window manager this call is ignored.
+ * @note The window is redrawn if it is changed. See the comments in @p gwinSetVisible()
+ * with regard to what can be redrawn and what can't.
+ * @note It is up to the window manager to determine what happens with any screen area
+ * uncovered by resizing the window.
+ * @note When a window is minimised it may be asked to draw the window or the window
+ * manager may draw the minimised window.
+ *
+ * @api
+ */
+ void gwinSetMinMax(GHandle gh, GWindowMinMax minmax);
+
+ /**
+ * @brief Get the Minimized/Maximized state of a window
+ * @pre GWIN_NEED_WINDOWMANAGER must be TRUE
+ *
+ * @param[in] gh The window
+ *
+ * @api
+ */
+ GWindowMinMax gwinGetMinMax(GHandle gh);
+
+ /**
+ * @brief Raise a window to the top of the z-order
+ * @pre GWIN_NEED_WINDOWMANAGER must be TRUE
+ *
+ * @param[in] gh The window
+ *
+ * @note The window z-order is only supported by some window managers. See the comments
+ * in @p gwinSetVisible() with regard to what can be redrawn and what can't.
+ *
+ * @api
+ */
+ void gwinRaise(GHandle gh);
+ #endif
+
+ #if GDISP_NEED_TEXT || defined(__DOXYGEN__)
+ /**
+ * @brief Set the current font for this window.
+ *
+ * @param[in] gh The window handle
+ * @param[in] font The font to use for text functions
+ *
+ * @api
+ */
+ void gwinSetFont(GHandle gh, font_t font);
+ #endif
+
+/*-------------------------------------------------
+ * Drawing functions
+ *-------------------------------------------------*/
+
+ /**
+ * @brief Clear the window
+ * @note Uses the current background color to clear the window
+ *
+ * @param[in] gh The window handle
+ *
+ * @api
+ */
+ void gwinClear(GHandle gh);
+
+ /**
+ * @brief Set a pixel in the window
+ * @note Uses the current foreground color to set the pixel
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The coordinates of the pixel
+ *
+ * @api
+ */
+ void gwinDrawPixel(GHandle gh, coord_t x, coord_t y);
+
+ /**
+ * @brief Draw a line in the window
+ * @note Uses the current foreground color to draw the line
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x0,y0 The start position
+ * @param[in] x1,y1 The end position
+ *
+ * @api
+ */
+ void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1);
+
+ /**
+ * @brief Draw a box in the window
+ * @note Uses the current foreground color to draw the box
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ *
+ * @api
+ */
+ void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy);
+
+ /**
+ * @brief Fill an rectangular area in the window
+ * @note Uses the current foreground color to fill the box
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ *
+ * @api
+ */
+ void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy);
+
+ /**
+ * @brief Fill an area in the window using the supplied bitmap.
+ * @details The bitmap is in the pixel format specified by the low level driver
+ * @note If GDISP_NEED_ASYNC is defined then the buffer must be static
+ * or at least retained until this call has finished the blit. You can
+ * tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x, y The start filled area
+ * @param[in] cx, cy The width and height to be filled
+ * @param[in] srcx, srcy The bitmap position to start the fill from
+ * @param[in] srccx The width of a line in the bitmap.
+ * @param[in] buffer The pixels to use to fill the area.
+ *
+ * @api
+ */
+ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer);
+
+/*-------------------------------------------------
+ * Circle, ellipse and arc functions
+ *-------------------------------------------------*/
+
+ #if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a circle in the window.
+ * @note Uses the current foreground color to draw the circle
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x, y The center of the circle
+ * @param[in] radius The radius of the circle
+ *
+ * @api
+ */
+ void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius);
+
+ /**
+ * @brief Draw a filled circle in the window.
+ * @note Uses the current foreground color to draw the filled circle
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x, y The center of the circle
+ * @param[in] radius The radius of the circle
+ *
+ * @api
+ */
+ void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius);
+ #endif
+
+ #if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
+ /**
+ * @brief Draw an ellipse.
+ * @note Uses the current foreground color to draw the ellipse
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ *
+ * @api
+ */
+ void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b);
+
+ /**
+ * @brief Draw an filled ellipse.
+ * @note Uses the current foreground color to draw the filled ellipse
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ *
+ * @api
+ */
+ void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b);
+ #endif
+
+ #if GDISP_NEED_ARC || defined(__DOXYGEN__)
+ /*
+ * @brief Draw an arc in the window.
+ * @note Uses the current foreground color to draw the arc
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The center point
+ * @param[in] radius The radius of the arc
+ * @param[in] start The start angle (0 to 360)
+ * @param[in] end The end angle (0 to 360)
+ *
+ * @api
+ */
+ void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle);
+
+ /*
+ * @brief Draw a filled arc in the window.
+ * @note Uses the current foreground color to draw the filled arc
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The center point
+ * @param[in] radius The radius of the arc
+ * @param[in] start The start angle (0 to 360)
+ * @param[in] end The end angle (0 to 360)
+ *
+ * @api
+ */
+ void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle);
+ #endif
+
+/*-------------------------------------------------
+ * Pixel read-back functions
+ *-------------------------------------------------*/
+
+ #if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__)
+ /**
+ * @brief Get the color of a pixel in the window.
+ * @return The color of the pixel.
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position in the window
+ *
+ * @api
+ */
+ color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y);
+ #endif
+
+/*-------------------------------------------------
+ * Text functions
+ *-------------------------------------------------*/
+
+ #if GDISP_NEED_TEXT || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a text character at the specified position in the window.
+ * @pre The font must have been set.
+ * @note Uses the current foreground color to draw the character
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position for the text
+ * @param[in] c The character to draw
+ *
+ * @api
+ */
+ void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c);
+
+ /**
+ * @brief Draw a text character with a filled background at the specified position in the window.
+ * @pre The font must have been set.
+ * @note Uses the current foreground color to draw the character and fills the background using the background drawing color
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position for the text
+ * @param[in] c The character to draw
+ *
+ * @api
+ */
+ void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c);
+
+ /**
+ * @brief Draw a text string in the window
+ * @pre The font must have been set.
+ * @note Uses the current foreground color to draw the character
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position for the text
+ * @param[in] str The string to draw
+ *
+ * @api
+ */
+ void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str);
+
+ /**
+ * @brief Draw a text string with a filled background in the window
+ * @pre The font must have been set.
+ * @note Uses the current foreground color to draw the character and fills the background using the background drawing color
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position for the text
+ * @param[in] str The string to draw
+ *
+ * @api
+ */
+ void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str);
+
+ /**
+ * @brief Draw a text string verticly centered within the specified box.
+ * @pre The font must have been set.
+ * @note Uses the current foreground color to draw the character.
+ * @note The specified box does not need to align with the window box
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position for the text (need to define top-right or base-line - check code)
+ * @param[in] cx,cy The width and height of the box
+ * @param[in] str The string to draw
+ * @param[in] justify Justify the text left, center or right within the box
+ *
+ * @api
+ */
+ void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
+
+ /**
+ * @brief Draw a text string verticly centered within the specified filled box.
+ * @pre The font must have been set.
+ * @note Uses the current foreground color to draw the character and fills the background using the background drawing color
+ * @note The entire box is filled. Note this box does not need to align with the window box
+ * @note May leave GDISP clipping to this window's dimensions
+ *
+ * @param[in] gh The window handle
+ * @param[in] x,y The position for the text (need to define top-right or base-line - check code)
+ * @param[in] cx,cy The width and height of the box
+ * @param[in] str The string to draw
+ * @param[in] justify Justify the text left, center or right within the box
+ *
+ * @api
+ */
+ void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
+ #endif
+
+/*-------------------------------------------------
+ * Polygon functions
+ *-------------------------------------------------*/
+
+ #if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
+ /**
+ * @brief Draw an enclosed polygon (convex, non-convex or complex).
+ *
+ * @note Uses the current foreground color.
+ *
+ * @param[in] gh The window handle
+ * @param[in] tx, ty Transform all points in pntarray by tx, ty
+ * @param[in] pntarray An array of points
+ * @param[in] cnt The number of points in the array
+ *
+ * @api
+ */
+ void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
+
+ /**
+ * @brief Fill a convex polygon
+ * @details Doesn't handle non-convex or complex polygons.
+ *
+ * @note Uses the current foreground color.
+ *
+ * @param[in] gh The window handle
+ * @param[in] tx, ty Transform all points in pntarray by tx, ty
+ * @param[in] pntarray An array of points
+ * @param[in] cnt The number of points in the array
+ *
+ * @note Convex polygons are those that have no internal angles. That is;
+ * you can draw a line from any point on the polygon to any other point
+ * on the polygon without it going outside the polygon. In our case we generalise
+ * this a little by saying that an infinite horizontal line (at any y value) will cross
+ * no more than two edges on the polygon. Some non-convex polygons do fit this criteria
+ * and can therefore be drawn.
+ * @note This routine is designed to be very efficient with even simple display hardware.
+ *
+ * @api
+ */
+ void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
+ #endif
+
+/*-------------------------------------------------
+ * Image functions
+ *-------------------------------------------------*/
+
+ #if GDISP_NEED_IMAGE || defined(__DOXYGEN__)
+ /**
+ * @brief Draw the image
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] gh The window handle
+ * @param[in] img The image structure
+ * @param[in] x,y The window location to draw the image
+ * @param[in] cx,cy The area on the screen to draw
+ * @param[in] sx,sy The image position to start drawing at
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image
+ * is simply not drawn.
+ * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a
+ * fast blit from the cached frame. If not, it reads the input and decodes it as it
+ * is drawing. This may be significantly slower than if the image has been cached (but
+ * uses a lot less RAM)
+ *
+ * @api
+ */
+ gdispImageError gwinDrawImage(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ #endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*-------------------------------------------------
+ * Additional functionality
+ *-------------------------------------------------*/
+
+ /* Include widgets */
+ #if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
+ #include "src/gwin/gwidget.h"
+ #endif
+
+ /* Include extra window types */
+ #if GWIN_NEED_CONSOLE || defined(__DOXYGEN__)
+ #include "src/gwin/console.h"
+ #endif
+
+ #if GWIN_NEED_GRAPH || defined(__DOXYGEN__)
+ #include "src/gwin/graph.h"
+ #endif
+
+ #if GWIN_NEED_IMAGE || defined(__DOXYGEN__)
+ #include "src/gwin/image.h"
+ #endif
+
+#endif /* GFX_USE_GWIN */
+
+#endif /* _GWIN_H */
+/** @} */
diff --git a/src/gwin/gwin.mk b/src/gwin/sys_make.mk
index 4c670ea2..4c670ea2 100644
--- a/src/gwin/gwin.mk
+++ b/src/gwin/sys_make.mk
diff --git a/src/gwin/sys_options.h b/src/gwin/sys_options.h
new file mode 100644
index 00000000..02467916
--- /dev/null
+++ b/src/gwin/sys_options.h
@@ -0,0 +1,185 @@
+/*
+ * 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
+ */
+
+/**
+ * @file include/gwin/sys_options.h
+ * @brief GWIN sub-system options header file.
+ *
+ * @addtogroup GWIN
+ * @brief Module which provides a complete GUI toolkit based on widgets
+ *
+ * @{
+ */
+
+#ifndef _GWIN_OPTIONS_H
+#define _GWIN_OPTIONS_H
+
+/**
+ * @name GWIN Functionality to be included
+ * @{
+ */
+ /**
+ * @brief Should window manager support be included
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_WINDOWMANAGER
+ #define GWIN_NEED_WIDGET FALSE
+ #endif
+ /**
+ * @brief Should widget functions be included. Needed for any widget (eg Buttons, Sliders etc)
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_WIDGET
+ #define GWIN_NEED_WIDGET FALSE
+ #endif
+ /**
+ * @brief Should console functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_CONSOLE
+ #define GWIN_NEED_CONSOLE FALSE
+ #endif
+ /**
+ * @brief Should graph functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_GRAPH
+ #define GWIN_NEED_GRAPH FALSE
+ #endif
+ /**
+ * @brief Should button functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_BUTTON
+ #define GWIN_NEED_BUTTON FALSE
+ #endif
+ /**
+ * @brief Should slider functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_SLIDER
+ #define GWIN_NEED_SLIDER FALSE
+ #endif
+ /**
+ * @brief Should checkbox functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_CHECKBOX
+ #define GWIN_NEED_CHECKBOX FALSE
+ #endif
+ /**
+ * @brief Should image functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_IMAGE
+ #define GWIN_NEED_IMAGE FALSE
+ #endif
+ /**
+ * @brief Should label functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_LABEL
+ #define GWIN_NEED_LABEL FALSE
+ #endif
+ /**
+ * @brief Should radio button functions be included.
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_RADIO
+ #define GWIN_NEED_RADIO FALSE
+ #endif
+/**
+ * @}
+ *
+ * @name GWIN Optional Parameters
+ * @{
+ */
+ /**
+ * @brief Buttons should not insist the mouse is over the button on mouse release
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_BUTTON_LAZY_RELEASE
+ #define GWIN_BUTTON_LAZY_RELEASE FALSE
+ #endif
+ /**
+ * @brief Should the content of the console be saved for redrawing.
+ * @details Defaults to FALSE
+ * @details If this feature is enabled, the contents of the console will be saved
+ * as it is written. If a redraw is required it will be redrawn from the
+ * history. Scrolling will also use the history buffer if it is turned on.
+ * @note Using this option allocates the amount of memory to store the
+ * history based on the minimum character width in the current font
+ * at the time the history is turned on. Using a fixed width font is a good
+ * idea to minimize memory usage.
+ * @note If you change the size of the window or you change the font being displayed
+ * you should turn off the history and then turn it back on in order to get
+ * a new buffer of the correct size for the window/font combination. Strange
+ * redrawing and scrolling effects can occur if the buffer is too small to
+ * save a complete screen of data. Note the system tries to optimize storage
+ * so this may only be evident in very limited situations eg with a console
+ * with many characters in it.
+ * @note @p gwinConsoleSetBuffer() can be used to turn the history buffer off and on.
+ */
+ #ifndef GWIN_CONSOLE_USE_HISTORY
+ #define GWIN_CONSOLE_USE_HISTORY FALSE
+ #endif
+ /**
+ * @brief Use font width averaging for the history buffer allocation.
+ * @details Defaults to FALSE
+ * @details If this feature is enabled, the width one third of the way between
+ * the font's character width minimum and maximum will be used instead
+ * of the font's minimum width.
+ * @note This option reduces the memory allocation for a variable width font's
+ * history buffer. Note that strange
+ * redrawing and scrolling effects can occur if the buffer is too small to
+ * save a complete screen of data. The system tries to optimize storage
+ * so this may only be evident in very limited situations eg with a console
+ * with many characters in it.
+ */
+ #ifndef GWIN_CONSOLE_HISTORY_AVERAGING
+ #define GWIN_CONSOLE_HISTORY_AVERAGING FALSE
+ #endif
+ /**
+ * @brief Should the history be turned on for all console windows when they are first created.
+ * @details Defaults to FALSE
+ * @note @p gwinConsoleSetBuffer() can be used to turn the history buffer off and on at
+ * any time.
+ */
+ #ifndef GWIN_CONSOLE_HISTORY_ATCREATE
+ #define GWIN_CONSOLE_HISTORY_ATCREATE FALSE
+ #endif
+ /**
+ * @brief Console Windows need floating point support in @p gwinPrintf
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_CONSOLE_USE_FLOAT
+ #define GWIN_CONSOLE_USE_FLOAT FALSE
+ #endif
+ /**
+ * @brief Console Windows need BaseStreamSequential support (ChibiOS only)
+ * @details Defaults to FALSE
+ * @note To use the ChibiOS basestream functions such as chprintf()
+ * for printing in a console window you need to set this option to
+ * TRUE in your gfxconf.h and include in your application source file...
+ * \#include "chprintf.h"
+ * In your makefile, as part of your list of C source files, include
+ * ${CHIBIOS}/os/various/chprintf.c
+ */
+ #ifndef GWIN_CONSOLE_USE_BASESTREAM
+ #define GWIN_CONSOLE_USE_BASESTREAM FALSE
+ #endif
+ /**
+ * @brief Image windows can optionally support animated images
+ * @details Defaults to FALSE
+ */
+ #ifndef GWIN_NEED_IMAGE_ANIMATION
+ #define GWIN_NEED_IMAGE_ANIMATION FALSE
+ #endif
+/** @} */
+
+#endif /* _GWIN_OPTIONS_H */
+/** @} */
diff --git a/src/gwin/sys_rules.h b/src/gwin/sys_rules.h
new file mode 100644
index 00000000..77f029f0
--- /dev/null
+++ b/src/gwin/sys_rules.h
@@ -0,0 +1,99 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gwin/sys_rules.h
+ * @brief GWIN safety rules header file.
+ *
+ * @addtogroup GWIN
+ * @{
+ */
+
+#ifndef _GWIN_RULES_H
+#define _GWIN_RULES_H
+
+#if GFX_USE_GWIN
+ #if !GFX_USE_GDISP
+ #error "GWIN: GFX_USE_GDISP must be TRUE when using GWIN"
+ #endif
+ #if !GDISP_NEED_CLIP
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GWIN: Drawing can occur outside the defined windows as GDISP_NEED_CLIP is FALSE"
+ #endif
+ #endif
+ #if GWIN_NEED_IMAGE
+ #if !GDISP_NEED_IMAGE
+ #error "GWIN: GDISP_NEED_IMAGE is required when GWIN_NEED_IMAGE is TRUE."
+ #endif
+ #endif
+ #if GWIN_NEED_RADIO
+ #if !GDISP_NEED_CIRCLE
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GWIN: GDISP_NEED_CIRCLE should be set to TRUE for much nicer radio button widgets."
+ #endif
+ #endif
+ #endif
+ #if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX || GWIN_NEED_LABEL || GWIN_NEED_RADIO || GWIN_NEED_LIST || \
+ GWIN_NEED_IMAGE || GWIN_NEED_CHECKBOX || GWIN_NEED_PROGRESSBAR
+ #if !GWIN_NEED_WIDGET
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GWIN: GWIN_NEED_WIDGET is required when a Widget is used. It has been turned on for you."
+ #endif
+ #undef GWIN_NEED_WIDGET
+ #define GWIN_NEED_WIDGET TRUE
+ #endif
+ #endif
+ #if GWIN_NEED_LIST
+ #if !GDISP_NEED_TEXT
+ #error "GWIN: GDISP_NEED_TEXT is required when GWIN_NEED_LIST is TRUE."
+ #endif
+ #endif
+ #if GWIN_NEED_WIDGET
+ #if !GDISP_NEED_TEXT
+ #error "GWIN: GDISP_NEED_TEXT is required if GWIN_NEED_WIDGET is TRUE."
+ #endif
+ #if !GFX_USE_GINPUT
+ // This test also ensures that GFX_USE_GEVENT is set
+ #error "GWIN: GFX_USE_GINPUT (and one or more input sources) is required if GWIN_NEED_WIDGET is TRUE"
+ #endif
+ #if !GWIN_NEED_WINDOWMANAGER
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GWIN: GWIN_NEED_WINDOWMANAGER is required if GWIN_NEED_WIDGET is TRUE. It has been turned on for you."
+ #endif
+ #undef GWIN_NEED_WINDOWMANAGER
+ #define GWIN_NEED_WINDOWMANAGER TRUE
+ #endif
+ #if !GDISP_NEED_MULTITHREAD
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GWIN: GDISP_NEED_MULTITHREAD is required if GWIN_NEED_WIDGET is TRUE. It has been turned on for you"
+ #endif
+ #undef GDISP_NEED_MULTITHREAD
+ #define GDISP_NEED_MULTITHREAD TRUE
+ #endif
+ #endif
+ #if GWIN_NEED_WINDOWMANAGER
+ #if !GFX_USE_GQUEUE || !GQUEUE_NEED_ASYNC
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GWIN: GFX_USE_GQUEUE and GQUEUE_NEED_ASYNC is required if GWIN_NEED_WINDOWMANAGER is TRUE. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GQUEUE
+ #undef GQUEUE_NEED_ASYNC
+ #define GFX_USE_GQUEUE TRUE
+ #define GQUEUE_NEED_ASYNC TRUE
+ #endif
+ #endif
+ #if GWIN_NEED_CONSOLE
+ #if !GDISP_NEED_TEXT
+ #error "GWIN: GDISP_NEED_TEXT is required if GWIN_NEED_CONSOLE is TRUE."
+ #endif
+ #endif
+ #if GWIN_NEED_GRAPH
+ #endif
+#endif
+
+#endif /* _GWIN_RULES_H */
+/** @} */