src/events/SDL_windowevents.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 11 Feb 2011 00:25:44 -0800
changeset 5249 7a963be087ef
parent 5166 4d39eeaad00b
child 5261 595814f561f7
permissions -rw-r--r--
Mostly fixed fullscreen mode on Mac OS X, and you can toggle it on and off.

There are still some problems with the ConvertNSRect() calculations when switching video modes, which causes wierd window positioning issues, and the fullscreen window is still minimized on exit.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 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 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_SHOWN;
    75         SDL_OnWindowShown(window);
    76         break;
    77     case SDL_WINDOWEVENT_HIDDEN:
    78         if (!(window->flags & SDL_WINDOW_SHOWN)) {
    79             return 0;
    80         }
    81         window->flags &= ~SDL_WINDOW_SHOWN;
    82         SDL_OnWindowHidden(window);
    83         break;
    84     case SDL_WINDOWEVENT_MOVED:
    85         if (SDL_WINDOWPOS_ISUNDEFINED(data1) ||
    86             SDL_WINDOWPOS_ISUNDEFINED(data2)) {
    87             return 0;
    88         }
    89         if (window->flags & SDL_WINDOW_FULLSCREEN) {
    90             window->fullscreen.x = data1;
    91             window->fullscreen.y = data1;
    92         } else {
    93             window->windowed.x = data1;
    94             window->windowed.y = data1;
    95         }
    96         if (data1 == window->x && data2 == window->y) {
    97             return 0;
    98         }
    99         window->x = data1;
   100         window->y = data2;
   101 
   102         if (window->flags & SDL_WINDOW_FULLSCREEN) {
   103             /* Do we really want to do this? */
   104             return 0;
   105         }
   106         break;
   107     case SDL_WINDOWEVENT_RESIZED:
   108         if (window->flags & SDL_WINDOW_FULLSCREEN) {
   109             window->fullscreen.w = data1;
   110             window->fullscreen.h = data1;
   111         } else {
   112             window->windowed.w = data1;
   113             window->windowed.h = data1;
   114         }
   115         if (data1 == window->w && data2 == window->h) {
   116             return 0;
   117         }
   118         window->w = data1;
   119         window->h = data2;
   120         SDL_OnWindowResized(window);
   121 
   122         if (window->flags & SDL_WINDOW_FULLSCREEN) {
   123             /* Do we really want to do this? */
   124             return 0;
   125         }
   126         break;
   127     case SDL_WINDOWEVENT_MINIMIZED:
   128         if (window->flags & SDL_WINDOW_MINIMIZED) {
   129             return 0;
   130         }
   131         window->flags |= SDL_WINDOW_MINIMIZED;
   132         SDL_OnWindowMinimized(window);
   133         break;
   134     case SDL_WINDOWEVENT_MAXIMIZED:
   135         if (window->flags & SDL_WINDOW_MAXIMIZED) {
   136             return 0;
   137         }
   138         window->flags |= SDL_WINDOW_MAXIMIZED;
   139         break;
   140     case SDL_WINDOWEVENT_RESTORED:
   141         if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
   142             return 0;
   143         }
   144         window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
   145         SDL_OnWindowRestored(window);
   146         break;
   147     case SDL_WINDOWEVENT_ENTER:
   148         if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
   149             return 0;
   150         }
   151         window->flags |= SDL_WINDOW_MOUSE_FOCUS;
   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         break;
   159     case SDL_WINDOWEVENT_FOCUS_GAINED:
   160         if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
   161             return 0;
   162         }
   163         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   164         SDL_OnWindowFocusGained(window);
   165         break;
   166     case SDL_WINDOWEVENT_FOCUS_LOST:
   167         if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   168             return 0;
   169         }
   170         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
   171         SDL_OnWindowFocusLost(window);
   172         break;
   173     }
   174 
   175     /* Post the event, if desired */
   176     posted = 0;
   177     if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
   178         SDL_Event event;
   179         event.type = SDL_WINDOWEVENT;
   180         event.window.event = windowevent;
   181         event.window.data1 = data1;
   182         event.window.data2 = data2;
   183         event.window.windowID = window->id;
   184 
   185         /* Fixes queue overflow with resize events that aren't processed */
   186         if (windowevent == SDL_WINDOWEVENT_RESIZED) {
   187             SDL_FilterEvents(RemovePendingSizeEvents, &event);
   188         }
   189         if (windowevent == SDL_WINDOWEVENT_MOVED) {
   190             SDL_FilterEvents(RemovePendingMoveEvents, &event);
   191         }
   192 
   193         posted = (SDL_PushEvent(&event) > 0);
   194     }
   195 	
   196 	if (windowevent == SDL_WINDOWEVENT_CLOSE) {
   197 		if ( !window->prev && !window->next ) {
   198 			// This is the last window in the list so send the SDL_QUIT event
   199 			SDL_SendQuit();
   200 		}
   201 	}
   202 
   203     return (posted);
   204 }
   205 
   206 /* vi: set ts=4 sw=4 expandtab: */