summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqdnd_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqdnd_x11.cpp1863
1 files changed, 0 insertions, 1863 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp b/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp
deleted file mode 100644
index 6292a07..0000000
--- a/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp
+++ /dev/null
@@ -1,1863 +0,0 @@
-/****************************************************************************
-**
-** XDND implementation for TQt. See http://www.cco.caltech.edu/~jafl/xdnd/
-**
-** Created : 980320
-**
-** 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.
-**
-**********************************************************************/
-
-#include "tqplatformdefs.h"
-
-#include "tqapplication.h"
-
-#ifndef TQT_NO_DRAGANDDROP
-
-#include "tqwidget.h"
-#include "tqintdict.h"
-#include "tqdatetime.h"
-#include "tqdict.h"
-#include "tqguardedptr.h"
-#include "tqdragobject.h"
-#include "tqobjectlist.h"
-#include "tqcursor.h"
-#include "tqbitmap.h"
-#include "tqpainter.h"
-
-#include "tqt_x11_p.h"
-
-// conflict resolution
-
-const int XKeyPress = KeyPress;
-const int XKeyRelease = KeyRelease;
-#undef KeyPress
-#undef KeyRelease
-
-// this stuff is copied from qapp_x11.cpp
-
-extern void qt_x11_intern_atom( const char *, Atom * );
-
-#if defined(TQ_C_CALLBACKS)
-extern "C" {
-#endif
-
-extern void qt_ignore_badwindow();
-extern bool qt_badwindow();
-extern void qt_enter_modal( TQWidget *widget );
-extern void qt_leave_modal( TQWidget *widget );
-
-#if defined(TQ_C_CALLBACKS)
-}
-#endif
-
-extern Window qt_x11_findClientWindow( Window, Atom, bool );
-extern Atom qt_wm_state;
-
-// this stuff is copied from qclb_x11.cpp
-
-extern bool qt_xclb_wait_for_event( Display *dpy, Window win, int type,
- XEvent *event, int timeout );
-extern bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
- bool deleteProperty,
- TQByteArray *buffer, int *size, Atom *type,
- int *format, bool nullterm );
-extern TQByteArray qt_xclb_read_incremental_property( Display *dpy, Window win,
- Atom property,
- int nbytes, bool nullterm );
-// and all this stuff is copied -into- qapp_x11.cpp
-
-void qt_xdnd_setup();
-void qt_handle_xdnd_enter( TQWidget *, const XEvent *, bool );
-void qt_handle_xdnd_position( TQWidget *, const XEvent *, bool );
-void qt_handle_xdnd_status( TQWidget *, const XEvent *, bool );
-void qt_handle_xdnd_leave( TQWidget *, const XEvent *, bool );
-void qt_handle_xdnd_drop( TQWidget *, const XEvent *, bool );
-void qt_handle_xdnd_finished( TQWidget *, const XEvent *, bool );
-void qt_xdnd_handle_selection_request( const XSelectionRequestEvent * );
-bool qt_xdnd_handle_badwindow();
-// client messages
-Atom qt_xdnd_enter;
-Atom qt_xdnd_position;
-Atom qt_xdnd_status;
-Atom qt_xdnd_leave;
-Atom qt_xdnd_drop;
-Atom qt_xdnd_finished;
-Atom qt_xdnd_type_list;
-const int qt_xdnd_version = 4;
-
-extern int qt_x11_translateButtonState( int s );
-
-// Actions
-//
-// The Xdnd spec allows for user-defined actions. This could be implemented
-// with a registration process in TQt. WE SHOULD do that later.
-//
-Atom qt_xdnd_action_copy;
-Atom qt_xdnd_action_link;
-Atom qt_xdnd_action_move;
-Atom qt_xdnd_action_private;
-static
-TQDropEvent::Action xdndaction_to_qtaction(Atom atom)
-{
- if ( atom == qt_xdnd_action_copy || atom == 0 )
- return TQDropEvent::Copy;
- if ( atom == qt_xdnd_action_link )
- return TQDropEvent::Link;
- if ( atom == qt_xdnd_action_move )
- return TQDropEvent::Move;
- return TQDropEvent::Private;
-}
-static
-int qtaction_to_xdndaction(TQDropEvent::Action a)
-{
- switch ( a ) {
- case TQDropEvent::Copy:
- return qt_xdnd_action_copy;
- case TQDropEvent::Link:
- return qt_xdnd_action_link;
- case TQDropEvent::Move:
- return qt_xdnd_action_move;
- case TQDropEvent::Private:
- return qt_xdnd_action_private;
- default:
- return qt_xdnd_action_copy;
- }
-}
-
-// clean up the stuff used.
-static void qt_xdnd_cleanup();
-
-static void qt_xdnd_send_leave();
-
-// XDND selection
-Atom qt_xdnd_selection;
-// other selection
-static Atom qt_selection_property;
-// INCR
-static Atom qt_incr_atom;
-
-// properties for XDND drop sites
-Atom qt_xdnd_aware;
-Atom qt_xdnd_proxy;
-
-// real variables:
-// xid of current drag source
-static Atom qt_xdnd_dragsource_xid = 0;
-
-// the types in this drop. 100 is no good, but at least it's big.
-const int qt_xdnd_max_type = 100;
-static Atom qt_xdnd_types[qt_xdnd_max_type];
-
-static TQIntDict<TQCString> * qt_xdnd_drag_types = 0;
-static TQDict<Atom> * qt_xdnd_atom_numbers = 0;
-
-// timer used when target wants "continuous" move messages (eg. scroll)
-static int heartbeat = -1;
-// rectangle in which the answer will be the same
-static TQRect qt_xdnd_source_sameanswer;
-//static TQRect qt_xdnd_target_sameanswer;
-static bool qt_xdnd_target_answerwas;
-// top-level window we sent position to last.
-static Window qt_xdnd_current_target;
-// window to send events to (always valid if qt_xdnd_current_target)
-static Window qt_xdnd_current_proxy_target;
-// widget we forwarded position to last, and local position
-static TQGuardedPtr<TQWidget> qt_xdnd_current_widget;
-static TQPoint qt_xdnd_current_position;
-// time of this drop, as type Atom to save on casts
-static Atom qt_xdnd_source_current_time;
-// timestamp from the XdndPosition and XdndDrop
-static Time qt_xdnd_target_current_time;
-// screen number containing the pointer... -1 means default
-static int qt_xdnd_current_screen = -1;
-// state of dragging... true if dragging, false if not
-bool qt_xdnd_dragging = FALSE;
-// need to check state of keyboard modifiers
-static bool need_modifiers_check = FALSE;
-
-// dict of payload data, sorted by type atom
-static TQIntDict<TQByteArray> * qt_xdnd_target_data = 0;
-
-// first drag object, or 0
-static TQDragObject * qt_xdnd_source_object = 0;
-
-// Motif dnd
-extern void qt_motifdnd_enable( TQWidget *, bool );
-extern TQByteArray qt_motifdnd_obtain_data( const char *format );
-extern const char *qt_motifdnd_format( int n );
-
-bool qt_motifdnd_active = FALSE;
-static bool dndCancelled = FALSE;
-
-// Shift/Ctrl handling, and final drop status
-static TQDragObject::DragMode drag_mode;
-static TQDropEvent::Action global_requested_action = TQDropEvent::Copy;
-static TQDropEvent::Action global_accepted_action = TQDropEvent::Copy;
-
-// for embedding only
-static TQWidget* current_embedding_widget = 0;
-static XEvent last_enter_event;
-
-// cursors
-static TQCursor *noDropCursor = 0;
-static TQCursor *moveCursor = 0;
-static TQCursor *copyCursor = 0;
-static TQCursor *linkCursor = 0;
-
-static TQPixmap *defaultPm = 0;
-
-static const int default_pm_hotx = -2;
-static const int default_pm_hoty = -16;
-static const char* const default_pm[] = {
-"13 9 3 1",
-". c None",
-" c #000000",
-"X c #FFFFFF",
-"X X X X X X X",
-" X X X X X X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X X X X X X ",
-"X X X X X X X"
-};
-
-#define WStyle_Tool Qt::Tool
-#define WStyle_NoBorder Qt::FramelessWindowHint
-
-class TQShapedPixmapWidget : public TQWidget {
-
-public:
- TQShapedPixmapWidget(int screen = -1) :
- TQWidget(TQApplication::desktop()->screen( screen ),
- 0, (Qt::WindowType)(WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM) ), oldpmser( 0 ), oldbmser( 0 )
- {
- x11SetWindowType( X11WindowTypeDND );
- }
-
- void setPixmap(TQPixmap pm, TQPoint hot)
- {
- int bmser = pm.mask() ? pm.mask()->serialNumber() : 0;
- if( oldpmser == pm.serialNumber() && oldbmser == bmser
- && oldhot == hot )
- return;
- oldpmser = pm.serialNumber();
- oldbmser = bmser;
- oldhot = hot;
- bool hotspot_in = !(hot.x() < 0 || hot.y() < 0 || hot.x() >= pm.width() || hot.y() >= pm.height());
-// if the pixmap has hotspot in its area, make a "hole" in it at that position
-// this will allow XTranslateCoordinates() to find directly the window below the cursor instead
-// of finding this pixmap, and therefore there won't be needed any (slow) search for the window
-// using findRealWindow()
- if( hotspot_in ) {
- TQBitmap mask = pm.mask() ? *pm.mask() : TQBitmap( pm.width(), pm.height());
- if( !pm.mask())
- mask.fill( TQt::color1 );
- TQPainter p( &mask );
- p.setPen( TQt::color0 );
- p.drawPoint( hot.x(), hot.y());
- p.end();
- pm.setMask( mask );
- setMask( mask );
- } else if ( pm.mask() ) {
- setMask( *pm.mask() );
- } else {
- clearMask();
- }
- resize(pm.width(),pm.height());
- setErasePixmap(pm);
- erase();
- }
-
-private:
- int oldpmser;
- int oldbmser;
- TQPoint oldhot;
-};
-
-static TQShapedPixmapWidget * qt_xdnd_deco = 0;
-
-static TQWidget* desktop_proxy = 0;
-
-class TQExtraWidget : public TQWidget
-{
-public:
- TQWExtra* extraData() { return TQWidget::extraData(); }
- TQTLWExtra* topData() { return TQWidget::topData(); }
-};
-
-
-static bool qt_xdnd_enable( TQWidget* w, bool on )
-{
- if ( on ) {
- TQWidget * xdnd_widget = 0;
- if ( w->isDesktop() ) {
- if ( desktop_proxy ) // *WE* already have one.
- return FALSE;
-
- // As per Xdnd4, use XdndProxy
- XGrabServer( w->x11Display() );
- Atom type = None;
- int f;
- unsigned long n, a;
- WId *proxy_id_ptr;
- XGetWindowProperty( w->x11Display(), w->winId(),
- qt_xdnd_proxy, 0, 1, False,
- XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id_ptr );
- WId proxy_id = 0;
- if ( type == XA_WINDOW && proxy_id_ptr ) {
- proxy_id = *proxy_id_ptr;
- XFree(proxy_id_ptr);
- proxy_id_ptr = 0;
- // Already exists. Real?
- qt_ignore_badwindow();
- XGetWindowProperty( w->x11Display(), proxy_id,
- qt_xdnd_proxy, 0, 1, False,
- XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id_ptr );
- if ( qt_badwindow() || type != XA_WINDOW || !proxy_id_ptr || *proxy_id_ptr != proxy_id ) {
- // Bogus - we will overwrite.
- proxy_id = 0;
- }
- }
- if ( proxy_id_ptr )
- XFree(proxy_id_ptr);
-
- if ( !proxy_id ) {
- xdnd_widget = desktop_proxy = new TQWidget;
- proxy_id = desktop_proxy->winId();
- XChangeProperty ( w->x11Display(),
- w->winId(), qt_xdnd_proxy,
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&proxy_id, 1 );
- XChangeProperty ( w->x11Display(),
- proxy_id, qt_xdnd_proxy,
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&proxy_id, 1 );
- }
-
- XUngrabServer( w->x11Display() );
- } else {
- xdnd_widget = w->tqtopLevelWidget();
- }
- if ( xdnd_widget ) {
- Atom atm = (Atom)qt_xdnd_version;
- XChangeProperty ( xdnd_widget->x11Display(), xdnd_widget->winId(),
- qt_xdnd_aware, XA_ATOM, 32, PropModeReplace,
- (unsigned char *)&atm, 1 );
- return TRUE;
- } else {
- return FALSE;
- }
- } else {
- if ( w->isDesktop() ) {
- XDeleteProperty( w->x11Display(), w->winId(),
- qt_xdnd_proxy );
- delete desktop_proxy;
- desktop_proxy = 0;
- }
- return TRUE;
- }
-}
-
-const char* qt_xdnd_atom_to_str( Atom a )
-{
- if ( !a ) return 0;
-
- if ( a == XA_STRING )
- return "text/plain"; // some Xdnd clients are dumb
-
- if ( !qt_xdnd_drag_types ) {
- qt_xdnd_drag_types = new TQIntDict<TQCString>( 17 );
- qt_xdnd_drag_types->setAutoDelete( TRUE );
- }
- TQCString* result;
- if ( !(result=qt_xdnd_drag_types->find( a )) ) {
- const char* mimeType = XGetAtomName( TQPaintDevice::x11AppDisplay(), a );
- if ( !mimeType )
- return 0; // only happens on protocol error
- result = new TQCString( mimeType );
- qt_xdnd_drag_types->insert( (long)a, result );
- XFree((void*)mimeType);
- }
- return *result;
-}
-
-Atom* qt_xdnd_str_to_atom( const char *mimeType )
-{
- if ( !mimeType || !*mimeType )
- return 0;
- if ( !qt_xdnd_atom_numbers ) {
- qt_xdnd_atom_numbers = new TQDict<Atom>( 17 );
- qt_xdnd_atom_numbers->setAutoDelete( TRUE );
- }
-
- Atom * result;
- if ( (result = qt_xdnd_atom_numbers->find( mimeType )) )
- return result;
-
- result = new Atom;
- *result = 0;
- qt_x11_intern_atom( mimeType, result );
- qt_xdnd_atom_numbers->insert( mimeType, result );
- qt_xdnd_atom_to_str( *result );
-
- return result;
-}
-
-
-void qt_xdnd_setup() {
- // set up protocol atoms
- qt_x11_intern_atom( "XdndEnter", &qt_xdnd_enter );
- qt_x11_intern_atom( "XdndPosition", &qt_xdnd_position );
- qt_x11_intern_atom( "XdndtqStatus", &qt_xdnd_status );
- qt_x11_intern_atom( "XdndLeave", &qt_xdnd_leave );
- qt_x11_intern_atom( "XdndDrop", &qt_xdnd_drop );
- qt_x11_intern_atom( "XdndFinished", &qt_xdnd_finished );
- qt_x11_intern_atom( "XdndTypeList", &qt_xdnd_type_list );
-
- qt_x11_intern_atom( "XdndSelection", &qt_xdnd_selection );
-
- qt_x11_intern_atom( "XdndAware", &qt_xdnd_aware );
- qt_x11_intern_atom( "XdndProxy", &qt_xdnd_proxy );
-
-
- qt_x11_intern_atom( "XdndActionCopy", &qt_xdnd_action_copy );
- qt_x11_intern_atom( "XdndActionLink", &qt_xdnd_action_link );
- qt_x11_intern_atom( "XdndActionMove", &qt_xdnd_action_move );
- qt_x11_intern_atom( "XdndActionPrivate", &qt_xdnd_action_private );
-
- qt_x11_intern_atom( "TQT_SELECTION", &qt_selection_property );
- qt_x11_intern_atom( "INCR", &qt_incr_atom );
-
- qAddPostRoutine( qt_xdnd_cleanup );
-}
-
-
-void qt_xdnd_cleanup()
-{
- delete qt_xdnd_drag_types;
- qt_xdnd_drag_types = 0;
- delete qt_xdnd_atom_numbers;
- qt_xdnd_atom_numbers = 0;
- delete qt_xdnd_target_data;
- qt_xdnd_target_data = 0;
- delete noDropCursor;
- noDropCursor = 0;
- delete copyCursor;
- copyCursor = 0;
- delete moveCursor;
- moveCursor = 0;
- delete linkCursor;
- linkCursor = 0;
- delete defaultPm;
- defaultPm = 0;
- delete desktop_proxy;
- desktop_proxy = 0;
-}
-
-
-static TQWidget * find_child( TQWidget * tlw, TQPoint & p )
-{
- TQWidget * w = tlw;
-
- p = w->mapFromGlobal( p );
- bool done = FALSE;
- while ( !done ) {
- done = TRUE;
- if ( ((TQExtraWidget*)w)->extraData() &&
- ((TQExtraWidget*)w)->extraData()->xDndProxy != 0 )
- break; // stop searching for widgets under the mouse cursor if found widget is a proxy.
- if ( !w->childrenListObject().isEmpty() ) {
- TQObjectListIt it( w->childrenListObject() );
- it.toLast();
- TQObject * o;
- while( (o=it.current()) ) {
- --it;
- if ( o->isWidgetType() &&
- ((TQWidget*)o)->isVisible() &&
- ((TQWidget*)o)->tqgeometry().contains( p ) &&
- !((TQWidget*)o)->isTopLevel()) {
- w = (TQWidget *)o;
- done = FALSE;
- p = w->mapFromParent( p );
- break;
- }
- }
- }
- }
- return w;
-}
-
-
-static bool checkEmbedded(TQWidget* w, const XEvent* xe)
-{
- if (!w)
- return FALSE;
-
- if (current_embedding_widget != 0 && current_embedding_widget != w) {
- qt_xdnd_current_target = ((TQExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
- qt_xdnd_current_proxy_target = qt_xdnd_current_target;
- qt_xdnd_send_leave();
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- current_embedding_widget = 0;
- }
-
- TQWExtra* extra = ((TQExtraWidget*)w)->extraData();
- if ( extra && extra->xDndProxy != 0 ) {
-
- if (current_embedding_widget != w) {
-
- last_enter_event.xany.window = extra->xDndProxy;
- XSendEvent( TQPaintDevice::x11AppDisplay(), extra->xDndProxy, False, NoEventMask,
- &last_enter_event );
- current_embedding_widget = w;
- }
-
- ((XEvent*)xe)->xany.window = extra->xDndProxy;
- XSendEvent( TQPaintDevice::x11AppDisplay(), extra->xDndProxy, False, NoEventMask,
- (XEvent*)xe );
- qt_xdnd_current_widget = w;
- return TRUE;
- }
- current_embedding_widget = 0;
- return FALSE;
-}
-
-void qt_handle_xdnd_enter( TQWidget *, const XEvent * xe, bool /*passive*/ )
-{
- //if ( !w->neveHadAChildWithDropEventsOn() )
- //return; // haven't been set up for dnd
-
- qt_motifdnd_active = FALSE;
-
- last_enter_event.xclient = xe->xclient;
-
- qt_xdnd_target_answerwas = FALSE;
-
- const long *l = xe->xclient.data.l;
- int version = (int)(((unsigned long)(l[1])) >> 24);
-
- if ( version > qt_xdnd_version )
- return;
-
- qt_xdnd_dragsource_xid = l[0];
-
- int j = 0;
- if ( l[1] & 1 ) {
- // get the types from XdndTypeList
- Atom type = None;
- int f;
- unsigned long n, a;
- Atom *data;
- XGetWindowProperty( TQPaintDevice::x11AppDisplay(), qt_xdnd_dragsource_xid,
- qt_xdnd_type_list, 0,
- qt_xdnd_max_type, False, XA_ATOM, &type, &f,&n,&a,(uchar**)&data );
- for ( ; j<qt_xdnd_max_type && j < (int)n; j++ ) {
- qt_xdnd_types[j] = data[j];
- }
- if ( data )
- XFree( (uchar*)data );
- } else {
- // get the types from the message
- int i;
- for( i=2; i < 5; i++ ) {
- qt_xdnd_types[j++] = l[i];
- }
- }
- qt_xdnd_types[j] = 0;
-}
-
-
-
-void qt_handle_xdnd_position( TQWidget *w, const XEvent * xe, bool passive )
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- TQPoint p( (l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff );
- TQWidget * c = find_child( w, p ); // changes p to to c-local coordinates
-
- if (!passive && checkEmbedded(c, xe))
- return;
-
- if ( !c || (!c->acceptDrops() && c->isDesktop()) ) {
- return;
- }
-
- if ( l[0] != qt_xdnd_dragsource_xid ) {
- //qDebug( "xdnd drag position from unexpected source (%08lx not %08lx)",
- // l[0], qt_xdnd_dragsource_xid );
- return;
- }
-
- if (l[3] != 0) {
- // timestamp from the source
- SET_QT_X_USER_TIME(l[3]);
- qt_xdnd_target_current_time = l[3];
- }
-
- XClientMessageEvent response;
- response.type = ClientMessage;
- response.window = qt_xdnd_dragsource_xid;
- response.format = 32;
- response.message_type = qt_xdnd_status;
- response.data.l[0] = w->winId();
- response.data.l[1] = 0; // flags
- response.data.l[2] = 0; // x, y
- response.data.l[3] = 0; // w, h
- response.data.l[4] = 0; // action
-
- if ( !passive ) { // otherwise just reject
- while ( c && !c->acceptDrops() && !c->isTopLevel() ) {
- p = c->mapToParent( p );
- c = c->parentWidget();
- }
-
- TQRect answerRect( c->mapToGlobal( p ), TQSize( 1,1 ) );
-
- TQDragMoveEvent me( p );
- TQDropEvent::Action accepted_action = xdndaction_to_qtaction(l[4]);
- me.setAction(accepted_action);
-
- if ( c != qt_xdnd_current_widget ) {
- qt_xdnd_target_answerwas = FALSE;
- if ( qt_xdnd_current_widget ) {
- TQDragLeaveEvent e;
- TQApplication::sendEvent( qt_xdnd_current_widget, &e );
- }
- if ( c->acceptDrops() ) {
- qt_xdnd_current_widget = c;
- qt_xdnd_current_position = p;
-
- TQDragEnterEvent de( p );
- de.setAction(accepted_action);
- TQApplication::sendEvent( c, &de );
- if ( de.isAccepted() ) {
- me.accept( de.answerRect() );
- if ( !de.isActionAccepted() ) // only as a copy (move if we del)
- accepted_action = TQDropEvent::Copy;
- else
- me.acceptAction(TRUE);
- } else {
- me.ignore( de.answerRect() );
- }
- }
- } else {
- if ( qt_xdnd_target_answerwas ) {
- me.accept();
- me.acceptAction(global_requested_action == global_accepted_action);
- }
- }
-
- if ( !c->acceptDrops() ) {
- qt_xdnd_current_widget = 0;
- answerRect = TQRect( p, TQSize( 1, 1 ) );
- } else if ( xdndaction_to_qtaction(l[4]) < TQDropEvent::Private ) {
- qt_xdnd_current_widget = c;
- qt_xdnd_current_position = p;
-
- TQApplication::sendEvent( c, &me );
- qt_xdnd_target_answerwas = me.isAccepted();
- if ( me.isAccepted() ) {
- response.data.l[1] = 1; // yes
- if ( !me.isActionAccepted() ) // only as a copy (move if we del)
- accepted_action = TQDropEvent::Copy;
- } else {
- response.data.l[0] = 0;
- }
- answerRect = me.answerRect().intersect( c->rect() );
- } else {
- response.data.l[0] = 0;
- answerRect = TQRect( p, TQSize( 1, 1 ) );
- }
- answerRect = TQRect( c->mapToGlobal( answerRect.topLeft() ),
- answerRect.size() );
-
- if ( answerRect.left() < 0 )
- answerRect.setLeft( 0 );
- if ( answerRect.right() > 4096 )
- answerRect.setRight( 4096 );
- if ( answerRect.top() < 0 )
- answerRect.setTop( 0 );
- if ( answerRect.bottom() > 4096 )
- answerRect.setBottom( 4096 );
- if ( answerRect.width() < 0 )
- answerRect.setWidth( 0 );
- if ( answerRect.height() < 0 )
- answerRect.setHeight( 0 );
-
- response.data.l[2] = (answerRect.x() << 16) + answerRect.y();
- response.data.l[3] = (answerRect.width() << 16) + answerRect.height();
- response.data.l[4] = qtaction_to_xdndaction(accepted_action);
- global_accepted_action = accepted_action;
- }
-
- // reset
- qt_xdnd_target_current_time = CurrentTime;
-
- TQWidget * source = TQWidget::find( qt_xdnd_dragsource_xid );
-
- if ( source && source->isDesktop() && !source->acceptDrops() )
- source = 0;
-
- if ( source )
- qt_handle_xdnd_status( source, (const XEvent *)&response, passive );
- else
- XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_dragsource_xid, False,
- NoEventMask, (XEvent*)&response );
-}
-
-
-void qt_handle_xdnd_status( TQWidget * w, const XEvent * xe, bool /*passive*/ )
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
- // Messy: TQDragResponseEvent is just a call to TQDragManager function
- global_accepted_action = xdndaction_to_qtaction(l[4]);
- TQDragResponseEvent e( (int)(l[1] & 1) );
- TQApplication::sendEvent( w, &e );
-
- if ( (int)(l[1] & 2) == 0 ) {
- TQPoint p( (l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff );
- TQSize s( (l[3] & 0xffff0000) >> 16, l[3] & 0x0000ffff );
- qt_xdnd_source_sameanswer = TQRect( p, s );
- if ( qt_xdnd_source_sameanswer.isNull() ) {
- // Application wants "coninutous" move events
- }
- } else {
- qt_xdnd_source_sameanswer = TQRect();
- }
-}
-
-
-void qt_handle_xdnd_leave( TQWidget *w, const XEvent * xe, bool /*passive*/ )
-{
- //qDebug( "xdnd leave" );
- if ( !qt_xdnd_current_widget ||
- w->tqtopLevelWidget() != qt_xdnd_current_widget->tqtopLevelWidget() ) {
- return; // sanity
- }
-
- if (checkEmbedded(current_embedding_widget, xe)) {
- current_embedding_widget = 0;
- qt_xdnd_current_widget = 0;
- return;
- }
-
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- TQDragLeaveEvent e;
- TQApplication::sendEvent( qt_xdnd_current_widget, &e );
-
- if ( l[0] != qt_xdnd_dragsource_xid ) {
- // This often happens - leave other-process window quickly
- //qDebug( "xdnd drag leave from unexpected source (%08lx not %08lx",
- //l[0], qt_xdnd_dragsource_xid );
- qt_xdnd_current_widget = 0;
- return;
- }
-
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_types[0] = 0;
- qt_xdnd_current_widget = 0;
-}
-
-
-void qt_xdnd_send_leave()
-{
- if ( !qt_xdnd_current_target )
- return;
-
- XClientMessageEvent leave;
- leave.type = ClientMessage;
- leave.window = qt_xdnd_current_target;
- leave.format = 32;
- leave.message_type = qt_xdnd_leave;
- leave.data.l[0] = qt_xdnd_dragsource_xid;
- leave.data.l[1] = 0; // flags
- leave.data.l[2] = 0; // x, y
- leave.data.l[3] = 0; // w, h
- leave.data.l[4] = 0; // just null
-
- TQWidget * w = TQWidget::find( qt_xdnd_current_proxy_target );
-
- if ( w && w->isDesktop() && !w->acceptDrops() )
- w = 0;
-
- if ( w )
- qt_handle_xdnd_leave( w, (const XEvent *)&leave, FALSE );
- else
- XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_current_proxy_target, False,
- NoEventMask, (XEvent*)&leave );
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
-}
-
-
-
-void qt_handle_xdnd_drop( TQWidget *, const XEvent * xe, bool passive )
-{
- if ( !qt_xdnd_current_widget ) {
- qt_xdnd_dragsource_xid = 0;
- return; // sanity
- }
-
- if (!passive && checkEmbedded(qt_xdnd_current_widget, xe)){
- current_embedding_widget = 0;
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_current_widget = 0;
- return;
- }
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- //qDebug( "xdnd drop" );
-
- if ( l[0] != qt_xdnd_dragsource_xid ) {
- //qDebug( "xdnd drop from unexpected source (%08lx not %08lx",
- // l[0], qt_xdnd_dragsource_xid );
- return;
- }
-
- if (l[2] != 0) {
- // update the "user time" from the timestamp in the event.
- SET_QT_X_USER_TIME(l[2]);
- qt_xdnd_target_current_time = l[2];
- }
-
- if ( qt_xdnd_source_object )
- qt_xdnd_source_object->setTarget( qt_xdnd_current_widget );
-
- if ( !passive ) {
- TQDropEvent de( qt_xdnd_current_position );
- de.setAction( global_accepted_action );
- TQApplication::sendEvent( qt_xdnd_current_widget, &de );
- if ( !de.isAccepted() ) {
- // Ignore a failed drag
- global_accepted_action = TQDropEvent::Copy;
- dndCancelled = TRUE;
- }
- XClientMessageEvent finished;
- finished.type = ClientMessage;
- finished.window = qt_xdnd_dragsource_xid;
- finished.format = 32;
- finished.message_type = qt_xdnd_finished;
- finished.data.l[0] = qt_xdnd_current_widget?qt_xdnd_current_widget->tqtopLevelWidget()->winId():0;
- finished.data.l[1] = 0; // flags
- XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_dragsource_xid, False,
- NoEventMask, (XEvent*)&finished );
- } else {
- TQDragLeaveEvent e;
- TQApplication::sendEvent( qt_xdnd_current_widget, &e );
- }
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_current_widget = 0;
-
- // reset
- qt_xdnd_target_current_time = CurrentTime;
-}
-
-
-void qt_handle_xdnd_finished( TQWidget *, const XEvent * xe, bool passive )
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- if ( l[0] && (l[0] == qt_xdnd_current_target
- || l[0] == qt_xdnd_current_proxy_target) ) {
- //
- if ( !passive )
- (void ) checkEmbedded( qt_xdnd_current_widget, xe);
- current_embedding_widget = 0;
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- delete qt_xdnd_source_object;
- qt_xdnd_source_object = 0;
- }
-}
-
-
-void TQDragManager::timerEvent( TQTimerEvent* e )
-{
- if ( e->timerId() == heartbeat ) {
- if( need_modifiers_check ) {
- Window root, child;
- int root_x, root_y, win_x, win_y;
- unsigned int mask;
- XQueryPointer( qt_xdisplay(), qt_xrootwin( qt_xdnd_current_screen ),
- &root, &child, &root_x, &root_y, &win_x, &win_y, &mask );
- if( updateMode( (ButtonState)qt_x11_translateButtonState( mask )))
- qt_xdnd_source_sameanswer = TQRect(); // force move
- }
- need_modifiers_check = TRUE;
- if( qt_xdnd_source_sameanswer.isNull() )
- move( TQCursor::pos() );
- }
-}
-
-static bool qt_xdnd_was_move = false;
-static bool qt_xdnd_found = false;
-// check whole incoming X queue for move events
-// checking whole queue is done by always returning False in the predicate
-// if there's another move event in the queue, and there's not a mouse button
-// or keyboard or ClientMessage event before it, the current move event
-// may be safely discarded
-// this helps avoiding being overloaded by being flooded from many events
-// from the XServer
-static
-Bool qt_xdnd_predicate( Display*, XEvent* ev, XPointer )
-{
- if( qt_xdnd_found )
- return False;
- if( ev->type == MotionNotify )
- {
- qt_xdnd_was_move = true;
- qt_xdnd_found = true;
- }
- if( ev->type == ButtonPress || ev->type == ButtonRelease
- || ev->type == XKeyPress || ev->type == XKeyRelease
- || ev->type == ClientMessage )
- {
- qt_xdnd_was_move = false;
- qt_xdnd_found = true;
- }
- return False;
-}
-
-static
-bool qt_xdnd_another_movement()
-{
- qt_xdnd_was_move = false;
- qt_xdnd_found = false;
- XEvent dummy;
- XCheckIfEvent( qt_xdisplay(), &dummy, qt_xdnd_predicate, NULL );
- return qt_xdnd_was_move;
-}
-
-bool TQDragManager::eventFilter( TQObject * o, TQEvent * e)
-{
- if ( beingCancelled ) {
- if ( e->type() == TQEvent::KeyRelease &&
- ((TQKeyEvent*)e)->key() == Key_Escape ) {
- tqApp->removeEventFilter( this );
- object = 0;
- dragSource = 0;
- beingCancelled = FALSE;
- tqApp->exit_loop();
- return TRUE; // block the key release
- }
- return FALSE;
- }
-
- TQ_ASSERT( object != 0 );
-
- if ( !o->isWidgetType() )
- return FALSE;
-
- if ( e->type() == TQEvent::MouseMove ) {
- TQMouseEvent* me = (TQMouseEvent *)e;
- if( !qt_xdnd_another_movement()) {
- updateMode(me->stateAfter());
- move( me->globalPos() );
- }
- need_modifiers_check = FALSE;
- return TRUE;
- } else if ( e->type() == TQEvent::MouseButtonRelease ) {
- tqApp->removeEventFilter( this );
- if ( willDrop )
- drop();
- else
- cancel();
- object = 0;
- dragSource = 0;
- beingCancelled = FALSE;
- tqApp->exit_loop();
- return TRUE;
- } else if ( e->type() == TQEvent::DragResponse ) {
- if ( ((TQDragResponseEvent *)e)->dragAccepted() ) {
- if ( !willDrop ) {
- willDrop = TRUE;
- }
- } else {
- if ( willDrop ) {
- willDrop = FALSE;
- }
- }
- updateCursor();
- return TRUE;
- }
-
- if ( e->type() == TQEvent::KeyPress
- || e->type() == TQEvent::KeyRelease )
- {
- TQKeyEvent *ke = ((TQKeyEvent*)e);
- if ( ke->key() == Key_Escape && e->type() == TQEvent::KeyPress ) {
- cancel();
- tqApp->removeEventFilter( this );
- object = 0;
- dragSource = 0;
- beingCancelled = FALSE;
- tqApp->exit_loop();
- } else {
- if( updateMode(ke->stateAfter())) {
- qt_xdnd_source_sameanswer = TQRect(); // force move
- move( TQCursor::pos() );
- }
- need_modifiers_check = FALSE;
- }
- return TRUE; // Eat all key events
- }
-
- // ### We bind modality to widgets, so we have to do this
- // ### "manually".
- // DnD is modal - eat all other interactive events
- switch ( e->type() ) {
- case TQEvent::MouseButtonPress:
- case TQEvent::MouseButtonRelease:
- case TQEvent::MouseButtonDblClick:
- case TQEvent::MouseMove:
- case TQEvent::KeyPress:
- case TQEvent::KeyRelease:
- case TQEvent::Wheel:
- case TQEvent::Accel:
- case TQEvent::AccelAvailable:
- case TQEvent::AccelOverride:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-
-static TQt::ButtonState oldstate;
-bool TQDragManager::updateMode( TQt::ButtonState newstate )
-{
- if ( newstate == oldstate )
- return false;
- const int both = ShiftButton|ControlButton;
- if ( (newstate & both) == both ) {
- global_requested_action = TQDropEvent::Link;
- } else {
- bool local = qt_xdnd_source_object != 0;
- if ( drag_mode == TQDragObject::DragMove )
- global_requested_action = TQDropEvent::Move;
- else if ( drag_mode == TQDragObject::DragCopy )
- global_requested_action = TQDropEvent::Copy;
- else if ( drag_mode == TQDragObject::DragLink )
- global_requested_action = TQDropEvent::Link;
- else {
- if ( drag_mode == TQDragObject::DragDefault && local )
- global_requested_action = TQDropEvent::Move;
- else
- global_requested_action = TQDropEvent::Copy;
- if ( newstate & ShiftButton )
- global_requested_action = TQDropEvent::Move;
- else if ( newstate & ControlButton )
- global_requested_action = TQDropEvent::Copy;
- }
- }
- oldstate = newstate;
- return true;
-}
-
-
-void TQDragManager::createCursors()
-{
- if ( !noDropCursor ) {
- noDropCursor = new TQCursor( Qt::ForbiddenCursor );
- if ( !pm_cursor[0].isNull() )
- moveCursor = new TQCursor(pm_cursor[0], 0,0);
- if ( !pm_cursor[1].isNull() )
- copyCursor = new TQCursor(pm_cursor[1], 0,0);
- if ( !pm_cursor[2].isNull() )
- linkCursor = new TQCursor(pm_cursor[2], 0,0);
- }
-}
-
-void TQDragManager::updateCursor()
-{
- TQCursor *c;
- if ( willDrop ) {
- if ( global_accepted_action == TQDropEvent::Copy ) {
- if ( global_requested_action == TQDropEvent::Move )
- c = moveCursor; // (source can delete)
- else
- c = copyCursor;
- } else if ( global_accepted_action == TQDropEvent::Link ) {
- c = linkCursor;
- } else {
- c = moveCursor;
- }
- if ( qt_xdnd_deco ) {
- qt_xdnd_deco->show();
- qt_xdnd_deco->raise();
- }
- } else {
- c = noDropCursor;
- //if ( qt_xdnd_deco )
- // qt_xdnd_deco->hide();
- }
-#ifndef TQT_NO_CURSOR
- if ( c )
- tqApp->setOverrideCursor( *c, TRUE );
-#endif
-}
-
-
-void TQDragManager::cancel( bool deleteSource )
-{
- killTimer( heartbeat );
- heartbeat = -1;
- if ( object ) {
- beingCancelled = TRUE;
- object = 0;
- }
-
- if ( qt_xdnd_current_target ) {
- qt_xdnd_send_leave();
- }
-
-#ifndef TQT_NO_CURSOR
- if ( restoreCursor ) {
- TQApplication::restoreOverrideCursor();
- restoreCursor = FALSE;
- }
-#endif
-
- if ( deleteSource )
- delete qt_xdnd_source_object;
- qt_xdnd_source_object = 0;
- delete qt_xdnd_deco;
- qt_xdnd_deco = 0;
-
- dndCancelled = TRUE;
-}
-
-static
-Window findRealWindow( const TQPoint & pos, Window w, int md )
-{
- if ( qt_xdnd_deco && w == qt_xdnd_deco->winId() )
- return 0;
-
- if ( md ) {
- qt_ignore_badwindow();
- XWindowAttributes attr;
- XGetWindowAttributes( TQPaintDevice::x11AppDisplay(), w, &attr );
- if (qt_badwindow())
- return 0;
-
- if ( attr.map_state == IsViewable
- && TQRect(attr.x,attr.y,attr.width,attr.height)
- .contains(pos) )
- {
- {
- Atom type = None;
- int f;
- unsigned long n, a;
- unsigned char *data;
-
- XGetWindowProperty( TQPaintDevice::x11AppDisplay(), w, qt_xdnd_aware, 0,
- 0, False, AnyPropertyType, &type, &f,&n,&a,&data );
- if ( data ) XFree(data);
- if ( type ) return w;
- }
-
- Window r, p;
- Window* c;
- uint nc;
- if ( XQueryTree( TQPaintDevice::x11AppDisplay(), w, &r, &p, &c, &nc ) ) {
- r=0;
- for (uint i=nc; !r && i--; ) {
- r = findRealWindow( pos-TQPoint(attr.x,attr.y),
- c[i], md-1 );
- }
- XFree(c);
- if ( r )
- return r;
-
- // We didn't find a client window! Just use the
- // innermost window.
- }
-
- // No tqchildren!
- return w;
- }
- }
- return 0;
-}
-
-void TQDragManager::move( const TQPoint & globalPos )
-{
- if (!object) {
- // perhaps the target crashed?
- return;
- }
-
- int screen = TQCursor::x11Screen();
- if ( ( qt_xdnd_current_screen == -1 && screen != TQPaintDevice::x11AppScreen() ) ||
- ( screen != qt_xdnd_current_screen ) ) {
- // recreate the pixmap on the new screen...
- delete qt_xdnd_deco;
- qt_xdnd_deco = new TQShapedPixmapWidget( screen );
- qt_xdnd_deco->x11SetWindowTransient( dragSource->tqtopLevelWidget());
- if (!TQWidget::mouseGrabber()) {
- updatePixmap();
- qt_xdnd_deco->grabMouse();
- }
- }
- updatePixmap( globalPos );
-
- if ( qt_xdnd_source_sameanswer.contains( globalPos ) &&
- qt_xdnd_source_sameanswer.isValid() ) {
- return;
- }
-
- qt_xdnd_current_screen = screen;
- Window rootwin = TQPaintDevice::x11AppRootWindow( qt_xdnd_current_screen );
- Window target = 0;
- int lx = 0, ly = 0;
- if ( !XTranslateCoordinates( TQPaintDevice::x11AppDisplay(), rootwin, rootwin,
- globalPos.x(), globalPos.y(),
- &lx, &ly, &target) )
- // some wierd error...
- return;
-
- if ( target == rootwin ) {
- // Ok.
- } else if ( target ) {
- //me
- Window src = rootwin;
- while (target != 0) {
- int lx2, ly2;
- Window t;
- // translate coordinates
- if (!XTranslateCoordinates(TQPaintDevice::x11AppDisplay(), src, target,
- lx, ly, &lx2, &ly2, &t)) {
- target = 0;
- break;
- }
- lx = lx2;
- ly = ly2;
- src = target;
-
- // check if it has XdndAware
- Atom type = None;
- int f;
- unsigned long n, a;
- unsigned char *data = 0;
- XGetWindowProperty(TQPaintDevice::x11AppDisplay(), target, qt_xdnd_aware, 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data);
- if (data)
- XFree(data);
- if (type)
- break;
-
- // find child at the coordinates
- if (!XTranslateCoordinates( TQPaintDevice::x11AppDisplay(), src, src,
- lx, ly, &lx2, &ly2, &target)) {
- target = 0;
- break;
- }
- }
- if ( qt_xdnd_deco && (!target || target == qt_xdnd_deco->winId()) ) {
- target = findRealWindow(globalPos,rootwin,6);
- }
- }
-
- TQWidget* w;
- if ( target ) {
- w = TQWidget::find( (WId)target );
- if ( w && w->isDesktop() && !w->acceptDrops() )
- w = 0;
- } else {
- w = 0;
- target = rootwin;
- }
-
- WId proxy_target = target;
- int target_version = 1;
-
- {
- Atom type = None;
- int r, f;
- unsigned long n, a;
- WId *proxy_id;
- qt_ignore_badwindow();
- r = XGetWindowProperty( qt_xdisplay(), target, qt_xdnd_proxy, 0,
- 1, False, XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id );
- if ( ( r != Success ) || qt_badwindow() ) {
- proxy_target = target = 0;
- } else if ( type == XA_WINDOW && proxy_id ) {
- proxy_target = *proxy_id;
- XFree(proxy_id);
- proxy_id = 0;
- r = XGetWindowProperty( qt_xdisplay(), proxy_target, qt_xdnd_proxy, 0,
- 1, False, XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id );
- if ( ( r != Success ) || qt_badwindow() || !type || !proxy_id || *proxy_id != proxy_target ) {
- // Bogus
- proxy_target = 0;
- target = 0;
- }
- if ( proxy_id )
- XFree(proxy_id);
- }
- if ( proxy_target ) {
- int *tv;
- qt_ignore_badwindow();
- r = XGetWindowProperty( qt_xdisplay(), proxy_target, qt_xdnd_aware, 0,
- 1, False, AnyPropertyType, &type, &f,&n,&a,(uchar**)&tv );
- if ( r != Success ) {
- target = 0;
- } else {
- target_version = TQMIN(qt_xdnd_version,tv ? *tv : 1);
- if ( tv )
- XFree( tv );
- if (!(!qt_badwindow() && type))
- target = 0;
- }
- }
- }
-
- if ( target != qt_xdnd_current_target ) {
- if ( qt_xdnd_current_target )
- qt_xdnd_send_leave();
-
- qt_xdnd_current_target = target;
- qt_xdnd_current_proxy_target = proxy_target;
- if ( target ) {
- TQMemArray<Atom> type;
- int flags = target_version << 24;
- const char* fmt;
- int nfmt=0;
- for (nfmt=0; (fmt=object->format(nfmt)); nfmt++) {
- type.resize(nfmt+1);
- type[nfmt] = *qt_xdnd_str_to_atom( fmt );
- }
- if ( nfmt >= 3 ) {
- XChangeProperty( TQPaintDevice::x11AppDisplay(),
- object->source()->winId(), qt_xdnd_type_list,
- XA_ATOM, 32, PropModeReplace,
- (unsigned char *)type.data(),
- type.size() );
- flags |= 0x0001;
- }
- XClientMessageEvent enter;
- enter.type = ClientMessage;
- enter.window = target;
- enter.format = 32;
- enter.message_type = qt_xdnd_enter;
- enter.data.l[0] = object->source()->winId();
- enter.data.l[1] = flags;
- enter.data.l[2] = type.size()>0 ? type[0] : 0;
- enter.data.l[3] = type.size()>1 ? type[1] : 0;
- enter.data.l[4] = type.size()>2 ? type[2] : 0;
- // provisionally set the rectangle to 5x5 pixels...
- qt_xdnd_source_sameanswer = TQRect( globalPos.x() - 2,
- globalPos.y() -2 , 5, 5 );
-
- if ( w ) {
- qt_handle_xdnd_enter( w, (const XEvent *)&enter, FALSE );
- } else if ( target ) {
- XSendEvent( TQPaintDevice::x11AppDisplay(), proxy_target, False, NoEventMask,
- (XEvent*)&enter );
- }
- }
- }
-
- if ( target ) {
- XClientMessageEvent move;
- move.type = ClientMessage;
- move.window = target;
- move.format = 32;
- move.message_type = qt_xdnd_position;
- move.window = target;
- move.data.l[0] = object->source()->winId();
- move.data.l[1] = 0; // flags
- move.data.l[2] = (globalPos.x() << 16) + globalPos.y();
- move.data.l[3] = GET_QT_X_TIME();
- move.data.l[4] = qtaction_to_xdndaction( global_requested_action );
-
- if ( w )
- qt_handle_xdnd_position( w, (const XEvent *)&move, FALSE );
- else
- XSendEvent( TQPaintDevice::x11AppDisplay(), proxy_target, False, NoEventMask,
- (XEvent*)&move );
- } else {
- if ( willDrop ) {
- willDrop = FALSE;
- updateCursor();
- }
- }
-}
-
-
-void TQDragManager::drop()
-{
- killTimer( heartbeat );
- heartbeat = -1;
- if ( !qt_xdnd_current_target )
- return;
-
- delete qt_xdnd_deco;
- qt_xdnd_deco = 0;
-
- XClientMessageEvent drop;
- drop.type = ClientMessage;
- drop.window = qt_xdnd_current_target;
- drop.format = 32;
- drop.message_type = qt_xdnd_drop;
- drop.data.l[0] = object->source()->winId();
- drop.data.l[1] = 0; // flags
- drop.data.l[2] = GET_QT_X_TIME();
- drop.data.l[3] = 0;
- drop.data.l[4] = 0;
-
- TQWidget * w = TQWidget::find( qt_xdnd_current_proxy_target );
-
- if ( w && w->isDesktop() && !w->acceptDrops() )
- w = 0;
-
- if ( w )
- qt_handle_xdnd_drop( w, (const XEvent *)&drop, FALSE );
- else
- XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_current_proxy_target, False,
- NoEventMask, (XEvent*)&drop );
-
-#ifndef TQT_NO_CURSOR
- if ( restoreCursor ) {
- TQApplication::restoreOverrideCursor();
- restoreCursor = FALSE;
- }
-#endif
-}
-
-
-
-bool qt_xdnd_handle_badwindow()
-{
- if ( qt_xdnd_source_object && qt_xdnd_current_target ) {
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- delete qt_xdnd_source_object;
- qt_xdnd_source_object = 0;
- delete qt_xdnd_deco;
- qt_xdnd_deco = 0;
- return TRUE;
- }
- if ( qt_xdnd_dragsource_xid ) {
- qt_xdnd_dragsource_xid = 0;
- if ( qt_xdnd_current_widget ) {
- TQDragLeaveEvent e;
- TQApplication::sendEvent( qt_xdnd_current_widget, &e );
- qt_xdnd_current_widget = 0;
- }
- return TRUE;
- }
- return FALSE;
-}
-
-
-/*!
- \class TQDragMoveEvent tqevent.h
- \ingroup events
- \ingroup draganddrop
- \brief The TQDragMoveEvent class provides an event which is sent while a drag and drop is in progress.
-
- When a widget \link TQWidget::setAcceptDrops() accepts drop
- events\endlink, it will receive this event repeatedly while the
- drag is within the widget's boundaries. The widget should examine
- the event to see what data it \link TQDragMoveEvent::provides()
- provides\endlink, and accept() the drop if appropriate.
-
- Note that this class inherits most of its functionality from
- TQDropEvent.
-*/
-
-
-/*!
- Returns TRUE if this event provides format \a mimeType; otherwise
- returns FALSE.
-
- \sa data()
-*/
-
-bool TQDropEvent::provides( const char *mimeType ) const
-{
- if ( qt_motifdnd_active && qstrnicmp( mimeType, "text/", 5 ) == 0 )
- return TRUE;
-
- int n=0;
- const char* f;
- do {
- f = format( n );
- if ( !f )
- return FALSE;
- n++;
- } while( qstricmp( mimeType, f ) );
- return TRUE;
-}
-
-void qt_xdnd_handle_selection_request( const XSelectionRequestEvent * req )
-{
- if ( !req )
- return;
- XEvent evt;
- evt.xselection.type = SelectionNotify;
- evt.xselection.display = req->display;
- evt.xselection.requestor = req->requestor;
- evt.xselection.selection = req->selection;
- evt.xselection.target = req->target;
- evt.xselection.property = None;
- evt.xselection.time = req->time;
- const char* format = qt_xdnd_atom_to_str( req->target );
- if ( format && qt_xdnd_source_object &&
- qt_xdnd_source_object->provides( format ) ) {
- TQByteArray a = qt_xdnd_source_object->tqencodedData(format);
- XChangeProperty ( TQPaintDevice::x11AppDisplay(), req->requestor, req->property,
- req->target, 8, PropModeReplace,
- (unsigned char *)a.data(), a.size() );
- evt.xselection.property = req->property;
- }
- // ### this can die if req->requestor crashes at the wrong
- // ### moment
- XSendEvent( TQPaintDevice::x11AppDisplay(), req->requestor, False, 0, &evt );
-}
-
-/*
- XChangeProperty ( TQPaintDevice::x11AppDisplay(), req->requestor, req->property,
- XA_STRING, 8,
- PropModeReplace,
- (uchar *)d->text(), strlen(d->text()) );
- evt.xselection.property = req->property;
-*/
-
-static TQByteArray qt_xdnd_obtain_data( const char *format )
-{
- TQByteArray result;
-
- TQWidget* w;
- if ( qt_xdnd_dragsource_xid && qt_xdnd_source_object &&
- (w=TQWidget::find( qt_xdnd_dragsource_xid ))
- && (!w->isDesktop() || w->acceptDrops()) )
- {
- TQDragObject * o = qt_xdnd_source_object;
- if ( o->provides( format ) )
- result = o->tqencodedData(format);
- return result;
- }
-
- Atom * a = qt_xdnd_str_to_atom( format );
- if ( !a || !*a )
- return result;
-
- if ( !qt_xdnd_target_data )
- qt_xdnd_target_data = new TQIntDict<TQByteArray>( 17 );
-
- if ( qt_xdnd_target_data->find( (int)*a ) ) {
- result = *(qt_xdnd_target_data->find( (int)*a ));
- } else {
- if ( XGetSelectionOwner( TQPaintDevice::x11AppDisplay(),
- qt_xdnd_selection ) == None )
- return result; // should never happen?
-
- TQWidget* tw = qt_xdnd_current_widget;
- if ( !qt_xdnd_current_widget ||
- qt_xdnd_current_widget->isDesktop() ) {
- tw = new TQWidget;
- }
- XConvertSelection( TQPaintDevice::x11AppDisplay(),
- qt_xdnd_selection,
- *a,
- qt_xdnd_selection,
- tw->winId(),
- qt_xdnd_target_current_time );
- XFlush( TQPaintDevice::x11AppDisplay() );
-
- XEvent xevent;
- bool got=qt_xclb_wait_for_event( TQPaintDevice::x11AppDisplay(),
- tw->winId(),
- SelectionNotify, &xevent, 5000);
- if ( got ) {
- Atom type;
-
- if ( qt_xclb_read_property( TQPaintDevice::x11AppDisplay(),
- tw->winId(),
- qt_xdnd_selection, TRUE,
- &result, 0, &type, 0, FALSE ) ) {
- if ( type == qt_incr_atom ) {
- int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
- result = qt_xclb_read_incremental_property( TQPaintDevice::x11AppDisplay(),
- tw->winId(),
- qt_xdnd_selection,
- nbytes, FALSE );
- } else if ( type != *a ) {
- // (includes None) qDebug( "TQt clipboard: unknown atom %ld", type);
- }
-#if 0
- // this needs to be matched by a qt_xdnd_target_data->clear()
- // when each drag is finished. for 2.0, we do the safe thing
- // and disable the entire caching.
- if ( type != None )
- qt_xdnd_target_data->insert( (int)((long)a), new TQByteArray(result) );
-#endif
- }
- }
- if ( !qt_xdnd_current_widget ||
- qt_xdnd_current_widget->isDesktop() ) {
- delete tw;
- }
- }
-
- return result;
-}
-
-
-/*
- Enable drag and drop for widget w by installing the proper
- properties on w's toplevel widget.
-*/
-bool qt_dnd_enable( TQWidget* w, bool on )
-{
- w = w->tqtopLevelWidget();
-
- if ( on ) {
- if ( ( (TQExtraWidget*)w)->topData()->dnd )
- return TRUE; // been there, done that
- ((TQExtraWidget*)w)->topData()->dnd = 1;
- }
-
- qt_motifdnd_enable( w, on );
- return qt_xdnd_enable( w, on );
-}
-
-
-/*!
- \class TQDropEvent tqevent.h
- \ingroup events
- \ingroup draganddrop
-
- \brief The TQDropEvent class provides an event which is sent when a drag and drop is completed.
-
- When a widget \link TQWidget::setAcceptDrops() accepts drop
- events\endlink, it will receive this event if it has accepted the
- most recent TQDragEnterEvent or TQDragMoveEvent sent to it.
-
- The widget should use data() to extract the data in an appropriate
- format.
-*/
-
-
-/*!
- \fn TQDropEvent::TQDropEvent (const TQPoint & pos, Type typ)
-
- Constructs a drop event that drops a drop of type \a typ on point
- \a pos.
-*/ // ### pos is in which coordinate system?
-
-
-/*!
- Returns a byte array containing the drag's data, in \a format.
-
- data() normally needs to get the data from the drag source, which
- is potentially very slow, so it's advisable to call this function
- only if you're sure that you will need the data in \a format.
-
- The resulting data will have a size of 0 if the format was not
- available.
-
- \sa format() TQByteArray::size()
-*/
-
-TQByteArray TQDropEvent::tqencodedData( const char *format ) const
-{
- if ( qt_motifdnd_active )
- return qt_motifdnd_obtain_data( format );
- return qt_xdnd_obtain_data( format );
-}
-
-/*!
- Returns a string describing one of the available data types for
- this drag. Common examples are "text/plain" and "image/gif". If \a
- n is less than zero or greater than the number of available data
- types, format() returns 0.
-
- This function is provided mainly for debugging. Most drop targets
- will use provides().
-
- \sa data() provides()
-*/
-
-const char* TQDropEvent::format( int n ) const
-{
- if ( qt_motifdnd_active )
- return qt_motifdnd_format( n );
-
- int i = 0;
- while( i<n && qt_xdnd_types[i] )
- i++;
- if ( i < n )
- return 0;
-
- const char* name = qt_xdnd_atom_to_str( qt_xdnd_types[i] );
- if ( !name )
- return 0; // should never happen
-
- return name;
-}
-
-bool TQDragManager::drag( TQDragObject * o, TQDragObject::DragMode mode )
-{
- if ( object == o || !o || !o->parent() )
- return FALSE;
-
- if ( object ) {
- cancel();
- tqApp->removeEventFilter( this );
- beingCancelled = FALSE;
- }
-
- if ( qt_xdnd_source_object ) {
- // the last drag and drop operation hasn't finished, so we are going to wait
- // for one second to see if it does... if the finish message comes after this,
- // then we could still have problems, but this is highly unlikely
- TQApplication::flushX();
-
- TQTime started = TQTime::currentTime();
- TQTime now = started;
- do {
- XEvent event;
- if ( XCheckTypedEvent( TQPaintDevice::x11AppDisplay(),
- ClientMessage, &event ) )
- tqApp->x11ProcessEvent( &event );
-
- now = TQTime::currentTime();
- if ( started > now ) // crossed midnight
- started = now;
-
- // 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 ( qt_xdnd_source_object && started.msecsTo(now) < 1000 );
- }
-
- qt_xdnd_source_object = o;
- qt_xdnd_source_object->setTarget( 0 );
- qt_xdnd_deco = new TQShapedPixmapWidget();
-
- willDrop = FALSE;
-
- object = o;
- updatePixmap();
-
- dragSource = (TQWidget *)(object->parent());
-
- qt_xdnd_deco->x11SetWindowTransient( dragSource->tqtopLevelWidget());
- tqApp->installEventFilter( this );
- qt_xdnd_source_current_time = GET_QT_X_TIME();
- XSetSelectionOwner( TQPaintDevice::x11AppDisplay(), qt_xdnd_selection,
- dragSource->tqtopLevelWidget()->winId(),
- qt_xdnd_source_current_time );
- oldstate = TQt::ButtonState(-1); // #### Should use state that caused the drag
- drag_mode = mode;
- global_accepted_action = TQDropEvent::Copy;
- updateMode(TQt::ButtonState(0));
- qt_xdnd_source_sameanswer = TQRect();
- move(TQCursor::pos());
- heartbeat = startTimer(200);
- need_modifiers_check = FALSE;
-
-#ifndef TQT_NO_CURSOR
- tqApp->setOverrideCursor( Qt::ArrowCursor );
- restoreCursor = TRUE;
- updateCursor();
-#endif
-
- dndCancelled = FALSE;
- qt_xdnd_dragging = TRUE;
-
- if (!TQWidget::mouseGrabber())
- qt_xdnd_deco->grabMouse();
-
- tqApp->enter_loop(); // Do the DND.
-
-#ifndef TQT_NO_CURSOR
- tqApp->restoreOverrideCursor();
-#endif
-
- delete qt_xdnd_deco;
- qt_xdnd_deco = 0;
- killTimer( heartbeat );
- heartbeat = -1;
- qt_xdnd_current_screen = -1;
- qt_xdnd_dragging = FALSE;
-
- return ((! dndCancelled) && // source del?
- (global_accepted_action == TQDropEvent::Copy &&
- global_requested_action == TQDropEvent::Move));
-
- // qt_xdnd_source_object persists until we get an xdnd_finish message
-}
-
-void TQDragManager::updatePixmap( const TQPoint& cursorPos )
-{
- if ( qt_xdnd_deco ) {
- TQPixmap pm;
- TQPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if ( object ) {
- pm = object->pixmap();
- if ( !pm.isNull() )
- pm_hot = object->pixmapHotSpot();
- }
- if ( pm.isNull() ) {
- if ( !defaultPm )
- defaultPm = new TQPixmap(default_pm);
- pm = *defaultPm;
- }
- qt_xdnd_deco->setPixmap(pm, pm_hot);
- qt_xdnd_deco->move(cursorPos-pm_hot);
- //if ( willDrop ) {
- qt_xdnd_deco->show();
- //} else {
- // qt_xdnd_deco->hide();
- //}
- }
-}
-
-void TQDragManager::updatePixmap()
-{
- updatePixmap( TQCursor::pos());
-}
-
-#endif // TQT_NO_DRAGANDDROP