src/video/wayland/SDL_waylandtouch.c
author Alex Szpakowski <slime73@gmail.com>
Sat, 10 Nov 2018 16:15:48 -0400
changeset 12404 eb60e952b13f
parent 12201 8bdc4d340419
child 12503 806492103856
permissions -rw-r--r--
Add SDL_TouchDeviceType enum and SDL_GetTouchDeviceType(SDL_TouchID id).

Touch device types include SDL_TOUCH_DEVICE_DIRECT (a touch screen with window-relative coordinates for touches), SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE (a trackpad-style device with absolute device coordinates), and SDL_TOUCH_DEVICE_INDIRECT_RELATIVE (a trackpad-style device with screen cursor-relative coordinates).

Phone screens are an example of a direct device type. Mac trackpads are the indirect-absolute touch device type. The Apple TV remote is an indirect-relative touch device type.
gabomdq@8082
     1
/*
gabomdq@8082
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 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@8104
    24
#include "../../SDL_internal.h"
gabomdq@8082
    25
gabomdq@8082
    26
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
gabomdq@8082
    27
gabomdq@8912
    28
#include "SDL_log.h"
gabomdq@8082
    29
#include "SDL_waylandtouch.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
philipp@9726
    91
    SDL_TouchID deviceId = 1;
slime73@12404
    92
    if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "qt_touch_extension") < 0) {
slouken@12201
    93
         SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
slouken@12201
    94
    }
gabomdq@8082
    95
gabomdq@8082
    96
    switch (touchState) {
gabomdq@8082
    97
        case QtWaylandTouchPointPressed:
gabomdq@8082
    98
        case QtWaylandTouchPointReleased:
gabomdq@8082
    99
            SDL_SendTouch(deviceId, (SDL_FingerID)id,
gabomdq@8082
   100
                    (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
gabomdq@8082
   101
                    xf, yf, pressuref);
gabomdq@8082
   102
            break;
gabomdq@8082
   103
        case QtWaylandTouchPointMoved:
gabomdq@8082
   104
            SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, xf, yf, pressuref);
gabomdq@8082
   105
            break;
gabomdq@8082
   106
        default:
gabomdq@8082
   107
            /* Should not happen */
gabomdq@8082
   108
            break;
gabomdq@8082
   109
    }
gabomdq@8082
   110
}
gabomdq@8082
   111
gabomdq@8082
   112
static void
gabomdq@8082
   113
touch_handle_configure(void *data,
gabomdq@8082
   114
        struct qt_touch_extension *qt_touch_extension,
gabomdq@8082
   115
        uint32_t flags)
gabomdq@8082
   116
{
gabomdq@8082
   117
}
gabomdq@8082
   118
gabomdq@8104
   119
gabomdq@8082
   120
/* wayland-qt-touch-extension.c BEGINS */
gabomdq@8082
   121
gabomdq@8082
   122
static const struct qt_touch_extension_listener touch_listener = {
gabomdq@8082
   123
    touch_handle_touch,
gabomdq@8082
   124
    touch_handle_configure,
gabomdq@8082
   125
};
gabomdq@8082
   126
gabomdq@8082
   127
static const struct wl_interface *qt_touch_extension_types[] = {
gabomdq@8082
   128
    NULL,
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
};
gabomdq@8082
   143
gabomdq@8082
   144
static const struct wl_message qt_touch_extension_requests[] = {
gabomdq@8082
   145
    { "dummy", "", qt_touch_extension_types + 0 },
gabomdq@8082
   146
};
gabomdq@8082
   147
gabomdq@8082
   148
static const struct wl_message qt_touch_extension_events[] = {
gabomdq@8082
   149
    { "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 },
gabomdq@8082
   150
    { "configure", "u", qt_touch_extension_types + 0 },
gabomdq@8082
   151
};
gabomdq@8082
   152
gabomdq@8082
   153
WL_EXPORT const struct wl_interface qt_touch_extension_interface = {
gabomdq@8082
   154
    "qt_touch_extension", 1,
gabomdq@8082
   155
    1, qt_touch_extension_requests,
gabomdq@8082
   156
    2, qt_touch_extension_events,
gabomdq@8082
   157
};
gabomdq@8082
   158
gabomdq@8082
   159
/* wayland-qt-touch-extension.c ENDS */
gabomdq@8082
   160
gabomdq@8082
   161
/* wayland-qt-windowmanager.c BEGINS */
gabomdq@8082
   162
static const struct wl_interface *qt_windowmanager_types[] = {
gabomdq@8082
   163
    NULL,
gabomdq@8082
   164
    NULL,
gabomdq@8082
   165
};
gabomdq@8082
   166
gabomdq@8082
   167
static const struct wl_message qt_windowmanager_requests[] = {
gabomdq@8082
   168
    { "open_url", "us", qt_windowmanager_types + 0 },
gabomdq@8082
   169
};
gabomdq@8082
   170
gabomdq@8082
   171
static const struct wl_message qt_windowmanager_events[] = {
gabomdq@8082
   172
    { "hints", "i", qt_windowmanager_types + 0 },
gabomdq@8082
   173
    { "quit", "", qt_windowmanager_types + 0 },
gabomdq@8082
   174
};
gabomdq@8082
   175
gabomdq@8082
   176
WL_EXPORT const struct wl_interface qt_windowmanager_interface = {
gabomdq@8082
   177
    "qt_windowmanager", 1,
gabomdq@8082
   178
    1, qt_windowmanager_requests,
gabomdq@8082
   179
    2, qt_windowmanager_events,
gabomdq@8082
   180
};
gabomdq@8082
   181
/* wayland-qt-windowmanager.c ENDS */
gabomdq@8082
   182
gabomdq@8082
   183
/* wayland-qt-surface-extension.c BEGINS */
gabomdq@8082
   184
extern const struct wl_interface qt_extended_surface_interface;
gabomdq@8104
   185
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
gabomdq@8082
   186
extern const struct wl_interface wl_surface_interface;
gabomdq@8104
   187
#endif
gabomdq@8082
   188
gabomdq@8082
   189
static const struct wl_interface *qt_surface_extension_types[] = {
gabomdq@8082
   190
    NULL,
gabomdq@8082
   191
    NULL,
gabomdq@8082
   192
    &qt_extended_surface_interface,
gabomdq@8104
   193
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
gabomdq@8104
   194
    /* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ? 
gabomdq@8104
   195
     * The value comes from auto generated code and does 
gabomdq@8104
   196
     * not appear to actually be used anywhere
gabomdq@8104
   197
     */
gabomdq@8104
   198
    NULL, 
gabomdq@8104
   199
#else
gabomdq@8082
   200
    &wl_surface_interface,
gabomdq@8104
   201
#endif    
gabomdq@8082
   202
};
gabomdq@8082
   203
gabomdq@8082
   204
static const struct wl_message qt_surface_extension_requests[] = {
gabomdq@8082
   205
    { "get_extended_surface", "no", qt_surface_extension_types + 2 },
gabomdq@8082
   206
};
gabomdq@8082
   207
gabomdq@8082
   208
WL_EXPORT const struct wl_interface qt_surface_extension_interface = {
gabomdq@8082
   209
    "qt_surface_extension", 1,
gabomdq@8082
   210
    1, qt_surface_extension_requests,
gabomdq@8082
   211
    0, NULL,
gabomdq@8082
   212
};
gabomdq@8082
   213
gabomdq@8082
   214
static const struct wl_message qt_extended_surface_requests[] = {
gabomdq@8082
   215
    { "update_generic_property", "sa", qt_surface_extension_types + 0 },
gabomdq@8082
   216
    { "set_content_orientation", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   217
    { "set_window_flags", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   218
};
gabomdq@8082
   219
gabomdq@8082
   220
static const struct wl_message qt_extended_surface_events[] = {
gabomdq@8082
   221
    { "onscreen_visibility", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   222
    { "set_generic_property", "sa", qt_surface_extension_types + 0 },
gabomdq@8082
   223
    { "close", "", qt_surface_extension_types + 0 },
gabomdq@8082
   224
};
gabomdq@8082
   225
gabomdq@8082
   226
WL_EXPORT const struct wl_interface qt_extended_surface_interface = {
gabomdq@8082
   227
    "qt_extended_surface", 1,
gabomdq@8082
   228
    3, qt_extended_surface_requests,
gabomdq@8082
   229
    3, qt_extended_surface_events,
gabomdq@8082
   230
};
gabomdq@8082
   231
gabomdq@8082
   232
/* wayland-qt-surface-extension.c ENDS */
gabomdq@8082
   233
gabomdq@8082
   234
void
gabomdq@8082
   235
Wayland_touch_create(SDL_VideoData *data, uint32_t id)
gabomdq@8082
   236
{
icculus@8721
   237
    struct SDL_WaylandTouch *touch;
icculus@8721
   238
gabomdq@8082
   239
    if (data->touch) {
gabomdq@8082
   240
        Wayland_touch_destroy(data);
gabomdq@8082
   241
    }
gabomdq@8082
   242
icculus@8721
   243
    /* !!! FIXME: check for failure, call SDL_OutOfMemory() */
icculus@8721
   244
    data->touch = SDL_malloc(sizeof(struct SDL_WaylandTouch));
gabomdq@8082
   245
icculus@8721
   246
    touch = data->touch;
gabomdq@8082
   247
    touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1);
gabomdq@8082
   248
    qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data);
gabomdq@8082
   249
}
gabomdq@8082
   250
gabomdq@8082
   251
void
gabomdq@8082
   252
Wayland_touch_destroy(SDL_VideoData *data)
gabomdq@8082
   253
{
gabomdq@8082
   254
    if (data->touch) {
gabomdq@8082
   255
        struct SDL_WaylandTouch *touch = data->touch;
gabomdq@8082
   256
        if (touch->touch_extension) {
gabomdq@8082
   257
            qt_touch_extension_destroy(touch->touch_extension);
gabomdq@8082
   258
        }
gabomdq@8082
   259
icculus@8721
   260
        SDL_free(data->touch);
gabomdq@8082
   261
        data->touch = NULL;
gabomdq@8082
   262
    }
gabomdq@8082
   263
}
gabomdq@8082
   264
gabomdq@8082
   265
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */