Exemple #1
0
static int vid_mode_available (void)
{
#ifdef USE_VIDMODE_EXTENSION
    int MajorVersion, MinorVersion;
    int EventBase, ErrorBase;

    if (! dgaavail)
	return 0;
    if (! XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) {
	write_log ("Unable to query video extension version\n");
	return 0;
    }
    if (! XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
	write_log ("Unable to query video extension information\n");
	return 0;
    }
    if (MajorVersion < VidMode_MINMAJOR
	|| (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) {
	/* Fail if the extension version in the server is too old */
	write_log ("Xserver is running an old XFree86-VidMode version (%d.%d)\n",
		 MajorVersion, MinorVersion);
	write_log ("Minimum required version is %d.%d\n",
		 VidMode_MINMAJOR, VidMode_MINMINOR);
	return 0;
    }
    if (! get_vidmodes ()) {
	write_log ("Error getting video mode information\n");
	return 0;
    }
    return 1;
#else
    return 0;
#endif
}
Exemple #2
0
static int _glfwInitDisplay( void )
{
    // Open display
    _glfwLibrary.Dpy = XOpenDisplay( 0 );
    if( !_glfwLibrary.Dpy )
    {
        return GL_FALSE;
    }

    // Check screens
    _glfwLibrary.NumScreens = ScreenCount( _glfwLibrary.Dpy );
    _glfwLibrary.DefaultScreen = DefaultScreen( _glfwLibrary.Dpy );

    // Check for XF86VidMode extension
#ifdef _GLFW_HAS_XF86VIDMODE
    _glfwLibrary.XF86VidMode.Available =
        XF86VidModeQueryExtension( _glfwLibrary.Dpy,
                                   &_glfwLibrary.XF86VidMode.EventBase,
                                   &_glfwLibrary.XF86VidMode.ErrorBase);
#else
    _glfwLibrary.XF86VidMode.Available = 0;
#endif

    // Check for XRandR extension
#ifdef _GLFW_HAS_XRANDR
    _glfwLibrary.XRandR.Available =
        XRRQueryExtension( _glfwLibrary.Dpy,
                           &_glfwLibrary.XRandR.EventBase,
                           &_glfwLibrary.XRandR.ErrorBase );
#else
    _glfwLibrary.XRandR.Available = 0;
#endif

    return GL_TRUE;
}
Exemple #3
0
void X11DRV_XF86VM_Init(void)
{
  Bool ok;
  int nmodes;
  unsigned int i;

  if (xf86vm_major) return; /* already initialized? */

  /* see if XVidMode is available */
  wine_tsx11_lock();
  ok = XF86VidModeQueryExtension(gdi_display, &xf86vm_event, &xf86vm_error);
  if (ok)
  {
      X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL);
      ok = XF86VidModeQueryVersion(gdi_display, &xf86vm_major, &xf86vm_minor);
      if (X11DRV_check_error()) ok = FALSE;
  }
  if (ok)
  {
#ifdef X_XF86VidModeSetGammaRamp
      if (xf86vm_major > 2 || (xf86vm_major == 2 && xf86vm_minor >= 1))
      {
          XF86VidModeGetGammaRampSize(gdi_display, DefaultScreen(gdi_display),
                                      &xf86vm_gammaramp_size);
          if (xf86vm_gammaramp_size == 256)
              xf86vm_use_gammaramp = TRUE;
      }
#endif /* X_XF86VidModeSetGammaRamp */

      /* retrieve modes */
      if (usexvidmode && root_window == DefaultRootWindow( gdi_display ))
          ok = XF86VidModeGetAllModeLines(gdi_display, DefaultScreen(gdi_display), &nmodes, &real_xf86vm_modes);
      else
          ok = FALSE; /* In desktop mode, do not switch resolution... But still use the Gamma ramp stuff */
  }
  wine_tsx11_unlock();
  if (!ok) return;

  TRACE("XVidMode modes: count=%d\n", nmodes);

  real_xf86vm_mode_count = nmodes;

  dd_modes = X11DRV_Settings_SetHandlers("XF86VidMode", 
                                         X11DRV_XF86VM_GetCurrentMode, 
                                         X11DRV_XF86VM_SetCurrentMode, 
                                         nmodes, 1);

  /* convert modes to DDHALMODEINFO format */
  for (i=0; i<real_xf86vm_mode_count; i++)
  {
      convert_modeinfo(real_xf86vm_modes[i]);
  }
  /* add modes for different color depths */
  X11DRV_Settings_AddDepthModes();
  dd_mode_count = X11DRV_Settings_GetModeCount();

  TRACE("Available DD modes: count=%d\n", dd_mode_count);
  TRACE("Enabling XVidMode\n");
}
Exemple #4
0
gboolean xmms_fullscreen_init(GtkWidget * win)
{
	int event_base, error_base, dummy;
	fullscreen_window_t *fwin;
	gint i;
	XF86VidModeModeLine origmode;

	FULL_LOCK();
	fwin = getwindow(win);

	if (!XF86VidModeQueryExtension
	    (fwin->display->display, &event_base, &error_base))
	{
		FULL_UNLOCK();
		return FALSE;
	}

	if (!fwin->display->modes)
	{
		XF86VidModeGetAllModeLines(fwin->display->display,
					   DefaultScreen(fwin->display->display),
					   &fwin->display->num_modes,
					   &fwin->display->modes);

		if (!fwin->display->origmode)
		{
			XF86VidModeGetModeLine(fwin->display->display,
					       DefaultScreen(fwin->display->display),
					       &dummy, &origmode);
			for (i = 0; i < fwin->display->num_modes; i++)
			{
				if (fwin->display->modes[i]->hdisplay ==
				    origmode.hdisplay
				    && fwin->display->modes[i]->vdisplay ==
				    origmode.vdisplay)
				{
					fwin->display->origmode =
						fwin->display->modes[i];
					break;
				}
			}

			if (!fwin->display->origmode)
			{
				fprintf(stderr,
					"ERROR: Could not determine original mode.\n");
				FULL_UNLOCK();
				return FALSE;
			}

		}

		fwin->display->can_full = (fwin->display->num_modes > 1);
	}
	FULL_UNLOCK();
	return fwin->display->can_full;
}
Exemple #5
0
gboolean xmms_fullscreen_available(Display * dpy)
{
	int event_base, error_base, num_modes;
	XF86VidModeModeInfo **dummy;

	if (!XF86VidModeQueryExtension(dpy, &event_base, &error_base))
		return FALSE;

	XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &num_modes, &dummy);
	XFree(dummy);

	return (num_modes > 1);
}
Exemple #6
0
static bool GetModes(Resolution **_modes, bool fullscreen)
{
	MFCALLSTACK;

	int numModeLines;

	if(!fullscreen)
	{
		modes = defaultModes;

		for(uint32 i = 0; modes[i].width != 0; ++i)
		{
			++numModes;
		}
	}
	else
	{
		int throwaway;
		if(!XF86VidModeQueryExtension(xdisplay, &throwaway, &throwaway))
		{
			SetSingleMode(_modes);
			return true;
		}

		if((!XF86VidModeGetAllModeLines(xdisplay, screen, &numModeLines, &vidModes)) || numModeLines < 2)
		{
			SetSingleMode(_modes);
			return true;
		}

		originalVidMode = vidModes[0];
		numModes = (uint32)numModeLines;

		modes = (Resolution *)MFHeap_Alloc(sizeof(Resolution) * (numModes + 1));

		for(int32 i = 0; i < numModes; i++)
		{
			modes[i].width = vidModes[i]->hdisplay;
			modes[i].height = vidModes[i]->vdisplay;
			modes[i].refresh = ((float)vidModes[i]->dotclock / (float)vidModes[i]->htotal) / (float)vidModes[i]->htotal;
		}

		modes[numModes].width = 0;
		modes[numModes].height = 0;
	}

	if(_modes != NULL)
		*_modes = modes;

	return true;
}
Exemple #7
0
/* If the viewport has been scrolled since the screen was blanked,
   then scroll it back to where it belongs.  This function only exists
   to patch over a very brief race condition.
 */
