Exemplo n.º 1
0
void QClipboard::setMimeData(QMimeData* src, Mode mode)
{
    if (mode != Clipboard) return;

    QClipboardData *d = clipboardData();

    /* Propagate text data to other QWSClients */

    QString newText;
    if( src != 0 )
	newText = src->text();
    QString oldText;
    if( d->source() != 0 )
	oldText = d->source()->text();

    d->setSource(src);

    if( oldText != newText ) {
	if( d->source() == 0 ) {
	    qwsSetClipboardText( QString() );
	} else {
	    qwsSetClipboardText( d->source()->text() );
	}
    }

    emitChanged(QClipboard::Clipboard);
}
Exemplo n.º 2
0
void QClipboard::setMimeData(QMimeData *src, Mode mode)
{
    if (mode != Clipboard) {
        delete src;
        return;
    }

    QClipboardData *d = clipboardData();

    if (!(d->iData && d->iData->mimeData() == src)) {
        d->releaseIData();
        d->iData = new QOleDataObject(src);
    }

    if (OleSetClipboard(d->iData) != S_OK) {
        d->releaseIData();
        qErrnoWarning("QClipboard::setMimeData: Failed to set data on clipboard");
        return;
    }
#if defined(Q_OS_WINCE)
    // As WinCE does not support notifications we send the signal here
    // We will get no event when the clipboard changes outside...
    emit dataChanged();
    emit changed(Clipboard);
#endif
}
Exemplo n.º 3
0
ClipboardDialog::ClipboardDialog(QWidget *parent)
    : QDialog(parent)
{
    init();

    const QMimeData *clipData = clipboardData();
    if (clipData)
        setData( cloneData(*clipData) );
}
Exemplo n.º 4
0
bool QClipboard::ownsMode(Mode mode) const
{
    if (mode == Clipboard)
        return clipboardData()->timestamp != CurrentTime;
    else if(mode == Selection)
        return selectionData()->timestamp != CurrentTime;
    else
        return false;
}
Exemplo n.º 5
0
bool QClipboard::ownsMode(Mode mode) const
{
    if (mode == Clipboard) {
        QClipboardData *d = clipboardData();
        return d->iData && OleIsCurrentClipboard(d->iData) == S_OK;

    } else {
        return false;
    }
}
Exemplo n.º 6
0
void QClipboard::connectNotify(const char *signal)
{
    if (qstrcmp(signal,SIGNAL(dataChanged())) == 0) {
        // ensure we are up and running but block signals so the dataChange signal
        // is not emitted while being connected to.
        bool blocked = blockSignals(true);
        QClipboardData *d = clipboardData();
        blockSignals(blocked);
        Q_UNUSED(d);
    }
}
Exemplo n.º 7
0
const QMimeData *QClipboard::mimeData(Mode mode) const
{
    if (mode != Clipboard)
        return 0;

    QClipboardData *data = clipboardData();
    // sort cut for local copy / paste
    if (ownsClipboard() && data->iData->mimeData())
        return data->iData->mimeData();
    return &data->watcher;
}
Exemplo n.º 8
0
QByteArray ScriptableProxyHelper::getClipboardData(const QString &mime, QClipboard::Mode mode)
{
    INVOKE(getClipboardData(mime, mode));
    const QMimeData *data = clipboardData(mode);
    if (!data)
        return QByteArray();

    if (mime == "?")
        return data->formats().join("\n").toUtf8() + '\n';

    return cloneData(*data, QStringList(mime)).value(mime).toByteArray();
}
Exemplo n.º 9
0
bool qt_xfixes_clipboard_changed(Window clipboardOwner, Time timestamp)
{
    QClipboardData *d = clipboardData();
#ifdef QCLIPBOARD_DEBUG
    DEBUG("qt_xfixes_clipboard_changed: owner = %u; clipboardOwner = %u; internal timestamp = %u; external timestamp = %u",
          (unsigned int)(owner ? (int)owner->internalWinId() : 0), (unsigned int)clipboardOwner,
          (unsigned int)(d ? d->timestamp : 0), (unsigned int)timestamp);
#endif
    if (!owner || (clipboardOwner && clipboardOwner != owner->internalWinId()) ||
        (!clipboardOwner && (d->timestamp == CurrentTime || d->timestamp < timestamp)))
        return qt_check_clipboard_sentinel();
    return false;
}
Exemplo n.º 10
0
bool QClipboard::ownsMode(Mode mode) const
{
    if (mode == Clipboard) {
        QClipboardData *d = clipboardData();
#if !defined(Q_OS_WINCE)
        return d->iData && OleIsCurrentClipboard(d->iData) == S_OK;
#else
        return d->iData && GetClipboardOwner() == d->clipBoardViewer->internalWinId();
#endif
    } else {
        return false;
    }
}
Exemplo n.º 11
0
void QClipboard::clear(Mode mode)
{
    if (mode != Clipboard) return;

    QClipboardData *d = clipboardData();

    d->releaseIData();

    if (OleSetClipboard(0) != S_OK) {
        qErrnoWarning("QClipboard::clear: Failed to clear data on clipboard");
        return;
    }
}
Exemplo n.º 12
0
bool QClipboard::event(QEvent *e)
{
    if (e->type() != QEvent::Clipboard)
        return QObject::event(e);

    QClipboardData *d = clipboardData();

    MSG *m = (MSG *)((QClipboardEvent*)e)->data();
    if (!m) {
        // this is sent to render all formats at app shut down
        if (ownsClipboard()) {
            OleFlushClipboard();
            d->releaseIData();
        }
        return true;
    }

    bool propagate = false;

    if (m->message == WM_CHANGECBCHAIN) {
        if ((HWND)m->wParam == d->nextClipboardViewer)
            d->nextClipboardViewer = (HWND)m->lParam;
        else
            propagate = true;
    } else if (m->message == WM_DRAWCLIPBOARD) {
        emitChanged(QClipboard::Clipboard);
        if (!ownsClipboard() && d->iData)
            // clean up the clipboard object if we no longer own the clipboard
            d->releaseIData();
        propagate = true;
    }
    if (propagate && d->nextClipboardViewer) {
        if (ptrIsHungAppWindow == 0) {
            QSystemLibrary library(QLatin1String("User32"));
            ptrIsHungAppWindow = (PtrIsHungAppWindow)library.resolve("IsHungAppWindow");
        }
        if (ptrIsHungAppWindow && ptrIsHungAppWindow(d->nextClipboardViewer)) {
            qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO);
        } else if (isProcessBeingDebugged(d->nextClipboardViewer)) {
            // Also refuse if the process is being debugged, specifically, if it is
            // displaying a runtime assert, which is not caught by isHungAppWindow().
            qWarning("%s: Cowardly refusing to send clipboard message to application under debugger...", Q_FUNC_INFO);
        } else {
            SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam);
        }
    }

    return true;
}
Exemplo n.º 13
0
const QMimeData* QClipboard::mimeData(Mode mode) const
{
    if (mode != Clipboard) return 0;

    QClipboardData *d = clipboardData();
    // Try and get data from QWSProperty if no mime data has been set on us.
    if( !d->source() ) {
	QString t = qwsClipboardText();
	if( !t.isEmpty() ) {
	    QMimeData* nd = new QMimeData;
	    nd->setText( t );
	    d->setSource( nd );
	}
    }
    return d->source();
}
Exemplo n.º 14
0
void QClipboard::setMimeData(QMimeData *src, Mode mode)
{
    if (mode != Clipboard)
        return;
    QClipboardData *d = clipboardData();

    if (!(d->iData && d->iData->mimeData() == src)) {
        d->releaseIData();
        d->iData = new QOleDataObject(src);
    }

    if (OleSetClipboard(d->iData) != S_OK) {
        d->releaseIData();
        qErrnoWarning("QClipboard::setMimeData: Failed to set data on clipboard");
        return;
    }
}
Exemplo n.º 15
0
void QClipboard::clear(Mode mode)
{
    if (mode != Clipboard) return;

    QClipboardData *d = clipboardData();

    d->releaseIData();

    if (OleSetClipboard(0) != S_OK) {
        qErrnoWarning("QClipboard::clear: Failed to clear data on clipboard");
        return;
    }
#if defined(Q_OS_WINCE)
    // As WinCE does not support notifications we send the signal here
    // We will get no event when the clipboard changes outside...
    emit dataChanged();
    emit changed(Clipboard);
#endif
}
Exemplo n.º 16
0
    void synchronize()
    {
        if (m_syncTimer.isActive())
            return;

        if ( m_syncTo == QClipboard::Selection && isSelectionIncomplete() ) {
            m_syncTimer.start();
            return;
        }

        const QVariantMap &sourceData =
                (m_syncTo == QClipboard::Clipboard) ? m_selectionData : m_clipboardData;
        if ( !sourceData.isEmpty() ) {
            const QMimeData *data = clipboardData(m_syncTo);
            if  ( !data || sourceData != cloneData(*data, sourceData.keys()) )
                setClipboardData(sourceData, m_syncTo);
        }

    }
