From 7a479e4f451cc1f8a63025aa37cf4b29a7b5fb6b Mon Sep 17 00:00:00 2001 From: Lephe Date: Tue, 7 Jan 2025 21:14:51 +0100 Subject: [PATCH] keydev: support for the Math+ layout and track row/col key_event_t is now 8 bytes instead of 4, a change that was doomed to happen anyway to deal with touch input (where it's not clear either whether 8 bytes will be enough for double touch). --- include/gint/drivers/keydev.h | 2 ++ include/gint/keyboard.h | 17 ++++++++--- include/gint/keycodes.h | 19 ++++++++++-- src/keysc/keydev.c | 56 +++++++++++++++++++++++++++-------- 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/include/gint/drivers/keydev.h b/include/gint/drivers/keydev.h index 4d9b956..0e15645 100644 --- a/include/gint/drivers/keydev.h +++ b/include/gint/drivers/keydev.h @@ -184,6 +184,8 @@ typedef struct { /* Candidate key for repeats (or 0 if no key is candidate yet) */ int16_t rep_key; + /* Matrix code for rep_key, if rep_key is not 0. */ + uint8_t rep_row, rep_col; /* Number of repeats already sent */ int16_t rep_count; /* Time since key was first pressed (us) */ diff --git a/include/gint/keyboard.h b/include/gint/keyboard.h index 4bf8b3f..06170d8 100644 --- a/include/gint/keyboard.h +++ b/include/gint/keyboard.h @@ -114,16 +114,25 @@ extern "C" { * 0xffff is "just before" 0x0000, not "long after". */ typedef struct { - uint time :16; /* Time of event, unique over short periods */ + /* Time of event, unique over short periods */ + u16 time; uint :2; /* Reserved for future use */ - uint mod :1; /* Whether modifiers are used */ uint shift :1; /* If mod=1, whether SHIFT was pressed */ uint alpha :1; /* If mod=1, whether ALPHA was pressed */ - uint type :3; /* Type of key event */ - uint key :8; /* Hit key */ + + /* Key that was pressed or released. */ + u8 key; + + // The following attributes will be union'd with touch info on the CP. + + /* Matrix code: physical location of the key being it. */ + u8 row, col; + + /* Reserved for future use. */ + uint :16; } GPACKED(4) key_event_t; diff --git a/include/gint/keycodes.h b/include/gint/keycodes.h index 5e904fa..dc2dd3f 100644 --- a/include/gint/keycodes.h +++ b/include/gint/keycodes.h @@ -9,7 +9,6 @@ extern "C" { #endif -/* Raw matrix codes */ enum { KEY_F1 = 0x91, KEY_F2 = 0x92, @@ -87,7 +86,23 @@ enum { KEY_EQUALS = 0xa5, KEY_CLEAR = KEY_EXIT, - /* Key aliases (handle with care =D) */ + /* Key codes for the CG-100 */ + KEY_ON = 0xa6, + KEY_HOME = KEY_MENU, + KEY_PREVTAB = 0xa7, + KEY_NEXTTAB = 0xa8, + KEY_PAGEUP = 0xa9, + KEY_PAGEDOWN = 0xaa, + KEY_SETTINGS = 0xab, + KEY_BACK = KEY_EXIT, + KEY_OK = 0xac, + KEY_CATALOG = 0xad, + KEY_TOOLS = KEY_OPTN, + KEY_FORMAT = KEY_FD, + KEY_SQRT = 0xae, + KEY_EXPFUN = 0xaf, + + /* Key aliases (deprecated--no more will be added) */ KEY_X2 = KEY_SQUARE, KEY_CARET = KEY_POWER, KEY_SWITCH = KEY_FD, diff --git a/src/keysc/keydev.c b/src/keysc/keydev.c index 4edee84..1071458 100644 --- a/src/keysc/keydev.c +++ b/src/keysc/keydev.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -45,12 +46,39 @@ static void keycode_to_keymatrix(int keycode, int *row, int *col) *col = 0; } #else -static GINLINE int keymatrix_to_keycode(int row, int col) +static uint8_t const CG100_keymap[] = { + KEY_ON, KEY_HOME, KEY_PREVTAB, KEY_UP, KEY_NEXTTAB, KEY_PAGEUP, + KEY_SETTINGS, KEY_BACK, KEY_LEFT, KEY_OK, KEY_RIGHT, KEY_PAGEDOWN, + KEY_SHIFT, KEY_ALPHA, KEY_VARS, KEY_DOWN, KEY_CATALOG, KEY_TOOLS, + KEY_XOT, KEY_FRAC, KEY_SQRT, KEY_POWER, KEY_SQUARE, KEY_EXPFUN, + KEY_COMMA, KEY_SIN, KEY_COS, KEY_TAN, KEY_LEFTP, KEY_RIGHTP, +}; +static int keymatrix_to_keycode(int row, int col) { + if(gint[HWCALC] == HWCALC_FXCG100) { + if(row >= 7 && row <= 9) + return CG100_keymap[6 * (9-row) + (6-col)]; + if(row == 1 && col == 3) + return KEY_FORMAT; + } return (row << 4) + (7 - col); } -static GINLINE void keycode_to_keymatrix(int keycode, int *row, int *col) +static void keycode_to_keymatrix(int keycode, int *row, int *col) { + if(gint[HWCALC] == HWCALC_FXCG100) { + if(keycode == KEY_FORMAT) { + *row = 1; + *col = 3; + return; + } + for(int i = 0; i < (int)sizeof(CG100_keymap); i++) { + if(CG100_keymap[i] == keycode) { + *row = 9 - i / 6; + *col = 6 - (i % 6); + return; + } + } + } *row = keycode >> 4; *col = 7 - (keycode & 7); } @@ -125,6 +153,8 @@ void keydev_process_state(keydev_t *d, uint8_t scan[12]) for(int mask = 0x80, col = 7; mask; mask >>= 1, col--) { + ev.row = row; + ev.col = col; ev.key = keymatrix_to_keycode(row, col); /* Update state only if the push succeeds */ if((diff & mask) && keydev_queue_push(d, ev)) @@ -173,6 +203,8 @@ key_event_t keydev_repeat_event(keydev_t *d) ev.type = KEYEV_HOLD; ev.key = d->rep_key; + ev.row = d->rep_row; + ev.col = d->rep_col; return ev; } @@ -188,11 +220,11 @@ void keydev_tick(keydev_t *d, uint us) /* Disable repeat if the repeating key was released */ if(d->rep_key != 0) { - int row, col; - keycode_to_keymatrix(d->rep_key, &row, &col); - if(!(d->state_now[row] & (1 << col))) + if(!(d->state_now[d->rep_row] & (1 << d->rep_col))) { d->rep_key = 0; + d->rep_row = 0; + d->rep_col = 0; d->rep_count = -1; d->rep_time = -1; d->rep_delay = -1; @@ -232,18 +264,18 @@ key_event_t keydev_unqueue_event(keydev_t *d) return ev; /* Update the event state accordingly */ - int row, col; - keycode_to_keymatrix(ev.key, &row, &col); - int mask = 1 << col; + int mask = 1 << ev.col; if(ev.type == KEYEV_DOWN) { - d->state_queue[row] |= mask; - d->state_flips[row] ^= mask; + d->state_queue[ev.row] |= mask; + d->state_flips[ev.row] ^= mask; /* Mark this key as the currently repeating one */ if(d->rep_key == 0 && can_repeat(d, ev.key)) { d->rep_key = ev.key; + d->rep_row = ev.row; + d->rep_col = ev.col; d->rep_count = -1; d->rep_time = 0; d->rep_delay = 0; @@ -251,8 +283,8 @@ key_event_t keydev_unqueue_event(keydev_t *d) } else if(ev.type == KEYEV_UP) { - d->state_queue[row] &= ~mask; - d->state_flips[row] ^= mask; + d->state_queue[ev.row] &= ~mask; + d->state_flips[ev.row] ^= mask; } return ev;