src/events/SDL_windowevents.c
author Sam Lantinga
Fri, 08 Apr 2011 13:03:26 -0700
changeset 5535 96594ac5fd1a
parent 5525 e427bb6266a4
child 6138 4c64952a58fb
permissions -rw-r--r--
SDL 1.3 is now under the zlib license.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 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_config.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
    32 RemovePendingSizeEvents(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.event == SDL_WINDOWEVENT_SIZE_CHANGED) &&
    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 static int
    47 RemovePendingMoveEvents(void * userdata, SDL_Event *event)
    48 {
    49     SDL_Event *new_event = (SDL_Event *)userdata;
    50 
    51     if (event->type == SDL_WINDOWEVENT &&
    52         event->window.event == SDL_WINDOWEVENT_MOVED &&
    53         event->window.windowID == new_event->window.windowID) {
    54         /* We're about to post a new move event, drop the old one */
    55         return 0;
    56     }
    57     return 1;
    58 }
    59 
    60 int
    61 SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
    62                     int data2)
    63 {
    64     int posted;
    65 
    66     if (!window) {
    67         return 0;
    68     }
    69     switch (windowevent) {
    70     case SDL_WINDOWEVENT_SHOWN:
    71         if (window->flags & SDL_WINDOW_SHOWN) {
    72             return 0;
    73         }
    74         window->flags &= ~SDL_WINDOW_HIDDEN;
    75         window->flags |= SDL_WINDOW_SHOWN;
    76         SDL_OnWindowShown(window);
    77         break;
    78     case SDL_WINDOWEVENT_HIDDEN:
    79         if (!(window->flags & SDL_WINDOW_SHOWN)) {
    80             return 0;
    81         }
    82         window->flags &= ~SDL_WINDOW_SHOWN;
    83         window->flags |= SDL_WINDOW_HIDDEN;
    84         SDL_OnWindowHidden(window);
    85         break;
    86     case SDL_WINDOWEVENT_MOVED:
    87         if (SDL_WINDOWPOS_ISUNDEFINED(data1) ||
    88             SDL_WINDOWPOS_ISUNDEFINED(data2)) {
    89             return 0;
    90         }
    91         if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
    92             window->windowed.x = data1;
    93             window->windowed.y = data2;
    94         }
    95         if (data1 == window->x && data2 == window->y) {
    96             return 0;
    97         }
    98         window->x = data1;
    99         window->y = data2;
   100         break;
   101     case SDL_WINDOWEVENT_RESIZED:
   102         if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
   103             window->windowed.w = data1;
   104             window->windowed.h = data2;
   105         }
   106         if (data1 == window->w && data2 == window->h) {
   107             return 0;
   108         }
   109         window->w = data1;
   110         window->h = data2;
   111         SDL_OnWindowResized(window);
   112         break;
   113     case SDL_WINDOWEVENT_MINIMIZED:
   114         if (window->flags & SDL_WINDOW_MINIMIZED) {
   115             return 0;
   116         }
   117         window->flags |= SDL_WINDOW_MINIMIZED;
   118         SDL_OnWindowMinimized(window);
   119         break;
   120     case SDL_WINDOWEVENT_MAXIMIZED:
   121         if (window->flags & SDL_WINDOW_MAXIMIZED) {
   122             return 0;
   123         }
   124         window->flags |= SDL_WINDOW_MAXIMIZED;
   125         break;
   126     case SDL_WINDOWEVENT_RESTORED:
   127         if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
   128             return 0;
   129         }
   130         window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
   131         SDL_OnWindowRestored(window);
   132         break;
   133     case SDL_WINDOWEVENT_ENTER:
   134         if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
   135             return 0;
   136         }
   137         window->flags |= SDL_WINDOW_MOUSE_FOCUS;
   138         break;
   139     case SDL_WINDOWEVENT_LEAVE:
   140         if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
   141             return 0;
   142         }
   143         window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
   144         break;
   145     case SDL_WINDOWEVENT_FOCUS_GAINED:
   146         if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
   147             return 0;
   148         }
   149         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   150         SDL_OnWindowFocusGained(window);
   151         break;
   152     case SDL_WINDOWEVENT_FOCUS_LOST:
   153         if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   154             return 0;
   155         }
   156         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
   157         SDL_OnWindowFocusLost(window);
   158         break;
   159     }
   160 
   161     /* Post the event, if desired */
   162     posted = 0;
   163     if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
   164         SDL_Event event;
   165         event.type = SDL_WINDOWEVENT;
   166         event.window.event = windowevent;
   167         event.window.data1 = data1;
   168         event.window.data2 = data2;
   169         event.window.windowID = window->id;
   170 
   171         /* Fixes queue overflow with resize events that aren't processed */
   172         if (windowevent == SDL_WINDOWEVENT_RESIZED ||
   173             windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
   174             SDL_FilterEvents(RemovePendingSizeEvents, &event);
   175         }
   176         if (windowevent == SDL_WINDOWEVENT_MOVED) {
   177             SDL_FilterEvents(RemovePendingMoveEvents, &event);
   178         }
   179 
   180         posted = (SDL_PushEvent(&event) > 0);
   181     }
   182 	
   183 	if (windowevent == SDL_WINDOWEVENT_CLOSE) {
   184 		if ( !window->prev && !window->next ) {
   185 			// This is the last window in the list so send the SDL_QUIT event
   186 			SDL_SendQuit();
   187 		}
   188 	}
   189 
   190     return (posted);
   191 }
   192 
   193 /* vi: set ts=4 sw=4 expandtab: */