13 #include "../../gfx.h"
15 #if GFX_USE_GWIN && GWIN_NEED_KEYBOARD
17 #include "gwin_class.h"
27 static GSourceHandle AllKeyboards;
30 static int UTF8StrLen(
const utf8 *s) {
39 else if ((s[0] & 0xE0) == 0xC0 && (s[1] & 0xC0) == 0x80)
41 else if ((s[0] & 0xF0) == 0xE0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80)
43 else if ((s[0] & 0xF8) == 0xF0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80 && (s[3] & 0xC0) == 0x80)
54 static ucode UTF8CharAt(
const utf8 *s,
int n) {
64 }
else if ((s[0] & 0xE0) == 0xC0 && (s[1] & 0xC0) == 0x80) {
65 u = s[1] | ((ucode)s[0] << 8);
67 }
else if ((s[0] & 0xF0) == 0xE0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80) {
68 u = s[2] | ((ucode)s[1] << 8) | ((ucode)s[0] << 16);
70 }
else if ((s[0] & 0xF8) == 0xF0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80 && (s[3] & 0xC0) == 0x80) {
71 u = s[3] | ((ucode)s[2] << 8) | ((ucode)s[1] << 16) | ((ucode)s[0] << 24);
85 static unsigned UCode2UTF8(utf8 *dst, ucode u) {
86 if (!(u & 0xFFFFFF00)) {
90 if (!(u & 0xFFFF0000)) {
95 if (!(u & 0xFF000000)) {
108 static int NumKeyRows(
const char **keyset) {
117 static void SendVirtualKeyEventToListener(GSourceListener *psl,
GKeyboardObject *gk) {
125 psl->srcflags |= GKEYSTATE_MISSED_EVENT;
145 pe->type = GEVENT_KEYBOARD;
146 if (gk->key < 0x20) {
147 skey = &gk->keytable->skeys[gk->key-1];
148 for(i=0; skey->sendkey[i]; i++)
149 pe->c[i] = skey->sendkey[i];
151 i = UCode2UTF8((utf8 *)pe->c, gk->key);
155 pe->keystate = psl->srcflags;
161 GSourceListener *psl;
166 SendVirtualKeyEventToListener(psl, gk);
171 SendVirtualKeyEventToListener(psl, gk);
175 #if GINPUT_NEED_MOUSE
182 if (x < 0 || y < 0 || x >= gk->w.
g.
width || y >= gk->w.
g.
height) {
183 gk->keyrow = gk->keycol = GKEY_BAD_ROWCOL;
189 gk->keyrow =
FIXED(y) / f;
190 gk->keyy = NONFIXED(f * gk->keyrow + FIXED0_5);
191 gk->keycy = NONFIXED(f * (gk->keyrow+1) + FIXED0_5) - gk->keyy;
194 krow = (
const utf8 *)gk->keyset[gk->keyrow];
198 gk->keycol =
FIXED(x) / f;
201 gk->key = UTF8CharAt(krow, gk->keycol);
205 while(gk->keycol > 0 && UTF8CharAt(krow, gk->keycol-1) == gk->key)
207 while(UTF8CharAt(krow, ++idx) == gk->key);
208 gk->keyx = NONFIXED(f * gk->keycol + FIXED0_5);
209 gk->keycx = NONFIXED(f * idx + FIXED0_5) - gk->keyx;
214 #define gk ((GKeyboardObject *)gw)
216 KeyFindKey(gk, x, y);
219 if (gk->keyrow == GKEY_BAD_ROWCOL) {
220 if (gk->lastkeyrow != GKEY_BAD_ROWCOL) {
221 gw->
g.
flags |= GKEYBOARD_FLG_QUICKUPDATE;
228 gk->keyrow = gk->keycol = GKEY_BAD_ROWCOL;
231 if (gk->key < 0x20) {
235 skey = &gk->keytable->skeys[gk->key - 1];
237 if ((skey->flags & GVKEY_SINGLESET)) {
239 gk->keyset = gk->keytable->ksets[skey->newset];
243 }
else if ((skey->flags & GVKEY_LOCKSET)) {
245 gk->keyset = gk->keytable->ksets[skey->newset];
250 gk->keyset = gk->keytable->ksets[0];
255 gw->
g.
flags |= GKEYBOARD_FLG_QUICKUPDATE;
259 if (skey->sendkey && skey->sendkey[0])
260 SendVirtualKeyEvent(gk);
270 gk->keyset = gk->keytable->ksets[0];
273 gw->
g.
flags |= GKEYBOARD_FLG_QUICKUPDATE;
277 SendVirtualKeyEvent(gk);
285 #define gk ((GKeyboardObject *)gw)
287 KeyFindKey(gk, x, y);
289 if (gk->keyrow != gk->lastkeyrow || gk->keycol != gk->lastkeycol) {
290 gk->w.
g.
flags |= GKEYBOARD_FLG_QUICKUPDATE;
309 #if GINPUT_NEED_MOUSE
316 #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
321 #if GINPUT_NEED_TOGGLE
341 if (!(gk = (
GKeyboardObject *)_gwidgetCreate(g, &gk->w, pInit, &keyboardVMT)))
345 gk->keyset = gk->keytable->ksets[0];
346 gk->lastkeyrow = gk->lastkeycol = gk->keyrow = gk->keycol = GKEY_BAD_ROWCOL;
358 return (GSourceHandle)gh;
362 #define gk ((GKeyboardObject *)gh)
369 gk->keytable = layout;
370 gk->keyset = gk->keytable->ksets[0];
371 gk->lastkeyrow = gk->lastkeycol = gk->keyrow = gk->keycol = GKEY_BAD_ROWCOL;
390 #define gk ((GKeyboardObject *)gw)
396 gU8 rows, cols, row, col, kcols;
408 rows = NumKeyRows(gk->keyset);
410 for (row = 0; row < rows; row++) {
411 y = NONFIXED(fy * row + FIXED0_5);
412 cy = NONFIXED(fy * (row+1) + FIXED0_5) - y;
415 krow = (
const utf8 *)gk->keyset[row];
418 cols = UTF8StrLen(krow);
420 for (col = 0; col < cols; col=kcols) {
423 if (!(gk->w.
g.
flags & GWIN_FLG_SYSENABLED))
429 key = UTF8CharAt(krow, col);
433 while (UTF8CharAt(krow, kcols) == key)
437 if ( (gk->w.
g.
flags & GKEYBOARD_FLG_QUICKUPDATE) && !(gk->w.
g.
flags & GWIN_FLG_BGREDRAW) ) {
440 if ( (gk->keyrow != GKEY_BAD_ROWCOL) && (gk->keycol != GKEY_BAD_ROWCOL) ) {
443 if ( (gk->lastkeyrow != GKEY_BAD_ROWCOL) && (gk->lastkeycol != GKEY_BAD_ROWCOL) ) {
445 if (gk->lastkeyrow == row && gk->lastkeycol == col) {
449 gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
458 if (gk->keyrow == row && gk->keycol == col) {
461 gk->lastkeyrow = row;
462 gk->lastkeycol = col;
464 else if (gk->lastkeyrow == row && gk->lastkeycol == col)
473 else if ( (gk->lastkeyrow != GKEY_BAD_ROWCOL) && (gk->lastkeycol != GKEY_BAD_ROWCOL) )
475 if ( (gk->lastkeyrow == row) && (gk->lastkeycol == col) )
484 gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
487 x = NONFIXED(fx * col + FIXED0_5);
488 cx = NONFIXED(fx * kcols + FIXED0_5) - x;
491 pcap = gk->keytable->skeys[key-1].keycap;
493 cap[UCode2UTF8((utf8 *)cap, key)] = 0;
564 if ( (gk->keyrow == GKEY_BAD_ROWCOL) && (gk->keycol == GKEY_BAD_ROWCOL) && (gk->lastkeyrow == row) && (gk->lastkeycol == col) ) {
565 gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
570 if ( (row >= gk->keyrow && col >= gk->keycol) && (row >= gk->lastkeyrow && col >= gk->lastkeycol) ) {
579 #if !(GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD)
581 if (instance == GKEYBOARD_ALL_INSTANCES)
582 return (GSourceHandle)&AllKeyboards;
void gdispGFillArea(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gColor color)
Fill an area with a color.
void gdispGDrawLine(GDisplay *g, gCoord x0, gCoord y0, gCoord x1, gCoord y1, gColor color)
Draw a line.
void gdispGFillStringBox(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, const char *str, gFont font, gColor color, gColor bgColor, gJustify justify)
Draw a text string vertically centered within the specified box. The box background is filled with th...
gI16 gCoord
The type for a coordinate or length on the screen.
void gdispGDrawBox(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gColor color)
Draw a rectangular box.
GEvent * geventGetEventBuffer(GSourceListener *psl)
Get the event buffer from the GSourceListener.
void geventSendEvent(GSourceListener *psl)
Called by a source to indicate the listener's event buffer has been filled.
GSourceListener * geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr)
Called by a source with a possible event to get a listener record.
gI32 fixed
The type for a fixed point type.
#define FIXED(x)
Macros to convert to and from a fixed point.
#define GWIN_KEYBOARD_DEFAULT_LAYOUT
The default keyboard layout for the virtual gwin keyboard.
GSourceHandle ginputGetKeyboard(unsigned instance)
Create a keyboard input instance.
void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param)
The default rendering function for the keyboard widget.
#define GKEYBOARD_FLG_REVERTSET
The internal keyboard flags and other defines.
GHandle gwinGKeyboardCreate(GDisplay *g, GKeyboardObject *gb, const GWidgetInit *pInit)
Create a keyboard widget.
void gwinKeyboardSetLayout(GHandle gh, const struct GVKeyTable *layout)
Set the layout for the virtual keyboard.
struct GKeyboardObject GKeyboardObject
The keyboard widget structure.
GSourceHandle gwinKeyboardGetEventSource(GHandle gh)
Get the keyboard event source for a GWIN virtual keyboard.
void gwinRedraw(GHandle gh)
Redraw a window.
void gwinSetVisible(GHandle gh, gBool visible)
Sets whether a window is visible or not.
GWIN Virtual Keyboard Layout structures.
The keyboard widget structure.
A window object structure.
const struct gwinVMT * vmt
The Virtual Method Table for a GWIN window.