diff --git a/src/add-ons/input_server/devices/virtualkeyboard/Jamfile b/src/add-ons/input_server/devices/virtualkeyboard/Jamfile
index 0f545e763f..83c33f78f6 100644
--- a/src/add-ons/input_server/devices/virtualkeyboard/Jamfile
+++ b/src/add-ons/input_server/devices/virtualkeyboard/Jamfile
@@ -3,6 +3,8 @@ SubDir HAIKU_TOP src add-ons input_server devices virtualkeyboard ;
UsePrivateHeaders input interface shared tracker ;
UsePrivateSystemHeaders ;
+SubDirC++Flags -DVIRTUAL_KEYBOARD_DEVICE ;
+
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src preferences keymap ] ;
AddResources virtualkeyboard : VirtualKeyboard.rdef ;
diff --git a/src/add-ons/input_server/devices/virtualkeyboard/KeyboardLayoutView.cpp b/src/add-ons/input_server/devices/virtualkeyboard/KeyboardLayoutView.cpp
deleted file mode 100644
index e4e3c1aec6..0000000000
--- a/src/add-ons/input_server/devices/virtualkeyboard/KeyboardLayoutView.cpp
+++ /dev/null
@@ -1,1170 +0,0 @@
-/*
- * Copyright 2009-2010, Axel Dörfler, axeld@pinc-software.de.
- * Distributed under the terms of the MIT License.
- */
-
-
-#include "KeyboardLayoutView.h"
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "Keymap.h"
-
-
-static const rgb_color kBrightColor = {230, 230, 230, 255};
-static const rgb_color kDarkColor = {200, 200, 200, 255};
-static const rgb_color kSecondDeadKeyColor = {240, 240, 150, 255};
-static const rgb_color kDeadKeyColor = {152, 203, 255, 255};
-static const rgb_color kLitIndicatorColor = {116, 212, 83, 255};
-
-
-#undef TRACE
-
-//#define TRACE_KEYBOARD_DEVICE
-#ifdef TRACE_KEYBOARD_DEVICE
-
-static int32 sFunctionDepth = -1;
-
-class FunctionTracer {
-public:
- FunctionTracer(const void* pointer, const char* className,
- const char* functionName)
- :
- fFunctionName(),
- fPrepend(),
- fPointer(pointer)
- {
- sFunctionDepth++;
- fPrepend.Append(' ', sFunctionDepth * 2);
- fFunctionName << className << "::" << functionName << "()";
-
- debug_printf("%p -> %s%s {\n", fPointer, fPrepend.String(),
- fFunctionName.String());
- }
-
- ~FunctionTracer()
- {
- debug_printf("%p -> %s}\n", fPointer, fPrepend.String());
- sFunctionDepth--;
- }
-
- static int32 Depth() { return sFunctionDepth; }
-
-private:
- BString fFunctionName;
- BString fPrepend;
- const void* fPointer;
-};
-
-# define KD_CALLED(x...) \
- FunctionTracer _ft(this, "LayoutView", __FUNCTION__)
-# define KID_CALLED(x...) \
- FunctionTracer _ft(this, "LayoutView", __FUNCTION__)
-# define TRACE(x...) \
- do { BString _to; \
- _to.Append(' ', (FunctionTracer::Depth() + 1) * 2); \
- debug_printf("%p -> %s", this, _to.String()); \
- debug_printf(x); } while (0)
-# define LOG_EVENT(text...) debug_printf(text)
-# define LOG_ERR(text...) TRACE(text)
-#else
-# define TRACE(x...) do {} while (0)
-# define KD_CALLED(x...) TRACE(x)
-# define KID_CALLED(x...) TRACE(x)
-# define LOG_ERR(text...) debug_printf(text)
-# define LOG_EVENT(text...) TRACE(x)
-#endif
-
-
-KeyboardLayoutView::KeyboardLayoutView(const char* name,
- BInputServerDevice* dev)
- :
- BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
- fOffscreenBitmap(NULL),
- fKeymap(NULL),
- fEditable(true),
- fModifiers(0),
- fDeadKey(0),
- fButtons(0),
- fDragKey(NULL),
- fDropTarget(NULL),
- fOldSize(0, 0),
- fDevice(dev)
-{
- fLayout = new KeyboardLayout;
- memset(fKeyState, 0, sizeof(fKeyState));
-
- SetEventMask(B_KEYBOARD_EVENTS);
-}
-
-
-KeyboardLayoutView::~KeyboardLayoutView()
-{
- delete fOffscreenBitmap;
-}
-
-
-void
-KeyboardLayoutView::SetKeyboardLayout(KeyboardLayout* layout)
-{
- fLayout = layout;
- _InitOffscreen();
- _LayoutKeyboard();
- Invalidate();
-}
-
-
-void
-KeyboardLayoutView::SetKeymap(Keymap* keymap)
-{
- fKeymap = keymap;
- Invalidate();
-}
-
-
-void
-KeyboardLayoutView::SetEditable(bool editable)
-{
- fEditable = editable;
-}
-
-
-void
-KeyboardLayoutView::SetTarget(BMessenger target)
-{
- fTarget = target;
-}
-
-
-void
-KeyboardLayoutView::SetBaseFont(const BFont& font)
-{
- fBaseFont = font;
-
- font_height fontHeight;
- fBaseFont.GetHeight(&fontHeight);
- fBaseFontHeight = fontHeight.ascent + fontHeight.descent;
- fBaseFontSize = fBaseFont.Size();
-
- Invalidate();
-}
-
-
-void
-KeyboardLayoutView::AttachedToWindow()
-{
- SetViewColor(B_TRANSPARENT_COLOR);
-
- SetBaseFont(*be_plain_font);
- fSpecialFont = *be_fixed_font;
- fModifiers = modifiers();
-}
-
-
-void
-KeyboardLayoutView::FrameResized(float width, float height)
-{
- _InitOffscreen();
- _LayoutKeyboard();
-}
-
-
-void
-KeyboardLayoutView::WindowActivated(bool active)
-{
- if (active)
- Invalidate();
-}
-
-
-BSize
-KeyboardLayoutView::MinSize()
-{
- return BLayoutUtils::ComposeSize(ExplicitMinSize(), BSize(100, 50));
-}
-
-
-void
-KeyboardLayoutView::KeyDown(const char* bytes, int32 numBytes)
-{
- _KeyChanged(Window()->CurrentMessage());
-}
-
-
-void
-KeyboardLayoutView::KeyUp(const char* bytes, int32 numBytes)
-{
- _KeyChanged(Window()->CurrentMessage());
-}
-
-
-void
-KeyboardLayoutView::MouseDown(BPoint point)
-{
- fClickPoint = point;
- fDragKey = NULL;
- fDropPoint.x = -1;
-
- Key* key = _KeyAt(point);
- if (key == NULL)
- return;
-
- int32 buttons = 0;
- if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
- Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
-
- if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0
- && (fButtons & B_TERTIARY_MOUSE_BUTTON) == 0) {
- // toggle the "deadness" of dead keys via middle mouse button
- if (fKeymap != NULL) {
- bool isEnabled = false;
- uint8 deadKey
- = fKeymap->DeadKey(key->code, fModifiers, &isEnabled);
- if (deadKey > 0) {
- fKeymap->SetDeadKeyEnabled(key->code, fModifiers, !isEnabled);
- _InvalidateKey(key);
- }
- }
- } else {
- if (fKeymap != NULL && fKeymap->IsModifierKey(key->code)) {
- if (_KeyState(key->code)) {
- uint32 modifier = fKeymap->Modifier(key->code);
- if ((modifier & modifiers()) == 0) {
- _SetKeyState(key->code, false);
- fModifiers &= ~modifier;
- Invalidate();
- }
- } else {
- _SetKeyState(key->code, true);
- fModifiers |= fKeymap->Modifier(key->code);
- Invalidate();
- }
-
- // TODO: if possible, we could handle the lock keys for real
- } else {
- _SetKeyState(key->code, true);
- _InvalidateKey(key);
- }
- }
-
- fButtons = buttons;
-}
-
-
-void
-KeyboardLayoutView::MouseUp(BPoint point)
-{
- Key* key = _KeyAt(fClickPoint);
-
- int32 buttons = 0;
- if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
- Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
-
- if (key != NULL) {
- if ((fButtons & B_TERTIARY_MOUSE_BUTTON) != 0
- && (buttons & B_TERTIARY_MOUSE_BUTTON) == 0) {
- _SetKeyState(key->code, false);
- _InvalidateKey(key);
- fButtons = buttons;
- } else {
- fButtons = buttons;
-
- // modifier keys are sticky when used with the mouse
- if (fKeymap != NULL && fKeymap->IsModifierKey(key->code))
- return;
-
- _SetKeyState(key->code, false);
-
- if (_HandleDeadKey(key->code, fModifiers) && fDeadKey != 0)
- return;
-
- _InvalidateKey(key);
-
- if (fDragKey == NULL && fKeymap != NULL) {
- _SendKeyDown(key);
- }
- }
- }
- fDragKey = NULL;
-}
-
-
-void
-KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
- const BMessage* dragMessage)
-{
-}
-
-
-void
-KeyboardLayoutView::Draw(BRect updateRect)
-{
- if (fOldSize != BSize(Bounds().Width(), Bounds().Height())) {
- _InitOffscreen();
- _LayoutKeyboard();
- }
-
- BView* view;
- if (fOffscreenBitmap != NULL) {
- view = fOffscreenView;
- view->LockLooper();
- } else
- view = this;
-
- // Draw background
-
- if (Parent())
- view->SetLowColor(Parent()->ViewColor());
- else
- view->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
-
- view->FillRect(updateRect, B_SOLID_LOW);
-
- // Draw keys
-
- for (int32 i = 0; i < fLayout->CountKeys(); i++) {
- Key* key = fLayout->KeyAt(i);
-
- _DrawKey(view, updateRect, key, _FrameFor(key),
- _IsKeyPressed(key->code));
- }
-
- // Draw LED indicators
-
- for (int32 i = 0; i < fLayout->CountIndicators(); i++) {
- Indicator* indicator = fLayout->IndicatorAt(i);
-
- _DrawIndicator(view, updateRect, indicator, _FrameFor(indicator->frame),
- (fModifiers & indicator->modifier) != 0);
- }
-
- if (fOffscreenBitmap != NULL) {
- view->Sync();
- view->UnlockLooper();
-
- DrawBitmapAsync(fOffscreenBitmap, BPoint(0, 0));
- }
-}
-
-
-void
-KeyboardLayoutView::MessageReceived(BMessage* message)
-{
- if (message->WasDropped() && fEditable && fDropTarget != NULL
- && fKeymap != NULL) {
- int32 keyCode;
- const char* data;
- ssize_t size;
- if (message->FindData("text/plain", B_MIME_DATA,
- (const void**)&data, &size) == B_OK) {
- // Automatically convert UTF-8 escaped strings (for example from
- // CharacterMap)
- int32 dataSize = 0;
- uint8 buffer[16];
- if (size > 3 && data[0] == '\\' && data[1] == 'x') {
- char tempBuffer[16];
- if (size > 15)
- size = 15;
- memcpy(tempBuffer, data, size);
- tempBuffer[size] = '\0';
- data = tempBuffer;
-
- while (size > 3 && data[0] == '\\' && data[1] == 'x') {
- buffer[dataSize++] = strtoul(&data[2], NULL, 16);
- if ((buffer[dataSize - 1] & 0x80) == 0)
- break;
-
- size -= 4;
- data += 4;
- }
- data = (const char*)buffer;
- } else if ((data[0] & 0xc0) != 0x80 && (data[0] & 0x80) != 0) {
- // only accept the first character UTF-8 character
- while (dataSize < size && (data[dataSize] & 0x80) != 0) {
- dataSize++;
- }
- } else if ((data[0] & 0x80) == 0) {
- // an ASCII character
- dataSize = 1;
- } else {
- // no valid character
- beep();
- return;
- }
-
- int32 buttons;
- if (!message->IsSourceRemote()
- && message->FindInt32("buttons", &buttons) == B_OK
- && (buttons & B_SECONDARY_MOUSE_BUTTON) != 0
- && message->FindInt32("key", &keyCode) == B_OK) {
- // switch keys if the dropped object came from us
- Key* key = _KeyForCode(keyCode);
- if (key == NULL
- || (key == fDropTarget && fDragModifiers == fModifiers))
- return;
-
- char* string;
- int32 numBytes;
- fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
- &string, &numBytes);
- if (string != NULL) {
- // switch keys
- fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
- (const char*)data, dataSize);
- fKeymap->SetKey(key->code, fDragModifiers, fDeadKey,
- string, numBytes);
- delete[] string;
- } else if (fKeymap->IsModifierKey(fDropTarget->code)) {
- // switch key with modifier
- fKeymap->SetModifier(key->code,
- fKeymap->Modifier(fDropTarget->code));
- fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
- (const char*)data, dataSize);
- }
- } else {
- // Send the old key to the target, so it's not lost entirely
- _SendKeyDown(fDropTarget);
-
- fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
- (const char*)data, dataSize);
- }
- } else if (!message->IsSourceRemote()
- && message->FindInt32("key", &keyCode) == B_OK) {
- // Switch an unmapped key
-
- Key* key = _KeyForCode(keyCode);
- if (key != NULL && key == fDropTarget)
- return;
-
- uint32 modifier = fKeymap->Modifier(keyCode);
-
- char* string;
- int32 numBytes;
- fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
- &string, &numBytes);
- if (string != NULL) {
- // switch key with modifier
- fKeymap->SetModifier(fDropTarget->code, modifier);
- fKeymap->SetKey(keyCode, fDragModifiers, fDeadKey,
- string, numBytes);
- delete[] string;
- } else {
- // switch modifier keys
- fKeymap->SetModifier(keyCode,
- fKeymap->Modifier(fDropTarget->code));
- fKeymap->SetModifier(fDropTarget->code, modifier);
- }
-
- _InvalidateKey(fDragKey);
- }
-
- _InvalidateKey(fDropTarget);
- fDropTarget = NULL;
- fDropPoint.x = -1;
- return;
- }
-
- switch (message->what) {
- case B_UNMAPPED_KEY_DOWN:
- case B_UNMAPPED_KEY_UP:
- _KeyChanged(message);
- break;
-
- case B_MODIFIERS_CHANGED:
- {
- int32 newModifiers;
- if (message->FindInt32("modifiers", &newModifiers) == B_OK
- && fModifiers != newModifiers) {
- fModifiers = newModifiers;
- _EvaluateDropTarget(fDropPoint);
- if (Window()->IsActive())
- Invalidate();
- }
- break;
- }
-
- default:
- BView::MessageReceived(message);
- break;
- }
-}
-
-
-void
-KeyboardLayoutView::_InitOffscreen()
-{
- delete fOffscreenBitmap;
- fOffscreenView = NULL;
-
- fOffscreenBitmap = new(std::nothrow) BBitmap(Bounds(),
- B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
- if (fOffscreenBitmap != NULL && fOffscreenBitmap->IsValid()) {
- fOffscreenBitmap->Lock();
- fOffscreenView = new(std::nothrow) BView(Bounds(), "offscreen view",
- 0, 0);
- if (fOffscreenView != NULL) {
- if (Parent() != NULL) {
- fOffscreenView->SetViewColor(Parent()->ViewColor());
- } else {
- fOffscreenView->SetViewColor(
- ui_color(B_PANEL_BACKGROUND_COLOR));
- }
-
- fOffscreenView->SetLowColor(fOffscreenView->ViewColor());
- fOffscreenBitmap->AddChild(fOffscreenView);
- }
- fOffscreenBitmap->Unlock();
- }
-
- if (fOffscreenView == NULL) {
- // something went wrong
- delete fOffscreenBitmap;
- fOffscreenBitmap = NULL;
- }
-}
-
-
-void
-KeyboardLayoutView::_LayoutKeyboard()
-{
- float factorX = Bounds().Width() / fLayout->Bounds().Width();
- float factorY = Bounds().Height() / fLayout->Bounds().Height();
-
- fFactor = min_c(factorX, factorY);
- fOffset = BPoint((Bounds().Width() - fLayout->Bounds().Width()
- * fFactor) / 2,
- (Bounds().Height() - fLayout->Bounds().Height() * fFactor) / 2);
-
- if (fLayout->DefaultKeySize().width < 11)
- fGap = 1;
- else
- fGap = 2;
-
- fOldSize.width = Bounds().Width();
- fOldSize.height = Bounds().Height();
-}
-
-
-void
-KeyboardLayoutView::_DrawKeyButton(BView* view, BRect& rect, BRect updateRect,
- rgb_color base, rgb_color background, bool pressed)
-{
- be_control_look->DrawButtonFrame(view, rect, updateRect, 4.0f, base,
- background, pressed ? BControlLook::B_ACTIVATED : 0);
- be_control_look->DrawButtonBackground(view, rect, updateRect, 4.0f,
- base, pressed ? BControlLook::B_ACTIVATED : 0);
-}
-
-
-void
-KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key,
- BRect rect, bool pressed)
-{
- rgb_color base = key->dark ? kDarkColor : kBrightColor;
- rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
- key_kind keyKind = kNormalKey;
- int32 deadKey = 0;
- bool secondDeadKey = false;
- bool isDeadKeyEnabled = true;
-
- char text[32];
- if (fKeymap != NULL) {
- _GetKeyLabel(key, text, sizeof(text), keyKind);
- deadKey = fKeymap->DeadKey(key->code, fModifiers, &isDeadKeyEnabled);
- secondDeadKey = fKeymap->IsDeadSecondKey(key->code, fModifiers,
- fDeadKey);
- } else {
- // Show the key code if there is no keymap
- snprintf(text, sizeof(text), "%02" B_PRIx32, key->code);
- }
-
- _SetFontSize(view, keyKind);
-
- if (secondDeadKey)
- base = kSecondDeadKeyColor;
- else if (deadKey > 0 && isDeadKeyEnabled)
- base = kDeadKeyColor;
-
- if (key->shape == kRectangleKeyShape) {
- _DrawKeyButton(view, rect, updateRect, base, background, pressed);
-
- rect.InsetBy(1, 1);
-
- _GetAbbreviatedKeyLabelIfNeeded(view, rect, key, text, sizeof(text));
- be_control_look->DrawLabel(view, text, rect, updateRect,
- base, 0, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE));
- } else if (key->shape == kEnterKeyShape) {
- BRect topLeft = rect;
- BRect topRight = rect;
- BRect bottomLeft = rect;
- BRect bottomRight = rect;
-
- // TODO: for some reason, this does not always equal the bottom of
- // the other keys...
- bottomLeft.top = floorf(rect.top
- + fLayout->DefaultKeySize().height * fFactor - fGap - 1);
- bottomLeft.right = floorf(rect.left
- + (key->frame.Width() - key->second_row) * fFactor - fGap - 2);
-
- topLeft.bottom = bottomLeft.top;
- topLeft.right = bottomLeft.right + 1;
- // add one to make the borders meet
-
- topRight.bottom = topLeft.bottom;
- topRight.left = topLeft.right;
-
- bottomRight.top = bottomLeft.top;
- bottomRight.left = bottomLeft.right;
-
- // draw top left corner
- be_control_look->DrawButtonFrame(view, topLeft, updateRect,
- 4.0f, 0.0f, 4.0f, 0.0f, base, background,
- pressed ? BControlLook::B_ACTIVATED : 0,
- BControlLook::B_LEFT_BORDER | BControlLook::B_TOP_BORDER
- | BControlLook::B_BOTTOM_BORDER);
- be_control_look->DrawButtonBackground(view, topLeft, updateRect,
- 4.0f, 0.0f, 4.0f, 0.0f, base,
- pressed ? BControlLook::B_ACTIVATED : 0,
- BControlLook::B_LEFT_BORDER | BControlLook::B_TOP_BORDER
- | BControlLook::B_BOTTOM_BORDER);
-
- // draw top right corner
- be_control_look->DrawButtonFrame(view, topRight, updateRect,
- 0.0f, 4.0f, 0.0f, 0.0f, base, background,
- pressed ? BControlLook::B_ACTIVATED : 0,
- BControlLook::B_TOP_BORDER | BControlLook::B_RIGHT_BORDER);
- be_control_look->DrawButtonBackground(view, topRight, updateRect,
- 0.0f, 4.0f, 0.0f, 0.0f, base,
- pressed ? BControlLook::B_ACTIVATED : 0,
- BControlLook::B_TOP_BORDER | BControlLook::B_RIGHT_BORDER);
-
- // draw bottom right corner
- be_control_look->DrawButtonFrame(view, bottomRight, updateRect,
- 0.0f, 0.0f, 4.0f, 4.0f, base, background,
- pressed ? BControlLook::B_ACTIVATED : 0,
- BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER
- | BControlLook::B_BOTTOM_BORDER);
- be_control_look->DrawButtonBackground(view, bottomRight, updateRect,
- 0.0f, 0.0f, 4.0f, 4.0f, base,
- pressed ? BControlLook::B_ACTIVATED : 0,
- BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER
- | BControlLook::B_BOTTOM_BORDER);
-
- // clip out the bottom left corner
- bottomLeft.right += 1;
- bottomLeft.top -= 2;
- BRegion region(rect);
- region.Exclude(bottomLeft);
- view->ConstrainClippingRegion(®ion);
-
- // Fill in the rect with the background color
- SetHighColor(background);
- FillRect(rect);
-
- // draw the button background
- BRect bgRect = rect.InsetByCopy(2, 2);
- be_control_look->DrawButtonBackground(view, bgRect, updateRect,
- 4.0f, 4.0f, 0.0f, 4.0f, base,
- pressed ? BControlLook::B_ACTIVATED : 0);
-
- rect.left = bottomLeft.right;
- _GetAbbreviatedKeyLabelIfNeeded(view, rect, key, text, sizeof(text));
-
- // draw the button label
- be_control_look->DrawLabel(view, text, rect, updateRect,
- base, 0, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE));
-
- // reset the clipping region
- view->ConstrainClippingRegion(NULL);
- }
-}
-
-
-void
-KeyboardLayoutView::_DrawIndicator(BView* view, BRect updateRect,
- const Indicator* indicator, BRect rect, bool lit)
-{
- float rectTop = rect.top;
- rect.top += 2 * rect.Height() / 3;
-
- const char* label = NULL;
- if (indicator->modifier == B_CAPS_LOCK)
- label = "caps";
- else if (indicator->modifier == B_NUM_LOCK)
- label = "num";
- else if (indicator->modifier == B_SCROLL_LOCK)
- label = "scroll";
- if (label != NULL) {
- _SetFontSize(view, kIndicator);
-
- font_height fontHeight;
- GetFontHeight(&fontHeight);
- if (ceilf(rect.top - fontHeight.ascent + fontHeight.descent - 2)
- >= rectTop) {
- view->SetHighColor(0, 0, 0);
- view->SetLowColor(ViewColor());
-
- BString text(label);
- view->TruncateString(&text, B_TRUNCATE_END, rect.Width());
- view->DrawString(text.String(),
- BPoint(ceilf(rect.left + (rect.Width()
- - StringWidth(text.String())) / 2),
- ceilf(rect.top - fontHeight.descent - 2)));
- }
- }
-
- rect.left += rect.Width() / 4;
- rect.right -= rect.Width() / 3;
-
- rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
- rgb_color base = lit ? kLitIndicatorColor : kDarkColor;
-
- be_control_look->DrawButtonFrame(view, rect, updateRect, base,
- background, BControlLook::B_DISABLED);
- be_control_look->DrawButtonBackground(view, rect, updateRect,
- base, BControlLook::B_DISABLED);
-}
-
-
-const char*
-KeyboardLayoutView::_SpecialKeyLabel(const key_map& map, uint32 code,
- bool abbreviated)
-{
- if (code == map.caps_key)
- return abbreviated ? "CAPS" : "CAPS LOCK";
- if (code == map.scroll_key)
- return "SCROLL";
- if (code == map.num_key)
- return abbreviated ? "NUM" : "NUM LOCK";
- if (code == map.left_shift_key || code == map.right_shift_key)
- return "SHIFT";
- if (code == map.left_command_key || code == map.right_command_key)
- return abbreviated ? "CMD" : "COMMAND";
- if (code == map.left_control_key || code == map.right_control_key)
- return abbreviated ? "CTRL" : "CONTROL";
- if (code == map.left_option_key || code == map.right_option_key)
- return abbreviated ? "OPT" : "OPTION";
- if (code == map.menu_key)
- return "MENU";
- if (code == B_PRINT_KEY)
- return "PRINT";
- if (code == B_PAUSE_KEY)
- return "PAUSE";
-
- return NULL;
-}
-
-
-const char*
-KeyboardLayoutView::_SpecialMappedKeySymbol(const char* bytes, size_t numBytes)
-{
- if (numBytes != 1)
- return NULL;
-
- if (bytes[0] == B_TAB)
- return "\xe2\x86\xb9";
- if (bytes[0] == B_ENTER)
- return "\xe2\x86\xb5";
- if (bytes[0] == B_BACKSPACE)
- return "\xe2\x8c\xab";
-
- if (bytes[0] == B_UP_ARROW)
- return "\xe2\x86\x91";
- if (bytes[0] == B_LEFT_ARROW)
- return "\xe2\x86\x90";
- if (bytes[0] == B_DOWN_ARROW)
- return "\xe2\x86\x93";
- if (bytes[0] == B_RIGHT_ARROW)
- return "\xe2\x86\x92";
-
- return NULL;
-}
-
-
-const char*
-KeyboardLayoutView::_SpecialMappedKeyLabel(const char* bytes, size_t numBytes,
- bool abbreviated)
-{
- if (numBytes != 1)
- return NULL;
-
- if (bytes[0] == B_ESCAPE)
- return "ESC";
-
- if (bytes[0] == B_INSERT)
- return "INS";
- if (bytes[0] == B_DELETE)
- return "DEL";
- if (bytes[0] == B_HOME)
- return "HOME";
- if (bytes[0] == B_END)
- return "END";
- if (bytes[0] == B_PAGE_UP)
- return abbreviated ? "PG \xe2\x86\x91" : "PAGE \xe2\x86\x91";
- if (bytes[0] == B_PAGE_DOWN)
- return abbreviated ? "PG \xe2\x86\x93" : "PAGE \xe2\x86\x93";
-
- return NULL;
-}
-
-
-bool
-KeyboardLayoutView::_FunctionKeyLabel(uint32 code, char* text, size_t textSize)
-{
- if (code >= B_F1_KEY && code <= B_F12_KEY) {
- snprintf(text, textSize, "F%" B_PRId32, code + 1 - B_F1_KEY);
- return true;
- }
-
- return false;
-}
-
-
-void
-KeyboardLayoutView::_GetAbbreviatedKeyLabelIfNeeded(BView* view, BRect rect,
- const Key* key, char* text, size_t textSize)
-{
- if (floorf(rect.Width()) > ceilf(view->StringWidth(text)))
- return;
-
- // Check if we have a shorter version of this key
-
- const key_map& map = fKeymap->Map();
-
- const char* special = _SpecialKeyLabel(map, key->code, true);
- if (special != NULL) {
- strlcpy(text, special, textSize);
- return;
- }
-
- char* bytes = NULL;
- int32 numBytes;
- fKeymap->GetChars(key->code, fModifiers, fDeadKey, &bytes, &numBytes);
- if (bytes != NULL) {
- special = _SpecialMappedKeyLabel(bytes, numBytes, true);
- if (special != NULL)
- strlcpy(text, special, textSize);
-
- delete[] bytes;
- }
-}
-
-
-void
-KeyboardLayoutView::_GetKeyLabel(const Key* key, char* text, size_t textSize,
- key_kind& keyKind)
-{
- const key_map& map = fKeymap->Map();
- keyKind = kNormalKey;
- text[0] = '\0';
-
- const char* special = _SpecialKeyLabel(map, key->code);
- if (special != NULL) {
- strlcpy(text, special, textSize);
- keyKind = kSpecialKey;
- return;
- }
-
- if (_FunctionKeyLabel(key->code, text, textSize)) {
- keyKind = kSpecialKey;
- return;
- }
-
- char* bytes = NULL;
- int32 numBytes;
- fKeymap->GetChars(key->code, fModifiers, fDeadKey, &bytes, &numBytes);
- if (bytes != NULL) {
- special = _SpecialMappedKeyLabel(bytes, numBytes);
- if (special != NULL) {
- strlcpy(text, special, textSize);
- keyKind = kSpecialKey;
- } else {
- special = _SpecialMappedKeySymbol(bytes, numBytes);
- if (special != NULL) {
- strlcpy(text, special, textSize);
- keyKind = kSymbolKey;
- } else {
- bool hasGlyphs;
- fBaseFont.GetHasGlyphs(bytes, 1, &hasGlyphs);
- if (hasGlyphs)
- strlcpy(text, bytes, textSize);
- }
- }
-
- delete[] bytes;
- }
-}
-
-
-bool
-KeyboardLayoutView::_IsKeyPressed(uint32 code)
-{
- if (fDropTarget != NULL && fDropTarget->code == code)
- return true;
-
- return _KeyState(code);
-}
-
-
-bool
-KeyboardLayoutView::_KeyState(uint32 code) const
-{
- if (code >= 16 * 8)
- return false;
-
- return (fKeyState[code / 8] & (1 << (7 - (code & 7)))) != 0;
-}
-
-
-void
-KeyboardLayoutView::_SetKeyState(uint32 code, bool pressed)
-{
- if (code >= 16 * 8)
- return;
-
- if (pressed)
- fKeyState[code / 8] |= (1 << (7 - (code & 7)));
- else
- fKeyState[code / 8] &= ~(1 << (7 - (code & 7)));
-}
-
-
-Key*
-KeyboardLayoutView::_KeyForCode(uint32 code)
-{
- // TODO: have a lookup array
-
- for (int32 i = 0; i < fLayout->CountKeys(); i++) {
- Key* key = fLayout->KeyAt(i);
- if (key->code == code)
- return key;
- }
-
- return NULL;
-}
-
-
-void
-KeyboardLayoutView::_InvalidateKey(uint32 code)
-{
- _InvalidateKey(_KeyForCode(code));
-}
-
-
-void
-KeyboardLayoutView::_InvalidateKey(const Key* key)
-{
- if (key != NULL)
- Invalidate(_FrameFor(key));
-}
-
-
-/*! Updates the fDeadKey member, and invalidates the view if needed.
-
- \return true if the view has been invalidated.
-*/
-bool
-KeyboardLayoutView::_HandleDeadKey(uint32 key, int32 modifiers)
-{
- if (fKeymap == NULL || fKeymap->IsModifierKey(key))
- return false;
-
- bool isEnabled = false;
- int32 deadKey = fKeymap->DeadKey(key, modifiers, &isEnabled);
- if (fDeadKey != deadKey) {
- if (isEnabled) {
- Invalidate();
- fDeadKey = deadKey;
- return true;
- }
- } else if (fDeadKey != 0) {
- Invalidate();
- fDeadKey = 0;
- return true;
- }
-
- return false;
-}
-
-
-void
-KeyboardLayoutView::_KeyChanged(const BMessage* message)
-{
- const uint8* state;
- ssize_t size;
- int32 key;
- if (message->FindData("states", B_UINT8_TYPE, (const void**)&state, &size)
- != B_OK
- || message->FindInt32("key", &key) != B_OK)
- return;
-
- // Update key state, and invalidate change keys
-
- bool checkSingle = true;
-
- if (message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN) {
- if (_HandleDeadKey(key, fModifiers))
- checkSingle = false;
-
- if (_KeyForCode(key) == NULL)
- printf("no key for code %" B_PRId32 "\n", key);
- }
-
- for (int32 i = 0; i < 16; i++) {
- if (fKeyState[i] != state[i]) {
- uint8 diff = fKeyState[i] ^ state[i];
- fKeyState[i] = state[i];
-
- if (!checkSingle || !Window()->IsActive())
- continue;
-
- for (int32 j = 7; diff != 0; j--, diff >>= 1) {
- if (diff & 1) {
- _InvalidateKey(i * 8 + j);
- }
- }
- }
- }
-}
-
-
-Key*
-KeyboardLayoutView::_KeyAt(BPoint point)
-{
- // Find key candidate
-
- BPoint keyPoint = point;
- keyPoint -= fOffset;
- keyPoint.x /= fFactor;
- keyPoint.y /= fFactor;
-
- for (int32 i = 0; i < fLayout->CountKeys(); i++) {
- Key* key = fLayout->KeyAt(i);
- if (key->frame.Contains(keyPoint)) {
- BRect frame = _FrameFor(key);
- if (frame.Contains(point))
- return key;
-
- return NULL;
- }
- }
-
- return NULL;
-}
-
-
-BRect
-KeyboardLayoutView::_FrameFor(BRect keyFrame)
-{
- BRect rect;
- rect.left = ceilf(keyFrame.left * fFactor);
- rect.top = ceilf(keyFrame.top * fFactor);
- rect.right = floorf((keyFrame.Width()) * fFactor + rect.left - fGap - 1);
- rect.bottom = floorf((keyFrame.Height()) * fFactor + rect.top - fGap - 1);
- rect.OffsetBy(fOffset);
-
- return rect;
-}
-
-
-BRect
-KeyboardLayoutView::_FrameFor(const Key* key)
-{
- return _FrameFor(key->frame);
-}
-
-
-void
-KeyboardLayoutView::_SetFontSize(BView* view, key_kind keyKind)
-{
- BSize size = fLayout->DefaultKeySize();
- float fontSize = fBaseFontSize;
- if (fBaseFontHeight >= size.height * fFactor * 0.5) {
- fontSize *= (size.height * fFactor * 0.5) / fBaseFontHeight;
- if (fontSize < 8)
- fontSize = 8;
- }
-
- switch (keyKind) {
- case kNormalKey:
- fBaseFont.SetSize(fontSize);
- view->SetFont(&fBaseFont);
- break;
- case kSpecialKey:
- fSpecialFont.SetSize(fontSize * 0.7);
- view->SetFont(&fSpecialFont);
- break;
- case kSymbolKey:
- fSpecialFont.SetSize(fontSize * 1.6);
- view->SetFont(&fSpecialFont);
- break;
-
- case kIndicator:
- {
- BFont font;
- font.SetSize(fontSize * 0.8);
- view->SetFont(&font);
- break;
- }
- }
-}
-
-
-void
-KeyboardLayoutView::_EvaluateDropTarget(BPoint point)
-{
- fDropTarget = _KeyAt(point);
- if (fDropTarget != NULL) {
- if (fDropTarget == fDragKey && fModifiers == fDragModifiers)
- fDropTarget = NULL;
- else
- _InvalidateKey(fDropTarget);
- }
-}
-
-
-void
-KeyboardLayoutView::_SendKeyDown(const Key* key)
-{
- KID_CALLED();
-
- BMessage* message = new BMessage(B_KEY_DOWN);
- message->AddInt64("when", system_time());
- message->AddData("states", B_UINT8_TYPE, &fKeyState,
- sizeof(fKeyState));
- message->AddInt32("key", key->code);
- message->AddInt32("modifiers", fModifiers);
- message->AddInt32("be:key_repeat", 1);
- //message.AddPointer("keymap", fKeymap);
-
- char* string;
- int32 numBytes;
- fKeymap->GetChars(key->code, fModifiers, fDeadKey, &string,
- &numBytes);
- if (string != NULL) {
- message->AddString("bytes", string);
- delete[] string;
- }
-
- fKeymap->GetChars(key->code, 0, 0, &string, &numBytes);
- if (string != NULL) {
- message->AddInt32("raw_char", string[0]);
- message->AddInt8("byte", string[0]);
- delete[] string;
- }
-
- if (fDevice->EnqueueMessage(message) != B_OK)
- delete message;
-
-}
diff --git a/src/add-ons/input_server/devices/virtualkeyboard/KeyboardLayoutView.h b/src/add-ons/input_server/devices/virtualkeyboard/KeyboardLayoutView.h
deleted file mode 100644
index 6805bfce5b..0000000000
--- a/src/add-ons/input_server/devices/virtualkeyboard/KeyboardLayoutView.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
- * Distributed under the terms of the MIT License.
- */
-#ifndef KEYBOARD_LAYOUT_VIEW_H
-#define KEYBOARD_LAYOUT_VIEW_H
-
-
-#include
-#include
-#include
-
-#include "KeyboardLayout.h"
-
-
-class Keymap;
-
-
-class KeyboardLayoutView : public BView {
-public:
- KeyboardLayoutView(const char* name,
- BInputServerDevice* dev);
- ~KeyboardLayoutView();
-
- void SetKeyboardLayout(KeyboardLayout* layout);
- void SetKeymap(Keymap* keymap);
- void SetTarget(BMessenger target);
-
- KeyboardLayout* GetKeyboardLayout() { return fLayout; }
-
- void SetBaseFont(const BFont& font);
-
- void SetEditable(bool editable);
-
-protected:
- virtual void AttachedToWindow();
- virtual void FrameResized(float width, float height);
- virtual BSize MinSize();
-
- virtual void KeyDown(const char* bytes, int32 numBytes);
- virtual void KeyUp(const char* bytes, int32 numBytes);
- virtual void MouseDown(BPoint point);
- virtual void MouseUp(BPoint point);
- virtual void MouseMoved(BPoint point, uint32 transit,
- const BMessage* dragMessage);
-
- virtual void Draw(BRect updateRect);
- virtual void MessageReceived(BMessage* message);
- virtual void WindowActivated(bool active);
-
-private:
- enum key_kind {
- kNormalKey,
- kSpecialKey,
- kSymbolKey,
- kIndicator
- };
-
- void _InitOffscreen();
- void _LayoutKeyboard();
- void _DrawKeyButton(BView* view, BRect& rect,
- BRect updateRect, rgb_color base,
- rgb_color background, bool pressed);
- void _DrawKey(BView* view, BRect updateRect,
- const Key* key, BRect frame, bool pressed);
- void _DrawIndicator(BView* view, BRect updateRect,
- const Indicator* indicator, BRect rect,
- bool lit);
- const char* _SpecialKeyLabel(const key_map& map,
- uint32 code, bool abbreviated = false);
- const char* _SpecialMappedKeySymbol(const char* bytes,
- size_t numBytes);
- const char* _SpecialMappedKeyLabel(const char* bytes,
- size_t numBytes, bool abbreviated = false);
- bool _FunctionKeyLabel(uint32 code, char* text,
- size_t textSize);
- void _GetAbbreviatedKeyLabelIfNeeded(BView* view,
- BRect rect, const Key* key, char* text,
- size_t textSize);
- void _GetKeyLabel(const Key* key, char* text,
- size_t textSize, key_kind& keyKind);
- bool _IsKeyPressed(uint32 code);
- bool _KeyState(uint32 code) const;
- void _SetKeyState(uint32 code, bool pressed);
- Key* _KeyForCode(uint32 code);
- void _InvalidateKey(uint32 code);
- void _InvalidateKey(const Key* key);
- bool _HandleDeadKey(uint32 key, int32 modifiers);
- void _KeyChanged(const BMessage* message);
- Key* _KeyAt(BPoint point);
- BRect _FrameFor(BRect keyFrame);
- BRect _FrameFor(const Key* key);
- void _SetFontSize(BView* view, key_kind keyKind);
- void _EvaluateDropTarget(BPoint point);
- void _SendKeyDown(const Key* key);
-
- BBitmap* fOffscreenBitmap;
- BView* fOffscreenView;
-
- KeyboardLayout* fLayout;
- Keymap* fKeymap;
- BMessenger fTarget;
- bool fEditable;
-
- uint8 fKeyState[16];
- int32 fModifiers;
- int32 fDeadKey;
- int32 fButtons;
-
- BPoint fClickPoint;
- Key* fDragKey;
- int32 fDragModifiers;
- Key* fDropTarget;
- BPoint fDropPoint;
-
- BSize fOldSize;
- BFont fBaseFont;
- BFont fSpecialFont;
- float fBaseFontHeight;
- float fBaseFontSize;
- BPoint fOffset;
- float fFactor;
- float fGap;
-
- BInputServerDevice* fDevice;
-};
-
-
-#endif // KEYBOARD_LAYOUT_VIEW_H
diff --git a/src/add-ons/input_server/devices/virtualkeyboard/VirtualKeyboardWindow.cpp b/src/add-ons/input_server/devices/virtualkeyboard/VirtualKeyboardWindow.cpp
index 6086e393ea..596961172b 100644
--- a/src/add-ons/input_server/devices/virtualkeyboard/VirtualKeyboardWindow.cpp
+++ b/src/add-ons/input_server/devices/virtualkeyboard/VirtualKeyboardWindow.cpp
@@ -61,7 +61,6 @@ VirtualKeyboardWindow::VirtualKeyboardWindow(BInputServerDevice* dev)
fKeyboardView = new KeyboardLayoutView("Keyboard",fDevice);
fKeyboardView->GetKeyboardLayout()->SetDefault();
- fKeyboardView->SetEditable(false);
fKeyboardView->SetKeymap(&fCurrentKeymap);
AddChild(BGroupLayoutBuilder(B_VERTICAL)
@@ -130,7 +129,7 @@ VirtualKeyboardWindow::_LoadMaps()
if (directory.SetTo(path.Path()) == B_OK) {
while (directory.GetNextRef(&ref) == B_OK) {
- fMapListView->AddItem(new KeymapListItem(ref));
+ fMapListView->AddItem(new KeymapListItem(ref));
}
}
fMapListView->SortItems(&compare_key_list_items);
diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp
index c9890eaa79..8432dc396f 100644
--- a/src/preferences/keymap/KeyboardLayoutView.cpp
+++ b/src/preferences/keymap/KeyboardLayoutView.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -80,17 +81,18 @@ is_mappable_to_modifier(uint32 keyCode)
// #pragma mark - KeyboardLayoutView
-KeyboardLayoutView::KeyboardLayoutView(const char* name)
+KeyboardLayoutView::KeyboardLayoutView(const char* name, BInputServerDevice* dev)
:
BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
fKeymap(NULL),
- fEditable(true),
+ fEditable(dev == NULL),
fModifiers(0),
fDeadKey(0),
fButtons(0),
fDragKey(NULL),
fDropTarget(NULL),
- fOldSize(0, 0)
+ fOldSize(0, 0),
+ fDevice(dev)
{
fLayout = new KeyboardLayout;
memset(fKeyState, 0, sizeof(fKeyState));
@@ -210,7 +212,7 @@ KeyboardLayoutView::MouseDown(BPoint point)
|| ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0
&& (modifiers() & B_CONTROL_KEY) != 0)) {
// secondary mouse button, pop up a swap context menu
- if (!is_mappable_to_modifier(key->code)) {
+ if (fEditable && !is_mappable_to_modifier(key->code)) {
// ToDo: Pop up a list of alternative characters to map
// the key to. Currently we only add an option to remove the
// current key mapping.
@@ -224,7 +226,7 @@ KeyboardLayoutView::MouseDown(BPoint point)
alternativesPopUp->SetAsyncAutoDestruct(true);
if (alternativesPopUp->SetTargetForItems(Window()) == B_OK)
alternativesPopUp->Go(ConvertToScreen(point), true);
- } else {
+ } else if (fEditable) {
// pop up the modifier keys menu
BPopUpMenu* modifiersPopUp = new BPopUpMenu("Modifiers pop up",
true, true, B_ITEMS_IN_COLUMN);
@@ -403,7 +405,7 @@ KeyboardLayoutView::MouseUp(BPoint point)
_InvalidateKey(key);
if (fDragKey == NULL)
- _SendFakeKeyDown(key);
+ _SendKeyDown(key);
}
fDragKey = NULL;
@@ -417,6 +419,10 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
if (fKeymap == NULL)
return;
+ // Ignore mouse-moved events if we are acting as a real input device.
+ if (fDevice != NULL)
+ return;
+
// prevent dragging for tertiary mouse button
if ((fButtons & B_TERTIARY_MOUSE_BUTTON) != 0)
return;
@@ -607,7 +613,7 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
}
} else {
// Send the old key to the target, so it's not lost entirely
- _SendFakeKeyDown(fDropTarget);
+ _SendKeyDown(fDropTarget);
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
(const char*)data, dataSize);
@@ -1290,7 +1296,7 @@ KeyboardLayoutView::_EvaluateDropTarget(BPoint point)
void
-KeyboardLayoutView::_SendFakeKeyDown(const Key* key)
+KeyboardLayoutView::_SendKeyDown(const Key* key)
{
BMessage message(B_KEY_DOWN);
message.AddInt64("when", system_time());
@@ -1298,7 +1304,10 @@ KeyboardLayoutView::_SendFakeKeyDown(const Key* key)
sizeof(fKeyState));
message.AddInt32("key", key->code);
message.AddInt32("modifiers", fModifiers);
- message.AddPointer("keymap", fKeymap);
+ message.AddInt32("be:key_repeat", 1);
+
+ if (fDevice == NULL)
+ message.AddPointer("keymap", fKeymap);
char* string;
int32 numBytes;
@@ -1316,7 +1325,15 @@ KeyboardLayoutView::_SendFakeKeyDown(const Key* key)
delete[] string;
}
- fTarget.SendMessage(&message);
+ if (fDevice == NULL) {
+ fTarget.SendMessage(&message);
+ } else {
+#if defined(VIRTUAL_KEYBOARD_DEVICE)
+ BMessage* deviceMessage = new BMessage(message);
+ if (fDevice->EnqueueMessage(deviceMessage) != B_OK)
+ delete deviceMessage;
+#endif
+ }
}
diff --git a/src/preferences/keymap/KeyboardLayoutView.h b/src/preferences/keymap/KeyboardLayoutView.h
index 0d1d485732..a9b638112a 100644
--- a/src/preferences/keymap/KeyboardLayoutView.h
+++ b/src/preferences/keymap/KeyboardLayoutView.h
@@ -17,13 +17,15 @@
#include "KeyboardLayout.h"
+class BInputServerDevice;
class BMenuItem;
class Keymap;
class KeyboardLayoutView : public BView {
public:
- KeyboardLayoutView(const char* name);
+ KeyboardLayoutView(const char* name,
+ BInputServerDevice* dev = NULL);
~KeyboardLayoutView();
void SetKeyboardLayout(KeyboardLayout* layout);
@@ -95,7 +97,7 @@ private:
BRect _FrameFor(const Key* key);
void _SetFontSize(BView* view, key_kind keyKind);
void _EvaluateDropTarget(BPoint point);
- void _SendFakeKeyDown(const Key* key);
+ void _SendKeyDown(const Key* key);
BMenuItem* _CreateSwapModifiersMenuItem(uint32 modifier,
uint32 displayModifier, uint32 oldCode,
@@ -126,6 +128,8 @@ private:
BPoint fOffset;
float fFactor;
float fGap;
+
+ BInputServerDevice* fDevice;
};