/* 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 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!"<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 ; countheight; } 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:"<depth<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 ; countinit(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 ; countsupportedModes & 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"<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 juntwin; 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, &juntwin); } 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); } }