This is ABAppInfo.m in view mode; [Download] [Up]
/********************************************************************** 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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.