Browse Source

Update to latest SDL source.

woollybah 10 years ago
parent
commit
8f6157f996

+ 1 - 1
sdl.mod/SDL/COPYING.txt

@@ -1,6 +1,6 @@
 
 Simple DirectMedia Layer
-Copyright (C) 1997-2014 Sam Lantinga <[email protected]>
+Copyright (C) 1997-2015 Sam Lantinga <[email protected]>
   
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages

File diff suppressed because it is too large
+ 1032 - 755
sdl.mod/SDL/include/SDL_egl.h


+ 2 - 2
sdl.mod/SDL/include/SDL_render.h

@@ -229,7 +229,7 @@ extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer,
  *  \param w      The width of the texture in pixels.
  *  \param h      The height of the texture in pixels.
  *
- *  \return The created texture is returned, or 0 if no rendering context was
+ *  \return The created texture is returned, or NULL if no rendering context was
  *          active,  the format was unsupported, or the width or height were out
  *          of range.
  *
@@ -248,7 +248,7 @@ extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer,
  *  \param renderer The renderer.
  *  \param surface The surface containing pixel data used to fill the texture.
  *
- *  \return The created texture is returned, or 0 on error.
+ *  \return The created texture is returned, or NULL on error.
  *
  *  \note The surface is not modified or freed by this function.
  *

+ 1 - 1
sdl.mod/SDL/include/SDL_timer.h

@@ -88,7 +88,7 @@ typedef int SDL_TimerID;
 /**
  * \brief Add a new timer to the pool of timers already running.
  *
- * \return A timer ID, or NULL when an error occurs.
+ * \return A timer ID, or 0 when an error occurs.
  */
 extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval,
                                                  SDL_TimerCallback callback,

+ 4 - 0
sdl.mod/SDL/src/audio/emscripten/SDL_emscriptenaudio.c

@@ -263,6 +263,10 @@ Emscripten_Init(SDL_AudioDriverImpl * impl)
         return 0;
     });
 
+    if (!available) {
+        SDL_SetError("No audio context available");
+    }
+
     return available;
 }
 

+ 3 - 3
sdl.mod/SDL/src/joystick/emscripten/SDL_sysjoystick.c

@@ -200,7 +200,7 @@ SDL_SYS_JoystickInit(void)
 
     /* Check if gamepad is supported by browser */
     if (numjs == EMSCRIPTEN_RESULT_NOT_SUPPORTED) {
-        return -1;
+        return SDL_SetError("Gamepads not supported");
     }
 
     /* handle already connected gamepads */
@@ -221,7 +221,7 @@ SDL_SYS_JoystickInit(void)
 
     if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
         SDL_SYS_JoystickQuit();
-        return -1;
+        return SDL_SetError("Could not set gamepad connect callback");
     }
 
     retval = emscripten_set_gamepaddisconnected_callback(NULL,
@@ -229,7 +229,7 @@ SDL_SYS_JoystickInit(void)
                                                          Emscripten_JoyStickDisconnected);
     if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
         SDL_SYS_JoystickQuit();
-        return -1;
+        return SDL_SetError("Could not set gamepad disconnect callback");
     }
 
     return 0;

+ 1 - 1
sdl.mod/SDL/src/render/SDL_render.c

@@ -457,7 +457,7 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int
     if (IsSupportedFormat(renderer, format)) {
         if (renderer->CreateTexture(renderer, texture) < 0) {
             SDL_DestroyTexture(texture);
-            return 0;
+            return NULL;
         }
     } else {
         texture->native = SDL_CreateTexture(renderer,

+ 0 - 3
sdl.mod/SDL/src/thread/pthread/SDL_systhread.c

@@ -87,7 +87,6 @@ int
 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 {
     pthread_attr_t type;
-    size_t ss;
     const char *hint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE);
 
     /* do this here before any threads exist, so there's no race condition. */
@@ -116,8 +115,6 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
             pthread_attr_setstacksize(&type, stacksize);
         }
     }
-    
-    pthread_attr_getstacksize(&type, &ss);
 
     /* Create the thread and go! */
     if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {

+ 6 - 4
sdl.mod/SDL/src/video/cocoa/SDL_cocoawindow.m

@@ -1288,11 +1288,13 @@ Cocoa_SetWindowSize(_THIS, SDL_Window * window)
 {
     SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
     NSWindow *nswindow = windata->nswindow;
-    NSSize size;
 
-    size.width = window->w;
-    size.height = window->h;
-    [nswindow setContentSize:size];
+    NSRect frame = [nswindow frame];
+    frame.origin.y = (frame.origin.y + frame.size.height) - ((float) window->h);
+    frame.size.width = window->w;
+    frame.size.height = window->h;
+
+    [nswindow setFrame:frame display:YES];
 
     ScheduleContextUpdates(windata);
 }}

+ 388 - 389
sdl.mod/SDL/src/video/uikit/SDL_uikitopenglview.m

