home *** CD-ROM | disk | FTP | other *** search
- #import <appkit/OpenPanel.h>
- #import <appkit/publicWraps.h>
- #import <appkit/Application.h>
- #import <appkit/Listener.h>
- #import <appkit/NXImage.h>
- #import <appkit/PrintInfo.h>
- #import <appkit/Pasteboard.h>
- #import <stdio.h>
- #import <stdlib.h>
- #import <string.h>
- #import <sys/types.h>
- #import <sys/stat.h>
- #import <sys/file.h>
- #import "TVController.h"
- #import "PrefControl.h"
- #import "ToyWin.h"
- #import "ToyWinPPM.h"
- #import "ToyWinEPS.h"
- #import "ToyWinBMP.h"
- #import "ToyWinGIF.h"
- #import "ToyWinPCD.h"
- #import "DirList.h"
- #import "ADController.h"
- #import "strfunc.h"
- #import "Exttab.h"
- #import "common.h"
-
- TVController *theController = NULL;
-
- @implementation TVController
-
- #define typeNumber 18
-
- /* ToyViewer treats these extensions as pre-defined */
- static const char *const fileType[typeNumber + 1] = {
- "tiff", "tif", "TIFF", "TIF",
- "eps", "EPS",
- "gif", "GIF",
- "bmp", "BMP", "dib", "DIB",
- "ppm", "pgm", "pbm", "pnm",
- "pcd", "PCD",
- NULL };
- static const char fileTypeID[typeNumber] = {
- Type_tiff, Type_tiff, Type_tiff, Type_tiff,
- Type_eps, Type_eps,
- Type_gif, Type_gif,
- Type_bmp, Type_bmp, Type_bmp, Type_bmp,
- Type_ppm, Type_ppm, Type_ppm, Type_ppm,
- Type_pcd, Type_pcd };
- /* extern */ const char **fileTypeBuffer;
- /* extern */ short *fileTypeIDBuffer;
- static char odir[MAXFILENAMELEN]; /* Last Opened Directory */
- static Exttab *extTable;
-
- /* If file has no extension, this func. recognize its file type */
- static int discriminate(const char *fn)
- {
- int maybe = Type_none;
- int cc;
- FILE *fp;
-
- if ((fp = fopen(fn, "r")) == NULL)
- return Type_none;
- switch (cc = getc(fp)) {
- case 0x0a: maybe = Type_pcx; break;
- case '%': maybe = Type_eps; break;
- case 'B': maybe = Type_bmp; break;
- case 'G': maybe = Type_gif; break;
- case 'I': maybe = Type_tiff; break;
- case 'M': maybe = Type_mag; break;
- case 'P': maybe = Type_ppm; break;
- case 0x89: maybe = Type_png; break;
- case 0xff:
- if (getc(fp) == 0xd8)
- maybe = Type_jpg;
- break;
- default: break;
- }
- fclose(fp);
- return maybe;
- }
-
-
- - appDidInit:sender
- {
- int i, j, n;
- char buf[MAXFILENAMELEN], *p, **q;
- NXCoord lmg, rmg, tmg, bmg;
- const char *sendTypes[3];
- const char *returnTypes[3];
- const char *const *types = [NXImage imageFileTypes];
-
- // [preference init];
- if (thePreference == NULL) thePreference = preference;
- theController = self;
-
- extTable = [[Exttab alloc] init];
- n = dircopy(buf, NXArgv[0], YES);
- strcpy(&buf[n], toyviewerTAB);
- [extTable readExtData: buf];
- p = getenv("HOME");
- sprintf(buf, "%s/%s", p, toyviewerRC);
- [extTable readExtData: buf];
- sprintf(buf, "%s/Library/ToyViewer/rc.%s", p, __ARCHITECTURE__);
- [extTable readExtData: buf];
- n = [extTable entry];
-
- for (i = 0; types[i]; i++) ;
- n += i + typeNumber + 1;
- fileTypeBuffer = (const char **)malloc(sizeof(char *const *) * n);
- fileTypeIDBuffer = (short *)malloc(sizeof(short) * n);
- i = 0;
- if ((q = [extTable table]) != NULL)
- for (j = 0; q[j]; j++) {
- fileTypeBuffer[i] = q[j];
- fileTypeIDBuffer[i++] = Type_user;
- }
- for (j = 0; fileType[j]; j++) {
- fileTypeBuffer[i] = fileType[j];
- fileTypeIDBuffer[i++] = fileTypeID[j];
- }
- for (j = 0; types[j]; j++) {
- fileTypeBuffer[i] = types[j];
- fileTypeIDBuffer[i++] = Type_other;
- }
- fileTypeBuffer[i] = NULL;
- [DirList setExtList: fileTypeBuffer];
-
- if ([thePreference isUpdatedServices])
- NXUpdateDynamicServices(); // service re-providing
- [[NXApp appListener] setServicesDelegate: self];
- sendTypes[0] = NULL;
- returnTypes[0] = NXPostScriptPboardType;
- returnTypes[1] = NXTIFFPboardType;
- returnTypes[2] = NULL;
- [NXApp registerServicesMenuSendTypes:sendTypes
- andReturnTypes:returnTypes];
-
- printInfo = [NXApp printInfo];
- [printInfo setOrientation:NX_LANDSCAPE andAdjust:YES];
- [printInfo getMarginLeft:&lmg right:&rmg top:&tmg bottom:&bmg];
- lmg = (lmg + rmg) * 0.3;
- tmg = (tmg + bmg) * 0.3;
- [printInfo setMarginLeft:lmg right:lmg top:tmg bottom:tmg];
-
- [self initWallpaper];
- return self;
- }
-
- - (int)getFTypeID: (const char *)aType
- {
- int i;
-
- if (aType && *aType) {
- for (i = 0; fileTypeBuffer[i]; i++)
- if (strcmp(aType, fileTypeBuffer[i]) == 0)
- return fileTypeIDBuffer[i];
- }
- return Type_none;
- }
-
-
- /* Local Method */
- - allocWinFromFile: (const char *)fn :(const char *)aType
- type:(int *)ftype display:(BOOL)display
- /* Return Value: nil: Error, id: New ToyWin */
- {
- id twtmp = nil;
- int itype = Type_none;
- const char *key = NULL;
-
- itype = [self getFTypeID: aType];
- if (itype == Type_none) { /* Unknown Extension */
- if ((itype = discriminate(fn)) == Type_none)
- return nil;
- key = NULL;
- }else
- key = aType;
-
- if (viaPipe(itype)) { /* Type_user and ... */
- if (key == NULL)
- switch (itype) {
- case Type_pcx: key = "pcx"; break;
- case Type_mag: key = "mag"; break;
- case Type_jpg: key = "jpg"; break;
- case Type_xbm: key = "xbm"; break;
- case Type_jbg: key = "bie"; break;
- case Type_png: key = "png"; break;
- }
- twtmp = [ToyWinPPM alloc];
- if (display) [twtmp init:nil by:0];
- else [twtmp initMapOnly];
- [twtmp setExecList:
- [extTable execListAlloc: key with: fn] ext: key];
- }else if (itype == Type_pcd) {
- twtmp = [ToyWinPCD alloc];
- if (display) [twtmp init:nil by:0];
- else [twtmp initMapOnly];
- [twtmp setting];
- }else {
- switch (itype) {
- case Type_bmp:
- twtmp = [ToyWinBMP alloc]; break;
- case Type_gif:
- twtmp = [ToyWinGIF alloc]; break;
- case Type_eps:
- twtmp = [ToyWinEPS alloc];
- display = YES;
- break;
- case Type_ppm:
- twtmp = [ToyWinPPM alloc]; break;
- case Type_tiff:
- case Type_other:
- default:
- twtmp = [ToyWin alloc];
- display = YES;
- break;
- }
- if (display) [twtmp init:nil by:0];
- else [twtmp initMapOnly];
- }
- *ftype = itype;
- return twtmp; // return New ToyWin
- }
-
- - drawFile: (const char *)fn :(const char *)aType
- /* Return Value: nil: Error, id: New ToyWin */
- {
- unsigned char *map[MAXPLANE];
- id newtw;
- commonInfo *cinf;
- int itype, err = 0;
-
- newtw = [self allocWinFromFile:fn : aType type:&itype display:YES];
- if (!newtw)
- return nil;
- cinf = [newtw drawToyWin:(const char *)fn type:itype map:map err:&err];
- if (cinf == NULL && err) {
- if (err > 0) errAlert(fn, err);
- [newtw free];
- return nil;
- }
- [self newWindow: newtw];
- return newtw;
- }
-
- /* Local Method */
- /* This method is NOT used for EPS and TIFF */
- - (NXBitmapImageRep *)imageFromFile: (const char *)fn :(const char *)aType map:(unsigned char **)map
- {
- id newtw;
- commonInfo *cinf;
- NXBitmapImageRep *img;
- int itype, err = 0, spp;
-
- map[0] = NULL;
- newtw = [self allocWinFromFile:fn : aType type:&itype display:NO];
- if (!newtw)
- return NULL;
- cinf = [newtw drawToyWin:(const char *)fn type:itype map:map err:&err];
- if (cinf == NULL && err) {
- if (err > 0) errAlert(fn, err);
- [newtw free];
- return NULL;
- }
-
- if ((img = [NXBitmapImageRep alloc]) != NULL) {
- spp = cinf->numcolors;
- if (cinf->alpha) spp++;
- [img initDataPlanes: map pixelsWide: cinf->width
- pixelsHigh: cinf->height bitsPerSample: cinf->bits
- samplesPerPixel: spp hasAlpha: cinf->alpha
- isPlanar: YES colorSpace: cinf->cspace
- bytesPerRow: cinf->xbytes
- bitsPerPixel: cinf->bits];
- }
- [newtw free];
- if (cinf->palette)
- free((void *)cinf->palette);
- free((void *)cinf);
- /* An instance of ToyWin initialized by "initMapOnly"
- does not have instances of ToyView in it.
- So, "cinf" must be freed here. */
- return img;
- }
-
- /* Get stream from file without actual window.
- This method is used to provide Pasteboard-Services and Initial Wallpaper.
- */
- - (NXStream *)openStreamFromFile: (const char *)fn :(const char *)aType
- {
- unsigned char *map[MAXPLANE];
- NXBitmapImageRep *img;
- NXStream *pbStream = NULL;
- ToyWinEPS *tweps;
- int itype, err;
-
- if ((pbStream = NXOpenMemory(NULL, 0, NX_READWRITE)) == NULL)
- return NULL;
-
- itype = [self getFTypeID: aType];
- if (itype == Type_eps) {
- tweps = [[ToyWinEPS alloc] initMapOnly];
- pbStream = [tweps openStreamFromFile:fn err:&err];
- [tweps free];
- if (pbStream == NULL && err > 0) {
- errAlert(fn, err);
- if (pbStream)
- NXCloseMemory(pbStream, NX_FREEBUFFER);
- return NULL;
- }
- return pbStream;
- }
- map[0] = NULL;
- img = (itype == Type_tiff)
- ? [[NXBitmapImageRep alloc] initFromFile: fn]
- : [self imageFromFile: fn : aType map: map];
- if (img) {
- [img writeTIFF: pbStream];
- NXSeek(pbStream, 0L, NX_FROMSTART);
- [img free];
- }else {
- NXCloseMemory(pbStream, NX_FREEBUFFER);
- pbStream = NULL;
- }
- if (map[0])
- free((void *)map[0]);
- return pbStream;
- }
-
- - openFile:sender
- {
- char fn[MAXFILENAMELEN];
- id openPanel;
-
- if (!odir[0])
- strcpy(odir, getenv("HOME"));
- openPanel = [OpenPanel new];
- [[openPanel chooseDirectories: NO] allowMultipleFiles:YES];
- if ([openPanel runModalForDirectory:odir
- file:NULL types:fileTypeBuffer]) {
- const char *const *files = [openPanel filenames];
- strcpy(odir, [openPanel directory]);
- for ( ; files && *files; files++) {
- sprintf(fn, "%s/%s", odir, *files);
- if (! [self isOpened: fn]) {
- int j;
- if ((j = getExtension(fn)) == 0)
- return self; /* No Extension */
- [self drawFile: fn : &fn[j]];
- }
- }
- }
- return self;
- }
-
- #define AutoThreshold 4
-
- /* Local Method */
- - openDirectory: (const char *)dir
- {
- char fn[MAXFILENAMELEN];
- const char *p;
- int n, i;
- id dirlist;
- static id autoDisplayCtr = nil;
-
- dirlist = [[DirList alloc] init];
- n = [dirlist getDirList: dir];
- if (n <= 0) {
- errAlert(dir, Err_NOFILE);
- [dirlist free];
- }else if (n < AutoThreshold) {
- for (i = 0; i < n; i++) {
- p = [dirlist filenameAt: i];
- sprintf(fn, "%s/%s", dir, p);
- if (! [self isOpened: fn]) {
- int j = getExtension(p);
- (void)[self drawFile: fn : &p[j]];
- }
- }
- [dirlist free];
- }else { /* Auto Display */
- char bdir[MAXFILENAMELEN];
- id bundle, ad;
- if (autoDisplayCtr == nil) {
- n = dircopy(bdir, NXArgv[0], YES);
- strcpy(&bdir[n], "ADController.bundle");
- bundle = [[NXBundle alloc] initForDirectory: bdir];
- if (bundle == nil) /* ERROR */
- return nil;
- autoDisplayCtr = [bundle classNamed:"ADController"];
- if (autoDisplayCtr == nil) /* ERROR */
- return nil;
- }
- ad = [autoDisplayCtr alloc];
- [ad init:self dir:dir with:dirlist];
- }
-
- return self;
- }
-
- - autoDisplay:sender
- {
- char fn[MAXFILENAMELEN];
- id openPanel;
- const char *const *files;
-
- if (!odir[0])
- strcpy(odir, getenv("HOME"));
- openPanel = [OpenPanel new];
- [[openPanel chooseDirectories: YES] allowMultipleFiles:NO];
- if (![openPanel runModalForDirectory:odir file:NULL])
- return self;
-
- files = [openPanel filenames];
- strcpy(odir, [openPanel directory]);
- sprintf(fn, "%s/%s", odir, *files);
- [self openDirectory: fn];
- return self;
- }
-
-
- - readSelectionFromPasteboard:pb
- {
- const NXAtom *cont;
- NXStream *st;
- id twtmp = nil;
- char *ext, fn[256];
- int err;
- static int untitledCount = 0;
-
- ext = NULL;
- for (cont = [pb types]; cont && *cont; cont++) {
- if (*cont == NXTIFFPboardType) {
- twtmp = [[ToyWin alloc] init:nil by:0];
- ext = "tiff";
- break;
- }
- if (*cont == NXPostScriptPboardType) {
- twtmp = [[ToyWinEPS alloc] init:nil by:0];
- ext = "eps";
- break;
- }
- }
- if (ext == NULL) {
- NXBeep();
- return self;
- }
- st = [pb readTypeToStream: *cont];
- sprintf(fn, "%s/Untitled%d.%s", getenv("HOME"), ++untitledCount, ext);
-
- err = [twtmp drawFromFile:(const char *)fn or:st];
- if (err == 0)
- [self newWindow: twtmp];
- else {
- if (err > 0)
- errAlert(fn, err);
- [twtmp free];
- }
- NXCloseMemory(st, NX_FREEBUFFER);
- return self;
- }
-
- - openPasteBoard:sender
- {
- Pasteboard *pb = [Pasteboard new]; // don't free it
- return [self readSelectionFromPasteboard:pb];
- }
-
- - (int)app:sender openFile:(const char *)fn type:(const char *)aType
- {
- struct stat buf;
- int mode;
- id res = nil;
-
- if (printInfo == nil)
- [self appDidInit:sender];
- if (stat((char *)fn, &buf) != 0) return NO;
- mode = (buf.st_mode & S_IFMT);
- if (mode == S_IFDIR) {
- if (access(fn, X_OK) != 0) return NO;
- res = [self openDirectory: fn];
- }else {
- if ([self isOpened: fn]) return YES;
- res = [self drawFile: fn : aType];
- }
- return (res != nil);
- }
-
- - (BOOL)appAcceptsAnotherFile:sender
- {
- return YES;
- }
-
- - messageDisplay:(const char *)msg
- {
- if (msg) {
- [messagePanel makeKeyAndOrderFront: self];
- [messageText setStringValue: msg];
- [messagePanel setFloatingPanel: YES];
- NXPing();
- }else {
- [messagePanel setFloatingPanel: NO];
- [messagePanel close];
- }
- return messageText;
- }
-
- - validRequestorForSendType:(NXAtom)typeSent
- andReturnType:(NXAtom)typeReturned
- {
- if (typeReturned == NXPostScriptPboardType
- || typeReturned == NXTIFFPboardType)
- return self;
- return nil;
- }
-
- @end
-