diff options
Diffstat (limited to 'pkg/osx')
25 files changed, 1732 insertions, 0 deletions
diff --git a/pkg/osx/.gitignore b/pkg/osx/.gitignore new file mode 100644 index 00000000..ca1a7908 --- /dev/null +++ b/pkg/osx/.gitignore @@ -0,0 +1,7 @@ +Info.plist +Info-gnustep.plist +launcher +*.o +*.d +*.dmg +staging diff --git a/pkg/osx/AppController.h b/pkg/osx/AppController.h new file mode 100644 index 00000000..88b59043 --- /dev/null +++ b/pkg/osx/AppController.h @@ -0,0 +1,53 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#ifndef LAUNCHER_APPCONTROLLER_H +#define LAUNCHER_APPCONTROLLER_H + +#include <AppKit/AppKit.h> + +#include "LauncherManager.h" + +@interface AppController : NSObject +{ + LauncherManager *launcherManager; + BOOL filesAdded; +} + ++ (void)initialize; + +- (id)init; +- (void)dealloc; + +- (void)awakeFromNib; + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotif; +- (BOOL)applicationShouldTerminate:(id)sender; +- (void)applicationWillTerminate:(NSNotification *)aNotif; +- (BOOL)application:(NSApplication *)application openFile:(NSString *)fileName; + +- (void)showPrefPanel:(id)sender; + +@end + +#endif + diff --git a/pkg/osx/AppController.m b/pkg/osx/AppController.m new file mode 100644 index 00000000..a26a7c9e --- /dev/null +++ b/pkg/osx/AppController.m @@ -0,0 +1,124 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#include "AppController.h" + +#include "config.h" + +@implementation AppController + ++ (void)initialize +{ + NSMutableDictionary *defaults = [NSMutableDictionary dictionary]; + + /* + * Register your app's defaults here by adding objects to the + * dictionary, eg + * + * [defaults setObject:anObject forKey:keyForThatObject]; + * + */ + + [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (id)init +{ + if ((self = [super init])) + { + } + + self->filesAdded = NO; + + return self; +} + +- (void)dealloc +{ + [super dealloc]; +} + +- (void)awakeFromNib +{ + [[NSApp mainMenu] setTitle:@PACKAGE_NAME]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotif +{ +// Uncomment if your application is Renaissance-based +// [NSBundle loadGSMarkupNamed:@"Main" owner:self]; +} + +- (BOOL)applicationShouldTerminate:(id)sender +{ + return YES; +} + +- (void)applicationWillTerminate:(NSNotification *)aNotif +{ +} + +- (BOOL) application:(NSApplication *) application + openFile:(NSString *) fileName +{ + NSString *extension; + + // If this is the first file added, clear out the existing + // command line. This allows us to select multiple files + // in the finder and open them all together (for TCs, etc). + + if (!self->filesAdded) + { + [self->launcherManager clearCommandLine]; + } + + // Add file with appropriate command line option based on extension: + + extension = [fileName pathExtension]; + + if (![extension caseInsensitiveCompare: @"wad"]) + { + [self->launcherManager addFileToCommandLine: fileName + forArgument: @"-merge"]; + } + else if (![extension caseInsensitiveCompare: @"deh"]) + { + [self->launcherManager addFileToCommandLine: fileName + forArgument: @"-deh"]; + } + else + { + return NO; + } + + self->filesAdded = YES; + + return YES; +} + +- (void)showPrefPanel:(id)sender +{ +} + +@end + diff --git a/pkg/osx/Execute.h b/pkg/osx/Execute.h new file mode 100644 index 00000000..2098be8a --- /dev/null +++ b/pkg/osx/Execute.h @@ -0,0 +1,31 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#ifndef LAUNCHER_EXECUTE_H +#define LAUNCHER_EXECUTE_H + +void SetProgramLocation(const char *path); +void ExecuteProgram(const char *executable, const char *iwad, const char *args); +void OpenTerminalWindow(const char *doomwadpath); + +#endif /* #ifndef LAUNCHER_EXECUTE_H */ + diff --git a/pkg/osx/Execute.m b/pkg/osx/Execute.m new file mode 100644 index 00000000..608443e2 --- /dev/null +++ b/pkg/osx/Execute.m @@ -0,0 +1,208 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <AppKit/AppKit.h> + +#include "config.h" + +#define RESPONSE_FILE "/tmp/launcher.rsp" +#define TEMP_SCRIPT "/tmp/tempscript.sh" + +static char *executable_path; + +// Called on startup to save the location of the launcher program +// (within a package, other executables should be in the same directory) + +void SetProgramLocation(const char *path) +{ + char *p; + + executable_path = strdup(path); + + p = strrchr(executable_path, '/'); + *p = '\0'; +} + +// Write out the response file containing command line arguments. + +static void WriteResponseFile(const char *iwad, const char *args) +{ + FILE *fstream; + + fstream = fopen(RESPONSE_FILE, "w"); + + if (iwad != NULL) + { + fprintf(fstream, "-iwad \"%s\"", iwad); + } + + if (args != NULL) + { + fprintf(fstream, "%s", args); + } + + fclose(fstream); +} + +static void DoExec(const char *executable, const char *iwad, const char *args) +{ + char *argv[3]; + + argv[0] = malloc(strlen(executable_path) + strlen(executable) + 3); + sprintf(argv[0], "%s/%s", executable_path, executable); + + if (iwad != NULL || args != NULL) + { + WriteResponseFile(iwad, args); + + argv[1] = "@" RESPONSE_FILE; + argv[2] = NULL; + } + else + { + argv[1] = NULL; + } + + execv(argv[0], argv); + exit(-1); +} + +// Execute the specified executable contained in the same directory +// as the launcher, with the specified arguments. + +void ExecuteProgram(const char *executable, const char *iwad, const char *args) +{ + pid_t childpid; + char *homedir; + + childpid = fork(); + + if (childpid == 0) + { + signal(SIGCHLD, SIG_DFL); + + // Change directory to home dir before launch, so that any demos + // are saved somewhere sensible. + + homedir = getenv("HOME"); + + if (homedir != NULL) + { + chdir(homedir); + } + + DoExec(executable, iwad, args); + } + else + { + signal(SIGCHLD, SIG_IGN); + } +} + +// Write a sequence of commands that will display the specified message +// via shell commands. + +static void WriteMessage(FILE *script, char *msg) +{ + char *p; + + fprintf(script, "echo \""); + + for (p=msg; *p != '\0'; ++p) + { + // Start new line? + + if (*p == '\n') + { + fprintf(script, "\"\necho \""); + continue; + } + + // Escaped character? + + if (*p == '\\' || *p == '\"') + { + fprintf(script, "\\"); + } + + fprintf(script, "%c", *p); + } + + fprintf(script, "\"\n"); +} + +// Open a terminal window with the PATH set appropriately, and DOOMWADPATH +// set to the specified value. + +void OpenTerminalWindow(const char *doomwadpath) +{ + FILE *stream; + + // Generate a shell script that sets the PATH to include the location + // where the Doom binaries are, and DOOMWADPATH to include the + // IWAD files that have been configured in the launcher interface. + // The script then deletes itself and starts a shell. + + stream = fopen(TEMP_SCRIPT, "w"); + + fprintf(stream, "#!/bin/sh\n"); + //fprintf(stream, "set -x\n"); + fprintf(stream, "PATH=\"%s:$PATH\"\n", executable_path); + fprintf(stream, "DOOMWADPATH=\"%s\"\n", doomwadpath); + fprintf(stream, "export DOOMWADPATH\n"); + fprintf(stream, "rm -f \"%s\"\n", TEMP_SCRIPT); + + // Display a useful message: + + fprintf(stream, "clear\n"); + WriteMessage(stream, + "\n" + "This command line has the PATH variable configured so that you may\n" + "launch the game with whatever parameters you desire.\n" + "\n" + "For example:\n" + "\n" + " " PACKAGE_TARNAME " -iwad doom2.wad -file sid.wad -warp 1\n" + "\n" + "Type 'exit' to exit.\n"); + + fprintf(stream, "exec $SHELL\n"); + fprintf(stream, "\n"); + + fclose(stream); + + chmod(TEMP_SCRIPT, 0755); + + // Tell the terminal to open a window to run the script. + + [[NSWorkspace sharedWorkspace] openFile: @TEMP_SCRIPT + withApplication: @"Terminal"]; +} + diff --git a/pkg/osx/GNUmakefile b/pkg/osx/GNUmakefile new file mode 100644 index 00000000..d119efa1 --- /dev/null +++ b/pkg/osx/GNUmakefile @@ -0,0 +1,101 @@ + +# Makefile for building the OS X launcher program and DMG package. +# It is also possible to build and run the launcher under Unix +# systems using GNUstep, although this is only here for development +# and debugging purposes. + +include ../config.make + +STAGING_DIR=staging +DMG=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).dmg + +TOPLEVEL=../.. +TOPLEVEL_DOCS=$(patsubst %,../../%,$(DOC_FILES)) + +ifndef GNUSTEP_MAKEFILES + +# DMG file containing package: + +$(DMG) : $(STAGING_DIR) + rm -f $@ + hdiutil create -volname "$(PACKAGE_STRING)" -srcdir $(STAGING_DIR) $@ + +endif + +# Staging dir build for package: + +APP_DIR=$(STAGING_DIR)/$(PACKAGE_NAME).app + +# OS X and GNUstep apps have a slightly different internal structure: +# OS X apps have their files within a containing "Contents" directory +# that does not exist in GNUstep apps. Similarly, the binaries are +# installed at the top level, rather than in a "MacOS" directory. +# Finally, we must install a different Info.plist file. + +ifdef GNUSTEP_MAKEFILES +APP_TOP_DIR=$(APP_DIR) +APP_BIN_DIR=$(APP_DIR) +SRC_INFO_PLIST=Info-gnustep.plist +else +APP_TOP_DIR=$(APP_DIR)/Contents +APP_BIN_DIR=$(APP_DIR)/Contents/MacOS +SRC_INFO_PLIST=Info.plist +endif + +$(STAGING_DIR): launcher $(TOPLEVEL_DOCS) + rm -rf $(STAGING_DIR) + mkdir $(STAGING_DIR) + + cp $(TOPLEVEL_DOCS) "$(STAGING_DIR)" + + mkdir -p "$(APP_TOP_DIR)" + cp -R Resources "$(APP_TOP_DIR)" + cp PkgInfo "$(APP_TOP_DIR)" + cp $(SRC_INFO_PLIST) "$(APP_TOP_DIR)" + + mkdir -p "$(APP_BIN_DIR)" + + cp launcher "$(APP_BIN_DIR)" + $(STRIP) "$(APP_BIN_DIR)/launcher" + + ./cp-with-libs $(TOPLEVEL)/src/$(PACKAGE_TARNAME) "$(APP_BIN_DIR)" + $(STRIP) "$(APP_BIN_DIR)/$(PACKAGE_TARNAME)" + ./cp-with-libs $(TOPLEVEL)/setup/chocolate-setup "$(APP_BIN_DIR)" + $(STRIP) "$(APP_BIN_DIR)/chocolate-setup" + + find $(STAGING_DIR) -name .svn -delete -exec rm -rf {} \; || true + +clean : launcher_clean + rm -f $(DMG) + rm -rf $(STAGING_DIR) + +# Launcher build: + +CFLAGS = -Wall -I$(TOPLEVEL) + +# Are we building using gs_make? + +ifdef GNUSTEP_MAKEFILES +CFLAGS += $(shell gnustep-config --objc-flags) +LDFLAGS = $(shell gnustep-config --gui-libs) +else +LDFLAGS = -framework Cocoa +endif + +LAUNCHER_OBJS= \ + AppController.o \ + Execute.o \ + IWADController.o \ + IWADLocation.o \ + LauncherManager.o \ + main.o + +launcher : $(LAUNCHER_OBJS) + $(CC) $(LDFLAGS) $(LAUNCHER_OBJS) -o $@ + +%.o : %.m + $(CC) -c $(CFLAGS) $^ -o $@ + +launcher_clean : + rm -f $(LAUNCHER_OBJS) launcher + diff --git a/pkg/osx/IWADController.h b/pkg/osx/IWADController.h new file mode 100644 index 00000000..90f44667 --- /dev/null +++ b/pkg/osx/IWADController.h @@ -0,0 +1,54 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#ifndef LAUNCHER_IWADCONTROLLER_H +#define LAUNCHER_IWADCONTROLLER_H + +#include <AppKit/AppKit.h> +#include <AppKit/NSNibLoading.h> + +@interface IWADController : NSObject +{ + id iwadSelector; + id configWindow; + + id chex; + id doom1; + id doom2; + id plutonia; + id tnt; +} + +- (void) closeConfigWindow: (id)sender; +- (void) openConfigWindow: (id)sender; +- (NSString *) getIWADLocation; +- (void) awakeFromNib; +- (BOOL) setDropdownList; +- (void) setDropdownSelection; +- (void) saveConfig; +- (char *) doomWadPath; +- (void) setEnvironment; + +@end + +#endif /* #ifndef LAUNCHER_IWADCONTROLLER_H */ + diff --git a/pkg/osx/IWADController.m b/pkg/osx/IWADController.m new file mode 100644 index 00000000..3c596850 --- /dev/null +++ b/pkg/osx/IWADController.m @@ -0,0 +1,347 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#include <stdlib.h> +#include <string.h> +#include <AppKit/AppKit.h> +#include "IWADController.h" +#include "IWADLocation.h" + +typedef enum +{ + IWAD_DOOM1, + IWAD_DOOM2, + IWAD_TNT, + IWAD_PLUTONIA, + IWAD_CHEX, + NUM_IWAD_TYPES +} IWAD; + +static NSString *IWADLabels[NUM_IWAD_TYPES] = +{ + @"Doom", + @"Doom II: Hell on Earth", + @"Final Doom: TNT: Evilution", + @"Final Doom: Plutonia Experiment", + @"Chex Quest" +}; + +static NSString *IWADFilenames[NUM_IWAD_TYPES + 1] = +{ + @"doom.wad", + @"doom2.wad", + @"tnt.wad", + @"plutonia.wad", + @"chex.wad", + @"undefined" +}; + +@implementation IWADController + +- (void) getIWADList: (IWADLocation **) iwadList +{ + iwadList[IWAD_DOOM1] = self->doom1; + iwadList[IWAD_DOOM2] = self->doom2; + iwadList[IWAD_TNT] = self->tnt; + iwadList[IWAD_PLUTONIA] = self->plutonia; + iwadList[IWAD_CHEX] = self->chex; +} + +- (IWAD) getSelectedIWAD +{ + unsigned int i; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + if ([self->iwadSelector titleOfSelectedItem] == IWADLabels[i]) + { + return i; + } + } + + return NUM_IWAD_TYPES; +} + +// Get the location of the selected IWAD. + +- (NSString *) getIWADLocation +{ + IWAD selectedIWAD; + IWADLocation *iwadList[NUM_IWAD_TYPES]; + + selectedIWAD = [self getSelectedIWAD]; + + if (selectedIWAD == NUM_IWAD_TYPES) + { + return nil; + } + else + { + [self getIWADList: iwadList]; + + return [iwadList[selectedIWAD] getLocation]; + } +} + +- (void) setIWADConfig +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + NSUserDefaults *defaults; + NSString *key; + NSString *value; + unsigned int i; + + [self getIWADList: iwadList]; + + // Load IWAD filename paths + + defaults = [NSUserDefaults standardUserDefaults]; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + key = IWADFilenames[i]; + value = [defaults stringForKey:key]; + + if (value != nil) + { + [iwadList[i] setLocation:value]; + } + } +} + +// On startup, set the selected item in the IWAD dropdown + +- (void) setDropdownSelection +{ + NSUserDefaults *defaults; + NSString *selected; + unsigned int i; + + defaults = [NSUserDefaults standardUserDefaults]; + selected = [defaults stringForKey: @"selected_iwad"]; + + if (selected == nil) + { + return; + } + + // Find this IWAD in the filenames list, and select it. + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + if ([selected isEqualToString:IWADFilenames[i]]) + { + [self->iwadSelector selectItemWithTitle:IWADLabels[i]]; + break; + } + } +} + +// Set the dropdown list to include an entry for each IWAD that has +// been configured. Returns true if at least one IWAD is configured. + +- (BOOL) setDropdownList +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + BOOL have_wads; + id location; + unsigned int i; + unsigned int enabled_wads; + + // Build the new list. + + [self getIWADList: iwadList]; + [self->iwadSelector removeAllItems]; + + enabled_wads = 0; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + location = [iwadList[i] getLocation]; + + if (location != nil && [location length] > 0) + { + [self->iwadSelector addItemWithTitle: IWADLabels[i]]; + ++enabled_wads; + } + } + + // Enable/disable the dropdown depending on whether there + // were any configured IWADs. + + have_wads = enabled_wads > 0; + [self->iwadSelector setEnabled: have_wads]; + + // Restore the old selection. + + [self setDropdownSelection]; + + return have_wads; +} + +- (void) saveConfig +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + IWAD selectedIWAD; + NSUserDefaults *defaults; + NSString *key; + NSString *value; + unsigned int i; + + [self getIWADList: iwadList]; + + // Store all IWAD locations to user defaults. + + defaults = [NSUserDefaults standardUserDefaults]; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + key = IWADFilenames[i]; + value = [iwadList[i] getLocation]; + + [defaults setObject:value forKey:key]; + } + + // Save currently selected IWAD. + + selectedIWAD = [self getSelectedIWAD]; + [defaults setObject:IWADFilenames[selectedIWAD] + forKey:@"selected_iwad"]; +} + +// Callback method invoked when the configuration button in the main +// window is clicked. + +- (void) openConfigWindow: (id)sender +{ + if (![self->configWindow isVisible]) + { + [self->configWindow makeKeyAndOrderFront: sender]; + } +} + +// Callback method invoked when the close button is clicked. + +- (void) closeConfigWindow: (id)sender +{ + [self->configWindow orderOut: sender]; + [self saveConfig]; + [self setDropdownList]; +} + +- (void) awakeFromNib +{ + [self->configWindow center]; + + // Set configuration for all IWADs from configuration file. + + [self setIWADConfig]; + + // Populate the dropdown IWAD list. + + if ([self setDropdownList]) + { + [self setDropdownSelection]; + } +} + +// Generate a value to set for the DOOMWADPATH environment variable +// that contains each of the configured IWAD files. + +- (char *) doomWadPath +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + NSString *location; + unsigned int i; + unsigned int len; + BOOL first; + char *env; + + [self getIWADList: iwadList]; + + // Calculate length of environment string. + + len = 0; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + location = [iwadList[i] getLocation]; + + if (location != nil && [location length] > 0) + { + len += [location length] + 1; + } + } + + // Build string. + + env = malloc(len); + strcpy(env, ""); + + first = YES; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + location = [iwadList[i] getLocation]; + + if (location != nil && [location length] > 0) + { + if (!first) + { + strcat(env, ":"); + } + + strcat(env, [location UTF8String]); + first = NO; + } + } + + return env; +} + +// Set the DOOMWADPATH environment variable to contain the path to each +// of the configured IWAD files. + +- (void) setEnvironment +{ + char *doomwadpath; + char *env; + + // Get the value for the path. + + doomwadpath = [self doomWadPath]; + + env = malloc(strlen(doomwadpath) + 15); + + sprintf(env, "DOOMWADPATH=%s", doomwadpath); + + free(doomwadpath); + + // Load into environment: + + putenv(env); + + //free(env); +} + +@end + diff --git a/pkg/osx/IWADLocation.h b/pkg/osx/IWADLocation.h new file mode 100644 index 00000000..4ddfebc2 --- /dev/null +++ b/pkg/osx/IWADLocation.h @@ -0,0 +1,44 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#ifndef LAUNCHER_IWADLOCATION_H +#define LAUNCHER_IWADLOCATION_H + +#include <AppKit/AppKit.h> + +#include "IWADController.h" + +@interface IWADLocation : NSObject +{ + IWADController *iwadController; + + id locationConfigBox; +} + +- (void) setButtonClicked: (id)sender; +- (NSString *) getLocation; +- (void) setLocation: (NSString *) value; + +@end + +#endif /* #ifndef LAUNCHER_IWADLOCATION_H */ + diff --git a/pkg/osx/IWADLocation.m b/pkg/osx/IWADLocation.m new file mode 100644 index 00000000..3f2ac188 --- /dev/null +++ b/pkg/osx/IWADLocation.m @@ -0,0 +1,74 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#include <AppKit/AppKit.h> +#include "IWADLocation.h" + +static id WAD_TYPES[] = +{ + @"wad", @"WAD" +}; + +@implementation IWADLocation + +- (void) setButtonClicked: (id)sender +{ + NSArray *wadTypes = [NSArray arrayWithObjects: WAD_TYPES count: 2]; + NSOpenPanel *openPanel; + NSArray *filenames; + int result; + + [wadTypes retain]; + + // Open a file selector for the new file. + + openPanel = [NSOpenPanel openPanel]; + [openPanel setTitle: @"Add IWAD file"]; + [openPanel setCanChooseFiles: YES]; + [openPanel setCanChooseDirectories: NO]; + + result = [openPanel runModalForTypes: wadTypes]; + + // If the "OK" button was clicked, add the new IWAD file to the list. + + if (result == NSOKButton) + { + filenames = [openPanel filenames]; + [self setLocation: [filenames lastObject]]; + + [self->iwadController saveConfig]; + [self->iwadController setDropdownList]; + } +} + +- (NSString *) getLocation +{ + return [self->locationConfigBox stringValue]; +} + +- (void) setLocation: (NSString *) filename +{ + [self->locationConfigBox setStringValue: filename]; +} + +@end + diff --git a/pkg/osx/Info-gnustep.plist.in b/pkg/osx/Info-gnustep.plist.in new file mode 100644 index 00000000..da6675ba --- /dev/null +++ b/pkg/osx/Info-gnustep.plist.in @@ -0,0 +1,36 @@ +{ + ApplicationName = "@PACKAGE_NAME@"; + ApplicationDescription = "@PACKAGE_SHORTDESC@"; + ApplicationIcon = app.png; + ApplicationRelease = @PACKAGE_VERSION@; + ApplicationURL = "@PACKAGE_URL@"; + Authors = ( + "@PACKAGE_MAINTAINER@ <@PACKAGE_BUGREPORT@>" + ); + Copyright = "@PACKAGE_COPYRIGHT@"; + CopyrightDescription = "@PACKAGE_LICENSE@"; + FullVersionID = @PACKAGE_VERSION@; + GSMainMarkupFile = ""; + NSExecutable = "launcher"; + NSIcon = app.png; + NSMainNibFile = launcher.nib; + NSPrincipalClass = NSApplication; + NSRole = Application; + NSTypes = ( + { + NSHumanReadableName = "Doom WAD file"; + NSUnixExtensions = ( wad ); + NSRole = Viewer; + NSMimeTypes = ( + "application/x-doom" + ); + NSIcon = "wadfile.png"; + }, + { + NSHumanReadableName = "Dehacked patch"; + NSUnixExtensions = ( deh ); + NSRole = Viewer; + NSIcon = "wadfile.png"; + } + ); +} diff --git a/pkg/osx/Info.plist.in b/pkg/osx/Info.plist.in new file mode 100644 index 00000000..8b8436f7 --- /dev/null +++ b/pkg/osx/Info.plist.in @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleDisplayName</key> + <string>@PACKAGE_NAME@</string> + <key>CFBundleExecutable</key> + <string>launcher</string> + <key>CFBundleGetInfoString</key> + <string>@PACKAGE_STRING@</string> + <key>CFBundleIconFile</key> + <string>app.icns</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>@PACKAGE_NAME@</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>@PACKAGE_VERSION@</string> + <key>CFBundleVersion</key> + <string>@PACKAGE_VERSION@</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> + <key>NSMainNibFile</key> + <string>launcher</string> + + <!-- file associations: --> + + <key>CFBundleDocumentTypes</key> + <array> + <dict> + <key>CFBundleTypeName</key> + <string>Doom WAD file</string> + <key>CFBundleTypeIconFile</key> + <string>wadfile.icns</string> + <key>CFBundleTypeRole</key> + <string>Viewer</string> + <key>CFBundleTypeExtensions</key> + <array> + <string>wad</string> + </array> + </dict> + <dict> + <key>CFBundleTypeName</key> + <string>Dehacked patch</string> + <key>CFBundleTypeIconFile</key> + <string>wadfile.icns</string> + <key>CFBundleTypeRole</key> + <string>Viewer</string> + <key>CFBundleTypeExtensions</key> + <array> + <string>deh</string> + </array> + </dict> + </array> +</dict> +</plist> diff --git a/pkg/osx/LauncherManager.h b/pkg/osx/LauncherManager.h new file mode 100644 index 00000000..e454ab4f --- /dev/null +++ b/pkg/osx/LauncherManager.h @@ -0,0 +1,52 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#ifndef LAUNCHER_LAUNCHERMANAGER_H +#define LAUNCHER_LAUNCHERMANAGER_H + +#include <AppKit/AppKit.h> +#include <AppKit/NSNibLoading.h> +#include "IWADController.h" + +@interface LauncherManager : NSObject +{ + IWADController *iwadController; + + id launcherWindow; + id launchButton; + + id commandLineArguments; + id packageLabel; +} + +- (void) launch: (id)sender; +- (void) runSetup: (id)sender; +- (void) awakeFromNib; +- (void) clearCommandLine; +- (void) addFileToCommandLine: (NSString *) fileName + forArgument: (NSString *) args; +- (void) openTerminal: (id) sender; + +@end + +#endif /* #ifndef LAUNCHER_LAUNCHERMANAGER_H */ + diff --git a/pkg/osx/LauncherManager.m b/pkg/osx/LauncherManager.m new file mode 100644 index 00000000..ae91ef4d --- /dev/null +++ b/pkg/osx/LauncherManager.m @@ -0,0 +1,338 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#include <AppKit/AppKit.h> +#include "Execute.h" +#include "LauncherManager.h" +#include "config.h" + +@implementation LauncherManager + +// Save configuration. Invoked when we launch the game or quit. + +- (void) saveConfig +{ + NSUserDefaults *defaults; + + // Save IWAD configuration and selected IWAD. + + [self->iwadController saveConfig]; + + // Save command line arguments. + + defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:[self->commandLineArguments stringValue] + forKey:@"command_line_args"]; +} + +// Load configuration, invoked on startup. + +- (void) setConfig +{ + NSUserDefaults *defaults; + NSString *args; + + defaults = [NSUserDefaults standardUserDefaults]; + + args = [defaults stringForKey:@"command_line_args"]; + + if (args != nil) + { + [self->commandLineArguments setStringValue:args]; + } +} + +// Get the next command line argument from the command line. +// The position counter used to iterate over arguments is in 'pos'. +// The index of the argument that was found is saved in arg_pos. + +static NSString *GetNextArgument(NSString *commandLine, int *pos, int *arg_pos) +{ + NSRange arg_range; + + // Skip past any whitespace + + while (*pos < [commandLine length] + && isspace([commandLine characterAtIndex: *pos])) + { + ++*pos; + } + + if (*pos >= [commandLine length]) + { + *arg_pos = *pos; + return nil; + } + + // We are at the start of the argument. This may be a quoted + // string argument, or a "normal" one. + + if ([commandLine characterAtIndex: *pos] == '\"') + { + // Quoted string, skip past first quote + + ++*pos; + + // Save start position: + + *arg_pos = *pos; + + while (*pos < [commandLine length] + && [commandLine characterAtIndex: *pos] != '\"') + { + ++*pos; + } + + // Unexpected end of string? + + if (*pos >= [commandLine length]) + { + return nil; + } + + arg_range = NSMakeRange(*arg_pos, *pos - *arg_pos); + + // Skip past last quote + + ++*pos; + } + else + { + // Normal argument + + // Save position: + + *arg_pos = *pos; + + // Read until end: + + while (*pos < [commandLine length] + && !isspace([commandLine characterAtIndex: *pos])) + { + ++*pos; + } + + arg_range = NSMakeRange(*arg_pos, *pos - *arg_pos); + } + + return [commandLine substringWithRange: arg_range]; +} + +// Given the specified command line argument, find the index +// to insert the new file within the command line. Returns -1 if the +// argument is not already within the arguments string. + +static int GetFileInsertIndex(NSString *commandLine, NSString *needle) +{ + NSString *arg; + int arg_pos; + int pos; + + pos = 0; + + // Find the command line parameter we are searching + // for (-merge, -deh, etc) + + for (;;) + { + arg = GetNextArgument(commandLine, &pos, &arg_pos); + + // Searched to end of string and never found? + + if (arg == nil) + { + return -1; + } + + if (![arg caseInsensitiveCompare: needle]) + { + break; + } + } + + // Now skip over existing files. For example, if we + // have -file foo.wad bar.wad, the new file should be appended + // to the end of the list. + + for (;;) + { + arg = GetNextArgument(commandLine, &pos, &arg_pos); + + // If we search to the end of the string now, it is fine; + // the new string should be added to the end of the command + // line. Otherwise, if we find an argument that begins + // with '-', it is a new command line parameter and the end + // of the list. + + if (arg == nil || [arg characterAtIndex: 0] == '-') + { + break; + } + } + + // arg_pos should now contain the offset to insert the new filename. + + return arg_pos; +} + +// Given the specified string, append a filename, quoted if necessary. + +static NSString *AppendQuotedFilename(NSString *str, NSString *fileName) +{ + int i; + + // Search the filename for spaces, and quote if necessary. + + for (i=0; i<[fileName length]; ++i) + { + if (isspace([fileName characterAtIndex: i])) + { + str = [str stringByAppendingString: @" \""]; + str = [str stringByAppendingString: fileName]; + str = [str stringByAppendingString: @"\" "]; + + return str; + } + } + + str = [str stringByAppendingString: @" "]; + str = [str stringByAppendingString: fileName]; + + return str; +} + +// Clear out the existing command line options. +// Invoked before the first file is added. + +- (void) clearCommandLine +{ + [self->commandLineArguments setStringValue: @""]; +} + +// Add a file to the command line to load with the game. + +- (void) addFileToCommandLine: (NSString *) fileName + forArgument: (NSString *) arg +{ + NSString *commandLine; + int insert_pos; + + // Get the current command line + + commandLine = [self->commandLineArguments stringValue]; + + // Find the location to insert the new filename: + + insert_pos = GetFileInsertIndex(commandLine, arg); + + // If position < 0, we should add the new argument and filename + // to the end. Otherwise, append the new filename to the existing + // list of files. + + if (insert_pos < 0) + { + commandLine = [commandLine stringByAppendingString: @" "]; + commandLine = [commandLine stringByAppendingString: arg]; + commandLine = AppendQuotedFilename(commandLine, fileName); + } + else + { + NSString *start; + NSString *end; + + // Divide existing command line in half: + + start = [commandLine substringToIndex: insert_pos]; + end = [commandLine substringFromIndex: insert_pos]; + + // Construct new command line: + + commandLine = AppendQuotedFilename(start, fileName); + commandLine = [commandLine stringByAppendingString: @" "]; + commandLine = [commandLine stringByAppendingString: end]; + } + + [self->commandLineArguments setStringValue: commandLine]; +} + +- (void) launch: (id)sender +{ + NSString *iwad; + NSString *args; + + [self saveConfig]; + + iwad = [self->iwadController getIWADLocation]; + args = [self->commandLineArguments stringValue]; + + if (iwad == nil) + { + NSRunAlertPanel(@"No IWAD selected", + @"You have not selected an IWAD (game) file.\n\n" + "You must configure and select a valid IWAD file " + "in order to launch the game.", + @"OK", nil, nil); + return; + } + + ExecuteProgram(PACKAGE_TARNAME, [iwad UTF8String], + [args UTF8String]); + [NSApp terminate:sender]; +} + +// Invoked when the "Setup Tool" button is clicked, to run the setup tool: + +- (void) runSetup: (id)sender +{ + [self saveConfig]; + + [self->iwadController setEnvironment]; + ExecuteProgram("chocolate-setup", NULL, NULL); +} + +// Invoked when the "Terminal" option is selected from the menu, to open +// a terminal window. + +- (void) openTerminal: (id) sender +{ + char *doomwadpath; + + [self saveConfig]; + + doomwadpath = [self->iwadController doomWadPath]; + + OpenTerminalWindow(doomwadpath); + + free(doomwadpath); +} + +- (void) awakeFromNib +{ + [self->packageLabel setStringValue: @PACKAGE_STRING]; + [self->launcherWindow setTitle: @PACKAGE_NAME " Launcher"]; + [self->launcherWindow center]; + [self->launcherWindow setDefaultButtonCell: [self->launchButton cell]]; + [self setConfig]; +} + +@end + diff --git a/pkg/osx/PkgInfo b/pkg/osx/PkgInfo new file mode 100644 index 00000000..6f749b0f --- /dev/null +++ b/pkg/osx/PkgInfo @@ -0,0 +1 @@ +APPL???? diff --git a/pkg/osx/Resources/128x128.png b/pkg/osx/Resources/128x128.png Binary files differnew file mode 100644 index 00000000..0ef1fe9c --- /dev/null +++ b/pkg/osx/Resources/128x128.png diff --git a/pkg/osx/Resources/app.icns b/pkg/osx/Resources/app.icns Binary files differnew file mode 100644 index 00000000..9b535a25 --- /dev/null +++ b/pkg/osx/Resources/app.icns diff --git a/pkg/osx/Resources/app.png b/pkg/osx/Resources/app.png Binary files differnew file mode 100644 index 00000000..5b932e8c --- /dev/null +++ b/pkg/osx/Resources/app.png diff --git a/pkg/osx/Resources/launcher.nib/classes.nib b/pkg/osx/Resources/launcher.nib/classes.nib new file mode 100644 index 00000000..7efc837a --- /dev/null +++ b/pkg/osx/Resources/launcher.nib/classes.nib @@ -0,0 +1,47 @@ +{ + IBClasses = ( + { + CLASS = AppController; + LANGUAGE = ObjC; + OUTLETS = {launcherManager = id; }; + SUPERCLASS = NSObject; + }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + ACTIONS = {closeConfigWindow = id; openConfigWindow = id; }; + CLASS = IWADController; + LANGUAGE = ObjC; + OUTLETS = { + chex = id; + configWindow = id; + doom1 = id; + doom2 = id; + iwadSelector = id; + plutonia = id; + tnt = id; + }; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {setButtonClicked = id; }; + CLASS = IWADLocation; + LANGUAGE = ObjC; + OUTLETS = {locationConfigBox = id; }; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {launch = id; openTerminal = id; runSetup = id; }; + CLASS = LauncherManager; + LANGUAGE = ObjC; + OUTLETS = { + commandLineArguments = id; + iwadController = id; + launchButton = id; + launcherWindow = id; + packageLabel = id; + }; + SUPERCLASS = NSObject; + } + ); + IBVersion = 1; +}
\ No newline at end of file diff --git a/pkg/osx/Resources/launcher.nib/info.nib b/pkg/osx/Resources/launcher.nib/info.nib new file mode 100644 index 00000000..512ee6dd --- /dev/null +++ b/pkg/osx/Resources/launcher.nib/info.nib @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IBDocumentLocation</key> + <string>325 73 612 260 0 0 1440 878 </string> + <key>IBEditorPositions</key> + <dict> + <key>29</key> + <string>221 322 205 44 0 0 1440 878 </string> + </dict> + <key>IBFramework Version</key> + <string>446.1</string> + <key>IBOpenObjects</key> + <array> + <integer>29</integer> + <integer>21</integer> + <integer>227</integer> + </array> + <key>IBSystem Version</key> + <string>8S2167</string> +</dict> +</plist> diff --git a/pkg/osx/Resources/launcher.nib/keyedobjects.nib b/pkg/osx/Resources/launcher.nib/keyedobjects.nib Binary files differnew file mode 100644 index 00000000..cc763056 --- /dev/null +++ b/pkg/osx/Resources/launcher.nib/keyedobjects.nib diff --git a/pkg/osx/Resources/wadfile.icns b/pkg/osx/Resources/wadfile.icns Binary files differnew file mode 100644 index 00000000..13502a55 --- /dev/null +++ b/pkg/osx/Resources/wadfile.icns diff --git a/pkg/osx/Resources/wadfile.png b/pkg/osx/Resources/wadfile.png Binary files differnew file mode 100644 index 00000000..394a3e33 --- /dev/null +++ b/pkg/osx/Resources/wadfile.png diff --git a/pkg/osx/cp-with-libs b/pkg/osx/cp-with-libs new file mode 100755 index 00000000..04fb5bc6 --- /dev/null +++ b/pkg/osx/cp-with-libs @@ -0,0 +1,100 @@ +#!/bin/bash +# +# Copy a program to the specified destination, along +# with libraries it depends upon. + +src_bin=$1 +dest_dir=$2 + +# Returns true if the specified file is a dylib. + +is_dylib() { + case "$1" in + *.dylib) + true + ;; + *) + false + ;; + esac +} + +# Returns true if the specified file is in a system location +# (/System or /usr): + +is_sys_lib() { + case "$1" in + /System/*) + true + ;; + /usr/*) + true + ;; + *) + false + ;; + esac +} + +# Install the specified file to the location in dest_dir, along with +# any libraries it depends upon (recursively): + +install_with_deps() { + local src_file + local bin_name + local dest_file + local lib_name + + src_file=$1 + bin_name=$(basename "$src_file") + dest_file="$dest_dir/$bin_name" + + # Already copied into the package? Don't copy again. + # Prevents endless recursion. + + if [ -e "$dest_file" ]; then + return + fi + + echo "Installing $bin_name..." + + # Copy file into package. + + cp "$src_file" "$dest_file" + + # Copy libraries that this file depends on: + + otool -L "$src_file" | tail -n +2 | sed 's/^.//; s/ (.*//' | while read; do + + # Don't copy system libraries + + if is_sys_lib "$REPLY"; then + continue + fi + + #echo " - $bin_name depends on $REPLY" + + # Copy this library into the package, and: + # recursively install any libraries that _this_ library depends on: + + install_with_deps "$REPLY" + + # Change destination binary to depend on the + # copy inside the package: + + lib_name=$(basename "$REPLY") + install_name_tool -change "$REPLY" "@executable_path/$lib_name" \ + "$dest_file" + done + + # If this is a library that we have installed, change its id: + + if is_dylib "$dest_file"; then + install_name_tool -id "@executable_path/$bin_name" "$dest_file" + fi +} + +# Install the file, and recursively install any libraries: + +install_with_deps "$src_bin" + diff --git a/pkg/osx/main.m b/pkg/osx/main.m new file mode 100644 index 00000000..e3c70dc1 --- /dev/null +++ b/pkg/osx/main.m @@ -0,0 +1,32 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + +#include <AppKit/AppKit.h> +#include "Execute.h" + +int main(int argc, const char *argv[]) +{ + SetProgramLocation(argv[0]); + + return NSApplicationMain (argc, argv); +} + |