Example #1
0
/**
 * 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;
}
Example #2
0
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);
	}
}
Example #3
0
void KeyboardOpen()
{
	//Debug("Pokopom -> Keyboard Open\n");
	aProtocols = XInternAtom(hDisplay, "WM_PROTOCOLS", 0);
	aDeleteWindow = XInternAtom(hDisplay, "WM_DELETE_WINDOW", 0);

	XkbSetDetectableAutoRepeat(hDisplay, true, NULL);
}
Example #4
0
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;
}
Example #5
0
//-----------------------------------------------------------------------------
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 */
}
Example #7
0
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
}
Example #8
0
    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;
    }
Example #9
0
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);
    }
}
Example #10
0
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;
}
Example #11
0
/*
 * 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;
}
Example #13
0
void KeyboardClose()
{
	//Debug("Pokopom -> Keyboard Close\n");
	XkbSetDetectableAutoRepeat(hDisplay, false, NULL);
}
Example #14
0
bool wxSetDetectableAutoRepeat( bool flag )
{
    Bool result;
    XkbSetDetectableAutoRepeat( GDK_DISPLAY(), flag, &result );
    return result;       /* true if keyboard hardware supports this mode */
}
Example #15
0
static void DestroyKeyboard(void) {
	Display *disp = (Display *)gpuDisp;
	if (disp)
		XkbSetDetectableAutoRepeat(disp, 0, NULL);
}
Example #16
0
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
}
Example #17
0
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
}
Example #18
0
/* 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;
}
Example #19
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;
}
Example #20
0
	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);
	}
Example #21
0
	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;
	}
Example #22
0
void DestroyKeyboard() {
	XkbSetDetectableAutoRepeat(g.Disp, 0, NULL);
}
Example #23
0
	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);
	}
Example #24
0
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;
}
Example #25
0
// 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;
}
Example #26
0
File: x11_init.c Project: jku/glfw
// 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;
}
Example #27
0
// 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;
}