src/events/SDL_windowevents.c
author Sam Lantinga
Mon, 14 Aug 2017 20:25:53 -0700
changeset 11297 905d34b4033c
parent 11272 d60ede5a0c2e
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Added missing files from the previous commit
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../SDL_internal.h"
    22 
    23 /* Window event handling code for SDL */
    24 
    25 #include "SDL_events.h"
    26 #include "SDL_events_c.h"
    27 #include "SDL_mouse_c.h"
    28 #include "../video/SDL_sysvideo.h"
    29 
    30 
    31 static int SDLCALL
    32 RemovePendingResizedEvents(void * userdata, SDL_Event *event)
    33 {
    34     SDL_Event *new_event = (SDL_Event *)userdata;
    35 
    36     if (event->type == SDL_WINDOWEVENT &&
    37         event->window.event == SDL_WINDOWEVENT_RESIZED &&
    38         event->window.windowID == new_event->window.windowID) {
    39         /* We're about to post a new size event, drop the old one */
    40         return 0;
    41     }
    42     return 1;
    43 }
    44 
    45 static int SDLCALL
    46 RemovePendingSizeChangedEvents(void * userdata, SDL_Event *event)
    47 {
    48     SDL_Event *new_event = (SDL_Event *)userdata;
    49 
    50     if (event->type == SDL_WINDOWEVENT &&
    51         event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
    52         event->window.windowID == new_event->window.windowID) {
    53         /* We're about to post a new size event, drop the old one */
    54         return 0;
    55     }
    56     return 1;
    57 }
    58 
    59 static int SDLCALL
    60 RemovePendingMoveEvents(void * userdata, SDL_Event *event)
    61 {
    62     SDL_Event *new_event = (SDL_Event *)userdata;
    63 
    64     if (event->type == SDL_WINDOWEVENT &&
    65         event->window.event == SDL_WINDOWEVENT_MOVED &&
    66         event->window.windowID == new_event->window.windowID) {
    67         /* We're about to post a new move event, drop the old one */
    68         return 0;
    69     }
    70     return 1;
    71 }
    72 
    73 static int SDLCALL
    74 RemovePendingExposedEvents(void * userdata, SDL_Event *event)
    75 {
    76     SDL_Event *new_event = (SDL_Event *)userdata;
    77 
    78     if (event->type == SDL_WINDOWEVENT &&
    79         event->window.event == SDL_WINDOWEVENT_EXPOSED &&
    80         event->window.windowID == new_event->window.windowID) {
    81         /* We're about to post a new exposed event, drop the old one */
    82         return 0;
    83     }
    84     return 1;
    85 }
    86 
    87 int
    88 SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
    89                     int data2)
    90 {
    91     int posted;
    92 
    93     if (!window) {
    94         return 0;
    95     }
    96     switch (windowevent) {
    97     case SDL_WINDOWEVENT_SHOWN:
    98         if (window->flags & SDL_WINDOW_SHOWN) {
    99             return 0;
   100         }
   101         window->flags &= ~SDL_WINDOW_HIDDEN;
   102         window->flags |= SDL_WINDOW_SHOWN;
   103         SDL_OnWindowShown(window);
   104         break;
   105     case SDL_WINDOWEVENT_HIDDEN:
   106         if (!(window->flags & SDL_WINDOW_SHOWN)) {
   107             return 0;
   108         }
   109         window->flags &= ~SDL_WINDOW_SHOWN;
   110         window->flags |= SDL_WINDOW_HIDDEN;
   111         SDL_OnWindowHidden(window);
   112         break;
   113     case SDL_WINDOWEVENT_MOVED:
   114         if (SDL_WINDOWPOS_ISUNDEFINED(data1) ||
   115             SDL_WINDOWPOS_ISUNDEFINED(data2)) {
   116             return 0;
   117         }
   118         if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
   119             window->windowed.x = data1;
   120             window->windowed.y = data2;
   121         }
   122         if (data1 == window->x && data2 == window->y) {
   123             return 0;
   124         }
   125         window->x = data1;
   126         window->y = data2;
   127         break;
   128     case SDL_WINDOWEVENT_RESIZED:
   129         if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
   130             window->windowed.w = data1;
   131             window->windowed.h = data2;
   132         }
   133         if (data1 == window->w && data2 == window->h) {
   134             return 0;
   135         }
   136         window->w = data1;
   137         window->h = data2;
   138         SDL_OnWindowResized(window);
   139         break;
   140     case SDL_WINDOWEVENT_MINIMIZED:
   141         if (window->flags & SDL_WINDOW_MINIMIZED) {
   142             return 0;
   143         }
   144         window->flags &= ~SDL_WINDOW_MAXIMIZED;
   145         window->flags |= SDL_WINDOW_MINIMIZED;
   146         SDL_OnWindowMinimized(window);
   147         break;
   148     case SDL_WINDOWEVENT_MAXIMIZED:
   149         if (window->flags & SDL_WINDOW_MAXIMIZED) {
   150             return 0;
   151         }
   152         window->flags &= ~SDL_WINDOW_MINIMIZED;
   153         window->flags |= SDL_WINDOW_MAXIMIZED;
   154         break;
   155     case SDL_WINDOWEVENT_RESTORED:
   156         if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
   157             return 0;
   158         }
   159         window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
   160         SDL_OnWindowRestored(window);
   161         break;
   162     case SDL_WINDOWEVENT_ENTER:
   163         if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
   164             return 0;
   165         }
   166         window->flags |= SDL_WINDOW_MOUSE_FOCUS;
   167         SDL_OnWindowEnter(window);
   168         break;
   169     case SDL_WINDOWEVENT_LEAVE:
   170         if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
   171             return 0;
   172         }
   173         window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
   174         SDL_OnWindowLeave(window);
   175         break;
   176     case SDL_WINDOWEVENT_FOCUS_GAINED:
   177         if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
   178             return 0;
   179         }
   180         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   181         SDL_OnWindowFocusGained(window);
   182         break;
   183     case SDL_WINDOWEVENT_FOCUS_LOST:
   184         if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   185             return 0;
   186         }
   187         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
   188         SDL_OnWindowFocusLost(window);
   189         break;
   190     }
   191 
   192     /* Post the event, if desired */
   193     posted = 0;
   194     if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
   195         SDL_Event event;
   196         event.type = SDL_WINDOWEVENT;
   197         event.window.event = windowevent;
   198         event.window.data1 = data1;
   199         event.window.data2 = data2;
   200         event.window.windowID = window->id;
   201 
   202         /* Fixes queue overflow with resize events that aren't processed */
   203         if (windowevent == SDL_WINDOWEVENT_RESIZED) {
   204             SDL_FilterEvents(RemovePendingResizedEvents, &event);
   205         }
   206         if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
   207             SDL_FilterEvents(RemovePendingSizeChangedEvents, &event);
   208         }
   209         if (windowevent == SDL_WINDOWEVENT_MOVED) {
   210             SDL_FilterEvents(RemovePendingMoveEvents, &event);
   211         }
   212         if (windowevent == SDL_WINDOWEVENT_EXPOSED) {
   213             SDL_FilterEvents(RemovePendingExposedEvents, &event);
   214         }
   215         posted = (SDL_PushEvent(&event) > 0);
   216     }
   217 
   218     if (windowevent == SDL_WINDOWEVENT_CLOSE) {
   219         if ( !window->prev && !window->next ) {
   220             /* This is the last window in the list so send the SDL_QUIT event */
   221             SDL_SendQuit();
   222         }
   223     }
   224 
   225     return (posted);
   226 }
   227 
   228 /* vi: set ts=4 sw=4 expandtab: */