SDL_windowevents.c (6585B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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 31static int 32RemovePendingResizedEvents(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 45static int 46RemovePendingSizeChangedEvents(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 59static int 60RemovePendingMoveEvents(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 73int 74SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, 75 int data2) 76{ 77 int posted; 78 79 if (!window) { 80 return 0; 81 } 82 switch (windowevent) { 83 case SDL_WINDOWEVENT_SHOWN: 84 if (window->flags & SDL_WINDOW_SHOWN) { 85 return 0; 86 } 87 window->flags &= ~SDL_WINDOW_HIDDEN; 88 window->flags |= SDL_WINDOW_SHOWN; 89 SDL_OnWindowShown(window); 90 break; 91 case SDL_WINDOWEVENT_HIDDEN: 92 if (!(window->flags & SDL_WINDOW_SHOWN)) { 93 return 0; 94 } 95 window->flags &= ~SDL_WINDOW_SHOWN; 96 window->flags |= SDL_WINDOW_HIDDEN; 97 SDL_OnWindowHidden(window); 98 break; 99 case SDL_WINDOWEVENT_MOVED: 100 if (SDL_WINDOWPOS_ISUNDEFINED(data1) || 101 SDL_WINDOWPOS_ISUNDEFINED(data2)) { 102 return 0; 103 } 104 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { 105 window->windowed.x = data1; 106 window->windowed.y = data2; 107 } 108 if (data1 == window->x && data2 == window->y) { 109 return 0; 110 } 111 window->x = data1; 112 window->y = data2; 113 break; 114 case SDL_WINDOWEVENT_RESIZED: 115 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { 116 window->windowed.w = data1; 117 window->windowed.h = data2; 118 } 119 if (data1 == window->w && data2 == window->h) { 120 return 0; 121 } 122 window->w = data1; 123 window->h = data2; 124 SDL_OnWindowResized(window); 125 break; 126 case SDL_WINDOWEVENT_MINIMIZED: 127 if (window->flags & SDL_WINDOW_MINIMIZED) { 128 return 0; 129 } 130 window->flags |= SDL_WINDOW_MINIMIZED; 131 SDL_OnWindowMinimized(window); 132 break; 133 case SDL_WINDOWEVENT_MAXIMIZED: 134 if (window->flags & SDL_WINDOW_MAXIMIZED) { 135 return 0; 136 } 137 window->flags |= SDL_WINDOW_MAXIMIZED; 138 break; 139 case SDL_WINDOWEVENT_RESTORED: 140 if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) { 141 return 0; 142 } 143 window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED); 144 SDL_OnWindowRestored(window); 145 break; 146 case SDL_WINDOWEVENT_ENTER: 147 if (window->flags & SDL_WINDOW_MOUSE_FOCUS) { 148 return 0; 149 } 150 window->flags |= SDL_WINDOW_MOUSE_FOCUS; 151 SDL_OnWindowEnter(window); 152 break; 153 case SDL_WINDOWEVENT_LEAVE: 154 if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) { 155 return 0; 156 } 157 window->flags &= ~SDL_WINDOW_MOUSE_FOCUS; 158 SDL_OnWindowLeave(window); 159 break; 160 case SDL_WINDOWEVENT_FOCUS_GAINED: 161 if (window->flags & SDL_WINDOW_INPUT_FOCUS) { 162 return 0; 163 } 164 window->flags |= SDL_WINDOW_INPUT_FOCUS; 165 SDL_OnWindowFocusGained(window); 166 break; 167 case SDL_WINDOWEVENT_FOCUS_LOST: 168 if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { 169 return 0; 170 } 171 window->flags &= ~SDL_WINDOW_INPUT_FOCUS; 172 SDL_OnWindowFocusLost(window); 173 break; 174 } 175 176 /* Post the event, if desired */ 177 posted = 0; 178 if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) { 179 SDL_Event event; 180 event.type = SDL_WINDOWEVENT; 181 event.window.event = windowevent; 182 event.window.data1 = data1; 183 event.window.data2 = data2; 184 event.window.windowID = window->id; 185 186 /* Fixes queue overflow with resize events that aren't processed */ 187 if (windowevent == SDL_WINDOWEVENT_RESIZED) { 188 SDL_FilterEvents(RemovePendingResizedEvents, &event); 189 } 190 if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) { 191 SDL_FilterEvents(RemovePendingSizeChangedEvents, &event); 192 } 193 if (windowevent == SDL_WINDOWEVENT_MOVED) { 194 SDL_FilterEvents(RemovePendingMoveEvents, &event); 195 } 196 197 posted = (SDL_PushEvent(&event) > 0); 198 } 199 200 if (windowevent == SDL_WINDOWEVENT_CLOSE) { 201 if ( !window->prev && !window->next ) { 202 /* This is the last window in the list so send the SDL_QUIT event */ 203 SDL_SendQuit(); 204 } 205 } 206 207 return (posted); 208} 209 210/* vi: set ts=4 sw=4 expandtab: */