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); }
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 }
ClipboardDialog::ClipboardDialog(QWidget *parent) : QDialog(parent) { init(); const QMimeData *clipData = clipboardData(); if (clipData) setData( cloneData(*clipData) ); }
bool QClipboard::ownsMode(Mode mode) const { if (mode == Clipboard) return clipboardData()->timestamp != CurrentTime; else if(mode == Selection) return selectionData()->timestamp != CurrentTime; else return false; }
bool QClipboard::ownsMode(Mode mode) const { if (mode == Clipboard) { QClipboardData *d = clipboardData(); return d->iData && OleIsCurrentClipboard(d->iData) == S_OK; } else { return false; } }
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); } }
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; }
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(); }
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; }
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; } }
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; } }
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; }
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(); }
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; } }
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 }
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); } }
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(); } }
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; } }
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(); }*/ }
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(); }
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; }
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; }
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); }
QByteArray clipboardOwnerData(ClipboardMode mode) { const auto data = clipboardData(mode); return data ? data->data(mimeOwner) : QByteArray(); }
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 }
QVariantMap DummyClipboard::data(ClipboardMode mode, const QStringList &formats) const { const QMimeData *data = clipboardData(mode); return data ? cloneData(*data, formats) : QVariantMap(); }
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); }
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; }
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"); }