Implemented SetWindowHitTest() for Wayland (thanks, x414e54!).
authorRyan C. Gordon <icculus@icculus.org>
Sun, 12 Apr 2015 20:40:06 -0400
changeset 9554879f71e1478b
parent 9553 75dca0c33be6
child 9555 fff4b6354b99
Implemented SetWindowHitTest() for Wayland (thanks, x414e54!).

Fixes Bugzilla #2941.
src/video/wayland/SDL_waylandevents.c
src/video/wayland/SDL_waylandvideo.c
src/video/wayland/SDL_waylandwindow.c
src/video/wayland/SDL_waylandwindow.h
     1.1 --- a/src/video/wayland/SDL_waylandevents.c	Sun Apr 12 20:28:28 2015 -0400
     1.2 +++ b/src/video/wayland/SDL_waylandevents.c	Sun Apr 12 20:40:06 2015 -0400
     1.3 @@ -52,6 +52,10 @@
     1.4      SDL_WindowData *pointer_focus;
     1.5      SDL_WindowData *keyboard_focus;
     1.6  
     1.7 +    /* Last motion location */
     1.8 +    wl_fixed_t sx_w;
     1.9 +    wl_fixed_t sy_w;
    1.10 +    
    1.11      struct {
    1.12          struct xkb_keymap *keymap;
    1.13          struct xkb_state *state;
    1.14 @@ -119,6 +123,8 @@
    1.15  {
    1.16      struct SDL_WaylandInput *input = data;
    1.17      SDL_WindowData *window = input->pointer_focus;
    1.18 +    input->sx_w = sx_w;
    1.19 +    input->sy_w = sy_w;
    1.20      int sx = wl_fixed_to_int(sx_w);
    1.21      int sy = wl_fixed_to_int(sy_w);
    1.22      if (input->pointer_focus) {
    1.23 @@ -126,6 +132,70 @@
    1.24      }
    1.25  }
    1.26  
    1.27 +static SDL_bool
    1.28 +ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
    1.29 +{
    1.30 +    SDL_WindowData *window_data = input->pointer_focus;
    1.31 +    SDL_Window *window = window_data->sdlwindow;
    1.32 +    SDL_bool ret = SDL_FALSE;
    1.33 +
    1.34 +    if (window->hit_test) {
    1.35 +        const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
    1.36 +        const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
    1.37 +        switch (rc) {
    1.38 +            case SDL_HITTEST_DRAGGABLE: {
    1.39 +                    wl_shell_surface_move(window_data->shell_surface, input->seat, serial);
    1.40 +                    ret = SDL_TRUE;
    1.41 +                }
    1.42 +                break;
    1.43 +            case SDL_HITTEST_RESIZE_TOPLEFT: {
    1.44 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial, WL_SHELL_SURFACE_RESIZE_TOP_LEFT);
    1.45 +                    ret = SDL_TRUE;
    1.46 +                }
    1.47 +                break;
    1.48 +            case SDL_HITTEST_RESIZE_TOP: {
    1.49 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial, WL_SHELL_SURFACE_RESIZE_TOP);
    1.50 +                    ret = SDL_TRUE;
    1.51 +                }
    1.52 +                break;
    1.53 +            case SDL_HITTEST_RESIZE_TOPRIGHT: {
    1.54 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial,  WL_SHELL_SURFACE_RESIZE_TOP_RIGHT);
    1.55 +                    ret = SDL_TRUE;
    1.56 +                }
    1.57 +                break;
    1.58 +            case SDL_HITTEST_RESIZE_RIGHT: {
    1.59 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial, WL_SHELL_SURFACE_RESIZE_RIGHT);
    1.60 +                    ret = SDL_TRUE;
    1.61 +                }
    1.62 +                break;
    1.63 +            case SDL_HITTEST_RESIZE_BOTTOMRIGHT: {
    1.64 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial,  WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT);
    1.65 +                    ret = SDL_TRUE;
    1.66 +                }
    1.67 +                break;
    1.68 +            case SDL_HITTEST_RESIZE_BOTTOM: {
    1.69 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial, WL_SHELL_SURFACE_RESIZE_BOTTOM);
    1.70 +                    ret = SDL_TRUE;
    1.71 +                }
    1.72 +                break;
    1.73 +            case SDL_HITTEST_RESIZE_BOTTOMLEFT: {
    1.74 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT);
    1.75 +                    ret = SDL_TRUE;
    1.76 +                }
    1.77 +                break;
    1.78 +            case SDL_HITTEST_RESIZE_LEFT: {
    1.79 +                    wl_shell_surface_resize(window_data->shell_surface, input->seat, serial, WL_SHELL_SURFACE_RESIZE_LEFT);
    1.80 +                    ret = SDL_TRUE;
    1.81 +                }
    1.82 +                break;
    1.83 +            default:
    1.84 +                break;
    1.85 +        }
    1.86 +    }
    1.87 +
    1.88 +    return ret;
    1.89 +}
    1.90 +
    1.91  static void
    1.92  pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
    1.93                        uint32_t time, uint32_t button, uint32_t state_w)
    1.94 @@ -139,6 +209,9 @@
    1.95          switch (button) {
    1.96              case BTN_LEFT:
    1.97                  sdl_button = SDL_BUTTON_LEFT;
    1.98 +                if (ProcessHitTest(data, serial)) {
    1.99 +                    return;  /* don't pass this event on to app. */
   1.100 +                }
   1.101                  break;
   1.102              case BTN_MIDDLE:
   1.103                  sdl_button = SDL_BUTTON_MIDDLE;
   1.104 @@ -364,7 +437,8 @@
   1.105  
   1.106      input->display = d;
   1.107      input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
   1.108 -
   1.109 +    input->sx_w = wl_fixed_from_int(0);
   1.110 +    input->sy_w = wl_fixed_from_int(0);
   1.111      d->input = input;
   1.112  
   1.113      wl_seat_add_listener(input->seat, &seat_listener, input);
     2.1 --- a/src/video/wayland/SDL_waylandvideo.c	Sun Apr 12 20:28:28 2015 -0400
     2.2 +++ b/src/video/wayland/SDL_waylandvideo.c	Sun Apr 12 20:40:06 2015 -0400
     2.3 @@ -119,6 +119,7 @@
     2.4      device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
     2.5      device->SetWindowSize = Wayland_SetWindowSize;
     2.6      device->DestroyWindow = Wayland_DestroyWindow;
     2.7 +    device->SetWindowHitTest = Wayland_SetWindowHitTest;
     2.8  
     2.9      device->free = Wayland_DeleteDevice;
    2.10  
     3.1 --- a/src/video/wayland/SDL_waylandwindow.c	Sun Apr 12 20:28:28 2015 -0400
     3.2 +++ b/src/video/wayland/SDL_waylandwindow.c	Sun Apr 12 20:40:06 2015 -0400
     3.3 @@ -109,6 +109,12 @@
     3.4      return SDL_TRUE;
     3.5  }
     3.6  
     3.7 +int
     3.8 +Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
     3.9 +{
    3.10 +    return 0;  /* just succeed, the real work is done elsewhere. */
    3.11 +}
    3.12 +
    3.13  void Wayland_ShowWindow(_THIS, SDL_Window *window)
    3.14  {
    3.15      SDL_WindowData *wind = window->driverdata;
     4.1 --- a/src/video/wayland/SDL_waylandwindow.h	Sun Apr 12 20:28:28 2015 -0400
     4.2 +++ b/src/video/wayland/SDL_waylandwindow.h	Sun Apr 12 20:40:06 2015 -0400
     4.3 @@ -55,6 +55,7 @@
     4.4  
     4.5  extern SDL_bool
     4.6  Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
     4.7 +extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
     4.8  
     4.9  #endif /* _SDL_waylandwindow_h */
    4.10