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

📄 qmotifdnd_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            SWAP2BYTES(dnd_message->data.pot.y);            SWAP4BYTES(dnd_message->data.pot.property);            SWAP4BYTES(dnd_message->data.pot.src_window);        }        dnd_data->x = dnd_message->data.pot.x ;        dnd_data->y = dnd_message->data.pot.y ;        dnd_data->property = dnd_message->data.pot.property ;        dnd_data->src_window = dnd_message->data.pot.src_window ;        break ;    case DND_DROP_SITE_LEAVE:        break;    default:        break ;    }    return True ;}static Window MotifWindow(Display *display){    Atom            type;    int             format;    unsigned long   size;    unsigned long   bytes_after;    Window         *property = 0;    Window            motif_window ;    /* this version does no caching, so it's slow: round trip each time */    if ((XGetWindowProperty (display, DefaultRootWindow(display),                             ATOM(_MOTIF_DRAG_WINDOW),                             0L, 100000L, False, AnyPropertyType,                             &type, &format, &size, &bytes_after,                             (unsigned char **) &property) == Success) &&        (type != XNone)) {        motif_window = *property;    } else {        XSetWindowAttributes sAttributes;        /* really, this should be done on a separate connection,           with XSetCloseDownMode (RetainPermanent), so that           others don't have to recreate it; hopefully, some real           Motif application will be around to do it */        sAttributes.override_redirect = True;        sAttributes.event_mask = PropertyChangeMask;        motif_window = XCreateWindow (display,                                      DefaultRootWindow (display),                                      -170, -560, 1, 1, 0, 0,                                      InputOnly, CopyFromParent,                                      (CWOverrideRedirect |CWEventMask),                                      &sAttributes);        XMapWindow (display, motif_window);    }    if (property) {        XFree ((char *)property);    }    return (motif_window);}static DndTargetsTable TargetsTable(Display *display){    Atom            type;    int             format;    unsigned long   size;    unsigned long   bytes_after;    Window motif_window = MotifWindow(display) ;    DndTargets * target_prop;    DndTargetsTable targets_table ;    int i,j ;    char * target_data ;    /* this version does no caching, so it's slow: round trip each time */    /* ideally, register for property notify on this target_list       atom and update when necessary only */    if ((XGetWindowProperty (display, motif_window,                             ATOM(_MOTIF_DRAG_TARGETS), 0L, 100000L,                             False, ATOM(_MOTIF_DRAG_TARGETS),                             &type, &format, &size, &bytes_after,                             (unsigned char **) &target_prop) != Success) ||        type == XNone) {        qWarning("QMotifDND: cannot get property on motif window");        return 0;    }    if (target_prop->protocol_version != DND_PROTOCOL_VERSION) {        qWarning("QMotifDND: protocol mismatch");    }    if (target_prop->byte_order != DndByteOrder()) {        /* need to swap num_target_lists and size */        SWAP2BYTES(target_prop->num_target_lists);        SWAP4BYTES(target_prop->data_size);    }    /* now parse DndTarget prop data in a TargetsTable */    targets_table = (DndTargetsTable)malloc(sizeof(DndTargetsTableRec));    targets_table->num_entries = target_prop->num_target_lists ;    targets_table->entries = (DndTargetsTableEntry)                             malloc(sizeof(DndTargetsTableEntryRec) * target_prop->num_target_lists);    target_data = (char*)target_prop + sizeof(*target_prop) ;    for (i = 0 ; i < targets_table->num_entries; i++) {        CARD16 num_targets ;        CARD32 atom ;        memcpy(&num_targets, target_data, 2);        target_data += 2;        /* potential swap needed here */        if (target_prop->byte_order != DndByteOrder())            SWAP2BYTES(num_targets);        targets_table->entries[i].num_targets = num_targets ;        targets_table->entries[i].targets = (Atom *)                                            malloc(sizeof(Atom) * targets_table->entries[i].num_targets);        for (j = 0; j < num_targets; j++) {            memcpy(&atom, target_data, 4);            target_data += 4;            /* another potential swap needed here */            if (target_prop->byte_order != DndByteOrder())                SWAP4BYTES(atom);            targets_table->entries[i].targets[j] = (Atom) atom ;        }    }    if (target_prop) {        XFree((char *)target_prop);    }    return targets_table ;}static int _DndIndexToTargets(Display * display,                              int index,                              Atom ** targets){    DndTargetsTable        targets_table;    int i ;    /* again, slow: no caching here, alloc/free each time */    if (!(targets_table = TargetsTable (display)) ||        (index >= targets_table->num_entries)) {        if (targets_table)            XFree((char*)targets_table);        return -1;    }    /* transfer the correct target list index */    *targets = (Atom*)malloc(sizeof(Atom)*targets_table->                             entries[index].num_targets);    memcpy((char*)*targets,           (char*)targets_table->entries[index].targets,           sizeof(Atom)*targets_table->entries[index].num_targets);    /* free the target table and its guts */    for (i=0 ; i < targets_table->num_entries; i++)        XFree((char*)targets_table->entries[i].targets);    int tmp = targets_table->entries[index].num_targets;    XFree((char*)targets_table);    return tmp; // targets_table->entries[index].num_targets;}QByteArray QX11Data::motifdndFormat(int n){    if (!motifdnd_active)        return 0; // should not happen    if (n == 0)        return "text/plain";    if (n == 1)        return "text/uri-list";    n -= 2;    if (n >= num_src_targets)        return 0;    Atom target = src_targets[n];    if (target == XA_STRING)        return "text/plain;charset=ISO-8859-1";    if (target == ATOM(UTF8_STRING))        return "text/plain;charset=UTF-8";    if (target == ATOM(TEXT) ||         target == ATOM(COMPOUND_TEXT))        return "text/plain";    return X11->xdndAtomToString(target);}QByteArray QX11Data::motifdndObtainData(const char *mimeType){    QByteArray result;    if (Dnd_selection == 0)        return result;    // try to convert the selection to the requested property    // qDebug("trying to convert to '%s'", mimeType);    int n=0;    QByteArray f;    do {        f = motifdndFormat(n);        if (f.isEmpty())            return result;        n++;    } while(qstricmp(mimeType, f.data()));    // found one    Atom conversion_type;    if (qstrnicmp(f, "text/", 5) == 0) {        // always convert text to XA_STRING for compatibility with        // prior Qt versions        conversion_type = XA_STRING;    } else {        conversion_type = X11->xdndStringToAtom(f);        // qDebug("found format '%s' 0x%lx '%s'", f, conversion_type,        // X11->xdndAtomToString(conversion_type));    }    if (XGetSelectionOwner(X11->display,                             Dnd_selection) == XNone) {        return result; // should never happen?    }    QWidget* tw = drop_widget;    if ((drop_widget->windowType() == Qt::Desktop)) {        tw = new QWidget;    }    // convert selection to the appropriate type    XConvertSelection (X11->display, Dnd_selection, conversion_type,                       Dnd_selection, tw->winId(), Dnd_selection_time);    XFlush(X11->display);    XEvent xevent;    bool got=X11->clipboardWaitForEvent(tw->winId(), SelectionNotify, &xevent, 5000);    if (got) {        Atom type;        if (X11->clipboardReadProperty(tw->winId(), Dnd_selection, true, &result, 0, &type, 0, true)) {        }    }    //   we have to convert selection in order to indicate success to the initiator    XConvertSelection (X11->display, Dnd_selection, ATOM(XmTRANSFER_SUCCESS),                       Dnd_selection, tw->winId(), Dnd_selection_time);    // wait again for SelectionNotify event    X11->clipboardWaitForEvent(tw->winId(), SelectionNotify, &xevent, 5000);    if ((drop_widget->windowType() == Qt::Desktop)) {        delete tw;    }    return result;}void QX11Data::motifdndEnable(QWidget *widget, bool){    DndWriteReceiverProperty(display, widget->winId(), DND_DRAG_DYNAMIC);}void QX11Data::motifdndHandle(QWidget * /* w */ , const XEvent * xe, bool /* passive */){    XEvent event = *xe;    XClientMessageEvent cm ;    DndData dnd_data ;    char receiver ;    if (!(DndParseClientMessage ((XClientMessageEvent*)&event,                                 &dnd_data, &receiver))) {        return;    }    switch (dnd_data.reason) {    case DND_DRAG_MOTION:        {            /* check if in drop site, and depending on the state,               send a drop site enter or drop site leave or echo */            QPoint p(dnd_data.x, dnd_data.y);            QWidget *c = QApplication::widgetAt(p);            if (c)                p = c->mapFromGlobal(p);            while (c && !c->acceptDrops() && !c->isWindow()) {                p = c->mapToParent(p);                c = c->parentWidget();            }            QDragMoveEvent me(p, Qt::CopyAction, QDragManager::self()->dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());            if (c != 0L && c->acceptDrops()) {                if (drop_widget != 0L && drop_widget->acceptDrops() &&                     drop_widget != c) {                    QDragLeaveEvent e;                    QApplication::sendEvent(drop_widget, &e);                    QDragEnterEvent de(p, Qt::CopyAction, QDragManager::self()->dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());                    QApplication::sendEvent(c, &de);                }                drop_widget = c;                if (!in_drop_site) {                    in_drop_site = True ;                    dnd_data.reason = DND_DROP_SITE_ENTER ;                    dnd_data.time = CurrentTime ;                    dnd_data.operation = DND_MOVE|DND_COPY;                    dnd_data.operations = DND_MOVE|DND_COPY;                    DndFillClientMessage (event.xclient.display,                                          cur_window,                                          &cm, &dnd_data, 0);                    XSendEvent(event.xbutton.display,                               cur_window, False, 0,                               (XEvent *)&cm) ;                    QDragEnterEvent de(p, Qt::CopyAction, QDragManager::self()->dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());                    QApplication::sendEvent(drop_widget, &de);                    if (de.isAccepted()) {                        me.accept(de.answerRect());                    } else {                        me.ignore(de.answerRect());                    }                } else {                    dnd_data.reason = DND_DRAG_MOTION ;                    dnd_data.time = CurrentTime ;                    dnd_data.operation = DND_MOVE|DND_COPY;                    dnd_data.operations = DND_MOVE|DND_COPY;                    DndFillClientMessage (event.xclient.display,                                          cur_window,                                          &cm, &dnd_data, 0);                    XSendEvent(event.xbutton.display,                               cur_window, False, 0,                               (XEvent *)&cm) ;                    QApplication::sendEvent(drop_widget, &me);                }            } else {                if (in_drop_site) {                    in_drop_site = False ;                    dnd_data.reason = DND_DROP_SITE_LEAVE ;                    dnd_data.time = CurrentTime ;                    DndFillClientMessage (event.xclient.display,                                          cur_window,                                          &cm, &dnd_data, 0);                    XSendEvent(event.xbutton.display,                               cur_window, False, 0,                               (XEvent *)&cm) ;                    QDragLeaveEvent e;                    QApplication::sendEvent(drop_widget, &e);                }            }        }        break;    case DND_TOP_LEVEL_ENTER:        /* get the size of our drop site for later use */        cur_window = dnd_data.src_window ;        motifdnd_active = true;        /* no answer needed, just read source property */        DndReadSourceProperty (event.xclient.display,                               cur_window,                               dnd_data.property,                               &src_targets, &num_src_targets);        break;    case DND_TOP_LEVEL_LEAVE:        /* no need to do anything */        break;    case DND_OPERATION_CHANGED:        /* need to echo */        break;    case DND_DROP_START:        if (!in_drop_site) {            // we have to convert selection in order to indicate failure to the initiator            XConvertSelection (X11->display, dnd_data.property, ATOM(XmTRANSFER_FAILURE),                               dnd_data.property, cur_window, dnd_data.time);            if (drop_widget) {                QDragLeaveEvent e;                QApplication::sendEvent(drop_widget, &e);                drop_widget = 0;            }            return;        }        /* need to echo and then request a convert */        dnd_data.reason = DND_DROP_START ;        DndFillClientMessage (event.xclient.display,                              drop_widget->winId(),                              &cm, &dnd_data, 0);        XSendEvent(event.xbutton.display,                   cur_window, False, 0,                   (XEvent *)&cm) ;        // store selection and its time        Dnd_selection = dnd_data.property;        Dnd_selection_time = dnd_data.time;        QPoint p(dnd_data.x, dnd_data.y);        QDropEvent de(drop_widget->mapFromGlobal(p), Qt::CopyAction, QDragManager::self()->dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());        QApplication::sendEvent(drop_widget, &de);        if (in_drop_site)            in_drop_site = False ;        drop_widget = 0;        cur_window = 0;        break;    }   //  end of switch (dnd_data.reason)}#endif // QT_NO_DRAGANDDROP

⌨️ 快捷键说明

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