1 #include "displaywrapper.h"
2
3 DisplayWrapper DisplayWrapper::dwrapper;
4
5 #ifdef Q_OS_WIN32
6
DisplayWrapper()7 DisplayWrapper::DisplayWrapper()
8 {
9 }
10
~DisplayWrapper()11 DisplayWrapper::~DisplayWrapper()
12 {
13 }
14
dw_init(bool filter,int minWidth,int minHeight)15 void DisplayWrapper::dw_init(bool filter, int minWidth, int minHeight)
16 {
17 base_height = base_width = 0;
18 base_bpp = 0;
19
20 DEVMODE devmode;
21 DWORD modenum = 0;
22 VideoModeInfo mode;
23
24 while (EnumDisplaySettings(NULL, modenum, &devmode))
25 {
26 if (devmode.dmPelsWidth >= minWidth && devmode.dmPelsHeight >= minHeight)
27 {
28 modeNames.append(QString("%1 x %2")
29 .arg(devmode.dmPelsWidth)
30 .arg(devmode.dmPelsHeight)
31 );
32
33 mode.width = devmode.dmPelsWidth;
34 mode.height = devmode.dmPelsHeight;
35 mode.bpp = devmode.dmBitsPerPel;
36 modes.append(mode);
37 }
38 modenum++;
39 }
40
41 if (filter)
42 modeNames.removeDuplicates();
43 }
44
dw_switchMode(int w,int h,int bpp,bool fs)45 bool DisplayWrapper::dw_switchMode(int w, int h, int bpp, bool fs)
46 {
47 DEVMODE originalMode;
48 originalMode.dmSize = sizeof(originalMode);
49
50 EnumDisplaySettings(0,
51 ENUM_CURRENT_SETTINGS,
52 &originalMode);
53
54 DEVMODE newMode = originalMode;
55
56 bool downgrade = false;
57
58 // Changing the settings
59 newMode.dmPelsWidth = (uint)w;
60 newMode.dmPelsHeight = (uint)h;
61 if (bpp > 0)
62 newMode.dmBitsPerPel = (uint)bpp;
63 else {
64 newMode.dmBitsPerPel = 32;
65 downgrade = true;
66 }
67
68 DWORD flags = 0;
69 if (fs) flags |= CDS_FULLSCREEN;
70 long res = ChangeDisplaySettings(&newMode, flags);
71 if (res == DISP_CHANGE_SUCCESSFUL) return true;
72
73 if (downgrade)
74 {
75 // 24
76 newMode.dmBitsPerPel = 24;
77 res = ChangeDisplaySettings(&newMode, flags);
78 if (res == DISP_CHANGE_SUCCESSFUL) return true;
79
80 // 16
81 newMode.dmBitsPerPel = 16;
82 res = ChangeDisplaySettings(&newMode, flags);
83 if (res == DISP_CHANGE_SUCCESSFUL) return true;
84
85 // 8
86 newMode.dmBitsPerPel = 8;
87 res = ChangeDisplaySettings(&newMode, flags);
88 if (res == DISP_CHANGE_SUCCESSFUL) return true;
89 }
90
91 return false;
92 }
93
dw_restoreMode()94 void DisplayWrapper::dw_restoreMode()
95 {
96 ChangeDisplaySettings(0,0);
97 }
98
dw_currentMode()99 VideoModeInfo DisplayWrapper::dw_currentMode()
100 {
101 DEVMODE devmode;
102 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
103 VideoModeInfo mode;
104 mode.width = devmode.dmPelsWidth;
105 mode.height = devmode.dmPelsHeight;
106 mode.bpp = devmode.dmBitsPerPel;
107 return mode;
108 }
109
110 #else
111
DisplayWrapper()112 DisplayWrapper::DisplayWrapper()
113 {
114 base_height = base_width = 0;
115 base_bpp = 0;
116 }
117
~DisplayWrapper()118 DisplayWrapper::~DisplayWrapper()
119 {
120 }
121
dw_init(bool filter,int minWidth,int minHeight)122 void DisplayWrapper::dw_init(bool filter, int minWidth, int minHeight)
123 {
124 VideoModeInfo mode;
125
126 int num_sizes;
127 Rotation original_rotation;
128
129 Display *dpy = XOpenDisplay(NULL);
130 Window root = RootWindow(dpy, 0);
131 XRRScreenSize *xrrs = XRRSizes(dpy, 0, &num_sizes);
132 //
133 // GET CURRENT RESOLUTION AND FREQUENCY
134 //
135 XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
136 short original_rate = XRRConfigCurrentRate(conf);
137 SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
138
139 XCloseDisplay(dpy);
140
141 for (int i = 0; i < num_sizes; i++)
142 {
143 int width = xrrs[i].width;
144 int height = xrrs[i].height;
145
146 if (width >= minWidth && height >= minHeight)
147 {
148 modeNames.append(QString("%1 x %2")
149 .arg(width)
150 .arg(height)
151 );
152
153 mode.width = width;
154 mode.height = height;
155 mode.bpp = 32; // #### How to know BPP from XRandr ???
156 modes.append(mode);
157 }
158 }
159
160 if (filter)
161 modeNames.removeDuplicates();
162
163 }
164
dw_switchMode(int w,int h,int bpp,bool fs)165 bool DisplayWrapper::dw_switchMode(int w, int h, int bpp, bool fs)
166 {
167 if (!base_height || !base_width)
168 {
169 XRRScreenConfiguration * info = XRRGetScreenInfo (QX11Info::display(), QX11Info::appRootWindow());
170 if (!info)
171 return false;
172
173 int numSizes;
174 XRRScreenSize * sizes = XRRConfigSizes(info, &numSizes);
175 if (!numSizes)
176 return false;
177
178 base_width = sizes->width;
179 base_height = sizes->height;
180
181 XRRFreeScreenConfigInfo(info);
182 }
183
184 QStringList args; args << "--size" << QString("%1x%2").arg(w).arg(h);
185 QProcess::execute("xrandr", args);
186
187 return true;
188 }
189
dw_restoreMode()190 void DisplayWrapper::dw_restoreMode()
191 {
192 if (base_height && base_width)
193 dw_switchMode(base_width, base_height, base_bpp, true);
194 }
195
196 #endif
197