src/gui/kernel/qdnd_x11.cpp File Reference

#include "qplatformdefs.h"
#include "qapplication.h"
#include "qwidget.h"
#include "qpixmap.h"
#include "qbitmap.h"
#include "qdesktopwidget.h"
#include "qevent.h"
#include "qdatetime.h"
#include "qiodevice.h"
#include "qpointer.h"
#include "qcursor.h"
#include "qvariant.h"
#include "qvector.h"
#include "qurl.h"
#include "qdebug.h"
#include "qimagewriter.h"
#include "qbuffer.h"
#include "qdnd_p.h"
#include "qt_x11_p.h"
#include "qx11info_x11.h"
#include "qwidget_p.h"
#include "qcursor_p.h"

Include dependency graph for qdnd_x11.cpp:

Go to the source code of this file.

Classes

class  QShapedPixmapWidget
struct  XdndData
class  QExtraWidget

Defines

#define DEBUG   if(0) qDebug
#define DNDDEBUG   if(0) qDebug()

Enumerations

enum  

Functions

static int findXdndDropTransactionByWindow (Window window)
static int findXdndDropTransactionByTime (Time timestamp)
static void restartXdndDropExpiryTimer ()
static Window findXdndAwareParent (Window window)
static void handle_xdnd_position (QWidget *, const XEvent *, bool)
static void handle_xdnd_status (QWidget *w, const XEvent *xe, bool)
static Qt::DropAction xdndaction_to_qtaction (Atom atom)
static int qtaction_to_xdndaction (Qt::DropAction a)
static void qt_xdnd_cleanup ()
static void qt_xdnd_send_leave ()
static WId xdndProxy (WId w)
static bool xdndEnable (QWidget *w, bool on)
static QWidgetfind_child (QWidget *tlw, QPoint &p)
static bool checkEmbedded (QWidget *w, const XEvent *xe)
static Bool xdnd_position_scanner (Display *, XEvent *event, XPointer)
static Bool xdnd_status_scanner (Display *, XEvent *event, XPointer)
static Window findRealWindow (const QPoint &pos, Window w, int md)
static QByteArray xdndObtainData (const char *format)

Variables

static int transaction_expiry_timer = -1
const int xdnd_version = 5
static Atom qt_xdnd_dragsource_xid = 0
const int qt_xdnd_max_type = 100
static Atom qt_xdnd_types [qt_xdnd_max_type+1]
static int heartbeat = -1
static QRect qt_xdnd_source_sameanswer
static Window qt_xdnd_current_target
static Window qt_xdnd_current_proxy_target
static Time qt_xdnd_source_current_time
static QPointer< QWidgetqt_xdnd_current_widget
static QPoint qt_xdnd_current_position
static Time qt_xdnd_target_current_time
static int qt_xdnd_current_screen = -1
bool qt_xdnd_dragging = false
static bool waiting_for_status = false
static Qt::DropAction last_target_accepted_action = Qt::IgnoreAction
static Qt::DropAction global_accepted_action = Qt::CopyAction
static Qt::DropActions possible_actions = Qt::IgnoreAction
static QWidgetcurrent_embedding_widget = 0
static XEvent last_enter_event
static QCursornoDropCursor = 0
static QCursormoveCursor = 0
static QCursorcopyCursor = 0
static QCursorlinkCursor = 0
static QPixmapdefaultPm = 0
static const int default_pm_hotx = -2
static const int default_pm_hoty = -16
static const char *const default_pm []
static XdndData xdnd_data = { 0, 0 }


Define Documentation

#define DEBUG   if(0) qDebug

Definition at line 57 of file qdnd_x11.cpp.

#define DNDDEBUG   if(0) qDebug()

Definition at line 63 of file qdnd_x11.cpp.

Referenced by QDragManager::move(), xdndEnable(), QX11Data::xdndHandleDrop(), and QX11Data::xdndHandleFinished().


Enumeration Type Documentation

anonymous enum

Definition at line 94 of file qdnd_x11.cpp.

00094 { XdndDropTransactionTimeout = 5000 }; // 5 seconds


Function Documentation

static bool checkEmbedded ( QWidget w,
const XEvent *  xe 
) [static]

Definition at line 702 of file qdnd_x11.cpp.

References current_embedding_widget, last_enter_event, qt_xdnd_current_proxy_target, qt_xdnd_current_target, qt_xdnd_current_widget, qt_xdnd_send_leave(), w, and X11.

Referenced by handle_xdnd_position(), QX11Data::xdndHandleDrop(), QX11Data::xdndHandleFinished(), and QX11Data::xdndHandleLeave().

