Changed: #1060 Implement getWndProc() on Mac OS X

hg/feature/sound
rti 15 years ago
parent 03db06e0c6
commit 9bc0f3e06a

@ -873,8 +873,11 @@ bool CDriverGL::swapBuffers()
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
// TODO: maybe do this somewhere else? // TODO: maybe do this somewhere else?
[_autoreleasePool release]; if(_DestroyWindow)
_autoreleasePool = [[NSAutoreleasePool alloc] init]; {
[_autoreleasePool release];
_autoreleasePool = [[NSAutoreleasePool alloc] init];
}
[_ctx flushBuffer]; [_ctx flushBuffer];
[containerView() display]; [containerView() display];

@ -116,8 +116,7 @@ bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM
#elif defined (NL_OS_MAC) #elif defined (NL_OS_MAC)
// TODO: change that bool GlWndProc(CDriverGL *driver, NSEvent* e);
bool GlWndProc(CDriverGL *driver);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -703,9 +702,11 @@ private:
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
friend bool GlWndProc(CDriverGL* driver, NSEvent* e);
NLMISC::CCocoaEventEmitter _EventEmitter; NLMISC::CCocoaEventEmitter _EventEmitter;
NSOpenGLContext* _ctx; NSOpenGLContext* _ctx;
NSOpenGLView* _glView; CocoaOpenGLView* _glView;
NSAutoreleasePool* _autoreleasePool; NSAutoreleasePool* _autoreleasePool;
uint16 _backBufferHeight; uint16 _backBufferHeight;
uint16 _backBufferWidth; uint16 _backBufferWidth;

@ -164,8 +164,22 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
#elif defined (NL_OS_MAC) #elif defined (NL_OS_MAC)
bool GlWndProc(CDriverGL *driver) bool GlWndProc(CDriverGL *driver, NSEvent* e)
{ {
H_AUTO_OGL(GlWndProc)
if(!driver)
return false;
// NSLog(@"NSEvent in GlWndProc %@", e);
switch([e type])
{
/* TODO handle window move, resize, activate, close, etc. */
default:
return driver->_EventEmitter.processMessage(e);
}
return false; return false;
} }
@ -951,6 +965,8 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
[_ctx flushBuffer]; [_ctx flushBuffer];
[containerView() display]; [containerView() display];
_EventEmitter.init(this, _glView);
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
static int sAttribList16bpp[] = static int sAttribList16bpp[] =
@ -2164,7 +2180,7 @@ void CDriverGL::showWindow(bool show)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
// TODO implement me # warning "OpenGL Driver: Missing Mac Implementation for showWindow"
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2601,7 +2617,7 @@ bool CDriverGL::isActive()
res = (IsWindow(_win) != FALSE); res = (IsWindow(_win) != FALSE);
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation for isActive" # warning "OpenGL Driver: Missing Mac Implementation for isActive (always true if a window is set)"
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
#endif // NL_OS_UNIX #endif // NL_OS_UNIX

