src/events/SDL_windowevents.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 22 Jun 2015 23:36:06 -0700
changeset 9776 952ff8a5076f
parent 9619 b94b6d0bff0f
child 9968 0a420ec24b6a
permissions -rw-r--r--
Fixed bug 3030 - SDL_RecreateWindow fails to restore title, icon, etc.

Adam M.

It loses the title and icon when window recreation fails. For instance, this may happen when trying to create an OpenGL ES window on a system that doesn't support it. But at that point, the title and icon have already been lost.
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
slouken@1895
     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.
slouken@1895
     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:
slouken@1895
    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.
slouken@1895
    20
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@1895
    22
slouken@1895
    23
/* Window event handling code for SDL */
slouken@1895
    24
slouken@1895
    25
#include "SDL_events.h"
slouken@1895
    26
#include "SDL_events_c.h"
slouken@2794
    27
#include "SDL_mouse_c.h"
slouken@1895
    28
#include "../video/SDL_sysvideo.h"
slouken@1895
    29
slouken@3573
    30
slouken@3573
    31
static int
slouken@6512
    32
RemovePendingResizedEvents(void * userdata, SDL_Event *event)
slouken@3573
    33
{
slouken@3573
    34
    SDL_Event *new_event = (SDL_Event *)userdata;
slouken@3573
    35
slouken@3573
    36
    if (event->type == SDL_WINDOWEVENT &&
slouken@6512
    37
        event->window.event == SDL_WINDOWEVENT_RESIZED &&
slouken@6512
    38
        event->window.windowID == new_event->window.windowID) {
slouken@6512
    39
        /* We're about to post a new size event, drop the old one */
slouken@6512
    40
        return 0;
slouken@6512
    41
    }
slouken@6512
    42
    return 1;
slouken@6512
    43
}
slouken@6512
    44
slouken@6512
    45
static int
slouken@6512
    46
RemovePendingSizeChangedEvents(void * userdata, SDL_Event *event)
slouken@6512
    47
{
slouken@6512
    48
    SDL_Event *new_event = (SDL_Event *)userdata;
slouken@6512
    49
slouken@6512
    50
    if (event->type == SDL_WINDOWEVENT &&
slouken@6512
    51
        event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
slouken@3573
    52
        event->window.windowID == new_event->window.windowID) {
slouken@3573
    53
        /* We're about to post a new size event, drop the old one */
slouken@3573
    54
        return 0;
slouken@3573
    55
    }
slouken@3573
    56
    return 1;
slouken@3573
    57
}
slouken@3573
    58
slouken@5042
    59
static int
slouken@5042
    60
RemovePendingMoveEvents(void * userdata, SDL_Event *event)
slouken@5042
    61
{
slouken@5042
    62
    SDL_Event *new_event = (SDL_Event *)userdata;
slouken@5042
    63
slouken@5042
    64
    if (event->type == SDL_WINDOWEVENT &&
slouken@5042
    65
        event->window.event == SDL_WINDOWEVENT_MOVED &&
slouken@5042
    66
        event->window.windowID == new_event->window.windowID) {
slouken@5042
    67
        /* We're about to post a new move event, drop the old one */
slouken@5042
    68
        return 0;
slouken@5042
    69
    }
slouken@5042
    70
    return 1;
slouken@5042
    71
}
slouken@5042
    72
slouken@1895
    73
int
slouken@3685
    74
SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
slouken@1895
    75
                    int data2)
slouken@1895
    76
{
slouken@1895
    77
    int posted;
slouken@1895
    78
slouken@1895
    79
    if (!window) {
slouken@1895
    80
        return 0;
slouken@1895
    81
    }
slouken@1895
    82
    switch (windowevent) {
slouken@1895
    83
    case SDL_WINDOWEVENT_SHOWN:
slouken@1895
    84
        if (window->flags & SDL_WINDOW_SHOWN) {
slouken@1895
    85
            return 0;
slouken@1895
    86
        }
slouken@5383
    87
        window->flags &= ~SDL_WINDOW_HIDDEN;
slouken@1895
    88
        window->flags |= SDL_WINDOW_SHOWN;
slouken@1895
    89
        SDL_OnWindowShown(window);
slouken@1895
    90
        break;
slouken@1895
    91
    case SDL_WINDOWEVENT_HIDDEN:
slouken@1895
    92
        if (!(window->flags & SDL_WINDOW_SHOWN)) {
slouken@1895
    93
            return 0;
slouken@1895
    94
        }
slouken@1895
    95
        window->flags &= ~SDL_WINDOW_SHOWN;
slouken@5383
    96
        window->flags |= SDL_WINDOW_HIDDEN;
slouken@1895
    97
        SDL_OnWindowHidden(window);
slouken@1895
    98
        break;
slouken@1895
    99
    case SDL_WINDOWEVENT_MOVED:
slouken@5249
   100
        if (SDL_WINDOWPOS_ISUNDEFINED(data1) ||
slouken@5249
   101
            SDL_WINDOWPOS_ISUNDEFINED(data2)) {
slouken@1895
   102
            return 0;
slouken@1895
   103
        }
slouken@5398
   104
        if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@5398
   105
            window->windowed.x = data1;
slouken@5398
   106
            window->windowed.y = data2;
slouken@5398
   107
        }
slouken@1895
   108
        if (data1 == window->x && data2 == window->y) {
slouken@1895
   109
            return 0;
slouken@1895
   110
        }
slouken@1915
   111
        window->x = data1;
slouken@1915
   112
        window->y = data2;
slouken@1895
   113
        break;
slouken@1895
   114
    case SDL_WINDOWEVENT_RESIZED:
slouken@5398
   115
        if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@5398
   116
            window->windowed.w = data1;
slouken@5398
   117
            window->windowed.h = data2;
slouken@5398
   118
        }
