src/video/wayland/SDL_waylandtouch.c
author Alex Szpakowski
Sun, 04 Aug 2019 16:56:40 -0300
changeset 12996 b4a7e94357f2
parent 12979 bbbb30026158
child 13201 c88f111dc41f
permissions -rw-r--r--
Fix touch-related compile errors on Linux.
gabomdq@8082
     1
/*
gabomdq@8082
     2
  Simple DirectMedia Layer
slouken@12503
     3
  Copyright (C) 1997-2019 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"
slime73@12996
    29
#include "SDL_mouse.h"
slime73@12996
    30
#include "SDL_keyboard.h"
gabomdq@8082
    31
#include "SDL_waylandtouch.h"
gabomdq@8082
    32
#include "../../events/SDL_touch_c.h"
gabomdq@8082
    33
gabomdq@8082
    34
struct SDL_WaylandTouch {
gabomdq@8082
    35
    struct qt_touch_extension *touch_extension;
gabomdq@8082
    36
};
gabomdq@8082
    37
gabomdq@8082
    38
gabomdq@8082
    39
/**
gabomdq@8082
    40
 * Qt TouchPointState
gabomdq@8082
    41
 * adapted from qtbase/src/corelib/global/qnamespace.h
gabomdq@8082
    42
 **/
gabomdq@8082
    43
enum QtWaylandTouchPointState {
gabomdq@8082
    44
    QtWaylandTouchPointPressed    = 0x01,
gabomdq@8082
    45
    QtWaylandTouchPointMoved      = 0x02,
gabomdq@8082
    46
    /*
gabomdq@8082
    47
    Never sent by the server:
gabomdq@8082
    48
    QtWaylandTouchPointStationary = 0x04,
gabomdq@8082
    49
    */
gabomdq@8082
    50
    QtWaylandTouchPointReleased   = 0x08,
gabomdq@8082
    51
};
gabomdq@8082
    52
gabomdq@8082
    53
static void
gabomdq@8082
    54
touch_handle_touch(void *data,
gabomdq@8082
    55
        struct qt_touch_extension *qt_touch_extension,
gabomdq@8082
    56
        uint32_t time,
gabomdq@8082
    57
        uint32_t id,
gabomdq@8082
    58
        uint32_t state,
gabomdq@8082
    59
        int32_t x,
gabomdq@8082
    60
        int32_t y,
gabomdq@8082
    61
        int32_t normalized_x,
gabomdq@8082
    62
        int32_t normalized_y,
gabomdq@8082
    63
        int32_t width,
gabomdq@8082
    64
        int32_t height,
gabomdq@8082
    65
        uint32_t pressure,
gabomdq@8082
    66
        int32_t velocity_x,
gabomdq@8082
    67
        int32_t velocity_y,
gabomdq@8082
    68
        uint32_t flags,
gabomdq@8082
    69
        struct wl_array *rawdata)
gabomdq@8082
    70
{
gabomdq@8082
    71
    /**
gabomdq@8082
    72
     * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent
gabomdq@8082
    73
     * (src/compositor/wayland_wrapper/qwltouch.cpp)
gabomdq@8082
    74
     **/
gabomdq@8082
    75
gabomdq@8082
    76
    float FIXED_TO_FLOAT = 1. / 10000.;
gabomdq@8082
    77
    float xf = FIXED_TO_FLOAT * x;
gabomdq@8082
    78
    float yf = FIXED_TO_FLOAT * y;
gabomdq@8082
    79
gabomdq@8082
    80
    float PRESSURE_TO_FLOAT = 1. / 255.;
gabomdq@8082
    81
    float pressuref = PRESSURE_TO_FLOAT * pressure;
gabomdq@8082
    82
gabomdq@8082
    83
    uint32_t touchState = state & 0xFFFF;
gabomdq@8082
    84
    /*
gabomdq@8082
    85
    Other fields that are sent by the server (qwltouch.cpp),
gabomdq@8082
    86
    but not used at the moment can be decoded in this way:
gabomdq@8082
    87
gabomdq@8082
    88
    uint32_t sentPointCount = state >> 16;
gabomdq@8082
    89
    uint32_t touchFlags = flags & 0xFFFF;
gabomdq@8082
    90
    uint32_t capabilities = flags >> 16;
gabomdq@8082
    91
    */
gabomdq@8082
    92
slime73@12996
    93
    SDL_Window* window = NULL;
slime73@12996
    94
philipp@9726
    95
    SDL_TouchID deviceId = 1;
slime73@12404
    96
    if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "qt_touch_extension") < 0) {
slouken@12201
    97
         SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
slouken@12201
    98
    }
gabomdq@8082
    99
slime73@12996
   100
    /* FIXME: This should be the window the given wayland surface is associated
slime73@12996
   101
     * with, but how do we get the wayland surface? */
slime73@12996
   102
    window = SDL_GetMouseFocus();
