summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2019-04-21 23:22:20 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2019-04-21 23:22:20 +0900
commitdba036816b279bc1539a9f3894fbc414665d2bce (patch)
tree29e4bf00bafe515e7afdd02168d65a47a3f9fbc0 /tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp
parent6f1b4f0c7505a049d992a33f6e409b7c75732d4b (diff)
downloadexperimental-dba036816b279bc1539a9f3894fbc414665d2bce.tar.gz
experimental-dba036816b279bc1539a9f3894fbc414665d2bce.zip
Removed unnecessary and/or TDE-unrelated code.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it> Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp2038
1 files changed, 0 insertions, 2038 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp b/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp
deleted file mode 100644
index b1f76c0..0000000
--- a/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp
+++ /dev/null
@@ -1,2038 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQClipboard class for X11
-**
-** Created : 960430
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the kernel module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** 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.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-// #define TQCLIPBOARD_DEBUG
-// #define TQCLIPBOARD_DEBUG_VERBOSE
-
-#ifdef TQCLIPBOARD_DEBUG
-# define TQDEBUG qDebug
-#else
-# define TQDEBUG if (FALSE) qDebug
-#endif
-
-#ifdef TQCLIPBOARD_DEBUG_VERBOSE
-# define VTQDEBUG qDebug
-#else
-# define VTQDEBUG if (FALSE) qDebug
-#endif
-
-#include "tqplatformdefs.h"
-
-// POSIX Large File Support redefines open -> open64
-#if defined(open)
-# undef open
-#endif
-
-#include "tqclipboard.h"
-
-#ifndef TQT_NO_CLIPBOARD
-
-#include "tqapplication.h"
-#include "tqeventloop.h"
-#include "tqbitmap.h"
-#include "tqdatetime.h"
-#include "tqdragobject.h"
-#include "tqbuffer.h"
-#include "tqtextcodec.h"
-#include "tqvaluelist.h"
-#include "tqmap.h"
-#include "tqt_x11_p.h"
-#include "tqapplication_p.h"
-
-// #ifdef USE_QT4
-#if 0
-
-/*****************************************************************************
- Internal TQClipboard functions for X11.
- *****************************************************************************/
-
-// from qapplication_x11.cpp
-typedef int (*QX11EventFilter) (XEvent*);
-extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
-
-extern Time qt_x_incr; // def. in qapplication_x11.cpp
-extern Atom qt_xa_clipboard;
-extern Atom qt_selection_property;
-extern Atom qt_clipboard_sentinel;
-extern Atom qt_selection_sentinel;
-extern Atom qt_utf8_string;
-
-// from qdnd_x11.cpp
-extern Atom* qt_xdnd_str_to_atom( const char *mimeType );
-extern const char* qt_xdnd_atom_to_str( Atom );
-
-
-static int clipboard_timeout = 5000; // 5s timeout on clipboard operations
-
-static TQWidget * owner = 0;
-static TQWidget *requestor = 0;
-static bool inSelectionMode_obsolete = FALSE; // ### remove 4.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;
-
-TQ_EXPORT bool qt_qclipboard_bailout_hack = false;
-
-// event capture mechanism for qt_xclb_wait_for_event
-static bool waiting_for_data = FALSE;
-static bool has_captured_event = FALSE;
-static Window capture_event_win = None;
-static int capture_event_type = -1;
-static XEvent captured_event;
-
-// event filter function... captures interesting events while
-// qt_xclb_wait_for_event is running the event loop
-static int qt_xclb_event_filter(XEvent *event)
-{
- if (event->xany.type == capture_event_type &&
- event->xany.window == capture_event_win) {
- VTQDEBUG( "TQClipboard: event_filter(): caught event type %d", event->type );
- has_captured_event = TRUE;
- captured_event = *event;
- return 1;
- }
-
- return 0;
-}
-
-static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
-{
- return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY
- || e->xselectionrequest.selection == qt_xa_clipboard))
- || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY
- || e->xselectionclear.selection == qt_xa_clipboard)));
-}
-
-static bool selection_request_pending = false;
-
-static Bool check_selection_request_pending( Display*, XEvent* e, XPointer )
- {
- if( e->type == SelectionRequest && e->xselectionrequest.owner == owner->winId())
- selection_request_pending = true;
- return False;
- }
-
-bool qt_xclb_wait_for_event( Display *dpy, Window win, int type, XEvent *event,
- int timeout )
-{
- TQTime started = TQTime::currentTime();
- TQTime now = started;
-
- if (tqApp->eventLoop()->inherits("TQMotif")) { // yes yes, evil hack, we know
- if ( waiting_for_data )
- qFatal( "TQClipboard: internal error, qt_xclb_wait_for_event recursed" );
-
- waiting_for_data = TRUE;
- has_captured_event = FALSE;
- capture_event_win = win;
- capture_event_type = type;
-
- QX11EventFilter old_event_filter = qt_set_x11_event_filter(qt_xclb_event_filter);
-
- do {
- if ( XCheckTypedWindowEvent(dpy,win,type,event) ) {
- waiting_for_data = FALSE;
- qt_set_x11_event_filter(old_event_filter);
- return TRUE;
- }
-
- now = TQTime::currentTime();
- if ( started > now ) // crossed midnight
- started = now;
-
- // 0x08 == ExcludeTimers for X11 only
- tqApp->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput |
- TQEventLoop::ExcludeSocketNotifiers |
- TQEventLoop::WaitForMore | 0x08 );
-
- if ( has_captured_event ) {
- waiting_for_data = FALSE;
- *event = captured_event;
- qt_set_x11_event_filter(old_event_filter);
- return TRUE;
- }
- } while ( started.msecsTo(now) < timeout );
-
- waiting_for_data = FALSE;
- qt_set_x11_event_filter(old_event_filter);
-
- return FALSE;
- }
-
- bool flushed = FALSE;
- do {
- if ( XCheckTypedWindowEvent(dpy,win,type,event) )
- return TRUE;
- if( qt_qclipboard_bailout_hack ) {
- XEvent dummy;
- selection_request_pending = false;
- if ( owner != NULL )
- XCheckIfEvent(dpy,&dummy,check_selection_request_pending,NULL);
- if( selection_request_pending )
- return TRUE;
- }
-
- // process other clipboard events, since someone is probably requesting data from us
- XEvent e;
- if (XCheckIfEvent(dpy, &e, checkForClipboardEvents, 0))
- tqApp->x11ProcessEvent(&e);
-
- now = TQTime::currentTime();
- if ( started > now ) // crossed midnight
- started = now;
-
- if(!flushed) {
- XFlush( dpy );
- flushed = TRUE;
- }
-
- // 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; }
-
-// uglyhack: externed into qt_xdnd.cpp. qt is really not designed for
-// single-platform, multi-purpose blocks of code...
-bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
- bool deleteProperty,
- TQByteArray *buffer, int *size, Atom *type,
- int *format, bool nullterm )
-{
- int maxsize = maxSelectionIncr(dpy);
- 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( dpy, win, property, 0, 0, False,
- AnyPropertyType, type, format,
- &length, &bytes_left, &data );
- if (r != Success || (type && *type == None)) {
- buffer->resize( 0 );
- return FALSE;
- }
- XFree( (char*)data );
-
- int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
-
- VTQDEBUG("TQClipboard: 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;
- }
-
- bool ok = buffer->tqresize( proplen + (nullterm ? 1 : 0) );
-
- VTQDEBUG("TQClipboard: read_property(): buffer resized to %d", buffer->size());
-
- if ( ok ) {
- // could allocate buffer
-
- while ( bytes_left ) {
- // more to read...
-
- r = XGetWindowProperty( dpy, win, property, offset, maxsize/4,
- False, AnyPropertyType, type, format,
- &length, &bytes_left, &data );
- if (r != Success || (type && *type == None))
- 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 (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 );
- }
-
- static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
- if ( *format == 8 && *type == xa_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( dpy, &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->tqat(buffer_offset) = '\0';
- }
-
- // correct size, not 0-term.
- if ( size )
- *size = buffer_offset;
-
- VTQDEBUG("TQClipboard: read_property(): buffer size %d, buffer offset %d, offset %d",
- buffer->size(), buffer_offset, offset);
-
- if ( deleteProperty )
- XDeleteProperty( dpy, win, property );
-
- XFlush( dpy );
-
- return ok;
-}
-
-// this is externed into qt_xdnd.cpp too.
-TQByteArray qt_xclb_read_incremental_property( Display *dpy, Window win,
- Atom property, int nbytes,
- bool nullterm )
-{
- XEvent event;
-
- TQByteArray buf;
- TQByteArray 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
- alloc_error = !buf.tqresize(nbytes+1);
- }
-
- for (;;) {
- XFlush( dpy );
- if ( !qt_xclb_wait_for_event(dpy,win,PropertyNotify,&event,clipboard_timeout) )
- break;
- if ( event.xproperty.atom != property ||
- event.xproperty.state != PropertyNewValue )
- continue;
- if ( qt_xclb_read_property(dpy, 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.tqat( offset ) = '\0';
- } else {
- buf.resize(offset);
- }
- return buf;
- } else if ( !alloc_error ) {
- if ( offset+length > (int)buf.size() ) {
- if ( !buf.tqresize(offset+length+65535) ) {
- alloc_error = TRUE;
- length = buf.size() - offset;
- }
- }
- memcpy( buf.data()+offset, tmp_buf.data(), 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 TQWidget( 0, "internal clipboard requestor" );
-
- return TQByteArray();
-}
-
-/*! \obsolete
-
- Use the TQClipboard::data(), TQClipboard::setData() and related functions
- which take a TQClipboard::Mode argument.
-
- Sets the clipboard selection mode. If \a enable is TRUE, then
- subsequent calls to TQClipboard::setData() and other functions
- which put data into the clipboard will put the data into the mouse
- selection, otherwise the data will be put into the clipboard.
-
- \sa supportsSelection(), selectionModeEnabled()
-*/
-void TQClipboard::setSelectionMode(bool enable)
-{ inSelectionMode_obsolete = enable; }
-
-
-/*! \obsolete
-
- Use the TQClipboard::data(), TQClipboard::setData() and related functions
- which take a TQClipboard::Mode argument.
-
- Returns the selection mode.
-
- \sa setSelectionMode(), supportsSelection()
-*/
-bool TQClipboard::selectionModeEnabled() const
-{ return inSelectionMode_obsolete; }
-
-#else // USE_QT4
-
-
-// REVISED: arnt
-
-/*****************************************************************************
- Internal TQClipboard functions for X11.
- *****************************************************************************/
-
-// from qapplication_x11.cpp
-typedef int (*QX11EventFilter) (XEvent*);
-extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
-
-extern Time qt_x_incr; // def. in qapplication_x11.cpp
-extern Atom qt_xa_clipboard;
-extern Atom qt_selection_property;
-extern Atom qt_clipboard_sentinel;
-extern Atom qt_selection_sentinel;
-extern Atom qt_utf8_string;
-
-// from qdnd_x11.cpp
-extern Atom* qt_xdnd_str_to_atom( const char *mimeType );
-extern const char* qt_xdnd_atom_to_str( Atom );
-
-
-static int clipboard_timeout = 5000; // 5s timeout on clipboard operations
-
-static TQWidget * owner = 0;
-static TQWidget *requestor = 0;
-static bool inSelectionMode_obsolete = FALSE; // ### remove 4.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_event
-static bool waiting_for_data = FALSE;
-static bool has_captured_event = FALSE;
-static Window capture_event_win = None;
-static int capture_event_type = -1;
-static XEvent captured_event;
-
-class TQClipboardWatcher; // forward decl
-static TQClipboardWatcher *selection_watcher = 0;
-static TQClipboardWatcher *clipboard_watcher = 0;
-
-static void cleanup()
-{
- delete owner;
- delete requestor;
- owner = 0;
- requestor = 0;
-}
-
-static
-void setupOwner()
-{
- if ( owner )
- return;
- owner = new TQWidget( 0, "internal clipboard owner" );
- requestor = new TQWidget(0, "internal clipboard requestor");
- qAddPostRoutine( cleanup );
-}
-
-static
-int sizeof_format(int format)
-{
- int sz;
- switch (format) {
- default:
- case 8: sz = sizeof( char); break;
- case 16: sz = sizeof(short); break;
- case 32: sz = sizeof( long); break;
- }
- return sz;
-}
-
-class TQClipboardWatcher : public TQMimeSource {
-public:
- TQClipboardWatcher( TQClipboard::Mode mode );
- ~TQClipboardWatcher();
- bool empty() const;
- const char* format( int n ) const;
- TQByteArray tqencodedData( const char* fmt ) const;
- TQByteArray getDataInFormat(Atom fmtatom) const;
-
- Atom atom;
- TQValueList<const char *> formatList;
-};
-
-
-
-class TQClipboardData
-{
-public:
- TQClipboardData();
- ~TQClipboardData();
-
- void setSource(TQMimeSource* s)
- {
- clear(TRUE);
- src = s;
- }
-
- TQMimeSource *source() const { return src; }
-
- void addTransferredPixmap(TQPixmap pm)
- {
- /* TODO: queue them */
- transferred[tindex] = pm;
- tindex=(tindex+1)%2;
- }
- void clearTransfers()
- {
- transferred[0] = TQPixmap();
- transferred[1] = TQPixmap();
- }
-
- void clear(bool destruct=TRUE);
-
- TQMimeSource *src;
- Time timestamp;
-
- TQPixmap transferred[2];
- int tindex;
-};
-
-TQClipboardData::TQClipboardData()
-{
- src = 0;
- timestamp = CurrentTime;
- tindex=0;
-}
-
-TQClipboardData::~TQClipboardData()
-{ clear(); }
-
-void TQClipboardData::clear(bool destruct)
-{
- if(destruct)
- delete src;
- src = 0;
- timestamp = CurrentTime;
-}
-
-
-static TQClipboardData *internalCbData = 0;
-static TQClipboardData *internalSelData = 0;
-
-static void cleanupClipboardData()
-{
- delete internalCbData;
- internalCbData = 0;
-}
-
-static TQClipboardData *clipboardData()
-{
- if ( internalCbData == 0 ) {
- internalCbData = new TQClipboardData;
- TQ_CHECK_PTR( internalCbData );
- qAddPostRoutine( cleanupClipboardData );
- }
- return internalCbData;
-}
-
-void qt_clipboard_cleanup_mime_source(TQMimeSource *src)
-{
- if(internalCbData && internalCbData->source() == src)
- internalCbData->clear(FALSE);
-}
-
-static void cleanupSelectionData()
-{
- delete internalSelData;
- internalSelData = 0;
-}
-
-static TQClipboardData *selectionData()
-{
- if (internalSelData == 0) {
- internalSelData = new TQClipboardData;
- TQ_CHECK_PTR(internalSelData);
- qAddPostRoutine(cleanupSelectionData);
- }
- return internalSelData;
-}
-
-class TQClipboardINCRTransaction
-{
-public:
- TQClipboardINCRTransaction(Window w, Atom p, Atom t, int f, TQByteArray d, unsigned int i);
- ~TQClipboardINCRTransaction(void);
-
- int x11Event(XEvent *event);
-
- Window window;
- Atom property, target;
- int format;
- TQByteArray data;
- unsigned int increment;
- unsigned int offset;
-};
-
-typedef TQMap<Window,TQClipboardINCRTransaction*> TransactionMap;
-static TransactionMap *transactions = 0;
-static QX11EventFilter prev_x11_event_filter = 0;
-static int incr_timer_id = 0;
-
-static int qt_xclb_transation_event_handler(XEvent *event)
-{
- TransactionMap::Iterator it = transactions->find(event->xany.window);
- if (it != transactions->end()) {
- if ((*it)->x11Event(event) != 0)
- return 1;
- }
- if (prev_x11_event_filter)
- return prev_x11_event_filter(event);
- return 0;
-}
-
-/*
- 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("TQClipboard: timed out while sending data");
-
- while (transactions)
- delete *transactions->begin();
-}
-
-TQClipboardINCRTransaction::TQClipboardINCRTransaction(Window w, Atom p, Atom t, int f,
- TQByteArray d, unsigned int i)
- : window(w), property(p), target(t), format(f), data(d), increment(i), offset(0u)
-{
- TQDEBUG("TQClipboard: sending %d bytes (INCR transaction %p)", d.size(), this);
-
- XSelectInput(TQPaintDevice::x11AppDisplay(), window, PropertyChangeMask);
-
- if (! transactions) {
- VTQDEBUG("TQClipboard: created INCR transaction map");
- transactions = new TransactionMap;
- prev_x11_event_filter = qt_set_x11_event_filter(qt_xclb_transation_event_handler);
-
- incr_timer_id = TQApplication::clipboard()->startTimer(clipboard_timeout);
- }
- transactions->insert(window, this);
-}
-
-TQClipboardINCRTransaction::~TQClipboardINCRTransaction(void)
-{
- VTQDEBUG("TQClipboard: destroyed INCR transacton %p", this);
-
- XSelectInput(TQPaintDevice::x11AppDisplay(), window, NoEventMask);
-
- transactions->remove(window);
- if (transactions->isEmpty()) {
- VTQDEBUG("TQClipboard: no more INCR transations");
- delete transactions;
- transactions = 0;
- (void)qt_set_x11_event_filter(prev_x11_event_filter);
-
- if (incr_timer_id != 0) {
- TQApplication::clipboard()->killTimer(incr_timer_id);
- incr_timer_id = 0;
- }
- }
-}
-
-int TQClipboardINCRTransaction::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) TQApplication::clipboard()->killTimer(incr_timer_id);
- incr_timer_id = TQApplication::clipboard()->startTimer(clipboard_timeout);
-
- unsigned int bytes_left = data.size() - offset;
- if (bytes_left > 0) {
- unsigned int xfer = TQMIN(increment, bytes_left);
- VTQDEBUG("TQClipboard: sending %d bytes, %d remaining (INCR transaction %p)",
- xfer, bytes_left - xfer, this);
-
- XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, target, format,
- PropModeReplace, (uchar *) data.data() + offset, xfer);
- offset += xfer;
- } else {
- // INCR transaction finished...
- XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, target, format,
- PropModeReplace, (uchar *) data.data(), 0);
- delete this;
- }
-
- return 1;
-}
-
-
-/*****************************************************************************
- TQClipboard member functions for X11.
- *****************************************************************************/
-
-
-void TQClipboard::clear( Mode mode )
-{ setData(0, mode); }
-
-
-/*!
- Returns TRUE if the clipboard supports mouse selection; otherwise
- returns FALSE.
-*/
-bool TQClipboard::supportsSelection() const
-{ return TRUE; }
-
-
-/*!
- Returns TRUE if this clipboard object owns the mouse selection
- data; otherwise returns FALSE.
-*/
-bool TQClipboard::ownsSelection() const
-{ return selectionData()->timestamp != CurrentTime; }
-
-/*!
- Returns TRUE if this clipboard object owns the clipboard data;
- otherwise returns FALSE.
-*/
-bool TQClipboard::ownsClipboard() const
-{ return clipboardData()->timestamp != CurrentTime; }
-
-
-/*! \obsolete
-
- Use the TQClipboard::data(), TQClipboard::setData() and related functions
- which take a TQClipboard::Mode argument.
-
- Sets the clipboard selection mode. If \a enable is TRUE, then
- subsequent calls to TQClipboard::setData() and other functions
- which put data into the clipboard will put the data into the mouse
- selection, otherwise the data will be put into the clipboard.
-
- \sa supportsSelection(), selectionModeEnabled()
-*/
-void TQClipboard::setSelectionMode(bool enable)
-{ inSelectionMode_obsolete = enable; }
-
-
-/*! \obsolete
-
- Use the TQClipboard::data(), TQClipboard::setData() and related functions
- which take a TQClipboard::Mode argument.
-
- Returns the selection mode.
-
- \sa setSelectionMode(), supportsSelection()
-*/
-bool TQClipboard::selectionModeEnabled() const
-{ return inSelectionMode_obsolete; }
-
-
-// event filter function... captures interesting events while
-// qt_xclb_wait_for_event is running the event loop
-static int qt_xclb_event_filter(XEvent *event)
-{
- if (event->xany.type == capture_event_type &&
- event->xany.window == capture_event_win) {
- VTQDEBUG( "TQClipboard: event_filter(): caught event type %d", event->type );
- has_captured_event = TRUE;
- captured_event = *event;
- return 1;
- }
-
- return 0;
-}
-
-static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
-{
- return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY
- || e->xselectionrequest.selection == qt_xa_clipboard))
- || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY
- || e->xselectionclear.selection == qt_xa_clipboard)));
-}
-
-bool qt_xclb_wait_for_event( Display *dpy, Window win, int type, XEvent *event,
- int timeout )
-{
- TQTime started = TQTime::currentTime();
- TQTime now = started;
-
- if (tqApp->eventLoop()->inherits("TQMotif")) { // yes yes, evil hack, we know
- if ( waiting_for_data )
- qFatal( "TQClipboard: internal error, qt_xclb_wait_for_event recursed" );
-
- waiting_for_data = TRUE;
- has_captured_event = FALSE;
- capture_event_win = win;
- capture_event_type = type;
-
- QX11EventFilter old_event_filter = qt_set_x11_event_filter(qt_xclb_event_filter);
-
- do {
- if ( XCheckTypedWindowEvent(dpy,win,type,event) ) {
- waiting_for_data = FALSE;
- qt_set_x11_event_filter(old_event_filter);
- return TRUE;
- }
-
- now = TQTime::currentTime();
- if ( started > now ) // crossed midnight
- started = now;
-
- // 0x08 == ExcludeTimers for X11 only
- tqApp->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput |
- TQEventLoop::ExcludeSocketNotifiers |
- TQEventLoop::WaitForMore | 0x08 );
-
- if ( has_captured_event ) {
- waiting_for_data = FALSE;
- *event = captured_event;
- qt_set_x11_event_filter(old_event_filter);
- return TRUE;
- }
- } while ( started.msecsTo(now) < timeout );
-
- waiting_for_data = FALSE;
- qt_set_x11_event_filter(old_event_filter);
-
- return FALSE;
- }
-
- bool flushed = FALSE;
- do {
- if ( XCheckTypedWindowEvent(dpy,win,type,event) )
- return TRUE;
-
- // process other clipboard events, since someone is probably requesting data from us
- XEvent e;
- if (XCheckIfEvent(dpy, &e, checkForClipboardEvents, 0))
- tqApp->x11ProcessEvent(&e);
-
- now = TQTime::currentTime();
- if ( started > now ) // crossed midnight
- started = now;
-
- if(!flushed) {
- XFlush( dpy );
- flushed = TRUE;
- }
-
- // 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; }
-
-// uglyhack: externed into qt_xdnd.cpp. qt is really not designed for
-// single-platform, multi-purpose blocks of code...
-bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
- bool deleteProperty,
- TQByteArray *buffer, int *size, Atom *type,
- int *format, bool nullterm )
-{
- int maxsize = maxSelectionIncr(dpy);
- 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( dpy, win, property, 0, 0, False,
- AnyPropertyType, type, format,
- &length, &bytes_left, &data );
- if (r != Success || (type && *type == None)) {
- buffer->resize( 0 );
- return FALSE;
- }
- XFree( (char*)data );
-
- int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
-
- VTQDEBUG("TQClipboard: 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;
- }
-
- bool ok = buffer->tqresize( proplen + (nullterm ? 1 : 0) );
-
- VTQDEBUG("TQClipboard: read_property(): buffer resized to %d", buffer->size());
-
- if ( ok ) {
- // could allocate buffer
-
- while ( bytes_left ) {
- // more to read...
-
- r = XGetWindowProperty( dpy, win, property, offset, maxsize/4,
- False, AnyPropertyType, type, format,
- &length, &bytes_left, &data );
- if (r != Success || (type && *type == None))
- 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 (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 );
- }
-
- static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
- if ( *format == 8 && *type == xa_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( dpy, &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->tqat(buffer_offset) = '\0';
- }
-
- // correct size, not 0-term.
- if ( size )
- *size = buffer_offset;
-
- VTQDEBUG("TQClipboard: read_property(): buffer size %d, buffer offset %d, offset %d",
- buffer->size(), buffer_offset, offset);
-
- if ( deleteProperty )
- XDeleteProperty( dpy, win, property );
-
- XFlush( dpy );
-
- return ok;
-}
-
-
-// this is externed into qt_xdnd.cpp too.
-TQByteArray qt_xclb_read_incremental_property( Display *dpy, Window win,
- Atom property, int nbytes,
- bool nullterm )
-{
- XEvent event;
-
- TQByteArray buf;
- TQByteArray 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
- alloc_error = !buf.tqresize(nbytes+1);
- }
-
- for (;;) {
- XFlush( dpy );
- if ( !qt_xclb_wait_for_event(dpy,win,PropertyNotify,&event,clipboard_timeout) )
- break;
- if ( event.xproperty.atom != property ||
- event.xproperty.state != PropertyNewValue )
- continue;
- if ( qt_xclb_read_property(dpy, 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.tqat( offset ) = '\0';
- } else {
- buf.resize(offset);
- }
- return buf;
- } else if ( !alloc_error ) {
- if ( offset+length > (int)buf.size() ) {
- if ( !buf.tqresize(offset+length+65535) ) {
- alloc_error = TRUE;
- length = buf.size() - offset;
- }
- }
- memcpy( buf.data()+offset, tmp_buf.data(), 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 TQWidget( 0, "internal clipboard requestor" );
-
- return TQByteArray();
-}
-
-static Atom send_selection(TQClipboardData *d, Atom target, Window window, Atom property,
- int format = 0, TQByteArray data = TQByteArray());
-
-static Atom send_targets_selection(TQClipboardData *d, Window window, Atom property)
-{
- int atoms = 0;
- while (d->source()->format(atoms)) atoms++;
- if (d->source()->provides("image/ppm")) atoms++;
- if (d->source()->provides("image/pbm")) atoms++;
- if (d->source()->provides("text/plain")) atoms+=4;
-
- VTQDEBUG("TQClipboard: send_targets_selection(): %d provided types", atoms);
-
- // for 64 bit cleanness... XChangeProperty expects long* for data with format == 32
- TQByteArray data((atoms+3) * sizeof(long)); // plus TARGETS, MULTIPLE and TIMESTAMP
- long *atarget = (long *) data.data();
-
- const char *fmt;
- int n = 0;
- while ((fmt=d->source()->format(n)) && n < atoms)
- atarget[n++] = *qt_xdnd_str_to_atom(fmt);
-
- static Atom xa_text = *qt_xdnd_str_to_atom("TEXT");
- static Atom xa_compound_text = *qt_xdnd_str_to_atom("COMPOUND_TEXT");
- static Atom xa_targets = *qt_xdnd_str_to_atom("TARGETS");
- static Atom xa_multiple = *qt_xdnd_str_to_atom("MULTIPLE");
- static Atom xa_timestamp = *qt_xdnd_str_to_atom("TIMESTAMP");
-
- if (d->source()->provides("image/ppm"))
- atarget[n++] = XA_PIXMAP;
- if (d->source()->provides("image/pbm"))
- atarget[n++] = XA_BITMAP;
- if (d->source()->provides("text/plain")) {
- atarget[n++] = qt_utf8_string;
- atarget[n++] = xa_text;
- atarget[n++] = xa_compound_text;
- atarget[n++] = XA_STRING;
- }
-
- atarget[n++] = xa_targets;
- atarget[n++] = xa_multiple;
- atarget[n++] = xa_timestamp;
-
-#if defined(TQCLIPBOARD_DEBUG_VERBOSE)
- for (int index = 0; index < n; index++) {
- VTQDEBUG(" atom %d: 0x%lx (%s)", index, atarget[index],
- qt_xdnd_atom_to_str(atarget[index]));
- }
-#endif
-
- XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, XA_ATOM, 32,
- PropModeReplace, (uchar *) data.data(), n);
- return property;
-}
-
-static Atom send_string_selection(TQClipboardData *d, Atom target, Window window, Atom property)
-{
- static Atom xa_text = *qt_xdnd_str_to_atom("TEXT");
- static Atom xa_compound_text = *qt_xdnd_str_to_atom("COMPOUND_TEXT");
-
- TQDEBUG("TQClipboard: send_string_selection():\n"
- " property type %lx\n"
- " property name '%s'",
- target, qt_xdnd_atom_to_str(target));
-
- if (target == xa_text || target == xa_compound_text) {
- // the ICCCM states that TEXT and COMPOUND_TEXT are in the
- // encoding of choice, so we choose the encoding of the locale
- TQByteArray data = d->source()->tqencodedData("text/plain");
- if(data.tqresize(data.size() + 1))
- data[int(data.size() - 1)] = '\0';
- char *list[] = { data.data(), NULL };
-
- XICCEncodingStyle style =
- (target == xa_compound_text) ? XCompoundTextStyle : XStdICCTextStyle;
- XTextProperty textprop;
- if (list[0] != NULL
- && XmbTextListToTextProperty(TQPaintDevice::x11AppDisplay(),
- list, 1, style, &textprop) == Success) {
- TQDEBUG(" textprop type %lx\n"
- " textprop name '%s'\n"
- " format %d\n"
- " %ld items",
- textprop.encoding, qt_xdnd_atom_to_str(textprop.encoding),
- textprop.format, textprop.nitems);
-
- int sz = sizeof_format(textprop.format);
- data.duplicate((const char *) textprop.value, textprop.nitems * sz);
- XFree(textprop.value);
-
- return send_selection(d, textprop.encoding, window, property, textprop.format, data);
- }
-
- return None;
- }
-
- Atom xtarget = None;
- const char *fmt = 0;
- if (target == XA_STRING
- || (target == xa_text && TQTextCodec::codecForLocale()->mibEnum() == 4)) {
- // the ICCCM states that STRING is latin1 plus newline and tab
- // see section 2.6.2
- fmt = "text/plain;charset=ISO-8859-1";
- xtarget = XA_STRING;
- } else if (target == qt_utf8_string) {
- // proposed UTF8_STRING conversion type
- fmt = "text/plain;charset=UTF-8";
- xtarget = qt_utf8_string;
- }
-
- if (xtarget == None) // should not happen
- return None;
-
- TQByteArray data = d->source()->tqencodedData(fmt);
-
- TQDEBUG(" format 8\n %d bytes", data.size());
-
- return send_selection(d, xtarget, window, property, 8, data);
-}
-
-static Atom send_pixmap_selection(TQClipboardData *d, Atom target, Window window, Atom property)
-{
- TQPixmap pm;
-
- if ( target == XA_PIXMAP ) {
- TQByteArray data = d->source()->tqencodedData("image/ppm");
- pm.loadFromData(data);
- } else if ( target == XA_BITMAP ) {
- TQByteArray data = d->source()->tqencodedData("image/pbm");
- TQImage img;
- img.loadFromData(data);
- if ( img.depth() != 1 )
- img = img.convertDepth(1);
- }
-
- if (pm.isNull()) // should never happen
- return None;
-
- Pixmap handle = pm.handle();
- XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property,
- target, 32, PropModeReplace, (uchar *) &handle, 1);
- d->addTransferredPixmap(pm);
- return property;
-
-}
-
-static Atom send_selection(TQClipboardData *d, Atom target, Window window, Atom property,
- int format, TQByteArray data)
-{
- if (format == 0) format = 8;
-
- if (data.isEmpty()) {
- const char *fmt = qt_xdnd_atom_to_str(target);
- TQDEBUG("TQClipboard: send_selection(): converting to type '%s'", fmt);
- if (fmt && !d->source()->provides(fmt)) // Not a MIME type we can produce
- return None;
- data = d->source()->tqencodedData(fmt);
- }
-
- TQDEBUG("TQClipboard: send_selection():\n"
- " property type %lx\n"
- " property name '%s'\n"
- " format %d\n"
- " %d bytes",
- target, qt_xdnd_atom_to_str(target), format, data.size());
-
- // don't allow INCR transfers when using MULTIPLE or to
- // Motif clients (since Motif doesn't support INCR)
- static Atom motif_clip_temporary = *qt_xdnd_str_to_atom("CLIP_TEMPORARY");
- bool allow_incr = property != motif_clip_temporary;
-
- // X_ChangeProperty protocol request is 24 bytes
- const unsigned int increment = (XMaxRequestSize(TQPaintDevice::x11AppDisplay()) * 4) - 24;
- if (data.size() > increment && allow_incr) {
- long bytes = data.size();
- XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property,
- qt_x_incr, 32, PropModeReplace, (uchar *) &bytes, 1);
-
- (void)new TQClipboardINCRTransaction(window, property, target, format, data, increment);
- return qt_x_incr;
- }
-
- // make sure we can perform the XChangeProperty in a single request
- if (data.size() > increment)
- return None; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
-
- // use a single request to transfer data
- XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, target,
- format, PropModeReplace, (uchar *) data.data(),
- data.size() / sizeof_format(format));
- return property;
-}
-
-/*! \internal
- Internal cleanup for Windows.
-*/
-void TQClipboard::ownerDestroyed()
-{ }
-
-
-/*! \internal
- Internal optimization for Windows.
-*/
-void TQClipboard::connectNotify( const char * )
-{ }
-
-
-/*! \reimp
- */
-bool TQClipboard::event( TQEvent *e )
-{
- if ( e->type() == TQEvent::Timer ) {
- TQTimerEvent *te = (TQTimerEvent *) 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();
- emit dataChanged();
- }
- if ( pending_selection_changed ) {
- pending_selection_changed = FALSE;
- selectionData()->clear();
- emit selectionChanged();
- }
-
- 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 TQObject::event( e );
- }
- } else if ( e->type() != TQEvent::Clipboard ) {
- return TQObject::event( e );
- }
-
- XEvent *xevent = (XEvent *)(((TQCustomEvent *)e)->data());
- Display *dpy = TQPaintDevice::x11AppDisplay();
-
- if ( !xevent )
- return TRUE;
-
- switch ( xevent->type ) {
-
- case SelectionClear:
- // new selection owner
- if (xevent->xselectionclear.selection == XA_PRIMARY) {
- TQClipboardData *d = selectionData();
-
- // ignore the event if it was generated before we gained selection ownership
- if (d->timestamp != CurrentTime && xevent->xselectionclear.time < d->timestamp)
- break;
-
- TQDEBUG("TQClipboard: 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();
- emit selectionChanged();
- } else {
- pending_selection_changed = TRUE;
- if ( ! pending_timer_id )
- pending_timer_id = TQApplication::clipboard()->startTimer( 0 );
- }
- } else if (xevent->xselectionclear.selection == qt_xa_clipboard) {
- TQClipboardData *d = clipboardData();
-
- // ignore the event if it was generated before we gained selection ownership
- if (d->timestamp != CurrentTime && xevent->xselectionclear.time < d->timestamp)
- break;
-
- TQDEBUG("TQClipboard: new clipboard owner 0x%lx at time %lx (%lx)",
- XGetSelectionOwner(dpy, qt_xa_clipboard),
- xevent->xselectionclear.time, d->timestamp);
-
- if ( ! waiting_for_data ) {
- d->clear();
- emit dataChanged();
- } else {
- pending_clipboard_changed = TRUE;
- if ( ! pending_timer_id )
- pending_timer_id = TQApplication::clipboard()->startTimer( 0 );
- }
- } else {
-#ifdef TQT_CHECK_STATE
- qWarning("TQClipboard: Unknown SelectionClear event received.");
-#endif
- return FALSE;
- }
- break;
-
- case SelectionNotify:
- /*
- Something has delivered data to us, but this was not caught
- by TQClipboardWatcher::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->winId())
- 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 = None;
- event.xselection.time = req->time;
-
- TQDEBUG("TQClipboard: SelectionRequest from %lx\n"
- " selection 0x%lx (%s) target 0x%lx (%s)",
- req->requestor,
- req->selection,
- qt_xdnd_atom_to_str(req->selection),
- req->target,
- qt_xdnd_atom_to_str(req->target));
-
- TQClipboardData *d;
-
- if ( req->selection == XA_PRIMARY ) {
- d = selectionData();
- } else if ( req->selection == qt_xa_clipboard ) {
- d = clipboardData();
- } else {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQClipboard: unknown selection '%lx'", req->selection);
-#endif // TQT_CHECK_RANGE
-
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
-
- if (! d->source()) {
-#ifdef TQT_CHECK_STATE
- qWarning("TQClipboard: cannot transfer data, no data available");
-#endif // TQT_CHECK_STATE
-
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
-
- TQDEBUG("TQClipboard: 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)) {
- TQDEBUG("TQClipboard: SelectionRequest too old");
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
-
- static Atom xa_text = *qt_xdnd_str_to_atom("TEXT");
- static Atom xa_compound_text = *qt_xdnd_str_to_atom("COMPOUND_TEXT");
- static Atom xa_targets = *qt_xdnd_str_to_atom("TARGETS");
- static Atom xa_multiple = *qt_xdnd_str_to_atom("MULTIPLE");
- static Atom xa_timestamp = *qt_xdnd_str_to_atom("TIMESTAMP");
-
- struct AtomPair { Atom target; Atom property; } *multi = 0;
- Atom multi_type = None;
- int multi_format = 0;
- int nmulti = 0;
- int imulti = -1;
- bool multi_writeback = FALSE;
-
- if ( req->target == xa_multiple ) {
- TQByteArray multi_data;
- if (req->property == None
- || !qt_xclb_read_property(dpy, 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 == None) // obsolete client
- property = target;
- }
-
- Atom ret = None;
- if (target == None || property == None) {
- ;
- } else if (target == xa_timestamp) {
- if (d->timestamp != CurrentTime) {
- XChangeProperty(dpy, req->requestor, property, xa_timestamp, 32,
- PropModeReplace, (uchar *) &d->timestamp, 1);
- ret = property;
- } else {
-
-#ifdef TQT_CHECK_STATE
- qWarning("TQClipboard: invalid data timestamp");
-#endif // TQT_CHECK_STATE
- }
- } else if (target == xa_targets) {
- ret = send_targets_selection(d, req->requestor, property);
- } else if (target == XA_STRING
- || target == xa_text
- || target == xa_compound_text
- || target == qt_utf8_string) {
- ret = send_string_selection(d, target, req->requestor, property);
- } else if (target == XA_PIXMAP
- || target == XA_BITMAP) {
- ret = send_pixmap_selection(d, target, req->requestor, property);
- } else {
- ret = send_selection(d, target, req->requestor, property);
- }
-
- if (nmulti > 0) {
- if (ret == None) {
- multi[imulti].property = None;
- 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);
-
- TQDEBUG("TQClipboard: SelectionNotify to 0x%lx\n"
- " property 0x%lx (%s)",
- req->requestor, event.xselection.property,
- qt_xdnd_atom_to_str(event.xselection.property));
- }
- break;
- }
-
- return TRUE;
-}
-
-
-
-
-
-
-TQClipboardWatcher::TQClipboardWatcher( TQClipboard::Mode mode )
-{
- switch ( mode ) {
- case TQClipboard::Selection:
- atom = XA_PRIMARY;
- break;
-
- case TQClipboard::Clipboard:
- atom = qt_xa_clipboard;
- break;
-
-#ifdef TQT_CHECK_RANGE
- default:
- qWarning( "TQClipboardWatcher: internal error, unknown clipboard mode" );
- break;
-#endif // TQT_CHECK_RANGE
- }
-
- setupOwner();
-}
-
-TQClipboardWatcher::~TQClipboardWatcher()
-{
- if( selection_watcher == this )
- selection_watcher = 0;
- if( clipboard_watcher == this )
- clipboard_watcher = 0;
-}
-
-bool TQClipboardWatcher::empty() const
-{
- Display *dpy = TQPaintDevice::x11AppDisplay();
- Window win = XGetSelectionOwner( dpy, atom );
-
-#ifdef TQT_CHECK_STATE
- if( win == requestor->winId()) {
- qWarning( "TQClipboardWatcher::empty: internal error, app owns the selection" );
- return TRUE;
- }
-#endif // TQT_CHECK_STATE
-
- return win == None;
-}
-
-const char* TQClipboardWatcher::format( int n ) const
-{
- if ( empty() )
- return 0;
-
- 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...
- static Atom xa_targets = *qt_xdnd_str_to_atom( "TARGETS" );
-
- TQClipboardWatcher *that = (TQClipboardWatcher *) this;
- TQByteArray ba = getDataInFormat(xa_targets);
- if (ba.size() > 0) {
- Atom *unsorted_target = (Atom *) ba.data();
- static Atom xa_text = *qt_xdnd_str_to_atom( "TEXT" );
- static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
- int i, size = ba.size() / sizeof(Atom);
-
- // sort TARGETS to prefer some types over others. some apps
- // will report XA_STRING before COMPOUND_TEXT, and we want the
- // latter, not the former (if it is present).
- Atom* target = new Atom[size+4];
- memset( target, 0, (size+4) * sizeof(Atom) );
-
- for ( i = 0; i < size; ++i ) {
- if ( unsorted_target[i] == qt_utf8_string )
- target[0] = unsorted_target[i];
- else if ( unsorted_target[i] == xa_compound_text )
- target[1] = unsorted_target[i];
- else if ( unsorted_target[i] == xa_text )
- target[2] = unsorted_target[i];
- else if ( unsorted_target[i] == XA_STRING )
- target[3] = unsorted_target[i];
- else
- target[i + 4] = unsorted_target[i];
- }
-
- for (i = 0; i < size + 4; ++i) {
- if ( target[i] == 0 ) continue;
-
- VTQDEBUG(" format: %s", qt_xdnd_atom_to_str(target[i]));
-
- if ( target[i] == XA_PIXMAP )
- that->formatList.append("image/ppm");
- else if ( target[i] == XA_STRING )
- that->formatList.append( "text/plain;charset=ISO-8859-1" );
- else if ( target[i] == qt_utf8_string )
- that->formatList.append( "text/plain;charset=UTF-8" );
- else if ( target[i] == xa_text ||
- target[i] == xa_compound_text )
- that->formatList.append( "text/plain" );
- else
- that->formatList.append(qt_xdnd_atom_to_str(target[i]));
- }
- delete []target;
-
- TQDEBUG("TQClipboardWatcher::format: %d formats available",
- int(that->formatList.count()));
- }
- }
-
- if (n >= 0 && n < (signed) formatList.count())
- return formatList[n];
- if (n == 0)
- return "text/plain";
- return 0;
-}
-
-TQByteArray TQClipboardWatcher::tqencodedData( const char* fmt ) const
-{
- if ( !fmt || empty() )
- return TQByteArray( 0 );
-
- TQDEBUG("TQClipboardWatcher::tqencodedData: fetching format '%s'", fmt);
-
- Atom fmtatom = 0;
-
- if ( 0==qstricmp(fmt,"text/plain;charset=iso-8859-1") ) {
- // ICCCM section 2.6.2 says STRING is latin1 text
- fmtatom = XA_STRING;
- } else if ( 0==qstricmp(fmt,"text/plain;charset=utf-8") ) {
- // proprosed UTF8_STRING conversion type
- fmtatom = *qt_xdnd_str_to_atom( "UTF8_STRING" );
- } else if ( 0==qstrcmp(fmt,"text/plain") ) {
- fmtatom = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
- } else if ( 0==qstrcmp(fmt,"image/ppm") ) {
- fmtatom = XA_PIXMAP;
- TQByteArray pmd = getDataInFormat(fmtatom);
- if ( pmd.size() == sizeof(Pixmap) ) {
- Pixmap xpm = *((Pixmap*)pmd.data());
- Display *dpy = TQPaintDevice::x11AppDisplay();
- Window r;
- int x,y;
- uint w,h,bw,d;
- if ( ! xpm )
- return TQByteArray( 0 );
- XGetGeometry(dpy,xpm, &r,&x,&y,&w,&h,&bw,&d);
- TQImageIO iio;
- GC gc = XCreateGC( dpy, xpm, 0, 0 );
- if ( d == 1 ) {
- TQBitmap qbm(w,h);
- XCopyArea(dpy,xpm,qbm.handle(),gc,0,0,w,h,0,0);
- iio.setFormat("PBMRAW");
- iio.setImage(qbm.convertToImage());
- } else {
- TQPixmap qpm(w,h);
- XCopyArea(dpy,xpm,qpm.handle(),gc,0,0,w,h,0,0);
- iio.setFormat("PPMRAW");
- iio.setImage(qpm.convertToImage());
- }
- XFreeGC(dpy,gc);
- TQBuffer buf;
- buf.open(IO_WriteOnly);
- iio.setIODevice(TQT_TQIODEVICE(&buf));
- iio.write();
- return buf.buffer();
- } else {
- fmtatom = *qt_xdnd_str_to_atom(fmt);
- }
- } else {
- fmtatom = *qt_xdnd_str_to_atom(fmt);
- }
- return getDataInFormat(fmtatom);
-}
-
-TQByteArray TQClipboardWatcher::getDataInFormat(Atom fmtatom) const
-{
- TQByteArray buf;
-
- Display *dpy = TQPaintDevice::x11AppDisplay();
- Window win = requestor->winId();
-
- TQDEBUG("TQClipboardWatcher::getDataInFormat: selection '%s' format '%s'",
- qt_xdnd_atom_to_str(atom), qt_xdnd_atom_to_str(fmtatom));
-
- XSelectInput(dpy, win, NoEventMask); // don't listen for any events
-
- XDeleteProperty(dpy, win, qt_selection_property);
- XConvertSelection(dpy, atom, fmtatom, qt_selection_property, win, GET_QT_X_TIME());
- XSync(dpy, FALSE);
-
- VTQDEBUG("TQClipboardWatcher::getDataInFormat: waiting for SelectionNotify event");
-
- XEvent xevent;
- if ( !qt_xclb_wait_for_event(dpy,win,SelectionNotify,&xevent,clipboard_timeout) ||
- xevent.xselection.property == None ) {
- TQDEBUG("TQClipboardWatcher::getDataInFormat: format not available");
- return buf;
- }
-
- VTQDEBUG("TQClipboardWatcher::getDataInFormat: fetching data...");
-
- Atom type;
- XSelectInput(dpy, win, PropertyChangeMask);
-
- if ( qt_xclb_read_property(dpy,win,qt_selection_property,TRUE,
- &buf,0,&type,0,FALSE) ) {
- if ( type == qt_x_incr ) {
- int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
- buf = qt_xclb_read_incremental_property( dpy, win,
- qt_selection_property,
- nbytes, FALSE );
- }
- }
-
- XSelectInput(dpy, win, NoEventMask);
-
- TQDEBUG("TQClipboardWatcher::getDataInFormat: %d bytes received", buf.size());
-
- return buf;
-}
-
-
-TQMimeSource* TQClipboard::data( Mode mode ) const
-{
- TQClipboardData *d;
- switch ( mode ) {
- case Selection: d = selectionData(); break;
- case Clipboard: d = clipboardData(); break;
-
- default:
-#ifdef TQT_CHECK_RANGE
- qWarning( "TQClipboard::data: invalid mode '%d'", mode );
-#endif // TQT_CHECK_RANGE
- return 0;
- }
-
- if ( ! d->source() && ! timer_event_clear ) {
- if ( mode == Selection ) {
- if ( ! selection_watcher )
- selection_watcher = new TQClipboardWatcher( mode );
- d->setSource( selection_watcher );
- } else {
- if ( ! clipboard_watcher )
- clipboard_watcher = new TQClipboardWatcher( 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
- TQClipboard *that = ((TQClipboard *) this);
- timer_id = that->startTimer(0);
- }
- }
-
- return d->source();
-}
-
-
-void TQClipboard::setData( TQMimeSource* src, Mode mode )
-{
- Atom atom, sentinel_atom;
- TQClipboardData *d;
- switch ( mode ) {
- case Selection:
- atom = XA_PRIMARY;
- sentinel_atom = qt_selection_sentinel;
- d = selectionData();
- break;
-
- case Clipboard:
- atom = qt_xa_clipboard;
- sentinel_atom = qt_clipboard_sentinel;
- d = clipboardData();
- break;
-
- default:
-#ifdef TQT_CHECK_RANGE
- qWarning( "TQClipboard::data: invalid mode '%d'", mode );
-#endif // TQT_CHECK_RANGE
- return;
- }
-
- Display *dpy = TQPaintDevice::x11AppDisplay();
- Window newOwner;
-
- if (! src) { // no data, clear clipboard contents
- newOwner = None;
- d->clear();
- } else {
- setupOwner();
-
- newOwner = owner->winId();
-
- d->setSource(src);
- d->timestamp = GET_QT_X_TIME();
- }
-
- Window prevOwner = XGetSelectionOwner( dpy, atom );
- // use qt_x_time, since d->timestamp == CurrentTime when clearing
- XSetSelectionOwner(dpy, atom, newOwner, GET_QT_X_TIME());
-
- if ( mode == Selection )
- emit selectionChanged();
- else
- emit dataChanged();
-
- if (XGetSelectionOwner(dpy, atom) != newOwner) {
-#ifdef TQT_CHECK_STATE
- qWarning("TQClipboard::setData: Cannot set X11 selection owner for %s",
- qt_xdnd_atom_to_str(atom));
-#endif // TQT_CHECK_STATE
-
- d->clear();
- return;
- }
-
- // Signal to other TQt processes that the selection has changed
- Window owners[2];
- owners[0] = newOwner;
- owners[1] = prevOwner;
- XChangeProperty( dpy, TQApplication::desktop()->screen(0)->winId(),
- sentinel_atom, XA_WINDOW, 32, PropModeReplace,
- (unsigned char*)&owners, 2 );
-}
-
-
-/*
- Called by the main event loop in qapplication_x11.cpp when the
- _TQT_SELECTION_SENTINEL property has been changed (i.e. when some TQt
- process has performed TQClipboard::setData(). If it returns TRUE, the
- TQClipBoard 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 TQt 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)
- */
-
- Window* owners;
- Atom actualType;
- int actualFormat;
- ulong nitems;
- ulong bytesLeft;
-
- if (XGetWindowProperty(TQPaintDevice::x11AppDisplay(),
- TQApplication::desktop()->screen(0)->winId(),
- qt_selection_sentinel, 0, 2, False, XA_WINDOW,
- &actualType, &actualFormat, &nitems,
- &bytesLeft, (unsigned char**)&owners) == Success) {
- if ( actualType == XA_WINDOW && actualFormat == 32 && nitems == 2 ) {
- Window win = owner->winId();
- 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 = TQApplication::clipboard()->startTimer( 0 );
- doIt = FALSE;
- } else {
- selectionData()->clear();
- }
- }
-
- return doIt;
-}
-
-
-bool qt_check_clipboard_sentinel()
-{
- bool doIt = TRUE;
- if (owner) {
- Window *owners;
- Atom actualType;
- int actualFormat;
- unsigned long nitems, bytesLeft;
-
- if (XGetWindowProperty(TQPaintDevice::x11AppDisplay(),
- TQApplication::desktop()->screen(0)->winId(),
- qt_clipboard_sentinel, 0, 2, False, XA_WINDOW,
- &actualType, &actualFormat, &nitems, &bytesLeft,
- (unsigned char **) &owners) == Success) {
- if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {
- Window win = owner->winId();
- 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 = TQApplication::clipboard()->startTimer( 0 );
- doIt = FALSE;
- } else {
- clipboardData()->clear();
- }
- }
-
- return doIt;
-}
-
-#endif // TQT_NO_CLIPBOARD
-
-#endif // USE_QT4