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
This commit is contained in:
richard 1999-03-05 15:47:22 +00:00
parent 7efd28bd8b
commit db56ad4a9d
4 changed files with 90 additions and 91 deletions

View file

@ -1,4 +1,14 @@
hu Mar 4 12:46:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Fri Mar 5 14:46:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* 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 <richard@brainstorm.co.uk>
* Source/NSClipView.m: Fixed to cope with nil document view. * Source/NSClipView.m: Fixed to cope with nil document view.

View file

@ -31,8 +31,10 @@
#include <AppKit/GSMethodTable.h> #include <AppKit/GSMethodTable.h>
@class NSMutableArray;
@class NSMutableData; @class NSMutableData;
@class NSDictionary; @class NSDictionary;
@class NSView;
// //
// Backing Store Types // Backing Store Types
@ -81,11 +83,16 @@ typedef enum _NSWindowOrderingMode
@interface NSGraphicsContext : NSObject @interface NSGraphicsContext : NSObject
{ {
NSDictionary *context_info; /* Make the one public instance variable first in the object so that, if we
NSMutableData *context_data; * add or remove others, we don't necessarily need to recompile everything.
*/
@public @public
const gsMethodTable *methods; const gsMethodTable *methods;
@protected
NSDictionary *context_info;
NSMutableData *context_data;
NSMutableArray *focus_stack;
} }
+ (NSGraphicsContext*) currentContext; + (NSGraphicsContext*) currentContext;
@ -105,6 +112,13 @@ typedef enum _NSWindowOrderingMode
- (id) initWithContextInfo: (NSDictionary *)info; - (id) initWithContextInfo: (NSDictionary *)info;
- (void) destroyContext; - (void) destroyContext;
- (NSMutableData *) mutableData; - (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 @end
#endif #endif

View file

@ -5,6 +5,7 @@
Written by: Adam Fedor <fedor@gnu.org> Written by: Adam Fedor <fedor@gnu.org>
Date: Nov 1998 Date: Nov 1998
Updated by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Updated by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: Feb 1999
This file is part of the GNUStep GUI Library. This file is part of the GNUStep GUI Library.
@ -30,6 +31,8 @@
#include <Foundation/NSDictionary.h> #include <Foundation/NSDictionary.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <Foundation/NSData.h> #include <Foundation/NSData.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSThread.h>
#include <Foundation/NSZone.h> #include <Foundation/NSZone.h>
#include "AppKit/NSGraphicsContext.h" #include "AppKit/NSGraphicsContext.h"
@ -37,9 +40,6 @@
are also allocated from this zone) */ are also allocated from this zone) */
NSZone *_globalGSZone = NULL; NSZone *_globalGSZone = NULL;
/* The current context */
NSGraphicsContext *_currentNSGraphicsContext = nil;
/* The current concrete class */ /* The current concrete class */
static Class defaultNSGraphicsContextClass = NULL; static Class defaultNSGraphicsContextClass = NULL;
@ -49,6 +49,11 @@ static NSMutableArray *contextList;
/* Class variable for holding pointers to method functions */ /* Class variable for holding pointers to method functions */
static NSMutableDictionary *classMethodTable; static NSMutableDictionary *classMethodTable;
/* Lock for use when creating contexts */
static NSRecursiveLock *contextLock = nil;
static NSString *NSGraphicsContextThredKey = @"NSGraphicsContextThredKey";
@interface NSGraphicsContext (Private) @interface NSGraphicsContext (Private)
+ (gsMethodTable *) _initializeMethodTable; + (gsMethodTable *) _initializeMethodTable;
@end @end
@ -57,22 +62,19 @@ static NSMutableDictionary *classMethodTable;
+ (void) initialize + (void) initialize
{ {
if (defaultNSGraphicsContextClass == nil) if (contextLock == nil)
{ {
defaultNSGraphicsContextClass = [NSGraphicsContext class]; [gnustep_global_lock lock];
} if (contextLock == nil)
if (_globalGSZone == 0) {
{ contextLock = [NSRecursiveLock new];
_globalGSZone = NSDefaultMallocZone(); defaultNSGraphicsContextClass = [NSGraphicsContext class];
} _globalGSZone = NSDefaultMallocZone();
if (contextList == nil) contextList = [[NSMutableArray allocWithZone: _globalGSZone] init];
{ classMethodTable =
contextList = [[NSMutableArray allocWithZone: _globalGSZone] init]; [[NSMutableDictionary allocWithZone: _globalGSZone] init];
} }
if (classMethodTable == 0) [gnustep_global_lock unlock];
{
classMethodTable =
[[NSMutableDictionary allocWithZone: _globalGSZone] init];
} }
} }
@ -95,16 +97,21 @@ static NSMutableDictionary *classMethodTable;
+ (void) setCurrentContext: (NSGraphicsContext *)context + (void) setCurrentContext: (NSGraphicsContext *)context
{ {
_currentNSGraphicsContext = context; NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
[dict setObject: context forKey: NSGraphicsContextThredKey];
} }
+ (NSGraphicsContext *) currentContext + (NSGraphicsContext *) currentContext
{ {
return _currentNSGraphicsContext; NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
return (NSGraphicsContext*) [dict objectForKey: NSGraphicsContextThredKey];
} }
- (void) dealloc - (void) dealloc
{ {
DESTROY(focus_stack);
DESTROY(context_data); DESTROY(context_data);
DESTROY(context_info); DESTROY(context_info);
[super dealloc]; [super dealloc];
@ -114,7 +121,9 @@ static NSMutableDictionary *classMethodTable;
the next autorelease pool end */ the next autorelease pool end */
- (void) destroyContext; - (void) destroyContext;
{ {
[contextLock lock];
[contextList removeObject: self]; [contextList removeObject: self];
[contextLock unlock];
} }
- (id) init - (id) init
@ -126,15 +135,25 @@ static NSMutableDictionary *classMethodTable;
- (id) initWithContextInfo: (NSDictionary *)info - (id) initWithContextInfo: (NSDictionary *)info
{ {
[super init]; [super init];
[contextList addObject: self];
context_info = [info retain]; 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])) if (!(methods = [[classMethodTable objectForKey: [self class]] pointerValue]))
{ {
methods = [[self class] _initializeMethodTable]; methods = [[self class] _initializeMethodTable];
[classMethodTable setObject: [NSValue valueWithPointer: methods] [classMethodTable setObject: [NSValue valueWithPointer: methods]
forKey: [self class]]; forKey: [self class]];
} }
[contextList addObject: self];
[contextLock unlock];
return self; 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 @end
@implementation NSGraphicsContext (Private) @implementation NSGraphicsContext (Private)

View file

@ -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 * or nil if none is focused
*/ */
+ (NSView*) focusView + (NSView*) focusView
{ {
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; return [[NSGraphicsContext currentContext] focusView];
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;
} }
// //