slouken@1895
   119
        if (data1 == window->w && data2 == window->h) {
slouken@1895
   120
            return 0;
slouken@1895
   121
        }
slouken@1915
   122
        window->w = data1;
slouken@1915
   123
        window->h = data2;
slouken@5166
   124
        SDL_OnWindowResized(window);
slouken@1895
   125
        break;
slouken@1895
   126
    case SDL_WINDOWEVENT_MINIMIZED:
slouken@1895
   127
        if (window->flags & SDL_WINDOW_MINIMIZED) {
slouken@1895
   128
            return 0;
slouken@1895
   129
        }
slouken@1895
   130
        window->flags |= SDL_WINDOW_MINIMIZED;
slouken@3502
   131
        SDL_OnWindowMinimized(window);
slouken@1895
   132
        break;
slouken@1895
   133
    case SDL_WINDOWEVENT_MAXIMIZED:
slouken@1895
   134
        if (window->flags & SDL_WINDOW_MAXIMIZED) {
slouken@1895
   135
            return 0;
slouken@1895
   136
        }
slouken@1895
   137
        window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@1895
   138
        break;
slouken@1895
   139
    case SDL_WINDOWEVENT_RESTORED:
slouken@1895
   140
        if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
slouken@1895
   141
            return 0;
slouken@1895
   142
        }
slouken@1895
   143
        window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
slouken@3502
   144
        SDL_OnWindowRestored(window);
slouken@1895
   145
        break;
slouken@1895
   146
    case SDL_WINDOWEVENT_ENTER:
slouken@1895
   147
        if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
slouken@1895
   148
            return 0;
slouken@1895
   149
        }
slouken@1895
   150
        window->flags |= SDL_WINDOW_MOUSE_FOCUS;
jorgen@7089
   151
        SDL_OnWindowEnter(window);
slouken@1895
   152
        break;
slouken@1895
   153
    case SDL_WINDOWEVENT_LEAVE:
slouken@1895
   154
        if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
slouken@1895
   155
            return 0;
slouken@1895
   156
        }
slouken@1895
   157
        window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
slouken@7191
   158
        SDL_OnWindowLeave(window);
slouken@1895
   159
        break;
slouken@1895
   160
    case SDL_WINDOWEVENT_FOCUS_GAINED:
slouken@1895
   161
        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
slouken@1895
   162
            return 0;
slouken@1895
   163
        }
slouken@1895
   164
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@1895
   165
        SDL_OnWindowFocusGained(window);
slouken@1895
   166
        break;
slouken@1895
   167
    case SDL_WINDOWEVENT_FOCUS_LOST:
slouken@1895
   168
        if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   169
            return 0;
slouken@1895
   170
        }
slouken@1895
   171
        window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
slouken@1895
   172
        SDL_OnWindowFocusLost(window);
slouken@1895
   173
        break;
slouken@1895
   174
    }
slouken@1895
   175
slouken@1895
   176
    /* Post the event, if desired */
slouken@1895
   177
    posted = 0;
slouken@4429
   178
    if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
slouken@1895
   179
        SDL_Event event;
slouken@1895
   180
        event.type = SDL_WINDOWEVENT;
slouken@1895
   181
        event.window.event = windowevent;
slouken@1895
   182
        event.window.data1 = data1;
slouken@1895
   183
        event.window.data2 = data2;
slouken@3685
   184
        event.window.windowID = window->id;
slouken@3573
   185
slouken@3573
   186
        /* Fixes queue overflow with resize events that aren't processed */
slouken@6512
   187
        if (windowevent == SDL_WINDOWEVENT_RESIZED) {
slouken@6512
   188
            SDL_FilterEvents(RemovePendingResizedEvents, &event);
slouken@6512
   189
        }
slouken@6512
   190
        if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
slouken@6512
   191
            SDL_FilterEvents(RemovePendingSizeChangedEvents, &event);
slouken@3573
   192
        }
slouken@5042
   193
        if (windowevent == SDL_WINDOWEVENT_MOVED) {
slouken@5042
   194
            SDL_FilterEvents(RemovePendingMoveEvents, &event);
slouken@5042
   195
        }
slouken@3573
   196
slouken@1895
   197
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   198
    }
slouken@7191
   199
icculus@7609
   200
    if (windowevent == SDL_WINDOWEVENT_CLOSE) {
icculus@7609
   201
        if ( !window->prev && !window->next ) {
icculus@7609
   202
            /* This is the last window in the list so send the SDL_QUIT event */
icculus@7609
   203
            SDL_SendQuit();
icculus@7609
   204
        }
icculus@7609
   205
    }
icculus@7609
   206
slouken@1895
   207
    return (posted);
slouken@1895
   208
}
slouken@1895
   209
slouken@1895
   210
/* vi: set ts=4 sw=4 expandtab: */