summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/util/render/x11
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch)
tree9047cf9e6b5c43878d5bf82660adae77ceee097a /mpeglib/lib/util/render/x11
downloadtdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz
tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'mpeglib/lib/util/render/x11')
-rw-r--r--mpeglib/lib/util/render/x11/Makefile.am48
-rw-r--r--mpeglib/lib/util/render/x11/imageDGAFull.cpp289
-rw-r--r--mpeglib/lib/util/render/x11/imageDGAFull.h131
-rw-r--r--mpeglib/lib/util/render/x11/imageDeskX11.cpp439
-rw-r--r--mpeglib/lib/util/render/x11/imageDeskX11.h85
-rw-r--r--mpeglib/lib/util/render/x11/imageXVDesk.cpp405
-rw-r--r--mpeglib/lib/util/render/x11/imageXVDesk.h88
-rw-r--r--mpeglib/lib/util/render/x11/initDisplay.cpp255
-rw-r--r--mpeglib/lib/util/render/x11/initDisplay.h34
-rw-r--r--mpeglib/lib/util/render/x11/x11Surface.cpp389
-rw-r--r--mpeglib/lib/util/render/x11/x11Surface.h79
-rw-r--r--mpeglib/lib/util/render/x11/xinit.h99
12 files changed, 2341 insertions, 0 deletions
diff --git a/mpeglib/lib/util/render/x11/Makefile.am b/mpeglib/lib/util/render/x11/Makefile.am
new file mode 100644
index 00000000..97ab0d67
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/Makefile.am
@@ -0,0 +1,48 @@
+# player - Makefile.am
+
+INCLUDES = $(all_includes)
+
+
+noinst_LTLIBRARIES = libutilx11.la
+
+
+noinst_HEADERS = initDisplay.h \
+ imageDeskX11.h imageDGAFull.h \
+ imageXVDesk.h x11Surface.h xinit.h
+
+libutilx11_la_SOURCES = initDisplay.cpp \
+ imageDeskX11.cpp \
+ imageDGAFull.cpp imageXVDesk.cpp \
+ x11Surface.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/x11/imageDGAFull.cpp b/mpeglib/lib/util/render/x11/imageDGAFull.cpp
new file mode 100644
index 00000000..6e07b658
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDGAFull.cpp
@@ -0,0 +1,289 @@
+/*
+ xfree 4.0 dga fullscreen mode
+ Copyright (C) 2000 Martin Vogt, Christian Gerlach
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "imageDGAFull.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageDGAFull::ImageDGAFull() {
+
+ m_iMode = -1;
+ m_bIsActive = false;
+ lSupport=false;
+ m_pxWindow = NULL;
+ m_iImageMode = _IMAGE_NONE;
+ ditherWrapper=NULL;
+ supportedModes = _IMAGE_NONE;
+ setIdentifier("DGA");
+}
+
+
+ImageDGAFull::~ImageDGAFull() {
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+}
+
+void ImageDGAFull::init(XWindow *xWindow, YUVPicture*)
+{
+ int uid;
+
+ m_pxWindow = xWindow;
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new DitherWrapper(xWindow->depth,
+ xWindow->redMask,
+ xWindow->greenMask,
+ xWindow->blueMask,
+ xWindow->pixel);
+ }
+
+#ifndef X11_DGA2
+ return;
+#endif
+
+#ifdef X11_DGA2
+ m_pDGAModes=NULL;
+ m_iNumberModes = 0;
+
+ m_iVideoWidth = xWindow->width;
+ m_iVideoHeight = xWindow->height;
+ uid=getuid();
+ if (uid != 0) {
+ //cout << "you are :"<<uid<<" and not root(0). DGA 2.0 needs root"<<endl;
+ return;
+ }
+
+ if ((m_pDisplay =xWindow->display)==NULL ) {
+ fprintf( stderr, " cannot connect to X server %s\n", XDisplayName(NULL));
+ return;
+ }
+
+ m_iScreen = DefaultScreen(xWindow->display);
+
+
+ if (!XF86DGAQueryVersion(xWindow->display,
+ &m_iMajorVersion, &m_iMinorVersion)) {
+ fprintf(stderr, "Unable to query video extension version\n");
+ return ;
+ }
+ printf("DGA version %d.%d detected!\n", m_iMajorVersion, m_iMinorVersion);
+
+ // Fail if the extension version in the server is too old
+ if (m_iMajorVersion < DGA_MINMAJOR ||
+ (m_iMajorVersion == DGA_MINMAJOR && m_iMinorVersion < DGA_MINMINOR)) {
+ fprintf(stderr, "Xserver is running an old XFree86-DGA version"
+ " (%d.%d)\n", m_iMajorVersion, m_iMinorVersion);
+ fprintf(stderr, "Minimum required version is %d.%d\n",
+ DGA_MINMAJOR, DGA_MINMINOR);
+ return ;
+ }
+
+ if (!XF86DGAQueryExtension(m_pDisplay, &m_iEventBase, &m_iErrorBase)) {
+ fprintf(stderr, "Unable to query video extension information\n");
+ return ;
+ }
+ printf("Event base %d\n", m_iEventBase);
+ printf("Error base %d\n", m_iErrorBase);
+
+ lSupport=true;
+ supportedModes = _IMAGE_FULL;
+#endif
+}
+
+int ImageDGAFull::support() {
+ return lSupport;
+}
+
+
+int ImageDGAFull::openImage(int mode) {
+#ifdef X11_DGA2
+ int width, bank, ram;
+ m_bAllowZoom = IS_DOUBLE(mode);
+ m_iImageMode = mode;
+
+ /* Open access to the framebuffer */
+ if ( ! XDGAOpenFramebuffer(m_pDisplay,m_iScreen) ) {
+ return(false);
+ }
+
+ findMode(m_pxWindow->width, m_pxWindow->height, m_pxWindow->depth);
+ m_pDevice = XDGASetMode(m_pDisplay, m_iScreen, m_pDGAModes[m_iMode].num);
+
+
+ XDGASelectInput(m_pDisplay, m_iScreen,
+ KeyPressMask | ButtonPressMask | PointerMotionMask);
+
+ XF86DGAGetVideo(m_pDisplay,m_iScreen,&m_pAddr,&width,&bank,&ram);
+
+
+ if(bank < (ram * 1024)) {
+ XF86DGASetVidPage(m_pxWindow->display,
+ DefaultScreen(m_pxWindow->display), 0);
+ }
+
+ XF86DGASetViewPort(m_pxWindow->display,
+ DefaultScreen(m_pxWindow->display),0,0);
+
+
+ printf("Offset:%8x\n",m_iOffsetScreen);
+ m_pStartAddr = m_pAddr + m_iOffsetScreen;
+ m_iOffsetLine = (m_iBytesPerLine - m_iBytesPerRow) / m_iBytesPerPixel;
+ cout << "LineOffset: " << m_iOffsetLine << endl;
+
+ // Clear the screen
+ memset(m_pAddr, 0, m_iBytesPerLine * m_iScreenHeight);
+ /* char *pos = m_pStartAddr;
+ int end = (m_bZoom) ? 2*m_iVideoHeight : m_iVideoHeight;
+ for (int line=0 ; line<end ; line++) {
+ memset(pos, 80, m_iBytesPerRow);
+ pos += m_iBytesPerRow + m_iOffsetLine * m_iBytesPerPixel;
+ }
+ sleep(2);*/
+
+ m_bIsActive = true;
+#endif
+ return true;
+}
+
+
+int ImageDGAFull::closeImage() {
+#ifdef X11_DGA2
+ m_bIsActive = false;
+ stop();
+
+ // delete resources
+ if (m_pDGAModes != NULL) {
+ delete m_pDGAModes;
+ m_pDGAModes=NULL;
+ }
+#endif
+ return true;
+}
+
+
+unsigned char* ImageDGAFull::address() {
+ return (unsigned char*) m_pStartAddr;
+}
+
+
+int ImageDGAFull::offset() {
+ return m_iOffsetLine;
+}
+
+
+void ImageDGAFull::ditherImage(YUVPicture* pic) {
+
+ int useMode = (m_bZoom) ? m_iImageMode : m_iImageMode & (!_IMAGE_DOUBLE);
+
+ ditherWrapper->doDither(pic,m_pxWindow->depth,useMode,
+ address(),offset());
+}
+
+
+void ImageDGAFull::putImage() {
+
+ if (event())
+ closeImage();
+}
+
+
+int ImageDGAFull::findMode(int width, int height, int bpp) {
+#ifdef X11_DGA2
+ int minBorder = INT_MAX;
+ int yBorder=0;
+ int border;
+
+ // TODO: also check the y-axis
+
+ m_iMode = -1;
+ m_iNumberModes = 0;
+ m_pDGAModes = XDGAQueryModes(m_pDisplay, m_iScreen, &m_iNumberModes);
+ printf("Number modes: %d\n", m_iNumberModes);
+
+ for (int count=0 ; count<m_iNumberModes ; count++) {
+
+
+ if (m_pDGAModes[count].depth != bpp)
+ continue;
+
+ printf("Mode: %d %dx%d \t bpp %d\n",
+ count,
+ m_pDGAModes[count].viewportWidth,
+ m_pDGAModes[count].viewportHeight,
+ m_pDGAModes[count].bitsPerPixel);
+
+ // test normal video
+ border = m_pDGAModes[count].viewportWidth - width;
+ if ((border >= 0) && (border < minBorder)) {
+ minBorder = border;
+ m_iMode = count;
+ m_bZoom = false;
+ yBorder = m_pDGAModes[count].viewportHeight - height;
+ }
+
+ // test zoomed video
+ if (m_bAllowZoom) {
+ border = m_pDGAModes[count].viewportWidth - 2 * width;
+ if ((border >= 0) && (border < minBorder)) {
+ minBorder = border;
+ m_iMode = count;
+ m_bZoom = true;
+ yBorder = m_pDGAModes[count].viewportHeight-2*height;
+ }
+ }
+ }
+
+ if (m_iMode != -1) {
+ m_iScreenWidth = m_pDGAModes[m_iMode].viewportWidth;
+ m_iScreenHeight = m_pDGAModes[m_iMode].viewportHeight;
+
+ m_iBytesPerPixel = m_pDGAModes[m_iMode].bitsPerPixel / 8;
+ m_iBytesPerLine = m_pDGAModes[m_iMode].bytesPerScanline;
+ m_iBytesPerRow = width * m_iBytesPerPixel;
+ if (m_bZoom) {
+ m_iBytesPerRow += m_iBytesPerRow;
+ }
+
+ m_iOffsetScreen = minBorder * (m_iBytesPerPixel / 2) +
+ (yBorder / 2) * m_iBytesPerLine;
+ }
+
+ cout << "Best Mode: " << m_iMode << endl;
+ cout << "Border Size: " << minBorder / 2 << endl;
+ cout << "Zoom: " << m_bZoom << endl;
+ cout << "Bytes per Line: " << m_iBytesPerLine << endl;
+ cout << "Bytes per Row: " << m_iBytesPerRow << endl;
+ cout << "Bytes per Pixel:" << m_iBytesPerPixel << endl;
+ cout << "Total offset: " << m_iOffsetScreen << endl;
+#endif
+ return (m_iMode != -1);
+}
+
+
+
+int ImageDGAFull::event() {
+ XEvent event;
+ return XCheckTypedEvent(m_pDisplay, ButtonPress + m_iEventBase, &event);
+}
+
+void ImageDGAFull::stop() {
+#ifdef X11_DGA2
+ m_bIsActive = false;
+ XF86DGADirectVideo(m_pDisplay, m_iScreen, 0);
+
+ XUngrabPointer(m_pDisplay, CurrentTime);
+ XUngrabKeyboard(m_pDisplay, CurrentTime);
+#endif
+}
diff --git a/mpeglib/lib/util/render/x11/imageDGAFull.h b/mpeglib/lib/util/render/x11/imageDGAFull.h
new file mode 100644
index 00000000..ddb8f493
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDGAFull.h
@@ -0,0 +1,131 @@
+/*
+ xfree 4.0 dga fullscreen mode
+ Copyright (C) 2000 Martin Vogt, Christian Gerlach
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __IMAGEDGAFULL_H
+#define __IMAGEDGAFULL_H
+#include "xinit.h"
+
+#include "../imageBase.h"
+
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+
+
+
+
+#define DGA_MINMAJOR 2
+#define DGA_MINMINOR 0
+
+
+
+
+/**
+
+ Displays and renders X11 images in software with the help
+ of the ditherWrapper class. It switches to xfree 4.0 dga 2.0
+ and needs root priviliges for that
+
+*/
+
+
+class ImageDGAFull : public ImageBase {
+
+
+ XWindow* m_pxWindow;
+
+ // DGA status
+ int m_iMajorVersion;
+ int m_iMinorVersion;
+ int m_iEventBase;
+ int m_iErrorBase;
+
+ int m_iScreen;
+
+ Display *m_pDisplay;
+
+ int m_iNumberModes;
+
+#ifdef X11_DGA2
+ XDGAMode *m_pDGAModes;
+ XDGADevice *m_pDevice;
+#endif
+
+ int m_iScreenWidth;
+ int m_iScreenHeight;
+
+ char *m_pAddr; // Base address of the screen
+
+ // DGA parameter
+ int m_iVideoWidth;
+ int m_iVideoHeight;
+
+ int m_iBytesPerLine;
+ int m_iBytesPerRow; // Size of one image line
+ int m_iBytesPerPixel;
+ int m_iOffsetScreen;
+ int m_iOffsetLine;
+ char *m_pStartAddr; // Start address for a centered image
+
+ int m_iImageMode;
+ int m_iMode;
+ bool m_bZoom;
+ bool m_bAllowZoom;
+
+ bool m_bIsActive;
+
+ int lSupport;
+ DitherWrapper* ditherWrapper;
+
+
+ public:
+ ImageDGAFull();
+ ~ImageDGAFull();
+
+ void init(XWindow *xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int mode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ int active() { return m_bIsActive; }
+
+ private:
+
+ // Tries to find a fullscreen-mode which matches the resolution best
+ int findMode(int width, int height, int bpp);
+
+ // Returns TRUE if an event is waiting
+ int event();
+
+ // Returns the start address of the upper left corner of the video frame
+ unsigned char *address();
+
+ // Number of bytes from the end of a row to the beginning of next one
+ int offset();
+
+ // Disables DGA-View (performs a mode-switch if neccesary)
+ void stop();
+
+
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/imageDeskX11.cpp b/mpeglib/lib/util/render/x11/imageDeskX11.cpp
new file mode 100644
index 00000000..9607d749
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDeskX11.cpp
@@ -0,0 +1,439 @@
+/*
+ standard and shared mem X11 images
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "imageDeskX11.h"
+
+#include <iostream>
+
+using namespace std;
+
+static int lXerror;
+
+static int dummy(Display* , XErrorEvent*) {
+ lXerror=true;
+ return true;
+}
+
+
+
+ImageDeskX11::ImageDeskX11() {
+ lSupport=true;
+ supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL;
+ setIdentifier("Standard X11");
+ xWindow = NULL;
+ ditherWrapper=NULL;
+#ifdef X11_XVIDMODE
+ iOldMode = -1;
+ vm_modelines = NULL;
+#endif
+}
+
+
+ImageDeskX11::~ImageDeskX11() {
+ destroyImage();
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+}
+
+
+void ImageDeskX11::init(XWindow* xWindow, YUVPicture*)
+{
+ videoaccesstype=VIDEO_XI_NONE;
+ this->xWindow=xWindow;
+ virtualscreen=NULL;
+ ximage=NULL;
+ imageMode=_IMAGE_NONE;
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new DitherWrapper(xWindow->depth,
+ xWindow->redMask,
+ xWindow->greenMask,
+ xWindow->blueMask,
+ xWindow->pixel);
+ }
+
+#ifdef X11_SHARED_MEM
+ shmseginfo=NULL;
+#endif
+}
+
+int ImageDeskX11::support() {
+ return lSupport;
+}
+
+
+int ImageDeskX11::openImage(int mode) {
+
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::openImage - call init before open!" << endl;
+ return false;
+ }
+
+ closeImage();
+ imageMode = mode;
+ int err;
+
+ if ((err=createImage(VIDEO_XI_SHMSTD,imageMode)) != ERR_XI_OK) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ if ((err=createImage(VIDEO_XI_STANDARD,imageMode)) != ERR_XI_OK) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
+ videoaccesstype=VIDEO_XI_NONE;
+ } else {
+ lSupport=true;
+ }
+ } else {
+ lSupport=true;
+ }
+ switch(videoaccesstype) {
+ case VIDEO_XI_STANDARD:
+ //printf(" # using conventional Xlib calls.\n\n");
+ break;
+ case VIDEO_XI_SHMSTD:
+ //printf(" # Using Xlib shared memory extension %d.%d\n\n",
+ //XShmMajor,XShmMinor);
+ break;
+ default:
+ cout << "could not create image->no video output possible"<<endl;
+
+ }
+
+ iOffsetX = iOffsetY = 0;
+ int w = xWindow->width;
+ int h = xWindow->height;
+ if (IS_FULL(imageMode)) {
+ switchMode(xWindow->width, xWindow->height, IS_DOUBLE(imageMode));
+ iOffsetX = (iWidth - w) / 2;
+ iOffsetY = (iHeight - h) / 2;
+ if (bZoom) {
+ iOffsetX -= w / 2;
+ iOffsetY -= h / 2;
+ }
+ XResizeWindow(xWindow->display, xWindow->window, iWidth, iHeight);
+ } else if (IS_DOUBLE(imageMode)) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->width * 2, xWindow->height * 2);
+ }
+
+ if (lSupport==true) {
+ return true;
+ }
+ return false;
+}
+
+
+int ImageDeskX11::closeImage() {
+ destroyImage();
+
+#ifdef X11_XVIDMODE
+ if (iOldMode != -1) {
+ cout << "switch back to original videomode" << endl;
+ XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
+ vm_modelines[iOldMode]);
+ XFlush(xWindow->display);
+ iOldMode=-1;
+ }
+#endif
+
+ return true;
+}
+
+
+void ImageDeskX11::ditherImage(YUVPicture* pic) {
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::ditherImage - you have to call init first!" << endl;
+ return;
+ }
+
+ ditherWrapper->doDither(pic,xWindow->depth,imageMode,
+ virtualscreen,0);
+}
+
+
+void ImageDeskX11::putImage(){
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::putImage - you have to call init first!" << endl;
+ return;
+ }
+
+
+ int height=xWindow->height;
+ int width=xWindow->width;
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ height=2*height;
+ width=2*width;
+ }
+
+#ifdef X11_SHARED_MEM
+ switch(videoaccesstype) {
+ case VIDEO_XI_SHMSTD:
+ XShmPutImage(xWindow->display,xWindow->window,
+ xWindow->gc,ximage,
+ 0, 0, iOffsetX, iOffsetY, width, height, False);
+ XSync(xWindow->display,false); /* true not needed, done by XPending */
+ break;
+
+
+ case VIDEO_XI_STANDARD:
+#endif
+ XPutImage(xWindow->display,xWindow->window,
+ xWindow->gc, ximage,
+ 0, 0, iOffsetX, iOffsetY, width, height);
+ XSync(xWindow->display,false); /* true not needed, done by XPending */
+#ifdef X11_SHARED_MEM
+ break;
+ }
+#endif
+}
+
+
+
+int ImageDeskX11::createImage(int createType,int mode) {
+
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::createImage - you have to call init first!" << endl;
+ return false;
+ }
+
+ videoaccesstype=VIDEO_XI_NONE;
+
+#ifdef X11_SHARED_MEM
+ if(XShmQueryVersion(xWindow->display,&XShmMajor,&XShmMinor,&XShmPixmaps)) {
+ if (XShmPixmaps==True) {
+ if (createType & VIDEO_XI_SHMSTD) {
+ videoaccesstype=VIDEO_XI_SHMSTD;
+ }
+ }
+ } else {
+ if (createType & VIDEO_XI_SHMSTD) {
+ return ERR_XI_NOSHAREDMEMORY;
+ }
+ }
+#endif
+ if (videoaccesstype == VIDEO_XI_NONE) {
+ videoaccesstype=createType;
+ }
+
+ switch(videoaccesstype)
+ {
+#ifdef X11_SHARED_MEM
+
+
+ case VIDEO_XI_SHMSTD:
+
+ lXerror=false;
+ XSetErrorHandler(dummy);
+
+ shmseginfo=(XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo));
+ if(!shmseginfo)
+ return ERR_XI_SHMALLOC;
+
+ memset(shmseginfo,0, sizeof(XShmSegmentInfo));
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ ximage=XShmCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,
+ ZPixmap,NULL,shmseginfo,2*xWindow->width,
+ 2*xWindow->height);
+ } else {
+ ximage=XShmCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,
+ ZPixmap,NULL,shmseginfo,xWindow->width,
+ xWindow->height);
+ }
+
+ if(!ximage)
+ return ERR_XI_SHMXIMAGE;
+
+ shmseginfo->shmid=shmget(IPC_PRIVATE,
+ ximage->bytes_per_line*
+ ximage->height,IPC_CREAT|0777);
+
+ if(shmseginfo->shmid<0)
+ return ERR_XI_SHMSEGINFO;
+
+ shmseginfo->shmaddr=(char*)shmat(shmseginfo->shmid,NULL,0);
+ ximage->data=shmseginfo->shmaddr;
+ virtualscreen=(unsigned char *)ximage->data;
+
+ if(!virtualscreen)
+ return ERR_XI_SHMVIRTALLOC;
+
+ shmseginfo->readOnly=False;
+
+ XShmAttach(xWindow->display,shmseginfo);
+ XSync(xWindow->display, False);
+ XSetErrorHandler(NULL);
+ XFlush(xWindow->display);
+ if (lXerror) {
+ cout << "ERR_XI_SHMATTACH -2"<<endl;
+ return ERR_XI_SHMATTACH;
+ }
+
+ break;
+#endif
+
+ case VIDEO_XI_STANDARD:
+ if (mode & _IMAGE_DOUBLE) {
+ virtualscreen=(unsigned char *)
+ malloc(xWindow->screensize*sizeof(char)*4);
+
+ if(virtualscreen==NULL)
+ return ERR_XI_VIRTALLOC;
+
+ ximage=XCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,ZPixmap,
+ 0,(char*)virtualscreen,
+ 2*xWindow->width,2*xWindow->height,
+ 32,2*xWindow->width*xWindow->pixelsize);
+ } else {
+ virtualscreen=(unsigned char *)
+ malloc(xWindow->screensize*sizeof(char));
+
+ if(virtualscreen==NULL)
+ return ERR_XI_VIRTALLOC;
+
+ ximage=XCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,ZPixmap,
+ 0,(char*)virtualscreen,
+ xWindow->width,xWindow->height,
+ 32,xWindow->width*xWindow->pixelsize);
+ }
+
+ if(!ximage)
+ return ERR_XI_XIMAGE;
+ break;
+
+ default:
+ return ERR_XI_FAILURE;
+
+ }
+
+ if ( (videoaccesstype == VIDEO_XI_STANDARD) ||
+ (videoaccesstype == VIDEO_XI_SHMSTD) ) {
+#ifndef WORDS_BIGENDIAN
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+#else
+ ximage->byte_order = MSBFirst;
+ ximage->bitmap_bit_order = MSBFirst;
+#endif
+
+ }
+ return ERR_XI_OK;
+}
+
+
+
+int ImageDeskX11::destroyImage() {
+ if(xWindow && xWindow->display && xWindow->window) {
+ switch(videoaccesstype) {
+#ifdef X11_SHARED_MEM
+ case VIDEO_XI_SHMSTD:
+ if (shmseginfo) {
+ XShmDetach(xWindow->display,shmseginfo);
+ if(ximage) {
+ XDestroyImage(ximage);
+ ximage=NULL;
+ }
+ if(shmseginfo->shmaddr) {
+ shmdt(shmseginfo->shmaddr);
+ shmseginfo->shmaddr=NULL;
+ }
+ if(shmseginfo->shmid>=0)
+ shmctl(shmseginfo->shmid,IPC_RMID,NULL);
+
+ free(shmseginfo);
+ }
+ shmseginfo=NULL;
+ break;
+
+#endif
+ case VIDEO_XI_STANDARD:
+ if(ximage) {
+ XDestroyImage(ximage);
+ ximage=NULL;
+ /*
+ XDestroyImage function calls frees both the image structure
+ and the data pointed to by the image structure.
+ */
+ virtualscreen=NULL;
+ }
+ break;
+
+ default:
+ // cout << "no open window to close"<<endl;
+ break;
+ }
+ }
+ videoaccesstype=VIDEO_XI_NONE;
+ imageMode=_IMAGE_NONE;
+ return true;
+}
+
+
+bool ImageDeskX11::switchMode(int width, int , bool zoom)
+{
+ iWidth = xWindow->screenptr->width;
+ iHeight = xWindow->screenptr->height;
+
+#ifdef X11_XVIDMODE
+ iOldMode = -1;
+ int vm_count,i;
+
+ cout << "Find best matching videomode ..." << endl;
+
+ if (!XF86VidModeGetAllModeLines(xWindow->display,XDefaultScreen(xWindow->display),
+ &vm_count,&vm_modelines)) {
+ return false;
+ }
+
+ int bestMode = -1;
+ int border, minBorder = INT_MAX;
+
+ for (i = 0; i < vm_count; i++) {
+ printf("mode %d: %dx%d\n",i, vm_modelines[i]->hdisplay,vm_modelines[i]->vdisplay);
+
+ if (xWindow->screenptr->width == vm_modelines[i]->hdisplay)
+ iOldMode = i;
+
+ border = vm_modelines[i]->hdisplay - width;
+ if ((border > 0) && (border < minBorder)) {
+ bestMode = i;
+ minBorder = border;
+ bZoom = false;
+ }
+ if (zoom) {
+ border = vm_modelines[i]->hdisplay - 2 * width;
+ if ((border > 0) && (border < minBorder)) {
+ bestMode = i;
+ minBorder = border;
+ bZoom = true;
+ }
+ }
+ }
+ cout << "best mode: " << bestMode << endl;
+
+ iWidth = vm_modelines[bestMode]->hdisplay;
+ iHeight = vm_modelines[bestMode]->vdisplay;
+
+ if (XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
+ vm_modelines[bestMode])) {
+ XF86VidModeSetViewPort(xWindow->display,XDefaultScreen(xWindow->display), 0, 0);
+ XFlush(xWindow->display);
+ return true;
+ }
+#endif
+ return false;
+}
diff --git a/mpeglib/lib/util/render/x11/imageDeskX11.h b/mpeglib/lib/util/render/x11/imageDeskX11.h
new file mode 100644
index 00000000..efbd4e90
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDeskX11.h
@@ -0,0 +1,85 @@
+/*
+ standard and shared mem X11 images
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __IMAGEDESKX11_H
+#define __IMAGEDESKX11_H
+#include <limits.h>
+#include "xinit.h"
+
+#include "../imageBase.h"
+
+#define VIDEO_XI_NONE 0x00 /* No access defined */
+#define VIDEO_XI_STANDARD 0x01 /* Use standard Xlib calls */
+#define VIDEO_XI_SHMSTD 0X02 /* Use Xlib shared memory extension */
+
+/**
+
+ Displays and renders X11 images in software with the help
+ of the ditherWrapper class.
+*/
+
+
+class ImageDeskX11 : public ImageBase {
+
+#ifdef X11_SHARED_MEM
+ XShmSegmentInfo *shmseginfo;
+#endif
+
+ unsigned char *virtualscreen;
+ int videoaccesstype;
+ XImage *ximage;
+ int lSupport;
+
+ int XShmMajor,XShmMinor;
+ Bool XShmPixmaps;
+
+ XWindow* xWindow;
+ int imageMode;
+ DitherWrapper* ditherWrapper;
+
+ int iOffsetX;
+ int iOffsetY;
+ int iWidth;
+ int iHeight;
+
+#ifdef X11_XVIDMODE
+ XF86VidModeModeInfo **vm_modelines;
+
+ int iOldMode;
+#endif
+
+ bool bZoom;
+
+ public:
+ ImageDeskX11();
+ ~ImageDeskX11();
+
+ void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int ditherSize);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ private:
+ int createImage(int createType,int size);
+ int destroyImage();
+
+ bool switchMode(int width, int height, bool zoom);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/imageXVDesk.cpp b/mpeglib/lib/util/render/x11/imageXVDesk.cpp
new file mode 100644
index 00000000..e087ba40
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageXVDesk.cpp
@@ -0,0 +1,405 @@
+/*
+ xfree 4.0 XV extension desk mode
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "imageXVDesk.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageXVDesk::ImageXVDesk() {
+
+ lSupport=false;
+
+ ditherWrapper=NULL;
+ supportedModes = _IMAGE_NONE;
+ setIdentifier("XV");
+
+ xWindow = NULL;
+
+#ifdef X11_XV
+ keepRatio = false;
+
+#endif
+}
+
+
+ImageXVDesk::~ImageXVDesk() {
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+ freeImage();
+}
+
+void ImageXVDesk::init(XWindow* xWindow, YUVPicture*)
+{
+#ifdef X11_XV
+ this->xWindow=xWindow;
+
+ xv_port=-1;
+ shmem_flag = 0;
+ yuv_image=NULL;
+ yuv_shminfo.shmaddr=NULL;
+ yuv_shminfo.shmid=-1;
+
+ if (XShmQueryExtension(xWindow->display)) shmem_flag = 1;
+ if (!shmem_flag) {
+ printf("no shmem available.\n");
+ return;
+ }
+
+
+ if (haveXVSupport(xWindow)==true) {
+ supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL | _IMAGE_RESIZE;
+ lSupport=true;
+ } else {
+ return;
+ }
+
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new Dither2YUV();
+ }
+ imageID = -1;
+#endif
+}
+
+int ImageXVDesk::support() {
+ return lSupport;
+}
+
+int ImageXVDesk::openImage(int imageMode) {
+
+
+ if (imageMode & _IMAGE_FULL) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->screenptr->width, xWindow->screenptr->height);
+ setKeepRatio(true);
+ } else if (imageMode & _IMAGE_DOUBLE) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->width * 2, xWindow->height * 2);
+ setKeepRatio(false);
+ } else {
+ setKeepRatio(false);
+ }
+
+ return true;
+}
+
+
+int ImageXVDesk::closeImage() {
+ freeImage();
+ return true;
+}
+
+void ImageXVDesk::ditherImage(YUVPicture* pic) {
+
+#ifdef X11_XV
+ int x_return;
+ int y_return;
+ int height, dy;
+ unsigned int border_width_return;
+ unsigned int depth_return;
+ unsigned int _w;
+ unsigned int _h;
+ Window _dw;
+
+ if (xWindow == NULL) {
+ cout << "ImageXVDesk::ditherImage - you have to call before dithering an image!" << endl;
+ return;
+ }
+
+ // check for not supported formats and if possible convert them
+ int inputType=pic->getImageType();
+ if (inputType == PICTURE_RGB_FLIPPED) {
+ cout << "xv for flipped rgb not implemented"<<endl;
+ return;
+ }
+
+ // create xv image
+ int id;
+ if (imageID != pic->getImageType()) {
+ imageID = pic->getImageType();
+ switch (imageID) {
+ case PICTURE_YUVMODE_CR_CB:
+ case PICTURE_YUVMODE_CB_CR:
+ case PICTURE_RGB:
+ id = GUID_YUV12_PLANAR;
+ break;
+ case PICTURE_YUVMODE_YUY2:
+ id = GUID_YUY2_PACKED;
+ break;
+ case PICTURE_YUVMODE_UYVY:
+ id = GUID_UYVY_PACKED;
+ break;
+ default:
+ cout << "unknown type for yuv image!" << endl;
+ return;
+ }
+ freeImage();
+
+ createImage(id);
+ }
+
+ XGetGeometry(xWindow->display,(Drawable)xWindow->window,
+ &_dw, &x_return, &y_return, &_w, &_h,
+ &border_width_return, &depth_return);
+
+ // now dither the image
+
+ // we (currently) cannot create yuvPicture _in_
+ // the shared segment here we copy it
+
+ unsigned char* image=pic->getImagePtr();
+ if (inputType == PICTURE_RGB) {
+ ditherWrapper->doDither(pic,
+ DefaultDepth(xWindow->display,xWindow->screennum),
+ _SIZE_NORMAL, (unsigned char*) yuv_image->data, 0);
+ } else {
+ memcpy(yuv_image->data,image,pic->getImageSize());
+ }
+
+ if (keepRatio) {
+ height = (_w * yuv_image->height) / yuv_image->width;
+ dy = (((int) _h) - height + 1) / 2;
+ XvShmPutImage(xWindow->display, xv_port,xWindow->window,
+ xWindow->gc, yuv_image,
+ 0, 0, yuv_image->width, yuv_image->height,
+ 0, dy, _w, height, False);
+ if (dy > 0) {
+ XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
+ 0, 0, _w, dy);
+ XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
+ 0, height+dy-1, _w, dy+1);
+ }
+ } else {
+ XvShmPutImage(xWindow->display, xv_port,xWindow->window,
+ xWindow->gc, yuv_image,
+ 0, 0, yuv_image->width, yuv_image->height,
+ 0, 0, _w, _h, False);
+ }
+#endif
+}
+
+
+void ImageXVDesk::putImage() {
+
+ //XFlush(xWindow->display);
+ XSync(xWindow->display, false);
+}
+
+void ImageXVDesk::setKeepRatio(bool enable)
+{
+#ifdef X11_XV
+ keepRatio = enable;
+#endif
+}
+
+
+int ImageXVDesk::haveXVSupport(XWindow* xWindow) {
+#ifdef X11_XV
+ int ret;
+ unsigned int p_version=0;
+ unsigned int p_release=0;
+ unsigned int p_request_base=0;
+ unsigned int p_event_base=0;
+ unsigned int p_error_base=0;
+
+ unsigned int p_num_adaptors=0;
+
+ /**------------------------------- XV ------------------------------------*/
+
+ /** query and print Xvideo properties */
+
+ ret = XvQueryExtension(xWindow->display,
+ &p_version, &p_release, &p_request_base,
+ &p_event_base, &p_error_base);
+ if (ret != Success) {
+ if (ret == XvBadExtension) {
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ } else if (ret == XvBadAlloc) {
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ } else {
+ printf("other error happened at XvQueryExtension.\n");
+ }
+ return false;
+ }
+ /*
+ printf("========================================\n");
+ printf("XvQueryExtension returned the following:\n");
+ printf("p_version : %u\n", p_version);
+ printf("p_release : %u\n", p_release);
+ printf("p_request_base : %u\n", p_request_base);
+ printf("p_event_base : %u\n", p_event_base);
+ printf("p_error_base : %u\n", p_error_base);
+ printf("========================================\n");
+ */
+
+ ret = XvQueryAdaptors(xWindow->display, DefaultRootWindow(xWindow->display),
+ &p_num_adaptors, &ai);
+
+ if (ret != Success) {
+ if (ret == XvBadExtension) {
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ } else if (ret == XvBadAlloc) {
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ } else {
+ printf("other error happaned at XvQueryAdaptors.\n");
+ }
+ return false;
+ }
+ /*
+ printf("=======================================\n");
+ printf("XvQueryAdaptors returned the following:\n");
+ printf("%d adaptors available.\n", p_num_adaptors);
+ */
+ if (p_num_adaptors == 0) {
+ //cout << "no adaptors found. XV not possible"<<endl;
+ return false;
+ }
+
+ unsigned int i;
+ unsigned int j;
+
+ for (i = 0; i < p_num_adaptors; i++) {
+ /*
+ printf(" name: %s\n"
+ " type: %s%s%s%s%s\n"
+ " ports: %ld\n"
+ " first port: %ld\n",
+ ai[i].name,
+ (ai[i].type & XvInputMask) ? "input | " : "",
+ (ai[i].type & XvOutputMask) ? "output | " : "",
+ (ai[i].type & XvVideoMask) ? "video | " : "",
+ (ai[i].type & XvStillMask) ? "still | " : "",
+ (ai[i].type & XvImageMask) ? "image | " : "",
+ ai[i].num_ports,
+ ai[i].base_id);
+ */
+ xv_port = ai[i].base_id;
+
+ //printf("adaptor %d ; format list:\n", i);
+ for (j = 0; j < ai[i].num_formats; j++) {
+ /*
+ printf(" depth=%d, visual=%ld\n",
+ ai[i].formats[j].depth,
+ ai[i].formats[j].visual_id);
+ */
+ }
+ unsigned int p;
+ unsigned int encodings;
+ int attributes;
+ int formats;
+
+ for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
+
+ //printf(" encoding list for port %d\n", p);
+ if (XvQueryEncodings(xWindow->display, p, &encodings, &ei) != Success) {
+ //printf("XvQueryEncodings failed.\n");
+ continue;
+ }
+ for (j = 0; j < encodings; j++) {
+ /*
+ printf(" id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n",
+ ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
+ ei[j].rate.numerator, ei[j].rate.denominator);
+ */
+ }
+ XvFreeEncodingInfo(ei);
+ int k;
+ //printf(" attribute list for port %d\n", p);
+ at = XvQueryPortAttributes(xWindow->display, p, &attributes);
+ for (k = 0; k < attributes; k++) {
+ /*
+ printf(" name: %s\n"
+ " flags: %s%s\n"
+ " min_color: %i\n"
+ " max_color: %i\n",
+ at[k].name,
+ (at[k].flags & XvGettable) ? " get" : "",
+ (at[k].flags & XvSettable) ? " set" : "",
+ at[k].min_value, at[k].max_value);
+ */
+ }
+ if (at)
+ XFree(at);
+
+ //printf(" image format list for port %d\n", p);
+ fo = XvListImageFormats(xWindow->display, p, &formats);
+ for (k = 0; k < formats; k++) {
+ /*
+ printf(" 0x%x (%4.4s) %s\n",
+ fo[k].id,
+ (char *)&fo[k].id,
+ (fo[k].format == XvPacked) ? "packed" : "planar");
+ */
+ }
+ if (fo)
+ XFree(fo);
+ }
+ printf("\n");
+ }
+ if (p_num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+ if (xv_port == -1) {
+ return false;
+ }
+#endif
+ return true;
+
+}
+
+
+void ImageXVDesk::freeImage() {
+#ifdef X11_XV
+ if (xWindow == NULL) {
+ return;
+ }
+ if (yuv_shminfo.shmid >=0) {
+ XShmDetach(xWindow->display,&yuv_shminfo);
+ if(yuv_shminfo.shmaddr) {
+ shmdt(yuv_shminfo.shmaddr);
+ XFree(yuv_image);
+ yuv_shminfo.shmaddr=NULL;
+ }
+ XSync(xWindow->display, False);
+ yuv_shminfo.shmid=-1;
+ }
+#endif
+}
+
+
+void ImageXVDesk::createImage(int id) {
+#ifdef X11_XV
+ if (xWindow == NULL) {
+ cout << "ImageXVDesk::freeImage - you have to call init before creating an image!" << endl;
+ return;
+ }
+
+ yuv_image = XvShmCreateImage(xWindow->display, xv_port,
+ id, 0,
+ xWindow->width,
+ xWindow->height, &yuv_shminfo);
+
+ yuv_shminfo.shmid = shmget(IPC_PRIVATE,
+ yuv_image->data_size, IPC_CREAT | 0777);
+ yuv_shminfo.shmaddr = yuv_image->data =
+ (char*)shmat(yuv_shminfo.shmid, 0, 0);
+ yuv_shminfo.readOnly = False;
+
+ if (!XShmAttach(xWindow->display, &yuv_shminfo)) {
+ printf("XShmAttach failed !\n");
+ lSupport=false;
+ return;
+ }
+ shmctl(yuv_shminfo.shmid, IPC_RMID, 0);
+#endif
+}
diff --git a/mpeglib/lib/util/render/x11/imageXVDesk.h b/mpeglib/lib/util/render/x11/imageXVDesk.h
new file mode 100644
index 00000000..44124428
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageXVDesk.h
@@ -0,0 +1,88 @@
+/*
+ xfree 4.0 XV extension desk mode
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __IMAGEXVDESK_H
+#define __IMAGEXVDESK_H
+
+#include "xinit.h"
+
+#include "../imageBase.h"
+#include "../dither2YUV/dither2YUV.h"
+
+#include <stdio.h>
+
+#if !defined(__NetBSD__)
+#include <semaphore.h>
+#endif
+
+//#undef X11_XV
+
+#define GUID_YUV12_PLANAR 0x32315659
+#define GUID_I420_PLANAR 0x30323449
+#define GUID_YUY2_PACKED 0x32595559
+#define GUID_UYVY_PACKED 0x59565955
+
+/**
+ The XV extension dither yuv images in hardware and allows
+ scaling of images.
+ But its currently not supported by many drivers.
+
+*/
+
+
+class ImageXVDesk : public ImageBase {
+
+#ifdef X11_XV
+ XvAdaptorInfo *ai;
+ XvEncodingInfo *ei;
+ XvAttribute *at;
+ XvImageFormatValues *fo;
+
+ XvImage *yuv_image;
+ bool keepRatio;
+
+ int xv_port;
+ int imageID;
+
+ int shmem_flag;
+ XShmSegmentInfo yuv_shminfo;
+#endif
+ Dither2YUV* ditherWrapper;
+
+ int lSupport;
+ XWindow* xWindow;
+
+ public:
+ ImageXVDesk();
+ ~ImageXVDesk();
+
+ void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int imageMode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ void setKeepRatio(bool enable);
+
+ private:
+ int haveXVSupport(XWindow* xWindow);
+ void freeImage();
+ void createImage(int id);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/initDisplay.cpp b/mpeglib/lib/util/render/x11/initDisplay.cpp
new file mode 100644
index 00000000..d0029eb6
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/initDisplay.cpp
@@ -0,0 +1,255 @@
+/*
+ here are the different initialisation routines for different displays
+ Copyright (C) 1999 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+
+#include "initDisplay.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+
+static unsigned long wpixel[256];
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitColorDisplay --
+ *
+ * Initialized display for full color output.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void initColorDisplay(XWindow* xwindow) {
+ XWindowAttributes winattr;
+
+
+ XGetWindowAttributes(xwindow->display, xwindow->window, &winattr);
+
+ xwindow->redMask = winattr.visual->red_mask;
+ xwindow->greenMask = winattr.visual->green_mask;
+ xwindow->blueMask = winattr.visual->blue_mask;
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FindFullColorVisual
+ *
+ * Returns a pointer to a full color bit visual on the display
+ *
+ * Results:
+ * See above.
+ *
+ * Side effects:
+ * Unknown.
+ *
+ *--------------------------------------------------------------
+ */
+Visual* FindFullColorVisual (Display* dpy,int* depth) {
+ XVisualInfo vinfo;
+ XVisualInfo *vinfo_ret;
+ int numitems, maxdepth;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+ vinfo.c_class = TrueColor;
+#else
+ vinfo.class = TrueColor;
+#endif
+
+ vinfo_ret = XGetVisualInfo(dpy, VisualClassMask, &vinfo, &numitems);
+
+ if (numitems == 0) return NULL;
+
+ maxdepth = 0;
+ while(numitems > 0) {
+ if (vinfo_ret[numitems-1].depth > maxdepth) {
+ maxdepth = vinfo_ret[numitems-1 ].depth;
+ }
+ numitems--;
+ }
+ XFree((void *) vinfo_ret);
+
+ if (maxdepth < 16) return NULL;
+
+ if (XMatchVisualInfo(dpy, DefaultScreen(dpy), maxdepth,
+ TrueColor, &vinfo)) {
+ *depth = maxdepth;
+ return vinfo.visual;
+ }
+
+ return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * CreateFullColorWindow
+ *
+ * Creates a window capable of handling 32 bit color.
+ *
+ * Results:
+ * See above.
+ *
+ * Side effects:
+ * Unknown.
+ *
+ *--------------------------------------------------------------
+ */
+void CreateFullColorWindow (XWindow* xwindow) {
+ int depth;
+ Visual *visual;
+ XSetWindowAttributes xswa;
+ unsigned long mask;
+ unsigned int c_class;
+ int screen;
+ Display *dpy=xwindow->display;
+ /*
+ int x = xinfo->hints.x,
+ y = xinfo->hints.y;
+ unsigned int w = xinfo->hints.width,
+ h = xinfo->hints.height;
+ */
+ screen = XDefaultScreen(dpy);
+ c_class = InputOutput; /* Could be InputOnly */
+ if (xwindow->visual == NULL) {
+ xwindow->visual = visual = FindFullColorVisual (dpy, &depth);
+ xwindow->depth = depth;
+ } else {
+ visual=xwindow->visual;
+ depth=xwindow->depth;
+ }
+
+ if (visual == NULL) {
+ cout << "visual is null"<<endl;
+ return;
+ }
+ mask = CWBackPixel | CWColormap | CWBorderPixel;
+ if (xwindow->colormap==0) {
+ xswa.colormap = XCreateColormap(dpy,
+ XRootWindow(dpy, screen),
+ visual, AllocNone);
+ } else xswa.colormap = xwindow->colormap;
+ xswa.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
+ xswa.border_pixel = WhitePixel(dpy, DefaultScreen(dpy));
+ XSetWindowColormap(xwindow->display,xwindow->window,xwindow->colormap);
+
+
+ /*
+ xwindow->window = XCreateWindow(dpy, RootWindow(dpy, screen), x, y, w, h,
+ (unsigned int) 1, depth, c_class,
+ visual, mask, &xswa);
+ */
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitSimpleDisplay --
+ *
+ * Initialized display, sets up colormap, etc. Use for 8 Bit color
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void initSimpleDisplay(XWindow* xwindow) {
+ int ncolors = LUM_RANGE*CB_RANGE*CR_RANGE;
+ XColor xcolor;
+ int i, lum_num, cr_num, cb_num;
+ unsigned char r, g, b;
+ Colormap dcmap;
+ Display *display;
+ ColorTable8Bit colorTable8Bit;
+
+ display = xwindow->display;
+
+
+ xwindow->colormap = XDefaultColormap(display, DefaultScreen(display));
+ dcmap = xwindow->colormap;
+
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+
+
+ //if (xinfo->owncmFlag) goto create_map;
+
+retry_alloc_colors:
+ for (i=0; i<ncolors; i++) {
+
+ lum_num = (i / (CR_RANGE*CB_RANGE))%LUM_RANGE;
+ cr_num = (i / CB_RANGE)%CR_RANGE;
+ cb_num = i % CB_RANGE;
+
+ colorTable8Bit.ConvertColor(lum_num, cr_num, cb_num, &r, &g, &b);
+
+ xcolor.red = r * 256;
+ xcolor.green = g * 256;
+ xcolor.blue = b * 256;
+
+ if ((XAllocColor(display,xwindow->colormap , &xcolor) == 0
+ && xwindow->colormap == dcmap)) {
+ int j;
+ unsigned long tmp_pixel;
+ XWindowAttributes xwa;
+
+ // Free colors.
+ for (j = 0; j < i; j ++) {
+ tmp_pixel = wpixel[j];
+ XFreeColors(display,xwindow->colormap , &tmp_pixel, 1, 0);
+ }
+
+
+ //create_map:
+ XGetWindowAttributes(display, xwindow->window, &xwa);
+ xwindow->colormap = XCreateColormap(display, xwindow->window,
+ xwa.visual, AllocNone);
+ XSetWindowColormap(display, xwindow->window,xwindow->colormap );
+
+ goto retry_alloc_colors;
+ }
+ xwindow->pixel[i]=xcolor.pixel;
+ wpixel[i] = xcolor.pixel;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/x11/initDisplay.h b/mpeglib/lib/util/render/x11/initDisplay.h
new file mode 100644
index 00000000..62841f19
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/initDisplay.h
@@ -0,0 +1,34 @@
+/*
+ here are the different initialisation routines for different displays
+ Copyright (C) 1999 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+
+
+#ifndef __INITDISPLAY_H
+#define __INITDISPLAY_H
+
+#include "math.h"
+#include "xinit.h"
+#include "../dither/colorTable8Bit.h"
+
+
+
+extern void initColorDisplay(XWindow* xwindow);
+extern void initSimpleDisplay(XWindow* xwindow);
+
+// helper functions
+Visual *FindFullColorVisual (Display *dpy ,int *depth);
+void CreateFullColorWindow (XWindow* xwindow);
+
+
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/x11Surface.cpp b/mpeglib/lib/util/render/x11/x11Surface.cpp
new file mode 100644
index 00000000..d7b8f052
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/x11Surface.cpp
@@ -0,0 +1,389 @@
+/*
+ surface wrapper for X11 Window
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "x11Surface.h"
+
+#include <iostream>
+
+using namespace std;
+
+const char *ERR_XI_STR[] = {
+ "X initialisation OK!",
+ "No Shared Memory available",
+ "cannot open Display",
+ "bad color depth",
+ "can't create Window",
+ "can't alloc memory for virtual screen",
+ "cannot create XImage",
+ "can't alloc memory for Shared memory segment info",
+ "cannot create Shared Memory XImage",
+ "Shared memory segment info error",
+ "Shared memory virtual screen allocation failed",
+ "cannot attach Shared Memory segment to display"
+};
+
+
+#ifndef KDE_USE_FINAL
+static int dummy(Display* , XErrorEvent*) {
+ cout << "received x11 error!"<<endl;
+ return true;
+}
+#endif
+
+X11Surface::X11Surface() {
+ xWindow=(XWindow *)malloc(sizeof(XWindow));
+ xWindow->lOpen=false;
+ xWindow->x = xWindow->y = 0;
+ xWindow->window = 0;
+ m_windowIdAvailable = false;
+
+ imageMode=_IMAGE_NONE;
+
+ imageCurrent=NULL;
+ xWindow->lOpen=false;
+
+
+ xWindow->display=XOpenDisplay(NULL);
+ if (xWindow->display)
+ XFlush(xWindow->display);
+ xWindow->redMask=0;
+ xWindow->greenMask=0;
+ xWindow->blueMask=0;
+ lXVAllow=true;
+
+ images=0;
+ imageList = new ImageBase* [4];
+ imageList[images++] = new ImageXVDesk();
+ imageList[images++] = new ImageDGAFull();
+ imageList[images++] = new ImageDeskX11();
+ imageList[images] = NULL;
+}
+
+
+X11Surface::~X11Surface() {
+ close();
+ if (xWindow->display)
+ XCloseDisplay(xWindow->display);
+ free(xWindow);
+
+ for (int count=0 ; count<images ; count++) {
+ if (imageList[count] != NULL)
+ delete imageList[count];
+ }
+ delete [] imageList;
+}
+
+
+int X11Surface::getHeight() {
+ return xWindow->height;
+}
+
+
+int X11Surface::getWidth() {
+ return xWindow->width;
+}
+
+int X11Surface::isOpen() {
+ return xWindow->lOpen;
+}
+
+int X11Surface::x11WindowId() {
+ if(m_windowIdAvailable)
+ return xWindow->window;
+ else
+ return -1;
+}
+
+int X11Surface::open(int width, int height,const char *title, bool border) {
+
+ close();
+ xWindow->width=width;
+ xWindow->height=height;
+
+ if(!xWindow->display) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[ERR_XI_DISPLAY]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ exit(0);
+ }
+
+ xWindow->screennum=DefaultScreen(xWindow->display);
+ xWindow->screenptr=DefaultScreenOfDisplay(xWindow->display);
+ xWindow->visual=DefaultVisualOfScreen(xWindow->screenptr);
+ xWindow->depth=DefaultDepth(xWindow->display,xWindow->screennum);
+
+ switch(xWindow->depth) {
+ case 8:
+ xWindow->pixelsize=1;
+ break;
+ case 16:
+ xWindow->pixelsize=2;
+ break;
+ case 24:
+ xWindow->pixelsize=4;
+ break;
+ case 32:
+ xWindow->pixelsize=4;
+ break;
+ default:
+ cout << "unknown pixelsize for depth:"<<xWindow->depth<<endl;
+ exit(0);
+ }
+
+ XColor background, ignored;
+ XAllocNamedColor (xWindow->display,
+ DefaultColormap (xWindow->display, xWindow->screennum),
+ "black", &background, &ignored);
+
+ XSetWindowAttributes attributes;
+ attributes.background_pixel=background.pixel;
+ attributes.backing_store=NotUseful;
+ attributes.override_redirect=True;
+
+ xWindow->window=XCreateWindow(xWindow->display,
+ RootWindowOfScreen(xWindow->screenptr),
+ 0,0,
+ xWindow->width,
+ xWindow->height,0,
+ xWindow->depth,
+ InputOutput, xWindow->visual,
+ (border) ? CWBackingStore : CWBackPixel|CWOverrideRedirect,
+ &attributes);
+
+ m_windowIdAvailable = true;
+ if(!xWindow->window) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[ERR_XI_WINDOW]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ return false;
+ }
+
+ WM_DELETE_WINDOW = XInternAtom(xWindow->display, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(xWindow->display, xWindow->window, &WM_DELETE_WINDOW, 1);
+
+ XSetErrorHandler(dummy);
+
+ XStoreName(xWindow->display,xWindow->window,title);
+ XSelectInput(xWindow->display,xWindow->window,
+ ExposureMask|KeyPressMask|KeyReleaseMask|ButtonPressMask);
+ xWindow->gc=XCreateGC(xWindow->display,xWindow->window,0,NULL);
+ XMapRaised(xWindow->display,xWindow->window);
+
+ if (xWindow->depth >= 16) {
+ initColorDisplay(xWindow);
+
+ } else {
+ // depth is <= 8
+ // allocate memory for dithertables
+ // gets the rgb masks
+ initColorDisplay(xWindow);
+ // create 8 bit dithertables
+ // create private colormap
+ initSimpleDisplay(xWindow);
+
+ }
+
+ xWindow->palette=NULL;
+ xWindow->screensize=xWindow->height*xWindow->width*xWindow->pixelsize;
+ xWindow->lOpen=true;
+
+ for (int count=0 ; count<images ; count++) {
+ if (imageList[count] != NULL)
+ imageList[count]->init(xWindow);
+ }
+
+ return true;
+}
+
+
+int X11Surface::close() {
+ if (isOpen()==false) {
+ return true;
+ }
+ closeImage();
+
+ XFreeGC(xWindow->display,xWindow->gc);
+ XDestroyWindow(xWindow->display,xWindow->window);
+
+ xWindow->lOpen=false;
+
+
+ return true;
+}
+
+ImageBase *X11Surface::findImage(int mode) {
+ for (int count=0 ; count<images ; count++) {
+ if ((imageList[count] == NULL) || (IS_DISABLED(imageList[count])))
+ continue;
+
+ if (imageList[count]->supportedModes & mode)
+ return imageList[count];
+ }
+ return NULL;
+}
+
+ImageBase **X11Surface::getModes() {
+ return imageList;
+}
+
+void X11Surface::setModes(ImageBase **modes) {
+ imageList = modes;
+}
+
+int X11Surface::openImage(int mode, YUVPicture*) {
+ if (imageMode != _IMAGE_NONE) {
+ cout << "bad open error X11Surface::openImage"<<endl;
+ return false;
+ }
+ if (mode == _IMAGE_NONE) {
+ cout << "X11Surface::openImage - no valid mode specified"<<endl;
+ return false;
+ }
+
+ ImageBase *newImage=findImage(mode);
+
+ if (newImage == NULL) {
+ cout << " X11Surface::openImage - no matching image found"<<endl;
+ imageMode=_IMAGE_NONE;
+ } else {
+ /*
+ printf("Best image found: %s\n", newImage->getIdentifier());
+ printf("\tsupported modes: desk=%d, double=%d, full=%d, resize=%d\n",
+ HAS_DESK(newImage),
+ HAS_DOUBLE(newImage),
+ HAS_FULL(newImage),
+ HAS_RESIZE(newImage));
+ */
+
+ open(xWindow->width, xWindow->height, "mpeglib", !(mode & _IMAGE_FULL));
+ newImage->openImage(mode);
+ if (!IS_FULL(mode)) {
+ XMoveWindow(xWindow->display, xWindow->window,
+ xWindow->x, xWindow->y);
+
+ XSizeHints hints;
+ hints.flags = PMaxSize;
+ if (HAS_RESIZE(newImage)) {
+ hints.max_width = INT_MAX;
+ hints.max_height = INT_MAX;
+ } else {
+ hints.max_width = xWindow->width;
+ hints.max_height = xWindow->height;
+ }
+ XSetWMNormalHints(xWindow->display, xWindow->window, &hints);
+ }
+
+ imageMode=mode;
+ }
+ imageCurrent = newImage;
+ XSync(xWindow->display,true);
+ return (imageCurrent != NULL);
+}
+
+
+int X11Surface::closeImage() {
+
+ if ((imageMode == _IMAGE_NONE) || (!xWindow->lOpen))
+ return false;
+
+ ImageBase *old = imageCurrent;
+ imageCurrent=NULL;
+
+ XWindowAttributes attr;
+ Window junkwin;
+
+ if (!IS_FULL(imageMode)) {
+ if (!XGetWindowAttributes(xWindow->display, xWindow->window, &attr))
+ cout << "Can't get window attributes." << endl;
+
+ XTranslateCoordinates (xWindow->display, xWindow->window, attr.root,
+ -attr.border_width,
+ -attr.border_width,
+ &xWindow->x, &xWindow->y, &junkwin);
+ }
+
+ imageMode=_IMAGE_NONE;
+ old->closeImage();
+
+ return true;
+}
+
+
+int X11Surface::dither(YUVPicture* pic) {
+ if (imageCurrent != NULL) {
+ imageCurrent->ditherImage(pic);
+ }
+ return true;
+}
+
+
+int X11Surface::putImage(YUVPicture* ) {
+ if (imageCurrent != NULL) {
+ imageCurrent->putImage();
+ }
+ return true;
+}
+
+
+int X11Surface::getDepth() {
+ return xWindow->depth;
+}
+
+int X11Surface::getImageMode() {
+ return imageMode;
+}
+
+int X11Surface::checkEvent(int* newMode) {
+ XEvent event;
+
+ if (isOpen()==false)
+ return false;
+
+ // check if we forward the call to the FULLSCREEN mode
+ if (!imageCurrent->active()) {
+ if (IS_FULL(imageMode)) {
+ *newMode=imageMode ^ _IMAGE_FULL;
+ return true;
+ }
+ }
+
+ // normal X11 images use the X11 event queue
+ if (XCheckTypedWindowEvent(xWindow->display,
+ xWindow->window,ButtonPress,&event)) {
+ if (event.xbutton.button == Button1) {
+ if (findImage(_IMAGE_DOUBLE) != NULL)
+ *newMode = imageMode ^ _IMAGE_DOUBLE;
+ } else if (event.xbutton.button == Button3) {
+ if (findImage(_IMAGE_FULL) != NULL)
+ *newMode = imageMode ^ _IMAGE_DESK ^ _IMAGE_FULL;
+ }
+ return true;
+ }
+ // now check if there are unneeded events in the queue,
+ // then delete them
+ int eventCnt=XPending(xWindow->display);
+ if (eventCnt > 10) {
+ XSync(xWindow->display,true);
+ }
+ return false;
+
+
+}
+
+
+
+void X11Surface::config(const char* key,
+ const char* value, void* ) {
+ if (strcmp(key,"xvAllow")==0) {
+ lXVAllow=atoi(value);
+ }
+}
+
diff --git a/mpeglib/lib/util/render/x11/x11Surface.h b/mpeglib/lib/util/render/x11/x11Surface.h
new file mode 100644
index 00000000..54a6582d
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/x11Surface.h
@@ -0,0 +1,79 @@
+/*
+ surface wrapper for X11 Window
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __X11SURFACE_H
+#define __X11SURFACE_H
+
+#include <limits.h>
+#include "xinit.h"
+#include "../surface.h"
+#include "initDisplay.h"
+#include "../dither/ditherWrapper.h"
+#include "imageDeskX11.h"
+#include "imageDGAFull.h"
+#include "imageXVDesk.h"
+
+
+
+class X11Surface : public Surface {
+
+ int lOpen;
+ int imageMode;
+
+ XWindow* xWindow;
+
+ ImageBase** imageList;
+ int images;
+
+ ImageBase* imageCurrent;
+
+ Atom WM_DELETE_WINDOW;
+ Atom WM_RESIZE_WINDOW;
+ int lXVAllow;
+
+ public:
+ X11Surface();
+ ~X11Surface();
+
+ int isOpen();
+ int open(int width, int height,const char *title, bool border = false);
+ int close();
+ int getHeight();
+ int getWidth();
+ int getDepth();
+ int getImageMode();
+ int x11WindowId();
+
+ ImageBase *findImage(int mode);
+
+ // these functions grant access to the supported images. be careful when changing
+ // entries, because these are no copies. they are the original values!
+ ImageBase **getModes();
+ void setModes(ImageBase **modes);
+
+ int openImage(int mode, YUVPicture* pic = NULL);
+ int closeImage();
+ int dither(YUVPicture* pic);
+ int putImage(YUVPicture* pic);
+
+ int checkEvent(int* mode);
+
+ void config(const char* key,
+ const char* value,void* user_data);
+
+
+ private:
+ int initX11();
+ bool m_windowIdAvailable;
+};
+#endif
diff --git a/mpeglib/lib/util/render/x11/xinit.h b/mpeglib/lib/util/render/x11/xinit.h
new file mode 100644
index 00000000..c42c290f
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/xinit.h
@@ -0,0 +1,99 @@
+
+#ifndef __XINIT_H__
+#define __XINIT_H__
+
+#define __USE_X_SHAREDMEMORY__
+
+#include <pthread.h>
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+
+
+
+#ifdef X11_SHARED_MEM
+#include <X11/extensions/XShm.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
+
+#ifdef X11_XV
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+#ifdef X11_XVIDMODE
+#include <X11/extensions/xf86vmode.h>
+#endif
+
+#ifdef X11_DGA2
+#include <X11/extensions/xf86dga.h>
+#endif
+
+#define ERR_XI_FAILURE 0xFF
+#define ERR_XI_OK 0x00
+#define ERR_XI_NOSHAREDMEMORY 0x01
+#define ERR_XI_DISPLAY 0x02
+#define ERR_XI_BADDEPTH 0x03
+#define ERR_XI_WINDOW 0x04
+#define ERR_XI_VIRTALLOC 0x05
+#define ERR_XI_XIMAGE 0x06
+#define ERR_XI_SHMALLOC 0x07
+#define ERR_XI_SHMXIMAGE 0x08
+#define ERR_XI_SHMSEGINFO 0x09
+#define ERR_XI_SHMVIRTALLOC 0x0A
+#define ERR_XI_SHMATTACH 0x0B
+
+
+
+
+#define PIXEL unsigned long
+
+extern const char *ERR_XI_STR[];
+
+struct XWindow {
+
+ Display *display;
+ Window window;
+ Screen *screenptr;
+ int screennum;
+ Visual *visual;
+ GC gc;
+
+ Colormap colormap;
+ PIXEL *palette;
+ int colorcells;
+
+ int x;
+ int y;
+ int width;
+ int height;
+ int depth;
+ int pixelsize;
+ int screensize;
+ int lOpen;
+
+ // colorMask
+ unsigned int redMask;
+ unsigned int greenMask;
+ unsigned int blueMask;
+
+ // colortable for 8 bit colormap
+ // (created with interference by the XServer)
+ unsigned char pixel[256];
+
+};
+
+
+#endif /* __XINIT_H__ */