Пример #1
0
static void leave_dga_mode (void)
{
    XF86DGADirectVideo (display, screen, 0);
    XUngrabPointer (display, CurrentTime);
    XUngrabKeyboard (display, CurrentTime);
#ifdef USE_VIDMODE_EXTENSION
    if (vidmodeavail)
	XF86VidModeSwitchToMode (display, screen, allmodes[0]);
#endif
}
Пример #2
0
bool x11_enter_fullscreen(Display *dpy, unsigned width,
      unsigned height, XF86VidModeModeInfo *desktop_mode)
{
   XF86VidModeModeInfo mode;

   if (!get_video_mode(dpy, width, height, &mode, desktop_mode))
      return false;

   if (!XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), &mode))
      return false;

   XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0);
   return true;
}
Пример #3
0
void fxwt::destroy_graphics() {
	info("Shutting down GLX");
	glXDestroyContext(fxwt_x_dpy, glx_ctx);
	XDestroyWindow(fxwt_x_dpy, fxwt_x_win);

#ifdef USE_XF86VIDMODE
	if(fullscreen) {
		XF86VidModeSwitchToMode(fxwt_x_dpy, DefaultScreen(fxwt_x_dpy), &orig_mode);
		XF86VidModeSetViewPort(fxwt_x_dpy, DefaultScreen(fxwt_x_dpy), 0, 0);
	}
#endif	// USE_XF86VIDMODE
	
	XCloseDisplay(fxwt_x_dpy);
}
Пример #4
0
void DestroyWindowGL(GL_Window* window) {
	if(window->init.ctx ) {
		if( !glXMakeCurrent(window->init.dpy, None, NULL ) ) {
			fprintf( stderr, "Error releasing drawing context\n" );
		}
		glXDestroyContext( window->init.dpy, window->init.ctx );
	}

	if(window->init.isFullScreen) {
		XF86VidModeSwitchToMode( window->init.dpy,
														 window->init.screen, &window->init.deskMode );
		XF86VidModeSetViewPort( window->init.dpy, window->init.screen, 0, 0 );
	}
	XCloseDisplay( window->init.dpy );
}
Пример #5
0
void fv_switch_to_mode(int i)
{
    if ((!vmode_modes) || (i<0)) {
	ERROR_MSG("fv_switch_to_mode: no valid mode available.\n");
	return;
    }

    vmode_mode_selected = i;

    win_width = vmode_modes[i]->hdisplay;
    win_height = vmode_modes[i]->vdisplay;
    TRACE_MSG("fv_switch_to_mode: mode selected: %d (%d,%d).\n", 
	  vmode_mode_selected, win_width, win_height);
    XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[i]);
    XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0);
}
Пример #6
0
Файл: vidmode.c Проект: aosm/X11
static void
SelectCallback(Widget w, XtPointer call_data, XtPointer client_data)
{
    XF86VidModeModeInfo *info = (XF86VidModeModeInfo*)call_data;
    Arg args[1];
    Bool result;

    XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
    result = XF86VidModeSwitchToMode(XtDisplay(toplevel), vidtune->screen, info);
    XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
    if (!result)
	return;

    XtSetArg(args[0], XtNlabel, XtName(w));
    XtSetValues(mode, args, 1);
    UpdateCallback(w, call_data, client_data);
}
Пример #7
0
void OpenGLApp::exitAPI(){
	delete renderer;

    glXMakeCurrent(display, None, NULL);
    glXDestroyContext(display, glContext);

	if (fullscreen){
		if (XF86VidModeSwitchToMode(display, screen, dmodes[0])){
			XF86VidModeSetViewPort(display, screen, 0, 0);
		}
	}
    XFree(dmodes);
	XFreeCursor(display, blankCursor);

	XDestroyWindow(display, window);

	XSync(display, False);
}
Пример #8
0
bool			LinuxDisplayMode::doSet(int index, bool position)
{
  // ignore attempts to set video format to current format.
  // normally this only happens when restoring the default
  // format, when BzfDisplay deliberately forces the change.
  // that's useful for win32 where the OS knows the right
  // format and will ignore calls to switch the current
  // format.  however, irix isn't so clever and may cause
  // the display to flicker even when the format isn't
  // really changing.
  if (index == lastResolution || numResolutions <= 1)
    return true;

  // deactivate windows before resolution change.  if we don't do this
  // then the app will almost certainly crash in the OpenGL driver.
  XWindow::deactivateAll();

  // change resolution
  if (XF86VidModeSwitchToMode(display->getRep()->getDisplay(),
				display->getRep()->getScreen(),
				resolutions[index])) {
    if (position) {
      // kludge for accelerated GLX.  when we set the view port after
      // changing the resolution just before quiting, GLX does not
      // release the display to X server control.  or something like
      // that.  the effect is that you see the game window still on
      // the screen but maybe shifted around and you can't see any of
      // the other windows.  without this code, a workaround for the
      // problem is ctrl_alt_+ or ctrl_alt_- to force a resize.
      XF86VidModeSetViewPort(display->getRep()->getDisplay(),
				display->getRep()->getScreen(), 0, 0);
    }
    XSync(display->getRep()->getDisplay(), false);
    lastResolution = index;

    // reactivate previously deactivated window after change
    XWindow::reactivateAll();
    return true;
  }

  // reactivate previously deactivated window after change
  XWindow::reactivateAll();
  return false;
}
void GLWindow::Dispose()
{
    if (glctx)
    {
        if (!glXMakeCurrent(hDC, None, NULL))
            printf("Could not release drawing context.\n");
        glXDestroyContext(hDC, glctx);
    }
    /* switch back to original desktop resolution if we were in fs */
    if (FL_fullscreen)
    {
        XF86VidModeSwitchToMode(hDC, screen, &deskMode);
        XF86VidModeSetViewPort(hDC, screen, 0, 0);
    }
    if (hDC) XCloseDisplay(hDC);

    glctx = NULL;
    hDC   = NULL;
}
Пример #10
0
/* function to release/destroy our resources and restoring the old desktop */
GLvoid killGLWindow(GLvoid)
{
    if (GLWin.ctx)
    {
        if (!glXMakeCurrent(GLWin.dpy, None, NULL))
        {
            printf("Could not release drawing context.\n");
        }
        glXDestroyContext(GLWin.dpy, GLWin.ctx);
        GLWin.ctx = NULL;
    }
    /* switch back to original desktop resolution if we were in fs */
    if (GLWin.fs)
    {
        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
    }
    XCloseDisplay(GLWin.dpy);
}
Пример #11
0
void _glfwRestoreVideoMode(void)
{
    if (_glfwLibrary.X11.FS.modeChanged)
    {
        if (_glfwLibrary.X11.RandR.available)
        {
#if defined(_GLFW_HAS_XRANDR)
            XRRScreenConfiguration* sc;

            if (_glfwLibrary.X11.RandR.available)
            {
                sc = XRRGetScreenInfo(_glfwLibrary.X11.display,
                                      _glfwLibrary.X11.root);

                XRRSetScreenConfig(_glfwLibrary.X11.display,
                                   sc,
                                   _glfwLibrary.X11.root,
                                   _glfwLibrary.X11.FS.oldSizeID,
                                   _glfwLibrary.X11.FS.oldRotation,
                                   CurrentTime);

                XRRFreeScreenConfigInfo(sc);
            }
#endif /*_GLFW_HAS_XRANDR*/
        }
        else if (_glfwLibrary.X11.VidMode.available)
        {
#if defined(_GLFW_HAS_XF86VIDMODE)
            // Unlock mode switch
            XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
                                      _glfwLibrary.X11.screen,
                                      0);

            // Change the video mode back to the old mode
            XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
                                    _glfwLibrary.X11.screen,
                                    &_glfwLibrary.X11.FS.oldMode);
#endif /*_GLFW_HAS_XF86VIDMODE*/
        }

        _glfwLibrary.X11.FS.modeChanged = GL_FALSE;
    }
}
Пример #12
0
void vidmode_shutdown(void)
{
    unsigned int i;

    if (vm_is_enabled > 0 && vm_is_suspended == 0) {
        log_message(vidmode_log, "Disabling Vidmode");
        XF86VidModeSwitchToMode(x11ui_get_display_ptr(), screen, vm_modes[0]);
    }

    if (vm_available == 0) {
        return;
    }

    for (i = 0; i < vm_index; i++) {
        lib_free(vm_bestmodes[i].name);
    }

    lib_free(vm_bestmodes);
}
Пример #13
0
void GLWindow::free()
{
#ifdef _WIN32
  if(mhRC) {									
		if(!wglMakeCurrent(NULL, NULL)) {
		}
		if (!wglDeleteContext(mhRC))	{
		}
    mhRC = 0;	
	}

	if(mhDC && !ReleaseDC(mhWnd, mhDC)) {
		mhDC = 0;
	}

	if(mhWnd && !DestroyWindow(mhWnd)) {
		mhWnd = 0;
	}

	if(!UnregisterClass("OpenGL", mhInstance)) {
		mhInstance = 0;
	}
#else
  if(mCtx)    
  {
      if(!glXMakeCurrent(mDisplay, None, NULL))
      {                                        
          printf("Could not release drawing context.\n");
      }                                                  
      /* destroy the context */                          
      glXDestroyContext(mDisplay, mCtx);               
      mCtx = NULL;                                    
  }                                                      
  /* switch back to original desktop resolution if we were in fullscreen */
  if( mFullscreen )                                                         
  {                                                                        
      XF86VidModeSwitchToMode(mDisplay, mScreen, &mDeskMode);              
      XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0);                       
  }                                                                        
  XCloseDisplay(mDisplay);                                                  
