Copyright ã1992 by Eric P. Scott.  All Rights Reserved.
PRELIMINARY

MapView

INHERITS FROM	View : Responder : Object

DECLARED IN	MapView.h

CLASS DESCRIPTION

The MapView class provides a graphic representation of hosts on a network and can query their status using the rusers protocol (version 2).  Each machine image shows ªcoarseº status: whether the host is up, if it's being used, and if someone is logged onto the console.  By positioning the cursor over a machine and pressing the mouse button, the user can obtain more detailed information akin to rusers -a -l.

Unlike the command-line rusers program, MapView needs to be told in advance which machines to be interested in.  While it uses exactly the same protocolÐand hence obtains the same information, data for unexpected hosts is silently discarded. 

The external form of the map description takes the form of an ASCII con®guration ®le, which speci®es the name of each machine, its IP address, an origin in MapView coordinates, and the name of an image to display.  The exact appearance of machine graphics is of little concern; the main requirement is the presence of a 64x64 area where NeXT Mail ªPeople imagesº can be composited to indicate console users.

Con®guration File Format

This ®le consists of two sections: a prologue followed by machine descriptions.  The ®rst character of each line speci®es its type.  Blank lines and lines beginning # with are ignored.  Processing stops at end-of-®le or when a line beginning with Q is read.

Types valid in the prologue:

Axxx.xxx.xxx.xxx  speci®es a broadcast IP address.  This type may appear multiple times in the prologue.  If absent, the broadcast list is constructed by querying each network interface.  (If you don't understand exactly what this does and when you might want to use it, it's probably not for you.)

Bx,y,w,h  forcibly adjusts the MapView to the given rectangle.  Rarely useful.

I0,0,imagename  sets a background image and disables automatic expansion of the MapView while adding machine descriptions.

Ttitle  sets the MapView's title string.  The title string is not displayed by the MapView, although its value is accessible through methods described below.

Types valid in machine descriptions:

Nname  begins a new machine description.  MANDATORY.

Axxx.xxx.xxx.xxx  speci®es the IP address for this machine.  No two machine descriptions may have the same IP address.  If omitted, the ®rst address returned by gethostbyname(3N) will be used.

Ix,y,imagename  speci®es the image to display for this machine and its origin in MapView coordinates.

Px,y,w,h  speci®es the rectangle relative to the machine image where user images should be inserted.  w,h should normally be 64,64.  If written as P~x,y,w,h all usernames will be considered unknown.  If omitted, no subimages will appear!

The con®guration ®le is processed by readConfigFile:, which should be called after the MapView has been initialized with initFrame:.

Remote Procedure Call

The startRPC method constructs a rusers request RPC message, and sends it to all known broadcast addresses.  Replies are collected using an procedure registered with DPSAddFD at suf®cient priority to be serviced from modal responders.  MapView continues to collect responses until 4 seconds elapse with no replies.  Then the timeout is lengthened to 6 seconds, and the broadcast repeated.  This continues four more times, with the timeout lengthened by 2 seconds each time.  When no replies arrive for 14 seconds after the ®nal broadcast, the RPC is deemed complete.  If a delegate has been set, it will receive a mapDidRPC: message.

Portions of MapView's RPC code are copyrighted by Sun Microsystems, Inc. and used with permission.

How Replies Are Displayed

When a reply arrives from a mapped machine, an image is composited over the corresponding ªPº rectangle.

·	If a user is logged onto the console, MapView looks for an NXImage named ªusername+º to display.  If not found, it will attempt to create it from ~/Library/Images/People/username.tiff or /LocalLibrary/Images/People/username.tiff (unless the tilde flag was given in the P line).  If still unresolved, the image ªunknownº will be used.
·	If users are logged in, but not on the console, MapView will display the ªsomebodyº image.
·	If no users are logged in, the ªnobodyº image will be shown.

NXImages are allocated from the Application's zone and are not themselves freed when MapView instances are freed.

Indicating Nonresponsive Hosts

Since MapView already knows which hosts are supposed to be ªout there,º it's possible to indicate ªdeadº machines as well as ªliveº ones.  The markDown method can be used prior to startRPC to ¯ag each machine as not having received any replies.  Then the delegate's mapDidRPC: method can use showDown to set each nonresponsive machine to display the ªdownº image. 

INSTANCE VARIABLES

Inherited from Object	Class	isa;

Inherited from Responder	id	nextResponder;

Inherited from View	NXRect	frame;
NXRect	bounds;
id	superview;
id	subviews;
id	window;
struct __vFlags	vFlags;

Declared in MapView	id	delegate;
id	image;
id	titleCell;
id	cursor;
NXZone	*htZone;
NXHashTable	*ht;
NXZone	*configZone;
struct mapview_ihost{
struct in_addr		inaddr;
char		*name;
int		flags;
id		image;
NXRect		frame;
NXRect		p_frame;
id		p_image;
int		uiacnt;
struct utmp		*uiaa;
NXPoint		unorigin;
}	*curihost;
NXZone	*utmpZone;
struct {
struct sockaddr_in		baddr;
DPSTimedEntry		tid;
double		tper;
char		outbuf[MAX_BROADCAST_SIZE];
int		nets;
struct in_addr		addrs[20];
}	_rpc;

delegate 	The id of this MapView's delegate

image 	The id of the background NXImage  (if any)

titleCell 	The id of a TextFieldCell containing this MapView's title

cursor 	The id of a NXCursor to be displayed over machine images

htZone 	The NXZone from which ht was allocated

ht 	A pointer to a hash table containing struct mapview_ihost entries

configZone 	The NXZone in which machine names are stored

curihost 	A pointer to the structure being built as a con®guration ®le is read

utmpZone 	The NXZone used to store RPC results

_rpc 	Private state information for the RPC code

METHOD TYPES

Initializing and freeing a MapView	± initFrame:
- free

Assigning a delegate	- setDelegate:
- delegate

Setting the MapView's title	- setTitle: 
- title

Reading a stored con®guration 	- readConfigFile:

Displaying the Map	- drawSelf::
- showDown

Managing the cursor	- setCursor:
- cursor 
- resetCursorRects 

Tracking the mouse	- acceptsFirstMouse 
- mouseDown:

Resetting internal state	- markDown 

Scrolling the MapView	- scrollToHostName:
- scrollToCenterHostName: 

Managing Remote Procedure Calls	- startRPC 
- stopRPC 
- isRPCing 

INSTANCE METHODS

acceptsFirstMouse
- (BOOL)acceptsFirstMouse

Returns YES to indicate that MapView accepts a mouse click that activates its window.

See also:  ± mouseDown:

cursor
- cursor

Returns the NXCursor to displayed when the mouse is positioned over a machine image.

See also:  ±setCursor:

delegate
- delegate

Returns the MapView's delegate.

See also:  ±setDelegate:

drawSelf::
- drawSelf:(const NXRect *)rects :(int)rectCount

Draws the MapView.  Returns self.  

free
- free

Frees the memory used by the MapView and its title.  Does not free any NXImages.  Returns nil.  

initFrame:
- initFrame:(const NXRect *)frameRect

Initializes and returns the receiver, a new instance of MapView, setting frameRect as its frame rectangle.  Since a newly-initialized MapView has no con®guration information, it won't display anything.  

See also:  ± readConfigFile:

isRPCing
- (BOOL)isRPCing

Returns YES if the MapView has a RPC active.

See also:  ± startRPC, ± stopRPC

mouseDown:
- mouseDown:(NXEvent *)theEvent

