aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJoel Bodenmann <joel@unormal.org>2013-11-10 21:07:16 +0100
committerJoel Bodenmann <joel@unormal.org>2013-11-10 21:07:16 +0100
commitda2740b706d720292113445ee1db30f8a9873dc4 (patch)
tree8f8b1902d4af6a23b3daf26990f580b76ea31ea4 /include
parent6ca3537a696e7ace8098771a9a7105380604253d (diff)
parenta8ce005e2621b0108863297948cea0fa52c8bf2a (diff)
downloaduGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.gz
uGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.bz2
uGFX-da2740b706d720292113445ee1db30f8a9873dc4.zip
merging GDISPStreaming
Diffstat (limited to 'include')
-rw-r--r--include/gdisp/colors.h377
-rw-r--r--include/gdisp/gdisp.h941
-rw-r--r--include/gdisp/image.h14
-rw-r--r--include/gdisp/lld/emulation.c558
-rw-r--r--include/gdisp/lld/gdisp_lld.h933
-rw-r--r--include/gdisp/lld/gdisp_lld_msgs.h181
-rw-r--r--include/gdisp/options.h201
-rw-r--r--include/gfx_rules.h51
-rw-r--r--include/ginput/mouse.h29
-rw-r--r--include/gmisc/gmisc.h18
-rw-r--r--include/gmisc/options.h39
-rw-r--r--include/gwin/button.h4
-rw-r--r--include/gwin/checkbox.h4
-rw-r--r--include/gwin/class_gwin.h6
-rw-r--r--include/gwin/console.h4
-rw-r--r--include/gwin/graph.h4
-rw-r--r--include/gwin/gwin.h5
-rw-r--r--include/gwin/image.h4
-rw-r--r--include/gwin/label.h14
-rw-r--r--include/gwin/list.h16
-rw-r--r--include/gwin/radio.h4
-rw-r--r--include/gwin/slider.h4
22 files changed, 1941 insertions, 1470 deletions
diff --git a/include/gdisp/colors.h b/include/gdisp/colors.h
new file mode 100644
index 00000000..efd7076c
--- /dev/null
+++ b/include/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/include/gdisp/gdisp.h b/include/gdisp/gdisp.h
index b82c9f3c..51415805 100644
--- a/include/gdisp/gdisp.h
+++ b/include/gdisp/gdisp.h
@@ -17,6 +17,10 @@
*
* @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.
* @{
*/
@@ -43,53 +47,56 @@ typedef int16_t coord_t;
/**
* @brief Type for a 2D point on the screen.
*/
-typedef struct point_t {
- coord_t x, y;
- } point;
+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;
+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;
+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, GDISP_ROTATE_90, GDISP_ROTATE_180, GDISP_ROTATE_270} gdisp_orientation_t;
+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} gdisp_powermode_t;
+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 GDISPDriver_t {
+typedef struct GDISPControl {
coord_t Width;
coord_t Height;
- gdisp_orientation_t Orientation;
- gdisp_powermode_t Powermode;
+ orientation_t Orientation;
+ powermode_t Powermode;
uint8_t Backlight;
uint8_t Contrast;
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- coord_t clipx0, clipy0;
- coord_t clipx1, clipy1; /* not inclusive */
- #endif
- } GDISPDriver;
+ } GDISPControl;
-extern GDISPDriver GDISP;
+/*
+ * 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. */
@@ -115,475 +122,476 @@ extern GDISPDriver GDISP;
#define GDISP_CONTROL_CONTRAST 3
#define GDISP_CONTROL_LLD 1000
-/**
- * @brief Driver Query Constants
- * @details Unsupported query codes return (void *)-1.
- * @note The result should be typecast the required type.
- * @note GDISP_QUERY_LLD - Low level driver control constants start at
- * this value.
- */
-#define GDISP_QUERY_LLD 1000
+/*===========================================================================*/
+/* Defines relating to the display hardware */
+/*===========================================================================*/
-/**
- * @brief Driver Pixel Format Constants
- */
-#define GDISP_PIXELFORMAT_MONO 1
-#define GDISP_PIXELFORMAT_RGB565 565
-#define GDISP_PIXELFORMAT_RGB888 888
-#define GDISP_PIXELFORMAT_RGB444 444
-#define GDISP_PIXELFORMAT_RGB332 332
-#define GDISP_PIXELFORMAT_RGB666 666
-#define GDISP_PIXELFORMAT_CUSTOM 99999
-#define GDISP_PIXELFORMAT_ERROR 88888
+#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 Some basic colors
+ * @name GDISP pixel format choices
* @{
*/
-#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)
+ /**
+ * @brief The pixel format.
+ * @default 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 */
/*===========================================================================*/
-#if defined(__DOXYGEN__)
- /**
- * @brief The color of a pixel.
- */
- typedef uint16_t color_t;
- /**
- * @brief Convert a number (of any type) to a color_t.
- * @details Masks any invalid bits in the color
- */
- #define COLOR(c) ((color_t)(c))
- /**
- * @brief Does the color_t type contain invalid bits that need masking.
- */
- #define MASKCOLOR FALSE
- /**
- * @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 red component (0 to 255) of a color value.
- */
- #define RED_OF(c) (((c) & 0xF800)>>8)
- /**
- * @brief Extract the green component (0 to 255) of a color value.
- */
- #define GREEN_OF(c) (((c)&0x007E)>>3)
- /**
- * @brief Extract the blue component (0 to 255) of a color value.
- */
- #define BLUE_OF(c) (((c)&0x001F)<<3)
+/* Load our color definitions and pixel formats */
+#include "colors.h"
+
+/**
+ * @brief The type of a pixel.
+ */
+typedef color_t pixel_t;
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_MONO
- typedef uint8_t color_t;
- #define COLOR(c) ((color_t)(c))
- #define MASKCOLOR FALSE
- #define RGB2COLOR(r,g,b) ((r|g|b) ? 1 : 0)
- #define HTML2COLOR(h) (h ? 1 : 0)
- #define RED_OF(c) (c ? 255 : 0)
- #define GREEN_OF(c) (c ? 255 : 0)
- #define BLUE_OF(c) (c ? 255 : 0)
+#ifdef __cplusplus
+extern "C" {
+#endif
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565
- typedef uint16_t color_t;
- #define COLOR(c) ((color_t)(c))
- #define MASKCOLOR FALSE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
- #define RED_OF(c) (((c) & 0xF800)>>8)
- #define GREEN_OF(c) (((c)&0x07E0)>>3)
- #define BLUE_OF(c) (((c)&0x001F)<<3)
+/* Base Functions */
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888
- typedef uint32_t color_t;
- #define COLOR(c) ((color_t)(((c) & 0xFFFFFF)))
- #define MASKCOLOR TRUE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xFF)<<16) | (((g) & 0xFF) << 8) | ((b) & 0xFF)))
- #define HTML2COLOR(h) ((color_t)(h))
- #define RED_OF(c) (((c) & 0xFF0000)>>16)
- #define GREEN_OF(c) (((c)&0x00FF00)>>8)
- #define BLUE_OF(c) ((c)&0x0000FF)
+/**
+ * @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);
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB444
- typedef uint16_t color_t;
- #define COLOR(c) ((color_t)(((c) & 0x0FFF)))
- #define MASKCOLOR TRUE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF0)<<4) | ((g) & 0xF0) | (((b) & 0xF0)>>4)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xF00000)>>12) | (((h) & 0x00F000)>>8) | (((h) & 0x0000F0)>>4)))
- #define RED_OF(c) (((c) & 0x0F00)>>4)
- #define GREEN_OF(c) ((c)&0x00F0)
- #define BLUE_OF(c) (((c)&0x000F)<<4)
+/**
+ * @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);
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB332
- typedef uint8_t color_t;
- #define COLOR(c) ((color_t)(c))
- #define MASKCOLOR FALSE
- #define RGB2COLOR(r,g,b) ((color_t)(((r) & 0xE0) | (((g) & 0xE0)>>3) | (((b) & 0xC0)>>6)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xE00000)>>16) | (((h) & 0x00E000)>>11) | (((h) & 0x0000C0)>>6)))
- #define RED_OF(c) ((c) & 0xE0)
- #define GREEN_OF(c) (((c)&0x1C)<<3)
- #define BLUE_OF(c) (((c)&0x03)<<6)
+/**
+ * @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] display The display number (0..n)
+ *
+ * @api
+ */
+void gdispSetDisplay(GDisplay *g);
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB666
- typedef uint32_t color_t;
- #define COLOR(c) ((color_t)(((c) & 0x03FFFF)))
- #define MASKCOLOR TRUE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xFC)<<10) | (((g) & 0xFC)<<4) | (((b) & 0xFC)>>2)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xFC0000)>>6) | (((h) & 0x00FC00)>>4) | (((h) & 0x0000FC)>>2)))
- #define RED_OF(c) (((c) & 0x03F000)>>12)
- #define GREEN_OF(c) (((c)&0x00FC00)>>8)
- #define BLUE_OF(c) (((c)&0x00003F)<<2)
+/* Drawing Functions */
-#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
- #error "GDISP: No supported pixel format has been specified."
-#endif
+/**
+ * @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] display The display number (0..n)
+ *
+ * @api
+ */
+void gdispGFlush(GDisplay *g);
+#define gdispFlush() gdispGFlush(GDISP)
-/* 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
+/**
+ * @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)
-#if GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL
- #error "GDISP: Hardware scrolling is wanted but not supported."
-#endif
+/**
+ * @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)
-#if GDISP_NEED_PIXELREAD && !GDISP_HARDWARE_PIXELREAD
- #error "GDISP: Pixel read-back is wanted but not supported."
-#endif
+/**
+ * @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 The type of a pixel.
+ * @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
*/
-typedef color_t pixel_t;
+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)
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * @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)
-#if GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC || defined(__DOXYGEN__)
- /* These routines can be hardware accelerated
- * - Do not add a routine here unless it has also been added to the hardware acceleration layer
+/**
+ * @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)
- /* Base Functions */
+ /**
+ * @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 Test if the GDISP engine is currently drawing.
- * @note This function will always return FALSE if
- * GDISP_NEED_ASYNC is not defined.
+ * @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.
*
- * @return TRUE if gdisp is busy, FALSE otherwise
+ * @param[in] g The display to use
*
* @api
*/
- bool_t gdispIsBusy(void);
+ void gdispGStreamStop(GDisplay *g);
+ #define gdispStreamStop() gdispGStreamStop(GDISP)
+#endif
- /* Drawing Functions */
+/* Clipping Functions */
+#if GDISP_NEED_CLIP || defined(__DOXYGEN__)
/**
- * @brief Clear the display to the specified color.
+ * @brief Clip all drawing to the defined area.
*
- * @param[in] color The color to use when clearing the screen
+ * @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 gdispClear(color_t color);
+ 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 Set a pixel in the specified color.
+ * @brief Draw a circle.
*
- * @param[in] x,y The position to set the pixel.
- * @param[in] color The color to use
+ * @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 gdispDrawPixel(coord_t x, coord_t y, color_t color);
+ 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 line.
+ * @brief Draw a filled circle.
*
- * @param[in] x0,y0 The start position
- * @param[in] x1,y1 The end position
+ * @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 gdispDrawLine(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+ 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 Fill an area with a color.
+ * @brief Draw an ellipse.
*
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the box (outside dimensions)
+ * @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 gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+ 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 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.
+ * @brief Draw a filled ellipse.
*
- * @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
+ * @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 gdispBlitAreaEx(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);
-
- /* Clipping Functions */
+ 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
- #if GDISP_NEED_CLIP || defined(__DOXYGEN__)
- /**
- * @brief Clip all drawing to the defined area.
- *
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the clip area
- *
- * @api
- */
- void gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy);
- #endif
+/* Arc Functions */
- /* Circle Functions */
-
- #if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
- /**
- * @brief Draw a circle.
- *
- * @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 gdispDrawCircle(coord_t x, coord_t y, coord_t radius, color_t color);
-
- /**
- * @brief Draw a filled circle.
- *
- * @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 gdispFillCircle(coord_t x, coord_t y, coord_t radius, color_t color);
- #endif
-
- /* Ellipse Functions */
-
- #if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
- /**
- * @brief Draw an ellipse.
- *
- * @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 gdispDrawEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
-
- /**
- * @brief Draw a filled ellipse.
- *
- * @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 gdispFillEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
- #endif
+#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)
- /* Arc Functions */
-
- #if GDISP_NEED_ARC || defined(__DOXYGEN__)
- /*
- * @brief Draw an arc.
- *
- * @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 gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
-
- /*
- * @brief Draw a filled arc.
- * @note Not very efficient currently - does lots of overdrawing
- *
- * @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 gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
- #endif
+ /*
+ * @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] x,y The position of the pixel
- *
- * @api
- */
- color_t gdispGetPixelColor(coord_t x, coord_t y);
- #endif
+/* Read a pixel Function */
- /* 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] 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 gdispVerticalScroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
- #endif
+#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
- /* 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] what what you want to control
- * @param[in] value The value to be assigned
- *
- * @api
- */
- void gdispControl(unsigned what, void *value);
- #endif
+/* Scrolling Function - clears the area scrolled out */
- /* 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] what What to query
- *
- * @api
- */
- void *gdispQuery(unsigned what);
- #endif
+#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
-#else
- /* Include the low level driver information */
- #include "gdisp/lld/gdisp_lld.h"
-
- /* The same as above but use the low level driver directly if no multi-thread support is needed */
- #define gdispIsBusy() FALSE
- #define gdispClear(color) gdisp_lld_clear(color)
- #define gdispDrawPixel(x, y, color) gdisp_lld_draw_pixel(x, y, color)
- #define gdispDrawLine(x0, y0, x1, y1, color) gdisp_lld_draw_line(x0, y0, x1, y1, color)
- #define gdispFillArea(x, y, cx, cy, color) gdisp_lld_fill_area(x, y, cx, cy, color)
- #define gdispBlitAreaEx(x, y, cx, cy, sx, sy, scx, buf) gdisp_lld_blit_area_ex(x, y, cx, cy, sx, sy, scx, buf)
- #define gdispSetClip(x, y, cx, cy) gdisp_lld_set_clip(x, y, cx, cy)
- #define gdispDrawCircle(x, y, radius, color) gdisp_lld_draw_circle(x, y, radius, color)
- #define gdispFillCircle(x, y, radius, color) gdisp_lld_fill_circle(x, y, radius, color)
- #define gdispDrawArc(x, y, radius, sangle, eangle, color) gdisp_lld_draw_arc(x, y, radius, sangle, eangle, color)
- #define gdispFillArc(x, y, radius, sangle, eangle, color) gdisp_lld_fill_arc(x, y, radius, sangle, eangle, color)
- #define gdispDrawEllipse(x, y, a, b, color) gdisp_lld_draw_ellipse(x, y, a, b, color)
- #define gdispFillEllipse(x, y, a, b, color) gdisp_lld_fill_ellipse(x, y, a, b, color)
- #define gdispGetPixelColor(x, y) gdisp_lld_get_pixel_color(x, y)
- #define gdispVerticalScroll(x, y, cx, cy, lines, bgcolor) gdisp_lld_vertical_scroll(x, y, cx, cy, lines, bgcolor)
- #define gdispControl(what, value) gdisp_lld_control(what, value)
- #define gdispQuery(what) gdisp_lld_query(what)
+/* 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
-/* These routines are not hardware accelerated
- * - Do not add a hardware accelerated routines here.
- */
+/* Query driver specific data */
-/* Extra drawing functions */
-
-/**
- * @brief Draw a rectangular box.
- *
- * @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 gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#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
@@ -591,12 +599,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ 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
@@ -612,7 +622,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ 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)
#endif
/* Text Functions */
@@ -621,6 +632,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @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
@@ -628,11 +640,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
+ 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
@@ -641,11 +655,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ 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] font The font to use
* @param[in] str The string to draw
@@ -653,11 +669,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color);
+ 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
@@ -666,11 +684,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
+ 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
@@ -680,12 +700,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
+ 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
@@ -696,7 +718,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillStringBox(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);
+ 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.
@@ -781,6 +804,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @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
@@ -788,11 +812,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ 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
@@ -800,37 +826,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
-#endif
-
-
-/**
- * @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);
-
-/* 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);
+ 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
/*
@@ -838,7 +835,7 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
*/
/* Now obsolete functions */
-#define gdispBlitArea(x, y, cx, cy, buffer) gdispBlitAreaEx(x, y, cx, cy, 0, 0, cx, buffer)
+#define gdispBlitArea(x, y, cx, cy, buffer) gdispGBlitArea(GDISP, x, y, cx, cy, 0, 0, cx, buffer)
/* Macro definitions for common gets and sets */
@@ -846,26 +843,31 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
* @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 gdispSetPowerMode(powerMode) gdispControl(GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+#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 gdispSetOrientation(newOrientation) gdispControl(GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+#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,
@@ -873,69 +875,92 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
*
* @api
*/
-#define gdispSetBacklight(percent) gdispControl(GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+#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 gdispSetContrast(percent) gdispControl(GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+#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 gdispGetWidth() (GDISP.Width)
+#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 gdispGetHeight() (GDISP.Height)
+#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 gdispGetPowerMode() (GDISP.Powermode)
+#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 gdispGetOrientation() (GDISP.Orientation)
+#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 gdispGetBacklight() (GDISP.Backlight)
+#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 gdispGetContrast() (GDISP.Contrast)
+#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 gdispUnsetClip() gdispSetClip(0,0,gdispGetWidth(),gdispGetHeight())
-
+#define gdispGUnsetClip(g) gdispGSetClip((g),0,0,gdispGGetWidth(g),gdispGGetHeight(g))
+#define gdispUnsetClip() gdispGUnsetClip(GDISP)
#ifdef __cplusplus
}
diff --git a/include/gdisp/image.h b/include/gdisp/image.h
index 8619cb9c..ff2e9d85 100644
--- a/include/gdisp/image.h
+++ b/include/gdisp/image.h
@@ -243,6 +243,7 @@ extern "C" {
* @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
@@ -257,7 +258,8 @@ extern "C" {
* is drawing. This may be significantly slower than if the image has been cached (but
* uses a lot less RAM)
*/
- gdispImageError gdispImageDraw(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ 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.
@@ -299,7 +301,7 @@ extern "C" {
gdispImageError gdispImageOpen_NATIVE(gdispImage *img);
void gdispImageClose_NATIVE(gdispImage *img);
gdispImageError gdispImageCache_NATIVE(gdispImage *img);
- gdispImageError gdispImageDraw_NATIVE(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_NATIVE(gdispImage *img);
/* @} */
#endif
@@ -315,7 +317,7 @@ extern "C" {
gdispImageError gdispImageOpen_GIF(gdispImage *img);
void gdispImageClose_GIF(gdispImage *img);
gdispImageError gdispImageCache_GIF(gdispImage *img);
- gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_GIF(gdispImage *img);
/* @} */
#endif
@@ -331,7 +333,7 @@ extern "C" {
gdispImageError gdispImageOpen_BMP(gdispImage *img);
void gdispImageClose_BMP(gdispImage *img);
gdispImageError gdispImageCache_BMP(gdispImage *img);
- gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_BMP(gdispImage *img);
/* @} */
#endif
@@ -347,7 +349,7 @@ extern "C" {
gdispImageError gdispImageOpen_JPG(gdispImage *img);
void gdispImageClose_JPG(gdispImage *img);
gdispImageError gdispImageCache_JPG(gdispImage *img);
- gdispImageError gdispImageDraw_JPG(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_JPG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_JPG(gdispImage *img);
/* @} */
#endif
@@ -363,7 +365,7 @@ extern "C" {
gdispImageError gdispImageOpen_PNG(gdispImage *img);
void gdispImageClose_PNG(gdispImage *img);
gdispImageError gdispImageCache_PNG(gdispImage *img);
- gdispImageError gdispImageDraw_PNG(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_PNG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_PNG(gdispImage *img);
/* @} */
#endif
diff --git a/include/gdisp/lld/emulation.c b/include/gdisp/lld/emulation.c
deleted file mode 100644
index cb0c9c4b..00000000
--- a/include/gdisp/lld/emulation.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * 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/lld/emulation.c
- * @brief GDISP emulation routines for stuff the driver dosen't support
- *
- * @addtogroup GDISP
- *
- * @details Even though this is a software emulation of a low level driver
- * most validation doesn't need to happen here as eventually
- * we call a real low level driver routine and if validation is
- * required - it will do it.
- *
- * @{
- */
-#ifndef GDISP_EMULATION_C
-#define GDISP_EMULATION_C
-
-#if GFX_USE_GDISP
-
-/* Include the low level driver information */
-#include "gdisp/lld/gdisp_lld.h"
-
-/* Declare the GDISP structure */
-GDISPDriver GDISP;
-
-#if !GDISP_HARDWARE_CLEARS
- void gdisp_lld_clear(color_t color) {
- gdisp_lld_fill_area(0, 0, GDISP.Width, GDISP.Height, color);
- }
-#endif
-
-#if !GDISP_HARDWARE_LINES
- void gdisp_lld_draw_line(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
- int16_t dy, dx;
- int16_t addx, addy;
- int16_t P, diff, i;
-
- #if GDISP_HARDWARE_FILLS || GDISP_HARDWARE_SCROLL
- // speed improvement if vertical or horizontal
- if (x0 == x1) {
- if (y1 > y0)
- gdisp_lld_fill_area(x0, y0, 1, y1-y0+1, color);
- else
- gdisp_lld_fill_area(x0, y1, 1, y0-y1+1, color);
- return;
- }
- if (y0 == y1) {
- if (x1 > x0)
- gdisp_lld_fill_area(x0, y0, x1-x0+1, 1, color);
- else
- gdisp_lld_fill_area(x1, y0, x0-x1+1, 1, color);
- return;
- }
- #endif
-
- if (x1 >= x0) {
- dx = x1 - x0;
- addx = 1;
- } else {
- dx = x0 - x1;
- addx = -1;
- }
- if (y1 >= y0) {
- dy = y1 - y0;
- addy = 1;
- } else {
- dy = y0 - y1;
- addy = -1;
- }
-
- if (dx >= dy) {
- dy *= 2;
- P = dy - dx;
- diff = P - dx;
-
- for(i=0; i<=dx; ++i) {
- gdisp_lld_draw_pixel(x0, y0, color);
- if (P < 0) {
- P += dy;
- x0 += addx;
- } else {
- P += diff;
- x0 += addx;
- y0 += addy;
- }
- }
- } else {
- dx *= 2;
- P = dx - dy;
- diff = P - dy;
-
- for(i=0; i<=dy; ++i) {
- gdisp_lld_draw_pixel(x0, y0, color);
- if (P < 0) {
- P += dx;
- y0 += addy;
- } else {
- P += diff;
- x0 += addx;
- y0 += addy;
- }
- }
- }
- }
-#endif
-
-#if !GDISP_HARDWARE_FILLS
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- #if GDISP_HARDWARE_SCROLL
- gdisp_lld_vertical_scroll(x, y, cx, cy, cy, color);
- #elif GDISP_HARDWARE_LINES
- coord_t x1, y1;
-
- x1 = x + cx - 1;
- y1 = y + cy;
- for(; y < y1; y++)
- gdisp_lld_draw_line(x, y, x1, y, color);
- #else
- coord_t x0, x1, y1;
-
- x0 = x;
- x1 = x + cx;
- y1 = y + cy;
- for(; y < y1; y++)
- for(x = x0; x < x1; x++)
- gdisp_lld_draw_pixel(x, y, color);
- #endif
- }
-#endif
-
-#if !GDISP_HARDWARE_BITFILLS
- void gdisp_lld_blit_area_ex(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) {
- coord_t x0, x1, y1;
-
- x0 = x;
- x1 = x + cx;
- y1 = y + cy;
- buffer += srcy*srccx+srcx;
- srccx -= cx;
- for(; y < y1; y++, buffer += srccx)
- for(x=x0; x < x1; x++)
- gdisp_lld_draw_pixel(x, y, *buffer++);
- }
-#endif
-
-#if GDISP_NEED_CLIP && !GDISP_HARDWARE_CLIP
- void gdisp_lld_set_clip(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- #if GDISP_NEED_VALIDATION
- if (x >= GDISP.Width || y >= GDISP.Height || cx < 0 || cy < 0)
- return;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x+cx > GDISP.Width) cx = GDISP.Width - x;
- if (y+cy > GDISP.Height) cy = GDISP.Height - y;
- #endif
- GDISP.clipx0 = x;
- GDISP.clipy0 = y;
- GDISP.clipx1 = x+cx;
- GDISP.clipy1 = y+cy;
- }
-#endif
-
-#if GDISP_NEED_CIRCLE && !GDISP_HARDWARE_CIRCLES
- void gdisp_lld_draw_circle(coord_t x, coord_t y, coord_t radius, color_t color) {
- coord_t a, b, P;
-
- a = 0;
- b = radius;
- P = 1 - radius;
-
- do {
- gdisp_lld_draw_pixel(x+a, y+b, color);
- gdisp_lld_draw_pixel(x+b, y+a, color);
- gdisp_lld_draw_pixel(x-a, y+b, color);
- gdisp_lld_draw_pixel(x-b, y+a, color);
- gdisp_lld_draw_pixel(x+b, y-a, color);
- gdisp_lld_draw_pixel(x+a, y-b, color);
- gdisp_lld_draw_pixel(x-a, y-b, color);
- gdisp_lld_draw_pixel(x-b, y-a, color);
- if (P < 0)
- P += 3 + 2*a++;
- else
- P += 5 + 2*(a++ - b--);
- } while(a <= b);
- }
-#endif
-
-#if GDISP_NEED_CIRCLE && !GDISP_HARDWARE_CIRCLEFILLS
- void gdisp_lld_fill_circle(coord_t x, coord_t y, coord_t radius, color_t color) {
- coord_t a, b, P;
-
- a = 0;
- b = radius;
- P = 1 - radius;
-
- do {
- gdisp_lld_draw_line(x-a, y+b, x+a, y+b, color);
- gdisp_lld_draw_line(x-a, y-b, x+a, y-b, color);
- gdisp_lld_draw_line(x-b, y+a, x+b, y+a, color);
- gdisp_lld_draw_line(x-b, y-a, x+b, y-a, color);
- if (P < 0)
- P += 3 + 2*a++;
- else
- P += 5 + 2*(a++ - b--);
- } while(a <= b);
- }
-#endif
-
-#if GDISP_NEED_ELLIPSE && !GDISP_HARDWARE_ELLIPSES
- void gdisp_lld_draw_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- int dx = 0, dy = b; /* im I. Quadranten von links oben nach rechts unten */
- long a2 = a*a, b2 = b*b;
- long err = b2-(2*b-1)*a2, e2; /* Fehler im 1. Schritt */
-
- do {
- gdisp_lld_draw_pixel(x+dx, y+dy, color); /* I. Quadrant */
- gdisp_lld_draw_pixel(x-dx, y+dy, color); /* II. Quadrant */
- gdisp_lld_draw_pixel(x-dx, y-dy, color); /* III. Quadrant */
- gdisp_lld_draw_pixel(x+dx, y-dy, color); /* IV. Quadrant */
-
- e2 = 2*err;
- if(e2 < (2*dx+1)*b2) {
- dx++;
- err += (2*dx+1)*b2;
- }
- if(e2 > -(2*dy-1)*a2) {
- dy--;
- err -= (2*dy-1)*a2;
- }
- } while(dy >= 0);
-
- while(dx++ < a) { /* fehlerhafter Abbruch bei flachen Ellipsen (b=1) */
- gdisp_lld_draw_pixel(x+dx, y, color); /* -> Spitze der Ellipse vollenden */
- gdisp_lld_draw_pixel(x-dx, y, color);
- }
- }
-#endif
-
-#if GDISP_NEED_ELLIPSE && !GDISP_HARDWARE_ELLIPSEFILLS
- void gdisp_lld_fill_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- int dx = 0, dy = b; /* im I. Quadranten von links oben nach rechts unten */
- long a2 = a*a, b2 = b*b;
- long err = b2-(2*b-1)*a2, e2; /* Fehler im 1. Schritt */
-
- do {
- gdisp_lld_draw_line(x-dx,y+dy,x+dx,y+dy, color);
- gdisp_lld_draw_line(x-dx,y-dy,x+dx,y-dy, color);
-
- e2 = 2*err;
- if(e2 < (2*dx+1)*b2) {
- dx++;
- err += (2*dx+1)*b2;
- }
- if(e2 > -(2*dy-1)*a2) {
- dy--;
- err -= (2*dy-1)*a2;
- }
- } while(dy >= 0);
-
- while(dx++ < a) { /* fehlerhafter Abbruch bei flachen Ellipsen (b=1) */
- gdisp_lld_draw_pixel(x+dx, y, color); /* -> Spitze der Ellipse vollenden */
- gdisp_lld_draw_pixel(x-dx, y, color);
- }
- }
-#endif
-
-#if GDISP_NEED_ARC && !GDISP_HARDWARE_ARCS
-
- #include <math.h>
-
- /*
- * @brief Internal helper function for gdispDrawArc()
- *
- * @note DO NOT USE DIRECTLY!
- *
- * @param[in] x, y The middle point of the arc
- * @param[in] start The start angle of the arc
- * @param[in] end The end angle of the arc
- * @param[in] radius The radius of the arc
- * @param[in] color The color in which the arc will be drawn
- *
- * @notapi
- */
- static void _draw_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
- if (/*start >= 0 && */start <= 180) {
- float x_maxI = x + radius*cos(start*M_PI/180);
- float x_minI;
-
- if (end > 180)
- x_minI = x - radius;
- else
- x_minI = x + radius*cos(end*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxI && x-a >= x_minI)
- gdisp_lld_draw_pixel(x-a, y-b, color);
- if(x+a <= x_maxI && x+a >= x_minI)
- gdisp_lld_draw_pixel(x+a, y-b, color);
- if(x-b <= x_maxI && x-b >= x_minI)
- gdisp_lld_draw_pixel(x-b, y-a, color);
- if(x+b <= x_maxI && x+b >= x_minI)
- gdisp_lld_draw_pixel(x+b, y-a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while(a <= b);
- }
-
- if (end > 180 && end <= 360) {
- float x_maxII = x+radius*cos(end*M_PI/180);
- float x_minII;
-
- if(start <= 180)
- x_minII = x - radius;
- else
- x_minII = x+radius*cos(start*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxII && x-a >= x_minII)
- gdisp_lld_draw_pixel(x-a, y+b, color);
- if(x+a <= x_maxII && x+a >= x_minII)
- gdisp_lld_draw_pixel(x+a, y+b, color);
- if(x-b <= x_maxII && x-b >= x_minII)
- gdisp_lld_draw_pixel(x-b, y+a, color);
- if(x+b <= x_maxII && x+b >= x_minII)
- gdisp_lld_draw_pixel(x+b, y+a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while (a <= b);
- }
- }
-
- void gdisp_lld_draw_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color) {
- if(endangle < startangle) {
- _draw_arc(x, y, startangle, 360, radius, color);
- _draw_arc(x, y, 0, endangle, radius, color);
- } else {
- _draw_arc(x, y, startangle, endangle, radius, color);
- }
- }
-#endif
-
-#if GDISP_NEED_ARC && !GDISP_HARDWARE_ARCFILLS
- /*
- * @brief Internal helper function for gdispDrawArc()
- *
- * @note DO NOT USE DIRECTLY!
- *
- * @param[in] x, y The middle point of the arc
- * @param[in] start The start angle of the arc
- * @param[in] end The end angle of the arc
- * @param[in] radius The radius of the arc
- * @param[in] color The color in which the arc will be drawn
- *
- * @notapi
- */
- static void _fill_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
- if (/*start >= 0 && */start <= 180) {
- float x_maxI = x + radius*cos(start*M_PI/180);
- float x_minI;
-
- if (end > 180)
- x_minI = x - radius;
- else
- x_minI = x + radius*cos(end*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxI && x-a >= x_minI)
- gdisp_lld_draw_line(x, y, x-a, y-b, color);
- if(x+a <= x_maxI && x+a >= x_minI)
- gdisp_lld_draw_line(x, y, x+a, y-b, color);
- if(x-b <= x_maxI && x-b >= x_minI)
- gdisp_lld_draw_line(x, y, x-b, y-a, color);
- if(x+b <= x_maxI && x+b >= x_minI)
- gdisp_lld_draw_line(x, y, x+b, y-a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while(a <= b);
- }
-
- if (end > 180 && end <= 360) {
- float x_maxII = x+radius*cos(end*M_PI/180);
- float x_minII;
-
- if(start <= 180)
- x_minII = x - radius;
- else
- x_minII = x+radius*cos(start*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxII && x-a >= x_minII)
- gdisp_lld_draw_line(x, y, x-a, y+b, color);
- if(x+a <= x_maxII && x+a >= x_minII)
- gdisp_lld_draw_line(x, y, x+a, y+b, color);
- if(x-b <= x_maxII && x-b >= x_minII)
- gdisp_lld_draw_line(x, y, x-b, y+a, color);
- if(x+b <= x_maxII && x+b >= x_minII)
- gdisp_lld_draw_line(x, y, x+b, y+a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while (a <= b);
- }
- }
-
- void gdisp_lld_fill_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color) {
- if(endangle < startangle) {
- _fill_arc(x, y, startangle, 360, radius, color);
- _fill_arc(x, y, 0, endangle, radius, color);
- } else {
- _fill_arc(x, y, startangle, endangle, radius, color);
- }
- }
-#endif
-
-#if GDISP_NEED_CONTROL && !GDISP_HARDWARE_CONTROL
- void gdisp_lld_control(unsigned what, void *value) {
- (void)what;
- (void)value;
- /* Ignore everything */
- }
-#endif
-
-#if GDISP_NEED_QUERY && !GDISP_HARDWARE_QUERY
-void *gdisp_lld_query(unsigned what) {
- (void) what;
- return (void *)-1;
-}
-#endif
-
-#if GDISP_NEED_MSGAPI
- void gdisp_lld_msg_dispatch(gdisp_lld_msg_t *msg) {
- switch(msg->action) {
- case GDISP_LLD_MSG_NOP:
- break;
- case GDISP_LLD_MSG_INIT:
- gdisp_lld_init();
- break;
- case GDISP_LLD_MSG_CLEAR:
- gdisp_lld_clear(msg->clear.color);
- break;
- case GDISP_LLD_MSG_DRAWPIXEL:
- gdisp_lld_draw_pixel(msg->drawpixel.x, msg->drawpixel.y, msg->drawpixel.color);
- break;
- case GDISP_LLD_MSG_FILLAREA:
- gdisp_lld_fill_area(msg->fillarea.x, msg->fillarea.y, msg->fillarea.cx, msg->fillarea.cy, msg->fillarea.color);
- break;
- case GDISP_LLD_MSG_BLITAREA:
- gdisp_lld_blit_area_ex(msg->blitarea.x, msg->blitarea.y, msg->blitarea.cx, msg->blitarea.cy, msg->blitarea.srcx, msg->blitarea.srcy, msg->blitarea.srccx, msg->blitarea.buffer);
- break;
- case GDISP_LLD_MSG_DRAWLINE:
- gdisp_lld_draw_line(msg->drawline.x0, msg->drawline.y0, msg->drawline.x1, msg->drawline.y1, msg->drawline.color);
- break;
- #if GDISP_NEED_CLIP
- case GDISP_LLD_MSG_SETCLIP:
- gdisp_lld_set_clip(msg->setclip.x, msg->setclip.y, msg->setclip.cx, msg->setclip.cy);
- break;
- #endif
- #if GDISP_NEED_CIRCLE
- case GDISP_LLD_MSG_DRAWCIRCLE:
- gdisp_lld_draw_circle(msg->drawcircle.x, msg->drawcircle.y, msg->drawcircle.radius, msg->drawcircle.color);
- break;
- case GDISP_LLD_MSG_FILLCIRCLE:
- gdisp_lld_fill_circle(msg->fillcircle.x, msg->fillcircle.y, msg->fillcircle.radius, msg->fillcircle.color);
- break;
- #endif
- #if GDISP_NEED_ELLIPSE
- case GDISP_LLD_MSG_DRAWELLIPSE:
- gdisp_lld_draw_ellipse(msg->drawellipse.x, msg->drawellipse.y, msg->drawellipse.a, msg->drawellipse.b, msg->drawellipse.color);
- break;
- case GDISP_LLD_MSG_FILLELLIPSE:
- gdisp_lld_fill_ellipse(msg->fillellipse.x, msg->fillellipse.y, msg->fillellipse.a, msg->fillellipse.b, msg->fillellipse.color);
- break;
- #endif
- #if GDISP_NEED_ARC
- case GDISP_LLD_MSG_DRAWARC:
- gdisp_lld_draw_circle(msg->drawarc.x, msg->drawarc.y, msg->drawarc.radius, msg->drawarc.startangle, msg->drawarc.endangle, msg->drawarc.color);
- break;
- case GDISP_LLD_MSG_FILLARC:
- gdisp_lld_fill_circle(msg->fillarc.x, msg->fillarc.y, msg->fillarc.radius, msg->fillarc.startangle, msg->fillarc.endangle, msg->fillarc.color);
- break;
- #endif
- #if GDISP_NEED_PIXELREAD
- case GDISP_LLD_MSG_GETPIXELCOLOR:
- msg->getpixelcolor.result = gdisp_lld_get_pixel_color(msg->getpixelcolor.x, msg->getpixelcolor.y);
- break;
- #endif
- #if GDISP_NEED_SCROLL
- case GDISP_LLD_MSG_VERTICALSCROLL:
- gdisp_lld_vertical_scroll(msg->verticalscroll.x, msg->verticalscroll.y, msg->verticalscroll.cx, msg->verticalscroll.cy, msg->verticalscroll.lines, msg->verticalscroll.bgcolor);
- break;
- #endif
- #if GDISP_NEED_CONTROL
- case GDISP_LLD_MSG_CONTROL:
- gdisp_lld_control(msg->control.what, msg->control.value);
- break;
- #endif
- #if GDISP_NEED_QUERY
- case GDISP_LLD_MSG_QUERY:
- msg->query.result = gdisp_lld_query(msg->query.what);
- break;
- #endif
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-#endif /* GDISP_EMULATION_C */
-/** @} */
-
diff --git a/include/gdisp/lld/gdisp_lld.h b/include/gdisp/lld/gdisp_lld.h
index 98c7569c..d928d83d 100644
--- a/include/gdisp/lld/gdisp_lld.h
+++ b/include/gdisp/lld/gdisp_lld.h
@@ -22,266 +22,881 @@
/* 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 Hardware accelerated line drawing.
- * @details If set to @p FALSE software emulation is used.
- */
- #ifndef GDISP_HARDWARE_LINES
- #define GDISP_HARDWARE_LINES FALSE
- #endif
-
- /**
- * @brief Hardware accelerated screen clears.
- * @details If set to @p FALSE software emulation is used.
+ * @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_CLEARS
- #define GDISP_HARDWARE_CLEARS FALSE
+ #ifndef GDISP_HARDWARE_FLUSH
+ #define GDISP_HARDWARE_FLUSH HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated rectangular fills.
- * @details If set to @p FALSE software emulation is used.
+ * @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_FILLS
- #define GDISP_HARDWARE_FILLS FALSE
+ #ifndef GDISP_HARDWARE_STREAM_WRITE
+ #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated fills from an image.
- * @details If set to @p FALSE software emulation is used.
+ * @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_BITFILLS
- #define GDISP_HARDWARE_BITFILLS FALSE
+ #ifndef GDISP_HARDWARE_STREAM_READ
+ #define GDISP_HARDWARE_STREAM_READ HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated circles.
- * @details If set to @p FALSE software emulation is used.
+ * @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_CIRCLES
- #define GDISP_HARDWARE_CIRCLES FALSE
+ #ifndef GDISP_HARDWARE_STREAM_POS
+ #define GDISP_HARDWARE_STREAM_POS HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated filled circles.
- * @details If set to @p FALSE software emulation is used.
+ * @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_CIRCLEFILLS
- #define GDISP_HARDWARE_CIRCLEFILLS FALSE
+ #ifndef GDISP_HARDWARE_DRAWPIXEL
+ #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated ellipses.
- * @details If set to @p FALSE software emulation is used.
- */
- #ifndef GDISP_HARDWARE_ELLIPSES
- #define GDISP_HARDWARE_ELLIPSES FALSE
- #endif
-
- /**
- * @brief Hardware accelerated filled ellipses.
- * @details If set to @p FALSE software emulation is used.
+ * @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_ELLIPSEFILLS
- #define GDISP_HARDWARE_ELLIPSEFILLS FALSE
+ #ifndef GDISP_HARDWARE_CLEARS
+ #define GDISP_HARDWARE_CLEARS HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated arc's.
- * @details If set to @p FALSE software emulation is used.
+ * @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_ARCS
- #define GDISP_HARDWARE_ARCS FALSE
+ #ifndef GDISP_HARDWARE_FILLS
+ #define GDISP_HARDWARE_FILLS HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated filled arcs.
- * @details If set to @p FALSE software emulation is used.
+ * @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_ARCFILLS
- #define GDISP_HARDWARE_ARCFILLS FALSE
+ #ifndef GDISP_HARDWARE_BITFILLS
+ #define GDISP_HARDWARE_BITFILLS HARDWARE_DEFAULT
#endif
/**
* @brief Hardware accelerated scrolling.
- * @details If set to @p FALSE there is no support for 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 FALSE
+ #define GDISP_HARDWARE_SCROLL HARDWARE_DEFAULT
#endif
/**
* @brief Reading back of pixel values.
- * @details If set to @p FALSE there is no support for pixel read-back.
+ * @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 FALSE
+ #define GDISP_HARDWARE_PIXELREAD HARDWARE_DEFAULT
#endif
/**
* @brief The driver supports one or more control commands.
- * @details If set to @p FALSE there is no support for 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 FALSE
+ #define GDISP_HARDWARE_CONTROL HARDWARE_DEFAULT
#endif
/**
* @brief The driver supports a non-standard query.
- * @details If set to @p FALSE there is no support for non-standard queries.
+ * @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 FALSE
+ #define GDISP_HARDWARE_QUERY HARDWARE_DEFAULT
#endif
/**
* @brief The driver supports a clipping in hardware.
- * @details If set to @p FALSE there is no support for non-standard queries.
+ * @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 FALSE
+ #define GDISP_HARDWARE_CLIP HARDWARE_DEFAULT
#endif
/** @} */
-/**
- * @name GDISP software algorithm choices
- * @{
- */
-/** @} */
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
-/**
- * @name GDISP pixel format choices
- * @{
- */
- /**
- * @brief The native pixel format for this device
- * @note Should be set to one of the following:
- * GDISP_PIXELFORMAT_RGB565
- * GDISP_PIXELFORMAT_RGB888
- * GDISP_PIXELFORMAT_RGB444
- * GDISP_PIXELFORMAT_RGB332
- * GDISP_PIXELFORMAT_RGB666
- * GDISP_PIXELFORMAT_CUSTOM
- * @note If you set GDISP_PIXELFORMAT_CUSTOM you need to also define
- * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h),
- * RED_OF(c), GREEN_OF(c), BLUE_OF(c),
- * COLOR(c) and MASKCOLOR.
- */
- #ifndef GDISP_PIXELFORMAT
- #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
+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
- /**
- * @brief Do pixels require packing for a blit
- * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats:
- * GDISP_PIXELFORMAT_RGB888
- * GDISP_PIXELFORMAT_RGB444
- * GDISP_PIXELFORMAT_RGB666
- * GDISP_PIXELFORMAT_CUSTOM
- * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills
- * you need to also define @p gdispPackPixels(buf,cx,x,y,c)
- * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel
- * format must not be a packed format as the software blit does
- * not support packed pixels
- * @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.
- */
- #ifndef GDISP_PACKED_PIXELS
- #define GDISP_PACKED_PIXELS FALSE
+ 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 Do lines of pixels require packing for a blit
- * @note Ignored if GDISP_PACKED_PIXELS is FALSE
+ * @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
*/
- #ifndef GDISP_PACKED_LINES
- #define GDISP_PACKED_LINES FALSE
+ 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
-/** @} */
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
+ #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
+ * @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.
+ * @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
+ * @param[in] 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
-#ifdef __cplusplus
-extern "C" {
-#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
- /* Core functions */
- extern bool_t gdisp_lld_init(void);
+ #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
- /* Some of these functions will be implemented in software by the high level driver
- depending on the GDISP_HARDWARE_XXX macros defined in gdisp_lld_config.h.
- */
+ #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
- /* Drawing functions */
- extern void gdisp_lld_clear(color_t color);
- extern void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color);
- extern void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
- extern void gdisp_lld_blit_area_ex(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);
- extern void gdisp_lld_draw_line(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+ #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
- /* Circular Drawing Functions */
- #if GDISP_NEED_CIRCLE
- extern void gdisp_lld_draw_circle(coord_t x, coord_t y, coord_t radius, color_t color);
- extern void gdisp_lld_fill_circle(coord_t x, coord_t y, coord_t radius, color_t color);
+ #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_NEED_ELLIPSE
- extern void gdisp_lld_draw_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
- extern void gdisp_lld_fill_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #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
- /* Arc Drawing Functions */
- #if GDISP_NEED_ARC
- extern void gdisp_lld_draw_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
- extern void gdisp_lld_fill_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #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
- /* Text Rendering Functions */
- #if GDISP_NEED_TEXT
- extern void gdisp_lld_draw_char(coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
- extern void gdisp_lld_fill_char(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ #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
- /* Pixel readback */
- #if GDISP_NEED_PIXELREAD
- extern color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y);
+ #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
- /* Scrolling Function - clears the area scrolled out */
- #if GDISP_NEED_SCROLL
- extern void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
+ #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
- /* Set driver specific control */
- #if GDISP_NEED_CONTROL
- extern void gdisp_lld_control(unsigned what, void *value);
+ #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
- /* Query driver specific data */
- #if GDISP_NEED_QUERY
- extern void *gdisp_lld_query(unsigned what);
+/* 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
- /* Clipping Functions */
- #if GDISP_NEED_CLIP
- extern void gdisp_lld_set_clip(coord_t x, coord_t y, coord_t cx, coord_t cy);
+ // 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
- /* Messaging API */
- #if GDISP_NEED_MSGAPI
- #include "gdisp_lld_msgs.h"
- extern void gdisp_lld_msg_dispatch(gdisp_lld_msg_t *msg);
+/**
+ * @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
-#ifdef __cplusplus
-}
+/* 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 COLOR2NATIVE(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 NATIVE2COLOR(c) (c)
+
+#else
+ #if COLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE || LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ #define COLOR2NATIVE(c) LLDLUMA2COLOR(EXACT_LUMA_OF(c))
+ #define NATIVE2COLOR(c) LUMA2COLOR(LLDEXACT_LUMA_OF(c))
+ #else
+ #define COLOR2NATIVE(c) LLDLUMA2COLOR(LUMA_OF(c))
+ #define NATIVE2COLOR(c) LUMA2COLOR(LLDLUMA_OF(c))
+ #endif
+ #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR && LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ #define COLOR2NATIVE(c) LLDRGB2COLOR(EXACT_RED_OF(c), EXACT_GREEN_OF(c), EXACT_BLUE_OF(c))
+ #define NATIVE2COLOR(c) RGB2COLOR(LLDEXACT_RED_OF(c), LLDEXACT_GREEN_OF(c), LLDEXACT_BLUE_OF(c))
+ #else
+ #define COLOR2NATIVE(c) LLDRGB2COLOR(RED_OF(c), GREEN_OF(c), BLUE_OF(c))
+ #define NATIVE2COLOR(c) RGB2COLOR(LLDRED_OF(c), LLDGREEN_OF(c), LLDBLUE_OF(c))
+ #endif
+
+ /*
+ #elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888 && GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_BGR888
+ #define COLOR2NATIVE(c) ((LLDCOLOR_TYPE)(((c)&0xFF0000)>>16)|((c)&0x00FF00)|(((c)&0x0000FF)<<16))
+ #define NATIVE2COLOR(c) ((COLOR_TYPE)(((c)&0xFF0000)>>16)|((c)&0x00FF00)|(((c)&0x0000FF)<<16))
+ #elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565 && GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_BGR888
+ #define COLOR2NATIVE(c) ((LLDCOLOR_TYPE)( \
+ ((LARGER_COLOR_TYPE)((c)&(((1<<COLOR_BITS_R)-1)<<COLOR_SHIFT_R))>>(COLOR_BITS_R+COLOR_SHIFT_R-8))| \
+ ((LARGER_COLOR_TYPE)((c)&(((1<<COLOR_BITS_G)-1)<<COLOR_SHIFT_G))<<(16-(COLOR_BITS_G+COLOR_SHIFT_G)))| \
+ ((LARGER_COLOR_TYPE)((c)&(((1<<COLOR_BITS_B)-1)<<COLOR_SHIFT_B))<<(24-(COLOR_BITS_B+COLOR_SHIFT_B)))))
+ #define NATIVE2COLOR(c) ((COLOR_TYPE)( \
+ ((LARGER_COLOR_TYPE)((c)&0x0000F8)<<COLOR_SHIFT_R)| \
+ ((LARGER_COLOR_TYPE)((c)&0x00FC00)>>(16-(COLOR_BITS_G+COLOR_SHIFT_G)))| \
+ ((LARGER_COLOR_TYPE)((c)&0xF80000)>>(24-(COLOR_BITS_B+COLOR_SHIFT_B)))))
+ */
+ #else
+ #error "GDISP: This pixel format conversion is not supported yet"
+ #endif
#endif
#endif /* GFX_USE_GDISP */
diff --git a/include/gdisp/lld/gdisp_lld_msgs.h b/include/gdisp/lld/gdisp_lld_msgs.h
deleted file mode 100644
index 2c199cbe..00000000
--- a/include/gdisp/lld/gdisp_lld_msgs.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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/lld/gdisp_lld_msgs.h
- * @brief GDISP Graphic Driver subsystem low level driver message structures.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_MSGS_H
-#define _GDISP_LLD_MSGS_H
-
-/* This file describes the message API for gdisp_lld */
-#if GFX_USE_GDISP && GDISP_NEED_MSGAPI
-
-typedef enum gdisp_msgaction {
- GDISP_LLD_MSG_NOP,
- GDISP_LLD_MSG_INIT,
- GDISP_LLD_MSG_CLEAR,
- GDISP_LLD_MSG_DRAWPIXEL,
- GDISP_LLD_MSG_FILLAREA,
- GDISP_LLD_MSG_BLITAREA,
- GDISP_LLD_MSG_DRAWLINE,
- #if GDISP_NEED_CLIP
- GDISP_LLD_MSG_SETCLIP,
- #endif
- #if GDISP_NEED_CIRCLE
- GDISP_LLD_MSG_DRAWCIRCLE,
- GDISP_LLD_MSG_FILLCIRCLE,
- #endif
- #if GDISP_NEED_ELLIPSE
- GDISP_LLD_MSG_DRAWELLIPSE,
- GDISP_LLD_MSG_FILLELLIPSE,
- #endif
- #if GDISP_NEED_ARC
- GDISP_LLD_MSG_DRAWARC,
- GDISP_LLD_MSG_FILLARC,
- #endif
- #if GDISP_NEED_PIXELREAD
- GDISP_LLD_MSG_GETPIXELCOLOR,
- #endif
- #if GDISP_NEED_SCROLL
- GDISP_LLD_MSG_VERTICALSCROLL,
- #endif
- #if GDISP_NEED_CONTROL
- GDISP_LLD_MSG_CONTROL,
- #endif
- GDISP_LLD_MSG_QUERY,
-} gdisp_msgaction_t;
-
-typedef union gdisp_lld_msg {
- struct {
- gfxQueueItem qi;
- gdisp_msgaction_t action;
- };
- struct gdisp_lld_msg_init {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_INIT
- } init;
- struct gdisp_lld_msg_clear {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_CLEAR
- color_t color;
- } clear;
- struct gdisp_lld_msg_drawpixel {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWPIXEL
- coord_t x, y;
- color_t color;
- } drawpixel;
- struct gdisp_lld_msg_fillarea {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLAREA
- coord_t x, y;
- coord_t cx, cy;
- color_t color;
- } fillarea;
- struct gdisp_lld_msg_blitarea {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_BLITAREA
- coord_t x, y;
- coord_t cx, cy;
- coord_t srcx, srcy;
- coord_t srccx;
- const pixel_t *buffer;
- } blitarea;
- struct gdisp_lld_msg_setclip {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_SETCLIP
- coord_t x, y;
- coord_t cx, cy;
- } setclip;
- struct gdisp_lld_msg_drawline {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWLINE
- coord_t x0, y0;
- coord_t x1, y1;
- color_t color;
- } drawline;
- struct gdisp_lld_msg_drawcircle {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWCIRCLE
- coord_t x, y;
- coord_t radius;
- color_t color;
- } drawcircle;
- struct gdisp_lld_msg_fillcircle {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLCIRCLE
- coord_t x, y;
- coord_t radius;
- color_t color;
- } fillcircle;
- struct gdisp_lld_msg_drawellipse {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWELLIPSE
- coord_t x, y;
- coord_t a, b;
- color_t color;
- } drawellipse;
- struct gdisp_lld_msg_fillellipse {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLELLIPSE
- coord_t x, y;
- coord_t a, b;
- color_t color;
- } fillellipse;
- struct gdisp_lld_msg_drawarc {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWARC
- coord_t x, y;
- coord_t radius;
- coord_t startangle, endangle;
- color_t color;
- } drawarc;
- struct gdisp_lld_msg_fillarc {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLARC
- coord_t x, y;
- coord_t radius;
- coord_t startangle, endangle;
- color_t color;
- } fillarc;
- struct gdisp_lld_msg_getpixelcolor {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_GETPIXELCOLOR
- coord_t x, y;
- color_t result;
- } getpixelcolor;
- struct gdisp_lld_msg_verticalscroll {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_VERTICALSCROLL
- coord_t x, y;
- coord_t cx, cy;
- int lines;
- color_t bgcolor;
- } verticalscroll;
- struct gdisp_lld_msg_control {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_CONTROL
- int what;
- void * value;
- } control;
- struct gdisp_lld_msg_query {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_QUERY
- int what;
- void * result;
- } query;
-} gdisp_lld_msg_t;
-
-#endif /* GFX_USE_GDISP && GDISP_NEED_MSGAPI */
-#endif /* _GDISP_LLD_MSGS_H */
-/** @} */
-
diff --git a/include/gdisp/options.h b/include/gdisp/options.h
index efabe417..650e81c5 100644
--- a/include/gdisp/options.h
+++ b/include/gdisp/options.h
@@ -21,11 +21,31 @@
* @{
*/
/**
- * @brief The priority of the GDISP thread.
- * @details Defaults to NORMAL_PRIORITY
+ * @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_THREAD_PRIORITY
- #define GDISP_THREAD_PRIORITY NORMAL_PRIORITY
+ #ifndef GDISP_NEED_TIMERFLUSH
+ #define GDISP_NEED_TIMERFLUSH FALSE
#endif
/**
* @brief Should all operations be clipped to the screen and colors validated.
@@ -33,49 +53,67 @@
* @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 If defined then all low level and high level GDISP driver routines
- * must check the validity of inputs and do something sensible
- * if they are out of range. It doesn't have to be efficient,
- * just valid.
+ * @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
+ #define GDISP_NEED_VALIDATION TRUE
#endif
/**
* @brief Are clipping functions needed.
* @details Defaults to TRUE
*/
#ifndef GDISP_NEED_CLIP
- #define GDISP_NEED_CLIP TRUE
+ #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
+ #define GDISP_NEED_TEXT FALSE
#endif
/**
* @brief Are circle functions needed.
- * @details Defaults to TRUE
+ * @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 TRUE
+ #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
+ #define GDISP_NEED_ELLIPSE FALSE
#endif
/**
* @brief Are arc functions needed.
* @details Defaults to FALSE
- * @note Requires the maths library to be included in the link. ie -lm
+ * @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
+ #define GDISP_NEED_ARC FALSE
#endif
/**
* @brief Are convex polygon functions needed.
@@ -95,7 +133,7 @@
* option will cause a compile error.
*/
#ifndef GDISP_NEED_SCROLL
- #define GDISP_NEED_SCROLL FALSE
+ #define GDISP_NEED_SCROLL FALSE
#endif
/**
* @brief Is the capability to read pixels back needed.
@@ -105,7 +143,7 @@
* option will cause a compile error.
*/
#ifndef GDISP_NEED_PIXELREAD
- #define GDISP_NEED_PIXELREAD FALSE
+ #define GDISP_NEED_PIXELREAD FALSE
#endif
/**
* @brief Control some aspect of the hardware operation.
@@ -114,7 +152,7 @@
* screen rotation, backlight levels, contrast etc
*/
#ifndef GDISP_NEED_CONTROL
- #define GDISP_NEED_CONTROL FALSE
+ #define GDISP_NEED_CONTROL FALSE
#endif
/**
* @brief Query some aspect of the hardware operation.
@@ -122,21 +160,58 @@
* @note This allows query of hardware specific features
*/
#ifndef GDISP_NEED_QUERY
- #define GDISP_NEED_QUERY FALSE
+ #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
+ #define GDISP_NEED_IMAGE FALSE
#endif
+/**
+ * @}
+ *
+ * @name GDISP Multiple Display Support
+ * @{
+ */
/**
- * @brief Is the messaging api interface required.
- * @details Defaults to FALSE
+ * @brief The total number of displays.
+ * @note This can be on just one type of controller or spread across several different controllers
*/
- #ifndef GDISP_NEED_MSGAPI
- #define GDISP_NEED_MSGAPI FALSE
+ #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
/**
* @}
@@ -150,42 +225,42 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_NATIVE
- #define GDISP_NEED_IMAGE_NATIVE FALSE
+ #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
+ #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
+ #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
+ #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
+ #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
+ #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
#endif
/**
* @}
@@ -198,7 +273,7 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_UTF8
- #define GDISP_NEED_UTF8 FALSE
+ #define GDISP_NEED_UTF8 FALSE
#endif
/**
@@ -206,7 +281,7 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_TEXT_KERNING
- #define GDISP_NEED_TEXT_KERNING FALSE
+ #define GDISP_NEED_TEXT_KERNING FALSE
#endif
/**
@@ -214,7 +289,7 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_ANTIALIAS
- #define GDISP_NEED_ANTIALIAS FALSE
+ #define GDISP_NEED_ANTIALIAS FALSE
#endif
/**
@@ -226,27 +301,10 @@
/**
* @brief Do the drawing functions need to be thread-safe.
* @details Defaults to FALSE
- * @note Both GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC make
- * the gdisp API thread-safe.
- * @note This is more efficient than GDISP_NEED_ASYNC as it only
- * requires a context switch if something else is already
- * drawing.
*/
#ifndef GDISP_NEED_MULTITHREAD
#define GDISP_NEED_MULTITHREAD FALSE
#endif
- /**
- * @brief Use asynchronous calls (multi-thread safe).
- * @details Defaults to FALSE
- * @note Both GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC make
- * the gdisp API thread-safe.
- * @note Turning this on adds two context switches per transaction
- * so it can significantly slow graphics drawing but it allows
- * drawing operations to continue in the background.
- */
- #ifndef GDISP_NEED_ASYNC
- #define GDISP_NEED_ASYNC FALSE
- #endif
/**
* @}
*
@@ -264,6 +322,23 @@
* @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
/**
* @}
*
@@ -271,14 +346,10 @@
* @{
*/
/**
- * @brief Use a custom board definition even if a board definition exists.
- * @details Defaults to FALSE
- * @details If TRUE, add gdisp_lld_board.h to your project directory and customise it.
- * @note Not all GDISP low level drivers currently use board definition files.
+ * @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)
*/
- #ifndef GDISP_USE_CUSTOM_BOARD
- #define GDISP_USE_CUSTOM_BOARD FALSE
- #endif
+ // #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.
@@ -289,24 +360,14 @@
/* #define GDISP_SCREEN_WIDTH nnnn */
/* #define GDISP_SCREEN_HEIGHT nnnn */
/**
- * @brief Define which threading model to use.
- * @details Optional for the X11 driver.
- * @note Defaults to TRUE. Setting to FALSE causes POSIX threads to be used
- */
- /* #define GDISP_THREAD_CHIBIOS FALSE */
- /**
* @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 */
+ // #define GDISP_USE_FSMC
+ // #define GDISP_USE_GPIO
/** @} */
-#if GFX_USE_GDISP
- #include "gdisp_lld_config.h"
-#endif
-
#endif /* _GDISP_OPTIONS_H */
/** @} */
diff --git a/include/gfx_rules.h b/include/gfx_rules.h
index afd2a8fe..534c2cc9 100644
--- a/include/gfx_rules.h
+++ b/include/gfx_rules.h
@@ -87,10 +87,9 @@
#undef GWIN_NEED_WINDOWMANAGER
#define GWIN_NEED_WINDOWMANAGER TRUE
#endif
- #if !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC
+ #if !GDISP_NEED_MULTITHREAD
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GWIN: Either GDISP_NEED_MULTITHREAD or GDISP_NEED_ASYNC is required if GWIN_NEED_WIDGET is TRUE."
- #warning "GWIN: GDISP_NEED_MULTITHREAD has been turned on for you."
+ #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
@@ -134,17 +133,37 @@
#endif
#if GFX_USE_GDISP
- #if GDISP_NEED_MULTITHREAD && GDISP_NEED_ASYNC
- #error "GDISP: Only one of GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC should be defined."
+ #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_ASYNC && !(GFX_USE_GQUEUE && GQUEUE_NEED_GSYNC)
+ #if GDISP_NEED_AUTOFLUSH && GDISP_NEED_TIMERFLUSH
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GDISP: GDISP_NEED_ASYNC requires GFX_USE_GQUEUE and GQUEUE_NEED_GSYNC. They have been turned on for you."
+ #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
- #undef GFX_USE_GQUEUE
- #define GFX_USE_GQUEUE TRUE
- #undef GQUEUE_NEED_GSYNC
- #define GQUEUE_NEED_GSYNC TRUE
#endif
#if GDISP_NEED_ANTIALIAS && !GDISP_NEED_PIXELREAD
#if GDISP_HARDWARE_PIXELREAD
@@ -161,11 +180,11 @@
#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 DEJAVUSANS12 has been added instead."
+ #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_DEJAVUSANS12
- #define GDISP_INCLUDE_FONT_DEJAVUSANS12 TRUE
+ #undef GDISP_INCLUDE_FONT_UI2
+ #define GDISP_INCLUDE_FONT_UI2 TRUE
#endif
#endif
@@ -196,9 +215,9 @@
#endif
#if GFX_USE_GTIMER
- #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC
+ #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GTIMER: Neither GDISP_NEED_MULTITHREAD nor GDISP_NEED_ASYNC has been specified."
+ #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
diff --git a/include/ginput/mouse.h b/include/ginput/mouse.h
index 93537329..aa9864a9 100644
--- a/include/ginput/mouse.h
+++ b/include/ginput/mouse.h
@@ -56,6 +56,7 @@ typedef struct GEventMouse_t {
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()
@@ -84,7 +85,8 @@ extern "C" {
/**
* @brief Creates an instance of a mouse and returns the Source handler
- * @note hack: if the instance is 9999, no calibration will be performed!
+ * @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)
*
@@ -93,6 +95,28 @@ extern "C" {
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
+ * @param[in] g The GDisplay to which this mouse belongs
+ */
+ 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".
@@ -129,12 +153,11 @@ extern "C" {
* 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.
*
* @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 ToDo
+ * @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);
diff --git a/include/gmisc/gmisc.h b/include/gmisc/gmisc.h
index 998dda50..ff3d0c76 100644
--- a/include/gmisc/gmisc.h
+++ b/include/gmisc/gmisc.h
@@ -51,6 +51,7 @@ typedef int32_t fixed;
*/
#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 */
/* @} */
@@ -183,6 +184,23 @@ extern "C" {
/** @} */
#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
diff --git a/include/gmisc/options.h b/include/gmisc/options.h
index d5cf5898..06f689ec 100644
--- a/include/gmisc/options.h
+++ b/include/gmisc/options.h
@@ -28,25 +28,50 @@
#define GMISC_NEED_ARRAYOPS FALSE
#endif
/**
- * @brief Include fast array based trig functions (sin, cos)
+ * @brief Include fast fixed point trig functions (sin, cos)
* @details Defaults to FALSE
*/
- #ifndef GMISC_NEED_FASTTRIG
- #define GMISC_NEED_FASTTRIG FALSE
+ #ifndef GMISC_NEED_FIXEDTRIG
+ #define GMISC_NEED_FIXEDTRIG FALSE
#endif
/**
- * @brief Include fast fixed point trig functions (sin, cos)
+ * @brief Include fast inverse square root (x^-1/2)
* @details Defaults to FALSE
*/
- #ifndef GMISC_NEED_FIXEDTRIG
- #define GMISC_NEED_FIXEDTRIG FALSE
+ #ifndef GMISC_NEED_INVSQRT
+ #define GMISC_NEED_INVSQRT FALSE
#endif
/**
* @}
*
- * @name GMISC Optional Sizing Parameters
+ * @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/include/gwin/button.h b/include/gwin/button.h
index 13b135a3..d11764d6 100644
--- a/include/gwin/button.h
+++ b/include/gwin/button.h
@@ -59,6 +59,7 @@ extern "C" {
* @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
*
@@ -74,7 +75,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinButtonCreate(GButtonObject *gb, const GWidgetInit *pInit);
+GHandle gwinGButtonCreate(GDisplay *g, GButtonObject *gb, const GWidgetInit *pInit);
+#define gwinButtonCreate(gb, pInit) gwinGButtonCreate(GDISP, gb, pInit)
/**
* @brief Is the button current pressed
diff --git a/include/gwin/checkbox.h b/include/gwin/checkbox.h
index 29ebe96e..946f7e4a 100644
--- a/include/gwin/checkbox.h
+++ b/include/gwin/checkbox.h
@@ -52,6 +52,7 @@ typedef struct 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
*
@@ -67,7 +68,8 @@ typedef struct GCheckboxObject {
*
* @api
*/
-GHandle gwinCheckboxCreate(GCheckboxObject *gb, const GWidgetInit *pInit);
+GHandle gwinGCheckboxCreate(GDisplay *g, GCheckboxObject *gb, const GWidgetInit *pInit);
+#define gwinCheckboxCreate(gb, pInit) gwinGCheckboxCreate(GDISP, gb, pInit)
/**
* @brief Set the state of a checkbox
diff --git a/include/gwin/class_gwin.h b/include/gwin/class_gwin.h
index b3f630e3..62b1752e 100644
--- a/include/gwin/class_gwin.h
+++ b/include/gwin/class_gwin.h
@@ -150,6 +150,7 @@ extern "C" {
/**
* @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
@@ -159,12 +160,13 @@ extern "C" {
*
* @notapi
*/
-GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags);
+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
@@ -173,7 +175,7 @@ GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinV
*
* @notapi
*/
- GHandle _gwidgetCreate(GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt);
+ GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt);
/**
* @brief Destroy the Widget object
diff --git a/include/gwin/console.h b/include/gwin/console.h
index c05c4ad2..ed65581e 100644
--- a/include/gwin/console.h
+++ b/include/gwin/console.h
@@ -50,6 +50,7 @@ extern "C" {
* @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
*
@@ -64,7 +65,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinConsoleCreate(GConsoleObject *gc, const GWindowInit *pInit);
+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
/**
diff --git a/include/gwin/graph.h b/include/gwin/graph.h
index fd99458d..65a64126 100644
--- a/include/gwin/graph.h
+++ b/include/gwin/graph.h
@@ -90,6 +90,7 @@ extern "C" {
* @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
*
@@ -107,7 +108,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinGraphCreate(GGraphObject *gg, const GWindowInit *pInit);
+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.
diff --git a/include/gwin/gwin.h b/include/gwin/gwin.h
index 45e29b00..fa5ba613 100644
--- a/include/gwin/gwin.h
+++ b/include/gwin/gwin.h
@@ -38,6 +38,7 @@ typedef struct GWindowObject {
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
@@ -165,6 +166,7 @@ extern "C" {
* @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
*
@@ -177,7 +179,8 @@ extern "C" {
*
* @api
*/
- GHandle gwinWindowCreate(GWindowObject *pgw, const GWindowInit *pInit);
+ 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.
diff --git a/include/gwin/image.h b/include/gwin/image.h
index eae196e9..66dd0b94 100644
--- a/include/gwin/image.h
+++ b/include/gwin/image.h
@@ -47,6 +47,7 @@ extern "C" {
* @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.
*
@@ -55,7 +56,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinImageCreate(GImageObject *widget, GWindowInit *pInit);
+GHandle gwinGImageCreate(GDisplay *g, GImageObject *widget, GWindowInit *pInit);
+#define gwinImageCreate(w, pInit) gwinGImageCreate(GDISP, w, pInit)
/**
* @brief Sets the input routines that support reading the image from memory
diff --git a/include/gwin/label.h b/include/gwin/label.h
index 3156ca71..caa4c1d1 100644
--- a/include/gwin/label.h
+++ b/include/gwin/label.h
@@ -42,6 +42,7 @@ extern "C" {
* @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.
*
@@ -49,7 +50,18 @@ extern "C" {
*
* @api
*/
-GHandle gwinLabelCreate(GLabelObject *widget, GWidgetInit *pInit);
+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);
/**
* @brief Border settings for the default rendering routine
diff --git a/include/gwin/list.h b/include/gwin/list.h
index b45e7767..11815d05 100644
--- a/include/gwin/list.h
+++ b/include/gwin/list.h
@@ -82,6 +82,7 @@ extern "C" {
* 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.
@@ -90,7 +91,20 @@ extern "C" {
*
* @api
*/
-GHandle gwinListCreate(GListObject *widget, GWidgetInit *pInit, bool_t multiselect);
+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 and @p scrollAuto
+ *
+ * @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 Change the behaviour of the scroll bar
diff --git a/include/gwin/radio.h b/include/gwin/radio.h
index e59c526e..3ee2918f 100644
--- a/include/gwin/radio.h
+++ b/include/gwin/radio.h
@@ -59,6 +59,7 @@ extern "C" {
* @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.
@@ -77,7 +78,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinRadioCreate(GRadioObject *gb, const GWidgetInit *pInit, uint16_t group);
+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)
diff --git a/include/gwin/slider.h b/include/gwin/slider.h
index b037a621..8f87745c 100644
--- a/include/gwin/slider.h
+++ b/include/gwin/slider.h
@@ -58,6 +58,7 @@ extern "C" {
* @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
*
@@ -77,7 +78,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinSliderCreate(GSliderObject *gb, const GWidgetInit *pInit);
+GHandle gwinGSliderCreate(GDisplay *g, GSliderObject *gb, const GWidgetInit *pInit);
+#define gwinSliderCreate(w, pInit) gwinGSliderCreate(GDISP, w, pInit)
/**
* @brief Set the slider range.