* 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())
|
if (!item->HasData())
|
||||||
continue;
|
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());
|
TRACE("keyboard item with usage %lx\n", item->UsageMinimum());
|
||||||
item->PrintToStream();
|
|
||||||
|
|
||||||
if (item->Array()) {
|
if (item->Array()) {
|
||||||
// normal keys handled as array items
|
// normal or "consumer" keys handled as array items
|
||||||
if (fKeyCount < MAX_KEYS)
|
if (fKeyCount < MAX_KEYS)
|
||||||
fKeys[fKeyCount++] = item;
|
fKeys[fKeyCount++] = item;
|
||||||
} else {
|
} 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) {
|
&& item->UsageID() <= HID_USAGE_ID_RIGHT_GUI) {
|
||||||
// modifiers are generally implemented as bitmaps
|
// modifiers are generally implemented as bitmaps
|
||||||
if (fModifierCount < MAX_MODIFIERS)
|
if (fModifierCount < MAX_MODIFIERS)
|
||||||
fModifiers[fModifierCount++] = item;
|
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,
|
TRACE("keyboard device with %lu keys and %lu modifiers\n", fKeyCount,
|
||||||
fModifierCount);
|
fModifierCount);
|
||||||
|
|
||||||
fLastKeys = (uint8 *)malloc(fKeyCount * 2);
|
fLastKeys = (uint32 *)malloc(fKeyCount * 2 * sizeof(uint32));
|
||||||
fCurrentKeys = fLastKeys + fKeyCount;
|
fCurrentKeys = &fLastKeys[fKeyCount];
|
||||||
if (fLastKeys == NULL) {
|
if (fLastKeys == NULL) {
|
||||||
fStatus = B_NO_MEMORY;
|
fStatus = B_NO_MEMORY;
|
||||||
return;
|
return;
|
||||||
@@ -150,8 +156,11 @@ KeyboardDevice::AddHandler(HIDDevice *device)
|
|||||||
|
|
||||||
for (uint32 j = 0; j < input->CountItems(); j++) {
|
for (uint32 j = 0; j < input->CountItems(); j++) {
|
||||||
HIDReportItem *item = input->ItemAt(j);
|
HIDReportItem *item = input->ItemAt(j);
|
||||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD) {
|
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||||
// found at least one item with a keyboard usage
|
|| (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;
|
foundKeyboardUsage = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -347,11 +356,9 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
|||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (key->Extract() == B_OK && key->Valid()) {
|
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
|
|
||||||
fCurrentKeys[i] = key->Data();
|
fCurrentKeys[i] = key->Data();
|
||||||
} else
|
else
|
||||||
fCurrentKeys[i] = 0;
|
fCurrentKeys[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +532,8 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
|||||||
|
|
||||||
bool phantomState = true;
|
bool phantomState = true;
|
||||||
for (size_t i = 0; i < fKeyCount; i++) {
|
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;
|
phantomState = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -542,11 +550,12 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
|||||||
static bool sysReqPressed = false;
|
static bool sysReqPressed = false;
|
||||||
|
|
||||||
bool keyDown = false;
|
bool keyDown = false;
|
||||||
uint8 *current = fLastKeys;
|
uint32 *current = fLastKeys;
|
||||||
uint8 *compare = fCurrentKeys;
|
uint32 *compare = fCurrentKeys;
|
||||||
for (int32 twice = 0; twice < 2; twice++) {
|
for (int32 twice = 0; twice < 2; twice++) {
|
||||||
for (size_t i = 0; i < fKeyCount; i++) {
|
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;
|
continue;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -562,6 +571,7 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
|||||||
|
|
||||||
// a change occured
|
// a change occured
|
||||||
uint32 key = 0;
|
uint32 key = 0;
|
||||||
|
if (fKeys[i]->UsagePage() == HID_USAGE_PAGE_KEYBOARD) {
|
||||||
if (current[i] < kKeyTableSize)
|
if (current[i] < kKeyTableSize)
|
||||||
key = kKeyTable[current[i]];
|
key = kKeyTable[current[i]];
|
||||||
|
|
||||||
@@ -574,20 +584,25 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
|||||||
&& current[i] >= 4 && current[i] <= 29
|
&& current[i] >= 4 && current[i] <= 29
|
||||||
&& (fLastModifiers & ALT_KEYS) != 0) {
|
&& (fLastModifiers & ALT_KEYS) != 0) {
|
||||||
// Alt-SysReq+letter was pressed
|
// Alt-SysReq+letter was pressed
|
||||||
sDebugKeyboardPipe = fInputReport->Device()->InterruptPipe();
|
sDebugKeyboardPipe
|
||||||
|
= fInputReport->Device()->InterruptPipe();
|
||||||
sDebugKeyboardReportSize
|
sDebugKeyboardReportSize
|
||||||
= fInputReport->Parser()->MaxReportSize();
|
= fInputReport->Parser()->MaxReportSize();
|
||||||
|
|
||||||
char letter = current[i] - 4 + 'a';
|
char letter = current[i] - 4 + 'a';
|
||||||
|
|
||||||
if (debug_emergency_key_pressed(letter)) {
|
if (debug_emergency_key_pressed(letter)) {
|
||||||
// we probably have lost some keys, so reset our key state
|
// we probably have lost some keys, so reset our key
|
||||||
|
// state
|
||||||
sysReqPressed = false;
|
sysReqPressed = false;
|
||||||
continue;
|
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);
|
_WriteKey(key, keyDown);
|
||||||
@@ -610,6 +625,6 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
|||||||
keyDown = true;
|
keyDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(fLastKeys, fCurrentKeys, fKeyCount);
|
memcpy(fLastKeys, fCurrentKeys, fKeyCount * sizeof(uint32));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ private:
|
|||||||
uint32 fModifierCount;
|
uint32 fModifierCount;
|
||||||
|
|
||||||
uint8 fLastModifiers;
|
uint8 fLastModifiers;
|
||||||
uint8 * fCurrentKeys;
|
uint32 * fCurrentKeys;
|
||||||
uint8 * fLastKeys;
|
uint32 * fLastKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // USB_KEYBOARD_DEVICE_H
|
#endif // USB_KEYBOARD_DEVICE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user