src/video/wayland/SDL_waylandtouch.c
author Gabriel Jacobo <gabomdq@gmail.com>
Fri, 27 Dec 2013 09:29:39 -0300
changeset 8082 5b83ad3f01ac
child 8104 2e4f1bd21196
permissions -rw-r--r--
Implements touch support on QTWayland. Contributed by Thomas Perl.
gabomdq@8082
     1
/*
gabomdq@8082
     2
  Simple DirectMedia Layer
gabomdq@8082
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
gabomdq@8082
     4
gabomdq@8082
     5
  This software is provided 'as-is', without any express or implied
gabomdq@8082
     6
  warranty.  In no event will the authors be held liable for any damages
gabomdq@8082
     7
  arising from the use of this software.
gabomdq@8082
     8
gabomdq@8082
     9
  Permission is granted to anyone to use this software for any purpose,
gabomdq@8082
    10
  including commercial applications, and to alter it and redistribute it
gabomdq@8082
    11
  freely, subject to the following restrictions:
gabomdq@8082
    12
gabomdq@8082
    13
  1. The origin of this software must not be misrepresented; you must not
gabomdq@8082
    14
     claim that you wrote the original software. If you use this software
gabomdq@8082
    15
     in a product, an acknowledgment in the product documentation would be
gabomdq@8082
    16
     appreciated but is not required.
gabomdq@8082
    17
  2. Altered source versions must be plainly marked as such, and must not be
gabomdq@8082
    18
     misrepresented as being the original software.
gabomdq@8082
    19
  3. This notice may not be removed or altered from any source distribution.
gabomdq@8082
    20
*/
gabomdq@8082
    21
gabomdq@8082
    22
/* Contributed by Thomas Perl <thomas.perl@jollamobile.com> */
gabomdq@8082
    23
gabomdq@8082
    24
#include "SDL_config.h"
gabomdq@8082
    25
gabomdq@8082
    26
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
gabomdq@8082
    27
gabomdq@8082
    28
#include "SDL_waylandtouch.h"
gabomdq@8082
    29
#include "SDL_log.h"
gabomdq@8082
    30
#include "../../events/SDL_touch_c.h"
gabomdq@8082
    31
gabomdq@8082
    32
struct SDL_WaylandTouch {
gabomdq@8082
    33
    struct qt_touch_extension *touch_extension;
gabomdq@8082
    34
};
gabomdq@8082
    35
gabomdq@8082
    36
gabomdq@8082
    37
/**
gabomdq@8082
    38
 * Qt TouchPointState
gabomdq@8082
    39
 * adapted from qtbase/src/corelib/global/qnamespace.h
gabomdq@8082
    40
 **/
gabomdq@8082
    41
enum QtWaylandTouchPointState {
gabomdq@8082
    42
    QtWaylandTouchPointPressed    = 0x01,
gabomdq@8082
    43
    QtWaylandTouchPointMoved      = 0x02,
gabomdq@8082
    44
    /*
gabomdq@8082
    45
    Never sent by the server:
gabomdq@8082
    46
    QtWaylandTouchPointStationary = 0x04,
gabomdq@8082
    47
    */
gabomdq@8082
    48
    QtWaylandTouchPointReleased   = 0x08,
gabomdq@8082
    49
};
gabomdq@8082
    50
gabomdq@8082
    51
static void
gabomdq@8082
    52
touch_handle_touch(void *data,
gabomdq@8082
    53
        struct qt_touch_extension *qt_touch_extension,
gabomdq@8082
    54
        uint32_t time,
gabomdq@8082
    55
        uint32_t id,
gabomdq@8082
    56
        uint32_t state,
gabomdq@8082
    57
        int32_t x,
gabomdq@8082
    58
        int32_t y,
gabomdq@8082
    59
        int32_t normalized_x,
gabomdq@8082
    60
        int32_t normalized_y,
gabomdq@8082
    61
        int32_t width,
gabomdq@8082
    62
        int32_t height,
gabomdq@8082
    63
        uint32_t pressure,
gabomdq@8082
    64
        int32_t velocity_x,
gabomdq@8082
    65
        int32_t velocity_y,
gabomdq@8082
    66
        uint32_t flags,
gabomdq@8082
    67
        struct wl_array *rawdata)
