diff options
| author | Manolo Gouy <Manolo> | 2011-01-03 16:50:34 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2011-01-03 16:50:34 +0000 |
| commit | 874bca74f55f686ded8f0b3d2df08196911f26f0 (patch) | |
| tree | f1d394945f49314ee4a8706a4b98daf8ec830ce8 /src | |
| parent | bb6392f7ec94ba682ebade1d5b30eba9ff30ceb1 (diff) | |
Mac OS X: removed all uses of Carbon (except for older OS versions) and re-organized
text input around the NSTextInput protocol.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8173 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Gl_Choice.cxx | 26 | ||||
| -rw-r--r-- | src/Fl_Gl_Window.cxx | 4 | ||||
| -rw-r--r-- | src/Fl_Preferences.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_Quartz_Printer.mm | 12 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 234 | ||||
| -rw-r--r-- | src/Fl_compose.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_get_key_mac.cxx | 11 |
7 files changed, 162 insertions, 129 deletions
diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx index fa99d2705..df6267650 100644 --- a/src/Fl_Gl_Choice.cxx +++ b/src/Fl_Gl_Choice.cxx @@ -37,8 +37,8 @@ # include <FL/fl_utf8.h> # ifdef __APPLE__ +# include <ApplicationServices/ApplicationServices.H> # include <FL/Fl_Window.H> -# include <Carbon/Carbon.h> # endif # ifdef WIN32 @@ -296,6 +296,14 @@ GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int lay } # elif defined(__APPLE_QUARTZ__) +static CGrafPtr fl_GetWindowPort(WindowRef window) +{ + typedef CGrafPtr (*wf)(WindowRef); + static wf f = NULL; + if ( ! f) f = (wf)Fl_X::get_carbon_function("GetWindowPort"); + return (*f)(window); +} + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { GLContext context, shared_ctx = 0; @@ -312,17 +320,17 @@ GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int lay #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 #if __LP64__ // 64 bit version - aglSetWindowRef(context, Fl_X::i(window)->window_ref()/*fl_mac_windowref(window)*/ ); + aglSetWindowRef(context, Fl_X::i(window)->window_ref() ); #else // 32 bit version >= 10.5 if (aglSetWindowRef != NULL) - aglSetWindowRef(context, Fl_X::i(window)->window_ref()/*fl_mac_windowref(window)*/ ); + aglSetWindowRef(context, Fl_X::i(window)->window_ref() ); else - aglSetDrawable( context, GetWindowPort( Fl_X::i(window)->window_ref()/*fl_mac_windowref(window)*/ ) ); + aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) ); #endif #else // 32 bit version < 10.5 - aglSetDrawable( context, GetWindowPort( Fl_X::i(window)->window_ref()/*fl_mac_windowref(window)*/ ) ); + aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) ); #endif return (context); } @@ -352,17 +360,17 @@ void fl_set_gl_context(Fl_Window* w, GLContext context) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 #if __LP64__ // 64 bit version - aglSetWindowRef(context, Fl_X::i(w)->window_ref()/*fl_mac_windowref(w)*/ ); + aglSetWindowRef(context, Fl_X::i(w)->window_ref() ); #else // 32 bit version >= 10.5 if (aglSetWindowRef != NULL) - aglSetWindowRef(context, Fl_X::i(w)->window_ref()/*fl_mac_windowref(w)*/ ); + aglSetWindowRef(context, Fl_X::i(w)->window_ref() ); else - aglSetDrawable( context, GetWindowPort( Fl_X::i(w)->window_ref()/*fl_mac_windowref(w)*/ ) ); + aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) ); #endif #else // 32 bit version < 10.5 - aglSetDrawable( context, GetWindowPort( Fl_X::i(w)->window_ref()/*fl_mac_windowref(w)*/ ) ); + aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) ); #endif aglSetCurrentContext(context); # else diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index 0f46b23bb..52bf72bad 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -277,12 +277,12 @@ void Fl_Gl_Window::flush() { // warning: the Quartz version should probably use Core GL (CGL) instead of AGL //: clear previous clipping in this shared port #if ! __LP64__ - GrafPtr port = GetWindowPort( Fl_X::i(this)->window_ref() ); +/*GrafPtr port = GetWindowPort( Fl_X::i(this)->window_ref() ); Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff ); GrafPtr old; GetPort( &old ); SetPort( port ); ClipRect( &rect ); - SetPort( old ); + SetPort( old );*/ #endif #endif diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx index eb393cf3f..7e70e7316 100644 --- a/src/Fl_Preferences.cxx +++ b/src/Fl_Preferences.cxx @@ -47,7 +47,7 @@ # define access _access # define mkdir _mkdir #elif defined (__APPLE__) -# include <Carbon/Carbon.h> +# include <ApplicationServices/ApplicationServices.h> # include <unistd.h> # include <dlfcn.h> #else diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm index 825826457..e531fa706 100644 --- a/src/Fl_Quartz_Printer.mm +++ b/src/Fl_Quartz_Printer.mm @@ -92,7 +92,11 @@ int Fl_Printer::start_job (int pagecount, int *frompage, int *topage) status = PMCreatePageFormat(&pageFormat); status = PMSessionDefaultPageFormat(printSession, pageFormat); if (status != noErr) return 1; - status = PMSessionPageSetupDialog(printSession, pageFormat, &accepted); + // get pointer to the PMSessionPageSetupDialog Carbon fucntion + typedef OSStatus (*dialog_f)(PMPrintSession, PMPageFormat, Boolean *); + static dialog_f f = NULL; + if (!f) f = (dialog_f)Fl_X::get_carbon_function("PMSessionPageSetupDialog"); + status = (*f)(printSession, pageFormat, &accepted); if (status != noErr || !accepted) { Fl::first_window()->show(); return 1; @@ -102,7 +106,11 @@ int Fl_Printer::start_job (int pagecount, int *frompage, int *topage) status = PMSessionDefaultPrintSettings (printSession, printSettings); if (status != noErr) return 1; PMSetPageRange(printSettings, 1, (UInt32)kPMPrintAllPages); - status = PMSessionPrintDialog(printSession, printSettings, pageFormat, &accepted); + // get pointer to the PMSessionPrintDialog Carbon fucntion + typedef OSStatus (*dialog_f2)(PMPrintSession, PMPrintSettings, PMPageFormat, Boolean *); + static dialog_f2 f2 = NULL; + if (!f2) f2 = (dialog_f2)Fl_X::get_carbon_function("PMSessionPrintDialog"); + status = (*f2)(printSession, printSettings, pageFormat, &accepted); if (!accepted) status = kPMCancel; if (status != noErr) { Fl::first_window()->show(); diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 2ad315037..20a7250f8 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -38,23 +38,6 @@ // One Compile to copy them all and in the bundle bind them, // in the Land of MacOS X where the Drop-Shadows lie." -/* - TODO: The following messages point to the last Carbon remainders. We should - really remove these as well, so we can stop linking to Carbon alltogether. - - "_GetKeys", referenced from: - Fl::get_key(int) in Fl_get_key.o (kept only for pre-10.4 runs) - - "_GetEventParameter", referenced from: - carbonTextHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) in Fl.o - - "_InstallEventHandler", referenced from: - fl_open_display() in Fl.o - - "_GetEventDispatcherTarget", referenced from: - fl_open_display() in Fl.o -*/ - #ifdef __APPLE__ #define CONSOLIDATE_MOTION 0 @@ -84,7 +67,7 @@ extern "C" { typedef long NSInteger; typedef unsigned long NSUInteger; #else -typedef int NSInteger; +typedef long NSInteger; typedef unsigned int NSUInteger; #endif #endif @@ -878,77 +861,14 @@ static void calc_e_text(CFStringRef s, char *buffer, size_t len, unsigned sym) } } +static int cocoaKeyboardHandler(NSEvent *theEvent); -// this gets called by CJK character palette input -static OSStatus carbonTextHandler( EventHandlerCallRef nextHandler, EventRef event, void *unused ) +@interface FLTextView : NSTextView +// this subclass is needed under OS X 10.3 and 10.4 but not under 10.6 where the base class is enough { - // make sure the key window is an FLTK window - NSWindow *keywindow = [NSApp keyWindow]; - if (keywindow == nil || ![keywindow isMemberOfClass:[FLWindow class]]) return eventNotHandledErr; - // under 10.5 this gets called only after character palette inputs - // but under 10.6 this gets also called by interpretKeyEvents - // during keyboard input when we don't want to run it - if ([[NSApp currentEvent] type] != NSSystemDefined) return eventNotHandledErr; - Fl_Window *window = [(FLWindow*)keywindow getFl_Window]; - fl_lock_function(); - UniChar ucs[20]; - ByteCount actual_size; - unsigned int i; - GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, - NULL, 20, &actual_size, ucs ); - char utf8buf[50], *p; - p = utf8buf; - for(i=0; i < actual_size/2; i++) { - p += fl_utf8encode(ucs[i], p); - } - int len = p - utf8buf; - utf8buf[len]=0; - - Fl::e_length = len; - Fl::e_text = utf8buf; - while (window->parent()) window = window->window(); - Fl::handle(FL_KEYBOARD, window); - fl_unlock_function(); - fl_lock_function(); - Fl::handle(FL_KEYUP, window); - fl_unlock_function(); - // for some reason, the window does not redraw until the next mouse move or button push - // sending a 'redraw()' or 'awake()' does not solve the issue! - Fl::flush(); - return noErr; -} - -static OSStatus cocoaKeyboardHandler(NSEvent *theEvent); - -@interface FLTextView : NSTextView -{ - BOOL compose_key; // YES iff entering a character composition - BOOL needKBhandler_val; } -- (BOOL)needKBhandler; -- (void)needKBhandler:(BOOL)value; -- (BOOL)compose; -- (void)compose:(BOOL)value; -- (void)insertText:(id)aString; -- (void)doCommandBySelector:(SEL)aSelector; @end @implementation FLTextView -- (BOOL)needKBhandler -{ - return needKBhandler_val; -} -- (void)needKBhandler:(BOOL)value -{ - needKBhandler_val = value; -} -- (BOOL)compose -{ - return compose_key; -} -- (void)compose:(BOOL)value -{ - compose_key = value; -} - (void)insertText:(id)aString { cocoaKeyboardHandler([NSApp currentEvent]); @@ -960,7 +880,7 @@ static OSStatus cocoaKeyboardHandler(NSEvent *theEvent); @end /* - * handle cocoa keyboard events +Handle cocoa keyboard events Events during a character composition sequence: - keydown with deadkey -> [[theEvent characters] length] is 0 - keyup -> [theEvent characters] contains the deadkey: display it temporarily @@ -968,7 +888,7 @@ Events during a character composition sequence: replace the temporary character by this one - keyup -> [theEvent characters] contains the standard character */ -static OSStatus cocoaKeyboardHandler(NSEvent *theEvent) +static int cocoaKeyboardHandler(NSEvent *theEvent) { static char buffer[32]; int sendEvent = 0, retval = 0; @@ -984,8 +904,6 @@ static OSStatus cocoaKeyboardHandler(NSEvent *theEvent) unsigned short sym = 0; keyCode = [theEvent keyCode]; NSString *s = [theEvent characters]; - FLTextView *edit = (FLTextView*)[[theEvent window] fieldEditor:YES forObject:nil]; - [edit needKBhandler:NO]; if ( (mods & NSShiftKeyMask) && (mods & NSCommandKeyMask) ) { s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit } @@ -999,7 +917,6 @@ static OSStatus cocoaKeyboardHandler(NSEvent *theEvent) sendEvent = FL_KEYBOARD; // fall through case NSKeyUp: - if([edit compose]) sendEvent = FL_KEYBOARD; // when composing, the temporary character appears at KeyUp if ( !sendEvent ) { sendEvent = FL_KEYUP; Fl::e_state &= 0xbfffffff; // clear the deadkey flag @@ -1026,13 +943,9 @@ static OSStatus cocoaKeyboardHandler(NSEvent *theEvent) } if (sendEvent) { retval = Fl::handle(sendEvent,window); - if([edit compose]) { - Fl::compose_state = 1; - [edit compose:NO]; - } } fl_unlock_function(); - return retval ? (int)noErr : (int)eventNotHandledErr; // return noErr if FLTK handled the event + return retval; } @@ -1310,8 +1223,7 @@ extern "C" { static FLTextView *view = nil; if (!view) { view = [[FLTextView alloc] initWithFrame:rect]; - [view compose:NO]; - } + } return view; } @end @@ -1422,12 +1334,6 @@ void fl_open_display() { } } createAppleMenu(); - // Install Carbon Event handler for character palette input - static EventTypeSpec textEvents[] = { - { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } - }; - EventHandlerUPP textHandler = NewEventHandlerUPP( carbonTextHandler ); - InstallEventHandler(GetEventDispatcherTarget(), textHandler, 1, textEvents, NULL, 0L); [[NSNotificationCenter defaultCenter] addObserver:mydelegate selector:@selector(anywindowwillclosenotif:) @@ -1653,7 +1559,7 @@ static void q_set_window_title(NSWindow *nsw, const char * name ) { } -@interface FLView : NSView { +@interface FLView : NSView <NSTextInput> { } - (void)drawRect:(NSRect)rect; - (BOOL)acceptsFirstResponder; @@ -1694,8 +1600,8 @@ static void q_set_window_title(NSWindow *nsw, const char * name ) { } - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { - OSStatus err = cocoaKeyboardHandler(theEvent); - return (err ? NO : YES); + int err = cocoaKeyboardHandler(theEvent); + return (err ? YES : NO); } - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent { @@ -1738,12 +1644,7 @@ static void q_set_window_title(NSWindow *nsw, const char * name ) { } - (void)keyDown:(NSEvent *)theEvent { FLTextView *edit = (FLTextView*)[[theEvent window] fieldEditor:YES forObject:nil]; - if ([[theEvent characters] length] == 0) [edit compose:YES]; - if (Fl::compose_state) [edit needKBhandler:YES]; - else [edit needKBhandler:NO]; [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; - // in some cases (e.g., some Greek letters with tonos) interpretKeyEvents does not call insertText - if ([edit needKBhandler]) cocoaKeyboardHandler(theEvent); } - (void)keyUp:(NSEvent *)theEvent { cocoaKeyboardHandler(theEvent); @@ -1843,6 +1744,99 @@ static void q_set_window_title(NSWindow *nsw, const char * name ) { { return NSDragOperationGeneric; } + +// These functions implement text input. +// Only two-stroke character composition works at this point. +// Needs much elaboration to fully support CJK text input, +// but this is the way to go. +- (void)doCommandBySelector:(SEL)aSelector { +} + +- (void)insertText:(id)aString { + NSEvent *event = [NSApp currentEvent]; + NSEventType type = [event type]; + NSString *str = @""; + NSString *received; + if ([aString isKindOfClass:[NSAttributedString class]]) { + received = [(NSAttributedString*)aString string]; + } else { + received = (NSString*)aString; + } +//NSLog(@"insertText: received=%@ event type=%d",received, type); + if (type == NSKeyDown ) { + str = [event characters]; + } + if ([received isEqualToString:@"\b"] || [str isEqualToString:received]) { + if (type == NSKeyDown ) cocoaKeyboardHandler(event); + } else { + fl_lock_function(); + Fl_Window *window = [(FLWindow*)[NSApp keyWindow] getFl_Window]; + Fl::e_text = (char*)[received UTF8String]; + Fl::e_length = strlen(Fl::e_text); + Fl::handle(FL_KEYBOARD, window); + Fl::handle(FL_KEYUP, window); + fl_unlock_function(); + // for some reason, the window does not redraw until the next mouse move or button push + // sending a 'redraw()' or 'awake()' does not solve the issue! + Fl::flush(); + } +} + +- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection { + // NSLog(@"setMarkedText: %@ %d %d Fl::compose_state=%d", + // aString,newSelection.location,newSelection.length,newSelection.location); + [self insertText:aString]; + Fl::compose_state = newSelection.location; +} + +- (void)unmarkText { + Fl::compose_state = 0; + //NSLog(@"unmarkText"); +} + +- (NSRange)selectedRange { + return NSMakeRange(NSNotFound, 0); +} + +- (NSRange)markedRange { + //NSLog(@"markedRange ?"); + return NSMakeRange(NSNotFound, Fl::compose_state); +} + +- (BOOL)hasMarkedText { + //NSLog(@"hasMarkedText %s", Fl::compose_state > 0?"YES":"NO"); + return (Fl::compose_state > 0); +} + +- (NSAttributedString *)attributedSubstringFromRange:(NSRange)aRange { + //NSLog(@"attributedSubstringFromRange: %d %d",aRange.location,aRange.length); + return nil; +} + +- (NSArray *)validAttributesForMarkedText { + return nil; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange { + NSRect glyphRect, frame; + + frame = [self frame]; + glyphRect.origin.x = frame.size.width; + glyphRect.origin.y = 0; + glyphRect.size.width = glyphRect.size.height = 0; + // Convert the rect to screen coordinates + glyphRect.origin = [[self window] convertBaseToScreen:glyphRect.origin]; + return glyphRect; +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { + return 0; +} + +- (NSInteger)conversationIdentifier { + return (NSInteger)self; +} + @end @@ -3271,6 +3265,26 @@ Window fl_xid(const Fl_Window* w) return Fl_X::i(w)->xid; } +#include <dlfcn.h> + +/* Returns the address of a Carbon function after dynamically loading the Carbon library if needed. + Supports old Mac OS X versions that may use a couple of Carbon calls: + GetKeys used by OS X 10.3 or before (in Fl::get_key()) + PMSessionPageSetupDialog and PMSessionPrintDialog used by 10.4 or before (in Fl_Printer::start_job()) + GetWindowPort used by 10.4 or before (in Fl_Gl_Choice.cxx) + */ +void *Fl_X::get_carbon_function(const char *function_name) { + static void *carbon = NULL; + void *f = NULL; + if (!carbon) { + carbon = dlopen("/System/Library/Frameworks/Carbon.framework/Carbon", RTLD_LAZY); + } + if (carbon) { + f = dlsym(carbon, function_name); + } + return f; +} + #endif // __APPLE__ // diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx index c773c6bef..7069c1f27 100644 --- a/src/Fl_compose.cxx +++ b/src/Fl_compose.cxx @@ -65,7 +65,7 @@ int Fl::compose(int& del) { if ((e_state & (FL_ALT | FL_META)) && !(ascii & 128)) return 0; #endif if(Fl::compose_state) { - del = 1; + del = Fl::compose_state; Fl::compose_state = 0; } else { #ifndef __APPLE__ diff --git a/src/Fl_get_key_mac.cxx b/src/Fl_get_key_mac.cxx index 7f3c7a227..126b17806 100644 --- a/src/Fl_get_key_mac.cxx +++ b/src/Fl_get_key_mac.cxx @@ -83,8 +83,6 @@ int Fl::event_key(int k) { return get_key(k); } -#include <stdio.h> - //: returns true, if that key is pressed right now int Fl::get_key(int k) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 @@ -94,8 +92,13 @@ int Fl::get_key(int k) { else #endif { - KeyMap foo; - GetKeys(foo); + typedef UInt32 fl_KeyMap[4]; + fl_KeyMap foo; + // use the GetKeys Carbon function + typedef void (*keymap_f)(fl_KeyMap); + static keymap_f f = NULL; + if (!f) f = ( keymap_f )Fl_X::get_carbon_function("GetKeys"); + (*f)(foo); #ifdef MAC_TEST_FOR_KEYCODES static int cnt = 0; if (cnt++>1024) { |
