From 77c74a324e5c40b07ce1ee41b3f301d0d94f4b9d Mon Sep 17 00:00:00 2001 From: Adam Fedor Date: Wed, 27 Sep 2000 22:18:34 +0000 Subject: [PATCH] Implementation of deferred windows git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@7623 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 13 +++++++ Source/NSClipView.m | 2 +- Source/NSMenu.m | 2 +- Source/NSView.m | 10 +++-- Source/NSWindow.m | 91 +++++++++++++++++++++++++++++++++------------ 5 files changed, 90 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea04f2eae..bd19910ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2000-09-27 Adam Fedor + * Implementation of deferred windows (with the help of + mirko.viviani@rccr.cremona.it) + * Source/NSClipView.m (-setBoundsOrigin:): Make sure window + is not deferred before attempting to draw. + * Source/NSMenu.m (-init): Defer window. + * Source/NSView.m (-lockFocusInRect:): Don't lock if window is + deferred. + (-unlockFocus): Likewise. + * Source/NSWindow.m (_initBackendWindow:): New method. + (-initWithContentRect:styleMask:backing:defer:screen:): Use it + if not deferring. + (-orderWindow:relativeTo:): Create window if deferred. + * Source/tiff.m (NSTiffRead): For PHOTOMETRIC_PALETTE, don't free colormap tables, they are owned by libtiff. diff --git a/Source/NSClipView.m b/Source/NSClipView.m index 1a31ea5a5..37f139ec7 100644 --- a/Source/NSClipView.m +++ b/Source/NSClipView.m @@ -116,7 +116,7 @@ if (_documentView == nil) return; - if (_copiesOnScroll && _window) + if (_copiesOnScroll && _window && [_window gState]) { // copy the portion of the view that is common before // and after scrolling. diff --git a/Source/NSMenu.m b/Source/NSMenu.m index aea7fa0da..ccce5c85a 100644 --- a/Source/NSMenu.m +++ b/Source/NSMenu.m @@ -1295,7 +1295,7 @@ static NSString *NSMenuLocationsKey = @"NSMenuLocations"; self = [self initWithContentRect: NSZeroRect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered - defer: NO]; + defer: YES]; return self; } diff --git a/Source/NSView.m b/Source/NSView.m index d1b72654c..56b46d71e 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -1259,8 +1259,12 @@ GSSetDragTypes(NSView* obj, NSArray *types) NSGraphicsContext *ctxt = GSCurrentContext(); struct NSWindow_struct *window_t; NSRect wrect; + int window_gstate; NSAssert(_window != nil, NSInternalInconsistencyException); + /* Check for deferred window */ + if ((window_gstate = [_window gState]) == 0) + return; [ctxt lockFocusView: self inRect: rect]; wrect = [self convertRect: rect toView: nil]; @@ -1280,12 +1284,9 @@ GSSetDragTypes(NSView* obj, NSArray *types) } else { - int window_gstate; NSAffineTransform *matrix; float x, y, w, h; - window_gstate = [_window gState]; - NSAssert(window_gstate, NSInternalInconsistencyException); DPSsetgstate(ctxt, window_gstate); DPSgsave(ctxt); matrix = [self _matrixToWindow]; @@ -1331,6 +1332,9 @@ GSSetDragTypes(NSView* obj, NSArray *types) NSGraphicsContext *ctxt = GSCurrentContext(); NSAssert(_window != nil, NSInternalInconsistencyException); + /* Check for deferred window */ + if ([_window gState] == 0) + return; /* Restore our original gstate */ DPSgrestore(ctxt); diff --git a/Source/NSWindow.m b/Source/NSWindow.m index c3565e7c4..64ff26d78 100644 --- a/Source/NSWindow.m +++ b/Source/NSWindow.m @@ -560,6 +560,35 @@ static NSMapTable* windowmaps = NULL; [super dealloc]; } +- (void) _initBackendWindow: (NSRect)frame +{ + NSGraphicsContext *context = GSCurrentContext(); + + frame = [NSWindow contentRectForFrameRect: frame styleMask: _styleMask]; + DPSwindow(context, NSMinX(frame), NSMinY(frame), + NSWidth(frame), NSHeight(frame), + _backingType, &_windowNum); + DPSstylewindow(context, _styleMask, _windowNum); + DPSsetwindowlevel(context, [self level], _windowNum); + + // Set window in new _gstate + DPSgsave(context); + DPSwindowdevice(context, _windowNum); + DPSgstate(context); + _gstate = GSWDefineAsUserObj(context); + DPSgrestore(context); + NSMapInsert (windowmaps, (void*)_windowNum, self); + + if (NSIsEmptyRect([_wv frame])) + { + frame.origin = NSZeroPoint; + [_wv setFrame: frame]; + [_wv setNeedsDisplay: YES]; + } + NSDebugLLog(@"NSWindow", @"Created NSWindow frame %@", + NSStringFromRect(_frame)); +} + /* * Initializing and getting a new NSWindow object */ @@ -583,7 +612,6 @@ static NSMapTable* windowmaps = NULL; defer: (BOOL)flag screen: (NSScreen*)aScreen { - NSGraphicsContext *context = GSCurrentContext(); NSRect cframe; NSDebugLog(@"NSWindow default initializer\n"); @@ -628,21 +656,16 @@ static NSMapTable* windowmaps = NULL; part a view is drawing in, so NSWindow only has to flush that portion */ _rectsBeingDrawn = RETAIN([NSMutableArray arrayWithCapacity: 10]); - // FIXME: If flag is YES, the creation of the window should be defered - DPSwindow(context, NSMinX(contentRect), NSMinY(contentRect), - NSWidth(contentRect), NSHeight(contentRect), - bufferingType, &_windowNum); - DPSstylewindow(context, aStyle, _windowNum); - DPSsetwindowlevel(context, [self level], _windowNum); - - // Set window in new _gstate - DPSgsave(context); - DPSwindowdevice(context, _windowNum); - DPSgstate(context); - _gstate = GSWDefineAsUserObj(context); - DPSgrestore(context); - - NSMapInsert (windowmaps, (void*)_windowNum, self); + /* Create window (if not deferred) */ + _windowNum = 0; + _gstate = 0; + if (flag == NO) + { + NSDebugLLog(@"NSWindow", @"Creating NSWindow\n"); + [self _initBackendWindow: _frame]; + } + else + NSDebugLLog(@"NSWindow", @"Defering NSWindow creation\n"); NSDebugLog(@"NSWindow end of init\n"); return self; @@ -1037,6 +1060,9 @@ static NSMapTable* windowmaps = NULL; - (void) orderWindow: (NSWindowOrderingMode)place relativeTo: (int)otherWin { + NSGraphicsContext *context = GSCurrentContext(); + BOOL display = NO; + if (place == NSWindowOut) { _f.visible = NO; @@ -1052,7 +1078,19 @@ static NSMapTable* windowmaps = NULL; } [self _lossOfKeyOrMainWindow]; } - DPSorderwindow(GSCurrentContext(), place, otherWin, _windowNum); + else + { + // create deferred window + if(_windowNum == 0) + { + [self _initBackendWindow: _frame]; + display = YES; + } + } + DPSorderwindow(context, place, otherWin, _windowNum); + if (display) + [self display]; + if (place != NSWindowOut) { if (_rFlags.needs_display == NO) @@ -1091,8 +1129,8 @@ static NSMapTable* windowmaps = NULL; } if ([self isKeyWindow] == YES) { - DPSsetinputstate(GSCurrentContext(), _windowNum, GSTitleBarKey); - DPSsetinputfocus(GSCurrentContext(), _windowNum); + DPSsetinputstate(context, _windowNum, GSTitleBarKey); + DPSsetinputfocus(context, _windowNum); } } } @@ -1272,8 +1310,11 @@ static NSMapTable* windowmaps = NULL; * Now we can tell the graphics context to do the actual resizing. * We will recieve an event to tell us when the resize is done. */ + if(_gstate) DPSplacewindow(GSCurrentContext(), frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height, _windowNum); + else + _frame = frameRect; if (flag) [self display]; @@ -1381,6 +1422,9 @@ static NSMapTable* windowmaps = NULL; - (void) display { + if (_gstate == 0 || _f.visible == NO) + return; + _rFlags.needs_display = NO; // FIXME: Is the first responder processing needed here? if ((!_firstResponder) || (_firstResponder == self)) @@ -1472,10 +1516,11 @@ static NSMapTable* windowmaps = NULL; [[_rectsBeingDrawn objectAtIndex: i] rectValue]); } - DPSflushwindowrect(context, - NSMinX(_rectNeedingFlush), NSMinY(_rectNeedingFlush), - NSWidth(_rectNeedingFlush), NSHeight(_rectNeedingFlush), - _windowNum); + if (_windowNum) + DPSflushwindowrect(context, + NSMinX(_rectNeedingFlush), NSMinY(_rectNeedingFlush), + NSWidth(_rectNeedingFlush), NSHeight(_rectNeedingFlush), + _windowNum); _f.needs_flush = NO; _rectNeedingFlush = NSZeroRect; }