Пример #1
0
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
    : QXcbObject(screen->connection())
    , m_gc(0)
    , m_gc_window(0)
{
    Q_XCB_NOOP(connection());
    m_xcb_image = xcb_image_create_native(xcb_connection(),
                                          size.width(),
                                          size.height(),
                                          XCB_IMAGE_FORMAT_Z_PIXMAP,
                                          depth,
                                          0,
                                          ~0,
                                          0);

    m_shm_info.shmid = shmget (IPC_PRIVATE,
          m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);

    m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
    m_shm_info.shmseg = xcb_generate_id(xcb_connection());

    xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
    if (error) {
        qWarning() << "QXcbWindowSurface: Unable to attach to shared memory segment";
        free(error);
    }

    if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
        qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";

    m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
Пример #2
0
void QXcbCursor::setPos(const QPoint &pos)
{
    QXcbVirtualDesktop *virtualDesktop = Q_NULLPTR;
    queryPointer(connection(), &virtualDesktop, 0);
    xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
    xcb_flush(xcb_connection());
}
Пример #3
0
QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number)
    : QXcbObject(connection)
    , m_screen(screen)
    , m_number(number)
{
    printf ("\n");
    printf ("Information of screen %d:\n", screen->root);
    printf ("  width.........: %d\n", screen->width_in_pixels);
    printf ("  height........: %d\n", screen->height_in_pixels);
    printf ("  depth.........: %d\n", screen->root_depth);
    printf ("  white pixel...: %x\n", screen->white_pixel);
    printf ("  black pixel...: %x\n", screen->black_pixel);
    printf ("\n");

    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_generic_error_t *error;

    xcb_get_property_reply_t *reply =
        xcb_get_property_reply(xcb_connection(),
            xcb_get_property(xcb_connection(), false, screen->root,
                             atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK),
                             XCB_ATOM_WINDOW, 0, 1024), &error);

    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(xcb_connection(), false, windowManager,
                                     atom(QXcbAtom::_NET_WM_NAME),
                                     atom(QXcbAtom::UTF8_STRING), 0, 1024), &error);
            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));
                printf("Running window manager: %s\n", qPrintable(m_windowManagerName));
            } else if (error) {
                connection->handleXcbError(error);
                free(error);
            }

            free(windowManagerReply);
        }
    } else if (error) {
        connection->handleXcbError(error);
        free(error);
    }

    free(reply);

    m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin");
}
Пример #4
0
QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
    : QXcbObject(conn), m_screen(screen), m_gtkCursorThemeInitialized(false)
{
    if (cursorCount++)
        return;

    cursorFont = xcb_generate_id(xcb_connection());
    const char *cursorStr = "cursor";
    xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr);