#endif
}
Пример #14
0
void VID_Shutdown(void)
{
	if (!vidx11_display)
		return;

	VID_EnableJoystick(false);
	VID_SetMouse(false, false, false);
	VID_RestoreSystemGamma();

	// FIXME: glXDestroyContext here?
	if (vid_isvidmodefullscreen)
		XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, &init_vidmode);

	if(vidx11_gc)
		XFreeGC(vidx11_display, vidx11_gc);
	vidx11_gc = NULL;

	DestroyXImages();
	vidx11_shmevent = -1;
	vid.softpixels = NULL;

	if (vid.softdepthpixels)
		free(vid.softdepthpixels);
	vid.softdepthpixels = NULL;

	if (win)
		XDestroyWindow(vidx11_display, win);
	XCloseDisplay(vidx11_display);

	vid_hidden = true;
	vid_isfullscreen = false;
	vid_isnetwmfullscreen = false;
	vid_isvidmodefullscreen = false;
	vid_isoverrideredirect = false;
	vidx11_display = NULL;
	win = 0;
	ctx = NULL;

	GL_CloseLibrary();
	Key_ClearStates ();
}
Пример #15
0
void Sys_KillWindow(void) {
    if (g_Window.glctx) {
        if (!glXMakeCurrent(g_Window.display, None, NULL)) {
            fprintf(stderr, "Can't release drawing context\n");
        }
        glXDestroyContext(g_Window.display, g_Window.glctx);
        g_Window.glctx = NULL;
    }

    if (g_Window.fs) {
        XF86VidModeSwitchToMode(g_Window.display, g_Window.screen,
                                &g_Window.desktop_mode);
        XF86VidModeSetViewPort(g_Window.display, g_Window.screen, 0, 0);
    }

    if (g_Player != NULL) {
        free(g_Player);
    }

    XCloseDisplay(g_Window.display);
}
Пример #16
0
void fv_resetGeometry()
{
#ifdef HAVE_XF86_VMODE
    int oldMode, i;

    if (fullscreen) {
	XF86VidModeGetAllModeLines(Xdpy, Xscreen, &vmode_nb_modes, &vmode_modes);
	oldMode = 0;
	
	for (i=0; i < vmode_nb_modes; i++) {
	    if ((vmode_modes[i]->hdisplay == oldx) && (vmode_modes[i]->vdisplay==oldy)) {
		oldMode = i;
		break;
	    }
	}
	
	XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[oldMode]);
	XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0);
	XFlush(Xdpy);
    }
#endif /* HAVE_XF86_VMODE */
}
Пример #17
0
MWindow::~MWindow(void)
{
    if(display)
    {
        if(context)
        {
            glXMakeCurrent(display, None, NULL);
            glXDestroyContext(display, context);
            context = NULL;
        }

        if(m_fullscreen)
        {
			#ifndef __CYGWIN__
				XF86VidModeSwitchToMode(display, screen, &desktopMode);
				XF86VidModeSetViewPort(display, screen, 0, 0);
			#endif
        }

        XCloseDisplay(display);
    }
}
Пример #18
0
/*
** GLimp_Shutdown
**
** This routine does all OS specific shutdown procedures for the OpenGL
** subsystem.  Under OpenGL this means NULLing out the current DC and
** HGLRC, deleting the rendering context, and releasing the DC acquired
** for the window.  The state structure is also nulled out.
**
*/
void GLimp_Shutdown( void )
{
  if (!ctx || !dpy)
    return;
  IN_DeactivateMouse();
  // bk001206 - replaced with H2/Fakk2 solution
  // XAutoRepeatOn(dpy);
  // autorepeaton = qfalse; // bk001130 - from cvs1.17 (mkv)
  if (dpy)
  {
    if (ctx)
      qglXDestroyContext(dpy, ctx);
    if (win)
      XDestroyWindow(dpy, win);
#ifdef HAVE_XF86DGA
    if (vidmode_active)
      XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]);
    if (glConfig.deviceSupportsGamma)
    {
      XF86VidModeSetGamma(dpy, scrnum, &vidmode_InitialGamma);
    }
