Changeset 345 for trunk/appswitch/appswitch/main.c
- Timestamp:
- 11/05/07 10:05:50 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/appswitch/appswitch/main.c
r306 r345 3 3 Nicholas Riley <appswitch@sabi.net> 4 4 5 Copyright (c) 2003-0 6, Nicholas Riley5 Copyright (c) 2003-07, Nicholas Riley 6 6 All rights reserved. 7 7 … … 26 26 const char *APP_NAME; 27 27 28 #define VERSION "1.1d 1"28 #define VERSION "1.1d2" 29 29 30 30 struct { … … 64 64 // CoreGraphics errors 65 65 { kCGErrorIllegalArgument, "window server error.\nAre you logged in?" }, 66 { kCGErrorInvalidContext, "application context unavailable" }, 66 67 { fnfErr, "file not found" }, 67 68 // (abused) errors … … 295 296 } 296 297 297 char *getInfoCString(CFDictionaryRef info, CFStringRef key) { 298 CFStringRef str = CFDictionaryGetValue(info, key); 298 CFStringRef stringTrimmedToWidth(CFStringRef str, CFIndex width) { 299 299 if (str == NULL) 300 return ""; 301 static char *cStr = NULL; 302 static bool wasDynamic = false; 303 if (wasDynamic) 304 free(cStr); 305 cStr = (char *)CFStringGetCStringPtr(str, CFStringGetSystemEncoding()); 306 if (cStr != NULL) { 307 wasDynamic = false; 308 } else { 309 CFIndex cStrLength = CFStringGetMaximumSizeOfFileSystemRepresentation(str); 310 cStr = (char *)malloc(cStrLength * sizeof(char)); 311 if (!CFStringGetFileSystemRepresentation(str, cStr, cStrLength)) { 312 CFShow(cStr); 313 errexit("internal error: string encoding conversion failed"); 314 } 315 wasDynamic = true; 316 } 317 return cStr; 300 str = CFSTR(""); 301 CFIndex length = CFStringGetLength(str); 302 if (length == width) 303 return CFRetain(str); 304 305 CFMutableStringRef padStr = CFStringCreateMutableCopy(NULL, width, str); 306 CFStringPad(padStr, CFSTR(" "), width, 0); 307 return padStr; 318 308 } 319 309 … … 326 316 }; 327 317 pid_t pid; 328 char *format = NULL; 318 CFStringRef format = NULL; 319 CFIndex nameWidth = 19; 320 CFIndex pathWidth = 0; 329 321 if (OPTS.appAction == APP_LIST) { 330 322 int termwidth = 80; … … 336 328 ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&ws) != -1) || 337 329 ws.ws_col != 0) termwidth = ws.ws_col; 338 char *formatButPath = "%9ld.%ld %5ld %4s %4s %-19.19s"; 339 int pathlen = termwidth - strlen(banner) - 1; 340 // XXX don't ever free 'format', should fix if we get called repeatedly 330 char *formatButPath = "%9ld.%ld %5ld %@ %@ %@"; 331 // XXX don't ever release 'format', should fix if we get called repeatedly 341 332 if (OPTS.longList) { 333 pathWidth = 1; 342 334 printf("%s PATH (bundle identifier)\n", banner); 343 asprintf(&format, "%s %%s", formatButPath); 344 } else if (pathlen >= 4) { 345 printf("%s PATH\n", banner); 346 asprintf(&format, "%s %%-%d.%ds", formatButPath, pathlen, pathlen); 335 format = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s %%@"), formatButPath); 347 336 } else { 348 format = formatButPath; 337 pathWidth = termwidth - strlen(banner) - 1; 338 if (pathWidth >= 4) { 339 printf("%s PATH\n", banner); 340 format = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s %%@"), formatButPath); 341 } else { 342 pathWidth = 0; 343 format = CFStringCreateWithCString(NULL, formatButPath, kCFStringEncodingUTF8); 344 } 349 345 } 350 346 } … … 366 362 case MATCH_PID: err = GetProcessPID(&psn, &pid); if (err != noErr || OPTS.pid != pid) continue; 367 363 break; 368 case MATCH_PATH: if (!infoStringMatches(info, CFSTR("BundlePath"), OPTS.path)) continue; 364 case MATCH_PATH: if (!infoStringMatches(info, CFSTR("BundlePath"), OPTS.path) && 365 !infoStringMatches(info, CFSTR("CFBundleExecutable"), OPTS.path)) continue; 369 366 break; 370 367 case MATCH_BUNDLE_ID: if (!infoStringMatches(info, CFSTR("CFBundleIdentifier"), OPTS.bundleID)) continue; … … 376 373 if (GetProcessPID(&psn, &pid) != noErr) 377 374 pid = -1; 378 printf(format, psn.lowLongOfPSN, psn.highLongOfPSN, pid, 379 getInfoCString(info, CFSTR("FileType")), getInfoCString(info, CFSTR("FileCreator")), 380 getInfoCString(info, CFSTR("CFBundleName")), getInfoCString(info, CFSTR("BundlePath"))); 381 if (OPTS.longList) { 382 char *bundleID = getInfoCString(info, CFSTR("CFBundleIdentifier")); 383 if (bundleID[0] != '\0') 384 printf(" (%s)", bundleID); 375 CFStringRef path = NULL; 376 // XXX padding/truncation probably breaks with double-width characters 377 if (pathWidth) { 378 path = CFDictionaryGetValue(info, CFSTR("BundlePath")); 379 if (path == NULL) 380 path = CFDictionaryGetValue(info, CFSTR("CFBundleExecutable")); 381 if (!OPTS.longList) 382 path = stringTrimmedToWidth(path, pathWidth); 385 383 } 386 putchar('\n'); 384 CFStringRef name = stringTrimmedToWidth(CFDictionaryGetValue(info, CFSTR("CFBundleName")), nameWidth); 385 CFStringRef type = stringTrimmedToWidth(CFDictionaryGetValue(info, CFSTR("FileType")), 4); 386 CFStringRef creator = stringTrimmedToWidth(CFDictionaryGetValue(info, CFSTR("FileCreator")), 4); 387 CFStringRef line = CFStringCreateWithFormat(NULL, NULL, format, 388 psn.lowLongOfPSN, psn.highLongOfPSN, pid, type, creator, name, path); 389 CFRelease(name); 390 CFRelease(type); 391 CFRelease(creator); 392 if (!OPTS.longList) 393 CFRelease(path); 394 else { 395 CFStringRef bundleID = CFDictionaryGetValue(info, CFSTR("CFBundleIdentifier")); 396 if (bundleID != NULL && CFStringGetLength(bundleID) != 0) { 397 CFStringRef origLine = line; 398 line = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)"), line, bundleID); 399 CFRelease(origLine); 400 } 401 } 402 char *cStr = (char *)CFStringGetCStringPtr(line, CFStringGetSystemEncoding()); 403 if (cStr != NULL) { 404 puts(cStr); 405 } else { 406 CFIndex cStrLength = CFStringGetMaximumSizeOfFileSystemRepresentation(line); 407 cStr = (char *)malloc(cStrLength * sizeof(char)); 408 if (!CFStringGetFileSystemRepresentation(line, cStr, cStrLength)) { 409 CFShow(cStr); 410 errexit("internal error: string encoding conversion failed"); 411 } 412 puts(cStr); 413 free(cStr); 414 } 387 415 continue; 388 416 } … … 394 422 395 423 errexit("can't find matching process"); 396 return psn; 424 return psn; // not reached 397 425 } 398 426 … … 410 438 case APP_LIST: break; // already handled in matchApplication 411 439 case APP_SWITCH: err = SetFrontProcess(&psn); verb = "set front"; break; 440 // XXX show/hide return paramErr - rdar://problem/5579375 - ask on carbon-dev later 412 441 case APP_SHOW: err = ShowHideProcess(&psn, true); verb = "show"; break; 413 442 case APP_HIDE: err = ShowHideProcess(&psn, false); verb = "hide"; break; … … 416 445 case APP_KILL_HARD: 417 446 { 447 // no Process Manager equivalent - rdar://problem/4808400 418 448 if (kill(getPID(&psn), SIGKILL) == -1) 419 449 err = (errno == ESRCH) ? procNotFound : (errno == EPERM ? permErr : paramErr); … … 431 461 switch (OPTS.action) { 432 462 case ACTION_NONE: break; 463 // no Process Manager equivalents - rdar://problem/4808397 433 464 case ACTION_SHOW_ALL: err = CPSPostShowAllReq(&psn); verb = "show all"; break; 434 465 case ACTION_HIDE_OTHERS: err = CPSPostHideMostReq(&psn); verb = "hide other"; break;
Note:
See TracChangeset
for help on using the changeset viewer.