forked from bartvdbraak/blender
GHOST/X11 support for frequency, from SDL's mode switching.
also free the modes when done.
This commit is contained in:
parent
92189ab353
commit
233b69f0bd
@ -40,7 +40,6 @@
|
||||
#include "GHOST_SystemX11.h"
|
||||
|
||||
|
||||
|
||||
GHOST_DisplayManagerX11::
|
||||
GHOST_DisplayManagerX11(
|
||||
GHOST_SystemX11 *system
|
||||
@ -95,6 +94,17 @@ getNumDisplaySettings(
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
/* from SDL2 */
|
||||
#ifdef WITH_X11_XF86VMODE
|
||||
static int
|
||||
calculate_rate(XF86VidModeModeInfo *info)
|
||||
{
|
||||
return (info->htotal
|
||||
&& info->vtotal) ? (1000 * info->dotclock / (info->htotal *
|
||||
info->vtotal)) : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_DisplayManagerX11::
|
||||
getDisplaySetting(
|
||||
@ -128,6 +138,7 @@ getDisplaySetting(
|
||||
setting.xPixels = vidmodes[index]->hdisplay;
|
||||
setting.yPixels = vidmodes[index]->vdisplay;
|
||||
setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
|
||||
setting.frequency = (float)calculate_rate(vidmodes[index]);
|
||||
|
||||
#else
|
||||
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
|
||||
@ -142,11 +153,9 @@ getDisplaySetting(
|
||||
setting.xPixels = DisplayWidth(x_display, DefaultScreen(x_display));
|
||||
setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display));
|
||||
setting.bpp = DefaultDepth(x_display, DefaultScreen(x_display));
|
||||
setting.frequency = 60.0f;
|
||||
#endif
|
||||
|
||||
/* Don't think it's possible to get this value from X!
|
||||
* So let's guess!! */
|
||||
setting.frequency = 60;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@ -179,7 +188,6 @@ setCurrentDisplaySetting(
|
||||
XF86VidModeModeInfo **vidmodes;
|
||||
Display *dpy = m_system->getXDisplay();
|
||||
int scrnum, num_vidmodes;
|
||||
int best_fit, best_dist, dist, x, y;
|
||||
|
||||
if (dpy == NULL)
|
||||
return GHOST_kFailure;
|
||||
@ -197,41 +205,62 @@ setCurrentDisplaySetting(
|
||||
majorVersion, minorVersion);
|
||||
# endif
|
||||
|
||||
/* The X11 man page says vidmodes needs to be freed, but doing so causes a
|
||||
* segfault. - z0r */
|
||||
XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
|
||||
if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) {
|
||||
int best_fit = -1;
|
||||
|
||||
best_dist = 9999999;
|
||||
best_fit = -1;
|
||||
for (int i = 0; i < num_vidmodes; i++) {
|
||||
if (vidmodes[i]->hdisplay < setting.xPixels ||
|
||||
vidmodes[i]->vdisplay < setting.yPixels)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_vidmodes; i++) {
|
||||
if (setting.xPixels > vidmodes[i]->hdisplay ||
|
||||
setting.yPixels > vidmodes[i]->vdisplay)
|
||||
continue;
|
||||
if (best_fit == -1 ||
|
||||
(vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) ||
|
||||
(vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay &&
|
||||
vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay))
|
||||
{
|
||||
best_fit = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
x = setting.xPixels - vidmodes[i]->hdisplay;
|
||||
y = setting.yPixels - vidmodes[i]->vdisplay;
|
||||
dist = (x * x) + (y * y);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_fit = i;
|
||||
if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) &&
|
||||
(vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay))
|
||||
{
|
||||
if (!setting.frequency) {
|
||||
/* Higher is better, right? */
|
||||
if (calculate_rate(vidmodes[i]) >
|
||||
calculate_rate(vidmodes[best_fit]))
|
||||
{
|
||||
best_fit = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) <
|
||||
abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency))
|
||||
{
|
||||
best_fit = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_fit != -1) {
|
||||
# ifdef _DEBUG
|
||||
int actualWidth, actualHeight;
|
||||
actualWidth = vidmodes[best_fit]->hdisplay;
|
||||
actualHeight = vidmodes[best_fit]->vdisplay;
|
||||
printf("Switching to video mode %dx%d\n",
|
||||
actualWidth, actualHeight);
|
||||
# endif
|
||||
if (best_fit != -1) {
|
||||
# ifdef _DEBUG
|
||||
printf("Switching to video mode %dx%d %dx%d %d\n",
|
||||
vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay,
|
||||
vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal,
|
||||
calculate_rate(vidmodes[best_fit]));
|
||||
# endif
|
||||
|
||||
/* change to the mode */
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
|
||||
/* change to the mode */
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
|
||||
|
||||
/* Move the viewport to top left */
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
/* Move the viewport to top left */
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
}
|
||||
|
||||
XFree(vidmodes);
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
@ -245,7 +274,3 @@ setCurrentDisplaySetting(
|
||||
return GHOST_kSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user