/*
Platypus - create MacOS X application bundles that execute scripts
This is the executable that goes into Platypus apps
Copyright (C) 2003 Sveinbjorn Thordarson <sveinbt@hi.is>
With modifications by Aaron Voisine for gimp.app
With modifications by Marianne gagnon for Wilber-loves-apple
With modifications by Michael Wybrow for Inkscape.app
With modifications by ~suv for Inkscape.app
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., 675 Mass Ave, Cambridge, MA 02139, USA.
main.c - main program file
*/
/*
* This app laucher basically takes care of:
* - launching Inkscape when double-clicked
* - bringing X11 to the top when its icon is clicked in the dock (via a small applescript)
* - catch file dropped on icon events (and double-clicked gimp documents) and notify gimp.
* - catch quit events performed outside gimp, e.g. on the dock icon.
*/
///////////////////////////////////////
// Includes
///////////////////////////////////////
// Apple stuff
// Note: including Carbon prevents building the launcher app in x86_64
// used for StandardAlert in RequestUserAttention(),
// RedFatalAlert()
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Authorization.h>
#include <Security/AuthorizationTags.h>
// Unix stuff
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
///////////////////////////////////////
// Definitions
///////////////////////////////////////
#pragma mark Definitions
// name length limits
// names of files bundled with app
// custom carbon event class
// custom carbon event types
//maximum arguments the script accepts
///////////////////////////////////////
// Prototypes
///////////////////////////////////////
#pragma mark Prototypes
static void GetParameters(void);
static unsigned char* GetScript(void);
static unsigned char* GetOpenDoc(void);
static short DoesFileExist(unsigned char *path);
AEDesc *resultData);
///////////////////////////////////////
// Globals
///////////////////////////////////////
// process id of forked process
// thread id of threads that start scripts
// indicator of whether the script has completed executing
short taskDone = true;
// execution parameters
//arguments to the script
short numArgs = 0;
extern char **environ;
#pragma mark -
///////////////////////////////////////
// Program entrance point
///////////////////////////////////////
{
InitCursor();
//install Apple Event handlers
0, false);
0, false);
0, false);
0, false);
"\pError initing Apple Event handlers.");
//create the menu bar
"\pError loading MenuBar.nib.");
GetParameters(); //load data from files containing exec settings
// compile "icon clicked" script so it's ready to execute
SimpleCompileAppleScript("tell application \"XQuartz\" to activate");
RunApplicationEventLoop(); //Run the event loop
return 0;
}
#pragma mark -
static void RequestUserAttention(void)
{
notificationRequest->nmIcon = 0;
notificationRequest->nmSound = 0;
}
static void ShowFirstStartWarningDialog(void)
{
params.helpButton = false;
"\pWhile Inkscape is open, its windows can be displayed or hidden by displaying or hiding the X11 application.\n\nThe first time this version of Inkscape is run it may take several minutes before the main window is displayed while font caches are built.",
}
//////////////////////////////////
// Handler for when fontconfig caches need to be generated
// TODO: remove (alert and touch moved to launcher script)
//////////////////////////////////
{
// Bounce Inkscape Dock icon
// Need to show warning to the user, then carry on.
// Note that we've seen the warning.
// Rerun now.
ExitToShell();
return noErr;
}
///////////////////////////////////
// Execution thread starts here
///////////////////////////////////
{
taskDone = false;
}
else ExitToShell();
return 0;
}
///////////////////////////////////
// Open additional documents thread starts here
///////////////////////////////////
{
return 0;
}
///////////////////////////////////////
// Run a script via the system command
///////////////////////////////////////
{
int status, i;
// Generate the array of argument strings before we do any executing
else if (*pid == 0) { //child process started
}
}
#pragma mark -
///////////////////////////////////////
// This function loads all the neccesary settings
// from config files in the Resources folder
///////////////////////////////////////
static void GetParameters (void)
{
char *str;
RedFatalAlert("\pInitialization Error",
"\pError getting script from application bundle.");
RedFatalAlert("\pInitialization Error",
"\pError getting openDoc from application bundle.");
}
///////////////////////////////////////
// Get path to the script in Resources folder
///////////////////////////////////////
static unsigned char* GetScript (void)
{
unsigned char *path;
//get CF URL for script
return NULL;
//Get file reference from Core Foundation URL
//dispose of the CF variables
//create path string
return path;
}
///////////////////////////////////////
// Gets the path to openDoc in Resources folder
///////////////////////////////////////
static unsigned char* GetOpenDoc (void)
{
unsigned char *path;
//get CF URL for openDoc
return NULL;
//Get file reference from Core Foundation URL
//dispose of the CF variables
//create path string
return path;
}
#pragma mark -
/////////////////////////////////////
// Load menu bar from nib
/////////////////////////////////////
{
return noErr;
}
#pragma mark -
///////////////////////////////////////
// Generate path string from FSSpec record
///////////////////////////////////////
{
// and then convert the FSRef to a path
}
////////////////////////////////////////
// Standard red error alert, then exit application
////////////////////////////////////////
{
ExitToShell();
}
///////////////////////////////////////
// Determines whether file exists at path or not
///////////////////////////////////////
{
return true;
}
#pragma mark -
///////////////////////////////////////
// Apple Event handler for Quit i.e. from
// the dock or Application menu item
///////////////////////////////////////
{
}
ExitToShell();
return noErr;
}
/////////////////////////////////////
// Handler for docs dragged on app icon
/////////////////////////////////////
{
short i;
//Read the AppleEvent
&fileRefList);
//get fsref from apple event
{
//get path from file ref
kMaxPathLength))) return err;
if (numArgs == kMaxArgumentsToScript) break;
}
else return err;
}
return err;
}
///////////////////////////////
// Handler for clicking on app icon
///////////////////////////////
// if app is already open
{
return runScript();
}
// if app is being opened
{
// the app has been opened without any items dragged on to it
return noErr;
}
// Compile and run a small AppleScript. The code below does no cleanup and no proper error checks
// but since it's there until the app is shut down, and since we know the script is okay,
// there should not be any problems.
AEDesc *resultData) {
resultData = NULL;
/* set up locals to a known state */
theComponent = NULL;
/* open the scripting component */
/* put the script text into an aedesc */
/* compile the script */
kOSAModeNull, &scriptID);
return err;
}
/* runs the compiled applescript */
{
/* run the script */
kOSAModeNull, &resultID);
return err;
}
/* Simple shortcut to the function that actually compiles the applescript. */
}