static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w) { xcb_window_t proxy = XCB_NONE; xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, w, c->atom(QXcbAtom::XdndProxy), XCB_ATOM_WINDOW, 0, 1), c); xcb_get_property_reply_t *reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0); if (reply && reply->type == XCB_ATOM_WINDOW) proxy = *((xcb_window_t *)xcb_get_property_value(reply)); free(reply); if (proxy == XCB_NONE) return proxy; // exists and is real? cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, proxy, c->atom(QXcbAtom::XdndProxy), XCB_ATOM_WINDOW, 0, 1), c); reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0); if (reply && reply->type == XCB_ATOM_WINDOW) { xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply)); if (proxy != p) proxy = 0; } else { proxy = 0; } free(reply); return proxy; }
QT_BEGIN_NAMESPACE QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, xcb_randr_get_output_info_reply_t *output, QString outputName, int number) : QXcbObject(connection) , m_screen(scr) , m_crtc(output ? output->crtc : 0) , m_outputName(outputName) , m_sizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) , m_virtualSize(scr->width_in_pixels, scr->height_in_pixels) , m_virtualSizeMillimeters(scr->width_in_millimeters, scr->height_in_millimeters) , m_orientation(Qt::PrimaryOrientation) , m_number(number) , m_refreshRate(60) , m_forcedDpi(-1) { if (connection->hasXRandr()) xcb_randr_select_input(xcb_connection(), screen()->root, true); updateGeometry(output ? output->timestamp : 0); updateRefreshRate(); // On VNC, it can be that physical size is unknown while // virtual size is known (probably back-calculated from DPI and resolution) if (m_sizeMillimeters.isEmpty()) m_sizeMillimeters = m_virtualSizeMillimeters; if (m_geometry.isEmpty()) m_geometry = QRect(QPoint(), m_virtualSize); if (m_availableGeometry.isEmpty()) m_availableGeometry = QRect(QPoint(), m_virtualSize); readXResources(); #ifdef Q_XCB_DEBUG qDebug(); qDebug("Screen output %s of xcb screen %d:", m_outputName.toUtf8().constData(), m_number); qDebug(" width..........: %lf", m_sizeMillimeters.width()); qDebug(" height.........: %lf", m_sizeMillimeters.height()); qDebug(" geometry.......: %d x %d +%d +%d", m_geometry.width(), m_geometry.height(), m_geometry.x(), m_geometry.y()); qDebug(" virtual width..: %lf", m_virtualSizeMillimeters.width()); qDebug(" virtual height.: %lf", m_virtualSizeMillimeters.height()); qDebug(" virtual geom...: %d x %d", m_virtualSize.width(), m_virtualSize.height()); qDebug(" avail virt geom: %d x %d +%d +%d", m_availableGeometry.width(), m_availableGeometry.height(), m_availableGeometry.x(), m_availableGeometry.y()); qDebug(" depth..........: %d", screen()->root_depth); qDebug(" white pixel....: %x", screen()->white_pixel); qDebug(" black pixel....: %x", screen()->black_pixel); qDebug(" refresh rate...: %d", m_refreshRate); qDebug(" root ID........: %x", screen()->root); #endif const quint32 mask = XCB_CW_EVENT_MASK; const quint32 values[] = { // XCB_CW_EVENT_MASK XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_PROPERTY_CHANGE }; xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values); xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), xcb_get_property_unchecked(xcb_connection(), false, screen()->root, atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK), XCB_ATOM_WINDOW, 0, 1024), NULL); if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) { xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply)); if (windowManager != XCB_WINDOW_NONE) { xcb_get_property_reply_t *windowManagerReply = xcb_get_property_reply(xcb_connection(), xcb_get_property_unchecked(xcb_connection(), false, windowManager, atom(QXcbAtom::_NET_WM_NAME), atom(QXcbAtom::UTF8_STRING), 0, 1024), NULL); if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) { m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply)); #ifdef Q_XCB_DEBUG qDebug(" window manager.: %s", qPrintable(m_windowManagerName)); qDebug(); #endif } free(windowManagerReply); } } free(reply); const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id); if (!sync_reply || !sync_reply->present) m_syncRequestSupported = false; else m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin"); m_clientLeader = xcb_generate_id(xcb_connection()); Q_XCB_CALL2(xcb_create_window(xcb_connection(), XCB_COPY_FROM_PARENT, m_clientLeader, screen()->root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen()->root_visual, 0, 0), connection); Q_XCB_CALL2(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_clientLeader, atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32, 1, &m_clientLeader), connection); xcb_depth_iterator_t depth_iterator = xcb_screen_allowed_depths_iterator(screen()); while (depth_iterator.rem) { xcb_depth_t *depth = depth_iterator.data; xcb_visualtype_iterator_t visualtype_iterator = xcb_depth_visuals_iterator(depth); while (visualtype_iterator.rem) { xcb_visualtype_t *visualtype = visualtype_iterator.data; m_visuals.insert(visualtype->visual_id, *visualtype); xcb_visualtype_next(&visualtype_iterator); } xcb_depth_next(&depth_iterator); } m_cursor = new QXcbCursor(connection, this); }