[mythtv] Revised CVS Patch: Xinerama + new over/underscan
mythtv-dev@snowman.net
mythtv-dev@snowman.net
Tue, 17 Dec 2002 13:13:20 -0600 (CST)
--1547859840-1804289383-1040152406=:9739
Content-Type: TEXT/plain; CHARSET=US-ASCII
Ok, here is a revision of my previous patch. It should apply to CVS as
of Dec 17 12:30.
Nothing new. just moved over/underscan out of XvOutput::Show() to a new
function XVoutput:MoveResize. I haven't added true fullscreen yet. I
wanted to get this in first because it is a pain keeping up with all
the other patches going into CVS.
-matthew
--1547859840-1804289383-1040152406=:9739
Content-Type: TEXT/plain; CHARSET=US-ASCII
Content-Disposition: attachment ; filename="patch.txt"
diff -uNr cvs.orig/MC/libs/libNuppelVideo/XJ.cpp cvs/MC/libs/libNuppelVideo/XJ.cpp
--- cvs.orig/MC/libs/libNuppelVideo/XJ.cpp 2002-12-13 21:39:42.000000000 -0600
+++ cvs/MC/libs/libNuppelVideo/XJ.cpp 2002-12-17 12:44:51.000000000 -0600
@@ -16,6 +16,7 @@
#include "XJ.h"
#include "../libmyth/oldsettings.h"
+#include "../libmyth/util.h"
#include <X11/keysym.h>
#include <X11/Xatom.h>
@@ -25,7 +26,6 @@
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
-
extern "C" {
extern int XShmQueryExtension(Display*);
extern int XShmGetEventBase(Display*);
@@ -127,13 +127,37 @@
printf("open display failed\n");
return false;
}
-
+
+
data->XJ_screen = DefaultScreenOfDisplay(data->XJ_disp);
XJ_screen_num = DefaultScreen(data->XJ_disp);
- XJ_screenwidth = DisplayWidth(data->XJ_disp, XJ_screen_num);
- XJ_screenheight = DisplayHeight(data->XJ_disp, XJ_screen_num);
-
+ char *prefix = (char *)PREFIX;
+
+ Settings *settings = new Settings();
+ settings->LoadSettingsFiles(QString("settings.txt"), QString(prefix));
+
+ QString HorizScanMode = settings->GetSetting("HorizScanMode", "overscan");
+ QString VertScanMode = settings->GetSetting("VertScanMode", "overscan");
+
+ img_hscanf = settings->GetNumSetting("HorizScanPercentage", 5) / 100.0;
+ img_vscanf = settings->GetNumSetting("VertScanPercentage",5) / 100.0;
+
+ img_xoff = settings->GetNumSetting("xScanDisplacement", 0);
+ img_yoff = settings->GetNumSetting("yScanDisplacement",0);
+
+
+ if (VertScanMode == "underscan") {
+ img_vscanf = 0 - img_vscanf;
+ }
+ if (HorizScanMode == "underscan") {
+ img_hscanf = 0 - img_hscanf;
+ }
+
+ printf("Over/underscanning. V: %f, H: %f, XOff: %d, YOff: %d\n", img_vscanf,img_hscanf,img_xoff,img_yoff);
+
+ delete settings;
+
XJ_white=XWhitePixel(data->XJ_disp, XJ_screen_num);
XJ_black=XBlackPixel(data->XJ_disp, XJ_screen_num);
@@ -141,7 +165,7 @@
data->XJ_root = DefaultRootWindow(data->XJ_disp);
- curx = 0; cury = 0;
+ GetMythTVGeometry(data->XJ_disp, XJ_screen_num, &curx, &cury, &XJ_screenwidth, &XJ_screenheight);
curw = XJ_width; curh = XJ_height;
dispx = 0; dispy = 0;
@@ -159,7 +183,7 @@
if (createwindow)
{
- data->XJ_win = XCreateSimpleWindow(data->XJ_disp, data->XJ_root, 0, 0,
+ data->XJ_win = XCreateSimpleWindow(data->XJ_disp, data->XJ_root, curx, cury,
XJ_width, XJ_height, 0, XJ_white,
XJ_black);
data->XJ_curwin = data->XJ_win;
@@ -374,21 +398,6 @@
{
pthread_mutex_lock(&lock);
- float HorizScanFactor, VertScanFactor;
- int xScanDisp, yScanDisp;
- char *prefix = (char *)PREFIX;
-
- Settings *settings = new Settings();
- settings->LoadSettingsFiles(QString("settings.txt"), QString(prefix));
-
- QString HorizScanMode = settings->GetSetting("HorizScanMode", "overscan");
- QString VertScanMode = settings->GetSetting("VertScanMode", "overscan");
-
- HorizScanFactor = settings->GetNumSetting("HorizScanPercentage", 5) / 100.0;
- VertScanFactor = settings->GetNumSetting("VertScanPercentage",5) / 100.0;
- xScanDisp = settings->GetNumSetting("xScanDisplacement", 0);
- yScanDisp = settings->GetNumSetting("yScanDisplacement",0);
-
if (XJ_fullscreen)
{
XJ_fullscreen = 0;
@@ -400,66 +409,18 @@
{
XJ_fullscreen = 1;
oldx = curx; oldy = cury; oldw = curw; oldh = curh;
-
- if (VertScanMode == "overscan")
- {
- if (HorizScanMode == "overscan")
- {
- curx = xScanDisp - (int)ceil(XJ_screenwidth * HorizScanFactor);
- curw = (int)ceil(XJ_screenwidth * (1 + 2 * HorizScanFactor));
- }
- else
- {
- curx = xScanDisp + (int)ceil(XJ_screenwidth * HorizScanFactor);
- curw = (int)ceil(XJ_screenwidth * (1 - 2 * HorizScanFactor));
- }
-
- cury = yScanDisp - (int)ceil(XJ_screenheight * VertScanFactor);
- curh = (int)ceil(XJ_screenheight * (1 + 2 * (VertScanFactor + 0.01)));
- }
- else
- {
- if (HorizScanMode == "overscan")
- {
- curx = xScanDisp - (int)ceil(XJ_screenwidth * HorizScanFactor);
- curw = (int)ceil(XJ_screenwidth * (1 + 2 * HorizScanFactor));
- }
- else
- {
- curx = xScanDisp + (int)ceil(XJ_screenwidth * HorizScanFactor);
- curw = (int)ceil(XJ_screenwidth * (1 - 2 * HorizScanFactor));
- }
-
- cury = yScanDisp + (int)ceil(XJ_screenheight * VertScanFactor);
- curh = (int)ceil(XJ_screenheight * (1 - 2 * VertScanFactor));
- }
-
+ curw = XJ_screenwidth;
+ curh = XJ_screenheight;
hide_cursor();
decorate(0);
}
- curx = ((curx - 1) / 2) * 2;
- cury = ((cury - 1) / 2) * 2;
-
- int hclamp = XJ_height / 4;
-
- curh = (int)((rintf(curh) / hclamp) * hclamp) + 4;
- curw = ((curw) / 2) * 2 + 4;
-
dispx = 0;
dispy = 0;
dispw = curw;
disph = curh;
- delete settings;
-
- sizehint(curx, cury, curw, curh, 0);
-
- XMoveResizeWindow(data->XJ_disp, data->XJ_win, curx, cury, curw, curh);
- XMapRaised(data->XJ_disp, data->XJ_win);
-
- XRaiseWindow(data->XJ_disp, data->XJ_win);
- XFlush(data->XJ_disp);
+ MoveResize();
pthread_mutex_unlock(&lock);
}
@@ -520,11 +481,11 @@
memcpy((unsigned char *)image->data + (width * height) * 5 / 4,
scratchspace, width * height / 4);
}
-
+
pthread_mutex_lock(&lock);
XvShmPutImage(data->XJ_disp, xv_port, data->XJ_curwin, data->XJ_gc, image,
- 0, 0, width, height, dispx, dispy, dispw, disph, False);
+ imgx, imgy, imgw, imgh, dispxoff, dispyoff, dispwoff, disphoff, False);
XSync(data->XJ_disp, False);
pthread_mutex_unlock(&lock);
@@ -559,3 +520,104 @@
return key;
}
+
+void XvVideoOutput::MoveResize(void)
+{
+ int yoff, xoff;
+
+ XMoveResizeWindow(data->XJ_disp, data->XJ_win, curx, cury, curw, curh);
+ XMapRaised(data->XJ_disp, data->XJ_win);
+
+ XRaiseWindow(data->XJ_disp, data->XJ_win);
+ XFlush(data->XJ_disp);
+
+ // Preset all image placement and sizing variables.
+ imgx = 0; imgy = 0;
+ imgw = XJ_width; imgh = XJ_height;
+ xoff = img_xoff; yoff = img_yoff;
+ dispxoff = dispx; dispyoff = dispy;
+ dispwoff = dispw; disphoff = disph;
+
+/*
+ Here we apply playback over/underscanning and offsetting (if any apply).
+
+ It doesn't make any sense to me to offset an image such that it is clipped.
+ Therefore, we only apply offsets if there is an underscan or overscan which creates
+ "room" to move the image around. That is, if we overscan, we can move the "viewport".
+ If we underscan, we change where we place the image into the display window. If
+ no over/underscanning is performed, you just get the full original image scaled into
+ the full display area.
+*/
+
+ if (img_vscanf > 0) {
+ // Veritcal overscan. Move the Y start point in original image.
+ imgy = (int)ceil(XJ_height * img_vscanf);
+ imgh = (int)ceil(XJ_height * (1 - 2 * img_vscanf));
+
+ // If there is an offset, apply it now that we have a room.
+ // To move the image down, move the start point up.
+ if(yoff > 0) {
+ // Can't offset the image more than we have overscanned.
+ if(yoff > imgy) yoff = imgy;
+ imgy -= yoff;
+ }
+ // To move the image up, move the start point down.
+ if(yoff < 0) {
+ // Again, can't offset more than overscanned.
+ if( abs(yoff) > imgy ) yoff = 0 - imgy;
+ imgy -= yoff;
+ }
+ }
+
+ if (img_hscanf > 0) {
+ // Horizontal overscan. Move the X start point in original image.
+ imgx = (int)ceil(XJ_width * img_hscanf);
+ imgw = (int)ceil(XJ_width * (1 - 2 * img_hscanf));
+ if(xoff > 0) {
+ if(xoff > imgx) xoff = imgx;
+ imgx -= xoff;
+ }
+ if(xoff < 0) {
+ if( abs(xoff) > imgx ) xoff = 0 - imgx;
+ imgx -= xoff;
+ }
+ }
+
+ float vscanf, hscanf;
+ if (img_vscanf < 0) {
+ // Veritcal underscan. Move the starting Y point in the display window.
+ // Use the abolute value of scan factor.
+ vscanf = fabs(img_vscanf);
+ dispyoff = (int)ceil(disph * vscanf);
+ disphoff = (int)ceil(disph * (1 - 2 * vscanf));
+ // Now offset the image within the extra blank space created by underscanning.
+ // To move the image down, increase the Y offset inside the display window.
+ if(yoff > 0) {
+ // Can't offset more than we have underscanned.
+ if(yoff > dispyoff) yoff = dispyoff;
+ dispyoff += yoff;
+ }
+ if(yoff < 0) {
+ if( abs(yoff) > dispyoff ) yoff = 0 - dispyoff;
+ dispyoff += yoff;
+ }
+ }
+
+ if (img_hscanf < 0) {
+ hscanf = fabs(img_hscanf);
+ dispxoff = (int)ceil(dispw * hscanf);
+ dispwoff = (int)ceil(dispw * (1 - 2 * hscanf));
+ if(xoff > 0) {
+ if(xoff > dispxoff) xoff = dispxoff;
+ dispxoff += xoff;
+ }
+ if(xoff < 0) {
+ if( abs(xoff) > dispxoff ) xoff = 0 - dispxoff;
+ dispxoff += xoff;
+ }
+ }
+
+}
+
+
+
diff -uNr cvs.orig/MC/libs/libNuppelVideo/XJ.h cvs/MC/libs/libNuppelVideo/XJ.h
--- cvs.orig/MC/libs/libNuppelVideo/XJ.h 2002-12-13 21:39:42.000000000 -0600
+++ cvs/MC/libs/libNuppelVideo/XJ.h 2002-12-17 12:44:51.000000000 -0600
@@ -22,6 +22,7 @@
void EmbedInWidget(unsigned long wid, int x, int y, int w, int h);
void StopEmbedding(void);
+ void MoveResize(void);
private:
@@ -45,6 +46,9 @@
int oldx, oldy, oldw, oldh;
int curx, cury, curw, curh;
+ int img_xoff, img_yoff;
+ int imgx, imgy, imgw, imgh, dispxoff, dispyoff, dispwoff, disphoff;
+ float img_hscanf, img_vscanf;
int dispx, dispy, dispw, disph;
int olddispx, olddispy, olddispw, olddisph;
diff -uNr cvs.orig/MC/libs/libmyth/mythwidgets.cpp cvs/MC/libs/libmyth/mythwidgets.cpp
--- cvs.orig/MC/libs/libmyth/mythwidgets.cpp 2002-12-17 00:09:26.000000000 -0600
+++ cvs/MC/libs/libmyth/mythwidgets.cpp 2002-12-17 12:50:25.000000000 -0600
@@ -7,6 +7,7 @@
#include "mythwidgets.h"
#include "mythcontext.h"
+#include "util.h"
void MythComboBox::keyPressEvent(QKeyEvent *e)
{
@@ -283,7 +284,10 @@
context->GetScreenSettings(screenwidth, wmult, screenheight, hmult);
- setGeometry(0, 0, screenwidth, screenheight);
+ int x, y, w, h;
+ GetMythTVGeometry(qt_xdisplay(), qt_xscreen(), &x, &y, &w, &h);
+
+ setGeometry(x, y, screenwidth, screenheight);
setFixedSize(QSize(screenwidth, screenheight));
setFont(QFont("Arial", (int)(context->GetMediumFontSize() * hmult),
diff -uNr cvs.orig/MC/libs/libmyth/util.cpp cvs/MC/libs/libmyth/util.cpp
--- cvs.orig/MC/libs/libmyth/util.cpp 2002-12-16 23:18:19.000000000 -0600
+++ cvs/MC/libs/libmyth/util.cpp 2002-12-17 12:47:47.000000000 -0600
@@ -6,6 +6,13 @@
using namespace std;
#include "util.h"
+#include "../libmyth/oldsettings.h"
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/extensions/Xinerama.h>
+}
+
bool WriteStringList(QSocket *socket, QStringList &list)
{
@@ -120,3 +127,50 @@
return retval;
}
+
+void GetMythTVGeometry(Display *dpy, int screen_num, int *x, int *y, int *w, int *h) {
+ int event_base, error_base;
+
+ char *prefix = (char *)PREFIX;
+
+ Settings *settings = new Settings();
+ settings->LoadSettingsFiles(QString("settings.txt"), QString(prefix));
+
+ if( XineramaQueryExtension(dpy, &event_base, &error_base) &&
+ XineramaIsActive(dpy) ) {
+
+ XineramaScreenInfo *xinerama_screens;
+ XineramaScreenInfo *screen;
+ int nr_xinerama_screens;
+
+ int screen_nr = settings->GetNumSetting("XineramaScreen",0);
+
+ xinerama_screens = XineramaQueryScreens(dpy, &nr_xinerama_screens);
+
+ printf("Found %d Xinerama Screens.\n", nr_xinerama_screens);
+
+ if( screen_nr > 0 && screen_nr < nr_xinerama_screens ) {
+ screen = &xinerama_screens[screen_nr];
+ printf("Using screen %d, %dx%d+%d+%d\n",
+ screen_nr, screen->width, screen->height, screen->x_org, screen->y_org );
+ } else {
+ screen = &xinerama_screens[0];
+ printf("Using first Xinerama screen, %dx%d+%d+%d\n",
+ screen->width, screen->height, screen->x_org, screen->y_org);
+ }
+
+ *w = screen->width;
+ *h = screen->height;
+ *x = screen->x_org;
+ *y = screen->y_org;
+
+ XFree(xinerama_screens);
+ } else {
+ *w = DisplayWidth(dpy, screen_num);
+ *h = DisplayHeight(dpy, screen_num);
+ *x = 0; *y = 0;
+ }
+
+ delete settings;
+}
+
diff -uNr cvs.orig/MC/libs/libmyth/util.h cvs/MC/libs/libmyth/util.h
--- cvs.orig/MC/libs/libmyth/util.h 2002-12-10 04:56:43.000000000 -0600
+++ cvs/MC/libs/libmyth/util.h 2002-12-17 12:48:40.000000000 -0600
@@ -13,4 +13,6 @@
void encodeLongLong(QStringList &list, long long num);
long long decodeLongLong(QStringList &list, int offset);
+void GetMythTVGeometry(Display *dpy, int screen_num, int *x, int *y, int *w, int *h);
+
#endif
diff -uNr cvs.orig/MC/libs/libmythtv/settings.txt cvs/MC/libs/libmythtv/settings.txt
--- cvs.orig/MC/libs/libmythtv/settings.txt 2002-12-14 05:56:57.000000000 -0600
+++ cvs/MC/libs/libmythtv/settings.txt 2002-12-17 13:05:02.000000000 -0600
@@ -62,6 +62,10 @@
# Which input on the tuner card to start on?
str TunerCardInput=Television
+# If using Xinerama, what screen to use?
+# Ignored if not using Xinerama
+int XineramaScreen=0
+
# TV options
#
#
@@ -74,8 +78,8 @@
str VertScanMode=overscan
str HorizScanMode=overscan
# How much do we chop (or add)? %, 0 - 100
-int VertScanPercentage=5
-int HorizScanPercentage=5
+int VertScanPercentage=1
+int HorizScanPercentage=1
# How much do we offset the picture?
int xScanDisplacement=0
int yScanDisplacement=0
diff -uNr cvs.orig/MC/programs/mythbackend/mythbackend.pro cvs/MC/programs/mythbackend/mythbackend.pro
--- cvs.orig/MC/programs/mythbackend/mythbackend.pro 2002-12-12 02:44:15.000000000 -0600
+++ cvs/MC/programs/mythbackend/mythbackend.pro 2002-12-17 12:52:13.000000000 -0600
@@ -20,7 +20,7 @@
LIBS += -L../../libs/libmythtv -L../../libs/libNuppelVideo
LIBS += -L../../libs/libavcodec -L../../libs/libmyth
-LIBS += -lmythtv -lNuppelVideo -lavcodec -lmyth-$$LIBVERSION -lXv -lmp3lame
+LIBS += -lmythtv -lNuppelVideo -lavcodec -lmyth-$$LIBVERSION -lXv -lXinerama -lmp3lame
TARGETDEPS = ../../libs/libNuppelVideo/libNuppelVideo.a
TARGETDEPS += ../../libs/libmythtv/libmythtv.a
diff -uNr cvs.orig/MC/programs/mythfrontend/mythfrontend.pro cvs/MC/programs/mythfrontend/mythfrontend.pro
--- cvs.orig/MC/programs/mythfrontend/mythfrontend.pro 2002-12-08 23:37:04.000000000 -0600
+++ cvs/MC/programs/mythfrontend/mythfrontend.pro 2002-12-17 12:51:53.000000000 -0600
@@ -21,7 +21,7 @@
LIBS += -L../../libs/libmythtv -L../../libs/libNuppelVideo
LIBS += -L../../libs/libavcodec -L../../libs/libmyth
-LIBS += -lmythtv -lNuppelVideo -lavcodec -lmyth-$$LIBVERSION -lXv -lmp3lame
+LIBS += -lmythtv -lNuppelVideo -lavcodec -lmyth-$$LIBVERSION -lXv -lXinerama -lmp3lame
TARGETDEPS = ../../libs/libNuppelVideo/libNuppelVideo.a
TARGETDEPS += ../../libs/libmythtv/libmythtv.a
diff -uNr cvs.orig/MC/programs/mythtv/mythtv.pro cvs/MC/programs/mythtv/mythtv.pro
--- cvs.orig/MC/programs/mythtv/mythtv.pro 2002-10-28 22:58:52.000000000 -0600
+++ cvs/MC/programs/mythtv/mythtv.pro 2002-12-17 12:44:51.000000000 -0600
@@ -14,7 +14,7 @@
LIBS += -L../../libs/libNuppelVideo -L../../libs/libmythtv
LIBS += -L../../libs/libavcodec -L../../libs/libmyth
-LIBS += -lmythtv -lNuppelVideo -lavcodec -lmyth-$$LIBVERSION -lXv -lmp3lame
+LIBS += -lmythtv -lNuppelVideo -lavcodec -lmyth-$$LIBVERSION -lXv -lXinerama -lmp3lame
TARGETDEPS = ../../libs/libNuppelVideo/libNuppelVideo.a
TARGETDEPS += ../../libs/libmythtv/libmythtv.a
--1547859840-1804289383-1040152406=:9739--