Changeset 9e9d9bc6 in mainline for uspace/drv/hid/xtkbd/xtkbd.c


Ignore:
Timestamp:
2022-06-27T16:13:45Z (22 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0d59ea7e
Parents:
bb4ba92
Message:

XT keyboard scancode parsing needs some work

Properly decode fake shift as well as Pause sequences.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/hid/xtkbd/xtkbd.c

    rbb4ba92 r9e9d9bc6  
    132132        [0x58] = KC_F12,
    133133
     134        [0x54] = KC_SYSREQ,
    134135        [0x46] = KC_SCROLL_LOCK,
    135136
     
    163164        [0x1d] = KC_RCTRL,
    164165
    165         [0x37] = KC_SYSREQ,
     166        [0x37] = KC_PRTSCR,
     167        [0x46] = KC_PAUSE,
    166168
    167169        [0x52] = KC_INSERT,
     
    230232static errno_t polling(void *arg)
    231233{
     234        kbd_event_type_t evtype;
     235        unsigned int key;
     236        size_t map_size;
    232237        xt_kbd_t *kbd = arg;
     238        uint8_t code;
     239        uint8_t xcode1;
     240        uint8_t xcode2;
    233241        errno_t rc;
    234242
    235243        while (true) {
    236                 const unsigned int *map = scanmap_simple;
    237                 size_t map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
    238 
    239                 uint8_t code = 0;
    240244                rc = xtkbd_get_code(kbd, &code);
    241245                if (rc != EOK)
     
    248252                /* Extended set */
    249253                if (code == KBD_SCANCODE_SET_EXTENDED) {
    250                         map = scanmap_e0;
    251                         map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
    252 
    253                         rc = xtkbd_get_code(kbd, &code);
     254                        rc = xtkbd_get_code(kbd, &xcode1);
    254255                        if (rc != EOK)
    255256                                return EIO;
    256257
    257                         /* Handle really special keys */
    258 
    259                         if (code == 0x2a) {  /* Print Screen */
    260                                 rc = xtkbd_get_code(kbd, &code);
    261                                 if (rc != EOK)
    262                                         return EIO;
    263 
    264                                 if (code != 0xe0)
    265                                         continue;
    266 
    267                                 rc = xtkbd_get_code(kbd, &code);
    268                                 if (rc != EOK)
    269                                         return EIO;
    270 
    271                                 if (code == 0x37)
    272                                         push_event(kbd->client_sess, KEY_PRESS, KC_PRTSCR);
    273 
     258                        if ((xcode1 & 0x7f) == 0x2a)  /* Fake shift */
     259                                continue;
     260
     261                        /* Bit 7 indicates press/release */
     262                        evtype = (xcode1 & 0x80) ? KEY_RELEASE : KEY_PRESS;
     263
     264                        map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
     265                        key = (xcode1 & 0x7f) < map_size ?
     266                            scanmap_e0[xcode1 & 0x7f] : 0;
     267
     268                        if (key != 0)
     269                                push_event(kbd->client_sess, evtype, key);
     270                        else
     271                                ddf_msg(LVL_WARN, "Unknown scancode: e0 %hhx", xcode1);
     272
     273                        continue;
     274                }
     275
     276                /* Extended special set */
     277                if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
     278                        rc = xtkbd_get_code(kbd, &xcode1);
     279                        if (rc != EOK)
     280                                return EIO;
     281
     282                        rc = xtkbd_get_code(kbd, &xcode2);
     283                        if (rc != EOK)
     284                                return EIO;
     285
     286                        if ((xcode1 & 0x80) == (xcode2 & 0x80) &&
     287                            (xcode1 & 0x7f) == 0x1d && (xcode2 & 0x7f) == 0x45) {
     288                                /* Pause */
     289                                evtype = (xcode1 & 0x80) ? KEY_RELEASE :
     290                                    KEY_PRESS;
     291                                push_event(kbd->client_sess, evtype, KC_PAUSE);
    274292                                continue;
    275293                        }
    276294
    277                         if (code == 0x46) {  /* Break */
    278                                 rc = xtkbd_get_code(kbd, &code);
    279                                 if (rc != EOK)
    280                                         return EIO;
    281 
    282                                 if (code != 0xe0)
    283                                         continue;
    284 
    285                                 rc = xtkbd_get_code(kbd, &code);
    286                                 if (rc != EOK)
    287                                         return EIO;
    288 
    289                                 if (code == 0xc6)
    290                                         push_event(kbd->client_sess, KEY_PRESS, KC_BREAK);
    291 
    292                                 continue;
    293                         }
    294                 }
    295 
    296                 /* Extended special set */
    297                 if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
    298                         rc = xtkbd_get_code(kbd, &code);
    299                         if (rc != EOK)
    300                                 return EIO;
    301 
    302                         if (code != 0x1d)
    303                                 continue;
    304 
    305                         rc = xtkbd_get_code(kbd, &code);
    306                         if (rc != EOK)
    307                                 return EIO;
    308 
    309                         if (code != 0x45)
    310                                 continue;
    311 
    312                         rc = xtkbd_get_code(kbd, &code);
    313                         if (rc != EOK)
    314                                 return EIO;
    315 
    316                         if (code != 0xe1)
    317                                 continue;
    318 
    319                         rc = xtkbd_get_code(kbd, &code);
    320                         if (rc != EOK)
    321                                 return EIO;
    322 
    323                         if (code != 0x9d)
    324                                 continue;
    325 
    326                         rc = xtkbd_get_code(kbd, &code);
    327                         if (rc != EOK)
    328                                 return EIO;
    329 
    330                         if (code == 0xc5)
    331                                 push_event(kbd->client_sess, KEY_PRESS, KC_PAUSE);
    332 
     295                        ddf_msg(LVL_WARN, "Unknown scancode: e1 %hhx %hhx",
     296                            xcode1, xcode2);
    333297                        continue;
    334298                }
    335299
    336300                /* Bit 7 indicates press/release */
    337                 const kbd_event_type_t type =
    338                     (code & 0x80) ? KEY_RELEASE : KEY_PRESS;
    339                 code &= ~0x80;
    340 
    341                 const unsigned int key = (code < map_size) ? map[code] : 0;
     301                evtype = (code & 0x80) ? KEY_RELEASE : KEY_PRESS;
     302
     303                map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
     304                key = (code & 0x7f) < map_size ?
     305                    scanmap_simple[code & 0x7f] : 0;
    342306
    343307                if (key != 0)
    344                         push_event(kbd->client_sess, type, key);
     308                        push_event(kbd->client_sess, evtype, key);
    345309                else
    346310                        ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
Note: See TracChangeset for help on using the changeset viewer.