📄 qgl_x11.cpp
字号:
spec[i++] = GLX_STEREO; } if ( f.stencil() ) { spec[i++] = GLX_STENCIL_SIZE; spec[i++] = 1; } if ( f.rgba() ) { spec[i++] = GLX_RGBA; spec[i++] = GLX_RED_SIZE; spec[i++] = 1; spec[i++] = GLX_GREEN_SIZE; spec[i++] = 1; spec[i++] = GLX_BLUE_SIZE; spec[i++] = 1; if ( f.alpha() ) { spec[i++] = GLX_ALPHA_SIZE; spec[i++] = 1; } if ( f.accum() ) { spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = 1; spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = 1; spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = 1; if ( f.alpha() ) { spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = 1; } } } else { spec[i++] = GLX_BUFFER_SIZE; spec[i++] = bufDepth; } spec[i] = None; return glXChooseVisual( paintDevice->x11Display(), paintDevice->x11Screen(), spec );}void QGLContext::reset(){ if ( !valid ) return; doneCurrent(); if ( gpm ) glXDestroyGLXPixmap( paintDevice->x11Display(), (GLXPixmap)gpm ); gpm = 0; glXDestroyContext( paintDevice->x11Display(), (GLXContext)cx ); if ( vi ) XFree( vi ); vi = 0; cx = 0; crWin = FALSE; sharing = FALSE; valid = FALSE; transpColor = QColor(); initDone = FALSE;}void QGLContext::makeCurrent(){ if ( !valid ) {#if defined(CHECK_STATE) qWarning("QGLContext::makeCurrent(): Cannot make invalid context current.");#endif return; } bool ok = TRUE; if ( deviceIsPixmap() ) ok = glXMakeCurrent( paintDevice->x11Display(), (GLXPixmap)gpm, (GLXContext)cx ); else ok = glXMakeCurrent( paintDevice->x11Display(), ((QWidget *)paintDevice)->winId(), (GLXContext)cx );#if defined(CHECK_NULL) // qDebug("makeCurrent: %i, vi=%i, vi->vi=%i, vi->id=%i", (int)this, (int)vi, (int)((XVisualInfo*)vi)->visual, (int)((XVisualInfo*)vi)->visualid ); if ( !ok ) qWarning("QGLContext::makeCurrent(): Failed.");#endif if ( ok ) currentCtx = this;}void QGLContext::doneCurrent(){ glXMakeCurrent( paintDevice->x11Display(), 0, 0 ); currentCtx = 0;}void QGLContext::swapBuffers() const{ if ( !valid ) return; if ( !deviceIsPixmap() ) glXSwapBuffers( paintDevice->x11Display(), ((QWidget *)paintDevice)->winId() );}QColor QGLContext::overlayTransparentColor() const{ //### make more efficient using the transpColor member if ( isValid() ) { if ( !trans_colors_init ) find_trans_colors(); VisualID myVisualId = ((XVisualInfo*)vi)->visualid; for ( int i = 0; i < (int)trans_colors.size(); i++ ) { if ( trans_colors[i].vis == myVisualId ) return QColor( qRgb( 1, 2, 3 ), trans_colors[i].color ); } } return QColor(); // Invalid color}uint QGLContext::colorIndex( const QColor& c ) const{ if ( isValid() ) { if ( format().plane() && c.pixel() == overlayTransparentColor().pixel() ) return c.pixel(); // Special; don't look-up if ( ((XVisualInfo*)vi)->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) ) return c.pixel(); // We're using QColor's cmap CMapEntry *x = cmap_dict->find( (long)((XVisualInfo*)vi)->visualid ); if ( x && !x->alloc) { // It's a standard colormap int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0); int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0); int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0); uint p = x->scmap.base_pixel + ( rf * x->scmap.red_mult ) + ( gf * x->scmap.green_mult ) + ( bf * x->scmap.blue_mult ); return p; } else return c.pixel(); // ### wrong; should really ask QColor to alloc } return 0;}/***************************************************************************** QGLOverlayWidget (Internal overlay class for X11) *****************************************************************************/class QGLOverlayWidget : public QGLWidget{ Q_OBJECTpublic: QGLOverlayWidget( const QGLFormat& format, QGLWidget* parent, const char* name=0, const QGLWidget* shareWidget=0 );protected: void initializeGL(); void paintGL(); void resizeGL( int w, int h ); void mousePressEvent( QMouseEvent* e ); void mouseMoveEvent( QMouseEvent* e ); void mouseReleaseEvent( QMouseEvent* e ); void mouseDoubleClickEvent( QMouseEvent* e ); void enterEvent( QEvent* ); void leaveEvent( QEvent* ); private: QGLWidget* realWidget;private: // Disabled copy constructor and operator=#if defined(Q_DISABLE_COPY) QGLOverlayWidget( const QGLOverlayWidget& ); QGLOverlayWidget& operator=( const QGLOverlayWidget& );#endif};QGLOverlayWidget::QGLOverlayWidget( const QGLFormat& format, QGLWidget* parent, const char* name, const QGLWidget* shareWidget ) : QGLWidget( format, parent, name, shareWidget ? shareWidget->olw : 0 ){ realWidget = parent;}void QGLOverlayWidget::initializeGL(){ QColor transparentColor = context()->overlayTransparentColor(); if ( transparentColor.isValid() ) qglClearColor( transparentColor ); else qWarning( "QGLOverlayWidget::initializeGL(): Could not get transparent color" ); realWidget->initializeOverlayGL();}void QGLOverlayWidget::resizeGL( int w, int h ){ glViewport( 0, 0, w, h ); realWidget->resizeOverlayGL( w, h );}void QGLOverlayWidget::paintGL(){ realWidget->paintOverlayGL();}void QGLOverlayWidget::mousePressEvent( QMouseEvent* e ){ QApplication::sendEvent( realWidget, e );}void QGLOverlayWidget::mouseMoveEvent( QMouseEvent* e ){ QApplication::sendEvent( realWidget, e );}void QGLOverlayWidget::mouseReleaseEvent( QMouseEvent* e ){ QApplication::sendEvent( realWidget, e );}void QGLOverlayWidget::mouseDoubleClickEvent( QMouseEvent* e ){ QApplication::sendEvent( realWidget, e );}void QGLOverlayWidget::enterEvent( QEvent* e ){ QApplication::sendEvent( realWidget, e );}void QGLOverlayWidget::leaveEvent( QEvent* e ){ QApplication::sendEvent( realWidget, e );}#include "qgl_x11.moc"/***************************************************************************** QGLWidget UNIX/GLX-specific code *****************************************************************************/void QGLWidget::init( const QGLFormat& format, const QGLWidget* shareWidget ){ glcx = 0; olw = 0; autoSwap = TRUE; if ( shareWidget ) setContext( new QGLContext( format, this ), shareWidget->context() ); else setContext( new QGLContext( format, this ) ); setBackgroundMode( NoBackground ); if ( isValid() && format.hasOverlay() ) { QCString olwName( name() ); olwName += "-QGL_internal_overlay_widget"; olw = new QGLOverlayWidget( QGLFormat::defaultOverlayFormat(), this, olwName, shareWidget ); if ( olw->isValid() ) { olw->setAutoBufferSwap( FALSE ); olw->setFocusProxy( this ); } else { delete olw; olw = 0; glcx->glFormat.setOverlay( FALSE ); } }}void QGLWidget::setMouseTracking( bool enable ){ if ( olw ) olw->setMouseTracking( enable ); QWidget::setMouseTracking( enable );}void QGLWidget::resizeEvent( QResizeEvent * ){ makeCurrent(); if ( !glcx->initialized() ) glInit(); glXWaitX(); resizeGL( width(), height() ); if ( olw ) olw->setGeometry( rect() );}const QGLContext* QGLWidget::overlayContext() const{ if ( olw ) return olw->context(); else return 0;}void QGLWidget::makeOverlayCurrent(){ if ( olw ) olw->makeCurrent();}void QGLWidget::updateOverlayGL(){ if ( olw ) olw->updateGL();}void QGLWidget::setContext( QGLContext *context, const QGLContext* shareContext, bool deleteOldContext ){ if ( context == 0 ) {#if defined(CHECK_NULL) qWarning( "QGLWidget::setContext: Cannot set null context" );#endif return; } if ( !context->deviceIsPixmap() && context->device() != this ) {#if defined(CHECK_STATE) qWarning( "QGLWidget::setContext: Context must refer to this widget" );#endif return; } if ( glcx ) glcx->doneCurrent(); QGLContext* oldcx = glcx; glcx = context; bool createFailed = FALSE; if ( !glcx->isValid() ) { if ( !glcx->create( shareContext ? shareContext : oldcx ) ) createFailed = TRUE; } if ( createFailed ) { if ( deleteOldContext ) delete oldcx; return; } if ( glcx->windowCreated() || glcx->deviceIsPixmap() ) { if ( deleteOldContext ) delete oldcx; return; } bool visible = isVisible(); if ( visible ) hide(); XVisualInfo *vi = (XVisualInfo*)glcx->vi; XSetWindowAttributes a; a.colormap = choose_cmap( x11Display(), vi ); // find best colormap a.background_pixel = backgroundColor().pixel(); a.border_pixel = black.pixel(); Window p = RootWindow( x11Display(), DefaultScreen(x11Display()) ); //# if ( parentWidget() ) p = parentWidget()->winId(); Window w = XCreateWindow( x11Display(), p, x(), y(), width(), height(), 0, vi->depth, InputOutput, vi->visual, CWBackPixel|CWBorderPixel|CWColormap, &a ); Window *cmw; Window *cmwret; int count; if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) ) { cmw = new Window[count+1]; memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count ); XFree( (char *)cmwret ); int i; for ( i=0; i<count; i++ ) { if ( cmw[i] == winId() ) { // replace old window cmw[i] = w; break; } } if ( i >= count ) // append new window cmw[count++] = w; } else { count = 1; cmw = new Window[count]; cmw[0] = w; }#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT) if ( oldcx && oldcx->windowCreated() ) glXReleaseBuffersMESA( x11Display(), winId() );#endif if ( deleteOldContext ) delete oldcx; oldcx = 0; create( w ); XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count ); delete [] cmw; if ( visible ) show(); XFlush( x11Display() ); glcx->setWindowCreated( TRUE );}bool QGLWidget::renderCxPm( QPixmap* pm ){ if ( ((XVisualInfo*)glcx->vi)->depth != pm->depth() ) return FALSE; GLXPixmap glPm;#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT) glPm = glXCreateGLXPixmapMESA( x11Display(), (XVisualInfo*)glcx->vi, (Pixmap)pm->handle(), choose_cmap( pm->x11Display(), (XVisualInfo*)glcx->vi ) );#else glPm = (Q_UINT32)glXCreateGLXPixmap( x11Display(), (XVisualInfo*)glcx->vi, (Pixmap)pm->handle() );#endif if ( !glXMakeCurrent( x11Display(), glPm, (GLXContext)glcx->cx ) ) { glXDestroyGLXPixmap( x11Display(), glPm ); return FALSE; } glDrawBuffer( GL_FRONT_LEFT ); if ( !glcx->initialized() ) glInit(); resizeGL( pm->width(), pm->height() ); paintGL(); glFlush(); makeCurrent(); glXDestroyGLXPixmap( x11Display(), glPm ); resizeGL( width(), height() ); return TRUE;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -