int init_xkb(void *dpy) { return XkbQueryExtension(dpy, NULL, NULL, NULL, NULL, NULL); }
// Initialize X11 display and look for supported X11 extensions // static GLFWbool initExtensions(void) { #if defined(_GLFW_HAS_XF86VM) // Check for XF86VidMode extension _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); #endif /*_GLFW_HAS_XF86VM*/ // Check for RandR extension if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase)) { if (XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.major, &_glfw.x11.randr.minor)) { // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) _glfw.x11.randr.available = GLFW_TRUE; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); } } if (_glfw.x11.randr.available) { XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { // This is either a headless system or an older Nvidia binary driver // with broken gamma support // Flag it as useless and fall back to Xf86VidMode gamma, if // available _glfwInputError(GLFW_PLATFORM_ERROR, "X11: RandR gamma ramp support seems broken"); _glfw.x11.randr.gammaBroken = GLFW_TRUE; } XRRFreeScreenResources(sr); XRRSelectInput(_glfw.x11.display, _glfw.x11.root, RROutputChangeNotifyMask); } if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, &_glfw.x11.xinerama.minor)) { if (XineramaIsActive(_glfw.x11.display)) _glfw.x11.xinerama.available = GLFW_TRUE; } // Check if Xkb is supported on this display _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.major, &_glfw.x11.xkb.minor); if (_glfw.x11.xkb.available) { Bool supported; if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { if (supported) _glfw.x11.xkb.detectable = GLFW_TRUE; } } _glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.x11xcb.handle) { _glfw.x11.x11xcb.XGetXCBConnection = (XGETXCBCONNECTION_T) dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // String format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False); _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.COMPOUND_STRING = XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Custom selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // ICCCM standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Xdnd (drag and drop) atoms _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); // ICCCM, EWMH and Motif window property atoms // These can be set safely even without WM support // The EWMH atoms that require WM support are handled in detectEWMH _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False); _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.NET_WM_ICON = XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False); _glfw.x11.NET_WM_PING = XInternAtom(_glfw.x11.display, "_NET_WM_PING", False); _glfw.x11.NET_WM_PID = XInternAtom(_glfw.x11.display, "_NET_WM_PID", False); _glfw.x11.NET_WM_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False); _glfw.x11.NET_WM_ICON_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False); _glfw.x11.NET_WM_BYPASS_COMPOSITOR = XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); return GLFW_TRUE; }
static GLboolean initDisplay(void) { _glfwLibrary.X11.display = XOpenDisplay(NULL); if (!_glfwLibrary.X11.display) { _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: Failed to open X display"); return GL_FALSE; } // As the API currently doesn't understand multiple display devices, we hard-code // this choice and hope for the best _glfwLibrary.X11.screen = DefaultScreen(_glfwLibrary.X11.display); _glfwLibrary.X11.root = RootWindow(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); // Check for XF86VidMode extension #ifdef _GLFW_HAS_XF86VIDMODE _glfwLibrary.X11.VidMode.available = XF86VidModeQueryExtension(_glfwLibrary.X11.display, &_glfwLibrary.X11.VidMode.eventBase, &_glfwLibrary.X11.VidMode.errorBase); #else _glfwLibrary.X11.VidMode.available = GL_FALSE; #endif /*_GLFW_HAS_XF86VIDMODE*/ // Check for XRandR extension #ifdef _GLFW_HAS_XRANDR _glfwLibrary.X11.RandR.available = XRRQueryExtension(_glfwLibrary.X11.display, &_glfwLibrary.X11.RandR.eventBase, &_glfwLibrary.X11.RandR.errorBase); if (_glfwLibrary.X11.RandR.available) { if (!XRRQueryVersion(_glfwLibrary.X11.display, &_glfwLibrary.X11.RandR.majorVersion, &_glfwLibrary.X11.RandR.minorVersion)) { _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to query RandR version"); return GL_FALSE; } } #else _glfwLibrary.X11.RandR.available = GL_FALSE; #endif /*_GLFW_HAS_XRANDR*/ // Check if GLX is supported on this display if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL)) { _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX supported not found"); return GL_FALSE; } if (!glXQueryVersion(_glfwLibrary.X11.display, &_glfwLibrary.GLX.majorVersion, &_glfwLibrary.GLX.minorVersion)) { _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: Failed to query GLX version"); return GL_FALSE; } // Check if Xkb is supported on this display #if defined(_GLFW_HAS_XKB) _glfwLibrary.X11.Xkb.majorVersion = 1; _glfwLibrary.X11.Xkb.minorVersion = 0; _glfwLibrary.X11.Xkb.available = XkbQueryExtension(_glfwLibrary.X11.display, &_glfwLibrary.X11.Xkb.majorOpcode, &_glfwLibrary.X11.Xkb.eventBase, &_glfwLibrary.X11.Xkb.errorBase, &_glfwLibrary.X11.Xkb.majorVersion, &_glfwLibrary.X11.Xkb.minorVersion); #else _glfwLibrary.X11.Xkb.available = GL_FALSE; #endif /* _GLFW_HAS_XKB */ // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. updateKeyCodeLUT(); // Find or create selection property atom _glfwLibrary.X11.selection.property = XInternAtom(_glfwLibrary.X11.display, "GLFW_SELECTION", False); // Find or create clipboard atom _glfwLibrary.X11.selection.atom = XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False); // Find or create selection target atoms _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] = XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False); _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] = XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False); _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] = XA_STRING; _glfwLibrary.X11.selection.targets = XInternAtom(_glfwLibrary.X11.display, "TARGETS", False); return GL_TRUE; }
MInputContext::MInputContext(QObject *parent) : QInputContext(parent), active(false), inputPanelState(InputPanelHidden), imServer(0), correctionEnabled(false), styleContainer(0), #ifdef HAVE_MEEGOTOUCH currOrientation(M::Angle0), #endif connectedObject(0), pasteAvailable(false), copyAvailable(false), copyAllowed(true), redirectKeys(false), objectPath(QString("%1%2").arg(DBusCallbackPath).arg(++connectionCount)), currentKeyEventTime(0) { int opcode = -1; int xkbEventBase = -1; int xkbErrorBase = -1; int xkblibMajor = XkbMajorVersion; int xkblibMinor = XkbMinorVersion; if (!XkbLibraryVersion(&xkblibMajor, &xkblibMinor)) { qCritical("%s xkb query version error!", __PRETTY_FUNCTION__); return; } Display* display = QX11Info::display(); if (!XkbQueryExtension(display, &opcode, &xkbEventBase, &xkbErrorBase, &xkblibMajor, &xkblibMinor)) { qCritical("%s xkb query extension error!", __PRETTY_FUNCTION__); return; } sipHideTimer.setSingleShot(true); sipHideTimer.setInterval(SoftwareInputPanelHideTimer); // TODO: sipHideTimer is used not only when focus is lost but also with // CloseSoftwareInputPanel event, so hideOnFocusOut is misleading. connect(&sipHideTimer, SIGNAL(timeout()), SLOT(hideOnFocusOut())); #ifdef HAVE_MEEGOTOUCH // using theming only when there is MComponentData instance, should be // there for meegotouch apps (naturally) and for plain qt with meego style plugin if (MComponentData::instance() != 0) { styleContainer = new MPreeditStyleContainer; styleContainer->initialize("DefaultStyle", "MPreeditStyle", 0); } #endif connectToDBus(); #ifdef HAVE_MEEGOTOUCH connect(MInputMethodState::instance(), SIGNAL(activeWindowOrientationAngleAboutToChange(M::OrientationAngle)), this, SLOT(notifyOrientationAboutToChange(M::OrientationAngle))); connect(MInputMethodState::instance(), SIGNAL(activeWindowOrientationAngleAboutToChange(M::OrientationAngle)), this, SLOT(notifyOrientationAboutToChange(M::OrientationAngle))); connect(MInputMethodState::instance(), SIGNAL(activeWindowOrientationAngleChanged(M::OrientationAngle)), this, SLOT(notifyOrientationChanged(M::OrientationAngle))); connect(MInputMethodState::instance(), SIGNAL(attributeExtensionRegistered(int, QString)), this, SLOT(notifyAttributeExtensionRegistered(int, QString))); connect(MInputMethodState::instance(), SIGNAL(attributeExtensionUnregistered(int)), this, SLOT(notifyAttributeExtensionUnregistered(int))); connect(MInputMethodState::instance(), SIGNAL(toolbarItemAttributeChanged(int, QString, QString, QVariant)), this, SLOT(notifyToolbarItemAttributeChanged(int, QString, QString, QVariant))); connect(MInputMethodState::instance(), SIGNAL(extendedAttributeChanged(int, QString, QString, QString, QVariant)), this, SLOT(notifyExtendedAttributeChanged(int, QString, QString, QString, QVariant))); #endif }
bool numlock_xkb_init(Display* dpy) { int opcode, event, error; int maj, min; return XkbLibraryVersion(&maj, &min) && XkbQueryExtension(dpy, &opcode, &event, &error, &maj, &min); }
NestedClientPrivatePtr NestedClientCreateScreen(int scrnIndex, Bool wantFullscreenHint, unsigned int width, unsigned int height, int originX, int originY, unsigned int depth, unsigned int bitsPerPixel, Pixel *retRedMask, Pixel *retGreenMask, Pixel *retBlueMask) { NestedClientPrivatePtr pPriv; XSizeHints sizeHints; Bool supported; char windowTitle[32]; pPriv = malloc(sizeof(struct NestedClientPrivate)); pPriv->scrnIndex = scrnIndex; /* Needed until we can pass authorization file * directly to XOpenDisplay() */ if (xauthFile != NULL) setenv("XAUTHORITY", xauthFile, 1); pPriv->display = XOpenDisplay(NULL); if (!pPriv->display) return NULL; #ifdef NESTED_INPUT supported = XkbQueryExtension(pPriv->display, &pPriv->xkb.op, &pPriv->xkb.event, &pPriv->xkb.error, &pPriv->xkb.major, &pPriv->xkb.minor); if (!supported) { xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "The remote server does not support the XKEYBOARD extension.\n"); XCloseDisplay(pPriv->display); return NULL; } #endif pPriv->screenNumber = DefaultScreen(pPriv->display); pPriv->screen = ScreenOfDisplay(pPriv->display, pPriv->screenNumber); pPriv->rootWindow = RootWindow(pPriv->display, pPriv->screenNumber); pPriv->gc = DefaultGC(pPriv->display, pPriv->screenNumber); pPriv->window = XCreateSimpleWindow(pPriv->display, pPriv->rootWindow, originX, originY, width, height, 0, 0, 0); sizeHints.flags = PPosition | PSize | PMinSize | PMaxSize; sizeHints.min_width = width; sizeHints.max_width = width; sizeHints.min_height = height; sizeHints.max_height = height; XSetWMNormalHints(pPriv->display, pPriv->window, &sizeHints); snprintf(windowTitle, sizeof(windowTitle), "Screen %d", scrnIndex); XStoreName(pPriv->display, pPriv->window, windowTitle); XMapWindow(pPriv->display, pPriv->window); XSelectInput(pPriv->display, pPriv->window, #ifdef NESTED_INPUT PointerMotionMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | #endif ExposureMask); if (!NestedClientTryXShm(pPriv, scrnIndex, width, height, depth)) { pPriv->img = XCreateImage(pPriv->display, DefaultVisualOfScreen(pPriv->screen), depth, ZPixmap, 0, /* offset */ NULL, /* data */ width, height, 32, /* XXX: bitmap_pad */ 0 /* XXX: bytes_per_line */); if (!pPriv->img) return NULL; pPriv->img->data = malloc(pPriv->img->bytes_per_line * pPriv->img->height); pPriv->usingShm = FALSE; } if (!pPriv->img->data) return NULL; NestedClientHideCursor(pPriv); /* Hide cursor */ #if 0 xf86DrvMsg(scrnIndex, X_INFO, "width: %d\n", pPriv->img->width); xf86DrvMsg(scrnIndex, X_INFO, "height: %d\n", pPriv->img->height); xf86DrvMsg(scrnIndex, X_INFO, "xoffset: %d\n", pPriv->img->xoffset); xf86DrvMsg(scrnIndex, X_INFO, "depth: %d\n", pPriv->img->depth); xf86DrvMsg(scrnIndex, X_INFO, "bpp: %d\n", pPriv->img->bits_per_pixel); xf86DrvMsg(scrnIndex, X_INFO, "red_mask: 0x%lx\n", pPriv->img->red_mask); xf86DrvMsg(scrnIndex, X_INFO, "gre_mask: 0x%lx\n", pPriv->img->green_mask); xf86DrvMsg(scrnIndex, X_INFO, "blu_mask: 0x%lx\n", pPriv->img->blue_mask); #endif *retRedMask = pPriv->img->red_mask; *retGreenMask = pPriv->img->green_mask; *retBlueMask = pPriv->img->blue_mask; XEvent ev; while (1) { XNextEvent(pPriv->display, &ev); if (ev.type == Expose) { break; } } pPriv->dev = (DeviceIntPtr)NULL; return pPriv; }
int xnestKeyboardProc(DeviceIntPtr pDev, int onoff) { XModifierKeymap *modifier_keymap; KeySym *keymap; int mapWidth; int min_keycode, max_keycode; KeySymsRec keySyms; CARD8 modmap[MAP_LENGTH]; int i, j; XKeyboardState values; switch (onoff) { case DEVICE_INIT: modifier_keymap = XGetModifierMapping(xnestDisplay); XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); #ifdef _XSERVER64 { KeySym64 *keymap64; int i, len; keymap64 = XGetKeyboardMapping(xnestDisplay, min_keycode, max_keycode - min_keycode + 1, &mapWidth); len = (max_keycode - min_keycode + 1) * mapWidth; keymap = (KeySym *)xalloc(len * sizeof(KeySym)); for(i = 0; i < len; ++i) keymap[i] = keymap64[i]; XFree(keymap64); } #else keymap = XGetKeyboardMapping(xnestDisplay, min_keycode, max_keycode - min_keycode + 1, &mapWidth); #endif for (i = 0; i < MAP_LENGTH; i++) modmap[i] = 0; for (j = 0; j < 8; j++) for(i = 0; i < modifier_keymap->max_keypermod; i++) { CARD8 keycode; if ((keycode = modifier_keymap-> modifiermap[j * modifier_keymap->max_keypermod + i])) modmap[keycode] |= 1<<j; } XFreeModifiermap(modifier_keymap); keySyms.minKeyCode = min_keycode; keySyms.maxKeyCode = max_keycode; keySyms.mapWidth = mapWidth; keySyms.map = keymap; #ifdef XKB if (noXkbExtension) { XkbError: #endif XGetKeyboardControl(xnestDisplay, &values); memmove((char *) defaultKeyboardControl.autoRepeats, (char *) values.auto_repeats, sizeof(values.auto_repeats)); InitKeyboardDeviceStruct(&pDev->public, &keySyms, modmap, xnestBell, xnestChangeKeyboardControl); #ifdef XKB } else { FILE *file; XkbConfigRtrnRec config; XkbComponentNamesRec names; char *rules, *model, *layout, *variants, *options; XkbDescPtr xkb; int op, event, error, major, minor; if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { ErrorF("Unable to initialize XKEYBOARD extension.\n"); goto XkbError; } xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); if (xkb == NULL || xkb->geom == NULL) { ErrorF("Couldn't get keyboard.\n"); goto XkbError; } XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); memset(&names, 0, sizeof(XkbComponentNamesRec)); rules = XKB_DFLT_RULES_FILE; model = XKB_DFLT_KB_MODEL; layout = XKB_DFLT_KB_LAYOUT; variants = XKB_DFLT_KB_VARIANT; options = XKB_DFLT_KB_OPTIONS; if (XkbInitialMap) { if ((names.keymap = strchr(XkbInitialMap, '/')) != NULL) ++names.keymap; else names.keymap = XkbInitialMap; } XkbSetRulesDflts(rules, model, layout, variants, options); XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modmap, xnestBell, xnestChangeKeyboardControl); XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); XkbFreeKeyboard(xkb, 0, False); } #endif #ifdef _XSERVER64 xfree(keymap); #else XFree(keymap); #endif break; case DEVICE_ON: xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; for (i = 0; i < xnestNumScreens; i++) XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); break; case DEVICE_OFF: xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; for (i = 0; i < xnestNumScreens; i++) XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); break; case DEVICE_CLOSE: break; }
// Look for and initialize supported X11 extensions // static GLFWbool initExtensions(void) { _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1"); if (_glfw.x11.vidmode.handle) { _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension"); _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp"); _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp"); _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize"); _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); } #if defined(__CYGWIN__) _glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so"); #else _glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6"); #endif if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) _glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion"); _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents) _glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents"); if (XQueryExtension(_glfw.x11.display, "XInputExtension", &_glfw.x11.xi.majorOpcode, &_glfw.x11.xi.eventBase, &_glfw.x11.xi.errorBase)) { _glfw.x11.xi.major = 2; _glfw.x11.xi.minor = 0; if (XIQueryVersion(_glfw.x11.display, &_glfw.x11.xi.major, &_glfw.x11.xi.minor) == Success) { _glfw.x11.xi.available = GLFW_TRUE; } } } #if defined(__CYGWIN__) _glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so"); #else _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2"); #endif if (_glfw.x11.randr.handle) { _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma"); _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo"); _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo"); _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources"); _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma"); _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize"); _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo"); _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo"); _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary"); _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent"); _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension) _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension"); _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion) _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion"); _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput) _glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput"); _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig) _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig"); _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma"); _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration) _glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration"); if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase)) { if (XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.major, &_glfw.x11.randr.minor)) { // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) _glfw.x11.randr.available = GLFW_TRUE; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); } } } if (_glfw.x11.randr.available) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { // This is likely an older Nvidia driver with broken gamma support // Flag it as useless and fall back to xf86vm gamma, if available _glfw.x11.randr.gammaBroken = GLFW_TRUE; } if (!sr->ncrtc) { // A system without CRTCs is likely a system with broken RandR // Disable the RandR monitor path and fall back to core functions _glfw.x11.randr.monitorBroken = GLFW_TRUE; } XRRFreeScreenResources(sr); } if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRSelectInput(_glfw.x11.display, _glfw.x11.root, RROutputChangeNotifyMask); } #if defined(__CYGWIN__) _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so"); #else _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1"); #endif if (_glfw.x11.xcursor.handle) { _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate"); _glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy"); _glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor"); } #if defined(__CYGWIN__) _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so"); #else _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1"); #endif if (_glfw.x11.xinerama.handle) { _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive) _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive"); _glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension) _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension"); _glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens) _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens"); if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, &_glfw.x11.xinerama.minor)) { if (XineramaIsActive(_glfw.x11.display)) _glfw.x11.xinerama.available = GLFW_TRUE; } } _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.major, &_glfw.x11.xkb.minor); if (_glfw.x11.xkb.available) { Bool supported; if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { if (supported) _glfw.x11.xkb.detectable = GLFW_TRUE; } } #if defined(__CYGWIN__) _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so"); #else _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1"); #endif if (_glfw.x11.x11xcb.handle) { _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection) _glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); } #if defined(__CYGWIN__) _glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so"); #else _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1"); #endif if (_glfw.x11.xrender.handle) { _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension) _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension"); _glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion) _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion"); _glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat) _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat"); if (XRenderQueryExtension(_glfw.x11.display, &_glfw.x11.xrender.errorBase, &_glfw.x11.xrender.eventBase)) { if (XRenderQueryVersion(_glfw.x11.display, &_glfw.x11.xrender.major, &_glfw.x11.xrender.minor)) { _glfw.x11.xrender.available = GLFW_TRUE; } } } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // String format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False); _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Custom selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // ICCCM standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False); _glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Xdnd (drag and drop) atoms _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False); _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False); // ICCCM, EWMH and Motif window property atoms // These can be set safely even without WM support // The EWMH atoms that require WM support are handled in detectEWMH _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False); _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.NET_WM_ICON = XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False); _glfw.x11.NET_WM_PING = XInternAtom(_glfw.x11.display, "_NET_WM_PING", False); _glfw.x11.NET_WM_PID = XInternAtom(_glfw.x11.display, "_NET_WM_PID", False); _glfw.x11.NET_WM_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False); _glfw.x11.NET_WM_ICON_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False); _glfw.x11.NET_WM_BYPASS_COMPOSITOR = XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False); _glfw.x11.NET_WM_WINDOW_OPACITY = XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); // The compositing manager selection name contains the screen number { char name[32]; snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen); _glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False); } return GLFW_TRUE; }
int main(int argc, char *argv[]) { Widget toplevel; XtAppContext app_con; Widget panel; Widget leds[XkbNumIndicators]; register int i; unsigned bit; unsigned n; XkbDescPtr xkb; XkbEvent ev; static Arg boxArgs[]= {{ XtNorientation, (XtArgVal)XtorientHorizontal }}; static Arg onArgs[]= {{ XtNon, (XtArgVal)True }}; static Arg offArgs[]= {{ XtNon, (XtArgVal)False }}; static char * fallback_resources[] = { "*Box*background: grey40", NULL }; uSetEntryFile(NullString); uSetDebugFile(NullString); uSetErrorFile(NullString); bzero(leds,XkbNumIndicators*sizeof(Widget)); toplevel = XtOpenApplication(&app_con, "XkbLEDPanel", NULL, 0, &argc, argv, fallback_resources, sessionShellWidgetClass, NULL, ZERO); if (toplevel==NULL) { uFatalError("Couldn't create application top level\n"); return 1; } if ((argc>1)&&(!parseArgs(argc,argv))) { usage(argv[0]); return 1; } if ((wanted==0)&&(wantNamed==DONT_CARE)&&(wantExplicit==DONT_CARE)&& (wantAutomatic==DONT_CARE)&&(wantReal==DONT_CARE)) { wantNamed= YES; wantReal= YES; wantAutomatic= YES; } outDpy= XtDisplay(toplevel); if (inDpyName!=NULL) { inDpy= GetDisplay(argv[0],inDpyName); if (!inDpy) return 1; } else { inDpy= outDpy; } if (inDpy) { int i1,mn,mj; mj= XkbMajorVersion; mn= XkbMinorVersion; if (!XkbLibraryVersion(&mj,&mn)) { uInformation("%s was compiled with XKB version %d.%02d\n", argv[0],XkbMajorVersion,XkbMinorVersion); uError("X library supports incompatible version %d.%02d\n", mj,mn); } if (!XkbQueryExtension(inDpy,&i1,&evBase,&errBase,&mj,&mn)) { uFatalError("Server doesn't support a compatible XKB\n"); return 1; } } else { uFatalError("No input display\n"); return 1; } panel= XtCreateManagedWidget("xkbleds",boxWidgetClass,toplevel,boxArgs,1); if (panel==NULL) { uFatalError("Couldn't create list of leds\n"); return 1; } real= virtual= named= explicit= automatic= 0; if (wantReal || wantNamed || wantAutomatic || wantExplicit || wantVirtual) { register int i,bit; xkb= XkbGetMap(inDpy,0,XkbUseCoreKbd); if (!xkb) { uFatalError("Couldn't read keymap\n"); return 1; } if (XkbGetIndicatorMap(inDpy,XkbAllIndicatorsMask,xkb)!=Success) { uFatalError("Couldn't read indicator map\n"); return 1; } if (XkbGetNames(inDpy,XkbAllNamesMask,xkb)!=Success) { uFatalError("Couldn't read indicator names\n"); return 1; } for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; if (xkb->names->indicators[i]!=None) named|= bit; if (xkb->indicators->phys_indicators&bit) real|= bit; if ((((map->which_groups!=0)&&(map->groups!=0))|| ((map->which_mods!=0)&& ((map->mods.real_mods!=0)||(map->mods.vmods!=0)))|| (map->ctrls!=0))&& ((map->flags&XkbIM_NoAutomatic)==0)) { automatic|= bit; } else explicit|= bit; } virtual= ~real; if (wantReal==NO) real= ~real; else if (wantReal==DONT_CARE) real= (useUnion?0:~0); if (wantVirtual==NO) virtual= ~virtual; else if (wantVirtual==DONT_CARE) virtual= (useUnion?0:~0); if (wantNamed==NO) named= ~named; else if (wantNamed==DONT_CARE) named= (useUnion?0:~0); if (wantAutomatic==NO) automatic= ~automatic; else if (wantAutomatic==DONT_CARE) automatic= (useUnion?0:~0); if (wantExplicit==NO) explicit= ~explicit; else if (wantExplicit==DONT_CARE) explicit= (useUnion?0:~0);
/* *---------------------------------------------------------- * StartUp-- * starts the window manager and setup global data. * Called from main() at startup. * * Side effects: * global data declared in main.c is initialized *---------------------------------------------------------- */ void StartUp(Bool defaultScreenOnly) { struct sigaction sig_action; int i, j, max; char **formats; Atom atom[wlengthof(atomNames)]; /* * Ignore CapsLock in modifiers */ w_global.shortcut.modifiers_mask = 0xff & ~LockMask; getOffendingModifiers(); /* * Ignore NumLock and ScrollLock too */ w_global.shortcut.modifiers_mask &= ~(_NumLockMask | _ScrollLockMask); memset(&wKeyBindings, 0, sizeof(wKeyBindings)); w_global.context.client_win = XUniqueContext(); w_global.context.app_win = XUniqueContext(); w_global.context.stack = XUniqueContext(); /* _XA_VERSION = XInternAtom(dpy, "VERSION", False); */ #ifdef HAVE_XINTERNATOMS XInternAtoms(dpy, atomNames, wlengthof(atomNames), False, atom); #else { int i; for (i = 0; i < wlengthof(atomNames); i++) atom[i] = XInternAtom(dpy, atomNames[i], False); } #endif w_global.atom.wm.state = atom[0]; w_global.atom.wm.change_state = atom[1]; w_global.atom.wm.protocols = atom[2]; w_global.atom.wm.take_focus = atom[3]; w_global.atom.wm.delete_window = atom[4]; w_global.atom.wm.save_yourself = atom[5]; w_global.atom.wm.client_leader = atom[6]; w_global.atom.wm.colormap_windows = atom[7]; w_global.atom.wm.colormap_notify = atom[8]; w_global.atom.wmaker.menu = atom[9]; w_global.atom.wmaker.state = atom[10]; w_global.atom.wmaker.wm_protocols = atom[11]; w_global.atom.wmaker.wm_function = atom[12]; w_global.atom.wmaker.noticeboard = atom[13]; w_global.atom.wmaker.command = atom[14]; w_global.atom.wmaker.icon_size = atom[15]; w_global.atom.wmaker.icon_tile = atom[16]; w_global.atom.gnustep.wm_attr = atom[17]; w_global.atom.gnustep.wm_miniaturize_window = atom[18]; w_global.atom.gnustep.titlebar_state = atom[19]; w_global.atom.wm.ignore_focus_events = atom[20]; #ifdef XDND wXDNDInitializeAtoms(); #endif /* cursors */ wPreferences.cursor[WCUR_NORMAL] = None; /* inherit from root */ wPreferences.cursor[WCUR_ROOT] = XCreateFontCursor(dpy, XC_left_ptr); wPreferences.cursor[WCUR_ARROW] = XCreateFontCursor(dpy, XC_top_left_arrow); wPreferences.cursor[WCUR_MOVE] = XCreateFontCursor(dpy, XC_fleur); wPreferences.cursor[WCUR_RESIZE] = XCreateFontCursor(dpy, XC_sizing); wPreferences.cursor[WCUR_TOPLEFTRESIZE] = XCreateFontCursor(dpy, XC_top_left_corner); wPreferences.cursor[WCUR_TOPRIGHTRESIZE] = XCreateFontCursor(dpy, XC_top_right_corner); wPreferences.cursor[WCUR_BOTTOMLEFTRESIZE] = XCreateFontCursor(dpy, XC_bottom_left_corner); wPreferences.cursor[WCUR_BOTTOMRIGHTRESIZE] = XCreateFontCursor(dpy, XC_bottom_right_corner); wPreferences.cursor[WCUR_VERTICALRESIZE] = XCreateFontCursor(dpy, XC_sb_v_double_arrow); wPreferences.cursor[WCUR_HORIZONRESIZE] = XCreateFontCursor(dpy, XC_sb_h_double_arrow); wPreferences.cursor[WCUR_WAIT] = XCreateFontCursor(dpy, XC_watch); wPreferences.cursor[WCUR_QUESTION] = XCreateFontCursor(dpy, XC_question_arrow); wPreferences.cursor[WCUR_TEXT] = XCreateFontCursor(dpy, XC_xterm); /* odd name??? */ wPreferences.cursor[WCUR_SELECT] = XCreateFontCursor(dpy, XC_cross); Pixmap cur = XCreatePixmap(dpy, DefaultRootWindow(dpy), 16, 16, 1); GC gc = XCreateGC(dpy, cur, 0, NULL); XColor black; memset(&black, 0, sizeof(XColor)); XSetForeground(dpy, gc, 0); XFillRectangle(dpy, cur, gc, 0, 0, 16, 16); XFreeGC(dpy, gc); wPreferences.cursor[WCUR_EMPTY] = XCreatePixmapCursor(dpy, cur, cur, &black, &black, 0, 0); XFreePixmap(dpy, cur); /* emergency exit... */ sig_action.sa_handler = handleSig; sigemptyset(&sig_action.sa_mask); sig_action.sa_flags = SA_RESTART; sigaction(SIGQUIT, &sig_action, NULL); /* instead of catching these, we let the default handler abort the * program. The new monitor process will take appropriate action * when it detects the crash. sigaction(SIGSEGV, &sig_action, NULL); sigaction(SIGBUS, &sig_action, NULL); sigaction(SIGFPE, &sig_action, NULL); sigaction(SIGABRT, &sig_action, NULL); */ sig_action.sa_handler = handleExitSig; /* Here we set SA_RESTART for safety, because SIGUSR1 may not be handled * immediately. -Dan */ sig_action.sa_flags = SA_RESTART; sigaction(SIGTERM, &sig_action, NULL); sigaction(SIGINT, &sig_action, NULL); sigaction(SIGHUP, &sig_action, NULL); sigaction(SIGUSR1, &sig_action, NULL); sigaction(SIGUSR2, &sig_action, NULL); /* ignore dead pipe */ /* Because POSIX mandates that only signal with handlers are reset * accross an exec*(), we do not want to propagate ignoring SIGPIPEs * to children. Hence the dummy handler. * Philippe Troin <*****@*****.**> */ sig_action.sa_handler = &dummyHandler; sig_action.sa_flags = SA_RESTART; sigaction(SIGPIPE, &sig_action, NULL); /* handle dead children */ sig_action.sa_handler = buryChild; sig_action.sa_flags = SA_NOCLDSTOP | SA_RESTART; sigaction(SIGCHLD, &sig_action, NULL); /* Now we unblock all signals, that may have been blocked by the parent * who exec()-ed us. This can happen for example if Window Maker crashes * and restarts itself or another window manager from the signal handler. * In this case, the new proccess inherits the blocked signal mask and * will no longer react to that signal, until unblocked. * This is because the signal handler of the proccess who crashed (parent) * didn't return, and the signal remained blocked. -Dan */ sigfillset(&sig_action.sa_mask); sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, NULL); /* handle X shutdowns a such */ XSetIOErrorHandler(handleXIO); /* set hook for out event dispatcher in WINGs event dispatcher */ WMHookEventHandler(DispatchEvent); /* initialize defaults stuff */ w_global.domain.wmaker = wDefaultsInitDomain("WindowMaker", True); if (!w_global.domain.wmaker->dictionary) wwarning(_("could not read domain \"%s\" from defaults database"), "WindowMaker"); /* read defaults that don't change until a restart and are * screen independent */ wReadStaticDefaults(w_global.domain.wmaker ? w_global.domain.wmaker->dictionary : NULL); /* check sanity of some values */ if (wPreferences.icon_size < 16) { wwarning(_("icon size is configured to %i, but it's too small. Using 16 instead"), wPreferences.icon_size); wPreferences.icon_size = 16; } /* init other domains */ w_global.domain.root_menu = wDefaultsInitDomain("WMRootMenu", False); if (!w_global.domain.root_menu->dictionary) wwarning(_("could not read domain \"%s\" from defaults database"), "WMRootMenu"); wDefaultsMergeGlobalMenus(w_global.domain.root_menu); w_global.domain.window_attr = wDefaultsInitDomain("WMWindowAttributes", True); if (!w_global.domain.window_attr->dictionary) wwarning(_("could not read domain \"%s\" from defaults database"), "WMWindowAttributes"); XSetErrorHandler((XErrorHandler) catchXError); #ifdef USE_XSHAPE /* ignore j */ w_global.xext.shape.supported = XShapeQueryExtension(dpy, &w_global.xext.shape.event_base, &j); #endif #ifdef USE_XRANDR w_global.xext.randr.supported = XRRQueryExtension(dpy, &w_global.xext.randr.event_base, &j); #endif #ifdef KEEP_XKB_LOCK_STATUS w_global.xext.xkb.supported = XkbQueryExtension(dpy, NULL, &w_global.xext.xkb.event_base, NULL, NULL, NULL); if (wPreferences.modelock && !w_global.xext.xkb.supported) { wwarning(_("XKB is not supported. KbdModeLock is automatically disabled.")); wPreferences.modelock = 0; } #endif if (defaultScreenOnly) max = 1; else max = ScreenCount(dpy); wScreen = wmalloc(sizeof(WScreen *) * max); w_global.screen_count = 0; /* Check if TIFF images are supported */ formats = RSupportedFileFormats(); if (formats) { for (i = 0; formats[i] != NULL; i++) { if (strcmp(formats[i], "TIFF") == 0) { wPreferences.supports_tiff = 1; break; } } } /* manage the screens */ for (j = 0; j < max; j++) { if (defaultScreenOnly || max == 1) { wScreen[w_global.screen_count] = wScreenInit(DefaultScreen(dpy)); if (!wScreen[w_global.screen_count]) { wfatal(_("it seems that there is already a window manager running")); Exit(1); } } else { wScreen[w_global.screen_count] = wScreenInit(j); if (!wScreen[w_global.screen_count]) { wwarning(_("could not manage screen %i"), j); continue; } } w_global.screen_count++; } InitializeSwitchMenu(); /* initialize/restore state for the screens */ for (j = 0; j < w_global.screen_count; j++) { int lastDesktop; lastDesktop = wNETWMGetCurrentDesktopFromHint(wScreen[j]); wScreenRestoreState(wScreen[j]); /* manage all windows that were already here before us */ if (!wPreferences.flags.nodock && wScreen[j]->dock) wScreen[j]->last_dock = wScreen[j]->dock; manageAllWindows(wScreen[j], wPreferences.flags.restarting == 2); /* restore saved menus */ wMenuRestoreState(wScreen[j]); /* If we're not restarting, restore session */ if (wPreferences.flags.restarting == 0 && !wPreferences.flags.norestore) wSessionRestoreState(wScreen[j]); if (!wPreferences.flags.noautolaunch) { /* auto-launch apps */ if (!wPreferences.flags.nodock && wScreen[j]->dock) { wScreen[j]->last_dock = wScreen[j]->dock; wDockDoAutoLaunch(wScreen[j]->dock, 0); } /* auto-launch apps in clip */ if (!wPreferences.flags.noclip) { int i; for (i = 0; i < w_global.workspace.count; i++) { if (w_global.workspace.array[i]->clip) { wScreen[j]->last_dock = w_global.workspace.array[i]->clip; wDockDoAutoLaunch(w_global.workspace.array[i]->clip, i); } } } /* auto-launch apps in drawers */ if (!wPreferences.flags.nodrawer) { WDrawerChain *dc; for (dc = wScreen[j]->drawers; dc; dc = dc->next) { wScreen[j]->last_dock = dc->adrawer; wDockDoAutoLaunch(dc->adrawer, 0); } } } /* go to workspace where we were before restart */ if (lastDesktop >= 0) wWorkspaceForceChange(wScreen[j], lastDesktop); else wSessionRestoreLastWorkspace(wScreen[j]); } if (w_global.screen_count == 0) { wfatal(_("could not manage any screen")); Exit(1); } #ifndef HAVE_INOTIFY /* setup defaults file polling */ if (!wPreferences.flags.nopolling && !wPreferences.flags.noupdates) WMAddTimerHandler(3000, wDefaultsCheckDomains, NULL); #endif }
int main(void) { Display *xdisplay; XkbEvent xevent; int opcode, xkbEventBase, xkbErrorBase, major, minor; int currentLayout = 0; time_t timestamp; char datetime[DATETIME_BUFFER + 1]; int status; snd_mixer_t *amixer; snd_mixer_elem_t *amixer_elem; snd_mixer_selem_id_t *amixer_selem; long int volume, volumeMin, volumeMax, volumePercent; struct udev *udev; struct udev_monitor *udev_monitor; struct udev_device *udev_device; int udev_fd; int ps_current = 0, ps_total = 0; openlog(NULL, LOG_CONS|LOG_PERROR|LOG_PID, LOG_DAEMON); if (!(xdisplay = XOpenDisplay(NULL))) { syslog(LOG_ERR, "Can't open display: %s!\n", strerror(errno)); return EXIT_FAILURE; } if (!XkbQueryExtension(xdisplay, &opcode, &xkbEventBase, &xkbErrorBase, &major, &minor)) { syslog(LOG_ERR, "X doesn't support a compatible Xkb!\n"); return EXIT_FAILURE; } if (!XkbSelectEvents(xdisplay, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask)) { syslog(LOG_ERR, "Could not set Xkb event mask!\n"); return EXIT_FAILURE; } if ((status = snd_mixer_open(&amixer, 0)) < 0 || (status = snd_mixer_selem_register(amixer, NULL, NULL)) < 0 || (status = snd_mixer_attach(amixer, "default")) < 0) { syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status)); return EXIT_FAILURE; } if ((status = snd_mixer_load(amixer)) || (status = snd_mixer_selem_id_malloc(&amixer_selem)) < 0) { syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status)); return EXIT_FAILURE; } snd_mixer_selem_id_set_index(amixer_selem, 0); snd_mixer_selem_id_set_name(amixer_selem, "Master"); amixer_elem = snd_mixer_find_selem(amixer, amixer_selem); snd_mixer_selem_get_playback_volume_range(amixer_elem, &volumeMin, &volumeMax); if (amixer_elem == NULL) { syslog(LOG_ERR, "Mixer simple element handle not found!\n"); return EXIT_FAILURE; } udev = udev_new(); if (udev == NULL) { syslog(LOG_ERR, "Can't create udev object!\n"); return EXIT_FAILURE; } udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (udev_monitor == NULL) { syslog(LOG_ERR, "Can't create udev monitor!\n"); return EXIT_SUCCESS; } if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "power_supply", NULL) < 0) { syslog(LOG_ERR, "Could't watch power_supply events!\n"); return EXIT_FAILURE; } if (udev_monitor_enable_receiving(udev_monitor) < 0) { syslog(LOG_ERR, "Could't bind udev monitor event!\n"); return EXIT_FAILURE; } udev_fd = udev_monitor_get_fd(udev_monitor); while(1) { time(×tamp); strftime(datetime, DATETIME_BUFFER, DATETIME_FORMAT, localtime(×tamp)); while(XPending(xdisplay)) { XNextEvent(xdisplay, &xevent.core); if (xevent.type == xkbEventBase && xevent.any.xkb_type == XkbStateNotify) { currentLayout = xevent.state.group; } } if ((status = snd_mixer_handle_events(amixer)) < 0) { syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status)); return EXIT_FAILURE; } if ((status = snd_mixer_selem_get_playback_volume(amixer_elem, SND_MIXER_SCHN_MONO, &volume)) < 0) { syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status)); return EXIT_FAILURE; } volumePercent = (volume * 100) / volumeMax; fd_set fds; int ret; struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; FD_ZERO(&fds); FD_SET(udev_fd, &fds); ret = select(udev_fd + 1, &fds, NULL, NULL, &tv); if (ret > 0 && FD_ISSET(udev_fd, &fds)) { udev_device = udev_monitor_receive_device(udev_monitor); if (udev_device == NULL) { syslog(LOG_ERR, "Can't get udev device!\n"); return EXIT_SUCCESS; } printf("Name: %s\n", udev_device_get_sysname(udev_device)); printf("Node: %s\n", udev_device_get_devnode(udev_device)); printf("Subsystem: %s\n", udev_device_get_subsystem(udev_device)); printf("Devtype: %s\n", udev_device_get_devtype(udev_device)); printf("Action: %s\n", udev_device_get_action(udev_device)); /*ps_current = atoi(udev_device_get_property_value(udev_device, "POWER_SUPPLY_CHARGE_NOW"));*/ /*ps_total = atoi(udev_device_get_property_value(udev_device, "POWER_SUPPLY_CHARGE_FULL"));*/ printf("%s\n", udev_device_get_sysattr_value(udev_device, "energy_now")); printf("%s\n", udev_device_get_sysattr_value(udev_device, "energy_full")); udev_device_unref(udev_device); } printf("%s %s\t%s %li\t%s %i\t%s %s\n", GLYPH_KEYBOARD, layouts[currentLayout], GLYPH_VOLUME, volumePercent, GLYPH_BATTERY, ps_current, GLYPH_CLOCK, datetime ); usleep(SLEEP_MSECONDS * 1000); } snd_mixer_selem_id_free(amixer_selem); snd_mixer_close(amixer); XCloseDisplay(xdisplay); closelog(); return EXIT_SUCCESS; }
int xnestKeyboardProc(DeviceIntPtr pDev, int onoff) { XModifierKeymap *modifier_keymap; KeySym *keymap; int mapWidth; int min_keycode, max_keycode; KeySymsRec keySyms; CARD8 modmap[MAP_LENGTH]; int i, j; XKeyboardState values; XkbDescPtr xkb; int op, event, error, major, minor; switch (onoff) { case DEVICE_INIT: XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); #ifdef _XSERVER64 { KeySym64 *keymap64; int len; keymap64 = XGetKeyboardMapping(xnestDisplay, min_keycode, max_keycode - min_keycode + 1, &mapWidth); len = (max_keycode - min_keycode + 1) * mapWidth; keymap = xallocarray(len, sizeof(KeySym)); for (i = 0; i < len; ++i) keymap[i] = keymap64[i]; XFree(keymap64); } #else keymap = XGetKeyboardMapping(xnestDisplay, min_keycode, max_keycode - min_keycode + 1, &mapWidth); #endif memset(modmap, 0, sizeof(modmap)); modifier_keymap = XGetModifierMapping(xnestDisplay); for (j = 0; j < 8; j++) for (i = 0; i < modifier_keymap->max_keypermod; i++) { CARD8 keycode; if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap-> max_keypermod + i])) modmap[keycode] |= 1 << j; } XFreeModifiermap(modifier_keymap); keySyms.minKeyCode = min_keycode; keySyms.maxKeyCode = max_keycode; keySyms.mapWidth = mapWidth; keySyms.map = keymap; if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { ErrorF("Unable to initialize XKEYBOARD extension.\n"); goto XkbError; } xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); if (xkb == NULL || xkb->geom == NULL) { ErrorF("Couldn't get keyboard.\n"); goto XkbError; } XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, keySyms.maxKeyCode - keySyms.minKeyCode + 1, modmap, serverClient); XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); XkbFreeKeyboard(xkb, 0, False); free(keymap); break; case DEVICE_ON: xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; for (i = 0; i < xnestNumScreens; i++) XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); break; case DEVICE_OFF: xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; for (i = 0; i < xnestNumScreens; i++) XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); break; case DEVICE_CLOSE: break; } return Success; XkbError: XGetKeyboardControl(xnestDisplay, &values); memmove((char *) defaultKeyboardControl.autoRepeats, (char *) values.auto_repeats, sizeof(values.auto_repeats)); InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); free(keymap); return Success; }
static void spi_controller_register_with_devices (SpiDEController *controller) { DEControllerPrivateData *priv; int event_base, error_base, major_version, minor_version; priv = controller->priv; if (XTestQueryExtension (spi_get_display(), &event_base, &error_base, &major_version, &minor_version)) { XTestGrabControl (spi_get_display (), True); } /* calls to device-specific implementations and routines go here */ /* register with: keyboard hardware code handler */ /* register with: (translated) keystroke handler */ priv->have_xkb = XkbQueryExtension (spi_get_display (), &priv->xkb_major_extension_opcode, &priv->xkb_base_event_code, &priv->xkb_base_error_code, NULL, NULL); if (priv->have_xkb) { gint i; guint64 reserved = 0; priv->xkb_desc = XkbGetMap (spi_get_display (), XkbKeySymsMask, XkbUseCoreKbd); XkbSelectEvents (spi_get_display (), XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); _numlock_physical_mask = XkbKeysymToModifiers (spi_get_display (), XK_Num_Lock); for (i = priv->xkb_desc->max_key_code; i >= priv->xkb_desc->min_key_code; --i) { if (priv->xkb_desc->map->key_sym_map[i].kt_index[0] == XkbOneLevelIndex) { if (XkbKeycodeToKeysym (spi_get_display (), i, 0, 0) != 0) { /* don't use this one if there's a grab client! */ /* Runtime errors are generated from these functions, * that are then quashed. Equivalent to: * try * {Blah} * except * {;} */ spi_x_error_trap (); XGrabKey (spi_get_display (), i, 0, spi_get_root_window (), TRUE, GrabModeSync, GrabModeSync); XSync (spi_get_display (), TRUE); XUngrabKey (spi_get_display (), i, 0, spi_get_root_window ()); if (!spi_x_error_release ()) { reserved = i; break; } } } } if (reserved) { priv->reserved_keycode = reserved; priv->reserved_keysym = XkbKeycodeToKeysym (spi_get_display (), reserved, 0, 0); } else { priv->reserved_keycode = XKeysymToKeycode (spi_get_display (), XK_numbersign); priv->reserved_keysym = XK_numbersign; } #ifdef SPI_RESERVED_DEBUG unsigned sym = 0; sym = XKeycodeToKeysym (spi_get_display (), reserved, 0); fprintf (stderr, "%x\n", sym); fprintf (stderr, "setting the reserved keycode to %d (%s)\n", reserved, XKeysymToString (XKeycodeToKeysym (spi_get_display (), reserved, 0))); #endif } spi_set_filter (global_filter_fn, controller); spi_set_events (KeyPressMask | KeyReleaseMask); x_default_error_handler = XSetErrorHandler (_spi_controller_device_error_handler); }
static int setup_display() { int major = 1; int minor = 0; int majorOpcode = 0; int eventBase = 0; int errorBase = 0; int depth, i, formatCount, convDepth = -1; XPixmapFormatValues* formats; if (s_setup_done) { return 1; } s_display = XOpenDisplay(0); if (!s_display) { printf("Unable to open X11 display\n"); return 0; } s_context = XUniqueContext(); s_screen = DefaultScreen(s_display); s_visual = DefaultVisual(s_display, s_screen); formats = XListPixmapFormats(s_display, &formatCount); depth = DefaultDepth(s_display, s_screen); for (i = 0; i < formatCount; ++i) { if (depth == formats[i].depth) { convDepth = formats[i].bits_per_pixel; break; } } XFree(formats); // We only support 32-bit right now if (convDepth != 32) { printf("Unable to find 32-bit format for X11 display\n"); XCloseDisplay(s_display); return 0; } s_depth = depth; s_gc = DefaultGC(s_display, s_screen); s_screen_width = DisplayWidth(s_display, s_screen); s_screen_height = DisplayHeight(s_display, s_screen); const char* wmDeleteWindowName = "WM_DELETE_WINDOW"; XInternAtoms(s_display, (char**)&wmDeleteWindowName, 1, False, &s_wm_delete_window); s_setup_done = 1; init_cursors(); s_keyb_ext = XkbQueryExtension(s_display, &majorOpcode, &eventBase, &errorBase, &major, &minor); return 1; }
Boolean InitXkb(Display *theDisplay) { int i,opcode,errorBase,major,minor; XkbDescPtr xkb; unsigned int bit; unsigned int real,virtual,named,explicit,automatic; char *name; if (!XkbQueryExtension(theDisplay, &opcode, &xkbEventBase, &errorBase, &major, &minor)) return False; if (!XkbUseExtension(theDisplay,&major,&minor)) return False; XkbSelectEvents(theDisplay, XkbUseCoreKbd, XkbIndicatorStateNotifyMask|XkbIndicatorMapNotifyMask, XkbIndicatorStateNotifyMask|XkbIndicatorMapNotifyMask); XtSetEventDispatcher(theDisplay, xkbEventBase+XkbEventCode, XkbEventHandler); xkb=XkbGetMap(theDisplay,0,XkbUseCoreKbd); real=virtual=named=explicit=automatic=0; if (!xkb) { fprintf(stderr,"Couldn't get keymap\n"); return False; } if (XkbGetIndicatorMap(theDisplay,XkbAllIndicatorsMask,xkb)!=Success) { fprintf(stderr,"Couldn't read indicator map\n"); XkbFreeKeyboard(xkb,XkbAllComponentsMask,True); return False; } real=virtual=named=explicit=automatic=0; if (XkbGetNames(theDisplay,XkbIndicatorNamesMask,xkb)!=Success) { fprintf(stderr,"Couldn't read indicator names\n"); XkbFreeKeyboard(xkb,XkbAllComponentsMask,True); return False; } real=virtual=named=explicit=automatic=0; for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; name = NULL; if (xkb->names->indicators[i]!=None) { named|= bit; name = XGetAtomName(theDisplay,xkb->names->indicators[i]); } if (name != NULL) { ledAtoms[i] = xkb->names->indicators[i]; ledNames[i] = XmStringCreate(name,XmSTRING_DEFAULT_CHARSET); } else { char temp[12]; sprintf(temp,"led%d\0",i+1); ledAtoms[i] = None; ledNames[i] = XmStringCreate(temp,XmSTRING_DEFAULT_CHARSET); } if (xkb->indicators->phys_indicators&bit) real|= bit; if ((((map->which_groups!=0)&&(map->groups!=0))|| ((map->which_mods!=0)&& ((map->mods.real_mods!=0)||(map->mods.vmods!=0)))|| (map->ctrls!=0))&& ((map->flags&XkbIM_NoAutomatic)==0)) { automatic|= bit; } else explicit|= bit; } virtual = ~real; if (options.useUnion) { if ((options.wantReal==NO) || (options.wantReal==DONT_CARE)) real = 0; if ((options.wantVirtual==NO) || (options.wantVirtual==DONT_CARE)) virtual = 0; if ((options.wantNamed==NO) || (options.wantNamed==DONT_CARE)) named = 0; if ((options.wantAutomatic==NO) || (options.wantAutomatic==DONT_CARE)) automatic = 0; if ((options.wantExplicit==NO) || (options.wantExplicit==DONT_CARE)) explicit = 0; options.wanted |= real|virtual|named|automatic|explicit; } else { if (options.wanted == DONT_CARE)
static GLboolean initDisplay(void) { Bool supported; _glfw.x11.display = XOpenDisplay(NULL); if (!_glfw.x11.display) { _glfwInputError(GLFW_API_UNAVAILABLE, "X11: Failed to open X display"); return GL_FALSE; } // As the API currently doesn't understand multiple display devices, we hard-code // this choice and hope for the best _glfw.x11.screen = DefaultScreen(_glfw.x11.display); _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen); // Find or create window manager atoms _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); // Check for XF86VidMode extension _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); // Check for RandR extension _glfw.x11.randr.available = XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase); if (_glfw.x11.randr.available) { if (!XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.versionMajor, &_glfw.x11.randr.versionMinor)) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); return GL_FALSE; } // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.versionMajor == 1 && _glfw.x11.randr.versionMinor < 3) { _glfw.x11.randr.available = GL_FALSE; } } // Check if Xkb is supported on this display _glfw.x11.xkb.versionMajor = 1; _glfw.x11.xkb.versionMinor = 0; if (!XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.versionMajor, &_glfw.x11.xkb.versionMinor)) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: The keyboard extension is not available"); return GL_FALSE; } XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported); if (!supported) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Detectable key repeat is not available"); return GL_FALSE; } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. updateKeyCodeLUT(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // Find or create string format atoms _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.COMPOUND_STRING = XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); // Find or create selection property atom _glfw.x11.selection.property = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // Find or create standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Find or create selection target atoms _glfw.x11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] = _glfw.x11.UTF8_STRING; _glfw.x11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] = _glfw.x11.COMPOUND_STRING; _glfw.x11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] = XA_STRING; return GL_TRUE; }
void xrecord_thread (gpointer data) { int dummy; self_xcape = calloc (sizeof (XCape_t), 1); if ( !self_xcape ) { g_debug ("Got XCape memory failed!\n"); /*return FALSE;*/ g_thread_exit (NULL); } self_xcape->data_conn = XOpenDisplay (NULL); self_xcape->ctrl_conn = XOpenDisplay (NULL); if ( !self_xcape->data_conn || !self_xcape->ctrl_conn ) { g_debug ("Unable to connect to X11 display!\n"); /*return FALSE;*/ g_thread_exit (NULL); } if ( !XQueryExtension (self_xcape->ctrl_conn, "XTEST", &dummy, &dummy, &dummy) ) { g_debug ("Xtst extension missing!\n"); /*return FALSE;*/ g_thread_exit (NULL); } if ( !XRecordQueryVersion (self_xcape->ctrl_conn, &dummy, &dummy) ) { g_debug ("Failed to obtain xrecord version!\n"); /*return FALSE;*/ g_thread_exit (NULL); } if ( !XkbQueryExtension (self_xcape->ctrl_conn, &dummy, &dummy, &dummy, &dummy, &dummy)) { g_debug ("Failed to obtain xkb version!\n"); /*return FALSE;*/ g_thread_exit (NULL); } XRecordRange* rec_range = XRecordAllocRange (); rec_range->device_events.first = KeyPress; rec_range->device_events.last = ButtonRelease; XRecordClientSpec client_spec = XRecordAllClients; self_xcape->record_ctx = XRecordCreateContext (self_xcape->ctrl_conn, 0, &client_spec, 1, &rec_range, 1); if ( self_xcape->record_ctx == 0 ) { g_debug ("Failed to create xrecord context!\n"); /*return FALSE;*/ g_thread_exit (NULL); } /*XSync (self_xcape->ctrl_conn, FALSE);*/ XFlush (self_xcape->ctrl_conn); if ( !XRecordEnableContext (self_xcape->data_conn, self_xcape->record_ctx, intercept, (XPointer)self_xcape) ) { g_debug ("Failed to enable xrecord context!\n"); /*return FALSE;*/ g_thread_exit (NULL); } g_thread_exit (NULL); }
// Initialize X11 display and look for supported X11 extensions // static GLboolean initExtensions(void) { Bool supported; // Find or create window manager atoms _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); // Check for XF86VidMode extension _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); // Check for RandR extension _glfw.x11.randr.available = XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase); if (_glfw.x11.randr.available) { if (!XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.versionMajor, &_glfw.x11.randr.versionMinor)) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); return GL_FALSE; } // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.versionMajor == 1 && _glfw.x11.randr.versionMinor < 3) { _glfw.x11.randr.available = GL_FALSE; } } if (XQueryExtension(_glfw.x11.display, "XInputExtension", &_glfw.x11.xi.majorOpcode, &_glfw.x11.xi.eventBase, &_glfw.x11.xi.errorBase)) { _glfw.x11.xi.versionMajor = 2; _glfw.x11.xi.versionMinor = 0; if (XIQueryVersion(_glfw.x11.display, &_glfw.x11.xi.versionMajor, &_glfw.x11.xi.versionMinor) != BadRequest) { _glfw.x11.xi.available = GL_TRUE; } } // Check if Xkb is supported on this display _glfw.x11.xkb.versionMajor = 1; _glfw.x11.xkb.versionMinor = 0; if (!XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.versionMajor, &_glfw.x11.xkb.versionMinor)) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: The keyboard extension is not available"); return GL_FALSE; } if (!XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to set detectable key repeat"); return GL_FALSE; } if (!supported) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Detectable key repeat is not supported"); return GL_FALSE; } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. updateKeyCodeLUT(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // Find or create string format atoms _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.COMPOUND_STRING = XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Find or create selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // Find or create standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Find or create clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); return GL_TRUE; }
// Initialize X11 display and look for supported X11 extensions // static GLboolean initExtensions(void) { // Find or create window manager atoms _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False); _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); #if defined(_GLFW_HAS_XF86VM) // Check for XF86VidMode extension _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); #endif /*_GLFW_HAS_XF86VM*/ // Check for RandR extension _glfw.x11.randr.available = XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase); if (_glfw.x11.randr.available) { XRRScreenResources* sr; if (!XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.major, &_glfw.x11.randr.minor)) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); return GL_FALSE; } // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.major == 1 && _glfw.x11.randr.minor < 3) _glfw.x11.randr.available = GL_FALSE; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { // This is either a headless system or an older Nvidia binary driver // with broken gamma support // Flag it as useless and fall back to Xf86VidMode gamma, if // available _glfwInputError(GLFW_PLATFORM_ERROR, "X11: RandR gamma ramp support seems broken"); _glfw.x11.randr.gammaBroken = GL_TRUE; } XRRFreeScreenResources(sr); } if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, &_glfw.x11.xinerama.minor)) { if (XineramaIsActive(_glfw.x11.display)) _glfw.x11.xinerama.available = GL_TRUE; } #if defined(_GLFW_HAS_XINPUT) if (XQueryExtension(_glfw.x11.display, "XInputExtension", &_glfw.x11.xi.majorOpcode, &_glfw.x11.xi.eventBase, &_glfw.x11.xi.errorBase)) { _glfw.x11.xi.major = 2; _glfw.x11.xi.minor = 0; if (XIQueryVersion(_glfw.x11.display, &_glfw.x11.xi.major, &_glfw.x11.xi.minor) != BadRequest) { _glfw.x11.xi.available = GL_TRUE; } } #endif /*_GLFW_HAS_XINPUT*/ // Check if Xkb is supported on this display _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.major, &_glfw.x11.xkb.minor); if (_glfw.x11.xkb.available) { Bool supported; if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { if (supported) _glfw.x11.xkb.detectable = GL_TRUE; } } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // Find or create string format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False); _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.COMPOUND_STRING = XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Find or create selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // Find or create standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Find or create clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Find Xdnd (drag and drop) atoms, if available _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True); _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); return GL_TRUE; }
int main(int argc, char *argv[]) { Widget toplevel; XtAppContext app_con; Widget panel; Widget base[XkbNumModifiers]; Widget latched[XkbNumModifiers]; Widget locked[XkbNumModifiers]; Widget effective[XkbNumModifiers]; Widget compat[XkbNumModifiers]; Widget baseBox, latchBox, lockBox, effBox, compatBox; register int i; unsigned bit; XkbEvent ev; XkbStateRec state; static Arg hArgs[] = { {XtNorientation, (XtArgVal) XtorientHorizontal} }; static Arg vArgs[] = { {XtNorientation, (XtArgVal) XtorientVertical} }; static Arg onArgs[] = { {XtNon, (XtArgVal) True} }; static Arg offArgs[] = { {XtNon, (XtArgVal) False} }; static char *fallback_resources[] = { "*Box*background: grey50", "*Box*borderWidth: 0", "*Box*vSpace: 1", NULL }; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-version") == 0) { printf("xkbwatch (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); exit(0); } } uSetErrorFile(NullString); toplevel = XtOpenApplication(&app_con, "XkbWatch", options, XtNumber(options), &argc, argv, fallback_resources, sessionShellWidgetClass, NULL, ZERO); if (toplevel == NULL) { uFatalError("Couldn't create application top level\n"); exit(1); } inDpy = outDpy = XtDisplay(toplevel); if (inDpy) { int i1, mn, mj; mj = XkbMajorVersion; mn = XkbMinorVersion; if (!XkbQueryExtension(inDpy, &i1, &evBase, &errBase, &mj, &mn)) { uFatalError("Server doesn't support a compatible XKB\n"); exit(1); } } panel = XtCreateManagedWidget("xkbwatch", boxWidgetClass, toplevel, vArgs, 1); if (panel == NULL) { uFatalError("Couldn't create top level box\n"); exit(1); } baseBox = XtCreateManagedWidget("base", boxWidgetClass, panel, hArgs, 1); if (baseBox == NULL) uFatalError("Couldn't create base modifiers box\n"); latchBox = XtCreateManagedWidget("latched", boxWidgetClass, panel, hArgs, 1); if (latchBox == NULL) uFatalError("Couldn't create latched modifiers box\n"); lockBox = XtCreateManagedWidget("locked", boxWidgetClass, panel, hArgs, 1); if (lockBox == NULL) uFatalError("Couldn't create locked modifiers box\n"); effBox = XtCreateManagedWidget("effective", boxWidgetClass, panel, hArgs, 1); if (effBox == NULL) uFatalError("Couldn't create effective modifiers box\n"); compatBox = XtCreateManagedWidget("compat", boxWidgetClass, panel, hArgs, 1); if (compatBox == NULL) uFatalError("Couldn't create compatibility state box\n"); XkbSelectEvents(inDpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); XkbGetState(inDpy, XkbUseCoreKbd, &state); for (i = XkbNumModifiers - 1, bit = 0x80; i >= 0; i--, bit >>= 1) { ArgList list; char buf[30]; sprintf(buf, "base%d", i); if (state.base_mods & bit) list = onArgs; else list = offArgs; base[i] = XtCreateManagedWidget(buf, ledWidgetClass, baseBox, list, 1); sprintf(buf, "latched%d", i); if (state.latched_mods & bit) list = onArgs; else list = offArgs; latched[i] = XtCreateManagedWidget(buf, ledWidgetClass, latchBox, list, 1); sprintf(buf, "locked%d", i); if (state.locked_mods & bit) list = onArgs; else list = offArgs; locked[i] = XtCreateManagedWidget(buf, ledWidgetClass, lockBox, list, 1); sprintf(buf, "effective%d", i); if (state.mods & bit) list = onArgs; else list = offArgs; effective[i] = XtCreateManagedWidget(buf, ledWidgetClass, effBox, list, 1); sprintf(buf, "compat%d", i); if (state.compat_state & bit) list = onArgs; else list = offArgs; compat[i] = XtCreateManagedWidget(buf, ledWidgetClass, compatBox, list, 1); } XtRealizeWidget(toplevel); while (1) { XtAppNextEvent(app_con, &ev.core); if (ev.core.type == evBase + XkbEventCode) { if (ev.any.xkb_type == XkbStateNotify) { unsigned changed; if (ev.state.changed & XkbModifierBaseMask) { changed = ev.state.base_mods ^ state.base_mods; state.base_mods = ev.state.base_mods; for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { if (changed & bit) { ArgList list; if (state.base_mods & bit) list = onArgs; else list = offArgs; XtSetValues(base[i], list, 1); } } } if (ev.state.changed & XkbModifierLatchMask) { changed = ev.state.latched_mods ^ state.latched_mods; state.latched_mods = ev.state.latched_mods; for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { if (changed & bit) { ArgList list; if (state.latched_mods & bit) list = onArgs; else list = offArgs; XtSetValues(latched[i], list, 1); } } } if (ev.state.changed & XkbModifierLockMask) { changed = ev.state.locked_mods ^ state.locked_mods; state.locked_mods = ev.state.locked_mods; for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { if (changed & bit) { ArgList list; if (state.locked_mods & bit) list = onArgs; else list = offArgs; XtSetValues(locked[i], list, 1); } } } if (ev.state.changed & XkbModifierStateMask) { changed = ev.state.mods ^ state.mods; state.mods = ev.state.mods; for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { if (changed & bit) { ArgList list; if (state.mods & bit) list = onArgs; else list = offArgs; XtSetValues(effective[i], list, 1); } } } if (ev.state.changed & XkbCompatStateMask) { changed = ev.state.compat_state ^ state.compat_state; state.compat_state = ev.state.compat_state; for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { if (changed & bit) { ArgList list; if (state.compat_state & bit) list = onArgs; else list = offArgs; XtSetValues(compat[i], list, 1); } } } } } else XtDispatchEvent(&ev.core); } /* BAIL: */ if (inDpy) XCloseDisplay(inDpy); if (outDpy != inDpy) XCloseDisplay(outDpy); inDpy = outDpy = NULL; return 0; }
/************************************************************************ * Main function ***********************************************************************/ int main(int argc, char **argv) { XCape_t *self = malloc(sizeof(XCape_t)); int dummy, ch; static char default_mapping[] = "Num_Lock;Caps_Lock"; char *mapping = default_mapping; self->debug = False; while ((ch = getopt(argc, argv, "d")) != -1) { switch (ch) { case 'd': self->debug = True; break; default: fprintf(stdout, "Usage: %s [-d]\n", argv[0]); fprintf(stdout, "Runs as a daemon unless -d flag is set\n"); return EXIT_SUCCESS; } } self->data_conn = XOpenDisplay(NULL); self->ctrl_conn = XOpenDisplay(NULL); if (!self->data_conn || !self->ctrl_conn) { fprintf(stderr, "Unable to connect to X11 display. Is $DISPLAY set?\n"); exit(EXIT_FAILURE); } if (!XQueryExtension(self->ctrl_conn, "XTEST", &dummy, &dummy, &dummy)) { fprintf(stderr, "Xtst extension missing\n"); exit(EXIT_FAILURE); } if (!XRecordQueryVersion(self->ctrl_conn, &dummy, &dummy)) { fprintf(stderr, "Failed to obtain xrecord version\n"); exit(EXIT_FAILURE); } if (!XkbQueryExtension(self->ctrl_conn, &dummy, &dummy, &dummy, &dummy, &dummy)) { fprintf(stderr, "Failed to obtain xkb version\n"); exit(EXIT_FAILURE); } self->map = parse_mapping(self->ctrl_conn, mapping); if (self->map == NULL) exit(EXIT_FAILURE); if (self->debug != True) daemon(0, 0); sigemptyset(&self->sigset); sigaddset(&self->sigset, SIGINT); sigaddset(&self->sigset, SIGTERM); pthread_sigmask(SIG_BLOCK, &self->sigset, NULL); pthread_create(&self->sigwait_thread, NULL, sig_handler, self); XRecordRange *rec_range = XRecordAllocRange(); rec_range->device_events.first = KeyPress; rec_range->device_events.last = ButtonRelease; XRecordClientSpec client_spec = XRecordAllClients; self->record_ctx = XRecordCreateContext(self->ctrl_conn, 0, &client_spec, 1, &rec_range, 1); if (self->record_ctx == 0) { fprintf(stderr, "Failed to create xrecord context\n"); exit(EXIT_FAILURE); } XSync(self->ctrl_conn, False); if (!XRecordEnableContext(self->data_conn, self->record_ctx, intercept, (XPointer) self)) { fprintf(stderr, "Failed to enable xrecord context\n"); exit(EXIT_FAILURE); } if (!XRecordFreeContext(self->ctrl_conn, self->record_ctx)) { fprintf(stderr, "Failed to free xrecord context\n"); } XCloseDisplay(self->ctrl_conn); XCloseDisplay(self->data_conn); if (self->debug) fprintf(stdout, "main exiting\n"); return EXIT_SUCCESS; }