LLWindow: Move to using Cocoa for window and view creation along with setting up callbacks for event handling as such.
parent
b6abf5c0ee
commit
c8aa1fb7c8
|
|
@ -75,11 +75,13 @@ if (DARWIN)
|
|||
llkeyboardmacosx.cpp
|
||||
llwindowmacosx.cpp
|
||||
llwindowmacosx-objc.mm
|
||||
llopenglview-objc.mm
|
||||
)
|
||||
list(APPEND llwindow_HEADER_FILES
|
||||
llkeyboardmacosx.h
|
||||
llwindowmacosx.h
|
||||
llwindowmacosx-objc.h
|
||||
llopenglview-objc.h
|
||||
)
|
||||
|
||||
# We use a bunch of deprecated system APIs.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "llkeyboardmacosx.h"
|
||||
#include "llwindowcallbacks.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
LLKeyboardMacOSX::LLKeyboardMacOSX()
|
||||
{
|
||||
|
|
@ -162,23 +162,23 @@ LLKeyboardMacOSX::LLKeyboardMacOSX()
|
|||
|
||||
void LLKeyboardMacOSX::resetMaskKeys()
|
||||
{
|
||||
U32 mask = GetCurrentEventKeyModifiers();
|
||||
U32 mask = getModifiers();
|
||||
|
||||
// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
|
||||
// It looks a bit suspicious, as it won't correct for keys that have been released.
|
||||
// Is this the way it's supposed to work?
|
||||
|
||||
if(mask & shiftKey)
|
||||
if(mask & MAC_SHIFT_KEY)
|
||||
{
|
||||
mKeyLevel[KEY_SHIFT] = TRUE;
|
||||
}
|
||||
|
||||
if(mask & (controlKey))
|
||||
if(mask & (MAC_CTRL_KEY))
|
||||
{
|
||||
mKeyLevel[KEY_CONTROL] = TRUE;
|
||||
}
|
||||
|
||||
if(mask & optionKey)
|
||||
if(mask & MAC_ALT_KEY)
|
||||
{
|
||||
mKeyLevel[KEY_ALT] = TRUE;
|
||||
}
|
||||
|
|
@ -201,17 +201,17 @@ MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
|
|||
// translate the mask
|
||||
MASK out_mask = 0;
|
||||
|
||||
if(mask & shiftKey)
|
||||
if(mask & MAC_SHIFT_KEY)
|
||||
{
|
||||
out_mask |= MASK_SHIFT;
|
||||
}
|
||||
|
||||
if(mask & (controlKey | cmdKey))
|
||||
if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
|
||||
{
|
||||
out_mask |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
if(mask & optionKey)
|
||||
if(mask & MAC_ALT_KEY)
|
||||
{
|
||||
out_mask |= MASK_ALT;
|
||||
}
|
||||
|
|
@ -231,7 +231,12 @@ BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
|
|||
{
|
||||
handled = handleTranslatedKeyDown(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
LL_INFOS("Keyboard") << "Unhandled key: " << mTranslateKeyMap[key] << LL_ENDL;
|
||||
} else {
|
||||
LL_INFOS("Keyboard") << "Handled key: " << mTranslateKeyMap[key] << LL_ENDL;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
@ -255,16 +260,16 @@ BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
|
|||
MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
|
||||
{
|
||||
MASK result = MASK_NONE;
|
||||
U32 mask = GetCurrentEventKeyModifiers();
|
||||
U32 mask = getModifiers();
|
||||
|
||||
if (mask & shiftKey) result |= MASK_SHIFT;
|
||||
if (mask & controlKey) result |= MASK_CONTROL;
|
||||
if (mask & optionKey) result |= MASK_ALT;
|
||||
if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT;
|
||||
if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL;
|
||||
if (mask & MAC_ALT_KEY) result |= MASK_ALT;
|
||||
|
||||
// For keyboard events, consider Command equivalent to Control
|
||||
if (!for_mouse_event)
|
||||
{
|
||||
if (mask & cmdKey) result |= MASK_CONTROL;
|
||||
if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@
|
|||
|
||||
#include "llkeyboard.h"
|
||||
|
||||
// These more or less mirror their equivalents in NSEvent.h.
|
||||
enum EMacEventKeys {
|
||||
MAC_SHIFT_KEY = 1 << 17,
|
||||
MAC_CTRL_KEY = 1 << 18,
|
||||
MAC_ALT_KEY = 1 << 19,
|
||||
MAC_CMD_KEY = 1 << 20,
|
||||
MAC_FN_KEY = 1 << 23
|
||||
};
|
||||
|
||||
class LLKeyboardMacOSX : public LLKeyboard
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// LLOpenGLView.h
|
||||
// SecondLife
|
||||
//
|
||||
// Created by Geenz on 10/2/12.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
// Some nasty shovelling of LLOpenGLView from LLNativeBindings to prevent any C++ <-> Obj-C interop oddities.
|
||||
// Redraw callback handling removed (for now) due to being unneeded in the patch that preceeds this addition.
|
||||
|
||||
@interface LLOpenGLView : NSOpenGLView
|
||||
{
|
||||
NSPoint mousePos;
|
||||
ResizeCallback mResizeCallback;
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
|
||||
|
||||
// rebuildContext
|
||||
// Destroys and recreates a context with the view's internal format set via setPixelFormat;
|
||||
// Use this in event of needing to rebuild a context for whatever reason, without needing to assign a new pixel format.
|
||||
- (BOOL) rebuildContext;
|
||||
|
||||
// rebuildContextWithFormat
|
||||
// Destroys and recreates a context with the specified pixel format.
|
||||
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format;
|
||||
|
||||
// These are mostly just for C++ <-> Obj-C interop. We can manipulate the CGLContext from C++ without reprecussions.
|
||||
- (CGLContextObj) getCGLContextObj;
|
||||
- (CGLPixelFormatObj*)getCGLPixelFormatObj;
|
||||
|
||||
- (void) registerResizeCallback:(ResizeCallback)callback;
|
||||
@end
|
||||
|
||||
@interface LLNSWindow : NSWindow {
|
||||
float mMousePos[2];
|
||||
unsigned int mModifiers;
|
||||
|
||||
KeyCallback mKeyDownCallback;
|
||||
KeyCallback mKeyUpCallback;
|
||||
UnicodeCallback mUnicodeCallback;
|
||||
ModifierCallback mModifierCallback;
|
||||
MouseCallback mMouseDownCallback;
|
||||
MouseCallback mMouseUpCallback;
|
||||
MouseCallback mMouseDoubleClickCallback;
|
||||
MouseCallback mRightMouseDownCallback;
|
||||
MouseCallback mRightMouseUpCallback;
|
||||
MouseCallback mMouseMovedCallback;
|
||||
ScrollWheelCallback mScrollWhellCallback;
|
||||
VoidCallback mMouseExitCallback;
|
||||
MouseCallback mDeltaUpdateCallback;
|
||||
}
|
||||
|
||||
- (void) registerKeyDownCallback:(KeyCallback)callback;
|
||||
- (void) registerKeyUpCallback:(KeyCallback)callback;
|
||||
- (void) registerUnicodeCallback:(UnicodeCallback)callback;
|
||||
- (void) registerModifierCallback:(ModifierCallback)callback;
|
||||
- (void) registerMouseDownCallback:(MouseCallback)callback;
|
||||
- (void) registerMouseUpCallback:(MouseCallback)callback;
|
||||
- (void) registerRightMouseDownCallback:(MouseCallback)callback;
|
||||
- (void) registerRightMouseUpCallback:(MouseCallback)callback;
|
||||
- (void) registerDoubleClickCallback:(MouseCallback)callback;
|
||||
- (void) registerMouseMovedCallback:(MouseCallback)callback;
|
||||
- (void) registerScrollCallback:(ScrollWheelCallback)callback;
|
||||
- (void) registerMouseExitCallback:(VoidCallback)callback;
|
||||
- (void) registerDeltaUpdateCallback:(MouseCallback)callback;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
//
|
||||
// LLOpenGLView.m
|
||||
// SecondLife
|
||||
//
|
||||
// Created by Geenz on 10/2/12.
|
||||
//
|
||||
//
|
||||
|
||||
#import "llopenglview-objc.h"
|
||||
|
||||
@implementation LLOpenGLView
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowResized:) name:NSWindowDidResizeNotification
|
||||
object:[self window]];
|
||||
}
|
||||
|
||||
- (void)windowResized:(NSNotification *)notification;
|
||||
{
|
||||
NSSize size = [[self window] frame].size;
|
||||
|
||||
mResizeCallback(size.width, size.height);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
|
||||
{
|
||||
|
||||
[self initWithFrame:frame];
|
||||
|
||||
// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
|
||||
// Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
|
||||
// 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons).
|
||||
NSOpenGLPixelFormatAttribute attrs[] = {
|
||||
NSOpenGLPFANoRecovery,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAClosestPolicy,
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFASampleBuffers, (samples > 0 ? 1 : 0),
|
||||
NSOpenGLPFASamples, samples,
|
||||
NSOpenGLPFAStencilSize, 8,
|
||||
NSOpenGLPFADepthSize, 24,
|
||||
NSOpenGLPFAAlphaSize, 8,
|
||||
NSOpenGLPFAColorSize, 24,
|
||||
0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
|
||||
|
||||
if (pixelFormat == nil)
|
||||
{
|
||||
NSLog(@"Failed to create pixel format!", nil);
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
|
||||
|
||||
if (glContext == nil)
|
||||
{
|
||||
NSLog(@"Failed to create OpenGL context!", nil);
|
||||
return nil;
|
||||
}
|
||||
|
||||
[self setPixelFormat:pixelFormat];
|
||||
|
||||
[self setOpenGLContext:glContext];
|
||||
|
||||
[glContext setView:self];
|
||||
|
||||
[glContext makeCurrentContext];
|
||||
|
||||
if (vsync)
|
||||
{
|
||||
[glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
|
||||
} else {
|
||||
[glContext setValues:(const GLint*)0 forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) rebuildContext
|
||||
{
|
||||
return [self rebuildContextWithFormat:[self pixelFormat]];
|
||||
}
|
||||
|
||||
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format
|
||||
{
|
||||
NSOpenGLContext *ctx = [self openGLContext];
|
||||
|
||||
[ctx clearDrawable];
|
||||
[ctx initWithFormat:format shareContext:nil];
|
||||
|
||||
if (ctx == nil)
|
||||
{
|
||||
NSLog(@"Failed to create OpenGL context!", nil);
|
||||
return false;
|
||||
}
|
||||
|
||||
[self setOpenGLContext:ctx];
|
||||
[ctx setView:self];
|
||||
[ctx makeCurrentContext];
|
||||
return true;
|
||||
}
|
||||
|
||||
- (CGLContextObj)getCGLContextObj
|
||||
{
|
||||
NSOpenGLContext *ctx = [self openGLContext];
|
||||
return (CGLContextObj)[ctx CGLContextObj];
|
||||
}
|
||||
|
||||
- (CGLPixelFormatObj*)getCGLPixelFormatObj
|
||||
{
|
||||
NSOpenGLPixelFormat *fmt = [self pixelFormat];
|
||||
return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj];
|
||||
}
|
||||
|
||||
- (void) registerResizeCallback:(ResizeCallback)callback
|
||||
{
|
||||
mResizeCallback = callback;
|
||||
}
|
||||
|
||||
// Various events can be intercepted by our view, thus not reaching our window.
|
||||
// Intercept these events, and pass them to the window as needed. - Geenz
|
||||
|
||||
- (void) mouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
[super mouseDragged:theEvent];
|
||||
}
|
||||
|
||||
- (void) scrollWheel:(NSEvent *)theEvent
|
||||
{
|
||||
[super scrollWheel:theEvent];
|
||||
}
|
||||
|
||||
- (void) mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
[super mouseDown:theEvent];
|
||||
}
|
||||
|
||||
- (void) mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
[super mouseUp:theEvent];
|
||||
}
|
||||
|
||||
- (void) rightMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
[super rightMouseDown:theEvent];
|
||||
}
|
||||
|
||||
- (void) rightMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
[super rightMouseUp:theEvent];
|
||||
}
|
||||
|
||||
- (void) keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
[super keyUp:theEvent];
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
[super keyDown:theEvent];
|
||||
}
|
||||
|
||||
- (void) mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
[super mouseMoved:theEvent];
|
||||
}
|
||||
|
||||
- (void) flagsChanged:(NSEvent *)theEvent
|
||||
{
|
||||
[super flagsChanged:theEvent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// We use a custom NSWindow for our event handling.
|
||||
// Why not an NSWindowController you may ask?
|
||||
// Answer: this is easier.
|
||||
|
||||
@implementation LLNSWindow
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *)theEvent {
|
||||
mKeyDownCallback([theEvent keyCode], [theEvent modifierFlags]);
|
||||
|
||||
NSString *chars = [theEvent charactersIgnoringModifiers];
|
||||
for (uint i = 0; i < [chars length]; i++)
|
||||
{
|
||||
mUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
// The viewer expects return to be submitted separately as a unicode character.
|
||||
if ([theEvent keyCode] == 3 || [theEvent keyCode] == 13)
|
||||
{
|
||||
mUnicodeCallback([theEvent keyCode], [theEvent modifierFlags]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) keyUp:(NSEvent *)theEvent {
|
||||
mKeyUpCallback([theEvent keyCode], [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent *)theEvent {
|
||||
mModifiers = [theEvent modifierFlags];
|
||||
}
|
||||
|
||||
- (void) mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
if ([theEvent clickCount] == 2)
|
||||
{
|
||||
mMouseDoubleClickCallback(mMousePos, [theEvent modifierFlags]);
|
||||
} else if ([theEvent clickCount] == 1) {
|
||||
mMouseDownCallback(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
mMouseUpCallback(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void) rightMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
mRightMouseDownCallback(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void) rightMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
mRightMouseUpCallback(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)theEvent {
|
||||
float mouseDeltas[2] = {
|
||||
[theEvent deltaX],
|
||||
[theEvent deltaZ]
|
||||
};
|
||||
|
||||
mDeltaUpdateCallback(mouseDeltas, 0);
|
||||
|
||||
NSPoint mPoint = [theEvent locationInWindow];
|
||||
mMousePos[0] = mPoint.x;
|
||||
mMousePos[1] = mPoint.y;
|
||||
mMouseMovedCallback(mMousePos, 0);
|
||||
}
|
||||
|
||||
// NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
|
||||
// Use mouseDragged for situations like this to trigger our movement callback instead.
|
||||
|
||||
- (void) mouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
float mouseDeltas[2] = {
|
||||
[theEvent deltaX],
|
||||
[theEvent deltaZ]
|
||||
};
|
||||
|
||||
mDeltaUpdateCallback(mouseDeltas, 0);
|
||||
|
||||
NSPoint mPoint = [theEvent locationInWindow];
|
||||
mMousePos[0] = mPoint.x;
|
||||
mMousePos[1] = mPoint.y;
|
||||
mMouseMovedCallback(mMousePos, 0);
|
||||
}
|
||||
|
||||
- (void) scrollWheel:(NSEvent *)theEvent
|
||||
{
|
||||
mScrollWhellCallback(-[theEvent deltaY]);
|
||||
}
|
||||
|
||||
- (void) mouseExited:(NSEvent *)theEvent
|
||||
{
|
||||
mMouseExitCallback();
|
||||
}
|
||||
|
||||
- (void) registerKeyDownCallback:(KeyCallback)callback
|
||||
{
|
||||
mKeyDownCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerKeyUpCallback:(KeyCallback)callback
|
||||
{
|
||||
mKeyUpCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerUnicodeCallback:(UnicodeCallback)callback
|
||||
{
|
||||
mUnicodeCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerModifierCallback:(ModifierCallback)callback
|
||||
{
|
||||
mModifierCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerMouseDownCallback:(MouseCallback)callback
|
||||
{
|
||||
mMouseDownCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerMouseUpCallback:(MouseCallback)callback
|
||||
{
|
||||
mMouseUpCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerRightMouseDownCallback:(MouseCallback)callback
|
||||
{
|
||||
mRightMouseDownCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerRightMouseUpCallback:(MouseCallback)callback
|
||||
{
|
||||
mRightMouseUpCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerDoubleClickCallback:(MouseCallback)callback
|
||||
{
|
||||
mMouseDoubleClickCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerMouseMovedCallback:(MouseCallback)callback
|
||||
{
|
||||
mMouseMovedCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerScrollCallback:(ScrollWheelCallback)callback
|
||||
{
|
||||
mScrollWhellCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerMouseExitCallback:(VoidCallback)callback
|
||||
{
|
||||
mMouseExitCallback = callback;
|
||||
}
|
||||
|
||||
- (void) registerDeltaUpdateCallback:(MouseCallback)callback
|
||||
{
|
||||
mDeltaUpdateCallback = callback;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -24,14 +24,61 @@
|
|||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <boost/tr1/functional.hpp>
|
||||
typedef std::tr1::function<void(unsigned short, unsigned int)> KeyCallback;
|
||||
typedef std::tr1::function<void(unsigned int)> ModifierCallback;
|
||||
typedef std::tr1::function<void(float*, unsigned int)> MouseCallback;
|
||||
typedef std::tr1::function<void(wchar_t, unsigned int)> UnicodeCallback;
|
||||
typedef std::tr1::function<void(unsigned int, unsigned int)> ResizeCallback;
|
||||
typedef std::tr1::function<void(float)> ScrollWheelCallback;
|
||||
typedef std::tr1::function<void()> VoidCallback;
|
||||
|
||||
// This will actually hold an NSCursor*, but that type is only available in objective C.
|
||||
typedef void *CursorRef;
|
||||
typedef void *NSWindowRef;
|
||||
typedef void *GLViewRef;
|
||||
|
||||
/* Defined in llwindowmacosx-objc.mm: */
|
||||
void setupCocoa();
|
||||
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
|
||||
OSErr releaseImageCursor(CursorRef ref);
|
||||
OSErr setImageCursor(CursorRef ref);
|
||||
short releaseImageCursor(CursorRef ref);
|
||||
short setImageCursor(CursorRef ref);
|
||||
void setArrowCursor();
|
||||
void setIBeamCursor();
|
||||
void setPointingHandCursor();
|
||||
void setCopyCursor();
|
||||
void setCrossCursor();
|
||||
void hideNSCursor();
|
||||
void showNSCursor();
|
||||
void hideNSCursorTillMove(bool hide);
|
||||
|
||||
NSWindowRef createNSWindow(int x, int y, int width, int height);
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
GLViewRef createOpenGLView(NSWindowRef window);
|
||||
void glSwapBuffers(void* context);
|
||||
CGLContextObj getCGLContextObj(NSWindowRef window);
|
||||
void getContentViewBounds(NSWindowRef window, float* bounds);
|
||||
void getWindowSize(NSWindowRef window, float* size);
|
||||
void setWindowSize(NSWindowRef window, int width, int height);
|
||||
void getCursorPos(NSWindowRef window, float* pos);
|
||||
void makeWindowOrderFront(NSWindowRef window);
|
||||
void convertScreenToWindow(NSWindowRef window, float *coord);
|
||||
void convertWindowToScreen(NSWindowRef window, float *coord);
|
||||
void setWindowPos(NSWindowRef window, float* pos);
|
||||
|
||||
void registerKeyUpCallback(NSWindowRef window, KeyCallback callback);
|
||||
void registerKeyDownCallback(NSWindowRef window, KeyCallback callback);
|
||||
void registerUnicodeCallback(NSWindowRef window, UnicodeCallback callback);
|
||||
void registerMouseUpCallback(NSWindowRef window, MouseCallback callback);
|
||||
void registerMouseDownCallback(NSWindowRef window, MouseCallback callback);
|
||||
void registerRightMouseUpCallback(NSWindowRef window, MouseCallback callback);
|
||||
void registerRightMouseDownCallback(NSWindowRef window, MouseCallback callback);
|
||||
void registerDoubleClickCallback(NSWindowRef window, MouseCallback callback);
|
||||
void registerResizeEventCallback(GLViewRef window, ResizeCallback callback);
|
||||
void registerMouseMovedCallback(NSWindowRef window, MouseCallback callback);
|
||||
void registerScrollCallback(NSWindowRef window, ScrollWheelCallback callback);
|
||||
void registerMouseExitCallback(NSWindowRef window, VoidCallback callback);
|
||||
void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback);
|
||||
|
||||
unsigned int getModifiers();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#include "llopenglview-objc.h"
|
||||
|
||||
/*
|
||||
* These functions are broken out into a separate file because the
|
||||
|
|
@ -34,8 +37,6 @@
|
|||
* linden headers with any objective-C++ source.
|
||||
*/
|
||||
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
void setupCocoa()
|
||||
{
|
||||
static bool inited = false;
|
||||
|
|
@ -83,6 +84,51 @@ CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
|
|||
return (CursorRef)cursor;
|
||||
}
|
||||
|
||||
void setArrowCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor arrowCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setIBeamCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor IBeamCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setPointingHandCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor pointingHandCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setCopyCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor dragCopyCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setCrossCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor crosshairCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void hideNSCursor()
|
||||
{
|
||||
[NSCursor hide];
|
||||
}
|
||||
|
||||
void showNSCursor()
|
||||
{
|
||||
[NSCursor unhide];
|
||||
}
|
||||
|
||||
void hideNSCursorTillMove(bool hide)
|
||||
{
|
||||
[NSCursor setHiddenUntilMouseMoves:hide];
|
||||
}
|
||||
|
||||
// This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness.
|
||||
OSErr releaseImageCursor(CursorRef ref)
|
||||
{
|
||||
|
|
@ -118,3 +164,174 @@ OSErr setImageCursor(CursorRef ref)
|
|||
return noErr;
|
||||
}
|
||||
|
||||
// Now for some unholy juggling between generic pointers and casting them to Obj-C objects!
|
||||
// Note: things can get a bit hairy from here. This is not for the faint of heart.
|
||||
|
||||
NSWindowRef createNSWindow(int x, int y, int width, int height)
|
||||
{
|
||||
LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
|
||||
styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
[window setAcceptsMouseMovedEvents:TRUE];
|
||||
return window;
|
||||
}
|
||||
|
||||
GLViewRef createOpenGLView(NSWindowRef window)
|
||||
{
|
||||
LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:0 andVsync:FALSE];
|
||||
[(LLNSWindow*)window setContentView:glview];
|
||||
return glview;
|
||||
}
|
||||
|
||||
void glSwapBuffers(void* context)
|
||||
{
|
||||
[(NSOpenGLContext*)context flushBuffer];
|
||||
}
|
||||
|
||||
CGLContextObj getCGLContextObj(NSWindowRef window)
|
||||
{
|
||||
LLOpenGLView *glview = [(LLNSWindow*)window contentView];
|
||||
return [glview getCGLContextObj];
|
||||
}
|
||||
|
||||
CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
|
||||
{
|
||||
LLOpenGLView *glview = [(LLNSWindow*)window contentView];
|
||||
return [glview getCGLPixelFormatObj];
|
||||
}
|
||||
|
||||
void getContentViewBounds(NSWindowRef window, float* bounds)
|
||||
{
|
||||
bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
|
||||
bounds[1] = [[(LLNSWindow*)window contentView] bounds].origin.y;
|
||||
bounds[2] = [[(LLNSWindow*)window contentView] bounds].size.width;
|
||||
bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
|
||||
}
|
||||
|
||||
void getWindowSize(NSWindowRef window, float* size)
|
||||
{
|
||||
NSRect frame = [(LLNSWindow*)window frame];
|
||||
size[0] = frame.origin.x;
|
||||
size[1] = frame.origin.y;
|
||||
size[2] = frame.size.width;
|
||||
size[3] = frame.size.height;
|
||||
}
|
||||
|
||||
void setWindowSize(NSWindowRef window, int width, int height)
|
||||
{
|
||||
NSRect frame = [(LLNSWindow*)window frame];
|
||||
frame.size.width = width;
|
||||
frame.size.height = height;
|
||||
[(LLNSWindow*)window setFrame:frame display:TRUE];
|
||||
}
|
||||
|
||||
void setWindowPos(NSWindowRef window, float* pos)
|
||||
{
|
||||
NSPoint point;
|
||||
point.x = pos[0];
|
||||
point.y = pos[1];
|
||||
[(LLNSWindow*)window setFrameOrigin:point];
|
||||
}
|
||||
|
||||
void getCursorPos(NSWindowRef window, float* pos)
|
||||
{
|
||||
NSPoint mLoc;
|
||||
mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
|
||||
pos[0] = mLoc.x;
|
||||
pos[1] = mLoc.y;
|
||||
}
|
||||
|
||||
void makeWindowOrderFront(NSWindowRef window)
|
||||
{
|
||||
[(LLNSWindow*)window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
void convertScreenToWindow(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSPoint point;
|
||||
point.x = coord[0];
|
||||
point.y = coord[1];
|
||||
point = [(LLNSWindow*)window convertScreenToBase:point];
|
||||
coord[0] = point.x;
|
||||
coord[1] = point.y;
|
||||
}
|
||||
|
||||
void convertWindowToScreen(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSPoint point;
|
||||
point.x = coord[0];
|
||||
point.y = coord[1];
|
||||
point = [(LLNSWindow*)window convertBaseToScreen:point];
|
||||
coord[0] = point.x;
|
||||
coord[1] = point.y;
|
||||
}
|
||||
|
||||
void registerKeyUpCallback(NSWindowRef window, std::tr1::function<void(unsigned short, unsigned int)> callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerKeyUpCallback:callback];
|
||||
}
|
||||
|
||||
void registerKeyDownCallback(NSWindowRef window, std::tr1::function<void(unsigned short, unsigned int)> callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerKeyDownCallback:callback];
|
||||
}
|
||||
|
||||
void registerUnicodeCallback(NSWindowRef window, std::tr1::function<void(wchar_t, unsigned int)> callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerUnicodeCallback:callback];
|
||||
}
|
||||
|
||||
void registerMouseUpCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerMouseUpCallback:callback];
|
||||
}
|
||||
|
||||
void registerMouseDownCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerMouseDownCallback:callback];
|
||||
}
|
||||
|
||||
void registerRightMouseUpCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerRightMouseUpCallback:callback];
|
||||
}
|
||||
|
||||
void registerRightMouseDownCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerRightMouseDownCallback:callback];
|
||||
}
|
||||
|
||||
void registerDoubleClickCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerDoubleClickCallback:callback];
|
||||
}
|
||||
|
||||
void registerResizeEventCallback(GLViewRef glview, ResizeCallback callback)
|
||||
{
|
||||
[(LLOpenGLView*)glview registerResizeCallback:callback];
|
||||
}
|
||||
|
||||
void registerMouseMovedCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerMouseMovedCallback:callback];
|
||||
}
|
||||
|
||||
void registerScrollCallback(NSWindowRef window, ScrollWheelCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerScrollCallback:callback];
|
||||
}
|
||||
|
||||
void registerMouseExitCallback(NSWindowRef window, VoidCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerMouseExitCallback:callback];
|
||||
}
|
||||
|
||||
void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback)
|
||||
{
|
||||
[(LLNSWindow*)window registerDeltaUpdateCallback:callback];
|
||||
}
|
||||
|
||||
unsigned int getModifiers()
|
||||
{
|
||||
return [NSEvent modifierFlags];
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -29,11 +29,14 @@
|
|||
|
||||
#include "llwindow.h"
|
||||
#include "llwindowcallbacks.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
#include "lltimer.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AGL/agl.h>
|
||||
//#include <Carbon/Carbon.h>
|
||||
//#include <AGL/agl.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
#include "fix_macros.h"
|
||||
|
|
@ -106,7 +109,6 @@ public:
|
|||
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
|
||||
|
||||
/*virtual*/ void *getPlatformWindow();
|
||||
/*virtual*/ void *getMediaWindow();
|
||||
/*virtual*/ void bringToFront() {};
|
||||
|
||||
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
|
||||
|
|
@ -117,6 +119,12 @@ public:
|
|||
|
||||
// Provide native key event data
|
||||
/*virtual*/ LLSD getNativeKeyData();
|
||||
|
||||
void* getWindow() { return mWindow; }
|
||||
LLWindowCallbacks* getCallbacks() { return mCallbacks; }
|
||||
|
||||
void updateMouseDeltas();
|
||||
void getMouseDeltas(float* delta);
|
||||
|
||||
|
||||
protected:
|
||||
|
|
@ -153,40 +161,35 @@ protected:
|
|||
BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync);
|
||||
void destroyContext();
|
||||
void setupFailure(const std::string& text, const std::string& caption, U32 type);
|
||||
static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
|
||||
static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
|
||||
OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
|
||||
void adjustCursorDecouple(bool warpingMouse = false);
|
||||
void stopDockTileBounce();
|
||||
static MASK modifiersToMask(SInt16 modifiers);
|
||||
static MASK modifiersToMask(S16 modifiers);
|
||||
|
||||
#if LL_OS_DRAGDROP_ENABLED
|
||||
/*
|
||||
static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
|
||||
void * handlerRefCon, DragRef theDrag);
|
||||
static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
|
||||
*/
|
||||
#endif // LL_OS_DRAGDROP_ENABLED
|
||||
|
||||
//
|
||||
// Platform specific variables
|
||||
//
|
||||
WindowRef mWindow;
|
||||
AGLContext mContext;
|
||||
AGLPixelFormat mPixelFormat;
|
||||
CGDirectDisplayID mDisplay;
|
||||
CFDictionaryRef mOldDisplayMode;
|
||||
EventLoopTimerRef mTimer;
|
||||
EventHandlerUPP mEventHandlerUPP;
|
||||
EventHandlerRef mGlobalHandlerRef;
|
||||
EventHandlerRef mWindowHandlerRef;
|
||||
EventComparatorUPP mMoveEventCampartorUPP;
|
||||
|
||||
Rect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
|
||||
Rect mPreviousWindowRect; // Save previous window for un-maximize event
|
||||
Str255 mWindowTitle;
|
||||
// Use generic pointers here. This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise.
|
||||
NSWindowRef mWindow;
|
||||
GLViewRef mGLView;
|
||||
CGLContextObj mContext;
|
||||
CGLPixelFormatObj mPixelFormat;
|
||||
CGDirectDisplayID mDisplay;
|
||||
|
||||
LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
|
||||
std::string mWindowTitle;
|
||||
double mOriginalAspectRatio;
|
||||
BOOL mSimulatedRightClick;
|
||||
UInt32 mLastModifiers;
|
||||
U32 mLastModifiers;
|
||||
BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing.
|
||||
// Used to allow event processing when putting up dialogs in fullscreen mode.
|
||||
BOOL mCursorDecoupled;
|
||||
|
|
@ -204,22 +207,17 @@ protected:
|
|||
S32 mDragOverrideCursor;
|
||||
|
||||
F32 mBounceTime;
|
||||
NMRec mBounceRec;
|
||||
//NMRec mBounceRec;
|
||||
LLTimer mBounceTimer;
|
||||
|
||||
// Input method management through Text Service Manager.
|
||||
TSMDocumentID mTSMDocument;
|
||||
BOOL mLanguageTextInputAllowed;
|
||||
ScriptCode mTSMScriptCode;
|
||||
LangCode mTSMLangCode;
|
||||
LLPreeditor* mPreeditor;
|
||||
|
||||
static BOOL sUseMultGL;
|
||||
|
||||
friend class LLWindowManager;
|
||||
static WindowRef sMediaWindow;
|
||||
EventRef mRawKeyEvent;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -653,6 +653,8 @@ BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode)
|
|||
|
||||
BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated)
|
||||
{
|
||||
LL_INFOS("Keyboard Handling") << "Handling key " << translated_key << LL_ENDL;
|
||||
LL_INFOS("Keyboard Handling") << "Keyboard has focus? " << gFocusMgr.getKeyboardFocus() << LL_ENDL;
|
||||
// check for re-map
|
||||
EKeyboardMode mode = gViewerKeyboard.getMode();
|
||||
U32 keyidx = (translated_mask<<16) | translated_key;
|
||||
|
|
|
|||
|
|
@ -2428,6 +2428,7 @@ void LLViewerWindow::draw()
|
|||
// Takes a single keydown event, usually when UI is visible
|
||||
BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
||||
{
|
||||
LL_INFOS("Keyboard Handling") << "Handling key " << key << LL_ENDL;
|
||||
// hide tooltips on keypress
|
||||
LLToolTipMgr::instance().blockToolTips();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue