From 72c0e344ad7c4c637616487d690f01e7930728df Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 5 Jun 2018 20:02:49 +0100 Subject: [PATCH] Extract SDL2HardwareCursor to its own file. --- .../OpenRA.Platforms.Default.csproj | 1 + .../Sdl2GraphicsDevice.cs | 70 +--------------- .../Sdl2HardwareCursor.cs | 82 +++++++++++++++++++ 3 files changed, 86 insertions(+), 67 deletions(-) create mode 100644 OpenRA.Platforms.Default/Sdl2HardwareCursor.cs diff --git a/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj b/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj index d9dff01017..66fe36b528 100644 --- a/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj +++ b/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj @@ -58,6 +58,7 @@ + diff --git a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs index d0edb3c6fc..0c71379814 100644 --- a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs +++ b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs @@ -11,7 +11,6 @@ using System; using System.Drawing; -using System.IO; using System.Runtime.InteropServices; using OpenRA.Graphics; using SDL2; @@ -185,18 +184,18 @@ namespace OpenRA.Platforms.Default data = scaledData; } - return new SDL2HardwareCursor(size, data, hotspot); + return new Sdl2HardwareCursor(size, data, hotspot); } catch (Exception ex) { - throw new SDL2HardwareCursorException("Failed to create hardware cursor `{0}` - {1}".F(name, ex.Message), ex); + throw new Sdl2HardwareCursorException("Failed to create hardware cursor `{0}` - {1}".F(name, ex.Message), ex); } } public void SetHardwareCursor(IHardwareCursor cursor) { VerifyThreadAffinity(); - var c = cursor as SDL2HardwareCursor; + var c = cursor as Sdl2HardwareCursor; if (c == null) SDL.SDL_ShowCursor((int)SDL.SDL_bool.SDL_FALSE); else @@ -226,69 +225,6 @@ namespace OpenRA.Platforms.Default } } - class SDL2HardwareCursorException : Exception - { - public SDL2HardwareCursorException(string message) : base(message) { } - public SDL2HardwareCursorException(string message, Exception innerException) : base(message, innerException) { } - } - - sealed class SDL2HardwareCursor : IHardwareCursor - { - public IntPtr Cursor { get; private set; } - IntPtr surface; - - public SDL2HardwareCursor(Size size, byte[] data, int2 hotspot) - { - try - { - surface = SDL.SDL_CreateRGBSurface(0, size.Width, size.Height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); - if (surface == IntPtr.Zero) - throw new InvalidDataException("Failed to create surface: {0}".F(SDL.SDL_GetError())); - - var sur = (SDL.SDL_Surface)Marshal.PtrToStructure(surface, typeof(SDL.SDL_Surface)); - Marshal.Copy(data, 0, sur.pixels, data.Length); - - // This call very occasionally fails on Windows, but often works when retried. - for (var retries = 0; retries < 3 && Cursor == IntPtr.Zero; retries++) - Cursor = SDL.SDL_CreateColorCursor(surface, hotspot.X, hotspot.Y); - - if (Cursor == IntPtr.Zero) - throw new SDL2HardwareCursorException("Failed to create cursor: {0}".F(SDL.SDL_GetError())); - } - catch - { - Dispose(); - throw; - } - } - - ~SDL2HardwareCursor() - { - Game.RunAfterTick(() => Dispose(false)); - } - - public void Dispose() - { - Game.RunAfterTick(() => Dispose(true)); - GC.SuppressFinalize(this); - } - - void Dispose(bool disposing) - { - if (Cursor != IntPtr.Zero) - { - SDL.SDL_FreeCursor(Cursor); - Cursor = IntPtr.Zero; - } - - if (surface != IntPtr.Zero) - { - SDL.SDL_FreeSurface(surface); - surface = IntPtr.Zero; - } - } - } - public void Dispose() { if (disposed) diff --git a/OpenRA.Platforms.Default/Sdl2HardwareCursor.cs b/OpenRA.Platforms.Default/Sdl2HardwareCursor.cs new file mode 100644 index 0000000000..9f83715e1e --- /dev/null +++ b/OpenRA.Platforms.Default/Sdl2HardwareCursor.cs @@ -0,0 +1,82 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using SDL2; + +namespace OpenRA.Platforms.Default +{ + class Sdl2HardwareCursorException : Exception + { + public Sdl2HardwareCursorException(string message) : base(message) { } + public Sdl2HardwareCursorException(string message, Exception innerException) : base(message, innerException) { } + } + + sealed class Sdl2HardwareCursor : IHardwareCursor + { + public IntPtr Cursor { get; private set; } + IntPtr surface; + + public Sdl2HardwareCursor(Size size, byte[] data, int2 hotspot) + { + try + { + surface = SDL.SDL_CreateRGBSurface(0, size.Width, size.Height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + if (surface == IntPtr.Zero) + throw new InvalidDataException("Failed to create surface: {0}".F(SDL.SDL_GetError())); + + var sur = (SDL.SDL_Surface)Marshal.PtrToStructure(surface, typeof(SDL.SDL_Surface)); + Marshal.Copy(data, 0, sur.pixels, data.Length); + + // This call very occasionally fails on Windows, but often works when retried. + for (var retries = 0; retries < 3 && Cursor == IntPtr.Zero; retries++) + Cursor = SDL.SDL_CreateColorCursor(surface, hotspot.X, hotspot.Y); + + if (Cursor == IntPtr.Zero) + throw new Sdl2HardwareCursorException("Failed to create cursor: {0}".F(SDL.SDL_GetError())); + } + catch + { + Dispose(); + throw; + } + } + + ~Sdl2HardwareCursor() + { + Game.RunAfterTick(() => Dispose(false)); + } + + public void Dispose() + { + Game.RunAfterTick(() => Dispose(true)); + GC.SuppressFinalize(this); + } + + void Dispose(bool disposing) + { + if (Cursor != IntPtr.Zero) + { + SDL.SDL_FreeCursor(Cursor); + Cursor = IntPtr.Zero; + } + + if (surface != IntPtr.Zero) + { + SDL.SDL_FreeSurface(surface); + surface = IntPtr.Zero; + } + } + } +}