/** * Queries all the available modes in the display configuration. */ RRInfo() : _numSizes(0) { _conf = XRRGetScreenInfo(QX11Info::display(), QX11Info::appRootWindow()); if(!_conf) return; // Not available. // Let's see which modes are available. _sizes = XRRConfigSizes(_conf, &_numSizes); for(int i = 0; i < _numSizes; ++i) { int numRates = 0; short* rates = XRRConfigRates(_conf, i, &numRates); for(int k = 0; k < numRates; k++) { DisplayMode mode; de::zap(mode); mode.width = _sizes[i].width; mode.height = _sizes[i].height; mode.depth = displayDepth; mode.refreshRate = rates[k]; _modes.push_back(mode); } } ::Time prevConfTime; _confTime = XRRConfigTimes(_conf, &prevConfTime); }
int find(const DisplayMode* mode) const { for(int i = 0; i < _numSizes; ++i) { int numRates = 0; short* rates = XRRConfigRates(_conf, i, &numRates); for(int k = 0; k < numRates; k++) { if(rateFromMode(mode) == rates[k] && mode->width == _sizes[i].width && mode->height == _sizes[i].height) { // This is the one. return i; } } } return -1; }
void QxtScreenPrivate::init_sys() { #ifdef HAVE_XRANDR Display* display = XOpenDisplay(NULL); Window root = RootWindow(display, screen); XRRScreenConfiguration* config = XRRGetScreenInfo(display, root); // available resolutions & rates if (availResos.isEmpty() || availRates.isEmpty()) { availResos.clear(); availRates.clear(); int sizeCount = 0; XRRScreenSize* sizes = XRRSizes(display, 0, &sizeCount); for (int i = 0; i < sizeCount; ++i) { QSize reso(sizes[i].width, sizes[i].height); if (!availResos.contains(reso)) availResos += reso; int rateCount = 0; short* rates = XRRConfigRates(config, i, &rateCount); for (int j = 0; j < rateCount; ++j) availRates.insertMulti(reso, rates[j]); } } // current resolution & rate if (!currReso.isValid() || currRate < 0) { Rotation rotation; SizeID sizeId = XRRConfigCurrentConfiguration(config, &rotation); currReso = availResos.at(sizeId); currRate = XRRConfigCurrentRate(config); } XRRFreeScreenConfigInfo(config); XCloseDisplay(display); #endif // HAVE_XRANDR }
XRandRToggler::XRandRToggler() : config(XRRGetScreenInfo(QX11Info::display(), QX11Info::appRootWindow())), originalResIndex(0), fullResIndex(0), rotation(0), fullRateIndex(0), originalRate(0), isFull(false) { fullResIndex = originalResIndex = XRRConfigCurrentConfiguration(config, &rotation); originalRate = XRRConfigCurrentRate(config); int nSizes; XRRScreenSize *randrSizes = XRRConfigSizes(config, &nSizes); for (int i = 0; i < nSizes; ++i) { ResInfo info; info.w = randrSizes[i].width; info.h = randrSizes[i].height; int nHz; short *rates = XRRConfigRates(config, i, &nHz); for (int j = 0; j < nHz; ++j) info.rates.push_back(rates[j] * 10); infoVector.push_back(info); } { unsigned i = 0; while (i < infoVector[fullResIndex].rates.size() && infoVector[fullResIndex].rates[i] != originalRate * 10) ++i; if (i == infoVector[fullResIndex].rates.size()) infoVector[fullResIndex].rates.push_back(originalRate * 10); fullRateIndex = i; } }
X11EGLSupport::X11EGLSupport() { mNativeDisplay = getNativeDisplay(); mGLDisplay = getGLDisplay(); int dummy; if (XQueryExtension((Display*)mNativeDisplay, "RANDR", &dummy, &dummy, &dummy)) { XRRScreenConfiguration *screenConfig; mRandr = true; screenConfig = XRRGetScreenInfo((Display*)mNativeDisplay, DefaultRootWindow((Display*)mNativeDisplay)); if (screenConfig) { XRRScreenSize *screenSizes; int nSizes = 0; Rotation currentRotation; int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, ¤tRotation); screenSizes = XRRConfigSizes(screenConfig, &nSizes); mCurrentMode.first.first = screenSizes[currentSizeID].width; mCurrentMode.first.second = screenSizes[currentSizeID].height; mCurrentMode.second = XRRConfigCurrentRate(screenConfig); mOriginalMode = mCurrentMode; for (int sizeID = 0; sizeID < nSizes; sizeID++) { short *rates; int nRates = 0; rates = XRRConfigRates(screenConfig, sizeID, &nRates); for (int rate = 0; rate < nRates; rate++) { VideoMode mode; mode.first.first = screenSizes[sizeID].width; mode.first.second = screenSizes[sizeID].height; mode.second = rates[rate]; mVideoModes.push_back(mode); } } XRRFreeScreenConfigInfo(screenConfig); } } else { mCurrentMode.first.first = DisplayWidth((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay)); mCurrentMode.first.second = DisplayHeight((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay)); mCurrentMode.second = 0; mOriginalMode = mCurrentMode; mVideoModes.push_back(mCurrentMode); } EGLConfig *glConfigs; int config, nConfigs = 0; glConfigs = chooseGLConfig(NULL, &nConfigs); for (config = 0; config < nConfigs; config++) { int caveat, samples; getGLConfigAttrib(glConfigs[config], EGL_CONFIG_CAVEAT, &caveat); if (caveat != EGL_SLOW_CONFIG) { getGLConfigAttrib(glConfigs[config], EGL_SAMPLES, &samples); mSampleLevels.push_back(StringConverter::toString(samples)); } } free(glConfigs); removeDuplicates(mSampleLevels); }
int _glfwGetClosestVideoMode(int* width, int* height, int* rate) { int i, match, bestmatch; if (_glfwLibrary.X11.RandR.available) { #if defined(_GLFW_HAS_XRANDR) int sizecount, bestsize; int ratecount, bestrate; short* ratelist; XRRScreenConfiguration* sc; XRRScreenSize* sizelist; sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); sizelist = XRRConfigSizes(sc, &sizecount); // Find the best matching mode bestsize = -1; bestmatch = INT_MAX; for (i = 0; i < sizecount; i++) { match = (*width - sizelist[i].width) * (*width - sizelist[i].width) + (*height - sizelist[i].height) * (*height - sizelist[i].height); if (match < bestmatch) { bestmatch = match; bestsize = i; } } if (bestsize != -1) { // Report width & height of best matching mode *width = sizelist[bestsize].width; *height = sizelist[bestsize].height; if (*rate > 0) { ratelist = XRRConfigRates(sc, bestsize, &ratecount); bestrate = -1; bestmatch = INT_MAX; for (i = 0; i < ratecount; i++) { match = abs(ratelist[i] - *rate); if (match < bestmatch) { bestmatch = match; bestrate = ratelist[i]; } } if (bestrate != -1) *rate = bestrate; } } XRRFreeScreenConfigInfo(sc); if (bestsize != -1) return bestsize; #endif /*_GLFW_HAS_XRANDR*/ } else if (_glfwLibrary.X11.VidMode.available) { #if defined(_GLFW_HAS_XF86VIDMODE) XF86VidModeModeInfo** modelist; int bestmode, modecount; // Get a list of all available display modes XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, _glfwLibrary.X11.screen, &modecount, &modelist); // Find the best matching mode bestmode = -1; bestmatch = INT_MAX; for (i = 0; i < modecount; i++) { match = (*width - modelist[i]->hdisplay) * (*width - modelist[i]->hdisplay) + (*height - modelist[i]->vdisplay) * (*height - modelist[i]->vdisplay); if (match < bestmatch) { bestmatch = match; bestmode = i; } } if (bestmode != -1) { // Report width & height of best matching mode *width = modelist[bestmode]->hdisplay; *height = modelist[bestmode]->vdisplay; } XFree(modelist); if (bestmode != -1) return bestmode; #endif /*_GLFW_HAS_XF86VIDMODE*/ } // Default: Simply use the screen resolution *width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); *height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); return 0; }
JNIEXPORT jobjectArray JNICALL Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetDisplayModes (JNIEnv *env, jobject obj __attribute__((unused)), jobject gdkGraphicsEnv __attribute__((unused))) { #ifdef HAVE_XRANDR GdkDisplay *display; XRRScreenConfiguration *config; XRRScreenSize *screenSizes; int nsizes = 0, nrates = 0, i = 0; jclass x11DisplayMode_class; jmethodID x11DisplayMode_ctor; jobjectArray array; jobject instance; short *rates; jshortArray shortArray; display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, gdkGraphicsEnv); gdk_threads_enter(); config = XRRGetScreenInfo (GDK_DISPLAY_XDISPLAY(display), GDK_ROOT_WINDOW()); screenSizes = XRRConfigSizes(config, &nsizes); x11DisplayMode_class = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice$X11DisplayMode"); x11DisplayMode_ctor = (*env)->GetMethodID(env, x11DisplayMode_class, "<init>", "(II[S)V"); array = (*env)->NewObjectArray(env, nsizes, x11DisplayMode_class, NULL); for (; i < nsizes ; i++) { /* Retrieves refresh rate information. */ rates = XRRConfigRates(config, i, &nrates); /* Create a Java short array and put them in. */ shortArray = (*env)->NewShortArray(env, nrates); (*env)->SetShortArrayRegion(env, shortArray, 0, nrates, (jshort *) rates); /* Create a GdkScreenGraphicsDevice.X11DisplayMode instance. */ instance = (*env)->NewObject(env, x11DisplayMode_class, x11DisplayMode_ctor, screenSizes[i].width, screenSizes[i].height, shortArray); /* Put it into the result array. */ (*env)->SetObjectArrayElement(env, array, i, instance); } /* Free everything acquired by xlib. */ XRRFreeScreenConfigInfo (config); gdk_threads_leave(); return array; #else JCL_ThrowException(env, "java/lang/InternalError", "Method should not have been invoked."); return NULL; #endif }
//-------------------------------------------------------------------------------------------------// GLXGLSupport::GLXGLSupport() : mGLDisplay(0), mXDisplay(0) { // A connection that might be shared with the application for GL rendering: mGLDisplay = getGLDisplay(); // A connection that is NOT shared to enable independent event processing: mXDisplay = getXDisplay(); int dummy; if (XQueryExtension(mXDisplay, "RANDR", &dummy, &dummy, &dummy)) { XRRScreenConfiguration *screenConfig; screenConfig = XRRGetScreenInfo(mXDisplay, DefaultRootWindow(mXDisplay)); if (screenConfig) { XRRScreenSize *screenSizes; int nSizes = 0; Rotation currentRotation; int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, ¤tRotation); screenSizes = XRRConfigSizes(screenConfig, &nSizes); mCurrentMode.first.first = screenSizes[currentSizeID].width; mCurrentMode.first.second = screenSizes[currentSizeID].height; mCurrentMode.second = XRRConfigCurrentRate(screenConfig); mOriginalMode = mCurrentMode; for(int sizeID = 0; sizeID < nSizes; sizeID++) { short *rates; int nRates = 0; rates = XRRConfigRates(screenConfig, sizeID, &nRates); for (int rate = 0; rate < nRates; rate++) { VideoMode mode; mode.first.first = screenSizes[sizeID].width; mode.first.second = screenSizes[sizeID].height; mode.second = rates[rate]; mVideoModes.push_back(mode); } } XRRFreeScreenConfigInfo(screenConfig); } } else { mCurrentMode.first.first = DisplayWidth(mXDisplay, DefaultScreen(mXDisplay)); mCurrentMode.first.second = DisplayHeight(mXDisplay, DefaultScreen(mXDisplay)); mCurrentMode.second = 0; mOriginalMode = mCurrentMode; mVideoModes.push_back(mCurrentMode); } GLXFBConfig *fbConfigs; int config, nConfigs = 0; fbConfigs = chooseFBConfig(NULL, &nConfigs); for (config = 0; config < nConfigs; config++) { int caveat, samples; getFBConfigAttrib (fbConfigs[config], GLX_CONFIG_CAVEAT, &caveat); if (caveat != GLX_SLOW_CONFIG) { getFBConfigAttrib (fbConfigs[config], GLX_SAMPLES, &samples); mSampleLevels.push_back(StringConverter::toString(samples)); } } XFree (fbConfigs); remove_duplicates(mSampleLevels); }
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; }