From d942fc45e21900cf6bcc8f94d8a6af2cd792ec75 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Aug 15 2023 08:17:24 +0000 Subject: key clones --- diff --git a/app.c b/app.c index a35983b..0af0ad3 100644 --- a/app.c +++ b/app.c @@ -173,9 +173,9 @@ int appRun(App *app) { LOGDBG("app: draw: x=%d, y=%d, w=%d, h=%d", app->irx, app->iry, app->irw, app->irh); graphDrawBackgound(&app->graph, app->irx, app->iry, app->irw, app->irh); keyboardDraw(&app->keyboard, app->irx, app->iry, app->irw, app->irh); - xcb_flush(app->xcb); app->irw = 0; } + xcb_flush(app->xcb); } int err = app->run == -2; diff --git a/input.c b/input.c index c8a1cdb..01b303a 100644 --- a/input.c +++ b/input.c @@ -15,7 +15,6 @@ void inputPrepareKeysyms(unsigned int *ks0, unsigned int *ks1, int *isLetter, int *isKeypad) { if (!*ks0) *ks0 = *ks1; - *isKeypad = (0xFF80 <= *ks1 && *ks1 <= 0xFFBD) || (0x11000000 <= *ks1 && *ks1 <= 0x1100FFFF); *isLetter = 0; if (*ks0) { KeySym kl = 0, ku = 0; @@ -27,6 +26,7 @@ void inputPrepareKeysyms(unsigned int *ks0, unsigned int *ks1, int *isLetter, in } if (!*ks1) *ks1 = *ks0; + *isKeypad = (0xFF80 <= *ks1 && *ks1 <= 0xFFBD) || (0x11000000 <= *ks1 && *ks1 <= 0x1100FFFF); } diff --git a/keyboard.c b/keyboard.c index d09a1f8..b762574 100644 --- a/keyboard.c +++ b/keyboard.c @@ -10,6 +10,8 @@ int keyInit(Key *k, Layout *l) { k->mx = k->my = 0; k->isLetter = k->isKeypad = 0; k->x = k->y = k->w = k->h = 0; + k->prevHeld = k->nextHeld = NULL; + k->orig = k->clone = NULL; inputPrepareKeysyms(&k->keySym, &k->keySym2, &k->isLetter, &k->isKeypad); if (!k->label[0]) keysymString(k->keySym, k->label); @@ -29,6 +31,15 @@ void keyDeinit(Key *k) { } +void keyInvalidateRect(Key* k) { + if (k->orig) k = k->orig; + while(k) { + appInvalidateRect(k->l->kbd->app, k->x, k->y, k->w, k->h); + k = k->clone; + } +} + + void keyDraw(Key *k, int cx, int cy, int cw, int ch) { if ( k->x + k->w <= cx || k->x >= cx + cw || k->y + k->h <= cy || k->y >= cy + ch ) return; @@ -36,6 +47,8 @@ void keyDraw(Key *k, int cx, int cy, int cw, int ch) { App *app = k->l->kbd->app; int active = k->down; + if (k->orig) + active = k->orig->down; if (!active && (k->flags & KF_MOD)) active = (app->input.modifiers & (unsigned int)k->optValue); @@ -63,6 +76,8 @@ void keyDraw(Key *k, int cx, int cy, int cw, int ch) { void keyDown(Key *k, int x, int y) { + if (k->orig) + return keyDown(k->orig, x, y); if (k->down == 2) k->down = 1; if (k->down) return; @@ -99,11 +114,13 @@ void keyDown(Key *k, int x, int y) { } // redraw - appInvalidateRect(kbd->app, k->x, k->y, k->w, k->h); + keyInvalidateRect(k); } void keyMotion(Key *k, int x, int y) { + if (k->orig) + return keyMotion(k->orig, x, y); App *app = k->l->kbd->app; if (k->flags & KF_MOVE) { appMove(app, app->x + x - k->mx, app->y + y - k->my, app->w, app->h); @@ -115,7 +132,13 @@ void keyMotion(Key *k, int x, int y) { void keyUp(Key *k, int force) { - if (!force && k->down != 1) return; + if (k->orig) { + // clones must not be in held list + assert( !(k->prevHeld || k->nextHeld || k->l->kbd->firstHeld == k) ); + return keyUp(k->orig, force); + } + if (!force && k->down != 1) + return; Keyboard *kbd = k->l->kbd; int wasDown = k->down; @@ -127,6 +150,7 @@ void keyUp(Key *k, int force) { k->downKeycode = 0; } + // remove from held list if (k->prevHeld || k->nextHeld || kbd->firstHeld == k) { if (k->nextHeld) k->nextHeld->prevHeld = k->prevHeld; @@ -148,7 +172,7 @@ void keyUp(Key *k, int force) { keyboardRelaseHeld(kbd); // redraw - appInvalidateRect(kbd->app, k->x, k->y, k->w, k->h); + keyInvalidateRect(k); } @@ -292,6 +316,27 @@ int keyboardInit(Keyboard *kbd, App *app) { } LOGDBG("keyboard: init: size ow=%d oh=%d", kbd->ow, kbd->oh); + // search clones + for(int ila = 0; ila < kbd->layoutsCount; ++ila) + for(int ika = 0; ika < kbd->layouts[ila].keysCount; ++ika) { + Key *a = &kbd->layouts[ila].keys[ika]; + + if (!a->orig) + for(int ilb = ila; ilb < kbd->layoutsCount; ++ilb) + for(int ikb = ilb==ila ? ika+1: 0; ikb < kbd->layouts[ilb].keysCount; ++ikb) { + Key *b = &kbd->layouts[ilb].keys[ikb]; + if ( a->flags == b->flags + && a->optValue == b->optValue + && a->keySym == b->keySym + && a->keySym2 == b->keySym2 ) + { + b->orig = a; + b->clone = a->clone; + a->clone = b; + } + } + } + //appMove(app, app->x, app->y, kbd->ow, kbd->oh); return 1; } @@ -353,24 +398,28 @@ void keyboardRelaseHeld(Keyboard *kbd) { void keyboardSwitchLayout(Keyboard *kbd, int index) { - LOGDBG("keyboard: switch layout"); if (!kbd->layoutsCount) return; - keyboardRelaseHeld(kbd); + + int prevIndex = kbd->current - kbd->layouts; + int remember = 1; + + LOGDBG("keyboard: switch layout: prevIndex=%d nextIndex=%d", prevIndex, index); + //keyboardRelaseHeld(kbd); if (index == LI_PREV) { - index = kbd->current ? kbd->current - kbd->layouts - 1: 0; + index = kbd->current ? prevIndex - 1: 0; if (index < 0) index = kbd->layoutsCount - 1; } else if (index == LI_NEXT) { - index = kbd->current ? kbd->current - kbd->layouts + 1: 0; + index = kbd->current ? prevIndex + 1: 0; if (index >= kbd->layoutsCount) index = 0; } else if (index == LI_REVERT) { - if (kbd->current && kbd->current->prev) - kbd->current = kbd->current->prev; - keyboardResize(kbd); - appInvalidateRect(kbd->app, 0, 0, kbd->app->w, kbd->app->h); + if (!kbd->current || !kbd->current->prev) + return; + index = kbd->current->prev - kbd->layouts; + remember = 0; return; } @@ -379,7 +428,9 @@ void keyboardSwitchLayout(Keyboard *kbd, int index) { return; } - kbd->layouts[index].prev = kbd->current; + LOGDBG("keyboard: switch layout: actual index=%d", index); + if (remember) + kbd->layouts[index].prev = kbd->current; kbd->current = &kbd->layouts[index]; keyboardResize(kbd); diff --git a/keyboard.h b/keyboard.h index 178d77c..7349ea9 100644 --- a/keyboard.h +++ b/keyboard.h @@ -57,6 +57,7 @@ struct Key { int downKeycode; int mx, my; // values for move and size buttons Key *nextHeld, *prevHeld; + Key *orig, *clone; }; @@ -94,6 +95,7 @@ struct Keyboard { int keyInit(Key *k, Layout *l); void keyDeinit(Key *k); +void keyInvalidateRect(Key *k); void keyDraw(Key *k, int cx, int cy, int cw, int ch); void keyDown(Key *k, int x, int y); void keyMotion(Key *k, int x, int y); diff --git a/layout.en.full.inc.c b/layout.en.full.inc.c index d9a0b49..7258c02 100644 --- a/layout.en.full.inc.c +++ b/layout.en.full.inc.c @@ -11,6 +11,7 @@ Key keysEnFull[] = { HEADER(LEF_FW) + { S, Y, W, H, XK_Escape, 0, "Esc" }, { N-W, 0, 0, 0, XK_F1, 0, "F1" }, { N, 0, 0, 0, XK_F2, 0, "F2" }, @@ -24,6 +25,7 @@ Key keysEnFull[] = { { N, 0, 0, 0, XK_F10, 0, "F10" }, { N, 0, 0, 0, XK_F11, 0, "F11" }, { N, 0, 0, 0, XK_F12, 0, "F12" }, + { S, N-S, W2, H, XK_grave, XK_asciitilde }, { N, 0, W, 0, XK_1, XK_exclam }, { N, 0, 0, 0, XK_2, XK_at }, @@ -38,6 +40,7 @@ Key keysEnFull[] = { { N, 0, 0, 0, XK_minus, XK_underscore }, { N, 0, 0, 0, XK_equal, XK_plus }, { N, 0, W2, 0, XK_BackSpace, 0, "<-Bksp" }, + { S, N, W2, 0, XK_Tab, 0, "->|" }, { N, 0, W, 0, XK_q }, { N, 0, 0, 0, XK_w }, @@ -52,6 +55,7 @@ Key keysEnFull[] = { { N, 0, 0, 0, XK_bracketleft, XK_braceleft }, { N, 0, 0, 0, XK_bracketright, XK_braceright }, { N, 0, W2, H2, XK_Return, 0, "Enter" }, + { S, Y4+S, W2, H, XK_Caps_Lock, 0, "Caps Lock", "", KF_MOD, IM_CAPSLOCK_BIT }, { N, 0, W, 0, XK_a }, { N, 0, 0, 0, XK_s }, @@ -65,6 +69,7 @@ Key keysEnFull[] = { { N, 0, 0, 0, XK_semicolon, XK_colon }, { N, 0, 0, 0, XK_apostrophe, XK_quotedbl }, { N, 0, 0, 0, XK_backslash, XK_bar }, + { S, N, W4, 0, XK_Shift_L, 0, "Shift", "", KF_HOLD }, { N, 0, W, 0, XK_z }, { N, 0, 0, 0, XK_x }, @@ -77,6 +82,7 @@ Key keysEnFull[] = { { N, 0, 0, 0, XK_period, XK_greater }, { N, 0, 0, 0, XK_slash, XK_question }, { N, 0, W4, 0, XK_Shift_R, 0, "Shift", "", KF_HOLD }, + { S, N, W2, 0, XK_Control_L, 0, "Ctrl", "", KF_HOLD }, { N, 0, W2, 0, XK_Alt_L, 0, "Alt", "", KF_HOLD }, { N, 0, W2, 0, 0, 0, "<--", "", KF_LAYOUT, LI_PREV }, @@ -84,36 +90,50 @@ Key keysEnFull[] = { { N, 0, W2, 0, 0, 0, "-->", "", KF_LAYOUT, LI_NEXT }, { N, 0, W2, 0, XK_Alt_R, 0, "Alt", "", KF_HOLD }, { N, 0, W2, 0, XK_Control_R, 0, "Ctrl", "", KF_HOLD }, + + // col 2 + { LEF_COL2, Y, W, 0, XK_Print, 0, "PrtScr" }, { N, 0, 0, 0, XK_Scroll_Lock, 0, "ScrLk", "", KF_MOD, IM_SCRLOCK_BIT }, { N, 0, 0, 0, XK_Pause, 0, "Pause" }, + { LEF_COL2, N-S, 0, 0, XK_Insert, 0, "Ins" }, { N, 0, 0, 0, XK_Home, 0, "Home" }, { N, 0, 0, 0, XK_Page_Up, 0, "PgUp" }, + { LEF_COL2, N, 0, 0, XK_Delete, 0, "Del" }, { N, 0, 0, 0, XK_End, 0, "End" }, { N, 0, 0, 0, XK_Page_Down, 0, "PgDn" }, { LEF_COL2+W+S, N-H-S, 0, 0, XK_Up, 0, "↑" }, + { LEF_COL2, N, 0, 0, XK_Left, 0, "←" }, { N, 0, 0, 0, XK_Down, 0, "↓" }, { N, 0, 0, 0, XK_Right, 0, "→" }, + + // col3 + { LEF_COL3, Y+H+2*S, 0, 0, XK_Num_Lock, 0, "NumLk", "", KF_MOD, IM_NUMLOCK_BIT }, { N, 0, 0, 0, XK_KP_Divide, 0, "/" }, { N, 0, 0, 0, XK_KP_Multiply, 0, "*" }, { N, 0, 0, 0, XK_KP_Subtract, 0, "-" }, + { LEF_COL3, N, 0, 0, XK_KP_Home, XK_KP_7, "Home", "7" }, { N, 0, 0, 0, XK_KP_Up, XK_KP_8, "↑", "8" }, { N, 0, 0, 0, XK_KP_Page_Down, XK_KP_9, "PgDn", "9" }, { N, 0, 0, H2, XK_KP_Add, 0, "+" }, + { LEF_COL3, Y4+S, 0, H, XK_KP_Left, XK_KP_4, "←", "4" }, { N, 0, 0, 0, 0, XK_KP_5, "", "5" }, { N, 0, 0, 0, XK_KP_Right, XK_KP_6, "→", "6" }, + { LEF_COL3, N, 0, 0, XK_KP_End, XK_KP_1, "End", "1" }, { N, 0, 0, 0, XK_KP_Down, XK_KP_2, "↓", "2" }, { N, 0, 0, 0, XK_KP_Page_Down, XK_KP_3, "PgDn", "2" }, { N, 0, 0, H2, XK_KP_Enter, 0, "Enter" }, + { LEF_COL3, Y6+S, 2*W+S, H, XK_KP_Insert, XK_KP_0, "Ins", "0" }, { N, 0, W, 0, XK_KP_Delete, XK_KP_Decimal, "Del", "." }, + FOOTER(LEF_FW) };