diff options
Diffstat (limited to 'mpeglib/lib/util/render/x11')
-rw-r--r-- | mpeglib/lib/util/render/x11/Makefile.am | 48 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/imageDGAFull.cpp | 289 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/imageDGAFull.h | 131 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/imageDeskX11.cpp | 439 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/imageDeskX11.h | 85 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/imageXVDesk.cpp | 405 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/imageXVDesk.h | 88 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/initDisplay.cpp | 255 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/initDisplay.h | 34 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/x11Surface.cpp | 389 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/x11Surface.h | 79 | ||||
-rw-r--r-- | mpeglib/lib/util/render/x11/xinit.h | 99 |
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__ */ |