]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
merge usb into keylayouts
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 21 Aug 2010 21:17:44 +0000 (23:17 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 21 Aug 2010 21:17:44 +0000 (23:17 +0200)
1  2 
term/usb_keyboard.c

index 7b67c6e96f82dd854b8062dbb555d265dc2ea502,ea13418e0b66c75113e3cc26b7a7b9b6d7ecb7a6..fc1435c053e890e868c7117fa2ac76174652e63d
@@@ -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;
  
    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;
  
 -  /* 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;
+   grub_usb_keyboard_checkkey (term);
 +  return interpret_status (termdata->status) | termdata->mods;
  }
  
  struct grub_usb_attach_desc attach_hook =