@@ -1,389 +1,388 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2015 Sam Lantinga <[email protected]>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-#include "../../SDL_internal.h"
-
-#if SDL_VIDEO_DRIVER_UIKIT
-
-#include <OpenGLES/EAGLDrawable.h>
-#include <OpenGLES/ES2/glext.h>
-#import "SDL_uikitopenglview.h"
-#include "SDL_uikitwindow.h"
-
-@implementation SDL_uikitopenglview {
-    /* The renderbuffer and framebuffer used to render to this layer. */
-    GLuint viewRenderbuffer, viewFramebuffer;
-
-    /* The depth buffer that is attached to viewFramebuffer, if it exists. */
-    GLuint depthRenderbuffer;
-
-    GLenum colorBufferFormat;
-
-    /* format of depthRenderbuffer */
-    GLenum depthBufferFormat;
-
-    /* The framebuffer and renderbuffer used for rendering with MSAA. */
-    GLuint msaaFramebuffer, msaaRenderbuffer;
-
-    /* The number of MSAA samples. */
-    int samples;
-
-    BOOL retainedBacking;
-}
-
-@synthesize context;
-@synthesize backingWidth;
-@synthesize backingHeight;
-
-+ (Class)layerClass
-{
-    return [CAEAGLLayer class];
-}
-
-- (instancetype)initWithFrame:(CGRect)frame
-                        scale:(CGFloat)scale
-                retainBacking:(BOOL)retained
-                        rBits:(int)rBits
-                        gBits:(int)gBits
-                        bBits:(int)bBits
-                        aBits:(int)aBits
-                    depthBits:(int)depthBits
-                  stencilBits:(int)stencilBits
-                         sRGB:(BOOL)sRGB
-                 multisamples:(int)multisamples
-                      context:(EAGLContext *)glcontext
-{
-    if ((self = [super initWithFrame:frame])) {
-        const BOOL useStencilBuffer = (stencilBits != 0);
-        const BOOL useDepthBuffer = (depthBits != 0);
-        NSString *colorFormat = nil;
-
-        context = glcontext;
-        samples = multisamples;
-        retainedBacking = retained;
-
-        if (!context || ![EAGLContext setCurrentContext:context]) {
-            SDL_SetError("Could not create OpenGL ES drawable (could not make context current)");
-            return nil;
-        }
-
-        if (samples > 0) {
-            GLint maxsamples = 0;
-            glGetIntegerv(GL_MAX_SAMPLES, &maxsamples);
-
-            /* Verify that the sample count is supported before creating any
-             * multisample Renderbuffers, to avoid generating GL errors. */
-            if (samples > maxsamples) {
-                SDL_SetError("Failed creating OpenGL ES framebuffer: Unsupported MSAA sample count");
-                return nil;
-            }
-        }
-
-        if (sRGB) {
-            /* sRGB EAGL drawable support was added in iOS 7. */
-            if (UIKit_IsSystemVersionAtLeast(7.0)) {
-                colorFormat = kEAGLColorFormatSRGBA8;
-                colorBufferFormat = GL_SRGB8_ALPHA8;
-            } else {
-                SDL_SetError("sRGB drawables are not supported.");
-                return nil;
-            }
-        } else if (rBits >= 8 || gBits >= 8 || bBits >= 8) {
-            /* if user specifically requests rbg888 or some color format higher than 16bpp */
-            colorFormat = kEAGLColorFormatRGBA8;
-            colorBufferFormat = GL_RGBA8;
-        } else {
-            /* default case (potentially faster) */
-            colorFormat = kEAGLColorFormatRGB565;
-            colorBufferFormat = GL_RGB565;
-        }
-
-        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
-
-        eaglLayer.opaque = YES;
-        eaglLayer.drawableProperties = @{
-            kEAGLDrawablePropertyRetainedBacking:@(retained),
-            kEAGLDrawablePropertyColorFormat:colorFormat
-        };
-
-        /* Set the appropriate scale (for retina display support) */
-        self.contentScaleFactor = scale;
-
-        /* Create the color Renderbuffer Object */
-        glGenRenderbuffers(1, &viewRenderbuffer);
-        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
-
-        if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]) {
-            SDL_SetError("Failed to create OpenGL ES drawable");
-            return nil;
-        }
-
-        /* Create the Framebuffer Object */
-        glGenFramebuffers(1, &viewFramebuffer);
-        glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
-
-        /* attach the color renderbuffer to the FBO */
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
-
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
-
-        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-            SDL_SetError("Failed creating OpenGL ES framebuffer");
-            return nil;
-        }
-
-        /* When MSAA is used we'll use a separate framebuffer for rendering to,
-         * since we'll need to do an explicit MSAA resolve before presenting. */
-        if (samples > 0) {
-            glGenFramebuffers(1, &msaaFramebuffer);
-            glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
-
-            glGenRenderbuffers(1, &msaaRenderbuffer);
-            glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
-
-            glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
-
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderbuffer);
-        }
-
-        if (useDepthBuffer || useStencilBuffer) {
-            if (useStencilBuffer) {
-                /* Apparently you need to pack stencil and depth into one buffer. */
-                depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
-            } else if (useDepthBuffer) {
-                /* iOS only uses 32-bit float (exposed as fixed point 24-bit)
-                 * depth buffers. */
-                depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
-            }
-
-            glGenRenderbuffers(1, &depthRenderbuffer);
-            glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
-
-            if (samples > 0) {
-                glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
-            } else {
-                glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
-            }
-
-            if (useDepthBuffer) {
-                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
-            }
-            if (useStencilBuffer) {
-                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
-            }
-        }
-
-        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-            SDL_SetError("Failed creating OpenGL ES framebuffer");
-            return nil;
-        }
-
-        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
-
-        [self setDebugLabels];
-    }
-
-    return self;
-}
-
-- (GLuint)drawableRenderbuffer
-{
-    return viewRenderbuffer;
-}
-
-- (GLuint)drawableFramebuffer
-{
-    /* When MSAA is used, the MSAA draw framebuffer is used for drawing. */
-    if (msaaFramebuffer) {
-        return msaaFramebuffer;
-    } else {
-        return viewFramebuffer;
-    }
-}
-
-- (GLuint)msaaResolveFramebuffer
-{
-    /* When MSAA is used, the MSAA draw framebuffer is used for drawing and the
-     * view framebuffer is used as a MSAA resolve framebuffer. */
-    if (msaaFramebuffer) {
-        return viewFramebuffer;
-    } else {
-        return 0;
-    }
-}
-
-- (void)updateFrame
-{
-    GLint prevRenderbuffer = 0;
-    glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRenderbuffer);
-
-    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
-    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
-
-    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
-    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
-
-    if (msaaRenderbuffer != 0) {
-        glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
-        glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, backingWidth, backingHeight);
-    }
-
-    if (depthRenderbuffer != 0) {
-        glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
-
-        if (samples > 0) {
-            glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
-        } else {
-            glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
-        }
-    }
-
-    glBindRenderbuffer(GL_RENDERBUFFER, prevRenderbuffer);
-}
-
-- (void)setDebugLabels
-{
-    if (viewFramebuffer != 0) {
-        glLabelObjectEXT(GL_FRAMEBUFFER, viewFramebuffer, 0, "context FBO");
-    }
-
-    if (viewRenderbuffer != 0) {
-        glLabelObjectEXT(GL_RENDERBUFFER, viewRenderbuffer, 0, "context color buffer");
-    }
-
-    if (depthRenderbuffer != 0) {
-        if (depthBufferFormat == GL_DEPTH24_STENCIL8_OES) {
-            glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth-stencil buffer");
-        } else {
-            glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth buffer");
-        }
-    }
-
-    if (msaaFramebuffer != 0) {
-        glLabelObjectEXT(GL_FRAMEBUFFER, msaaFramebuffer, 0, "context MSAA FBO");
-    }
-
-    if (msaaRenderbuffer != 0) {
-        glLabelObjectEXT(GL_RENDERBUFFER, msaaRenderbuffer, 0, "context MSAA renderbuffer");
-    }
-}
-
-- (void)swapBuffers
-{
-    if (msaaFramebuffer) {
-        const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
-
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, viewFramebuffer);
-
-        /* OpenGL ES 3+ provides explicit MSAA resolves via glBlitFramebuffer.
-         * In OpenGL ES 1 and 2, MSAA resolves must be done via an extension. */
-        if (context.API >= kEAGLRenderingAPIOpenGLES3) {
-            int w = backingWidth;
-            int h = backingHeight;
-            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-
-            if (!retainedBacking) {
-                /* Discard the contents of the MSAA drawable color buffer. */
-                glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, attachments);
-            }
-        } else {
-printf("swapbuffers...\n");fflush(stdout);
-            glResolveMultisampleFramebufferAPPLE();
-
-            if (!retainedBacking) {
-                glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER, 1, attachments);
-            }
-        }
-
-        /* We assume the "drawable framebuffer" (MSAA draw framebuffer) was
-         * previously bound... */
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFramebuffer);
-    }
-
-    /* viewRenderbuffer should always be bound here. Code that binds something
-     * else is responsible for rebinding viewRenderbuffer, to reduce duplicate
-     * state changes. */
-    [context presentRenderbuffer:GL_RENDERBUFFER];
-}
-
-- (void)layoutSubviews
-{
-    [super layoutSubviews];
-
-    int width  = (int) (self.bounds.size.width * self.contentScaleFactor);
-    int height = (int) (self.bounds.size.height * self.contentScaleFactor);
-
-    /* Update the color and depth buffer storage if the layer size has changed. */
-    if (width != backingWidth || height != backingHeight) {
-        EAGLContext *prevContext = [EAGLContext currentContext];
-        if (prevContext != context) {
-            [EAGLContext setCurrentContext:context];
-        }
-
-        [self updateFrame];
-
-        if (prevContext != context) {
-            [EAGLContext setCurrentContext:prevContext];
-        }
-    }
-}
-
-- (void)destroyFramebuffer
-{
-    if (viewFramebuffer != 0) {
-        glDeleteFramebuffers(1, &viewFramebuffer);
-        viewFramebuffer = 0;
-    }
-
-    if (viewRenderbuffer != 0) {
-        glDeleteRenderbuffers(1, &viewRenderbuffer);
-        viewRenderbuffer = 0;
-    }
-
-    if (depthRenderbuffer != 0) {
-        glDeleteRenderbuffers(1, &depthRenderbuffer);
-        depthRenderbuffer = 0;
-    }
-
-    if (msaaFramebuffer != 0) {
-        glDeleteFramebuffers(1, &msaaFramebuffer);
-        msaaFramebuffer = 0;
-    }
-
-    if (msaaRenderbuffer != 0) {
-        glDeleteRenderbuffers(1, &msaaRenderbuffer);
-        msaaRenderbuffer = 0;
-    }
-}
-
-- (void)dealloc
-{
-    if (context && context == [EAGLContext currentContext]) {
-        [self destroyFramebuffer];
-        [EAGLContext setCurrentContext:nil];
-    }
-}
-
-@end
-
-#endif /* SDL_VIDEO_DRIVER_UIKIT */
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2015 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include <OpenGLES/EAGLDrawable.h>
+#include <OpenGLES/ES2/glext.h>
+#import "SDL_uikitopenglview.h"
+#include "SDL_uikitwindow.h"
+
+@implementation SDL_uikitopenglview {
+    /* The renderbuffer and framebuffer used to render to this layer. */
+    GLuint viewRenderbuffer, viewFramebuffer;
+
+    /* The depth buffer that is attached to viewFramebuffer, if it exists. */
+    GLuint depthRenderbuffer;
+
+    GLenum colorBufferFormat;
+
+    /* format of depthRenderbuffer */
+    GLenum depthBufferFormat;
+
+    /* The framebuffer and renderbuffer used for rendering with MSAA. */
+    GLuint msaaFramebuffer, msaaRenderbuffer;
+
+    /* The number of MSAA samples. */
+    int samples;
+
+    BOOL retainedBacking;
+}
+
+@synthesize context;
+@synthesize backingWidth;
+@synthesize backingHeight;
+
++ (Class)layerClass
+{
+    return [CAEAGLLayer class];
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+                        scale:(CGFloat)scale
+                retainBacking:(BOOL)retained
+                        rBits:(int)rBits
+                        gBits:(int)gBits
+                        bBits:(int)bBits
+                        aBits:(int)aBits
+                    depthBits:(int)depthBits
+                  stencilBits:(int)stencilBits
+                         sRGB:(BOOL)sRGB
+                 multisamples:(int)multisamples
+                      context:(EAGLContext *)glcontext
+{
+    if ((self = [super initWithFrame:frame])) {
+        const BOOL useStencilBuffer = (stencilBits != 0);
+        const BOOL useDepthBuffer = (depthBits != 0);
+        NSString *colorFormat = nil;
+
+        context = glcontext;
+        samples = multisamples;
+        retainedBacking = retained;
+
+        if (!context || ![EAGLContext setCurrentContext:context]) {
+            SDL_SetError("Could not create OpenGL ES drawable (could not make context current)");
+            return nil;
+        }
+
+        if (samples > 0) {
+            GLint maxsamples = 0;
+            glGetIntegerv(GL_MAX_SAMPLES, &maxsamples);
+
+            /* Verify that the sample count is supported before creating any
+             * multisample Renderbuffers, to avoid generating GL errors. */
+            if (samples > maxsamples) {
+                SDL_SetError("Failed creating OpenGL ES framebuffer: Unsupported MSAA sample count");
+                return nil;
+            }
+        }
+
+        if (sRGB) {
+            /* sRGB EAGL drawable support was added in iOS 7. */
+            if (UIKit_IsSystemVersionAtLeast(7.0)) {
+                colorFormat = kEAGLColorFormatSRGBA8;
+                colorBufferFormat = GL_SRGB8_ALPHA8;
+            } else {
+                SDL_SetError("sRGB drawables are not supported.");
+                return nil;
+            }
+        } else if (rBits >= 8 || gBits >= 8 || bBits >= 8) {
+            /* if user specifically requests rbg888 or some color format higher than 16bpp */
+            colorFormat = kEAGLColorFormatRGBA8;
+            colorBufferFormat = GL_RGBA8;
+        } else {
+            /* default case (potentially faster) */
+            colorFormat = kEAGLColorFormatRGB565;
+            colorBufferFormat = GL_RGB565;
+        }
+
+        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+
+        eaglLayer.opaque = YES;
+        eaglLayer.drawableProperties = @{
+            kEAGLDrawablePropertyRetainedBacking:@(retained),
+            kEAGLDrawablePropertyColorFormat:colorFormat
+        };
+
+        /* Set the appropriate scale (for retina display support) */
+        self.contentScaleFactor = scale;
+
+        /* Create the color Renderbuffer Object */
+        glGenRenderbuffers(1, &viewRenderbuffer);
+        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+
+        if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]) {
+            SDL_SetError("Failed to create OpenGL ES drawable");
+            return nil;
+        }
+
+        /* Create the Framebuffer Object */
+        glGenFramebuffers(1, &viewFramebuffer);
+        glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
+
+        /* attach the color renderbuffer to the FBO */
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
+
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
+
+        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+            SDL_SetError("Failed creating OpenGL ES framebuffer");
+            return nil;
+        }
+
+        /* When MSAA is used we'll use a separate framebuffer for rendering to,
+         * since we'll need to do an explicit MSAA resolve before presenting. */
+        if (samples > 0) {
+            glGenFramebuffers(1, &msaaFramebuffer);
+            glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
+
+            glGenRenderbuffers(1, &msaaRenderbuffer);
+            glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
+
+            glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
+
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderbuffer);
+        }
+
+        if (useDepthBuffer || useStencilBuffer) {
+            if (useStencilBuffer) {
+                /* Apparently you need to pack stencil and depth into one buffer. */
+                depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
+            } else if (useDepthBuffer) {
+                /* iOS only uses 32-bit float (exposed as fixed point 24-bit)
+                 * depth buffers. */
+                depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
+            }
+
+            glGenRenderbuffers(1, &depthRenderbuffer);
+            glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
+
+            if (samples > 0) {
+                glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
+            } else {
+                glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
+            }
+
+            if (useDepthBuffer) {
+                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
+            }
+            if (useStencilBuffer) {
+                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
+            }
+        }
+
+        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+            SDL_SetError("Failed creating OpenGL ES framebuffer");
+            return nil;
+        }
+
+        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+
+        [self setDebugLabels];
+    }
+
+    return self;
+}
+
+- (GLuint)drawableRenderbuffer
+{
+    return viewRenderbuffer;
+}
+
+- (GLuint)drawableFramebuffer
+{
+    /* When MSAA is used, the MSAA draw framebuffer is used for drawing. */
+    if (msaaFramebuffer) {
+        return msaaFramebuffer;
+    } else {
+        return viewFramebuffer;
+    }
+}
+
+- (GLuint)msaaResolveFramebuffer
+{
+    /* When MSAA is used, the MSAA draw framebuffer is used for drawing and the
+     * view framebuffer is used as a MSAA resolve framebuffer. */
+    if (msaaFramebuffer) {
+        return viewFramebuffer;
+    } else {
+        return 0;
+    }
+}
+
+- (void)updateFrame
+{
+    GLint prevRenderbuffer = 0;
+    glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRenderbuffer);
+
+    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
+
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
+
+    if (msaaRenderbuffer != 0) {
+        glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
+        glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, backingWidth, backingHeight);
+    }
+
+    if (depthRenderbuffer != 0) {
+        glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
+
+        if (samples > 0) {
+            glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
+        } else {
+            glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
+        }
+    }
+
+    glBindRenderbuffer(GL_RENDERBUFFER, prevRenderbuffer);
+}
+
+- (void)setDebugLabels
+{
+    if (viewFramebuffer != 0) {
+        glLabelObjectEXT(GL_FRAMEBUFFER, viewFramebuffer, 0, "context FBO");
+    }
+
+    if (viewRenderbuffer != 0) {
+        glLabelObjectEXT(GL_RENDERBUFFER, viewRenderbuffer, 0, "context color buffer");
+    }
+
+    if (depthRenderbuffer != 0) {
+        if (depthBufferFormat == GL_DEPTH24_STENCIL8_OES) {
+            glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth-stencil buffer");
+        } else {
+            glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth buffer");
+        }
+    }
+
+    if (msaaFramebuffer != 0) {
+        glLabelObjectEXT(GL_FRAMEBUFFER, msaaFramebuffer, 0, "context MSAA FBO");
+    }
+
+    if (msaaRenderbuffer != 0) {
+        glLabelObjectEXT(GL_RENDERBUFFER, msaaRenderbuffer, 0, "context MSAA renderbuffer");
+    }
+}
+
+- (void)swapBuffers
+{
+    if (msaaFramebuffer) {
+        const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
+
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, viewFramebuffer);
+
+        /* OpenGL ES 3+ provides explicit MSAA resolves via glBlitFramebuffer.
+         * In OpenGL ES 1 and 2, MSAA resolves must be done via an extension. */
+        if (context.API >= kEAGLRenderingAPIOpenGLES3) {
+            int w = backingWidth;
+            int h = backingHeight;
+            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+            if (!retainedBacking) {
+                /* Discard the contents of the MSAA drawable color buffer. */
+                glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, attachments);
+            }
+        } else {
+            glResolveMultisampleFramebufferAPPLE();
+
+            if (!retainedBacking) {
+                glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER, 1, attachments);
+            }
+        }
+
+        /* We assume the "drawable framebuffer" (MSAA draw framebuffer) was
+         * previously bound... */
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFramebuffer);
+    }
+
+    /* viewRenderbuffer should always be bound here. Code that binds something
+     * else is responsible for rebinding viewRenderbuffer, to reduce duplicate
+     * state changes. */
+    [context presentRenderbuffer:GL_RENDERBUFFER];
+}
+
+- (void)layoutSubviews
+{
+    [super layoutSubviews];
+
+    int width  = (int) (self.bounds.size.width * self.contentScaleFactor);
+    int height = (int) (self.bounds.size.height * self.contentScaleFactor);
+
+    /* Update the color and depth buffer storage if the layer size has changed. */
+    if (width != backingWidth || height != backingHeight) {
+        EAGLContext *prevContext = [EAGLContext currentContext];
+        if (prevContext != context) {
+            [EAGLContext setCurrentContext:context];
+        }
+
+        [self updateFrame];
+
+        if (prevContext != context) {
+            [EAGLContext setCurrentContext:prevContext];
+        }
+    }
+}
+
+- (void)destroyFramebuffer
+{
+    if (viewFramebuffer != 0) {
+        glDeleteFramebuffers(1, &viewFramebuffer);
+        viewFramebuffer = 0;
+    }
+
+    if (viewRenderbuffer != 0) {
+        glDeleteRenderbuffers(1, &viewRenderbuffer);
+        viewRenderbuffer = 0;
+    }
+
+    if (depthRenderbuffer != 0) {
+        glDeleteRenderbuffers(1, &depthRenderbuffer);
+        depthRenderbuffer = 0;
+    }
+
+    if (msaaFramebuffer != 0) {
+        glDeleteFramebuffers(1, &msaaFramebuffer);
+        msaaFramebuffer = 0;
+    }
+
+    if (msaaRenderbuffer != 0) {
+        glDeleteRenderbuffers(1, &msaaRenderbuffer);
+        msaaRenderbuffer = 0;
+    }
+}
+
+- (void)dealloc
+{
+    if (context && context == [EAGLContext currentContext]) {
+        [self destroyFramebuffer];
+        [EAGLContext setCurrentContext:nil];
+    }
+}
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 30 - 53
sdl.mod/SDL/src/video/x11/SDL_x11events.c

@@ -167,54 +167,20 @@ static SDL_bool X11_KeyRepeat(Display *display, XEvent *event)
     return d.found;
 }
 
-static Bool X11_IsWheelCheckIfEvent(Display *display, XEvent *chkev,
-    XPointer arg)
-{
-    XEvent *event = (XEvent *) arg;
-    /* we only handle buttons 4 and 5 - false positive avoidance */
-    if (chkev->type == ButtonRelease &&
-        (event->xbutton.button == Button4 || event->xbutton.button == Button5 ||
-         event->xbutton.button == 6 || event->xbutton.button == 7) &&
-        chkev->xbutton.button == event->xbutton.button &&
-        chkev->xbutton.time == event->xbutton.time)
-        return True;
-    return False;
-}
-
-static SDL_bool X11_IsWheelEvent(Display * display,XEvent * event,int * xticks,int * yticks)
+static SDL_bool
+X11_IsWheelEvent(Display * display,XEvent * event,int * xticks,int * yticks)
 {
-    XEvent relevent;
-    if (X11_XPending(display)) {
-        /* according to the xlib docs, no specific mouse wheel events exist.
-           however, mouse wheel events trigger a button press and a button release
-           immediately. thus, checking if the same button was released at the same
-           time as it was pressed, should be an adequate hack to derive a mouse
-           wheel event.
-           However, there is broken and unusual hardware out there...
-           - False positive: a button for which a release event is
-             generated (or synthesised) immediately.
-           - False negative: a wheel which, when rolled, doesn't have
-             a release event generated immediately. */
-        if (X11_XCheckIfEvent(display, &relevent, X11_IsWheelCheckIfEvent,
-            (XPointer) event)) {
-
-            /* by default, X11 only knows 5 buttons. on most 3 button + wheel mouse,
-               Button4 maps to (vertical) wheel up, Button5 maps to wheel down.
-               Horizontal scrolling usually maps to 6 and 7 which have no name */
-            if (event->xbutton.button == Button4) {
-                *yticks = 1;
-            }
-            else if (event->xbutton.button == Button5) {
-                *yticks = -1;
-            }
-            else if (event->xbutton.button == 6) {
-                *xticks = 1;
-            }
-            else if (event->xbutton.button == 7) {
-                *xticks = -1;
-            }
-            return SDL_TRUE;
-        }
+    /* according to the xlib docs, no specific mouse wheel events exist.
+       However, the defacto standard is that the vertical wheel is X buttons
+       4 (up) and 5 (down) and a horizontal wheel is 6 (left) and 7 (right). */
+
+    /* Xlib defines "Button1" through 5, so we just use literals here. */
+    switch (event->xbutton.button) {
+        case 4: *yticks = 1; return SDL_TRUE;
+        case 5: *yticks = -1; return SDL_TRUE;
+        case 6: *xticks = 1; return SDL_TRUE;
+        case 7: *xticks = -1; return SDL_TRUE;
+        default: break;
     }
     return SDL_FALSE;
 }
@@ -1056,11 +1022,15 @@ X11_DispatchEvent(_THIS)
 
     case ButtonRelease:{
             int button = xevent.xbutton.button;
-            if (button > 7) {
-                /* see explanation at case ButtonPress */
-                button -= (8-SDL_BUTTON_X1);
+            /* The X server sends a Release event for each Press for wheels. Ignore them. */
+            int xticks = 0, yticks = 0;
+            if (!X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
+                if (button > 7) {
+                    /* see explanation at case ButtonPress */
+                    button -= (8-SDL_BUTTON_X1);
+                }
+                SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button);
             }
-            SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button);
         }
         break;
 
