This morning’s hacking: KDE 4.2 HDMI HDTV Overscan Fix

Ever since I switched to using HDMI/DVI to connect my HDTV to my media box, there has been a slight problem: overscan. The HDTV chops a bit off the edges of the picture, in order to hide any possible graphical rubbish which might be there (quite common with some equipment).

My media box doesn’t have that problem, but unfortunately the TV does not let me turn off the overscan (gah!). This means you cannot see the edges of windows on the desktop, or the task bar etc, which is rather irritating!

What I really want to do is make the display size of the screen slightly smaller than the physical display size – so the overscanned area will simply be filled with black bars. I tried various configuration options in X windows (VirtualSize), but none of them worked. Last night at Disgraceland, I was suddenly struck by inspiration: hacking X to reduce the screen size sounds like a big pain, so why not see if I can hack the window manager (kwin) instead?

As it turns out, this was very easy. The calls to retrieve the screen/desktop dimensions are all implemented by a library called “Kephal”. I just patched “screens.cpp”, recompiled, and stuck it on the PC, and it worked!

The patch is below the cut in case anyone else finds this useful; I saw lots of people asking about this on the web, but never anyone with an actual solution before.


diff -Naur kephal-4.1.96/libs/kephal/kephal/screens.cpp /tmp/kephal-4.1.96/libs/kephal/kephal/screens.cpp
— kephal-4.1.96/libs/kephal/kephal/screens.cpp 2008-11-19 10:17:58.000000000 +0000
+++ /tmp/kephal-4.1.96/libs/kephal/kephal/screens.cpp 2009-01-17 12:18:27.680610113 +0000
@@ -28,6 +28,8 @@
void SCREENS_FACTORY();
#endif

+#define XADJUST 44
+#define YADJUST 25

namespace Kephal {

@@ -80,7 +82,12 @@
}

QRect Screen::geom() {
– return QRect(position(), size());
+ QRect tmp = QRect(position(), size());
+ tmp.setWidth(tmp.width() – XADJUST);
+ tmp.setHeight(tmp.height() – YADJUST);
+ tmp.setX(XADJUST);
+ tmp.setY(YADJUST);
+ return tmp;
}

bool Screen::isPrimary() {
@@ -95,24 +102,39 @@
if (id >= numScreens())
return QRect();

+ QRect tmp;
if (id == -1)
– return QApplication::desktop()->screenGeometry();
+ tmp = QApplication::desktop()->screenGeometry();
else
return Screens::self()->screen(id)->geom();
+ tmp.setWidth(tmp.width() – XADJUST);
+ tmp.setHeight(tmp.height() – YADJUST);
+ tmp.setX(XADJUST);
+ tmp.setY(YADJUST);
+ return tmp;
}

QSize ScreenUtils::screenSize(int id) {
if (id >= numScreens())
return QSize();

+ QSize tmp;
if (id == -1)
– return QApplication::desktop()->screenGeometry().size();
+ tmp = QApplication::desktop()->screenGeometry().size();
else
return Screens::self()->screen(id)->size();
+ tmp.setWidth(tmp.width() – XADJUST);
+ tmp.setHeight(tmp.height() – YADJUST);
+ return tmp;
}

QRect ScreenUtils::desktopGeometry() {
– return QApplication::desktop()->geometry();
+ QRect tmp = QApplication::desktop()->geometry();
+ tmp.setWidth(tmp.width() – XADJUST);
+ tmp.setHeight(tmp.height() – YADJUST);
+ tmp.setX(XADJUST);
+ tmp.setY(YADJUST);
+ return tmp;
}

int ScreenUtils::screenId(QPoint p) {

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: