115 lines
2.9 KiB
C++
115 lines
2.9 KiB
C++
|
|
#include <Spectre/System/Log.h>
|
|
#include <Platform/PlatformMisc.h>
|
|
#include "X11SharedDisplay.h"
|
|
#include <X11/Xlib.h>
|
|
#include <X11/extensions/Xrandr.h>
|
|
#include <algorithm>
|
|
|
|
namespace sp {
|
|
|
|
// Code "borrowed" from SFML :)
|
|
// see: https://github.com/SFML/SFML/blob/master/src/SFML/Window/Unix/VideoModeImpl.cpp
|
|
|
|
void PlatformMisc::GetDisplayModes(std::vector<DisplayMode>& modes)
|
|
{
|
|
::Display *disp = XGetDisplay();
|
|
|
|
if (disp) {
|
|
int scr = DefaultScreen(disp);
|
|
|
|
// Check for XRandR.
|
|
int ver;
|
|
if (XQueryExtension(disp, "RANDR", &ver, &ver, &ver)) {
|
|
|
|
XRRScreenConfiguration* config = ::XRRGetScreenInfo(disp, RootWindow(disp, scr));
|
|
if (config) {
|
|
int nbSizes;
|
|
XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes);
|
|
if (sizes && nbSizes > 0) {
|
|
int nbDepths = 0;
|
|
int* depths = XListDepths(disp, scr, &nbDepths);
|
|
if (depths && nbDepths > 0) {
|
|
|
|
for(int i = 0; i < nbDepths; i++) {
|
|
for(int j = 0; j < nbSizes; j++) {
|
|
DisplayMode mode(sizes[j].width, sizes[j].height, depths[i]);
|
|
|
|
::Rotation rot;
|
|
XRRConfigRotations(config, &rot);
|
|
|
|
if (rot == RR_Rotate_90 || rot == RR_Rotate_270) {
|
|
std::swap(mode.width, mode.height);
|
|
}
|
|
|
|
if (std::find(modes.begin(), modes.end(), mode) == modes.end()) {
|
|
modes.push_back(mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
XFree(depths);
|
|
}
|
|
}
|
|
} else {
|
|
Log::error("Failed to get screen configuration while trying to get display modes.");
|
|
}
|
|
|
|
XRRFreeScreenConfigInfo(config);
|
|
} else {
|
|
Log::error("Failed to use XRandR extension while trying to get display modes.");
|
|
}
|
|
|
|
XReleaseDisplay(disp);
|
|
} else {
|
|
Log::error("Failed to connect to the X server while trying to get display modes.");
|
|
}
|
|
}
|
|
|
|
DisplayMode PlatformMisc::GetDesktopMode()
|
|
{
|
|
DisplayMode mode;
|
|
|
|
::Display *disp = XGetDisplay();
|
|
|
|
if (disp) {
|
|
int scr = DefaultScreen(disp);
|
|
|
|
// Check for XRandR.
|
|
int ver;
|
|
if (XQueryExtension(disp, "RANDR", &ver, &ver, &ver)) {
|
|
|
|
XRRScreenConfiguration* config = ::XRRGetScreenInfo(disp, RootWindow(disp, scr));
|
|
if (config) {
|
|
int nbSizes;
|
|
::Rotation rot;
|
|
int current = XRRConfigCurrentConfiguration(config, &rot);
|
|
|
|
XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes);
|
|
if (sizes && nbSizes > 0) {
|
|
|
|
mode = DisplayMode(sizes[current].width, sizes[current].height, DefaultDepth(disp, scr));
|
|
|
|
XRRConfigRotations(config, &rot);
|
|
if (rot == RR_Rotate_90 || rot == RR_Rotate_270) {
|
|
std::swap(mode.width, mode.height);
|
|
}
|
|
}
|
|
} else {
|
|
Log::error("Failed to get screen configuration while trying to get desktop display mode.");
|
|
}
|
|
|
|
XRRFreeScreenConfigInfo(config);
|
|
} else {
|
|
Log::error("Failed to use XRandR extension while trying to get desktop display mode.");
|
|
}
|
|
|
|
XReleaseDisplay(disp);
|
|
} else {
|
|
Log::error("Failed to connect to the X server while trying to get desktop display mode.");
|
|
}
|
|
|
|
return mode;
|
|
}
|
|
|
|
} // namespace sp
|