src/events/SDL_windowevents.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 16 Dec 2009 00:55:33 +0000
changeset 3573 41cd18e05965
parent 3502 98a819296cdc
child 3685 64ce267332c6
permissions -rw-r--r--
Fixed bug #666

Don't let the event queue overflow with resize events
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* Window event handling code for SDL */
    25 
    26 #include "SDL_events.h"
    27 #include "SDL_events_c.h"
    28 #include "SDL_mouse_c.h"
    29 #include "../video/SDL_sysvideo.h"
    30 
    31 
    32 static int
    33 RemovePendingSizeEvents(void * userdata, SDL_Event *event)
    34 {
    35     SDL_Event *new_event = (SDL_Event *)userdata;
    36 
    37     if (event->type == SDL_WINDOWEVENT &&
    38         event->window.event == SDL_WINDOWEVENT_RESIZED &&
    39         event->window.windowID == new_event->window.windowID) {
    40         /* We're about to post a new size event, drop the old one */
    41         return 0;
    42     }
    43     return 1;
    44 }
    45 
    46 int
    47 SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1,
    48                     int data2)
    49 {
    50     int posted;
    51     SDL_Window *window;
    52 
    53     window = SDL_GetWindowFromID(windowID);
    54     if (!window) {
    55         return 0;
    56     }
    57     switch (windowevent) {
    58     case SDL_WINDOWEVENT_SHOWN:
    59         if (window->flags & SDL_WINDOW_SHOWN) {
    60             return 0;
    61         }
    62         window->flags |= SDL_WINDOW_SHOWN;
    63         SDL_OnWindowShown(window);
    64         break;
    65     case SDL_WINDOWEVENT_HIDDEN:
    66         if (!(window->flags & SDL_WINDOW_SHOWN)) {
    67             return 0;
    68         }
    69         window->flags &= ~SDL_WINDOW_SHOWN;
    70         SDL_OnWindowHidden(window);
    71         break;
    72     case SDL_WINDOWEVENT_MOVED:
    73         if (window->flags & SDL_WINDOW_FULLSCREEN) {
    74             return 0;
    75         }
    76         if (data1 == SDL_WINDOWPOS_UNDEFINED) {
    77             data1 = window->x;
    78         }
    79         if (data2 == SDL_WINDOWPOS_UNDEFINED) {
    80             data2 = window->y;
    81         }
    82         if (data1 == window->x && data2 == window->y) {
    83             return 0;
    84         }
    85         window->x = data1;
    86         window->y = data2;
    87         break;
    88     case SDL_WINDOWEVENT_RESIZED:
    89         if (window->flags & SDL_WINDOW_FULLSCREEN) {
    90             return 0;
    91         }
    92         if (data1 == window->w && data2 == window->h) {
    93             return 0;
    94         }
    95         window->w = data1;
    96         window->h = data2;
    97         SDL_OnWindowResized(window);
    98         break;
    99     case SDL_WINDOWEVENT_MINIMIZED:
   100         if (window->flags & SDL_WINDOW_MINIMIZED) {
   101             return 0;
   102         }
   103         window->flags |= SDL_WINDOW_MINIMIZED;
   104         SDL_OnWindowMinimized(window);
   105         break;
   106     case SDL_WINDOWEVENT_MAXIMIZED:
   107         if (window->flags & SDL_WINDOW_MAXIMIZED) {
   108             return 0;
   109         }
   110         window->flags |= SDL_WINDOW_MAXIMIZED;
   111         break;
   112     case SDL_WINDOWEVENT_RESTORED:
   113         if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
   114             return 0;
   115         }
   116         window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
   117         SDL_OnWindowRestored(window);
   118         break;
   119     case SDL_WINDOWEVENT_ENTER:
   120         if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
   121             return 0;
   122         }
   123         window->flags |= SDL_WINDOW_MOUSE_FOCUS;
   124         break;
   125     case SDL_WINDOWEVENT_LEAVE:
   126         if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
   127             return 0;
   128         }
   129         window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
   130         break;
   131     case SDL_WINDOWEVENT_FOCUS_GAINED:
   132         if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
   133             return 0;
   134         }
   135         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   136         SDL_OnWindowFocusGained(window);
   137         break;
   138     case SDL_WINDOWEVENT_FOCUS_LOST:
   139         if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   140             return 0;
   141         }
   142         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
   143         SDL_OnWindowFocusLost(window);
   144         break;
   145     }
   146 
   147     /* Post the event, if desired */
   148     posted = 0;
   149     if (SDL_ProcessEvents[SDL_WINDOWEVENT] == SDL_ENABLE) {
   150         SDL_Event event;
   151         event.type = SDL_WINDOWEVENT;
   152         event.window.event = windowevent;
   153         event.window.data1 = data1;
   154         event.window.data2 = data2;
   155         event.window.windowID = windowID;
   156 
   157         /* Fixes queue overflow with resize events that aren't processed */
   158         if (windowevent == SDL_WINDOWEVENT_RESIZED) {
   159             SDL_FilterEvents(RemovePendingSizeEvents, &event);
   160         }
   161 
   162         posted = (SDL_PushEvent(&event) > 0);
   163     }
   164     return (posted);
   165 }
   166 
   167 /* vi: set ts=4 sw=4 expandtab: */