bool RandRScreen::applyProposed() { // kdDebug() << k_funcinfo << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << // refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) << endl; Status status; if(proposedRefreshRate() < 0) status = XRRSetScreenConfig(qt_xdisplay(), d->config, DefaultRootWindow(qt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime); else { if(refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0) { m_proposedRefreshRate = 0; } status = XRRSetScreenConfigAndRate(qt_xdisplay(), d->config, DefaultRootWindow(qt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime); } // kdDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << ", " << // HeightOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << endl; if(status == RRSetConfigSuccess) { m_currentSize = m_proposedSize; m_currentRotation = m_proposedRotation; m_currentRefreshRate = m_proposedRefreshRate; return true; } return false; }
bool QxtScreenPrivate::set(const QSize& reso, int rate, int depth) { bool result = false; Q_UNUSED(reso); Q_UNUSED(rate); Q_UNUSED(depth); #ifdef HAVE_XRANDR Display* display = XOpenDisplay(NULL); Window root = RootWindow(display, screen); XRRScreenConfiguration* config = XRRGetScreenInfo(display, root); int sizeIndex = 0; if (reso.isValid()) sizeIndex = availResos.indexOf(reso); else sizeIndex = availResos.indexOf(currReso); Q_ASSERT(sizeIndex != -1); if (rate == -1) result = XRRSetScreenConfig(display, config, root, sizeIndex, RR_Rotate_0, CurrentTime); else result = XRRSetScreenConfigAndRate(display, config, root, sizeIndex, RR_Rotate_0, rate, CurrentTime); XRRFreeScreenConfigInfo(config); XCloseDisplay(display); #endif // HAVE_XRANDR return result; }
/* * @brief sets a given screen's primary output's orientation * @param root window which's screen's primary output will be queried * @param orientation orientation which should be set for the root window's screen primary output * @return EINA_TRUE if the primary output's orientation could be successfully altered */ EAPI Eina_Bool ecore_x_randr_screen_primary_output_orientation_set( Ecore_X_Window root, Ecore_X_Randr_Orientation orientation) { #ifdef ECORE_XRANDR XRRScreenConfiguration *xrr_screen_cfg = NULL; int sizeid; Rotation crot; Eina_Bool ret = EINA_FALSE; if (!(xrr_screen_cfg = XRRGetScreenInfo(_ecore_x_disp, root))) return EINA_FALSE; sizeid = XRRConfigCurrentConfiguration(xrr_screen_cfg, &crot); if (!XRRSetScreenConfig(_ecore_x_disp, xrr_screen_cfg, root, sizeid, orientation, CurrentTime)) ret = EINA_TRUE; if (xrr_screen_cfg) XRRFreeScreenConfigInfo(xrr_screen_cfg); return ret; #else /* ifdef ECORE_XRANDR */ return EINA_FALSE; #endif /* ifdef ECORE_XRANDR */ } /* ecore_x_randr_screen_primary_output_orientation_set */
//////////////////////////////////////////////////////////// /// Cleanup graphical resources attached to the window //////////////////////////////////////////////////////////// void WindowImplX11::CleanUp() { // Restore the previous video mode (in case we were running in fullscreen) if (ourFullscreenWindow == this) { // Get current screen info XRRScreenConfiguration* Config = XRRGetScreenInfo(ourDisplay, RootWindow(ourDisplay, ourScreen)); if (Config) { // Get the current rotation Rotation CurrentRotation; XRRConfigCurrentConfiguration(Config, &CurrentRotation); // Reset the video mode XRRSetScreenConfig(ourDisplay, Config, RootWindow(ourDisplay, ourScreen), myOldVideoMode, CurrentRotation, CurrentTime); // Free the configuration instance XRRFreeScreenConfigInfo(Config); } // Reset the fullscreen window ourFullscreenWindow = NULL; } // Unhide the mouse cursor (in case it was hidden) ShowMouseCursor(true); // Destroy the OpenGL context if (myGLContext) { glXDestroyContext(ourDisplay, myGLContext); myGLContext = NULL; } }
void uaw::ConcreteX11Connection::ChangeSizeIndex (Display *disp, ScreenConfig const &config, unsigned int index) const { XRRSetScreenConfig (disp, config.get (), DefaultRootWindow (disp), index, RR_Rotate_0, CurrentTime); }
int set_x11videomode(const x11videomode_t * xvidmode, x11screen_t * x11screen) { int err ; XRRScreenConfiguration * screen_config = 0 ; if (!isextxrandr_x11display(display_x11screen(x11screen))) { err = ENOSYS ; goto ONERR; } Display * sys_display = display_x11screen(x11screen)->sys_display ; screen_config = XRRGetScreenInfo(sys_display, RootWindow(sys_display, number_x11screen(x11screen))) ; if (!screen_config) { err = ENOSYS ; goto ONERR; } Rotation current_rotation ; uint16_t current_size = XRRConfigCurrentConfiguration(screen_config, ¤t_rotation) ; int sizes_count ; XRRScreenSize * sizes = XRRConfigSizes(screen_config, &sizes_count) ; if ( !sizes || (current_size >= sizes_count)) { err = EOVERFLOW ; goto ONERR; } if ( xvidmode->modeid > sizes_count || xvidmode->width_in_pixel != (uint32_t) sizes[xvidmode->modeid].width || xvidmode->height_in_pixel != (uint32_t) sizes[xvidmode->modeid].height) { err = EINVAL ; goto ONERR; } if (XRRSetScreenConfig( sys_display, screen_config, RootWindow(sys_display, number_x11screen(x11screen)), xvidmode->modeid, current_rotation, CurrentTime)) { err = EOPNOTSUPP ; goto ONERR; } XRRFreeScreenConfigInfo(screen_config) ; return 0 ; ONERR: if (screen_config) { XRRFreeScreenConfigInfo(screen_config) ; } TRACEEXIT_ERRLOG(err); return err ; }
//////////////////////////////////////////////////////////// /// Switch to fullscreen mode //////////////////////////////////////////////////////////// void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode) { // Check if the XRandR extension is present int Version; if (XQueryExtension(ourDisplay, "RANDR", &Version, &Version, &Version)) { // Get the current configuration XRRScreenConfiguration* Config = XRRGetScreenInfo(ourDisplay, RootWindow(ourDisplay, ourScreen)); if (Config) { // Get the current rotation Rotation CurrentRotation; myOldVideoMode = XRRConfigCurrentConfiguration(Config, &CurrentRotation); // Get the available screen sizes int NbSizes; XRRScreenSize* Sizes = XRRConfigSizes(Config, &NbSizes); if (Sizes && (NbSizes > 0)) { // Search a matching size for (int i = 0; i < NbSizes; ++i) { if ((Sizes[i].width == static_cast<int>(Mode.Width)) && (Sizes[i].height == static_cast<int>(Mode.Height))) { // Switch to fullscreen mode XRRSetScreenConfig(ourDisplay, Config, RootWindow(ourDisplay, ourScreen), i, CurrentRotation, CurrentTime); // Set "this" as the current fullscreen window ourFullscreenWindow = this; break; } } } // Free the configuration instance XRRFreeScreenConfigInfo(Config); } else { // Failed to get the screen configuration std::cerr << "Failed to get the current screen configuration for fullscreen mode, switching to windiw mode" << std::endl; } } else { // XRandr extension is not supported : we cannot use fullscreen mode std::cerr << "Fullscreen is not supported, switching to window mode" << std::endl; } }
KDE_EXPORT bool RandRScreen::applyProposed() { //kdDebug() << k_funcinfo << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) << endl; Status status; if (!d->config) { d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen)); Q_ASSERT(d->config); } if (d->config) { if (proposedRefreshRate() < 0) status = XRRSetScreenConfig(tqt_xdisplay(), d->config, DefaultRootWindow(tqt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime); else { if( refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0 ) { m_proposedRefreshRate = 0; } status = XRRSetScreenConfigAndRate(tqt_xdisplay(), d->config, DefaultRootWindow(tqt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime); } } else { // Great, now we have to set the information manually. Ughh. // FIXME--this does not work! ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay()); screeninfo->cur_width = (*m_pixelSizes.at(proposedSize())).width(); screeninfo->cur_height = (*m_pixelSizes.at(proposedSize())).height(); internal_main_low_apply(screeninfo); status = RRSetConfigSuccess; } //kdDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), screen)) << ", " << HeightOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), screen)) << endl; if (status == RRSetConfigSuccess) { m_currentSize = m_proposedSize; m_currentRotation = m_proposedRotation; m_currentRefreshRate = m_proposedRefreshRate; return true; } return false; }
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; } }
/** * This method first resets the current resolution using RandR to wake up * the graphics driver, then sets the resolution requested if it is among * those offered by the driver. */ static void setSize(Display *pDisplay, uint32_t cx, uint32_t cy) { XRRScreenConfiguration *pConfig; XRRScreenSize *pSizes; int cSizes; pConfig = XRRGetScreenInfo(pDisplay, DefaultRootWindow(pDisplay)); /* Reset the current mode */ LogRelFlowFunc(("Setting size %ux%u\n", cx, cy)); if (pConfig) { pSizes = XRRConfigSizes(pConfig, &cSizes); unsigned uDist = UINT32_MAX; int iMode = -1; for (int i = 0; i < cSizes; ++i) { #define VBCL_SQUARE(x) (x) * (x) unsigned uThisDist = VBCL_SQUARE(pSizes[i].width - cx) + VBCL_SQUARE(pSizes[i].height - cy); LogRelFlowFunc(("Found size %dx%d, distance %u\n", pSizes[i].width, pSizes[i].height, uThisDist)); #undef VBCL_SQUARE if (uThisDist < uDist) { uDist = uThisDist; iMode = i; } } if (iMode >= 0) { Time config_timestamp = 0; XRRConfigTimes(pConfig, &config_timestamp); LogRelFlowFunc(("Setting new size %d\n", iMode)); XRRSetScreenConfig(pDisplay, pConfig, DefaultRootWindow(pDisplay), iMode, RR_Rotate_0, config_timestamp); } XRRFreeScreenConfigInfo(pConfig); } }
void C4AbstractApp::RestoreVideoMode() { #ifdef GDK_WINDOWING_X11 // Restore resolution Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); if (fDspModeSet && Priv->xrandr_major_version >= 0 && Priv->xrandr_oldmode != -1) { XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->renderwnd); #ifdef _DEBUG LogF("XRRSetScreenConfig %d (back)", Priv->xrandr_oldmode); #endif XRRSetScreenConfig (dpy, conf, pWindow->renderwnd, Priv->xrandr_oldmode, Priv->xrandr_rot, CurrentTime); Priv->xrandr_oldmode = -1; XRRFreeScreenConfigInfo(conf); fDspModeSet = false; } // pWindow may be unset when C4AbstractApp gets destroyed during the // initialization code, before a window has been created if (pWindow) gtk_window_unfullscreen(GTK_WINDOW(pWindow->window)); #endif }
bool C4AbstractApp::SetVideoMode(int iXRes, int iYRes, unsigned int iColorDepth, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen) { #ifdef GDK_WINDOWING_X11 Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); if (!fFullScreen) { RestoreVideoMode(); if (iXRes != -1) pWindow->SetSize(iXRes, iYRes); return true; } if (Priv->xrandr_major_version >= 0 && !(iXRes == -1 && iYRes == -1)) { // randr spec says to always get fresh info, so don't cache. XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->renderwnd); if (Priv->xrandr_oldmode == -1) Priv->xrandr_oldmode = XRRConfigCurrentConfiguration (conf, &Priv->xrandr_rot); int n; XRRScreenSize * sizes = XRRConfigSizes(conf, &n); for (int i = 0; i < n; ++i) { if (int(sizes[i].width) == iXRes && int(sizes[i].height) == iYRes) { #ifdef _DEBUG LogF("XRRSetScreenConfig %d", i); #endif fDspModeSet = XRRSetScreenConfig(dpy, conf, pWindow->renderwnd, i, Priv->xrandr_rot, CurrentTime) == RRSetConfigSuccess; break; } } XRRFreeScreenConfigInfo(conf); } gtk_window_fullscreen(GTK_WINDOW(pWindow->window)); return fDspModeSet || (iXRes == -1 && iYRes == -1); #endif }
/* * @brief sets a given screen's primary output size, but disables all other outputs at the same time * @param root window which's primary output will be queried * @param size_index within the list of sizes reported as supported by the root window's screen primary output * @return EINA_TRUE on success, EINA_FALSE on failure due to e.g. invalid times */ EAPI Eina_Bool ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index) { #ifdef ECORE_XRANDR XRRScreenConfiguration *sc = NULL; XRRScreenSize *sizes; Eina_Bool ret = EINA_FALSE; int nsizes = 0; if (size_index >= 0 && _ecore_x_randr_root_validate(root)) { sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &nsizes); if (size_index < nsizes) { sc = XRRGetScreenInfo(_ecore_x_disp, root); if (!XRRSetScreenConfig(_ecore_x_disp, sc, root, size_index, ECORE_X_RANDR_ORIENTATION_ROT_0, CurrentTime)) { ret = EINA_TRUE; } if (sc) XRRFreeScreenConfigInfo(sc); } } return ret; #else /* ifdef ECORE_XRANDR */ return EINA_FALSE; #endif /* ifdef ECORE_XRANDR */ } /* ecore_x_randr_screen_primary_output_size_set */
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*/ } }
bool CIrrDeviceLinux::createWindow() { #ifdef _IRR_COMPILE_WITH_X11_ #ifdef _DEBUG os::Printer::log("Creating X window...", ELL_INFORMATION); XSetErrorHandler(IrrPrintXError); #endif display = XOpenDisplay(0); if (!display) { os::Printer::log("Error: Need running XServer to start Irrlicht Engine.", ELL_ERROR); os::Printer::log("Could not open display", XDisplayName(0), ELL_ERROR); return false; } screennr = DefaultScreen(display); // query extension if (CreationParams.Fullscreen) { getVideoModeList(); #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) s32 eventbase, errorbase; s32 bestMode = -1; #endif #ifdef _IRR_LINUX_X11_VIDMODE_ if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) { // enumerate video modes s32 modeCount; XF86VidModeModeInfo** modes; XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); // find fitting mode for (s32 i = 0; i<modeCount; ++i) { if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height) bestMode = i; else if (bestMode!=-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height && modes[i]->hdisplay < modes[bestMode]->hdisplay && modes[i]->vdisplay < modes[bestMode]->vdisplay) bestMode = i; } if (bestMode != -1) { os::Printer::log("Starting fullscreen mode...", ELL_INFORMATION); XF86VidModeSwitchToMode(display, screennr, modes[bestMode]); XF86VidModeSetViewPort(display, screennr, 0, 0); UseXVidMode=true; } else { os::Printer::log("Could not find specified video mode, running windowed.", ELL_WARNING); CreationParams.Fullscreen = false; } XFree(modes); } else #endif #ifdef _IRR_LINUX_X11_RANDR_ if (XRRQueryExtension(display, &eventbase, &errorbase)) { s32 modeCount; XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); for (s32 i = 0; i<modeCount; ++i) { if (bestMode==-1 && (u32)modes[i].width >= Width && (u32)modes[i].height >= Height) bestMode = i; else if (bestMode!=-1 && (u32)modes[i].width >= Width && (u32)modes[i].height >= Height && modes[i].width < modes[bestMode].width && modes[i].height < modes[bestMode].height) bestMode = i; } if (bestMode != -1) { XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime); UseXRandR=true; } XRRFreeScreenConfigInfo(config); } else #endif { os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht " "to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING); CreationParams.Fullscreen = false; } } #ifdef _IRR_COMPILE_WITH_OPENGL_ GLXFBConfig glxFBConfig; int major, minor; bool isAvailableGLX=false; if (CreationParams.DriverType==video::EDT_OPENGL) { isAvailableGLX=glXQueryExtension(display,&major,&minor); if (isAvailableGLX && glXQueryVersion(display, &major, &minor)) { if (major==1 && minor>2) { const int MAX_SAMPLES = 16; // attribute array for the draw buffer int visualAttrBuffer[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0, GLX_DEPTH_SIZE, CreationParams.ZBufferBits, GLX_DOUBLEBUFFER, GL_TRUE, GLX_STENCIL_SIZE, 1, GLX_SAMPLE_BUFFERS_ARB, 1, GLX_SAMPLES_ARB, MAX_SAMPLES, None }; GLXFBConfig *configList=0; int nitems=0; if (!CreationParams.AntiAlias) { visualAttrBuffer[17] = 0; visualAttrBuffer[19] = 0; } if (CreationParams.Stencilbuffer) { configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); if (!configList && CreationParams.AntiAlias) { while (!configList && (visualAttrBuffer[19]>1)) { visualAttrBuffer[19] >>= 1; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); } if (!configList) { visualAttrBuffer[17] = 0; visualAttrBuffer[19] = 0; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); if (configList) { os::Printer::log("No FSAA available.", ELL_WARNING); CreationParams.AntiAlias=false; } else { //reenable multisampling visualAttrBuffer[17] = 1; visualAttrBuffer[19] = MAX_SAMPLES; } } } } // Next try without stencil buffer if (!configList) { if (CreationParams.Stencilbuffer) os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING); CreationParams.Stencilbuffer = false; visualAttrBuffer[15]=0; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); if (!configList && CreationParams.AntiAlias) { while (!configList && (visualAttrBuffer[19]>1)) { visualAttrBuffer[19] >>= 1; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); } if (!configList) { visualAttrBuffer[17] = 0; visualAttrBuffer[19] = 0; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); if (configList) { os::Printer::log("No FSAA available.", ELL_WARNING); CreationParams.AntiAlias=false; } else { //reenable multisampling visualAttrBuffer[17] = 1; visualAttrBuffer[19] = MAX_SAMPLES; } } } } // Next try without double buffer if (!configList) { os::Printer::log("No doublebuffering available.", ELL_WARNING); visualAttrBuffer[13] = GL_FALSE; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); if (!configList && CreationParams.AntiAlias) { while (!configList && (visualAttrBuffer[19]>1)) { visualAttrBuffer[19] >>= 1; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); } if (!configList) { visualAttrBuffer[17] = 0; visualAttrBuffer[19] = 0; configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); if (configList) { os::Printer::log("No FSAA available.", ELL_WARNING); CreationParams.AntiAlias=false; } else { //reenable multisampling visualAttrBuffer[17] = 1; visualAttrBuffer[19] = MAX_SAMPLES; } } } } if (configList) { glxFBConfig=configList[0]; XFree(configList); UseGLXWindow=true; visual = glXGetVisualFromFBConfig(display,glxFBConfig); } }
Bool SelectResolution(uint32 width, uint32 height) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; XRRScreenConfiguration* xrrConfig; XRRScreenSize *xrrSizes; Rotation xrrCurRotation; uint32 xrrNumSizes; uint32 i; uint32 bestFitIndex = 0; uint64 bestFitSize = 0; uint64 potentialSize; Bool perfectMatch; #ifndef NO_MULTIMON if (resInfoX->canUseRandR12) { xXineramaScreenInfo display; display.x_org = 0; display.y_org = 0; display.width = width; display.height = height; return RandR12_SetTopology(resInfoX->display, DefaultScreen(resInfoX->display), resInfoX->rootWindow, 1, &display, width, height); } #endif xrrConfig = XRRGetScreenInfo(resInfoX->display, resInfoX->rootWindow); xrrSizes = XRRConfigSizes(xrrConfig, &xrrNumSizes); bestFitIndex = XRRConfigCurrentConfiguration(xrrConfig, &xrrCurRotation); /* * Iterate thru the list finding the best fit that is still <= in both width * and height. */ for (i = 0; i < xrrNumSizes; i++) { potentialSize = xrrSizes[i].width * xrrSizes[i].height; if (xrrSizes[i].width <= width && xrrSizes[i].height <= height && potentialSize > bestFitSize ) { bestFitSize = potentialSize; bestFitIndex = i; } } if (bestFitSize > 0) { Status rc; g_debug("Setting guest resolution to: %dx%d (requested: %d, %d)\n", xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height, width, height); rc = XRRSetScreenConfig(resInfoX->display, xrrConfig, resInfoX->rootWindow, bestFitIndex, xrrCurRotation, GDK_CURRENT_TIME); g_debug("XRRSetScreenConfig returned %d (result: %dx%d)\n", rc, xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height); } else { g_debug("Can't find a suitable guest resolution, ignoring request for %dx%d\n", width, height); } perfectMatch = xrrSizes[bestFitIndex].width == width && xrrSizes[bestFitIndex].height == height; XRRFreeScreenConfigInfo(xrrConfig); return perfectMatch; }
void MMSFBManager::applySettings() { DEBUGMSG("MMSGUI", "configure graphics layer"); // get layer settings from config MMSConfigDataLayer videolayer_conf = this->config.getVideoLayer(); MMSConfigDataLayer graphicslayer_conf = this->config.getGraphicsLayer(); // get the window pixelformat MMSFBSurfacePixelFormat window_pixelformat = config.getGraphicsWindowPixelformat(); switch (window_pixelformat) { case MMSFB_PF_ARGB: case MMSFB_PF_AiRGB: case MMSFB_PF_AYUV: case MMSFB_PF_ARGB4444: case MMSFB_PF_RGB16: break; default: // window pixelformat not set or unsupported, use the layer pixelformat window_pixelformat = graphicslayer_conf.pixelformat; if (!isAlphaPixelFormat(window_pixelformat)) { // the gui internally needs surfaces with alpha channel // now we have to decide if we are working in RGB or YUV color space if (!isRGBPixelFormat(window_pixelformat)) // so switch all non-alpha pixelformats to AYUV window_pixelformat = MMSFB_PF_AYUV; else // so switch all non-alpha pixelformats to ARGB window_pixelformat = MMSFB_PF_ARGB; } else if (isIndexedPixelFormat(window_pixelformat)) { // the gui internally needs non-indexed surfaces // so switch all indexed pixelformats to ARGB window_pixelformat = MMSFB_PF_ARGB; } break; } // get the surface pixelformat MMSFBSurfacePixelFormat surface_pixelformat = config.getGraphicsSurfacePixelformat(); switch (surface_pixelformat) { case MMSFB_PF_ARGB: case MMSFB_PF_AiRGB: case MMSFB_PF_AYUV: case MMSFB_PF_ARGB4444: case MMSFB_PF_RGB16: break; default: // surface pixelformat not set or unsupported, use the layer pixelformat surface_pixelformat = graphicslayer_conf.pixelformat; if (!isAlphaPixelFormat(surface_pixelformat)) { // the gui internally needs surfaces with alpha channel // now we have to decide if we are working in RGB or YUV color space if (!isRGBPixelFormat(surface_pixelformat)) // so switch all non-alpha pixelformats to AYUV surface_pixelformat = MMSFB_PF_AYUV; else // so switch all non-alpha pixelformats to ARGB surface_pixelformat = MMSFB_PF_ARGB; } else if (isIndexedPixelFormat(surface_pixelformat)) { // the gui internally needs non-indexed surfaces // so switch all indexed pixelformats to ARGB surface_pixelformat = MMSFB_PF_ARGB; } break; } // set exclusive access to the graphics layer DEBUGMSG("MMSGUI", "set exclusive access"); if (!this->graphicslayer->setExclusiveAccess()) throw MMSFBManagerError(0, MMSFB_LastErrorString); DEBUGMSG("MMSGUI", "set configuration"); if(!this->graphicslayer->setConfiguration(graphicslayer_conf.rect.w, graphicslayer_conf.rect.h, graphicslayer_conf.pixelformat, graphicslayer_conf.buffermode, graphicslayer_conf.options, window_pixelformat, surface_pixelformat)) throw MMSFBManagerError(0, MMSFB_LastErrorString); #ifdef __HAVE_XRANDR__ if(config.getBackend() == MMSFB_BE_X11 && MMSFBBase_rotate180) { X11_IMPL *impl = (X11_IMPL*)this->graphicslayer->getImplementation(); /* check for RandR extension */ int event_base, error_base; if (!XRRQueryExtension (impl->x_display, &event_base, &error_base)) { fprintf(stderr, "RandR extension missing: Rotation not supported\n"); } else { Window root = DefaultRootWindow(impl->x_display); XRRScreenConfiguration *sc = XRRGetScreenInfo(impl->x_display, root); if(sc) { Rotation rot = RR_Rotate_0; SizeID size = XRRConfigCurrentConfiguration(sc, &rot); if(rot != RR_Rotate_180) { XRRSetScreenConfig(impl->x_display, sc, root, size, RR_Rotate_180, CurrentTime); } MMSFBBase_rotate180 = false; } } } #endif if (this->videolayerid != this->graphicslayerid) { #ifdef __HAVE_DIRECTFB__ if (config.getBackend() == MMSFB_BE_X11) { //give a little time to window routines usleep(300000); } #endif // use both layers DEBUGMSG("MMSGUI", "configure video layer"); DEBUGMSG("MMSGUI", "set exclusive access"); // set exclusive access to the video layer if (!this->videolayer->setExclusiveAccess()) throw MMSFBManagerError(0, MMSFB_LastErrorString); DEBUGMSG("MMSGUI", "set configuration"); // set video layer's config if (!this->videolayer->setConfiguration(videolayer_conf.rect.w, videolayer_conf.rect.h, videolayer_conf.pixelformat, videolayer_conf.buffermode, videolayer_conf.options)) throw MMSFBManagerError(0, MMSFB_LastErrorString); //this->videolayer->dfblayer->SetFieldParity(this->videolayer->dfblayer,0); // set the full opacity of the graphics layer this->graphicslayer->setOpacity(0); if (graphicslayer_conf.outputtype == MMSFB_OT_VIAFB) { // set the video layer behind the graphics layer DEBUGMSG("MMSGUI", "set the video layer behind the graphics layer"); this->videolayer->setLevel(-1); } else if (graphicslayer_conf.outputtype == MMSFB_OT_XSHM) { DEBUGMSG("MMSGUI", "set the video layer behind the graphics layer"); this->graphicslayer->setLevel(+1); } } // set global surface attributes string buffermode = graphicslayer_conf.buffermode; MMSFBSurface *gls; if (this->graphicslayer->getSurface(&gls, this->virtual_console)) { // set the static extended accel flag gls->setExtendedAcceleration(config.getExtendedAccel()); // set the global alloc method (default is malloc) if (mmsfb->getBackend() == MMSFB_BE_DFB) { #ifdef __HAVE_DIRECTFB__ string am = config.getAllocMethod(); if (am == "MALLOC") { if (!config.getExtendedAccel()) gls->setAllocMethod(MMSFBSurfaceAllocMethod_dfb); } else gls->setAllocMethod(MMSFBSurfaceAllocMethod_dfb); #endif } else if (graphicslayer_conf.outputtype == MMSFB_OT_OGL) { gls->setAllocMethod(MMSFBSurfaceAllocMethod_ogl); } } // init the mmsfbwindowmanager mmsfbwindowmanager->init(this->graphicslayer, (config.getPointer()==MMSFB_PM_TRUE)); DEBUGMSG("MMSGUI", "creating temporary surface: %dx%d, %s", graphicslayer_conf.rect.w, graphicslayer_conf.rect.h, getMMSFBPixelFormatString(surface_pixelformat).c_str()); mmsfbsurfacemanager->createTemporarySurface(graphicslayer_conf.rect.w, graphicslayer_conf.rect.h, surface_pixelformat, (buffermode == MMSFB_BM_BACKSYSTEM)); }
static int xrandr_resize(int xsz, int ysz, int rate, int just_checking) { #ifdef HAVE_X11_EXTENSIONS_XRANDR_H int event_base, error_base, ver_major, ver_minor, use_rate; XRRScreenConfiguration *xrr_config = 0; Status result = -1; /* must check at runtime for the availability of the extension */ if(!XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) { return -1; } XRRQueryVersion(fgDisplay.Display, &ver_major, &ver_minor); /* we only heed the rate if we CAN actually use it (Xrandr >= 1.1) and * the user actually cares about it (rate > 0) */ use_rate = ( rate > 0 ) && ( ( ver_major >= 1 ) || ( ( ver_major == 1 ) && ( ver_minor >= 1 ) ) ); /* this loop is only so that the whole thing will be repeated if someone * else changes video mode between our query of the current information and * the attempt to change it. */ do { XRRScreenSize *ssizes; short *rates; Rotation rot; int i, ssizes_count, rates_count, curr, res_idx = -1; Time timestamp, cfg_timestamp; if(xrr_config) { XRRFreeScreenConfigInfo(xrr_config); } if(!(xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) { fgWarning("XRRGetScreenInfo failed"); break; } ssizes = XRRConfigSizes(xrr_config, &ssizes_count); curr = XRRConfigCurrentConfiguration(xrr_config, &rot); timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp); /* if either of xsz or ysz are unspecified, use the current values */ if(xsz <= 0) xsz = fgState.GameModeSize.X = ssizes[curr].width; if(ysz <= 0) ysz = fgState.GameModeSize.Y = ssizes[curr].height; if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) { /* no need to switch, we're already in the requested resolution */ res_idx = curr; } else { for(i=0; i<ssizes_count; i++) { if(ssizes[i].width == xsz && ssizes[i].height == ysz) { res_idx = i; break; /* found it */ } } } if(res_idx == -1) break; /* no matching resolution */ #if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) ) if(use_rate) { rate = fgState.GameModeRefresh; /* for the selected resolution, let's find out if there is * a matching refresh rate available. */ rates = XRRConfigRates(xrr_config, res_idx, &rates_count); for(i=0; i<rates_count; i++) { if(rates[i] == rate) { break; } } if(i == rates_count) { break; /* no matching rate */ } } #endif if(just_checking) { result = 0; break; } #if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) ) if(use_rate) result = XRRSetScreenConfigAndRate(fgDisplay.Display, xrr_config, fgDisplay.RootWindow, res_idx, rot, rate, timestamp); else #endif result = XRRSetScreenConfig(fgDisplay.Display, xrr_config, fgDisplay.RootWindow, res_idx, rot, timestamp); } while(result == RRSetConfigInvalidTime); if(xrr_config) { XRRFreeScreenConfigInfo(xrr_config); } if(result == 0) { return 0; } #endif /* HAVE_X11_EXTENSIONS_XRANDR_H */ return -1; }
int32_t run(Filesystem* fs, ConfigSettings* cs) { // Create main window XInitThreads(); XSetErrorHandler(x11_error_handler); m_x11_display = XOpenDisplay(NULL); CE_ASSERT(m_x11_display != NULL, "Unable to open X11 display"); int screen = DefaultScreen(m_x11_display); int depth = DefaultDepth(m_x11_display, screen); Visual* visual = DefaultVisual(m_x11_display, screen); m_x11_parent_window = (m_parent_window_handle == 0) ? RootWindow(m_x11_display, screen) : (Window) m_parent_window_handle; // Create main window XSetWindowAttributes win_attribs; win_attribs.background_pixmap = 0; win_attribs.border_pixel = 0; win_attribs.event_mask = FocusChangeMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; m_x11_window = XCreateWindow(m_x11_display, m_x11_parent_window, 0, 0, cs->window_width, cs->window_height, 0, depth, InputOutput, visual, CWBorderPixel | CWEventMask, &win_attribs ); CE_ASSERT(m_x11_window != None, "Unable to create X window"); // Do we have detectable autorepeat? Bool detectable; m_x11_detectable_autorepeat = (bool) XkbSetDetectableAutoRepeat(m_x11_display, true, &detectable); // Build hidden cursor Pixmap bm_no; XColor black, dummy; Colormap colormap; static char no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; colormap = XDefaultColormap(m_x11_display, screen); XAllocNamedColor(m_x11_display, colormap, "black", &black, &dummy); bm_no = XCreateBitmapFromData(m_x11_display, m_x11_window, no_data, 8, 8); m_x11_hidden_cursor = XCreatePixmapCursor(m_x11_display, bm_no, bm_no, &black, &black, 0, 0); m_wm_delete_message = XInternAtom(m_x11_display, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_x11_display, m_x11_window, &m_wm_delete_message, 1); oswindow_set_window(m_x11_display, m_x11_window); bgfx::x11SetDisplayWindow(m_x11_display, m_x11_window); XMapRaised(m_x11_display, m_x11_window); // Get screen configuration m_screen_config = XRRGetScreenInfo(m_x11_display, RootWindow(m_x11_display, screen)); Rotation rr_old_rot; const SizeID rr_old_sizeid = XRRConfigCurrentConfiguration(m_screen_config, &rr_old_rot); // Start main thread MainThreadArgs mta; mta.fs = fs; mta.cs = cs; Thread main_thread; main_thread.start(func, &mta); while (!s_exit) { pump_events(); } main_thread.stop(); // Restore previous screen configuration if changed Rotation rr_cur_rot; const SizeID rr_cur_sizeid = XRRConfigCurrentConfiguration(m_screen_config, &rr_cur_rot); if (rr_cur_rot != rr_old_rot || rr_cur_sizeid != rr_old_sizeid) { XRRSetScreenConfig(m_x11_display, m_screen_config, RootWindow(m_x11_display, screen), rr_old_sizeid, rr_old_rot, CurrentTime); } XRRFreeScreenConfigInfo(m_screen_config); XDestroyWindow(m_x11_display, m_x11_window); XCloseDisplay(m_x11_display); return EXIT_SUCCESS; }