#endif /* HAVE_XF86DGA */
    // NOTE TTimo opening/closing the display should be necessary only once per run
    //   but it seems QGL_Shutdown gets called in a lot of occasion
    //   in some cases, this XCloseDisplay is known to raise some X errors
    //   ( https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=33 )
    XCloseDisplay(dpy);
  }
  vidmode_active = qfalse;
  dpy = NULL;
  win = 0;
  ctx = NULL;

  memset( &glConfig, 0, sizeof( glConfig ) );
  memset( &glState, 0, sizeof( glState ) );

  QGL_Shutdown();
}
Пример #19
0
void MFDisplay_DestroyDisplay()
{
	MFCALLSTACK;

	if((!gDisplay.windowed) && (originalVidMode != NULL) && xdisplay != NULL && numModes > 1)
	{
		XF86VidModeSwitchToMode(xdisplay, screen, originalVidMode);
	}

	MFRenderer_DestroyDisplay();

	if(sizeHints != NULL)
	{
		XFree(sizeHints);
		sizeHints = NULL;
	}

	if(window != 0)
	{
		XDestroyWindow(xdisplay, window);
		window = 0;
	}

	if(colorMap != 0)
	{
		XFreeColormap(xdisplay, colorMap);
		colorMap = 0L;
	}

	if(xdisplay != NULL)
	{
		XCloseDisplay(xdisplay);
		xdisplay = NULL;
	}

	FreeModes();
}
Пример #20
0
void S9xTextMode ()
{
	if (!is_graphics)
		return;

	if (ourdisp == NULL)
		return;


	XF86DGADirectVideo (ourdisp, ourscreen, 0);
#ifdef USE_XF86VIDMODE
	if (orig_mode != mod320x240) {
		XF86VidModeSwitchToMode (ourdisp, ourscreen, orig_mode);
	}
#endif
	XAutoRepeatOn (ourdisp);

	XUngrabKeyboard (ourdisp, CurrentTime);
	XUngrabPointer (ourdisp, CurrentTime);
	XSelectInput (ourdisp, inputwin, 0);
	XSync (ourdisp, True);

	is_graphics = FALSE;
}
Пример #21
0
static LONG X11DRV_XF86VM_SetCurrentMode(int mode)
{
  DWORD dwBpp = screen_bpp;
  /* only set modes from the original color depth */
  if (dwBpp != dd_modes[mode].dwBPP)
  {
      FIXME("Cannot change screen BPP from %d to %d\n", dwBpp, dd_modes[mode].dwBPP);
  }
  mode = mode % real_xf86vm_mode_count;

  wine_tsx11_lock();
  TRACE("Resizing X display to %dx%d\n", 
        real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay);
  XF86VidModeSwitchToMode(gdi_display, DefaultScreen(gdi_display), real_xf86vm_modes[mode]);
#if 0 /* it is said that SetViewPort causes problems with some X servers */
  XF86VidModeSetViewPort(gdi_display, DefaultScreen(gdi_display), 0, 0);
#else
  XWarpPointer(gdi_display, None, DefaultRootWindow(gdi_display), 0, 0, 0, 0, 0, 0);
#endif
  XSync(gdi_display, False);
  wine_tsx11_unlock();
  X11DRV_resize_desktop( real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay );
  return DISP_CHANGE_SUCCESSFUL;
}
void X11Device::shutdown() {
    X11Session *session = static_cast<X11Session *>(getSession());
    Log(EDebug, "Shutting down X11 device");
    Device::shutdown();
    setVisible(false);
    XDestroyWindow(session->m_display, m_window);
    XFree(m_visinfo);

    if (m_fullscreen) {
        /* Switch back to the previous screen resolution */
        XF86VidModeSwitchToMode(session->m_display, session->m_screen, &m_previousMode);
        XF86VidModeSetViewPort(session->m_display, session->m_screen, 0, 0);
    }

    /* In case auto_repeat was left on */
    XKeyboardState xkbs;
    XAutoRepeatOn(session->m_display);
    XGetKeyboardControl(session->m_display, &xkbs);

    if (!xkbs.global_auto_repeat)
        Log(EWarn, "Unable to restore the keyboard auto-repeat flag");

    m_initialized = false;
}
Пример #23
0
void VID_Shutdown(void)
{
    if (!ctx)
        return;

    uninstall_grabs();

    RestoreHWGamma();

#ifdef USE_VMODE
    if (x_disp)
    {
        glXDestroyContext(x_disp, ctx);
        if (x_win)
            XDestroyWindow(x_disp, x_win);
        if (vidmode_active)
            XF86VidModeSwitchToMode(x_disp, scrnum, vidmodes[0]);
        XCloseDisplay(x_disp);
        vidmode_active = false;
    }
#else
    glXDestroyContext(x_disp, ctx);
#endif
}
Пример #24
0
/*
** GLW_SetMode
*/
int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) {
#ifdef HAVE_GLES
	glConfig.vidWidth = 800;
	glConfig.vidHeight = 480;
//	glConfig.windowAspect = 800.0 / 480.0;

	long event_mask=X_MASK;
	dpy = XOpenDisplay(0);
	if(!dpy)
	{
		ri.Printf( PRINT_ALL, "couldn't open display\n");
		return qfalse;
	}
	
	scrnum = DefaultScreen(dpy);
	ri.Printf( PRINT_ALL, "using default screen %d\n", scrnum);
	ri.Printf( PRINT_ALL, "setting up EGL window\n");
 
	XSetWindowAttributes attr = { 0 };
	attr.event_mask = event_mask;
//	attr.colormap = colormap;
	attr.override_redirect = qtrue;
	win = XCreateWindow(dpy, RootWindow(dpy, scrnum),
		0, 0, glConfig.vidWidth, glConfig.vidHeight, 0, 
		CopyFromParent, InputOutput,
		CopyFromParent, CWEventMask, &attr);

	if(!win) {
		return qfalse;
	}

	Atom wmState = XInternAtom(dpy, "_NET_WM_STATE", False);
	Atom wmFullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
	XChangeProperty(dpy, win, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1);

	XMapRaised(dpy, win);

	g_EGLWindow = (NativeWindowType)win;
	#ifdef PANDORA
	g_EGLDisplay  =  eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
	#else
	g_EGLDisplay  =  eglGetDisplay((EGLNativeDisplayType)dpy);
	#endif

	if(g_EGLDisplay == EGL_NO_DISPLAY) {
		ri.Printf( PRINT_ALL, "error getting EGL display\n");
		return qfalse;
	}

	if(!eglInitialize(g_EGLDisplay, NULL, NULL)) {
		ri.Printf( PRINT_ALL, "error initializing EGL");
		return 0;
	}

	const EGLint attribs[] = {
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
		EGL_DEPTH_SIZE, 16,
		EGL_NONE, 0,
	};

	EGLint configs = 0;
	eglChooseConfig(g_EGLDisplay, attribs, &g_EGLConfig, 1, &configs);
	if(!configs) {
		static const EGLint eglAttrWinLowColor[] = {
			EGL_NONE
		};
		ri.Printf( PRINT_ALL, "falling back to lowest color config\n");
		eglChooseConfig(g_EGLDisplay, eglAttrWinLowColor, &g_EGLConfig, 1, &configs);
		if(!configs) {
			ri.Printf( PRINT_ALL, "no valid EGL configs found\n");
			return qfalse;
		}
	}
	
	#ifdef PANDORA
	g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig,
		NULL, NULL);
	#else
	g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig,
		g_EGLWindow, NULL);
	#endif
	if(g_EGLWindowSurface == EGL_NO_SURFACE) {
		ri.Printf( PRINT_ALL, "error creating window surface: 0x%X\n", (int)eglGetError());
		return qfalse;
	}

	EGLint ctxAttr[] = {
		EGL_CONTEXT_CLIENT_VERSION, 1,
		EGL_NONE
	};
	g_EGLContext = eglCreateContext(g_EGLDisplay, g_EGLConfig, EGL_NO_CONTEXT, ctxAttr);
	if(g_EGLContext == EGL_NO_CONTEXT) {
		ri.Printf( PRINT_ALL, "error creating context: 0x%X\n", (int)eglGetError());
		return qfalse;
	}
	
	eglMakeCurrent(g_EGLDisplay, g_EGLWindowSurface, g_EGLWindowSurface, g_EGLContext);
	{
	  EGLint width, height, color, depth, stencil;
	  eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_WIDTH, &width);
	  eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_HEIGHT, &height);
	  ri.Printf(PRINT_ALL, "Window size: %dx%d\n", width, height);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_BUFFER_SIZE, &color);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_DEPTH_SIZE, &depth);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_STENCIL_SIZE, &stencil);
/*	  glConfig.vidWidth = width;
	  glConfig.vidHeight = height;*/
	  glConfig.colorBits = color;
	  glConfig.depthBits = depth;
	  glConfig.stencilBits = stencil;
	}

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

