Ignore:
File:
1 edited

Legend:

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

    rfafb8e5 ra635535  
    11/*
     2 * Copyright (c) 2022 Jiri Svoboda
    23 * Copyright (c) 2011 Jan Vesely
    3  * Copyright (c) 2017 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3939#include <io/keycode.h>
    4040#include <io/chardev.h>
    41 #include <io/console.h>
     41#include <io/kbd_event.h>
    4242#include <ipc/kbdev.h>
    4343#include <abi/ipc/methods.h>
     
    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,
     
    198200}
    199201
     202/** Get one scancode byte from the keyboard.
     203 *
     204 * @param kbd Keyboard
     205 * @param code Place to store scancode byte
     206 * @return EOK on success or an error code
     207 */
     208static errno_t xtkbd_get_code(xt_kbd_t *kbd, uint8_t *code)
     209{
     210        errno_t rc;
     211        size_t nread;
     212
     213        *code = 0;
     214        rc = chardev_read(kbd->chardev, code, 1, &nread, chardev_f_none);
     215        if (rc != EOK) {
     216                ddf_msg(LVL_WARN, "Error reading from keyboard device.");
     217                return EIO;
     218        }
     219
     220        ddf_msg(LVL_DEBUG, "Read scancode: 0x%02hhx", *code);
     221
     222        return EOK;
     223}
     224
    200225/** Get data and parse scancodes.
    201226 *
     
    207232static errno_t polling(void *arg)
    208233{
     234        kbd_event_type_t evtype;
     235        unsigned int key;
     236        size_t map_size;
    209237        xt_kbd_t *kbd = arg;
    210         size_t nread;
     238        uint8_t code;
     239        uint8_t xcode1;
     240        uint8_t xcode2;
    211241        errno_t rc;
    212242
    213243        while (true) {
    214                 const unsigned int *map = scanmap_simple;
    215                 size_t map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
    216 
    217                 uint8_t code = 0;
    218                 rc = chardev_read(kbd->chardev, &code, 1, &nread, chardev_f_none);
     244                rc = xtkbd_get_code(kbd, &code);
    219245                if (rc != EOK)
    220246                        return EIO;
     
    226252                /* Extended set */
    227253                if (code == KBD_SCANCODE_SET_EXTENDED) {
    228                         map = scanmap_e0;
    229                         map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
    230 
    231                         rc = chardev_read(kbd->chardev, &code, 1, &nread,
    232                             chardev_f_none);
     254                        rc = xtkbd_get_code(kbd, &xcode1);
    233255                        if (rc != EOK)
    234256                                return EIO;
    235257
    236                         /* Handle really special keys */
    237 
    238                         if (code == 0x2a) {  /* Print Screen */
    239                                 rc = chardev_read(kbd->chardev, &code, 1, &nread,
    240                                     chardev_f_none);
    241                                 if (rc != EOK)
    242                                         return EIO;
    243 
    244                                 if (code != 0xe0)
    245                                         continue;
    246 
    247                                 rc = chardev_read(kbd->chardev, &code, 1, &nread,
    248                                     chardev_f_none);
    249                                 if (rc != EOK)
    250                                         return EIO;
    251 
    252                                 if (code == 0x37)
    253                                         push_event(kbd->client_sess, KEY_PRESS, KC_PRTSCR);
    254 
     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);
    255292                                continue;
    256293                        }
    257294
    258                         if (code == 0x46) {  /* Break */
    259                                 rc = chardev_read(kbd->chardev, &code, 1, &nread,
    260                                     chardev_f_none);
    261                                 if (rc != EOK)
    262                                         return EIO;
    263 
    264                                 if (code != 0xe0)
    265                                         continue;
    266 
    267                                 rc = chardev_read(kbd->chardev, &code, 1, &nread,
    268                                     chardev_f_none);
    269                                 if (rc != EOK)
    270                                         return EIO;
    271 
    272                                 if (code == 0xc6)
    273                                         push_event(kbd->client_sess, KEY_PRESS, KC_BREAK);
    274 
    275                                 continue;
    276                         }
    277                 }
    278 
    279                 /* Extended special set */
    280                 if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
    281                         rc = chardev_read(kbd->chardev, &code, 1, &nread,
    282                             chardev_f_none);
    283                         if (rc != EOK)
    284                                 return EIO;
    285 
    286                         if (code != 0x1d)
    287                                 continue;
    288 
    289                         rc = chardev_read(kbd->chardev, &code, 1, &nread,
    290                             chardev_f_none);
    291                         if (rc != EOK)
    292                                 return EIO;
    293 
    294                         if (code != 0x45)
    295                                 continue;
    296 
    297                         rc = chardev_read(kbd->chardev, &code, 1, &nread,
    298                             chardev_f_none);
    299                         if (rc != EOK)
    300                                 return EIO;
    301 
    302                         if (code != 0xe1)
    303                                 continue;
    304 
    305                         rc = chardev_read(kbd->chardev, &code, 1, &nread,
    306                             chardev_f_none);
    307                         if (rc != EOK)
    308                                 return EIO;
    309 
    310                         if (code != 0x9d)
    311                                 continue;
    312 
    313                         rc = chardev_read(kbd->chardev, &code, 1, &nread,
    314                             chardev_f_none);
    315                         if (rc != EOK)
    316                                 return EIO;
    317 
    318                         if (code == 0xc5)
    319                                 push_event(kbd->client_sess, KEY_PRESS, KC_PAUSE);
    320 
     295                        ddf_msg(LVL_WARN, "Unknown scancode: e1 %hhx %hhx",
     296                            xcode1, xcode2);
    321297                        continue;
    322298                }
    323299
    324300                /* Bit 7 indicates press/release */
    325                 const kbd_event_type_t type =
    326                     (code & 0x80) ? KEY_RELEASE : KEY_PRESS;
    327                 code &= ~0x80;
    328 
    329                 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;
    330306
    331307                if (key != 0)
    332                         push_event(kbd->client_sess, type, key);
     308                        push_event(kbd->client_sess, evtype, key);
    333309                else
    334310                        ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
Note: See TracChangeset for help on using the changeset viewer.