@@ -1164,8 +1134,15 @@ X11_DispatchEvent(_THIS)
                     } else {
                         SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
                     }
-                 }
-
+                }
+            } else if (xevent.xproperty.atom == videodata->XKLAVIER_STATE) {
+                /* Hack for Ubuntu 12.04 (etc) that doesn't send MappingNotify
+                   events when the keyboard layout changes (for example,
+                   changing from English to French on the menubar's keyboard
+                   icon). Since it changes the XKLAVIER_STATE property, we
+                   notice and reinit our keymap here. This might not be the
+                   right approach, but it seems to work. */
+                X11_UpdateKeymap(_this);
             }
         }
         break;

+ 16 - 3
sdl.mod/SDL/src/video/x11/SDL_x11keyboard.c

@@ -29,6 +29,7 @@
 #include "../../events/scancodes_xfree86.h"
 
 #include <X11/keysym.h>
+#include <X11/XKBlib.h>
 
 #include "imKStoUCS.h"
 
@@ -177,12 +178,12 @@ X11_KeyCodeToSDLScancode(Display *display, KeyCode keycode)
 }
 
 static Uint32
-X11_KeyCodeToUcs4(Display *display, KeyCode keycode)
+X11_KeyCodeToUcs4(Display *display, KeyCode keycode, unsigned char group)
 {
     KeySym keysym;
 
 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
-    keysym = X11_XkbKeycodeToKeysym(display, keycode, 0, 0);
+    keysym = X11_XkbKeycodeToKeysym(display, keycode, group, 0);
 #else
     keysym = X11_XKeycodeToKeysym(display, keycode, 0);
 #endif
@@ -300,8 +301,20 @@ X11_UpdateKeymap(_THIS)
     int i;
     SDL_Scancode scancode;
     SDL_Keycode keymap[SDL_NUM_SCANCODES];
+    unsigned char group = 0;
 
     SDL_GetDefaultKeymap(keymap);
+    
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+    {
+        XkbStateRec state;
+        if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) {
+            group = state.group;
+        }
+    }
+#endif
+
+
     for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
         Uint32 key;
 
