/* If the viewport has been scrolled since the screen was blanked, then scroll it back to where it belongs. This function only exists to patch over a very brief race condition. */ static void undo_vp_motion (saver_info *si) { #ifdef HAVE_XF86VMODE saver_preferences *p = &si->prefs; int screen; int real_nscreens = ScreenCount (si->dpy); int event, error; if (!XF86VidModeQueryExtension (si->dpy, &event, &error)) return; for (screen = 0; screen < real_nscreens; screen++) { saver_screen_info *ssi = &si->screens[screen]; int x, y; Bool status; if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1) break; if (!XF86VidModeGetViewPort (si->dpy, screen, &x, &y)) return; if (ssi->blank_vp_x == x && ssi->blank_vp_y == y) return; /* We're going to move the viewport. The mouse has just been grabbed on (and constrained to, thus warped to) the password window, so it is no longer near the edge of the screen. However, wait a bit anyway, just to make sure the server drains its last motion event, so that the screen doesn't continue to scroll after we've reset the viewport. */ XSync (si->dpy, False); usleep (250000); /* 1/4 second */ XSync (si->dpy, False); status = XF86VidModeSetViewPort (si->dpy, screen, ssi->blank_vp_x, ssi->blank_vp_y); if (!status) fprintf (stderr, "%s: %d: unable to move vp from (%d,%d) back to (%d,%d)!\n", blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y); else if (p->verbose_p) fprintf (stderr, "%s: %d: vp moved to (%d,%d); moved it back to (%d,%d).\n", blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y); } #endif /* HAVE_XF86VMODE */ }
/* * Remembers the current visual settings, so that * we can change them and restore later... */ static void fghRememberState( void ) { #if TARGET_HOST_UNIX_X11 /* * This highly depends on the XFree86 extensions, * not approved as X Consortium standards */ # ifdef X_XF86VidModeGetModeLine /* * Remember the current ViewPort location of the screen to be able to * restore the ViewPort on LeaveGameMode(): */ if( !XF86VidModeGetViewPort( fgDisplay.Display, fgDisplay.Screen, &fgDisplay.DisplayViewPortX, &fgDisplay.DisplayViewPortY ) ) fgWarning( "XF86VidModeGetViewPort failed" ); /* * Remember the current pointer location before going fullscreen * for restoring it later: */ { Window junk_window; unsigned int mask; XQueryPointer( fgDisplay.Display, fgDisplay.RootWindow, &junk_window, &junk_window, &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &mask ); } /* Query the current display settings: */ fgDisplay.DisplayModeValid = XF86VidModeGetModeLine( fgDisplay.Display, fgDisplay.Screen, &fgDisplay.DisplayModeClock, &fgDisplay.DisplayMode ); if( !fgDisplay.DisplayModeValid ) fgWarning( "XF86VidModeGetModeLine failed" ); # else /* * XXX warning fghRememberState: missing XFree86 video mode extensions, * XXX game mode will not change screen resolution when activated */ # endif #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE /* DEVMODE devMode; */ /* Grab the current desktop settings... */ /* hack to get around my stupid cross-gcc headers */ #define FREEGLUT_ENUM_CURRENT_SETTINGS -1 EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS, &fgDisplay.DisplayMode ); /* Make sure we will be restoring all settings needed */ fgDisplay.DisplayMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; #endif }
/* * Remembers the current visual settings, so that * we can change them and restore later... */ static void fghRememberState( void ) { #if TARGET_HOST_POSIX_X11 int event_base, error_base; /* * Remember the current pointer location before going fullscreen * for restoring it later: */ Window junk_window; unsigned int junk_mask; XQueryPointer(fgDisplay.Display, fgDisplay.RootWindow, &junk_window, &junk_window, &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &junk_mask); # ifdef HAVE_X11_EXTENSIONS_XRANDR_H if(XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) { XRRScreenConfiguration *xrr_config; XRRScreenSize *ssizes; Rotation rot; int ssize_count, curr; if((xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) { ssizes = XRRConfigSizes(xrr_config, &ssize_count); curr = XRRConfigCurrentConfiguration(xrr_config, &rot); fgDisplay.prev_xsz = ssizes[curr].width; fgDisplay.prev_ysz = ssizes[curr].height; fgDisplay.prev_refresh = -1; # if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) ) if(fgState.GameModeRefresh != -1) { fgDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config); } # endif fgDisplay.prev_size_valid = 1; XRRFreeScreenConfigInfo(xrr_config); } } # endif /* * This highly depends on the XFree86 extensions, * not approved as X Consortium standards */ # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H if(!XF86VidModeQueryExtension(fgDisplay.Display, &event_base, &error_base)) { return; } /* * Remember the current ViewPort location of the screen to be able to * restore the ViewPort on LeaveGameMode(): */ if( !XF86VidModeGetViewPort( fgDisplay.Display, fgDisplay.Screen, &fgDisplay.DisplayViewPortX, &fgDisplay.DisplayViewPortY ) ) fgWarning( "XF86VidModeGetViewPort failed" ); /* Query the current display settings: */ fgDisplay.DisplayModeValid = XF86VidModeGetModeLine( fgDisplay.Display, fgDisplay.Screen, &fgDisplay.DisplayModeClock, &fgDisplay.DisplayMode ); if( !fgDisplay.DisplayModeValid ) fgWarning( "XF86VidModeGetModeLine failed" ); # endif #elif TARGET_HOST_MS_WINDOWS /* DEVMODE devMode; */ /* Grab the current desktop settings... */ /* hack to get around my stupid cross-gcc headers */ #define FREEGLUT_ENUM_CURRENT_SETTINGS -1 EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS, &fgDisplay.DisplayMode ); /* Make sure we will be restoring all settings needed */ fgDisplay.DisplayMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; #endif }
static int SwitchRes(char inout, int x, int y, int w, int h, int *dw, int *dh) { static int vp_x, vp_y; XF86VidModeModeInfo *mode; int scr; scr = Dpy.screen; if (inout) { XF86VidModeModeLine curmode; int dotclock; int rx, ry; if (!XF86VidModeGetModeLine(disp, scr, &dotclock, &curmode)) return 0; XF86VidModeGetViewPort(disp, scr, &vp_x, &vp_y); mode = FindMode(w, h); if (mode) { #if USE_XRANDR int vw, vh; vw = WinGetW(VROOT); vh = WinGetH(VROOT); /* x and y relative to unrotated display */ if (Mode.screen.rotation == RR_Rotate_90) { rx = y; ry = vw - mode->vdisplay - x; } else if (Mode.screen.rotation == RR_Rotate_270) { rx = vh - mode->hdisplay - y; ry = x; } else if (Mode.screen.rotation == RR_Rotate_180) { rx = vw - mode->hdisplay - x; ry = vh - mode->vdisplay - y; } else #endif { rx = x; ry = y; } #if USE_XRANDR if ((Mode.screen.rotation == RR_Rotate_90) || (Mode.screen.rotation == RR_Rotate_270)) { *dw = mode->vdisplay; *dh = mode->hdisplay; } else #endif { *dw = mode->hdisplay; *dh = mode->vdisplay; } XF86VidModeLockModeSwitch(disp, scr, 0); std_vid_mode_cur = GetModeIndex(dotclock, &curmode); XF86VidModeSwitchToMode(disp, scr, mode); XF86VidModeSetViewPort(disp, scr, rx, ry); XF86VidModeLockModeSwitch(disp, scr, 1); return 1; } } else { mode = std_vid_modes[std_vid_mode_cur]; XF86VidModeLockModeSwitch(disp, scr, 0); XF86VidModeSwitchToMode(disp, scr, mode); XF86VidModeSetViewPort(disp, scr, vp_x, vp_y); #if 0 /* No, don't lock or we can't switch resolution */ XF86VidModeLockModeSwitch(disp, scr, 1); #endif } return 0; }
/* * Remembers the current visual settings, so that * we can change them and restore later... */ void fgPlatformRememberState( void ) { int event_base, error_base; /* * Remember the current pointer location before going fullscreen * for restoring it later: */ Window junk_window; unsigned int junk_mask; XQueryPointer(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow, &junk_window, &junk_window, &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY, &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY, &junk_mask); # ifdef HAVE_X11_EXTENSIONS_XRANDR_H if(XRRQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) { XRRScreenConfiguration *xrr_config; XRRScreenSize *ssizes; Rotation rot; int ssize_count, curr; if((xrr_config = XRRGetScreenInfo(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow))) { ssizes = XRRConfigSizes(xrr_config, &ssize_count); curr = XRRConfigCurrentConfiguration(xrr_config, &rot); fgDisplay.pDisplay.prev_xsz = ssizes[curr].width; fgDisplay.pDisplay.prev_ysz = ssizes[curr].height; fgDisplay.pDisplay.prev_refresh = -1; # if ( RANDR_MAJOR > 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) ) if(fgState.GameModeRefresh != -1) { fgDisplay.pDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config); } # endif fgDisplay.pDisplay.prev_size_valid = 1; XRRFreeScreenConfigInfo(xrr_config); } } # endif /* * This highly depends on the XFree86 extensions, * not approved as X Consortium standards */ # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H if(!XF86VidModeQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) { return; } /* * Remember the current ViewPort location of the screen to be able to * restore the ViewPort on LeaveGameMode(): */ if( !XF86VidModeGetViewPort( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen, &fgDisplay.pDisplay.DisplayViewPortX, &fgDisplay.pDisplay.DisplayViewPortY ) ) fgWarning( "XF86VidModeGetViewPort failed" ); /* Query the current display settings: */ fgDisplay.pDisplay.DisplayModeValid = XF86VidModeGetModeLine( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen, &fgDisplay.pDisplay.DisplayModeClock, &fgDisplay.pDisplay.DisplayMode ); if( !fgDisplay.pDisplay.DisplayModeValid ) fgWarning( "XF86VidModeGetModeLine failed" ); # endif }
void CL_DisplayWindow_OpenGL::set_fullscreen(int width, int height, int bpp, int refresh_rate) { if(fullscreen) return; // Vid-mode Switching XF86VidModeModeLine cur_mode; XF86VidModeGetModeLine(disp, 0, &dotclock, &cur_mode); old_mode.dotclock = dotclock; old_mode.hdisplay = cur_mode.hdisplay; old_mode.hsyncstart = cur_mode.hsyncstart; old_mode.hsyncend = cur_mode.hsyncend; old_mode.htotal = cur_mode.htotal; old_mode.vdisplay = cur_mode.vdisplay; old_mode.vsyncstart = cur_mode.vsyncstart; old_mode.vsyncend = cur_mode.vsyncend; old_mode.vtotal = cur_mode.vtotal; old_mode.flags = cur_mode.flags; old_mode.privsize = 0; int num_modes; XF86VidModeModeInfo **modes; XF86VidModeGetAllModeLines(disp, 0, &num_modes, &modes); std::list<XF86VidModeModeInfo *> usable_modes; for(int i = 0; i < num_modes; i++) { if(modes[i]->hdisplay == width && modes[i]->vdisplay == height) { CL_Log::log("debug", "Useable fullscreen mode found: %1x%2", width, height); usable_modes.push_back(modes[i]); } } if (usable_modes.empty()) { CL_Log::log("debug", "No useable fullscreen modes available!"); } else { if(!width) width = get_width(); if(!height) height = get_height(); if(!bpp) bpp = glx_bpp; //Hide Window if (0) { // FIXME: allow_override doesn't play together with // GrabPointer, not sure what is wrong but it simply doesn't // work. // // The code outside the 'if(0)' as it is now, works mostly, // however it doesn't work when the window or a part of it is // outside of the screen, since the window isn't moved // fullscreen will only show half the window, shouldn't be a // problem for most of the time, but will be tricky if the // window has equal size as the desktop. // Move the window into the right position, this must happen // BEFORE we remove control from the window manager XMoveResizeWindow(disp, window, 0, 0, width, height); // Move the mouse and switch moves XWarpPointer(disp, None, None, 0, 0, 0, 0, width/2, height/2); XUnmapWindow(disp, window); { // Wait for window to disapear XEvent event; do { XMaskEvent(disp, StructureNotifyMask, &event); } while ( (event.type != UnmapNotify) || (event.xunmap.event != window) ); } // Turn off WM control attributes.override_redirect = True; XChangeWindowAttributes(disp, window, CWBorderPixel | CWColormap | CWOverrideRedirect, &attributes); // Re-appear window XMapRaised(disp, window); } // Get input focus //XSetInputFocus(disp,window, RevertToNone, CurrentTime); while (1) { int result = XGrabPointer(disp, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); if ( result == GrabSuccess ) { break; } CL_System::sleep(100); } XF86VidModeGetViewPort(disp, DefaultScreen(disp), &old_x, &old_y); XF86VidModeSwitchToMode(disp, 0, *(usable_modes.begin())); Window child_window; int x, y; // Get the windows absolute position (aka relative to // the root window) XTranslateCoordinates(disp, window, DefaultRootWindow(disp), 0, 0, &x, &y, &child_window); XF86VidModeSetViewPort(disp, DefaultScreen(disp), x, y); XSync(disp, True); fullscreen = true; } }