Ignore:
File:
1 edited

Legend:

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

    ra635535 rfafb8e5  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
    32 * 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/kbd_event.h>
     41#include <io/console.h>
    4242#include <ipc/kbdev.h>
    4343#include <abi/ipc/methods.h>
     
    132132        [0x58] = KC_F12,
    133133
    134         [0x54] = KC_SYSREQ,
    135134        [0x46] = KC_SCROLL_LOCK,
    136135
     
    164163        [0x1d] = KC_RCTRL,
    165164
    166         [0x37] = KC_PRTSCR,
    167         [0x46] = KC_PAUSE,
     165        [0x37] = KC_SYSREQ,
    168166
    169167        [0x52] = KC_INSERT,
     
    200198}
    201199
    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  */
    208 static 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 
    225200/** Get data and parse scancodes.
    226201 *
     
    232207static errno_t polling(void *arg)
    233208{
    234         kbd_event_type_t evtype;
    235         unsigned int key;
    236         size_t map_size;
    237209        xt_kbd_t *kbd = arg;
    238         uint8_t code;
    239         uint8_t xcode1;
    240         uint8_t xcode2;
     210        size_t nread;
    241211        errno_t rc;
    242212
    243213        while (true) {
    244                 rc = xtkbd_get_code(kbd, &code);
     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);
    245219                if (rc != EOK)
    246220                        return EIO;
     
    252226                /* Extended set */
    253227                if (code == KBD_SCANCODE_SET_EXTENDED) {
    254                         rc = xtkbd_get_code(kbd, &xcode1);
    255                         if (rc != EOK)
    256                                 return EIO;
    257 
    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 
     228                        map = scanmap_e0;
    264229                        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);
     230
     231                        rc = chardev_read(kbd->chardev, &code, 1, &nread,
     232                            chardev_f_none);
     233                        if (rc != EOK)
     234                                return EIO;
     235
     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
     255                                continue;
     256                        }
     257
     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);
    272320
    273321                        continue;
    274322                }
    275323
    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);
    292                                 continue;
    293                         }
    294 
    295                         ddf_msg(LVL_WARN, "Unknown scancode: e1 %hhx %hhx",
    296                             xcode1, xcode2);
    297                         continue;
    298                 }
    299 
    300324                /* Bit 7 indicates press/release */
    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;
     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;
    306330
    307331                if (key != 0)
    308                         push_event(kbd->client_sess, evtype, key);
     332                        push_event(kbd->client_sess, type, key);
    309333                else
    310334                        ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
Note: See TracChangeset for help on using the changeset viewer.