Fix Launcher not drawing on 32bpp windows on the X11 backend. (Thanks Jjp137)

This commit is contained in:
UnknownShadow200 2016-03-31 17:32:06 +11:00
parent 27ff9d3e44
commit fd321a61e3

View File

@ -1,6 +1,7 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ClassicalSharp;
using OpenTK.Platform;
using OpenTK.Platform.X11;
@ -54,7 +55,7 @@ namespace Launcher {
IntPtr scan0 = bmp.Scan0;
int size = bmp.Width * bmp.Height * 4;
IntPtr colorSpace = OSX.API.CGColorSpaceCreateDeviceRGB();
IntPtr colorSpace = OSX.API.CGColorSpaceCreateDeviceRGB();
IntPtr provider = OSX.API.CGDataProviderCreateWithData( IntPtr.Zero, scan0, size, IntPtr.Zero );
const uint flags = 4 | (2 << 12);
IntPtr image = OSX.API.CGImageCreate( bmp.Width, bmp.Height, 8, 8 * 4, bmp.Stride,
@ -62,7 +63,7 @@ namespace Launcher {
IntPtr context = IntPtr.Zero;
OSStatus err = OSX.API.QDBeginCGContext( windowPort, ref context );
OSX.API.CheckReturn( err );
OSX.HIRect rect = new OSX.HIRect();
rect.Origin.X = 0; rect.Origin.Y = 0;
rect.Size.X = bmp.Width; rect.Size.Y = bmp.Height;
@ -79,29 +80,95 @@ namespace Launcher {
}
}
public sealed class X11PlatformDrawer : PlatformDrawer {
public unsafe sealed class X11PlatformDrawer : PlatformDrawer {
IntPtr gc;
int depth;
public override void Init( IWindowInfo info ) {
gc = API.XCreateGC( API.DefaultDisplay, info.WinHandle, IntPtr.Zero, null );
depth = ((X11WindowInfo)info).VisualInfo.Depth;
}
public override void Resize( IWindowInfo info ) {
if( gc != IntPtr.Zero )
API.XFreeGC( API.DefaultDisplay, gc );
if( gc != IntPtr.Zero ) API.XFreeGC( API.DefaultDisplay, gc );
gc = API.XCreateGC( API.DefaultDisplay, info.WinHandle, IntPtr.Zero, null );
depth = ((X11WindowInfo)info).VisualInfo.Depth;
}
public override void Draw( IWindowInfo info, Bitmap framebuffer ) {
X11WindowInfo x11Info = (X11WindowInfo)info;
using( FastBitmap fastBmp = new FastBitmap( framebuffer, true ) ) {
IntPtr image = API.XCreateImage( API.DefaultDisplay, x11Info.VisualInfo.Visual,
24, ImageFormat.ZPixmap, 0, fastBmp.Scan0,
fastBmp.Width, fastBmp.Height, 32, 0 );
API.XPutImage( API.DefaultDisplay, x11Info.WindowHandle, gc, image,
0, 0, 0, 0, fastBmp.Width, fastBmp.Height );
API.XFree( image );
switch( depth ) {
case 32: DrawDirect( fastBmp, 32, x11Info ); break;
case 24: DrawDirect( fastBmp, 24, x11Info ); break;
//case 16: Draw16Bits( fastBmp, x11Info ); break;
//case 15: Draw15Bits( fastBmp, x11Info ); break;
default: throw new NotSupportedException("Unsupported bits per pixel: " + depth );
}
}
}
void DrawDirect( FastBitmap bmp, uint bits, X11WindowInfo x11Info ) {
IntPtr image = API.XCreateImage( API.DefaultDisplay, x11Info.VisualInfo.Visual,
bits, ImageFormat.ZPixmap, 0, bmp.Scan0,
bmp.Width, bmp.Height, 32, 0 );
API.XPutImage( API.DefaultDisplay, x11Info.WindowHandle, gc, image,
0, 0, 0, 0, bmp.Width, bmp.Height );
API.XFree( image );
}
// These bits per pixel are less common but are much slower
// TODO: find a platform that actually creates 16bpp windows
/*void Draw16Bits( FastBitmap bmp, X11WindowInfo x11Info ) {
int bytes = bmp.Width * bmp.Height * 2;
IntPtr ptr = Marshal.AllocHGlobal( bytes + 16 ); // ensure we allocate aligned num bytes
ushort* dst = (ushort*)ptr;
for( int y = 0; y < bmp.Height; y++ ) {
int* src = bmp.GetRowPtr( y );
for( int x = 0; x < bmp.Width; x++ ) {
int value = *src; src++;
int pixel =
(((value & 0xFF0000) >> (16 + 3)) << 11) // R
| (((value & 0xFF00) >> (8 + 2)) << 5) // G
| ((value & 0xFF) >> (0 + 3)); // B
*dst = (ushort)pixel; dst++;
}
}
IntPtr image = API.XCreateImage( API.DefaultDisplay, x11Info.VisualInfo.Visual,
16, ImageFormat.ZPixmap, 0, ptr,
bmp.Width, bmp.Height, 16, 0 );
API.XPutImage( API.DefaultDisplay, x11Info.WindowHandle, gc, image,
0, 0, 0, 0, bmp.Width, bmp.Height );
API.XFree( image );
Marshal.FreeHGlobal( ptr );
}
void Draw15Bits( FastBitmap bmp, X11WindowInfo x11Info ) {
int bytes = bmp.Width * bmp.Height * 2;
IntPtr ptr = Marshal.AllocHGlobal( bytes + 16 ); // ensure we allocate aligned num bytes
ushort* dst = (ushort*)ptr;
for( int y = 0; y < bmp.Height; y++ ) {
int* src = bmp.GetRowPtr( y );
for( int x = 0; x < bmp.Width; x++ ) {
int value = *src; src++;
int pixel =
(((value & 0xFF0000) >> (16 + 3)) << 10) // R
| (((value & 0xFF00) >> (8 + 3)) << 5) // G
| ((value & 0xFF) >> (0 + 3)); // B
*dst = (ushort)pixel; dst++;
}
}
IntPtr image = API.XCreateImage( API.DefaultDisplay, x11Info.VisualInfo.Visual,
15, ImageFormat.ZPixmap, 0, ptr,
bmp.Width, bmp.Height, 16, 0 );
API.XPutImage( API.DefaultDisplay, x11Info.WindowHandle, gc, image,
0, 0, 0, 0, bmp.Width, bmp.Height );
API.XFree( image );
Marshal.FreeHGlobal( ptr );
}*/
}
}