@@ -312,7 +325,7 @@ X11_UpdateKeymap(_THIS)
         }
 
         /* See if there is a UCS keycode for this scancode */
-        key = X11_KeyCodeToUcs4(data->display, (KeyCode)i);
+        key = X11_KeyCodeToUcs4(data->display, (KeyCode)i, group);
         if (key) {
             keymap[scancode] = key;
         } else {

+ 231 - 127
sdl.mod/SDL/src/video/x11/SDL_x11modes.c

@@ -244,10 +244,12 @@ CheckXRandR(Display * display, int *major, int *minor)
     }
 
     /* Query the extension version */
+    *major = 1; *minor = 3;  /* we want 1.3 */
     if (!X11_XRRQueryVersion(display, major, minor)) {
 #ifdef X11MODES_DEBUG
         printf("XRandR not active on the display\n");
 #endif
+        *major = *minor = 0;
         return SDL_FALSE;
     }
 #ifdef X11MODES_DEBUG
@@ -267,20 +269,20 @@ CalculateXRandRRefreshRate(const XRRModeInfo *info)
 }
 
 static SDL_bool
-SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *output_info,
+SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRCrtc crtc,
                   RRMode modeID, SDL_DisplayMode *mode)
 {
     int i;
     for (i = 0; i < res->nmode; ++i) {
-        if (res->modes[i].id == modeID) {
-            XRRCrtcInfo *crtc;
+        const XRRModeInfo *info = &res->modes[i];
+        if (info->id == modeID) {
+            XRRCrtcInfo *crtcinfo;
             Rotation rotation = 0;
-            const XRRModeInfo *info = &res->modes[i];
 
-            crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
-            if (crtc) {
-                rotation = crtc->rotation;
-                X11_XRRFreeCrtcInfo(crtc);
+            crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc);
+            if (crtcinfo) {
+                rotation = crtcinfo->rotation;
+                X11_XRRFreeCrtcInfo(crtcinfo);
             }
 
             if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
@@ -300,6 +302,203 @@ SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *outp
     }
     return SDL_FALSE;
 }
+
+static void
+SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, RROutput output, const unsigned long widthmm, const unsigned long heightmm)
+{
+    /* See if we can get the EDID data for the real monitor name */
+    int inches;
+    int nprop;
+    Atom *props = X11_XRRListOutputProperties(dpy, output, &nprop);
+    int i;
+
+    for (i = 0; i < nprop; ++i) {
+        unsigned char *prop;
+        int actual_format;
+        unsigned long nitems, bytes_after;
+        Atom actual_type;
+
+        if (props[i] == EDID) {
+            if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False,
+                                         False, AnyPropertyType, &actual_type,
+                                         &actual_format, &nitems, &bytes_after,
+                                         &prop) == Success) {
+                MonitorInfo *info = decode_edid(prop);
+                if (info) {
+#ifdef X11MODES_DEBUG
+                    printf("Found EDID data for %s\n", name);
+                    dump_monitor_info(info);
+#endif
+                    SDL_strlcpy(name, info->dsc_product_name, namelen);
+                    free(info);
+                }
+                X11_XFree(prop);
+            }
+            break;
+        }
+    }
+
+    if (props) {
+        X11_XFree(props);
+    }
+
+    inches = (int)((SDL_sqrt(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f);
+    if (*name && inches) {
+        const size_t len = SDL_strlen(name);
+        SDL_snprintf(&name[len], namelen-len, " %d\"", inches);
+    }
+
+#ifdef X11MODES_DEBUG
+    printf("Display name: %s\n", name);
+#endif
+}
+
+
+int
+X11_InitModes_XRandR(_THIS)
+{
+    /* In theory, you _could_ have multiple screens (like DISPLAY=:0.0
+       and DISPLAY=:0.1) but no XRandR system we care about is like this,
+       as all the physical displays would be separate XRandR "outputs" on
+       the one X11 virtual "screen". So we don't use ScreenCount() here. */
+
+    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    Display *dpy = data->display;
+    Atom EDID = X11_XInternAtom(dpy, "EDID", False);
+    const int screen = DefaultScreen(dpy);
+    RROutput primary;
+    XRRScreenResources *res = NULL;
+    Uint32 pixelformat;
+    XVisualInfo vinfo;
+    XPixmapFormatValues *pixmapformats;
+    int looking_for_primary;
+    int scanline_pad;
+    int output;
+    int i, n;
+
+    if (get_visualinfo(dpy, screen, &vinfo) < 0) {
+        return -1;
+    }
+
+    pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo);
+    if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) {
+        return SDL_SetError("Palettized video modes are no longer supported");
+    }
+
+    scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8;
+    pixmapformats = X11_XListPixmapFormats(dpy, &n);
+    if (pixmapformats) {
+        for (i = 0; i < n; ++i) {
+            if (pixmapformats[i].depth == vinfo.depth) {
+                scanline_pad = pixmapformats[i].scanline_pad;
+                break;
+            }
+        }
+        X11_XFree(pixmapformats);
+    }
+
+    res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
+    if (!res) {
+        return -1;
+    }
+
+    primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, screen));
+
+    for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) {
+        for (output = 0; output < res->noutput; output++) {
+            XRROutputInfo *output_info;
+            int display_x, display_y;
+            unsigned long display_mm_width, display_mm_height;
+            SDL_DisplayData *displaydata;
+            char display_name[128];
+            SDL_DisplayMode mode;
+            SDL_DisplayModeData *modedata;
+            SDL_VideoDisplay display;
+            RRMode modeID;
+            RRCrtc output_crtc;
+            XRRCrtcInfo *crtc;
+
+            /* The primary output _should_ always be sorted first, but just in case... */
+            if ((looking_for_primary && (res->outputs[output] != primary)) ||
+                (!looking_for_primary && (res->outputs[output] == primary))) {
+                continue;
+            }
+
+            output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
+            if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
+                X11_XRRFreeOutputInfo(output_info);
+                continue;
+            }
+
+            SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
+            display_mm_width = output_info->mm_width;
+            display_mm_height = output_info->mm_height;
+            output_crtc = output_info->crtc;
+            X11_XRRFreeOutputInfo(output_info);
+
+            crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
+            if (!crtc) {
+                continue;
+            }
+
+            SDL_zero(mode);
+            modeID = crtc->mode;
+            mode.w = crtc->width;
+            mode.h = crtc->height;
+            mode.format = pixelformat;
+
+            display_x = crtc->x;
+            display_y = crtc->y;
+
+            X11_XRRFreeCrtcInfo(crtc);
+
+            displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
+            if (!displaydata) {
+                return SDL_OutOfMemory();
+            }
+
+            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+            if (!modedata) {
+                SDL_free(displaydata);
+                return SDL_OutOfMemory();
+            }
+            modedata->xrandr_mode = modeID;
+            mode.driverdata = modedata;
+
+            displaydata->screen = screen;
+            displaydata->visual = vinfo.visual;
+            displaydata->depth = vinfo.depth;
+            displaydata->hdpi = ((float) mode.w) * 25.4f / display_mm_width;
+            displaydata->vdpi = ((float) mode.h) * 25.4f / display_mm_height;
+            displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f);
+            displaydata->scanline_pad = scanline_pad;
+            displaydata->x = display_x;
+            displaydata->y = display_y;
+            displaydata->use_xrandr = 1;
+            displaydata->xrandr_output = res->outputs[output];
+
+            SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
+            SetXRandRDisplayName(dpy, EDID, display_name, sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
+
+            SDL_zero(display);
+            if (*display_name) {
+                display.name = display_name;
+            }
+            display.desktop_mode = mode;
+            display.current_mode = mode;
+            display.driverdata = displaydata;
+            SDL_AddVideoDisplay(&display);
+        }
+    }
+
+    X11_XRRFreeScreenResources(res);
+
+    if (_this->num_displays == 0) {
+        return SDL_SetError("No available displays");
+    }
+
+    return 0;
+}
 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
 
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
@@ -399,14 +598,24 @@ X11_InitModes(_THIS)
 #endif
 #if SDL_VIDEO_DRIVER_X11_XRANDR
     int xrandr_major, xrandr_minor;
