Made the keyboard device more resistant against any kind of error:
* Scancodes greater 255 are now handled correctly, and will no longer crash the input_server. This fixes bug #830. * Use new (std:nothrow) instead of a simple new * Now checks all allocations and appropriately handle failure * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18694 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
458b6f4b90
commit
304d592760
@ -13,6 +13,7 @@
|
||||
#include <String.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -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)
|
||||
|
@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <File.h>
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user