src/opengl/qgl_x11.cpp File Reference

#include "qgl.h"
#include "qgl_p.h"
#include "qmap.h"
#include "qapplication.h"
#include "qcolormap.h"
#include "qdesktopwidget.h"
#include "qpixmap.h"
#include "qhash.h"
#include "qlibrary.h"
#include "qdebug.h"
#include <private/qfontengine_p.h>
#include <private/qt_x11_p.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include "qgl_x11.moc"

Include dependency graph for qgl_x11.cpp:

Go to the source code of this file.

Classes

struct  QCMapEntry
struct  QGLCMapCleanupHandler
struct  QTransColor
class  QGLOverlayWidget

Defines

#define INT8   dummy_INT8
#define INT32   dummy_INT32
#define GLX_SAMPLE_BUFFERS_ARB   100000
#define GLX_SAMPLES_ARB   100001

Typedefs

typedef QHash< int, QCMapEntry * > CMapEntryHash
typedef QHash< int, QMap<
int, QRgb > > 
GLCMapHash

Functions

Drawable qt_x11Handle (const QPaintDevice *pd)
const QX11Infoqt_x11Info (const QPaintDevice *pd)
static void cleanup_cmaps ()
 Q_GLOBAL_STATIC (QGLCMapCleanupHandler, cmap_handler)
static Colormap choose_cmap (Display *dpy, XVisualInfo *vi)
static void find_trans_colors ()
static void qgl_use_font (QFontEngineFT *engine, int first, int count, int listBase)
static void qStoreColors (QWidget *tlw, Colormap cmap, const QGLColormap &cols)
static bool qCanAllocColors (QWidget *w)

Variables

static bool mesa_gl = false
static bool first_time = true
static QVector< QTransColortrans_colors
static int trans_colors_init = false


Define Documentation

#define GLX_SAMPLE_BUFFERS_ARB   100000

Definition at line 52 of file qgl_x11.cpp.

Referenced by QGLContext::chooseContext(), QGLPixelBufferPrivate::init(), and qt_format_to_attrib_list().

#define GLX_SAMPLES_ARB   100001

Definition at line 53 of file qgl_x11.cpp.

Referenced by QGLContext::chooseContext(), QGLPixelBufferPrivate::init(), and qt_format_to_attrib_list().

#define INT32   dummy_INT32

Definition at line 39 of file qgl_x11.cpp.

#define INT8   dummy_INT8

Definition at line 38 of file qgl_x11.cpp.


Typedef Documentation

typedef QHash<int, QCMapEntry *> CMapEntryHash

Definition at line 85 of file qgl_x11.cpp.

typedef QHash<int, QMap<int, QRgb> > GLCMapHash

Definition at line 86 of file qgl_x11.cpp.


Function Documentation

static Colormap choose_cmap ( Display dpy,
XVisualInfo *  vi 
) [static]

Definition at line 125 of file qgl_x11.cpp.

References QX11Info::appColormap(), QX11Info::appVisual(), c, QHash< Key, T >::constEnd(), QHash< Key, T >::constFind(), first_time, i, mesa_gl, n, QHash< Key, T >::const_iterator::value(), and x.

Referenced by QGLContext::chooseContext(), QGLContext::overlayTransparentColor(), QGLWidgetPrivate::renderCxPm(), and QGLWidget::setContext().

