commit e019134a31ad5f7acfa7774bb0167e770c0c1a14
Author: Bastien Dejean <nihilhill@gmail.com>
Date: Thu, 3 Jan 2013 18:26:10 +0100
First commit
Diffstat:
A | .gitignore | | | 3 | +++ |
A | LICENSE | | | 26 | ++++++++++++++++++++++++++ |
A | Makefile | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | README.md | | | 46 | ++++++++++++++++++++++++++++++++++++++++++++++ |
A | examples/sxhkdrc | | | 22 | ++++++++++++++++++++++ |
A | helpers.c | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
A | helpers.h | | | 21 | +++++++++++++++++++++ |
A | keys.c | | | 2557 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | keys.h | | | 22 | ++++++++++++++++++++++ |
A | sxhkd.c | | | 240 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | sxhkd.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