Qt 4.8
qgl_x11.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenGL module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qgl.h"
43 #include "qgl_p.h"
44 
45 #include "qmap.h"
46 #include "qapplication.h"
47 #include "qcolormap.h"
48 #include "qdesktopwidget.h"
49 #include "qpixmap.h"
50 #include "qhash.h"
51 #include "qlibrary.h"
52 #include "qdebug.h"
53 #include <private/qfontengine_ft_p.h>
54 #include <private/qt_x11_p.h>
55 #include <private/qpixmap_x11_p.h>
56 #include <private/qimagepixmapcleanuphooks_p.h>
57 #include <private/qunicodetables_p.h>
58 #ifdef Q_OS_HPUX
59 // for GLXPBuffer
60 #include <private/qglpixelbuffer_p.h>
61 #endif
62 
63 // We always define GLX_EXT_texture_from_pixmap ourselves because
64 // we can't trust system headers to do it properly
65 #define GLX_EXT_texture_from_pixmap 1
66 
67 #define INT8 dummy_INT8
68 #define INT32 dummy_INT32
69 #include <GL/glx.h>
70 #undef INT8
71 #undef INT32
72 
73 #include <X11/Xlib.h>
74 #include <X11/Xutil.h>
75 #include <X11/Xos.h>
76 #ifdef Q_OS_VXWORS
77 # ifdef open
78 # undef open
79 # endif
80 # ifdef getpid
81 # undef getpid
82 # endif
83 #endif // Q_OS_VXWORKS
84 #include <X11/Xatom.h>
85 
86 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
87 #include <dlfcn.h>
88 #endif
89 
91 
92 extern Drawable qt_x11Handle(const QPaintDevice *pd);
93 extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
94 
95 #ifndef GLX_ARB_multisample
96 #define GLX_SAMPLE_BUFFERS_ARB 100000
97 #define GLX_SAMPLES_ARB 100001
98 #endif
99 
100 #ifndef GLX_TEXTURE_2D_BIT_EXT
101 #define GLX_TEXTURE_2D_BIT_EXT 0x00000002
102 #define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
103 #define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
104 #define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
105 #define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
106 #define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
107 #define GLX_Y_INVERTED_EXT 0x20D4
108 #define GLX_TEXTURE_FORMAT_EXT 0x20D5
109 #define GLX_TEXTURE_TARGET_EXT 0x20D6
110 #define GLX_MIPMAP_TEXTURE_EXT 0x20D7
111 #define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
112 #define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
113 #define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
114 #define GLX_TEXTURE_2D_EXT 0x20DC
115 #define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
116 #define GLX_FRONT_LEFT_EXT 0x20DE
117 #endif
118 
119 #ifndef GLX_ARB_create_context
120 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
121 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
122 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
123 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
124 #define GLX_CONTEXT_FLAGS_ARB 0x2094
125 #endif
126 
127 #ifndef GLX_ARB_create_context_profile
128 #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
129 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
130 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
131 #endif
132 
133 /*
134  The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext()
135  and GLX (not Windows). If the application can't find any sharable
136  colormaps, it must at least create as few colormaps as possible. The
137  dictionary solution below ensures only one colormap is created per visual.
138  Colormaps are also deleted when the application terminates.
139 */
140 
141 struct QCMapEntry {
142  QCMapEntry();
143  ~QCMapEntry();
144 
145  Colormap cmap;
146  bool alloc;
147  XStandardColormap scmap;
148 };
149 
151 {
152  cmap = 0;
153  alloc = false;
154  scmap.colormap = 0;
155 }
156 
158 {
159  if (alloc)
160  XFreeColormap(X11->display, cmap);
161 }
164 static bool mesa_gl = false;
165 static bool first_time = true;
166 
167 static void cleanup_cmaps();
168 
171  cmap_hash = new CMapEntryHash;
172  qglcmap_hash = new GLCMapHash;
173  }
175  delete cmap_hash;
176  delete qglcmap_hash;
177  }
180 };
182 
183 static void cleanup_cmaps()
184 {
185  CMapEntryHash *hash = cmap_handler()->cmap_hash;
187  while (it != hash->constEnd()) {
188  delete it.value();
189  ++it;
190  }
191 
192  hash->clear();
193  cmap_handler()->qglcmap_hash->clear();
194 }
195 
196 Colormap qt_gl_choose_cmap(Display *dpy, XVisualInfo *vi)
197 {
198  if (first_time) {
199  const char *v = glXQueryServerString(dpy, vi->screen, GLX_VERSION);
200  if (v)
201  mesa_gl = (strstr(v, "Mesa") != 0);
202  first_time = false;
203  }
204 
205  CMapEntryHash *hash = cmap_handler()->cmap_hash;
206  CMapEntryHash::ConstIterator it = hash->constFind((long) vi->visualid + (vi->screen * 256));
207  if (it != hash->constEnd())
208  return it.value()->cmap; // found colormap for visual
209 
210  if (vi->visualid ==
211  XVisualIDFromVisual((Visual *) QX11Info::appVisual(vi->screen))) {
212  // qDebug("Using x11AppColormap");
213  return QX11Info::appColormap(vi->screen);
214  }
215 
216  QCMapEntry *x = new QCMapEntry();
217 
218  XStandardColormap *c;
219  int n, i;
220 
221  // qDebug("Choosing cmap for vID %0x", vi->visualid);
222 
223  if (mesa_gl) { // we're using MesaGL
224  Atom hp_cmaps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", true);
225  if (hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8) {
226  if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
227  hp_cmaps)) {
228  i = 0;
229  while (i < n && x->cmap == 0) {
230  if (c[i].visualid == vi->visual->visualid) {
231  x->cmap = c[i].colormap;
232  x->scmap = c[i];
233  //qDebug("Using HP_RGB scmap");
234 
235  }
236  i++;
237  }
238  XFree((char *)c);
239  }
240  }
241  }
242  if (!x->cmap) {
243  if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
244  XA_RGB_DEFAULT_MAP)) {
245  for (int i = 0; i < n && x->cmap == 0; ++i) {
246  if (!c[i].red_max ||
247  !c[i].green_max ||
248  !c[i].blue_max ||
249  !c[i].red_mult ||
250  !c[i].green_mult ||
251  !c[i].blue_mult)
252  continue; // invalid stdcmap
253  if (c[i].visualid == vi->visualid) {
254  x->cmap = c[i].colormap;
255  x->scmap = c[i];
256  //qDebug("Using RGB_DEFAULT scmap");
257  }
258  }
259  XFree((char *)c);
260  }
261  }
262  if (!x->cmap) { // no shared cmap found
263  x->cmap = XCreateColormap(dpy, RootWindow(dpy,vi->screen), vi->visual,
264  AllocNone);
265  x->alloc = true;
266  // qDebug("Allocating cmap");
267  }
268 
269  // colormap hash should be cleanup only when the QApplication dtor is called
270  if (hash->isEmpty())
272 
273  // associate cmap with visualid
274  hash->insert((long) vi->visualid + (vi->screen * 256), x);
275  return x->cmap;
276 }
277 
279 {
280  VisualID vis;
281  int screen;
282  long color;
283 };
284 
286 static int trans_colors_init = false;
287 
288 static void find_trans_colors()
289 {
290  struct OverlayProp {
291  long visual;
292  long type;
293  long value;
294  long layer;
295  };
296 
297  trans_colors_init = true;
298 
299  Display* appDisplay = X11->display;
300 
301  int scr;
302  int lastsize = 0;
303  for (scr = 0; scr < ScreenCount(appDisplay); scr++) {
304  QWidget* rootWin = QApplication::desktop()->screen(scr);
305  if (!rootWin)
306  return; // Should not happen
307  Atom overlayVisualsAtom = XInternAtom(appDisplay,
308  "SERVER_OVERLAY_VISUALS", True);
309  if (overlayVisualsAtom == XNone)
310  return; // Server has no overlays
311 
312  Atom actualType;
313  int actualFormat;
314  ulong nItems;
315  ulong bytesAfter;
316  unsigned char *retval = 0;
317  int res = XGetWindowProperty(appDisplay, rootWin->winId(),
318  overlayVisualsAtom, 0, 10000, False,
319  overlayVisualsAtom, &actualType,
320  &actualFormat, &nItems, &bytesAfter,
321  &retval);
322 
323  if (res != Success || actualType != overlayVisualsAtom
324  || actualFormat != 32 || nItems < 4 || !retval)
325  return; // Error reading property
326 
327  OverlayProp *overlayProps = (OverlayProp *)retval;
328 
329  int numProps = nItems / 4;
330  trans_colors.resize(lastsize + numProps);
331  int j = lastsize;
332  for (int i = 0; i < numProps; i++) {
333  if (overlayProps[i].type == 1) {
334  trans_colors[j].vis = (VisualID)overlayProps[i].visual;
335  trans_colors[j].screen = scr;
336  trans_colors[j].color = (int)overlayProps[i].value;
337  j++;
338  }
339  }
340  XFree(overlayProps);
341  lastsize = j;
342  trans_colors.resize(lastsize);
343  }
344 }
345 
346 /*****************************************************************************
347  QGLFormat UNIX/GLX-specific code
348  *****************************************************************************/
349 
350 void* qglx_getProcAddress(const char* procName)
351 {
352  // On systems where the GL driver is pluggable (like Mesa), we have to use
353  // the glXGetProcAddressARB extension to resolve other function pointers as
354  // the symbols wont be in the GL library, but rather in a plugin loaded by
355  // the GL library.
356  typedef void* (*qt_glXGetProcAddressARB)(const char *);
357  static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
358  static bool triedResolvingGlxGetProcAddress = false;
359  if (!triedResolvingGlxGetProcAddress) {
360  triedResolvingGlxGetProcAddress = true;
361  QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
362  if (extensions.match("GLX_ARB_get_proc_address")) {
363 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
364  void *handle = dlopen(NULL, RTLD_LAZY);
365  if (handle) {
366  glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
367  dlclose(handle);
368  }
369  if (!glXGetProcAddressARB)
370 #endif
371  {
372 #if !defined(QT_NO_LIBRARY)
373  extern const QString qt_gl_library_name();
376  glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
377 #endif
378  }
379  }
380  }
381 
382  void *procAddress = 0;
383  if (glXGetProcAddressARB)
384  procAddress = glXGetProcAddressARB(procName);
385 
386  // If glXGetProcAddress didn't work, try looking the symbol up in the GL library
387 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
388  if (!procAddress) {
389  void *handle = dlopen(NULL, RTLD_LAZY);
390  if (handle) {
391  procAddress = dlsym(handle, procName);
392  dlclose(handle);
393  }
394  }
395 #endif
396 #if !defined(QT_NO_LIBRARY)
397  if (!procAddress) {
398  extern const QString qt_gl_library_name();
401  procAddress = lib.resolve(procName);
402  }
403 #endif
404 
405  return procAddress;
406 }
407 
409 {
410  return glXQueryExtension(X11->display, 0, 0) != 0;
411 }
412 
413 
415 {
416  if (!trans_colors_init)
418  return trans_colors.size() > 0;
419 }
420 
421 static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice,
422  int bufDepth, bool onlyFBConfig = false)
423 {
424  int i = 0;
425  spec[i++] = GLX_LEVEL;
426  spec[i++] = f.plane();
427  const QX11Info *xinfo = qt_x11Info(paintDevice);
428  bool useFBConfig = onlyFBConfig;
429 
430 #if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX)
431  /*
432  HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
433  Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
434  */
435  QWidget* widget = 0;
436  if (paintDevice->devType() == QInternal::Widget)
437  widget = static_cast<QWidget*>(paintDevice);
438 
439  // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual
440  if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender)
441  useFBConfig = true;
442 #endif
443 
444 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
445  static bool useTranspExt = false;
446  static bool useTranspExtChecked = false;
447  if (f.plane() && !useTranspExtChecked && paintDevice) {
448  QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
449  useTranspExt = extensions.match("GLX_EXT_visual_info");
450  //# (A bit simplistic; that could theoretically be a substring)
451  if (useTranspExt) {
452  QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
453  useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
454  if (useTranspExt) {
455  // bug workaround - some systems (eg. FireGL) refuses to return an overlay
456  // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if
457  // the implementation supports transparent overlays
458  int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
459  f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
460  XNone };
461  XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec);
462  if (!vinf) {
463  useTranspExt = false;
464  }
465  }
466  }
467 
468  useTranspExtChecked = true;
469  }
470  if (f.plane() && useTranspExt && !useFBConfig) {
471  // Required to avoid non-transparent overlay visual(!) on some systems
472  spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
473  spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
474  }
475 #endif
476 
477 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
478  // GLX_RENDER_TYPE is only in glx >=1.3
479  if (useFBConfig) {
480  spec[i++] = GLX_RENDER_TYPE;
481  spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
482  }
483 #endif
484 
485  if (f.doubleBuffer())
486  spec[i++] = GLX_DOUBLEBUFFER;
487  if (useFBConfig)
488  spec[i++] = True;
489  if (f.depth()) {
490  spec[i++] = GLX_DEPTH_SIZE;
491  spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
492  }
493  if (f.stereo()) {
494  spec[i++] = GLX_STEREO;
495  if (useFBConfig)
496  spec[i++] = True;
497  }
498  if (f.stencil()) {
499  spec[i++] = GLX_STENCIL_SIZE;
500  spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
501  }
502  if (f.rgba()) {
503  if (!useFBConfig)
504  spec[i++] = GLX_RGBA;
505  spec[i++] = GLX_RED_SIZE;
506  spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
507  spec[i++] = GLX_GREEN_SIZE;
508  spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
509  spec[i++] = GLX_BLUE_SIZE;
510  spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
511  if (f.alpha()) {
512  spec[i++] = GLX_ALPHA_SIZE;
513  spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
514  }
515  if (f.accum()) {
516  spec[i++] = GLX_ACCUM_RED_SIZE;
517  spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
518  spec[i++] = GLX_ACCUM_GREEN_SIZE;
519  spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
520  spec[i++] = GLX_ACCUM_BLUE_SIZE;
521  spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
522  if (f.alpha()) {
523  spec[i++] = GLX_ACCUM_ALPHA_SIZE;
524  spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
525  }
526  }
527  } else {
528  spec[i++] = GLX_BUFFER_SIZE;
529  spec[i++] = bufDepth;
530  }
531 
532  if (f.sampleBuffers()) {
533  spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
534  spec[i++] = 1;
535  spec[i++] = GLX_SAMPLES_ARB;
536  spec[i++] = f.samples() == -1 ? 4 : f.samples();
537  }
538 
539 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
540  if (useFBConfig) {
541  spec[i++] = GLX_DRAWABLE_TYPE;
542  switch(paintDevice->devType()) {
543  case QInternal::Pixmap:
544  spec[i++] = GLX_PIXMAP_BIT;
545  break;
546  case QInternal::Pbuffer:
547  spec[i++] = GLX_PBUFFER_BIT;
548  break;
549  default:
550  qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType());
551  // Fall-through & assume it's a window
552  case QInternal::Widget:
553  spec[i++] = GLX_WINDOW_BIT;
554  break;
555  };
556  }
557 #endif
558 
559  spec[i] = XNone;
560  return useFBConfig;
561 }
562 
563 /*****************************************************************************
564  QGLContext UNIX/GLX-specific code
565  *****************************************************************************/
566 
567 bool QGLContext::chooseContext(const QGLContext* shareContext)
568 {
569  Q_D(QGLContext);
570  const QX11Info *xinfo = qt_x11Info(d->paintDevice);
571 
572  Display* disp = xinfo->display();
573  d->vi = chooseVisual();
574  if (!d->vi)
575  return false;
576 
577  if (deviceIsPixmap() &&
578  (((XVisualInfo*)d->vi)->depth != xinfo->depth() ||
579  ((XVisualInfo*)d->vi)->screen != xinfo->screen()))
580  {
581  XFree(d->vi);
582  XVisualInfo appVisInfo;
583  memset(&appVisInfo, 0, sizeof(XVisualInfo));
584  appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual());
585  appVisInfo.screen = xinfo->screen();
586  int nvis;
587  d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis);
588  if (!d->vi)
589  return false;
590 
591  int useGL;
592  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL);
593  if (!useGL)
594  return false; //# Chickening out already...
595  }
596  int res;
597  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res);
598  d->glFormat.setPlane(res);
599  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res);
600  d->glFormat.setDoubleBuffer(res);
601  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res);
602  d->glFormat.setDepth(res);
603  if (d->glFormat.depth())
604  d->glFormat.setDepthBufferSize(res);
605  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res);
606  d->glFormat.setRgba(res);
607  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res);
608  d->glFormat.setRedBufferSize(res);
609  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res);
610  d->glFormat.setGreenBufferSize(res);
611  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res);
612  d->glFormat.setBlueBufferSize(res);
613  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res);
614  d->glFormat.setAlpha(res);
615  if (d->glFormat.alpha())
616  d->glFormat.setAlphaBufferSize(res);
617  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res);
618  d->glFormat.setAccum(res);
619  if (d->glFormat.accum())
620  d->glFormat.setAccumBufferSize(res);
621  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res);
622  d->glFormat.setStencil(res);
623  if (d->glFormat.stencil())
624  d->glFormat.setStencilBufferSize(res);
625  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res);
626  d->glFormat.setStereo(res);
627  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res);
628  d->glFormat.setSampleBuffers(res);
629  if (d->glFormat.sampleBuffers()) {
630  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res);
631  d->glFormat.setSamples(res);
632  }
633 
634  Bool direct = format().directRendering() ? True : False;
635 
636  if (shareContext &&
637  (!shareContext->isValid() || !shareContext->d_func()->cx)) {
638  qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
639  shareContext = 0;
640  }
641 
642  // 1. Sharing between rgba and color-index will give wrong colors.
643  // 2. Contexts cannot be shared btw. direct/non-direct renderers.
644  // 3. Pixmaps cannot share contexts that are set up for direct rendering.
645  // 4. If the contexts are not created on the same screen, they can't be shared
646 
647  if (shareContext
648  && (format().rgba() != shareContext->format().rgba()
649  || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx))
650  || (shareContext->d_func()->screen != xinfo->screen())))
651  {
652  shareContext = 0;
653  }
654 
655  const int major = d->reqFormat.majorVersion();
656  const int minor = d->reqFormat.minorVersion();
657  const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile
660 
661  d->cx = 0;
662 
663 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
664  /*
665  HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
666  Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
667  */
668  if ((major == 3 && minor >= 2) || major > 3) {
669  QGLTemporaryContext *tmpContext = 0;
671  tmpContext = new QGLTemporaryContext;
672 
673  int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major,
676  0 };
677 
678  typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC)
679  (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
680 
681 
682  Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
683  (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB");
684 
685  if (glXCreateContextAttribs) {
686  int spec[45];
687  glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res);
688  buildSpec(spec, format(), d->paintDevice, res, true);
689 
690  GLXFBConfig *configs;
691  int configCount = 0;
692  configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount);
693 
694  if (configs && configCount > 0) {
695  d->cx = glXCreateContextAttribs(disp, configs[0],
696  shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes);
697  if (!d->cx && shareContext) {
698  shareContext = 0;
699  d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes);
700  }
701  d->screen = ((XVisualInfo*)d->vi)->screen;
702  }
703  XFree(configs);
704  } else {
705  qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor);
706  }
707 
708  if (tmpContext)
709  delete tmpContext;
710  }
711 #else
712  Q_UNUSED(major);
713  Q_UNUSED(minor);
714  Q_UNUSED(profile);
715 #endif
716 
717  if (!d->cx && shareContext) {
718  d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi,
719  (GLXContext)shareContext->d_func()->cx, direct);
720  d->screen = ((XVisualInfo*)d->vi)->screen;
721  }
722  if (!d->cx) {
723  d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct);
724  d->screen = ((XVisualInfo*)d->vi)->screen;
725  shareContext = 0;
726  }
727 
728  if (shareContext && d->cx) {
729  QGLContext *share = const_cast<QGLContext *>(shareContext);
730  d->sharing = true;
731  share->d_func()->sharing = true;
732  }
733 
734  if (!d->cx)
735  return false;
736  d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx));
737  if (deviceIsPixmap()) {
738 #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
739  d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi,
740  qt_x11Handle(d->paintDevice),
741  qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi));
742 #else
743  d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi,
744  qt_x11Handle(d->paintDevice));
745 #endif
746  if (!d->gpm)
747  return false;
748  }
749  QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
750  if (extensions.match("GLX_SGI_video_sync")) {
751  if (d->glFormat.swapInterval() == -1)
752  d->glFormat.setSwapInterval(0);
753  } else {
754  d->glFormat.setSwapInterval(-1);
755  }
756  return true;
757 }
758 
759 /*
760  See qgl.cpp for qdoc comment.
761  */
763 {
764  Q_D(QGLContext);
765  static const int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also?
766  //todo: if pixmap, also make sure that vi->depth == pixmap->depth
767  void* vis = 0;
768  int i = 0;
769  bool fail = false;
770  QGLFormat fmt = format();
771  bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double
772  bool triedDouble = false;
773  bool triedSample = false;
774  if (fmt.sampleBuffers())
776  while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) {
777  if (!fmt.rgba() && bufDepths[i] > 1) {
778  i++;
779  continue;
780  }
781  if (tryDouble) {
782  fmt.setDoubleBuffer(true);
783  tryDouble = false;
784  triedDouble = true;
785  continue;
786  } else if (triedDouble) {
787  fmt.setDoubleBuffer(false);
788  triedDouble = false;
789  }
790  if (!triedSample && fmt.sampleBuffers()) {
791  fmt.setSampleBuffers(false);
792  triedSample = true;
793  continue;
794  }
795  if (fmt.stereo()) {
796  fmt.setStereo(false);
797  continue;
798  }
799  if (fmt.accum()) {
800  fmt.setAccum(false);
801  continue;
802  }
803  if (fmt.stencil()) {
804  fmt.setStencil(false);
805  continue;
806  }
807  if (fmt.alpha()) {
808  fmt.setAlpha(false);
809  continue;
810  }
811  if (fmt.depth()) {
812  fmt.setDepth(false);
813  continue;
814  }
815  if (fmt.doubleBuffer()) {
816  fmt.setDoubleBuffer(false);
817  continue;
818  }
819  fail = true;
820  }
821  d->glFormat = fmt;
822  return vis;
823 }
824 
825 /*
826  See qgl.cpp for qdoc comment.
827  */
828 void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
829 {
830  Q_D(QGLContext);
831  int spec[45];
832  const QX11Info *xinfo = qt_x11Info(d->paintDevice);
833  bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false);
834 
835  XVisualInfo* chosenVisualInfo = 0;
836 
837 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
838  while (useFBConfig) {
839  GLXFBConfig *configs;
840  int configCount = 0;
841  configs = glXChooseFBConfig(xinfo->display(), xinfo->screen(), spec, &configCount);
842 
843  if (!configs)
844  break; // fallback to trying glXChooseVisual
845 
846  for (int i = 0; i < configCount; ++i) {
847  XVisualInfo* vi;
848  vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]);
849  if (!vi)
850  continue;
851 
852 #if !defined(QT_NO_XRENDER)
853  QWidget* w = 0;
854  if (d->paintDevice->devType() == QInternal::Widget)
855  w = static_cast<QWidget*>(d->paintDevice);
856 
857  if (w && w->testAttribute(Qt::WA_TranslucentBackground) && f.alpha()) {
858  // Attempt to find a config who's visual has a proper alpha channel
859  XRenderPictFormat *pictFormat;
860  pictFormat = XRenderFindVisualFormat(xinfo->display(), vi->visual);
861 
862  if (pictFormat && (pictFormat->type == PictTypeDirect) && pictFormat->direct.alphaMask) {
863  // The pict format for the visual matching the FBConfig indicates ARGB
864  if (chosenVisualInfo)
865  XFree(chosenVisualInfo);
866  chosenVisualInfo = vi;
867  break;
868  }
869  } else
870 #endif //QT_NO_XRENDER
871  if (chosenVisualInfo) {
872  // If we've got a visual we can use and we're not trying to find one with a
873  // real alpha channel, we might as well just use the one we've got
874  break;
875  }
876 
877  if (!chosenVisualInfo)
878  chosenVisualInfo = vi; // Have something to fall back to
879  else
880  XFree(vi);
881  }
882 
883  XFree(configs);
884  break;
885  }
886 #endif // defined(GLX_VERSION_1_3)
887 
888  if (!chosenVisualInfo)
889  chosenVisualInfo = glXChooseVisual(xinfo->display(), xinfo->screen(), spec);
890 
891  return chosenVisualInfo;
892 }
893 
894 
895 void QGLContext::reset()
896 {
897  Q_D(QGLContext);
898  if (!d->valid)
899  return;
900  d->cleanup();
901  const QX11Info *xinfo = qt_x11Info(d->paintDevice);
902  doneCurrent();
903  if (d->gpm)
904  glXDestroyGLXPixmap(xinfo->display(), (GLXPixmap)d->gpm);
905  d->gpm = 0;
906  glXDestroyContext(xinfo->display(), (GLXContext)d->cx);
907  if (d->vi)
908  XFree(d->vi);
909  d->vi = 0;
910  d->cx = 0;
911  d->crWin = false;
912  d->sharing = false;
913  d->valid = false;
914  d->transpColor = QColor();
915  d->initDone = false;
917 }
918 
919 
921 {
922  Q_D(QGLContext);
923  if (!d->valid) {
924  qWarning("QGLContext::makeCurrent(): Cannot make invalid context current.");
925  return;
926  }
927  const QX11Info *xinfo = qt_x11Info(d->paintDevice);
928  bool ok = true;
929  if (d->paintDevice->devType() == QInternal::Pixmap) {
930  ok = glXMakeCurrent(xinfo->display(), (GLXPixmap)d->gpm, (GLXContext)d->cx);
931  } else if (d->paintDevice->devType() == QInternal::Pbuffer) {
932  ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx);
933  } else if (d->paintDevice->devType() == QInternal::Widget) {
934  ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx);
935  }
936  if (!ok)
937  qWarning("QGLContext::makeCurrent(): Failed.");
938 
939  if (ok)
941 }
942 
944 {
945  Q_D(QGLContext);
946  glXMakeCurrent(qt_x11Info(d->paintDevice)->display(), 0, 0);
948 }
949 
950 
951 void QGLContext::swapBuffers() const
952 {
953  Q_D(const QGLContext);
954  if (!d->valid)
955  return;
956  if (!deviceIsPixmap()) {
957  int interval = d->glFormat.swapInterval();
958  if (interval > 0) {
959  typedef int (*qt_glXGetVideoSyncSGI)(uint *);
960  typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *);
961  static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0;
962  static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0;
963  static bool resolved = false;
964  if (!resolved) {
965  const QX11Info *xinfo = qt_x11Info(d->paintDevice);
966  QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
967  if (extensions.match("GLX_SGI_video_sync")) {
968  glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
969  glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
970  }
971  resolved = true;
972  }
973  if (glXGetVideoSyncSGI && glXWaitVideoSyncSGI) {
974  uint counter;
975  if (!glXGetVideoSyncSGI(&counter))
976  glXWaitVideoSyncSGI(interval + 1, (counter + interval) % (interval + 1), &counter);
977  }
978  }
979  glXSwapBuffers(qt_x11Info(d->paintDevice)->display(),
980  static_cast<QWidget *>(d->paintDevice)->winId());
981  }
982 }
983 
985 {
986  if (isValid())
987  return Qt::transparent;
988  return QColor(); // Invalid color
989 }
990 
991 static uint qt_transparent_pixel(VisualID id, int screen)
992 {
993  for (int i = 0; i < trans_colors.size(); i++) {
994  if (trans_colors[i].vis == id && trans_colors[i].screen == screen)
995  return trans_colors[i].color;
996  }
997  return 0;
998 }
999 
1000 uint QGLContext::colorIndex(const QColor& c) const
1001 {
1002  Q_D(const QGLContext);
1003  int screen = ((XVisualInfo *)d->vi)->screen;
1004  QColormap colmap = QColormap::instance(screen);
1005  if (isValid()) {
1006  if (format().plane() && c == Qt::transparent) {
1007  return qt_transparent_pixel(((XVisualInfo *)d->vi)->visualid,
1008  ((XVisualInfo *)d->vi)->screen);
1009  }
1010  if (((XVisualInfo*)d->vi)->visualid ==
1011  XVisualIDFromVisual((Visual *) QX11Info::appVisual(screen)))
1012  return colmap.pixel(c); // We're using QColor's cmap
1013 
1014  XVisualInfo *info = (XVisualInfo *) d->vi;
1015  CMapEntryHash *hash = cmap_handler()->cmap_hash;
1016  CMapEntryHash::ConstIterator it = hash->constFind(long(info->visualid)
1017  + (info->screen * 256));
1018  QCMapEntry *x = 0;
1019  if (it != hash->constEnd())
1020  x = it.value();
1021  if (x && !x->alloc) { // It's a standard colormap
1022  int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0);
1023  int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0);
1024  int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0);
1025  uint p = x->scmap.base_pixel
1026  + (rf * x->scmap.red_mult)
1027  + (gf * x->scmap.green_mult)
1028  + (bf * x->scmap.blue_mult);
1029  return p;
1030  } else {
1031  QMap<int, QRgb> &cmap = (*cmap_handler()->qglcmap_hash)[(long)info->visualid];
1032 
1033  // already in the map?
1034  QRgb target = c.rgb();
1035  QMap<int, QRgb>::Iterator it = cmap.begin();
1036  for (; it != cmap.end(); ++it) {
1037  if ((*it) == target)
1038  return it.key();
1039  }
1040 
1041  // need to alloc color
1042  unsigned long plane_mask[2];
1043  unsigned long color_map_entry;
1044  if (!XAllocColorCells (QX11Info::display(), x->cmap, true, plane_mask, 0,
1045  &color_map_entry, 1))
1046  return colmap.pixel(c);
1047 
1048  XColor col;
1049  col.flags = DoRed | DoGreen | DoBlue;
1050  col.pixel = color_map_entry;
1051  col.red = (ushort)((qRed(c.rgb()) / 255.0) * 65535.0 + 0.5);
1052  col.green = (ushort)((qGreen(c.rgb()) / 255.0) * 65535.0 + 0.5);
1053  col.blue = (ushort)((qBlue(c.rgb()) / 255.0) * 65535.0 + 0.5);
1054  XStoreColor(QX11Info::display(), x->cmap, &col);
1055 
1056  cmap.insert(color_map_entry, target);
1057  return color_map_entry;
1058  }
1059  }
1060  return 0;
1061 }
1062 
1063 #ifndef QT_NO_FONTCONFIG
1064 
1073 static void qgl_use_font(QFontEngineFT *engine, int first, int count, int listBase)
1074 {
1075  GLfloat color[4];
1076  glGetFloatv(GL_CURRENT_COLOR, color);
1077 
1078  // save the pixel unpack state
1079  GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment;
1080  glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
1081  glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
1082  glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
1083  glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
1084  glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
1085  glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment);
1086 
1087  glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
1088  glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
1089  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1090  glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1091  glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1092  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1093 
1094  const bool antialiased = engine->drawAntialiased();
1095  FT_Face face = engine->lockFace();
1096 
1097  // start generating font glyphs
1098  for (int i = first; i < count; ++i) {
1099  int list = listBase + i;
1100  GLfloat x0, y0, dx, dy;
1101 
1102  FT_Error err;
1103 
1104  err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
1105  if (err) {
1106  qDebug("failed loading glyph %d from font", i);
1107  Q_ASSERT(!err);
1108  }
1109  err = FT_Render_Glyph(face->glyph, (antialiased ? FT_RENDER_MODE_NORMAL
1110  : FT_RENDER_MODE_MONO));
1111  if (err) {
1112  qDebug("failed rendering glyph %d from font", i);
1113  Q_ASSERT(!err);
1114  }
1115 
1116  FT_Bitmap bm = face->glyph->bitmap;
1117  x0 = face->glyph->metrics.horiBearingX >> 6;
1118  y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
1119  dx = face->glyph->metrics.horiAdvance >> 6;
1120  dy = 0;
1121  int sz = bm.pitch * bm.rows;
1122  uint *aa_glyph = 0;
1123  uchar *ua_glyph = 0;
1124 
1125  if (antialiased)
1126  aa_glyph = new uint[sz];
1127  else
1128  ua_glyph = new uchar[sz];
1129 
1130  // convert to GL format
1131  for (int y = 0; y < bm.rows; ++y) {
1132  for (int x = 0; x < bm.pitch; ++x) {
1133  int c1 = y*bm.pitch + x;
1134  int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
1135  if (antialiased) {
1136  aa_glyph[c1] = (int(color[0]*255) << 24)
1137  | (int(color[1]*255) << 16)
1138  | (int(color[2]*255) << 8) | bm.buffer[c2];
1139  } else {
1140  ua_glyph[c1] = bm.buffer[c2];
1141  }
1142  }
1143  }
1144 
1145  glNewList(list, GL_COMPILE);
1146  if (antialiased) {
1147  // calling glBitmap() is just a trick to move the current
1148  // raster pos, since glGet*() won't work in display lists
1149  glBitmap(0, 0, 0, 0, x0, -y0, 0);
1150  glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
1151  glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
1152  } else {
1153  glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
1154  }
1155  glEndList();
1156  antialiased ? delete[] aa_glyph : delete[] ua_glyph;
1157  }
1158 
1159  engine->unlockFace();
1160 
1161  // restore pixel unpack settings
1162  glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
1163  glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
1164  glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
1165  glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
1166  glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
1167  glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
1168 }
1169 #endif
1170 
1171 #undef d
1172 void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
1173 {
1174  QFont f(fnt);
1176 
1177  if (engine->type() == QFontEngine::Multi)
1178  engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
1179 #ifndef QT_NO_FONTCONFIG
1180  if(engine->type() == QFontEngine::Freetype) {
1181  qgl_use_font(static_cast<QFontEngineFT *>(engine), 0, 256, listBase);
1182  return;
1183  }
1184 #endif
1185  // glXUseXFont() only works with XLFD font structures and a few GL
1186  // drivers crash if 0 is passed as the font handle
1188  if (f.handle() && engine->type() == QFontEngine::XLFD)
1189  glXUseXFont(static_cast<Font>(f.handle()), 0, 256, listBase);
1190 }
1191 
1192 void *QGLContext::getProcAddress(const QString &proc) const
1193 {
1194  typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
1195  static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
1196  static bool resolved = false;
1197 
1198  if (resolved && !glXGetProcAddressARB)
1199  return 0;
1200  if (!glXGetProcAddressARB) {
1201  QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
1202  if (extensions.match("GLX_ARB_get_proc_address")) {
1203 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
1204  void *handle = dlopen(NULL, RTLD_LAZY);
1205  if (handle) {
1206  glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
1207  dlclose(handle);
1208  }
1209  if (!glXGetProcAddressARB)
1210 #endif
1211  {
1212 #if !defined(QT_NO_LIBRARY)
1213  extern const QString qt_gl_library_name();
1216  glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
1217 #endif
1218  }
1219  }
1220  resolved = true;
1221  }
1222  if (!glXGetProcAddressARB)
1223  return 0;
1224  return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(proc.toLatin1().data()));
1225 }
1226 
1227 /*
1228  QGLTemporaryContext implementation
1229 */
1230 
1232 public:
1235  GLXContext context;
1236  GLXDrawable oldDrawable;
1237  GLXContext oldContext;
1238 };
1239 
1242 {
1243  d->initialized = false;
1244  d->oldDrawable = 0;
1245  d->oldContext = 0;
1246  int screen = 0;
1247 
1248  int attribs[] = {GLX_RGBA, XNone};
1249  XVisualInfo *vi = glXChooseVisual(X11->display, screen, attribs);
1250  if (!vi) {
1251  qWarning("QGLTempContext: No GL capable X visuals available.");
1252  return;
1253  }
1254 
1255  int useGL;
1256  glXGetConfig(X11->display, vi, GLX_USE_GL, &useGL);
1257  if (!useGL) {
1258  XFree(vi);
1259  return;
1260  }
1261 
1262  d->oldDrawable = glXGetCurrentDrawable();
1263  d->oldContext = glXGetCurrentContext();
1264 
1265  XSetWindowAttributes a;
1266  a.colormap = qt_gl_choose_cmap(X11->display, vi);
1267  d->drawable = XCreateWindow(X11->display, RootWindow(X11->display, screen),
1268  0, 0, 1, 1, 0,
1269  vi->depth, InputOutput, vi->visual,
1270  CWColormap, &a);
1271  d->context = glXCreateContext(X11->display, vi, 0, True);
1272  if (d->context && glXMakeCurrent(X11->display, d->drawable, d->context)) {
1273  d->initialized = true;
1274  } else {
1275  qWarning("QGLTempContext: Unable to create GL context.");
1276  XDestroyWindow(X11->display, d->drawable);
1277  }
1278  XFree(vi);
1279 }
1280 
1282 {
1283  if (d->initialized) {
1284  glXMakeCurrent(X11->display, 0, 0);
1285  glXDestroyContext(X11->display, d->context);
1286  XDestroyWindow(X11->display, d->drawable);
1287  }
1288  if (d->oldDrawable && d->oldContext)
1289  glXMakeCurrent(X11->display, d->oldDrawable, d->oldContext);
1290 }
1291 
1292 /*****************************************************************************
1293  QGLOverlayWidget (Internal overlay class for X11)
1294  *****************************************************************************/
1295 
1297 {
1298  Q_OBJECT
1299 public:
1300  QGLOverlayWidget(const QGLFormat& format, QGLWidget* parent, const QGLWidget* shareWidget=0);
1301 
1302 protected:
1303  void initializeGL();
1304  void paintGL();
1305  void resizeGL(int w, int h);
1306  bool x11Event(XEvent *e) { return realWidget->x11Event(e); }
1307 
1308 private:
1310 
1311 private:
1313 };
1314 
1315 
1317  const QGLWidget* shareWidget)
1318  : QGLWidget(format, parent, shareWidget ? shareWidget->d_func()->olw : 0)
1319 {
1321  realWidget = parent;
1322 }
1323 
1324 
1325 
1327 {
1328  QColor transparentColor = context()->overlayTransparentColor();
1329  if (transparentColor.isValid())
1330  qglClearColor(transparentColor);
1331  else
1332  qWarning("QGLOverlayWidget::initializeGL(): Could not get transparent color");
1334 }
1335 
1336 
1337 void QGLOverlayWidget::resizeGL(int w, int h)
1338 {
1339  glViewport(0, 0, w, h);
1340  realWidget->resizeOverlayGL(w, h);
1341 }
1342 
1343 
1345 {
1347 }
1348 
1349 #undef Bool
1351 #include "qgl_x11.moc"
1353 
1354 /*****************************************************************************
1355  QGLWidget UNIX/GLX-specific code
1356  *****************************************************************************/
1357 void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
1358 {
1359  Q_Q(QGLWidget);
1360  initContext(context, shareWidget);
1361  olw = 0;
1362 
1363  if (q->isValid() && context->format().hasOverlay()) {
1364  QString olwName = q->objectName();
1365  olwName += QLatin1String("-QGL_internal_overlay_widget");
1366  olw = new QGLOverlayWidget(QGLFormat::defaultOverlayFormat(), q, shareWidget);
1367  olw->setObjectName(olwName);
1368  if (olw->isValid()) {
1369  olw->setAutoBufferSwap(false);
1370  olw->setFocusProxy(q);
1371  }
1372  else {
1373  delete olw;
1374  olw = 0;
1375  glcx->d_func()->glFormat.setOverlay(false);
1376  }
1377  }
1378 }
1379 
1381 {
1382  Q_Q(QGLWidget);
1383  if (((XVisualInfo*)glcx->d_func()->vi)->depth != pm->depth())
1384  return false;
1385 
1386  GLXPixmap glPm;
1387 #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
1388  glPm = glXCreateGLXPixmapMESA(X11->display,
1389  (XVisualInfo*)glcx->vi,
1390  (Pixmap)pm->handle(),
1391  qt_gl_choose_cmap(pm->X11->display,
1392  (XVisualInfo*)glcx->vi));
1393 #else
1394  glPm = (quint32)glXCreateGLXPixmap(X11->display,
1395  (XVisualInfo*)glcx->d_func()->vi,
1396  (Pixmap)pm->handle());
1397 #endif
1398 
1399  if (!glXMakeCurrent(X11->display, glPm, (GLXContext)glcx->d_func()->cx)) {
1400  glXDestroyGLXPixmap(X11->display, glPm);
1401  return false;
1402  }
1403 
1404  glDrawBuffer(GL_FRONT);
1405  if (!glcx->initialized())
1406  q->glInit();
1407  q->resizeGL(pm->width(), pm->height());
1408  q->paintGL();
1409  glFlush();
1410  q->makeCurrent();
1411  glXDestroyGLXPixmap(X11->display, glPm);
1412  q->resizeGL(q->width(), q->height());
1413  return true;
1414 }
1415 
1417 {
1418  if (!cmap.handle()) {
1419  return;
1420  } else {
1421  XFreeColormap(X11->display, (Colormap) cmap.handle());
1422  cmap.setHandle(0);
1423  }
1424 }
1425 
1426 void QGLWidget::setMouseTracking(bool enable)
1427 {
1428  Q_D(QGLWidget);
1429  if (d->olw)
1430  d->olw->setMouseTracking(enable);
1431  QWidget::setMouseTracking(enable);
1432 }
1433 
1434 
1436 {
1437  Q_D(QGLWidget);
1438  if (!isValid())
1439  return;
1440  makeCurrent();
1441  if (!d->glcx->initialized())
1442  glInit();
1443  glXWaitX();
1444  resizeGL(width(), height());
1445  if (d->olw)
1446  d->olw->setGeometry(rect());
1447 }
1448 
1450 {
1451  Q_D(const QGLWidget);
1452  if (d->olw)
1453  return d->olw->context();
1454  else
1455  return 0;
1456 }
1457 
1458 
1460 {
1461  Q_D(QGLWidget);
1462  if (d->olw)
1463  d->olw->makeCurrent();
1464 }
1465 
1466 
1468 {
1469  Q_D(QGLWidget);
1470  if (d->olw)
1471  d->olw->updateGL();
1472 }
1473 
1484 void QGLWidget::setContext(QGLContext *context,
1485  const QGLContext* shareContext,
1486  bool deleteOldContext)
1487 {
1488  Q_D(QGLWidget);
1489  if (context == 0) {
1490  qWarning("QGLWidget::setContext: Cannot set null context");
1491  return;
1492  }
1493  if (!context->deviceIsPixmap() && context->device() != this) {
1494  qWarning("QGLWidget::setContext: Context must refer to this widget");
1495  return;
1496  }
1497 
1498  if (d->glcx)
1499  d->glcx->doneCurrent();
1500  QGLContext* oldcx = d->glcx;
1501  d->glcx = context;
1502 
1503  if (parentWidget()) {
1504  // force creation of delay-created widgets
1505  parentWidget()->winId();
1506  if (parentWidget()->x11Info().screen() != x11Info().screen())
1507  d_func()->xinfo = parentWidget()->d_func()->xinfo;
1508  }
1509 
1510  // If the application has set WA_TranslucentBackground and not explicitly set
1511  // the alpha buffer size to zero, modify the format so it have an alpha channel
1512  QGLFormat& fmt = d->glcx->d_func()->glFormat;
1514  fmt.setAlphaBufferSize(1);
1515 
1516  bool createFailed = false;
1517  if (!d->glcx->isValid()) {
1518  if (!d->glcx->create(shareContext ? shareContext : oldcx))
1519  createFailed = true;
1520  }
1521  if (createFailed) {
1522  if (deleteOldContext)
1523  delete oldcx;
1524  return;
1525  }
1526 
1527  if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) {
1528  if (deleteOldContext)
1529  delete oldcx;
1530  return;
1531  }
1532 
1533  bool visible = isVisible();
1534  if (visible)
1535  hide();
1536 
1537  XVisualInfo *vi = (XVisualInfo*)d->glcx->d_func()->vi;
1538  XSetWindowAttributes a;
1539 
1540  QColormap colmap = QColormap::instance(vi->screen);
1541  a.colormap = qt_gl_choose_cmap(QX11Info::display(), vi); // find best colormap
1542  a.background_pixel = colmap.pixel(palette().color(backgroundRole()));
1543  a.border_pixel = colmap.pixel(Qt::black);
1544  Window p = RootWindow(X11->display, vi->screen);
1545  if (parentWidget())
1546  p = parentWidget()->winId();
1547 
1548  Window w = XCreateWindow(X11->display, p, x(), y(), width(), height(),
1549  0, vi->depth, InputOutput, vi->visual,
1550  CWBackPixel|CWBorderPixel|CWColormap, &a);
1551  Window *cmw;
1552  Window *cmwret;
1553  int count;
1554  if (XGetWMColormapWindows(X11->display, window()->winId(),
1555  &cmwret, &count)) {
1556  cmw = new Window[count+1];
1557  memcpy((char *)cmw, (char *)cmwret, sizeof(Window)*count);
1558  XFree((char *)cmwret);
1559  int i;
1560  for (i=0; i<count; i++) {
1561  if (cmw[i] == winId()) { // replace old window
1562  cmw[i] = w;
1563  break;
1564  }
1565  }
1566  if (i >= count) // append new window
1567  cmw[count++] = w;
1568  } else {
1569  count = 1;
1570  cmw = new Window[count];
1571  cmw[0] = w;
1572  }
1573 
1574 #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
1575  if (oldcx && oldcx->windowCreated())
1576  glXReleaseBuffersMESA(X11->display, winId());
1577 #endif
1578  if (deleteOldContext)
1579  delete oldcx;
1580  oldcx = 0;
1581 
1583  create(w);
1584  else
1585  d->createWinId(w);
1586  XSetWMColormapWindows(X11->display, window()->winId(), cmw, count);
1587  delete [] cmw;
1588 
1589  // calling QWidget::create() will always result in a new paint
1590  // engine being created - get rid of it and replace it with our
1591  // own
1592 
1593  if (visible)
1594  show();
1595  XFlush(X11->display);
1596  d->glcx->setWindowCreated(true);
1597 }
1598 
1599 const QGLColormap & QGLWidget::colormap() const
1600 {
1601  Q_D(const QGLWidget);
1602  return d->cmap;
1603 }
1604 
1605 /*\internal
1606  Store color values in the given colormap.
1607 */
1608 static void qStoreColors(QWidget * tlw, Colormap cmap,
1609  const QGLColormap & cols)
1610 {
1611  Q_UNUSED(tlw);
1612  XColor c;
1613  QRgb color;
1614 
1615  for (int i = 0; i < cols.size(); i++) {
1616  color = cols.entryRgb(i);
1617  c.pixel = i;
1618  c.red = (ushort)((qRed(color) / 255.0) * 65535.0 + 0.5);
1619  c.green = (ushort)((qGreen(color) / 255.0) * 65535.0 + 0.5);
1620  c.blue = (ushort)((qBlue(color) / 255.0) * 65535.0 + 0.5);
1621  c.flags = DoRed | DoGreen | DoBlue;
1622  XStoreColor(X11->display, cmap, &c);
1623  }
1624 }
1625 
1626 /*\internal
1627  Check whether the given visual supports dynamic colormaps or not.
1628 */
1629 static bool qCanAllocColors(QWidget * w)
1630 {
1631  bool validVisual = false;
1632  int numVisuals;
1633  long mask;
1634  XVisualInfo templ;
1635  XVisualInfo * visuals;
1636  VisualID id = XVisualIDFromVisual((Visual *) w->window()->x11Info().visual());
1637 
1638  mask = VisualScreenMask;
1639  templ.screen = w->x11Info().screen();
1640  visuals = XGetVisualInfo(X11->display, mask, &templ, &numVisuals);
1641 
1642  for (int i = 0; i < numVisuals; i++) {
1643  if (visuals[i].visualid == id) {
1644  switch (visuals[i].c_class) {
1645  case TrueColor:
1646  case StaticColor:
1647  case StaticGray:
1648  case XGrayScale:
1649  validVisual = false;
1650  break;
1651  case DirectColor:
1652  case PseudoColor:
1653  validVisual = true;
1654  break;
1655  }
1656  break;
1657  }
1658  }
1659  XFree(visuals);
1660 
1661  if (!validVisual)
1662  return false;
1663  return true;
1664 }
1665 
1666 
1667 void QGLWidget::setColormap(const QGLColormap & c)
1668 {
1669  Q_D(QGLWidget);
1670  QWidget * tlw = window(); // must return a valid widget
1671 
1672  d->cmap = c;
1673  if (!d->cmap.handle())
1674  return;
1675 
1676  if (!qCanAllocColors(this)) {
1677  qWarning("QGLWidget::setColormap: Cannot create a read/write "
1678  "colormap for this visual");
1679  return;
1680  }
1681 
1682  // If the child GL widget is not of the same visual class as the
1683  // toplevel widget we will get in trouble..
1684  Window wid = tlw->winId();
1685  Visual * vis = (Visual *) tlw->x11Info().visual();;
1686  VisualID cvId = XVisualIDFromVisual((Visual *) x11Info().visual());
1687  VisualID tvId = XVisualIDFromVisual((Visual *) tlw->x11Info().visual());
1688  if (cvId != tvId) {
1689  wid = winId();
1690  vis = (Visual *) x11Info().visual();
1691  }
1692 
1693  if (!d->cmap.handle()) // allocate a cmap if necessary
1694  d->cmap.setHandle(XCreateColormap(X11->display, wid, vis, AllocAll));
1695 
1696  qStoreColors(this, (Colormap) d->cmap.handle(), c);
1697  XSetWindowColormap(X11->display, wid, (Colormap) d->cmap.handle());
1698 
1699  // tell the wm that this window has a special colormap
1700  Window * cmw;
1701  Window * cmwret;
1702  int count;
1703  if (XGetWMColormapWindows(X11->display, tlw->winId(), &cmwret, &count))
1704  {
1705  cmw = new Window[count+1];
1706  memcpy((char *) cmw, (char *) cmwret, sizeof(Window) * count);
1707  XFree((char *) cmwret);
1708  int i;
1709  for (i = 0; i < count; i++) {
1710  if (cmw[i] == winId()) {
1711  break;
1712  }
1713  }
1714  if (i >= count) // append new window only if not in the list
1715  cmw[count++] = winId();
1716  } else {
1717  count = 1;
1718  cmw = new Window[count];
1719  cmw[0] = winId();
1720  }
1721  XSetWMColormapWindows(X11->display, tlw->winId(), cmw, count);
1722  delete [] cmw;
1723 }
1724 
1725 // Solaris defines glXBindTexImageEXT as part of the GL library
1726 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
1727 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
1728 typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
1729 static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
1730 static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
1731 
1732 static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice)
1733 {
1734  static bool resolvedTextureFromPixmap = false;
1735 
1736  if (!resolvedTextureFromPixmap) {
1737  resolvedTextureFromPixmap = true;
1738 
1739  // Check to see if we have NPOT texture support
1742  {
1743  return false; // Can't use TFP without NPOT
1744  }
1745 
1746  const QX11Info *xinfo = qt_x11Info(paintDevice);
1747  Display *display = xinfo ? xinfo->display() : X11->display;
1748  int screen = xinfo ? xinfo->screen() : X11->defaultScreen;
1749 
1750  QGLExtensionMatcher serverExtensions(glXQueryExtensionsString(display, screen));
1751  QGLExtensionMatcher clientExtensions(glXGetClientString(display, GLX_EXTENSIONS));
1752  if (serverExtensions.match("GLX_EXT_texture_from_pixmap")
1753  && clientExtensions.match("GLX_EXT_texture_from_pixmap"))
1754  {
1755  glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
1756  glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
1757  }
1758  }
1759 
1760  return glXBindTexImageEXT && glXReleaseTexImageEXT;
1761 }
1762 #endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
1763 
1764 
1766  QGLContext::BindOptions options)
1767 {
1768 #if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
1769  return 0;
1770 #else
1771 
1772  // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap
1773  int majorVersion = 0;
1774  int minorVersion = 0;
1775  glXQueryVersion(X11->display, &majorVersion, &minorVersion);
1776  if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3))
1777  return 0;
1778 
1779  Q_Q(QGLContext);
1780 
1781  QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
1782  Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
1783 
1784  // We can't use TFP if the pixmap has a separate X11 mask
1785  if (pixmapData->x11_mask)
1786  return 0;
1787 
1788  if (!qt_resolveTextureFromPixmap(paintDevice))
1789  return 0;
1790 
1791  const QX11Info &x11Info = pixmapData->xinfo;
1792 
1793  // Store the configs (Can be static because configs aren't dependent on current context)
1794  static GLXFBConfig glxRGBPixmapConfig = 0;
1795  static bool RGBConfigInverted = false;
1796  static GLXFBConfig glxRGBAPixmapConfig = 0;
1797  static bool RGBAConfigInverted = false;
1798 
1799  bool hasAlpha = pixmapData->hasAlphaChannel();
1800 
1801  // Check to see if we need a config
1802  if ( (hasAlpha && !glxRGBAPixmapConfig) || (!hasAlpha && !glxRGBPixmapConfig) ) {
1803  GLXFBConfig *configList = 0;
1804  int configCount = 0;
1805 
1806  int configAttribs[] = {
1808  GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
1810  // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can:
1811  GLX_Y_INVERTED_EXT, int(options & QGLContext::CanFlipNativePixmapBindOption ? GLX_DONT_CARE : False),
1812  XNone
1813  };
1814  configList = glXChooseFBConfig(x11Info.display(), x11Info.screen(), configAttribs, &configCount);
1815  if (!configList)
1816  return 0;
1817 
1818  int yInv;
1819  glXGetFBConfigAttrib(x11Info.display(), configList[0], GLX_Y_INVERTED_EXT, &yInv);
1820 
1821  if (hasAlpha) {
1822  glxRGBAPixmapConfig = configList[0];
1823  RGBAConfigInverted = yInv;
1824  }
1825  else {
1826  glxRGBPixmapConfig = configList[0];
1827  RGBConfigInverted = yInv;
1828  }
1829 
1830  XFree(configList);
1831  }
1832 
1833  // Check to see if the surface is still valid
1834  if (pixmapData->gl_surface &&
1835  hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
1836  {
1837  // Surface is invalid!
1838  destroyGlSurfaceForPixmap(pixmapData);
1839  }
1840 
1841  // Check to see if we need a surface
1842  if (!pixmapData->gl_surface) {
1843  GLXPixmap glxPixmap;
1844  int pixmapAttribs[] = {
1847  GLX_MIPMAP_TEXTURE_EXT, False, // Maybe needs to be don't care
1848  XNone
1849  };
1850 
1851  // Wrap the X Pixmap into a GLXPixmap:
1852  glxPixmap = glXCreatePixmap(x11Info.display(),
1853  hasAlpha ? glxRGBAPixmapConfig : glxRGBPixmapConfig,
1854  pixmapData->handle(), pixmapAttribs);
1855 
1856  if (!glxPixmap)
1857  return 0;
1858 
1859  pixmapData->gl_surface = (void*)glxPixmap;
1860 
1861  // Make sure the cleanup hook gets called so we can delete the glx pixmap
1863  }
1864 
1865  GLuint textureId;
1866  glGenTextures(1, &textureId);
1867  glBindTexture(GL_TEXTURE_2D, textureId);
1868  glXBindTexImageEXT(x11Info.display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT, 0);
1869 
1870  glBindTexture(GL_TEXTURE_2D, textureId);
1871  GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST;
1872  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
1873  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
1874 
1875  if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted)))
1876  options &= ~QGLContext::InvertedYBindOption;
1877 
1878  QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
1881 
1882  // We assume the cost of bound pixmaps is zero
1883  QGLTextureCache::instance()->insert(q, key, texture, 0);
1884 
1885  return texture;
1886 #endif
1887 }
1888 
1889 
1891 {
1892 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
1894  QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
1895  if (pixmapData->gl_surface) {
1896  glXDestroyPixmap(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface);
1897  pixmapData->gl_surface = 0;
1898  }
1899 #endif
1900 }
1901 
1903 {
1904 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
1907  QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
1908  if (pixmapData->gl_surface)
1909  glXReleaseTexImageEXT(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT);
1910 #endif
1911 }
1912 
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
static uint hash(const uchar *p, int n)
Definition: qhash.cpp:68
int depth() const
Returns the color depth (bits per pixel) of the X display.
virtual void swapBuffers() const
Swaps the screen contents with an off-screen buffer.
Definition: qgl_egl.cpp:287
DataPtr & data_ptr()
Definition: qpixmap.h:297
VisualID vis
Definition: qgl_x11.cpp:280
GLCMapHash * qglcmap_hash
Definition: qgl_x11.cpp:179
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
const Key & key() const
Returns the current item&#39;s key as a const reference.
Definition: qmap.h:250
void insert(QGLContext *ctx, qint64 key, QGLTexture *texture, int cost)
Definition: qgl.cpp:1922
static QColormap instance(int screen=-1)
unsigned int QRgb
Definition: qrgb.h:53
virtual void glInit()
Initializes OpenGL for this widget&#39;s context.
Definition: qgl.cpp:4772
The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash...
Definition: qhash.h:395
void makeCurrent()
Makes this widget the current widget for OpenGL operations, i.
Definition: qgl.cpp:4187
int type
Definition: qmetatype.cpp:239
#define GL_TEXTURE_MIN_FILTER
void setStencil(bool enable)
If enable is true enables the stencil buffer; otherwise disables the stencil buffer.
Definition: qgl.cpp:724
bool rgba() const
Returns true if RGBA color mode is set.
Definition: qgl.h:623
int y() const
static OpenGLVersionFlags openGLVersionFlags()
static mach_timebase_info_data_t info
unsigned char c[8]
Definition: qnumeric_p.h:62
bool alloc
Definition: qgl_x11.cpp:146
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
QPointer< QWidget > widget
void clear()
Removes all items from the hash.
Definition: qhash.h:574
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
Drawable qt_x11Handle(const QPaintDevice *pd)
Returns the X11 Drawable of the paint device.
int greenBufferSize() const
Returns the green buffer size.
Definition: qgl.cpp:1070
#define GLX_FRONT_LEFT_EXT
Definition: qgl_x11.cpp:116
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB
Definition: qgl_x11.cpp:128
static void setCurrentContext(QGLContext *context)
Definition: qgl.cpp:3577
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
Definition: qgl_x11.cpp:129
#define GLX_RGBA_BIT
#define GLX_CONTEXT_PROFILE_MASK_ARB
Definition: qgl_x11.cpp:130
#define it(className, varName)
static QGLTextureCache * instance()
Definition: qgl.cpp:1995
void qAddPostRoutine(QtCleanUpFunction p)
int size() const
Returns the number of colorcells in the colormap.
bool isVisible() const
Definition: qwidget.h:1005
#define GLX_TEXTURE_TARGET_EXT
Definition: qgl_x11.cpp:109
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static QVector< QTransColor > trans_colors
Definition: qgl_x11.cpp:285
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
#define GLX_TEXTURE_2D_EXT
Definition: qgl_x11.cpp:114
static QColor cmap[256]
Definition: qgl_mac.mm:760
const QX11Info & x11Info() const
Returns information about the configuration of the X display used to display the widget.
#define glXGetFBConfigAttrib
const QGLContext * context() const
Returns the context of this widget.
Definition: qgl.cpp:5303
QColor overlayTransparentColor() const
If this context is a valid context in an overlay plane, returns the plane&#39;s transparent color...
Definition: qgl_egl.cpp:362
virtual void * tryVisual(const QGLFormat &f, int bufDepth=1)
Definition: qgl_x11.cpp:828
QPalette::ColorRole backgroundRole() const
Returns the background role of the widget.
Definition: qwidget.cpp:4677
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
#define Q_DISABLE_COPY(Class)
Disables the use of copy constructors and assignment operators for the given Class.
Definition: qglobal.h:2523
Qt::HANDLE handle() const
Returns the pixmap&#39;s handle to the device context.
Definition: qpixmap.cpp:1299
CMapEntryHash * cmap_hash
Definition: qgl_x11.cpp:178
void * getProcAddress(const QString &proc) const
Returns a function pointer to the GL extension function passed in proc.
Definition: qgl_egl.cpp:379
void setAlpha(bool enable)
If enable is true enables the alpha buffer; otherwise disables the alpha buffer.
Definition: qgl.cpp:664
static void enableCleanupHooks(const QImage &image)
long ASN1_INTEGER_get ASN1_INTEGER * a
void * resolve(const char *symbol)
Returns the address of the exported symbol symbol.
Definition: qlibrary.cpp:1155
void setSampleBuffers(bool enable)
If enable is true, a GL context with multisample buffer support is picked; otherwise ignored...
Definition: qgl.cpp:812
int depth() const
Returns the depth of the pixmap.
Definition: qpixmap.cpp:695
ushort red
Returns the red color component of this color.
Definition: qcolor.h:243
The QString class provides a Unicode character string.
Definition: qstring.h:83
void init(QGLContext *context, const QGLWidget *shareWidget)
Definition: qgl_mac.mm:950
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
HFONT handle() const
Returns the window system handle to the font, for low-level access.
Definition: qfont_mac.cpp:121
static void removeShare(const QGLContext *context)
Definition: qgl.cpp:5867
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
int redBufferSize() const
Returns the red buffer size.
Definition: qgl.cpp:1035
#define X11
Definition: qt_x11_p.h:724
Q_GUI_EXPORT QString extensions()
Definition: qegl.cpp:785
#define Q_D(Class)
Definition: qglobal.h:2482
#define glXChooseFBConfig
static void cleanup_cmaps()
Definition: qgl_x11.cpp:183
int height() const
virtual Type type() const =0
virtual int devType() const
Definition: qpaintdevice.h:167
QGLContext::BindOptions options
Definition: qgl_p.h:611
#define GL_TEXTURE_2D
#define GLX_BIND_TO_TEXTURE_RGB_EXT
Definition: qgl_x11.cpp:103
virtual void resizeOverlayGL(int w, int h)
This virtual function is used in the same manner as paintGL() except that it operates on the widget&#39;s...
Definition: qgl.cpp:4465
void setStyleStrategy(StyleStrategy s)
Sets the style strategy for the font to s.
Definition: qfont.cpp:1578
static void find_trans_colors()
Definition: qgl_x11.cpp:288
#define GLX_SAMPLE_BUFFERS_ARB
Definition: qgl_x11.cpp:96
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
static const QGLContext * currentContext()
Returns the current context, i.e.
Definition: qgl.cpp:3545
#define Q_Q(Class)
Definition: qglobal.h:2483
QGLTexture * bindTextureFromNativePixmap(QPixmap *, const qint64 key, QGLContext::BindOptions options)
Definition: qgl_x11.cpp:1765
static int trans_colors_init
Definition: qgl_x11.cpp:286
static void qStoreColors(QWidget *tlw, Colormap cmap, const QGLColormap &cols)
Definition: qgl_x11.cpp:1608
union _XEvent XEvent
Definition: qwindowdefs.h:116
QHash< int, QMap< int, QRgb > > GLCMapHash
Definition: qgl_x11.cpp:163
Q_CORE_EXPORT void qDebug(const char *,...)
bool sampleBuffers() const
Returns true if multisample buffer support is enabled; otherwise returns false.
Definition: qgl.h:658
#define GLX_PBUFFER_BIT
#define GLX_BIND_TO_TEXTURE_TARGETS_EXT
Definition: qgl_x11.cpp:106
#define GL_FALSE
unsigned char uchar
Definition: qglobal.h:994
T * data() const
Returns a pointer to the shared data object.
Definition: qshareddata.h:145
bool isValid() const
Returns true if the widget has a valid GL rendering context; otherwise returns false.
Definition: qgl.cpp:4151
void setAlphaBufferSize(int size)
Set the preferred alpha buffer size to size.
Definition: qgl.cpp:1116
int plane() const
Returns the plane of this format.
Definition: qgl.cpp:924
int alphaBufferSize() const
Returns the alpha buffer size.
Definition: qgl.cpp:1132
Q_OPENGL_EXPORT const QString qt_gl_library_name()
Definition: qgl.cpp:5827
const Q_GUI_EXPORT QX11Info * qt_x11Info(const QPaintDevice *pd)
Returns the QX11Info structure for the pd paint device.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define GLX_DRAWABLE_TYPE
bool depth() const
Returns true if the depth buffer is enabled; otherwise returns false.
Definition: qgl.h:618
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
QGLWidget * realWidget
Definition: qgl_x11.cpp:1309
void qglClearColor(const QColor &c) const
Convenience function for specifying the clearing color to OpenGL.
Definition: qgl.cpp:4861
struct FT_FaceRec_ * FT_Face
Definition: qfont.h:50
void generateFontDisplayLists(const QFont &fnt, int listBase)
Generates a set of 256 display lists for the 256 first characters in the font font.
Definition: qgl_egl.cpp:373
bool visible
whether the widget is visible
Definition: qwidget.h:191
QGLFormat format() const
Returns the frame buffer format that was obtained (this may be a subset of what was requested)...
Definition: qgl.cpp:3495
int accumBufferSize() const
Returns the accumulation buffer size.
Definition: qgl.cpp:1159
Qt::HANDLE handle() const
Definition: qpixmap_x11_p.h:95
The QGLFormat class specifies the display format of an OpenGL rendering context.
Definition: qgl.h:175
The QGLContext class encapsulates an OpenGL rendering context.
Definition: qgl.h:310
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
#define GLX_RENDER_TYPE
int depthBufferSize() const
Returns the depth buffer size.
Definition: qgl.cpp:1000
int width() const
void unlockFace() const
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
#define GLX_TEXTURE_FORMAT_RGB_EXT
Definition: qgl_x11.cpp:112
#define GLX_CONTEXT_MAJOR_VERSION_ARB
Definition: qgl_x11.cpp:122
const QPalette & palette() const
bool x11Event(XEvent *e)
This special event handler can be reimplemented in a subclass to receive native X11 events passed in ...
Definition: qgl_x11.cpp:1306
bool stencil() const
Returns true if the stencil buffer is enabled; otherwise returns false.
Definition: qgl.h:638
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
const T & value() const
Returns the current item&#39;s value.
Definition: qhash.h:420
Q_CORE_EXPORT void qWarning(const char *,...)
void setDoubleBuffer(bool enable)
If enable is true sets double buffering; otherwise sets single buffering.
Definition: qgl.cpp:566
static bool hasOpenGL()
Returns true if the window system has any OpenGL support; otherwise returns false.
Definition: qgl_egl.cpp:186
unsigned int uint
Definition: qglobal.h:996
const_iterator constFind(const Key &key) const
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:859
QPaintDevice * device() const
Returns the paint device set for this context.
Definition: qgl.cpp:3507
void create(WId=0, bool initializeWindow=true, bool destroyOldWindow=true)
Creates a new widget window if window is 0, otherwise sets the widget&#39;s window to window...
Definition: qwidget.cpp:1454
ClassId classId() const
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
void setDepth(bool enable)
If enable is true enables the depth buffer; otherwise disables the depth buffer.
Definition: qgl.cpp:599
bool accum() const
Returns true if the accumulation buffer is enabled; otherwise returns false.
Definition: qgl.h:633
__int64 qint64
Definition: qglobal.h:942
bool deviceIsPixmap() const
Returns true if the paint device of this context is a pixmap; otherwise returns false.
Definition: qgl.cpp:3513
unsigned long ulong
Definition: qglobal.h:997
void * visual() const
Returns the current visual.
void resizeGL(int w, int h)
This virtual function is called whenever the widget has been resized.
Definition: qgl_x11.cpp:1337
static Qt::HANDLE appColormap(int screen=-1)
Returns a handle for the application&#39;s color map on the given screen.
void show()
Shows the widget and its child widgets.
static void destroyGlSurfaceForPixmap(QPixmapData *)
Definition: qgl_x11.cpp:1890
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
The QGLColormap class is used for installing custom colormaps into a QGLWidget.
Definition: qglcolormap.h:54
#define GL_FRONT
uint pixel(const QColor &color) const
QRect rect() const
QRegion mask() const
Returns the mask currently set on a widget.
Definition: qwidget.cpp:10058
#define Q_OBJECT
Definition: qobjectdefs.h:157
QHash< int, QCMapEntry * > CMapEntryHash
Definition: qgl_x11.cpp:162
void hide()
Hides the widget.
Definition: qwidget.h:501
#define GL_UNPACK_ALIGNMENT
QFontEngine * engineForScript(int script) const
Definition: qfont.cpp:294
QWidget * screen(int screen=-1)
void setMouseTracking(bool enable)
Definition: qwidget.h:990
virtual void paintOverlayGL()
This virtual function is used in the same manner as paintGL() except that it operates on the widget&#39;s...
Definition: qgl.cpp:4444
virtual void * chooseVisual()
X11 only: This virtual function tries to find a visual that matches the format, reducing the demands ...
Definition: qgl_x11.cpp:762
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
static QDesktopWidget * desktop()
Returns the desktop widget (also called the root window).
QRgb entryRgb(int idx) const
Returns the QRgb value in the colorcell with index idx.
#define GLX_Y_INVERTED_EXT
Definition: qgl_x11.cpp:107
#define GLX_SAMPLES_ARB
Definition: qgl_x11.cpp:97
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
static void qgl_use_font(QFontEngineFT *engine, int first, int count, int listBase)
This is basically a substitute for glxUseXFont() which can only handle XLFD fonts.
Definition: qgl_x11.cpp:1073
bool windowCreated() const
Returns true if a window has been created for this context; otherwise returns false.
Definition: qgl.cpp:3520
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
#define GL_LINEAR
void reset()
Resets the context and makes it invalid.
Definition: qgl_egl.cpp:191
struct _XDisplay Display
Definition: qwindowdefs.h:115
The QGLWidget class is a widget for rendering OpenGL graphics.
Definition: qgl.h:474
bool hasOverlay() const
Returns true if overlay plane is enabled; otherwise returns false.
Definition: qgl.h:653
virtual bool chooseContext(const QGLContext *shareContext=0)
This semi-internal function is called by create().
Definition: qgl_mac.mm:190
The QX11Info class provides information about the X display configuration.
Definition: qx11info_x11.h:63
static bool first_time
Definition: qgl_x11.cpp:165
ushort blue
Returns the blue color component of this color.
Definition: qcolor.h:245
Qt::HANDLE x11_mask
int x() const
static bool hasOpenGLOverlays()
Returns true if the window system supports OpenGL overlays; otherwise returns false.
Definition: qgl_mac.mm:185
The QMap::iterator class provides an STL-style non-const iterator for QMap and QMultiMap.
Definition: qmap.h:233
bool isValid() const
Returns true if a GL rendering context has been successfully created; otherwise returns false...
Definition: qgl.cpp:3477
Colormap cmap
Definition: qgl_x11.cpp:145
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
bool hasAlphaChannel() const
static void * appVisual(int screen=-1)
Returns the current visual used by the application on the given screen.
unsigned short ushort
Definition: qglobal.h:995
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
static uint qt_transparent_pixel(VisualID id, int screen)
Definition: qgl_x11.cpp:991
#define GLX_MIPMAP_TEXTURE_EXT
Definition: qgl_x11.cpp:110
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
static bool qCanAllocColors(QWidget *w)
Definition: qgl_x11.cpp:1629
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
virtual void doneCurrent()
Makes no GL context the current context.
Definition: qgl_egl.cpp:277
void * qglx_getProcAddress(const char *procName)
Definition: qgl_x11.cpp:350
void resizeEvent(QResizeEvent *)
Handles resize events that are passed in the event parameter.
Definition: qgl_mac.mm:896
int key
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
const QGLContext * overlayContext() const
Returns the overlay context of this widget, or 0 if this widget has no overlay.
Definition: qgl_mac.mm:919
unsigned int quint32
Definition: qglobal.h:938
FT_Face lockFace(Scaling scale=Scaled) const
void makeOverlayCurrent()
Makes the overlay context of this widget current.
Definition: qgl_mac.mm:924
bool alpha() const
Returns true if the alpha buffer in the framebuffer is enabled; otherwise returns false...
Definition: qgl.h:628
virtual void makeCurrent()
Makes this context the current OpenGL rendering context.
Definition: qgl_egl.cpp:213
void paintGL()
This virtual function is called whenever the widget needs to be painted.
Definition: qgl_x11.cpp:1344
bool match(const char *str) const
Definition: qgl_p.h:906
int blueBufferSize() const
Returns the blue buffer size.
Definition: qgl.cpp:1105
QGLTemporaryContext(bool directRendering=true, QWidget *parent=0)
Definition: qgl_mac.mm:132
bool doubleBuffer() const
Returns true if double buffering is enabled; otherwise returns false.
Definition: qgl.h:613
static Extensions glExtensions()
Definition: qgl.cpp:5781
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
void setLoadHints(LoadHints hints)
Definition: qlibrary.cpp:1304
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
typedef GLint
Definition: glfunctions.h:67
int depth() const
Definition: qpaintdevice.h:103
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
#define GLX_TEXTURE_FORMAT_EXT
Definition: qgl_x11.cpp:108
XStandardColormap scmap
Definition: qgl_x11.cpp:147
#define GL_RGBA
uint colorIndex(const QColor &c) const
Returns a colormap index for the color c, in ColorIndex mode.
Definition: qgl_egl.cpp:367
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
#define GLX_CONTEXT_MINOR_VERSION_ARB
Definition: qgl_x11.cpp:123
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
QGLOverlayWidget(const QGLFormat &format, QGLWidget *parent, const QGLWidget *shareWidget=0)
Definition: qgl_x11.cpp:1316
void setStereo(bool enable)
If enable is true enables stereo buffering; otherwise disables stereo buffering.
Definition: qgl.cpp:754
static QGLFormat defaultOverlayFormat()
Returns the default QGLFormat for overlay contexts.
Definition: qgl.cpp:1559
long color
Definition: qgl_x11.cpp:282
virtual void updateOverlayGL()
Updates the widget&#39;s overlay (if any).
Definition: qgl_mac.mm:928
bool isValid() const
Returns true if the color is valid; otherwise returns false.
Definition: qcolor.h:295
#define GLX_TEXTURE_2D_BIT_EXT
Definition: qgl_x11.cpp:101
#define GL_TEXTURE_MAG_FILTER
const QGLColormap & colormap() const
Returns the colormap for this widget.
Definition: qgl_mac.mm:974
void setColormap(const QGLColormap &map)
Set the colormap for this widget to cmap.
Definition: qgl_mac.mm:979
static void unbindPixmapFromTexture(QPixmapData *)
Definition: qgl_x11.cpp:1902
#define GLX_BIND_TO_TEXTURE_RGBA_EXT
Definition: qgl_x11.cpp:104
void setMouseTracking(bool enable)
If enable is true then mouse tracking is enabled; otherwise it is disabled.
Definition: qgl_egl.cpp:357
int stencilBufferSize() const
Returns the stencil buffer size.
Definition: qgl.cpp:1185
const QX11Info * qt_x11Info(const QPaintDevice *pd)
void initializeGL()
This virtual function is called once before the first call to paintGL() or resizeGL(), and then once whenever the widget has been assigned a new QGLContext.
Definition: qgl_x11.cpp:1326
bool stereo() const
Returns true if stereo buffering is enabled; otherwise returns false.
Definition: qgl.h:643
static bool mesa_gl
Definition: qgl_x11.cpp:164
virtual void initializeOverlayGL()
This virtual function is used in the same manner as initializeGL() except that it operates on the wid...
Definition: qgl.cpp:4428
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
ushort green
Returns the green color component of this color.
Definition: qcolor.h:244
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
int samples() const
Returns the number of samples per pixel when multisampling is enabled.
Definition: qgl.cpp:824
bool drawAntialiased() const
QRgb rgb() const
Returns the RGB value of the color.
Definition: qcolor.cpp:1051
Colormap qt_gl_choose_cmap(Display *dpy, XVisualInfo *vi)
Definition: qgl_x11.cpp:196
static Display * display()
Returns the default display for the application.
The QMap class is a template class that provides a skip-list-based dictionary.
Definition: qdatastream.h:67
void setAccum(bool enable)
If enable is true enables the accumulation buffer; otherwise disables the accumulation buffer...
Definition: qgl.cpp:694
int screen() const
Returns the number of the screen currently in use.
static bool buildSpec(int *spec, const QGLFormat &f, QPaintDevice *paintDevice, int bufDepth, bool onlyFBConfig=false)
Definition: qgl_x11.cpp:421
The QLibrary class loads shared libraries at runtime.
Definition: qlibrary.h:62
#define GLX_TEXTURE_FORMAT_RGBA_EXT
Definition: qgl_x11.cpp:113
void setContext(QGLContext *context, const QGLContext *shareContext=0, bool deleteOldContext=true)
Sets a new QGLContext, context, for this QGLWidget, using the shared context, shareContext.
Definition: qgl_mac.mm:932
QBool contains(char c) const
Returns true if the byte array contains the character ch; otherwise returns false.
Definition: qbytearray.h:525
bool renderCxPm(QPixmap *pixmap)
Definition: qgl_egl.cpp:384
void cleanupColormaps()
Free up any allocated colormaps.
Definition: qgl_mac.mm:970
#define GL_NEAREST