#ifdef XCB_USE_XLIB
    static bool function_ptrs_not_initialized = true;
    if (function_ptrs_not_initialized) {
        QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
        bool xcursorFound = xcursorLib.load();
        if (!xcursorFound) { // try without the version number
            xcursorLib.setFileName(QLatin1String("Xcursor"));
            xcursorFound = xcursorLib.load();
        }
        if (xcursorFound) {
            ptrXcursorLibraryLoadCursor =
                (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
            ptrXcursorLibraryGetTheme =
                    (PtrXcursorLibraryGetTheme) xcursorLib.resolve("XcursorGetTheme");
            ptrXcursorLibrarySetTheme =
                    (PtrXcursorLibrarySetTheme) xcursorLib.resolve("XcursorSetTheme");
            ptrXcursorLibraryGetDefaultSize =
                    (PtrXcursorLibraryGetDefaultSize) xcursorLib.resolve("XcursorGetDefaultSize");
        }
        function_ptrs_not_initialized = false;
    }

#endif
}
Пример #5
0
void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
{
    Q_XCB_NOOP(connection());
    if (m_gc_window != window) {
        if (m_gc)
            Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));

        m_gc = xcb_generate_id(xcb_connection());
        Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));

        m_gc_window = window;
    }

    Q_XCB_NOOP(connection());
    xcb_image_shm_put(xcb_connection(),
                      window,
                      m_gc,
                      m_xcb_image,
                      m_shm_info,
                      source.x(),
                      source.y(),
                      target.x(),
                      target.y(),
                      source.width(),
                      source.height(),
                      false);
    Q_XCB_NOOP(connection());

    m_dirty = m_dirty | source;

    xcb_flush(xcb_connection());
    Q_XCB_NOOP(connection());
}
Пример #6
0
void QXcbWindow::setVisible(bool visible)
{
    xcb_wm_hints_t hints;
    if (visible) {
        if (widget()->isMinimized())
            xcb_wm_hints_set_iconic(&hints);
        else
            xcb_wm_hints_set_normal(&hints);
        xcb_set_wm_hints(xcb_connection(), m_window, &hints);
        Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
        connection()->sync();
    } else {
        Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));

        // send synthetic UnmapNotify event according to icccm 4.1.4
        xcb_unmap_notify_event_t event;
        event.response_type = XCB_UNMAP_NOTIFY;
        event.sequence = 0; // does this matter?
        event.event = m_screen->root();
        event.window = m_window;
        event.from_configure = false;
        Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
                                  XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));

        xcb_flush(xcb_connection());
    }
}
Пример #7
0
QXcbWindow::~QXcbWindow()
{
    delete m_context;
    if (m_screen->syncRequestSupported())
        Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
    Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
}
Пример #8
0
void QXcbConnection::initializeAllAtoms() {
    const char *names[QXcbAtom::NAtoms];
    const char *ptr = xcb_atomnames;

    int i = 0;
    while (*ptr) {
        names[i++] = ptr;
        while (*ptr)
            ++ptr;
        ++ptr;
    }

    Q_ASSERT(i == QXcbAtom::NPredefinedAtoms);

    QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
    settings_atom_name += m_displayName;
    names[i++] = settings_atom_name;

    xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms];

    Q_ASSERT(i == QXcbAtom::NAtoms);
    for (i = 0; i < QXcbAtom::NAtoms; ++i)
        cookies[i] = xcb_intern_atom(xcb_connection(), false, strlen(names[i]), names[i]);

    for (i = 0; i < QXcbAtom::NAtoms; ++i) {
        xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0);
        m_allAtoms[i] = reply->atom;
        free(reply);
    }
}
Пример #9
0
void QXcbCursor::setPos(const QPoint &pos)
{
    xcb_window_t root = 0;
    queryPointer(connection(), &root, 0);
    xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
    xcb_flush(xcb_connection());
}
Пример #10
0
void QXcbScreen::readXResources()
{
    int offset = 0;
    QByteArray resources;
    while(1) {
        xcb_get_property_reply_t *reply =
            xcb_get_property_reply(xcb_connection(),
                xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
                                 XCB_ATOM_RESOURCE_MANAGER,
                                 XCB_ATOM_STRING, offset/4, 8192), NULL);
        bool more = false;
        if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
            resources += QByteArray((const char *)xcb_get_property_value(reply), xcb_get_property_value_length(reply));
            offset += xcb_get_property_value_length(reply);
            more = reply->bytes_after != 0;
        }

        if (reply)
            free(reply);

        if (!more)
            break;
    }

    QList<QByteArray> split = resources.split('\n');
    for (int i = 0; i < split.size(); ++i) {
        const QByteArray &r = split.at(i);
        int value;
        if (xResource(r, "Xft.dpi:\t", &value))
            m_forcedDpi = value;
        else if (xResource(r, "Xft.hintstyle:\t", &value))
            m_hintStyle = QFontEngine::HintStyle(value);
    }
}
Пример #11
0
void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
{
    if (connection()->hasXRandr()) {
        xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(xcb_connection(),
            xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp), NULL);
        if (crtc) {
            m_geometry = QRect(crtc->x, crtc->y, crtc->width, crtc->height);
            m_availableGeometry = m_geometry;
            free(crtc);
        }
    }

    xcb_get_property_reply_t * workArea =
        xcb_get_property_reply(xcb_connection(),
            xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
                             atom(QXcbAtom::_NET_WORKAREA),
                             XCB_ATOM_CARDINAL, 0, 1024), NULL);

    if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) {
        // If workArea->value_len > 4, the remaining ones seem to be for virtual desktops.
        // But QScreen doesn't know about that concept.  In reality there could be a
        // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop.
        // But for now just assume the first 4 values give us the geometry of the
        // "work area", AKA "available geometry"
        uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea);
        QRect virtualAvailableGeometry(geom[0], geom[1], geom[2], geom[3]);
        // Take the intersection of the desktop's available geometry with this screen's geometry
        // to get the part of the available geometry which belongs to this screen.
        m_availableGeometry = m_geometry & virtualAvailableGeometry;
    }
    free(workArea);
}
Пример #12
0
void QXcbCursor::setPos(const QPoint &pos)
{
    const int dpr = int(m_screen->devicePixelRatio());
    xcb_window_t root = 0;
    queryPointer(connection(), &root, 0);
    xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x()*dpr, pos.y()*dpr);
    xcb_flush(xcb_connection());
}
Пример #13
0
void QXcbCursor::setPos(const QPoint &pos)
{
    const QPoint xPos = m_screen->mapToNative(pos);
    xcb_window_t root = 0;
    queryPointer(connection(), &root, 0);
    xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, xPos.x(), xPos.y());
    xcb_flush(xcb_connection());
}
Пример #14
0
void QXcbShmImage::destroy()
{
    Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
    xcb_image_destroy(m_xcb_image);
    shmdt(m_shm_info.shmaddr);
    shmctl(m_shm_info.shmid, IPC_RMID, 0);
    if (m_gc)
        Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
}
Пример #15
0
void QXcbWindow::updateSyncRequestCounter()
{
    if (m_screen->syncRequestSupported() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
        Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
        xcb_flush(xcb_connection());
        connection()->sync();

        m_syncValue.lo = 0;
        m_syncValue.hi = 0;
    }
}
Пример #16
0
QXcbConnection::QXcbConnection(const char *displayName)
    : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