#else
	int attrib[] = {
		GLX_RGBA,     // 0
		GLX_RED_SIZE, 4,  // 1, 2
		GLX_GREEN_SIZE, 4,  // 3, 4
		GLX_BLUE_SIZE, 4, // 5, 6
		GLX_DOUBLEBUFFER, // 7
		GLX_DEPTH_SIZE, 1,  // 8, 9
		GLX_STENCIL_SIZE, 1, // 10, 11
		None
	};
	// these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
	Window root;
	XVisualInfo *visinfo;
	XSetWindowAttributes attr;
	unsigned long mask;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int dga_MajorVersion, dga_MinorVersion;
	int actualWidth, actualHeight;
	int i;
	const char*   glstring; // bk001130 - from cvs1.17 (mkv)

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" );

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) {
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	if ( !( dpy = XOpenDisplay( NULL ) ) ) {
		fprintf( stderr, "Error couldn't open the X display\n" );
		return RSERR_INVALID_MODE;
	}

	scrnum = DefaultScreen( dpy );
	root = RootWindow( dpy, scrnum );

	actualWidth = glConfig.vidWidth;
	actualHeight = glConfig.vidHeight;

	// Get video mode list
	if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) {
		vidmode_ext = qfalse;
	} else
	{
		ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
				   vidmode_MajorVersion, vidmode_MinorVersion );
		vidmode_ext = qtrue;
	}

	// Check for DGA
	dga_MajorVersion = 0, dga_MinorVersion = 0;
	if ( in_dgamouse->value ) {
		if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) {
			// unable to query, probalby not supported
			ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
			ri.Cvar_Set( "in_dgamouse", "0" );
		} else
		{
			ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n",
					   dga_MajorVersion, dga_MinorVersion );
		}
	}

	if ( vidmode_ext ) {
		int best_fit, best_dist, dist, x, y;

		XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

		// Are we going fullscreen?  If so, let's change video mode
		if ( fullscreen ) {
			best_dist = 9999999;
			best_fit = -1;

			for ( i = 0; i < num_vidmodes; i++ )
			{
				if ( glConfig.vidWidth > vidmodes[i]->hdisplay ||
					 glConfig.vidHeight > vidmodes[i]->vdisplay ) {
					continue;
				}

				x = glConfig.vidWidth - vidmodes[i]->hdisplay;
				y = glConfig.vidHeight - vidmodes[i]->vdisplay;
				dist = ( x * x ) + ( y * y );
				if ( dist < best_dist ) {
					best_dist = dist;
					best_fit = i;
				}
			}

			if ( best_fit != -1 ) {
				actualWidth = vidmodes[best_fit]->hdisplay;
				actualHeight = vidmodes[best_fit]->vdisplay;

				// change to the mode
				XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] );
				vidmode_active = qtrue;

				// Move the viewport to top left
				XF86VidModeSetViewPort( dpy, scrnum, 0, 0 );

				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n",
						   actualWidth, actualHeight );

			} else
			{
				fullscreen = 0;
				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" );
			}
		} else
		{
			ri.Printf( PRINT_ALL, "XFree86-VidModeExtension:  Ignored on non-fullscreen/Voodoo\n" );
		}
	}


	if ( !r_colorbits->value ) {
		colorbits = 24;
	} else {
		colorbits = r_colorbits->value;
	}

	if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) {
		colorbits = 16;
	}

	if ( !r_depthbits->value ) {
		depthbits = 24;
	} else {
		depthbits = r_depthbits->value;
	}
	stencilbits = r_stencilbits->value;

	for ( i = 0; i < 16; i++ )
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ( ( i % 4 ) == 0 && i ) {
			// one pass, reduce
			switch ( i / 4 )
			{
			case 2:
				if ( colorbits == 24 ) {
					colorbits = 16;
				}
				break;
			case 1:
				if ( depthbits == 24 ) {
					depthbits = 16;
				} else if ( depthbits == 16 ) {
					depthbits = 8;
				}
			case 3:
				if ( stencilbits == 24 ) {
					stencilbits = 16;
				} else if ( stencilbits == 16 ) {
					stencilbits = 8;
				}
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ( ( i % 4 ) == 3 ) { // reduce colorbits
			if ( tcolorbits == 24 ) {
				tcolorbits = 16;
			}
		}

		if ( ( i % 4 ) == 2 ) { // reduce depthbits
			if ( tdepthbits == 24 ) {
				tdepthbits = 16;
			} else if ( tdepthbits == 16 ) {
				tdepthbits = 8;
			}
		}

		if ( ( i % 4 ) == 1 ) { // reduce stencilbits
			if ( tstencilbits == 24 ) {
				tstencilbits = 16;
			} else if ( tstencilbits == 16 ) {
				tstencilbits = 8;
			} else {
				tstencilbits = 0;
			}
		}

		if ( tcolorbits == 24 ) {
			attrib[ATTR_RED_IDX] = 8;
			attrib[ATTR_GREEN_IDX] = 8;
			attrib[ATTR_BLUE_IDX] = 8;
		} else
		{
			// must be 16 bit
			attrib[ATTR_RED_IDX] = 4;
			attrib[ATTR_GREEN_IDX] = 4;
			attrib[ATTR_BLUE_IDX] = 4;
		}

		attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth
		attrib[ATTR_STENCIL_IDX] = tstencilbits;

		visinfo = qglXChooseVisual( dpy, scrnum, attrib );
		if ( !visinfo ) {
			continue;
		}

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				   attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
				   attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] );

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if ( !visinfo ) {
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	/* window attributes */
	attr.background_pixel = BlackPixel( dpy, scrnum );
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
	attr.event_mask = X_MASK;
	if ( vidmode_active ) {
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
			   CWEventMask | CWOverrideRedirect;
		attr.override_redirect = True;
		attr.backing_store = NotUseful;
		attr.save_under = False;
	} else {
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
	}

	win = XCreateWindow( dpy, root, 0, 0,
						 actualWidth, actualHeight,
						 0, visinfo->depth, InputOutput,
						 visinfo->visual, mask, &attr );

	XStoreName( dpy, win, WINDOW_CLASS_NAME );

	XMapWindow( dpy, win );

	if ( vidmode_active ) {
		XMoveWindow( dpy, win, 0, 0 );
	}

	XFlush( dpy );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)
	ctx = qglXCreateContext( dpy, visinfo, NULL, True );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)

	qglXMakeCurrent( dpy, win, ctx );

	// bk001130 - from cvs1.17 (mkv)
	glstring = qglGetString( GL_RENDERER );
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	// bk010122 - new software token (Indirect)
	if ( !Q_stricmp( glstring, "Mesa X11" )
		 || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) {
		if ( !r_allowSoftwareGL->integer ) {
			ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
			ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)!   \n" );
			ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername );
			ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
			ri.Printf( PRINT_ALL, "       \"+set r_allowSoftwareGL 1\"\n" );
			ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
			ri.Printf( PRINT_ALL, "***********************************************************\n" );
			GLimp_Shutdown();
			return RSERR_INVALID_MODE;
		} else
		{
			ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
		}
	}
#endif	//HAVE_GLES
	return RSERR_OK;
}
Пример #25
0
GLWindow::GLWindow(const char * title, int width, int height, int bits, bool fullscreen, WNDPROC wndproc)
{
#ifdef _WIN32
	GLuint PixelFormat;			            // Holds The Results After Searching For A Match
	WNDCLASS wc;						            // Windows Class Structure
	DWORD dwExStyle;				            // Window Extended Style
	DWORD dwStyle;				              // Window Style
	RECT WindowRect;				            // Grabs Rectangle Upper Left / Lower Right Values
	WindowRect.left = (long) 0;			    // Set Left Value To 0
	WindowRect.right =(long) width;		  // Set Right Value To Requested Width
	WindowRect.top = (long) 0;				  // Set Top Value To 0
	WindowRect.bottom = (long) height;  // Set Bottom Value To Requested Height
  bool result = true;
  mInitialized = false;

  if(result) {
	  mhInstance = GetModuleHandle(NULL);				
	  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	
	  wc.lpfnWndProc = (WNDPROC) wndproc;
	  wc.cbClsExtra = 0;									
	  wc.cbWndExtra = 0;									
    wc.hInstance = mhInstance;					
	  wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);		
	  wc.hCursor = LoadCursor(NULL, IDC_ARROW);	
	  wc.hbrBackground = NULL;							
	  wc.lpszMenuName = NULL;							
	  wc.lpszClassName = "OpenGL";
  }
  
  if(result) {
	  if(!RegisterClass(&wc)) {
		  result = false;
	  }
  }

  if(result) {
	  DEVMODE dmScreenSettings;								
	  memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
	  dmScreenSettings.dmSize=sizeof(dmScreenSettings);
	  dmScreenSettings.dmPelsWidth	= width;
	  dmScreenSettings.dmPelsHeight	= height;
	  dmScreenSettings.dmBitsPerPel	= bits;
	  dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

    if(fullscreen) {
		  ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
		  dwExStyle = WS_EX_APPWINDOW;
		  dwStyle = WS_POPUP;
	  }	else {
		  dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
		  dwStyle = WS_OVERLAPPEDWINDOW;					
	  }

    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);	
  }

  if(result) {
    dwStyle |=	WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    mhWnd = CreateWindowEx(dwExStyle, "OpenGL", title, dwStyle, 0, 0, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top,	NULL,	NULL, mhInstance, NULL);

    if(!mhWnd) {
		  free();
		  result = false;		
	  }
  }
	
  if(result) {
    mhDC = GetDC(mhWnd);
	  if(!mhDC)	{
		  free();
		  result = false;	
	  }
  }

  static PIXELFORMATDESCRIPTOR pfd =	
	{
		sizeof(PIXELFORMATDESCRIPTOR),		
		1,										
		PFD_DRAW_TO_WINDOW |	
		PFD_SUPPORT_OPENGL |	
		PFD_DOUBLEBUFFER,			
		PFD_TYPE_RGBA,				
		bits,									
		0, 0, 0, 0, 0, 0,			
		0,										
		0,										
		0,										
		0, 0, 0, 0,						
		16,										
		0,										
		0,										
		PFD_MAIN_PLANE,				
		0,										
		0, 0, 0								
	};

  if(result) {
    PixelFormat = ChoosePixelFormat(mhDC, &pfd);
	  if(!PixelFormat) {
		  free();
		  result = false;	
	  }
  }

  if(result) {
	  if(!SetPixelFormat(mhDC, PixelFormat, &pfd))	{
		  free();
		  result = false;	
	  }
  }

  if(result) {
    mhRC = wglCreateContext(mhDC);
	  if(!mhRC) {
		  free();
		  result = false;	
	  }
  }

  if(result) {
	  if(!wglMakeCurrent(mhDC, mhRC))	{
		  free();
		  result = false;							
	  }
  }

  if(result) {
    ShowCursor(FALSE);
	  ShowWindow(mhWnd, SW_SHOW);				
	  SetForegroundWindow(mhWnd);			
	  SetFocus(mhWnd);									
  }

  if(result) {
	  if(!initOpenGL()) {
		  free();
		  result = false;	
	  }
  }

  mInitialized = result;
