Bool initX11(void) { int revert_to_return; int keycode; int count = 0; KeySym keysym; if ((display = XOpenDisplay(NULL)) == NULL) return False; /* Find a key code to reprogram with all the different possible keys. This is required because not all keys that we want to test are available on all keyboards (e.g. the function keys up to F36). If we find a key that is not used, we can temporarily reprogram that key to the key we need for each key stroke. */ for (keycode = 255; keycode >= 0; keycode--) { if (XKeycodeToKeysym(display, keycode, 0) == NoSymbol) { reprogram_code[count++] = keycode; if (count == 4) break; } } if (count != 4) fatal("Can not use auto-learn because not enough reprogrammable keys were found\n"); keysym = XK_Shift_L; if (XChangeKeyboardMapping(display, reprogram_code[0], 1, &keysym, 1) != 0) fatal("Could not reprogram key\n"); keysym = XK_Control_L; if (XChangeKeyboardMapping(display, reprogram_code[1], 1, &keysym, 1) != 0) fatal("Could not reprogram key\n"); keysym = XK_Meta_L; if (XChangeKeyboardMapping(display, reprogram_code[2], 1, &keysym, 1) != 0) fatal("Could not reprogram key\n"); XGetInputFocus(display, &focus_window, &revert_to_return); if (focus_window == PointerRoot) { Window root, child; int root_x, root_y, win_x, win_y; unsigned int mask; XQueryPointer(display, DefaultRootWindow(display), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); focus_window = child; } if (focus_window == PointerRoot) { option_auto_learn = False; fatal("Auto-learn disabled because the current focus window could not be determined\n"); XCloseDisplay(display); } return True; }
EAPI int ecore_x_test_fake_key_press(const char *key) { #ifdef ECORE_XTEST KeyCode keycode = 0; KeySym keysym = 0; int shift = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!strncmp(key, "Keycode-", 8)) keycode = atoi(key + 8); else { keysym = XStringToKeysym(key); if (keysym == NoSymbol) return 0; keycode = XKeysymToKeycode(_ecore_x_disp, keysym); if (XKeycodeToKeysym(_ecore_x_disp, keycode, 0) != keysym) { if (XKeycodeToKeysym(_ecore_x_disp, keycode, 1) == keysym) shift = 1; else keycode = 0; } else shift = 0; } if (keycode == 0) { static int mod = 0; KeySym *keysyms; int keycode_min, keycode_max, keycode_num; int i; XDisplayKeycodes(_ecore_x_disp, &keycode_min, &keycode_max); keysyms = XGetKeyboardMapping(_ecore_x_disp, keycode_min, keycode_max - keycode_min + 1, &keycode_num); mod = (mod + 1) & 0x7; i = (keycode_max - keycode_min - mod - 1) * keycode_num; keysyms[i] = keysym; XChangeKeyboardMapping(_ecore_x_disp, keycode_min, keycode_num, keysyms, (keycode_max - keycode_min)); XFree(keysyms); XSync(_ecore_x_disp, False); keycode = keycode_max - mod - 1; } if (shift) XTestFakeKeyEvent(_ecore_x_disp, XKeysymToKeycode(_ecore_x_disp, XK_Shift_L), 1, 0); XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0); XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0); if (shift) XTestFakeKeyEvent(_ecore_x_disp, XKeysymToKeycode(_ecore_x_disp, XK_Shift_L), 0, 0); return 1; #else return 0; #endif }
void ModifiersModule::setupMacModifierKeys() { const int CODE_Ctrl_L = 0x25, CODE_Ctrl_R = 0x6d; const int CODE_Win_L = 0x73, CODE_Win_R = 0x74; //const int CODE_Alt_L = 0x40, CODE_Alt_R = 0x71; int keyCodeMin, keyCodeMax, nKeyCodes, nSymsPerCode; XDisplayKeycodes( tqt_xdisplay(), &keyCodeMin, &keyCodeMax ); nKeyCodes = keyCodeMax - keyCodeMin + 1; KeySym* rgKeySyms = XGetKeyboardMapping( tqt_xdisplay(), keyCodeMin, nKeyCodes, &nSymsPerCode ); XModifierKeymap* xmk = XGetModifierMapping( tqt_xdisplay() ); SET_CODE_SYM( CODE_Ctrl_L, XK_Super_L ) SET_CODE_SYM( CODE_Ctrl_R, XK_Super_R ) SET_CODE_SYM( CODE_Win_L, XK_Control_L ) SET_CODE_SYM( CODE_Win_R, XK_Control_R ) //SET_CODE_SYM( CODE_Win_L, XK_Alt_L ) //SET_CODE_SYM( CODE_Win_R, XK_Alt_R ) //SET_CODE_SYM( CODE_Alt_L, XK_Control_L ) //SET_CODE_SYM( CODE_Alt_R, XK_Control_R ) SET_MOD_CODE( ControlMapIndex, CODE_Win_L, CODE_Win_R ); SET_MOD_CODE( Mod4MapIndex, CODE_Ctrl_L, CODE_Ctrl_R ); //SET_MOD_CODE( ControlMapIndex, CODE_Alt_L, CODE_Alt_R ); //SET_MOD_CODE( Mod1MapIndex, CODE_Win_L, CODE_Win_R ); //SET_MOD_CODE( Mod4MapIndex, CODE_Ctrl_L, CODE_Ctrl_R ); XSetModifierMapping( tqt_xdisplay(), xmk ); XChangeKeyboardMapping( tqt_xdisplay(), keyCodeMin, nSymsPerCode, rgKeySyms, nKeyCodes ); XFree( rgKeySyms ); XFreeModifiermap( xmk ); }
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; i<SYMBOL_KEYS_COUNT; i++) { // loop by keybt for(int j=0; j<8; j++) { KEYCODE& kc = (*locale)[i]->codes[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; i<SYMBOL_KEYS_COUNT; i++) { // loop by keybt for(int j=0; j<8; j++) { KEYCODE& kc = (*locale)[i]->codes[j]; if (!kc.empty()) { if (kc.modifier > maxMapOffset) { for(int i1=0; i1<SYMBOL_KEYS_COUNT; i1++) for(int j1=0; j1<=maxMapOffset; j1++) if (keySyms[i1 * byte_per_code + j1]==NoSymbol) { kc.code =i1; kc.modifier =j1; break; } } keySyms[kc.code * byte_per_code + kc.modifier] = kc.symbol; } } } XChangeKeyboardMapping(display, min_keycodes, byte_per_code, keySyms, max_keycodes - min_keycodes); XFree(keySyms); XCloseDisplay(display); }
/* ensure that the multimedia keys are configured */ void configure_mmediakeys(){ KeySym newmap[1]; int i=0; pthread_mutex_lock(&x11mutex); for(i=0;i<6;i++){ newmap[0]=mmedia_defaults[i]; XChangeKeyboardMapping (dpy, mmedia_codes[i], 1, newmap, 1); } XFlush(dpy); pthread_mutex_unlock(&x11mutex); }
static int exec_keycode(struct op_keycode *opk) { if (!opk->target_keycode) { int i, j; KeyCode free; if (!opk->count) return (0); free = 0; for (i = min_keycode; i <= max_keycode; i++) { for (j = 0; j < opk->count; j++) { if (XKeycodeToKeysym(dpy, (KeyCode) i, j) != opk->keysyms[j]) break; } if (j >= opk->count) return (0); if (free) continue; for (j = 0; j < 8; j++) { if (XKeycodeToKeysym(dpy, (KeyCode) i, j) != None) break; } if (j >= 8) free = i; } if (!free) { fprintf(stderr, "%s: no available keycode for assignment\n", ProgramName); return (-1); } XChangeKeyboardMapping (dpy, free, opk->count, opk->keysyms, 1); } else if (opk->count == 0) { KeySym dummy = NoSymbol; XChangeKeyboardMapping (dpy, opk->target_keycode, 1, &dummy, 1); } else { XChangeKeyboardMapping (dpy, opk->target_keycode, opk->count, opk->keysyms, 1); } return (0); }
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 PressKey(wchar key, _XDisplay *dpy = NULL) { bool local = false; if (!dpy) { if (!(dpy = XOpenDisplay(NULL))) return; local = true; } wchar k = key; if (key > 0x00ff) key = key | 0x01000000; bool shift = false; KeyCode code = XKeysymToKeycode(dpy, key); if (code != 0) { if (XkbKeycodeToKeysym(dpy, code, 0, 0) != key) { if (XkbKeycodeToKeysym(dpy, code, 1, 0) == key) shift = true; else code = 0; } } else { int firstKeycode, maxKeycode; int keysymsPerKeycode; XDisplayKeycodes(dpy, &firstKeycode, &maxKeycode); KeySym *keysyms = XGetKeyboardMapping(dpy, firstKeycode, maxKeycode - firstKeycode + 1, &keysymsPerKeycode); int indx = (maxKeycode - firstKeycode - 1)*keysymsPerKeycode; keysyms[indx] = key; XChangeKeyboardMapping(dpy, firstKeycode, keysymsPerKeycode, keysyms, maxKeycode-firstKeycode); XSync(dpy, False); code = maxKeycode-1; if (XkbKeycodeToKeysym(dpy, code, 0, 0) != key) { if (XkbKeycodeToKeysym(dpy, code, 1, 0) == key) shift = true; } } if (code != 0) { if (shift) XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, XK_Shift_L), True, CurrentTime); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); if (shift) XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, XK_Shift_L), False, CurrentTime); } if (local) { XFlush(dpy); XCloseDisplay(dpy); } }
void change_keymap(int offset){ int i=0,j=0; //TODO: If they ever make a new G15keyboard(or this is reused for G19), change. int keys = G15Version == 0 ? 18 : 6; pthread_mutex_lock(&x11mutex); for(i=offset;i<offset + keys;i++,j++) { KeySym newmap[1]; newmap[0]=gkeydefaults[i]; XChangeKeyboardMapping (dpy, gkeycodes[j], 1, newmap, 1); } XFlush(dpy); pthread_mutex_unlock(&x11mutex); }
// Allocate a keycode for a special keysym. static bool allocateSpecialKeysym (Display *dpy, int& min_keycode, int& max_keycode, KeySym key) { if (XKeysymToKeycode(dpy, key) != NoSymbol) return true; // There is already a mapping for this key. Good! while (max_keycode >= min_keycode) { if (!keycodeInUse(dpy, max_keycode)) break; --max_keycode; } if (max_keycode < min_keycode) return false; XChangeKeyboardMapping(dpy, max_keycode, 1, &key, 1); --max_keycode; return true; }
void send_event(KeySym keysym, unsigned int state) { unsigned int current_state = 0; if (state & ShiftMask) { send_key(0, current_state, True); current_state |= ShiftMask; } if (state & ControlMask) { send_key(1, current_state, True); current_state |= ControlMask; } if (state & Mod1Mask) { send_key(2, current_state, True); current_state |= Mod1Mask; } if (XChangeKeyboardMapping(display, reprogram_code[3], 1, &keysym, 1) != 0) fatal("Could not reprogram key\n"); send_key(3, state, True); XSync(display, True); send_key(3, state, False); if (state & Mod1Mask) { send_key(2, current_state, False); current_state &= ~Mod1Mask; } if (state & ControlMask) { send_key(1, current_state, False); current_state &= ~ControlMask; } if (state & ShiftMask) { send_key(0, current_state, False); current_state &= ~ShiftMask; } XSync(display, True); }
static void setup_binding (Rebinder *rebinder, Binding *binding) { FakeKey *fake = rebinder->fake; /* evdev bindings */ if (is_evdev_enabled () && binding->keycode > 255) { Binding *evdev_binding; evdev_binding = g_slice_dup (Binding, binding); MEX_NOTE (REMAPPING, "evdev mapping %d to 0x%08x (%s)", evdev_binding->keycode, (int) evdev_binding->keysym, XKeysymToString (evdev_binding->keysym)); g_ptr_array_add (rebinder->evdev_bindings, evdev_binding); return; } /* X bindings */ else if (binding->keycode < fake->min_keycode || binding->keycode > fake->max_keycode) { g_warning ("Cannot use the keycode %d as it's outside the allowed range " "[%d..%d]", binding->keycode, fake->min_keycode, fake->max_keycode); return; } MEX_NOTE (REMAPPING, "Rebinding %d to 0x%08x (%s)", binding->keycode, (guint) binding->keysym, XKeysymToString (binding->keysym)); XChangeKeyboardMapping (rebinder->dpy, binding->keycode, 1, &binding->keysym, 1); }
main() { Window w2; Display *dpy = XOpenDisplay(NIL); assert(dpy); Screen *scr = DefaultScreenOfDisplay(dpy); // CreateWindow Window w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XDestroyWindow(dpy, w); // CreateWindow with arguments XSetWindowAttributes swa; swa.background_pixel = WhitePixelOfScreen(scr); swa.bit_gravity = NorthWestGravity; swa.border_pixel = BlackPixelOfScreen(scr); swa.colormap = DefaultColormapOfScreen(scr); swa.cursor = None; swa.win_gravity = NorthGravity; w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWWinGravity, &swa); // CreateWindow with other arguments XDestroyWindow(dpy, w); Pixmap pixmap = XCreatePixmap(dpy, RootWindowOfScreen(scr), 45, 25, DefaultDepthOfScreen(scr)); assert(pixmap); swa.background_pixmap = pixmap; swa.border_pixmap = pixmap; w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixmap | CWBorderPixmap, &swa); // ChangeWindowAttributes swa.backing_planes = 0x1; swa.backing_pixel = WhitePixelOfScreen(scr); swa.save_under = True; swa.event_mask = KeyPressMask | KeyReleaseMask; swa.do_not_propagate_mask = ButtonPressMask | Button4MotionMask; swa.override_redirect = False; XChangeWindowAttributes(dpy, w, CWBackingPlanes | CWBackingPixel | CWSaveUnder | CWEventMask | CWDontPropagate | CWOverrideRedirect, &swa); // GetWindowAttributes XWindowAttributes wa; Status success = XGetWindowAttributes(dpy, w, &wa); // DestroyWindow (done) // DestroySubwindows w2 = XCreateWindow(dpy, w, 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XDestroySubwindows(dpy, w); // ChangeSaveSet // Display *dpy2 = XOpenDisplay(NIL); // assert(dpy2); // XAddToSaveSet(dpy2, w); // XCloseDisplay(dpy2); // ReparentWindow w2 = XCreateWindow(dpy, RootWindowOfScreen(scr), 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XReparentWindow(dpy, w2, w, 10, 5); // MapWindow XMapWindow(dpy, w); // MapSubwindows XMapSubwindows(dpy, w); // UnmapWindow XUnmapWindow(dpy, w); // UnmapSubwindows XMapWindow(dpy, w); XUnmapSubwindows(dpy, w2); XMapSubwindows(dpy, w); // ConfigureWindow Window w3 = XCreateWindow(dpy, w, 10, 50, 100, 10, 2, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XMapWindow(dpy, w3); XWindowChanges wc; wc.x = -5; wc.y = -10; wc.width = 50; wc.height = 40; wc.border_width = 7; wc.sibling = w2; wc.stack_mode = Opposite; XConfigureWindow(dpy, w3, CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWSibling | CWStackMode, &wc); // CirculateWindow XCirculateSubwindows(dpy, w, RaiseLowest); // GetGeometry Window root; int x, y; unsigned width, height, border_width, depth; XGetGeometry(dpy, w, &root, &x, &y, &width, &height, &border_width, &depth); // QueryTree Window parent; Window *children; unsigned nchildren; success = XQueryTree(dpy, w, &root, &parent, &children, &nchildren); XFree(children); // InternAtom Atom a = XInternAtom(dpy, "WM_PROTOCOLS", True); // GetAtomName char *string = XGetAtomName(dpy, XA_PRIMARY); XFree(string); // ChangeProperty XStoreName(dpy, w, "test window"); // DeleteProperty XDeleteProperty(dpy, w, XA_WM_NAME); // GetProperty // TODO // ListProperties int num_prop; Atom *list = XListProperties(dpy, w, &num_prop); XFree(list); // SetSelectionOwner XSetSelectionOwner(dpy, XA_PRIMARY, w, 12000); XSetSelectionOwner(dpy, XA_SECONDARY, w, CurrentTime); // GetSelectionOwner Window wx = XGetSelectionOwner(dpy, XA_PRIMARY); // ConvertSelection XConvertSelection(dpy, XA_SECONDARY, XA_CURSOR, XA_POINT, w, CurrentTime); // SendEvent // GrabPointer std::cerr << "Grabbing" << std::endl; int res = XGrabPointer(dpy, w, False, Button5MotionMask | PointerMotionHintMask, GrabModeSync, GrabModeAsync, w, None, CurrentTime); XSync(dpy, False); // sleep(5); // UngrabPointer std::cerr << "Ungrabbing" << std::endl; XUngrabPointer(dpy, CurrentTime); // GrabButton XGrabButton(dpy, 3, ShiftMask | ControlMask, w, False, PointerMotionHintMask | Button2MotionMask, GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, 2, AnyModifier, w, False, PointerMotionHintMask | Button2MotionMask, GrabModeAsync, GrabModeSync, None, None); // UngrabButton XUngrabButton(dpy, 2, LockMask, w); // ChangeActivePointerGrab XChangeActivePointerGrab(dpy, ButtonPressMask, None, CurrentTime); // GrabKeyboard XGrabKeyboard(dpy, w, True, GrabModeSync, GrabModeSync, 12000); // UngrabKeyboard XUngrabKeyboard(dpy, 13000); // GrabKey XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), ShiftMask | Mod3Mask, w, True, GrabModeSync, GrabModeSync); // UngrabKey XUngrabKey(dpy, AnyKey, AnyModifier, w); // AllowEvents XAllowEvents(dpy, AsyncPointer, 14000); // GrabServer XGrabServer(dpy); // UngrabServer XUngrabServer(dpy); // QueryPointer Window child; int root_x, root_y, win_x, win_y; unsigned mask; Bool bres = XQueryPointer(dpy, w, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); // GetMotionEvents int nevents; XGetMotionEvents(dpy, w, 15000, 16000, &nevents); // TranslateCoordinates int dest_x, dest_y; XTranslateCoordinates(dpy, w, w2, 10, 20, &dest_x, &dest_y, &child); // WarpPointer XWarpPointer(dpy, w, w2, 0, 0, 100, 100, 20, 30); // SetInputFocus XSetInputFocus(dpy,w, RevertToPointerRoot, 17000); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, 17000); // GetInputFocus Window focus; int revert_to; XGetInputFocus(dpy, &focus, &revert_to); // QueryKeymap char keys_return[32]; XQueryKeymap(dpy, keys_return); // OpenFont Font fid = XLoadFont(dpy, "cursor"); // CloseFont XUnloadFont(dpy, fid); // QueryFont XFontStruct *fs = XLoadQueryFont(dpy, "cursor"); assert(fs); // QueryTextExtents int direction, font_ascent, font_descent; XCharStruct overall; XQueryTextExtents(dpy, fs -> fid, "toto", 4, &direction, &font_ascent, &font_descent, &overall); XQueryTextExtents(dpy, fs -> fid, "odd__length", 11, &direction, &font_ascent, &font_descent, &overall); XChar2b c2bs; c2bs.byte1 = '$'; c2bs.byte2 = 'B'; XQueryTextExtents16(dpy, fs -> fid, &c2bs, 1, &direction, &font_ascent, &font_descent, &overall); XQueryTextExtents(dpy, fs -> fid, longString, strlen(longString), &direction, &font_ascent, &font_descent, &overall); // ListFonts int actual_count; char **fontList = XListFonts(dpy, "*", 100, &actual_count); XFree((char *)fontList); // ListFontsWithInfo int count; XFontStruct *info; char **names = XListFontsWithInfo(dpy, "*", 100, &count, &info); XFreeFontInfo(names, info, count); // SetFontPath // GetFontPath int npaths; char **charList = XGetFontPath(dpy, &npaths); char **charList2 = new char *[npaths + 1]; memcpy(charList2, charList, npaths * sizeof(char *)); charList2[npaths] = charList2[0]; XSetFontPath(dpy, charList2, npaths + 1); XSetFontPath(dpy, charList, npaths); // Reset to some reasonnable value XFreeFontPath(charList); delete [] charList2; // CreatePixmap Pixmap pix2 = XCreatePixmap(dpy, w, 100, 200, DefaultDepthOfScreen(scr)); // FreePixmap XFreePixmap(dpy, pix2); // CreateGC Pixmap bitmap = XCreateBitmapFromData(dpy, RootWindowOfScreen(scr), "\000\000\001\000\000\001\000\000\001\377\377\377", 3, 4); XGCValues gcv; gcv.function = GXand; gcv.plane_mask = 0x1; gcv.foreground = WhitePixelOfScreen(scr); gcv.background = BlackPixelOfScreen(scr); gcv.line_width = 2; gcv.line_style = LineDoubleDash; gcv.cap_style = CapProjecting; gcv.join_style = JoinRound; gcv.fill_style = FillStippled; gcv.fill_rule = EvenOddRule; gcv.arc_mode = ArcPieSlice; gcv.tile = pixmap; gcv.stipple = bitmap; gcv.ts_x_origin = 3; gcv.ts_y_origin = 4; gcv.font = fs -> fid; gcv.subwindow_mode = ClipByChildren; gcv.graphics_exposures = True; gcv.clip_x_origin = 5; gcv.clip_y_origin = 6; gcv.clip_mask = bitmap; gcv.dash_offset = 1; gcv.dashes = 0xc2; GC gc = XCreateGC(dpy, w, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList | GCArcMode, &gcv); // ChangeGC gcv.function = GXandReverse; // Only a few of these should appear, since the values are cached on the client side by the Xlib. XChangeGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, &gcv); // CopyGC GC gc2 = XCreateGC(dpy, w, 0, NIL); XCopyGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, gc2); // SetDashes XSetDashes(dpy, gc, 3, "\001\377\001", 3); // SetClipRectangles XRectangle rectangles[] = { { 10, 20, 30, 40 }, { 100, 200, 5, 3 }, { -5, 1, 12, 24 } }; XSetClipRectangles(dpy, gc, 12, 9, rectangles, SIZEOF(rectangles), Unsorted); // FreeGC // done already // ClearArea XClearArea(dpy, w, 30, 10, 10, 100, False); // CopyArea XCopyArea(dpy, w, pixmap, gc, 0, 0, 100, 100, 10, 10); // CopyPlane // This won't work if the Screen doesn't have at least 3 planes XCopyPlane(dpy, pixmap, w, gc, 20, 10, 40, 30, 0, 0, 0x4); // PolyPoint XDrawPoint(dpy, w, gc, 1, 2); XPoint points[] = { { 3, 4 }, { 5, 6 } }; XDrawPoints(dpy, w, gc, points, SIZEOF(points), CoordModeOrigin); // PolyLine XDrawLines(dpy, w, gc, points, SIZEOF(points), CoordModePrevious); // PolySegment XSegment segments[] = { { 7, 8, 9, 10 }, { 11, 12, 13, 14 }, { 15, 16, 17, 18 } }; XDrawSegments(dpy, w, gc, segments, SIZEOF(segments)); // PolyRectangle XDrawRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles)); // PolyArc XArc arcs[] = { { 10, 20, 30, 40, 50, 60 }, { -70, 80, 90, 100, 110, 120 }, { 10, 20, 30, 40, 50, -30 } }; XDrawArcs(dpy, w, gc, arcs, SIZEOF(arcs)); // FillPoly XFillPolygon(dpy, w, gc, points, SIZEOF(points), Convex, CoordModePrevious); // PolyFillRectangle XFillRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles)); // PolyFillArc XFillArcs(dpy, w, gc, arcs, SIZEOF(arcs)); // PutImage // GetImage XImage *image = XGetImage(dpy, w, 10, 20, 40, 30, AllPlanes, ZPixmap); XPutImage(dpy, w, gc, image, 0, 0, 50, 60, 40, 30); XSync(dpy, False); // Make the next request starts at the beginning of a packet // PolyText8 XTextItem textItems[3]; textItems[0].chars = "toto"; textItems[0].nchars = strlen(textItems[0].chars); textItems[0].delta = -3; textItems[0].font = fs->fid; textItems[1].chars = "titi"; textItems[1].nchars = strlen(textItems[1].chars); textItems[1].delta = 3; textItems[1].font = None; textItems[2].chars = "tutu"; textItems[2].nchars = strlen(textItems[2].chars); textItems[2].delta = 0; textItems[2].font = fs->fid; XDrawText(dpy, w, gc, 10, 10, textItems, 3); XTextItem textItems2[3]; textItems2[0].chars = "totox"; textItems2[0].nchars = strlen(textItems2[0].chars); textItems2[0].delta = -3; textItems2[0].font = fs->fid; textItems2[1].chars = "titi"; textItems2[1].nchars = strlen(textItems2[1].chars); textItems2[1].delta = 3; textItems2[1].font = None; textItems2[2].chars = "tutu"; textItems2[2].nchars = strlen(textItems2[2].chars); textItems2[2].delta = 0; textItems2[2].font = fs->fid; XDrawText(dpy, w, gc, 10, 10, textItems2, 3); // PolyText16 XChar2b c2b2[] = { 0, 't', 0, 'x' }; XTextItem16 items16[] = { { &c2bs, 1, -5, None }, { NULL, 0, 0, None }, { c2b2, 2, 0, fs -> fid } }; XDrawText16(dpy, w, gc, 10, 0, items16, SIZEOF(items16)); // ImageText8 XDrawImageString(dpy, w, gc, 10, 10, "toto", 4); // ImageText16 XDrawImageString16(dpy, w, gc, 10, 10, &c2bs, 1); XDrawImageString16(dpy, w, gc, 10, 20, c2b2, 2); // CreateColormap // Don't forget to tell the kids how it was when we had only 8 bits per pixel. Colormap colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None); // FreeColormap XFreeColormap(dpy, colormap); colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None); // CopyColormapAndFree Colormap colormap2 = XCopyColormapAndFree(dpy, colormap); // InstallColormap XInstallColormap(dpy, colormap2); // UninstallColormap XUninstallColormap(dpy, colormap2); // ListInstalledColormaps int num; Colormap *colormapList = XListInstalledColormaps(dpy, w, &num); // AllocColor XColor screen; screen.red = 0; screen.green = 32767; screen.blue = 65535; screen.flags = DoRed | DoGreen | DoBlue; success = XAllocColor(dpy, colormap, &screen); // AllocNamedColor XColor screen2, exact; success = XAllocNamedColor(dpy, colormap, "Wheat", &screen2, &exact); // AllocColorCells unsigned long plane_masks, pixels; success = XAllocColorCells(dpy, colormap, False, &plane_masks, 1, &pixels, 1); // AllocColorPlanes unsigned long rmask, gmask, bmask; success = XAllocColorPlanes(dpy, colormap, False, &pixels, 1, 0, 0, 0, &rmask, &gmask, &bmask); // FreeColors unsigned long pixels2[2] = { screen.pixel, screen2.pixel }; XFreeColors(dpy, colormap, pixels2, 2, 0); // StoreColors success = XAllocColorCells(dpy, colormap, False, NIL, 0, pixels2, 2); // On many contemporary (that is, year 2000) video cards, you can't allocate read / write cells // I want my requests to be sent, however. if (!success) { XSetErrorHandler(errorHandler); } XColor colors[2]; colors[0] = screen; colors[0].pixel = pixels2[0]; colors[1] = screen2; colors[1].pixel = pixels2[1]; XStoreColors(dpy, colormap, colors, 2); // StoreNamedColor XStoreNamedColor(dpy, colormap, "Wheat", colors[0].pixel, DoBlue); XSync(dpy, False); XSetErrorHandler(NIL); // Restore the default handler // QueryColors screen2.pixel = WhitePixelOfScreen(scr); XQueryColor(dpy, colormap, &screen2); // LookupColor success = XLookupColor(dpy, colormap, "DarkCyan", &exact, &screen); // CreateCursor Cursor cursor = XCreatePixmapCursor(dpy, pixmap, None, &exact, colors, 10, 10); // CreateGlyphCursor Cursor cursor2 = XCreateGlyphCursor(dpy, fs -> fid, fs -> fid, 'X', 0, &exact, colors); // FreeCursor XFreeCursor(dpy, cursor2); // RecolorCursor XRecolorCursor(dpy, cursor, colors, &exact); // QueryBestSize success = XQueryBestSize(dpy, CursorShape, RootWindowOfScreen(scr), 100, 20, &width, &height); // QueryExtension int major_opcode, first_event, first_error; XQueryExtension(dpy, "toto", &major_opcode, &first_event, &first_error); // ListExtensions int nextensions; char **extensionList = XListExtensions(dpy, &nextensions); for(char **p = extensionList; nextensions; nextensions--, p++) std::cout << *p << std::endl; XFree(extensionList); // ChangeKeyboardMapping // GetKeyboardMapping int min_keycodes, max_keycodes; XDisplayKeycodes(dpy, &min_keycodes, &max_keycodes); int keysyms_per_keycode; KeySym *keysyms = XGetKeyboardMapping(dpy, min_keycodes, max_keycodes - min_keycodes + 1, &keysyms_per_keycode); XChangeKeyboardMapping(dpy, min_keycodes, keysyms_per_keycode, keysyms, max_keycodes - min_keycodes + 1); // ChangeKeyboardControl // GetKeyboardControl XKeyboardState keyboardState; XGetKeyboardControl(dpy, &keyboardState); XKeyboardControl keyboardValues; keyboardValues.key_click_percent = keyboardState.key_click_percent; keyboardValues.bell_percent = keyboardState.bell_percent; keyboardValues.bell_pitch = keyboardState.bell_pitch; keyboardValues.bell_duration = keyboardState.bell_duration; keyboardValues.led = 1; keyboardValues.led_mode = LedModeOn; keyboardValues.key = min_keycodes; keyboardValues.auto_repeat_mode = AutoRepeatModeDefault; XChangeKeyboardControl(dpy, KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration | KBLed | KBLedMode | KBKey | KBAutoRepeatMode, &keyboardValues); // Bell XBell(dpy, 90); // ChangePointerControl // GetPointerControl int accel_numerator, accel_denominator, threshold; XGetPointerControl(dpy, &accel_numerator, &accel_denominator, &threshold); XChangePointerControl(dpy, True, True, accel_numerator, accel_denominator, threshold); // SetScreenSaver // GetScreenSaver int timeout, interval, prefer_blanking, allow_exposures; XGetScreenSaver(dpy, &timeout, &interval, &prefer_blanking, &allow_exposures); XSetScreenSaver(dpy, timeout, interval, prefer_blanking, allow_exposures); // ChangeHosts // ListHosts int nhosts; Bool state; XHostAddress *hostList = XListHosts(dpy, &nhosts, &state); XHostAddress host; host.family = FamilyInternet; host.length = 4; host.address = "\001\002\003\004"; XAddHost(dpy, &host); // SetAccessControl XSetAccessControl(dpy, EnableAccess); // SetCloseDownMode XSetCloseDownMode(dpy, RetainTemporary); // KillClient XKillClient(dpy, AllTemporary); // RotateProperties Atom properties[] = { XInternAtom(dpy, "CUT_BUFFER0", False), XInternAtom(dpy, "CUT_BUFFER1", False), XInternAtom(dpy, "CUT_BUFFER2", False) }; XRotateWindowProperties(dpy, RootWindowOfScreen(scr), properties, SIZEOF(properties), -1); // ForceScreenSaver XForceScreenSaver(dpy, ScreenSaverReset); // SetPointerMapping // GetPointerMapping unsigned char map[64]; int map_length = XGetPointerMapping(dpy, map, 64); XSetPointerMapping(dpy, map, map_length); // SetModifierMapping // GetModifierMapping XModifierKeymap *modmap = XGetModifierMapping(dpy); XSetModifierMapping(dpy, modmap); // NoOperation XNoOp(dpy); for(;;) { XEvent e; XNextEvent(dpy, &e); std::cout << "Got an event of type " << e.type << std::endl; } }
int main(int argc, char **argv) { char *window_name = "xkbd"; char *icon_name = "xkbd"; #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 #define MWM_HINTS_DECORATIONS (1L << 1) #define MWM_DECOR_BORDER (1L << 1) typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; } PropMotifWmHints ; PropMotifWmHints *mwm_hints; XSizeHints size_hints; XWMHints *wm_hints; char *display_name = (char *)getenv("DISPLAY"); Xkbd *kb = NULL; char *wm_name; int wm_type = WM_UNKNOWN; char *geometry = NULL; int xret=0, yret=0, wret=0, hret=0; char *conf_file = NULL; char *font_name = NULL; int cmd_xft_selected = 0; /* ugly ! */ int embed = 0; Bool use_normal_win = False; XEvent an_event; int done = 0; int i; char userconffile[256]; FILE *fp; KeySym mode_switch_ksym; // bthid pipe bthid_open(); // parent if ((bthid_pid = fork())) { close(0); } // child else { close(1); sdp_open(); sdp_add_keyboard(); bthid(es[0]); exit(0); } for (i=1; argv[i]; i++) { char *arg = argv[i]; if (*arg=='-') { switch (arg[1]) { case 'd' : /* display */ display_name = argv[i+1]; i++; break; case 'g' : geometry = argv[i+1]; i++; break; case 'f': font_name = argv[i+1]; #ifdef USE_XFT cmd_xft_selected = 1; #endif break; case 'o' : /* wm override */ case 't' : fprintf( stderr, "Overide redirect support deprciated\n"); exit(1); break; case 'k' : conf_file = argv[i+1]; i++; break; case 'x' : embed = 1; break; case 'n' : use_normal_win = True; break; case 'v' : version(); exit(0); break; default: usage(); exit(0); break; } } } display = XOpenDisplay(display_name); if (display != NULL) { Atom wm_protocols[]={ XInternAtom(display, "WM_DELETE_WINDOW",False), XInternAtom(display, "WM_PROTOCOLS",False), XInternAtom(display, "WM_NORMAL_HINTS", False), }; Atom window_type_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE" , False); Atom window_type_toolbar_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_TOOLBAR",False); Atom mwm_atom = XInternAtom(display, "_MOTIF_WM_HINTS",False); Atom window_type_dock_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK",False); /* HACK to get libvirtkeys to work without mode_switch */ screen_num = DefaultScreen(display); if (XKeysymToKeycode(display, XK_Mode_switch) == 0) { int keycode; int min_kc, max_kc; XDisplayKeycodes(display, &min_kc, &max_kc); for (keycode = min_kc; keycode <= max_kc; keycode++) if (XKeycodeToKeysym (display, keycode, 0) == NoSymbol) { mode_switch_ksym = XStringToKeysym("Mode_switch"); XChangeKeyboardMapping(display, keycode, 1, &mode_switch_ksym, 1); XSync(display, False); } } wm_name = get_current_window_manager_name (); use_normal_win = True; if (wm_name) { wm_type = WM_EHWM_UNKNOWN; if (!strcmp(wm_name, "metacity")) wm_type = WM_METACITY; else if (!strcmp(wm_name, "matchbox")) { use_normal_win = False; wm_type = WM_MATCHBOX; } } win = XCreateSimpleWindow(display, RootWindow(display, screen_num), 0, 0, 300, 300, 0, BlackPixel(display, screen_num), WhitePixel(display, screen_num)); if (geometry != NULL) { XParseGeometry(geometry, &xret, &yret, &wret, &hret ); } else { if (wm_type != WM_MATCHBOX) { wret = DisplayWidth(display, screen_num); hret = DisplayHeight(display, screen_num)/4; xret = 0; yret = DisplayHeight(display, screen_num) - hret; } } /* check for user selected keyboard conf file */ if (conf_file == NULL) { strcpy(userconffile,getenv("HOME")); strcat(userconffile, "/.xkbd"); if ((fp = fopen(userconffile, "r")) != NULL) { conf_file = (char *)malloc(sizeof(char)*512); if (fgets(conf_file, 512, fp) != NULL) { fclose(fp); if ( conf_file[strlen(conf_file)-1] == '\n') conf_file[strlen(conf_file)-1] = '\0'; } } else { conf_file = DEFAULTCONFIG; } } kb = xkbd_realize(display, win, conf_file, font_name, 0, 0, wret, hret, cmd_xft_selected); XResizeWindow(display, win, xkbd_get_width(kb), xkbd_get_height(kb)); if (xret || yret) XMoveWindow(display,win,xret,yret); size_hints.flags = PPosition | PSize | PMinSize; size_hints.x = 0; size_hints.y = 0; size_hints.width = xkbd_get_width(kb); size_hints.height = xkbd_get_height(kb); size_hints.min_width = xkbd_get_width(kb); size_hints.min_height = xkbd_get_height(kb); XSetStandardProperties(display, win, window_name, icon_name, 0, argv, argc, &size_hints); wm_hints = XAllocWMHints(); wm_hints->input = False; wm_hints->flags = InputHint; XSetWMHints(display, win, wm_hints ); /* Tell the WM we dont want no borders */ mwm_hints = malloc(sizeof(PropMotifWmHints)); memset(mwm_hints, 0, sizeof(PropMotifWmHints)); mwm_hints->flags = MWM_HINTS_DECORATIONS; mwm_hints->decorations = 0; XChangeProperty(display, win, mwm_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)mwm_hints, PROP_MOTIF_WM_HINTS_ELEMENTS); free(mwm_hints); XSetWMProtocols(display, win, wm_protocols, sizeof(wm_protocols) / sizeof(Atom)); if (use_normal_win == False) XChangeProperty(display, win, window_type_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *) &window_type_toolbar_atom, 1); if (embed) { fprintf(stdout, "%i\n", win); fclose(stdout); } else { XMapWindow(display, win); } signal(SIGUSR1, handle_sig); /* for extenal mapping / unmapping */ XSelectInput(display, win, ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | StructureNotifyMask | VisibilityChangeMask); while (!done) { while ( XPending(display) ) { XNextEvent(display, &an_event); xkbd_process(kb, &an_event); switch (an_event.type) { case ClientMessage: if ((an_event.xclient.message_type == wm_protocols[1]) && (an_event.xclient.data.l[0] == wm_protocols[0])) done = 1; break; case ConfigureNotify: if ( an_event.xconfigure.width != xkbd_get_width(kb) || an_event.xconfigure.height != xkbd_get_height(kb)) { xkbd_resize(kb, an_event.xconfigure.width, an_event.xconfigure.height ); } break; case Expose: xkbd_repaint(kb); break; } } xkbd_process_repeats(kb); usleep(10000L); /* sleep for a 10th of a second */ } xkbd_destroy(kb); XCloseDisplay(display); } else { fprintf(stderr, "%s: cannot connect to X server '%s'\n", argv[0], display_name); exit(1); } exit(0); }
long keysym2keycode(virtkey * cvirt, KeySym keysym, int * flags){ static int modifiedkey; KeyCode code = 0; if ((code = XKeysymToKeycode(cvirt->display, keysym)) != 0) { if (XKeycodeToKeysym(cvirt->display, code, 0) != keysym) { if (XKeycodeToKeysym(cvirt->display, code, 1) == keysym) *flags |= 1; //can get at it via shift else code = 0; // urg, some other modifier do it the heavy way } } if (!code) { int index; // Change one of the last 10 keysyms to our converted utf8, // remapping the x keyboard on the fly. // // This make assumption the last 10 arn't already used. // TODO: probably safer to check for this. modifiedkey = (modifiedkey+1) % 10; // Point at the end of keysyms, modifier 0 index = (cvirt->max_keycode - cvirt->min_keycode - modifiedkey - 1) * cvirt->n_keysyms_per_keycode; cvirt->keysyms[index] = keysym; XChangeKeyboardMapping(cvirt->display, cvirt->min_keycode, cvirt->n_keysyms_per_keycode, cvirt->keysyms, (cvirt->max_keycode-cvirt->min_keycode)); XSync(cvirt->display, False); // From dasher src; // There's no way whatsoever that this could ever possibly // be guaranteed to work (ever), but it does. code = cvirt->max_keycode - modifiedkey - 1; // The below is lightly safer; // // code = XKeysymToKeycode(fk->display, keysym); // // but this appears to break in that the new mapping is not immediatly // put to work. It would seem a MappingNotify event is needed so // Xlib can do some changes internally ? ( xlib is doing something // related to above ? ) // // Probably better to try and grab the mapping notify *here* ? } return code; }