00703 {
00704     if (!w)
00705         return false;
00706 
00707     if (current_embedding_widget != 0 && current_embedding_widget != w) {
00708         qt_xdnd_current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
00709         qt_xdnd_current_proxy_target = qt_xdnd_current_target;
00710         qt_xdnd_send_leave();
00711         qt_xdnd_current_target = 0;
00712         qt_xdnd_current_proxy_target = 0;
00713         current_embedding_widget = 0;
00714     }
00715 
00716     QWExtra* extra = ((QExtraWidget*)w)->extraData();
00717     if (extra && extra->xDndProxy != 0) {
00718 
00719         if (current_embedding_widget != w) {
00720 
00721             last_enter_event.xany.window = extra->xDndProxy;
00722             XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event);
00723             current_embedding_widget = w;
00724         }
00725 
00726         ((XEvent*)xe)->xany.window = extra->xDndProxy;
00727         XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe);
00728         if (qt_xdnd_current_widget != w) {
00729             qt_xdnd_current_widget = w;
00730         }
00731         return true;
00732     }
00733     current_embedding_widget = 0;
00734     return false;
00735 }

Here is the call graph for this function:

static QWidget* find_child ( QWidget tlw,
QPoint p 
) [static]

Definition at line 669 of file qdnd_x11.cpp.

References QObject::children(), i, QWidget::mapFromGlobal(), QWidget::mapFromParent(), p, qobject_cast< QWidget * >(), QObject::QObjectList(), and w.

Referenced by handle_xdnd_position().

00670 {
00671     QWidget *widget = tlw;
00672 
00673     p = widget->mapFromGlobal(p);
00674     bool done = false;
00675     while (!done) {
00676         done = true;
00677         if (((QExtraWidget*)widget)->extraData() &&
00678              ((QExtraWidget*)widget)->extraData()->xDndProxy != 0)
00679             break; // stop searching for widgets under the mouse cursor if found widget is a proxy.
00680         QObjectList children = widget->children();
00681         if (!children.isEmpty()) {
00682             for(int i = children.size(); i > 0;) {
00683                 --i;
00684                 QWidget *w = qobject_cast<QWidget *>(children.at(i));
00685                 if (!w)
00686                     continue;
00687                 if (w->isVisible() &&
00688                      w->geometry().contains(p) &&
00689                      !w->isWindow()) {
00690                     widget = w;
00691                     done = false;
00692                     p = widget->mapFromParent(p);
00693                     break;
00694                 }
00695             }
00696         }
00697     }
00698     return widget;
00699 }

Here is the call graph for this function:

static Window findRealWindow ( const QPoint pos,
Window  w,
int  md 
) [static]

Definition at line 1318 of file qdnd_x11.cpp.

References a, ATOM, c, data, XdndData::deco, i, QWidget::internalWinId(), n, p, type, w, X11, xdnd_data, and XNone.

Referenced by QDragManager::move().

01319 {
01320     if (xdnd_data.deco && w == xdnd_data.deco->internalWinId())
01321         return 0;
01322 
01323     if (md) {
01324         X11->ignoreBadwindow();
01325         XWindowAttributes attr;
01326         XGetWindowAttributes(X11->display, w, &attr);
01327         if (X11->badwindow())
01328             return 0;
01329 
01330         if (attr.map_state == IsViewable
01331             && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
01332             {
01333                 Atom   type = XNone;
01334                 int f;
01335                 unsigned long n, a;
01336                 unsigned char *data;
01337 
01338                 XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
01339                                    AnyPropertyType, &type, &f,&n,&a,&data);
01340                 if (data) XFree(data);
01341                 if (type)
01342                     return w;
01343             }
01344 
01345             Window r, p;
01346             Window* c;
01347             uint nc;
01348             if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
01349                 r=0;
01350                 for (uint i=nc; !r && i--;) {
01351                     r = findRealWindow(pos-QPoint(attr.x,attr.y),
01352                                         c[i], md-1);
01353                 }
01354                 XFree(c);
01355                 if (r)
01356                     return r;
01357 
01358                 // We didn't find a client window!  Just use the
01359                 // innermost window.
01360             }
01361 
01362             // No children!
01363             return w;
01364         }
01365     }
01366     return 0;
01367 }

Here is the call graph for this function:

static Window findXdndAwareParent ( Window  window  )  [static]

Definition at line 105 of file qdnd_x11.cpp.

References a, ATOM, data, n, Success, type, and X11.

Referenced by QX11Data::xdndHandleSelectionRequest().

00106 {
00107     Window target = 0;
00108     forever {
00109         // check if window has XdndAware
00110         Atom type = 0;
00111         int f;
00112         unsigned long n, a;
00113         unsigned char *data = 0;
00114         if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
00115                                AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
00116       if (data)
00117                 XFree(data);
00118       if (type) {
00119                 target = window;
00120                 break;
00121             }
00122         }
00123 
00124         // try window's parent
00125         Window root;
00126         Window parent;
00127         Window *children;
00128         uint unused;
00129         if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
00130             break;
00131         if (children)
00132             XFree(children);
00133         if (window == root)
00134             break;
00135         window = parent;
00136     }
00137     return target;
00138 }

static int findXdndDropTransactionByTime ( Time  timestamp  )  [static]

Definition at line 79 of file qdnd_x11.cpp.

References i, t, and X11.

Referenced by QX11Data::xdndHandleSelectionRequest().

00080 {
00081     int at = -1;
00082     for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
00083         const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
00084         if (t.timestamp == timestamp) {
00085             at = i;
00086             break;
00087         }
00088     }
00089     return at;
00090 }

static int findXdndDropTransactionByWindow ( Window  window  )  [static]

Definition at line 66 of file qdnd_x11.cpp.

References i, t, and X11.

Referenced by QX11Data::xdndHandleFinished(), and QX11Data::xdndHandleSelectionRequest().

00067 {
00068     int at = -1;
00069     for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
00070         const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
00071         if (t.target == window || t.proxy_target == window) {
00072             at = i;
00073             break;
00074         }
00075     }
00076     return at;
00077 }

static void handle_xdnd_position ( QWidget ,
const XEvent *  ,
bool   
) [static]

Definition at line 775 of file qdnd_x11.cpp.

References QDragMoveEvent::accept(), QWidget::acceptDrops(), QDragMoveEvent::answerRect(), ATOM, c, checkEmbedded(), QDragPrivate::data, DEBUG, Qt::Desktop, QDragManager::dragPrivate(), QDropEvent::dropAction(), QDragManager::dropData, QWidget::find(), find_child(), handle_xdnd_status(), Qt::IgnoreAction, QRect::intersected(), QEvent::isAccepted(), QApplication::keyboardModifiers(), l, last_target_accepted_action, QApplication::mouseButtons(), QDragManager::object, p, QDragPrivate::possible_actions, possible_actions, qt_xdnd_current_position, qt_xdnd_current_widget, qt_xdnd_dragsource_xid, qt_xdnd_target_current_time, qtaction_to_xdndaction(), QDragManager::self(), QCoreApplication::sendEvent(), QDropEvent::setDropAction(), QRect::setLeft(), w, QWidget::windowType(), X11, and xdndaction_to_qtaction().

Referenced by QDragManager::move(), and QX11Data::xdndHandlePosition().

00776 {
00777     const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
00778 
00779     QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
00780     QWidget * c = find_child(w, p); // changes p to to c-local coordinates
00781 
00782     if (!passive && checkEmbedded(c, xe))
00783         return;
00784 
00785     if (!c || !c->acceptDrops() && (c->windowType() == Qt::Desktop))
00786         return;
00787 
00788     if (l[0] != qt_xdnd_dragsource_xid) {
00789         DEBUG("xdnd drag position from unexpected source (%08lx not %08lx)", l[0], qt_xdnd_dragsource_xid);
00790         return;
00791     }
00792 
00793     if (l[3] != 0) {
00794         // timestamp from the source
00795         qt_xdnd_target_current_time = X11->userTime = l[3];
00796     }
00797 
00798     QDragManager *manager = QDragManager::self();
00799     QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData;
00800 
00801     XClientMessageEvent response;
00802     response.type = ClientMessage;
00803     response.window = qt_xdnd_dragsource_xid;
00804     response.format = 32;
00805     response.message_type = ATOM(XdndStatus);
00806     response.data.l[0] = w->internalWinId();
00807     response.data.l[1] = 0; // flags
00808     response.data.l[2] = 0; // x, y
00809     response.data.l[3] = 0; // w, h
00810     response.data.l[4] = 0; // action
00811 
00812     if (!passive) { // otherwise just reject
00813         while (c && !c->acceptDrops() && !c->isWindow()) {
00814             p = c->mapToParent(p);
00815             c = c->parentWidget();
00816         }
00817         QWidget *target_widget = c && c->acceptDrops() ? c : 0;
00818 
00819         QRect answerRect(c->mapToGlobal(p), QSize(1,1));
00820 
00821         if (manager->object) {
00822             possible_actions = manager->dragPrivate()->possible_actions;
00823         } else {
00824             possible_actions = Qt::DropActions(xdndaction_to_qtaction(l[4]));
00825 //             possible_actions |= Qt::CopyAction;
00826         }
00827         QDragMoveEvent me(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
00828 
00829         Qt::DropAction accepted_action = Qt::IgnoreAction;
00830 
00831 
00832         if (target_widget != qt_xdnd_current_widget) {
00833             if (qt_xdnd_current_widget) {
00834                 QDragLeaveEvent e;
00835                 QApplication::sendEvent(qt_xdnd_current_widget, &e);
00836             }
00837             if (qt_xdnd_current_widget != target_widget) {
00838                 qt_xdnd_current_widget = target_widget;
00839             }
00840             if (target_widget) {
00841                 qt_xdnd_current_position = p;
00842 
00843                 last_target_accepted_action = Qt::IgnoreAction;
00844                 QDragEnterEvent de(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
00845                 QApplication::sendEvent(target_widget, &de);
00846                 if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
00847                     last_target_accepted_action = de.dropAction();
00848             }
00849         }
00850 
00851         DEBUG() << "qt_handle_xdnd_position action=" << X11->xdndAtomToString(l[4]);
00852         if (!target_widget) {
00853             answerRect = QRect(p, QSize(1, 1));
00854         } else {
00855             qt_xdnd_current_widget = c;
00856             qt_xdnd_current_position = p;
00857 
00858             if (last_target_accepted_action != Qt::IgnoreAction) {
00859                 me.setDropAction(last_target_accepted_action);
00860                 me.accept();
00861             }
00862             QApplication::sendEvent(c, &me);
00863             if (me.isAccepted()) {
00864                 response.data.l[1] = 1; // yes
00865                 accepted_action = me.dropAction();
00866                 last_target_accepted_action = accepted_action;
00867             } else {
00868                 response.data.l[0] = 0;
00869                 last_target_accepted_action = Qt::IgnoreAction;
00870             }
00871             answerRect = me.answerRect().intersected(c->rect());
00872         }
00873         answerRect = QRect(c->mapToGlobal(answerRect.topLeft()), answerRect.size());
00874 
00875         if (answerRect.left() < 0)
00876             answerRect.setLeft(0);
00877         if (answerRect.right() > 4096)
00878             answerRect.setRight(4096);
00879         if (answerRect.top() < 0)
00880             answerRect.setTop(0);
00881         if (answerRect.bottom() > 4096)
00882             answerRect.setBottom(4096);
00883         if (answerRect.width() < 0)
00884             answerRect.setWidth(0);
00885         if (answerRect.height() < 0)
00886             answerRect.setHeight(0);
00887 
00888         response.data.l[2] = (answerRect.x() << 16) + answerRect.y();
00889         response.data.l[3] = (answerRect.width() << 16) + answerRect.height();
00890         response.data.l[4] = qtaction_to_xdndaction(accepted_action);
00891     }
00892 
00893     // reset
00894     qt_xdnd_target_current_time = CurrentTime;
00895 
00896     QWidget * source = QWidget::find(qt_xdnd_dragsource_xid);
00897     if (source && (source->windowType() == Qt::Desktop) && !source->acceptDrops())
00898         source = 0;
00899 
00900     DEBUG() << "sending XdndStatus";
00901     if (source)
00902         handle_xdnd_status(source, (const XEvent *)&response, passive);
00903     else
00904         XSendEvent(X11->display, qt_xdnd_dragsource_xid, False, NoEventMask, (XEvent*)&response);
00905 }

Here is the call graph for this function:

static void handle_xdnd_status ( QWidget w,
const XEvent *  xe,
bool   
) [static]

Definition at line 929 of file qdnd_x11.cpp.

References QDragManager::emitActionChanged(), global_accepted_action, Qt::IgnoreAction, l, p, qt_xdnd_current_proxy_target, qt_xdnd_source_sameanswer, s, QDragManager::self(), QDragManager::updateCursor(), waiting_for_status, QDragManager::willDrop, and xdndaction_to_qtaction().

Referenced by handle_xdnd_position(), and QX11Data::xdndHandleStatus().

00930 {
00931     const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
00932     // ignore late status messages
00933     if (l[0] && l[0] != qt_xdnd_current_proxy_target)
00934         return;
00935     Qt::DropAction newAction = (l[1] & 0x1) ? xdndaction_to_qtaction(l[4]) : Qt::IgnoreAction;
00936 
00937     if ((int)(l[1] & 2) == 0) {
00938         QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
00939         QSize s((l[3] & 0xffff0000) >> 16, l[3] & 0x0000ffff);
00940         qt_xdnd_source_sameanswer = QRect(p, s);
00941     } else {
00942         qt_xdnd_source_sameanswer = QRect();
00943     }
00944     QDragManager *manager = QDragManager::self();
00945     manager->willDrop = (l[1] & 0x1);
00946     if (global_accepted_action != newAction)
00947         manager->emitActionChanged(newAction);
00948     global_accepted_action = newAction;
00949     manager->updateCursor();
00950     waiting_for_status = false;
00951 }

Here is the call graph for this function:

void qt_xdnd_cleanup (  )  [static]

Definition at line 650 of file qdnd_x11.cpp.

References copyCursor, XdndData::deco, defaultPm, XdndData::desktop_proxy, linkCursor, moveCursor, noDropCursor, and xdnd_data.

Referenced by QX11Data::xdndSetup().

00651 {
00652     delete noDropCursor;
00653     noDropCursor = 0;
00654     delete copyCursor;
00655     copyCursor = 0;
00656     delete moveCursor;
00657     moveCursor = 0;
00658     delete linkCursor;
00659     linkCursor = 0;
00660     delete defaultPm;
00661     defaultPm = 0;
00662     delete xdnd_data.desktop_proxy;
00663     xdnd_data.desktop_proxy = 0;
00664     delete xdnd_data.deco;
00665     xdnd_data.deco = 0;
00666 }

void qt_xdnd_send_leave (  )  [static]

Definition at line 1007 of file qdnd_x11.cpp.

References ATOM, Qt::Desktop, QDragManager::emitActionChanged(), QWidget::find(), global_accepted_action, Qt::IgnoreAction, qt_xdnd_current_proxy_target, qt_xdnd_current_target, qt_xdnd_dragsource_xid, qt_xdnd_source_current_time, QDragManager::self(), QDragManager::updateCursor(), w, waiting_for_status, QDragManager::willDrop, and X11.

Referenced by QDragManager::cancel(), checkEmbedded(), and QDragManager::move().

01008 {
01009     if (!qt_xdnd_current_target)
01010         return;
01011 
01012     XClientMessageEvent leave;
01013     leave.type = ClientMessage;
01014     leave.window = qt_xdnd_current_target;
01015     leave.format = 32;
01016     leave.message_type = ATOM(XdndLeave);
01017     leave.data.l[0] = qt_xdnd_dragsource_xid;
01018     leave.data.l[1] = 0; // flags
01019     leave.data.l[2] = 0; // x, y
01020     leave.data.l[3] = 0; // w, h
01021     leave.data.l[4] = 0; // just null
01022 
01023     QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
01024 
01025     if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
01026         w = 0;
01027 
01028     if (w)
01029         X11->xdndHandleLeave(w, (const XEvent *)&leave, false);
01030     else
01031         XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
01032                     NoEventMask, (XEvent*)&leave);
01033     // reset the drag manager state
01034     QDragManager *manager = QDragManager::self();
01035     manager->willDrop = false;
01036     if (global_accepted_action != Qt::IgnoreAction)
01037         manager->emitActionChanged(Qt::IgnoreAction);
01038     global_accepted_action = Qt::IgnoreAction;
01039     manager->updateCursor();
01040     qt_xdnd_current_target = 0;
01041     qt_xdnd_current_proxy_target = 0;
01042     qt_xdnd_source_current_time = 0;
01043     waiting_for_status = false;
01044 }

Here is the call graph for this function:

static int qtaction_to_xdndaction ( Qt::DropAction  a  )  [static]

Definition at line 161 of file qdnd_x11.cpp.

References ATOM, Qt::CopyAction, Qt::IgnoreAction, Qt::LinkAction, Qt::MoveAction, Qt::TargetMoveAction, and XNone.

Referenced by handle_xdnd_position(), QDragManager::move(), and QX11Data::xdndHandleDrop().

00162 {
00163     switch (a) {
00164     case Qt::CopyAction:
00165         return ATOM(XdndActionCopy);
00166     case Qt::LinkAction:
00167         return ATOM(XdndActionLink);
00168     case Qt::MoveAction:
00169     case Qt::TargetMoveAction:
00170         return ATOM(XdndActionMove);
00171     case Qt::IgnoreAction:
00172         return XNone;
00173     default:
00174         return ATOM(XdndActionCopy);
00175     }
00176 }

static void restartXdndDropExpiryTimer (  )  [static]

Definition at line 96 of file qdnd_x11.cpp.

References QObject::killTimer(), QDragManager::self(), QObject::startTimer(), transaction_expiry_timer, and XdndDropTransactionTimeout.

Referenced by QDragManager::drop(), QX11Data::xdndHandleFinished(), and QX11Data::xdndHandleSelectionRequest().

Here is the call graph for this function:

static Bool xdnd_position_scanner ( Display ,
XEvent *  event,
XPointer   
) [static]

Definition at line 907 of file qdnd_x11.cpp.

References ATOM.

Referenced by QX11Data::xdndHandlePosition().

00908 {
00909     if (event->type != ClientMessage)
00910         return false;
00911     XClientMessageEvent *ev = &event->xclient;
00912 
00913     if (ev->message_type == ATOM(XdndPosition))
00914         return true;
00915 
00916     return false;
00917 }

static Bool xdnd_status_scanner ( Display ,
XEvent *  event,
XPointer   
) [static]

Definition at line 953 of file qdnd_x11.cpp.

References ATOM.

Referenced by QX11Data::xdndHandleStatus().

00954 {
00955     if (event->type != ClientMessage)
00956         return false;
00957     XClientMessageEvent *ev = &event->xclient;
00958 
00959     if (ev->message_type == ATOM(XdndStatus))
00960         return true;
00961 
00962     return false;
00963 }

static Qt::DropAction xdndaction_to_qtaction ( Atom  atom  )  [static]

Definition at line 150 of file qdnd_x11.cpp.

References ATOM, Qt::CopyAction, Qt::LinkAction, and Qt::MoveAction.

Referenced by handle_xdnd_position(), and handle_xdnd_status().

00151 {
00152     if (atom == ATOM(XdndActionCopy) || atom == 0)
00153         return Qt::CopyAction;
00154     if (atom == ATOM(XdndActionLink))
00155         return Qt::LinkAction;
00156     if (atom == ATOM(XdndActionMove))
00157         return Qt::MoveAction;
00158     return Qt::CopyAction;
00159 }

static bool xdndEnable ( QWidget w,
bool  on 
) [static]

Definition at line 321 of file qdnd_x11.cpp.

References ATOM, Qt::Desktop, XdndData::desktop_proxy, DNDDEBUG, QWidget::internalWinId(), QWidget::testAttribute(), w, Qt::WA_WState_Created, QWidget::WId(), X11, xdnd_data, xdnd_version, and xdndProxy().

Referenced by QX11Data::dndEnable().

00322 {
00323     DNDDEBUG << "xdndEnable" << w << on;
00324     if (on) {
00325         QWidget * xdnd_widget = 0;
00326         if ((w->windowType() == Qt::Desktop)) {
00327             if (xdnd_data.desktop_proxy) // *WE* already have one.
00328                 return false;
00329 
00330             // As per Xdnd4, use XdndProxy
00331             XGrabServer(X11->display);
00332             Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
00333             WId proxy_id = xdndProxy(w->internalWinId());
00334 
00335             if (!proxy_id) {
00336                 xdnd_widget = xdnd_data.desktop_proxy = new QWidget;
00337                 proxy_id = xdnd_data.desktop_proxy->internalWinId();
00338                 XChangeProperty (X11->display, w->internalWinId(), ATOM(XdndProxy),
00339                                  XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
00340                 XChangeProperty (X11->display, proxy_id, ATOM(XdndProxy),
00341                                  XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
00342             }
00343 
00344             XUngrabServer(X11->display);
00345         } else {
00346             xdnd_widget = w->window();
00347         }
00348         if (xdnd_widget) {
00349             DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->internalWinId();
00350             Atom atm = (Atom)xdnd_version;
00351             Q_ASSERT(xdnd_widget->testAttribute(Qt::WA_WState_Created));
00352             XChangeProperty(X11->display, xdnd_widget->internalWinId(), ATOM(XdndAware),
00353                              XA_ATOM, 32, PropModeReplace, (unsigned char *)&atm, 1);
00354             return true;
00355         } else {
00356             return false;
00357         }
00358     } else {
00359         if ((w->windowType() == Qt::Desktop)) {
00360             XDeleteProperty(X11->display, w->internalWinId(), ATOM(XdndProxy));
00361             delete xdnd_data.desktop_proxy;
00362             xdnd_data.desktop_proxy = 0;
00363         } else {
00364             DNDDEBUG << "not deleting XDndAware";
00365         }
00366         return true;
00367     }
00368 }

Here is the call graph for this function:

static QByteArray xdndObtainData ( const char *  format  )  [static]

Definition at line 1728 of file qdnd_x11.cpp.

References a, QList< T >::append(), ATOM, QByteArray::data(), DEBUG, Qt::Desktop, QDragManager::dragPrivate(), QWidget::find(), i, INCR, QWidget::internalWinId(), o, QDragManager::object, qt_xdnd_current_widget, qt_xdnd_dragsource_xid, qt_xdnd_target_current_time, qt_xdnd_types, QDragManager::self(), QByteArray::size(), type, w, X11, and XNone.

Referenced by QDropData::retrieveData_sys().

01729 {
01730     QByteArray result;
01731 
01732     QWidget* w;
01733     QDragManager *manager = QDragManager::self();
01734     if (qt_xdnd_dragsource_xid && manager->object &&
01735          (w=QWidget::find(qt_xdnd_dragsource_xid))
01736          && (!(w->windowType() == Qt::Desktop) || w->acceptDrops()))
01737     {
01738         QDragPrivate * o = QDragManager::self()->dragPrivate();
01739         if (o->data->hasFormat(QLatin1String(format)))
01740             result = o->data->data(QLatin1String(format));
01741         return result;
01742     }
01743 
01744     QList<Atom> atoms;
01745     int i = 0;
01746     while ((qt_xdnd_types[i])) {
01747         atoms.append(qt_xdnd_types[i]);
01748         ++i;
01749     }
01750     Atom a = X11->xdndMimeAtomForFormat(QLatin1String(format), atoms);
01751     if (!a)
01752         return result;
01753 
01754     if (XGetSelectionOwner(X11->display, ATOM(XdndSelection)) == XNone)
01755         return result; // should never happen?
01756 
01757     QWidget* tw = qt_xdnd_current_widget;
01758     if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
01759         tw = new QWidget;
01760 
01761     XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->internalWinId(),
01762                       qt_xdnd_target_current_time);
01763     XFlush(X11->display);
01764 
01765     XEvent xevent;
01766     bool got=X11->clipboardWaitForEvent(tw->internalWinId(), SelectionNotify, &xevent, 5000);
01767     if (got) {
01768         Atom type;
01769 
01770         if (X11->clipboardReadProperty(tw->internalWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0, false)) {
01771             if (type == ATOM(INCR)) {
01772                 int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
01773                 result = X11->clipboardReadIncrementalProperty(tw->internalWinId(), ATOM(XdndSelection), nbytes, false);
01774             } else if (type != a && type != XNone) {
01775                 DEBUG("Qt clipboard: unknown atom %ld", type);
01776             }
01777         }
01778     }
01779     if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
01780         delete tw;
01781 
01782     return X11->xdndMimeConvertToFormat(a, result, QLatin1String(format));
01783 }

Here is the call graph for this function:

static WId xdndProxy ( WId  w  )  [static]

Definition at line 295 of file qdnd_x11.cpp.

References a, ATOM, n, type, QWidget::WId(), X11, and XNone.

Referenced by QDragManager::move(), and xdndEnable().

00296 {
00297     Atom type = XNone;
00298     int f;
00299     unsigned long n, a;
00300     WId *proxy_id_ptr;
00301     XGetWindowProperty(X11->display, w, ATOM(XdndProxy), 0, 1, False,
00302                        XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id_ptr);
00303     WId proxy_id = 0;
00304     if (type == XA_WINDOW && proxy_id_ptr) {
00305         proxy_id = *proxy_id_ptr;
00306         XFree(proxy_id_ptr);
00307         proxy_id_ptr = 0;
00308         // Already exists. Real?
00309         X11->ignoreBadwindow();
00310         XGetWindowProperty(X11->display, proxy_id, ATOM(XdndProxy), 0, 1, False,
00311                            XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id_ptr);
00312         if (X11->badwindow() || type != XA_WINDOW || !proxy_id_ptr || *proxy_id_ptr != proxy_id)
00313             // Bogus - we will overwrite.
00314             proxy_id = 0;
00315     }
00316     if (proxy_id_ptr)
00317         XFree(proxy_id_ptr);
00318     return proxy_id;
00319 }

Here is the call graph for this function:


Variable Documentation

QCursor* copyCursor = 0 [static]

Definition at line 227 of file qdnd_x11.cpp.

Referenced by QDragManager::drag(), qt_xdnd_cleanup(), and QDragManager::updateCursor().

QWidget* current_embedding_widget = 0 [static]

Definition at line 221 of file qdnd_x11.cpp.

Referenced by checkEmbedded(), QDragManager::drop(), QX11Data::xdndHandleDrop(), QX11Data::xdndHandleFinished(), and QX11Data::xdndHandleLeave().

const char* const default_pm[] [static]

Initial value:

 {
"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"
}

Definition at line 234 of file qdnd_x11.cpp.

Referenced by QDragManager::updatePixmap().

const int default_pm_hotx = -2 [static]

Definition at line 232 of file qdnd_x11.cpp.

Referenced by QDragManager::updatePixmap().

const int default_pm_hoty = -16 [static]

Definition at line 233 of file qdnd_x11.cpp.

Referenced by QDragManager::updatePixmap().

QPixmap* defaultPm = 0 [static]

Definition at line 230 of file qdnd_x11.cpp.

Referenced by qt_xdnd_cleanup(), and QDragManager::updatePixmap().

Qt::DropAction global_accepted_action = Qt::CopyAction [static]

Definition at line 217 of file qdnd_x11.cpp.

Referenced by QDragManager::cancel(), QDragManager::drag(), handle_xdnd_status(), qt_xdnd_send_leave(), QDragManager::updateCursor(), and QX11Data::xdndHandleDrop().

int heartbeat = -1 [static]

Definition at line 192 of file qdnd_x11.cpp.

Referenced by QDragManager::cancel(), QDragManager::drag(), QDragManager::drop(), and QDragManager::timerEvent().

XEvent last_enter_event [static]

Definition at line 222 of file qdnd_x11.cpp.

Referenced by checkEmbedded(), and QX11Data::xdndHandleEnter().

Qt::DropAction last_target_accepted_action = Qt::IgnoreAction [static]

Definition at line 214 of file qdnd_x11.cpp.

Referenced by handle_xdnd_position().

QCursor* linkCursor = 0 [static]

Definition at line 228 of file qdnd_x11.cpp.

Referenced by QDragManager::drag(), qt_xdnd_cleanup(), and QDragManager::updateCursor().

QCursor* moveCursor = 0 [static]

Definition at line 226 of file qdnd_x11.cpp.

Referenced by QDragManager::drag(), qt_xdnd_cleanup(), and QDragManager::updateCursor().

QCursor* noDropCursor = 0 [static]

Definition at line 225 of file qdnd_x11.cpp.

Referenced by QDragManager::drag(), qt_xdnd_cleanup(), and QDragManager::updateCursor().

Qt::DropActions possible_actions = Qt::IgnoreAction [static]

Definition at line 218 of file qdnd_x11.cpp.

Referenced by handle_xdnd_position(), QDragManager::move(), and QX11Data::xdndHandleDrop().

QPoint qt_xdnd_current_position [static]

Definition at line 203 of file qdnd_x11.cpp.

Referenced by handle_xdnd_position(), and QX11Data::xdndHandleDrop().

Window qt_xdnd_current_proxy_target [static]

Definition at line 198 of file qdnd_x11.cpp.

Referenced by checkEmbedded(), QDragManager::drop(), handle_xdnd_status(), QDragManager::move(), qt_xdnd_send_leave(), QX11Data::xdndHandleBadwindow(), and QX11Data::xdndHandleFinished().

int qt_xdnd_current_screen = -1 [static]

Definition at line 207 of file qdnd_x11.cpp.

Referenced by QDragManager::drag(), and QDragManager::move().

Window qt_xdnd_current_target [static]

Definition at line 196 of file qdnd_x11.cpp.

Referenced by QDragManager::cancel(), checkEmbedded(), QDragManager::drop(), QDragManager::move(), qt_xdnd_send_leave(), QX11Data::xdndHandleBadwindow(), QX11Data::xdndHandleFinished(), and QX11Data::xdndHandleSelectionRequest().

QPointer<QWidget> qt_xdnd_current_widget [static]

Definition at line 202 of file qdnd_x11.cpp.

Referenced by checkEmbedded(), handle_xdnd_position(), QX11Data::xdndHandleBadwindow(), QX11Data::xdndHandleDrop(), QX11Data::xdndHandleFinished(), QX11Data::xdndHandleLeave(), and xdndObtainData().

bool qt_xdnd_dragging = false

Definition at line 209 of file qdnd_x11.cpp.

Referenced by QDragManager::cancel(), QDragManager::drag(), QDragManager::drop(), qt_try_modal(), and QETWidget::translateMouseEvent().

Atom qt_xdnd_dragsource_xid = 0 [static]

Definition at line 185 of file qdnd_x11.cpp.

Referenced by handle_xdnd_position(), qt_xdnd_send_leave(), QX11Data::xdndHandleBadwindow(), QX11Data::xdndHandleDrop(), QX11Data::xdndHandleEnter(), QX11Data::xdndHandleLeave(), and xdndObtainData().

const int qt_xdnd_max_type = 100

Definition at line 188 of file qdnd_x11.cpp.

Referenced by QX11Data::xdndHandleEnter().

Time qt_xdnd_source_current_time [static]

Definition at line 199 of file qdnd_x11.cpp.

Referenced by QDragManager::drop(), QDragManager::move(), qt_xdnd_send_leave(), and QX11Data::xdndHandleSelectionRequest().

QRect qt_xdnd_source_sameanswer [static]

Definition at line 194 of file qdnd_x11.cpp.

Referenced by QDragManager::drag(), QDragManager::eventFilter(), handle_xdnd_status(), QDragManager::move(), and QDragManager::timerEvent().

Time qt_xdnd_target_current_time [static]

Definition at line 205 of file qdnd_x11.cpp.

Referenced by handle_xdnd_position(), QX11Data::xdndHandleDrop(), and xdndObtainData().

Atom qt_xdnd_types[qt_xdnd_max_type+1] [static]

Definition at line 189 of file qdnd_x11.cpp.

Referenced by QDropData::formats_sys(), QX11Data::xdndHandleEnter(), QX11Data::xdndHandleLeave(), and xdndObtainData().

int transaction_expiry_timer = -1 [static]

Definition at line 93 of file qdnd_x11.cpp.

Referenced by restartXdndDropExpiryTimer(), and QDragManager::timerEvent().

bool waiting_for_status = false [static]

Definition at line 211 of file qdnd_x11.cpp.

Referenced by handle_xdnd_status(), QDragManager::move(), qt_xdnd_send_leave(), QX11Data::xdndHandleDrop(), and QX11Data::xdndHandleFinished().

XdndData xdnd_data = { 0, 0 } [static]

Definition at line 281 of file qdnd_x11.cpp.

Referenced by QDragManager::cancel(), QDragManager::drag(), QDragManager::drop(), findRealWindow(), QDragManager::move(), qt_xdnd_cleanup(), QDragManager::updateCursor(), QDragManager::updatePixmap(), xdndEnable(), and QX11Data::xdndHandleBadwindow().

const int xdnd_version = 5

Definition at line 148 of file qdnd_x11.cpp.

Referenced by QDragManager::move(), xdndEnable(), and QX11Data::xdndHandleEnter().


Generated on Thu Mar 15 13:26:29 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1