~ubuntu-branches/ubuntu/jaunty/ekiga/jaunty-updates

« back to all changes in this revision

Viewing changes to lib/gui/xwindow.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2008-12-07 10:30:45 UTC
  • mfrom: (1.2.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20081207103045-iaurrjo4p7d1nngo
Tags: 3.0.1-1ubuntu1
* Merge to Debian experimental, to get Ekiga 3. (LP: #274085) Remaining
  Ubuntu changes:
  - Launchpad Integration: (Ubuntu specific)
    + debian/control.in: Add liblaunchpad-integration-dev build dependency.
    + Add ubuntu_lpi.patch: Call launchpad_integration_add_items() in main() and
      check for the launchpad-integration pkg-config module.
    + Add autoconf.patch: autoconf changes from above patch.
  - Add ubuntu_desktop-file-onlyshowin.patch: Show ekiga in Mobile, too.
    (Ubuntu specific).
  - debian/control.in: Add missing fdupes build dependency for identical
    GNOME help file symlinking. (Debian #505536)
* Drop 42_change_pixmaps.dpatch: Many of the old icons do not exist any
  more, some have been replaced, and keeping the remaining three would make
  them look very inconsistent.
* Convert our dpatches to quilt patches and rewrite them for new upstream
  version.
* Add migrate_2.0_settings.patch: Properly migrate settings from
  2.0. Taken from upstream SVN, thanks to Damien Sandras!

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* Ekiga -- A VoIP and Video-Conferencing application
 
3
 * Copyright (C) 2000-2007 Damien Sandras
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software Foundation,
 
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 
18
 *
 
19
 *
 
20
 * Ekiga is licensed under the GPL license and as a special exception,
 
21
 * you have permission to link or otherwise combine this program with the
 
22
 * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
 
23
 * without applying the requirements of the GNU GPL to the OPAL, OpenH323
 
24
 * and PWLIB programs, as long as you do follow the requirements of the
 
25
 * GNU GPL for all the rest of the software thus combined.
 
26
 */
 
27
 
 
28
 
 
29
/*
 
30
 *                         XWindow.cpp  -  description
 
31
 *                         ----------------------------
 
32
 *   begin                : Fri Oct 26 2007
 
33
 *   copyright            : (C) 2007 by Matthias Schneider <ma30002000@yahoo.de>
 
34
 *   description          : High-level class offering direct X server drawing
 
35
 *
 
36
 */
 
37
 
 
38
 
 
39
#include "xwindow.h"
 
40
 
 
41
#include <ptlib/object.h>
 
42
 
 
43
extern "C" {
 
44
#include <pixops.h>
 
45
}
 
46
 
 
47
#ifdef HAVE_SHM
 
48
#include <sys/shm.h>
 
49
#include <sys/ipc.h>
 
50
#endif
 
51
 
 
52
#ifdef WORDS_BIGENDIAN
 
53
#define BO_NATIVE    MSBFirst
 
54
#define BO_NONNATIVE LSBFirst
 
55
#else
 
56
#define BO_NATIVE    LSBFirst
 
57
#define BO_NONNATIVE MSBFirst
 
58
#endif
 
59
 
 
60
struct xFormatsentry {
 
61
  const char* name;
 
62
  int depth;
 
63
  int planes;
 
64
  int byte_order;
 
65
  unsigned red_mask;
 
66
  unsigned green_mask;
 
67
  unsigned blue_mask;
 
68
} xFormats[] = {
 
69
  {"RGB24", 24, 3, MSBFirst,     0x00FF0000, 0x0000FF00, 0x000000FF}, //-RGB
 
70
  {"RGB24", 24, 3, LSBFirst,     0x000000FF, 0x0000FF00, 0x00FF0000}, //-BGR
 
71
  {"BGR24", 24, 3, MSBFirst,     0x000000FF, 0x0000FF00, 0x00FF0000}, //-BGR
 
72
  {"BGR24", 24, 3, LSBFirst,     0x00FF0000, 0x0000FF00, 0x000000FF}, //-RGB
 
73
  {"RGB32", 32, 4, BO_NATIVE,    0x000000FF, 0x0000FF00, 0x00FF0000}, //XBGR
 
74
  {"RGB32", 32, 4, BO_NONNATIVE, 0xFF000000, 0x00FF0000, 0x0000FF00}, //RGBX
 
75
  {"BGR32", 32, 4, BO_NATIVE,    0x00FF0000, 0x0000FF00, 0x000000FF}, //XRGB
 
76
  {"BGR32", 32, 4, BO_NONNATIVE, 0x0000FF00, 0x00FF0000, 0xFF000000}, //BGRX
 
77
  {"ARGB",   1, 0, MSBFirst,     0x00FF0000, 0x0000FF00, 0x000000FF},  //ARGB *
 
78
  {"BGR32",  1, 4, LSBFirst,     0x0000FF00, 0x00FF0000, 0xFF000000},  //ARGB
 
79
  {"ABGR",   1, 0, MSBFirst,     0x000000FF, 0x0000FF00, 0x00FF0000},  //ABGR *
 
80
  {"RGB32",  1, 4, LSBFirst,     0xFF000000, 0x00FF0000, 0x0000FF00},  //ABGR
 
81
  {"RGB32",  1, 4, MSBFirst,     0xFF000000, 0x00FF0000, 0x0000FF00},  //RGBA
 
82
  {"RGBA",   1, 0, LSBFirst,     0x000000FF, 0x0000FF00, 0x00FF0000},  //RGBA *
 
83
  {"BGR32",  1, 4, MSBFirst,     0x0000FF00, 0x00FF0000, 0xFF000000},  //BGRA
 
84
  {"BGRA",   1, 0, LSBFirst,     0x00FF0000, 0x0000FF00, 0x000000FF},  //BGRA *
 
85
  {NULL, 0, 0, 0, 0, 0, 0}
 
86
};
 
87
 
 
88
#ifdef HAVE_SHM
 
89
bool XWindow::_shmError = false;
 
90
 
 
91
static void catchXShmError(Display * , XErrorEvent * )
 
92
{
 
93
  XWindow::_shmError = true;
 
94
}
 
95
#endif
 
96
 
 
97
XWindow::XWindow()
 
98
{
 
99
  // initialize class variables
 
100
  _display = NULL;
 
101
  _rootWindow = 0;
 
102
  _XWindow = 0;
 
103
  _gc = NULL;
 
104
  _master = NULL;
 
105
  _slave = NULL;
 
106
 
 
107
  _imageWidth = 0;
 
108
  _imageHeight = 0;
 
109
 
 
110
  _useShm = false;
 
111
  _paintColorKey = false;
 
112
  _colorKey = 0;
 
113
  _wmType = 0;
 
114
  _isInitialized = false;
 
115
  _embedded = false;
 
116
  _state.fullscreen = false;
 
117
  _state.ontop = false;
 
118
  _state.decoration = true;
 
119
  _state.origLayer=0;
 
120
  _depth = 0;
 
121
 
 
122
  _XImage = NULL;
 
123
  _imageDataOrig = NULL;
 
124
  _outOffset = 0;
 
125
   snprintf (_colorFormat, sizeof(_colorFormat), "NONE");
 
126
  _planes = 0;
 
127
  _colorConverter = NULL;
 
128
  _frameBuffer = NULL;
 
129
 
 
130
#ifdef HAVE_SHM
 
131
  _XShmInfo.shmaddr = NULL;
 
132
#endif
 
133
 _scalingAlgorithm = NULL;
 
134
}
 
135
 
 
136
 
 
137
XWindow::~XWindow()
 
138
{
 
139
  XLockDisplay (_display);
 
140
 
 
141
#ifdef HAVE_SHM
 
142
    if (_useShm) {
 
143
      if (_isInitialized && _XShmInfo.shmaddr) {
 
144
        XShmDetach (_display, &_XShmInfo);
 
145
        shmdt (_XShmInfo.shmaddr);
 
146
      }
 
147
    } else
 
148
#endif
 
149
    {
 
150
      if (_XImage) {
 
151
        _XImage->data = _imageDataOrig;
 
152
      }
 
153
    }
 
154
 
 
155
  if (_XImage) {
 
156
    XDestroyImage(_XImage);
 
157
    _XImage = NULL;
 
158
  }
 
159
 
 
160
  _imageDataOrig = NULL;
 
161
 
 
162
  // shared data structures
 
163
  if (!_embedded && _gc)
 
164
    XFreeGC (_display, _gc);
 
165
 
 
166
  if (_XWindow) {
 
167
 
 
168
    PTRACE(4, "X11\tUnmapping and destroying Window with ID " << _XWindow);
 
169
    XUnmapWindow (_display, _XWindow);
 
170
    XDestroyWindow (_display, _XWindow);
 
171
    XFlush (_display);
 
172
  }
 
173
 
 
174
  XUnlockDisplay (_display);
 
175
 
 
176
  if (_colorConverter)
 
177
    delete (_colorConverter);
 
178
 
 
179
  if (_frameBuffer)
 
180
    free (_frameBuffer);
 
181
}
 
182
 
 
183
 
 
184
int 
 
185
XWindow::Init (Display* dp, 
 
186
                Window rootWindow, 
 
187
                GC gc, 
 
188
                int x, 
 
189
                int y,
 
190
                int windowWidth, 
 
191
                int windowHeight, 
 
192
                int imageWidth, 
 
193
                int imageHeight)
 
194
{
 
195
  _display = dp;
 
196
  _rootWindow = rootWindow;
 
197
  _imageWidth = imageWidth;
 
198
  _imageHeight = imageHeight;
 
199
 
 
200
  PTRACE(4, "X11\tInitiasing new X11 window with " << windowWidth << "x" << windowHeight << " at " << x << "," << y);
 
201
  XLockDisplay (_display);
 
202
 
 
203
  if (PTrace::CanTrace (4)) 
 
204
    DumpVisuals();
 
205
 
 
206
  if (!CreateAtomsAndWindow(gc, x, y, windowWidth, windowHeight)) {
 
207
    XUnlockDisplay(_display);
 
208
    return 0;
 
209
  }
 
210
  
 
211
  CreateXImage(windowWidth, windowHeight);
 
212
 
 
213
  _isInitialized = true;
 
214
  XUnlockDisplay (_display);
 
215
 
 
216
  // check if that format is supported 
 
217
  struct xFormatsentry* xFormat = xFormats;
 
218
  while (xFormat->name) {
 
219
    if (xFormat->depth == _XImage->bits_per_pixel &&
 
220
        xFormat->byte_order == _XImage->byte_order &&
 
221
        xFormat->red_mask   == _XImage->red_mask   &&
 
222
        xFormat->green_mask == _XImage->green_mask &&
 
223
        xFormat->blue_mask  == _XImage->blue_mask)
 
224
      break;
 
225
    xFormat++;
 
226
  }
 
227
  PTRACE(4, "X11\tXImage created with format: " << _XImage->bits_per_pixel <<" BPP,  "
 
228
          << "Byte order: " << (_XImage->byte_order ? "MSBFirst" : "LSBFirst")
 
229
          << " Native: " << (BO_NATIVE ? "MSBFirst" : "LSBFirst"));
 
230
  PTRACE(4, std::hex << "X11\tMask: Red: 0x" <<  _XImage->red_mask
 
231
                      <<         " Green: 0x" << _XImage->green_mask 
 
232
                      <<          " Blue: 0x" << _XImage->blue_mask << std::dec);
 
233
  if (!xFormat->name) {
 
234
    PTRACE(1, "X11\tX server image format not supported, please contact the developers");
 
235
    return 0;
 
236
  }
 
237
 
 
238
  snprintf (_colorFormat, sizeof(_colorFormat), "%s", xFormat->name);
 
239
  _outOffset = 0;
 
240
  _planes = xFormat->planes;
 
241
 
 
242
#ifdef WORDS_BIGENDIAN
 
243
  if (strcmp (xFormat->name, "BGRA") == 0) {
 
244
    snprintf (_colorFormat, sizeof(_colorFormat), "RGB32");
 
245
    _outOffset = 1;
 
246
    _planes = 4;
 
247
  } 
 
248
  if (strcmp (xFormat->name, "RGBA") == 0) {
 
249
    snprintf (_colorFormat, sizeof(_colorFormat), "BGR32");
 
250
    _outOffset = 1;
 
251
    _planes = 4;
 
252
  } 
 
253
#else
 
254
  if (strcmp (xFormat->name, "ABGR") == 0) {
 
255
    snprintf (_colorFormat, sizeof(_colorFormat), "BGR32");
 
256
    _outOffset = -1;
 
257
    _planes = 4;
 
258
  } 
 
259
  if (strcmp (xFormat->name, "ARGB") == 0) {
 
260
    snprintf (_colorFormat, sizeof(_colorFormat), "RGB32");
 
261
    _outOffset = -1;
 
262
    _planes = 4;
 
263
  } 
 
264
#endif
 
265
  PTRACE(4, "X11\tUsing color format: " << _colorFormat);
 
266
  PTRACE(4, "X11\tPlanes: " << _planes);
 
267
 
 
268
  PVideoFrameInfo srcFrameInfo, dstFrameInfo;
 
269
  srcFrameInfo.SetFrameSize(_imageWidth,_imageHeight);
 
270
  dstFrameInfo.SetFrameSize(_imageWidth,_imageHeight);
 
271
  dstFrameInfo.SetColourFormat(_colorFormat);
 
272
  _colorConverter = PColourConverter::Create(srcFrameInfo, dstFrameInfo);
 
273
  if (!_colorConverter)
 
274
    return 0;
 
275
 
 
276
  _frameBuffer = (uint8_t*) malloc (_imageWidth * _imageHeight * _planes);
 
277
 
 
278
  // detect the window manager type
 
279
  _wmType = GetWMType ();
 
280
  CalculateSize (windowWidth, windowHeight, true);
 
281
 
 
282
  return 1;
 
283
}
 
284
 
 
285
 
 
286
void 
 
287
XWindow::PutFrame (uint8_t* frame, 
 
288
                    uint16_t width, 
 
289
                    uint16_t height)
 
290
{
 
291
  if (!_XImage) 
 
292
    return;
 
293
 
 
294
  if (width != _imageWidth || height != _imageHeight) {
 
295
    PTRACE (1, "X11\tDynamic switching of resolution not supported\n");
 
296
    return;
 
297
  }
 
298
 
 
299
  XLockDisplay (_display);
 
300
 
 
301
 
 
302
  if ((_state.curWidth != _XImage->width) || (_state.curHeight!=_XImage->height))
 
303
    CreateXImage(_state.curWidth, _state.curHeight);
 
304
 
 
305
  _colorConverter->Convert((BYTE*)frame, (BYTE*)_frameBuffer);
 
306
 
 
307
  pixops_scale ((guchar*) _XImage->data,
 
308
                 0,0,
 
309
                 _state.curWidth, _state.curHeight,
 
310
                 _state.curWidth * _planes, //dest_rowstride
 
311
                 _planes,                   //dest_channels,
 
312
                 FALSE,                     //dest_has_alpha,
 
313
 
 
314
                 (const guchar*) _frameBuffer,
 
315
                 width,
 
316
                 height,
 
317
                 width * _planes,           //src_rowstride
 
318
                 _planes,                   //src_channels,
 
319
                 FALSE,                     //src_has_alpha,
 
320
 
 
321
                 (double) _state.curWidth / width,
 
322
                 (double) _state.curHeight / height,
 
323
                 (PixopsInterpType) _scalingAlgorithm);
 
324
 
 
325
       _XImage->data += _outOffset;
 
326
#ifdef HAVE_SHM
 
327
  if (_useShm)
 
328
  {
 
329
    XShmPutImage(_display, _XWindow, _gc, _XImage,
 
330
                 0, 0,
 
331
                 _state.curX, _state.curY,
 
332
                 _state.curWidth, _state.curHeight, false);
 
333
  } else
 
334
#endif
 
335
  {
 
336
    XPutImage(_display, _XWindow, _gc, _XImage,
 
337
              0, 0,
 
338
              _state.curX, _state.curY,
 
339
              _state.curWidth,_state.curHeight);
 
340
  }
 
341
  _XImage->data -= _outOffset;
 
342
 
 
343
  XUnlockDisplay (_display);
 
344
}
 
345
 
 
346
bool
 
347
XWindow::ProcessEvents()
 
348
{
 
349
  XEvent event;
 
350
  bool ret = false;
 
351
 
 
352
  XLockDisplay (_display);
 
353
  while (XCheckWindowEvent (_display, _XWindow, StructureNotifyMask 
 
354
                                              | SubstructureRedirectMask
 
355
                                              | ExposureMask
 
356
                                              | KeyPressMask
 
357
                                              | ButtonPressMask, &event) == True) {
 
358
 
 
359
    switch (event.type) {
 
360
      case ClientMessage:
 
361
              // If "closeWindow" is clicked do nothing right now 
 
362
              // (window is closed from the GUI)
 
363
              break;
 
364
 
 
365
      case ConfigureNotify:
 
366
              {
 
367
                // the window size has changed
 
368
                XConfigureEvent *xce = &(event.xconfigure);
 
369
 
 
370
                    // if a slave window exists it has to be resized as well
 
371
                if (_slave)
 
372
                  _slave->SetWindow (xce->width - (int) (xce->width / ( _state.fullscreen ? PIP_RATIO_FS : PIP_RATIO_WIN)),
 
373
                                     xce->height - (int) (_slave->GetYUVHeight () * xce->width / ( _state.fullscreen ? PIP_RATIO_FS :  PIP_RATIO_WIN) / _slave->GetYUVWidth ()),
 
374
                                     (int) (xce->width / ( _state.fullscreen ? PIP_RATIO_FS :  PIP_RATIO_WIN)),
 
375
                                     (int) (_slave->GetYUVHeight () * xce->width / ( _state.fullscreen ? PIP_RATIO_FS :  PIP_RATIO_WIN) / _slave->GetYUVWidth ()));
 
376
 
 
377
                CalculateSize (xce->width, xce->height, true);
 
378
 
 
379
                if( _paintColorKey ) {
 
380
 
 
381
                  XSetForeground( _display, _gc, _colorKey );
 
382
                  XFillRectangle( _display, _XWindow, _gc, _state.curX, _state.curY, _state.curWidth, _state.curHeight);
 
383
                }
 
384
              }
 
385
              break;
 
386
 
 
387
      case Expose:
 
388
              if (_paintColorKey) {
 
389
                XSetForeground( _display, _gc, _colorKey );
 
390
                XFillRectangle( _display, _XWindow, _gc, _state.curX, _state.curY, _state.curWidth, _state.curHeight);
 
391
              }
 
392
              ret = true;
 
393
              break;
 
394
 
 
395
      case KeyPress:
 
396
              // a key is pressed
 
397
              {
 
398
                XKeyEvent *xke = &(event.xkey);
 
399
                switch (xke->keycode) {
 
400
                  case 41:  
 
401
                    if (_master) 
 
402
                      _master->ToggleFullscreen (); 
 
403
                    else 
 
404
                      ToggleFullscreen (); // "f"
 
405
                    break;
 
406
                  case 40:  
 
407
                    if (_master) 
 
408
                      _master->ToggleDecoration (); 
 
409
                    else 
 
410
                      ToggleDecoration (); // "d"
 
411
                    break;
 
412
                  case 32:  
 
413
                    if (_master) 
 
414
                      _master->ToggleOntop (); 
 
415
                    else 
 
416
                      ToggleOntop ();      // "o"
 
417
                    break;
 
418
                  case 9:   
 
419
                    if (_master) { 
 
420
                      if (_master->IsFullScreen ()) 
 
421
                        _master->ToggleFullscreen(); 
 
422
                    } // esc
 
423
                    else { 
 
424
                      if (IsFullScreen ()) 
 
425
                        ToggleFullscreen(); 
 
426
                    }
 
427
                    break;
 
428
                  default:
 
429
                    break;
 
430
                }
 
431
              }
 
432
              break;
 
433
 
 
434
    case ButtonPress:
 
435
              // a mouse button is clicked
 
436
 
 
437
              if (_master)
 
438
                if (!_master->HasDecoration())
 
439
                  _master->ToggleDecoration();
 
440
                else
 
441
                  _master->ToggleFullscreen();
 
442
              else 
 
443
                if (!_state.decoration)
 
444
                  ToggleDecoration();
 
445
                else
 
446
                  ToggleFullscreen();
 
447
              break;
 
448
 
 
449
    case DestroyNotify:
 
450
              PTRACE(4, "X11\tWindow is being destroyed");
 
451
              break;
 
452
 
 
453
    default:
 
454
              PTRACE(1, "X11\tUnknown X Event " << event.type << " received");
 
455
    }
 
456
  }
 
457
  XUnlockDisplay (_display);
 
458
 
 
459
  return ret;
 
460
}
 
461
 
 
462
 
 
463
void
 
464
XWindow::Sync()
 
465
{
 
466
  XLockDisplay(_display);
 
467
  XSync (_display, False);
 
468
  XUnlockDisplay(_display);
 
469
}
 
470
 
 
471
 
 
472
void 
 
473
XWindow::ToggleFullscreen ()
 
474
{
 
475
  if (_embedded)
 
476
    return;
 
477
 
 
478
  Window childWindow;
 
479
  XWindowAttributes xwattributes;
 
480
 
 
481
  int newX = 0;
 
482
  int newY = 0;
 
483
  int newWidth = 0;
 
484
  int newHeight = 0;
 
485
 
 
486
  if (_state.fullscreen) {
 
487
    
 
488
    // not needed with EWMH fs
 
489
    if (!(_wmType & wm_FULLSCREEN)) {
 
490
      
 
491
      newX = _state.oldx;
 
492
      newY = _state.oldy;
 
493
      newWidth = _state.oldWidth;
 
494
      newHeight = _state.oldHeight;
 
495
      SetDecoration (true);
 
496
    }
 
497
 
 
498
    // removes fullscreen state if wm supports EWMH
 
499
    SetEWMHFullscreen (_NET_WM_STATE_REMOVE);
 
500
  } 
 
501
  else {
 
502
 
 
503
    // sets fullscreen state if wm supports EWMH
 
504
    SetEWMHFullscreen (_NET_WM_STATE_ADD);
 
505
 
 
506
    // not needed with EWMH fs - save window coordinates/size 
 
507
    // and discover fullscreen window size
 
508
    if (!(_wmType & wm_FULLSCREEN)) {
 
509
 
 
510
      XLockDisplay (_display);
 
511
 
 
512
      newX = 0;
 
513
      newY = 0;
 
514
      newWidth = DisplayWidth (_display, DefaultScreen (_display));
 
515
      newHeight = DisplayHeight (_display, DefaultScreen (_display));
 
516
 
 
517
      SetDecoration (false);
 
518
      XFlush (_display);
 
519
 
 
520
      XTranslateCoordinates (_display, _XWindow, RootWindow (_display, DefaultScreen (_display)), 
 
521
                             0, 0, &_state.oldx, &_state.oldy, &childWindow);
 
522
 
 
523
      XGetWindowAttributes (_display, _XWindow, &xwattributes);
 
524
      XUnlockDisplay (_display);
 
525
      
 
526
      _state.oldWidth = xwattributes.width;
 
527
      _state.oldHeight = xwattributes.height;
 
528
    }
 
529
  }
 
530
  
 
531
  // not needed with EWMH fs - create a screen-filling window on top 
 
532
  // and turn of decorations
 
533
  if (!(_wmType & wm_FULLSCREEN)) {
 
534
 
 
535
    SetSizeHints (newX, newY, _XImage->width, _XImage->height, newWidth, newHeight);
 
536
 
 
537
    XLockDisplay (_display);
 
538
    SetLayer (!_state.fullscreen ? 0 : 1);
 
539
    XMoveResizeWindow (_display, _XWindow, newX, newY, newWidth, newHeight);
 
540
    XUnlockDisplay (_display);
 
541
  }
 
542
 
 
543
  // some WMs lose ontop after fullscreeen
 
544
  if (_state.fullscreen & _state.ontop)
 
545
    SetLayer (1);
 
546
 
 
547
  XLockDisplay (_display);
 
548
  XMapRaised (_display, _XWindow);
 
549
  XRaiseWindow (_display, _XWindow);
 
550
  XSync (_display, False);
 
551
  XUnlockDisplay (_display);
 
552
 
 
553
  _state.fullscreen = !_state.fullscreen;
 
554
}
 
555
 
 
556
 
 
557
void 
 
558
XWindow::ToggleOntop ()
 
559
{
 
560
  if (_embedded)
 
561
    return;
 
562
  SetLayer (_state.ontop ? 0 : 1);
 
563
  _state.ontop = !_state.ontop;
 
564
}
 
565
 
 
566
 
 
567
void 
 
568
XWindow::ToggleDecoration ()
 
569
{
 
570
  if (_embedded)
 
571
    return;
 
572
  SetDecoration (!_state.decoration);
 
573
}
 
574
 
 
575
 
 
576
void 
 
577
XWindow::SetWindow (int x, 
 
578
                    int y, 
 
579
                    unsigned int windowWidth, 
 
580
                    unsigned int windowHeight)
 
581
{
 
582
  PTRACE(4, "X11\tSetWindow " << x << "," << y << " " << windowWidth << "x" << windowHeight);
 
583
  XLockDisplay (_display);
 
584
  XMoveResizeWindow (_display, _XWindow, x, y, windowWidth, windowHeight);
 
585
  XUnlockDisplay (_display);
 
586
  CalculateSize (windowWidth, windowHeight, true);
 
587
}
 
588
 
 
589
 
 
590
void 
 
591
XWindow::GetWindow (int *x, 
 
592
                     int *y, 
 
593
                     unsigned int *windowWidth, 
 
594
                     unsigned int *windowHeight)
 
595
{
 
596
  unsigned int ud = 0; 
 
597
  Window _dw;
 
598
  
 
599
  int oldx = 0; 
 
600
  int oldy = 0;
 
601
  
 
602
  Window root;
 
603
  bool decoration = false;
 
604
  
 
605
  decoration = _state.decoration;
 
606
  SetDecoration (false);
 
607
 
 
608
  XLockDisplay (_display);
 
609
  XSync (_display, False); 
 
610
  XGetGeometry (_display, _XWindow, &root, &oldx, &oldy, windowWidth, windowHeight, &ud, &ud);
 
611
  XTranslateCoordinates (_display, _XWindow, root, oldx, oldy, x, y, &_dw);
 
612
  XUnlockDisplay (_display);
 
613
 
 
614
  SetDecoration (decoration);
 
615
}
 
616
 
 
617
 
 
618
 
 
619
bool
 
620
XWindow::CreateAtomsAndWindow(GC gc,
 
621
                              int x, 
 
622
                              int y,
 
623
                              int windowWidth,
 
624
                              int windowHeight)
 
625
{
 
626
  XSetWindowAttributes xswattributes;
 
627
 
 
628
  // initialize atoms
 
629
  WM_DELETE_WINDOW = XInternAtom (_display, "WM_DELETE_WINDOW", False);
 
630
  XA_WIN_PROTOCOLS = XInternAtom (_display, "_WIN_PROTOCOLS", False);
 
631
  XA_NET_SUPPORTED = XInternAtom (_display, "_NET_SUPPORTED", False);
 
632
  XA_NET_WM_STATE = XInternAtom (_display, "_NET_WM_STATE", False);
 
633
  XA_NET_WM_STATE_FULLSCREEN = XInternAtom (_display, "_NET_WM_STATE_FULLSCREEN", False);
 
634
  XA_NET_WM_STATE_ABOVE = XInternAtom (_display, "_NET_WM_STATE_ABOVE", False);
 
635
  XA_NET_WM_STATE_STAYS_ON_TOP = XInternAtom (_display, "_NET_WM_STATE_STAYS_ON_TOP", False);
 
636
  XA_NET_WM_STATE_BELOW = XInternAtom (_display, "_NET_WM_STATE_BELOW", False);
 
637
 
 
638
  XSync (_display, False);
 
639
 
 
640
  if (!checkDepth()) 
 
641
    return false;
 
642
 
 
643
  // define window properties and create the window
 
644
  xswattributes.colormap = XCreateColormap (_display, _rootWindow, _XVInfo.visual, AllocNone);
 
645
  xswattributes.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask;
 
646
 
 
647
  xswattributes.background_pixel = WhitePixel (_display, DefaultScreen (_display));
 
648
 
 
649
  xswattributes.border_pixel = WhitePixel (_display, DefaultScreen (_display));
 
650
 
 
651
  _XWindow = XCreateWindow (_display, _rootWindow, x, y, windowWidth, windowHeight, 
 
652
                             0, _XVInfo.depth, InputOutput, _XVInfo.visual, 
 
653
                             CWBackPixel | CWBorderPixel | CWColormap | CWEventMask,  &xswattributes);
 
654
 
 
655
  PTRACE(4, "X11\tCreated Window with ID " << _XWindow);
 
656
 
 
657
  SetSizeHints (DEFAULT_X,DEFAULT_Y, _imageWidth, _imageHeight, windowWidth, windowHeight);
 
658
  
 
659
  // map the window
 
660
  XMapWindow (_display, _XWindow);
 
661
 
 
662
  XSetWMProtocols (_display, _XWindow, &WM_DELETE_WINDOW, 1);
 
663
 
 
664
  // Checking if we are going embedded or not
 
665
  if (gc) {
 
666
    _gc = gc; 
 
667
    _embedded = true;
 
668
  }
 
669
  else {
 
670
    _gc = XCreateGC (_display, _XWindow, 0, 0);
 
671
    _embedded = false;
 
672
  }
 
673
  return true;
 
674
}
 
675
 
 
676
 
 
677
void 
 
678
XWindow::SetLayer (int layer)
 
679
{
 
680
  char *state = NULL;
 
681
 
 
682
  Window mRootWin = RootWindow (_display, DefaultScreen (_display));
 
683
  XEvent xev;
 
684
  memset (&xev, 0, sizeof(xev));
 
685
 
 
686
  if (_wmType & wm_LAYER) {
 
687
 
 
688
    if (!_state.origLayer) 
 
689
      _state.origLayer = GetGnomeLayer ();
 
690
    
 
691
    xev.type = ClientMessage;
 
692
    xev.xclient.display = _display;
 
693
    xev.xclient.window = _XWindow;
 
694
    xev.xclient.message_type = XA_WIN_LAYER;
 
695
    xev.xclient.format = 32;
 
696
    xev.xclient.data.l [0] = layer ? WIN_LAYER_ABOVE_DOCK : _state.origLayer;
 
697
    xev.xclient.data.l [1] = CurrentTime;
 
698
    PTRACE(4, "X11\tLayered style stay on top (layer " << xev.xclient.data.l[0] << ")");
 
699
    
 
700
    XLockDisplay (_display);
 
701
    XSendEvent (_display, mRootWin, FALSE, SubstructureNotifyMask,  &xev);
 
702
    XUnlockDisplay (_display);
 
703
 
 
704
  } 
 
705
  else if (_wmType & wm_NETWM) {
 
706
 
 
707
    xev.type = ClientMessage;
 
708
    xev.xclient.message_type = XA_NET_WM_STATE;
 
709
    xev.xclient.display = _display;
 
710
    xev.xclient.window = _XWindow;
 
711
    xev.xclient.format = 32;
 
712
    xev.xclient.data.l [0] = layer;
 
713
 
 
714
    if (_wmType & wm_STAYS_ON_TOP) 
 
715
      xev.xclient.data.l [1] = XA_NET_WM_STATE_STAYS_ON_TOP;
 
716
    else 
 
717
      if (_wmType & wm_ABOVE) 
 
718
        xev.xclient.data.l [1] = XA_NET_WM_STATE_ABOVE;
 
719
    else 
 
720
      if (_wmType & wm_FULLSCREEN) 
 
721
        xev.xclient.data.l [1] = XA_NET_WM_STATE_FULLSCREEN;
 
722
    else 
 
723
      if (_wmType & wm_BELOW) 
 
724
        xev.xclient.data.l [1] = XA_NET_WM_STATE_BELOW;
 
725
 
 
726
    XLockDisplay (_display);
 
727
    XSendEvent (_display, mRootWin, FALSE, SubstructureRedirectMask, &xev);
 
728
    state = XGetAtomName (_display, xev.xclient.data.l [1]);
 
729
    PTRACE(4, "X11\tNET style stay on top (layer " << layer << "). Using state " << state );
 
730
    XFree (state);
 
731
    XUnlockDisplay (_display);
 
732
  }
 
733
}
 
734
 
 
735
 
 
736
void 
 
737
XWindow::SetEWMHFullscreen (int action)
 
738
{
 
739
  if (_wmType & wm_FULLSCREEN) {
 
740
 
 
741
    // create an event event to toggle fullscreen mode
 
742
    XEvent xev;
 
743
    
 
744
    xev.xclient.type = ClientMessage;
 
745
    xev.xclient.serial = 0;
 
746
    xev.xclient.send_event = True;
 
747
    xev.xclient.message_type = XInternAtom (_display, "_NET_WM_STATE", False);
 
748
    xev.xclient.window = _XWindow;
 
749
    xev.xclient.format = 32;
 
750
    
 
751
    xev.xclient.data.l[0] = action;
 
752
    xev.xclient.data.l[1] = XInternAtom (_display, "_NET_WM_STATE_FULLSCREEN", False);
 
753
    xev.xclient.data.l[2] = 0;
 
754
    xev.xclient.data.l[3] = 0;
 
755
    xev.xclient.data.l[4] = 0;
 
756
 
 
757
    // send the event to the window
 
758
    XLockDisplay (_display);
 
759
    if (!XSendEvent (_display, _rootWindow, FALSE, SubstructureRedirectMask | SubstructureNotifyMask, &xev)) {
 
760
      PTRACE(1, "X11\tSetEWMHFullscreen failed");
 
761
    }
 
762
    XUnlockDisplay (_display);
 
763
  }
 
764
}
 
765
 
 
766
 
 
767
void 
 
768
XWindow::SetDecoration (bool d)
 
769
{
 
770
  Atom motifHints;
 
771
  Atom mType;
 
772
  
 
773
  MotifWmHints setHints;
 
774
  MotifWmHints *getHints = NULL;
 
775
  
 
776
  unsigned char *args = NULL;
 
777
 
 
778
  int mFormat = 0;
 
779
  unsigned long mn = 0;
 
780
  unsigned long mb = 0;
 
781
 
 
782
  static unsigned int oldDecor = MWM_DECOR_ALL;
 
783
  static unsigned int oldFuncs = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE;
 
784
 
 
785
  XLockDisplay (_display);
 
786
 
 
787
  motifHints = XInternAtom (_display, "_MOTIF_WM_HINTS", 0);
 
788
 
 
789
  if (motifHints != None) {
 
790
 
 
791
    memset (&setHints, 0, sizeof (setHints));
 
792
 
 
793
    if (!d) {
 
794
 
 
795
      XGetWindowProperty (_display, _XWindow, motifHints, 0, 20, False, motifHints, &mType, &mFormat, &mn, &mb, &args);
 
796
      getHints = (MotifWmHints*) args;
 
797
 
 
798
      if (getHints) {
 
799
 
 
800
        if (getHints->flags & MWM_HINTS_DECORATIONS) 
 
801
          oldDecor = getHints->decorations;
 
802
        
 
803
        if (getHints->flags & MWM_HINTS_FUNCTIONS) 
 
804
          oldFuncs = getHints->functions;
 
805
        
 
806
        XFree(getHints);
 
807
      }
 
808
 
 
809
      
 
810
      setHints.decorations = 0;
 
811
    } 
 
812
    else {
 
813
    
 
814
      setHints.functions = oldFuncs;
 
815
      setHints.decorations = oldDecor;
 
816
    }
 
817
 
 
818
    setHints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
 
819
    
 
820
    XChangeProperty (_display, _XWindow, motifHints, motifHints, 32, PropModeReplace, (unsigned char *) &setHints, 5);
 
821
    
 
822
    _state.decoration=!_state.decoration;
 
823
  }
 
824
 
 
825
  XUnlockDisplay (_display);
 
826
}
 
827
 
 
828
 
 
829
int 
 
830
XWindow::GetWMType ()
 
831
{
 
832
  Atom *args = NULL;
 
833
 
 
834
  unsigned int i = 0;
 
835
  int wmType = 0;
 
836
  int metacityHack = 0;
 
837
  unsigned long nitems = 0;
 
838
 
 
839
  // check if WM supports layers
 
840
  if (GetWindowProperty (XA_WIN_PROTOCOLS, &args, &nitems)) {
 
841
    
 
842
    PTRACE(4, "X11\tDetected WM supports layers");
 
843
    for (i = 0; i < nitems; i++) {
 
844
      
 
845
      if (args [i] == XA_WIN_LAYER) {
 
846
        wmType |= wm_LAYER;
 
847
        metacityHack |= 1;
 
848
      } 
 
849
      else 
 
850
        metacityHack |= 2;
 
851
    }
 
852
 
 
853
    XLockDisplay (_display);
 
854
    XFree (args);
 
855
    XUnlockDisplay (_display);
 
856
 
 
857
    // metacity WM reports that it supports layers, 
 
858
    // but it is not really true :-)
 
859
    if (wmType && metacityHack == 1) {
 
860
      wmType ^= wm_LAYER;
 
861
      PTRACE(4, "X11\tUsing workaround for Metacity bug");
 
862
    }
 
863
  }
 
864
 
 
865
  // NETWM
 
866
  if (GetWindowProperty (XA_NET_SUPPORTED, &args, &nitems)) {
 
867
    
 
868
    PTRACE(4, "X11\tDetected wm supports NetWM.");
 
869
 
 
870
    for (i = 0; i < nitems; i++) 
 
871
      wmType |= GetSupportedState (args[i]);
 
872
    
 
873
    XLockDisplay (_display);
 
874
    XFree (args);
 
875
    XUnlockDisplay (_display);
 
876
  }
 
877
 
 
878
  // unknown WM
 
879
  if (wmType == 0) {
 
880
    PTRACE(4, "X11\tUnknown wm type...");
 
881
  }
 
882
  
 
883
  return wmType;
 
884
}
 
885
 
 
886
 
 
887
int 
 
888
XWindow::GetGnomeLayer ()
 
889
{
 
890
  Atom type;
 
891
 
 
892
  int format = 0;
 
893
  unsigned long count = 0;
 
894
  unsigned long bytesafter = 0;
 
895
  unsigned char *prop = NULL;
 
896
 
 
897
  long layer = WIN_LAYER_NORMAL;
 
898
 
 
899
  XLockDisplay (_display);
 
900
  if (XGetWindowProperty (_display, _XWindow,XA_WIN_LAYER, 0, 16384, false, XA_CARDINAL, &type, &format, &count, &bytesafter, &prop) 
 
901
      == Success && prop) {
 
902
    
 
903
    if (type == XA_CARDINAL && format == 32 && count == 1) 
 
904
      layer = ((long *) prop) [0];
 
905
 
 
906
    XFree(prop);
 
907
  }
 
908
  XUnlockDisplay(_display);
 
909
 
 
910
  return layer;
 
911
}
 
912
 
 
913
 
 
914
int 
 
915
XWindow::GetSupportedState (Atom atom)
 
916
{
 
917
  if (atom == XA_NET_WM_STATE_FULLSCREEN)
 
918
    return wm_FULLSCREEN;
 
919
 
 
920
  if (atom == XA_NET_WM_STATE_ABOVE)
 
921
    return wm_ABOVE;
 
922
 
 
923
  if (atom == XA_NET_WM_STATE_STAYS_ON_TOP)
 
924
    return wm_STAYS_ON_TOP;
 
925
 
 
926
  if (atom==XA_NET_WM_STATE_BELOW)
 
927
    return wm_BELOW;
 
928
 
 
929
  return 0;
 
930
}
 
931
 
 
932
 
 
933
int 
 
934
XWindow::GetWindowProperty (Atom type, 
 
935
                             Atom **args, 
 
936
                             unsigned long *nitems)
 
937
{
 
938
  int format = 0;
 
939
  unsigned long bytesafter = 0;
 
940
  int ret = 0;
 
941
 
 
942
  XLockDisplay(_display);
 
943
  ret = (Success == XGetWindowProperty (_display, _rootWindow, type, 0, 16384, false,
 
944
         AnyPropertyType, &type, &format, nitems, &bytesafter, (unsigned char **) args) && *nitems > 0);
 
945
  XUnlockDisplay(_display);
 
946
 
 
947
  return ret; 
 
948
}
 
949
 
 
950
 
 
951
void 
 
952
XWindow::CalculateSize (int windowWidth,
 
953
                        int windowHeight,
 
954
                        bool doAspectCorrection) 
 
955
{
 
956
  if ( doAspectCorrection && ((windowWidth * _imageHeight / _imageWidth) > windowHeight)) {
 
957
 
 
958
    _state.curX = (int) ((windowWidth - (windowHeight * _imageWidth / _imageHeight)) / 2);
 
959
    _state.curY = 0;
 
960
    _state.curWidth = (int) (windowHeight * _imageWidth / _imageHeight);
 
961
    _state.curHeight = windowHeight;
 
962
 
 
963
  } 
 
964
  else if ( doAspectCorrection && ((windowHeight * _imageWidth / _imageHeight) > windowWidth)) {
 
965
 
 
966
    _state.curX = 0;
 
967
    _state.curY = (int) ((windowHeight - (windowWidth * _imageHeight / _imageWidth)) / 2);
 
968
    _state.curWidth = windowWidth;
 
969
    _state.curHeight = (int) (windowWidth * _imageHeight / _imageWidth);
 
970
  } 
 
971
  else {
 
972
 
 
973
    _state.curX = 0;
 
974
    _state.curY = 0;
 
975
    _state.curWidth = windowWidth;
 
976
    _state.curHeight = windowHeight;
 
977
  }
 
978
}
 
979
 
 
980
 
 
981
void 
 
982
XWindow::SetSizeHints (int x, 
 
983
                        int y, 
 
984
                        int imageWidth, 
 
985
                        int imageHeight, 
 
986
                        int windowWidth, 
 
987
                        int windowHeight)
 
988
{
 
989
  XSizeHints xshints;
 
990
 
 
991
  xshints.flags = PPosition | PSize | PAspect | PMinSize | PMaxSize;
 
992
 
 
993
  xshints.min_aspect.x = imageWidth;
 
994
  xshints.min_aspect.y = imageHeight;
 
995
  xshints.max_aspect.x = imageWidth;
 
996
  xshints.max_aspect.y = imageHeight;
 
997
 
 
998
  xshints.x = x;
 
999
  xshints.y = y;
 
1000
  xshints.width = windowWidth;
 
1001
  xshints.height = windowHeight;
 
1002
  xshints.min_width = windowWidth;
 
1003
  xshints.min_height = windowHeight;
 
1004
  xshints.max_width = windowWidth;
 
1005
  xshints.max_height = windowHeight;
 
1006
  
 
1007
  XSetStandardProperties (_display, _XWindow, "Video", "Video", None, NULL, 0, &xshints);
 
1008
}
 
1009
 
 
1010
 
 
1011
bool XWindow::checkDepth ()
 
1012
{
 
1013
 
 
1014
  XWindowAttributes xwattributes;
 
1015
  XGetWindowAttributes (_display, _rootWindow, &xwattributes);
 
1016
  if (xwattributes.depth == 32) {
 
1017
    _depth = 32;
 
1018
    if (!XMatchVisualInfo (_display, DefaultScreen (_display), _depth, TrueColor, &_XVInfo)) {
 
1019
      PTRACE(4, "X11\tCould not find visual with colordepth of " << _depth  << " bits per pixel");
 
1020
      _depth = 24;
 
1021
      if (!XMatchVisualInfo (_display, DefaultScreen (_display), _depth, TrueColor, &_XVInfo)) {
 
1022
        PTRACE(1, "X11\tCould neither find visual with colordepth of 32 bits per pixel nor with 24 bits per pixel");
 
1023
        return false;
 
1024
      }
 
1025
    }
 
1026
  }
 
1027
  else {
 
1028
    _depth = 24;
 
1029
    if (!XMatchVisualInfo (_display, DefaultScreen (_display), _depth, TrueColor, &_XVInfo)) {
 
1030
      PTRACE(4, "X11\tCould not find visual with colordepth of " << _depth  << " bits per pixel");
 
1031
      _depth = 32;
 
1032
      if (!XMatchVisualInfo (_display, DefaultScreen (_display), _depth, TrueColor, &_XVInfo)) {
 
1033
        PTRACE(1, "X11\tCould neither find visual with colordepth of 24 bits per pixel nor with 32 bits per pixel");
 
1034
        return false;
 
1035
      }
 
1036
    }
 
1037
  }
 
1038
  return true;
 
1039
}
 
1040
 
 
1041
 
 
1042
#ifdef HAVE_SHM
 
1043
void XWindow::ShmAttach(int imageWidth, int imageHeight)
 
1044
{
 
1045
  if (_useShm) {
 
1046
    _XImage = XShmCreateImage(_display, _XVInfo.visual, _depth, ZPixmap, NULL, &_XShmInfo, imageWidth, imageHeight);
 
1047
    if (_XImage == NULL) {
 
1048
      PTRACE(1, "X11\tXShmCreateImage failed");
 
1049
      _useShm = FALSE;
 
1050
    }
 
1051
  }
 
1052
 
 
1053
  if (_useShm) {
 
1054
    _XShmInfo.shmid = shmget(IPC_PRIVATE, _XImage->bytes_per_line * _XImage->height, IPC_CREAT | 0777);
 
1055
    if (_XShmInfo.shmid < 0) {
 
1056
       XDestroyImage(_XImage);
 
1057
       _XImage = NULL;
 
1058
       PTRACE(1, "X11\tshmget failed"); //strerror(errno)
 
1059
       _useShm = FALSE;
 
1060
    }
 
1061
  }
 
1062
 
 
1063
  if (_useShm) {
 
1064
    _XShmInfo.shmaddr = (char *) shmat(_XShmInfo.shmid, 0, 0);
 
1065
    if (_XShmInfo.shmaddr == ((char *) -1)) { 
 
1066
      XDestroyImage(_XImage);
 
1067
      _XImage = NULL;
 
1068
      PTRACE(1, "X11\tshmat failed"); //strerror(errno)
 
1069
      _useShm = FALSE;
 
1070
    }
 
1071
  }
 
1072
 
 
1073
  if (_useShm) {
 
1074
    _XImage->data = _XShmInfo.shmaddr;
 
1075
    _XShmInfo.readOnly = False;
 
1076
 
 
1077
    // Attaching the shared memory to the display
 
1078
    XErrorHandler oldHandler = XSetErrorHandler((XErrorHandler) catchXShmError);
 
1079
    Status status = XShmAttach (_display, &_XShmInfo);
 
1080
    XSync(_display, False);
 
1081
    XSetErrorHandler((XErrorHandler) oldHandler);
 
1082
 
 
1083
    if ( (status != True) || (_shmError) ) {
 
1084
      XDestroyImage(_XImage);
 
1085
      _XImage = NULL;
 
1086
      if (_XShmInfo.shmaddr != ((char *) -1)) {
 
1087
        shmdt(_XShmInfo.shmaddr);
 
1088
      }
 
1089
      PTRACE(1, "X11\t  XShmAttach failed");
 
1090
      if ( (status == True) && (_shmError) ) {
 
1091
        PTRACE(1, "X11\t  X server supports SHM but apparently we are remotely connected...");
 
1092
      }
 
1093
      _useShm = false;
 
1094
    } 
 
1095
  } 
 
1096
 
 
1097
  if (_useShm) {
 
1098
    shmctl(_XShmInfo.shmid, IPC_RMID, 0);
 
1099
  }
 
1100
}
 
1101
#endif
 
1102
 
 
1103
 
 
1104
void XWindow::CreateXImage(int width, int height)
 
1105
{
 
1106
#ifdef HAVE_SHM
 
1107
    if (_useShm) {
 
1108
      if (_isInitialized && _XShmInfo.shmaddr) {
 
1109
        XShmDetach (_display, &_XShmInfo);
 
1110
        shmdt (_XShmInfo.shmaddr);
 
1111
      }
 
1112
    } else
 
1113
#endif
 
1114
    {
 
1115
      if (_XImage) {
 
1116
        _XImage->data = _imageDataOrig;
 
1117
      }
 
1118
    }
 
1119
 
 
1120
  if (_XImage)
 
1121
    XDestroyImage(_XImage);
 
1122
 
 
1123
  _imageDataOrig = NULL;
 
1124
 
 
1125
#ifdef HAVE_SHM
 
1126
   if (XShmQueryExtension (_display)) {
 
1127
     _useShm = true;
 
1128
     PTRACE(1, "X11\tXQueryShmExtension success");
 
1129
   }
 
1130
   else {
 
1131
     _useShm = false;
 
1132
     PTRACE(1, "X11\tXQueryShmExtension failed");
 
1133
   }
 
1134
 
 
1135
  if (_useShm)
 
1136
     ShmAttach(width, height);
 
1137
 
 
1138
  if (_useShm) {
 
1139
     PTRACE(4, "X11\tUsing shm extension");
 
1140
  }
 
1141
  else
 
1142
#endif
 
1143
  {
 
1144
        _XImage = XCreateImage(_display, _XVInfo.visual, _depth, ZPixmap, 0, NULL,  width, height, 8, 0);
 
1145
         _imageDataOrig = (char*)malloc(width  * height * 4 + 32);
 
1146
         _XImage->data = _imageDataOrig + 16 - ((long)_imageDataOrig & 15);
 
1147
         memset(_XImage->data, 0, width * 4 * height);
 
1148
  }
 
1149
}
 
1150
 
 
1151
 
 
1152
void
 
1153
XWindow::DumpVisuals()
 
1154
{
 
1155
    XVisualInfo visualTemplate;
 
1156
    XVisualInfo *visuals;
 
1157
    int nbVisuals = 0;
 
1158
    int i = 0;
 
1159
 
 
1160
    visualTemplate.screen = DefaultScreen(_display);
 
1161
    visuals = XGetVisualInfo(_display, VisualScreenMask , &visualTemplate, &nbVisuals);
 
1162
    if (visuals != NULL) {
 
1163
        for (i = 0; i < nbVisuals; i++) {
 
1164
            PTRACE(4, "X11\tVisual #"  << i << " ID: " << visuals[i].visualid
 
1165
                       << " Class: "   << visuals[i].c_class  
 
1166
                       << " BPRGB: "     << visuals[i].bits_per_rgb
 
1167
                       << " Depth: "   << visuals[i].depth << std::hex
 
1168
                       << " Red: 0x"   << visuals[i].red_mask 
 
1169
                       << " Green: 0x" << visuals[i].green_mask
 
1170
                       << " Blue 0x"   << visuals[i].blue_mask << std::dec);
 
1171
        }
 
1172
        XFree(visuals);
 
1173
    }
 
1174
}