From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 21:17:44 +0000 (+0200) Subject: merge usb into keylayouts X-Git-Tag: 1.99~488^2~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=524c2712ad42fa85a5db5634224abbf3d2c5129d;p=thirdparty%2Fgrub.git merge usb into keylayouts --- 524c2712ad42fa85a5db5634224abbf3d2c5129d diff --cc term/usb_keyboard.c index 7b67c6e96,ea13418e0..fc1435c05 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@@ -113,25 -66,6 +113,28 @@@ static grub_uint8_t usb_to_at_map[128] #define USB_HID_BOOT_SUBCLASS 0x01 #define USB_HID_KBD_PROTOCOL 0x01 +#define GRUB_USB_KEYBOARD_LEFT_CTRL 0x01 +#define GRUB_USB_KEYBOARD_LEFT_SHIFT 0x02 +#define GRUB_USB_KEYBOARD_LEFT_ALT 0x04 +#define GRUB_USB_KEYBOARD_RIGHT_CTRL 0x10 +#define GRUB_USB_KEYBOARD_RIGHT_SHIFT 0x20 +#define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 + +struct grub_usb_keyboard_data +{ + grub_usb_device_t usbdev; + grub_uint8_t status; + grub_uint16_t mods; + int key; + int interfno; + struct grub_usb_desc_endp *endp; ++ grub_usb_transfer_t transfer; ++ grub_uint8_t report[8]; ++ int dead; +}; + +static struct grub_term_input grub_usb_keyboards[16]; + static int grub_usb_keyboard_checkkey (struct grub_term_input *term); static int grub_usb_keyboard_getkey (struct grub_term_input *term); static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term); @@@ -144,27 -78,18 +147,29 @@@ static struct grub_term_input grub_usb_ .next = 0 }; -struct grub_usb_keyboard_data ++static struct grub_term_input grub_usb_keyboards[16]; ++ +static int +interpret_status (grub_uint8_t data0) { - grub_usb_device_t usbdev; - grub_uint8_t status; - int key; - struct grub_usb_desc_endp *endp; - grub_usb_transfer_t transfer; - grub_uint8_t report[8]; - int dead; -}; + int mods = 0; -static struct grub_term_input grub_usb_keyboards[16]; + /* Check Shift, Control, and Alt status. */ + if (data0 & GRUB_USB_KEYBOARD_LEFT_SHIFT) + mods |= GRUB_TERM_STATUS_LSHIFT; + if (data0 & GRUB_USB_KEYBOARD_RIGHT_SHIFT) + mods |= GRUB_TERM_STATUS_RSHIFT; + if (data0 & GRUB_USB_KEYBOARD_LEFT_CTRL) + mods |= GRUB_TERM_STATUS_LCTRL; + if (data0 & GRUB_USB_KEYBOARD_RIGHT_CTRL) + mods |= GRUB_TERM_STATUS_RCTRL; + if (data0 & GRUB_USB_KEYBOARD_LEFT_ALT) + mods |= GRUB_TERM_STATUS_LALT; + if (data0 & GRUB_USB_KEYBOARD_RIGHT_ALT) + mods |= GRUB_TERM_STATUS_RALT; + + return mods; +} static void grub_usb_keyboard_detach (grub_usb_device_t usbdev, @@@ -282,11 -215,25 +296,27 @@@ grub_usb_keyboard_attach (grub_usb_devi data->key = report[2] ? : -1; } } + #else + data->status = 0; + data->key = -1; + #endif + + data->transfer = grub_usb_bulk_read_background (usbdev, + data->endp->endp_addr, + sizeof (data->report), + (char *) data->report); + if (!data->transfer) + { + grub_print_error (); + return 0; + } + data->mods = 0; + grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]); + data->dead = 0; + return 1; } @@@ -316,11 -250,34 +346,35 @@@ grub_usb_keyboard_checkkey (struct grub if (termdata->key != -1) return termdata->key; - data[2] = 0; + if (termdata->dead) + return -1; + /* Poll interrupt pipe. */ - err = grub_usb_bulk_read_extended (termdata->usbdev, - termdata->endp->endp_addr, sizeof (data), - (char *) data, 10, &actual); + err = grub_usb_check_transfer (termdata->transfer, &actual); + + if (err == GRUB_USB_ERR_WAIT) + return -1; + + grub_memcpy (data, termdata->report, sizeof (data)); + - grub_dprintf ("usb_keyboard", - "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" - " 0x%02x 0x%02x 0x%02x 0x%02x\n", - err, actual, - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7]); - + termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev, + termdata->endp->endp_addr, + sizeof (termdata->report), + (char *) termdata->report); + if (!termdata->transfer) + { + grub_printf ("%s failed. Stopped\n", term->name); + termdata->dead = 1; + } + ++ ++ grub_dprintf ("usb_keyboard", ++ "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" ++ " 0x%02x 0x%02x 0x%02x 0x%02x\n", ++ err, actual, ++ data[0], data[1], data[2], data[3], ++ data[4], data[5], data[6], data[7]); ++ if (err || actual < 1) return -1; @@@ -329,26 -286,16 +383,19 @@@ if (actual < 3 || !data[2]) return -1; - /* Check if the Control or Shift key was pressed. */ - if (data[0] & 0x01 || data[0] & 0x10) - termdata->key = keyboard_map[data[2]] - 'a' + 1; - else if (data[0] & 0x02 || data[0] & 0x20) - termdata->key = keyboard_map_shift[data[2]]; - else - termdata->key = keyboard_map[data[2]]; + if (data[2] == CAPS_LOCK) + { + termdata->mods ^= GRUB_TERM_STATUS_CAPS; + send_leds (termdata); + return -1; + } - grub_dprintf ("usb_keyboard", - "report: 0x%02x 0x%02x 0x%02x 0x%02x" - " 0x%02x 0x%02x 0x%02x 0x%02x\n", - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7]); - - if (termdata->key == 0) + if (usb_to_at_map[data[2]] == 0) grub_printf ("Unknown key 0x%x detected\n", data[2]); - + else + termdata->key = grub_term_map_key (usb_to_at_map[data[2]], + interpret_status (data[0]) + | termdata->mods); grub_errno = GRUB_ERR_NONE; @@@ -375,8 -322,19 +422,10 @@@ static in grub_usb_keyboard_getkeystatus (struct grub_term_input *term) { struct grub_usb_keyboard_data *termdata = term->data; - int mods = 0; + grub_usb_keyboard_checkkey (term); + - /* Check Shift, Control, and Alt status. */ - if (termdata->status & 0x02 || termdata->status & 0x20) - mods |= GRUB_TERM_STATUS_SHIFT; - if (termdata->status & 0x01 || termdata->status & 0x10) - mods |= GRUB_TERM_STATUS_CTRL; - if (termdata->status & 0x04 || termdata->status & 0x40) - mods |= GRUB_TERM_STATUS_ALT; - - return mods; + return interpret_status (termdata->status) | termdata->mods; } struct grub_usb_attach_desc attach_hook =