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

📄 qclipboard_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            int imulti = -1;            bool multi_writeback = false;            if (req->target == xa_multiple) {                QByteArray multi_data;                if (req->property == XNone                    || !X11->clipboardReadProperty(req->requestor, req->property, false, &multi_data,                                                   0, &multi_type, &multi_format, 0)                    || multi_format != 32) {                    // MULTIPLE property not formatted correctly                    XSendEvent(dpy, req->requestor, False, NoEventMask, &event);                    break;                }                nmulti = multi_data.size()/sizeof(*multi);                multi = new AtomPair[nmulti];                memcpy(multi,multi_data.data(),multi_data.size());                imulti = 0;            }            for (; imulti < nmulti; ++imulti) {                Atom target;                Atom property;                if (multi) {                    target = multi[imulti].target;                    property = multi[imulti].property;                } else {                    target = req->target;                    property = req->property;                    if (property == XNone) // obsolete client                        property = target;                }                Atom ret = XNone;                if (target == XNone || property == XNone) {                    ;                } else if (target == xa_timestamp) {                    if (d->timestamp != CurrentTime) {                        XChangeProperty(dpy, req->requestor, property, XA_INTEGER, 32,                                        PropModeReplace, (uchar *) &d->timestamp, 1);                        ret = property;                    } else {                        qWarning("QClipboard: Invalid data timestamp");                    }                } else if (target == xa_targets) {                    ret = send_targets_selection(d, req->requestor, property);                } else {                    ret = send_selection(d, target, req->requestor, property);                }                if (nmulti > 0) {                    if (ret == XNone) {                        multi[imulti].property = XNone;                        multi_writeback = true;                    }                } else {                    event.xselection.property = ret;                    break;                }            }            if (nmulti > 0) {                if (multi_writeback) {                    // according to ICCCM 2.6.2 says to put None back                    // into the original property on the requestor window                    XChangeProperty(dpy, req->requestor, req->property, multi_type, 32,                                    PropModeReplace, (uchar *) multi, nmulti * 2);                }                delete [] multi;                event.xselection.property = req->property;            }            // send selection notify to requestor            XSendEvent(dpy, req->requestor, False, NoEventMask, &event);            DEBUG("QClipboard: SelectionNotify to 0x%lx\n"                  "    property 0x%lx (%s)",                  req->requestor, event.xselection.property,                  X11->xdndAtomToString(event.xselection.property).data());        }        break;    }    return true;}QClipboardWatcher::QClipboardWatcher(QClipboard::Mode mode)    : QInternalMimeData(){    switch (mode) {    case QClipboard::Selection:        atom = XA_PRIMARY;        break;    case QClipboard::Clipboard:        atom = ATOM(CLIPBOARD);        break;    default:        qWarning("QClipboardWatcher: Internal error: Unsupported clipboard mode");        break;    }    setupOwner();}QClipboardWatcher::~QClipboardWatcher(){    if(selection_watcher == this)        selection_watcher = 0;    if(clipboard_watcher == this)        clipboard_watcher = 0;}bool QClipboardWatcher::empty() const{    Display *dpy = X11->display;    Window win = XGetSelectionOwner(dpy, atom);    if(win == requestor->internalWinId()) {        qWarning("QClipboardWatcher::empty: Internal error: Application owns the selection");        return true;    }    return win == XNone;}QStringList QClipboardWatcher::formats_sys() const{    if (empty())        return QStringList();    if (!formatList.count()) {        // get the list of targets from the current clipboard owner - we do this        // once so that multiple calls to this function don't require multiple        // server round trips...        format_atoms = getDataInFormat(ATOM(TARGETS));        if (format_atoms.size() > 0) {            Atom *targets = (Atom *) format_atoms.data();            int size = format_atoms.size() / sizeof(Atom);            for (int i = 0; i < size; ++i) {                if (targets[i] == 0)                    continue;                QStringList formatsForAtom = X11->xdndMimeFormatsForAtom(targets[i]);                for (int j = 0; j < formatsForAtom.size(); ++j) {                    if (!formatList.contains(formatsForAtom.at(j)))                        formatList.append(formatsForAtom.at(j));                }                VDEBUG("    format: %s", X11->xdndAtomToString(targets[i]).data());                VDEBUG("    data:\n%s\n", getDataInFormat(targets[i]).data());            }            DEBUG("QClipboardWatcher::format: %d formats available", formatList.count());        }    }    return formatList;}bool QClipboardWatcher::hasFormat_sys(const QString &format) const{    QStringList list = formats();    return list.contains(format);}QVariant QClipboardWatcher::retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const{    if (fmt.isEmpty() || empty())        return QByteArray();    (void)formats(); // trigger update of format list    DEBUG("QClipboardWatcher::data: fetching format '%s'", fmt.toLatin1().data());    QList<Atom> atoms;    Atom *targets = (Atom *) format_atoms.data();    int size = format_atoms.size() / sizeof(Atom);    for (int i = 0; i < size; ++i)        atoms.append(targets[i]);    QByteArray encoding;    Atom fmtatom = X11->xdndMimeAtomForFormat(fmt, requestedType, atoms, &encoding);    if (fmtatom == 0)        return QVariant();    return X11->xdndMimeConvertToFormat(fmtatom, getDataInFormat(fmtatom), fmt, requestedType, encoding);}QByteArray QClipboardWatcher::getDataInFormat(Atom fmtatom) const{    QByteArray buf;    Display *dpy = X11->display;    requestor->createWinId();    Window   win = requestor->internalWinId();    Q_ASSERT(requestor->testAttribute(Qt::WA_WState_Created));    DEBUG("QClipboardWatcher::getDataInFormat: selection '%s' format '%s'",          X11->xdndAtomToString(atom).data(), X11->xdndAtomToString(fmtatom).data());    XSelectInput(dpy, win, NoEventMask); // don't listen for any events    XDeleteProperty(dpy, win, ATOM(_QT_SELECTION));    XConvertSelection(dpy, atom, fmtatom, ATOM(_QT_SELECTION), win, X11->time);    XSync(dpy, false);    VDEBUG("QClipboardWatcher::getDataInFormat: waiting for SelectionNotify event");    XEvent xevent;    if (!X11->clipboardWaitForEvent(win,SelectionNotify,&xevent,clipboard_timeout) ||         xevent.xselection.property == XNone) {        DEBUG("QClipboardWatcher::getDataInFormat: format not available");        return buf;    }    VDEBUG("QClipboardWatcher::getDataInFormat: fetching data...");    Atom   type;    XSelectInput(dpy, win, PropertyChangeMask);    if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0, false)) {        if (type == ATOM(INCR)) {            int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;            buf = X11->clipboardReadIncrementalProperty(win, ATOM(_QT_SELECTION), nbytes, false);        }    }    XSelectInput(dpy, win, NoEventMask);    DEBUG("QClipboardWatcher::getDataInFormat: %d bytes received", buf.size());    return buf;}const QMimeData* QClipboard::mimeData(Mode mode) const{    QClipboardData *d = 0;    switch (mode) {    case Selection:        d = selectionData();        break;    case Clipboard:        d = clipboardData();        break;    default:        qWarning("QClipboard::mimeData: unsupported mode '%d'", mode);        return 0;    }    if (! d->source() && ! timer_event_clear) {        if (mode == Selection) {            if (! selection_watcher)                selection_watcher = new QClipboardWatcher(mode);            d->setSource(selection_watcher);        } else {            if (! clipboard_watcher)                clipboard_watcher = new QClipboardWatcher(mode);            d->setSource(clipboard_watcher);        }        if (! timer_id) {            // start a zero timer - we will clear cached data when the timer            // times out, which will be the next time we hit the event loop...            // that way, the data is cached long enough for calls within a single            // loop/function, but the data doesn't linger around in case the selection            // changes            QClipboard *that = ((QClipboard *) this);            timer_id = that->startTimer(0);        }    }    return d->source();}void QClipboard::setMimeData(QMimeData* src, Mode mode){    Atom atom, sentinel_atom;    QClipboardData *d;    switch (mode) {    case Selection:        atom = XA_PRIMARY;        sentinel_atom = ATOM(_QT_SELECTION_SENTINEL);        d = selectionData();        break;    case Clipboard:        atom = ATOM(CLIPBOARD);        sentinel_atom = ATOM(_QT_CLIPBOARD_SENTINEL);        d = clipboardData();        break;    default:        qWarning("QClipboard::setMimeData: unsupported mode '%d'", mode);        return;    }    Display *dpy = X11->display;    Window newOwner;    if (! src) { // no data, clear clipboard contents        newOwner = XNone;        d->clear();    } else {        setupOwner();        newOwner = owner->internalWinId();        d->setSource(src);        d->timestamp = X11->time;    }    Window prevOwner = XGetSelectionOwner(dpy, atom);    // use X11->time, since d->timestamp == CurrentTime when clearing    XSetSelectionOwner(dpy, atom, newOwner, X11->time);    if (mode == Selection)        emitChanged(QClipboard::Selection);    else        emitChanged(QClipboard::Clipboard);    if (XGetSelectionOwner(dpy, atom) != newOwner) {        qWarning("QClipboard::setData: Cannot set X11 selection owner for %s",                 X11->xdndAtomToString(atom).data());        d->clear();        return;    }    // Signal to other Qt processes that the selection has changed    Window owners[2];    owners[0] = newOwner;    owners[1] = prevOwner;    XChangeProperty(dpy, QApplication::desktop()->screen(0)->internalWinId(),                     sentinel_atom, XA_WINDOW, 32, PropModeReplace,                     (unsigned char*)&owners, 2);}/*  Called by the main event loop in qapplication_x11.cpp when the  _QT_SELECTION_SENTINEL property has been changed (i.e. when some Qt  process has performed QClipboard::setData(). If it returns true, the  QClipBoard dataChanged() signal should be emitted.*/bool qt_check_selection_sentinel(){    bool doIt = true;    if (owner) {        /*          Since the X selection mechanism cannot give any signal when          the selection has changed, we emulate it (for Qt processes) here.          The notification should be ignored in case of either          a) This is the process that did setData (because setData()          then has already emitted dataChanged())          b) This is the process that owned the selection when dataChanged()          was called (because we have then received a SelectionClear event,          and have already emitted dataChanged() as a result of that)        */        unsigned char *retval;        Atom actualType;        int actualFormat;        ulong nitems;        ulong bytesLeft;        if (XGetWindowProperty(X11->display,                               QApplication::desktop()->screen(0)->internalWinId(),                               ATOM(_QT_SELECTION_SENTINEL), 0, 2, False, XA_WINDOW,                               &actualType, &actualFormat, &nitems,                               &bytesLeft, &retval) == Success) {            Window *owners = (Window *)retval;            if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {                Window win = owner->internalWinId();                if (owners[0] == win || owners[1] == win)                    doIt = false;            }            XFree(owners);        }    }    if (doIt) {        if (waiting_for_data) {            pending_selection_changed = true;            if (! pending_timer_id)                pending_timer_id = QApplication::clipboard()->startTimer(0);            doIt = false;        } else {            selectionData()->clear();        }    }    return doIt;}bool qt_check_clipboard_sentinel(){    bool doIt = true;    if (owner) {        unsigned char *retval;        Atom actualType;        int actualFormat;        unsigned long nitems, bytesLeft;        if (XGetWindowProperty(X11->display,                               QApplication::desktop()->screen(0)->internalWinId(),                               ATOM(_QT_CLIPBOARD_SENTINEL), 0, 2, False, XA_WINDOW,                               &actualType, &actualFormat, &nitems, &bytesLeft,                               &retval) == Success) {            Window *owners = (Window *)retval;            if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {                Window win = owner->internalWinId();                if (owners[0] == win || owners[1] == win)                    doIt = false;            }            XFree(owners);        }    }    if (doIt) {        if (waiting_for_data) {            pending_clipboard_changed = true;            if (! pending_timer_id)                pending_timer_id = QApplication::clipboard()->startTimer(0);            doIt = false;        } else {            clipboardData()->clear();        }    }    return doIt;}#endif // QT_NO_CLIPBOARD

⌨️ 快捷键说明

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