00126 {
00127     if (first_time) {
00128         const char *v = glXQueryServerString(dpy, vi->screen, GLX_VERSION);
00129         if (v)
00130             mesa_gl = (strstr(v, "Mesa") != 0);
00131         first_time = false;
00132     }
00133 
00134     CMapEntryHash *hash = cmap_handler()->cmap_hash;
00135     CMapEntryHash::ConstIterator it = hash->constFind((long) vi->visualid + (vi->screen * 256));
00136     if (it != hash->constEnd())
00137         return it.value()->cmap; // found colormap for visual
00138 
00139     if (vi->visualid ==
00140         XVisualIDFromVisual((Visual *) QX11Info::appVisual(vi->screen))) {
00141         // qDebug("Using x11AppColormap");
00142         return QX11Info::appColormap(vi->screen);
00143     }
00144 
00145     QCMapEntry *x = new QCMapEntry();
00146 
00147     XStandardColormap *c;
00148     int n, i;
00149 
00150     // qDebug("Choosing cmap for vID %0x", vi->visualid);
00151 
00152     if (mesa_gl) {                                // we're using MesaGL
00153         Atom hp_cmaps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", true);
00154         if (hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8) {
00155             if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
00156                                  hp_cmaps)) {
00157                 i = 0;
00158                 while (i < n && x->cmap == 0) {
00159                     if (c[i].visualid == vi->visual->visualid) {
00160                         x->cmap = c[i].colormap;
00161                         x->scmap = c[i];
00162                         //qDebug("Using HP_RGB scmap");
00163 
00164                     }
00165                     i++;
00166                 }
00167                 XFree((char *)c);
00168             }
00169         }
00170     }
00171     if (!x->cmap) {
00172         if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
00173                              XA_RGB_DEFAULT_MAP)) {
00174             for (int i = 0; i < n && x->cmap == 0; ++i) {
00175                 if (!c[i].red_max ||
00176                     !c[i].green_max ||
00177                     !c[i].blue_max ||
00178                     !c[i].red_mult ||
00179                     !c[i].green_mult ||
00180                     !c[i].blue_mult)
00181                     continue; // invalid stdcmap
00182                 if (c[i].visualid == vi->visualid) {
00183                     x->cmap = c[i].colormap;
00184                     x->scmap = c[i];
00185                     //qDebug("Using RGB_DEFAULT scmap");
00186                 }
00187             }
00188             XFree((char *)c);
00189         }
00190     }
00191     if (!x->cmap) {                                // no shared cmap found
00192         x->cmap = XCreateColormap(dpy, RootWindow(dpy,vi->screen), vi->visual,
00193                                   AllocNone);
00194         x->alloc = true;
00195         // qDebug("Allocating cmap");
00196     }
00197 
00198     // associate cmap with visualid
00199     hash->insert((long) vi->visualid + (vi->screen * 256), x);
00200     return x->cmap;
00201 }

Here is the call graph for this function:

static void cleanup_cmaps (  )  [static]

Definition at line 111 of file qgl_x11.cpp.

References QHash< Key, T >::clear(), QHash< Key, T >::constBegin(), QHash< Key, T >::constEnd(), and QHash< Key, T >::value().

Referenced by QGLCMapCleanupHandler::QGLCMapCleanupHandler(), and QGLCMapCleanupHandler::~QGLCMapCleanupHandler().

00112 {
00113     if (!cmap_handler()->cleaned_up) {
00114         CMapEntryHash *hash = cmap_handler()->cmap_hash;
00115         QHash<int, QCMapEntry *>::ConstIterator it = hash->constBegin();
00116         while (it != hash->constEnd()) {
00117             delete it.value();
00118             ++it;
00119         }
00120         hash->clear();
00121         cmap_handler()->cleaned_up = true;
00122     }
00123 }

Here is the call graph for this function:

static void find_trans_colors (  )  [static]

Definition at line 213 of file qgl_x11.cpp.

References QApplication::desktop(), i, int, j, QDesktopWidget::screen(), Success, trans_colors, type, value, X11, and XNone.

Referenced by QGLFormat::hasOpenGLOverlays(), and QGLContext::overlayTransparentColor().

00214 {
00215     struct OverlayProp {
00216         long  visual;
00217         long  type;
00218         long  value;
00219         long  layer;
00220     };
00221 
00222     trans_colors_init = true;
00223 
00224     Display* appDisplay = X11->display;
00225 
00226     int scr;
00227     int lastsize = 0;
00228     for (scr = 0; scr < ScreenCount(appDisplay); scr++) {
00229         QWidget* rootWin = QApplication::desktop()->screen(scr);
00230         if (!rootWin)
00231             return;                                        // Should not happen
00232         Atom overlayVisualsAtom = XInternAtom(appDisplay,
00233                                                "SERVER_OVERLAY_VISUALS", True);
00234         if (overlayVisualsAtom == XNone)
00235             return;                                        // Server has no overlays
00236 
00237         Atom actualType;
00238         int actualFormat;
00239         ulong nItems;
00240         ulong bytesAfter;
00241         OverlayProp* overlayProps = 0;
00242         int res = XGetWindowProperty(appDisplay, rootWin->winId(),
00243                                       overlayVisualsAtom, 0, 10000, False,
00244                                       overlayVisualsAtom, &actualType,
00245                                       &actualFormat, &nItems, &bytesAfter,
00246                                       (uchar**)&overlayProps);
00247 
00248         if (res != Success || actualType != overlayVisualsAtom
00249              || actualFormat != 32 || nItems < 4 || !overlayProps)
00250             return;                                        // Error reading property
00251 
00252         int numProps = nItems / 4;
00253         trans_colors.resize(lastsize + numProps);
00254         int j = lastsize;
00255         for (int i = 0; i < numProps; i++) {
00256             if (overlayProps[i].type == 1) {
00257                 trans_colors[j].vis = (VisualID)overlayProps[i].visual;
00258                 trans_colors[j].screen = scr;
00259                 trans_colors[j].color = (int)overlayProps[i].value;
00260                 j++;
00261             }
00262         }
00263         XFree(overlayProps);
00264         lastsize = j;
00265         trans_colors.resize(lastsize);
00266     }
00267 }

