~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to mpeglib/lib/util/render/x11/imageDeskX11.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  standard and shared mem  X11 images 
 
3
  Copyright (C) 2000  Martin Vogt
 
4
 
 
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.
 
8
 
 
9
  For more information look at the file COPYRIGHT in this package
 
10
 
 
11
 */
 
12
 
 
13
 
 
14
#include "imageDeskX11.h"
 
15
 
 
16
 
 
17
static int lXerror;
 
18
 
 
19
static int dummy(Display* , XErrorEvent*) {
 
20
  lXerror=true;
 
21
  return true;
 
22
}
 
23
 
 
24
 
 
25
 
 
26
ImageDeskX11::ImageDeskX11() {
 
27
  lSupport=true;
 
28
  supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL;
 
29
  setIdentifier("Standard X11");
 
30
  xWindow = NULL;
 
31
  ditherWrapper=NULL;
 
32
#ifdef X11_XVIDMODE
 
33
  iOldMode = -1;
 
34
  vm_modelines = NULL;
 
35
#endif
 
36
}
 
37
 
 
38
 
 
39
ImageDeskX11::~ImageDeskX11() {
 
40
  destroyImage();
 
41
  if (ditherWrapper != NULL) {
 
42
    delete ditherWrapper;
 
43
  }
 
44
}
 
45
 
 
46
 
 
47
void ImageDeskX11::init(XWindow* xWindow, YUVPicture*)
 
48
{
 
49
  videoaccesstype=VIDEO_XI_NONE;
 
50
  this->xWindow=xWindow;
 
51
  virtualscreen=NULL;
 
52
  ximage=NULL;
 
53
  imageMode=_IMAGE_NONE;
 
54
  if (ditherWrapper == NULL) {
 
55
    ditherWrapper=new DitherWrapper(xWindow->depth,
 
56
                                    xWindow->redMask,
 
57
                                    xWindow->greenMask,
 
58
                                    xWindow->blueMask,
 
59
                                    xWindow->pixel);
 
60
  }
 
61
 
 
62
#ifdef X11_SHARED_MEM
 
63
  shmseginfo=NULL;
 
64
#endif
 
65
}
 
66
 
 
67
int ImageDeskX11::support() {
 
68
  return lSupport;
 
69
}
 
70
 
 
71
 
 
72
int ImageDeskX11::openImage(int mode) {
 
73
 
 
74
  if (xWindow == NULL) {
 
75
    cout << "ImageDeskX11::openImage - call init before open!" << endl;
 
76
    return false;
 
77
  }
 
78
  
 
79
  closeImage();
 
80
  imageMode = mode;
 
81
  int err;
 
82
 
 
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;
 
89
    } else {
 
90
      lSupport=true;
 
91
    }
 
92
  } else {
 
93
    lSupport=true;
 
94
  }
 
95
  switch(videoaccesstype)  {
 
96
    case VIDEO_XI_STANDARD:
 
97
      //printf("  # using conventional Xlib calls.\n\n");
 
98
      break;
 
99
    case VIDEO_XI_SHMSTD:
 
100
      //printf("  # Using Xlib shared memory extension %d.%d\n\n",
 
101
      //XShmMajor,XShmMinor);
 
102
      break;
 
103
  default:
 
104
    cout << "could not create image->no video output possible"<<endl;
 
105
 
 
106
  }  
 
107
 
 
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;
 
115
    if (bZoom) {
 
116
      iOffsetX -= w / 2;
 
117
      iOffsetY -= h / 2;
 
118
    }
 
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);
 
123
  }
 
124
 
 
125
  if (lSupport==true) {
 
126
    return true;
 
127
  }
 
128
  return false;
 
129
}
 
130
 
 
131
 
 
132
int ImageDeskX11::closeImage() {
 
133
  destroyImage();
 
134
 
 
135
#ifdef X11_XVIDMODE
 
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);
 
141
    iOldMode=-1;
 
142
  }
 
143
#endif
 
144
  
 
145
  return true;
 
146
}
 
147
 
 
148
 
 
149
void ImageDeskX11::ditherImage(YUVPicture* pic) {
 
150
  if (xWindow == NULL) {
 
151
    cout << "ImageDeskX11::ditherImage - you have to call init first!" << endl;
 
152
    return;
 
153
  }
 
154
  
 
155
  ditherWrapper->doDither(pic,xWindow->depth,imageMode,
 
156
                          virtualscreen,0);
 
157
}
 
158
 
 
159
 
 
160
void ImageDeskX11::putImage(){
 
161
  if (xWindow == NULL) {
 
162
    cout << "ImageDeskX11::putImage - you have to call init first!" << endl;
 
163
    return;
 
164
  }
 
165
  
 
166
 
 
167
  int height=xWindow->height;
 
168
  int width=xWindow->width;
 
169
 
 
170
  if (imageMode & _IMAGE_DOUBLE) {
 
171
    height=2*height;
 
172
    width=2*width;
 
173
  }
 
174
  
 
175
#ifdef X11_SHARED_MEM
 
176
  switch(videoaccesstype) {
 
177
    case VIDEO_XI_SHMSTD:
 
178
      XShmPutImage(xWindow->display,xWindow->window, 
 
179
                   xWindow->gc,ximage,
 
180
                   0, 0, iOffsetX, iOffsetY, width, height, False);
 
181
      XSync(xWindow->display,false); /* true not needed, done by XPending */
 
182
      break;
 
183
      
 
184
      
 
185
    case VIDEO_XI_STANDARD:
 
186
#endif
 
187
      XPutImage(xWindow->display,xWindow->window,
 
188
                xWindow->gc, ximage,
 
189
                0, 0, iOffsetX, iOffsetY, width, height);      
 
190
      XSync(xWindow->display,false); /* true not needed, done by XPending */
 
191
#ifdef X11_SHARED_MEM
 
192
      break;
 
193
    }
 
194
#endif
 
195
}
 
196
 
 
197
 
 
198
 
 
199
int ImageDeskX11::createImage(int createType,int mode) {
 
200
 
 
201
  if (xWindow == NULL) {
 
202
    cout << "ImageDeskX11::createImage - you have to call init first!" << endl;
 
203
    return false;
 
204
  }
 
205
  
 
206
  videoaccesstype=VIDEO_XI_NONE;
 
207
 
 
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;
 
213
      }
 
214
    }
 
215
  } else {
 
216
    if (createType & VIDEO_XI_SHMSTD) {
 
217
      return ERR_XI_NOSHAREDMEMORY;
 
218
    }
 
219
  }
 
220
#endif
 
221
  if (videoaccesstype == VIDEO_XI_NONE) {
 
222
    videoaccesstype=createType;
 
223
  }
 
224
    
 
225
  switch(videoaccesstype)
 
226
    {
 
227
#ifdef X11_SHARED_MEM
 
228
 
 
229
 
 
230
    case VIDEO_XI_SHMSTD:
 
231
 
 
232
      lXerror=false;
 
233
      XSetErrorHandler(dummy);
 
234
 
 
235
      shmseginfo=(XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo));
 
236
      if(!shmseginfo)
 
237
        return ERR_XI_SHMALLOC;
 
238
 
 
239
      memset(shmseginfo,0, sizeof(XShmSegmentInfo));
 
240
 
 
241
      if (imageMode & _IMAGE_DOUBLE) {
 
242
        ximage=XShmCreateImage(xWindow->display,xWindow->visual,
 
243
                               xWindow->depth,
 
244
                               ZPixmap,NULL,shmseginfo,2*xWindow->width,
 
245
                               2*xWindow->height);
 
246
      } else {
 
247
        ximage=XShmCreateImage(xWindow->display,xWindow->visual,
 
248
                               xWindow->depth,
 
249
                               ZPixmap,NULL,shmseginfo,xWindow->width,
 
250
                               xWindow->height);
 
251
      }
 
252
      
 
253
      if(!ximage)
 
254
        return ERR_XI_SHMXIMAGE;
 
255
      
 
256
      shmseginfo->shmid=shmget(IPC_PRIVATE,
 
257
                               ximage->bytes_per_line*
 
258
                               ximage->height,IPC_CREAT|0777);
 
259
 
 
260
      if(shmseginfo->shmid<0)
 
261
        return ERR_XI_SHMSEGINFO;
 
262
      
 
263
      shmseginfo->shmaddr=(char*)shmat(shmseginfo->shmid,NULL,0);
 
264
      ximage->data=shmseginfo->shmaddr;
 
265
      virtualscreen=(unsigned char *)ximage->data;
 
266
 
 
267
      if(!virtualscreen)
 
268
        return ERR_XI_SHMVIRTALLOC;
 
269
 
 
270
      shmseginfo->readOnly=False;
 
271
 
 
272
      XShmAttach(xWindow->display,shmseginfo);
 
273
      XSync(xWindow->display, False);
 
274
      XSetErrorHandler(NULL);
 
275
      XFlush(xWindow->display);
 
276
      if (lXerror) {
 
277
        cout << "ERR_XI_SHMATTACH -2"<<endl;
 
278
        return ERR_XI_SHMATTACH;
 
279
      }
 
280
 
 
281
      break;
 
282
#endif
 
283
 
 
284
    case VIDEO_XI_STANDARD:
 
285
      if (mode & _IMAGE_DOUBLE) {
 
286
        virtualscreen=(unsigned char *)
 
287
          malloc(xWindow->screensize*sizeof(char)*4);
 
288
        
 
289
        if(virtualscreen==NULL)
 
290
          return ERR_XI_VIRTALLOC;
 
291
        
 
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);
 