gabomdq@8082
    68
{
gabomdq@8082
    69
    /**
gabomdq@8082
    70
     * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent
gabomdq@8082
    71
     * (src/compositor/wayland_wrapper/qwltouch.cpp)
gabomdq@8082
    72
     **/
gabomdq@8082
    73
gabomdq@8082
    74
    float FIXED_TO_FLOAT = 1. / 10000.;
gabomdq@8082
    75
    float xf = FIXED_TO_FLOAT * x;
gabomdq@8082
    76
    float yf = FIXED_TO_FLOAT * y;
gabomdq@8082
    77
gabomdq@8082
    78
    float PRESSURE_TO_FLOAT = 1. / 255.;
gabomdq@8082
    79
    float pressuref = PRESSURE_TO_FLOAT * pressure;
gabomdq@8082
    80
gabomdq@8082
    81
    uint32_t touchState = state & 0xFFFF;
gabomdq@8082
    82
    /*
gabomdq@8082
    83
    Other fields that are sent by the server (qwltouch.cpp),
gabomdq@8082
    84
    but not used at the moment can be decoded in this way:
gabomdq@8082
    85
gabomdq@8082
    86
    uint32_t sentPointCount = state >> 16;
gabomdq@8082
    87
    uint32_t touchFlags = flags & 0xFFFF;
gabomdq@8082
    88
    uint32_t capabilities = flags >> 16;
gabomdq@8082
    89
    */
gabomdq@8082
    90
gabomdq@8082
    91
    SDL_TouchID deviceId = 0;
gabomdq@8082
    92
    if (!SDL_GetTouch(deviceId)) {
gabomdq@8082
    93
        if (SDL_AddTouch(deviceId, "qt_touch_extension") < 0) {
gabomdq@8082
    94
             SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
gabomdq@8082
    95
        }
gabomdq@8082
    96
    }
gabomdq@8082
    97
gabomdq@8082
    98
    switch (touchState) {
gabomdq@8082
    99
        case QtWaylandTouchPointPressed:
gabomdq@8082
   100
        case QtWaylandTouchPointReleased:
gabomdq@8082
   101
            SDL_SendTouch(deviceId, (SDL_FingerID)id,
gabomdq@8082
   102
                    (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
gabomdq@8082
   103
                    xf, yf, pressuref);
gabomdq@8082
   104
            break;
gabomdq@8082
   105
        case QtWaylandTouchPointMoved:
gabomdq@8082
   106
            SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, xf, yf, pressuref);
gabomdq@8082
   107
            break;
gabomdq@8082
   108
        default:
gabomdq@8082
   109
            /* Should not happen */
gabomdq@8082
   110
            break;
gabomdq@8082
   111
    }
gabomdq@8082
   112
}
gabomdq@8082
   113
gabomdq@8082
   114
static void
gabomdq@8082
   115
touch_handle_configure(void *data,
gabomdq@8082
   116
        struct qt_touch_extension *qt_touch_extension,
gabomdq@8082
   117
        uint32_t flags)
gabomdq@8082
   118
{
gabomdq@8082
   119
}
gabomdq@8082
   120
gabomdq@8082
   121
/* wayland-qt-touch-extension.c BEGINS */
gabomdq@8082
   122
gabomdq@8082
   123
static const struct qt_touch_extension_listener touch_listener = {
gabomdq@8082
   124
    touch_handle_touch,
gabomdq@8082
   125
    touch_handle_configure,
gabomdq@8082
   126
};
gabomdq@8082
   127
gabomdq@8082
   128
static const struct wl_interface *qt_touch_extension_types[] = {
gabomdq@8082
   129
    NULL,
gabomdq@8082
   130
    NULL,
gabomdq@8082
   131
    NULL,
gabomdq@8082
   132
    NULL,
gabomdq@8082
   133
    NULL,
gabomdq@8082
   134
    NULL,
gabomdq@8082
   135
    NULL,
gabomdq@8082
   136
    NULL,
gabomdq@8082
   137
    NULL,
gabomdq@8082
   138
    NULL,
gabomdq@8082
   139
    NULL,
gabomdq@8082
   140
    NULL,
gabomdq@8082
   141
    NULL,
gabomdq@8082
   142
    NULL,
gabomdq@8082
   143
};
gabomdq@8082
   144
gabomdq@8082
   145
static const struct wl_message qt_touch_extension_requests[] = {
gabomdq@8082
   146
    { "dummy", "", qt_touch_extension_types + 0 },
gabomdq@8082
   147
};
gabomdq@8082
   148
gabomdq@8082
   149
static const struct wl_message qt_touch_extension_events[] = {
gabomdq@8082
   150
    { "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 },
gabomdq@8082
   151
    { "configure", "u", qt_touch_extension_types + 0 },
gabomdq@8082
   152
};
gabomdq@8082
   153
gabomdq@8082
   154
WL_EXPORT const struct wl_interface qt_touch_extension_interface = {
gabomdq@8082
   155
    "qt_touch_extension", 1,
gabomdq@8082
   156
    1, qt_touch_extension_requests,
gabomdq@8082
   157
    2, qt_touch_extension_events,
gabomdq@8082
   158
};
gabomdq@8082
   159
gabomdq@8082
   160
/* wayland-qt-touch-extension.c ENDS */
gabomdq@8082
   161
gabomdq@8082
   162
/* wayland-qt-windowmanager.c BEGINS */
gabomdq@8082
   163
static const struct wl_interface *qt_windowmanager_types[] = {
gabomdq@8082
   164
    NULL,
gabomdq@8082
   165
    NULL,
gabomdq@8082
   166
};
gabomdq@8082
   167
gabomdq@8082
   168
static const struct wl_message qt_windowmanager_requests[] = {
gabomdq@8082
   169
    { "open_url", "us", qt_windowmanager_types + 0 },
gabomdq@8082
   170
};
gabomdq@8082
   171
gabomdq@8082
   172
static const struct wl_message qt_windowmanager_events[] = {
gabomdq@8082
   173
    { "hints", "i", qt_windowmanager_types + 0 },
gabomdq@8082
   174
    { "quit", "", qt_windowmanager_types + 0 },
gabomdq@8082
   175
};
gabomdq@8082
   176
gabomdq@8082
   177
WL_EXPORT const struct wl_interface qt_windowmanager_interface = {
gabomdq@8082
   178
    "qt_windowmanager", 1,
gabomdq@8082
   179
    1, qt_windowmanager_requests,
gabomdq@8082
   180
    2, qt_windowmanager_events,
gabomdq@8082
   181
};
gabomdq@8082
   182
/* wayland-qt-windowmanager.c ENDS */
gabomdq@8082
   183
gabomdq@8082
   184
/* wayland-qt-surface-extension.c BEGINS */
gabomdq@8082
   185
extern const struct wl_interface qt_extended_surface_interface;
gabomdq@8082
   186
extern const struct wl_interface wl_surface_interface;
gabomdq@8082
   187
gabomdq@8082
   188
static const struct wl_interface *qt_surface_extension_types[] = {
gabomdq@8082
   189
    NULL,
gabomdq@8082
   190
    NULL,
gabomdq@8082
   191
    &qt_extended_surface_interface,
gabomdq@8082
   192
    &wl_surface_interface,
gabomdq@8082
   193
};
gabomdq@8082
   194
gabomdq@8082
   195
static const struct wl_message qt_surface_extension_requests[] = {
gabomdq@8082
   196
    { "get_extended_surface", "no", qt_surface_extension_types + 2 },
gabomdq@8082
   197
};
gabomdq@8082
   198
gabomdq@8082
   199
WL_EXPORT const struct wl_interface qt_surface_extension_interface = {
gabomdq@8082
   200
    "qt_surface_extension", 1,
gabomdq@8082
   201
    1, qt_surface_extension_requests,
gabomdq@8082
   202
    0, NULL,
gabomdq@8082
   203
};
gabomdq@8082
   204
gabomdq@8082
   205
static const struct wl_message qt_extended_surface_requests[] = {
gabomdq@8082
   206
    { "update_generic_property", "sa", qt_surface_extension_types + 0 },
gabomdq@8082
   207
    { "set_content_orientation", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   208
    { "set_window_flags", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   209
};
gabomdq@8082
   210
gabomdq@8082
   211
static const struct wl_message qt_extended_surface_events[] = {
gabomdq@8082
   212
    { "onscreen_visibility", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   213
    { "set_generic_property", "sa", qt_surface_extension_types + 0 },
gabomdq@8082
   214
    { "close", "", qt_surface_extension_types + 0 },
gabomdq@8082
   215
};
gabomdq@8082
   216
gabomdq@8082
   217
WL_EXPORT const struct wl_interface qt_extended_surface_interface = {
gabomdq@8082
   218
    "qt_extended_surface", 1,
gabomdq@8082
   219
    3, qt_extended_surface_requests,
gabomdq@8082
   220
    3, qt_extended_surface_events,
gabomdq@8082
   221
};
gabomdq@8082
   222
gabomdq@8082
   223
/* wayland-qt-surface-extension.c ENDS */
gabomdq@8082
   224
gabomdq@8082
   225
void
gabomdq@8082
   226
Wayland_touch_create(SDL_VideoData *data, uint32_t id)
gabomdq@8082
   227
{
gabomdq@8082
   228
    if (data->touch) {
gabomdq@8082
   229
        Wayland_touch_destroy(data);
gabomdq@8082
   230
    }
gabomdq@8082
   231
gabomdq@8082
   232
    data->touch = malloc(sizeof(struct SDL_WaylandTouch));
gabomdq@8082
   233
gabomdq@8082
   234
    struct SDL_WaylandTouch *touch = data->touch;
gabomdq@8082
   235
    touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1);
gabomdq@8082
   236
    qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data);
gabomdq@8082
   237
}
gabomdq@8082
   238
gabomdq@8082
   239
void
gabomdq@8082
   240
Wayland_touch_destroy(SDL_VideoData *data)
gabomdq@8082
   241
{
gabomdq@8082
   242
    if (data->touch) {
gabomdq@8082
   243
        struct SDL_WaylandTouch *touch = data->touch;
gabomdq@8082
   244
        if (touch->touch_extension) {
gabomdq@8082
   245
            qt_touch_extension_destroy(touch->touch_extension);
gabomdq@8082
   246
        }
gabomdq@8082
   247
gabomdq@8082
   248
        free(data->touch);
gabomdq@8082
   249
        data->touch = NULL;
gabomdq@8082
   250
    }
gabomdq@8082
   251
}
gabomdq@8082
   252
gabomdq@8082
   253
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */