Index: Source/GSWindowDecorationView.m
===================================================================
--- Source/GSWindowDecorationView.m	(revision 32836)
+++ Source/GSWindowDecorationView.m	(working copy)
@@ -31,6 +31,7 @@
 #import "AppKit/NSColor.h"
 #import "AppKit/NSGraphics.h"
 #import "AppKit/NSMenuView.h"
+#import "AppKit/NSScreen.h"
 #import "AppKit/NSWindow.h"
 #import "GNUstepGUI/GSDisplayServer.h"
 #import "GNUstepGUI/GSTheme.h"
@@ -39,6 +40,14 @@
 
 @implementation GSWindowDecorationView
 
+static inline NSRect RectScaledByFactor(NSRect aRect, CGFloat factor)
+{
+  return NSMakeRect(aRect.origin.x * factor,
+		    aRect.origin.y * factor,
+		    aRect.size.width * factor,
+		    aRect.size.height * factor);
+}
+
 + (id<GSWindowDecorator>) windowDecorator
 {
   if ([GSCurrentServer() handlesWindowDecorations])
@@ -65,6 +74,15 @@
 + (NSRect) contentRectForFrameRect: (NSRect)aRect
 			 styleMask: (unsigned int)aStyle
 {
+  if (0 == (aStyle & NSUnscaledWindowMask))
+    {
+      // FIXME: This method should probably take a screen parameter
+      // rather than assuming the mainScreen
+
+      CGFloat factor = [[NSScreen mainScreen] userSpaceScaleFactor]; 
+      aRect = RectScaledByFactor(aRect, 1/factor);
+    }
+
   float t = 0.0, b = 0.0, l = 0.0, r = 0.0;
 
   [self offsets: &l : &r : &t : &b forStyleMask: aStyle];
@@ -85,6 +103,15 @@
   aRect.size.height += t + b;
   aRect.origin.x -= l;
   aRect.origin.y -= b;
+
+  if (0 == (aStyle & NSUnscaledWindowMask))
+    {
+      // FIXME: This method should probably take a screen parameter
+      // rather than assuming the mainScreen
+
+      CGFloat factor = [[NSScreen mainScreen] userSpaceScaleFactor];
+      aRect = RectScaledByFactor(aRect, factor);
+    }
   return aRect;
 }
 
@@ -286,6 +313,13 @@
       contentViewFrame.size.height -= newToolbarViewHeight;
     }
 
+  if (0 == ([window styleMask] & NSUnscaledWindowMask))
+    {
+      CGFloat factor = [window userSpaceScaleFactor];
+      NSRect aRect = RectScaledByFactor([self frame], 1/factor);
+      [self setBoundsSize: aRect.size];
+    }
+
   if ([windowContentView superview] == self)
     {
       [windowContentView setFrame:contentViewFrame];
Index: Source/NSScreen.m
===================================================================
--- Source/NSScreen.m	(revision 32836)
+++ Source/NSScreen.m	(working copy)
@@ -35,6 +35,7 @@
 #import <Foundation/NSGeometry.h>
 #import <Foundation/NSNotification.h>
 #import <Foundation/NSValue.h>
+#import <Foundation/NSUserDefaults.h>
 #import "AppKit/AppKitExceptions.h"
 #import "AppKit/NSApplication.h"
 #import "AppKit/NSInterfaceStyle.h"
@@ -414,19 +415,27 @@
 
 - (float) userSpaceScaleFactor
 {
-  GSDisplayServer *srv;
-  NSSize dpi;
+  NSNumber *factor = [[NSUserDefaults standardUserDefaults]
+		       objectForKey: @"GSScaleFactor"];
 
-  srv = GSCurrentServer();
-  if (srv != nil)
+  if (factor != nil)
     {
-      dpi = [GSCurrentServer() resolutionForScreen: _screenNumber];
-      // take average for 72dpi
-      return (dpi.width + dpi.height) / 144;
+      return [factor floatValue];
     }
   else
     {
-      return 1.0;
+      GSDisplayServer *srv = GSCurrentServer();
+
+      if (srv != nil)
+	{
+	  NSSize dpi = [GSCurrentServer() resolutionForScreen: _screenNumber];
+	  // take average for 72dpi
+	  return (dpi.width + dpi.height) / 144;
+	}
+      else
+	{
+	  return 1.0;
+	}
     }
 }
 
Index: Source/GSStandardWindowDecorationView.m
===================================================================
--- Source/GSStandardWindowDecorationView.m	(revision 32836)
+++ Source/GSStandardWindowDecorationView.m	(working copy)
@@ -99,24 +99,24 @@
     {
       float titleHeight = [theme titlebarHeight];
 
-      titleBarRect = NSMakeRect(0.0, _frame.size.height - titleHeight,
-	_frame.size.width, titleHeight);
+      titleBarRect = NSMakeRect(0.0, [self bounds].size.height - titleHeight,
+	[self bounds].size.width, titleHeight);
     }
   if (hasResizeBar)
     {
-      resizeBarRect = NSMakeRect(0.0, 0.0, _frame.size.width, [theme resizebarHeight]);
+      resizeBarRect = NSMakeRect(0.0, 0.0, [self bounds].size.width, [theme resizebarHeight]);
     }
   if (hasCloseButton)
     {
       closeButtonRect = NSMakeRect(
-	_frame.size.width - 15 - 4, _frame.size.height - 15 - 4, 15, 15);
+	[self bounds].size.width - 15 - 4, [self bounds].size.height - 15 - 4, 15, 15);
       [closeButton setFrame: closeButtonRect];
     }
 
   if (hasMiniaturizeButton)
     {
       miniaturizeButtonRect = NSMakeRect(
-	4, _frame.size.height - 15 - 4, 15, 15);
+	4, [self bounds].size.height - 15 - 4, 15, 15);
       [miniaturizeButton setFrame: miniaturizeButtonRect];
     }
 }
@@ -180,7 +180,7 @@
 - (void) drawRect: (NSRect)rect
 {
   [[GSTheme theme] drawWindowBorder: rect
-                   withFrame: _frame 
+                   withFrame: [self bounds] 
                    forStyleMask: [window styleMask]
                    state: inputState
                    andTitle: [window title]];
Index: Source/NSCachedImageRep.m
===================================================================
--- Source/NSCachedImageRep.m	(revision 32836)
+++ Source/NSCachedImageRep.m	(working copy)
@@ -92,7 +92,7 @@
   frame.origin = NSMakePoint(0,0);
   frame.size = aSize;
   win = [[GSCacheW alloc] initWithContentRect: frame
-				    styleMask: NSBorderlessWindowMask
+				    styleMask: NSBorderlessWindowMask | NSUnscaledWindowMask
 				      backing: NSBackingStoreRetained
 					defer: NO];
   self = [self initWithWindow: win rect: frame];
@@ -136,7 +136,7 @@
     }
   if (!_window)
     _window = [[GSCacheW alloc] initWithContentRect: _rect
-					  styleMask: NSBorderlessWindowMask
+					  styleMask: NSBorderlessWindowMask | NSUnscaledWindowMask
 					    backing: NSBackingStoreRetained
 					      defer: NO];
   [self setSize: _rect.size];
Index: Source/NSImage.m
===================================================================
--- Source/NSImage.m	(revision 32836)
+++ Source/NSImage.m	(working copy)
@@ -840,61 +840,35 @@
                 operation: (NSCompositingOperation)op
                  fraction: (float)delta
 {
-  NS_DURING
-    { 
-      NSImageRep *rep = [self bestRepresentationForDevice: nil];
-      NSCachedImageRep *cache = nil;
+  NSGraphicsContext *ctxt = GSCurrentContext();
 
-      if (rep == nil)
-        NS_VOIDRETURN;
+  // Calculate the user space scale factor of the current window
+  NSView *focusView = [NSView focusView];
+  CGFloat scaleFactor = 1.0;
+  if (focusView != nil)
+    {
+      scaleFactor = [[focusView window] userSpaceScaleFactor];
+    }
 
-      if (([GSCurrentContext() isDrawingToScreen] == YES)
-          && _cacheMode != NSImageCacheNever)
-        cache = [self _doImageCache: rep];
+  // Create a transform which undoes the CTM, except preserves
+  // the current translation and doesn't undo the user space scale factor
 
-      if (cache != nil)
-        {
-          NSGraphicsContext *ctxt = GSCurrentContext();
-          NSRect rect = [cache rect];
+  NSAffineTransform *transform = [ctxt GSCurrentCTM];
 
-          NSDebugLLog(@"NSImage", @"composite rect %@ in %@", 
-                      NSStringFromRect(rect), NSStringFromRect(srcRect));
+  NSAffineTransform *newTransform = [NSAffineTransform transform];
+  NSPoint translation = [transform transformPoint: aPoint];
+  [newTransform translateXBy: translation.x
+			 yBy: translation.y];
+  [newTransform scaleBy: scaleFactor];
 
-          // Move the drawing rectangle to the origin of the image rep
-          // and intersect the two rects.
-          srcRect.origin.x += rect.origin.x;
-          srcRect.origin.y += rect.origin.y;
-          rect = NSIntersectionRect(srcRect, rect);
-          
-          [ctxt GScomposite: [[cache window] gState]
-                    toPoint: aPoint
-                   fromRect: rect
-                  operation: op
-                   fraction: delta];
-        }
-      else        
-        {
-          NSRect rect = NSMakeRect(aPoint.x, aPoint.y, _size.width, _size.height);
-          [self drawRepresentation: rep inRect: rect];
-        }
-    }
-  NS_HANDLER
-    {
-      NSLog(@"NSImage: compositeToPoint:fromRect:operation:fraction:"
-        @"failed due to %@: %@", 
-        [localException name], [localException reason]);
-      if ([_delegate respondsToSelector: @selector(imageDidNotDraw:inRect:)])
-        {
-            NSImage *image = [_delegate imageDidNotDraw: self inRect: srcRect];
-            
-            if (image != nil)
-              [image compositeToPoint: aPoint
-                     fromRect: srcRect 
-                     operation: op
-                     fraction: delta];
-        }
-    }
-  NS_ENDHANDLER
+  [ctxt GSSetCTM: newTransform];
+
+  [self drawAtPoint: NSMakePoint(0,0)
+	   fromRect: srcRect
+	  operation: op
+	   fraction: delta];
+  
+  [ctxt GSSetCTM: transform];
 }
 
 - (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat
Index: Source/NSView.m
===================================================================
--- Source/NSView.m	(revision 32836)
+++ Source/NSView.m	(working copy)
@@ -296,19 +296,26 @@
           [_matrixToWindow makeIdentityMatrix];
           [_matrixFromWindow makeIdentityMatrix];
         }