Here is the call graph for this function:

Q_GLOBAL_STATIC ( QGLCMapCleanupHandler  ,
cmap_handler   
)

static bool qCanAllocColors ( QWidget w  )  [static]

Definition at line 1242 of file qgl_x11.cpp.

References mask, w, X11, and XGrayScale.

Referenced by QGLWidget::setColormap().

01243 {
01244     bool validVisual = false;
01245     int  numVisuals;
01246     long mask;
01247     XVisualInfo templ;
01248     XVisualInfo * visuals;
01249     VisualID id = XVisualIDFromVisual((Visual *) w->window()->x11Info().visual());
01250 
01251     mask = VisualScreenMask;
01252     templ.screen = w->x11Info().screen();
01253     visuals = XGetVisualInfo(X11->display, mask, &templ, &numVisuals);
01254 
01255     for (int i = 0; i < numVisuals; i++) {
01256         if (visuals[i].visualid == id) {
01257             switch (visuals[i].c_class) {
01258                 case TrueColor:
01259                 case StaticColor:
01260                 case StaticGray:
01261                 case XGrayScale:
01262                     validVisual = false;
01263                     break;
01264                 case DirectColor:
01265                 case PseudoColor:
01266                     validVisual = true;
01267                     break;
01268             }
01269             break;
01270         }
01271     }
01272     XFree(visuals);
01273 
01274     if (!validVisual)
01275         return false;
01276     return true;
01277 }

static void qgl_use_font ( QFontEngineFT engine,
int  first,
int  count,
int  listBase 
) [static]

Definition at line 759 of file qgl_x11.cpp.

References FT_Bitmap_::buffer, FT_Get_Char_Index(), FT_LOAD_DEFAULT, FT_Load_Glyph(), FT_Render_Glyph(), ft_render_mode_mono, ft_render_mode_normal, GLint, QFontEngineFT::lockFace(), QFontEngineFT::pattern(), FT_Bitmap_::pitch, qDebug(), FT_Bitmap_::rows, QFontEngineFT::unlockFace(), x, and y.

Referenced by QGLContext::generateFontDisplayLists().

00760 {
00761     GLfloat color[4];
00762     glGetFloatv(GL_CURRENT_COLOR, color);
00763 
00764     // save the pixel unpack state
00765     GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment;
00766     glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
00767     glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
00768     glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
00769     glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
00770     glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
00771     glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment);
00772 
00773     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
00774     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
00775     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00776     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00777     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00778     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00779 
00780     FcBool antialiased = True;
00781     FcPatternGetBool(engine->pattern(), FC_ANTIALIAS, 0, &antialiased);
00782     FT_Face face = engine->lockFace();
00783 
00784     // start generating font glyphs
00785     for (int i = first; i < count; ++i) {
00786         int list = listBase + i;
00787         GLfloat x0, y0, dx, dy;
00788 
00789         FT_Error err;
00790 
00791         err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
00792         if (err) {
00793             qDebug("failed loading glyph %d from font", i);
00794             Q_ASSERT(!err);
00795         }
00796         err = FT_Render_Glyph(face->glyph, (antialiased ? ft_render_mode_normal
00797                                             : ft_render_mode_mono));
00798         if (err) {
00799             qDebug("failed rendering glyph %d from font", i);
00800             Q_ASSERT(!err);
00801         }
00802 
00803         FT_Bitmap bm = face->glyph->bitmap;
00804         x0 = face->glyph->metrics.horiBearingX >> 6;
00805         y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
00806         dx = face->glyph->metrics.horiAdvance >> 6;
00807         dy = 0;
00808         int sz = bm.pitch * bm.rows;
00809         uint *aa_glyph = 0;
00810         uchar *ua_glyph = 0;
00811 
00812         if (antialiased)
00813             aa_glyph = new uint[sz];
00814         else
00815             ua_glyph = new uchar[sz];
00816 
00817         // convert to GL format
00818         for (int y = 0; y < bm.rows; ++y) {
00819             for (int x = 0; x < bm.pitch; ++x) {
00820                 int c1 = y*bm.pitch + x;
00821                 int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
00822                 if (antialiased) {
00823                     aa_glyph[c1] = (int(color[0]*255) << 24)
00824                                    | (int(color[1]*255) << 16)
00825                                    | (int(color[2]*255) << 8) | bm.buffer[c2];
00826                 } else {
00827                     ua_glyph[c1] = bm.buffer[c2];
00828                 }
00829             }
00830         }
00831 
00832         glNewList(list, GL_COMPILE);
00833         if (antialiased) {
00834             // calling glBitmap() is just a trick to move the current
00835             // raster pos, since glGet*() won't work in display lists
00836             glBitmap(0, 0, 0, 0, x0, -y0, 0);
00837             glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
00838             glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
00839         } else {
00840             glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
00841         }
00842         glEndList();
00843         antialiased ? delete[] aa_glyph : delete[] ua_glyph;
00844     }
00845 
00846     engine->unlockFace();
00847 
00848     // restore pixel unpack settings
00849     glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
00850     glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
00851     glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
00852     glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
00853     glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
00854     glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
00855 }

Here is the call graph for this function:

static void qStoreColors ( QWidget tlw,
Colormap  cmap,
const QGLColormap cols 
) [static]

Definition at line 1221 of file qgl_x11.cpp.

References c, QGLColormap::entryRgb(), QColor::qBlue(), QColor::qGreen(), QColor::qRed(), QColor::QRgb(), QGLColormap::size(), and X11.

Referenced by QGLWidget::setColormap().

01223 {
01224     Q_UNUSED(tlw);
01225     XColor c;
01226     QRgb color;
01227 
01228     for (int i = 0; i < cols.size(); i++) {
01229         color = cols.entryRgb(i);
01230         c.pixel = i;
01231         c.red   = (ushort)((qRed(color) / 255.0) * 65535.0 + 0.5);
01232         c.green = (ushort)((qGreen(color) / 255.0) * 65535.0 + 0.5);
01233         c.blue  = (ushort)((qBlue(color) / 255.0) * 65535.0 + 0.5);
01234         c.flags = DoRed | DoGreen | DoBlue;
01235         XStoreColor(X11->display, cmap, &c);
01236     }
01237 }

Here is the call graph for this function:

Drawable qt_x11Handle ( const QPaintDevice pd  ) 

Definition at line 182 of file qpaintdevice_x11.cpp.

References QPaintDevice::devType(), QInternal::Pixmap, and QInternal::Widget.

Referenced by QX11PaintEngine::begin(), and QGLContext::chooseContext().

00183 {
00184     if (!pd) return 0;
00185     if (pd->devType() == QInternal::Widget)
00186         return static_cast<const QWidget *>(pd)->handle();
00187     else if (pd->devType() == QInternal::Pixmap)
00188         return static_cast<const QPixmap *>(pd)->handle();
00189     return 0;
00190 }

Here is the call graph for this function:

const QX11Info* qt_x11Info ( const QPaintDevice pd  )  [related]


Variable Documentation

bool first_time = true [static]

Definition at line 88 of file qgl_x11.cpp.

Referenced by choose_cmap().

bool mesa_gl = false [static]

Definition at line 87 of file qgl_x11.cpp.

Referenced by choose_cmap().

QVector<QTransColor> trans_colors [static]

Definition at line 210 of file qgl_x11.cpp.

Referenced by find_trans_colors(), QGLFormat::hasOpenGLOverlays(), and QGLContext::overlayTransparentColor().

int trans_colors_init = false [static]

Definition at line 211 of file qgl_x11.cpp.


Generated on Thu Mar 15 13:54:31 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1