Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt key translation #5

Merged
merged 7 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
iso-codes \
json-c \
openssl@3 \
libevent
libuv
cp -f /usr/local/bin/msgfmt /opt/homebrew/bin

- name: Build
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Cross build from Intel to Apple Silicon is performed in [CI](.github/workflows/c

### Install dependencies
```sh
brew install cmake ninja extra-cmake-modules gettext fmt libevent libxkbcommon iso-codes json-c
brew install cmake ninja extra-cmake-modules gettext fmt libuv libxkbcommon iso-codes json-c
```

### Build with CMake
Expand All @@ -22,4 +22,5 @@ sudo cmake --install build

## Credits
* [fcitx5-android](https://github.com/fcitx5-android/fcitx5-android): LGPL-2.1-or-later
* [squirrel](https://github.com/rime/squirrel): GPL-3.0-only
* [swift-cmake-examples](https://github.com/apple/swift-cmake-examples): Apache-2.0
6 changes: 4 additions & 2 deletions include/fcitx.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#ifndef FCITX5_MACOS_FCITX_H
#define FCITX5_MACOS_FCITX_H
#include <string>

#include <cstdint>
#include "fcitx-swift.h"

void start_fcitx();
bool process_key(std::string key);
// Though being UInt, 32b is enough for modifiers
bool process_key(uint32_t unicode, uint32_t osxModifiers, uint16_t osxKeycode);

#endif
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_executable(Fcitx5
server.swift
controller.swift
fcitx.cpp
keycode.cpp
)

add_dependencies(Fcitx5 macosfrontend)
Expand Down
14 changes: 9 additions & 5 deletions src/controller.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,21 @@ class FcitxInputController: IMKInputController {
return false
}
setClient(client)
var keySym = ""
switch event.type {
case .keyDown:
var unicode: UInt32 = 0
if let characters = event.characters {
keySym = characters
let usv = characters.unicodeScalars
unicode = usv[usv.startIndex].value
}
let code = event.keyCode
let modifiers = UInt32(event.modifierFlags.rawValue)
let handled = process_key(unicode, modifiers, code)
return handled
default:
NSLog("\(event.type)")
NSLog("Unhandled event: \(String(describing: event.type))")
return false
}
let accepted = process_key(std.string(keySym))
return accepted
}

override func candidates(_ sender: Any!) -> [Any]! {
Expand Down
9 changes: 7 additions & 2 deletions src/fcitx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <fcitx/instance.h>
#include "../macosfrontend/macosfrontend.h"
#include "keyboard.h"
#include "keycode.h"
#include "nativestreambuf.h"

#define APP_CONTENTS_PATH "/Library/Input Methods/Fcitx5.app/Contents"
Expand Down Expand Up @@ -58,7 +59,11 @@ void start_fcitx() {
ic_uuid = p_frontend->createInputContext();
}

bool process_key(std::string key) {
const fcitx::Key parsedKey{fcitx::Key::keySymFromString(key)};
bool process_key(uint32_t unicode, uint32_t osxModifiers, uint16_t osxKeycode) {
const fcitx::Key parsedKey{
fcitx::Key::keySymFromUnicode(unicode),
osx_modifiers_to_fcitx_keystates(osxModifiers),
osx_keycode_to_fcitx_keycode(osxKeycode),
};
return p_frontend->keyEvent(ic_uuid, parsedKey);
}
157 changes: 157 additions & 0 deletions src/keycode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#include "keycode.h"
#include <cstring>

static struct {
uint16_t osxKeycode;
uint16_t linuxKeycode;
} mappings[] = {
// alphabet
{OSX_VK_A, 30},
{OSX_VK_B, 48},
{OSX_VK_C, 46},
{OSX_VK_D, 32},
{OSX_VK_E, 18},
{OSX_VK_F, 33},
{OSX_VK_G, 34},
{OSX_VK_H, 35},
{OSX_VK_I, 23},
{OSX_VK_J, 36},
{OSX_VK_K, 37},
{OSX_VK_L, 38},
{OSX_VK_M, 50},
{OSX_VK_N, 49},
{OSX_VK_O, 24},
{OSX_VK_P, 25},
{OSX_VK_Q, 16},
{OSX_VK_R, 19},
{OSX_VK_S, 31},
{OSX_VK_T, 20},
{OSX_VK_U, 22},
{OSX_VK_V, 47},
{OSX_VK_W, 17},
{OSX_VK_X, 45},
{OSX_VK_Y, 21},
{OSX_VK_Z, 44},

// number
{OSX_VK_KEY_0, 11},
{OSX_VK_KEY_1, 2},
{OSX_VK_KEY_2, 3},
{OSX_VK_KEY_3, 4},
{OSX_VK_KEY_4, 5},
{OSX_VK_KEY_5, 6},
{OSX_VK_KEY_6, 7},
{OSX_VK_KEY_7, 8},
{OSX_VK_KEY_8, 9},
{OSX_VK_KEY_9, 10},

// symbol
{OSX_VK_BACKQUOTE, 41},
{OSX_VK_BACKSLASH, 43},
{OSX_VK_BRACKET_LEFT, 26},
{OSX_VK_BRACKET_RIGHT, 27},
{OSX_VK_COMMA, 51},
{OSX_VK_DOT, 52},
{OSX_VK_EQUAL, 13},
{OSX_VK_MINUS, 12},
{OSX_VK_QUOTE, 40},
{OSX_VK_SEMICOLON, 39},
{OSX_VK_SLASH, 53},

// keypad
{OSX_VK_KEYPAD_0, 82},
{OSX_VK_KEYPAD_1, 79},
{OSX_VK_KEYPAD_2, 80},
{OSX_VK_KEYPAD_3, 81},
{OSX_VK_KEYPAD_4, 75},
{OSX_VK_KEYPAD_5, 76},
{OSX_VK_KEYPAD_6, 77},
{OSX_VK_KEYPAD_7, 71},
{OSX_VK_KEYPAD_8, 72},
{OSX_VK_KEYPAD_9, 73},
// {OSX_VK_KEYPAD_CLEAR, }, XXX: not sure map to what
{OSX_VK_KEYPAD_COMMA, 121},
{OSX_VK_KEYPAD_DOT, 83},
{OSX_VK_KEYPAD_EQUAL, 117},
{OSX_VK_KEYPAD_MINUS, 74},
{OSX_VK_KEYPAD_MULTIPLY, 55},
{OSX_VK_KEYPAD_PLUS, 78},
{OSX_VK_KEYPAD_SLASH, 98},

// special
{OSX_VK_DELETE, 14},
{OSX_VK_ENTER, 96},
// {OSX_VK_ENTER_POWERBOOK, }, XXX: not sure map to what
{OSX_VK_ESCAPE, 1},
{OSX_VK_FORWARD_DELETE, 111},
// {OSX_VK_HELP, }, XXX: not sure map to what
{OSX_VK_RETURN, 28},
{OSX_VK_SPACE, 57},
{OSX_VK_TAB, 15},

// function
{OSX_VK_F1, 59},
{OSX_VK_F2, 60},
{OSX_VK_F3, 61},
{OSX_VK_F4, 62},
{OSX_VK_F5, 63},
{OSX_VK_F6, 64},
{OSX_VK_F7, 65},
{OSX_VK_F8, 66},
{OSX_VK_F9, 67},
{OSX_VK_F10, 68},
{OSX_VK_F11, 87},
{OSX_VK_F12, 88},

// cursor
{OSX_VK_CURSOR_UP, 103},
{OSX_VK_CURSOR_DOWN, 108},
{OSX_VK_CURSOR_LEFT, 105},
{OSX_VK_CURSOR_RIGHT, 106},

{OSX_VK_PAGEUP, 104},
{OSX_VK_PAGEDOWN, 109},
{OSX_VK_HOME, 102},
{OSX_VK_END, 107},

// modifiers
{OSX_VK_CAPSLOCK, 58},
{OSX_VK_COMMAND_L, 125},
{OSX_VK_COMMAND_R, 126},
{OSX_VK_CONTROL_L, 29},
{OSX_VK_CONTROL_R, 97},
{OSX_VK_FN, 0x1d0},
{OSX_VK_OPTION_L, 56},
{OSX_VK_OPTION_R, 100},
{OSX_VK_SHIFT_L, 42},
{OSX_VK_SHIFT_R, 54},
};

uint16_t osx_keycode_to_fcitx_keycode(uint16_t osxKeycode) {
for (const auto &pair : mappings) {
if (pair.osxKeycode == osxKeycode) {
return pair.linuxKeycode + 8 /* evdev offset */;
}
}
return 0;
}

fcitx::KeyStates osx_modifiers_to_fcitx_keystates(unsigned int osxModifiers) {
fcitx::KeyStates ret{};
if (osxModifiers & OSX_MODIFIER_CAPSLOCK) {
ret |= fcitx::KeyState::CapsLock;
}
if (osxModifiers & OSX_MODIFIER_SHIFT) {
ret |= fcitx::KeyState::Shift;
}
if (osxModifiers & OSX_MODIFIER_CONTROL) {
ret |= fcitx::KeyState::Ctrl;
}
if (osxModifiers & OSX_MODIFIER_OPTION) {
ret |= fcitx::KeyState::Alt;
}
if (osxModifiers & OSX_MODIFIER_COMMAND) {
ret |= fcitx::KeyState::Super;
}
return ret;
}
Loading