#ifdef XCB_USE_DRI2
    , m_dri2_major(0)
    , m_dri2_minor(0)
    , m_dri2_support_probed(false)
    , m_has_support_for_dri2(false)
#endif
{
    int primaryScreen = 0;

#ifdef XCB_USE_XLIB
    Display *dpy = XOpenDisplay(m_displayName.constData());
    primaryScreen = DefaultScreen(dpy);
    m_connection = XGetXCBConnection(dpy);
    XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
    m_xlib_display = dpy;
#ifdef XCB_USE_EGL
    EGLDisplay eglDisplay = eglGetDisplay(dpy);
    m_egl_display = eglDisplay;
    EGLint major, minor;
    eglBindAPI(EGL_OPENGL_ES_API);
    m_has_egl = eglInitialize(eglDisplay,&major,&minor);
#endif //XCB_USE_EGL
#else
    m_connection = xcb_connect(m_displayName.constData(), &primaryScreen);

#endif //XCB_USE_XLIB
    m_setup = xcb_get_setup(xcb_connection());

    initializeAllAtoms();

    xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);

    int screenNumber = 0;
    while (it.rem) {
        m_screens << new QXcbScreen(this, it.data, screenNumber++);
        xcb_screen_next(&it);
    }

    m_keyboard = new QXcbKeyboard(this);

#ifdef XCB_USE_DRI2
    initializeDri2();
#endif

    QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
    connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));

    QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread());
    connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));

    sync();
}
Пример #17
0
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
    : QXcbObject(screen->connection())
    , m_gc(0)
    , m_gc_window(0)
{
    Q_XCB_NOOP(connection());
    m_xcb_image = xcb_image_create_native(xcb_connection(),
                                          size.width(),
                                          size.height(),
                                          XCB_IMAGE_FORMAT_Z_PIXMAP,
                                          depth,
                                          0,
                                          ~0,
                                          0);

    const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
    if (!segmentSize)
        return;

    int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
    if (id == -1)
        qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)",
                 errno, segmentSize, size.width(), size.height());
    else
        m_shm_info.shmid = id;
    m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
    m_shm_info.shmseg = xcb_generate_id(xcb_connection());

    const xcb_query_extension_reply_t *shm_reply = xcb_get_extension_data(xcb_connection(), &xcb_shm_id);
    bool shm_present = shm_reply != NULL && shm_reply->present;
    xcb_generic_error_t *error = NULL;
    if (shm_present)
        error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
    if (!shm_present || error) {
        free(error);

        shmdt(m_shm_info.shmaddr);
        shmctl(m_shm_info.shmid, IPC_RMID, 0);

        m_shm_info.shmaddr = 0;

        m_xcb_image->data = (uint8_t *)malloc(segmentSize);
    } else {
        if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
            qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed";
    }

    m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