Invoked when the mouse button goes down with the cursor within the bounds of the MapView.  If the cursor lies within the frame rectangle of one of the mapped machines, pops up a balloon containing information about the currently logged-in users.  The balloon remains until the mouse goes up.  If updated information arrives while the mouse is held down, the balloon's contents will not be revised on-screen.  The application's NXFixedPitchFont and NXFixedPitchFontSize defaults determine which font to use (12 point Courier is a good choice).

markDown
- markDown

Clears the ªvalid RPC response receivedº ¯ag for each machine.

See also:  ± showDown

readConfigFile:
- readConfigFile:(const char *)filename

Reads a map description from the speci®ed ®le filename.  If an error occurs while reading a con®guration ®le, an alert Panel is displayed, and the application terminates.  «this will be changed in a future release»  This should be called exactly once after the instance has been initialized.

resetCursorRects
- resetCursorRects

Establishes cursor rectangles for visible machine images if a non-nil cursor has been set.

See also:  ± setCursor:

scrollToCenterHostName:
- scrollToCenterHostName:(const char *)hostName

Attempts to scroll the MapView so the image representing hostName appears centered within its parent ClipView.  The receiving MapView must be a ClipView's document view.  Returns self if scrolling actually occurs; otherwise returns nil.

See also:   ±scrollToHostName:

scrollToHostName:
- scrollToHostName:(const char *)hostName

Scrolls the MapView so the image representing hostName becomes visible within the MapView's parent ClipView.  The receiving MapView must be a ClipView's document view.  This method will scroll the ClipView the minimum amount necessary to make the image visible.  Returns self if scrolling actually occurs; otherwise returns nil.

See also:   ± scrollToCenterHostName:

setCursor:
- setCursor:newCursor

Sets the NXCursor displayed when the mouse is positioned over a machine's image.  Invalidates cursor rectangles.  Returns the old cursor.

See also:  ± cursor

setDelegate:
- setDelegate:sender

Sets the MapView's delegate.  See METHODS IMPLEMENTED BY THE DELEGATE, below.

See also:  ± delegate

setTitle:
- setTitle:(const char *)aString

Sets the MapView's title.  Titles are not displayed by any of MapView's methods.

See also:  ± title

showDown
- showDown

Sets the image for any machines that haven't responded to RPC to the ªdownº icon and redisplays.  This is typically invoked from the mapDidRPC: delegate method.

See also:  ± markDown

startRPC
- startRPC

Sends a broadcast RPC request and registers for replies with DPSAddFD.

See also:  ± isRPCing, ± stopRPC

stopRPC
- stopRPC

Cancels any pending RPC activity.  The delegate will not receive a mapDidRPC: message.

See also:  ± isRPCing, ± startRPC

title
- (const char *)title

Returns the title associated with this MapView.

METHODS IMPLEMENTED BY THE DELEGATE

mapDidRPC:
- mapDidRPC:sender

Responds to a message informing the delegate that the sender MapView has completed a broadcast RPC.

CONSTANTS AND DEFINED TYPES

/* structure representing a mapped machine */
struct mapview_ihost {
    struct in_addr inaddr;           /* IP address of this machine--must come first */
    char *name;                      /* pointer to name of this machine */
    int flags;                       /* status flags */
    id image;                        /* NXImage to display for this machine */
    NXRect frame;                    /* image's frame rectangle */
    NXRect p_frame;                  /* where to display mug shots */
    id p_image;                      /* NXImage for current console luser */
    int uiacnt;                      /* number of logged-in users according to rusers */
    struct utmpidle *uiaa;           /* pointer to struct utmpidle array */
    NXPoint unorigin;                /* RESERVED for future use */ «will probably go away»
};

/* 
 * flags bits 
 */
 
#define MAPVIEW_RESPONDED 1          /* received at least one reply since last markDown */
#define MAPVIEW_P_ORIGIN_OK 2        /* p_frame is valid */
#define MAPVIEW_P_ANON 4             /* don't use People images for this machine */ 
#define MAPVIEW_UNORIGIN_OK 8        /* RESERVED for future use */ «will probably go away»