/** * Initialize X connection, establish grab. */ Display* initX(const char* keyName, int keyModifier, int* keyCode) { KeySym sym = XStringToKeysym(keyName); if (sym == NoSymbol) { fprintf(stderr, "ERROR: Unknown key: %s\n", keyName); exit(2); } Display* display = XOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "ERROR: Could not open display.\n"); exit(3); } *keyCode = XKeysymToKeycode(display, sym); Window rootWindow = DefaultRootWindow(display); initMasks(display); Bool detectableAutoRepeatSupported; XkbSetDetectableAutoRepeat(display, True, &detectableAutoRepeatSupported); if (!detectableAutoRepeatSupported) { fprintf(stderr, "ERROR: Detectable auto repeat is not supported.\n"); exit(4); } // Grab grabKey(display, rootWindow, *keyCode, keyModifier); // Enable events XAllowEvents(display, AsyncBoth, CurrentTime); XSelectInput(display, rootWindow, KeyPressMask | KeyReleaseMask); return display; }
static void InitKeyboard(void) { Display *disp = (Display *)gpuDisp; if (disp){ wmprotocols = XInternAtom(disp, "WM_PROTOCOLS", 0); wmdelwindow = XInternAtom(disp, "WM_DELETE_WINDOW", 0); XkbSetDetectableAutoRepeat(disp, 1, NULL); } }
void KeyboardOpen() { //Debug("Pokopom -> Keyboard Open\n"); aProtocols = XInternAtom(hDisplay, "WM_PROTOCOLS", 0); aDeleteWindow = XInternAtom(hDisplay, "WM_DELETE_WINDOW", 0); XkbSetDetectableAutoRepeat(hDisplay, true, NULL); }
void InitKeyboard() { wmprotocols = XInternAtom(g.Disp, "WM_PROTOCOLS", 0); wmdelwindow = XInternAtom(g.Disp, "WM_DELETE_WINDOW", 0); XkbSetDetectableAutoRepeat(g.Disp, 1, NULL); g.PadState[0].KeyStatus = 0xFFFF; g.PadState[1].KeyStatus = 0xFFFF; }
//----------------------------------------------------------------------------- void init_input() { // We want to track keyboard and mouse events XSelectInput(display, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); // Check presence of detectable autorepeat Bool detectable; x11_detectable_autorepeat = (bool) XkbSetDetectableAutoRepeat(display, true, &detectable); x11_create_hidden_cursor(); }
static void clutter_keymap_x11_constructed (GObject *gobject) { ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (gobject); ClutterBackendX11 *backend_x11; g_assert (keymap_x11->backend != NULL); backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); #ifdef HAVE_XKB { gint xkb_major = XkbMajorVersion; gint xkb_minor = XkbMinorVersion; if (XkbLibraryVersion (&xkb_major, &xkb_minor)) { xkb_major = XkbMajorVersion; xkb_minor = XkbMinorVersion; if (XkbQueryExtension (backend_x11->xdpy, NULL, &keymap_x11->xkb_event_base, NULL, &xkb_major, &xkb_minor)) { Bool detectable_autorepeat_supported; backend_x11->use_xkb = TRUE; XkbSelectEvents (backend_x11->xdpy, XkbUseCoreKbd, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask); XkbSelectEventDetails (backend_x11->xdpy, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupLockMask | XkbModifierLockMask); /* enable XKB autorepeat */ XkbSetDetectableAutoRepeat (backend_x11->xdpy, True, &detectable_autorepeat_supported); backend_x11->have_xkb_autorepeat = detectable_autorepeat_supported; CLUTTER_NOTE (BACKEND, "Detectable autorepeat: %s", backend_x11->have_xkb_autorepeat ? "supported" : "not supported"); } } } #endif /* HAVE_XKB */ }
void OnLibraryLoad() { // Tell X Threads are OK. XInitThreads(); #ifdef XT XtToolkitInitialize(); app_context = XtCreateApplicationContext(); #endif // Open local display. disp = XOpenDisplay(XDisplayName(NULL)); #ifdef DEBUG if (disp != NULL) { fprintf(stdout, "OnLibraryLoad(): XOpenDisplay successful.\n"); } else { fprintf(stderr, "OnLibraryLoad(): XOpenDisplay failure!\n"); } #endif Bool isAutoRepeat = False; #ifdef XKB // Enable detectable autorepeat. XkbSetDetectableAutoRepeat(disp, True, &isAutoRepeat); #else XAutoRepeatOn(disp); XKeyboardState kb_state; XGetKeyboardControl(disp, &kb_state); isAutoRepeat = (kb_state.global_auto_repeat == AutoRepeatModeOn); #endif #ifdef DEBUG if (isAutoRepeat) { fprintf(stdout, "OnLibraryLoad(): Successfully enabled detectable autorepeat.\n"); } else { fprintf(stderr, "OnLibraryLoad(): Could not enable detectable auto-repeat!\n"); } #endif }
static Display* _initX11Package() { Display* display = XOpenDisplay( 0 ); if ( display ) { X11Package::ourScreen = DefaultScreen( display ); X11Package::ourRootWindow = DefaultRootWindow( display ); Bool Supported; XkbSetDetectableAutoRepeat( display, True, &Supported ); XFlush( display ); X11Package::ourInputMethod = XOpenIM( display, 0, 0, 0 ); } else throw; atexit( _cleanX11Package ); return display; }
void DestroyKeyboard() { XkbSetDetectableAutoRepeat(g.Disp, 0, NULL); // Enable cursor and revert grab cursor if mouse if (g.cfg.PadDef[0].Type == PSE_PAD_TYPE_MOUSE || g.cfg.PadDef[1].Type == PSE_PAD_TYPE_MOUSE) { grabCursor(g.Disp, window, 0); showCursor(g.Disp, window, 1); } else if (g.cfg.HideCursor) { showCursor(g.Disp, window, 1); } // Enable screensaver if it was disabled - this could be in different place if (resumeScrSaver) { char buf[64]; printf("Resuming Window ID 0x%x to activate screensaver.\n", window); snprintf(buf, 64, "xdg-screensaver resume 0x%x", window); FILE *phandle = popen(buf, "r"); pclose(phandle); } }
void InitKeyboard() { int revert_to; wmprotocols = XInternAtom(g.Disp, "WM_PROTOCOLS", 0); wmdelwindow = XInternAtom(g.Disp, "WM_DELETE_WINDOW", 0); // Hide cursor and lock cursor to window if type is mouse XkbSetDetectableAutoRepeat(g.Disp, 1, NULL); XGetInputFocus(g.Disp, &window, &revert_to); if (g.cfg.PadDef[0].Type == PSE_PAD_TYPE_MOUSE || g.cfg.PadDef[1].Type == PSE_PAD_TYPE_MOUSE) { grabCursor(g.Disp, window, 1); showCursor(g.Disp, window, 0); } else if (g.cfg.HideCursor) { showCursor(g.Disp, window, 0); } // Disable screensaver - this could be in different place resumeScrSaver = 0; if (g.cfg.PreventScrSaver) { char buf[64]; snprintf(buf, 64, "xdg-screensaver suspend 0x%x > /dev/null 2>&1", window); if (pclose(popen(buf, "r")) == 0) { resumeScrSaver = 1; printf("Suspending Window ID 0x%x of activating screensaver.\n", window); } else { //resumeScrSaver = 0; fprintf(stderr, "Failed to execute xdg-screensaver (maybe not installed?)\n"); } } g_currentMouse_X = 0; g_currentMouse_Y = 0; g.PadState[0].KeyStatus = 0xFFFF; g.PadState[1].KeyStatus = 0xFFFF; }
/* * Setup X11 wnd System */ void X11_SetupWindow (GF_VideoOutput * vout) { X11VID (); const char *sOpt; Bool autorepeat, supported; xWindow->display = XOpenDisplay (NULL); xWindow->screennum = DefaultScreen (xWindow->display); xWindow->screenptr = DefaultScreenOfDisplay (xWindow->display); xWindow->visual = DefaultVisualOfScreen (xWindow->screenptr); xWindow->depth = DefaultDepth (xWindow->display, xWindow->screennum); { Float screenWidth = (Float)XWidthOfScreen(xWindow->screenptr); Float screenWidthIn = (Float)XWidthMMOfScreen(xWindow->screenptr) / 25.4f; Float screenHeight = (Float)XHeightOfScreen(xWindow->screenptr); Float screenHeightIn = (Float)XHeightMMOfScreen(xWindow->screenptr) / 25.4f; vout->dpi_x = (u32)(screenWidth / screenWidthIn); vout->dpi_y = (u32)(screenHeight / screenHeightIn); } switch (xWindow->depth) { case 8: xWindow->pixel_format = GF_PIXEL_GREYSCALE; break; case 16: xWindow->pixel_format = GF_PIXEL_RGB_565; break; case 24: xWindow->pixel_format = GF_PIXEL_RGB_32; break; default: xWindow->pixel_format = GF_PIXEL_GREYSCALE; break; } xWindow->bpp = xWindow->depth / 8; xWindow->bpp = xWindow->bpp == 3 ? 4 : xWindow->bpp; xWindow->screennum=0; vout->max_screen_width = DisplayWidth(xWindow->display, xWindow->screennum); vout->max_screen_height = DisplayHeight(xWindow->display, xWindow->screennum); /* * Full screen wnd */ xWindow->full_wnd = XCreateWindow (xWindow->display, RootWindowOfScreen (xWindow->screenptr), 0, 0, vout->max_screen_width, vout->max_screen_height, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XSelectInput(xWindow->display, xWindow->full_wnd, FocusChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask); if (!xWindow->par_wnd) { xWindow->w_width = 320; xWindow->w_height = 240; xWindow->wnd = XCreateWindow (xWindow->display, RootWindowOfScreen(xWindow->screenptr), 0, 0, xWindow->w_width, xWindow->w_height, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XMapWindow (xWindow->display, (Window) xWindow->wnd); } else { XWindowAttributes pwa; XGetWindowAttributes(xWindow->display, xWindow->par_wnd, &pwa); xWindow->w_width = pwa.width; xWindow->w_height = pwa.height; xWindow->wnd = XCreateWindow (xWindow->display, xWindow->par_wnd, pwa.x, pwa.y, xWindow->w_width, xWindow->w_height, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XMapWindow (xWindow->display, (Window) xWindow->wnd); } XSync(xWindow->display, False); XUnmapWindow (xWindow->display, (Window) xWindow->wnd); XSync(xWindow->display, False); old_handler = XSetErrorHandler(X11_BadAccess_ByPass); selectinput_err = 0; XSelectInput(xWindow->display, xWindow->wnd, FocusChangeMask | StructureNotifyMask | PropertyChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask); XSync(xWindow->display, False); XSetErrorHandler(old_handler); if (selectinput_err) { XSelectInput(xWindow->display, xWindow->wnd, StructureNotifyMask | PropertyChangeMask | ExposureMask | KeyPressMask | KeyReleaseMask); GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Cannot select input focus\n")); } XSync(xWindow->display, False); XMapWindow (xWindow->display, (Window) xWindow->wnd); XSizeHints *Hints = XAllocSizeHints (); Hints->flags = PSize | PMinSize; Hints->min_width = 64; Hints->min_height = 64; Hints->max_height = 4096; Hints->max_width = 4096; if (!xWindow->par_wnd) { XSetWMNormalHints (xWindow->display, xWindow->wnd, Hints); XStoreName (xWindow->display, xWindow->wnd, "GPAC X11 Output"); } Hints->x = 0; Hints->y = 0; Hints->flags |= USPosition; XSetWMNormalHints (xWindow->display, xWindow->full_wnd, Hints); autorepeat = 1; XkbSetDetectableAutoRepeat(xWindow->display, autorepeat, &supported); if (xWindow->init_flags & GF_TERM_WINDOW_NO_DECORATION) { #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 #define MWM_HINTS_DECORATIONS (1L << 1) struct { unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; } hints = {2, 0, 0, 0, 0}; hints.flags = MWM_HINTS_DECORATIONS; hints.decorations = 0; XChangeProperty(xWindow->display, xWindow->wnd, XInternAtom(xWindow->display,"_MOTIF_WM_HINTS", False), XInternAtom(xWindow->display, "_MOTIF_WM_HINTS", False), 32, PropModeReplace, (unsigned char *)&hints, PROP_MOTIF_WM_HINTS_ELEMENTS); } xWindow->the_gc = XCreateGC (xWindow->display, xWindow->wnd, 0, NULL); xWindow->use_shared_memory = 0; #ifdef GPAC_HAS_X11_SHM sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseHardwareMemory"); if (sOpt && !strcmp(sOpt, "yes")) { int XShmMajor, XShmMinor; Bool XShmPixmaps; if (XShmQueryVersion(xWindow->display, &XShmMajor, &XShmMinor, &XShmPixmaps)) { xWindow->use_shared_memory = 1; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using X11 Shared Memory\n")); if ((XShmPixmaps==True) && (XShmPixmapFormat(xWindow->display)==ZPixmap)) { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] X11 Shared Memory Pixmaps available\n")); } } } #endif #ifdef GPAC_HAS_X11_XV sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "DisableColorKeying"); if (sOpt && !strcmp(sOpt, "yes")) { xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0); } else { xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 1); if (xWindow->xvport<0) { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware has no color keying\n")); vout->overlay_color_key = 0; xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0); } else { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware uses color key %08x\n", vout->overlay_color_key)); } } if (xWindow->xvport>=0) { XvUngrabPort(xWindow->display, xWindow->xvport, CurrentTime ); xWindow->xvport = -1; vout->yuv_pixel_format = X11_GetPixelFormat(xWindow->xv_pf_format); vout->Blit = X11_Blit; vout->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV YUV Overlays\n")); #ifdef GPAC_HAS_X11_SHM /*if user asked for YUV->RGB on offscreen, do it (it may crash the system)*/ sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "EnableOffscreenYUV"); if (sOpt && !strcmp(sOpt, "yes")) { vout->hw_caps |= GF_VIDEO_HW_HAS_YUV; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV Offscreen YUV2RGB acceleration\n")); } #endif } #endif XSetWindowAttributes xsw; xsw.border_pixel = WhitePixel (xWindow->display, xWindow->screennum); xsw.background_pixel = BlackPixel (xWindow->display, xWindow->screennum); xsw.win_gravity = NorthWestGravity; XChangeWindowAttributes (xWindow->display, xWindow->wnd, CWBackPixel | CWWinGravity, &xsw); xsw.override_redirect = True; XChangeWindowAttributes(xWindow->display, xWindow->full_wnd, CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWWinGravity, &xsw); if (!xWindow->par_wnd) { xWindow->WM_DELETE_WINDOW = XInternAtom (xWindow->display, "WM_DELETE_WINDOW", False); XSetWMProtocols(xWindow->display, xWindow->wnd, &xWindow->WM_DELETE_WINDOW, 1); } { XEvent ev; long mask; memset (&ev, 0, sizeof (ev)); ev.xclient.type = ClientMessage; ev.xclient.window = RootWindowOfScreen (xWindow->screenptr); ev.xclient.message_type = XInternAtom (xWindow->display, "KWM_KEEP_ON_TOP", False); ev.xclient.format = 32; ev.xclient.data.l[0] = xWindow->full_wnd; ev.xclient.data.l[1] = CurrentTime; mask = SubstructureRedirectMask; XSendEvent (xWindow->display,RootWindowOfScreen (xWindow->screenptr), False, mask, &ev); } /*openGL setup*/ #ifdef GPAC_HAS_OPENGL { int attribs[64]; int i, nb_bits; sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent"); /* Most outputs are 24/32 bits these days, use 8 bits per channel instead of 5, works better on MacOS X */ nb_bits = sOpt ? atoi(sOpt) : 8; if (!sOpt){ gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent", "8"); } i=0; attribs[i++] = GLX_RGBA; attribs[i++] = GLX_RED_SIZE; attribs[i++] = nb_bits; attribs[i++] = GLX_GREEN_SIZE; attribs[i++] = nb_bits; attribs[i++] = GLX_BLUE_SIZE; attribs[i++] = nb_bits; sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth"); nb_bits = sOpt ? atoi(sOpt) : 16; if (!sOpt){ gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth", "16"); } if (nb_bits) { attribs[i++] = GLX_DEPTH_SIZE; attribs[i++] = nb_bits; } sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering"); if (!sOpt){ gf_modules_set_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering", "yes"); } if (!sOpt || !strcmp(sOpt, "yes")) attribs[i++] = GLX_DOUBLEBUFFER; attribs[i++] = None; xWindow->glx_visualinfo = glXChooseVisual(xWindow->display, xWindow->screennum, attribs); if (!xWindow->glx_visualinfo) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Error selecting GL display\n")); } } xWindow->gl_wnd = XCreateWindow (xWindow->display, RootWindowOfScreen (xWindow->screenptr), 0, 0, 200, 200, 0, xWindow->depth, InputOutput, xWindow->visual, 0, NULL); XSync(xWindow->display, False); XUnmapWindow(xWindow->display, (Window) xWindow->gl_wnd); XSync(xWindow->display, False); sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode"); if (!sOpt) gf_modules_set_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode", "Pixmap"); if (sOpt && !strcmp(sOpt, "Window")) { xWindow->offscreen_type = 1; } else if (sOpt && !strcmp(sOpt, "VisibleWindow")) { xWindow->offscreen_type = 2; XSetWMNormalHints (xWindow->display, xWindow->gl_wnd, Hints); } else if (sOpt && !strcmp(sOpt, "Pixmap")) { xWindow->offscreen_type = 0; } else { xWindow->offscreen_type = 0; } #endif /*turn off xscreensaver*/ X11_XScreenSaverState(xWindow, 0); xWindow->setup_done = 1; XFree (Hints); }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_nSetDetectableKeyRepeat(JNIEnv *env, jclass unused, jlong display_ptr, jboolean set_enabled) { Display *disp = (Display *)(intptr_t)display_ptr; Bool enabled = set_enabled == JNI_TRUE ? True : False; Bool result = XkbSetDetectableAutoRepeat(disp, enabled, NULL); return result == enabled ? JNI_TRUE : JNI_FALSE; }
void KeyboardClose() { //Debug("Pokopom -> Keyboard Close\n"); XkbSetDetectableAutoRepeat(hDisplay, false, NULL); }
bool wxSetDetectableAutoRepeat( bool flag ) { Bool result; XkbSetDetectableAutoRepeat( GDK_DISPLAY(), flag, &result ); return result; /* true if keyboard hardware supports this mode */ }
static void DestroyKeyboard(void) { Display *disp = (Display *)gpuDisp; if (disp) XkbSetDetectableAutoRepeat(disp, 0, NULL); }
kgmWindow::kgmWindow(kgmWindow* wp, kgmString wname, int x, int y, int w, int h, int bpp, bool fs) { m_parent = wp; m_msAbs = true; m_msf = false; m_fs = false; kgmLog::log("Init screen"); #ifdef WIN32 WNDCLASS wcl; if(!GetClassInfo(0, cWndClass, &wcl)) kgmRegisterWindowClass(); m_wnd = CreateWindow(cWndClass, wname, (fs)?(WS_POPUP|WS_VISIBLE):(WS_OVERLAPPEDWINDOW|WS_VISIBLE), x, y, w, h, (wp)?(wp->m_wnd):(0), 0, 0, 0); SetWindowLong(m_wnd, GWL_USERDATA, (LONG)this); ShowWindow(m_wnd, SW_SHOW); UpdateWindow(m_wnd); #elif defined(ANDROID) kgm_log() << "Init window rect: " << w << " " << h << "."; m_wRect[0] = x; m_wRect[1] = y; m_wRect[2] = w; m_wRect[3] = h; #else XSetWindowAttributes swa; int cmask = CWColormap | CWBorderPixel | CWEventMask | CWOverrideRedirect; m_dpy = (wp) ? (wp->m_dpy) : XOpenDisplay(NULL); m_screen = (wp) ? (wp->m_screen) : DefaultScreen(m_dpy); m_wnd = XCreateSimpleWindow(m_dpy, (wp)?(wp->m_wnd):RootWindow(m_dpy, 0), x, y, w, h, 0, BlackPixel(m_dpy, 0), BlackPixel(m_dpy, 0)); //m_wnd = XCreateWindow(m_dpy, DefaultRootWindow(m_dpy), x, y, w, h, 0, // DefaultDepth(m_dpy, 0), InputOutput, DefaultVisual(m_dpy, 0), // cmask, &swa); //m_wnd = XCreateWindow(m_dpy, RootWindow(m_dpy, 0), x, y, w, h, 0, // DefaultDepth(m_dpy, 0), InputOutput, DefaultVisual(m_dpy, 0), // cmask, &swa); Atom delWindow = XInternAtom( m_dpy, "WM_DELETE_WINDOW", 0 ); XSetWMProtocols(m_dpy, m_wnd, &delWindow, 1); XSelectInput(m_dpy, m_wnd, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ButtonMotionMask); XMapWindow(m_dpy, m_wnd); XStoreName(m_dpy, m_wnd, wname); XFlush(m_dpy); Bool b_ret; XkbSetDetectableAutoRepeat(m_dpy, True, &b_ret); #endif }
void os_CreateWindow() { #if defined(SUPPORT_X11) // Variables regarding keyboard auto-repeat Bool ar_set, ar_supp = false; if (cfgLoadInt("pvr","nox11",0)==0) { XInitThreads(); // X11 variables Window x11Window = 0; Display* x11Display = 0; long x11Screen = 0; XVisualInfo* x11Visual = 0; Colormap x11Colormap = 0; /* Step 0 - Create a NativeWindowType that we can use it for OpenGL ES output */ Window sRootWindow; XSetWindowAttributes sWA; unsigned int ui32Mask; int i32Depth; // Initializes the display and screen x11Display = XOpenDisplay( 0 ); if (!x11Display && !(x11Display = XOpenDisplay( ":0" ))) { printf("Error: Unable to open X display\n"); return; } x11Screen = XDefaultScreen( x11Display ); // Gets the window parameters sRootWindow = RootWindow(x11Display, x11Screen); int depth = CopyFromParent; #if !defined(GLES) // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, //GLX_SAMPLE_BUFFERS , 1, //GLX_SAMPLES , 4, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if ( !glXQueryVersion( x11Display, &glx_major, &glx_minor ) || ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) { printf("Invalid GLX version"); exit(1); } int fbcount; GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); if (!fbc) { printf( "Failed to retrieve a framebuffer config\n" ); exit(1); } printf( "Found %d matching FB configs.\n", fbcount ); GLXFBConfig bestFbc = fbc[ 0 ]; XFree( fbc ); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig( x11Display, bestFbc ); printf( "Chosen visual ID = 0x%x\n", vi->visualid ); depth = vi->depth; x11Visual = vi; x11Colormap = XCreateColormap(x11Display, RootWindow(x11Display, x11Screen), vi->visual, AllocNone); #else i32Depth = DefaultDepth(x11Display, x11Screen); x11Visual = new XVisualInfo; XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, x11Visual); if (!x11Visual) { printf("Error: Unable to acquire visual\n"); return; } x11Colormap = XCreateColormap( x11Display, sRootWindow, x11Visual->visual, AllocNone ); #endif sWA.colormap = x11Colormap; // Add to these for handling other events sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; #ifdef TARGET_PANDORA int width=800; int height=480; #else int width=cfgLoadInt("x11","width", WINDOW_WIDTH); int height=cfgLoadInt("x11","height", WINDOW_HEIGHT); #endif if (width==-1 || height==-1 || cfgLoadInt("x11","fullscreen",0)==1) { width=XDisplayWidth(x11Display,x11Screen); height=XDisplayHeight(x11Display,x11Screen); } // Create the X11 window x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height, 0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA); #ifdef TARGET_PANDORA // fullscreen Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); XMapRaised(x11Display, x11Window); #else if (cfgLoadInt("x11","fullscreen",0)==1) //FIX { Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); } XMapWindow(x11Display, x11Window); sleep(1); //fix black border at the top of the screen.... #if !defined(GLES) #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); verify( glXCreateContextAttribsARB != 0 ); int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; x11_glc = glXCreateContextAttribsARB( x11Display, bestFbc, 0, True, context_attribs); XSync( x11Display, False ); if (!x11_glc) { die("Failed to create GL3.1 context\n"); } #endif #endif XFlush(x11Display); //(EGLNativeDisplayType)x11Display; x11_disp=(void*)x11Display; x11_win=(void*)x11Window; // Turn off autorepeat so that keyboard controls do not simulate rapid on/off ar_set = XkbSetDetectableAutoRepeat(x11Display, True, &ar_supp); printf("XkbSetDetectableAutoRepeat returns %u, supported = %u\n",ar_set, ar_supp); } else printf("Not creating X11 window ..\n"); #endif }
/* x_keyboard_init * Initialise the X11 keyboard driver. */ static int x_keyboard_init(void) { #ifdef ALLEGRO_XWINDOWS_WITH_XIM char *old_locale; XIMStyles *xim_styles; XIMStyle xim_style = 0; char *imvalret; int i; #endif ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); if (xkeyboard_installed) return 0; if (s->x11display == NULL) return 0; main_pid = getpid(); memcpy(key_names, _al_keyboard_common_names, sizeof key_names); _al_mutex_lock(&s->lock); /* HACK: XkbSetDetectableAutoRepeat is broken in some versions of X.Org */ Bool supported; XkbSetDetectableAutoRepeat(s->x11display, True, &supported); if (!supported) { ALLEGRO_WARN("XkbSetDetectableAutoRepeat failed.\n"); } #ifdef ALLEGRO_XWINDOWS_WITH_XIM ALLEGRO_INFO("Using X Input Method.\n"); old_locale = setlocale(LC_CTYPE, NULL); ALLEGRO_DEBUG("Old locale: %s\n", old_locale ? old_locale : "(null)"); if (old_locale) { /* The return value of setlocale() may be clobbered by the next call * to setlocale() so we must copy it. */ old_locale = strdup(old_locale); } /* Otherwise we are restricted to ISO-8859-1 characters. */ if (setlocale(LC_CTYPE, "") == NULL) { ALLEGRO_WARN("Could not set default locale.\n"); } /* TODO: is this needed? modifiers = XSetLocaleModifiers("@im=none"); if (modifiers == NULL) { ALLEGRO_WARN("XSetLocaleModifiers failed.\n"); } */ xim = XOpenIM(s->x11display, NULL, NULL, NULL); if (xim == NULL) { ALLEGRO_WARN("XOpenIM failed.\n"); } if (old_locale) { ALLEGRO_DEBUG("Restoring old locale: %s\n", old_locale); setlocale(LC_CTYPE, old_locale); free(old_locale); } if (xim) { imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); if (imvalret != NULL || xim_styles == NULL) { ALLEGRO_WARN("Input method doesn't support any styles.\n"); } if (xim_styles) { xim_style = 0; for (i = 0; i < xim_styles->count_styles; i++) { if (xim_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) { xim_style = xim_styles->supported_styles[i]; break; } } if (xim_style == 0) { ALLEGRO_WARN("Input method doesn't support the style we support.\n"); } else { ALLEGRO_INFO("Input method style = %ld\n", xim_style); } XFree(xim_styles); } } if (xim && xim_style) { xic = XCreateIC(xim, XNInputStyle, xim_style, NULL); if (xic == NULL) { ALLEGRO_WARN("XCreateIC failed.\n"); } else { ALLEGRO_INFO("XCreateIC succeeded.\n"); } /* In case al_install_keyboard() is called when there already is * a display, we set it as client window. */ ALLEGRO_DISPLAY *display = al_get_current_display(); ALLEGRO_DISPLAY_XGLX *display_glx = (void *)display; if (display_glx && xic) XSetICValues(xic, XNClientWindow, display_glx->window, NULL); } #endif if (!_al_xwin_get_keyboard_mapping()) { return 1; } _al_mutex_unlock(&s->lock); xkeyboard_installed = 1; return 0; }
// 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; }
void X11Window::create(XVisualInfo *visual, DisplayWindowSite *new_site, const DisplayWindowDescription &desc) { site = new_site; // Reset all variables close_window(); handle.screen = visual->screen; atoms = X11Atoms(handle.display); int disp_width_px = XDisplayWidth(handle.display, handle.screen); int disp_height_px = XDisplayHeight(handle.display, handle.screen); int disp_width_mm = XDisplayWidthMM(handle.display, handle.screen); // Get DPI of screen or use 96.0f if Xlib doesn't have a value. ppi = (disp_width_mm < 24) ? 96.0f : (25.4f * static_cast<float>(disp_width_px) / static_cast<float>(disp_width_mm)); // Update pixel ratio. set_pixel_ratio(pixel_ratio); // Get X11 root window. auto _root_window = RootWindow(handle.display, handle.screen); // Get and validate initial window position and size. int win_x = desc.get_position().left * pixel_ratio; int win_y = desc.get_position().top * pixel_ratio; int win_width = desc.get_size().width * pixel_ratio; int win_height = desc.get_size().height * pixel_ratio; if (win_width <= 0) throw Exception("Invalid window width."); if (win_height <= 0) throw Exception("Invalid window height."); // Set values if fullscreen requested. if (desc.is_fullscreen()) { win_x = 0; win_y = 0; win_width = disp_width_px; win_height = disp_height_px; } // Center window if position supplied is (-1, -1) if (win_x == -1 && win_y == -1) { win_x = (disp_width_px - win_width)/2 - 1; win_y = (disp_height_px - win_height)/2 - 1; } // Set minimum and maximum size this->resize_allowed = desc.get_allow_resize() || desc.is_fullscreen(); // Fullscreen mode needs a resizable window. if (resize_allowed) { minimum_size = Size(_ResizeMinimumSize_, _ResizeMinimumSize_); maximum_size = Size(0, 0); // No maximum size by default. } else { minimum_size = Size(win_width, win_height); maximum_size = Size(win_width, win_height); } // Setup X11 size hints. this->size_hints = XAllocSizeHints(); if (size_hints == NULL) throw Exception("Failed to allocate X11 XSizeHints structure."); size_hints->flags = PMinSize | (resize_allowed ? 0 : PMaxSize); size_hints->flags |= PResizeInc | PBaseSize | PWinGravity; // x, y, width, height are obsolete. size_hints->flags |= USSize | USPosition; // See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472522864 size_hints->min_width = minimum_size.width; size_hints->min_height = minimum_size.height; size_hints->max_width = maximum_size.width; size_hints->max_height = maximum_size.height; size_hints->width_inc = 1; size_hints->height_inc = 1; size_hints->base_width = win_width; size_hints->base_height = win_height; size_hints->win_gravity = NorthWestGravity; // Setup X11 colormap. // // The X.Org XServer implementation used on most systems requires that // a color-map be set for the window. Additionally, windows with a // different color-depth than its parent must have the border-pixel flag // set when creating them. Failure to do either will cause XCreateWindow() // to result in a BadMatch error. // // Source: stackoverflow.com/questions/3645632 color_map = XCreateColormap(handle.display, _root_window, visual->visual, AllocNone); // Static popups are unresizable captionless popup windows. // These windows should not be decorated. bool is_static_popup = desc.is_popup() && !desc.has_caption() && !desc.get_allow_resize(); // Tell X11 to perserve graphical content under small popup windows to avoid redraws. bool save_under = desc.is_popup() && ( (win_width * win_height) < (256 * 256 * pixel_ratio * pixel_ratio) ); // Setup window attributes. XSetWindowAttributes attr = XSetWindowAttributes { .background_pixmap = None, /* default */ .background_pixel = 0ul, /* default: undefined */ .border_pixmap = CopyFromParent, /* default */ .border_pixel = 0ul, /* see color_map details above */ .bit_gravity = ForgetGravity, /* default */ .win_gravity = NorthWestGravity, /* default */ .backing_store = NotUseful, /* default */ .backing_planes = -1ul, /* default */ .backing_pixel = 0ul, /* default */ .save_under = save_under ? True : False, .event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask | ExposureMask // | VisibilityChangeMask | StructureNotifyMask | FocusChangeMask | PropertyChangeMask , .do_not_propagate_mask = NoEventMask, /* default */ .override_redirect = is_static_popup ? True : False, .colormap = color_map, /* see color_map details above */ .cursor = None /* default; Let X11 handle the cursor for now. */ }; this->system_cursor = XCreateFontCursor(handle.display, XC_left_ptr); // This is allowed to fail log_event("debug", "clan::X11Window::create(): Creating window..."); log_event("debug", " x%1 y%2 w%3 h%4 b%5 d%6", win_x, win_y, win_width, win_height, border_width, visual->depth); log_event("debug", " a.su%1, a.od%2", save_under, is_static_popup); // Create window handle.window = XCreateWindow( handle.display, _root_window, win_x, win_y, win_width, win_height, border_width, visual->depth, InputOutput, visual->visual, CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap, &attr ); if (!handle.window) throw Exception("Unable to create the X11 window"); if (!desc.get_owner().is_null()) { DisplayWindow owner = desc.get_owner(); XSetTransientForHint(handle.display, handle.window, owner.get_handle().window); } // Setup the hidden cursor (Maybe this should be done only once when required) char data[64]; // 8x8 memset(data, 0, 64); XColor black_color; memset(&black_color, 0, sizeof(black_color)); cursor_bitmap = XCreateBitmapFromData(handle.display, handle.window, data, 8, 8); hidden_cursor = XCreatePixmapCursor(handle.display, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0); // Set title of window: set_title(desc.get_title()); { // Inform the window manager who we are, so it can kill us if we're not good for its universe. Atom atom; int32_t pid = getpid(); if (pid > 0) { atom = atoms.get_atom(handle.display, "_NET_WM_PID", False); XChangeProperty(handle.display, handle.window, atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &pid, 1); } char hostname[256]; if (gethostname(hostname, sizeof(hostname)) > -1) { hostname[255] = 0; atom = atoms.get_atom(handle.display, "WM_CLIENT_MACHINE", False); XChangeProperty(handle.display, handle.window, atom, XA_STRING, 8, PropModeReplace, (unsigned char *) hostname, strlen(hostname)); } } // Set-up window type/styling. // TODO Support more window types, broaden ClanLib window type support, etc. if (atoms["_NET_WM_WINDOW_TYPE"] != None) { Atom type = None; std::string name; if (desc.is_dialog()) { name = "_NET_WM_WINDOW_TYPE_DIALOG"; type = atoms[name]; } else if (desc.is_popup()) { if (is_static_popup) { name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; type = atoms[name]; } else if (desc.has_caption()) // A pop-up with title bar -> utility { name = "_NET_WM_WINDOW_TYPE_UTILITY"; type = atoms[name]; } // else, a pop-up without a title bar -> popup-menu, combo, dropdown, tooltip, ... if (type == None) { name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; type = atoms[name]; } if (type == None) { name = "_NET_WM_WINDOW_TYPE_COMBO"; type = atoms[name]; } if (type == None) { name = "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"; type = atoms[name]; } } // else if (desc.is_normal()) // Fallback to normal window type if WM doesn't support what we want. if (type == None) { name = "_NET_WM_WINDOW_TYPE_NORMAL"; type = atoms[name]; } if (type != None) // Ensure selected type exists. { XChangeProperty(handle.display, handle.window, atoms["_NET_WM_WINDOW_TYPE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&type, 1); log_event("debug", "clan::X11Window::create(): Creating window of type '%1'.", name); } else { log_event("debug", "clan::X11Window::create(): Failed to find a suitable window type."); } } else { log_event("debug", "clan::X11Window::create(): _NET_WM_WINDOW_TYPE does not exist."); } // Set size hints XSetWMNormalHints(handle.display, handle.window, size_hints); { // Subscribe to WM events. Atom protocol = atoms["WM_DELETE_WINDOW"]; Status result = XSetWMProtocols(handle.display, handle.window, &protocol, 1); if (result == 0) log_event("debug", "clan::X11Window::create(): Failed to set WM_PROTOCOLS."); } { // Make auto-repeat keys detectable. Bool supports_detectable_autorepeat; XkbSetDetectableAutoRepeat(handle.display, True, &supports_detectable_autorepeat); } { // Make window full-screen if requested. if (atoms["_NET_WM_STATE"] == None && atoms["_NET_WM_STATE_FULLSCREEN"]) { fullscreen = false; log_event("debug", "clan::X11Window: Fullscreen not supported by WM."); } else { fullscreen = desc.is_fullscreen(); } if (fullscreen) { Atom state = atoms["_NET_WM_STATE_FULLSCREEN"]; XChangeProperty(handle.display, handle.window, atoms["_NET_WM_STATE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&state, 1); } } update_frame_extents(); auto new_client_area = desc.get_position_client_area() // supplied position is at ? client area : window area; ? Rect::xywh(win_x, win_y, win_width, win_height) : Rect::xywh(win_x + frame_extents.left, win_y + frame_extents.right, win_width, win_height) ; process_window_resize(new_client_area); // Set window visibility if (desc.is_visible()) { show(false); } // Setup the clipboard clipboard.setup(); // Go looking for joysticks: setup_joysticks(); } void X11Window::update_frame_extents() { frame_extents = Rect { border_width, border_width, border_width, border_width }; if (atoms["_NET_FRAME_EXTENTS"] == None) return; // Request frame extents from WM. if (atoms["_NET_REQUEST_FRAME_EXTENTS"] != None) { XEvent event; memset(&event, 0, sizeof(event)); event.type = ClientMessage; event.xclient.window = handle.window; event.xclient.format = 32; event.xclient.message_type = atoms["_NET_REQUEST_FRAME_EXTENTS"]; XSendEvent(handle.display, RootWindow(handle.display, handle.screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &event); int timer = 10; while(true) { if (timer < 0) { log_event("debug", "clan::X11Window: Your window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation."); break; } if (XCheckMaskEvent(handle.display, PropertyNotify, &event)) { break; } clan::System::sleep(5); timer--; } } unsigned long item_count; // _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32 unsigned char *data = atoms.get_property(handle.window, "_NET_FRAME_EXTENTS", item_count); if (data == NULL) return; if (item_count >= 4) { long *cardinal = (long *)data; frame_extents.left = cardinal[0]; frame_extents.right = cardinal[1]; frame_extents.top = cardinal[2]; frame_extents.bottom = cardinal[3]; } XFree(data); }
int32_t run(Filesystem* fs, ConfigSettings* cs) { // Create main window XInitThreads(); XSetErrorHandler(x11_error_handler); m_x11_display = XOpenDisplay(NULL); CE_ASSERT(m_x11_display != NULL, "Unable to open X11 display"); int screen = DefaultScreen(m_x11_display); int depth = DefaultDepth(m_x11_display, screen); Visual* visual = DefaultVisual(m_x11_display, screen); m_x11_parent_window = (m_parent_window_handle == 0) ? RootWindow(m_x11_display, screen) : (Window) m_parent_window_handle; // Create main window XSetWindowAttributes win_attribs; win_attribs.background_pixmap = 0; win_attribs.border_pixel = 0; win_attribs.event_mask = FocusChangeMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; m_x11_window = XCreateWindow(m_x11_display, m_x11_parent_window, 0, 0, cs->window_width, cs->window_height, 0, depth, InputOutput, visual, CWBorderPixel | CWEventMask, &win_attribs ); CE_ASSERT(m_x11_window != None, "Unable to create X window"); // Do we have detectable autorepeat? Bool detectable; m_x11_detectable_autorepeat = (bool) XkbSetDetectableAutoRepeat(m_x11_display, true, &detectable); // Build hidden cursor Pixmap bm_no; XColor black, dummy; Colormap colormap; static char no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; colormap = XDefaultColormap(m_x11_display, screen); XAllocNamedColor(m_x11_display, colormap, "black", &black, &dummy); bm_no = XCreateBitmapFromData(m_x11_display, m_x11_window, no_data, 8, 8); m_x11_hidden_cursor = XCreatePixmapCursor(m_x11_display, bm_no, bm_no, &black, &black, 0, 0); m_wm_delete_message = XInternAtom(m_x11_display, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_x11_display, m_x11_window, &m_wm_delete_message, 1); oswindow_set_window(m_x11_display, m_x11_window); bgfx::x11SetDisplayWindow(m_x11_display, m_x11_window); XMapRaised(m_x11_display, m_x11_window); // Get screen configuration m_screen_config = XRRGetScreenInfo(m_x11_display, RootWindow(m_x11_display, screen)); Rotation rr_old_rot; const SizeID rr_old_sizeid = XRRConfigCurrentConfiguration(m_screen_config, &rr_old_rot); // Start main thread MainThreadArgs mta; mta.fs = fs; mta.cs = cs; Thread main_thread; main_thread.start(func, &mta); while (!s_exit) { pump_events(); } main_thread.stop(); // Restore previous screen configuration if changed Rotation rr_cur_rot; const SizeID rr_cur_sizeid = XRRConfigCurrentConfiguration(m_screen_config, &rr_cur_rot); if (rr_cur_rot != rr_old_rot || rr_cur_sizeid != rr_old_sizeid) { XRRSetScreenConfig(m_x11_display, m_screen_config, RootWindow(m_x11_display, screen), rr_old_sizeid, rr_old_rot, CurrentTime); } XRRFreeScreenConfigInfo(m_screen_config); XDestroyWindow(m_x11_display, m_x11_window); XCloseDisplay(m_x11_display); return EXIT_SUCCESS; }
void DestroyKeyboard() { XkbSetDetectableAutoRepeat(g.Disp, 0, NULL); }
void setup_x(int w, int h) { keys[XK_Up] = false; keys[XK_Down] = false; keys[XK_Left] = false; keys[XK_Right] = false; display = XOpenDisplay(NULL); if (!display) { printf("Failed to open X display\n"); exit(1); } // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, True, // GLX_SAMPLE_BUFFERS , 1, // GLX_SAMPLES , 4, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if (!glXQueryVersion(display, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { printf("Invalid GLX version"); exit(1); } XkbSetDetectableAutoRepeat(display, True, NULL); //printf("Getting matching framebuffer configs\n"); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount); if (!fbc) { printf("Failed to retrieve a framebuffer config\n"); exit(1); } printf("Found %d matching FB configs.\n", fbcount); // Pick the FB config/visual with the most samples per pixel //printf("Getting XVisualInfos\n"); int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; int i; for (i = 0; i < fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[i]); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLES, &samples); /*printf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," " SAMPLES = %d\n", i, vi->visualid, samp_buf, samples);*/ if (best_fbc < 0 || samp_buf && samples > best_num_samp) best_fbc = i, best_num_samp = samples; if (worst_fbc < 0 || !samp_buf || samples < worst_num_samp) worst_fbc = i, worst_num_samp = samples; } XFree(vi); } GLXFBConfig bestFbc = fbc[best_fbc]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree(fbc); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig(display, bestFbc); //printf("Chosen visual ID = 0x%x\n", vi->visualid); //printf("Creating colormap\n"); swa.colormap = cmap = XCreateColormap( display, RootWindow(display, vi->screen), vi->visual, AllocNone); swa.background_pixmap = None; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; Atom WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", False); //printf("Creating window\n"); win = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, w, h, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetWMProtocols(display, win, &WM_DELETE_WINDOW, 1); if (!win) { printf("Failed to create window.\n"); exit(1); } // Done with the visual info data XFree(vi); set_title("GL 3.0 Window"); //printf("Mapping window\n"); XMapWindow(display, win); XSelectInput(display, win, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString(display, DefaultScreen(display)); // NOTE: It is not necessary to create or make current to a context before // calling glXGetProcAddressARB glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB( (const GLubyte *)"glXCreateContextAttribsARB"); // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. All display connections in all threads // of a process use the same error handler, so be sure to guard against other // threads issuing X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if (!isExtensionSupported(glxExts, "GLX_ARB_create_context") || !glXCreateContextAttribsARB) { printf("glXCreateContextAttribsARB() not found" " ... using old-style GLX context\n"); ctx = glXCreateNewContext(display, bestFbc, GLX_RGBA_TYPE, 0, True); } // If it does, try to get a GL 3.0 context! else { int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 3, // GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; //printf("Creating context\n"); ctx = glXCreateContextAttribsARB(display, bestFbc, 0, True, context_attribs); // Sync to ensure any errors generated are processed. XSync(display, False); if (!ctxErrorOccurred && ctx) printf("Created GL 3.0 context\n"); else { // Couldn't create GL 3.0 context. Fall back to old-style 2.x context. // When a context version below 3.0 is requested, implementations will // return the newest context version compatible with OpenGL versions less // than version 3.0. // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 context_attribs[1] = 1; // GLX_CONTEXT_MINOR_VERSION_ARB = 0 context_attribs[3] = 0; ctxErrorOccurred = false; printf("Failed to create GL 3.0 context" " ... using old-style GLX context\n"); ctx = glXCreateContextAttribsARB(display, bestFbc, 0, True, context_attribs); } } // Sync to ensure any errors generated are processed. XSync(display, False); // Restore the original error handler XSetErrorHandler(oldHandler); if (ctxErrorOccurred || !ctx) { printf("Failed to create an OpenGL context\n"); exit(1); } // Verifying that context is a direct context if (!glXIsDirect(display, ctx)) { printf("Indirect GLX rendering context obtained\n"); } else { printf("Direct GLX rendering context obtained\n"); } //printf("Making context current\n"); glXMakeCurrent(display, win, ctx); }
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; }
// 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; }
// Initialize X11 display and look for supported X11 extensions // static GLFWbool 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 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; } #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 = GLFW_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 = 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(); // 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 GLFW_TRUE; }
// Initialize X11 display and look for supported X11 extensions // static GLFWbool initExtensions(void) { _glfw.x11.vidmode.handle = dlopen("libXxf86vm.so.1", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.vidmode.handle) { _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension"); _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp"); _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp"); _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize"); _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); } _glfw.x11.xi.handle = dlopen("libXi.so", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) dlsym(_glfw.x11.xi.handle, "XIQueryVersion"); _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents) 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; } } } // 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 = XRRGetScreenResourcesCurrent(_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: Detected broken RandR gamma ramp support"); _glfw.x11.randr.gammaBroken = GLFW_TRUE; } if (!sr->ncrtc || !sr->noutput || !sr->nmode) { // This is either a headless system or broken Cygwin/X RandR // Flag it as useless and fall back to Xlib display functions _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Detected broken RandR monitor support"); _glfw.x11.randr.monitorBroken = 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.1", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.x11xcb.handle) { _glfw.x11.x11xcb.XGetXCBConnection = (PFN_XGetXCBConnection) 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.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.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); return GLFW_TRUE; }