Пример #1
0
bool QClipboard::ownsMode(Mode mode) const
{
    if (mode == Clipboard)
        return clipboardData()->timestamp != CurrentTime;
    else if(mode == Selection)
        return selectionData()->timestamp != CurrentTime;
    else
        return false;
}
Пример #2
0
bool qt_xfixes_selection_changed(Window selectionOwner, Time timestamp)
{
    QClipboardData *d = selectionData();
#ifdef QCLIPBOARD_DEBUG
    DEBUG("qt_xfixes_selection_changed: owner = %u; selectionOwner = %u; internal timestamp = %u; external timestamp = %u",
          (unsigned int)(owner ? (int)owner->internalWinId() : 0), (unsigned int)selectionOwner,
          (unsigned int)(d ? d->timestamp : 0), (unsigned int)timestamp);
#endif
    if (!owner || (selectionOwner && selectionOwner != owner->internalWinId()) ||
        (!selectionOwner && (d->timestamp == CurrentTime || d->timestamp < timestamp)))
        return qt_check_selection_sentinel();
    return false;
}
Пример #3
0
bool qt_check_selection_sentinel()
{
    bool doIt = true;
    if (owner && !X11->use_xfixes) {
        /*
          Since the X selection mechanism cannot give any signal when
          the selection has changed, we emulate it (for Qt processes) here.
          The notification should be ignored in case of either
          a) This is the process that did setData (because setData()
          then has already emitted dataChanged())
          b) This is the process that owned the selection when dataChanged()
          was called (because we have then received a SelectionClear event,
          and have already emitted dataChanged() as a result of that)
        */

        unsigned char *retval;
        Atom actualType;
        int actualFormat;
        ulong nitems;
        ulong bytesLeft;

        if (XGetWindowProperty(X11->display,
                               QApplication::desktop()->screen(0)->internalWinId(),
                               ATOM(_QT_SELECTION_SENTINEL), 0, 2, False, XA_WINDOW,
                               &actualType, &actualFormat, &nitems,
                               &bytesLeft, &retval) == Success) {
            Window *owners = (Window *)retval;
            if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {
                Window win = owner->internalWinId();
                if (owners[0] == win || owners[1] == win)
                    doIt = false;
            }

            XFree(owners);
        }
    }

    if (doIt) {
        if (waiting_for_data) {
            pending_selection_changed = true;
            if (! pending_timer_id)
                pending_timer_id = QApplication::clipboard()->startTimer(0);
            doIt = false;
        } else {
            selectionData()->clear();
        }
    }

    return doIt;
}
Пример #4
0
const QMimeData* QClipboard::mimeData(Mode mode) const
{
    QClipboardData *d = 0;
    switch (mode) {
    case Selection:
        d = selectionData();
        break;
    case Clipboard:
        d = clipboardData();
        break;
    default:
        qWarning("QClipboard::mimeData: unsupported mode '%d'", mode);
        return 0;
    }

    if (! d->source() && ! timer_event_clear) {
        if (mode == Selection) {
            if (! selection_watcher)
                selection_watcher = new QClipboardWatcher(mode);
            d->setSource(selection_watcher);
        } else {
            if (! clipboard_watcher)
                clipboard_watcher = new QClipboardWatcher(mode);
            d->setSource(clipboard_watcher);
        }

        if (! timer_id) {
            // start a zero timer - we will clear cached data when the timer
            // times out, which will be the next time we hit the event loop...
            // that way, the data is cached long enough for calls within a single
            // loop/function, but the data doesn't linger around in case the selection
            // changes
            QClipboard *that = ((QClipboard *) this);
            timer_id = that->startTimer(0);
        }
    }

    return d->source();
}
Пример #5
0
    ResearchTech getResearchTech(const PlayerTactics& playerTactics, TechTypes ignoreTechType)
    {
        TechSelectionData selectionData(playerTactics);

        // pure tech tactics ('first to tech' items, open borders, etc...)
        for (PlayerTactics::TechTacticsMap::const_iterator ci = playerTactics.techTacticsMap_.begin(), ciEnd = playerTactics.techTacticsMap_.end();
            ci != ciEnd; ++ci)
        {
            if (ci->second)
            {
                ci->second->apply(selectionData.tacticSelectionDataMap[DependencyItem(ResearchTechDependency::ID, ci->first)]);
            }
        }

        // buildings
        for (PlayerTactics::CityBuildingTacticsMap::const_iterator ci = playerTactics.cityBuildingTacticsMap_.begin(), 
            ciEnd = playerTactics.cityBuildingTacticsMap_.end(); ci != ciEnd; ++ci)
        {
            const CvCity* pCity = getCity(ci->first);
            const City& city = gGlobals.getGame().getAltAI()->getPlayer(pCity->getOwner())->getCity(pCity);

            for (PlayerTactics::CityBuildingTacticsList::const_iterator li(ci->second.begin()), liEnd(ci->second.end()); li != liEnd; ++li)
            {
                li->second->update(playerTactics.player, city.getCityData());
                li->second->apply(selectionData.tacticSelectionDataMap, IDependentTactic::Ignore_Techs);
            }
        }

        // units
        for (PlayerTactics::UnitTacticsMap::const_iterator iter(playerTactics.unitTacticsMap_.begin()),
            endIter(playerTactics.unitTacticsMap_.end()); iter != endIter; ++iter)
        {
            if (iter->second)
            {
                iter->second->update(playerTactics.player);
                iter->second->apply(selectionData.tacticSelectionDataMap, IDependentTactic::Ignore_Techs);
            }
        }

        // city improvements
        for (PlayerTactics::CityImprovementTacticsMap::const_iterator ci(playerTactics.cityImprovementTacticsMap_.begin()), ciEnd(playerTactics.cityImprovementTacticsMap_.end());
            ci != ciEnd; ++ci)
        {
            const CvCity* pCity = getCity(ci->first);
            if (pCity)
            {
                const City& city = playerTactics.player.getCity(pCity);
                TotalOutput base = city.getCurrentOutputProjection().getOutput();

                for (PlayerTactics::CityImprovementTacticsList::const_iterator li(ci->second.begin()), liEnd(ci->second.end()); li != liEnd; ++li)
                {
                    (*li)->update(playerTactics.player, city.getCityData());

                    const std::vector<ResearchTechDependencyPtr> techs = (*li)->getTechDependencies();
                    for (size_t i = 0, count = techs.size(); i < count; ++i)
                    {
                        selectionData.tacticSelectionDataMap[techs[i]->getDependencyItem()].cityImprovementsDelta +=
                            (*li)->getProjection().getOutput() - base;
                    }
                }
            }
        }

        // processes
        for (PlayerTactics::ProcessTacticsMap::const_iterator ci(playerTactics.processTacticsMap_.begin()), ciEnd(playerTactics.processTacticsMap_.end());
            ci != ciEnd; ++ci)
        {
            if (ci->second->areDependenciesSatisfied(playerTactics.player, IDependentTactic::Ignore_Techs))
            {
                CityIter iter(*playerTactics.player.getCvPlayer());
                TotalOutput processOutput;
                while (CvCity* pCity = iter())
                {
                    ProjectionLadder projection = ci->second->getProjection(pCity->getIDInfo());
                    processOutput += projection.getProcessOutput();
                }

                const std::vector<ResearchTechDependencyPtr>& techs = ci->second->getTechDependencies();
                for (size_t i = 0, count = techs.size(); i < count; ++i)
                {
                    selectionData.tacticSelectionDataMap[techs[i]->getDependencyItem()].
                        processOutputsMap[ci->second->getProcessType()] += processOutput;
                }
            }
        }

        selectionData.processTechs();
        if (ignoreTechType != NO_TECH)
        {
            //selectionData.removeTech(ignoreTechType);
        }
        selectionData.scoreTechs();
        selectionData.debug();

        return selectionData.getSelection();
    }
Пример #6
0
bool QClipboard::event(QEvent *e)
{
    if (e->type() == QEvent::Timer) {
        QTimerEvent *te = (QTimerEvent *) e;

        if (waiting_for_data) // should never happen
            return false;

        if (te->timerId() == timer_id) {
            killTimer(timer_id);
            timer_id = 0;

            timer_event_clear = true;
            if (selection_watcher) // clear selection
                selectionData()->clear();
            if (clipboard_watcher) // clear clipboard
                clipboardData()->clear();
            timer_event_clear = false;

            return true;
        } else if (te->timerId() == pending_timer_id) {
            // I hate klipper
            killTimer(pending_timer_id);
            pending_timer_id = 0;

            if (pending_clipboard_changed) {
                pending_clipboard_changed = false;
                clipboardData()->clear();
                emitChanged(QClipboard::Clipboard);
            }
            if (pending_selection_changed) {
                pending_selection_changed = false;
                selectionData()->clear();
                emitChanged(QClipboard::Selection);
            }

            return true;
        } else if (te->timerId() == incr_timer_id) {
            killTimer(incr_timer_id);
            incr_timer_id = 0;

            qt_xclb_incr_timeout();

            return true;
        } else {
            return QObject::event(e);
        }
    } else if (e->type() != QEvent::Clipboard) {
        return QObject::event(e);
    }

    XEvent *xevent = (XEvent *)(((QClipboardEvent *)e)->data());
    Display *dpy = X11->display;

    if (!xevent) {
        // That means application exits and we need to give clipboard
        // content to the clipboard manager.
        // First we check if there is a clipboard manager.
        if (XGetSelectionOwner(X11->display, ATOM(CLIPBOARD_MANAGER)) == XNone
            || !owner)
            return true;

        Window ownerId = owner->internalWinId();
        Q_ASSERT(ownerId);
        // we delete the property so the manager saves all TARGETS.
        XDeleteProperty(X11->display, ownerId, ATOM(_QT_SELECTION));
        XConvertSelection(X11->display, ATOM(CLIPBOARD_MANAGER), ATOM(SAVE_TARGETS),
                          ATOM(_QT_SELECTION), ownerId, X11->time);
        XSync(dpy, false);

        XEvent event;
        // waiting until the clipboard manager fetches the content.
        if (!X11->clipboardWaitForEvent(ownerId, SelectionNotify, &event, 10000)) {
            qWarning("QClipboard: Unable to receive an event from the "
                     "clipboard manager in a reasonable time");
        }

        return true;
    }

    switch (xevent->type) {

    case SelectionClear:
        // new selection owner
        if (xevent->xselectionclear.selection == XA_PRIMARY) {
            QClipboardData *d = selectionData();

            // ignore the event if it was generated before we gained selection ownership
            if (d->timestamp != CurrentTime && xevent->xselectionclear.time <= d->timestamp)
                break;

            DEBUG("QClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
                  XGetSelectionOwner(dpy, XA_PRIMARY),
                  xevent->xselectionclear.time, d->timestamp);

            if (! waiting_for_data) {
                d->clear();
                emitChanged(QClipboard::Selection);
            } else {
                pending_selection_changed = true;
                if (! pending_timer_id)
                    pending_timer_id = QApplication::clipboard()->startTimer(0);
            }
        } else if (xevent->xselectionclear.selection == ATOM(CLIPBOARD)) {
            QClipboardData *d = clipboardData();

            // ignore the event if it was generated before we gained selection ownership
            if (d->timestamp != CurrentTime && xevent->xselectionclear.time <= d->timestamp)
                break;

            DEBUG("QClipboard: new clipboard owner 0x%lx at time %lx (%lx)",
                  XGetSelectionOwner(dpy, ATOM(CLIPBOARD)),
                  xevent->xselectionclear.time, d->timestamp);

            if (! waiting_for_data) {
                d->clear();
                emitChanged(QClipboard::Clipboard);
            } else {
                pending_clipboard_changed = true;
                if (! pending_timer_id)
                    pending_timer_id = QApplication::clipboard()->startTimer(0);
            }
        } else {
            qWarning("QClipboard: Unknown SelectionClear event received");
            return false;
        }
        break;

    case SelectionNotify:
        /*
          Something has delivered data to us, but this was not caught
          by QClipboardWatcher::getDataInFormat()

          Just skip the event to prevent Bad Things (tm) from
          happening later on...
        */
        break;

    case SelectionRequest:
        {
            // someone wants our data
            XSelectionRequestEvent *req = &xevent->xselectionrequest;

            if (requestor && req->requestor == requestor->internalWinId())
                break;

            XEvent event;
            event.xselection.type      = SelectionNotify;
            event.xselection.display   = req->display;
            event.xselection.requestor = req->requestor;
            event.xselection.selection = req->selection;
            event.xselection.target    = req->target;
            event.xselection.property  = XNone;
            event.xselection.time      = req->time;

            DEBUG("QClipboard: SelectionRequest from %lx\n"
                  "    selection 0x%lx (%s) target 0x%lx (%s)",
                  req->requestor,
                  req->selection,
                  X11->xdndAtomToString(req->selection).data(),
                  req->target,
                  X11->xdndAtomToString(req->target).data());

            QClipboardData *d;
            if (req->selection == XA_PRIMARY) {
                d = selectionData();
            } else if (req->selection == ATOM(CLIPBOARD)) {
                d = clipboardData();
            } else {
                qWarning("QClipboard: Unknown selection '%lx'", req->selection);
                XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                break;
            }

            if (! d->source()) {
                qWarning("QClipboard: Cannot transfer data, no data available");
                XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                break;
            }

            DEBUG("QClipboard: SelectionRequest at time %lx (ours %lx)",
                  req->time, d->timestamp);

            if (d->timestamp == CurrentTime // we don't own the selection anymore
                || (req->time != CurrentTime && req->time < d->timestamp)) {
                DEBUG("QClipboard: SelectionRequest too old");
                XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                break;
            }

            Atom xa_targets = ATOM(TARGETS);
            Atom xa_multiple = ATOM(MULTIPLE);
            Atom xa_timestamp = ATOM(TIMESTAMP);

            struct AtomPair { Atom target; Atom property; } *multi = 0;
            Atom multi_type = XNone;
            int multi_format = 0;
            int nmulti = 0;
            int imulti = -1;
            bool multi_writeback = false;

            if (req->target == xa_multiple) {
                QByteArray multi_data;
                if (req->property == XNone
                    || !X11->clipboardReadProperty(req->requestor, req->property, false, &multi_data,
                                                   0, &multi_type, &multi_format)
                    || multi_format != 32) {
                    // MULTIPLE property not formatted correctly
                    XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
                    break;
                }
                nmulti = multi_data.size()/sizeof(*multi);
                multi = new AtomPair[nmulti];
                memcpy(multi,multi_data.data(),multi_data.size());
                imulti = 0;
            }

            for (; imulti < nmulti; ++imulti) {
                Atom target;
                Atom property;

                if (multi) {
                    target = multi[imulti].target;
                    property = multi[imulti].property;
                } else {
                    target = req->target;
                    property = req->property;
                    if (property == XNone) // obsolete client
                        property = target;
                }

                Atom ret = XNone;
                if (target == XNone || property == XNone) {
                    ;
                } else if (target == xa_timestamp) {
                    if (d->timestamp != CurrentTime) {
                        XChangeProperty(dpy, req->requestor, property, XA_INTEGER, 32,
                                        PropModeReplace, (uchar *) &d->timestamp, 1);
                        ret = property;
                    } else {
                        qWarning("QClipboard: Invalid data timestamp");
                    }
                } else if (target == xa_targets) {
                    ret = send_targets_selection(d, req->requestor, property);
                } else {
                    ret = send_selection(d, target, req->requestor, property);
                }

                if (nmulti > 0) {
                    if (ret == XNone) {
                        multi[imulti].property = XNone;
                        multi_writeback = true;
                    }
                } else {
                    event.xselection.property = ret;
                    break;
                }
            }

            if (nmulti > 0) {
                if (multi_writeback) {
                    // according to ICCCM 2.6.2 says to put None back
                    // into the original property on the requestor window
                    XChangeProperty(dpy, req->requestor, req->property, multi_type, 32,
                                    PropModeReplace, (uchar *) multi, nmulti * 2);
                }

                delete [] multi;
                event.xselection.property = req->property;
            }

            // send selection notify to requestor
            XSendEvent(dpy, req->requestor, False, NoEventMask, &event);

            DEBUG("QClipboard: SelectionNotify to 0x%lx\n"
                  "    property 0x%lx (%s)",
                  req->requestor, event.xselection.property,
                  X11->xdndAtomToString(event.xselection.property).data());
        }
        break;
    }

    return true;
}
Пример #7
0
void QClipboard::setMimeData(QMimeData* src, Mode mode)
{
    Atom atom, sentinel_atom;
    QClipboardData *d;
    switch (mode) {
    case Selection:
        atom = XA_PRIMARY;
        sentinel_atom = ATOM(_QT_SELECTION_SENTINEL);
        d = selectionData();
        break;

    case Clipboard:
        atom = ATOM(CLIPBOARD);
        sentinel_atom = ATOM(_QT_CLIPBOARD_SENTINEL);
        d = clipboardData();
        break;

    default:
        qWarning("QClipboard::setMimeData: unsupported mode '%d'", mode);
        return;
    }

    Display *dpy = X11->display;
    Window newOwner;

    if (! src) { // no data, clear clipboard contents
        newOwner = XNone;
        d->clear();
    } else {
        setupOwner();

        newOwner = owner->internalWinId();

        d->setSource(src);
        d->timestamp = X11->time;
    }

    Window prevOwner = XGetSelectionOwner(dpy, atom);
    // use X11->time, since d->timestamp == CurrentTime when clearing
    XSetSelectionOwner(dpy, atom, newOwner, X11->time);

    if (mode == Selection)
        emitChanged(QClipboard::Selection);
    else
        emitChanged(QClipboard::Clipboard);

    if (XGetSelectionOwner(dpy, atom) != newOwner) {
        qWarning("QClipboard::setData: Cannot set X11 selection owner for %s",
                 X11->xdndAtomToString(atom).data());
        d->clear();
        return;
    }

    // Signal to other Qt processes that the selection has changed
    Window owners[2];
    owners[0] = newOwner;
    owners[1] = prevOwner;
    XChangeProperty(dpy, QApplication::desktop()->screen(0)->internalWinId(),
                     sentinel_atom, XA_WINDOW, 32, PropModeReplace,
                     (unsigned char*)&owners, 2);
}
Пример #8
0
void TNMScatterPlot::process() {
    if (!_inport.hasData())
        return;

	// Activate the outport as the rendering target
    _outport.activateTarget();
	// Clear the buffer
    _outport.clearTarget();

	// Access the provided data. We have already checked before that it exists, so dereferencing it here is safe
    const Data& data = *(_inport.getData());

	// The set contains all indices of voxels that should be ignored
	const std::set<unsigned int>& brushingIndices = _brushingIndices.get();
	// The set contains all indices of voxels that should be visually selected
	const std::set<unsigned int>& selectionIndices = _linkingIndices.get();

	// The number of points is equal to the number in the original dataset minus the number we are ignoring
	const size_t dataSize = data.size() - brushingIndices.size();
	// There are 2 coordinate components for each point
	const size_t nCoordinateComponents = dataSize * 2;

	// The vector containing the position data
	std::vector<float> positionData;
	// Make room in the vector
	positionData.resize(nCoordinateComponents); 

	// The vector containing boolean flags saying for each position if it is selected
	// OpenGL doesn't support boolean values for the vertex buffer, so we take the next best thing instead
	std::vector<unsigned char> selectionData(dataSize, 0);
	
	// In order to map the value ranges to [-1,1] we need to find the mininum and maximum values
	float minimumFirstCoordinate = std::numeric_limits<float>::max();
	float maximumFirstCoordinate = -std::numeric_limits<float>::max();
	float minimumSecondCoordinate = std::numeric_limits<float>::max();
	float maximumSecondCoordinate = -std::numeric_limits<float>::max();
	// i: index into the data
	// j: index into the coordinates
	for (size_t i = 0, j = 0; i < data.size(); ++i) {
		//// See if the index i is in the vector for brushing
		if (brushingIndices.find(data[i].voxelIndex) != brushingIndices.end())
			// If it is, we ignore it
			continue;
		else {
			// otherwise add it to the position data
			// _firstAxis.getValue() and _secondAxis.getValue() returns the integer value specified above
			// to determine which selection was chosen in the GUI
			const float firstCoordinate = data[i].dataValues[_firstAxis.getValue()];
			const float secondCoordinate = data[i].dataValues[_secondAxis.getValue()];
			positionData[j] = firstCoordinate;
			positionData[j+1] = secondCoordinate;
			j += 2;

			minimumFirstCoordinate = std::min(minimumFirstCoordinate, firstCoordinate);
			maximumFirstCoordinate = std::max(maximumFirstCoordinate, firstCoordinate);
			minimumSecondCoordinate = std::min(minimumSecondCoordinate, secondCoordinate);
			maximumSecondCoordinate = std::max(maximumSecondCoordinate, secondCoordinate);
		}
	}

	// In a second step, we need to normalize the found data. By now we have looked at each value and found the
	// min/max values
	// Normalizing the data values to the range [-1,1]
	for (size_t i = 0; i < nCoordinateComponents; i+=2) {
		// First normalize to [0,1]
		positionData[i] = (positionData[i] - minimumFirstCoordinate) / (maximumFirstCoordinate - minimumFirstCoordinate);
		positionData[i+1] = (positionData[i+1] - minimumSecondCoordinate) / (maximumSecondCoordinate - minimumSecondCoordinate);
		
		// Then shift the normalized values to [-1,1]
		positionData[i] = (positionData[i] - 0.5f) * 2.f;
		positionData[i+1] = (positionData[i+1] - 0.5f) * 2.f;
	}

	// Set the selection array for all selected indices
	for (std::set<unsigned int>::const_iterator i = selectionIndices.begin();
		i != selectionIndices.end();
		++i) 
	{
		const unsigned int thisIndex = *i;
		selectionData[thisIndex] = 1;
	}

	// We want to be able to set the point size from the vertex shader
	glEnable(GL_PROGRAM_POINT_SIZE);

	// Activate, create, and fill the vbo containing the position data
	GLuint vbo;
	glEnableVertexAttribArray(0);
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, positionData.size() * sizeof(float), &(positionData[0]), GL_STATIC_DRAW);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);

	// Activate, create, and fill the vbo containing the selection data
	GLuint selectionVbo;
	glEnableVertexAttribArray(1);
	glGenBuffers(1, &selectionVbo);
	glBindBuffer(GL_ARRAY_BUFFER, selectionVbo);
	glBufferData(GL_ARRAY_BUFFER, selectionData.size() * sizeof(unsigned char), &(selectionData[0]), GL_STATIC_DRAW);
	glVertexAttribIPointer(1, 1, GL_UNSIGNED_BYTE, 0, 0);

	// Activate the shader required for rendering
	_shader->activate();

	// Draw the points
	glDrawArrays(GL_POINTS, 0, dataSize);

	// And be a good citizen and clean up
	_shader->deactivate();
	glDeleteBuffers(1, &vbo);
	glDisable(GL_PROGRAM_POINT_SIZE);
    _outport.deactivateTarget();
}