diff --git a/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp b/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp index 4726ec4349..3ccdf60dbd 100644 --- a/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp +++ b/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -327,7 +328,7 @@ extern "C" BInputServerDevice * instantiate_input_device() { - return new KeyboardInputDevice(); + return new (std::nothrow) KeyboardInputDevice(); } @@ -409,20 +410,19 @@ KeyboardInputDevice::InitFromSettings(void *cookie, uint32 opcode) keyboard_device *device = (keyboard_device *)cookie; - if (opcode == 0 - || opcode == B_KEY_REPEAT_RATE_CHANGED) { + if (opcode == 0 || opcode == B_KEY_REPEAT_RATE_CHANGED) { if (get_key_repeat_rate(&device->settings.key_repeat_rate) != B_OK) LOG_ERR("error when get_key_repeat_rate\n"); - else - if (ioctl(device->fd, KB_SET_KEY_REPEAT_RATE, &device->settings.key_repeat_rate)!=B_OK) - LOG_ERR("error when KB_SET_KEY_REPEAT_RATE, fd:%d\n", device->fd); + else if (ioctl(device->fd, KB_SET_KEY_REPEAT_RATE, + &device->settings.key_repeat_rate) != B_OK) + LOG_ERR("error when KB_SET_KEY_REPEAT_RATE, fd:%d\n", device->fd); } if (opcode == 0 || opcode == B_KEY_REPEAT_DELAY_CHANGED) { if (get_key_repeat_delay(&device->settings.key_repeat_delay) != B_OK) LOG_ERR("error when get_key_repeat_delay\n"); else if (ioctl(device->fd, KB_SET_KEY_REPEAT_DELAY, - &device->settings.key_repeat_delay)!=B_OK) + &device->settings.key_repeat_delay) != B_OK) LOG_ERR("error when KB_SET_KEY_REPEAT_DELAY, fd:%d\n", device->fd); } @@ -566,8 +566,8 @@ status_t KeyboardInputDevice::AddDevice(const char *path) { CALLED(); - keyboard_device *device = new keyboard_device(path); - if (!device) + keyboard_device *device = new (std::nothrow) keyboard_device(path); + if (device == NULL) return B_NO_MEMORY; device->fd = -1; @@ -634,6 +634,7 @@ KeyboardInputDevice::DeviceWatcher(void *arg) bigtime_t timestamp = 0; LOG("KB_READ :"); + if (dev->isAT) { at_kbd_io *at_kbd = (at_kbd_io *)buffer; if (at_kbd->scancode > 0) @@ -653,27 +654,29 @@ KeyboardInputDevice::DeviceWatcher(void *arg) LOG(" %Ld, %02x, %02lx\n", timestamp, isKeyDown, keycode); - if (isKeyDown - && (keycode == 0x68) ) { // MENU KEY for OpenTracker 5.2.0+ - bool nokey = true; + if (isKeyDown && keycode == 0x68) { + // MENU KEY for OpenTracker 5.2.0+ + bool noOtherKeyPressed = true; for (int32 i = 0; i < 16; i++) { if (states[i] != 0) { - nokey = false; + noOtherKeyPressed = false; break; } } - if (nokey) { - BMessenger msger("application/x-vnd.Be-TSKB"); - if (msger.IsValid()) - msger.SendMessage('BeMn'); + if (noOtherKeyPressed) { + BMessenger deskbar("application/x-vnd.Be-TSKB"); + if (deskbar.IsValid()) + deskbar.SendMessage('BeMn'); } } - if (isKeyDown) - states[(keycode)>>3] |= (1 << (7 - (keycode & 0x7))); - else - states[(keycode)>>3] &= (!(1 << (7 - (keycode & 0x7)))); + if (keycode < 256) { + if (isKeyDown) + states[(keycode) >> 3] |= (1 << (7 - (keycode & 0x7))); + else + states[(keycode) >> 3] &= (!(1 << (7 - (keycode & 0x7)))); + } if (isKeyDown && keycode == 0x34 // DELETE KEY @@ -682,24 +685,30 @@ KeyboardInputDevice::DeviceWatcher(void *arg) LOG("TeamMonitor called\n"); // show the team monitor - if (!dev->owner->fTMWindow) - dev->owner->fTMWindow = new TMWindow(); + if (dev->owner->fTMWindow == NULL) + dev->owner->fTMWindow = new (std::nothrow) TMWindow(); - dev->owner->fTMWindow->Enable(); + if (dev->owner->fTMWindow != NULL) { + dev->owner->fTMWindow->Enable(); - // cancel timer only for R5 - if (ioctl(dev->fd, KB_CANCEL_CONTROL_ALT_DEL, NULL) == B_OK) - LOG("KB_CANCEL_CONTROL_ALT_DEL : OK\n"); + // cancel timer only for R5 + if (ioctl(dev->fd, KB_CANCEL_CONTROL_ALT_DEL, NULL) == B_OK) + LOG("KB_CANCEL_CONTROL_ALT_DEL : OK\n"); + } } uint32 modifiers = keymap->Modifier(keycode); if (modifiers && (!(modifiers & (B_CAPS_LOCK | B_NUM_LOCK | B_SCROLL_LOCK)) - || isKeyDown)) { + || isKeyDown)) { BMessage *msg = new BMessage; + if (msg == NULL) + continue; + msg->AddInt64("when", timestamp); msg->what = B_MODIFIERS_CHANGED; msg->AddInt32("be:old_modifiers", dev->modifiers); + if ((isKeyDown && !(modifiers & (B_CAPS_LOCK | B_NUM_LOCK | B_SCROLL_LOCK))) || (isKeyDown && !(dev->modifiers & modifiers))) dev->modifiers |= modifiers; @@ -708,6 +717,7 @@ KeyboardInputDevice::DeviceWatcher(void *arg) msg->AddInt32("modifiers", dev->modifiers); msg->AddData("states", B_UINT8_TYPE, states, 16); + if (dev->owner->EnqueueMessage(msg)!=B_OK) delete msg; @@ -715,10 +725,7 @@ KeyboardInputDevice::DeviceWatcher(void *arg) dev->owner->SetLeds(dev); } - char *str = NULL, *str2 = NULL; - int32 numBytes = 0, numBytes2 = 0; uint8 newDeadKey = 0; - if (activeDeadKey == 0) newDeadKey = keymap->IsDeadKey(keycode, dev->modifiers); @@ -732,10 +739,15 @@ KeyboardInputDevice::DeviceWatcher(void *arg) // R5-like dead key behaviour if (newDeadKey == 0) { + char *str = NULL, *str2 = NULL; + int32 numBytes = 0, numBytes2 = 0; keymap->GetChars(keycode, dev->modifiers, activeDeadKey, &str, &numBytes); keymap->GetChars(keycode, 0, 0, &str2, &numBytes2); BMessage *msg = new BMessage; + if (msg == NULL) + continue; + if (numBytes > 0) msg->what = isKeyDown ? B_KEY_DOWN : B_KEY_UP; else @@ -768,6 +780,7 @@ KeyboardInputDevice::DeviceWatcher(void *arg) if (numBytes2 > 0) msg->AddInt32("raw_char", (uint32)((uint8)str2[0] & 0x7f)); + delete[] str2; if (dev->owner->EnqueueMessage(msg) != B_OK) diff --git a/src/add-ons/input_server/devices/keyboard/Keymap.cpp b/src/add-ons/input_server/devices/keyboard/Keymap.cpp index 49a1066d56..0b790c35e3 100644 --- a/src/add-ons/input_server/devices/keyboard/Keymap.cpp +++ b/src/add-ons/input_server/devices/keyboard/Keymap.cpp @@ -1,86 +1,91 @@ -// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ -// -// Copyright (c) 2004, Haiku -// -// This software is part of the Haiku distribution and is covered -// by the Haiku license. -// -// -// File: Keymap.h -// Author: Jérôme Duval -// Description: Keyboard input server addon -// Created : September 7, 2004 -// -// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ +/* + * Copyright 2004-2006, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval + */ + #include "Keymap.h" -#include -#include -#include + #include #include +#include +#include +#include +#include + + static void -print_key( char *chars, int32 offset ) +print_key(char *chars, int32 offset) { int size = chars[offset++]; - - switch( size ) { - case 0: - // Not mapped - printf( "N/A" ); - break; - - case 1: - // 1-byte UTF-8/ASCII character - printf( "%c", chars[offset] ); - break; - - default: - // 2-, 3-, or 4-byte UTF-8 character - { - char *str = new char[size + 1]; - strncpy( str, &(chars[offset]), size ); - str[size] = 0; - printf( "%s", str ); - delete [] str; - } - break; - } - - printf( "\t" ); + + switch (size) { + case 0: + // Not mapped + printf("N/A"); + break; + + case 1: + // 1-byte UTF-8/ASCII character + printf("%c", chars[offset]); + break; + + default: + { + // 2-, 3-, or 4-byte UTF-8 character + char *str = new (std::nothrow) char[size + 1]; + if (str == NULL) + break; + + strncpy(str, &(chars[offset]), size); + str[size] = 0; + printf("%s", str); + delete [] str; + break; + } + } + + printf("\t"); } +// #pragma mark - + + void Keymap::DumpKeymap() { // Print a chart of the normal, shift, option, and option+shift // keys. - printf( "Key #\tNormal\tShift\tCaps\tC+S\tOption\tO+S\tO+C\tO+C+S\tControl\n" ); - for( int idx = 0; idx < 128; idx++ ) { - printf( " 0x%x\t", idx ); - print_key( fChars, fKeys.normal_map[idx] ); - print_key( fChars, fKeys.shift_map[idx] ); - print_key( fChars, fKeys.caps_map[idx] ); - print_key( fChars, fKeys.caps_shift_map[idx] ); - print_key( fChars, fKeys.option_map[idx] ); - print_key( fChars, fKeys.option_shift_map[idx] ); - print_key( fChars, fKeys.option_caps_map[idx] ); - print_key( fChars, fKeys.option_caps_shift_map[idx] ); - print_key( fChars, fKeys.control_map[idx] ); - printf( "\n" ); - } + printf("Key #\tNormal\tShift\tCaps\tC+S\tOption\tO+S\tO+C\tO+C+S\tControl\n"); + for (int i = 0; i < 128; i++) { + printf(" 0x%x\t", i); + print_key(fChars, fKeys.normal_map[i]); + print_key(fChars, fKeys.shift_map[i]); + print_key(fChars, fKeys.caps_map[i]); + print_key(fChars, fKeys.caps_shift_map[i]); + print_key(fChars, fKeys.option_map[i]); + print_key(fChars, fKeys.option_shift_map[i]); + print_key(fChars, fKeys.option_caps_map[i]); + print_key(fChars, fKeys.option_caps_shift_map[i]); + print_key(fChars, fKeys.control_map[i]); + printf("\n"); + } } -Keymap::Keymap() : +Keymap::Keymap() + : fChars(NULL) { key_map *keys; get_key_map(&keys, &fChars); - + if (keys) { memcpy(&fKeys, keys, sizeof(key_map)); free(keys); @@ -90,8 +95,7 @@ Keymap::Keymap() : Keymap::~Keymap() { - if (fChars) - free(fChars); + free(fChars); } @@ -101,25 +105,22 @@ Keymap::~Keymap() bool Keymap::IsModifierKey(uint32 keyCode) { - if ((keyCode == fKeys.caps_key) - || (keyCode == fKeys.num_key) - || (keyCode == fKeys.scroll_key) - || (keyCode == fKeys.left_shift_key) - || (keyCode == fKeys.right_shift_key) - || (keyCode == fKeys.left_command_key) - || (keyCode == fKeys.right_command_key) - || (keyCode == fKeys.left_control_key) - || (keyCode == fKeys.right_control_key) - || (keyCode == fKeys.left_option_key) - || (keyCode == fKeys.right_option_key) - || (keyCode == fKeys.menu_key)) - return true; - return false; + return keyCode == fKeys.caps_key + || keyCode == fKeys.num_key + || keyCode == fKeys.scroll_key + || keyCode == fKeys.left_shift_key + || keyCode == fKeys.right_shift_key + || keyCode == fKeys.left_command_key + || keyCode == fKeys.right_command_key + || keyCode == fKeys.left_control_key + || keyCode == fKeys.right_control_key + || keyCode == fKeys.left_option_key + || keyCode == fKeys.right_option_key + || keyCode == fKeys.menu_key; } -/* we need to know a modifier for a key -*/ +//! We need to know a modifier for a key uint32 Keymap::Modifier(uint32 keyCode) { @@ -147,14 +148,18 @@ Keymap::Modifier(uint32 keyCode) return B_RIGHT_OPTION_KEY | B_OPTION_KEY; if (keyCode == fKeys.menu_key) return B_MENU_KEY; + return 0; } -// tell if a key is a dead key, needed for draw a dead key +//! Tell if a key is a dead key, needed for draw a dead key uint8 Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers) { + if (keyCode >= 256) + return 0; + int32 offset; uint32 tableMask = 0; @@ -169,18 +174,18 @@ Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers) case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; tableMask = B_CONTROL_TABLE; break; default: offset = fKeys.normal_map[keyCode]; tableMask = B_NORMAL_TABLE; break; } - - if (offset<=0) + + if (offset <= 0) return 0; + uint32 numBytes = fChars[offset]; - if (!numBytes) return 0; - + char chars[4]; strncpy(chars, &(fChars[offset+1]), numBytes ); chars[numBytes] = 0; - + int32 deadOffsets[] = { fKeys.acute_dead_key[1], fKeys.grave_dead_key[1], @@ -188,7 +193,7 @@ Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers) fKeys.dieresis_dead_key[1], fKeys.tilde_dead_key[1] }; - + uint32 deadTables[] = { fKeys.acute_tables, fKeys.grave_tables, @@ -196,36 +201,34 @@ Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers) fKeys.dieresis_tables, fKeys.tilde_tables }; - - for (int32 i=0; i<5; i++) { + + for (int32 i = 0; i < 5; i++) { if ((deadTables[i] & tableMask) == 0) continue; - + if (offset == deadOffsets[i]) - return i+1; - + return i + 1; + uint32 deadNumBytes = fChars[deadOffsets[i]]; - if (!deadNumBytes) continue; - - if (strncmp(chars, &(fChars[deadOffsets[i]+1]), deadNumBytes ) == 0) { - return i+1; - } + + if (!strncmp(chars, &(fChars[deadOffsets[i] + 1]), deadNumBytes)) + return i + 1; } return 0; } -// tell if a key is a dead second key, needed for draw a dead second key +//! Tell if a key is a dead second key, needed for draw a dead second key bool Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey) { - if (!activeDeadKey) + if (!activeDeadKey || keyCode >= 256) return false; - + int32 offset; - + switch (modifiers & 0xcf) { case B_SHIFT_KEY: offset = fKeys.shift_map[keyCode]; break; case B_CAPS_LOCK: offset = fKeys.caps_map[keyCode]; break; @@ -240,11 +243,11 @@ Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey) if (offset <= 0) return false; + uint32 numBytes = fChars[offset]; - if (!numBytes) return false; - + int32* deadOffsets[] = { fKeys.acute_dead_key, fKeys.grave_dead_key, @@ -252,37 +255,40 @@ Keymap::IsDeadSecondKey(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey) fKeys.dieresis_dead_key, fKeys.tilde_dead_key }; - + int32 *deadOffset = deadOffsets[activeDeadKey-1]; - + for (int32 i=0; i<32; i++) { if (offset == deadOffset[i]) return true; - + uint32 deadNumBytes = fChars[deadOffset[i]]; - if (!deadNumBytes) continue; - - if (strncmp(&(fChars[offset+1]), &(fChars[deadOffset[i]+1]), deadNumBytes ) == 0) + + if (!strncmp(&(fChars[offset+1]), &(fChars[deadOffset[i]+1]), deadNumBytes)) return true; + i++; } + return false; } -// get the char for a key given modifiers and active dead key +//! Get the char for a key given modifiers and active dead key void -Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** chars, int32* numBytes) +Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, + char** chars, int32* numBytes) { - int32 offset; - *numBytes = 0; *chars = NULL; - + + if (keyCode >= 256) + return; + // here we take NUMLOCK into account - if (modifiers & B_NUM_LOCK) + if (modifiers & B_NUM_LOCK) { switch (keyCode) { case 0x37: case 0x38: @@ -296,7 +302,11 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c case 0x64: case 0x65: modifiers ^= B_SHIFT_KEY; - } + break; + } + } + + int32 offset; // here we choose the right map given the modifiers switch (modifiers & 0xcf) { @@ -308,30 +318,37 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c case B_OPTION_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_map[keyCode]; break; case B_OPTION_KEY|B_SHIFT_KEY|B_CAPS_LOCK: offset = fKeys.option_caps_shift_map[keyCode]; break; case B_CONTROL_KEY: offset = fKeys.control_map[keyCode]; break; - default: offset = fKeys.normal_map[keyCode]; break; + + default: + offset = fKeys.normal_map[keyCode]; + break; } if (offset <= 0) - return; + return; + // here we get the char size *numBytes = fChars[offset]; - if (!*numBytes) return; - + // here we take an potential active dead key - int32 *dead_key; - switch(activeDeadKey) { - case 1: dead_key = fKeys.acute_dead_key; break; - case 2: dead_key = fKeys.grave_dead_key; break; - case 3: dead_key = fKeys.circumflex_dead_key; break; - case 4: dead_key = fKeys.dieresis_dead_key; break; - case 5: dead_key = fKeys.tilde_dead_key; break; - default: + int32 *deadKey; + switch (activeDeadKey) { + case 1: deadKey = fKeys.acute_dead_key; break; + case 2: deadKey = fKeys.grave_dead_key; break; + case 3: deadKey = fKeys.circumflex_dead_key; break; + case 4: deadKey = fKeys.dieresis_dead_key; break; + case 5: deadKey = fKeys.tilde_dead_key; break; + default: { // if not dead, we copy and return the char - char *str = *chars = new char[*numBytes + 1]; - strncpy(str, &(fChars[offset+1]), *numBytes ); + char *str = *chars = new (std::nothrow) char[*numBytes + 1]; + if (str == NULL) { + *numBytes = 0; + return; + } + strncpy(str, &(fChars[offset + 1]), *numBytes); str[*numBytes] = 0; return; } @@ -339,23 +356,27 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c // if dead key, we search for our current offset char in the dead key offset table // string comparison is needed - for (int32 i=0; i<32; i++) { - if (strncmp(&(fChars[offset+1]), &(fChars[dead_key[i]+1]), *numBytes ) == 0) { - *numBytes = fChars[dead_key[i+1]]; - - switch( *numBytes ) { + for (int32 i = 0; i < 32; i++) { + if (strncmp(&(fChars[offset + 1]), &(fChars[deadKey[i] + 1]), *numBytes) == 0) { + *numBytes = fChars[deadKey[i + 1]]; + + switch (*numBytes) { case 0: // Not mapped - *chars = NULL; - break; + *chars = NULL; + break; default: - // 1-, 2-, 3-, or 4-byte UTF-8 character - { - char *str = *chars = new char[*numBytes + 1]; - strncpy(str, &fChars[dead_key[i+1]+1], *numBytes ); - str[*numBytes] = 0; - } - break; + { + // 1-, 2-, 3-, or 4-byte UTF-8 character + char *str = *chars = new (std::nothrow) char[*numBytes + 1]; + if (str == NULL) { + *numBytes = 0; + return; + } + strncpy(str, &fChars[deadKey[i + 1] + 1], *numBytes); + str[*numBytes] = 0; + break; + } } return; } @@ -363,10 +384,14 @@ Keymap::GetChars(uint32 keyCode, uint32 modifiers, uint8 activeDeadKey, char** c } // if not found we return the current char mapped - *chars = new char[*numBytes + 1]; + *chars = new (std::nothrow) char[*numBytes + 1]; + if (*chars == NULL) { + *numBytes = 0; + return; + } + strncpy(*chars, &(fChars[offset+1]), *numBytes ); (*chars)[*numBytes] = 0; - } @@ -374,9 +399,9 @@ status_t Keymap::LoadCurrent() { key_map *keys = NULL; - if (fChars) - free(fChars); + free(fChars); fChars = NULL; + get_key_map(&keys, &fChars); if (!keys) { fprintf(stderr, "error while getting current keymap!\n");