Personal tools
You are here: Home KtJ's Blog
« September 2019 »
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
 
Document Actions

oyainputをカスタマイズしよう

by ktj posted at 2019-04-30 18:14 last modified 2019-06-29 09:42

前回の記事は汎用的でなくわかりづらいのでリライトします。

概要

oyainputは「Linux + X Window System + fcitx又はibus」の環境で親指シフトを実現させるソフトです。これまではLinuxで親指シフトを実現するためにはfcitx-anthy又はibus-anthyを利用する必要があり、かな漢字変換エンジンとしてあまり変換効率の良くないAnthyを選択せざるを得ませんでした[1]が、oyainputではmozc(Google日本語入力のかな漢字変換エンジンのオープンソース版)を利用可能となり、快適な親指シフト環境が可能となります。

[1]過去に遡ればSCIM-anthyやQ's Nicolatter for Xという選択肢もありました。後者ではWnn、VJE-Delta、ATOKなどの商用IMEのかな漢字変換エンジンが利用できました。

基本的な利用方法は上記の公式サイトや、Qiitaの@inwskatsube氏の投稿に書かれている通りです。ある程度のキーカスタマイズ[2]は可能なのですが、そのままでは「xmodmap[3]との併用時に期待通りに動作をしてくれない場合がある[4]」「oyainputが想定していない文字を入力することはできない」という制約があります。本記事では、ソースコードに手を加えることでこの制約にとらわれない詳細なカスタマイズを行う方法を提供することを試みています。その際、チュートリアルとして英数入力モード含めFMV-KB613風の配列にするカスタマイズを行います。

[2]手順はダウンロードしたソースコード一式に含まれるドキュメント READMEJP.md に記載されています。
[3]ユーザ側でkeycode→keysymの変換テーブルを自由に設定するためのツール。セミコロンの右をBackspaceにしたり、左Ctrlと英数を入れ替えたりすることができる。
[4]oyainputは起動時にユーザが設定したxmodmapを無効にするようになっています(oyainputを終了させるとxmodmapの設定内容が再び有効になります)。xmodmapとoyainputを併用させる場合はoyainput立ち上げ後に改めてxmodmapを実行します。

原理

Linuxにおいては、OSのカーネルが「押された(又は離された)キーの情報」であるkeycodeを出力します。アプリケーションはキーイベント(キーが押されたか離されたか)を検出すると、X11からkeycodeを得てこれを文字情報であるkeysymに変換して処理します[5]。その際、日本語入力モードであれば、XIMという仕組みを介してIMEとやり取りして日本語に変換されたテキストを得ることができます[6] [7]

[5]あるkeycodeがどんなキーなのかはキーボードによって異なります。例えばUSキーボードのシングルクォートとJISキーボードのコロンは同じkeycodeを出力します。このため、アプリケーションは一旦keycodeをkeysymに変換する必要があります。また、keysymは文字情報なのでシフトキーが押されているかどうかに応じて変化します。
[6]Qiitaの@ai56go氏の投稿
[7]Ryo Ichinose氏のXlib Programming Lectures LECTURE10 キーボード入力処理の方法

