From db56ad4a9d1111484388533b9c8b59488d6c9112 Mon Sep 17 00:00:00 2001 From: richard Date: Fri, 5 Mar 1999 15:47:22 +0000 Subject: [PATCH] Moved focus handling to graphics context git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@3859 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 12 +++- Headers/gnustep/gui/NSGraphicsContext.h | 22 +++++-- Source/NSGraphicsContext.m | 81 ++++++++++++++++++------- Source/NSView.m | 66 +------------------- 4 files changed, 90 insertions(+), 91 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97d7767a3..c4249e284 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,14 @@ -hu Mar 4 12:46:00 1999 Richard Frith-Macdonald +Fri Mar 5 14:46:00 1999 Richard Frith-Macdonald + + * Headers/AppKit/NSGraphicsContext.h: Added three new methods to + support focusing - ([-focusView]), ([-pushFocusView:]) and + ([-popFocusView:]) + * Source/NSGraphicsContext.m: Added new focussing methods, tidied + a little, and made graphocs contexts thread-safe. + * Source/NSView.m: Removed old code to handle per-thread stack of + focussed views - use new code in NSGraphicsContext instead. + +Thu Mar 4 12:46:00 1999 Richard Frith-Macdonald * Source/NSClipView.m: Fixed to cope with nil document view. diff --git a/Headers/gnustep/gui/NSGraphicsContext.h b/Headers/gnustep/gui/NSGraphicsContext.h index 3d279f0df..8a7092de9 100644 --- a/Headers/gnustep/gui/NSGraphicsContext.h +++ b/Headers/gnustep/gui/NSGraphicsContext.h @@ -31,8 +31,10 @@ #include +@class NSMutableArray; @class NSMutableData; @class NSDictionary; +@class NSView; // // Backing Store Types @@ -81,11 +83,16 @@ typedef enum _NSWindowOrderingMode @interface NSGraphicsContext : NSObject { - NSDictionary *context_info; - NSMutableData *context_data; - + /* Make the one public instance variable first in the object so that, if we + * add or remove others, we don't necessarily need to recompile everything. + */ @public - const gsMethodTable *methods; + const gsMethodTable *methods; + +@protected + NSDictionary *context_info; + NSMutableData *context_data; + NSMutableArray *focus_stack; } + (NSGraphicsContext*) currentContext; @@ -105,6 +112,13 @@ typedef enum _NSWindowOrderingMode - (id) initWithContextInfo: (NSDictionary *)info; - (void) destroyContext; - (NSMutableData *) mutableData; +/* + * Focus management methods - lock and unlock should only be used by NSView + * in it's implementation of lockFocus and unlockFocus. + */ +- (NSView*) focusView; +- (void) lockFocusView: (NSView*)aView; +- (void) unlockFocusView: (NSView*)aView; @end #endif diff --git a/Source/NSGraphicsContext.m b/Source/NSGraphicsContext.m index d6b9239ce..6970dbeb4 100644 --- a/Source/NSGraphicsContext.m +++ b/Source/NSGraphicsContext.m @@ -5,6 +5,7 @@ Written by: Adam Fedor Date: Nov 1998 Updated by: Richard Frith-Macdonald + Date: Feb 1999 This file is part of the GNUStep GUI Library. @@ -30,6 +31,8 @@ #include #include #include +#include +#include #include #include "AppKit/NSGraphicsContext.h" @@ -37,9 +40,6 @@ are also allocated from this zone) */ NSZone *_globalGSZone = NULL; -/* The current context */ -NSGraphicsContext *_currentNSGraphicsContext = nil; - /* The current concrete class */ static Class defaultNSGraphicsContextClass = NULL; @@ -49,6 +49,11 @@ static NSMutableArray *contextList; /* Class variable for holding pointers to method functions */ static NSMutableDictionary *classMethodTable; +/* Lock for use when creating contexts */ +static NSRecursiveLock *contextLock = nil; + +static NSString *NSGraphicsContextThredKey = @"NSGraphicsContextThredKey"; + @interface NSGraphicsContext (Private) + (gsMethodTable *) _initializeMethodTable; @end @@ -57,22 +62,19 @@ static NSMutableDictionary *classMethodTable; + (void) initialize { - if (defaultNSGraphicsContextClass == nil) + if (contextLock == nil) { - defaultNSGraphicsContextClass = [NSGraphicsContext class]; - } - if (_globalGSZone == 0) - { - _globalGSZone = NSDefaultMallocZone(); - } - if (contextList == nil) - { - contextList = [[NSMutableArray allocWithZone: _globalGSZone] init]; - } - if (classMethodTable == 0) - { - classMethodTable = - [[NSMutableDictionary allocWithZone: _globalGSZone] init]; + [gnustep_global_lock lock]; + if (contextLock == nil) + { + contextLock = [NSRecursiveLock new]; + defaultNSGraphicsContextClass = [NSGraphicsContext class]; + _globalGSZone = NSDefaultMallocZone(); + contextList = [[NSMutableArray allocWithZone: _globalGSZone] init]; + classMethodTable = + [[NSMutableDictionary allocWithZone: _globalGSZone] init]; + } + [gnustep_global_lock unlock]; } } @@ -95,16 +97,21 @@ static NSMutableDictionary *classMethodTable; + (void) setCurrentContext: (NSGraphicsContext *)context { - _currentNSGraphicsContext = context; + NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; + + [dict setObject: context forKey: NSGraphicsContextThredKey]; } + (NSGraphicsContext *) currentContext { - return _currentNSGraphicsContext; + NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; + + return (NSGraphicsContext*) [dict objectForKey: NSGraphicsContextThredKey]; } - (void) dealloc { + DESTROY(focus_stack); DESTROY(context_data); DESTROY(context_info); [super dealloc]; @@ -114,7 +121,9 @@ static NSMutableDictionary *classMethodTable; the next autorelease pool end */ - (void) destroyContext; { + [contextLock lock]; [contextList removeObject: self]; + [contextLock unlock]; } - (id) init @@ -126,15 +135,25 @@ static NSMutableDictionary *classMethodTable; - (id) initWithContextInfo: (NSDictionary *)info { [super init]; - [contextList addObject: self]; + context_info = [info retain]; + focus_stack = [[NSMutableArray allocWithZone: [self zone]] + initWithCapacity: 1]; + + /* + * The classMethodTable dictionary and the list of all contexts must both + * be protected from other threads. + */ + [contextLock lock]; if (!(methods = [[classMethodTable objectForKey: [self class]] pointerValue])) { methods = [[self class] _initializeMethodTable]; [classMethodTable setObject: [NSValue valueWithPointer: methods] forKey: [self class]]; } - + [contextList addObject: self]; + [contextLock unlock]; + return self; } @@ -164,6 +183,24 @@ static NSMutableDictionary *classMethodTable; { } +- (NSView*) focusView +{ + return [focus_stack lastObject]; +} + +- (void) lockFocusView: (NSView*)aView +{ + [focus_stack addObject: aView]; +} + +- (void) unlockFocusView: (NSView*)aView +{ + NSView *v = [focus_stack lastObject]; + + NSAssert(v == aView, NSInvalidArgumentException); + [focus_stack removeLastObject]; +} + @end @implementation NSGraphicsContext (Private) diff --git a/Source/NSView.m b/Source/NSView.m index 61f36de5a..be1b4309c 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -89,74 +89,12 @@ static SEL invalidateSel = @selector(_invalidateCoordinates); } /* - * return the view at the top of thread's focus stack + * return the view at the top of graphics contexts stack * or nil if none is focused */ + (NSView*) focusView { - NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; - NSMutableArray *stack = [dict objectForKey: viewThreadKey]; - NSView *current_view = nil; - - if (stack) - { - unsigned count = [stack count]; - - if (count > 0) - current_view = [stack objectAtIndex: --count]; - } - - return current_view; -} - - -+ (void) pushFocusView: (NSView*)focusView -{ - if (focusView) - { - NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; - NSMutableArray *stack = [dict objectForKey: viewThreadKey]; - - if (stack == nil) - { - stack = [[NSMutableArray alloc] initWithCapacity: 4]; - [dict setObject: stack forKey: viewThreadKey]; - [stack release]; - } - [stack addObject: focusView]; - } - else - { - [NSException raise: NSInternalInconsistencyException - format: @"Attempt to push a 'nil' focus view on to stack."]; - } -} - - -/* - * Remove the top focusView for the current thread from the stack - * and return the new focusView (or nil if the stack is now empty). - */ -+ (NSView*) popFocusView -{ - NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; - NSMutableArray *stack = [dict objectForKey: viewThreadKey]; - NSView *v = nil; - - if (stack) - { - unsigned count = [stack count]; - - if (count > 0) - { - [stack removeObjectAtIndex: --count]; - } - if (count > 0) - { - v = [stack objectAtIndex: --count]; - } - } - return v; + return [[NSGraphicsContext currentContext] focusView]; } //