home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- ABAppInfo.m
-
- Copyright (c) 1998, David C. Lambert. All Rights Reserved.
- **********************************************************************/
- #import <time.h>
- #import "table.h"
- #import "ABWraps.h"
- #import "ABAppInfo.h"
-
- static id processTable;
- static id pidUidTable;
- static id pidMenuTable;
- static id pidIconTable;
- static id pidMinisTable;
- static id pidCtxtTable;
- static id ctxtPidTable;
- static NXSize screenSize;
- static DPSContext myContext;
-
- static int
- safeGetCtxtIconPidAndMenu(int context, int *icon, int *pid, int *menu)
- {
- int status = 0;
-
- if (context < 0) return -1;
-
- DPSTraceContext(myContext, NO);
- NX_DURING
- PSWGetCtxtIconPidAndMenu(context, icon, pid, menu);
- NXPing();
- NX_HANDLER
- NXReportError(&NXLocalHandler);
- switch (NXLocalHandler.code) {
- case dps_err_ps:
- status = -1;
- break;
- default:
- NX_RERAISE();
- }
- NX_ENDHANDLER
- if (*menu == 100000) *menu = -1;
- return status;
- }
-
- static int
- safeGetWindowList(int *windows)
- {
- int count;
-
- if (!windows) return -1;
-
- NX_DURING
- PScountwindowlist(0, &count);
- PSwindowlist(0, count, windows);
- NXPing();
- NX_HANDLER
- NXReportError(&NXLocalHandler);
- switch (NXLocalHandler.code) {
- case dps_err_ps:
- PScountwindowlist(0, &count);
- break;
- default:
- NX_RERAISE();
- }
- NX_ENDHANDLER
- return count;
- }
-
- static int
- safeGetCurrrentOwner(int windowNum, int *owner)
- {
- int status = 0;
-
- if (windowNum <= 0) return -1;
-
- NX_DURING
- PSWGetCurrentOwner(windowNum, owner);
- NXPing();
- NX_HANDLER
- NXReportError(&NXLocalHandler);
- switch (NXLocalHandler.code) {
- case dps_err_ps:
- status = -1;
- break;
- default:
- NX_RERAISE();
- }
- NX_ENDHANDLER
- return status;
- }
-
- static int
- safeUnhideContext(int appCtxt, int raiseFlag, int activateFlag, int hideFlag)
- {
- int status = 0;
-
- if (appCtxt <= 0) return -1;
-
- DPSTraceContext(myContext, NO);
- NX_DURING
- PSWUnhideContext(appCtxt, raiseFlag, activateFlag, hideFlag);
- NXPing();
- NX_HANDLER
- NXReportError(&NXLocalHandler);
- switch (NXLocalHandler.code) {
- case dps_err_ps:
- status = -1;
- NXLogError("PS error in PSWUnhideContext: %d, %d, %d, %d",
- appCtxt, raiseFlag, activateFlag, hideFlag);
- break;
- default:
- NX_RERAISE();
- }
- NX_ENDHANDLER
-
- return status;
- }
-
- static int
- safeGetMiniWindows(int appCtxt, int *minis)
- {
- int miniCount;
- int screenCount;
-
- if (appCtxt <= 0) return -1;
-
- DPSTraceContext(myContext, NO);
- NX_DURING
- PScountscreenlist(appCtxt, &screenCount);
- PSWGetMiniWindows(appCtxt, screenCount, &miniCount, minis);
- NX_HANDLER
- NXReportError(&NXLocalHandler);
- switch (NXLocalHandler.code) {
- case dps_err_ps:
- miniCount = 0;
- NXLogError("PS error in PSWGetMiniWindows: %d, %d, %d",
- appCtxt, screenCount, miniCount);
- break;
- default:
- NX_RERAISE();
- }
- NX_ENDHANDLER
- return miniCount;
- }
-
- @implementation ABAppInfo : Object
-
- + initialize
- {
- static BOOL done = NO;
-
- if (!done) {
- done = YES;
-
- processTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"%" valueDesc:"i"];
-
- pidUidTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"i" valueDesc:"i"];
- pidIconTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"i" valueDesc:"i"];
- pidMenuTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"i" valueDesc:"i"];
- pidCtxtTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"i" valueDesc:"i"];
- ctxtPidTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"i" valueDesc:"i"];
- pidMinisTable = [[HashTable allocFromZone:[self zone]] initKeyDesc:"i" valueDesc:"@"];
-
- [NXApp getScreenSize:&screenSize];
- myContext = DPSGetCurrentContext();
- [self reset];
- }
- return self;
- }
-
- + reset
- {
- id miniStore;
- int i;
- int j;
- int pid;
- int icon;
- int menu;
- int count;
- int owner;
- int miniCount;
- int screenCount;
- int *minis;
- int *windows;
- int table();
- char nameUidString[40];
- struct tbl_procinfo pi;
- NXZone *theZone = [self zone];
-
- [pidUidTable empty];
- [pidMenuTable empty];
- [pidIconTable empty];
- [pidCtxtTable empty];
- [ctxtPidTable empty];
- [processTable empty];
- [pidMinisTable freeObjects];
-
- PScountwindowlist(0, &count);
- windows = (int *)NXZoneMalloc(theZone, count*sizeof(int)+ARRBUF);
- count = safeGetWindowList(windows);
-
- minis = (int *)NXZoneMalloc(theZone, count*sizeof(int)+ARRBUF);
-
- for(i = 0; i < count; i++) {
- if (safeGetCurrrentOwner(windows[i], &owner) < 0)
- continue;
- if (safeGetCtxtIconPidAndMenu(owner, &icon, &pid, &menu) < 0)
- continue;
- if (![pidIconTable isKey:(const void *)pid]) {
- miniCount = safeGetMiniWindows(owner, minis);
- if (pid > 0 && miniCount > 0) {
- if (icon < 0) icon = minis[--miniCount];
- miniStore = [[Storage allocFromZone:theZone]
- initCount:miniCount
- elementSize:sizeof(int)
- description:"i"];
- for(j = 0; j < miniCount; j++)
- [miniStore replaceElementAt:j with:(void *)(minis+j)];
- [pidMinisTable insertKey:(const void *)pid value:(void *)miniStore];
- }
- [pidMenuTable insertKey:(const void *)pid value:(void *)menu];
- [pidIconTable insertKey:(const void *)pid value:(void *)icon];
- [pidCtxtTable insertKey:(const void *)pid value:(void *)owner];
- [ctxtPidTable insertKey:(const void *)owner value:(void *)pid];
- if ((int)table(TBL_PROCINFO, pid, (char *)&pi, 1, sizeof pi) == 1 && pi.pi_status==PI_ACTIVE) {
- [pidUidTable insertKey:(const void *)pid value:(void *)pi.pi_uid];
- sprintf(nameUidString, "%s::%d", pi.pi_comm, pi.pi_uid);
- [processTable insertKey:(const void *)NXUniqueString(nameUidString) value:(void *)pid];
- }
- }
- }
- NXZoneFree(theZone, minis);
- NXZoneFree(theZone, windows);
- return self;
- }
-
- + unhideCtxt:(int)ctxt raise:(BOOL)raiseFlag activate:(BOOL)activateFlag hideOthers:(BOOL)hideFlag
- {
- if (safeUnhideContext(ctxt, (int)raiseFlag, (int)activateFlag, (int)hideFlag) == 0)
- return self;
- else
- return nil;
- }
-
- + unhidePid:(int)pid raise:(BOOL)raiseFlag activate:(BOOL)activateFlag hideOthers:(BOOL)hideFlag
- {
- int ctxt = [self getAppCtxtForPid:pid];
-
- if (safeUnhideContext(ctxt, (int)raiseFlag, (int)activateFlag, (int)hideFlag) == 0)
- return self;
- else
- return nil;
- }
-
- + vanishIconForCtxt:(int)ctxt
- {
- return [self vanishIconForPid:[self getPidForAppCtxt:ctxt]];
- }
-
- + vanishIconForPid:(int)pid
- {
- int appIcon = [self getAppIconForPid:pid];
-
- if (appIcon > 0) {
- DPSTraceContext(myContext, NO);
- PSWMove(NOWHERE, NOWHERE, appIcon);
- NXPing();
- return self;
- }
- else
- return nil;
- }
-
- + unvanishIconForCtxt:(int)ctxt
- {
- return [self unvanishIconForPid:[self getPidForAppCtxt:ctxt]];
- }
-
- + unvanishIconForPid:(int)pid
- {
- int appIcon = [self getAppIconForPid:pid];
-
- if (appIcon > 0) {
- DPSTraceContext(myContext, NO);
- PSWReplaceIcon(appIcon, (int)(screenSize.width)-64);
- NXPing();
- return self;
- }
- else
- return nil;
- }
-
- + getShortName:(char *)shortName from:(const char *)theAppFileName
- {
- char *theAppName;
-
- if (!shortName || !theAppFileName)
- return self;
-
- shortName[0] = '\0';
- theAppName = strrchr(theAppFileName, '/');
-
- if (!theAppName) {
- strcpy(shortName, theAppFileName);
- return self;
- }
- else
- theAppName++;
-
- if (!strcmp(theAppName+strlen(theAppName)-4, ".app")) {
- strncpy(shortName, theAppName, strlen(theAppName)-4);
- shortName[strlen(theAppName)-4] = '\0';
- }
- else if (!strcmp(theAppName+strlen(theAppName)-6, ".debug")) {
- strncpy(shortName, theAppName, strlen(theAppName)-6);
- shortName[strlen(theAppName)-6] = '\0';
- }
- else if (!strcmp(theAppName+strlen(theAppName)-8, ".profile")) {
- strncpy(shortName, theAppName, strlen(theAppName)-8);
- shortName[strlen(theAppName)-6] = '\0';
- }
- else
- strcpy(shortName, theAppName);
- shortName[16]=0;
-
- return self;
- }
-
- + (int)getPidFor:(char *)aName
- {
- NXAtom atom = NXUniqueString(aName);
-
- if ([processTable isKey:atom])
- return (int)[processTable valueForKey:atom];
- else
- return -1;
- }
-
- + (int)getUidForPid:(int)aPid
- {
- if ([pidUidTable isKey:(void *)aPid])
- return (int)[pidUidTable valueForKey:(void *)aPid];
- else
- return -1;
- }
-
- + (int)getAppIconForPid:(int)aPid
- {
- if ([pidIconTable isKey:(void *)aPid])
- return (int)[pidIconTable valueForKey:(void *)aPid];
- else
- return -1;
- }
-
- + (int)getAppMenuForPid:(int)aPid
- {
- if ([pidMenuTable isKey:(void *)aPid])
- return (int)[pidMenuTable valueForKey:(void *)aPid];
- else
- return -1;
- }
-
- + (int)getAppCtxtForPid:(int)aPid
- {
- if ([pidCtxtTable isKey:(void *)aPid])
- return (int)[pidCtxtTable valueForKey:(void *)aPid];
- else
- return -1;
- }
-
- + getAppMiniWinsForPid:(int)aPid
- {
- if ([pidMinisTable isKey:(void *)aPid])
- return [pidMinisTable valueForKey:(void *)aPid];
- else
- return nil;
- }
-
- + (int)getPidForAppCtxt:(int)aCtxt
- {
- if ([ctxtPidTable isKey:(void *)aCtxt])
- return (int)[ctxtPidTable valueForKey:(void *)aCtxt];
- else
- return -1;
- }
-
- + (BOOL)pidExists:(int)aPid
- {
- return [pidUidTable isKey:(void *)aPid];
- }
-
- - initForFile:(char *)theAppFileName
- {
- char theShortName[100];
-
- [super init];
- [[self class] getShortName:theShortName from:theAppFileName];
-
- appFileName = NXUniqueString(theAppFileName);
- appShortName = NXUniqueString(theShortName);
-
- [self update];
-
- return self;
- }
-
- - update
- {
- isLaunched = ((appPid = [[self class] getPidFor:(char *)appShortName]) != -1);
-
- if (isLaunched) {
- appUid = (int)[pidUidTable valueForKey:(const void *)appPid];
- appCtxt = (int)[pidCtxtTable valueForKey:(const void *)appPid];
- appIconWin = (int)[pidIconTable valueForKey:(const void *)appPid];
- appMainMenu = (int)[pidMenuTable valueForKey:(const void *)appPid];
- appMiniWins = [pidMinisTable valueForKey:(const void *)appPid];
- }
- else {
- appUid = appCtxt = appIconWin = appMainMenu = -1;
- appMiniWins = nil;
- }
-
- return self;
- }
-
- - activateApp:(BOOL)activateFlag raise:(BOOL)raiseFlag hideOthers:(BOOL)hideFlag
- {
- return [[self class] unhideCtxt:appCtxt raise:raiseFlag activate:activateFlag hideOthers:hideFlag];
- }
-
- - vanishIcon
- {
- if (appIconWin > 0)
- PSWMove(NOWHERE, NOWHERE, appIconWin);
- return self;
- }
-
- - unvanishIcon
- {
- if (appIconWin > 0) {
- DPSTraceContext(myContext, NO);
- PSWReplaceIcon(appIconWin, (int)(screenSize.width)-64);
- }
- return self;
- }
-
- - free
- {
- return [super free];
- }
-
- - (BOOL)isLaunched
- {
- return isLaunched;
- }
-
- - (int)appPid
- {
- return appPid;
- }
-
- - (int)appUid
- {
- return appUid;
- }
-
- - (int)appCtxt
- {
- return appCtxt;
- }
-
- - (int)appIconWin
- {
- return appIconWin;
- }
-
- - (int)appMainMenu
- {
- return appMainMenu;
- }
-
- - appMiniWins
- {
- return appMiniWins;
- }
-
- - (NXAtom)appFileName
- {
- return appFileName;
- }
-
- - (NXAtom)appShortName
- {
- return appShortName;
- }
-
- @end
-
- #ifdef ABTEST
- #include <libc.h>
- #include <string.h>
- #include <stdlib.h>
-
- void
- listApps()
- {
- id appMinis;
- int i;
- int count;
- int appPid;
- int appUid;
- int appCtxt;
- int appMenu;
- int appIcon;
- char theName[30];
- char *shortName;
- NXHashState state = [processTable initState];
-
- printf("%-17s%7s%7s%12s%7s%7s%10s\n", "SHORTNAME", "PID", "UID", "CTXT", "ICON", "MENU", "MINIWINS");
- while ([processTable nextState:&state key:(void *)&shortName value:(void *)&appPid]) {
- if (strstr(shortName, "kernel idle")) continue;
- strcpy(theName, shortName);
- *strstr(theName, "::") = '\0';
- appUid = (int)[pidUidTable valueForKey:(void *)appPid];
- appCtxt = (int)[pidCtxtTable valueForKey:(void *)appPid];
- appIcon = (int)[pidIconTable valueForKey:(void *)appPid];
- appMenu = (int)[pidMenuTable valueForKey:(void *)appPid];
- appMinis = [pidMinisTable valueForKey:(void *)appPid];
- printf("%-17s%7d%7d%12d%7d%7d ", theName, appPid, appUid, appCtxt, appIcon, appMenu);
- if (appMinis != nil) {
- count = [appMinis count];
- for(i = 0; i < count; i++)
- printf("%d ", *(int *)[appMinis elementAt:i]);
- }
- printf("\n");
- }
- }
-
- main(int argc, char **argv)
- {
- id miniWins;
- int c;
- int i;
- int count;
- char *theName;
- int pid = -1;
- int ctxt = -1;
- int appUid = -1;
- int action = 0;
- BOOL list = NO;
- BOOL raise = NO;
- BOOL activate = NO;
- BOOL hideOthers = NO;
- BOOL vanishIcon = NO;
- BOOL unvanishIcon = NO;
- ABAppInfo *info;
- extern char *optarg;
-
- [Application new];
- while((c = getopt(argc, argv, "ac:hHp:ruvN:")) != -1) {
- switch(c) {
- case 'a': activate = YES; break;
- case 'c': ctxt = atoi(optarg); break;
- case 'H': hideOthers = YES; break;
- case 'p': pid = atoi(optarg); break;
- case 'r': raise = YES; break;
- case 'u': unvanishIcon = YES; action++; break;
- case 'v': vanishIcon = YES; action++; break;
- case 'N':
- info = [[ABAppInfo alloc] initForFile:optarg];
- printf("%-17s%7s%7s%12s%7s%7s%10s\n",
- "SHORTNAME", "PID", "UID", "CTXT", "ICON", "MENU", "MINIWINS");
- sscanf([info appShortName], "%[^:]::%d", theName, &appUid);
- printf("%-17s%7d%7d%12d%7d%7d ", theName, [info appPid], appUid,
- [info appCtxt], [info appIconWin], [info appMainMenu]);
- miniWins = [info appMiniWins];
- if (miniWins != nil) {
- count = [miniWins count];
- for(i = 0; i < count; i++)
- printf("%d ", *(int *)[miniWins elementAt:i]);
- }
- printf("\n");
- exit(0);
- break;
- case 'h':
- case '?':
- fprintf(stderr, "Usage: ctxt-util [[-h] | [-N appName::uid] | [[-p pid|-c ctxt] -arHvu]\n");
- fprintf(stderr, " with no args, lists all active contexts\n");
- fprintf(stderr, " -h: show this message\n");
- fprintf(stderr, " -N: list info for a single app name::uid (eg, 'Edit::0')\n");
- fprintf(stderr, " In conjunction with -p or -c:\n");
- fprintf(stderr, " -a: activate (hides if not present)\n");
- fprintf(stderr, " -r: raise windows\n");
- fprintf(stderr, " -H: hide other apps\n");
- fprintf(stderr, " -v: vanish app icon\n");
- fprintf(stderr, " -u: restore app icon\n");
- exit(c!='h');
- }
- }
-
- if (action != 1) list = YES;
-
- if (unvanishIcon && vanishIcon) {
- fprintf(stderr, "Can only replace OR vanish an icon, not both!\n");
- exit(1);
- }
-
- if ((raise || activate || hideOthers || vanishIcon || unvanishIcon) && !(pid>0 || ctxt>0)) {
- fprintf(stderr, "You need a process or context id to do that!\n");
- exit(1);
- }
-
- [ABAppInfo initialize];
-
- if (raise || activate || hideOthers) {
- if (pid > 0)
- [ABAppInfo unhidePid:pid raise:raise activate:activate hideOthers:hideOthers];
- else
- [ABAppInfo unhideCtxt:ctxt raise:raise activate:activate hideOthers:hideOthers];
- }
- else if (unvanishIcon) {
- if (pid > 0)
- [ABAppInfo unvanishIconForPid:pid];
- else
- [ABAppInfo unvanishIconForCtxt:ctxt];
- }
- else if (vanishIcon) {
- if (pid > 0)
- [ABAppInfo vanishIconForPid:pid];
- else
- [ABAppInfo vanishIconForCtxt:ctxt];
- }
- else
- listApps();
- exit(0);
- }
-
- #endif
-