Пример #18
0
void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
    QRect bounds = region.boundingRect();

    if (size().isEmpty() || !geometry().contains(bounds))
        return;

    Q_XCB_NOOP(connection());

    QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow());

    extern QWidgetData* qt_widget_data(QWidget *);
    QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft();

    QVector<QRect> rects = region.rects();
    for (int i = 0; i < rects.size(); ++i)
        m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset));

    Q_XCB_NOOP(connection());

    if (m_syncingResize) {
        xcb_flush(xcb_connection());
        connection()->sync();
        m_syncingResize = false;
        window->updateSyncRequestCounter();
    }
}
Пример #19
0
void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
{
    // in order of decreasing priority
    QVector<uint> windowTypes;

    Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));

    switch (type) {
    case Qt::Dialog:
    case Qt::Sheet:
        windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
        break;
    case Qt::Tool:
    case Qt::Drawer:
        windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
        break;
    case Qt::ToolTip:
        windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
        break;
    case Qt::SplashScreen:
        windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
        break;
    default:
        break;
    }

    if (flags & Qt::FramelessWindowHint)
        windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));

    windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));

    Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
                                   atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
                                   windowTypes.count(), windowTypes.constData()));
}
Пример #20
0
void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
    if (!m_image || m_image->size().isEmpty())
        return;

    QSize imageSize = m_image->size();

    QRegion clipped = region;
    clipped &= QRect(0, 0, window->width(), window->height());
    clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset);

    QRect bounds = clipped.boundingRect();

    if (bounds.isNull())
        return;

    Q_XCB_NOOP(connection());

    QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());

    QVector<QRect> rects = clipped.rects();
    for (int i = 0; i < rects.size(); ++i)
        m_image->put(platformWindow->xcb_window(), rects.at(i).topLeft(), rects.at(i).translated(offset));

    Q_XCB_NOOP(connection());

    if (m_syncingResize) {
        xcb_flush(xcb_connection());
        connection()->sync();
        m_syncingResize = false;
        platformWindow->updateSyncRequestCounter();
    }
}
Пример #21
0
void QXcbWindow::setGeometry(const QRect &rect)
{
    QPlatformWindow::setGeometry(rect);

    const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
    const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };

    Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