-      if (!_super_view)
-        {
-          _visibleRect = _bounds;
-          [_matrixToWindow makeIdentityMatrix];
-          [_matrixFromWindow makeIdentityMatrix];
-        }
       else
         {
           NSRect		superviewsVisibleRect;
-          BOOL			wasFlipped = [_super_view isFlipped];
-          NSAffineTransform	*pMatrix = [_super_view _matrixToWindow];
-          NSAffineTransformStruct     ts = [pMatrix transformStruct];
+          BOOL			wasFlipped;
+          NSAffineTransform	*pMatrix;
+          NSAffineTransformStruct     ts;
  
+	  if (_super_view != nil)
+	    {
+	      wasFlipped = [_super_view isFlipped];
+	      pMatrix = [_super_view _matrixToWindow];
+	    }
+	  else
+	    {
+	      wasFlipped = NO;
+	      pMatrix = [NSAffineTransform transform];
+           }
+	      
+	  ts = [pMatrix transformStruct];
+
           /* prepend translation */
           ts.tX = NSMinX(_frame) * ts.m11 + NSMinY(_frame) * ts.m21 + ts.tX;
           ts.tY = NSMinX(_frame) * ts.m12 + NSMinY(_frame) * ts.m22 + ts.tY;
@@ -340,10 +347,17 @@
           [_matrixFromWindow setTransformStruct: ts];
           [_matrixFromWindow invert];
 
-          superviewsVisibleRect = [self convertRect: [_super_view visibleRect]
-                                        fromView: _super_view];
-
-          _visibleRect = NSIntersectionRect(superviewsVisibleRect, _bounds);
+	  if (_super_view != nil)
+	    {
+	      superviewsVisibleRect = [self convertRect: [_super_view visibleRect]
+					       fromView: _super_view];
+	      
+	      _visibleRect = NSIntersectionRect(superviewsVisibleRect, _bounds);
+	    }
+	  else
+	    {
+	      _visibleRect = _bounds;
+	    }
         }
       if (_rFlags.has_tooltips != 0)
         {
@@ -1605,59 +1619,44 @@
 
 - (NSPoint) convertPoint: (NSPoint)aPoint fromView: (NSView*)aView
 {
-  NSPoint	new;
-  NSAffineTransform	*matrix;
+  NSPoint inBase;
 
-  if (!aView)
-    aView = [[_window contentView] superview];
-  if (aView == self || aView == nil)
-    return aPoint;
-  NSAssert(_window == [aView window], NSInvalidArgumentException);
+  if (aView == self)
+    {
+      return aPoint;
+    }
 
-  matrix = [aView _matrixToWindow];
-  new = [matrix transformPoint: aPoint];
-
-  if (_coordinates_valid)
+  if (aView != nil)
     {
-      matrix = _matrixFromWindow;
+      NSAssert(_window == [aView window], NSInvalidArgumentException);      
+      inBase = [[aView _matrixToWindow] transformPoint: aPoint];    
     }
   else
     {
-      matrix = [self _matrixFromWindow];
+      inBase = aPoint;
     }
-  new = [matrix transformPoint: new];
 
-  return new;
+  return [[self _matrixFromWindow] transformPoint: inBase];
 }
 
 - (NSPoint) convertPoint: (NSPoint)aPoint toView: (NSView*)aView
 {
-  NSPoint	new;
-  NSAffineTransform	*matrix;
+  NSPoint inBase;
 
-  if (aView == nil)
-    {
-      aView = [[_window contentView] superview];
-    }
-  if (aView == self || aView == nil)
-    {
-      return aPoint;
-    }
-  NSAssert(_window == [aView window], NSInvalidArgumentException);
+  if (aView == self)
+    return aPoint;
 
-  if (_coordinates_valid)
+  inBase = [[self _matrixFromWindow] transformPoint: aPoint];
+
+  if (aView != nil)
     {
-      matrix = _matrixToWindow;
+      NSAssert(_window == [aView window], NSInvalidArgumentException);      
+      return [[aView _matrixToWindow] transformPoint: inBase];
     }
   else
     {
-      matrix = [self _matrixToWindow];
+      return inBase;
     }
-  new = [matrix transformPoint: aPoint];  
-  matrix = [aView _matrixFromWindow];
-  new = [matrix transformPoint: new];
-
-  return new;
 }
 
 
@@ -1709,27 +1708,23 @@
 {
   NSAffineTransform *matrix1, *matrix2;
 
-  if (aView == nil)
+  if (aView == self || _window == nil || (aView != nil && [aView window] == nil))
     {
-      aView = [[_window contentView] superview];
-    }
-  if (aView == self || aView == nil || _window == nil || [aView window] == nil)
-    {
       return aRect;
     }
-  NSAssert(_window == [aView window], NSInvalidArgumentException); 
 
-  matrix1 = [aView _matrixToWindow];
-
-  if (_coordinates_valid)
+  if (aView != nil)
     {
-      matrix2 = _matrixFromWindow;
+      NSAssert(_window == [aView window], NSInvalidArgumentException); 
+      matrix1 = [aView _matrixToWindow];      
     }
   else
     {
-      matrix2 = [self _matrixFromWindow];
+      matrix1 = [NSAffineTransform transform];
     }
 
+  matrix2 = [self _matrixFromWindow];
+
   return convert_rect_using_matrices(aRect, matrix1, matrix2);
 }
 
@@ -1745,103 +1740,76 @@
 {
   NSAffineTransform *matrix1, *matrix2;
 
-  if (aView == nil)
+  if (aView == self || _window == nil || (aView != nil && [aView window] == nil))
     {
-      aView = [[_window contentView] superview];
-    }
-  if (aView == self || aView == nil || _window == nil || [aView window] == nil)
-    {
       return aRect;
     }
-  NSAssert(_window == [aView window], NSInvalidArgumentException);
 
-  if (_coordinates_valid)
+  matrix1 = [self _matrixToWindow];
+
+  if (aView != nil)
     {
-      matrix1 = _matrixToWindow;
+      NSAssert(_window == [aView window], NSInvalidArgumentException);
+      matrix2 = [aView _matrixFromWindow];
     }
   else
     {
-      matrix1 = [self _matrixToWindow];
+      matrix2 = [NSAffineTransform transform];
     }
 
-  matrix2 = [aView _matrixFromWindow];
-
   return convert_rect_using_matrices(aRect, matrix1, matrix2);
 }
 
 - (NSSize) convertSize: (NSSize)aSize fromView: (NSView*)aView
 {
-  NSSize		new;
-  NSAffineTransform	*matrix;
+  NSSize inBase;
+  NSSize inSelf;
 
-  if (aView == nil)
+  if (aView)
     {
-      aView = [[_window contentView] superview];
+      NSAssert(_window == [aView window], NSInvalidArgumentException);      
+      inBase = [[aView _matrixToWindow] transformSize: aSize];
+      if (inBase.height < 0.0)
+	{
+	  inBase.height = -inBase.height;
+	} 
     }
-  if (aView == self || aView == nil)
+  else
     {
-      return aSize;
+      inBase = aSize;
     }
-  NSAssert(_window == [aView window], NSInvalidArgumentException);
-  matrix = [aView _matrixToWindow];
-  new = [matrix transformSize: aSize];
-  if (new.height < 0.0)
-    {
-      new.height = -new.height;
-    }
 
-  if (_coordinates_valid)
+  inSelf = [[self _matrixFromWindow] transformSize: inBase];
+  if (inSelf.height < 0.0)
     {
-      matrix = _matrixFromWindow;
+      inSelf.height = -inSelf.height;
     }
-  else
-    {
-      matrix = [self _matrixFromWindow];
-    }
-  new = [matrix transformSize: new];
-  if (new.height < 0.0)
-    {
-      new.height = -new.height;
-    }
-  return new;
+  return inSelf;
 }
 
 - (NSSize) convertSize: (NSSize)aSize toView: (NSView*)aView
 {
-  NSSize		new;
-  NSAffineTransform	*matrix;
+  NSSize inBase = [[self _matrixToWindow] transformSize: aSize];
+  if (inBase.height < 0.0)
+    {
+      inBase.height = -inBase.height;
+    } 
 
-  if (aView == nil)
+  if (aView)
     {
-      aView = [[_window contentView] superview];
+      NSSize inOther;
+      NSAssert(_window == [aView window], NSInvalidArgumentException);      
+      inOther = [[aView _matrixFromWindow] transformSize: inBase];
+      if (inOther.height < 0.0)
+	{
+	  inOther.height = -inOther.height;
+	}
+      return inOther;
     }
-  if (aView == self || aView == nil)
-    {
-      return aSize;
-    }
-  NSAssert(_window == [aView window], NSInvalidArgumentException);
-  if (_coordinates_valid)
-    {
-      matrix = _matrixToWindow;
-    }
   else
     {
-      matrix = [self _matrixToWindow];
+      return inBase;
     }
-  new = [matrix transformSize: aSize];
-  if (new.height < 0.0)
-    {
-      new.height = -new.height;
-    }
-
-  matrix = [aView _matrixFromWindow];
-  new = [matrix transformSize: new];
-  if (new.height < 0.0)
-    {
-      new.height = -new.height;
-    }
-
-  return new;
 }
 
 - (NSPoint) convertPointFromBase: (NSPoint)aPoint
Index: ColorPickers/GSWheelColorPicker.m
===================================================================
--- ColorPickers/GSWheelColorPicker.m	(revision 32836)
+++ ColorPickers/GSWheelColorPicker.m	(working copy)
@@ -187,24 +187,24 @@
 
 -(void) regenerateImage
 {
-  NSRect frame = [self bounds];
+  NSSize size = [self convertSizeToBase: [self bounds].size];
   CGFloat cx, cy, cr;
- 
+
   [image release];
   image = nil;
 
-  cx = (frame.origin.x + frame.size.width) / 2;
-  cy = (frame.origin.y + frame.size.height) / 2;
+  cx = (size.width) / 2;
+  cy = (size.height) / 2;
 
-  cr = frame.size.width;
-  if (cr > frame.size.height)
-    cr = frame.size.height;
+  cr = size.width;
+  if (cr > size.height)
+    cr = size.height;
 
   cr = cr / 2 - 2;
 
   {
-    NSUInteger width = frame.size.width;
-    NSUInteger height = frame.size.height;
+    NSUInteger width = size.width;
+    NSUInteger height = size.height;
     NSUInteger bytesPerRow;
     NSBitmapImageRep *bmp;
     unsigned char *data;
@@ -303,7 +303,7 @@
 	  }
       }
 
-    image = [[NSImage alloc] initWithSize: frame.size];
+    image = [[NSImage alloc] initWithSize: [self bounds].size];
     [image addRepresentation: bmp];
     [bmp release];
   }
