⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qclipboard_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }    return false;}bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout){    QTime started = QTime::currentTime();    QTime now = started;    if (QAbstractEventDispatcher::instance()->inherits("QMotif")) {        if (waiting_for_data)            qFatal("QClipboard: internal error, qt_xclb_wait_for_event recursed");        waiting_for_data = true;        has_captured_event = false;        capture_event_win = win;        capture_event_type = type;        QApplication::EventFilter old_event_filter =            qApp->setEventFilter(qt_x11_clipboard_event_filter);        do {            if (XCheckTypedWindowEvent(display, win, type, event)) {                waiting_for_data = false;                qApp->setEventFilter(old_event_filter);                return true;            }            XSync(X11->display, false);            usleep(50000);            now = QTime::currentTime();            if (started > now)                        // crossed midnight                started = now;            QEventLoop::ProcessEventsFlags flags(QEventLoop::ExcludeUserInputEvents                                                 | QEventLoop::ExcludeSocketNotifiers                                                 | QEventLoop::WaitForMoreEvents                                                 | QEventLoop::X11ExcludeTimers);            QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();            eventDispatcher->processEvents(flags);            if (has_captured_event) {                waiting_for_data = false;                *event = captured_event;                qApp->setEventFilter(old_event_filter);                return true;            }        } while (started.msecsTo(now) < timeout);        waiting_for_data = false;        qApp->setEventFilter(old_event_filter);    } else {        do {            if (XCheckTypedWindowEvent(X11->display,win,type,event))                return true;            now = QTime::currentTime();            if ( started > now )			// crossed midnight                started = now;            XFlush(X11->display);            // sleep 50ms, so we don't use up CPU cycles all the time.            struct timeval usleep_tv;            usleep_tv.tv_sec = 0;            usleep_tv.tv_usec = 50000;            select(0, 0, 0, 0, &usleep_tv);        } while (started.msecsTo(now) < timeout);    }    return false;}static inline int maxSelectionIncr(Display *dpy){ return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; }bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deleteProperty,                                     QByteArray *buffer, int *size, Atom *type, int *format, bool nullterm){    int           maxsize = maxSelectionIncr(display);    ulong  bytes_left; // bytes_after    ulong  length;     // nitems    uchar *data;    Atom   dummy_type;    int    dummy_format;    int    r;    if (!type)                                // allow null args        type = &dummy_type;    if (!format)        format = &dummy_format;    // Don't read anything, just get the size of the property data    r = XGetWindowProperty(display, win, property, 0, 0, False,                            AnyPropertyType, type, format,                            &length, &bytes_left, &data);    if (r != Success || (type && *type == XNone)) {        buffer->resize(0);        return false;    }    XFree((char*)data);    int  offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;    VDEBUG("QClipboard: read_property(): initial property length: %d", proplen);    switch (*format) {    case 8:    default:        format_inc = sizeof(char) / 1;        break;    case 16:        format_inc = sizeof(short) / 2;        proplen *= sizeof(short) / 2;        break;    case 32:        format_inc = sizeof(long) / 4;        proplen *= sizeof(long) / 4;        break;    }    int newSize = proplen + (nullterm ? 1 : 0);    buffer->resize(newSize);    bool ok = (buffer->size() == newSize);    VDEBUG("QClipboard: read_property(): buffer resized to %d", buffer->size());    if (ok) {        // could allocate buffer        while (bytes_left) {            // more to read...            r = XGetWindowProperty(display, win, property, offset, maxsize/4,                                   False, AnyPropertyType, type, format,                                   &length, &bytes_left, &data);            if (r != Success || (type && *type == XNone))                break;            offset += length / (32 / *format);            length *= format_inc * (*format) / 8;            // Here we check if we get a buffer overflow and tries to            // recover -- this shouldn't normally happen, but it doesn't            // hurt to be defensive            if ((int)(buffer_offset + length) > buffer->size()) {                length = buffer->size() - buffer_offset;                // escape loop                bytes_left = 0;            }            memcpy(buffer->data() + buffer_offset, data, length);            buffer_offset += length;            XFree((char*)data);        }        if (*format == 8 && *type == ATOM(COMPOUND_TEXT)) {            // convert COMPOUND_TEXT to a multibyte string            XTextProperty textprop;            textprop.encoding = *type;            textprop.format = *format;            textprop.nitems = length;            textprop.value = (unsigned char *) buffer->data();            char **list_ret = 0;            int count;            if (XmbTextPropertyToTextList(display, &textprop, &list_ret,                                            &count) == Success &&                 count && list_ret) {                offset = strlen(list_ret[0]);                buffer->resize(offset + (nullterm ? 1 : 0));                memcpy(buffer->data(), list_ret[0], offset);            }            if (list_ret) XFreeStringList(list_ret);        }        // zero-terminate (for text)        if (nullterm)            buffer[buffer_offset] = '\0';    }    // correct size, not 0-term.    if (size)        *size = buffer_offset;    VDEBUG("QClipboard: read_property(): buffer size %d, buffer offset %d, offset %d",           buffer->size(), buffer_offset, offset);    if (deleteProperty)        XDeleteProperty(display, win, property);    XFlush(display);    return ok;}QByteArray QX11Data::clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm){    XEvent event;    QByteArray buf;    QByteArray tmp_buf;    bool alloc_error = false;    int  length;    int  offset = 0;    if (nbytes > 0) {        // Reserve buffer + zero-terminator (for text data)        // We want to complete the INCR transfer even if we cannot        // allocate more memory        buf.resize(nbytes+1);        alloc_error = buf.size() != nbytes+1;    }    for (;;) {        XFlush(display);        if (!clipboardWaitForEvent(win,PropertyNotify,&event,clipboard_timeout))            break;        if (event.xproperty.atom != property ||             event.xproperty.state != PropertyNewValue)            continue;        if (X11->clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0, false)) {            if (length == 0) {                // no more data, we're done                if (nullterm) {                    buf.resize(offset+1);                    buf[offset] = '\0';                } else {                    buf.resize(offset);                }                return buf;            } else if (!alloc_error) {                if (offset+length > (int)buf.size()) {                    buf.resize(offset+length+65535);                    if (buf.size() != offset+length+65535) {                        alloc_error = true;                        length = buf.size() - offset;                    }                }                memcpy(buf.data()+offset, tmp_buf.constData(), length);                tmp_buf.resize(0);                offset += length;            }        } else {            break;        }    }    // timed out ... create a new requestor window, otherwise the requestor    // could consider next request to be still part of this timed out request    delete requestor;    requestor = new QWidget(0);    requestor->setObjectName(QLatin1String("internal clipboard requestor"));    return QByteArray();}static Atom send_selection(QClipboardData *d, Atom target, Window window, Atom property,                           int format = 0, QByteArray data = QByteArray());static Atom send_targets_selection(QClipboardData *d, Window window, Atom property){    QStringList formats = QInternalMimeData::formatsHelper(d->source());    int atoms = formats.size();    if (formats.contains("image/ppm")) atoms++;    if (formats.contains("image/pbm")) atoms++;    if (formats.contains("text/plain")) atoms+=4;    VDEBUG("QClipboard: send_targets_selection(): data provides %d types, mapped to %d provided types", formats.size(), atoms);    // for 64 bit cleanness... XChangeProperty expects long* for data with format == 32    QByteArray data;    data.resize((atoms+3) * sizeof(long)); // plus TARGETS, MULTIPLE and TIMESTAMP    long *atarget = (long *) data.data();    int n = 0;    for (n = 0; n < formats.size(); ++n) {        VDEBUG("    original format %s", formats.at(n).toLatin1().data());        atarget[n] = X11->xdndStringToAtom(formats.at(n).toLatin1().data());    }    if (formats.contains("image/ppm"))        atarget[n++] = XA_PIXMAP;    if (formats.contains("image/pbm"))        atarget[n++] = XA_BITMAP;    if (formats.contains("text/plain")) {        atarget[n++] = ATOM(UTF8_STRING);        atarget[n++] = ATOM(TEXT);        atarget[n++] = ATOM(COMPOUND_TEXT);        atarget[n++] = XA_STRING;    }    atarget[n++] = ATOM(TARGETS);    atarget[n++] = ATOM(MULTIPLE);    atarget[n++] = ATOM(TIMESTAMP);#if defined(QCLIPBOARD_DEBUG_VERBOSE)    for (int index = 0; index < n; index++) {        VDEBUG("    atom %d: 0x%lx (%s)", index, atarget[index],               X11->xdndAtomToString(atarget[index]).data());    }#endif    XChangeProperty(X11->display, window, property, XA_ATOM, 32,                    PropModeReplace, (uchar *) data.data(), n);    return property;}static Atom send_string_selection(QClipboardData *d, Atom target, Window window, Atom property){    DEBUG("QClipboard: send_string_selection():\n"          "    property type %lx\n"          "    property name '%s'",          target, X11->xdndAtomToString(target).data());    if (target == ATOM(TEXT) || target == ATOM(COMPOUND_TEXT)) {        // the ICCCM states that TEXT and COMPOUND_TEXT are in the        // encoding of choice, so we choose the encoding of the locale        QByteArray data = d->source()->text().toLocal8Bit();        char *list[] = { data.data(), NULL };        XICCEncodingStyle style =            (target == ATOM(COMPOUND_TEXT)) ? XCompoundTextStyle : XStdICCTextStyle;        XTextProperty textprop;        if (list[0] != NULL            && XmbTextListToTextProperty(X11->display,                                         list, 1, style, &textprop) == Success) {            DEBUG("    textprop type %lx\n"                  "    textprop name '%s'\n"                  "    format %d\n"                  "    %ld items",                  textprop.encoding, X11->xdndAtomToString(textprop.encoding).data(),                  textprop.format, textprop.nitems);            int sz = sizeof_format(textprop.format);            data = QByteArray((const char *) textprop.value, textprop.nitems * sz);            XFree(textprop.value);            return send_selection(d, textprop.encoding, window, property, textprop.format, data);        }        return XNone;    }    Atom xtarget = XNone;    QByteArray data;    if (target == XA_STRING) {        // the ICCCM states that STRING is latin1 plus newline and tab        // see section 2.6.2        data = d->source()->text().toLatin1();        xtarget = XA_STRING;    } else if (target == ATOM(UTF8_STRING)) {        // proposed UTF8_STRING conversion type        data = d->source()->text().toUtf8();        xtarget = ATOM(UTF8_STRING);    }    if (xtarget == XNone) // should not happen        return XNone;    DEBUG("    format 8\n    %d bytes", data.size());    return send_selection(d, xtarget, window, property, 8, data);}static Atom send_pixmap_selection(QClipboardData *d, Atom target, Window window, Atom property){    QPixmap pm;    if (target == XA_PIXMAP) {        pm = qvariant_cast<QPixmap>(d->source()->imageData());    } else if (target == XA_BITMAP) {        pm = qvariant_cast<QPixmap>(d->source()->imageData());        QImage img = pm.toImage();        if (img.depth() != 1) {            img = img.convertToFormat(QImage::Format_MonoLSB);            pm = QPixmap::fromImage(img);        }    }    if (pm.isNull()) // should never happen        return XNone;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -