static PyObject *Icn_WriteIconFile(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; IconFamilyHandle iconFamily; FSSpec iconFile; #ifndef WriteIconFile PyMac_PRECHECK(WriteIconFile); #endif if (!PyArg_ParseTuple(_args, "O&O&", ResObj_Convert, &iconFamily, PyMac_GetFSSpec, &iconFile)) return NULL; _err = WriteIconFile(iconFamily, &iconFile); if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); _res = Py_None; return _res; }
/* main: * Guess what this function does. */ int main(int argc, char *argv[]) { PACKFILE *f; CFURLRef cf_url_ref; FSRef fs_ref; FSSpec fs_spec; IconFamilyHandle icon_family; Handle raw_data; char datafile[MAX_STRING_SIZE]; char bundle[MAX_STRING_SIZE]; char bundle_dir[MAX_STRING_SIZE]; char bundle_contents_dir[MAX_STRING_SIZE]; char bundle_contents_resources_dir[MAX_STRING_SIZE]; char bundle_contents_macos_dir[MAX_STRING_SIZE]; char bundle_contents_frameworks_dir[MAX_STRING_SIZE]; char *bundle_exe = NULL; char bundle_plist[MAX_STRING_SIZE]; char bundle_pkginfo[MAX_STRING_SIZE]; char bundle_icns[MAX_STRING_SIZE]; char bundle_version[MAX_STRING_SIZE]; char bundle_long_version[MAX_STRING_SIZE]; char *buffer = NULL; int arg, type = 0, result = 0; int i, size, x, y, mask_bit, mask_byte; unsigned char *data; install_allegro(SYSTEM_NONE, &errno, &atexit); set_color_depth(32); set_color_conversion(COLORCONV_TOTAL | COLORCONV_KEEP_TRANS); if (argc < 2) usage(); datafile[0] = '\0'; bundle[0] = '\0'; select_palette(black_palette); /* Parse command line and load any given resource */ for (arg = 2; arg < argc; arg++) { if (!strcmp(argv[arg], "-m")) flags |= F_MOVE; else if (!strcmp(argv[arg], "-e")) flags |= F_EMBED_FRAMEWORK; else if (!strcmp(argv[arg], "-o")) { if ((argc < arg + 2) || (bundle[0] != '\0')) usage(); strcpy(bundle, argv[++arg]); } else if (!strcmp(argv[arg], "-v")) { if (argc < arg + 2) usage(); flags |= F_GOT_VERSION; strcpy(bundle_version, argv[++arg]); } else if (!strcmp(argv[arg], "-V")) { if (argc < arg + 2) usage(); flags |= F_GOT_LONG_VERSION; strcpy(bundle_long_version, argv[++arg]); } else if (!strcmp(argv[arg], "-d")) { if (argc < arg + 2) usage(); strcpy(datafile, argv[++arg]); } else if ((!strcmp(argv[arg], "-16")) || (!strcmp(argv[arg], "-32")) || (!strcmp(argv[arg], "-48")) || (!strcmp(argv[arg], "-128"))) { if (argc < arg + 2) usage(); switch (atoi(&argv[arg][1])) { case 16: type = 0; break; case 32: type = 1; break; case 48: type = 2; break; case 128: type = 3; break; } if (load_resource(datafile, argv[++arg], &icon_data[type])) { result = -1; goto exit_error; } } else { if (load_resource(datafile, argv[arg], NULL)) { result = -1; goto exit_error; } } } buffer = malloc(4096); if (!buffer) { result = -1; goto exit_error_bundle; } bundle_exe = argv[1]; if (!exists(bundle_exe)) { fprintf(stderr, "Cannot locate executable file '%s'\n", bundle_exe); result = -1; goto exit_error; } if (bundle[0] == '\0') strcpy(bundle, bundle_exe); replace_extension(bundle_dir, bundle, "app", MAX_STRING_SIZE); strcpy(bundle_contents_dir, bundle_dir); strcat(bundle_contents_dir, "/Contents"); strcpy(bundle_contents_resources_dir, bundle_contents_dir); strcat(bundle_contents_resources_dir, "/Resources"); strcpy(bundle_contents_macos_dir, bundle_contents_dir); strcat(bundle_contents_macos_dir, "/MacOS"); strcpy(bundle_contents_frameworks_dir, bundle_contents_dir); strcat(bundle_contents_frameworks_dir, "/Frameworks"); bundle_icns[0] = '\0'; bundle_plist[0] = '\0'; bundle_pkginfo[0] = '\0'; /* Create bundle structure */ if ((mkdir(bundle_dir, 0777) && (errno != EEXIST)) || (mkdir(bundle_contents_dir, 0777) && (errno != EEXIST)) || (mkdir(bundle_contents_resources_dir, 0777) && (errno != EEXIST)) || (mkdir(bundle_contents_macos_dir, 0777) && (errno != EEXIST))) { fprintf(stderr, "Cannot create %s\n", bundle_dir); result = -1; goto exit_error_bundle; } /* Copy/move executable into the bundle */ if (copy_file(bundle_exe, bundle_contents_macos_dir)) { fprintf(stderr, "Cannot create %s\n", bundle_contents_macos_dir); result = -1; goto exit_error_bundle; } strcat(bundle_contents_macos_dir, "/"); strcat(bundle_contents_macos_dir, get_filename(bundle_exe)); chmod(bundle_contents_macos_dir, 0755); if (flags & F_MOVE) unlink(bundle_exe); /* Embed Allegro framework if requested */ if (flags & F_EMBED_FRAMEWORK) { if (!file_exists("/Library/Frameworks/Allegro.framework", FA_RDONLY | FA_DIREC, NULL)) { fprintf(stderr, "Cannot find Allegro framework\n"); result = -1; goto exit_error_bundle; } if (!exists("/Library/Frameworks/Allegro.framework/Resources/Embeddable")) { fprintf(stderr, "Cannot embed system wide Allegro framework; install embeddable version first!\n"); result = -1; goto exit_error_bundle; } sprintf(buffer, "/Developer/Tools/pbxcp -exclude .DS_Store -exclude CVS -resolve-src-symlinks /Library/Frameworks/Allegro.framework %s", bundle_contents_frameworks_dir); if ((mkdir(bundle_contents_frameworks_dir, 0777) && (errno != EEXIST)) || (system(buffer))) { fprintf(stderr, "Cannot create %s\n", bundle_contents_frameworks_dir); result = -1; goto exit_error_bundle; } } /* Setup the .icns resource */ if (flags & F_ICONS_DEFINED) { strcat(bundle_contents_resources_dir, "/"); strcat(bundle_contents_resources_dir, get_filename(bundle)); replace_extension(bundle_icns, bundle_contents_resources_dir, "icns", MAX_STRING_SIZE); icon_family = (IconFamilyHandle)NewHandle(0); for (i = 0; i < 4; i++) { if (flags & icon_data[i].defined) { /* Set 32bit RGBA data */ raw_data = NewHandle(icon_data[i].size * icon_data[i].size * 4); data = *(unsigned char **)raw_data; for (y = 0; y < icon_data[i].size; y++) { for (x = 0; x < icon_data[i].size; x++) { *data++ = geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); *data++ = getr32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); *data++ = getg32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); *data++ = getb32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); } } if (SetIconFamilyData(icon_family, icon_data[i].data, raw_data) != noErr) { DisposeHandle(raw_data); fprintf(stderr, "Error setting %dx%d icon resource RGBA data\n", icon_data[i].size, icon_data[i].size); result = -1; goto exit_error_bundle; } DisposeHandle(raw_data); /* Set 8bit mask */ raw_data = NewHandle(icon_data[i].size * icon_data[i].size); data = *(unsigned char **)raw_data; for (y = 0; y < icon_data[i].size; y++) { for (x = 0; x < icon_data[i].size; x++) { *data++ = geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); } } if (SetIconFamilyData(icon_family, icon_data[i].mask8, raw_data) != noErr) { DisposeHandle(raw_data); fprintf(stderr, "Error setting %dx%d icon resource 8bit mask\n", icon_data[i].size, icon_data[i].size); result = -1; goto exit_error_bundle; } DisposeHandle(raw_data); /* Set 1bit mask */ if (icon_data[i].mask1) { size = ((icon_data[i].size * icon_data[i].size) + 7) / 8; raw_data = NewHandle(size * 2); data = *(unsigned char **)raw_data; mask_byte = 0; mask_bit = 7; for (y = 0; y < icon_data[i].size; y++) { for (x = 0; x < icon_data[i].size; x++) { if (geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]) >= 0xfd) mask_byte |= (1 << mask_bit); mask_bit--; if (mask_bit < 0) { *data++ = mask_byte; mask_byte = 0; mask_bit = 7; } } } memcpy(*raw_data + size, *raw_data, size); if (SetIconFamilyData(icon_family, icon_data[i].mask1, raw_data) != noErr) { DisposeHandle(raw_data); fprintf(stderr, "Error setting %dx%d icon resource 1bit mask\n", icon_data[i].size, icon_data[i].size); result = -1; goto exit_error_bundle; } DisposeHandle(raw_data); } } } f = pack_fopen(bundle_icns, F_WRITE); if (!f) { fprintf(stderr, "Cannot create %s\n", bundle_icns); result = -1; goto exit_error_bundle; } pack_fclose(f); cf_url_ref = CFURLCreateWithBytes(kCFAllocatorDefault, (unsigned char *)bundle_icns, strlen(bundle_icns), 0, NULL); if (!cf_url_ref) { fprintf(stderr, "Cannot create %s\n", bundle_icns); result = -1; goto exit_error_bundle; } CFURLGetFSRef(cf_url_ref, &fs_ref); CFRelease(cf_url_ref); if ((FSGetCatalogInfo(&fs_ref, kFSCatInfoNone, NULL, NULL, &fs_spec, NULL)) || (WriteIconFile(icon_family, &fs_spec) != noErr)) { fprintf(stderr, "Cannot create %s\n", bundle_icns); result = -1; goto exit_error_bundle; } DisposeHandle((Handle)icon_family); } /* Setup Info.plist */ sprintf(bundle_plist, "%s/Info.plist", bundle_contents_dir); f = pack_fopen(bundle_plist, F_WRITE); if (!f) { fprintf(stderr, "Cannot create %s\n", bundle_plist); result = -1; goto exit_error_bundle; } sprintf(buffer, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" "<plist version=\"1.0\">\n" "<dict>\n" "\t<key>CFBundleExecutable</key>\n" "\t<string>%s</string>\n" "\t<key>CFBundleInfoDictionaryVersion</key>\n" "\t<string>6.0</string>\n" "\t<key>CFBundlePackageType</key>\n" "\t<string>APPL</string>\n" "\t<key>CFBundleSignature</key>\n" "\t<string>%s</string>\n" "\t<key>CFBundleVersion</key>\n" "\t<string>%s</string>\n" "\t<key>CFBundleDocumentTypes</key>\n" "\t<array>\n" "\t\t<dict>\n" "\t\t\t<key>CFBundleTypeExtensions</key>\n" "\t\t\t<array>\n" "\t\t\t\t<string>*</string>\n" "\t\t\t</array>\n" "\t\t\t<key>CFBundleTypeName</key>\n" "\t\t\t<string>NSStringPboardType</string>\n" "\t\t\t<key>CFBundleTypeOSTypes</key>\n" "\t\t\t<array>\n" "\t\t\t\t<string>****</string>\n" "\t\t\t</array>\n" "\t\t\t<key>CFBundleTypeRole</key>\n" "\t\t\t<string>Viewer</string>\n" "\t\t</dict>\n" "\t</array>\n", get_filename(bundle_exe), "????", (flags & F_GOT_VERSION) ? bundle_version : "1.0"); pack_fputs(buffer, f); if (flags & F_GOT_LONG_VERSION) { sprintf(buffer, "\t<key>CFBundleGetInfoString</key>\n" "\t<string>%s</string>\n", bundle_long_version); pack_fputs(buffer, f); } if (flags & F_ICONS_DEFINED) { sprintf(buffer, "\t<key>CFBundleIconFile</key>\n" "\t<string>%s</string>\n", get_filename(bundle_icns)); pack_fputs(buffer, f); } pack_fputs("</dict>\n</plist>\n", f); pack_fclose(f); /* Setup PkgInfo */ sprintf(bundle_pkginfo, "%s/PkgInfo", bundle_contents_dir); f = pack_fopen(bundle_pkginfo, F_WRITE); if (!f) { fprintf(stderr, "Cannot create %s\n", bundle_pkginfo); result = -1; goto exit_error_bundle; } pack_fputs("APPL????", f); pack_fclose(f); exit_error: if (buffer) free(buffer); for (i = 0; i < 4; i++) { if (icon_data[i].original) destroy_bitmap(icon_data[i].original); if (icon_data[i].workspace) destroy_bitmap(icon_data[i].workspace); if (icon_data[i].scaled) destroy_bitmap(icon_data[i].scaled); } return result; exit_error_bundle: sprintf(buffer, "%s/%s", bundle_contents_macos_dir, get_filename(bundle_exe)); unlink(buffer); unlink(bundle_plist); unlink(bundle_pkginfo); unlink(bundle_icns); rmdir(bundle_dir); rmdir(bundle_contents_dir); rmdir(bundle_contents_resources_dir); rmdir(bundle_contents_macos_dir); goto exit_error; }