浏览代码

Update to latest SDL source.

woollybah 10 年之前
父节点
当前提交
8f6157f996

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

@@ -1,6 +1,6 @@
 
 
 Simple DirectMedia Layer
 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
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages
 warranty.  In no event will the authors be held liable for any damages

文件差异内容过多而无法显示
+ 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 w      The width of the texture in pixels.
  *  \param h      The height 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
  *          active,  the format was unsupported, or the width or height were out
  *          of range.
  *          of range.
  *
  *
@@ -248,7 +248,7 @@ extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer,
  *  \param renderer The renderer.
  *  \param renderer The renderer.
  *  \param surface The surface containing pixel data used to fill the texture.
  *  \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.
  *  \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.
  * \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,
 extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval,
                                                  SDL_TimerCallback callback,
                                                  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;
         return 0;
     });
     });
 
 
+    if (!available) {
+        SDL_SetError("No audio context available");
+    }
+
     return 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 */
     /* Check if gamepad is supported by browser */
     if (numjs == EMSCRIPTEN_RESULT_NOT_SUPPORTED) {
     if (numjs == EMSCRIPTEN_RESULT_NOT_SUPPORTED) {
-        return -1;
+        return SDL_SetError("Gamepads not supported");
     }
     }
 
 
     /* handle already connected gamepads */
     /* handle already connected gamepads */
@@ -221,7 +221,7 @@ SDL_SYS_JoystickInit(void)
 
 
     if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
     if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
         SDL_SYS_JoystickQuit();
         SDL_SYS_JoystickQuit();
-        return -1;
+        return SDL_SetError("Could not set gamepad connect callback");
     }
     }
 
 
     retval = emscripten_set_gamepaddisconnected_callback(NULL,
     retval = emscripten_set_gamepaddisconnected_callback(NULL,
@@ -229,7 +229,7 @@ SDL_SYS_JoystickInit(void)
                                                          Emscripten_JoyStickDisconnected);
                                                          Emscripten_JoyStickDisconnected);
     if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
     if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
         SDL_SYS_JoystickQuit();
         SDL_SYS_JoystickQuit();
-        return -1;
+        return SDL_SetError("Could not set gamepad disconnect callback");
     }
     }
 
 
     return 0;
     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 (IsSupportedFormat(renderer, format)) {
         if (renderer->CreateTexture(renderer, texture) < 0) {
         if (renderer->CreateTexture(renderer, texture) < 0) {
             SDL_DestroyTexture(texture);
             SDL_DestroyTexture(texture);
-            return 0;
+            return NULL;
         }
         }
     } else {
     } else {
         texture->native = SDL_CreateTexture(renderer,
         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)
 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 {
 {
     pthread_attr_t type;
     pthread_attr_t type;
-    size_t ss;
     const char *hint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE);
     const char *hint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE);
 
 
     /* do this here before any threads exist, so there's no race condition. */
     /* 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_setstacksize(&type, stacksize);
         }
         }
     }
     }
-    
-    pthread_attr_getstacksize(&type, &ss);
 
 
     /* Create the thread and go! */
     /* Create the thread and go! */
     if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
     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;
     SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
     NSWindow *nswindow = windata->nswindow;
     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);
     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;
     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;
     return SDL_FALSE;
 }
 }
@@ -1056,11 +1022,15 @@ X11_DispatchEvent(_THIS)
 
 
     case ButtonRelease:{
     case ButtonRelease:{
             int button = xevent.xbutton.button;
             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;
         break;
 
 
@@ -1164,8 +1134,15 @@ X11_DispatchEvent(_THIS)
                     } else {
                     } else {
                         SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
                         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;
         break;

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

@@ -29,6 +29,7 @@
 #include "../../events/scancodes_xfree86.h"
 #include "../../events/scancodes_xfree86.h"
 
 
 #include <X11/keysym.h>
 #include <X11/keysym.h>
+#include <X11/XKBlib.h>
 
 
 #include "imKStoUCS.h"
 #include "imKStoUCS.h"
 
 
@@ -177,12 +178,12 @@ X11_KeyCodeToSDLScancode(Display *display, KeyCode keycode)
 }
 }
 
 
 static Uint32
 static Uint32
-X11_KeyCodeToUcs4(Display *display, KeyCode keycode)
+X11_KeyCodeToUcs4(Display *display, KeyCode keycode, unsigned char group)
 {
 {
     KeySym keysym;
     KeySym keysym;
 
 
 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
-    keysym = X11_XkbKeycodeToKeysym(display, keycode, 0, 0);
+    keysym = X11_XkbKeycodeToKeysym(display, keycode, group, 0);
 #else
 #else
     keysym = X11_XKeycodeToKeysym(display, keycode, 0);
     keysym = X11_XKeycodeToKeysym(display, keycode, 0);
 #endif
 #endif
@@ -300,8 +301,20 @@ X11_UpdateKeymap(_THIS)
     int i;
     int i;
     SDL_Scancode scancode;
     SDL_Scancode scancode;
     SDL_Keycode keymap[SDL_NUM_SCANCODES];
     SDL_Keycode keymap[SDL_NUM_SCANCODES];
+    unsigned char group = 0;
 
 
     SDL_GetDefaultKeymap(keymap);
     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++) {
     for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
         Uint32 key;
         Uint32 key;
 
 
@@ -312,7 +325,7 @@ X11_UpdateKeymap(_THIS)
         }
         }
 
 
         /* See if there is a UCS keycode for this scancode */
         /* 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) {
         if (key) {
             keymap[scancode] = key;
             keymap[scancode] = key;
         } else {
         } 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 */
     /* Query the extension version */
+    *major = 1; *minor = 3;  /* we want 1.3 */
     if (!X11_XRRQueryVersion(display, major, minor)) {
     if (!X11_XRRQueryVersion(display, major, minor)) {
 #ifdef X11MODES_DEBUG
 #ifdef X11MODES_DEBUG
         printf("XRandR not active on the display\n");
         printf("XRandR not active on the display\n");
 #endif
 #endif
+        *major = *minor = 0;
         return SDL_FALSE;
         return SDL_FALSE;
     }
     }
 #ifdef X11MODES_DEBUG
 #ifdef X11MODES_DEBUG
@@ -267,20 +269,20 @@ CalculateXRandRRefreshRate(const XRRModeInfo *info)
 }
 }
 
 
 static SDL_bool
 static SDL_bool
-SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *output_info,
+SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRCrtc crtc,
                   RRMode modeID, SDL_DisplayMode *mode)
                   RRMode modeID, SDL_DisplayMode *mode)
 {
 {
     int i;
     int i;
     for (i = 0; i < res->nmode; ++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;
             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)) {
             if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
@@ -300,6 +302,203 @@ SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *outp
     }
     }
     return SDL_FALSE;
     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 */
 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
 
 
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
@@ -399,14 +598,24 @@ X11_InitModes(_THIS)
 #endif
 #endif
 #if SDL_VIDEO_DRIVER_X11_XRANDR
 #if SDL_VIDEO_DRIVER_X11_XRANDR
     int xrandr_major, xrandr_minor;
     int xrandr_major, xrandr_minor;
-    int use_xrandr = 0;
-    XRRScreenResources *res = NULL;
 #endif
 #endif
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
     int vm_major, vm_minor;
     int vm_major, vm_minor;
     int use_vidmode = 0;
     int use_vidmode = 0;
 #endif
 #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
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
     /* Query Xinerama extention
     /* Query Xinerama extention
      * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
      * 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);
     screencount = ScreenCount(data->display);
 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
 #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 SDL_VIDEO_DRIVER_X11_XVIDMODE
     if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
     if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
         use_vidmode = vm_major * 100 + vm_minor;
         use_vidmode = vm_major * 100 + vm_minor;
@@ -569,106 +770,6 @@ X11_InitModes(_THIS)
             displaydata->y = 0;
             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 SDL_VIDEO_DRIVER_X11_XVIDMODE
         if (!displaydata->use_xrandr &&
         if (!displaydata->use_xrandr &&
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
 #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;
                 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
             }
             }
             mode.driverdata = modedata;
             mode.driverdata = modedata;
-            SDL_AddDisplayMode(sdl_display, &mode);
+            if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+                SDL_free(modedata);
+            }
         }
         }
         else if (!data->use_xrandr)
         else if (!data->use_xrandr)
         {
         {
@@ -762,7 +865,9 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
                 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
                 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
             }
             }
             mode.driverdata = modedata;
             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;
                     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);
                         SDL_free(modedata);
                     }
                     }
                 }
                 }
@@ -822,9 +926,7 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
             }
             }
             mode.driverdata = modedata;
             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);
                 SDL_free(modedata);
             }
             }
         }
         }
@@ -842,7 +944,9 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
             *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
             *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
         }
         }
         mode.driverdata = modedata;
         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
 #else
 SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return)
 SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return)
 #endif
 #endif
+SDL_X11_SYM(Status,XkbGetState,(Display* a,unsigned int b,XkbStatePtr c),(a,b,c),return)
 #endif
 #endif
 
 
 #if NeedWidePrototypes
 #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(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(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(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
 #endif
 
 
 /* MIT-SCREEN-SAVER support */
 /* 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(XdndDrop);
     GET_ATOM(XdndFinished);
     GET_ATOM(XdndFinished);
     GET_ATOM(XdndSelection);
     GET_ATOM(XdndSelection);
+    GET_ATOM(XKLAVIER_STATE);
 
 
     /* Detect the window manager */
     /* Detect the window manager */
     X11_CheckWindowManager(_this);
     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 XdndDrop;
     Atom XdndFinished;
     Atom XdndFinished;
     Atom XdndSelection;
     Atom XdndSelection;
+    Atom XKLAVIER_STATE;
 
 
     SDL_Scancode key_layout[256];
     SDL_Scancode key_layout[256];
     SDL_bool selection_waiting;
     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);
     return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win);
 }
 }
+
+/*
 static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
 static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
 {
 {
     return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win);
     return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win);
 }
 }
-
-/*
 static Bool
 static Bool
 X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS)
 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);
     SetWindowBordered(display, displaydata->screen, data->xwindow, bordered);
     X11_XFlush(display);
     X11_XFlush(display);
-    X11_XIfEvent(display, &event, &isConfigureNotify, (XPointer)&data->xwindow);
 
 
     if (visible) {
     if (visible) {
         XWindowAttributes attr;
         XWindowAttributes attr;

部分文件因为文件数量过多而无法显示