static void
undo_vp_motion (saver_info *si)
{
#ifdef HAVE_XF86VMODE
  saver_preferences *p = &si->prefs;
  int screen;
  int real_nscreens = ScreenCount (si->dpy);
  int event, error;

  if (!XF86VidModeQueryExtension (si->dpy, &event, &error))
    return;

  for (screen = 0; screen < real_nscreens; screen++)
    {
      saver_screen_info *ssi = &si->screens[screen];
      int x, y;
      Bool status;

      if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1)
        break;
      if (!XF86VidModeGetViewPort (si->dpy, screen, &x, &y))
        return;
      if (ssi->blank_vp_x == x && ssi->blank_vp_y == y)
        return;

      /* We're going to move the viewport.  The mouse has just been grabbed on
         (and constrained to, thus warped to) the password window, so it is no
         longer near the edge of the screen.  However, wait a bit anyway, just
         to make sure the server drains its last motion event, so that the
         screen doesn't continue to scroll after we've reset the viewport.
       */
      XSync (si->dpy, False);
      usleep (250000);  /* 1/4 second */
      XSync (si->dpy, False);

      status = XF86VidModeSetViewPort (si->dpy, screen,
                                       ssi->blank_vp_x, ssi->blank_vp_y);

      if (!status)
        fprintf (stderr,
                 "%s: %d: unable to move vp from (%d,%d) back to (%d,%d)!\n",
                 blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y);
      else if (p->verbose_p)
        fprintf (stderr,
                 "%s: %d: vp moved to (%d,%d); moved it back to (%d,%d).\n",
                 blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y);
    }
#endif /* HAVE_XF86VMODE */
}
Exemple #8
0
static void
ZoomInit(void)
{
   int                 ev_base, er_base;

   zoom_can = -1;

   if (!XF86VidModeQueryExtension(disp, &ev_base, &er_base))
      return;

   XF86VidModeGetAllModeLines(disp, Dpy.screen,
			      &std_vid_modes_num, &std_vid_modes);

   if (std_vid_modes_num > 1)
      zoom_can = 1;
}
static gboolean _xf86vidmode_supported (void)
{
	static gboolean s_bXf86VidModeChecked = FALSE;
	if (s_bXf86VidModeChecked)
		return s_bUseXf86VidMode;

	int event_base, error_base;
	Display *dpy = gdk_x11_get_default_xdisplay ();
	if (! XF86VidModeQueryExtension (dpy, &event_base, &error_base))  // on regarde si le serveur X supporte l'extension.
	{
		cd_warning ("XF86VidMode extension not available.");
		s_bUseXf86VidMode = FALSE;
	}
	else
		s_bUseXf86VidMode = TRUE;
	s_bXf86VidModeChecked = TRUE;
	return s_bUseXf86VidMode;
}
Exemple #10
0
static void
xfree_lock_mode_switch (saver_info *si, Bool lock_p)
{
  static Bool any_mode_locked_p = False;
  saver_preferences *p = &si->prefs;
  int screen;
  int real_nscreens = ScreenCount (si->dpy);
  int event, error;
  Bool status;
  XErrorHandler old_handler;

  if (any_mode_locked_p == lock_p)
    return;
  if (!XF86VidModeQueryExtension (si->dpy, &event, &error))
    return;

  for (screen = 0; screen < real_nscreens; screen++)
    {
      XSync (si->dpy, False);
      old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
      error_handler_hit_p = False;
      status = XF86VidModeLockModeSwitch (si->dpy, screen, lock_p);
      XSync (si->dpy, False);
      XSetErrorHandler (old_handler);
      if (error_handler_hit_p) status = False;

      if (status)
        any_mode_locked_p = lock_p;

      if (!status && (p->verbose_p || !lock_p))
        /* Only print this when verbose, or when we locked but can't unlock.
           I tried printing this message whenever it comes up, but
           mode-locking always fails if DontZoom is set in XF86Config. */
        fprintf (stderr, "%s: %d: unable to %s mode switching!\n",
                 blurb(), screen, (lock_p ? "lock" : "unlock"));
      else if (p->verbose_p)
        fprintf (stderr, "%s: %d: %s mode switching.\n",
                 blurb(), screen, (lock_p ? "locked" : "unlocked"));
    }
}
Exemple #11
0
static GLboolean initDisplay(void)
{
    _glfwLibrary.X11.display = XOpenDisplay(NULL);
    if (!_glfwLibrary.X11.display)
    {
        _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: Failed to open X display");
        return GL_FALSE;
    }

    // As the API currently doesn't understand multiple display devices, we hard-code
    // this choice and hope for the best
    _glfwLibrary.X11.screen = DefaultScreen(_glfwLibrary.X11.display);
    _glfwLibrary.X11.root = RootWindow(_glfwLibrary.X11.display,
                                       _glfwLibrary.X11.screen);

    // Check for XF86VidMode extension
#ifdef _GLFW_HAS_XF86VIDMODE
    _glfwLibrary.X11.VidMode.available =
        XF86VidModeQueryExtension(_glfwLibrary.X11.display,
                                  &_glfwLibrary.X11.VidMode.eventBase,
                                  &_glfwLibrary.X11.VidMode.errorBase);
#else
    _glfwLibrary.X11.VidMode.available = GL_FALSE;
#endif /*_GLFW_HAS_XF86VIDMODE*/

    // Check for XRandR extension
#ifdef _GLFW_HAS_XRANDR
    _glfwLibrary.X11.RandR.available =
        XRRQueryExtension(_glfwLibrary.X11.display,
                          &_glfwLibrary.X11.RandR.eventBase,
                          &_glfwLibrary.X11.RandR.errorBase);

    if (_glfwLibrary.X11.RandR.available)
    {
        if (!XRRQueryVersion(_glfwLibrary.X11.display,
                             &_glfwLibrary.X11.RandR.majorVersion,
                             &_glfwLibrary.X11.RandR.minorVersion))
        {
            _glfwSetError(GLFW_PLATFORM_ERROR,
                          "X11/GLX: Failed to query RandR version");
            return GL_FALSE;
        }
    }
#else
    _glfwLibrary.X11.RandR.available = GL_FALSE;
#endif /*_GLFW_HAS_XRANDR*/

    // Check if GLX is supported on this display
    if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
    {
        _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX supported not found");
        return GL_FALSE;
    }

    if (!glXQueryVersion(_glfwLibrary.X11.display,
                         &_glfwLibrary.GLX.majorVersion,
                         &_glfwLibrary.GLX.minorVersion))
    {
        _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
                      "X11/GLX: Failed to query GLX version");
        return GL_FALSE;
    }

    // Check if Xkb is supported on this display
#if defined(_GLFW_HAS_XKB)
    _glfwLibrary.X11.Xkb.majorVersion = 1;
    _glfwLibrary.X11.Xkb.minorVersion = 0;
    _glfwLibrary.X11.Xkb.available =
        XkbQueryExtension(_glfwLibrary.X11.display,
                          &_glfwLibrary.X11.Xkb.majorOpcode,
                          &_glfwLibrary.X11.Xkb.eventBase,
                          &_glfwLibrary.X11.Xkb.errorBase,
                          &_glfwLibrary.X11.Xkb.majorVersion,
                          &_glfwLibrary.X11.Xkb.minorVersion);
#else
    _glfwLibrary.X11.Xkb.available = GL_FALSE;
#endif /* _GLFW_HAS_XKB */

    // Update the key code LUT
    // FIXME: We should listen to XkbMapNotify events to track changes to
    // the keyboard mapping.
    updateKeyCodeLUT();

    // Find or create selection property atom
    _glfwLibrary.X11.selection.property =
        XInternAtom(_glfwLibrary.X11.display, "GLFW_SELECTION", False);

    // Find or create clipboard atom
    _glfwLibrary.X11.selection.atom =
        XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False);

    // Find or create selection target atoms
    _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] =
        XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
    _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] =
        XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
    _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] =
        XA_STRING;

    _glfwLibrary.X11.selection.targets = XInternAtom(_glfwLibrary.X11.display,
                                         "TARGETS",
                                         False);

    return GL_TRUE;
}
Exemple #12
0
int
main(int argc, char *argv[])
{
    int i, ret;
    char *displayname = NULL;
    Display *dpy;
    float gam = -1., rgam = -1., ggam = -1., bgam = -1.;
    XF86VidModeGamma gamma;
    Bool quiet = False;
    int screen = -1;

    ProgramName = argv[0];
    for (i = 1; i < argc; i++) {
	char *arg = argv[i];

	if (arg[0] == '-') {
	    if (isabbreviation ("-display", arg, 1)) {
		if (++i >= argc) Syntax ("-display requires an argument");
		displayname = argv[i];
		continue;
	    } else if (isabbreviation ("-quiet", arg, 1)) {
		quiet = True;
		continue;
	    } else if (isabbreviation ("-version", arg, 1)) {
		puts(PACKAGE_STRING);
		exit(0);
	    } else if (isabbreviation ("-screen", arg, 1)) {
		if (++i >= argc) Syntax ("-screen requires an argument");
		screen = atoi(argv[i]);
		continue;
	    } else if (isabbreviation ("-gamma", arg, 2)) {
		if (++i >= argc) Syntax ("-gamma requires an argument");
		if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.))
		    Syntax ("-gamma cannot be used with -rgamma, -ggamma, or -bgamma");
		gam = (float)atof(argv[i]);
		if ((gam < GAMMA_MIN) || (gam > GAMMA_MAX)) {
		    fprintf(stderr,
			    "Gamma values must be between %6.3f and %6.3f\n",
			    GAMMA_MIN, GAMMA_MAX);
		    exit(1);
		}
		continue;
	    } else if (isabbreviation ("-rgamma", arg, 2)) {
		if (++i >= argc) Syntax ("-rgamma requires an argument");
		if (gam >= 0.) Syntax ("cannot set both -gamma and -rgamma");
		rgam = (float)atof(argv[i]);
		if ((rgam < GAMMA_MIN) || (rgam > GAMMA_MAX)) {
		    fprintf(stderr,
			    "Gamma values must be between %6.3f and %6.3f\n",
			    GAMMA_MIN, GAMMA_MAX);
		    exit(1);
		}
		continue;
	    } else if (isabbreviation ("-ggamma", arg, 2)) {
		if (++i >= argc) Syntax ("-ggamma requires an argument");
		if (gam >= 0.) Syntax ("cannot set both -gamma and -ggamma");
		ggam = (float)atof(argv[i]);
		if ((ggam < GAMMA_MIN) || (ggam > GAMMA_MAX)) {
		    fprintf(stderr,
			    "Gamma values must be between %6.3f and %6.3f\n",
			    GAMMA_MIN, GAMMA_MAX);
		    exit(1);
		}
		continue;
	    } else if (isabbreviation ("-bgamma", arg, 2)) {
		if (++i >= argc) Syntax ("-bgamma requires an argument");
		if (gam >= 0.) Syntax ("cannot set both -gamma and -bgamma");
		bgam = (float)atof(argv[i]);
		if ((bgam < GAMMA_MIN) || (bgam > GAMMA_MAX)) {
		    fprintf(stderr,
			    "Gamma values must be between %6.3f and %6.3f\n",
			    GAMMA_MIN, GAMMA_MAX);
		    exit(1);
		}
		continue;
	    } else {
		if (!isabbreviation ("-help", arg, 1))
		    fprintf (stderr, "%s: unrecognized argument %s\n\n",
			     ProgramName, arg);
		Syntax (NULL);
	    }
	} else {
	    fprintf (stderr, "%s: unrecognized argument %s\n\n",
		     ProgramName, arg);
	    Syntax (NULL);
	}
    }

    if ((dpy = XOpenDisplay(displayname)) == NULL) {
	fprintf (stderr, "%s:  unable to open display '%s'\n",
		 ProgramName, XDisplayName (displayname));
	exit(1);
    } else if (screen == -1)
	screen = DefaultScreen(dpy);

    if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
	fprintf(stderr, "Unable to query video extension version\n");
	exit(2);
    }

    if (!XF86VidModeQueryExtension(dpy, &EventBase, &ErrorBase)) {
	fprintf(stderr, "Unable to query video extension information\n");
	exit(2);
    }

    /* Fail if the extension version in the server is too old */
    if (MajorVersion < MINMAJOR || 
	(MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
	fprintf(stderr,
		"Xserver is running an old XFree86-VidModeExtension version"
		" (%d.%d)\n", MajorVersion, MinorVersion);
	fprintf(stderr, "Minimum required version is %d.%d\n",
		MINMAJOR, MINMINOR);
	exit(2);
    }

    if (!XF86VidModeGetGamma(dpy, screen, &gamma)) {
	fprintf(stderr, "Unable to query gamma correction\n");
	XCloseDisplay (dpy);
	exit (2);
    } else if (!quiet)
	fprintf(stderr, "-> Red %6.3f, Green %6.3f, Blue %6.3f\n", gamma.red,
		gamma.green, gamma.blue);

    ret = 0;
    if (gam >= 0.) {
	gamma.red = gam;
	gamma.green = gam;
	gamma.blue = gam;
	if (!XF86VidModeSetGamma(dpy, screen, &gamma)) {
	    fprintf(stderr, "Unable to set gamma correction\n");
	    ret = 2;
	} else {
	    if (!XF86VidModeGetGamma(dpy, screen, &gamma)) {
		fprintf(stderr, "Unable to query gamma correction\n");
		ret = 2;
	    } else if (!quiet)
		fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n",
		        gamma.red, gamma.green, gamma.blue);
	}
    } else if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.)) {
	if (rgam >= 0.) gamma.red = rgam;
	if (ggam >= 0.) gamma.green = ggam;
	if (bgam >= 0.) gamma.blue = bgam;
	if (!XF86VidModeSetGamma(dpy, screen, &gamma)) {
	    fprintf(stderr, "Unable to set gamma correction\n");
	    ret = 2;
	} else {
	    if (!XF86VidModeGetGamma(dpy, screen, &gamma)) {
		fprintf(stderr, "Unable to query gamma correction\n");
		ret = 2;
	    } else if (!quiet)
		fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n",
		        gamma.red, gamma.green, gamma.blue);
	}
    }

    XCloseDisplay (dpy);
    exit (ret);
}
Exemple #13
0
static int config(uint32_t width, uint32_t height,
                       uint32_t d_width, uint32_t d_height,
                       uint32_t flags, char *title, uint32_t format)
{

    int x_off, y_off;
    int wanted_width, wanted_height;

    static unsigned char *vo_dga_base;
    static int prev_width, prev_height;

#ifdef HAVE_DGA2
    // needed to change DGA video mode
    int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI =
        100000, mMaxY = 0, i, j = 0;
    int dga_modenum;
    XDGAMode *modeline;
    XDGADevice *dgadevice;
#else
#ifdef HAVE_XF86VM
    unsigned int vm_event, vm_error;
    unsigned int vm_ver, vm_rev;
    int i, j = 0, have_vm = 0;
    int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI =
        100000, mMaxY = 0, dga_modenum;
#endif
    int bank, ram;
#endif

    vo_dga_src_format = format;

    wanted_width = d_width;
    wanted_height = d_height;

    if (!wanted_height)
        wanted_height = height;
    if (!wanted_width)
        wanted_width = width;

    if (!vo_dbpp)
    {
        if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR)
        {
            vo_dga_src_mode = vd_ModeValid(format & 0xff);
        }
    } else
    {
        vo_dga_src_mode = vd_ModeValid(vo_dbpp);
    }
    vo_dga_hw_mode = SRC_MODE.vdm_hw_mode;

    if (!vo_dga_src_mode)
    {
        mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: unsupported video format!\n");
        return 1;
    }

    vo_dga_vp_width = vo_screenwidth;
    vo_dga_vp_height = vo_screenheight;

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: XServer res: %dx%d\n",
           vo_dga_vp_width, vo_dga_vp_height);

// choose a suitable mode ...

#ifdef HAVE_DGA2
// Code to change the video mode added by Michael Graffam
// [email protected]

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: vo_modelines=%p, vo_modecount=%d\n",
           vo_modelines, vo_modecount);

    if (vo_modelines == NULL)
    {
        mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: can't get modelines\n");
        return 1;
    }

    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: DGA 2.0 available :-) Can switch resolution AND depth!\n");
    for (i = 0; i < vo_modecount; i++)
    {
        if (vd_ModeEqual(vo_modelines[i].depth,
                         vo_modelines[i].bitsPerPixel,
                         vo_modelines[i].redMask,
                         vo_modelines[i].greenMask,
                         vo_modelines[i].blueMask, vo_dga_hw_mode))
        {

            mp_msg(MSGT_VO, MSGL_V, "maxy: %4d, depth: %2d, %4dx%4d, ",
                   vo_modelines[i].maxViewportY, vo_modelines[i].depth,
                   vo_modelines[i].imageWidth,
                   vo_modelines[i].imageHeight);
            if (check_res
                (i, wanted_width, wanted_height, vo_modelines[i].depth,
                 vo_modelines[i].viewportWidth,
                 vo_modelines[i].viewportHeight,
                 (unsigned) vo_modelines[i].verticalRefresh,
                 vo_modelines[i].maxViewportY, &mX, &mY, &mVBI, &mMaxY))
                j = i;
        }
    }
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Selected hardware mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d.\n",
           mX, mY, mVBI, HW_MODE.vdm_depth, HW_MODE.vdm_bitspp);
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Video parameters by codec: %3d x %3d, depth %2d, bitspp %2d.\n",
           width, height, SRC_MODE.vdm_depth, SRC_MODE.vdm_bitspp);
    vo_dga_vp_width = mX;
    vo_dga_vp_height = mY;

    if ((flags & VOFLAG_SWSCALE) || (flags & VOFLAG_FULLSCREEN))
    {                           /* -zoom or -fs */
        scale_dstW = (d_width + 7) & ~7;
        scale_dstH = d_height;
        scale_srcW = width;
        scale_srcH = height;
        aspect_save_screenres(mX, mY);
        aspect_save_orig(scale_srcW, scale_srcH);
        aspect_save_prescale(scale_dstW, scale_dstH);
        if (flags & VOFLAG_FULLSCREEN)       /* -fs */
            aspect(&scale_dstW, &scale_dstH, A_ZOOM);
        else if (flags & VOFLAG_SWSCALE)  /* -fs */
            aspect(&scale_dstW, &scale_dstH, A_NOZOOM);
        mp_msg(MSGT_VO, MSGL_INFO,
               "vo_dga: Aspect corrected size for SwScaler: %4d x %4d.\n",
               scale_dstW, scale_dstH);
        /* XXX this is a hack, but I'm lazy ;-) :: atmos */
        width = scale_dstW;
        height = scale_dstH;
    }

    vo_dga_width = vo_modelines[j].bytesPerScanline / HW_MODE.vdm_bytespp;
    dga_modenum = vo_modelines[j].num;
    modeline = vo_modelines + j;

#else

#ifdef HAVE_XF86VM

    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n");

    if (XF86VidModeQueryExtension(mDisplay, &vm_event, &vm_error))
    {
        XF86VidModeQueryVersion(mDisplay, &vm_ver, &vm_rev);
        mp_msg(MSGT_VO, MSGL_INFO,
               "vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev);
        have_vm = 1;
    } else
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: XF86VidMode Extension not available.\n");
    }

#define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) )

    if (have_vm)
    {
        int modecount;

        XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount,
                                   &vo_dga_vidmodes);

        if (vo_dga_vidmodes != NULL)
        {
            for (i = 0; i < modecount; i++)
            {
                if (check_res(i, wanted_width, wanted_height,
                              vo_dga_modes[vo_dga_hw_mode].vdm_depth,
                              vo_dga_vidmodes[i]->hdisplay,
                              vo_dga_vidmodes[i]->vdisplay,
                              GET_VREFRESH(vo_dga_vidmodes[i]->dotclock,
                                           vo_dga_vidmodes[i]->htotal,
                                           vo_dga_vidmodes[i]->vtotal),
                              0, &mX, &mY, &mVBI, &mMaxY))
                    j = i;
            }

            mp_msg(MSGT_VO, MSGL_INFO,
                   "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n",
                   mX, mY, mVBI,
                   vo_dga_modes[vo_dga_hw_mode].vdm_depth,
                   vo_dga_modes[vo_dga_hw_mode].vdm_bitspp, width, height);
        } else
        {
            mp_msg(MSGT_VO, MSGL_INFO,
                   "vo_dga: XF86VidMode returned no screens - using current resolution.\n");
        }
        dga_modenum = j;
        vo_dga_vp_width = mX;
        vo_dga_vp_height = mY;
    }

#else
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n");
    mp_msg(MSGT_VO, MSGL_INFO,
           "        Thus, resolution switching is NOT possible.\n");

#endif
#endif

    vo_dga_src_width = width;
    vo_dga_src_height = height;

    if (vo_dga_src_width > vo_dga_vp_width ||
        vo_dga_src_height > vo_dga_vp_height)
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: Sorry, video larger than viewport is not yet supported!\n");
        // ugly, do something nicer in the future ...
#ifndef HAVE_DGA2
#ifdef HAVE_XF86VM
        if (vo_dga_vidmodes)
        {
            XFree(vo_dga_vidmodes);
            vo_dga_vidmodes = NULL;
        }
#endif
#endif
        return 1;
    }

    if (vo_dga_vp_width == VO_DGA_INVALID_RES)
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: Something is wrong with your DGA. There doesn't seem to be a\n"
               "         single suitable mode!\n"
               "         Please file a bug report (see DOCS/HTML/en/bugreports.html)\n");
#ifndef HAVE_DGA2
#ifdef HAVE_XF86VM
        if (vo_dga_vidmodes)
        {
            XFree(vo_dga_vidmodes);
            vo_dga_vidmodes = NULL;
        }
#endif
#endif
        return 1;
    }
// now let's start the DGA thing 

    if (!vo_config_count || width != prev_width || height != prev_height)
    {
#ifdef HAVE_DGA2

        if (!XDGAOpenFramebuffer(mDisplay, mScreen))
        {
            mp_msg(MSGT_VO, MSGL_ERR,
                   "vo_dga: Framebuffer mapping failed!!!\n");
            return 1;
        }

        dgadevice = XDGASetMode(mDisplay, mScreen, dga_modenum);
        XDGASync(mDisplay, mScreen);

        vo_dga_base = dgadevice->data;
        XFree(dgadevice);

        XDGASetViewport(mDisplay, mScreen, 0, 0, XDGAFlipRetrace);

#else

#ifdef HAVE_XF86VM
        if (have_vm)
        {
            XF86VidModeLockModeSwitch(mDisplay, mScreen, 0);
            // Two calls are needed to switch modes on my ATI Rage 128. Why?
            // for riva128 one call is enough!
            XF86VidModeSwitchToMode(mDisplay, mScreen,
                                    vo_dga_vidmodes[dga_modenum]);
            XF86VidModeSwitchToMode(mDisplay, mScreen,
                                    vo_dga_vidmodes[dga_modenum]);
        }
#endif

        XF86DGAGetViewPortSize(mDisplay, mScreen,
                               &vo_dga_vp_width, &vo_dga_vp_height);

        XF86DGAGetVideo(mDisplay, mScreen,
                        (char **) &vo_dga_base, &vo_dga_width, &bank,
                        &ram);

        XF86DGADirectVideo(mDisplay, mScreen,
                           XF86DGADirectGraphics | XF86DGADirectMouse |
                           XF86DGADirectKeyb);

        XF86DGASetViewPort(mDisplay, mScreen, 0, 0);

#endif
    }
    // do some more checkings here ...

    mp_msg(MSGT_VO, MSGL_V,
           "vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %p, bpp: %d\n",
           vo_dga_width, vo_dga_vp_width, vo_dga_vp_height,
           HW_MODE.vdm_bytespp, vo_dga_base, HW_MODE.vdm_bitspp);

    x_off = (vo_dga_vp_width - vo_dga_src_width) >> 1;
    y_off = (vo_dga_vp_height - vo_dga_src_height) >> 1;

    vo_dga_bytes_per_line = vo_dga_src_width * HW_MODE.vdm_bytespp;
    vo_dga_lines = vo_dga_src_height;

    vo_dga_src_offset = 0;
    vo_dga_vp_offset =
        (y_off * vo_dga_width + x_off) * HW_MODE.vdm_bytespp;

    vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * HW_MODE.vdm_bytespp;   // todo

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n",
           vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line);


    XGrabKeyboard(mDisplay, DefaultRootWindow(mDisplay), True,
                  GrabModeAsync, GrabModeAsync, CurrentTime);
    if (vo_grabpointer)
        XGrabPointer(mDisplay, DefaultRootWindow(mDisplay), True,
                     ButtonPressMask, GrabModeAsync, GrabModeAsync,
                     None, None, CurrentTime);

    if (!vo_config_count || width != prev_width || height != prev_height)
    {
        init_video_buffers(vo_dga_base,
                           vo_dga_vp_height,
                           vo_dga_width * HW_MODE.vdm_bytespp,
#ifdef HAVE_DGA2
                           modeline->maxViewportY,
#else
                           vo_dga_vp_height,
#endif
                           vo_doublebuffering);
        prev_width = width;
        prev_height = height;
    }

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: Using %d frame buffer%s.\n",
           vo_dga_nr_video_buffers,
           vo_dga_nr_video_buffers == 1 ? "" : "s");

    vo_dga_is_running = 1;
    return 0;
}
Exemple #14
0
/*
 * Remembers the current visual settings, so that
 * we can change them and restore later...
 */
void fgPlatformRememberState( void )
{
    int event_base, error_base;

    /*
     * Remember the current pointer location before going fullscreen
     * for restoring it later:
     */
    Window junk_window;
    unsigned int junk_mask;

    XQueryPointer(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow,
            &junk_window, &junk_window,
            &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY,
            &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY, &junk_mask);

#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
    if(XRRQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
        XRRScreenConfiguration *xrr_config;
        XRRScreenSize *ssizes;
        Rotation rot;
        int ssize_count, curr;

        if((xrr_config = XRRGetScreenInfo(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow))) {
            ssizes = XRRConfigSizes(xrr_config, &ssize_count);
            curr = XRRConfigCurrentConfiguration(xrr_config, &rot);

            fgDisplay.pDisplay.prev_xsz = ssizes[curr].width;
            fgDisplay.pDisplay.prev_ysz = ssizes[curr].height;
            fgDisplay.pDisplay.prev_refresh = -1;

#       if ( RANDR_MAJOR > 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
            if(fgState.GameModeRefresh != -1) {
                fgDisplay.pDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config);
            }
#       endif

            fgDisplay.pDisplay.prev_size_valid = 1;

            XRRFreeScreenConfigInfo(xrr_config);
        }
    }
#   endif

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */
#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
    if(!XF86VidModeQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
        return;
    }

    /*
     * Remember the current ViewPort location of the screen to be able to
     * restore the ViewPort on LeaveGameMode():
     */
    if( !XF86VidModeGetViewPort(
             fgDisplay.pDisplay.Display,
             fgDisplay.pDisplay.Screen,
             &fgDisplay.pDisplay.DisplayViewPortX,
             &fgDisplay.pDisplay.DisplayViewPortY ) )
        fgWarning( "XF86VidModeGetViewPort failed" );


    /* Query the current display settings: */
    fgDisplay.pDisplay.DisplayModeValid =
      XF86VidModeGetModeLine(
        fgDisplay.pDisplay.Display,
        fgDisplay.pDisplay.Screen,
        &fgDisplay.pDisplay.DisplayModeClock,
        &fgDisplay.pDisplay.DisplayMode
    );

    if( !fgDisplay.pDisplay.DisplayModeValid )
        fgWarning( "XF86VidModeGetModeLine failed" );
