Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'features/org.eclipse.equinox.executable.feature/library')
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/.cvsignore3
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/build.sh100
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/build.xml20
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbon.c855
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonCommon.c195
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonMain.c237
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/eclipseMain.c15
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/make_carbon.mak93
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/carbon/make_cocoa.mak97
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipse.c1781
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseCommon.c570
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseCommon.h106
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseConfig.c186
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseConfig.h62
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseJNI.c568
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseJNI.h87
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseMain.c468
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.c300
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.h21
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseNix.c234
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseOS.h121
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseShm.c273
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseShm.h60
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseUnicode.h112
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseUtil.c333
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/eclipseUtil.h61
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/.gitignore3
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/build.sh238
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/build.xml28
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c347
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h77
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkCommon.c134
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c126
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/make_aix.mak116
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/make_hpux.mak102
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak112
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/gtk/make_solaris.mak111
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/make_version.mak14
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/.cvsignore4
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.c178
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.h95
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgImage.c246
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgImage.h54
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.c490
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.h170
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.c367
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.h34
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/build.sh164
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/build.xml20
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.c336
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.h96
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifCommon.c219
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifInit.c179
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifShim.c17
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/make_aix.mak104
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_PA_RISC.mak94
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_ia64_32.mak101
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/make_linux.mak108
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/motif/make_solaris.mak104
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/photon/.cvsignore2
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/photon/build.sh79
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/photon/build.xml20
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/photon/eclipsePhoton.c288
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/photon/make_qnx.mak57
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/.cvsignore8
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/build.bat156
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/build.sh77
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/build.xml18
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/eclipse.exe.manifest11
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/eclipse.icobin0 -> 292878 bytes
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/eclipse.rc21
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c619
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/eclipseWinCommon.c116
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/make_mingw.mak127
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/make_win32.mak103
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak107
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/make_win64_ia64.mak108
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/.cvsignore12
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/build.bat127
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/build.xml19
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/com.c28
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.icobin0 -> 317270 bytes
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.rc21
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpf.cpp561
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpfCommon.cpp87
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/wpf/make_wpf.mak113
86 files changed, 14431 insertions, 0 deletions
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/.cvsignore b/features/org.eclipse.equinox.executable.feature/library/carbon/.cvsignore
new file mode 100644
index 000000000..f0fdae47c
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/.cvsignore
@@ -0,0 +1,3 @@
+*.o
+eclipse
+*.so
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/build.sh b/features/org.eclipse.equinox.executable.feature/library/carbon/build.sh
new file mode 100644
index 000000000..ac923d2ff
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/build.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+#*******************************************************************************
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+#
+# Usage: sh build.sh [<optional switches>] [clean]
+#
+# where the optional switches are:
+# -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+# -os <DEFAULT_OS> - default Eclipse "-os" value
+# -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value
+# -ws <DEFAULT_WS> - default Eclipse "-ws" value
+#
+#
+# This script can also be invoked with the "clean" argument.
+
+cd `dirname $0`
+
+# Define default values for environment variables used in the makefiles.
+programOutput="eclipse"
+defaultOS="macosx"
+defaultOSArch="x86"
+defaultWS="carbon"
+makefile="make_carbon.mak"
+if [ "$OS" = "" ]; then
+ OS=`uname -s`
+fi
+
+# Parse the command line arguments and override the default values.
+extraArgs=""
+while [ "$1" != "" ]; do
+ if [ "$1" = "-os" ] && [ "$2" != "" ]; then
+ defaultOS="$2"
+ shift
+ elif [ "$1" = "-arch" ] && [ "$2" != "" ]; then
+ defaultOSArch="$2"
+ shift
+ elif [ "$1" = "-ws" ] && [ "$2" != "" ]; then
+ defaultWS="$2"
+ shift
+ elif [ "$1" = "-output" ] && [ "$2" != "" ]; then
+ programOutput="$2"
+ shift
+ else
+ extraArgs="$extraArgs $1"
+ fi
+ shift
+done
+
+# Set up environment variables needed by the makefiles.
+PROGRAM_OUTPUT="$programOutput"
+DEFAULT_OS="$defaultOS"
+DEFAULT_OS_ARCH="$defaultOSArch"
+DEFAULT_WS="$defaultWS"
+EXEC_DIR=../../../../../rt.equinox.binaries/org.eclipse.equinox.executable
+PPC_OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/ppc/Eclipse.app/Contents/MacOS"
+X86_OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/x86/Eclipse.app/Contents/MacOS"
+X86_64_OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/x86_64/Eclipse.app/Contents/MacOS"
+
+if [ "$DEFAULT_WS" == "cocoa" ]; then
+ makefile="make_cocoa.mak"
+ export MACOSX_DEPLOYMENT_TARGET=10.5
+else
+ export MACOSX_DEPLOYMENT_TARGET=10.3
+fi
+
+if [ "$DEFAULT_OS_ARCH" == "x86_64" ]; then
+ echo "build x86_64"
+ ARCHS="-arch x86_64"
+ PROGRAM_OUTPUT_DIR=$X86_64_OUTPUT_DIR
+ DEFAULT_OS_ARCH="x86_64"
+else
+ echo "build x86 and ppc"
+ ARCHS="-arch i386 -arch ppc"
+ PROGRAM_OUTPUT_DIR=$X86_OUTPUT_DIR
+fi
+
+export PPC_OUTPUT_DIR X86_OUTPUT_DIR X86_64_OUTPUT_DIR PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS ARCHS PROGRAM_OUTPUT_DIR
+
+# If the OS is supported (a makefile exists)
+if [ "$makefile" != "" ]; then
+ if [ "$extraArgs" != "" ]; then
+ make -f $makefile $extraArgs
+ else
+ echo "Building $OS launcher. Defaults: -os $DEFAULT_OS -arch $DEFAULT_OS_ARCH -ws $DEFAULT_WS"
+ make -f $makefile clean
+ make -f $makefile all
+ make -f $makefile install
+ fi
+else
+ echo "Unknown OS ($OS) -- build aborted"
+fi
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/build.xml b/features/org.eclipse.equinox.executable.feature/library/carbon/build.xml
new file mode 100644
index 000000000..990298e64
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/build.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="build_eclipse" basedir=".">
+
+<target name="build_eclipse">
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="install"/>
+ </exec>
+</target>
+
+<target name="clean">
+ <tstamp/>
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="clean"/>
+ </exec>
+</target>
+
+</project> \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbon.c b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbon.c
new file mode 100644
index 000000000..29348fc56
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbon.c
@@ -0,0 +1,855 @@
+/*
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andre Weinand (OTI Labs)
+ * David Green - OpenJDK bsd port integration
+ */
+
+/* MacOS X Carbon specific logic for displaying the splash screen. */
+
+#include "eclipseOS.h"
+#include "eclipseCommon.h"
+#include "eclipseJNI.h"
+#include "eclipseUtil.h"
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <CoreServices/CoreServices.h>
+#ifdef COCOA
+#include <Cocoa/Cocoa.h>
+#else
+#include <Carbon/Carbon.h>
+#include "NgCommon.h"
+#include "NgImageData.h"
+#include "NgWinBMPFileFormat.h"
+#endif
+#include <mach-o/dyld.h>
+#include <pthread.h>
+
+#define startupJarName "startup.jar"
+#define LAUNCHER "-launcher"
+#define SPLASH_LAUNCHER "/Resources/Splash.app/Contents/"
+
+#define DEBUG 0
+
+static _TCHAR* noForkingMsg = _T_ECLIPSE("Internal Error, forking the jvm is not supported on MacOS.\n");
+
+char *findCommand(char *command);
+
+/* Global Variables */
+char* defaultVM = "java";
+char* vmLibrary = "JavaVM";
+char* shippedVMDir = "../../../jre/Contents/Home/jre/bin/";
+int isSUN = 0;
+
+static void adjustLibraryPath(char * vmLibrary);
+static char * findLib(char * command);
+
+#ifdef i386
+#define JAVA_ARCH "i386"
+#define JAVA_HOME_ARCH "i386"
+#elif defined(__ppc__) || defined(__powerpc64__)
+#define JAVA_ARCH "ppc"
+#define JAVA_HOME_ARCH "ppc"
+#elif defined(__amd64__) || defined(__x86_64__)
+#define JAVA_ARCH "amd64"
+#define JAVA_HOME_ARCH "x86_64"
+#else
+#define JAVA_ARCH DEFAULT_OS_ARCH
+#define JAVA_HOME_ARCH DEFAULT_OS_ARCH
+#endif
+
+#define LIB_PATH_VAR _T_ECLIPSE("LD_LIBRARY_PATH")
+#define DYLD_FALLBACK_VAR _T_ECLIPSE("DYLD_FALLBACK_LIBRARY_PATH")
+
+#define MAX_LOCATION_LENGTH 40 /* none of the jvmLocations strings should be longer than this */
+#define MAX_JVMLIB_LENGTH 15 /* none of the jvmLibs strings should be longer than this */
+static const char* jvmLocations[] = { "../lib/" JAVA_ARCH "/client",
+ "../lib/" JAVA_ARCH "/server",
+ "../jre/lib/" JAVA_ARCH "/client",
+ "../jre/lib/" JAVA_ARCH "/server",
+ "../jre/lib/client",
+ "../jre/lib/server", NULL };
+static const char* jvmLibs[] = { "libjvm.dylib", "libjvm.jnilib", "libjvm.so", NULL };
+
+/* Define the window system arguments for the various Java VMs. */
+static char* argVM_JAVA[] = { "-XstartOnFirstThread", NULL };
+
+/* thread stuff */
+typedef struct {
+ _TCHAR * libPath;
+ _TCHAR ** vmArgs;
+ _TCHAR ** progArgs;
+ _TCHAR * jarFile;
+ JavaResults* result;
+} StartVMArgs;
+
+#ifdef COCOA
+static NSWindow* window = nil;
+@interface KeyWindow : NSWindow { }
+- (BOOL)canBecomeKeyWindow;
+@end
+
+@implementation KeyWindow
+- (BOOL)canBecomeKeyWindow {
+ return YES;
+}
+
+- (void)close {
+ [super close];
+ window = nil;
+}
+
+@end
+
+@interface AppleEventDelegate : NSObject
+- (void)handleOpenDocuments:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+@end
+@implementation AppleEventDelegate
+ NSTimer *timer;
+ NSMutableArray *files;
+
+- (void)handleOpenDocuments:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ int count = [event numberOfItems];
+ int index = 1;
+
+ if (!files) {
+ files = [NSMutableArray arrayWithCapacity:count];
+ [files retain];
+ }
+
+ for (index = 1; index<=count; index++) {
+ CFURLRef url = NULL;
+ NSAppleEventDescriptor *desc = [event descriptorAtIndex:index], *coerceDesc;
+ if (!desc) continue;
+ if ((coerceDesc = [desc coerceToDescriptorType: typeFSRef]) != NULL) {
+ url = CFURLCreateFromFSRef(kCFAllocatorDefault, [[coerceDesc data] bytes]);
+ } else if ((coerceDesc = [desc coerceToDescriptorType: typeFileURL]) != NULL) {
+ NSData *data = [coerceDesc data];
+ url = CFURLCreateWithBytes(kCFAllocatorDefault, [data bytes], [data length], kCFStringEncodingUTF8, NULL);
+ }
+ if (url) {
+ NSString *pathName = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+ [files addObject:pathName];
+ [pathName release];
+ CFRelease(url);
+ }
+ }
+
+ if (!timer) {
+ timer = [NSTimer scheduledTimerWithTimeInterval: 1.0
+ target: self
+ selector: @selector(handleTimer:)
+ userInfo: nil
+ repeats: YES];
+ }
+ [pool release];
+}
+- (void) handleTimer: (NSTimer *) timer {
+ NSObject *delegate = [[NSApplication sharedApplication] delegate];
+ if (delegate != NULL && [delegate respondsToSelector: @selector(application:openFiles:)]) {
+ [delegate performSelector:@selector(application:openFiles:) withObject:[NSApplication sharedApplication] withObject:files];
+ [files release];
+ [timer invalidate];
+ }
+}
+@end
+#endif
+
+static CFRunLoopRef loopRef = NULL;
+static void * startThread(void * init);
+static void runEventLoop(CFRunLoopRef ref);
+static void dummyCallback(void * info) {}
+#ifndef COCOA
+static CFMutableArrayRef files;
+static EventHandlerRef appHandler;
+static int SWT_CLASS = 'SWT-';
+static int SWT_OPEN_FILE_KIND = 1;
+static int SWT_OPEN_FILE_PARAM = 'odoc';
+#endif
+
+int main() {
+ return -1;
+}
+
+void installAppleEventHandler();
+
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
+ installAppleEventHandler();
+ return 0;
+}
+
+#ifdef COCOA
+
+/* Show the Splash Window
+ *
+ * Create the splash window, load the bitmap and display the splash window.
+ */
+int showSplash( const _TCHAR* featureImage )
+{
+ if (window != NULL)
+ return 0; /*already showing */
+ if (featureImage == NULL)
+ return ENOENT;
+
+ int result = ENOENT;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [NSApplication sharedApplication];
+ NSImage* image = [[NSImage alloc] initByReferencingFile: [NSString stringWithUTF8String: featureImage]];
+ if (image != NULL) {
+ NSImageRep* imageRep = [image bestRepresentationForDevice: [[NSScreen mainScreen] deviceDescription]];
+ NSRect rect = {{0, 0}, {[imageRep pixelsWide], [imageRep pixelsHigh]}};
+ [image setSize: NSMakeSize([imageRep pixelsWide], [imageRep pixelsHigh])];
+ [image autorelease];
+ window = [[KeyWindow alloc] initWithContentRect: rect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: 0];
+ if (window != nil) {
+ [window center];
+ [window setBackgroundColor: [NSColor colorWithPatternImage: image]];
+ [window makeKeyAndOrderFront: nil];
+ dispatchMessages();
+ result = 0;
+ }
+ }
+ [pool release];
+ return result;
+}
+
+void takeDownSplash() {
+ if (window != 0) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [window close];
+ window = nil;
+ [pool release];
+ }
+}
+
+void dispatchMessages() {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSEvent* event;
+ NSApplication* application = [NSApplication sharedApplication];
+ while ((event = [application nextEventMatchingMask: 0 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: TRUE]) != nil) {
+ [application sendEvent: event];
+ }
+ [pool release];
+}
+
+#else
+static WindowRef window;
+static ControlRef pane = NULL;
+static CGImageRef image = NULL;
+static CGImageRef loadBMPImage(const char *image);
+
+typedef CGImageSourceRef (*CGImageSourceCreateWithURL_FUNC) (CFURLRef, CFDictionaryRef);
+typedef CGImageRef (*CGImageSourceCreateImageAtIndex_FUNC)(CGImageSourceRef, size_t, CFDictionaryRef);
+static CGImageSourceCreateWithURL_FUNC createWithURL = NULL;
+static CGImageSourceCreateImageAtIndex_FUNC createAtIndex = NULL;
+
+static pascal OSErr openDocumentsProc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
+
+static OSStatus drawProc (EventHandlerCallRef eventHandlerCallRef, EventRef eventRef, void * data) {
+ int result = CallNextEventHandler(eventHandlerCallRef, eventRef);
+ if (image) {
+ ControlRef control;
+ CGContextRef context;
+
+ GetEventParameter(eventRef, kEventParamDirectObject, typeControlRef, NULL, 4, NULL, &control);
+ GetEventParameter(eventRef, kEventParamCGContextRef, typeCGContextRef, NULL, 4, NULL, &context);
+
+ HIRect rect;
+ HIViewGetBounds(control, &rect);
+ HIViewDrawCGImage(context, &rect, image);
+ }
+ return result;
+}
+
+static OSStatus disposeProc (EventHandlerCallRef eventHandlerCallRef, EventRef eventRef, void * data) {
+ window = NULL;
+ return eventNotHandledErr;
+}
+
+void loadImageFns()
+{
+ static int initialized = 0;
+ static CFBundleRef bundle = NULL;
+
+ if (!initialized) {
+ if (!bundle) bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Carbon"));
+ if (bundle) createAtIndex = (CGImageSourceCreateImageAtIndex_FUNC)CFBundleGetFunctionPointerForName(bundle, CFSTR("CGImageSourceCreateImageAtIndex"));
+ if (bundle) createWithURL = (CGImageSourceCreateWithURL_FUNC)CFBundleGetFunctionPointerForName(bundle, CFSTR("CGImageSourceCreateWithURL"));
+ initialized = 1;
+ }
+}
+
+static OSStatus appleEventProc(EventHandlerCallRef inCaller, EventRef theEvent, void* inRefcon) {
+ EventRecord eventRecord;
+ Boolean release = false;
+ EventQueueRef queue;
+
+ queue = GetCurrentEventQueue();
+ if (IsEventInQueue (queue, theEvent)) {
+ RetainEvent (theEvent);
+ release = true;
+ RemoveEventFromQueue (queue, theEvent);
+ }
+ ConvertEventRefToEventRecord (theEvent, &eventRecord);
+ AEProcessAppleEvent (&eventRecord);
+ if (release) ReleaseEvent (theEvent);
+ return noErr;
+}
+
+static void timerProc(EventLoopTimerRef timer, void *userData) {
+ EventTargetRef target = GetApplicationEventTarget();
+ CFIndex count = CFArrayGetCount (files);
+ int i;
+ for (i=0; i<count; i++) {
+ CFStringRef file = (CFStringRef) CFArrayGetValueAtIndex(files, i);
+ EventRef event = NULL;
+ CreateEvent (NULL, SWT_CLASS, SWT_OPEN_FILE_KIND, 0, kEventAttributeNone, &event);
+ SetEventParameter (event, SWT_OPEN_FILE_PARAM, typeCFStringRef, sizeof(file), &file);
+ OSStatus status = SendEventToEventTarget(event, target);
+ ReleaseEvent(event);
+ if (status == eventNotHandledErr) return;
+ }
+ CFRelease(files);
+ RemoveEventLoopTimer(timer);
+ RemoveEventHandler(appHandler);
+ AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(openDocumentsProc), false);
+}
+
+static pascal OSErr openDocumentsProc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) {
+ AEDescList docList;
+ FSRef theFSRef;
+ long index;
+ long count = 0;
+
+ AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
+ AECountItems(&docList, &count);
+ for(index = 1; index <= count; index++) {
+ AEGetNthPtr(&docList, index, typeFSRef, NULL, NULL, &theFSRef, sizeof(FSRef), NULL);
+ CFURLRef url = CFURLCreateFromFSRef(kCFAllocatorDefault, &theFSRef);
+ CFStringRef pathName = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+ if (!files) {
+ files = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
+ InstallEventLoopTimer(GetMainEventLoop(), 1, 1, NewEventLoopTimerUPP(timerProc), NULL, NULL);
+ }
+ CFArrayAppendValue(files, pathName);
+ CFRelease(pathName);
+ CFRelease(url);
+ }
+ AEDisposeDesc(&docList);
+ return noErr;
+}
+
+/* Show the Splash Window
+ *
+ * Create the splash window, load the bitmap and display the splash window.
+ */
+int showSplash( const _TCHAR* featureImage )
+{
+ Rect wRect;
+ int w, h, deviceWidth, deviceHeight;
+ int attributes;
+ EventTypeSpec draw = {kEventClassControl, kEventControlDraw};
+ EventTypeSpec dispose = {kEventClassWindow, kEventWindowDispose};
+ ControlRef root;
+
+ if(window != NULL)
+ return 0; /*already showing */
+ if (featureImage == NULL)
+ return ENOENT;
+
+ loadImageFns();
+ if (createWithURL && createAtIndex) {
+ CFStringRef imageString = CFStringCreateWithCString(kCFAllocatorDefault, featureImage, kCFStringEncodingUTF8);
+ if(imageString != NULL) {
+ CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, imageString, kCFURLPOSIXPathStyle, false);
+ if(url != NULL) {
+ CGImageSourceRef imageSource = createWithURL(url, NULL);
+ if(imageSource != NULL) {
+ image = createAtIndex(imageSource, 0, NULL);
+ }
+ CFRelease(url);
+ }
+ }
+ CFRelease(imageString);
+ } else {
+ image = loadBMPImage(featureImage);
+ }
+
+ /*If the splash image data could not be loaded, return an error.*/
+ if (image == NULL)
+ return ENOENT;
+
+ w = CGImageGetWidth(image);
+ h = CGImageGetHeight(image);
+
+ GetAvailableWindowPositioningBounds(GetMainDevice(), &wRect);
+
+ deviceWidth= wRect.right - wRect.left;
+ deviceHeight= wRect.bottom - wRect.top;
+
+ wRect.left+= (deviceWidth-w)/2;
+ wRect.top+= (deviceHeight-h)/3;
+ wRect.right= wRect.left + w;
+ wRect.bottom= wRect.top + h;
+
+ attributes = kWindowStandardHandlerAttribute | kWindowCompositingAttribute;
+ attributes &= GetAvailableWindowAttributes(kSheetWindowClass);
+ CreateNewWindow(kSheetWindowClass, attributes, &wRect, &window);
+ if (window != NULL) {
+ GetRootControl(window, &root);
+ wRect.left = wRect.top = 0;
+ wRect.right = w;
+ wRect.bottom = h;
+ CreateUserPaneControl(window, &wRect, kControlSupportsEmbedding | kControlSupportsFocus | kControlGetsFocusOnClick, &pane);
+ HIViewAddSubview(root, pane);
+
+ InstallEventHandler(GetControlEventTarget(pane), (EventHandlerUPP)drawProc, 1, &draw, NULL, NULL);
+ InstallEventHandler(GetWindowEventTarget(window), (EventHandlerUPP)disposeProc, 1, &dispose, NULL, NULL);
+ ShowWindow(window);
+ dispatchMessages();
+ }
+
+ return 0;
+}
+
+void takeDownSplash() {
+ if( window != 0) {
+ DisposeWindow(window);
+ window = NULL;
+ }
+ if(image){
+ CGImageRelease(image);
+ image = NULL;
+ }
+}
+
+void dispatchMessages() {
+ EventRef event;
+ EventTargetRef target;
+
+ target = GetEventDispatcherTarget();
+ while( ReceiveNextEvent(0, NULL, kEventDurationNoWait, true, &event) == noErr ) {
+ SendEventToEventTarget(event, target);
+ ReleaseEvent(event);
+ }
+}
+#endif
+
+void installAppleEventHandler() {
+#ifdef COCOA
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ AppleEventDelegate *appleEventDelegate = [[AppleEventDelegate alloc] init];
+ [NSApplication sharedApplication];
+ NSAppleEventManager *manager = [NSAppleEventManager sharedAppleEventManager];
+ [manager setEventHandler:appleEventDelegate
+ andSelector:@selector(handleOpenDocuments:withReplyEvent:)
+ forEventClass:kCoreEventClass
+ andEventID:kAEOpenDocuments];
+// [appleEventDelegate release];
+ [pool release];
+#else
+ EventTypeSpec kEvents[] = { {kEventClassAppleEvent, kEventAppleEvent} };
+ InstallApplicationEventHandler(NewEventHandlerUPP(appleEventProc), GetEventTypeCount(kEvents), kEvents, 0, &appHandler);
+ AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(openDocumentsProc), 0, false);
+#endif
+}
+
+jlong getSplashHandle() {
+ return (jlong)window;
+}
+
+/* Get the window system specific VM arguments */
+char** getArgVM( char* vm )
+{
+ char** result;
+
+ /* Use the default arguments for a standard Java VM */
+ result = argVM_JAVA;
+
+ return result;
+}
+
+char * getJavaHome() {
+ FILE *fp;
+ char path[4096];
+ char *result, *start;
+ sprintf(path, "/usr/libexec/java_home -a %s", JAVA_HOME_ARCH);
+ fp = popen(path, "r");
+ if (fp == NULL) {
+ return NULL;
+ }
+ while (fgets(path, sizeof(path)-1, fp) != NULL) {
+ }
+ result = path;
+ start = strchr(result, '\n');
+ if (start) {
+ start[0] = 0;
+ }
+ sprintf(path, "%s/bin/java", result);
+ pclose(fp);
+ return strdup(path);
+}
+
+char * findVMLibrary( char* command ) {
+ char *start, *end;
+ char *version, *result, *cmd;
+ int length;
+
+ /*check first to see if command already points to the library */
+ if (strcmp(command, JAVA_FRAMEWORK) == 0) {
+ return JAVA_FRAMEWORK;
+ }
+
+ /* select a version to use based on the command */
+ start = strstr(command, "/Versions/");
+ if (start != NULL){
+ start += 10;
+ end = strchr( start, dirSeparator);
+ if (end != NULL && end > start) {
+ length = end - start;
+ version = malloc(length + 1);
+ strncpy(version, start, length);
+ version[length] = 0;
+
+ /*only set a version if it starts with a number */
+ if(strtol(version, NULL, 10) != 0 || version[0] == '0') {
+ setenv("JAVA_JVM_VERSION", version, 1);
+ }
+
+ free(version);
+ }
+ }
+ cmd = command;
+ if (strstr(cmd, "/JavaVM.framework/") != NULL && (strstr(cmd, "/Current/") != NULL || strstr(cmd, "/A/") != NULL)) {
+ cmd = getJavaHome();
+ }
+ result = JAVA_FRAMEWORK;
+ if (strstr(cmd, "/JavaVM.framework/") == NULL) {
+ char * lib = findLib(cmd);
+ if (lib != NULL) {
+ adjustLibraryPath(lib);
+ result = lib;
+ }
+ }
+ if (cmd != command) free(cmd);
+ return result;
+}
+
+static char * findLib(char * command) {
+ int i, q;
+ int pathLength;
+ struct stat stats;
+ char * path; /* path to resulting jvm shared library */
+ char * location; /* points to begining of jvmLocations section of path */
+
+ if (command != NULL) {
+ /*check first to see if command already points to the library */
+ if (isVMLibrary(command)) {
+ if (stat(command, &stats) == 0 && (stats.st_mode & S_IFREG) != 0) { /* found it */
+ return strdup(command);
+ }
+ return NULL;
+ }
+
+ location = strrchr(command, dirSeparator) + 1;
+ pathLength = location - command;
+ path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + MAX_JVMLIB_LENGTH + 1) * sizeof(char));
+ strncpy(path, command, pathLength);
+ location = &path[pathLength];
+
+ /*
+ * We are trying base/jvmLocations[*]/vmLibrary
+ * where base is the directory containing the given java command, normally jre/bin
+ */
+ for (q = 0; jvmLibs[q] != NULL; ++q) {
+ const char *jvmLib = jvmLibs[q];
+ i = -1;
+ while (jvmLocations[++i] != NULL) {
+ sprintf(location, "%s%c%s", jvmLocations[i], dirSeparator, jvmLib);
+ /*fprintf(stderr,"checking path: %s\n",path);*/
+ if (stat(path, &stats) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /* found it */
+ return path;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+/* adjust the LD_LIBRARY_PATH for the vmLibrary */
+static void adjustLibraryPath(char * vmLibrary) {
+ char * c;
+ char * ldPath, *dylibPath;
+ char * newPath;
+ int i;
+ int numPaths = 0;
+ int length = 0;
+ int needAdjust = 0, needDylibAdjust = 0;
+
+ char ** paths = getVMLibrarySearchPath(vmLibrary);
+
+ ldPath = (char*) getenv(LIB_PATH_VAR);
+ if (!ldPath) {
+ ldPath = _T_ECLIPSE("");
+ needAdjust = 1;
+ } else {
+ needAdjust = !containsPaths(ldPath, paths);
+ }
+
+ dylibPath = (char*) getenv(DYLD_FALLBACK_VAR);
+ if (!dylibPath) {
+ dylibPath = _T_ECLIPSE("");
+ needDylibAdjust = 1;
+ } else {
+ needDylibAdjust = !containsPaths(dylibPath, paths);
+ }
+
+ if (!needAdjust && !needDylibAdjust) {
+ for (i = 0; paths[i] != NULL; i++)
+ free(paths[i]);
+ free(paths);
+ return;
+ }
+
+ c = concatStrings(paths);
+
+ /* set the value for LD_LIBRARY_PATH */
+ length = strlen(ldPath);
+ newPath = malloc((_tcslen(c) + length + 1) * sizeof(_TCHAR));
+ _stprintf(newPath, _T_ECLIPSE("%s%s"), c, ldPath);
+ setenv(LIB_PATH_VAR, newPath, 1);
+ free(newPath);
+
+ /* set the value for DYLD_FALLBACK_LIBRARY_PATH */
+ length = strlen(dylibPath);
+ newPath = malloc((_tcslen(c) + length + 1) * sizeof(_TCHAR));
+ _stprintf(newPath, _T_ECLIPSE("%s%s"), c, dylibPath);
+ setenv(DYLD_FALLBACK_VAR, newPath, 1);
+ free(newPath);
+ free(c);
+
+ for (i = 0; i < numPaths; i++)
+ free(paths[i]);
+ free(paths);
+
+ /* now we must restart for this to take affect*/
+ restartLauncher(initialArgv[0], initialArgv);
+}
+
+void restartLauncher(char* program, char* args[]) {
+ pid_t pid= fork();
+ if (pid == 0) {
+ /* Child process ... start the JVM */
+ execv(program != NULL ? program : args[0], args);
+
+ /* The JVM would not start ... return error code to parent process. */
+ _exit(errno);
+ } else {
+ exit(0);
+ }
+}
+
+JavaResults* launchJavaVM( _TCHAR* args[] )
+{
+ /*for now always do JNI on Mac, should not come in here */
+ JavaResults * results = malloc(sizeof(JavaResults));
+ results->launchResult = -1;
+ results->runResult = 0;
+ results->errorMessage = _tcsdup(noForkingMsg);
+ return results;
+}
+
+JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile )
+{
+ if (secondThread == 0) {
+ /* Set an environment variable that tells the AWT (if started) we started the JVM on the main thread. */
+ char firstThreadEnvVariable[80];
+ sprintf(firstThreadEnvVariable, "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
+ setenv(firstThreadEnvVariable, "1", 1);
+ return startJavaJNI(libPath, vmArgs, progArgs, jarFile);
+ }
+
+ /* else, --launcher.secondThread was specified, create a new thread and run the
+ * vm on it. This main thread will run the CFRunLoop
+ */
+ pthread_t thread;
+ struct rlimit limit = {0, 0};
+ int stackSize = 0;
+ if (getrlimit(RLIMIT_STACK, &limit) == 0) {
+ if (limit.rlim_cur != 0) {
+ stackSize = limit.rlim_cur;
+ }
+ }
+
+ /* initialize thread attributes */
+ pthread_attr_t attributes;
+ pthread_attr_init(&attributes);
+ pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM);
+ pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
+ if (stackSize != 0)
+ pthread_attr_setstacksize(&attributes, stackSize);
+
+ /* arguments to start the vm */
+ StartVMArgs args;
+ args.libPath = libPath;
+ args.vmArgs = vmArgs;
+ args.progArgs = progArgs;
+ args.jarFile = jarFile;
+ args.result = 0;
+
+ loopRef = CFRunLoopGetCurrent();
+
+ /* create the thread */
+ pthread_create( &thread, &attributes, &startThread, &args);
+ pthread_attr_destroy(&attributes);
+
+ runEventLoop(loopRef);
+
+ return args.result;
+}
+
+void * startThread(void * init) {
+ StartVMArgs *args = (StartVMArgs *) init;
+ args->result = startJavaJNI(args->libPath, args->vmArgs, args->progArgs, args->jarFile);
+ return NULL;
+}
+
+void runEventLoop(CFRunLoopRef ref) {
+ CFRunLoopSourceContext sourceContext = { .version = 0, .info = NULL, .retain = NULL, .release = NULL,
+ .copyDescription = NULL, .equal = NULL, .hash = NULL,
+ .schedule = NULL, .cancel = NULL, .perform = &dummyCallback };
+
+ CFRunLoopSourceRef sourceRef = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+ CFRunLoopAddSource(ref, sourceRef, kCFRunLoopCommonModes);
+
+ CFRunLoopRun();
+ CFRelease(sourceRef);
+}
+
+#ifndef COCOA
+void disposeData(void *info, void *data, size_t size)
+{
+ DisposePtr(data);
+}
+
+/**
+ * loadBMPImage
+ * Create a QuickDraw PixMap representing the given BMP file.
+ *
+ * bmpPathname: absolute path and name to the bmp file
+ *
+ * returned value: the PixMapHandle newly created if successful. 0 otherwise.
+ */
+static CGImageRef loadBMPImage (const char *bmpPathname) {
+ ng_stream_t in;
+ ng_bitmap_image_t image;
+ ng_err_t err= ERR_OK;
+ CGImageRef ref;
+ UBYTE1* data = NULL;
+
+ NgInit();
+
+ if (NgStreamInit(&in, (char*) bmpPathname) != ERR_OK) {
+ NgError(ERR_NG, "Error can't open BMP file");
+ return 0;
+ }
+
+ NgBitmapImageInit(&image);
+ err= NgBmpDecoderReadImage (&in, &image);
+ NgStreamClose(&in);
+
+ if (err != ERR_OK) {
+ NgBitmapImageFree(&image);
+ return 0;
+ }
+
+ UBYTE4 srcDepth= NgBitmapImageBitCount(&image);
+ if (srcDepth != 24) { /* We only support image depth of 24 bits */
+ NgBitmapImageFree(&image);
+ NgError (ERR_NG, "Error unsupported depth - only support 24 bit");
+ return 0;
+ }
+
+ int width= (int)NgBitmapImageWidth(&image);
+ int height= (int)NgBitmapImageHeight(&image);
+ int rowBytes= width * 4;
+ int alphainfo = kCGImageAlphaNoneSkipFirst | (NgIsMSB() ? 0 : kCGBitmapByteOrder32Little);
+ data = (UBYTE1*)NewPtr(rowBytes * height);
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, data, rowBytes * height, (CGDataProviderReleaseDataCallback)disposeData);
+
+ ref = CGImageCreate(width, height, 8, 32, width * 4, CGColorSpaceCreateDeviceRGB(), alphainfo, provider, NULL, 1, 0);
+ CGDataProviderRelease(provider);
+
+ /* 24 bit source to direct screen destination */
+ NgBitmapImageBlitDirectToDirect(NgBitmapImageImageData(&image), NgBitmapImageBytesPerRow(&image), width, height,
+ data, 32, rowBytes, NgIsMSB(), 0xff0000, 0x00ff00, 0x0000ff);
+
+ NgBitmapImageFree(&image);
+
+ return ref;
+}
+#endif
+
+#define DOCK_ICON_PREFIX "-Xdock:icon="
+#define DOCK_NAME_PREFIX "-Xdock:name="
+#define APP_ICON_PATTERN "APP_ICON_%d"
+#define APP_NAME_PATTERN "APP_NAME_%d"
+
+void processVMArgs(char **vmargs[] )
+{
+ int i = -1;
+ int pid = 0, pidLength = 1, temp = 0;
+ char * name = NULL, *icon = NULL;
+ char * c;
+
+ if( *vmargs == NULL)
+ return;
+
+ while( (*vmargs)[++i] != NULL ) {
+ /*-Xdock:icon -> APP_ICON_<pid>*/
+ if(_tcsncmp((*vmargs)[i], DOCK_ICON_PREFIX, _tcslen(DOCK_ICON_PREFIX)) == 0) {
+ icon = (*vmargs)[i] + _tcslen(DOCK_ICON_PREFIX);
+ }
+ /*-Xdock:name -> APP_NAME_<pid>*/
+ else if(_tcsncmp((*vmargs)[i], DOCK_NAME_PREFIX, _tcslen(DOCK_NAME_PREFIX)) == 0) {
+ name = (*vmargs)[i] + _tcslen(DOCK_NAME_PREFIX);
+ }
+ if (name != NULL && icon != NULL)
+ break;
+ }
+
+ if (name == NULL && icon == NULL)
+ return; /* don't need to do anything */
+
+ temp = pid = getpid();
+ /* how many digits in pid? */
+ while (temp > 9) {
+ pidLength++;
+ temp /= 10;
+ }
+
+ if (name != NULL) {
+ c = malloc( (_tcslen(APP_NAME_PATTERN) + pidLength + 1) * sizeof(char*));
+ _stprintf( c, APP_NAME_PATTERN, pid );
+ setenv(c, name, 1);
+ }
+
+ if (icon != NULL) {
+ c = malloc( (_tcslen(icon) + _tcslen(APP_ICON_PATTERN) + pidLength + 1) * sizeof(char*));
+ _stprintf( c, APP_ICON_PATTERN, pid );
+ setenv(c, icon, 1);
+ }
+}
+
+int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib ) {
+ return isSUN;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonCommon.c b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonCommon.c
new file mode 100644
index 000000000..2870c62e8
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonCommon.c
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+
+#include <locale.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <CoreServices/CoreServices.h>
+#ifdef COCOA
+#include <Cocoa/Cocoa.h>
+#else
+#include <Carbon/Carbon.h>
+#endif
+#include <mach-o/dyld.h>
+
+char dirSeparator = '/';
+char pathSeparator = ':';
+
+static CFBundleRef javaVMBundle = NULL;
+
+int initialized = 0;
+
+static void init() {
+ if (!initialized) {
+ ProcessSerialNumber psn;
+ if (GetCurrentProcess(&psn) == noErr) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
+ }
+#ifdef COCOA
+ [NSApplication sharedApplication];
+#else
+ ClearMenuBar();
+#endif
+ initialized= true;
+ }
+}
+
+
+/* Initialize Window System
+ *
+ * Initialize Carbon.
+ */
+int initWindowSystem( int* pArgc, char* argv[], int showSplash )
+{
+ char *homeDir = getProgramDir();
+ /*debug("install dir: %s\n", homeDir);*/
+ if (homeDir != NULL)
+ chdir(homeDir);
+
+ if (showSplash)
+ init();
+
+ return 0;
+}
+
+/* Display a Message */
+void displayMessage(char *title, char *message)
+{
+ CFStringRef inError, inDescription= NULL;
+
+ /* try to break the message into a first sentence and the rest */
+ char *pos= strstr(message, ". ");
+ if (pos != NULL) {
+ char *to, *from, *buffer= calloc(pos-message+2, sizeof(char));
+ /* copy and replace line separators with blanks */
+ for (to= buffer, from= message; from <= pos; from++, to++) {
+ char c= *from;
+ if (c == '\n') c= ' ';
+ *to= c;
+ }
+ inError= CFStringCreateWithCString(kCFAllocatorDefault, buffer, kCFStringEncodingUTF8);
+ free(buffer);
+ inDescription= CFStringCreateWithCString(kCFAllocatorDefault, pos+2, kCFStringEncodingUTF8);
+ } else {
+ inError= CFStringCreateWithCString(kCFAllocatorDefault, message, kCFStringEncodingUTF8);
+ }
+
+ init();
+
+#ifdef COCOA
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSAlert* alert = [NSAlert alertWithMessageText: (NSString*)(inDescription != nil ? inError : nil) defaultButton: nil alternateButton: nil otherButton: nil informativeTextWithFormat: (NSString*)(inDescription != nil ? inDescription : inError)];
+ [[alert window] setTitle: [NSString stringWithUTF8String: title]];
+ [alert setAlertStyle: NSCriticalAlertStyle];
+ [alert runModal];
+ [pool release];
+#else
+ DialogRef outAlert;
+ OSStatus status= CreateStandardAlert(kAlertStopAlert, inError, inDescription, NULL, &outAlert);
+ if (status == noErr) {
+ DialogItemIndex outItemHit;
+ RunStandardAlert(outAlert, NULL, &outItemHit);
+ } else {
+ /*debug("%s: displayMessage: %s\n", title, message);*/
+ }
+#endif
+ CFRelease(inError);
+ if (inDescription != NULL)
+ CFRelease(inDescription);
+}
+
+static int isLibrary( _TCHAR* vm ){
+ _TCHAR *ch = NULL;
+ if (vm == NULL) return 0;
+ ch = _tcsrchr( vm, '.' );
+ if(ch == NULL)
+ return 0;
+ return (_tcsicmp(ch, _T_ECLIPSE(".so")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".jnilib")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".dylib")) == 0);
+}
+
+/* Load the specified shared library
+ */
+void * loadLibrary( char * library ){
+ if (!isLibrary(library)) {
+ CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)library, strlen(library), true);
+ javaVMBundle = CFBundleCreate(kCFAllocatorDefault, url);
+ CFRelease(url);
+ return (void*) &javaVMBundle;
+ } else {
+ void * result= dlopen(library, RTLD_NOW);
+ if(result == 0)
+ printf("%s\n",dlerror());
+ return result;
+ }
+}
+
+/* Unload the shared library
+ */
+void unloadLibrary( void * handle ){
+ if (handle == &javaVMBundle)
+ CFRelease(javaVMBundle);
+ else
+ dlclose(handle);
+}
+
+/* Find the given symbol in the shared library
+ */
+void * findSymbol( void * handle, char * symbol ){
+ if(handle == &javaVMBundle) {
+ CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, symbol, kCFStringEncodingASCII);
+ void * ptr = CFBundleGetFunctionPointerForName(javaVMBundle, string);
+ CFRelease(string);
+ return ptr;
+ } else
+ return dlsym(handle, symbol);
+}
+
+char * resolveSymlinks( char * path ) {
+ char * result = 0;
+ CFURLRef url, resolved;
+ CFStringRef string;
+ FSRef fsRef;
+ Boolean isFolder, wasAliased;
+
+ if(path == NULL)
+ return path;
+
+ string = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
+ url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, string, kCFURLPOSIXPathStyle, false);
+ CFRelease(string);
+ if(url == NULL)
+ return path;
+
+ if(CFURLGetFSRef(url, &fsRef)) {
+ if( FSResolveAliasFile(&fsRef, true, &isFolder, &wasAliased) == noErr) {
+ resolved = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsRef);
+ if(resolved != NULL) {
+ string = CFURLCopyFileSystemPath(resolved, kCFURLPOSIXPathStyle);
+ CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8);
+ char *s = malloc(length);
+ if (CFStringGetCString(string, s, length, kCFStringEncodingUTF8)) {
+ result = s;
+ } else {
+ free(s);
+ }
+ CFRelease(string);
+ CFRelease(resolved);
+ }
+ }
+ }
+ CFRelease(url);
+ return result;
+} \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonMain.c b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonMain.c
new file mode 100644
index 000000000..51cafc275
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseCarbonMain.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ */
+
+#include "eclipseCommon.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <CoreServices/CoreServices.h>
+#include <Carbon/Carbon.h>
+#include <mach-o/dyld.h>
+
+
+#define APP_PACKAGE_PATTERN ".app/Contents/MacOS/"
+#define APP_PACKAGE "APP_PACKAGE"
+#define JAVAROOT "JAVAROOT"
+
+static void debug(const char *fmt, ...);
+static void dumpArgs(char *tag, int argc, char* argv[]);
+static char *append(char *buffer, const char *s);
+static char *appendc(char *buffer, char c);
+static char *expandShell(char *arg, const char *appPackage, const char *javaRoot);
+static char *my_strcasestr(const char *big, const char *little);
+
+static FILE *fgConsoleLog;
+static char *fgAppPackagePath;
+static int fgPid;
+
+extern int original_main(int argc, char* argv[]);
+int main( int argc, char* argv[] ) {
+
+ SInt32 systemVersion= 0;
+ if (Gestalt(gestaltSystemVersion, &systemVersion) == noErr) {
+ systemVersion &= 0xffff;
+#ifdef COCOA
+ if (systemVersion < 0x1050) {
+ displayMessage("Error", "This application requires Mac OS X 10.5 (Leopard) or greater.");
+ return 0;
+ }
+#else
+ if (systemVersion < 0x1020) {
+ displayMessage("Error", "This application requires Jaguar (Mac OS X >= 10.2)");
+ return 0;
+ }
+#endif
+ }
+
+ fgConsoleLog= fopen("/dev/console", "w");
+ fgPid= getpid();
+
+ dumpArgs("start", argc, argv);
+ if ( (argc > 1 && strncmp(argv[1], "-psn_", 5) == 0) || argc == 1) {
+ /* find path to application bundle (ignoring case) */
+ char *pos= my_strcasestr(argv[0], APP_PACKAGE_PATTERN);
+ if (pos != NULL) {
+ int l= pos-argv[0] + 4; // reserve space for ".app"
+ fgAppPackagePath= malloc(l+1);
+ strncpy(fgAppPackagePath, argv[0], l);
+ fgAppPackagePath[l]= '\0'; // terminate result
+ }
+
+ /* Get the main bundle for the app */
+ CFBundleRef mainBundle= CFBundleGetMainBundle();
+ if (mainBundle != NULL) {
+
+ /* Get an instance of the info plist.*/
+ CFDictionaryRef bundleInfoDict= CFBundleGetInfoDictionary(mainBundle);
+
+ /* If we succeeded, look for our property. */
+ if (bundleInfoDict != NULL) {
+ CFArrayRef ar= CFDictionaryGetValue(bundleInfoDict, CFSTR("Eclipse"));
+ if (ar) {
+ CFIndex size= CFArrayGetCount(ar);
+ if (size > 0) {
+ int i;
+ char **old_argv= argv;
+ argv= (char**) calloc(size+2, sizeof(char*));
+ argc= 0;
+ argv[argc++]= old_argv[0];
+ for (i= 0; i < size; i++) {
+ CFStringRef sr= (CFStringRef) CFArrayGetValueAtIndex (ar, i);
+ CFIndex argStringSize= CFStringGetMaximumSizeForEncoding(CFStringGetLength(sr), kCFStringEncodingUTF8);
+ char *s= malloc(argStringSize);
+ if (CFStringGetCString(sr, s, argStringSize, kCFStringEncodingUTF8)) {
+ argv[argc++]= expandShell(s, fgAppPackagePath, NULL);
+ } else {
+ fprintf(fgConsoleLog, "can't extract bytes\n");
+ }
+ //free(s);
+ }
+ }
+ } else {
+ fprintf(fgConsoleLog, "no Eclipse dict found\n");
+ }
+ } else {
+ fprintf(fgConsoleLog, "no bundle dict found\n");
+ }
+ } else {
+ fprintf(fgConsoleLog, "no bundle found\n");
+ }
+ }
+ int exitcode= original_main(argc, argv);
+ debug("<<<< exit(%d)\n", exitcode);
+ fclose(fgConsoleLog);
+ return exitcode;
+}
+
+static void debug(const char *fmt, ...) {
+#if DEBUG
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(fgConsoleLog, "%05d: ", fgPid);
+ vfprintf(fgConsoleLog, fmt, ap);
+ va_end(ap);
+#endif
+}
+
+static void dumpArgs(char *tag, int argc, char* argv[]) {
+#if DEBUG
+ int i;
+ if (argc < 0) {
+ argc= 0;
+ for (i= 0; argv[i] != NULL; i++)
+ argc++;
+ }
+ debug(">>>> %s:", tag);
+ for (i= 0; i < argc && argv[i] != NULL; i++)
+ fprintf(fgConsoleLog, " <%s>", argv[i]);
+ fprintf(fgConsoleLog, "\n");
+#endif
+}
+
+/*
+ * Expand $APP_PACKAGE, $JAVA_HOME, and does tilde expansion.
+
+ A word beginning with an unquoted tilde character (~) is
+ subject to tilde expansion. All the characters up to a
+ slash (/) or the end of the word are treated as a username
+ and are replaced with the user's home directory. If the
+ username is missing (as in ~/foobar), the tilde is
+ replaced with the value of the HOME variable (the current
+ user's home directory).
+ */
+static char *expandShell(char *arg, const char *appPackage, const char *javaRoot) {
+
+ if (index(arg, '~') == NULL && index(arg, '$') == NULL)
+ return arg;
+
+ char *buffer= strdup("");
+ char c, lastChar= ' ';
+ const char *cp= arg;
+ while ((c = *cp++) != 0) {
+ if (isspace(lastChar) && c == '~') {
+ char name[100], *dir= NULL;
+ int j= 0;
+ for (; (c = *cp) != 0; cp++) {
+ if (! isalnum(c))
+ break;
+ name[j++]= c;
+ lastChar= c;
+ }
+ name[j]= '\0';
+ if (j > 0) {
+ struct passwd *pw= getpwnam(name);
+ if (pw != NULL)
+ dir= pw->pw_dir;
+ } else {
+ dir= getenv("HOME");
+ }
+ if (dir != NULL)
+ buffer= append(buffer, dir);
+
+ } else if (c == '$') {
+ int l= strlen(APP_PACKAGE);
+ if (appPackage != NULL && strncmp(cp, APP_PACKAGE, l) == 0) {
+ cp+= l;
+ buffer= append(buffer, appPackage);
+ } else {
+ int l= strlen(JAVAROOT);
+ if (javaRoot != NULL && strncmp(cp, JAVAROOT, l) == 0) {
+ cp+= l;
+ buffer= append(buffer, javaRoot);
+ } else {
+ buffer= appendc(buffer, c);
+ }
+ }
+ } else
+ buffer= appendc(buffer, c);
+ lastChar= c;
+ }
+ return buffer;
+}
+
+static char *my_strcasestr(const char *big, const char *little) {
+ char *cp, *s, *t;
+ for (cp= (char*) big; *cp; cp++) {
+ for (s= cp, t= (char*) little; *s && *t; s++, t++)
+ if (toupper(*s) != toupper(*t))
+ break;
+ if (*t == '\0')
+ return cp;
+ }
+ return NULL;
+}
+
+static char *append(char *buffer, const char *s) {
+ int bl= strlen(buffer);
+ int sl= strlen(s);
+ buffer= realloc(buffer, bl+sl+1);
+ strcpy(&buffer[bl], s);
+ return buffer;
+}
+
+static char *appendc(char *buffer, char c) {
+ int bl= strlen(buffer);
+ buffer= realloc(buffer, bl+2);
+ buffer[bl++]= c;
+ buffer[bl]= '\0';
+ return buffer;
+} \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseMain.c b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseMain.c
new file mode 100644
index 000000000..c0eaffa13
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/eclipseMain.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andre Weinand (OTI Labs)
+ */
+
+#define main original_main
+
+#include "../eclipseMain.c"
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/make_carbon.mak b/features/org.eclipse.equinox.executable.feature/library/carbon/make_carbon.mak
new file mode 100644
index 000000000..34843b739
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/make_carbon.mak
@@ -0,0 +1,93 @@
+#**********************************************************************
+# Copyright (c) 2000, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Kevin Cornell (Rational Software Corporation)
+#**********************************************************************
+include ../make_version.mak
+# Makefile for creating the Carbon eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+
+#default value for PROGRAM_OUTPUT
+ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+endif
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o eclipseCarbonMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseCarbonCommon.o
+DLL_OBJS = eclipse.o eclipseCarbon.o eclipseUtil.o eclipseJNI.o eclipseShm.o NgImageData.o NgWinBMPFileFormat.o NgCommon.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -framework Carbon
+ARCHS = -arch i386 -arch ppc
+CFLAGS = -O -s \
+ -mmacosx-version-min=10.3 \
+ -Wall \
+ $(ARCHS) \
+ -DMACOSX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -I.. -I../motif -I/System/Library/Frameworks/JavaVM.framework/Headers
+
+all: $(EXEC) $(DLL)
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseCarbonMain.o : eclipseCarbonMain.c
+ $(CC) $(CFLAGS) -c eclipseCarbonMain.c -o $@
+
+eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h eclipseMain.c ../eclipseMain.c
+ $(CC) $(CFLAGS) -c eclipseMain.c -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+NgCommon.o: ../motif/NgCommon.c
+ $(CC) $(CFLAGS) -c ../motif/NgCommon.c -o $@
+
+NgWinBMPFileFormat.o: ../motif/NgWinBMPFileFormat.c
+ $(CC) $(CFLAGS) -c ../motif/NgWinBMPFileFormat.c -o $@
+
+NgImageData.o: ../motif/NgImageData.c
+ $(CC) $(CFLAGS) -c ../motif/NgImageData.c -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(ARCHS) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) -bundle -o $(DLL) $(ARCHS) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(PPC_OUTPUT_DIR)
+ cp $(EXEC) $(X86_OUTPUT_DIR)
+ rm -f $(EXEC) $(OBJS)
+
+clean:
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/carbon/make_cocoa.mak b/features/org.eclipse.equinox.executable.feature/library/carbon/make_cocoa.mak
new file mode 100644
index 000000000..868c34bbf
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/carbon/make_cocoa.mak
@@ -0,0 +1,97 @@
+#**********************************************************************
+# Copyright (c) 2000, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Kevin Cornell (Rational Software Corporation)
+#**********************************************************************
+include ../make_version.mak
+# Makefile for creating the Carbon eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+
+#default value for PROGRAM_OUTPUT
+ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+endif
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o eclipseCarbonMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseCarbonCommon.o
+DLL_OBJS = eclipse.o eclipseCarbon.o eclipseUtil.o eclipseJNI.o eclipseShm.o
+#NgImageData.o NgWinBMPFileFormat.o NgCommon.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -framework Cocoa
+
+ifeq ($(ARCHS),)
+ARCHS = -arch i386 -arch ppc
+endif
+
+CFLAGS = -O -s \
+ -Wall \
+ -DCOCOA -xobjective-c \
+ $(ARCHS) \
+ -DMACOSX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -I.. -I../motif -I/System/Library/Frameworks/JavaVM.framework/Headers
+
+all: $(EXEC) $(DLL)
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseCarbonMain.o : eclipseCarbonMain.c
+ $(CC) $(CFLAGS) -c eclipseCarbonMain.c -o $@
+
+eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h eclipseMain.c ../eclipseMain.c
+ $(CC) $(CFLAGS) -c eclipseMain.c -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+NgCommon.o: ../motif/NgCommon.c
+ $(CC) $(CFLAGS) -c ../motif/NgCommon.c -o $@
+
+NgWinBMPFileFormat.o: ../motif/NgWinBMPFileFormat.c
+ $(CC) $(CFLAGS) -c ../motif/NgWinBMPFileFormat.c -o $@
+
+NgImageData.o: ../motif/NgImageData.c
+ $(CC) $(CFLAGS) -c ../motif/NgImageData.c -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(ARCHS) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) -bundle -o $(DLL) $(ARCHS) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp -v $(EXEC) $(PROGRAM_OUTPUT_DIR)
+ rm -f $(EXEC) $(OBJS)
+
+clean:
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipse.c b/features/org.eclipse.equinox.executable.feature/library/eclipse.c
new file mode 100644
index 000000000..be01c9ccc
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipse.c
@@ -0,0 +1,1781 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ * Markus Schorn (Wind River Systems), bug 193340
+ * Martin Oberhuber (Wind River) - [149994] Add --launcher.appendVmargs
+ *******************************************************************************/
+
+/* Eclipse Program Launcher
+ *
+ * This file forms the base of the eclipse_*.dll/so. This dll is loaded by eclipse.exe
+ * to start a Java VM, or alternatively it is loaded from Java to show the splash
+ * screen or write to the shared memory. See eclipseJNI.c for descriptions of the methods
+ * exposed to the Java program using JNI.
+ *
+ * To display a splash screen before starting the java vm, the launcher should be started
+ * with the location of the splash bitmap to use:
+ * -showsplash <path/to/splash.bmp>
+ * Otherwise, when the Java program starts, it should determine the location of
+ * the splash bitmap to be used and use the JNI method show_splash.
+ *
+ * When the Java program initialization is complete, the splash window
+ * is brought down by calling the JNI method takedown_splash.
+ *
+ * The Java program can also call the get_splash_handle method to get the handle to the splash
+ * window. This can be passed to SWT to create SWT widgets in the splash screen.
+ *
+ * The Java application will receive two other arguments:
+ * -exitdata <shared memory id>
+ *
+ * The java program can call set_exit_data with this shared-memory-id
+ * to provide specific exit data to the launcher.
+ *
+ * The exit data size must not exceed MAX_SHARED_LENGTH which is
+ * 16Kb. The interpretation of the exit data is dependent on the
+ * exit value of the java application.
+ *
+ * The main launcher recognizes the following exit codes from the
+ * Java application:
+ *
+ * 0 - Exit normally.
+ * RESTART_LAST_EC = 23
+ * - restart the java VM again with the same arguments as the previous one.
+ * RESTART_NEW_EC = 24
+ * - restart the java VM again with the arguments taken from the exit data.
+ * The exit data format is a list of arguments separated by '\n'. The Java
+ * application should build this list using the arguments passed to it on
+ * startup. See below.
+ *
+ * Additionally, if the Java application exits with an exit code other than the
+ * ones above, the main launcher will display an error message with the contents
+ * of the exit data. If the exit data is empty, a generic error message is
+ * displayed. The generic error message shows the exit code and the arguments
+ * passed to the Java application.
+ *
+ * The options that can be specified by the user to the launcher are:
+ * -vm <javaVM> the Java VM to be used
+ * -os <opSys> the operating system being run on
+ * -arch <osArch> the hardware architecture of the OS: x86, sparc, hp9000
+ * -ws <gui> the window system to be used: win32, motif, gtk, ...
+ * -nosplash do not display the splash screen. The java application will
+ * not receive the -showsplash command.
+ * -showsplash <bitmap> show the given bitmap in the splash screen.
+ * -name <name> application name displayed in error message dialogs and
+ * splash screen window. Default value is computed from the
+ * name of the executable - with the first letter capitalized
+ * if possible. e.g. eclipse.exe defaults to the name Eclipse.
+ * -startup <startup.jar> the startup jar to execute. The argument is first assumed to be
+ * relative to the path of the launcher. If such a file does not
+ * exist, the argument is then treated as an absolute path.
+ * The default is find the plugins/org.eclipse.equinox.launcher jar
+ * with the highest version number.
+ * The jar must contain an org.eclipse.equinox.launcher.Main class.
+ * (unless JNI invocation is not being used, then the jar only needs to be
+ * an executable jar)
+ * -library the location of the eclipse launcher shared library (this library) to use
+ * By default, the launcher exe (see eclipseMain.c) finds
+ * <userArgs> arguments that are passed along to the Java application
+ * (i.e, -data <path>, -debug, -console, -consoleLog, etc)
+ * -vmargs <userVMargs> ... a list of arguments for the VM itself
+ *
+ * The -vmargs option and all user specified VM arguments must appear
+ * at the end of the command line, after all arguments that are
+ * being passed to Java application.
+ *
+ * The argument order for the new Java VM process is as follows:
+ *
+ * <javaVM> <all VM args>
+ * -os <user or default OS value>
+ * -ws <user or default WS value>
+ * -arch <user or default ARCH value>
+ * -launcher <absolute launcher name>
+ * -name <application name>
+ * -library <eclipse library location>
+ * -startup <startup.jar location>
+ * [-showsplash]
+ * [-exitdata <shared memory id>]
+ * <userArgs>
+ * -vm <javaVM>
+ * -vmargs <all VM args>
+ *
+ * where:
+ * <all VM args> =
+ * [<defaultVMargs | <userVMargs>]
+ * -jar
+ * <startup jar full path>
+ *
+ * The startup jar must be an executable jar.
+ *
+ *
+ * See "Main.java" for a simple implementation of the Java
+ * application.
+ *
+ * Configuration file
+ * The launcher gets arguments from the command line and/or from a configuration file.
+ * The configuration file must have the same name and location as the launcher executable
+ * and the extension .ini. For example, the eclipse.ini configuration file must be
+ * in the same folder as the eclipse.exe or eclipse executable.
+ * The format of the ini file matches that of the command line arguments - one
+ * argument per line.
+ * In general, the settings of the config file are expected to be overriden by the
+ * command line.
+ * - launcher arguments (-os, -arch...) set in the config file are overriden by the command line
+ * - the -vmargs from the command line replaces in its entirety the -vmargs from the config file.
+ * - user arguments from the config file are prepended to the user arguments defined in the
+ * config file. This is consistent with the java behaviour in the following case:
+ * java -Dtest="one" -Dtest="two" ... : test is set to the value "two"
+ */
+
+#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include "eclipseShm.h"
+#include "eclipseJNI.h"
+#include "eclipseConfig.h"
+#include "eclipseCommon.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <direct.h>
+#include <io.h>
+#include <fcntl.h>
+#else
+#include <unistd.h>
+#include <strings.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <ctype.h>
+
+#define MAX_PATH_LENGTH 2000
+#define MAX_SHARED_LENGTH (16 * 1024)
+
+/* Global Data */
+static _TCHAR* program = NULL; /* full pathname of the program */
+static _TCHAR* programDir = NULL; /* directory where program resides */
+static _TCHAR* javaVM = NULL; /* full pathname of the Java VM to run */
+static _TCHAR* jniLib = NULL; /* full path of a java vm library for JNI invocation */
+static _TCHAR* jarFile = NULL; /* full pathname of the startup jar file to run */
+static _TCHAR* sharedID = NULL; /* ID for the shared memory */
+static _TCHAR* officialName = NULL;
+
+_TCHAR* exitData = NULL; /* exit data set from Java */
+int initialArgc;
+_TCHAR** initialArgv = NULL;
+
+
+/* Define the special exit codes returned from Eclipse. */
+#define RESTART_LAST_EC 23
+#define RESTART_NEW_EC 24
+
+/* constants for launch mode */
+#define LAUNCH_JNI 1
+#define LAUNCH_EXE 2
+
+#define DEFAULT_EE _T_ECLIPSE("default.ee")
+
+/* Define error messages. (non-NLS) */
+static _TCHAR* exitMsg = _T_ECLIPSE("JVM terminated. Exit code=%d\n%s");
+static _TCHAR* javaFailureMsg = _T_ECLIPSE("Internal Error, unable to determine the results of running the JVM.");
+static _TCHAR* returnCodeMsg = _T_ECLIPSE("Java was started but returned exit code=%d\n%s");
+static _TCHAR* goVMMsg = _T_ECLIPSE("Start VM: %s\n");
+static _TCHAR* pathMsg = _T_ECLIPSE("%s in your current PATH");
+static _TCHAR* shareMsg = _T_ECLIPSE("No exit data available.");
+static _TCHAR* noVMMsg =
+_T_ECLIPSE("A Java Runtime Environment (JRE) or Java Development Kit (JDK)\n\
+must be available in order to run %s. No Java virtual machine\n\
+was found after searching the following locations:\n\
+%s");
+static _TCHAR* startupMsg =
+_T_ECLIPSE("The %s executable launcher was unable to locate its \n\
+companion launcher jar.");
+
+static _TCHAR* homeMsg =
+_T_ECLIPSE("The %s executable launcher was unable to locate its \n\
+home directory.");
+
+#define OLD_STARTUP _T_ECLIPSE("startup.jar")
+#define CLASSPATH_PREFIX _T_ECLIPSE("-Djava.class.path=")
+
+/* Define constants for the options recognized by the launcher. */
+#define CONSOLE _T_ECLIPSE("-console")
+#define CONSOLELOG _T_ECLIPSE("-consoleLog")
+#define DEBUG _T_ECLIPSE("-debug")
+#define OS _T_ECLIPSE("-os")
+#define OSARCH _T_ECLIPSE("-arch")
+#define NOSPLASH _T_ECLIPSE("-nosplash")
+#define LAUNCHER _T_ECLIPSE("-launcher")
+#define SHOWSPLASH _T_ECLIPSE("-showsplash")
+#define EXITDATA _T_ECLIPSE("-exitdata")
+#define STARTUP _T_ECLIPSE("-startup")
+#define VM _T_ECLIPSE("-vm")
+#define WS _T_ECLIPSE("-ws")
+#define NAME _T_ECLIPSE("-name")
+#define VMARGS _T_ECLIPSE("-vmargs") /* special option processing required */
+#define CP _T_ECLIPSE("-cp")
+#define CLASSPATH _T_ECLIPSE("-classpath")
+#define JAR _T_ECLIPSE("-jar")
+
+#define OPENFILE _T_ECLIPSE("--launcher.openFile")
+#define DEFAULTACTION _T_ECLIPSE("--launcher.defaultAction")
+#define TIMEOUT _T_ECLIPSE("--launcher.timeout")
+#define LIBRARY _T_ECLIPSE("--launcher.library")
+#define SUPRESSERRORS _T_ECLIPSE("--launcher.suppressErrors")
+#define INI _T_ECLIPSE("--launcher.ini")
+#define APPEND_VMARGS _T_ECLIPSE("--launcher.appendVmargs")
+#define OVERRIDE_VMARGS _T_ECLIPSE("--launcher.overrideVmargs")
+#define SECOND_THREAD _T_ECLIPSE("--launcher.secondThread")
+#define PERM_GEN _T_ECLIPSE("--launcher.XXMaxPermSize")
+
+#define XXPERMGEN _T_ECLIPSE("-XX:MaxPermSize=")
+#define ACTION_OPENFILE _T_ECLIPSE("openFile")
+
+/* constants for ee options file */
+#define EE_EXECUTABLE _T_ECLIPSE("-Dee.executable=")
+#define EE_CONSOLE _T_ECLIPSE("-Dee.executable.console=")
+#define EE_VM_LIBRARY _T_ECLIPSE("-Dee.vm.library=")
+#define EE_LIBRARY_PATH _T_ECLIPSE("-Dee.library.path=")
+#define EE_HOME _T_ECLIPSE("-Dee.home=")
+#define EE_FILENAME _T_ECLIPSE("-Dee.filename=")
+#define EE_HOME_VAR _T_ECLIPSE("${ee.home}")
+
+/* Define the variables to receive the option values. */
+static int needConsole = 0; /* True: user wants a console */
+static int debug = 0; /* True: output debugging info */
+static int noSplash = 0; /* True: do not show splash win */
+static int suppressErrors = 0; /* True: do not display errors dialogs */
+ int secondThread = 0; /* True: start the VM on a second thread */
+static int appendVmargs = 0; /* True: append cmdline vmargs to launcher.ini vmargs */
+
+static _TCHAR* showSplashArg = NULL; /* showsplash data (main launcher window) */
+static _TCHAR* splashBitmap = NULL; /* the actual splash bitmap */
+static _TCHAR * startupArg = NULL; /* path of the startup.jar the user wants to run relative to the program path */
+static _TCHAR* vmName = NULL; /* Java VM that the user wants to run */
+static _TCHAR* name = NULL; /* program name */
+static _TCHAR* permGen = NULL; /* perm gen size for sun */
+static _TCHAR** filePath = NULL; /* list of files to open */
+static _TCHAR* timeoutString = NULL; /* timeout value for opening a file */
+static _TCHAR* defaultAction = NULL; /* default action for non '-' command line arguments */
+static _TCHAR* iniFile = NULL; /* the launcher.ini file set if --launcher.ini was specified */
+
+/* variables for ee options */
+static _TCHAR* eeExecutable = NULL;
+static _TCHAR* eeConsole = NULL;
+static _TCHAR* eeLibrary = NULL;
+
+_TCHAR* eeLibPath = NULL; /* this one is global so others can see it */
+_TCHAR* eclipseLibrary = NULL; /* the shared library */
+
+/* Define a table for processing command line options. */
+typedef struct
+{
+ _TCHAR* name; /* the option recognized by the launcher */
+ void* value; /* the variable where the option value is saved */
+ /* value is a _TCHAR** or int* depending on if VALUE_IS_FLAG is set */
+ int flag; /* flags */
+ int remove; /* the number of argments to remove from the list, -1 can be used with VALUE_IS_LIST */
+} Option;
+
+/* flags for the Option struct */
+#define VALUE_IS_FLAG 1 /* value is an int*, if not set, value is a _TCHAR** or _TCHAR*** (VALUE_IS_LIST) */
+#define OPTIONAL_VALUE 2 /* value is optional, if next arg does not start with '-', */
+ /* don't assign it and only remove (remove - 1) arguments */
+#define ADJUST_PATH 4 /* value is a path, do processing on relative paths to try and make them absolute */
+#define VALUE_IS_LIST 8 /* value is a pointer to a tokenized _TCHAR* string for EE files, or a _TCHAR** list for the command line */
+#define INVERT_FLAG 16 /* invert the meaning of a flag, i.e. reset it */
+
+static Option options[] = {
+ { CONSOLE, &needConsole, VALUE_IS_FLAG, 0 },
+ { CONSOLELOG, &needConsole, VALUE_IS_FLAG, 0 },
+ { DEBUG, &debug, VALUE_IS_FLAG, 0 },
+ { NOSPLASH, &noSplash, VALUE_IS_FLAG, 1 },
+ { SUPRESSERRORS, &suppressErrors, VALUE_IS_FLAG, 1},
+ { SECOND_THREAD, &secondThread, VALUE_IS_FLAG, 1 },
+ { APPEND_VMARGS, &appendVmargs, VALUE_IS_FLAG, 1 },
+ { OVERRIDE_VMARGS, &appendVmargs, VALUE_IS_FLAG | INVERT_FLAG, 1 },
+ { LIBRARY, NULL, 0, 2 }, /* library was parsed by exe, just remove it */
+ { INI, &iniFile, 0, 2 },
+ { OS, &osArg, 0, 2 },
+ { OSARCH, &osArchArg, 0, 2 },
+ { SHOWSPLASH, &showSplashArg, OPTIONAL_VALUE, 2 },
+ { STARTUP, &startupArg, 0, 2 },
+ { VM, &vmName, 0, 2 },
+ { NAME, &name, 0, 2 },
+ { PERM_GEN, &permGen, 0, 2 },
+ { OPENFILE, &filePath, ADJUST_PATH | VALUE_IS_LIST, -1 },
+ { TIMEOUT, &timeoutString, 0, 2 },
+ { DEFAULTACTION,&defaultAction, 0, 2 },
+ { WS, &wsArg, 0, 2 } };
+static int optionsSize = (sizeof(options) / sizeof(options[0]));
+
+static Option eeOptions[] = {
+ { EE_EXECUTABLE, &eeExecutable, ADJUST_PATH, 0 },
+ { EE_CONSOLE, &eeConsole, ADJUST_PATH, 0 },
+ { EE_VM_LIBRARY, &eeLibrary, ADJUST_PATH, 0 },
+ { EE_LIBRARY_PATH, &eeLibPath, ADJUST_PATH | VALUE_IS_LIST, 0 }
+};
+static int eeOptionsSize = (sizeof(eeOptions) / sizeof(eeOptions[0]));
+
+/* Define the required VM arguments (all platforms). */
+static _TCHAR* cp = NULL;
+static _TCHAR* cpValue = NULL;
+static _TCHAR** reqVMarg[] = { &cp, &cpValue, NULL }; /* required VM args */
+static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */
+static _TCHAR** eeVMarg = NULL; /* vm args specified in ee file */
+static int nEEargs = 0;
+
+/* Local methods */
+static void parseArgs( int* argc, _TCHAR* argv[] );
+static void processDefaultAction(int argc, _TCHAR* argv[]);
+static void mergeUserVMArgs( _TCHAR **vmArgs[] );
+static void getVMCommand( int launchMode, int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] );
+static int determineVM(_TCHAR** msg);
+static int vmEEProps(_TCHAR* eeFile, _TCHAR** msg);
+static int processEEProps(_TCHAR* eeFile);
+static _TCHAR** buildLaunchCommand( _TCHAR* program, _TCHAR** vmArgs, _TCHAR** progArgs );
+static _TCHAR** parseArgList( _TCHAR *data );
+static _TCHAR* formatVmCommandMsg( _TCHAR* args[], _TCHAR* vmArgs[], _TCHAR* progArgs[] );
+static _TCHAR* getDefaultOfficialName();
+static _TCHAR* findStartupJar();
+static _TCHAR* findSplash(_TCHAR* splashArg);
+static _TCHAR** getRelaunchCommand( _TCHAR **vmCommand );
+static const _TCHAR* getVMArch();
+
+#ifdef _WIN32
+static void createConsole();
+static void fixDLLSearchPath();
+static int isConsoleLauncher();
+#endif
+static int consoleLauncher = 0;
+
+/* Record the arguments that were used to start the original executable */
+JNIEXPORT void setInitialArgs(int argc, _TCHAR** argv, _TCHAR* lib) {
+ initialArgc = argc;
+ initialArgv = argv;
+ eclipseLibrary = lib;
+}
+
+/* this method must match the RunMethod typedef in eclipseMain.c */
+/* vmArgs must be NULL terminated */
+JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
+{
+ _TCHAR** vmCommand = NULL;
+ _TCHAR** vmCommandArgs = NULL;
+ _TCHAR** progCommandArgs = NULL;
+ _TCHAR** relaunchCommand = NULL;
+ _TCHAR* errorMsg = NULL, *msg = NULL;
+ JavaResults* javaResults = NULL;
+ int launchMode;
+ int running = 1;
+
+ /* arg[0] should be the full pathname of this program. */
+ program = _tcsdup( argv[0] );
+
+ /* Parse command line arguments (looking for the VM to use). */
+ /* Override configuration file arguments */
+ parseArgs( &argc, argv );
+
+ /* Initialize official program name */
+ officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName();
+
+ if (defaultAction != NULL) {
+ processDefaultAction(initialArgc, initialArgv);
+ }
+
+ /* try to open the specified file in an already running eclipse */
+ /* on Mac we are only registering an event handler here, always do this */
+#ifndef MACOSX
+ if (filePath != NULL && filePath[0] != NULL)
+#endif
+ {
+ int timeout = 60;
+ if (timeoutString != NULL)
+ _stscanf(timeoutString, _T_ECLIPSE("%d"), &timeout);
+ if (reuseWorkbench(filePath, timeout) > 0)
+ return 0;
+ }
+
+#ifdef MACOSX
+ /* Most platforms, we will initialize the window system later before trying to do any
+ * graphics. On Mac, we need it initialized to get the dock icon properly, so always do
+ * it now.
+ */
+ initWindowSystem( &argc, argv, !noSplash );
+#elif _WIN32
+ /* this must be before doing any console stuff, platforms other than win32 leave this set to 0 */
+ consoleLauncher = isConsoleLauncher();
+
+ /*fix the DLL search path for security */
+ fixDLLSearchPath();
+#endif
+
+ /* Find the directory where the Eclipse program is installed. */
+ programDir = getProgramDir();
+ if (programDir == NULL)
+ {
+ errorMsg = malloc( (_tcslen(homeMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, homeMsg, officialName );
+ if (!suppressErrors)
+ displayMessage( officialName, errorMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, errorMsg);
+ free( errorMsg );
+ exit( 1 );
+ }
+
+ if (vmArgs != NULL) {
+ /* reconcile VM Args from commandline with launcher.ini (append or override),
+ * this always allocates new memory */
+ mergeUserVMArgs(&vmArgs);
+ /* platform specific processing of user's vmargs */
+ processVMArgs(&vmArgs);
+ }
+
+ launchMode = determineVM(&msg);
+ if (launchMode == -1) {
+ /* problem */
+ errorMsg = malloc((_tcslen(noVMMsg) + _tcslen(officialName) + _tcslen(msg) + 1) * sizeof(_TCHAR));
+ _stprintf( errorMsg, noVMMsg, officialName, msg );
+ if (!suppressErrors)
+ displayMessage( officialName, errorMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, errorMsg);
+ free( errorMsg );
+ free( msg );
+ exit(1);
+ }
+
+ /* Find the startup.jar */
+ jarFile = findStartupJar();
+ if(jarFile == NULL) {
+ errorMsg = malloc( (_tcslen(startupMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, startupMsg, officialName );
+ if (!suppressErrors)
+ displayMessage( officialName, errorMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, errorMsg);
+ free( errorMsg );
+ exit( 1 );
+ }
+
+#ifdef _WIN32
+ if( launchMode == LAUNCH_JNI && (debug || needConsole) ) {
+ createConsole();
+ }
+#endif
+
+ /* If the showsplash option was given and we are using JNI */
+ if (!noSplash && showSplashArg)
+ {
+ splashBitmap = findSplash(showSplashArg);
+ if (splashBitmap != NULL && launchMode == LAUNCH_JNI) {
+ showSplash(splashBitmap);
+ }
+ }
+
+ /* not using JNI launching, need some shared data */
+ if (launchMode == LAUNCH_EXE && createSharedData( &sharedID, MAX_SHARED_LENGTH )) {
+ if (debug) {
+ if (!suppressErrors)
+ displayMessage( officialName, shareMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, shareMsg);
+ }
+ }
+
+ /* the startup jarFile goes on the classpath */
+ if (launchMode == LAUNCH_JNI) {
+ /* JNI launching, classpath is set using -Djava.class.path */
+ cp = malloc((_tcslen(CLASSPATH_PREFIX) + _tcslen(jarFile) + 1) * sizeof(_TCHAR));
+ cp = _tcscpy(cp, CLASSPATH_PREFIX);
+ _tcscat(cp, jarFile);
+ } else {
+ /* exec java, jar is specified with -jar */
+ cp = JAR;
+ cpValue = malloc((_tcslen(jarFile) + 1) * sizeof(_TCHAR));
+ _tcscpy(cpValue, jarFile);
+ }
+
+ /* Get the command to start the Java VM. */
+ userVMarg = vmArgs;
+ getVMCommand( launchMode, argc, argv, &vmCommandArgs, &progCommandArgs );
+
+ if (launchMode == LAUNCH_EXE) {
+ vmCommand = buildLaunchCommand(javaVM, vmCommandArgs, progCommandArgs);
+ }
+
+ /* While the Java VM should be restarted */
+ while(running)
+ {
+ msg = formatVmCommandMsg( vmCommand, vmCommandArgs, progCommandArgs );
+ if (debug) _tprintf( goVMMsg, msg );
+
+ if(launchMode == LAUNCH_JNI) {
+ javaResults = startJavaVM(jniLib, vmCommandArgs, progCommandArgs, jarFile);
+ } else {
+ javaResults = launchJavaVM(vmCommand);
+ }
+
+ if (javaResults == NULL) {
+ /* shouldn't happen, but just in case */
+ javaResults = malloc(sizeof(JavaResults));
+ javaResults->launchResult = -11;
+ javaResults->runResult = 0;
+ javaResults->errorMessage = _tcsdup(javaFailureMsg);
+ }
+
+ switch( javaResults->launchResult + javaResults->runResult ) {
+ case 0: /* normal exit */
+ running = 0;
+ break;
+ case RESTART_LAST_EC:
+ if (launchMode == LAUNCH_JNI) {
+ /* copy for relaunch, +1 to ensure NULL terminated */
+ relaunchCommand = malloc((initialArgc + 1) * sizeof(_TCHAR*));
+ memcpy(relaunchCommand, initialArgv, (initialArgc + 1) * sizeof(_TCHAR*));
+ relaunchCommand[initialArgc] = 0;
+ relaunchCommand[0] = program;
+ running = 0;
+ }
+ break;
+
+ case RESTART_NEW_EC:
+ if(launchMode == LAUNCH_EXE) {
+ if (exitData != NULL) free(exitData);
+ if (getSharedData( sharedID, &exitData ) != 0)
+ exitData = NULL;
+ }
+ if (exitData != 0) {
+ if (vmCommand != NULL) free( vmCommand );
+ vmCommand = parseArgList( exitData );
+ if (launchMode == LAUNCH_JNI) {
+ relaunchCommand = getRelaunchCommand(vmCommand);
+ running = 0;
+ }
+ } else {
+ running = 0;
+ if (debug) {
+ if (!suppressErrors)
+ displayMessage( officialName, shareMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, shareMsg);
+ }
+ }
+ break;
+ default: {
+ _TCHAR *title = _tcsdup(officialName);
+ running = 0;
+ errorMsg = NULL;
+ if (launchMode == LAUNCH_EXE) {
+ if (exitData != NULL) free(exitData);
+ if (getSharedData( sharedID, &exitData ) != 0)
+ exitData = NULL;
+ }
+ if (exitData != 0) {
+ errorMsg = exitData;
+ exitData = NULL;
+ if (_tcslen( errorMsg ) > 0) {
+ _TCHAR *str;
+ if (_tcsncmp(errorMsg, _T_ECLIPSE("<title>"), _tcslen(_T_ECLIPSE("<title>"))) == 0) {
+ str = _tcsstr(errorMsg, _T_ECLIPSE("</title>"));
+ if (str != NULL) {
+ free( title );
+ str[0] = _T_ECLIPSE('\0');
+ title = _tcsdup( errorMsg + _tcslen(_T_ECLIPSE("<title>")) );
+ str = _tcsdup( str + _tcslen(_T_ECLIPSE("</title>")) );
+ free( errorMsg );
+ errorMsg = str;
+ }
+ }
+ }
+ } else {
+ if (debug) {
+ if (!suppressErrors)
+ displayMessage( title, shareMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), title, shareMsg);
+ }
+ }
+ if (errorMsg == NULL) {
+ if (javaResults->runResult) {
+ /* java was started ok, but returned non-zero exit code */
+ errorMsg = malloc( (_tcslen(returnCodeMsg) + _tcslen(msg) + 10) *sizeof(_TCHAR));
+ _stprintf(errorMsg, returnCodeMsg,javaResults->runResult, msg);
+ } else if (javaResults->errorMessage != NULL){
+ /* else we had a problem launching java, use custom error message */
+ errorMsg = javaResults->errorMessage;
+ } else {
+ /* no custom message, use generic message */
+ errorMsg = malloc( (_tcslen(exitMsg) + _tcslen(msg) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, exitMsg, javaResults->launchResult, msg );
+ }
+ }
+
+ if (_tcslen(errorMsg) > 0) {
+ if (!suppressErrors)
+ displayMessage( title, errorMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), title, errorMsg);
+ }
+ free( errorMsg );
+ free( title );
+ break;
+ }
+ }
+ free( msg );
+ }
+
+ if(relaunchCommand != NULL)
+ restartLauncher(NULL, relaunchCommand);
+
+ if (launchMode == LAUNCH_JNI)
+ cleanupVM(javaResults->launchResult ? javaResults->launchResult : javaResults->runResult);
+
+ if (sharedID != NULL) {
+ destroySharedData( sharedID );
+ free( sharedID );
+ }
+
+ /* Cleanup time. */
+ free( vmCommandArgs );
+ free( progCommandArgs );
+ free( jarFile );
+ free( programDir );
+ free( program );
+ free( officialName );
+ if(vmCommand != NULL) free(vmCommand);
+ if(launchMode == LAUNCH_JNI) free(cp);
+ if(cpValue != NULL) free(cpValue);
+ if(exitData != NULL) free(exitData);
+ if(splashBitmap != NULL) free(splashBitmap);
+ if(vmArgs != NULL) free(vmArgs);
+
+ if (javaResults == NULL)
+ return -1;
+
+ /* reuse the running variable for convenience */
+ running = javaResults->launchResult != 0 ? javaResults->launchResult : javaResults->runResult;
+ free(javaResults);
+ return running;
+}
+
+static _TCHAR** buildLaunchCommand( _TCHAR* program, _TCHAR** vmArgs, _TCHAR** progArgs ) {
+ int nVM = -1, nProg = -1;
+ _TCHAR** result;
+
+ while(vmArgs[++nVM] != NULL) {}
+ while(progArgs[++nProg] != NULL) {}
+
+ result = malloc((nVM + nProg + 2) * sizeof(_TCHAR*));
+ memset(result, 0, (nVM + nProg + 2) * sizeof(_TCHAR*));
+ result[0] = program;
+ memcpy(result + 1, vmArgs, nVM * sizeof(_TCHAR*));
+ memcpy(result + 1 + nVM, progArgs, nProg * sizeof(_TCHAR*));
+ return result;
+}
+
+static void processDefaultAction(int argc, _TCHAR* argv[]) {
+ /* scan the arg list, no default if any start with '-' */
+ int i = 0;
+ for (i = 0; i < argc; i++) {
+ if (argv[i][0] == _T_ECLIPSE('-'))
+ return;
+ }
+ /* argv[0] is the program (eclipse), we process the default actions by inserting
+ * the appropriate -argument at argv[1]
+ */
+ if (argc <= 1)
+ return;
+
+ if (_tcsicmp(defaultAction, ACTION_OPENFILE) == 0) {
+ int newArgc = argc + 1;
+ _TCHAR ** newArgv = malloc((newArgc + 1) * sizeof(_TCHAR*));
+ newArgv[0] = argv[0];
+ newArgv[1] = OPENFILE;
+ memcpy(&newArgv[2], &argv[1], argc * sizeof(_TCHAR*));
+ parseArgs(&newArgc, newArgv);
+ free(newArgv);
+ }
+}
+
+/*
+ * Parse arguments of the command.
+ */
+static void parseArgs(int* pArgc, _TCHAR* argv[]) {
+ Option* option;
+ int remArgs;
+ int index;
+ int i;
+ _TCHAR * c;
+
+ /* For each user defined argument (excluding the program) */
+ for (index = 1; index < *pArgc; index++) {
+ remArgs = 0;
+
+ /* Find the corresponding argument is a option supported by the launcher */
+ option = NULL;
+ for (i = 0; option == NULL && i < optionsSize; i++) {
+ if (_tcsicmp(argv[index], options[i].name) == 0) {
+ option = &options[i];
+ break;
+ }
+ }
+
+ /* If the option is recognized by the launcher */
+ if (option != NULL) {
+ int optional = 0;
+ c = option->name;
+ /* If the option requires a value and there is one, extract the value. */
+ if (option->value != NULL) {
+ if (option->flag & VALUE_IS_FLAG)
+ *((int *) option->value) = (option->flag & INVERT_FLAG) ? 0 : 1;
+ else {
+ int count = 1;
+ if (option->flag & VALUE_IS_LIST) {
+ /* count how many args, this is the -argument itself + following the non'-' args */
+ while (count + index < *pArgc && argv[count + index][0] != _T_ECLIPSE('-'))
+ count++;
+
+ /* allocate memory for a _TCHAR* list and initialize it with NULLs*/
+ *((void**) option->value) = malloc(count * sizeof(_TCHAR *));
+ memset(*((void **) option->value), 0, count * sizeof(_TCHAR *));
+
+ if (option->remove != 0)
+ option->remove = count;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((index + i + 1) < *pArgc) {
+ _TCHAR * next = argv[index + i + 1];
+ if (option->flag & ADJUST_PATH)
+ next = checkPath(next, getProgramDir(), 0);
+ if (next[0] != _T_ECLIPSE('-')) {
+ if (option->flag & VALUE_IS_LIST)
+ (*((_TCHAR***) option->value))[i] = next;
+ else
+ *((_TCHAR**) option->value) = next;
+ } else if (option->flag & OPTIONAL_VALUE) {
+ /* value was optional, and the next arg starts with '-' */
+ optional = 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* If the option requires a flag to be set, set it. */
+ remArgs = option->remove - optional;
+ }
+
+ /* Remove any matched arguments from the list. */
+ if (remArgs > 0) {
+ for (i = (index + remArgs); i <= *pArgc; i++) {
+ argv[i - remArgs] = argv[i];
+ }
+ index--;
+ *pArgc -= remArgs;
+ }
+ }
+}
+
+/*
+ * Parse the data into a list of arguments separated by \n.
+ */
+static _TCHAR** parseArgList( _TCHAR* data ) {
+ int totalArgs = 0, dst = 0;
+ size_t length;
+ _TCHAR *ch1, *ch2, **execArg;
+ length = _tcslen( data );
+ ch1 = ch2 = data;
+ while ((ch2 = _tcschr( ch1, _T_ECLIPSE('\n') )) != NULL) {
+ totalArgs++;
+ ch1 = ch2 + 1;
+ }
+ if (ch1 != data + length) totalArgs++;
+ execArg = malloc( (totalArgs + 1) * sizeof( _TCHAR* ) );
+ ch1 = ch2 = data;
+ while ((ch2 = _tcschr( ch1, _T_ECLIPSE('\n') )) != NULL) {
+ execArg[ dst++ ] = ch1;
+ ch2[ 0 ] = _T_ECLIPSE('\0');
+ ch1 = ch2 + 1;
+ }
+ if (ch1 != data + length) execArg[ dst++ ] = ch1;
+ execArg[ dst++ ] = NULL;
+ return execArg;
+}
+
+/* Return the list of args from the launcher ini file (if it exists). Caller is responsible to free(). */
+static _TCHAR** getConfigArgs() {
+ _TCHAR** configArgv = NULL;
+ _TCHAR * configFile = NULL;
+ int configArgc = 0;
+ int ret = 0;
+
+ configFile = (iniFile != NULL) ? iniFile : getIniFile(program, consoleLauncher);
+ ret = readConfigFile(configFile, &configArgc, &configArgv);
+ if (ret == 0)
+ return configArgv;
+ return NULL;
+}
+
+/** Append Commandline VM Args to VM Args that came from the launcher.ini
+ * Always returns new memory even if no new arguments were appended */
+static void mergeUserVMArgs(_TCHAR **vmArgs[]) {
+ _TCHAR** configVMArgs = NULL;
+ _TCHAR** configArgs = NULL;
+
+ if (appendVmargs != 0 && indexOf(VMARGS, initialArgv) > 0) {
+ /* Get vmargs from the launcher.ini, if any */
+ configArgs = getConfigArgs();
+ if (configArgs != NULL) {
+ int vmArg = indexOf(VMARGS, configArgs);
+ if (vmArg >= 0)
+ configVMArgs = configArgs + vmArg + 1;
+ }
+ }
+
+ /* This always allocates new memory so we don't need to guess if it is safe
+ * to free later */
+ *vmArgs = concatArgs(configVMArgs, *vmArgs);
+ if (configArgs != NULL)
+ free(configArgs);
+}
+
+static void adjustVMArgs(_TCHAR *javaVM, _TCHAR *jniLib, _TCHAR **vmArgv[]) {
+ /* Sun VMs need some extra perm gen space */
+ /* Detecting Sun VM is expensive - only do so if necessary */
+ if (permGen != NULL) {
+ int specified = 0, i = -1;
+
+ /* first check to see if it is already specified */
+ while ((*vmArgv)[++i] != NULL) {
+ /* we are also counting the number of args here */
+ if (!specified && _tcsncmp((*vmArgv)[i], XXPERMGEN, _tcslen(XXPERMGEN)) == 0) {
+ specified = 1;
+ }
+ }
+
+ if (!specified && isSunVM(javaVM, jniLib)) {
+ _TCHAR ** oldArgs = *vmArgv;
+ _TCHAR *newArg = malloc((_tcslen(XXPERMGEN) + _tcslen(permGen) + 1) * sizeof(_TCHAR));
+ _stprintf(newArg, _T_ECLIPSE("%s%s"), XXPERMGEN, permGen);
+
+ *vmArgv = malloc((i + 2) * sizeof(_TCHAR *));
+ memcpy(*vmArgv, oldArgs, i * sizeof(_TCHAR *));
+ (*vmArgv)[i] = newArg;
+ (*vmArgv)[i + 1] = 0;
+ }
+ }
+}
+
+/*
+ * Get the command and arguments to start the Java VM.
+ *
+ * Memory allocated by this function is assumed to be
+ * deallocated when the program terminates.
+ *
+ * Some of the arguments returned by this function were
+ * passed directly from the main( argv ) array so they
+ * should not be deallocated.
+ *
+ * Arguments are split into 2: vm arguments and program arguments
+ */
+static void getVMCommand( int launchMode, int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] )
+{
+ _TCHAR** vmArg;
+ int nReqVMarg = 0;
+ int nVMarg = 0;
+ int totalVMArgs;
+ int totalProgArgs;
+ int src;
+ int dst;
+
+ /* If the user specified "-vmargs", add them instead of the default VM args. */
+ vmArg = (userVMarg != NULL) ? userVMarg : getArgVM( (launchMode == LAUNCH_JNI) ? jniLib : javaVM );
+
+ adjustVMArgs(javaVM, jniLib, &vmArg);
+
+ /* Calculate the number of VM arguments. */
+ while (vmArg[ nVMarg ] != NULL)
+ nVMarg++;
+
+ /* Calculate the number of required VM arguments. */
+ while (reqVMarg[ nReqVMarg ] != NULL)
+ nReqVMarg++;
+
+ /* VM argument list */
+ totalVMArgs = nVMarg + nReqVMarg + nEEargs + 1;
+ *vmArgv = malloc( totalVMArgs * sizeof(_TCHAR*) );
+
+ dst = 0;
+ for (src = 0; src < nVMarg; src++){
+ /*if the user specified a classpath, skip it */
+ if(_tcscmp(vmArg[src], cp) == 0){
+ src++;
+ continue;
+ }
+ (*vmArgv)[ dst++ ] = vmArg[ src ];
+ }
+
+ if (eeVMarg != NULL)
+ for (src = 0; src < nEEargs; src++)
+ (*vmArgv)[ dst++ ] = eeVMarg[ src ];
+
+ /* For each required VM arg */
+ for (src = 0; src < nReqVMarg; src++)
+ if( *(reqVMarg[src]) != NULL)
+ (*vmArgv)[ dst++ ] = *(reqVMarg[ src ]);
+
+
+ (*vmArgv)[dst] = NULL;
+
+ /* Program arguments */
+ /* OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> +
+ * + LIBRARY <library> + SHOWSPLASH <cmd> + EXITDATA <cmd> + STARTUP <jar> + OVERRIDE/APPEND + argv[] + VM + <vm> +
+ * VMARGS + vmArg + requiredVMargs
+ * + NULL)
+ */
+ totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + argc + 2 + 1 + nVMarg + nEEargs + nReqVMarg + 1;
+ *progArgv = malloc( totalProgArgs * sizeof( _TCHAR* ) );
+ dst = 0;
+
+ /* Append the required options. */
+ (*progArgv)[ dst++ ] = OS;
+ (*progArgv)[ dst++ ] = osArg;
+ (*progArgv)[ dst++ ] = WS;
+ (*progArgv)[ dst++ ] = wsArg;
+ if (_tcslen(osArchArg) > 0) {
+ (*progArgv)[ dst++ ] = OSARCH;
+ (*progArgv)[ dst++ ] = osArchArg;
+ }
+
+ /* Append the show splash window command, if defined. */
+ if (!noSplash)
+ {
+ (*progArgv)[ dst++ ] = SHOWSPLASH;
+ if(splashBitmap != NULL)
+ (*progArgv)[ dst++ ] = splashBitmap;
+ }
+
+ /* Append the launcher command */
+ (*progArgv)[ dst++ ] = LAUNCHER;
+ (*progArgv)[ dst++ ] = program;
+
+ /* Append the name command */
+ (*progArgv)[ dst++ ] = NAME;
+ (*progArgv)[ dst++ ] = officialName;
+
+ /* And the shared library */
+ if (eclipseLibrary != NULL) {
+ (*progArgv)[ dst++ ] = LIBRARY;
+ (*progArgv)[ dst++ ] = eclipseLibrary;
+ }
+
+ /* the startup jar */
+ (*progArgv)[ dst++ ] = STARTUP;
+ (*progArgv)[ dst++ ] = jarFile;
+
+ /* override or append vm args */
+ (*progArgv)[ dst++ ] = appendVmargs ? APPEND_VMARGS : OVERRIDE_VMARGS;
+
+ /* Append the exit data command. */
+ if (sharedID) {
+ (*progArgv)[ dst++ ] = EXITDATA;
+ (*progArgv)[ dst++ ] = sharedID;
+ }
+
+ /* Append the remaining user defined arguments. */
+ for (src = 1; src < argc; src++)
+ {
+ (*progArgv)[ dst++ ] = argv[ src ];
+ }
+
+ /* Append VM and VMARGS to be able to relaunch using exit data. */
+ (*progArgv)[ dst++ ] = VM;
+ if(jniLib != NULL)
+ (*progArgv)[ dst++ ] = jniLib;
+ else
+ (*progArgv)[ dst++ ] = javaVM;
+ (*progArgv)[ dst++ ] = VMARGS;
+
+ for (src = 0; src < nVMarg; src++)
+ (*progArgv)[ dst++ ] = vmArg[ src ];
+
+ if (eeVMarg != NULL)
+ for (src = 0; src < nEEargs; src++)
+ (*progArgv)[ dst++ ] = eeVMarg[ src ];
+
+ /* For each required VM arg */
+ for (src = 0; src < nReqVMarg; src++)
+ if (*(reqVMarg[src]) != NULL)
+ (*progArgv)[ dst++ ] = *(reqVMarg[ src ]);
+
+ (*progArgv)[ dst++ ] = NULL;
+
+ }
+
+ /* Format the JVM start command for error messages
+ *
+ * This method formats a string with the JVM start command (and all arguments)
+ * that can be used in displaying error messages. The string returned from this
+ * method is probably not NLS compliant and must be deallocated by the caller.
+ *
+ * The arguments in the message are either args (if not null) or the combination
+ * of vmArgs + progArgs
+ */
+static _TCHAR* formatVmCommandMsg( _TCHAR* args[], _TCHAR* vmArgs[], _TCHAR* progArgs[] )
+{
+ int index;
+ size_t length = 0;
+ _TCHAR** list;
+ _TCHAR* ch;
+ _TCHAR* message;
+
+ /* Determine the length of the message buffer. */
+ if(args != NULL) list = args;
+ else list = vmArgs;
+ while(list != NULL) {
+ for (index = 0; list[index] != NULL; index++)
+ {
+ length += _tcslen(list[index]) + 1;
+ }
+ if(list == vmArgs) list = progArgs;
+ else list = NULL;
+ }
+ message = malloc( (length + 5) * sizeof(_TCHAR) );
+
+ /* Format the message such that options (args starting with '-') begin
+ on a new line. Otherwise, the Motif MessageBox does not automatically wrap
+ the messages and the message window can extend beyond both sides of the display. */
+ ch = message;
+ if(args != NULL) list = args;
+ else list = vmArgs;
+ while(list != NULL) {
+ for (index = 0; list[index] != NULL; index++)
+ {
+ if (ch != message && list[index][0] == _T_ECLIPSE('-') && *(ch-1) == _T_ECLIPSE(' '))
+ *(ch-1) = _T_ECLIPSE('\n');
+ _tcscpy( ch, list[index] );
+ ch += _tcslen( list[index] );
+ *ch++ = _T_ECLIPSE(' ');
+ }
+ if(list == vmArgs) list = progArgs;
+ else list = NULL;
+ }
+ *ch = _T_ECLIPSE('\0');
+
+ return message;
+}
+
+_TCHAR* getOfficialName() {
+ return officialName;
+}
+
+void setOfficialName(_TCHAR* name) {
+ officialName = name;
+}
+
+_TCHAR* getProgramPath() {
+ return program;
+}
+
+void setProgramPath(_TCHAR* path) {
+ program = path;
+}
+
+/*
+ * Determine the default official application name
+ *
+ * This function provides the default application name that appears in a variety of
+ * places such as: title of message dialog, title of splash screen window
+ * that shows up in Windows task bar.
+ * It is computed from the name of the launcher executable and
+ * by capitalizing the first letter. e.g. "c:/ide/eclipse.exe" provides
+ * a default name of "Eclipse".
+ */
+static _TCHAR* getDefaultOfficialName()
+{
+ _TCHAR *ch = NULL;
+
+ /* Skip the directory part */
+ ch = lastDirSeparator( program );
+ if (ch == NULL) ch = program;
+ else ch++;
+
+ ch = _tcsdup( ch );
+#ifdef _WIN32
+ {
+ /* Search for the extension .exe and cut it */
+ _TCHAR *extension = _tcsrchr(ch, _T_ECLIPSE('.'));
+ if (extension != NULL)
+ {
+ *extension = _T_ECLIPSE('\0');
+ }
+ }
+#endif
+ /* Upper case the first character */
+#ifndef LINUX
+ {
+ *ch = _totupper(*ch);
+ }
+#else
+ {
+ if (*ch >= 'a' && *ch <= 'z')
+ {
+ *ch -= 32;
+ }
+ }
+#endif
+ return ch;
+}
+
+/* Determine the Program Directory
+ *
+ * This function takes the directory where program executable resides and
+ * determines the installation directory.
+ */
+_TCHAR* getProgramDir( )
+{
+ _TCHAR* ch;
+ _TCHAR* programDir;
+ if (program == NULL)
+ return NULL;
+ programDir = malloc( (_tcslen( program ) + 1) * sizeof(_TCHAR) );
+ _tcscpy( programDir, program );
+ ch = lastDirSeparator( programDir );
+ if (ch != NULL)
+ {
+ *(ch+1) = _T_ECLIPSE('\0');
+ return programDir;
+ }
+
+ free( programDir );
+ return NULL;
+}
+
+static _TCHAR* findSplash(_TCHAR* splashArg) {
+ struct _stat stats;
+ _TCHAR *ch;
+ _TCHAR *path, *prefix;
+ size_t length;
+
+ if (splashArg == NULL)
+ return NULL;
+
+ splashArg = _tcsdup(splashArg);
+ length = _tcslen(splashArg);
+ /* _tstat doesn't seem to like dirSeparators on the end */
+ while (IS_DIR_SEPARATOR(splashArg[length - 1])) {
+ splashArg[--length] = 0;
+ }
+
+ /* does splashArg exist */
+ if (_tstat(splashArg, &stats) == 0) {
+ /* pointing to a file */
+ if (stats.st_mode & S_IFREG) {
+ /* file, use it*/
+ return splashArg;
+ } else if (stats.st_mode & S_IFDIR) {
+ /*directory, look for splash.bmp*/
+ ch = malloc( (length + 12) * sizeof(_TCHAR));
+ _stprintf( ch, _T_ECLIPSE("%s%c%s"), splashArg, dirSeparator, _T_ECLIPSE("splash.bmp") );
+ if (_tstat(ch, &stats) == 0 && stats.st_mode & S_IFREG) {
+ free(splashArg);
+ return ch;
+ }
+ free(ch);
+ }
+ free(splashArg);
+ return NULL;
+ }
+
+ /* doesn't exist, separate into path & prefix and look for a /path/prefix_<version> */
+ ch = lastDirSeparator( splashArg );
+ if (ch != NULL) {
+ if (IS_ABSOLUTE(splashArg))
+ { /*absolute path*/
+ path = _tcsdup(splashArg);
+ path[ch - splashArg] = 0;
+ } else {
+ /* relative path, prepend with programDir */
+ path = malloc( (_tcslen(programDir) + ch - splashArg + 2) * sizeof(_TCHAR));
+ *ch = 0;
+ _stprintf(path, _T_ECLIPSE("%s%c%s"), programDir, dirSeparator, splashArg);
+ *ch = dirSeparator;
+ }
+ prefix = _tcsdup(ch + 1);
+ } else {
+ /* No separator, treat splashArg as the prefix and look in the plugins dir */
+ path = malloc( (_tcslen(programDir) + 9) * sizeof(_TCHAR));
+ _stprintf(path, _T_ECLIPSE("%s%c%s"), programDir, dirSeparator, _T_ECLIPSE("plugins"));
+ prefix = _tcsdup(splashArg);
+ }
+
+ ch = findFile(path, prefix);
+ free(path);
+ free(prefix);
+ free(splashArg);
+ if (ch != NULL) {
+ path = malloc((_tcslen(ch) + 12) * sizeof(_TCHAR));
+ _stprintf( path, _T_ECLIPSE("%s%c%s"), ch, dirSeparator, _T_ECLIPSE("splash.bmp") );
+ return path;
+ }
+ return NULL;
+}
+
+static _TCHAR* findStartupJar(){
+ _TCHAR * file, *ch;
+ _TCHAR * pluginsPath;
+ struct _stat stats;
+ size_t pathLength, progLength;
+
+ if( startupArg != NULL ) {
+ /* startup jar was specified on the command line */
+ ch = _tcsdup(startupArg);
+ /* check path will check relative paths against programDir and workingDir */
+ file = checkPath(ch, programDir, 1);
+ if(file != ch)
+ free(ch);
+ /* check existence */
+ if (_tstat( file, &stats ) != 0) {
+ free(file);
+ file = NULL;
+ }
+ return file;
+ }
+
+ progLength = pathLength = _tcslen(programDir);
+#ifdef MACOSX
+ pathLength += 9;
+#endif
+ pluginsPath = malloc( (pathLength + 1 + 7 + 1) * sizeof(_TCHAR));
+ _tcscpy(pluginsPath, programDir);
+ if(!IS_DIR_SEPARATOR(pluginsPath[progLength - 1])) {
+ pluginsPath[progLength] = dirSeparator;
+ pluginsPath[progLength + 1] = 0;
+ }
+#ifdef MACOSX
+ _tcscat(pluginsPath, _T_ECLIPSE("../../../"));
+#endif
+ _tcscat(pluginsPath, _T_ECLIPSE("plugins"));
+
+ /* equinox startup jar? */
+ file = findFile(pluginsPath, DEFAULT_EQUINOX_STARTUP);
+ if(file != NULL)
+ return file;
+
+ /* old startup.jar? */
+ ch = OLD_STARTUP;
+ file = checkPath(ch, programDir, 1);
+ if (_tstat( file, &stats ) == 0)
+ return (file == ch) ? _tcsdup(ch) : file;
+
+ return NULL;
+}
+
+/*
+ * Return the portion of the vmCommand that should be used for relaunching
+ *
+ * The memory allocated for the command array must be freed
+ */
+static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand )
+{
+ int i = -1, req = 0, begin = -1;
+ int idx = 0;
+ _TCHAR ** relaunch;
+
+ if (vmCommand == NULL) return NULL;
+ while(vmCommand[++i] != NULL){
+ if ( begin == -1 && _tcsicmp( vmCommand[i], *reqVMarg[req] ) == 0) {
+ if(reqVMarg[++req] == NULL || *reqVMarg[req] == NULL){
+ begin = i + 1;
+ }
+ }
+ }
+
+ relaunch = malloc((1 + i + 1) * sizeof(_TCHAR *));
+ relaunch[idx++] = program;
+ if(begin == -1) {
+ begin = 1;
+ }
+ for (i = begin; vmCommand[i] != NULL; i++){
+ if (_tcsicmp(vmCommand[i], SHOWSPLASH) == 0) {
+ /* remove if the next argument is not the bitmap to show */
+ if(vmCommand[i + 1] != NULL && vmCommand[i + 1][0] == _T_ECLIPSE('-')) {
+ continue;
+ }
+ } else if(_tcsncmp(vmCommand[i], CLASSPATH_PREFIX, _tcslen(CLASSPATH_PREFIX)) == 0) {
+ /* skip -Djava.class.path=... */
+ continue;
+ }
+ relaunch[idx++] = vmCommand[i];
+ }
+ if(_tcsicmp(relaunch[idx - 1], VMARGS) == 0)
+ relaunch[idx - 1] = NULL;
+ relaunch[idx] = NULL;
+ return relaunch;
+}
+
+#ifdef _WIN32
+static void createConsole() {
+#ifndef WIN64
+#define intptr_t long
+#endif
+ intptr_t stdHandle;
+ int conHandle;
+ FILE *fp;
+
+ AllocConsole();
+
+ /* redirect stdout */
+ stdHandle = (intptr_t) GetStdHandle(STD_OUTPUT_HANDLE);
+ conHandle = _open_osfhandle(stdHandle, _O_TEXT);
+ if (conHandle != -1) {
+ fp = _fdopen(conHandle, "w");
+ *stdout = *fp;
+ }
+
+ /* redirect stdin */
+ stdHandle = (intptr_t) GetStdHandle(STD_INPUT_HANDLE);
+ conHandle = _open_osfhandle(stdHandle, _O_TEXT);
+ if (conHandle != -1) {
+ fp = _fdopen(conHandle, "r");
+ *stdin = *fp;
+ }
+
+ /* stderr */
+ stdHandle = (intptr_t) GetStdHandle(STD_ERROR_HANDLE);
+ conHandle = _open_osfhandle(stdHandle, _O_TEXT);
+ if (conHandle != -1) {
+ fp = _fdopen(conHandle, "r");
+ *stderr = *fp;
+ }
+}
+
+/* Determine if the launcher was the eclipsec.exe or not based on whether we have an attached console.
+ * This will only be correct if called before createConsole.
+ */
+static int isConsoleLauncher() {
+ HWND (WINAPI *GetConsoleWindow)();
+ void * handle = loadLibrary(_T_ECLIPSE("Kernel32.dll"));
+ if (handle != NULL) {
+ if ( (GetConsoleWindow = findSymbol(handle, _T_ECLIPSE("GetConsoleWindow"))) != NULL) {
+ return GetConsoleWindow() != NULL;
+ }
+ }
+ return 0;
+}
+
+static void fixDLLSearchPath() {
+#ifdef UNICODE
+ _TCHAR* functionName = _T_ECLIPSE("SetDllDirectoryW");
+#else
+ _TCHAR* functionName = _T_ECLIPSE("SetDllDirectoryA");
+#endif
+
+ BOOL (WINAPI *SetDLLDirectory)(LPCTSTR);
+ void * handle = loadLibrary(_T_ECLIPSE("Kernel32.dll"));
+ if (handle != NULL) {
+ if ( (SetDLLDirectory = findSymbol(handle, functionName)) != NULL) {
+ SetDLLDirectory(_T_ECLIPSE(""));
+ }
+ }
+}
+
+#endif
+
+/* Set the vm to use based on the given .ee file.
+ */
+static int vmEEProps(_TCHAR * eeFile, _TCHAR ** msg) {
+ if (processEEProps(eeFile) != 0) {
+ *msg = _tcsdup(eeFile);
+ return -1;
+ }
+ if (eeLibrary != NULL) {
+ jniLib = findVMLibrary(eeLibrary);
+ if (jniLib != NULL)
+ return LAUNCH_JNI;
+ }
+
+ if (eeConsole != NULL && (debug || needConsole || consoleLauncher) ) {
+ javaVM = findSymlinkCommand(eeConsole, 0);
+ if (javaVM != NULL)
+ return LAUNCH_EXE;
+ }
+
+ if (eeExecutable != NULL) {
+ javaVM = findSymlinkCommand(eeExecutable, 0);
+ if (javaVM != NULL)
+ return LAUNCH_EXE;
+ }
+
+ *msg = _tcsdup(eeFile);
+ return -1;
+}
+
+/*
+ * determine the vm to use.
+ * return LAUNCH_JNI for launching with JNI invocation API. jniLib contains the name of the library
+ * returh LAUNCH_EXE for execing java, javaVM contains the path to the exe
+ * return -1 if problem finding vm, the passed in msg points to the places we looked. Caller should free
+ * this memory.
+ */
+static int determineVM(_TCHAR** msg) {
+ _TCHAR* ch = NULL;
+ _TCHAR* result = NULL;
+ _TCHAR* vmSearchPath = NULL;
+ _TCHAR* defaultJava = defaultVM; /* default exe to look for */
+ int type = 0;
+
+#ifdef _WIN32
+ if (debug || needConsole || consoleLauncher)
+ defaultJava = consoleVM; /* windows will want java.exe for the console, not javaw.exe */
+#endif
+
+ /* vmName is passed in on command line with -vm */
+ if (vmName != NULL) {
+ size_t length = _tcslen(vmName);
+ /* remove the trailing separator */
+ if (vmName[length - 1] == _T_ECLIPSE('/') || vmName[length - 1] == _T_ECLIPSE('\\')) {
+ vmName[length - 1] = 0;
+ }
+
+ vmName = checkPath(vmName, programDir, 1);
+ type = checkProvidedVMType(vmName);
+ switch (type) {
+ case VM_DIRECTORY:
+ /* vmName is a directory, look for default.ee */
+ ch = malloc((_tcslen(vmName) + 1 + _tcslen(DEFAULT_EE) + 1) * sizeof(_TCHAR));
+ _stprintf( ch, _T_ECLIPSE("%s%c%s"), vmName, dirSeparator, DEFAULT_EE );
+
+ result = findCommand(ch);
+ free(ch);
+ if (result == NULL) {
+ /* No default.ee file, look for default VM */
+ ch = malloc((_tcslen(vmName) + 1 + _tcslen(defaultJava) + 1) * sizeof(_TCHAR));
+ _stprintf( ch, _T_ECLIPSE("%s%c%s"), vmName, dirSeparator, defaultJava );
+ javaVM = findSymlinkCommand(ch, 0);
+ free(ch);
+ if (javaVM == NULL) {
+ /* No vm executable, look for library */
+ ch = malloc((_tcslen(vmName) + 1 + _tcslen(vmLibrary) + 1) * sizeof(_TCHAR));
+ _stprintf( ch, _T_ECLIPSE("%s%c%s"), vmName, dirSeparator, vmLibrary );
+ jniLib = findVMLibrary(ch);
+ if (jniLib != ch)
+ free(ch);
+ if (jniLib != NULL) {
+ return LAUNCH_JNI;
+ }
+ /* found nothing, return error */
+ *msg = malloc( (3 * (_tcslen(vmName) + 2) + _tcslen(DEFAULT_EE) + _tcslen(defaultJava) + _tcslen(vmLibrary) + 1) * sizeof(_TCHAR));
+ _stprintf( *msg, _T_ECLIPSE("%s%c%s\n%s%c%s\n%s%c%s"), vmName, dirSeparator, DEFAULT_EE,
+ vmName, dirSeparator, defaultJava,
+ vmName, dirSeparator, vmLibrary);
+ return -1;
+ }
+ break;
+ }
+
+ /* else default.ee does exist */
+ vmName = result;
+ /* fall through to VM_EE_PROPS*/
+ case VM_EE_PROPS:
+ return vmEEProps(vmName, msg);
+
+ case VM_LIBRARY:
+ ch = findCommand(vmName);
+ if(ch != NULL) {
+ jniLib = findVMLibrary(ch);
+ if (ch != jniLib)
+ free(ch);
+ return LAUNCH_JNI;
+ }
+ /* file didn't exist, error */
+ if (firstDirSeparator( vmName ) == NULL) {
+ /* if vmName doesn't contain a dirSeparator, we looked on the path */
+ *msg = malloc((_tcslen(pathMsg) + _tcslen(vmName)) * sizeof(_TCHAR));
+ _stprintf( *msg, pathMsg,vmName );
+ } else {
+ *msg = _tcsdup(vmName);
+ }
+ return -1;
+
+ default:
+ /*otherwise, assume executable */
+ javaVM = findSymlinkCommand(vmName, 0);
+ if(javaVM != NULL) {
+#ifdef MACOSX
+ /* right now, we are always doing JNI on Mac */
+ break;
+#else
+ return LAUNCH_EXE;
+#endif
+ }
+ /* file didn't exist, error */
+ if (firstDirSeparator( vmName ) == NULL) {
+ /* if vmName doesn't contain a dirSeparator, we looked on the path */
+ *msg = malloc((_tcslen(pathMsg) + _tcslen(vmName)) * sizeof(_TCHAR));
+ _stprintf( *msg, pathMsg, vmName );
+ } else {
+ *msg = _tcsdup(vmName);
+ }
+ return -1;
+ }
+ }
+
+ if (vmName == NULL) {
+ /* no vm specified, Try to find the VM shipped with eclipse. */
+
+ /* look first for default.ee */
+ ch = malloc( (_tcslen( programDir ) + _tcslen( shippedVMDir ) + _tcslen( DEFAULT_EE ) + 1) * sizeof(_TCHAR) );
+ _stprintf( ch, _T_ECLIPSE("%s%s%s"), programDir, shippedVMDir, DEFAULT_EE );
+ result = findCommand(ch);
+ free(ch);
+ if (result != NULL) {
+ type = vmEEProps(result, msg);
+ free(result);
+ return type;
+ }
+
+ /* then look for java(w).exe */
+ ch = malloc( (_tcslen( programDir ) + _tcslen( shippedVMDir ) + _tcslen( defaultJava ) + 10) * sizeof(_TCHAR) );
+ _stprintf( ch, _T_ECLIPSE("%s%s%s"), programDir, shippedVMDir, defaultJava );
+ vmSearchPath = _tcsdup(ch);
+
+ javaVM = findSymlinkCommand( ch, 0 );
+ free(ch);
+ }
+
+ if (javaVM == NULL) {
+ /* vm not found yet, look for one on the search path, but don't resolve symlinks */
+ javaVM = findSymlinkCommand(defaultJava, 0);
+ if (javaVM == NULL) {
+ /* can't find vm, error */
+ ch = malloc( (_tcslen(pathMsg) + _tcslen(defaultJava) + 1) * sizeof(_TCHAR));
+ _stprintf(ch, pathMsg, defaultJava);
+
+ if(vmSearchPath != NULL) {
+ *msg = malloc((_tcslen(ch) + 1 + _tcslen(vmSearchPath) + 1) * sizeof(_TCHAR));
+ _stprintf(*msg, _T_ECLIPSE("%s\n%s"), vmSearchPath, ch);
+ free(ch);
+ } else {
+ *msg = ch;
+ }
+ return -1;
+ }
+ }
+
+ if (vmSearchPath != NULL)
+ free(vmSearchPath);
+
+#ifndef DEFAULT_JAVA_EXEC
+ /* resolve symlinks for finding the library */
+ ch = resolveSymlinks(javaVM);
+ jniLib = findVMLibrary(ch);
+ if (ch != jniLib && ch != javaVM)
+ free(ch);
+ if (jniLib != NULL)
+ return LAUNCH_JNI;
+#endif
+
+ return LAUNCH_EXE;
+}
+
+static int processEEProps(_TCHAR* eeFile)
+{
+ _TCHAR ** argv;
+ _TCHAR * c1, * c2;
+ _TCHAR * eeDir;
+ int argc;
+ int index, i;
+ int matches = 0;
+ Option *option;
+
+ if(readConfigFile(eeFile, &argc, &argv) != 0)
+ return -1;
+
+ nEEargs = argc;
+ eeVMarg = argv;
+
+ eeDir = _tcsdup(eeFile);
+ c1 = lastDirSeparator( eeDir );
+ while (c1 != NULL)
+ {
+ *c1 = _T_ECLIPSE('\0');
+ c1--; /* IS_DIR_SEPARATOR evalutes c twice, decrement out here */
+ if (!IS_DIR_SEPARATOR(*c1))
+ c1 = NULL;
+ }
+
+ for (index = 0; index < argc; index++){
+ /* replace ${ee.home} with eeDir, loop in case there is more than one per argument */
+ while( (c1 = _tcsstr(argv[index], EE_HOME_VAR)) != NULL)
+ {
+ /* the space needed for c1 is included in _tcslen(argv[index]) */
+ c2 = malloc( (_tcslen(argv[index]) + _tcslen(eeDir) + 1) * sizeof(_TCHAR));
+ *c1 = _T_ECLIPSE('\0');
+ _stprintf(c2, _T_ECLIPSE("%s%s%s"), argv[index], eeDir, c1 + 10); /* ${ee.home} is 10 characters */
+ free(argv[index]);
+ argv[index] = c2;
+ }
+
+ /* Find the corresponding argument is a option supported by the launcher */
+ option = NULL;
+ for (i = 0; option == NULL && i < eeOptionsSize; i++)
+ {
+ if (_tcsncmp( argv[index], eeOptions[i].name, _tcslen(eeOptions[i].name) ) == 0) {
+ option = &eeOptions[i];
+ break;
+ }
+ }
+ if(option != NULL) {
+ ++matches;
+ if (option->flag & VALUE_IS_FLAG)
+ *((int*)option->value) = 1;
+ else {
+ c1 = malloc( (_tcslen(argv[index]) - _tcslen(option->name) + 1) *sizeof(_TCHAR));
+ _tcscpy(c1, argv[index] + _tcslen(option->name));
+ if (option->flag & ADJUST_PATH && option->flag & VALUE_IS_LIST) {
+ c2 = checkPathList(c1, eeDir, 1);
+ free(c1);
+ c1 = c2;
+ } else if (option->flag & ADJUST_PATH) {
+ c2 = checkPath(c1, eeDir, 1);
+ if (c2 != c1) {
+ free(c1);
+ c1 = c2;
+ }
+ }
+ *((_TCHAR**)option->value) = c1;
+ }
+ if(matches == eeOptionsSize)
+ break;
+ }
+ }
+ /* set ee.home, ee.filename variables, and NULL */
+ argv = realloc(argv, (nEEargs + 3) * sizeof(_TCHAR*));
+
+ c1 = malloc( (_tcslen(EE_HOME) + _tcslen(eeDir) + 1) * sizeof(_TCHAR));
+ _stprintf(c1, _T_ECLIPSE("%s%s"), EE_HOME, eeDir);
+ argv[nEEargs++] = c1;
+
+ c1 = malloc( (_tcslen(EE_FILENAME) + _tcslen(eeFile) + 1) * sizeof(_TCHAR));
+ _stprintf(c1, _T_ECLIPSE("%s%s"), EE_FILENAME, eeFile);
+ argv[nEEargs++] = c1;
+
+ argv[nEEargs] = NULL;
+
+ free(eeDir);
+ return 0;
+}
+
+/* returns an array of paths that should be place on the search path for loading
+ * the vm shared libraries.
+ * Each entry is terminated with the platform path separator.
+ * Entries are either from the ee.library.path or calculated from the path to the
+ * vm shared library itself.
+ */
+_TCHAR ** getVMLibrarySearchPath(_TCHAR * vmLibrary) {
+ _TCHAR ** paths = NULL;
+ _TCHAR * buffer = NULL;
+ _TCHAR * path, * entry, *c;
+ _TCHAR separator;
+ int numPaths = 3;
+ int i;
+ struct _stat stats;
+
+ buffer = (eeLibPath != NULL) ? _tcsdup(eeLibPath) : _tcsdup(vmLibrary);
+#ifdef WIN32
+ /* On windows we sometimes get '/' instead of '\', just always use '/' */
+ i = -1;
+ while (buffer[++i] != 0) {
+ if (buffer[i] == _T_ECLIPSE('\\'))
+ buffer[i] = _T_ECLIPSE('/');
+ }
+#endif
+
+ separator = (eeLibPath != NULL) ? pathSeparator : _T_ECLIPSE('/');
+
+ if (eeLibPath != NULL) {
+ /* count number of path elements */
+ numPaths = 1;
+ c = eeLibPath;
+ while( (c = _tcschr(c, pathSeparator)) != NULL) {
+ numPaths++;
+ c++;
+ }
+ }
+
+ paths = malloc((numPaths + 1) * sizeof(_TCHAR*));
+ paths[numPaths] = NULL;
+
+ /* We are either splitting eeLibPath (eg path1:path2), or we are extracting
+ * from libPath where we want the directory containing the library and the
+ * parent directory of that, and also grandparent/lib/arch */
+ for (i = 0; i < numPaths; i++) {
+ c = _tcsrchr(buffer, separator);
+ if (c != 0) {
+ *c++ = 0;
+ if (eeLibPath != NULL) {
+ path = c; /* we want from c to the end */
+ } else {
+ path = buffer; /* we want from the start to c */
+ }
+ } else {
+ if (eeLibPath != NULL) {
+ path = buffer;
+ } else {
+ paths[i] = NULL;
+ break;
+ }
+ }
+ if (path != NULL) {
+ entry = resolveSymlinks(path); /* this may be a new string */
+ if (eeLibPath == NULL && i == 2) {
+ /* trying grandparent/lib/arch */
+ const _TCHAR * arch = getVMArch();
+ paths[i] = malloc((_tcslen(entry) + 7 + _tcslen(arch)) * sizeof(_TCHAR));
+ _stprintf(paths[i], _T_ECLIPSE("%s/lib/%s"), entry, arch);
+ /* only add if the path actually exists */
+ if (_tstat(paths[i], &stats) == 0) {
+ _TCHAR separatorString[] = { pathSeparator, 0 };
+ _tcscat(paths[i], separatorString);
+ } else {
+ free(paths[i]);
+ paths[i] = NULL;
+ }
+ } else {
+ paths[i] = malloc((_tcslen(entry) + 2) * sizeof(_TCHAR));
+ _stprintf( paths[i], _T_ECLIPSE("%s%c"), entry, pathSeparator );
+ }
+ if (entry != path)
+ free(entry);
+ path = NULL;
+ }
+ }
+
+ free(buffer);
+ return paths;
+}
+
+/* translate the osArchArg into the value that we expect the jre to use */
+const _TCHAR* getVMArch() {
+ if (_tcscmp(osArchArg, _T_ECLIPSE("x86_64")) == 0)
+ return _T_ECLIPSE("amd64");
+ else if (_tcscmp(osArchArg, _T_ECLIPSE("x86")) == 0)
+ return _T_ECLIPSE("i386");
+ else
+ return osArchArg;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.c b/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.c
new file mode 100644
index 000000000..923b3c22e
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.c
@@ -0,0 +1,570 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ * Martin Oberhuber (Wind River) - [176805] Support Solaris9 by adding setenv()
+ *******************************************************************************/
+
+#include "eclipseCommon.h"
+#include "eclipseUnicode.h"
+
+#ifdef _WIN32
+#include <direct.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <limits.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Global Variables */
+_TCHAR* osArg = _T_ECLIPSE(DEFAULT_OS);
+#ifdef MACOSX
+ /* on the mac we have a universal binary, decide ppc vs x86 based on endianness */
+ #ifdef __BIG_ENDIAN__
+ _TCHAR* osArchArg = _T_ECLIPSE("ppc");
+ #else
+ _TCHAR* osArchArg = _T_ECLIPSE(DEFAULT_OS_ARCH);
+ #endif
+#else
+_TCHAR* osArchArg = _T_ECLIPSE(DEFAULT_OS_ARCH);
+#endif
+_TCHAR* wsArg = _T_ECLIPSE(DEFAULT_WS); /* the SWT supported GUI to be used */
+
+/* Local Variables */
+static _TCHAR* filterPrefix = NULL; /* prefix for the find files filter */
+static size_t prefixLength = 0;
+
+static int isFolder(const _TCHAR* path, const _TCHAR* entry);
+
+typedef struct {
+ int segment[3];
+ _TCHAR * qualifier;
+} Version;
+
+static void freeVersion(Version *version)
+{
+ if(version->qualifier)
+ free(version->qualifier);
+ free(version);
+}
+
+static Version* parseVersion(const _TCHAR * str) {
+ _TCHAR *copy;
+ _TCHAR *c1, *c2 = NULL;
+ int i = 0;
+
+ Version *version = malloc(sizeof(Version));
+ memset(version, 0, sizeof(Version));
+
+ c1 = copy = _tcsdup(str);
+ while (c1 && *c1 != 0)
+ {
+ if (i < 3) {
+ version->segment[i] = (int)_tcstol(c1, &c2, 10);
+ /* if the next character is not '.', then we couldn't
+ * parse as a int, the remainder is not valid (or we are at the end)*/
+ if (*c2 && *c2 != _T_ECLIPSE('.'))
+ break;
+ c2++; /* increment past the . */
+ } else {
+ c2 = _tcschr(c1, _T_ECLIPSE('.'));
+ if(c2 != NULL) {
+ *c2 = 0;
+ version->qualifier = _tcsdup(c1);
+ *c2 = _T_ECLIPSE('.'); /* put the dot back */
+ } else {
+ if(_tcsicmp(c1, _T_ECLIPSE("jar")) == 0)
+ version->qualifier = 0;
+ else
+ version->qualifier = _tcsdup(c1);
+ }
+ break;
+ }
+ c1 = c2;
+ i++;
+ }
+ free(copy);
+ return version;
+}
+
+static int compareVersions(const _TCHAR* str1, const _TCHAR* str2) {
+ int result = 0, i = 0;
+ Version *v1 = parseVersion(str1);
+ Version *v2 = parseVersion(str2);
+
+ while (result == 0 && i < 3) {
+ result = v1->segment[i] - v2->segment[i];
+ i++;
+ }
+ if(result == 0) {
+ _TCHAR * q1 = v1->qualifier ? v1->qualifier : _T_ECLIPSE("");
+ _TCHAR * q2 = v2->qualifier ? v2->qualifier : _T_ECLIPSE("");
+ result = _tcscmp(q1, q2);
+ }
+
+ freeVersion(v1);
+ freeVersion(v2);
+ return result;
+}
+
+/**
+ * Convert a wide string to a narrow one
+ * Caller must free the null terminated string returned.
+ */
+char *toNarrow(const _TCHAR* src)
+{
+#ifdef UNICODE
+ int byteCount = WideCharToMultiByte (CP_ACP, 0, (wchar_t *)src, -1, NULL, 0, NULL, NULL);
+ char *dest = malloc(byteCount+1);
+ dest[byteCount] = 0;
+ WideCharToMultiByte (CP_ACP, 0, (wchar_t *)src, -1, dest, byteCount, NULL, NULL);
+ return dest;
+#else
+ return (char*)_tcsdup(src);
+#endif
+}
+
+
+/**
+ * Set an environment variable.
+ * Solaris versions <= Solaris 9 did not know setenv in libc,
+ * so emulate it here.
+ */
+#if defined(SOLARIS) || defined(HPUX)
+int setenv (const char *name, const char *value, int replace)
+{
+ int namelen, valuelen, rc;
+ char *var;
+ if (replace == 0) {
+ const char *oldval = getenv(name);
+ if (oldval != NULL) {
+ return 0;
+ }
+ }
+ namelen = strlen(name);
+ valuelen = strlen(value);
+ var = malloc( (namelen + valuelen + 2) * sizeof(char) );
+ if (var == NULL) {
+ return -1;
+ }
+ /* Use strncpy as protection, in case a thread modifies var
+ * after we obtained its length */
+ strncpy(var, name, namelen);
+ var[namelen] = '=';
+ strncpy( &var[namelen + 1], value, valuelen);
+ var[namelen + valuelen + 1] = '\0';
+ rc = putenv(var);
+ if (rc != 0) rc = -1; /*putenv returns non-zero on error; setenv -1*/
+ return rc;
+}
+#endif
+
+ /*
+ * Find the absolute pathname to where a command resides.
+ *
+ * The string returned by the function must be freed.
+ */
+#define EXTRA 20
+_TCHAR* findCommand( _TCHAR* command )
+{
+ return findSymlinkCommand( command, 1 );
+}
+
+_TCHAR* findSymlinkCommand( _TCHAR* command, int resolve )
+{
+ _TCHAR* cmdPath;
+ size_t length;
+ _TCHAR* ch;
+ _TCHAR* dir;
+ _TCHAR* path;
+ struct _stat stats;
+
+ /* If the command was an abolute pathname, use it as is. */
+ if (IS_ABSOLUTE(command))
+ {
+ length = _tcslen( command );
+ cmdPath = malloc( (length + EXTRA) * sizeof(_TCHAR) ); /* add extra space for a possible ".exe" extension */
+ _tcscpy( cmdPath, command );
+ }
+
+ else
+ {
+ /* If the command string contains a path separator */
+ if (firstDirSeparator( command ) != NULL)
+ {
+ /* It must be relative to the current directory. */
+ length = MAX_PATH_LENGTH + EXTRA + _tcslen( command );
+ cmdPath = malloc( length * sizeof (_TCHAR));
+ _tgetcwd( cmdPath, length );
+ length = _tcslen(cmdPath);
+ if (!IS_DIR_SEPARATOR(cmdPath[ length - 1 ]))
+ {
+ cmdPath[ length ] = dirSeparator;
+ cmdPath[ length+1 ] = _T_ECLIPSE('\0');
+ }
+ _tcscat( cmdPath, command );
+ }
+
+ /* else the command must be in the PATH somewhere */
+ else
+ {
+ /* Get the directory PATH where executables reside. */
+ path = _tgetenv( _T_ECLIPSE("PATH") );
+#ifdef _WIN32
+ /* on windows, prepend the current directory */
+ if (path == NULL)
+ path = _T_ECLIPSE("");
+ ch = malloc((_tcslen(path) + MAX_PATH_LENGTH + 2) * sizeof(_TCHAR));
+ _tgetcwd( ch, MAX_PATH_LENGTH );
+ length = _tcslen(ch);
+ ch[length] = pathSeparator;
+ _tcscpy(&ch[length + 1], path);
+ path = ch;
+#endif
+ if (!path)
+ {
+ return NULL;
+ }
+ else
+ {
+ length = _tcslen( path ) + _tcslen( command ) + MAX_PATH_LENGTH;
+ cmdPath = malloc( length * sizeof(_TCHAR));
+
+ /* Foreach directory in the PATH */
+ dir = path;
+ while (dir != NULL && *dir != _T_ECLIPSE('\0'))
+ {
+ ch = _tcschr( dir, pathSeparator );
+ if (ch == NULL)
+ {
+ _tcscpy( cmdPath, dir );
+ }
+ else
+ {
+ length = ch - dir;
+ _tcsncpy( cmdPath, dir, length );
+ cmdPath[ length ] = _T_ECLIPSE('\0');
+ ch++;
+ }
+ dir = ch; /* advance for the next iteration */
+
+#ifdef _WIN32
+ /* Remove quotes */
+ if (_tcschr( cmdPath, _T_ECLIPSE('"') ) != NULL)
+ {
+ size_t i = 0, j = 0;
+ _TCHAR c;
+ length = _tcslen( cmdPath );
+ while (i < length) {
+ c = cmdPath[ i++ ];
+ if (c == _T_ECLIPSE('"')) continue;
+ cmdPath[ j++ ] = c;
+ }
+ cmdPath[ j ] = _T_ECLIPSE('\0');
+ }
+#endif
+ /* Determine if the executable resides in this directory. */
+ if (_tcslen(cmdPath) == 0 || /*an empty path entry is treated as '.' */
+ (cmdPath[0] == _T_ECLIPSE('.') && (_tcslen(cmdPath) == 1 || (_tcslen(cmdPath) == 2 && IS_DIR_SEPARATOR(cmdPath[1])))))
+ {
+ _tgetcwd( cmdPath, MAX_PATH_LENGTH );
+ }
+ length = _tcslen(cmdPath);
+ if (!IS_DIR_SEPARATOR(cmdPath[ length - 1 ]))
+ {
+ cmdPath[ length ] = dirSeparator;
+ cmdPath[ length+1 ] = _T_ECLIPSE('\0');
+ }
+ _tcscat( cmdPath, command );
+
+ /* If the file is not a directory and can be executed */
+ if (_tstat( cmdPath, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ {
+ /* Stop searching */
+ dir = NULL;
+ }
+ }
+ }
+ }
+ }
+
+#ifdef _WIN32
+ /* If the command does not exist */
+ if (_tstat( cmdPath, &stats ) != 0 || (stats.st_mode & S_IFREG) == 0)
+ {
+ /* If the command does not end with .exe, append it an try again. */
+ length = _tcslen( cmdPath );
+ if (length > 4 && _tcsicmp( &cmdPath[ length - 4 ], _T_ECLIPSE(".exe") ) != 0)
+ _tcscat( cmdPath, _T_ECLIPSE(".exe") );
+ }
+#endif
+
+ /* Verify the resulting command actually exists. */
+ if (_tstat( cmdPath, &stats ) != 0 || (stats.st_mode & S_IFREG) == 0)
+ {
+ free( cmdPath );
+ cmdPath = NULL;
+ return cmdPath;
+ }
+
+ if (resolve) {
+ ch = resolveSymlinks(cmdPath);
+ if (ch != cmdPath) {
+ free(cmdPath);
+ cmdPath = ch;
+ }
+ }
+ return cmdPath;
+}
+
+#if !defined(_WIN32) && !defined(MACOSX)
+char * resolveSymlinks( char * path ) {
+ char * ch, *buffer;
+ if(path == NULL)
+ return path;
+ /* resolve symlinks */
+ ch = path;
+ buffer = malloc(PATH_MAX);
+ path = realpath(path, buffer);
+ if (path != buffer)
+ free(buffer);
+ if (path == NULL)
+ return ch; /* failed to resolve the links, return original path */
+ return path;
+}
+#endif
+
+#ifdef _WIN32
+static int filter(_TCHAR* candidate, int isFolder) {
+#else
+#ifdef MACOSX
+static int filter(struct dirent *dir, int isFolder) {
+#else
+static int filter(const struct dirent *dir, int isFolder) {
+#endif
+ char * candidate = (char *)dir->d_name;
+#endif
+ _TCHAR *lastDot, *lastUnderscore;
+ int result;
+
+ if(_tcslen(candidate) <= prefixLength)
+ return 0;
+ if (_tcsncmp(candidate, filterPrefix, prefixLength) != 0 || candidate[prefixLength] != _T_ECLIPSE('_'))
+ return 0;
+
+ candidate = _tcsdup(candidate);
+
+ /* remove trailing .jar and .zip extensions, leave other extensions because we need the '.' */
+ lastDot = _tcsrchr(candidate, _T_ECLIPSE('.'));
+ if (!isFolder && lastDot != NULL && (_tcscmp(lastDot, _T_ECLIPSE(".jar")) == 0 || _tcscmp(lastDot, _T_ECLIPSE(".zip")) == 0)) {
+ *lastDot = 0;
+ lastDot = _tcsrchr(candidate, _T_ECLIPSE('.'));
+ }
+
+ if (lastDot < &candidate[prefixLength]) {
+ free(candidate);
+ return 0;
+ }
+
+ lastUnderscore = _tcsrchr(candidate, _T_ECLIPSE('_'));
+
+ /* get past all the '_' that are part of the qualifier */
+ while(lastUnderscore > lastDot) {
+ *lastUnderscore = 0;
+ lastUnderscore = _tcsrchr(candidate, _T_ECLIPSE('_'));
+ }
+ /* is this the underscore at the end of the prefix? */
+ result = (lastUnderscore == &candidate[prefixLength]);
+ free(candidate);
+ return result;
+}
+
+ /*
+ * Looks for files of the form /path/prefix_version.<extension> and returns the full path to
+ * the file with the largest version number
+ */
+_TCHAR* findFile( _TCHAR* path, _TCHAR* prefix)
+{
+ struct _stat stats;
+ size_t pathLength;
+ _TCHAR* candidate = NULL;
+ _TCHAR* result = NULL;
+
+#ifdef _WIN32
+ _TCHAR* fileName = NULL;
+ WIN32_FIND_DATA data;
+ HANDLE handle;
+#else
+ DIR *dir = NULL;
+ struct dirent * entry = NULL;
+#endif
+
+ path = _tcsdup(path);
+ pathLength = _tcslen(path);
+
+ /* strip dirSeparators off the end */
+ while (IS_DIR_SEPARATOR(path[pathLength - 1])) {
+ path[--pathLength] = 0;
+ }
+
+ /* does path exist? */
+ if( _tstat(path, &stats) != 0 ) {
+ free(path);
+ return NULL;
+ }
+
+ filterPrefix = prefix;
+ prefixLength = _tcslen(prefix);
+#ifdef _WIN32
+ fileName = malloc( (_tcslen(path) + 1 + _tcslen(prefix) + 3) * sizeof(_TCHAR));
+ _stprintf(fileName, _T_ECLIPSE("%s%c%s_*"), path, dirSeparator, prefix);
+
+ handle = FindFirstFile(fileName, &data);
+ if(handle != INVALID_HANDLE_VALUE) {
+ if (filter(data.cFileName, isFolder(path, data.cFileName)))
+ candidate = _tcsdup(data.cFileName);
+ while(FindNextFile(handle, &data) != 0) {
+ if (filter(data.cFileName, isFolder(path, data.cFileName))) {
+ if (candidate == NULL) {
+ candidate = _tcsdup(data.cFileName);
+ } else if( compareVersions(candidate + prefixLength + 1, data.cFileName + prefixLength + 1) < 0) {
+ /* compare, take the highest version */
+ free(candidate);
+ candidate = _tcsdup(data.cFileName);
+ }
+ }
+ }
+ FindClose(handle);
+ }
+#else
+ if ((dir = opendir(path)) == NULL) {
+ free(path);
+ return NULL;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (filter(entry, isFolder(path, entry->d_name))) {
+ if (candidate == NULL) {
+ candidate = _tcsdup(entry->d_name);
+ } else if (compareVersions(candidate + prefixLength + 1, entry->d_name + prefixLength + 1) < 0) {
+ free(candidate);
+ candidate = _tcsdup(entry->d_name);
+ }
+ }
+ }
+ closedir(dir);
+#endif
+
+ if(candidate != NULL) {
+ result = malloc((pathLength + 1 + _tcslen(candidate) + 1) * sizeof(_TCHAR));
+ _tcscpy(result, path);
+ result[pathLength] = dirSeparator;
+ result[pathLength + 1] = 0;
+ _tcscat(result, candidate);
+ free(candidate);
+ }
+ free(path);
+ return result;
+}
+
+int isFolder(const _TCHAR* path, const _TCHAR* entry) {
+ int result = 0;
+ struct _stat stats;
+ _TCHAR * fullPath = malloc((_tcslen(path) + _tcslen(entry) + 2) * sizeof(_TCHAR));
+ _stprintf(fullPath, _T_ECLIPSE("%s%c%s"), path, dirSeparator, entry);
+
+ result = _tstat(fullPath, &stats);
+ free(fullPath);
+ return (result == 0 && (stats.st_mode & S_IFDIR) != 0);
+}
+
+/*
+ * If path is relative, attempt to make it absolute by
+ * 1) check relative to working directory
+ * 2) check relative to provided programDir
+ * If reverseOrder, then check the programDir before the working dir
+ */
+_TCHAR* checkPath( _TCHAR* path, _TCHAR* programDir, int reverseOrder )
+{
+ int cwdLength = MAX_PATH_LENGTH;
+ int i;
+ _TCHAR * workingDir, * buffer, * result = NULL;
+ _TCHAR * paths[2];
+ struct _stat stats;
+
+ /* If the command was an abolute pathname, use it as is. */
+ if (IS_ABSOLUTE(path)) {
+ return path;
+ }
+
+ /* get the current working directory */
+ workingDir = malloc(cwdLength * sizeof(_TCHAR));
+ while ( _tgetcwd( workingDir, cwdLength ) == NULL ){
+ if (errno == ERANGE) {
+ /* ERANGE : the buffer isn't big enough, allocate more memory */
+ cwdLength *= 2;
+ workingDir = realloc(workingDir, cwdLength * sizeof(_TCHAR));
+ continue;
+ } else {
+ /* some other error occurred, perhaps ENOENT (directory has been unlinked) */
+ /* the contents of workingDir are undefined, set it to empty, we will end up testing against root */
+ workingDir[0] = _T_ECLIPSE('\0');
+ break;
+ }
+ }
+
+ paths[0] = reverseOrder ? programDir : workingDir;
+ paths[1] = reverseOrder ? workingDir : programDir;
+
+ /* just make a buffer big enough to hold everything */
+ buffer = malloc((_tcslen(paths[0]) + _tcslen(paths[1]) + _tcslen(path) + 2) * sizeof(_TCHAR));
+ for ( i = 0; i < 2; i++ ) {
+ if (_tcslen(paths[i]) == 0)
+ continue;
+ _stprintf(buffer, _T_ECLIPSE("%s%c%s"), paths[i], dirSeparator, path);
+ if (_tstat(buffer, &stats) == 0) {
+ result = _tcsdup(buffer);
+ break;
+ }
+ }
+
+ free(buffer);
+ free(workingDir);
+
+ /* if we found something, return it, otherwise, return the original */
+ return result != NULL ? result : path;
+}
+
+_TCHAR * lastDirSeparator(_TCHAR* str) {
+#ifndef _WIN32
+ return _tcsrchr(str, dirSeparator);
+#else
+ int i = -1;
+ _TCHAR * c = NULL;
+ while (str[++i] != 0) {
+ if (str[i] == _T_ECLIPSE('\\') || str[i] == _T_ECLIPSE('/'))
+ c = &str[i];
+ }
+ return c;
+#endif
+}
+
+_TCHAR * firstDirSeparator(_TCHAR* str) {
+#ifdef _WIN32
+ return _tcspbrk(str, _T_ECLIPSE("\\/"));
+#else
+ return _tcschr(str, dirSeparator);
+#endif
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.h b/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.h
new file mode 100644
index 000000000..655f90122
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.h
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#ifndef ECLIPSE_COMMON_H
+#define ECLIPSE_COMMON_H
+
+#include "eclipseUnicode.h"
+
+/* Variables and Methods that will be needed by both the executable and the library */
+
+#define MAX_PATH_LENGTH 2000
+
+#ifdef UNICODE
+#define run runW
+#define setInitialArgs setInitialArgsW
+#define RUN_METHOD _T_ECLIPSE("runW")
+#define SET_INITIAL_ARGS _T_ECLIPSE("setInitialArgsW")
+#else
+#define RUN_METHOD _T_ECLIPSE("run")
+#define SET_INITIAL_ARGS _T_ECLIPSE("setInitialArgs")
+#endif
+
+#define DEFAULT_EQUINOX_STARTUP _T_ECLIPSE("org.eclipse.equinox.launcher")
+
+#ifdef _WIN32
+#define IS_ABSOLUTE(path) (path[0] == _T_ECLIPSE('/') || path[0] == _T_ECLIPSE('\\') || (path[0] != 0 && path[1] == _T_ECLIPSE(':')))
+#define IS_DIR_SEPARATOR(c) (c == _T_ECLIPSE('/') || c == _T_ECLIPSE('\\'))
+#else
+#define IS_ABSOLUTE(path) (path[0] == dirSeparator)
+#define IS_DIR_SEPARATOR(c) (c == dirSeparator)
+#endif
+
+extern _TCHAR* osArg;
+extern _TCHAR* osArchArg;
+extern _TCHAR* wsArg;
+
+extern _TCHAR dirSeparator; /* '/' or '\\' */
+extern _TCHAR pathSeparator; /* separator used in PATH variable */
+extern _TCHAR* eclipseLibrary; /* path the the eclipse_<ver>.so shared library */
+
+extern char *toNarrow(const _TCHAR* src);
+
+ /*
+ * Find the absolute pathname to where a command resides.
+ *
+ * The string returned by the function must be freed.
+ * Symlinks are resolved
+ */
+extern _TCHAR* findCommand( _TCHAR* command );
+
+/*
+ * Same as findCommand but optionally resolve symlinks
+ */
+extern _TCHAR* findSymlinkCommand( _TCHAR* command, int resolve );
+
+extern _TCHAR* findFile( _TCHAR* path, _TCHAR* prefix);
+
+extern _TCHAR* getProgramDir();
+
+extern _TCHAR* getOfficialName();
+
+extern void setOfficialName(_TCHAR * name);
+
+extern _TCHAR* getProgramPath();
+
+extern void setProgramPath(_TCHAR* name);
+
+extern _TCHAR* resolveSymlinks( _TCHAR* path );
+
+/** Display a Message
+ *
+ * This method is called to display an error message to the user before exiting.
+ * The method should not return until the user has acknowledged
+ * the message. This method may be called before the window
+ * system has been initialized. The program should exit after calling this method.
+ */
+extern void displayMessage( _TCHAR* title, _TCHAR* message );
+
+/* Load the specified shared library
+ */
+extern void * loadLibrary( _TCHAR * library );
+
+/* Unload the shared library
+ */
+extern void unloadLibrary( void * handle );
+
+/* Find the given symbol in the shared library
+ */
+extern void * findSymbol( void * handle, _TCHAR * symbol );
+
+/* check the given path and attempt to make it absolute if it is relative */
+extern _TCHAR* checkPath( _TCHAR* path, _TCHAR* programDir, int reverseOrder );
+
+extern _TCHAR * lastDirSeparator(_TCHAR* str);
+
+extern _TCHAR * firstDirSeparator(_TCHAR* str);
+#endif
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseConfig.c b/features/org.eclipse.equinox.executable.feature/library/eclipseConfig.c
new file mode 100644
index 000000000..bc7a5cdc0
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseConfig.c
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Martin Oberhuber (Wind River) - [316975] memory leak on failure reading .ini file
+ *******************************************************************************/
+
+#include "eclipseOS.h"
+#include "eclipseConfig.h"
+
+#ifdef _WIN32
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#ifdef __MINGW32__
+#include <stdlib.h>
+#endif
+
+#else /* Unix like platforms */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#endif
+
+int readIniFile(_TCHAR* program, int *argc, _TCHAR ***argv)
+{
+ _TCHAR* config_file = NULL;
+ int result;
+
+ if (program == NULL || argc == NULL || argv == NULL) return -1;
+
+#if defined(_WIN32) && defined(_WIN32_CONSOLE)
+ config_file = getIniFile(program, 1);
+#else
+ config_file = getIniFile(program, 0);
+#endif
+
+ result = readConfigFile(config_file, argc, argv);
+ free(config_file);
+ return result;
+}
+
+_TCHAR* getIniFile(_TCHAR* program, int consoleLauncher){
+ _TCHAR* config_file = NULL;
+
+ /* Get a copy with room for .ini at the end */
+ config_file = malloc( (_tcslen(program) + 5) * sizeof(_TCHAR));
+ _tcscpy(config_file, program);
+
+#ifdef _WIN32
+ {
+ /* Search for the extension .exe and replace it with .ini */
+ _TCHAR *extension = _tcsrchr(config_file, _T_ECLIPSE('.'));
+ if (extension == NULL)
+ {
+ /* does not end with an extension, just append .ini */
+ extension = config_file + _tcslen(config_file);
+ }
+ _tcscpy(extension, _T_ECLIPSE(".ini"));
+ if(consoleLauncher){
+ /* We are the console version, if the ini file does not exist, try
+ * removing the 'c' from the end of the program name */
+ struct _stat stats;
+ if (_tstat( config_file, &stats ) != 0 && *(extension - 1) == _T('c')) {
+ _tcscpy(extension - 1, extension);
+ }
+ }
+ }
+#else
+ /* Append the extension */
+ strcat(config_file, ".ini");
+#endif
+ return config_file;
+}
+
+int readConfigFile( _TCHAR * config_file, int *argc, _TCHAR ***argv )
+{
+ _TCHAR * buffer;
+ _TCHAR * argument;
+ _TCHAR * arg;
+ FILE *file = NULL;
+ int maxArgs = 128;
+ int index;
+ size_t bufferSize = 1024;
+ size_t length;
+
+
+ /* Open the config file as a text file
+ * Note that carriage return-linefeed combination \r\n are automatically
+ * translated into single linefeeds on input in the t (translated) mode
+ * on windows, on other platforms we will strip the \r as whitespace.
+ */
+ file = _tfopen(config_file, _T_ECLIPSE("rt"));
+ if (file == NULL) return -3;
+
+ /* allocate buffers */
+ buffer = (_TCHAR*)malloc(bufferSize * sizeof(_TCHAR));
+ argument = (_TCHAR*)malloc(bufferSize * sizeof(_TCHAR));
+ *argv = (_TCHAR **)malloc((1 + maxArgs) * sizeof(_TCHAR*));
+
+ index = 0;
+
+ /* Parse every line */
+ while (_fgetts(buffer, bufferSize, file) != NULL)
+ {
+ /* did we fill the buffer without reaching the end of a line? */
+ while (buffer[bufferSize - 2] != _T_ECLIPSE('\n') && _tcslen(buffer) == (bufferSize - 1)) {
+ bufferSize += 1024;
+ buffer = (_TCHAR*)realloc(buffer, bufferSize * sizeof(_TCHAR));
+ argument = (_TCHAR*)realloc(argument, bufferSize * sizeof(_TCHAR));
+ buffer[bufferSize - 2] = 0;
+
+ /* read the next chunk to overwrite the \0 left by the last read */
+ if(_fgetts(buffer + bufferSize - 1025, 1025, file) == NULL)
+ break;
+ }
+
+ /* Extract the string prior to the first newline character.
+ * We don't have to worry about \r\n combinations since the file
+ * is opened in translated mode.
+ */
+ if (_stscanf(buffer, _T_ECLIPSE("%[^\n]"), argument) == 1)
+ {
+ /* watch for comments */
+ if(argument[0] == _T_ECLIPSE('#'))
+ continue;
+
+ arg = _tcsdup(argument);
+ length = _tcslen(arg);
+
+ /* basic whitespace trimming */
+ while (length > 0 && (arg[length - 1] == _T_ECLIPSE(' ') ||
+ arg[length - 1] == _T_ECLIPSE('\t') ||
+ arg[length - 1] == _T_ECLIPSE('\r')))
+ {
+ arg[--length] = 0;
+ }
+ /* ignore empty lines */
+ if (length == 0) {
+ free(arg);
+ continue;
+ }
+
+ (*argv)[index] = arg;
+ index++;
+
+ /* Grow the array of TCHAR*. Ensure one more entry is
+ * available for the final NULL entry
+ */
+ if (index == maxArgs - 1)
+ {
+ maxArgs += 128;
+ *argv = (_TCHAR **)realloc(*argv, maxArgs * sizeof(_TCHAR*));
+ }
+ }
+ }
+ (*argv)[index] = NULL;
+ *argc = index;
+
+ fclose(file);
+ free(buffer);
+ free(argument);
+ return 0;
+}
+
+void freeConfig(_TCHAR **argv)
+{
+ int index = 0;
+ if (argv == NULL) return;
+ while (argv[index] != NULL)
+ {
+ free(argv[index]);
+ index++;
+ }
+ free(argv);
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseConfig.h b/features/org.eclipse.equinox.executable.feature/library/eclipseConfig.h
new file mode 100644
index 000000000..cd8ef9c97
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseConfig.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef ECLIPSE_CONFIG_H
+#define ECLIPSE_CONFIG_H
+
+/* Configuration file reading utilities */
+
+/**
+ * Reads a configuration file for the corresponding
+ * program argument.
+ * e.g if the program argument contains "c:/folder/eclipse.exe"
+ * then the config file "c:/folder/eclipse.ini" will be parsed.
+ * On a Unix like platform, for a program argument "/usr/eclipse/eclipse"
+ * should correspond a configuration file "/usr/eclipse/eclipse.ini"
+ *
+ * This method will call readConfigFile to read the actual ini file
+ *
+ * This method will use getIniFile with a value for consoleLauncher that
+ * is determined at compile time. Clients who are not the actual
+ * win32 console executable should instead use getIniFile and readConfigFile.
+ *
+ * Returns 0 if success.
+ */
+extern int readIniFile(_TCHAR* program, int *argc, _TCHAR ***argv);
+
+/**
+ * Return the path to the launcher ini file for the corresponding program
+ * argument. On win32, an "eclipsec.exe' console launcher can use the "eclipse.ini"
+ * ini file.
+ * consoleLauncher : whether or not we are using the win32 "eclipsec" console launcher
+ * has no affect on other platforms
+ */
+extern _TCHAR* getIniFile(_TCHAR* program, int consoleLauncher);
+
+/**
+ * Reads the given configuration file
+ * The argument argv refers to a newly allocated array of strings.
+ * The first entry is the program name to mimic the expectations
+ * from a typical argv list.
+ * The last entry of that array is NULL.
+ * Each non NULL entry in that array must be freed by the caller
+ * as well as the array itself, using freeConfig().
+ * The argument argc contains the number of string allocated.
+ *
+ * Returns 0 if success.
+ */
+extern int readConfigFile( _TCHAR * config_file, int *argc, _TCHAR ***argv );
+/**
+ * Free the memory allocated by readConfigFile().
+ */
+extern void freeConfig(_TCHAR **args);
+
+#endif /* ECLIPSE_CONFIG_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseJNI.c b/features/org.eclipse.equinox.executable.feature/library/eclipseJNI.c
new file mode 100644
index 000000000..845c646c6
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseJNI.c
@@ -0,0 +1,568 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#include "eclipseJNI.h"
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+#include "eclipseShm.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+static _TCHAR* failedToLoadLibrary = _T_ECLIPSE("Failed to load the JNI shared library \"%s\".\n");
+static _TCHAR* createVMSymbolNotFound = _T_ECLIPSE("The JVM shared library \"%s\"\ndoes not contain the JNI_CreateJavaVM symbol.\n");
+static _TCHAR* failedCreateVM = _T_ECLIPSE("Failed to create the Java Virtual Machine.\n");
+static _TCHAR* internalExpectedVMArgs = _T_ECLIPSE("Internal Error, the JVM argument list is empty.\n");
+static _TCHAR* mainClassNotFound = _T_ECLIPSE("Failed to find a Main Class in \"%s\".\n");
+
+static JNINativeMethod natives[] = {{"_update_splash", "()V", (void *)&update_splash},
+ {"_get_splash_handle", "()J", (void *)&get_splash_handle},
+ {"_set_exit_data", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)&set_exit_data},
+ {"_set_launcher_info", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)&set_launcher_info},
+ {"_show_splash", "(Ljava/lang/String;)V", (void *)&show_splash},
+ {"_takedown_splash", "()V", (void *)&takedown_splash}};
+
+/* local methods */
+static jstring newJavaString(JNIEnv *env, _TCHAR * str);
+static void registerNatives(JNIEnv *env);
+static int shouldShutdown(JNIEnv *env);
+static void JNI_ReleaseStringChars(JNIEnv *env, jstring s, const _TCHAR* data);
+static const _TCHAR* JNI_GetStringChars(JNIEnv *env, jstring str);
+static char * getMainClass(JNIEnv *env, _TCHAR * jarFile);
+static void setLibraryLocation(JNIEnv *env, jobject obj);
+
+static JavaVM * jvm = 0;
+static JNIEnv *env = 0;
+
+/* cache String class and methods to avoid looking them up all the time */
+static jclass string_class = NULL;
+#if !defined(UNICODE) && !defined(MACOSX)
+static jmethodID string_getBytesMethod = NULL;
+static jmethodID string_ctor = NULL;
+#endif
+
+/* JNI Callback methods */
+JNIEXPORT void JNICALL set_exit_data(JNIEnv * env, jobject obj, jstring id, jstring s){
+ const _TCHAR* data = NULL;
+ const _TCHAR* sharedId = NULL;
+ size_t length;
+
+ if(s != NULL) {
+ length = (*env)->GetStringLength(env, s);
+ if(!(*env)->ExceptionOccurred(env)) {
+ data = JNI_GetStringChars(env, s);
+ if (data != NULL) {
+ if(id != NULL) {
+ sharedId = JNI_GetStringChars(env, id);
+ if(sharedId != NULL) {
+ setSharedData(sharedId, data);
+ JNI_ReleaseStringChars(env, id, sharedId);
+ }
+ } else {
+ exitData = malloc((length + 1) * sizeof(_TCHAR*));
+ _tcsncpy( exitData, data, length);
+ exitData[length] = _T_ECLIPSE('\0');
+ }
+ JNI_ReleaseStringChars(env, s, data);
+ }
+ }
+ if(data == NULL && sharedId == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ }
+}
+
+JNIEXPORT void JNICALL set_launcher_info(JNIEnv * env, jobject obj, jstring launcher, jstring name){
+ const _TCHAR* launcherPath = NULL;
+ const _TCHAR* launcherName = NULL;
+
+ if (launcher != NULL) {
+ launcherPath = JNI_GetStringChars(env, launcher);
+ if (launcherPath != NULL) {
+ setProgramPath(_tcsdup(launcherPath));
+ JNI_ReleaseStringChars(env, launcher, launcherPath);
+ }
+ }
+
+ if (name != NULL) {
+ launcherName = JNI_GetStringChars(env, name);
+ if (launcherName != NULL) {
+ setOfficialName(_tcsdup(launcherName));
+ JNI_ReleaseStringChars(env, name, launcherName);
+ }
+ }
+}
+
+
+JNIEXPORT void JNICALL update_splash(JNIEnv * env, jobject obj){
+ dispatchMessages();
+}
+
+JNIEXPORT jlong JNICALL get_splash_handle(JNIEnv * env, jobject obj){
+ return getSplashHandle();
+}
+
+JNIEXPORT void JNICALL show_splash(JNIEnv * env, jobject obj, jstring s){
+ const _TCHAR* data = NULL;
+
+ setLibraryLocation(env, obj);
+
+ if(s != NULL) {
+ data = JNI_GetStringChars(env, s);
+ if(data != NULL) {
+ showSplash(data);
+ JNI_ReleaseStringChars(env, s, data);
+ } else {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ }
+}
+
+JNIEXPORT void JNICALL takedown_splash(JNIEnv * env, jobject obj){
+ takeDownSplash();
+}
+
+/*
+ * On AIX we need the location of the eclipse shared library so that we
+ * can find the libeclipse-motif.so library. Reach into the JNIBridge
+ * object to get the "library" field.
+ */
+static void setLibraryLocation(JNIEnv * env, jobject obj) {
+ jclass bridge = (*env)->FindClass(env, "org/eclipse/equinox/launcher/JNIBridge");
+ if (bridge != NULL) {
+ jfieldID libraryField = (*env)->GetFieldID(env, bridge, "library", "Ljava/lang/String;");
+ if (libraryField != NULL) {
+ jstring stringObject = (jstring) (*env)->GetObjectField(env, obj, libraryField);
+ if (stringObject != NULL) {
+ const _TCHAR * str = JNI_GetStringChars(env, stringObject);
+ eclipseLibrary = _tcsdup(str);
+ JNI_ReleaseStringChars(env, stringObject, str);
+ }
+ }
+ }
+ if( (*env)->ExceptionOccurred(env) != 0 ){
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+}
+
+static void registerNatives(JNIEnv *env) {
+ jclass bridge = (*env)->FindClass(env, "org/eclipse/equinox/launcher/JNIBridge");
+ if(bridge != NULL) {
+ int numNatives = sizeof(natives) / sizeof(natives[0]);
+ (*env)->RegisterNatives(env, bridge, natives, numNatives);
+ }
+ if( (*env)->ExceptionOccurred(env) != 0 ){
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+}
+
+
+/* Get a _TCHAR* from a jstring, string should be released later with JNI_ReleaseStringChars */
+static const _TCHAR * JNI_GetStringChars(JNIEnv *env, jstring str) {
+ const _TCHAR * result = NULL;
+#ifdef UNICODE
+ /* GetStringChars is not null terminated, make a copy */
+ const _TCHAR * stringChars = (*env)->GetStringChars(env, str, 0);
+ int length = (*env)->GetStringLength(env, str);
+ _TCHAR * copy = malloc( (length + 1) * sizeof(_TCHAR));
+ _tcsncpy(copy, stringChars, length);
+ copy[length] = _T_ECLIPSE('\0');
+ (*env)->ReleaseStringChars(env, str, stringChars);
+ result = copy;
+#elif MACOSX
+ /* Use UTF on the Mac */
+ result = (*env)->GetStringUTFChars(env, str, 0);
+#else
+ /* Other platforms, use java's default encoding */
+ _TCHAR* buffer = NULL;
+ if (string_class == NULL)
+ string_class = (*env)->FindClass(env, "java/lang/String");
+ if (string_class != NULL) {
+ if (string_getBytesMethod == NULL)
+ string_getBytesMethod = (*env)->GetMethodID(env, string_class, "getBytes", "()[B");
+ if (string_getBytesMethod != NULL) {
+ jbyteArray bytes = (*env)->CallObjectMethod(env, str, string_getBytesMethod);
+ if (!(*env)->ExceptionOccurred(env)) {
+ jsize length = (*env)->GetArrayLength(env, bytes);
+ buffer = malloc( (length + 1) * sizeof(_TCHAR*));
+ (*env)->GetByteArrayRegion(env, bytes, 0, length, (jbyte*)buffer);
+ buffer[length] = 0;
+ }
+ (*env)->DeleteLocalRef(env, bytes);
+ }
+ }
+ if(buffer == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ result = buffer;
+#endif
+ return result;
+}
+
+/* Release the string that was obtained using JNI_GetStringChars */
+static void JNI_ReleaseStringChars(JNIEnv *env, jstring s, const _TCHAR* data) {
+#ifdef UNICODE
+ free((_TCHAR*)data);
+#elif MACOSX
+ (*env)->ReleaseStringUTFChars(env, s, data);
+#else
+ free((_TCHAR*)data);
+#endif
+}
+
+static jstring newJavaString(JNIEnv *env, _TCHAR * str)
+{
+ jstring newString = NULL;
+#ifdef UNICODE
+ size_t length = _tcslen(str);
+ newString = (*env)->NewString(env, str, length);
+#elif MACOSX
+ newString = (*env)->NewStringUTF(env, str);
+#else
+ size_t length = _tcslen(str);
+ jbyteArray bytes = (*env)->NewByteArray(env, length);
+ if(bytes != NULL) {
+ (*env)->SetByteArrayRegion(env, bytes, 0, length, (jbyte *)str);
+ if (!(*env)->ExceptionOccurred(env)) {
+ if (string_class == NULL)
+ string_class = (*env)->FindClass(env, "java/lang/String");
+ if(string_class != NULL) {
+ if (string_ctor == NULL)
+ string_ctor = (*env)->GetMethodID(env, string_class, "<init>", "([B)V");
+ if(string_ctor != NULL) {
+ newString = (*env)->NewObject(env, string_class, string_ctor, bytes);
+ }
+ }
+ }
+ (*env)->DeleteLocalRef(env, bytes);
+ }
+#endif
+ if(newString == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ return newString;
+}
+
+static jobjectArray createRunArgs( JNIEnv *env, _TCHAR * args[] ) {
+ int index = 0, length = -1;
+ jobjectArray stringArray = NULL;
+ jstring string;
+
+ /*count the number of elements first*/
+ while(args[++length] != NULL);
+
+ if (string_class == NULL)
+ string_class = (*env)->FindClass(env, "java/lang/String");
+ if(string_class != NULL) {
+ stringArray = (*env)->NewObjectArray(env, length, string_class, 0);
+ if(stringArray != NULL) {
+ for( index = 0; index < length; index++) {
+ string = newJavaString(env, args[index]);
+ if(string != NULL) {
+ (*env)->SetObjectArrayElement(env, stringArray, index, string);
+ (*env)->DeleteLocalRef(env, string);
+ } else {
+ (*env)->DeleteLocalRef(env, stringArray);
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return NULL;
+ }
+ }
+ }
+ }
+ if(stringArray == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ return stringArray;
+}
+
+JavaResults * startJavaJNI( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile )
+{
+ int i;
+ int numVMArgs = -1;
+ void * jniLibrary;
+ JNI_createJavaVM createJavaVM;
+ JavaVMInitArgs init_args;
+ JavaVMOption * options;
+ char * mainClassName = NULL;
+ JavaResults * results = NULL;
+
+ /* JNI reflection */
+ jclass mainClass = NULL; /* The Main class to load */
+ jmethodID mainConstructor = NULL; /* Main's default constructor Main() */
+ jobject mainObject = NULL; /* An instantiation of the main class */
+ jmethodID runMethod = NULL; /* Main.run(String[]) */
+ jobjectArray methodArgs = NULL; /* Arguments to pass to run */
+
+ results = malloc(sizeof(JavaResults));
+ memset(results, 0, sizeof(JavaResults));
+
+ jniLibrary = loadLibrary(libPath);
+ if(jniLibrary == NULL) {
+ results->launchResult = -1;
+ results->errorMessage = malloc((_tcslen(failedToLoadLibrary) + _tcslen(libPath) + 1) * sizeof(_TCHAR));
+ _stprintf(results->errorMessage, failedToLoadLibrary, libPath);
+ return results; /*error*/
+ }
+
+ createJavaVM = (JNI_createJavaVM)findSymbol(jniLibrary, _T_ECLIPSE("JNI_CreateJavaVM"));
+ if(createJavaVM == NULL) {
+ results->launchResult = -2;
+ results->errorMessage = malloc((_tcslen(createVMSymbolNotFound) + _tcslen(libPath) + 1) * sizeof(_TCHAR));
+ _stprintf(results->errorMessage, createVMSymbolNotFound, libPath);
+ return results; /*error*/
+ }
+
+ /* count the vm args */
+ while(vmArgs[++numVMArgs] != NULL) {}
+
+ if(numVMArgs <= 0) {
+ /*error, we expect at least the required vm arg */
+ results->launchResult = -3;
+ results->errorMessage = _tcsdup(internalExpectedVMArgs);
+ return results;
+ }
+
+ options = malloc(numVMArgs * sizeof(JavaVMOption));
+ for(i = 0; i < numVMArgs; i++){
+ options[i].optionString = toNarrow(vmArgs[i]);
+ options[i].extraInfo = 0;
+ }
+
+#ifdef MACOSX
+ init_args.version = JNI_VERSION_1_4;
+#else
+ init_args.version = JNI_VERSION_1_2;
+#endif
+ init_args.options = options;
+ init_args.nOptions = numVMArgs;
+ init_args.ignoreUnrecognized = JNI_TRUE;
+
+ if( createJavaVM(&jvm, &env, &init_args) == 0 ) {
+ registerNatives(env);
+
+ mainClassName = getMainClass(env, jarFile);
+ if (mainClassName != NULL) {
+ mainClass = (*env)->FindClass(env, mainClassName);
+ free(mainClassName);
+ }
+
+ if (mainClass == NULL) {
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ mainClass = (*env)->FindClass(env, "org/eclipse/equinox/launcher/Main");
+ }
+
+ if(mainClass != NULL) {
+ results->launchResult = -6; /* this will be reset to 0 below on success */
+ mainConstructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
+ if(mainConstructor != NULL) {
+ mainObject = (*env)->NewObject(env, mainClass, mainConstructor);
+ if(mainObject != NULL) {
+ runMethod = (*env)->GetMethodID(env, mainClass, "run", "([Ljava/lang/String;)I");
+ if(runMethod != NULL) {
+ methodArgs = createRunArgs(env, progArgs);
+ if(methodArgs != NULL) {
+ results->launchResult = 0;
+ results->runResult = (*env)->CallIntMethod(env, mainObject, runMethod, methodArgs);
+ (*env)->DeleteLocalRef(env, methodArgs);
+ }
+ }
+ (*env)->DeleteLocalRef(env, mainObject);
+ }
+ }
+ } else {
+ results->launchResult = -5;
+ results->errorMessage = malloc((_tcslen(mainClassNotFound) + _tcslen(jarFile) + 1) * sizeof(_TCHAR));
+ _stprintf(results->errorMessage, mainClassNotFound, jarFile);
+ }
+ if((*env)->ExceptionOccurred(env)){
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+
+ } else {
+ results->launchResult = -4;
+ results->errorMessage = _tcsdup(failedCreateVM);
+ }
+
+ /* toNarrow allocated new strings, free them */
+ for(i = 0; i < numVMArgs; i++){
+ free( options[i].optionString );
+ }
+ free(options);
+ return results;
+}
+
+static char * getMainClass(JNIEnv *env, _TCHAR * jarFile) {
+ jclass jarFileClass = NULL, manifestClass = NULL, attributesClass = NULL;
+ jmethodID jarFileConstructor = NULL, getManifestMethod = NULL, getMainAttributesMethod = NULL, closeJarMethod = NULL, getValueMethod = NULL;
+ jobject jarFileObject, manifest, attributes;
+ jstring mainClassString = NULL;
+ jstring jarFileString, headerString;
+ const _TCHAR *mainClass;
+
+ /* get the classes we need */
+ jarFileClass = (*env)->FindClass(env, "java/util/jar/JarFile");
+ if (jarFileClass != NULL) {
+ manifestClass = (*env)->FindClass(env, "java/util/jar/Manifest");
+ if (manifestClass != NULL) {
+ attributesClass = (*env)->FindClass(env, "java/util/jar/Attributes");
+ }
+ }
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ if (attributesClass == NULL)
+ return NULL;
+
+ /* find the methods */
+ jarFileConstructor = (*env)->GetMethodID(env, jarFileClass, "<init>", "(Ljava/lang/String;Z)V");
+ if(jarFileConstructor != NULL) {
+ getManifestMethod = (*env)->GetMethodID(env, jarFileClass, "getManifest", "()Ljava/util/jar/Manifest;");
+ if(getManifestMethod != NULL) {
+ closeJarMethod = (*env)->GetMethodID(env, jarFileClass, "close", "()V");
+ if (closeJarMethod != NULL) {
+ getMainAttributesMethod = (*env)->GetMethodID(env, manifestClass, "getMainAttributes", "()Ljava/util/jar/Attributes;");
+ if (getMainAttributesMethod != NULL) {
+ getValueMethod = (*env)->GetMethodID(env, attributesClass, "getValue", "(Ljava/lang/String;)Ljava/lang/String;");
+ }
+ }
+ }
+ }
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ if (getValueMethod == NULL)
+ return NULL;
+
+ /* jarFileString = new String(jarFile); */
+ jarFileString = newJavaString(env, jarFile);
+ /* headerString = new String("Main-Class"); */
+ headerString = newJavaString(env, _T_ECLIPSE("Main-Class"));
+ if (jarFileString != NULL && headerString != NULL) {
+ /* jarfileObject = new JarFile(jarFileString, false); */
+ jarFileObject = (*env)->NewObject(env, jarFileClass, jarFileConstructor, jarFileString, JNI_FALSE);
+ if (jarFileObject != NULL) {
+ /* manifest = jarFileObject.getManifest(); */
+ manifest = (*env)->CallObjectMethod(env, jarFileObject, getManifestMethod);
+ if (manifest != NULL) {
+ /*jarFileObject.close() */
+ (*env)->CallVoidMethod(env, jarFileObject, closeJarMethod);
+ if (!(*env)->ExceptionOccurred(env)) {
+ /* attributes = manifest.getMainAttributes(); */
+ attributes = (*env)->CallObjectMethod(env, manifest, getMainAttributesMethod);
+ if (attributes != NULL) {
+ /* mainClassString = attributes.getValue(headerString); */
+ mainClassString = (*env)->CallObjectMethod(env, attributes, getValueMethod, headerString);
+ }
+ }
+ }
+ (*env)->DeleteLocalRef(env, jarFileObject);
+ }
+ }
+
+ if (jarFileString != NULL)
+ (*env)->DeleteLocalRef(env, jarFileString);
+ if (headerString != NULL)
+ (*env)->DeleteLocalRef(env, headerString);
+
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+
+ if (mainClassString == NULL)
+ return NULL;
+
+ mainClass = JNI_GetStringChars(env, mainClassString);
+ if(mainClass != NULL) {
+ int i = -1;
+ char *result = toNarrow(mainClass);
+ JNI_ReleaseStringChars(env, mainClassString, mainClass);
+
+ /* replace all the '.' with '/' */
+ while(result[++i] != '\0') {
+ if(result[i] == '.')
+ result[i] = '/';
+ }
+ return result;
+ }
+ return NULL;
+}
+
+void cleanupVM(int exitCode) {
+ JNIEnv * localEnv = env;
+ if (jvm == 0)
+ return;
+
+ if (secondThread)
+ (*jvm)->AttachCurrentThread(jvm, (void**)&localEnv, NULL);
+ else
+ localEnv = env;
+ if (localEnv == 0)
+ return;
+
+ /* we call System.exit() unless osgi.noShutdown is set */
+ if (shouldShutdown(env)) {
+ jclass systemClass = NULL;
+ jmethodID exitMethod = NULL;
+ systemClass = (*env)->FindClass(env, "java/lang/System");
+ if (systemClass != NULL) {
+ exitMethod = (*env)->GetStaticMethodID(env, systemClass, "exit", "(I)V");
+ if (exitMethod != NULL) {
+ (*env)->CallStaticVoidMethod(env, systemClass, exitMethod, exitCode);
+ }
+ }
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ }
+ (*jvm)->DestroyJavaVM(jvm);
+}
+
+static int shouldShutdown(JNIEnv * env) {
+ jclass booleanClass = NULL;
+ jmethodID method = NULL;
+ jstring arg = NULL;
+ jboolean result = 0;
+
+ booleanClass = (*env)->FindClass(env, "java/lang/Boolean");
+ if (booleanClass != NULL) {
+ method = (*env)->GetStaticMethodID(env, booleanClass, "getBoolean", "(Ljava/lang/String;)Z");
+ if (method != NULL) {
+ arg = newJavaString(env, _T_ECLIPSE("osgi.noShutdown"));
+ result = (*env)->CallStaticBooleanMethod(env, booleanClass, method, arg);
+ (*env)->DeleteLocalRef(env, arg);
+ }
+ }
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ return (result == 0);
+}
+
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseJNI.h b/features/org.eclipse.equinox.executable.feature/library/eclipseJNI.h
new file mode 100644
index 000000000..3ef4b89dc
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseJNI.h
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+#ifndef ECLIPSE_JNI_H
+#define ECLIPSE_JNI_H
+
+#include "eclipseUnicode.h"
+#include <jni.h>
+
+typedef struct {
+ int launchResult;
+ int runResult;
+ _TCHAR * errorMessage;
+} JavaResults;
+
+typedef jint (JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args);
+
+/* JNI Callback methods */
+/* Use name mangling since we may be linking these from java with System.LoadLibrary */
+#define set_exit_data Java_org_eclipse_equinox_launcher_JNIBridge__1set_1exit_1data
+#define set_launcher_info Java_org_eclipse_equinox_launcher_JNIBridge__1set_1launcher_1info
+#define update_splash Java_org_eclipse_equinox_launcher_JNIBridge__1update_1splash
+#define show_splash Java_org_eclipse_equinox_launcher_JNIBridge__1show_1splash
+#define get_splash_handle Java_org_eclipse_equinox_launcher_JNIBridge__1get_1splash_1handle
+#define takedown_splash Java_org_eclipse_equinox_launcher_JNIBridge__1takedown_1splash
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * org_eclipse_equinox_launcher_JNIBridge#_set_exit_data
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL set_exit_data(JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * org_eclipse_equinox_launcher_JNIBridge#_set_launcher_info
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL set_launcher_info(JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * org_eclipse_equinox_launcher_JNIBridge#_update_splash
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL update_splash(JNIEnv *, jobject);
+
+/*
+ * org_eclipse_equinox_launcher_JNIBridge#_get_splash_handle
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL get_splash_handle(JNIEnv *, jobject);
+
+/*
+ * org_eclipse_equinox_launcher_JNIBridge#_show_splash
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL show_splash(JNIEnv *, jobject, jstring);
+
+/*
+ * org_eclipse_equinox_launcher_JNIBridge#_takedown_splash
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL takedown_splash(JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Start the Java VM and Wait For It to Terminate
+ *
+ * This method is responsible for starting the Java VM and for
+ * detecting its termination. The resulting JVM exit code should
+ * be returned to the main launcher, which will display a message if
+ * the termination was not normal.
+ */
+extern JavaResults* startJavaJNI( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile );
+
+extern void cleanupVM( int );
+#endif
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseMain.c b/features/org.eclipse.equinox.executable.feature/library/eclipseMain.c
new file mode 100644
index 000000000..c45f3656f
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseMain.c
@@ -0,0 +1,468 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#include "eclipseUnicode.h"
+#include "eclipseCommon.h"
+#include "eclipseConfig.h"
+
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <locale.h>
+#include <sys/stat.h>
+
+static _TCHAR* libraryMsg =
+_T_ECLIPSE("The %s executable launcher was unable to locate its \n\
+companion shared library.");
+
+static _TCHAR* entryMsg =
+_T_ECLIPSE("There was a problem loading the shared library and \n\
+finding the entry point.");
+
+#define NAME _T_ECLIPSE("-name")
+#define VMARGS _T_ECLIPSE("-vmargs") /* special option processing required */
+/* New arguments have the form --launcher.<arg> to avoid collisions */
+#define LIBRARY _T_ECLIPSE("--launcher.library")
+#define SUPRESSERRORS _T_ECLIPSE("--launcher.suppressErrors")
+#define INI _T_ECLIPSE("--launcher.ini")
+
+/* this typedef must match the run method in eclipse.c */
+typedef int (*RunMethod)(int argc, _TCHAR* argv[], _TCHAR* vmArgs[]);
+typedef void (*SetInitialArgs)(int argc, _TCHAR*argv[], _TCHAR* library);
+
+static _TCHAR* name = NULL; /* program name */
+static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */
+static _TCHAR* programDir = NULL; /* directory where program resides */
+static _TCHAR* officialName = NULL;
+static int suppressErrors = 0; /* supress error dialogs */
+
+static int createUserArgs(int configArgc, _TCHAR **configArgv, int *argc, _TCHAR ***argv);
+static void parseArgs( int* argc, _TCHAR* argv[] );
+static _TCHAR* getDefaultOfficialName(_TCHAR* program);
+static _TCHAR* findProgram(_TCHAR* argv[]);
+static _TCHAR* findLibrary(_TCHAR* library, _TCHAR* program);
+static _TCHAR* checkForIni(int argc, _TCHAR* argv[]);
+static _TCHAR* getDirFromProgram(_TCHAR* program);
+
+static int initialArgc;
+static _TCHAR** initialArgv;
+
+_TCHAR* eclipseLibrary = NULL; /* path to the eclipse shared library */
+
+#ifdef UNICODE
+extern int main(int, char**);
+int mainW(int, wchar_t**);
+int wmain( int argc, wchar_t** argv ) {
+ return mainW(argc, argv);
+}
+
+int main(int argc, char* argv[]) {
+ /*
+ * Run the UNICODE version, convert the arguments from MBCS to UNICODE
+ */
+ int i, result;
+ wchar_t **newArgv = malloc((argc + 1) * sizeof(wchar_t *));
+ for (i=0; i<argc; i++) {
+ char *oldArg = argv[i];
+ int numChars = MultiByteToWideChar(CP_ACP, 0, oldArg, -1, NULL, 0);
+ wchar_t *newArg = malloc((numChars + 1) * sizeof(wchar_t));
+ newArg[numChars] = 0;
+ MultiByteToWideChar(CP_ACP, 0, oldArg, -1, newArg, numChars);
+ newArgv[i] = newArg;
+ }
+ newArgv[i] = NULL;
+ result = mainW(argc, newArgv);
+ for (i=0; i<argc; i++) {
+ free(newArgv[i]);
+ }
+ free(newArgv);
+ return result;
+}
+
+#define main mainW
+#endif /* UNICODE */
+
+int main( int argc, _TCHAR* argv[] )
+{
+ _TCHAR* errorMsg;
+ _TCHAR* program;
+ _TCHAR* iniFile;
+ _TCHAR* ch;
+ _TCHAR** configArgv = NULL;
+ int configArgc = 0;
+ int exitCode = 0;
+ int ret = 0;
+ void * handle = 0;
+ RunMethod runMethod;
+ SetInitialArgs setArgs;
+
+ setlocale(LC_ALL, "");
+
+ initialArgc = argc;
+ initialArgv = malloc((argc + 1) * sizeof(_TCHAR*));
+ memcpy(initialArgv, argv, (argc + 1) * sizeof(_TCHAR*));
+
+ /*
+ * Strip off any extroneous <CR> from the last argument. If a shell script
+ * on Linux is created in DOS format (lines end with <CR><LF>), the C-shell
+ * does not strip off the <CR> and hence the argument is bogus and may
+ * not be recognized by the launcher or eclipse itself.
+ */
+ ch = _tcschr( argv[ argc - 1 ], _T_ECLIPSE('\r') );
+ if (ch != NULL)
+ {
+ *ch = _T_ECLIPSE('\0');
+ }
+
+ /* Determine the full pathname of this program. */
+ program = findProgram(argv);
+
+ /* Parse configuration file arguments */
+ iniFile = checkForIni(argc, argv);
+ if (iniFile != NULL)
+ ret = readConfigFile(iniFile, &configArgc, &configArgv);
+ else
+ ret = readIniFile(program, &configArgc, &configArgv);
+ if (ret == 0)
+ {
+ parseArgs (&configArgc, configArgv);
+ }
+
+ /* Parse command line arguments */
+ /* Overrides configuration file arguments */
+ parseArgs( &argc, argv );
+
+ /* Special case - user arguments specified in the config file
+ * are appended to the user arguments passed from the command line.
+ */
+ if (configArgc > 0)
+ {
+ createUserArgs(configArgc, configArgv, &argc, &argv);
+ }
+
+ /* Initialize official program name */
+ officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName(program);
+
+ /* Find the directory where the Eclipse program is installed. */
+ programDir = getDirFromProgram(program);
+
+ /* Find the eclipse library */
+ eclipseLibrary = findLibrary(eclipseLibrary, program);
+
+ if(eclipseLibrary != NULL)
+ handle = loadLibrary(eclipseLibrary);
+ if(handle == NULL) {
+ errorMsg = malloc( (_tcslen(libraryMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, libraryMsg, officialName );
+ if (!suppressErrors)
+ displayMessage( officialName, errorMsg );
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, errorMsg);
+ free( errorMsg );
+ exit( 1 );
+ }
+
+ setArgs = (SetInitialArgs)findSymbol(handle, SET_INITIAL_ARGS);
+ if(setArgs != NULL)
+ setArgs(initialArgc, initialArgv, eclipseLibrary);
+ else {
+ if(!suppressErrors)
+ displayMessage(officialName, entryMsg);
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, entryMsg);
+ exit(1);
+ }
+
+ runMethod = (RunMethod)findSymbol(handle, RUN_METHOD);
+ if(runMethod != NULL)
+ exitCode = runMethod(argc, argv, userVMarg);
+ else {
+ if(!suppressErrors)
+ displayMessage(officialName, entryMsg);
+ else
+ _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, entryMsg);
+ exit(1);
+ }
+ unloadLibrary(handle);
+
+ free( eclipseLibrary );
+ free( programDir );
+ free( program );
+ free( officialName );
+
+ return exitCode;
+}
+
+_TCHAR* getProgramPath() {
+ return NULL;
+}
+
+static _TCHAR* findProgram(_TCHAR* argv[]) {
+ _TCHAR * program;
+#ifdef _WIN32
+ /* windows, make sure we are looking for the .exe */
+ _TCHAR * ch;
+ int length = _tcslen(argv[0]);
+ ch = malloc( (length + 5) * sizeof(_TCHAR));
+ _tcscpy(ch, argv[0]);
+
+ if (length <= 4 || _tcsicmp( &ch[ length - 4 ], _T_ECLIPSE(".exe") ) != 0)
+ _tcscat(ch, _T_ECLIPSE(".exe"));
+
+ program = findCommand(ch);
+ if (ch != program)
+ free(ch);
+#else
+ program = findCommand( argv[0] );
+#endif
+ if (program == NULL)
+ {
+#ifdef _WIN32
+ program = malloc( MAX_PATH_LENGTH + 1 );
+ GetModuleFileName( NULL, program, MAX_PATH_LENGTH );
+ argv[0] = program;
+#else
+ program = malloc( (strlen( argv[0] ) + 1) * sizeof(_TCHAR) );
+ strcpy( program, argv[0] );
+#endif
+ } else if (_tcscmp(argv[0], program) != 0) {
+ argv[0] = program;
+ }
+ return program;
+}
+
+/*
+ * Parse arguments of the command.
+ */
+static void parseArgs( int* pArgc, _TCHAR* argv[] )
+{
+ int index;
+
+ /* Ensure the list of user argument is NULL terminated. */
+ argv[ *pArgc ] = NULL;
+
+ /* For each user defined argument */
+ for (index = 0; index < *pArgc; index++){
+ if(_tcsicmp(argv[index], VMARGS) == 0) {
+ userVMarg = &argv[ index+1 ];
+ argv[ index ] = NULL;
+ *pArgc = index;
+ } else if(_tcsicmp(argv[index], NAME) == 0) {
+ name = argv[++index];
+ } else if(_tcsicmp(argv[index], LIBRARY) == 0) {
+ eclipseLibrary = argv[++index];
+ } else if(_tcsicmp(argv[index], SUPRESSERRORS) == 0) {
+ suppressErrors = 1;
+ }
+ }
+}
+
+/* We need to look for --launcher.ini before parsing the other args */
+static _TCHAR* checkForIni(int argc, _TCHAR* argv[])
+{
+ int index;
+ for(index = 0; index < (argc - 1); index++) {
+ if(_tcsicmp(argv[index], INI) == 0) {
+ return argv[++index];
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Create a new array containing user arguments from the config file first and
+ * from the command line second.
+ * Allocate an array large enough to host all the strings passed in from
+ * the argument configArgv and argv. That array is passed back to the
+ * argv argument. That array must be freed with the regular free().
+ * Note that both arg lists are expected to contain the argument 0 from the C
+ * main method. That argument contains the path/executable name. It is
+ * only copied once in the resulting list.
+ *
+ * Returns 0 if success.
+ */
+static int createUserArgs(int configArgc, _TCHAR **configArgv, int *argc, _TCHAR ***argv)
+{
+ _TCHAR** newArray = (_TCHAR **)malloc((configArgc + *argc + 1) * sizeof(_TCHAR *));
+
+ newArray[0] = (*argv)[0]; /* use the original argv[0] */
+ memcpy(newArray + 1, configArgv, configArgc * sizeof(_TCHAR *));
+
+ /* Skip the argument zero (program path and name) */
+ memcpy(newArray + 1 + configArgc, *argv + 1, (*argc - 1) * sizeof(_TCHAR *));
+
+ /* Null terminate the new list of arguments and return it. */
+ *argv = newArray;
+ *argc += configArgc;
+ (*argv)[*argc] = NULL;
+
+ return 0;
+}
+
+/* Determine the Program Directory
+ *
+ * This function takes the directory where program executable resides and
+ * determines the installation directory.
+ */
+_TCHAR* getDirFromProgram(_TCHAR* program)
+{
+ _TCHAR* ch;
+
+ if(programDir != NULL)
+ return programDir;
+
+ programDir = malloc( (_tcslen( program ) + 1) * sizeof(_TCHAR) );
+ _tcscpy( programDir, program );
+ ch = lastDirSeparator( programDir );
+ if (ch != NULL)
+ {
+ *(ch+1) = _T_ECLIPSE('\0');
+ return programDir;
+ }
+
+ /* Can't figure out from the program, lets use the cwd */
+ free(programDir);
+ programDir = malloc( MAX_PATH_LENGTH * sizeof (_TCHAR));
+ _tgetcwd( programDir, MAX_PATH_LENGTH );
+ return programDir;
+}
+
+_TCHAR* getProgramDir()
+{
+ return programDir;
+}
+
+_TCHAR* getOfficialName() {
+ return officialName;
+}
+
+/*
+ * Determine the default official application name
+ *
+ * This function provides the default application name that appears in a variety of
+ * places such as: title of message dialog, title of splash screen window
+ * that shows up in Windows task bar.
+ * It is computed from the name of the launcher executable and
+ * by capitalizing the first letter. e.g. "c:/ide/eclipse.exe" provides
+ * a default name of "Eclipse".
+ */
+static _TCHAR* getDefaultOfficialName(_TCHAR* program)
+{
+ _TCHAR *ch = NULL;
+
+ /* Skip the directory part */
+ ch = lastDirSeparator( program );
+ if (ch == NULL) ch = program;
+ else ch++;
+
+ ch = _tcsdup( ch );
+#ifdef _WIN32
+ {
+ /* Search for the extension .exe and cut it */
+ _TCHAR *extension = _tcsrchr(ch, _T_ECLIPSE('.'));
+ if (extension != NULL)
+ {
+ *extension = _T_ECLIPSE('\0');
+ }
+ }
+#endif
+ /* Upper case the first character */
+#ifndef LINUX
+ {
+ *ch = _totupper(*ch);
+ }
+#else
+ {
+ if (*ch >= 'a' && *ch <= 'z')
+ {
+ *ch -= 32;
+ }
+ }
+#endif
+ return ch;
+}
+
+static _TCHAR* findLibrary(_TCHAR* library, _TCHAR* program)
+{
+ _TCHAR* c;
+ _TCHAR* path;
+ _TCHAR* fragment;
+ _TCHAR* result;
+ _TCHAR* dot = _T_ECLIPSE(".");
+ size_t progLength, pathLength;
+ size_t fragmentLength;
+ struct _stat stats;
+
+ if (library != NULL) {
+ path = checkPath(library, programDir, 1);
+ if (_tstat(path, &stats) == 0 && (stats.st_mode & S_IFDIR) != 0)
+ {
+ /* directory, find the highest version eclipse_* library */
+ result = findFile(path, _T_ECLIPSE("eclipse"));
+ } else {
+ /* file, return it */
+ result = _tcsdup(path);
+ }
+
+ if (path != library)
+ free(path);
+ return result;
+ }
+
+ /* build the equinox.launcher fragment name */
+ fragmentLength = _tcslen(DEFAULT_EQUINOX_STARTUP) + 1 + _tcslen(wsArg) + 1 + _tcslen(osArg) + 1 + _tcslen(osArchArg) + 1;
+ fragment = malloc(fragmentLength * sizeof(_TCHAR));
+ _tcscpy(fragment, DEFAULT_EQUINOX_STARTUP);
+ _tcscat(fragment, dot);
+ _tcscat(fragment, wsArg);
+ _tcscat(fragment, dot);
+ _tcscat(fragment, osArg);
+ //!(fragmentOS.equals(Constants.OS_MACOSX) && !Constants.ARCH_X86_64.equals(fragmentArch))
+#if !(defined(MACOSX) && !defined(__x86_64__))
+ /* The Mac fragment covers both archs and does not have that last segment */
+ _tcscat(fragment, dot);
+ _tcscat(fragment, osArchArg);
+#endif
+ progLength = pathLength = _tcslen(programDir);
+#ifdef MACOSX
+ pathLength += 9;
+#endif
+ path = malloc( (pathLength + 1 + 7 + 1) * sizeof(_TCHAR));
+ _tcscpy(path, programDir);
+ if (!IS_DIR_SEPARATOR(path[progLength - 1])) {
+ path[progLength] = dirSeparator;
+ path[progLength + 1] = 0;
+ }
+#ifdef MACOSX
+ _tcscat(path, _T_ECLIPSE("../../../"));
+#endif
+ _tcscat(path, _T_ECLIPSE("plugins"));
+
+ c = findFile(path, fragment);
+ free(fragment);
+ if (c == NULL)
+ return c;
+ fragment = c;
+
+ result = findFile(fragment, _T_ECLIPSE("eclipse"));
+
+ free(fragment);
+ free(path);
+
+ return result;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.c b/features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.c
new file mode 100644
index 000000000..a599589d5
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.c
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+/* Eclipse Mozilla Utility Methods */
+
+#ifdef MOZILLA_FIX
+
+#include "eclipseMozilla.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+static char* prefixes[] = {
+ "xulrunner-1",
+ "mozilla-seamonkey-1",
+ "seamonkey-1",
+ "mozilla-1",
+ "mozilla-firefox-2",
+ "firefox-2",
+ "mozilla-firefox-3",
+ "firefox-3",
+ NULL
+};
+static const int XULRUNNER_INDEX = 0;
+
+/* Filter function used by fixEnvForMozilla() for finding directories
+ * with a desired prefix.
+ */
+int filter(const struct dirent *dir)
+{
+#if defined(__amd64__) || defined(__x86_64__) || defined(__powerpc64__)
+ char* root = "/usr/lib64/";
+#else
+ char* root = "/usr/lib/";
+#endif
+
+#if defined (SOLARIS)
+ /*
+ * The solaris compiler does not do static linking, so just check
+ * for a common lib to ensure that the install seems valid.
+ */
+ char* testlib = "/libxpcom.so";
+#else
+ /* Ensure that the install is dynamically-linked and is built with GTK2 */
+ char* testlib = "/components/libwidget_gtk2.so";
+#endif
+
+ struct stat buf;
+ int index = 0;
+ char* dirname = (char *)dir->d_name;
+
+ char* prefix = prefixes [index];
+ while (prefix != NULL)
+ {
+ int prefixLength = strlen(prefix);
+ if (strncmp(dirname, prefix, prefixLength) == 0)
+ {
+ /* If a xulrunner install is found then success is immediate since
+ * xulrunner always provides an embeddable GRE.
+ */
+ if (index == XULRUNNER_INDEX) return 1; /* include in scandir result */
+
+ int dirLength = strlen(dirname);
+ char* testpath = malloc (strlen(root) + dirLength + strlen(testlib) + 1);
+ strcpy(testpath, root);
+ strcat(testpath, dirname);
+ strcat(testpath, testlib);
+ int success = stat(testpath, &buf) == 0;
+ free(testpath);
+ if (success)
+ {
+ return 1; /* include in scandir result */
+ }
+ }
+ prefix = prefixes [++index];
+ }
+ return 0; /* exclude from scandir result */
+}
+
+#if defined (SOLARIS)
+/*
+ * A replacement for
+ * scandir(const char *dir, struct dirent ***namelist, filter, alphasort);
+ * because scandir & alphasort don't exist on Solaris 9.
+ * Return the dirent->d_name that was sorted the highest according to strcoll,
+ * or NULL on error or if no entries matched the filter.
+ * The caller is responsible for freeing the returned string
+ */
+char * scan(const char * path) {
+ DIR *dir = NULL;
+ struct dirent * entry = NULL;
+ char * candidate = NULL;
+
+ if ((dir = opendir(path)) == NULL) {
+ return NULL;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (filter(entry)) {
+ if (candidate == NULL) {
+ candidate = strdup(entry->d_name);
+ } else if (strcoll(candidate, entry->d_name) < 0) {
+ free(candidate);
+ candidate = strdup(entry->d_name);
+ }
+ }
+ }
+ closedir(dir);
+
+ return candidate;
+}
+#endif
+
+/* Set the environmnent required by the SWT Browser widget to bind to Mozilla.
+ * The SWT Browser widget relies on Mozilla on Linux. The LD_LIBRARY_PATH
+ * and the Mozilla environment variable MOZILLA_FIVE_HOME must point
+ * to the installation directory of Mozilla.
+ *
+ * 1. Use the location set by MOZILLA_FIVE_HOME if it is defined
+ * 2. Parse the file /etc/gre.conf if it is defined. This file is
+ * set by the RedtHat RPM manager.
+ * 3. Try some common installation locations.
+ */
+void fixEnvForMozilla() {
+ static int fixed = 0;
+ if (fixed) return;
+ {
+ char *ldPath = (char*)getenv("LD_LIBRARY_PATH");
+ char *mozillaFiveHome = (char*)getenv("MOZILLA_FIVE_HOME");
+ char *grePath = NULL; /* Gecko Runtime Environment Location */
+ fixed = 1;
+ /* Always dup the string so we can free later */
+ if (ldPath != NULL) ldPath = strdup(ldPath);
+ else ldPath = strdup("");
+
+ /* MOZILLA_FIVE_HOME (if defined) points to the Mozilla
+ * install directory. Don't look any further if it is set.
+ */
+ if (mozillaFiveHome != NULL)
+ {
+ grePath = strdup(mozillaFiveHome);
+ }
+
+ /* The file gre.conf (if available) points to the
+ * Mozilla install directory. Don't look any further if
+ * it is set.
+ */
+ if (grePath == NULL)
+ {
+ struct stat buf;
+ FILE *file = NULL;
+#if defined(__amd64__) || defined(__x86_64__) || defined(__powerpc64__)
+ if (stat("/etc/gre64.conf", &buf) == 0)
+ {
+ file = fopen("/etc/gre64.conf", "r");
+ }
+ else if (stat("/etc/gre.d/gre64.conf", &buf) == 0)
+ {
+ file = fopen("/etc/gre.d/gre64.conf", "r");
+ } else
+#endif
+ if (stat("/etc/gre.conf", &buf) == 0)
+ {
+ file = fopen("/etc/gre.conf", "r");
+ }
+ else if (stat("/etc/gre.d/gre.conf", &buf) == 0)
+ {
+ file = fopen("/etc/gre.d/gre.conf", "r");
+ }
+ if (file != NULL)
+ {
+ char buffer[1024];
+ char path[1024];
+ while (fgets(buffer, 1024, file) != NULL)
+ {
+ if (sscanf(buffer, "GRE_PATH=%s", path) == 1)
+ {
+ int index = 0;
+ char* prefix = prefixes [index];
+ while (prefix != NULL)
+ {
+ if (strstr(path, prefix))
+ {
+ grePath = strdup(path);
+ break;
+ }
+ prefix = prefixes [++index];
+ }
+ }
+ }
+ fclose(file);
+ }
+ }
+
+ /* Try some common installation locations. */
+ if (grePath == NULL)
+ {
+ /* try xulrunner-1*, mozilla-1*, firefox-2/3*, seamonkey-1* directories in /usr/lib/ */
+#if defined(__amd64__) || defined(__x86_64__) || defined(__powerpc64__)
+ char* dir = "/usr/lib64/";
+#else
+ char* dir = "/usr/lib/";
+#endif
+#if defined (SOLARIS)
+ char * name = scan(dir);
+ if (name != NULL) {
+#else
+ struct dirent **namelist;
+ int i;
+ int count = scandir(dir, &namelist, filter, alphasort);
+ if (count > 0)
+ {
+ /* count-1 is used below in an attempt to choose XULRunner
+ * any time one is found
+ */
+ char* name = namelist [count - 1]->d_name;
+#endif
+ grePath = malloc (strlen(dir) + strlen(name) + 1);
+ strcpy(grePath, dir);
+ strcat(grePath, name);
+#if defined (SOLARIS)
+ free(name);
+#else
+ for (i = 0; i < count; i++) {
+ free(namelist [i]);
+ }
+ free(namelist);
+#endif
+ }
+
+#if defined (SOLARIS)
+ if (grePath == NULL)
+ {
+ /* some other typical installation locations */
+ char* dirs[] = {
+ "/usr/sfw/lib/mozilla/", /* Solaris location */
+ "/usr/lib/firefox/", /* OpenSolaris location */
+ NULL
+ };
+
+ /*
+ * The solaris compiler does not do static linking, so just check
+ * for a common lib to ensure that the install seems valid.
+ */
+ char* testlib = "libxpcom.so";
+
+ struct stat buf;
+ int index = 0;
+
+ char* dir = dirs [index++];
+ while (dir != NULL)
+ {
+ char* testpath = malloc (strlen(dir) + strlen(testlib) + 1);
+ strcpy(testpath, dir);
+ strcat(testpath, testlib);
+ int success = stat(testpath, &buf) == 0;
+ free(testpath);
+ if (success)
+ {
+ grePath = strdup(dir);
+ break;
+ }
+ dir = dirs [index++];
+ }
+ }
+#endif // SOLARIS
+ }
+
+ if (grePath != NULL)
+ {
+ /* If grePath contains "xulrunner" then do not change the LD_LIBRARY_PATH,
+ * since it is likely that a xulrunner (not a mozilla or firefox)
+ * will be found at runtime. Note that MOZILLA_FIVE_HOME is still
+ * updated if grePath contains "xul" since this variable can act as
+ * a backup GRE to try if an initially-detected one fails to load.
+ */
+ if (!strstr(grePath, "xulrunner")) {
+ ldPath = (char*)realloc(ldPath, strlen(ldPath) + strlen(grePath) + 2);
+ if (strlen(ldPath) > 0) strcat(ldPath, ":");
+ strcat(ldPath, grePath);
+ setenv("LD_LIBRARY_PATH", ldPath, 1);
+ }
+
+ if (mozillaFiveHome == NULL) setenv("MOZILLA_FIVE_HOME", grePath, 1);
+ free(grePath);
+ }
+ free(ldPath);
+ }
+}
+#endif /* MOZILLA_FIX */
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.h b/features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.h
new file mode 100644
index 000000000..e227741af
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseMozilla.h
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef ECLIPSE_MOZILLA_H
+#define ECLIPSE_MOZILLA_H
+
+/* Eclipse Mozilla Utility Methods */
+
+#ifdef MOZILLA_FIX
+extern void fixEnvForMozilla();
+#endif /* MOZILLA_FIX */
+
+#endif /* ECLIPSE_MOZILLA_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseNix.c b/features/org.eclipse.equinox.executable.feature/library/eclipseNix.c
new file mode 100644
index 000000000..bc57e2250
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseNix.c
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+/* This file contains code common between GTK & Motif */
+#include "eclipseOS.h"
+#include "eclipseCommon.h"
+#include "eclipseMozilla.h"
+#include "eclipseUtil.h"
+#include "eclipseJNI.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef i386
+#define JAVA_ARCH "i386"
+#elif defined(__ppc__) || defined(__powerpc64__)
+#define JAVA_ARCH "ppc"
+#elif defined(SOLARIS)
+#define JAVA_ARCH "sparc"
+#elif defined(__amd64__) || defined(__x86_64__)
+#define JAVA_ARCH "amd64"
+#else
+#define JAVA_ARCH DEFAULT_OS_ARCH
+#endif
+
+#ifdef AIX
+#define LIB_PATH_VAR _T_ECLIPSE("LIBPATH")
+#else
+#define LIB_PATH_VAR _T_ECLIPSE("LD_LIBRARY_PATH")
+#endif
+
+#define MAX_LOCATION_LENGTH 40 /* none of the jvmLocations strings should be longer than this */
+static const char* jvmLocations [] = { "j9vm", "../jre/bin/j9vm",
+ "classic", "../jre/bin/classic",
+ "../lib/" JAVA_ARCH "/client",
+ "../lib/" JAVA_ARCH "/server",
+ "../lib/" JAVA_ARCH "/jrockit",
+ "../jre/lib/" JAVA_ARCH "/client",
+ "../jre/lib/" JAVA_ARCH "/server",
+ "../jre/lib/" JAVA_ARCH "/jrockit",
+ "../lib/jvm/jre/lib/" JAVA_ARCH "/client",
+ NULL };
+
+static void adjustLibraryPath( char * vmLibrary );
+static char * findLib(char * command);
+#ifdef NETSCAPE_FIX
+extern void fixEnvForNetscape();
+#endif /* NETSCAPE_FIX */
+
+char * findVMLibrary( char* command ) {
+ char * lib = findLib(command);
+ if( lib != NULL ) {
+ adjustLibraryPath(lib);
+ }
+ return lib;
+}
+
+static char * findLib(char * command) {
+ int i;
+ int pathLength;
+ struct stat stats;
+ char * path; /* path to resulting jvm shared library */
+ char * location; /* points to begining of jvmLocations section of path */
+
+ if (command != NULL) {
+ /*check first to see if command already points to the library */
+ if (isVMLibrary(command)) {
+ if (stat( command, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /* found it */
+ return strdup(command);
+ }
+ return NULL;
+ }
+
+ location = strrchr( command, dirSeparator ) + 1;
+ pathLength = location - command;
+ path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + strlen(vmLibrary) + 1) * sizeof(char));
+ strncpy(path, command, pathLength);
+ location = &path[pathLength];
+
+ /*
+ * We are trying base/jvmLocations[*]/vmLibrary
+ * where base is the directory containing the given java command, normally jre/bin
+ */
+ i = -1;
+ while(jvmLocations[++i] != NULL) {
+ sprintf(location, "%s%c%s", jvmLocations[i], dirSeparator, vmLibrary);
+ if (stat( path, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /* found it */
+ return path;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* adjust the LD_LIBRARY_PATH for the vmLibrary */
+static void adjustLibraryPath( char * vmLibrary ) {
+ char * c;
+ char * ldPath;
+ char * newPath;
+ int i;
+ int numPaths = 0;
+ int length = 0;
+ int needAdjust = 0;
+
+ char ** paths = NULL;
+#ifdef MOZILLA_FIX
+ fixEnvForMozilla();
+#endif /* MOZILLA_FIX */
+#ifdef NETSCAPE_FIX
+ fixEnvForNetscape();
+#endif /* NETSCAPE_FIX */
+
+ paths = getVMLibrarySearchPath(vmLibrary);
+
+ ldPath = (char*)getenv(LIB_PATH_VAR);
+ if (!ldPath) {
+ ldPath = _T_ECLIPSE("");
+ needAdjust = 1;
+ } else {
+ needAdjust = !containsPaths(ldPath, paths);
+ }
+ if (!needAdjust) {
+ for (i = 0; paths[i] != NULL; i++)
+ free(paths[i]);
+ free(paths);
+ return;
+ }
+
+ /* set the value for LD_LIBRARY_PATH */
+ length = strlen(ldPath);
+ c = concatStrings(paths);
+ newPath = malloc((_tcslen(c) + length + 1) * sizeof(_TCHAR));
+ _stprintf(newPath, _T_ECLIPSE("%s%s"), c, ldPath);
+
+ setenv( LIB_PATH_VAR, newPath, 1);
+ free(newPath);
+ free(c);
+
+ for (i = 0; i < numPaths; i++)
+ free(paths[i]);
+ free(paths);
+
+ /* now we must restart for this to take affect */
+ restartLauncher(initialArgv[0], initialArgv);
+}
+
+void restartLauncher( char* program, char* args[] )
+{
+ /* just restart in-place */
+ execvp( program != NULL ? program : args[0], args);
+}
+
+void processVMArgs(_TCHAR **vmargs[] ) {
+ /* nothing yet */
+}
+
+JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile )
+{
+ return startJavaJNI(libPath, vmArgs, progArgs, jarFile);
+}
+
+int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib ) {
+ int descriptors[2];
+ int result = 0;
+ int pid = -1;
+
+ if (javaVM == NULL)
+ return 0;
+
+ /* create pipe, [0] is read end, [1] is write end */
+ if (pipe(descriptors) != 0)
+ return 0; /* error */
+
+ pid = fork();
+ if (pid == 0 ) {
+ /* child, connect stdout & stderr to write end of the pipe*/
+ dup2(descriptors[1], STDERR_FILENO);
+ dup2(descriptors[1], STDOUT_FILENO);
+
+ /* close descriptors */
+ close(descriptors[0]);
+ close(descriptors[1]);
+
+ {
+ /* exec java -version */
+ _TCHAR *args [] = { javaVM, _T_ECLIPSE("-version"), NULL };
+ execv(args[0], args);
+ /* if we make it here, there was a problem with exec, just exit */
+ exit(0);
+ }
+ } else if (pid > 0){
+ /* parent */
+ FILE * stream = NULL;
+ int status = 0;
+ close(descriptors[1]);
+ stream = fdopen( descriptors[0], "r");
+ if (stream != NULL) {
+ _TCHAR buffer[256];
+ while ( fgets(buffer, 256, stream) != NULL) {
+ if (_tcsstr(buffer, _T_ECLIPSE("Java HotSpot(TM)")) || _tcsstr(buffer, _T_ECLIPSE("OpenJDK"))) {
+ result = 1;
+ break;
+ }
+ if (_tcsstr(buffer, _T_ECLIPSE("IBM")) != NULL) {
+ result = 0;
+ break;
+ }
+ }
+ fclose(stream);
+ close(descriptors[0]);
+ }
+ waitpid(pid, &status, 0);
+ } else {
+ /* failed to fork */
+ close(descriptors[0]);
+ close(descriptors[1]);
+ }
+ return result;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h b/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h
new file mode 100644
index 000000000..a0e0902d1
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ *******************************************************************************/
+
+#ifndef ECLIPSE_OS_H
+#define ECLIPSE_OS_H
+
+#include "eclipseJNI.h"
+#include "eclipseUnicode.h"
+
+#ifdef MACOSX
+#define JAVA_FRAMEWORK "/System/Library/Frameworks/JavaVM.framework"
+#endif
+
+/* Operating System Dependent Information */
+
+/*** See eclipse.c for information on the launcher runtime architecture ***/
+
+/* Global Variables */
+extern _TCHAR* defaultVM; /* name of VM to use normally */
+#ifdef _WIN32
+extern _TCHAR* consoleVM; /* windows needs a different vm executable for the console */
+#endif
+extern _TCHAR* shippedVMDir; /* VM bin directory with separator */
+extern _TCHAR* exitData; /* exit data set from Java */
+extern _TCHAR* vmLibrary; /* name of the VM shared library */
+extern int initialArgc; /* argc originally used to start launcher */
+extern _TCHAR** initialArgv; /* argv originally used to start launcher */
+extern _TCHAR* eeLibPath; /* library path specified in a .ee file */
+extern int secondThread; /* whether or not to start the vm on a second thread */
+
+/* OS Specific Functions */
+
+/** Display a Message
+ *
+ * This method is called to display a message to the user.
+ * The method should not return until the user has acknowledged
+ * the message. This method will only be called after the window
+ * system has been initialized.
+ */
+extern void displayMessage( _TCHAR* title, _TCHAR* message );
+
+
+/** Initialize the Window System
+ *
+ * This method is called after the command line arguments have been
+ * parsed. Its purpose is to initialize the corresponding window system.
+ *
+ * The showSplash flag indicates the splash window will be displayed by
+ * this process (e.g., value will be zero for the main launcher).
+ */
+extern int initWindowSystem( int* argc, _TCHAR* argv[], int showSplash );
+
+
+/** Show the Splash Window
+ *
+ * This method is called to display the actual splash window. It will only
+ * be called by the splash window process and not the main launcher process.
+ * The splash ID passed corresponds to the string returned from initWindowSystem().
+ * If possible, this ID should be used to communicate some piece of data back
+ * to the main launcher program for two reasons:
+ * 1) to detect when the splash window process terminates
+ * 2) to terminate the splash window process should the JVM terminate before it
+ * completes its initialization.
+ *
+ * Two parameters are passed: the install home directory and a specific bitmap image
+ * file for a feature. The feature's image file is tried first and if it cannot be
+ * displayed, the images from the install directory are used.
+ *
+ * Return (exit code):
+ * 0 - success
+ * non-zero - could not find a splash image to display
+ */
+extern int showSplash( const _TCHAR* featureImage );
+
+/** Get List of Java VM Arguments
+ *
+ * A given Java VM might require a special set of arguments in order to
+ * optimize its performance. This method returns a NULL terminated array
+ * of strings, where each string is a separate VM argument.
+ */
+extern _TCHAR** getArgVM( _TCHAR *vm );
+
+/* Find the vm shared library associated with the given java executable */
+extern _TCHAR * findVMLibrary( _TCHAR * command );
+
+extern void dispatchMessages();
+
+extern jlong getSplashHandle();
+
+extern void takeDownSplash();
+
+extern void restartLauncher( _TCHAR* program, _TCHAR* args[] );
+
+/* launch the vm in a separate process and wait for it to finish */
+extern JavaResults* launchJavaVM( _TCHAR* args[] );
+
+/* launch the vm in this process using JNI invocation */
+extern JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile );
+
+/* do any platform specific processing of the user vmargs */
+extern void processVMArgs(_TCHAR **vmargs[] );
+
+/* is this a Sun VM, returns 0 if we don't know */
+extern int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib );
+
+/* an array of paths that will need to be on the search path to load the vm shared library */
+extern _TCHAR ** getVMLibrarySearchPath(_TCHAR * vmLibrary);
+
+extern int reuseWorkbench(_TCHAR** filePath, int timeout);
+
+#endif /* ECLIPSE_OS_H */
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseShm.c b/features/org.eclipse.equinox.executable.feature/library/eclipseShm.c
new file mode 100644
index 000000000..e46c1f5bc
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseShm.c
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Silenio Quarti
+ *******************************************************************************/
+
+#include "eclipseOS.h"
+#include "eclipseShm.h"
+
+static _TCHAR* ECLIPSE_UNITIALIZED = _T_ECLIPSE("ECLIPSE_UNINITIALIZED");
+
+#ifdef _WIN32
+
+#include <stdio.h>
+
+#ifdef __MINGW32__
+#include <stdlib.h>
+#endif
+
+int createSharedData(_TCHAR** id, int size) {
+ HANDLE mapHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, NULL);
+ if (mapHandle == 0) return -1;
+ if (id != NULL) {
+ *id = malloc(18 * sizeof(_TCHAR));
+#ifdef WIN64
+ _stprintf(*id, _T_ECLIPSE("%lx_%lx"), GetCurrentProcessId(), (DWORDLONG) mapHandle);
+#else
+ _stprintf(*id, _T_ECLIPSE("%lx_%lx"), GetCurrentProcessId(), (DWORD) mapHandle);
+#endif
+ }
+ /* set the shared data to "uninitialized" */
+ setSharedData(*id, ECLIPSE_UNITIALIZED);
+ return 0;
+}
+
+static int getShmID(const _TCHAR* id, LPDWORD processID, LPHANDLE handle) {
+ if (id != NULL && _tcslen(id) > 0) {
+ DWORD i1;
+#ifdef WIN64
+ DWORDLONG i2;
+#else
+ DWORD i2;
+#endif
+ if (_stscanf(id, _T_ECLIPSE("%lx_%lx"), &i1, &i2) != 2) return -1;
+ *processID = (DWORD)i1;
+ *handle = (HANDLE)i2;
+ return 0;
+ }
+ return -1;
+}
+
+int destroySharedData(_TCHAR* id) {
+ DWORD processID;
+ HANDLE handle;
+ if (getShmID(id, &processID, &handle) == -1) return -1;
+ if (!CloseHandle(handle)) return -1;
+ return 0;
+}
+
+int getSharedData(_TCHAR* id, _TCHAR** data) {
+ _TCHAR *sharedData, *newData = NULL;
+ DWORD processID;
+ HANDLE handle, mapHandle = NULL, processHandle;
+ if (getShmID(id, &processID, &handle) == -1) return -1;
+ if (processID == GetCurrentProcessId()) {
+ mapHandle = handle;
+ } else {
+ processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
+ if (processHandle == NULL) return -1;
+ DuplicateHandle(processHandle, handle, GetCurrentProcess(), &mapHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS);
+ CloseHandle(processHandle);
+ }
+ if (mapHandle == NULL) return -1;
+ sharedData = MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, 0);
+ if (sharedData == NULL) return -1;
+ if (_tcscmp(sharedData, ECLIPSE_UNITIALIZED)== 0) return 0;
+ if (data != NULL) {
+ size_t length = (_tcslen(sharedData) + 1) * sizeof(_TCHAR);
+ newData = malloc(length);
+ memcpy(newData, sharedData, length);
+ }
+ if (!UnmapViewOfFile(sharedData)) {
+ free(newData);
+ return -1;
+ }
+ if (handle != mapHandle) {
+ CloseHandle(mapHandle);
+ }
+ *data = newData;
+ return 0;
+}
+
+int setSharedData(const _TCHAR* id, const _TCHAR* data) {
+ _TCHAR* sharedData;
+ DWORD processID;
+ HANDLE handle, mapHandle = NULL, processHandle;
+ if (getShmID(id, &processID, &handle) == -1) return -1;
+ if (processID == GetCurrentProcessId()) {
+ mapHandle = handle;
+ } else {
+ processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
+ if (processHandle == NULL) return -1;
+ DuplicateHandle(processHandle, handle, GetCurrentProcess(), &mapHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS);
+ CloseHandle(processHandle);
+ }
+ if (mapHandle == NULL) return -1;
+ sharedData = MapViewOfFile(mapHandle, FILE_MAP_WRITE, 0, 0, 0);
+ if (sharedData == NULL) return -1;
+ if (data != NULL) {
+ size_t length = (_tcslen(data) + 1) * sizeof(_TCHAR);
+ memcpy(sharedData, data, length);
+ } else {
+ memset(sharedData, 0, sizeof(_TCHAR));
+ }
+ if (!UnmapViewOfFile(sharedData)) {
+ return -1;
+ }
+ if (handle != mapHandle) {
+ CloseHandle(mapHandle);
+ }
+ return 0;
+}
+
+#elif PHOTON
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int createSharedData(char** id, int size) {
+ int fd;
+ char* location = "/tmp/eclipse_%x";
+ char* name = malloc(strlen(location) + 9);
+ sprintf(name, location, getpid());
+ if ((fd = shm_open(name, O_RDWR | O_CREAT, 0666 )) == -1) return -1;
+ if (ftruncate(fd, size) == -1 ) {
+ shm_unlink(name);
+ return -1;
+ }
+ close( fd );
+ if (id != NULL) {
+ *id = name;
+ }
+ return 0;
+}
+
+int destroySharedData(char* id) {
+ return shm_unlink(id);
+}
+
+int getSharedData(char* id, char** data) {
+ int fd, length, size;
+ char *sharedData, *newData = NULL;
+ if ((fd = shm_open(id, O_RDWR, 0666 )) == -1) return -1;
+ size = lseek(fd, 0, SEEK_END);
+ sharedData = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
+ if (sharedData != MAP_FAILED) {
+ if (data != NULL) {
+ length = strlen(sharedData) + 1;
+ newData = malloc(length);
+ memcpy(newData, sharedData, length);
+ }
+ munmap(sharedData, size);
+ }
+ close(fd);
+ *data = newData;
+ return newData == NULL ? -1 : 0;
+}
+
+int setSharedData(char* id, char* data) {
+ int fd, length, size;
+ char *sharedData;
+ if ((fd = shm_open(id, O_RDWR, 0666 )) == -1) return -1;
+ size = lseek(fd, 0, SEEK_END);
+ sharedData = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
+ if (sharedData != MAP_FAILED) {
+ if (data != NULL) {
+ length = strlen(data) + 1;
+ memcpy(sharedData, data, length);
+ } else {
+ memset(sharedData, 0, sizeof(char));
+ }
+ munmap(sharedData, size);
+ }
+ close(fd);
+ return 0;
+}
+
+#else /* Unix like platforms */
+
+#include <sys/shm.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int createSharedData(char** id, int size) {
+ int shmid;
+ key_t key = getpid();
+ if ((shmid = shmget(key, size, IPC_CREAT | 0666)) < 0) {
+ return -1;
+ }
+ if (id != NULL) {
+ *id = malloc(9 * sizeof(char));
+ sprintf(*id, "%x", shmid);
+ }
+ setSharedData(*id, ECLIPSE_UNITIALIZED);
+ return 0;
+}
+
+static int getShmID(const char* id) {
+ int shmid = -1;
+ /* Determine the shared memory id. */
+ if (id != NULL && strlen(id) > 0) {
+ sscanf(id, "%x", &shmid);
+ }
+ return shmid;
+}
+
+int destroySharedData(char* id) {
+ int shmid = getShmID(id);
+ if (shmid == -1) return -1;
+ return shmctl(shmid, IPC_RMID, NULL);
+}
+
+int getSharedData( char* id, char** data ) {
+ char *sharedData, *newData = NULL;
+ int length;
+ int shmid = getShmID(id);
+ if (shmid == -1) return -1;
+ sharedData = shmat(shmid, (void *)0, 0);
+ if (sharedData == (char *)(-1)) return -1;
+ if (_tcscmp(sharedData, ECLIPSE_UNITIALIZED) == 0) return 0;
+ length = strlen(sharedData) + 1;
+ newData = malloc(length);
+ memcpy(newData, sharedData, length);
+ if (shmdt(sharedData) != 0) {
+ free(newData);
+ return -1;
+ }
+ *data = newData;
+ return 0;
+}
+
+int setSharedData(const char* id, const char* data) {
+ char* sharedData;
+ int length;
+ int shmid = getShmID(id);
+ if (shmid == -1) return -1;
+ sharedData = shmat(shmid, (void *)0, 0);
+ if (sharedData == (char *)(-1)) return -1;
+ if (data != NULL) {
+ length = strlen(data) + 1;
+ memcpy(sharedData, data, length);
+ } else {
+ memset(sharedData, 0, sizeof(char));
+ }
+ if (shmdt(sharedData) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+#endif /* Unix like platforms */
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseShm.h b/features/org.eclipse.equinox.executable.feature/library/eclipseShm.h
new file mode 100644
index 000000000..9cac1aa34
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseShm.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Silenio Quarti
+ *******************************************************************************/
+
+#ifndef ECLIPSE_SHM_H
+#define ECLIPSE_SHM_H
+
+/* Shared memory utilities */
+
+/**
+ * Creates and initializes a shared memory segment
+ * with the specified size in bytes. The id for the
+ * shared memory segment is stored in the id argument
+ * and can be used from any process. It must be freed
+ * with free().
+ *
+ * Returns 0 if success.
+ */
+extern int createSharedData(_TCHAR** id, int size);
+
+/**
+ * Destroy the shared memory segment specified by the
+ * id argument. The id is the same as the one return
+ * by createSharedData(). This function must be called
+ * by the same process that created the segment.
+ *
+ * Returns 0 if success.
+ */
+extern int destroySharedData(_TCHAR* id);
+
+/**
+ * Gets a copy of the shared memory segment specified
+ * by the id argument. The copy is stored in the data
+ * argument as a null terminated string and must be
+ * freed by free().
+ *
+ * Returns 0 if success.
+ */
+extern int getSharedData(_TCHAR* id, _TCHAR** data);
+
+/**
+ * Sets the shared memory segment specified by the id
+ * argument with a null terminated string specified by
+ * data.
+ *
+ * Returns 0 if sucess.
+ */
+extern int setSharedData(const _TCHAR* id, const _TCHAR* data);
+
+#endif /* ECLIPSE_SHM_H */
+
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseUnicode.h b/features/org.eclipse.equinox.executable.feature/library/eclipseUnicode.h
new file mode 100644
index 000000000..f98b77dc7
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseUnicode.h
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Silenio Quarti
+ *******************************************************************************/
+
+#ifndef ECLIPSE_UNICODE_H
+#define ECLIPSE_UNICODE_H
+
+#ifdef _WIN32
+
+#ifdef UNICODE
+#define _UNICODE
+#endif
+#include <windows.h>
+#include <tchar.h>
+#include <ctype.h>
+
+#ifdef __MINGW32__
+# ifdef UNICODE
+# ifndef _TCHAR
+# define _TCHAR TCHAR
+# endif /* _TCHAR */
+# ifndef _tgetcwd
+# define _tgetcwd _wgetcwd
+# endif /* _tgetcwd */
+# ifndef _tstat
+# define _tstat _wstat
+# endif /* _tstat */
+# ifndef _topendir
+# define _topendir _wopendir
+# endif /* _topendir */
+# ifndef _treaddir
+# define _treaddir _wreaddir
+# endif /* _treaddir */
+# ifndef _tclosedir
+# define _tclosedir _wclosedir
+# endif /* _tclosedir */
+# ifndef _tDIR
+# define _tDIR _WDIR
+# endif /* _tDIR */
+# else /* UNICODE */
+# ifndef _TCHAR
+# define _TCHAR char
+# endif /* _TCHAR */
+# ifndef _tgetcwd
+# define _tgetcwd getcwd
+# endif /* _tgetcwd */
+# ifndef _tstat
+# define _tstat _stat
+# endif /* _tstat */
+# ifndef _topendir
+#error message!
+# define _topendir opendir
+# endif /* _topendir */
+# ifndef _treaddir
+# define _treaddir readdir
+# endif /* _treaddir */
+# ifndef _tclosedir
+# define _tclosedir closedir
+# endif /* _tclosedir */
+# ifndef _tDIR
+# define _tDIR DIR
+# endif /* _tDIR */
+# endif /* UNICODE */
+#endif /* __MINGW32__ */
+
+#define _T_ECLIPSE _T
+
+#else /* Platforms other than Windows */
+
+#define _TCHAR char
+#define _T_ECLIPSE(s) s
+#define _fgetts fgets
+#define _stat stat
+#define _stprintf sprintf
+#define _ftprintf fprintf
+#define _stscanf sscanf
+#define _tcscat strcat
+#define _tcschr strchr
+#define _tcspbrk strpbrk
+#define _tcscmp strcmp
+#define _tcscpy strcpy
+#define _tcsdup strdup
+#define _tcsicmp strcasecmp
+#define _tcslen strlen
+#define _tcsncpy strncpy
+#define _tcsrchr strrchr
+#define _tfopen fopen
+#define _tgetcwd getcwd
+#define _tgetenv getenv
+#define _tcstol strtol
+#ifndef LINUX
+#define _totupper toupper
+#endif /* LINUX */
+#define _tprintf printf
+#define _tstat stat
+#define _tcsncmp strncmp
+#define _tcsstr strstr
+#define _topendir opendir
+#define _treaddir readdir
+#define _tclosedir closedir
+#define _tDIR DIR
+#endif /* _WIN32 */
+
+#endif /* ECLIPSE_UNICODE_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseUtil.c b/features/org.eclipse.equinox.executable.feature/library/eclipseUtil.c
new file mode 100644
index 000000000..130afb347
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseUtil.c
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ * Martin Oberhuber (Wind River) - [149994] Add --launcher.appendVmargs
+ *******************************************************************************/
+
+/* Eclipse Launcher Utility Methods */
+
+#include "eclipseOS.h"
+#include "eclipseCommon.h"
+#include "eclipseUtil.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <strings.h>
+#endif
+
+#define MAX_LINE_LENGTH 256
+
+/* Is the given VM J9 */
+int isJ9VM( _TCHAR* vm )
+{
+ _TCHAR * ch = NULL, *ch2 = NULL;
+ int res = 0;
+
+ if (vm == NULL)
+ return 0;
+
+ ch = lastDirSeparator( vm );
+ if (isVMLibrary(vm)) {
+ /* a library, call it j9 if the parent dir is j9vm */
+ if(ch == NULL)
+ return 0;
+ ch[0] = 0;
+ ch2 = lastDirSeparator(vm);
+ if(ch2 != NULL) {
+ res = (_tcsicmp(ch2 + 1, _T_ECLIPSE("j9vm")) == 0);
+ }
+ ch[0] = dirSeparator;
+ return res;
+ } else {
+ if (ch == NULL)
+ ch = vm;
+ else
+ ch++;
+ return (_tcsicmp( ch, _T_ECLIPSE("j9") ) == 0);
+ }
+}
+
+int checkProvidedVMType( _TCHAR* vm )
+{
+ _TCHAR* ch = NULL;
+ struct _stat stats;
+
+ if (vm == NULL) return VM_NOTHING;
+
+ if (_tstat(vm, &stats) == 0 && (stats.st_mode & S_IFDIR) != 0) {
+ /* directory */
+ return VM_DIRECTORY;
+ }
+
+ ch = _tcsrchr( vm, _T_ECLIPSE('.') );
+ if(ch == NULL)
+ return VM_OTHER;
+
+#ifdef _WIN32
+ if (_tcsicmp(ch, _T_ECLIPSE(".dll")) == 0)
+#else
+ if ((_tcsicmp(ch, _T_ECLIPSE(".so")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".jnilib")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".dylib")) == 0))
+#endif
+ {
+ return VM_LIBRARY;
+ }
+
+ if (_tcsicmp(ch, _T_ECLIPSE(".ee")) == 0)
+ return VM_EE_PROPS;
+
+ return VM_OTHER;
+}
+
+/*
+ * pathList is a pathSeparator separated list of paths, run each through
+ * checkPath and recombine the results.
+ * New memory is always allocated for the result
+ */
+_TCHAR * checkPathList( _TCHAR* pathList, _TCHAR* programDir, int reverseOrder) {
+ _TCHAR * c1, *c2;
+ _TCHAR * checked, *result;
+ size_t checkedLength = 0, resultLength = 0;
+ size_t bufferLength = _tcslen(pathList);
+
+ result = malloc(bufferLength * sizeof(_TCHAR));
+ c1 = pathList;
+ while (c1 != NULL && *c1 != _T_ECLIPSE('\0'))
+ {
+ c2 = _tcschr(c1, pathSeparator);
+ if (c2 != NULL)
+ *c2 = 0;
+
+ checked = checkPath(c1, programDir, reverseOrder);
+ checkedLength = _tcslen(checked);
+ if (resultLength + checkedLength + 1> bufferLength) {
+ bufferLength += checkedLength + 1;
+ result = realloc(result, bufferLength * sizeof(_TCHAR));
+ }
+
+ if(resultLength > 0) {
+ result[resultLength++] = pathSeparator;
+ result[resultLength] = _T_ECLIPSE('\0');
+ }
+ _tcscpy(result + resultLength, checked);
+ resultLength += checkedLength;
+
+ if(checked != c1)
+ free(checked);
+ if(c2 != NULL)
+ *(c2++) = pathSeparator;
+ c1 = c2;
+ }
+
+ return result;
+}
+
+_TCHAR * concatStrings(_TCHAR**strs) {
+ return concatPaths(strs, 0);
+}
+
+_TCHAR * concatPaths(_TCHAR** strs, _TCHAR separator) {
+ _TCHAR separatorString[] = { separator, 0 };
+ _TCHAR * result;
+ int i = -1;
+ size_t length = 0;
+ /* first count how large a buffer we need */
+ while (strs[++i] != NULL) {
+ length += _tcslen(strs[i]) + (separator != 0 ? 1 : 0);
+ }
+
+ result = malloc((length + 1) * sizeof(_TCHAR));
+ result[0] = 0;
+ i = -1;
+ while (strs[++i] != NULL) {
+ result = _tcscat(result, strs[i]);
+ if (separator != 0)
+ result = _tcscat(result, separatorString);
+ }
+ return result;
+}
+
+/*
+ * Concatenates two NULL-terminated arrays of Strings,
+ * returning a new NULL-terminated array.
+ * The returned array must be freed with the regular free().
+ */
+_TCHAR** concatArgs(_TCHAR** l1, _TCHAR** l2) {
+ _TCHAR** newArray = NULL;
+ int size1 = 0;
+ int size2 = 0;
+
+ if (l1 != NULL)
+ while (l1[size1] != NULL) size1++;
+ if (l2 != NULL)
+ while (l2[size2] != NULL) size2++;
+
+ newArray = (_TCHAR **) malloc((size1 + size2 + 1) * sizeof(_TCHAR *));
+ if (size1 > 0) {
+ memcpy(newArray, l1, size1 * sizeof(_TCHAR *));
+ }
+ if (size2 > 0) {
+ memcpy(newArray + size1, l2, size2 * sizeof(_TCHAR *));
+ }
+ newArray[size1 + size2] = NULL;
+ return newArray;
+}
+
+/*
+ * returns the relative position of arg in the NULL-terminated list of args,
+ * or -1 if args does not contain arg.
+ */
+int indexOf(_TCHAR *arg, _TCHAR **args) {
+ int i = -1;
+ if (arg != NULL && args != NULL) {
+ while (args[++i] != NULL) {
+ if (_tcsicmp(arg, args[i]) == 0) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+/*
+ * buffer contains a pathSeparator separated list of paths, check
+ * that it contains all the paths given. Each path is expected to be
+ * terminated with a pathSeparator character.
+ */
+int containsPaths(_TCHAR * str, _TCHAR** paths) {
+ _TCHAR * buffer;
+ _TCHAR * c;
+ int i;
+
+ /* terminate the string with a pathSeparator */
+ buffer = malloc((_tcslen(str) + 2) * sizeof(_TCHAR));
+ _stprintf(buffer, _T_ECLIPSE("%s%c"), str, pathSeparator);
+
+ for (i = 0; paths[i] != NULL; i++) {
+ c = _tcsstr(buffer, paths[i]);
+ if ( c == NULL || !(c == buffer || *(c - 1) == pathSeparator))
+ {
+ /* entry not found */
+ free(buffer);
+ return 0;
+ }
+ }
+ free(buffer);
+ return 1;
+}
+
+int isVMLibrary( _TCHAR* vm )
+{
+ _TCHAR *ch = NULL;
+ if (vm == NULL) return 0;
+ ch = _tcsrchr( vm, '.' );
+ if(ch == NULL)
+ return 0;
+#ifdef _WIN32
+ return (_tcsicmp(ch, _T_ECLIPSE(".dll")) == 0);
+#else
+ return (_tcsicmp(ch, _T_ECLIPSE(".so")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".jnilib")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".dylib")) == 0);
+#endif
+}
+
+#ifdef AIX
+
+#include <sys/types.h>
+#include <time.h>
+
+/* Return the JVM version in the format x.x.x
+ */
+char* getVMVersion( char *vmPath )
+{
+ char cmd[MAX_LINE_LENGTH];
+ char lineString[MAX_LINE_LENGTH];
+ char* firstChar;
+ char fileName[MAX_LINE_LENGTH];
+ time_t curTime;
+ FILE* fp;
+ int numChars = 0;
+ char* version = NULL;
+
+ /* Define a unique filename for the java output. */
+ (void) time(&curTime);
+ (void) sprintf(fileName, "/tmp/tmp%ld.txt", curTime);
+
+ /* Write java -version output to a temp file */
+ (void) sprintf(cmd,"%s -version 2> %s", vmPath, fileName);
+ (void) system(cmd);
+
+ fp = fopen(fileName, "r");
+ if (fp != NULL)
+ {
+ /* Read java -version output from a temp file */
+ if (fgets(lineString, MAX_LINE_LENGTH, fp) == NULL)
+ lineString[0] = '\0';
+ fclose(fp);
+ unlink(fileName);
+
+ /* Extract version number */
+ firstChar = (char *) (strchr(lineString, '"') + 1);
+ if (firstChar != NULL)
+ numChars = (int) (strrchr(lineString, '"') - firstChar);
+
+ /* Allocate a buffer and copy the version string into it. */
+ if (numChars > 0)
+ {
+ version = malloc( numChars + 1 );
+ strncpy(version, firstChar, numChars);
+ version[numChars] = '\0';
+ }
+ }
+
+ return version;
+}
+#endif /* AIX */
+
+/* Compare JVM Versions of the form "x.x.x..."
+ *
+ * Returns -1 if ver1 < ver2
+ * Returns 0 if ver1 = ver2
+ * Returns 1 if ver1 > ver2
+ */
+int versionCmp(char *ver1, char *ver2)
+{
+ char* dot1;
+ char* dot2;
+ int num1;
+ int num2;
+
+ dot1 = strchr(ver1, '.');
+ dot2 = strchr(ver2, '.');
+
+ num1 = atoi(ver1);
+ num2 = atoi(ver2);
+
+ if (num1 > num2)
+ return 1;
+
+ if (num1 < num2)
+ return -1;
+
+ if (dot1 && !dot2) /* x.y > x */
+ return 1;
+
+ if (!dot1 && dot2) /* x < x.y */
+ return -1;
+
+ if (!dot1 && !dot2) /* x == x */
+ return 0;
+
+ return versionCmp((char*)(dot1 + 1), (char*)(dot2 + 1) );
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseUtil.h b/features/org.eclipse.equinox.executable.feature/library/eclipseUtil.h
new file mode 100644
index 000000000..7843a3f9b
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/eclipseUtil.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ * Martin Oberhuber (Wind River) - [149994] Add --launcher.appendVmargs
+ *******************************************************************************/
+
+#ifndef ECLIPSE_UTIL_H
+#define ECLIPSE_UTIL_H
+
+/* constants for checkProvidedVMType */
+#define VM_NOTHING 0 /* NULL was given as input */
+#define VM_OTHER 1 /* don't know, could be executable or could be nothing */
+#define VM_DIRECTORY 2 /* it is a directory */
+#define VM_LIBRARY 3 /* it is a library (isVmLibrary would return true) */
+#define VM_EE_PROPS 4 /* it is a vm .ee properties file */
+
+/* Eclipse Launcher Utility Methods */
+
+/* Is the given Java VM J9 */
+extern int isJ9VM( _TCHAR* vm );
+
+/* Is the given file a shared library? */
+extern int isVMLibrary( _TCHAR* vm );
+
+/* determine what the provided -vm argument is referring to */
+extern int checkProvidedVMType( _TCHAR* vm );
+
+/* take a list of path separated with pathSeparator and run them through checkPath */
+extern _TCHAR * checkPathList( _TCHAR* pathList, _TCHAR* programDir, int reverseOrder);
+
+/* take a NULL terminated array of strings and concatenate them together into one string */
+extern _TCHAR * concatStrings(_TCHAR** strs);
+
+/* Concatenates two NULL-terminated arrays of strings into a new array of strings */
+extern _TCHAR** concatArgs(_TCHAR** l1, _TCHAR** l2);
+
+/* Returns the relative position of arg in the NULL-terminated list of args, or -1 */
+extern int indexOf(_TCHAR *arg, _TCHAR **args);
+
+/* take a NULL terminated array of strings and concatenate them together using the give pathSeparator */
+extern _TCHAR* concatPaths(_TCHAR** paths, _TCHAR pathSeparator);
+
+/* check that the buffer contains all the given paths */
+extern int containsPaths(_TCHAR * str, _TCHAR** paths);
+
+#ifdef AIX
+/* Get the version of the VM */
+extern char* getVMVersion( char* vm );
+#endif
+
+/* Compare JVM Versions */
+extern int versionCmp( char* ver1, char* ver2 );
+
+#endif /* ECLIPSE_UTIL_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/.gitignore b/features/org.eclipse.equinox.executable.feature/library/gtk/.gitignore
new file mode 100644
index 000000000..8d396827f
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/.gitignore
@@ -0,0 +1,3 @@
+/*.o
+/eclipse
+/eclipse_*.so \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/build.sh b/features/org.eclipse.equinox.executable.feature/library/gtk/build.sh
new file mode 100644
index 000000000..29d3871cb
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/build.sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#*******************************************************************************
+# Copyright (c) 2000, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Martin Oberhuber (Wind River) - [176805] Support building with gcc and debug
+#*******************************************************************************
+#
+# Usage: sh build.sh [<optional switches>] [clean]
+#
+# where the optional switches are:
+# -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+# -os <DEFAULT_OS> - default Eclipse "-os" value
+# -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value
+# -ws <DEFAULT_WS> - default Eclipse "-ws" value
+# -java <JAVA_HOME> - java install for jni headers
+#
+# All other arguments are directly passed to the "make" program.
+# This script can also be invoked with the "clean" argument.
+#
+# Examples:
+# sh build.sh clean
+# sh build.sh -java /usr/j2se OPTFLAG=-g PICFLAG=-fpic
+
+cd `dirname $0`
+
+# Define default values for environment variables used in the makefiles.
+programOutput="eclipse"
+defaultOS=""
+defaultOSArch=""
+defaultWS="gtk"
+EXEC_DIR=../../../../../rt.equinox.binaries/org.eclipse.equinox.executable
+defaultJava=DEFAULT_JAVA_JNI
+defaultJavaHome=""
+javaHome=""
+makefile=""
+if [ "${CC}" = "" ]; then
+ CC=cc
+ export CC
+fi
+
+# Parse the command line arguments and override the default values.
+extraArgs=""
+while [ "$1" != "" ]; do
+ if [ "$1" = "-os" ] && [ "$2" != "" ]; then
+ defaultOS="$2"
+ shift
+ elif [ "$1" = "-arch" ] && [ "$2" != "" ]; then
+ defaultOSArch="$2"
+ shift
+ elif [ "$1" = "-ws" ] && [ "$2" != "" ]; then
+ defaultWS="$2"
+ shift
+ elif [ "$1" = "-output" ] && [ "$2" != "" ]; then
+ programOutput="$2"
+ shift
+ elif [ "$1" = "-java" ] && [ "$2" != "" ]; then
+ javaHome="$2"
+ shift
+ else
+ extraArgs="$extraArgs $1"
+ fi
+ shift
+done
+if [ "$defaultOS" = "" ]; then
+ defaultOS=`uname -s`
+fi
+if [ "$defaultOSArch" = "" ]; then
+ defaultOSArch=`uname -m`
+fi
+
+
+case $defaultOS in
+ "Linux" | "linux")
+ makefile="make_linux.mak"
+ defaultOS="linux"
+ case $defaultOSArch in
+ "x86_64")
+ defaultOSArch="x86_64"
+ defaultJava=DEFAULT_JAVA_EXEC
+ [ -d /bluebird/teamswt/swt-builddir/build/JRE/x64/jdk1.6.0_14 ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/build/JRE/x64/jdk1.6.0_14"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ i?86 | "x86")
+ defaultOSArch="x86"
+ [ -d /bluebird/teamswt/swt-builddir/build/JRE/x32/jdk1.6.0_14 ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/build/JRE/x32/jdk1.6.0_14"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "ppc")
+ defaultOSArch="ppc"
+ defaultJava=DEFAULT_JAVA_EXEC
+ [ -d /bluebird/teamswt/swt-builddir/JDKs/PPC/ibm-java2-ppc-50 ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/JDKs/PPC/ibm-java2-ppc-50"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "ppc64")
+ defaultOSArch="ppc64"
+ defaultJava=DEFAULT_JAVA_EXEC
+ [ -d /bluebird/teamswt/swt-builddir/JDKs/PPC64/ibm-java2-ppc64-50 ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/JDKs/PPC64/ibm-java2-ppc64-50"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "s390")
+ defaultOSArch="s390"
+ defaultJava=DEFAULT_JAVA_EXEC
+ OUTPUT_DIR="$EXEC_DIR/contributed/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "s390x")
+ defaultOSArch="s390x"
+ defaultJava=DEFAULT_JAVA_EXEC
+ OUTPUT_DIR="$EXEC_DIR/contributed/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "ia64")
+ defaultOSArch="ia64"
+ defaultJava=DEFAULT_JAVA_EXEC
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ *)
+ echo "*** Unknown MODEL <${MODEL}>"
+ ;;
+ esac
+ ;;
+ "AIX" | "aix")
+ makefile="make_aix.mak"
+ defaultOS="aix"
+ if [ -z "$defaultOSArch" ]; then
+ defaultOSArch="ppc64"
+ fi
+ [ -d /bluebird/teamswt/swt-builddir/JDKs/AIX/PPC64/j564/sdk ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/JDKs/AIX/PPC64/j564/sdk"
+ ;;
+ "HP-UX" | "hpux")
+ makefile="make_hpux.mak"
+ defaultOS="hpux"
+ case $defaultOSArch in
+ "ia64_32")
+ PATH=$PATH:/opt/hp-gcc/bin:/opt/gtk2.6/bin
+ PKG_CONFIG_PATH="/opt/gtk2.6/lib/pkgconfig"
+ ;;
+ "ia64")
+ PATH=$PATH:/opt/hp-gcc/bin:/opt/gtk_64bit/bin
+ PKG_CONFIG_PATH="/opt/gtk_64bit/lib/hpux64/pkgconfig"
+ ;;
+ esac
+ export PATH PKG_CONFIG_PATH
+ [ -d /opt/java1.5 ] && defaultJavaHome="/opt/java1.5"
+ ;;
+ "SunOS" | "solaris")
+ makefile="make_solaris.mak"
+ defaultOS="solaris"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ #PATH=/usr/ccs/bin:/opt/SUNWspro/bin:$PATH
+ PATH=/usr/ccs/bin:/export/home/SUNWspro/bin:$PATH
+ export PATH
+ if [ "$PROC" = "" ]; then
+ PROC=`uname -p`
+ fi
+ case ${PROC} in
+ "i386" | "x86")
+ defaultOSArch="x86"
+ [ -d /bluebird/teamswt/swt-builddir/build/JRE/Solaris_x86/jdk1.6.0_14 ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/build/JRE/Solaris_x86/jdk1.6.0_14"
+ CC=cc
+ ;;
+ "sparc")
+ defaultOSArch="sparc"
+ [ -d /bluebird/teamswt/swt-builddir/build/JRE/SPARC/jdk1.6.0_14 ] && defaultJavaHome="/bluebird/teamswt/swt-builddir/build/JRE/SPARC/jdk1.6.0_14"
+ CC=cc
+ ;;
+ *)
+ echo "*** Unknown processor type <${PROC}>"
+ ;;
+ esac
+ ;;
+ *)
+ echo "Unknown OS -- build aborted"
+ ;;
+esac
+export CC
+
+
+# Set up environment variables needed by the makefiles.
+PROGRAM_OUTPUT="$programOutput"
+DEFAULT_OS="$defaultOS"
+DEFAULT_OS_ARCH="$defaultOSArch"
+DEFAULT_WS="$defaultWS"
+DEFAULT_JAVA=$defaultJava
+
+origJavaHome=$JAVA_HOME
+if [ -n "$javaHome" ]; then
+ JAVA_HOME=$javaHome
+ export JAVA_HOME
+elif [ -z "$JAVA_HOME" -a -n "$defaultJavaHome" ]; then
+ JAVA_HOME="$defaultJavaHome"
+ export JAVA_HOME
+fi
+
+if [ "$defaultOSArch" = "ppc64" ]; then
+ if [ "$defaultOS" = "aix" ]; then
+ M_ARCH=-maix64
+ else
+ M_ARCH=-m64
+ fi
+ export M_ARCH
+elif [ "$defaultOSArch" = "s390" ]; then
+ M_ARCH=-m31
+ export M_ARCH
+elif [ "$defaultOSArch" = "ia64" ]; then
+ M_ARCH=-mlp64
+ export M_ARCH
+fi
+
+LIBRARY_DIR="$EXEC_DIR/../org.eclipse.equinox.launcher.$defaultWS.$defaultOS.$defaultOSArch"
+OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+
+export OUTPUT_DIR PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS DEFAULT_JAVA LIBRARY_DIR
+
+# If the OS is supported (a makefile exists)
+if [ "$makefile" != "" ]; then
+ if [ "$extraArgs" != "" ]; then
+ make -f $makefile $extraArgs
+ else
+ echo "Building $OS launcher. Defaults: -os $DEFAULT_OS -arch $DEFAULT_OS_ARCH -ws $DEFAULT_WS"
+ make -f $makefile clean
+ case x$CC in
+ x*gcc*) make -f $makefile all PICFLAG=-fpic ;;
+ *) make -f $makefile all ;;
+ esac
+ fi
+else
+ echo "Unknown OS $OS -- build aborted"
+fi
+
+#restore original JAVA_HOME
+JAVA_HOME="$origJavaHome"
+export JAVA_HOME
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/build.xml b/features/org.eclipse.equinox.executable.feature/library/gtk/build.xml
new file mode 100644
index 000000000..f485479d3
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/build.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="build_eclipse" basedir=".">
+
+<target name="build_eclipse">
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="install"/>
+ </exec>
+</target>
+
+<target name="build_eclipse_ppc">
+ <exec dir="." executable="sh">
+ <env key="MODEL" value="ppc"/>
+ <arg line="${basedir}/build.sh"/>
+ <arg line="install"/>
+ </exec>
+</target>
+
+<target name="clean">
+ <tstamp/>
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="clean"/>
+ </exec>
+</target>
+
+</project> \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c
new file mode 100644
index 000000000..6ec48e79f
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ * Tom Tromey (Red Hat, Inc.)
+ *******************************************************************************/
+
+#include "eclipseMozilla.h"
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include "eclipseGtk.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#ifdef SOLARIS
+#include <sys/filio.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <semaphore.h>
+#include <fcntl.h>
+
+#ifdef HPUX
+#define SEM_FAILED (void *)-1
+#endif
+
+/* Global Variables */
+char* defaultVM = "java";
+char* vmLibrary = "libjvm.so";
+char* shippedVMDir = "jre/bin/";
+
+/* Define the special arguments for the various Java VMs. */
+static char* argVM_JAVA[] = { NULL };
+
+/* Define local variables . */
+static long splashHandle = 0;
+static GtkWidget* shellHandle = 0;
+
+static sem_t* mutex;
+static Atom appWindowAtom, launcherWindowAtom;
+static _TCHAR** openFilePath = NULL; /* the files we want to open */
+static int openFileTimeout = 60; /* number of seconds to wait before timeout */
+static int windowPropertySet = 0; /* set to 1 on success */
+
+static struct sigaction quitAction;
+static struct sigaction intAction;
+
+/* Local functions */
+static void catch_signal(int sig) {
+ //catch signals, free the lock, reinstall the original
+ //signal handlers and reraise the signal.
+ sem_post(mutex);
+ sem_close(mutex);
+ sigaction(SIGINT, &intAction, NULL);
+ sigaction(SIGQUIT, &intAction, NULL);
+ raise(sig);
+}
+
+typedef int (*LockFunc)();
+int executeWithLock(char *name, LockFunc func) {
+ int result = -1;
+ int lock = -1;
+ struct sigaction action;
+
+ mutex = sem_open(name, O_CREAT | O_EXCL, S_IRWXU | S_IRWXG | S_IRWXO, 1);
+ if (mutex == SEM_FAILED) {
+ //create failed. Probably lock is already created so try opening the existing lock.
+ mutex = sem_open(name, 0);
+ }
+ if (mutex == SEM_FAILED)
+ return -1; //this is an error.
+
+ // install signal handler to free the lock if something bad happens.
+ // sem_t is not freed automatically when a process ends.
+ action.sa_handler = catch_signal;
+ sigaction(SIGINT, &action, &intAction);
+ sigaction(SIGQUIT, &action, &quitAction);
+
+ while ((lock = sem_trywait(mutex)) != 0) {
+ if (errno == EAGAIN) {
+ //couldn't acquire lock, sleep a bit and try again
+ sleep(1);
+ if (--openFileTimeout > 0)
+ continue;
+ }
+ break;
+ }
+
+ if (lock == 0)
+ result = func();
+
+ sem_post(mutex);
+ sem_close(mutex);
+
+ //reinstall the original signal handlers
+ sigaction(SIGINT, &intAction, NULL);
+ sigaction(SIGQUIT, &quitAction, NULL);
+ return result;
+}
+
+/* Create a "SWT_Window_" + APP_NAME string with optional suffix.
+ * Caller should free the memory when finished */
+static char * createSWTWindowString(char * suffix, int semaphore) {
+#ifdef SOLARIS
+ /* solaris requires semaphore names to start with '/' */
+ char * prefix = semaphore != 0 ? _T_ECLIPSE("/SWT_Window_") : _T_ECLIPSE("SWT_Window_");
+#else
+ char * prefix = _T_ECLIPSE("SWT_Window_");
+#endif
+
+ char * result = malloc((_tcslen(prefix) + _tcslen(getOfficialName()) + (suffix != NULL ? _tcslen(suffix) : 0) + 1) * sizeof(char));
+ if (suffix != NULL)
+ _stprintf(result, _T_ECLIPSE("%s%s%s"), prefix, getOfficialName(), suffix);
+ else
+ _stprintf(result, _T_ECLIPSE("%s%s"), prefix, getOfficialName());
+ return result;
+}
+
+static int setAppWindowPropertyFn() {
+ Window appWindow;
+ Atom propAtom;
+ _TCHAR *propVal;
+
+ //Look for the SWT window. If it's there, set a property on it.
+ appWindow = gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, appWindowAtom);
+ if (appWindow) {
+ propAtom = gtk.XInternAtom(gtk_GDK_DISPLAY, "org.eclipse.swt.filePath.message", FALSE);
+ //append a colon delimiter in case more than one file gets appended to the app windows property.
+ propVal = concatPaths(openFilePath, _T_ECLIPSE(':'));
+ gtk.XChangeProperty(gtk_GDK_DISPLAY, appWindow, propAtom, propAtom, 8, PropModeAppend, (unsigned char *)propVal, _tcslen(propVal));
+ free(propVal);
+ windowPropertySet = 1;
+ return 1;
+ }
+ return 0;
+}
+
+/* set the Application window property by executing _setWindowPropertyFn within a semaphore */
+int setAppWindowProperty() {
+ int result;
+ char * mutexName = createSWTWindowString(NULL, 1);
+ result = executeWithLock(mutexName, setAppWindowPropertyFn);
+ gtk.XSync(gtk_GDK_DISPLAY, False);
+ free(mutexName);
+ return result;
+}
+
+/* timer callback function to call setAppWindowProperty */
+static gboolean setAppWindowTimerProc(gpointer data) {
+ //try to set the app window property. If unsuccessful return true to reschedule the timer.
+ openFileTimeout--;
+ return !setAppWindowProperty() && openFileTimeout > 0;
+}
+
+int createLauncherWindow() {
+ Window window, launcherWindow;
+ //check if a launcher window exists. If none exists, we know we are the first and we should be launching the app.
+ window = gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, launcherWindowAtom);
+ if (window == 0) {
+ //create a launcher window that other processes can find.
+ launcherWindow = gtk.XCreateWindow(gtk_GDK_DISPLAY, gtk.XRootWindow(gtk_GDK_DISPLAY, gtk.XDefaultScreen(gtk_GDK_DISPLAY)), -10, -10, 1,
+ 1, 0, 0, InputOnly, CopyFromParent, (unsigned long) 0, (XSetWindowAttributes *) NULL);
+ //for some reason Set and Get are both necessary. Set alone does nothing.
+ gtk.XSetSelectionOwner(gtk_GDK_DISPLAY, launcherWindowAtom, launcherWindow, CurrentTime);
+ gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, launcherWindowAtom);
+ //add a timeout to set the property on the apps window once the app is launched.
+ gtk.g_timeout_add(1000, setAppWindowTimerProc, 0);
+ return 0;
+ }
+ return 1;
+}
+
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
+ char *appName, *launcherName;
+ int result = 0;
+
+ if (initWindowSystem(&initialArgc, initialArgv, 1) != 0)
+ return -1;
+
+ openFileTimeout = timeout;
+ openFilePath = filePath;
+
+ //App name is defined in SWT as well. Values must be consistent.
+ appName = createSWTWindowString(NULL, 0);
+ appWindowAtom = gtk.XInternAtom(gtk_GDK_DISPLAY, appName, FALSE);
+ free(appName);
+
+ //check if app is already running. Just set property if it is.
+ if (setAppWindowProperty() > 0)
+ return 1;
+
+ /* app is not running, create a launcher window to act as a mutex so we don't need to keep the semaphore locked */
+ launcherName = createSWTWindowString(_T_ECLIPSE("_Launcher"), 1);
+ launcherWindowAtom = gtk.XInternAtom(gtk_GDK_DISPLAY, launcherName, FALSE);
+ result = executeWithLock(launcherName, createLauncherWindow);
+ free(launcherName);
+
+ if (result == 1) {
+ //The app is already being launched in another process. Set the property on that app window and exit
+ while (openFileTimeout > 0) {
+ if (setAppWindowProperty() > 0)
+ return 1; //success
+ else {
+ openFileTimeout--;
+ sleep(1);
+ }
+ }
+ //timed out trying to set the app property
+ result = 0;
+ }
+ return result;
+}
+
+/* Create and Display the Splash Window */
+int showSplash( const char* featureImage )
+{
+ GtkWidget *image;
+ GdkPixbuf *pixbuf;
+
+ if (splashHandle != 0)
+ return 0; /* already showing splash */
+ if (featureImage == NULL)
+ return -1;
+
+ if (initialArgv == NULL)
+ initialArgc = 0;
+
+ if( initWindowSystem(&initialArgc, initialArgv, 1) != 0)
+ return -1;
+
+ shellHandle = gtk.gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk.gtk_window_set_decorated((GtkWindow*)(shellHandle), FALSE);
+ gtk.g_signal_connect_data((gpointer)shellHandle, "destroy", (GtkSignalFunc)(gtk.gtk_widget_destroyed), &shellHandle, NULL, 0);
+
+ pixbuf = gtk.gdk_pixbuf_new_from_file(featureImage, NULL);
+ image = gtk.gtk_image_new_from_pixbuf(pixbuf);
+ if (pixbuf) {
+ gtk.g_object_unref(pixbuf);
+ }
+ gtk.gtk_container_add((GtkContainer*)(shellHandle), image);
+
+ if (getOfficialName() != NULL)
+ gtk.gtk_window_set_title((GtkWindow*)(shellHandle), getOfficialName());
+ gtk.gtk_window_set_position((GtkWindow*)(shellHandle), GTK_WIN_POS_CENTER);
+ gtk.gtk_window_resize((GtkWindow*)(shellHandle), gtk.gdk_pixbuf_get_width(pixbuf), gtk.gdk_pixbuf_get_height(pixbuf));
+ gtk.gtk_widget_show_all((GtkWidget*)(shellHandle));
+ splashHandle = (long)shellHandle;
+ dispatchMessages();
+ return 0;
+}
+
+void dispatchMessages() {
+ if (gtk.g_main_context_iteration != 0)
+ while(gtk.g_main_context_iteration(0,0) != 0) {}
+}
+
+jlong getSplashHandle() {
+ return splashHandle;
+}
+
+void takeDownSplash() {
+ if(shellHandle != 0) {
+ gtk.gtk_widget_destroy(shellHandle);
+ dispatchMessages();
+ splashHandle = 0;
+ shellHandle = NULL;
+ }
+}
+
+/* Get the window system specific VM arguments */
+char** getArgVM( char* vm )
+{
+ char** result;
+
+/* if (isJ9VM( vm ))
+ return argVM_J9;*/
+
+ /* Use the default arguments for a standard Java VM */
+ result = argVM_JAVA;
+ return result;
+}
+
+JavaResults* launchJavaVM( char* args[] )
+{
+ JavaResults* jvmResults = NULL;
+ pid_t jvmProcess, finishedProcess = 0;
+ int exitCode;
+
+#ifdef MOZILLA_FIX
+ fixEnvForMozilla();
+#endif /* MOZILLA_FIX */
+
+ jvmProcess = fork();
+ if (jvmProcess == 0)
+ {
+ /* Child process ... start the JVM */
+ execv(args[0], args);
+
+ /* The JVM would not start ... return error code to parent process. */
+ /* TODO, how to distinguish this as a launch problem to the other process? */
+ _exit(errno);
+ }
+
+ jvmResults = malloc(sizeof(JavaResults));
+ memset(jvmResults, 0, sizeof(JavaResults));
+
+ /* If the JVM is still running, wait for it to terminate. */
+ if (jvmProcess != 0)
+ {
+ /* When attempting a file open, we need to spin the event loop
+ * for setAppWindowTimerProc to run. When that succeeds or times out,
+ * we can stop the event loop and just wait on the child process.
+ */
+ if (openFilePath != NULL) {
+ struct timespec sleepTime;
+ sleepTime.tv_sec = 0;
+ sleepTime.tv_nsec = 5e+8; // 500 milliseconds
+
+ while(openFileTimeout > 0 && !windowPropertySet && (finishedProcess = waitpid(jvmProcess, &exitCode, WNOHANG)) == 0) {
+ dispatchMessages();
+ nanosleep(&sleepTime, NULL);
+ }
+ }
+ if (finishedProcess == 0)
+ waitpid(jvmProcess, &exitCode, 0);
+ if (WIFEXITED(exitCode))
+ /* TODO, this should really be a runResult if we could distinguish the launch problem above */
+ jvmResults->launchResult = WEXITSTATUS(exitCode);
+ }
+
+ return jvmResults;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h
new file mode 100644
index 000000000..503c9a5f9
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+#ifndef ECLIPSE_GTK_H
+#define ECLIPSE_GTK_H
+
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdkx.h>
+
+struct GTK_PTRS {
+ short not_initialized;
+ void (*gtk_container_add) (GtkContainer*, GtkWidget*);
+ gint (*gtk_dialog_run) (GtkDialog *);
+ GtkWidget* (*gtk_image_new_from_pixbuf)(GdkPixbuf*);
+ gboolean (*gtk_init_check) (int*, char***);
+ gboolean (*gtk_init_with_args) (int*, char***, const char *, void *, const char *, GError **);
+ GtkWidget* (*gtk_message_dialog_new) (GtkWindow*, GtkDialogFlags, GtkMessageType, GtkButtonsType, const gchar*, ...);
+ gchar* (*gtk_set_locale) ();
+ void (*gtk_widget_destroy) (GtkWidget*);
+ void (*gtk_widget_destroyed) (GtkWidget*, GtkWidget**);
+ void (*gtk_widget_show_all) (GtkWidget*);
+ GtkWidget* (*gtk_window_new) (GtkWindowType);
+ void (*gtk_window_resize) (GtkWindow*, gint, gint);
+ void (*gtk_window_set_title) (GtkWindow*, const gchar*);
+ void (*gtk_window_set_decorated) (GtkWindow*, gboolean);
+ void (*gtk_window_set_position) (GtkWindow*, GtkWindowPosition);
+
+ gulong (*g_signal_connect_data) (gpointer, const gchar*, GCallback, gpointer, GClosureNotify, GConnectFlags);
+ gboolean (*g_main_context_iteration) (GMainContext*, gboolean);
+ void (*g_object_unref) (gpointer);
+ GObject* (*g_object_new) (GType, const gchar*, ...);
+ guint (*g_timeout_add) (guint, GSourceFunc, gpointer);
+ void (*g_error_free) (GError *);
+
+#ifdef SOLARIS
+ GString* (*g_string_insert_c) (GString *, gssize, gchar);
+#endif
+
+ GdkDisplay* (*gdk_display_get_default) ();
+ Display* (*gdk_x11_display_get_xdisplay) (GdkDisplay*);
+ GdkPixbuf* (*gdk_pixbuf_new_from_file) (const char*, GError **);
+ int (*gdk_pixbuf_get_width) (const GdkPixbuf*);
+ int (*gdk_pixbuf_get_height) (const GdkPixbuf*);
+ void (*gdk_set_program_class) (const char*);
+
+ Window (*XGetSelectionOwner) (Display*, Atom);
+ void (*XSetSelectionOwner) (Display*, Atom, Window, Time);
+ void (*XChangeProperty) (Display*, Window, Atom, Atom, int, int, unsigned char *, int);
+ Window (*XCreateWindow) (Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*);
+ void (*XSync) (Display*, Bool);
+ int (*XDefaultScreen) (Display*);
+ Window (*XRootWindow) (Display*, int);
+ Atom (*XInternAtom) (Display*, _Xconst char*, Bool );
+};
+
+#define gtk_GDK_DISPLAY gtk.gdk_x11_display_get_xdisplay(gtk.gdk_display_get_default())
+extern struct GTK_PTRS gtk;
+
+#define FN_TABLE_ENTRY(fn, required) { (void**)& gtk.fn, #fn, required }
+typedef struct {
+ void ** fnPtr;
+ char * fnName;
+ int required;
+} FN_TABLE;
+
+/* load the gtk libraries and initialize the function pointers */
+extern int loadGtk();
+
+#endif
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkCommon.c b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkCommon.c
new file mode 100644
index 000000000..b30327ec5
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkCommon.c
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+#include "eclipseGtk.h"
+
+#include <locale.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+#define ECLIPSE_ICON 401
+
+char dirSeparator = '/';
+char pathSeparator = ':';
+
+/* Define local variables for the main window. */
+static int saveArgc = 0; /* arguments after they were parsed, for window system */
+static char** saveArgv = 0;
+
+gboolean gtkInitialized = FALSE;
+
+#ifdef SOLARIS
+/* a call to this function appears inline in glib/gstring.h on Solaris,
+ so provide a definition here and hook it up
+ */
+GString* g_string_insert_c (GString *string, gssize pos, gchar c) {
+ /* see bug 264615, we can get here without having initialized the gtk pointers */
+ if (gtk.not_initialized)
+ loadGtk();
+ return gtk.g_string_insert_c(string, pos, c);
+}
+#endif
+
+/* Display a Message */
+void displayMessage(char* title, char* message)
+{
+ GtkWidget* dialog;
+
+ /* If GTK has not been initialized yet, do it now. */
+ if (initWindowSystem( &saveArgc, saveArgv, 1 ) != 0) {
+ printf("%s:\n%s\n", title, message);
+ return;
+ }
+
+ dialog = gtk.gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ "%s", message);
+ gtk.gtk_window_set_title((GtkWindow*)dialog, title);
+ gtk.gtk_dialog_run((GtkDialog*)dialog);
+ gtk.gtk_widget_destroy(dialog);
+}
+
+/* Initialize the Window System */
+int initWindowSystem(int* pArgc, char* argv[], int showSplash)
+{
+ int defaultArgc = 1;
+ char * defaultArgv [] = { "", 0 };
+
+ if(gtkInitialized)
+ return 0;
+
+ /* load the GTK libraries and initialize function pointers */
+ if (loadGtk() != 0)
+ return -1;
+
+ if (getOfficialName() != NULL)
+ defaultArgv[0] = getOfficialName();
+
+ if (argv == NULL) {
+ /* gtk_init_check on Solaris 9 doesn't like NULL or empty argv */
+ pArgc = &defaultArgc;
+ argv = defaultArgv;
+ }
+
+ /* Save the arguments in case displayMessage() is called in the main launcher. */
+ if (saveArgv == 0)
+ {
+ saveArgc = *pArgc;
+ saveArgv = argv;
+ }
+
+ /* Initialize GTK. */
+ if (gtk.gtk_set_locale) gtk.gtk_set_locale();
+ if (gtk.gtk_init_with_args) {
+ GError *error = NULL;
+ if (!gtk.gtk_init_with_args(pArgc, &argv, NULL, NULL, NULL, &error)) {
+ if (error) {
+ fprintf(stderr, "%s: %s\n", getOfficialName(), error->message);
+ if (gtk.g_error_free) gtk.g_error_free(error);
+ }
+ return -1;
+ }
+ } else {
+ if (!gtk.gtk_init_check(pArgc, &argv)) {
+ return -1;
+ }
+ }
+
+ /*_gdk_set_program_class(getOfficialName());*/
+ gtkInitialized = TRUE;
+ return 0;
+}
+
+/* Load the specified shared library
+ */
+void * loadLibrary( char * library ){
+ void * result= dlopen(library, RTLD_LAZY);
+ if(result == 0)
+ printf("%s\n",dlerror());
+ return result;
+}
+
+/* Unload the shared library
+ */
+void unloadLibrary( void * handle ){
+ dlclose(handle);
+}
+
+/* Find the given symbol in the shared library
+ */
+void * findSymbol( void * handle, char * symbol ){
+ return dlsym(handle, symbol);
+}
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c
new file mode 100644
index 000000000..51ed70a9f
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "eclipseGtk.h"
+#include "eclipseCommon.h"
+#include <dlfcn.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct GTK_PTRS gtk = { 1 }; /* initialize the first field "not_initialized" so we can tell when we've loaded the pointers */
+
+/* tables to help initialize the function pointers */
+/* functions from libgtk-x11-2.0 or libgtk-3.so.0*/
+static FN_TABLE gtkFunctions[] = {
+ FN_TABLE_ENTRY(gtk_container_add, 1),
+ FN_TABLE_ENTRY(gtk_dialog_run, 1),
+ FN_TABLE_ENTRY(gtk_image_new_from_pixbuf, 1),
+ FN_TABLE_ENTRY(gtk_init_check, 1),
+ FN_TABLE_ENTRY(gtk_init_with_args, 0),
+ FN_TABLE_ENTRY(gtk_message_dialog_new, 1),
+ FN_TABLE_ENTRY(gtk_set_locale, 0),
+ FN_TABLE_ENTRY(gtk_widget_destroy, 1),
+ FN_TABLE_ENTRY(gtk_widget_destroyed, 1),
+ FN_TABLE_ENTRY(gtk_widget_show_all, 1),
+ FN_TABLE_ENTRY(gtk_window_new, 1),
+ FN_TABLE_ENTRY(gtk_window_resize, 1),
+ FN_TABLE_ENTRY(gtk_window_set_title, 1),
+ FN_TABLE_ENTRY(gtk_window_set_decorated, 1),
+ FN_TABLE_ENTRY(gtk_window_set_position, 1),
+ { NULL, NULL }
+};
+/* functions from libgdk-x11-2.0 or libgdk-3.so.0*/
+static FN_TABLE gdkFunctions[] = {
+ FN_TABLE_ENTRY(gdk_set_program_class, 1),
+ FN_TABLE_ENTRY(gdk_display_get_default, 1),
+ FN_TABLE_ENTRY(gdk_x11_display_get_xdisplay, 1),
+ { NULL, NULL }
+};
+/* functions from libgdk_pixbuf-2.0 */
+static FN_TABLE pixFunctions[] = {
+ FN_TABLE_ENTRY(gdk_pixbuf_new_from_file, 1),
+ FN_TABLE_ENTRY(gdk_pixbuf_get_width, 1),
+ FN_TABLE_ENTRY(gdk_pixbuf_get_height, 1),
+ { NULL, NULL }
+};
+/* functions from libgobject-2.0 */
+static FN_TABLE gobjFunctions[] = {
+ FN_TABLE_ENTRY(g_signal_connect_data, 1),
+ FN_TABLE_ENTRY(g_main_context_iteration, 1),
+ FN_TABLE_ENTRY(g_object_unref, 1),
+ FN_TABLE_ENTRY(g_timeout_add, 1),
+ FN_TABLE_ENTRY(g_error_free, 1),
+#ifdef SOLARIS
+ FN_TABLE_ENTRY(g_string_insert_c, 1),
+#endif
+ { NULL, NULL }
+};
+
+/* functions from libX11 */
+static FN_TABLE x11Functions[] = {
+ FN_TABLE_ENTRY(XGetSelectionOwner, 1),
+ FN_TABLE_ENTRY(XSetSelectionOwner, 1),
+ FN_TABLE_ENTRY(XCreateWindow, 1),
+ FN_TABLE_ENTRY(XChangeProperty, 1),
+ FN_TABLE_ENTRY(XSync, 1),
+ FN_TABLE_ENTRY(XRootWindow, 1),
+ FN_TABLE_ENTRY(XDefaultScreen, 1),
+ FN_TABLE_ENTRY(XInternAtom, 1),
+ { NULL, NULL }
+};
+
+
+static int loadGtkSymbols( void * library, FN_TABLE * table) {
+ int i = 0;
+ void * fn;
+ for (i = 0; table[i].fnName != NULL; i++) {
+ fn = findSymbol(library, table[i].fnName);
+ if (fn != 0) {
+ *(table[i].fnPtr) = fn;
+ } else {
+ if (table[i].required) return -1;
+ }
+ }
+ return 0;
+}
+
+int loadGtk() {
+#ifdef AIX
+#define DLFLAGS RTLD_LAZY | RTLD_MEMBER
+#else
+#define DLFLAGS RTLD_LAZY
+#endif
+
+ void *gdkLib = NULL, *gtkLib = NULL, *objLib = NULL, *pixLib = NULL, *x11Lib = NULL;
+
+ if (getenv("SWT_GTK3")) {
+ gdkLib = dlopen(GDK3_LIB, DLFLAGS);
+ gtkLib = dlopen(GTK3_LIB, DLFLAGS);
+ }
+ if (!gtkLib || !gdkLib) {
+ gdkLib = dlopen(GDK_LIB, DLFLAGS);
+ gtkLib = dlopen(GTK_LIB, DLFLAGS);
+ }
+ objLib = dlopen(GOBJ_LIB, DLFLAGS);
+ pixLib = dlopen(PIXBUF_LIB, DLFLAGS);
+ x11Lib = dlopen(X11_LIB, DLFLAGS);
+
+ /* initialize ptr struct to 0's */
+ memset(&gtk, 0, sizeof(struct GTK_PTRS));
+
+ if ( gtkLib == NULL || loadGtkSymbols(gtkLib, gtkFunctions) != 0) return -1;
+ if ( gdkLib == NULL || loadGtkSymbols(gdkLib, gdkFunctions) != 0) return -1;
+ if ( pixLib == NULL || loadGtkSymbols(pixLib, pixFunctions) != 0) return -1;
+ if ( objLib == NULL || loadGtkSymbols(objLib, gobjFunctions) != 0) return -1;
+ if ( x11Lib == NULL || loadGtkSymbols(x11Lib, x11Functions) != 0) return -1;
+
+ return 0;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/make_aix.mak b/features/org.eclipse.equinox.executable.feature/library/gtk/make_aix.mak
new file mode 100644
index 000000000..2d3a71d9b
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/make_aix.mak
@@ -0,0 +1,116 @@
+#*******************************************************************************
+# Copyright (c) 2010, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Tom Tromey (Red Hat, Inc.)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the GTK eclipse launcher program.
+#
+# This makefile expects the utility "pkg-config" to be in the PATH.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - JAVA_HOME for jni headers
+#default value for PROGRAM_OUTPUT
+
+PROGRAM_OUTPUT=eclipse
+PROGRAM_LIBRARY=$(PROGRAM_OUTPUT)_$(LIB_VERSION).so
+
+
+# Define the object modules to be compiled and flags.
+CC=gcc
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseGtkCommon.o eclipseGtkInit.o
+DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o eclipseMozilla.o eclipseShm.o eclipseNix.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+#LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lpthread -ldl -lX11
+LIBS = -lpthread -ldl
+
+X11_LIB_ppc = shr4.o
+X11_LIB_ppc64 = shr_64.o
+X11_LIB = -DX11_LIB="\"libX11.a($(X11_LIB_$(DEFAULT_OS_ARCH)))\""
+GTK_LIBS = -DGTK_LIB="\"libgtk-x11-2.0.a(libgtk-x11-2.0.so.0)\"" \
+ -DGDK_LIB="\"libgdk-x11-2.0.a(libgdk-x11-2.0.so.0)\"" \
+ -DGTK3_LIB="\"libgtk-3.a(libgtk-3.so.0)\"" \
+ -DGDK3_LIB="\"libgdk-3.a(libgdk-3.so.0)\"" \
+ -DPIXBUF_LIB="\"libgdk_pixbuf-2.0.a(libgdk_pixbuf-2.0.so.0)\"" \
+ -DGOBJ_LIB="\"libgobject-2.0.a(libgobject-2.0.so.0)\"" \
+ $(X11_LIB)
+
+LFLAGS = ${M_ARCH} -shared
+CFLAGS = ${M_ARCH} -g -s -Wall\
+ -fpic \
+ -DAIX \
+ -DMOZILLA_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -D$(DEFAULT_JAVA) \
+ $(GTK_LIBS) \
+ -I. \
+ -I.. \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux \
+ `pkg-config --cflags gtk+-2.0`
+
+all: $(EXEC) $(DLL)
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o
+
+eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o eclipseMain.o
+
+eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c
+
+eclipseGtkCommon.o: ../eclipseCommon.h ../eclipseOS.h eclipseGtk.h eclipseGtkCommon.c
+ $(CC) $(CFLAGS) -c eclipseGtkCommon.c -o eclipseGtkCommon.o
+
+eclipseGtkInit.o: ../eclipseCommon.h eclipseGtk.h eclipseGtkInit.c
+ $(CC) $(CFLAGS) -c eclipseGtkInit.c -o eclipseGtkInit.o
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o eclipseJNI.o
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o eclipseConfig.o
+
+eclipseMozilla.o: ../eclipseMozilla.c ../eclipseMozilla.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseMozilla.c -o eclipseMozilla.o
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o eclipseShm.o
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o eclipseNix.o
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) ${M_ARCH} -Wl,-bM:UR -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+ sedmgr -c exempt $(EXEC)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/make_hpux.mak b/features/org.eclipse.equinox.executable.feature/library/gtk/make_hpux.mak
new file mode 100644
index 000000000..d0227efc2
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/make_hpux.mak
@@ -0,0 +1,102 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Sumit Sarkar (Hewlett-Packard)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the HPUX/Motif eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# X11_HOME - the full path to X11 header files
+# MOTIF_HOME - the full path to Motif header files
+
+#ifeq ($(PROGRAM_OUTPUT),)
+# PROGRAM_OUTPUT=eclipse
+#endif
+
+DEFAULT_JAVA=DEFAULT_JAVA_EXEC
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+CC=gcc
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseGtkCommon.o eclipseGtkInit.o
+DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o eclipseShm.o eclipseNix.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lpthread -lrt
+GTK_LIBS = \
+ -DGTK_LIB="\"libgtk-x11-2.0.so\"" -DGDK_LIB="\"libgdk-x11-2.0.so\"" \
+ -DGTK3_LIB="\"libgtk-3.so\"" -DGDK3_LIB="\"libgdk-3.so\"" \
+ -DPIXBUF_LIB="\"libgdk_pixbuf-2.0.so\"" \
+ -DGOBJ_LIB="\"libgobject-2.0.so\"" -DX11_LIB="\"libX11.so\""
+LFLAGS = ${M_ARCH} -shared -static-libgcc
+# -Wl,--export-dynamic
+CFLAGS = ${M_ARCH} -O -s \
+ -DNETSCAPE_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -D$(DEFAULT_JAVA) \
+ -DHPUX \
+ $(GTK_LIBS) \
+ -I./ \
+ -I../ \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/hp-ux \
+ `pkg-config --cflags gtk+-2.0`
+
+all: $(EXEC) $(DLL)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o $@
+
+eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) ${M_ARCH} -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak b/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak
new file mode 100644
index 000000000..6abe01702
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak
@@ -0,0 +1,112 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Tom Tromey (Red Hat, Inc.)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the GTK eclipse launcher program.
+#
+# This makefile expects the utility "pkg-config" to be in the PATH.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - JAVA_HOME for jni headers
+#default value for PROGRAM_OUTPUT
+ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+endif
+
+PROGRAM_LIBRARY=$(PROGRAM_OUTPUT)_$(LIB_VERSION).so
+
+ifeq ($(DEFAULT_JAVA),)
+ DEFAULT_JAVA=DEFAULT_JAVA_JNI
+endif
+
+# Define the object modules to be compiled and flags.
+CC?=gcc
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseGtkCommon.o eclipseGtkInit.o
+DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o eclipseMozilla.o eclipseShm.o eclipseNix.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+#LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lpthread -ldl -lX11
+LIBS = -lpthread -ldl
+GTK_LIBS = \
+ -DGTK_LIB="\"libgtk-x11-2.0.so.0\"" -DGDK_LIB="\"libgdk-x11-2.0.so.0\"" \
+ -DGTK3_LIB="\"libgtk-3.so.0\"" -DGDK3_LIB="\"libgdk-3.so.0\"" \
+ -DPIXBUF_LIB="\"libgdk_pixbuf-2.0.so.0\"" -DGOBJ_LIB="\"libgobject-2.0.so.0\"" -DX11_LIB="\"libX11.so.6\""
+LFLAGS = ${M_ARCH} -shared -fpic -Wl,--export-dynamic
+CFLAGS = ${M_ARCH} -g -s -Wall\
+ -fpic \
+ -DLINUX \
+ -DMOZILLA_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -D$(DEFAULT_JAVA) \
+ $(GTK_LIBS) \
+ -I. \
+ -I.. \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux \
+ `pkg-config --cflags gtk+-2.0`
+
+all: $(EXEC) $(DLL)
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o
+
+eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o eclipseMain.o
+
+eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c
+
+eclipseGtkCommon.o: ../eclipseCommon.h ../eclipseOS.h eclipseGtk.h eclipseGtkCommon.c
+ $(CC) $(CFLAGS) -c eclipseGtkCommon.c -o eclipseGtkCommon.o
+
+eclipseGtkInit.o: ../eclipseCommon.h eclipseGtk.h eclipseGtkInit.c
+ $(CC) $(CFLAGS) -c eclipseGtkInit.c -o eclipseGtkInit.o
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o eclipseJNI.o
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o eclipseConfig.o
+
+eclipseMozilla.o: ../eclipseMozilla.c ../eclipseMozilla.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseMozilla.c -o eclipseMozilla.o
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o eclipseShm.o
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o eclipseNix.o
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) ${M_ARCH} -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/make_solaris.mak b/features/org.eclipse.equinox.executable.feature/library/gtk/make_solaris.mak
new file mode 100644
index 000000000..945becf9e
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/gtk/make_solaris.mak
@@ -0,0 +1,111 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Tom Tromey (Red Hat, Inc.)
+# Martin Oberhuber (Wind River) - [176805] Support building with gcc and debug
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the GTK eclipse launcher program.
+#
+# This makefile expects the utility "pkg-config" to be in the PATH.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - JAVA_HOME for JNI headers
+
+#ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+#endif
+
+PROGRAM_LIBRARY=$(PROGRAM_OUTPUT)_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseGtkCommon.o eclipseGtkInit.o
+DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o eclipseMozilla.o eclipseShm.o eclipseNix.o
+PICFLAG = -K PIC
+# Optimize and remove all debugging information by default
+OPTFLAG = -O -s
+# OPTFLAG = -g
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+#LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lglib-2.0 -lthread -ldl -lc
+LIBS = -lthread -ldl -lc -lrt
+GTK_LIBS = \
+ -DGTK_LIB="\"libgtk-x11-2.0.so.0\"" -DGDK_LIB="\"libgdk-x11-2.0.so.0\"" \
+ -DGTK3_LIB="\"libgtk-3.so.0\"" -DGDK3_LIB="\"libgdk-3.so.0\"" \
+ -DPIXBUF_LIB="\"libgdk_pixbuf-2.0.so.0\"" -DGOBJ_LIB="\"libgobject-2.0.so.0\"" -DX11_LIB="\"libX11.so.4\""
+LFLAGS = -G
+CFLAGS = $(OPTFLAG) \
+ -DSOLARIS \
+ $(PICFLAG) \
+ -DMOZILLA_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ $(GTK_LIBS) \
+ -I. \
+ -I.. \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/solaris \
+ `pkg-config --cflags gtk+-2.0`
+
+all: $(EXEC) $(DLL)
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o
+
+eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o eclipseMain.o
+
+eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c
+
+eclipseGtkCommon.o: ../eclipseCommon.h ../eclipseOS.h eclipseGtk.h eclipseGtkCommon.c
+ $(CC) $(CFLAGS) -c eclipseGtkCommon.c -o eclipseGtkCommon.o
+
+eclipseGtkInit.o: ../eclipseCommon.h eclipseGtk.h eclipseGtkInit.c
+ $(CC) $(CFLAGS) -c eclipseGtkInit.c -o eclipseGtkInit.o
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o eclipseJNI.o
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o eclipseConfig.o
+
+eclipseMozilla.o: ../eclipseMozilla.c ../eclipseMozilla.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseMozilla.c -o eclipseMozilla.o
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o eclipseShm.o
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o eclipseNix.o
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/make_version.mak b/features/org.eclipse.equinox.executable.feature/library/make_version.mak
new file mode 100644
index 000000000..41c9b799c
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/make_version.mak
@@ -0,0 +1,14 @@
+#*******************************************************************************
+# Copyright (c) 2006, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+#*******************************************************************************
+
+maj_ver=1
+min_ver=505
+LIB_VERSION = $(maj_ver)$(min_ver)
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/.cvsignore b/features/org.eclipse.equinox.executable.feature/library/motif/.cvsignore
new file mode 100644
index 000000000..e64b3dbf5
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/.cvsignore
@@ -0,0 +1,4 @@
+*.o
+eclipse
+eclipse_*.so
+libeclipse-motif.so
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.c b/features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.c
new file mode 100644
index 000000000..2f4e525b0
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.c
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "NgCommon.h"
+
+/* Non-zero = big-endian architecture */
+static BYTE4 hostIsMSB = 0;
+
+/* Store last error msg */
+#define MAX_MSG_SIZE 100
+char errorMsg[MAX_MSG_SIZE];
+
+/* Library initialization */
+void NgInit()
+{
+ BYTE4 result = (BYTE4) 'A';
+
+ /* determine the byte ordering of the host machine */
+ hostIsMSB = (BYTE4) (*((char *) &result) != 'A');
+
+ errorMsg[0] = 0;
+}
+
+/**
+ * Memory allocation routine
+ */
+void *NgMalloc (UBYTE4 size)
+{
+ return malloc (size);
+}
+
+/**
+ * Memory allocation routine
+ */
+void NgFree (void *memblock)
+{
+ if (memblock != NULL)
+ free (memblock);
+}
+
+void NgMemSet (void *dest, UBYTE1 c, BYTE4 count)
+{
+ memset (dest, c, count);
+}
+
+void NgMemCpy (void *dest, void *src, BYTE4 count)
+{
+ memcpy (dest, src, count);
+}
+
+/**
+ * Error Reporting
+ */
+
+ng_err_t NgError (ng_err_t error_type, char* msg) {
+ if (msg != NULL)
+ {
+ /* Store a copy of the last error msg - truncate if necessary */
+ size_t size = strlen (msg);
+ if (size >= MAX_MSG_SIZE) size = MAX_MSG_SIZE - 1;
+ NgMemCpy (errorMsg, msg, size);
+ errorMsg[size] = 0;
+ }
+ return error_type;
+}
+
+const char *NgGetLastErrorMsg()
+{
+ return errorMsg;
+}
+
+/**
+ * Stream manipulation routines
+ */
+ng_err_t NgStreamInit (ng_stream_t *stream, char *fullname)
+{
+ stream->file = fopen (fullname, "rb");
+ stream->size = 0;
+ stream->pos = 0;
+ if (stream->file == NULL) return NgError (ERR_NG, "Can't open file");
+ return ERR_OK;
+}
+
+void NgStreamClose (ng_stream_t *stream)
+{
+ if (stream->file != NULL)
+ {
+ fclose (stream->file);
+ stream->file = NULL;
+ }
+ stream->size = -1;
+}
+
+char NgStreamEof (ng_stream_t *stream)
+{
+ return stream->size == -1;
+}
+
+BYTE4 NgStreamGetPosition (ng_stream_t *stream)
+{
+ return stream->pos;
+}
+
+BYTE4 NgStreamSkip (ng_stream_t *stream, BYTE4 nbr)
+{
+ if (stream->size == -1) return 0;
+ if (fseek (stream->file, nbr, SEEK_CUR))
+ {
+ NgStreamClose (stream);
+ return 0;
+ }
+ stream->pos += nbr;
+ return nbr;
+}
+
+BYTE4 NgStreamRead (ng_stream_t *stream, char *buffer, BYTE4 nbr)
+{
+ size_t cnt;
+ if (stream->size == -1) return 0;
+ cnt = fread (buffer, sizeof (char), nbr, stream->file);
+ if (cnt != nbr)
+ {
+ NgStreamClose (stream);
+ return 0;
+ }
+ stream->pos += nbr;
+ return nbr;
+}
+
+BYTE1 NgIsMSB()
+{
+ return hostIsMSB != 0;
+}
+
+UBYTE2 SystemToLittleEndianUBYTE2 (UBYTE2 value)
+{
+ return hostIsMSB ? ((value&0xFF) << 8)|((value&0xFF00)>>8) : value;
+}
+
+UBYTE4 SystemToLittleEndianUBYTE4 (UBYTE4 value)
+{
+ return hostIsMSB ? ((value&0xFF000000L)>>24)|((value&0xFF0000L)>>8) | ((value&0xFF00L)<<8) | ((value&0xFFL)<<24) : value;
+}
+
+UBYTE2 SystemToBigEndianUBYTE2 (UBYTE2 value)
+{
+ return hostIsMSB ? value : ((value&0xFF) << 8)|((value&0xFF00)>>8);
+}
+
+UBYTE2 LittleEndianToSystemUBYTE2 (UBYTE2 value)
+{
+ return hostIsMSB ? ((value&0xFF) << 8)|((value&0xFF00)>>8) : value;
+}
+
+UBYTE4 LittleEndianToSystemUBYTE4 (UBYTE4 value)
+{
+ return hostIsMSB ? ((value&0xFF000000L)>>24)|((value&0xFF0000L)>>8) | ((value&0xFF00L)<<8) | ((value&0xFFL)<<24) : value;
+}
+
+UBYTE2 BigEndianToSystemUBYTE2 (UBYTE2 value)
+{
+ return hostIsMSB ? value : ((value&0xFF) << 8)|((value&0xFF00)>>8);
+}
+
+UBYTE4 BigEndianToSystemUBYTE4 (UBYTE4 value)
+{
+ return hostIsMSB ? value : ((value&0xFF000000L)>>24)|((value&0xFF0000L)>>8)|((value&0xFF00L)<<8) | ((value&0xFFL)<<24);
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.h b/features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.h
new file mode 100644
index 000000000..31252d753
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgCommon.h
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef __NG_COMMON_H
+#define __NG_COMMON_H
+
+#include <memory.h>
+#include <stdio.h>
+
+typedef char BYTE1;
+typedef unsigned char UBYTE1;
+typedef short BYTE2;
+typedef unsigned short UBYTE2;
+typedef long BYTE4;
+typedef unsigned long UBYTE4;
+
+/* error reporting */
+#define ERR_OK 1
+#define ERR_SUBSCRIPT_OUT_OF_RANGE -1
+#define ERR_INVALID_BIT_COUNT -2
+#define ERR_NG -4
+
+typedef BYTE4 ng_err_t;
+ng_err_t NgError (ng_err_t error_type, char* msg);
+const char *NgGetLastErrorMsg();
+
+/**
+ * NgInit
+ * Must be called prior to using the image decoders
+ */
+void NgInit();
+
+/* memory management */
+void *NgMalloc (UBYTE4 size);
+void NgFree (void *memblock);
+void NgMemSet (void *dest, UBYTE1 c, BYTE4 count);
+void NgMemCpy (void *dest, void *src, BYTE4 count);
+
+/* stream api */
+typedef struct {
+ FILE *file;
+ BYTE4 size;
+ BYTE4 pos;
+} ng_stream_t;
+
+/**
+ * Init a stream given the path and name of a file
+ * Note. NgStreamClose should be called to release
+ * the related OS resource.
+ */
+ng_err_t NgStreamInit (ng_stream_t *stream, char *fullname);
+
+/**
+ * Close any OS resource managed the given stream.
+ * In particular, close the file if the stream is using one.
+ */
+void NgStreamClose (ng_stream_t *stream);
+
+char NgStreamEof (ng_stream_t *stream);
+
+BYTE4 NgStreamGetPosition (ng_stream_t *stream);
+/**
+ * Skips nbr bytes.
+ * Return nbr if all bytes were skipped.
+ * If nbr bytes can't be skipped, the stream is closed
+ * (NgStreamEof returns 1). 0 is returned.
+ */
+BYTE4 NgStreamSkip (ng_stream_t *stream, BYTE4 nbr);
+/**
+ * Copies nbr bytes to buffer from stream.
+ * Returns nbr if all bytes were copied.
+ * If nbr bytes can't be read, no bytes are copied. The stream
+ * is closed (NgStreamEof returns 1). 0 is returned.
+ */
+BYTE4 NgStreamRead (ng_stream_t *stream, char *buffer, BYTE4 nbr);
+
+/* little/big endian conversion */
+BYTE1 NgIsMSB();
+UBYTE2 SystemToLittleEndianUBYTE2 (UBYTE2);
+UBYTE4 SystemToLittleEndianUBYTE4 (UBYTE4);
+UBYTE2 SystemToBigEndianUBYTE2 (UBYTE2);
+UBYTE2 LittleEndianToSystemUBYTE2 (UBYTE2);
+UBYTE4 LittleEndianToSystemUBYTE4 (UBYTE4);
+UBYTE2 BigEndianToSystemUBYTE2 (UBYTE2);
+UBYTE4 BigEndianToSystemUBYTE4 (UBYTE4);
+
+#endif /* NG_COMMON_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgImage.c b/features/org.eclipse.equinox.executable.feature/library/motif/NgImage.c
new file mode 100644
index 000000000..056b09de3
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgImage.c
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "NgCommon.h"
+#include "NgImageData.h"
+#include "NgImage.h"
+#include "NgWinBMPFileFormat.h"
+#include <dlfcn.h>
+
+struct NG_PTRS ng;
+
+#define FN_TABLE_ENTRY(fn) { (void**)&ng.fn, #fn }
+typedef struct {
+ void ** fnPtr;
+ char * fnName;
+} FN_TABLE;
+static FN_TABLE x11Functions[] = { FN_TABLE_ENTRY(XCreateGC),
+ FN_TABLE_ENTRY(XCreateImage),
+ FN_TABLE_ENTRY(XCreatePixmap),
+ FN_TABLE_ENTRY(XDefaultColormap),
+ FN_TABLE_ENTRY(XDefaultDepthOfScreen),
+ FN_TABLE_ENTRY(XDefaultRootWindow),
+ FN_TABLE_ENTRY(XDefaultScreen),
+ FN_TABLE_ENTRY(XDefaultScreenOfDisplay),
+ FN_TABLE_ENTRY(XDefaultVisual),
+ FN_TABLE_ENTRY(XFreeGC),
+ FN_TABLE_ENTRY(XFreePixmap),
+ FN_TABLE_ENTRY(XPutImage),
+ FN_TABLE_ENTRY(XQueryColor),
+ { NULL, NULL }
+ };
+
+static FN_TABLE xtFunctions[] = { FN_TABLE_ENTRY(XtMalloc), {NULL, NULL} };
+
+int NGImageInit() {
+ int i = 0;
+ void * fn;
+#ifdef AIX
+ void * x11Lib = dlopen(X11_LIB, RTLD_LAZY | RTLD_MEMBER);
+ void * xtLib = dlopen(XT_LIB, RTLD_LAZY | RTLD_MEMBER);
+#else
+ void * x11Lib = dlopen(X11_LIB, RTLD_LAZY);
+ void * xtLib = dlopen(XT_LIB, RTLD_LAZY);
+#endif
+ /* initialize ptr struct to 0's */
+ memset(&ng, 0, sizeof(struct NG_PTRS));
+
+
+ if (x11Lib == NULL || xtLib == NULL)
+ return -1;
+
+ for (i = 0; x11Functions[i].fnName != NULL; i++) {
+ fn = dlsym(x11Lib, x11Functions[i].fnName);
+ if (fn != 0)
+ *(x11Functions[i].fnPtr) = fn;
+ else
+ return -1;
+ }
+
+ for (i = 0; xtFunctions[i].fnName != NULL; i++) {
+ fn = dlsym(xtLib, xtFunctions[i].fnName);
+ if (fn != 0)
+ *(xtFunctions[i].fnPtr) = fn;
+ else
+ return -1;
+ }
+ return 0;
+}
+/**
+ * Return the nbr of entries in the default color palette
+ */
+int getNbrColorsXPalette(Display *xDisplay)
+{
+ Visual *visual = ng.XDefaultVisual (xDisplay, ng.XDefaultScreen(xDisplay));
+ return visual->map_entries;
+}
+
+/**
+ * Return the RGB codes of the default palette
+ * palette: buffer of size numColors * 3, holding the RGB values
+ */
+ng_err_t getXPalette (Display *xDisplay, int numColors, char* palette)
+{
+ XColor color;
+ int i;
+ int index = 0;
+ int colormap = ng.XDefaultColormap (xDisplay, ng.XDefaultScreen(xDisplay));
+ for (i = 0; i < numColors; i++)
+ {
+ color.pixel = i;
+ ng.XQueryColor (xDisplay, colormap, &color);
+ palette[index++] = ((color.red >> 8) & 0xFF);
+ palette[index++] = ((color.green >> 8) & 0xFF);
+ palette[index++] = ((color.blue >> 8) & 0xFF);
+ }
+ return ERR_OK;
+}
+
+/**
+ * Put a device-independent image of any depth into a drawable of the same size,
+ */
+ng_err_t putImage(ng_bitmap_image_t *image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY,
+ Display *xDisplay, Visual *visual, int screenDepth,
+ int drawable)
+{
+
+ XImage *xImagePtr;
+ int bufSize;
+ int destRedMask = 0, destGreenMask = 0, destBlueMask = 0;
+ BYTE1 screenDirect;
+ UBYTE1 *srcData = NgBitmapImageImageData(image);
+ UBYTE4 srcDepth = NgBitmapImageBitCount(image);
+ BYTE4 sbpp, dbpp;
+ GC tempGC;
+ int numColors = 0;
+
+ /* We only support image depth of 24 bits */
+ if (srcDepth != 24) return NgError (ERR_NG, "Error unsupported depth - only support 24 bit");
+ if (screenDepth <= 8)
+ {
+ numColors = getNbrColorsXPalette (xDisplay);
+ if (numColors == 0)
+ return NgError (ERR_NG, "Error pseudo-color mode detected, no colors available");
+ numColors = 1 << ng.XDefaultDepthOfScreen (ng.XDefaultScreenOfDisplay (xDisplay));
+ screenDirect = 0;
+ } else
+ {
+ destRedMask = visual->red_mask;
+ destGreenMask = visual->green_mask;
+ destBlueMask = visual->blue_mask;
+ screenDirect = 1;
+ }
+
+ xImagePtr = ng.XCreateImage(xDisplay, visual, screenDepth, ZPixmap, 0, 0, srcWidth, srcHeight, 32, 0);
+ if (xImagePtr == NULL) return NgError (ERR_NG, "Error XCreateImage failed");
+ bufSize = xImagePtr->bytes_per_line * srcHeight;
+
+ xImagePtr->data = (char*) ng.XtMalloc (bufSize);
+ sbpp = NgBitmapImageBytesPerRow(image);
+ dbpp = xImagePtr->bytes_per_line;
+
+ if (screenDirect)
+ {
+ /* 24 bit source to direct screen destination */
+ NgBitmapImageBlitDirectToDirect(srcData, sbpp, srcWidth, srcHeight,
+ (UBYTE1*)xImagePtr->data, xImagePtr->bits_per_pixel, dbpp, xImagePtr->byte_order,
+ destRedMask, destGreenMask, destBlueMask);
+ } else
+ {
+ /* 24 bit source to palette screen destination */
+ char *palette = (char*) NgMalloc (numColors * 3);
+ getXPalette (xDisplay, numColors, palette);
+ NgBitmapImageBlitDirectToPalette(srcData, sbpp, srcWidth, srcHeight,
+ (UBYTE1*)xImagePtr->data, xImagePtr->bits_per_pixel, dbpp, xImagePtr->byte_order,
+ (UBYTE1*)palette, numColors);
+ NgFree (palette);
+ }
+
+ tempGC = ng.XCreateGC (xDisplay, drawable, 0, NULL);
+ ng.XPutImage(xDisplay, drawable, tempGC, xImagePtr, 0, 0, 0, 0, srcWidth, srcHeight);
+
+ XDestroyImage (xImagePtr);
+ ng.XFreeGC (xDisplay, tempGC);
+ return ERR_OK;
+}
+
+ng_err_t init(ng_bitmap_image_t *image, Display *xDisplay, int screenDepth, int drawable, Pixmap *pixmap)
+{
+ ng_err_t err;
+ int width = (int)NgBitmapImageWidth(image);
+ int height = (int)NgBitmapImageHeight(image);
+
+ Visual *visual = ng.XDefaultVisual(xDisplay, ng.XDefaultScreen(xDisplay));
+ *pixmap = ng.XCreatePixmap(xDisplay, drawable, width, height, screenDepth);
+ if (*pixmap == 0)
+ {
+ return NgError (ERR_NG, "Error XCreatePixmap failed");
+ }
+ err = putImage(image, 0, 0, width, height, 0, 0, xDisplay, visual, screenDepth, *pixmap);
+ if (err != ERR_OK)
+ {
+ ng.XFreePixmap (xDisplay, *pixmap);
+ return NgError (err, "Error putImage failed");
+ }
+
+ return ERR_OK;
+}
+
+/**
+ * loadBMPImage
+ * Create a pixmap representing the given BMP file, for the specified display and screen.
+ *
+ * display: connection to X server
+ * screen: the screen to create the pixmap for
+ * bmpPathname: absolute path and name to the bmp file
+ *
+ * returned value: the pixmap newly created if successful. 0 otherwise.
+ */
+Pixmap loadBMPImage (Display *display, Screen *screen, char *bmpPathname) {
+ Window drawable;
+ ng_stream_t in;
+ ng_bitmap_image_t image;
+ ng_err_t err = ERR_OK;
+ int screenDepth;
+ Pixmap pixmap;
+
+ /* this must be called before any X functions are used */
+ NGImageInit();
+ NgInit();
+
+ drawable = ng.XDefaultRootWindow (display);
+ screenDepth = ng.XDefaultDepthOfScreen (screen);
+
+ if (NgStreamInit (&in, bmpPathname) != ERR_OK)
+ {
+ NgError (ERR_NG, "Error can't open BMP file");
+ return 0;
+ }
+ NgBitmapImageInit (&image);
+ err = NgBmpDecoderReadImage (&in, &image);
+ NgStreamClose (&in);
+
+ if (err != ERR_OK)
+ {
+ NgBitmapImageFree (&image);
+ return 0;
+ }
+
+ err = init (&image, display, screenDepth, drawable, &pixmap);
+ NgBitmapImageFree (&image);
+
+ return err == ERR_OK ? pixmap : 0;
+}
+
+const char *getBMPErrorMessage ()
+{
+ return NgGetLastErrorMsg ();
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgImage.h b/features/org.eclipse.equinox.executable.feature/library/motif/NgImage.h
new file mode 100644
index 000000000..a12218fb2
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgImage.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef __NG_IMAGE_H
+#define __NG_IMAGE_H
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+
+struct NG_PTRS {
+ GC (*XCreateGC) (Display*, Drawable, unsigned long, XGCValues*);
+ XImage * (*XCreateImage) (Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int);
+ Pixmap (*XCreatePixmap) (Display*, Drawable, unsigned int, unsigned int, unsigned int);
+ Colormap (*XDefaultColormap) (Display*, int);
+ int (*XDefaultDepthOfScreen)(Screen*);
+ Window (*XDefaultRootWindow) (Display*);
+ int (*XDefaultScreen) (Display*);
+ Screen * (*XDefaultScreenOfDisplay)(Display*);
+ Visual * (*XDefaultVisual) (Display*, int);
+ int (*XFreeGC) (Display*, GC);
+ int (*XFreePixmap) (Display*, Pixmap);
+ int (*XPutImage) (Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int);
+ int (*XQueryColor) (Display*, Colormap, XColor*);
+ char * (*XtMalloc) (Cardinal);
+};
+
+/**
+ * loadBMPImage
+ * Create a pixmap representing the given BMP file, for the specified display and screen.
+ *
+ * display: connection to X server
+ * screen: the screen to create the pixmap for
+ * bmpPathname: absolute path and name to the bmp file
+ *
+ * returned value: the pixmap newly created if successful. 0 otherwise.
+ */
+Pixmap loadBMPImage (Display *display, Screen *screen, char *bmpPathname);
+
+/**
+ * Return error message describing why the BMP file could not be displayed
+ */
+const char *getBMPErrorMessage();
+
+#endif /* NG_IMAGE_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.c b/features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.c
new file mode 100644
index 000000000..96053b305
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.c
@@ -0,0 +1,490 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "NgImageData.h"
+
+static UBYTE4 RoundRow (UBYTE4 width)
+{
+ UBYTE4 result = (width + RowRounding - 1)
+ & ~(RowRounding - 1) ;
+ return result ;
+}
+
+void NgBitmapImageInit (ng_bitmap_image_t *image)
+{
+ NgBitmapImageClearData (image);
+}
+
+void NgBitmapImageFree (ng_bitmap_image_t *image)
+{
+ NgFree (image->color_map);
+ NgFree (image->image_data);
+ NgFree (image->alpha_data);
+}
+
+void NgBitmapImageClearData (ng_bitmap_image_t *image)
+{
+ image->bit_count = 0;
+ image->image_width = 0;
+ image->image_height = 0;
+ image->color_count = 0;
+ image->color_map = NULL;
+ image->image_data = NULL;
+ image->alpha_data = NULL;
+ image->transparent_pixel = -1;
+}
+
+void NgBitmapImageSetSize(ng_bitmap_image_t *image,
+ UBYTE4 color_count,
+ UBYTE4 bits,
+ UBYTE4 width,
+ UBYTE4 height)
+{
+ NgFree (image->color_map);
+ NgFree (image->image_data);
+ NgBitmapImageClearData (image);
+
+ switch (bits)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ {
+ UBYTE4 bitsize;
+ UBYTE4 bytecount;
+
+ image->bit_count = bits;
+ image->color_count = color_count;
+ image->image_width = width;
+ image->image_height = height;
+
+ image->color_map = (ng_color_map_entry_t *) NgMalloc (sizeof(ng_color_map_entry_t) * image->color_count);
+ NgMemSet (image->color_map, 0, sizeof (ng_color_map_entry_t) * image->color_count);
+ bitsize = image->bit_count * image->image_width;
+ image->row_width = RoundRow ((bitsize + 7)/8);
+ bytecount = image->row_width * image->image_height;
+ image->image_data = (UBYTE1 *) NgMalloc (bytecount);
+ NgMemSet (image->image_data, 0, (BYTE4)bytecount);
+ }
+ break ;
+ case 16:
+ {
+ image->bit_count = bits;
+ image->color_count = color_count;
+ image->image_width = width;
+ image->image_height = height;
+ image->row_width = RoundRow (2 * image->image_width);
+ image->image_data = (UBYTE1 *) NgMalloc (image->row_width * image->image_height);
+ NgMemSet (image->image_data, 0, image->row_width * image->image_height);
+ }
+ break;
+ case 24:
+ {
+ image->bit_count = bits;
+ image->color_count = color_count;
+ image->image_width = width;
+ image->image_height = height;
+ image->row_width = RoundRow (3 * image->image_width);
+ image->image_data = (UBYTE1 *) NgMalloc (image->row_width * image->image_height);
+ NgMemSet (image->image_data, 0, image->row_width * image->image_height);
+ }
+ break;
+ case 32:
+ {
+ image->bit_count = bits;
+ image->color_count = color_count;
+ image->image_width = width;
+ image->image_height = height;
+ image->row_width = RoundRow (4 * image->image_width);
+ image->image_data = (UBYTE1 *) NgMalloc (image->row_width * image->image_height);
+ NgMemSet (image->image_data, 0, image->row_width * image->image_height);
+ }
+ break ;
+ default:
+ NgError (ERR_INVALID_BIT_COUNT, NULL);
+ }
+}
+
+ng_color_map_entry_t *NgBitmapImageColorMap (ng_bitmap_image_t *image, UBYTE4 index)
+{
+ if (index >= image->color_count)
+ {
+ NgError (ERR_SUBSCRIPT_OUT_OF_RANGE, "Error NgBitmapImageColorMap failed");
+ return NULL;
+ }
+
+ return &image->color_map [index] ;
+}
+
+/* blit constants */
+#define TYPE_INDEX_1_MSB 1
+#define TYPE_INDEX_1_LSB 2
+#define TYPE_INDEX_2 3
+#define TYPE_INDEX_4 4
+#define TYPE_INDEX_8 5
+#define TYPE_GENERIC_24 6
+#define TYPE_GENERIC_8 7
+#define TYPE_GENERIC_16_MSB 8
+#define TYPE_GENERIC_16_LSB 9
+#define TYPE_GENERIC_32_MSB 10
+#define TYPE_GENERIC_32_LSB 11
+
+/**
+ * Computes the required channel shift from a mask.
+ */
+UBYTE4 getChannelShift(UBYTE4 mask)
+{
+ UBYTE4 i;
+ if (mask == 0) return 0;
+ for (i = 0; ((mask & 1) == 0) && (i < 32); ++i)
+ {
+ mask >>= 1;
+ }
+ return i;
+}
+
+/**
+ * Computes the required channel width (depth) from a mask.
+ */
+UBYTE4 getChannelWidth(UBYTE4 mask, UBYTE4 shift)
+{
+ UBYTE4 i;
+ if (mask == 0) return 0;
+ mask >>= shift;
+ for (i = shift; ((mask & 1) != 0) && (i < 32); ++i)
+ {
+ mask >>= 1;
+ }
+ return i - shift;
+}
+
+/**
+ * Blits a direct palette image into a direct palette image.
+ *
+ * srcData the source byte array containing image data
+ * srcStride the source number of bytes per line
+ * srcWidth the width of the source blit region
+ * srcHeight the height of the source blit region
+ * destData the destination byte array containing image data
+ * destDepth the destination depth: one of 8, 16, 24, 32
+ * destStride the destination number of bytes per line
+ * destOrder the destination byte ordering: 0 for LSB, 1 otherwise
+ * ignored if destDepth is not 16 or 32
+ * destRedMask the destination red channel mask
+ * destGreenMask the destination green channel mask
+ * destBlueMask the destination blue channel mask
+ *
+ * It is assumed that.
+ * srcDepth: 24 - BGR ordering (BMP format)
+ * no alpha
+ * srcX: 0
+ * srcY: 0
+ * destX: 0
+ * destY: 0
+ * destWidth: same as srcWidth
+ * destHeight: same as srcHeight
+ */
+void NgBitmapImageBlitDirectToDirect(
+ UBYTE1 *srcData, BYTE4 srcStride,
+ BYTE4 srcWidth, BYTE4 srcHeight,
+ UBYTE1 *destData, BYTE4 destDepth, BYTE4 destStride, BYTE4 destOrder,
+ UBYTE4 destRedMask, UBYTE4 destGreenMask, UBYTE4 destBlueMask)
+{
+ BYTE4 srcX = 0, srcY = 0, destX = 0, destY = 0, destWidth = srcWidth, destHeight = srcHeight;
+
+ BYTE4 sbpp, stype, spr, dbpp, dtype, dpr, dprxi, dpryi, dp, sp, dy, dx;
+ BYTE4 destRedShift, destRedWidth;
+ BYTE4 destRedPreShift, destGreenShift, destGreenWidth, destGreenPreShift;
+ BYTE4 destBlueShift, destBlueWidth, destBluePreShift;
+ UBYTE1 r, g, b;
+ UBYTE4 data;
+
+ /*** Prepare source-related data ***/
+ sbpp = 3;
+ stype = TYPE_GENERIC_24;
+
+ spr = srcY * srcStride + srcX * sbpp;
+
+ /*** Prepare destination-related data ***/
+ switch (destDepth)
+ {
+ case 8:
+ dbpp = 1;
+ dtype = TYPE_GENERIC_8;
+ break;
+ case 16:
+ dbpp = 2;
+ dtype = (destOrder != 0) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
+ break;
+ case 24:
+ dbpp = 3;
+ dtype = TYPE_GENERIC_24;
+ break;
+ case 32:
+ dbpp = 4;
+ dtype = (destOrder != 0) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
+ break;
+ default:
+ return;
+ }
+
+ dpr = destY * destStride + destX * dbpp;
+ dprxi = dbpp;
+ dpryi = destStride;
+
+ /*** Blit ***/
+ dp = dpr;
+ sp = spr;
+
+ /*** Comprehensive blit (apply transformations) ***/
+ destRedShift = getChannelShift(destRedMask);
+ destRedWidth = getChannelWidth(destRedMask, destRedShift);
+ destRedPreShift = 8 - destRedWidth;
+ destGreenShift = getChannelShift(destGreenMask);
+ destGreenWidth = getChannelWidth(destGreenMask, destGreenShift);
+ destGreenPreShift = 8 - destGreenWidth;
+ destBlueShift = getChannelShift(destBlueMask);
+ destBlueWidth = getChannelWidth(destBlueMask, destBlueShift);
+ destBluePreShift = 8 - destBlueWidth;
+
+ r = 0; g = 0; b = 0;
+ for (dy = destHeight; dy > 0; --dy, sp = spr += srcStride, dp = dpr += dpryi)
+ {
+ for (dx = destWidth; dx > 0; --dx, dp += dprxi)
+ {
+ /*** READ NEXT PIXEL ASSUMING BGR ordering (BMP format) ***/
+ b = srcData[sp];
+ g = srcData[sp + 1];
+ r = srcData[sp + 2];
+ sp += 3;
+ /*** WRITE NEXT PIXEL ***/
+ data =
+ (r >> destRedPreShift << destRedShift) |
+ (g >> destGreenPreShift << destGreenShift) |
+ (b >> destBluePreShift << destBlueShift);
+ switch (dtype)
+ {
+ case TYPE_GENERIC_8:
+ {
+ destData[dp] = (UBYTE1) data;
+ } break;
+ case TYPE_GENERIC_16_MSB:
+ {
+ destData[dp] = (UBYTE1) (data >> 8);
+ destData[dp + 1] = (UBYTE1) (data & 0xff);
+ } break;
+ case TYPE_GENERIC_16_LSB:
+ {
+ destData[dp] = (UBYTE1) (data & 0xff);
+ destData[dp + 1] = (UBYTE1) (data >> 8);
+ } break;
+ case TYPE_GENERIC_24:
+ {
+ destData[dp] = (UBYTE1) (data >> 16);
+ destData[dp + 1] = (UBYTE1) (data >> 8);
+ destData[dp + 2] = (UBYTE1) (data & 0xff);
+ } break;
+ case TYPE_GENERIC_32_MSB:
+ {
+ destData[dp] = (UBYTE1) (data >> 24);
+ destData[dp + 1] = (UBYTE1) (data >> 16);
+ destData[dp + 2] = (UBYTE1) (data >> 8);
+ destData[dp + 3] = (UBYTE1) (data & 0xff);
+ } break;
+ case TYPE_GENERIC_32_LSB:
+ {
+ destData[dp] = (UBYTE1) (data & 0xff);
+ destData[dp + 1] = (UBYTE1) (data >> 8);
+ destData[dp + 2] = (UBYTE1) (data >> 16);
+ destData[dp + 3] = (UBYTE1) (data >> 24);
+ } break;
+ }
+ }
+ }
+}
+
+/**
+ * Create a simple hash table used when converting direct colors to values in a palette
+ * Each bucket stores the RGB codes and the corresponding palette index.
+ * The key is made from the RGB values.
+ * It is used as a cache. New entries colliding with older ones simply
+ * replace them.
+ */
+ng_palette_bucket_t *NgRGBIndexCreate ()
+{
+ ng_palette_bucket_t *table = (ng_palette_bucket_t *)NgMalloc (RGBIndexTableSize * sizeof (ng_palette_bucket_t));
+ NgMemSet (table, 0, RGBIndexTableSize * sizeof (ng_palette_bucket_t));
+ return table;
+}
+
+void NgRGBIndexFree (ng_palette_bucket_t *table)
+{
+ NgFree (table);
+}
+
+void NgRGBIndexSet (ng_palette_bucket_t *table, UBYTE1 r, UBYTE1 g, UBYTE1 b, UBYTE1 index)
+{
+ int i = (r * g * b) % RGBIndexTableSize;
+ table[i].blue = b;
+ table[i].green = g;
+ table[i].red = r;
+ table[i].index = index;
+ table[i].isSet = 1;
+}
+
+int NgRGBIndexGet (ng_palette_bucket_t *table, UBYTE1 r, UBYTE1 g, UBYTE1 b)
+{
+ int i = (r * g * b) % RGBIndexTableSize;
+ if (table[i].isSet && table[i].blue == b && table[i].green == g && table[i].red == r)
+ return table[i].index;
+ return -1;
+}
+
+/**
+ * Blits a direct palette image into an index palette image.
+ *
+ * srcData the source byte array containing image data
+ * srcStride the source number of bytes per line
+ * srcX the top-left x-coord of the source blit region
+ * srcY the top-left y-coord of the source blit region
+ * srcWidth the width of the source blit region
+ * srcHeight the height of the source blit region
+ * destData the destination byte array containing image data
+ * destDepth the destination depth: one of 1, 2, 4, 8
+ * destStride the destination number of bytes per line
+ * destOrder the destination byte ordering: 0 if LSB, 1 otherwise;
+ * ignored if destDepth is not 1
+ * destX the top-left x-coord of the destination blit region
+ * destY the top-left y-coord of the destination blit region
+ * destWidth the width of the destination blit region
+ * destHeight the height of the destination blit region
+ * destColors the destination palette red green blue component intensities
+ * destNumColors the number of colors in destColors
+ *
+ * It is assumed that.
+ * srcDepth: 24 - BGR ordering (BMP format)
+ * no alpha
+ * srcX: 0
+ * srcY: 0
+ * destX: 0
+ * destY: 0
+ * destWidth: same as srcWidth
+ * destHeight: same as srcHeight
+ */
+
+void NgBitmapImageBlitDirectToPalette(
+ UBYTE1 *srcData, BYTE4 srcStride,
+ BYTE4 srcWidth, BYTE4 srcHeight,
+ UBYTE1 *destData, BYTE4 destDepth, BYTE4 destStride, BYTE4 destOrder,
+ UBYTE1 *destColors, int destNumColors)
+{
+ BYTE4 srcX = 0, srcY = 0, destX = 0, destY = 0, destWidth = srcWidth, destHeight = srcHeight;
+ BYTE4 sbpp, spr, dtype, dpr, dp, sp, destPaletteSize, dy, dx, j, dr, dg, db, distance, minDistance;
+
+ UBYTE1 r = 0, g = 0, b = 0, index = 0;
+ int storedIndex;
+ ng_palette_bucket_t *RGBIndexTable;
+
+ /*** Prepare source-related data ***/
+ sbpp = 3;
+ spr = srcY * srcStride + srcX * sbpp;
+
+ /*** Prepare destination-related data ***/
+ switch (destDepth)
+ {
+ case 8:
+ dtype = TYPE_INDEX_8;
+ break;
+ case 4:
+ destStride <<= 1;
+ dtype = TYPE_INDEX_4;
+ break;
+ case 2:
+ destStride <<= 2;
+ dtype = TYPE_INDEX_2;
+ break;
+ case 1:
+ destStride <<= 3;
+ dtype = (destOrder != 0) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
+ break;
+ default:
+ return;
+ }
+ dpr = destY * destStride + destX;
+
+ dp = dpr;
+ sp = spr;
+ destPaletteSize = destNumColors;
+
+ RGBIndexTable = NgRGBIndexCreate ();
+ for (dy = destHeight; dy > 0; --dy, sp = spr += srcStride, dp = dpr += destStride)
+ {
+ for (dx = destWidth; dx > 0; --dx, dp += 1)
+ {
+ /*** READ NEXT PIXEL ASSUMING BGR ordering (BMP format) ***/
+ b = srcData[sp];
+ g = srcData[sp+1];
+ r = srcData[sp+2];
+ sp += 3;
+
+ /*** MAP COLOR TO THE PALETTE ***/
+ storedIndex = NgRGBIndexGet (RGBIndexTable, r, g, b);
+ if (storedIndex >= 0)
+ {
+ index = (UBYTE1) storedIndex;
+ } else
+ {
+ for (j = 0, minDistance = 0x7fffffff; j < destPaletteSize; ++j)
+ {
+ dr = (destColors[j*3] & 0xff) - r;
+ dg = (destColors[j*3+1] & 0xff) - g;
+ db = (destColors[j*3+2] & 0xff) - b;
+ distance = dr * dr + dg * dg + db * db;
+ if (distance < minDistance)
+ {
+ index = (UBYTE1)j;
+ if (distance == 0) break;
+ minDistance = distance;
+ }
+ }
+ NgRGBIndexSet (RGBIndexTable, r, g, b, index);
+ }
+
+ /*** WRITE NEXT PIXEL ***/
+ switch (dtype) {
+ case TYPE_INDEX_8:
+ destData[dp] = (UBYTE1) index;
+ break;
+ case TYPE_INDEX_4:
+ if ((dp & 1) != 0) destData[dp >> 1] = ((destData[dp >> 1] & 0xf0) | index);
+ else destData[dp >> 1] = ((destData[dp >> 1] & 0x0f) | (index << 4));
+ break;
+ case TYPE_INDEX_2:
+ {
+ int shift = 6 - (dp & 3) * 2;
+ destData[dp >> 2] = ((destData[dp >> 2] & ~(0x03 << shift)) | (index << shift));
+ } break;
+ case TYPE_INDEX_1_MSB:
+ {
+ int shift = 7 - (dp & 7);
+ destData[dp >> 3] = ((destData[dp >> 3] & ~(0x01 << shift)) | (index << shift));
+ } break;
+ case TYPE_INDEX_1_LSB:
+ {
+ int shift = dp & 7;
+ destData[dp >> 3] = ((destData[dp >> 3] & ~(0x01 << shift)) | (index << shift));
+ } break;
+ }
+ }
+ }
+ NgRGBIndexFree (RGBIndexTable);
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.h b/features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.h
new file mode 100644
index 000000000..2b0f9f4af
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgImageData.h
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef __NG_IMAGEDATA_H
+#define __NG_IMAGEDATA_H
+
+/**
+ * Type ng_bitmap_image_t (C version of SWT ImageData)
+ *
+ * Unlike ImageData, ng_bitmap_image_t and all its api are 'internal'.
+ * The api marked 'public' is in the sense that it can be used
+ * by the rest of the native graphic library.
+ */
+
+#include "NgCommon.h"
+
+typedef struct ng_bitmap_image_t ng_bitmap_image_t;
+
+typedef struct {
+ UBYTE1 blue;
+ UBYTE1 green;
+ UBYTE1 red;
+} ng_color_map_entry_t;
+
+/* ImageData in SWT expects RGB not BGR */
+enum { RedOffset=0, GreenOffset=1, BlueOffset=2 };
+
+struct ng_bitmap_image_t {
+ /* Width in bytes of each row */
+ UBYTE4 row_width;
+ /* Number of bits per pixel (depth) 1, 2, 4, 8, 16 or 24 */
+ UBYTE4 bit_count;
+ UBYTE4 image_width;
+ UBYTE4 image_height;
+ /* image data
+ * 24-bit images, 3 bytes per pixel representing RGB values
+ * 32 bit images, 4 bytes per pixel representing RGB values + one wasted byte
+ * 16 bit images, 2 bytes per pixel
+ * rest (1, 2, 4, 8): index into color map
+ */
+ UBYTE1 *image_data;
+ /* alpha data (either NULL or of size image_width*image_height) */
+ UBYTE1 *alpha_data;
+ /* transparent pixel - default is -1 which means no transparent pixel */
+ BYTE4 transparent_pixel;
+ /* number of entries in color map */
+ UBYTE4 color_count;
+ ng_color_map_entry_t *color_map;
+};
+
+/************************************************
+ * Public API ng_bitmap_image_t
+ ************************************************/
+
+/**
+ * Init an image
+ */
+void NgBitmapImageInit (ng_bitmap_image_t *);
+
+/**
+ * Dispose the resources allocated by the image.
+ */
+void NgBitmapImageFree (ng_bitmap_image_t *);
+
+/**
+ * Access start of image data
+ * return: a pointer to an array of UBYTE1 of size image_row * image_width
+ * signature: UBYTE1 *NgBitmapImageImageData (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageImageData(image) ((image)->image_data)
+
+/**
+ * signature: UBYTE4 NgBitmapImageWidth (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageWidth(image) ((image)->image_width)
+
+/**
+ * signature: UBYTE4 NgBitmapImageHeight (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageHeight(image) ((image)->image_height)
+
+/**
+ * signature: UBYTE4 NgBitmapImageBitCount (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageBitCount(image) ((image)->bit_count)
+
+/**
+ * signature: UBYTE4 NgBitmapImageColorCount (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageColorCount(image) ((image)->color_count)
+
+/**
+ * Access a row of the image
+ * row: a value which must be between 0 and image_height-1
+ * return: a pointer to the desired row, which is an array of size row_width
+ * signature: UBYTE1 *NgBitmapImageGetRow (ng_bitmap_image_t *image, UBYTE4 row)
+ */
+#define NgBitmapImageGetRow(image, row) (&image->image_data[row * image->row_width])
+
+/**
+ * signature: UBYTE4 NgBitmapImageBytesPerRow (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageBytesPerRow(image) ((image)->row_width)
+
+/**
+ * Retrieve an entry from the color map
+ * index: a value which must be between 0 and color_count-1
+ */
+ng_color_map_entry_t *NgBitmapImageColorMap (ng_bitmap_image_t *, UBYTE4 index);
+
+/**
+ * Get the value of the transparent pixel
+ * signature: BYTE4 NgBitmapImageGetTransparent (ng_bitmap_image_t *image)
+ */
+#define NgBitmapImageGetTransparent(image) ((image)->transparent_pixel)
+
+/**
+ * Get the alpha data
+ * signature: UBYTE1 *NgBitmapImageGetAlpha (ng_bitmap_image_t* image)
+ */
+#define NgBitmapImageGetAlpha(image) ((image)->alpha_data)
+
+void NgBitmapImageBlitDirectToDirect(
+ UBYTE1 *srcData, BYTE4 srcStride,
+ BYTE4 srcWidth, BYTE4 srcHeight,
+ UBYTE1 *destData, BYTE4 destDepth, BYTE4 destStride, BYTE4 destOrder,
+ UBYTE4 destRedMask, UBYTE4 destGreenMask, UBYTE4 destBlueMask);
+
+/* Size of hash table used in NgBitmapImageBlitDirectToPalette */
+#define RGBIndexTableSize 103
+
+typedef struct {
+ UBYTE1 isSet;
+ UBYTE1 blue;
+ UBYTE1 green;
+ UBYTE1 red;
+ UBYTE1 index;
+} ng_palette_bucket_t;
+
+void NgBitmapImageBlitDirectToPalette(
+ UBYTE1 *srcData, BYTE4 srcStride,
+ BYTE4 srcWidth, BYTE4 srcHeight,
+ UBYTE1 *destData, BYTE4 destDepth, BYTE4 destStride, BYTE4 destOrder,
+ UBYTE1 *destColors, int destNumColors);
+
+/************************************************
+ * Private API ng_bitmap_image_t
+ ************************************************/
+
+/* Number of bytes to round each row to */
+#define RowRounding 4
+
+void NgBitmapImageInitialize (ng_bitmap_image_t *);
+void NgBitmapImageClearData (ng_bitmap_image_t *);
+
+void NgBitmapImageSetSize(ng_bitmap_image_t *,
+ UBYTE4 color_count,
+ UBYTE4 bits,
+ UBYTE4 width,
+ UBYTE4 height);
+
+#endif /* NG_IMAGEDATA_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.c b/features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.c
new file mode 100644
index 000000000..57989f649
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.c
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "NgCommon.h"
+#include "NgWinBMPFileFormat.h"
+
+#define BMPHeaderFixedSize 40
+
+BYTE4 decompressRLE4Data(BYTE1 *src, BYTE4 numBytes, BYTE4 stride, BYTE1 *dest, BYTE4 destSize)
+{
+ BYTE4 sp = 0;
+ BYTE4 se = numBytes;
+ BYTE4 dp = 0;
+ BYTE4 de = destSize;
+ BYTE4 x = 0, y = 0;
+ BYTE4 i;
+ while (sp < se)
+ {
+ int len = src[sp] & 0xFF;
+ sp++;
+ if (len == 0)
+ {
+ len = src[sp] & 0xFF;
+ sp++;
+ switch (len)
+ {
+ case 0: /* end of line */
+ y++;
+ x = 0;
+ dp = y * stride;
+ if (dp >= de)
+ return -1;
+ break;
+ case 1: /* end of bitmap */
+ return 1;
+ case 2: /* delta */
+ x += src[sp] & 0xFF;
+ sp++;
+ y += src[sp] & 0xFF;
+ sp++;
+ dp = y * stride + x / 2;
+ if (dp >= de)
+ return -1;
+ break;
+ default: /* absolute mode run */
+ if ((len & 1) != 0) /* odd run lengths not currently supported */
+ return -1;
+ x += len;
+ len = len / 2;
+ if (len > (se - sp))
+ return -1;
+ if (len > (de - dp))
+ return -1;
+ for (i = 0; i < len; i++)
+ {
+ dest[dp] = src[sp];
+ dp++;
+ sp++;
+ }
+ if ((sp & 1) != 0)
+ sp++; /* word align sp? */
+ break;
+ }
+ } else
+ {
+ BYTE1 theByte;
+ if ((len & 1) != 0)
+ return -1;
+ x += len;
+ len = len / 2;
+ theByte = src[sp];
+ sp++;
+ if (len > (de - dp))
+ return -1;
+ for (i = 0; i < len; i++)
+ {
+ dest[dp] = theByte;
+ dp++;
+ }
+ }
+ }
+ return 1;
+}
+
+BYTE4 decompressRLE8Data(BYTE1 *src, BYTE4 numBytes, BYTE4 stride, BYTE1 *dest, BYTE4 destSize)
+{
+ BYTE4 sp = 0;
+ BYTE4 se = numBytes;
+ BYTE4 dp = 0;
+ BYTE4 de = destSize;
+ BYTE4 x = 0, y = 0;
+ BYTE4 i;
+ while (sp < se) {
+ int len = src[sp] & 0xFF;
+ sp++;
+ if (len == 0) {
+ len = src[sp] & 0xFF;
+ sp++;
+ switch (len)
+ {
+ case 0: /* end of line */
+ y++;
+ x = 0;
+ dp = y * stride;
+ if (dp >= de)
+ return -1;
+ break;
+ case 1: /* end of bitmap */
+ return 1;
+ case 2: /* delta */
+ x += src[sp] & 0xFF;
+ sp++;
+ y += src[sp] & 0xFF;
+ sp++;
+ dp = y * stride + x;
+ if (dp >= de)
+ return -1;
+ break;
+ default: /* absolute mode run */
+ if (len > (se - sp))
+ return -1;
+ if (len > (de - dp))
+ return -1;
+ for (i = 0; i < len; i++)
+ {
+ dest[dp] = src[sp];
+ dp++;
+ sp++;
+ }
+ if ((sp & 1) != 0)
+ sp++; /* word align sp? */
+ x += len;
+ break;
+ }
+ } else
+ {
+ BYTE1 theByte = src[sp];
+ sp++;
+ if (len > (de - dp))
+ return -1;
+ for (i = 0; i < len; i++)
+ {
+ dest[dp] = theByte;
+ dp++;
+ }
+ x += len;
+ }
+ }
+ return 1;
+}
+
+ng_err_t decompressData (BYTE1 *src, BYTE4 numBytes, BYTE1 *dest, BYTE4 destSize, BYTE4 stride, BYTE4 cmp)
+{
+ if (cmp == 1)
+ {
+ /* BMP_RLE8_COMPRESSION */
+ if (decompressRLE8Data (src, numBytes, stride, dest, destSize) <= 0)
+ return NgError (ERR_NG, "Error decompressRLE8Data failed");
+ } else if (cmp == 2)
+ {
+ /* BMP_RLE4_COMPRESSION */
+ if (decompressRLE4Data (src, numBytes, stride, dest, destSize) <= 0)
+ return NgError (ERR_NG, "Error decompressRLE4Data failed");
+ } else
+ {
+ return NgError (ERR_NG, "Error decompressData failed - unsupported compression");
+ }
+ return ERR_OK;
+}
+
+void flipScanLines(BYTE1 *data, BYTE4 numBytes, int stride, int height)
+{
+ BYTE4 i1 = 0;
+ BYTE4 i2 = (height - 1) * stride;
+ BYTE4 i, index;
+ for (i = 0; i < height / 2; i++)
+ {
+ for (index = 0; index < stride; index++)
+ {
+ BYTE1 b = data[index + i1];
+ data[index + i1] = data[index + i2];
+ data[index + i2] = b;
+ }
+ i1 += stride;
+ i2 -= stride;
+ }
+}
+
+/**
+ * BmpDecoderReadImage
+ *
+ * Decode the content of a bmp file.
+ *
+ * in : the input stream
+ * image : a pointer to a ng_bitmap_image_t
+ *
+ * return: ERR_OK if the image was correctly built from the input stream
+ * ERR_NG otherwise.
+ */
+ng_err_t NgBmpDecoderReadImage (ng_stream_t *in, ng_bitmap_image_t *image)
+{
+ BYTE4 *fileHeader = (BYTE4*) NgMalloc (5 * sizeof(BYTE4));
+ BYTE1 *infoHeader, *data;
+ BYTE4 width, height, stride, dataSize, cmp, pos;
+ BYTE2 depth;
+ BYTE2 d0;
+
+ NgStreamRead (in, (char *) &d0, sizeof(BYTE2));
+ fileHeader[0] = (BYTE4)LittleEndianToSystemUBYTE2(d0);
+ NgStreamRead (in, (char *) &fileHeader[1], sizeof(BYTE4));
+ fileHeader[1] = LittleEndianToSystemUBYTE4(fileHeader[1]);
+ NgStreamRead (in, (char *) &d0, sizeof(BYTE2));
+ fileHeader[2] = (BYTE4)LittleEndianToSystemUBYTE2(d0);
+ NgStreamRead (in, (char *) &d0, sizeof(BYTE2));
+ fileHeader[3] = (BYTE4)LittleEndianToSystemUBYTE2(d0);
+ NgStreamRead (in, (char *) &fileHeader[4], sizeof(BYTE4));
+ fileHeader[4] = LittleEndianToSystemUBYTE4(fileHeader[4]);
+
+ if (NgStreamEof (in))
+ {
+ NgFree (fileHeader);
+ return NgError (ERR_NG, "Error invalid header file");
+ }
+ if (fileHeader[0] != 0x4D42)
+ {
+ NgFree (fileHeader);
+ return NgError (ERR_NG, "Error not a BMP file");
+ }
+
+ infoHeader = (BYTE1*) NgMalloc (BMPHeaderFixedSize * sizeof (BYTE1));
+ NgStreamRead (in, infoHeader, BMPHeaderFixedSize * sizeof (BYTE1));
+
+ if (NgStreamEof (in))
+ {
+ NgFree (fileHeader);
+ NgFree (infoHeader);
+ return NgError (ERR_NG, "Error invalid info header");
+ }
+
+ NgMemCpy (&width, &infoHeader[4], sizeof (BYTE4));
+ width = LittleEndianToSystemUBYTE4(width);
+
+ NgMemCpy (&height, &infoHeader[8], sizeof (BYTE4));
+ height = LittleEndianToSystemUBYTE4(height);
+
+ NgMemCpy (&depth, &infoHeader[14], sizeof (BYTE2));
+ depth = LittleEndianToSystemUBYTE2(depth);
+
+ stride = (width * depth + 7) / 8;
+ stride = (stride + 3) / 4 * 4; /* Round up to 4 byte multiple */
+
+ if (depth <= 8)
+ {
+ BYTE4 i, index;
+ BYTE1 *colors;
+ BYTE4 numColors;
+ NgMemCpy (&numColors, &infoHeader[32], sizeof (BYTE4));
+ numColors = LittleEndianToSystemUBYTE4(numColors);
+ if (numColors == 0)
+ {
+ BYTE2 value;
+ NgMemCpy (&value, &infoHeader[14], sizeof (BYTE2));
+ value = LittleEndianToSystemUBYTE2(value);
+ numColors = 1 << value;
+ } else
+ {
+ if (numColors > 256)
+ numColors = 256;
+ }
+ colors = (BYTE1*) NgMalloc (numColors * 4);
+ NgStreamRead (in, colors, numColors * 4);
+
+ if (NgStreamEof (in))
+ {
+ NgFree (fileHeader);
+ NgFree (infoHeader);
+ NgFree (colors);
+ return NgError (ERR_NG, "Error invalid palette info");
+ }
+
+ index = 0;
+
+ NgBitmapImageSetSize(image, (UBYTE4)numColors, (UBYTE4)depth,
+ (UBYTE4)width, (UBYTE4)height);
+
+ for (i = 0; i < numColors; i++)
+ {
+ ng_color_map_entry_t *color_map = NgBitmapImageColorMap (image, i);
+ color_map->blue = colors[index++];
+ color_map->green = colors[index++];
+ color_map->red = colors[index++];
+ index++;
+ }
+
+ NgFree (colors);
+ } else
+ {
+ /* direct - 16 and 24 bits */
+ NgBitmapImageSetSize(image, 0, (UBYTE4)depth,
+ (UBYTE4)width, (UBYTE4)height);
+ }
+
+ pos = NgStreamGetPosition (in);
+ if (pos < fileHeader[4])
+ {
+ NgStreamSkip (in, fileHeader[4] - pos);
+ }
+
+ dataSize = height * stride;
+
+ data = (BYTE1*)NgBitmapImageImageData(image);
+ NgMemCpy (&cmp, &infoHeader[16], sizeof (BYTE4));
+ cmp = LittleEndianToSystemUBYTE4(cmp);
+ if (cmp == 0)
+ {
+ /* BMP_NO_COMPRESSION */
+ BYTE4 cnt;
+ cnt = NgStreamRead (in, data, dataSize);
+ if (cnt != dataSize)
+ {
+ NgFree (fileHeader);
+ NgFree (infoHeader);
+ return NgError (ERR_NG, "Error failed reading uncompressed data");
+ }
+ } else
+ {
+ BYTE4 compressedSize;
+ BYTE1 *compressed;
+ BYTE4 cnt;
+ ng_err_t res;
+ NgMemCpy (&compressedSize, &infoHeader[20], sizeof (BYTE4));
+ compressedSize = LittleEndianToSystemUBYTE4(compressedSize);
+ compressed = (BYTE1*) NgMalloc (compressedSize * sizeof (BYTE1));
+ cnt = NgStreamRead (in, compressed, compressedSize);
+ if (cnt != compressedSize)
+ {
+ NgFree (fileHeader);
+ NgFree (infoHeader);
+ NgFree (compressed);
+ return NgError (ERR_NG, "Error failed reading compressed data");
+ }
+ res = decompressData (compressed, compressedSize, data, dataSize, stride, cmp);
+ if (res != ERR_OK)
+ {
+ NgFree (fileHeader);
+ NgFree (infoHeader);
+ NgFree (compressed);
+ return NgError (res, "Error failed data decompression");
+ }
+
+ NgFree (compressed);
+ }
+
+ flipScanLines(data, dataSize, stride, height);
+
+ NgFree (fileHeader);
+ NgFree (infoHeader);
+ return ERR_OK;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.h b/features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.h
new file mode 100644
index 000000000..8ef7dda6b
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/NgWinBMPFileFormat.h
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef __NG_WINBMPFILEFORMAT_H
+#define __NG_WINBMPFILEFORMAT_H
+
+/**
+ * BMP Decoder
+ */
+#include "NgCommon.h"
+#include "NgImageData.h"
+
+/**
+ * BmpDecoderReadImage
+ *
+ * Decode the content of a bmp file.
+ *
+ * in : the input stream
+ * image : a pointer to a ng_bitmap_image_t
+ *
+ * return: ERR_OK if the image was correctly built from the input stream
+ * ERR_NG otherwise.
+ */
+ng_err_t NgBmpDecoderReadImage (ng_stream_t *in, ng_bitmap_image_t *image);
+
+#endif /* __NG_WINBMPFILEFORMAT_H */
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/build.sh b/features/org.eclipse.equinox.executable.feature/library/motif/build.sh
new file mode 100644
index 000000000..7bc48e7d6
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/build.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+#*******************************************************************************
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Sumit Sarkar (Hewlett-Packard)
+# Martin Oberhuber (Wind River) - [185734] Support building with gcc and debug
+#*******************************************************************************
+#
+# Usage: sh build.sh [<optional switches>] [clean]
+#
+# where the optional switches are:
+# -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+# -os <DEFAULT_OS> - default Eclipse "-os" value
+# -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value
+# -ws <DEFAULT_WS> - default Eclipse "-ws" value
+# -java <JAVA_HOME> - java insgtall for jni headers
+#
+# All other arguments are directly passed to the "make" program.
+# This script can also be invoked with the "clean" argument.
+#
+# Examples:
+# sh build.sh clean
+# sh build.sh -java /usr/j2se OPTFLAG=-g PICFLAG=-fpic
+
+cd `dirname $0`
+
+# Define default values for environment variables used in the makefiles.
+programOutput="eclipse"
+defaultOS=""
+defaultOSArch=""
+defaultWS="motif"
+defaultJava=DEFAULT_JAVA_JNI
+EXEC_DIR=../../../../../rt.equinox.binaries/org.eclipse.equinox.executable
+makefile=""
+javaHome=""
+outputRoot="bin"
+if [ "$OS" = "" ]; then
+ OS=`uname -s`
+fi
+if [ "$MODEL" = "" ]; then
+ MODEL=`uname -m`
+fi
+
+case $OS in
+ "AIX")
+ makefile="make_aix.mak"
+ defaultOS="aix"
+ defaultOSArch="ppc"
+ defaultWS="motif"
+ MOTIF_HOME=/usr
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "Linux")
+ makefile="make_linux.mak"
+ defaultOS="linux"
+ defaultOSArch="x86"
+ defaultWS="motif"
+ X11_HOME=/usr/X11R6
+ MOTIF_HOME=~/motif21
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "SunOS")
+# PATH=/usr/ccs/bin:/opt/SUNWspro/bin:$PATH
+ PATH=/usr/ccs/bin:/export/home/SUNWspro/bin:$PATH
+ [ -d /bluebird/teamswt/swt-builddir/build/JRE/SPARC/jdk1.6.0_14 ] && javaHome="/bluebird/teamswt/swt-builddir/build/JRE/SPARC/jdk1.6.0_14"
+ outputRoot="contributed"
+ export PATH
+ makefile="make_solaris.mak"
+ defaultOS="solaris"
+ defaultOSArch="sparc"
+ defaultWS="motif"
+ OS="Solaris"
+ X11_HOME=/usr/openwin
+ MOTIF_HOME=/usr/dt
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ "HP-UX")
+ X11_HOME=/usr
+ MOTIF_HOME=/usr
+ case $MODEL in
+ "ia64")
+ makefile="make_hpux_ia64_32.mak"
+ defaultOS="hpux"
+ defaultOSArch="ia64_32"
+ defaultWS="motif"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ javaHome="/opt/java1.5"
+ defaultJava=DEFAULT_JAVA_EXEC
+ PATH=/opt/hp-gcc/bin:$PATH
+ export PATH
+ ;;
+ *)
+ makefile="make_hpux_PA_RISC.mak"
+ defaultOS="hpux"
+ defaultOSArch="PA_RISC"
+ defaultWS="motif"
+ OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+ ;;
+ esac
+ ;;
+ *)
+ echo "Unknown OS -- build aborted"
+ ;;
+esac
+
+# Parse the command line arguments and override the default values.
+extraArgs=""
+while [ "$1" != "" ]; do
+ if [ "$1" = "-os" ] && [ "$2" != "" ]; then
+ defaultOS="$2"
+ shift
+ elif [ "$1" = "-arch" ] && [ "$2" != "" ]; then
+ defaultOSArch="$2"
+ shift
+ elif [ "$1" = "-ws" ] && [ "$2" != "" ]; then
+ defaultWS="$2"
+ shift
+ elif [ "$1" = "-output" ] && [ "$2" != "" ]; then
+ programOutput="$2"
+ shift
+ elif [ "$1" = "-java" ] && [ "$2" != "" ]; then
+ javaHome="$2"
+ shift
+ else
+ extraArgs="$extraArgs $1"
+ fi
+ shift
+done
+
+# Set up environment variables needed by the makefiles.
+PROGRAM_OUTPUT="$programOutput"
+DEFAULT_OS="$defaultOS"
+DEFAULT_OS_ARCH="$defaultOSArch"
+DEFAULT_WS="$defaultWS"
+JAVA_HOME=$javaHome
+DEFAULT_JAVA=$defaultJava
+
+LIBRARY_DIR="$EXEC_DIR/../org.eclipse.equinox.launcher.$defaultWS.$defaultOS.$defaultOSArch"
+OUTPUT_DIR="$EXEC_DIR/$outputRoot/$defaultWS/$defaultOS/$defaultOSArch"
+
+export OUTPUT_DIR PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS X11_HOME MOTIF_HOME JAVA_HOME DEFAULT_JAVA LIBRARY_DIR
+
+# If the OS is supported (a makefile exists)
+if [ "$makefile" != "" ]; then
+ if [ "$extraArgs" != "" ]; then
+ make -f $makefile $extraArgs
+ else
+ echo "Building $OS launcher. Defaults: -os $DEFAULT_OS -arch $DEFAULT_OS_ARCH -ws $DEFAULT_WS"
+ make -f $makefile clean
+ case x$CC in
+ x*gcc*) make -f $makefile all PICFLAG=-fpic ;;
+ *) make -f $makefile all ;;
+ esac
+ fi
+else
+ echo "Unknown OS ($OS) -- build aborted"
+fi
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/build.xml b/features/org.eclipse.equinox.executable.feature/library/motif/build.xml
new file mode 100644
index 000000000..990298e64
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/build.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="build_eclipse" basedir=".">
+
+<target name="build_eclipse">
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="install"/>
+ </exec>
+</target>
+
+<target name="clean">
+ <tstamp/>
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="clean"/>
+ </exec>
+</target>
+
+</project> \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.c b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.c
new file mode 100644
index 000000000..049cb7837
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.c
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ *******************************************************************************/
+
+
+/* UNIX/Motif specific logic for displaying the splash screen. */
+#include "eclipseCommon.h"
+#include "eclipseMozilla.h"
+#include "eclipseMotif.h"
+#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include "NgImage.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#ifdef SOLARIS
+#include <sys/filio.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <stdlib.h>
+
+/* Global Variables */
+char* defaultVM = "java";
+char* vmLibrary = "libjvm.so";
+char* shippedVMDir = "jre/bin/";
+
+/* Define the special arguments for the various Java VMs. */
+static char* argVM_JAVA[] = { NULL };
+#if AIX
+static char* argVM_JAVA_AIX131[] = { "-Xquickstart", NULL };
+#endif
+static char* argVM_J9[] = { "-jit", "-mca:1024", "-mco:1024", "-mn:256", "-mo:4096",
+ "-moi:16384", "-mx:262144", "-ms:16", "-mr:16", NULL };
+
+/* Define local variables for the main window. */
+extern XtAppContext appContext;
+extern Widget topWindow;
+
+static pid_t jvmProcess = 0;
+static int jvmExitCode;
+
+/* Define local variables for handling the splash window and its image. */
+static Widget shellHandle = 0;
+
+extern void centreShell( Widget widget, Widget expose );
+
+#ifdef NETSCAPE_FIX
+void fixEnvForNetscape();
+#endif /* NETSCAPE_FIX */
+
+void takeDownSplashCB( Widget shell, XtPointer app_data, XtPointer widget_data ) {
+ shellHandle = NULL;
+}
+
+/* Show the Splash Window
+ *
+ * Create the splash window, load the pixmap and display the splash window.
+ */
+int showSplash( const char* featureImage )
+{
+ int x, y;
+ unsigned int width, height, depth, border;
+ ArgList args;
+ unsigned int nArgs;
+ Pixmap splashPixmap = 0;
+ Window root;
+ Display *xDisplay;
+ Screen* screen;
+ Widget scrolledHandle, drawingHandle, image;
+
+ if (shellHandle != 0)
+ return 0; /* already showing splash */
+
+ if (initialArgv == NULL)
+ initialArgc = 0;
+
+ if (initWindowSystem(&initialArgc, initialArgv, 1) != 0) {
+ return -1;
+ }
+
+ xDisplay = motif_XtDisplay(topWindow);
+ screen = motif.XDefaultScreenOfDisplay( xDisplay );
+ if (featureImage != NULL)
+ {
+ splashPixmap = loadBMPImage(xDisplay, screen, (char*)featureImage);
+ }
+ /* If the splash image could not be found, return an error. */
+ if (splashPixmap == 0)
+ return ENOENT;
+
+ motif.XGetGeometry (xDisplay, splashPixmap, &root, &x, &y, &width, &height, &border, &depth);
+
+ /* make sure we never pass more than 20 args */
+ args = malloc(10 * sizeof(Arg));
+
+ nArgs = 0;
+ /* Note that XtSetArg is a macro, and the 1st argument will be evaluated twice
+ * so increment nArgs on its own */
+ motif_XtSetArg(args[nArgs], XmNmwmDecorations, 0); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNtitle, getOfficialName()); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNwidth, width); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNheight, height); nArgs++;
+ shellHandle = motif.XtAppCreateShell(getOfficialName(), "", *motif.applicationShellWidgetClass, xDisplay, args, nArgs);
+ motif.XtAddCallback(shellHandle, XmNdestroyCallback, (XtCallbackProc) takeDownSplashCB, NULL);
+
+ nArgs = 0;
+ motif_XtSetArg(args[nArgs++], XmNancestorSensitive, 1);
+ scrolledHandle = motif.XmCreateMainWindow(shellHandle, NULL, args, nArgs);
+ if(scrolledHandle == 0)
+ return -1;
+ motif.XtManageChild(scrolledHandle);
+
+ nArgs = 0;
+ motif_XtSetArg(args[nArgs], XmNancestorSensitive, 1); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNborderWidth, 0); nArgs++;
+ /*motif_XtSetArg(args[nArgs], XmNbackground, 0xFF00FF); nArgs++; */
+ motif_XtSetArg(args[nArgs], XmNmarginWidth, 0); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNmarginHeight, 0); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNresizePolicy, XmRESIZE_NONE); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNtraversalOn, 1); nArgs++;
+ drawingHandle = motif.XmCreateDrawingArea(scrolledHandle, NULL, args, nArgs);
+ if(drawingHandle == 0)
+ return -1;
+ motif.XtManageChild(drawingHandle);
+
+ nArgs = 0;
+ motif_XtSetArg(args[nArgs], XmNlabelType, XmPIXMAP); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNlabelPixmap, splashPixmap); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNwidth, width); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNheight, height); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNmarginWidth, 0); nArgs++;
+ motif_XtSetArg(args[nArgs], XmNmarginHeight, 0); nArgs++;
+ image = motif.XmCreateLabelGadget ( drawingHandle, "", args, nArgs );
+ motif.XtManageChild( image );
+
+ motif.XtRealizeWidget(shellHandle);
+ motif.XtSetMappedWhenManaged(shellHandle, 1);
+
+ if(motif_XtIsTopLevelShell(shellHandle))
+ motif_XtMapWidget(shellHandle);
+ else
+ motif.XtPopup(shellHandle, XtGrabNone);
+
+ /* Centre the splash screen and display it. */
+ centreShell( shellHandle, drawingHandle );
+ dispatchMessages();
+
+ free(args);
+ return 0;
+}
+
+/* Get the window system specific VM arguments */
+char** getArgVM( char* vm )
+{
+ char** result;
+
+#ifdef AIX
+ char* version;
+#endif
+
+ if (isJ9VM( vm ))
+ return argVM_J9;
+
+ /* Use the default arguments for a standard Java VM */
+ result = argVM_JAVA;
+
+#ifdef AIX
+ /* Determine whether Java version is 1.3.1 or later */
+ version = getVMVersion( vm );
+ if (version != NULL)
+ {
+ if (versionCmp(version, "1.3.1") >= 0)
+ result = argVM_JAVA_AIX131;
+ free(version);
+ }
+#endif
+
+ return result;
+}
+
+
+jlong getSplashHandle() {
+ return (jlong)shellHandle;
+}
+
+void dispatchMessages() {
+ XtInputMask mask;
+ if (appContext != NULL && motif.XtAppPending != 0) {
+ /* Process any outstanding messages */
+ while ((mask = motif.XtAppPending(appContext)) != 0) {
+ motif.XtAppProcessEvent(appContext, mask);
+ }
+ }
+}
+
+void takeDownSplash()
+{
+ if (shellHandle != 0)
+ {
+ motif.XtDestroyWidget( shellHandle );
+ /*XFlush( XtDisplay( shellHandle ) );*/
+ shellHandle = NULL;
+ }
+}
+
+#ifdef NETSCAPE_FIX
+extern char* findCommand( char*);
+static const char* XFILESEARCHPATH = "XFILESEARCHPATH";
+
+void fixEnvForNetscape()
+{
+ char* netscapePath = NULL;
+ char* netscapeResource = NULL;
+ char* ch;
+ char* envValue;
+ struct stat stats;
+
+ /* If netscape appears to be installed */
+ netscapePath = findCommand("netscape");
+ if (netscapePath != NULL)
+ {
+ /* Look for the resource file Netscape.ad in the same directory as "netscape". */
+ netscapeResource = malloc( strlen(netscapePath) + 50 );
+ strcpy( netscapeResource, netscapePath );
+ ch = strrchr( netscapeResource, (int) dirSeparator );
+ ch =(ch == NULL ? netscapeResource : (ch+1));
+ strcpy( ch, "Netscape.ad" );
+
+ /* If it does not exist there, try "/opt/netscape/Netscape.ad". */
+ if (stat( netscapeResource, &stats ) != 0)
+ {
+ strcpy( netscapeResource, "/opt/netscape/Netscape.ad" );
+ }
+
+ /* If the resource file exists */
+ if (stat( netscapeResource, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ {
+ /* Either define XFILESEARCHPATH or append the Netscape resource file. */
+ envValue = getenv( XFILESEARCHPATH );
+ if (envValue == NULL)
+ {
+ ch = malloc( strlen(XFILESEARCHPATH) + strlen(netscapeResource) + 5 );
+ sprintf( ch, "%s=%s", XFILESEARCHPATH, netscapeResource );
+ }
+ else
+ {
+ ch = malloc( strlen(XFILESEARCHPATH) + strlen(netscapeResource) +
+ strlen(envValue) + 5 );
+ sprintf( ch, "%s=%s:%s", XFILESEARCHPATH, envValue, netscapeResource );
+ }
+ putenv( ch );
+ free( ch );
+ }
+
+ /* Clean up. */
+ free( netscapePath );
+ free( netscapeResource );
+ }
+}
+#endif /* NETSCAPE_FIX */
+
+JavaResults* launchJavaVM( char* args[] )
+{
+ JavaResults* jvmResults = NULL;
+ int exitCode;
+
+#ifdef NETSCAPE_FIX
+ fixEnvForNetscape();
+#endif /* NETSCAPE_FIX */
+#ifdef MOZILLA_FIX
+ fixEnvForMozilla();
+#endif /* MOZILLA_FIX */
+
+#ifdef LINUX
+ {
+ /* put the root of eclipse on the LD_LIBRARY_PATH */
+ char * ldPath = (char*)getenv(_T_ECLIPSE("LD_LIBRARY_PATH"));
+ if (ldPath == NULL)
+ ldPath = _T_ECLIPSE("");
+ char * root = getProgramDir();
+ if (root != NULL) {
+ char * newPath = malloc((strlen(root) + strlen(ldPath) + 2) * sizeof(char));
+ sprintf(newPath, "%s%c%s", root, pathSeparator, ldPath);
+ setenv("LD_LIBRARY_PATH", newPath, 1);
+ free(newPath);
+ }
+ }
+#endif
+
+ /* Create a child process for the JVM. */
+ jvmProcess = fork();
+ if (jvmProcess == 0)
+ {
+ /* Child process ... start the JVM */
+ execv( args[0], args );
+
+ /* The JVM would not start ... return error code to parent process. */
+ /* TODO, how to distinguish this as a launch problem to the other process? */
+ jvmExitCode = errno;
+ exit( jvmExitCode );
+ }
+
+ jvmResults = malloc(sizeof(JavaResults));
+ memset(jvmResults, 0, sizeof(JavaResults));
+
+ /* If the JVM is still running, wait for it to terminate. */
+ if (jvmProcess != 0)
+ {
+ waitpid(jvmProcess, &exitCode, 0);
+ /* TODO, this should really be a runResult if we could distinguish the launch problem above */
+ jvmResults->launchResult = ((exitCode & 0x00ff) == 0 ? (exitCode >> 8) : exitCode); /* see wait(2) */
+ }
+
+ /* Return the exit code from the JVM. */
+ return jvmResults;
+}
+
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
+ /* not yet implemented on motif */
+ return -1;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.h b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.h
new file mode 100644
index 000000000..26b807b8a
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotif.h
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifndef ECLIPSE_MOTIF_H
+#define ECLIPSE_MOTIF_H
+
+#include <Xm/XmAll.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Intrinsic.h>
+#include <X11/Shell.h>
+
+#ifndef NO_XINERAMA_EXTENSIONS
+#include <X11/extensions/Xinerama.h>
+#endif
+
+struct MOTIF_PTRS {
+#ifndef NO_XINERAMA_EXTENSIONS
+ Bool (*XineramaIsActive) (Display*);
+ XineramaScreenInfo* (*XineramaQueryScreens) (Display*, int*);
+#endif
+ Widget (*XmCreateDrawingArea) (Widget, String, ArgList, Cardinal);
+ Widget (*XmCreateLabelGadget) (Widget, char *, Arg *, Cardinal);
+ Widget (*XmCreateMainWindow) (Widget, char *, ArgList, Cardinal);
+ Widget (*XmCreateMessageDialog)(Widget, String, ArgList, Cardinal);
+ Widget (*XmMessageBoxGetChild) (Widget, unsigned char);
+ void (*XmStringFree) (XmString);
+ XmString (*XmStringGenerate) (XtPointer, XmStringTag, XmTextType, XmStringTag);
+
+ void (*XtAddCallback) (Widget, String, XtCallbackProc, XtPointer);
+ Widget (*XtAppCreateShell) (String, String, WidgetClass, Display*, ArgList, Cardinal);
+ void (*XtAppNextEvent) (XtAppContext, XEvent*);
+ XtInputMask (*XtAppPending) (XtAppContext);
+ void (*XtAppProcessEvent) (XtAppContext, XtInputMask);
+ void (*XtDestroyWidget) (Widget);
+ Boolean (*XtDispatchEvent) (XEvent*);
+ void (*XtGetValues) (Widget, ArgList, Cardinal);
+ Widget (*XtInitialize) (String, String, XrmOptionDescRec*, Cardinal, int*, char**);
+#ifdef AIX
+ Widget (*eclipseXtInitialize) (String, String, XrmOptionDescRec*, Cardinal, int*, char**);
+#endif
+ Boolean (*XtIsManaged) (Widget);
+ void (*XtManageChild) (Widget);
+ int (*XtMapWidget) (Widget);
+ void (*XtPopup) (Widget, XtGrabKind);
+ void (*XtRealizeWidget) (Widget);
+ Widget (*XtSetLanguageProc) (XtAppContext, XtLanguageProc, XtPointer);
+ void (*XtSetMappedWhenManaged)(Widget, Boolean);
+ void (*XtSetValues) (Widget, ArgList, Cardinal);
+ void (*XtUnmanageChild) (Widget);
+ XtAppContext (*XtWidgetToApplicationContext) (Widget);
+ Window (*XtWindowOfObject) (Widget);
+
+ Screen * (*XDefaultScreenOfDisplay)(Display*);
+ int (*XFree) (void*);
+ int (*XFlush) (Display*);
+ Status (*XGetGeometry) (Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*);
+ int (*XMapWindow) (Display*, Window);
+
+ char * _XmStrings;
+ char * XtShellStrings;
+ char * XtStrings;
+ WidgetClass *applicationShellWidgetClass;
+};
+
+extern struct MOTIF_PTRS motif;
+
+#define motif_XtDisplay XtDisplay
+#define motif_XtSetArg XtSetArg
+#define motif_XtWindow XtWindow
+#define motif_XtIsTopLevelShell XtIsTopLevelShell
+#define motif_XtIsRealized(object) (motif.XtWindowOfObject(object) != None)
+#define motif_XtMapWidget(widget) motif.XMapWindow(XtDisplay(widget), XtWindow(widget))
+
+#define _XmStrings motif._XmStrings
+#define XtShellStrings motif.XtShellStrings
+#define XtStrings motif.XtStrings
+
+/* macro resolves to { (void**)&motif.foo, "foo" }, use it to initialize FN_TABLEs */
+#define FN_TABLE_ENTRY(fn) { (void**)&motif.fn, #fn }
+typedef struct {
+ void ** fnPtr;
+ char * fnName;
+} FN_TABLE;
+
+extern int loadMotif();
+#endif
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifCommon.c b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifCommon.c
new file mode 100644
index 000000000..93f21cbd3
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifCommon.c
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+#include "eclipseMotif.h"
+
+#include <locale.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#define ECLIPSE_ICON 401
+
+char dirSeparator = '/';
+char pathSeparator = ':';
+
+void centreShell( Widget widget, Widget expose );
+
+/* Global Variables */
+XtAppContext appContext = 0;
+Widget topWindow = 0;
+
+/* Define local variables for the main window. */
+static int saveArgc = 0; /* arguments after they were parsed, for window system */
+static char** saveArgv = 0;
+
+int motifInitialized = 0;
+
+/* Display a Message */
+void displayMessage( char* title, char* message )
+{
+ char* displayName = NULL;
+ Widget msgBox = NULL;
+ XmString msg;
+ Arg arg[20];
+ int nArgs;
+ XEvent event;
+
+ /* If there is no associated display, or we fail to initialize Xt, just print the error and return. */
+ displayName = getenv("DISPLAY");
+ if ( displayName == NULL || strlen(displayName) == 0 ||
+ (topWindow == 0 && initWindowSystem( &saveArgc, saveArgv, 1 ) != 0) )
+ {
+ printf("%s:\n%s\n", title, message);
+ return;
+ }
+ msg = motif.XmStringGenerate( message, NULL, XmCHARSET_TEXT, NULL );
+
+ /* Output a simple message box. */
+ nArgs = 0;
+
+ motif_XtSetArg( arg[ nArgs ], XmNdialogType, XmDIALOG_MESSAGE ); nArgs++;
+ motif_XtSetArg( arg[ nArgs ], XmNtitle, title ); nArgs++;
+ motif_XtSetArg( arg[ nArgs ], XmNmessageString, msg ); nArgs++;
+ msgBox = motif.XmCreateMessageDialog( topWindow, getOfficialName(), arg, nArgs );
+
+ motif.XtUnmanageChild( motif.XmMessageBoxGetChild( msgBox, XmDIALOG_CANCEL_BUTTON ) );
+ motif.XtUnmanageChild( motif.XmMessageBoxGetChild( msgBox, XmDIALOG_HELP_BUTTON ) );
+ motif.XtManageChild( msgBox );
+ centreShell( msgBox, msgBox );
+ if (msg != 0) motif.XmStringFree (msg);
+
+ /* Wait for the OK button to be pressed. */
+ while (motif_XtIsRealized( msgBox ) && motif.XtIsManaged( msgBox ))
+ {
+ motif.XtAppNextEvent( appContext, &event );
+ motif.XtDispatchEvent( &event );
+ }
+ motif.XtDestroyWidget( msgBox );
+}
+
+/* Initialize Window System
+ *
+ * Initialize the Xt and Xlib.
+ */
+int initWindowSystem( int* pArgc, char* argv[], int showSplash )
+{
+ Arg arg[20];
+ char * officialName;
+
+ if(motifInitialized == 1)
+ return 0;
+
+ if (loadMotif() != 0)
+ return -1;
+
+ /* Save the arguments in case displayMessage() is called in the main launcher. */
+ if (saveArgv == 0)
+ {
+ saveArgc = *pArgc;
+ saveArgv = argv;
+ }
+
+ officialName = getOfficialName();
+ if (officialName != NULL)
+ setenv("RESOURCE_NAME", getOfficialName(), 1);
+
+ /* Create the top level shell that will not be used other than
+ to initialize the application.
+ */
+#ifdef AIX
+ topWindow = motif.eclipseXtInitialize(NULL, officialName, NULL, 0, pArgc, argv);
+#else
+ topWindow = motif.XtInitialize(NULL, officialName, NULL, 0, pArgc, argv);
+#endif
+ appContext = motif.XtWidgetToApplicationContext(topWindow);
+ motif.XtSetLanguageProc (appContext, NULL, NULL);
+ motif_XtSetArg( arg[ 0 ], XmNmappedWhenManaged, False );
+ motif.XtSetValues( topWindow, arg, 1 );
+ motif.XtRealizeWidget( topWindow );
+ motifInitialized = 1;
+ return 0;
+}
+
+/* Centre the shell on the screen. */
+void centreShell( Widget widget, Widget expose )
+{
+ XtAppContext context;
+ XEvent event;
+ Arg arg[20];
+ int nArgs;
+ Position x, y;
+ Dimension width, height;
+ Screen* screen;
+ int waiting;
+ short screenWidth, screenHeight;
+
+#ifndef NO_XINERAMA_EXTENSIONS
+ Display* display;
+ int monitorCount;
+ XineramaScreenInfo* info;
+#endif
+
+ /* Realize the shell to calculate its width/height. */
+ motif.XtRealizeWidget( widget );
+
+ /* Get the desired dimensions of the shell. */
+ nArgs = 0;
+ motif_XtSetArg( arg[ nArgs ], XmNwidth, &width ); nArgs++;
+ motif_XtSetArg( arg[ nArgs ], XmNheight, &height ); nArgs++;
+ motif_XtSetArg( arg[ nArgs ], XmNscreen, &screen ); nArgs++;
+ motif.XtGetValues( widget, arg, nArgs );
+
+ screenWidth = screen->width;
+ screenHeight = screen->height;
+#ifndef NO_XINERAMA_EXTENSIONS
+ display = motif_XtDisplay( widget );
+ if (motif.XineramaIsActive != 0 && motif.XineramaIsActive( display )) {
+ info = motif.XineramaQueryScreens( display, &monitorCount );
+ if (info != 0) {
+ if (monitorCount > 1) {
+ screenWidth = info->width;
+ screenHeight = info->height;
+ }
+ motif.XFree (info);
+ }
+ }
+#endif
+
+ /* Calculate the X and Y position for the shell. */
+ x = (screenWidth - width) / 2;
+ y = (screenHeight - height) / 2;
+
+ /* Set the new shell position and display it. */
+ nArgs = 0;
+ motif_XtSetArg( arg[ nArgs ], XmNx, x ); nArgs++;
+ motif_XtSetArg( arg[ nArgs ], XmNy, y ); nArgs++;
+ motif.XtSetValues( widget, arg, nArgs );
+ motif_XtMapWidget( widget );
+
+ /* Wait for an expose event on the desired widget. This wait loop is required when
+ * the startVM command fails and the message box is created before the splash
+ * window is displayed. Without this wait, the message box sometimes appears
+ * under the splash window and the user cannot see it.
+ */
+ context = motif.XtWidgetToApplicationContext( widget );
+ waiting = True;
+ while (waiting)
+ {
+ motif.XtAppNextEvent( context, &event );
+ if (event.xany.type == Expose && event.xany.window == motif_XtWindow( expose ))
+ {
+ waiting = False;
+ }
+ motif.XtDispatchEvent( &event );
+ }
+ motif.XFlush( motif_XtDisplay( widget ) );
+}
+
+/* Load the specified shared library
+ */
+void * loadLibrary( char * library ){
+ void * result= dlopen(library, RTLD_LAZY);
+ if(result == 0)
+ printf("%s\n",dlerror());
+ return result;
+}
+
+/* Unload the shared library
+ */
+void unloadLibrary( void * handle ){
+ dlclose(handle);
+}
+
+/* Find the given symbol in the shared library
+ */
+void * findSymbol( void * handle, char * symbol ){
+ return dlsym(handle, symbol);
+}
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifInit.c b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifInit.c
new file mode 100644
index 000000000..c9ca22e7c
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifInit.c
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "eclipseMotif.h"
+#include "eclipseCommon.h"
+#include <dlfcn.h>
+#include <stdlib.h>
+
+struct MOTIF_PTRS motif;
+
+/* need to undef these so the FN_TABLE works ok */
+#undef _XmStrings
+#undef XtShellStrings
+#undef XtStrings
+
+/* functions from libXm */
+static FN_TABLE xmFunctions[] = { FN_TABLE_ENTRY(XmCreateDrawingArea),
+ FN_TABLE_ENTRY(XmCreateLabelGadget),
+ FN_TABLE_ENTRY(XmCreateMainWindow),
+ FN_TABLE_ENTRY(XmCreateMessageDialog),
+ FN_TABLE_ENTRY(XmMessageBoxGetChild),
+ FN_TABLE_ENTRY(XmStringFree),
+ FN_TABLE_ENTRY(XmStringGenerate),
+ FN_TABLE_ENTRY(_XmStrings), /* not a function */
+ { NULL, NULL }
+ };
+
+/* functions from libXt */
+static FN_TABLE xtFunctions[] = { FN_TABLE_ENTRY(XtAddCallback),
+ FN_TABLE_ENTRY(XtAppCreateShell),
+ FN_TABLE_ENTRY(XtAppNextEvent),
+ FN_TABLE_ENTRY(XtAppPending),
+ FN_TABLE_ENTRY(XtAppProcessEvent),
+ FN_TABLE_ENTRY(XtDestroyWidget),
+ FN_TABLE_ENTRY(XtDispatchEvent),
+ FN_TABLE_ENTRY(XtGetValues),
+#ifndef AIX
+ FN_TABLE_ENTRY(XtInitialize),
+#endif
+ FN_TABLE_ENTRY(XtIsManaged),
+ FN_TABLE_ENTRY(XtManageChild),
+ FN_TABLE_ENTRY(XtMapWidget),
+ FN_TABLE_ENTRY(XtPopup),
+ FN_TABLE_ENTRY(XtRealizeWidget),
+ FN_TABLE_ENTRY(XtSetLanguageProc),
+ FN_TABLE_ENTRY(XtSetMappedWhenManaged),
+ FN_TABLE_ENTRY(XtSetValues),
+ FN_TABLE_ENTRY(XtUnmanageChild),
+ FN_TABLE_ENTRY(XtWidgetToApplicationContext),
+ FN_TABLE_ENTRY(XtWindowOfObject),
+ FN_TABLE_ENTRY(XtShellStrings), /* not a function */
+ FN_TABLE_ENTRY(XtStrings), /* not a function */
+ FN_TABLE_ENTRY(applicationShellWidgetClass), /* not a function */
+ { NULL, NULL }
+ };
+
+#ifdef AIX
+static FN_TABLE shimFunctions[] = { FN_TABLE_ENTRY(eclipseXtInitialize), {NULL, NULL} };
+#endif
+
+/* functions from libX11 */
+static FN_TABLE x11Functions[] = { FN_TABLE_ENTRY(XDefaultScreenOfDisplay),
+ FN_TABLE_ENTRY(XFree),
+ FN_TABLE_ENTRY(XFlush),
+ FN_TABLE_ENTRY(XGetGeometry),
+ FN_TABLE_ENTRY(XMapWindow),
+ { NULL, NULL }
+ };
+
+#ifndef NO_XINERAMA_EXTENSIONS
+static FN_TABLE xinFunctions[] = { FN_TABLE_ENTRY(XineramaIsActive),
+ FN_TABLE_ENTRY(XineramaQueryScreens),
+ { NULL, NULL }
+ };
+#endif
+
+static int loadMotifSymbols( void * library, FN_TABLE * table) {
+ int i = 0;
+ void * fn;
+ for (i = 0; table[i].fnName != NULL; i++) {
+ fn = findSymbol(library, table[i].fnName);
+ if (fn != 0) {
+ *(table[i].fnPtr) = fn;
+ } else {
+ *(table[i].fnPtr) = 0;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+#ifdef AIX
+void * loadMotifShimLibrary() {
+ if (eclipseLibrary != NULL) {
+ /* library is the normal eclipse_<ver>.so, look for libeclipse-motif.so beside it */
+ _TCHAR* eclipseMotifLib = _T_ECLIPSE("libeclipse-motif.so");
+ _TCHAR* path = strdup(eclipseLibrary);
+ _TCHAR* c = strrchr(path, '/');
+ if (c == NULL) {
+ free(path);
+ return NULL;
+ }
+
+ *c = 0;
+ c = malloc((strlen(path) + 2 + strlen(eclipseMotifLib)) * sizeof(char));
+ _stprintf(c, _T_ECLIPSE("%s/%s"), path, eclipseMotifLib);
+ free(path);
+ return dlopen(c, RTLD_LAZY);
+ }
+ return 0;
+}
+#endif
+
+int loadMotif() {
+ void * xmLib = NULL, *xtLib = NULL, *x11Lib = NULL, *xinLib = NULL;
+#ifdef AIX
+ void * motifShim = NULL;
+#endif
+ char * path = getProgramDir();
+ int dlFlags = RTLD_LAZY;
+
+ /* initialize ptr struct to 0's */
+ memset(&motif, 0, sizeof(struct MOTIF_PTRS));
+
+#ifndef AIX
+ if (path != NULL) {
+ /* look for libXm first in the root of eclipse */
+ char * lib = malloc((strlen(path) + strlen(_T_ECLIPSE(XM_LIB)) + 2) * sizeof(char));
+ sprintf( lib, "%s%c%s", path, dirSeparator, XM_LIB);
+ xmLib = dlopen(lib, dlFlags);
+ free(lib);
+ }
+#else
+ dlFlags |= RTLD_MEMBER;
+ motifShim = loadMotifShimLibrary();
+ if (motifShim == NULL)
+ return -1;
+#endif
+
+ if (xmLib == NULL) {
+ xmLib = dlopen(XM_LIB, dlFlags);
+ }
+
+ if (xmLib == NULL) {
+ /* bail now, don't load the others, libXm must be loaded first, so leave things for
+ * swt to do later */
+ return -1;
+ }
+
+ xtLib = dlopen(XT_LIB, dlFlags);
+ x11Lib = dlopen(X11_LIB, dlFlags);
+
+ /* printf("XmLib: %s: %x\nXtLib: %s: %x\nX11Lib:%s, %x\n", XM_LIB, xmLib, XT_LIB, xtLib, X11_LIB, x11Lib);*/
+#ifndef NO_XINERAMA_EXTENSIONS
+ /* don't fail without Xinerama */
+ xinLib = dlopen(XIN_LIB, dlFlags);
+ if (xinLib != NULL)
+ loadMotifSymbols(xinLib, xinFunctions);
+#endif
+ if( xtLib == NULL || x11Lib == NULL)
+ return -1;
+
+ if (loadMotifSymbols(xmLib, xmFunctions) != 0) return -1;
+ if (loadMotifSymbols(xtLib, xtFunctions) != 0) return -1;
+ if (loadMotifSymbols(x11Lib, x11Functions) != 0) return -1;
+#ifdef AIX
+ if (loadMotifSymbols(motifShim, shimFunctions) !=0) return -1;
+#endif
+
+ return 0;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifShim.c b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifShim.c
new file mode 100644
index 000000000..2648ec65e
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/eclipseMotifShim.c
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <Xm/XmAll.h>
+
+Widget eclipseXtInitialize(String shellName, String appClass, XrmOptionDescRec* options, Cardinal numOptions, int* argc, char** argv) {
+ return XtInitialize(shellName, appClass, options, numOptions, argc, argv);
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/make_aix.mak b/features/org.eclipse.equinox.executable.feature/library/motif/make_aix.mak
new file mode 100644
index 000000000..1d4689e1c
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/make_aix.mak
@@ -0,0 +1,104 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the AIX/Motif eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the filename of the output library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# X11_HOME - the full path to X11 header files
+# MOTIF_HOME - the full path to Motif header files
+# JAVA_JNI - the full path to the java jni header files
+
+PROGRAM_OUTPUT=eclipse
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+SHIM=libeclipse-motif.so
+
+CC = gcc
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o
+SHIM_OBJS = eclipseMotifShim.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseMotifCommon.o eclipseMotifInit.o
+DLL_OBJS = eclipse.o eclipseMotif.o eclipseUtil.o eclipseJNI.o eclipseShm.o eclipseNix.o\
+ NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -L$(MOTIF_HOME)/lib -ldl
+SHIM_LIBS = -L$(MOTIF_HOME)/lib -lXm -lXt -lX11
+MOTIF_LIBS = -DXM_LIB="\"libXm.a(shr_32.o)\"" -DXT_LIB="\"libXt.a(shr4.o)\"" -DX11_LIB="\"libX11.a(shr4.o)\""
+LFLAGS = -G -bnoentry -bexpall -lm -lc_r -lC_r
+CFLAGS = -O -s \
+ -DMOTIF \
+ -DNO_XINERAMA_EXTENSIONS \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ $(MOTIF_LIBS) \
+ -DAIX \
+ -I./ \
+ -I../ \
+ -I$(MOTIF_HOME)/include \
+ -I/usr/java5/include
+
+all: $(EXEC) $(DLL) $(SHIM)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -Wl,-bM:UR -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+ sedmgr -c exempt $(EXEC)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ ld $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(SHIM): $(SHIM_OBJS)
+ ld $(LFLAGS) -o $(SHIM) $(SHIM_OBJS) $(SHIM_LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(SHIM) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(DLL) $(SHIM) $(SHIM_OBJS) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_PA_RISC.mak b/features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_PA_RISC.mak
new file mode 100644
index 000000000..2552b56fc
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_PA_RISC.mak
@@ -0,0 +1,94 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the HPUX/Motif eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# X11_HOME - the full path to X11 header files
+# MOTIF_HOME - the full path to Motif header files
+
+ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+endif
+
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseMotifCommon.o
+DLL_OBJS = eclipse.o eclipseMotif.o eclipseUtil.o eclipseJNI.o eclipseNix.o eclipseShm.o\
+ NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lXm -lXt -lX11 -lpthread
+LFLAGS = -shared -Wl,--export-dynamic
+CFLAGS = -O -s \
+ -DNO_XINERAMA_EXTENSIONS \
+ -DNETSCAPE_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ +Z \
+ -I./ \
+ -I../ \
+ -I$(MOTIF_HOME)/include \
+ -I$(X11_HOME)/include \
+ -I$(JAVA_JNI) \
+ +DAportable
+
+all: $(EXEC)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(DLL) $(OUTPUT_DIR)
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_ia64_32.mak b/features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_ia64_32.mak
new file mode 100644
index 000000000..92667dac0
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/make_hpux_ia64_32.mak
@@ -0,0 +1,101 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Sumit Sarkar (Hewlett-Packard)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the HPUX/Motif eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# X11_HOME - the full path to X11 header files
+# MOTIF_HOME - the full path to Motif header files
+
+#ifeq ($(PROGRAM_OUTPUT),)
+# PROGRAM_OUTPUT=eclipse
+#endif
+
+DEFAULT_JAVA=DEFAULT_JAVA_EXEC
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+CC=gcc
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseMotifCommon.o eclipseMotifInit.o
+DLL_OBJS = eclipse.o eclipseMotif.o eclipseUtil.o eclipseJNI.o eclipseNix.o eclipseShm.o \
+ NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lpthread
+MOTIF_LIBS = -DXM_LIB="\"libXm.so.1\"" -DXT_LIB="\"libXt.so.1\"" -DX11_LIB="\"libX11.so.1\""
+LFLAGS = -shared -static-libgcc
+# -Wl,--export-dynamic
+CFLAGS = -O -s \
+ -DNO_XINERAMA_EXTENSIONS \
+ -DNETSCAPE_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -D$(DEFAULT_JAVA) \
+ -DHPUX \
+ $(MOTIF_LIBS) \
+ -I./ \
+ -I../ \
+ -I$(MOTIF_HOME)/include \
+ -I$(X11_HOME)/include \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/hp-ux
+
+all: $(EXEC) $(DLL)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o $@
+
+eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/make_linux.mak b/features/org.eclipse.equinox.executable.feature/library/motif/make_linux.mak
new file mode 100644
index 000000000..a29d1b9b6
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/make_linux.mak
@@ -0,0 +1,108 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the Linux/Motif eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the filename of the output library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# X11_HOME - the full path to X11 header files
+# MOTIF_HOME - the full path to Motif header files
+# JAVA_HOME - JAVA_HOME for the java jni header files
+
+ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+endif
+
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+ifeq ($(DEFAULT_JAVA),)
+ DEFAULT_JAVA=DEFAULT_JAVA_JNI
+endif
+
+# Define the object modules to be compiled and flags.
+CC?=gcc
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseMotifCommon.o eclipseMotifInit.o
+DLL_OBJS = eclipse.o eclipseMotif.o eclipseUtil.o eclipseJNI.o eclipseMozilla.o eclipseShm.o eclipseNix.o \
+ NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -Xlinker -rpath -Xlinker . -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lpthread -ldl
+MOTIF_LIBS = -DXM_LIB="\"libXm.so.2\"" -DXT_LIB="\"libXt.so.6\"" -DX11_LIB="\"libX11.so.6\"" -DXIN_LIB="\"libXinerama.so.1\""
+LFLAGS = -shared -fpic -Wl,--export-dynamic
+CFLAGS = -g -s -Wall \
+ -DLINUX \
+ -DMOTIF \
+ -DMOZILLA_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ $(MOTIF_LIBS) \
+ -D$(DEFAULT_JAVA)\
+ -fPIC \
+ -I./ \
+ -I../ \
+ -I$(MOTIF_HOME)/include \
+ -I$(X11_HOME)/include \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
+
+all: $(EXEC) $(DLL)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseMozilla.o: ../eclipseMozilla.c ../eclipseMozilla.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/motif/make_solaris.mak b/features/org.eclipse.equinox.executable.feature/library/motif/make_solaris.mak
new file mode 100644
index 000000000..3438ce369
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/motif/make_solaris.mak
@@ -0,0 +1,104 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Martin Oberhuber (Wind River) - [185734] Support building with gcc and debug
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the Solaris/Motif eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# X11_HOME - the full path to X11 header files
+# MOTIF_HOME - the full path to Motif header files
+# JAVA_HOME - path to java for JNI headers
+
+#ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse
+#endif
+
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).so
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseMotifCommon.o eclipseMotifInit.o
+DLL_OBJS = eclipse.o eclipseMotif.o eclipseUtil.o eclipseJNI.o eclipseShm.o eclipseNix.o\
+ NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o
+PICFLAG = -K PIC
+# Optimize and remove all debugging information by default
+OPTFLAG = -O -s
+# OPTFLAG = -g
+
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lintl -lthread -ldl -lc
+MOTIF_LIBS = -DXM_LIB="\"libXm.so.4\"" -DXT_LIB="\"libXt.so.4\"" -DX11_LIB="\"libX11.so.4\"" -DXIN_LIB="\"libXinerama.so.1\""
+#LFLAGS = -shared -Wl,--export-dynamic
+LFLAGS = -G
+CFLAGS =$(OPTFLAG) \
+ -DSOLARIS \
+ $(PICFLAG) \
+ -DNO_XINERAMA_EXTENSIONS \
+ -DNETSCAPE_FIX \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ $(MOTIF_LIBS) \
+ -I./ \
+ -I../ \
+ -I$(MOTIF_HOME)/include \
+ -I$(X11_HOME)/include \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/solaris
+
+all: $(EXEC) $(DLL)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h
+ $(CC) $(CFLAGS) -c ../eclipseMain.c -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h
+ $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h
+ $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+eclipseNix.o: ../eclipseNix.c
+ $(CC) $(CFLAGS) -c ../eclipseNix.c -o $@
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ cp $(DLL) $(LIBRARY_DIR)
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
+
+clean:
+ rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/photon/.cvsignore b/features/org.eclipse.equinox.executable.feature/library/photon/.cvsignore
new file mode 100644
index 000000000..5535df034
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/photon/.cvsignore
@@ -0,0 +1,2 @@
+*.o
+eclipse
diff --git a/features/org.eclipse.equinox.executable.feature/library/photon/build.sh b/features/org.eclipse.equinox.executable.feature/library/photon/build.sh
new file mode 100644
index 000000000..43ef9b167
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/photon/build.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+#*******************************************************************************
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+#
+# Usage: sh build.sh [<optional switches>] [clean]
+#
+# where the optional switches are:
+# -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+# -os <DEFAULT_OS> - default Eclipse "-os" value
+# -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value
+# -ws <DEFAULT_WS> - default Eclipse "-ws" value
+#
+#
+# This script can also be invoked with the "clean" argument.
+
+cd `dirname $0`
+
+# Define default values for environment variables used in the makefiles.
+programOutput="eclipse"
+defaultOS="qnx"
+defaultOSArch="x86"
+defaultWS="photon"
+makefile="make_qnx.mak"
+if [ "$OS" = "" ]; then
+ OS=`uname -s`
+fi
+
+# Parse the command line arguments and override the default values.
+extraArgs=""
+while [ "$1" != "" ]; do
+ if [ "$1" = "-os" ] && [ "$2" != "" ]; then
+ defaultOS="$2"
+ shift
+ elif [ "$1" = "-arch" ] && [ "$2" != "" ]; then
+ defaultOSArch="$2"
+ shift
+ elif [ "$1" = "-ws" ] && [ "$2" != "" ]; then
+ defaultWS="$2"
+ shift
+ elif [ "$1" = "-output" ] && [ "$2" != "" ]; then
+ programOutput="$2"
+ shift
+ else
+ extraArgs="$extraArgs $1"
+ fi
+ shift
+done
+
+# Set up environment variables needed by the makefiles.
+PROGRAM_OUTPUT="$programOutput"
+DEFAULT_OS="$defaultOS"
+DEFAULT_OS_ARCH="$defaultOSArch"
+DEFAULT_WS="$defaultWS"
+EXEC_DIR=../../../../../rt.equinox.binaries/org.eclipse.equinox.executable
+OUTPUT_DIR="$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch"
+
+export OUTPUT_DIR PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS
+
+# If the OS is supported (a makefile exists)
+if [ "$makefile" != "" ]; then
+ if [ "$extraArgs" != "" ]; then
+ make -f $makefile $extraArgs
+ else
+ echo "Building $OS launcher. Defaults: -os $DEFAULT_OS -arch $DEFAULT_OS_ARCH -ws $DEFAULT_WS"
+ make -f $makefile clean
+ make -f $makefile all
+ fi
+else
+ echo "Unknown OS ($OS) -- build aborted"
+fi
diff --git a/features/org.eclipse.equinox.executable.feature/library/photon/build.xml b/features/org.eclipse.equinox.executable.feature/library/photon/build.xml
new file mode 100644
index 000000000..990298e64
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/photon/build.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="build_eclipse" basedir=".">
+
+<target name="build_eclipse">
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="install"/>
+ </exec>
+</target>
+
+<target name="clean">
+ <tstamp/>
+ <exec dir="." executable="sh">
+ <arg line="${basedir}/build.sh"/>
+ <arg line="clean"/>
+ </exec>
+</target>
+
+</project> \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/photon/eclipsePhoton.c b/features/org.eclipse.equinox.executable.feature/library/photon/eclipsePhoton.c
new file mode 100644
index 000000000..e5dfbd2a1
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/photon/eclipsePhoton.c
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ *******************************************************************************/
+
+/* Photon specific logic for displaying the splash screen. */
+
+#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include <Pt.h>
+
+#define PX_IMAGE_MODULES
+#define PX_BMP_SUPPORT
+
+#include <photon/PxImage.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <libgen.h>
+
+/* Global Variables */
+char dirSeparator = '/';
+char pathSeparator = ':';
+#ifndef J9VM
+char* defaultVM = "java";
+char* shippedVMDir = "jre/bin/";
+#else
+char* defaultVM = "j9";
+char* shippedVMDir = "ive/bin/";
+#endif
+
+/* Define the window system arguments for the various Java VMs. */
+static char* argVM_JAVA[] = { NULL };
+static char* argVM_J9[] = { "-jit", "-ms:32", "-mso:256", NULL };
+
+
+/* Define local variables for the main window. */
+static PtWidget_t* topWindow = NULL;
+
+/* Define local variables for running the JVM and detecting its exit. */
+static pid_t jvmProcess = 0;
+static int jvmExitCode;
+
+/* Local functions */
+static void bringDownSplashWindow( int );
+static void centreWindow( PtWidget_t *widget, PtWidget_t *label);
+static int splashTimeout( PtWidget_t* widget, void* data, PtCallbackInfo_t* id );
+
+/* Display a Message */
+void displayMessage( char* title, char* message )
+{
+ if (topWindow == 0)
+ {
+ initWindowSystem( NULL, NULL, 0 );
+ }
+
+ PtNotice( NULL,NULL, title, NULL, message, NULL, NULL, NULL, Pt_CENTER | Pt_MODAL );
+}
+
+
+/* Initialize Window System
+ *
+ * Initialize Photon.
+ */
+void initWindowSystem( int* pArgc, char* argv[], int showSplash )
+{
+ PtArg_t arg[5];
+ int nArgs;
+
+ /* Create a top level window with no decorations. */
+ setlocale(LC_ALL, "");
+ PtInit( NULL );
+ nArgs = 0;
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_RENDER_FLAGS, 0, ~0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_MANAGED_FLAGS, Ph_WM_TASKBAR | Ph_WM_CLOSE, ~0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_STATE, Ph_WM_STATE_ISFRONT, ~0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_TITLE, getOfficialName(), ~0 );
+ topWindow = PtCreateWidget( PtWindow, Pt_NO_PARENT, nArgs, arg );
+}
+
+
+/* Show the Splash Window
+ *
+ * Create the splash window, load the bitmap and display the splash window.
+ *
+ */
+int showSplash( char* timeoutString, char* featureImage )
+{
+ int timeout = 0;
+ PtWidget_t* label;
+ PtArg_t arg[10];
+ PhImage_t* image = NULL;
+ int nArgs;
+ int depth;
+ PgDisplaySettings_t settings;
+ PgVideoModeInfo_t mode_info;
+
+ /* Determine the splash timeout value (in seconds). */
+ if (timeoutString != NULL && strlen( timeoutString ) > 0)
+ {
+ sscanf( timeoutString, "%d", &timeout );
+ }
+
+ /* Install a signal handler to catch SIGUSR2 (which will shut down the window). */
+ signal( SIGUSR2, bringDownSplashWindow );
+
+ /* Load the splash image from the feature directory. */
+ PgGetVideoMode( &settings );
+ PgGetVideoModeInfo( settings.mode, &mode_info );
+ depth = mode_info.bits_per_pixel;
+ if (featureImage != NULL)
+ image = PxLoadImage( featureImage, NULL );
+
+ /* If the splash image could not be found, return an error. */
+ if (image == NULL)
+ return ENOENT;
+
+ /* Create a label widget (only child of top window) with the image. */
+ nArgs = 0;
+ image->flags |= Ph_RELEASE_IMAGE_ALL;
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_LABEL_TYPE, Pt_IMAGE, 0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_LABEL_IMAGE, image, 0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_TEXT_STRING, officialName, 0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_MARGIN_WIDTH, 0, 0 );
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_MARGIN_HEIGHT, 0, 0 );
+ label = PtCreateWidget( PtLabel, topWindow, nArgs, arg );
+
+ /* Free the image */
+ free( image );
+
+ /* Centre the splash window and display it. */
+ centreWindow( topWindow, label );
+
+ /* If a timeout for the splash window was given */
+ if (timeout != 0)
+ {
+ PtAddEventHandler( topWindow, Ph_EV_TIMER, splashTimeout, NULL );
+ PtTimerArm( topWindow, (timeout * 1000) );
+ }
+
+ /* Process messages until the splash window is closed or process is terminated. */
+ while (PtWidgetIsRealized( topWindow ))
+ {
+ PtProcessEvent();
+ }
+
+ /* Destroy the splash window. */
+ PtDestroyWidget( topWindow );
+ topWindow = 0;
+
+ return 0;
+}
+
+
+/* Get the window system specific VM arguments */
+char** getArgVM( char* vm )
+{
+ return (isJ9VM( vm ) ? argVM_J9 : argVM_JAVA);
+}
+
+void fixEnvForJ9( char* vm ) {
+ if (isJ9VM( vm )) {
+ char *ldpath;
+ char newpath[PATH_MAX+1];
+
+ ldpath = getenv( "LD_LIBRARY_PATH" );
+
+ /* Always dup the string so we can free later */
+ if( ldpath != NULL )
+ ldpath = strdup( ldpath );
+ else
+ ldpath = strdup( "" );
+
+ /* Get the j9 binary location */
+ strncpy( newpath, vm, PATH_MAX );
+ dirname( newpath );
+
+ /* Add j9 binary location to LD_LIBRARY_PATH */
+ ldpath = realloc( ldpath, strlen( ldpath ) + strlen( newpath ) + 2 );
+ if( ldpath != NULL )
+ {
+ strcat( ldpath, ":" );
+ strcat( ldpath, newpath );
+ }
+
+ setenv( "LD_LIBRARY_PATH", ldpath, 1 );
+
+ free( ldpath );
+ }
+}
+
+/* Start the Java VM
+ *
+ * This method is called to start the Java virtual machine and to wait until it
+ * terminates. The function returns the exit code from the JVM.
+ */
+int startJavaVM( char* args[] )
+{
+ int exitCode;
+
+ fixEnvForJ9 (args [0]);
+
+ /* Create a child process for the JVM. */
+ jvmProcess = fork();
+ if (jvmProcess == 0)
+ {
+ /* Child process ... start the JVM */
+ execv( args[0], args );
+
+ /* The JVM would not start ... return error code to parent process. */
+ jvmExitCode = errno;
+ exit( jvmExitCode );
+ }
+
+ /* If the JVM is still running, wait for it to terminate. */
+ if (jvmProcess != 0)
+ {
+ wait( &exitCode );
+ jvmExitCode = ((exitCode & 0x00ff) == 0 ? (exitCode >> 8) : exitCode); /* see wait(2) */
+ }
+
+ /* Return the exit code from the JVM. */
+ return jvmExitCode;
+}
+
+/*------ Local functions -----*/
+
+
+/* Catch a signal that indicates the splash window is to be brought down. */
+static void bringDownSplashWindow( int sig )
+{
+ if (topWindow != 0)
+ {
+ PtUnrealizeWidget( topWindow );
+ }
+}
+
+
+/* Centre the top window on the screen. */
+
+static void centreWindow( PtWidget_t* window, PtWidget_t* expose )
+{
+ PtArg_t arg[2];
+ int nArgs;
+ PhPoint_t pos;
+ PhArea_t area;
+ PhRect_t rect;
+ int width, height;
+
+ /* Realize the top window to calculate its width/height. */
+ PtExtentWidgetFamily( window );
+
+ /* Get the desired dimensions of the window. */
+ PtWidgetArea( window, &area );
+
+ /* Calculate the X and Y position for the window. */
+ PhWindowQueryVisible( Ph_QUERY_WORKSPACE, 0, PhInputGroup(0), &rect );
+ width = rect.lr.x - rect.ul.x + 1;
+ height = rect.lr.y - rect.ul.y + 1;
+ pos.x = rect.ul.x + (width - area.size.w) / 2;
+ pos.y = rect.ul.y + (height - area.size.h) / 2;
+
+ /* Set the new shell position and display it. */
+ nArgs = 0;
+ PtSetArg( &arg[ nArgs++ ], Pt_ARG_POS, &pos, 0 );
+ PtSetResources( window, nArgs, arg );
+ PtRealizeWidget( window );
+}
+
+
+/* Splash Timeout */
+static int splashTimeout( PtWidget_t* widget, void* data, PtCallbackInfo_t* info )
+{
+ bringDownSplashWindow( 0 );
+ return 1;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/photon/make_qnx.mak b/features/org.eclipse.equinox.executable.feature/library/photon/make_qnx.mak
new file mode 100644
index 000000000..475cf48a3
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/photon/make_qnx.mak
@@ -0,0 +1,57 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+
+# Makefile for creating the Photon eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+
+# Define the object modules to be compiled and flags.
+OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipsePhoton.o
+EXEC = $(PROGRAM_OUTPUT)
+LIBS = -lph -lphrender -lphexlib
+CFLAGS = -O -s -Wall \
+ -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -DJ9VM -I.. -DPHOTON
+
+all: $(EXEC)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+eclipse.o: ../eclipse.c ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipse.c -o $@
+
+eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseShm.c -o $@
+
+eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@
+
+eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h
+ $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@
+
+$(EXEC): $(OBJS)
+ $(CC) -o $(EXEC) $(OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(OUTPUT_DIR)
+ rm -f $(EXEC) $(OBJS)
+
+clean:
+ rm -f $(EXEC) $(OBJS)
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/.cvsignore b/features/org.eclipse.equinox.executable.feature/library/win32/.cvsignore
new file mode 100644
index 000000000..431170f6f
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/.cvsignore
@@ -0,0 +1,8 @@
+*.obj
+eclipse.exe
+eclipse.res
+*.pdb
+*.exp
+*.lib
+eclipse_*.dll
+eclipsec.exe
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/build.bat b/features/org.eclipse.equinox.executable.feature/library/win32/build.bat
new file mode 100644
index 000000000..81f5afcd1
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/build.bat
@@ -0,0 +1,156 @@
+@rem *******************************************************************************
+@rem Copyright (c) 2000, 2009 IBM Corporation and others.
+@rem All rights reserved. This program and the accompanying materials
+@rem are made available under the terms of the Eclipse Public License v1.0
+@rem which accompanies this distribution, and is available at
+@rem http://www.eclipse.org/legal/epl-v10.html
+@rem
+@rem Contributors:
+@rem IBM Corporation - initial API and implementation
+@rem Kevin Cornell (Rational Software Corporation)
+@rem **********************************************************************
+@rem
+@rem Usage: sh build.sh [<optional switches>] [clean]
+@rem
+@rem where the optional switches are:
+@rem -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+@rem -library <PROGRAM_LIBRARY>- dll filename (eclipse.dll)
+@rem -os <DEFAULT_OS> - default Eclipse "-os" value (qnx)
+@rem -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value (x86)
+@rem -ws <DEFAULT_WS> - default Eclipse "-ws" value (photon)
+@rem -java <JAVA_HOME> - location of a Java SDK for JNI headers
+@rem
+@rem
+@rem This script can also be invoked with the "clean" argument.
+@rem
+@rem NOTE: The C compiler needs to be setup. This script has been
+@rem tested against Microsoft Visual C and C++ Compiler 6.0.
+@rem
+@rem Uncomment the lines below and edit MSVC_HOME to point to the
+@rem correct root directory of the compiler installation, if you
+@rem want this to be done by this script.
+@rem
+@rem ******
+@echo off
+
+IF EXIST C:\BUILD\swt-builddir set LAUNCHER_BUILDDIR=C:\BUILD\swt-builddir
+IF x.%LAUNCHER_BUILDDIR%==x. set LAUNCHER_BUILDDIR=S:\swt-builddir
+echo LAUNCHER build dir: %LAUNCHER_BUILDDIR%
+
+IF x.%1==x.x86_64 GOTO X86_64
+IF x.%1==x.ia64 GOTO IA64
+
+:X86
+IF x.%DEV_TOOLS%==x. set DEV_TOOLS=%LAUNCHER_BUILDDIR%
+IF x.%JAVA_HOME%==x. set JAVA_HOME=%LAUNCHER_BUILDDIR%\ibm-java2-sdk-50-win-i386
+set javaHome=%JAVA_HOME%
+if not x.%MSVC_HOME% == x. goto MAKE
+set MSVC_HOME="%LAUNCHER_BUILDDIR%\MSVCs\msvc60\VC98"
+call %MSVC_HOME%\bin\vcvars32.bat
+if not "%MSSDK%" == "" goto MAKE
+set MSSDK="%LAUNCHER_BUILDDIR%\MSSDKs\feb2003"
+call %MSSDK%\setenv.bat
+IF x.%1==x.x86 shift
+set defaultOSArch=x86
+set makefile=make_win32.mak
+GOTO MAKE
+
+:X86_64
+shift
+set defaultOSArch=x86_64
+IF x.%JAVA_HOME%==x. set JAVA_HOME=%LAUNCHER_BUILDDIR%\ibm-sdk50-x86_64
+IF "x.%MSSDK%" == "x." set MSSDK="%LAUNCHER_BUILDDIR%\MSSDKs\Windows Server 2003 SP1 SDK"
+set javaHome=%JAVA_HOME%
+set makefile=make_win64.mak
+call %MSSDK%\setenv /X64 /RETAIL
+GOTO MAKE
+
+:IA64
+shift
+set defaultOSArch=ia64
+IF x.%JAVA_HOME%==x. set JAVA_HOME=%LAUNCHER_BUILDDIR%\ibm-sdk142-ia64
+IF "x.%MSSDK%" == "x." set MSSDK="%LAUNCHER_BUILDDIR%\MSSDKs\Windows Server 2003 SP1 SDK"
+set javaHome=%JAVA_HOME%
+set makefile=make_win64_ia64.mak
+call %MSSDK%\setenv /SRV64 /RETAIL
+GOTO MAKE
+
+:MAKE
+rem --------------------------
+rem Define default values for environment variables used in the makefiles.
+rem --------------------------
+set programOutput=eclipse.exe
+set programLibrary=eclipse.dll
+set defaultOS=win32
+set defaultWS=win32
+set OS=Windows
+
+rem --------------------------
+rem Parse the command line arguments and override the default values.
+rem --------------------------
+set extraArgs=
+:WHILE
+if "%1" == "" goto WHILE_END
+ if "%2" == "" goto LAST_ARG
+
+ if "%1" == "-os" (
+ set defaultOS=%2
+ shift
+ goto NEXT )
+ if "%1" == "-arch" (
+ set defaultOSArch=%2
+ shift
+ goto NEXT )
+ if "%1" == "-ws" (
+ set defaultWS=%2
+ shift
+ goto NEXT )
+ if "%1" == "-output" (
+ set programOutput=%2
+ shift
+ goto NEXT )
+ if "%1" == "-library" (
+ set programLibrary=%2
+ shift
+ goto NEXT )
+ if "%1" == "-java" (
+ set javaHome=%2
+ echo %javaHome%
+ shift
+ goto NEXT )
+:LAST_ARG
+ set extraArgs=%extraArgs% %1
+
+:NEXT
+ shift
+ goto WHILE
+:WHILE_END
+
+rem --------------------------
+rem Set up environment variables needed by the makefile.
+rem --------------------------
+set PROGRAM_OUTPUT=%programOutput%
+set PROGRAM_LIBRARY=%programLibrary%
+set DEFAULT_OS=%defaultOS%
+set DEFAULT_OS_ARCH=%defaultOSArch%
+set DEFAULT_WS=%defaultWS%
+set EXEC_DIR=..\..\.\..\..\rt.equinox.binaries\org.eclipse.equinox.executable
+set OUTPUT_DIR=%EXEC_DIR%\bin\%defaultWS%\%defaultOS%\%defaultOSArch%
+set JAVA_HOME=%javaHome%
+
+rem --------------------------
+rem Run nmake to build the executable.
+rem --------------------------
+if "%extraArgs%" == "" goto MAKE_ALL
+
+nmake -f %makefile% %extraArgs%
+goto DONE
+
+:MAKE_ALL
+echo Building %OS% launcher. Defaults: -os %DEFAULT_OS% -arch %DEFAULT_OS_ARCH% -ws %DEFAULT_WS%
+nmake -f %makefile% clean
+nmake -f %makefile% %1 %2 %3 %4
+goto DONE
+
+
+:DONE
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/build.sh b/features/org.eclipse.equinox.executable.feature/library/win32/build.sh
new file mode 100644
index 000000000..853eaf4cf
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/build.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+#*******************************************************************************
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+#
+# Usage: sh build.sh [<optional switches>] [clean]
+#
+# where the optional switches are:
+# -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+# -os <DEFAULT_OS> - default Eclipse "-os" value
+# -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value
+# -ws <DEFAULT_WS> - default Eclipse "-ws" value
+#
+#
+# This script can also be invoked with the "clean" argument.
+
+cd `dirname $0`
+
+# Define default values for environment variables used in the makefiles.
+programOutput="eclipse.exe"
+defaultOS="win32"
+defaultOSArch="x86"
+defaultWS="win32"
+makefile="make_mingw.mak"
+OS="Windows"
+
+# Parse the command line arguments and override the default values.
+extraArgs=""
+while [ "$1" != "" ]; do
+ if [ "$1" = "-os" ] && [ "$2" != "" ]; then
+ defaultOS="$2"
+ shift
+ elif [ "$1" = "-arch" ] && [ "$2" != "" ]; then
+ defaultOSArch="$2"
+ shift
+ elif [ "$1" = "-ws" ] && [ "$2" != "" ]; then
+ defaultWS="$2"
+ shift
+ elif [ "$1" = "-output" ] && [ "$2" != "" ]; then
+ programOutput="$2"
+ shift
+ else
+ extraArgs="$extraArgs $1"
+ fi
+ shift
+done
+
+# Set up environment variables needed by the makefiles.
+PROGRAM_OUTPUT="$programOutput"
+DEFAULT_OS="$defaultOS"
+DEFAULT_OS_ARCH="$defaultOSArch"
+DEFAULT_WS="$defaultWS"
+EXEC_DIR=../../../../../rt.equinox.binaries/org.eclipse.equinox.executable
+OUTPUT_DIR=$EXEC_DIR/bin/$defaultWS/$defaultOS/$defaultOSArch
+
+export OUTPUT_DIR PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS
+
+# If the OS is supported (a makefile exists)
+if [ "$makefile" != "" ]; then
+ if [ "$extraArgs" != "" ]; then
+ make -f $makefile $extraArgs
+ else
+ echo "Building $OS launcher. Defaults: -os $DEFAULT_OS -arch $DEFAULT_OS_ARCH -ws $DEFAULT_WS"
+ make -f $makefile clean
+ make -f $makefile all
+ fi
+else
+ echo "Unknown OS ($OS) -- build aborted"
+fi
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/build.xml b/features/org.eclipse.equinox.executable.feature/library/win32/build.xml
new file mode 100644
index 000000000..056b85926
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/build.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="build_eclipse" basedir=".">
+
+<target name="build_eclipse">
+ <exec dir="." executable="${basedir}\build.bat">
+ <arg line="install"/>
+ </exec>
+</target>
+
+<target name="clean">
+ <tstamp/>
+ <exec dir="." executable="${basedir}\build.bat">
+ <arg line="clean"/>
+ </exec>
+</target>
+
+</project> \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.exe.manifest b/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.exe.manifest
new file mode 100644
index 000000000..dda153470
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.exe.manifest
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="3.1.0.0" processorArchitecture="*" name="Eclipse Launcher" type="win32"/>
+ <description>Standard Widget Toolkit</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
+</assembly>
+ \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.ico b/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.ico
new file mode 100644
index 000000000..d73e6869c
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.ico
Binary files differ
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.rc b/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.rc
new file mode 100644
index 000000000..c05708362
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/eclipse.rc
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#define ECLIPSE_ICON 401
+
+#include "windows.h"
+#include "winver.h"
+
+
+ECLIPSE_ICON ICON DISCARDABLE "eclipse.ico"
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "eclipse.exe.manifest"
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c b/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c
new file mode 100644
index 000000000..387576994
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c
@@ -0,0 +1,619 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ *******************************************************************************/
+
+#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include "eclipseCommon.h"
+#include "eclipseJNI.h"
+#include "eclipseShm.h"
+
+#include <windows.h>
+#include <commctrl.h>
+#include <process.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#ifdef __MINGW32__
+#include <stdlib.h>
+#endif
+
+extern HWND topWindow;
+
+/* Global Variables */
+_TCHAR* defaultVM = _T("javaw.exe");
+_TCHAR* consoleVM = _T("java.exe");
+_TCHAR* vmLibrary = _T("jvm.dll");
+_TCHAR* shippedVMDir = _T("jre\\bin\\");
+
+/* Define local variables for communicating with running eclipse instance. */
+static HANDLE mutex;
+static UINT findWindowTimeout = 1000;
+static UINT_PTR findWindowTimerId = 97;
+static UINT timerCount = 0;
+static UINT openFileTimeout = 60;
+static _TCHAR** openFilePath;
+
+/* Define the window system arguments for the Java VM. */
+static _TCHAR* argVM[] = { NULL };
+
+/* Define local variables for running the JVM and detecting its exit. */
+static HANDLE jvmProcess = 0;
+static JavaResults* jvmResults = NULL;
+static UINT jvmExitTimeout = 100;
+static UINT_PTR jvmExitTimerId = 99;
+
+static void CALLBACK findWindowProc(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime);
+static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime );
+static _TCHAR* checkVMRegistryKey(HKEY jrekey, _TCHAR* subKeyName);
+static void adjustSearchPath( _TCHAR * vmLibrary );
+static _TCHAR* findLib( _TCHAR* command );
+
+/* define default locations in which to find the jvm shared library
+ * these are paths relative to the java exe, the shared library is
+ * for example jvmLocations[0] + dirSeparator + vmLibrary */
+#define MAX_LOCATION_LENGTH 25 /* none of the jvmLocations strings should be longer than this */
+static const _TCHAR* jvmLocations [] = { _T("j9vm"), _T("..\\jre\\bin\\j9vm"),
+ _T("client"), _T("..\\jre\\bin\\client"),
+ _T("server"), _T("..\\jre\\bin\\server"),
+ _T("classic"), _T("..\\jre\\bin\\classic"),
+ _T("jrockit"), _T("..\\jre\\bin\\jrockit"),
+ NULL };
+
+/* for detecting sun vms */
+typedef struct {
+ WORD language;
+ WORD codepage;
+} TRANSLATIONS;
+
+#define COMPANY_NAME_KEY _T_ECLIPSE("\\StringFileInfo\\%04x%04x\\CompanyName")
+#define SUN_MICROSYSTEMS _T_ECLIPSE("Sun Microsystems")
+#define ORACLE _T_ECLIPSE("Oracle")
+
+static void sendOpenFileMessage(HWND window) {
+ _TCHAR* id;
+ UINT msg;
+ int index = 0;
+ int size = 0;
+ DWORD wParam;
+#ifdef WIN64
+ DWORDLONG lParam;
+#else
+ DWORD lParam;
+#endif
+
+ /* what's the longest path? */
+ while (openFilePath[index] != NULL) {
+ int length = _tcslen(openFilePath[index++]);
+ if (size <= length)
+ size = length + 1;
+ }
+
+ createSharedData(&id, size * sizeof(_TCHAR));
+ _stscanf(id, _T_ECLIPSE("%lx_%lx"), &wParam, &lParam);
+ msg = RegisterWindowMessage(_T("SWT_OPENDOC"));
+
+ index = 0;
+ for(index = 0; openFilePath[index] != NULL; index++) {
+ /* SendMessage does not return until the message has been processed */
+ setSharedData(id, openFilePath[index]);
+ SendMessage(window, msg, wParam, lParam);
+ }
+ destroySharedData(id);
+ free(id);
+}
+
+static HWND findSWTMessageWindow() {
+ HWND window = NULL;
+ _TCHAR *windowTitle, *windowPrefix, *name;
+
+ windowPrefix = _T("SWT_Window_");
+ name = getOfficialName();
+ windowTitle = malloc((_tcslen(windowPrefix) + _tcslen(name) + 1) * sizeof(_TCHAR));
+ _stprintf(windowTitle, _T_ECLIPSE("%s%s"), windowPrefix, name);
+ window = FindWindow(NULL, windowTitle);
+ free(windowTitle);
+ return window;
+}
+
+static void CALLBACK findWindowProc(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime) {
+ HWND window = findSWTMessageWindow();
+ if (window != NULL) {
+ sendOpenFileMessage(window);
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+ KillTimer(hwnd, findWindowTimerId);
+ return;
+ }
+
+ /* no window yet, set timer to try again later */
+ if (timerCount++ >= openFileTimeout) {
+ KillTimer(hwnd, findWindowTimerId);
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+ }
+}
+
+/* return > 0 if we successfully send a message to another eclipse instance */
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
+ _TCHAR* mutexPrefix = _T("SWT_Mutex_");
+ _TCHAR* mutexName, *name;
+ DWORD lock;
+ HWND window = NULL;
+
+ /* store for later */
+ openFilePath = filePath;
+ openFileTimeout = timeout;
+
+ name = getOfficialName();
+ mutexName = malloc((_tcslen(mutexPrefix) + _tcslen(name) + 1) * sizeof(_TCHAR));
+ _stprintf(mutexName, _T_ECLIPSE("%s%s"), mutexPrefix, name);
+ mutex = CreateMutex(NULL, FALSE, mutexName);
+ free(mutexName);
+ if (mutex == NULL) return -1;
+
+ //wait for timeout seconds
+ lock = WaitForSingleObject(mutex, timeout * 1000);
+ if (lock != WAIT_OBJECT_0) {
+ /* failed to get the lock before timeout, We won't be reusing an existing eclipse. */
+ CloseHandle(mutex);
+ return 0;
+ }
+
+ /* we have the mutex, look for the SWT window */
+ window = findSWTMessageWindow();
+ if (window != NULL) {
+ sendOpenFileMessage(window);
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+ return 1; /* success! */
+ }
+
+ /* no window, set a timer to look again later */
+ if (initWindowSystem(0, NULL, 0) == 0)
+ SetTimer( topWindow, findWindowTimerId, findWindowTimeout, findWindowProc );
+
+ return 0;
+}
+
+/* Show the Splash Window
+ *
+ * Open the bitmap, insert into the splash window and display it.
+ *
+ */
+int showSplash( const _TCHAR* featureImage )
+{
+ static int splashing = 0;
+ HBITMAP hBitmap = 0;
+ BITMAP bmp;
+ HDC hDC;
+ int depth;
+ int x, y;
+ int width, height;
+
+ if(splashing) {
+ /*splash screen is already showing, do nothing */
+ return 0;
+ }
+ if (featureImage == NULL)
+ return -1;
+
+ /* if Java was started first and is calling back to show the splash, we might not
+ * have initialized the window system yet
+ */
+ initWindowSystem(0, NULL, 1);
+
+ /* Load the bitmap for the feature. */
+ hDC = GetDC( NULL);
+ depth = GetDeviceCaps( hDC, BITSPIXEL ) * GetDeviceCaps( hDC, PLANES);
+ ReleaseDC(NULL, hDC);
+ if (featureImage != NULL)
+ hBitmap = LoadImage(NULL, featureImage, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+
+ /* If the bitmap could not be found, return an error. */
+ if (hBitmap == 0)
+ return ERROR_FILE_NOT_FOUND;
+
+ GetObject(hBitmap, sizeof(BITMAP), &bmp);
+
+ /* figure out position */
+ width = GetSystemMetrics (SM_CXSCREEN);
+ height = GetSystemMetrics (SM_CYSCREEN);
+ x = (width - bmp.bmWidth) / 2;
+ y = (height - bmp.bmHeight) / 2;
+
+ /* Centre the splash window and display it. */
+ SetWindowPos (topWindow, 0, x, y, bmp.bmWidth, bmp.bmHeight, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
+ SendMessage( topWindow, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBitmap );
+ ShowWindow( topWindow, SW_SHOW );
+ BringWindowToTop( topWindow );
+ splashing = 1;
+
+ /* Process messages */
+ dispatchMessages();
+ return 0;
+}
+
+void dispatchMessages() {
+ MSG msg;
+
+ if(topWindow == 0)
+ return;
+ while (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+}
+
+jlong getSplashHandle() {
+ return (jlong)topWindow;
+}
+
+void takeDownSplash() {
+ if(topWindow != NULL) {
+ DestroyWindow(topWindow);
+ dispatchMessages();
+ topWindow = 0;
+ }
+}
+
+/* Get the window system specific VM args */
+_TCHAR** getArgVM( _TCHAR *vm )
+{
+ return argVM;
+}
+
+/* Local functions */
+
+_TCHAR * findVMLibrary( _TCHAR* command ) {
+ _TCHAR* lib = findLib(command);
+ if( lib != NULL ) {
+ adjustSearchPath(lib);
+ }
+ return lib;
+}
+
+void adjustSearchPath( _TCHAR* vmLib ){
+ _TCHAR ** paths;
+ _TCHAR* cwd = NULL;
+ _TCHAR * path = NULL, *newPath = NULL;
+ _TCHAR * c;
+ int i, length;
+ int needAdjust = 0, freePath = 0;
+
+ paths = getVMLibrarySearchPath(vmLib);
+
+ /* bug 325902 - add current working dir to the end of the search path */
+ length = GetCurrentDirectory(0, NULL);
+ cwd = malloc((length + 1)* sizeof(_TCHAR));
+ GetCurrentDirectory(length, cwd);
+ cwd[length - 1] = pathSeparator;
+ cwd[length] = 0;
+
+ /* first call to GetEnvironmentVariable tells us how big to make the buffer */
+ length = GetEnvironmentVariable(_T_ECLIPSE("PATH"), path, 0);
+ if (length > 0) {
+ _TCHAR* current [] = { cwd, NULL };
+ path = malloc(length * sizeof(_TCHAR));
+ GetEnvironmentVariable(_T_ECLIPSE("PATH"), path, length);
+ needAdjust = !containsPaths(path, paths) || !containsPaths(path, current);
+ freePath = 1;
+ } else {
+ path = _T_ECLIPSE("");
+ freePath = 0;
+ needAdjust = 1;
+ }
+
+ if (needAdjust) {
+ c = concatStrings(paths);
+ newPath = malloc((_tcslen(c) + length + 1 + _tcslen(cwd) + 1) * sizeof(_TCHAR));
+ _stprintf(newPath, _T_ECLIPSE("%s%s%c%s"), c, path, pathSeparator, cwd);
+ SetEnvironmentVariable( _T_ECLIPSE("PATH"), newPath);
+ free(c);
+ free(newPath);
+ }
+
+ for (i = 0; paths[i] != NULL; i++)
+ free(paths[i]);
+ free(paths);
+ free(cwd);
+ if (freePath)
+ free(path);
+}
+/*
+ * Find the VM shared library starting from the java executable
+ */
+static _TCHAR* findLib( _TCHAR* command ) {
+ int i, j;
+ size_t pathLength;
+ struct _stat stats;
+ _TCHAR * path; /* path to resulting jvm shared library */
+ _TCHAR * location; /* points to begining of jvmLocations section of path */
+
+ /* for looking in the registry */
+ HKEY jreKey = NULL;
+ DWORD length = MAX_PATH;
+ _TCHAR keyName[MAX_PATH];
+ _TCHAR * jreKeyName;
+
+ if (command != NULL) {
+ location = lastDirSeparator( command ) + 1;
+
+ /*check first to see if command already points to the library */
+ if (isVMLibrary(command)) {
+ if (_tstat( command, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ return command; /* exists */
+ return NULL; /* doesn't exist */
+ }
+
+ pathLength = (size_t) (location - command);
+ path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + _tcslen(vmLibrary) + 1) * sizeof(_TCHAR));
+ _tcsncpy(path, command, pathLength);
+ location = &path[pathLength];
+
+ /*
+ * We are trying base/jvmLocations[*]/vmLibrary
+ * where base is the directory containing the given java command, normally jre/bin
+ */
+ i = -1;
+ while(jvmLocations[++i] != NULL) {
+ _stprintf(location, _T_ECLIPSE("%s%c%s"), jvmLocations[i], dirSeparator, vmLibrary);
+ if (_tstat( path, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /* found it */
+ return path;
+ }
+ }
+
+ /* if command is eclipse/jre, don't look in registry */
+ location = malloc( (_tcslen( getProgramDir() ) + _tcslen( shippedVMDir ) + 1) * sizeof(_TCHAR) );
+ _stprintf( location, _T_ECLIPSE("%s%s"), getProgramDir(), shippedVMDir );
+ if( _tcsncmp(command, location, _tcslen(location)) == 0) {
+ free(location);
+ return NULL;
+ }
+ free(location);
+ }
+
+ /* Not found yet, try the registry, we will use the first vm >= 1.4 */
+ jreKeyName = _T("Software\\JavaSoft\\Java Runtime Environment");
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, jreKeyName, 0, KEY_READ, &jreKey) == ERROR_SUCCESS) {
+ if(RegQueryValueEx(jreKey, _T_ECLIPSE("CurrentVersion"), NULL, NULL, (void*)&keyName, &length) == ERROR_SUCCESS) {
+ path = checkVMRegistryKey(jreKey, keyName);
+ if (path != NULL) {
+ RegCloseKey(jreKey);
+ return path;
+ }
+ }
+ j = 0;
+ length = MAX_PATH;
+ while (RegEnumKeyEx(jreKey, j++, keyName, &length, 0, 0, 0, 0) == ERROR_SUCCESS) {
+ /*look for a 1.4 or 1.5 vm*/
+ if( _tcsncmp(_T("1.4"), keyName, 3) <= 0 ) {
+ path = checkVMRegistryKey(jreKey, keyName);
+ if (path != NULL) {
+ RegCloseKey(jreKey);
+ return path;
+ }
+ }
+ }
+ RegCloseKey(jreKey);
+ }
+ return NULL;
+}
+
+/*
+ * Read the subKeyName subKey of jreKey and look to see if it has a Value
+ * "RuntimeLib" which points to a jvm library we can use
+ *
+ * Does not close jreKey
+ */
+static _TCHAR* checkVMRegistryKey(HKEY jreKey, _TCHAR* subKeyName) {
+ _TCHAR value[MAX_PATH];
+ HKEY subKey = NULL;
+ DWORD length = MAX_PATH;
+ _TCHAR *result = NULL;
+ struct _stat stats;
+
+ if(RegOpenKeyEx(jreKey, subKeyName, 0, KEY_READ, &subKey) == ERROR_SUCCESS) {
+ /*The RuntimeLib value should point to the library we want*/
+ if(RegQueryValueEx(subKey, _T("RuntimeLib"), NULL, NULL, (void*)&value, &length) == ERROR_SUCCESS) {
+ if (_tstat( value, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /*library exists*/
+ result = _tcsdup(value);
+ }
+ }
+ RegCloseKey(subKey);
+ }
+ return result;
+}
+
+static _TCHAR* buildCommandLine( _TCHAR* program, _TCHAR* args[] )
+{
+ int index, slash;
+ size_t length = 0;
+ _TCHAR *commandLine, *ch, *space;
+
+ /*
+ * Build the command line. Any argument with spaces must be in
+ * double quotes in the command line.
+ */
+ if(program != NULL)
+ length = _tcslen(program) + 1;
+ for (index = 0; args[index] != NULL; index++)
+ {
+ /* String length plus space character */
+ length += _tcslen( args[ index ] ) + 1;
+ /* Quotes + potential escaping '\' */
+ if (_tcschr( args[ index ], _T(' ') ) != NULL) length += 3;
+ }
+
+ commandLine = ch = malloc ( (length + 1) * sizeof(_TCHAR) );
+ if (program != NULL) {
+ _tcscpy(ch, program);
+ ch += _tcslen(program);
+ *ch++ = _T(' ');
+ }
+ for (index = 0; args[index] != NULL; index++)
+ {
+ space = _tcschr( args[ index ], _T(' '));
+ if (space != NULL) *ch++ = _T('\"');
+ _tcscpy( ch, args[index] );
+ ch += _tcslen( args[index] );
+ if (space != NULL) {
+ if ( *(ch - 1) == _T('\\') ) {
+ /* escape a trailing unescaped '\' or it will escape our closing '"' and mess things up */
+ slash = 1;
+ while ( *(ch - 1 - slash) == _T('\\')) slash++;
+ if (slash % 2) *ch++ = _T('\\');
+ }
+ *ch++ = _T('\"');
+ }
+ *ch++ = _T(' ');
+ }
+ *ch = _T('\0');
+ return commandLine;
+}
+void restartLauncher( _TCHAR* program, _TCHAR* args[] )
+{
+ _TCHAR* commandLine = buildCommandLine(program, args);
+
+ {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ GetStartupInfo(&si);
+ if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ CloseHandle( pi.hThread );
+ }
+ }
+ free(commandLine);
+}
+
+JavaResults* launchJavaVM( _TCHAR* args[] )
+{
+ MSG msg;
+ _TCHAR* commandLine;
+ jvmProcess = 0;
+ commandLine = buildCommandLine(NULL, args);
+ jvmResults = malloc(sizeof(JavaResults));
+ memset(jvmResults, 0, sizeof(JavaResults));
+
+ /*
+ * Start the Java virtual machine. Use CreateProcess() instead of spawnv()
+ * otherwise the arguments cannot be freed since spawnv() segments fault.
+ */
+ {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ GetStartupInfo(&si);
+ if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ CloseHandle( pi.hThread );
+ jvmProcess = pi.hProcess;
+ } else {
+ jvmResults->launchResult = errno;
+ }
+ }
+
+ free( commandLine );
+
+ if (jvmProcess > 0)
+ {
+ /* Set a timer to detect JVM process termination. */
+ SetTimer( topWindow, jvmExitTimerId, jvmExitTimeout, detectJvmExit );
+
+ /* Process messages until the JVM terminates.
+ This launcher process must continue to process events until the JVM exits
+ or else Windows 2K will hang if the desktop properties (e.g., background) are
+ changed by the user. Windows does a SendMessage() to every top level window
+ process, which blocks the caller until the process responds. */
+ while (jvmProcess != 0)
+ {
+ GetMessage( &msg, NULL, 0, 0 );
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ /* Kill the timer. */
+ KillTimer( topWindow, jvmExitTimerId );
+ }
+
+ /* Return the exit code from the JVM. */
+ return jvmResults;
+}
+
+/* Detect JVM Process Termination */
+static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime )
+{
+ DWORD exitCode;
+
+ /* If the JVM process has terminated */
+ if (!GetExitCodeProcess( (HANDLE)jvmProcess, &exitCode ) ||
+ exitCode != STILL_ACTIVE)
+ {
+ /* Save the JVM exit code. This should cause the loop in launchJavaVM() to exit. */
+ jvmResults->runResult = exitCode;
+ jvmProcess = 0;
+ }
+}
+
+void processVMArgs(_TCHAR **vmargs[] ) {
+ /* nothing yet */
+}
+
+JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile )
+{
+ return startJavaJNI(libPath, vmArgs, progArgs, jarFile);
+}
+
+int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib ) {
+ _TCHAR *vm = (jniLib != NULL) ? jniLib : javaVM;
+ int result = 0;
+ DWORD infoSize;
+ DWORD handle;
+ void * info;
+
+ _TCHAR * key, *value;
+ size_t i;
+ int valueSize;
+
+ if (vm == NULL)
+ return 0;
+
+ infoSize = GetFileVersionInfoSize(vm, &handle);
+ if (infoSize > 0) {
+ info = malloc(infoSize);
+ if (GetFileVersionInfo(vm, 0, infoSize, info)) {
+ TRANSLATIONS * translations;
+ int translationsSize;
+ VerQueryValue(info, _T_ECLIPSE("\\VarFileInfo\\Translation"), (void *) &translations, &translationsSize);
+
+ /* this size is only right because %04x is 4 characters */
+ key = malloc( (_tcslen(COMPANY_NAME_KEY) + 1) * sizeof(_TCHAR));
+ for (i = 0; i < (translationsSize / sizeof(TRANSLATIONS)); i++) {
+ _stprintf(key, COMPANY_NAME_KEY, translations[i].language, translations[i].codepage);
+
+ VerQueryValue(info, key, (void *)&value, &valueSize);
+ if (_tcsncmp(value, SUN_MICROSYSTEMS, _tcslen(SUN_MICROSYSTEMS)) == 0) {
+ result = 1;
+ break;
+ } else if (_tcsncmp(value, ORACLE, _tcslen(ORACLE)) == 0) {
+ result = 1;
+ break;
+ }
+ }
+ free(key);
+ }
+ free(info);
+ }
+ return result;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWinCommon.c b/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWinCommon.c
new file mode 100644
index 000000000..27546bfaa
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWinCommon.c
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+
+#include <windows.h>
+#include <stdlib.h>
+#include <commctrl.h>
+
+#define ECLIPSE_ICON 401
+
+_TCHAR dirSeparator = _T('\\');
+_TCHAR pathSeparator = _T(';');
+
+/* Global Main Window*/
+HWND topWindow = 0;
+
+/* Define local variables for the main window. */
+/*static WNDPROC oldProc;*/
+
+static int initialized = 0;
+
+/* Display a Message */
+void displayMessage( _TCHAR* title, _TCHAR* message )
+{
+ if(!initialized)
+ initWindowSystem(0, NULL, 0);
+ MessageBox( topWindow, message, title, MB_OK );
+}
+
+/* Initialize Window System
+ *
+ * Create a pop window to display the bitmap image.
+ *
+ * Return the window handle as the data for the splash command.
+ *
+ */
+int initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash )
+{
+ HINSTANCE module = GetModuleHandle(NULL);
+ HICON icon = NULL;
+
+ if(initialized)
+ return 0;
+
+ icon = LoadIcon(module, MAKEINTRESOURCE(ECLIPSE_ICON));
+ if (icon == NULL) {
+ HMODULE hm = LoadLibraryEx(getProgramPath(), 0, LOAD_LIBRARY_AS_DATAFILE & 0x2 /*LOAD_LIBRARY_AS_IMAGE_RESOURCE*/);
+ if (hm != NULL)
+ icon = LoadIcon(hm, MAKEINTRESOURCE(ECLIPSE_ICON));
+ }
+
+ /* Create a window that has no decorations. */
+ InitCommonControls();
+ topWindow = CreateWindowEx ( icon != NULL ? 0 : WS_EX_TOOLWINDOW,
+ _T("STATIC"),
+ getOfficialName(),
+ SS_BITMAP | WS_POPUP | WS_CLIPCHILDREN,
+ CW_USEDEFAULT,
+ 0,
+ CW_USEDEFAULT,
+ 0,
+ NULL,
+ NULL,
+ module,
+ NULL);
+
+ if (icon != NULL)
+#ifdef WIN64
+ SetClassLongPtr(topWindow, GCLP_HICON, (LONG_PTR)icon);
+#else
+ SetClassLong(topWindow, GCL_HICON, (LONG)icon);
+#endif
+
+ initialized = 1;
+ return 0;
+}
+
+/* Load the specified shared library
+ */
+void * loadLibrary( _TCHAR * library ){
+ return LoadLibrary(library);
+}
+
+/* Unload the shared library
+ */
+void unloadLibrary( void * handle ){
+ FreeLibrary(handle);
+}
+
+/* Find the given symbol in the shared library
+ */
+void * findSymbol( void * handle, _TCHAR * symbol ){
+ char * str = NULL;
+ void * result;
+
+ str = toNarrow(symbol);
+ result = GetProcAddress(handle, str);
+ free(str);
+ return result;
+}
+
+_TCHAR* resolveSymlinks( _TCHAR* path ) {
+ /* no symlinks on windows */
+ return path;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/make_mingw.mak b/features/org.eclipse.equinox.executable.feature/library/win32/make_mingw.mak
new file mode 100644
index 000000000..aaee41e85
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/make_mingw.mak
@@ -0,0 +1,127 @@
+#*******************************************************************************
+# Copyright (c) 2000, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+# Silenio Quarti (IBM)
+# Sam Robb (TimeSys Corporation)
+#*******************************************************************************
+include ../make_version.mak
+# Makefile for creating the eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the file of the output shared library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+
+#if PROGRAM_OUTPUT is not set, assume eclipse.exe
+ifeq ($(PROGRAM_OUTPUT),)
+ PROGRAM_OUTPUT=eclipse.exe
+endif
+
+# Separate filename from extention
+PROGRAM_NAME=$(PROGRAM_OUTPUT:.exe=)
+
+PROGRAM_LIBRARY=eclipse_$(LIB_VERSION).dll
+
+# Allow for cross-compiling under linux
+OSTYPE ?= $(shell if uname -s | grep -iq cygwin ; then echo cygwin; else echo linux; fi)
+
+ifeq ($(OSTYPE),cygwin)
+CCVER = i686
+CC = i686-pc-cygwin-gcc-3
+RC = windres
+else
+CCVER = i586
+CC = $(shell which i586-pc-cygwin-gcc)
+TDIR = $(dir $(shell test -L $(CC) && readlink $(CC) || echo $(CC)))
+RC = $(TDIR)/i586-pc-cygwin-windres
+SYSINC = -isystem $(TDIR)/../include/mingw
+endif
+
+ifeq ($(CC),)
+$(error Unable to find $(CCVER)-pc-cygwin-gcc)
+endif
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.o
+COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseWinCommon.o
+DLL_OBJS = eclipse.o eclipseWin.o eclipseUtil.o eclipseJNI.o eclipseShm.o
+
+LIBS = -lkernel32 -luser32 -lgdi32 -lcomctl32 -lmsvcrt -lversion
+LDFLAGS = -mwindows -mno-cygwin
+CONSOLEFLAGS = -mconsole -mno-cygwin
+DLL_LDFLAGS = -mno-cygwin -shared -Wl,--export-all-symbols -Wl,--kill-at,--image-base=0x72000000
+RES = $(PROGRAM_NAME).res
+CONSOLE = $(PROGRAM_NAME)c.exe
+EXEC = $(PROGRAM_OUTPUT)
+DLL = $(PROGRAM_LIBRARY)
+DEBUG = $(CDEBUG)
+CFLAGS = -g -s -Wall \
+ -I. -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/win32 $(SYSINC) \
+ -D_WIN32 \
+ -DWIN32_LEAN_AND_MEAN \
+ -mno-cygwin -D__int64="long long"
+WCFLAGS = -DUNICODE -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ $(DEBUG) $(CFLAGS)
+
+all: $(EXEC) $(DLL) $(CONSOLE)
+
+eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseMain.c
+
+eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseCommon.c
+
+eclipseWinCommon.o: ../eclipseCommon.h eclipseWinCommon.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ eclipseWinCommon.c
+
+eclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipseJNI.h ../eclipseCommon.h ../eclipse.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipse.c
+
+eclipseUtil.o: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseUtil.c
+
+eclipseConfig.o: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseConfig.c
+
+eclipseWin.o: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ eclipseWin.c
+
+eclipseJNI.o: ../eclipseUnicode.h ../eclipseJNI.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseJNI.c
+
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseShm.c
+
+$(RES): $(PROGRAM_NAME).rc
+ $(RC) --output-format=coff --include-dir=.. -o $@ $<
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES)
+ $(CC) $(LDFLAGS) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS)
+
+#the console version needs a flag set, should look for a better way to do this
+$(CONSOLE): $(MAIN_OBJS) $(COMMON_OBJS)
+ rm -f eclipseConfig.o aeclipseConfig.o
+ $(CC) $(DEBUG) $(WCFLAGS) -D_WIN32_CONSOLE -c -o eclipseConfig.o ../eclipseConfig.c
+ $(CC) $(CONSOLEFLAGS) -o $(CONSOLE) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(CC) $(DLL_LDFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS)
+
+install: all
+ cp $(EXEC) $(DLL) $(CONSOLE) $(OUTPUT_DIR)
+ rm -f $(EXEC) $(DLL_OBJS) $(COMMON_OBJS) $(MAIN_OBJS) $(RES) $(CONSOLE)
+
+clean:
+ $(RM) $(EXEC) $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(MAIN_OBJS) $(RES) $(CONSOLE)
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/make_win32.mak b/features/org.eclipse.equinox.executable.feature/library/win32/make_win32.mak
new file mode 100644
index 000000000..252708832
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/make_win32.mak
@@ -0,0 +1,103 @@
+#******************************************************************************
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+
+# Makefile for creating the eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the filename of the output dll library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - the location of the Java for JNI includes
+NODEBUG=1
+!include <ntwin32.mak>
+!include <..\make_version.mak>
+
+PROGRAM_OUTPUT=eclipse.exe
+# Separate filename from extention
+PROGRAM_NAME=$(PROGRAM_OUTPUT:.exe=)
+
+PROGRAM_LIBRARY = eclipse_$(LIB_VERSION).dll
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.obj
+COMMON_OBJS = eclipseConfig.obj eclipseCommon.obj eclipseWinCommon.obj
+DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj eclipseShm.obj
+
+LIBS = kernel32.lib user32.lib comctl32.lib msvcrt.lib
+DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib msvcrt.lib version.lib
+LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /LARGEADDRESSAWARE /RELEASE /NOLOGO -subsystem:windows,4.0 -entry:wmainCRTStartup
+CONSOLEFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /LARGEADDRESSAWARE /RELEASE /NOLOGO -subsystem:console,4.0 -entry:wmainCRTStartup
+DLL_LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /LARGEADDRESSAWARE /PDB:NONE /RELEASE /NOLOGO -entry:_DllMainCRTStartup@12 -dll /BASE:0x72000000 /DLL
+RES = $(PROGRAM_NAME).res
+EXEC = $(PROGRAM_OUTPUT)
+CONSOLE = $(PROGRAM_NAME)c.exe
+DLL = $(PROGRAM_LIBRARY)
+DEBUG = #$(cdebug)
+wcflags = -DUNICODE -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -I$(JAVA_HOME)\include -I$(JAVA_HOME)\include\win32 \
+ $(cflags)
+
+all: $(EXEC) $(DLL) $(CONSOLE)
+
+eclipseMain.obj: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseMain.c
+
+eclipseCommon.obj: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseCommon.c
+
+eclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipse.c
+
+eclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseUtil.c
+
+eclipseConfig.obj: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseConfig.c
+
+eclipseWin.obj: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj eclipseWin.c
+
+eclipseWinCommon.obj: ../eclipseCommon.h eclipseWinCommon.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj eclipseWinCommon.c
+
+eclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c
+ $(CC) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseJNI.c
+
+eclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseShm.c
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES)
+ $(link) $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS)
+
+#the console version needs a flag set, should look for a better way to do this
+$(CONSOLE): $(MAIN_OBJS) $(COMMON_OBJS)
+ del -f eclipseConfig.obj aeclipseConfig.obj
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) -D_WIN32_CONSOLE /FoeclipseConfig.obj ../eclipseConfig.c
+ $(link) $(CONSOLEFLAGS) -out:$(CONSOLE) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(link) $(DLL_LFLAGS) -out:$(PROGRAM_LIBRARY) $(DLL_OBJS) $(COMMON_OBJS) $(DLL_LIBS)
+
+$(RES): $(PROGRAM_NAME).rc
+ $(rc) -r -fo $(RES) eclipse.rc
+
+install: all
+ copy $(EXEC) $(OUTPUT_DIR)
+ del -f $(EXEC) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
+
+clean:
+ del $(EXEC) $(DLL) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak b/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak
new file mode 100644
index 000000000..f1faaabca
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak
@@ -0,0 +1,107 @@
+#******************************************************************************
+# Copyright (c) 2007, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+#*******************************************************************************
+
+# Makefile for creating the eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the filename of the output dll library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - the location of the Java for JNI includes
+NODEBUG=1
+
+APPVER=4.0
+_WIN32_WINNT=0x0400
+_WIN32_IE=0x0300
+
+!include <ntwin32.mak>
+!include <..\make_version.mak>
+
+PROGRAM_OUTPUT=eclipse.exe
+# Separate filename from extention
+PROGRAM_NAME=$(PROGRAM_OUTPUT:.exe=)
+
+PROGRAM_LIBRARY = eclipse_$(LIB_VERSION).dll
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.obj
+COMMON_OBJS = eclipseConfig.obj eclipseCommon.obj eclipseWinCommon.obj
+DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj eclipseShm.obj
+
+LIBS = kernel32.lib user32.lib comctl32.lib msvcrt.lib bufferoverflowU.lib
+DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib msvcrt.lib version.lib bufferoverflowU.lib
+LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO -subsystem:windows -entry:wmainCRTStartup
+CONSOLEFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO -subsystem:console -entry:wmainCRTStartup
+#DLL_LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO -entry:_DllMainCRTStartup@12 -dll /BASE:0x72000000 /DLL
+DLL_LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO -dll /BASE:0x72000000 /DLL
+RES = $(PROGRAM_NAME).res
+EXEC = $(PROGRAM_OUTPUT)
+CONSOLE = $(PROGRAM_NAME)c.exe
+DLL = $(PROGRAM_LIBRARY)
+DEBUG = #$(cdebug)
+wcflags = -DUNICODE -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -I$(JAVA_HOME)\include -I$(JAVA_HOME)\include\win32 \
+ $(cflags)
+all: $(EXEC) $(DLL) $(CONSOLE)
+
+eclipseMain.obj: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseMain.c
+
+eclipseCommon.obj: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseCommon.c
+
+eclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipse.c
+
+eclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseUtil.c
+
+eclipseConfig.obj: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseConfig.c
+
+eclipseWin.obj: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj eclipseWin.c
+
+eclipseWinCommon.obj: ../eclipseCommon.h eclipseWinCommon.c
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj eclipseWinCommon.c
+
+eclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c
+ $(CC) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseJNI.c
+
+eclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseShm.c
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES)
+ $(link) $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS)
+
+#the console version needs a flag set, should look for a better way to do this
+$(CONSOLE): $(MAIN_OBJS) $(COMMON_OBJS)
+ del -f eclipseConfig.obj aeclipseConfig.obj
+ $(cc) $(DEBUG) $(wcflags) $(cvarsdll) -D_WIN32_CONSOLE /FoeclipseConfig.obj ../eclipseConfig.c
+ $(link) $(CONSOLEFLAGS) -out:$(CONSOLE) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(link) $(DLL_LFLAGS) -out:$(PROGRAM_LIBRARY) $(DLL_OBJS) $(COMMON_OBJS) $(DLL_LIBS)
+
+$(RES): $(PROGRAM_NAME).rc
+ $(rc) -r -fo $(RES) eclipse.rc
+
+install: all
+ copy $(EXEC) $(OUTPUT_DIR)
+ del -f $(EXEC) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
+
+clean:
+ del $(EXEC) $(DLL) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/make_win64_ia64.mak b/features/org.eclipse.equinox.executable.feature/library/win32/make_win64_ia64.mak
new file mode 100644
index 000000000..5d9ff5c86
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/make_win64_ia64.mak
@@ -0,0 +1,108 @@
+#******************************************************************************
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+
+# Makefile for creating the eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the filename of the output dll library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - the location of the Java for JNI includes
+NODEBUG=1
+!include <ntwin32.mak>
+!include <..\make_version.mak>
+
+PROGRAM_LIBRARY = eclipse_$(LIB_VERSION).dll
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.obj
+COMMON_OBJS = eclipseConfig.obj eclipseCommon.obj eclipseWinCommon.obj
+DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj eclipseShm.obj
+
+# using dynamic lib
+#LIBS = kernel32.lib user32.lib comctl32.lib msvcrt.lib
+#DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib msvcrt.lib version.lib
+
+LIBS = kernel32.lib user32.lib comctl32.lib libcmt.lib bufferoverflowU.lib
+DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib libcmt.lib version.lib bufferoverflowU.lib
+# LIBS = kernel32.lib user32.lib gdi32.lib comctl32.lib bufferoverflowu.lib
+# LFLAGS = /INCREMENTAL:NO /NOLOGO -subsystem:windows -entry:wmainCRTStartup -machine:IA64
+
+# was: windows
+LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO -subsystem:windows -entry:wmainCRTStartup -machine:IA64
+CONSOLEFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO -subsystem:console -entry:wmainCRTStartup -machine:IA64
+DLL_LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO /PDB:NONE -entry:_DllMainCRTStartup -dll /BASE:0x72000000 /DLL -machine:IA64
+RES = eclipse.res
+EXEC = eclipse.exe
+CONSOLE = eclipsec.exe
+DLL = $(PROGRAM_LIBRARY)
+DEBUG = #$(cdebug)
+wcflags = -DUNICODE -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -I$(JAVA_HOME)\include -I$(JAVA_HOME)\include\win32 \
+ $(cflags) -D_CRT_SECURE_NO_WARNINGS -D_CRT_NON_CONFORMING_SWPRINTFS
+all: $(EXEC) $(DLL) $(CONSOLE)
+
+eclipseMain.obj: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseMain.c
+
+eclipseCommon.obj: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseCommon.c
+
+eclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipse.c
+
+eclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseUtil.c
+
+eclipseConfig.obj: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseConfig.c
+
+eclipseWin.obj: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj eclipseWin.c
+
+eclipseWinCommon.obj: ../eclipseCommon.h eclipseWinCommon.c
+ $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj eclipseWinCommon.c
+
+eclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c
+ $(CC) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseJNI.c
+
+eclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseShm.c
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES)
+ $(link) $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS)
+#$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES)
+# $(link) $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS)
+
+#the console version needs a flag set, should look for a better way to do this
+$(CONSOLE): $(MAIN_OBJS) $(COMMON_OBJS)
+ del -f eclipseConfig.obj aeclipseConfig.obj
+ $(cc) $(DEBUG) $(wcflags) $(cvars) -D_WIN32_CONSOLE /FoeclipseConfig.obj ../eclipseConfig.c
+ $(link) $(CONSOLEFLAGS) -out:$(CONSOLE) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ $(link) $(DLL_LFLAGS) -out:$(PROGRAM_LIBRARY) $(DLL_OBJS) $(COMMON_OBJS) $(DLL_LIBS)
+
+$(RES): eclipse.rc
+ $(rc) -v -r -fo $(RES) eclipse.rc
+
+install: all
+ copy $(EXEC) $(OUTPUT_DIR)
+ del -f $(EXEC) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
+
+clean:
+ del $(EXEC) $(DLL) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/.cvsignore b/features/org.eclipse.equinox.executable.feature/library/wpf/.cvsignore
new file mode 100644
index 000000000..b5e85ecb0
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/.cvsignore
@@ -0,0 +1,12 @@
+*.obj
+eclipse.exe
+eclipse.res
+*.pdb
+*.exp
+*.lib
+eclipse_*.dll
+com_*.dll
+eclipsec.exe
+eclipsec.exe.manifest
+eclipse_*.dll.manifest
+eclipse.exe.manifest
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/build.bat b/features/org.eclipse.equinox.executable.feature/library/wpf/build.bat
new file mode 100644
index 000000000..57e1d7525
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/build.bat
@@ -0,0 +1,127 @@
+@rem *******************************************************************************
+@rem Copyright (c) 2000, 2009 IBM Corporation and others.
+@rem All rights reserved. This program and the accompanying materials
+@rem are made available under the terms of the Eclipse Public License v1.0
+@rem which accompanies this distribution, and is available at
+@rem http://www.eclipse.org/legal/epl-v10.html
+@rem
+@rem Contributors:
+@rem IBM Corporation - initial API and implementation
+@rem Kevin Cornell (Rational Software Corporation)
+@rem **********************************************************************
+@rem
+@rem Usage: sh build.sh [<optional switches>] [clean]
+@rem
+@rem where the optional switches are:
+@rem -output <PROGRAM_OUTPUT> - executable filename ("eclipse")
+@rem -library <PROGRAM_LIBRARY>- dll filename (eclipse.dll)
+@rem -os <DEFAULT_OS> - default Eclipse "-os" value (qnx)
+@rem -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value (x86)
+@rem -ws <DEFAULT_WS> - default Eclipse "-ws" value (photon)
+@rem -java <JAVA_HOME> - location of a Java SDK for JNI headers
+@rem
+@rem
+@rem This script can also be invoked with the "clean" argument.
+@rem
+@rem NOTE: The C compiler needs to be setup. This script has been
+@rem tested against Microsoft Visual C and C++ Compiler 6.0.
+@rem
+@rem Uncomment the lines below and edit MSVC_HOME to point to the
+@rem correct root directory of the compiler installation, if you
+@rem want this to be done by this script.
+@rem
+@rem ******
+@echo off
+
+IF x.%1==x.x86 shift
+
+rem *****
+rem Javah
+rem *****
+IF x."%JAVA_HOME%"==x. set JAVA_HOME="S:\swt-builddir\ibm-java2-sdk-50-win-i386"
+set javaHome=%JAVA_HOME%
+
+:MSVC
+
+call "S:\swt-builddir\MSSDKs\Microsoft SDK 6.0 Vista\Bin\setenv.cmd" /x86 /vista
+:MAKE
+
+rem --------------------------
+rem Define default values for environment variables used in the makefiles.
+rem --------------------------
+set programOutput=eclipse.exe
+set programLibrary=eclipse.dll
+set defaultOS=win32
+set defaultOSArch=x86
+set defaultWS=wpf
+set makefile=make_wpf.mak
+set OS=Windows
+
+rem --------------------------
+rem Parse the command line arguments and override the default values.
+rem --------------------------
+set extraArgs=
+:WHILE
+if "%1" == "" goto WHILE_END
+ if "%2" == "" goto LAST_ARG
+
+ if "%1" == "-os" (
+ set defaultOS=%2
+ shift
+ goto NEXT )
+ if "%1" == "-arch" (
+ set defaultOSArch=%2
+ shift
+ goto NEXT )
+ if "%1" == "-ws" (
+ set defaultWS=%2
+ shift
+ goto NEXT )
+ if "%1" == "-output" (
+ set programOutput=%2
+ shift
+ goto NEXT )
+ if "%1" == "-library" (
+ set programLibrary=%2
+ shift
+ goto NEXT )
+ if "%1" == "-java" (
+ set javaHome=%2
+ shift
+ goto NEXT )
+:LAST_ARG
+ set extraArgs=%extraArgs% %1
+
+:NEXT
+ shift
+ goto WHILE
+:WHILE_END
+
+rem --------------------------
+rem Set up environment variables needed by the makefile.
+rem --------------------------
+set PROGRAM_OUTPUT=%programOutput%
+set PROGRAM_LIBRARY=%programLibrary%
+set DEFAULT_OS=%defaultOS%
+set DEFAULT_OS_ARCH=%defaultOSArch%
+set DEFAULT_WS=%defaultWS%
+set EXEC_DIR=..\..\.\..\..\rt.equinox.binaries\org.eclipse.equinox.executable
+set OUTPUT_DIR=%EXEC_DIR%\bin\%defaultWS%\%defaultOS%\%defaultOSArch%
+set JAVA_HOME=%javaHome%
+
+rem --------------------------
+rem Run nmake to build the executable.
+rem --------------------------
+if "%extraArgs%" == "" goto MAKE_ALL
+
+nmake -f %makefile% %extraArgs%
+goto DONE
+
+:MAKE_ALL
+echo Building %OS% launcher. Defaults: -os %DEFAULT_OS% -arch %DEFAULT_OS_ARCH% -ws %DEFAULT_WS%
+nmake -f %makefile% clean
+nmake -f %makefile% %1 %2 %3 %4
+goto DONE
+
+
+:DONE
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/build.xml b/features/org.eclipse.equinox.executable.feature/library/wpf/build.xml
new file mode 100644
index 000000000..f4b96fe70
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/build.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project default="build_eclipse" basedir=".">
+
+<target name="build_eclipse">
+ <exec dir="." executable="${basedir}\build.bat">
+ <arg line="install"/>
+ </exec>
+ <eclipse.refreshLocal resource="org.eclipse.equinox.executable" depth="infinite" />
+</target>
+
+<target name="clean">
+ <tstamp/>
+ <exec dir="." executable="${basedir}\build.bat">
+ <arg line="clean"/>
+ </exec>
+</target>
+
+</project> \ No newline at end of file
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/com.c b/features/org.eclipse.equinox.executable.feature/library/wpf/com.c
new file mode 100644
index 000000000..35ce38514
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/com.c
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include <jni.h>
+#include <ole2.h>
+
+#define COM_NATIVE(func) Java_org_eclipse_equinox_launcher_JNIBridge_##func
+
+JNIEXPORT jint JNICALL COM_NATIVE(OleInitialize)
+ (JNIEnv *env, jclass that, jint arg0)
+{
+ return (jint)OleInitialize((LPVOID)arg0);
+}
+
+JNIEXPORT void JNICALL COM_NATIVE(OleUninitialize)
+ (JNIEnv *env, jclass that)
+{
+ OleUninitialize();
+}
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.ico b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.ico
new file mode 100644
index 000000000..9fb5b5b94
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.ico
Binary files differ
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.rc b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.rc
new file mode 100644
index 000000000..874a4b94e
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipse.rc
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#define ECLIPSE_ICON 401
+
+#include "windows.h"
+#include "winver.h"
+
+
+ECLIPSE_ICON ICON DISCARDABLE "eclipse.ico"
+
+//CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "eclipse.exe.manifest"
+
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpf.cpp b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpf.cpp
new file mode 100644
index 000000000..f96523995
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpf.cpp
@@ -0,0 +1,561 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ *******************************************************************************/
+
+extern "C" {
+
+#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include "eclipseCommon.h"
+#include "eclipseJNI.h"
+
+#include <process.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+using namespace System;
+using namespace System::IO;
+using namespace System::Windows;
+using namespace System::Windows::Input;
+using namespace System::Windows::Media;
+using namespace System::Windows::Media::Imaging;
+using namespace System::Windows::Controls;
+using namespace System::Windows::Threading;
+using namespace System::Runtime::InteropServices;
+using namespace System::ComponentModel;
+
+
+/* Global Variables */
+_TCHAR* defaultVM = _T("javaw.exe");
+_TCHAR* consoleVM = _T("java.exe");
+_TCHAR* vmLibrary = _T("jvm.dll");
+_TCHAR* shippedVMDir = _T("jre\\bin\\");
+
+/* Define the window system arguments for the Java VM. */
+static _TCHAR* argVM[] = { NULL };
+
+/* Define local variables for running the JVM and detecting its exit. */
+static int jvmProcess = 0;
+static JavaResults* jvmResults = NULL;
+static int jvmExitTimeout = 100;
+static int jvmExitTimerId = 99;
+
+static void CALLBACK detectJvmExit ();
+static _TCHAR* checkVMRegistryKey(HKEY jrekey, _TCHAR* subKeyName);
+static void adjustSearchPath( _TCHAR * vmLibrary );
+static _TCHAR* findLib( _TCHAR* command );
+
+/* define default locations in which to find the jvm shared library
+ * these are paths relative to the java exe, the shared library is
+ * for example jvmLocations[0] + dirSeparator + vmLibrary */
+#define MAX_LOCATION_LENGTH 25 /* none of the jvmLocations strings should be longer than this */
+static const _TCHAR* jvmLocations [] = { _T("j9vm"), _T("..\\jre\\bin\\j9vm"),
+ _T("client"), _T("..\\jre\\bin\\client"),
+ _T("server"), _T("..\\jre\\bin\\server"),
+ _T("classic"), _T("..\\jre\\bin\\classic"),
+ _T("jrockit"), _T("..\\jre\\bin\\jrockit"),
+ NULL };
+/* for detecting sun vms */
+typedef struct {
+ WORD language;
+ WORD codepage;
+} TRANSLATIONS;
+
+#define COMPANY_NAME_KEY _T_ECLIPSE("\\StringFileInfo\\%04x%04x\\CompanyName")
+#define SUN_MICROSYSTEMS _T_ECLIPSE("Sun Microsystems")
+
+delegate void NoArgsHandler ();
+
+public ref class Globals {
+public:
+ static Window^ window = nullptr;
+ static DispatcherFrame^ frame = nullptr;
+
+ static void HandleDispatcherInactive (Object^ o, EventArgs^ e) {
+ if (frame != nullptr) frame->Continue = false;
+ }
+ static void HandleClosing (Object^ o, CancelEventArgs^ e) {
+ window = nullptr;
+ }
+ static void HandleTimer (Object^ o, EventArgs^ e) {
+ detectJvmExit();
+ if (jvmProcess == 0) {
+ if (frame != nullptr) {
+ frame->Continue = false;
+ }
+ }
+ }
+ static void CloseWindow () {
+ if (window != nullptr) {
+ window->Close();
+ window = nullptr;
+ }
+ }
+};
+
+
+/* Show the Splash Window
+ *
+ * Open the bitmap, insert into the splash window and display it.
+ *
+ */
+int showSplash( const _TCHAR* featureImage )
+{
+ static int splashing = 0;
+
+ if(splashing) {
+ /*splash screen is already showing, do nothing */
+ return 0;
+ }
+ if (featureImage == NULL)
+ return -1;
+
+ /* if Java was started first and is calling back to show the splash, we might not
+ * have initialized the window system yet
+ */
+ initWindowSystem(0, NULL, 1);
+
+ /* Load the bitmap for the feature. */
+ BitmapSource^ image = nullptr;
+ if (featureImage != NULL) {
+ String^ string = gcnew String (featureImage);
+ if (File::Exists (string)) {
+ Uri^ uri = gcnew Uri (string);
+ image = gcnew BitmapImage (uri);
+ }
+ }
+
+ /* If the bitmap could not be found, return an error. */
+ if (image == nullptr)
+ return ERROR_FILE_NOT_FOUND;
+
+ /* Create a window that has no decorations. */
+ Window^ window = Globals::window = gcnew Window();
+ window->Closing += gcnew CancelEventHandler(&Globals::HandleClosing);
+ window->WindowStyle = WindowStyle::None;
+ window->ShowInTaskbar = false;
+ window->ResizeMode = ResizeMode::NoResize;
+ window->WindowStartupLocation = WindowStartupLocation::CenterScreen;
+ KeyboardNavigation::SetTabNavigation (window, KeyboardNavigationMode::None);
+
+ Grid^ grid = gcnew Grid();
+ GridLength length (1, GridUnitType::Auto);
+ ColumnDefinition^ column = gcnew ColumnDefinition();
+ grid->ColumnDefinitions->Add (column);
+ column = gcnew ColumnDefinition();
+ column->Width = length;
+ grid->ColumnDefinitions->Add (column);
+ RowDefinition^ row = gcnew RowDefinition ();
+ row->Height = length;
+ grid->RowDefinitions->Add (row);
+ row = gcnew RowDefinition ();
+ grid->RowDefinitions->Add (row);
+ row = gcnew RowDefinition ();
+ row->Height = length;
+ grid->RowDefinitions->Add (row);
+ window->Content = grid;
+
+ Canvas^ canvas = gcnew Canvas ();
+ canvas->FocusVisualStyle = nullptr;
+ canvas->Focusable = true;
+ Grid::SetRow (canvas, 1);
+ Grid::SetColumn (canvas, 0);
+ grid->Children->Add (canvas);
+
+ ImageBrush^ brush = gcnew ImageBrush(image);
+ canvas->Background = brush;
+
+ window->Width = image->Width;
+ window->Height = image->Height;
+ window->Show();
+
+ splashing = 1;
+
+ /* Process messages */
+ dispatchMessages();
+ return 0;
+}
+
+void dispatchMessages() {
+ DispatcherFrame^ frame = gcnew DispatcherFrame();
+ Globals::frame = frame;
+ EventHandler^ handler = gcnew EventHandler (&Globals::HandleDispatcherInactive);
+ Dispatcher^ dispatcher = Dispatcher::CurrentDispatcher;
+ DispatcherHooks^ hooks = dispatcher->Hooks;
+ hooks->DispatcherInactive += handler;
+ Dispatcher::PushFrame (frame);
+ hooks->DispatcherInactive -= handler;
+ Globals::frame = nullptr;
+}
+
+jlong getSplashHandle() {
+ Window^ window = Globals::window;
+ return (jlong)(int)GCHandle::ToIntPtr(GCHandle::Alloc(window));
+}
+
+void takeDownSplash() {
+ if (false) {
+ NoArgsHandler^ handler = gcnew NoArgsHandler(&Globals::CloseWindow);
+ Dispatcher::CurrentDispatcher->BeginInvoke(DispatcherPriority::Send, handler);
+ } else {
+ Window^ window = Globals::window;
+ if(window != nullptr) {
+ window->Close ();
+ window = nullptr;
+ dispatchMessages();
+ }
+ }
+}
+
+/* Get the window system specific VM args */
+_TCHAR** getArgVM( _TCHAR *vm )
+{
+ return argVM;
+}
+
+/* Local functions */
+
+/*
+ * Find the VM shared library starting from the java executable
+ */
+_TCHAR * findVMLibrary( _TCHAR* command ) {
+ _TCHAR* lib = findLib(command);
+ if( lib != NULL ) {
+ adjustSearchPath(lib);
+ }
+ return lib;
+}
+
+void adjustSearchPath( _TCHAR* vmLib ){
+ _TCHAR ** paths;
+ _TCHAR * path = NULL, *newPath = NULL;
+ _TCHAR * buffer, *c;
+ int i, length;
+ int needAdjust = 0, freePath = 0;
+
+ /* we want the directory containing the library, and the parent directory of that */
+ paths = getVMLibrarySearchPath(vmLib);
+
+ /* first call to GetEnvironmentVariable tells us how big to make the buffer */
+ length = GetEnvironmentVariable(_T_ECLIPSE("PATH"), path, 0);
+ if (length > 0) {
+ path = (_TCHAR*)malloc(length * sizeof(_TCHAR));
+ GetEnvironmentVariable(_T_ECLIPSE("PATH"), path, length);
+ needAdjust = !containsPaths(path, paths);
+ freePath = 1;
+ } else {
+ path = _T_ECLIPSE("");
+ freePath = 0;
+ needAdjust = 1;
+ }
+
+ if (needAdjust) {
+ c = concatStrings(paths);
+ newPath = (_TCHAR*)malloc((_tcslen(c) + length + 1) * sizeof(_TCHAR));
+ _stprintf(newPath, _T_ECLIPSE("%s%s"), c, path);
+ SetEnvironmentVariable( _T_ECLIPSE("PATH"), newPath);
+ free(c);
+ free(newPath);
+ }
+
+ for (i = 0; i < 2 && paths[i] != NULL; i++)
+ free(paths[i]);
+ free(paths);
+ if (freePath)
+ free(path);
+}
+
+static _TCHAR* findLib( _TCHAR* command ) {
+ int i, j;
+ int pathLength;
+ struct _stat stats;
+ _TCHAR * path; /* path to resulting jvm shared library */
+ _TCHAR * location; /* points to begining of jvmLocations section of path */
+
+ /* for looking in the registry */
+ HKEY jreKey = NULL;
+ DWORD length = MAX_PATH;
+ _TCHAR keyName[MAX_PATH];
+ _TCHAR * jreKeyName;
+
+ if (command != NULL) {
+ location = lastDirSeparator( command ) + 1;
+
+ /*check first to see if command already points to the library */
+ if (isVMLibrary(command)) {
+ if (_tstat( command, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ return command; /* exists */
+ return NULL; /* doesn't exist */
+ }
+
+ pathLength = location - command;
+ path = (_TCHAR *)malloc((pathLength + MAX_LOCATION_LENGTH + 1 + _tcslen(vmLibrary) + 1) * sizeof(_TCHAR));
+ _tcsncpy(path, command, pathLength);
+ location = &path[pathLength];
+
+ /*
+ * We are trying base/jvmLocations[*]/vmLibrary
+ * where base is the directory containing the given java command, normally jre/bin
+ */
+ i = -1;
+ while(jvmLocations[++i] != NULL) {
+ _stprintf(location, _T_ECLIPSE("%s%c%s"), jvmLocations[i], dirSeparator, vmLibrary);
+ if (_tstat( path, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /* found it */
+ return path;
+ }
+ }
+ }
+
+ /* Not found yet, try the registry, we will use the first vm >= 1.4 */
+ jreKeyName = _T("Software\\JavaSoft\\Java Runtime Environment");
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, jreKeyName, 0, KEY_READ, &jreKey) == ERROR_SUCCESS) {
+ if(RegQueryValueEx(jreKey, _T_ECLIPSE("CurrentVersion"), NULL, NULL, (LPBYTE)&keyName, &length) == ERROR_SUCCESS) {
+ path = checkVMRegistryKey(jreKey, keyName);
+ if (path != NULL) {
+ RegCloseKey(jreKey);
+ return path;
+ }
+ }
+ j = 0;
+ length = MAX_PATH;
+ while (RegEnumKeyEx(jreKey, j++, keyName, &length, 0, 0, 0, 0) == ERROR_SUCCESS) {
+ /*look for a 1.4 or 1.5 vm*/
+ if( _tcsncmp(_T("1.4"), keyName, 3) <= 0 ) {
+ path = checkVMRegistryKey(jreKey, keyName);
+ if (path != NULL) {
+ RegCloseKey(jreKey);
+ return path;
+ }
+ }
+ }
+ RegCloseKey(jreKey);
+ }
+ return NULL;
+}
+
+/*
+ * Read the subKeyName subKey of jreKey and look to see if it has a Value
+ * "RuntimeLib" which points to a jvm library we can use
+ *
+ * Does not close jreKey
+ */
+static _TCHAR* checkVMRegistryKey(HKEY jreKey, _TCHAR* subKeyName) {
+ _TCHAR value[MAX_PATH];
+ HKEY subKey = NULL;
+ DWORD length = MAX_PATH;
+ _TCHAR *result = NULL;
+ struct _stat stats;
+
+ if(RegOpenKeyEx(jreKey, subKeyName, 0, KEY_READ, &subKey) == ERROR_SUCCESS) {
+ /*The RuntimeLib value should point to the library we want*/
+ if(RegQueryValueEx(subKey, _T("RuntimeLib"), NULL, NULL, (LPBYTE)&value, &length) == ERROR_SUCCESS) {
+ if (_tstat( value, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /*library exists*/
+ result = _tcsdup(value);
+ }
+ }
+ RegCloseKey(subKey);
+ }
+ return result;
+}
+
+static _TCHAR* buildCommandLine( _TCHAR* program, _TCHAR* args[] )
+{
+ int index, length = 0, slash;
+ _TCHAR *commandLine, *ch, *space;
+
+ /*
+ * Build the command line. Any argument with spaces must be in
+ * double quotes in the command line.
+ */
+ if(program != NULL)
+ length = _tcslen(program) + 1;
+ for (index = 0; args[index] != NULL; index++)
+ {
+ /* String length plus space character */
+ length += _tcslen( args[ index ] ) + 1;
+ /* Quotes + potential escaping '\' */
+ if (_tcschr( args[ index ], _T(' ') ) != NULL) length += 3;
+ }
+
+ commandLine = ch = (_TCHAR *)malloc ( (length + 1) * sizeof(_TCHAR) );
+ if (program != NULL) {
+ _tcscpy(ch, program);
+ ch += _tcslen(program);
+ *ch++ = _T(' ');
+ }
+ for (index = 0; args[index] != NULL; index++)
+ {
+ space = _tcschr( args[ index ], _T(' '));
+ if (space != NULL) *ch++ = _T('\"');
+ _tcscpy( ch, args[index] );
+ ch += _tcslen( args[index] );
+ if (space != NULL) {
+ if ( *(ch - 1) == _T('\\') ) {
+ /* escape a trailing unescaped '\' or it will escape our closing '"' and mess things up */
+ slash = 1;
+ while ( *(ch - 1 - slash) == _T('\\')) slash++;
+ if (slash % 2) *ch++ = _T('\\');
+ }
+ *ch++ = _T('\"');
+ }
+ *ch++ = _T(' ');
+ }
+ *ch = _T('\0');
+ return commandLine;
+}
+void restartLauncher( _TCHAR* program, _TCHAR* args[] )
+{
+ _TCHAR* commandLine = buildCommandLine(program, args);
+
+ {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ GetStartupInfo(&si);
+ if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ CloseHandle( pi.hThread );
+ }
+ }
+ free(commandLine);
+}
+
+JavaResults* launchJavaVM( _TCHAR* args[] )
+{
+ MSG msg;
+ _TCHAR* commandLine;
+ jvmProcess = -1;
+ commandLine = buildCommandLine(NULL, args);
+ jvmResults = (JavaResults*) malloc(sizeof(JavaResults));
+ memset(jvmResults, 0, sizeof(JavaResults));
+
+ /*
+ * Start the Java virtual machine. Use CreateProcess() instead of spawnv()
+ * otherwise the arguments cannot be freed since spawnv() segments fault.
+ */
+ {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ GetStartupInfo(&si);
+ if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ CloseHandle( pi.hThread );
+ jvmProcess = (int)pi.hProcess;
+ }
+ }
+
+ free( commandLine );
+
+ /* If the child process (JVM) would not start */
+ if (jvmProcess == -1)
+ {
+ /* Return the error number. */
+ jvmResults->launchResult = errno;
+ jvmProcess = 0;
+ }
+
+ /* else */
+ else
+ {
+
+ /* Set a timer to detect JVM process termination. */
+ DispatcherTimer^ timer = gcnew DispatcherTimer();
+ timer->Interval = TimeSpan::FromMilliseconds (jvmExitTimeout);
+ timer->Tick += gcnew EventHandler(&Globals::HandleTimer);
+
+ /* Process messages until the JVM terminates.
+ This launcher process must continue to process events until the JVM exits
+ or else Windows 2K will hang if the desktop properties (e.g., background) are
+ changed by the user. Windows does a SendMessage() to every top level window
+ process, which blocks the caller until the process responds. */
+
+ DispatcherFrame^ frame = gcnew DispatcherFrame();
+ Globals::frame = frame;
+ timer->Start();
+ Dispatcher::PushFrame(frame);
+ Globals::frame = nullptr;
+ timer->Stop();
+
+ }
+
+ /* Return the exit code from the JVM. */
+ return jvmResults;
+}
+
+/* Detect JVM Process Termination */
+static void CALLBACK detectJvmExit ()
+{
+ DWORD exitCode;
+ /* If the JVM process has terminated */
+ if (!GetExitCodeProcess( (HANDLE)jvmProcess, &exitCode ) ||
+ exitCode != STILL_ACTIVE)
+ {
+ /* Save the JVM exit code. This should cause the loop in launchJavaVM() to exit. */
+ jvmResults->runResult = exitCode;
+ jvmProcess = 0;
+ }
+}
+
+void processVMArgs(_TCHAR **vmargs[] ) {
+// /* nothing yet */
+}
+
+JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile )
+{
+ return startJavaJNI(libPath, vmArgs, progArgs, jarFile);
+}
+
+int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib ) {
+ _TCHAR *vm = (jniLib != NULL) ? jniLib : javaVM;
+ int result = 0;
+ DWORD infoSize;
+ DWORD handle;
+ void * info;
+
+ _TCHAR * key, *value;
+ size_t i;
+ int valueSize;
+
+ if (vm == NULL)
+ return 0;
+
+ infoSize = GetFileVersionInfoSize(vm, &handle);
+ if (infoSize > 0) {
+ info = malloc(infoSize);
+ if (GetFileVersionInfo(vm, 0, infoSize, info)) {
+ TRANSLATIONS * translations;
+ int translationsSize;
+ VerQueryValue(info, _T_ECLIPSE("\\VarFileInfo\\Translation"), (LPVOID *) &translations, (PUINT)&translationsSize);
+
+ /* this size is only right because %04x is 4 characters */
+ key = (_TCHAR *) malloc( (_tcslen(COMPANY_NAME_KEY) + 1) * sizeof(_TCHAR));
+ for (i = 0; i < (translationsSize / sizeof(TRANSLATIONS)); i++) {
+ _stprintf(key, COMPANY_NAME_KEY, translations[i].language, translations[i].codepage);
+
+ VerQueryValue(info, key, (LPVOID *)&value, (PUINT)&valueSize);
+ if (_tcsncmp(value, SUN_MICROSYSTEMS, _tcslen(SUN_MICROSYSTEMS)) == 0) {
+ result = 1;
+ break;
+ }
+ }
+ free(key);
+ }
+ free(info);
+ }
+ return result;
+}
+
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
+ /* not implemented for WPF */
+ return -1;
+}
+} // extern "C"
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpfCommon.cpp b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpfCommon.cpp
new file mode 100644
index 000000000..03ce3fceb
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/eclipseWpfCommon.cpp
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Niefer
+ *******************************************************************************/
+
+
+extern "C" {
+
+#include "eclipseCommon.h"
+#include "eclipseOS.h"
+
+#include <windows.h>
+#include <stdlib.h>
+#include <commctrl.h>
+
+
+#define ECLIPSE_ICON 401
+
+_TCHAR dirSeparator = _T('\\');
+_TCHAR pathSeparator = _T(';');
+
+static int initialized = 0;
+
+/* Load the specified shared library
+ */
+void * loadLibrary( _TCHAR * library ){
+ return (void *)LoadLibrary(library);
+}
+
+/* Unload the shared library
+ */
+void unloadLibrary( void * handle ){
+ FreeLibrary((HMODULE)handle);
+}
+
+/* Find the given symbol in the shared library
+ */
+void * findSymbol( void * handle, _TCHAR * symbol ){
+ char * str = NULL;
+ void * result;
+
+ str = toNarrow(symbol);
+ result = GetProcAddress((HMODULE)handle, str);
+ free(str);
+ return result;
+}
+
+_TCHAR* resolveSymlinks( _TCHAR* path ) {
+ /* no symlinks on windows */
+ return path;
+}
+
+} //end extern C
+
+/* Display a Message */
+void displayMessage( _TCHAR* title, _TCHAR* message )
+{
+ if(!initialized)
+ initWindowSystem(0, NULL, 0);
+
+ System::String^ titleStr = gcnew System::String (title);
+ System::String^ messageStr = gcnew System::String (message);
+ System::Windows::MessageBox::Show (messageStr, titleStr, System::Windows::MessageBoxButton::OK);
+}
+
+/* Initialize Window System
+ *
+ * Create a pop window to display the bitmap image.
+ *
+ * Return the window handle as the data for the splash command.
+ *
+ */
+int initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash )
+{
+
+ if(initialized)
+ return 0;
+ initialized = 1;
+ return 0;
+}
diff --git a/features/org.eclipse.equinox.executable.feature/library/wpf/make_wpf.mak b/features/org.eclipse.equinox.executable.feature/library/wpf/make_wpf.mak
new file mode 100644
index 000000000..1d92df461
--- /dev/null
+++ b/features/org.eclipse.equinox.executable.feature/library/wpf/make_wpf.mak
@@ -0,0 +1,113 @@
+#******************************************************************************
+# Copyright (c) 2000, 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Kevin Cornell (Rational Software Corporation)
+#*******************************************************************************
+
+# Makefile for creating the eclipse launcher program.
+
+# This makefile expects the following environment variables set:
+#
+# PROGRAM_OUTPUT - the filename of the output executable
+# PROGRAM_LIBRARY - the filename of the output dll library
+# DEFAULT_OS - the default value of the "-os" switch
+# DEFAULT_OS_ARCH - the default value of the "-arch" switch
+# DEFAULT_WS - the default value of the "-ws" switch
+# JAVA_HOME - the location of the Java for JNI includes
+NODEBUG=1
+!include <..\make_version.mak>
+
+PROGRAM_LIBRARY = eclipse_$(LIB_VERSION).dll
+PROGRAM_OUTPUT=eclipse.exe
+# Separate filename from extention
+PROGRAM_NAME=$(PROGRAM_OUTPUT:.exe=)
+
+# Define the object modules to be compiled and flags.
+MAIN_OBJS = eclipseMain.obj
+COMMON_OBJS = eclipseConfig.obj eclipseCommon.obj eclipseWpfCommon.obj
+DLL_OBJS = eclipse.obj eclipseWpf.obj eclipseUtil.obj eclipseJNI.obj eclipseShm.obj
+
+LIBS = kernel32.lib msvcrt.lib mscoree.lib
+DLL_LIBS = kernel32.lib Advapi32.lib msvcrt.lib version.lib
+LFLAGS = -CLRTHREADATTRIBUTE:STA /NODEFAULTLIB:LIBCMT /INCREMENTAL:NO /LARGEADDRESSAWARE /RELEASE /NOLOGO -subsystem:windows,4.0 -entry:wmainCRTStartup
+CONSOLEFLAGS = -CLRTHREADATTRIBUTE:STA /NODEFAULTLIB:LIBCMT /INCREMENTAL:NO /LARGEADDRESSAWARE /RELEASE /NOLOGO -subsystem:console,4.0 -entry:wmainCRTStartup
+DLL_LFLAGS = -CLRTHREADATTRIBUTE:STA /NODEFAULTLIB:LIBCMT /INCREMENTAL:NO /LARGEADDRESSAWARE /PDB:NONE -dll /BASE:0x72000000 /DLL
+RES = $(PROGRAM_NAME).res
+EXEC = $(PROGRAM_OUTPUT)
+CONSOLE = $(PROGRAM_NAME)c.exe
+DLL = $(PROGRAM_LIBRARY)
+DEBUG = #$(cdebug)
+
+CFLAGS = -c -DUNICODE -DVISTA -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NON_CONFORMING_SWPRINTFS -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \
+ -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \
+ -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \
+ -I$(JAVA_HOME)\include -I$(JAVA_HOME)\include\win32 \
+ $(cflags)
+
+WPF_HOME = C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0
+DOTNET_HOME = C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
+CPPFLAGS = -clr /FU"$(WPF_HOME)\PresentationCore.dll" /FU"$(WPF_HOME)\PresentationFramework.dll" /FU$(DOTNET_HOME)\System.Data.dll /FU$(DOTNET_HOME)\System.dll /FU$(DOTNET_HOME)\System.Xml.dll /FU"$(WPF_HOME)\UIAutomationProvider.dll" /FU"$(WPF_HOME)\UIAutomationTypes.dll" /FU"$(WPF_HOME)\WindowsBase.dll"
+
+
+all: $(EXEC) $(DLL) com $(CONSOLE)
+
+eclipseMain.obj: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipseMain.c
+
+eclipseCommon.obj: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipseCommon.c
+
+eclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipse.c
+
+eclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipseUtil.c
+
+eclipseConfig.obj: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipseConfig.c
+
+eclipseWpf.obj: ../eclipseOS.h ../eclipseUnicode.h eclipseWpf.cpp
+ $(CC) $(DEBUG) $(CFLAGS) $(CPPFLAGS) $(cvarsdll) /Fo$*.obj eclipseWpf.cpp
+
+eclipseWpfCommon.obj: ../eclipseCommon.h eclipseWpfCommon.cpp
+ $(CC) $(DEBUG) $(CFLAGS) $(CPPFLAGS) $(cvarsdll) /Fo$*.obj eclipseWpfCommon.cpp
+
+eclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipseJNI.c
+
+eclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj ../eclipseShm.c
+
+$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS)
+ rc.exe -r -fo $(RES) $(PROGRAM_NAME).rc
+ link $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS)
+ mt.exe -manifest $(PROGRAM_OUTPUT).manifest -outputresource:$(PROGRAM_OUTPUT);2
+
+$(CONSOLE): $(MAIN_OBJS) $(COMMON_OBJS)
+ del -f eclipseConfig.obj
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) -D_WIN32_CONSOLE /FoeclipseConfig.obj ../eclipseConfig.c
+ link $(CONSOLEFLAGS) -out:$(CONSOLE) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS)
+ mt.exe -manifest $(PROGRAM_OUTPUT).manifest -outputresource:$(CONSOLE);2
+
+$(DLL): $(DLL_OBJS) $(COMMON_OBJS)
+ link $(DLL_LFLAGS) -out:$(PROGRAM_LIBRARY) $(DLL_OBJS) $(COMMON_OBJS) $(DLL_LIBS)
+ mt.exe -manifest $(PROGRAM_LIBRARY).manifest -outputresource:$(PROGRAM_LIBRARY);2
+
+com.obj: com.c
+ $(CC) $(DEBUG) $(CFLAGS) $(cvarsdll) /Fo$*.obj com.c
+
+com: com.obj
+ link /DLL -out:com_$(LIB_VERSION).dll com.obj ole32.lib
+
+install: all
+ copy $(EXEC) $(OUTPUT_DIR)
+ del -f $(EXEC) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES)
+
+clean:
+ del $(EXEC) $(DLL) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES) *.manifest *.exp *.lib *.dll

Back to the top