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.