私は同じ問題を抱えていましたが、解決策を見つけました。明白な最初から始めましょう。
「W」や「4」などの特定のキーを取得したい場合は、その場所のどこにあっても、イベントから受け取ったキーコードをKeySymに変換することができます。この場合、「W」はXK_W
およびXK_w
であり、「4」はXK_4
(ほとんどのキーボードではXK_dollar
)です。
しかし、時には「th行のキー」などのキーを取得したい場合があります。それを行うにはキー名が必要です。この場合、「W」はAD02
で、QWERTYキーボードでは「4」はAE04
です。
プレイヤーがWASDキーを使用して移動する必要があるゲームを作っているとします。 KeySymsを探すと、QWERTYキーボードで正常に動作しますが、AZERTY、QWERTZ、DVORAKなどの他のキーボードレイアウトを使用している人には問題があります。したがって、この場合はキー名を使用する方がよいでしょう。
実際にキー名を使用するのはかなり簡単ですが、documentationは非常に面倒です(ただし、まだ見てみることをお勧めします)。私は無知だったのでGLFWのソースコード(具体的にはsrc/x11_init.c)を見なければならなかった。この方法にはXkbが必要ですが、既にそれを使用していたので問題はないと思います。
まず、キーボードマップを取得して記号名を取得する必要があります。キー名だけが必要なので、XkbKeyNamesMask
を使用します。
XEvent Event;
XNextEvent(XDisplay, &Event);
switch (Event.type)
{
case KeyPress:
/* I'm not sure this 'if' is necessary, but better safe than sorry */
if ((Event.xkey.keycode >= KbDesc->min_key_code) && (Event.xkey.keycode <= KbDesc->max_key_code))
{
/* Copy key name into Name */
char Name[XkbKeyNameLength + 1];
memcmp(Name, KbDesc->names->keys[Event.xkey.keycode].name, XkbKeyNameLength);
Name[XkbKeyNameLength] = '\0'; /* Null terminator */
if (strcmp(Name, "AD02") == 0) /* Is it W (for QWERTY and QWERTZ)/Z (for AZERTY)/comma (for DVORAK)/ц (for Russian) etc... ? */
{
/* Do something... */
}
else if (strcmp(Name, "AE04") == 0) /* Is it 4 (for most keyboards)/whatever's in its place? */
{
/* Do something... */
}
/* ... */
}
/* ... */
}
をそして、それはこれだけです:
#include <X11/XKBlib.h>
XkbDescPtr KbDesc = XkbGetMap(XDisplay, 0, XkbUseCoreKbd);
XkbGetNames(XDisplay, XkbKeyNamesMask, KbDesc);
その後、イベントループで、あなたは、特定のキーコードのキー名を取得するKbDesc-> names->キー配列を使用することができます。それはこれまでかなりうまくいくようです。私は特別なキーは非常に異なるキー名を持っていることを言及したいと思います。たとえば、左シフトはLFSH
、左コントロールはLCTL
、スペースはSPCE
、エスケープはESC
です。
私はそれが役に立ちそうです。
キーが固定された物理的な場所を持つという考えは、文字入力の特定の実装に依存します。人々は、キー自体を自由に並べ替えることができる仮想キーボードを使用することができる。または手書きの入力または音声認識またはこれらのいずれの場合でも、キーに関連付けられた物理的な場所はありません。スキャンコードを持つ物理的なキーボードがあっても、互換性のないモデルがたくさんあります。 '/ usr/share/X11/xkb/keycodes'の他のファイルを参照してください。 –
それは理にかなっています。従来のキーボード以外の特別な入力方法を無視するとします。 "/ usr/share/X11/xkb/keycodes"にあるファイルのいずれかがマッピングに使用されている場合、そのファイルがデバイスによって使用されているかどうかを検出する方法はありますか? – ComfyS
キーボードのジオメトリを調べることで、キーの物理的な位置を取得できます。 'setxkbmap -print -verbose 10'を実行すると、ジオメトリのinclude文が表示されます。 X11/xkb /ジオメトリ(おそらく "pc"という名前のファイル)を調べます。使用中のマッピングも表示されます。私は 'setxkbmap -print'に相当するプログラマティックを知りませんが、確かに一つです。ユーザーがxmodmapを使ってキーボードを再マッピングするとどうなるか分かりませんが、私はそれに対処すると言います。 –