home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Utilities / Fiend-1.4.1-src / IconView.m < prev    next >
Encoding:
Text File  |  1995-12-01  |  23.5 KB  |  1,099 lines

  1. #import <mach/mach.h>
  2. #import <sys/types.h>
  3. #import <bsd/sys/file.h>
  4. #import <appkit/appkit.h>
  5. #import <dpsclient/dpsclient.h>
  6. #import <appkit/workspaceRequest.h>
  7.  
  8. #import "table.h"
  9. #import "Fiend.h"
  10. #import "IconView.h"
  11. #import "ShelfView.h"
  12. #import "Controller.h"
  13. #import "FiendWraps.h"
  14.  
  15. @interface Application(CtxtNum)
  16. - (int)contextNum;
  17. @end
  18.  
  19. @implementation NXImage(UsefulMethod)
  20. - (NXSize)scaleToFitInside:(NXSize)size max:(NXSize)maxSize
  21.                      onDock:(BOOL)dockFlag isApp:(BOOL)isApp
  22. {
  23.     NXSize    imageSize;
  24.     float    scale;
  25.  
  26.     [self getSize:&imageSize];
  27.  
  28.     scale = MIN(size.width/imageSize.width, size.height/imageSize.height);
  29.     scale *= (isApp && dockFlag) ? 0.98 : 0.98;
  30.  
  31.     size.width = floor(scale * imageSize.width);
  32.     size.height = floor(scale * imageSize.height);
  33.     if (size.width > maxSize.width)
  34.         size.width = maxSize.width;
  35.     if (size.height > maxSize.height)
  36.         size.height = maxSize.height;
  37.  
  38.     [self setSize:&size];
  39.     return size;
  40. }
  41. @end
  42.  
  43.  
  44. @implementation IconView : View
  45.  
  46. static id    processTable;
  47. static id    pidIconTable;
  48. static id    pidCtxtTable;
  49. static id    scaledDockHilite;
  50. static id    scaledShelfHilite;
  51. static id    scaledShelfAppHilite;
  52. static id    scaledShelfAppTile;
  53. static id    scaledAppTile;
  54. static id    scaledDotsTile;
  55. static id    scaledKill;
  56. static DPSContext theContext;
  57.  
  58. + resetCachedShelfImages
  59. {
  60.     NXZone    *theZone = [[NXApp delegate] shelfZone];
  61.     if (scaledShelfHilite == nil)    {
  62.         scaledShelfHilite = [[[NXImage allocFromZone:theZone] initFromSection:"hilite"] setScalable:YES];
  63.         scaledShelfAppHilite = scaledShelfHilite;
  64.         scaledShelfAppTile = [[[NXImage findImageNamed:"NXAppTile"] copyFromZone:theZone] setScalable:YES];
  65.     }
  66.     [scaledShelfAppTile free];
  67.     scaledShelfAppTile = [[[NXImage findImageNamed:"NXAppTile"] copyFromZone:theZone] setScalable:YES];
  68.  
  69.     return self;
  70. }
  71.  
  72. + resetCachedDockImages
  73. {
  74.     NXZone    *theZone = [[NXApp delegate] dockZone];
  75.     if (scaledAppTile == nil)    {
  76.         scaledKill = [[[NXImage allocFromZone:theZone] initFromSection:"kill"] setScalable:YES];
  77.         scaledDotsTile = [[[NXImage allocFromZone:theZone] initFromSection:"dots"] setScalable:YES];
  78.         scaledDockHilite = [[[NXImage allocFromZone:theZone] initFromSection:"hilite"] setScalable:YES];
  79.         scaledAppTile = [[[NXImage findImageNamed:"NXAppTile"] copyFromZone:theZone] setScalable:YES];
  80.     }
  81.  
  82.     [scaledKill recache];
  83.     [scaledDotsTile recache];
  84.     [scaledDockHilite recache];
  85.     [scaledAppTile free];
  86.     scaledAppTile = [[[NXImage findImageNamed:"NXAppTile"] copyFromZone:theZone] setScalable:YES];
  87.  
  88.     return self;
  89. }
  90.  
  91. + setCachedDockImageSize:(NXSize *)aSize
  92. {
  93.     NXSize killSize = {0.75*aSize->width, 0.75*aSize->height};
  94.  
  95.     [scaledKill setSize:&killSize];
  96.     [scaledAppTile setSize:aSize];
  97.     [scaledDotsTile setSize:aSize];
  98.     [scaledDockHilite scaleToFitInside:*aSize max:*aSize onDock:YES isApp:NO];
  99.     return self;
  100. }
  101.  
  102. + shelfHilite
  103. {
  104.     return scaledShelfHilite;
  105. }
  106.  
  107. + dockHilite
  108. {
  109.     return scaledDockHilite;
  110. }
  111.  
  112. + shelfAppHilite
  113. {
  114.     return scaledShelfAppHilite;
  115. }
  116.  
  117.  
  118. + getImageForPath:(const char *)path fileIcon:(BOOL)flag zone:(NXZone *)aZone
  119. {
  120.     id            tImage;
  121.     id            newImage = nil;
  122.     struct stat    buf;
  123.     const char *const *typeArray = [NXImage imageFileTypes];
  124.  
  125. //    if (strstr(path, RECYC_FILE))
  126. //        newImage = [[NXImage allocFromZone:aZone] initFromFile:"trash.1.alpha.tiff"];
  127. //    else 
  128.  
  129.     if (!strcmp("/", path))
  130.         newImage = [[NXImage allocFromZone:aZone] initFromFile:"/.dir.tiff"];
  131.  
  132.     if (!newImage && !flag && !stat(path, &buf))    {
  133.         char    *pos = strrchr(path, '.');
  134.         newImage = nil;
  135.         if (pos)    {
  136.             if (!strcmp(pos+1, "tiff"))
  137.                     newImage = [[NXImage allocFromZone:aZone] initFromFile:path];
  138.             else    {
  139.                 do    {
  140.                     if (!strcmp(pos+1, *typeArray++))    {
  141.                         newImage = [[NXImage allocFromZone:aZone] initFromFile:path];
  142.                         break;
  143.                     }
  144.                 }    while (*typeArray != NULL);
  145.             }
  146.         }
  147.     }
  148.  
  149.     if (newImage != nil)    {
  150.         if ([newImage lockFocus])    {
  151.             [newImage unlockFocus];
  152.             return newImage;
  153.         }
  154.         [newImage free];
  155.         newImage = nil;
  156.     }
  157.  
  158.     if (newImage == nil)    {
  159.         tImage = [[Application workspace] getIconForFile:path];
  160.         newImage = [tImage copyFromZone:aZone];
  161.         [tImage free];
  162.     }
  163.  
  164.     [newImage setScalable:YES];
  165.  
  166.     return newImage;
  167. }
  168.  
  169. + processTable
  170. {
  171.     return processTable;
  172. }
  173.  
  174. + getExecPath:(char *)execPath from:(const char *)theAppName
  175. {
  176.     char    *appFileName = strrchr(theAppName, '/');
  177.  
  178.     if (!execPath || !theAppName)
  179.         return self;
  180.  
  181.     execPath[0] = '\0';
  182.  
  183.     if (!appFileName)    {
  184.         strcpy(execPath, theAppName);
  185.         return self;
  186.     }
  187.     else
  188.         appFileName++;
  189.  
  190.     if (!strcmp(appFileName+strlen(appFileName)-4, ".app"))    {
  191.         sprintf(execPath, "%s/%s", theAppName, appFileName);
  192.         execPath[strlen(execPath)-4] = '\0';
  193.     }
  194.     else if  (!strcmp(appFileName+strlen(appFileName)-6, ".debug"))    {
  195.         sprintf(execPath, "%s/%s", theAppName, appFileName);
  196.         execPath[strlen(execPath)-6] = '\0';
  197.     }
  198.     else if  (!strcmp(appFileName+strlen(appFileName)-8, ".profile"))    {
  199.         sprintf(execPath, "%s/%s", theAppName, appFileName);
  200.         execPath[strlen(execPath)-8] = '\0';
  201.     }
  202.     else
  203.         sprintf(execPath, "%s", theAppName);
  204.     return self;
  205. }
  206.  
  207.  
  208. + getShortName:(char *)shortName from:(const char *)theAppName
  209. {
  210.     char    *appFileName;
  211.  
  212.     if (!shortName || !theAppName)
  213.         return self;
  214.  
  215.     shortName[0] = '\0';
  216.     appFileName = strrchr(theAppName, '/');
  217.  
  218.     if (!appFileName)    {
  219.         strcpy(shortName, theAppName);
  220.         return self;
  221.     }
  222.     else
  223.         appFileName++;
  224.  
  225.     if (!strcmp(appFileName+strlen(appFileName)-4, ".app"))    {
  226.         strncpy(shortName, appFileName, strlen(appFileName)-4);
  227.         shortName[strlen(appFileName)-4] = '\0';
  228.     }
  229.     else if (!strcmp(appFileName+strlen(appFileName)-6, ".debug"))    {
  230.         strncpy(shortName, appFileName, strlen(appFileName)-6);
  231.         shortName[strlen(appFileName)-6] = '\0';
  232.     }
  233.     else if (!strcmp(appFileName+strlen(appFileName)-8, ".profile"))    {
  234.         strncpy(shortName, appFileName, strlen(appFileName)-8);
  235.         shortName[strlen(appFileName)-8] = '\0';
  236.     }
  237.     else
  238.         strcpy(shortName, appFileName);
  239.     shortName[16] = '\0';
  240.     return self;
  241. }
  242.  
  243. static int
  244. safeGetCtxtIconAndPid(int context, int *icon, int *pid)
  245. {
  246.     int        status = 0;
  247.  
  248.     if (context < 0) return -1;
  249.  
  250.     NX_DURING
  251.         PSWGetCtxtIconAndPid(context, icon, pid);
  252.         NXPing();
  253.     NX_HANDLER
  254.         NXReportError(&NXLocalHandler);
  255.         switch (NXLocalHandler.code) {
  256.           case dps_err_ps:
  257.             status = -1;
  258.             break;
  259.           default:
  260.             NX_RERAISE();
  261.         }
  262.     NX_ENDHANDLER
  263.     return status;
  264. }
  265.  
  266. static int
  267. safeGetWindowList(int count, int *windows)
  268. {
  269.     if (!windows) return -1;
  270.  
  271.     NX_DURING
  272.         PSwindowlist(0, count, windows);
  273.         NXPing();
  274.     NX_HANDLER
  275.         NXReportError(&NXLocalHandler);
  276.            switch (NXLocalHandler.code) {
  277.           case dps_err_ps:
  278.             PScountwindowlist(0, &count);
  279.             break;
  280.           default:
  281.             NX_RERAISE();
  282.            }
  283.     NX_ENDHANDLER
  284.     return count;
  285. }
  286.  
  287. static int
  288. safeGetCurrrentOwner(int windowNum, int *owner)
  289. {
  290.     int        status = 0;
  291.  
  292.     if (windowNum <= 0) return -1;
  293.  
  294.     NX_DURING
  295.         PSWGetCurrentOwner(windowNum, owner);
  296.         NXPing();
  297.     NX_HANDLER
  298.         NXReportError(&NXLocalHandler);
  299.         switch (NXLocalHandler.code) {
  300.           case dps_err_ps:
  301.             status = -1;
  302.             break;
  303.           default:
  304.             NX_RERAISE();
  305.         }
  306.     NX_ENDHANDLER
  307.     return status; 
  308. }
  309.  
  310. + resetProcessTable
  311. {
  312.     int            i;
  313.     int            pid;
  314.     int            icon;
  315.     int            count;
  316.     int            owner;
  317.     int            *windows;
  318.     struct tbl_procinfo pi;
  319.     int            table();
  320.     NXZone        *theZone = [[NXApp delegate] dockZone];
  321.  
  322.     if (processTable == nil)    {
  323.         theContext = DPSGetCurrentContext();
  324.         processTable = [[HashTable allocFromZone:theZone] initKeyDesc:"%" valueDesc:"i"];
  325.         pidIconTable = [[HashTable allocFromZone:theZone] initKeyDesc:"i" valueDesc:"i"];
  326.         pidCtxtTable = [[HashTable allocFromZone:theZone] initKeyDesc:"i" valueDesc:"i"];
  327.     }
  328.     else    {
  329.         [pidIconTable empty];
  330.         [pidCtxtTable empty];
  331.         [processTable empty];
  332.     }
  333.  
  334.     PScountwindowlist(0, &count);
  335.     windows = (int *)NXZoneMalloc(theZone, count*sizeof(int)+20);
  336.     PScountwindowlist(0, &count);
  337.     count = safeGetWindowList(count, windows);
  338.     for(i = 0; i < count; i++)    {
  339.         if (safeGetCurrrentOwner(windows[i], &owner) < 0)
  340.             continue;
  341.         DPSTraceContext(theContext, NO);
  342.         if (safeGetCtxtIconAndPid(owner, &icon, &pid) < 0)
  343.             continue;
  344.         if (![pidIconTable isKey:(const void *)pid])    {
  345.             [pidIconTable insertKey:(const void *)pid value:(void *)icon];
  346.             [pidCtxtTable insertKey:(const void *)pid value:(void *)owner];
  347.             if ((int)table(TBL_PROCINFO, pid, (char *)&pi, 1, sizeof pi) == 1 && pi.pi_status==PI_ACTIVE)    {
  348.                 [processTable insertKey:(const void *)NXUniqueString(pi.pi_comm) value:(void *)pid];
  349.             }
  350.         }
  351.     }
  352.     NXZoneFree(theZone, windows);
  353.     return self;
  354. }
  355.  
  356.  
  357. + (int)getLastPidFor:(char *)aName
  358. {
  359.     int        pid;
  360.     NXAtom    atom = NXUniqueString(aName);
  361.  
  362.     if ([processTable isKey:atom])    {
  363.         pid = (int)[processTable valueForKey:atom];
  364.         return pid;
  365.     }
  366.     else
  367.         return -1;
  368. }
  369.  
  370. + (int)getIconForPid:(int)pid
  371. {
  372.     if ([pidIconTable isKey:(const void *)pid])
  373.         return (int)[pidIconTable valueForKey:(const void *)pid];
  374.     else
  375.         return -1;
  376. }
  377.  
  378. + (int)getCtxtForPid:(int)pid
  379. {
  380.     if ([pidCtxtTable isKey:(const void *)pid])
  381.         return (int)[pidCtxtTable valueForKey:(const void *)pid];
  382.     else
  383.         return -1;
  384. }
  385.  
  386. + getCtxt:(int *)ctxt pid:(int *)pid andIcon:(int *)icon forPath:(char *)path
  387. {
  388.     char    shortName[MAXPATHLEN+1];
  389.  
  390.     if (!IS_APP_PATH(path))    {
  391.         *icon = *ctxt = -1;
  392.         return self;
  393.     }
  394.  
  395.     [IconView getShortName:shortName from:path];
  396.     if ((*pid = [IconView getLastPidFor:shortName]) != -1)  {
  397.         *icon = (int)[pidIconTable valueForKey:(const void *)*pid];
  398.         *ctxt = (int)[pidCtxtTable valueForKey:(const void *)*pid];
  399.     }
  400.     else
  401.         *icon = *ctxt = -1;
  402.     
  403.     return self;
  404. }
  405.  
  406.  
  407. + (BOOL)pidExists:(int)testPid
  408. {
  409.     const int    value;
  410.     const void    *key;
  411.     NXHashState    state = [processTable initState];
  412.  
  413.     while ([processTable nextState:&state key:&key value:(void *)&value])    {
  414.         if (testPid == value)
  415.             return YES;
  416.     }
  417.     return NO;
  418. }
  419.  
  420. + copyIconView:aView
  421. {
  422.     NXRect        aFrame;
  423.     void        *oldData;
  424.     unsigned int    len;
  425.  
  426.     [aView getFrame:&aFrame];
  427.     [aView getData:&oldData andLength:&len];
  428.  
  429.     return [[self allocFromZone:[aView zone]] initFrame:&aFrame
  430.             image:[[aView image] copyFromZone:[aView zone]]
  431.             data:oldData andLength:len
  432.             useSize:YES onDock:NO];
  433. }
  434.  
  435. - initFrame:(const NXRect *) newFrame image:anImage    data:(const void *) someData
  436.   andLength:(unsigned int) newLength useSize:(BOOL) sizeValid onDock:(BOOL)dockFlag;
  437. {
  438.     id            hilite;
  439.     char        hostname[40];
  440.     struct stat    buf;
  441.     NXSize        imageSize = {400, 400};
  442.  
  443.     [NXApp getScreenSize:&screenSize];
  444.  
  445.     if (newLength > 0 && *((char *)someData + newLength - 1))
  446.         length = newLength + 1;
  447.     else
  448.         length = newLength;
  449.  
  450.     data = (char **)NXZoneMalloc([self zone], length+1);
  451.     bcopy(someData, data, length+1);
  452.  
  453.     ghost = NO;
  454.     sticky = NO;
  455.     autoScan = NO;
  456.     selected = NO;
  457.     isLaunched = NO;
  458.     onDock = dockFlag;
  459.  
  460.     isApp = IS_APP_PATH(data);
  461.     statReturn = stat(data, &buf);
  462.  
  463.     if (isApp && onDock)
  464.         [self getAppPid];
  465.     if (isLaunched)
  466.         [self getScreenStatus];
  467.  
  468.     shelfHilite = [IconView shelfHilite];
  469.     dockHilite = [IconView dockHilite];
  470.     shelfAppHilite = [IconView shelfAppHilite];
  471.     hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite);
  472.  
  473.     hiliteMax.width = 400;
  474.     hiliteMax.height = 400;
  475.  
  476.     image = anImage;
  477.     imageMax = imageSize;
  478.     tempImage = [[NXImage allocFromZone:[self zone]] init];
  479.  
  480.     [self setClipping:NO];
  481.     if (!isApp || !onDock)    {
  482.         titleCell = [[TextFieldCell allocFromZone:[self zone]] init];
  483.         [titleCell setAlignment:NX_CENTERED];
  484.         [titleCell setBackgroundTransparent:YES];
  485.  
  486.         if (!strcmp(data, "/"))    {
  487.             gethostname(hostname, 39);
  488.             [titleCell setStringValue:hostname];
  489.         }
  490.         else if (rindex(data, '/'))
  491.             [titleCell setStringValue:rindex(data, '/') + 1];
  492.         else
  493.             [titleCell setStringValue:data];
  494.     }
  495.  
  496.     if (!sizeValid) {
  497.         NXSize    titleSize = {0.0, 0.0};
  498.         NXRect    aRect = {{0, 0}, {0, 0}};
  499.  
  500.         [hilite getSize:&imageSize];
  501.         if (!isApp || !onDock)
  502.             [titleCell calcCellSize:&titleSize];
  503.  
  504.         if (newFrame)
  505.             aRect.origin = newFrame->origin;
  506.         aRect.size.height = imageSize.height + titleSize.height;
  507.         aRect.size.width = MAX(titleSize.width, imageSize.width);
  508.         [super initFrame:&aRect];
  509.     }
  510.     else
  511.         [super initFrame:newFrame];
  512.  
  513.     [self setImageSize];
  514.     [self getImagePoint:&imagePoint andHilitePoint:&hilitePoint];
  515.  
  516.     return self;
  517. }
  518.  
  519. - initFromDragContext:(id <NXDraggingInfo>)context andSize:(NXSize *)aSize onDock:(BOOL)dockFlag;
  520. {
  521.     char            *pbData;
  522.     unsigned int    len;
  523.     NXImage            *copiedImage = [context draggedImageCopy];
  524.     Pasteboard        *pb = [Pasteboard newName:NXDragPboard];
  525.     NXRect            aRect = {{0, 0}, {0, 0}};
  526.     NXRect            *rectPtr = NULL;
  527.  
  528.     [pb types];
  529.     [pb readType:NXFilenamePboardType data:&pbData length:&len];
  530.  
  531.     if (aSize != NULL) {
  532.         rectPtr = &aRect;
  533.         aRect.size = *aSize;
  534.     }
  535.  
  536.     [self initFrame:rectPtr image:copiedImage data:pbData andLength:len+1
  537.      useSize:aSize != NULL onDock:dockFlag];
  538.  
  539.     [pb deallocatePasteboardData:pbData length:len];
  540.     [self display];
  541.  
  542.     return self;
  543. }
  544.  
  545.  
  546. - free
  547. {
  548.     NXZoneFree([self zone], data);
  549.     [image free];
  550.     [tempImage free];
  551.     if (!isApp || !onDock)
  552.         [titleCell free];
  553.     return [super free];
  554. }
  555.  
  556. - getAppPid
  557. {
  558.     char    shortName[MAXPATHLEN+1];
  559.  
  560.     if (!isApp)    {
  561.         appIcon = appCtxt = -1;
  562.         return self;
  563.     }
  564.  
  565.     [IconView getShortName:shortName from:(const char *)data];
  566.     isLaunched = ((appPid = [IconView getLastPidFor:shortName]) != -1);
  567.     if (isLaunched)    {
  568.         appIcon = (int)[pidIconTable valueForKey:(const void *)appPid];
  569.         appCtxt = (int)[pidCtxtTable valueForKey:(const void *)appPid];
  570.     }
  571.     else
  572.         appIcon = appCtxt = -1;
  573.     
  574.     return self;
  575. }
  576.  
  577. BOOL
  578. onNeXTDock(const char *aPath, int height)
  579. {
  580.     char    string[100];
  581.     const     char    *defValue;
  582.     BOOL    answer = NO;
  583.  
  584.     if (height != ORIG_SCREEN_HEIGHT)    {
  585.         sprintf(string, "DockPathsForHt%d", height);
  586.         defValue = NXGetDefaultValue("Workspace", string);
  587.         if (defValue)
  588.             answer = (strstr(defValue, (char *)aPath) != (char *)NULL);
  589.     }
  590.     else    {
  591.         defValue = NXGetDefaultValue("Workspace", "DockPaths");
  592.         if (defValue)
  593.             answer = (strstr(defValue, (char *)aPath) != (char *)NULL);
  594.     }
  595.     return answer;
  596. }
  597.  
  598. - unvanishIcon
  599. {
  600. //    BOOL        hideIcons = !strcmp(NXGetDefaultValue([NXApp appName], HIDE_ICONS), "YES");
  601.  
  602.     if (appIcon <= 0 || onNeXTDock(data, (int)screenSize.height) || appCtxt == [NXApp contextNum])
  603.         return nil;
  604.     PSWReplaceIcon(appIcon, (int)(screenSize.width)-64);
  605.     return self;
  606. }
  607.  
  608.  
  609. - vanishIcon
  610. {
  611.     if (appIcon <= 0 || onNeXTDock(data, (int)screenSize.height))
  612.         return nil;
  613.     PSWMove(-1000.0, -1000.0, appIcon);
  614.     return self;
  615. }
  616.  
  617.  
  618. static int
  619. safeCopyWindow(float x, float y, float w, float h, int windowNum)
  620. {
  621.     if (windowNum <= 0) return -1;
  622.  
  623.     NX_DURING
  624.         PSWCopyWindow(0.0, 0.0, 64.0, 64.0, windowNum);
  625.         NXPing();
  626.     NX_HANDLER
  627.         NXReportError(&NXLocalHandler);
  628.         switch(NXLocalHandler.code)    {
  629.           case dps_err_ps:
  630.             NXLogError("PS error in safeCopyWindow: %.0f %.0f %.0f %.0f %d",
  631.                        x, y, w, h, windowNum);
  632.             windowNum = -1;
  633.             break;
  634.           default:
  635.             NX_RERAISE();
  636.         }
  637.     NX_ENDHANDLER
  638.     return windowNum;
  639. }
  640.  
  641. - refreshIcon
  642. {
  643.     NXSize    iconSize = {64.0, 64.0};
  644.     BOOL    showCues = !strcmp(NXGetDefaultValue([NXApp appName], SHOW_CUES), "YES");
  645.     float    scanTime = atof(NXGetDefaultValue([NXApp appName], "ScanTime"));
  646.  
  647.     if (!ghost && !selected && appIcon >= 0 && autoScan && isLaunched && scanTime > 0.0)    {
  648.         [image setSize:&iconSize];
  649.  
  650.         [image lockFocus];
  651.         appIcon = safeCopyWindow(0.0, 0.0, 64.0, 64.0, appIcon);
  652.         [image unlockFocus];
  653.         if (appIcon == -1)
  654.             return nil;
  655.  
  656.         if (NX_WIDTH(&frame) != 64.0 || NX_HEIGHT(&frame) != 64.0)
  657.             [image setSize:&bounds.size];
  658.         [self lockFocus];
  659.         [image composite:NX_COPY toPoint:&frame.origin];
  660.         if (showCues)    {
  661.             PSWMarkStatus(NX_Y(&bounds), NX_WIDTH(&bounds), NX_HEIGHT(&bounds),
  662.                           [self shouldDrawColor], autoLaunch, autoScan,
  663.                           sticky);
  664.         }
  665.         [self unlockFocus];
  666.  
  667.         [window flushWindow];
  668.     }
  669.     return self;
  670. }
  671.  
  672. - (NXCoord) cellHeight
  673. {
  674.     NXSize    cellSize = {0.0, 0.0};
  675.  
  676.     if (!isApp || !onDock)
  677.         [titleCell calcCellSize:&cellSize];
  678.  
  679.     return cellSize.height;
  680. }
  681.  
  682. - getScreenStatus
  683. {
  684.     int        count;
  685.  
  686.     if (!isApp || !onDock)
  687.         return nil;
  688.  
  689.     PScountscreenlist(appCtxt, &count);
  690.     appWasVisible = (count>0) ? YES : NO;
  691.     appWasActive = ([NXApp activeApp] == appCtxt) ? YES : NO;
  692.  
  693.     return self;
  694. }
  695.  
  696. - (BOOL)appIsVisible
  697. {
  698.     int        count;
  699.  
  700.     if (!isApp || !onDock)
  701.         return NO;
  702.  
  703.     PScountscreenlist(appCtxt, &count);
  704.     return (count > 0) ? YES : NO;
  705. }
  706.  
  707. - (BOOL)appWasVisible
  708. {
  709.     return appWasVisible;
  710. }
  711.  
  712. - (BOOL)appWasActive
  713. {
  714.     return appWasActive;
  715. }
  716.  
  717. - setImage:anImage
  718. {
  719.     id    tImage = image;
  720.     image = anImage;
  721.     return tImage;
  722. }    
  723.  
  724. - getImagePoint:(NXPoint *)imageLoc andHilitePoint:(NXPoint *)hiliteLoc
  725. {
  726.     NXSize    imageSize;
  727.     id        hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite);
  728.     NXSize    hiliteSize = {48.0, 48.0};
  729.     NXCoord    cellHeight = 0.0;
  730.  
  731.     if (!isApp || !onDock)
  732.         cellHeight = [self cellHeight];
  733.  
  734.     if (imageLoc) {
  735.         [image getSize:&imageSize];
  736.         imageLoc->x = (NX_WIDTH(&bounds) - imageSize.width)/2;
  737.         imageLoc->y = cellHeight + (NX_HEIGHT(&bounds) - imageSize.height - cellHeight)/2;
  738.         if (!isApp || !onDock)
  739.             imageLoc->y -= 3.0*NX_HEIGHT(&bounds)/64.0;
  740.     }
  741.  
  742.     if (hiliteLoc && imageLoc) {
  743.         [hilite getSize:&hiliteSize];
  744.         hiliteLoc->x = (NX_WIDTH(&bounds) - hiliteSize.width)/2;
  745.         hiliteLoc->y = 3*NX_HEIGHT(&bounds)/128+imageLoc->y - (hiliteSize.height-imageSize.height)/2;
  746.     }
  747.  
  748.     return self;
  749. }
  750.  
  751.  
  752. - (void) setImageSize
  753. {
  754.     float    fontSize;
  755.     NXSize    imageSize;
  756.     NXSize    hMax = {416, 416};
  757.     NXSize    iMax = {400, 400};
  758.     BOOL    sizeFont = !strcmp(NXGetDefaultValue([NXApp appName], SIZE_FONT), "YES");
  759.     id        hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite);
  760.  
  761.     [image setScalable:YES];
  762.     [hilite setScalable:YES];
  763.  
  764.     imageSize = bounds.size;
  765.     if (!onDock)
  766.         [scaledShelfAppTile setSize:&imageSize];
  767.  
  768.     imageSize = [hilite scaleToFitInside:imageSize max:hMax onDock:onDock isApp:isApp];
  769.     imageSize = [image scaleToFitInside:imageSize max:iMax onDock:onDock isApp:isApp];
  770.  
  771.     if ((!isApp || !onDock) && sizeFont)    {
  772.         fontSize = [[Font userFontOfSize:0 matrix:NX_FLIPPEDMATRIX] pointSize];
  773.         fontSize *= (imageSize.height/(48.0*0.95));
  774.         fontSize = 2.0 * ((int)fontSize/2);
  775.         fontSize = (fontSize < 8.0) ? 8.0 : fontSize;
  776.         fontSize = (fontSize > 18.0) ? 18.0 : fontSize;
  777.         [titleCell setFont:[Font userFontOfSize:fontSize matrix:NX_FLIPPEDMATRIX]];
  778.     }
  779. }
  780.  
  781. - (BOOL)isApp
  782. {
  783.     return isApp;
  784. }
  785.  
  786. - sizeTo:(NXCoord) width :(NXCoord) height
  787. {
  788.     [super sizeTo:width :height];
  789.     [self setImageSize];
  790.     [self getImagePoint:&imagePoint andHilitePoint:&hilitePoint];
  791.     oldSize.width = oldSize.height = 0.0;
  792.  
  793.     return self;
  794. }
  795.  
  796.  
  797. - setDockMgrView:aView
  798. {
  799.     onDock = YES;
  800.     dockMgrView = aView;
  801.     return self;
  802. }
  803.  
  804. - dockMgrView
  805. {
  806.     return dockMgrView;
  807. }
  808.  
  809. - drawAppTile
  810. {
  811.     [scaledAppTile composite:NX_COPY toPoint:&frame.origin];
  812.     if (onDock && isApp && !isLaunched)
  813.         [scaledDotsTile composite:NX_SOVER toPoint:&frame.origin];
  814.  
  815.     return self;
  816. }
  817.  
  818. - drawGhost
  819. {
  820.     float    scanTime = atof(NXGetDefaultValue([NXApp appName], "ScanTime"));
  821.     BOOL    shelfAppTiles = !strcmp(NXGetDefaultValue([NXApp appName], SHELF_APPTIL), "YES");
  822.  
  823.     [tempImage setSize:&bounds.size];
  824.     if (!onDock)    {
  825.         if ([tempImage lockFocus]) {
  826.             if (!shelfAppTiles)    {
  827.                 PSsetalpha(0);
  828.                 NXRectFill(&bounds);
  829.                 [image dissolve:0.666 toPoint:&imagePoint];
  830.                 [tempImage unlockFocus];
  831.                 [tempImage composite:NX_SOVER toPoint:&bounds.origin];
  832.             }
  833.             else    {
  834.                 [scaledShelfAppTile composite:NX_COPY toPoint:&bounds.origin];
  835.                 [image composite:NX_SOVER toPoint:&imagePoint];
  836.                 [tempImage unlockFocus];
  837.                 [tempImage dissolve:0.666 toPoint:&bounds.origin];
  838.             }
  839.         }
  840.     }
  841.     else    {
  842.         if ([tempImage lockFocus])    {
  843.             if (isLaunched && autoScan && scanTime > 0.0)
  844.                 [image composite:NX_SOVER toPoint:&bounds.origin];
  845.             else    {
  846.                 [self drawAppTile];
  847.                 [image composite:NX_SOVER toPoint:&imagePoint];
  848.             }
  849.             PSsetgray(NX_WHITE);
  850.             PSsetalpha(0.666);
  851.             PScompositerect(2.0, 2.0, NX_WIDTH(&frame)-4.0, NX_HEIGHT(&frame)-4.0, NX_SOVER);
  852.             [tempImage unlockFocus];
  853.             [tempImage composite:NX_SOVER toPoint:&bounds.origin];
  854.         }
  855.     }
  856.  
  857.     return self;
  858. }
  859.  
  860.  
  861. - markForPreDelete
  862. {
  863.     NXRect    killRect = {{0.125*NX_WIDTH(&bounds), 0.125*NX_HEIGHT(&bounds)},
  864.                         {0.75*NX_WIDTH(&bounds), 0.75*NX_HEIGHT(&bounds)}};
  865.  
  866.     [scaledKill composite:NX_SOVER toPoint:&killRect.origin];
  867.  
  868.     return self;
  869. }
  870.  
  871. - drawRegular
  872. {
  873.     NXSize    aSize;
  874.     NXPoint    origin = {0.0, 0.0};
  875.     BOOL    shelfAppTiles = !strcmp(NXGetDefaultValue([NXApp appName], SHELF_APPTIL), "YES");
  876.     id        hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite);
  877.  
  878.     if (selected)
  879.         [hilite composite:NX_SOVER toPoint:&hilitePoint];
  880.     else if ([self isFocusView]) {
  881.         if (!onDock)    {
  882.             if (!shelfAppTiles)    {
  883.                 NXRect    aRect;
  884.                 [hilite getSize:&aRect.size];
  885.                 aRect.origin = hilitePoint;
  886.                 [self convertRect:&aRect toView:superview];
  887.                 [superview lockFocus];
  888.                 [superview drawSelf:&aRect :1];
  889.                 [superview unlockFocus];
  890.             }
  891.             else
  892.                 [scaledShelfAppTile composite:NX_COPY toPoint:&origin];
  893.         }
  894.         else
  895.             [self drawAppTile];
  896.     }
  897.  
  898.     [image getSize:&aSize];
  899.     if (isLaunched && (aSize.width == NX_WIDTH(&frame)))
  900.         [image composite:NX_SOVER toPoint:&frame.origin];
  901.     else
  902.         [image composite:NX_SOVER toPoint:&imagePoint];
  903.     return self;
  904. }
  905.  
  906. - drawSelf:(const NXRect *)rects :(int)rectCount
  907. {
  908.     NXRect    cellRect;
  909.     NXPoint    midPoint = {2.0, 2.0};
  910.     BOOL    showCues = !strcmp(NXGetDefaultValue([NXApp appName], SHOW_CUES), "YES");
  911.     BOOL    shelfAppTiles = !strcmp(NXGetDefaultValue([NXApp appName], SHELF_APPTIL), "YES");
  912.  
  913.     if (ghost || (onDock && selected))
  914.         [self drawGhost];
  915.     else
  916.         [self drawRegular];
  917.  
  918.     if (!isApp || !onDock)    {
  919.         if (!shelfAppTiles && NXBrightnessComponent(NXReadPixel(&midPoint)) < NX_DKGRAY + 0.01)
  920.             [titleCell setTextGray:ghost ? NX_LTGRAY : NX_WHITE];
  921.         else
  922.             [titleCell setTextGray:ghost ? NX_DKGRAY : NX_BLACK];
  923.     }
  924.  
  925.     if (showCues && onDock && !ghost && !selected)    {
  926.         PSWMarkStatus(NX_Y(&bounds), NX_WIDTH(&bounds), NX_HEIGHT(&bounds),
  927.                       [self shouldDrawColor], autoLaunch, autoScan,
  928.                       sticky);
  929.     }
  930.  
  931.     if (preDelete)
  932.         [self markForPreDelete];
  933.  
  934.     if (!isApp || !onDock)    {
  935.         NXSetRect(&cellRect, 0.0, 1.0, NX_WIDTH(&bounds), [self cellHeight]);
  936.         [titleCell drawInside:&cellRect inView:self];
  937.     }
  938.  
  939.     return self;
  940. }
  941.  
  942. - restoreIconImage
  943. {
  944.     BOOL        drawThumbnail = !strcmp(NXGetDefaultValue([NXApp appName], DRAW_TNAIL), "YES");
  945.  
  946.     [image free];
  947.     image = [IconView getImageForPath:data fileIcon:!drawThumbnail zone:[self zone]];
  948.     [self setImageSize];
  949.     [self getImagePoint:&imagePoint andHilitePoint:&hilitePoint];
  950.     [self display];
  951.     return self;
  952. }
  953.  
  954. - setAutoScan:(BOOL)flag
  955. {
  956.     autoScan = flag;
  957.     if (autoScan)
  958.         [self allocateGState];
  959.     else
  960.         [self freeGState];
  961.     if (!autoScan && isLaunched)
  962.         [self restoreIconImage];
  963.  
  964.     return self;
  965. }
  966.  
  967. - (BOOL)autoScan
  968. {
  969.     return autoScan;
  970. }
  971.  
  972. - image
  973. {
  974.     return image;
  975. }
  976.  
  977. - (const char *)data
  978. {
  979.     return (const char *)data;
  980. }
  981.  
  982. - getData:(void **)aPtr andLength:(unsigned int *)aLength
  983. {
  984.     *aPtr = data;
  985.     *aLength = length;
  986.     return self;
  987. }
  988.  
  989. - setGhost:(BOOL) newGhost
  990. {
  991.     ghost = newGhost;
  992.     return self;
  993. }
  994.  
  995. - (BOOL) isGhost
  996. {
  997.     return ghost;
  998. }
  999.  
  1000. - setPreDelete:(BOOL)flag
  1001. {
  1002.     preDelete = flag;
  1003.     return self;
  1004. }
  1005.  
  1006. - (BOOL)preDelete
  1007. {
  1008.     return preDelete;
  1009. }
  1010.  
  1011. - setAutoLaunch:(BOOL)flag
  1012. {
  1013.     autoLaunch = flag;
  1014.     return self;
  1015. }
  1016.  
  1017. - (BOOL)autoLaunch
  1018. {
  1019.     return autoLaunch;
  1020. }
  1021.  
  1022. - (int) state
  1023. {
  1024.     return selected;
  1025. }
  1026.  
  1027. - setState:(int) flag
  1028. {
  1029.     if (flag ^ selected) {
  1030.         selected = flag ? YES : NO;
  1031.         [self display];
  1032.     }
  1033.     return self;
  1034. }
  1035.  
  1036. - (BOOL)onDock
  1037. {
  1038.     return onDock;
  1039. }
  1040.  
  1041. - (BOOL)isLaunched
  1042. {
  1043.     return isLaunched;
  1044. }
  1045.  
  1046. - setLaunched:(BOOL)flag
  1047. {
  1048.     isLaunched = flag;
  1049.     if (!isLaunched && autoScan)    {
  1050.         appPid = -1;
  1051.         [image free];
  1052.         image = [IconView getImageForPath:data fileIcon:YES zone:[self zone]];
  1053.         [self setImageSize];
  1054.     }
  1055.     return self;
  1056. }
  1057.  
  1058. - (int)appPid
  1059. {
  1060.     return appPid;
  1061. }
  1062.  
  1063. - setSticky:(BOOL)flag
  1064. {
  1065.     sticky = flag;
  1066.     return self;
  1067. }
  1068.  
  1069. - (BOOL)isSticky
  1070. {
  1071.     return sticky;
  1072. }
  1073.  
  1074. - (int)appCtxt
  1075. {
  1076.     return appCtxt;
  1077. }
  1078.  
  1079. - setFiendLaunch:(BOOL)flag
  1080. {
  1081.     fiendLaunch = flag;
  1082.     return self;
  1083. }
  1084.  
  1085. - (BOOL)fiendLaunch
  1086. {
  1087.     return fiendLaunch;
  1088. }
  1089.  
  1090. - setCtxt:(int)ctxt pid:(int)pid andIcon:(int)icon
  1091. {
  1092.     appPid = pid;
  1093.     appCtxt = ctxt;
  1094.     appIcon = icon;
  1095.     return self;
  1096. }
  1097.  
  1098. @end
  1099.