You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
390 lines
8.9 KiB
390 lines
8.9 KiB
/*
|
|
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 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);
|
|
}
|
|
}
|
|
|