Hopefully fix OSX issues this time.

This commit is contained in:
UnknownShadow200 2015-11-04 12:11:23 +11:00
parent 38b8d95946
commit 44a52d50ab
8 changed files with 644 additions and 290 deletions

View File

@ -4,6 +4,7 @@ using ClassicalSharp;
using OpenTK.Platform; using OpenTK.Platform;
using OpenTK.Platform.X11; using OpenTK.Platform.X11;
using OSX = OpenTK.Platform.MacOS.Carbon; using OSX = OpenTK.Platform.MacOS.Carbon;
using OSStatus = OpenTK.Platform.MacOS.OSStatus;
namespace Launcher2 { namespace Launcher2 {
@ -49,7 +50,32 @@ namespace Launcher2 {
} }
public override void Draw( IWindowInfo info, Bitmap framebuffer ) { public override void Draw( IWindowInfo info, Bitmap framebuffer ) {
//g.DrawImage( framebuffer, 0, 0, framebuffer.Width, framebuffer.Height );
using( FastBitmap bmp = new FastBitmap( framebuffer, true ) ) {
IntPtr scan0 = bmp.Scan0;
int size = bmp.Width * bmp.Height * 4;
IntPtr colorSpace = OSX.API.CGColorSpaceCreateDeviceRGB();
IntPtr provider = OSX.API.CGDataProviderCreateWithData( IntPtr.Zero, scan0, size, IntPtr.Zero );
IntPtr image = OSX.API.CGImageCreate( bmp.Width, bmp.Height, 8, 8 * 4, bmp.Stride,
colorSpace, 4, provider, IntPtr.Zero, 0, 0 );
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;
OSX.API.CGContextDrawImage( context, rect, image );
OSX.API.CGContextSynchronize( context );
err = OSX.API.QDEndCGContext( windowPort, ref context );
OSX.API.CheckReturn( err );
OSX.API.CGImageRelease( image );
OSX.API.CGDataProviderRelease( provider );
OSX.API.CGColorSpaceRelease( colorSpace );
}
} }
} }

View File

@ -92,7 +92,6 @@
<Compile Include="Platform\MacOS\CarbonBindings\QuartzDisplayServicesAPI.cs" /> <Compile Include="Platform\MacOS\CarbonBindings\QuartzDisplayServicesAPI.cs" />
<Compile Include="Platform\MacOS\CarbonGLNative.cs" /> <Compile Include="Platform\MacOS\CarbonGLNative.cs" />
<Compile Include="Platform\MacOS\CarbonWindowInfo.cs" /> <Compile Include="Platform\MacOS\CarbonWindowInfo.cs" />
<Compile Include="Platform\MacOS\EventInfo.cs" />
<Compile Include="Platform\MacOS\MacOSException.cs" /> <Compile Include="Platform\MacOS\MacOSException.cs" />
<Compile Include="Platform\MacOS\MacOSKeyMap.cs" /> <Compile Include="Platform\MacOS\MacOSKeyMap.cs" />
<Compile Include="Platform\MacOS\QuartzDisplayDeviceDriver.cs" /> <Compile Include="Platform\MacOS\QuartzDisplayDeviceDriver.cs" />

View File

