QGLXContext::~QGLXContext() { Q_XCB_NOOP(m_screen->connection()); if (m_context) glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context); Q_XCB_NOOP(m_screen->connection()); }
void QGLXContext::makeCurrent() { Q_XCB_NOOP(m_screen->connection()); QPlatformGLContext::makeCurrent(); glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context); Q_XCB_NOOP(m_screen->connection()); }
void* QGLXContext::getProcAddress(const QString& procName) { Q_XCB_NOOP(m_screen->connection()); typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; static bool resolved = false; if (resolved && !glXGetProcAddressARB) return 0; if (!glXGetProcAddressARB) { QList<QByteArray> glxExt = QByteArray(glXGetClientString(DISPLAY_FROM_XCB(m_screen), GLX_EXTENSIONS)).split(' '); if (glxExt.contains("GLX_ARB_get_proc_address")) { #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) void *handle = dlopen(NULL, RTLD_LAZY); if (handle) { glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); dlclose(handle); } if (!glXGetProcAddressARB) #endif { extern const QString qt_gl_library_name(); // QLibrary lib(qt_gl_library_name()); QLibrary lib(QLatin1String("GL")); glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); } } resolved = true; } if (!glXGetProcAddressARB) return 0; return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data())); }
void QGLXContext::doneCurrent() { Q_XCB_NOOP(m_screen->connection()); QPlatformGLContext::doneCurrent(); glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0); Q_XCB_NOOP(m_screen->connection()); }
void *QXcbGlxWindow::createVisual() { QXcbScreen *scr = xcbScreen(); if (!scr) return Q_NULLPTR; return qglx_findVisualInfo(DISPLAY_FROM_XCB(scr), scr->screenNumber(), &m_format); }
void QGLXContext::swapBuffers() { Q_XCB_NOOP(m_screen->connection()); glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable); doneCurrent(); Q_XCB_NOOP(m_screen->connection()); }
QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format) : QPlatformGLContext() , m_screen(screen) , m_drawable((Drawable)window) , m_context(0) { Q_XCB_NOOP(m_screen->connection()); const QPlatformGLContext *sharePlatformContext; sharePlatformContext = format.sharedGLContext(); GLXContext shareGlxContext = 0; if (sharePlatformContext) shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext(); GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE); m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); Q_XCB_NOOP(m_screen->connection()); }
xcb_cursor_t QXcbCursor::createFontCursor(int cshape) { xcb_connection_t *conn = xcb_connection(); int cursorId = cursorIdForShape(cshape); xcb_cursor_t cursor = XCB_NONE; // Try Xcursor first #ifdef XCB_USE_XLIB if (cshape >= 0 && cshape <= Qt::LastCursor) { void *dpy = connection()->xlib_display(); // special case for non-standard dnd-* cursors cursor = loadCursor(dpy, cshape); if (!cursor && !m_gtkCursorThemeInitialized && m_screen->xSettings()->initialized()) { QByteArray gtkCursorTheme = m_screen->xSettings()->setting("Gtk/CursorThemeName").toByteArray(); m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName",cursorThemePropertyChanged,this); if (updateCursorTheme(dpy,gtkCursorTheme)) { cursor = loadCursor(dpy, cshape); } m_gtkCursorThemeInitialized = true; } } if (cursor) return cursor; if (!cursor && cursorId) { cursor = XCreateFontCursor(DISPLAY_FROM_XCB(this), cursorId); if (cursor) return cursor; } #endif // Non-standard X11 cursors are created from bitmaps cursor = createNonStandardCursor(cshape); // Create a glpyh cursor if everything else failed if (!cursor && cursorId) { cursor = xcb_generate_id(conn); xcb_create_glyph_cursor(conn, cursor, cursorFont, cursorFont, cursorId, cursorId + 1, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); } if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { const char *name = cursorNames[cshape]; xcb_xfixes_set_cursor_name(conn, cursor, strlen(name), name); } return cursor; }
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)); }