You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/krdc/vidmode.cpp

160 lines
4.0 KiB

/***************************************************************************
vidmode.cpp - video mode switching
-------------------
begin : Tue June 3 03:08:00 CET 2002
copyright : (C) 2002 by Tim Jansen
email : tim@tjansen.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <config.h>
#include <X11/Xlib.h>
#ifdef HAVE_VIDMODE_EXTENSION
#include <X11/extensions/xf86vmode.h>
#endif
#include "vidmode.h"
#ifdef HAVE_VIDMODE_EXTENSION
void vidmodeNormalSwitch(Display *dpy, Resolution oldResolution)
{
if (!oldResolution.valid)
return;
XF86VidModeModeInfo **modes;
int modecount;
int eventB, errorB;
if (!XF86VidModeQueryExtension(dpy, &eventB, &errorB))
return;
if (!XF86VidModeGetAllModeLines(dpy, oldResolution.screen, &modecount, &modes))
return;
for (int i = 0; i < modecount; i++) {
int w = (*modes[i]).hdisplay;
int h = (*modes[i]).vdisplay;
if ((oldResolution.width == w) &&
(oldResolution.height == h)) {
XF86VidModeSwitchToMode(dpy,oldResolution.screen,modes[i]);
XFlush(dpy);
XF86VidModeSetViewPort(dpy,DefaultScreen(dpy),0,0);
XFlush(dpy);
return;
}
}
}
Resolution vidmodeFullscreenSwitch(Display *dpy, int screen,
int sw, int sh, int &nx, int &ny)
{
XF86VidModeModeInfo **modes;
int modecount;
int bestmode = -1;
int bestw, besth;
int eventB, errorB;
if (screen < 0)
return Resolution();
if (!XF86VidModeQueryExtension(dpy, &eventB, &errorB))
return Resolution();
if (!XF86VidModeGetAllModeLines(dpy,screen,&modecount, &modes))
return Resolution();
int cw = (*modes[0]).hdisplay;
int ch = (*modes[0]).vdisplay;
nx = cw;
ny = ch;
if ((cw == sw) && (ch == sh))
return Resolution();
bool foundLargeEnoughRes = (cw>=sw) && (ch>=sh);
bestw = cw;
besth = ch;
for (int i = 1; i < modecount; i++) {
int w = (*modes[i]).hdisplay;
int h = (*modes[i]).vdisplay;
if ((w == cw) && (h == ch))
continue;
/* If resolution matches framebuffer, take it */
if ((w == sw) && (h == sh)) {
bestw = w;
besth = h;
bestmode = i;
break;
}
/* if resolution larger than framebuffer... */
if ((w>=sw) && (h>=sh)) {
/* and no other previously found resoltion was smaller or
this is smaller than the best resolution so far, take it*/
if ((!foundLargeEnoughRes) ||
(w*h < bestw*besth)) {
bestw = w;
besth = h;
bestmode = i;
foundLargeEnoughRes = true;
}
}
/* If all resolutions so far were smaller than framebuffer... */
else if (!foundLargeEnoughRes) {
/* take this one it it is bigger then they were */
if (w*h > bestw*besth) {
bestw = w;
besth = h;
bestmode = i;
}
}
}
if (bestmode == -1)
return Resolution();
nx = bestw;
ny = besth;
XF86VidModeSwitchToMode(dpy,screen,modes[bestmode]);
XF86VidModeSetViewPort(dpy,screen,0,0);
XFlush(dpy);
return Resolution(cw, ch, screen);
}
#else
void vidmodeNormalSwitch(Display *dpy, Resolution oldResolution)
{
}
Resolution vidmodeFullscreenSwitch(Display *dpy, int screen, int sw, int sh, int &nx, int &ny)
{
return Resolution();
}
#endif
void grabInput(Display *dpy, unsigned int winId) {
XGrabPointer(dpy, winId, True, 0,
GrabModeAsync, GrabModeAsync,
winId, None, CurrentTime);
XFlush(dpy);
}
void ungrabInput(Display *dpy) {
XUngrabPointer(dpy, CurrentTime);
}