oyainputは、日本語入力時に同時打鍵を含むキー入力を検出すると、keycode自体をすり替えてしまいます。例えば、右親指キーとセミコロンの同時打鍵を検出した場合、この同時打鍵を「x押→x離→t押→t離→u押→u離」にすり替え、結果的に「っ」が入力されます。また、親指キーと8の同時打鍵を検出した場合は「左シフト押→8押→8離→左シフト離」にすり替えて「(」が入力されるようにします。

このように、oyainputはkeycode自体をすり替えるものであるため、xmodmapを使って大幅にキーボードのレイアウトを変更している場合は希望通りの入力ができなくなる可能性があります[8]。また、そもそも標準のローマ字かな変換テーブルに登録されていない文字(,.等)は入力できません。

[8]例えば、シフト+8にドットを割り当てているような場合は、親指と8の同時打鍵で「。」が入力されてしまいます。

チュートリアルの目標

FMV-KB631の配列をベースに、下記のような特徴をもたせるレイアウトにしてみました。

  • 昔の106キーボードに刻印されておりNicolaに含まれていない£々¬¢を小指シフトで入力できるようにする[9]
  • 原則としてJIS X201 Roman相当の全角記号は全て入力できるようにする。具体的には上記£々¬¢や単独打鍵とかぶってしまう;+:*|を追加する
  • \と¥の両方を入力可能とする[10]。つまり、右シフトの左のキーでは従来通りのUTF-8コードx7E、バックスペースの左のキーではユニコードでの(全角でない)円記号つまりUTF-8コードxA5を入力可能とする[11]。かな入力時についても同様

結果としてレイアウトは下図のようになります。IMEはfcitx-mozcを採用します。

/img/blog/oyayubi.jpg
[9]Japanistだったかその前身のOAKだったかでは入力可能でしたので。
[10]JISキーボードには右シフトの左のキー(\)とバックスペースの左のキー(¥)の2つがあり、Windows等ではどちらも同じ文字が表示されます(UTF-8コードx7E。フォントによって¥か\のどちらかが表示されます。韓国のフォントだとウォン記号(₩)になることも。Windowsの仕様では「円記号(又はウォン記号)のような字形のバックスラッシュ」だったりします)。
[11]現在のMacが似たような実装になっています。Deleteの左のキーではコードxA5を入力するようになっており、コードx7Eはoption+Deleteの左のキーで入力します。ただターミナルではoptionなしでもコードx7Eが入力されます。

ステップ1: ローマ字かな変換テーブルの設定

ローマ字かな変換テーブルに無い[]『』.,£々¬¢/\用のテーブルを追加する必要があります。oyainputは小指シフト面については何もしないので、£々¬¢については必然的に=~|*に割り当てることになり、=|*には別の文字を割り当てる必要が出てきます(〜については"z-"というローマ字かな変換テーブルが設定済であり、oyainputも〜を入力したい時はz-のkeycodeにすり替えているため対策不要です)。fcitxでは記号類についてはzに続く一文字で出すように設定しているようなので、これに合わせて以下のようにしてみましょう。

= £
~
| ¬
* ¢
z=
z|
z*
z[
z]
z(
z)
z.
z,
z/
z\
z"
z'

ステップ2: 英数入力時のキーボードレイアウトの設定

一般に英数のカスタマイズは、ホームディレクトリに .Xmodmap というファイルを作り、oyainput起動後に xmodmap ~/.Xmodmap を実行することによって行われます。このチュートリアルでは

  • :→バックスペース
  • @→: *
  • ]→@ `
  • バックスペース→] }
  • ¥→¥ |

の5つですね。この場合.Xmodmapの内容は以下の通りです。

keycode 48 = BackSpace
keycode 34 = colon asterisk
keycode 51 = at grave
keycode 22 = bracketright braceright
keycode 132 = yen bar

この意味ですが、例えば二行目の keycode 34 = colon asterisk は「keycode34のキーの単独打鍵で:、シフトキーとの併用で*のkeysymを出力する」を意味します。今回は文字キーの入れ替えのみですが、モディファイヤーキー(シフト、コントロール等他のキーとのコンビネーションでkeysymを出力するキー)やロックキー(ロックされているかどうかで出力されるkeysymが変わるようなキー)の入れ替えを行う場合はもう少し複雑な書き方になります。keycodeは xev コマンドを実行することで取得できます。

ステップ3: oyainputのソースコードの修正

上述のようにoyainputは日本語入力時に単独打鍵、左右親指シフトとの同時打鍵があった時にkeycodeをすり替えるソフトです。どの打鍵が合った時にどの文字(=複数のkeycode)が出力されるのかは設定ファイル ~/.oyainputconf で設定可能ですが、未定義の文字については当然設定できず、また、xmodmap実行により出力されるべきkeycodeの組み合わせが変わってしまう場合もうまく行きません。そのため、ソースコードを修正する必要があります。

出力ローマ字は oyastate.c 内で [MOJI_ローマ字名] = {KEY_keycode名1,KEY_keycode名2,KEY_keycode名3} といった形で定義されています(入力されるべきキーコードが2つ以下の時は、残りの設定箇所には0を入れます)。ここで注意すべきことは、keycode名はUSキーボードがベースになっており、JISキーボードのキーの刻印とは必ずしも一致しないということです。keycodeとkeycode名の対応はUbuntuであれば /usr/include/linux/input-event-codes.h に記載されています。なお、keycodeの値も上述のxmodmap用のものと異なります。keycodeは sudo showkey -k で調べることができます。主要なkeycodeとkeycode名、JISキーボード上での刻印、実際に出力される文字の対応を以下に示します。一般的な109キーボードでは半角/全角キーはGRAVE、カタカナひらがなキーはKATAKANAHIRAGANAであることに注意下さい。

keycode keycode名 JISキーボードでの刻印 実際に入力される文字(xmodmap実行後)
13 EQUAL ^ ~ ^
14 BACKSPACE Back Space ]
26 LEFTBRACE @ ` :
27 RIGHTBRACE [ { [
40 APOSTROPHE : * Back Space
41 GRAVE 半角/全角 (半角/全角キー)
42 LEFTSHIFT Shift (左シフトキー)
43 BACKSLASH ] } @
51 COMMA , < ,
52 PERIOD . > .
53 SLASH / ? /
89 RO \ _ \
93 KATAKANAHIRAGANA カタカナ ひらがな (カタカナ ひらがなキー)
124 YEN \ | ¥
125 LEFTMETA Window (左Windowsキー)
126 RIGHTMETA Window (右Windowsキー)
127 COMPOSE Menu (メニューキー)

以上を踏まえて oyastate.c を以下のように変更します。

修正:

[MOJI_BS] = {KEY_APOSTROPHE,0,0}, /* MOJI_BS 90 */
[MOJI_SLASH] = {KEY_Z,KEY_SLASH,0}, /* MOJI_SLASH 92 */
[MOJI_LKAGI] = {KEY_Z,KEY_LEFTSHIFT, KEY_8}, /* MOJI_LKAGI 94 */
[MOJI_RKAGI] = {KEY_Z,KEY_LEFTSHIFT, KEY_9}, /* MOJI_RKAGI 95 */
[MOJI_LBRACKET] = {KEY_Z,KEY_RIGHTBRACE,0}, /* MOJI_LBRACKET 96 */
[MOJI_RBRACKET] = {KEY_Z,KEY_BACKSPACE,0}, /* MOJI_RBRACKET 97 */
[MOJI_PERIOD] = {KEY_Z,KEY_DOT,0}, /* MOJI_PERIOD 111 */
[MOJI_COMMA] = {KEY_Z,KEY_COMMA,0}, /* MOJI_COMMA 112 */
[MOJI_DAKUTEN] = {KEY_Z,KEY_LEFTSHIFT,KEY_2}, /* MOJI_DAKUTEN 116 */
[MOJI_HANDAKUTEN] = {KEY_Z,KEY_LEFTSHIFT,KEY_7}, /* MOJI_HANDAKUTEN 117 */
[MOJI_RKAKKO] = {KEY_BACKSPACE,0,0}, /* MOJI_RKAGI 119 */

追加( [MOJI_RKAKKO]〜 の次の行から):

[MOJI_ATMARK] = {KEY_BACKSLASH,0,0}, /* MOJI_ATMARK 120 */
[MOJI_BACKSLASH] = {KEY_Z,KEY_RO,0}, /* MOJI_BACKSLASH 121 */
[MOJI_EQUAL] = {KEY_Z,KEY_LEFTSHIFT,KEY_MINUS}, /* MOJI_EQUAL 122 */
[MOJI_SEMICOLON] = {KEY_SEMICOLON,0,0}, /* MOJI_SEMICOLON 123 */
[MOJI_PLUS] = {KEY_LEFTSHIFT,KEY_SEMICOLON,0}, /* MOJI_PLUS 124 */
[MOJI_COLON] = {KEY_LEFTBRACE,0,0}, /* MOJI_COLON 125 */
[MOJI_ASTERISK] = {KEY_Z,KEY_LEFTSHIFT,KEY_LEFTBRACE}, /* MOJI_ASTERISK 126 */
[MOJI_BAR] = {KEY_Z,KEY_LEFTSHIFT,KEY_YEN}, /* MOJI_BAR 127 */
[MOJI_CIRCUMFLEX] = {KEY_EQUAL,0,0} /* MOJI_CIRCUMFLEX 128 */

これに合わせて、 common.h も以下のように変更します。

変更前:

#define MOJI_RKAKKO 119
#define MOJI_MAX 119 // last index

変更後:

#define MOJI_RKAKKO 119
#define MOJI_ATMARK 120
#define MOJI_BACKSLASH 121
#define MOJI_EQUAL 122
#define MOJI_SEMICOLON 123
#define MOJI_PLUS 124
#define MOJI_COLON 125
#define MOJI_ASTERISK 126
#define MOJI_BAR 127
#define MOJI_CIRCUMFLEX 128
#define MOJI_MAX 128 // last index

さらに、 config.c も以下のように変更します。

変更前:

        {"RKAKKO",119},
};