Exemplo n.º 17
0
const QMimeData* QClipboard::mimeData(Mode mode) const
{
    if (mode != Clipboard) return 0;
    QClipboardData *d = clipboardData();
    bool dataExists(false);
    if (d)
    {
        TRAPD(err,{
            RFs fs = qt_s60GetRFs();
            CClipboard* cb = CClipboard::NewForReadingLC(fs);
            Q_ASSERT(cb);
            //stream for qt
            RStoreReadStream stream;
            TStreamId stid = (cb->StreamDictionary()).At(KQtCbDataStream);
            if (stid != 0) {
                stream.OpenLC(cb->Store(),stid);
                QT_TRYCATCH_LEAVING(readFromStreamLX(d->source(),stream));
                CleanupStack::PopAndDestroy(&stream);
                dataExists = true;
            }
            else {
                //symbian clipboard
                RStoreReadStream symbianStream;
                TStreamId symbianStId = (cb->StreamDictionary()).At(KClipboardUidTypePlainText);
                if (symbianStId != 0) {
                    symbianStream.OpenLC(cb->Store(), symbianStId);
                    QT_TRYCATCH_LEAVING(readSymbianStoreLX(d->source(), cb));
                    CleanupStack::PopAndDestroy(&symbianStream);
                    dataExists = true;
                }
            }
            CleanupStack::PopAndDestroy(cb);
        });
        if (err != KErrNone){
            qDebug()<< "clipboard is empty/err: " << err;
        }

        if (dataExists) {
            return d->source();
        }
    }
Exemplo n.º 18
0
bool QClipboard::event(QEvent *e)
{
    static bool recursionWatch = false;
    if (e->type() != QEvent::Clipboard || recursionWatch)
        return QObject::event(e);

    recursionWatch = true;
    QWSPropertyNotifyEvent *event = (QWSPropertyNotifyEvent *)(((QClipboardEvent *)e)->data());
    if (event && event->simpleData.state == QWSPropertyNotifyEvent::PropertyNewValue) {
	QClipboardData *d = clipboardData();
	QString t = qwsClipboardText();
	if( (d->source() == 0 && !t.isEmpty()) || (d->source() != 0 && d->source()->text() != t) ) {
	    if( !d->source() )
		d->setSource(new QMimeData);
	    d->source()->setText( t );
	    emitChanged(QClipboard::Clipboard);
	}
    }

    recursionWatch = false;
    return true;
}
const QMimeData* QClipboard::mimeData(Mode mode) const
{
    if (mode != Clipboard) return 0;
    QClipboardData *d = clipboardData();
    if (d)
    {
        TRAPD(err,{
            RFs fs = qt_s60GetRFs();
            CClipboard* cb = CClipboard::NewForReadingLC(fs);
            Q_ASSERT(cb);
            RStoreReadStream stream;
            TStreamId stid = (cb->StreamDictionary()).At(KQtCbDataStream);
            stream.OpenLC(cb->Store(),stid);
            QT_TRYCATCH_LEAVING(readFromStreamLX(d->source(),stream));
            CleanupStack::PopAndDestroy(2,cb);
            return d->source();
        });
        if (err != KErrNone){
            qDebug()<< "clipboard is empty/err: " << err;
        }

    }
Exemplo n.º 20
0
void ClipboardSingleton::clipboardChanged()
{
    QVariant data;
    ClipboardType type;

    clipboardData(data, type);

    clipboardQueue_.append(ClipboardPair(data, type));

    // remove one element if needed
    if (clipboardQueue_.count() > ::MAX_CLIPBOARD_QUEUE)
    {
        clipboardQueue_.dequeue();
    }

    // do not store clipboard data to database
    /*if (type != NONE)
    {
        database::databasequery::StoreClipboardQuery query(data, type);
        query.execute();
    }*/
}
Exemplo n.º 21
0
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();
}
Exemplo n.º 22
0
bool QClipboard::event(QEvent *e)
{
    if (e->type() != QEvent::Clipboard)
        return QObject::event(e);

    QClipboardData *d = clipboardData();

    MSG *m = (MSG *)((QClipboardEvent*)e)->data();
    if (!m) {
        // this is sent to render all formats at app shut down
        if (ownsClipboard()) {
            OleFlushClipboard();
            d->releaseIData();
        }
        return true;
    }

    bool propagate = false;

    if (m->message == WM_CHANGECBCHAIN) {
        if ((HWND)m->wParam == d->nextClipboardViewer)
            d->nextClipboardViewer = (HWND)m->lParam;
        else
            propagate = true;
    } else if (m->message == WM_DRAWCLIPBOARD) {
        emitChanged(QClipboard::Clipboard);
        if (!ownsClipboard() && d->iData)
            // clean up the clipboard object if we no longer own the clipboard
            d->releaseIData();
        propagate = true;
    }

    if (propagate && d->nextClipboardViewer) {
        SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam);
    }

    return true;
}
Exemplo n.º 23
0
bool qt_check_clipboard_sentinel()
{
    bool doIt = true;
    if (owner && !X11->use_xfixes) {
        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;
}
Exemplo n.º 24
0
ClipboardDialog::ClipboardDialog(const ClipboardItemPtr &item, QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ClipboardDialog)
    , m_item(item)
{
    ui->setupUi(this);

    setWindowIcon( ConfigurationManager::instance()->iconFactory()->appIcon() );

    QVariantMap data;
    if ( m_item.isNull() ) {
        const QMimeData *clipData = clipboardData();
        if (clipData)
            data = cloneData(*clipData);
    } else {
        setWindowTitle( tr("CopyQ Item Content") );
        data = item->data();
    }

    // Show only data that can be displayed.
    foreach ( const QString &mime, data.keys() ) {
        if ( data[mime].canConvert<QByteArray>() && mime != mimeOwner ) {
            m_data.insert(mime, data[mime]);
            ui->listWidgetFormats->addItem(mime);
        }
    }

    ui->horizontalLayout->setStretchFactor(1, 1);
    ui->listWidgetFormats->setCurrentRow(0);

    ConfigurationManager::instance()->registerWindowGeometry(this);

    ui->actionRemove_Format->setIcon( getIcon("list-remove", IconRemove) );
    ui->actionRemove_Format->setShortcut(shortcutToRemove());
    ui->listWidgetFormats->addAction(ui->actionRemove_Format);
}
Exemplo n.º 25
0
QByteArray clipboardOwnerData(ClipboardMode mode)
{
    const auto data = clipboardData(mode);
    return data ? data->data(mimeOwner) : QByteArray();
}
Exemplo n.º 26
0
void ClipboardMonitor::checkClipboard(QClipboard::Mode mode)
{
#ifdef COPYQ_WS_X11
    m_x11->cancelSynchronization();
#endif

    // Check clipboard after interval because someone is updating it very quickly.
    bool needToWait = m_updateTimer->isActive();
    if (mode == QClipboard::Clipboard)
        m_needCheckClipboard = needToWait;
#ifdef COPYQ_WS_X11
    else if (mode == QClipboard::Selection)
        m_needCheckSelection = needToWait;
#endif
    else
        return;

    m_updateTimer->start();
    if (needToWait)
        return;

#ifdef COPYQ_WS_X11
    if ( mode == QClipboard::Selection && m_x11->isSelectionIncomplete() )
        return;
    if ( m_x11->maybeResetClipboard(mode) )
        return;
#endif

    COPYQ_LOG( QString("Checking for new %1 content.")
               .arg(mode == QClipboard::Clipboard ? "clipboard" : "selection") );

    // get clipboard data
    const QMimeData *data = clipboardData(mode);

    // data retrieved?
    if (!data) {
        log( tr("Cannot access clipboard data!"), LogError );
        return;
    }

    // clone only mime types defined by user
#if defined(Q_OS_MAC)
    //  On OS X, when you copy files in Finder, etc. you get:
    //  - The file name(s) (not paths) as plain text
    //  - The file URI(s)
    //  - The icon (not thumbnail) for the type of item you have in various image formants
    // We really only want the URI list, so throw the rest away
    QStringList formats = m_formats;
    if (data->formats().contains(mimeUriList) && formats.contains(mimeUriList)) {
        formats = QStringList() << mimeUriList;
    }
    QVariantMap data2( cloneData(*data, formats) );
#else
    QVariantMap data2( cloneData(*data, m_formats) );
#endif

    // add window title of clipboard owner
    if ( !data2.contains(mimeOwner) && !data2.contains(mimeWindowTitle) ) {
        PlatformPtr platform = createPlatformNativeInterface();
        PlatformWindowPtr currentWindow = platform->getCurrentWindow();
        if (currentWindow)
            data2.insert( mimeWindowTitle, currentWindow->getTitle().toUtf8() );
    }

#ifdef COPYQ_WS_X11
    m_x11->setData(mode, data2);

    if (mode == QClipboard::Clipboard) {
        if ( !ownsClipboardData(data2) && m_x11->synchronize(QClipboard::Selection) )
            m_needCheckSelection = false;
        clipboardChanged(data2);
    } else {
        data2.insert(mimeClipboardMode, "selection");
        if ( !ownsClipboardData(data2) && m_x11->synchronize(QClipboard::Clipboard) )
            m_needCheckClipboard = false;
        if ( m_x11->hasCheckSelection() )
            clipboardChanged(data2);
    }
#else /* !COPYQ_WS_X11 */
    clipboardChanged(data2);
#endif
}
Exemplo n.º 27
0
QVariantMap DummyClipboard::data(ClipboardMode mode, const QStringList &formats) const
{
    const QMimeData *data = clipboardData(mode);
    return data ? cloneData(*data, formats) : QVariantMap();
}
Exemplo n.º 28
0
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);
}
Exemplo n.º 29
0
bool QClipboard::event(QEvent *e)
{
    if (e->type() == QEvent::Timer) {
        QTimerEvent *te = (QTimerEvent *) e;

        if (waiting_for_data) // should never happen
            return false;

        if (te->timerId() == timer_id) {
            killTimer(timer_id);
            timer_id = 0;

            timer_event_clear = true;
            if (selection_watcher) // clear selection
                selectionData()->clear();
            if (clipboard_watcher) // clear clipboard
                clipboardData()->clear();
            timer_event_clear = false;

            return true;
        } else if (te->timerId() == pending_timer_id) {
            // I hate klipper
            killTimer(pending_timer_id);
            pending_timer_id = 0;

            if (pending_clipboard_changed) {
                pending_clipboard_changed = false;
                clipboardData()->clear();
                emitChanged(QClipboard::Clipboard);
            }
            if (pending_selection_changed) {
                pending_selection_changed = false;
                selectionData()->clear();
                emitChanged(QClipboard::Selection);
            }

            return true;
        } else if (te->timerId() == incr_timer_id) {
            killTimer(incr_timer_id);
            incr_timer_id = 0;

            qt_xclb_incr_timeout();

            return true;
        } else {
            return QObject::event(e);
        }
    } else if (e->type() != QEvent::Clipboard) {
        return QObject::event(e);
    }

    XEvent *xevent = (XEvent *)(((QClipboardEvent *)e)->data());
    Display *dpy = X11->display;

    if (!xevent) {
        // That means application exits and we need to give clipboard
        // content to the clipboard manager.
        // First we check if there is a clipboard manager.
        if (XGetSelectionOwner(X11->display, ATOM(CLIPBOARD_MANAGER)) == XNone
            || !owner)
            return true;

        Window ownerId = owner->internalWinId();
        Q_ASSERT(ownerId);
        // we delete the property so the manager saves all TARGETS.
        XDeleteProperty(X11->display, ownerId, ATOM(_QT_SELECTION));
        XConvertSelection(X11->display, ATOM(CLIPBOARD_MANAGER), ATOM(SAVE_TARGETS),
                          ATOM(_QT_SELECTION), ownerId, X11->time);
        XSync(dpy, false);

        XEvent event;
        // waiting until the clipboard manager fetches the content.
        if (!X11->clipboardWaitForEvent(ownerId, SelectionNotify, &event, 10000)) {
            qWarning("QClipboard: Unable to receive an event from the "
                     "clipboard manager in a reasonable time");
        }

        return true;
    }

    switch (xevent->type) {

    case SelectionClear:
        // new selection owner
        if (xevent->xselectionclear.selection == XA_PRIMARY) {
            QClipboardData *d = selectionData();

            // ignore the event if it was generated before we gained selection ownership
            if (d->timestamp != CurrentTime && xevent->xselectionclear.time <= d->timestamp)
                break;

            DEBUG("QClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
                  XGetSelectionOwner(dpy, XA_PRIMARY),
                  xevent->xselectionclear.time, d->timestamp);

            if (! waiting_for_data) {
                d->clear();
                emitChanged(QClipboard::Selection);
            } else {
                pending_selection_changed = true;
                if (! pending_timer_id)
                    pending_timer_id = QApplication::clipboard()->startTimer(0);
            }
        } else if (xevent->xselectionclear.selection == ATOM(CLIPBOARD)) {
            QClipboardData *d = clipboardData();

            // ignore the event if it was generated before we gained selection ownership
            if (d->timestamp != CurrentTime && xevent->xselectionclear.time <= d->timestamp)
                break;

            DEBUG("QClipboard: new clipboard owner 0x%lx at time %lx (%lx)",
                  XGetSelectionOwner(dpy, ATOM(CLIPBOARD)),
                  xevent->xselectionclear.time, d->timestamp);

            if (! waiting_for_data) {
                d->clear();
                emitChanged(QClipboard::Clipboard);
            } else {
                pending_clipboard_changed = true;
                if (! pending_timer_id)
                    pending_timer_id = QApplication::clipboard()->startTimer(0);
            }
        } else {
            qWarning("QClipboard: Unknown SelectionClear event received");
            return false;
        }
        break;

    case SelectionNotify:
        /*
          Something has delivered data to us, but this was not caught
          by QClipboardWatcher::getDataInFormat()

          Just skip the event to prevent Bad Things (tm) from
          happening later on...
        */
        break;

    case SelectionRequest:
        {
            // someone wants our data
            XSelectionRequestEvent *req = &xevent->xselectionrequest;

            if (requestor && req->requestor == requestor->internalWinId())
                break;

            XEvent event;
            event.xselection.type      = SelectionNotify;
            event.xselection.display   = req->display;
            event.xselection.requestor = req->requestor;
            event.xselection.selection = req->selection;
            event.xselection.target    = req->target;
            event.xselection.property  = XNone;
            event.xselection.time      = req->time;

            DEBUG("QClipboard: SelectionRequest from %lx\n"
                  "    selection 0x%lx (%s) target 0x%lx (%s)",
                  req->requestor,
                  req->selection,
                  X11->xdndAtomToString(req->selection).data(),
                  req->target,
                  X11->xdndAtomToString(req->target).data());

            QClipboardData *d;
            if (req->selection == XA_PRIMARY) {
                d = selectionData();
            } else if (req->selection == ATOM(CLIPBOARD)) {
                d = clipboardData();
            } else {
                qWarning("QClipboard: Unknown selection '%lx'", req->selection);
                XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                break;
            }

            if (! d->source()) {
                qWarning("QClipboard: Cannot transfer data, no data available");
                XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                break;
            }

            DEBUG("QClipboard: SelectionRequest at time %lx (ours %lx)",
                  req->time, d->timestamp);

            if (d->timestamp == CurrentTime // we don't own the selection anymore
                || (req->time != CurrentTime && req->time < d->timestamp)) {
                DEBUG("QClipboard: SelectionRequest too old");
                XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                break;
            }

            Atom xa_targets = ATOM(TARGETS);
            Atom xa_multiple = ATOM(MULTIPLE);
            Atom xa_timestamp = ATOM(TIMESTAMP);

            struct AtomPair { Atom target; Atom property; } *multi = 0;
            Atom multi_type = XNone;
            int multi_format = 0;
            int nmulti = 0;
            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)
                    || 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;
}
Exemplo n.º 30
0
void AFXAPI AfxDumpStack(DWORD dwTarget /* = AFX_STACK_DUMP_TARGET_DEFAULT */)
{
	CTraceClipboardData clipboardData(dwTarget);

	clipboardData.SendOut("=== begin AfxDumpStack output ===\r\n");

	CDWordArray adwAddress;
	HANDLE hProcess = ::GetCurrentProcess();
	if (SymInitialize(hProcess, NULL, FALSE))
	{
		// force undecorated names to get params
		DWORD dw = SymGetOptions();
		dw &= ~SYMOPT_UNDNAME;
		SymSetOptions(dw);

		HANDLE hThread = ::GetCurrentThread();
		CONTEXT threadContext;

		threadContext.ContextFlags = CONTEXT_FULL;

		if (::GetThreadContext(hThread, &threadContext))
		{
			STACKFRAME stackFrame;
			memset(&stackFrame, 0, sizeof(stackFrame));
			stackFrame.AddrPC.Mode = AddrModeFlat;

			DWORD dwMachType;

#if defined(_M_IX86)
			dwMachType                  = IMAGE_FILE_MACHINE_I386;

			// program counter, stack pointer, and frame pointer
			stackFrame.AddrPC.Offset    = threadContext.Eip;
			stackFrame.AddrStack.Offset = threadContext.Esp;
			stackFrame.AddrStack.Mode   = AddrModeFlat;
			stackFrame.AddrFrame.Offset = threadContext.Ebp;
			stackFrame.AddrFrame.Mode   = AddrModeFlat;
#elif defined(_M_MRX000)
			// only program counter
			dwMachType                  = IMAGE_FILE_MACHINE_R4000;
			stackFrame.AddrPC. Offset    = treadContext.Fir;
#elif defined(_M_ALPHA)
			// only program counter
			dwMachType                  = IMAGE_FILE_MACHINE_ALPHA;
			stackFrame.AddrPC.Offset    = (unsigned long) threadContext.Fir;
#elif defined(_M_PPC)
			// only program counter
			dwMachType                  = IMAGE_FILE_MACHINE_POWERPC;
			stackFrame.AddrPC.Offset    = threadContext.Iar;
#elif
#error("Unknown Target Machine");
#endif

			adwAddress.SetSize(0, 16);

			int nFrame;
			for (nFrame = 0; nFrame < 1024; nFrame++)
			{
				if (!StackWalk(dwMachType, hProcess, hProcess,
					&stackFrame, &threadContext, NULL,
					FunctionTableAccess, GetModuleBase, NULL))
				{
					break;
				}

				adwAddress.SetAtGrow(nFrame, stackFrame.AddrPC.Offset);
			}
		}
	}
	else
	{
		DWORD dw = GetLastError();
		char sz[100];
		wsprintfA(sz,
			"AfxDumpStack Error: IMAGEHLP.DLL wasn't found. "
			"GetLastError() returned 0x%8.8X\r\n", dw);
		clipboardData.SendOut(sz);
	}

	// dump it out now
	int nAddress;
	int cAddresses = adwAddress.GetSize();
	for (nAddress = 0; nAddress < cAddresses; nAddress++)
	{
		SYMBOL_INFO info;
		DWORD dwAddress = adwAddress[nAddress];

		char sz[20];
		wsprintfA(sz, "%8.8X: ", dwAddress);
		clipboardData.SendOut(sz);

		if (ResolveSymbol(hProcess, dwAddress, info))
		{
			clipboardData.SendOut(info.szModule);
			clipboardData.SendOut(info.szSymbol);
		}
		else
			clipboardData.SendOut("symbol not found");
		clipboardData.SendOut("\r\n");
	}

	clipboardData.SendOut("=== end AfxDumpStack() output ===\r\n");
}