1 ////////////////////////////////////////////////////////////
2 //
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
23 ////////////////////////////////////////////////////////////
24
25 ////////////////////////////////////////////////////////////
26 // Headers
27 ////////////////////////////////////////////////////////////
28 #include <SFML/Window/VideoModeImpl.hpp>
29 #include <SFML/Window/Unix/Display.hpp>
30 #include <SFML/System/Err.hpp>
31 #include <X11/Xlib.h>
32 #include <X11/extensions/Xrandr.h>
33 #include <algorithm>
34
35
36 namespace sf
37 {
38 namespace priv
39 {
40 ////////////////////////////////////////////////////////////
getFullscreenModes()41 std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
42 {
43 std::vector<VideoMode> modes;
44
45 // Open a connection with the X server
46 Display* display = OpenDisplay();
47 if (display)
48 {
49 // Retrieve the default screen number
50 int screen = DefaultScreen(display);
51
52 // Check if the XRandR extension is present
53 int version;
54 if (XQueryExtension(display, "RANDR", &version, &version, &version))
55 {
56 // Get the current configuration
57 XRRScreenConfiguration* config = XRRGetScreenInfo(display, RootWindow(display, screen));
58 if (config)
59 {
60 // Get the available screen sizes
61 int nbSizes;
62 XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes);
63 if (sizes && (nbSizes > 0))
64 {
65 // Get the list of supported depths
66 int nbDepths = 0;
67 int* depths = XListDepths(display, screen, &nbDepths);
68 if (depths && (nbDepths > 0))
69 {
70 // Combine depths and sizes to fill the array of supported modes
71 for (int i = 0; i < nbDepths; ++i)
72 {
73 for (int j = 0; j < nbSizes; ++j)
74 {
75 // Convert to VideoMode
76 VideoMode mode(sizes[j].width, sizes[j].height, depths[i]);
77
78 Rotation currentRotation;
79 XRRConfigRotations(config, ¤tRotation);
80
81 if (currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270)
82 std::swap(mode.width, mode.height);
83
84 // Add it only if it is not already in the array
85 if (std::find(modes.begin(), modes.end(), mode) == modes.end())
86 modes.push_back(mode);
87 }
88 }
89
90 // Free the array of depths
91 XFree(depths);
92 }
93 }
94
95 // Free the configuration instance
96 XRRFreeScreenConfigInfo(config);
97 }
98 else
99 {
100 // Failed to get the screen configuration
101 err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;
102 }
103 }
104 else
105 {
106 // XRandr extension is not supported: we cannot get the video modes
107 err() << "Failed to use the XRandR extension while trying to get the supported video modes" << std::endl;
108 }
109
110 // Close the connection with the X server
111 CloseDisplay(display);
112 }
113 else
114 {
115 // We couldn't connect to the X server
116 err() << "Failed to connect to the X server while trying to get the supported video modes" << std::endl;
117 }
118
119 return modes;
120 }
121
122
123 ////////////////////////////////////////////////////////////
getDesktopMode()124 VideoMode VideoModeImpl::getDesktopMode()
125 {
126 VideoMode desktopMode;
127
128 // Open a connection with the X server
129 Display* display = OpenDisplay();
130 if (display)
131 {
132 // Retrieve the default screen number
133 int screen = DefaultScreen(display);
134
135 // Check if the XRandR extension is present
136 int version;
137 if (XQueryExtension(display, "RANDR", &version, &version, &version))
138 {
139 // Get the current configuration
140 XRRScreenConfiguration* config = XRRGetScreenInfo(display, RootWindow(display, screen));
141 if (config)
142 {
143 // Get the current video mode
144 Rotation currentRotation;
145 int currentMode = XRRConfigCurrentConfiguration(config, ¤tRotation);
146
147 // Get the available screen sizes
148 int nbSizes;
149 XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes);
150 if (sizes && (nbSizes > 0))
151 {
152 desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, DefaultDepth(display, screen));
153
154 Rotation currentRotation;
155 XRRConfigRotations(config, ¤tRotation);
156
157 if (currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270)
158 std::swap(desktopMode.width, desktopMode.height);
159 }
160
161 // Free the configuration instance
162 XRRFreeScreenConfigInfo(config);
163 }
164 else
165 {
166 // Failed to get the screen configuration
167 err() << "Failed to retrieve the screen configuration while trying to get the desktop video modes" << std::endl;
168 }
169 }
170 else
171 {
172 // XRandr extension is not supported: we cannot get the video modes
173 err() << "Failed to use the XRandR extension while trying to get the desktop video modes" << std::endl;
174 }
175
176 // Close the connection with the X server
177 CloseDisplay(display);
178 }
179 else
180 {
181 // We couldn't connect to the X server
182 err() << "Failed to connect to the X server while trying to get the desktop video modes" << std::endl;
183 }
184
185 return desktopMode;
186 }
187
188 } // namespace priv
189
190 } // namespace sf
191