src/video/windows/SDL_windowsshape.c
author Alex Szpakowski <slime73@gmail.com>
Sat, 10 Nov 2018 16:15:48 -0400
changeset 12404 eb60e952b13f
parent 11811 5d94cb6b24d3
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.
eligottlieb@4777
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
eligottlieb@4777
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
eligottlieb@4777
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
eligottlieb@4777
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
eligottlieb@4777
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
eligottlieb@4777
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@6044
    24
egottlieb@4850
    25
#include "SDL_assert.h"
slouken@5062
    26
#include "SDL_windowsshape.h"
slouken@5062
    27
#include "SDL_windowsvideo.h"
eligottlieb@4777
    28
eligottlieb@4838
    29
SDL_WindowShaper*
eligottlieb@4838
    30
Win32_CreateShaper(SDL_Window * window) {
eligottlieb@4838
    31
    int resized_properly;
eligottlieb@4838
    32
    SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper));
eligottlieb@4838
    33
    result->window = window;
eligottlieb@4838
    34
    result->mode.mode = ShapeModeDefault;
eligottlieb@4838
    35
    result->mode.parameters.binarizationCutoff = 1;
eligottlieb@4851
    36
    result->userx = result->usery = 0;
eligottlieb@4838
    37
    result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData));
eligottlieb@4838
    38
    ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL;
slouken@7191
    39
    /* Put some driver-data here. */
eligottlieb@4838
    40
    window->shaper = result;
eligottlieb@4838
    41
    resized_properly = Win32_ResizeWindowShape(window);
eligottlieb@4838
    42
    if (resized_properly != 0)
eligottlieb@4838
    43
            return NULL;
slouken@7191
    44
eligottlieb@4838
    45
    return result;
eligottlieb@4785
    46
}
eligottlieb@4785
    47
philipp@10982
    48
static void
egottlieb@4844
    49
CombineRectRegions(SDL_ShapeTree* node,void* closure) {
egottlieb@4850
    50
    HRGN mask_region = *((HRGN*)closure),temp_region = NULL;
eligottlieb@4838
    51
    if(node->kind == OpaqueShape) {
slouken@7191
    52
        /* Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. */
egottlieb@4858
    53
        temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1);
egottlieb@4850
    54
        if(mask_region != NULL) {
egottlieb@4850
    55
            CombineRgn(mask_region,mask_region,temp_region,RGN_OR);
egottlieb@4850
    56
            DeleteObject(temp_region);
slouken@7191
    57
        }
slouken@7191
    58
        else
egottlieb@4850
    59
            *((HRGN*)closure) = temp_region;
slouken@7191
    60
    }
egottlieb@4844
    61
}
egottlieb@4844
    62
eligottlieb@4838
    63
int
egottlieb@4849
    64
Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) {
eligottlieb@4838
    65
    SDL_ShapeData *data;
egottlieb@4850
    66
    HRGN mask_region = NULL;
eligottlieb@4815
    67
icculus@6403
    68
    if( (shaper == NULL) ||
icculus@6403
    69
        (shape == NULL) ||
icculus@6403
    70
        ((shape->format->Amask == 0) && (shape_mode->mode != ShapeModeColorKey)) ||
icculus@6403
    71
        (shape->w != shaper->window->w) ||
icculus@6403
    72
        (shape->h != shaper->window->h) ) {
eligottlieb@4838
    73
        return SDL_INVALID_SHAPE_ARGUMENT;
icculus@6403
    74
    }
icculus@6403
    75
eligottlieb@4838
    76
    data = (SDL_ShapeData*)shaper->driverdata;
eligottlieb@4838
    77
    if(data->mask_tree != NULL)
eligottlieb@4838
    78
        SDL_FreeShapeTree(&data->mask_tree);
egottlieb@4849
    79
    data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape);
slouken@7191
    80
egottlieb@4850
    81
    SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region);
slouken@7191
    82
    SDL_assert(mask_region != NULL);
egottlieb@4844
    83
egottlieb@4844
    84
    SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE);
slouken@7191
    85
eligottlieb@4838
    86
    return 0;
eligottlieb@4785
    87
}
eligottlieb@4785
    88
eligottlieb@4838
    89
int
eligottlieb@4838
    90
Win32_ResizeWindowShape(SDL_Window *window) {
eligottlieb@4838
    91
    SDL_ShapeData* data;
eligottlieb@4815
    92
eligottlieb@4838
    93
    if (window == NULL)
eligottlieb@4838
    94
        return -1;
eligottlieb@4838
    95
    data = (SDL_ShapeData *)window->shaper->driverdata;
eligottlieb@4838
    96
    if (data == NULL)
eligottlieb@4838
    97
        return -1;
slouken@7191
    98
eligottlieb@4838
    99
    if(data->mask_tree != NULL)
eligottlieb@4838
   100
        SDL_FreeShapeTree(&data->mask_tree);
egottlieb@4852
   101
    if(window->shaper->hasshape == SDL_TRUE) {
egottlieb@4852
   102
        window->shaper->userx = window->x;
egottlieb@4852
   103
        window->shaper->usery = window->y;
egottlieb@4852
   104
        SDL_SetWindowPosition(window,-1000,-1000);
slouken@7191
   105
    }
slouken@7191
   106
eligottlieb@4838
   107
    return 0;
eligottlieb@4785
   108
}
slouken@6044
   109
slouken@6044
   110
#endif /* SDL_VIDEO_DRIVER_WINDOWS */