#   endif

}
Exemple #15
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;
}
bool CIrrDeviceLinux::createWindow()
{
#ifdef _IRR_COMPILE_WITH_X11_
#ifdef _DEBUG
	os::Printer::log("Creating X window...", ELL_INFORMATION);
	XSetErrorHandler(IrrPrintXError);
#endif

	display = XOpenDisplay(0);
	if (!display)
	{
		os::Printer::log("Error: Need running XServer to start Irrlicht Engine.", ELL_ERROR);
		os::Printer::log("Could not open display", XDisplayName(0), ELL_ERROR);
		return false;
	}

	screennr = DefaultScreen(display);

	// query extension

	if (CreationParams.Fullscreen)
	{
		getVideoModeList();
		#if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
		s32 eventbase, errorbase;
		s32 bestMode = -1;
		#endif

		#ifdef _IRR_LINUX_X11_VIDMODE_
		if (XF86VidModeQueryExtension(display, &eventbase, &errorbase))
		{
			// enumerate video modes
			s32 modeCount;
			XF86VidModeModeInfo** modes;

			XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes);

			// find fitting mode
			for (s32 i = 0; i<modeCount; ++i)
			{
				if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height)
					bestMode = i;
				else if (bestMode!=-1 &&
						modes[i]->hdisplay >= Width &&
						modes[i]->vdisplay >= Height &&
						modes[i]->hdisplay < modes[bestMode]->hdisplay &&
						modes[i]->vdisplay < modes[bestMode]->vdisplay)
					bestMode = i;
			}
			if (bestMode != -1)
			{
				os::Printer::log("Starting fullscreen mode...", ELL_INFORMATION);
				XF86VidModeSwitchToMode(display, screennr, modes[bestMode]);
				XF86VidModeSetViewPort(display, screennr, 0, 0);
				UseXVidMode=true;
			}
			else
			{
				os::Printer::log("Could not find specified video mode, running windowed.", ELL_WARNING);
				CreationParams.Fullscreen = false;
			}

			XFree(modes);
		}
		else
		#endif
		#ifdef _IRR_LINUX_X11_RANDR_
		if (XRRQueryExtension(display, &eventbase, &errorbase))
		{
			s32 modeCount;
			XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display));
			XRRScreenSize *modes=XRRConfigSizes(config,&modeCount);
			for (s32 i = 0; i<modeCount; ++i)
			{
				if (bestMode==-1 && (u32)modes[i].width >= Width && (u32)modes[i].height >= Height)
					bestMode = i;
				else if (bestMode!=-1 &&
						(u32)modes[i].width >= Width &&
						(u32)modes[i].height >= Height &&
						modes[i].width < modes[bestMode].width &&
						modes[i].height < modes[bestMode].height)
					bestMode = i;
			}
			if (bestMode != -1)
			{
				XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime);
				UseXRandR=true;
			}
			XRRFreeScreenConfigInfo(config);
		}
		else
		#endif
		{
			os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht "
			"to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING);
			CreationParams.Fullscreen = false;
		}
	}