@ -16,13 +16,6 @@
#include "cocoa_event_emitter.h" #include "cocoa_event_emitter.h"
#include "nel/misc/event_server.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
namespace NLMISC namespace NLMISC
{ {
@ -217,191 +210,224 @@ static bool isTextKeyEvent(NSEvent* event)
return false; return false;
} }
void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */) void CCocoaEventEmitter::init(NL3D::IDriver* driver, CocoaOpenGLView* glView)
{ {
// break if there was no event to handle _driver = driver;
while(true) _glView = glView;
{ }
// get the next event to handle
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:nil /*[NSDate distantFuture]*/
inMode:NSDefaultRunLoopMode dequeue:YES];
// stop, if there was no event bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server)
if(!event) {
break; if(!server && !_server)
nlerror("no server to post events to");
NSView* glView = [[[[event window] contentView] subviews] lastObject]; if(!server)
NSRect viewRect = [glView frame]; server = _server;
// TODO this code assumes, that the view fills the window NSRect viewRect = [_glView frame];
// convert the mouse position to NeL style (relative)
float mouseX = event.locationInWindow.x / (float)viewRect.size.width;
float mouseY = event.locationInWindow.y / (float)viewRect.size.height;
// if the mouse event was placed outside the view, don't tell NeL :) // TODO this code assumes, that the view fills the window
if((mouseX < 0.0 || mouseX > 1.0 || mouseY < 0.0 || mouseY > 1.0) && // convert the mouse position to NeL style (relative)
event.type != NSKeyDown && event.type != NSKeyUp) float mouseX = event.locationInWindow.x / (float)viewRect.size.width;
{ float mouseY = event.locationInWindow.y / (float)viewRect.size.height;
[NSApp sendEvent:event];
continue;
}
// convert the modifiers for nel to pass them with the events // if the mouse event was placed outside the view, don't tell NeL :)
NLMISC::TKeyButton modifiers = if((mouseX < 0.0 || mouseX > 1.0 || mouseY < 0.0 || mouseY > 1.0) &&
modifierFlagsToNelKeyButton([event modifierFlags]); event.type != NSKeyDown && event.type != NSKeyUp)
{
[NSApp sendEvent:event];
return false;
}
switch(event.type) // convert the modifiers for nel to pass them with the events
{ NLMISC::TKeyButton modifiers =
case NSLeftMouseDown: modifierFlagsToNelKeyButton([event modifierFlags]);
{
server.postEvent(new NLMISC::CEventMouseDown( switch(event.type)
mouseX, mouseY, {
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); case NSLeftMouseDown:
} {
server->postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this));
}
break;
case NSLeftMouseUp:
{
server->postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this));
break; break;
case NSLeftMouseUp: }
{ case NSRightMouseDown:
server.postEvent(new NLMISC::CEventMouseUp( {
mouseX, mouseY, server->postEvent(new NLMISC::CEventMouseDown(
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); mouseX, mouseY,
break; (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this));
} break;
case NSRightMouseDown: }
{ case NSRightMouseUp:
server.postEvent(new NLMISC::CEventMouseDown( {
mouseX, mouseY, server->postEvent(new NLMISC::CEventMouseUp(
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); mouseX, mouseY,
break; (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this));
} break;
case NSRightMouseUp: }
{ case NSMouseMoved:
server.postEvent(new NLMISC::CEventMouseUp( {
mouseX, mouseY, NLMISC::CEvent* nelEvent;
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this));
break;
}
case NSMouseMoved:
{
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event // when emulating raw mode, send the delta in a CGDMouseMove event
if(_emulateRawMode) if(_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove( nelEvent = new NLMISC::CGDMouseMove(
this, NULL /* no mouse device */, event.deltaX, -event.deltaY); this, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove // normally send position in a CEventMouseMove
else else
nelEvent = new NLMISC::CEventMouseMove( nelEvent = new NLMISC::CEventMouseMove(
mouseX, mouseY, (NLMISC::TMouseButton)modifiers, this); mouseX, mouseY, (NLMISC::TMouseButton)modifiers, this);
server.postEvent(nelEvent); server->postEvent(nelEvent);
break; break;
} }
case NSLeftMouseDragged: case NSLeftMouseDragged:
{ {
NLMISC::CEvent* nelEvent; NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event // when emulating raw mode, send the delta in a CGDMouseMove event
if(_emulateRawMode) if(_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove( nelEvent = new NLMISC::CGDMouseMove(
this, NULL /* no mouse device */, event.deltaX, -event.deltaY); this, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove // normally send position in a CEventMouseMove
else else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this); (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this);
server.postEvent(nelEvent); server->postEvent(nelEvent);
break; break;
} }
case NSRightMouseDragged: case NSRightMouseDragged:
{ {
NLMISC::CEvent* nelEvent; NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event // when emulating raw mode, send the delta in a CGDMouseMove event
if(_emulateRawMode) if(_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove( nelEvent = new NLMISC::CGDMouseMove(
this, NULL /* no mouse device */, event.deltaX, -event.deltaY); this, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove // normally send position in a CEventMouseMove
else else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this); (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this);
server.postEvent(nelEvent); server->postEvent(nelEvent);
break; break;
} }
case NSMouseEntered:break; case NSMouseEntered:break;
case NSMouseExited:break; case NSMouseExited:break;
case NSKeyDown: case NSKeyDown:
{ {
// push the key press event to the event server // push the key press event to the event server
server.postEvent(new NLMISC::CEventKeyDown( server->postEvent(new NLMISC::CEventKeyDown(
virtualKeycodeToNelKey([event keyCode]), virtualKeycodeToNelKey([event keyCode]),
modifierFlagsToNelKeyButton([event modifierFlags]), modifierFlagsToNelKeyButton([event modifierFlags]),
[event isARepeat] == NO, this)); [event isARepeat] == NO, this));
// if this was a text event // if this was a text event
if(isTextKeyEvent(event)) if(isTextKeyEvent(event))
{
ucstring ucstr;
// get the string associated with the key press event
ucstr.fromUtf8([[event characters] UTF8String]);
// push the text event to event server as well
server.postEvent(new NLMISC::CEventChar(
ucstr[0], NLMISC::noKeyButton, this));
}
break;
}
case NSKeyUp:
{
// push the key release event to the event server
server.postEvent(new NLMISC::CEventKeyUp(
virtualKeycodeToNelKey([event keyCode]),
modifierFlagsToNelKeyButton([event modifierFlags]), this));
break;
}
case NSFlagsChanged:break;
case NSAppKitDefined:break;
case NSSystemDefined:break;
case NSApplicationDefined:break;
case NSPeriodic:break;
case NSCursorUpdate:break;
case NSScrollWheel:
{ {
if(fabs(event.deltaY) > 0.1) ucstring ucstr;
server.postEvent(new NLMISC::CEventMouseWheel(
mouseX, mouseY, (NLMISC::TMouseButton)modifiers,
(event.deltaY > 0), this));
break; // get the string associated with the key press event
ucstr.fromUtf8([[event characters] UTF8String]);
// push the text event to event server as well
server->postEvent(new NLMISC::CEventChar(
ucstr[0], NLMISC::noKeyButton, this));
} }
case NSTabletPoint:break; break;
case NSTabletProximity:break; }
case NSOtherMouseDown:break; case NSKeyUp:
case NSOtherMouseUp:break; {
case NSOtherMouseDragged:break; // push the key release event to the event server
server->postEvent(new NLMISC::CEventKeyUp(
virtualKeycodeToNelKey([event keyCode]),
modifierFlagsToNelKeyButton([event modifierFlags]), this));
break;
}
case NSFlagsChanged:break;
case NSAppKitDefined:break;
case NSSystemDefined:break;
case NSApplicationDefined:break;
case NSPeriodic:break;
case NSCursorUpdate:break;
case NSScrollWheel:
{
if(fabs(event.deltaY) > 0.1)
server->postEvent(new NLMISC::CEventMouseWheel(
mouseX, mouseY, (NLMISC::TMouseButton)modifiers,
(event.deltaY > 0), this));
break;
}
case NSTabletPoint:break;
case NSTabletProximity:break;
case NSOtherMouseDown:break;
case NSOtherMouseUp:break;
case NSOtherMouseDragged:break;
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER #ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
case NSEventTypeGesture:break; case NSEventTypeGesture:break;
case NSEventTypeMagnify:break; case NSEventTypeMagnify:break;
case NSEventTypeSwipe:break; case NSEventTypeSwipe:break;
case NSEventTypeRotate:break; case NSEventTypeRotate:break;
case NSEventTypeBeginGesture:break; case NSEventTypeBeginGesture:break;
case NSEventTypeEndGesture:break; case NSEventTypeEndGesture:break;
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER #endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
default: default:
{ {
nlwarning("Unknown event type. dropping."); nlwarning("Unknown event type. dropping.");
// NSLog(@"%@", event); // NSLog(@"%@", event);
break;
}
}
[NSApp sendEvent:event];
return true;
}
typedef bool (*cocoaProc)(NL3D::IDriver*, void* e);
void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */)
{
// break if there was no event to handle
while(true)
{
// get the next event to handle
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:nil /*[NSDate distantFuture]*/
inMode:NSDefaultRunLoopMode dequeue:YES];
// stop, if there was no event
if(!event)
break; break;
if(_driver)
{
cocoaProc proc = (cocoaProc)_driver->getWindowProc();
if(proc)
proc(_driver, event);
} }
else
{
processMessage(event, &server);
} }
[NSApp sendEvent:event];
} }
// TODO like internal server in unix event emitter... review!
_server = &server;
// _server->pump();
} }
void CCocoaEventEmitter::emulateMouseRawMode(bool enable) void CCocoaEventEmitter::emulateMouseRawMode(bool enable)

@ -17,19 +17,38 @@
#ifndef NL_COCOA_EVENT_EMITTER_H #ifndef NL_COCOA_EVENT_EMITTER_H
#define NL_COCOA_EVENT_EMITTER_H #define NL_COCOA_EVENT_EMITTER_H
#include <nel/misc/event_emitter.h> #include "nel/misc/event_emitter.h"
#include "nel/misc/event_server.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include "nel/3d/driver.h"
#import "cocoa_opengl_view.h"
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
namespace NLMISC namespace NLMISC
{ {
class CCocoaEventEmitter : public IEventEmitter class CCocoaEventEmitter : public IEventEmitter
{ {
bool _emulateRawMode; bool _emulateRawMode;
NL3D::IDriver* _driver;
CocoaOpenGLView* _glView;
// TODO like internal server in unix event emitter... review!
CEventServer* _server;
public: public:
CCocoaEventEmitter() : _emulateRawMode(false) { } CCocoaEventEmitter() :
_emulateRawMode(false),
_driver(NULL),
_glView(nil),
_server(NULL) { }
virtual void submitEvents(CEventServer & server, bool allWindows); void init(NL3D::IDriver* driver, CocoaOpenGLView* glView);
bool processMessage(NSEvent* event, CEventServer* server = NULL);
virtual void submitEvents(CEventServer& server, bool allWindows);
virtual void emulateMouseRawMode(bool enable); virtual void emulateMouseRawMode(bool enable);
}; };

Loading…
Cancel
Save