This is Background.m in view mode; [Download] [Up]
/* Background.m based on "Background" by Scott Hess and Andreas Windemut (1991) */ #import "Background.h" #import <dpsclient/wraps.h> #import <appkit/Application.h> #import <appkit/Window.h> #import <appkit/NXImage.h> #import <appkit/Control.h> #import <appkit/screens.h> #import <defaults/defaults.h> #import <stdio.h> #import "../PSsplat.h" #import "../backgops.h" #import "../TVController.h" #define PSsplat(r, p) _PSsplat( (r)->origin.x, (r)->origin.y, \ (r)->size.width, (r)->size.height, (p)->x, (p)->y ) #define WLevel_Behind (-2) #define WLevel_Front 30 /* must be < 50 (BackSpace's SaverWindow) */ #define TooLargeRatio 2.2 #define bgMonoDefault 0 #define bgMonoCustom 1 #define bgColorDefault 2 #define bgColorCustom 3 @implementation Background:View - initFrame:(const NXRect *)frameRect; { [super initFrame: frameRect]; [NXApp getScreenSize:&screenSize]; image = NULL; isfront = NO; bgPaint = bgMonoDefault; return self; } - free { if (image != nil) [image free]; [super free]; return self; } /* Local Method */ - getDafaultBGColor { const NXScreen *sc; const char *defcolor; sc = [NXApp colorScreen]; if (sc->depth == NX_TwoBitGrayDepth || sc->depth == NX_EightBitGrayDepth) { defcolor = NXGetDefaultValue("NeXT1", "BWBackgroundColor"); if (!defcolor) bgPaint = bgMonoDefault; else { sscanf(defcolor, "%f", &bgColor[0]); bgPaint = bgMonoCustom; } }else { defcolor = NXGetDefaultValue("NeXT1", "BackgroundColor"); if (!defcolor) bgPaint = bgColorDefault; else { sscanf(defcolor, "%f%f%f", &bgColor[0], &bgColor[1], &bgColor[2]); bgPaint = bgColorCustom; } } return self; } /* Local Method */ - paintDefault:(NXRect *)rect { switch (bgPaint) { case bgMonoDefault: PSsetgray(NX_DKGRAY); break; case bgMonoCustom: PSsetgray(bgColor[0]); break; case bgColorDefault: PSsetrgbcolor(0.33333, 0.33333, 0.46667); break; case bgColorCustom: PSsetrgbcolor(bgColor[0], bgColor[1], bgColor[2]); break; default: PSsetgray(NX_DKGRAY); break; } NXRectFill(rect); return self; } - (Window *)initWinAttr { Window *win; NXRect rect; [self getFrame: &rect]; win = [[Window allocFromZone:[self zone]] initContent:&rect style:NX_TOKENSTYLE backing:NX_BUFFERED buttonMask:0 defer:NO]; [win setContentView: self]; [win useOptimizedDrawing:YES]; [win removeFromEventMask:(NX_LMOUSEDOWNMASK | NX_LMOUSEUPMASK | NX_MOUSEMOVEDMASK | NX_LMOUSEDRAGGEDMASK | NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK | NX_KEYDOWNMASK | NX_KEYUPMASK | NX_CURSORUPDATEMASK)]; [self getDafaultBGColor]; /* { */ [self lockFocus]; [self paintDefault: &rect]; /* } */ [self unlockFocus]; [self toBehind: self]; return win; } - (BOOL)acceptsFirstMouse { return YES; } - toBehind:sender { PSsetwindowlevel(WLevel_Behind, [window windowNum]); [window orderWindow:NX_BELOW relativeTo:0]; [window removeFromEventMask:NX_MOUSEDOWNMASK]; [theController backWinFront: (isfront = NO)]; return self; } - toFront:sender { PSsetwindowlevel(WLevel_Front, [window windowNum]); // [window orderFront:sender]; [window addToEventMask:NX_MOUSEDOWNMASK]; [theController backWinFront:(isfront = YES)]; return self; } - mouseDown:(NXEvent *)event { [[NXApp hide: self] unhide: self]; /* These calls are needed because of illegal action of WM. */ return [self toBehind: self]; } - (BOOL)isFront { return isfront; } /* Local Method */ - (double)enlargeScale: (const NXSize *)size by: (int)method err:(int *)err { double xr, yr, w, ratio = 1.0; if (err) *err = 0; xr = (double)screenSize.width / size->width; yr = (double)screenSize.height / size->height; if (method == bk_FitScreen) ratio = (xr < yr) ? xr : yr; else if (err == NULL) /* bk_CoverScreen for Bitmap */ ratio = (xr > yr) ? xr : yr; else { /* bk_CoverScreen */ if (xr > yr) { w = xr * size->height / (double)screenSize.height; ratio = xr; }else { w = yr * size->width / (double)screenSize.width; ratio = yr; } if (w > TooLargeRatio) { /* Too Large */ ratio = (xr < yr) ? xr : yr; /* bk_FitScreen */ *err = 1; } } return ratio; } - setImage: (NXImage *)backimage hasAlpha:(BOOL)alpha with: (int)method { NXSize sz, nwsz; NXPoint pnt; double ratio = 1.0; int mode; BOOL large = FALSE; drawMethod = method; [backimage getSize: &sz]; if (sz.width <= 0 || sz.height <= 0) return self; if (image != NULL) [image free]; image = [[NXImage allocFromZone:[self zone]] setScalable:YES]; if (image == NULL) return nil; if (drawMethod == bk_FitScreen || drawMethod == bk_CoverScreen) { ratio = [self enlargeScale:&sz by:drawMethod err:NULL]; nwsz.width = sz.width * ratio; nwsz.height = sz.height * ratio; drawMethod = bk_Centering; }else nwsz = sz; /* To make size of 'image' smaller than screen */ pnt.x = pnt.y = 0; if (nwsz.width > screenSize.width) { pnt.x = (screenSize.width - nwsz.width) / (ratio * 2.0); nwsz.width = screenSize.width; large = TRUE; } if (nwsz.height > screenSize.height) { pnt.y = (screenSize.height - nwsz.height) / (ratio * 2.0); nwsz.height = screenSize.height; large = TRUE; } if (large) { sz.width = nwsz.width / ratio; sz.height = nwsz.height / ratio; } [image setSize: &sz]; [self getDafaultBGColor]; mode = alpha ? NX_SOVER : NX_COPY; /* { */ [image lockFocus]; if (alpha) { NXRect rect; rect.size = sz; rect.origin.x = rect.origin.y = 0; [self paintDefault: &rect]; } [backimage composite:mode toPoint:&pnt]; /* } */ [image unlockFocus]; [image setSize: &nwsz]; return self; } - setStream: (NXStream *)stream with: (int)method { NXImage *backimage; NXSize sz; int err = 0; id rtn; if ((backimage = [NXImage allocFromZone:[self zone]]) == NULL) return nil; [backimage initFromStream: stream]; [backimage getSize: &sz]; if (method == bk_FitScreen || method == bk_CoverScreen) { double r = [self enlargeScale:&sz by:method err:&err]; sz.width *= r; sz.height *= r; method = bk_Centering; [backimage setScalable:YES]; [backimage setSize: &sz]; } rtn = [self setImage: backimage hasAlpha:YES with:method]; [backimage free]; return (err ? nil : rtn); } - drawSelf:(NXRect *)rect :(int)count { NXSize sz; NXPoint pnt; if (image == nil) return self; [image getSize:&sz]; if (sz.width <= 0 || sz.height <= 0) return self; if (drawMethod == bk_Centering) { /* Centering */ [self paintDefault: rect]; pnt.x = (screenSize.width - sz.width) / 2; pnt.y = (screenSize.height - sz.height) / 2; [image composite:NX_COPY toPoint:&pnt]; }else { int i, wd, ht; NXRect irect; if (drawMethod == bk_Tiling || sz.height >= screenSize.height) { /* Tiling */ wd = irect.size.width = sz.width; ht = irect.size.height = sz.height; }else { /* Brick Work */ wd = (int)(sz.width) / 2; pnt.x = -wd, pnt.y = sz.height; [image composite:NX_COPY toPoint:&pnt]; pnt.x = sz.width - wd; [image composite:NX_COPY toPoint:&pnt]; wd = irect.size.width = sz.width; ht = irect.size.height = sz.height * 2; } pnt.x = pnt.y = 0; [image composite:NX_COPY toPoint:&pnt]; irect.origin = pnt; for(i = wd; i < screenSize.width; i += wd) { pnt.x = i; PSsplat(&irect, &pnt); } pnt.x=0; irect.size.width = screenSize.width; for(i = ht; i < screenSize.height; i += ht) { pnt.y = i; PSsplat(&irect, &pnt); } } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.