QPlatformGLContext *QXcbWindow::glContext() const { if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { printf("no opengl\n"); return 0; } if (!m_context) { #if defined(XCB_USE_GLX) QXcbWindow *that = const_cast<QXcbWindow *>(this); that->m_context = new QGLXContext(m_window, m_screen, widget()->platformWindowFormat()); #elif defined(XCB_USE_EGL) EGLDisplay display = connection()->egl_display(); EGLConfig config = q_configFromQPlatformWindowFormat(display,widget()->platformWindowFormat(),true); QVector<EGLint> eglContextAttrs; eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2); eglContextAttrs.append(EGL_NONE); EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0); QXcbWindow *that = const_cast<QXcbWindow *>(this); that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API); #elif defined(XCB_USE_DRI2) QXcbWindow *that = const_cast<QXcbWindow *>(this); that->m_context = new QDri2Context(that); #endif } return m_context; }
QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window) : QPlatformGLContext() , mEglIntegration(glxIntegration) , mWindow(window) , mBuffer(0) , mXWindow(0) , mConfig(q_configFromQPlatformWindowFormat(glxIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_WINDOW_BIT)) , mWaitingForSync(false) { QVector<EGLint> eglContextAttrs; eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2); eglContextAttrs.append(EGL_NONE); mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData()); if (mContext == EGL_NO_CONTEXT) { qFatal("failed to find context"); } geometryChanged(); }
QWebOSGLContext::QWebOSGLContext(QWebOSWindow* platformWindow) : m_platformWindow(platformWindow) , m_eglSurface(EGL_NO_SURFACE) { m_windowFormat = QPlatformWindowFormat::defaultFormat(); m_windowFormat.setWindowApi(QPlatformWindowFormat::OpenGL); QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH"); if (depthString.toInt() == 16) { m_windowFormat.setDepth(16); m_windowFormat.setRedBufferSize(5); m_windowFormat.setGreenBufferSize(6); m_windowFormat.setBlueBufferSize(5); } else { m_windowFormat.setDepth(32); m_windowFormat.setRedBufferSize(8); m_windowFormat.setGreenBufferSize(8); m_windowFormat.setBlueBufferSize(8); } if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) m_windowFormat.setSampleBuffers(true); EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); if (eglResult != EGL_TRUE) qFatal("QWebOS: failed to set EGL API, err=%d", eglGetError()); m_eglConfig = q_configFromQPlatformWindowFormat(s_eglDisplay, m_windowFormat); EGLint contextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; m_eglContext = eglCreateContext(s_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs); if (m_eglContext == EGL_NO_CONTEXT) qFatal("QWebOS: failed to create EGL context, err=%d", eglGetError()); createSurface(); }
QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format) : QPlatformGLContext() , mEglDisplay(eglDisplay) , mSurface(EGL_NO_SURFACE) , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true)) , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig)) { QPlatformGLContext *sharePlatformContext = 0; sharePlatformContext = format.sharedGLContext(); mFormat.setSharedContext(sharePlatformContext); EGLContext shareEGLContext = EGL_NO_CONTEXT; if (sharePlatformContext) shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext; eglBindAPI(EGL_OPENGL_ES_API); QVector<EGLint> eglContextAttrs; eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2); eglContextAttrs.append(EGL_NONE); mContext = eglCreateContext(mEglDisplay, mConfig, shareEGLContext, eglContextAttrs.constData()); }
QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw) : QPlatformWindow(tlw), isFullScreen(false) { if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenVG) { m_eglApi = EGL_OPENVG_API; } else { m_eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); m_eglContextAttrs.append(2); m_eglApi = EGL_OPENGL_ES_API; } eglBindAPI(m_eglApi); m_eglContextAttrs.append(EGL_NONE); m_eglWindowAttrs.append(EGL_NONE); QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens(); //XXXX: jl figure out how to pick the correct screen. // Q_ASSERT(screens.size() > tlw->d_func()->screenNumber); // QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(tlw->d_func()->screenNumber)); QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0)); if (!screen) { qErrnoWarning("Could not make QOpenKODEWindow without a screen"); } QPlatformWindowFormat format = tlw->platformWindowFormat(); format.setRedBufferSize(5); format.setGreenBufferSize(6); format.setBlueBufferSize(5); m_eglConfig = q_configFromQPlatformWindowFormat(screen->eglDisplay(),format); m_kdWindow = kdCreateWindow(screen->eglDisplay(), m_eglConfig, this); kdInstallCallback(kdProcessMouseEvents,KD_EVENT_INPUT_POINTER,this); #ifdef KD_ATX_keyboard kdInstallCallback(kdProcessKeyEvents, KD_EVENT_INPUT_KEY_ATX,this); #endif //KD_ATX_keyboard if (!m_kdWindow) { qErrnoWarning(kdGetError(), "Error creating native window"); return; } KDboolean exclusive(false); if (kdSetWindowPropertybv(m_kdWindow,KD_WINDOWPROPERTY_DESKTOP_EXCLUSIVE_NV, &exclusive)) { isFullScreen = true; } if (isFullScreen) { tlw->setGeometry(screen->geometry()); screen->setFullScreen(isFullScreen); }else { const KDint windowSize[2] = { tlw->width(), tlw->height() }; if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) { qErrnoWarning(kdGetError(), "Could not set native window size"); } KDboolean visibillity(false); if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) { qErrnoWarning(kdGetError(), "Could not set visibillity to false"); } const KDint windowPos[2] = { tlw->x(), tlw->y() }; if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) { qErrnoWarning(kdGetError(), "Could not set native window position"); return; } } QOpenKODEIntegration *integration = static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration()); if (!isFullScreen || (isFullScreen && !integration->mainGLContext())) { if (kdRealizeWindow(m_kdWindow, &m_eglWindow)) { qErrnoWarning(kdGetError(), "Could not realize native window"); return; } EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData()); m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(), m_eglConfig, m_eglContextAttrs.data(), surface, m_eglApi); integration->setMainGLContext(m_platformGLContext); } else { m_platformGlContext = integration->mainGLContext(); kdDestroyWindow(m_kdWindow); m_kdWindow = 0; } }
void QEglFSScreen::createAndSetPlatformContext() { QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat(); platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL); QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH"); if (depthString.toInt() == 16) { platformFormat.setDepth(16); platformFormat.setRedBufferSize(5); platformFormat.setGreenBufferSize(6); platformFormat.setBlueBufferSize(5); m_depth = 16; m_format = QImage::Format_RGB16; } else { platformFormat.setDepth(32); platformFormat.setRedBufferSize(8); platformFormat.setGreenBufferSize(8); platformFormat.setBlueBufferSize(8); m_depth = 32; m_format = QImage::Format_RGB32; } if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) { platformFormat.setSampleBuffers(true); } EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat); EGLNativeWindowType eglWindow = 0; #ifdef Q_OPENKODE if (kdInitializeNV() == KD_ENOTINITIALIZED) { qFatal("Did not manage to initialize openkode"); } KDWindow *window = kdCreateWindow(m_dpy,config,0); kdRealizeWindow(window,&eglWindow); #endif m_surface = eglCreateWindowSurface(m_dpy, config, eglWindow, NULL); if (m_surface == EGL_NO_SURFACE) { qWarning("Could not create the egl surface: error = 0x%x\n", eglGetError()); eglTerminate(m_dpy); qFatal("EGL error"); } // qWarning("Created surface %dx%d\n", w, h); #ifdef QEGL_EXTRA_DEBUG qWarning("Configuration %d matches requirements\n", (int)config); for (index = 0; attrs[index].attr != -1; ++index) { EGLint value; if (eglGetConfigAttrib(m_dpy, config, attrs[index].attr, &value)) { qWarning("\t%s: %d\n", attrs[index].name, (int)value); } } qWarning("\n"); #endif EGLint temp; EGLint attribList[32]; temp = 0; attribList[temp++] = EGL_CONTEXT_CLIENT_VERSION; attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); m_platformContext = platformContext; EGLint w,h; // screen size detection eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w); eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h); m_geometry = QRect(0,0,w,h); }
QT_BEGIN_NAMESPACE QXlibWindow::QXlibWindow(QWidget *window) : QPlatformWindow(window) , mGLContext(0) , mScreen(QXlibScreen::testLiteScreenForWidget(window)) { int x = window->x(); int y = window->y(); int w = window->width(); int h = window->height(); #if !defined(QT_NO_OPENGL) if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) || window->platformWindowFormat().alpha()) { #if !defined(QT_OPENGL_ES_2) XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat()); #else QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat()); EGLDisplay eglDisplay = mScreen->eglDisplay(); EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,windowFormat); VisualID id = QXlibEglIntegration::getCompatibleVisualId(mScreen->display()->nativeDisplay(), eglDisplay, eglConfig); XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); visualInfoTemplate.visualid = id; XVisualInfo *visualInfo; int matchingCount = 0; visualInfo = XGetVisualInfo(mScreen->display()->nativeDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); #endif //!defined(QT_OPENGL_ES_2) if (visualInfo) { mDepth = visualInfo->depth; mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; mVisual = visualInfo->visual; Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(), mScreen->rootWindow(), visualInfo->visual, AllocNone); XSetWindowAttributes a; a.background_pixel = WhitePixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber()); a.border_pixel = BlackPixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber()); a.colormap = cmap; x_window = XCreateWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),x, y, w, h, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel|CWBorderPixel|CWColormap, &a); } else { qFatal("no window!"); } } else #endif //!defined(QT_NO_OPENGL) { mDepth = mScreen->depth(); mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; mVisual = mScreen->defaultVisual(); x_window = XCreateSimpleWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(), x, y, w, h, 0 /*border_width*/, mScreen->blackPixel(), mScreen->whitePixel()); } #ifdef MYX11_DEBUG qDebug() << "QTestLiteWindow::QTestLiteWindow creating" << hex << x_window << window; #endif XSetWindowBackgroundPixmap(mScreen->display()->nativeDisplay(), x_window, XNone); XSelectInput(mScreen->display()->nativeDisplay(), x_window, ExposureMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PropertyChangeMask | StructureNotifyMask); gc = createGC(); Atom protocols[5]; int n = 0; protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW); // support del window protocol protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_TAKE_FOCUS); // support take focus window protocol // protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_PING); // support _NET_WM_PING protocol #ifndef QT_NO_XSYNC protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol #endif // QT_NO_XSYNC if (window->windowFlags() & Qt::WindowContextHelpButtonHint) protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_CONTEXT_HELP); XSetWMProtocols(mScreen->display()->nativeDisplay(), x_window, protocols, n); }
QXcbWindow::QXcbWindow(QWidget *tlw) : QPlatformWindow(tlw) , m_context(0) { m_screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(tlw)); setConnection(m_screen->connection()); const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK; const quint32 values[] = { // XCB_CW_BACK_PIXMAP XCB_NONE, // XCB_CW_EVENT_MASK XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE }; #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL) if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) || tlw->platformWindowFormat().alpha()) { #if defined(XCB_USE_GLX) XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat()); #elif defined(XCB_USE_EGL) EGLDisplay eglDisplay = connection()->egl_display(); EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true); VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig); XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); visualInfoTemplate.visualid = id; XVisualInfo *visualInfo; int matchingCount = 0; visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount); #endif //XCB_USE_GLX if (visualInfo) { m_depth = visualInfo->depth; m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone); XSetWindowAttributes a; a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber()); a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber()); a.colormap = cmap; m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(), 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel|CWBorderPixel|CWColormap, &a); printf("created GL window: %d\n", m_window); } else { qFatal("no window!"); } } else #endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL) { m_window = xcb_generate_id(xcb_connection()); m_depth = m_screen->screen()->root_depth; m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; Q_XCB_CALL(xcb_create_window(xcb_connection(), XCB_COPY_FROM_PARENT, // depth -- same as root m_window, // window id m_screen->root(), // parent window id tlw->x(), tlw->y(), tlw->width(), tlw->height(), 0, // border width XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class m_screen->screen()->root_visual, // visual 0, // value mask 0)); // value list printf("created regular window: %d\n", m_window); } Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values)); xcb_atom_t properties[4]; int propertyCount = 0; properties[propertyCount++] = atom(QXcbAtom::WM_DELETE_WINDOW); properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS); properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING); if (m_screen->syncRequestSupported()) properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST); if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint) properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::WM_PROTOCOLS), XCB_ATOM_ATOM, 32, propertyCount, properties)); m_syncValue.hi = 0; m_syncValue.lo = 0; if (m_screen->syncRequestSupported()) { m_syncCounter = xcb_generate_id(xcb_connection()); Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue)); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_SYNC_REQUEST_COUNTER), XCB_ATOM_CARDINAL, 32, 1, &m_syncCounter)); } if (isTransient(tlw) && tlw->parentWidget()) { // ICCCM 4.1.2.6 QWidget *p = tlw->parentWidget()->window(); xcb_window_t parentWindow = p->winId(); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, 1, &parentWindow)); } // set the PID to let the WM kill the application if unresponsive long pid = getpid(); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32, 1, &pid)); }