1 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://sam.zoy.org/wtfpl/COPYING for more details.
17 #include <X11/XKBlib.h>
20 ////////////////////////////////////////////////////////////////////////////////
21 int activeLayout (Display
*dpy
) {
23 memset(&state
, 0, sizeof(state
));
24 XkbGetState(dpy
, XkbUseCoreKbd
, &state
);
25 return (int)state
.group
;
29 void setActiveLayout (Display
*dpy
, int group
) {
31 memset(&state
, 0, sizeof(state
));
32 XkbLockGroup(dpy
, XkbUseCoreKbd
, group
);
33 // the following call is necessary
34 XkbGetState(dpy
, XkbUseCoreKbd
, &state
);
38 int layoutNames (Display
*dpy
, char *names
[]) {
41 memset(&desc
, 0, sizeof(desc
));
42 desc
.device_spec
= XkbUseCoreKbd
;
43 XkbGetControls(dpy
, XkbGroupsWrapMask
, &desc
);
44 XkbGetNames(dpy
, XkbGroupNamesMask
, &desc
);
45 cnt
= (int)desc
.ctrls
->num_groups
;
46 XGetAtomNames(dpy
, desc
.names
->groups
, cnt
, names
);
47 XkbFreeControls(&desc
, XkbGroupsWrapMask
, True
);
48 XkbFreeNames(&desc
, XkbGroupNamesMask
, True
);
53 void freeLayoutNames (char **names
, int cnt
) {
54 for (; cnt
> 0; ++names
, --cnt
) if (*names
) { XFree(*names
); *names
= NULL
; }
58 void printLayouts (Display
*dpy
) {
59 char *names
[XkbNumKbdGroups
+1];
60 int cnt
= layoutNames(dpy
, names
);
61 int active
= activeLayout(dpy
);
62 for (int f
= 0; f
< cnt
; ++f
) printf("%d: %s%s\n", f
, names
[f
], f
==active
?" (active)":"");
63 freeLayoutNames(names
, cnt
);
67 int layoutCount (Display
*dpy
) {
69 memset(desc
, 0, sizeof(desc
));
70 desc
->device_spec
= XkbUseCoreKbd
;
71 XkbGetControls(dpy
, XkbGroupsWrapMask
, desc
);
72 return (int)desc
->ctrls
->num_groups
;