XKB 詳細データ
XKB では、キーボードに関する色々な設定を細かく変更できるので、クライアントがそれらをまとめて取得したり、変更できるように、すべての関連データを一つの構造体に格納することができます。
それが XkbDescRec 構造体です (そのポインタ型は XkbDescPtr)。
Xkb*Ptr の各データは、必要なデータのみ確保してセットすることができます。
device_spec で指定したデバイスの詳細データを、確保して返します。
which は、Xkb*Ptr の各データのうち、取得するもののマスクです。
XkbDescRec 構造体のデータを解放します。
which は、上記と同じです。解放するデータのマスクを指定します。
各データを解放した上で、ポインタを NULL に設定します。
free_all が True の場合は、xkb 自身も含めて、すべてのデータを解放します。which は無視されます。
それが XkbDescRec 構造体です (そのポインタ型は XkbDescPtr)。
XkbDescRec 構造体
typedef struct { struct _XDisplay * display; unsigned short flags; unsigned short device_spec; KeyCode min_key_code; KeyCode max_key_code; XkbControlsPtr ctrls; XkbServerMapPtr server; XkbClientMapPtr map; XkbIndicatorPtr indicators; XkbNamesPtr names; XkbCompatMapPtr compat; XkbGeometryPtr geom; } XkbDescRec, *XkbDescPtr;
flags | プライベート値。変更しないこと |
---|---|
device_spec | キーボードのデバイスID または XkbUseCoreKbd |
min_key_code max_key_code | 指定デバイスの、最小キーコードと最大キーコード |
ctrls | 機能のコントロール関連 |
server | サーバー用のマップ |
map | クライアント用のマップ |
indicators | インディケータ (LED) 関連 |
names | 各名前の情報 |
compat | 互換性マップ |
geom | キーボードのジオメトリ関連 (物理的なキー配置) |
Xkb*Ptr の各データは、必要なデータのみ確保してセットすることができます。
指定デバイスの詳細データを取得
XkbDescPtr XkbGetKeyboard(Display *display, unsigned int which, unsigned int device_spec); //which #define XkbClientMapMask (1L << 0) #define XkbServerMapMask (1L << 1) #define XkbCompatMapMask (1L << 2) #define XkbIndicatorMapMask (1L << 3) #define XkbNamesMask (1L << 4) #define XkbGeometryMask (1L << 5) #define XkbControlsMask (1L << 6) #define XkbAllComponentsMask (0x7f)
device_spec で指定したデバイスの詳細データを、確保して返します。
which は、Xkb*Ptr の各データのうち、取得するもののマスクです。
解放
void XkbFreeKeyboard(XkbDescPtr xkb, unsigned int which, Bool free_all);
XkbDescRec 構造体のデータを解放します。
which は、上記と同じです。解放するデータのマスクを指定します。
各データを解放した上で、ポインタを NULL に設定します。
free_all が True の場合は、xkb 自身も含めて、すべてのデータを解放します。which は無視されます。
名前
XkbDescRec 構造体の XkbNamesPtr names には、XKB に関する各名前のデータが格納されています。
Atom もしくは、4文字のキー名が含まれています。
Atom もしくは、4文字のキー名が含まれています。
#define XkbKeyNameLength 4 #define XkbKeyNumVirtualMods 16 #define XkbKeyNumIndicators 32 #define XkbKeyNumKbdGroups 4 #define XkbMaxRadioGroups 32 typedef struct { char name[XkbKeyNameLength]; } XkbKeyNameRec, *XkbKeyNamePtr; typedef struct { char real[XkbKeyNameLength]; char alias[XkbKeyNameLength]; } XkbKeyAliasRec, *XkbKeyAliasPtr; typedef struct _XkbNamesRec { Atom keycodes; Atom geometry; Atom symbols; Atom types; Atom compat; Atom vmods[XkbNumVirtualMods]; Atom indicators[XkbNumIndicators]; Atom groups[XkbNumKbdGroups]; XkbKeyNamePtr keys; XkbKeyAliasPtr key_aliases; Atom * radio_groups; Atom phys_symbols; unsigned char num_keys; unsigned char num_key_aliases; unsigned short num_rg; } XkbNamesRec, *XkbNamesPtr;
vmods | 各仮想修飾子の名前 |
---|---|
indicators | 各インディケータ (LED) の名前 |
groups | 各グループの名前 |
keys | num_keys 個の配列。 キーコードをインデックスとした、各キーの名前 (4byte)。 |
key_aliases | num_key_aliases 個の配列。 実際のキー名と、エイリアス (別名) のキー名のペア。 real は keys 内にある名前で、alias はその別名の名前です。 |
radio_groups | num_rg 個の配列。 キーをラジオグループとして扱う場合の、各グループの名前 |
プログラム
XKB の名前の情報を表示します。
※XkbGetKeyboard 関数で、which に XkbNamesMask だけを指定すると、NULL が返ります。名前の情報を取得するには、他のデータも必要となるので、ここではすべてのデータを取得しています。
<e12-xkb2.c>
※XkbGetKeyboard 関数で、which に XkbNamesMask だけを指定すると、NULL が返ります。名前の情報を取得するには、他のデータも必要となるので、ここではすべてのデータを取得しています。
$ cc -o run e12-xkb2.c util.c -lXlib
<e12-xkb2.c>
#include <stdio.h> #include <X11/Xlib.h> #include <X11/XKBlib.h> #include "util.h" static void _put_names(XkbNamesPtr p) { int i; put_atom_name_line("keycodes: ", p->keycodes); put_atom_name_line("geometry: ", p->geometry); put_atom_name_line("symbols: ", p->symbols); put_atom_name_line("types: ", p->types); put_atom_name_line("compat: ", p->compat); put_atom_name_line("phys_symbols: ", p->phys_symbols); //vmods printf("--- vmods ---\n"); for(i = 0; i < XkbNumVirtualMods; i++) { if(p->vmods[i]) { printf("[%d] ", i); put_atom_name_line(NULL, p->vmods[i]); } } //indicators printf("--- indicators ---\n"); for(i = 0; i < XkbNumIndicators; i++) { if(p->indicators[i]) { printf("[%d] ", i); put_atom_name_line(NULL, p->indicators[i]); } } //groups printf("--- groups ---\n"); for(i = 0; i < XkbNumKbdGroups; i++) { if(p->groups[i]) { printf("[%d] ", i); put_atom_name_line(NULL, p->groups[i]); } } //keys printf("--- keys ---\n"); for(i = 0; i < p->num_keys; i++) printf("[%d] %.4s\n", i, p->keys[i].name); //key_aliases printf("--- key_aliases ---\n"); for(i = 0; i < p->num_key_aliases; i++) { printf("[%d] real(%.4s) alias(%.4s)\n", i, p->key_aliases[i].real, p->key_aliases[i].alias); } //radio_groups printf("--- radio_groups ---\n"); for(i = 0; i < p->num_rg; i++) { printf("[%d] ", i); put_atom_name_line(NULL, p->radio_groups[i]); } } int main(int argc,char **argv) { Display *disp; XkbDescPtr desc; disp = XOpenDisplay(NULL); if(!disp) return 1; set_display(disp); //XKB 初期化 if(init_xkb(disp, NULL)) return 1; //データ取得 desc = XkbGetKeyboard(disp, XkbAllComponentsMask, XkbUseCoreKbd); _put_names(desc->names); XkbFreeKeyboard(desc, 0, True); XCloseDisplay(disp); return 0; }
実行例
keycodes: "evdev_aliases(qwerty)" geometry: <None> symbols: "pc_jp_inet(evdev)" types: "complete" compat: "complete_japan" phys_symbols: "pc_jp_inet(evdev)" --- vmods --- [0] "NumLock" [1] "Alt" [2] "LevelThree" [3] "LevelFive" [4] "Meta" [5] "Super" [6] "Hyper" [7] "ScrollLock" --- indicators --- [0] "Caps Lock" [1] "Num Lock" [2] "Scroll Lock" [3] "Compose" [4] "Kana" [5] "Sleep" [6] "Suspend" [7] "Mute" [8] "Misc" [9] "Mail" [10] "Charging" [11] "Shift Lock" [12] "Group 2" [13] "Mouse Keys" --- groups --- [0] "Japanese" --- keys --- [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] ESC [10] AE01 [11] AE02 [12] AE03 ... --- key_aliases --- [0] real(BKSL) alias(AC12) [1] real(RALT) alias(ALGR) [2] real(COMP) alias(MENU) [3] real(TLDE) alias(HZTG) [4] real(LWIN) alias(LMTA) ...