Changeset 8c3c756 in mainline for uspace/drv/usbhid/main.c


Ignore:
Timestamp:
2011-02-04T16:12:46Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4837092
Parents:
9e7cdf8
Message:

Setting configuration + key press / key release tracking.

  • Added list of pressed keys to usb_hid_dev_kbd_t - its size is determined when the configuration is set. Now hard-wired to count of pressed keys supported by boot protocol (6).
  • Added function for comparing new keys with old ones and sending events
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/main.c

    r9e7cdf8 r8c3c756  
    5151#include <usb/debug.h>
    5252#include <io/console.h>
     53#include <stdint.h>
    5354#include "hid.h"
    5455#include "descparser.h"
     
    6162
    6263#define GUESSED_POLL_ENDPOINT 1
     64#define BOOTP_REPORT_SIZE 6
    6365
    6466static void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
     
    231233        usb_log_debug("Sending key %d to the console\n", ev.key);
    232234        assert(console_callback_phone != -1);
    233         async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
     235        async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key,
     236            ev.mods, ev.c);
    234237}
    235238/*
     
    239242        /*
    240243         * TODO:
    241          * 1) key press / key release - how does the keyboard notify about release?
     244         * 1) key press / key release - how does the keyboard notify about
     245         *    release?
    242246         * 2) layouts (use the already defined), not important now
    243247         * 3)
    244248         */
    245249
     250static void usbkbd_check_modifier_changes(usb_hid_dev_kbd_t *kbd_dev,
     251    uint8_t modifiers)
     252{
     253        // ignore for now
     254        // modifiers should be sent as normal keys to usbkbd_parse_scancode()!!
     255        // so it would be better if I received it from report parser in that way
     256}
     257
     258static void usbkbd_check_key_changes(usb_hid_dev_kbd_t *kbd_dev,
     259    const uint8_t *key_codes)
     260{
     261        // TODO: phantom state!!
     262       
     263        unsigned int key;
     264        int i, j;
     265       
     266        // TODO: quite dummy right now, think of better implementation
     267       
     268        // key releases
     269        for (j = 0; j < kbd_dev->keycode_count; ++j) {
     270                // try to find the old key in the new key list
     271                i = 0;
     272                while (i < kbd_dev->keycode_count
     273                    && key_codes[i] != kbd_dev->keycodes[j]) {
     274                        ++j;
     275                }
     276               
     277                if (j == kbd_dev->keycode_count) {
     278                        // not found, i.e. the key was released
     279                        key = usbkbd_parse_scancode(kbd_dev->keycodes[j]);
     280                        kbd_push_ev(KEY_RELEASE, key);
     281                } else {
     282                        // found, nothing happens
     283                }
     284        }
     285       
     286        // key presses
     287        for (i = 0; i < kbd_dev->keycode_count; ++i) {
     288                // try to find the new key in the old key list
     289                j = 0;
     290                while (j < kbd_dev->keycode_count
     291                    && kbd_dev->keycodes[j] != key_codes[i]) {
     292                        ++j;
     293                }
     294               
     295                assert(kbd_dev->keycode_count <= kbd_dev->keycode_count);
     296               
     297                if (j == kbd_dev->keycode_count) {
     298                        // not found, i.e. new key pressed
     299                        key = usbkbd_parse_scancode(key_codes[i]);
     300                        kbd_push_ev(KEY_PRESS, key);
     301                } else {
     302                        // found, nothing happens
     303                }
     304        }
     305}
     306
    246307/*
    247308 * Callbacks for parser
     
    250311    uint8_t modifiers, void *arg)
    251312{
     313        if (arg == NULL) {
     314                usb_log_warning("Missing argument in callback "
     315                    "usbkbd_process_keycodes().\n");
     316                return;
     317        }
     318
    252319        usb_log_debug2("Got keys from parser: ");
    253320        unsigned i;
    254321        for (i = 0; i < count; ++i) {
    255322                usb_log_debug2("%d ", key_codes[i]);
    256                 // TODO: Key press / release
    257                 unsigned int key = usbkbd_parse_scancode(key_codes[i]);
    258                 kbd_push_ev(KEY_PRESS, key);
    259323        }
    260324        usb_log_debug2("\n");
     325       
     326        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;
     327       
     328        if (count != kbd_dev->keycode_count) {
     329                usb_log_warning("Number of received keycodes (%d) differs from"
     330                    " expected number (%d).\n", count, kbd_dev->keycode_count);
     331                return;
     332        }
     333       
     334        usbkbd_check_modifier_changes(kbd_dev, modifiers);
     335        usbkbd_check_key_changes(kbd_dev, key_codes);
    261336}
    262337
     
    271346        for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
    272347                // TODO: endianness
    273                 uint16_t length =
    274                     kbd_dev->conf->interfaces[i].hid_desc.report_desc_info.length;
     348                uint16_t length =  kbd_dev->conf->interfaces[i].hid_desc.
     349                    report_desc_info.length;
    275350                size_t actual_size = 0;
    276351
    277352                // allocate space for the report descriptor
    278                 kbd_dev->conf->interfaces[i].report_desc = (uint8_t *)malloc(length);
     353                kbd_dev->conf->interfaces[i].report_desc =
     354                    (uint8_t *)malloc(length);
    279355               
    280356                // get the descriptor from the device
    281                 int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone,
    282                     kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
     357                int rc = usb_drv_req_get_descriptor(
     358                    kbd_dev->device->parent_phone, kbd_dev->address,
     359                    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    283360                    0, i, kbd_dev->conf->interfaces[i].report_desc, length,
    284361                    &actual_size);
     
    355432         * 1) select one configuration (lets say the first)
    356433         * 2) how many interfaces?? how to select one??
    357          *    ("The default setting for an interface is always alternate setting zero.")
     434         *    ("The default setting for an interface is always alternate
     435         *      setting zero.")
    358436         * 3) find endpoint which is IN and INTERRUPT (parse), save its number
    359437         *    as the endpoint for polling
     
    403481         */
    404482
    405         // TODO: get descriptors, parse descriptors and save endpoints
    406483        usbkbd_process_descriptors(kbd_dev);
    407 
     484       
     485        // save the size of the report
     486        kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
     487        kbd_dev->keycodes = (uint8_t *)calloc(
     488            kbd_dev->keycode_count * sizeof(uint8_t));
     489       
     490        if (kbd_dev->keycodes == NULL) {
     491                usb_log_fatal("No memory!\n");
     492                goto error_leave;
     493        }
     494       
     495        // set configuration to the first one
     496        // TODO: handle case with no configurations
     497        usb_drv_req_set_configuration(kbd_dev->device->parent_phone,
     498            kbd_dev->address,
     499            kbd_dev->conf->config_descriptor.configuration_number);
     500       
    408501        /*
    409502         * Initialize the backing connection to the host controller.
     
    440533        usb_hid_report_in_callbacks_t *callbacks =
    441534            (usb_hid_report_in_callbacks_t *)malloc(
    442                 sizeof(usb_hid_report_in_callbacks_t));
     535                sizeof(usb_hid_report_in_callbacks_t));
    443536        callbacks->keyboard = usbkbd_process_keycodes;
    444537
     
    449542        //dump_buffer("bufffer: ", buffer, actual_size);
    450543        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    451             callbacks, NULL);
     544            callbacks, kbd_dev);
    452545       
    453546        if (rc != EOK) {
Note: See TracChangeset for help on using the changeset viewer.