1
0
Fork 0
spectre/source/Platform/Unix/UnixMisc.cpp

110 lines
2.8 KiB
C++

#include <Spectre/System/Log.h>
#include <Platform/PlatformMisc.h>
#include "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 = Xlib::getDisplay();
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.");
}
} else {
Log::error("Failed to connect to the X server while trying to get display modes.");
}
}
DisplayMode PlatformMisc::GetDesktopMode()
{
DisplayMode mode;
::Display *disp = Xlib::getDisplay();
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.");
}
} else {
Log::error("Failed to connect to the X server while trying to get desktop display mode.");
}
return mode;
}
} // namespace sp