From 354b95931863234ca8eaf687a6c371e257b54bc5 Mon Sep 17 00:00:00 2001 From: Adam Fedor Date: Mon, 1 Apr 2002 17:34:08 +0000 Subject: [PATCH] Better release/retain of server and context git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@13286 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 14 ++++ Headers/gnustep/gui/NSGraphicsContext.h | 14 +++- Source/GSDisplayServer.m | 7 +- Source/NSApplication.m | 8 ++- Source/NSGraphicsContext.m | 87 +++++++++++++++++++------ Source/NSWindow.m | 3 +- Version | 2 +- 7 files changed, 105 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index c24b85567..1bb9803d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2002-04-01 Adam Fedor + + * Source/NSApplication.m (-init): Retain the server + and default context. + (-dealloc): Release server and context. + * Source/NSGraphicsContext.m (+restoreGraphicsState): Implement. + (+saveGraphicsState): Likewise. + ( destroyContext): Remove. + (-restoreGraphicsState): Implement. + (-saveGraphicsState): Likewise. + Add some documentation. + * Source/NSWindow.m ([NSWindow -dealloc]): Check for context + before undefining gstate. + 2002-04-01 Gregory Casamento * Source/NSOutlineView.m diff --git a/Headers/gnustep/gui/NSGraphicsContext.h b/Headers/gnustep/gui/NSGraphicsContext.h index e13fefc7e..d9cd8445d 100644 --- a/Headers/gnustep/gui/NSGraphicsContext.h +++ b/Headers/gnustep/gui/NSGraphicsContext.h @@ -187,7 +187,6 @@ APPKIT_DECLARE NSGraphicsContext *GSCurrentContext(); + (void) setDefaultContextClass: (Class)defaultContextClass; - (id) initWithContextInfo: (NSDictionary*)info; -- (void) destroyContext; /* * Focus management methods - lock and unlock should only be used by NSView @@ -392,6 +391,19 @@ APPKIT_EXPORT NSString *NSGraphicsContextPDFFormat; APPKIT_EXPORT NSString *NSGraphicsContextPSFormat; APPKIT_EXPORT NSString *NSGraphicsContextRepresentationFormatAttributeName; +/* Colorspace constants */ +APPKIT_DECLARE NSString *GSColorSpaceName; +APPKIT_DECLARE NSString *GSColorSpaceWhitePoint; +APPKIT_DECLARE NSString *GSColorSpaceBlackPoint; +APPKIT_DECLARE NSString *GSColorSpaceGamma; +APPKIT_DECLARE NSString *GSColorSpaceMatrix; +APPKIT_DECLARE NSString *GSColorSpaceRange; +APPKIT_DECLARE NSString *GSColorSpaceComponents; +APPKIT_DECLARE NSString *GSColorSpaceProfile; +APPKIT_DECLARE NSString *GSAlternateColorSpace; +APPKIT_DECLARE NSString *GSBaseColorSpace; +APPKIT_DECLARE NSString *GSColorSpaceColorTable; + #endif /* _NSGraphicsContext_h_INCLUDE */ #endif /* STRICT_OPENSTEP */ diff --git a/Source/GSDisplayServer.m b/Source/GSDisplayServer.m index 22ae13cd5..dae7af6e3 100644 --- a/Source/GSDisplayServer.m +++ b/Source/GSDisplayServer.m @@ -46,9 +46,6 @@ static Class defaultServerClass = NULL; /* Maps windows to a server */ static NSMapTable *windowmaps = NULL; -/* Current server */ -static GSDisplayServer *currentServer = nil; - /* Lock for use when creating contexts */ static NSRecursiveLock *serverLock = nil; @@ -209,7 +206,7 @@ GSCurrentServer(void) /** Causes the server to disconnect from the display. If the receiver - is the current server, it removes it self and sets the current + is the current server, it removes itself and sets the current server to nil. Sending any more messages to the receiver after this is likely to cause severe problems and probably crash the application. @@ -222,8 +219,6 @@ GSCurrentServer(void) - (void) dealloc { - if (self == GSCurrentServer()) - currentServer = nil; DESTROY(server_info); DESTROY(event_queue); NSFreeMapTable(drag_types); diff --git a/Source/NSApplication.m b/Source/NSApplication.m index 85b19ba7d..d04ac41ed 100644 --- a/Source/NSApplication.m +++ b/Source/NSApplication.m @@ -522,10 +522,12 @@ static NSCell* tileCell = nil; /* Connect to our window server */ srv = [GSDisplayServer serverWithAttributes: nil]; + RETAIN(srv); [GSDisplayServer setCurrentServer: srv]; /* Create a default context. */ _default_context = [NSGraphicsContext graphicsContextWithAttributes: nil]; + RETAIN(_default_context); [NSGraphicsContext setCurrentContext: _default_context]; /* Initialize font manager */ @@ -754,11 +756,13 @@ static NSCell* tileCell = nil; TEST_RELEASE(_app_icon_window); TEST_RELEASE(_infoPanel); - /* Destroy the default context, this will free it */ - [_default_context destroyContext]; + /* Destroy the default context */ + [NSGraphicsContext setCurrentContext: nil]; + DESTROY(_default_context); /* Close the server */ [srv closeServer]; + DESTROY(srv); [super dealloc]; } diff --git a/Source/NSGraphicsContext.m b/Source/NSGraphicsContext.m index b3f0b1568..3c68a7f71 100644 --- a/Source/NSGraphicsContext.m +++ b/Source/NSGraphicsContext.m @@ -52,9 +52,6 @@ static NSZone *_globalGSZone = NULL; /* The current concrete class */ static Class defaultNSGraphicsContextClass = NULL; -/* List of contexts */ -static NSMutableArray *contextList; - /* Class variable for holding pointers to method functions */ static NSMutableDictionary *classMethodTable; @@ -64,6 +61,7 @@ static NSRecursiveLock *contextLock = nil; #ifndef GNUSTEP_BASE_LIBRARY static NSString *NSGraphicsContextThreadKey = @"NSGraphicsContextThreadKey"; #endif +static NSString *NSGraphicsContextStackKey = @"NSGraphicsContextStackKey"; /* * Function for rapid access to current graphics context. @@ -116,7 +114,6 @@ NSGraphicsContext *GSCurrentContext() contextLock = [NSRecursiveLock new]; defaultNSGraphicsContextClass = [NSGraphicsContext class]; _globalGSZone = NSDefaultMallocZone(); - contextList = [[NSMutableArray allocWithZone: _globalGSZone] init]; classMethodTable = [[NSMutableDictionary allocWithZone: _globalGSZone] init]; } @@ -199,17 +196,40 @@ NSGraphicsContext *GSCurrentContext() + (void) restoreGraphicsState { -// FIXME + NSGraphicsContext *ctxt; + NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; + NSMutableArray *stack = [dict objectForKey: NSGraphicsContextStackKey]; + if (stack == nil || [stack count] == 0) + { + [NSException raise: NSGenericException + format: @"restoreGraphicsState without previous save"]; + } + ctxt = [stack lastObject]; + [NSGraphicsContext setCurrentContext: ctxt]; + [stack removeLastObject]; + [ctxt restoreGraphicsState]; } + (void) saveGraphicsState { -// FIXME + NSGraphicsContext *ctxt; + NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; + NSMutableArray *stack = [dict objectForKey: NSGraphicsContextStackKey]; + if (stack == nil) + { + stack = [[NSMutableArray allocWithZone: _globalGSZone] init]; + [dict setObject: stack forKey: NSGraphicsContextStackKey]; + } + ctxt = GSCurrentContext(); + [ctxt saveGraphicsState]; + [stack addObject: ctxt]; } + (void) setGraphicsState: (int)graphicsState { -// FIXME + /* FIXME: Need to keep a table of which context goes with a graphicState, + or perhaps we could rely on the backend? */ + [self notImplemented: _cmd]; } - (void) dealloc @@ -220,17 +240,6 @@ NSGraphicsContext *GSCurrentContext() [super dealloc]; } -/* Just remove ourselves from the context list so we will be dealloced on - the next autorelease pool end */ -- (void) destroyContext -{ - if (GSCurrentContext() == self) - [NSGraphicsContext setCurrentContext: nil]; - [contextLock lock]; - [contextList removeObject: self]; - [contextLock unlock]; -} - - (id) init { return [self initWithContextInfo: NULL]; @@ -257,7 +266,6 @@ NSGraphicsContext *GSCurrentContext() [classMethodTable setObject: [NSValue valueWithPointer: methods] forKey: [self class]]; } - [contextList addObject: self]; [contextLock unlock]; return self; @@ -270,6 +278,7 @@ NSGraphicsContext *GSCurrentContext() - (void)flushGraphics { + [self subclassResponsibility: _cmd]; } - (void *)graphicsPort @@ -284,10 +293,12 @@ NSGraphicsContext *GSCurrentContext() - (void) restoreGraphicsState { + [self DPSgrestore]; } - (void) saveGraphicsState { + [self DPSgsave]; } - (void *) focusStack @@ -658,71 +669,109 @@ NSGraphicsContext *GSCurrentContext() /* ----------------------------------------------------------------------- */ /* Color operations */ /* ----------------------------------------------------------------------- */ +/** Returns the current alpha component */ - (void) DPScurrentalpha: (float *)a { [self subclassResponsibility: _cmd]; } +/** Returns the current color according to the CMYK color model */ - (void) DPScurrentcmykcolor: (float*)c : (float*)m : (float*)y : (float*)k { [self subclassResponsibility: _cmd]; } +/** Returns the gray-level equivalent in the current color space. The + value may depend on the current color space and may be 0 if the + current color space has no notion of a gray value */ - (void) DPScurrentgray: (float*)gray { [self subclassResponsibility: _cmd]; } +/** Returns the current color according to the HSB color model. */ - (void) DPScurrenthsbcolor: (float*)h : (float*)s : (float*)b { [self subclassResponsibility: _cmd]; } +/** Returns the current color according to the RGB color model */ - (void) DPScurrentrgbcolor: (float*)r : (float*)g : (float*)b { [self subclassResponsibility: _cmd]; } +/** Sets the alpha drawing component. For this and other color setting + commands that have no differentiation between fill and stroke colors, + both the fill and stroke alpha are set. */ - (void) DPSsetalpha: (float)a { [self subclassResponsibility: _cmd]; } +/** Sets the current colorspace to Device CMYK and the current color + based on the indicated values. For this and other color setting + commands that have no differentiation between fill and stroke colors, + both the fill and stroke colors are set. */ - (void) DPSsetcmykcolor: (float)c : (float)m : (float)y : (float)k { [self subclassResponsibility: _cmd]; } +/** Sets the current colorspace to Device Gray and the current gray value */ - (void) DPSsetgray: (float)gray { [self subclassResponsibility: _cmd]; } +/** Sets the current colorspace to Device RGB and the current color based on + the indicated values */ - (void) DPSsethsbcolor: (float)h : (float)s : (float)b { [self subclassResponsibility: _cmd]; } +/** Sets the current colorspace to Device RGB and the current color based on + the indicated values */ - (void) DPSsetrgbcolor: (float)r : (float)g : (float)b { [self subclassResponsibility: _cmd]; } +/** +

Sets the colorspace for fill operations based on values in the supplied + dictionary dict.

+

For device colorspaces (GSDeviceGray, GSDeviceRGB, + GSDeviceCMYK), only the name of the colorspace needs to be set + using the GSColorSpaceName key.

+

Other colorspaces will be documented later

+*/ - (void) GSSetFillColorspace: (NSDictionary *)dict { [self subclassResponsibility: _cmd]; } +/** Sets the colorspace for stroke operations based on the values in + the supplied dictionary. See -GSSetFillColorspace: for a + description of the values that need to be supplied */ - (void) GSSetStrokeColorspace: (NSDictionary *)dict { [self subclassResponsibility: _cmd]; } +/** Sets the current color for fill operations. The values array + should have n components, where n corresponds to the number of + color components required to specify the color in the current + colorspace. */ - (void) GSSetFillColor: (float *)values { [self subclassResponsibility: _cmd]; } +/** Sets the current color for fill operations. The values array + should have n components, where n corresponds to the number of + color components required to specify the color in the current + colorspace. */ - (void) GSSetStrokeColor: (float *)values { [self subclassResponsibility: _cmd]; diff --git a/Source/NSWindow.m b/Source/NSWindow.m index 9d9b897e5..2bcc9ae97 100644 --- a/Source/NSWindow.m +++ b/Source/NSWindow.m @@ -626,7 +626,8 @@ static NSNotificationCenter *nc = nil; */ [GSServerForWindow(self) removeDragTypes: nil fromWindow: self]; - if (_gstate) + /* Check for context also as it might have disappeared before us */ + if (context && _gstate) { GSUndefineGState(context, _gstate); } diff --git a/Version b/Version index ebb1dbe80..9db020e0b 100644 --- a/Version +++ b/Version @@ -11,7 +11,7 @@ GNUSTEP_GUI_LIBTIFF=3.4 # The version number of this release. GNUSTEP_GUI_MAJOR_VERSION=0 GNUSTEP_GUI_MINOR_VERSION=7 -GNUSTEP_GUI_SUBMINOR_VERSION=6 +GNUSTEP_GUI_SUBMINOR_VERSION=7 GNUSTEP_GUI_VERSION=${GNUSTEP_GUI_MAJOR_VERSION}.${GNUSTEP_GUI_MINOR_VERSION}.${GNUSTEP_GUI_SUBMINOR_VERSION} VERSION=${GNUSTEP_GUI_VERSION}