-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2b8fed6
commit eaf2922
Showing
3 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
Simple X11 1-key Keyboard layout switcher | ||
|
||
(c) Alexey Korop, 2014. Mailto: [email protected]. | ||
This is free software under GNU GPLv3. | ||
|
||
Installation | ||
|
||
Unpack archive and copy the s1kls file to the any location that is suitable for programs. | ||
|
||
Command line | ||
|
||
xkbs1kls keycode1 keycode2 ... | ||
|
||
The key with keycode 'keycode1' sets the layout 1, | ||
the key with keycode 'keycode2' sets the layout 2 ... | ||
|
||
Features | ||
|
||
Only LockGroup switch type supported (each key select the own layout). No layout indicator supported. | ||
Key codes you can find out by calling this program in the terminal without parameters. | ||
|
||
Backgrownd | ||
|
||
Standard X11 layout switcher is activated immediately by pressing the keys and therefore conflicts with the application shortcuts. | ||
This switcher is activated by releasing the keys, but only under the condition that no other key is pressed. For example, You were asked to switch to the layout 2 by RCtrl. Then if You press and release RCtrl, the layout will be switched. But if You pressed in a text editor RCtrl-Right, then the editor performs jump forward a word and layout will not be switched. | ||
|
||
If You need a layout indicator, You can use a standard X11 LED indicator or any tray indicator as xxkb. | ||
|
||
Example | ||
|
||
I use 3 layouts: (us,ru,ua), LED "ScrollLock" as indicator and keys following: RShift sets "us", RCtrl sets "ru" and RWin sets "ua". On the pc105 keyboard these keys have the keycodes 62, 105 and 134. | ||
|
||
In the X11 keyboard config (in my ArchLinux it is the file /etc/X11/xorg.conf.d/01-keyboard-layout.conf) I define: | ||
|
||
Option "XkbLayout" "us, ru, ua" | ||
Option "XkbOptions" "grp_led:scroll" | ||
|
||
In the autostart I call this program: | ||
|
||
xkbs1kls 62 105 134 & | ||
|
||
|
||
https://sourceforge.net/projects/s1kls/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
gcc -lX11 s1kls.c -O2 -o xkbs1kls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/* | ||
Simple X11 1-key Keyboard layout switcher. | ||
Only LockGroup switch type supported (each key select the own layout). | ||
No indicator supported. | ||
To switch layout You must press and realease the corresponding key; | ||
layout will be switched when the key is released, | ||
but only yf no other key(s) has been pressed. | ||
Developed by Alexey Korop, 2014 | ||
Compile: | ||
gcc -lX11 s1kls.c -o xkbs1kls | ||
This program is free software, under the GNU General Public License | ||
version 3. | ||
*/ | ||
|
||
#include <X11/Xlib.h> | ||
#include <X11/Xutil.h> | ||
#include <X11/XKBlib.h> | ||
#include <X11/Xlib.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
|
||
//#define TRACE | ||
|
||
static int switcher[16]; | ||
/* some keycodes on the pc105 keyboard: | ||
62 rshift | ||
105 rctrl | ||
108 ralt | ||
134 rwin | ||
50 lshift | ||
37 lctrl | ||
64 lalt | ||
133 lwin | ||
*/ | ||
|
||
typedef unsigned char bool; | ||
|
||
int main(int argc, char *argv[]) { | ||
Display *display; | ||
char keys_cur[32], keys_prev[32]; | ||
unsigned char diff, cur; | ||
int n_keys_pressed; | ||
int keycode = 0; | ||
int i; | ||
int byte, bit; | ||
int n; | ||
bool view_codes = 0; | ||
int layout = -1;/* | ||
-2 - Awaiting release all keys; | ||
-1 - all keys are released; | ||
0... - the key that selects this layout is pressed; expect its release */ | ||
|
||
for (n=0; n<argc-1; n++){ | ||
sscanf(argv[n+1], "%d", &switcher[n]); | ||
if (switcher[n] <= 0) | ||
goto help; | ||
} | ||
if (n < 2){ | ||
help: | ||
printf("Simple X11 1-key Keyboard layout switcher. Version 1.00.\n"); | ||
printf("(c) Alexey Korop, 2014. Free software under GNU GPLv3\n\n"); | ||
printf("Command line: s1kls keycode1 keycode2 ...\n\n"); | ||
printf("The key with keycode 'keycode1' sets the layout 1, \n"); | ||
printf("the key with keycode 'keycode2' sets the layout 2 ... \n\n"); | ||
printf("Now You may press the desired keys and see their keycodes.\n"); | ||
view_codes = 1; | ||
} | ||
|
||
display = XOpenDisplay(NULL); | ||
if (display == NULL){ | ||
fprintf(stderr, "XOpenDisplay error \n"); | ||
} | ||
|
||
XkbIgnoreExtension(False); | ||
XQueryKeymap(display, keys_prev); | ||
while(1) { | ||
XQueryKeymap(display, keys_cur); | ||
n_keys_pressed = 0; | ||
for (byte=0; byte<32; byte++) { | ||
cur = keys_cur[byte]; | ||
diff = keys_prev[byte] ^ cur; | ||
if (diff | cur) { | ||
keys_prev[byte] = cur; | ||
for (bit = 0; bit<8; bit++){ | ||
if (diff & 0x01){ | ||
if (!view_codes || (cur & 0x01)) | ||
keycode = byte*8 + bit; | ||
#ifdef TRACE | ||
printf("key %d", keycode); | ||
if (cur & 0x01) | ||
printf(" press\n"); | ||
else | ||
printf(" release\n"); | ||
#endif | ||
} | ||
if (cur & 0x01) | ||
n_keys_pressed++; | ||
diff >>= 1; | ||
cur >>= 1; | ||
} | ||
} | ||
} | ||
|
||
if (view_codes){ | ||
if (n_keys_pressed == 0){ | ||
if (keycode){ | ||
printf(" %4d \n", keycode); | ||
keycode = 0; | ||
} | ||
} | ||
} | ||
else { // normal work | ||
if (n_keys_pressed == 0){ | ||
if (layout >= 0){ | ||
#ifdef TRACE | ||
printf("new layout %d\n", layout); | ||
#endif | ||
if (!XkbLockGroup(display, XkbUseCoreKbd, layout)){ | ||
fprintf(stderr, "XkbLockGroup error \n"); | ||
return(1); | ||
} | ||
} | ||
layout = -1; | ||
} | ||
else if (layout == -2) | ||
; | ||
else if ((n_keys_pressed == 1) && (keycode == switcher[layout])) | ||
; //hold the key | ||
else if ((n_keys_pressed == 1) && (layout == -1)){ | ||
layout = -2; | ||
for (i=0; i<n; ++i) | ||
if (keycode == switcher[i]){ | ||
layout = i; | ||
#ifdef TRACE | ||
printf("wait for release the key %d\n", switcher[layout]); | ||
#endif | ||
break; | ||
} | ||
} | ||
else{ | ||
#ifdef TRACE | ||
if (layout >= 0) | ||
printf("reject waiting\n"); | ||
#endif | ||
layout = -2; | ||
} | ||
} | ||
usleep(20000); | ||
} | ||
// XCloseDisplay(display); | ||
} |