⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgl_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtOpenGL module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#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_ft_p.h>#include <private/qt_x11_p.h>#ifdef Q_OS_HPUX// for GLXPBuffer#include <private/qglpixelbuffer_p.h>#endif#define INT8  dummy_INT8#define INT32 dummy_INT32#include <GL/glx.h>#undef  INT8#undef  INT32#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xos.h>#include <X11/Xatom.h>extern Drawable qt_x11Handle(const QPaintDevice *pd);extern const QX11Info *qt_x11Info(const QPaintDevice *pd);#ifndef GLX_ARB_multisample#define GLX_SAMPLE_BUFFERS_ARB  100000#define GLX_SAMPLES_ARB         100001#endif/*  The choose_cmap function is internal and used by QGLWidget::setContext()  and GLX (not Windows).  If the application can't find any sharable  colormaps, it must at least create as few colormaps as possible.  The  dictionary solution below ensures only one colormap is created per visual.  Colormaps are also deleted when the application terminates.*/struct QCMapEntry {    QCMapEntry();    ~QCMapEntry();    Colormap cmap;    bool alloc;    XStandardColormap scmap;};QCMapEntry::QCMapEntry(){    cmap = 0;    alloc = false;    scmap.colormap = 0;}QCMapEntry::~QCMapEntry(){    if (alloc)        XFreeColormap(X11->display, cmap);}typedef QHash<int, QCMapEntry *> CMapEntryHash;typedef QHash<int, QMap<int, QRgb> > GLCMapHash;static bool mesa_gl = false;static bool first_time = true;static void cleanup_cmaps();struct QGLCMapCleanupHandler {    QGLCMapCleanupHandler() {        cmap_hash = new CMapEntryHash;        qglcmap_hash = new GLCMapHash;        cleaned_up = false;        qAddPostRoutine(cleanup_cmaps);    }    ~QGLCMapCleanupHandler() {        qRemovePostRoutine(cleanup_cmaps);        cleanup_cmaps();        delete cmap_hash;        delete qglcmap_hash;    }    CMapEntryHash *cmap_hash;    GLCMapHash *qglcmap_hash;    bool cleaned_up;};Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler);static void cleanup_cmaps(){    if (!cmap_handler()->cleaned_up) {        CMapEntryHash *hash = cmap_handler()->cmap_hash;        QHash<int, QCMapEntry *>::ConstIterator it = hash->constBegin();        while (it != hash->constEnd()) {            delete it.value();            ++it;        }        hash->clear();        cmap_handler()->cleaned_up = true;    }}static Colormap choose_cmap(Display *dpy, XVisualInfo *vi){    if (first_time) {        const char *v = glXQueryServerString(dpy, vi->screen, GLX_VERSION);        if (v)            mesa_gl = (strstr(v, "Mesa") != 0);        first_time = false;    }    CMapEntryHash *hash = cmap_handler()->cmap_hash;    CMapEntryHash::ConstIterator it = hash->constFind((long) vi->visualid + (vi->screen * 256));    if (it != hash->constEnd())        return it.value()->cmap; // found colormap for visual    if (vi->visualid ==        XVisualIDFromVisual((Visual *) QX11Info::appVisual(vi->screen))) {        // qDebug("Using x11AppColormap");        return QX11Info::appColormap(vi->screen);    }    QCMapEntry *x = new QCMapEntry();    XStandardColormap *c;    int n, i;    // qDebug("Choosing cmap for vID %0x", vi->visualid);    if (mesa_gl) {                                // we're using MesaGL        Atom hp_cmaps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", true);        if (hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8) {            if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,                                 hp_cmaps)) {                i = 0;                while (i < n && x->cmap == 0) {                    if (c[i].visualid == vi->visual->visualid) {                        x->cmap = c[i].colormap;                        x->scmap = c[i];                        //qDebug("Using HP_RGB scmap");                    }                    i++;                }                XFree((char *)c);            }        }    }    if (!x->cmap) {        if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,                             XA_RGB_DEFAULT_MAP)) {            for (int i = 0; i < n && x->cmap == 0; ++i) {                if (!c[i].red_max ||                    !c[i].green_max ||                    !c[i].blue_max ||                    !c[i].red_mult ||                    !c[i].green_mult ||                    !c[i].blue_mult)                    continue; // invalid stdcmap                if (c[i].visualid == vi->visualid) {                    x->cmap = c[i].colormap;                    x->scmap = c[i];                    //qDebug("Using RGB_DEFAULT scmap");                }            }            XFree((char *)c);        }    }    if (!x->cmap) {                                // no shared cmap found        x->cmap = XCreateColormap(dpy, RootWindow(dpy,vi->screen), vi->visual,                                  AllocNone);        x->alloc = true;        // qDebug("Allocating cmap");    }    // associate cmap with visualid    hash->insert((long) vi->visualid + (vi->screen * 256), x);    return x->cmap;}struct QTransColor{    VisualID vis;    int screen;    long color;};static QVector<QTransColor> trans_colors;static int trans_colors_init = false;static void find_trans_colors(){    struct OverlayProp {        long  visual;        long  type;        long  value;        long  layer;    };    trans_colors_init = true;    Display* appDisplay = X11->display;    int scr;    int lastsize = 0;    for (scr = 0; scr < ScreenCount(appDisplay); scr++) {        QWidget* rootWin = QApplication::desktop()->screen(scr);        if (!rootWin)            return;                                        // Should not happen        Atom overlayVisualsAtom = XInternAtom(appDisplay,                                               "SERVER_OVERLAY_VISUALS", True);        if (overlayVisualsAtom == XNone)            return;                                        // Server has no overlays        Atom actualType;        int actualFormat;        ulong nItems;        ulong bytesAfter;        unsigned char *retval = 0;        int res = XGetWindowProperty(appDisplay, rootWin->winId(),                                      overlayVisualsAtom, 0, 10000, False,                                      overlayVisualsAtom, &actualType,                                      &actualFormat, &nItems, &bytesAfter,                                      &retval);        if (res != Success || actualType != overlayVisualsAtom             || actualFormat != 32 || nItems < 4 || !retval)            return;                                        // Error reading property        OverlayProp *overlayProps = (OverlayProp *)retval;        int numProps = nItems / 4;        trans_colors.resize(lastsize + numProps);        int j = lastsize;        for (int i = 0; i < numProps; i++) {            if (overlayProps[i].type == 1) {                trans_colors[j].vis = (VisualID)overlayProps[i].visual;                trans_colors[j].screen = scr;                trans_colors[j].color = (int)overlayProps[i].value;                j++;            }        }        XFree(overlayProps);        lastsize = j;        trans_colors.resize(lastsize);    }}/*****************************************************************************  QGLFormat UNIX/GLX-specific code *****************************************************************************/bool QGLFormat::hasOpenGL(){    return glXQueryExtension(X11->display, 0, 0) != 0;}bool QGLFormat::hasOpenGLOverlays(){    if (!trans_colors_init)        find_trans_colors();    return trans_colors.size() > 0;}/*****************************************************************************  QGLContext UNIX/GLX-specific code *****************************************************************************/bool QGLContext::chooseContext(const QGLContext* shareContext){    Q_D(QGLContext);    const QX11Info *xinfo = qt_x11Info(d->paintDevice);    Display* disp = xinfo->display();    d->vi = chooseVisual();    if (!d->vi)        return false;    if (deviceIsPixmap() &&         (((XVisualInfo*)d->vi)->depth != xinfo->depth() ||          ((XVisualInfo*)d->vi)->screen != xinfo->screen()))    {        XFree(d->vi);        XVisualInfo appVisInfo;        memset(&appVisInfo, 0, sizeof(XVisualInfo));        appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual());        appVisInfo.screen = xinfo->screen();        int nvis;        d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis);        if (!d->vi)            return false;        int useGL;        glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL);        if (!useGL)            return false;        //# Chickening out already...    }    int res;    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res);    d->glFormat.setPlane(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res);    d->glFormat.setDoubleBuffer(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res);    d->glFormat.setDepth(res);    if (d->glFormat.depth())        d->glFormat.setDepthBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res);    d->glFormat.setRgba(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res);    d->glFormat.setRedBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res);    d->glFormat.setGreenBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res);    d->glFormat.setBlueBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res);    d->glFormat.setAlpha(res);    if (d->glFormat.alpha())        d->glFormat.setAlphaBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res);    d->glFormat.setAccum(res);    if (d->glFormat.accum())        d->glFormat.setAccumBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res);    d->glFormat.setStencil(res);    if (d->glFormat.stencil())        d->glFormat.setStencilBufferSize(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res);    d->glFormat.setStereo(res);    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res);    d->glFormat.setSampleBuffers(res);    if (d->glFormat.sampleBuffers()) {        glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res);        d->glFormat.setSamples(res);    }    Bool direct = format().directRendering() ? True : False;    if (shareContext &&         (!shareContext->isValid() || !shareContext->d_func()->cx)) {            qWarning("QGLContext::chooseContext(): Cannot share with invalid context");            shareContext = 0;    }    // 1. Sharing between rgba and color-index will give wrong colors.    // 2. Contexts cannot be shared btw. direct/non-direct renderers.    // 3. Pixmaps cannot share contexts that are set up for direct rendering.    // 4. If the contexts are not created on the same screen, they can't be shared    if (shareContext        && (format().rgba() != shareContext->format().rgba()            || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx))            || (shareContext->d_func()->screen != xinfo->screen())))    {        shareContext = 0;    }    d->cx = 0;    if (shareContext) {        d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi,                               (GLXContext)shareContext->d_func()->cx, direct);        d->screen = ((XVisualInfo*)d->vi)->screen;        if (d->cx) {            QGLContext *share = const_cast<QGLContext *>(shareContext);            d->sharing = true;            share->d_func()->sharing = true;        }    }    if (!d->cx) {        d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct);        d->screen = ((XVisualInfo*)d->vi)->screen;    }    if (!d->cx)        return false;    d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx));    if (deviceIsPixmap()) {#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)        d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi,                                        qt_x11Handle(d->paintDevice),                                        choose_cmap(disp, (XVisualInfo *)d->vi));#else        d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi,                                              qt_x11Handle(d->paintDevice));#endif        if (!d->gpm)            return false;    }    return true;}/*!  \bold{X11 only:} This virtual function tries to find a  visual that matches the format, reducing the demands if the original  request cannot be met.  The algorithm for reducing the demands of the format is quite  simple-minded, so override this method in your subclass if your  application has spcific requirements on visual selection.  \sa chooseContext()*/void *QGLContext::chooseVisual(){    Q_D(QGLContext);    static int bufDepths[] = { 8, 4, 2, 1 };        // Try 16, 12 also?    //todo: if pixmap, also make sure that vi->depth == pixmap->depth    void* vis = 0;    int i = 0;    bool fail = false;    QGLFormat fmt = format();    bool tryDouble = !fmt.doubleBuffer();  // Some GL impl's only have double    bool triedDouble = false;    bool triedSample = false;    if (fmt.sampleBuffers())        fmt.setSampleBuffers(QGLExtensions::glExtensions & QGLExtensions::SampleBuffers);    while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) {        if (!fmt.rgba() && bufDepths[i] > 1) {            i++;            continue;        }        if (tryDouble) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -