2
standard and shared mem X11 images
3
Copyright (C) 2000 Martin Vogt
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU Library General Public License as published by
7
the Free Software Foundation.
9
For more information look at the file COPYRIGHT in this package
14
#include "imageDeskX11.h"
19
static int dummy(Display* , XErrorEvent*) {
26
ImageDeskX11::ImageDeskX11() {
28
supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL;
29
setIdentifier("Standard X11");
39
ImageDeskX11::~ImageDeskX11() {
41
if (ditherWrapper != NULL) {
47
void ImageDeskX11::init(XWindow* xWindow, YUVPicture*)
49
videoaccesstype=VIDEO_XI_NONE;
50
this->xWindow=xWindow;
53
imageMode=_IMAGE_NONE;
54
if (ditherWrapper == NULL) {
55
ditherWrapper=new DitherWrapper(xWindow->depth,
67
int ImageDeskX11::support() {
72
int ImageDeskX11::openImage(int mode) {
74
if (xWindow == NULL) {
75
cout << "ImageDeskX11::openImage - call init before open!" << endl;
83
if ((err=createImage(VIDEO_XI_SHMSTD,imageMode)) != ERR_XI_OK) {
84
printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
85
printf("check ipcs and delete resources with ipcrm\n");
86
if ((err=createImage(VIDEO_XI_STANDARD,imageMode)) != ERR_XI_OK) {
87
printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
88
videoaccesstype=VIDEO_XI_NONE;
95
switch(videoaccesstype) {
96
case VIDEO_XI_STANDARD:
97
//printf(" # using conventional Xlib calls.\n\n");
100
//printf(" # Using Xlib shared memory extension %d.%d\n\n",
101
//XShmMajor,XShmMinor);
104
cout << "could not create image->no video output possible"<<endl;
108
iOffsetX = iOffsetY = 0;
109
int w = xWindow->width;
110
int h = xWindow->height;
111
if (IS_FULL(imageMode)) {
112
switchMode(xWindow->width, xWindow->height, IS_DOUBLE(imageMode));
113
iOffsetX = (iWidth - w) / 2;
114
iOffsetY = (iHeight - h) / 2;
119
XResizeWindow(xWindow->display, xWindow->window, iWidth, iHeight);
120
} else if (IS_DOUBLE(imageMode)) {
121
XResizeWindow(xWindow->display, xWindow->window,
122
xWindow->width * 2, xWindow->height * 2);
125
if (lSupport==true) {
132
int ImageDeskX11::closeImage() {
136
if (iOldMode != -1) {
137
cout << "switch back to original videomode" << endl;
138
XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
139
vm_modelines[iOldMode]);
140
XFlush(xWindow->display);
149
void ImageDeskX11::ditherImage(YUVPicture* pic) {
150
if (xWindow == NULL) {
151
cout << "ImageDeskX11::ditherImage - you have to call init first!" << endl;
155
ditherWrapper->doDither(pic,xWindow->depth,imageMode,
160
void ImageDeskX11::putImage(){
161
if (xWindow == NULL) {
162
cout << "ImageDeskX11::putImage - you have to call init first!" << endl;
167
int height=xWindow->height;
168
int width=xWindow->width;
170
if (imageMode & _IMAGE_DOUBLE) {
175
#ifdef X11_SHARED_MEM
176
switch(videoaccesstype) {
177
case VIDEO_XI_SHMSTD:
178
XShmPutImage(xWindow->display,xWindow->window,
180
0, 0, iOffsetX, iOffsetY, width, height, False);
181
XSync(xWindow->display,false); /* true not needed, done by XPending */
185
case VIDEO_XI_STANDARD:
187
XPutImage(xWindow->display,xWindow->window,
189
0, 0, iOffsetX, iOffsetY, width, height);
190
XSync(xWindow->display,false); /* true not needed, done by XPending */
191
#ifdef X11_SHARED_MEM
199
int ImageDeskX11::createImage(int createType,int mode) {
201
if (xWindow == NULL) {
202
cout << "ImageDeskX11::createImage - you have to call init first!" << endl;
206
videoaccesstype=VIDEO_XI_NONE;
208
#ifdef X11_SHARED_MEM
209
if(XShmQueryVersion(xWindow->display,&XShmMajor,&XShmMinor,&XShmPixmaps)) {
210
if (XShmPixmaps==True) {
211
if (createType & VIDEO_XI_SHMSTD) {
212
videoaccesstype=VIDEO_XI_SHMSTD;
216
if (createType & VIDEO_XI_SHMSTD) {
217
return ERR_XI_NOSHAREDMEMORY;
221
if (videoaccesstype == VIDEO_XI_NONE) {
222
videoaccesstype=createType;
225
switch(videoaccesstype)
227
#ifdef X11_SHARED_MEM
230
case VIDEO_XI_SHMSTD:
233
XSetErrorHandler(dummy);
235
shmseginfo=(XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo));
237
return ERR_XI_SHMALLOC;
239
memset(shmseginfo,0, sizeof(XShmSegmentInfo));
241
if (imageMode & _IMAGE_DOUBLE) {
242
ximage=XShmCreateImage(xWindow->display,xWindow->visual,
244
ZPixmap,NULL,shmseginfo,2*xWindow->width,
247
ximage=XShmCreateImage(xWindow->display,xWindow->visual,
249
ZPixmap,NULL,shmseginfo,xWindow->width,
254
return ERR_XI_SHMXIMAGE;
256
shmseginfo->shmid=shmget(IPC_PRIVATE,
257
ximage->bytes_per_line*
258
ximage->height,IPC_CREAT|0777);
260
if(shmseginfo->shmid<0)
261
return ERR_XI_SHMSEGINFO;
263
shmseginfo->shmaddr=(char*)shmat(shmseginfo->shmid,NULL,0);
264
ximage->data=shmseginfo->shmaddr;
265
virtualscreen=(unsigned char *)ximage->data;
268
return ERR_XI_SHMVIRTALLOC;
270
shmseginfo->readOnly=False;
272
XShmAttach(xWindow->display,shmseginfo);
273
XSync(xWindow->display, False);
274
XSetErrorHandler(NULL);
275
XFlush(xWindow->display);
277
cout << "ERR_XI_SHMATTACH -2"<<endl;
278
return ERR_XI_SHMATTACH;
284
case VIDEO_XI_STANDARD:
285
if (mode & _IMAGE_DOUBLE) {
286
virtualscreen=(unsigned char *)
287
malloc(xWindow->screensize*sizeof(char)*4);
289
if(virtualscreen==NULL)
290
return ERR_XI_VIRTALLOC;
292
ximage=XCreateImage(xWindow->display,xWindow->visual,
293
xWindow->depth,ZPixmap,
294
0,(char*)virtualscreen,
295
2*xWindow->width,2*xWindow->height,
296
32,2*xWindow->width*xWindow->pixelsize);
298
virtualscreen=(unsigned char *)
299
malloc(xWindow->screensize*sizeof(char));
301
if(virtualscreen==NULL)
302
return ERR_XI_VIRTALLOC;
304
ximage=XCreateImage(xWindow->display,xWindow->visual,
305
xWindow->depth,ZPixmap,
306
0,(char*)virtualscreen,
307
xWindow->width,xWindow->height,
308
32,xWindow->width*xWindow->pixelsize);
312
return ERR_XI_XIMAGE;
316
return ERR_XI_FAILURE;
320
if ( (videoaccesstype == VIDEO_XI_STANDARD) ||
321
(videoaccesstype == VIDEO_XI_SHMSTD) ) {
322
#ifndef WORDS_BIGENDIAN
323
ximage->byte_order = LSBFirst;
324
ximage->bitmap_bit_order = LSBFirst;
326
ximage->byte_order = MSBFirst;
327
ximage->bitmap_bit_order = MSBFirst;
336
int ImageDeskX11::destroyImage() {
337
if(xWindow && xWindow->display && xWindow->window) {
338
switch(videoaccesstype) {
339
#ifdef X11_SHARED_MEM
340
case VIDEO_XI_SHMSTD:
342
XShmDetach(xWindow->display,shmseginfo);
344
XDestroyImage(ximage);
347
if(shmseginfo->shmaddr) {
348
shmdt(shmseginfo->shmaddr);
349
shmseginfo->shmaddr=NULL;
351
if(shmseginfo->shmid>=0)
352
shmctl(shmseginfo->shmid,IPC_RMID,NULL);
360
case VIDEO_XI_STANDARD:
362
XDestroyImage(ximage);
365
XDestroyImage function calls frees both the image structure
366
and the data pointed to by the image structure.
373
// cout << "no open window to close"<<endl;
377
videoaccesstype=VIDEO_XI_NONE;
378
imageMode=_IMAGE_NONE;
383
bool ImageDeskX11::switchMode(int width, int , bool zoom)
385
iWidth = xWindow->screenptr->width;
386
iHeight = xWindow->screenptr->height;
392
cout << "Find best matching videomode ..." << endl;
394
if (!XF86VidModeGetAllModeLines(xWindow->display,XDefaultScreen(xWindow->display),
395
&vm_count,&vm_modelines)) {
400
int border, minBorder = MAXINT;
402
for (i = 0; i < vm_count; i++) {
403
printf("mode %d: %dx%d\n",i, vm_modelines[i]->hdisplay,vm_modelines[i]->vdisplay);
405
if (xWindow->screenptr->width == vm_modelines[i]->hdisplay)
408
border = vm_modelines[i]->hdisplay - width;
409
if ((border > 0) && (border < minBorder)) {
415
border = vm_modelines[i]->hdisplay - 2 * width;
416
if ((border > 0) && (border < minBorder)) {
423
cout << "best mode: " << bestMode << endl;
425
iWidth = vm_modelines[bestMode]->hdisplay;
426
iHeight = vm_modelines[bestMode]->vdisplay;
428
if (XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
429
vm_modelines[bestMode])) {
430
XF86VidModeSetViewPort(xWindow->display,XDefaultScreen(xWindow->display), 0, 0);
431
XFlush(xWindow->display);