* Allow key-like items from the consumer page to be recognized as well.
* Make the key arrays take the full range of possible index values (32-bits).
* Forward all unmapped keys with their HID usage as keycode.
* Remove some superflous debug output.
With this many of the extra keys on keyboards should be forwarded as unmapped
keys. An application could now watch for them (B_UNMAPPED_KEY{UP|DOWN} messages)
and interpret them based on their keycode which matches the HID usage.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31838 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -62,30 +62,36 @@ KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport)
|
||||
if (!item->HasData())
|
||||
continue;
|
||||
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD) {
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||
|| item->UsagePage() == HID_USAGE_PAGE_CONSUMER) {
|
||||
TRACE("keyboard item with usage %lx\n", item->UsageMinimum());
|
||||
item->PrintToStream();
|
||||
|
||||
if (item->Array()) {
|
||||
// normal keys handled as array items
|
||||
// normal or "consumer" keys handled as array items
|
||||
if (fKeyCount < MAX_KEYS)
|
||||
fKeys[fKeyCount++] = item;
|
||||
} else {
|
||||
if (item->UsageID() >= HID_USAGE_ID_LEFT_CONTROL
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||
&& item->UsageID() >= HID_USAGE_ID_LEFT_CONTROL
|
||||
&& item->UsageID() <= HID_USAGE_ID_RIGHT_GUI) {
|
||||
// modifiers are generally implemented as bitmaps
|
||||
if (fModifierCount < MAX_MODIFIERS)
|
||||
fModifiers[fModifierCount++] = item;
|
||||
}
|
||||
}
|
||||
} else if (item->UsagePage() == HID_USAGE_PAGE_CONSUMER) {
|
||||
if (item->Array()) {
|
||||
if (fKeyCount < MAX_KEYS)
|
||||
fKeys[fKeyCount++] = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("keyboard device with %lu keys and %lu modifiers\n", fKeyCount,
|
||||
fModifierCount);
|
||||
|
||||
fLastKeys = (uint8 *)malloc(fKeyCount * 2);
|
||||
fCurrentKeys = fLastKeys + fKeyCount;
|
||||
fLastKeys = (uint32 *)malloc(fKeyCount * 2 * sizeof(uint32));
|
||||
fCurrentKeys = &fLastKeys[fKeyCount];
|
||||
if (fLastKeys == NULL) {
|
||||
fStatus = B_NO_MEMORY;
|
||||
return;
|
||||
@@ -150,8 +156,11 @@ KeyboardDevice::AddHandler(HIDDevice *device)
|
||||
|
||||
for (uint32 j = 0; j < input->CountItems(); j++) {
|
||||
HIDReportItem *item = input->ItemAt(j);
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD) {
|
||||
// found at least one item with a keyboard usage
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||
|| (item->UsagePage() == HID_USAGE_PAGE_CONSUMER
|
||||
&& item->Array())) {
|
||||
// found at least one item with a keyboard usage or with
|
||||
// a consumer usage that is handled like a key
|
||||
foundKeyboardUsage = true;
|
||||
break;
|
||||
}
|
||||
@@ -347,11 +356,9 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
if (key == NULL)
|
||||
break;
|
||||
|
||||
if (key->Extract() == B_OK && key->Valid()) {
|
||||
// note that if there are ever more than 8 bit usage ids
|
||||
// we need to change all these key arrays to use bugger sizes
|
||||
if (key->Extract() == B_OK && key->Valid())
|
||||
fCurrentKeys[i] = key->Data();
|
||||
} else
|
||||
else
|
||||
fCurrentKeys[i] = 0;
|
||||
}
|
||||
|
||||
@@ -525,7 +532,8 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
|
||||
bool phantomState = true;
|
||||
for (size_t i = 0; i < fKeyCount; i++) {
|
||||
if (fCurrentKeys[i] != 0x01) {
|
||||
if (fCurrentKeys[i] != 1
|
||||
|| fKeys[i]->UsagePage() != HID_USAGE_PAGE_KEYBOARD) {
|
||||
phantomState = false;
|
||||
break;
|
||||
}
|
||||
@@ -542,11 +550,12 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
static bool sysReqPressed = false;
|
||||
|
||||
bool keyDown = false;
|
||||
uint8 *current = fLastKeys;
|
||||
uint8 *compare = fCurrentKeys;
|
||||
uint32 *current = fLastKeys;
|
||||
uint32 *compare = fCurrentKeys;
|
||||
for (int32 twice = 0; twice < 2; twice++) {
|
||||
for (size_t i = 0; i < fKeyCount; i++) {
|
||||
if (current[i] == 0x00 || current[i] == 0x01)
|
||||
if (current[i] == 0 || (current[i] == 1 &&
|
||||
fKeys[i]->UsagePage() == HID_USAGE_PAGE_KEYBOARD))
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
@@ -562,32 +571,38 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
|
||||
// a change occured
|
||||
uint32 key = 0;
|
||||
if (current[i] < kKeyTableSize)
|
||||
key = kKeyTable[current[i]];
|
||||
if (fKeys[i]->UsagePage() == HID_USAGE_PAGE_KEYBOARD) {
|
||||
if (current[i] < kKeyTableSize)
|
||||
key = kKeyTable[current[i]];
|
||||
|
||||
if (key == KEY_Pause && (modifiers & ALT_KEYS) != 0)
|
||||
key = KEY_Break;
|
||||
else if (key == 0xe && (modifiers & ALT_KEYS) != 0) {
|
||||
key = KEY_SysRq;
|
||||
sysReqPressed = keyDown;
|
||||
} else if (sysReqPressed && keyDown
|
||||
&& current[i] >= 4 && current[i] <= 29
|
||||
&& (fLastModifiers & ALT_KEYS) != 0) {
|
||||
// Alt-SysReq+letter was pressed
|
||||
sDebugKeyboardPipe = fInputReport->Device()->InterruptPipe();
|
||||
sDebugKeyboardReportSize
|
||||
= fInputReport->Parser()->MaxReportSize();
|
||||
if (key == KEY_Pause && (modifiers & ALT_KEYS) != 0)
|
||||
key = KEY_Break;
|
||||
else if (key == 0xe && (modifiers & ALT_KEYS) != 0) {
|
||||
key = KEY_SysRq;
|
||||
sysReqPressed = keyDown;
|
||||
} else if (sysReqPressed && keyDown
|
||||
&& current[i] >= 4 && current[i] <= 29
|
||||
&& (fLastModifiers & ALT_KEYS) != 0) {
|
||||
// Alt-SysReq+letter was pressed
|
||||
sDebugKeyboardPipe
|
||||
= fInputReport->Device()->InterruptPipe();
|
||||
sDebugKeyboardReportSize
|
||||
= fInputReport->Parser()->MaxReportSize();
|
||||
|
||||
char letter = current[i] - 4 + 'a';
|
||||
char letter = current[i] - 4 + 'a';
|
||||
|
||||
if (debug_emergency_key_pressed(letter)) {
|
||||
// we probably have lost some keys, so reset our key state
|
||||
sysReqPressed = false;
|
||||
continue;
|
||||
if (debug_emergency_key_pressed(letter)) {
|
||||
// we probably have lost some keys, so reset our key
|
||||
// state
|
||||
sysReqPressed = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (key == 0) {
|
||||
// unmapped key
|
||||
key = 0x200000 + current[i];
|
||||
}
|
||||
|
||||
if (key == 0) {
|
||||
// unmapped normal key or consumer key
|
||||
key = fKeys[i]->UsageMinimum() + current[i];
|
||||
}
|
||||
|
||||
_WriteKey(key, keyDown);
|
||||
@@ -610,6 +625,6 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
keyDown = true;
|
||||
}
|
||||
|
||||
memcpy(fLastKeys, fCurrentKeys, fKeyCount);
|
||||
memcpy(fLastKeys, fCurrentKeys, fKeyCount * sizeof(uint32));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ private:
|
||||
uint32 fModifierCount;
|
||||
|
||||
uint8 fLastModifiers;
|
||||
uint8 * fCurrentKeys;
|
||||
uint8 * fLastKeys;
|
||||
uint32 * fCurrentKeys;
|
||||
uint32 * fLastKeys;
|
||||
};
|
||||
|
||||
#endif // USB_KEYBOARD_DEVICE_H
|
||||
|
||||
Reference in New Issue
Block a user