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 }
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; }
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); }
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 ); }
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); }
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); }
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); }
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; }
/* 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); }
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; } }
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); }
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 }
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 (); }
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); }
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 */ }
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); } }
/* ** 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(); }
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(); }
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; }
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; }
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 }
/* ** 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; }
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 }
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; }
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*/ } }
/* =============== 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; }
/* =========== 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; } } } }
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; }