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

📄 qclipboard_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/// #define QCLIPBOARD_DEBUG// #define QCLIPBOARD_DEBUG_VERBOSE#ifdef QCLIPBOARD_DEBUG#  define DEBUG qDebug#else#  define DEBUG if (false) qDebug#endif#ifdef QCLIPBOARD_DEBUG_VERBOSE#  define VDEBUG qDebug#else#  define VDEBUG if (false) qDebug#endif#include "qplatformdefs.h"#include "qclipboard.h"#ifndef QT_NO_CLIPBOARD#include "qabstracteventdispatcher.h"#include "qapplication.h"#include "qdesktopwidget.h"#include "qbitmap.h"#include "qdatetime.h"#include "qiodevice.h"#include "qbuffer.h"#include "qtextcodec.h"#include "qlist.h"#include "qmap.h"#include "qapplication_p.h"#include "qevent.h"#include "qt_x11_p.h"#include "qx11info_x11.h"#include "qimagewriter.h"#include "qvariant.h"#include "qdnd_p.h"/*****************************************************************************  Internal QClipboard functions for X11. *****************************************************************************/static int clipboard_timeout = 5000; // 5s timeout on clipboard operationsstatic QWidget * owner = 0;static QWidget *requestor = 0;static bool timer_event_clear = false;static int timer_id = 0;static int pending_timer_id = 0;static bool pending_clipboard_changed = false;static bool pending_selection_changed = false;// event capture mechanism for qt_xclb_wait_for_eventstatic bool waiting_for_data = false;static bool has_captured_event = false;static Window capture_event_win = XNone;static int capture_event_type = -1;static XEvent captured_event;class QClipboardWatcher; // forward declstatic QClipboardWatcher *selection_watcher = 0;static QClipboardWatcher *clipboard_watcher = 0;static void cleanup(){    delete owner;    delete requestor;    owner = 0;    requestor = 0;}staticvoid setupOwner(){    if (owner)        return;    owner = new QWidget(0);    owner->setObjectName(QLatin1String("internal clipboard owner"));    owner->createWinId();    requestor = new QWidget(0);    requestor->createWinId();    requestor->setObjectName(QLatin1String("internal clipboard requestor"));    qAddPostRoutine(cleanup);}class QClipboardWatcher : public QInternalMimeData {public:    QClipboardWatcher(QClipboard::Mode mode);    ~QClipboardWatcher();    bool empty() const;    virtual bool hasFormat_sys(const QString &mimetype) const;    virtual QStringList formats_sys() const;    QVariant retrieveData_sys(const QString &mimetype, QVariant::Type type) const;    QByteArray getDataInFormat(Atom fmtatom) const;    Atom atom;    mutable QStringList formatList;    mutable QByteArray format_atoms;};class QClipboardData{public:    QClipboardData();    ~QClipboardData();    void setSource(QMimeData* s)    {        if (s == src)            return;        delete src;        src = s;    }    QMimeData *source() const { return src; }    void clear();    QMimeData *src;    Time timestamp;};QClipboardData::QClipboardData(){    src = 0;    timestamp = CurrentTime;}QClipboardData::~QClipboardData(){ clear(); }void QClipboardData::clear(){    delete src;    src = 0;    timestamp = CurrentTime;}static QClipboardData *internalCbData = 0;static QClipboardData *internalSelData = 0;static void cleanupClipboardData(){    delete internalCbData;    internalCbData = 0;}static QClipboardData *clipboardData(){    if (internalCbData == 0) {        internalCbData = new QClipboardData;        qAddPostRoutine(cleanupClipboardData);    }    return internalCbData;}static void cleanupSelectionData(){    delete internalSelData;    internalSelData = 0;}static QClipboardData *selectionData(){    if (internalSelData == 0) {        internalSelData = new QClipboardData;        qAddPostRoutine(cleanupSelectionData);    }    return internalSelData;}class QClipboardINCRTransaction{public:    QClipboardINCRTransaction(Window w, Atom p, Atom t, int f, QByteArray d, unsigned int i);    ~QClipboardINCRTransaction(void);    int x11Event(XEvent *event);    Window window;    Atom property, target;    int format;    QByteArray data;    unsigned int increment;    unsigned int offset;};typedef QMap<Window,QClipboardINCRTransaction*> TransactionMap;static TransactionMap *transactions = 0;static QApplication::EventFilter prev_event_filter = 0;static int incr_timer_id = 0;static bool qt_x11_incr_event_filter(void *message, long *result){    XEvent *event = reinterpret_cast<XEvent *>(message);    TransactionMap::Iterator it = transactions->find(event->xany.window);    if (it != transactions->end()) {        if ((*it)->x11Event(event) != 0)            return true;    }    if (prev_event_filter)        return prev_event_filter(event, result);    return false;}/*  called when no INCR activity has happened for 'clipboard_timeout'  milliseconds... we assume that all unfinished transactions have  timed out and remove everything from the transaction map*/static void qt_xclb_incr_timeout(void){    qWarning("QClipboard: Timed out while sending data");    while (transactions)        delete *transactions->begin();}QClipboardINCRTransaction::QClipboardINCRTransaction(Window w, Atom p, Atom t, int f,                                                     QByteArray d, unsigned int i)    : window(w), property(p), target(t), format(f), data(d), increment(i), offset(0u){    DEBUG("QClipboard: sending %d bytes (INCR transaction %p)", d.size(), this);    XSelectInput(X11->display, window, PropertyChangeMask);    if (! transactions) {        VDEBUG("QClipboard: created INCR transaction map");        transactions = new TransactionMap;        prev_event_filter = qApp->setEventFilter(qt_x11_incr_event_filter);        incr_timer_id = QApplication::clipboard()->startTimer(clipboard_timeout);    }    transactions->insert(window, this);}QClipboardINCRTransaction::~QClipboardINCRTransaction(void){    VDEBUG("QClipboard: destroyed INCR transacton %p", this);    XSelectInput(X11->display, window, NoEventMask);    transactions->remove(window);    if (transactions->isEmpty()) {        VDEBUG("QClipboard: no more INCR transactions");        delete transactions;        transactions = 0;        (void)qApp->setEventFilter(prev_event_filter);        if (incr_timer_id != 0) {            QApplication::clipboard()->killTimer(incr_timer_id);            incr_timer_id = 0;        }    }}int QClipboardINCRTransaction::x11Event(XEvent *event){    if (event->type != PropertyNotify        || (event->xproperty.state != PropertyDelete            || event->xproperty.atom != property))        return 0;    // restart the INCR timer    if (incr_timer_id) QApplication::clipboard()->killTimer(incr_timer_id);    incr_timer_id = QApplication::clipboard()->startTimer(clipboard_timeout);    unsigned int bytes_left = data.size() - offset;    if (bytes_left > 0) {        unsigned int xfer = qMin(increment, bytes_left);        VDEBUG("QClipboard: sending %d bytes, %d remaining (INCR transaction %p)",               xfer, bytes_left - xfer, this);        XChangeProperty(X11->display, window, property, target, format,                        PropModeReplace, (uchar *) data.data() + offset, xfer);        offset += xfer;    } else {        // INCR transaction finished...        XChangeProperty(X11->display, window, property, target, format,                        PropModeReplace, (uchar *) data.data(), 0);        delete this;    }    return 1;}/*****************************************************************************  QClipboard member functions for X11. *****************************************************************************/void QClipboard::clear(Mode mode){    setMimeData(0, mode);}bool QClipboard::supportsMode(Mode mode) const{    return (mode == Clipboard || mode == Selection);}bool QClipboard::ownsMode(Mode mode) const{    if (mode == Clipboard)        return clipboardData()->timestamp != CurrentTime;    else if(mode == Selection)        return selectionData()->timestamp != CurrentTime;    else        return false;}// event filter function... captures interesting events while// qt_xclb_wait_for_event is running the event loopstatic bool qt_x11_clipboard_event_filter(void *message, long *){    XEvent *event = reinterpret_cast<XEvent *>(message);    if (event->xany.type == capture_event_type &&        event->xany.window == capture_event_win) {        VDEBUG("QClipboard: event_filter(): caught event type %d", event->type);        has_captured_event = true;        captured_event = *event;        return true;    }    return false;}static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer){    return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY                                             || e->xselectionrequest.selection == ATOM(CLIPBOARD)))            || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY                                              || e->xselectionclear.selection == ATOM(CLIPBOARD))));}bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout){    QTime started = QTime::currentTime();    QTime now = started;    if (QAbstractEventDispatcher::instance()->inherits("QtMotif")) {        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;            // process other clipboard events, since someone is probably requesting data from us            XEvent e;            if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0))                qApp->x11ProcessEvent(&e);            now = QTime::currentTime();            if ( started > now )                        // crossed midnight                started = now;            XFlush(X11->display);            // sleep 50 ms, so we don't use up CPU cycles all the time.            struct timeval usleep_tv;

⌨️ 快捷键说明

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