変更後:

        {"RKAKKO",119},
        {"ATMARK",120},
        {"BACKSLASH",121},
        {"EQUAL",122},
        {"SEMICOLON",123},
        {"PLUS",124},
        {"COLON",125},
        {"ASTERISK",126},
        {"BAR",127},
        {"CIRCUMFLEX",128},
};

変更後、主なMOJI名と実際の文字の対応は以下の通りとなります。

MOJI名 実際の文字
KUTEN
KUTOUTEN
LKAKKO
RKAKKO
LBRACKET
RBRACKET
LKAGI
RKAGI
SLASH
CIRCUMFLEX

ステップ4: 設定ファイルの編集

以上のようにソースコードを編集し、oyainputを再ビルド、インストールします。一旦oyainputを実行して ~/.oyainputconf を生成した後、このファイルの末尾に以下の行を追加します。

KEYADD=Q:KUTEN
KEYADD=EQUAL:CIRCUMFLEX
KEYADD=LEFTBRACE:KUTOUTEN
KEYADD=RIGHTBRACE:DAKUTEN
KEYADD=BACKSLASH:ATMARK
KEYADD=RO:BACKSLASH
LKEYADD=EQUAL:EQUAL
LKEYADD=BACKSLASH:SEMICOLON
LKEYADD=LEFTBRACE:COLON
RKEYADD=EQUAL:EQUAL
RKEYADD=BACKSLASH:PLUS
RKEYADD=LEFTBRACE:ASTERISK
RKEYADD=RIGHTBRACE:HANDAKUTEN
RKEYADD=RO:BAR

そして、oyainputとxmodmapを再起動すれば完了です。

Category(s)
BSD and Linux

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: