#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 QX11Info * | qt_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< QTransColor > | trans_colors |
| static int | trans_colors_init = false |
| #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 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.
| 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] |
bool first_time = true [static] |
bool mesa_gl = false [static] |
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.
1.5.1