diff options
| author | Joel Bodenmann <joel@unormal.org> | 2013-11-10 21:07:16 +0100 |
|---|---|---|
| committer | Joel Bodenmann <joel@unormal.org> | 2013-11-10 21:07:16 +0100 |
| commit | da2740b706d720292113445ee1db30f8a9873dc4 (patch) | |
| tree | 8f8b1902d4af6a23b3daf26990f580b76ea31ea4 /include | |
| parent | 6ca3537a696e7ace8098771a9a7105380604253d (diff) | |
| parent | a8ce005e2621b0108863297948cea0fa52c8bf2a (diff) | |
| download | uGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.gz uGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.bz2 uGFX-da2740b706d720292113445ee1db30f8a9873dc4.zip | |
merging GDISPStreaming
Diffstat (limited to 'include')
| -rw-r--r-- | include/gdisp/colors.h | 377 | ||||
| -rw-r--r-- | include/gdisp/gdisp.h | 941 | ||||
| -rw-r--r-- | include/gdisp/image.h | 14 | ||||
| -rw-r--r-- | include/gdisp/lld/emulation.c | 558 | ||||
| -rw-r--r-- | include/gdisp/lld/gdisp_lld.h | 933 | ||||
| -rw-r--r-- | include/gdisp/lld/gdisp_lld_msgs.h | 181 | ||||
| -rw-r--r-- | include/gdisp/options.h | 201 | ||||
| -rw-r--r-- | include/gfx_rules.h | 51 | ||||
| -rw-r--r-- | include/ginput/mouse.h | 29 | ||||
| -rw-r--r-- | include/gmisc/gmisc.h | 18 | ||||
| -rw-r--r-- | include/gmisc/options.h | 39 | ||||
| -rw-r--r-- | include/gwin/button.h | 4 | ||||
| -rw-r--r-- | include/gwin/checkbox.h | 4 | ||||
| -rw-r--r-- | include/gwin/class_gwin.h | 6 | ||||
| -rw-r--r-- | include/gwin/console.h | 4 | ||||
| -rw-r--r-- | include/gwin/graph.h | 4 | ||||
| -rw-r--r-- | include/gwin/gwin.h | 5 | ||||
| -rw-r--r-- | include/gwin/image.h | 4 | ||||
| -rw-r--r-- | include/gwin/label.h | 14 | ||||
| -rw-r--r-- | include/gwin/list.h | 16 | ||||
| -rw-r--r-- | include/gwin/radio.h | 4 | ||||
| -rw-r--r-- | include/gwin/slider.h | 4 |
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. |
