This is MyApp.m in view mode; [Download] [Up]
/* MyApp.m */ #import <objc/List.h> #import <appkit/Window.h> #import <appkit/Bitmap.h> #import <appkit/Listener.h> #import <appkit/Bitmap.h> #import <appkit/graphics.h> #import <dpsclient/psops.h> #import <dpsclient/wraps.h> #import <streams/streams.h> #import <libc.h> #import <strings.h> #import <pwd.h> #import "IconView.h" #import "DockSpeaker.h" #import "MyApp.h" #define READ 0 #define DOCK_WINDOW_LEVEL (NX_MAINMENULEVEL - 1) char *mySalloc(string) /* returns a copy of string */ char *string; { char *newString; newString = (char *)malloc(strlen(string) + 1); if (!newString) { return(""); } strcpy(newString, string); return newString; } @implementation MyApp /* factory methods */ + new { self = [super new]; /* we want to be our own delegate */ [self setDelegate:self]; return self; } /* class methods */ - createDockWindows:(int *)minX :(int *)minY :(int *)maxX :(int *)maxY /* creates the dock windows based on the .altdock file */ { id dockWindowList, appBitmap; NXStream *fileStream; int fd, scanResult, success, xCoordinate, yCoordinate; char *homeDir, *dockFile, *appFileName; struct passwd *passwdEntry; /* initialize the bounding box */ *minX = *minY = *maxX = *maxY = 0; /* create a list to hold the dock's windows */ dockWindowList = [List new]; /* get ready to ask the WorkSpace for icons */ [[self appSpeaker] setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)]; /* get the user's home directory and create the .altdock file's abs path */ passwdEntry = getpwuid((int)getuid()); homeDir = passwdEntry->pw_dir; dockFile = (char *)malloc(strlen(homeDir) + 10); sprintf(dockFile, "%s/.altdock", homeDir); /* open a stream on the .altdock file */ fd = open(dockFile, READ); if (fd < 0) { NXRunAlertPanel(NULL, "Couldn't open .altdock file", NULL, NULL, NULL); free(dockFile); return dockWindowList; } fileStream = NXOpenFile(fd, NX_READONLY); while (YES) { /* get the window's x and y coordinates, then the app's path */ scanResult = NXScanf(fileStream, "%d %d\n", &xCoordinate, &yCoordinate); if (scanResult == EOF) { break; } else if (scanResult < 2) { NXRunAlertPanel(NULL, "Error reading .altdock file", NULL, NULL, NULL); break; } appFileName = [self stringFromStream:fileStream ok:&success]; if (!success) { /* we've reached the end of the .altdock file */ NXRunAlertPanel(NULL, "Error reading .altdock file", NULL, NULL, NULL); break; } /* get the app's bitmap */ appBitmap = [self bitmapFor:appFileName]; /* create the window */ [dockWindowList addObject:[self newIconWindowFor:appBitmap :xCoordinate :yCoordinate :appFileName]]; /* adjust the bounding box */ if (xCoordinate < *minX) *minX = xCoordinate; if (yCoordinate < *minY) *minY = yCoordinate; if (xCoordinate > *maxX) *maxX = xCoordinate; if (yCoordinate > *maxY) *maxY = yCoordinate; free(appFileName); } /* clean up */ NXClose(fileStream); free(dockFile); return dockWindowList; } - bitmapFor:(char *)appFileName { id bitmap; char tiffDataBuffer[3000], *tiffDataBufferPtr; int length, flag; NXStream *tiffDataStream; if (!strcmp("Dock", appFileName)) { /* assign the dock window's bitmap */ bitmap = [Bitmap findBitmapFor:"TXeN"]; } else { /* ask the WorkSpace for the app's bitmap */ tiffDataBufferPtr = tiffDataBuffer; [[self appSpeaker] getFileIconFor:appFileName TIFF:&tiffDataBufferPtr TIFFLength:&length ok:&flag]; /* get a stream on memory buffer holding the TIFF data */ tiffDataStream = NXOpenMemory(tiffDataBufferPtr, length, NX_READONLY); bitmap = [Bitmap newFromStream:tiffDataStream]; NXClose(tiffDataStream); } return bitmap; } - newIconWindowFor:bitmap :(int)xCoord :(int)yCoord :(char *)applicationName { NXRect windowRect; id iconWindow, iconView; /* compute the new window's screen location */ windowRect.origin.x = 4.0 + 64.0 * xCoord; windowRect.origin.y = 0.0 + 64.0 * yCoord; windowRect.size.height = windowRect.size.width = 64.0; /* create a new window */ iconWindow = [Window newContent:&windowRect style:NX_PLAINSTYLE backing:NX_BUFFERED buttonMask:0 defer:YES]; /* create an iconView to go in this window */ iconView = [IconView new:applicationName :bitmap :xCoord :yCoord]; /* stick the iconView in the window */ [iconWindow setContentView:iconView]; /* make the view the window's delegate and first responder */ [iconWindow setDelegate:iconView]; [iconWindow makeFirstResponder:iconView]; /* create the PostScript window and stick it in the screen list */ [iconWindow makeKeyAndOrderFront:self]; /* set the window's level in the screen list to be just below menus */ _NXSetWindowLevel([iconWindow windowNum], DOCK_WINDOW_LEVEL); return iconWindow; } - (char *)stringFromStream:(NXStream *)fileStream ok:(int *)success /* reads a newline-terminated string from a stream */ { char stringBuffer[1024]; int nextChar, characterNumber = 0; while ((nextChar = NXGetc(fileStream)) != '\n') { /* make sure we haven't reached the end of the file */ if (nextChar == EOF) { *success = 0; return ""; } stringBuffer[characterNumber++] = (char)nextChar; } stringBuffer[characterNumber] = '\0'; *success = 1; /* create space for the string, copy it, and return the new string */ return mySalloc(stringBuffer); } /* delegation methods */ - appDidInit:sender { id dockWindowList, dockWindow; int minX, minY, maxX, maxY, i; /* we need to use our own special Speaker class object */ [self setAppSpeaker:[DockSpeaker new]]; /* create the dock's windows */ dockWindowList = [self createDockWindows:&minX :&minY :&maxX :&maxY]; /* find the dock window (the one with the backward NeXT) */ i = [dockWindowList count]; while (i--) { dockWindow = [dockWindowList objectAt:i]; if ([[dockWindow contentView] theDock]) { break; } } if ([[dockWindow contentView] theDock]) { /* give the dock window the bounding box of all of the windows */ [[dockWindow contentView] initialize:dockWindowList :minX :minY :maxX :maxY]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.