#include #include #include #include char* getActiveLayout(char* names, unsigned char active) { int i; for (i = 0; names[i]; i++) { if (names[i] == '+') { if (active <= 0) { int j = ++i; for (; names[j] && names[j] != '+' && names[j] != ':'; j++); char* ret = malloc(j - i + 1); strncpy(ret, names + i, j - i); ret[j - i] = '\0'; return ret; } else { active--; } } } return NULL; } int main(void) { int evCode, errRet, rsnRet; int maj = XkbMajorVersion; int min = XkbMinorVersion; Display* disp = XkbOpenDisplay("", &evCode, &errRet, &maj, &min, &rsnRet); if (disp == NULL) { fprintf(stderr,"Failed to open display, is X running?\n"); exit(1); } // State XkbStatePtr state = calloc(1, sizeof(XkbStateRec)); XkbGetState(disp, 0x100, state); // Names XkbDescPtr desc = XkbAllocKeyboard(); XkbGetNames(disp, XkbSymbolsNameMask, desc); Atom symNameAtom = desc->names->symbols; char* layouts = XGetAtomName(disp, symNameAtom); printf("%s\n", getActiveLayout(layouts, state->group)); unsigned int mask = XkbStateNotifyMask; XkbSelectEvents(disp, XkbUseCoreKbd, mask, mask); XkbEvent event; while (1) { XNextEvent(disp, &event.core); if (event.state.changed & 0x90) printf("%s\n", getActiveLayout(layouts, event.state.group)); } }