-    int use_xrandr = 0;
-    XRRScreenResources *res = NULL;
 #endif
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
     int vm_major, vm_minor;
     int use_vidmode = 0;
 #endif
 
+/* XRandR is the One True Modern Way to do this on X11. If it's enabled and
+   available, don't even look at other ways of doing things. */
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+    /* require at least XRandR v1.3 */
+    if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
+        (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
+        return X11_InitModes_XRandR(_this);
+    }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+/* !!! FIXME: eventually remove support for Xinerama and XVidMode (everything below here). */
+
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
     /* Query Xinerama extention
      * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
@@ -433,14 +642,6 @@ X11_InitModes(_THIS)
     screencount = ScreenCount(data->display);
 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
 
-#if SDL_VIDEO_DRIVER_X11_XRANDR
-    /* require at least XRandR v1.2 */
-    if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
-        (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 2))) {
-        use_xrandr = xrandr_major * 100 + xrandr_minor;
-    }
-#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
-
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
     if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
         use_vidmode = vm_major * 100 + vm_minor;
@@ -569,106 +770,6 @@ X11_InitModes(_THIS)
             displaydata->y = 0;
         }
 
-#if SDL_VIDEO_DRIVER_X11_XRANDR
-        if (use_xrandr) {
-            res = X11_XRRGetScreenResources(data->display, RootWindow(data->display, displaydata->screen));
-        }
-        if (res) {
-            XRROutputInfo *output_info;
-            XRRCrtcInfo *crtc;
-            int output;
-            Atom EDID = X11_XInternAtom(data->display, "EDID", False);
-            Atom *props;
-            int nprop;
-            unsigned long width_mm;
-            unsigned long height_mm;
-            int inches = 0;
-
-            for (output = 0; output < res->noutput; output++) {
-                output_info = X11_XRRGetOutputInfo(data->display, res, res->outputs[output]);
-                if (!output_info || !output_info->crtc ||
-                    output_info->connection == RR_Disconnected) {
-                    X11_XRRFreeOutputInfo(output_info);
-                    continue;
-                }
-
-                /* Is this the output that corresponds to the current screen?
-                   We're checking the crtc position, but that may not be a valid test
-                   in all cases.  Anybody want to give this some love?
-                 */
-                crtc = X11_XRRGetCrtcInfo(data->display, res, output_info->crtc);
-                if (!crtc || crtc->x != displaydata->x || crtc->y != displaydata->y ||
-                    crtc->width != mode.w || crtc->height != mode.h) {
-                    X11_XRRFreeOutputInfo(output_info);
-                    X11_XRRFreeCrtcInfo(crtc);
-                    continue;
-                }
-
-                displaydata->use_xrandr = use_xrandr;
-                displaydata->xrandr_output = res->outputs[output];
-                SetXRandRModeInfo(data->display, res, output_info, crtc->mode, &mode);
-
-                /* Get the name of this display */
-                width_mm = output_info->mm_width;
-                height_mm = output_info->mm_height;
-                inches = (int)((sqrt(width_mm * width_mm +
-                                     height_mm * height_mm) / 25.4f) + 0.5f);
-                SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
-
-                /* See if we can get the EDID data for the real monitor name */
-                props = X11_XRRListOutputProperties(data->display, res->outputs[output], &nprop);
-                for (i = 0; i < nprop; ++i) {
-                    unsigned char *prop;
-                    int actual_format;
-                    unsigned long nitems, bytes_after;
-                    Atom actual_type;
-
-                    if (props[i] == EDID) {
-                        if (X11_XRRGetOutputProperty(data->display,
-                                                 res->outputs[output], props[i],
-                                                 0, 100, False, False,
-                                                 AnyPropertyType,
-                                                 &actual_type, &actual_format,
-                                                 &nitems, &bytes_after, &prop) == Success ) {
-                            MonitorInfo *info = decode_edid(prop);
-                            if (info) {
-    #ifdef X11MODES_DEBUG
-                                printf("Found EDID data for %s\n", output_info->name);
-                                dump_monitor_info(info);
-    #endif
-                                SDL_strlcpy(display_name, info->dsc_product_name, sizeof(display_name));
-                                free(info);
-                            }
-                            X11_XFree(prop);
-                        }
-                        break;
-                    }
-                }
-                if (props) {
-                    X11_XFree(props);
-                }
-
-                if (*display_name && inches) {
-                    size_t len = SDL_strlen(display_name);
-                    SDL_snprintf(&display_name[len], sizeof(display_name)-len, " %d\"", inches);
-                }
-#ifdef X11MODES_DEBUG
-                printf("Display name: %s\n", display_name);
-#endif
-
-                X11_XRRFreeOutputInfo(output_info);
-                X11_XRRFreeCrtcInfo(crtc);
-                break;
-            }
-#ifdef X11MODES_DEBUG
-            if (output == res->noutput) {
-                printf("Couldn't find XRandR CRTC at %d,%d\n", displaydata->x, displaydata->y);
-            }
-#endif
-            X11_XRRFreeScreenResources(res);
-        }
-#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
-
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
         if (!displaydata->use_xrandr &&
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
@@ -748,7 +849,9 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
                 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
             }
             mode.driverdata = modedata;
-            SDL_AddDisplayMode(sdl_display, &mode);
+            if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+                SDL_free(modedata);
+            }
         }
         else if (!data->use_xrandr)
         {
@@ -762,7 +865,9 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
                 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
             }
             mode.driverdata = modedata;
-            SDL_AddDisplayMode(sdl_display, &mode);
+            if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+                SDL_free(modedata);
+            }
         }
 
     }
@@ -787,9 +892,8 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
                     }
                     mode.driverdata = modedata;
 
-                    if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) {
-                        SDL_AddDisplayMode(sdl_display, &mode);
-                    } else {
+                    if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
+                        !SDL_AddDisplayMode(sdl_display, &mode)) {
                         SDL_free(modedata);
                     }
                 }
@@ -822,9 +926,7 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
             }
             mode.driverdata = modedata;
 
-            if (SetXVidModeModeInfo(modes[i], &mode)) {
-                SDL_AddDisplayMode(sdl_display, &mode);
-            } else {
+            if (!SetXVidModeModeInfo(modes[i], &mode) || !SDL_AddDisplayMode(sdl_display, &mode)) {
                 SDL_free(modedata);
             }
         }
@@ -842,7 +944,9 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
             *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
         }
         mode.driverdata = modedata;
-        SDL_AddDisplayMode(sdl_display, &mode);
+        if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+            SDL_free(modedata);
+        }
     }
 }
 