Пример #22
0
QByteArray QXcbConnection::atomName(xcb_atom_t atom)
{
    if (!atom)
        return QByteArray();

    xcb_generic_error_t *error = 0;
    xcb_get_atom_name_cookie_t cookie = Q_XCB_CALL(xcb_get_atom_name(xcb_connection(), atom));
    xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error);
    if (error) {
        qWarning() << "QXcbConnection::atomName: bad Atom" << atom;
        free(error);
    }
    if (reply) {
        QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply));
        free(reply);
        return result;
    }
    return QByteArray();
}
Пример #23
0
void QXcbShmImage::destroy()
{
    const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0;
    if (segmentSize && m_shm_info.shmaddr)
        Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));

    xcb_image_destroy(m_xcb_image);

    if (segmentSize) {
        if (m_shm_info.shmaddr) {
            shmdt(m_shm_info.shmaddr);
            shmctl(m_shm_info.shmid, IPC_RMID, 0);
        } else {
            free(m_xcb_image->data);
        }
    }

    if (m_gc)
        Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
}
Пример #24
0
void QXcbWindow::setWindowTitle(const QString &title)
{
    QByteArray ba = title.toUtf8();
    Q_XCB_CALL(xcb_change_property(xcb_connection(),
                                   XCB_PROP_MODE_REPLACE,
                                   m_window,
                                   atom(QXcbAtom::_NET_WM_NAME),
                                   atom(QXcbAtom::UTF8_STRING),
                                   8,
                                   ba.length(),
                                   ba.constData()));
}
Пример #25
0
QXcbConnection::~QXcbConnection()
{
    qDeleteAll(m_screens);

#ifdef XCB_USE_XLIB
    XCloseDisplay((Display *)m_xlib_display);
#else
    xcb_disconnect(xcb_connection());
#endif

    delete m_keyboard;
}
Пример #26
0
void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *event)
{
    Q_UNUSED(window);
    DEBUG() << "handleEnter" << window;

    xdnd_types.clear();

    int version = (int)(event->data.data32[1] >> 24);
    if (version > xdnd_version)
        return;

    xdnd_dragsource = event->data.data32[0];

    if (event->data.data32[1] & 1) {
        // get the types from XdndTypeList
        xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, xdnd_dragsource,
                                                            atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM,
                                                            0, xdnd_max_type);
        xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
        if (reply && reply->type != XCB_NONE && reply->format == 32) {
            int length = xcb_get_property_value_length(reply) / 4;
            if (length > xdnd_max_type)
                length = xdnd_max_type;

            xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
            for (int i = 0; i < length; ++i)
                xdnd_types.append(atoms[i]);
        }
        free(reply);
    } else {
        // get the types from the message
        for(int i = 2; i < 5; i++) {
            if (event->data.data32[i])
                xdnd_types.append(event->data.data32[i]);
        }
    }
    for(int i = 0; i < xdnd_types.length(); ++i)
        DEBUG() << "    " << connection()->atomName(xdnd_types.at(i));
}
Пример #27
0
void QXcbDrag::drop(const QMouseEvent *event)
{
    QBasicDrag::drop(event);

    if (!current_target)
        return;

    xcb_client_message_event_t drop;
    drop.response_type = XCB_CLIENT_MESSAGE;
    drop.window = current_target;
    drop.format = 32;
    drop.type = atom(QXcbAtom::XdndDrop);
    drop.data.data32[0] = connection()->clipboard()->owner();
    drop.data.data32[1] = 0; // flags
    drop.data.data32[2] = connection()->time();

    drop.data.data32[3] = 0;
    drop.data.data32[4] = currentDrag()->supportedActions();

    QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);

    if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
        w = 0;

    Transaction t = {
        connection()->time(),
        current_target,
        current_proxy_target,
        (w ? w->window() : 0),
//        current_embeddig_widget,
        currentDrag(),
        QTime::currentTime()
    };
    transactions.append(t);

    // timer is needed only for drops that came from other processes.
    if (!t.targetWindow && cleanup_timer == -1) {
        cleanup_timer = startTimer(XdndDropTransactionTimeout);
    }

    if (w) {
        handleDrop(w->window(), &drop);
    } else {
        xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
    }

    current_target = 0;
    current_proxy_target = 0;
    source_time = 0;
//    current_embedding_widget = 0;
}
Пример #28
0
QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{
    xcb_window_t root = m_screen->root;

    int x = p.x();
    int y = p.y();

    xcb_window_t parent = root;
    xcb_window_t child = root;

    do {
        xcb_translate_coordinates_cookie_t translate_cookie =
            xcb_translate_coordinates_unchecked(xcb_connection(), parent, child, x, y);

        xcb_translate_coordinates_reply_t *translate_reply =
            xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, NULL);

        if (!translate_reply) {
            return 0;
        }

        parent = child;
        child = translate_reply->child;
        x = translate_reply->dst_x;
        y = translate_reply->dst_y;

        free(translate_reply);

        if (!child || child == root)
            return 0;

        QPlatformWindow *platformWindow = connection()->platformWindowFromId(child);
        if (platformWindow)
            return platformWindow->window();
    } while (parent != child);

    return 0;
}
Пример #29
0
void QXcbDrag::startDrag()
{
    // #fixme enableEventFilter();

    init();

    xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(),
                            atom(QXcbAtom::XdndSelection), connection()->time());

    QStringList fmts = QXcbMime::formatsHelper(drag()->mimeData());
    for (int i = 0; i < fmts.size(); ++i) {
        QVector<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i));
        for (int j = 0; j < atoms.size(); ++j) {
            if (!drag_types.contains(atoms.at(j)))
                drag_types.append(atoms.at(j));
        }
    }
    if (drag_types.size() > 3)
        xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
                            atom(QXcbAtom::XdndTypelist),
                            XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
    QBasicDrag::startDrag();
}
Пример #30
0
QXcbCursor::~QXcbCursor()
{
    xcb_connection_t *conn = xcb_connection();

    if (m_gtkCursorThemeInitialized) {
        m_screen->xSettings()->removeCallbackForHandle(this);
    }

    if (!--cursorCount)
        xcb_close_font(conn, cursorFont);

    foreach (xcb_cursor_t cursor, m_cursorHash)
        xcb_free_cursor(conn, cursor);
}