Changed drag area API to a hit-testing API.
There were several good arguments for this: it's how Windows works with
WM_NCHITTEST, SDL doesn't need to manage a list of rects, it allows more
control over the regions (how do you use rects to cleanly surround a circular
button?), the callback can be more optimized than a iterating a list of
rects, and you don't have to send an updated list of rects whenever the
window resizes or layout changes.
--- a/.hgignore Tue May 27 15:47:25 2014 -0400
+++ b/.hgignore Wed May 28 01:22:47 2014 -0400
@@ -55,7 +55,6 @@
test/testatomic
test/testaudioinfo
test/testautomation
-test/testdragareas
test/testdraw2
test/testerror
test/testfile
@@ -64,6 +63,7 @@
test/testgl2
test/testgles
test/testhaptic
+test/testhittesting
test/testiconv
test/testime
test/testintersections
--- a/include/SDL_video.h Tue May 27 15:47:25 2014 -0400
+++ b/include/SDL_video.h Wed May 28 01:22:47 2014 -0400
@@ -791,43 +791,51 @@
Uint16 * green,
Uint16 * blue);
+typedef enum
+{
+ SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */
+ SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */
+ /* !!! FIXME: resize enums here. */
+} SDL_HitTestResult;
+
+typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win,
+ const SDL_Point *area,
+ void *data);
+
/**
- * \brief Define regions of a window that can be used to drag it.
- *
- * Normally windows are dragged by decorations provided by the system
- * window manager (usually, a title bar), but for some apps, it makes sense
- * to drag them from somewhere else inside the window itself; for example,
- * one might have a borderless window that wants to be draggable from any
- * part, or simulate its own title bar, etc.
+ * \brief Provide a callback that decides if a window region has special properties.
*
- * This method designates pieces of a given window as "drag areas," which
- * will move the window when the user drags with his mouse, as if she had
- * used the titlebar.
+ * Normally windows are dragged and resized by decorations provided by the
+ * system window manager (a title bar, borders, etc), but for some apps, it
+ * makes sense to drag them from somewhere else inside the window itself; for
+ * example, one might have a borderless window that wants to be draggable
+ * from any part, or simulate its own title bar, etc.
*
- * You may specify multiple drag areas, disconnected or overlapping. This
- * function accepts an array of rectangles. Each call to this function will
- * replace any previously-defined drag areas. To disable drag areas on a
- * window, call this function with a NULL array of zero elements.
- *
- * Drag areas do not automatically resize. If your window changes dimensions
- * you should plan to re-call this function with new drag areas if
- * appropriate.
+ * This function lets the app provide a callback that designates pieces of
+ * a given window as special. This callback is run during event processing
+ * if we need to tell the OS to treat a region of the window specially; the
+ * use of this callback is known as "hit testing."
*
* Mouse input may not be delivered to your application if it is within
- * a drag area; the OS will often apply that input to moving the window and
- * not deliver it to the application.
+ * a special area; the OS will often apply that input to moving the window or
+ * resizing the window and not deliver it to the application.
+ *
+ * Specifying NULL for a callback disables hit-testing. Hit-testing is
+ * disabled by default.
*
* Platforms that don't support this functionality will return -1
- * unconditionally, even if you're attempting to disable drag areas.
+ * unconditionally, even if you're attempting to disable hit-testing.
+ *
+ * Your callback may fire at any time.
*
- * \param window The window to set drag areas on.
- * \param areas An array of SDL_Rects containing num_areas elements.
- * \param num_areas The number of elements in the areas parameter.
+ * \param window The window to set hit-testing on.
+ * \param callback The callback to call when doing a hit-test.
+ * \param callback_data An app-defined void pointer passed to the callback.
* \return 0 on success, -1 on error (including unsupported).
*/
-extern DECLSPEC int SDLCALL SDL_SetWindowDragAreas(SDL_Window * window,
- const SDL_Rect *areas,
- int num_areas);
+extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window,
+ SDL_HitTest callback,
+ void *callback_data);
/**
* \brief Destroy a window.
--- a/src/dynapi/SDL_dynapi_overrides.h Tue May 27 15:47:25 2014 -0400
+++ b/src/dynapi/SDL_dynapi_overrides.h Wed May 28 01:22:47 2014 -0400
@@ -580,4 +580,4 @@
#define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL
#define SDL_WinRTRunApp SDL_WinRTRunApp_REAL
#define SDL_CaptureMouse SDL_CaptureMouse_REAL
-#define SDL_SetWindowDragAreas SDL_SetWindowDragAreas_REAL
+#define SDL_SetWindowHitTest SDL_SetWindowHitTest_REAL
--- a/src/dynapi/SDL_dynapi_procs.h Tue May 27 15:47:25 2014 -0400
+++ b/src/dynapi/SDL_dynapi_procs.h Wed May 28 01:22:47 2014 -0400
@@ -613,4 +613,4 @@
SDL_DYNAPI_PROC(int,SDL_WinRTRunApp,(int a, char **b, void *c),(a,b,c),return)
#endif
SDL_DYNAPI_PROC(int,SDL_CaptureMouse,(SDL_bool a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_SetWindowDragAreas,(SDL_Window *a, const SDL_Rect *b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_SetWindowHitTest,(SDL_Window *a, SDL_HitTest b, void *c),(a,b,c),return)
--- a/src/video/SDL_sysvideo.h Tue May 27 15:47:25 2014 -0400
+++ b/src/video/SDL_sysvideo.h Wed May 28 01:22:47 2014 -0400
@@ -97,8 +97,8 @@
SDL_WindowShaper *shaper;
- int num_drag_areas;
- SDL_Rect *drag_areas;
+ SDL_HitTest hit_test;
+ void *hit_test_data;
SDL_WindowUserData *data;
@@ -264,8 +264,8 @@
/* MessageBox */
int (*ShowMessageBox) (_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid);
- /* Drag areas. Note that (areas) and (num_areas) are also copied to the SDL_Window for you after this call. */
- int (*SetWindowDragAreas)(SDL_Window * window, const SDL_Rect *areas, int num_areas);
+ /* Hit-testing */
+ int (*SetWindowHitTest)(SDL_Window * window, SDL_bool enabled);
/* * * */
/* Data common to all drivers */
--- a/src/video/SDL_video.c Tue May 27 15:47:25 2014 -0400
+++ b/src/video/SDL_video.c Wed May 28 01:22:47 2014 -0400
@@ -1411,8 +1411,8 @@
SDL_FreeSurface(icon);
}
- if (window->num_drag_areas > 0) {
- _this->SetWindowDragAreas(window, window->drag_areas, window->num_drag_areas);
+ if (window->hit_test > 0) {
+ _this->SetWindowHitTest(window, SDL_TRUE);
}
SDL_FinishWindowCreation(window, flags);
@@ -2310,8 +2310,6 @@
_this->windows = window->next;
}
- SDL_free(window->drag_areas);
-
SDL_free(window);
}
@@ -3388,33 +3386,20 @@
}
int
-SDL_SetWindowDragAreas(SDL_Window * window, const SDL_Rect *_areas, int num_areas)
+SDL_SetWindowHitTest(SDL_Window * window, SDL_HitTest callback, void *userdata)
{
- SDL_Rect *areas = NULL;
-
CHECK_WINDOW_MAGIC(window, -1);
- if (!_this->SetWindowDragAreas) {
+ if (!_this->SetWindowHitTest) {
return SDL_Unsupported();
- }
-
- if (num_areas > 0) {
- const size_t len = sizeof (SDL_Rect) * num_areas;
- areas = (SDL_Rect *) SDL_malloc(len);
- if (!areas) {
- return SDL_OutOfMemory();
- }
- SDL_memcpy(areas, _areas, len);
- }
-
- if (_this->SetWindowDragAreas(window, areas, num_areas) == -1) {
- SDL_free(areas);
+ } else if (_this->SetWindowHitTest(window, callback != NULL) == -1) {
return -1;
}
- SDL_free(window->drag_areas);
- window->drag_areas = areas;
- window->num_drag_areas = num_areas;
+ window->hit_test = callback;
+ window->hit_test_data = userdata;
+
+ return 0;
}
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/cocoa/SDL_cocoavideo.m Tue May 27 15:47:25 2014 -0400
+++ b/src/video/cocoa/SDL_cocoavideo.m Wed May 28 01:22:47 2014 -0400
@@ -108,7 +108,7 @@
device->SetWindowGrab = Cocoa_SetWindowGrab;
device->DestroyWindow = Cocoa_DestroyWindow;
device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
- device->SetWindowDragAreas = Cocoa_SetWindowDragAreas;
+ device->SetWindowHitTest = Cocoa_SetWindowHitTest;
device->shape_driver.CreateShaper = Cocoa_CreateShaper;
device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
--- a/src/video/cocoa/SDL_cocoawindow.h Tue May 27 15:47:25 2014 -0400
+++ b/src/video/cocoa/SDL_cocoawindow.h Wed May 28 01:22:47 2014 -0400
@@ -77,7 +77,7 @@
-(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions;
/* See if event is in a drag area, toggle on window dragging. */
--(BOOL) processDragArea:(NSEvent *)theEvent;
+-(BOOL) processHitTest:(NSEvent *)theEvent;
/* Window event handling */
-(void) mouseDown:(NSEvent *) theEvent;
@@ -119,7 +119,6 @@
SDL_bool inWindowMove;
Cocoa_WindowListener *listener;
struct SDL_VideoData *videodata;
- NSView *dragarea;
};
extern int Cocoa_CreateWindow(_THIS, SDL_Window * window);
@@ -144,7 +143,7 @@
extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);
-extern int Cocoa_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas);
+extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
#endif /* _SDL_cocoawindow_h */
--- a/src/video/cocoa/SDL_cocoawindow.m Tue May 27 15:47:25 2014 -0400
+++ b/src/video/cocoa/SDL_cocoawindow.m Wed May 28 01:22:47 2014 -0400
@@ -657,26 +657,20 @@
/*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
}
-- (BOOL)processDragArea:(NSEvent *)theEvent
+- (BOOL)processHitTest:(NSEvent *)theEvent
{
- const int num_areas = _data->window->num_drag_areas;
-
SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]);
- SDL_assert((num_areas > 0) || !isDragAreaRunning);
- if (num_areas > 0) { /* if no drag areas, skip this. */
- int i;
+ if (_data->window->hit_test) { /* if no hit-test, skip this. */
const NSPoint location = [theEvent locationInWindow];
const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) };
- const SDL_Rect *areas = _data->window->drag_areas;
- for (i = 0; i < num_areas; i++) {
- if (SDL_PointInRect(&point, &areas[i])) {
- if (!isDragAreaRunning) {
- isDragAreaRunning = YES;
- [_data->nswindow setMovableByWindowBackground:YES];
- }
- return YES; /* started a new drag! */
+ const SDL_HitTestResult rc = _data->window->hit_test(_data->window, &point, _data->window->hit_test_data);
+ if (rc == SDL_HITTEST_DRAGGABLE) {
+ if (!isDragAreaRunning) {
+ isDragAreaRunning = YES;
+ [_data->nswindow setMovableByWindowBackground:YES];
}
+ return YES; /* dragging! */
}
}
@@ -686,14 +680,14 @@
return YES; /* was dragging, drop event. */
}
- return NO; /* not a drag area, carry on. */
+ return NO; /* not a special area, carry on. */
}
- (void)mouseDown:(NSEvent *)theEvent
{
int button;
- if ([self processDragArea:theEvent]) {
+ if ([self processHitTest:theEvent]) {
return; /* dragging, drop event. */
}
@@ -735,7 +729,7 @@
{
int button;
- if ([self processDragArea:theEvent]) {
+ if ([self processHitTest:theEvent]) {
return; /* stopped dragging, drop event. */
}
@@ -778,7 +772,7 @@
NSPoint point;
int x, y;
- if ([self processDragArea:theEvent]) {
+ if ([self processHitTest:theEvent]) {
return; /* dragging, drop event. */
}
@@ -1599,7 +1593,7 @@
}
int
-Cocoa_SetWindowDragAreas(SDL_Window * window, const SDL_Rect *areas, int num_areas)
+Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled)
{
return 0; /* just succeed, the real work is done elsewhere. */
}
--- a/src/video/x11/SDL_x11events.c Tue May 27 15:47:25 2014 -0400
+++ b/src/video/x11/SDL_x11events.c Wed May 28 01:22:47 2014 -0400
@@ -303,21 +303,16 @@
}
static SDL_bool
-ProcessDragArea(_THIS, const SDL_WindowData *data, const XEvent *xev)
+ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev)
{
- const SDL_Window *window = data->window;
- const int num_areas = window->num_drag_areas;
+ SDL_Window *window = data->window;
- if (num_areas > 0) {
+ if (window->hit_test) {
const SDL_Point point = { xev->xbutton.x, xev->xbutton.y };
- const SDL_Rect *areas = window->drag_areas;
- int i;
-
- for (i = 0; i < num_areas; i++) {
- if (SDL_PointInRect(&point, &areas[i])) {
- InitiateWindowMove(_this, data, &point);
- return SDL_TRUE; /* dragging, drop this event. */
- }
+ const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
+ if (rc == SDL_HITTEST_DRAGGABLE) {
+ InitiateWindowMove(_this, data, &point);
+ return SDL_TRUE; /* dragging, drop this event. */
}
}
@@ -762,7 +757,7 @@
SDL_SendMouseWheel(data->window, 0, 0, ticks);
} else {
if(xevent.xbutton.button == Button1) {
- if (ProcessDragArea(_this, data, &xevent)) {
+ if (ProcessHitTest(_this, data, &xevent)) {
break; /* don't pass this event on to app. */
}
}
--- a/src/video/x11/SDL_x11video.c Tue May 27 15:47:25 2014 -0400
+++ b/src/video/x11/SDL_x11video.c Wed May 28 01:22:47 2014 -0400
@@ -457,7 +457,7 @@
device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = X11_DestroyWindowFramebuffer;
device->GetWindowWMInfo = X11_GetWindowWMInfo;
- device->SetWindowDragAreas = X11_SetWindowDragAreas;
+ device->SetWindowHitTest = X11_SetWindowHitTest;
device->shape_driver.CreateShaper = X11_CreateShaper;
device->shape_driver.SetWindowShape = X11_SetWindowShape;
--- a/src/video/x11/SDL_x11window.c Tue May 27 15:47:25 2014 -0400
+++ b/src/video/x11/SDL_x11window.c Wed May 28 01:22:47 2014 -0400
@@ -1445,9 +1445,9 @@
}
int
-X11_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas)
+X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
{
- return 0; // nothing to do, will be handled in event handler
+ return 0; /* just succeed, the real work is done elsewhere. */
}
#endif /* SDL_VIDEO_DRIVER_X11 */
--- a/src/video/x11/SDL_x11window.h Tue May 27 15:47:25 2014 -0400
+++ b/src/video/x11/SDL_x11window.h Wed May 28 01:22:47 2014 -0400
@@ -93,7 +93,7 @@
extern void X11_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
-extern int X11_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas);
+extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
#endif /* _SDL_x11window_h */
--- a/test/Makefile.in Tue May 27 15:47:25 2014 -0400
+++ b/test/Makefile.in Wed May 28 01:22:47 2014 -0400
@@ -12,7 +12,6 @@
loopwave$(EXE) \
testaudioinfo$(EXE) \
testautomation$(EXE) \
- testdragareas$(EXE) \
testdraw2$(EXE) \
testdrawchessboard$(EXE) \
testdropfile$(EXE) \
@@ -24,6 +23,7 @@
testgles$(EXE) \
testgles2$(EXE) \
testhaptic$(EXE) \
+ testhittesting$(EXE) \
testrumble$(EXE) \
testhotplug$(EXE) \
testthread$(EXE) \
@@ -109,7 +109,7 @@
testrelative$(EXE): $(srcdir)/testrelative.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
-testdragareas$(EXE): $(srcdir)/testdragareas.c
+testhittesting$(EXE): $(srcdir)/testhittesting.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
testdraw2$(EXE): $(srcdir)/testdraw2.c
--- a/test/testdragareas.c Tue May 27 15:47:25 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#include <stdio.h>
-#include "SDL.h"
-
-/* !!! FIXME: rewrite this to be wired in to test framework. */
-
-int main(int argc, char **argv)
-{
- int done = 0;
- SDL_Window *window;
- SDL_Renderer *renderer;
-
- const SDL_Rect drag_areas[] = {
- { 20, 20, 100, 100 },
- { 200, 70, 100, 100 },
- { 400, 90, 100, 100 }
- };
-
- const SDL_Rect *areas = drag_areas;
- int numareas = SDL_arraysize(drag_areas);
-
- /* !!! FIXME: check for errors. */
- SDL_Init(SDL_INIT_VIDEO);
- window = SDL_CreateWindow("Drag the red boxes", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_BORDERLESS);
- renderer = SDL_CreateRenderer(window, -1, 0);
-
- if (SDL_SetWindowDragAreas(window, areas, numareas) == -1) {
- fprintf(stderr, "Setting drag areas failed!\n");
- SDL_Quit();
- return 1;
- }
-
- while (!done)
- {
- SDL_SetRenderDrawColor(renderer, 0, 0, 127, 255);
- SDL_RenderClear(renderer);
- SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
- SDL_RenderFillRects(renderer, areas, SDL_arraysize(drag_areas));
- SDL_RenderPresent(renderer);
-
- SDL_Event e;
- int nothing_to_do = 1;
- while (SDL_PollEvent(&e)) {
- nothing_to_do = 0;
-
- switch (e.type)
- {
- case SDL_MOUSEBUTTONDOWN:
- printf("button down!\n");
- break;
-
- case SDL_MOUSEBUTTONUP:
- printf("button up!\n");
- break;
-
- case SDL_WINDOWEVENT:
- if (e.window.event == SDL_WINDOWEVENT_MOVED) {
- printf("Window event moved to (%d, %d)!\n", (int) e.window.data1, (int) e.window.data2);
- }
- break;
-
- case SDL_KEYDOWN:
- if (e.key.keysym.sym == SDLK_ESCAPE) {
- done = 1;
- } else if (e.key.keysym.sym == SDLK_x) {
- if (!areas) {
- areas = drag_areas;
- numareas = SDL_arraysize(drag_areas);
- } else {
- areas = NULL;
- numareas = 0;
- }
- if (SDL_SetWindowDragAreas(window, areas, numareas) == -1) {
- fprintf(stderr, "Setting drag areas failed!\n");
- SDL_Quit();
- return 1;
- }
- }
- break;
-
- case SDL_QUIT:
- done = 1;
- break;
- }
- }
-
- if (nothing_to_do) {
- SDL_Delay(50);
- }
- }
-
- SDL_Quit();
- return 0;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testhittesting.c Wed May 28 01:22:47 2014 -0400
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include "SDL.h"
+
+/* !!! FIXME: rewrite this to be wired in to test framework. */
+
+const SDL_Rect drag_areas[] = {
+ { 20, 20, 100, 100 },
+ { 200, 70, 100, 100 },
+ { 400, 90, 100, 100 }
+};
+
+static const SDL_Rect *areas = drag_areas;
+static int numareas = SDL_arraysize(drag_areas);
+
+static SDL_HitTestResult
+hitTest(SDL_Window *window, const SDL_Point *pt, void *data)
+{
+ int i;
+ for (i = 0; i < numareas; i++) {
+ if (SDL_PointInRect(pt, &areas[i])) {
+ return SDL_HITTEST_DRAGGABLE;
+ }
+ }
+
+ return SDL_HITTEST_NORMAL;
+}
+
+
+int main(int argc, char **argv)
+{
+ int done = 0;
+ SDL_Window *window;
+ SDL_Renderer *renderer;
+
+ /* !!! FIXME: check for errors. */
+ SDL_Init(SDL_INIT_VIDEO);
+ window = SDL_CreateWindow("Drag the red boxes", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_BORDERLESS);
+ renderer = SDL_CreateRenderer(window, -1, 0);
+
+ if (SDL_SetWindowHitTest(window, hitTest, NULL) == -1) {
+ fprintf(stderr, "Enabling hit-testing failed!\n");
+ SDL_Quit();
+ return 1;
+ }
+
+ while (!done)
+ {
+ SDL_SetRenderDrawColor(renderer, 0, 0, 127, 255);
+ SDL_RenderClear(renderer);
+ SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
+ SDL_RenderFillRects(renderer, areas, SDL_arraysize(drag_areas));
+ SDL_RenderPresent(renderer);
+
+ SDL_Event e;
+ int nothing_to_do = 1;
+ while (SDL_PollEvent(&e)) {
+ nothing_to_do = 0;
+
+ switch (e.type)
+ {
+ case SDL_MOUSEBUTTONDOWN:
+ printf("button down!\n");
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ printf("button up!\n");
+ break;
+
+ case SDL_WINDOWEVENT:
+ if (e.window.event == SDL_WINDOWEVENT_MOVED) {
+ printf("Window event moved to (%d, %d)!\n", (int) e.window.data1, (int) e.window.data2);
+ }
+ break;
+
+ case SDL_KEYDOWN:
+ if (e.key.keysym.sym == SDLK_ESCAPE) {
+ done = 1;
+ } else if (e.key.keysym.sym == SDLK_x) {
+ if (!areas) {
+ areas = drag_areas;
+ numareas = SDL_arraysize(drag_areas);
+ } else {
+ areas = NULL;
+ numareas = 0;
+ }
+ }
+ break;
+
+ case SDL_QUIT:
+ done = 1;
+ break;
+ }
+ }
+
+ if (nothing_to_do) {
+ SDL_Delay(50);
+ }
+ }
+
+ SDL_Quit();
+ return 0;
+}