slime73@12996
   103
    if (window == NULL) {
slime73@12996
   104
        window = SDL_GetKeyboardFocus();
slime73@12996
   105
    }
slime73@12996
   106
gabomdq@8082
   107
    switch (touchState) {
gabomdq@8082
   108
        case QtWaylandTouchPointPressed:
gabomdq@8082
   109
        case QtWaylandTouchPointReleased:
slime73@12996
   110
            SDL_SendTouch(deviceId, (SDL_FingerID)id, window,
gabomdq@8082
   111
                    (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
gabomdq@8082
   112
                    xf, yf, pressuref);
gabomdq@8082
   113
            break;
gabomdq@8082
   114
        case QtWaylandTouchPointMoved:
slime73@12996
   115
            SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, window, xf, yf, pressuref);
gabomdq@8082
   116
            break;
gabomdq@8082
   117
        default:
gabomdq@8082
   118
            /* Should not happen */
gabomdq@8082
   119
            break;
gabomdq@8082
   120
    }
gabomdq@8082
   121
}
gabomdq@8082
   122
gabomdq@8082
   123
static void
gabomdq@8082
   124
touch_handle_configure(void *data,
gabomdq@8082
   125
        struct qt_touch_extension *qt_touch_extension,
gabomdq@8082
   126
        uint32_t flags)
gabomdq@8082
   127
{
gabomdq@8082
   128
}
gabomdq@8082
   129
gabomdq@8104
   130
gabomdq@8082
   131
/* wayland-qt-touch-extension.c BEGINS */
gabomdq@8082
   132
gabomdq@8082
   133
static const struct qt_touch_extension_listener touch_listener = {
gabomdq@8082
   134
    touch_handle_touch,
gabomdq@8082
   135
    touch_handle_configure,
gabomdq@8082
   136
};
gabomdq@8082
   137
gabomdq@8082
   138
static const struct wl_interface *qt_touch_extension_types[] = {
gabomdq@8082
   139
    NULL,
gabomdq@8082
   140
    NULL,
gabomdq@8082
   141
    NULL,
gabomdq@8082
   142
    NULL,
gabomdq@8082
   143
    NULL,
gabomdq@8082
   144
    NULL,
gabomdq@8082
   145
    NULL,
gabomdq@8082
   146
    NULL,
gabomdq@8082
   147
    NULL,
gabomdq@8082
   148
    NULL,
gabomdq@8082
   149
    NULL,
gabomdq@8082
   150
    NULL,
gabomdq@8082
   151
    NULL,
gabomdq@8082
   152
    NULL,
gabomdq@8082
   153
};
gabomdq@8082
   154
gabomdq@8082
   155
static const struct wl_message qt_touch_extension_requests[] = {
gabomdq@8082
   156
    { "dummy", "", qt_touch_extension_types + 0 },
gabomdq@8082
   157
};
gabomdq@8082
   158
gabomdq@8082
   159
static const struct wl_message qt_touch_extension_events[] = {
gabomdq@8082
   160
    { "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 },
gabomdq@8082
   161
    { "configure", "u", qt_touch_extension_types + 0 },
gabomdq@8082
   162
};
gabomdq@8082
   163
gabomdq@8082
   164
WL_EXPORT const struct wl_interface qt_touch_extension_interface = {
gabomdq@8082
   165
    "qt_touch_extension", 1,
gabomdq@8082
   166
    1, qt_touch_extension_requests,
gabomdq@8082
   167
    2, qt_touch_extension_events,
gabomdq@8082
   168
};
gabomdq@8082
   169
gabomdq@8082
   170
/* wayland-qt-touch-extension.c ENDS */
gabomdq@8082
   171
gabomdq@8082
   172
/* wayland-qt-windowmanager.c BEGINS */
gabomdq@8082
   173
static const struct wl_interface *qt_windowmanager_types[] = {
gabomdq@8082
   174
    NULL,
gabomdq@8082
   175
    NULL,
gabomdq@8082
   176
};
gabomdq@8082
   177
gabomdq@8082
   178
static const struct wl_message qt_windowmanager_requests[] = {
gabomdq@8082
   179
    { "open_url", "us", qt_windowmanager_types + 0 },
gabomdq@8082
   180
};
gabomdq@8082
   181
gabomdq@8082
   182
static const struct wl_message qt_windowmanager_events[] = {
gabomdq@8082
   183
    { "hints", "i", qt_windowmanager_types + 0 },
gabomdq@8082
   184
    { "quit", "", qt_windowmanager_types + 0 },
gabomdq@8082
   185
};
gabomdq@8082
   186
gabomdq@8082
   187
WL_EXPORT const struct wl_interface qt_windowmanager_interface = {
gabomdq@8082
   188
    "qt_windowmanager", 1,
gabomdq@8082
   189
    1, qt_windowmanager_requests,
gabomdq@8082
   190
    2, qt_windowmanager_events,
gabomdq@8082
   191
};
gabomdq@8082
   192
/* wayland-qt-windowmanager.c ENDS */
gabomdq@8082
   193
gabomdq@8082
   194
/* wayland-qt-surface-extension.c BEGINS */
gabomdq@8082
   195
extern const struct wl_interface qt_extended_surface_interface;
gabomdq@8104
   196
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
gabomdq@8082
   197
extern const struct wl_interface wl_surface_interface;
gabomdq@8104
   198
#endif
gabomdq@8082
   199
gabomdq@8082
   200
static const struct wl_interface *qt_surface_extension_types[] = {
gabomdq@8082
   201
    NULL,
gabomdq@8082
   202
    NULL,
gabomdq@8082
   203
    &qt_extended_surface_interface,
gabomdq@8104
   204
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
gabomdq@8104
   205
    /* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ? 
gabomdq@8104
   206
     * The value comes from auto generated code and does 
gabomdq@8104
   207
     * not appear to actually be used anywhere
gabomdq@8104
   208
     */
gabomdq@8104
   209
    NULL, 
gabomdq@8104
   210
#else
gabomdq@8082
   211
    &wl_surface_interface,
gabomdq@8104
   212
#endif    
gabomdq@8082
   213
};
gabomdq@8082
   214
gabomdq@8082
   215
static const struct wl_message qt_surface_extension_requests[] = {
gabomdq@8082
   216
    { "get_extended_surface", "no", qt_surface_extension_types + 2 },
gabomdq@8082
   217
};
gabomdq@8082
   218
gabomdq@8082
   219
WL_EXPORT const struct wl_interface qt_surface_extension_interface = {
gabomdq@8082
   220
    "qt_surface_extension", 1,
gabomdq@8082
   221
    1, qt_surface_extension_requests,
gabomdq@8082
   222
    0, NULL,
gabomdq@8082
   223
};
gabomdq@8082
   224
gabomdq@8082
   225
static const struct wl_message qt_extended_surface_requests[] = {
gabomdq@8082
   226
    { "update_generic_property", "sa", qt_surface_extension_types + 0 },
gabomdq@8082
   227
    { "set_content_orientation", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   228
    { "set_window_flags", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   229
};
gabomdq@8082
   230
gabomdq@8082
   231
static const struct wl_message qt_extended_surface_events[] = {
gabomdq@8082
   232
    { "onscreen_visibility", "i", qt_surface_extension_types + 0 },
gabomdq@8082
   233
    { "set_generic_property", "sa", qt_surface_extension_types + 0 },
gabomdq@8082
   234
    { "close", "", qt_surface_extension_types + 0 },
gabomdq@8082
   235
};
gabomdq@8082
   236
gabomdq@8082
   237
WL_EXPORT const struct wl_interface qt_extended_surface_interface = {
gabomdq@8082
   238
    "qt_extended_surface", 1,
gabomdq@8082
   239
    3, qt_extended_surface_requests,
gabomdq@8082
   240
    3, qt_extended_surface_events,
gabomdq@8082
   241
};
gabomdq@8082
   242
gabomdq@8082
   243
/* wayland-qt-surface-extension.c ENDS */
gabomdq@8082
   244
gabomdq@8082
   245
void
gabomdq@8082
   246
Wayland_touch_create(SDL_VideoData *data, uint32_t id)
gabomdq@8082
   247
{
icculus@8721
   248
    struct SDL_WaylandTouch *touch;
icculus@8721
   249
gabomdq@8082
   250
    if (data->touch) {
gabomdq@8082
   251
        Wayland_touch_destroy(data);
gabomdq@8082
   252
    }
gabomdq@8082
   253
icculus@8721
   254
    /* !!! FIXME: check for failure, call SDL_OutOfMemory() */
icculus@8721
   255
    data->touch = SDL_malloc(sizeof(struct SDL_WaylandTouch));
gabomdq@8082
   256
icculus@8721
   257
    touch = data->touch;
gabomdq@8082
   258
    touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1);
gabomdq@8082
   259
    qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data);
gabomdq@8082
   260
}
gabomdq@8082
   261
gabomdq@8082
   262
void
gabomdq@8082
   263
Wayland_touch_destroy(SDL_VideoData *data)
gabomdq@8082
   264
{
gabomdq@8082
   265
    if (data->touch) {
gabomdq@8082
   266
        struct SDL_WaylandTouch *touch = data->touch;
gabomdq@8082
   267
        if (touch->touch_extension) {
gabomdq@8082
   268
            qt_touch_extension_destroy(touch->touch_extension);
gabomdq@8082
   269
        }
gabomdq@8082
   270
icculus@8721
   271
        SDL_free(data->touch);
gabomdq@8082
   272
        data->touch = NULL;
gabomdq@8082
   273
    }
gabomdq@8082
   274
}
gabomdq@8082
   275
gabomdq@8082
   276
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */