<commit_before>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation <EMAIL>
**
** You may use this file under the terms of the BSD license as follows:
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**
** Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "wlinputdevice.h"

#include "wlshmbuffer.h"
#include "wlcompositor.h"
#include "wldatadevice.h"
#include "wlsurface.h"

#include "waylandcompositor.h"

#include <QtGui/QTouchEvent>

namespace Wayland {

static ShmBuffer *currentCursor;

InputDevice::InputDevice(WaylandInputDevice *handle, Compositor *compositor)
    : m_handle(handle)
    , m_compositor(compositor)
{
    wl_input_device_init(base());
    wl_display_add_global(compositor->wl_display(),&wl_input_device_interface,this,InputDevice::bind_func);
}

void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPoint &localPos, const QPoint &globalPos)
{
    sendMouseMoveEvent(localPos,globalPos);

    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *pointer_focus_resource = base()->pointer_focus_resource;
    if (pointer_focus_resource) {
        wl_resource_post_event(pointer_focus_resource,
                               WL_INPUT_DEVICE_BUTTON, time, toWaylandButton(button), 1);
    }
}

void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPoint &localPos, const QPoint &globalPos)
{
    sendMouseMoveEvent(localPos,globalPos);

    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *pointer_focus_resource = base()->pointer_focus_resource;
    if (pointer_focus_resource) {
        wl_resource_post_event(pointer_focus_resource,
                               WL_INPUT_DEVICE_BUTTON, time, toWaylandButton(button), 0);
    }
}

void InputDevice::sendMouseMoveEvent(const QPoint &localPos, const QPoint &globalPos)
{
    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *pointer_focus_resource = base()->pointer_focus_resource;
    if (pointer_focus_resource) {
        QPoint validGlobalPos = globalPos.isNull()?localPos:globalPos;
        wl_resource_post_event(pointer_focus_resource,
                               WL_INPUT_DEVICE_MOTION,
                               time,
                               validGlobalPos.x(), validGlobalPos.y(), //wayland sends globals before locals
                               localPos.x(), localPos.y());
    }
}

void InputDevice::sendMouseMoveEvent(Surface *surface, const QPoint &localPos, const QPoint &globalPos)
{
    if (mouseFocus() != surface) {
        setMouseFocus(surface,localPos,globalPos);
    }
    sendMouseMoveEvent(localPos,globalPos);
}

void InputDevice::sendKeyPressEvent(uint code)
{
    if (base()->keyboard_focus_resource != NULL) {
        uint32_t time = m_compositor->currentTimeMsecs();
        wl_resource_post_event(base()->keyboard_focus_resource,
                               WL_INPUT_DEVICE_KEY, time, code - 8, 1);
    }
}

void InputDevice::sendKeyReleaseEvent(uint code)
{
    if (base()->keyboard_focus_resource != NULL) {
        uint32_t time = m_compositor->currentTimeMsecs();
        wl_resource_post_event(base()->keyboard_focus_resource,
                               WL_INPUT_DEVICE_KEY, time, code - 8, 0);
    }
}

void InputDevice::sendTouchPointEvent(int id, int x, int y, Qt::TouchPointState state)
{
    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *resource = base()->pointer_focus_resource;
    switch (state) {
    case Qt::TouchPointPressed:
        wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_DOWN, time, base()->pointer_focus, id, x, y);
        break;
    case Qt::TouchPointMoved:
        wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_MOTION, time, id, x, y);
        break;
    case Qt::TouchPointReleased:
        wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_UP, time, id);
        break;
    case Qt::TouchPointStationary:
        // stationary points are not sent through wayland, the client must cache them
        break;
    default:
        break;
    }
}

void InputDevice::sendTouchFrameEvent()
{
    struct wl_resource *resource = base()->pointer_focus_resource;
    wl_resource_post_event(resource,
                         WL_INPUT_DEVICE_TOUCH_FRAME);
}

void InputDevice::sendTouchCancelEvent()
{
    struct wl_resource *resource = base()->pointer_focus_resource;
    wl_resource_post_event(resource,
                         WL_INPUT_DEVICE_TOUCH_CANCEL);
}

void InputDevice::sendFullTouchEvent(QTouchEvent *event)
{
    const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
    if (points.isEmpty())
        return;
    const int pointCount = points.count();
    QPointF pos = mouseFocus()? mouseFocus()->pos():QPointF(0,0);
    for (int i = 0; i < pointCount; ++i) {
        const QTouchEvent::TouchPoint &tp(points.at(i));
        // Convert the local pos in the compositor window to surface-relative.
        QPoint p = (tp.pos() - pos).toPoint();
        sendTouchPointEvent(tp.id(), p.x(), p.y(), tp.state());
    }
    sendTouchFrameEvent();
}

Surface *InputDevice::keyboardFocus() const
{
    return wayland_cast<Surface *>(base()->keyboard_focus);
}

void InputDevice::setKeyboardFocus(Surface *surface)
{
    sendSelectionFocus(surface);
    wl_input_device_set_keyboard_focus(base(), surface ? surface->base() : 0, m_compositor->currentTimeMsecs());<commit_msg>Make touch event sending more robust in the InputDevice.<commit_after>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation <EMAIL>
**
** You may use this file under the terms of the BSD license as follows:
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**
** Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "wlinputdevice.h"

#include "wlshmbuffer.h"
#include "wlcompositor.h"
#include "wldatadevice.h"
#include "wlsurface.h"

#include "waylandcompositor.h"

#include <QtGui/QTouchEvent>

namespace Wayland {

static ShmBuffer *currentCursor;

InputDevice::InputDevice(WaylandInputDevice *handle, Compositor *compositor)
    : m_handle(handle)
    , m_compositor(compositor)
{
    wl_input_device_init(base());
    wl_display_add_global(compositor->wl_display(),&wl_input_device_interface,this,InputDevice::bind_func);
}

void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPoint &localPos, const QPoint &globalPos)
{
    sendMouseMoveEvent(localPos,globalPos);

    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *pointer_focus_resource = base()->pointer_focus_resource;
    if (pointer_focus_resource) {
        wl_resource_post_event(pointer_focus_resource,
                               WL_INPUT_DEVICE_BUTTON, time, toWaylandButton(button), 1);
    }
}

void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPoint &localPos, const QPoint &globalPos)
{
    sendMouseMoveEvent(localPos,globalPos);

    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *pointer_focus_resource = base()->pointer_focus_resource;
    if (pointer_focus_resource) {
        wl_resource_post_event(pointer_focus_resource,
                               WL_INPUT_DEVICE_BUTTON, time, toWaylandButton(button), 0);
    }
}

void InputDevice::sendMouseMoveEvent(const QPoint &localPos, const QPoint &globalPos)
{
    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *pointer_focus_resource = base()->pointer_focus_resource;
    if (pointer_focus_resource) {
        QPoint validGlobalPos = globalPos.isNull()?localPos:globalPos;
        wl_resource_post_event(pointer_focus_resource,
                               WL_INPUT_DEVICE_MOTION,
                               time,
                               validGlobalPos.x(), validGlobalPos.y(), //wayland sends globals before locals
                               localPos.x(), localPos.y());
    }
}

void InputDevice::sendMouseMoveEvent(Surface *surface, const QPoint &localPos, const QPoint &globalPos)
{
    if (mouseFocus() != surface) {
        setMouseFocus(surface,localPos,globalPos);
    }
    sendMouseMoveEvent(localPos,globalPos);
}

void InputDevice::sendKeyPressEvent(uint code)
{
    if (base()->keyboard_focus_resource != NULL) {
        uint32_t time = m_compositor->currentTimeMsecs();
        wl_resource_post_event(base()->keyboard_focus_resource,
                               WL_INPUT_DEVICE_KEY, time, code - 8, 1);
    }
}

void InputDevice::sendKeyReleaseEvent(uint code)
{
    if (base()->keyboard_focus_resource != NULL) {
        uint32_t time = m_compositor->currentTimeMsecs();
        wl_resource_post_event(base()->keyboard_focus_resource,
                               WL_INPUT_DEVICE_KEY, time, code - 8, 0);
    }
}

void InputDevice::sendTouchPointEvent(int id, int x, int y, Qt::TouchPointState state)
{
    uint32_t time = m_compositor->currentTimeMsecs();
    struct wl_resource *resource = base()->pointer_focus_resource;
    if (!resource)
        return;
    switch (state) {
    case Qt::TouchPointPressed:
        wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_DOWN, time, base()->pointer_focus, id, x, y);
        break;
    case Qt::TouchPointMoved:
        wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_MOTION, time, id, x, y);
        break;
    case Qt::TouchPointReleased:
        wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_UP, time, id);
        break;
    case Qt::TouchPointStationary:
        // stationary points are not sent through wayland, the client must cache them
        break;
    default:
        break;
    }
}

void InputDevice::sendTouchFrameEvent()
{
    struct wl_resource *resource = base()->pointer_focus_resource;
    if (resource) {
        wl_resource_post_event(resource,
                               WL_INPUT_DEVICE_TOUCH_FRAME);
    }
}

void InputDevice::sendTouchCancelEvent()
{
    struct wl_resource *resource = base()->pointer_focus_resource;
    if (resource) {
        wl_resource_post_event(resource,
                               WL_INPUT_DEVICE_TOUCH_CANCEL);
    }
}

void InputDevice::sendFullTouchEvent(QTouchEvent *event)
{
    const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
    if (points.isEmpty())
        return;
    if (!mouseFocus()) {
        qWarning("Cannot send touch event, no pointer focus, fix the compositor");
        return;
    }
    const int pointCount = points.count();
    QPointF pos = mouseFocus()->pos();
    for (int i = 0; i < pointCount; ++i) {
        const QTouchEvent::TouchPoint &tp(points.at(i));
        // Convert the local pos in the compositor window to surface-relative.
        QPoint p = (tp.pos() - pos).toPoint();
        sendTouchPointEvent(tp.id(), p.x(), p.y(), tp.state());
    }
    sendTouchFrameEvent();
}

Surface *InputDevice::keyboardFocus() const
{
    return wayland_cast<Surface *>(base()->keyboard_focus);
}

void InputDevice::setKeyboardFocus(Surface *surface)
{
    sendSelectionFocus(surface);
    wl_input_device_set_keyboard_focus(base(), surface ? surface->base() : 0, m_compositor->currentTimeMsecs());
{'fraction_non_alphanumeric': 0.1167716480930297, 'fraction_numerical': 0.0034609261438360906, 'mean_word_length': 3.9226575809199318, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1684569', 'n_tokens_mistral': 4282, 'n_tokens_neox': 4061, 'n_words': 1106}