sxhkd-rc

[fork] simple X hotkey daemon (but for the rc shell)
Log | Files | Refs | README | LICENSE

commit e019134a31ad5f7acfa7774bb0167e770c0c1a14
Author: Bastien Dejean <nihilhill@gmail.com>
Date:   Thu,  3 Jan 2013 18:26:10 +0100

First commit

Diffstat:
A.gitignore | 3+++
ALICENSE | 26++++++++++++++++++++++++++
AMakefile | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
AREADME.md | 46++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/sxhkdrc | 22++++++++++++++++++++++
Ahelpers.c | 42++++++++++++++++++++++++++++++++++++++++++
Ahelpers.h | 21+++++++++++++++++++++
Akeys.c | 2557+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Akeys.h | 22++++++++++++++++++++++
Asxhkd.c | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asxhkd.h | 45+++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 3077 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +*.o +sxhkd +tags diff --git a/LICENSE b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2013, Bastien Dejean +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. diff --git a/Makefile b/Makefile @@ -0,0 +1,53 @@ +VERSION = 0.1 + +CC = gcc +LIBS = -lm -lxcb -lxcb-keysyms +CFLAGS = -std=c99 -pedantic -Wall -Wextra -DVERSION=\"$(VERSION)\" +LDFLAGS = $(LIBS) + +PREFIX ?= /usr/local +BINPREFIX = $(PREFIX)/bin +MANPREFIX = $(PREFIX)/share/man + +SRC = sxhkd.c keys.c helpers.c +OBJ = $(SRC:.c=.o) + +all: CFLAGS += -Os +all: LDFLAGS += -s +all: options sxhkd + +debug: CFLAGS += -O0 -g -DDEBUG +debug: options sxhkd + +options: + @echo "sxhkd build options:" + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "PREFIX = $(PREFIX)" + +.c.o: + @echo "CC $<" + @$(CC) $(CFLAGS) -DVERSION=\"$(VERSION)\" -c -o $@ $< + +sxhkd: $(OBJ) + @echo CC -o $@ + @$(CC) -o $@ $(OBJ) $(LDFLAGS) + +clean: + @echo "cleaning" + @rm -f $(OBJ) sxhkd + +install: + @echo "installing executable files to $(DESTDIR)$(BINPREFIX)" + @install -D -m 755 sxhkd $(DESTDIR)$(BINPREFIX)/xshkd + @echo "installing manual page to $(DESTDIR)$(MANPREFIX)/man1" + @install -D -m 644 sxhkd.1 $(DESTDIR)$(MANPREFIX)/man1/xshkd.1 + +uninstall: + @echo "removing executable files from $(DESTDIR)$(BINPREFIX)" + @rm -f $(DESTDIR)$(BINPREFIX)/sxhkd + @echo "removing manual page from $(DESTDIR)$(MANPREFIX)/man1" + @rm -f $(DESTDIR)$(MANPREFIX)/man1/sxhkd.1 + +.PHONY: all debug options clean install uninstall diff --git a/README.md b/README.md @@ -0,0 +1,46 @@ +## Description + +sxhkd is a simple X hotkey daemon. + +## Usage + +### Synopsis + + sxhkd [OPTIONS] + +### Options + +* `-h`: Print the synopsis to standard output and exit. +* `-v`: Print the version information to standard output and exit. +* `-c CONFIG_FILE`: Use the given configuration file instead of the default (`$XDG_CONFIG_HOME/sxhkd/sxhkdrc`). + +## Configuration + +Each line of the configuration file is interpreted as so: +- If it starts with `#`, it is ignored. +- If it starts with a white space character, it is read as a command. +- Otherwise, it is parsed as a hotkey: each key name is separated by spaces and/or `+` characters. + +General syntax: + [MODIFIER + ]*[@]KEYSYM + COMMAND + +Where `MODIFIER` is `super|hyper|meta|alt|control|ctrl|shift|mode_switch|lock|mod1|mod2|mod3|mod4|mod5`. + +If `@` is added at the beginning of the keysym, the command will be run on key release events, otherwise on key press events. + +The keysym names are those your will get from `xev` (minus the prefix if any). + +What is actually executed is `/bin/sh -c COMMAND`, which means you can use environment variables in `COMMAND`. + +If *sxhkd* receives a `SIGUSR1` signal, it will reload its configuration file. + +## Installation + + make + make install + +## Dependencies + +- libxcb +- xcb-util-keysyms diff --git a/examples/sxhkdrc b/examples/sxhkdrc @@ -0,0 +1,22 @@ +MonBrightnessDown + backlight -1 + +MonBrightnessUp + backlight +1 + +AudioPrev + mpc -q prev + +AudioNext + mpc -q next + +super + LaunchA + scrot + +super + shift + @LaunchA + scrot -s + +super + shift + equal + mosaic "$HOME/image" + +# vim: set ft=conf: diff --git a/helpers.c b/helpers.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/wait.h> +#include "helpers.h" +#include "sxhkd.h" + +void warn(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +__attribute__((noreturn)) +void err(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +void spawn(char *cmd[]) +{ + if (fork() == 0) { + if (dpy != NULL) + close(xcb_get_file_descriptor(dpy)); + if (fork() == 0) { + setsid(); + execvp(cmd[0], cmd); + err("Spawning failed.\n"); + } + exit(EXIT_SUCCESS); + } + wait(NULL); +} diff --git a/helpers.h b/helpers.h @@ -0,0 +1,21 @@ +#ifndef _HELPERS_H +#define _HELPERS_H + +#define LENGTH(x) (sizeof(x) / sizeof(*x)) +#define SHELL "/bin/sh" +#define MAXLEN 256 + +#ifdef DEBUG +# define PUTS(x) puts(x) +# define PRINTF(x,...) printf(x, __VA_ARGS__) +#else +# define PUTS(x) ((void)0) +# define PRINTF(x,...) ((void)0) +#endif + +void warn(char *, ...); +__attribute__((noreturn)) +void err(char *, ...); +void spawn(char *[]); + +#endif diff --git a/keys.c b/keys.c @@ -0,0 +1,2557 @@ +#include <X11/keysym.h> +#include <X11/XF86keysym.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include "keys.h" +#include "helpers.h" +#include "sxhkd.h" + +keysym_dict_t nks_dict[] = { +#define NKS(x) { #x, XK_ ## x } + NKS(VoidSymbol), +#ifdef XK_MISCELLANY + NKS(BackSpace), + NKS(Tab), + NKS(Linefeed), + NKS(Clear), + NKS(Return), + NKS(Pause), + NKS(Scroll_Lock), + NKS(Sys_Req), + NKS(Escape), + NKS(Delete), + NKS(Multi_key), + NKS(Codeinput), + NKS(SingleCandidate), + NKS(MultipleCandidate), + NKS(PreviousCandidate), + NKS(Kanji), + NKS(Muhenkan), + NKS(Henkan_Mode), + NKS(Henkan), + NKS(Romaji), + NKS(Hiragana), + NKS(Katakana), + NKS(Hiragana_Katakana), + NKS(Zenkaku), + NKS(Hankaku), + NKS(Zenkaku_Hankaku), + NKS(Touroku), + NKS(Massyo), + NKS(Kana_Lock), + NKS(Kana_Shift), + NKS(Eisu_Shift), + NKS(Eisu_toggle), + NKS(Kanji_Bangou), + NKS(Zen_Koho), + NKS(Mae_Koho), + NKS(Home), + NKS(Left), + NKS(Up), + NKS(Right), + NKS(Down), + NKS(Prior), + NKS(Page_Up), + NKS(Next), + NKS(Page_Down), + NKS(End), + NKS(Begin), + NKS(Select), + NKS(Print), + NKS(Execute), + NKS(Insert), + NKS(Undo), + NKS(Redo), + NKS(Menu), + NKS(Find), + NKS(Cancel), + NKS(Help), + NKS(Break), + NKS(Mode_switch), + NKS(script_switch), + NKS(Num_Lock), + NKS(KP_Space), + NKS(KP_Tab), + NKS(KP_Enter), + NKS(KP_F1), + NKS(KP_F2), + NKS(KP_F3), + NKS(KP_F4), + NKS(KP_Home), + NKS(KP_Left), + NKS(KP_Up), + NKS(KP_Right), + NKS(KP_Down), + NKS(KP_Prior), + NKS(KP_Page_Up), + NKS(KP_Next), + NKS(KP_Page_Down), + NKS(KP_End), + NKS(KP_Begin), + NKS(KP_Insert), + NKS(KP_Delete), + NKS(KP_Equal), + NKS(KP_Multiply), + NKS(KP_Add), + NKS(KP_Separator), + NKS(KP_Subtract), + NKS(KP_Decimal), + NKS(KP_Divide), + NKS(KP_0), + NKS(KP_1), + NKS(KP_2), + NKS(KP_3), + NKS(KP_4), + NKS(KP_5), + NKS(KP_6), + NKS(KP_7), + NKS(KP_8), + NKS(KP_9), + NKS(F1), + NKS(F2), + NKS(F3), + NKS(F4), + NKS(F5), + NKS(F6), + NKS(F7), + NKS(F8), + NKS(F9), + NKS(F10), + NKS(F11), + NKS(L1), + NKS(F12), + NKS(L2), + NKS(F13), + NKS(L3), + NKS(F14), + NKS(L4), + NKS(F15), + NKS(L5), + NKS(F16), + NKS(L6), + NKS(F17), + NKS(L7), + NKS(F18), + NKS(L8), + NKS(F19), + NKS(L9), + NKS(F20), + NKS(L10), + NKS(F21), + NKS(R1), + NKS(F22), + NKS(R2), + NKS(F23), + NKS(R3), + NKS(F24), + NKS(R4), + NKS(F25), + NKS(R5), + NKS(F26), + NKS(R6), + NKS(F27), + NKS(R7), + NKS(F28), + NKS(R8), + NKS(F29), + NKS(R9), + NKS(F30), + NKS(R10), + NKS(F31), + NKS(R11), + NKS(F32), + NKS(R12), + NKS(F33), + NKS(R13), + NKS(F34), + NKS(R14), + NKS(F35), + NKS(R15), + NKS(Shift_L), + NKS(Shift_R), + NKS(Control_L), + NKS(Control_R), + NKS(Caps_Lock), + NKS(Shift_Lock), + NKS(Meta_L), + NKS(Meta_R), + NKS(Alt_L), + NKS(Alt_R), + NKS(Super_L), + NKS(Super_R), + NKS(Hyper_L), + NKS(Hyper_R), +#endif /* XK_MISCELLANY */ +#ifdef XK_XKB_KEYS + NKS(ISO_Lock), + NKS(ISO_Level2_Latch), + NKS(ISO_Level3_Shift), + NKS(ISO_Level3_Latch), + NKS(ISO_Level3_Lock), + NKS(ISO_Level5_Shift), + NKS(ISO_Level5_Latch), + NKS(ISO_Level5_Lock), + NKS(ISO_Group_Shift), + NKS(ISO_Group_Latch), + NKS(ISO_Group_Lock), + NKS(ISO_Next_Group), + NKS(ISO_Next_Group_Lock), + NKS(ISO_Prev_Group), + NKS(ISO_Prev_Group_Lock), + NKS(ISO_First_Group), + NKS(ISO_First_Group_Lock), + NKS(ISO_Last_Group), + NKS(ISO_Last_Group_Lock), + NKS(ISO_Left_Tab), + NKS(ISO_Move_Line_Up), + NKS(ISO_Move_Line_Down), + NKS(ISO_Partial_Line_Up), + NKS(ISO_Partial_Line_Down), + NKS(ISO_Partial_Space_Left), + NKS(ISO_Partial_Space_Right), + NKS(ISO_Set_Margin_Left), + NKS(ISO_Set_Margin_Right), + NKS(ISO_Release_Margin_Left), + NKS(ISO_Release_Margin_Right), + NKS(ISO_Release_Both_Margins), + NKS(ISO_Fast_Cursor_Left), + NKS(ISO_Fast_Cursor_Right), + NKS(ISO_Fast_Cursor_Up), + NKS(ISO_Fast_Cursor_Down), + NKS(ISO_Continuous_Underline), + NKS(ISO_Discontinuous_Underline), + NKS(ISO_Emphasize), + NKS(ISO_Center_Object), + NKS(ISO_Enter), + NKS(dead_grave), + NKS(dead_acute), + NKS(dead_circumflex), + NKS(dead_tilde), + NKS(dead_perispomeni), + NKS(dead_macron), + NKS(dead_breve), + NKS(dead_abovedot), + NKS(dead_diaeresis), + NKS(dead_abovering), + NKS(dead_doubleacute), + NKS(dead_caron), + NKS(dead_cedilla), + NKS(dead_ogonek), + NKS(dead_iota), + NKS(dead_voiced_sound), + NKS(dead_semivoiced_sound), + NKS(dead_belowdot), + NKS(dead_hook), + NKS(dead_horn), + NKS(dead_stroke), + NKS(dead_abovecomma), + NKS(dead_psili), + NKS(dead_abovereversedcomma), + NKS(dead_dasia), + NKS(dead_doublegrave), + NKS(dead_belowring), + NKS(dead_belowmacron), + NKS(dead_belowcircumflex), + NKS(dead_belowtilde), + NKS(dead_belowbreve), + NKS(dead_belowdiaeresis), + NKS(dead_invertedbreve), + NKS(dead_belowcomma), + NKS(dead_currency), + NKS(dead_a), + NKS(dead_A), + NKS(dead_e), + NKS(dead_E), + NKS(dead_i), + NKS(dead_I), + NKS(dead_o), + NKS(dead_O), + NKS(dead_u), + NKS(dead_U), + NKS(dead_small_schwa), + NKS(dead_capital_schwa), + NKS(dead_greek), + NKS(First_Virtual_Screen), + NKS(Prev_Virtual_Screen), + NKS(Next_Virtual_Screen), + NKS(Last_Virtual_Screen), + NKS(Terminate_Server), + NKS(AccessX_Enable), + NKS(AccessX_Feedback_Enable), + NKS(RepeatKeys_Enable), + NKS(SlowKeys_Enable), + NKS(BounceKeys_Enable), + NKS(StickyKeys_Enable), + NKS(MouseKeys_Enable), + NKS(MouseKeys_Accel_Enable), + NKS(Overlay1_Enable), + NKS(Overlay2_Enable), + NKS(AudibleBell_Enable), + NKS(Pointer_Left), + NKS(Pointer_Right), + NKS(Pointer_Up), + NKS(Pointer_Down), + NKS(Pointer_UpLeft), + NKS(Pointer_UpRight), + NKS(Pointer_DownLeft), + NKS(Pointer_DownRight), + NKS(Pointer_Button_Dflt), + NKS(Pointer_Button1), + NKS(Pointer_Button2), + NKS(Pointer_Button3), + NKS(Pointer_Button4), + NKS(Pointer_Button5), + NKS(Pointer_DblClick_Dflt), + NKS(Pointer_DblClick1), + NKS(Pointer_DblClick2), + NKS(Pointer_DblClick3), + NKS(Pointer_DblClick4), + NKS(Pointer_DblClick5), + NKS(Pointer_Drag_Dflt), + NKS(Pointer_Drag1), + NKS(Pointer_Drag2), + NKS(Pointer_Drag3), + NKS(Pointer_Drag4), + NKS(Pointer_Drag5), + NKS(Pointer_EnableKeys), + NKS(Pointer_Accelerate), + NKS(Pointer_DfltBtnNext), + NKS(Pointer_DfltBtnPrev), + NKS(ch), + NKS(Ch), + NKS(CH), + NKS(c_h), + NKS(C_h), + NKS(C_H), +#endif /* XK_XKB_KEYS */ +#ifdef XK_3270 + NKS(3270_Duplicate), + NKS(3270_FieldMark), + NKS(3270_Right2), + NKS(3270_Left2), + NKS(3270_BackTab), + NKS(3270_EraseEOF), + NKS(3270_EraseInput), + NKS(3270_Reset), + NKS(3270_Quit), + NKS(3270_PA1), + NKS(3270_PA2), + NKS(3270_PA3), + NKS(3270_Test), + NKS(3270_Attn), + NKS(3270_CursorBlink), + NKS(3270_AltCursor), + NKS(3270_KeyClick), + NKS(3270_Jump), + NKS(3270_Ident), + NKS(3270_Rule), + NKS(3270_Copy), + NKS(3270_Play), + NKS(3270_Setup), + NKS(3270_Record), + NKS(3270_ChangeScreen), + NKS(3270_DeleteWord), + NKS(3270_ExSelect), + NKS(3270_CursorSelect), + NKS(3270_PrintScreen), + NKS(3270_Enter), +#endif /* XK_3270 */ +#ifdef XK_LATIN1 + NKS(space), + NKS(exclam), + NKS(quotedbl), + NKS(numbersign), + NKS(dollar), + NKS(percent), + NKS(ampersand), + NKS(apostrophe), + NKS(quoteright), + NKS(parenleft), + NKS(parenright), + NKS(asterisk), + NKS(plus), + NKS(comma), + NKS(minus), + NKS(period), + NKS(slash), + NKS(0), + NKS(1), + NKS(2), + NKS(3), + NKS(4), + NKS(5), + NKS(6), + NKS(7), + NKS(8), + NKS(9), + NKS(colon), + NKS(semicolon), + NKS(less), + NKS(equal), + NKS(greater), + NKS(question), + NKS(at), + NKS(A), + NKS(B), + NKS(C), + NKS(D), + NKS(E), + NKS(F), + NKS(G), + NKS(H), + NKS(I), + NKS(J), + NKS(K), + NKS(L), + NKS(M), + NKS(N), + NKS(O), + NKS(P), + NKS(Q), + NKS(R), + NKS(S), + NKS(T), + NKS(U), + NKS(V), + NKS(W), + NKS(X), + NKS(Y), + NKS(Z), + NKS(bracketleft), + NKS(backslash), + NKS(bracketright), + NKS(asciicircum), + NKS(underscore), + NKS(grave), + NKS(quoteleft), + NKS(a), + NKS(b), + NKS(c), + NKS(d), + NKS(e), + NKS(f), + NKS(g), + NKS(h), + NKS(i), + NKS(j), + NKS(k), + NKS(l), + NKS(m), + NKS(n), + NKS(o), + NKS(p), + NKS(q), + NKS(r), + NKS(s), + NKS(t), + NKS(u), + NKS(v), + NKS(w), + NKS(x), + NKS(y), + NKS(z), + NKS(braceleft), + NKS(bar), + NKS(braceright), + NKS(asciitilde), + NKS(nobreakspace), + NKS(exclamdown), + NKS(cent), + NKS(sterling), + NKS(currency), + NKS(yen), + NKS(brokenbar), + NKS(section), + NKS(diaeresis), + NKS(copyright), + NKS(ordfeminine), + NKS(guillemotleft), + NKS(notsign), + NKS(hyphen), + NKS(registered), + NKS(macron), + NKS(degree), + NKS(plusminus), + NKS(twosuperior), + NKS(threesuperior), + NKS(acute), + NKS(mu), + NKS(paragraph), + NKS(periodcentered), + NKS(cedilla), + NKS(onesuperior), + NKS(masculine), + NKS(guillemotright), + NKS(onequarter), + NKS(onehalf), + NKS(threequarters), + NKS(questiondown), + NKS(Agrave), + NKS(Aacute), + NKS(Acircumflex), + NKS(Atilde), + NKS(Adiaeresis), + NKS(Aring), + NKS(AE), + NKS(Ccedilla), + NKS(Egrave), + NKS(Eacute), + NKS(Ecircumflex), + NKS(Ediaeresis), + NKS(Igrave), + NKS(Iacute), + NKS(Icircumflex), + NKS(Idiaeresis), + NKS(ETH), + NKS(Eth), + NKS(Ntilde), + NKS(Ograve), + NKS(Oacute), + NKS(Ocircumflex), + NKS(Otilde), + NKS(Odiaeresis), + NKS(multiply), + NKS(Oslash), + NKS(Ooblique), + NKS(Ugrave), + NKS(Uacute), + NKS(Ucircumflex), + NKS(Udiaeresis), + NKS(Yacute), + NKS(THORN), + NKS(Thorn), + NKS(ssharp), + NKS(agrave), + NKS(aacute), + NKS(acircumflex), + NKS(atilde), + NKS(adiaeresis), + NKS(aring), + NKS(ae), + NKS(ccedilla), + NKS(egrave), + NKS(eacute), + NKS(ecircumflex), + NKS(ediaeresis), + NKS(igrave), + NKS(iacute), + NKS(icircumflex), + NKS(idiaeresis), + NKS(eth), + NKS(ntilde), + NKS(ograve), + NKS(oacute), + NKS(ocircumflex), + NKS(otilde), + NKS(odiaeresis), + NKS(division), + NKS(oslash), + NKS(ooblique), + NKS(ugrave), + NKS(uacute), + NKS(ucircumflex), + NKS(udiaeresis), + NKS(yacute), + NKS(thorn), + NKS(ydiaeresis), +#endif /* XK_LATIN1 */ +#ifdef XK_LATIN2 + NKS(Aogonek), + NKS(breve), + NKS(Lstroke), + NKS(Lcaron), + NKS(Sacute), + NKS(Scaron), + NKS(Scedilla), + NKS(Tcaron), + NKS(Zacute), + NKS(Zcaron), + NKS(Zabovedot), + NKS(aogonek), + NKS(ogonek), + NKS(lstroke), + NKS(lcaron), + NKS(sacute), + NKS(caron), + NKS(scaron), + NKS(scedilla), + NKS(tcaron), + NKS(zacute), + NKS(doubleacute), + NKS(zcaron), + NKS(zabovedot), + NKS(Racute), + NKS(Abreve), + NKS(Lacute), + NKS(Cacute), + NKS(Ccaron), + NKS(Eogonek), + NKS(Ecaron), + NKS(Dcaron), + NKS(Dstroke), + NKS(Nacute), + NKS(Ncaron), + NKS(Odoubleacute), + NKS(Rcaron), + NKS(Uring), + NKS(Udoubleacute), + NKS(Tcedilla), + NKS(racute), + NKS(abreve), + NKS(lacute), + NKS(cacute), + NKS(ccaron), + NKS(eogonek), + NKS(ecaron), + NKS(dcaron), + NKS(dstroke), + NKS(nacute), + NKS(ncaron), + NKS(odoubleacute), + NKS(rcaron), + NKS(uring), + NKS(udoubleacute), + NKS(tcedilla), + NKS(abovedot), +#endif /* XK_LATIN2 */ +#ifdef XK_LATIN3 + NKS(Hstroke), + NKS(Hcircumflex), + NKS(Iabovedot), + NKS(Gbreve), + NKS(Jcircumflex), + NKS(hstroke), + NKS(hcircumflex), + NKS(idotless), + NKS(gbreve), + NKS(jcircumflex), + NKS(Cabovedot), + NKS(Ccircumflex), + NKS(Gabovedot), + NKS(Gcircumflex), + NKS(Ubreve), + NKS(Scircumflex), + NKS(cabovedot), + NKS(ccircumflex), + NKS(gabovedot), + NKS(gcircumflex), + NKS(ubreve), + NKS(scircumflex), +#endif /* XK_LATIN3 */ +#ifdef XK_LATIN4 + NKS(kra), + NKS(kappa), + NKS(Rcedilla), + NKS(Itilde), + NKS(Lcedilla), + NKS(Emacron), + NKS(Gcedilla), + NKS(Tslash), + NKS(rcedilla), + NKS(itilde), + NKS(lcedilla), + NKS(emacron), + NKS(gcedilla), + NKS(tslash), + NKS(ENG), + NKS(eng), + NKS(Amacron), + NKS(Iogonek), + NKS(Eabovedot), + NKS(Imacron), + NKS(Ncedilla), + NKS(Omacron), + NKS(Kcedilla), + NKS(Uogonek), + NKS(Utilde), + NKS(Umacron), + NKS(amacron), + NKS(iogonek), + NKS(eabovedot), + NKS(imacron), + NKS(ncedilla), + NKS(omacron), + NKS(kcedilla), + NKS(uogonek), + NKS(utilde), + NKS(umacron), +#endif /* XK_LATIN4 */ +#ifdef XK_LATIN8 + NKS(Wcircumflex), + NKS(wcircumflex), + NKS(Ycircumflex), + NKS(ycircumflex), + NKS(Babovedot), + NKS(babovedot), + NKS(Dabovedot), + NKS(dabovedot), + NKS(Fabovedot), + NKS(fabovedot), + NKS(Mabovedot), + NKS(mabovedot), + NKS(Pabovedot), + NKS(pabovedot), + NKS(Sabovedot), + NKS(sabovedot), + NKS(Tabovedot), + NKS(tabovedot), + NKS(Wgrave), + NKS(wgrave), + NKS(Wacute), + NKS(wacute), + NKS(Wdiaeresis), + NKS(wdiaeresis), + NKS(Ygrave), + NKS(ygrave), +#endif /* XK_LATIN8 */ +#ifdef XK_LATIN9 + NKS(OE), + NKS(oe), + NKS(Ydiaeresis), +#endif /* XK_LATIN9 */ +#ifdef XK_KATAKANA + NKS(overline), + NKS(kana_fullstop), + NKS(kana_openingbracket), + NKS(kana_closingbracket), + NKS(kana_comma), + NKS(kana_conjunctive), + NKS(kana_middledot), + NKS(kana_WO), + NKS(kana_a), + NKS(kana_i), + NKS(kana_u), + NKS(kana_e), + NKS(kana_o), + NKS(kana_ya), + NKS(kana_yu), + NKS(kana_yo), + NKS(kana_tsu), + NKS(kana_tu), + NKS(prolongedsound), + NKS(kana_A), + NKS(kana_I), + NKS(kana_U), + NKS(kana_E), + NKS(kana_O), + NKS(kana_KA), + NKS(kana_KI), + NKS(kana_KU), + NKS(kana_KE), + NKS(kana_KO), + NKS(kana_SA), + NKS(kana_SHI), + NKS(kana_SU), + NKS(kana_SE), + NKS(kana_SO), + NKS(kana_TA), + NKS(kana_CHI), + NKS(kana_TI), + NKS(kana_TSU), + NKS(kana_TU), + NKS(kana_TE), + NKS(kana_TO), + NKS(kana_NA), + NKS(kana_NI), + NKS(kana_NU), + NKS(kana_NE), + NKS(kana_NO), + NKS(kana_HA), + NKS(kana_HI), + NKS(kana_FU), + NKS(kana_HU), + NKS(kana_HE), + NKS(kana_HO), + NKS(kana_MA), + NKS(kana_MI), + NKS(kana_MU), + NKS(kana_ME), + NKS(kana_MO), + NKS(kana_YA), + NKS(kana_YU), + NKS(kana_YO), + NKS(kana_RA), + NKS(kana_RI), + NKS(kana_RU), + NKS(kana_RE), + NKS(kana_RO), + NKS(kana_WA), + NKS(kana_N), + NKS(voicedsound), + NKS(semivoicedsound), + NKS(kana_switch), +#endif /* XK_KATAKANA */ +#ifdef XK_ARABIC + NKS(Farsi_0), + NKS(Farsi_1), + NKS(Farsi_2), + NKS(Farsi_3), + NKS(Farsi_4), + NKS(Farsi_5), + NKS(Farsi_6), + NKS(Farsi_7), + NKS(Farsi_8), + NKS(Farsi_9), + NKS(Arabic_percent), + NKS(Arabic_superscript_alef), + NKS(Arabic_tteh), + NKS(Arabic_peh), + NKS(Arabic_tcheh), + NKS(Arabic_ddal), + NKS(Arabic_rreh), + NKS(Arabic_comma), + NKS(Arabic_fullstop), + NKS(Arabic_0), + NKS(Arabic_1), + NKS(Arabic_2), + NKS(Arabic_3), + NKS(Arabic_4), + NKS(Arabic_5), + NKS(Arabic_6), + NKS(Arabic_7), + NKS(Arabic_8), + NKS(Arabic_9), + NKS(Arabic_semicolon), + NKS(Arabic_question_mark), + NKS(Arabic_hamza), + NKS(Arabic_maddaonalef), + NKS(Arabic_hamzaonalef), + NKS(Arabic_hamzaonwaw), + NKS(Arabic_hamzaunderalef), + NKS(Arabic_hamzaonyeh), + NKS(Arabic_alef), + NKS(Arabic_beh), + NKS(Arabic_tehmarbuta), + NKS(Arabic_teh), + NKS(Arabic_theh), + NKS(Arabic_jeem), + NKS(Arabic_hah), + NKS(Arabic_khah), + NKS(Arabic_dal), + NKS(Arabic_thal), + NKS(Arabic_ra), + NKS(Arabic_zain), + NKS(Arabic_seen), + NKS(Arabic_sheen), + NKS(Arabic_sad), + NKS(Arabic_dad), + NKS(Arabic_tah), + NKS(Arabic_zah), + NKS(Arabic_ain), + NKS(Arabic_ghain), + NKS(Arabic_tatweel), + NKS(Arabic_feh), + NKS(Arabic_qaf), + NKS(Arabic_kaf), + NKS(Arabic_lam), + NKS(Arabic_meem), + NKS(Arabic_noon), + NKS(Arabic_ha), + NKS(Arabic_heh), + NKS(Arabic_waw), + NKS(Arabic_alefmaksura), + NKS(Arabic_yeh), + NKS(Arabic_fathatan), + NKS(Arabic_dammatan), + NKS(Arabic_kasratan), + NKS(Arabic_fatha), + NKS(Arabic_damma), + NKS(Arabic_kasra), + NKS(Arabic_shadda), + NKS(Arabic_sukun), + NKS(Arabic_madda_above), + NKS(Arabic_hamza_above), + NKS(Arabic_hamza_below), + NKS(Arabic_jeh), + NKS(Arabic_veh), + NKS(Arabic_keheh), + NKS(Arabic_gaf), + NKS(Arabic_noon_ghunna), + NKS(Arabic_heh_doachashmee), + NKS(Farsi_yeh), + NKS(Arabic_farsi_yeh), + NKS(Arabic_yeh_baree), + NKS(Arabic_heh_goal), + NKS(Arabic_switch), +#endif /* XK_ARABIC */ +#ifdef XK_CYRILLIC + NKS(Cyrillic_GHE_bar), + NKS(Cyrillic_ghe_bar), + NKS(Cyrillic_ZHE_descender), + NKS(Cyrillic_zhe_descender), + NKS(Cyrillic_KA_descender), + NKS(Cyrillic_ka_descender), + NKS(Cyrillic_KA_vertstroke), + NKS(Cyrillic_ka_vertstroke), + NKS(Cyrillic_EN_descender), + NKS(Cyrillic_en_descender), + NKS(Cyrillic_U_straight), + NKS(Cyrillic_u_straight), + NKS(Cyrillic_U_straight_bar), + NKS(Cyrillic_u_straight_bar), + NKS(Cyrillic_HA_descender), + NKS(Cyrillic_ha_descender), + NKS(Cyrillic_CHE_descender), + NKS(Cyrillic_che_descender), + NKS(Cyrillic_CHE_vertstroke), + NKS(Cyrillic_che_vertstroke), + NKS(Cyrillic_SHHA), + NKS(Cyrillic_shha), + NKS(Cyrillic_SCHWA), + NKS(Cyrillic_schwa), + NKS(Cyrillic_I_macron), + NKS(Cyrillic_i_macron), + NKS(Cyrillic_O_bar), + NKS(Cyrillic_o_bar), + NKS(Cyrillic_U_macron), + NKS(Cyrillic_u_macron), + NKS(Serbian_dje), + NKS(Macedonia_gje), + NKS(Cyrillic_io), + NKS(Ukrainian_ie), + NKS(Ukranian_je), + NKS(Macedonia_dse), + NKS(Ukrainian_i), + NKS(Ukranian_i), + NKS(Ukrainian_yi), + NKS(Ukranian_yi), + NKS(Cyrillic_je), + NKS(Serbian_je), + NKS(Cyrillic_lje), + NKS(Serbian_lje), + NKS(Cyrillic_nje), + NKS(Serbian_nje), + NKS(Serbian_tshe), + NKS(Macedonia_kje), + NKS(Ukrainian_ghe_with_upturn), + NKS(Byelorussian_shortu), + NKS(Cyrillic_dzhe), + NKS(Serbian_dze), + NKS(numerosign), + NKS(Serbian_DJE), + NKS(Macedonia_GJE), + NKS(Cyrillic_IO), + NKS(Ukrainian_IE), + NKS(Ukranian_JE), + NKS(Macedonia_DSE), + NKS(Ukrainian_I), + NKS(Ukranian_I), + NKS(Ukrainian_YI), + NKS(Ukranian_YI), + NKS(Cyrillic_JE), + NKS(Serbian_JE), + NKS(Cyrillic_LJE), + NKS(Serbian_LJE), + NKS(Cyrillic_NJE), + NKS(Serbian_NJE), + NKS(Serbian_TSHE), + NKS(Macedonia_KJE), + NKS(Ukrainian_GHE_WITH_UPTURN), + NKS(Byelorussian_SHORTU), + NKS(Cyrillic_DZHE), + NKS(Serbian_DZE), + NKS(Cyrillic_yu), + NKS(Cyrillic_a), + NKS(Cyrillic_be), + NKS(Cyrillic_tse), + NKS(Cyrillic_de), + NKS(Cyrillic_ie), + NKS(Cyrillic_ef), + NKS(Cyrillic_ghe), + NKS(Cyrillic_ha), + NKS(Cyrillic_i), + NKS(Cyrillic_shorti), + NKS(Cyrillic_ka), + NKS(Cyrillic_el), + NKS(Cyrillic_em), + NKS(Cyrillic_en), + NKS(Cyrillic_o), + NKS(Cyrillic_pe), + NKS(Cyrillic_ya), + NKS(Cyrillic_er), + NKS(Cyrillic_es), + NKS(Cyrillic_te), + NKS(Cyrillic_u), + NKS(Cyrillic_zhe), + NKS(Cyrillic_ve), + NKS(Cyrillic_softsign), + NKS(Cyrillic_yeru), + NKS(Cyrillic_ze), + NKS(Cyrillic_sha), + NKS(Cyrillic_e), + NKS(Cyrillic_shcha), + NKS(Cyrillic_che), + NKS(Cyrillic_hardsign), + NKS(Cyrillic_YU), + NKS(Cyrillic_A), + NKS(Cyrillic_BE), + NKS(Cyrillic_TSE), + NKS(Cyrillic_DE), + NKS(Cyrillic_IE), + NKS(Cyrillic_EF), + NKS(Cyrillic_GHE), + NKS(Cyrillic_HA), + NKS(Cyrillic_I), + NKS(Cyrillic_SHORTI), + NKS(Cyrillic_KA), + NKS(Cyrillic_EL), + NKS(Cyrillic_EM), + NKS(Cyrillic_EN), + NKS(Cyrillic_O), + NKS(Cyrillic_PE), + NKS(Cyrillic_YA), + NKS(Cyrillic_ER), + NKS(Cyrillic_ES), + NKS(Cyrillic_TE), + NKS(Cyrillic_U), + NKS(Cyrillic_ZHE), + NKS(Cyrillic_VE), + NKS(Cyrillic_SOFTSIGN), + NKS(Cyrillic_YERU), + NKS(Cyrillic_ZE), + NKS(Cyrillic_SHA), + NKS(Cyrillic_E), + NKS(Cyrillic_SHCHA), + NKS(Cyrillic_CHE), + NKS(Cyrillic_HARDSIGN), +#endif /* XK_CYRILLIC */ +#ifdef XK_GREEK + NKS(Greek_ALPHAaccent), + NKS(Greek_EPSILONaccent), + NKS(Greek_ETAaccent), + NKS(Greek_IOTAaccent), + NKS(Greek_IOTAdieresis), + NKS(Greek_IOTAdiaeresis), + NKS(Greek_OMICRONaccent), + NKS(Greek_UPSILONaccent), + NKS(Greek_UPSILONdieresis), + NKS(Greek_OMEGAaccent), + NKS(Greek_accentdieresis), + NKS(Greek_horizbar), + NKS(Greek_alphaaccent), + NKS(Greek_epsilonaccent), + NKS(Greek_etaaccent), + NKS(Greek_iotaaccent), + NKS(Greek_iotadieresis), + NKS(Greek_iotaaccentdieresis), + NKS(Greek_omicronaccent), + NKS(Greek_upsilonaccent), + NKS(Greek_upsilondieresis), + NKS(Greek_upsilonaccentdieresis), + NKS(Greek_omegaaccent), + NKS(Greek_ALPHA), + NKS(Greek_BETA), + NKS(Greek_GAMMA), + NKS(Greek_DELTA), + NKS(Greek_EPSILON), + NKS(Greek_ZETA), + NKS(Greek_ETA), + NKS(Greek_THETA), + NKS(Greek_IOTA), + NKS(Greek_KAPPA), + NKS(Greek_LAMDA), + NKS(Greek_LAMBDA), + NKS(Greek_MU), + NKS(Greek_NU), + NKS(Greek_XI), + NKS(Greek_OMICRON), + NKS(Greek_PI), + NKS(Greek_RHO), + NKS(Greek_SIGMA), + NKS(Greek_TAU), + NKS(Greek_UPSILON), + NKS(Greek_PHI), + NKS(Greek_CHI), + NKS(Greek_PSI), + NKS(Greek_OMEGA), + NKS(Greek_alpha), + NKS(Greek_beta), + NKS(Greek_gamma), + NKS(Greek_delta), + NKS(Greek_epsilon), + NKS(Greek_zeta), + NKS(Greek_eta), + NKS(Greek_theta), + NKS(Greek_iota), + NKS(Greek_kappa), + NKS(Greek_lamda), + NKS(Greek_lambda), + NKS(Greek_mu), + NKS(Greek_nu), + NKS(Greek_xi), + NKS(Greek_omicron), + NKS(Greek_pi), + NKS(Greek_rho), + NKS(Greek_sigma), + NKS(Greek_finalsmallsigma), + NKS(Greek_tau), + NKS(Greek_upsilon), + NKS(Greek_phi), + NKS(Greek_chi), + NKS(Greek_psi), + NKS(Greek_omega), + NKS(Greek_switch), +#endif /* XK_GREEK */ +#ifdef XK_TECHNICAL + NKS(leftradical), + NKS(topleftradical), + NKS(horizconnector), + NKS(topintegral), + NKS(botintegral), + NKS(vertconnector), + NKS(topleftsqbracket), + NKS(botleftsqbracket), + NKS(toprightsqbracket), + NKS(botrightsqbracket), + NKS(topleftparens), + NKS(botleftparens), + NKS(toprightparens), + NKS(botrightparens), + NKS(leftmiddlecurlybrace), + NKS(rightmiddlecurlybrace), + NKS(topleftsummation), + NKS(botleftsummation), + NKS(topvertsummationconnector), + NKS(botvertsummationconnector), + NKS(toprightsummation), + NKS(botrightsummation), + NKS(rightmiddlesummation), + NKS(lessthanequal), + NKS(notequal), + NKS(greaterthanequal), + NKS(integral), + NKS(therefore), + NKS(variation), + NKS(infinity), + NKS(nabla), + NKS(approximate), + NKS(similarequal), + NKS(ifonlyif), + NKS(implies), + NKS(identical), + NKS(radical), + NKS(includedin), + NKS(includes), + NKS(intersection), + NKS(union), + NKS(logicaland), + NKS(logicalor), + NKS(partialderivative), + NKS(function), + NKS(leftarrow), + NKS(uparrow), + NKS(rightarrow), + NKS(downarrow), +#endif /* XK_TECHNICAL */ +#ifdef XK_SPECIAL + NKS(blank), + NKS(soliddiamond), + NKS(checkerboard), + NKS(ht), + NKS(ff), + NKS(cr), + NKS(lf), + NKS(nl), + NKS(vt), + NKS(lowrightcorner), + NKS(uprightcorner), + NKS(upleftcorner), + NKS(lowleftcorner), + NKS(crossinglines), + NKS(horizlinescan1), + NKS(horizlinescan3), + NKS(horizlinescan5), + NKS(horizlinescan7), + NKS(horizlinescan9), + NKS(leftt), + NKS(rightt), + NKS(bott), + NKS(topt), + NKS(vertbar), +#endif /* XK_SPECIAL */ +#ifdef XK_PUBLISHING + NKS(emspace), + NKS(enspace), + NKS(em3space), + NKS(em4space), + NKS(digitspace), + NKS(punctspace), + NKS(thinspace), + NKS(hairspace), + NKS(emdash), + NKS(endash), + NKS(signifblank), + NKS(ellipsis), + NKS(doubbaselinedot), + NKS(onethird), + NKS(twothirds), + NKS(onefifth), + NKS(twofifths), + NKS(threefifths), + NKS(fourfifths), + NKS(onesixth), + NKS(fivesixths), + NKS(careof), + NKS(figdash), + NKS(leftanglebracket), + NKS(decimalpoint), + NKS(rightanglebracket), + NKS(marker), + NKS(oneeighth), + NKS(threeeighths), + NKS(fiveeighths), + NKS(seveneighths), + NKS(trademark), + NKS(signaturemark), + NKS(trademarkincircle), + NKS(leftopentriangle), + NKS(rightopentriangle), + NKS(emopencircle), + NKS(emopenrectangle), + NKS(leftsinglequotemark), + NKS(rightsinglequotemark), + NKS(leftdoublequotemark), + NKS(rightdoublequotemark), + NKS(prescription), + NKS(permille), + NKS(minutes), + NKS(seconds), + NKS(latincross), + NKS(hexagram), + NKS(filledrectbullet), + NKS(filledlefttribullet), + NKS(filledrighttribullet), + NKS(emfilledcircle), + NKS(emfilledrect), + NKS(enopencircbullet), + NKS(enopensquarebullet), + NKS(openrectbullet), + NKS(opentribulletup), + NKS(opentribulletdown), + NKS(openstar), + NKS(enfilledcircbullet), + NKS(enfilledsqbullet), + NKS(filledtribulletup), + NKS(filledtribulletdown), + NKS(leftpointer), + NKS(rightpointer), + NKS(club), + NKS(diamond), + NKS(heart), + NKS(maltesecross), + NKS(dagger), + NKS(doubledagger), + NKS(checkmark), + NKS(ballotcross), + NKS(musicalsharp), + NKS(musicalflat), + NKS(malesymbol), + NKS(femalesymbol), + NKS(telephone), + NKS(telephonerecorder), + NKS(phonographcopyright), + NKS(caret), + NKS(singlelowquotemark), + NKS(doublelowquotemark), + NKS(cursor), +#endif /* XK_PUBLISHING */ +#ifdef XK_APL + NKS(leftcaret), + NKS(rightcaret), + NKS(downcaret), + NKS(upcaret), + NKS(overbar), + NKS(downtack), + NKS(upshoe), + NKS(downstile), + NKS(underbar), + NKS(jot), + NKS(quad), + NKS(uptack), + NKS(circle), + NKS(upstile), + NKS(downshoe), + NKS(rightshoe), + NKS(leftshoe), + NKS(lefttack), + NKS(righttack), +#endif /* XK_APL */ +#ifdef XK_HEBREW + NKS(hebrew_doublelowline), + NKS(hebrew_aleph), + NKS(hebrew_bet), + NKS(hebrew_beth), + NKS(hebrew_gimel), + NKS(hebrew_gimmel), + NKS(hebrew_dalet), + NKS(hebrew_daleth), + NKS(hebrew_he), + NKS(hebrew_waw), + NKS(hebrew_zain), + NKS(hebrew_zayin), + NKS(hebrew_chet), + NKS(hebrew_het), + NKS(hebrew_tet), + NKS(hebrew_teth), + NKS(hebrew_yod), + NKS(hebrew_finalkaph), + NKS(hebrew_kaph), + NKS(hebrew_lamed), + NKS(hebrew_finalmem), + NKS(hebrew_mem), + NKS(hebrew_finalnun), + NKS(hebrew_nun), + NKS(hebrew_samech), + NKS(hebrew_samekh), + NKS(hebrew_ayin), + NKS(hebrew_finalpe), + NKS(hebrew_pe), + NKS(hebrew_finalzade), + NKS(hebrew_finalzadi), + NKS(hebrew_zade), + NKS(hebrew_zadi), + NKS(hebrew_qoph), + NKS(hebrew_kuf), + NKS(hebrew_resh), + NKS(hebrew_shin), + NKS(hebrew_taw), + NKS(hebrew_taf), + NKS(Hebrew_switch), +#endif /* XK_HEBREW */ +#ifdef XK_THAI + NKS(Thai_kokai), + NKS(Thai_khokhai), + NKS(Thai_khokhuat), + NKS(Thai_khokhwai), + NKS(Thai_khokhon), + NKS(Thai_khorakhang), + NKS(Thai_ngongu), + NKS(Thai_chochan), + NKS(Thai_choching), + NKS(Thai_chochang), + NKS(Thai_soso), + NKS(Thai_chochoe), + NKS(Thai_yoying), + NKS(Thai_dochada), + NKS(Thai_topatak), + NKS(Thai_thothan), + NKS(Thai_thonangmontho), + NKS(Thai_thophuthao), + NKS(Thai_nonen), + NKS(Thai_dodek), + NKS(Thai_totao), + NKS(Thai_thothung), + NKS(Thai_thothahan), + NKS(Thai_thothong), + NKS(Thai_nonu), + NKS(Thai_bobaimai), + NKS(Thai_popla), + NKS(Thai_phophung), + NKS(Thai_fofa), + NKS(Thai_phophan), + NKS(Thai_fofan), + NKS(Thai_phosamphao), + NKS(Thai_moma), + NKS(Thai_yoyak), + NKS(Thai_rorua), + NKS(Thai_ru), + NKS(Thai_loling), + NKS(Thai_lu), + NKS(Thai_wowaen), + NKS(Thai_sosala), + NKS(Thai_sorusi), + NKS(Thai_sosua), + NKS(Thai_hohip), + NKS(Thai_lochula), + NKS(Thai_oang), + NKS(Thai_honokhuk), + NKS(Thai_paiyannoi), + NKS(Thai_saraa), + NKS(Thai_maihanakat), + NKS(Thai_saraaa), + NKS(Thai_saraam), + NKS(Thai_sarai), + NKS(Thai_saraii), + NKS(Thai_saraue), + NKS(Thai_sarauee), + NKS(Thai_sarau), + NKS(Thai_sarauu), + NKS(Thai_phinthu), + NKS(Thai_maihanakat_maitho), + NKS(Thai_baht), + NKS(Thai_sarae), + NKS(Thai_saraae), + NKS(Thai_sarao), + NKS(Thai_saraaimaimuan), + NKS(Thai_saraaimaimalai), + NKS(Thai_lakkhangyao), + NKS(Thai_maiyamok), + NKS(Thai_maitaikhu), + NKS(Thai_maiek), + NKS(Thai_maitho), + NKS(Thai_maitri), + NKS(Thai_maichattawa), + NKS(Thai_thanthakhat), + NKS(Thai_nikhahit), + NKS(Thai_leksun), + NKS(Thai_leknung), + NKS(Thai_leksong), + NKS(Thai_leksam), + NKS(Thai_leksi), + NKS(Thai_lekha), + NKS(Thai_lekhok), + NKS(Thai_lekchet), + NKS(Thai_lekpaet), + NKS(Thai_lekkao), +#endif /* XK_THAI */ +#ifdef XK_KOREAN + NKS(Hangul), + NKS(Hangul_Start), + NKS(Hangul_End), + NKS(Hangul_Hanja), + NKS(Hangul_Jamo), + NKS(Hangul_Romaja), + NKS(Hangul_Codeinput), + NKS(Hangul_Jeonja), + NKS(Hangul_Banja), + NKS(Hangul_PreHanja), + NKS(Hangul_PostHanja), + NKS(Hangul_SingleCandidate), + NKS(Hangul_MultipleCandidate), + NKS(Hangul_PreviousCandidate), + NKS(Hangul_Special), + NKS(Hangul_switch), + NKS(Hangul_Kiyeog), + NKS(Hangul_SsangKiyeog), + NKS(Hangul_KiyeogSios), + NKS(Hangul_Nieun), + NKS(Hangul_NieunJieuj), + NKS(Hangul_NieunHieuh), + NKS(Hangul_Dikeud), + NKS(Hangul_SsangDikeud), + NKS(Hangul_Rieul), + NKS(Hangul_RieulKiyeog), + NKS(Hangul_RieulMieum), + NKS(Hangul_RieulPieub), + NKS(Hangul_RieulSios), + NKS(Hangul_RieulTieut), + NKS(Hangul_RieulPhieuf), + NKS(Hangul_RieulHieuh), + NKS(Hangul_Mieum), + NKS(Hangul_Pieub), + NKS(Hangul_SsangPieub), + NKS(Hangul_PieubSios), + NKS(Hangul_Sios), + NKS(Hangul_SsangSios), + NKS(Hangul_Ieung), + NKS(Hangul_Jieuj), + NKS(Hangul_SsangJieuj), + NKS(Hangul_Cieuc), + NKS(Hangul_Khieuq), + NKS(Hangul_Tieut), + NKS(Hangul_Phieuf), + NKS(Hangul_Hieuh), + NKS(Hangul_A), + NKS(Hangul_AE), + NKS(Hangul_YA), + NKS(Hangul_YAE), + NKS(Hangul_EO), + NKS(Hangul_E), + NKS(Hangul_YEO), + NKS(Hangul_YE), + NKS(Hangul_O), + NKS(Hangul_WA), + NKS(Hangul_WAE), + NKS(Hangul_OE), + NKS(Hangul_YO), + NKS(Hangul_U), + NKS(Hangul_WEO), + NKS(Hangul_WE), + NKS(Hangul_WI), + NKS(Hangul_YU), + NKS(Hangul_EU), + NKS(Hangul_YI), + NKS(Hangul_I), + NKS(Hangul_J_Kiyeog), + NKS(Hangul_J_SsangKiyeog), + NKS(Hangul_J_KiyeogSios), + NKS(Hangul_J_Nieun), + NKS(Hangul_J_NieunJieuj), + NKS(Hangul_J_NieunHieuh), + NKS(Hangul_J_Dikeud), + NKS(Hangul_J_Rieul), + NKS(Hangul_J_RieulKiyeog), + NKS(Hangul_J_RieulMieum), + NKS(Hangul_J_RieulPieub), + NKS(Hangul_J_RieulSios), + NKS(Hangul_J_RieulTieut), + NKS(Hangul_J_RieulPhieuf), + NKS(Hangul_J_RieulHieuh), + NKS(Hangul_J_Mieum), + NKS(Hangul_J_Pieub), + NKS(Hangul_J_PieubSios), + NKS(Hangul_J_Sios), + NKS(Hangul_J_SsangSios), + NKS(Hangul_J_Ieung), + NKS(Hangul_J_Jieuj), + NKS(Hangul_J_Cieuc), + NKS(Hangul_J_Khieuq), + NKS(Hangul_J_Tieut), + NKS(Hangul_J_Phieuf), + NKS(Hangul_J_Hieuh), + NKS(Hangul_RieulYeorinHieuh), + NKS(Hangul_SunkyeongeumMieum), + NKS(Hangul_SunkyeongeumPieub), + NKS(Hangul_PanSios), + NKS(Hangul_KkogjiDalrinIeung), + NKS(Hangul_SunkyeongeumPhieuf), + NKS(Hangul_YeorinHieuh), + NKS(Hangul_AraeA), + NKS(Hangul_AraeAE), + NKS(Hangul_J_PanSios), + NKS(Hangul_J_KkogjiDalrinIeung), + NKS(Hangul_J_YeorinHieuh), + NKS(Korean_Won), +#endif /* XK_KOREAN */ +#ifdef XK_ARMENIAN + NKS(Armenian_ligature_ew), + NKS(Armenian_full_stop), + NKS(Armenian_verjaket), + NKS(Armenian_separation_mark), + NKS(Armenian_but), + NKS(Armenian_hyphen), + NKS(Armenian_yentamna), + NKS(Armenian_exclam), + NKS(Armenian_amanak), + NKS(Armenian_accent), + NKS(Armenian_shesht), + NKS(Armenian_question), + NKS(Armenian_paruyk), + NKS(Armenian_AYB), + NKS(Armenian_ayb), + NKS(Armenian_BEN), + NKS(Armenian_ben), + NKS(Armenian_GIM), + NKS(Armenian_gim), + NKS(Armenian_DA), + NKS(Armenian_da), + NKS(Armenian_YECH), + NKS(Armenian_yech), + NKS(Armenian_ZA), + NKS(Armenian_za), + NKS(Armenian_E), + NKS(Armenian_e), + NKS(Armenian_AT), + NKS(Armenian_at), + NKS(Armenian_TO), + NKS(Armenian_to), + NKS(Armenian_ZHE), + NKS(Armenian_zhe), + NKS(Armenian_INI), + NKS(Armenian_ini), + NKS(Armenian_LYUN), + NKS(Armenian_lyun), + NKS(Armenian_KHE), + NKS(Armenian_khe), + NKS(Armenian_TSA), + NKS(Armenian_tsa), + NKS(Armenian_KEN), + NKS(Armenian_ken), + NKS(Armenian_HO), + NKS(Armenian_ho), + NKS(Armenian_DZA), + NKS(Armenian_dza), + NKS(Armenian_GHAT), + NKS(Armenian_ghat), + NKS(Armenian_TCHE), + NKS(Armenian_tche), + NKS(Armenian_MEN), + NKS(Armenian_men), + NKS(Armenian_HI), + NKS(Armenian_hi), + NKS(Armenian_NU), + NKS(Armenian_nu), + NKS(Armenian_SHA), + NKS(Armenian_sha), + NKS(Armenian_VO), + NKS(Armenian_vo), + NKS(Armenian_CHA), + NKS(Armenian_cha), + NKS(Armenian_PE), + NKS(Armenian_pe), + NKS(Armenian_JE), + NKS(Armenian_je), + NKS(Armenian_RA), + NKS(Armenian_ra), + NKS(Armenian_SE), + NKS(Armenian_se), + NKS(Armenian_VEV), + NKS(Armenian_vev), + NKS(Armenian_TYUN), + NKS(Armenian_tyun), + NKS(Armenian_RE), + NKS(Armenian_re), + NKS(Armenian_TSO), + NKS(Armenian_tso), + NKS(Armenian_VYUN), + NKS(Armenian_vyun), + NKS(Armenian_PYUR), + NKS(Armenian_pyur), + NKS(Armenian_KE), + NKS(Armenian_ke), + NKS(Armenian_O), + NKS(Armenian_o), + NKS(Armenian_FE), + NKS(Armenian_fe), + NKS(Armenian_apostrophe), +#endif /* XK_ARMENIAN */ +#ifdef XK_GEORGIAN + NKS(Georgian_an), + NKS(Georgian_ban), + NKS(Georgian_gan), + NKS(Georgian_don), + NKS(Georgian_en), + NKS(Georgian_vin), + NKS(Georgian_zen), + NKS(Georgian_tan), + NKS(Georgian_in), + NKS(Georgian_kan), + NKS(Georgian_las), + NKS(Georgian_man), + NKS(Georgian_nar), + NKS(Georgian_on), + NKS(Georgian_par), + NKS(Georgian_zhar), + NKS(Georgian_rae), + NKS(Georgian_san), + NKS(Georgian_tar), + NKS(Georgian_un), + NKS(Georgian_phar), + NKS(Georgian_khar), + NKS(Georgian_ghan), + NKS(Georgian_qar), + NKS(Georgian_shin), + NKS(Georgian_chin), + NKS(Georgian_can), + NKS(Georgian_jil), + NKS(Georgian_cil), + NKS(Georgian_char), + NKS(Georgian_xan), + NKS(Georgian_jhan), + NKS(Georgian_hae), + NKS(Georgian_he), + NKS(Georgian_hie), + NKS(Georgian_we), + NKS(Georgian_har), + NKS(Georgian_hoe), + NKS(Georgian_fi), +#endif /* XK_GEORGIAN */ +#ifdef XK_CAUCASUS + NKS(Xabovedot), + NKS(Ibreve), + NKS(Zstroke), + NKS(Gcaron), + NKS(Ocaron), + NKS(Obarred), + NKS(xabovedot), + NKS(ibreve), + NKS(zstroke), + NKS(gcaron), + NKS(ocaron), + NKS(obarred), + NKS(SCHWA), + NKS(schwa), + NKS(EZH), + NKS(ezh), + NKS(Lbelowdot), + NKS(lbelowdot), +#endif /* XK_CAUCASUS */ +#ifdef XK_VIETNAMESE + NKS(Abelowdot), + NKS(abelowdot), + NKS(Ahook), + NKS(ahook), + NKS(Acircumflexacute), + NKS(acircumflexacute), + NKS(Acircumflexgrave), + NKS(acircumflexgrave), + NKS(Acircumflexhook), + NKS(acircumflexhook), + NKS(Acircumflextilde), + NKS(acircumflextilde), + NKS(Acircumflexbelowdot), + NKS(acircumflexbelowdot), + NKS(Abreveacute), + NKS(abreveacute), + NKS(Abrevegrave), + NKS(abrevegrave), + NKS(Abrevehook), + NKS(abrevehook), + NKS(Abrevetilde), + NKS(abrevetilde), + NKS(Abrevebelowdot), + NKS(abrevebelowdot), + NKS(Ebelowdot), + NKS(ebelowdot), + NKS(Ehook), + NKS(ehook), + NKS(Etilde), + NKS(etilde), + NKS(Ecircumflexacute), + NKS(ecircumflexacute), + NKS(Ecircumflexgrave), + NKS(ecircumflexgrave), + NKS(Ecircumflexhook), + NKS(ecircumflexhook), + NKS(Ecircumflextilde), + NKS(ecircumflextilde), + NKS(Ecircumflexbelowdot), + NKS(ecircumflexbelowdot), + NKS(Ihook), + NKS(ihook), + NKS(Ibelowdot), + NKS(ibelowdot), + NKS(Obelowdot), + NKS(obelowdot), + NKS(Ohook), + NKS(ohook), + NKS(Ocircumflexacute), + NKS(ocircumflexacute), + NKS(Ocircumflexgrave), + NKS(ocircumflexgrave), + NKS(Ocircumflexhook), + NKS(ocircumflexhook), + NKS(Ocircumflextilde), + NKS(ocircumflextilde), + NKS(Ocircumflexbelowdot), + NKS(ocircumflexbelowdot), + NKS(Ohornacute), + NKS(ohornacute), + NKS(Ohorngrave), + NKS(ohorngrave), + NKS(Ohornhook), + NKS(ohornhook), + NKS(Ohorntilde), + NKS(ohorntilde), + NKS(Ohornbelowdot), + NKS(ohornbelowdot), + NKS(Ubelowdot), + NKS(ubelowdot), + NKS(Uhook), + NKS(uhook), + NKS(Uhornacute), + NKS(uhornacute), + NKS(Uhorngrave), + NKS(uhorngrave), + NKS(Uhornhook), + NKS(uhornhook), + NKS(Uhorntilde), + NKS(uhorntilde), + NKS(Uhornbelowdot), + NKS(uhornbelowdot), + NKS(Ybelowdot), + NKS(ybelowdot), + NKS(Yhook), + NKS(yhook), + NKS(Ytilde), + NKS(ytilde), + NKS(Ohorn), + NKS(ohorn), + NKS(Uhorn), + NKS(uhorn), +#endif /* XK_VIETNAMESE */ +#ifdef XK_CURRENCY + NKS(EcuSign), + NKS(ColonSign), + NKS(CruzeiroSign), + NKS(FFrancSign), + NKS(LiraSign), + NKS(MillSign), + NKS(NairaSign), + NKS(PesetaSign), + NKS(RupeeSign), + NKS(WonSign), + NKS(NewSheqelSign), + NKS(DongSign), + NKS(EuroSign), +#endif /* XK_CURRENCY */ +#ifdef XK_MATHEMATICAL + NKS(zerosuperior), + NKS(foursuperior), + NKS(fivesuperior), + NKS(sixsuperior), + NKS(sevensuperior), + NKS(eightsuperior), + NKS(ninesuperior), + NKS(zerosubscript), + NKS(onesubscript), + NKS(twosubscript), + NKS(threesubscript), + NKS(foursubscript), + NKS(fivesubscript), + NKS(sixsubscript), + NKS(sevensubscript), + NKS(eightsubscript), + NKS(ninesubscript), + NKS(partdifferential), + NKS(emptyset), + NKS(elementof), + NKS(notelementof), + NKS(containsas), + NKS(squareroot), + NKS(cuberoot), + NKS(fourthroot), + NKS(dintegral), + NKS(tintegral), + NKS(because), + NKS(approxeq), + NKS(notapproxeq), + NKS(notidentical), + NKS(stricteq), +#endif /* XK_MATHEMATICAL */ +#ifdef XK_BRAILLE + NKS(braille_dot_1), + NKS(braille_dot_2), + NKS(braille_dot_3), + NKS(braille_dot_4), + NKS(braille_dot_5), + NKS(braille_dot_6), + NKS(braille_dot_7), + NKS(braille_dot_8), + NKS(braille_dot_9), + NKS(braille_dot_10), + NKS(braille_blank), + NKS(braille_dots_1), + NKS(braille_dots_2), + NKS(braille_dots_12), + NKS(braille_dots_3), + NKS(braille_dots_13), + NKS(braille_dots_23), + NKS(braille_dots_123), + NKS(braille_dots_4), + NKS(braille_dots_14), + NKS(braille_dots_24), + NKS(braille_dots_124), + NKS(braille_dots_34), + NKS(braille_dots_134), + NKS(braille_dots_234), + NKS(braille_dots_1234), + NKS(braille_dots_5), + NKS(braille_dots_15), + NKS(braille_dots_25), + NKS(braille_dots_125), + NKS(braille_dots_35), + NKS(braille_dots_135), + NKS(braille_dots_235), + NKS(braille_dots_1235), + NKS(braille_dots_45), + NKS(braille_dots_145), + NKS(braille_dots_245), + NKS(braille_dots_1245), + NKS(braille_dots_345), + NKS(braille_dots_1345), + NKS(braille_dots_2345), + NKS(braille_dots_12345), + NKS(braille_dots_6), + NKS(braille_dots_16), + NKS(braille_dots_26), + NKS(braille_dots_126), + NKS(braille_dots_36), + NKS(braille_dots_136), + NKS(braille_dots_236), + NKS(braille_dots_1236), + NKS(braille_dots_46), + NKS(braille_dots_146), + NKS(braille_dots_246), + NKS(braille_dots_1246), + NKS(braille_dots_346), + NKS(braille_dots_1346), + NKS(braille_dots_2346), + NKS(braille_dots_12346), + NKS(braille_dots_56), + NKS(braille_dots_156), + NKS(braille_dots_256), + NKS(braille_dots_1256), + NKS(braille_dots_356), + NKS(braille_dots_1356), + NKS(braille_dots_2356), + NKS(braille_dots_12356), + NKS(braille_dots_456), + NKS(braille_dots_1456), + NKS(braille_dots_2456), + NKS(braille_dots_12456), + NKS(braille_dots_3456), + NKS(braille_dots_13456), + NKS(braille_dots_23456), + NKS(braille_dots_123456), + NKS(braille_dots_7), + NKS(braille_dots_17), + NKS(braille_dots_27), + NKS(braille_dots_127), + NKS(braille_dots_37), + NKS(braille_dots_137), + NKS(braille_dots_237), + NKS(braille_dots_1237), + NKS(braille_dots_47), + NKS(braille_dots_147), + NKS(braille_dots_247), + NKS(braille_dots_1247), + NKS(braille_dots_347), + NKS(braille_dots_1347), + NKS(braille_dots_2347), + NKS(braille_dots_12347), + NKS(braille_dots_57), + NKS(braille_dots_157), + NKS(braille_dots_257), + NKS(braille_dots_1257), + NKS(braille_dots_357), + NKS(braille_dots_1357), + NKS(braille_dots_2357), + NKS(braille_dots_12357), + NKS(braille_dots_457), + NKS(braille_dots_1457), + NKS(braille_dots_2457), + NKS(braille_dots_12457), + NKS(braille_dots_3457), + NKS(braille_dots_13457), + NKS(braille_dots_23457), + NKS(braille_dots_123457), + NKS(braille_dots_67), + NKS(braille_dots_167), + NKS(braille_dots_267), + NKS(braille_dots_1267), + NKS(braille_dots_367), + NKS(braille_dots_1367), + NKS(braille_dots_2367), + NKS(braille_dots_12367), + NKS(braille_dots_467), + NKS(braille_dots_1467), + NKS(braille_dots_2467), + NKS(braille_dots_12467), + NKS(braille_dots_3467), + NKS(braille_dots_13467), + NKS(braille_dots_23467), + NKS(braille_dots_123467), + NKS(braille_dots_567), + NKS(braille_dots_1567), + NKS(braille_dots_2567), + NKS(braille_dots_12567), + NKS(braille_dots_3567), + NKS(braille_dots_13567), + NKS(braille_dots_23567), + NKS(braille_dots_123567), + NKS(braille_dots_4567), + NKS(braille_dots_14567), + NKS(braille_dots_24567), + NKS(braille_dots_124567), + NKS(braille_dots_34567), + NKS(braille_dots_134567), + NKS(braille_dots_234567), + NKS(braille_dots_1234567), + NKS(braille_dots_8), + NKS(braille_dots_18), + NKS(braille_dots_28), + NKS(braille_dots_128), + NKS(braille_dots_38), + NKS(braille_dots_138), + NKS(braille_dots_238), + NKS(braille_dots_1238), + NKS(braille_dots_48), + NKS(braille_dots_148), + NKS(braille_dots_248), + NKS(braille_dots_1248), + NKS(braille_dots_348), + NKS(braille_dots_1348), + NKS(braille_dots_2348), + NKS(braille_dots_12348), + NKS(braille_dots_58), + NKS(braille_dots_158), + NKS(braille_dots_258), + NKS(braille_dots_1258), + NKS(braille_dots_358), + NKS(braille_dots_1358), + NKS(braille_dots_2358), + NKS(braille_dots_12358), + NKS(braille_dots_458), + NKS(braille_dots_1458), + NKS(braille_dots_2458), + NKS(braille_dots_12458), + NKS(braille_dots_3458), + NKS(braille_dots_13458), + NKS(braille_dots_23458), + NKS(braille_dots_123458), + NKS(braille_dots_68), + NKS(braille_dots_168), + NKS(braille_dots_268), + NKS(braille_dots_1268), + NKS(braille_dots_368), + NKS(braille_dots_1368), + NKS(braille_dots_2368), + NKS(braille_dots_12368), + NKS(braille_dots_468), + NKS(braille_dots_1468), + NKS(braille_dots_2468), + NKS(braille_dots_12468), + NKS(braille_dots_3468), + NKS(braille_dots_13468), + NKS(braille_dots_23468), + NKS(braille_dots_123468), + NKS(braille_dots_568), + NKS(braille_dots_1568), + NKS(braille_dots_2568), + NKS(braille_dots_12568), + NKS(braille_dots_3568), + NKS(braille_dots_13568), + NKS(braille_dots_23568), + NKS(braille_dots_123568), + NKS(braille_dots_4568), + NKS(braille_dots_14568), + NKS(braille_dots_24568), + NKS(braille_dots_124568), + NKS(braille_dots_34568), + NKS(braille_dots_134568), + NKS(braille_dots_234568), + NKS(braille_dots_1234568), + NKS(braille_dots_78), + NKS(braille_dots_178), + NKS(braille_dots_278), + NKS(braille_dots_1278), + NKS(braille_dots_378), + NKS(braille_dots_1378), + NKS(braille_dots_2378), + NKS(braille_dots_12378), + NKS(braille_dots_478), + NKS(braille_dots_1478), + NKS(braille_dots_2478), + NKS(braille_dots_12478), + NKS(braille_dots_3478), + NKS(braille_dots_13478), + NKS(braille_dots_23478), + NKS(braille_dots_123478), + NKS(braille_dots_578), + NKS(braille_dots_1578), + NKS(braille_dots_2578), + NKS(braille_dots_12578), + NKS(braille_dots_3578), + NKS(braille_dots_13578), + NKS(braille_dots_23578), + NKS(braille_dots_123578), + NKS(braille_dots_4578), + NKS(braille_dots_14578), + NKS(braille_dots_24578), + NKS(braille_dots_124578), + NKS(braille_dots_34578), + NKS(braille_dots_134578), + NKS(braille_dots_234578), + NKS(braille_dots_1234578), + NKS(braille_dots_678), + NKS(braille_dots_1678), + NKS(braille_dots_2678), + NKS(braille_dots_12678), + NKS(braille_dots_3678), + NKS(braille_dots_13678), + NKS(braille_dots_23678), + NKS(braille_dots_123678), + NKS(braille_dots_4678), + NKS(braille_dots_14678), + NKS(braille_dots_24678), + NKS(braille_dots_124678), + NKS(braille_dots_34678), + NKS(braille_dots_134678), + NKS(braille_dots_234678), + NKS(braille_dots_1234678), + NKS(braille_dots_5678), + NKS(braille_dots_15678), + NKS(braille_dots_25678), + NKS(braille_dots_125678), + NKS(braille_dots_35678), + NKS(braille_dots_135678), + NKS(braille_dots_235678), + NKS(braille_dots_1235678), + NKS(braille_dots_45678), + NKS(braille_dots_145678), + NKS(braille_dots_245678), + NKS(braille_dots_1245678), + NKS(braille_dots_345678), + NKS(braille_dots_1345678), + NKS(braille_dots_2345678), + NKS(braille_dots_12345678), +#endif /* XK_BRAILLE */ +#ifdef XK_SINHALA + NKS(Sinh_ng), + NKS(Sinh_h2), + NKS(Sinh_a), + NKS(Sinh_aa), + NKS(Sinh_ae), + NKS(Sinh_aee), + NKS(Sinh_i), + NKS(Sinh_ii), + NKS(Sinh_u), + NKS(Sinh_uu), + NKS(Sinh_ri), + NKS(Sinh_rii), + NKS(Sinh_lu), + NKS(Sinh_luu), + NKS(Sinh_e), + NKS(Sinh_ee), + NKS(Sinh_ai), + NKS(Sinh_o), + NKS(Sinh_oo), + NKS(Sinh_au), + NKS(Sinh_ka), + NKS(Sinh_kha), + NKS(Sinh_ga), + NKS(Sinh_gha), + NKS(Sinh_ng2), + NKS(Sinh_nga), + NKS(Sinh_ca), + NKS(Sinh_cha), + NKS(Sinh_ja), + NKS(Sinh_jha), + NKS(Sinh_nya), + NKS(Sinh_jnya), + NKS(Sinh_nja), + NKS(Sinh_tta), + NKS(Sinh_ttha), + NKS(Sinh_dda), + NKS(Sinh_ddha), + NKS(Sinh_nna), + NKS(Sinh_ndda), + NKS(Sinh_tha), + NKS(Sinh_thha), + NKS(Sinh_dha), + NKS(Sinh_dhha), + NKS(Sinh_na), + NKS(Sinh_ndha), + NKS(Sinh_pa), + NKS(Sinh_pha), + NKS(Sinh_ba), + NKS(Sinh_bha), + NKS(Sinh_ma), + NKS(Sinh_mba), + NKS(Sinh_ya), + NKS(Sinh_ra), + NKS(Sinh_la), + NKS(Sinh_va), + NKS(Sinh_sha), + NKS(Sinh_ssha), + NKS(Sinh_sa), + NKS(Sinh_ha), + NKS(Sinh_lla), + NKS(Sinh_fa), + NKS(Sinh_al), + NKS(Sinh_aa2), + NKS(Sinh_ae2), + NKS(Sinh_aee2), + NKS(Sinh_i2), + NKS(Sinh_ii2), + NKS(Sinh_u2), + NKS(Sinh_uu2), + NKS(Sinh_ru2), + NKS(Sinh_e2), + NKS(Sinh_ee2), + NKS(Sinh_ai2), + NKS(Sinh_o2), + NKS(Sinh_oo2), + NKS(Sinh_au2), + NKS(Sinh_lu2), + NKS(Sinh_ruu2), + NKS(Sinh_luu2), + NKS(Sinh_kunddaliya), +#endif /* XK_SINHALA */ +#undef NKS +#define NKS(x) { #x, XF86XK_ ## x } + NKS(ModeLock), + NKS(MonBrightnessUp), + NKS(MonBrightnessDown), + NKS(KbdLightOnOff), + NKS(KbdBrightnessUp), + NKS(KbdBrightnessDown), + NKS(Standby), + NKS(AudioLowerVolume), + NKS(AudioMute), + NKS(AudioRaiseVolume), + NKS(AudioPlay), + NKS(AudioStop), + NKS(AudioPrev), + NKS(AudioNext), + NKS(HomePage), + NKS(Mail), + NKS(Start), + NKS(Search), + NKS(AudioRecord), + NKS(Calculator), + NKS(Memo), + NKS(ToDoList), + NKS(Calendar), + NKS(PowerDown), + NKS(ContrastAdjust), + NKS(RockerUp), + NKS(RockerDown), + NKS(RockerEnter), + NKS(Back), + NKS(Forward), + NKS(Stop), + NKS(Refresh), + NKS(PowerOff), + NKS(WakeUp), + NKS(Eject), + NKS(ScreenSaver), + NKS(WWW), + NKS(Sleep), + NKS(Favorites), + NKS(AudioPause), + NKS(AudioMedia), + NKS(MyComputer), + NKS(VendorHome), + NKS(LightBulb), + NKS(Shop), + NKS(History), + NKS(OpenURL), + NKS(AddFavorite), + NKS(HotLinks), + NKS(BrightnessAdjust), + NKS(Finance), + NKS(Community), + NKS(AudioRewind), + NKS(BackForward), + NKS(Launch0), + NKS(Launch1), + NKS(Launch2), + NKS(Launch3), + NKS(Launch4), + NKS(Launch5), + NKS(Launch6), + NKS(Launch7), + NKS(Launch8), + NKS(Launch9), + NKS(LaunchA), + NKS(LaunchB), + NKS(LaunchC), + NKS(LaunchD), + NKS(LaunchE), + NKS(LaunchF), + NKS(ApplicationLeft), + NKS(ApplicationRight), + NKS(Book), + NKS(CD), + NKS(Calculater), + NKS(Clear), + NKS(Close), + NKS(Copy), + NKS(Cut), + NKS(Display), + NKS(DOS), + NKS(Documents), + NKS(Excel), + NKS(Explorer), + NKS(Game), + NKS(Go), + NKS(iTouch), + NKS(LogOff), + NKS(Market), + NKS(Meeting), + NKS(MenuKB), + NKS(MenuPB), + NKS(MySites), + NKS(New), + NKS(News), + NKS(OfficeHome), + NKS(Open), + NKS(Option), + NKS(Paste), + NKS(Phone), + NKS(Q), + NKS(Reply), + NKS(Reload), + NKS(RotateWindows), + NKS(RotationPB), + NKS(RotationKB), + NKS(Save), + NKS(ScrollUp), + NKS(ScrollDown), + NKS(ScrollClick), + NKS(Send), + NKS(Spell), + NKS(SplitScreen), + NKS(Support), + NKS(TaskPane), + NKS(Terminal), + NKS(Tools), + NKS(Travel), + NKS(UserPB), + NKS(User1KB), + NKS(User2KB), + NKS(Video), + NKS(WheelButton), + NKS(Word), + NKS(Xfer), + NKS(ZoomIn), + NKS(ZoomOut), + NKS(Away), + NKS(Messenger), + NKS(WebCam), + NKS(MailForward), + NKS(Pictures), + NKS(Music), + NKS(Battery), + NKS(Bluetooth), + NKS(WLAN), + NKS(UWB), + NKS(AudioForward), + NKS(AudioRepeat), + NKS(AudioRandomPlay), + NKS(Subtitle), + NKS(AudioCycleTrack), + NKS(CycleAngle), + NKS(FrameBack), + NKS(FrameForward), + NKS(Time), + NKS(Select), + NKS(View), + NKS(TopMenu), + NKS(Red), + NKS(Green), + NKS(Yellow), + NKS(Blue), + NKS(Suspend), + NKS(Hibernate), + NKS(TouchpadToggle), + NKS(TouchpadOn), + NKS(TouchpadOff), + NKS(Switch_VT_1), + NKS(Switch_VT_2), + NKS(Switch_VT_3), + NKS(Switch_VT_4), + NKS(Switch_VT_5), + NKS(Switch_VT_6), + NKS(Switch_VT_7), + NKS(Switch_VT_8), + NKS(Switch_VT_9), + NKS(Switch_VT_10), + NKS(Switch_VT_11), + NKS(Switch_VT_12), + NKS(Ungrab), + NKS(ClearGrab), + NKS(Next_VMode), + NKS(Prev_VMode), + NKS(LogWindowTree), + NKS(LogGrabInfo), +#undef NKS +}; + +void grab(void) +{ + PUTS("grab"); + for (hotkey_t *hk = hotkeys; hk != NULL; hk = hk->next) { + xcb_keycode_t *keycodes = keycodes_from_keysym(hk->keysym); + if (keycodes != NULL) + for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++) + if (hk->keysym == xcb_key_symbols_get_keysym(symbols, *kc, 0)) { + PRINTF("keycode for %u is %u\n", hk->keysym, *kc); + grab_key(*kc, hk->modfield); + } + free(keycodes); + } +} + +void grab_key(xcb_keycode_t keycode, uint16_t modfield) +{ + grab_key_checked(keycode, modfield); + for (uint8_t i = 0; i < 8; i++) { + uint16_t lockfield = (i & 1 ? num_lock : 0) | (i & 2 ? caps_lock : 0) | (i & 4 ? scroll_lock : 0); + grab_key_checked(keycode, modfield | lockfield); + } +} + +void grab_key_checked(xcb_keycode_t keycode, uint16_t modfield) +{ + xcb_generic_error_t *err; + err = xcb_request_check(dpy, xcb_grab_key_checked(dpy, false, root, modfield, keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC)); + if (err != NULL) { + warn("Could not grab keycode %u with modfield %u: ", keycode, modfield); + if (err->error_code == XCB_ACCESS) + warn("the key combination is already grabbed.\n"); + else + warn("error no %u encountered.\n", err->error_code); + free(err); + } else { + PRINTF("grab key %u %u\n", keycode, modfield); + } +} + +void ungrab(void) +{ + PUTS("ungrab"); + xcb_ungrab_key(dpy, XCB_GRAB_ANY, root, XCB_BUTTON_MASK_ANY); +} + +int16_t modfield_from_keysym(xcb_keysym_t keysym) +{ + uint16_t modfield = 0; + xcb_keycode_t *keycodes = NULL, *mod_keycodes = NULL; + xcb_get_modifier_mapping_reply_t *reply = NULL; + if ((keycodes = keycodes_from_keysym(keysym)) != NULL) { + if ((reply = xcb_get_modifier_mapping_reply(dpy, xcb_get_modifier_mapping(dpy), NULL)) != NULL) { + if ((mod_keycodes = xcb_get_modifier_mapping_keycodes(reply)) != NULL) { + unsigned int num_mod = xcb_get_modifier_mapping_keycodes_length(reply) / reply->keycodes_per_modifier; + for (unsigned int i = 0; i < num_mod; i++) { + for (unsigned int j = 0; j < reply->keycodes_per_modifier; j++) { + xcb_keycode_t mk = mod_keycodes[i * reply->keycodes_per_modifier + j]; + if (mk == XCB_NO_SYMBOL) + continue; + for (xcb_keycode_t *k = keycodes; *k != XCB_NO_SYMBOL; k++) + if (*k == mk) + modfield |= (1 << i); + } + } + + } + } + } + free(keycodes); + free(reply); + return modfield; +} + +xcb_keycode_t *keycodes_from_keysym(xcb_keysym_t keysym) +{ + xcb_setup_t const *setup; + unsigned int num = 0; + xcb_keycode_t *result = NULL, *result_np = NULL; + + if ((setup = xcb_get_setup(dpy)) != NULL) { + xcb_keycode_t min_kc = setup->min_keycode; + xcb_keycode_t max_kc = setup->max_keycode; + /* We must choose a type for kc other than xcb_keycode_t whose size is 1, otherwise, since max_kc will most likely be 255, if kc == 255, kc++ would be 0 and the outer loop would start over ad infinitum */ + for(unsigned int kc = min_kc; kc <= max_kc; kc++) + for(unsigned int col = 0; col < KEYSYMS_PER_KEYCODE; col++) { + xcb_keysym_t ks = xcb_key_symbols_get_keysym(symbols, kc, col); + if (ks == keysym) { + num++; + result_np = realloc(result, sizeof(xcb_keycode_t) * (num + 1)); + if (result_np == NULL) { + free(result); + return NULL; + } + result = result_np; + result[num - 1] = kc; + result[num] = XCB_NO_SYMBOL; + break; + } + } + } + return result; +} + +bool parse_keysym(char *name, xcb_keysym_t *keysym) +{ + for (unsigned int i = 0; i < LENGTH(nks_dict); i++) { + keysym_dict_t nks = nks_dict[i]; + if (strcmp(name, nks.name) == 0) { + *keysym = nks.keysym; + return true; + } + } + return false; +} + +bool parse_modmask(char *name, uint16_t *modfield) +{ + if (strcmp(name, "shift") == 0) { + *modfield |= XCB_MOD_MASK_SHIFT; + return true; + } else if (strcmp(name, "control") == 0 || strcmp(name, "ctrl") == 0) { + *modfield |= XCB_MOD_MASK_CONTROL; + return true; + } else if (strcmp(name, "alt") == 0) { + *modfield |= (modfield_from_keysym(XK_Alt_L) | modfield_from_keysym(XK_Alt_R)); + return true; + } else if (strcmp(name, "super") == 0) { + *modfield |= (modfield_from_keysym(XK_Super_L) | modfield_from_keysym(XK_Super_R)); + return true; + } else if (strcmp(name, "hyper") == 0) { + *modfield |= (modfield_from_keysym(XK_Hyper_L) | modfield_from_keysym(XK_Hyper_R)); + return true; + } else if (strcmp(name, "meta") == 0) { + *modfield |= (modfield_from_keysym(XK_Meta_L) | modfield_from_keysym(XK_Meta_R)); + return true; + } else if (strcmp(name, "mode_switch") == 0) { + *modfield |= modfield_from_keysym(XK_Mode_switch); + return true; + } else if (strcmp(name, "mod1") == 0) { + *modfield |= XCB_MOD_MASK_1; + return true; + } else if (strcmp(name, "mod2") == 0) { + *modfield |= XCB_MOD_MASK_2; + return true; + } else if (strcmp(name, "mod3") == 0) { + *modfield |= XCB_MOD_MASK_3; + return true; + } else if (strcmp(name, "mod4") == 0) { + *modfield |= XCB_MOD_MASK_4; + return true; + } else if (strcmp(name, "mod5") == 0) { + *modfield |= XCB_MOD_MASK_5; + return true; + } else if (strcmp(name, "lock") == 0) { + *modfield |= XCB_MOD_MASK_LOCK; + return true; + } + return false; +} + +void get_lock_fields(void) +{ + num_lock = modfield_from_keysym(XK_Num_Lock); + caps_lock = XCB_MOD_MASK_LOCK; + scroll_lock = modfield_from_keysym(XK_Scroll_Lock); + PRINTF("lock fields %u %u %u\n", num_lock, caps_lock, scroll_lock); +} + +void generate_hotkeys(xcb_keysym_t keysym, uint16_t modfield, xcb_event_mask_t event_mask, char *command) +{ + xcb_keycode_t *keycodes = keycodes_from_keysym(keysym); + if (keycodes != NULL) + for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++) { + xcb_keysym_t natural_keysym = xcb_key_symbols_get_keysym(symbols, *kc, 0); + for (unsigned char col = 0; col < KEYSYMS_PER_KEYCODE; col++) { + xcb_keysym_t ks = xcb_key_symbols_get_keysym(symbols, *kc, col); + if (ks == keysym) { + uint16_t implicit_modfield = (col & 1 ? XCB_MOD_MASK_SHIFT : 0) | (col & 2 ? modfield_from_keysym(XK_Mode_switch) : 0); + uint16_t explicit_modfield = modfield | implicit_modfield; + hotkey_t *hk = make_hotkey(natural_keysym, explicit_modfield, event_mask, command); + add_hotkey(hk); + PRINTF("hotkey %u %u %u %s\n", natural_keysym, explicit_modfield, event_mask, command); + break; + } + } + } + free(keycodes); +} + +hotkey_t *make_hotkey(xcb_keysym_t keysym, uint16_t modfield, xcb_event_mask_t event_mask, char *command) +{ + hotkey_t *hk = malloc(sizeof(hotkey_t)); + hk->keysym = keysym; + hk->modfield = modfield; + hk->event_mask = event_mask; + strncpy(hk->command, command, sizeof(hk->command)); + hk->next = NULL; + return hk; +} + +hotkey_t *find_hotkey(xcb_keysym_t keysym, uint16_t modfield, xcb_event_mask_t event_mask) +{ + for (hotkey_t *hk = hotkeys; hk != NULL; hk = hk->next) + if (hk->keysym == keysym && hk->modfield == modfield && hk->event_mask == event_mask) + return hk; + return NULL; +} + +void add_hotkey(hotkey_t *hk) +{ + hk->next = hotkeys; + hotkeys = hk; +} diff --git a/keys.h b/keys.h @@ -0,0 +1,22 @@ +#ifndef _KEYS_H +#define _KEYS_H + +#include "sxhkd.h" + +#define KEYSYMS_PER_KEYCODE 4 + +void grab(void); +void grab_key(xcb_keycode_t, uint16_t); +void grab_key_checked(xcb_keycode_t, uint16_t); +void ungrab(void); +int16_t modfield_from_keysym(xcb_keysym_t); +xcb_keycode_t *keycodes_from_keysym(xcb_keysym_t); +bool parse_keysym(char *, xcb_keysym_t *); +bool parse_modmask(char *, uint16_t *); +void get_lock_fields(void); +void generate_hotkeys(xcb_keysym_t, uint16_t, xcb_event_mask_t, char *); +hotkey_t *make_hotkey(xcb_keysym_t, uint16_t, xcb_event_mask_t, char *); +hotkey_t *find_hotkey(xcb_keysym_t, uint16_t, xcb_event_mask_t); +void add_hotkey(hotkey_t *); + +#endif diff --git a/sxhkd.c b/sxhkd.c @@ -0,0 +1,240 @@ +#include <xcb/xcb_keysyms.h> +#include <xcb/xcb_event.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/select.h> +#include <ctype.h> +#include <getopt.h> +#include <signal.h> +#include <stdbool.h> +#include "helpers.h" +#include "keys.h" +#include "sxhkd.h" + +void hold(int sig) +{ + if (sig == SIGHUP || sig == SIGINT || sig == SIGTERM) + running = false; + else if (sig == SIGUSR1) + reload = true; +} + +void setup(void) +{ + dpy = xcb_connect(NULL, NULL); + if (xcb_connection_has_error(dpy)) + err("Can't open display.\n"); + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; + if (screen == NULL) + err("Can't acquire screen.\n"); + root = screen->root; + /* Makes key repeat events only send key press events */ + /* xcb_xkb_per_client_flags_reply_t *reply = xcb_xkb_per_client_flags_reply(dpy, xcb_xkb_per_client_flags(dpy, XCB_XKB_ID_USE_CORE_KBD, XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, 0, 0, 0), NULL); */ + /* if (reply == NULL) */ + /* warn("couldn't set detectable auto repeat\n"); */ + /* free(reply); */ + symbols = xcb_key_symbols_alloc(dpy); + hotkeys = NULL; +} + +void cleanup(void) +{ + hotkey_t *hk = hotkeys; + while (hk != NULL) { + hotkey_t *tmp = hk->next; + free(hk); + hk = tmp; + } +} + +void load_config(void) +{ + PUTS("load configuration"); + if (hotkeys != NULL) { + cleanup(); + hotkeys = NULL; + } + + char path[MAXLEN]; + if (config_file == NULL) + snprintf(path, sizeof(path), "%s/%s", getenv("XDG_CONFIG_HOME"), CONFIG_PATH); + else + strncpy(path, config_file, sizeof(path)); + + FILE *cfg = fopen(path, "r"); + if (cfg == NULL) + err("Can't open configuration file.\n"); + + char line[MAXLEN]; + xcb_keysym_t keysym = XCB_NO_SYMBOL; + uint16_t modfield = 0; + xcb_event_mask_t event_mask = XCB_KEY_PRESS; + + while (fgets(line, sizeof(line), cfg) != NULL) { + if (strlen(line) < 2 || line[0] == '#') { + continue; + } else if (isspace(line[0])) { + if (keysym == XCB_NO_SYMBOL) + continue; + unsigned int i = strlen(line) - 1; + while (i > 0 && isspace(line[i])) + line[i--] = '\0'; + i = 1; + while (i < strlen(line) && isspace(line[i])) + i++; + if (i < strlen(line)) { + char *command = line + i; + generate_hotkeys(keysym, modfield, event_mask, command); + } + keysym = XCB_NO_SYMBOL; + modfield = 0; + event_mask = XCB_KEY_PRESS; + } else { + char *name = strtok(line, TOK_SEP); + if (name == NULL) + continue; + do { + if (name[0] == '@') { + event_mask = XCB_KEY_RELEASE; + name++; + } + if (!parse_modmask(name, &modfield) && !parse_keysym(name, &keysym)) + warn("Unrecognized key name: '%s'.\n", name); + } while ((name = strtok(NULL, TOK_SEP)) != NULL); + } + } + + fclose(cfg); +} + +void mapping_notify(xcb_generic_event_t *evt) +{ + if (!running || reload) + return; + xcb_mapping_notify_event_t *e = (xcb_mapping_notify_event_t *) evt; + PRINTF("mapping notify %u %u\n", e->request, e->count); + if (e->request == XCB_MAPPING_KEYBOARD || e->request == XCB_MAPPING_MODIFIER) { + /* PUTS("refreshing everything"); */ + /* xcb_refresh_keyboard_mapping(symbols, e); */ + /* get_lock_fields(); */ + /* load_config(); */ + /* ungrab(); */ + /* grab(); */ + } +} + +void key_event(xcb_generic_event_t *evt, xcb_event_mask_t event_mask) +{ + xcb_keycode_t keycode = XCB_NO_SYMBOL; + uint16_t modfield = 0; + uint16_t lockfield = num_lock | caps_lock | scroll_lock; + if (event_mask == XCB_KEY_PRESS) { + xcb_key_press_event_t *e = (xcb_key_press_event_t *) evt; + keycode = e->detail; + modfield = e->state; + PRINTF("key press %u %u\n", keycode, modfield); + } else { + xcb_key_release_event_t *e = (xcb_key_release_event_t *) evt; + keycode = e->detail; + modfield = e->state; + PRINTF("key release %u %u\n", keycode, modfield); + } + xcb_keysym_t keysym = xcb_key_symbols_get_keysym(symbols, keycode, 0); + if (keysym != XCB_NO_SYMBOL) { + modfield &= ~lockfield; + hotkey_t *hk = find_hotkey(keysym, modfield, event_mask); + if (hk != NULL) { + char *cmd[] = {SHELL, "-c", hk->command, NULL}; + spawn(cmd); + } + } +} + +int main(int argc, char *argv[]) +{ + char opt; + config_file = NULL; + + while ((opt = getopt(argc, argv, "vhc:")) != -1) { + switch (opt) { + case 'v': + printf("%s\n", VERSION); + exit(EXIT_SUCCESS); + break; + case 'h': + printf("sxhkd [-h|-v|-c CONFIG_FILE]\n"); + exit(EXIT_SUCCESS); + break; + case 'c': + config_file = optarg; + break; + } + } + + signal(SIGINT, hold); + signal(SIGHUP, hold); + signal(SIGTERM, hold); + signal(SIGUSR1, hold); + + setup(); + get_lock_fields(); + load_config(); + grab(); + + xcb_generic_event_t *evt; + int fd = xcb_get_file_descriptor(dpy); + + fd_set descriptors; + + reload = false; + running = true; + + xcb_flush(dpy); + + while (running) { + FD_ZERO(&descriptors); + FD_SET(fd, &descriptors); + + if (select(fd + 1, &descriptors, NULL, NULL, NULL) > 0) { + while ((evt = xcb_poll_for_event(dpy)) != NULL) { + uint8_t event_mask = XCB_EVENT_RESPONSE_TYPE(evt); + switch (event_mask) { + case XCB_KEY_PRESS: + case XCB_KEY_RELEASE: + key_event(evt, event_mask); + break; + case XCB_MAPPING_NOTIFY: + mapping_notify(evt); + break; + default: + PRINTF("unknown event %u\n", event_mask); + break; + } + free(evt); + } + } + + if (reload) { + PUTS("reload configuration"); + signal(SIGUSR1, hold); + load_config(); + ungrab(); + grab(); + reload = false; + } + + if (xcb_connection_has_error(dpy)) { + warn("One of the previous requests failed.\n"); + running = false; + } + } + + ungrab(); + cleanup(); + xcb_key_symbols_free(symbols); + xcb_disconnect(dpy); + return EXIT_SUCCESS; +} diff --git a/sxhkd.h b/sxhkd.h @@ -0,0 +1,45 @@ +#ifndef _SXHKD_H +#define _SXHKD_H + +#include <xcb/xcb_keysyms.h> +#include <stdio.h> +#include <stdbool.h> +#include "helpers.h" + +#define CONFIG_PATH "sxhkd/sxhkdrc" +#define TOK_SEP "+ \n" +#define NUM_MOD 8 + +typedef struct hotkey_t hotkey_t; +struct hotkey_t { + xcb_keysym_t keysym; + uint16_t modfield; + xcb_event_mask_t event_mask; + char command[MAXLEN]; + hotkey_t *next; +}; + +typedef struct { + char *name; + xcb_keysym_t keysym; +} keysym_dict_t; + +xcb_connection_t *dpy; +xcb_window_t root; +xcb_key_symbols_t *symbols; +hotkey_t *hotkeys; +char *config_file; +bool running, reload; + +uint16_t num_lock; +uint16_t caps_lock; +uint16_t scroll_lock; + +void hold(int); +void setup(void); +void cleanup(void); +void load_config(void); +void mapping_notify(xcb_generic_event_t *); +void key_event(xcb_generic_event_t *, xcb_event_mask_t); + +#endif