/* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "UBKeyboardPalette.h" #include #include // The key code to be sent. // A full list of available codes can be found in /usr/include/X11/keysymdef.h //#define KEYCODE XK_Down // Function to create a keyboard event XKeyEvent createKeyEvent(Display *display, Window &win, Window &winRoot, bool press, int keycode, int modifiers) { XKeyEvent event; event.display = display; event.window = win; event.root = winRoot; event.subwindow = None; event.time = CurrentTime; event.x = 1; event.y = 1; event.x_root = 1; event.y_root = 1; event.same_screen = True; event.keycode = keycode; event.state = modifiers; if(press) event.type = KeyPress; else event.type = KeyRelease; return event; } void x11SendKey(Display *display, int keyCode, int modifiers) { // Get the root window for the current display. Window winRoot = XDefaultRootWindow(display); if (winRoot==0) return; // Find the window which has the current keyboard focus. Window winFocus; int revert; XGetInputFocus(display, &winFocus, &revert); // Send a fake key press event to the window. XKeyEvent event = createKeyEvent(display, winFocus, winRoot, true, keyCode, modifiers); XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); // Send a fake key release event to the window. event = createKeyEvent(display, winFocus, winRoot, false, keyCode, modifiers); XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); } /* void traceKeyCodes() { Display *display = XOpenDisplay(0); if(display == NULL) return; int min_keycodes, max_keycodes, byte_per_code; XDisplayKeycodes(display, &min_keycodes, &max_keycodes); KeySym* keySyms = XGetKeyboardMapping(display, min_keycodes, max_keycodes - min_keycodes, &byte_per_code); qDebug() << "Codes table, min_keycodes: " << min_keycodes << ", max_keycodes: " << max_keycodes << ", bytes_per_code:" << byte_per_code; for(int i=0; imin_keycodes , modifier); } XCloseDisplay(display); } void UBKeyboardButton::sendControlSymbol(int nSymbol) { // Obtain the X11 display. Display *display = XOpenDisplay(0); if(display == NULL) return; KeyCode keyCode = XKeysymToKeycode(display, nSymbol); if (keyCode != NoSymbol) { x11SendKey(display, keyCode, 0); } XCloseDisplay(display); } void UBKeyboardPalette::createCtrlButtons() { ctrlButtons = new UBKeyboardButton*[9]; ctrlButtons[0] = new UBCntrlButton(this, XK_BackSpace, "backspace"); ctrlButtons[1] = new UBCntrlButton(this, XK_Tab, "tab"); ctrlButtons[2] = new UBCapsLockButton(this, "capslock"); ctrlButtons[3] = new UBCntrlButton(this, tr("Enter"), XK_Return); ctrlButtons[4] = new UBShiftButton(this, "shift"); ctrlButtons[5] = new UBShiftButton(this, "shift"); ctrlButtons[6] = new UBLocaleButton(this); ctrlButtons[7] = new UBCntrlButton(this, "", XK_space); ctrlButtons[8] = new UBLocaleButton(this); } void UBKeyboardPalette::onActivated(bool activated) { if (activated) { if (storage) { qDebug() << "Keybard already activated...."; return; } Display *display = XOpenDisplay(0); if(display == NULL) return; XDisplayKeycodes(display, &this->min_keycodes, &this->max_keycodes); KeySym* keySyms = XGetKeyboardMapping(display, min_keycodes, max_keycodes - min_keycodes, &byte_per_code); storage = keySyms; XCloseDisplay(display); onLocaleChanged(locales[nCurrentLocale]); } else { Display *display = XOpenDisplay(0); if(display == NULL) { qDebug() << "Keybard not activated...."; return; } KeySym* keySyms = (KeySym*)storage; if (keySyms!=NULL) { qDebug() << "Default key table restored....."; XChangeKeyboardMapping(display, min_keycodes, byte_per_code, keySyms, max_keycodes - min_keycodes); XFree(keySyms); storage = NULL; } XCloseDisplay(display); } } void UBKeyboardPalette::onLocaleChanged(UBKeyboardLocale* locale) { const int maxMapOffset = 3; //Suppose to have at least 2 keysym groups due to X11 xlib specification Display *display = XOpenDisplay(0); if(display == NULL) return; int byte_per_code; KeySym* keySyms = XGetKeyboardMapping(display, min_keycodes, max_keycodes - min_keycodes, &byte_per_code); for(int i=0; icodes[j]; if (!kc.empty()) { if (kc.modifier <= maxMapOffset) keySyms[kc.code * byte_per_code + kc.modifier] = kc.symbol; } } } //Now look for modifiers > 5 and reassign them to free places for(int i=0; icodes[j]; if (!kc.empty()) { if (kc.modifier > maxMapOffset) { for(int i1=0; i1