297
      } else {
 
298
        virtualscreen=(unsigned char *)
 
299
          malloc(xWindow->screensize*sizeof(char));
 
300
        
 
301
        if(virtualscreen==NULL)
 
302
          return ERR_XI_VIRTALLOC;
 
303
        
 
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);
 
309
      }
 
310
      
 
311
      if(!ximage)
 
312
        return ERR_XI_XIMAGE;
 
313
      break;
 
314
      
 
315
    default:
 
316
      return ERR_XI_FAILURE;
 
317
 
 
318
    }
 
319
 
 
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;
 
325
#else
 
326
    ximage->byte_order = MSBFirst;
 
327
    ximage->bitmap_bit_order = MSBFirst;
 
328
#endif
 
329
    
 
330
  }
 
331
  return ERR_XI_OK;
 
332
}
 
333
 
 
334
 
 
335
 
 
336
int ImageDeskX11::destroyImage() {
 
337
  if(xWindow && xWindow->display && xWindow->window) {
 
338
    switch(videoaccesstype) {
 
339
#ifdef X11_SHARED_MEM
 
340
    case VIDEO_XI_SHMSTD:
 
341
      if (shmseginfo) {
 
342
        XShmDetach(xWindow->display,shmseginfo);
 
343
        if(ximage) {
 
344
          XDestroyImage(ximage);
 
345
          ximage=NULL;
 
346
        }
 
347
        if(shmseginfo->shmaddr) {
 
348
          shmdt(shmseginfo->shmaddr);
 
349
          shmseginfo->shmaddr=NULL;
 
350
        }
 
351
        if(shmseginfo->shmid>=0)
 
352
          shmctl(shmseginfo->shmid,IPC_RMID,NULL);
 
353
        
 
354
        free(shmseginfo);
 
355
      }
 
356
      shmseginfo=NULL;
 
357
      break;
 
358
      
 
359
#endif
 
360
    case VIDEO_XI_STANDARD:
 
361
      if(ximage) {
 
362
        XDestroyImage(ximage);
 
363
        ximage=NULL;
 
364
        /*
 
365
          XDestroyImage function calls frees both the image structure
 
366
          and the data pointed to by the image structure.
 
367
        */
 
368
        virtualscreen=NULL;
 
369
      }
 
370
      break;
 
371
 
 
372
    default:
 
373
                //      cout << "no open window to close"<<endl;
 
374
                break;
 
375
    }
 
376
  }
 
377
  videoaccesstype=VIDEO_XI_NONE;
 
378
  imageMode=_IMAGE_NONE;
 
379
  return true;
 
380
}
 
381
 
 
382
 
 
383
bool ImageDeskX11::switchMode(int width, int , bool zoom)
 
384
{
 
385
        iWidth = xWindow->screenptr->width;
 
386
        iHeight = xWindow->screenptr->height;
 
387
 
 
388
#ifdef X11_XVIDMODE
 
389
        iOldMode = -1;
 
390
        int vm_count,i;
 
391
 
 
392
        cout << "Find best matching videomode ..." << endl;
 
393
 
 
394
        if (!XF86VidModeGetAllModeLines(xWindow->display,XDefaultScreen(xWindow->display),
 
395
                                                                        &vm_count,&vm_modelines)) {
 
396
                return false;
 
397
        }
 
398
 
 
399
        int bestMode = -1;
 
400
        int border, minBorder = MAXINT;
 
401
 
 
402
        for (i = 0; i < vm_count; i++) {
 
403
                printf("mode %d: %dx%d\n",i, vm_modelines[i]->hdisplay,vm_modelines[i]->vdisplay);
 
404
 
 
405
                if (xWindow->screenptr->width == vm_modelines[i]->hdisplay)
 
406
                        iOldMode = i;
 
407
                        
 
408
                border = vm_modelines[i]->hdisplay - width;
 
409
                if ((border > 0) && (border < minBorder)) {
 
410
                        bestMode = i;
 
411
                        minBorder = border;
 
412
                        bZoom = false;
 
413
                }
 
414
                if (zoom) {
 
415
                        border = vm_modelines[i]->hdisplay - 2 * width;
 
416
                        if ((border > 0) && (border < minBorder)) {
 
417
                                bestMode = i;
 
418
                                minBorder = border;
 
419
                                bZoom = true;
 
420
                        }
 
421
                }
 
422
        }
 
423
        cout << "best mode: " << bestMode << endl;
 
424
 
 
425
        iWidth = vm_modelines[bestMode]->hdisplay;
 
426
        iHeight = vm_modelines[bestMode]->vdisplay;
 
427
        
 
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);
 
432
                return true;
 
433
        }
 
434
#endif
 
435
        return false;
 
436
}