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