+ 2 - 0
sdl.mod/SDL/src/video/x11/SDL_x11sym.h

@@ -165,6 +165,7 @@ SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,unsigned int b,int c,int d),(a
 #else
 SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return)
 #endif
+SDL_X11_SYM(Status,XkbGetState,(Display* a,unsigned int b,XkbStatePtr c),(a,b,c),return)
 #endif
 
 #if NeedWidePrototypes
@@ -283,6 +284,7 @@ SDL_X11_SYM(Status,XRRSetCrtcConfig,(Display *dpy, XRRScreenResources *resources
 SDL_X11_SYM(Atom*,XRRListOutputProperties,(Display *dpy, RROutput output, int *nprop),(dpy,output,nprop),return)
 SDL_X11_SYM(XRRPropertyInfo*,XRRQueryOutputProperty,(Display *dpy,RROutput output, Atom property),(dpy,output,property),return)
 SDL_X11_SYM(int,XRRGetOutputProperty,(Display *dpy,RROutput output, Atom property, long offset, long length, Bool _delete, Bool pending, Atom req_type, Atom *actual_type, int *actual_format, unsigned long *nitems, unsigned long *bytes_after, unsigned char **prop),(dpy,output,property,offset,length, _delete, pending, req_type, actual_type, actual_format, nitems, bytes_after, prop),return)
+SDL_X11_SYM(RROutput,XRRGetOutputPrimary,(Display *dpy,Window window),(dpy,window),return)
 #endif
 
 /* MIT-SCREEN-SAVER support */

+ 1 - 0
sdl.mod/SDL/src/video/x11/SDL_x11video.c

@@ -408,6 +408,7 @@ X11_VideoInit(_THIS)
     GET_ATOM(XdndDrop);
     GET_ATOM(XdndFinished);
     GET_ATOM(XdndSelection);
+    GET_ATOM(XKLAVIER_STATE);
 
     /* Detect the window manager */
     X11_CheckWindowManager(_this);

+ 1 - 0
sdl.mod/SDL/src/video/x11/SDL_x11video.h

@@ -111,6 +111,7 @@ typedef struct SDL_VideoData
     Atom XdndDrop;
     Atom XdndFinished;
     Atom XdndSelection;
+    Atom XKLAVIER_STATE;
 
     SDL_Scancode key_layout[256];
     SDL_bool selection_waiting;

+ 2 - 3
sdl.mod/SDL/src/video/x11/SDL_x11window.c

@@ -54,12 +54,12 @@ static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win)
 {
     return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win);
 }
+
+/*
 static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
 {
     return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win);
 }
-
-/*
 static Bool
 X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS)
 {
@@ -864,7 +864,6 @@ X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
 
     SetWindowBordered(display, displaydata->screen, data->xwindow, bordered);
     X11_XFlush(display);
-    X11_XIfEvent(display, &event, &isConfigureNotify, (XPointer)&data->xwindow);
 
     if (visible) {
         XWindowAttributes attr;

Some files were not shown because too many files changed in this diff