#else            
  XVisualInfo *vi;
  Colormap cmap;  
  int i, dpyWidth, dpyHeight;
  int glxMajor, glxMinor, vmMajor, vmMinor;
  XF86VidModeModeInfo **modes;             
  int modeNum, bestMode;                   
  Atom wmDelete;                           
  Window winDummy;                         
  unsigned int borderDummy;                

  mFullscreen = fullscreen;

  /* set best mode to current */
  bestMode = 0;                 
  /* get a connection */        
  mDisplay = XOpenDisplay(0);    
  mScreen = DefaultScreen(mDisplay);
  XF86VidModeQueryVersion(mDisplay, &vmMajor, &vmMinor);
  XF86VidModeGetAllModeLines(mDisplay, mScreen, &modeNum, &modes);       
  /* save desktop-resolution before switching modes */                 
  mDeskMode = *modes[0];
  /* look for mode with requested resolution */                        
  for (i = 0; i < modeNum; i++)                                        
  {                                                                    
      if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
          bestMode = i;                                                   
  }                                                                       
  /* get an appropriate visual */                                         
  vi = glXChooseVisual(mDisplay, mScreen, attrListDbl);                     
  if (vi == NULL)                                                         
  {                                                                       
      vi = glXChooseVisual(mDisplay, mScreen, attrListSgl);                 
      mDoubleBuffered = False;                                             
  }                                                                                   
  else                                                                                
  {                                                                                   
      mDoubleBuffered = True;                                                                                        
  }                                                                                   
  glXQueryVersion(mDisplay, &glxMajor, &glxMinor);                                     
  Debug::Log("GLX-Version %d.%d\n", glxMajor, glxMinor); 
  /* create a GLX context */                                                          
  mCtx = glXCreateContext(mDisplay, vi, 0, GL_TRUE);                                
  /* create a color map */                                                            
  cmap = XCreateColormap(mDisplay, RootWindow(mDisplay, vi->screen),                    
      vi->visual, AllocNone);                                                         
  mWinAttr.colormap = cmap;                                                            
  mWinAttr.border_pixel = 0;                                                           

  if(fullscreen)
  {              
      /* switch to fullscreen */
      XF86VidModeSwitchToMode(mDisplay, mScreen, modes[bestMode]);
      XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0);            
      dpyWidth = modes[bestMode]->hdisplay;                     
      dpyHeight = modes[bestMode]->vdisplay;                          
      XFree(modes);                                             

      /* set window attributes */
      mWinAttr.override_redirect = True;
      mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
          StructureNotifyMask;                                            
      mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen),    
          0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
          CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,   
          &mWinAttr);                                                       
      XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, 0, 0);               
              XMapRaised(mDisplay, mWindow);                                 
      XGrabKeyboard(mDisplay, mWindow, True, GrabModeAsync,                  
          GrabModeAsync, CurrentTime);                                     
      XGrabPointer(mDisplay, mWindow, True, ButtonPressMask,                 
          GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime);        
  }                                                                        
  else                                                                     
  {                                                                        
      /* create a window in window mode*/                                  
      mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | 
          StructureNotifyMask;                                             
      mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen),        
          0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,      
          CWBorderPixel | CWColormap | CWEventMask, &mWinAttr);             
      /* only set window title and handle wm_delete_events if in windowed mode */
      wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", True);                 
      XSetWMProtocols(mDisplay, mWindow, &wmDelete, 1);                            
      XSetStandardProperties(mDisplay, mWindow, title,                             
          title, None, NULL, 0, NULL);                                           
      XMapRaised(mDisplay, mWindow);                                               
  }                                                                              
  /* connect the glx-context to the window */                                    
  glXMakeCurrent(mDisplay, mWindow, mCtx);                                                                                
  initOpenGL();

  mInitialized = true;    
#endif
}
Пример #26
0
Error ContextGL_X11::initialize() {

	
	GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL;
	
//	const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
	
	glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
	
	ERR_FAIL_COND_V( !glXCreateContextAttribsARB, ERR_UNCONFIGURED );


	static int visual_attribs[] = {
	    GLX_RENDER_TYPE, GLX_RGBA_BIT,
	    GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
	    GLX_DOUBLEBUFFER, true,
	    GLX_RED_SIZE, 1,
	    GLX_GREEN_SIZE, 1,
	    GLX_BLUE_SIZE, 1,
	    GLX_DEPTH_SIZE, 24,
	    None 
	};

	int fbcount;
	GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
	ERR_FAIL_COND_V(!fbc,ERR_UNCONFIGURED);
	
	XVisualInfo *vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);

	XSetWindowAttributes swa;

	swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
	swa.border_pixel = 0;
	swa.event_mask = StructureNotifyMask;

	/*
	char* windowid = getenv("GODOT_WINDOWID");
	if (windowid) {

		//freopen("/home/punto/stdout", "w", stdout);
		//reopen("/home/punto/stderr", "w", stderr);
		x11_window = atol(windowid);
	} else {
	*/

    x11MotivHints.flags         = 2;
    x11MotivHints.decorations   = 0;
    xiaNewProperty              = XInternAtom( x11_display,"_MOTIF_WM_HINTS", True );
    vidModeBest                 = 0;
    vidModeCount                = 0;
    windowWidth                 = 1024;
    windowHeight                = 768;
    dpyWidth                    = 0;
    dpyHeight                   = 0;
    screenBackup                = vi->screen;

    XF86VidModeGetAllModeLines( x11_display, vi->screen, &vidModeCount, &vidModes );

    printf("Debug: vidModeCount=%d\n", vidModeCount );

    desktopMode = *vidModes[ 0 ];

    for ( int i = 0; i < vidModeCount; i++ ){

        if (( vidModes[i]->hdisplay == windowWidth) && ( vidModes[i]->vdisplay == windowHeight ))
                    vidModeBest = i;

    }

    printf("vidModeBest=%d\n",vidModeBest);

    glXQueryVersion(    x11_display, &glxMajor, &glxMinor                 );
    printf(             "Debug: GLX-Version %d.%d\n", glxMajor, glxMinor  );

    context                 = glXCreateContext( x11_display, vi, 0, GL_TRUE                                                 );
    cmap                    = XCreateColormap(  x11_display, RootWindow( x11_display, vi->screen ), vi->visual, AllocNone   );
    winAttr.colormap        = cmap;
    winAttr.border_pixel    = 0;

    XChangeProperty(            x11_display, RootWindow( x11_display, vi->screen ), xiaNewProperty, xiaNewProperty, 32, PropModeReplace, ( unsigned char * ) &x11MotivHints, 5        );
    XF86VidModeSwitchToMode(    x11_display, vi->screen, vidModes[ vidModeBest ]                                                                                                        );
    XF86VidModeSetViewPort(     x11_display, vi->screen, 0, 0                                                                                                                         );
    XMoveResizeWindow(          x11_display, RootWindow( x11_display, vi->screen ), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height   );
    XMapRaised(                 x11_display, RootWindow( x11_display, vi->screen )                                                                                                    );

    dpyWidth    = vidModes[vidModeBest]->hdisplay;
    dpyHeight   = vidModes[vidModeBest]->vdisplay;

    XFree(vidModes);

    winAttr.override_redirect   = True;
    winAttr.event_mask          = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;

    x11_window = XCreateWindow( x11_display,
                                RootWindow( x11_display, vi->screen ),
                                0, 0,
                                dpyWidth, dpyHeight,
                                0,
                                vi->depth,
                                InputOutput,
                                vi->visual,
                                CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &winAttr );
    XWarpPointer(               x11_display,
                                None,
                                x11_window,
                                0, 0, 0, 0, 0, 0                                                        );
    XMapRaised(                 x11_display, x11_window                                                 );
    XGrabKeyboard(              x11_display, x11_window,
                                True,
                                GrabModeAsync, GrabModeAsync,
                                CurrentTime                                                             );
    XGrabPointer(               x11_display, x11_window,
                                True, ButtonPressMask,
                                GrabModeAsync, GrabModeAsync,
                                x11_window,
                                None,
                                CurrentTime                                                             );

        //x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
		ERR_FAIL_COND_V(!x11_window,ERR_UNCONFIGURED);
		XMapWindow(x11_display, x11_window);
		while(true) {
			// wait for mapnotify (window created)
			XEvent e;
			XNextEvent(x11_display, &e);
			if (e.type == MapNotify)
				break;
		}
		//};

	if (!OS::get_singleton()->get_video_mode().resizable) {
		XSizeHints *xsh;
		xsh = XAllocSizeHints();
		xsh->flags = PMinSize | PMaxSize;
		xsh->min_width = OS::get_singleton()->get_video_mode().width;
		xsh->max_width = OS::get_singleton()->get_video_mode().width;
		xsh->min_height = OS::get_singleton()->get_video_mode().height;
		xsh->max_height = OS::get_singleton()->get_video_mode().height;
		XSetWMNormalHints(x11_display, x11_window, xsh);
	}


	if (!opengl_3_context) {
		//oldstyle context:
		p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE);
	} else {
		static int context_attribs[] = {
			GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
			GLX_CONTEXT_MINOR_VERSION_ARB, 0,
			None
		};
	
		p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs);
		ERR_FAIL_COND_V(!p->glx_context,ERR_UNCONFIGURED);
	}

	glXMakeCurrent(x11_display, x11_window, p->glx_context);

	/*
	glWrapperInit(wrapper_get_proc_address);
	glFlush();
	
	glXSwapBuffers(x11_display,x11_window);
*/
	//glXMakeCurrent(x11_display, None, NULL);

	return OK;
}
Пример #27
0
void _glfwSetVideoModeMODE(int mode, int rate)
{
    if (_glfwLibrary.X11.RandR.available)
    {
#if defined(_GLFW_HAS_XRANDR)
        XRRScreenConfiguration* sc;
        Window root;

        root = _glfwLibrary.X11.root;
        sc   = XRRGetScreenInfo(_glfwLibrary.X11.display, root);

        // Remember old size and flag that we have changed the mode
        if (!_glfwLibrary.X11.FS.modeChanged)
        {
            _glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation);
            _glfwLibrary.X11.FS.oldWidth  = DisplayWidth(_glfwLibrary.X11.display,
                                                         _glfwLibrary.X11.screen);
            _glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display,
                                                          _glfwLibrary.X11.screen);

            _glfwLibrary.X11.FS.modeChanged = GL_TRUE;
        }

        if (rate > 0)
        {
            // Set desired configuration
            XRRSetScreenConfigAndRate(_glfwLibrary.X11.display,
                                      sc,
                                      root,
                                      mode,
                                      RR_Rotate_0,
                                      (short) rate,
                                      CurrentTime);
        }
        else
        {
            // Set desired configuration
            XRRSetScreenConfig(_glfwLibrary.X11.display,
                               sc,
                               root,
                               mode,
                               RR_Rotate_0,
                               CurrentTime);
        }

        XRRFreeScreenConfigInfo(sc);
