From c8aa1fb7c8ed44886599ea4e04eed403392e2e34 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Dec 2012 18:00:30 -0500
Subject: LLWindow: Move to using Cocoa for window and view creation along with
 setting up callbacks for event handling as such.

---
 indra/llwindow/CMakeLists.txt         |    2 +
 indra/llwindow/llkeyboardmacosx.cpp   |   33 +-
 indra/llwindow/llkeyboardmacosx.h     |    9 +
 indra/llwindow/llopenglview-objc.h    |   72 +
 indra/llwindow/llopenglview-objc.mm   |  352 +++++
 indra/llwindow/llwindowmacosx-objc.h  |   53 +-
 indra/llwindow/llwindowmacosx-objc.mm |  221 ++-
 indra/llwindow/llwindowmacosx.cpp     | 2632 ++++++---------------------------
 indra/llwindow/llwindowmacosx.h       |   52 +-
 9 files changed, 1214 insertions(+), 2212 deletions(-)
 create mode 100644 indra/llwindow/llopenglview-objc.h
 create mode 100644 indra/llwindow/llopenglview-objc.mm

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 341bddfffd..8a38db751e 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -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.
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 7f8f303517..3f357c600e 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -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;
diff --git a/indra/llwindow/llkeyboardmacosx.h b/indra/llwindow/llkeyboardmacosx.h
index f09ff720ce..6e1f4d3b96 100644
--- a/indra/llwindow/llkeyboardmacosx.h
+++ b/indra/llwindow/llkeyboardmacosx.h
@@ -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:
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
new file mode 100644
index 0000000000..8abe81ce9e
--- /dev/null
+++ b/indra/llwindow/llopenglview-objc.h
@@ -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
\ No newline at end of file
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
new file mode 100644
index 0000000000..a96c4cf82c
--- /dev/null
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -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
\ No newline at end of file
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 7893dedda4..47ae13cb25 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -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();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index bebb537cd8..03c0f55883 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -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];
+}
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 97637c937f..1fb8bea802 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -30,7 +30,6 @@
 
 #include "llkeyboardmacosx.h"
 #include "llwindowcallbacks.h"
-#include "llwindowmacosx-objc.h"
 #include "llpreeditor.h"
 
 #include "llerror.h"
@@ -58,7 +57,6 @@ const S32	MAX_NUM_RESOLUTIONS = 32;
 //
 
 BOOL LLWindowMacOSX::sUseMultGL = FALSE;
-WindowRef LLWindowMacOSX::sMediaWindow = NULL;
 
 // Cross-platform bits:
 
@@ -98,105 +96,9 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card)
 // We may want to base this on the setting of _DEBUG...
 
 #define CAPTURE_ALL_DISPLAYS 0
-static double getDictDouble (CFDictionaryRef refDict, CFStringRef key);
+//static double getDictDouble (CFDictionaryRef refDict, CFStringRef key);
 static long getDictLong (CFDictionaryRef refDict, CFStringRef key);
 
-
-
-
-// CarbonEvents we're interested in.
-static EventTypeSpec WindowHandlerEventList[] =
-{
-	// Window-related events
-	{ kEventClassWindow, kEventWindowActivated },
-	{ kEventClassWindow, kEventWindowDeactivated },
-	{ kEventClassWindow, kEventWindowShown },
-	{ kEventClassWindow, kEventWindowHidden },
-	{ kEventClassWindow, kEventWindowCollapsed },
-	{ kEventClassWindow, kEventWindowExpanded },
-	{ kEventClassWindow, kEventWindowGetClickActivation },
-	{ kEventClassWindow, kEventWindowClose },
-	{ kEventClassWindow, kEventWindowBoundsChanging },
-	{ kEventClassWindow, kEventWindowBoundsChanged },
-	{ kEventClassWindow, kEventWindowGetIdealSize },
-
-	// Mouse events
-	{ kEventClassMouse, kEventMouseDown },
-	{ kEventClassMouse, kEventMouseUp },
-	{ kEventClassMouse, kEventMouseDragged },
-	{ kEventClassMouse, kEventMouseWheelMoved },
-	{ kEventClassMouse, kEventMouseMoved },
-
-	// Keyboard events
-	// No longer handle raw key down events directly.
-	// When text input events come in, extract the raw key events from them and process at that point.
-	// This allows input methods to eat keystrokes the way they're supposed to.
-//	{ kEventClassKeyboard, kEventRawKeyDown },
-//	{ kEventClassKeyboard, kEventRawKeyRepeat },
-	{ kEventClassKeyboard, kEventRawKeyUp },
-	{ kEventClassKeyboard, kEventRawKeyModifiersChanged },
-
-	// Text input events
-	{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
-	{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
-	{ kEventClassTextInput, kEventTextInputOffsetToPos },
-	{ kEventClassTextInput, kEventTextInputPosToOffset },
-	{ kEventClassTextInput, kEventTextInputShowHideBottomWindow },
-	{ kEventClassTextInput, kEventTextInputGetSelectedText },
-	{ kEventClassTextInput, kEventTextInputFilterText },
-
-	// TSM Document Access events (advanced input method support)
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument }
-};
-
-static EventTypeSpec GlobalHandlerEventList[] =
-{
-	// Mouse events
-	{ kEventClassMouse, kEventMouseDown },
-	{ kEventClassMouse, kEventMouseUp },
-	{ kEventClassMouse, kEventMouseDragged },
-	{ kEventClassMouse, kEventMouseWheelMoved },
-	{ kEventClassMouse, kEventMouseMoved },
-
-	// Keyboard events
-	// No longer handle raw key down events directly.
-	// When text input events come in, extract the raw key events from them and process at that point.
-	// This allows input methods to eat keystrokes the way they're supposed to.
-//	{ kEventClassKeyboard, kEventRawKeyDown },
-//	{ kEventClassKeyboard, kEventRawKeyRepeat },
-	{ kEventClassKeyboard, kEventRawKeyUp },
-	{ kEventClassKeyboard, kEventRawKeyModifiersChanged },
-
-	// Text input events
-	{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
-	{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
-	{ kEventClassTextInput, kEventTextInputOffsetToPos },
-	{ kEventClassTextInput, kEventTextInputPosToOffset },
-	{ kEventClassTextInput, kEventTextInputShowHideBottomWindow },
-	{ kEventClassTextInput, kEventTextInputGetSelectedText },
-	{ kEventClassTextInput, kEventTextInputFilterText },
-
-	// TSM Document Access events (advanced input method support)
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument },
-	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument }
-};
-
-static EventTypeSpec CommandHandlerEventList[] =
-{
-	{ kEventClassCommand, kEventCommandProcess }
-};
-
 // MBW -- HACK ALERT
 // On the Mac, to put up an OS dialog in full screen mode, we must first switch OUT of full screen mode.
 // The proper way to do this is to bracket the dialog with calls to beforeDialog() and afterDialog(), but these
@@ -204,8 +106,6 @@ static EventTypeSpec CommandHandlerEventList[] =
 // This assumes that there will be only one object of this class at any time.  Hopefully this is true.
 static LLWindowMacOSX *gWindowImplementation = NULL;
 
-
-
 LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 							   const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
 							   S32 height, U32 flags,
@@ -233,8 +133,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	mContext = NULL;
 	mPixelFormat = NULL;
 	mDisplay = CGMainDisplayID();
-	mOldDisplayMode = NULL;
-	mTimer = NULL;
 	mSimulatedRightClick = FALSE;
 	mLastModifiers = 0;
 	mHandsOffEvents = FALSE;
@@ -246,12 +144,8 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	mOverrideAspectRatio = 0.f;
 	mMaximized = FALSE;
 	mMinimized = FALSE;
-	mTSMDocument = NULL; // Just in case.
 	mLanguageTextInputAllowed = FALSE;
-	mTSMScriptCode = 0;
-	mTSMLangCode = 0;
 	mPreeditor = NULL;
-	mRawKeyEvent = NULL;
 	mFSAASamples = fsaa_samples;
 	mForceRebuild = FALSE;
 
@@ -263,43 +157,23 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay);
 
 	// Stash the window title
-	strcpy((char*)mWindowTitle + 1, title.c_str()); /* Flawfinder: ignore */
-	mWindowTitle[0] = title.length();
-
-	mEventHandlerUPP = NewEventHandlerUPP(staticEventHandler);
-	mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator);
-	mGlobalHandlerRef = NULL;
-	mWindowHandlerRef = NULL;
+	mWindowTitle = title;
+	//mWindowTitle[0] = title.length();
 
 	mDragOverrideCursor = -1;
 
-	// We're not clipping yet
-	SetRect( &mOldMouseClip, 0, 0, 0, 0 );
-
 	// Set up global event handlers (the fullscreen case needs this)
-	InstallStandardEventHandler(GetApplicationEventTarget());
+	//InstallStandardEventHandler(GetApplicationEventTarget());
 
 	// Stash an object pointer for OSMessageBox()
 	gWindowImplementation = this;
-
 	// Create the GL context and set it up for windowed or fullscreen, as appropriate.
+	LL_INFOS("Window") << "Creating context..." << LL_ENDL;
 	if(createContext(x, y, width, height, 32, fullscreen, disable_vsync))
 	{
 		if(mWindow != NULL)
 		{
-			// MBW -- XXX -- I think we can now do this here?
-			// Constrain the window to the screen it's mostly on, resizing if necessary.
-			ConstrainWindowToScreen(
-				mWindow,
-				kWindowStructureRgn,
-				kWindowConstrainMayResize |
-				//				kWindowConstrainStandardOptions |
-				0,
-				NULL,
-				NULL);
-
-			MacShowWindow(mWindow);
-			BringToFront(mWindow);
+			makeWindowOrderFront(mWindow);
 		}
 
 		if (!gGLManager.initGL())
@@ -321,463 +195,193 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 
 	mCallbacks = callbacks;
 	stop_glerror();
+	
+	
 }
 
-BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync)
-{
-	OSStatus		err;
-	BOOL			glNeedsInit = FALSE;
-
-	if(mGlobalHandlerRef == NULL)
-	{
-		InstallApplicationEventHandler(mEventHandlerUPP, GetEventTypeCount (CommandHandlerEventList), CommandHandlerEventList, (void*)this, &mGlobalHandlerRef);
-	}
-
-	mFullscreen = fullscreen;
-
-	if (mFullscreen && (mOldDisplayMode == NULL))
-	{
-		LL_INFOS("Window") << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL;
-
-		// NOTE: The refresh rate will be REPORTED AS 0 for many DVI and notebook displays.  Plan accordingly.
-		double refresh = getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate);
+// These functions are used as callbacks for event handling within Cocoa.
+// It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow.
 
-		// If the requested width or height is 0, find the best default for the monitor.
-		if((width == 0) || (height == 0))
-		{
-			// Scan through the list of modes, looking for one which has:
-			//		height between 700 and 800
-			//		aspect ratio closest to the user's original mode
-			S32 resolutionCount = 0;
-			LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount);
+void callKeyUp(unsigned short key, unsigned int mask)
+{
+	gKeyboard->handleKeyUp(key, mask);
+}
 
-			if(resolutionList != NULL)
-			{
-				F32 closestAspect = 0;
-				U32 closestHeight = 0;
-				U32 closestWidth = 0;
-				int i;
+void callKeyDown(unsigned short key, unsigned int mask)
+{
+	gKeyboard->handleKeyDown(key, mask);
+}
 
-				LL_DEBUGS("Window") << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL;
+void callUnicodeCallback(wchar_t character, unsigned int mask)
+{
+	gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
+}
 
-				for(i=0; i < resolutionCount; i++)
-				{
-					F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight;
+void callModifierCallback(unsigned int mask)
+{
+	
+}
 
-					LL_DEBUGS("Window") << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL;
+void callRightMouseDown(float *pos, MASK mask)
+{
+	LLCoordGL		outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	gWindowImplementation->getCallbacks()->handleRightMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
 
-					if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) &&
-						(fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio)))
-					{
-						LL_DEBUGS("Window") << " (new closest mode) " << LL_ENDL;
+void callRightMouseUp(float *pos, MASK mask)
+{
+	LLCoordGL		outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	gWindowImplementation->getCallbacks()->handleRightMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
 
-						// This is the closest mode we've seen yet.
-						closestWidth = resolutionList[i].mWidth;
-						closestHeight = resolutionList[i].mHeight;
-						closestAspect = aspect;
-					}
-				}
+void callLeftMouseDown(float *pos, MASK mask)
+{
+	LLCoordGL		outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+	LL_INFOS("Window") << outCoords.mX << ", " << outCoords.mY << LL_ENDL;
+}
 
-				width = closestWidth;
-				height = closestHeight;
-			}
-		}
+void callLeftMouseUp(float *pos, MASK mask)
+{
+	LLCoordGL		outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	gWindowImplementation->getCallbacks()->handleMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+	
+}
 
-		if((width == 0) || (height == 0))
-		{
-			// Mode search failed for some reason.  Use the old-school default.
-			width = 1024;
-			height = 768;
-		}
+void callDoubleClick(float *pos, MASK mask)
+{
+	LLCoordGL	outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	gWindowImplementation->getCallbacks()->handleDoubleClick(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
 
-		if (true)
-		{
-			// Fullscreen support
-			CFDictionaryRef refDisplayMode = 0;
-			boolean_t exactMatch = false;
-
-#if CAPTURE_ALL_DISPLAYS
-			// Capture all displays (may want to do this for final build)
-			CGCaptureAllDisplays ();
-#else
-			// Capture only the main display (useful for debugging)
-			CGDisplayCapture (mDisplay);
-#endif
+void callResize(unsigned int width, unsigned int height)
+{
+	gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height);
+}
 
-			// Switch the display to the desired resolution and refresh
-			refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
-				mDisplay,
-				BITS_PER_PIXEL,
-				width,
-				height,
-				refresh,
-				&exactMatch);
+void callMouseMoved(float *pos, MASK mask)
+{
+	LLCoordGL		outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	float deltas[2];
+	gWindowImplementation->getMouseDeltas(deltas);
+	outCoords.mX += deltas[0];
+	outCoords.mY += deltas[1];
+	gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
 
-			if (refDisplayMode)
-			{
-				LL_DEBUGS("Window") << "createContext: switching display resolution" << LL_ENDL;
-				mOldDisplayMode = CGDisplayCurrentMode (mDisplay);
-				CGDisplaySwitchToMode (mDisplay, refDisplayMode);
-				//				CFRelease(refDisplayMode);
+void callScrollMoved(float delta)
+{
+	gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
+}
 
-				AddEventTypesToHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList);
-			}
+void callMouseExit()
+{
+	gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation);
+}
 
+void callWindowFocus()
+{
+	gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
+}
 
-			mFullscreen = TRUE;
-			mFullscreenWidth   = CGDisplayPixelsWide(mDisplay);
-			mFullscreenHeight  = CGDisplayPixelsHigh(mDisplay);
-			mFullscreenBits    = CGDisplayBitsPerPixel(mDisplay);
-			mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate));
+void callWindowUnfocus()
+{
+	gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+}
 
-			LL_INFOS("Window") << "Running at " << mFullscreenWidth
-				<< "x"   << mFullscreenHeight
-				<< "x"   << mFullscreenBits
-				<< " @ " << mFullscreenRefresh
-				<< LL_ENDL;
-		}
-		else
-		{
-			// No fullscreen support
-			mFullscreen = FALSE;
-			mFullscreenWidth   = -1;
-			mFullscreenHeight  = -1;
-			mFullscreenBits    = -1;
-			mFullscreenRefresh = -1;
-
-			std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
-			OSMessageBox(error, "Error", OSMB_OK);
-		}
-	}
+void callDeltaUpdate(float *delta, MASK mask)
+{
+	gWindowImplementation->updateMouseDeltas();
+}
 
-	if(!mFullscreen && (mWindow == NULL))
+void LLWindowMacOSX::updateMouseDeltas()
+{
+	if (mCursorDecoupled)
 	{
-		//int				displayWidth = CGDisplayPixelsWide(mDisplay);
-		//int				displayHeight = CGDisplayPixelsHigh(mDisplay);
-		//const int		menuBarPlusTitleBar = 44;   // Ugly magic number.
-
-		LL_DEBUGS("Window") << "createContext: creating window" << LL_ENDL;
-
-		mPreviousWindowRect.left = (long) x;
-		mPreviousWindowRect.right = (long) x + width;
-		mPreviousWindowRect.top = (long) y;
-		mPreviousWindowRect.bottom = (long) y + height;
-
-		//-----------------------------------------------------------------------
-		// Create the window
-		//-----------------------------------------------------------------------
-		mWindow = NewCWindow(
-			NULL,
-			&mPreviousWindowRect,
-			mWindowTitle,
-			false,				// Create the window invisible.  Whoever calls createContext() should show it after any moving/resizing.
-			//		noGrowDocProc,		// Window with no grow box and no zoom box
-			zoomDocProc,		// Window with a grow box and a zoom box
-			//		zoomNoGrow,			// Window with a zoom box but no grow box
-			kFirstWindowOfClass,
-			true,
-			(long)this);
-
-		if (!mWindow)
+		CGMouseDelta x, y;
+		CGGetLastMouseDelta( &x, &y );
+		mCursorLastEventDeltaX = x;
+		mCursorLastEventDeltaY = y;
+		
+		if (mCursorIgnoreNextDelta)
 		{
-			setupFailure("Window creation error", "Error", OSMB_OK);
-			return FALSE;
+			mCursorLastEventDeltaX = 0;
+			mCursorLastEventDeltaY = 0;
+			mCursorIgnoreNextDelta = FALSE;
 		}
+	} else {
+		mCursorLastEventDeltaX = 0;
+		mCursorLastEventDeltaY = 0;
+	}
+}
 
-		// Turn on live resize.
-		// For this to work correctly, we need to be able to call LLViewerWindow::draw from
-		// the event handler for kEventWindowBoundsChanged.  It's not clear that we have access from here.
-		//	err = ChangeWindowAttributes(mWindow, kWindowLiveResizeAttribute, 0);
+void LLWindowMacOSX::getMouseDeltas(float* delta)
+{
+	delta[0] = mCursorLastEventDeltaX;
+	delta[1] = mCursorLastEventDeltaY;
+}
 
-		// Set up window event handlers (some window-related events ONLY go to window handlers.)
-		InstallStandardEventHandler(GetWindowEventTarget(mWindow));
-		InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler
-#if LL_OS_DRAGDROP_ENABLED
-		InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this );
-		InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this );
-#endif // LL_OS_DRAGDROP_ENABLED
-	}
+BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync)
+{
+	BOOL			glNeedsInit = FALSE;
 
-	{
-		// Create and initialize our TSM document for language text input.
-		// If an error occured, we can do nothing better than simply ignore it.
-		// mTSMDocument will be kept NULL in case.
-		if (mTSMDocument)
-		{
-			DeactivateTSMDocument(mTSMDocument);
-			DeleteTSMDocument(mTSMDocument);
-			mTSMDocument = NULL;
-		}
-		static InterfaceTypeList types = { kUnicodeDocument };
-		err = NewTSMDocument(1, types, &mTSMDocument, 0);
-		if (err != noErr)
-		{
-			LL_WARNS("Window") << "createContext: couldn't create a TSMDocument (" << err << ")" << LL_ENDL;
-		}
-		if (mTSMDocument)
-		{
-			ActivateTSMDocument(mTSMDocument);
-			allowLanguageTextInput(NULL, FALSE);
-		}
+	mFullscreen = fullscreen;
+	
+	if (mWindow == NULL)
+	{
+		LL_INFOS("Window") << "Creating window..." << LL_ENDL;
+		mWindow = createNSWindow(x, y, width, height);
+		LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL;
+		registerKeyDownCallback(mWindow, callKeyDown);
+		registerKeyUpCallback(mWindow, callKeyUp);
+		registerUnicodeCallback(mWindow, callUnicodeCallback);
+		registerMouseDownCallback(mWindow, callLeftMouseDown);
+		registerMouseUpCallback(mWindow, callLeftMouseUp);
+		registerRightMouseDownCallback(mWindow, callRightMouseDown);
+		registerRightMouseUpCallback(mWindow, callRightMouseUp);
+		registerDoubleClickCallback(mWindow, callDoubleClick);
+		registerMouseMovedCallback(mWindow, callMouseMoved);
+		registerScrollCallback(mWindow, callScrollMoved);
+		registerDeltaUpdateCallback(mWindow, callDeltaUpdate);
+		registerMouseExitCallback(mWindow, callMouseExit);
 	}
 
 	if(mContext == NULL)
 	{
-		AGLRendererInfo rendererInfo = NULL;
-
-		//-----------------------------------------------------------------------
-		// Create GL drawing context
-		//-----------------------------------------------------------------------
-
-		if(mPixelFormat == NULL)
-		{
-			if(mFullscreen)
-			{
-				GLint fullscreenAttrib[] =
-				{
-					AGL_RGBA,
-					AGL_FULLSCREEN,
-					AGL_NO_RECOVERY,
-					AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
-					AGL_SAMPLES_ARB, mFSAASamples,
-					AGL_DOUBLEBUFFER,
-					AGL_CLOSEST_POLICY,
-					AGL_ACCELERATED,
-					AGL_RED_SIZE, 8,
-					AGL_GREEN_SIZE, 8,
-					AGL_BLUE_SIZE, 8,
-					AGL_ALPHA_SIZE, 8,
-					AGL_DEPTH_SIZE, 24,
-					AGL_STENCIL_SIZE, 8,
-					AGL_NONE
-				};
-
-				LL_DEBUGS("Window") << "createContext: creating fullscreen pixelformat" << LL_ENDL;
-
-				GDHandle gdhDisplay = NULL;
-				err = DMGetGDeviceByDisplayID ((DisplayIDType)mDisplay, &gdhDisplay, false);
-
-				mPixelFormat = aglChoosePixelFormat(&gdhDisplay, 1, fullscreenAttrib);
-				rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1);
-			}
-			else
-			{
-				// NOTE from Leslie:
-				//
-				// AGL_NO_RECOVERY, when combined with AGL_ACCELERATED prevents software rendering
-				// fallback which means we won't hvae shaders that compile and link but then don't
-				// work.  The drawback is that our shader compilation will be a bit more finicky though.
-
-				GLint windowedAttrib[] =
-				{
-					AGL_RGBA,
-					AGL_NO_RECOVERY,
-					AGL_DOUBLEBUFFER,
-					AGL_CLOSEST_POLICY,
-					AGL_ACCELERATED,
-					AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
-					AGL_SAMPLES_ARB, mFSAASamples,
-					AGL_RED_SIZE, 8,
-					AGL_GREEN_SIZE, 8,
-					AGL_BLUE_SIZE, 8,
-					AGL_ALPHA_SIZE, 8,
-					AGL_DEPTH_SIZE, 24,
-					AGL_STENCIL_SIZE, 8,
-					AGL_NONE
-				};
-
-				LL_DEBUGS("Window") << "createContext: creating windowed pixelformat" << LL_ENDL;
-
-				mPixelFormat = aglChoosePixelFormat(NULL, 0, windowedAttrib);
-
-				GDHandle gdhDisplay = GetMainDevice();
-				rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1);
-			}
-
-			// May want to get the real error text like this:
-			// (char *) aglErrorString(aglGetError());
-
-			if(aglGetError() != AGL_NO_ERROR)
-			{
-				setupFailure("Can't find suitable pixel format", "Error", OSMB_OK);
-				return FALSE;
-			}
-		}
-
-		if(mPixelFormat)
-		{
-			LL_DEBUGS("Window") << "createContext: creating GL context" << LL_ENDL;
-			mContext = aglCreateContext(mPixelFormat, NULL);
-		}
-
-		if(mContext == NULL)
-		{
-			setupFailure("Can't make GL context", "Error", OSMB_OK);
-			return FALSE;
-		}
-
-		gGLManager.mVRAM = 0;
-
-		if(rendererInfo != NULL)
-		{
-			GLint result;
-
-			if(aglDescribeRenderer(rendererInfo, AGL_VIDEO_MEMORY, &result))
-			{
-				//				llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) returned " << result << llendl;
-				gGLManager.mVRAM = result / (1024 * 1024);
-			}
-			else
-			{
-				//				llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) failed." << llendl;
-			}
-
-			// This could be useful at some point, if it takes into account the memory already used by screen buffers, etc...
-			if(aglDescribeRenderer(rendererInfo, AGL_TEXTURE_MEMORY, &result))
-			{
-				//				llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) returned " << result << llendl;
-			}
-			else
-			{
-				//				llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) failed." << llendl;
-			}
-
-			aglDestroyRendererInfo(rendererInfo);
-		}
-
+		LL_INFOS("Window") << "Creating GL view..." << LL_ENDL;
+		mGLView = createOpenGLView(mWindow);
+		registerResizeEventCallback(mGLView, callResize);
+		mContext = getCGLContextObj(mWindow);
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
 	}
 
 	// Hook up the context to a drawable
-	if (mFullscreen && (mOldDisplayMode != NULL))
-	{
-		// We successfully captured the display.  Use a fullscreen drawable
-
-		LL_DEBUGS("Window") << "createContext: attaching fullscreen drawable" << LL_ENDL;
-
-#if CAPTURE_ALL_DISPLAYS
-		// Capture all displays (may want to do this for final build)
-		aglDisable (mContext, AGL_FS_CAPTURE_SINGLE);
-#else
-		// Capture only the main display (useful for debugging)
-		aglEnable (mContext, AGL_FS_CAPTURE_SINGLE);
-#endif
-
-		if (!aglSetFullScreen (mContext, 0, 0, 0, 0))
-		{
-			setupFailure("Can't set GL fullscreen", "Error", OSMB_OK);
-			return FALSE;
-		}
-	}
-	else if(!mFullscreen && (mWindow != NULL))
-	{
-		LL_DEBUGS("Window") << "createContext: attaching windowed drawable" << LL_ENDL;
-
-		// We created a window.  Use it as the drawable.
-		if(!aglSetDrawable(mContext, GetWindowPort (mWindow)))
-		{
-			setupFailure("Can't set GL drawable", "Error", OSMB_OK);
-			return FALSE;
-		}
-	}
-	else
-	{
-		setupFailure("Can't get fullscreen or windowed drawable.", "Error", OSMB_OK);
-		return FALSE;
-	}
 
 	if(mContext != NULL)
 	{
+		LL_INFOS("Window") << "Setting CGL Context..." << LL_ENDL;
 		LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL;
-
-		if (!aglSetCurrentContext(mContext))
+		U32 err = CGLSetCurrentContext(mContext);
+		if (err != kCGLNoError)
 		{
 			setupFailure("Can't activate GL rendering context", "Error", OSMB_OK);
 			return FALSE;
 		}
 	}
 
-	if(glNeedsInit)
-	{
-		// Check for some explicitly unsupported cards.
-		const char* RENDERER = (const char*) glGetString(GL_RENDERER);
-
-		const char* CARD_LIST[] =
-		{	"RAGE 128",
-		"RIVA TNT2",
-		"Intel 810",
-		"3Dfx/Voodoo3",
-		"Radeon 7000",
-		"Radeon 7200",
-		"Radeon 7500",
-		"Radeon DDR",
-		"Radeon VE",
-		"GDI Generic" };
-		const S32 CARD_COUNT = LL_ARRAY_SIZE(CARD_LIST);
-
-		// Future candidates:
-		// ProSavage/Twister
-		// SuperSavage
-
-		S32 i;
-		for (i = 0; i < CARD_COUNT; i++)
-		{
-			if (check_for_card(RENDERER, CARD_LIST[i]))
-			{
-				close();
-				return FALSE;
-			}
-		}
-	}
-
-	GLint colorBits, alphaBits, depthBits, stencilBits;
-
-	if(	!aglDescribePixelFormat(mPixelFormat, AGL_BUFFER_SIZE, &colorBits) ||
-		!aglDescribePixelFormat(mPixelFormat, AGL_ALPHA_SIZE, &alphaBits) ||
-		!aglDescribePixelFormat(mPixelFormat, AGL_DEPTH_SIZE, &depthBits) ||
-		!aglDescribePixelFormat(mPixelFormat, AGL_STENCIL_SIZE, &stencilBits))
-	{
-		close();
-		setupFailure("Can't get pixel format description", "Error", OSMB_OK);
-		return FALSE;
-	}
-
-	LL_INFOS("GLInit") << "GL buffer: Color Bits " << S32(colorBits)
-		<< " Alpha Bits " << S32(alphaBits)
-		<< " Depth Bits " << S32(depthBits)
-		<< " Stencil Bits" << S32(stencilBits)
-		<< LL_ENDL;
-
-	if (colorBits < 32)
-	{
-		close();
-		setupFailure(
-			"Second Life requires True Color (32-bit) to run in a window.\n"
-			"Please go to Control Panels -> Display -> Settings and\n"
-			"set the screen to 32-bit color.\n"
-			"Alternately, if you choose to run fullscreen, Second Life\n"
-			"will automatically adjust the screen each time it runs.",
-			"Error",
-			OSMB_OK);
-		return FALSE;
-	}
-
-	if (alphaBits < 8)
-	{
-		close();
-		setupFailure(
-			"Second Life is unable to run because it can't get an 8 bit alpha\n"
-			"channel.  Usually this is due to video card driver issues.\n"
-			"Please make sure you have the latest video card drivers installed.\n"
-			"Also be sure your monitor is set to True Color (32-bit) in\n"
-			"Control Panels -> Display -> Settings.\n"
-			"If you continue to receive this message, contact customer service.",
-			"Error",
-			OSMB_OK);
-		return FALSE;
-	}
-
 	// Disable vertical sync for swap
 	GLint frames_per_swap = 0;
 	if (disable_vsync)
@@ -790,7 +394,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL;
 		frames_per_swap = 1;
 	}
-	aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap);
+	
+	CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap);
 
 	//enable multi-threaded OpenGL
 	if (sUseMultGL)
@@ -809,109 +414,17 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 			LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
 		}
 	}
-
+	LL_INFOS("Window") << "Completed context creation." << LL_ENDL;
 	// Don't need to get the current gamma, since there's a call that restores it to the system defaults.
 	return TRUE;
 }
 
 
-// changing fullscreen resolution, or switching between windowed and fullscreen mode.
+// We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop.
+// This makes this method obsolete.
 BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
 {
-	BOOL needsRebuild = FALSE;
-	BOOL result = true;
-
-	if(fullscreen)
-	{
-		if(mFullscreen)
-		{
-			// Switching resolutions in fullscreen mode.  Don't need to rebuild for this.
-			// Fullscreen support
-			CFDictionaryRef refDisplayMode = 0;
-			boolean_t exactMatch = false;
-
-			// Switch the display to the desired resolution and refresh
-			refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
-				mDisplay,
-				BITS_PER_PIXEL,
-				size.mX,
-				size.mY,
-				getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate),
-				&exactMatch);
-
-			if (refDisplayMode)
-			{
-				CGDisplaySwitchToMode (mDisplay, refDisplayMode);
-				//				CFRelease(refDisplayMode);
-			}
-
-			mFullscreenWidth   = CGDisplayPixelsWide(mDisplay);
-			mFullscreenHeight  = CGDisplayPixelsHigh(mDisplay);
-			mFullscreenBits    = CGDisplayBitsPerPixel(mDisplay);
-			mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate));
-
-			LL_INFOS("Window") << "Switched resolution to " << mFullscreenWidth
-				<< "x"   << mFullscreenHeight
-				<< "x"   << mFullscreenBits
-				<< " @ " << mFullscreenRefresh
-				<< LL_ENDL;
-
-			// Update the GL context to the new screen size
-			if (!aglUpdateContext(mContext))
-			{
-				setupFailure("Can't set GL fullscreen", "Error", OSMB_OK);
-				result = FALSE;
-			}
-		}
-		else
-		{
-			// Switching from windowed to fullscreen
-			needsRebuild = TRUE;
-		}
-	}
-	else
-	{
-		if(mFullscreen)
-		{
-			// Switching from fullscreen to windowed
-			needsRebuild = TRUE;
-		}
-		else
-		{
-			// Windowed to windowed -- not sure why we would be called like this.  Just change the window size.
-			// The bounds changed event handler will do the rest.
-			if(mWindow != NULL)
-			{
-				::SizeWindow(mWindow, size.mX, size.mY, true);
-			}
-		}
-	}
-
-	stop_glerror();
-	if(needsRebuild || mForceRebuild)
-	{
-		mForceRebuild = FALSE;
-		destroyContext();
-		result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync);
-		if (result)
-		{
-			if(mWindow != NULL)
-			{
-				MacShowWindow(mWindow);
-				BringToFront(mWindow);
-			}
-
-			llverify(gGLManager.initGL());
-
-			//start with arrow cursor
-			initCursors();
-			setCursor( UI_CURSOR_ARROW );
-		}
-	}
-
-	stop_glerror();
-
-	return result;
+	return FALSE;
 }
 
 void LLWindowMacOSX::destroyContext()
@@ -926,31 +439,8 @@ void LLWindowMacOSX::destroyContext()
 	{
 		LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL;
 
-		aglSetCurrentContext (NULL);
-		aglSetDrawable(mContext, NULL);
-	}
-
-	// Make sure the display resolution gets restored
-	if(mOldDisplayMode != NULL)
-	{
-		LL_DEBUGS("Window") << "destroyContext: restoring display resolution " << LL_ENDL;
-
-		CGDisplaySwitchToMode (mDisplay, mOldDisplayMode);
-
-#if CAPTURE_ALL_DISPLAYS
-		// Uncapture all displays (may want to do this for final build)
-		CGReleaseAllDisplays ();
-#else
-		// Uncapture only the main display (useful for debugging)
-		CGDisplayRelease (mDisplay);
-#endif
-
-		//		CFRelease(mOldDisplayMode);
-
-		mOldDisplayMode = NULL;
-
-		// Remove the global event handlers the fullscreen case needed
-		RemoveEventTypesFromHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList);
+		CGLSetCurrentContext(NULL);
+		mContext = NULL;
 	}
 
 	// Clean up remaining GL state before blowing away window
@@ -959,49 +449,19 @@ void LLWindowMacOSX::destroyContext()
 	// Clean up the pixel format
 	if(mPixelFormat != NULL)
 	{
-		LL_DEBUGS("Window") << "destroyContext: destroying pixel format " << LL_ENDL;
-		aglDestroyPixelFormat(mPixelFormat);
+		CGLDestroyPixelFormat(mPixelFormat);
 		mPixelFormat = NULL;
 	}
 
-	// Remove any Carbon Event handlers we installed
-	if(mGlobalHandlerRef != NULL)
-	{
-		LL_DEBUGS("Window") << "destroyContext: removing global event handler" << LL_ENDL;
-		RemoveEventHandler(mGlobalHandlerRef);
-		mGlobalHandlerRef = NULL;
-	}
-
-	if(mWindowHandlerRef != NULL)
-	{
-		LL_DEBUGS("Window") << "destroyContext: removing window event handler" << LL_ENDL;
-		RemoveEventHandler(mWindowHandlerRef);
-		mWindowHandlerRef = NULL;
-	}
-
-	// Cleanup any TSM document we created.
-	if(mTSMDocument != NULL)
-	{
-		LL_DEBUGS("Window") << "destroyContext: deleting TSM document" << LL_ENDL;
-		DeactivateTSMDocument(mTSMDocument);
-		DeleteTSMDocument(mTSMDocument);
-		mTSMDocument = NULL;
-	}
-
 	// Close the window
 	if(mWindow != NULL)
 	{
-		LL_DEBUGS("Window") << "destroyContext: disposing window" << LL_ENDL;
-		DisposeWindow(mWindow);
-		mWindow = NULL;
 	}
 
 	// Clean up the GL context
 	if(mContext != NULL)
 	{
-		LL_DEBUGS("Window") << "destroyContext: destroying GL context" << LL_ENDL;
-		aglDestroyContext(mContext);
-		mContext = NULL;
+		CGLDestroyContext(mContext);
 	}
 
 }
@@ -1022,17 +482,11 @@ LLWindowMacOSX::~LLWindowMacOSX()
 
 void LLWindowMacOSX::show()
 {
-	if(IsWindowCollapsed(mWindow))
-		CollapseWindow(mWindow, false);
-
-	MacShowWindow(mWindow);
-	BringToFront(mWindow);
 }
 
 void LLWindowMacOSX::hide()
 {
 	setMouseClipping(FALSE);
-	HideWindow(mWindow);
 }
 
 //virtual
@@ -1040,7 +494,6 @@ void LLWindowMacOSX::minimize()
 {
 	setMouseClipping(FALSE);
 	showCursor();
-	CollapseWindow(mWindow, true);
 }
 
 //virtual
@@ -1086,7 +539,6 @@ BOOL LLWindowMacOSX::getVisible()
 		result = TRUE;
 	}if (mWindow)
 	{
-		if(MacIsWindowVisible(mWindow))
 			result = TRUE;
 	}
 
