├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── Sourcedeps
├── VERSION
├── contrib
└── systemd
│ └── sxhkd.service
├── doc
├── sxhkd.1
└── sxhkd.1.asciidoc
├── examples
├── background_shell
│ ├── profile
│ ├── shell
│ ├── sxhkdrc
│ └── xinitrc
└── notification
│ ├── autostart
│ ├── pam_environment
│ ├── sxhkd_notify
│ └── xinitrc
└── src
├── grab.c
├── grab.h
├── helpers.c
├── helpers.h
├── locales.h
├── parse.c
├── parse.h
├── sxhkd.c
├── sxhkd.h
├── types.c
└── types.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | sxhkd
3 | tags
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Bastien Dejean
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | OUT = sxhkd
2 | VERCMD ?= git describe --tags 2> /dev/null
3 | VERSION := $(shell $(VERCMD) || cat VERSION)
4 |
5 | CPPFLAGS += -D_POSIX_C_SOURCE=200112L -DVERSION=\"$(VERSION)\"
6 | CFLAGS += -std=c99 -pedantic -Wall -Wextra
7 | LDFLAGS ?=
8 | LDLIBS = $(LDFLAGS) -lxcb -lxcb-keysyms
9 |
10 | PREFIX ?= /usr/local
11 | BINPREFIX ?= $(PREFIX)/bin
12 | MANPREFIX ?= $(PREFIX)/share/man
13 | DOCPREFIX ?= $(PREFIX)/share/doc/$(OUT)
14 |
15 | all: $(OUT)
16 |
17 | debug: CFLAGS += -O0 -g
18 | debug: CPPFLAGS += -DDEBUG
19 | debug: $(OUT)
20 |
21 | VPATH = src
22 | OBJ =
23 |
24 | include Sourcedeps
25 |
26 | $(OBJ): Makefile
27 |
28 | $(OUT): $(OBJ)
29 |
30 | install:
31 | mkdir -p "$(DESTDIR)$(BINPREFIX)"
32 | cp -pf $(OUT) "$(DESTDIR)$(BINPREFIX)"
33 | mkdir -p "$(DESTDIR)$(MANPREFIX)"/man1
34 | cp -p doc/$(OUT).1 "$(DESTDIR)$(MANPREFIX)"/man1
35 | mkdir -p "$(DESTDIR)$(DOCPREFIX)"
36 | cp -pr examples "$(DESTDIR)$(DOCPREFIX)"/examples
37 |
38 | uninstall:
39 | rm -f "$(DESTDIR)$(BINPREFIX)"/$(OUT)
40 | rm -f "$(DESTDIR)$(MANPREFIX)"/man1/$(OUT).1
41 | rm -rf "$(DESTDIR)$(DOCPREFIX)"
42 |
43 | doc:
44 | a2x -v -d manpage -f manpage -a revnumber=$(VERSION) doc/$(OUT).1.asciidoc
45 |
46 | clean:
47 | rm -f $(OBJ) $(OUT)
48 |
49 | .PHONY: all debug install uninstall doc clean
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | *sxhkd* is an X daemon that reacts to input events by executing commands.
4 |
5 | Its configuration file is a series of bindings that define the associations between the input events and the commands.
6 |
7 | The format of the configuration file supports a simple notation for mapping multiple shortcuts to multiple commands in parallel.
8 |
9 | ## Example Bindings
10 |
11 | XF86Audio{Prev,Next}
12 | mpc -q {prev,next}
13 |
14 | @XF86LaunchA
15 | scrot -s -e 'image_viewer $f'
16 |
17 | super + shift + equal
18 | sxiv -rt "$HOME/image"
19 |
20 | XF86LaunchB
21 | xdotool selectwindow | xsel -bi
22 |
23 | super + {h,j,k,l}
24 | bspc node -f {west,south,north,east}
25 |
26 | super + alt + {0-9}
27 | mpc -q seek {0-9}0%
28 |
29 | super + {alt,ctrl,alt + ctrl} + XF86Eject
30 | sudo systemctl {suspend,reboot,poweroff}
31 |
32 | super + {_,shift + }{h,j,k,l}
33 | bspc node -{f,s} {west,south,north,east}
34 |
35 | {_,shift + ,super + }XF86MonBrightness{Down,Up}
36 | bright {-1,-10,min,+1,+10,max}
37 |
38 | super + o ; {e,w,m}
39 | {gvim,firefox,thunderbird}
40 |
41 | super + alt + control + {h,j,k,l} ; {0-9}
42 | bspc node @{west,south,north,east} -r 0.{0-9}
43 |
44 | super + alt + p
45 | bspc config focus_follows_pointer {true,false}
46 |
47 | # Smart resize, will grow or shrink depending on location.
48 | # Will always grow for floating nodes.
49 | super + ctrl + alt + {Left,Down,Up,Right}
50 | n=10; \
51 | { d1=left; d2=right; dx=-$n; dy=0; \
52 | , d1=bottom; d2=top; dx=0; dy=$n; \
53 | , d1=top; d2=bottom; dx=0; dy=-$n; \
54 | , d1=right; d2=left; dx=$n; dy=0; \
55 | } \
56 | bspc node --resize $d1 $dx $dy || bspc node --resize $d2 $dx $dy
57 |
58 | ## Editor Plugins
59 |
60 | ### Vim
61 | - [vim-sxhkdrc](https://github.com/baskerville/vim-sxhkdrc).
62 | - [sxhkd-vim](https://github.com/kovetskiy/sxhkd-vim).
63 |
64 | ### VS Code
65 | - [sxhkdrc-syntax](https://github.com/mosbasik/sxhkdrc-syntax).
66 |
67 | ### Emacs
68 | - [sxhkd-mode](https://github.com/xFA25E/sxhkd-mode)
69 |
70 | ----
71 |
72 | For further information, check the `man` pages.
73 |
--------------------------------------------------------------------------------
/Sourcedeps:
--------------------------------------------------------------------------------
1 | grab.o: grab.c grab.h helpers.h parse.h sxhkd.h types.h
2 | OBJ += grab.o
3 | helpers.o: helpers.c helpers.h sxhkd.h types.h
4 | OBJ += helpers.o
5 | parse.o: parse.c helpers.h locales.h parse.h sxhkd.h types.h
6 | OBJ += parse.o
7 | sxhkd.o: sxhkd.c grab.h helpers.h parse.h sxhkd.h types.h
8 | OBJ += sxhkd.o
9 | types.o: types.c grab.h helpers.h parse.h sxhkd.h types.h
10 | OBJ += types.o
11 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 0.6.2
--------------------------------------------------------------------------------
/contrib/systemd/sxhkd.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Simple X Hotkey Daemon
3 | Documentation=man:sxhkd(1)
4 | BindsTo=display-manager.service
5 | After=display-manager.service
6 |
7 | [Service]
8 | ExecStart=/usr/bin/sxhkd
9 | ExecReload=/usr/bin/kill -SIGUSR1 $MAINPID
10 |
11 | [Install]
12 | WantedBy=graphical.target
13 |
--------------------------------------------------------------------------------
/doc/sxhkd.1:
--------------------------------------------------------------------------------
1 | '\" t
2 | .\" Title: sxhkd
3 | .\" Author: [see the "Author" section]
4 | .\" Generator: DocBook XSL Stylesheets vsnapshot
5 | .\" Date: 11/19/2022
6 | .\" Manual: Sxhkd Manual
7 | .\" Source: Sxhkd 0.6.2-3-g56d3377
8 | .\" Language: English
9 | .\"
10 | .TH "SXHKD" "1" "11/19/2022" "Sxhkd 0\&.6\&.2\-3\-g56d3377" "Sxhkd Manual"
11 | .\" -----------------------------------------------------------------
12 | .\" * Define some portability stuff
13 | .\" -----------------------------------------------------------------
14 | .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15 | .\" http://bugs.debian.org/507673
16 | .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
17 | .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 | .ie \n(.g .ds Aq \(aq
19 | .el .ds Aq '
20 | .\" -----------------------------------------------------------------
21 | .\" * set default formatting
22 | .\" -----------------------------------------------------------------
23 | .\" disable hyphenation
24 | .nh
25 | .\" disable justification (adjust text to left margin only)
26 | .ad l
27 | .\" -----------------------------------------------------------------
28 | .\" * MAIN CONTENT STARTS HERE *
29 | .\" -----------------------------------------------------------------
30 | .SH "NAME"
31 | sxhkd \- Simple X hotkey daemon
32 | .SH "SYNOPSIS"
33 | .sp
34 | \fBsxhkd\fR [\fIOPTIONS\fR] [\fIEXTRA_CONFIG\fR \&...]
35 | .SH "DESCRIPTION"
36 | .sp
37 | sxhkd is a simple X hotkey daemon with a powerful and compact configuration syntax\&.
38 | .SH "OPTIONS"
39 | .PP
40 | \fB\-h\fR
41 | .RS 4
42 | Print the synopsis to standard output and exit\&.
43 | .RE
44 | .PP
45 | \fB\-v\fR
46 | .RS 4
47 | Print the version information to standard output and exit\&.
48 | .RE
49 | .PP
50 | \fB\-m\fR \fICOUNT\fR
51 | .RS 4
52 | Handle the first
53 | \fICOUNT\fR
54 | mapping notify events\&.
55 | .RE
56 | .PP
57 | \fB\-t\fR \fITIMEOUT\fR
58 | .RS 4
59 | Timeout in seconds for the recording of chord chains\&.
60 | .RE
61 | .PP
62 | \fB\-c\fR \fICONFIG_FILE\fR
63 | .RS 4
64 | Read the main configuration from the given file\&.
65 | .RE
66 | .PP
67 | \fB\-r\fR \fIREDIR_FILE\fR
68 | .RS 4
69 | Redirect the commands output to the given file\&.
70 | .RE
71 | .PP
72 | \fB\-s\fR \fISTATUS_FIFO\fR
73 | .RS 4
74 | Output status information to the given FIFO\&.
75 | .RE
76 | .PP
77 | \fB\-a\fR \fIABORT_KEYSYM\fR
78 | .RS 4
79 | Name of the keysym used for aborting chord chains\&.
80 | .RE
81 | .SH "BEHAVIOR"
82 | .sp
83 | \fBsxhkd\fR is a daemon that listens to keyboard events and execute commands\&.
84 | .sp
85 | It reads its configuration file from \fB$XDG_CONFIG_HOME/sxhkd/sxhkdrc\fR by default, or from the given file if the \fB\-c\fR option is used\&.
86 | .sp
87 | Additional configuration files can be passed as arguments\&.
88 | .sp
89 | If \fBsxhkd\fR receives a \fISIGUSR1\fR (resp\&. \fISIGUSR2\fR) signal, it will reload its configuration file (resp\&. toggle the grabbing state of all its bindings)\&.
90 | .sp
91 | If \fBsxhkd\fR recieves a \fISIGALRM\fR signal, it will break the current chain if there is one in progress\&.
92 | .sp
93 | The commands are executed via \fBSHELL\fR \fI\-c\fR \fBCOMMAND\fR (hence you can use environment variables)\&.
94 | .sp
95 | \fBSHELL\fR will be the content of the first defined environment variable in the following list: \fBSXHKD_SHELL\fR, \fBSHELL\fR\&.
96 | .sp
97 | \fBSXHKD_PID\fR will be automatically set to the pid of \fBsxhkd\fR in processes spawned by \fBsxhkd\fR, which may be used by the child process to send easily signals such as \fISIGALRM\fR to the correct instance of \fBsxhkd\fR\&.
98 | .sp
99 | If you have a non\-QWERTY keyboard or a non\-standard layout configuration, you should provide a \fICOUNT\fR of \fI1\fR to the \fB\-m\fR option or \fI\-1\fR (interpreted as infinity) if you constantly switch from one layout to the other (\fBsxhkd\fR ignores all mapping notify events by default because the majority of those events are pointless)\&.
100 | .SH "CONFIGURATION"
101 | .sp
102 | Each line of the configuration file is interpreted as so:
103 | .sp
104 | .RS 4
105 | .ie n \{\
106 | \h'-04'\(bu\h'+03'\c
107 | .\}
108 | .el \{\
109 | .sp -1
110 | .IP \(bu 2.3
111 | .\}
112 | If it is empty or starts with
113 | #, it is ignored\&.
114 | .RE
115 | .sp
116 | .RS 4
117 | .ie n \{\
118 | \h'-04'\(bu\h'+03'\c
119 | .\}
120 | .el \{\
121 | .sp -1
122 | .IP \(bu 2.3
123 | .\}
124 | If it starts with a space, it is read as a command\&.
125 | .RE
126 | .sp
127 | .RS 4
128 | .ie n \{\
129 | \h'-04'\(bu\h'+03'\c
130 | .\}
131 | .el \{\
132 | .sp -1
133 | .IP \(bu 2.3
134 | .\}
135 | Otherwise, it is read as a hotkey\&.
136 | .RE
137 | .sp
138 | General syntax:
139 | .sp
140 | .if n \{\
141 | .RS 4
142 | .\}
143 | .nf
144 | HOTKEY
145 | [;]COMMAND
146 |
147 | HOTKEY := CHORD_1 ; CHORD_2 ; \&... ; CHORD_n
148 | CHORD_i := [MODIFIERS_i +] [~][@]KEYSYM_i
149 | MODIFIERS_i := MODIFIER_i1 + MODIFIER_i2 + \&... + MODIFIER_ik
150 | .fi
151 | .if n \{\
152 | .RE
153 | .\}
154 | .sp
155 | The valid modifier names are: \fIsuper\fR, \fIhyper\fR, \fImeta\fR, \fIalt\fR, \fIcontrol\fR, \fIctrl\fR, \fIshift\fR, \fImode_switch\fR, \fIlock\fR, \fImod1\fR, \fImod2\fR, \fImod3\fR, \fImod4\fR, \fImod5\fR and \fIany\fR\&.
156 | .sp
157 | The keysym names are given by the output of \fBxev \-event keyboard\fR\&.
158 | .sp
159 | Hotkeys and commands can be spread across multiple lines by ending each partial line with a backslash character\&.
160 | .sp
161 | When multiple chords are separated by semicolons, the hotkey is a chord chain: the command will only be executed after receiving each chord of the chain in consecutive order\&.
162 | .sp
163 | The colon character can be used instead of the semicolon to indicate that the chord chain shall not be aborted when the chain tail is reached\&.
164 | .sp
165 | If a command starts with a semicolon, it will be executed synchronously, otherwise asynchronously\&.
166 | .sp
167 | The \fIEscape\fR key can be used to abort a chord chain\&.
168 | .sp
169 | If \fB@\fR is added at the beginning of the keysym, the command will be run on key release events, otherwise on key press events\&.
170 | .sp
171 | If \fB~\fR is added at the beginning of the keysym, the captured event will be replayed for the other clients\&.
172 | .sp
173 | Pointer hotkeys can be defined by using one of the following special keysym names: \fIbutton1\fR, \fIbutton2\fR, \fIbutton3\fR, \&..., \fIbutton24\fR\&.
174 | .sp
175 | The hotkey and the command may contain sequences of the form \fI{STRING_1,\&...,STRING_N}\fR\&. Braces can be escaped with \fB\e\fR\&.
176 | .sp
177 | In addition, the sequences can contain ranges of the form \fIA\fR\-\fIZ\fR where \fIA\fR and \fIZ\fR are alphanumeric characters\&.
178 | .sp
179 | The underscore character represents an empty sequence element\&.
180 | .SH "AUTHOR"
181 | .sp
182 | Bastien Dejean
183 | .SH "MAILING LIST"
184 | .sp
185 | sxhkd at librelist\&.com
186 |
--------------------------------------------------------------------------------
/doc/sxhkd.1.asciidoc:
--------------------------------------------------------------------------------
1 | :man source: Sxhkd
2 | :man version: {revnumber}
3 | :man manual: Sxhkd Manual
4 |
5 | sxhkd(1)
6 | ========
7 |
8 | Name
9 | ----
10 |
11 | sxhkd - Simple X hotkey daemon
12 |
13 | Synopsis
14 | --------
15 |
16 | *sxhkd* [_OPTIONS_] [_EXTRA_CONFIG_ …]
17 |
18 | Description
19 | -----------
20 |
21 | sxhkd is a simple X hotkey daemon with a powerful and compact configuration syntax.
22 |
23 | Options
24 | -------
25 |
26 |
27 | *-h*::
28 | Print the synopsis to standard output and exit.
29 |
30 | *-v*::
31 | Print the version information to standard output and exit.
32 |
33 | *-m* _COUNT_::
34 | Handle the first _COUNT_ mapping notify events.
35 |
36 | *-t* _TIMEOUT_::
37 | Timeout in seconds for the recording of chord chains.
38 |
39 | *-c* _CONFIG_FILE_::
40 | Read the main configuration from the given file.
41 |
42 | *-r* _REDIR_FILE_::
43 | Redirect the commands output to the given file.
44 |
45 | *-s* _STATUS_FIFO_::
46 | Output status information to the given FIFO.
47 |
48 | *-a* _ABORT_KEYSYM_::
49 | Name of the keysym used for aborting chord chains.
50 |
51 |
52 | Behavior
53 | --------
54 |
55 | *sxhkd* is a daemon that listens to keyboard events and execute commands.
56 |
57 | It reads its configuration file from *$XDG_CONFIG_HOME/sxhkd/sxhkdrc* by default, or from the given file if the *-c* option is used.
58 |
59 | Additional configuration files can be passed as arguments.
60 |
61 | If *sxhkd* receives a _SIGUSR1_ (resp. _SIGUSR2_) signal, it will reload its configuration file (resp. toggle the grabbing state of all its bindings).
62 |
63 | If *sxhkd* recieves a _SIGALRM_ signal, it will break the current chain if there is one in progress.
64 |
65 | The commands are executed via *SHELL* _-c_ *COMMAND* (hence you can use environment variables).
66 |
67 | *SHELL* will be the content of the first defined environment variable in the following list: *SXHKD_SHELL*, *SHELL*.
68 |
69 | *SXHKD_PID* will be automatically set to the pid of *sxhkd* in processes spawned by *sxhkd*, which may be used by the child process to send easily signals such as _SIGALRM_ to the correct instance of *sxhkd*.
70 |
71 | If you have a non-QWERTY keyboard or a non-standard layout configuration, you should provide a _COUNT_ of _1_ to the *-m* option or _-1_ (interpreted as infinity) if you constantly switch from one layout to the other (*sxhkd* ignores all mapping notify events by default because the majority of those events are pointless).
72 |
73 |
74 | Configuration
75 | -------------
76 |
77 | Each line of the configuration file is interpreted as so:
78 |
79 | * If it is empty or starts with `#`, it is ignored.
80 | * If it starts with a space, it is read as a command.
81 | * Otherwise, it is read as a hotkey.
82 |
83 | General syntax:
84 |
85 | ----
86 | HOTKEY
87 | [;]COMMAND
88 |
89 | HOTKEY := CHORD_1 ; CHORD_2 ; … ; CHORD_n
90 | CHORD_i := [MODIFIERS_i +] [~][@]KEYSYM_i
91 | MODIFIERS_i := MODIFIER_i1 + MODIFIER_i2 + … + MODIFIER_ik
92 | ----
93 |
94 | The valid modifier names are: _super_, _hyper_, _meta_, _alt_, _control_, _ctrl_, _shift_, _mode_switch_, _lock_, _mod1_, _mod2_, _mod3_, _mod4_, _mod5_ and _any_.
95 |
96 | The keysym names are given by the output of *xev -event keyboard*.
97 |
98 | Hotkeys and commands can be spread across multiple lines by ending each partial line with a backslash character.
99 |
100 | When multiple chords are separated by semicolons, the hotkey is a chord chain: the command will only be executed after receiving each chord of the chain in consecutive order.
101 |
102 | The colon character can be used instead of the semicolon to indicate that the chord chain shall not be aborted when the chain tail is reached.
103 |
104 | If a command starts with a semicolon, it will be executed synchronously, otherwise asynchronously.
105 |
106 | The _Escape_ key can be used to abort a chord chain.
107 |
108 | If *@* is added at the beginning of the keysym, the command will be run on key release events, otherwise on key press events.
109 |
110 | If *~* is added at the beginning of the keysym, the captured event will be replayed for the other clients.
111 |
112 | Pointer hotkeys can be defined by using one of the following special keysym names: _button1_, _button2_, _button3_, …, _button24_.
113 |
114 | The hotkey and the command may contain sequences of the form '{STRING_1,…,STRING_N}'. Braces can be escaped with *\*.
115 |
116 | In addition, the sequences can contain ranges of the form _A_-_Z_ where _A_ and _Z_ are alphanumeric characters.
117 |
118 | The underscore character represents an empty sequence element.
119 |
120 | Author
121 | ------
122 |
123 | Bastien Dejean
124 |
125 | Mailing List
126 | ------------
127 |
128 | sxhkd at librelist.com
129 |
130 | ////
131 | vim: set ft=asciidoc:
132 | ////
133 |
--------------------------------------------------------------------------------
/examples/background_shell/profile:
--------------------------------------------------------------------------------
1 | export SXHKD_SHELL=shell
2 |
--------------------------------------------------------------------------------
/examples/background_shell/shell:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | printf "(%s)&\n" "$2" | tmux load-buffer -
4 | tmux paste-buffer -t sxhkd
5 |
--------------------------------------------------------------------------------
/examples/background_shell/sxhkdrc:
--------------------------------------------------------------------------------
1 | # Reload functions
2 | super + Escape
3 | "$XDG_CONFIG_HOME"/sxhkd/functions
4 |
--------------------------------------------------------------------------------
/examples/background_shell/xinitrc:
--------------------------------------------------------------------------------
1 | if ! tmux has-session -t sxhkd 2> /dev/null ; then
2 | tmux new-session -s sxhkd -d
3 | printf '%s\n' '. "$XDG_CONFIG_HOME"/sxhkd/functions' | tmux load-buffer -
4 | tmux paste-buffer -t sxhkd
5 | fi
6 |
--------------------------------------------------------------------------------
/examples/notification/autostart:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | sxhkd_notify "$SXHKD_FIFO" &
4 |
--------------------------------------------------------------------------------
/examples/notification/pam_environment:
--------------------------------------------------------------------------------
1 | SXHKD_FIFO=/tmp/sxhkd-fifo
2 |
--------------------------------------------------------------------------------
/examples/notification/sxhkd_notify:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | [ $# -ne 1 ] && exit 1
4 |
5 | status_fifo=$1
6 |
7 | { while read -r line ; do
8 | msg=${line#?}
9 | case $line in
10 | H*)
11 | duration=2
12 | ;;
13 | C*)
14 | duration=4
15 | ;;
16 | T*)
17 | duration=1
18 | ;;
19 | esac
20 | notify-send -t $duration "$msg"
21 | done } < "$status_fifo"
22 |
--------------------------------------------------------------------------------
/examples/notification/xinitrc:
--------------------------------------------------------------------------------
1 | [ -e "$SXHKD_FIFO" ] && rm "$SXHKD_FIFO"
2 | mkfifo "$SXHKD_FIFO"
3 | sxhkd -s "$SXHKD_FIFO" &
4 |
--------------------------------------------------------------------------------
/src/grab.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #include
26 | #include
27 | #include "parse.h"
28 | #include "grab.h"
29 |
30 | void grab(void)
31 | {
32 | PUTS("grab");
33 | for (hotkey_t *hk = hotkeys_head; hk != NULL; hk = hk->next)
34 | grab_chord(hk->chain->head);
35 | xcb_flush(dpy);
36 | grabbed = true;
37 | }
38 |
39 | void grab_chord(chord_t *chord)
40 | {
41 | for (chord_t *c = chord; c != NULL; c = c->more) {
42 | if (c->button == XCB_NONE) {
43 | xcb_keycode_t *keycodes = keycodes_from_keysym(c->keysym);
44 | if (keycodes != NULL)
45 | for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++)
46 | if (c->keysym == xcb_key_symbols_get_keysym(symbols, *kc, 0))
47 | grab_key_button(*kc, c->button, c->modfield);
48 | free(keycodes);
49 | } else {
50 | grab_key_button(XCB_NONE, c->button, c->modfield);
51 | }
52 | }
53 | }
54 |
55 | void grab_key_button(xcb_keycode_t keycode, xcb_button_t button, uint16_t modfield)
56 | {
57 | grab_key_button_checked(keycode, button, modfield);
58 | if (modfield == XCB_MOD_MASK_ANY)
59 | return;
60 | if (num_lock != 0)
61 | grab_key_button_checked(keycode, button, modfield | num_lock);
62 | if (caps_lock != 0)
63 | grab_key_button_checked(keycode, button, modfield | caps_lock);
64 | if (scroll_lock != 0)
65 | grab_key_button_checked(keycode, button, modfield | scroll_lock);
66 | if (num_lock != 0 && caps_lock != 0)
67 | grab_key_button_checked(keycode, button, modfield | num_lock | caps_lock);
68 | if (caps_lock != 0 && scroll_lock != 0)
69 | grab_key_button_checked(keycode, button, modfield | caps_lock | scroll_lock);
70 | if (num_lock != 0 && scroll_lock != 0)
71 | grab_key_button_checked(keycode, button, modfield | num_lock | scroll_lock);
72 | if (num_lock != 0 && caps_lock != 0 && scroll_lock != 0)
73 | grab_key_button_checked(keycode, button, modfield | num_lock | caps_lock | scroll_lock);
74 | }
75 |
76 | void grab_key_button_checked(xcb_keycode_t keycode, xcb_button_t button, uint16_t modfield)
77 | {
78 | xcb_generic_error_t *err;
79 | if (button == XCB_NONE)
80 | err = xcb_request_check(dpy, xcb_grab_key_checked(dpy, true, root, modfield, keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC));
81 | else
82 | err = xcb_request_check(dpy, xcb_grab_button_checked(dpy, true, root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, button, modfield));
83 | unsigned int value = (button == XCB_NONE ? keycode : button);
84 | char *type = (button == XCB_NONE ? "key" : "button");
85 | if (err != NULL) {
86 | warn("Could not grab %s %u with modfield %u: ", type, value, modfield);
87 | if (err->error_code == XCB_ACCESS)
88 | warn("the combination is already grabbed.\n");
89 | else
90 | warn("error %u encountered.\n", err->error_code);
91 | free(err);
92 | } else {
93 | PRINTF("grab %s %u %u\n", type, value, modfield);
94 | }
95 | }
96 |
97 | void ungrab(void)
98 | {
99 | PUTS("ungrab");
100 | xcb_ungrab_key(dpy, XCB_GRAB_ANY, root, XCB_BUTTON_MASK_ANY);
101 | xcb_ungrab_button(dpy, XCB_BUTTON_INDEX_ANY, root, XCB_MOD_MASK_ANY);
102 | xcb_flush(dpy);
103 | grabbed = false;
104 | }
105 |
--------------------------------------------------------------------------------
/src/grab.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #ifndef SXHKD_GRAB_H
26 | #define SXHKD_GRAB_H
27 |
28 | #include "sxhkd.h"
29 |
30 | void grab(void);
31 | void grab_chord(chord_t *chord);
32 | void grab_key_button(xcb_keycode_t keycode, xcb_button_t button, uint16_t modfield);
33 | void grab_key_button_checked(xcb_keycode_t keycode, xcb_button_t button, uint16_t modfield);
34 | void ungrab(void);
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/src/helpers.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include "sxhkd.h"
34 |
35 | void warn(char *fmt, ...)
36 | {
37 | va_list ap;
38 | va_start(ap, fmt);
39 | vfprintf(stderr, fmt, ap);
40 | va_end(ap);
41 | }
42 |
43 | __attribute__((noreturn))
44 | void err(char *fmt, ...)
45 | {
46 | va_list ap;
47 | va_start(ap, fmt);
48 | vfprintf(stderr, fmt, ap);
49 | va_end(ap);
50 | exit(EXIT_FAILURE);
51 | }
52 |
53 | void run(char *command, bool sync)
54 | {
55 | char *cmd[] = {shell, "-c", command, NULL};
56 | spawn(cmd, sync);
57 | }
58 |
59 | void spawn(char *cmd[], bool sync)
60 | {
61 | if (fork() == 0) {
62 | if (dpy != NULL)
63 | close(xcb_get_file_descriptor(dpy));
64 | if (sync) {
65 | execute(cmd);
66 | } else {
67 | if (fork() == 0) {
68 | execute(cmd);
69 | }
70 | exit(EXIT_SUCCESS);
71 | }
72 | }
73 | wait(NULL);
74 | }
75 |
76 | void execute(char *cmd[])
77 | {
78 | setsid();
79 | if (redir_fd != -1) {
80 | dup2(redir_fd, STDOUT_FILENO);
81 | dup2(redir_fd, STDERR_FILENO);
82 | }
83 | execvp(cmd[0], cmd);
84 | err("Spawning failed.\n");
85 | }
86 |
87 | char *lgraph(char *s)
88 | {
89 | size_t len = strlen(s);
90 | unsigned int i = 0;
91 | while (i < len && !isgraph(s[i]))
92 | i++;
93 | if (i < len)
94 | return (s + i);
95 | else
96 | return NULL;
97 | }
98 |
99 | char *rgraph(char *s)
100 | {
101 | int i = strlen(s) - 1;
102 | while (i >= 0 && !isgraph(s[i]))
103 | i--;
104 | if (i >= 0)
105 | return (s + i);
106 | else
107 | return NULL;
108 | }
109 |
--------------------------------------------------------------------------------
/src/helpers.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #ifndef SXHKD_HELPERS_H
26 | #define SXHKD_HELPERS_H
27 |
28 | #define LENGTH(x) (sizeof(x) / sizeof(*x))
29 | #define MAXLEN 256
30 |
31 | #ifdef DEBUG
32 | # define PUTS(x) puts(x)
33 | # define PRINTF(x,...) printf(x, __VA_ARGS__)
34 | #else
35 | # define PUTS(x) ((void)0)
36 | # define PRINTF(x,...) ((void)0)
37 | #endif
38 |
39 | void warn(char *fmt, ...);
40 | __attribute__((noreturn))
41 | void err(char *fmt, ...);
42 | void execute(char *cmd[]);
43 | void spawn(char *cmd[], bool sync);
44 | void run(char *command, bool sync);
45 | char *lgraph(char *s);
46 | char *rgraph(char *s);
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/src/locales.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #ifndef SXHKD_LOCALES_H
26 | #define SXHKD_LOCALES_H
27 |
28 | #define XK_MISCELLANY
29 | #define XK_XKB_KEYS
30 | #define XK_XFREE86
31 | #define XK_LATIN1
32 | #define XK_LATIN2
33 | #define XK_LATIN3
34 | #define XK_LATIN4
35 | #define XK_LATIN8
36 | #define XK_LATIN9
37 | #define XK_CAUCASUS
38 | #define XK_GREEK
39 | #define XK_KATAKANA
40 | #define XK_ARABIC
41 | #define XK_CYRILLIC
42 | #define XK_HEBREW
43 | #define XK_THAI
44 | #define XK_KOREAN
45 | #define XK_ARMENIAN
46 | #define XK_GEORGIAN
47 | #define XK_VIETNAMESE
48 | #define XK_CURRENCY
49 | #define XK_MATHEMATICAL
50 | #define XK_BRAILLE
51 | #define XK_SINHALA
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/src/parse.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include "locales.h"
33 | #include "parse.h"
34 |
35 | xcb_keysym_t Alt_L, Alt_R, Super_L, Super_R, Hyper_L, Hyper_R,
36 | Meta_L, Meta_R, Mode_switch, Num_Lock, Scroll_Lock;
37 |
38 | keysym_dict_t nks_dict[] = {/*{{{*/
39 | {"VoidSymbol" , 0xffffff} ,
40 | #ifdef XK_MISCELLANY
41 | {"BackSpace" , 0xff08} ,
42 | {"Tab" , 0xff09} ,
43 | {"Linefeed" , 0xff0a} ,
44 | {"Clear" , 0xff0b} ,
45 | {"Return" , 0xff0d} ,
46 | {"Pause" , 0xff13} ,
47 | {"Scroll_Lock" , 0xff14} ,
48 | {"Sys_Req" , 0xff15} ,
49 | {"Escape" , 0xff1b} ,
50 | {"Delete" , 0xffff} ,
51 | {"Multi_key" , 0xff20} ,
52 | {"Codeinput" , 0xff37} ,
53 | {"SingleCandidate" , 0xff3c} ,
54 | {"MultipleCandidate" , 0xff3d} ,
55 | {"PreviousCandidate" , 0xff3e} ,
56 | {"Kanji" , 0xff21} ,
57 | {"Muhenkan" , 0xff22} ,
58 | {"Henkan_Mode" , 0xff23} ,
59 | {"Henkan" , 0xff23} ,
60 | {"Romaji" , 0xff24} ,
61 | {"Hiragana" , 0xff25} ,
62 | {"Katakana" , 0xff26} ,
63 | {"Hiragana_Katakana" , 0xff27} ,
64 | {"Zenkaku" , 0xff28} ,
65 | {"Hankaku" , 0xff29} ,
66 | {"Zenkaku_Hankaku" , 0xff2a} ,
67 | {"Touroku" , 0xff2b} ,
68 | {"Massyo" , 0xff2c} ,
69 | {"Kana_Lock" , 0xff2d} ,
70 | {"Kana_Shift" , 0xff2e} ,
71 | {"Eisu_Shift" , 0xff2f} ,
72 | {"Eisu_toggle" , 0xff30} ,
73 | {"Kanji_Bangou" , 0xff37} ,
74 | {"Zen_Koho" , 0xff3d} ,
75 | {"Mae_Koho" , 0xff3e} ,
76 | {"Home" , 0xff50} ,
77 | {"Left" , 0xff51} ,
78 | {"Up" , 0xff52} ,
79 | {"Right" , 0xff53} ,
80 | {"Down" , 0xff54} ,
81 | {"Prior" , 0xff55} ,
82 | {"Page_Up" , 0xff55} ,
83 | {"Next" , 0xff56} ,
84 | {"Page_Down" , 0xff56} ,
85 | {"End" , 0xff57} ,
86 | {"Begin" , 0xff58} ,
87 | {"Select" , 0xff60} ,
88 | {"Print" , 0xff61} ,
89 | {"Execute" , 0xff62} ,
90 | {"Insert" , 0xff63} ,
91 | {"Undo" , 0xff65} ,
92 | {"Redo" , 0xff66} ,
93 | {"Menu" , 0xff67} ,
94 | {"Find" , 0xff68} ,
95 | {"Cancel" , 0xff69} ,
96 | {"Help" , 0xff6a} ,
97 | {"Break" , 0xff6b} ,
98 | {"Mode_switch" , 0xff7e} ,
99 | {"script_switch" , 0xff7e} ,
100 | {"Num_Lock" , 0xff7f} ,
101 | {"KP_Space" , 0xff80} ,
102 | {"KP_Tab" , 0xff89} ,
103 | {"KP_Enter" , 0xff8d} ,
104 | {"KP_F1" , 0xff91} ,
105 | {"KP_F2" , 0xff92} ,
106 | {"KP_F3" , 0xff93} ,
107 | {"KP_F4" , 0xff94} ,
108 | {"KP_Home" , 0xff95} ,
109 | {"KP_Left" , 0xff96} ,
110 | {"KP_Up" , 0xff97} ,
111 | {"KP_Right" , 0xff98} ,
112 | {"KP_Down" , 0xff99} ,
113 | {"KP_Prior" , 0xff9a} ,
114 | {"KP_Page_Up" , 0xff9a} ,
115 | {"KP_Next" , 0xff9b} ,
116 | {"KP_Page_Down" , 0xff9b} ,
117 | {"KP_End" , 0xff9c} ,
118 | {"KP_Begin" , 0xff9d} ,
119 | {"KP_Insert" , 0xff9e} ,
120 | {"KP_Delete" , 0xff9f} ,
121 | {"KP_Equal" , 0xffbd} ,
122 | {"KP_Multiply" , 0xffaa} ,
123 | {"KP_Add" , 0xffab} ,
124 | {"KP_Separator" , 0xffac} ,
125 | {"KP_Subtract" , 0xffad} ,
126 | {"KP_Decimal" , 0xffae} ,
127 | {"KP_Divide" , 0xffaf} ,
128 | {"KP_0" , 0xffb0} ,
129 | {"KP_1" , 0xffb1} ,
130 | {"KP_2" , 0xffb2} ,
131 | {"KP_3" , 0xffb3} ,
132 | {"KP_4" , 0xffb4} ,
133 | {"KP_5" , 0xffb5} ,
134 | {"KP_6" , 0xffb6} ,
135 | {"KP_7" , 0xffb7} ,
136 | {"KP_8" , 0xffb8} ,
137 | {"KP_9" , 0xffb9} ,
138 | {"F1" , 0xffbe} ,
139 | {"F2" , 0xffbf} ,
140 | {"F3" , 0xffc0} ,
141 | {"F4" , 0xffc1} ,
142 | {"F5" , 0xffc2} ,
143 | {"F6" , 0xffc3} ,
144 | {"F7" , 0xffc4} ,
145 | {"F8" , 0xffc5} ,
146 | {"F9" , 0xffc6} ,
147 | {"F10" , 0xffc7} ,
148 | {"F11" , 0xffc8} ,
149 | {"L1" , 0xffc8} ,
150 | {"F12" , 0xffc9} ,
151 | {"L2" , 0xffc9} ,
152 | {"F13" , 0xffca} ,
153 | {"L3" , 0xffca} ,
154 | {"F14" , 0xffcb} ,
155 | {"L4" , 0xffcb} ,
156 | {"F15" , 0xffcc} ,
157 | {"L5" , 0xffcc} ,
158 | {"F16" , 0xffcd} ,
159 | {"L6" , 0xffcd} ,
160 | {"F17" , 0xffce} ,
161 | {"L7" , 0xffce} ,
162 | {"F18" , 0xffcf} ,
163 | {"L8" , 0xffcf} ,
164 | {"F19" , 0xffd0} ,
165 | {"L9" , 0xffd0} ,
166 | {"F20" , 0xffd1} ,
167 | {"L10" , 0xffd1} ,
168 | {"F21" , 0xffd2} ,
169 | {"R1" , 0xffd2} ,
170 | {"F22" , 0xffd3} ,
171 | {"R2" , 0xffd3} ,
172 | {"F23" , 0xffd4} ,
173 | {"R3" , 0xffd4} ,
174 | {"F24" , 0xffd5} ,
175 | {"R4" , 0xffd5} ,
176 | {"F25" , 0xffd6} ,
177 | {"R5" , 0xffd6} ,
178 | {"F26" , 0xffd7} ,
179 | {"R6" , 0xffd7} ,
180 | {"F27" , 0xffd8} ,
181 | {"R7" , 0xffd8} ,
182 | {"F28" , 0xffd9} ,
183 | {"R8" , 0xffd9} ,
184 | {"F29" , 0xffda} ,
185 | {"R9" , 0xffda} ,
186 | {"F30" , 0xffdb} ,
187 | {"R10" , 0xffdb} ,
188 | {"F31" , 0xffdc} ,
189 | {"R11" , 0xffdc} ,
190 | {"F32" , 0xffdd} ,
191 | {"R12" , 0xffdd} ,
192 | {"F33" , 0xffde} ,
193 | {"R13" , 0xffde} ,
194 | {"F34" , 0xffdf} ,
195 | {"R14" , 0xffdf} ,
196 | {"F35" , 0xffe0} ,
197 | {"R15" , 0xffe0} ,
198 | {"Shift_L" , 0xffe1} ,
199 | {"Shift_R" , 0xffe2} ,
200 | {"Control_L" , 0xffe3} ,
201 | {"Control_R" , 0xffe4} ,
202 | {"Caps_Lock" , 0xffe5} ,
203 | {"Shift_Lock" , 0xffe6} ,
204 | {"Meta_L" , 0xffe7} ,
205 | {"Meta_R" , 0xffe8} ,
206 | {"Alt_L" , 0xffe9} ,
207 | {"Alt_R" , 0xffea} ,
208 | {"Super_L" , 0xffeb} ,
209 | {"Super_R" , 0xffec} ,
210 | {"Hyper_L" , 0xffed} ,
211 | {"Hyper_R" , 0xffee} ,
212 | #endif
213 | #ifdef XK_XKB_KEYS
214 | {"ISO_Lock" , 0xfe01} ,
215 | {"ISO_Level2_Latch" , 0xfe02} ,
216 | {"ISO_Level3_Shift" , 0xfe03} ,
217 | {"ISO_Level3_Latch" , 0xfe04} ,
218 | {"ISO_Level3_Lock" , 0xfe05} ,
219 | {"ISO_Level5_Shift" , 0xfe11} ,
220 | {"ISO_Level5_Latch" , 0xfe12} ,
221 | {"ISO_Level5_Lock" , 0xfe13} ,
222 | {"ISO_Group_Shift" , 0xff7e} ,
223 | {"ISO_Group_Latch" , 0xfe06} ,
224 | {"ISO_Group_Lock" , 0xfe07} ,
225 | {"ISO_Next_Group" , 0xfe08} ,
226 | {"ISO_Next_Group_Lock" , 0xfe09} ,
227 | {"ISO_Prev_Group" , 0xfe0a} ,
228 | {"ISO_Prev_Group_Lock" , 0xfe0b} ,
229 | {"ISO_First_Group" , 0xfe0c} ,
230 | {"ISO_First_Group_Lock" , 0xfe0d} ,
231 | {"ISO_Last_Group" , 0xfe0e} ,
232 | {"ISO_Last_Group_Lock" , 0xfe0f} ,
233 | {"ISO_Left_Tab" , 0xfe20} ,
234 | {"ISO_Move_Line_Up" , 0xfe21} ,
235 | {"ISO_Move_Line_Down" , 0xfe22} ,
236 | {"ISO_Partial_Line_Up" , 0xfe23} ,
237 | {"ISO_Partial_Line_Down" , 0xfe24} ,
238 | {"ISO_Partial_Space_Left" , 0xfe25} ,
239 | {"ISO_Partial_Space_Right" , 0xfe26} ,
240 | {"ISO_Set_Margin_Left" , 0xfe27} ,
241 | {"ISO_Set_Margin_Right" , 0xfe28} ,
242 | {"ISO_Release_Margin_Left" , 0xfe29} ,
243 | {"ISO_Release_Margin_Right" , 0xfe2a} ,
244 | {"ISO_Release_Both_Margins" , 0xfe2b} ,
245 | {"ISO_Fast_Cursor_Left" , 0xfe2c} ,
246 | {"ISO_Fast_Cursor_Right" , 0xfe2d} ,
247 | {"ISO_Fast_Cursor_Up" , 0xfe2e} ,
248 | {"ISO_Fast_Cursor_Down" , 0xfe2f} ,
249 | {"ISO_Continuous_Underline" , 0xfe30} ,
250 | {"ISO_Discontinuous_Underline" , 0xfe31} ,
251 | {"ISO_Emphasize" , 0xfe32} ,
252 | {"ISO_Center_Object" , 0xfe33} ,
253 | {"ISO_Enter" , 0xfe34} ,
254 | {"dead_grave" , 0xfe50} ,
255 | {"dead_acute" , 0xfe51} ,
256 | {"dead_circumflex" , 0xfe52} ,
257 | {"dead_tilde" , 0xfe53} ,
258 | {"dead_perispomeni" , 0xfe53} ,
259 | {"dead_macron" , 0xfe54} ,
260 | {"dead_breve" , 0xfe55} ,
261 | {"dead_abovedot" , 0xfe56} ,
262 | {"dead_diaeresis" , 0xfe57} ,
263 | {"dead_abovering" , 0xfe58} ,
264 | {"dead_doubleacute" , 0xfe59} ,
265 | {"dead_caron" , 0xfe5a} ,
266 | {"dead_cedilla" , 0xfe5b} ,
267 | {"dead_ogonek" , 0xfe5c} ,
268 | {"dead_iota" , 0xfe5d} ,
269 | {"dead_voiced_sound" , 0xfe5e} ,
270 | {"dead_semivoiced_sound" , 0xfe5f} ,
271 | {"dead_belowdot" , 0xfe60} ,
272 | {"dead_hook" , 0xfe61} ,
273 | {"dead_horn" , 0xfe62} ,
274 | {"dead_stroke" , 0xfe63} ,
275 | {"dead_abovecomma" , 0xfe64} ,
276 | {"dead_psili" , 0xfe64} ,
277 | {"dead_abovereversedcomma" , 0xfe65} ,
278 | {"dead_dasia" , 0xfe65} ,
279 | {"dead_doublegrave" , 0xfe66} ,
280 | {"dead_belowring" , 0xfe67} ,
281 | {"dead_belowmacron" , 0xfe68} ,
282 | {"dead_belowcircumflex" , 0xfe69} ,
283 | {"dead_belowtilde" , 0xfe6a} ,
284 | {"dead_belowbreve" , 0xfe6b} ,
285 | {"dead_belowdiaeresis" , 0xfe6c} ,
286 | {"dead_invertedbreve" , 0xfe6d} ,
287 | {"dead_belowcomma" , 0xfe6e} ,
288 | {"dead_currency" , 0xfe6f} ,
289 | {"dead_a" , 0xfe80} ,
290 | {"dead_A" , 0xfe81} ,
291 | {"dead_e" , 0xfe82} ,
292 | {"dead_E" , 0xfe83} ,
293 | {"dead_i" , 0xfe84} ,
294 | {"dead_I" , 0xfe85} ,
295 | {"dead_o" , 0xfe86} ,
296 | {"dead_O" , 0xfe87} ,
297 | {"dead_u" , 0xfe88} ,
298 | {"dead_U" , 0xfe89} ,
299 | {"dead_small_schwa" , 0xfe8a} ,
300 | {"dead_capital_schwa" , 0xfe8b} ,
301 | {"dead_greek" , 0xfe8c} ,
302 | {"First_Virtual_Screen" , 0xfed0} ,
303 | {"Prev_Virtual_Screen" , 0xfed1} ,
304 | {"Next_Virtual_Screen" , 0xfed2} ,
305 | {"Last_Virtual_Screen" , 0xfed4} ,
306 | {"Terminate_Server" , 0xfed5} ,
307 | {"AccessX_Enable" , 0xfe70} ,
308 | {"AccessX_Feedback_Enable" , 0xfe71} ,
309 | {"RepeatKeys_Enable" , 0xfe72} ,
310 | {"SlowKeys_Enable" , 0xfe73} ,
311 | {"BounceKeys_Enable" , 0xfe74} ,
312 | {"StickyKeys_Enable" , 0xfe75} ,
313 | {"MouseKeys_Enable" , 0xfe76} ,
314 | {"MouseKeys_Accel_Enable" , 0xfe77} ,
315 | {"Overlay1_Enable" , 0xfe78} ,
316 | {"Overlay2_Enable" , 0xfe79} ,
317 | {"AudibleBell_Enable" , 0xfe7a} ,
318 | {"Pointer_Left" , 0xfee0} ,
319 | {"Pointer_Right" , 0xfee1} ,
320 | {"Pointer_Up" , 0xfee2} ,
321 | {"Pointer_Down" , 0xfee3} ,
322 | {"Pointer_UpLeft" , 0xfee4} ,
323 | {"Pointer_UpRight" , 0xfee5} ,
324 | {"Pointer_DownLeft" , 0xfee6} ,
325 | {"Pointer_DownRight" , 0xfee7} ,
326 | {"Pointer_Button_Dflt" , 0xfee8} ,
327 | {"Pointer_Button1" , 0xfee9} ,
328 | {"Pointer_Button2" , 0xfeea} ,
329 | {"Pointer_Button3" , 0xfeeb} ,
330 | {"Pointer_Button4" , 0xfeec} ,
331 | {"Pointer_Button5" , 0xfeed} ,
332 | {"Pointer_DblClick_Dflt" , 0xfeee} ,
333 | {"Pointer_DblClick1" , 0xfeef} ,
334 | {"Pointer_DblClick2" , 0xfef0} ,
335 | {"Pointer_DblClick3" , 0xfef1} ,
336 | {"Pointer_DblClick4" , 0xfef2} ,
337 | {"Pointer_DblClick5" , 0xfef3} ,
338 | {"Pointer_Drag_Dflt" , 0xfef4} ,
339 | {"Pointer_Drag1" , 0xfef5} ,
340 | {"Pointer_Drag2" , 0xfef6} ,
341 | {"Pointer_Drag3" , 0xfef7} ,
342 | {"Pointer_Drag4" , 0xfef8} ,
343 | {"Pointer_Drag5" , 0xfefd} ,
344 | {"Pointer_EnableKeys" , 0xfef9} ,
345 | {"Pointer_Accelerate" , 0xfefa} ,
346 | {"Pointer_DfltBtnNext" , 0xfefb} ,
347 | {"Pointer_DfltBtnPrev" , 0xfefc} ,
348 | {"ch" , 0xfea0} ,
349 | {"Ch" , 0xfea1} ,
350 | {"CH" , 0xfea2} ,
351 | {"c_h" , 0xfea3} ,
352 | {"C_h" , 0xfea4} ,
353 | {"C_H" , 0xfea5} ,
354 | #endif
355 | #ifdef XK_3270
356 | {"3270_Duplicate" , 0xfd01} ,
357 | {"3270_FieldMark" , 0xfd02} ,
358 | {"3270_Right2" , 0xfd03} ,
359 | {"3270_Left2" , 0xfd04} ,
360 | {"3270_BackTab" , 0xfd05} ,
361 | {"3270_EraseEOF" , 0xfd06} ,
362 | {"3270_EraseInput" , 0xfd07} ,
363 | {"3270_Reset" , 0xfd08} ,
364 | {"3270_Quit" , 0xfd09} ,
365 | {"3270_PA1" , 0xfd0a} ,
366 | {"3270_PA2" , 0xfd0b} ,
367 | {"3270_PA3" , 0xfd0c} ,
368 | {"3270_Test" , 0xfd0d} ,
369 | {"3270_Attn" , 0xfd0e} ,
370 | {"3270_CursorBlink" , 0xfd0f} ,
371 | {"3270_AltCursor" , 0xfd10} ,
372 | {"3270_KeyClick" , 0xfd11} ,
373 | {"3270_Jump" , 0xfd12} ,
374 | {"3270_Ident" , 0xfd13} ,
375 | {"3270_Rule" , 0xfd14} ,
376 | {"3270_Copy" , 0xfd15} ,
377 | {"3270_Play" , 0xfd16} ,
378 | {"3270_Setup" , 0xfd17} ,
379 | {"3270_Record" , 0xfd18} ,
380 | {"3270_ChangeScreen" , 0xfd19} ,
381 | {"3270_DeleteWord" , 0xfd1a} ,
382 | {"3270_ExSelect" , 0xfd1b} ,
383 | {"3270_CursorSelect" , 0xfd1c} ,
384 | {"3270_PrintScreen" , 0xfd1d} ,
385 | {"3270_Enter" , 0xfd1e} ,
386 | #endif
387 | #ifdef XK_LATIN1
388 | {"space" , 0x0020} ,
389 | {"exclam" , 0x0021} ,
390 | {"quotedbl" , 0x0022} ,
391 | {"numbersign" , 0x0023} ,
392 | {"dollar" , 0x0024} ,
393 | {"percent" , 0x0025} ,
394 | {"ampersand" , 0x0026} ,
395 | {"apostrophe" , 0x0027} ,
396 | {"quoteright" , 0x0027} ,
397 | {"parenleft" , 0x0028} ,
398 | {"parenright" , 0x0029} ,
399 | {"asterisk" , 0x002a} ,
400 | {"plus" , 0x002b} ,
401 | {"comma" , 0x002c} ,
402 | {"minus" , 0x002d} ,
403 | {"period" , 0x002e} ,
404 | {"slash" , 0x002f} ,
405 | {"0" , 0x0030} ,
406 | {"1" , 0x0031} ,
407 | {"2" , 0x0032} ,
408 | {"3" , 0x0033} ,
409 | {"4" , 0x0034} ,
410 | {"5" , 0x0035} ,
411 | {"6" , 0x0036} ,
412 | {"7" , 0x0037} ,
413 | {"8" , 0x0038} ,
414 | {"9" , 0x0039} ,
415 | {"colon" , 0x003a} ,
416 | {"semicolon" , 0x003b} ,
417 | {"less" , 0x003c} ,
418 | {"equal" , 0x003d} ,
419 | {"greater" , 0x003e} ,
420 | {"question" , 0x003f} ,
421 | {"at" , 0x0040} ,
422 | {"A" , 0x0041} ,
423 | {"B" , 0x0042} ,
424 | {"C" , 0x0043} ,
425 | {"D" , 0x0044} ,
426 | {"E" , 0x0045} ,
427 | {"F" , 0x0046} ,
428 | {"G" , 0x0047} ,
429 | {"H" , 0x0048} ,
430 | {"I" , 0x0049} ,
431 | {"J" , 0x004a} ,
432 | {"K" , 0x004b} ,
433 | {"L" , 0x004c} ,
434 | {"M" , 0x004d} ,
435 | {"N" , 0x004e} ,
436 | {"O" , 0x004f} ,
437 | {"P" , 0x0050} ,
438 | {"Q" , 0x0051} ,
439 | {"R" , 0x0052} ,
440 | {"S" , 0x0053} ,
441 | {"T" , 0x0054} ,
442 | {"U" , 0x0055} ,
443 | {"V" , 0x0056} ,
444 | {"W" , 0x0057} ,
445 | {"X" , 0x0058} ,
446 | {"Y" , 0x0059} ,
447 | {"Z" , 0x005a} ,
448 | {"bracketleft" , 0x005b} ,
449 | {"backslash" , 0x005c} ,
450 | {"bracketright" , 0x005d} ,
451 | {"asciicircum" , 0x005e} ,
452 | {"underscore" , 0x005f} ,
453 | {"grave" , 0x0060} ,
454 | {"quoteleft" , 0x0060} ,
455 | {"a" , 0x0061} ,
456 | {"b" , 0x0062} ,
457 | {"c" , 0x0063} ,
458 | {"d" , 0x0064} ,
459 | {"e" , 0x0065} ,
460 | {"f" , 0x0066} ,
461 | {"g" , 0x0067} ,
462 | {"h" , 0x0068} ,
463 | {"i" , 0x0069} ,
464 | {"j" , 0x006a} ,
465 | {"k" , 0x006b} ,
466 | {"l" , 0x006c} ,
467 | {"m" , 0x006d} ,
468 | {"n" , 0x006e} ,
469 | {"o" , 0x006f} ,
470 | {"p" , 0x0070} ,
471 | {"q" , 0x0071} ,
472 | {"r" , 0x0072} ,
473 | {"s" , 0x0073} ,
474 | {"t" , 0x0074} ,
475 | {"u" , 0x0075} ,
476 | {"v" , 0x0076} ,
477 | {"w" , 0x0077} ,
478 | {"x" , 0x0078} ,
479 | {"y" , 0x0079} ,
480 | {"z" , 0x007a} ,
481 | {"braceleft" , 0x007b} ,
482 | {"bar" , 0x007c} ,
483 | {"braceright" , 0x007d} ,
484 | {"asciitilde" , 0x007e} ,
485 | {"nobreakspace" , 0x00a0} ,
486 | {"exclamdown" , 0x00a1} ,
487 | {"cent" , 0x00a2} ,
488 | {"sterling" , 0x00a3} ,
489 | {"currency" , 0x00a4} ,
490 | {"yen" , 0x00a5} ,
491 | {"brokenbar" , 0x00a6} ,
492 | {"section" , 0x00a7} ,
493 | {"diaeresis" , 0x00a8} ,
494 | {"copyright" , 0x00a9} ,
495 | {"ordfeminine" , 0x00aa} ,
496 | {"guillemotleft" , 0x00ab} ,
497 | {"notsign" , 0x00ac} ,
498 | {"hyphen" , 0x00ad} ,
499 | {"registered" , 0x00ae} ,
500 | {"macron" , 0x00af} ,
501 | {"degree" , 0x00b0} ,
502 | {"plusminus" , 0x00b1} ,
503 | {"twosuperior" , 0x00b2} ,
504 | {"threesuperior" , 0x00b3} ,
505 | {"acute" , 0x00b4} ,
506 | {"mu" , 0x00b5} ,
507 | {"paragraph" , 0x00b6} ,
508 | {"periodcentered" , 0x00b7} ,
509 | {"cedilla" , 0x00b8} ,
510 | {"onesuperior" , 0x00b9} ,
511 | {"masculine" , 0x00ba} ,
512 | {"guillemotright" , 0x00bb} ,
513 | {"onequarter" , 0x00bc} ,
514 | {"onehalf" , 0x00bd} ,
515 | {"threequarters" , 0x00be} ,
516 | {"questiondown" , 0x00bf} ,
517 | {"Agrave" , 0x00c0} ,
518 | {"Aacute" , 0x00c1} ,
519 | {"Acircumflex" , 0x00c2} ,
520 | {"Atilde" , 0x00c3} ,
521 | {"Adiaeresis" , 0x00c4} ,
522 | {"Aring" , 0x00c5} ,
523 | {"AE" , 0x00c6} ,
524 | {"Ccedilla" , 0x00c7} ,
525 | {"Egrave" , 0x00c8} ,
526 | {"Eacute" , 0x00c9} ,
527 | {"Ecircumflex" , 0x00ca} ,
528 | {"Ediaeresis" , 0x00cb} ,
529 | {"Igrave" , 0x00cc} ,
530 | {"Iacute" , 0x00cd} ,
531 | {"Icircumflex" , 0x00ce} ,
532 | {"Idiaeresis" , 0x00cf} ,
533 | {"ETH" , 0x00d0} ,
534 | {"Eth" , 0x00d0} ,
535 | {"Ntilde" , 0x00d1} ,
536 | {"Ograve" , 0x00d2} ,
537 | {"Oacute" , 0x00d3} ,
538 | {"Ocircumflex" , 0x00d4} ,
539 | {"Otilde" , 0x00d5} ,
540 | {"Odiaeresis" , 0x00d6} ,
541 | {"multiply" , 0x00d7} ,
542 | {"Oslash" , 0x00d8} ,
543 | {"Ooblique" , 0x00d8} ,
544 | {"Ugrave" , 0x00d9} ,
545 | {"Uacute" , 0x00da} ,
546 | {"Ucircumflex" , 0x00db} ,
547 | {"Udiaeresis" , 0x00dc} ,
548 | {"Yacute" , 0x00dd} ,
549 | {"THORN" , 0x00de} ,
550 | {"Thorn" , 0x00de} ,
551 | {"ssharp" , 0x00df} ,
552 | {"agrave" , 0x00e0} ,
553 | {"aacute" , 0x00e1} ,
554 | {"acircumflex" , 0x00e2} ,
555 | {"atilde" , 0x00e3} ,
556 | {"adiaeresis" , 0x00e4} ,
557 | {"aring" , 0x00e5} ,
558 | {"ae" , 0x00e6} ,
559 | {"ccedilla" , 0x00e7} ,
560 | {"egrave" , 0x00e8} ,
561 | {"eacute" , 0x00e9} ,
562 | {"ecircumflex" , 0x00ea} ,
563 | {"ediaeresis" , 0x00eb} ,
564 | {"igrave" , 0x00ec} ,
565 | {"iacute" , 0x00ed} ,
566 | {"icircumflex" , 0x00ee} ,
567 | {"idiaeresis" , 0x00ef} ,
568 | {"eth" , 0x00f0} ,
569 | {"ntilde" , 0x00f1} ,
570 | {"ograve" , 0x00f2} ,
571 | {"oacute" , 0x00f3} ,
572 | {"ocircumflex" , 0x00f4} ,
573 | {"otilde" , 0x00f5} ,
574 | {"odiaeresis" , 0x00f6} ,
575 | {"division" , 0x00f7} ,
576 | {"oslash" , 0x00f8} ,
577 | {"ooblique" , 0x00f8} ,
578 | {"ugrave" , 0x00f9} ,
579 | {"uacute" , 0x00fa} ,
580 | {"ucircumflex" , 0x00fb} ,
581 | {"udiaeresis" , 0x00fc} ,
582 | {"yacute" , 0x00fd} ,
583 | {"thorn" , 0x00fe} ,
584 | {"ydiaeresis" , 0x00ff} ,
585 | #endif
586 | #ifdef XK_LATIN2
587 | {"Aogonek" , 0x01a1} ,
588 | {"breve" , 0x01a2} ,
589 | {"Lstroke" , 0x01a3} ,
590 | {"Lcaron" , 0x01a5} ,
591 | {"Sacute" , 0x01a6} ,
592 | {"Scaron" , 0x01a9} ,
593 | {"Scedilla" , 0x01aa} ,
594 | {"Tcaron" , 0x01ab} ,
595 | {"Zacute" , 0x01ac} ,
596 | {"Zcaron" , 0x01ae} ,
597 | {"Zabovedot" , 0x01af} ,
598 | {"aogonek" , 0x01b1} ,
599 | {"ogonek" , 0x01b2} ,
600 | {"lstroke" , 0x01b3} ,
601 | {"lcaron" , 0x01b5} ,
602 | {"sacute" , 0x01b6} ,
603 | {"caron" , 0x01b7} ,
604 | {"scaron" , 0x01b9} ,
605 | {"scedilla" , 0x01ba} ,
606 | {"tcaron" , 0x01bb} ,
607 | {"zacute" , 0x01bc} ,
608 | {"doubleacute" , 0x01bd} ,
609 | {"zcaron" , 0x01be} ,
610 | {"zabovedot" , 0x01bf} ,
611 | {"Racute" , 0x01c0} ,
612 | {"Abreve" , 0x01c3} ,
613 | {"Lacute" , 0x01c5} ,
614 | {"Cacute" , 0x01c6} ,
615 | {"Ccaron" , 0x01c8} ,
616 | {"Eogonek" , 0x01ca} ,
617 | {"Ecaron" , 0x01cc} ,
618 | {"Dcaron" , 0x01cf} ,
619 | {"Dstroke" , 0x01d0} ,
620 | {"Nacute" , 0x01d1} ,
621 | {"Ncaron" , 0x01d2} ,
622 | {"Odoubleacute" , 0x01d5} ,
623 | {"Rcaron" , 0x01d8} ,
624 | {"Uring" , 0x01d9} ,
625 | {"Udoubleacute" , 0x01db} ,
626 | {"Tcedilla" , 0x01de} ,
627 | {"racute" , 0x01e0} ,
628 | {"abreve" , 0x01e3} ,
629 | {"lacute" , 0x01e5} ,
630 | {"cacute" , 0x01e6} ,
631 | {"ccaron" , 0x01e8} ,
632 | {"eogonek" , 0x01ea} ,
633 | {"ecaron" , 0x01ec} ,
634 | {"dcaron" , 0x01ef} ,
635 | {"dstroke" , 0x01f0} ,
636 | {"nacute" , 0x01f1} ,
637 | {"ncaron" , 0x01f2} ,
638 | {"odoubleacute" , 0x01f5} ,
639 | {"rcaron" , 0x01f8} ,
640 | {"uring" , 0x01f9} ,
641 | {"udoubleacute" , 0x01fb} ,
642 | {"tcedilla" , 0x01fe} ,
643 | {"abovedot" , 0x01ff} ,
644 | #endif
645 | #ifdef XK_LATIN3
646 | {"Hstroke" , 0x02a1} ,
647 | {"Hcircumflex" , 0x02a6} ,
648 | {"Iabovedot" , 0x02a9} ,
649 | {"Gbreve" , 0x02ab} ,
650 | {"Jcircumflex" , 0x02ac} ,
651 | {"hstroke" , 0x02b1} ,
652 | {"hcircumflex" , 0x02b6} ,
653 | {"idotless" , 0x02b9} ,
654 | {"gbreve" , 0x02bb} ,
655 | {"jcircumflex" , 0x02bc} ,
656 | {"Cabovedot" , 0x02c5} ,
657 | {"Ccircumflex" , 0x02c6} ,
658 | {"Gabovedot" , 0x02d5} ,
659 | {"Gcircumflex" , 0x02d8} ,
660 | {"Ubreve" , 0x02dd} ,
661 | {"Scircumflex" , 0x02de} ,
662 | {"cabovedot" , 0x02e5} ,
663 | {"ccircumflex" , 0x02e6} ,
664 | {"gabovedot" , 0x02f5} ,
665 | {"gcircumflex" , 0x02f8} ,
666 | {"ubreve" , 0x02fd} ,
667 | {"scircumflex" , 0x02fe} ,
668 | #endif
669 | #ifdef XK_LATIN4
670 | {"kra" , 0x03a2} ,
671 | {"kappa" , 0x03a2} ,
672 | {"Rcedilla" , 0x03a3} ,
673 | {"Itilde" , 0x03a5} ,
674 | {"Lcedilla" , 0x03a6} ,
675 | {"Emacron" , 0x03aa} ,
676 | {"Gcedilla" , 0x03ab} ,
677 | {"Tslash" , 0x03ac} ,
678 | {"rcedilla" , 0x03b3} ,
679 | {"itilde" , 0x03b5} ,
680 | {"lcedilla" , 0x03b6} ,
681 | {"emacron" , 0x03ba} ,
682 | {"gcedilla" , 0x03bb} ,
683 | {"tslash" , 0x03bc} ,
684 | {"ENG" , 0x03bd} ,
685 | {"eng" , 0x03bf} ,
686 | {"Amacron" , 0x03c0} ,
687 | {"Iogonek" , 0x03c7} ,
688 | {"Eabovedot" , 0x03cc} ,
689 | {"Imacron" , 0x03cf} ,
690 | {"Ncedilla" , 0x03d1} ,
691 | {"Omacron" , 0x03d2} ,
692 | {"Kcedilla" , 0x03d3} ,
693 | {"Uogonek" , 0x03d9} ,
694 | {"Utilde" , 0x03dd} ,
695 | {"Umacron" , 0x03de} ,
696 | {"amacron" , 0x03e0} ,
697 | {"iogonek" , 0x03e7} ,
698 | {"eabovedot" , 0x03ec} ,
699 | {"imacron" , 0x03ef} ,
700 | {"ncedilla" , 0x03f1} ,
701 | {"omacron" , 0x03f2} ,
702 | {"kcedilla" , 0x03f3} ,
703 | {"uogonek" , 0x03f9} ,
704 | {"utilde" , 0x03fd} ,
705 | {"umacron" , 0x03fe} ,
706 | #endif
707 | #ifdef XK_LATIN8
708 | {"Wcircumflex" , 0x1000174} ,
709 | {"wcircumflex" , 0x1000175} ,
710 | {"Ycircumflex" , 0x1000176} ,
711 | {"ycircumflex" , 0x1000177} ,
712 | {"Babovedot" , 0x1001e02} ,
713 | {"babovedot" , 0x1001e03} ,
714 | {"Dabovedot" , 0x1001e0a} ,
715 | {"dabovedot" , 0x1001e0b} ,
716 | {"Fabovedot" , 0x1001e1e} ,
717 | {"fabovedot" , 0x1001e1f} ,
718 | {"Mabovedot" , 0x1001e40} ,
719 | {"mabovedot" , 0x1001e41} ,
720 | {"Pabovedot" , 0x1001e56} ,
721 | {"pabovedot" , 0x1001e57} ,
722 | {"Sabovedot" , 0x1001e60} ,
723 | {"sabovedot" , 0x1001e61} ,
724 | {"Tabovedot" , 0x1001e6a} ,
725 | {"tabovedot" , 0x1001e6b} ,
726 | {"Wgrave" , 0x1001e80} ,
727 | {"wgrave" , 0x1001e81} ,
728 | {"Wacute" , 0x1001e82} ,
729 | {"wacute" , 0x1001e83} ,
730 | {"Wdiaeresis" , 0x1001e84} ,
731 | {"wdiaeresis" , 0x1001e85} ,
732 | {"Ygrave" , 0x1001ef2} ,
733 | {"ygrave" , 0x1001ef3} ,
734 | #endif
735 | #ifdef XK_LATIN9
736 | {"OE" , 0x13bc} ,
737 | {"oe" , 0x13bd} ,
738 | {"Ydiaeresis" , 0x13be} ,
739 | #endif
740 | #ifdef XK_KATAKANA
741 | {"overline" , 0x047e} ,
742 | {"kana_fullstop" , 0x04a1} ,
743 | {"kana_openingbracket" , 0x04a2} ,
744 | {"kana_closingbracket" , 0x04a3} ,
745 | {"kana_comma" , 0x04a4} ,
746 | {"kana_conjunctive" , 0x04a5} ,
747 | {"kana_middledot" , 0x04a5} ,
748 | {"kana_WO" , 0x04a6} ,
749 | {"kana_a" , 0x04a7} ,
750 | {"kana_i" , 0x04a8} ,
751 | {"kana_u" , 0x04a9} ,
752 | {"kana_e" , 0x04aa} ,
753 | {"kana_o" , 0x04ab} ,
754 | {"kana_ya" , 0x04ac} ,
755 | {"kana_yu" , 0x04ad} ,
756 | {"kana_yo" , 0x04ae} ,
757 | {"kana_tsu" , 0x04af} ,
758 | {"kana_tu" , 0x04af} ,
759 | {"prolongedsound" , 0x04b0} ,
760 | {"kana_A" , 0x04b1} ,
761 | {"kana_I" , 0x04b2} ,
762 | {"kana_U" , 0x04b3} ,
763 | {"kana_E" , 0x04b4} ,
764 | {"kana_O" , 0x04b5} ,
765 | {"kana_KA" , 0x04b6} ,
766 | {"kana_KI" , 0x04b7} ,
767 | {"kana_KU" , 0x04b8} ,
768 | {"kana_KE" , 0x04b9} ,
769 | {"kana_KO" , 0x04ba} ,
770 | {"kana_SA" , 0x04bb} ,
771 | {"kana_SHI" , 0x04bc} ,
772 | {"kana_SU" , 0x04bd} ,
773 | {"kana_SE" , 0x04be} ,
774 | {"kana_SO" , 0x04bf} ,
775 | {"kana_TA" , 0x04c0} ,
776 | {"kana_CHI" , 0x04c1} ,
777 | {"kana_TI" , 0x04c1} ,
778 | {"kana_TSU" , 0x04c2} ,
779 | {"kana_TU" , 0x04c2} ,
780 | {"kana_TE" , 0x04c3} ,
781 | {"kana_TO" , 0x04c4} ,
782 | {"kana_NA" , 0x04c5} ,
783 | {"kana_NI" , 0x04c6} ,
784 | {"kana_NU" , 0x04c7} ,
785 | {"kana_NE" , 0x04c8} ,
786 | {"kana_NO" , 0x04c9} ,
787 | {"kana_HA" , 0x04ca} ,
788 | {"kana_HI" , 0x04cb} ,
789 | {"kana_FU" , 0x04cc} ,
790 | {"kana_HU" , 0x04cc} ,
791 | {"kana_HE" , 0x04cd} ,
792 | {"kana_HO" , 0x04ce} ,
793 | {"kana_MA" , 0x04cf} ,
794 | {"kana_MI" , 0x04d0} ,
795 | {"kana_MU" , 0x04d1} ,
796 | {"kana_ME" , 0x04d2} ,
797 | {"kana_MO" , 0x04d3} ,
798 | {"kana_YA" , 0x04d4} ,
799 | {"kana_YU" , 0x04d5} ,
800 | {"kana_YO" , 0x04d6} ,
801 | {"kana_RA" , 0x04d7} ,
802 | {"kana_RI" , 0x04d8} ,
803 | {"kana_RU" , 0x04d9} ,
804 | {"kana_RE" , 0x04da} ,
805 | {"kana_RO" , 0x04db} ,
806 | {"kana_WA" , 0x04dc} ,
807 | {"kana_N" , 0x04dd} ,
808 | {"voicedsound" , 0x04de} ,
809 | {"semivoicedsound" , 0x04df} ,
810 | {"kana_switch" , 0xff7e} ,
811 | #endif
812 | #ifdef XK_ARABIC
813 | {"Farsi_0" , 0x10006f0} ,
814 | {"Farsi_1" , 0x10006f1} ,
815 | {"Farsi_2" , 0x10006f2} ,
816 | {"Farsi_3" , 0x10006f3} ,
817 | {"Farsi_4" , 0x10006f4} ,
818 | {"Farsi_5" , 0x10006f5} ,
819 | {"Farsi_6" , 0x10006f6} ,
820 | {"Farsi_7" , 0x10006f7} ,
821 | {"Farsi_8" , 0x10006f8} ,
822 | {"Farsi_9" , 0x10006f9} ,
823 | {"Arabic_percent" , 0x100066a} ,
824 | {"Arabic_superscript_alef" , 0x1000670} ,
825 | {"Arabic_tteh" , 0x1000679} ,
826 | {"Arabic_peh" , 0x100067e} ,
827 | {"Arabic_tcheh" , 0x1000686} ,
828 | {"Arabic_ddal" , 0x1000688} ,
829 | {"Arabic_rreh" , 0x1000691} ,
830 | {"Arabic_comma" , 0x05ac} ,
831 | {"Arabic_fullstop" , 0x10006d4} ,
832 | {"Arabic_0" , 0x1000660} ,
833 | {"Arabic_1" , 0x1000661} ,
834 | {"Arabic_2" , 0x1000662} ,
835 | {"Arabic_3" , 0x1000663} ,
836 | {"Arabic_4" , 0x1000664} ,
837 | {"Arabic_5" , 0x1000665} ,
838 | {"Arabic_6" , 0x1000666} ,
839 | {"Arabic_7" , 0x1000667} ,
840 | {"Arabic_8" , 0x1000668} ,
841 | {"Arabic_9" , 0x1000669} ,
842 | {"Arabic_semicolon" , 0x05bb} ,
843 | {"Arabic_question_mark" , 0x05bf} ,
844 | {"Arabic_hamza" , 0x05c1} ,
845 | {"Arabic_maddaonalef" , 0x05c2} ,
846 | {"Arabic_hamzaonalef" , 0x05c3} ,
847 | {"Arabic_hamzaonwaw" , 0x05c4} ,
848 | {"Arabic_hamzaunderalef" , 0x05c5} ,
849 | {"Arabic_hamzaonyeh" , 0x05c6} ,
850 | {"Arabic_alef" , 0x05c7} ,
851 | {"Arabic_beh" , 0x05c8} ,
852 | {"Arabic_tehmarbuta" , 0x05c9} ,
853 | {"Arabic_teh" , 0x05ca} ,
854 | {"Arabic_theh" , 0x05cb} ,
855 | {"Arabic_jeem" , 0x05cc} ,
856 | {"Arabic_hah" , 0x05cd} ,
857 | {"Arabic_khah" , 0x05ce} ,
858 | {"Arabic_dal" , 0x05cf} ,
859 | {"Arabic_thal" , 0x05d0} ,
860 | {"Arabic_ra" , 0x05d1} ,
861 | {"Arabic_zain" , 0x05d2} ,
862 | {"Arabic_seen" , 0x05d3} ,
863 | {"Arabic_sheen" , 0x05d4} ,
864 | {"Arabic_sad" , 0x05d5} ,
865 | {"Arabic_dad" , 0x05d6} ,
866 | {"Arabic_tah" , 0x05d7} ,
867 | {"Arabic_zah" , 0x05d8} ,
868 | {"Arabic_ain" , 0x05d9} ,
869 | {"Arabic_ghain" , 0x05da} ,
870 | {"Arabic_tatweel" , 0x05e0} ,
871 | {"Arabic_feh" , 0x05e1} ,
872 | {"Arabic_qaf" , 0x05e2} ,
873 | {"Arabic_kaf" , 0x05e3} ,
874 | {"Arabic_lam" , 0x05e4} ,
875 | {"Arabic_meem" , 0x05e5} ,
876 | {"Arabic_noon" , 0x05e6} ,
877 | {"Arabic_ha" , 0x05e7} ,
878 | {"Arabic_heh" , 0x05e7} ,
879 | {"Arabic_waw" , 0x05e8} ,
880 | {"Arabic_alefmaksura" , 0x05e9} ,
881 | {"Arabic_yeh" , 0x05ea} ,
882 | {"Arabic_fathatan" , 0x05eb} ,
883 | {"Arabic_dammatan" , 0x05ec} ,
884 | {"Arabic_kasratan" , 0x05ed} ,
885 | {"Arabic_fatha" , 0x05ee} ,
886 | {"Arabic_damma" , 0x05ef} ,
887 | {"Arabic_kasra" , 0x05f0} ,
888 | {"Arabic_shadda" , 0x05f1} ,
889 | {"Arabic_sukun" , 0x05f2} ,
890 | {"Arabic_madda_above" , 0x1000653} ,
891 | {"Arabic_hamza_above" , 0x1000654} ,
892 | {"Arabic_hamza_below" , 0x1000655} ,
893 | {"Arabic_jeh" , 0x1000698} ,
894 | {"Arabic_veh" , 0x10006a4} ,
895 | {"Arabic_keheh" , 0x10006a9} ,
896 | {"Arabic_gaf" , 0x10006af} ,
897 | {"Arabic_noon_ghunna" , 0x10006ba} ,
898 | {"Arabic_heh_doachashmee" , 0x10006be} ,
899 | {"Farsi_yeh" , 0x10006cc} ,
900 | {"Arabic_farsi_yeh" , 0x10006cc} ,
901 | {"Arabic_yeh_baree" , 0x10006d2} ,
902 | {"Arabic_heh_goal" , 0x10006c1} ,
903 | {"Arabic_switch" , 0xff7e} ,
904 | #endif
905 | #ifdef XK_CYRILLIC
906 | {"Cyrillic_GHE_bar" , 0x1000492} ,
907 | {"Cyrillic_ghe_bar" , 0x1000493} ,
908 | {"Cyrillic_ZHE_descender" , 0x1000496} ,
909 | {"Cyrillic_zhe_descender" , 0x1000497} ,
910 | {"Cyrillic_KA_descender" , 0x100049a} ,
911 | {"Cyrillic_ka_descender" , 0x100049b} ,
912 | {"Cyrillic_KA_vertstroke" , 0x100049c} ,
913 | {"Cyrillic_ka_vertstroke" , 0x100049d} ,
914 | {"Cyrillic_EN_descender" , 0x10004a2} ,
915 | {"Cyrillic_en_descender" , 0x10004a3} ,
916 | {"Cyrillic_U_straight" , 0x10004ae} ,
917 | {"Cyrillic_u_straight" , 0x10004af} ,
918 | {"Cyrillic_U_straight_bar" , 0x10004b0} ,
919 | {"Cyrillic_u_straight_bar" , 0x10004b1} ,
920 | {"Cyrillic_HA_descender" , 0x10004b2} ,
921 | {"Cyrillic_ha_descender" , 0x10004b3} ,
922 | {"Cyrillic_CHE_descender" , 0x10004b6} ,
923 | {"Cyrillic_che_descender" , 0x10004b7} ,
924 | {"Cyrillic_CHE_vertstroke" , 0x10004b8} ,
925 | {"Cyrillic_che_vertstroke" , 0x10004b9} ,
926 | {"Cyrillic_SHHA" , 0x10004ba} ,
927 | {"Cyrillic_shha" , 0x10004bb} ,
928 | {"Cyrillic_SCHWA" , 0x10004d8} ,
929 | {"Cyrillic_schwa" , 0x10004d9} ,
930 | {"Cyrillic_I_macron" , 0x10004e2} ,
931 | {"Cyrillic_i_macron" , 0x10004e3} ,
932 | {"Cyrillic_O_bar" , 0x10004e8} ,
933 | {"Cyrillic_o_bar" , 0x10004e9} ,
934 | {"Cyrillic_U_macron" , 0x10004ee} ,
935 | {"Cyrillic_u_macron" , 0x10004ef} ,
936 | {"Serbian_dje" , 0x06a1} ,
937 | {"Macedonia_gje" , 0x06a2} ,
938 | {"Cyrillic_io" , 0x06a3} ,
939 | {"Ukrainian_ie" , 0x06a4} ,
940 | {"Ukranian_je" , 0x06a4} ,
941 | {"Macedonia_dse" , 0x06a5} ,
942 | {"Ukrainian_i" , 0x06a6} ,
943 | {"Ukranian_i" , 0x06a6} ,
944 | {"Ukrainian_yi" , 0x06a7} ,
945 | {"Ukranian_yi" , 0x06a7} ,
946 | {"Cyrillic_je" , 0x06a8} ,
947 | {"Serbian_je" , 0x06a8} ,
948 | {"Cyrillic_lje" , 0x06a9} ,
949 | {"Serbian_lje" , 0x06a9} ,
950 | {"Cyrillic_nje" , 0x06aa} ,
951 | {"Serbian_nje" , 0x06aa} ,
952 | {"Serbian_tshe" , 0x06ab} ,
953 | {"Macedonia_kje" , 0x06ac} ,
954 | {"Ukrainian_ghe_with_upturn" , 0x06ad} ,
955 | {"Byelorussian_shortu" , 0x06ae} ,
956 | {"Cyrillic_dzhe" , 0x06af} ,
957 | {"Serbian_dze" , 0x06af} ,
958 | {"numerosign" , 0x06b0} ,
959 | {"Serbian_DJE" , 0x06b1} ,
960 | {"Macedonia_GJE" , 0x06b2} ,
961 | {"Cyrillic_IO" , 0x06b3} ,
962 | {"Ukrainian_IE" , 0x06b4} ,
963 | {"Ukranian_JE" , 0x06b4} ,
964 | {"Macedonia_DSE" , 0x06b5} ,
965 | {"Ukrainian_I" , 0x06b6} ,
966 | {"Ukranian_I" , 0x06b6} ,
967 | {"Ukrainian_YI" , 0x06b7} ,
968 | {"Ukranian_YI" , 0x06b7} ,
969 | {"Cyrillic_JE" , 0x06b8} ,
970 | {"Serbian_JE" , 0x06b8} ,
971 | {"Cyrillic_LJE" , 0x06b9} ,
972 | {"Serbian_LJE" , 0x06b9} ,
973 | {"Cyrillic_NJE" , 0x06ba} ,
974 | {"Serbian_NJE" , 0x06ba} ,
975 | {"Serbian_TSHE" , 0x06bb} ,
976 | {"Macedonia_KJE" , 0x06bc} ,
977 | {"Ukrainian_GHE_WITH_UPTURN" , 0x06bd} ,
978 | {"Byelorussian_SHORTU" , 0x06be} ,
979 | {"Cyrillic_DZHE" , 0x06bf} ,
980 | {"Serbian_DZE" , 0x06bf} ,
981 | {"Cyrillic_yu" , 0x06c0} ,
982 | {"Cyrillic_a" , 0x06c1} ,
983 | {"Cyrillic_be" , 0x06c2} ,
984 | {"Cyrillic_tse" , 0x06c3} ,
985 | {"Cyrillic_de" , 0x06c4} ,
986 | {"Cyrillic_ie" , 0x06c5} ,
987 | {"Cyrillic_ef" , 0x06c6} ,
988 | {"Cyrillic_ghe" , 0x06c7} ,
989 | {"Cyrillic_ha" , 0x06c8} ,
990 | {"Cyrillic_i" , 0x06c9} ,
991 | {"Cyrillic_shorti" , 0x06ca} ,
992 | {"Cyrillic_ka" , 0x06cb} ,
993 | {"Cyrillic_el" , 0x06cc} ,
994 | {"Cyrillic_em" , 0x06cd} ,
995 | {"Cyrillic_en" , 0x06ce} ,
996 | {"Cyrillic_o" , 0x06cf} ,
997 | {"Cyrillic_pe" , 0x06d0} ,
998 | {"Cyrillic_ya" , 0x06d1} ,
999 | {"Cyrillic_er" , 0x06d2} ,
1000 | {"Cyrillic_es" , 0x06d3} ,
1001 | {"Cyrillic_te" , 0x06d4} ,
1002 | {"Cyrillic_u" , 0x06d5} ,
1003 | {"Cyrillic_zhe" , 0x06d6} ,
1004 | {"Cyrillic_ve" , 0x06d7} ,
1005 | {"Cyrillic_softsign" , 0x06d8} ,
1006 | {"Cyrillic_yeru" , 0x06d9} ,
1007 | {"Cyrillic_ze" , 0x06da} ,
1008 | {"Cyrillic_sha" , 0x06db} ,
1009 | {"Cyrillic_e" , 0x06dc} ,
1010 | {"Cyrillic_shcha" , 0x06dd} ,
1011 | {"Cyrillic_che" , 0x06de} ,
1012 | {"Cyrillic_hardsign" , 0x06df} ,
1013 | {"Cyrillic_YU" , 0x06e0} ,
1014 | {"Cyrillic_A" , 0x06e1} ,
1015 | {"Cyrillic_BE" , 0x06e2} ,
1016 | {"Cyrillic_TSE" , 0x06e3} ,
1017 | {"Cyrillic_DE" , 0x06e4} ,
1018 | {"Cyrillic_IE" , 0x06e5} ,
1019 | {"Cyrillic_EF" , 0x06e6} ,
1020 | {"Cyrillic_GHE" , 0x06e7} ,
1021 | {"Cyrillic_HA" , 0x06e8} ,
1022 | {"Cyrillic_I" , 0x06e9} ,
1023 | {"Cyrillic_SHORTI" , 0x06ea} ,
1024 | {"Cyrillic_KA" , 0x06eb} ,
1025 | {"Cyrillic_EL" , 0x06ec} ,
1026 | {"Cyrillic_EM" , 0x06ed} ,
1027 | {"Cyrillic_EN" , 0x06ee} ,
1028 | {"Cyrillic_O" , 0x06ef} ,
1029 | {"Cyrillic_PE" , 0x06f0} ,
1030 | {"Cyrillic_YA" , 0x06f1} ,
1031 | {"Cyrillic_ER" , 0x06f2} ,
1032 | {"Cyrillic_ES" , 0x06f3} ,
1033 | {"Cyrillic_TE" , 0x06f4} ,
1034 | {"Cyrillic_U" , 0x06f5} ,
1035 | {"Cyrillic_ZHE" , 0x06f6} ,
1036 | {"Cyrillic_VE" , 0x06f7} ,
1037 | {"Cyrillic_SOFTSIGN" , 0x06f8} ,
1038 | {"Cyrillic_YERU" , 0x06f9} ,
1039 | {"Cyrillic_ZE" , 0x06fa} ,
1040 | {"Cyrillic_SHA" , 0x06fb} ,
1041 | {"Cyrillic_E" , 0x06fc} ,
1042 | {"Cyrillic_SHCHA" , 0x06fd} ,
1043 | {"Cyrillic_CHE" , 0x06fe} ,
1044 | {"Cyrillic_HARDSIGN" , 0x06ff} ,
1045 | #endif
1046 | #ifdef XK_GREEK
1047 | {"Greek_ALPHAaccent" , 0x07a1} ,
1048 | {"Greek_EPSILONaccent" , 0x07a2} ,
1049 | {"Greek_ETAaccent" , 0x07a3} ,
1050 | {"Greek_IOTAaccent" , 0x07a4} ,
1051 | {"Greek_IOTAdieresis" , 0x07a5} ,
1052 | {"Greek_IOTAdiaeresis" , 0x07a5} ,
1053 | {"Greek_OMICRONaccent" , 0x07a7} ,
1054 | {"Greek_UPSILONaccent" , 0x07a8} ,
1055 | {"Greek_UPSILONdieresis" , 0x07a9} ,
1056 | {"Greek_OMEGAaccent" , 0x07ab} ,
1057 | {"Greek_accentdieresis" , 0x07ae} ,
1058 | {"Greek_horizbar" , 0x07af} ,
1059 | {"Greek_alphaaccent" , 0x07b1} ,
1060 | {"Greek_epsilonaccent" , 0x07b2} ,
1061 | {"Greek_etaaccent" , 0x07b3} ,
1062 | {"Greek_iotaaccent" , 0x07b4} ,
1063 | {"Greek_iotadieresis" , 0x07b5} ,
1064 | {"Greek_iotaaccentdieresis" , 0x07b6} ,
1065 | {"Greek_omicronaccent" , 0x07b7} ,
1066 | {"Greek_upsilonaccent" , 0x07b8} ,
1067 | {"Greek_upsilondieresis" , 0x07b9} ,
1068 | {"Greek_upsilonaccentdieresis" , 0x07ba} ,
1069 | {"Greek_omegaaccent" , 0x07bb} ,
1070 | {"Greek_ALPHA" , 0x07c1} ,
1071 | {"Greek_BETA" , 0x07c2} ,
1072 | {"Greek_GAMMA" , 0x07c3} ,
1073 | {"Greek_DELTA" , 0x07c4} ,
1074 | {"Greek_EPSILON" , 0x07c5} ,
1075 | {"Greek_ZETA" , 0x07c6} ,
1076 | {"Greek_ETA" , 0x07c7} ,
1077 | {"Greek_THETA" , 0x07c8} ,
1078 | {"Greek_IOTA" , 0x07c9} ,
1079 | {"Greek_KAPPA" , 0x07ca} ,
1080 | {"Greek_LAMDA" , 0x07cb} ,
1081 | {"Greek_LAMBDA" , 0x07cb} ,
1082 | {"Greek_MU" , 0x07cc} ,
1083 | {"Greek_NU" , 0x07cd} ,
1084 | {"Greek_XI" , 0x07ce} ,
1085 | {"Greek_OMICRON" , 0x07cf} ,
1086 | {"Greek_PI" , 0x07d0} ,
1087 | {"Greek_RHO" , 0x07d1} ,
1088 | {"Greek_SIGMA" , 0x07d2} ,
1089 | {"Greek_TAU" , 0x07d4} ,
1090 | {"Greek_UPSILON" , 0x07d5} ,
1091 | {"Greek_PHI" , 0x07d6} ,
1092 | {"Greek_CHI" , 0x07d7} ,
1093 | {"Greek_PSI" , 0x07d8} ,
1094 | {"Greek_OMEGA" , 0x07d9} ,
1095 | {"Greek_alpha" , 0x07e1} ,
1096 | {"Greek_beta" , 0x07e2} ,
1097 | {"Greek_gamma" , 0x07e3} ,
1098 | {"Greek_delta" , 0x07e4} ,
1099 | {"Greek_epsilon" , 0x07e5} ,
1100 | {"Greek_zeta" , 0x07e6} ,
1101 | {"Greek_eta" , 0x07e7} ,
1102 | {"Greek_theta" , 0x07e8} ,
1103 | {"Greek_iota" , 0x07e9} ,
1104 | {"Greek_kappa" , 0x07ea} ,
1105 | {"Greek_lamda" , 0x07eb} ,
1106 | {"Greek_lambda" , 0x07eb} ,
1107 | {"Greek_mu" , 0x07ec} ,
1108 | {"Greek_nu" , 0x07ed} ,
1109 | {"Greek_xi" , 0x07ee} ,
1110 | {"Greek_omicron" , 0x07ef} ,
1111 | {"Greek_pi" , 0x07f0} ,
1112 | {"Greek_rho" , 0x07f1} ,
1113 | {"Greek_sigma" , 0x07f2} ,
1114 | {"Greek_finalsmallsigma" , 0x07f3} ,
1115 | {"Greek_tau" , 0x07f4} ,
1116 | {"Greek_upsilon" , 0x07f5} ,
1117 | {"Greek_phi" , 0x07f6} ,
1118 | {"Greek_chi" , 0x07f7} ,
1119 | {"Greek_psi" , 0x07f8} ,
1120 | {"Greek_omega" , 0x07f9} ,
1121 | {"Greek_switch" , 0xff7e} ,
1122 | #endif
1123 | #ifdef XK_TECHNICAL
1124 | {"leftradical" , 0x08a1} ,
1125 | {"topleftradical" , 0x08a2} ,
1126 | {"horizconnector" , 0x08a3} ,
1127 | {"topintegral" , 0x08a4} ,
1128 | {"botintegral" , 0x08a5} ,
1129 | {"vertconnector" , 0x08a6} ,
1130 | {"topleftsqbracket" , 0x08a7} ,
1131 | {"botleftsqbracket" , 0x08a8} ,
1132 | {"toprightsqbracket" , 0x08a9} ,
1133 | {"botrightsqbracket" , 0x08aa} ,
1134 | {"topleftparens" , 0x08ab} ,
1135 | {"botleftparens" , 0x08ac} ,
1136 | {"toprightparens" , 0x08ad} ,
1137 | {"botrightparens" , 0x08ae} ,
1138 | {"leftmiddlecurlybrace" , 0x08af} ,
1139 | {"rightmiddlecurlybrace" , 0x08b0} ,
1140 | {"topleftsummation" , 0x08b1} ,
1141 | {"botleftsummation" , 0x08b2} ,
1142 | {"topvertsummationconnector" , 0x08b3} ,
1143 | {"botvertsummationconnector" , 0x08b4} ,
1144 | {"toprightsummation" , 0x08b5} ,
1145 | {"botrightsummation" , 0x08b6} ,
1146 | {"rightmiddlesummation" , 0x08b7} ,
1147 | {"lessthanequal" , 0x08bc} ,
1148 | {"notequal" , 0x08bd} ,
1149 | {"greaterthanequal" , 0x08be} ,
1150 | {"integral" , 0x08bf} ,
1151 | {"therefore" , 0x08c0} ,
1152 | {"variation" , 0x08c1} ,
1153 | {"infinity" , 0x08c2} ,
1154 | {"nabla" , 0x08c5} ,
1155 | {"approximate" , 0x08c8} ,
1156 | {"similarequal" , 0x08c9} ,
1157 | {"ifonlyif" , 0x08cd} ,
1158 | {"implies" , 0x08ce} ,
1159 | {"identical" , 0x08cf} ,
1160 | {"radical" , 0x08d6} ,
1161 | {"includedin" , 0x08da} ,
1162 | {"includes" , 0x08db} ,
1163 | {"intersection" , 0x08dc} ,
1164 | {"union" , 0x08dd} ,
1165 | {"logicaland" , 0x08de} ,
1166 | {"logicalor" , 0x08df} ,
1167 | {"partialderivative" , 0x08ef} ,
1168 | {"function" , 0x08f6} ,
1169 | {"leftarrow" , 0x08fb} ,
1170 | {"uparrow" , 0x08fc} ,
1171 | {"rightarrow" , 0x08fd} ,
1172 | {"downarrow" , 0x08fe} ,
1173 | #endif
1174 | #ifdef XK_SPECIAL
1175 | {"blank" , 0x09df} ,
1176 | {"soliddiamond" , 0x09e0} ,
1177 | {"checkerboard" , 0x09e1} ,
1178 | {"ht" , 0x09e2} ,
1179 | {"ff" , 0x09e3} ,
1180 | {"cr" , 0x09e4} ,
1181 | {"lf" , 0x09e5} ,
1182 | {"nl" , 0x09e8} ,
1183 | {"vt" , 0x09e9} ,
1184 | {"lowrightcorner" , 0x09ea} ,
1185 | {"uprightcorner" , 0x09eb} ,
1186 | {"upleftcorner" , 0x09ec} ,
1187 | {"lowleftcorner" , 0x09ed} ,
1188 | {"crossinglines" , 0x09ee} ,
1189 | {"horizlinescan1" , 0x09ef} ,
1190 | {"horizlinescan3" , 0x09f0} ,
1191 | {"horizlinescan5" , 0x09f1} ,
1192 | {"horizlinescan7" , 0x09f2} ,
1193 | {"horizlinescan9" , 0x09f3} ,
1194 | {"leftt" , 0x09f4} ,
1195 | {"rightt" , 0x09f5} ,
1196 | {"bott" , 0x09f6} ,
1197 | {"topt" , 0x09f7} ,
1198 | {"vertbar" , 0x09f8} ,
1199 | #endif
1200 | #ifdef XK_PUBLISHING
1201 | {"emspace" , 0x0aa1} ,
1202 | {"enspace" , 0x0aa2} ,
1203 | {"em3space" , 0x0aa3} ,
1204 | {"em4space" , 0x0aa4} ,
1205 | {"digitspace" , 0x0aa5} ,
1206 | {"punctspace" , 0x0aa6} ,
1207 | {"thinspace" , 0x0aa7} ,
1208 | {"hairspace" , 0x0aa8} ,
1209 | {"emdash" , 0x0aa9} ,
1210 | {"endash" , 0x0aaa} ,
1211 | {"signifblank" , 0x0aac} ,
1212 | {"ellipsis" , 0x0aae} ,
1213 | {"doubbaselinedot" , 0x0aaf} ,
1214 | {"onethird" , 0x0ab0} ,
1215 | {"twothirds" , 0x0ab1} ,
1216 | {"onefifth" , 0x0ab2} ,
1217 | {"twofifths" , 0x0ab3} ,
1218 | {"threefifths" , 0x0ab4} ,
1219 | {"fourfifths" , 0x0ab5} ,
1220 | {"onesixth" , 0x0ab6} ,
1221 | {"fivesixths" , 0x0ab7} ,
1222 | {"careof" , 0x0ab8} ,
1223 | {"figdash" , 0x0abb} ,
1224 | {"leftanglebracket" , 0x0abc} ,
1225 | {"decimalpoint" , 0x0abd} ,
1226 | {"rightanglebracket" , 0x0abe} ,
1227 | {"marker" , 0x0abf} ,
1228 | {"oneeighth" , 0x0ac3} ,
1229 | {"threeeighths" , 0x0ac4} ,
1230 | {"fiveeighths" , 0x0ac5} ,
1231 | {"seveneighths" , 0x0ac6} ,
1232 | {"trademark" , 0x0ac9} ,
1233 | {"signaturemark" , 0x0aca} ,
1234 | {"trademarkincircle" , 0x0acb} ,
1235 | {"leftopentriangle" , 0x0acc} ,
1236 | {"rightopentriangle" , 0x0acd} ,
1237 | {"emopencircle" , 0x0ace} ,
1238 | {"emopenrectangle" , 0x0acf} ,
1239 | {"leftsinglequotemark" , 0x0ad0} ,
1240 | {"rightsinglequotemark" , 0x0ad1} ,
1241 | {"leftdoublequotemark" , 0x0ad2} ,
1242 | {"rightdoublequotemark" , 0x0ad3} ,
1243 | {"prescription" , 0x0ad4} ,
1244 | {"permille" , 0x0ad5} ,
1245 | {"minutes" , 0x0ad6} ,
1246 | {"seconds" , 0x0ad7} ,
1247 | {"latincross" , 0x0ad9} ,
1248 | {"hexagram" , 0x0ada} ,
1249 | {"filledrectbullet" , 0x0adb} ,
1250 | {"filledlefttribullet" , 0x0adc} ,
1251 | {"filledrighttribullet" , 0x0add} ,
1252 | {"emfilledcircle" , 0x0ade} ,
1253 | {"emfilledrect" , 0x0adf} ,
1254 | {"enopencircbullet" , 0x0ae0} ,
1255 | {"enopensquarebullet" , 0x0ae1} ,
1256 | {"openrectbullet" , 0x0ae2} ,
1257 | {"opentribulletup" , 0x0ae3} ,
1258 | {"opentribulletdown" , 0x0ae4} ,
1259 | {"openstar" , 0x0ae5} ,
1260 | {"enfilledcircbullet" , 0x0ae6} ,
1261 | {"enfilledsqbullet" , 0x0ae7} ,
1262 | {"filledtribulletup" , 0x0ae8} ,
1263 | {"filledtribulletdown" , 0x0ae9} ,
1264 | {"leftpointer" , 0x0aea} ,
1265 | {"rightpointer" , 0x0aeb} ,
1266 | {"club" , 0x0aec} ,
1267 | {"diamond" , 0x0aed} ,
1268 | {"heart" , 0x0aee} ,
1269 | {"maltesecross" , 0x0af0} ,
1270 | {"dagger" , 0x0af1} ,
1271 | {"doubledagger" , 0x0af2} ,
1272 | {"checkmark" , 0x0af3} ,
1273 | {"ballotcross" , 0x0af4} ,
1274 | {"musicalsharp" , 0x0af5} ,
1275 | {"musicalflat" , 0x0af6} ,
1276 | {"malesymbol" , 0x0af7} ,
1277 | {"femalesymbol" , 0x0af8} ,
1278 | {"telephone" , 0x0af9} ,
1279 | {"telephonerecorder" , 0x0afa} ,
1280 | {"phonographcopyright" , 0x0afb} ,
1281 | {"caret" , 0x0afc} ,
1282 | {"singlelowquotemark" , 0x0afd} ,
1283 | {"doublelowquotemark" , 0x0afe} ,
1284 | {"cursor" , 0x0aff} ,
1285 | #endif
1286 | #ifdef XK_APL
1287 | {"leftcaret" , 0x0ba3} ,
1288 | {"rightcaret" , 0x0ba6} ,
1289 | {"downcaret" , 0x0ba8} ,
1290 | {"upcaret" , 0x0ba9} ,
1291 | {"overbar" , 0x0bc0} ,
1292 | {"downtack" , 0x0bc2} ,
1293 | {"upshoe" , 0x0bc3} ,
1294 | {"downstile" , 0x0bc4} ,
1295 | {"underbar" , 0x0bc6} ,
1296 | {"jot" , 0x0bca} ,
1297 | {"quad" , 0x0bcc} ,
1298 | {"uptack" , 0x0bce} ,
1299 | {"circle" , 0x0bcf} ,
1300 | {"upstile" , 0x0bd3} ,
1301 | {"downshoe" , 0x0bd6} ,
1302 | {"rightshoe" , 0x0bd8} ,
1303 | {"leftshoe" , 0x0bda} ,
1304 | {"lefttack" , 0x0bdc} ,
1305 | {"righttack" , 0x0bfc} ,
1306 | #endif
1307 | #ifdef XK_HEBREW
1308 | {"hebrew_doublelowline" , 0x0cdf} ,
1309 | {"hebrew_aleph" , 0x0ce0} ,
1310 | {"hebrew_bet" , 0x0ce1} ,
1311 | {"hebrew_beth" , 0x0ce1} ,
1312 | {"hebrew_gimel" , 0x0ce2} ,
1313 | {"hebrew_gimmel" , 0x0ce2} ,
1314 | {"hebrew_dalet" , 0x0ce3} ,
1315 | {"hebrew_daleth" , 0x0ce3} ,
1316 | {"hebrew_he" , 0x0ce4} ,
1317 | {"hebrew_waw" , 0x0ce5} ,
1318 | {"hebrew_zain" , 0x0ce6} ,
1319 | {"hebrew_zayin" , 0x0ce6} ,
1320 | {"hebrew_chet" , 0x0ce7} ,
1321 | {"hebrew_het" , 0x0ce7} ,
1322 | {"hebrew_tet" , 0x0ce8} ,
1323 | {"hebrew_teth" , 0x0ce8} ,
1324 | {"hebrew_yod" , 0x0ce9} ,
1325 | {"hebrew_finalkaph" , 0x0cea} ,
1326 | {"hebrew_kaph" , 0x0ceb} ,
1327 | {"hebrew_lamed" , 0x0cec} ,
1328 | {"hebrew_finalmem" , 0x0ced} ,
1329 | {"hebrew_mem" , 0x0cee} ,
1330 | {"hebrew_finalnun" , 0x0cef} ,
1331 | {"hebrew_nun" , 0x0cf0} ,
1332 | {"hebrew_samech" , 0x0cf1} ,
1333 | {"hebrew_samekh" , 0x0cf1} ,
1334 | {"hebrew_ayin" , 0x0cf2} ,
1335 | {"hebrew_finalpe" , 0x0cf3} ,
1336 | {"hebrew_pe" , 0x0cf4} ,
1337 | {"hebrew_finalzade" , 0x0cf5} ,
1338 | {"hebrew_finalzadi" , 0x0cf5} ,
1339 | {"hebrew_zade" , 0x0cf6} ,
1340 | {"hebrew_zadi" , 0x0cf6} ,
1341 | {"hebrew_qoph" , 0x0cf7} ,
1342 | {"hebrew_kuf" , 0x0cf7} ,
1343 | {"hebrew_resh" , 0x0cf8} ,
1344 | {"hebrew_shin" , 0x0cf9} ,
1345 | {"hebrew_taw" , 0x0cfa} ,
1346 | {"hebrew_taf" , 0x0cfa} ,
1347 | {"Hebrew_switch" , 0xff7e} ,
1348 | #endif
1349 | #ifdef XK_THAI
1350 | {"Thai_kokai" , 0x0da1} ,
1351 | {"Thai_khokhai" , 0x0da2} ,
1352 | {"Thai_khokhuat" , 0x0da3} ,
1353 | {"Thai_khokhwai" , 0x0da4} ,
1354 | {"Thai_khokhon" , 0x0da5} ,
1355 | {"Thai_khorakhang" , 0x0da6} ,
1356 | {"Thai_ngongu" , 0x0da7} ,
1357 | {"Thai_chochan" , 0x0da8} ,
1358 | {"Thai_choching" , 0x0da9} ,
1359 | {"Thai_chochang" , 0x0daa} ,
1360 | {"Thai_soso" , 0x0dab} ,
1361 | {"Thai_chochoe" , 0x0dac} ,
1362 | {"Thai_yoying" , 0x0dad} ,
1363 | {"Thai_dochada" , 0x0dae} ,
1364 | {"Thai_topatak" , 0x0daf} ,
1365 | {"Thai_thothan" , 0x0db0} ,
1366 | {"Thai_thonangmontho" , 0x0db1} ,
1367 | {"Thai_thophuthao" , 0x0db2} ,
1368 | {"Thai_nonen" , 0x0db3} ,
1369 | {"Thai_dodek" , 0x0db4} ,
1370 | {"Thai_totao" , 0x0db5} ,
1371 | {"Thai_thothung" , 0x0db6} ,
1372 | {"Thai_thothahan" , 0x0db7} ,
1373 | {"Thai_thothong" , 0x0db8} ,
1374 | {"Thai_nonu" , 0x0db9} ,
1375 | {"Thai_bobaimai" , 0x0dba} ,
1376 | {"Thai_popla" , 0x0dbb} ,
1377 | {"Thai_phophung" , 0x0dbc} ,
1378 | {"Thai_fofa" , 0x0dbd} ,
1379 | {"Thai_phophan" , 0x0dbe} ,
1380 | {"Thai_fofan" , 0x0dbf} ,
1381 | {"Thai_phosamphao" , 0x0dc0} ,
1382 | {"Thai_moma" , 0x0dc1} ,
1383 | {"Thai_yoyak" , 0x0dc2} ,
1384 | {"Thai_rorua" , 0x0dc3} ,
1385 | {"Thai_ru" , 0x0dc4} ,
1386 | {"Thai_loling" , 0x0dc5} ,
1387 | {"Thai_lu" , 0x0dc6} ,
1388 | {"Thai_wowaen" , 0x0dc7} ,
1389 | {"Thai_sosala" , 0x0dc8} ,
1390 | {"Thai_sorusi" , 0x0dc9} ,
1391 | {"Thai_sosua" , 0x0dca} ,
1392 | {"Thai_hohip" , 0x0dcb} ,
1393 | {"Thai_lochula" , 0x0dcc} ,
1394 | {"Thai_oang" , 0x0dcd} ,
1395 | {"Thai_honokhuk" , 0x0dce} ,
1396 | {"Thai_paiyannoi" , 0x0dcf} ,
1397 | {"Thai_saraa" , 0x0dd0} ,
1398 | {"Thai_maihanakat" , 0x0dd1} ,
1399 | {"Thai_saraaa" , 0x0dd2} ,
1400 | {"Thai_saraam" , 0x0dd3} ,
1401 | {"Thai_sarai" , 0x0dd4} ,
1402 | {"Thai_saraii" , 0x0dd5} ,
1403 | {"Thai_saraue" , 0x0dd6} ,
1404 | {"Thai_sarauee" , 0x0dd7} ,
1405 | {"Thai_sarau" , 0x0dd8} ,
1406 | {"Thai_sarauu" , 0x0dd9} ,
1407 | {"Thai_phinthu" , 0x0dda} ,
1408 | {"Thai_maihanakat_maitho" , 0x0dde} ,
1409 | {"Thai_baht" , 0x0ddf} ,
1410 | {"Thai_sarae" , 0x0de0} ,
1411 | {"Thai_saraae" , 0x0de1} ,
1412 | {"Thai_sarao" , 0x0de2} ,
1413 | {"Thai_saraaimaimuan" , 0x0de3} ,
1414 | {"Thai_saraaimaimalai" , 0x0de4} ,
1415 | {"Thai_lakkhangyao" , 0x0de5} ,
1416 | {"Thai_maiyamok" , 0x0de6} ,
1417 | {"Thai_maitaikhu" , 0x0de7} ,
1418 | {"Thai_maiek" , 0x0de8} ,
1419 | {"Thai_maitho" , 0x0de9} ,
1420 | {"Thai_maitri" , 0x0dea} ,
1421 | {"Thai_maichattawa" , 0x0deb} ,
1422 | {"Thai_thanthakhat" , 0x0dec} ,
1423 | {"Thai_nikhahit" , 0x0ded} ,
1424 | {"Thai_leksun" , 0x0df0} ,
1425 | {"Thai_leknung" , 0x0df1} ,
1426 | {"Thai_leksong" , 0x0df2} ,
1427 | {"Thai_leksam" , 0x0df3} ,
1428 | {"Thai_leksi" , 0x0df4} ,
1429 | {"Thai_lekha" , 0x0df5} ,
1430 | {"Thai_lekhok" , 0x0df6} ,
1431 | {"Thai_lekchet" , 0x0df7} ,
1432 | {"Thai_lekpaet" , 0x0df8} ,
1433 | {"Thai_lekkao" , 0x0df9} ,
1434 | #endif
1435 | #ifdef XK_KOREAN
1436 | {"Hangul" , 0xff31} ,
1437 | {"Hangul_Start" , 0xff32} ,
1438 | {"Hangul_End" , 0xff33} ,
1439 | {"Hangul_Hanja" , 0xff34} ,
1440 | {"Hangul_Jamo" , 0xff35} ,
1441 | {"Hangul_Romaja" , 0xff36} ,
1442 | {"Hangul_Codeinput" , 0xff37} ,
1443 | {"Hangul_Jeonja" , 0xff38} ,
1444 | {"Hangul_Banja" , 0xff39} ,
1445 | {"Hangul_PreHanja" , 0xff3a} ,
1446 | {"Hangul_PostHanja" , 0xff3b} ,
1447 | {"Hangul_SingleCandidate" , 0xff3c} ,
1448 | {"Hangul_MultipleCandidate" , 0xff3d} ,
1449 | {"Hangul_PreviousCandidate" , 0xff3e} ,
1450 | {"Hangul_Special" , 0xff3f} ,
1451 | {"Hangul_switch" , 0xff7e} ,
1452 | {"Hangul_Kiyeog" , 0x0ea1} ,
1453 | {"Hangul_SsangKiyeog" , 0x0ea2} ,
1454 | {"Hangul_KiyeogSios" , 0x0ea3} ,
1455 | {"Hangul_Nieun" , 0x0ea4} ,
1456 | {"Hangul_NieunJieuj" , 0x0ea5} ,
1457 | {"Hangul_NieunHieuh" , 0x0ea6} ,
1458 | {"Hangul_Dikeud" , 0x0ea7} ,
1459 | {"Hangul_SsangDikeud" , 0x0ea8} ,
1460 | {"Hangul_Rieul" , 0x0ea9} ,
1461 | {"Hangul_RieulKiyeog" , 0x0eaa} ,
1462 | {"Hangul_RieulMieum" , 0x0eab} ,
1463 | {"Hangul_RieulPieub" , 0x0eac} ,
1464 | {"Hangul_RieulSios" , 0x0ead} ,
1465 | {"Hangul_RieulTieut" , 0x0eae} ,
1466 | {"Hangul_RieulPhieuf" , 0x0eaf} ,
1467 | {"Hangul_RieulHieuh" , 0x0eb0} ,
1468 | {"Hangul_Mieum" , 0x0eb1} ,
1469 | {"Hangul_Pieub" , 0x0eb2} ,
1470 | {"Hangul_SsangPieub" , 0x0eb3} ,
1471 | {"Hangul_PieubSios" , 0x0eb4} ,
1472 | {"Hangul_Sios" , 0x0eb5} ,
1473 | {"Hangul_SsangSios" , 0x0eb6} ,
1474 | {"Hangul_Ieung" , 0x0eb7} ,
1475 | {"Hangul_Jieuj" , 0x0eb8} ,
1476 | {"Hangul_SsangJieuj" , 0x0eb9} ,
1477 | {"Hangul_Cieuc" , 0x0eba} ,
1478 | {"Hangul_Khieuq" , 0x0ebb} ,
1479 | {"Hangul_Tieut" , 0x0ebc} ,
1480 | {"Hangul_Phieuf" , 0x0ebd} ,
1481 | {"Hangul_Hieuh" , 0x0ebe} ,
1482 | {"Hangul_A" , 0x0ebf} ,
1483 | {"Hangul_AE" , 0x0ec0} ,
1484 | {"Hangul_YA" , 0x0ec1} ,
1485 | {"Hangul_YAE" , 0x0ec2} ,
1486 | {"Hangul_EO" , 0x0ec3} ,
1487 | {"Hangul_E" , 0x0ec4} ,
1488 | {"Hangul_YEO" , 0x0ec5} ,
1489 | {"Hangul_YE" , 0x0ec6} ,
1490 | {"Hangul_O" , 0x0ec7} ,
1491 | {"Hangul_WA" , 0x0ec8} ,
1492 | {"Hangul_WAE" , 0x0ec9} ,
1493 | {"Hangul_OE" , 0x0eca} ,
1494 | {"Hangul_YO" , 0x0ecb} ,
1495 | {"Hangul_U" , 0x0ecc} ,
1496 | {"Hangul_WEO" , 0x0ecd} ,
1497 | {"Hangul_WE" , 0x0ece} ,
1498 | {"Hangul_WI" , 0x0ecf} ,
1499 | {"Hangul_YU" , 0x0ed0} ,
1500 | {"Hangul_EU" , 0x0ed1} ,
1501 | {"Hangul_YI" , 0x0ed2} ,
1502 | {"Hangul_I" , 0x0ed3} ,
1503 | {"Hangul_J_Kiyeog" , 0x0ed4} ,
1504 | {"Hangul_J_SsangKiyeog" , 0x0ed5} ,
1505 | {"Hangul_J_KiyeogSios" , 0x0ed6} ,
1506 | {"Hangul_J_Nieun" , 0x0ed7} ,
1507 | {"Hangul_J_NieunJieuj" , 0x0ed8} ,
1508 | {"Hangul_J_NieunHieuh" , 0x0ed9} ,
1509 | {"Hangul_J_Dikeud" , 0x0eda} ,
1510 | {"Hangul_J_Rieul" , 0x0edb} ,
1511 | {"Hangul_J_RieulKiyeog" , 0x0edc} ,
1512 | {"Hangul_J_RieulMieum" , 0x0edd} ,
1513 | {"Hangul_J_RieulPieub" , 0x0ede} ,
1514 | {"Hangul_J_RieulSios" , 0x0edf} ,
1515 | {"Hangul_J_RieulTieut" , 0x0ee0} ,
1516 | {"Hangul_J_RieulPhieuf" , 0x0ee1} ,
1517 | {"Hangul_J_RieulHieuh" , 0x0ee2} ,
1518 | {"Hangul_J_Mieum" , 0x0ee3} ,
1519 | {"Hangul_J_Pieub" , 0x0ee4} ,
1520 | {"Hangul_J_PieubSios" , 0x0ee5} ,
1521 | {"Hangul_J_Sios" , 0x0ee6} ,
1522 | {"Hangul_J_SsangSios" , 0x0ee7} ,
1523 | {"Hangul_J_Ieung" , 0x0ee8} ,
1524 | {"Hangul_J_Jieuj" , 0x0ee9} ,
1525 | {"Hangul_J_Cieuc" , 0x0eea} ,
1526 | {"Hangul_J_Khieuq" , 0x0eeb} ,
1527 | {"Hangul_J_Tieut" , 0x0eec} ,
1528 | {"Hangul_J_Phieuf" , 0x0eed} ,
1529 | {"Hangul_J_Hieuh" , 0x0eee} ,
1530 | {"Hangul_RieulYeorinHieuh" , 0x0eef} ,
1531 | {"Hangul_SunkyeongeumMieum" , 0x0ef0} ,
1532 | {"Hangul_SunkyeongeumPieub" , 0x0ef1} ,
1533 | {"Hangul_PanSios" , 0x0ef2} ,
1534 | {"Hangul_KkogjiDalrinIeung" , 0x0ef3} ,
1535 | {"Hangul_SunkyeongeumPhieuf" , 0x0ef4} ,
1536 | {"Hangul_YeorinHieuh" , 0x0ef5} ,
1537 | {"Hangul_AraeA" , 0x0ef6} ,
1538 | {"Hangul_AraeAE" , 0x0ef7} ,
1539 | {"Hangul_J_PanSios" , 0x0ef8} ,
1540 | {"Hangul_J_KkogjiDalrinIeung" , 0x0ef9} ,
1541 | {"Hangul_J_YeorinHieuh" , 0x0efa} ,
1542 | {"Korean_Won" , 0x0eff} ,
1543 | #endif
1544 | #ifdef XK_ARMENIAN
1545 | {"Armenian_ligature_ew" , 0x1000587} ,
1546 | {"Armenian_full_stop" , 0x1000589} ,
1547 | {"Armenian_verjaket" , 0x1000589} ,
1548 | {"Armenian_separation_mark" , 0x100055d} ,
1549 | {"Armenian_but" , 0x100055d} ,
1550 | {"Armenian_hyphen" , 0x100058a} ,
1551 | {"Armenian_yentamna" , 0x100058a} ,
1552 | {"Armenian_exclam" , 0x100055c} ,
1553 | {"Armenian_amanak" , 0x100055c} ,
1554 | {"Armenian_accent" , 0x100055b} ,
1555 | {"Armenian_shesht" , 0x100055b} ,
1556 | {"Armenian_question" , 0x100055e} ,
1557 | {"Armenian_paruyk" , 0x100055e} ,
1558 | {"Armenian_AYB" , 0x1000531} ,
1559 | {"Armenian_ayb" , 0x1000561} ,
1560 | {"Armenian_BEN" , 0x1000532} ,
1561 | {"Armenian_ben" , 0x1000562} ,
1562 | {"Armenian_GIM" , 0x1000533} ,
1563 | {"Armenian_gim" , 0x1000563} ,
1564 | {"Armenian_DA" , 0x1000534} ,
1565 | {"Armenian_da" , 0x1000564} ,
1566 | {"Armenian_YECH" , 0x1000535} ,
1567 | {"Armenian_yech" , 0x1000565} ,
1568 | {"Armenian_ZA" , 0x1000536} ,
1569 | {"Armenian_za" , 0x1000566} ,
1570 | {"Armenian_E" , 0x1000537} ,
1571 | {"Armenian_e" , 0x1000567} ,
1572 | {"Armenian_AT" , 0x1000538} ,
1573 | {"Armenian_at" , 0x1000568} ,
1574 | {"Armenian_TO" , 0x1000539} ,
1575 | {"Armenian_to" , 0x1000569} ,
1576 | {"Armenian_ZHE" , 0x100053a} ,
1577 | {"Armenian_zhe" , 0x100056a} ,
1578 | {"Armenian_INI" , 0x100053b} ,
1579 | {"Armenian_ini" , 0x100056b} ,
1580 | {"Armenian_LYUN" , 0x100053c} ,
1581 | {"Armenian_lyun" , 0x100056c} ,
1582 | {"Armenian_KHE" , 0x100053d} ,
1583 | {"Armenian_khe" , 0x100056d} ,
1584 | {"Armenian_TSA" , 0x100053e} ,
1585 | {"Armenian_tsa" , 0x100056e} ,
1586 | {"Armenian_KEN" , 0x100053f} ,
1587 | {"Armenian_ken" , 0x100056f} ,
1588 | {"Armenian_HO" , 0x1000540} ,
1589 | {"Armenian_ho" , 0x1000570} ,
1590 | {"Armenian_DZA" , 0x1000541} ,
1591 | {"Armenian_dza" , 0x1000571} ,
1592 | {"Armenian_GHAT" , 0x1000542} ,
1593 | {"Armenian_ghat" , 0x1000572} ,
1594 | {"Armenian_TCHE" , 0x1000543} ,
1595 | {"Armenian_tche" , 0x1000573} ,
1596 | {"Armenian_MEN" , 0x1000544} ,
1597 | {"Armenian_men" , 0x1000574} ,
1598 | {"Armenian_HI" , 0x1000545} ,
1599 | {"Armenian_hi" , 0x1000575} ,
1600 | {"Armenian_NU" , 0x1000546} ,
1601 | {"Armenian_nu" , 0x1000576} ,
1602 | {"Armenian_SHA" , 0x1000547} ,
1603 | {"Armenian_sha" , 0x1000577} ,
1604 | {"Armenian_VO" , 0x1000548} ,
1605 | {"Armenian_vo" , 0x1000578} ,
1606 | {"Armenian_CHA" , 0x1000549} ,
1607 | {"Armenian_cha" , 0x1000579} ,
1608 | {"Armenian_PE" , 0x100054a} ,
1609 | {"Armenian_pe" , 0x100057a} ,
1610 | {"Armenian_JE" , 0x100054b} ,
1611 | {"Armenian_je" , 0x100057b} ,
1612 | {"Armenian_RA" , 0x100054c} ,
1613 | {"Armenian_ra" , 0x100057c} ,
1614 | {"Armenian_SE" , 0x100054d} ,
1615 | {"Armenian_se" , 0x100057d} ,
1616 | {"Armenian_VEV" , 0x100054e} ,
1617 | {"Armenian_vev" , 0x100057e} ,
1618 | {"Armenian_TYUN" , 0x100054f} ,
1619 | {"Armenian_tyun" , 0x100057f} ,
1620 | {"Armenian_RE" , 0x1000550} ,
1621 | {"Armenian_re" , 0x1000580} ,
1622 | {"Armenian_TSO" , 0x1000551} ,
1623 | {"Armenian_tso" , 0x1000581} ,
1624 | {"Armenian_VYUN" , 0x1000552} ,
1625 | {"Armenian_vyun" , 0x1000582} ,
1626 | {"Armenian_PYUR" , 0x1000553} ,
1627 | {"Armenian_pyur" , 0x1000583} ,
1628 | {"Armenian_KE" , 0x1000554} ,
1629 | {"Armenian_ke" , 0x1000584} ,
1630 | {"Armenian_O" , 0x1000555} ,
1631 | {"Armenian_o" , 0x1000585} ,
1632 | {"Armenian_FE" , 0x1000556} ,
1633 | {"Armenian_fe" , 0x1000586} ,
1634 | {"Armenian_apostrophe" , 0x100055a} ,
1635 | #endif
1636 | #ifdef XK_GEORGIAN
1637 | {"Georgian_an" , 0x10010d0} ,
1638 | {"Georgian_ban" , 0x10010d1} ,
1639 | {"Georgian_gan" , 0x10010d2} ,
1640 | {"Georgian_don" , 0x10010d3} ,
1641 | {"Georgian_en" , 0x10010d4} ,
1642 | {"Georgian_vin" , 0x10010d5} ,
1643 | {"Georgian_zen" , 0x10010d6} ,
1644 | {"Georgian_tan" , 0x10010d7} ,
1645 | {"Georgian_in" , 0x10010d8} ,
1646 | {"Georgian_kan" , 0x10010d9} ,
1647 | {"Georgian_las" , 0x10010da} ,
1648 | {"Georgian_man" , 0x10010db} ,
1649 | {"Georgian_nar" , 0x10010dc} ,
1650 | {"Georgian_on" , 0x10010dd} ,
1651 | {"Georgian_par" , 0x10010de} ,
1652 | {"Georgian_zhar" , 0x10010df} ,
1653 | {"Georgian_rae" , 0x10010e0} ,
1654 | {"Georgian_san" , 0x10010e1} ,
1655 | {"Georgian_tar" , 0x10010e2} ,
1656 | {"Georgian_un" , 0x10010e3} ,
1657 | {"Georgian_phar" , 0x10010e4} ,
1658 | {"Georgian_khar" , 0x10010e5} ,
1659 | {"Georgian_ghan" , 0x10010e6} ,
1660 | {"Georgian_qar" , 0x10010e7} ,
1661 | {"Georgian_shin" , 0x10010e8} ,
1662 | {"Georgian_chin" , 0x10010e9} ,
1663 | {"Georgian_can" , 0x10010ea} ,
1664 | {"Georgian_jil" , 0x10010eb} ,
1665 | {"Georgian_cil" , 0x10010ec} ,
1666 | {"Georgian_char" , 0x10010ed} ,
1667 | {"Georgian_xan" , 0x10010ee} ,
1668 | {"Georgian_jhan" , 0x10010ef} ,
1669 | {"Georgian_hae" , 0x10010f0} ,
1670 | {"Georgian_he" , 0x10010f1} ,
1671 | {"Georgian_hie" , 0x10010f2} ,
1672 | {"Georgian_we" , 0x10010f3} ,
1673 | {"Georgian_har" , 0x10010f4} ,
1674 | {"Georgian_hoe" , 0x10010f5} ,
1675 | {"Georgian_fi" , 0x10010f6} ,
1676 | #endif
1677 | #ifdef XK_CAUCASUS
1678 | {"Xabovedot" , 0x1001e8a} ,
1679 | {"Ibreve" , 0x100012c} ,
1680 | {"Zstroke" , 0x10001b5} ,
1681 | {"Gcaron" , 0x10001e6} ,
1682 | {"Ocaron" , 0x10001d1} ,
1683 | {"Obarred" , 0x100019f} ,
1684 | {"xabovedot" , 0x1001e8b} ,
1685 | {"ibreve" , 0x100012d} ,
1686 | {"zstroke" , 0x10001b6} ,
1687 | {"gcaron" , 0x10001e7} ,
1688 | {"ocaron" , 0x10001d2} ,
1689 | {"obarred" , 0x1000275} ,
1690 | {"SCHWA" , 0x100018f} ,
1691 | {"schwa" , 0x1000259} ,
1692 | {"EZH" , 0x10001b7} ,
1693 | {"ezh" , 0x1000292} ,
1694 | {"Lbelowdot" , 0x1001e36} ,
1695 | {"lbelowdot" , 0x1001e37} ,
1696 | #endif
1697 | #ifdef XK_VIETNAMESE
1698 | {"Abelowdot" , 0x1001ea0} ,
1699 | {"abelowdot" , 0x1001ea1} ,
1700 | {"Ahook" , 0x1001ea2} ,
1701 | {"ahook" , 0x1001ea3} ,
1702 | {"Acircumflexacute" , 0x1001ea4} ,
1703 | {"acircumflexacute" , 0x1001ea5} ,
1704 | {"Acircumflexgrave" , 0x1001ea6} ,
1705 | {"acircumflexgrave" , 0x1001ea7} ,
1706 | {"Acircumflexhook" , 0x1001ea8} ,
1707 | {"acircumflexhook" , 0x1001ea9} ,
1708 | {"Acircumflextilde" , 0x1001eaa} ,
1709 | {"acircumflextilde" , 0x1001eab} ,
1710 | {"Acircumflexbelowdot" , 0x1001eac} ,
1711 | {"acircumflexbelowdot" , 0x1001ead} ,
1712 | {"Abreveacute" , 0x1001eae} ,
1713 | {"abreveacute" , 0x1001eaf} ,
1714 | {"Abrevegrave" , 0x1001eb0} ,
1715 | {"abrevegrave" , 0x1001eb1} ,
1716 | {"Abrevehook" , 0x1001eb2} ,
1717 | {"abrevehook" , 0x1001eb3} ,
1718 | {"Abrevetilde" , 0x1001eb4} ,
1719 | {"abrevetilde" , 0x1001eb5} ,
1720 | {"Abrevebelowdot" , 0x1001eb6} ,
1721 | {"abrevebelowdot" , 0x1001eb7} ,
1722 | {"Ebelowdot" , 0x1001eb8} ,
1723 | {"ebelowdot" , 0x1001eb9} ,
1724 | {"Ehook" , 0x1001eba} ,
1725 | {"ehook" , 0x1001ebb} ,
1726 | {"Etilde" , 0x1001ebc} ,
1727 | {"etilde" , 0x1001ebd} ,
1728 | {"Ecircumflexacute" , 0x1001ebe} ,
1729 | {"ecircumflexacute" , 0x1001ebf} ,
1730 | {"Ecircumflexgrave" , 0x1001ec0} ,
1731 | {"ecircumflexgrave" , 0x1001ec1} ,
1732 | {"Ecircumflexhook" , 0x1001ec2} ,
1733 | {"ecircumflexhook" , 0x1001ec3} ,
1734 | {"Ecircumflextilde" , 0x1001ec4} ,
1735 | {"ecircumflextilde" , 0x1001ec5} ,
1736 | {"Ecircumflexbelowdot" , 0x1001ec6} ,
1737 | {"ecircumflexbelowdot" , 0x1001ec7} ,
1738 | {"Ihook" , 0x1001ec8} ,
1739 | {"ihook" , 0x1001ec9} ,
1740 | {"Ibelowdot" , 0x1001eca} ,
1741 | {"ibelowdot" , 0x1001ecb} ,
1742 | {"Obelowdot" , 0x1001ecc} ,
1743 | {"obelowdot" , 0x1001ecd} ,
1744 | {"Ohook" , 0x1001ece} ,
1745 | {"ohook" , 0x1001ecf} ,
1746 | {"Ocircumflexacute" , 0x1001ed0} ,
1747 | {"ocircumflexacute" , 0x1001ed1} ,
1748 | {"Ocircumflexgrave" , 0x1001ed2} ,
1749 | {"ocircumflexgrave" , 0x1001ed3} ,
1750 | {"Ocircumflexhook" , 0x1001ed4} ,
1751 | {"ocircumflexhook" , 0x1001ed5} ,
1752 | {"Ocircumflextilde" , 0x1001ed6} ,
1753 | {"ocircumflextilde" , 0x1001ed7} ,
1754 | {"Ocircumflexbelowdot" , 0x1001ed8} ,
1755 | {"ocircumflexbelowdot" , 0x1001ed9} ,
1756 | {"Ohornacute" , 0x1001eda} ,
1757 | {"ohornacute" , 0x1001edb} ,
1758 | {"Ohorngrave" , 0x1001edc} ,
1759 | {"ohorngrave" , 0x1001edd} ,
1760 | {"Ohornhook" , 0x1001ede} ,
1761 | {"ohornhook" , 0x1001edf} ,
1762 | {"Ohorntilde" , 0x1001ee0} ,
1763 | {"ohorntilde" , 0x1001ee1} ,
1764 | {"Ohornbelowdot" , 0x1001ee2} ,
1765 | {"ohornbelowdot" , 0x1001ee3} ,
1766 | {"Ubelowdot" , 0x1001ee4} ,
1767 | {"ubelowdot" , 0x1001ee5} ,
1768 | {"Uhook" , 0x1001ee6} ,
1769 | {"uhook" , 0x1001ee7} ,
1770 | {"Uhornacute" , 0x1001ee8} ,
1771 | {"uhornacute" , 0x1001ee9} ,
1772 | {"Uhorngrave" , 0x1001eea} ,
1773 | {"uhorngrave" , 0x1001eeb} ,
1774 | {"Uhornhook" , 0x1001eec} ,
1775 | {"uhornhook" , 0x1001eed} ,
1776 | {"Uhorntilde" , 0x1001eee} ,
1777 | {"uhorntilde" , 0x1001eef} ,
1778 | {"Uhornbelowdot" , 0x1001ef0} ,
1779 | {"uhornbelowdot" , 0x1001ef1} ,
1780 | {"Ybelowdot" , 0x1001ef4} ,
1781 | {"ybelowdot" , 0x1001ef5} ,
1782 | {"Yhook" , 0x1001ef6} ,
1783 | {"yhook" , 0x1001ef7} ,
1784 | {"Ytilde" , 0x1001ef8} ,
1785 | {"ytilde" , 0x1001ef9} ,
1786 | {"Ohorn" , 0x10001a0} ,
1787 | {"ohorn" , 0x10001a1} ,
1788 | {"Uhorn" , 0x10001af} ,
1789 | {"uhorn" , 0x10001b0} ,
1790 | #endif
1791 | #ifdef XK_CURRENCY
1792 | {"EcuSign" , 0x10020a0} ,
1793 | {"ColonSign" , 0x10020a1} ,
1794 | {"CruzeiroSign" , 0x10020a2} ,
1795 | {"FFrancSign" , 0x10020a3} ,
1796 | {"LiraSign" , 0x10020a4} ,
1797 | {"MillSign" , 0x10020a5} ,
1798 | {"NairaSign" , 0x10020a6} ,
1799 | {"PesetaSign" , 0x10020a7} ,
1800 | {"RupeeSign" , 0x10020a8} ,
1801 | {"WonSign" , 0x10020a9} ,
1802 | {"NewSheqelSign" , 0x10020aa} ,
1803 | {"DongSign" , 0x10020ab} ,
1804 | {"EuroSign" , 0x20ac} ,
1805 | #endif
1806 | #ifdef XK_MATHEMATICAL
1807 | {"zerosuperior" , 0x1002070} ,
1808 | {"foursuperior" , 0x1002074} ,
1809 | {"fivesuperior" , 0x1002075} ,
1810 | {"sixsuperior" , 0x1002076} ,
1811 | {"sevensuperior" , 0x1002077} ,
1812 | {"eightsuperior" , 0x1002078} ,
1813 | {"ninesuperior" , 0x1002079} ,
1814 | {"zerosubscript" , 0x1002080} ,
1815 | {"onesubscript" , 0x1002081} ,
1816 | {"twosubscript" , 0x1002082} ,
1817 | {"threesubscript" , 0x1002083} ,
1818 | {"foursubscript" , 0x1002084} ,
1819 | {"fivesubscript" , 0x1002085} ,
1820 | {"sixsubscript" , 0x1002086} ,
1821 | {"sevensubscript" , 0x1002087} ,
1822 | {"eightsubscript" , 0x1002088} ,
1823 | {"ninesubscript" , 0x1002089} ,
1824 | {"partdifferential" , 0x1002202} ,
1825 | {"emptyset" , 0x1002205} ,
1826 | {"elementof" , 0x1002208} ,
1827 | {"notelementof" , 0x1002209} ,
1828 | {"containsas" , 0x100220B} ,
1829 | {"squareroot" , 0x100221A} ,
1830 | {"cuberoot" , 0x100221B} ,
1831 | {"fourthroot" , 0x100221C} ,
1832 | {"dintegral" , 0x100222C} ,
1833 | {"tintegral" , 0x100222D} ,
1834 | {"because" , 0x1002235} ,
1835 | {"approxeq" , 0x1002248} ,
1836 | {"notapproxeq" , 0x1002247} ,
1837 | {"notidentical" , 0x1002262} ,
1838 | {"stricteq" , 0x1002263} ,
1839 | #endif
1840 | #ifdef XK_BRAILLE
1841 | {"braille_dot_1" , 0xfff1} ,
1842 | {"braille_dot_2" , 0xfff2} ,
1843 | {"braille_dot_3" , 0xfff3} ,
1844 | {"braille_dot_4" , 0xfff4} ,
1845 | {"braille_dot_5" , 0xfff5} ,
1846 | {"braille_dot_6" , 0xfff6} ,
1847 | {"braille_dot_7" , 0xfff7} ,
1848 | {"braille_dot_8" , 0xfff8} ,
1849 | {"braille_dot_9" , 0xfff9} ,
1850 | {"braille_dot_10" , 0xfffa} ,
1851 | {"braille_blank" , 0x1002800} ,
1852 | {"braille_dots_1" , 0x1002801} ,
1853 | {"braille_dots_2" , 0x1002802} ,
1854 | {"braille_dots_12" , 0x1002803} ,
1855 | {"braille_dots_3" , 0x1002804} ,
1856 | {"braille_dots_13" , 0x1002805} ,
1857 | {"braille_dots_23" , 0x1002806} ,
1858 | {"braille_dots_123" , 0x1002807} ,
1859 | {"braille_dots_4" , 0x1002808} ,
1860 | {"braille_dots_14" , 0x1002809} ,
1861 | {"braille_dots_24" , 0x100280a} ,
1862 | {"braille_dots_124" , 0x100280b} ,
1863 | {"braille_dots_34" , 0x100280c} ,
1864 | {"braille_dots_134" , 0x100280d} ,
1865 | {"braille_dots_234" , 0x100280e} ,
1866 | {"braille_dots_1234" , 0x100280f} ,
1867 | {"braille_dots_5" , 0x1002810} ,
1868 | {"braille_dots_15" , 0x1002811} ,
1869 | {"braille_dots_25" , 0x1002812} ,
1870 | {"braille_dots_125" , 0x1002813} ,
1871 | {"braille_dots_35" , 0x1002814} ,
1872 | {"braille_dots_135" , 0x1002815} ,
1873 | {"braille_dots_235" , 0x1002816} ,
1874 | {"braille_dots_1235" , 0x1002817} ,
1875 | {"braille_dots_45" , 0x1002818} ,
1876 | {"braille_dots_145" , 0x1002819} ,
1877 | {"braille_dots_245" , 0x100281a} ,
1878 | {"braille_dots_1245" , 0x100281b} ,
1879 | {"braille_dots_345" , 0x100281c} ,
1880 | {"braille_dots_1345" , 0x100281d} ,
1881 | {"braille_dots_2345" , 0x100281e} ,
1882 | {"braille_dots_12345" , 0x100281f} ,
1883 | {"braille_dots_6" , 0x1002820} ,
1884 | {"braille_dots_16" , 0x1002821} ,
1885 | {"braille_dots_26" , 0x1002822} ,
1886 | {"braille_dots_126" , 0x1002823} ,
1887 | {"braille_dots_36" , 0x1002824} ,
1888 | {"braille_dots_136" , 0x1002825} ,
1889 | {"braille_dots_236" , 0x1002826} ,
1890 | {"braille_dots_1236" , 0x1002827} ,
1891 | {"braille_dots_46" , 0x1002828} ,
1892 | {"braille_dots_146" , 0x1002829} ,
1893 | {"braille_dots_246" , 0x100282a} ,
1894 | {"braille_dots_1246" , 0x100282b} ,
1895 | {"braille_dots_346" , 0x100282c} ,
1896 | {"braille_dots_1346" , 0x100282d} ,
1897 | {"braille_dots_2346" , 0x100282e} ,
1898 | {"braille_dots_12346" , 0x100282f} ,
1899 | {"braille_dots_56" , 0x1002830} ,
1900 | {"braille_dots_156" , 0x1002831} ,
1901 | {"braille_dots_256" , 0x1002832} ,
1902 | {"braille_dots_1256" , 0x1002833} ,
1903 | {"braille_dots_356" , 0x1002834} ,
1904 | {"braille_dots_1356" , 0x1002835} ,
1905 | {"braille_dots_2356" , 0x1002836} ,
1906 | {"braille_dots_12356" , 0x1002837} ,
1907 | {"braille_dots_456" , 0x1002838} ,
1908 | {"braille_dots_1456" , 0x1002839} ,
1909 | {"braille_dots_2456" , 0x100283a} ,
1910 | {"braille_dots_12456" , 0x100283b} ,
1911 | {"braille_dots_3456" , 0x100283c} ,
1912 | {"braille_dots_13456" , 0x100283d} ,
1913 | {"braille_dots_23456" , 0x100283e} ,
1914 | {"braille_dots_123456" , 0x100283f} ,
1915 | {"braille_dots_7" , 0x1002840} ,
1916 | {"braille_dots_17" , 0x1002841} ,
1917 | {"braille_dots_27" , 0x1002842} ,
1918 | {"braille_dots_127" , 0x1002843} ,
1919 | {"braille_dots_37" , 0x1002844} ,
1920 | {"braille_dots_137" , 0x1002845} ,
1921 | {"braille_dots_237" , 0x1002846} ,
1922 | {"braille_dots_1237" , 0x1002847} ,
1923 | {"braille_dots_47" , 0x1002848} ,
1924 | {"braille_dots_147" , 0x1002849} ,
1925 | {"braille_dots_247" , 0x100284a} ,
1926 | {"braille_dots_1247" , 0x100284b} ,
1927 | {"braille_dots_347" , 0x100284c} ,
1928 | {"braille_dots_1347" , 0x100284d} ,
1929 | {"braille_dots_2347" , 0x100284e} ,
1930 | {"braille_dots_12347" , 0x100284f} ,
1931 | {"braille_dots_57" , 0x1002850} ,
1932 | {"braille_dots_157" , 0x1002851} ,
1933 | {"braille_dots_257" , 0x1002852} ,
1934 | {"braille_dots_1257" , 0x1002853} ,
1935 | {"braille_dots_357" , 0x1002854} ,
1936 | {"braille_dots_1357" , 0x1002855} ,
1937 | {"braille_dots_2357" , 0x1002856} ,
1938 | {"braille_dots_12357" , 0x1002857} ,
1939 | {"braille_dots_457" , 0x1002858} ,
1940 | {"braille_dots_1457" , 0x1002859} ,
1941 | {"braille_dots_2457" , 0x100285a} ,
1942 | {"braille_dots_12457" , 0x100285b} ,
1943 | {"braille_dots_3457" , 0x100285c} ,
1944 | {"braille_dots_13457" , 0x100285d} ,
1945 | {"braille_dots_23457" , 0x100285e} ,
1946 | {"braille_dots_123457" , 0x100285f} ,
1947 | {"braille_dots_67" , 0x1002860} ,
1948 | {"braille_dots_167" , 0x1002861} ,
1949 | {"braille_dots_267" , 0x1002862} ,
1950 | {"braille_dots_1267" , 0x1002863} ,
1951 | {"braille_dots_367" , 0x1002864} ,
1952 | {"braille_dots_1367" , 0x1002865} ,
1953 | {"braille_dots_2367" , 0x1002866} ,
1954 | {"braille_dots_12367" , 0x1002867} ,
1955 | {"braille_dots_467" , 0x1002868} ,
1956 | {"braille_dots_1467" , 0x1002869} ,
1957 | {"braille_dots_2467" , 0x100286a} ,
1958 | {"braille_dots_12467" , 0x100286b} ,
1959 | {"braille_dots_3467" , 0x100286c} ,
1960 | {"braille_dots_13467" , 0x100286d} ,
1961 | {"braille_dots_23467" , 0x100286e} ,
1962 | {"braille_dots_123467" , 0x100286f} ,
1963 | {"braille_dots_567" , 0x1002870} ,
1964 | {"braille_dots_1567" , 0x1002871} ,
1965 | {"braille_dots_2567" , 0x1002872} ,
1966 | {"braille_dots_12567" , 0x1002873} ,
1967 | {"braille_dots_3567" , 0x1002874} ,
1968 | {"braille_dots_13567" , 0x1002875} ,
1969 | {"braille_dots_23567" , 0x1002876} ,
1970 | {"braille_dots_123567" , 0x1002877} ,
1971 | {"braille_dots_4567" , 0x1002878} ,
1972 | {"braille_dots_14567" , 0x1002879} ,
1973 | {"braille_dots_24567" , 0x100287a} ,
1974 | {"braille_dots_124567" , 0x100287b} ,
1975 | {"braille_dots_34567" , 0x100287c} ,
1976 | {"braille_dots_134567" , 0x100287d} ,
1977 | {"braille_dots_234567" , 0x100287e} ,
1978 | {"braille_dots_1234567" , 0x100287f} ,
1979 | {"braille_dots_8" , 0x1002880} ,
1980 | {"braille_dots_18" , 0x1002881} ,
1981 | {"braille_dots_28" , 0x1002882} ,
1982 | {"braille_dots_128" , 0x1002883} ,
1983 | {"braille_dots_38" , 0x1002884} ,
1984 | {"braille_dots_138" , 0x1002885} ,
1985 | {"braille_dots_238" , 0x1002886} ,
1986 | {"braille_dots_1238" , 0x1002887} ,
1987 | {"braille_dots_48" , 0x1002888} ,
1988 | {"braille_dots_148" , 0x1002889} ,
1989 | {"braille_dots_248" , 0x100288a} ,
1990 | {"braille_dots_1248" , 0x100288b} ,
1991 | {"braille_dots_348" , 0x100288c} ,
1992 | {"braille_dots_1348" , 0x100288d} ,
1993 | {"braille_dots_2348" , 0x100288e} ,
1994 | {"braille_dots_12348" , 0x100288f} ,
1995 | {"braille_dots_58" , 0x1002890} ,
1996 | {"braille_dots_158" , 0x1002891} ,
1997 | {"braille_dots_258" , 0x1002892} ,
1998 | {"braille_dots_1258" , 0x1002893} ,
1999 | {"braille_dots_358" , 0x1002894} ,
2000 | {"braille_dots_1358" , 0x1002895} ,
2001 | {"braille_dots_2358" , 0x1002896} ,
2002 | {"braille_dots_12358" , 0x1002897} ,
2003 | {"braille_dots_458" , 0x1002898} ,
2004 | {"braille_dots_1458" , 0x1002899} ,
2005 | {"braille_dots_2458" , 0x100289a} ,
2006 | {"braille_dots_12458" , 0x100289b} ,
2007 | {"braille_dots_3458" , 0x100289c} ,
2008 | {"braille_dots_13458" , 0x100289d} ,
2009 | {"braille_dots_23458" , 0x100289e} ,
2010 | {"braille_dots_123458" , 0x100289f} ,
2011 | {"braille_dots_68" , 0x10028a0} ,
2012 | {"braille_dots_168" , 0x10028a1} ,
2013 | {"braille_dots_268" , 0x10028a2} ,
2014 | {"braille_dots_1268" , 0x10028a3} ,
2015 | {"braille_dots_368" , 0x10028a4} ,
2016 | {"braille_dots_1368" , 0x10028a5} ,
2017 | {"braille_dots_2368" , 0x10028a6} ,
2018 | {"braille_dots_12368" , 0x10028a7} ,
2019 | {"braille_dots_468" , 0x10028a8} ,
2020 | {"braille_dots_1468" , 0x10028a9} ,
2021 | {"braille_dots_2468" , 0x10028aa} ,
2022 | {"braille_dots_12468" , 0x10028ab} ,
2023 | {"braille_dots_3468" , 0x10028ac} ,
2024 | {"braille_dots_13468" , 0x10028ad} ,
2025 | {"braille_dots_23468" , 0x10028ae} ,
2026 | {"braille_dots_123468" , 0x10028af} ,
2027 | {"braille_dots_568" , 0x10028b0} ,
2028 | {"braille_dots_1568" , 0x10028b1} ,
2029 | {"braille_dots_2568" , 0x10028b2} ,
2030 | {"braille_dots_12568" , 0x10028b3} ,
2031 | {"braille_dots_3568" , 0x10028b4} ,
2032 | {"braille_dots_13568" , 0x10028b5} ,
2033 | {"braille_dots_23568" , 0x10028b6} ,
2034 | {"braille_dots_123568" , 0x10028b7} ,
2035 | {"braille_dots_4568" , 0x10028b8} ,
2036 | {"braille_dots_14568" , 0x10028b9} ,
2037 | {"braille_dots_24568" , 0x10028ba} ,
2038 | {"braille_dots_124568" , 0x10028bb} ,
2039 | {"braille_dots_34568" , 0x10028bc} ,
2040 | {"braille_dots_134568" , 0x10028bd} ,
2041 | {"braille_dots_234568" , 0x10028be} ,
2042 | {"braille_dots_1234568" , 0x10028bf} ,
2043 | {"braille_dots_78" , 0x10028c0} ,
2044 | {"braille_dots_178" , 0x10028c1} ,
2045 | {"braille_dots_278" , 0x10028c2} ,
2046 | {"braille_dots_1278" , 0x10028c3} ,
2047 | {"braille_dots_378" , 0x10028c4} ,
2048 | {"braille_dots_1378" , 0x10028c5} ,
2049 | {"braille_dots_2378" , 0x10028c6} ,
2050 | {"braille_dots_12378" , 0x10028c7} ,
2051 | {"braille_dots_478" , 0x10028c8} ,
2052 | {"braille_dots_1478" , 0x10028c9} ,
2053 | {"braille_dots_2478" , 0x10028ca} ,
2054 | {"braille_dots_12478" , 0x10028cb} ,
2055 | {"braille_dots_3478" , 0x10028cc} ,
2056 | {"braille_dots_13478" , 0x10028cd} ,
2057 | {"braille_dots_23478" , 0x10028ce} ,
2058 | {"braille_dots_123478" , 0x10028cf} ,
2059 | {"braille_dots_578" , 0x10028d0} ,
2060 | {"braille_dots_1578" , 0x10028d1} ,
2061 | {"braille_dots_2578" , 0x10028d2} ,
2062 | {"braille_dots_12578" , 0x10028d3} ,
2063 | {"braille_dots_3578" , 0x10028d4} ,
2064 | {"braille_dots_13578" , 0x10028d5} ,
2065 | {"braille_dots_23578" , 0x10028d6} ,
2066 | {"braille_dots_123578" , 0x10028d7} ,
2067 | {"braille_dots_4578" , 0x10028d8} ,
2068 | {"braille_dots_14578" , 0x10028d9} ,
2069 | {"braille_dots_24578" , 0x10028da} ,
2070 | {"braille_dots_124578" , 0x10028db} ,
2071 | {"braille_dots_34578" , 0x10028dc} ,
2072 | {"braille_dots_134578" , 0x10028dd} ,
2073 | {"braille_dots_234578" , 0x10028de} ,
2074 | {"braille_dots_1234578" , 0x10028df} ,
2075 | {"braille_dots_678" , 0x10028e0} ,
2076 | {"braille_dots_1678" , 0x10028e1} ,
2077 | {"braille_dots_2678" , 0x10028e2} ,
2078 | {"braille_dots_12678" , 0x10028e3} ,
2079 | {"braille_dots_3678" , 0x10028e4} ,
2080 | {"braille_dots_13678" , 0x10028e5} ,
2081 | {"braille_dots_23678" , 0x10028e6} ,
2082 | {"braille_dots_123678" , 0x10028e7} ,
2083 | {"braille_dots_4678" , 0x10028e8} ,
2084 | {"braille_dots_14678" , 0x10028e9} ,
2085 | {"braille_dots_24678" , 0x10028ea} ,
2086 | {"braille_dots_124678" , 0x10028eb} ,
2087 | {"braille_dots_34678" , 0x10028ec} ,
2088 | {"braille_dots_134678" , 0x10028ed} ,
2089 | {"braille_dots_234678" , 0x10028ee} ,
2090 | {"braille_dots_1234678" , 0x10028ef} ,
2091 | {"braille_dots_5678" , 0x10028f0} ,
2092 | {"braille_dots_15678" , 0x10028f1} ,
2093 | {"braille_dots_25678" , 0x10028f2} ,
2094 | {"braille_dots_125678" , 0x10028f3} ,
2095 | {"braille_dots_35678" , 0x10028f4} ,
2096 | {"braille_dots_135678" , 0x10028f5} ,
2097 | {"braille_dots_235678" , 0x10028f6} ,
2098 | {"braille_dots_1235678" , 0x10028f7} ,
2099 | {"braille_dots_45678" , 0x10028f8} ,
2100 | {"braille_dots_145678" , 0x10028f9} ,
2101 | {"braille_dots_245678" , 0x10028fa} ,
2102 | {"braille_dots_1245678" , 0x10028fb} ,
2103 | {"braille_dots_345678" , 0x10028fc} ,
2104 | {"braille_dots_1345678" , 0x10028fd} ,
2105 | {"braille_dots_2345678" , 0x10028fe} ,
2106 | {"braille_dots_12345678" , 0x10028ff} ,
2107 | #endif
2108 | #ifdef XK_SINHALA
2109 | {"Sinh_ng" , 0x1000d82} ,
2110 | {"Sinh_h2" , 0x1000d83} ,
2111 | {"Sinh_a" , 0x1000d85} ,
2112 | {"Sinh_aa" , 0x1000d86} ,
2113 | {"Sinh_ae" , 0x1000d87} ,
2114 | {"Sinh_aee" , 0x1000d88} ,
2115 | {"Sinh_i" , 0x1000d89} ,
2116 | {"Sinh_ii" , 0x1000d8a} ,
2117 | {"Sinh_u" , 0x1000d8b} ,
2118 | {"Sinh_uu" , 0x1000d8c} ,
2119 | {"Sinh_ri" , 0x1000d8d} ,
2120 | {"Sinh_rii" , 0x1000d8e} ,
2121 | {"Sinh_lu" , 0x1000d8f} ,
2122 | {"Sinh_luu" , 0x1000d90} ,
2123 | {"Sinh_e" , 0x1000d91} ,
2124 | {"Sinh_ee" , 0x1000d92} ,
2125 | {"Sinh_ai" , 0x1000d93} ,
2126 | {"Sinh_o" , 0x1000d94} ,
2127 | {"Sinh_oo" , 0x1000d95} ,
2128 | {"Sinh_au" , 0x1000d96} ,
2129 | {"Sinh_ka" , 0x1000d9a} ,
2130 | {"Sinh_kha" , 0x1000d9b} ,
2131 | {"Sinh_ga" , 0x1000d9c} ,
2132 | {"Sinh_gha" , 0x1000d9d} ,
2133 | {"Sinh_ng2" , 0x1000d9e} ,
2134 | {"Sinh_nga" , 0x1000d9f} ,
2135 | {"Sinh_ca" , 0x1000da0} ,
2136 | {"Sinh_cha" , 0x1000da1} ,
2137 | {"Sinh_ja" , 0x1000da2} ,
2138 | {"Sinh_jha" , 0x1000da3} ,
2139 | {"Sinh_nya" , 0x1000da4} ,
2140 | {"Sinh_jnya" , 0x1000da5} ,
2141 | {"Sinh_nja" , 0x1000da6} ,
2142 | {"Sinh_tta" , 0x1000da7} ,
2143 | {"Sinh_ttha" , 0x1000da8} ,
2144 | {"Sinh_dda" , 0x1000da9} ,
2145 | {"Sinh_ddha" , 0x1000daa} ,
2146 | {"Sinh_nna" , 0x1000dab} ,
2147 | {"Sinh_ndda" , 0x1000dac} ,
2148 | {"Sinh_tha" , 0x1000dad} ,
2149 | {"Sinh_thha" , 0x1000dae} ,
2150 | {"Sinh_dha" , 0x1000daf} ,
2151 | {"Sinh_dhha" , 0x1000db0} ,
2152 | {"Sinh_na" , 0x1000db1} ,
2153 | {"Sinh_ndha" , 0x1000db3} ,
2154 | {"Sinh_pa" , 0x1000db4} ,
2155 | {"Sinh_pha" , 0x1000db5} ,
2156 | {"Sinh_ba" , 0x1000db6} ,
2157 | {"Sinh_bha" , 0x1000db7} ,
2158 | {"Sinh_ma" , 0x1000db8} ,
2159 | {"Sinh_mba" , 0x1000db9} ,
2160 | {"Sinh_ya" , 0x1000dba} ,
2161 | {"Sinh_ra" , 0x1000dbb} ,
2162 | {"Sinh_la" , 0x1000dbd} ,
2163 | {"Sinh_va" , 0x1000dc0} ,
2164 | {"Sinh_sha" , 0x1000dc1} ,
2165 | {"Sinh_ssha" , 0x1000dc2} ,
2166 | {"Sinh_sa" , 0x1000dc3} ,
2167 | {"Sinh_ha" , 0x1000dc4} ,
2168 | {"Sinh_lla" , 0x1000dc5} ,
2169 | {"Sinh_fa" , 0x1000dc6} ,
2170 | {"Sinh_al" , 0x1000dca} ,
2171 | {"Sinh_aa2" , 0x1000dcf} ,
2172 | {"Sinh_ae2" , 0x1000dd0} ,
2173 | {"Sinh_aee2" , 0x1000dd1} ,
2174 | {"Sinh_i2" , 0x1000dd2} ,
2175 | {"Sinh_ii2" , 0x1000dd3} ,
2176 | {"Sinh_u2" , 0x1000dd4} ,
2177 | {"Sinh_uu2" , 0x1000dd6} ,
2178 | {"Sinh_ru2" , 0x1000dd8} ,
2179 | {"Sinh_e2" , 0x1000dd9} ,
2180 | {"Sinh_ee2" , 0x1000dda} ,
2181 | {"Sinh_ai2" , 0x1000ddb} ,
2182 | {"Sinh_o2" , 0x1000ddc} ,
2183 | {"Sinh_oo2" , 0x1000ddd} ,
2184 | {"Sinh_au2" , 0x1000dde} ,
2185 | {"Sinh_lu2" , 0x1000ddf} ,
2186 | {"Sinh_ruu2" , 0x1000df2} ,
2187 | {"Sinh_luu2" , 0x1000df3} ,
2188 | {"Sinh_kunddaliya" , 0x1000df4} ,
2189 | #endif
2190 | #ifdef XK_XFREE86
2191 | {"XF86ModeLock" , 0x1008FF01} ,
2192 | {"XF86MonBrightnessUp" , 0x1008FF02} ,
2193 | {"XF86MonBrightnessDown" , 0x1008FF03} ,
2194 | {"XF86KbdLightOnOff" , 0x1008FF04} ,
2195 | {"XF86KbdBrightnessUp" , 0x1008FF05} ,
2196 | {"XF86KbdBrightnessDown" , 0x1008FF06} ,
2197 | {"XF86Standby" , 0x1008FF10} ,
2198 | {"XF86AudioLowerVolume" , 0x1008FF11} ,
2199 | {"XF86AudioMute" , 0x1008FF12} ,
2200 | {"XF86AudioRaiseVolume" , 0x1008FF13} ,
2201 | {"XF86AudioPlay" , 0x1008FF14} ,
2202 | {"XF86AudioStop" , 0x1008FF15} ,
2203 | {"XF86AudioPrev" , 0x1008FF16} ,
2204 | {"XF86AudioNext" , 0x1008FF17} ,
2205 | {"XF86HomePage" , 0x1008FF18} ,
2206 | {"XF86Mail" , 0x1008FF19} ,
2207 | {"XF86Start" , 0x1008FF1A} ,
2208 | {"XF86Search" , 0x1008FF1B} ,
2209 | {"XF86AudioRecord" , 0x1008FF1C} ,
2210 | {"XF86Calculator" , 0x1008FF1D} ,
2211 | {"XF86Memo" , 0x1008FF1E} ,
2212 | {"XF86ToDoList" , 0x1008FF1F} ,
2213 | {"XF86Calendar" , 0x1008FF20} ,
2214 | {"XF86PowerDown" , 0x1008FF21} ,
2215 | {"XF86ContrastAdjust" , 0x1008FF22} ,
2216 | {"XF86RockerUp" , 0x1008FF23} ,
2217 | {"XF86RockerDown" , 0x1008FF24} ,
2218 | {"XF86RockerEnter" , 0x1008FF25} ,
2219 | {"XF86Back" , 0x1008FF26} ,
2220 | {"XF86Forward" , 0x1008FF27} ,
2221 | {"XF86Stop" , 0x1008FF28} ,
2222 | {"XF86Refresh" , 0x1008FF29} ,
2223 | {"XF86PowerOff" , 0x1008FF2A} ,
2224 | {"XF86WakeUp" , 0x1008FF2B} ,
2225 | {"XF86Eject" , 0x1008FF2C} ,
2226 | {"XF86ScreenSaver" , 0x1008FF2D} ,
2227 | {"XF86WWW" , 0x1008FF2E} ,
2228 | {"XF86Sleep" , 0x1008FF2F} ,
2229 | {"XF86Favorites" , 0x1008FF30} ,
2230 | {"XF86AudioPause" , 0x1008FF31} ,
2231 | {"XF86AudioMedia" , 0x1008FF32} ,
2232 | {"XF86MyComputer" , 0x1008FF33} ,
2233 | {"XF86VendorHome" , 0x1008FF34} ,
2234 | {"XF86LightBulb" , 0x1008FF35} ,
2235 | {"XF86Shop" , 0x1008FF36} ,
2236 | {"XF86History" , 0x1008FF37} ,
2237 | {"XF86OpenURL" , 0x1008FF38} ,
2238 | {"XF86AddFavorite" , 0x1008FF39} ,
2239 | {"XF86HotLinks" , 0x1008FF3A} ,
2240 | {"XF86BrightnessAdjust" , 0x1008FF3B} ,
2241 | {"XF86Finance" , 0x1008FF3C} ,
2242 | {"XF86Community" , 0x1008FF3D} ,
2243 | {"XF86AudioRewind" , 0x1008FF3E} ,
2244 | {"XF86BackForward" , 0x1008FF3F} ,
2245 | {"XF86Launch0" , 0x1008FF40} ,
2246 | {"XF86Launch1" , 0x1008FF41} ,
2247 | {"XF86Launch2" , 0x1008FF42} ,
2248 | {"XF86Launch3" , 0x1008FF43} ,
2249 | {"XF86Launch4" , 0x1008FF44} ,
2250 | {"XF86Launch5" , 0x1008FF45} ,
2251 | {"XF86Launch6" , 0x1008FF46} ,
2252 | {"XF86Launch7" , 0x1008FF47} ,
2253 | {"XF86Launch8" , 0x1008FF48} ,
2254 | {"XF86Launch9" , 0x1008FF49} ,
2255 | {"XF86LaunchA" , 0x1008FF4A} ,
2256 | {"XF86LaunchB" , 0x1008FF4B} ,
2257 | {"XF86LaunchC" , 0x1008FF4C} ,
2258 | {"XF86LaunchD" , 0x1008FF4D} ,
2259 | {"XF86LaunchE" , 0x1008FF4E} ,
2260 | {"XF86LaunchF" , 0x1008FF4F} ,
2261 | {"XF86ApplicationLeft" , 0x1008FF50} ,
2262 | {"XF86ApplicationRight" , 0x1008FF51} ,
2263 | {"XF86Book" , 0x1008FF52} ,
2264 | {"XF86CD" , 0x1008FF53} ,
2265 | {"XF86Calculater" , 0x1008FF54} ,
2266 | {"XF86Clear" , 0x1008FF55} ,
2267 | {"XF86Close" , 0x1008FF56} ,
2268 | {"XF86Copy" , 0x1008FF57} ,
2269 | {"XF86Cut" , 0x1008FF58} ,
2270 | {"XF86Display" , 0x1008FF59} ,
2271 | {"XF86DOS" , 0x1008FF5A} ,
2272 | {"XF86Documents" , 0x1008FF5B} ,
2273 | {"XF86Excel" , 0x1008FF5C} ,
2274 | {"XF86Explorer" , 0x1008FF5D} ,
2275 | {"XF86Game" , 0x1008FF5E} ,
2276 | {"XF86Go" , 0x1008FF5F} ,
2277 | {"XF86iTouch" , 0x1008FF60} ,
2278 | {"XF86LogOff" , 0x1008FF61} ,
2279 | {"XF86Market" , 0x1008FF62} ,
2280 | {"XF86Meeting" , 0x1008FF63} ,
2281 | {"XF86MenuKB" , 0x1008FF65} ,
2282 | {"XF86MenuPB" , 0x1008FF66} ,
2283 | {"XF86MySites" , 0x1008FF67} ,
2284 | {"XF86New" , 0x1008FF68} ,
2285 | {"XF86News" , 0x1008FF69} ,
2286 | {"XF86OfficeHome" , 0x1008FF6A} ,
2287 | {"XF86Open" , 0x1008FF6B} ,
2288 | {"XF86Option" , 0x1008FF6C} ,
2289 | {"XF86Paste" , 0x1008FF6D} ,
2290 | {"XF86Phone" , 0x1008FF6E} ,
2291 | {"XF86Q" , 0x1008FF70} ,
2292 | {"XF86Reply" , 0x1008FF72} ,
2293 | {"XF86Reload" , 0x1008FF73} ,
2294 | {"XF86RotateWindows" , 0x1008FF74} ,
2295 | {"XF86RotationPB" , 0x1008FF75} ,
2296 | {"XF86RotationKB" , 0x1008FF76} ,
2297 | {"XF86Save" , 0x1008FF77} ,
2298 | {"XF86ScrollUp" , 0x1008FF78} ,
2299 | {"XF86ScrollDown" , 0x1008FF79} ,
2300 | {"XF86ScrollClick" , 0x1008FF7A} ,
2301 | {"XF86Send" , 0x1008FF7B} ,
2302 | {"XF86Spell" , 0x1008FF7C} ,
2303 | {"XF86SplitScreen" , 0x1008FF7D} ,
2304 | {"XF86Support" , 0x1008FF7E} ,
2305 | {"XF86TaskPane" , 0x1008FF7F} ,
2306 | {"XF86Terminal" , 0x1008FF80} ,
2307 | {"XF86Tools" , 0x1008FF81} ,
2308 | {"XF86Travel" , 0x1008FF82} ,
2309 | {"XF86UserPB" , 0x1008FF84} ,
2310 | {"XF86User1KB" , 0x1008FF85} ,
2311 | {"XF86User2KB" , 0x1008FF86} ,
2312 | {"XF86Video" , 0x1008FF87} ,
2313 | {"XF86WheelButton" , 0x1008FF88} ,
2314 | {"XF86Word" , 0x1008FF89} ,
2315 | {"XF86Xfer" , 0x1008FF8A} ,
2316 | {"XF86ZoomIn" , 0x1008FF8B} ,
2317 | {"XF86ZoomOut" , 0x1008FF8C} ,
2318 | {"XF86Away" , 0x1008FF8D} ,
2319 | {"XF86Messenger" , 0x1008FF8E} ,
2320 | {"XF86WebCam" , 0x1008FF8F} ,
2321 | {"XF86MailForward" , 0x1008FF90} ,
2322 | {"XF86Pictures" , 0x1008FF91} ,
2323 | {"XF86Music" , 0x1008FF92} ,
2324 | {"XF86Battery" , 0x1008FF93} ,
2325 | {"XF86Bluetooth" , 0x1008FF94} ,
2326 | {"XF86WLAN" , 0x1008FF95} ,
2327 | {"XF86UWB" , 0x1008FF96} ,
2328 | {"XF86AudioForward" , 0x1008FF97} ,
2329 | {"XF86AudioRepeat" , 0x1008FF98} ,
2330 | {"XF86AudioRandomPlay" , 0x1008FF99} ,
2331 | {"XF86Subtitle" , 0x1008FF9A} ,
2332 | {"XF86AudioCycleTrack" , 0x1008FF9B} ,
2333 | {"XF86CycleAngle" , 0x1008FF9C} ,
2334 | {"XF86FrameBack" , 0x1008FF9D} ,
2335 | {"XF86FrameForward" , 0x1008FF9E} ,
2336 | {"XF86Time" , 0x1008FF9F} ,
2337 | {"XF86Select" , 0x1008FFA0} ,
2338 | {"XF86View" , 0x1008FFA1} ,
2339 | {"XF86TopMenu" , 0x1008FFA2} ,
2340 | {"XF86Red" , 0x1008FFA3} ,
2341 | {"XF86Green" , 0x1008FFA4} ,
2342 | {"XF86Yellow" , 0x1008FFA5} ,
2343 | {"XF86Blue" , 0x1008FFA6} ,
2344 | {"XF86Suspend" , 0x1008FFA7} ,
2345 | {"XF86Hibernate" , 0x1008FFA8} ,
2346 | {"XF86TouchpadToggle" , 0x1008FFA9} ,
2347 | {"XF86TouchpadOn" , 0x1008FFB0} ,
2348 | {"XF86TouchpadOff" , 0x1008FFB1} ,
2349 | {"XF86AudioMicMute" , 0x1008FFB2} ,
2350 | {"XF86Switch_VT_1" , 0x1008FE01} ,
2351 | {"XF86Switch_VT_2" , 0x1008FE02} ,
2352 | {"XF86Switch_VT_3" , 0x1008FE03} ,
2353 | {"XF86Switch_VT_4" , 0x1008FE04} ,
2354 | {"XF86Switch_VT_5" , 0x1008FE05} ,
2355 | {"XF86Switch_VT_6" , 0x1008FE06} ,
2356 | {"XF86Switch_VT_7" , 0x1008FE07} ,
2357 | {"XF86Switch_VT_8" , 0x1008FE08} ,
2358 | {"XF86Switch_VT_9" , 0x1008FE09} ,
2359 | {"XF86Switch_VT_10" , 0x1008FE0A} ,
2360 | {"XF86Switch_VT_11" , 0x1008FE0B} ,
2361 | {"XF86Switch_VT_12" , 0x1008FE0C} ,
2362 | {"XF86Ungrab" , 0x1008FE20} ,
2363 | {"XF86ClearGrab" , 0x1008FE21} ,
2364 | {"XF86Next_VMode" , 0x1008FE22} ,
2365 | {"XF86Prev_VMode" , 0x1008FE23} ,
2366 | {"XF86LogWindowTree" , 0x1008FE24} ,
2367 | {"XF86LogGrabInfo" , 0x1008FE25} ,
2368 | #endif
2369 | };/*}}}*/
2370 |
2371 | void load_config(const char *config_file)
2372 | {
2373 | PRINTF("load configuration '%s'\n", config_file);
2374 | FILE *cfg = fopen(config_file, "r");
2375 | if (cfg == NULL)
2376 | err("Can't open configuration file: '%s'.\n", config_file);
2377 |
2378 | char buf[3 * MAXLEN];
2379 | char chain[MAXLEN] = {0};
2380 | char command[2 * MAXLEN] = {0};
2381 | int offset = 0;
2382 | char first;
2383 |
2384 | while (fgets(buf, sizeof(buf), cfg) != NULL) {
2385 | first = buf[0];
2386 | if (strlen(buf) < 2 || first == START_COMMENT) {
2387 | continue;
2388 | } else {
2389 | char *start = lgraph(buf);
2390 | if (start == NULL)
2391 | continue;
2392 | char *end = rgraph(buf);
2393 | *(end + 1) = '\0';
2394 |
2395 | if (isgraph(first))
2396 | snprintf(chain + offset, sizeof(chain) - offset, "%s", start);
2397 | else
2398 | snprintf(command + offset, sizeof(command) - offset, "%s", start);
2399 |
2400 | if (*end == PARTIAL_LINE) {
2401 | offset += end - start;
2402 | continue;
2403 | } else {
2404 | offset = 0;
2405 | }
2406 |
2407 | if (isspace(first) && strlen(chain) > 0 && strlen(command) > 0) {
2408 | process_hotkey(chain, command);
2409 | chain[0] = '\0';
2410 | command[0] = '\0';
2411 | }
2412 | }
2413 | }
2414 |
2415 | fclose(cfg);
2416 | }
2417 |
2418 | void parse_event(xcb_generic_event_t *evt, uint8_t event_type, xcb_keysym_t *keysym, xcb_button_t *button, uint16_t *modfield)
2419 | {
2420 | if (event_type == XCB_KEY_PRESS) {
2421 | xcb_key_press_event_t *e = (xcb_key_press_event_t *) evt;
2422 | xcb_keycode_t keycode = e->detail;
2423 | *modfield = e->state;
2424 | *keysym = xcb_key_symbols_get_keysym(symbols, keycode, 0);
2425 | PRINTF("key press %u %u\n", keycode, *modfield);
2426 | } else if (event_type == XCB_KEY_RELEASE) {
2427 | xcb_key_release_event_t *e = (xcb_key_release_event_t *) evt;
2428 | xcb_keycode_t keycode = e->detail;
2429 | *modfield = e->state & ~modfield_from_keycode(keycode);
2430 | *keysym = xcb_key_symbols_get_keysym(symbols, keycode, 0);
2431 | PRINTF("key release %u %u\n", keycode, *modfield);
2432 | } else if (event_type == XCB_BUTTON_PRESS) {
2433 | xcb_button_press_event_t *e = (xcb_button_press_event_t *) evt;
2434 | *button = e->detail;
2435 | *modfield = e->state;
2436 | PRINTF("button press %u %u\n", *button, *modfield);
2437 | } else if (event_type == XCB_BUTTON_RELEASE) {
2438 | xcb_button_release_event_t *e = (xcb_button_release_event_t *) evt;
2439 | *button = e->detail;
2440 | *modfield = e->state;
2441 | PRINTF("button release %u %u\n", *button, *modfield);
2442 | }
2443 | }
2444 |
2445 | void process_hotkey(char *hotkey_string, char *command_string)
2446 | {
2447 | char hotkey[2 * MAXLEN] = {0};
2448 | char command[2 * MAXLEN] = {0};
2449 | char last_hotkey[2 * MAXLEN] = {0};
2450 | unsigned char num_same = 0;
2451 | chunk_t *hk_chunks = extract_chunks(hotkey_string);
2452 | chunk_t *cm_chunks = extract_chunks(command_string);
2453 |
2454 | #define CHECKCHUNK(s, c) \
2455 | if (c->next == NULL && !c->sequence) { \
2456 | snprintf(s, sizeof(s), "%s", c->text); \
2457 | destroy_chunks(c); \
2458 | c = NULL; \
2459 | }
2460 | CHECKCHUNK(hotkey, hk_chunks)
2461 | CHECKCHUNK(command, cm_chunks)
2462 | #undef CHECKCHUNK
2463 |
2464 | render_next(hk_chunks, hotkey);
2465 | render_next(cm_chunks, command);
2466 |
2467 | while ((hk_chunks == NULL || hotkey[0] != '\0') && (cm_chunks == NULL || command[0] != '\0')) {
2468 |
2469 | PRINTF("%s: %s\n", hotkey, command);
2470 | chain_t *chain = make_chain();
2471 | if (parse_chain(hotkey, chain)) {
2472 | hotkey_t *hk = make_hotkey(chain, command);
2473 | for (hotkey_t* i = hotkeys_head; i; i = i->next) {
2474 | if (chains_interfere(i->chain, hk->chain)) {
2475 | warn("Hotkey interference found and may not be matched: '%s' (from '%s').\n", hotkey, hotkey_string);
2476 | }
2477 | }
2478 | add_hotkey(hk);
2479 | if (strcmp(hotkey, last_hotkey) == 0)
2480 | num_same++;
2481 | } else {
2482 | destroy_chain(chain);
2483 | }
2484 |
2485 | if (hk_chunks == NULL && cm_chunks == NULL)
2486 | break;
2487 |
2488 | snprintf(last_hotkey, sizeof(last_hotkey), "%s", hotkey);
2489 |
2490 | render_next(hk_chunks, hotkey);
2491 | render_next(cm_chunks, command);
2492 | }
2493 |
2494 | if (num_same > 0) {
2495 | int period = num_same + 1;
2496 | int delay = num_same;
2497 | for (hotkey_t *hk = hotkeys_tail; hk != NULL && delay >= 0; hk = hk->prev, delay--)
2498 | hk->cycle = make_cycle(delay, period);
2499 | }
2500 |
2501 | if (hk_chunks != NULL)
2502 | destroy_chunks(hk_chunks);
2503 | if (cm_chunks != NULL)
2504 | destroy_chunks(cm_chunks);
2505 | }
2506 |
2507 | char *get_token(char *dst, char *ign, char *src, char *sep)
2508 | {
2509 | size_t len = strlen(src);
2510 | unsigned int i = 0, j = 0, k = 0;
2511 | bool inhibit = false;
2512 | bool found = false;
2513 | while (i < len && !found) {
2514 | if (inhibit) {
2515 | dst[j++] = src[i];
2516 | inhibit = false;
2517 | } else if (src[i] == MAGIC_INHIBIT) {
2518 | inhibit = true;
2519 | if (src[i+1] != MAGIC_INHIBIT && strchr(sep, src[i+1]) == NULL)
2520 | dst[j++] = src[i];
2521 | } else if (strchr(sep, src[i]) != NULL) {
2522 | if (j > 0)
2523 | found = true;
2524 | do {
2525 | if (ign != NULL)
2526 | ign[k++] = src[i];
2527 | i++;
2528 | } while (i < len && strchr(sep, src[i]) != NULL);
2529 | i--;
2530 | } else {
2531 | dst[j++] = src[i];
2532 | }
2533 | i++;
2534 | }
2535 | dst[j] = '\0';
2536 | if (ign != NULL)
2537 | ign[k] = '\0';
2538 | return src + i;
2539 | }
2540 |
2541 | void render_next(chunk_t *chunks, char *dest)
2542 | {
2543 | if (chunks == NULL)
2544 | return;
2545 | int i = 0;
2546 | bool incr = false;
2547 | for (chunk_t *c = chunks; c != NULL; c = c->next) {
2548 | if (c->sequence) {
2549 | if (!incr) {
2550 | if (c->range_cur < c->range_max) {
2551 | c->range_cur++;
2552 | incr = true;
2553 | } else {
2554 | c->range_cur = 1, c->range_max = 0;
2555 | }
2556 | }
2557 | if (c->advance == NULL) {
2558 | incr = true;
2559 | c->advance = get_token(c->item, NULL, c->text, SEQ_SEP);
2560 | } else if (!incr && c->range_cur > c->range_max) {
2561 | if (c->advance[0] == '\0') {
2562 | c->advance = get_token(c->item, NULL, c->text, SEQ_SEP);
2563 | } else {
2564 | c->advance = get_token(c->item, NULL, c->advance, SEQ_SEP);
2565 | incr = true;
2566 | }
2567 | }
2568 | if (c->range_cur > c->range_max && strlen(c->item) == 3)
2569 | sscanf(c->item, "%c-%c", &c->range_cur, &c->range_max);
2570 | if (c->range_cur <= c->range_max) {
2571 | dest[i++] = c->range_cur;
2572 | } else {
2573 | if (c->item[0] == SEQ_NONE && c->item[1] == '\0')
2574 | continue;
2575 | strcpy(dest + i, c->item);
2576 | i += strlen(c->item);
2577 | }
2578 | } else {
2579 | strcpy(dest + i, c->text);
2580 | i += strlen(c->text);
2581 | }
2582 | }
2583 | dest[i] = '\0';
2584 | if (!incr)
2585 | dest[0] = '\0';
2586 | }
2587 |
2588 | chunk_t *extract_chunks(char *s)
2589 | {
2590 | size_t len = strlen(s);
2591 | unsigned int i = 0, j = 0;
2592 | bool inhibit = false;
2593 | int num_seq = 0;
2594 | chunk_t *c = make_chunk();
2595 | chunk_t *head = c;
2596 | while (i < len) {
2597 | if (inhibit) {
2598 | c->text[j++] = s[i];
2599 | inhibit = false;
2600 | } else if (s[i] == MAGIC_INHIBIT) {
2601 | inhibit = true;
2602 | if ((s[i+1] != MAGIC_INHIBIT || c->sequence)
2603 | && s[i+1] != SEQ_BEGIN
2604 | && s[i+1] != SEQ_END)
2605 | c->text[j++] = s[i];
2606 | } else if (s[i] == SEQ_BEGIN) {
2607 | if (j > 0) {
2608 | c->text[j] = '\0';
2609 | j = 0;
2610 | chunk_t *next = make_chunk();
2611 | c->next = next;
2612 | c = next;
2613 | }
2614 | c->sequence = true;
2615 | } else if (s[i] == SEQ_END) {
2616 | if (c->sequence)
2617 | num_seq++;
2618 | if (j > 0) {
2619 | c->text[j] = '\0';
2620 | j = 0;
2621 | chunk_t *next = make_chunk();
2622 | c->next = next;
2623 | c = next;
2624 | }
2625 | c->sequence = false;
2626 | } else {
2627 | c->text[j++] = s[i];
2628 | }
2629 | i++;
2630 | }
2631 | c->text[j] = '\0';
2632 | return head;
2633 | }
2634 |
2635 | chunk_t *make_chunk(void)
2636 | {
2637 | chunk_t *c = calloc(1, sizeof(chunk_t));
2638 | c->sequence = false;
2639 | c->advance = NULL;
2640 | c->next = NULL;
2641 | c->range_cur = 1;
2642 | c->range_max = 0;
2643 | return c;
2644 | }
2645 |
2646 | void destroy_chunks(chunk_t *chunk)
2647 | {
2648 | chunk_t *c = chunk;
2649 | while (c != NULL) {
2650 | chunk_t *next = c->next;
2651 | free(c);
2652 | c = next;
2653 | }
2654 | }
2655 |
2656 | bool parse_chain(char *string, chain_t *chain)
2657 | {
2658 | char chord[MAXLEN] = {0};
2659 | char name[MAXLEN] = {0};
2660 | char ignored[MAXLEN] = {0};
2661 | xcb_keysym_t keysym = XCB_NO_SYMBOL;
2662 | xcb_button_t button = XCB_NONE;
2663 | uint16_t modfield = 0;
2664 | uint8_t event_type = XCB_KEY_PRESS;
2665 | bool replay_event = false;
2666 | bool lock_chain = false;
2667 | char *outer_advance;
2668 | char *inner_advance;
2669 | for (outer_advance = get_token(chord, ignored, string, LNK_SEP); chord[0] != '\0'; outer_advance = get_token(chord, ignored, outer_advance, LNK_SEP)) {
2670 | for (inner_advance = get_token(name, NULL, chord, SYM_SEP); name[0] != '\0'; inner_advance = get_token(name, NULL, inner_advance, SYM_SEP)) {
2671 | int offset = 0;
2672 | if (name[offset] == REPLAY_PREFIX) {
2673 | replay_event = true;
2674 | offset++;
2675 | }
2676 | if (name[offset] == RELEASE_PREFIX) {
2677 | event_type = XCB_KEY_RELEASE;
2678 | offset++;
2679 | }
2680 | char *nm = name + offset;
2681 | if (!parse_modifier(nm, &modfield) && !parse_keysym(nm, &keysym) && !parse_button(nm, &button)) {
2682 | warn("Unknown keysym name: '%s'.\n", nm);
2683 | return false;
2684 | }
2685 | }
2686 | if (strstr(ignored, GRP_SEP) != NULL)
2687 | lock_chain = true;
2688 | if (button != XCB_NONE)
2689 | event_type = key_to_button(event_type);
2690 | chord_t *c = make_chord(keysym, button, modfield, event_type, replay_event, lock_chain);
2691 | if (c == NULL) {
2692 | return false;
2693 | }
2694 | add_chord(chain, c);
2695 | if (status_fifo != NULL) {
2696 | snprintf(c->repr, sizeof(c->repr), "%s", chord);
2697 | }
2698 | keysym = XCB_NO_SYMBOL;
2699 | button = XCB_NONE;
2700 | modfield = 0;
2701 | event_type = XCB_KEY_PRESS;
2702 | replay_event = false;
2703 | lock_chain = false;
2704 | }
2705 | return true;
2706 | }
2707 |
2708 | bool parse_keysym(char *name, xcb_keysym_t *keysym)
2709 | {
2710 | for (unsigned int i = 0; i < LENGTH(nks_dict); i++) {
2711 | keysym_dict_t nks = nks_dict[i];
2712 | if (strcmp(name, nks.name) == 0) {
2713 | *keysym = nks.keysym;
2714 | return true;
2715 | }
2716 | }
2717 | return false;
2718 | }
2719 |
2720 | bool parse_button(char *name, xcb_button_t *butidx)
2721 | {
2722 | /* X handles up to 24 buttons */
2723 | return (sscanf(name, "button%" SCNu8, butidx) == 1);
2724 | }
2725 |
2726 | bool parse_modifier(char *name, uint16_t *modfield)
2727 | {
2728 | if (strcmp(name, "shift") == 0) {
2729 | *modfield |= XCB_MOD_MASK_SHIFT;
2730 | return true;
2731 | } else if (strcmp(name, "control") == 0 || strcmp(name, "ctrl") == 0) {
2732 | *modfield |= XCB_MOD_MASK_CONTROL;
2733 | return true;
2734 | } else if (strcmp(name, "alt") == 0) {
2735 | *modfield |= (modfield_from_keysym(Alt_L) | modfield_from_keysym(Alt_R));
2736 | return true;
2737 | } else if (strcmp(name, "super") == 0) {
2738 | *modfield |= (modfield_from_keysym(Super_L) | modfield_from_keysym(Super_R));
2739 | return true;
2740 | } else if (strcmp(name, "hyper") == 0) {
2741 | *modfield |= (modfield_from_keysym(Hyper_L) | modfield_from_keysym(Hyper_R));
2742 | return true;
2743 | } else if (strcmp(name, "meta") == 0) {
2744 | *modfield |= (modfield_from_keysym(Meta_L) | modfield_from_keysym(Meta_R));
2745 | return true;
2746 | } else if (strcmp(name, "mode_switch") == 0) {
2747 | *modfield |= modfield_from_keysym(Mode_switch);
2748 | return true;
2749 | } else if (strcmp(name, "mod1") == 0) {
2750 | *modfield |= XCB_MOD_MASK_1;
2751 | return true;
2752 | } else if (strcmp(name, "mod2") == 0) {
2753 | *modfield |= XCB_MOD_MASK_2;
2754 | return true;
2755 | } else if (strcmp(name, "mod3") == 0) {
2756 | *modfield |= XCB_MOD_MASK_3;
2757 | return true;
2758 | } else if (strcmp(name, "mod4") == 0) {
2759 | *modfield |= XCB_MOD_MASK_4;
2760 | return true;
2761 | } else if (strcmp(name, "mod5") == 0) {
2762 | *modfield |= XCB_MOD_MASK_5;
2763 | return true;
2764 | } else if (strcmp(name, "lock") == 0) {
2765 | *modfield |= XCB_MOD_MASK_LOCK;
2766 | return true;
2767 | } else if (strcmp(name, "any") == 0) {
2768 | *modfield |= XCB_MOD_MASK_ANY;
2769 | return true;
2770 | }
2771 | return false;
2772 | }
2773 |
2774 | bool parse_fold(char *string, char *folded_string)
2775 | {
2776 | if (strchr(string, SEQ_BEGIN) != NULL && strrchr(string, SEQ_END) != NULL) {
2777 | snprintf(folded_string, strlen(string), "%s", string);
2778 | return true;
2779 | }
2780 | return false;
2781 | }
2782 |
2783 | uint8_t key_to_button(uint8_t event_type)
2784 | {
2785 | if (event_type == XCB_KEY_PRESS)
2786 | return XCB_BUTTON_PRESS;
2787 | else if (event_type == XCB_KEY_RELEASE)
2788 | return XCB_BUTTON_RELEASE;
2789 | return event_type;
2790 | }
2791 |
2792 | void get_standard_keysyms(void)
2793 | {
2794 | #define GETKS(X) \
2795 | if (!parse_keysym(#X, &X)) \
2796 | warn("Couldn't retrieve keysym for '%s'.\n", #X); \
2797 | else \
2798 | PRINTF("keysym for '%s' is 0x%X.\n", #X, X);
2799 | GETKS(Alt_L)
2800 | GETKS(Alt_R)
2801 | GETKS(Super_L)
2802 | GETKS(Super_R)
2803 | GETKS(Hyper_L)
2804 | GETKS(Hyper_R)
2805 | GETKS(Mode_switch)
2806 | GETKS(Num_Lock)
2807 | GETKS(Scroll_Lock)
2808 | #undef GETKS
2809 | }
2810 |
2811 | void get_lock_fields(void)
2812 | {
2813 | num_lock = modfield_from_keysym(Num_Lock);
2814 | caps_lock = XCB_MOD_MASK_LOCK;
2815 | scroll_lock = modfield_from_keysym(Scroll_Lock);
2816 | PRINTF("lock fields %u %u %u\n", num_lock, caps_lock, scroll_lock);
2817 | }
2818 |
2819 | int16_t modfield_from_keysym(xcb_keysym_t keysym)
2820 | {
2821 | uint16_t modfield = 0;
2822 | xcb_keycode_t *keycodes = NULL;
2823 | if ((keycodes = keycodes_from_keysym(keysym)) != NULL) {
2824 | for (xcb_keycode_t *k = keycodes; *k != XCB_NO_SYMBOL; k++)
2825 | modfield |= modfield_from_keycode(*k);
2826 | }
2827 | free(keycodes);
2828 | return modfield;
2829 | }
2830 |
2831 | int16_t modfield_from_keycode(xcb_keycode_t keycode)
2832 | {
2833 | uint16_t modfield = 0;
2834 | xcb_keycode_t *mod_keycodes = NULL;
2835 | xcb_get_modifier_mapping_reply_t *reply = NULL;
2836 | if ((reply = xcb_get_modifier_mapping_reply(dpy, xcb_get_modifier_mapping(dpy), NULL)) != NULL && reply->keycodes_per_modifier > 0) {
2837 | if ((mod_keycodes = xcb_get_modifier_mapping_keycodes(reply)) != NULL) {
2838 | unsigned int num_mod = xcb_get_modifier_mapping_keycodes_length(reply) / reply->keycodes_per_modifier;
2839 | for (unsigned int i = 0; i < num_mod; i++) {
2840 | for (unsigned int j = 0; j < reply->keycodes_per_modifier; j++) {
2841 | xcb_keycode_t mkc = mod_keycodes[i * reply->keycodes_per_modifier + j];
2842 | if (mkc == XCB_NO_SYMBOL)
2843 | continue;
2844 | if (keycode == mkc)
2845 | modfield |= (1 << i);
2846 | }
2847 | }
2848 |
2849 | }
2850 | }
2851 | free(reply);
2852 | return modfield;
2853 | }
2854 |
2855 | xcb_keycode_t *keycodes_from_keysym(xcb_keysym_t keysym)
2856 | {
2857 | xcb_setup_t const *setup;
2858 | unsigned int num = 0;
2859 | xcb_keycode_t *result = NULL, *result_np = NULL;
2860 |
2861 | if ((setup = xcb_get_setup(dpy)) != NULL) {
2862 | xcb_keycode_t min_kc = setup->min_keycode;
2863 | xcb_keycode_t max_kc = setup->max_keycode;
2864 |
2865 | /* We must choose a type for kc other than xcb_keycode_t whose size
2866 | * is 1, otherwise, since max_kc will most likely be 255, if kc == 255,
2867 | * kc++ would be 0 and the outer loop would start over ad infinitum */
2868 | for(unsigned int kc = min_kc; kc <= max_kc; kc++)
2869 | for(unsigned int col = 0; col < KEYSYMS_PER_KEYCODE; col++) {
2870 | xcb_keysym_t ks = xcb_key_symbols_get_keysym(symbols, kc, col);
2871 | if (ks == keysym) {
2872 | num++;
2873 | result_np = realloc(result, sizeof(xcb_keycode_t) * (num + 1));
2874 | if (result_np == NULL) {
2875 | free(result);
2876 | return NULL;
2877 | }
2878 | result = result_np;
2879 | result[num - 1] = kc;
2880 | result[num] = XCB_NO_SYMBOL;
2881 | break;
2882 | }
2883 | }
2884 | }
2885 | return result;
2886 | }
2887 |
--------------------------------------------------------------------------------
/src/parse.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #ifndef SXHKD_PARSE_H
26 | #define SXHKD_PARSE_H
27 |
28 | #include "sxhkd.h"
29 |
30 | #define RELEASE_PREFIX '@'
31 | #define REPLAY_PREFIX '~'
32 | #define START_COMMENT '#'
33 | #define MAGIC_INHIBIT '\\'
34 | #define PARTIAL_LINE '\\'
35 | #define GRP_SEP ":"
36 | #define LNK_SEP ";" GRP_SEP
37 | #define SYM_SEP "+ "
38 | #define SEQ_BEGIN '{'
39 | #define SEQ_END '}'
40 | #define SEQ_SEP ","
41 | #define SEQ_NONE '_'
42 |
43 | typedef struct chunk_t chunk_t;
44 | struct chunk_t {
45 | char text[2 * MAXLEN];
46 | char item[2 * MAXLEN];
47 | char *advance;
48 | bool sequence;
49 | char range_cur;
50 | char range_max;
51 | chunk_t *next;
52 | };
53 |
54 | void load_config(const char *config_file);
55 | void parse_event(xcb_generic_event_t *evt, uint8_t event_type, xcb_keysym_t *keysym, xcb_button_t *button, uint16_t *modfield);
56 | void process_hotkey(char *hotkey_string, char *command_string);
57 | char *get_token(char *dst, char *ign, char *src, char *sep);
58 | void render_next(chunk_t *chunks, char *dest);
59 | chunk_t *extract_chunks(char *s);
60 | chunk_t *make_chunk(void);
61 | void destroy_chunks(chunk_t *chunk);
62 | bool parse_chain(char *string, chain_t *chain);
63 | bool parse_keysym(char *name, xcb_keysym_t *keysym);
64 | bool parse_button(char *name, xcb_button_t *butidx);
65 | bool parse_modifier(char *name, uint16_t *modfield);
66 | bool parse_fold(char *string, char *folded_string);
67 | uint8_t key_to_button(uint8_t event_type);
68 | void get_standard_keysyms(void);
69 | void get_lock_fields(void);
70 | int16_t modfield_from_keysym(xcb_keysym_t keysym);
71 | int16_t modfield_from_keycode(xcb_keycode_t keycode);
72 | xcb_keycode_t *keycodes_from_keysym(xcb_keysym_t keysym);
73 |
74 | #endif
75 |
--------------------------------------------------------------------------------
/src/sxhkd.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include "parse.h"
37 | #include "grab.h"
38 |
39 | xcb_connection_t *dpy;
40 | xcb_window_t root;
41 | xcb_key_symbols_t *symbols;
42 |
43 | char *shell;
44 | char config_file[MAXLEN];
45 | char *config_path;
46 | char **extra_confs;
47 | int num_extra_confs;
48 | int redir_fd;
49 | FILE *status_fifo;
50 | char progress[3 * MAXLEN];
51 | int mapping_count;
52 | int timeout;
53 |
54 | char sxhkd_pid[MAXLEN];
55 |
56 | hotkey_t *hotkeys_head, *hotkeys_tail;
57 | bool running, grabbed, toggle_grab, reload, bell, chained, locked;
58 | xcb_keysym_t abort_keysym;
59 | chord_t *abort_chord;
60 |
61 | uint16_t num_lock;
62 | uint16_t caps_lock;
63 | uint16_t scroll_lock;
64 |
65 | int main(int argc, char *argv[])
66 | {
67 | int opt;
68 | char *fifo_path = NULL;
69 | status_fifo = NULL;
70 | config_path = NULL;
71 | mapping_count = 0;
72 | timeout = TIMEOUT;
73 | grabbed = false;
74 | redir_fd = -1;
75 | abort_keysym = ESCAPE_KEYSYM;
76 |
77 | while ((opt = getopt(argc, argv, "hvm:t:c:r:s:a:")) != -1) {
78 | switch (opt) {
79 | case 'v':
80 | printf("%s\n", VERSION);
81 | exit(EXIT_SUCCESS);
82 | break;
83 | case 'h':
84 | printf("sxhkd [-h|-v|-m COUNT|-t TIMEOUT|-c CONFIG_FILE|-r REDIR_FILE|-s STATUS_FIFO|-a ABORT_KEYSYM] [EXTRA_CONFIG ...]\n");
85 | exit(EXIT_SUCCESS);
86 | break;
87 | case 'm':
88 | if (sscanf(optarg, "%i", &mapping_count) != 1)
89 | warn("Can't parse mapping count.\n");
90 | break;
91 | case 't':
92 | timeout = atoi(optarg);
93 | break;
94 | case 'c':
95 | config_path = optarg;
96 | break;
97 | case 'r':
98 | redir_fd = open(optarg, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
99 | if (redir_fd == -1)
100 | warn("Failed to open the command redirection file.\n");
101 | break;
102 | case 's':
103 | fifo_path = optarg;
104 | break;
105 | case 'a':
106 | if (!parse_keysym(optarg, &abort_keysym)) {
107 | warn("Invalid keysym name: %s.\n", optarg);
108 | }
109 | break;
110 | }
111 | }
112 |
113 | num_extra_confs = argc - optind;
114 | extra_confs = argv + optind;
115 |
116 | if (config_path == NULL) {
117 | char *config_home = getenv(CONFIG_HOME_ENV);
118 | if (config_home != NULL)
119 | snprintf(config_file, sizeof(config_file), "%s/%s", config_home, CONFIG_PATH);
120 | else
121 | snprintf(config_file, sizeof(config_file), "%s/%s/%s", getenv("HOME"), ".config", CONFIG_PATH);
122 | } else {
123 | snprintf(config_file, sizeof(config_file), "%s", config_path);
124 | }
125 |
126 | if (fifo_path != NULL) {
127 | int fifo_fd = open(fifo_path, O_RDWR | O_NONBLOCK);
128 | if (fifo_fd != -1) {
129 | status_fifo = fdopen(fifo_fd, "w");
130 | } else {
131 | warn("Couldn't open status fifo.\n");
132 | }
133 | }
134 |
135 | signal(SIGINT, hold);
136 | signal(SIGHUP, hold);
137 | signal(SIGTERM, hold);
138 | signal(SIGUSR1, hold);
139 | signal(SIGUSR2, hold);
140 | signal(SIGALRM, hold);
141 |
142 | setup();
143 | get_standard_keysyms();
144 | get_lock_fields();
145 | abort_chord = make_chord(abort_keysym, XCB_NONE, 0, XCB_KEY_PRESS, false, false);
146 | load_config(config_file);
147 | for (int i = 0; i < num_extra_confs; i++)
148 | load_config(extra_confs[i]);
149 | grab();
150 |
151 | xcb_generic_event_t *evt;
152 | int fd = xcb_get_file_descriptor(dpy);
153 |
154 | fd_set descriptors;
155 |
156 | reload = toggle_grab = bell = chained = locked = false;
157 | running = true;
158 |
159 | xcb_flush(dpy);
160 |
161 | while (running) {
162 | FD_ZERO(&descriptors);
163 | FD_SET(fd, &descriptors);
164 |
165 | if (select(fd + 1, &descriptors, NULL, NULL, NULL) > 0) {
166 | while ((evt = xcb_poll_for_event(dpy)) != NULL) {
167 | uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(evt);
168 | switch (event_type) {
169 | case XCB_KEY_PRESS:
170 | case XCB_KEY_RELEASE:
171 | case XCB_BUTTON_PRESS:
172 | case XCB_BUTTON_RELEASE:
173 | key_button_event(evt, event_type);
174 | break;
175 | case XCB_MAPPING_NOTIFY:
176 | mapping_notify(evt);
177 | break;
178 | default:
179 | PRINTF("received event %u\n", event_type);
180 | break;
181 | }
182 | free(evt);
183 | }
184 | }
185 |
186 | if (reload) {
187 | signal(SIGUSR1, hold);
188 | reload_cmd();
189 | reload = false;
190 | }
191 |
192 | if (toggle_grab) {
193 | signal(SIGUSR2, hold);
194 | toggle_grab_cmd();
195 | toggle_grab = false;
196 | }
197 |
198 | if (bell) {
199 | signal(SIGALRM, hold);
200 | put_status(TIMEOUT_PREFIX, "Timeout reached");
201 | abort_chain();
202 | bell = false;
203 | }
204 |
205 | if (xcb_connection_has_error(dpy)) {
206 | warn("The server closed the connection.\n");
207 | running = false;
208 | }
209 | }
210 |
211 | if (redir_fd != -1) {
212 | close(redir_fd);
213 | }
214 |
215 | if (status_fifo != NULL) {
216 | fclose(status_fifo);
217 | }
218 |
219 | ungrab();
220 | cleanup();
221 | destroy_chord(abort_chord);
222 | xcb_key_symbols_free(symbols);
223 | xcb_disconnect(dpy);
224 | return EXIT_SUCCESS;
225 | }
226 |
227 | void key_button_event(xcb_generic_event_t *evt, uint8_t event_type)
228 | {
229 | xcb_keysym_t keysym = XCB_NO_SYMBOL;
230 | xcb_button_t button = XCB_NONE;
231 | bool replay_event = false;
232 | uint16_t modfield = 0;
233 | uint16_t lockfield = num_lock | caps_lock | scroll_lock;
234 | parse_event(evt, event_type, &keysym, &button, &modfield);
235 | modfield &= ~lockfield & MOD_STATE_FIELD;
236 | if (keysym != XCB_NO_SYMBOL || button != XCB_NONE) {
237 | hotkey_t *hk = find_hotkey(keysym, button, modfield, event_type, &replay_event);
238 | if (hk != NULL) {
239 | run(hk->command, hk->sync);
240 | put_status(COMMAND_PREFIX, hk->command);
241 | }
242 | }
243 | switch (event_type) {
244 | case XCB_BUTTON_PRESS:
245 | case XCB_BUTTON_RELEASE:
246 | if (replay_event)
247 | xcb_allow_events(dpy, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME);
248 | else
249 | xcb_allow_events(dpy, XCB_ALLOW_SYNC_POINTER, XCB_CURRENT_TIME);
250 | break;
251 | case XCB_KEY_PRESS:
252 | case XCB_KEY_RELEASE:
253 | if (replay_event)
254 | xcb_allow_events(dpy, XCB_ALLOW_REPLAY_KEYBOARD, XCB_CURRENT_TIME);
255 | else
256 | xcb_allow_events(dpy, XCB_ALLOW_SYNC_KEYBOARD, XCB_CURRENT_TIME);
257 | break;
258 | }
259 | xcb_flush(dpy);
260 | }
261 |
262 | void mapping_notify(xcb_generic_event_t *evt)
263 | {
264 | if (!mapping_count)
265 | return;
266 | xcb_mapping_notify_event_t *e = (xcb_mapping_notify_event_t *) evt;
267 | PRINTF("mapping notify %u %u\n", e->request, e->count);
268 | if (e->request == XCB_MAPPING_POINTER)
269 | return;
270 | if (xcb_refresh_keyboard_mapping(symbols, e) == 1) {
271 | destroy_chord(abort_chord);
272 | get_lock_fields();
273 | reload_cmd();
274 | abort_chord = make_chord(abort_keysym, XCB_NONE, 0, XCB_KEY_PRESS, false, false);
275 | if (mapping_count > 0)
276 | mapping_count--;
277 | }
278 | }
279 |
280 | void setup(void)
281 | {
282 | int screen_idx;
283 | dpy = xcb_connect(NULL, &screen_idx);
284 | if (xcb_connection_has_error(dpy))
285 | err("Can't open display.\n");
286 | xcb_screen_t *screen = NULL;
287 | xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(dpy));
288 | for (; screen_iter.rem; xcb_screen_next(&screen_iter), screen_idx--) {
289 | if (screen_idx == 0) {
290 | screen = screen_iter.data;
291 | break;
292 | }
293 | }
294 | if (screen == NULL)
295 | err("Can't acquire screen.\n");
296 | root = screen->root;
297 | if ((shell = getenv(SXHKD_SHELL_ENV)) == NULL && (shell = getenv(SHELL_ENV)) == NULL)
298 | err("The '%s' environment variable is not defined.\n", SHELL_ENV);
299 | symbols = xcb_key_symbols_alloc(dpy);
300 | hotkeys_head = hotkeys_tail = NULL;
301 | progress[0] = '\0';
302 |
303 | snprintf(sxhkd_pid, MAXLEN, "%i", getpid());
304 | setenv("SXHKD_PID", sxhkd_pid, 1);
305 | }
306 |
307 | void cleanup(void)
308 | {
309 | PUTS("cleanup");
310 | hotkey_t *hk = hotkeys_head;
311 | while (hk != NULL) {
312 | hotkey_t *next = hk->next;
313 | destroy_chain(hk->chain);
314 | free(hk->cycle);
315 | free(hk);
316 | hk = next;
317 | }
318 | hotkeys_head = hotkeys_tail = NULL;
319 | }
320 |
321 | void reload_cmd(void)
322 | {
323 | PUTS("reload");
324 | cleanup();
325 | load_config(config_file);
326 | for (int i = 0; i < num_extra_confs; i++)
327 | load_config(extra_confs[i]);
328 | ungrab();
329 | grab();
330 | }
331 |
332 | void toggle_grab_cmd(void)
333 | {
334 | PUTS("toggle grab");
335 | if (grabbed) {
336 | ungrab();
337 | } else {
338 | grab();
339 | }
340 | }
341 |
342 | void hold(int sig)
343 | {
344 | if (sig == SIGHUP || sig == SIGINT || sig == SIGTERM)
345 | running = false;
346 | else if (sig == SIGUSR1)
347 | reload = true;
348 | else if (sig == SIGUSR2)
349 | toggle_grab = true;
350 | else if (sig == SIGALRM)
351 | bell = true;
352 | }
353 |
354 | void put_status(char c, const char *s)
355 | {
356 | if (status_fifo == NULL) {
357 | return;
358 | }
359 | fprintf(status_fifo, "%c%s\n", c, s);
360 | fflush(status_fifo);
361 | }
362 |
--------------------------------------------------------------------------------
/src/sxhkd.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #ifndef SXHKD_SXHKD_H
26 | #define SXHKD_SXHKD_H
27 |
28 | #include
29 | #include
30 | #include
31 | #include "types.h"
32 | #include "helpers.h"
33 |
34 | #define CONFIG_HOME_ENV "XDG_CONFIG_HOME"
35 | #define SXHKD_SHELL_ENV "SXHKD_SHELL"
36 | #define SHELL_ENV "SHELL"
37 | #define CONFIG_PATH "sxhkd/sxhkdrc"
38 | #define HOTKEY_PREFIX 'H'
39 | #define COMMAND_PREFIX 'C'
40 | #define BEGIN_CHAIN_PREFIX 'B'
41 | #define END_CHAIN_PREFIX 'E'
42 | #define TIMEOUT_PREFIX 'T'
43 | #define TIMEOUT 3
44 |
45 | extern xcb_connection_t *dpy;
46 | extern xcb_window_t root;
47 | extern xcb_key_symbols_t *symbols;
48 |
49 | extern char *shell;
50 | extern char config_file[MAXLEN];
51 | extern char *config_path;
52 | extern char **extra_confs;
53 | extern int num_extra_confs;
54 | extern int redir_fd;
55 | extern FILE *status_fifo;
56 | extern char progress[3 * MAXLEN];
57 | extern int mapping_count;
58 | extern int timeout;
59 |
60 | extern hotkey_t *hotkeys_head, *hotkeys_tail;
61 | extern bool running, grabbed, toggle_grab, reload, bell, chained, locked;
62 | extern xcb_keysym_t abort_keysym;
63 | extern chord_t *abort_chord;
64 |
65 | extern uint16_t num_lock;
66 | extern uint16_t caps_lock;
67 | extern uint16_t scroll_lock;
68 |
69 | void key_button_event(xcb_generic_event_t *evt, uint8_t event_type);
70 | void mapping_notify(xcb_generic_event_t *evt);
71 | void setup(void);
72 | void cleanup(void);
73 | void reload_cmd(void);
74 | void toggle_grab_cmd(void);
75 | void hold(int sig);
76 | void put_status(char c, const char *s);
77 |
78 | #endif
79 |
--------------------------------------------------------------------------------
/src/types.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include "parse.h"
31 | #include "grab.h"
32 |
33 | hotkey_t *find_hotkey(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool *replay_event)
34 | {
35 | int num_active = 0;
36 | int num_locked = 0;
37 | hotkey_t *result = NULL;
38 |
39 | for (hotkey_t *hk = hotkeys_head; hk != NULL; hk = hk->next) {
40 | chain_t *c = hk->chain;
41 | if ((chained && c->state == c->head) || (locked && c->state != c->tail))
42 | continue;
43 | if (match_chord(c->state, event_type, keysym, button, modfield)) {
44 | if (status_fifo != NULL && num_active == 0) {
45 | if (!chained) {
46 | snprintf(progress, sizeof(progress), "%s", c->state->repr);
47 | } else {
48 | strncat(progress, ";", sizeof(progress) - strlen(progress) - 1);
49 | strncat(progress, c->state->repr, sizeof(progress) - strlen(progress) - 1);
50 | }
51 | put_status(HOTKEY_PREFIX, progress);
52 | }
53 | if (replay_event != NULL && c->state->replay_event)
54 | *replay_event = true;
55 | if (c->state->lock_chain) {
56 | num_locked += 1;
57 | if (timeout > 0)
58 | alarm(0);
59 | }
60 | if (c->state == c->tail) {
61 | if (hk->cycle != NULL) {
62 | unsigned char delay = hk->cycle->delay;
63 | hk->cycle->delay = (delay == 0 ? hk->cycle->period - 1 : delay - 1);
64 | if (delay == 0)
65 | result = hk;
66 | continue;
67 | }
68 | if (chained && !locked)
69 | abort_chain();
70 | return hk;
71 | } else {
72 | c->state = c->state->next;
73 | num_active++;
74 | grab_chord(c->state);
75 | }
76 | } else if (chained) {
77 | if (!locked && c->state->event_type == event_type)
78 | c->state = c->head;
79 | else
80 | num_active++;
81 | }
82 | }
83 |
84 | if (result != NULL)
85 | return result;
86 |
87 | if (num_locked > 0) {
88 | locked = true;
89 | }
90 |
91 | if (!chained) {
92 | if (num_active > 0) {
93 | chained = true;
94 | put_status(BEGIN_CHAIN_PREFIX, "Begin chain");
95 | grab_chord(abort_chord);
96 | }
97 | } else if (num_active == 0 || match_chord(abort_chord, event_type, keysym, button, modfield)) {
98 | abort_chain();
99 | return find_hotkey(keysym, button, modfield, event_type, replay_event);
100 | }
101 | if (chained && !locked && timeout > 0)
102 | alarm(timeout);
103 | PRINTF("num active %i\n", num_active);
104 |
105 | return NULL;
106 | }
107 |
108 | bool match_chord(chord_t *chord, uint8_t event_type, xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield)
109 | {
110 | for (chord_t *c = chord; c != NULL; c = c->more)
111 | if (c->event_type == event_type && c->keysym == keysym && c->button == button && (c->modfield == XCB_MOD_MASK_ANY || c->modfield == modfield))
112 | return true;
113 | return false;
114 | }
115 |
116 | bool chains_interfere(chain_t* a, chain_t* b) {
117 | chord_t* i = a->head;
118 | chord_t* j = b->head;
119 | for (; i && j; i = i->next, j = j->next) {
120 | bool match = false;
121 | for (chord_t* k = i; k; k = k->more) {
122 | if (match_chord(j, k->event_type, k->keysym, k->button, k->modfield)) {
123 | match = true;
124 | break;
125 | }
126 | }
127 | if (!match) {
128 | break;
129 | }
130 | }
131 | bool result = !i || !j;
132 | return result;
133 | }
134 |
135 | chord_t *make_chord(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool replay_event, bool lock_chain)
136 | {
137 | chord_t *chord;
138 | if (button == XCB_NONE) {
139 | chord_t *prev = NULL;
140 | chord_t *orig = NULL;
141 | xcb_keycode_t *keycodes = keycodes_from_keysym(keysym);
142 | if (keycodes != NULL) {
143 | for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++) {
144 | xcb_keysym_t natural_keysym = xcb_key_symbols_get_keysym(symbols, *kc, 0);
145 | for (unsigned char col = 0; col < KEYSYMS_PER_KEYCODE; col++) {
146 | xcb_keysym_t ks = xcb_key_symbols_get_keysym(symbols, *kc, col);
147 | if (ks == keysym) {
148 | uint16_t implicit_modfield = (col & 1 ? XCB_MOD_MASK_SHIFT : 0) | (col & 2 ? modfield_from_keysym(Mode_switch) : 0);
149 | uint16_t explicit_modfield = modfield | implicit_modfield;
150 | chord = malloc(sizeof(chord_t));
151 | bool unique = true;
152 | for (chord_t *c = orig; unique && c != NULL; c = c->more)
153 | if (c->modfield == explicit_modfield && c->keysym == natural_keysym)
154 | unique = false;
155 | if (!unique) {
156 | free(chord);
157 | break;
158 | }
159 | chord->keysym = natural_keysym;
160 | chord->button = button;
161 | chord->modfield = explicit_modfield;
162 | chord->next = chord->more = NULL;
163 | chord->event_type = event_type;
164 | chord->replay_event = replay_event;
165 | chord->lock_chain = lock_chain;
166 | if (prev != NULL)
167 | prev->more = chord;
168 | else
169 | orig = chord;
170 | prev = chord;
171 | PRINTF("key chord %u %u\n", natural_keysym, explicit_modfield);
172 | break;
173 | }
174 | }
175 | }
176 | } else {
177 | warn("No keycodes found for keysym %u.\n", keysym);
178 | }
179 | free(keycodes);
180 | chord = orig;
181 | } else {
182 | chord = malloc(sizeof(chord_t));
183 | chord->keysym = keysym;
184 | chord->button = button;
185 | chord->modfield = modfield;
186 | chord->event_type = event_type;
187 | chord->replay_event = replay_event;
188 | chord->lock_chain = lock_chain;
189 | chord->next = chord->more = NULL;
190 | PRINTF("button chord %u %u\n", button, modfield);
191 | }
192 | return chord;
193 | }
194 |
195 | void add_chord(chain_t *chain, chord_t *chord)
196 | {
197 | if (chain->head == NULL) {
198 | chain->head = chain->tail = chain->state = chord;
199 | } else {
200 | chain->tail->next = chord;
201 | chain->tail = chord;
202 | }
203 | }
204 |
205 | chain_t *make_chain(void)
206 | {
207 | chain_t *chain = malloc(sizeof(chain_t));
208 | chain->head = chain->tail = chain->state = NULL;
209 | return chain;
210 | }
211 |
212 | cycle_t *make_cycle(int delay, int period)
213 | {
214 | cycle_t *cycle = malloc(sizeof(cycle_t));
215 | cycle->delay = delay;
216 | cycle->period = period;
217 | return cycle;
218 | }
219 |
220 | hotkey_t *make_hotkey(chain_t *chain, char *command)
221 | {
222 | hotkey_t *hk = malloc(sizeof(hotkey_t));
223 | hk->chain = chain;
224 | hk->sync = false;
225 | if (command[0] == SYNCHRONOUS_CHAR) {
226 | command = lgraph(command+1);
227 | hk->sync = true;
228 | }
229 | snprintf(hk->command, sizeof(hk->command), "%s", command);
230 | hk->cycle = NULL;
231 | hk->next = hk->prev = NULL;
232 | return hk;
233 | }
234 |
235 | void add_hotkey(hotkey_t *hk)
236 | {
237 | if (hotkeys_head == NULL) {
238 | hotkeys_head = hotkeys_tail = hk;
239 | } else {
240 | hotkeys_tail->next = hk;
241 | hk->prev = hotkeys_tail;
242 | hotkeys_tail = hk;
243 | }
244 | }
245 |
246 | void abort_chain(void)
247 | {
248 | PUTS("abort chain");
249 | put_status(END_CHAIN_PREFIX, "End chain");
250 | for (hotkey_t *hk = hotkeys_head; hk != NULL; hk = hk->next)
251 | hk->chain->state = hk->chain->head;
252 | chained = false;
253 | locked = false;
254 | if (timeout > 0)
255 | alarm(0);
256 | ungrab();
257 | grab();
258 | }
259 |
260 | void destroy_chain(chain_t *chain)
261 | {
262 | chord_t *c = chain->head;
263 | while (c != NULL) {
264 | chord_t *n = c->next;
265 | destroy_chord(c);
266 | c = n;
267 | }
268 | free(chain);
269 | }
270 |
271 | void destroy_chord(chord_t *chord)
272 | {
273 | chord_t *c = chord->more;
274 | while (c != NULL) {
275 | chord_t *n = c->more;
276 | free(c);
277 | c = n;
278 | }
279 | free(chord);
280 | }
281 |
--------------------------------------------------------------------------------
/src/types.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2013, Bastien Dejean
2 | * All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * 1. Redistributions of source code must retain the above copyright notice, this
8 | * list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright notice,
10 | * this list of conditions and the following disclaimer in the documentation
11 | * and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 | */
24 |
25 | #ifndef SXHKD_TYPES_H
26 | #define SXHKD_TYPES_H
27 |
28 | #include
29 | #include
30 | #include "helpers.h"
31 |
32 | #define KEYSYMS_PER_KEYCODE 4
33 | #define MOD_STATE_FIELD 255
34 | #define ESCAPE_KEYSYM 0xff1b
35 | #define SYNCHRONOUS_CHAR ';'
36 |
37 | extern xcb_keysym_t Mode_switch;
38 |
39 | typedef struct chord_t chord_t;
40 | struct chord_t {
41 | char repr[MAXLEN];
42 | xcb_keysym_t keysym;
43 | xcb_button_t button;
44 | uint16_t modfield;
45 | uint8_t event_type;
46 | bool replay_event;
47 | bool lock_chain;
48 | chord_t *next;
49 | chord_t *more;
50 | };
51 |
52 | typedef struct {
53 | chord_t *head;
54 | chord_t *tail;
55 | chord_t *state;
56 | } chain_t;
57 |
58 | typedef struct {
59 | int period;
60 | int delay;
61 | } cycle_t;
62 |
63 | typedef struct hotkey_t hotkey_t;
64 | struct hotkey_t {
65 | chain_t *chain;
66 | char command[2 * MAXLEN];
67 | bool sync;
68 | cycle_t *cycle;
69 | hotkey_t *next;
70 | hotkey_t *prev;
71 | };
72 |
73 | typedef struct {
74 | char *name;
75 | xcb_keysym_t keysym;
76 | } keysym_dict_t;
77 |
78 | hotkey_t *find_hotkey(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool *replay_event);
79 | bool match_chord(chord_t *chord, uint8_t event_type, xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield);
80 | bool chains_interfere(chain_t* a, chain_t* b);
81 | chord_t *make_chord(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool replay_event, bool lock_chain);
82 | void add_chord(chain_t *chain, chord_t *chord);
83 | chain_t *make_chain(void);
84 | cycle_t *make_cycle(int delay, int period);
85 | hotkey_t *make_hotkey(chain_t *chain, char *command);
86 | void add_hotkey(hotkey_t *hk);
87 | void abort_chain(void);
88 | void destroy_chain(chain_t *chain);
89 | void destroy_chord(chord_t *chord);
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------