#endif /*_GLFW_HAS_XRANDR*/
    }
    else if (_glfwLibrary.X11.VidMode.available)
    {
#if defined(_GLFW_HAS_XF86VIDMODE)
        XF86VidModeModeInfo **modelist;
        int modecount;

        // Get a list of all available display modes
        XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
                                   _glfwLibrary.X11.screen,
                                   &modecount, &modelist);

        // Unlock mode switch if necessary
        if (_glfwLibrary.X11.FS.modeChanged)
        {
            XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
                                      _glfwLibrary.X11.screen,
                                      0);
        }

        // Change the video mode to the desired mode
        XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
                                _glfwLibrary.X11.screen,
                                modelist[mode]);

        // Set viewport to upper left corner (where our window will be)
        XF86VidModeSetViewPort(_glfwLibrary.X11.display,
                               _glfwLibrary.X11.screen,
                               0, 0);

        // Lock mode switch
        XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
                                  _glfwLibrary.X11.screen,
                                  1);

        // Remember old mode and flag that we have changed the mode
        if (!_glfwLibrary.X11.FS.modeChanged)
        {
            _glfwLibrary.X11.FS.oldMode = *modelist[0];
            _glfwLibrary.X11.FS.modeChanged = GL_TRUE;
        }

        XFree(modelist);