@@ -1107,7 +559,6 @@ BOOL LLWindowMacOSX::maximize()
 {
 	if (mWindow && !mMaximized)
 	{
-		ZoomWindow(mWindow, inContent, true);
 	}
 
 	return mMaximized;
@@ -1125,17 +576,14 @@ void LLWindowMacOSX::gatherInput()
 	{
 		stopDockTileBounce();
 	}
-
-	// Use the old-school version so we get AppleEvent handler dispatch and menuselect handling.
-	// Anything that has an event handler will get processed inside WaitNextEvent, so we only need to handle
-	// the odd stuff here.
+	
 	EventRecord evt;
 	while(WaitNextEvent(everyEvent, &evt, 0, NULL))
 	{
 		//			printf("WaitNextEvent returned true, event is %d.\n", evt.what);
 		switch(evt.what)
 		{
-		case mouseDown:
+			case mouseDown:
 			{
 				short part;
 				WindowRef window;
@@ -1143,35 +591,125 @@ void LLWindowMacOSX::gatherInput()
 				part = FindWindow(evt.where, &window);
 				switch ( part )
 				{
-				case inMenuBar:
-					selectResult = MenuSelect(evt.where);
-
-					HiliteMenu(0);
-					break;
+					case inMenuBar:
+						selectResult = MenuSelect(evt.where);
+						
+						HiliteMenu(0);
+						break;
 				}
 			}
-			break;
-
-		case kHighLevelEvent:
-			AEProcessAppleEvent (&evt);
-			break;
-
-		case updateEvt:
-			// We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly...
-			BeginUpdate((WindowRef)evt.message);
-			EndUpdate((WindowRef)evt.message);
-			break;
-
+				break;
+				
+			case kHighLevelEvent:
+				AEProcessAppleEvent (&evt);
+				break;
+				
+			case updateEvt:
+				// We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly...
+				BeginUpdate((WindowRef)evt.message);
+				EndUpdate((WindowRef)evt.message);
+				break;
+				
 		}
 	}
+	/*
+	U32 event = getLatestEvent(mWindow);
+	switch (event) {
+		case 0:
+			// Nothing's happened since our last handled event.
+			break;
+			
+		case 1:
+		{
+			gKeyboard->handleKeyDown(getKeyDown(mWindow), getModifiers(mWindow));
+			mCallbacks->handleUnicodeChar(getLastCharacter(mWindow), gKeyboard->currentMask(FALSE)); // currentMask has the appropriately translated modifiers.
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+		}
+			break;
+			
+		case 2:
+			gKeyboard->handleKeyUp(getKeyUp(mWindow), getModifiers(mWindow));
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+			break;
+			
+		case 3:
+			break;
+			
+		case 4:
+		{
+			LLCoordScreen	inCoords;
+			LLCoordGL		outCoords;
+			float*			mouseCoords = getMouseDown(mWindow);
+			inCoords.mX = llround(mouseCoords[0]);
+			inCoords.mY = llround(mouseCoords[1]);
+			convertCoords(inCoords, &outCoords);
+			mCallbacks->handleMouseDown(this, outCoords, getModifiers(mWindow));
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+		}
+			break;
+		case 5:
+		{
+			LLCoordScreen	inCoords;
+			LLCoordGL		outCoords;
+			float*			mouseCoords = getMouseUp(mWindow);
+			inCoords.mX = llround(mouseCoords[0]);
+			inCoords.mY = llround(mouseCoords[1]);
+			convertCoords(inCoords, &outCoords);
+			mCallbacks->handleMouseUp(this, outCoords, getModifiers(mWindow));
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+		}
+			break;
+		case 6:
+		{
+			LLCoordScreen	inCoords;
+			LLCoordGL		outCoords;
+			float*			mouseCoords = getRightMouseDown(mWindow);
+			inCoords.mX = llround(mouseCoords[0]);
+			inCoords.mY = llround(mouseCoords[1]);
+			convertCoords(inCoords, &outCoords);
+			mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow));
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+		}
+			break;
+		case 7:
+		{
+			LLCoordScreen	inCoords;
+			LLCoordGL		outCoords;
+			float*			mouseCoords = getRightMouseDown(mWindow);
+			inCoords.mX = llround(mouseCoords[0]);
+			inCoords.mY = llround(mouseCoords[1]);
+			convertCoords(inCoords, &outCoords);
+			mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow));
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+		}
+			break;
+		case 8: // Double click
+		{
+			LLCoordScreen	inCoords;
+			LLCoordGL		outCoords;
+			float*			mouseCoords = getRightMouseDown(mWindow);
+			inCoords.mX = llround(mouseCoords[0]);
+			inCoords.mY = llround(mouseCoords[1]);
+			convertCoords(inCoords, &outCoords);
+			mCallbacks->handleDoubleClick(this, outCoords, getModifiers(mWindow));
+			mLastModifiers = gKeyboard->currentMask(FALSE);
+		}
+			break;
+		case 10: // Text input (for IMEs)
+			
+			break;
+		default:
+			break;
+			
+	}*/
 	
 	updateCursor();
 }
 
 BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 {
-	Rect window_rect;
-	OSStatus err = -1;
+	float rect[4];
+	S32 err = -1;
 
 	if(mFullscreen)
 	{
@@ -1181,10 +719,10 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 	}
 	else if(mWindow)
 	{
-		err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
+		getContentViewBounds(mWindow, rect);
 
-		position->mX = window_rect.left;
-		position->mY = window_rect.top;
+		position->mX = rect[0];
+		position->mY = rect[1];
 	}
 	else
 	{
@@ -1196,8 +734,8 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 
 BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 {
-	Rect window_rect;
-	OSStatus err = -1;
+	float rect[4];
+	S32 err = -1;
 
 	if(mFullscreen)
 	{
@@ -1207,10 +745,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 	}
 	else if(mWindow)
 	{
-		err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
+		getContentViewBounds(mWindow, rect);
 
-		size->mX = window_rect.right - window_rect.left;
-		size->mY = window_rect.bottom - window_rect.top;
+		size->mX = rect[2];
+		size->mY = rect[3];
 	}
 	else
 	{
@@ -1222,9 +760,9 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 
 BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 {
-	Rect window_rect;
-	OSStatus err = -1;
-
+	float rect[4];
+	S32 err = -1;
+	
 	if(mFullscreen)
 	{
 		size->mX = mFullscreenWidth;
@@ -1233,16 +771,16 @@ BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 	}
 	else if(mWindow)
 	{
-		err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
-
-		size->mX = window_rect.right - window_rect.left;
-		size->mY = window_rect.bottom - window_rect.top;
+		getContentViewBounds(mWindow, rect);
+		
+		size->mX = rect[2];
+		size->mY = rect[3];
 	}
 	else
 	{
 		llerrs << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << llendl;
 	}
-
+	
 	return (err == noErr);
 }
 
@@ -1250,7 +788,8 @@ BOOL LLWindowMacOSX::setPosition(const LLCoordScreen position)
 {
 	if(mWindow)
 	{
-		MacMoveWindow(mWindow, position.mX, position.mY, false);
+		float pos[2] = {position.mX, position.mY};
+		setWindowPos(mWindow, pos);
 	}
 
 	return TRUE;
@@ -1260,7 +799,7 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size)
 {
 	if(mWindow)
 	{
-		SizeWindow(mWindow, size.mX, size.mY, true);
+		setWindowSize(mWindow, size.mX, size.mY);
 	}
 
 	return TRUE;
@@ -1268,15 +807,16 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size)
 
 BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
 {
-	Rect client_rect;
+	float client_rect[4];
 	if (mWindow)
 	{
-		OSStatus err = GetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
+		S32 err = noErr;
+		getContentViewBounds(mWindow, client_rect);
 		if (err == noErr)
 		{
-			client_rect.right = client_rect.left + size.mX;
-			client_rect.bottom = client_rect.top + size.mY;
-			err = SetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
+			client_rect[2] += size.mX;
+			client_rect[3] += size.mY;
+			setWindowSize(mWindow, client_rect[2], client_rect[3]);
 		}
 		if (err == noErr)
 		{
@@ -1293,7 +833,7 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
 
 void LLWindowMacOSX::swapBuffers()
 {
-	aglSwapBuffers(mContext);
+	CGLFlushDrawable(mContext);
 }
 
 F32 LLWindowMacOSX::getGamma()
@@ -1453,7 +993,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
 
 	return result;
 }
-
+/*
 static void fixOrigin(void)
 {
 	GrafPtr port;
@@ -1467,26 +1007,16 @@ static void fixOrigin(void)
 		::SetOrigin(0,0);
 	}
 }
-
+*/
 BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
 {
-	Point cursor_point;
+	float cursor_point[2];
 	LLCoordScreen screen_pos;
-	GrafPtr save;
 
 	if(mWindow == NULL)
 		return FALSE;
-
-	::GetPort(&save);
-	::SetPort(GetWindowPort(mWindow));
-	fixOrigin();
-
-	// gets the mouse location in local coordinates
-	::GetMouse(&cursor_point);
-
-//	lldebugs << "getCursorPosition(): cursor is at " << cursor_point.h << ", " << cursor_point.v << "  port origin: " << portrect.left << ", " << portrect.top << llendl;
-
-	::SetPort(save);
+	
+	getCursorPos(mWindow, cursor_point);
 
 	if(mCursorDecoupled)
 	{
@@ -1499,12 +1029,12 @@ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
 
 		// CGGetLastMouseDelta may behave strangely when the cursor's first captured.
 		// Stash in the event handler instead.
-		cursor_point.h += mCursorLastEventDeltaX;
-		cursor_point.v += mCursorLastEventDeltaY;
+		cursor_point[0] += mCursorLastEventDeltaX;
+		cursor_point[1] += mCursorLastEventDeltaY;
 	}
 
-	position->mX = cursor_point.h;
-	position->mY = cursor_point.v;
+	position->mX = cursor_point[0];
+	position->mY = cursor_point[1];
 
 	return TRUE;
 }
@@ -1521,7 +1051,6 @@ void LLWindowMacOSX::adjustCursorDecouple(bool warpingMouse)
 				//			llinfos << "adjustCursorDecouple: decoupling cursor" << llendl;
 				CGAssociateMouseAndMouseCursorPosition(false);
 				mCursorDecoupled = true;
-				FlushSpecificEventsFromQueue(GetCurrentEventQueue(), mMoveEventCampartorUPP, NULL);
 				mCursorIgnoreNextDelta = TRUE;
 			}
 		}
@@ -1568,52 +1097,13 @@ F32 LLWindowMacOSX::getPixelAspectRatio()
 
 // MBW -- XXX -- There's got to be a better way than this.  Find it, please...
 
+// Since we're no longer supporting the "typical" fullscreen mode with CGL or NSOpenGL anymore, these are unnecessary. -Geenz
 void LLWindowMacOSX::beforeDialog()
 {
-	if(mFullscreen)
-	{
-
-#if CAPTURE_ALL_DISPLAYS
-		// Uncapture all displays (may want to do this for final build)
-		CGReleaseAllDisplays ();
-#else
-		// Uncapture only the main display (useful for debugging)
-		CGDisplayRelease (mDisplay);
-#endif
-		// kDocumentWindowClass
-		// kMovableModalWindowClass
-		// kAllWindowClasses
-
-		//		GLint order = 0;
-		//		aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order);
-		aglSetDrawable(mContext, NULL);
-		//		GetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), &oldWindowLevel);
-		//		SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), CGShieldingWindowLevel());
-
-		mHandsOffEvents = TRUE;
-
-	}
 }
 
 void LLWindowMacOSX::afterDialog()
 {
-	if(mFullscreen)
-	{
-		mHandsOffEvents = FALSE;
-
-		//		SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), oldWindowLevel);
-		aglSetFullScreen(mContext, 0, 0, 0, 0);
-		//		GLint order = 1;
-		//		aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order);
-
-#if CAPTURE_ALL_DISPLAYS
-		// Capture all displays (may want to do this for final build)
-		CGCaptureAllDisplays ();
-#else
-		// Capture only the main display (useful for debugging)
-		CGDisplayCapture (mDisplay);
-#endif
-	}
 }
 
 
@@ -1622,14 +1112,10 @@ void LLWindowMacOSX::flashIcon(F32 seconds)
 	// Don't do this if we're already started, since this would try to install the NMRec twice.
 	if(!mBounceTimer.getStarted())
 	{
-		OSErr err;
-
+		S32 err = 0;
+		// TODO: Implement icon bouncing
 		mBounceTime = seconds;
-		memset(&mBounceRec, 0, sizeof(mBounceRec));
-		mBounceRec.qType = nmType;
-		mBounceRec.nmMark = 1;
-		err = NMInstall(&mBounceRec);
-		if(err == noErr)
+		if(err == 0)
 		{
 			mBounceTimer.start();
 		}
@@ -1643,104 +1129,25 @@ void LLWindowMacOSX::flashIcon(F32 seconds)
 
 BOOL LLWindowMacOSX::isClipboardTextAvailable()
 {
-	OSStatus err;
-	ScrapRef scrap;
-	ScrapFlavorFlags flags;
 	BOOL result = false;
-
-	err = GetCurrentScrap(&scrap);
-
-	if(err == noErr)
-	{
-		err = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &flags);
-	}
-
-	if(err == noErr)
-		result = true;
-
+	// TODO: Clipboard support.
 	return result;
 }
 
 BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
 {
-	OSStatus err;
-	ScrapRef scrap;
-	Size len;
 	BOOL result = false;
-
-	err = GetCurrentScrap(&scrap);
-
-	if(err == noErr)
-	{
-		err = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &len);
-	}
-
-	if((err == noErr) && (len > 0))
-	{
-		int u16len = len / sizeof(U16);
-		U16 *temp = new U16[u16len + 1];
-		if (temp)
-		{
-			memset(temp, 0, (u16len + 1) * sizeof(temp[0]));
-			err = GetScrapFlavorData(scrap, kScrapFlavorTypeUnicode, &len, temp);
-			if (err == noErr)
-			{
-				// convert \r\n to \n and \r to \n in the incoming text.
-				U16 *s, *d;
-				for(s = d = temp; s[0] != '\0'; s++, d++)
-				{
-					if(s[0] == '\r')
-					{
-						if(s[1] == '\n')
-						{
-							// CRLF, a.k.a. DOS newline.  Collapse to a single '\n'.
-							s++;
-						}
-
-						d[0] = '\n';
-					}
-					else
-					{
-						d[0] = s[0];
-					}
-				}
-
-				d[0] = '\0';
-
-				dst = utf16str_to_wstring(temp);
-
-				result = true;
-			}
-			delete[] temp;
-		}
-	}
+	
+	// TODO: Clipboard support.
 
 	return result;
 }
 
 BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s)
 {
-	OSStatus err;
-	ScrapRef scrap;
-	//Size len;
-	//char *temp;
 	BOOL result = false;
-
-	if (!s.empty())
-	{
-		err = GetCurrentScrap(&scrap);
-		if (err == noErr)
-			err = ClearScrap(&scrap);
-
-		if (err == noErr)
-		{
-			llutf16string utf16str = wstring_to_utf16str(s);
-			size_t u16len = utf16str.length() * sizeof(U16);
-			err = PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone, u16len, utf16str.data());
-			if (err == noErr)
-				result = true;
-		}
-	}
+	
+	// TODO: Clipboard support.
 
 	return result;
 }
@@ -1761,1048 +1168,162 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
 		CFArrayRef modes = CGDisplayAvailableModes(mDisplay);
 
 		if(modes != NULL)
-		{
-			CFIndex index, cnt;
-
-			mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS];
-			mNumSupportedResolutions = 0;
-
-			//  Examine each mode
-			cnt = CFArrayGetCount( modes );
-
-			for ( index = 0; (index < cnt) && (mNumSupportedResolutions < MAX_NUM_RESOLUTIONS); index++ )
-			{
-				//  Pull the mode dictionary out of the CFArray
-				CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex( modes, index );
-				long width = getDictLong(mode, kCGDisplayWidth);
-				long height = getDictLong(mode, kCGDisplayHeight);
-				long bits = getDictLong(mode, kCGDisplayBitsPerPixel);
-
-				if(bits == BITS_PER_PIXEL && width >= 800 && height >= 600)
-				{
-					BOOL resolution_exists = FALSE;
-					for(S32 i = 0; i < mNumSupportedResolutions; i++)
-					{
-						if (mSupportedResolutions[i].mWidth == width &&
-							mSupportedResolutions[i].mHeight == height)
-						{
-							resolution_exists = TRUE;
-						}
-					}
-					if (!resolution_exists)
-					{
-						mSupportedResolutions[mNumSupportedResolutions].mWidth = width;
-						mSupportedResolutions[mNumSupportedResolutions].mHeight = height;
-						mNumSupportedResolutions++;
-					}
-				}
-			}
-		}
-	}
-
-	num_resolutions = mNumSupportedResolutions;
-	return mSupportedResolutions;
-}
-
-BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to)
-{
-	S32		client_height;
-	Rect	client_rect;
-
-	if(mFullscreen)
-	{
-		// In the fullscreen case, the "window" is the entire screen.
-		client_rect.left = 0;
-		client_rect.top = 0;
-		client_rect.right = mFullscreenWidth;
-		client_rect.bottom = mFullscreenHeight;
-	}
-	else if (!mWindow ||
-		(GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) ||
-		NULL == to)
-	{
-		return FALSE;
-	}
-
-	to->mX = from.mX;
-	client_height = client_rect.bottom - client_rect.top;
-	to->mY = client_height - from.mY - 1;
-
-	return TRUE;
-}
-
-BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to)
-{
-	S32		client_height;
-	Rect	client_rect;
-
-	if(mFullscreen)
-	{
-		// In the fullscreen case, the "window" is the entire screen.
-		client_rect.left = 0;
-		client_rect.top = 0;
-		client_rect.right = mFullscreenWidth;
-		client_rect.bottom = mFullscreenHeight;
-	}
-	else if (!mWindow ||
-		(GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) ||
-		NULL == to)
-	{
-		return FALSE;
-	}
-
-	to->mX = from.mX;
-	client_height = client_rect.bottom - client_rect.top;
-	to->mY = client_height - from.mY - 1;
-
-	return TRUE;
-}
-
-BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
-{
-	if(mFullscreen)
-	{
-		// In the fullscreen case, window and screen coordinates are the same.
-		to->mX = from.mX;
-		to->mY = from.mY;
-		return TRUE;
-	}
-	else if(mWindow)
-	{
-		GrafPtr save;
-		Point mouse_point;
-
-		mouse_point.h = from.mX;
-		mouse_point.v = from.mY;
-
-		::GetPort(&save);
-		::SetPort(GetWindowPort(mWindow));
-		fixOrigin();
-
-		::GlobalToLocal(&mouse_point);
-
-		to->mX = mouse_point.h;
-		to->mY = mouse_point.v;
-
-		::SetPort(save);
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
-{
-	if(mFullscreen)
-	{
-		// In the fullscreen case, window and screen coordinates are the same.
-		to->mX = from.mX;
-		to->mY = from.mY;
-		return TRUE;
-	}
-	else if(mWindow)
-	{
-		GrafPtr save;
-		Point mouse_point;
-
-		mouse_point.h = from.mX;
-		mouse_point.v = from.mY;
-		::GetPort(&save);
-		::SetPort(GetWindowPort(mWindow));
-		fixOrigin();
-
-		LocalToGlobal(&mouse_point);
-
-		to->mX = mouse_point.h;
-		to->mY = mouse_point.v;
-
-		::SetPort(save);
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to)
-{
-	LLCoordWindow window_coord;
-
-	return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
-}
-
-BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to)
-{
-	LLCoordWindow window_coord;
-
-	return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
-}
-
-
-
-
-void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& caption, U32 type)
-{
-	destroyContext();
-
-	OSMessageBox(text, caption, type);
-}
-
-pascal Boolean LLWindowMacOSX::staticMoveEventComparator( EventRef event, void* data)
-{
-	UInt32 				evtClass = GetEventClass (event);
-	UInt32 				evtKind = GetEventKind (event);
-
-	if ((evtClass == kEventClassMouse) && ((evtKind == kEventMouseDragged) || (evtKind == kEventMouseMoved)))
-	{
-		return true;
-	}
-
-	else
-	{
-		return false;
-	}
-}
-
-
-pascal OSStatus LLWindowMacOSX::staticEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData)
-{
-	LLWindowMacOSX *self = (LLWindowMacOSX*)userData;
-
-	return(self->eventHandler(myHandler, event));
-}
-
-OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef event)
-{
-	OSStatus			result = eventNotHandledErr;
-	UInt32 				evtClass = GetEventClass (event);
-	UInt32 				evtKind = GetEventKind (event);
-
-	// Always handle command events, even in hands-off mode.
-	if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
-	{
-		HICommand command;
-		GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command);
-
-		switch(command.commandID)
-		{
-		case kHICommandQuit:
-			if(mCallbacks->handleCloseRequest(this))
-			{
-				// Get the app to initiate cleanup.
-				mCallbacks->handleQuit(this);
-				// The app is responsible for calling destroyWindow when done with GL
-			}
-			result = noErr;
-			break;
-
-		default:
-			// MBW -- XXX -- Should we handle other events here?
-			break;
-		}
-	}
-
-	if(mHandsOffEvents)
-	{
-		return(result);
-	}
-
-	switch (evtClass)
-	{
-	case kEventClassTextInput:
-		{
-			switch (evtKind)
-			{
-			case kEventTextInputUpdateActiveInputArea:
-				{
-					EventParamType param_type;
-
-					long fix_len;
-					UInt32 text_len;
-					if (mPreeditor
-						&& (result = GetEventParameter(event, kEventParamTextInputSendFixLen,
-										typeLongInteger, &param_type, sizeof(fix_len), NULL, &fix_len)) == noErr
-						&& typeLongInteger == param_type
-						&& (result = GetEventParameter(event, kEventParamTextInputSendText,
-										typeUnicodeText, &param_type, 0, &text_len, NULL)) == noErr
-						&& typeUnicodeText == param_type)
-					{
-						// Handle an optional (but essential to facilitate TSMDA) ReplaceRange param.
-						CFRange range;
-						if (GetEventParameter(event, kEventParamTextInputSendReplaceRange,
-								typeCFRange, &param_type, sizeof(range), NULL, &range) == noErr
-							&& typeCFRange == param_type)
-						{
-							// Although the spec. is unclear, replace range should
-							// not present when there is an active preedit.  We just
-							// ignore the case.  markAsPreedit will detect the case and warn it.
-							const LLWString & text = mPreeditor->getPreeditString();
-							const S32 location = wstring_wstring_length_from_utf16_length(text, 0, range.location);
-							const S32 length = wstring_wstring_length_from_utf16_length(text, location, range.length);
-							mPreeditor->markAsPreedit(location, length);
-						}
-						mPreeditor->resetPreedit();
-
-						// Receive the text from input method.
-						U16 *const text = new U16[text_len / sizeof(U16)];
-						GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, NULL, text_len, NULL, text);
-						if (fix_len < 0)
-						{
-							// Do we still need this?  Seems obsolete...
-							fix_len = text_len;
-						}
-						const LLWString fix_string
-								= utf16str_to_wstring(llutf16string(text, fix_len / sizeof(U16)));
-						const LLWString preedit_string
-								= utf16str_to_wstring(llutf16string(text + fix_len / sizeof(U16), (text_len - fix_len) / sizeof(U16)));
-						delete[] text;
-
-						// Handle fixed (comitted) string.
-						if (fix_string.length() > 0)
-						{
-							for (LLWString::const_iterator i = fix_string.begin(); i != fix_string.end(); i++)
-							{
-								mPreeditor->handleUnicodeCharHere(*i);
-							}
-						}
-
-						// Receive the segment info and caret position.
-						LLPreeditor::segment_lengths_t preedit_segment_lengths;
-						LLPreeditor::standouts_t preedit_standouts;
-						S32 caret_position = preedit_string.length();
-						UInt32 text_range_array_size;
-						if (GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray,
-								&param_type, 0, &text_range_array_size, NULL) == noErr
-							&& typeTextRangeArray == param_type
-							&& text_range_array_size > sizeof(TextRangeArray))
-						{
-							// TextRangeArray is a variable-length struct.
-							TextRangeArray * const text_range_array = (TextRangeArray *) new char[text_range_array_size];
-							GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray,
-									NULL, text_range_array_size, NULL, text_range_array);
-
-							// WARNING: We assume ranges are in ascending order,
-							// although the condition is undocumented.  It seems
-							// OK to assume this.  I also assumed
-							// the ranges are contiguous in previous versions, but I
-							// have heard a rumore that older versions os ATOK may
-							// return ranges with some _gap_.  I don't know whether
-							// it is true, but I'm preparing my code for the case.
-
-							const S32 ranges = text_range_array->fNumOfRanges;
-							preedit_segment_lengths.reserve(ranges);
-							preedit_standouts.reserve(ranges);
-
-							S32 last_bytes = 0;
-							S32 last_utf32 = 0;
-							for (S32 i = 0; i < ranges; i++)
-							{
-								const TextRange &range = text_range_array->fRange[i];
-								if (range.fStart > last_bytes)
-								{
-									const S32 length_utf16 = (range.fStart - last_bytes) / sizeof(U16);
-									const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16);
-									preedit_segment_lengths.push_back(length_utf32);
-									preedit_standouts.push_back(FALSE);
-									last_utf32 += length_utf32;
-								}
-								if (range.fEnd > range.fStart)
-								{
-									const S32 length_utf16 = (range.fEnd - range.fStart) / sizeof(U16);
-									const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16);
-									preedit_segment_lengths.push_back(length_utf32);
-									preedit_standouts.push_back(
-										kTSMHiliteSelectedRawText == range.fHiliteStyle
-										|| kTSMHiliteSelectedConvertedText ==  range.fHiliteStyle
-										|| kTSMHiliteSelectedText == range.fHiliteStyle);
-									last_utf32 += length_utf32;
-								}
-								if (kTSMHiliteCaretPosition == range.fHiliteStyle)
-								{
-									caret_position = last_utf32;
-								}
-								last_bytes = range.fEnd;
-							}
-							if (preedit_string.length() > last_utf32)
-							{
-								preedit_segment_lengths.push_back(preedit_string.length() - last_utf32);
-								preedit_standouts.push_back(FALSE);
-							}
-
-							delete[] (char *) text_range_array;
-						}
-
-						// Handle preedit string.
-						if (preedit_string.length() == 0)
-						{
-							preedit_segment_lengths.clear();
-							preedit_standouts.clear();
-						}
-						else if (preedit_segment_lengths.size() == 0)
-						{
-							preedit_segment_lengths.push_back(preedit_string.length());
-							preedit_standouts.push_back(FALSE);
-						}
-						mPreeditor->updatePreedit(preedit_string, preedit_segment_lengths, preedit_standouts, caret_position);
-
-						result = noErr;
-					}
-				}
-				break;
-
-			case kEventTextInputUnicodeForKeyEvent:
-				{
-					UInt32 modifiers = 0;
-
-
-					// First, process the raw event.
-					{
-						EventRef rawEvent = NULL;
-
-						// Get the original event and extract the modifier keys, so we can ignore command-key events.
-						if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr)
-						{
-							// Grab the modifiers for later use in this function...
-							GetEventParameter (rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
-
-							// and call this function recursively to handle the raw key event.
-							eventHandler (myHandler, rawEvent);
-
-							// save the raw event until we're done processing the unicode input as well.
-							mRawKeyEvent = rawEvent;
-						}
-					}
-
-					OSStatus err = noErr;
-					EventParamType actualType = typeUnicodeText;
-					UInt32 actualSize = 0;
-					size_t actualCount = 0;
-					U16 *buffer = NULL;
-
-					// Get the size of the unicode data
-					err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, 0, &actualSize, NULL);
-					if(err == noErr)
-					{
-						// allocate a buffer and get the actual data.
-						actualCount = actualSize / sizeof(U16);
-						buffer = new U16[actualCount];
-						err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, actualSize, &actualSize, buffer);
-					}
-
-					if(err == noErr)
-					{
-						if(modifiers & (cmdKey | controlKey))
-						{
-							// This was a menu key equivalent.  Ignore it.
-						}
-						else
-						{
-							MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
-
-							llassert( actualType == typeUnicodeText );
-
-							// The result is a UTF16 buffer.  Pass the characters in turn to handleUnicodeChar.
-
-							// Convert to UTF32 and go character-by-character.
-							llutf16string utf16(buffer, actualCount);
-							LLWString utf32 = utf16str_to_wstring(utf16);
-							LLWString::iterator iter;
-
-							for(iter = utf32.begin(); iter != utf32.end(); iter++)
-							{
-								mCallbacks->handleUnicodeChar(*iter, mask);
-							}
-						}
-					}
-
-					if(buffer != NULL)
-					{
-						delete[] buffer;
-					}
-
-					mRawKeyEvent = NULL;
-					result = err;
-				}
-				break;
-
-			case kEventTextInputOffsetToPos:
-				{
-					EventParamType param_type;
-					long offset;
-					if (mPreeditor
-						&& GetEventParameter(event, kEventParamTextInputSendTextOffset, typeLongInteger,
-								&param_type, sizeof(offset), NULL, &offset) == noErr
-						&& typeLongInteger == param_type)
-					{
-						S32 preedit, preedit_length;
-						mPreeditor->getPreeditRange(&preedit, &preedit_length);
-						const LLWString & text = mPreeditor->getPreeditString();
-
-						LLCoordGL caret_coord;
-						LLRect preedit_bounds;
-						if (0 <= offset
-							&& mPreeditor->getPreeditLocation(wstring_wstring_length_from_utf16_length(text, preedit, offset / sizeof(U16)),
-															  &caret_coord, &preedit_bounds, NULL))
-						{
-							LLCoordGL caret_base_coord(caret_coord.mX, preedit_bounds.mBottom);
-							LLCoordScreen caret_base_coord_screen;
-							convertCoords(caret_base_coord, &caret_base_coord_screen);
-							Point qd_point;
-							qd_point.h = caret_base_coord_screen.mX;
-							qd_point.v = caret_base_coord_screen.mY;
-							SetEventParameter(event, kEventParamTextInputReplyPoint, typeQDPoint, sizeof(qd_point), &qd_point);
-
-							short line_height = (short) preedit_bounds.getHeight();
-							SetEventParameter(event, kEventParamTextInputReplyLineHeight, typeShortInteger, sizeof(line_height), &line_height);
-
-							result = noErr;
-						}
-						else
-						{
-							result = errOffsetInvalid;
-						}
-					}
-				}
-				break;
-
-			case kEventTextInputGetSelectedText:
-				{
-					if (mPreeditor)
-					{
-						S32 selection, selection_length;
-						mPreeditor->getSelectionRange(&selection, &selection_length);
-						if (selection_length)
-						{
-							const LLWString text = mPreeditor->getPreeditString().substr(selection, selection_length);
-							const llutf16string text_utf16 = wstring_to_utf16str(text);
-							result = SetEventParameter(event, kEventParamTextInputReplyText, typeUnicodeText,
-										text_utf16.length() * sizeof(U16), text_utf16.c_str());
-						}
-					}
-				}
-				break;
-			}
-		}
-		break;
-
-	case kEventClassKeyboard:
-		{
-			UInt32 keyCode = 0;
-			char charCode = 0;
-			UInt32 modifiers = 0;
-
-			// Some of these may fail for some event types.  That's fine.
-			GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
-			GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
-
-			// save the raw event so getNativeKeyData can use it.
-			mRawKeyEvent = event;
-
-			//			printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers);
-			//			fflush(stdout);
-
-			switch (evtKind)
-			{
-			case kEventRawKeyDown:
-			case kEventRawKeyRepeat:
-				if (gDebugWindowProc)
-				{
-					printf("key down, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n",
-							(unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers);
-					fflush(stdout);
-				}
-				gKeyboard->handleKeyDown(keyCode, modifiers);
-				result = eventNotHandledErr;
-				break;
-
-			case kEventRawKeyUp:
-				if (gDebugWindowProc)
-				{
-					printf("key up,   key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n",
-							(unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers);
-					fflush(stdout);
-				}
-				gKeyboard->handleKeyUp(keyCode, modifiers);
-				result = eventNotHandledErr;
-				break;
-
-			case kEventRawKeyModifiersChanged:
-				// The keyboard input system wants key up/down events for modifier keys.
-				// Mac OS doesn't supply these directly, but can supply events when the collective modifier state changes.
-				// Use these events to generate up/down events for the modifiers.
-
-				if((modifiers & shiftKey) && !(mLastModifiers & shiftKey))
-				{
-					if (gDebugWindowProc) printf("Shift key down event\n");
-					gKeyboard->handleKeyDown(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000));
-				}
-				else if(!(modifiers & shiftKey) && (mLastModifiers & shiftKey))
-				{
-					if (gDebugWindowProc) printf("Shift key up event\n");
-					gKeyboard->handleKeyUp(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000));
-				}
-
-				if((modifiers & alphaLock) && !(mLastModifiers & alphaLock))
-				{
-					if (gDebugWindowProc) printf("Caps lock down event\n");
-					gKeyboard->handleKeyDown(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000));
-				}
-				else if(!(modifiers & alphaLock) && (mLastModifiers & alphaLock))
-				{
-					if (gDebugWindowProc) printf("Caps lock up event\n");
-					gKeyboard->handleKeyUp(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000));
-				}
-
-				if((modifiers & controlKey) && !(mLastModifiers & controlKey))
-				{
-					if (gDebugWindowProc) printf("Control key down event\n");
-					gKeyboard->handleKeyDown(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000));
-				}
-				else if(!(modifiers & controlKey) && (mLastModifiers & controlKey))
-				{
-					if (gDebugWindowProc) printf("Control key up event\n");
-					gKeyboard->handleKeyUp(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000));
-				}
-
-				if((modifiers & optionKey) && !(mLastModifiers & optionKey))
-				{
-					if (gDebugWindowProc) printf("Option key down event\n");
-					gKeyboard->handleKeyDown(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000));
-				}
-				else if(!(modifiers & optionKey) && (mLastModifiers & optionKey))
-				{
-					if (gDebugWindowProc) printf("Option key up event\n");
-					gKeyboard->handleKeyUp(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000));
-				}
-
-				// When the state of the 'Fn' key (the one that changes some of the mappings on a powerbook/macbook keyboard
-				// to an embedded keypad) changes, it may subsequently cause a key up event to be lost, which may lead to
-				// a movement key getting "stuck" down.  This is bad.
-				// This is an OS bug -- even the GetKeys() API doesn't tell you the key has been released.
-				// This workaround causes all held-down keys to be reset whenever the state of the Fn key changes.  This isn't
-				// exactly what we want, but it does avoid the case where you get stuck running forward.
-				if((modifiers & kEventKeyModifierFnMask) != (mLastModifiers & kEventKeyModifierFnMask))
-				{
-					if (gDebugWindowProc) printf("Fn key state change event\n");
-					gKeyboard->resetKeys();
-				}
-
-				if (gDebugWindowProc) fflush(stdout);
-
-				mLastModifiers = modifiers;
-				result = eventNotHandledErr;
-				break;
-			}
-
-			mRawKeyEvent = NULL;
-		}
-		break;
-
-	case kEventClassMouse:
-		{
-			result = CallNextEventHandler(myHandler, event);
-			if (eventNotHandledErr == result)
-			{ // only handle events not already handled (prevents wierd resize interaction)
-				EventMouseButton	button = kEventMouseButtonPrimary;
-				HIPoint				location = {0.0f, 0.0f};
-				UInt32				modifiers = 0;
-				UInt32				clickCount = 1;
-				long				wheelDelta = 0;
-				LLCoordScreen		inCoords;
-				LLCoordGL			outCoords;
-				MASK				mask = 0;
-
-				GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
-				GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(location), NULL, &location);
-				GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
-				GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(wheelDelta), NULL, &wheelDelta);
-				GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL, sizeof(clickCount), NULL, &clickCount);
-
-				inCoords.mX = llround(location.x);
-				inCoords.mY = llround(location.y);
-
-				if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
-				if(modifiers & controlKey) { mask |= MASK_CONTROL; }
-				if(modifiers & optionKey) { mask |= MASK_ALT; }
-
-				if(mCursorDecoupled)
-				{
-					CGMouseDelta x, y;
-
-					// If the cursor's decoupled, we need to read the latest movement delta as well.
-					CGGetLastMouseDelta( &x, &y );
-					mCursorLastEventDeltaX = x;
-					mCursorLastEventDeltaY = y;
-
-					if(mCursorIgnoreNextDelta)
-					{
-						mCursorLastEventDeltaX = 0;
-						mCursorLastEventDeltaY = 0;
-						mCursorIgnoreNextDelta = FALSE;
-					}
-				}
-				else
-				{
-					mCursorLastEventDeltaX = 0;
-					mCursorLastEventDeltaY = 0;
-				}
-
-				inCoords.mX += mCursorLastEventDeltaX;
-				inCoords.mY += mCursorLastEventDeltaY;
-
-				convertCoords(inCoords, &outCoords);
-
-				//				printf("coords in: %d, %d; coords out: %d, %d\n", inCoords.mX, inCoords.mY, outCoords.mX, outCoords.mY);
-				//				fflush(stdout);
-
-
-				switch (evtKind)
-				{
-				case kEventMouseDown:
-					if (mLanguageTextInputAllowed)
-					{
-						// We need to interrupt before handling mouse events,
-						// so that the fixed string from IM are delivered to
-						// the currently focused UI component.
-						interruptLanguageTextInput();
-					}
-					switch(button)
-					{
-					case kEventMouseButtonPrimary:
-						if(modifiers & cmdKey)
-						{
-							// Simulate a right click
-							mSimulatedRightClick = true;
-							mCallbacks->handleRightMouseDown(this, outCoords, mask);
-						}
-						else if(clickCount == 2)
-						{
-							// Windows double-click events replace the second mousedown event in a double-click.
-							mCallbacks->handleDoubleClick(this, outCoords, mask);
-						}
-						else
-						{
-							mCallbacks->handleMouseDown(this, outCoords, mask);
-						}
-						break;
-					case kEventMouseButtonSecondary:
-						mCallbacks->handleRightMouseDown(this, outCoords, mask);
-						break;
-
-					case kEventMouseButtonTertiary:
-						mCallbacks->handleMiddleMouseDown(this, outCoords, mask);
-						break;
-					}
-					result = noErr;
-					break;
-				case kEventMouseUp:
-
-					switch(button)
-					{
-					case kEventMouseButtonPrimary:
-						if(mSimulatedRightClick)
-						{
-							// End of simulated right click
-							mSimulatedRightClick = false;
-							mCallbacks->handleRightMouseUp(this, outCoords, mask);
-						}
-						else
-						{
-							mCallbacks->handleMouseUp(this, outCoords, mask);
-						}
-						break;
-					case kEventMouseButtonSecondary:
-						mCallbacks->handleRightMouseUp(this, outCoords, mask);
-						break;
+		{
+			CFIndex index, cnt;
 
-					case kEventMouseButtonTertiary:
-						mCallbacks->handleMiddleMouseUp(this, outCoords, mask);
-						break;
-					}
-					result = noErr;
-					break;
+			mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS];
+			mNumSupportedResolutions = 0;
 
-				case kEventMouseWheelMoved:
-					{
-						static S32  z_delta = 0;
+			//  Examine each mode
+			cnt = CFArrayGetCount( modes );
 
-						z_delta += wheelDelta;
+			for ( index = 0; (index < cnt) && (mNumSupportedResolutions < MAX_NUM_RESOLUTIONS); index++ )
+			{
+				//  Pull the mode dictionary out of the CFArray
+				CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex( modes, index );
+				long width = getDictLong(mode, kCGDisplayWidth);
+				long height = getDictLong(mode, kCGDisplayHeight);
+				long bits = getDictLong(mode, kCGDisplayBitsPerPixel);
 
-						if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta)
+				if(bits == BITS_PER_PIXEL && width >= 800 && height >= 600)
+				{
+					BOOL resolution_exists = FALSE;
+					for(S32 i = 0; i < mNumSupportedResolutions; i++)
+					{
+						if (mSupportedResolutions[i].mWidth == width &&
+							mSupportedResolutions[i].mHeight == height)
 						{
-							mCallbacks->handleScrollWheel(this, -z_delta / WHEEL_DELTA);
-							z_delta = 0;
+							resolution_exists = TRUE;
 						}
 					}
-					result = noErr;
-					break;
-
-				case kEventMouseDragged:
-				case kEventMouseMoved:
-					mCallbacks->handleMouseMove(this, outCoords, mask);
-					result = noErr;
-					break;
-
+					if (!resolution_exists)
+					{
+						mSupportedResolutions[mNumSupportedResolutions].mWidth = width;
+						mSupportedResolutions[mNumSupportedResolutions].mHeight = height;
+						mNumSupportedResolutions++;
+					}
 				}
 			}
 		}
-		break;
-
-	case kEventClassWindow:
-		switch(evtKind)
-		{
-		case kEventWindowActivated:
-			if (mTSMDocument)
-			{
-				ActivateTSMDocument(mTSMDocument);
-			}
-			mCallbacks->handleFocus(this);
-			break;
-		case kEventWindowDeactivated:
-			if (mTSMDocument)
-			{
-				DeactivateTSMDocument(mTSMDocument);
-			}
-			mCallbacks->handleFocusLost(this);
-			break;
-
-		case kEventWindowBoundsChanging:
-			{
-				// This is where we would constrain move/resize to a particular screen
-
-				const S32 MIN_WIDTH  = mMinWindowWidth;
-				const S32 MIN_HEIGHT = mMinWindowHeight;
-
-				Rect currentBounds;
-				Rect previousBounds;
-
-				GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds);
-				GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &previousBounds);
-
-				// Put an offset into window un-maximize operation since the kEventWindowGetIdealSize
-				// event only allows the specification of size and not position.
-				if (mMaximized)
-				{
-					short leftOffset = mPreviousWindowRect.left - currentBounds.left;
-					currentBounds.left += leftOffset;
-					currentBounds.right += leftOffset;
+	}
 
-					short topOffset = mPreviousWindowRect.top - currentBounds.top;
-					currentBounds.top += topOffset;
-					currentBounds.bottom += topOffset;
-				}
-				else
-				{
-					// Store off the size for future un-maximize operations
-					mPreviousWindowRect = previousBounds;
-				}
+	num_resolutions = mNumSupportedResolutions;
+	return mSupportedResolutions;
+}
 
-				if ((currentBounds.right - currentBounds.left) < MIN_WIDTH)
-				{
-					currentBounds.right = currentBounds.left + MIN_WIDTH;
-				}
+BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to)
+{
+	S32		client_height;
+	float	client_rect[4];
+	getContentViewBounds(mWindow, client_rect);
+	if (!mWindow ||
+		NULL == to)
+	{
+		return FALSE;
+	}
 
-				if ((currentBounds.bottom - currentBounds.top) < MIN_HEIGHT)
-				{
-					currentBounds.bottom = currentBounds.top + MIN_HEIGHT;
-				}
+	to->mX = from.mX;
+	client_height = client_rect[3];
+	to->mY = from.mY - 1;
 
-				SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &currentBounds);
-				result = noErr;
-			}
-			break;
+	return TRUE;
+}
 
-		case kEventWindowBoundsChanged:
-			{
-				// Get new window bounds
-				Rect newBounds;
-				GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &newBounds);
+BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to)
+{
+	S32		client_height;
+	float	client_rect[4];
+	
+	getContentViewBounds(mWindow, client_rect);
+	
+	if (!mWindow ||
+		NULL == to)
+	{
+		return FALSE;
+	}
 
-				// Get previous window bounds
-				Rect oldBounds;
-				GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &oldBounds);
+	to->mX = from.mX;
+	client_height = client_rect[3];
+	to->mY = from.mY - 1;
 
-				// Determine if the new size is larger than the old
-				bool newBoundsLarger = ((newBounds.right - newBounds.left) >= (oldBounds.right - oldBounds.left));
-				newBoundsLarger &= ((newBounds.bottom - newBounds.top) >= (oldBounds.bottom - oldBounds.top));
+	return TRUE;
+}
 
-				// Check to see if this is a zoom event (+ button on window pane)
-				unsigned int eventParams;
-				GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL, sizeof(int), NULL, &eventParams);
-				bool isZoomEvent = ((eventParams & kWindowBoundsChangeZoom) != 0);
+BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
+{
+	if(mFullscreen)
+	{
+		// In the fullscreen case, window and screen coordinates are the same.
+		to->mX = from.mX;
+		to->mY = from.mY;
+		return TRUE;
+	}
+	else if(mWindow)
+	{
+		float mouse_point[2];
 
-				// Maximized flag is if zoom event and increasing window size
-				mMaximized = (isZoomEvent && newBoundsLarger);
+		mouse_point[0] = from.mX;
+		mouse_point[1] = from.mY;
+		
+		convertScreenToWindow(mWindow, mouse_point);
 
-				aglUpdateContext(mContext);
+		to->mX = mouse_point[0];
+		to->mY = mouse_point[1];
 
-				mCallbacks->handleResize(this, newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
-			}
-			break;
+		return TRUE;
+	}
 
-		case kEventWindowGetIdealSize:
-			// Only recommend a new ideal size when un-maximizing
-			if (mMaximized == TRUE)
-			{
-				Point nonMaximizedSize;
+	return FALSE;
+}
 
-				nonMaximizedSize.v = mPreviousWindowRect.bottom - mPreviousWindowRect.top;
-				nonMaximizedSize.h = mPreviousWindowRect.right - mPreviousWindowRect.left;
+BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
+{
+	if(mFullscreen)
+	{
+		// In the fullscreen case, window and screen coordinates are the same.
+		to->mX = from.mX;
+		to->mY = from.mY;
+		return TRUE;
+	}
+	else if(mWindow)
+	{
+		float mouse_point[2];
 
-				SetEventParameter(event, kEventParamDimensions, typeQDPoint, sizeof(Point), &nonMaximizedSize);
-				result = noErr;
-			}
-			break;
+		mouse_point[0] = from.mX;
+		mouse_point[1] = from.mY;
+		convertWindowToScreen(mWindow, mouse_point);
 
-		case kEventWindowClose:
-			if(mCallbacks->handleCloseRequest(this))
-			{
-				// Get the app to initiate cleanup.
-				mCallbacks->handleQuit(this);
-				// The app is responsible for calling destroyWindow when done with GL
-			}
-			result = noErr;
-			break;
+		to->mX = mouse_point[0];
+		to->mY = mouse_point[1];
 
-		case kEventWindowHidden:
-			//					llinfos << "LLWindowMacOSX: Deactivating on hide" << llendl;
-			mMinimized = TRUE;
-			mCallbacks->handleActivate(this, false);
-			//					result = noErr;
-			break;
+		return TRUE;
+	}
 
-		case kEventWindowShown:
-			//					llinfos << "LLWindowMacOSX: Activating on show" << llendl;
-			mMinimized = FALSE;
-			mCallbacks->handleActivate(this, true);
-			//					result = noErr;
-			break;
+	return FALSE;
+}
 
-		case kEventWindowCollapsed:
-			//					llinfos << "LLWindowMacOSX: Deactivating on collapse" << llendl;
-			mMinimized = TRUE;
-			mCallbacks->handleActivate(this, false);
-			//					result = noErr;
-			break;
+BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to)
+{
+	LLCoordWindow window_coord;
 
-		case kEventWindowExpanded:
-			//					llinfos << "LLWindowMacOSX: Activating on expand" << llendl;
-			mMinimized = FALSE;
-			mCallbacks->handleActivate(this, true);
-			//					result = noErr;
-			break;
+	return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
+}
 
-		case kEventWindowGetClickActivation:
-			//					BringToFront(mWindow);
-			//					result = noErr;
-			break;
-		}
-		break;
+BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to)
+{
+	LLCoordWindow window_coord;
 
-	case kEventClassTSMDocumentAccess:
-		if (mPreeditor)
-		{
-			switch(evtKind)
-			{
+	return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
+}
 
-			case kEventTSMDocumentAccessGetLength:
-				{
-					// Return the number of UTF-16 units in the text, excluding those for preedit.
-
-					S32 preedit, preedit_length;
-					mPreeditor->getPreeditRange(&preedit, &preedit_length);
-					const LLWString & text = mPreeditor->getPreeditString();
-					const CFIndex length = wstring_utf16_length(text, 0, preedit)
-						+ wstring_utf16_length(text, preedit + preedit_length, text.length());
-					result = SetEventParameter(event, kEventParamTSMDocAccessCharacterCount, typeCFIndex, sizeof(length), &length);
-				}
-				break;
 
-			case kEventTSMDocumentAccessGetSelectedRange:
-				{
-					// Return the selected range, excluding preedit.
-					// In our preeditor, preedit and selection are exclusive, so,
-					// when it has a preedit, there is no selection and the
-					// insertion point is on the preedit that corrupses into the
-					// beginning of the preedit when the preedit was removed.
-
-					S32 preedit, preedit_length;
-					mPreeditor->getPreeditRange(&preedit, &preedit_length);
-					const LLWString & text = mPreeditor->getPreeditString();
-
-					CFRange range;
-					if (preedit_length)
-					{
-						range.location = wstring_utf16_length(text, 0, preedit);
-						range.length = 0;
-					}
-					else
-					{
-						S32 selection, selection_length;
-						mPreeditor->getSelectionRange(&selection, &selection_length);
-						range.location = wstring_utf16_length(text, 0, selection);
-						range.length = wstring_utf16_length(text, selection, selection_length);
-					}
 
-					result = SetEventParameter(event, kEventParamTSMDocAccessReplyCharacterRange, typeCFRange, sizeof(range), &range);
-				}
-				break;
 
-			case kEventTSMDocumentAccessGetCharacters:
-				{
-					UniChar *target_pointer;
-					CFRange range;
-					EventParamType param_type;
-					if ((result = GetEventParameter(event, kEventParamTSMDocAccessSendCharacterRange,
-										typeCFRange, &param_type, sizeof(range), NULL, &range)) == noErr
-						&& typeCFRange == param_type
-						&& (result = GetEventParameter(event, kEventParamTSMDocAccessSendCharactersPtr,
-										typePtr, &param_type, sizeof(target_pointer), NULL, &target_pointer)) == noErr
-						&& typePtr == param_type)
-					{
-						S32 preedit, preedit_length;
-						mPreeditor->getPreeditRange(&preedit, &preedit_length);
-						const LLWString & text = mPreeditor->getPreeditString();
-
-						// The GetCharacters event of TSMDA has a fundamental flaw;
-						// An input method need to decide the starting offset and length
-						// *before* it actually see the contents, so it is impossible
-						// to guarantee the character-aligned access.  The event reply
-						// has no way to indicate a condition something like "Request
-						// was not fulfilled due to unaligned access.  Please retry."
-						// Any error sent back to the input method stops use of TSMDA
-						// entirely during the session...
-						// We need to simulate very strictly the behaviour as if the
-						// underlying *text engine* holds the contents in UTF-16.
-						// I guess this is the reason why Apple repeats saying "all
-						// text handling application should use UTF-16."  They are
-						// trying to _fix_ the flaw by changing the appliations...
-						// ... or, domination of UTF-16 in the industry may be a part
-						// of the company vision, and Apple is trying to force third
-						// party developers to obey their vision.  Remember that use
-						// of 16 bits per _a_character_ was one of the very fundamental
-						// Unicode design policy on its early days (during late 80s)
-						// and the original Unicode design was by two Apple employees...
-
-						const llutf16string text_utf16
-							= wstring_to_utf16str(text, preedit)
-							+ wstring_to_utf16str(text.substr(preedit + preedit_length));
-
-						llassert_always(sizeof(U16) == sizeof(UniChar));
-						llassert(0 <= range.location && 0 <= range.length && range.location + range.length <= text_utf16.length());
-						memcpy(target_pointer, text_utf16.c_str() + range.location, range.length * sizeof(UniChar));
-
-						// Note that result has already been set above.
-					}
-				}
-				break;
+void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& caption, U32 type)
+{
+	destroyContext();
 
-			}
-		}
-		break;
-	}
-	return result;
+	OSMessageBox(text, caption, type);
 }
 
 const char* cursorIDToName(int id)
@@ -2876,7 +1397,7 @@ static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY)
 
 void LLWindowMacOSX::updateCursor()
 {
-	OSStatus result = noErr;
+	S32 result = 0;
 
 	if (mDragOverrideCursor != -1)
 	{
@@ -2913,7 +1434,7 @@ void LLWindowMacOSX::updateCursor()
 		if(mCursorHidden)
 		{
 			// Since InitCursor resets the hide level, correct for it here.
-			::HideCursor();
+			hideNSCursor();
 		}
 		break;
 
@@ -2921,12 +1442,12 @@ void LLWindowMacOSX::updateCursor()
 		//    Find out what they look like and replicate them.
 
 		// These are essentially correct
-	case UI_CURSOR_WAIT:		SetThemeCursor(kThemeWatchCursor);	break;
-	case UI_CURSOR_IBEAM:		SetThemeCursor(kThemeIBeamCursor);	break;
-	case UI_CURSOR_CROSS:		SetThemeCursor(kThemeCrossCursor);	break;
-	case UI_CURSOR_HAND:		SetThemeCursor(kThemePointingHandCursor);	break;
+	case UI_CURSOR_WAIT:		/* Apple purposely doesn't allow us to set the beachball cursor manually. */	break;
+	case UI_CURSOR_IBEAM:		setIBeamCursor();	break;
+	case UI_CURSOR_CROSS:		setCrossCursor();	break;
+	case UI_CURSOR_HAND:		setPointingHandCursor();	break;
 		//		case UI_CURSOR_NO:			SetThemeCursor(kThemeNotAllowedCursor);	break;
-	case UI_CURSOR_ARROWCOPY:   SetThemeCursor(kThemeCopyArrowCursor);	break;
+	case UI_CURSOR_ARROWCOPY:   setCopyCursor();	break;
 
 		// Double-check these
 	case UI_CURSOR_NO:
@@ -3039,7 +1560,7 @@ void LLWindowMacOSX::hideCursor()
 		//		llinfos << "hideCursor: hiding" << llendl;
 		mCursorHidden = TRUE;
 		mHideCursorPermanent = TRUE;
-		::HideCursor();
+		hideNSCursor();
 	}
 	else
 	{
@@ -3056,7 +1577,7 @@ void LLWindowMacOSX::showCursor()
 		//		llinfos << "showCursor: showing" << llendl;
 		mCursorHidden = FALSE;
 		mHideCursorPermanent = FALSE;
-		::ShowCursor();
+		showNSCursor();
 	}
 	else
 	{
@@ -3102,7 +1623,7 @@ void LLSplashScreenMacOSX::showImpl()
 	// This code _could_ be used to display a spash screen...
 #if 0
 	IBNibRef nib = NULL;
-	OSStatus err;
+	S32 err;
 
 	err = CreateNibReference(CFSTR("SecondLife"), &nib);
 
@@ -3127,25 +1648,6 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
 		CFStringRef string = NULL;
 
 		string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
-
-		if(string != NULL)
-		{
-			ControlRef progressText = NULL;
-			ControlID id;
-			OSStatus err;
-
-			id.signature = 'what';
-			id.id = 0;
-
-			err = GetControlByID(mWindow, &id, &progressText);
-			if(err == noErr)
-			{
-				err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&string);
-				Draw1Control(progressText);
-			}
-
-			CFRelease(string);
-		}
 	}
 }
 
@@ -3154,7 +1656,6 @@ void LLSplashScreenMacOSX::hideImpl()
 {
 	if(mWindow != NULL)
 	{
-		DisposeWindow(mWindow);
 		mWindow = NULL;
 	}
 }
@@ -3163,102 +1664,16 @@ void LLSplashScreenMacOSX::hideImpl()
 
 S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type)
 {
-	S32 result = OSBTN_CANCEL;
-	SInt16 retval_mac = 1;
-	AlertStdCFStringAlertParamRec params;
-	CFStringRef errorString = NULL;
-	CFStringRef explanationString = NULL;
-	DialogRef alert = NULL;
-	AlertType alertType = kAlertCautionAlert;
-	OSStatus err;
-
-	explanationString = CFStringCreateWithCString(NULL, text.c_str(), kCFStringEncodingUTF8);
-	errorString = CFStringCreateWithCString(NULL, caption.c_str(), kCFStringEncodingUTF8);
-
-	params.version = kStdCFStringAlertVersionOne;
-	params.movable = false;
-	params.helpButton = false;
-	params.defaultText = (CFStringRef)kAlertDefaultOKText;
-	params.cancelText = 0;
-	params.otherText = 0;
-	params.defaultButton = 1;
-	params.cancelButton = 0;
-	params.position = kWindowDefaultPosition;
-	params.flags = 0;
-
-	switch(type)
-	{
-	case OSMB_OK:
-	default:
-		break;
-	case OSMB_OKCANCEL:
-		params.cancelText = (CFStringRef)kAlertDefaultCancelText;
-		params.cancelButton = 2;
-		break;
-	case OSMB_YESNO:
-		alertType = kAlertNoteAlert;
-		params.defaultText = CFSTR("Yes");
-		params.cancelText = CFSTR("No");
-		params.cancelButton = 2;
-		break;
-	}
-
-	if(gWindowImplementation != NULL)
-		gWindowImplementation->beforeDialog();
-
-	err = CreateStandardAlert(
-		alertType,
-		errorString,
-		explanationString,
-		&params,
-		&alert);
-
-	if(err == noErr)
-	{
-		err = RunStandardAlert(
-			alert,
-			NULL,
-			&retval_mac);
-	}
-
-	if(gWindowImplementation != NULL)
-		gWindowImplementation->afterDialog();
-
-	switch(type)
-	{
-	case OSMB_OK:
-	case OSMB_OKCANCEL:
-	default:
-		if(retval_mac == 1)
-			result = OSBTN_OK;
-		else
-			result = OSBTN_CANCEL;
-		break;
-	case OSMB_YESNO:
-		if(retval_mac == 1)
-			result = OSBTN_YES;
-		else
-			result = OSBTN_NO;
-		break;
-	}
-
-	if(errorString != NULL)
-	{
-		CFRelease(errorString);
-	}
-
-	if(explanationString != NULL)
-	{
-		CFRelease(explanationString);
-	}
-
-	return result;
+	// TODO: Implement a native NSAlert function that replicates all of this.
+	return 0;
 }
 
 // Open a URL with the user's default web browser.
 // Must begin with protocol identifier.
 void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
 {
+	// I'm fairly certain that this is all legitimate under Apple's currently supported APIs.
+	
 	bool found = false;
 	S32 i;
 	for (i = 0; i < gURLProtocolWhitelistCount; i++)
@@ -3276,7 +1691,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
 		return;
 	}
 
-	OSStatus result = noErr;
+	S32 result = 0;
 	CFURLRef urlRef = NULL;
 
 	llinfos << "Opening URL " << escaped_url << llendl;
@@ -3313,7 +1728,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
 LLSD LLWindowMacOSX::getNativeKeyData()
 {
 	LLSD result = LLSD::emptyMap();
-
+#if 0
 	if(mRawKeyEvent)
 	{
 		char char_code = 0;
@@ -3335,7 +1750,7 @@ LLSD LLWindowMacOSX::getNativeKeyData()
 		// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
 		// cause llsd serialization to create XML that the llsd deserializer won't parse!
 		std::string unicode;
-		OSStatus err = noErr;
+		S32 err = noErr;
 		EventParamType actualType = typeUTF8Text;
 		UInt32 actualSize = 0;
 		char *buffer = NULL;
@@ -3357,7 +1772,7 @@ LLSD LLWindowMacOSX::getNativeKeyData()
 #endif
 
 	}
-
+#endif
 
 	lldebugs << "native key data is: " << result << llendl;
 
@@ -3367,34 +1782,9 @@ LLSD LLWindowMacOSX::getNativeKeyData()
 
 BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
 {
+	// Is this even used anywhere?  Do we really need an OS color picker?
 	BOOL	retval = FALSE;
-	OSErr	error = noErr;
-	NColorPickerInfo	info;
-
-	memset(&info, 0, sizeof(info));
-	info.theColor.color.rgb.red = (UInt16)(*r * 65535.f);
-	info.theColor.color.rgb.green = (UInt16)(*g * 65535.f);
-	info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f);
-	info.placeWhere = kCenterOnMainScreen;
-
-	if(gWindowImplementation != NULL)
-		gWindowImplementation->beforeDialog();
-
-	error = NPickColor(&info);
-
-	if(gWindowImplementation != NULL)
-		gWindowImplementation->afterDialog();
-
-	if (error == noErr)
-	{
-		retval = info.newColorChosen;
-		if (info.newColorChosen)
-		{
-			*r = ((float) info.theColor.color.rgb.red) / 65535.0;
-			*g = ((float) info.theColor.color.rgb.green) / 65535.0;
-			*b = ((float) info.theColor.color.rgb.blue) / 65535.0;
-		}
-	}
+	//S32		error = 0;
 	return (retval);
 }
 
@@ -3405,44 +1795,13 @@ void *LLWindowMacOSX::getPlatformWindow()
 	return (void*)mWindow;
 }
 
-void *LLWindowMacOSX::getMediaWindow()
-{
-	/*
-		Mozilla needs to be initialized with a WindowRef to function properly.
-		(There's no good reason for this, since it shouldn't be interacting with our window in any way, but that's another issue.)
-		If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window,
-		which trips up Mozilla.
-		Instead of using our actual window, we create an invisible window which will persist for the lifetime of the application and pass that to Mozilla.
-		This satisfies its deep-seated need to latch onto a WindowRef and solves the issue with switching between fullscreen and windowed modes.
-
-		Note that we will never destroy this window (by design!), but since only one will ever be created per run of the application, that's okay.
-	*/
-
-	if(sMediaWindow == NULL)
-	{
-		Rect window_rect = {100, 100, 200, 200};
-
-		sMediaWindow = NewCWindow(
-			NULL,
-			&window_rect,
-			(ConstStr255Param) "\p",
-			false,				// Create the window invisible.
-			zoomDocProc,		// Window with a grow box and a zoom box
-			kLastWindowOfClass,		// create it behind other windows
-			false,					// no close box
-			0);
-	}
-
-	return (void*)sMediaWindow;
-}
-
 void LLWindowMacOSX::stopDockTileBounce()
 {
-	NMRemove(&mBounceRec);
 	mBounceTimer.stop();
 }
 
 // get a double value from a dictionary
+/*
 static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
 {
 	double double_value;
@@ -3452,7 +1811,7 @@ static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
 	if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it
 		return -1; // fail
 	return double_value; // otherwise return the long value
-}
+}*/
 
 // get a long value from a dictionary
 static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
@@ -3468,71 +1827,12 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
 
 void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 {
-	ScriptLanguageRecord script_language;
-
-	if (preeditor != mPreeditor && !b)
-	{
-		// This condition may occur by a call to
-		// setEnabled(BOOL) against LLTextEditor or LLLineEditor
-		// when the control is not focused.
-		// We need to silently ignore the case so that
-		// the language input status of the focused control
-		// is not disturbed.
-		return;
-	}
-
-	UseInputWindow(mTSMDocument, !b);
-
-	// Take care of old and new preeditors.
-	if (preeditor != mPreeditor || !b)
-	{
-		// We need to interrupt before updating mPreeditor,
-		// so that the fix string from input method goes to
-		// the old preeditor.
-		if (mLanguageTextInputAllowed)
-		{
-			interruptLanguageTextInput();
-		}
-		mPreeditor = (b ? preeditor : NULL);
-	}
-
-	if (b == mLanguageTextInputAllowed)
-	{
-		return;
-	}
-	mLanguageTextInputAllowed = b;
-
-	if (b)
-	{
-		if (mTSMScriptCode != smRoman)
-		{
-			script_language.fScript = mTSMScriptCode;
-			script_language.fLanguage = mTSMLangCode;
-			SetTextServiceLanguage(&script_language);
-		}
-	}
-	else
-	{
-		GetTextServiceLanguage(&script_language);
-		mTSMScriptCode = script_language.fScript;
-		mTSMLangCode = script_language.fLanguage;
-		if (mTSMScriptCode != smRoman)
-		{
-			script_language.fScript = smRoman;
-			script_language.fLanguage = langEnglish;
-			SetTextServiceLanguage(&script_language);
-		}
-	}
+	// TODO: IME support
 }
 
 void LLWindowMacOSX::interruptLanguageTextInput()
 {
-	if (mTSMDocument)
-	{
-		FixTSMDocument(mTSMDocument);
-	}
-	// Don't we need to call resetPreedit here?
-	// Well, if Apple's TSM document is correct, we don't.
+	// TODO: IME support
 }
 
 //static
@@ -3543,21 +1843,21 @@ std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()
 }
 
 // static
-MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers)
+MASK LLWindowMacOSX::modifiersToMask(S16 modifiers)
 {
 	MASK mask = 0;
-	if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
-	if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; }
-	if(modifiers & optionKey) { mask |= MASK_ALT; }
+	if(modifiers & MAC_SHIFT_KEY) { mask |= MASK_SHIFT; }
+	if(modifiers & (MAC_CMD_KEY | MAC_CTRL_KEY)) { mask |= MASK_CONTROL; }
+	if(modifiers & MAC_ALT_KEY) { mask |= MASK_ALT; }
 	return mask;
 }
 
 #if LL_OS_DRAGDROP_ENABLED
-
-OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
+/*
+S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
 						  void * handlerRefCon, DragRef drag)
 {
-	OSErr result = noErr;
+	S16 result = 0;
 	LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon;
 
 	lldebugs << "drag tracking handler, message = " << message << llendl;
@@ -3711,5 +2011,5 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop
 
 	return result;
 }
-
+*/
 #endif // LL_OS_DRAGDROP_ENABLED
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index af83b50097..a821dcabd8 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -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;
+	
+	// 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;
-	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;
+	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;
-
+	
 };
 
 
-- 
cgit v1.2.3


From bd152c1fb75c4a8d4b9271896c44243ca8759e58 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Sat, 29 Dec 2012 06:59:43 -0500
Subject: Huge amount of refactoring to use Cocoa here: - Updated to .xib
 format.  To produce a new nib (which is required after changing the xib
 file), use "ibtool SecondLife.xib --compile SecondLife.nib" within the
 newview directory. - xib file now defines the viewer's window.  VIews are
 still being pragmatically added to the main window.  This may change in the
 future. - LLAppViewer's main loop has been slightly refactored to be executed
 on a timer for OS X.  This probably needs a bit more work. - Event handling
 still needs more work to work within a timer based event loop.  It works
 fairly sporadically at the moment, as if events are being dropped between
 timer executions, at least for the mouse. - Carbon has been purged from the
 viewer's startup, and from LLWindow entirely.  There's likely still a few
 odds and ends fragmented throughout the viewer and its dependencies.  Need to
 track these down. - LLAppViewerMacOSX now uses NSApplicationMain, and also
 implements the NSApplicationDelegate protocol in LLAppDelegate. - Fullscreen
 support has been implemented for OS X 10.7+ This is still a work in progress,
 however at this stage everything needed for a functional viewer is (mostly)
 complete.  From here, it's mostly just bug hunting and fixing.

---
 indra/llwindow/llopenglview-objc.h    |   7 +-
 indra/llwindow/llopenglview-objc.mm   | 140 ++++++++++++++++++++++------------
 indra/llwindow/llwindowmacosx-objc.h  |   4 +-
 indra/llwindow/llwindowmacosx-objc.mm |  19 +++--
 indra/llwindow/llwindowmacosx.cpp     | 133 +-------------------------------
 indra/llwindow/llwindowmacosx.h       |   2 -
 6 files changed, 120 insertions(+), 185 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 8abe81ce9e..6b055bc665 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -69,4 +69,9 @@
 - (void) registerMouseExitCallback:(VoidCallback)callback;
 - (void) registerDeltaUpdateCallback:(MouseCallback)callback;
 
-@end
\ No newline at end of file
+@end
+
+void setLLNSWindowRef(LLNSWindow* window);
+void setLLOpenGLViewRef(LLOpenGLView* view);
+LLNSWindow* winRef;
+LLOpenGLView* glviewRef;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index a96c4cf82c..7c148f4acd 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -19,9 +19,12 @@
 
 - (void)windowResized:(NSNotification *)notification;
 {
-	NSSize size = [[self window] frame].size;
-	
-	mResizeCallback(size.width, size.height);
+	if (mResizeCallback != nil)
+	{
+		NSSize size = [[self window] frame].size;
+		
+		mResizeCallback(size.width, size.height);
+	}
 }
 
 - (void)dealloc
@@ -194,23 +197,29 @@
 }
 
 - (void) keyDown:(NSEvent *)theEvent {
-	mKeyDownCallback([theEvent keyCode], [theEvent modifierFlags]);
-	
-	NSString *chars = [theEvent charactersIgnoringModifiers];
-	for (uint i = 0; i < [chars length]; i++)
+	if (mKeyDownCallback != nil && mUnicodeCallback != nil)
 	{
-		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]);
+		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]);
+	if (mKeyUpCallback != nil)
+	{
+		mKeyUpCallback([theEvent keyCode], [theEvent modifierFlags]);
+	}
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
@@ -219,41 +228,59 @@
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
-	if ([theEvent clickCount] == 2)
+	if (mMouseDoubleClickCallback != nil && mMouseDownCallback != nil)
 	{
-		mMouseDoubleClickCallback(mMousePos, [theEvent modifierFlags]);
-	} else if ([theEvent clickCount] == 1) {
-		mMouseDownCallback(mMousePos, [theEvent modifierFlags]);
+		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]);
+	if (mMouseUpCallback != nil)
+	{
+		mMouseUpCallback(mMousePos, [theEvent modifierFlags]);
+	}
 }
 
 - (void) rightMouseDown:(NSEvent *)theEvent
 {
-	mRightMouseDownCallback(mMousePos, [theEvent modifierFlags]);
+	if (mRightMouseDownCallback != nil)
+	{
+		mRightMouseDownCallback(mMousePos, [theEvent modifierFlags]);
+	}
 }
 
 - (void) rightMouseUp:(NSEvent *)theEvent
 {
-	mRightMouseUpCallback(mMousePos, [theEvent modifierFlags]);
+	if (mRightMouseUpCallback != nil)
+	{
+		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);
+	if (mDeltaUpdateCallback != nil && mMouseMovedCallback != nil)
+	{
+		float mouseDeltas[2] = {
+			[theEvent deltaX],
+			[theEvent deltaZ]
+		};
+		
+		mDeltaUpdateCallback(mouseDeltas, 0);
+		
+		NSPoint mPoint = [theEvent locationInWindow];
+		mMousePos[0] = mPoint.x;
+		mMousePos[1] = mPoint.y;
+		if (mMouseMovedCallback != nil)
+		{
+			mMouseMovedCallback(mMousePos, 0);
+		}
+	}
 }
 
 // NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
@@ -261,27 +288,36 @@
 
 - (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);
+	if (mDeltaUpdateCallback != nil && mMouseMovedCallback != nil)
+	{
+		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]);
+	if (mScrollWhellCallback != nil)
+	{
+		mScrollWhellCallback(-[theEvent deltaY]);
+	}
 }
 
 - (void) mouseExited:(NSEvent *)theEvent
 {
-	mMouseExitCallback();
+	if (mMouseExitCallback != nil)
+	{
+		mMouseExitCallback();
+	}
 }
 
 - (void) registerKeyDownCallback:(KeyCallback)callback
@@ -349,4 +385,14 @@
 	mDeltaUpdateCallback = callback;
 }
 
-@end
\ No newline at end of file
+@end
+
+void setLLNSWindowRef(LLNSWindow* window)
+{
+	winRef = window;
+}
+
+void setLLOpenGLViewRef(LLOpenGLView* view)
+{
+	glviewRef = view;
+}
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 47ae13cb25..abaeda1f91 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -57,7 +57,7 @@ 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);
+CGLContextObj getCGLContextObj(GLViewRef view);
 void getContentViewBounds(NSWindowRef window, float* bounds);
 void getWindowSize(NSWindowRef window, float* size);
 void setWindowSize(NSWindowRef window, int width, int height);
@@ -80,5 +80,7 @@ void registerMouseMovedCallback(NSWindowRef window, MouseCallback callback);
 void registerScrollCallback(NSWindowRef window, ScrollWheelCallback callback);
 void registerMouseExitCallback(NSWindowRef window, VoidCallback callback);
 void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback);
+NSWindowRef getMainAppWindow();
+GLViewRef getGLView(NSWindowRef window);
 
 unsigned int getModifiers();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 03c0f55883..07efc25ea6 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -54,10 +54,10 @@ void setupCocoa()
 		//   http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
 		
 		//	Needed for Carbon based applications which call into Cocoa
-		NSApplicationLoad();
+		// NSApplicationLoad();
 
 		//	Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
-		[[[NSWindow alloc] init] release];
+		//[[[NSWindow alloc] init] release];
 
 		[pool release];
 		
@@ -188,10 +188,9 @@ void glSwapBuffers(void* context)
 	[(NSOpenGLContext*)context flushBuffer];
 }
 
-CGLContextObj getCGLContextObj(NSWindowRef window)
+CGLContextObj getCGLContextObj(GLViewRef view)
 {
-	LLOpenGLView *glview = [(LLNSWindow*)window contentView];
-	return [glview getCGLContextObj];
+	return [(LLOpenGLView *)view getCGLContextObj];
 }
 
 CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
@@ -331,6 +330,16 @@ void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback)
 	[(LLNSWindow*)window registerDeltaUpdateCallback:callback];
 }
 
+NSWindowRef getMainAppWindow()
+{
+	return winRef;
+}
+
+GLViewRef getGLView(NSWindowRef window)
+{
+	return glviewRef;
+}
+
 unsigned int getModifiers()
 {
 	return [NSEvent modifierFlags];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 1fb8bea802..a616b2df2d 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -38,7 +38,6 @@
 #include "lldir.h"
 #include "indra_constants.h"
 
-#include <Carbon/Carbon.h>
 #include <OpenGL/OpenGL.h>
 
 extern BOOL gDebugWindowProc;
@@ -342,7 +341,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 	if (mWindow == NULL)
 	{
 		LL_INFOS("Window") << "Creating window..." << LL_ENDL;
-		mWindow = createNSWindow(x, y, width, height);
+		mWindow = getMainAppWindow();
 		LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL;
 		registerKeyDownCallback(mWindow, callKeyDown);
 		registerKeyUpCallback(mWindow, callKeyUp);
@@ -361,9 +360,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 	if(mContext == NULL)
 	{
 		LL_INFOS("Window") << "Creating GL view..." << LL_ENDL;
+		// Our OpenGL view is already defined within SecondLife.xib.
+		// Get the view instead.
 		mGLView = createOpenGLView(mWindow);
 		registerResizeEventCallback(mGLView, callResize);
-		mContext = getCGLContextObj(mWindow);
+		mContext = getCGLContextObj(mGLView);
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
 	}
@@ -577,132 +578,6 @@ void LLWindowMacOSX::gatherInput()
 		stopDockTileBounce();
 	}
 	
-	EventRecord evt;
-	while(WaitNextEvent(everyEvent, &evt, 0, NULL))
-	{
-		//			printf("WaitNextEvent returned true, event is %d.\n", evt.what);
-		switch(evt.what)
-		{
-			case mouseDown:
-			{
-				short part;
-				WindowRef window;
-				long selectResult;
-				part = FindWindow(evt.where, &window);
-				switch ( part )
-				{
-					case inMenuBar:
-						selectResult = MenuSelect(evt.where);
-						
-						HiliteMenu(0);
-						break;
-				}
-			}
-				break;
-				
-			case kHighLevelEvent:
-				AEProcessAppleEvent (&evt);
-				break;
-				
-			case updateEvt:
-				// We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly...
-				BeginUpdate((WindowRef)evt.message);
-				EndUpdate((WindowRef)evt.message);
-				break;
-				
-		}
-	}
-	/*
-	U32 event = getLatestEvent(mWindow);
-	switch (event) {
-		case 0:
-			// Nothing's happened since our last handled event.
-			break;
-			
-		case 1:
-		{
-			gKeyboard->handleKeyDown(getKeyDown(mWindow), getModifiers(mWindow));
-			mCallbacks->handleUnicodeChar(getLastCharacter(mWindow), gKeyboard->currentMask(FALSE)); // currentMask has the appropriately translated modifiers.
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-		}
-			break;
-			
-		case 2:
-			gKeyboard->handleKeyUp(getKeyUp(mWindow), getModifiers(mWindow));
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-			break;
-			
-		case 3:
-			break;
-			
-		case 4:
-		{
-			LLCoordScreen	inCoords;
-			LLCoordGL		outCoords;
-			float*			mouseCoords = getMouseDown(mWindow);
-			inCoords.mX = llround(mouseCoords[0]);
-			inCoords.mY = llround(mouseCoords[1]);
-			convertCoords(inCoords, &outCoords);
-			mCallbacks->handleMouseDown(this, outCoords, getModifiers(mWindow));
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-		}
-			break;
-		case 5:
-		{
-			LLCoordScreen	inCoords;
-			LLCoordGL		outCoords;
-			float*			mouseCoords = getMouseUp(mWindow);
-			inCoords.mX = llround(mouseCoords[0]);
-			inCoords.mY = llround(mouseCoords[1]);
-			convertCoords(inCoords, &outCoords);
-			mCallbacks->handleMouseUp(this, outCoords, getModifiers(mWindow));
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-		}
-			break;
-		case 6:
-		{
-			LLCoordScreen	inCoords;
-			LLCoordGL		outCoords;
-			float*			mouseCoords = getRightMouseDown(mWindow);
-			inCoords.mX = llround(mouseCoords[0]);
-			inCoords.mY = llround(mouseCoords[1]);
-			convertCoords(inCoords, &outCoords);
-			mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow));
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-		}
-			break;
-		case 7:
-		{
-			LLCoordScreen	inCoords;
-			LLCoordGL		outCoords;
-			float*			mouseCoords = getRightMouseDown(mWindow);
-			inCoords.mX = llround(mouseCoords[0]);
-			inCoords.mY = llround(mouseCoords[1]);
-			convertCoords(inCoords, &outCoords);
-			mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow));
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-		}
-			break;
-		case 8: // Double click
-		{
-			LLCoordScreen	inCoords;
-			LLCoordGL		outCoords;
-			float*			mouseCoords = getRightMouseDown(mWindow);
-			inCoords.mX = llround(mouseCoords[0]);
-			inCoords.mY = llround(mouseCoords[1]);
-			convertCoords(inCoords, &outCoords);
-			mCallbacks->handleDoubleClick(this, outCoords, getModifiers(mWindow));
-			mLastModifiers = gKeyboard->currentMask(FALSE);
-		}
-			break;
-		case 10: // Text input (for IMEs)
-			
-			break;
-		default:
-			break;
-			
-	}*/
-	
 	updateCursor();
 }
 
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index a821dcabd8..487af7658f 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -33,8 +33,6 @@
 
 #include "lltimer.h"
 
-//#include <Carbon/Carbon.h>
-//#include <AGL/agl.h>
 #include <ApplicationServices/ApplicationServices.h>
 #include <OpenGL/OpenGL.h>
 
-- 
cgit v1.2.3


From ddb48d51d996b18063b111faa3b7e709160074d9 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 1 Jan 2013 11:32:53 -0500
Subject: More things in this commit: - Removed the callback system in favor of
 simply defining functions in a header to later be implemented in whichever
 file is most convenient for what we want to do (i.e., calling LLWindow
 callbacks within LLWindowMacOSX, setting cursors in llwindowmacosx-objc.mm,
 etc.) - Viewer shutdown now works appropriately - Added a bit of debugging
 code to test if a key has been handled by the UI or not (useful for tracking
 down the mystery of the enter key not being handled) - Setup a cocoa quit
 handler within the application delegate that intercepts any termination
 requests

---
 indra/llwindow/llopenglview-objc.h    |  30 -----
 indra/llwindow/llopenglview-objc.mm   | 214 ++++++++++++----------------------
 indra/llwindow/llwindowmacosx-objc.h  |  38 +++---
 indra/llwindow/llwindowmacosx-objc.mm |  74 +++---------
 indra/llwindow/llwindowmacosx.cpp     |  73 +++++++++---
 indra/llwindow/llwindowmacosx.h       |   2 +-
 6 files changed, 170 insertions(+), 261 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 6b055bc665..20589e321d 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -15,7 +15,6 @@
 @interface LLOpenGLView : NSOpenGLView
 {
 	NSPoint mousePos;
-	ResizeCallback mResizeCallback;
 }
 
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
@@ -33,42 +32,13 @@
 - (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
 
 void setLLNSWindowRef(LLNSWindow* window);
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 7c148f4acd..cb8d7b315f 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -19,12 +19,9 @@
 
 - (void)windowResized:(NSNotification *)notification;
 {
-	if (mResizeCallback != nil)
-	{
-		NSSize size = [[self window] frame].size;
-		
-		mResizeCallback(size.width, size.height);
-	}
+	NSSize size = [self frame].size;
+	
+	callResize(size.width, size.height);
 }
 
 - (void)dealloc
@@ -125,11 +122,6 @@
 	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
 
@@ -183,6 +175,16 @@
 	[super flagsChanged:theEvent];
 }
 
+- (BOOL) becomeFirstResponder
+{
+	return [super becomeFirstResponder];
+}
+
+- (BOOL) resignFirstResponder
+{
+	return [super resignFirstResponder];
+}
+
 @end
 
 // We use a custom NSWindow for our event handling.
@@ -196,30 +198,19 @@
 	return self;
 }
 
-- (void) keyDown:(NSEvent *)theEvent {
-	if (mKeyDownCallback != nil && mUnicodeCallback != nil)
+- (void) keyDown:(NSEvent *)theEvent
+{
+	callKeyDown([theEvent keyCode], [theEvent modifierFlags]);
+	
+	NSString *chars = [theEvent characters];
+	for (uint i = 0; i < [chars length]; i++)
 	{
-		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]);
-		}
+		callUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]);
 	}
 }
 
 - (void) keyUp:(NSEvent *)theEvent {
-	if (mKeyUpCallback != nil)
-	{
-		mKeyUpCallback([theEvent keyCode], [theEvent modifierFlags]);
-	}
+	callKeyUp([theEvent keyCode], [theEvent modifierFlags]);
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
@@ -228,59 +219,42 @@
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
-	if (mMouseDoubleClickCallback != nil && mMouseDownCallback != nil)
+	if ([theEvent clickCount] >= 2)
 	{
-		if ([theEvent clickCount] == 2)
-		{
-			mMouseDoubleClickCallback(mMousePos, [theEvent modifierFlags]);
-		} else if ([theEvent clickCount] == 1) {
-			mMouseDownCallback(mMousePos, [theEvent modifierFlags]);
-		}
+		callDoubleClick(mMousePos, [theEvent modifierFlags]);
+	} else if ([theEvent clickCount] == 1) {
+		callLeftMouseDown(mMousePos, [theEvent modifierFlags]);
 	}
 }
 
 - (void) mouseUp:(NSEvent *)theEvent
 {
-	if (mMouseUpCallback != nil)
-	{
-		mMouseUpCallback(mMousePos, [theEvent modifierFlags]);
-	}
+	callLeftMouseUp(mMousePos, [theEvent modifierFlags]);
 }
 
 - (void) rightMouseDown:(NSEvent *)theEvent
 {
-	if (mRightMouseDownCallback != nil)
-	{
-		mRightMouseDownCallback(mMousePos, [theEvent modifierFlags]);
-	}
+	callRightMouseDown(mMousePos, [theEvent modifierFlags]);
 }
 
 - (void) rightMouseUp:(NSEvent *)theEvent
 {
-	if (mRightMouseUpCallback != nil)
-	{
-		mRightMouseUpCallback(mMousePos, [theEvent modifierFlags]);
-	}
+	callRightMouseUp(mMousePos, [theEvent modifierFlags]);
 }
 
-- (void)mouseMoved:(NSEvent *)theEvent {
-	if (mDeltaUpdateCallback != nil && mMouseMovedCallback != nil)
-	{
-		float mouseDeltas[2] = {
-			[theEvent deltaX],
-			[theEvent deltaZ]
-		};
-		
-		mDeltaUpdateCallback(mouseDeltas, 0);
-		
-		NSPoint mPoint = [theEvent locationInWindow];
-		mMousePos[0] = mPoint.x;
-		mMousePos[1] = mPoint.y;
-		if (mMouseMovedCallback != nil)
-		{
-			mMouseMovedCallback(mMousePos, 0);
-		}
-	}
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+	float mouseDeltas[2] = {
+		[theEvent deltaX],
+		[theEvent deltaY]
+	};
+	
+	callDeltaUpdate(mouseDeltas, 0);
+	
+	NSPoint mPoint = [theEvent locationInWindow];
+	mMousePos[0] = mPoint.x;
+	mMousePos[1] = mPoint.y;
+	callMouseMoved(mMousePos, 0);
 }
 
 // NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
@@ -288,101 +262,59 @@
 
 - (void) mouseDragged:(NSEvent *)theEvent
 {
-	if (mDeltaUpdateCallback != nil && mMouseMovedCallback != nil)
-	{
-		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
-{
-	if (mScrollWhellCallback != nil)
-	{
-		mScrollWhellCallback(-[theEvent deltaY]);
-	}
-}
-
-- (void) mouseExited:(NSEvent *)theEvent
-{
-	if (mMouseExitCallback != nil)
-	{
-		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;
+	// Trust the deltas supplied by NSEvent.
+	// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
+	// NSEvent isn't obsolete, and provides us with the correct deltas.
+	float mouseDeltas[2] = {
+		[theEvent deltaX],
+		[theEvent deltaY]
+	};
+	
+	callDeltaUpdate(mouseDeltas, 0);
+	
+	NSPoint mPoint = [theEvent locationInWindow];
+	mMousePos[0] = mPoint.x;
+	mMousePos[1] = mPoint.y;
+	callMouseMoved(mMousePos, 0);
 }
 
-- (void) registerRightMouseDownCallback:(MouseCallback)callback
+- (void) otherMouseDown:(NSEvent *)theEvent
 {
-	mRightMouseDownCallback = callback;
+	callMiddleMouseDown(mMousePos, 0);
 }
 
-- (void) registerRightMouseUpCallback:(MouseCallback)callback
+- (void) otherMouseUp:(NSEvent *)theEvent
 {
-	mRightMouseUpCallback = callback;
+	callMiddleMouseUp(mMousePos, 0);
 }
 
-- (void) registerDoubleClickCallback:(MouseCallback)callback
+- (void) otherMouseDragged:(NSEvent *)theEvent
 {
-	mMouseDoubleClickCallback = callback;
+	
 }
 
-- (void) registerMouseMovedCallback:(MouseCallback)callback
+- (void) scrollWheel:(NSEvent *)theEvent
 {
-	mMouseMovedCallback = callback;
+	callScrollMoved(-[theEvent deltaY]);
 }
 
-- (void) registerScrollCallback:(ScrollWheelCallback)callback
+- (void) mouseExited:(NSEvent *)theEvent
 {
-	mScrollWhellCallback = callback;
+	callMouseExit();
 }
 
-- (void) registerMouseExitCallback:(VoidCallback)callback
+- (BOOL) becomeFirstResponder
 {
-	mMouseExitCallback = callback;
+	NSLog(@"Window gained focus!");
+	callFocus();
+	return true;
 }
 
-- (void) registerDeltaUpdateCallback:(MouseCallback)callback
+- (BOOL) resignFirstResponder
 {
-	mDeltaUpdateCallback = callback;
+	NSLog(@"Window lost focus!");
+	callFocus();
+	return true;
 }
 
 @end
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index abaeda1f91..655d63ac12 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -65,21 +65,33 @@ void getCursorPos(NSWindowRef window, float* pos);
 void makeWindowOrderFront(NSWindowRef window);
 void convertScreenToWindow(NSWindowRef window, float *coord);
 void convertWindowToScreen(NSWindowRef window, float *coord);
+void convertScreenToView(NSWindowRef window, float *coord);
 void setWindowPos(NSWindowRef window, float* pos);
+void closeWindow(NSWindowRef window);
+void removeGLView(GLViewRef view);
+
+// These are all implemented in llwindowmacosx.cpp.
+// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
+void callKeyUp(unsigned short key, unsigned int mask);
+void callKeyDown(unsigned short key, unsigned int mask);
+void callUnicodeCallback(wchar_t character, unsigned int mask);
+void callRightMouseDown(float *pos, unsigned int mask);
+void callRightMouseUp(float *pos, unsigned int mask);
+void callLeftMouseDown(float *pos, unsigned int mask);
+void callLeftMouseUp(float *pos, unsigned int mask);
+void callDoubleClick(float *pos, unsigned int mask);
+void callResize(unsigned int width, unsigned int height);
+void callMouseMoved(float *pos, unsigned int mask);
+void callScrollMoved(float delta);
+void callMouseExit();
+void callWindowFocus();
+void callWindowUnfocus();
+void callDeltaUpdate(float *delta, unsigned int mask);
+void callMiddleMouseDown(float *pos, unsigned int mask);
+void callMiddleMouseUp(float *pos, unsigned int mask);
+void callFocus();
+void callFocusLost();
 
-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);
 NSWindowRef getMainAppWindow();
 GLViewRef getGLView(NSWindowRef window);
 
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 07efc25ea6..f3972303f1 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -255,6 +255,15 @@ void convertScreenToWindow(NSWindowRef window, float *coord)
 	coord[1] = point.y;
 }
 
+void convertScreenToView(NSWindowRef window, float *coord)
+{
+	NSRect point;
+	point.origin.x = coord[0];
+	point.origin.y = coord[1];
+	point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin];
+	point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil];
+}
+
 void convertWindowToScreen(NSWindowRef window, float *coord)
 {
 	NSPoint point;
@@ -265,73 +274,20 @@ void convertWindowToScreen(NSWindowRef window, float *coord)
 	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)
+void closeWindow(NSWindowRef window)
 {
-	[(LLNSWindow*)window registerMouseExitCallback:callback];
+	[(LLNSWindow*)window close];
 }
 
-void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback)
+void removeGLView(GLViewRef view)
 {
-	[(LLNSWindow*)window registerDeltaUpdateCallback:callback];
+	[(LLOpenGLView*)view removeFromSuperview];
+	[(LLOpenGLView*)view release];
 }
 
 NSWindowRef getMainAppWindow()
 {
+	[(LLNSWindow*)winRef setAcceptsMouseMovedEvents:TRUE];
 	return winRef;
 }
 
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index a616b2df2d..cfdfbe2138 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -198,7 +198,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	
 }
 
-// These functions are used as callbacks for event handling within Cocoa.
+// These functions are used as wrappers for our internal event handling callbacks.
 // It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow.
 
 void callKeyUp(unsigned short key, unsigned int mask)
@@ -216,9 +216,14 @@ void callUnicodeCallback(wchar_t character, unsigned int mask)
 	gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
 }
 
-void callModifierCallback(unsigned int mask)
+void callFocus()
 {
-	
+	gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
+}
+
+void callFocusLost()
+{
+	gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
 }
 
 void callRightMouseDown(float *pos, MASK mask)
@@ -302,17 +307,41 @@ void callWindowUnfocus()
 
 void callDeltaUpdate(float *delta, MASK mask)
 {
-	gWindowImplementation->updateMouseDeltas();
+	gWindowImplementation->updateMouseDeltas(delta);
+}
+
+void callMiddleMouseDown(float *pos, MASK mask)
+{
+	LLCoordGL		outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	float deltas[2];
+	gWindowImplementation->getMouseDeltas(deltas);
+	outCoords.mX += deltas[0];
+	outCoords.mY += deltas[1];
+	gWindowImplementation->getCallbacks()->handleMiddleMouseDown(gWindowImplementation, outCoords, mask);
+}
+
+void callMiddleMouseUp(float *pos, MASK mask)
+{
+	LLCoordGL outCoords;
+	outCoords.mX = llround(pos[0]);
+	outCoords.mY = llround(pos[1]);
+	float deltas[2];
+	gWindowImplementation->getMouseDeltas(deltas);
+	outCoords.mX += deltas[0];
+	outCoords.mY += deltas[1];
+	gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask);
 }
 
-void LLWindowMacOSX::updateMouseDeltas()
+void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 {
 	if (mCursorDecoupled)
 	{
-		CGMouseDelta x, y;
-		CGGetLastMouseDelta( &x, &y );
-		mCursorLastEventDeltaX = x;
-		mCursorLastEventDeltaY = y;
+		mCursorLastEventDeltaX = llround(deltas[0]);
+		mCursorLastEventDeltaY = llround(-deltas[1]);
+		
+		
 		
 		if (mCursorIgnoreNextDelta)
 		{
@@ -320,6 +349,7 @@ void LLWindowMacOSX::updateMouseDeltas()
 			mCursorLastEventDeltaY = 0;
 			mCursorIgnoreNextDelta = FALSE;
 		}
+		LL_INFOS("Delta Update") << "Last event delta: " << mCursorLastEventDeltaX << ", " << mCursorLastEventDeltaY << LL_ENDL;
 	} else {
 		mCursorLastEventDeltaX = 0;
 		mCursorLastEventDeltaY = 0;
@@ -342,6 +372,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 	{
 		LL_INFOS("Window") << "Creating window..." << LL_ENDL;
 		mWindow = getMainAppWindow();
+		/*
 		LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL;
 		registerKeyDownCallback(mWindow, callKeyDown);
 		registerKeyUpCallback(mWindow, callKeyUp);
@@ -355,6 +386,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		registerScrollCallback(mWindow, callScrollMoved);
 		registerDeltaUpdateCallback(mWindow, callDeltaUpdate);
 		registerMouseExitCallback(mWindow, callMouseExit);
+		 */
 	}
 
 	if(mContext == NULL)
@@ -363,7 +395,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		// Our OpenGL view is already defined within SecondLife.xib.
 		// Get the view instead.
 		mGLView = createOpenGLView(mWindow);
-		registerResizeEventCallback(mGLView, callResize);
+		//registerResizeEventCallback(mGLView, callResize);
 		mContext = getCGLContextObj(mGLView);
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
@@ -439,9 +471,7 @@ void LLWindowMacOSX::destroyContext()
 	if(mContext != NULL)
 	{
 		LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL;
-
 		CGLSetCurrentContext(NULL);
-		mContext = NULL;
 	}
 
 	// Clean up remaining GL state before blowing away window
@@ -454,16 +484,25 @@ void LLWindowMacOSX::destroyContext()
 		mPixelFormat = NULL;
 	}
 
-	// Close the window
-	if(mWindow != NULL)
-	{
-	}
-
 	// Clean up the GL context
 	if(mContext != NULL)
 	{
 		CGLDestroyContext(mContext);
 	}
+	
+	// Destroy our LLOpenGLView
+	if(mGLView != NULL)
+	{
+		removeGLView(mGLView);
+		mGLView = NULL;
+	}
+	
+	// Close the window
+	if(mWindow != NULL)
+	{
+		closeWindow(mWindow);
+		mWindow = NULL;
+	}
 
 }
 
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 487af7658f..c5e1b2290b 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -121,7 +121,7 @@ public:
 	void* getWindow() { return mWindow; }
 	LLWindowCallbacks* getCallbacks() { return mCallbacks; }
 	
-	void updateMouseDeltas();
+	void updateMouseDeltas(float* deltas);
 	void getMouseDeltas(float* delta);
 
 
-- 
cgit v1.2.3


From 2b0f50dd821848d18ab35095623c3bdbcdeb910c Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Wed, 2 Jan 2013 15:57:21 -0500
Subject: Crash on exit fix + general code cleanup in LLWindowMacOSX.

---
 indra/llwindow/llwindowmacosx.cpp | 21 ++-------------------
 1 file changed, 2 insertions(+), 19 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index cfdfbe2138..cc0959edf8 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -283,6 +283,7 @@ void callMouseMoved(float *pos, MASK mask)
 	outCoords.mX += deltas[0];
 	outCoords.mY += deltas[1];
 	gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+	
 }
 
 void callScrollMoved(float delta)
@@ -339,9 +340,7 @@ void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 	if (mCursorDecoupled)
 	{
 		mCursorLastEventDeltaX = llround(deltas[0]);
-		mCursorLastEventDeltaY = llround(-deltas[1]);
-		
-		
+		mCursorLastEventDeltaY = llround(deltas[1]);
 		
 		if (mCursorIgnoreNextDelta)
 		{
@@ -372,21 +371,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 	{
 		LL_INFOS("Window") << "Creating window..." << LL_ENDL;
 		mWindow = getMainAppWindow();
-		/*
-		LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL;
-		registerKeyDownCallback(mWindow, callKeyDown);
-		registerKeyUpCallback(mWindow, callKeyUp);
-		registerUnicodeCallback(mWindow, callUnicodeCallback);
-		registerMouseDownCallback(mWindow, callLeftMouseDown);
-		registerMouseUpCallback(mWindow, callLeftMouseUp);
-		registerRightMouseDownCallback(mWindow, callRightMouseDown);
-		registerRightMouseUpCallback(mWindow, callRightMouseUp);
-		registerDoubleClickCallback(mWindow, callDoubleClick);
-		registerMouseMovedCallback(mWindow, callMouseMoved);
-		registerScrollCallback(mWindow, callScrollMoved);
-		registerDeltaUpdateCallback(mWindow, callDeltaUpdate);
-		registerMouseExitCallback(mWindow, callMouseExit);
-		 */
 	}
 
 	if(mContext == NULL)
@@ -395,7 +379,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		// Our OpenGL view is already defined within SecondLife.xib.
 		// Get the view instead.
 		mGLView = createOpenGLView(mWindow);
-		//registerResizeEventCallback(mGLView, callResize);
 		mContext = getCGLContextObj(mGLView);
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
-- 
cgit v1.2.3


From 9ce3ab1a5248423eeea4d843bfb8407ed62b305e Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Wed, 2 Jan 2013 18:53:44 -0500
Subject: Fixed the enter and return keys not being sent appropriately as
 unicode characters.

---
 indra/llwindow/llkeyboardmacosx.cpp   |  2 +-
 indra/llwindow/llopenglview-objc.mm   | 14 +++++++++++++-
 indra/llwindow/llwindowmacosx-objc.h  |  2 +-
 indra/llwindow/llwindowmacosx-objc.mm |  2 +-
 indra/llwindow/llwindowmacosx.cpp     |  5 ++++-
 5 files changed, 20 insertions(+), 5 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 3f357c600e..077ebea909 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -206,7 +206,7 @@ MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
 		out_mask |= MASK_SHIFT;
 	}
 
-	if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
+	if(mask & MAC_CTRL_KEY || mask & MAC_CMD_KEY)
 	{
 		out_mask |= MASK_CONTROL;
 	}
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index cb8d7b315f..e5e198b856 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -30,6 +30,11 @@
 	[super dealloc];
 }
 
+- (id) init
+{
+	return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
+}
+
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
 {
 	
@@ -205,7 +210,14 @@
 	NSString *chars = [theEvent characters];
 	for (uint i = 0; i < [chars length]; i++)
 	{
-		callUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]);
+		// Enter and Return are special cases.
+		unichar returntest = [chars characterAtIndex:i];
+		if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) && !([theEvent modifierFlags] & NSCommandKeyMask) && !([theEvent modifierFlags] & NSAlternateKeyMask) && !([theEvent modifierFlags] & NSControlKeyMask))
+		{
+			callUnicodeCallback(returntest, 0);
+		} else {
+			callUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]);
+		}
 	}
 }
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 655d63ac12..414491f948 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -93,6 +93,6 @@ void callFocus();
 void callFocusLost();
 
 NSWindowRef getMainAppWindow();
-GLViewRef getGLView(NSWindowRef window);
+GLViewRef getGLView();
 
 unsigned int getModifiers();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index f3972303f1..5a024eda46 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -291,7 +291,7 @@ NSWindowRef getMainAppWindow()
 	return winRef;
 }
 
-GLViewRef getGLView(NSWindowRef window)
+GLViewRef getGLView()
 {
 	return glviewRef;
 }
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index cc0959edf8..902391e170 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -270,7 +270,10 @@ void callDoubleClick(float *pos, MASK mask)
 
 void callResize(unsigned int width, unsigned int height)
 {
-	gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height);
+	if (gWindowImplementation != NULL)
+	{
+		gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height);
+	}
 }
 
 void callMouseMoved(float *pos, MASK mask)
-- 
cgit v1.2.3


From 09b07e3619a71f142c1a3af41244d756e1230142 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 8 Jan 2013 16:22:54 -0500
Subject: Big change set: - LLAppDelegate header relocated to LLWindow. 
 Definition is still present in secondlife-bin (for compatibility reasons when
 loading a nib). - Return key handling fixed. - Command key now acts the same
 as the control key by issuing control character codes when the command key is
 pressed. - We now retrieve the window pointer directly from the app delegate
 in LLWindow.

---
 indra/llwindow/CMakeLists.txt         |   1 +
 indra/llwindow/llappdelegate-objc.h   |  22 +++++++
 indra/llwindow/llkeyboardmacosx.cpp   |  35 +++--------
 indra/llwindow/llopenglview-objc.h    |   5 --
 indra/llwindow/llopenglview-objc.mm   | 113 +++++++++++++++++++++++-----------
 indra/llwindow/llwindowmacosx-objc.h  |  11 ++++
 indra/llwindow/llwindowmacosx-objc.mm |  56 ++++++++++++-----
 indra/llwindow/llwindowmacosx.cpp     |  22 ++++---
 8 files changed, 172 insertions(+), 93 deletions(-)
 create mode 100644 indra/llwindow/llappdelegate-objc.h

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 8a38db751e..84e0169826 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -82,6 +82,7 @@ if (DARWIN)
     llwindowmacosx.h
     llwindowmacosx-objc.h
     llopenglview-objc.h
+    llappdelegate-objc.h
     )
 
   # We use a bunch of deprecated system APIs.
diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
new file mode 100644
index 0000000000..56b7a30797
--- /dev/null
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -0,0 +1,22 @@
+//
+//  LLAppDelegate.h
+//  SecondLife
+//
+//  Created by Geenz on 12/16/12.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+#import "llopenglview-objc.h"
+#include "llwindowmacosx-objc.h"
+
+@interface LLAppDelegate : NSObject <NSApplicationDelegate> {
+	LLNSWindow *window;
+	NSTimer *frameTimer;
+}
+
+@property (assign) IBOutlet LLNSWindow *window;
+
+- (void) mainLoop;
+
+@end
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 077ebea909..3db94e8835 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -167,13 +167,15 @@ void LLKeyboardMacOSX::resetMaskKeys()
 	// 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?
+	
+	// We apply the modifier masks directly within getModifiers.  So check to see which masks we've applied.
 
 	if(mask & MAC_SHIFT_KEY)
 	{
 		mKeyLevel[KEY_SHIFT] = TRUE;
 	}
 
-	if(mask & (MAC_CTRL_KEY))
+	if(mask & MAC_CTRL_KEY)
 	{
 		mKeyLevel[KEY_CONTROL] = TRUE;
 	}
@@ -198,25 +200,9 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out
 
 MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
 {
-	// translate the mask
-	MASK out_mask = 0;
-
-	if(mask & MAC_SHIFT_KEY)
-	{
-		out_mask |= MASK_SHIFT;
-	}
-
-	if(mask & MAC_CTRL_KEY || mask & MAC_CMD_KEY)
-	{
-		out_mask |= MASK_CONTROL;
-	}
-
-	if(mask & MAC_ALT_KEY)
-	{
-		out_mask |= MASK_ALT;
-	}
-
-	return out_mask;
+	// This is handled for us in LLNSWindow on OS X.
+	
+	return mask;
 }
 
 BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
@@ -231,12 +217,7 @@ 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;
 }
 
@@ -272,7 +253,7 @@ MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
 		if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
 	}
 
-	return result;
+	return mask;
 }
 
 void LLKeyboardMacOSX::scanKeyboard()
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 20589e321d..8412621392 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -40,8 +40,3 @@
 }
 
 @end
-
-void setLLNSWindowRef(LLNSWindow* window);
-void setLLOpenGLViewRef(LLOpenGLView* view);
-LLNSWindow* winRef;
-LLOpenGLView* glviewRef;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index e5e198b856..d91601152b 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -132,62 +132,72 @@
 
 - (void) mouseDragged:(NSEvent *)theEvent
 {
-	[super mouseDragged:theEvent];
+	[_window mouseDragged:theEvent];
 }
 
 - (void) scrollWheel:(NSEvent *)theEvent
 {
-	[super scrollWheel:theEvent];
+	[_window scrollWheel:theEvent];
 }
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
-	[super mouseDown:theEvent];
+	[_window mouseDown:theEvent];
 }
 
 - (void) mouseUp:(NSEvent *)theEvent
 {
-	[super mouseUp:theEvent];
+	[_window mouseUp:theEvent];
 }
 
 - (void) rightMouseDown:(NSEvent *)theEvent
 {
-	[super rightMouseDown:theEvent];
+	[_window rightMouseDown:theEvent];
 }
 
 - (void) rightMouseUp:(NSEvent *)theEvent
 {
-	[super rightMouseUp:theEvent];
+	[_window rightMouseUp:theEvent];
+}
+
+- (void) otherMouseDown:(NSEvent *)theEvent
+{
+	[_window otherMouseDown:theEvent];
+}
+
+- (void) otherMouseUp:(NSEvent *)theEvent
+{
+	[_window otherMouseUp:theEvent];
 }
 
 - (void) keyUp:(NSEvent *)theEvent
 {
-	[super keyUp:theEvent];
+	[_window keyUp:theEvent];
 }
 
 - (void) keyDown:(NSEvent *)theEvent
 {
-	[super keyDown:theEvent];
+	[_window keyDown:theEvent];
 }
 
 - (void) mouseMoved:(NSEvent *)theEvent
 {
-	[super mouseMoved:theEvent];
+	[_window mouseMoved:theEvent];
 }
 
 - (void) flagsChanged:(NSEvent *)theEvent
 {
-	[super flagsChanged:theEvent];
+	[_window flagsChanged:theEvent];
 }
 
 - (BOOL) becomeFirstResponder
 {
-	return [super becomeFirstResponder];
+	return [_window becomeFirstResponder];
 }
 
 - (BOOL) resignFirstResponder
 {
-	return [super resignFirstResponder];
+	return [_window resignFirstResponder];
 }
 
 @end
@@ -200,58 +210,99 @@
 
 - (id) init
 {
+	//[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType, nil]];
 	return self;
 }
 
 - (void) keyDown:(NSEvent *)theEvent
 {
-	callKeyDown([theEvent keyCode], [theEvent modifierFlags]);
-	
+	callKeyDown([theEvent keyCode], mModifiers);
 	NSString *chars = [theEvent characters];
 	for (uint i = 0; i < [chars length]; i++)
 	{
 		// Enter and Return are special cases.
 		unichar returntest = [chars characterAtIndex:i];
-		if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) && !([theEvent modifierFlags] & NSCommandKeyMask) && !([theEvent modifierFlags] & NSAlternateKeyMask) && !([theEvent modifierFlags] & NSControlKeyMask))
+		if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) &&
+			!([theEvent modifierFlags] & NSCommandKeyMask) &&
+			!([theEvent modifierFlags] & NSAlternateKeyMask) &&
+			!([theEvent modifierFlags] & NSControlKeyMask))
 		{
-			callUnicodeCallback(returntest, 0);
+			callUnicodeCallback(13, 0);
 		} else {
-			callUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]);
+			// The command key being pressed is also a special case.
+			// Control + <character> produces an ASCII control character code.
+			// Command + <character> produces just the character's code.
+			// Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range.
+			if ([theEvent modifierFlags] & NSCommandKeyMask)
+			{
+				if (returntest >= 64 && returntest <= 95)
+				{
+					callUnicodeCallback(returntest - 63, mModifiers);
+				} else if (returntest >= 97 && returntest <= 122)
+				{
+					callUnicodeCallback(returntest - 96, mModifiers);
+				}
+			} else {
+				callUnicodeCallback(returntest, mModifiers);
+			}
 		}
 	}
 }
 
 - (void) keyUp:(NSEvent *)theEvent {
-	callKeyUp([theEvent keyCode], [theEvent modifierFlags]);
+	callKeyUp([theEvent keyCode], mModifiers);
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
-	mModifiers = [theEvent modifierFlags];
+	uint modifiers = [theEvent modifierFlags];
+	
+	// Filter through our modifier keys, and only pick out the ones we care about.
+	
+	mModifiers = 0;
+	if (modifiers & NSCommandKeyMask)
+	{
+		mModifiers |= 0x0001;
+	}
+	
+	if (modifiers & NSAlternateKeyMask)
+	{
+		mModifiers |= 0x0002;
+	}
+	
+	if (modifiers & NSShiftKeyMask)
+	{
+		mModifiers |= 0x0004;
+	}
+	
+	if (modifiers & NSControlKeyMask)
+	{
+		mModifiers |= 0x0001;
+	}
 }
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
 	if ([theEvent clickCount] >= 2)
 	{
-		callDoubleClick(mMousePos, [theEvent modifierFlags]);
+		callDoubleClick(mMousePos, mModifiers);
 	} else if ([theEvent clickCount] == 1) {
-		callLeftMouseDown(mMousePos, [theEvent modifierFlags]);
+		callLeftMouseDown(mMousePos, mModifiers);
 	}
 }
 
 - (void) mouseUp:(NSEvent *)theEvent
 {
-	callLeftMouseUp(mMousePos, [theEvent modifierFlags]);
+	callLeftMouseUp(mMousePos, mModifiers);
 }
 
 - (void) rightMouseDown:(NSEvent *)theEvent
 {
-	callRightMouseDown(mMousePos, [theEvent modifierFlags]);
+	callRightMouseDown(mMousePos, mModifiers);
 }
 
 - (void) rightMouseUp:(NSEvent *)theEvent
 {
-	callRightMouseUp(mMousePos, [theEvent modifierFlags]);
+	callRightMouseUp(mMousePos, mModifiers);
 }
 
 - (void)mouseMoved:(NSEvent *)theEvent
@@ -292,12 +343,12 @@
 
 - (void) otherMouseDown:(NSEvent *)theEvent
 {
-	callMiddleMouseDown(mMousePos, 0);
+	callMiddleMouseDown(mMousePos, mModifiers);
 }
 
 - (void) otherMouseUp:(NSEvent *)theEvent
 {
-	callMiddleMouseUp(mMousePos, 0);
+	callMiddleMouseUp(mMousePos, mModifiers);
 }
 
 - (void) otherMouseDragged:(NSEvent *)theEvent
@@ -330,13 +381,3 @@
 }
 
 @end
-
-void setLLNSWindowRef(LLNSWindow* window)
-{
-	winRef = window;
-}
-
-void setLLOpenGLViewRef(LLOpenGLView* view)
-{
-	glviewRef = view;
-}
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 414491f948..57b3d11296 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -38,8 +38,19 @@ typedef void *CursorRef;
 typedef void *NSWindowRef;
 typedef void *GLViewRef;
 
+// These are defined in llappviewermacosx.cpp.
+bool initViewer();
+void handleQuit();
+bool runMainLoop();
+void initMainLoop();
+void cleanupViewer();
+
 /* Defined in llwindowmacosx-objc.mm: */
+int createNSApp(int argc, const char **argv);
 void setupCocoa();
+bool pasteBoardAvailable();
+bool copyToPBoard(const unsigned short *str, unsigned int len);
+const unsigned short *copyFromPBoard();
 CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
 short releaseImageCursor(CursorRef ref);
 short setImageCursor(CursorRef ref);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 5a024eda46..1a64c94b2d 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -29,6 +29,7 @@
 #include <Cocoa/Cocoa.h>
 #include "llwindowmacosx-objc.h"
 #include "llopenglview-objc.h"
+#include "llappdelegate-objc.h"
 
 /*
  * These functions are broken out into a separate file because the
@@ -37,6 +38,11 @@
  * linden headers with any objective-C++ source.
  */
 
+int createNSApp(int argc, const char *argv[])
+{
+	return NSApplicationMain(argc, argv);
+}
+
 void setupCocoa()
 {
 	static bool inited = false;
@@ -49,15 +55,6 @@ void setupCocoa()
 		// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' 
 		// when init'ing the Cocoa App window.		
 		[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
-		
-		// This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
-		//   http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
-		
-		//	Needed for Carbon based applications which call into Cocoa
-		// NSApplicationLoad();
-
-		//	Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
-		//[[[NSWindow alloc] init] release];
 
 		[pool release];
 		
@@ -65,6 +62,38 @@ void setupCocoa()
 	}
 }
 
+bool copyToPBoard(const unsigned short *str, unsigned int len)
+{
+	NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+	[pboard clearContents];
+	
+	NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
+	
+	return [pboard writeObjects:contentsToPaste];
+}
+
+bool pasteBoardAvailable()
+{
+	NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+	return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
+}
+
+const unsigned short *copyFromPBoard()
+{
+	NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+	NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+	NSString *str = NULL;
+	BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
+	if (ok)
+	{
+		NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
+		str = [objToPaste objectAtIndex:0];
+	}
+	unichar* temp = (unichar*)calloc([str length], sizeof(unichar));
+	[str getCharacters:temp];
+	return temp;
+}
+
 CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
 {
 	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -287,15 +316,12 @@ void removeGLView(GLViewRef view)
 
 NSWindowRef getMainAppWindow()
 {
-	[(LLNSWindow*)winRef setAcceptsMouseMovedEvents:TRUE];
+	LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
+	
+	[winRef setAcceptsMouseMovedEvents:TRUE];
 	return winRef;
 }
 
-GLViewRef getGLView()
-{
-	return glviewRef;
-}
-
 unsigned int getModifiers()
 {
 	return [NSEvent modifierFlags];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 902391e170..93b9f4c484 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1029,25 +1029,27 @@ void LLWindowMacOSX::flashIcon(F32 seconds)
 
 BOOL LLWindowMacOSX::isClipboardTextAvailable()
 {
-	BOOL result = false;
-	// TODO: Clipboard support.
-	return result;
+	return pasteBoardAvailable();
 }
 
 BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
-{
-	BOOL result = false;
-	
-	// TODO: Clipboard support.
-
-	return result;
+{	
+	llutf16string str(copyFromPBoard());
+	dst = utf16str_to_wstring(str);
+	if (dst != L"")
+	{
+		return true;
+	} else {
+		return false;
+	}
 }
 
 BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s)
 {
 	BOOL result = false;
+	llutf16string utf16str = wstring_to_utf16str(s);
 	
-	// TODO: Clipboard support.
+	result = copyToPBoard(utf16str.data(), utf16str.length());
 
 	return result;
 }
-- 
cgit v1.2.3


From da90fe352847d5f27358179cb4cdf88abc40a4af Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 15 Jan 2013 05:46:31 -0500
Subject: This *should* put an end to our modifier key woes.

---
 indra/llwindow/llkeyboardmacosx.cpp | 27 ++++++++++++++++++++++-----
 indra/llwindow/llopenglview-objc.mm | 31 +++++++------------------------
 2 files changed, 29 insertions(+), 29 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 3db94e8835..59cc2acaec 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -200,9 +200,25 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out
 
 MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
 {
-	// This is handled for us in LLNSWindow on OS X.
-	
-	return mask;
+	// translate the mask
+	MASK out_mask = 0;
+
+	if(mask & MAC_SHIFT_KEY)
+	{
+		out_mask |= MASK_SHIFT;
+	}
+
+	if(mask & MAC_CTRL_KEY || mask & MAC_CMD_KEY)
+	{
+		out_mask |= MASK_CONTROL;
+	}
+
+	if(mask & MAC_ALT_KEY)
+	{
+		out_mask |= MASK_ALT;
+	}
+
+	return out_mask;
 }
 
 BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
@@ -232,6 +248,7 @@ BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
 
 	if(translateNumpadKey(key, &translated_key))
 	{
+		LL_INFOS("Keyboard") << "Handled key!" << LL_ENDL;
 		handled = handleTranslatedKeyUp(translated_key, translated_mask);
 	}
 
@@ -252,8 +269,8 @@ MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
 	{
 		if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
 	}
-
-	return mask;
+	
+	return result;
 }
 
 void LLKeyboardMacOSX::scanKeyboard()
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index d91601152b..25669b25d3 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -190,6 +190,11 @@
 	[_window flagsChanged:theEvent];
 }
 
+- (void) mouseExited:(NSEvent *)theEvent
+{
+	[_window mouseExited:theEvent];
+}
+
 - (BOOL) becomeFirstResponder
 {
 	return [_window becomeFirstResponder];
@@ -217,6 +222,7 @@
 - (void) keyDown:(NSEvent *)theEvent
 {
 	callKeyDown([theEvent keyCode], mModifiers);
+	NSLog(@"Keycode: %hu", [theEvent keyCode]);
 	NSString *chars = [theEvent characters];
 	for (uint i = 0; i < [chars length]; i++)
 	{
@@ -254,30 +260,7 @@
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
-	uint modifiers = [theEvent modifierFlags];
-	
-	// Filter through our modifier keys, and only pick out the ones we care about.
-	
-	mModifiers = 0;
-	if (modifiers & NSCommandKeyMask)
-	{
-		mModifiers |= 0x0001;
-	}
-	
-	if (modifiers & NSAlternateKeyMask)
-	{
-		mModifiers |= 0x0002;
-	}
-	
-	if (modifiers & NSShiftKeyMask)
-	{
-		mModifiers |= 0x0004;
-	}
-	
-	if (modifiers & NSControlKeyMask)
-	{
-		mModifiers |= 0x0001;
-	}
+	mModifiers = [theEvent modifierFlags];
 }
 
 - (void) mouseDown:(NSEvent *)theEvent
-- 
cgit v1.2.3


From 1bbbaf8dd69a08a3e7c570e6ad14f57a4f6e91cb Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Fri, 18 Jan 2013 13:16:12 -0500
Subject: Partial workaround for mouse delta issue.

---
 indra/llwindow/llwindowmacosx.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 93b9f4c484..95ad87d58f 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -285,8 +285,9 @@ void callMouseMoved(float *pos, MASK mask)
 	gWindowImplementation->getMouseDeltas(deltas);
 	outCoords.mX += deltas[0];
 	outCoords.mY += deltas[1];
+	LL_INFOS("Mouse Movement") << "Moved coords: " << outCoords.mX << ", " << outCoords.mY << LL_ENDL;
 	gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
-	
+	gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
 }
 
 void callScrollMoved(float delta)
@@ -343,7 +344,7 @@ void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 	if (mCursorDecoupled)
 	{
 		mCursorLastEventDeltaX = llround(deltas[0]);
-		mCursorLastEventDeltaY = llround(deltas[1]);
+		mCursorLastEventDeltaY = llround(-deltas[1]);
 		
 		if (mCursorIgnoreNextDelta)
 		{
@@ -351,7 +352,6 @@ void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 			mCursorLastEventDeltaY = 0;
 			mCursorIgnoreNextDelta = FALSE;
 		}
-		LL_INFOS("Delta Update") << "Last event delta: " << mCursorLastEventDeltaX << ", " << mCursorLastEventDeltaY << LL_ENDL;
 	} else {
 		mCursorLastEventDeltaX = 0;
 		mCursorLastEventDeltaY = 0;
@@ -738,7 +738,7 @@ void LLWindowMacOSX::swapBuffers()
 
 F32 LLWindowMacOSX::getGamma()
 {
-	F32 result = 1.8;	// Default to something sane
+	F32 result = 2.2;	// Default to something sane
 
 	CGGammaValue redMin;
 	CGGammaValue redMax;
-- 
cgit v1.2.3


From 29e747c4f17818816c502a3aa653b828e689be4a Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 22 Jan 2013 15:37:01 -0500
Subject: And thus, the demonic mouse position conversions from view space to
 screen space were tamed.

---
 indra/llwindow/llopenglview-objc.h    | 22 +++++++++++++++
 indra/llwindow/llopenglview-objc.mm   | 50 +++++++++++++++++++++++++++++++++++
 indra/llwindow/llwindowmacosx-objc.mm |  2 +-
 3 files changed, 73 insertions(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 8412621392..dd2f35aafc 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -39,4 +39,26 @@
 	unsigned int mModifiers;
 }
 
+- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
+- (NSPoint)flipPoint:(NSPoint)aPoint;
+
+@end
+
+@interface NSScreen (PointConversion)
+
+/*
+ Returns the screen where the mouse resides
+ */
++ (NSScreen *)currentScreenForMouseLocation;
+
+/*
+ Allows you to convert a point from global coordinates to the current screen coordinates.
+ */
+- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint;
+
+/*
+ Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same
+ */
+- (NSPoint)flipPoint:(NSPoint)aPoint;
+
 @end
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 25669b25d3..ca66143b78 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -8,6 +8,35 @@
 
 #import "llopenglview-objc.h"
 
+@implementation NSScreen (PointConversion)
+
++ (NSScreen *)currentScreenForMouseLocation
+{
+    NSPoint mouseLocation = [NSEvent mouseLocation];
+    
+    NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
+    NSScreen *screen;
+    while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO))
+        ;
+    
+    return screen;
+}
+
+- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
+{
+    float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
+    float normalizedY = aPoint.y - self.frame.origin.y;
+    
+    return NSMakePoint(normalizedX, normalizedY);
+}
+
+- (NSPoint)flipPoint:(NSPoint)aPoint
+{
+    return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
+}
+
+@end
+
 @implementation LLOpenGLView
 
 - (void)viewDidMoveToWindow
@@ -349,6 +378,27 @@
 	callMouseExit();
 }
 
+- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
+{
+	NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
+	if(currentScreen)
+	{
+		NSPoint windowPoint = [view convertPoint:point toView:nil];
+		NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
+		NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint];
+		flippedScreenPoint.y += [currentScreen frame].origin.y;
+		
+		return flippedScreenPoint;
+	}
+	
+	return NSZeroPoint;
+}
+
+- (NSPoint)flipPoint:(NSPoint)aPoint
+{
+    return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
+}
+
 - (BOOL) becomeFirstResponder
 {
 	NSLog(@"Window gained focus!");
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 1a64c94b2d..b6e5767203 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -298,7 +298,7 @@ void convertWindowToScreen(NSWindowRef window, float *coord)
 	NSPoint point;
 	point.x = coord[0];
 	point.y = coord[1];
-	point = [(LLNSWindow*)window convertBaseToScreen:point];
+	point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]];
 	coord[0] = point.x;
 	coord[1] = point.y;
 }
-- 
cgit v1.2.3


From 461ab912a58b67579fffdf70ec7e38d682927185 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 22 Jan 2013 19:59:49 -0500
Subject: Initial Cocoa drag and drop support.

---
 indra/llwindow/llopenglview-objc.h    |   1 +
 indra/llwindow/llopenglview-objc.mm   |  50 ++++++++-
 indra/llwindow/llwindowmacosx-objc.h  |  15 ++-
 indra/llwindow/llwindowmacosx-objc.mm |   6 ++
 indra/llwindow/llwindowmacosx.cpp     | 186 +++++++++++++---------------------
 indra/llwindow/llwindowmacosx.h       |  16 +--
 6 files changed, 143 insertions(+), 131 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index dd2f35aafc..1592e6e01d 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -15,6 +15,7 @@
 @interface LLOpenGLView : NSOpenGLView
 {
 	NSPoint mousePos;
+	std::string mLastDraggedUrl;
 }
 
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index ca66143b78..763cf0c981 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -61,12 +61,13 @@
 
 - (id) init
 {
+	//[self registerForDraggedTypes:[NSArray arrayWithObjects:NSURLPboardType, NSFilenamesPboardType, nil]];
 	return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
 }
 
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
 {
-	
+	[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
 	[self initWithFrame:frame];
 	
 	// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
@@ -234,6 +235,49 @@
 	return [_window resignFirstResponder];
 }
 
+- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
+{
+	NSPasteboard *pboard;
+    NSDragOperation sourceDragMask;
+	
+	sourceDragMask = [sender draggingSourceOperationMask];
+	
+	pboard = [sender draggingPasteboard];
+	
+	if ([[pboard types] containsObject:NSURLPboardType])
+	{
+		if (sourceDragMask & NSDragOperationLink) {
+			NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
+			mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
+            return NSDragOperationLink;
+        }
+	}
+	return NSDragOperationNone;
+}
+
+- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
+{
+	callHandleDragUpdated(mLastDraggedUrl);
+	
+	return NSDragOperationLink;
+}
+
+- (void) draggingExited:(id<NSDraggingInfo>)sender
+{
+	callHandleDragExited(mLastDraggedUrl);
+}
+
+- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
+{
+	return YES;
+}
+
+- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
+{
+	callHandleDragDropped(mLastDraggedUrl);
+	return true;
+}
+
 @end
 
 // We use a custom NSWindow for our event handling.
@@ -244,7 +288,7 @@
 
 - (id) init
 {
-	//[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType, nil]];
+	
 	return self;
 }
 
@@ -378,6 +422,8 @@
 	callMouseExit();
 }
 
+
+
 - (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
 {
 	NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 57b3d11296..ebc1633f9d 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -24,14 +24,6 @@
  * 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;
@@ -59,6 +51,7 @@ void setIBeamCursor();
 void setPointingHandCursor();
 void setCopyCursor();
 void setCrossCursor();
+void setNotAllowedCursor();
 void hideNSCursor();
 void showNSCursor();
 void hideNSCursorTillMove(bool hide);
@@ -103,6 +96,12 @@ void callMiddleMouseUp(float *pos, unsigned int mask);
 void callFocus();
 void callFocusLost();
 
+#include <string>
+void callHandleDragEntered(std::string url);
+void callHandleDragExited(std::string url);
+void callHandleDragUpdated(std::string url);
+void callHandleDragDropped(std::string url);
+
 NSWindowRef getMainAppWindow();
 GLViewRef getGLView();
 
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index b6e5767203..7867226476 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -143,6 +143,12 @@ void setCrossCursor()
 	[cursor set];
 }
 
+void setNotAllowedCursor()
+{
+	NSCursor *cursor = [NSCursor operationNotAllowedCursor];
+	[cursor set];
+}
+
 void hideNSCursor()
 {
 	[NSCursor hide];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 95ad87d58f..f25fc82896 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -248,7 +248,6 @@ void callLeftMouseDown(float *pos, MASK mask)
 	outCoords.mX = llround(pos[0]);
 	outCoords.mY = llround(pos[1]);
 	gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
-	LL_INFOS("Window") << outCoords.mX << ", " << outCoords.mY << LL_ENDL;
 }
 
 void callLeftMouseUp(float *pos, MASK mask)
@@ -285,7 +284,6 @@ void callMouseMoved(float *pos, MASK mask)
 	gWindowImplementation->getMouseDeltas(deltas);
 	outCoords.mX += deltas[0];
 	outCoords.mY += deltas[1];
-	LL_INFOS("Mouse Movement") << "Moved coords: " << outCoords.mX << ", " << outCoords.mY << LL_ENDL;
 	gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
 	gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
 }
@@ -339,6 +337,26 @@ void callMiddleMouseUp(float *pos, MASK mask)
 	gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask);
 }
 
+void callHandleDragEntered(std::string url)
+{
+	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING);
+}
+
+void callHandleDragExited(std::string url)
+{
+	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING);
+}
+
+void callHandleDragUpdated(std::string url)
+{
+	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK);
+}
+
+void callHandleDragDropped(std::string url)
+{
+	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED);
+}
+
 void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 {
 	if (mCursorDecoupled)
@@ -1784,7 +1802,6 @@ S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef t
 
 	return result;
 }
-
 OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,
 										 DragRef drag)
 {
@@ -1792,126 +1809,69 @@ OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefC
 	return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED);
 
 }
-
-OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action)
+*/
+void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action)
 {
-	OSErr result = dragNotAcceptedErr;	// overall function result
-	OSErr err = noErr;	// for local error handling
-
-	// Get the mouse position and modifiers of this drag.
-	SInt16 modifiers, mouseDownModifiers, mouseUpModifiers;
-	::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers);
-	MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
+	MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers());
 
-	Point mouse_point;
+	float mouse_point[2];
 	// This will return the mouse point in global screen coords
-	::GetDragMouse(drag, &mouse_point, NULL);
-	LLCoordScreen screen_coords(mouse_point.h, mouse_point.v);
+	getCursorPos(mWindow, mouse_point);
+	LLCoordScreen screen_coords(mouse_point[0], mouse_point[1]);
 	LLCoordGL gl_pos;
 	convertCoords(screen_coords, &gl_pos);
-
-	// Look at the pasteboard and try to extract an URL from it
-	PasteboardRef   pasteboard;
-	if(GetDragPasteboard(drag, &pasteboard) == noErr)
+	
+	if(!url.empty())
 	{
-		ItemCount num_items = 0;
-		// Treat an error here as an item count of 0
-		(void)PasteboardGetItemCount(pasteboard, &num_items);
-
-		// Only deal with single-item drags.
-		if(num_items == 1)
-		{
-			PasteboardItemID item_id = NULL;
-			CFArrayRef flavors = NULL;
-			CFDataRef data = NULL;
-
-			err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based.
-
-			// Try to extract an URL from the pasteboard
-			if(err == noErr)
-			{
-				err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors);
-			}
-
-			if(err == noErr)
-			{
-				if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL))
-				{
-					// This is an URL.
-					err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeURL, &data);
-				}
-				else if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeUTF8PlainText))
+		LLWindowCallbacks::DragNDropResult res =
+		mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
+		
+		switch (res) {
+			case LLWindowCallbacks::DND_NONE:		// No drop allowed
+				if (action == LLWindowCallbacks::DNDA_TRACK)
 				{
-					// This is a string that might be an URL.
-					err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data);
+					mDragOverrideCursor = 0;
 				}
-
-			}
-
-			if(flavors != NULL)
-			{
-				CFRelease(flavors);
-			}
-
-			if(data != NULL)
-			{
-				std::string url;
-				url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data));
-				CFRelease(data);
-
-				if(!url.empty())
-				{
-					LLWindowCallbacks::DragNDropResult res =
-						mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
-
-					switch (res) {
-						case LLWindowCallbacks::DND_NONE:		// No drop allowed
-							if (action == LLWindowCallbacks::DNDA_TRACK)
-							{
-								mDragOverrideCursor = kThemeNotAllowedCursor;
-							}
-							else {
-								mDragOverrideCursor = -1;
-							}
-							break;
-						case LLWindowCallbacks::DND_MOVE:		// Drop accepted would result in a "move" operation
-							mDragOverrideCursor = kThemePointingHandCursor;
-							result = noErr;
-							break;
-						case LLWindowCallbacks::DND_COPY:		// Drop accepted would result in a "copy" operation
-							mDragOverrideCursor = kThemeCopyArrowCursor;
-							result = noErr;
-							break;
-						case LLWindowCallbacks::DND_LINK:		// Drop accepted would result in a "link" operation:
-							mDragOverrideCursor = kThemeAliasArrowCursor;
-							result = noErr;
-							break;
-						default:
-							mDragOverrideCursor = -1;
-							break;
-					}
-					// This overrides the cursor being set by setCursor.
-					// This is a bit of a hack workaround because lots of areas
-					// within the viewer just blindly set the cursor.
-					if (mDragOverrideCursor == -1)
-					{
-						// Restore the cursor
-						ECursorType temp_cursor = mCurrentCursor;
-						// get around the "setting the same cursor" code in setCursor()
-						mCurrentCursor = UI_CURSOR_COUNT;
- 						setCursor(temp_cursor);
-					}
-					else {
-						// Override the cursor
-						SetThemeCursor(mDragOverrideCursor);
-					}
-
+				else {
+					mDragOverrideCursor = -1;
 				}
-			}
+				break;
+			case LLWindowCallbacks::DND_MOVE:		// Drop accepted would result in a "move" operation
+				mDragOverrideCursor = UI_CURSOR_NO;
+				break;
+			case LLWindowCallbacks::DND_COPY:		// Drop accepted would result in a "copy" operation
+				mDragOverrideCursor = UI_CURSOR_ARROWCOPY;
+				break;
+			default:
+				mDragOverrideCursor = -1;
+				break;
+		}
+		// This overrides the cursor being set by setCursor.
+		// This is a bit of a hack workaround because lots of areas
+		// within the viewer just blindly set the cursor.
+		if (mDragOverrideCursor == -1)
+		{
+			// Restore the cursor
+			ECursorType temp_cursor = mCurrentCursor;
+			// get around the "setting the same cursor" code in setCursor()
+			mCurrentCursor = UI_CURSOR_COUNT;
+			setCursor(temp_cursor);
+		}
+		else {
+			// Override the cursor
+			switch (mDragOverrideCursor) {
+				case 0:
+					setArrowCursor();
+					break;
+				case UI_CURSOR_NO:
+					setNotAllowedCursor();
+				case UI_CURSOR_ARROWCOPY:
+					setCopyCursor();
+				default:
+					break;
+			};
 		}
 	}
-
-	return result;
 }
-*/
+
 #endif // LL_OS_DRAGDROP_ENABLED
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index c5e1b2290b..14d6e70fb3 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -123,7 +123,8 @@ public:
 	
 	void updateMouseDeltas(float* deltas);
 	void getMouseDeltas(float* delta);
-
+	
+	void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
 
 protected:
 	LLWindowMacOSX(LLWindowCallbacks* callbacks,
@@ -164,12 +165,11 @@ protected:
 	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);
-	 */
+	
+	//static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
+	//static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,	DragRef theDrag);
+	
+	
 #endif // LL_OS_DRAGDROP_ENABLED
 	
 	//
@@ -202,7 +202,7 @@ protected:
 	U32			mFSAASamples;
 	BOOL		mForceRebuild;
 	
-	S32			mDragOverrideCursor;
+	S32	mDragOverrideCursor;
 	
 	F32			mBounceTime;
 	//NMRec		mBounceRec;
-- 
cgit v1.2.3


From c52e6f9c597c67637045134d808a9039f85efc5c Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Wed, 23 Jan 2013 09:29:32 -0500
Subject: Refactor the key input handling to make it easier to filter out keys
 we don't need unicode characters for (such as the arrow keys).

---
 indra/llwindow/llopenglview-objc.h    |  1 -
 indra/llwindow/llopenglview-objc.mm   | 67 ++++++++++++++++++++---------------
 indra/llwindow/llwindowmacosx-objc.mm |  6 +++-
 3 files changed, 44 insertions(+), 30 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 1592e6e01d..cc1618b3bc 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -14,7 +14,6 @@
 
 @interface LLOpenGLView : NSOpenGLView
 {
-	NSPoint mousePos;
 	std::string mLastDraggedUrl;
 }
 
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 763cf0c981..b79b7b3fa5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -294,37 +294,48 @@
 
 - (void) keyDown:(NSEvent *)theEvent
 {
-	callKeyDown([theEvent keyCode], mModifiers);
-	NSLog(@"Keycode: %hu", [theEvent keyCode]);
-	NSString *chars = [theEvent characters];
-	for (uint i = 0; i < [chars length]; i++)
-	{
-		// Enter and Return are special cases.
-		unichar returntest = [chars characterAtIndex:i];
-		if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) &&
-			!([theEvent modifierFlags] & NSCommandKeyMask) &&
-			!([theEvent modifierFlags] & NSAlternateKeyMask) &&
-			!([theEvent modifierFlags] & NSControlKeyMask))
-		{
-			callUnicodeCallback(13, 0);
-		} else {
-			// The command key being pressed is also a special case.
-			// Control + <character> produces an ASCII control character code.
-			// Command + <character> produces just the character's code.
-			// Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range.
-			if ([theEvent modifierFlags] & NSCommandKeyMask)
-			{
-				if (returntest >= 64 && returntest <= 95)
-				{
-					callUnicodeCallback(returntest - 63, mModifiers);
-				} else if (returntest >= 97 && returntest <= 122)
+	uint keycode = [theEvent keyCode];
+	
+	switch (keycode) {
+		case 0x7b:
+		case 0x7c:
+		case 0x7d:
+		case 0x7e:
+			callKeyDown(keycode, mModifiers);
+			break;
+			
+		default:
+			callKeyDown(keycode, mModifiers);
+			NSString *chars = [theEvent characters];
+			for (uint i = 0; i < [chars length]; i++) {
+				// Enter and Return are special cases.
+				unichar returntest = [chars characterAtIndex:i];
+				if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) &&
+					!([theEvent modifierFlags] & NSCommandKeyMask) &&
+					!([theEvent modifierFlags] & NSAlternateKeyMask) &&
+					!([theEvent modifierFlags] & NSControlKeyMask))
 				{
-					callUnicodeCallback(returntest - 96, mModifiers);
+					callUnicodeCallback(13, 0);
+				} else {
+					// The command key being pressed is also a special case.
+					// Control + <character> produces an ASCII control character code.
+					// Command + <character> produces just the character's code.
+					// Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range.
+					if ([theEvent modifierFlags] & NSCommandKeyMask)
+					{
+						if (returntest >= 64 && returntest <= 95)
+						{
+							callUnicodeCallback(returntest - 63, mModifiers);
+						} else if (returntest >= 97 && returntest <= 122)
+						{
+							callUnicodeCallback(returntest - 96, mModifiers);
+						}
+					} else {
+						callUnicodeCallback(returntest, mModifiers);
+					}
 				}
-			} else {
-				callUnicodeCallback(returntest, mModifiers);
 			}
-		}
+			break;
 	}
 }
 
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 7867226476..b123ba0711 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -64,11 +64,12 @@ void setupCocoa()
 
 bool copyToPBoard(const unsigned short *str, unsigned int len)
 {
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
 	NSPasteboard *pboard = [NSPasteboard generalPasteboard];
 	[pboard clearContents];
 	
 	NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
-	
+	[pool release];
 	return [pboard writeObjects:contentsToPaste];
 }
 
@@ -80,6 +81,7 @@ bool pasteBoardAvailable()
 
 const unsigned short *copyFromPBoard()
 {
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
 	NSPasteboard *pboard = [NSPasteboard generalPasteboard];
 	NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
 	NSString *str = NULL;
@@ -91,6 +93,7 @@ const unsigned short *copyFromPBoard()
 	}
 	unichar* temp = (unichar*)calloc([str length], sizeof(unichar));
 	[str getCharacters:temp];
+	[pool release];
 	return temp;
 }
 
@@ -312,6 +315,7 @@ void convertWindowToScreen(NSWindowRef window, float *coord)
 void closeWindow(NSWindowRef window)
 {
 	[(LLNSWindow*)window close];
+	[(LLNSWindow*)window release];
 }
 
 void removeGLView(GLViewRef view)
-- 
cgit v1.2.3


From bf1e9124f1530339bfa35652a3b3e329b32a3240 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Sat, 2 Feb 2013 12:49:39 -0500
Subject: Restore the old Carbon crash handler, and more deprecated API
 removal.

---
 indra/llwindow/llwindowmacosx.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index f25fc82896..2e86759ec0 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1350,7 +1350,7 @@ void LLWindowMacOSX::updateCursor()
 	{
 	default:
 	case UI_CURSOR_ARROW:
-		InitCursor();
+		setArrowCursor();
 		if(mCursorHidden)
 		{
 			// Since InitCursor resets the hide level, correct for it here.
@@ -1410,7 +1410,7 @@ void LLWindowMacOSX::updateCursor()
 
 	if(result != noErr)
 	{
-		InitCursor();
+		setArrowCursor();
 	}
 
 	mCurrentCursor = mNextCursor;
-- 
cgit v1.2.3


From 4a935b68151f9d6951a1d1312a3437a8e8150f41 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Fri, 22 Feb 2013 16:41:49 -0500
Subject: Fix inconsistent handling of Control, Alt, and Shift keys through a
 new modifier update callback.

---
 indra/llwindow/llkeyboard.h           | 5 +++++
 indra/llwindow/llkeyboardheadless.cpp | 7 +++++++
 indra/llwindow/llkeyboardheadless.h   | 3 +++
 indra/llwindow/llkeyboardmacosx.cpp   | 5 +++++
 indra/llwindow/llkeyboardmacosx.h     | 1 +
 indra/llwindow/llopenglview-objc.mm   | 3 +--
 indra/llwindow/llwindowmacosx-objc.h  | 1 +
 indra/llwindow/llwindowmacosx.cpp     | 5 +++++
 8 files changed, 28 insertions(+), 2 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index c155c1b362..92449c123f 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -82,6 +82,11 @@ public:
 
 	virtual BOOL	handleKeyUp(const U16 key, MASK mask) = 0;
 	virtual BOOL	handleKeyDown(const U16 key, MASK mask) = 0;
+	
+#ifdef LL_DARWIN
+	// We only actually use this for OS X.
+	virtual void	handleModifier(MASK mask) = 0;
+#endif // LL_DARWIN
 
 	// Asynchronously poll the control, alt, and shift keys and set the
 	// appropriate internal key masks.
diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp
index c87617c9ff..a1b6b294e0 100644
--- a/indra/llwindow/llkeyboardheadless.cpp
+++ b/indra/llwindow/llkeyboardheadless.cpp
@@ -45,6 +45,13 @@ BOOL LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask)
 MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event)
 { return MASK_NONE; }
 
+#ifdef LL_DARWIN
+void LLKeyboardHeadless::handleModifier(MASK mask)
+{
+	
+}
+#endif
+
 void LLKeyboardHeadless::scanKeyboard()
 {
 	for (S32 key = 0; key < KEY_COUNT; key++)
diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h
index 4e666f8ce8..8ed28ace90 100644
--- a/indra/llwindow/llkeyboardheadless.h
+++ b/indra/llwindow/llkeyboardheadless.h
@@ -40,6 +40,9 @@ public:
 	/*virtual*/ void	resetMaskKeys();
 	/*virtual*/ MASK	currentMask(BOOL for_mouse_event);
 	/*virtual*/ void	scanKeyboard();
+#ifdef LL_DARWIN
+	/*virtual*/ void	handleModifier(MASK mask);
+#endif
 };
 
 #endif
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 59cc2acaec..d4c8214461 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -198,6 +198,11 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out
 }
 */
 
+void LLKeyboardMacOSX::handleModifier(MASK mask)
+{
+	updateModifiers(mask);
+}
+
 MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
 {
 	// translate the mask
diff --git a/indra/llwindow/llkeyboardmacosx.h b/indra/llwindow/llkeyboardmacosx.h
index 6e1f4d3b96..f9d014ab70 100644
--- a/indra/llwindow/llkeyboardmacosx.h
+++ b/indra/llwindow/llkeyboardmacosx.h
@@ -49,6 +49,7 @@ public:
 	/*virtual*/ void	resetMaskKeys();
 	/*virtual*/ MASK	currentMask(BOOL for_mouse_event);
 	/*virtual*/ void	scanKeyboard();
+	/*virtual*/ void	handleModifier(MASK mask);
 	
 protected:
 	MASK	updateModifiers(const U32 mask);
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index b79b7b3fa5..3a6225eab5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -345,6 +345,7 @@
 
 - (void)flagsChanged:(NSEvent *)theEvent {
 	mModifiers = [theEvent modifierFlags];
+	callModifier([theEvent modifierFlags]);
 }
 
 - (void) mouseDown:(NSEvent *)theEvent
@@ -433,8 +434,6 @@
 	callMouseExit();
 }
 
-
-
 - (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
 {
 	NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index ebc1633f9d..32d1a4d9a2 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -95,6 +95,7 @@ void callMiddleMouseDown(float *pos, unsigned int mask);
 void callMiddleMouseUp(float *pos, unsigned int mask);
 void callFocus();
 void callFocusLost();
+void callModifier(unsigned int mask);
 
 #include <string>
 void callHandleDragEntered(std::string url);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 2e86759ec0..9ce19bd977 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -337,6 +337,11 @@ void callMiddleMouseUp(float *pos, MASK mask)
 	gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask);
 }
 
+void callModifier(MASK mask)
+{
+	gKeyboard->handleModifier(mask);
+}
+
 void callHandleDragEntered(std::string url)
 {
 	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING);
-- 
cgit v1.2.3


From e19db5668853b7d3be2ed6af289a3c35bd213bca Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 25 Feb 2013 15:35:21 -0500
Subject: Fix for antialiasing and VSync not being enabled properly.

---
 indra/llwindow/llopenglview-objc.h    |  3 ++-
 indra/llwindow/llopenglview-objc.mm   | 11 ++++++++++-
 indra/llwindow/llwindowmacosx-objc.h  |  2 +-
 indra/llwindow/llwindowmacosx-objc.mm |  4 ++--
 indra/llwindow/llwindowmacosx.cpp     |  2 +-
 5 files changed, 16 insertions(+), 6 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index cc1618b3bc..b344bed2ef 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -16,7 +16,8 @@
 {
 	std::string mLastDraggedUrl;
 }
-
+- (id) initWithSamples:(NSUInteger)samples;
+- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
 
 // rebuildContext
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 3a6225eab5..e89c9267d5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -61,10 +61,19 @@
 
 - (id) init
 {
-	//[self registerForDraggedTypes:[NSArray arrayWithObjects:NSURLPboardType, NSFilenamesPboardType, nil]];
 	return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
 }
 
+- (id) initWithSamples:(NSUInteger)samples
+{
+	return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
+}
+
+- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync
+{
+	return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
+}
+
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
 {
 	[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 32d1a4d9a2..a0eab61e7c 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -59,7 +59,7 @@ void hideNSCursorTillMove(bool hide);
 NSWindowRef createNSWindow(int x, int y, int width, int height);
 
 #include <OpenGL/OpenGL.h>
-GLViewRef createOpenGLView(NSWindowRef window);
+GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
 void glSwapBuffers(void* context);
 CGLContextObj getCGLContextObj(GLViewRef view);
 void getContentViewBounds(NSWindowRef window, float* bounds);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index b123ba0711..b288671219 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -214,9 +214,9 @@ NSWindowRef createNSWindow(int x, int y, int width, int height)
 	return window;
 }
 
-GLViewRef createOpenGLView(NSWindowRef window)
+GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
 {
-	LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:0 andVsync:FALSE];
+	LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
 	[(LLNSWindow*)window setContentView:glview];
 	return glview;
 }
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 9ce19bd977..ac0fa54a68 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -404,7 +404,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		LL_INFOS("Window") << "Creating GL view..." << LL_ENDL;
 		// Our OpenGL view is already defined within SecondLife.xib.
 		// Get the view instead.
-		mGLView = createOpenGLView(mWindow);
+		mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync);
 		mContext = getCGLContextObj(mGLView);
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
-- 
cgit v1.2.3


From 21aa4b9c2494aab408fffa6c21010b6ca0a9a626 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 26 Feb 2013 16:18:42 -0500
Subject: Setup the quit handler for when the user attempts to close the
 window.  This restores the previous functionality of asking the user if they
 want to quit.

---
 indra/llwindow/llopenglview-objc.mm  | 7 +++++--
 indra/llwindow/llwindowmacosx-objc.h | 1 +
 indra/llwindow/llwindowmacosx.cpp    | 8 ++++++++
 3 files changed, 14 insertions(+), 2 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index e89c9267d5..1d26ca5ca1 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -466,16 +466,19 @@
 
 - (BOOL) becomeFirstResponder
 {
-	NSLog(@"Window gained focus!");
 	callFocus();
 	return true;
 }
 
 - (BOOL) resignFirstResponder
 {
-	NSLog(@"Window lost focus!");
 	callFocus();
 	return true;
 }
 
+- (void) close
+{
+	callQuitHandler();
+}
+
 @end
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index a0eab61e7c..6793666927 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -96,6 +96,7 @@ void callMiddleMouseUp(float *pos, unsigned int mask);
 void callFocus();
 void callFocusLost();
 void callModifier(unsigned int mask);
+void callQuitHandler();
 
 #include <string>
 void callHandleDragEntered(std::string url);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index ac0fa54a68..24f73c5631 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -362,6 +362,14 @@ void callHandleDragDropped(std::string url)
 	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED);
 }
 
+void callQuitHandler()
+{
+	if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
+	{
+		gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
+	}
+}
+
 void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 {
 	if (mCursorDecoupled)
-- 
cgit v1.2.3


From f5516e0fc0e6c22b25f9dca2b9b24ebd7618332a Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham Linden)" <graham@lindenlab.com>
Date: Wed, 27 Feb 2013 06:46:53 -0800
Subject: For MAINT-2404 Fixes detection of VRAM on OSX removed along with
 other AGL code. Code Review: callum

---
 indra/llwindow/llopenglview-objc.h    |  5 +++++
 indra/llwindow/llopenglview-objc.mm   | 22 ++++++++++++++++++++++
 indra/llwindow/llwindowmacosx-objc.h  |  1 +
 indra/llwindow/llwindowmacosx-objc.mm |  5 +++++
 indra/llwindow/llwindowmacosx.cpp     |  2 ++
 5 files changed, 35 insertions(+)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index b344bed2ef..c3ae34ea50 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -7,6 +7,9 @@
 //
 
 #import <Cocoa/Cocoa.h>
+#import <IOKit/IOKitLib.h>
+#import <CoreFoundation/CFBase.h>
+#import <CoreFoundation/CFNumber.h>
 #include "llwindowmacosx-objc.h"
 
 // Some nasty shovelling of LLOpenGLView from LLNativeBindings to prevent any C++ <-> Obj-C interop oddities.
@@ -33,6 +36,8 @@
 - (CGLContextObj) getCGLContextObj;
 - (CGLPixelFormatObj*)getCGLPixelFormatObj;
 
+- (unsigned long) getVramSize;
+
 @end
 
 @interface LLNSWindow : NSWindow {
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index e89c9267d5..a1dece54f4 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -39,6 +39,28 @@
 
 @implementation LLOpenGLView
 
+- (unsigned long)getVramSize
+{
+	unsigned long vram_bytes = 0;
+
+	io_service_t display_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
+	
+	const void* type_code = IORegistryEntryCreateCFProperty(display_port, CFSTR(kIOFBMemorySizeKey), kCFAllocatorDefault, kNilOptions);
+
+	// Ensure we have valid data from IOKit
+	if(type_code && CFGetTypeID(type_code) == CFNumberGetTypeID())
+	{
+		long val;
+        // Retrieve actual number...is Apple ever embarrassed by this nonsense?
+        //
+		CFNumberGetValue((const __CFNumber*)type_code, kCFNumberSInt32Type, &val);
+		vram_bytes = (unsigned long)val;
+		CFRelease(type_code);
+	}
+	
+	return vram_bytes;
+}
+
 - (void)viewDidMoveToWindow
 {
 	[[NSNotificationCenter defaultCenter] addObserver:self
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index a0eab61e7c..1724b85724 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -62,6 +62,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height);
 GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
 void glSwapBuffers(void* context);
 CGLContextObj getCGLContextObj(GLViewRef view);
+unsigned long getVramSize(GLViewRef view);
 void getContentViewBounds(NSWindowRef window, float* bounds);
 void getWindowSize(NSWindowRef window, float* size);
 void setWindowSize(NSWindowRef window, int width, int height);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index b288671219..9b57cd27cd 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -237,6 +237,11 @@ CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
 	return [glview getCGLPixelFormatObj];
 }
 
+unsigned long getVramSize(GLViewRef view)
+{
+	return [(LLOpenGLView *)view getVramSize];
+}
+
 void getContentViewBounds(NSWindowRef window, float* bounds)
 {
 	bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index ac0fa54a68..abb3c1e50c 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -408,6 +408,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		mContext = getCGLContextObj(mGLView);
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
+		
+		gGLManager.mVRAM = getVramSize(mGLView);
 	}
 
 	// Hook up the context to a drawable
-- 
cgit v1.2.3


From d046e606575b2c3714a88e321c88e05441cba4a8 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham Linden)" <graham@lindenlab.com>
Date: Wed, 27 Feb 2013 14:39:26 -0800
Subject: Fix max VRAM detection on some cards and issues with sequencing of
 application of mem multiplier

---
 indra/llwindow/llopenglview-objc.mm | 32 ++++++++++++++------------------
 indra/llwindow/llwindowmacosx.cpp   |  5 +++--
 2 files changed, 17 insertions(+), 20 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index a1dece54f4..735ef77cce 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -41,24 +41,20 @@
 
 - (unsigned long)getVramSize
 {
-	unsigned long vram_bytes = 0;
-
-	io_service_t display_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
-	
-	const void* type_code = IORegistryEntryCreateCFProperty(display_port, CFSTR(kIOFBMemorySizeKey), kCFAllocatorDefault, kNilOptions);
-
-	// Ensure we have valid data from IOKit
-	if(type_code && CFGetTypeID(type_code) == CFNumberGetTypeID())
-	{
-		long val;
-        // Retrieve actual number...is Apple ever embarrassed by this nonsense?
-        //
-		CFNumberGetValue((const __CFNumber*)type_code, kCFNumberSInt32Type, &val);
-		vram_bytes = (unsigned long)val;
-		CFRelease(type_code);
-	}
-	
-	return vram_bytes;
+    CGLRendererInfoObj info = 0;
+	GLint vram_bytes = 0;
+    int num_renderers = 0;
+    CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
+    if(0 == the_err)
+    {
+        CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes);
+        CGLDestroyRendererInfo (info);
+    }
+    else
+    {
+        vram_bytes = (256 << 20);
+    }
+	return (unsigned long)vram_bytes;
 }
 
 - (void)viewDidMoveToWindow
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index abb3c1e50c..2faebe5dd9 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -511,8 +511,9 @@ void LLWindowMacOSX::destroyContext()
 	// Close the window
 	if(mWindow != NULL)
 	{
-		closeWindow(mWindow);
-		mWindow = NULL;
+        NSWindowRef dead_window = mWindow;
+        mWindow = NULL;
+		closeWindow(dead_window);
 	}
 
 }
-- 
cgit v1.2.3


From 5caa7a465e73fc9cf70f5f2c5d147a509bd5e185 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 11 Mar 2013 10:16:22 -0400
Subject: Bug fixing and prep-work for IME support (along with refactored text
 input in general).

---
 indra/llwindow/llkeyboardmacosx.cpp   |  4 ++--
 indra/llwindow/llwindowmacosx-objc.h  |  8 ++++++++
 indra/llwindow/llwindowmacosx-objc.mm |  9 ++++++++-
 indra/llwindow/llwindowmacosx.cpp     | 25 +++++++++++++++++++++++++
 indra/llwindow/llwindowmacosx.h       |  1 +
 5 files changed, 44 insertions(+), 3 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index d4c8214461..274e92c225 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -213,7 +213,7 @@ MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
 		out_mask |= MASK_SHIFT;
 	}
 
-	if(mask & MAC_CTRL_KEY || mask & MAC_CMD_KEY)
+	if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
 	{
 		out_mask |= MASK_CONTROL;
 	}
@@ -267,7 +267,7 @@ MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
 
 	if (mask & MAC_SHIFT_KEY)			result |= MASK_SHIFT;
 	if (mask & MAC_CTRL_KEY)			result |= MASK_CONTROL;
-	if (mask & MAC_ALT_KEY)			result |= MASK_ALT;
+	if (mask & MAC_ALT_KEY)				result |= MASK_ALT;
 
 	// For keyboard events, consider Command equivalent to Control
 	if (!for_mouse_event)
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 6793666927..62c5b8298f 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -78,6 +78,7 @@ void removeGLView(GLViewRef view);
 // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
 void callKeyUp(unsigned short key, unsigned int mask);
 void callKeyDown(unsigned short key, unsigned int mask);
+void callResetKeys();
 void callUnicodeCallback(wchar_t character, unsigned int mask);
 void callRightMouseDown(float *pos, unsigned int mask);
 void callRightMouseUp(float *pos, unsigned int mask);
@@ -104,6 +105,13 @@ void callHandleDragExited(std::string url);
 void callHandleDragUpdated(std::string url);
 void callHandleDragDropped(std::string url);
 
+// LLPreeditor C bindings.
+std::basic_string<wchar_t> getPreeditString();
+void getPreeditSelectionRange(int *position, int *length);
+void getPreeditMarkedRange(int *position, int *length);
+void handleUnicodeCharacter(wchar_t c);
+void updatePreeditor(unsigned short *str);
+
 NSWindowRef getMainAppWindow();
 GLViewRef getGLView();
 
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index b288671219..e4e12f4b5c 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -332,7 +332,14 @@ NSWindowRef getMainAppWindow()
 	return winRef;
 }
 
-unsigned int getModifiers()
+/*
+GLViewRef getGLView()
 {
+	return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
+}
+*/
+
+unsigned int getModifiers()
+{	
 	return [NSEvent modifierFlags];
 }
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 24f73c5631..2f6c2101ef 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -211,6 +211,11 @@ void callKeyDown(unsigned short key, unsigned int mask)
 	gKeyboard->handleKeyDown(key, mask);
 }
 
+void callResetKeys()
+{
+	gKeyboard->resetKeys();
+}
+
 void callUnicodeCallback(wchar_t character, unsigned int mask)
 {
 	gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
@@ -370,6 +375,26 @@ void callQuitHandler()
 	}
 }
 
+std::basic_string<wchar_t> getPreeditString()
+{
+	return gWindowImplementation->getPreeditor()->getPreeditString();
+}
+
+void getPreeditSelectionRange(int *position, int *length)
+{
+	gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
+}
+
+void getPreeditMarkedRange(int *position, int *length)
+{
+	gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
+}
+
+void handleUnicodeCharacter(wchar_t c)
+{
+	gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
+}
+
 void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 {
 	if (mCursorDecoupled)
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 14d6e70fb3..de0340cf74 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -120,6 +120,7 @@ public:
 	
 	void* getWindow() { return mWindow; }
 	LLWindowCallbacks* getCallbacks() { return mCallbacks; }
+	LLPreeditor* getPreeditor() { return mPreeditor; }
 	
 	void updateMouseDeltas(float* deltas);
 	void getMouseDeltas(float* delta);
-- 
cgit v1.2.3


From ad26f3c39002b6043e5fc4e00f9793e0f0e4941c Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 19 Mar 2013 05:50:50 -0400
Subject: IME support (and revamped text input support) semi-working.

---
 indra/llwindow/llopenglview-objc.h  |   3 +-
 indra/llwindow/llopenglview-objc.mm | 126 ++++++++++++++++++++++++++++++++----
 indra/llwindow/llwindowmacosx.cpp   |  12 +++-
 3 files changed, 125 insertions(+), 16 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index c3ae34ea50..c144831da4 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -15,9 +15,10 @@
 // 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
+@interface LLOpenGLView : NSOpenGLView <NSTextInputClient>
 {
 	std::string mLastDraggedUrl;
+	unsigned int mModifiers;
 }
 - (id) initWithSamples:(NSUInteger)samples;
 - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 6ea523ea05..d568ed2fe5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -94,6 +94,7 @@
 
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
 {
+	[[self window] makeFirstResponder:self];
 	[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
 	[self initWithFrame:frame];
 	
@@ -199,6 +200,7 @@
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
+	[self becomeFirstResponder];
 	[_window mouseDown:theEvent];
 }
 
@@ -234,7 +236,49 @@
 
 - (void) keyDown:(NSEvent *)theEvent
 {
-	[_window keyDown:theEvent];
+	[[self inputContext] handleEvent:theEvent];
+	uint keycode = [theEvent keyCode];
+	
+	switch (keycode) {
+		case 0x7b:
+		case 0x7c:
+		case 0x7d:
+		case 0x7e:
+			callKeyDown(keycode, mModifiers);
+			break;
+			
+		default:
+			callKeyDown(keycode, mModifiers);
+			NSString *chars = [theEvent characters];
+			for (uint i = 0; i < [chars length]; i++) {
+				// Enter and Return are special cases.
+				unichar returntest = [chars characterAtIndex:i];
+				if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) &&
+					!([theEvent modifierFlags] & NSCommandKeyMask) &&
+					!([theEvent modifierFlags] & NSAlternateKeyMask) &&
+					!([theEvent modifierFlags] & NSControlKeyMask))
+				{
+					callUnicodeCallback(13, 0);
+				} else {
+					// The command key being pressed is also a special case.
+					// Control + <character> produces an ASCII control character code.
+					// Command + <character> produces just the character's code.
+					// Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range.
+					if ([theEvent modifierFlags] & NSCommandKeyMask)
+					{
+						if (returntest >= 64 && returntest <= 95)
+						{
+							callUnicodeCallback(returntest - 63, mModifiers);
+						} else if (returntest >= 97 && returntest <= 122)
+						{
+							callUnicodeCallback(returntest - 96, mModifiers);
+						}
+					}
+				}
+			}
+			break;
+	}
+	
 }
 
 - (void) mouseMoved:(NSEvent *)theEvent
@@ -242,9 +286,9 @@
 	[_window mouseMoved:theEvent];
 }
 
-- (void) flagsChanged:(NSEvent *)theEvent
-{
-	[_window flagsChanged:theEvent];
+- (void)flagsChanged:(NSEvent *)theEvent {
+	mModifiers = [theEvent modifierFlags];
+	callModifier([theEvent modifierFlags]);
 }
 
 - (void) mouseExited:(NSEvent *)theEvent
@@ -252,14 +296,9 @@
 	[_window mouseExited:theEvent];
 }
 
-- (BOOL) becomeFirstResponder
+- (BOOL) acceptsFirstResponder
 {
-	return [_window becomeFirstResponder];
-}
-
-- (BOOL) resignFirstResponder
-{
-	return [_window resignFirstResponder];
+	return YES;
 }
 
 - (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
@@ -305,6 +344,67 @@
 	return true;
 }
 
+- (BOOL)hasMarkedText
+{
+	return NO;
+}
+
+- (NSRange)markedRange
+{
+	return NSMakeRange(NSNotFound, 0);
+}
+
+- (NSRange)selectedRange
+{
+	return NSMakeRange(NSNotFound, 0);
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+}
+
+- (void)unmarkText
+{
+	
+}
+
+- (NSArray *)validAttributesForMarkedText
+{
+	return [NSArray array];
+}
+
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+	return nil;
+}
+
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
+{
+	for (NSInteger i = 0; i < [aString length]; i++)
+	{
+		callUnicodeCallback([aString characterAtIndex:i], mModifiers);
+	}
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
+{
+	return NSNotFound;
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+	return NSZeroRect;
+}
+
+- (void)doCommandBySelector:(SEL)aSelector
+{
+}
+
+- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
+{
+	return NO;
+}
+
 @end
 
 // We use a custom NSWindow for our event handling.
@@ -315,12 +415,13 @@
 
 - (id) init
 {
-	
+	[self makeFirstResponder:[self contentView]];
 	return self;
 }
 
 - (void) keyDown:(NSEvent *)theEvent
 {
+	
 	uint keycode = [theEvent keyCode];
 	
 	switch (keycode) {
@@ -364,6 +465,7 @@
 			}
 			break;
 	}
+	 
 }
 
 - (void) keyUp:(NSEvent *)theEvent {
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 34cc371526..08612bace4 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -223,7 +223,10 @@ void callUnicodeCallback(wchar_t character, unsigned int mask)
 
 void callFocus()
 {
-	gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
+	if (gWindowImplementation)
+	{
+		gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
+	}
 }
 
 void callFocusLost()
@@ -369,9 +372,12 @@ void callHandleDragDropped(std::string url)
 
 void callQuitHandler()
 {
-	if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
+	if (gWindowImplementation)
 	{
-		gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
+		if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
+		{
+			gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
+		}
 	}
 }
 
-- 
cgit v1.2.3


From ebe320e7c3579241e2e034a424ade9f087523b75 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 19 Mar 2013 06:32:56 -0400
Subject: Refactored LLNSWindow and LLOpenGLView significantly.  All input goes
 through LLOpenGLView now.

---
 indra/llwindow/llopenglview-objc.h  |   6 +-
 indra/llwindow/llopenglview-objc.mm | 290 ++++++++++--------------------------
 2 files changed, 80 insertions(+), 216 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index c144831da4..5134063193 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -19,6 +19,7 @@
 {
 	std::string mLastDraggedUrl;
 	unsigned int mModifiers;
+	float mMousePos[2];
 }
 - (id) initWithSamples:(NSUInteger)samples;
 - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
@@ -41,10 +42,7 @@
 
 @end
 
-@interface LLNSWindow : NSWindow {
-	float mMousePos[2];
-	unsigned int mModifiers;
-}
+@interface LLNSWindow : NSWindow
 
 - (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
 - (NSPoint)flipPoint:(NSPoint)aPoint;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index d568ed2fe5..45a5f24481 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -94,7 +94,6 @@
 
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
 {
-	[[self window] makeFirstResponder:self];
 	[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
 	[self initWithFrame:frame];
 	
@@ -188,102 +187,102 @@
 // 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
+- (void) mouseDown:(NSEvent *)theEvent
 {
-	[_window mouseDragged:theEvent];
+	if ([theEvent clickCount] >= 2)
+	{
+		callDoubleClick(mMousePos, mModifiers);
+	} else if ([theEvent clickCount] == 1) {
+		callLeftMouseDown(mMousePos, mModifiers);
+	}
 }
 
-- (void) scrollWheel:(NSEvent *)theEvent
+- (void) mouseUp:(NSEvent *)theEvent
 {
-	[_window scrollWheel:theEvent];
+	callLeftMouseUp(mMousePos, mModifiers);
 }
 
-- (void) mouseDown:(NSEvent *)theEvent
+- (void) rightMouseDown:(NSEvent *)theEvent
 {
-	[self becomeFirstResponder];
-	[_window mouseDown:theEvent];
+	callRightMouseDown(mMousePos, mModifiers);
 }
 
-- (void) mouseUp:(NSEvent *)theEvent
+- (void) rightMouseUp:(NSEvent *)theEvent
 {
-	[_window mouseUp:theEvent];
+	callRightMouseUp(mMousePos, mModifiers);
 }
 
-- (void) rightMouseDown:(NSEvent *)theEvent
+- (void)mouseMoved:(NSEvent *)theEvent
 {
-	[_window rightMouseDown:theEvent];
+	float mouseDeltas[2] = {
+		[theEvent deltaX],
+		[theEvent deltaY]
+	};
+	
+	callDeltaUpdate(mouseDeltas, 0);
+	
+	NSPoint mPoint = [theEvent locationInWindow];
+	mMousePos[0] = mPoint.x;
+	mMousePos[1] = mPoint.y;
+	callMouseMoved(mMousePos, 0);
 }
 
-- (void) rightMouseUp:(NSEvent *)theEvent
+// 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
 {
-	[_window rightMouseUp:theEvent];
+	// Trust the deltas supplied by NSEvent.
+	// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
+	// NSEvent isn't obsolete, and provides us with the correct deltas.
+	float mouseDeltas[2] = {
+		[theEvent deltaX],
+		[theEvent deltaY]
+	};
+	
+	callDeltaUpdate(mouseDeltas, 0);
+	
+	NSPoint mPoint = [theEvent locationInWindow];
+	mMousePos[0] = mPoint.x;
+	mMousePos[1] = mPoint.y;
+	callMouseMoved(mMousePos, 0);
 }
 
 - (void) otherMouseDown:(NSEvent *)theEvent
 {
-	[_window otherMouseDown:theEvent];
+	callMiddleMouseDown(mMousePos, mModifiers);
 }
 
 - (void) otherMouseUp:(NSEvent *)theEvent
 {
-	[_window otherMouseUp:theEvent];
+	callMiddleMouseUp(mMousePos, mModifiers);
+}
+
+- (void) otherMouseDragged:(NSEvent *)theEvent
+{
+	
+}
+
+- (void) scrollWheel:(NSEvent *)theEvent
+{
+	callScrollMoved(-[theEvent deltaY]);
+}
+
+- (void) mouseExited:(NSEvent *)theEvent
+{
+	callMouseExit();
 }
 
 - (void) keyUp:(NSEvent *)theEvent
 {
-	[_window keyUp:theEvent];
+	callKeyUp([theEvent keyCode], mModifiers);
 }
 
 - (void) keyDown:(NSEvent *)theEvent
 {
 	[[self inputContext] handleEvent:theEvent];
 	uint keycode = [theEvent keyCode];
-	
-	switch (keycode) {
-		case 0x7b:
-		case 0x7c:
-		case 0x7d:
-		case 0x7e:
-			callKeyDown(keycode, mModifiers);
-			break;
-			
-		default:
-			callKeyDown(keycode, mModifiers);
-			NSString *chars = [theEvent characters];
-			for (uint i = 0; i < [chars length]; i++) {
-				// Enter and Return are special cases.
-				unichar returntest = [chars characterAtIndex:i];
-				if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) &&
-					!([theEvent modifierFlags] & NSCommandKeyMask) &&
-					!([theEvent modifierFlags] & NSAlternateKeyMask) &&
-					!([theEvent modifierFlags] & NSControlKeyMask))
-				{
-					callUnicodeCallback(13, 0);
-				} else {
-					// The command key being pressed is also a special case.
-					// Control + <character> produces an ASCII control character code.
-					// Command + <character> produces just the character's code.
-					// Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range.
-					if ([theEvent modifierFlags] & NSCommandKeyMask)
-					{
-						if (returntest >= 64 && returntest <= 95)
-						{
-							callUnicodeCallback(returntest - 63, mModifiers);
-						} else if (returntest >= 97 && returntest <= 122)
-						{
-							callUnicodeCallback(returntest - 96, mModifiers);
-						}
-					}
-				}
-			}
-			break;
-	}
-	
-}
-
-- (void) mouseMoved:(NSEvent *)theEvent
-{
-	[_window mouseMoved:theEvent];
+	callKeyDown(keycode, mModifiers);
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
@@ -291,11 +290,6 @@
 	callModifier([theEvent modifierFlags]);
 }
 
-- (void) mouseExited:(NSEvent *)theEvent
-{
-	[_window mouseExited:theEvent];
-}
-
 - (BOOL) acceptsFirstResponder
 {
 	return YES;
@@ -386,6 +380,18 @@
 	}
 }
 
+- (void) insertNewline:(id)sender
+{
+	if (!(mModifiers & NSCommandKeyMask) &&
+		!(mModifiers & NSShiftKeyMask) &&
+		!(mModifiers & NSAlternateKeyMask))
+	{
+		callUnicodeCallback(13, 0);
+	} else {
+		callUnicodeCallback(13, mModifiers);
+	}
+}
+
 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
 {
 	return NSNotFound;
@@ -398,6 +404,10 @@
 
 - (void)doCommandBySelector:(SEL)aSelector
 {
+	if (aSelector == @selector(insertNewline:))
+	{
+		[self insertNewline:self];
+	}
 }
 
 - (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
@@ -419,150 +429,6 @@
 	return self;
 }
 
-- (void) keyDown:(NSEvent *)theEvent
-{
-	
-	uint keycode = [theEvent keyCode];
-	
-	switch (keycode) {
-		case 0x7b:
-		case 0x7c:
-		case 0x7d:
-		case 0x7e:
-			callKeyDown(keycode, mModifiers);
-			break;
-			
-		default:
-			callKeyDown(keycode, mModifiers);
-			NSString *chars = [theEvent characters];
-			for (uint i = 0; i < [chars length]; i++) {
-				// Enter and Return are special cases.
-				unichar returntest = [chars characterAtIndex:i];
-				if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) &&
-					!([theEvent modifierFlags] & NSCommandKeyMask) &&
-					!([theEvent modifierFlags] & NSAlternateKeyMask) &&
-					!([theEvent modifierFlags] & NSControlKeyMask))
-				{
-					callUnicodeCallback(13, 0);
-				} else {
-					// The command key being pressed is also a special case.
-					// Control + <character> produces an ASCII control character code.
-					// Command + <character> produces just the character's code.
-					// Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range.
-					if ([theEvent modifierFlags] & NSCommandKeyMask)
-					{
-						if (returntest >= 64 && returntest <= 95)
-						{
-							callUnicodeCallback(returntest - 63, mModifiers);
-						} else if (returntest >= 97 && returntest <= 122)
-						{
-							callUnicodeCallback(returntest - 96, mModifiers);
-						}
-					} else {
-						callUnicodeCallback(returntest, mModifiers);
-					}
-				}
-			}
-			break;
-	}
-	 
-}
-
-- (void) keyUp:(NSEvent *)theEvent {
-	callKeyUp([theEvent keyCode], mModifiers);
-}
-
-- (void)flagsChanged:(NSEvent *)theEvent {
-	mModifiers = [theEvent modifierFlags];
-	callModifier([theEvent modifierFlags]);
-}
-
-- (void) mouseDown:(NSEvent *)theEvent
-{
-	if ([theEvent clickCount] >= 2)
-	{
-		callDoubleClick(mMousePos, mModifiers);
-	} else if ([theEvent clickCount] == 1) {
-		callLeftMouseDown(mMousePos, mModifiers);
-	}
-}
-
-- (void) mouseUp:(NSEvent *)theEvent
-{
-	callLeftMouseUp(mMousePos, mModifiers);
-}
-
-- (void) rightMouseDown:(NSEvent *)theEvent
-{
-	callRightMouseDown(mMousePos, mModifiers);
-}
-
-- (void) rightMouseUp:(NSEvent *)theEvent
-{
-	callRightMouseUp(mMousePos, mModifiers);
-}
-
-- (void)mouseMoved:(NSEvent *)theEvent
-{
-	float mouseDeltas[2] = {
-		[theEvent deltaX],
-		[theEvent deltaY]
-	};
-	
-	callDeltaUpdate(mouseDeltas, 0);
-	
-	NSPoint mPoint = [theEvent locationInWindow];
-	mMousePos[0] = mPoint.x;
-	mMousePos[1] = mPoint.y;
-	callMouseMoved(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
-{
-	// Trust the deltas supplied by NSEvent.
-	// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
-	// NSEvent isn't obsolete, and provides us with the correct deltas.
-	float mouseDeltas[2] = {
-		[theEvent deltaX],
-		[theEvent deltaY]
-	};
-	
-	callDeltaUpdate(mouseDeltas, 0);
-	
-	NSPoint mPoint = [theEvent locationInWindow];
-	mMousePos[0] = mPoint.x;
-	mMousePos[1] = mPoint.y;
-	callMouseMoved(mMousePos, 0);
-}
-
-- (void) otherMouseDown:(NSEvent *)theEvent
-{
-	callMiddleMouseDown(mMousePos, mModifiers);
-}
-
-- (void) otherMouseUp:(NSEvent *)theEvent
-{
-	callMiddleMouseUp(mMousePos, mModifiers);
-}
-
-- (void) otherMouseDragged:(NSEvent *)theEvent
-{
-	
-}
-
-- (void) scrollWheel:(NSEvent *)theEvent
-{
-	callScrollMoved(-[theEvent deltaY]);
-}
-
-- (void) mouseExited:(NSEvent *)theEvent
-{
-	callMouseExit();
-}
-
 - (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
 {
 	NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
-- 
cgit v1.2.3


From 64c0455db568e6818c483785cff0fcd9cfa47aff Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 19 Mar 2013 23:02:47 -0400
Subject: More LLPreeditor work.

---
 indra/llwindow/llopenglview-objc.mm   | 10 +++++++---
 indra/llwindow/llwindowmacosx-objc.h  |  1 +
 indra/llwindow/llwindowmacosx-objc.mm |  5 +++++
 indra/llwindow/llwindowmacosx.cpp     | 24 ++++++++++++++++++++----
 4 files changed, 33 insertions(+), 7 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 45a5f24481..ca00185dff 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -345,16 +345,21 @@
 
 - (NSRange)markedRange
 {
-	return NSMakeRange(NSNotFound, 0);
+	int range[2];
+	getPreeditMarkedRange(&range[0], &range[1]);
+	return NSMakeRange(range[0], range[1]);
 }
 
 - (NSRange)selectedRange
 {
-	return NSMakeRange(NSNotFound, 0);
+	int range[2];
+	getPreeditSelectionRange(&range[0], &range[1]);
+	return NSMakeRange(range[0], range[1]);
 }
 
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
 {
+	
 }
 
 - (void)unmarkText
@@ -425,7 +430,6 @@
 
 - (id) init
 {
-	[self makeFirstResponder:[self contentView]];
 	return self;
 }
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index f3d6d2b1f1..57bb071690 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -74,6 +74,7 @@ void convertScreenToView(NSWindowRef window, float *coord);
 void setWindowPos(NSWindowRef window, float* pos);
 void closeWindow(NSWindowRef window);
 void removeGLView(GLViewRef view);
+void makeFirstResponder(NSWindowRef window, GLViewRef view);
 
 // These are all implemented in llwindowmacosx.cpp.
 // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index b859f236d4..9530785b83 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -337,6 +337,11 @@ NSWindowRef getMainAppWindow()
 	return winRef;
 }
 
+void makeFirstResponder(NSWindowRef window, GLViewRef view)
+{
+	[(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
+}
+
 /*
 GLViewRef getGLView()
 {
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 08612bace4..7e4b9a84a1 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -383,22 +383,37 @@ void callQuitHandler()
 
 std::basic_string<wchar_t> getPreeditString()
 {
-	return gWindowImplementation->getPreeditor()->getPreeditString();
+	std::basic_string<wchar_t> str;
+	if (gWindowImplementation->getPreeditor())
+	{
+		str = gWindowImplementation->getPreeditor()->getPreeditString();
+	}
+	
+	return str;
 }
 
 void getPreeditSelectionRange(int *position, int *length)
 {
-	gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
+	if (gWindowImplementation->getPreeditor())
+	{
+		gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
+	}
 }
 
 void getPreeditMarkedRange(int *position, int *length)
 {
-	gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
+	if (gWindowImplementation->getPreeditor())
+	{
+		gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
+	}
 }
 
 void handleUnicodeCharacter(wchar_t c)
 {
-	gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
+	if (gWindowImplementation->getPreeditor())
+	{
+		gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
+	}
 }
 
 void LLWindowMacOSX::updateMouseDeltas(float* deltas)
@@ -498,6 +513,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		}
 	}
 	LL_INFOS("Window") << "Completed context creation." << LL_ENDL;
+	makeFirstResponder(mWindow, mGLView);
 	// Don't need to get the current gamma, since there's a call that restores it to the system defaults.
 	return TRUE;
 }
-- 
cgit v1.2.3


From 6c200a94f705667201bcaf0753986da90a2748eb Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Sat, 23 Mar 2013 01:05:21 -0400
Subject: Fix for command key presses + a letter not triggering keyUp.  Fix by
 Katharine Berry.

---
 indra/llwindow/llopenglview-objc.mm | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index ca00185dff..de159816e0 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -283,6 +283,14 @@
 	[[self inputContext] handleEvent:theEvent];
 	uint keycode = [theEvent keyCode];
 	callKeyDown(keycode, mModifiers);
+	
+	// OS X intentionally does not send us key-up information on cmd-key combinations.
+	// This behaviour is not a bug, and only applies to cmd-combinations (no others).
+	// Since SL assumes we receive those, we fake it here.
+	if (mModifiers & NSCommandKeyMask)
+	{
+		callKeyUp([theEvent keyCode], mModifiers);
+	}
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
-- 
cgit v1.2.3


From 258b77b64777a5ce5fef0ef066aa52b34b43ba65 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 25 Mar 2013 05:26:55 -0400
Subject: Additional IME support.  LLPreeditor is largely good to go at this
 point, but there's still some work to do in getSegments.

---
 indra/llwindow/llkeyboardmacosx.cpp   |   1 -
 indra/llwindow/llopenglview-objc.h    |   4 ++
 indra/llwindow/llopenglview-objc.mm   |  97 ++++++++++++++++++++++----
 indra/llwindow/llwindowmacosx-objc.h  |  11 +++
 indra/llwindow/llwindowmacosx-objc.mm |  45 ++++++++++--
 indra/llwindow/llwindowmacosx.cpp     | 126 ++++++++++++++++++++++++++++++----
 6 files changed, 251 insertions(+), 33 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 274e92c225..85bb7b9aeb 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -253,7 +253,6 @@ BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
 
 	if(translateNumpadKey(key, &translated_key))
 	{
-		LL_INFOS("Keyboard") << "Handled key!" << LL_ENDL;
 		handled = handleTranslatedKeyUp(translated_key, translated_mask);
 	}
 
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 5134063193..8140421e44 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -20,6 +20,8 @@
 	std::string mLastDraggedUrl;
 	unsigned int mModifiers;
 	float mMousePos[2];
+	bool mHasMarkedText;
+	unsigned int mMarkedTextLength;
 }
 - (id) initWithSamples:(NSUInteger)samples;
 - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
@@ -40,6 +42,8 @@
 
 - (unsigned long) getVramSize;
 
+- (segment_t) getSegments:(NSAttributedString*)str;
+
 @end
 
 @interface LLNSWindow : NSWindow
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index de159816e0..31b0e02ad8 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -281,15 +281,18 @@
 - (void) keyDown:(NSEvent *)theEvent
 {
 	[[self inputContext] handleEvent:theEvent];
-	uint keycode = [theEvent keyCode];
-	callKeyDown(keycode, mModifiers);
-	
-	// OS X intentionally does not send us key-up information on cmd-key combinations.
-	// This behaviour is not a bug, and only applies to cmd-combinations (no others).
-	// Since SL assumes we receive those, we fake it here.
-	if (mModifiers & NSCommandKeyMask)
+	if (!mHasMarkedText)
 	{
-		callKeyUp([theEvent keyCode], mModifiers);
+		uint keycode = [theEvent keyCode];
+		callKeyDown(keycode, mModifiers);
+		
+		// OS X intentionally does not send us key-up information on cmd-key combinations.
+		// This behaviour is not a bug, and only applies to cmd-combinations (no others).
+		// Since SL assumes we receive those, we fake it here.
+		if (mModifiers & NSCommandKeyMask)
+		{
+			callKeyUp([theEvent keyCode], mModifiers);
+		}
 	}
 }
 
@@ -348,7 +351,7 @@
 
 - (BOOL)hasMarkedText
 {
-	return NO;
+	return mHasMarkedText;
 }
 
 - (NSRange)markedRange
@@ -365,21 +368,73 @@
 	return NSMakeRange(range[0], range[1]);
 }
 
-- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+- (segment_t) getSegments:(NSAttributedString*)str
 {
+	segment_t segments;
+	
+	int segment = 0;
+	
+	NSRange l;
+	NSRange r = NSMakeRange(0, [str length]);
+	
+	while (r.length > 0)
+	{
+		NSNumber *segmentAttrib = [str attribute:NSUnderlineStyleAttributeName atIndex:r.location longestEffectiveRange:&l inRange:r];
+		
+		r = NSMakeRange(NSMaxRange(l), NSMaxRange(r) - NSMaxRange(l));
+		bool standout;
+		if ([segmentAttrib integerValue] == 1)
+		{
+			standout = false;
+		} else {
+			standout = true;
+		}
+		segments.insert(std::pair<int, bool>(l.length, standout));
+		
+		segment++;
+	}
 	
+	return segments;
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+	if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
+	{
+		unsigned int selected[2] = {
+			selectedRange.location,
+			selectedRange.length
+		};
+		
+		unsigned int replacement[2] = {
+			replacementRange.location,
+			replacementRange.length
+		};
+		
+		NSLog(@"Attributed string: %@", aString);
+		
+		unichar text[[aString length]];
+		[[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
+		segment_t segments = [self getSegments:(NSAttributedString *)aString];
+		setMarkedText(text, selected, replacement, [aString length], segments);
+		mHasMarkedText = TRUE;
+		mMarkedTextLength = [aString length];
+	}
 }
 
 - (void)unmarkText
 {
-	
+	resetPreedit();
+	mHasMarkedText = FALSE;
 }
 
+// We don't support attributed strings.
 - (NSArray *)validAttributesForMarkedText
 {
 	return [NSArray array];
 }
 
+// See above.
 - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
 {
 	return nil;
@@ -387,9 +442,21 @@
 
 - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
-	for (NSInteger i = 0; i < [aString length]; i++)
+	if (!mHasMarkedText)
 	{
-		callUnicodeCallback([aString characterAtIndex:i], mModifiers);
+		for (NSInteger i = 0; i < [aString length]; i++)
+		{
+			callUnicodeCallback([aString characterAtIndex:i], mModifiers);
+		}
+	} else {
+		// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
+		// But just in case...
+		resetPreedit();
+		for (NSInteger i = 0; i < [aString length]; i++)
+		{
+			handleUnicodeCharacter([aString characterAtIndex:i]);
+		}
+		mHasMarkedText = FALSE;
 	}
 }
 
@@ -412,7 +479,9 @@
 
 - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
 {
-	return NSZeroRect;
+	float pos[4] = {0, 0, 0, 0};
+	getPreeditLocation(pos, mMarkedTextLength);
+	return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
 }
 
 - (void)doCommandBySelector:(SEL)aSelector
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 57bb071690..2de185fed3 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -25,6 +25,10 @@
  * $/LicenseInfo$
  */
 
+#include <map>
+
+typedef std::map<int, bool> segment_t;
+
 // This will actually hold an NSCursor*, but that type is only available in objective C.
 typedef void *CursorRef;
 typedef void *NSWindowRef;
@@ -71,6 +75,8 @@ void makeWindowOrderFront(NSWindowRef window);
 void convertScreenToWindow(NSWindowRef window, float *coord);
 void convertWindowToScreen(NSWindowRef window, float *coord);
 void convertScreenToView(NSWindowRef window, float *coord);
+void convertRectToScreen(NSWindowRef window, float *coord);
+void convertRectFromScreen(NSWindowRef window, float *coord);
 void setWindowPos(NSWindowRef window, float* pos);
 void closeWindow(NSWindowRef window);
 void removeGLView(GLViewRef view);
@@ -113,6 +119,11 @@ void getPreeditSelectionRange(int *position, int *length);
 void getPreeditMarkedRange(int *position, int *length);
 void handleUnicodeCharacter(wchar_t c);
 void updatePreeditor(unsigned short *str);
+void setPreeditMarkedRange(int position, int length);
+void resetPreedit();
+int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
+void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, segment_t segments);
+void getPreeditLocation(float *location, unsigned int length);
 
 NSWindowRef getMainAppWindow();
 GLViewRef getGLView();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 9530785b83..1a0647485c 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -119,6 +119,7 @@ CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
 void setArrowCursor()
 {
 	NSCursor *cursor = [NSCursor arrowCursor];
+	[NSCursor unhide];
 	[cursor set];
 }
 
@@ -290,12 +291,44 @@ void makeWindowOrderFront(NSWindowRef window)
 
 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;
+	NSRect point;
+	point.origin.x = coord[0];
+	point.origin.y = coord[1];
+	point = [(LLNSWindow*)window convertRectFromScreen:point];
+	coord[0] = point.origin.x;
+	coord[1] = point.origin.y;
+}
+
+void convertRectToScreen(NSWindowRef window, float *coord)
+{
+	NSRect point;
+	point.origin.x = coord[0];
+	point.origin.y = coord[1];
+	point.size.width = coord[2];
+	point.size.height = coord[3];
+	
+	point = [(LLNSWindow*)window convertRectToScreen:point];
+	
+	coord[0] = point.origin.x;
+	coord[1] = point.origin.y;
+	coord[2] = point.size.width;
+	coord[3] = point.size.height;
+}
+
+void convertRectFromScreen(NSWindowRef window, float *coord)
+{
+	NSRect point;
+	point.origin.x = coord[0];
+	point.origin.y = coord[1];
+	point.size.width = coord[2];
+	point.size.height = coord[3];
+	
+	point = [(LLNSWindow*)window convertRectFromScreen:point];
+	
+	coord[0] = point.origin.x;
+	coord[1] = point.origin.y;
+	coord[2] = point.size.width;
+	coord[3] = point.size.height;
 }
 
 void convertScreenToView(NSWindowRef window, float *coord)
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 7e4b9a84a1..4e8934b149 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -381,30 +381,27 @@ void callQuitHandler()
 	}
 }
 
-std::basic_string<wchar_t> getPreeditString()
+void getPreeditSelectionRange(int *position, int *length)
 {
-	std::basic_string<wchar_t> str;
 	if (gWindowImplementation->getPreeditor())
 	{
-		str = gWindowImplementation->getPreeditor()->getPreeditString();
+		gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
 	}
-	
-	return str;
 }
 
-void getPreeditSelectionRange(int *position, int *length)
+void getPreeditMarkedRange(int *position, int *length)
 {
 	if (gWindowImplementation->getPreeditor())
 	{
-		gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
+		gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
 	}
 }
 
-void getPreeditMarkedRange(int *position, int *length)
+void setPreeditMarkedRange(int position, int length)
 {
 	if (gWindowImplementation->getPreeditor())
 	{
-		gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
+		gWindowImplementation->getPreeditor()->markAsPreedit(position, length);
 	}
 }
 
@@ -416,6 +413,69 @@ void handleUnicodeCharacter(wchar_t c)
 	}
 }
 
+void resetPreedit()
+{
+	if (gWindowImplementation->getPreeditor())
+	{
+		gWindowImplementation->getPreeditor()->resetPreedit();
+	}
+}
+
+// For reasons of convenience, handle IME updates here.
+// This largely mirrors the old implementation, only sans the carbon parameters.
+void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, segment_t segments)
+{
+	if (gWindowImplementation->getPreeditor())
+	{
+		LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
+		
+		// This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter.
+		if (replacementRange[0] < replacementRange[1])
+		{
+			const LLWString& text = preeditor->getPreeditString();
+			const S32 location = wstring_wstring_length_from_utf16_length(text, 0, replacementRange[0]);
+			const S32 length = wstring_wstring_length_from_utf16_length(text, location, replacementRange[1]);
+			preeditor->markAsPreedit(location, length);
+		}
+		
+		preeditor->resetPreedit();
+		
+		LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len));
+		
+		LLPreeditor::segment_lengths_t preedit_segment_lengths;
+		LLPreeditor::standouts_t preedit_standouts;
+		S32 caret_position = fix_str.length();
+		
+		for (segment_t::iterator i = segments.begin(); i != segments.end(); i++)
+		{
+			preedit_segment_lengths.push_back(i->first);
+			preedit_standouts.push_back(i->second);
+		}
+		
+		preeditor->updatePreedit(fix_str, preedit_segment_lengths, preedit_standouts, caret_position);
+	}
+}
+
+void getPreeditLocation(float *location, unsigned int length)
+{
+	if (gWindowImplementation->getPreeditor())
+	{
+		LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
+		LLCoordGL coord;
+		LLCoordScreen screen;
+		LLRect rect;
+		
+		preeditor->getPreeditLocation(length, &coord, &rect, NULL);
+		
+		float c[4] = {coord.mX, coord.mY, 0, 0};
+		
+		convertRectToScreen(gWindowImplementation->getWindow(), c);
+		
+		location[0] = c[0];
+		location[1] = c[1];
+	}
+}
+
 void LLWindowMacOSX::updateMouseDeltas(float* deltas)
 {
 	if (mCursorDecoupled)
@@ -1295,8 +1355,22 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to)
 BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to)
 {
 	LLCoordWindow window_coord;
+	if (mFullscreen)
+	{
+		to->mX = from.mX;
+		to->mY = from.mY;
+		return TRUE;
+	} else if (mWindow)
+	{
+		convertCoords(from, &window_coord);
+		convertCoords(window_coord, to);
+		
+		LL_INFOS("Coords") << to->mX << ", " << to->mY << LL_ENDL;
+		
+		return TRUE;
+	}
 
-	return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
+	return FALSE;
 }
 
 
@@ -1425,7 +1499,7 @@ void LLWindowMacOSX::updateCursor()
 		//    Find out what they look like and replicate them.
 
 		// These are essentially correct
-	case UI_CURSOR_WAIT:		/* Apple purposely doesn't allow us to set the beachball cursor manually. */	break;
+	case UI_CURSOR_WAIT:		/* Apple purposely doesn't allow us to set the beachball cursor manually.  Let NSApp figure out when to do this. */	break;
 	case UI_CURSOR_IBEAM:		setIBeamCursor();	break;
 	case UI_CURSOR_CROSS:		setCrossCursor();	break;
 	case UI_CURSOR_HAND:		setPointingHandCursor();	break;
@@ -1810,7 +1884,35 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
 
 void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 {
-	// TODO: IME support
+	if (preeditor != mPreeditor && !b)
+	{
+		// This condition may occur by a call to
+		// setEnabled(BOOL) against LLTextEditor or LLLineEditor
+		// when the control is not focused.
+		// We need to silently ignore the case so that
+		// the language input status of the focused control
+		// is not disturbed.
+		return;
+	}
+	
+	// Take care of old and new preeditors.
+	if (preeditor != mPreeditor || !b)
+	{
+		// We need to interrupt before updating mPreeditor,
+		// so that the fix string from input method goes to
+		// the old preeditor.
+		if (mLanguageTextInputAllowed)
+		{
+			interruptLanguageTextInput();
+		}
+		mPreeditor = (b ? preeditor : NULL);
+	}
+	
+	if (b == mLanguageTextInputAllowed)
+	{
+		return;
+	}
+	mLanguageTextInputAllowed = b;
 }
 
 void LLWindowMacOSX::interruptLanguageTextInput()
-- 
cgit v1.2.3


From 80a79e5d7b4f37f862b312e848b1d1e7f85b0fa9 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Wed, 27 Mar 2013 08:49:45 -0400
Subject: IME support is pretty much finished at this point.

---
 indra/llwindow/llappdelegate-objc.h   |  1 -
 indra/llwindow/llopenglview-objc.h    |  4 +--
 indra/llwindow/llopenglview-objc.mm   | 66 ++++++++++++++++++-----------------
 indra/llwindow/llwindowmacosx-objc.h  | 13 +++++--
 indra/llwindow/llwindowmacosx-objc.mm |  2 +-
 indra/llwindow/llwindowmacosx.cpp     | 13 ++-----
 6 files changed, 50 insertions(+), 49 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index 56b7a30797..6a4794f3c3 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -8,7 +8,6 @@
 
 #import <Cocoa/Cocoa.h>
 #import "llopenglview-objc.h"
-#include "llwindowmacosx-objc.h"
 
 @interface LLAppDelegate : NSObject <NSApplicationDelegate> {
 	LLNSWindow *window;
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 8140421e44..5f972b1a98 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -10,7 +10,7 @@
 #import <IOKit/IOKitLib.h>
 #import <CoreFoundation/CFBase.h>
 #import <CoreFoundation/CFNumber.h>
-#include "llwindowmacosx-objc.h"
+#include <string>
 
 // 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.
@@ -42,8 +42,6 @@
 
 - (unsigned long) getVramSize;
 
-- (segment_t) getSegments:(NSAttributedString*)str;
-
 @end
 
 @interface LLNSWindow : NSWindow
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 31b0e02ad8..376d238c90 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -7,6 +7,7 @@
 //
 
 #import "llopenglview-objc.h"
+#include "llwindowmacosx-objc.h"
 
 @implementation NSScreen (PointConversion)
 
@@ -37,6 +38,37 @@
 
 @end
 
+attributedStringInfo getSegments(NSAttributedString *str)
+{
+	attributedStringInfo segments;
+	segment_lengths seg_lengths;
+	segment_standouts seg_standouts;
+	NSRange effectiveRange;
+	NSRange limitRange = NSMakeRange(0, [str length]);
+	while (limitRange.length > 0) {
+		NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
+		limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
+		
+		if (effectiveRange.length <= 0)
+		{
+			effectiveRange.length = 1;
+		}
+		
+		if ([attr integerValue] == 2)
+		{
+			seg_lengths.push_back(effectiveRange.length);
+			seg_standouts.push_back(true);
+		} else
+		{
+			seg_lengths.push_back(effectiveRange.length);
+			seg_standouts.push_back(false);
+		}
+	}
+	segments.seg_lengths = seg_lengths;
+	segments.seg_standouts = seg_standouts;
+	return segments;
+}
+
 @implementation LLOpenGLView
 
 - (unsigned long)getVramSize
@@ -368,35 +400,6 @@
 	return NSMakeRange(range[0], range[1]);
 }
 
-- (segment_t) getSegments:(NSAttributedString*)str
-{
-	segment_t segments;
-	
-	int segment = 0;
-	
-	NSRange l;
-	NSRange r = NSMakeRange(0, [str length]);
-	
-	while (r.length > 0)
-	{
-		NSNumber *segmentAttrib = [str attribute:NSUnderlineStyleAttributeName atIndex:r.location longestEffectiveRange:&l inRange:r];
-		
-		r = NSMakeRange(NSMaxRange(l), NSMaxRange(r) - NSMaxRange(l));
-		bool standout;
-		if ([segmentAttrib integerValue] == 1)
-		{
-			standout = false;
-		} else {
-			standout = true;
-		}
-		segments.insert(std::pair<int, bool>(l.length, standout));
-		
-		segment++;
-	}
-	
-	return segments;
-}
-
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
 {
 	if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
@@ -411,11 +414,9 @@
 			replacementRange.length
 		};
 		
