From 3fea02324831eba1773f45b1dc6d0bf2a0c8326d Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 17 Aug 2015 00:18:54 +1000 Subject: [PATCH] Add some keyboard widget support --- demos/modules/gwin/textedit/gfxconf.h | 3 +++ demos/modules/gwin/textedit/main.c | 14 ++++++++++ src/ginput/ginput_keyboard.h | 39 +++++++++++++-------------- src/gwin/gwin_button.c | 4 +-- src/gwin/gwin_checkbox.c | 4 +-- src/gwin/gwin_class.h | 2 +- src/gwin/gwin_container.c | 2 +- src/gwin/gwin_frame.c | 2 +- src/gwin/gwin_keyboard.c | 21 ++++++++++++++- src/gwin/gwin_label.c | 2 +- src/gwin/gwin_list.c | 2 +- src/gwin/gwin_progressbar.c | 2 +- src/gwin/gwin_radio.c | 2 +- src/gwin/gwin_rules.h | 4 +-- src/gwin/gwin_slider.c | 2 +- src/gwin/gwin_tabset.c | 2 +- src/gwin/gwin_textedit.c | 4 +-- 17 files changed, 73 insertions(+), 38 deletions(-) diff --git a/demos/modules/gwin/textedit/gfxconf.h b/demos/modules/gwin/textedit/gfxconf.h index 3c5d7b96..4faaae82 100644 --- a/demos/modules/gwin/textedit/gfxconf.h +++ b/demos/modules/gwin/textedit/gfxconf.h @@ -63,7 +63,10 @@ /* Features for the GINPUT subsystem. */ #define GINPUT_NEED_MOUSE TRUE + +/* One or both of these */ #define GINPUT_NEED_KEYBOARD TRUE +#define GWIN_NEED_KEYBOARD TRUE /* Features for the GQUEUE subsystem. */ #define GFX_USE_GQUEUE TRUE diff --git a/demos/modules/gwin/textedit/main.c b/demos/modules/gwin/textedit/main.c index ed52ccb2..4072f983 100644 --- a/demos/modules/gwin/textedit/main.c +++ b/demos/modules/gwin/textedit/main.c @@ -34,6 +34,9 @@ static GHandle ghTextedit1; static GHandle ghTextedit2; static GHandle ghTextedit3; static GListener gl; +#if GWIN_NEED_KEYBOARD + static GHandle ghKeyboard; +#endif static void guiCreate(void) { @@ -80,6 +83,17 @@ static void guiCreate(void) wi.text = "the different widgets"; ghTextedit3 = gwinTexteditCreate(0, &wi, 100); //gwinTexteditSetBorder(ghTextedit3, TRUE); + + // Virtual keyboard +#if GWIN_NEED_KEYBOARD + wi.g.show = TRUE; + wi.g.x = 0; + wi.g.y = gdispGetHeight()*3/4; + wi.g.width = gdispGetWidth(); + wi.g.height = gdispGetHeight()/4; + ghKeyboard = gwinKeyboardCreate(0, &wi); +#endif + } int main(void) { diff --git a/src/ginput/ginput_keyboard.h b/src/ginput/ginput_keyboard.h index 1349092f..40691a0d 100644 --- a/src/ginput/ginput_keyboard.h +++ b/src/ginput/ginput_keyboard.h @@ -164,13 +164,11 @@ typedef struct GEventKeyboard_t { #define GLISTEN_KEYTRANSITIONS 0x0008 // Return transitions to the key state #define GLISTEN_KEYRAW 0x0010 // Return raw scan-codes. This turns off normal character processing. -#endif - -#if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__) - // All keyboards #define GKEYBOARD_ALL_INSTANCES ((unsigned)-1) +#endif + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -188,33 +186,34 @@ extern "C" { */ GSourceHandle ginputGetKeyboard(unsigned instance); - /** - * @brief Get the current keyboard status - * - * @param[in] instance The ID of the keyboard input instance - * @param[in] pkeyboard The keyboard event struct - * - * @return Returns FALSE on an error (eg invalid instance) - */ - bool_t ginputGetKeyboardStatus(unsigned instance, GEventKeyboard *pkeyboard); + #if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__) - #if !GKEYBOARD_LAYOUT_OFF || defined(__DOXYGEN__) /** - * @brief Set the keyboard layout + * @brief Get the current keyboard status * * @param[in] instance The ID of the keyboard input instance - * @param[in] pLayout The keyboard layout micro-code. Passing NULL defaults to the driver's default layout. + * @param[in] pkeyboard The keyboard event struct * * @return Returns FALSE on an error (eg invalid instance) */ - bool_t ginputSetKeyboardLayout(unsigned instance, const void *pLayout); - #endif + bool_t ginputGetKeyboardStatus(unsigned instance, GEventKeyboard *pkeyboard); + + #if !GKEYBOARD_LAYOUT_OFF || defined(__DOXYGEN__) + /** + * @brief Set the keyboard layout + * + * @param[in] instance The ID of the keyboard input instance + * @param[in] pLayout The keyboard layout micro-code. Passing NULL defaults to the driver's default layout. + * + * @return Returns FALSE on an error (eg invalid instance) + */ + bool_t ginputSetKeyboardLayout(unsigned instance, const void *pLayout); + #endif + #endif /* GINPUT_NEED_KEYBOARD */ #ifdef __cplusplus } #endif -#endif /* GINPUT_NEED_KEYBOARD */ - #endif /* _GINPUT_KEYBOARD_H */ /** @} */ diff --git a/src/gwin/gwin_button.c b/src/gwin/gwin_button.c index 7705c4ce..4d83348e 100644 --- a/src/gwin/gwin_button.c +++ b/src/gwin/gwin_button.c @@ -50,7 +50,7 @@ } #endif -#if GINPUT_NEED_KEYBOARD +#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD static void ButtonKeyboard(GWidgetObject* gw, GEventKeyboard* pke) { // ENTER and SPACE keys to press the button @@ -113,7 +113,7 @@ static const gwidgetVMT buttonVMT = { 0, // Process mouse move events (NOT USED) }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { ButtonKeyboard // Process keyboard events }, diff --git a/src/gwin/gwin_checkbox.c b/src/gwin/gwin_checkbox.c index d6906b71..d477420b 100644 --- a/src/gwin/gwin_checkbox.c +++ b/src/gwin/gwin_checkbox.c @@ -55,7 +55,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) { } #endif -#if GINPUT_NEED_KEYBOARD +#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD static void CheckboxKeyboard(GWidgetObject* gw, GEventKeyboard* pke) { // Only react on KEYDOWN events. Ignore KEYUP events. @@ -108,7 +108,7 @@ static const gwidgetVMT checkboxVMT = { 0, // Process mouse move events (NOT USED) }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { CheckboxKeyboard // Process keyboard events }, diff --git a/src/gwin/gwin_class.h b/src/gwin/gwin_class.h index ad6df423..8aa5b9ff 100644 --- a/src/gwin/gwin_class.h +++ b/src/gwin/gwin_class.h @@ -96,7 +96,7 @@ typedef struct gwinVMT { void (*MouseMove) (GWidgetObject *gw, coord_t x, coord_t y); /**< Process mouse move events (optional) */ }; #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD struct { void (*KeyboardEvent) (GWidgetObject *gw, GEventKeyboard *pke); /**< Process keyboard events (optional) */ }; diff --git a/src/gwin/gwin_container.c b/src/gwin/gwin_container.c index 172b6ae8..89d09e9a 100644 --- a/src/gwin/gwin_container.c +++ b/src/gwin/gwin_container.c @@ -110,7 +110,7 @@ static const gcontainerVMT containerVMT = { 0, 0, 0, // No mouse }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_frame.c b/src/gwin/gwin_frame.c index f8787dcb..7400b0f5 100644 --- a/src/gwin/gwin_frame.c +++ b/src/gwin/gwin_frame.c @@ -178,7 +178,7 @@ static const gcontainerVMT frameVMT = { 0, // Process mouse move events }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_keyboard.c b/src/gwin/gwin_keyboard.c index c27580de..70771d9b 100644 --- a/src/gwin/gwin_keyboard.c +++ b/src/gwin/gwin_keyboard.c @@ -30,6 +30,8 @@ typedef uint32_t utf32; // A character code - note this is not UTF-32 but a representation of the UTF-8 code stream for a single character. typedef uint32_t ucode; +static GSourceHandle AllKeyboards; + // Get the length of a UTF-8 string static int UTF8StrLen(const utf8 *s) { int len; @@ -164,6 +166,11 @@ static void SendKeyboardEventToListener(GSourceListener *psl, GKeyboardObject *g static void SendKeyboardEvent(GKeyboardObject *gk) { GSourceListener *psl; + // Send to the "All Keyboards" source listeners + psl = 0; + while ((psl = geventGetSourceListener(AllKeyboards, psl))) + SendKeyboardEventToListener(psl, gk); + // Send to the keyboard specific source listeners psl = 0; while ((psl = geventGetSourceListener((GSourceHandle)gk, psl))) @@ -313,7 +320,7 @@ static const gwidgetVMT keyboardVMT = { KeyMouseMove, // Process mouse move events }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, @@ -344,6 +351,10 @@ GHandle gwinGKeyboardCreate(GDisplay *g, GKeyboardObject *gk, const GWidgetInit gk->keytable = &GWIN_KEYBOARD_DEFAULT_LAYOUT; gk->keyset = gk->keytable->ksets[0]; gk->lastkeyrow = gk->lastkeycol = gk->keyrow = gk->keycol = GKEY_BAD_ROWCOL; + + if (!AllKeyboards) + AllKeyboards = ginputGetKeyboard(GKEYBOARD_ALL_INSTANCES); + gwinSetVisible((GHandle)gk, pInit->g.show); return (GHandle)gk; } @@ -473,4 +484,12 @@ void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) { #undef gk } +#if !(GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) + GSourceHandle ginputGetKeyboard(unsigned instance) { + if (instance == GKEYBOARD_ALL_INSTANCES) + return (GSourceHandle)&AllKeyboards; + return 0; + } +#endif + #endif /* GFX_USE_GWIN && GWIN_NEED_KEYBOARD */ diff --git a/src/gwin/gwin_label.c b/src/gwin/gwin_label.c index 38d9b601..b78e4b3b 100644 --- a/src/gwin/gwin_label.c +++ b/src/gwin/gwin_label.c @@ -58,7 +58,7 @@ static const gwidgetVMT labelVMT = { 0, // Process mouse move events (NOT USED) }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard key down events }, diff --git a/src/gwin/gwin_list.c b/src/gwin/gwin_list.c index 3ea6286c..88d3028a 100644 --- a/src/gwin/gwin_list.c +++ b/src/gwin/gwin_list.c @@ -279,7 +279,7 @@ static const gwidgetVMT listVMT = { ListMouseMove, }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_progressbar.c b/src/gwin/gwin_progressbar.c index 3843949a..0de69867 100644 --- a/src/gwin/gwin_progressbar.c +++ b/src/gwin/gwin_progressbar.c @@ -51,7 +51,7 @@ static const gwidgetVMT progressbarVMT = { 0, // Process mouse move events }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_radio.c b/src/gwin/gwin_radio.c index fcdb242b..470a1f2a 100644 --- a/src/gwin/gwin_radio.c +++ b/src/gwin/gwin_radio.c @@ -92,7 +92,7 @@ static const gwidgetVMT radioVMT = { 0, // Process mouse move events (NOT USED) }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_rules.h b/src/gwin/gwin_rules.h index 3426eb67..ea35a426 100644 --- a/src/gwin/gwin_rules.h +++ b/src/gwin/gwin_rules.h @@ -127,8 +127,8 @@ #if !GDISP_NEED_TEXT #error "GWIN: GDISP_NEED_TEXT is required if GWIN_NEED_TEXTEDIT is TRUE." #endif - #if !GINPUT_NEED_KEYBOARD - #error "GWIN: GINPUT_NEED_KEYBOARD is required if GWIN_NEED_TEXTEDIT is TRUE." + #if !(GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD) + #error "GWIN: GINPUT_NEED_KEYBOARD or GWIN_NEED_KEYBOARD is required if GWIN_NEED_TEXTEDIT is TRUE." #endif #endif #endif diff --git a/src/gwin/gwin_slider.c b/src/gwin/gwin_slider.c index 218f4f6b..c8f47f95 100644 --- a/src/gwin/gwin_slider.c +++ b/src/gwin/gwin_slider.c @@ -250,7 +250,7 @@ static const gwidgetVMT sliderVMT = { SliderMouseMove, // Process mouse move events }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_tabset.c b/src/gwin/gwin_tabset.c index f8731f8f..d059256d 100644 --- a/src/gwin/gwin_tabset.c +++ b/src/gwin/gwin_tabset.c @@ -77,7 +77,7 @@ static const gcontainerVMT tabpageVMT = { 0, // Process mouse move events }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { 0 // Process keyboard events }, diff --git a/src/gwin/gwin_textedit.c b/src/gwin/gwin_textedit.c index 1395ab71..c1373897 100644 --- a/src/gwin/gwin_textedit.c +++ b/src/gwin/gwin_textedit.c @@ -61,7 +61,7 @@ static void _shiftTextRight(char* buffer, size_t maxSize, size_t index, char fil } -#if GINPUT_NEED_KEYBOARD +#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD static void TextEditKeyboard(GWidgetObject* gw, GEventKeyboard* pke) { // Only react on KEYDOWN events. Ignore KEYUP events. @@ -146,7 +146,7 @@ static const gwidgetVMT texteditVMT = { 0, // Process mouse move events (NOT USED) }, #endif - #if GINPUT_NEED_KEYBOARD + #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD { TextEditKeyboard // Process keyboard key down events },