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.