前回 に引き続き NiZ のキーマップをごにょごにょする。

とりあえず表題の通り、キーマップの書きかえまではできた。

#!/usr/bin/env ruby


require "./niz.rb"
require 'progress_bar'

override_mapping = lambda do |mapping|
	# mapping[level][key_id] = hwcode
	# level:
	#   0: normal
	#   1: Right Fn
	#   2: Left Fn
	# key_id: 1-66
	# hwcode: See ./niz.rb HWCODE constant

	mapping[0][61] = 68 # Set key_id 61 (right side of space) = 68 (super)
	mapping[0][62] = 71
	mapping[0][63] = 74
end

#################################################################

niz = NiZ.new
Timeout.timeout(1) do
	begin
		niz.open
	rescue => e
		$stderr.puts "#{e.inspect} retrying open device..."
		retry
	end
end

puts "Version: #{niz.version}"
puts "#{niz.keycount} keys"

puts "Reading key mapping..."
progress = ProgressBar.new(niz.keycount * 3)
read_all = niz.read_all do |count, keymap|
	progress.increment!
end

mapping = NiZ.mapping_from_array(read_all)

override_mapping[mapping]

puts "Writing key mapping..."
progress = ProgressBar.new(niz.keycount * 3)
niz.write_all(mapping) do |count|
	progress.increment!
end

ポイント

キーマップの書きかえコマンドを送ると、まず既存のキーマップが全てリセットされるみたい。つまり、プロトコル的には一部のキーだけを書きかえということはできない。常に全部のキーマップを送信する必要がある。

なので、一部の書きかえを実現したいのであれば、

  1. 全キーマップの読み出し
  2. キーマップの更新
  3. 全キーマップの書き出し

という手順になる。

HWCODE の定義

NiZ は内部的にキーに対応する数値を HWCODE という名前で持っている。このコードは USB HID の scan code や、multi media キーや、その他いろいろな機能キーを一意に特定するものになっている。HWCODE は ASCII や Usage とまったく別の規則で割り当てられているようで、マッピングは気合で作るしかない。

気合で作るしかないので、おおむね作った。https://github.com/cho45/niz-tools-ruby/blob/master/niz.rb#L13 ということで、ここを読んでいる良い子のみんなは気合を入れる必要がなくなった。

マクロは?

自分で使わないのでまったく調べてない。マクロ登録用のコマンドがあるっぽい。

  1. トップ
  2. tech
  3. NiZ Keyboard PLUM のキーマップを macOS や Linux から書き換える

CorvusSKK にしてみた。Ctrl-SPC で IME のオン・オフをしたいので、設定する。

「キー0」タブが IME の ON/OFF 用のキーを設定する画面になっている。スペースキーは 0x20 なので、0x20 と入力して修飾キーとして CTRL を選択し、ON と OFF それぞれについてキーを追加する。

順番にどういう意味があるかわかってないけど、一応一番上にしておいた。こういう感じに。

  1. トップ
  2. tech
  3. Windows での SKK

https://play.google.com/store/apps/details?id=jp.kcm.thumbctrl.en.layout これを入れて、レイアウトから Caps Lock -> Ctrl 置き換えする。いろいろレイアウトが追加されるけど、とりあえずこれで良い。

http://ray-mizuki.la.coocan.jp/software/skk_jp.html SKK for Android を apk から入れて、設定する

  • 辞書ファイル解凍
  • ハードキーボードの設定
    • かなキーを Ctrl+Space に (Ctrl+Unknown と表示されるけど、設定できている模様) 内部的には Ctrl 単体で割り当てらているみたい。Ctrl-Space は Android が OS 側で予約しており、割り当てることができない……
    • かなキーをトグルに
  • 句読点のタイプを「。、」に

これでほぼ違和感なく入力できる。ただ、SKK for Android には RET したとき改行しない設定がないので、ちょっと気をつけて入力する必要がある。

  1. トップ
  2. tech
  3. Android で外部キーボード使用時の日本語入力を快適にする (SKK)

JRE込みのPyCharmで日本語入力がおかしい · Issue #24 · codefirst/aquaskk · GitHub この問題と同じだと思う。

どうも JDK のバージョンによって変な挙動になるらしい。ので、Android Studio の bundled JDK を使うのをやめる。

Selecting the JDK version the IDE will run under – IDEs Support (IntelliJ Platform) | JetBrains この手順に従う

Choose Runtime プラグインをいれる

再起動後に

Shift 連打とかで Choose Runtime... のダイアログを出す。

適当に 1.8.0 の JDK を選んで Install ボタンを押すと勝手に再起動する。

これでおわり。

JDK11 を指定したら起動しなくなった……

なんとなく AdoptOpenJDK 11 を入れて指定したら、起動しなくなってしまった。起動しないので Choose Runtime も使えない。

macOS の場合 ~/Library/Preferences/AndroidStudio3.5 以下に設定ファイルがある。~/Library/Preferences/AndroidStudio3.5/studio.jdk というファイルがあるので、これを消せばデフォルトの JDK に戻すことができる。

  1. トップ
  2. tech
  3. Android Studio (IntelliJ IDEA) + AquaSKK で aiueo がそのまま入力されてしまうのを直す

Capacitor をつかって NanoVNA-Web-Client を Android アプリ化してみた。

あんまりハマりどころはなかったのでそれほど書くことはないけど、いくつかメモ。

node_modules

アプリサイズを減らすためにできるだけリソースを減らす必要がある。node_modules 以下を雑に入れると数十MBになってしまうので、気をつける。

Web 版のリソースを完全にそのまま入れるより、必要なリソースだけをコピーするようなビルドスクリプトを書いたほうが良さそう。今回は Makefile でなんとかした。

splash 画像の生成自動化

Ionic のブログに Photoshop template があるので、これを利用させてもらう。

が、ブログの通り cordova-res を使うとうまくいかなかったので、Makefile と ImageMagick でなんとかした。

res:
	convert images/splash.png -gravity center -resize 480x320^ -extent 480x320 ./android/app/src/main/res/drawable/splash.png
	convert images/splash.png -gravity center -resize 800x480^ -extent 800x480 ./android/app/src/main/res/drawable-land-hdpi/splash.png
	convert images/splash.png -gravity center -resize 480x320^ -extent 480x320 ./android/app/src/main/res/drawable-land-mdpi/splash.png
	convert images/splash.png -gravity center -resize 1280x720^ -extent 1280x720 ./android/app/src/main/res/drawable-land-xhdpi/splash.png
	convert images/splash.png -gravity center -resize 1600x960^ -extent 1600x960 ./android/app/src/main/res/drawable-land-xxhdpi/splash.png
	convert images/splash.png -gravity center -resize 1920x1280^ -extent 1920x1280 ./android/app/src/main/res/drawable-land-xxxhdpi/splash.png
	convert images/splash.png -gravity center -resize 480x800^ -extent 480x800 ./android/app/src/main/res/drawable-port-hdpi/splash.png
	convert images/splash.png -gravity center -resize 320x480^ -extent 320x480 ./android/app/src/main/res/drawable-port-mdpi/splash.png
	convert images/splash.png -gravity center -resize 720x1280^ -extent 720x1280 ./android/app/src/main/res/drawable-port-xhdpi/splash.png
	convert images/splash.png -gravity center -resize 960x1600^ -extent 960x1600 ./android/app/src/main/res/drawable-port-xxhdpi/splash.png
	convert images/splash.png -gravity center -resize 1280x1920^ -extent 1280x1920 ./android/app/src/main/res/drawable-port-xxxhdpi/splash.png
	optipng $(wildcard ./android/app/src/main/res/*/splash.png)

Play Store のメモ

リリースしたことある気がしていたが、よく考えたら前職で数回やっただけなので個人のアカウントではやったことがなかった。いろいろストアの使い勝手が変わっていた。

  • 初回の審査は結構時間がかかる。一週間ぐらい? 更新の審査は割とすぐ。
  • 要求される画像がいっぱいあってだるい。全部埋めないとベータ版すらリリースできない
  • adb という仕組みができていた。(端末にあわせて必要なリソースだけを含む apk を自動生成する)

無料アプリの開発者視点からすると、別に Play Store に出すメリットはぜんぜんない。他の端末にさくっと入れたいときに便利かな、と思う。けど、それも普通にウェブサイト経由で .apk ダウンロードして入れればいいだけなので、それほど致命的に面倒くさいわけではない。まぁ Play Store のショバ代は初回に $25 なので Apple (毎年$99もとる) よりは格段に優しいといえる。

  1. トップ
  2. tech
  3. NanoVNA WebApp の Android アプリ化
  1. トップ
  2. nanovna
  3. NanoVNA WebApp の Android アプリ化

NiZ のアプリケーションは Windows 向けしかない。プロトコルが気になったので、とりあえず打鍵回数を読み出すところをまでをやってみた。環境は macOS で hid_api gem を使い、Ruby で書いた。

できたもの

実行するとこういう出力をする。最後の数字がキーに対応するカウント。

key=  1 hwcode=   1             ESC: 35
key=  2 hwcode=  15               1: 66
key=  3 hwcode=  16               2: 92
key=  4 hwcode=  17               3: 114
key=  5 hwcode=  18               4: 119
key=  6 hwcode=  19               5: 53
key=  7 hwcode=  20               6: 99
key=  8 hwcode=  21               7: 18
key=  9 hwcode=  22               8: 115
key= 10 hwcode=  23               9: 76
key= 11 hwcode=  24               0: 171
key= 12 hwcode=  25               -: 307
key= 13 hwcode=  26               =: 78
key= 14 hwcode=  41               \: 38
key= 15 hwcode=  14               `: 33
key= 16 hwcode=  28             TAB: 575
key= 17 hwcode=  29               Q: 253
key= 18 hwcode=  30               W: 627
key= 19 hwcode=  31               E: 1461
key= 20 hwcode=  32               R: 911
key= 21 hwcode=  33               T: 1137
key= 22 hwcode=  34               Y: 616
key= 23 hwcode=  35               U: 1317
key= 24 hwcode=  36               I: 1662
key= 25 hwcode=  37               O: 1536
key= 26 hwcode=  38               P: 549
key= 27 hwcode=  39               [: 584
key= 28 hwcode=  40               ]: 41
key= 29 hwcode=  27              BS: 1662
key= 30 hwcode=  67          L-CTRL: 18
key= 31 hwcode=  43               A: 1794
key= 32 hwcode=  44               S: 914
key= 33 hwcode=  45               D: 853
key= 34 hwcode=  46               F: 249
key= 35 hwcode=  47               G: 520
key= 36 hwcode=  48               H: 828
key= 37 hwcode=  49               J: 671
key= 38 hwcode=  50               K: 1424
key= 39 hwcode=  51               L: 696
key= 40 hwcode=  52               ;: 452
key= 41 hwcode=  53               ': 155
key= 42 hwcode=  54             RET: 1281
key= 43 hwcode=  55         L-Shift: 1610
key= 44 hwcode=  56               Z: 177
key= 45 hwcode=  57               X: 128
key= 46 hwcode=  58               C: 459
key= 47 hwcode=  59               V: 253
key= 48 hwcode=  60               B: 384
key= 49 hwcode=  61               N: 1352
key= 50 hwcode=  62               M: 482
key= 51 hwcode=  63               ,: 383
key= 52 hwcode=  64               .: 255
key= 53 hwcode=  65               /: 161
key= 54 hwcode=  66         R-Shift: 850
key= 55 hwcode= 156            R-Fn: 135
key= 56 hwcode=  67          L-CTRL: 1653
key= 57 hwcode= 166            L-Fn: 6
key= 58 hwcode=  69           L-Alt: 35
key= 59 hwcode=  68           Super: 703
key= 60 hwcode=  70           Space: 2037
key= 61 hwcode=  68           Super: 7
key= 62 hwcode=  71           R-Alt: 5
key= 63 hwcode=  74          R-Ctrl: 5
key= 64 hwcode=  88      Left Arrow: 24
key= 65 hwcode=  89      Down Arrow: 19
key= 66 hwcode=  90     Right Arrow: 34
key= 67 hwcode=   0                : 0
key= 68 hwcode=   0                : 0
key= 69 hwcode=   0                : 0
key= 70 hwcode=   0                : 0
key= 71 hwcode=   0                : 0
key= 72 hwcode=   0                : 0
key= 73 hwcode=   0                : 0
key= 74 hwcode=   0                : 0
key= 75 hwcode=   0                : 0

プロトコルの概要

すべて HID 上で行われる。64bytes 固定で read/write する。

日本語で説明するよりソースコード読んだほうが早いので説明するのをやめる。

カウントを得るためにすること

キーマップを得る

NiZ キーボード側から、現在のキーマップを取得する。66キーのモデルなので、66キー × 3レイヤー (ノーマル・左Fn・右Fn) で 198 個の論理キー定義がある。

これによって、キーID (1〜66) と、割当られているキーコード (.pro ファイルの HWCODE) のマッピングを得られる。

カウント一覧を得る

カウントは66個の数値の配列のようなものが得られる。インデックスがそれぞれキーIDに対応していると思われる。

インデックスからキーマップを得てカウントと共に表示すればおわり。

備考

macOS だからか、実装が悪いのか、どこが悪いのかわからないが、挙動が不安定

  • HidApi.open がしばしば失敗する
  • read に失敗する (タイムアウト)

何回か繰替えすと成功する。

hid_api

hid_api は timeout のメソッドがあるにも関わらず timeout の処理が抜けているので、モンキーパッチを書いてる。PR 作ろうかと思ったけど結構放置されてそうでめんどい。

macOS でもキーマップを書きかえたいんだけど???

read した形式で書き戻せばいいだけだと思う。

どうやって解析したか?

Windows に USBPcap を入れて、公式のアプリケーションを操作しながらログをとった。

あとは気合

ソースコード

https://github.com/cho45/niz-tools-ruby github にうつしました

>

  1. トップ
  2. tech
  3. NiZ Keyboard PLUM からキーマップや打鍵回数を読み出す