@ -106,15 +106,32 @@ namespace OpenTK.Platform.MacOS {
Update(carbonWindow); Update(carbonWindow);
MakeCurrent(carbonWindow); MakeCurrent(carbonWindow);
Debug.Print("context: {0}", ContextHandle); Debug.Print("context: {0}", ContextHandle);
} }
private IntPtr GetQuartzDevice( CarbonWindowInfo carbonWindow ) { private IntPtr GetQuartzDevice(CarbonWindowInfo carbonWindow)
CarbonGLNative nativeWindow = carbonWindow.nativeWindow; {
return QuartzDisplayDeviceDriver.HandleTo( nativeWindow.TargetDisplayDevice ); IntPtr windowRef = carbonWindow.WindowRef;
if (!CarbonGLNative.WindowRefMap.ContainsKey(windowRef))
return IntPtr.Zero;
WeakReference nativeRef = CarbonGLNative.WindowRefMap[windowRef];
if (!nativeRef.IsAlive)
return IntPtr.Zero;
CarbonGLNative window = nativeRef.Target as CarbonGLNative;
if (window == null)
return IntPtr.Zero;
return QuartzDisplayDeviceDriver.HandleTo(window.TargetDisplayDevice);
} }
void SetDrawable(CarbonWindowInfo carbonWindow) { void SetDrawable(CarbonWindowInfo carbonWindow)
{
IntPtr windowPort = API.GetWindowPort(carbonWindow.WindowRef); IntPtr windowPort = API.GetWindowPort(carbonWindow.WindowRef);
//Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort); //Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort);
@ -122,12 +139,14 @@ namespace OpenTK.Platform.MacOS {
Agl.CheckReturnValue( code, "aglSetDrawable" ); Agl.CheckReturnValue( code, "aglSetDrawable" );
} }
public override void Update(IWindowInfo window) { public override void Update(IWindowInfo window)
CarbonWindowInfo winInfo = (CarbonWindowInfo)window; {
CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window;
if (winInfo.goFullScreenHack) { if (carbonWindow.goFullScreenHack)
winInfo.goFullScreenHack = false; {
CarbonGLNative wind = winInfo.nativeWindow; carbonWindow.goFullScreenHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null) if (wind != null)
wind.SetFullscreen(this); wind.SetFullscreen(this);
@ -135,9 +154,11 @@ namespace OpenTK.Platform.MacOS {
Debug.Print("Could not find window!"); Debug.Print("Could not find window!");
return; return;
} else if (winInfo.goWindowedHack) { }
winInfo.goWindowedHack = false; else if (carbonWindow.goWindowedHack)
CarbonGLNative wind = winInfo.nativeWindow; {
carbonWindow.goWindowedHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null) if (wind != null)
wind.UnsetFullscreen(this); wind.UnsetFullscreen(this);
@ -149,13 +170,22 @@ namespace OpenTK.Platform.MacOS {
if (mIsFullscreen) if (mIsFullscreen)
return; return;
SetDrawable(winInfo); SetDrawable(carbonWindow);
Agl.aglUpdateContext(ContextHandle); Agl.aglUpdateContext(ContextHandle);
} }
private CarbonGLNative GetCarbonWindow(CarbonWindowInfo carbonWindow)
{
WeakReference r = CarbonGLNative.WindowRefMap[carbonWindow.WindowRef];
return r.IsAlive ? (CarbonGLNative)r.Target : null;
}
bool firstFullScreen = false; bool firstFullScreen = false;
internal void SetFullScreen(CarbonWindowInfo info, out int width, out int height) { internal void SetFullScreen(CarbonWindowInfo info, out int width, out int height)
CarbonGLNative wind = info.nativeWindow; {
CarbonGLNative wind = GetCarbonWindow(info);
Debug.Print("Switching to full screen {0}x{1} on context {2}", Debug.Print("Switching to full screen {0}x{1} on context {2}",
wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, ContextHandle); wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, ContextHandle);
@ -175,10 +205,12 @@ namespace OpenTK.Platform.MacOS {
UnsetFullScreen(info); UnsetFullScreen(info);
SetFullScreen(info, out width, out height); SetFullScreen(info, out width, out height);
} }
mIsFullscreen = true; mIsFullscreen = true;
} }
internal void UnsetFullScreen(CarbonWindowInfo windowInfo) { internal void UnsetFullScreen(CarbonWindowInfo windowInfo)
{
Debug.Print("Unsetting AGL fullscreen."); Debug.Print("Unsetting AGL fullscreen.");
byte code = Agl.aglSetDrawable(ContextHandle, IntPtr.Zero); byte code = Agl.aglSetDrawable(ContextHandle, IntPtr.Zero);
Agl.CheckReturnValue( code, "aglSetDrawable" ); Agl.CheckReturnValue( code, "aglSetDrawable" );
@ -192,6 +224,7 @@ namespace OpenTK.Platform.MacOS {
mIsFullscreen = false; mIsFullscreen = false;
} }
#region IGraphicsContext Members #region IGraphicsContext Members
public override void SwapBuffers() { public override void SwapBuffers() {
@ -205,7 +238,7 @@ namespace OpenTK.Platform.MacOS {
} }
public override bool IsCurrent { public override bool IsCurrent {
get { return ContextHandle == Agl.aglGetCurrentContext(); } get { return ContextHandle == Agl.aglGetCurrentContext(); }
} }
public override bool VSync { public override bool VSync {

View File

@ -12,35 +12,41 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
namespace OpenTK.Platform.MacOS.Carbon { namespace OpenTK.Platform.MacOS.Carbon
{
static class Application { static class Application
{
static bool mInitialized = false; static bool mInitialized = false;
static IntPtr uppHandler; static IntPtr uppHandler;
public static CarbonGLNative WindowEventHandler; static CarbonGLNative eventHandler;
static int osMajor, osMinor, osBugfix; static int osMajor, osMinor, osBugfix;
static Application() { static Application()
{
Initialize(); Initialize();
} }
internal static void Initialize() { internal static void Initialize()
{
if (mInitialized) return; if (mInitialized) return;
API.AcquireRootMenu(); API.AcquireRootMenu();
ConnectEvents(); ConnectEvents();
API.Gestalt(GestaltSelector.SystemVersionMajor, out osMajor); API.Gestalt(GestaltSelector.SystemVersionMajor, out osMajor);
API.Gestalt(GestaltSelector.SystemVersionMinor, out osMinor); API.Gestalt(GestaltSelector.SystemVersionMinor, out osMinor);
API.Gestalt(GestaltSelector.SystemVersionBugFix, out osBugfix); API.Gestalt(GestaltSelector.SystemVersionBugFix, out osBugfix);
Debug.Print("Running on Mac OS X {0}.{1}.{2}.", osMajor, osMinor, osBugfix); Debug.Print("Running on Mac OS X {0}.{1}.{2}.", osMajor, osMinor, osBugfix);
TransformProcessToForeground(); TransformProcessToForeground();
} }
private static void TransformProcessToForeground() { private static void TransformProcessToForeground()
{
Carbon.ProcessSerialNumber psn = new ProcessSerialNumber(); Carbon.ProcessSerialNumber psn = new ProcessSerialNumber();
Debug.Print("Setting process to be foreground application."); Debug.Print("Setting process to be foreground application.");
API.GetCurrentProcess(ref psn); API.GetCurrentProcess(ref psn);
@ -48,8 +54,16 @@ namespace OpenTK.Platform.MacOS.Carbon {
API.SetFrontProcess(ref psn); API.SetFrontProcess(ref psn);
} }
static void ConnectEvents() { internal static CarbonGLNative WindowEventHandler
EventTypeSpec[] eventTypes = new EventTypeSpec[] { {
get { return eventHandler; }
set { eventHandler = value; }
}
static void ConnectEvents()
{
EventTypeSpec[] eventTypes = new EventTypeSpec[]
{
new EventTypeSpec(EventClass.Application, AppEventKind.AppActivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppActivated),
new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated),
new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit), new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit),
@ -75,12 +89,16 @@ namespace OpenTK.Platform.MacOS.Carbon {
API.InstallApplicationEventHandler( API.InstallApplicationEventHandler(
uppHandler, eventTypes, IntPtr.Zero, IntPtr.Zero); uppHandler, eventTypes, IntPtr.Zero, IntPtr.Zero);
mInitialized = true; mInitialized = true;
} }
static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData) { static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData)
{
EventInfo evt = new EventInfo(inEvent); EventInfo evt = new EventInfo(inEvent);
switch (evt.EventClass) {
switch (evt.EventClass)
{
case EventClass.AppleEvent: case EventClass.AppleEvent:
// only event here is the apple event. // only event here is the apple event.
Debug.Print("Processing apple event."); Debug.Print("Processing apple event.");
@ -90,7 +108,9 @@ namespace OpenTK.Platform.MacOS.Carbon {
case EventClass.Keyboard: case EventClass.Keyboard:
case EventClass.Mouse: case EventClass.Mouse:
if (WindowEventHandler != null) if (WindowEventHandler != null)
{
return WindowEventHandler.DispatchEvent(inCaller, inEvent, evt, userData); return WindowEventHandler.DispatchEvent(inCaller, inEvent, evt, userData);
}
break; break;
} }
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;

View File

@ -15,8 +15,8 @@ namespace OpenTK.Platform.MacOS.Carbon
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct CarbonPoint public struct CarbonPoint
{ {
internal short V; public short V;
internal short H; public short H;
public CarbonPoint(int x, int y) public CarbonPoint(int x, int y)
{ {
@ -33,26 +33,26 @@ namespace OpenTK.Platform.MacOS.Carbon
short bottom; short bottom;
short right; short right;
internal Rect(short _left, short _top, short _width, short _height) { public Rect(short _left, short _top, short _width, short _height) {
top = _top; top = _top;
left = _left; left = _left;
bottom = (short)(_top + _height); bottom = (short)(_top + _height);
right = (short)(_left + _width); right = (short)(_left + _width);
} }
internal short X { public short X {
get { return left; } get { return left; }
} }
internal short Y { public short Y {
get { return top; } get { return top; }
} }
internal short Width { public short Width {
get { return (short)(right - left); } get { return (short)(right - left); }
} }
internal short Height { public short Height {
get { return (short)(bottom - top); } get { return (short)(bottom - top); }
} }
@ -108,7 +108,7 @@ namespace OpenTK.Platform.MacOS.Carbon
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct HIRect { public struct HIRect {
public HIPoint Origin; public HIPoint Origin;
public HIPoint Size; public HIPoint Size;
@ -120,6 +120,21 @@ namespace OpenTK.Platform.MacOS.Carbon
#endregion #endregion
public struct EventInfo {
public EventInfo(IntPtr eventRef) {
EventClass = API.GetEventClass(eventRef);
EventKind = API.GetEventKind(eventRef);
}
public uint EventKind;
public EventClass EventClass;
public override string ToString() {
return "Event: " + EventClass + ",kind: " + EventKind;
}
}
#region --- Types defined in CarbonEvents.h --- #region --- Types defined in CarbonEvents.h ---
enum EventAttributes : uint enum EventAttributes : uint
@ -132,34 +147,34 @@ namespace OpenTK.Platform.MacOS.Carbon
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EventTypeSpec public struct EventTypeSpec
{ {
internal EventTypeSpec(EventClass evtClass, AppEventKind evtKind) public EventTypeSpec(EventClass evtClass, AppEventKind evtKind)
{ {
this.EventClass = evtClass; this.EventClass = evtClass;
this.EventKind = (uint)evtKind; this.EventKind = (uint)evtKind;
} }
internal EventTypeSpec(EventClass evtClass, AppleEventKind appleKind) public EventTypeSpec(EventClass evtClass, AppleEventKind appleKind)
{ {
this.EventClass = evtClass; this.EventClass = evtClass;
this.EventKind = (uint)appleKind; this.EventKind = (uint)appleKind;
} }
internal EventTypeSpec(EventClass evtClass, MouseEventKind evtKind) public EventTypeSpec(EventClass evtClass, MouseEventKind evtKind)
{ {
this.EventClass = evtClass; this.EventClass = evtClass;
this.EventKind = (uint)evtKind; this.EventKind = (uint)evtKind;
} }
internal EventTypeSpec(EventClass evtClass, KeyboardEventKind evtKind) public EventTypeSpec(EventClass evtClass, KeyboardEventKind evtKind)
{ {
this.EventClass = evtClass; this.EventClass = evtClass;
this.EventKind = (uint)evtKind; this.EventKind = (uint)evtKind;
} }
internal EventTypeSpec(EventClass evtClass, WindowEventKind evtKind) public EventTypeSpec(EventClass evtClass, WindowEventKind evtKind)
{ {
this.EventClass = evtClass; this.EventClass = evtClass;
this.EventKind = (uint)evtKind; this.EventKind = (uint)evtKind;
} }
internal EventClass EventClass; public EventClass EventClass;
internal uint EventKind; public uint EventKind;
} }
public enum EventClass : int public enum EventClass : int
@ -182,7 +197,7 @@ namespace OpenTK.Platform.MacOS.Carbon
Menu = 0x6d656e75, Menu = 0x6d656e75,
Window = 0x77696e64, Window = 0x77696e64,
} }
internal enum WindowEventKind : int public enum WindowEventKind : int
{ {
// window events // window events
WindowUpdate = 1, WindowUpdate = 1,
@ -204,7 +219,7 @@ namespace OpenTK.Platform.MacOS.Carbon
WindowClose = 72, WindowClose = 72,
WindowClosed = 73, WindowClosed = 73,
} }
internal enum MouseEventKind : int public enum MouseEventKind : int
{ {
MouseDown = 1, MouseDown = 1,
MouseUp = 2, MouseUp = 2,
@ -221,7 +236,7 @@ namespace OpenTK.Platform.MacOS.Carbon
Tertiary = 3, Tertiary = 3,
} }
internal enum KeyboardEventKind : int public enum KeyboardEventKind : int
{ {
// raw keyboard events // raw keyboard events
RawKeyDown = 1, RawKeyDown = 1,
@ -230,7 +245,7 @@ namespace OpenTK.Platform.MacOS.Carbon
RawKeyModifiersChanged = 4, RawKeyModifiersChanged = 4,
} }
internal enum AppEventKind : int public enum AppEventKind : int
{ {
// application events // application events
AppActivated = 1, AppActivated = 1,
@ -239,12 +254,12 @@ namespace OpenTK.Platform.MacOS.Carbon
AppLaunchNotification = 4, AppLaunchNotification = 4,
} }
enum AppleEventKind : int public enum AppleEventKind : int
{ {
AppleEvent = 1, AppleEvent = 1,
} }
internal enum EventParamName : int public enum EventParamName : int
{ {
WindowRef = 0x77696e64, // typeWindowRef, WindowRef = 0x77696e64, // typeWindowRef,
@ -263,7 +278,7 @@ namespace OpenTK.Platform.MacOS.Carbon
KeyModifiers = 0x6b6d6f64, // typeUInt32 KeyModifiers = 0x6b6d6f64, // typeUInt32
} }
internal enum EventParamType : int public enum EventParamType : int
{ {
typeWindowRef = 0x77696e64, typeWindowRef = 0x77696e64,
@ -283,7 +298,7 @@ namespace OpenTK.Platform.MacOS.Carbon
typeIEEE64BitFloatingPoint = 0x646f7562, typeIEEE64BitFloatingPoint = 0x646f7562,
} }
internal enum EventMouseButton : int public enum EventMouseButton : int
{ {
Primary = 0, Primary = 0,
Secondary = 1, Secondary = 1,
@ -354,7 +369,8 @@ namespace OpenTK.Platform.MacOS.Carbon
StandardFloating = (CloseBox | CollapseBox) StandardFloating = (CloseBox | CollapseBox)
} }
public enum WindowPositionMethod : uint { public enum WindowPositionMethod : uint
{
CenterOnMainScreen = 1, CenterOnMainScreen = 1,
CenterOnParentWindow = 2, CenterOnParentWindow = 2,
CenterOnParentWindowScreen = 3, CenterOnParentWindowScreen = 3,
@ -369,7 +385,8 @@ namespace OpenTK.Platform.MacOS.Carbon
public delegate OSStatus MacOSEventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData); public delegate OSStatus MacOSEventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData);
internal enum WindowPartCode : short { public enum WindowPartCode : short
{
inDesk = 0, inDesk = 0,
inNoWindow = 0, inNoWindow = 0,
inMenuBar = 1, inMenuBar = 1,
@ -400,11 +417,13 @@ namespace OpenTK.Platform.MacOS.Carbon
#endregion #endregion
#region --- Process Manager --- #region --- Process Manager ---
public enum ProcessApplicationTransformState : int { public enum ProcessApplicationTransformState : int
{
kProcessTransformToForegroundApplication = 1, kProcessTransformToForegroundApplication = 1,
} }
public struct ProcessSerialNumber { public struct ProcessSerialNumber
{
public ulong high; public ulong high;
public ulong low; public ulong low;
} }
@ -422,8 +441,8 @@ namespace OpenTK.Platform.MacOS.Carbon
#region --- Carbon API Methods --- #region --- Carbon API Methods ---
public static class API { public class API
{
const string carbon = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon"; const string carbon = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon";
[DllImport(carbon)] [DllImport(carbon)]
@ -463,11 +482,12 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
static extern OSStatus GetWindowBounds(IntPtr window, WindowRegionCode regionCode, out Rect globalBounds); static extern OSStatus GetWindowBounds(IntPtr window, WindowRegionCode regionCode, out Rect globalBounds);
public static Rect GetWindowBounds(IntPtr window, WindowRegionCode regionCode) { public static Rect GetWindowBounds(IntPtr window, WindowRegionCode regionCode)
Rect rect; {
OSStatus result = GetWindowBounds(window, regionCode, out rect); Rect retval;
CheckReturn(result); OSStatus error = GetWindowBounds(window, regionCode, out retval);
return rect; CheckReturn( error );
return retval;
} }
//[DllImport(carbon)] //[DllImport(carbon)]
@ -479,9 +499,11 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
static extern IntPtr GetEventDispatcherTarget(); static extern IntPtr GetEventDispatcherTarget();
[DllImport(carbon)] [DllImport(carbon,EntryPoint="ReceiveNextEvent")]
static extern OSStatus ReceiveNextEvent(uint inNumTypes, IntPtr inList, static extern OSStatus ReceiveNextEvent(uint inNumTypes,
double inTimeout, bool inPullEvent, IntPtr inList,
double inTimeout,
bool inPullEvent,
out IntPtr outEvent); out IntPtr outEvent);
[DllImport(carbon)] [DllImport(carbon)]
@ -490,32 +512,56 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
static extern void ReleaseEvent(IntPtr theEvent); static extern void ReleaseEvent(IntPtr theEvent);
public static void SendEvent(IntPtr theEvent)
{
IntPtr theTarget = GetEventDispatcherTarget();
SendEventToEventTarget(theEvent, theTarget);
}
// Processes events in the queue and then returns. // Processes events in the queue and then returns.
public static void ProcessEvents() { public static void ProcessEvents()
{
IntPtr theEvent; IntPtr theEvent;
IntPtr theTarget = GetEventDispatcherTarget(); IntPtr theTarget = GetEventDispatcherTarget();
for (;;) { for (;;)
{
OSStatus status = ReceiveNextEvent(0, IntPtr.Zero, 0.0, true, out theEvent); OSStatus status = ReceiveNextEvent(0, IntPtr.Zero, 0.0, true, out theEvent);
if (status == OSStatus.EventLoopTimedOut) if (status == OSStatus.EventLoopTimedOut)
break; break;
if (status != OSStatus.NoError) { if (status != OSStatus.NoError)
{
Debug.Print("Message Loop status: {0}", status); Debug.Print("Message Loop status: {0}", status);
break; break;
} }
if (theEvent == IntPtr.Zero) if (theEvent == IntPtr.Zero)
break; break;
SendEventToEventTarget(theEvent, theTarget); try
{
SendEventToEventTarget(theEvent, theTarget);
}
catch (System.ExecutionEngineException e)
{
Console.Error.WriteLine("ExecutionEngineException caught.");
Console.Error.WriteLine("theEvent: " + new EventInfo(theEvent).ToString());
Console.Error.WriteLine(e.Message);
Console.Error.WriteLine(e.StackTrace);
}
ReleaseEvent(theEvent); ReleaseEvent(theEvent);
} }
} }
#region --- Processing apple event ---
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct EventRecord {
struct EventRecord
{
public ushort what; public ushort what;
public uint message; public uint message;
public uint when; public uint when;
@ -529,15 +575,33 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
static extern OSStatus AEProcessAppleEvent(ref EventRecord theEventRecord); static extern OSStatus AEProcessAppleEvent(ref EventRecord theEventRecord);
public static void ProcessAppleEvent(IntPtr inEvent) { static public void ProcessAppleEvent(IntPtr inEvent)
{
EventRecord record; EventRecord record;
ConvertEventRefToEventRecord(inEvent, out record); ConvertEventRefToEventRecord(inEvent, out record);
AEProcessAppleEvent(ref record); AEProcessAppleEvent(ref record);
} }
#endregion #endregion
#region --- Event handlers --- #endregion
#region --- Getting Event Parameters ---
[DllImport(carbon)]
static extern OSStatus CreateEvent( IntPtr inAllocator,
EventClass inClassID, UInt32 kind, EventTime when,
EventAttributes flags, out IntPtr outEvent);
public static IntPtr CreateWindowEvent(WindowEventKind kind) {
IntPtr retval;
OSStatus stat = CreateEvent(IntPtr.Zero, EventClass.Window, (uint)kind,
0, EventAttributes.kEventAttributeNone, out retval);
if (stat != OSStatus.NoError)
throw new MacOSException(stat);
return retval;
}
[DllImport(carbon)] [DllImport(carbon)]
static extern OSStatus GetEventParameter( static extern OSStatus GetEventParameter(
@ -549,7 +613,9 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.KeyCode, EventParamType.typeUInt32, IntPtr.Zero, EventParamName.KeyCode, EventParamType.typeUInt32, IntPtr.Zero,
sizeof(uint), IntPtr.Zero, (IntPtr)(void*)&code); sizeof(uint), IntPtr.Zero, (IntPtr)(void*)&code);
CheckReturn(result);
if (result != OSStatus.NoError)
throw new MacOSException(result);
return (MacOSKeyCode)code; return (MacOSKeyCode)code;
} }
@ -558,7 +624,9 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.KeyMacCharCode, EventParamType.typeChar, IntPtr.Zero, EventParamName.KeyMacCharCode, EventParamType.typeChar, IntPtr.Zero,
Marshal.SizeOf(typeof(char)), IntPtr.Zero, (IntPtr)(void*)&code); Marshal.SizeOf(typeof(char)), IntPtr.Zero, (IntPtr)(void*)&code);
CheckReturn(result);
if (result != OSStatus.NoError)
throw new MacOSException(result);
return code; return code;
} }
@ -567,7 +635,9 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.MouseButton, EventParamType.typeMouseButton, IntPtr.Zero, EventParamName.MouseButton, EventParamType.typeMouseButton, IntPtr.Zero,
sizeof(short), IntPtr.Zero, (IntPtr)(void*)&button); sizeof(short), IntPtr.Zero, (IntPtr)(void*)&button);
CheckReturn(result);
if (result != OSStatus.NoError)
throw new MacOSException(result);
return (MacOSMouseButton)button; return (MacOSMouseButton)button;
} }
@ -576,7 +646,9 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.MouseWheelDelta, EventParamType.typeSInt32, EventParamName.MouseWheelDelta, EventParamType.typeSInt32,
IntPtr.Zero, sizeof(int), IntPtr.Zero, (IntPtr)(void*)&delta); IntPtr.Zero, sizeof(int), IntPtr.Zero, (IntPtr)(void*)&delta);
CheckReturn(result);
if (result != OSStatus.NoError)
throw new MacOSException(result);
return delta; return delta;
} }
@ -585,7 +657,7 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.WindowMouseLocation, EventParamType.typeHIPoint, IntPtr.Zero, EventParamName.WindowMouseLocation, EventParamType.typeHIPoint, IntPtr.Zero,
Marshal.SizeOf(typeof(HIPoint)), IntPtr.Zero, (IntPtr)(void*)&point); Marshal.SizeOf(typeof(HIPoint)), IntPtr.Zero, (IntPtr)(void*)&point);
//CheckReturn(result);
pt = point; pt = point;
return result; return result;
} }
@ -595,7 +667,7 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.WindowRef, EventParamType.typeWindowRef, IntPtr.Zero, EventParamName.WindowRef, EventParamType.typeWindowRef, IntPtr.Zero,
sizeof(IntPtr), IntPtr.Zero, (IntPtr)(void*)&retval); sizeof(IntPtr), IntPtr.Zero, (IntPtr)(void*)&retval);
//CheckReturn(result);
windowRef = retval; windowRef = retval;
return result; return result;
} }
@ -605,7 +677,7 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.MouseLocation, EventParamType.typeHIPoint, IntPtr.Zero, EventParamName.MouseLocation, EventParamType.typeHIPoint, IntPtr.Zero,
Marshal.SizeOf(typeof(HIPoint)), IntPtr.Zero, (IntPtr)(void*)&point); Marshal.SizeOf(typeof(HIPoint)), IntPtr.Zero, (IntPtr)(void*)&point);
//CheckReturn(result);
pt = point; pt = point;
return result; return result;
} }
@ -615,26 +687,33 @@ namespace OpenTK.Platform.MacOS.Carbon
OSStatus result = API.GetEventParameter(inEvent, OSStatus result = API.GetEventParameter(inEvent,
EventParamName.KeyModifiers, EventParamType.typeUInt32, IntPtr.Zero, EventParamName.KeyModifiers, EventParamType.typeUInt32, IntPtr.Zero,
sizeof(uint), IntPtr.Zero, (IntPtr)(void*)&code); sizeof(uint), IntPtr.Zero, (IntPtr)(void*)&code);
CheckReturn(result);
if (result != OSStatus.NoError)
throw new MacOSException(result);
return (MacOSKeyModifiers)code; return (MacOSKeyModifiers)code;
} }
[DllImport(carbon)] #endregion
static extern OSStatus InstallEventHandler( #region --- Event Handlers ---
IntPtr eventTargetRef, IntPtr handlerProc,
int numtypes, EventTypeSpec[] typeList,
IntPtr userData, IntPtr handlerRef);
public static void InstallWindowEventHandler(IntPtr windowRef, IntPtr uppHandlerProc, EventTypeSpec[] eventTypes, [DllImport(carbon)]
IntPtr userData, IntPtr handlerRef) { static extern OSStatus InstallEventHandler( IntPtr eventTargetRef, IntPtr handlerProc,
int numtypes, EventTypeSpec[] typeList,
IntPtr userData, IntPtr handlerRef);
public static void InstallWindowEventHandler(IntPtr windowRef, IntPtr uppHandlerProc,
EventTypeSpec[] eventTypes, IntPtr userData, IntPtr handlerRef)
{
IntPtr windowTarget = GetWindowEventTarget(windowRef); IntPtr windowTarget = GetWindowEventTarget(windowRef);
OSStatus error = InstallEventHandler(windowTarget, uppHandlerProc, eventTypes.Length, OSStatus error = InstallEventHandler(windowTarget, uppHandlerProc,
eventTypes, userData, handlerRef); eventTypes.Length, eventTypes,
userData, handlerRef);
CheckReturn( error ); CheckReturn( error );
} }
public static void InstallApplicationEventHandler(IntPtr uppHandlerProc, EventTypeSpec[] eventTypes, public static void InstallApplicationEventHandler(IntPtr uppHandlerProc,
IntPtr userData, IntPtr handlerRef) { EventTypeSpec[] eventTypes, IntPtr userData, IntPtr handlerRef)
{
OSStatus error = InstallEventHandler(GetApplicationEventTarget(), uppHandlerProc, OSStatus error = InstallEventHandler(GetApplicationEventTarget(), uppHandlerProc,
eventTypes.Length, eventTypes, eventTypes.Length, eventTypes,
userData, handlerRef); userData, handlerRef);
@ -644,12 +723,18 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
public static extern OSStatus RemoveEventHandler(IntPtr inHandlerRef); public static extern OSStatus RemoveEventHandler(IntPtr inHandlerRef);
#endregion
#region --- GetWindowEventTarget ---
[DllImport(carbon)] [DllImport(carbon)]
public static extern IntPtr GetWindowEventTarget(IntPtr window); public static extern IntPtr GetWindowEventTarget(IntPtr window);
[DllImport(carbon)] [DllImport(carbon)]
public static extern IntPtr GetApplicationEventTarget(); public static extern IntPtr GetApplicationEventTarget();
#endregion
#region --- UPP Event Handlers ---
[DllImport(carbon)] [DllImport(carbon)]
public static extern IntPtr NewEventHandlerUPP(MacOSEventHandler handler); public static extern IntPtr NewEventHandlerUPP(MacOSEventHandler handler);
@ -672,24 +757,50 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
public extern static IntPtr CGColorSpaceCreateDeviceRGB(); public extern static IntPtr CGColorSpaceCreateDeviceRGB();
[DllImport(carbon)] [DllImport(carbon)]
public extern static IntPtr CGDataProviderCreateWithData(IntPtr info, IntPtr[] data, int size, IntPtr releasefunc); public extern static IntPtr CGDataProviderCreateWithData(IntPtr info, IntPtr data, int size, IntPtr releasefunc);
[DllImport(carbon)] [DllImport(carbon)]
public extern static IntPtr CGImageCreate(int width, int height, int bitsPerComponent, int bitsPerPixel, int bytesPerRow, IntPtr colorspace, uint bitmapInfo, IntPtr provider, IntPtr decode, int shouldInterpolate, int intent); public extern static IntPtr CGImageCreate(int width, int height, int bitsPerComponent, int bitsPerPixel, int bytesPerRow, IntPtr colorspace,
uint bitmapInfo, IntPtr provider, IntPtr decode, int shouldInterpolate, int intent);
[DllImport(carbon)] [DllImport(carbon)]
public extern static void SetApplicationDockTileImage(IntPtr imageRef); public extern static void SetApplicationDockTileImage(IntPtr imageRef);
[DllImport(carbon)] [DllImport(carbon)]
public extern static void RestoreApplicationDockTileImage(); public extern static void RestoreApplicationDockTileImage();
[DllImport(carbon)]
public extern static void CGImageRelease(IntPtr image);
[DllImport(carbon)]
public extern static void CGDataProviderRelease(IntPtr provider);
[DllImport(carbon)]
public extern static void CGColorSpaceRelease(IntPtr space);
[DllImport(carbon)]
public extern static void CGContextDrawImage( IntPtr context, HIRect rect, IntPtr image );
[DllImport(carbon)]
public extern static void CGContextSynchronize( IntPtr context );
[DllImport(carbon)]
public extern static OSStatus QDBeginCGContext( IntPtr port, ref IntPtr context );
[DllImport(carbon)]
public extern static OSStatus QDEndCGContext( IntPtr port, ref IntPtr context );
#endregion #endregion
[DllImport(carbon)]
public static extern OSStatus ActivateWindow (IntPtr inWindow, bool inActivate);
[DllImport(carbon)]
public static extern void RunApplicationEventLoop();
[DllImport(carbon)]
public static extern void QuitApplicationEventLoop();
#region --- SetWindowTitle --- #region --- SetWindowTitle ---
[DllImport(carbon)] [DllImport(carbon)]
static extern void SetWindowTitleWithCFString(IntPtr windowRef, IntPtr title); static extern void SetWindowTitleWithCFString(IntPtr windowRef, IntPtr title);
public static void SetWindowTitle(IntPtr windowRef, string title) { public static void SetWindowTitle(IntPtr windowRef, string title)
{
IntPtr str = __CFStringMakeConstantString(title); IntPtr str = __CFStringMakeConstantString(title);
Debug.Print("Setting window title: {0}, CFstring : {1}, Text : {2}", windowRef, str, title); Debug.Print("Setting window title: {0}, CFstring : {1}, Text : {2}", windowRef, str, title);
SetWindowTitleWithCFString(windowRef, str); SetWindowTitleWithCFString(windowRef, str);
// Apparently releasing this reference to the CFConstantString here // Apparently releasing this reference to the CFConstantString here
@ -713,30 +824,36 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
public static extern IntPtr GetWindowPort(IntPtr windowRef); public static extern IntPtr GetWindowPort(IntPtr windowRef);
#region --- Menus ---
[DllImport(carbon)] [DllImport(carbon)]
public static extern IntPtr AcquireRootMenu(); public static extern IntPtr AcquireRootMenu();
#endregion
[DllImport(carbon)] [DllImport(carbon)]
public static extern bool IsWindowCollapsed(IntPtr windowRef); public static extern bool IsWindowCollapsed(IntPtr windowRef);
[DllImport(carbon)] [DllImport(carbon)]
public static extern OSStatus CollapseWindow(IntPtr windowRef, bool collapse); public static extern OSStatus CollapseWindow(IntPtr windowRef, bool collapse);
public static void CheckReturn(OSStatus error ) {
if( error != OSStatus.NoError )
throw new MacOSException( error );
}
[DllImport(carbon, EntryPoint="IsWindowInStandardState")] [DllImport(carbon, EntryPoint="IsWindowInStandardState")]
static extern bool _IsWindowInStandardState(IntPtr windowRef, IntPtr inIdealSize, IntPtr outIdealStandardState); static extern bool _IsWindowInStandardState(IntPtr windowRef, IntPtr inIdealSize, IntPtr outIdealStandardState);
public static bool IsWindowInStandardState(IntPtr windowRef) { public static bool IsWindowInStandardState(IntPtr windowRef)
{
return _IsWindowInStandardState(windowRef, IntPtr.Zero, IntPtr.Zero); return _IsWindowInStandardState(windowRef, IntPtr.Zero, IntPtr.Zero);
} }
[DllImport(carbon)] [DllImport(carbon)]
public unsafe static extern OSStatus ZoomWindowIdeal(IntPtr windowRef, short inPartCode, ref CarbonPoint toIdealSize); public unsafe static extern OSStatus ZoomWindowIdeal(IntPtr windowRef, short inPartCode, ref CarbonPoint toIdealSize);
public static void CheckReturn( OSStatus status ) {
if( status != OSStatus.NoError )
throw new MacOSException( status );
}
[DllImport(carbon)] [DllImport(carbon)]
public unsafe static extern OSStatus DMGetGDeviceByDisplayID( public unsafe static extern OSStatus DMGetGDeviceByDisplayID(
IntPtr displayID, out IntPtr displayDevice, Boolean failToMain); IntPtr displayID, out IntPtr displayDevice, Boolean failToMain);
@ -792,8 +909,13 @@ namespace OpenTK.Platform.MacOS.Carbon
#endregion #endregion
const string gestaltlib = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon"; const string gestaltlib = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon";
[DllImport(gestaltlib)] [DllImport(gestaltlib)]
public static extern OSStatus Gestalt(GestaltSelector selector, out int response); public static extern OSStatus Gestalt(GestaltSelector selector, out int response);
} }
#endregion #endregion
} }

View File

@ -26,15 +26,17 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using OpenTK.Input; using OpenTK.Graphics;
using OpenTK.Platform.MacOS.Carbon; using OpenTK.Platform.MacOS.Carbon;
using OpenTK.Input;
namespace OpenTK.Platform.MacOS { namespace OpenTK.Platform.MacOS
{
class CarbonGLNative : INativeWindow { class CarbonGLNative : INativeWindow
{
CarbonWindowInfo window; CarbonWindowInfo window;
static MacOSKeyMap Keymap = new MacOSKeyMap(); static MacOSKeyMap Keymap = new MacOSKeyMap();
IntPtr uppHandler; IntPtr uppHandler;
@ -42,88 +44,111 @@ namespace OpenTK.Platform.MacOS {
string title = "OpenTK Window"; string title = "OpenTK Window";
Rectangle bounds, clientRectangle; Rectangle bounds, clientRectangle;
Rectangle windowedBounds; Rectangle windowedBounds;
bool isDisposed = false; bool mIsDisposed = false;
bool exists = true; bool mExists = true;
DisplayDevice displayDevice; DisplayDevice mDisplayDevice;
WindowPositionMethod positionMethod = WindowPositionMethod.CenterOnMainScreen; WindowPositionMethod mPositionMethod = WindowPositionMethod.CenterOnMainScreen;
int titlebarHeight; int mTitlebarHeight;
private WindowState windowState = WindowState.Normal; private WindowState windowState = WindowState.Normal;
static Dictionary<IntPtr, WeakReference> mWindows = new Dictionary<IntPtr, WeakReference>();
KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs();
bool mMouseIn = false;
bool mIsActive = false;
Icon mIcon;
KeyPressEventArgs keyPressArgs = new KeyPressEventArgs(); static internal Dictionary<IntPtr, WeakReference> WindowRefMap { get { return mWindows; } }
bool mouseIn = false, isActive = false; internal DisplayDevice TargetDisplayDevice { get { return mDisplayDevice; } }
Icon icon;
internal DisplayDevice TargetDisplayDevice { get { return displayDevice; } }
static CarbonGLNative() { static CarbonGLNative() {
Application.Initialize(); Application.Initialize();
} }
public CarbonGLNative(int x, int y, int width, int height, string title, public CarbonGLNative(int x, int y, int width, int height, string title, GameWindowFlags options, DisplayDevice device)
GameWindowFlags options, DisplayDevice device) { {
this.title = title; this.title = title;
CreateNativeWindow(WindowClass.Document, CreateNativeWindow(WindowClass.Document,
WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | WindowAttributes.StandardDocument | WindowAttributes.StandardHandler |
WindowAttributes.InWindowMenu | WindowAttributes.LiveResize, WindowAttributes.InWindowMenu | WindowAttributes.LiveResize,
new Rect((short)x, (short)y, (short)width, (short)height)); new Rect((short)x, (short)y, (short)width, (short)height));
displayDevice = device;
mDisplayDevice = device;
} }
public void Dispose() { #region IDisposable
public void Dispose()
{
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected virtual void Dispose(bool disposing)
if (isDisposed) {
if (mIsDisposed)
return; return;
Debug.Print("Disposing of CarbonGLNative window."); Debug.Print("Disposing of CarbonGLNative window.");
API.DisposeWindow(window.WindowRef);
isDisposed = true;
exists = false;
if (disposing) { API.DisposeWindow(window.WindowRef);
mIsDisposed = true;
mExists = false;
if (disposing)
{
mWindows.Remove(window.WindowRef);
window.Dispose(); window.Dispose();
window = null; window = null;
} }
DisposeUPP(); DisposeUPP();
} }
~CarbonGLNative() { ~CarbonGLNative()
{
Dispose(false); Dispose(false);
} }
void DisposeUPP() { #endregion
if (uppHandler != IntPtr.Zero) {
API.RemoveEventHandler(uppHandler); #region Private Members
API.DisposeEventHandlerUPP(uppHandler);
void DisposeUPP()
{
if (uppHandler != IntPtr.Zero)
{
//API.RemoveEventHandler(uppHandler);
//API.DisposeEventHandlerUPP(uppHandler);
} }
uppHandler = IntPtr.Zero; uppHandler = IntPtr.Zero;
} }
void CreateNativeWindow(WindowClass @class, WindowAttributes attrib, Rect r) { void CreateNativeWindow(WindowClass @class, WindowAttributes attrib, Rect r) {
Debug.Print("Creating window..."); Debug.Print("Creating window...");
IntPtr windowRef; IntPtr windowRef;
OSStatus err = API.CreateNewWindow(@class, attrib, ref r, out windowRef); OSStatus err = API.CreateNewWindow(@class, attrib, ref r, out windowRef);
Debug.Print("Created Window: {0}", windowRef); API.CheckReturn( err );
API.CheckReturn(err); Debug.Print( "Created window " + windowRef );
API.SetWindowTitle(windowRef, title); API.SetWindowTitle(windowRef, title);
window = new CarbonWindowInfo(windowRef, this);
window = new CarbonWindowInfo(windowRef, true);
SetLocation(r.X, r.Y); SetLocation(r.X, r.Y);
SetSize(r.Width, r.Height); SetSize(r.Width, r.Height);
mWindows.Add(windowRef, new WeakReference(this));
LoadSize(); LoadSize();
Rect titleSize = API.GetWindowBounds(window.WindowRef, WindowRegionCode.TitleBarRegion);
titlebarHeight = titleSize.Height;
Rect titleSize = API.GetWindowBounds(window.WindowRef, WindowRegionCode.TitleBarRegion);
mTitlebarHeight = titleSize.Height;
Debug.Print("Titlebar size: {0}", titleSize); Debug.Print("Titlebar size: {0}", titleSize);
ConnectEvents(); ConnectEvents();
Debug.Print("Attached window events."); Debug.Print("Attached window events.");
} }
void ConnectEvents() { void ConnectEvents()
{
EventTypeSpec[] eventTypes = new EventTypeSpec[] EventTypeSpec[] eventTypes = new EventTypeSpec[]
{ {
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClose), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClose),
@ -146,9 +171,8 @@ namespace OpenTK.Platform.MacOS {
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged), //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
}; };
uppHandler = API.NewEventHandlerUPP(EventHandler); MacOSEventHandler handler = EventHandler;
// TODO: not sure if we need this. uppHandler = API.NewEventHandlerUPP(handler);
GC.KeepAlive( this ); // don't want to dispose the window as we need to keep the event handler open.
API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero); API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero);
Application.WindowEventHandler = this; Application.WindowEventHandler = this;
} }
@ -159,7 +183,7 @@ namespace OpenTK.Platform.MacOS {
void Show() { void Show() {
API.ShowWindow(window.WindowRef); API.ShowWindow(window.WindowRef);
API.RepositionWindow(window.WindowRef, IntPtr.Zero, positionMethod); API.RepositionWindow(window.WindowRef, IntPtr.Zero, mPositionMethod);
API.SelectWindow(window.WindowRef); API.SelectWindow(window.WindowRef);
} }
@ -177,7 +201,7 @@ namespace OpenTK.Platform.MacOS {
Debug.Print("New Size: {0}, {1}", Width, Height); Debug.Print("New Size: {0}, {1}", Width, Height);
// TODO: if we go full screen we need to make this use the device specified. // TODO: if we go full screen we need to make this use the device specified.
bounds = displayDevice.Bounds; bounds = mDisplayDevice.Bounds;
windowState = WindowState.Fullscreen; windowState = WindowState.Fullscreen;
} }
@ -186,57 +210,82 @@ namespace OpenTK.Platform.MacOS {
Debug.Print("Telling Carbon to reset window state to " + windowState.ToString()); Debug.Print("Telling Carbon to reset window state to " + windowState.ToString());
SetCarbonWindowState(); SetCarbonWindowState();
SetSize((short)windowedBounds.Width, (short)windowedBounds.Height); SetSize((short)windowedBounds.Width, (short)windowedBounds.Height);
} }
internal OSStatus DispatchEvent( IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData ) { internal OSStatus DispatchEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData)
switch (evt.EventClass) { {
switch (evt.EventClass)
{
case EventClass.Window: case EventClass.Window:
return ProcessWindowEvent(inCaller, inEvent, evt, userData); return ProcessWindowEvent(inCaller, inEvent, evt, userData);
case EventClass.Mouse: case EventClass.Mouse:
return ProcessMouseEvent(inCaller, inEvent, evt, userData); return ProcessMouseEvent(inCaller, inEvent, evt, userData);
case EventClass.Keyboard: case EventClass.Keyboard:
return ProcessKeyboardEvent(inCaller, inEvent, evt, userData); return ProcessKeyboardEvent(inCaller, inEvent, evt, userData);
default: default:
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
} }
} }
protected OSStatus EventHandler( IntPtr inCaller, IntPtr inEvent, IntPtr userData ) { protected static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData)
{
// bail out if the window passed in is not actually our window. // bail out if the window passed in is not actually our window.
if( window == null || userData != window.WindowRef ) // I think this happens if using winforms with a GameWindow sometimes.
if (!mWindows.ContainsKey(userData))
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
WeakReference reference = mWindows[userData];
// bail out if the CarbonGLNative window has been garbage collected.
if (!reference.IsAlive) {
mWindows.Remove(userData);
return OSStatus.EventNotHandled;
}
CarbonGLNative window = (CarbonGLNative)reference.Target;
//Debug.Print("Processing {0} event for {1}.", evt, window.window);
if (window == null) {
Debug.Print("Window for event not found.");
return OSStatus.EventNotHandled;
}
EventInfo evt = new EventInfo(inEvent); EventInfo evt = new EventInfo(inEvent);
return DispatchEvent( inCaller, inEvent, evt, userData ); return window.DispatchEvent(inCaller, inEvent, evt, userData);
} }
private OSStatus ProcessKeyboardEvent( IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData ) { private OSStatus ProcessKeyboardEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) {
MacOSKeyCode code = (MacOSKeyCode)0; MacOSKeyCode code = (MacOSKeyCode)0;
char charCode = '\0'; char charCode = '\0';
//Debug.Print("Processing keyboard event {0}", evt.KeyboardEventKind); //Debug.Print("Processing keyboard event {0}", evt.KeyboardEventKind);
switch ((KeyboardEventKind)evt.EventKind) { switch ((KeyboardEventKind)evt.EventKind)
{
case KeyboardEventKind.RawKeyDown: case KeyboardEventKind.RawKeyDown:
case KeyboardEventKind.RawKeyRepeat: case KeyboardEventKind.RawKeyRepeat:
case KeyboardEventKind.RawKeyUp: case KeyboardEventKind.RawKeyUp:
GetCharCodes(inEvent, out code, out charCode); GetCharCodes(inEvent, out code, out charCode);
keyPressArgs.KeyChar = charCode; mKeyPressArgs.KeyChar = charCode;
break; break;
} }
if( !Keymap.ContainsKey( code ) ) { if( !Keymap.ContainsKey( code ) ) {
Debug.Print( "{0} is not mapped, ignoring" ); Debug.Print( "{0} not mapped, ignoring press.", code );
return OSStatus.NoError; return OSStatus.NoError;
} }
switch ((KeyboardEventKind)evt.EventKind) { switch ((KeyboardEventKind)evt.EventKind)
{
case KeyboardEventKind.RawKeyRepeat: case KeyboardEventKind.RawKeyRepeat:
keyboard.KeyRepeat = true; keyboard.KeyRepeat = true;
goto case KeyboardEventKind.RawKeyDown; goto case KeyboardEventKind.RawKeyDown;
case KeyboardEventKind.RawKeyDown: case KeyboardEventKind.RawKeyDown:
OnKeyPress(keyPressArgs); OnKeyPress(mKeyPressArgs);
keyboard[Keymap[code]] = true; keyboard[Keymap[code]] = true;
return OSStatus.NoError; return OSStatus.NoError;
@ -254,7 +303,8 @@ namespace OpenTK.Platform.MacOS {
} }
private OSStatus ProcessWindowEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) { private OSStatus ProcessWindowEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) {
switch ((WindowEventKind)evt.EventKind) { switch ((WindowEventKind)evt.EventKind)
{
case WindowEventKind.WindowClose: case WindowEventKind.WindowClose:
CancelEventArgs cancel = new CancelEventArgs(); CancelEventArgs cancel = new CancelEventArgs();
OnClosing(cancel); OnClosing(cancel);
@ -265,7 +315,7 @@ namespace OpenTK.Platform.MacOS {
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
case WindowEventKind.WindowClosed: case WindowEventKind.WindowClosed:
exists = false; mExists = false;
OnClosed(); OnClosed();
return OSStatus.NoError; return OSStatus.NoError;
@ -290,34 +340,40 @@ namespace OpenTK.Platform.MacOS {
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
default: default:
Debug.Print("unhandled {0}", evt); Debug.Print("{0}", evt);
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
} }
} }
OSStatus ProcessMouseEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) {
protected OSStatus ProcessMouseEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) {
MacOSMouseButton button; MacOSMouseButton button;
HIPoint pt = new HIPoint(); HIPoint pt = new HIPoint();
HIPoint screenLoc = new HIPoint(); HIPoint screenLoc = new HIPoint();
OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc); OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc);
if (this.windowState == WindowState.Fullscreen) { if (this.windowState == WindowState.Fullscreen)
{
pt = screenLoc; pt = screenLoc;
} else { }
else
{
err = API.GetEventWindowMouseLocation(inEvent, out pt); err = API.GetEventWindowMouseLocation(inEvent, out pt);
} }
if (err != OSStatus.NoError) { if (err != OSStatus.NoError)
{
// this error comes up from the application event handler. // this error comes up from the application event handler.
if (err != OSStatus.EventParameterNotFound) { if (err != OSStatus.EventParameterNotFound)
{
throw new MacOSException(err); throw new MacOSException(err);
} }
} }
Point mousePosInClient = new Point((int)pt.X, (int)pt.Y); Point mousePosInClient = new Point((int)pt.X, (int)pt.Y);
if (this.windowState != WindowState.Fullscreen) { if (this.windowState != WindowState.Fullscreen)
mousePosInClient.Y -= titlebarHeight; {
mousePosInClient.Y -= mTitlebarHeight;
} }
// check for enter/leave events // check for enter/leave events
@ -325,7 +381,8 @@ namespace OpenTK.Platform.MacOS {
API.GetEventWindowRef(inEvent, out thisEventWindow); API.GetEventWindowRef(inEvent, out thisEventWindow);
CheckEnterLeaveEvents(thisEventWindow, mousePosInClient); CheckEnterLeaveEvents(thisEventWindow, mousePosInClient);
switch ((MouseEventKind)evt.EventKind) { switch ((MouseEventKind)evt.EventKind)
{
case MouseEventKind.MouseDown: case MouseEventKind.MouseDown:
button = API.GetEventMouseButton(inEvent); button = API.GetEventMouseButton(inEvent);
@ -392,12 +449,13 @@ namespace OpenTK.Platform.MacOS {
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
default: default:
Debug.Print("unhandled {0}", evt); Debug.Print("{0}", evt);
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
} }
} }
private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt) { private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt)
{
if (window == null) if (window == null)
return; return;
@ -406,21 +464,25 @@ namespace OpenTK.Platform.MacOS {
if (pt.Y < 0) if (pt.Y < 0)
thisIn = false; thisIn = false;
if (thisIn == mouseIn) return; if (thisIn != mMouseIn)
mouseIn = thisIn; {
mMouseIn = thisIn;
if (mouseIn) if (mMouseIn)
OnMouseEnter(); OnMouseEnter();
else else
OnMouseLeave(); OnMouseLeave();
}
} }
private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode) { private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode)
{
code = API.GetEventKeyboardKeyCode(inEvent); code = API.GetEventKeyboardKeyCode(inEvent);
charCode = API.GetEventKeyboardChar(inEvent); charCode = API.GetEventKeyboardChar(inEvent);
} }
private void ProcessModifierKey(IntPtr inEvent) { private void ProcessModifierKey(IntPtr inEvent)
{
MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent); MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent);
bool caps = (modifiers & MacOSKeyModifiers.CapsLock) != 0; bool caps = (modifiers & MacOSKeyModifiers.CapsLock) != 0;
@ -445,6 +507,11 @@ namespace OpenTK.Platform.MacOS {
if (keyboard[Key.CapsLock] ^ caps) if (keyboard[Key.CapsLock] ^ caps)
keyboard[Key.CapsLock] = caps; keyboard[Key.CapsLock] = caps;
}
Rect GetRegion() {
return API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
} }
void SetLocation(short x, short y) { void SetLocation(short x, short y) {
@ -492,43 +559,53 @@ namespace OpenTK.Platform.MacOS {
clientRectangle = new Rectangle(0, 0, r.Width, r.Height); clientRectangle = new Rectangle(0, 0, r.Width, r.Height);
} }
#endregion
#region INativeWindow Members #region INativeWindow Members
public void ProcessEvents() { public void ProcessEvents()
{
API.ProcessEvents(); API.ProcessEvents();
} }
public Point PointToClient(Point point) { public Point PointToClient(Point point)
{
IntPtr handle = window.WindowRef; IntPtr handle = window.WindowRef;
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
Debug.Print("Rect: {0}", r); Debug.Print("Rect: {0}", r);
return new Point(point.X - r.X, point.Y - r.Y); return new Point(point.X - r.X, point.Y - r.Y);
} }
public Point PointToScreen(Point point)
public Point PointToScreen(Point point) { {
IntPtr handle = window.WindowRef; IntPtr handle = window.WindowRef;
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
Debug.Print("Rect: {0}", r); Debug.Print("Rect: {0}", r);
return new Point(point.X + r.X, point.Y + r.Y); return new Point(point.X + r.X, point.Y + r.Y);
} }
public bool Exists { public bool Exists
get { return exists; } {
get { return mExists; }
} }
public IWindowInfo WindowInfo { public IWindowInfo WindowInfo
{
get { return window; } get { return window; }
} }
public Icon Icon { public Icon Icon {
get { return icon; } get { return mIcon; }
set { set {
icon = value;
SetIcon(value); SetIcon(value);
} }
} }
private void SetIcon(Icon icon) { private unsafe void SetIcon(Icon icon)
{
// The code for this function was adapted from Mono's // The code for this function was adapted from Mono's
// XplatUICarbon implementation, written by Geoff Norton // XplatUICarbon implementation, written by Geoff Norton
// http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs?view=markup&pathrev=136932 // http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs?view=markup&pathrev=136932
@ -572,37 +649,53 @@ namespace OpenTK.Platform.MacOS {
} }
} }
IntPtr provider = API.CGDataProviderCreateWithData(IntPtr.Zero, data, size * 4, IntPtr.Zero); fixed( IntPtr* ptr = data ) {
IntPtr image = API.CGImageCreate(128, 128, 8, 32, 4 * 128, API.CGColorSpaceCreateDeviceRGB(), 4, provider, IntPtr.Zero, 0, 0); IntPtr provider = API.CGDataProviderCreateWithData(IntPtr.Zero, (IntPtr)(void*)ptr, size * 4, IntPtr.Zero);
API.SetApplicationDockTileImage(image); IntPtr image = API.CGImageCreate(128, 128, 8, 32, 4 * 128, API.CGColorSpaceCreateDeviceRGB(), 4, provider, IntPtr.Zero, 0, 0);
API.SetApplicationDockTileImage(image);
}
} }
} }
public string Title { public string Title
get { return title; } {
set { get
{
return title;
}
set
{
API.SetWindowTitle(window.WindowRef, value); API.SetWindowTitle(window.WindowRef, value);
title = value; title = value;
} }
} }
public bool Visible { public bool Visible
{
get { return API.IsWindowVisible(window.WindowRef); } get { return API.IsWindowVisible(window.WindowRef); }
set { set
if (value && !Visible) {
if (value && Visible == false)
Show(); Show();
else else
Hide(); Hide();
} }
} }
public bool Focused { public bool Focused
get { return isActive; } {
get { return this.mIsActive; }
} }
public Rectangle Bounds { public Rectangle Bounds
get { return bounds; } {
set { get
{
return bounds;
}
set
{
Location = value.Location; Location = value.Location;
Size = value.Size; Size = value.Size;
} }
@ -618,12 +711,14 @@ namespace OpenTK.Platform.MacOS {
set { SetSize((short)value.Width, (short)value.Height); } set { SetSize((short)value.Width, (short)value.Height); }
} }
public int Width { public int Width
{
get { return ClientRectangle.Width; } get { return ClientRectangle.Width; }
set { SetClientSize((short)value, (short)Height); } set { SetClientSize((short)value, (short)Height); }
} }
public int Height { public int Height
{
get { return ClientRectangle.Height; } get { return ClientRectangle.Height; }
set { SetClientSize((short)Width, (short)value); } set { SetClientSize((short)Width, (short)value); }
} }
@ -638,24 +733,35 @@ namespace OpenTK.Platform.MacOS {
set { Location = new Point(X, value); } set { Location = new Point(X, value); }
} }
public Rectangle ClientRectangle { public Rectangle ClientRectangle
get { return clientRectangle; } {
set { get
{
return clientRectangle;
}
set
{
// just set the size, and ignore the location value. // just set the size, and ignore the location value.
// this is the behavior of the Windows WinGLNative. // this is the behavior of the Windows WinGLNative.
ClientSize = value.Size; ClientSize = value.Size;
} }
} }
public Size ClientSize { public Size ClientSize
get { return clientRectangle.Size; } {
set { get
{
return clientRectangle.Size;
}
set
{
API.SizeWindow(window.WindowRef, (short)value.Width, (short)value.Height, true); API.SizeWindow(window.WindowRef, (short)value.Width, (short)value.Height, true);
OnResize(); OnResize();
} }
} }
public void Close() { public void Close()
{
CancelEventArgs e = new CancelEventArgs(); CancelEventArgs e = new CancelEventArgs();
OnClosing(e); OnClosing(e);
@ -663,11 +769,14 @@ namespace OpenTK.Platform.MacOS {
return; return;
OnClosed(); OnClosed();
Dispose(); Dispose();
} }
public WindowState WindowState { public WindowState WindowState
get { {
get
{
if (windowState == WindowState.Fullscreen) if (windowState == WindowState.Fullscreen)
return WindowState.Fullscreen; return WindowState.Fullscreen;
@ -675,11 +784,14 @@ namespace OpenTK.Platform.MacOS {
return WindowState.Minimized; return WindowState.Minimized;
if (Carbon.API.IsWindowInStandardState(window.WindowRef)) if (Carbon.API.IsWindowInStandardState(window.WindowRef))
{
return WindowState.Maximized; return WindowState.Maximized;
}
return WindowState.Normal; return WindowState.Normal;
} }
set { set
{
if (value == WindowState) if (value == WindowState)
return; return;
@ -688,7 +800,8 @@ namespace OpenTK.Platform.MacOS {
windowState = value; windowState = value;
if (oldState == WindowState.Fullscreen) { if (oldState == WindowState.Fullscreen)
{
window.goWindowedHack = true; window.goWindowedHack = true;
// when returning from full screen, wait until the context is updated // when returning from full screen, wait until the context is updated
@ -709,7 +822,8 @@ namespace OpenTK.Platform.MacOS {
CarbonPoint idealSize; CarbonPoint idealSize;
OSStatus err; OSStatus err;
switch (windowState) { switch (windowState)
{
case WindowState.Fullscreen: case WindowState.Fullscreen:
window.goFullScreenHack = true; window.goFullScreenHack = true;
break; break;
@ -724,7 +838,8 @@ namespace OpenTK.Platform.MacOS {
break; break;
case WindowState.Normal: case WindowState.Normal:
if (WindowState == WindowState.Maximized) { if (WindowState == WindowState.Maximized)
{
idealSize = new CarbonPoint(); idealSize = new CarbonPoint();
err = API.ZoomWindowIdeal(window.WindowRef, (short)WindowPartCode.inZoomIn, ref idealSize); err = API.ZoomWindowIdeal(window.WindowRef, (short)WindowPartCode.inZoomIn, ref idealSize);
API.CheckReturn( err ); API.CheckReturn( err );
@ -741,47 +856,60 @@ namespace OpenTK.Platform.MacOS {
OnResize(); OnResize();
} }
private void OnKeyPress(KeyPressEventArgs keyPressArgs) { #region --- Event wrappers ---
private void OnKeyPress(KeyPressEventArgs keyPressArgs)
{
if (KeyPress != null) if (KeyPress != null)
KeyPress(this, keyPressArgs); KeyPress(this, keyPressArgs);
} }
private void OnWindowStateChanged() {
private void OnWindowStateChanged()
{
if (WindowStateChanged != null) if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty); WindowStateChanged(this, EventArgs.Empty);
} }
protected virtual void OnClosing(CancelEventArgs e) { protected virtual void OnClosing(CancelEventArgs e)
{
if (Closing != null) if (Closing != null)
Closing(this, e); Closing(this, e);
} }
protected virtual void OnClosed() { protected virtual void OnClosed()
{
if (Closed != null) if (Closed != null)
Closed(this, EventArgs.Empty); Closed(this, EventArgs.Empty);
} }
private void OnMouseLeave() {
private void OnMouseLeave()
{
if (MouseLeave != null) if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty); MouseLeave(this, EventArgs.Empty);
} }
private void OnMouseEnter() { private void OnMouseEnter()
{
if (MouseEnter != null) if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty); MouseEnter(this, EventArgs.Empty);
} }
private void OnActivate() { private void OnActivate()
isActive = true; {
mIsActive = true;
if (FocusedChanged != null)
FocusedChanged(this, EventArgs.Empty);
}
private void OnDeactivate()
{
mIsActive = false;
if (FocusedChanged != null) if (FocusedChanged != null)
FocusedChanged(this, EventArgs.Empty); FocusedChanged(this, EventArgs.Empty);
} }
private void OnDeactivate() { #endregion
isActive = false;
if (FocusedChanged != null)
FocusedChanged(this, EventArgs.Empty);
}
public event EventHandler<EventArgs> Load; public event EventHandler<EventArgs> Load;
public event EventHandler<EventArgs> Unload; public event EventHandler<EventArgs> Unload;
@ -802,6 +930,8 @@ namespace OpenTK.Platform.MacOS {
#endregion #endregion
#region IInputDriver Members
KeyboardDevice keyboard = new KeyboardDevice(); KeyboardDevice keyboard = new KeyboardDevice();
MouseDevice mouse = new MouseDevice(); MouseDevice mouse = new MouseDevice();
@ -840,5 +970,7 @@ namespace OpenTK.Platform.MacOS {
CG.CGDisplayHideCursor(CG.CGMainDisplayID()); CG.CGDisplayHideCursor(CG.CGMainDisplayID());
} }
} }
#endregion
} }
} }

View File

@ -26,33 +26,86 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Platform.MacOS { namespace OpenTK.Platform.MacOS
{
/// \internal /// \internal
/// <summary> Describes a Carbon window.</summary> /// <summary>
sealed class CarbonWindowInfo : IWindowInfo { /// Describes a Carbon window.
/// </summary>
public IntPtr WindowRef; sealed class CarbonWindowInfo : IWindowInfo
{
IntPtr windowRef;
bool ownHandle = false;
bool disposed = false; bool disposed = false;
internal bool goFullScreenHack = false; internal bool goFullScreenHack = false;
internal bool goWindowedHack = false; internal bool goWindowedHack = false;
internal CarbonGLNative nativeWindow;
public CarbonWindowInfo( IntPtr windowRef, CarbonGLNative nativeWindow ) { #region Constructors
this.WindowRef = windowRef;
this.nativeWindow = nativeWindow; /// <summary>
/// Constructs a new instance with the specified parameters.
/// </summary>
/// <param name="windowRef">A valid Carbon window reference.</param>
/// <param name="ownHandle"></param>
public CarbonWindowInfo(IntPtr windowRef, bool ownHandle)
{
this.windowRef = windowRef;
this.ownHandle = ownHandle;
} }
public override string ToString() { #endregion
return String.Format("CarbonWindowInfo: Handle {0}", WindowRef);
#region Public Members
/// <summary>
/// Gets the window reference for this instance.
/// </summary>
internal IntPtr WindowRef
{
get { return this.windowRef; }
} }
/// <summary>Returns a System.String that represents the current window.</summary>
/// <returns>A System.String that represents the current window.</returns>
public override string ToString()
{
return String.Format("MacOS.CarbonWindowInfo: Handle {0}", WindowRef);
}
#endregion
// TODO: I have no idea if this is right.
public IntPtr WinHandle { public IntPtr WinHandle {
get { return WindowRef; } get { return windowRef; }
} }
#region IDisposable Members
public void Dispose() { public void Dispose() {
Dispose(true);
} }
void Dispose(bool disposing) {
if (disposed)
return;
if (ownHandle)
{
Debug.Print("Disposing window {0}.", windowRef);
Carbon.API.DisposeWindow(this.windowRef);
windowRef = IntPtr.Zero;
}
disposed = true;
}
~CarbonWindowInfo() {
Dispose(false);
}
#endregion
} }
} }

View File

@ -1,31 +0,0 @@
//
//
// xCSCarbon
//
// Created by Erik Ylvisaker on 3/17/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace OpenTK.Platform.MacOS.Carbon
{
internal struct EventInfo {
internal EventInfo(IntPtr eventRef) {
EventClass = API.GetEventClass(eventRef);
EventKind = API.GetEventKind(eventRef);
}
public uint EventKind;
public EventClass EventClass;
public override string ToString() {
return "Event class " + EventClass + ", kind: " + EventKind;
}
}
}