-		NSLog(@"Attributed string: %@", aString);
-		
 		unichar text[[aString length]];
 		[[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
-		segment_t segments = [self getSegments:(NSAttributedString *)aString];
+		attributedStringInfo segments = getSegments((NSAttributedString *)aString);
 		setMarkedText(text, selected, replacement, [aString length], segments);
 		mHasMarkedText = TRUE;
 		mMarkedTextLength = [aString length];
@@ -452,6 +453,7 @@
 		// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
 		// But just in case...
 		resetPreedit();
+		
 		for (NSInteger i = 0; i < [aString length]; i++)
 		{
 			handleUnicodeCharacter([aString characterAtIndex:i]);
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 2de185fed3..1d05db14b2 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -26,8 +26,17 @@
  */
 
 #include <map>
+#include <vector>
 
-typedef std::map<int, bool> segment_t;
+typedef std::vector<std::pair<int, bool> > segment_t;
+
+typedef std::vector<int> segment_lengths;
+typedef std::vector<int> segment_standouts;
+
+struct attributedStringInfo {
+	segment_lengths seg_lengths;
+	segment_standouts seg_standouts;
+};
 
 // This will actually hold an NSCursor*, but that type is only available in objective C.
 typedef void *CursorRef;
@@ -122,7 +131,7 @@ void updatePreeditor(unsigned short *str);
 void setPreeditMarkedRange(int position, int length);
 void resetPreedit();
 int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
-void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, segment_t segments);
+void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
 void getPreeditLocation(float *location, unsigned int length);
 
 NSWindowRef getMainAppWindow();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 1a0647485c..43f853bfd1 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -27,8 +27,8 @@
 
 #include <AppKit/AppKit.h>
 #include <Cocoa/Cocoa.h>
-#include "llwindowmacosx-objc.h"
 #include "llopenglview-objc.h"
+#include "llwindowmacosx-objc.h"
 #include "llappdelegate-objc.h"
 
 /*
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 4e8934b149..6f66da66a4 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -39,6 +39,7 @@
 #include "indra_constants.h"
 
 #include <OpenGL/OpenGL.h>
+#include <CoreServices/CoreServices.h>
 
 extern BOOL gDebugWindowProc;
 
@@ -423,7 +424,7 @@ void resetPreedit()
 
 // For reasons of convenience, handle IME updates here.
 // This largely mirrors the old implementation, only sans the carbon parameters.
-void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, segment_t segments)
+void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments)
 {
 	if (gWindowImplementation->getPreeditor())
 	{
@@ -442,17 +443,9 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne
 		
 		LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len));
 		
-		LLPreeditor::segment_lengths_t preedit_segment_lengths;
-		LLPreeditor::standouts_t preedit_standouts;
 		S32 caret_position = fix_str.length();
 		
-		for (segment_t::iterator i = segments.begin(); i != segments.end(); i++)
-		{
-			preedit_segment_lengths.push_back(i->first);
-			preedit_standouts.push_back(i->second);
-		}
-		
-		preeditor->updatePreedit(fix_str, preedit_segment_lengths, preedit_standouts, caret_position);
+		preeditor->updatePreedit(fix_str, segments.seg_lengths, segments.seg_standouts, caret_position);
 	}
 }
 
-- 
cgit v1.2.3


From 2656b1f405dcf3b67d644bf47b02a64886ef2ca4 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 1 Apr 2013 08:15:12 -0400
Subject: First pass at adding a viable replacement for TSM's old
 UseInputWindow method (which is now deprecated with seemingly no Cocoa
 replacement).

---
 indra/llwindow/llappdelegate-objc.h   |  6 +++++-
 indra/llwindow/llopenglview-objc.h    | 12 +++++++++---
 indra/llwindow/llopenglview-objc.mm   | 22 +++++++++++++++++++---
 indra/llwindow/llwindowmacosx-objc.h  |  2 ++
 indra/llwindow/llwindowmacosx-objc.mm | 10 ++++++++++
 indra/llwindow/llwindowmacosx.cpp     | 14 +++++++++++---
 6 files changed, 56 insertions(+), 10 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index 6a4794f3c3..e7f6ecd5fc 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -11,11 +11,15 @@
 
 @interface LLAppDelegate : NSObject <NSApplicationDelegate> {
 	LLNSWindow *window;
+	NSWindow *inputWindow;
+	LLNonInlineTextView *inputView;
 	NSTimer *frameTimer;
 }
 
 @property (assign) IBOutlet LLNSWindow *window;
+@property (assign) IBOutlet NSWindow *inputWindow;
+@property (assign) IBOutlet LLNonInlineTextView *inputView;
 
 - (void) mainLoop;
-
+- (void) showInputWindow:(bool)show;
 @end
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 5f972b1a98..6b21148bb6 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -12,9 +12,6 @@
 #import <CoreFoundation/CFNumber.h>
 #include <string>
 
-// 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 <NSTextInputClient>
 {
 	std::string mLastDraggedUrl;
@@ -44,6 +41,15 @@
 
 @end
 
+@interface LLNonInlineTextView : NSTextView
+{
+	LLOpenGLView *glview;
+}
+
+- (void) setGLView:(LLOpenGLView*)view;
+
+@end
+
 @interface LLNSWindow : NSWindow
 
 - (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 376d238c90..a6ef35a8eb 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -501,9 +501,25 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 @end
 
-// We use a custom NSWindow for our event handling.
-// Why not an NSWindowController you may ask?
-// Answer: this is easier.
+@implementation LLNonInlineTextView
+
+- (void) setGLView:(LLOpenGLView *)view
+{
+	glview = view;
+}
+
+- (void) insertText:(id)insertString
+{
+	[self insertText:insertString replacementRange:NSMakeRange(0, 0)];
+}
+
+- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
+{
+	[glview insertText:aString replacementRange:replacementRange];
+	[_window orderOut:_window];
+}
+
+@end
 
 @implementation LLNSWindow
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 1d05db14b2..14a0c22d66 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -90,6 +90,8 @@ void setWindowPos(NSWindowRef window, float* pos);
 void closeWindow(NSWindowRef window);
 void removeGLView(GLViewRef view);
 void makeFirstResponder(NSWindowRef window, GLViewRef view);
+void setupInputWindow(NSWindowRef window, GLViewRef view);
+void showInputWindow(bool show);
 
 // These are all implemented in llwindowmacosx.cpp.
 // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 43f853bfd1..0eef8c9f83 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -362,6 +362,16 @@ void removeGLView(GLViewRef view)
 	[(LLOpenGLView*)view release];
 }
 
+void setupInputWindow(NSWindowRef window, GLViewRef glview)
+{
+	[[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
+}
+
+void showInputWindow(bool show)
+{
+	[(LLAppDelegate*)[NSApp delegate] showInputWindow:show];
+}
+
 NSWindowRef getMainAppWindow()
 {
 	LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 6f66da66a4..2d0f981b3e 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -191,6 +191,8 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 		//start with arrow cursor
 		initCursors();
 		setCursor( UI_CURSOR_ARROW );
+		
+		allowLanguageTextInput(NULL, FALSE);
 	}
 
 	mCallbacks = callbacks;
@@ -513,18 +515,22 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		// Get the view instead.
 		mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync);
 		mContext = getCGLContextObj(mGLView);
+		
 		// Since we just created the context, it needs to be set up.
 		glNeedsInit = TRUE;
 		
 		gGLManager.mVRAM = getVramSize(mGLView);
 	}
-
+	
+	// This sets up our view to recieve text from our non-inline text input window.
+	setupInputWindow(mWindow, mGLView);
+	
 	// Hook up the context to a drawable
 
 	if(mContext != NULL)
 	{
-		LL_INFOS("Window") << "Setting CGL Context..." << LL_ENDL;
-		LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL;
+		
+		
 		U32 err = CGLSetCurrentContext(mContext);
 		if (err != kCGLNoError)
 		{
@@ -1888,6 +1894,8 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 		return;
 	}
 	
+	showInputWindow(!b);
+	
 	// Take care of old and new preeditors.
 	if (preeditor != mPreeditor || !b)
 	{
-- 
cgit v1.2.3


From 5098d43a9be5b9638a8806918e9bb82a096c000f Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 1 Apr 2013 08:25:11 -0400
Subject: STORM-1941: Cocoa project viewer: some coordinate conversions are off
 (Katharine Berry)

---
 indra/llwindow/llwindowmacosx.cpp | 70 +++++----------------------------------
 1 file changed, 8 insertions(+), 62 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 2d0f981b3e..4f6ae5c799 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1255,52 +1255,21 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
 
 BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to)
 {
-	S32		client_height;
-	float	client_rect[4];
-	getContentViewBounds(mWindow, client_rect);
-	if (!mWindow ||
-		NULL == to)
-	{
-		return FALSE;
-	}
-
 	to->mX = from.mX;
-	client_height = client_rect[3];
-	to->mY = from.mY - 1;
-
+	to->mY = from.mY;
 	return TRUE;
 }
 
 BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to)
 {
-	S32		client_height;
-	float	client_rect[4];
-	
-	getContentViewBounds(mWindow, client_rect);
-	
-	if (!mWindow ||
-		NULL == to)
-	{
-		return FALSE;
-	}
-
 	to->mX = from.mX;
-	client_height = client_rect[3];
-	to->mY = from.mY - 1;
-
+	to->mY = from.mY;
 	return TRUE;
 }
 
 BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
 {
-	if(mFullscreen)
-	{
-		// In the fullscreen case, window and screen coordinates are the same.
-		to->mX = from.mX;
-		to->mY = from.mY;
-		return TRUE;
-	}
-	else if(mWindow)
+	if(mWindow)
 	{
 		float mouse_point[2];
 
@@ -1314,20 +1283,12 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
 
 		return TRUE;
 	}
-
 	return FALSE;
 }
 
 BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
 {
-	if(mFullscreen)
-	{
-		// In the fullscreen case, window and screen coordinates are the same.
-		to->mX = from.mX;
-		to->mY = from.mY;
-		return TRUE;
-	}
-	else if(mWindow)
+	if(mWindow)
 	{
 		float mouse_point[2];
 
@@ -1340,7 +1301,6 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
 
 		return TRUE;
 	}
-
 	return FALSE;
 }
 
@@ -1354,22 +1314,8 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to)
 BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to)
 {
 	LLCoordWindow window_coord;
-	if (mFullscreen)
-	{
-		to->mX = from.mX;
-		to->mY = from.mY;
-		return TRUE;
-	} else if (mWindow)
-	{
-		convertCoords(from, &window_coord);
-		convertCoords(window_coord, to);
-		
-		LL_INFOS("Coords") << to->mX << ", " << to->mY << LL_ENDL;
-		
-		return TRUE;
-	}
 
-	return FALSE;
+	return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
 }
 
 
@@ -1981,11 +1927,11 @@ void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDr
 	MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers());
 
 	float mouse_point[2];
-	// This will return the mouse point in global screen coords
+	// This will return the mouse point in window coords
 	getCursorPos(mWindow, mouse_point);
-	LLCoordScreen screen_coords(mouse_point[0], mouse_point[1]);
+	LLCoordWindow window_coords(mouse_point[0], mouse_point[1]);
 	LLCoordGL gl_pos;
-	convertCoords(screen_coords, &gl_pos);
+	convertCoords(window_coords, &gl_pos);
 	
 	if(!url.empty())
 	{
-- 
cgit v1.2.3


From aa0cb35db561004c205c7aac2570407ae88ad472 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Sun, 7 Apr 2013 11:33:39 -0400
Subject: Support the committing of the current pre edit string when language
 input is interrupted per the viewer's original pre edit functionality.

---
 indra/llwindow/llopenglview-objc.h    |  3 +++
 indra/llwindow/llopenglview-objc.mm   | 11 +++++++++++
 indra/llwindow/llwindowmacosx-objc.h  |  1 +
 indra/llwindow/llwindowmacosx-objc.mm |  5 +++++
 indra/llwindow/llwindowmacosx.cpp     |  2 +-
 5 files changed, 21 insertions(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 6b21148bb6..6d0f138950 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -19,11 +19,14 @@
 	float mMousePos[2];
 	bool mHasMarkedText;
 	unsigned int mMarkedTextLength;
+	NSAttributedString *mMarkedText;
 }
 - (id) initWithSamples:(NSUInteger)samples;
 - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
 - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
 
+- (void)commitCurrentPreedit;
+
 // 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.
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index a6ef35a8eb..9d55b2c551 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -420,11 +420,20 @@ attributedStringInfo getSegments(NSAttributedString *str)
 		setMarkedText(text, selected, replacement, [aString length], segments);
 		mHasMarkedText = TRUE;
 		mMarkedTextLength = [aString length];
+		mMarkedText = (NSAttributedString*)[aString mutableString];
 	}
 }
 
+- (void)commitCurrentPreedit
+{
+	[self insertText:mMarkedText replacementRange:NSMakeRange(0, [mMarkedText length])];
+	[[self inputContext] discardMarkedText];
+}
+
 - (void)unmarkText
 {
+	[[self inputContext] discardMarkedText];
+	[mMarkedText setValue:@""];
 	resetPreedit();
 	mHasMarkedText = FALSE;
 }
@@ -517,6 +526,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
 {
 	[glview insertText:aString replacementRange:replacementRange];
 	[_window orderOut:_window];
+	[[self textStorage] setValue:@""];
+	[[self inputContext] discardMarkedText];
 }
 
 @end
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 14a0c22d66..59d956d4c8 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -117,6 +117,7 @@ void callFocus();
 void callFocusLost();
 void callModifier(unsigned int mask);
 void callQuitHandler();
+void commitCurrentPreedit(GLViewRef glView);
 
 #include <string>
 void callHandleDragEntered(std::string url);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 0eef8c9f83..4bd65ade82 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -372,6 +372,11 @@ void showInputWindow(bool show)
 	[(LLAppDelegate*)[NSApp delegate] showInputWindow:show];
 }
 
+void commitCurrentPreedit(GLViewRef glView)
+{
+	[(LLOpenGLView*)glView commitCurrentPreedit];
+}
+
 NSWindowRef getMainAppWindow()
 {
 	LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 4f6ae5c799..e1220c83f4 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1864,7 +1864,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 
 void LLWindowMacOSX::interruptLanguageTextInput()
 {
-	// TODO: IME support
+	commitCurrentPreedit(mGLView);
 }
 
 //static
-- 
cgit v1.2.3


From b27899ee0e035ebd4072a5e6162678f2afe81053 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 13 May 2013 19:39:45 -0400
Subject: Added IME input window white list.

---
 indra/llwindow/llappdelegate-objc.h | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index e7f6ecd5fc..be9ad4d79f 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -14,12 +14,16 @@
 	NSWindow *inputWindow;
 	LLNonInlineTextView *inputView;
 	NSTimer *frameTimer;
+	NSString *currentInputLanguage;
 }
 
 @property (assign) IBOutlet LLNSWindow *window;
 @property (assign) IBOutlet NSWindow *inputWindow;
 @property (assign) IBOutlet LLNonInlineTextView *inputView;
 
+@property (retain) NSString *currentInputLanguage;
+
 - (void) mainLoop;
 - (void) showInputWindow:(bool)show;
+- (void) languageUpdated;
 @end
-- 
cgit v1.2.3


From cda10266ae91e28f2ac60b8472d6b8592f877d65 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 23 May 2013 08:50:05 -0400
Subject: Only show the input window when we attempt to add marked text, *and*
 we can't submit marked text directly to the viewer.

---
 indra/llwindow/llopenglview-objc.h    |  3 ++
 indra/llwindow/llopenglview-objc.mm   | 68 ++++++++++++++++++++++-------------
 indra/llwindow/llwindowmacosx-objc.h  |  9 ++---
 indra/llwindow/llwindowmacosx-objc.mm |  5 +++
 indra/llwindow/llwindowmacosx.cpp     | 42 ++++++++++------------
 5 files changed, 75 insertions(+), 52 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 6d0f138950..e20ea533fb 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -20,6 +20,7 @@
 	bool mHasMarkedText;
 	unsigned int mMarkedTextLength;
 	NSAttributedString *mMarkedText;
+    bool mMarkedTextAllowed;
 }
 - (id) initWithSamples:(NSUInteger)samples;
 - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
@@ -42,6 +43,8 @@
 
 - (unsigned long) getVramSize;
 
+- (void) allowMarkedTextInput:(bool)allowed;
+
 @end
 
 @interface LLNonInlineTextView : NSTextView
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 9d55b2c551..8ef6d4e682 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -45,6 +45,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	segment_standouts seg_standouts;
 	NSRange effectiveRange;
 	NSRange limitRange = NSMakeRange(0, [str length]);
+    
 	while (limitRange.length > 0) {
 		NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
 		limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
@@ -402,32 +403,40 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
 {
-	if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
-	{
-		unsigned int selected[2] = {
-			selectedRange.location,
-			selectedRange.length
-		};
-		
-		unsigned int replacement[2] = {
-			replacementRange.location,
-			replacementRange.length
-		};
-		
-		unichar text[[aString length]];
-		[[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
-		attributedStringInfo segments = getSegments((NSAttributedString *)aString);
-		setMarkedText(text, selected, replacement, [aString length], segments);
-		mHasMarkedText = TRUE;
-		mMarkedTextLength = [aString length];
-		mMarkedText = (NSAttributedString*)[aString mutableString];
-	}
+    if (mMarkedTextAllowed)
+    {
+        if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
+        {
+            unsigned int selected[2] = {
+                selectedRange.location,
+                selectedRange.length
+            };
+            
+            unsigned int replacement[2] = {
+                replacementRange.location,
+                replacementRange.length
+            };
+            
+            unichar text[[aString length]];
+            [[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
+            attributedStringInfo segments = getSegments((NSAttributedString *)aString);
+            setMarkedText(text, selected, replacement, [aString length], segments);
+            mHasMarkedText = TRUE;
+            mMarkedTextLength = [aString length];
+            mMarkedText = (NSAttributedString*)[aString mutableString];
+        }
+    } else {
+        showInputWindow(true);
+    }
 }
 
 - (void)commitCurrentPreedit
 {
-	[self insertText:mMarkedText replacementRange:NSMakeRange(0, [mMarkedText length])];
-	[[self inputContext] discardMarkedText];
+    if (mMarkedText)
+    {
+        [self insertText:mMarkedText];
+        [[self inputContext] discardMarkedText];
+    }
 }
 
 - (void)unmarkText
@@ -452,11 +461,12 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
+    bool success = false;
 	if (!mHasMarkedText)
 	{
 		for (NSInteger i = 0; i < [aString length]; i++)
 		{
-			callUnicodeCallback([aString characterAtIndex:i], mModifiers);
+			success = callUnicodeCallback([aString characterAtIndex:i], mModifiers);
 		}
 	} else {
 		// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
@@ -465,10 +475,12 @@ attributedStringInfo getSegments(NSAttributedString *str)
 		
 		for (NSInteger i = 0; i < [aString length]; i++)
 		{
-			handleUnicodeCharacter([aString characterAtIndex:i]);
+			success = handleUnicodeCharacter([aString characterAtIndex:i]);
 		}
 		mHasMarkedText = FALSE;
 	}
+    
+    NSLog(@"Successful text input: %d", success);
 }
 
 - (void) insertNewline:(id)sender
@@ -508,6 +520,11 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	return NO;
 }
 
+- (void) allowMarkedTextInput:(bool)allowed
+{
+    mMarkedTextAllowed = allowed;
+}
+
 @end
 
 @implementation LLNonInlineTextView
@@ -525,9 +542,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
 - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
 	[glview insertText:aString replacementRange:replacementRange];
-	[_window orderOut:_window];
 	[[self textStorage] setValue:@""];
 	[[self inputContext] discardMarkedText];
+    [self setString:@""];
+    [_window orderOut:_window];
 }
 
 @end
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 59d956d4c8..62543fa01d 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -95,10 +95,10 @@ void showInputWindow(bool show);
 
 // These are all implemented in llwindowmacosx.cpp.
 // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
-void callKeyUp(unsigned short key, unsigned int mask);
-void callKeyDown(unsigned short key, unsigned int mask);
+bool callKeyUp(unsigned short key, unsigned int mask);
+bool callKeyDown(unsigned short key, unsigned int mask);
 void callResetKeys();
-void callUnicodeCallback(wchar_t character, unsigned int mask);
+bool callUnicodeCallback(wchar_t character, unsigned int mask);
 void callRightMouseDown(float *pos, unsigned int mask);
 void callRightMouseUp(float *pos, unsigned int mask);
 void callLeftMouseDown(float *pos, unsigned int mask);
@@ -129,13 +129,14 @@ void callHandleDragDropped(std::string url);
 std::basic_string<wchar_t> getPreeditString();
 void getPreeditSelectionRange(int *position, int *length);
 void getPreeditMarkedRange(int *position, int *length);
-void handleUnicodeCharacter(wchar_t c);
+bool handleUnicodeCharacter(wchar_t c);
 void updatePreeditor(unsigned short *str);
 void setPreeditMarkedRange(int position, int length);
 void resetPreedit();
 int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
 void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
 void getPreeditLocation(float *location, unsigned int length);
+void allowDirectMarkedTextInput(bool allow);
 
 NSWindowRef getMainAppWindow();
 GLViewRef getGLView();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 4bd65ade82..95b9cdb863 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -377,6 +377,11 @@ void commitCurrentPreedit(GLViewRef glView)
 	[(LLOpenGLView*)glView commitCurrentPreedit];
 }
 
+void allowDirectMarkedTextInput(bool allow)
+{
+    
+}
+
 NSWindowRef getMainAppWindow()
 {
 	LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index e1220c83f4..16fd7e3382 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -204,14 +204,14 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 // These functions are used as wrappers for our internal event handling callbacks.
 // It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow.
 
-void callKeyUp(unsigned short key, unsigned int mask)
+bool callKeyUp(unsigned short key, unsigned int mask)
 {
-	gKeyboard->handleKeyUp(key, mask);
+	return gKeyboard->handleKeyUp(key, mask);
 }
 
-void callKeyDown(unsigned short key, unsigned int mask)
+bool callKeyDown(unsigned short key, unsigned int mask)
 {
-	gKeyboard->handleKeyDown(key, mask);
+	return gKeyboard->handleKeyDown(key, mask);
 }
 
 void callResetKeys()
@@ -219,9 +219,9 @@ void callResetKeys()
 	gKeyboard->resetKeys();
 }
 
-void callUnicodeCallback(wchar_t character, unsigned int mask)
+bool callUnicodeCallback(wchar_t character, unsigned int mask)
 {
-	gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
+	return gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
 }
 
 void callFocus()
@@ -408,12 +408,15 @@ void setPreeditMarkedRange(int position, int length)
 	}
 }
 
-void handleUnicodeCharacter(wchar_t c)
+bool handleUnicodeCharacter(wchar_t c)
 {
+    bool success = false;
 	if (gWindowImplementation->getPreeditor())
 	{
-		gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
+        success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
 	}
+    
+    return success;
 }
 
 void resetPreedit()
@@ -1033,21 +1036,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
 
 	return result;
 }
-/*
-static void fixOrigin(void)
-{
-	GrafPtr port;
-	Rect portrect;
 
-	::GetPort(&port);
-	::GetPortBounds(port, &portrect);
-	if((portrect.left != 0) || (portrect.top != 0))
-	{
-		// Mozilla sometimes changes our port origin.
-		::SetOrigin(0,0);
-	}
-}
-*/
 BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
 {
 	float cursor_point[2];
@@ -1840,7 +1829,14 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 		return;
 	}
 	
-	showInputWindow(!b);
+	if (preeditor == NULL) {
+        // If we don't have a pre editor, then we can't accept direct marked text input.
+        // We needs an input window (which is handled internally by LLOpenGLView)
+		allowDirectMarkedTextInput(false);
+	} else {
+        // If we have a preeditor, then accept direct marked text input.
+        allowDirectMarkedTextInput(true);
+    }
 	
 	// Take care of old and new preeditors.
 	if (preeditor != mPreeditor || !b)
-- 
cgit v1.2.3


From 7decac40e6453b2d8822d2677b9b59300bc260cf Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 23 May 2013 09:39:49 -0400
Subject: Override NSPanel's close method to hide the window instead of
 actually removing the window.

---
 indra/llwindow/llopenglview-objc.h  |  4 ++++
 indra/llwindow/llopenglview-objc.mm | 25 ++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index e20ea533fb..5309dea664 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -47,6 +47,10 @@
 
 @end
 
+@interface LLUserInputWindow : NSPanel
+
+@end
+
 @interface LLNonInlineTextView : NSTextView
 {
 	LLOpenGLView *glview;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 8ef6d4e682..17e8c3e3cc 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -527,6 +527,15 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 @end
 
+@implementation LLUserInputWindow
+
+- (void) close
+{
+    [self orderOut:self];
+}
+
+@end
+
 @implementation LLNonInlineTextView
 
 - (void) setGLView:(LLOpenGLView *)view
@@ -536,16 +545,30 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void) insertText:(id)insertString
 {
+	[[self inputContext] discardMarkedText];
+    [self setString:@""];
+    [_window orderOut:_window];
 	[self insertText:insertString replacementRange:NSMakeRange(0, 0)];
 }
 
 - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
 	[glview insertText:aString replacementRange:replacementRange];
+}
+
+- (void) insertNewline:(id)sender
+{
 	[[self textStorage] setValue:@""];
 	[[self inputContext] discardMarkedText];
     [self setString:@""];
-    [_window orderOut:_window];
+}
+
+- (void)doCommandBySelector:(SEL)aSelector
+{
+	if (aSelector == @selector(insertNewline:))
+	{
+		[self insertNewline:self];
+	}
 }
 
 @end
-- 
cgit v1.2.3


From f8abfb63c32a0926a393a4359c6f387482d2448e Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Jun 2013 07:52:19 -0400
Subject: This brings us to feature parity with CHUI for IME support.

---
 indra/llwindow/llopenglview-objc.mm | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 17e8c3e3cc..b431321da6 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -313,12 +313,13 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void) keyDown:(NSEvent *)theEvent
 {
-	[[self inputContext] handleEvent:theEvent];
 	if (!mHasMarkedText)
 	{
 		uint keycode = [theEvent keyCode];
-		callKeyDown(keycode, mModifiers);
-		
+		if (callKeyDown(keycode, mModifiers))
+        {
+            [[self inputContext] handleEvent:theEvent];
+        }
 		// OS X intentionally does not send us key-up information on cmd-key combinations.
 		// This behaviour is not a bug, and only applies to cmd-combinations (no others).
 		// Since SL assumes we receive those, we fake it here.
@@ -461,12 +462,11 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
-    bool success = false;
 	if (!mHasMarkedText)
 	{
 		for (NSInteger i = 0; i < [aString length]; i++)
 		{
-			success = callUnicodeCallback([aString characterAtIndex:i], mModifiers);
+			callUnicodeCallback([aString characterAtIndex:i], mModifiers);
 		}
 	} else {
 		// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
@@ -475,12 +475,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
 		
 		for (NSInteger i = 0; i < [aString length]; i++)
 		{
-			success = handleUnicodeCharacter([aString characterAtIndex:i]);
+			handleUnicodeCharacter([aString characterAtIndex:i]);
 		}
 		mHasMarkedText = FALSE;
 	}
-    
-    NSLog(@"Successful text input: %d", success);
 }
 
 - (void) insertNewline:(id)sender
-- 
cgit v1.2.3


From 93531f3ba85748ba5c9f1d797c4925f55fe8b92c Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Jun 2013 08:59:01 -0400
Subject: Insert text into the input window when we attempt to insert text
 without a pre-editor.  Also handle backspace as a special case when
 determining if the input window needs to be displayed.

---
 indra/llwindow/llappdelegate-objc.h   |  2 +-
 indra/llwindow/llopenglview-objc.mm   | 13 +++++++++----
 indra/llwindow/llwindowmacosx-objc.h  |  2 +-
 indra/llwindow/llwindowmacosx-objc.mm |  4 ++--
 4 files changed, 13 insertions(+), 8 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index be9ad4d79f..b1d78d5e3c 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -24,6 +24,6 @@
 @property (retain) NSString *currentInputLanguage;
 
 - (void) mainLoop;
-- (void) showInputWindow:(bool)show;
+- (void) showInputWindow:(bool)show withText:(id)text;
 - (void) languageUpdated;
 @end
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index b431321da6..062577baf8 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -404,10 +404,11 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
 {
-    if (mMarkedTextAllowed)
+    if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
     {
-        if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
+        if (mMarkedTextAllowed)
         {
+            
             unsigned int selected[2] = {
                 selectedRange.location,
                 selectedRange.length
@@ -425,9 +426,13 @@ attributedStringInfo getSegments(NSAttributedString *str)
             mHasMarkedText = TRUE;
             mMarkedTextLength = [aString length];
             mMarkedText = (NSAttributedString*)[aString mutableString];
+        } else if ([[aString mutableString] characterAtIndex:0] != NSBackspaceCharacter) {
+            showInputWindow(true, aString);
+            if (mHasMarkedText)
+            {
+                [self unmarkText];
+            }
         }
-    } else {
-        showInputWindow(true);
     }
 }
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 62543fa01d..daf7596cab 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -91,7 +91,7 @@ void closeWindow(NSWindowRef window);
 void removeGLView(GLViewRef view);
 void makeFirstResponder(NSWindowRef window, GLViewRef view);
 void setupInputWindow(NSWindowRef window, GLViewRef view);
-void showInputWindow(bool show);
+void showInputWindow(bool show, void* text);
 
 // These are all implemented in llwindowmacosx.cpp.
 // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 95b9cdb863..7f1af129b4 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -367,9 +367,9 @@ void setupInputWindow(NSWindowRef window, GLViewRef glview)
 	[[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
 }
 
-void showInputWindow(bool show)
+void showInputWindow(bool show, void* text)
 {
-	[(LLAppDelegate*)[NSApp delegate] showInputWindow:show];
+	[(LLAppDelegate*)[NSApp delegate] showInputWindow:show withText:(id)text];
 }
 
 void commitCurrentPreedit(GLViewRef glView)
-- 
cgit v1.2.3


From 440a1ee3bae4ea9553fa57d806f942a472923190 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Jun 2013 09:26:11 -0400
Subject: Move logic involving the input window to keyDown.  Pass input events
 to the input window from there.

---
 indra/llwindow/llopenglview-objc.h  | 5 +++++
 indra/llwindow/llopenglview-objc.mm | 9 +++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 5309dea664..d4207d598a 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -6,6 +6,9 @@
 //
 //
 
+#ifndef LLOpenGLView_H
+#define LLOpenGLView_H
+
 #import <Cocoa/Cocoa.h>
 #import <IOKit/IOKitLib.h>
 #import <CoreFoundation/CFBase.h>
@@ -85,3 +88,5 @@
 - (NSPoint)flipPoint:(NSPoint)aPoint;
 
 @end
+
+#endif
\ No newline at end of file
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 062577baf8..99c27e79a0 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -8,6 +8,7 @@
 
 #import "llopenglview-objc.h"
 #include "llwindowmacosx-objc.h"
+#import "llappdelegate-objc.h"
 
 @implementation NSScreen (PointConversion)
 
@@ -318,6 +319,11 @@ attributedStringInfo getSegments(NSAttributedString *str)
 		uint keycode = [theEvent keyCode];
 		if (callKeyDown(keycode, mModifiers))
         {
+            if (!mMarkedTextAllowed && [[theEvent characters] characterAtIndex:0] != NSBackspaceCharacter)
+            {
+                showInputWindow(true, @"");
+                [[[(LLAppDelegate*)[NSApp delegate] inputView] inputContext] handleEvent:theEvent];
+            }
             [[self inputContext] handleEvent:theEvent];
         }
 		// OS X intentionally does not send us key-up information on cmd-key combinations.
@@ -426,8 +432,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
             mHasMarkedText = TRUE;
             mMarkedTextLength = [aString length];
             mMarkedText = (NSAttributedString*)[aString mutableString];
-        } else if ([[aString mutableString] characterAtIndex:0] != NSBackspaceCharacter) {
-            showInputWindow(true, aString);
+        } else {
             if (mHasMarkedText)
             {
                 [self unmarkText];
-- 
cgit v1.2.3


From 2253d22eb85a6b4c5e48b9905d807d0ac48b1930 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Jun 2013 10:28:32 -0400
Subject: Have showInputWindow hand off input events to the bottom line input
 window.

---
 indra/llwindow/llappdelegate-objc.h   | 2 +-
 indra/llwindow/llopenglview-objc.mm   | 9 +++++++--
 indra/llwindow/llwindowmacosx-objc.h  | 1 -
 indra/llwindow/llwindowmacosx-objc.mm | 5 -----
 4 files changed, 8 insertions(+), 9 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index b1d78d5e3c..266f417c4b 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -24,6 +24,6 @@
 @property (retain) NSString *currentInputLanguage;
 
 - (void) mainLoop;
-- (void) showInputWindow:(bool)show withText:(id)text;
+- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
 - (void) languageUpdated;
 @end
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 99c27e79a0..2afd4993c5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -321,11 +321,16 @@ attributedStringInfo getSegments(NSAttributedString *str)
         {
             if (!mMarkedTextAllowed && [[theEvent characters] characterAtIndex:0] != NSBackspaceCharacter)
             {
-                showInputWindow(true, @"");
-                [[[(LLAppDelegate*)[NSApp delegate] inputView] inputContext] handleEvent:theEvent];
+                [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
             }
+            
+            [[self inputContext] handleEvent:theEvent];
+        } else if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == 13 || [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == 3)
+        {
+            // callKeyDown won't return the value we expect for enter or return.  Handle them as a separate case.
             [[self inputContext] handleEvent:theEvent];
         }
+        
 		// OS X intentionally does not send us key-up information on cmd-key combinations.
 		// This behaviour is not a bug, and only applies to cmd-combinations (no others).
 		// Since SL assumes we receive those, we fake it here.
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index daf7596cab..5b1f22046b 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -91,7 +91,6 @@ void closeWindow(NSWindowRef window);
 void removeGLView(GLViewRef view);
 void makeFirstResponder(NSWindowRef window, GLViewRef view);
 void setupInputWindow(NSWindowRef window, GLViewRef view);
-void showInputWindow(bool show, void* text);
 
 // These are all implemented in llwindowmacosx.cpp.
 // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 7f1af129b4..33a8cf34ce 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -367,11 +367,6 @@ void setupInputWindow(NSWindowRef window, GLViewRef glview)
 	[[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
 }
 
-void showInputWindow(bool show, void* text)
-{
-	[(LLAppDelegate*)[NSApp delegate] showInputWindow:show withText:(id)text];
-}
-
 void commitCurrentPreedit(GLViewRef glView)
 {
 	[(LLOpenGLView*)glView commitCurrentPreedit];
-- 
cgit v1.2.3


From 84f287b34e7d7edbd2e897b73008c782aabe60de Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Jun 2013 12:31:25 -0400
Subject: Moved detecting if we're using a roman-script language to it's own
 function in the application delegate.  Also consider the delete and backspace
 characters to be special cases.

---
 indra/llwindow/llappdelegate-objc.h |  1 +
 indra/llwindow/llopenglview-objc.mm | 22 ++++++++++++++--------
 2 files changed, 15 insertions(+), 8 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index 266f417c4b..a6fb77d93f 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -26,4 +26,5 @@
 - (void) mainLoop;
 - (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
 - (void) languageUpdated;
+- (bool) romanScript;
 @end
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 2afd4993c5..c3f0ef4aeb 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -317,15 +317,21 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	if (!mHasMarkedText)
 	{
 		uint keycode = [theEvent keyCode];
-		if (callKeyDown(keycode, mModifiers))
+        bool acceptsText = callKeyDown(keycode, mModifiers);
+        if (acceptsText &&
+            !mMarkedTextAllowed &&
+            ![(LLAppDelegate*)[NSApp delegate] romanScript] &&
+            [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
+            [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter)
+        {
+            [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
+        } else
         {
-            if (!mMarkedTextAllowed && [[theEvent characters] characterAtIndex:0] != NSBackspaceCharacter)
-            {
-                [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
-            }
-            
             [[self inputContext] handleEvent:theEvent];
-        } else if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == 13 || [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == 3)
+        }
+        
+        if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
+            [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
         {
             // callKeyDown won't return the value we expect for enter or return.  Handle them as a separate case.
             [[self inputContext] handleEvent:theEvent];
@@ -438,7 +444,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
             mMarkedTextLength = [aString length];
             mMarkedText = (NSAttributedString*)[aString mutableString];
         } else {
-            if (mHasMarkedText)
+            if (mHasMarkedText || ![mMarkedText isEqual: @""])
             {
                 [self unmarkText];
             }
-- 
cgit v1.2.3


From 2837ca7a474f92bb363a2a31d184431b636d2809 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Mon, 17 Jun 2013 17:08:48 -0400
Subject: This seems to be on par with viewer-release at this point.

---
 indra/llwindow/llopenglview-objc.h    |  1 -
 indra/llwindow/llopenglview-objc.mm   | 84 ++++++++++++++++++-----------------
 indra/llwindow/llwindowmacosx-objc.h  |  2 +-
 indra/llwindow/llwindowmacosx-objc.mm |  4 +-
 indra/llwindow/llwindowmacosx.cpp     | 42 ++++++++++++------
 indra/llwindow/llwindowmacosx.h       |  2 +
 6 files changed, 78 insertions(+), 57 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index d4207d598a..b783c41c0b 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -22,7 +22,6 @@
 	float mMousePos[2];
 	bool mHasMarkedText;
 	unsigned int mMarkedTextLength;
-	NSAttributedString *mMarkedText;
     bool mMarkedTextAllowed;
 }
 - (id) initWithSamples:(NSUInteger)samples;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index c3f0ef4aeb..24de5912f0 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -314,37 +314,34 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void) keyDown:(NSEvent *)theEvent
 {
-	if (!mHasMarkedText)
-	{
-		uint keycode = [theEvent keyCode];
-        bool acceptsText = callKeyDown(keycode, mModifiers);
-        if (acceptsText &&
-            !mMarkedTextAllowed &&
-            ![(LLAppDelegate*)[NSApp delegate] romanScript] &&
-            [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
-            [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter)
-        {
-            [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
-        } else
-        {
-            [[self inputContext] handleEvent:theEvent];
-        }
-        
-        if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
-            [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
-        {
-            // callKeyDown won't return the value we expect for enter or return.  Handle them as a separate case.
-            [[self inputContext] handleEvent:theEvent];
-        }
-        
-		// OS X intentionally does not send us key-up information on cmd-key combinations.
-		// This behaviour is not a bug, and only applies to cmd-combinations (no others).
-		// Since SL assumes we receive those, we fake it here.
-		if (mModifiers & NSCommandKeyMask)
-		{
-			callKeyUp([theEvent keyCode], mModifiers);
-		}
-	}
+    uint keycode = [theEvent keyCode];
+    bool acceptsText = callKeyDown(keycode, mModifiers);
+    if (acceptsText &&
+        !mMarkedTextAllowed &&
+        ![(LLAppDelegate*)[NSApp delegate] romanScript] &&
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter)
+    {
+        [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
+    } else
+    {
+        [[self inputContext] handleEvent:theEvent];
+    }
+    
+    if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
+    {
+        // callKeyDown won't return the value we expect for enter or return.  Handle them as a separate case.
+        [[self inputContext] handleEvent:theEvent];
+    }
+    
+    // OS X intentionally does not send us key-up information on cmd-key combinations.
+    // This behaviour is not a bug, and only applies to cmd-combinations (no others).
+    // Since SL assumes we receive those, we fake it here.
+    if (mModifiers & NSCommandKeyMask)
+    {
+        callKeyUp([theEvent keyCode], mModifiers);
+    }
 }
 
 - (void)flagsChanged:(NSEvent *)theEvent {
@@ -425,7 +422,6 @@ attributedStringInfo getSegments(NSAttributedString *str)
     {
         if (mMarkedTextAllowed)
         {
-            
             unsigned int selected[2] = {
                 selectedRange.location,
                 selectedRange.length
@@ -442,9 +438,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
             setMarkedText(text, selected, replacement, [aString length], segments);
             mHasMarkedText = TRUE;
             mMarkedTextLength = [aString length];
-            mMarkedText = (NSAttributedString*)[aString mutableString];
         } else {
-            if (mHasMarkedText || ![mMarkedText isEqual: @""])
+            if (mHasMarkedText)
             {
                 [self unmarkText];
             }
@@ -454,17 +449,18 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)commitCurrentPreedit
 {
-    if (mMarkedText)
+    if (mHasMarkedText)
     {
-        [self insertText:mMarkedText];
-        [[self inputContext] discardMarkedText];
+        if ([[self inputContext] respondsToSelector:@selector(commitEditing)])
+        {
+            [[self inputContext] commitEditing];
+        }
     }
 }
 
 - (void)unmarkText
 {
 	[[self inputContext] discardMarkedText];
-	[mMarkedText setValue:@""];
 	resetPreedit();
 	mHasMarkedText = FALSE;
 }
@@ -481,6 +477,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	return nil;
 }
 
+- (void)insertText:(id)insertString
+{
+    if (insertString != nil)
+    {
+        [self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
+    }
+}
+
 - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
 	if (!mHasMarkedText)
@@ -490,9 +494,9 @@ attributedStringInfo getSegments(NSAttributedString *str)
 			callUnicodeCallback([aString characterAtIndex:i], mModifiers);
 		}
 	} else {
+        resetPreedit();
 		// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
 		// But just in case...
-		resetPreedit();
 		
 		for (NSInteger i = 0; i < [aString length]; i++)
 		{
@@ -567,7 +571,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	[[self inputContext] discardMarkedText];
     [self setString:@""];
     [_window orderOut:_window];
-	[self insertText:insertString replacementRange:NSMakeRange(0, 0)];
+	[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
 }
 
 - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 5b1f22046b..914fc534fb 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -135,7 +135,7 @@ void resetPreedit();
 int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
 void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
 void getPreeditLocation(float *location, unsigned int length);
-void allowDirectMarkedTextInput(bool allow);
+void allowDirectMarkedTextInput(bool allow, GLViewRef glView);
 
 NSWindowRef getMainAppWindow();
 GLViewRef getGLView();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 33a8cf34ce..67b5279c0b 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -372,9 +372,9 @@ void commitCurrentPreedit(GLViewRef glView)
 	[(LLOpenGLView*)glView commitCurrentPreedit];
 }
 
-void allowDirectMarkedTextInput(bool allow)
+void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
 {
-    
+    [(LLOpenGLView*)glView allowMarkedTextInput:allow];
 }
 
 NSWindowRef getMainAppWindow()
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 16fd7e3382..737ecba368 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -239,6 +239,11 @@ void callFocusLost()
 
 void callRightMouseDown(float *pos, MASK mask)
 {
+    if (gWindowImplementation->allowsLanguageInput())
+    {
+        gWindowImplementation->interruptLanguageTextInput();
+    }
+    
 	LLCoordGL		outCoords;
 	outCoords.mX = llround(pos[0]);
 	outCoords.mY = llround(pos[1]);
@@ -247,6 +252,11 @@ void callRightMouseDown(float *pos, MASK mask)
 
 void callRightMouseUp(float *pos, MASK mask)
 {
+    if (gWindowImplementation->allowsLanguageInput())
+    {
+        gWindowImplementation->interruptLanguageTextInput();
+    }
+    
 	LLCoordGL		outCoords;
 	outCoords.mX = llround(pos[0]);
 	outCoords.mY = llround(pos[1]);
@@ -255,6 +265,11 @@ void callRightMouseUp(float *pos, MASK mask)
 
 void callLeftMouseDown(float *pos, MASK mask)
 {
+    if (gWindowImplementation->allowsLanguageInput())
+    {
+        gWindowImplementation->interruptLanguageTextInput();
+    }
+    
 	LLCoordGL		outCoords;
 	outCoords.mX = llround(pos[0]);
 	outCoords.mY = llround(pos[1]);
@@ -263,6 +278,11 @@ void callLeftMouseDown(float *pos, MASK mask)
 
 void callLeftMouseUp(float *pos, MASK mask)
 {
+    if (gWindowImplementation->allowsLanguageInput())
+    {
+        gWindowImplementation->interruptLanguageTextInput();
+    }
+    
 	LLCoordGL		outCoords;
 	outCoords.mX = llround(pos[0]);
 	outCoords.mY = llround(pos[1]);
@@ -272,6 +292,11 @@ void callLeftMouseUp(float *pos, MASK mask)
 
 void callDoubleClick(float *pos, MASK mask)
 {
+    if (gWindowImplementation->allowsLanguageInput())
+    {
+        gWindowImplementation->interruptLanguageTextInput();
+    }
+    
 	LLCoordGL	outCoords;
 	outCoords.mX = llround(pos[0]);
 	outCoords.mY = llround(pos[1]);
@@ -434,7 +459,7 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne
 	if (gWindowImplementation->getPreeditor())
 	{
 		LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
-		
+		preeditor->resetPreedit();
 		// This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter.
 		if (replacementRange[0] < replacementRange[1])
 		{
@@ -444,8 +469,6 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne
 			preeditor->markAsPreedit(location, length);
 		}
 		
-		preeditor->resetPreedit();
-		
 		LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len));
 		
 		S32 caret_position = fix_str.length();
@@ -1818,6 +1841,8 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
 
 void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 {
+    allowDirectMarkedTextInput(b, mGLView);
+	
 	if (preeditor != mPreeditor && !b)
 	{
 		// This condition may occur by a call to
@@ -1828,16 +1853,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 		// is not disturbed.
 		return;
 	}
-	
-	if (preeditor == NULL) {
-        // If we don't have a pre editor, then we can't accept direct marked text input.
-        // We needs an input window (which is handled internally by LLOpenGLView)
-		allowDirectMarkedTextInput(false);
-	} else {
-        // If we have a preeditor, then accept direct marked text input.
-        allowDirectMarkedTextInput(true);
-    }
-	
+    
 	// Take care of old and new preeditors.
 	if (preeditor != mPreeditor || !b)
 	{
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index de0340cf74..82195c2700 100755
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -126,6 +126,8 @@ public:
 	void getMouseDeltas(float* delta);
 	
 	void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
+    
+    bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
 
 protected:
 	LLWindowMacOSX(LLWindowCallbacks* callbacks,
-- 
cgit v1.2.3


From 90e511bbdf9e08059180218e47350e4d2b431b68 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 20 Jun 2013 11:28:05 -0400
Subject: Handle VRAM in megabytes.  This was previously being reported as
 bytes.

---
 indra/llwindow/llopenglview-objc.mm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 24de5912f0..aa7df2c985 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -88,7 +88,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
     {
         vram_bytes = (256 << 20);
     }
-	return (unsigned long)vram_bytes;
+    
+	return (unsigned long)vram_bytes / 1048576; // We need this in megabytes.
 }
 
 - (void)viewDidMoveToWindow
-- 
cgit v1.2.3


From 860b86e3d1c61c18be99301ea1c5027058a8353d Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 27 Jun 2013 13:48:44 -0400
Subject: Fix for down key presses not opening up the IME character selection
 window, and inadvertently being handled while marked text is selected.

---
 indra/llwindow/llopenglview-objc.mm | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index aa7df2c985..7803d78862 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -316,12 +316,16 @@ attributedStringInfo getSegments(NSAttributedString *str)
 - (void) keyDown:(NSEvent *)theEvent
 {
     uint keycode = [theEvent keyCode];
-    bool acceptsText = callKeyDown(keycode, mModifiers);
+    bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers);
     if (acceptsText &&
         !mMarkedTextAllowed &&
         ![(LLAppDelegate*)[NSApp delegate] romanScript] &&
         [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
-        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter)
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter &&
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey &&
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey &&
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey &&
+        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey)
     {
         [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
     } else
@@ -339,7 +343,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
     // OS X intentionally does not send us key-up information on cmd-key combinations.
     // This behaviour is not a bug, and only applies to cmd-combinations (no others).
     // Since SL assumes we receive those, we fake it here.
-    if (mModifiers & NSCommandKeyMask)
+    if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
     {
         callKeyUp([theEvent keyCode], mModifiers);
     }
-- 
cgit v1.2.3


From 623077e6a4eef516d445975eaa71d5f67e6767c5 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 27 Jun 2013 15:06:03 -0400
Subject: Added license headers.

---
 indra/llwindow/llappdelegate-objc.h   | 32 ++++++++++++++++++-----
 indra/llwindow/llopenglview-objc.h    | 32 ++++++++++++++++++-----
 indra/llwindow/llopenglview-objc.mm   | 32 ++++++++++++++++++-----
 indra/llwindow/llwindowmacosx-objc.mm | 48 +++++++++++++++++------------------
 4 files changed, 99 insertions(+), 45 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
index a6fb77d93f..faa5d3abb7 100644
--- a/indra/llwindow/llappdelegate-objc.h
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -1,10 +1,28 @@
-//
-//  LLAppDelegate.h
-//  SecondLife
-//
-//  Created by Geenz on 12/16/12.
-//
-//
+/**
+ * @file llappdelegate-objc.h
+ * @brief Class interface for the Mac version's application delegate.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
 
 #import <Cocoa/Cocoa.h>
 #import "llopenglview-objc.h"
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index b783c41c0b..f895aae577 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -1,10 +1,28 @@
-//
-//  LLOpenGLView.h
-//  SecondLife
-//
-//  Created by Geenz on 10/2/12.
-//
-//
+/**
+ * @file llopenglview-objc.h
+ * @brief Class interfaces for most of the Mac facing window functionality.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
 
 #ifndef LLOpenGLView_H
 #define LLOpenGLView_H
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 7803d78862..8a6984091d 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -1,10 +1,28 @@
-//
-//  LLOpenGLView.m
-//  SecondLife
-//
-//  Created by Geenz on 10/2/12.
-//
-//
+/**
+ * @file llopenglview-objc.mm
+ * @brief Class implementation for most of the Mac facing window functionality.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
 
 #import "llopenglview-objc.h"
 #include "llwindowmacosx-objc.h"
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 67b5279c0b..41d8e3ecd9 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file llwindowmacosx-objc.mm
  * @brief Definition of functions shared between llwindowmacosx.cpp
  * and llwindowmacosx-objc.mm.
@@ -6,21 +6,21 @@
  * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -52,10 +52,10 @@ void setupCocoa()
 		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 		
 		// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
-		// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' 
-		// when init'ing the Cocoa App window.		
+		// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
+		// when init'ing the Cocoa App window.
 		[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
-
+		
 		[pool release];
 		
 		inited = true;
@@ -100,17 +100,17 @@ const unsigned short *copyFromPBoard()
 CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
 {
 	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+	
 	// extra retain on the NSCursor since we want it to live for the lifetime of the app.
 	NSCursor *cursor =
-		[[[NSCursor alloc] 
-				initWithImage:
-					[[[NSImage alloc] initWithContentsOfFile:
-						[NSString stringWithFormat:@"%s", fullpath]
-					]autorelease] 
-				hotSpot:NSMakePoint(hotspotX, hotspotY)
-		]retain];	
-		
+	[[[NSCursor alloc]
+	  initWithImage:
+	  [[[NSImage alloc] initWithContentsOfFile:
+		[NSString stringWithFormat:@"%s", fullpath]
+		]autorelease]
+	  hotSpot:NSMakePoint(hotspotX, hotspotY)
+	  ]retain];
+	
 	[pool release];
 	
 	return (CursorRef)cursor;
@@ -209,7 +209,7 @@ OSErr setImageCursor(CursorRef ref)
 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];
+													  styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
 	[window makeKeyAndOrderFront:nil];
 	[window setAcceptsMouseMovedEvents:TRUE];
 	return window;
@@ -391,13 +391,13 @@ void makeFirstResponder(NSWindowRef window, GLViewRef view)
 }
 
 /*
-GLViewRef getGLView()
-{
-	return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
-}
-*/
+ GLViewRef getGLView()
+ {
+ return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
+ }
+ */
 
 unsigned int getModifiers()
-{	
+{
 	return [NSEvent modifierFlags];
 }
-- 
cgit v1.2.3


From 6fbafaf056d61ab0ab49cc16a998a528f0ea22e8 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 18:41:16 -0400
Subject: Restore control + right click functionality.

---
 indra/llwindow/llopenglview-objc.mm | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 8a6984091d..77c2fc7e19 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -242,12 +242,18 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
-	if ([theEvent clickCount] >= 2)
-	{
-		callDoubleClick(mMousePos, mModifiers);
-	} else if ([theEvent clickCount] == 1) {
-		callLeftMouseDown(mMousePos, mModifiers);
-	}
+    // Apparently people still use this?
+    if ([theEvent modifierFlags] & NSControlKeyMask)
+    {
+        callRightMouseDown(mMousePos, mModifiers);
+    } else {
+        if ([theEvent clickCount] >= 2)
+        {
+            callDoubleClick(mMousePos, mModifiers);
+        } else if ([theEvent clickCount] == 1) {
+            callLeftMouseDown(mMousePos, mModifiers);
+        }
+    }
 }
 
 - (void) mouseUp:(NSEvent *)theEvent
-- 
cgit v1.2.3


From 72bb473c9ed106cce6baf22ac74a13443d4630e8 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 18:59:28 -0400
Subject: Ensure that the correct method is called when we're simulating a
 right click.

---
 indra/llwindow/llopenglview-objc.h  | 1 +
 indra/llwindow/llopenglview-objc.mm | 9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index f895aae577..71149f8561 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -41,6 +41,7 @@
 	bool mHasMarkedText;
 	unsigned int mMarkedTextLength;
     bool mMarkedTextAllowed;
+    bool mSimulatedRightClick;
 }
 - (id) initWithSamples:(NSUInteger)samples;
 - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 77c2fc7e19..e5b7681435 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -246,6 +246,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
     if ([theEvent modifierFlags] & NSControlKeyMask)
     {
         callRightMouseDown(mMousePos, mModifiers);
+        mSimulatedRightClick = true;
     } else {
         if ([theEvent clickCount] >= 2)
         {
@@ -258,7 +259,13 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void) mouseUp:(NSEvent *)theEvent
 {
-	callLeftMouseUp(mMousePos, mModifiers);
+    if (mSimulatedRightClick)
+    {
+        callRightMouseUp(mMousePos, mModifiers);
+        mSimulatedRightClick = false;
+    } else {
+        callLeftMouseUp(mMousePos, mModifiers);
+    }
 }
 
 - (void) rightMouseDown:(NSEvent *)theEvent
-- 
cgit v1.2.3


From b2bec3f99c74d21bb1c2c68d73854f3990db26d5 Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 19:37:08 -0400
Subject: STORM-1942: dock icon bouncing unimplemented

---
 indra/llwindow/llwindowmacosx-objc.h  |  1 +
 indra/llwindow/llwindowmacosx-objc.mm |  5 +++++
 indra/llwindow/llwindowmacosx.cpp     | 34 +++-------------------------------
 indra/llwindow/llwindowmacosx.h       |  5 -----
 4 files changed, 9 insertions(+), 36 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 914fc534fb..020e2bff5b 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -68,6 +68,7 @@ void setNotAllowedCursor();
 void hideNSCursor();
 void showNSCursor();
 void hideNSCursorTillMove(bool hide);
+void requestUserAttention();
 
 NSWindowRef createNSWindow(int x, int y, int width, int height);
 
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 41d8e3ecd9..ef29515403 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -390,6 +390,11 @@ void makeFirstResponder(NSWindowRef window, GLViewRef view)
 	[(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
 }
 
+void requestUserAttention()
+{
+	[[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
+}
+
 /*
  GLViewRef getGLView()
  {
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 737ecba368..e5556c23d4 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -149,10 +149,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	mFSAASamples = fsaa_samples;
 	mForceRebuild = FALSE;
 
-	// For reasons that aren't clear to me, LLTimers seem to be created in the "started" state.
-	// Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state.
-	mBounceTimer.stop();
-
 	// Get the original aspect ratio of the main device.
 	mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay);
 
@@ -763,12 +759,6 @@ BOOL LLWindowMacOSX::getFullscreen()
 
 void LLWindowMacOSX::gatherInput()
 {
-	// stop bouncing icon after fixed period of time
-	if (mBounceTimer.getStarted() && mBounceTimer.getElapsedTimeF32() > mBounceTime)
-	{
-		stopDockTileBounce();
-	}
-	
 	updateCursor();
 }
 
@@ -1161,22 +1151,9 @@ void LLWindowMacOSX::afterDialog()
 
 void LLWindowMacOSX::flashIcon(F32 seconds)
 {
-	// Don't do this if we're already started, since this would try to install the NMRec twice.
-	if(!mBounceTimer.getStarted())
-	{
-		S32 err = 0;
-		// TODO: Implement icon bouncing
-		mBounceTime = seconds;
-		if(err == 0)
-		{
-			mBounceTimer.start();
-		}
-		else
-		{
-			// This is very not-fatal (only problem is the icon will not bounce), but we'd like to find out about it somehow...
-			llinfos << "NMInstall failed with error code " << err << llendl;
-		}
-	}
+	// For consistency with OS X conventions, the number of seconds given is ignored and
+	// left up to the OS (which will actually bounce it for one second).
+	requestUserAttention();
 }
 
 BOOL LLWindowMacOSX::isClipboardTextAvailable()
@@ -1809,11 +1786,6 @@ void *LLWindowMacOSX::getPlatformWindow()
 	return (void*)mWindow;
 }
 
-void LLWindowMacOSX::stopDockTileBounce()
-{
-	mBounceTimer.stop();
-}
-
 // get a double value from a dictionary
 /*
 static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 82195c2700..6a6b39e674 100755
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -164,7 +164,6 @@ protected:
 	void destroyContext();
 	void setupFailure(const std::string& text, const std::string& caption, U32 type);
 	void adjustCursorDecouple(bool warpingMouse = false);
-	void stopDockTileBounce();
 	static MASK modifiersToMask(S16 modifiers);
 	
 #if LL_OS_DRAGDROP_ENABLED
@@ -206,10 +205,6 @@ protected:
 	BOOL		mForceRebuild;
 	
 	S32	mDragOverrideCursor;
-	
-	F32			mBounceTime;
-	//NMRec		mBounceRec;
-	LLTimer		mBounceTimer;
 
 	// Input method management through Text Service Manager.
 	BOOL		mLanguageTextInputAllowed;
-- 
cgit v1.2.3


From dc7d287717ed42d1d8aa8b57cfd740ca75fe9e7b Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 19:41:57 -0400
Subject: OPEN-170: "Set Window Size" always increases window size by specified
 size

---
 indra/llwindow/llwindowmacosx.cpp | 21 +++------------------
 1 file changed, 3 insertions(+), 18 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index e5556c23d4..d657c629b9 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -863,26 +863,11 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size)
 
 BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
 {
-	float client_rect[4];
 	if (mWindow)
 	{
-		S32 err = noErr;
-		getContentViewBounds(mWindow, client_rect);
-		if (err == noErr)
-		{
-			client_rect[2] += size.mX;
-			client_rect[3] += size.mY;
-			setWindowSize(mWindow, client_rect[2], client_rect[3]);
-		}
-		if (err == noErr)
-		{
-			return TRUE;
-		}
-		else
-		{
-			llinfos << "Error setting size" << err << llendl;
-			return FALSE;
-		}
+		LLCoordScreen screen_size;
+		convertCoords(size, &screen_size);
+		return setSizeImpl(screen_size);
 	}
 	return FALSE;
 }
-- 
cgit v1.2.3


From a787e272c31d8e535dae75e4d95365d17cec78db Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 21:31:17 -0400
Subject: Alert box support!

---
 indra/llwindow/llopenglview-objc.mm   |  2 +-
 indra/llwindow/llwindowmacosx-objc.h  |  1 +
 indra/llwindow/llwindowmacosx-objc.mm | 35 +++++++++++++++++++++++++++++++++++
 indra/llwindow/llwindowmacosx.cpp     | 23 +----------------------
 4 files changed, 38 insertions(+), 23 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index e5b7681435..42ad4f8723 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -668,7 +668,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (BOOL) resignFirstResponder
 {
-	callFocus();
+	callFocusLost();
 	return true;
 }
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 020e2bff5b..32b3bfb078 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -69,6 +69,7 @@ void hideNSCursor();
 void showNSCursor();
 void hideNSCursorTillMove(bool hide);
 void requestUserAttention();
+long showAlert(std::string title, std::string text, int type);
 
 NSWindowRef createNSWindow(int x, int y, int width, int height);
 
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index ef29515403..3703dcf28d 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -395,6 +395,41 @@ void requestUserAttention()
 	[[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
 }
 
+long showAlert(std::string text, std::string title, int type)
+{
+    NSAlert *alert = [[NSAlert alloc] init];
+    
+    [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
+    [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
+    if (type == 0)
+    {
+        [alert addButtonWithTitle:@"Okay"];
+    } else if (type == 1)
+    {
+        [alert addButtonWithTitle:@"Okay"];
+        [alert addButtonWithTitle:@"Cancel"];
+    } else if (type == 2)
+    {
+        [alert addButtonWithTitle:@"Yes"];
+        [alert addButtonWithTitle:@"No"];
+    }
+    long ret = [alert runModal];
+    [alert dealloc];
+    
+    if (ret == NSAlertFirstButtonReturn)
+    {
+        ret = 0;
+    } else if (ret == NSAlertSecondButtonReturn)
+    {
+        ret = 1;
+    } else if (ret == NSAlertThirdButtonReturn)
+    {
+        ret = 2;
+    }
+    
+    return ret;
+}
+
 /*
  GLViewRef getGLView()
  {
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index d657c629b9..beb9ebe8e0 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1597,24 +1597,6 @@ LLSplashScreenMacOSX::~LLSplashScreenMacOSX()
 void LLSplashScreenMacOSX::showImpl()
 {
 	// This code _could_ be used to display a spash screen...
-#if 0
-	IBNibRef nib = NULL;
-	S32 err;
-
-	err = CreateNibReference(CFSTR("SecondLife"), &nib);
-
-	if(err == noErr)
-	{
-		CreateWindowFromNib(nib, CFSTR("Splash Screen"), &mWindow);
-
-		DisposeNibReference(nib);
-	}
-
-	if(mWindow != NULL)
-	{
-		ShowWindow(mWindow);
-	}
-#endif
 }
 
 void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
@@ -1636,12 +1618,9 @@ void LLSplashScreenMacOSX::hideImpl()
 	}
 }
 
-
-
 S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type)
 {
-	// TODO: Implement a native NSAlert function that replicates all of this.
-	return 0;
+	return showAlert(text, caption, type);
 }
 
 // Open a URL with the user's default web browser.
-- 
cgit v1.2.3


From 2f680eec93f1b06620c04af04116fe49d577cf8f Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 21:46:10 -0400
Subject: A bit of cleanup and make the return of showAlert match the OSBTN
 return types in llwindow.h.

---
 indra/llwindow/llwindowmacosx-objc.mm | 19 ++++++++++++++-----
 indra/llwindow/llwindowmacosx.cpp     |  8 +-------
 2 files changed, 15 insertions(+), 12 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 3703dcf28d..0354c2b717 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -418,13 +418,22 @@ long showAlert(std::string text, std::string title, int type)
     
     if (ret == NSAlertFirstButtonReturn)
     {
-        ret = 0;
+        if (type == 1)
+        {
+            ret = 3;
+        } else if (type == 2)
+        {
+            ret = 0;
+        }
     } else if (ret == NSAlertSecondButtonReturn)
     {
-        ret = 1;
-    } else if (ret == NSAlertThirdButtonReturn)
-    {
-        ret = 2;
+        if (type == 0 || type == 1)
+        {
+            ret = 2;
+        } else if (type == 2)
+        {
+            ret = 1;
+        }
     }
     
     return ret;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index beb9ebe8e0..a3e88ea7dc 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -164,7 +164,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	// Stash an object pointer for OSMessageBox()
 	gWindowImplementation = this;
 	// Create the GL context and set it up for windowed or fullscreen, as appropriate.
-	LL_INFOS("Window") << "Creating context..." << LL_ENDL;
 	if(createContext(x, y, width, height, 32, fullscreen, disable_vsync))
 	{
 		if(mWindow != NULL)
@@ -526,13 +525,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 	
 	if (mWindow == NULL)
 	{
-		LL_INFOS("Window") << "Creating window..." << LL_ENDL;
 		mWindow = getMainAppWindow();
 	}
 
 	if(mContext == NULL)
 	{
-		LL_INFOS("Window") << "Creating GL view..." << LL_ENDL;
 		// Our OpenGL view is already defined within SecondLife.xib.
 		// Get the view instead.
 		mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync);
@@ -565,12 +562,10 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 	GLint frames_per_swap = 0;
 	if (disable_vsync)
 	{
-		LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL;
 		frames_per_swap = 0;
 	}
 	else
 	{
-		LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL;
 		frames_per_swap = 1;
 	}
 	
@@ -593,9 +588,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 			LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
 		}
 	}
-	LL_INFOS("Window") << "Completed context creation." << LL_ENDL;
 	makeFirstResponder(mWindow, mGLView);
-	// Don't need to get the current gamma, since there's a call that restores it to the system defaults.
+    
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From dea416fd83497d22147b3c0abab1bf1240e472dd Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Thu, 11 Jul 2013 22:07:17 -0400
Subject: Rework the command+click functionality a bit to ensure we're not
 mistakenly simulating a right click where we shouldn't.

---
 indra/llwindow/llopenglview-objc.mm | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 42ad4f8723..5f34d03c35 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -243,7 +243,13 @@ attributedStringInfo getSegments(NSAttributedString *str)
 - (void) mouseDown:(NSEvent *)theEvent
 {
     // Apparently people still use this?
-    if ([theEvent modifierFlags] & NSControlKeyMask)
+    if ([theEvent modifierFlags] & NSCommandKeyMask &&
+        !([theEvent modifierFlags] & NSControlKeyMask) &&
+        !([theEvent modifierFlags] & NSShiftKeyMask) &&
+        !([theEvent modifierFlags] & NSAlternateKeyMask) &&
+        !([theEvent modifierFlags] & NSAlphaShiftKeyMask) &&
+        !([theEvent modifierFlags] & NSFunctionKeyMask) &&
+        !([theEvent modifierFlags] & NSHelpKeyMask))
     {
         callRightMouseDown(mMousePos, mModifiers);
         mSimulatedRightClick = true;
-- 
cgit v1.2.3


From 6ca0bbe3365b3d554789915ac143a87d2d39fdfa Mon Sep 17 00:00:00 2001
From: Geenz <geenz@geenzo.com>
Date: Tue, 23 Jul 2013 10:39:32 -0400
Subject: Fix for BUG-3364

---
 indra/llwindow/llwindowmacosx.cpp | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index a3e88ea7dc..56472e6b45 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -316,7 +316,7 @@ void callMouseMoved(float *pos, MASK mask)
 	outCoords.mX += deltas[0];
 	outCoords.mY += deltas[1];
 	gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
-	gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
+	//gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
 }
 
 void callScrollMoved(float delta)
@@ -849,20 +849,24 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size)
 {
 	if(mWindow)
 	{
-		setWindowSize(mWindow, size.mX, size.mY);
+        LLCoordWindow to;
+        convertCoords(size, &to);
+		setWindowSize(mWindow, to.mX, to.mY);
+        return TRUE;
 	}
 
-	return TRUE;
+	return FALSE;
 }
 
 BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
 {
 	if (mWindow)
 	{
-		LLCoordScreen screen_size;
-		convertCoords(size, &screen_size);
-		return setSizeImpl(screen_size);
+        const int titlePadding = 22;
+        setWindowSize(mWindow, size.mX, size.mY + titlePadding);
+        return TRUE;
 	}
+    
 	return FALSE;
 }
 
-- 
cgit v1.2.3


From efba897e45b5065619bbe0e1451a40b6391e503c Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 5 Aug 2013 15:38:43 -0400
Subject: correct coding standards problems

---
 indra/llwindow/llopenglview-objc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llwindow')

diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
index 71149f8561..41837b1eb4 100644
--- a/indra/llwindow/llopenglview-objc.h
+++ b/indra/llwindow/llopenglview-objc.h
@@ -107,4 +107,4 @@
 
 @end
 
-#endif
\ No newline at end of file
+#endif
-- 
cgit v1.2.3