Move input event handling to application level for fullscreen support.

This commit is contained in:
kanato 2009-02-05 04:38:37 +00:00
parent dc6f0e6461
commit b921bf95dd
2 changed files with 136 additions and 50 deletions

View file

@ -15,11 +15,11 @@ 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;
static CarbonGLNative eventHandler;
static Application() static Application()
{ {
@ -35,6 +35,12 @@ namespace OpenTK.Platform.MacOS.Carbon
ConnectEvents(); ConnectEvents();
} }
internal static CarbonGLNative WindowEventHandler
{
get { return eventHandler; }
set { eventHandler = value; }
}
static void ConnectEvents() static void ConnectEvents()
{ {
EventTypeSpec[] eventTypes = new EventTypeSpec[] EventTypeSpec[] eventTypes = new EventTypeSpec[]
@ -43,6 +49,19 @@ namespace OpenTK.Platform.MacOS.Carbon
new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated),
new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit), new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
new EventTypeSpec(EventClass.AppleEvent, AppleEventKind.AppleEvent), new EventTypeSpec(EventClass.AppleEvent, AppleEventKind.AppleEvent),
}; };
@ -59,21 +78,28 @@ namespace OpenTK.Platform.MacOS.Carbon
{ {
EventInfo evt = new EventInfo(inEvent); EventInfo evt = new EventInfo(inEvent);
//Debug.Print("{0}", evt); switch (evt.EventClass)
{
case EventClass.Application:
switch (evt.AppEventKind)
{
default:
return OSStatus.EventNotHandled;
}
if (evt.EventClass == EventClass.Application) case EventClass.AppleEvent:
{ // only event here is the apple event.
switch (evt.AppEventKind) Debug.Print("Processing apple event.");
{ API.ProcessAppleEvent(inEvent);
default: break;
return OSStatus.EventNotHandled;
} case EventClass.Keyboard:
} case EventClass.Mouse:
else if (evt.EventClass == EventClass.AppleEvent) if (WindowEventHandler != null)
{ {
// only event here is the apple event. return WindowEventHandler.DispatchEvent(inCaller, inEvent, evt, userData);
Debug.Print("Processing apple event."); }
API.ProcessAppleEvent(inEvent); break;
} }
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;

View file

@ -27,6 +27,7 @@ namespace OpenTK.Platform.MacOS
static MacOSKeyMap Keymap = new MacOSKeyMap(); static MacOSKeyMap Keymap = new MacOSKeyMap();
IntPtr uppHandler; IntPtr uppHandler;
string title = "OpenTK Window"; string title = "OpenTK Window";
short mWidth, mHeight; short mWidth, mHeight;
short mWindowedWidth, mWindowedHeight; short mWindowedWidth, mWindowedHeight;
@ -142,24 +143,26 @@ namespace OpenTK.Platform.MacOS
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClosed), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClosed),
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowBoundsChanged), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowBoundsChanged),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved), //new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown), //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat), //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp), //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged), //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
}; };
MacOSEventHandler handler = EventHandler; MacOSEventHandler handler = EventHandler;
uppHandler = API.NewEventHandlerUPP(handler); uppHandler = API.NewEventHandlerUPP(handler);
API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero); API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero);
Application.WindowEventHandler = this;
} }
@ -214,9 +217,28 @@ namespace OpenTK.Platform.MacOS
set { mPositionMethod = value; } set { mPositionMethod = value; }
} }
internal OSStatus DispatchEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData)
{
switch (evt.EventClass)
{
case EventClass.Window:
return ProcessWindowEvent(inCaller, inEvent, evt, userData);
case EventClass.Mouse:
return ProcessMouseEvent(inCaller, inEvent, evt, userData);
case EventClass.Keyboard:
return ProcessKeyboardEvent(inCaller, inEvent, evt, userData);
default:
return OSStatus.EventNotHandled;
}
}
protected static 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.
// I think this happens if using winforms with a GameWindow sometimes.
if (mWindows.ContainsKey(userData) == false) if (mWindows.ContainsKey(userData) == false)
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
@ -312,7 +334,14 @@ namespace OpenTK.Platform.MacOS
return OSStatus.NoError; return OSStatus.NoError;
case WindowEventKind.WindowBoundsChanged: case WindowEventKind.WindowBoundsChanged:
OnResize(); int thisWidth = Width;
int thisHeight = Height;
LoadSize();
if (thisWidth != Width || thisHeight != Height)
OnResize();
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
default: default:
@ -327,27 +356,45 @@ namespace OpenTK.Platform.MacOS
MouseButton button = MouseButton.Primary; MouseButton button = MouseButton.Primary;
HIPoint pt = new HIPoint(); HIPoint pt = new HIPoint();
OSStatus err = API.GetEventWindowMouseLocation(inEvent, out pt); OSStatus err ;
if (this.windowState == WindowState.Fullscreen)
{
err = API.GetEventMouseLocation(inEvent, out pt);
}
else
{
err = API.GetEventWindowMouseLocation(inEvent, out pt);
}
if (err != OSStatus.NoError) if (err != OSStatus.NoError)
{ {
// this error comes up if there is a mouse move event // this error comes up from the application event handler.
// while switching from fullscreen to windowed. just
// ignore it.
if (err != OSStatus.EventParameterNotFound) if (err != OSStatus.EventParameterNotFound)
{ {
throw new MacOSException(err); throw new MacOSException(err);
} }
} }
// ignore clicks in the title bar
if (pt.Y < mTitlebarHeight)
return OSStatus.EventNotHandled;
InputDriver.Mouse[0].Position = if (this.windowState == WindowState.Fullscreen)
new System.Drawing.Point( {
(int)pt.X, InputDriver.Mouse[0].Position =
(int)(pt.Y - mTitlebarHeight)); new System.Drawing.Point(
(int)pt.X,
(int)pt.Y);
}
else
{
// ignore clicks in the title bar
if (pt.Y < mTitlebarHeight)
return OSStatus.EventNotHandled;
InputDriver.Mouse[0].Position =
new System.Drawing.Point(
(int)pt.X,
(int)(pt.Y - mTitlebarHeight));
}
switch (evt.MouseEventKind) switch (evt.MouseEventKind)
{ {
@ -635,7 +682,7 @@ namespace OpenTK.Platform.MacOS
if (WindowState == WindowState.Fullscreen) if (WindowState == WindowState.Fullscreen)
{ {
((AglContext)context.Implementation).UnsetFullScreen(window); UnsetFullscreen();
} }
if (WindowState == WindowState.Minimized) if (WindowState == WindowState.Minimized)
{ {
@ -646,17 +693,7 @@ namespace OpenTK.Platform.MacOS
switch (value) switch (value)
{ {
case WindowState.Fullscreen: case WindowState.Fullscreen:
((AglContext)context.Implementation).SetFullScreen(window); SetFullscreen();
mWindowedWidth = mWidth;
mWindowedHeight = mHeight;
Debug.Print("Prev Size: {0}, {1}", Width, Height);
mWidth = (short) DisplayDevice.Default.Width;
mHeight = (short) DisplayDevice.Default.Height;
Debug.Print("New Size: {0}, {1}", Width, Height);
break; break;
@ -688,6 +725,28 @@ namespace OpenTK.Platform.MacOS
} }
} }
private void SetFullscreen()
{
((AglContext)context.Implementation).SetFullScreen(window);
mWindowedWidth = mWidth;
mWindowedHeight = mHeight;
Debug.Print("Prev Size: {0}, {1}", Width, Height);
mWidth = (short)DisplayDevice.Default.Width;
mHeight = (short)DisplayDevice.Default.Height;
Debug.Print("New Size: {0}, {1}", Width, Height);
}
private void UnsetFullscreen()
{
((AglContext)context.Implementation).UnsetFullScreen(window);
SetSize(mWindowedWidth, mWindowedHeight);
}
public WindowBorder WindowBorder public WindowBorder WindowBorder
{ {
get get
@ -712,5 +771,6 @@ namespace OpenTK.Platform.MacOS
} }
#endregion #endregion
} }
} }