#ifdef _IRR_COMPILE_WITH_OPENGL_

	GLXFBConfig glxFBConfig;
	int major, minor;
	bool isAvailableGLX=false;
	if (CreationParams.DriverType==video::EDT_OPENGL)
	{
		isAvailableGLX=glXQueryExtension(display,&major,&minor);
		if (isAvailableGLX && glXQueryVersion(display, &major, &minor))
		{
			if (major==1 && minor>2)
			{
				const int MAX_SAMPLES = 16;
				// attribute array for the draw buffer
				int visualAttrBuffer[] =
				{
					GLX_RENDER_TYPE, GLX_RGBA_BIT,
					GLX_RED_SIZE, 4,
					GLX_GREEN_SIZE, 4,
					GLX_BLUE_SIZE, 4,
					GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0,
					GLX_DEPTH_SIZE, CreationParams.ZBufferBits,
					GLX_DOUBLEBUFFER, GL_TRUE,
					GLX_STENCIL_SIZE, 1,
					GLX_SAMPLE_BUFFERS_ARB, 1,
					GLX_SAMPLES_ARB, MAX_SAMPLES,
					None
				};

				GLXFBConfig *configList=0;
				int nitems=0;
				if (!CreationParams.AntiAlias)
				{
					visualAttrBuffer[17] = 0;
					visualAttrBuffer[19] = 0;
				}
				if (CreationParams.Stencilbuffer)
				{
					configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
					if (!configList && CreationParams.AntiAlias)
					{
						while (!configList && (visualAttrBuffer[19]>1))
						{
							visualAttrBuffer[19] >>= 1;
							configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
						}
						if (!configList)
						{
							visualAttrBuffer[17] = 0;
							visualAttrBuffer[19] = 0;
							configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
							if (configList)
							{
								os::Printer::log("No FSAA available.", ELL_WARNING);
								CreationParams.AntiAlias=false;
							}
							else
							{
								//reenable multisampling
								visualAttrBuffer[17] = 1;
								visualAttrBuffer[19] = MAX_SAMPLES;
							}
						}
					}
				}
				// Next try without stencil buffer
				if (!configList)
				{
					if (CreationParams.Stencilbuffer)
						os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
					CreationParams.Stencilbuffer = false;
					visualAttrBuffer[15]=0;

					configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
					if (!configList && CreationParams.AntiAlias)
					{
						while (!configList && (visualAttrBuffer[19]>1))
						{
							visualAttrBuffer[19] >>= 1;
							configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
						}
						if (!configList)
						{
							visualAttrBuffer[17] = 0;
							visualAttrBuffer[19] = 0;
							configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
							if (configList)
							{
								os::Printer::log("No FSAA available.", ELL_WARNING);
								CreationParams.AntiAlias=false;
							}
							else
							{
								//reenable multisampling
								visualAttrBuffer[17] = 1;
								visualAttrBuffer[19] = MAX_SAMPLES;
							}
						}
					}
				}
				// Next try without double buffer
				if (!configList)
				{
					os::Printer::log("No doublebuffering available.", ELL_WARNING);
					visualAttrBuffer[13] = GL_FALSE;
					configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
					if (!configList && CreationParams.AntiAlias)
					{
						while (!configList && (visualAttrBuffer[19]>1))
						{
							visualAttrBuffer[19] >>= 1;
							configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
						}
						if (!configList)
						{
							visualAttrBuffer[17] = 0;
							visualAttrBuffer[19] = 0;
							configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
							if (configList)
							{
								os::Printer::log("No FSAA available.", ELL_WARNING);
								CreationParams.AntiAlias=false;
							}
							else
							{
								//reenable multisampling
								visualAttrBuffer[17] = 1;
								visualAttrBuffer[19] = MAX_SAMPLES;
							}
						}
					}
				}
				if (configList)
				{
					glxFBConfig=configList[0];
					XFree(configList);
					UseGLXWindow=true;
					visual = glXGetVisualFromFBConfig(display,glxFBConfig);
				}
			}
Exemple #17
0
/*
 * Remembers the current visual settings, so that
 * we can change them and restore later...
 */
static void fghRememberState( void )
{
#if TARGET_HOST_POSIX_X11
    int event_base, error_base;

    /*
     * Remember the current pointer location before going fullscreen
     * for restoring it later:
     */
    Window junk_window;
    unsigned int junk_mask;

    XQueryPointer(fgDisplay.Display, fgDisplay.RootWindow,
            &junk_window, &junk_window,
            &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY,
            &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &junk_mask);

#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
    if(XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
        XRRScreenConfiguration *xrr_config;
        XRRScreenSize *ssizes;
        Rotation rot;
        int ssize_count, curr;

        if((xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) {
            ssizes = XRRConfigSizes(xrr_config, &ssize_count);
            curr = XRRConfigCurrentConfiguration(xrr_config, &rot);

            fgDisplay.prev_xsz = ssizes[curr].width;
            fgDisplay.prev_ysz = ssizes[curr].height;
            fgDisplay.prev_refresh = -1;

#       if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
            if(fgState.GameModeRefresh != -1) {
                fgDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config);
            }
#       endif

            fgDisplay.prev_size_valid = 1;

            XRRFreeScreenConfigInfo(xrr_config);
        }
    }
#   endif

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */
#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
    if(!XF86VidModeQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
        return;
    }

    /*
     * Remember the current ViewPort location of the screen to be able to
     * restore the ViewPort on LeaveGameMode():
     */
    if( !XF86VidModeGetViewPort(
             fgDisplay.Display,
             fgDisplay.Screen,
             &fgDisplay.DisplayViewPortX,
             &fgDisplay.DisplayViewPortY ) )
        fgWarning( "XF86VidModeGetViewPort failed" );


    /* Query the current display settings: */
    fgDisplay.DisplayModeValid =
      XF86VidModeGetModeLine(
        fgDisplay.Display,
        fgDisplay.Screen,
        &fgDisplay.DisplayModeClock,
        &fgDisplay.DisplayMode
    );

    if( !fgDisplay.DisplayModeValid )
        fgWarning( "XF86VidModeGetModeLine failed" );
#   endif

#elif TARGET_HOST_MS_WINDOWS

/*    DEVMODE devMode; */

    /* Grab the current desktop settings... */

/* hack to get around my stupid cross-gcc headers */
#define FREEGLUT_ENUM_CURRENT_SETTINGS -1

    EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS,
                         &fgDisplay.DisplayMode );

    /* Make sure we will be restoring all settings needed */
    fgDisplay.DisplayMode.dmFields |=
        DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

#endif
}
Exemple #18
0
static void xfvm_init(ALLEGRO_SYSTEM_XGLX *s)
{
    int event_base = 0;
    int error_base = 0;

    /* init xfvm info to defaults */
    s->xfvm_available = 0;
    s->xfvm_screen_count = 0;
    s->xfvm_screen = NULL;

    _al_mutex_lock(&s->lock);

    if (XF86VidModeQueryExtension(s->x11display, &event_base, &error_base)) {
        int minor_version = 0, major_version = 0;
        int status = XF86VidModeQueryVersion(s->x11display, &major_version, &minor_version);
        ALLEGRO_INFO("XF86VidMode version: %i.%i\n", major_version, minor_version);

        if (!status) {
            ALLEGRO_WARN("XF86VidMode not available, XF86VidModeQueryVersion failed.\n");
        }
        else {
            // I don't actually know what versions are required here, just going to assume any is ok for now.
            ALLEGRO_INFO("XF86VidMode %i.%i is active\n", major_version, minor_version);
            s->xfvm_available = 1;
        }
    }
    else {
        ALLEGRO_WARN("XF86VidMode extension is not available.\n");
    }

    if (s->xfvm_available) {
        int num_screens;
#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
        /* This is some fun stuff right here, if XRANDR is available, we can't use the xinerama screen count
         * and we really want the xrandr init in xglx_initialize to come last so it overrides xf86vm if available
         * and I really don't want to add more XRRQuery* or #ifdefs here.
         * I don't think XRandR can be disabled once its loaded,
         * so just seeing if its in the extension list should be fine. */
        /* interesting thing to note is if XRandR is available, that means we have TwinView,
         * and not multi-head Xinerama mode, as True Xinerama disables XRandR on my NVidia.
         * which means all of those xfvm_screen_count != xinerama_screen_count tests
         * only apply to TwinView. As this code below sets xfvm_screen_count to xinerama_screen_count
         * making all those compares fail, and make us fall back to the normal xfvm multi-head code. */
        /* second note, if FakeXinerama is disabled on TwinView setups, we will end up using
         * XRandR, as there is no other way to detect TwinView outside of libNVCtrl */

        int ext_op, ext_evt, ext_err;
        Bool ext_ret = XQueryExtension(s->x11display, "RANDR", &ext_op, &ext_evt, &ext_err);

        if (s->xinerama_available && ext_ret == False) {
            num_screens = s->xinerama_screen_count;
        }
        else
#endif
        {
            num_screens = ScreenCount(s->x11display);
        }

        ALLEGRO_DEBUG("XF86VidMode Got %d screens.\n", num_screens);
        s->xfvm_screen_count = num_screens;

        s->xfvm_screen = al_calloc(num_screens, sizeof(*s->xfvm_screen));
        if (!s->xfvm_screen) {
            ALLEGRO_ERROR("XF86VidMode: failed to allocate screen array.\n");
            s->xfvm_available = 0;
        }
        else {
            int i;
            for (i = 0; i < num_screens; i++) {
                ALLEGRO_DEBUG("XF86VidMode GetAllModeLines on screen %d.\n", i);
                if (!XF86VidModeGetAllModeLines(s->x11display, i, &(s->xfvm_screen[i].mode_count), &(s->xfvm_screen[i].modes))) {
                    /* XXX what to do here? */
                }
            }

            _al_xglx_mmon_interface.get_num_display_modes = xfvm_get_num_modes;
            _al_xglx_mmon_interface.get_display_mode      = xfvm_get_mode;
            _al_xglx_mmon_interface.set_mode              = xfvm_set_mode;
            _al_xglx_mmon_interface.store_mode            = xfvm_store_video_mode;
            _al_xglx_mmon_interface.restore_mode          = xfvm_restore_video_mode;
            _al_xglx_mmon_interface.get_display_offset    = xfvm_get_display_offset;
            _al_xglx_mmon_interface.get_num_adapters      = xfvm_get_num_adapters;
            _al_xglx_mmon_interface.get_monitor_info      = xfvm_get_monitor_info;
            _al_xglx_mmon_interface.get_default_adapter   = xfvm_get_default_adapter;
            _al_xglx_mmon_interface.get_xscreen           = xfvm_get_xscreen;
            _al_xglx_mmon_interface.post_setup            = xfvm_post_setup;
        }
    }

    _al_mutex_unlock(&s->lock);
}
Exemple #19
0
/*
 * Implementation
 */
Bool
VideoModeInitialize(void)
{
    Widget form;
    char dispstr[128], *ptr, *tmp;

    static char *names[] = {
	NULL,
	NULL,
	"hsyncstart",
	"hsyncend",
	"htotal",
	"vsyncstart",
	"vsyncend",
	"vtotal",
	"flags",
	"clock",
	"hsync",
	"vsync",
    };
    static char *vnames[] = {
	NULL,
	NULL,
	"v-hsyncstart",
	"v-hsyncend",
	"v-htotal",
	"v-vsyncstart",
	"v-vsyncend",
	"v-vtotal",
	"v-flags",
	"v-clock",
	"v-hsync",
	"v-vsync",
    };
    Widget rep;
    int i;

    if (!XF86VidModeQueryVersion(XtDisplay(toplevel),
				 &MajorVersion, &MinorVersion)) {
	fprintf(stderr, "Unable to query video extension version\n");
	return (False);
    }
    else if (!XF86VidModeQueryExtension(XtDisplay(toplevel),
					&EventBase, &ErrorBase)) {
	fprintf(stderr, "Unable to query video extension information\n");
	return (False);
    }
    else if (MajorVersion < MINMAJOR ||
	(MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
	fprintf(stderr,
		"Xserver is running an old XFree86-VidModeExtension version"
		" (%d.%d)\n", MajorVersion, MinorVersion);
	fprintf(stderr, "Minimum required version is %d.%d\n",
		MINMAJOR, MINMINOR);
	return (False);
    }
    else
	InitializeVidmodes();

    vtune = XtCreateWidget("vidtune", formWidgetClass,
			   work, NULL, 0);

    (void) XtVaCreateManagedWidget("vesaB", menuButtonWidgetClass, vtune,
				    XtNmenuName, "vesaP", NULL, 0);
    vesap = XtCreatePopupShell("vesaP", simpleMenuWidgetClass, vtune, NULL, 0);
    for (i = 0; i < sizeof(vesamodes) / sizeof(vesamodes[0]); i++) {
	rep = XtCreateManagedWidget(vesamodes[i].ident, smeBSBObjectClass,
				    vesap, NULL, 0);
	XtAddCallback(rep, XtNcallback, AddVesaModeCallback,
		      (XtPointer)&vesamodes[i]);
    }

    rep = XtCreateManagedWidget("prev", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)-1);
    mode = XtCreateManagedWidget("mode", menuButtonWidgetClass, vtune, NULL, 0);
    rep = XtCreateManagedWidget("next", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)1);

    screenp = XtCreatePopupShell("screenP", simpleMenuWidgetClass, vtune,
				 NULL, 0);

    XmuSnprintf(dispstr, sizeof(dispstr), "%s",
		DisplayString(XtDisplay(toplevel)));
    ptr = strrchr(dispstr, '.');
    tmp = strrchr(dispstr, ':');
    if (tmp != NULL && ptr != NULL && ptr > tmp)
	*ptr = '\0';

    for (i = 0; i < ScreenCount(XtDisplay(toplevel)); i++) {
	char name[128];

	XmuSnprintf(name, sizeof(name), "%s.%d", dispstr, i);
	rep = XtCreateManagedWidget(name, smeBSBObjectClass, screenp,
				    NULL, 0);
	XtAddCallback(rep, XtNcallback, ChangeScreenCallback,
	    (XtPointer)(long)i);
	if (i == 0) {
	    screenb = XtVaCreateManagedWidget("screenB", menuButtonWidgetClass,
					      vtune,
					      XtNmenuName, "screenP",
					      XtNlabel, name,
					      NULL, 0);
	}
    }
    XtRealizeWidget(screenp);

    rep = XtCreateManagedWidget("up", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)UP);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    rep = XtCreateManagedWidget("left", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)LEFT);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    XtCreateManagedWidget("monitor", simpleWidgetClass, vtune, NULL, 0);
    rep = XtCreateManagedWidget("right", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)RIGHT);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    rep = XtCreateManagedWidget("down", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)DOWN);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    rep = XtCreateManagedWidget("wider", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)WIDER);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    rep = XtCreateManagedWidget("narrower", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)NARROWER);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    rep = XtCreateManagedWidget("shorter", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)SHORTER);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
    rep = XtCreateManagedWidget("taller", repeaterWidgetClass,
				vtune, NULL, 0);
    XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
    XtAddCallback(rep, XtNcallback,
		  AdjustMonitorCallback, (XtPointer)TALLER);
    XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);

    automatic = XtCreateManagedWidget("auto", toggleWidgetClass, vtune, NULL, 0);
    XtAddCallback(automatic, XtNcallback, AutoCallback, NULL);
    apply = XtCreateManagedWidget("apply", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(apply, XtNcallback, ApplyCallback, NULL);
    restore = XtCreateManagedWidget("restore", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(restore, XtNcallback, RestoreCallback, NULL);
    rep = XtCreateManagedWidget("update", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(rep, XtNcallback, UpdateCallback, NULL);
    rep = XtCreateManagedWidget("test", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(rep, XtNcallback, TestCallback, NULL);

    form = XtCreateManagedWidget("form", formWidgetClass, vtune, NULL, 0);
    for (i = 2; i < VSYNC + 1; i++) {
	(void) XtCreateManagedWidget(names[i], labelWidgetClass,
					  form, NULL, 0);
	values[i] = XtCreateManagedWidget(vnames[i], labelWidgetClass,
					  form, NULL, 0);
    }

    add = XtCreateManagedWidget("add", commandWidgetClass, vtune, NULL, 0);
    XtAddCallback(add, XtNcallback, AddModeCallback, NULL);
    XtCreateManagedWidget("addto", labelWidgetClass, vtune, NULL, 0);
    monitorb = XtCreateManagedWidget("ident", menuButtonWidgetClass, vtune,
				     NULL, 0);
    XtCreateManagedWidget("as", labelWidgetClass, vtune, NULL, 0);
    text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, vtune,
				   XtNeditType, XawtextEdit, NULL, 0);

    XtRealizeWidget(vtune);

    return (True);
}
float PsychSetNominalFramerate(int screenNumber, float requestedHz)
{
  // Information returned by/sent to the XF86VidModeExtension:
  XF86VidModeModeLine mode_line;  // The mode line of the current video mode.
  int dot_clock;                  // The RAMDAC / TDMS pixel clock frequency.
  int rc;
  int event_base;

  // We start with a default vrefresh of zero, which means "couldn't query refresh from OS":
  float vrefresh = 0;

  if(screenNumber>=numDisplays)
    PsychErrorExitMsg(PsychError_internal, "screenNumber is out of range"); 

  if (!XF86VidModeSetClientVersion(displayCGIDs[screenNumber])) {
    // Failed to use VidMode-Extension. We just return a vrefresh of zero.
    return(0);
  }

  if (!XF86VidModeQueryExtension(displayCGIDs[screenNumber], &event_base, &x11_errorbase)) {
    // Failed to use VidMode-Extension. We just return a vrefresh of zero.
    return(0);
  }

  // Attach our error callback handler and reset error-state:
  x11_errorval = 0;
  x11_olderrorhandler = XSetErrorHandler(x11VidModeErrorHandler);

  // Step 1: Query current dotclock and modeline:
  if (!XF86VidModeGetModeLine(displayCGIDs[screenNumber], PsychGetXScreenIdForScreen(screenNumber), &dot_clock, &mode_line)) {
    // Restore default error handler:
    XSetErrorHandler(x11_olderrorhandler);

    PsychErrorExitMsg(PsychError_internal, "Failed to query video dotclock and modeline!"); 
  }

  // Step 2: Calculate updated modeline:
  if (requestedHz > 10) {
    // Step 2-a: Given current dot-clock and modeline and requested vrefresh, compute
    // modeline for closest possible match:
    requestedHz*=1000.0f;
    vrefresh = (((dot_clock * 1000) / mode_line.htotal) * 1000) / requestedHz;
    
    // Assign it to closest modeline setting:
    mode_line.vtotal = (int)(vrefresh + 0.5f);
  }
  else {
    // Step 2-b: Delta mode. requestedHz represents a direct integral offset
    // to add or subtract from current modeline setting:
    mode_line.vtotal+=(int) requestedHz;
  }

  // Step 3: Try to set new modeline:
  if (!XF86VidModeModModeLine(displayCGIDs[screenNumber], PsychGetXScreenIdForScreen(screenNumber), &mode_line)) {
    // Restore default error handler:
    XSetErrorHandler(x11_olderrorhandler);

    // Invalid modeline? Signal this:
    return(-1);
  }

  // We synchronize and wait for X-Request completion. If the modeline was invalid,
  // this will trigger an invocation of our errorhandler, which in turn will
  // set the x11_errorval to a non-zero value:
  XSync(displayCGIDs[screenNumber], FALSE);
  
  // Restore default error handler:
  XSetErrorHandler(x11_olderrorhandler);

  // Check for error:
  if (x11_errorval) {
    // Failed to set new mode! Must be invalid. We return -1 to signal this:
    return(-1);
  }

  // No error...

  // Step 4: Query new settings and return them:
  vrefresh = PsychGetNominalFramerate(screenNumber);

  // Done.
  return(vrefresh);
}
Exemple #21
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;
}
Exemple #22
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;
}
Exemple #23
0
// 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;
}
Exemple #24
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;
}