#endif /*_GLFW_HAS_XF86VIDMODE*/
    }
}
Пример #28
0
/*
===============
GLX_Init
===============
*/
int GLX_Init(glimpParms_t a)
{
    int attrib[] =
    {
        GLX_RGBA,				// 0
        GLX_RED_SIZE, 8,		// 1, 2
        GLX_GREEN_SIZE, 8,		// 3, 4
        GLX_BLUE_SIZE, 8,		// 5, 6
        GLX_DOUBLEBUFFER,		// 7
        GLX_DEPTH_SIZE, 24,		// 8, 9
        GLX_STENCIL_SIZE, 8,	// 10, 11
        GLX_ALPHA_SIZE, 8, // 12, 13
        None
    };
    // these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
#define ATTR_ALPHA_IDX 13
    Window root;
    XVisualInfo *visinfo;
    XSetWindowAttributes attr;
    XSizeHints sizehints;
    unsigned long mask;
    int colorbits, depthbits, stencilbits;
    int tcolorbits, tdepthbits, tstencilbits;
    int actualWidth, actualHeight;
    int i;
    const char *glstring;

    if ( !GLimp_OpenDisplay() )
    {
        return false;
    }

    common->Printf( "Initializing OpenGL display\n" );

    root = RootWindow( dpy, scrnum );

    actualWidth = glConfig.vidWidth;
    actualHeight = glConfig.vidHeight;

    // Get video mode list
    if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) )
    {
        vidmode_ext = false;
        common->Printf("XFree86-VidModeExtension not available\n");
    }
    else
    {
        vidmode_ext = true;
        common->Printf("Using XFree86-VidModeExtension Version %d.%d\n",
                       vidmode_MajorVersion, vidmode_MinorVersion);
    }

    GLX_TestDGA();

    if ( vidmode_ext )
    {
        int best_fit, best_dist, dist, x, y;

        XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

        // Are we going fullscreen?  If so, let's change video mode
        if ( a.fullScreen )
        {
            best_dist = 9999999;
            best_fit = -1;

            for (i = 0; i < num_vidmodes; i++)
            {
                if (a.width > vidmodes[i]->hdisplay ||
                        a.height > vidmodes[i]->vdisplay)
                    continue;

                x = a.width - vidmodes[i]->hdisplay;
                y = a.height - vidmodes[i]->vdisplay;
                dist = (x * x) + (y * y);
                if (dist < best_dist)
                {
                    best_dist = dist;
                    best_fit = i;
                }
            }

            if (best_fit != -1)
            {
                actualWidth = vidmodes[best_fit]->hdisplay;
                actualHeight = vidmodes[best_fit]->vdisplay;

                // change to the mode
                XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
                vidmode_active = true;

                // Move the viewport to top left
                // FIXME: center?
                XF86VidModeSetViewPort(dpy, scrnum, 0, 0);

                common->Printf( "Free86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight );

            }
            else
            {
                a.fullScreen = false;
                common->Printf( "Free86-VidModeExtension: No acceptable modes found\n" );
            }
        }
        else
        {
            common->Printf( "XFree86-VidModeExtension: not fullscreen, ignored\n" );
        }
    }
    // color, depth and stencil
    colorbits = 24;
    depthbits = 24;
    stencilbits = 8;

    for (i = 0; i < 16; i++)
    {
        // 0 - default
        // 1 - minus colorbits
        // 2 - minus depthbits
        // 3 - minus stencil
        if ((i % 4) == 0 && i)
        {
            // one pass, reduce
            switch (i / 4)
            {
            case 2:
                if (colorbits == 24)
                    colorbits = 16;
                break;
            case 1:
                if (depthbits == 24)
                    depthbits = 16;
                else if (depthbits == 16)
                    depthbits = 8;
            case 3:
                if (stencilbits == 24)
                    stencilbits = 16;
                else if (stencilbits == 16)
                    stencilbits = 8;
            }
        }

        tcolorbits = colorbits;
        tdepthbits = depthbits;
        tstencilbits = stencilbits;

        if ((i % 4) == 3)  		// reduce colorbits
        {
            if (tcolorbits == 24)
                tcolorbits = 16;
        }

        if ((i % 4) == 2)  		// reduce depthbits
        {
            if (tdepthbits == 24)
                tdepthbits = 16;
            else if (tdepthbits == 16)
                tdepthbits = 8;
        }

        if ((i % 4) == 1)  		// reduce stencilbits
        {
            if (tstencilbits == 24)
                tstencilbits = 16;
            else if (tstencilbits == 16)
                tstencilbits = 8;
            else
                tstencilbits = 0;
        }

        if (tcolorbits == 24)
        {
            attrib[ATTR_RED_IDX] = 8;
            attrib[ATTR_GREEN_IDX] = 8;
            attrib[ATTR_BLUE_IDX] = 8;
        }
        else
        {
            // must be 16 bit
            attrib[ATTR_RED_IDX] = 4;
            attrib[ATTR_GREEN_IDX] = 4;
            attrib[ATTR_BLUE_IDX] = 4;
        }

        attrib[ATTR_DEPTH_IDX] = tdepthbits;	// default to 24 depth
        attrib[ATTR_STENCIL_IDX] = tstencilbits;

        visinfo = qglXChooseVisual(dpy, scrnum, attrib);
        if (!visinfo)
        {
            continue;
        }

        common->Printf( "Using %d/%d/%d Color bits, %d Alpha bits, %d depth, %d stencil display.\n",
                        attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX],
                        attrib[ATTR_BLUE_IDX], attrib[ATTR_ALPHA_IDX],
                        attrib[ATTR_DEPTH_IDX],
                        attrib[ATTR_STENCIL_IDX]);

        glConfig.colorBits = tcolorbits;
        glConfig.depthBits = tdepthbits;
        glConfig.stencilBits = tstencilbits;
        break;
    }

    if (!visinfo)
    {
        common->Printf("Couldn't get a visual\n");
        return false;
    }
    // window attributes
    attr.background_pixel = BlackPixel(dpy, scrnum);
    attr.border_pixel = 0;
    attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
    attr.event_mask = X_MASK;
    if (vidmode_active)
    {
        mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
               CWEventMask | CWOverrideRedirect;
        attr.override_redirect = True;
        attr.backing_store = NotUseful;
        attr.save_under = False;
    }
    else
    {
        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
    }

    win = XCreateWindow(dpy, root, 0, 0,
                        actualWidth, actualHeight,
                        0, visinfo->depth, InputOutput,
                        visinfo->visual, mask, &attr);

    XStoreName(dpy, win, GAME_NAME);

    // don't let the window be resized
    // FIXME: allow resize (win32 does)
    sizehints.flags = PMinSize | PMaxSize;
    sizehints.min_width = sizehints.max_width = actualWidth;
    sizehints.min_height = sizehints.max_height = actualHeight;

    XSetWMNormalHints(dpy, win, &sizehints);

    XMapWindow( dpy, win );

    if ( vidmode_active )
    {
        XMoveWindow( dpy, win, 0, 0 );
    }

    XFlush(dpy);
    XSync(dpy, False);
    ctx = qglXCreateContext(dpy, visinfo, NULL, True);
    XSync(dpy, False);

    // Free the visinfo after we're done with it
    XFree(visinfo);

    qglXMakeCurrent(dpy, win, ctx);

    glstring = (const char *) qglGetString(GL_RENDERER);
    common->Printf("GL_RENDERER: %s\n", glstring);

    glstring = (const char *) qglGetString(GL_EXTENSIONS);
    common->Printf("GL_EXTENSIONS: %s\n", glstring);

    // FIXME: here, software GL test

    glConfig.isFullscreen = a.fullScreen;

    if ( glConfig.isFullscreen )
    {
        Sys_GrabMouseCursor( true );
    }

    return true;
}
Пример #29
0
/*
===========
IN_ProcessEvents
===========
*/
void IN_ProcessEvents (void)
{

	// handle the mouse state when windowed if that's changed
	if (!vidmode_fullscreen)
	{
		if ( key_dest == key_game && !mouse_grab_active && vid_activewindow )
//		if ( key_dest != key_console && !mouse_grab_active && vid_activewindow )
		{
			IN_GrabMouse ();
		}
		else if ( key_dest != key_game && mouse_grab_active ) 
//		else if ( key_dest == key_console && mouse_grab_active ) 
		{
			IN_UngrabMouse ();
		}
	}

	// getting and handle events
	{
		XEvent x_event;
	
		static qboolean active = true;
	
		if (!x_disp)
			return;
	
		while (XPending(x_disp)) 
		{
			XNextEvent(x_disp, &x_event);
	
			switch (x_event.type) 
			{
			case KeyPress: // key pressed
			case KeyRelease: // key released
				Key_Event(XLateKey(&x_event.xkey), x_event.type == KeyPress);
				break;

			case MotionNotify: // mouse moved
				if (mouse_grab_active)
				{
					if (dga_mouse_active)
					{
						mouse_x += (float)x_event.xmotion.x_root;
						mouse_y += (float)x_event.xmotion.y_root;
					}
					else
					{
						mouse_x = (float)x_event.xmotion.x - (float)(vid.width / 2);
						mouse_y = (float)x_event.xmotion.y - (float)(vid.height / 2);

						if (mouse_x || mouse_y) // do warp
						{
							// move the mouse to the window center again
							XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
						}
					}
				}
				break;

			case ButtonPress: // mouse button pressed
			case ButtonRelease: // mouse button released
				switch (x_event.xbutton.button)
				{
				case 1:
					Key_Event (K_MOUSE1, x_event.type == ButtonPress);
					break;

				case 2:
					Key_Event (K_MOUSE3, x_event.type == ButtonPress);
					break;

				case 3:
					Key_Event (K_MOUSE2, x_event.type == ButtonPress);
					break;

				case 4:
					Key_Event (K_MWHEELUP, x_event.type == ButtonPress);
					break;

				case 5:
					Key_Event (K_MWHEELDOWN, x_event.type == ButtonPress);
					break;

				case 6:
					Key_Event (K_MOUSE4, x_event.type == ButtonPress);
					break;

				case 7:
					Key_Event (K_MOUSE5, x_event.type == ButtonPress);
					break;

				case 8:
					Key_Event (K_MOUSE6, x_event.type == ButtonPress);
					break;

				case 9:
					Key_Event (K_MOUSE7, x_event.type == ButtonPress);
					break;

				case 10:
					Key_Event (K_MOUSE8, x_event.type == ButtonPress);
					break;
				}
				break;

			case CreateNotify: // window created
				window_x = x_event.xcreatewindow.x;
				window_y = x_event.xcreatewindow.y;
				window_width = x_event.xcreatewindow.width;
				window_height = x_event.xcreatewindow.height;
				break;

			case ConfigureNotify: // window changed size/location
				window_x = x_event.xconfigure.x;
				window_y = x_event.xconfigure.y;
				window_width = x_event.xconfigure.width;
				window_height = x_event.xconfigure.height;

				// check for resize
				if (!vidmode_fullscreen)
				{
					if (window_width < 320)
						window_width = 320;
					if (window_height < 200)
						window_height = 200;

					vid.width = window_width;
					vid.height = window_height;

					vid.conwidth = vid.width;
					vid.conheight = vid.height;

					vid.recalc_refdef = true; // force a surface cache flush
				}
				break;

			case DestroyNotify: // window has been destroyed
				Sys_Quit (0);
				break; 

			case ClientMessage: // window manager messages
				if ((x_event.xclient.format == 32) && ((unsigned int)x_event.xclient.data.l[0] == wm_delete_window_atom))
					Sys_Quit (0);
				break; 

			case MapNotify: // window restored
			case UnmapNotify: // window iconified/rolledup/whatever
				vid_hiddenwindow = (x_event.type == UnmapNotify);
			case FocusIn: // window is now the input focus
			case FocusOut: // window is no longer the input focus
				switch (x_event.xfocus.mode)
				{
				case NotifyNormal:
				case NotifyGrab:
				case NotifyUngrab:
					vid_activewindow = (x_event.type == FocusIn);
					break;
				}

				if(vidmode_fullscreen)
				{
					if(x_event.type == MapNotify)
					{
						// set our video mode
						XF86VidModeSwitchToMode(x_disp, scrnum, &game_vidmode);
	
						// move the viewport to top left
						XF86VidModeSetViewPort(x_disp, scrnum, 0, 0);
					}
					else if(x_event.type == UnmapNotify)
					{
						// set our video mode
						XF86VidModeSwitchToMode(x_disp, scrnum, &init_vidmode);
					}
				}
				else //if (!vidmode_fullscreen)
				{
					// enable/disable sound, set/restore gamma and grab/ungrab keyb
					// on focus gain/loss
					if (vid_activewindow && !vid_hiddenwindow && !active)
					{
						S_UnblockSound ();
						S_ClearBuffer ();
						VID_Gamma_Set ();
						IN_GrabKeyboard();
						active = true;
					}
					else if (active)
					{
						S_BlockSound ();
						S_ClearBuffer ();
						VID_Gamma_Restore ();
						IN_UngrabKeyboard();
						active = false;
					}
				}

				// fix the leftover Alt from any Alt-Tab or the like that switched us away
				Key_ClearStates ();
				break;

			case EnterNotify: // mouse entered window
			case LeaveNotify: // mouse left window
				vid_notifywindow = (x_event.type == EnterNotify);
				break;
			}
		}
	}
}
Пример #30
0
bool fxwt::init_graphics(GraphicsInitParameters *gparams) {
	Display *dpy;
	Window win;
	info("Initializing GLX");

	if(!(dpy = XOpenDisplay(0))) {
		error("Could not connect to the X server");
		return false;
	}

	int screen = DefaultScreen(dpy);
	Window root_win = RootWindow(dpy, screen);

	info("Trying to set video mode %dx%dx%d, d:%d s:%d %s", gparams->x, gparams->y, gparams->bpp, gparams->depth_bits, gparams->stencil_bits, gparams->fullscreen ? "fullscreen" : "windowed");
	
	// determine color bits
	int color_bits = 1;
	if(!(gparams->dont_care_flags & DONT_CARE_BPP)) {
		switch(gparams->bpp) {
		case 32:
		case 24:
			color_bits = 8;
			break;

		case 16:
		case 15:
			color_bits = 5;
			break;

		case 12:
			color_bits = 4;
			break;

		default:
			error("%s: Tried to set unsupported pixel format: %d bpp", __func__, gparams->bpp);
		}
	}

	// determine stencil bits
	int stencil_bits = gparams->stencil_bits;
	if(gparams->dont_care_flags & DONT_CARE_STENCIL) {
		stencil_bits = 1;
	}

	// determine zbuffer bits
	int zbits = gparams->depth_bits == 32 ? 24 : gparams->depth_bits;
	if(gparams->dont_care_flags & DONT_CARE_BPP) {
		zbits = 1;
	}
	
	int glx_attrib[] = {
		GLX_RGBA, GLX_DOUBLEBUFFER,
		GLX_RED_SIZE, color_bits,
		GLX_GREEN_SIZE, color_bits,
		GLX_BLUE_SIZE, color_bits,
		GLX_DEPTH_SIZE, zbits,
		GLX_STENCIL_SIZE, stencil_bits,
		None
	};

	XVisualInfo *vis_info;
	if(!(vis_info = glXChooseVisual(dpy, screen, glx_attrib))) {
		error("%s: Could not set requested video mode", __func__);
		XCloseDisplay(dpy);
		return false;
	}

	// check the video mode we got
	int arbits, agbits, abbits, azbits, astencilbits;
	glXGetConfig(dpy, vis_info, GLX_RED_SIZE, &arbits);
	glXGetConfig(dpy, vis_info, GLX_GREEN_SIZE, &agbits);
	glXGetConfig(dpy, vis_info, GLX_BLUE_SIZE, &abbits);
	glXGetConfig(dpy, vis_info, GLX_DEPTH_SIZE, &azbits);
	glXGetConfig(dpy, vis_info, GLX_STENCIL_SIZE, &astencilbits);

	info("Initialized video mode:");
	info("    bpp: %d (%d%d%d)", arbits + agbits + abbits, arbits, agbits, abbits);
	info("zbuffer: %d", azbits);
	info("stencil: %d", astencilbits);

	/* if the dont_care_flags does not contain DONT_CARE_BPP and our color bits
	 * does not match, we should return failure, however we test against
	 * the difference allowing a +/-1 difference in order to allow for 16bpp
	 * formats of either 565 or 555 and consider them equal.
	 */
	if(!(gparams->dont_care_flags & DONT_CARE_BPP) && abs(arbits - color_bits) > 1 && abs(agbits - color_bits) > 1 && abs(abbits - color_bits) > 1) {
		error("%s: Could not set requested exact bpp mode", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	// now if we don't have DONT_CARE_DEPTH in the dont_care_flags check for 
	// exact depth buffer format, however consider 24 and 32 bit the same
	if(!(gparams->dont_care_flags & DONT_CARE_DEPTH) && azbits != zbits) {
		if(!(zbits == 32 && azbits == 24 || zbits == 24 && azbits == 32)) {
			error("%s: Could not set requested exact zbuffer depth", __func__);
			XFree(vis_info);
			XCloseDisplay(dpy);
			return false;
		}
	}

	// if we don't have DONT_CARE_STENCIL make sure we have the stencil format
	// that was asked.
	if(!(gparams->dont_care_flags & DONT_CARE_STENCIL) && astencilbits != gparams->stencil_bits) {
		error("%s: Could not set exact stencil format", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	// everything is ok, create the context
	if(!(glx_ctx = glXCreateContext(dpy, vis_info, 0, True))) {
		error("%s: Failed to create GLX context", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	XSetWindowAttributes xattr;
	xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen);
	xattr.colormap = XCreateColormap(dpy, root_win, vis_info->visual, AllocNone);

	if(gparams->fullscreen) {
		// TODO: also test for "XFree86-VidModeExtension"
#ifdef USE_XF86VIDMODE
		info("Using XF86VidMode extension for fullscreen resolution switch.");
		
		XF86VidModeModeInfo **modes;
		XF86VidModeModeInfo *vid_mode = 0;
		int mode_count;
		
		XF86VidModeGetAllModeLines(dpy, screen, &mode_count, &modes);
		orig_mode = *modes[0];

		for(int i=0; i<mode_count; i++) {
			if(modes[i]->hdisplay == gparams->x && modes[i]->vdisplay == gparams->y) {
				vid_mode = modes[i];
			}
		}
		if(!vid_mode) {
			error("Could not set requested video mode");
			XFree(modes);
			XFree(vis_info);
			XCloseDisplay(dpy);
			return -1;
		}
		
		XF86VidModeSwitchToMode(dpy, screen, vid_mode);
		XF86VidModeSetViewPort(dpy, screen, 0, 0);
		XFree(modes);

		xattr.override_redirect = True;
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr);

		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		XMapRaised(dpy, win);
        XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
#else
		info("Resolution switching is not compiled or not supported by the X server, using a full-screen window.");

		XWindowAttributes root_attr;
		XGetWindowAttributes(dpy, root_win, &root_attr);

		gparams->x = root_attr.width;
		gparams->y = root_attr.height;
		xattr.override_redirect = True;
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr);

		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		XMapRaised(dpy, win);
        XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
#endif	// USE_XF86VIDMODE

		fullscreen = true;
	} else {
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr);
	}

	long events = ExposureMask | StructureNotifyMask | KeyPressMask;	// expose and key events
	events |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask;	// mouse events
	XSelectInput(dpy, win, events);
		
	// set WM cooperation settings
	Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
	XSetWMProtocols(dpy, win, &wm_delete, 1);

	XTextProperty tp_wname;
	static char *win_title = "3dengfx/X";
	XStringListToTextProperty(&win_title, 1, &tp_wname);
	XSetWMName(dpy, win, &tp_wname);
	XFree(tp_wname.value);

	XClassHint class_hint;
	class_hint.res_name = "3dengfx";
	class_hint.res_class = "3dengfx_graphics";
	XSetClassHint(dpy, win, &class_hint);

	XFree(vis_info);

	if(glXMakeCurrent(dpy, win, glx_ctx) == False) {
		error("%s: Failed to make the GLX context current", __func__);
		glXDestroyContext(dpy, glx_ctx);
		XDestroyWindow(dpy, win);
		XCloseDisplay(dpy);
		return false;
	}

	if(!glXIsDirect(dpy, glx_ctx)) {
		warning("using indirect rendering, which might be slow...");
	}

	XMapWindow(dpy, win);
	XFlush(dpy);

	fxwt_x_dpy = dpy;
	fxwt_x_win = win;
	
	return true;
}