diff options
author | Andrew Niefer | 2006-11-13 14:55:12 -0500 |
---|---|---|
committer | Andrew Niefer | 2006-11-13 14:55:12 -0500 |
commit | 8f640484342701bc3ae07338370ba4a906c72dac (patch) | |
tree | 503fc359f8d0cabcf322ca615d5b6987fe97c0f3 | |
parent | 5ea0f123db7a598111065de9cf7b484f2239a61b (diff) | |
download | rt.equinox.framework-8f640484342701bc3ae07338370ba4a906c72dac.tar.gz rt.equinox.framework-8f640484342701bc3ae07338370ba4a906c72dac.tar.xz rt.equinox.framework-8f640484342701bc3ae07338370ba4a906c72dac.zip |
Initial code from platform-launcher
58 files changed, 7828 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.launcher/.cdtproject b/bundles/org.eclipse.equinox.launcher/.cdtproject new file mode 100644 index 000000000..d81ca9d42 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/.cdtproject @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse-cdt version="2.0"?> + +<cdtproject id="org.eclipse.cdt.make.core.make"> +<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> +<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/> +<extension id="org.eclipse.cdt.core.MachO" point="org.eclipse.cdt.core.BinaryParser"> +<attribute key="c++filt" value="c++filt"/> +</extension> +<data> +<item id="scannerConfiguration"> +<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/> +<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"> +<buildOutputProvider> +<openAction enabled="true" filePath=""/> +<parser enabled="true"/> +</buildOutputProvider> +<scannerInfoProvider id="specsFile"> +<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> +<parser enabled="true"/> +</scannerInfoProvider> +</profile> +<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"> +<buildOutputProvider> +<openAction enabled="false" filePath=""/> +<parser enabled="true"/> +</buildOutputProvider> +<scannerInfoProvider id="makefileGenerator"> +<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> +<parser enabled="false"/> +</scannerInfoProvider> +</profile> +<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile"> +<buildOutputProvider> +<openAction enabled="false" filePath=""/> +<parser enabled="true"/> +</buildOutputProvider> +<scannerInfoProvider id="specsFile"> +<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> +<parser enabled="false"/> +</scannerInfoProvider> +</profile> +<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile"> +<buildOutputProvider> +<openAction enabled="false" filePath=""/> +<parser enabled="true"/> +</buildOutputProvider> +<scannerInfoProvider id="specsFile"> +<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> +<parser enabled="false"/> +</scannerInfoProvider> +</profile> +</item> +<item id="org.eclipse.cdt.core.pathentry"> +<pathentry kind="src" path=""/> +<pathentry kind="out" path=""/> +<pathentry kind="con" path="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/> +</item> +</data> +</cdtproject> diff --git a/bundles/org.eclipse.equinox.launcher/.project b/bundles/org.eclipse.equinox.launcher/.project new file mode 100644 index 000000000..c88f4d22b --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/.project @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.equinox.launcher</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.make.core.makeBuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + <dictionary> + <key>org.eclipse.cdt.make.core.build.arguments</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.core.errorOutputParser</key> + <value>org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.VCErrorParser;</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableAutoBuild</key> + <value>false</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.environment</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableFullBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.build.target.inc</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.build.target.clean</key> + <value>clean</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.build.command</key> + <value>make</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableCleanBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.append_environment</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.build.target.auto</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.stopOnError</key> + <value>false</value> + </dictionary> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.make.core.ScannerConfigBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.make.core.makeNature</nature> + <nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature> + </natures> +</projectDescription> diff --git a/bundles/org.eclipse.equinox.launcher/.settings/org.eclipse.cdt.core.prefs b/bundles/org.eclipse.equinox.launcher/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 000000000..a44ad7e23 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,3 @@ +#Mon Nov 13 14:48:49 EST 2006 +eclipse.preferences.version=1 +indexerId=org.eclipse.cdt.core.fastIndexer diff --git a/bundles/org.eclipse.equinox.launcher/library/carbon/.cvsignore b/bundles/org.eclipse.equinox.launcher/library/carbon/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/carbon/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.launcher/library/carbon/build.sh b/bundles/org.eclipse.equinox.launcher/library/carbon/build.sh new file mode 100644 index 000000000..c5454cdb3 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/carbon/build.sh @@ -0,0 +1,79 @@ +#!/bin/sh +#******************************************************************************* +# Copyright (c) 2000, 2005 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="" # for universal binary the arch is not specified +defaultWS="carbon" +makefile="make_macosx.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" +PPC_OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/ppc/Eclipse.app/Contents/MacOS" +X86_OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/x86/Eclipse.app/Contents/MacOS" + +export PPC_OUTPUT_DIR X86_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/bundles/org.eclipse.equinox.launcher/library/carbon/build.xml b/bundles/org.eclipse.equinox.launcher/library/carbon/build.xml new file mode 100644 index 000000000..b4308a9a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/carbon/build.xml @@ -0,0 +1,21 @@ +<?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> + <eclipse.refreshLocal resource="platform-launcher" depth="infinite" /> +</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/bundles/org.eclipse.equinox.launcher/library/carbon/eclipse.c b/bundles/org.eclipse.equinox.launcher/library/carbon/eclipse.c new file mode 100644 index 000000000..897aeca53 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/carbon/eclipse.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2000, 2005 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 "../eclipse.c" diff --git a/bundles/org.eclipse.equinox.launcher/library/carbon/eclipseCarbon.c b/bundles/org.eclipse.equinox.launcher/library/carbon/eclipseCarbon.c new file mode 100644 index 000000000..2d5afd9f7 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/carbon/eclipseCarbon.c @@ -0,0 +1,704 @@ +/* + * Copyright (c) 2000, 2005 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) + */ + +/* MacOS X Carbon specific logic for displaying the splash screen. */ + +#include "eclipseOS.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> + +#include "NgCommon.h" +#include "NgImageData.h" +#include "NgWinBMPFileFormat.h" + +#define startupJarName "startup.jar" +#define APP_PACKAGE_PATTERN ".app/Contents/MacOS/" +#define APP_PACKAGE "APP_PACKAGE" +#define JAVAROOT "JAVAROOT" +#define LAUNCHER "-launcher" +#define SPLASH_LAUNCHER "/Resources/Splash.app/Contents/" + +#define DEBUG 0 + +char *findCommand(char *command); +char* getProgramDir(); + +static void debug(const char *fmt, ...); +static void dumpArgs(char *tag, int argc, char* argv[]); +static PixMapHandle loadBMPImage(const char *image); +static void init(); +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); + +/* Global Variables */ +char dirSeparator = '/'; +char pathSeparator = ':'; +char* consoleVM = "java"; +char* defaultVM = "java"; +char* shippedVMDir = "jre/bin/"; + +/* Define the window system arguments for the various Java VMs. */ +static char* argVM_JAVA[] = { "-XstartOnFirstThread", NULL }; + +static int fgPid, jvmPid, jvmExitCode = 0; +static FILE *fgConsoleLog; +static char *fgAppPackagePath; + +static int mainEclipse = 0; +static WindowRef window; +static ControlRef progress = NULL, pane = NULL; +static RGBColor foreground = {0xFFFF, 0xFFFF, 0xFFFF}; +static CFStringRef string = NULL; +static Rect messageRect = {0, 0, 0, 0}, progressRect = {0, 0, 0, 0}; +static int value = 0, maximum = 0; + +extern int original_main(int argc, char* argv[]); +int main( int argc, char* argv[] ) { + + SInt32 systemVersion= 0; + if (Gestalt(gestaltSystemVersion, &systemVersion) == noErr) { + systemVersion &= 0xffff; + if (systemVersion < 0x1020) { + displayMessage(officialName, "Eclipse requires Jaguar (Mac OS X >= 10.2)"); + return 0; + } + } + + fgConsoleLog= fopen("/dev/console", "w"); + fgPid= getpid(); + + dumpArgs("start", argc, argv); + + if (argc > 1 && strncmp(argv[1], "-psn_", 5) == 0) { + + /* 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; +} + +/* 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, kCFStringEncodingASCII); + free(buffer); + inDescription= CFStringCreateWithCString(kCFAllocatorDefault, pos+2, kCFStringEncodingASCII); + } else { + inError= CFStringCreateWithCString(kCFAllocatorDefault, message, kCFStringEncodingASCII); + } + + init(); + + 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); + } + CFRelease(inError); + if (inDescription != NULL) + CFRelease(inDescription); +} + +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 +} + +static void init() { + static int initialized= 0; + + if (!initialized) { + ProcessSerialNumber psn; + if (GetCurrentProcess(&psn) == noErr) { + if (mainEclipse) { + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + } + SetFrontProcess(&psn); + } + ClearMenuBar(); + initialized= true; + } +} + +/* Initialize Window System + * + * Initialize Carbon. + */ +void initWindowSystem( int* pArgc, char* argv[], int showSplash ) +{ + char *homeDir = getProgramDir(); + debug("install dir: %s\n", homeDir); + if (homeDir != NULL) + chdir(homeDir); + + mainEclipse = !showSplash; + if (showSplash) + init(); +} + +static void eventLoopTimerProc(EventLoopTimerRef inTimer, void *inUserData) { + QuitApplicationEventLoop(); +} + +static void detectExitTimerProc(EventLoopTimerRef inTimer, void *inUserData) { + int exitCode = 0; + if (waitpid(jvmPid, &exitCode, WNOHANG) != 0) { + jvmExitCode = exitCode; + QuitApplicationEventLoop(); + } +} + +static void invalidateWindow () { + Rect rect; + RgnHandle rgn; + ControlRef root; + rgn = NewRgn(); + GetRootControl(window, &root); + GetControlBounds(root, &rect); + SetRectRgn(rgn, rect.left, rect.top, rect.right, rect.bottom); + InvalWindowRgn (window, rgn); + DisposeRgn(rgn); +} + +static void readRect(char *str, Rect *rect) { + int x, y, width, height; + char *temp = str, *comma; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + x = atoi(temp); + temp = comma + 1; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + y = atoi(temp); + temp = comma + 1; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + width = atoi(temp); + temp = comma + 1; + height = atoi(temp); + rect->left = x; + rect->top = y; + rect->right = x + width; + rect->bottom = y + height; +} + +static void readColor(char *str, RGBColor *color) { + int value = atoi(str); + color->red = ((value & 0xFF0000) >> 16) * 0xFF; + color->green = ((value & 0xFF00) >> 8) * 0xFF; + color->blue = ((value & 0xFF) >> 0) * 0xFF; +} + +static void readInput() { + int available; + FILE *fd = stdin; + char *buffer = NULL, *equals = NULL, *end, *line; + ioctl(fileno(fd), FIONREAD, &available); + if (available <= 0) return; + buffer = malloc(available + 1); + available = fread(buffer, 1, available, fd); + buffer[available] = 0; + line = buffer; + while (line != NULL) { + end = strchr(line, '\n'); + equals = strchr(line, '='); + if (end != NULL) end[0] = 0; + if (equals != NULL) { + char *str = (char *)equals + 1; + equals[0] = 0; + if (strcmp(line, "maximum") == 0) { + maximum = atoi(str); + if (progress) { + SetControl32BitMaximum (progress, maximum); + } + } else if (strcmp(line, "value") == 0) { + value = atoi(str); + if (progress) { + SetControl32BitValue (progress, value); + } + } else if (strcmp(line, "progressRect") == 0) { + readRect(str, &progressRect); + if (progress) { + SetControlBounds (progress, &progressRect); + } + } else if (strcmp(line, "messageRect") == 0) { + readRect(str, &messageRect); + invalidateWindow(); + } else if (strcmp(line, "foreground") == 0) { + readColor(str, &foreground); + invalidateWindow(); + } else if (strcmp(line, "message") == 0) { + if (string != NULL) CFRelease(string); + string = CFStringCreateWithBytes (kCFAllocatorDefault, (UInt8 *)str, strlen(str), CFStringGetSystemEncoding(), 1); + invalidateWindow(); + } + + } + if (end != NULL) line = end + 1; + else line = NULL; + } + free(buffer); +} + +static void timerProc(EventLoopTimerRef inTimer, void *inUserData) { + readInput(); +} + +static OSStatus drawProc (EventHandlerCallRef eventHandlerCallRef, EventRef eventRef, PixMap * pixmap) { + Rect rect; + int result = CallNextEventHandler(eventHandlerCallRef, eventRef); + GrafPtr port = GetWindowPort(window); + SetPort(port); + GetControlBounds(pane, &rect); + CopyBits((BitMap*)pixmap, GetPortBitMapForCopyBits(port), &rect, &rect, srcCopy, NULL); + if (string != NULL) { + RGBForeColor(&foreground); + DrawThemeTextBox(string, kThemeSmallSystemFont, kThemeStateActive, 1, &messageRect, teFlushLeft, NULL); + } + return result; +} + +/* Show the Splash Window + * + * Create the splash window, load the bitmap and display the splash window. + */ +int showSplash( char* timeoutString, char* featureImage ) +{ + Rect wRect; + int w, h, deviceWidth, deviceHeight; + PixMap *pm; + PixMapHandle pixmap; + EventTypeSpec draw = {kEventClassControl, kEventControlDraw}; + + debug("featureImage: %s\n", featureImage); + + init(); + + /* Determine the splash timeout value (in seconds). */ + if (timeoutString != NULL && strlen(timeoutString) > 0) { + int timeout; + if (sscanf(timeoutString, "%d", &timeout) == 1) { + InstallEventLoopTimer(GetMainEventLoop(), (EventTimerInterval) timeout, 0.0, NewEventLoopTimerUPP(eventLoopTimerProc), NULL, NULL); + } + } + + pixmap= loadBMPImage(featureImage); + /* If the splash image data could not be loaded, return an error. */ + if (pixmap == NULL) + return ENOENT; + + pm= *pixmap; + w= pm->bounds.right; + h= pm->bounds.bottom; + + 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; + + CreateNewWindow(kModalWindowClass, kWindowStandardHandlerAttribute, &wRect, &window); + if (window != NULL) { + ControlRef root = NULL; + CreateRootControl(window, &root); + GetRootControl(window, &root); + SetRect(&wRect, 0, 0, w, h); + CreateUserPaneControl(window, &wRect, 0, &pane); + EmbedControl(pane, root); + CreateProgressBarControl(window, &progressRect, value, 0, maximum, 0, &progress); + EmbedControl(progress, pane); + InstallEventHandler(GetControlEventTarget(pane), (EventHandlerUPP)drawProc, 1, &draw, pm, NULL); + readInput(); + InstallEventLoopTimer (GetCurrentEventLoop (), 50 / 1000.0, 50 / 1000.0, NewEventLoopTimerUPP(timerProc), NULL, NULL); + ShowWindow(window); + RunApplicationEventLoop(); + DisposeWindow(window); + if (string != NULL) CFRelease(string); + string = NULL; + progress = pane = NULL; + } + + return 0; +} + + +/* 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; +} + +/* 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[] ) +{ + unsigned int length = 1024, rc; + int launcherIndex = 0, exitCode; + char *launcher = NULL, *oldLauncher = NULL, *newLauncher = NULL, *path = args[0]; + + /* + * In order to be able to keep the Java VM in the Dock and restart + * it, the first value of the list of arguments passed to execv() + * is changed to point back to the Eclipse launcher program. The Eclipse + * launcher program is marked as a LSBackgroundOnly app in its Info.plist + * file and the secondary launcher used to show the splash screen + * is marked as a LSUIElement app. Since it is not possible to change + * the Info.plist file dynamically, two application bundles are needed. + */ + launcher = malloc(length); + if ((rc = _NSGetExecutablePath(launcher, &length)) == -1) { + launcher = realloc(launcher, length); + rc = _NSGetExecutablePath(launcher, &length); + } + if (rc == 0) { + while (args[launcherIndex] != NULL) { + if (_tcsicmp( args[ launcherIndex++ ], LAUNCHER ) == 0) { + char *slash; + slash = strrchr (launcher, '/'); + if (slash) { + char * temp; + *slash = '\0'; + temp = strrchr (launcher, '/'); + *slash = '/'; + slash = temp; + } + if (slash) { + struct _stat stats; + char* buffer; + buffer = malloc(strlen(launcher) + strlen(SPLASH_LAUNCHER) + 1); + *slash = '\0'; + buffer[0] = '\0'; + strcat(buffer, launcher); + strcat(buffer, SPLASH_LAUNCHER); + strcat(buffer, slash + 1); + *slash = '/'; + if (stat(buffer, &stats) == 0) { + oldLauncher = args[launcherIndex]; + newLauncher = buffer; + args[launcherIndex] = buffer; + args[0] = launcher; + } else { + free(buffer); + } + } + break; + } + } + } + + /* Create a child process for the JVM. */ + pid_t pid= fork(); + if (pid == 0) { + + dumpArgs("execv", -1, args); + + /* Child process ... start the JVM */ + execv(path, args); + + /* The JVM would not start ... return error code to parent process. */ + _exit(errno); + } + + if (pid == -1) { + exitCode = errno; + } else { + /* wait for it to terminate processing events */ + jvmPid = pid; + InstallEventLoopTimer(GetCurrentEventLoop (), 100 / 1000.0, 100 / 1000.0, NewEventLoopTimerUPP(detectExitTimerProc), NULL, NULL); + RunApplicationEventLoop(); + exitCode = jvmExitCode; + exitCode = ((exitCode & 0x00ff) == 0 ? (exitCode >> 8) : exitCode); + } + + if (newLauncher != NULL) { + args[0] = path; + args[launcherIndex] = oldLauncher; + free(newLauncher); + } + if (launcher != NULL) free(launcher); + + return exitCode; +} + +/** + * 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 PixMapHandle loadBMPImage (const char *bmpPathname) { + ng_stream_t in; + ng_bitmap_image_t image; + ng_err_t err= ERR_OK; + PixMapHandle pixmap; + PixMap *pm; + + 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; + } + + pixmap= NewPixMap(); + if (pixmap == 0) { + NgBitmapImageFree(&image); + NgError(ERR_NG, "Error XCreatePixmap failed"); + return 0; + } + + pm= *pixmap; + + int width= (int)NgBitmapImageWidth(&image); + int height= (int)NgBitmapImageHeight(&image); + int rowBytes= width * 4; + + pm->bounds.right= width; + pm->bounds.bottom= height; + pm->rowBytes= rowBytes + 0x8000; + pm->baseAddr= NewPtr(rowBytes * height); + pm->pixelType= RGBDirect; + pm->pixelSize= 32; + pm->cmpCount= 3; + pm->cmpSize= 8; + + /* 24 bit source to direct screen destination */ + NgBitmapImageBlitDirectToDirect(NgBitmapImageImageData(&image), NgBitmapImageBytesPerRow(&image), width, height, + (UBYTE1*)pm->baseAddr, pm->pixelSize, rowBytes, NgIsMSB(), + 0xff0000, 0x00ff00, 0x0000ff); + + NgBitmapImageFree(&image); + + return pixmap; +} + +/* + * 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; +} + diff --git a/bundles/org.eclipse.equinox.launcher/library/carbon/make_macosx.mak b/bundles/org.eclipse.equinox.launcher/library/carbon/make_macosx.mak new file mode 100644 index 000000000..529d4b7a5 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/carbon/make_macosx.mak @@ -0,0 +1,66 @@ +#********************************************************************** +# Copyright (c) 2000, 2005 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) +#********************************************************************** + +# 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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseCarbon.o NgImageData.o NgWinBMPFileFormat.o NgCommon.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = -framework Carbon +ARCHS = -arch i386 -arch ppc +CFLAGS = -O -s \ + -Wall \ + $(ARCHS) \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I.. -I../motif + +all: $(EXEC) + +.c.o: ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.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 $@ + +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): $(OBJS) + $(CC) -o $(EXEC) $(ARCHS) $(OBJS) $(LIBS) + +install: all + cp $(EXEC) $(PPC_OUTPUT_DIR) + cp $(EXEC) $(X86_OUTPUT_DIR) + rm -f $(EXEC) $(OBJS) + +clean: + rm -f $(EXEC) $(OBJS) diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipse.c b/bundles/org.eclipse.equinox.launcher/library/eclipse.c new file mode 100644 index 000000000..798125765 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipse.c @@ -0,0 +1,1096 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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) + *******************************************************************************/ + +/* Eclipse Program Launcher + * + * This program performs the launching of the java VM used to + * start the Eclipse or RCP java application. + * As an implementation detail, this program serves two other + * purposes: display a splash window and write to a segment + * of shared memory. + * + * The java application receives the following arguments. + * -launcher <launcher absolute name. e.g. d:\eclipse\eclipse.exe> + * -name <application name. e.g. Eclipse> + * If the splash window is to be displayed, the java application + * will receive two extra arguments: + * -showsplash <splash time out in seconds e.g. 600> + * + * When the Java program starts, it should determine the location of + * the splash bitmap to be used. The Java program initiates the + * displaying of the splash window by executing the splash command + * as follows: + * + * Process splashProcess = Runtime.getRuntime().exec( array ); + * Where array stores String arguments in the following order: + * 0. <launcher absolute name. e.g. d:\eclipse\eclipse.exe> + * 1. -name + * 2. <application name. e.g. Eclipse> + * 3. -showsplash + * 4. <splash time out in seconds e.g. 600> + * 5. <absolute path of the splash screen e.g. d:\eclipse\splash.bmp> + * + * When the Java program initialization is complete, the splash window + * is brought down by destroying the splash process as follows: + * + * splashProcess.destroy(); + * + * Therefore, when the splash window is visible, there are actually three + * processes running: + * 1) the main launcher process + * 2) the Java VM process (Eclipse or RCP application) + * 3) the splash window process. + * + * The splash screen process can also show progress information. The + * communication between the Java VM process and the splash screen + * process is done through the standard input pipe. Messages sent to + * the splash screen process have this format: + * + * <key>=<value><LF> + * + * and the recognized messages are: + * + * value=50\n (changes the current progress value) + * maximum=100\n (changes the maximum progress value. Default is 100) + * message=starting...\n (changes the displayed message. Any char except LF is allowed) + * foreground=RRGGBB\n (changes the foreground color of the message, i.e. cyan=(0 << 16 | 255 << 8 | 255 << 0)) + * messageRect=10,10,100,20\n (changes the rectangle(x,y,width,height) where the message is displayed) + * progressRect=10,30,100,15\n (changes the rectangle(x,y,width,height) where the progress is displayed) + * + * Similarly, the Java application will receive two other arguments: + * -exitdata <shared memory id> + * + * The exitdata command can be used by the Java application + * to provide specific exit data to the main launcher process. The + * following causes another instance of the launcher to write to the + * segment of shared memory previously created by the + * main launcher. + * + * Process exitDataProcess = Runtime.getRuntime().exec( array ); + * exitDataProcess.waitFor(); + * Where array stores String arguments in the following order: + * 0. <launcher absolute name. e.g. d:\eclipse\eclipse.exe> + * 1. -name + * 2. <application name. e.g. Eclipse> + * 3. -exitdata + * 4. <shared memory id e.g. c60_7b4> + * 5. <exit data that either contain a series of characters> + * + * The exit data size must not exceed MAX_SHARED_LENGTH which is + * 16Kb. The exit data process will exit with an exit code + * different than 0 if that happens. 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. + * -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 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 to execute a jar called startup.jar in the folder + * where the launcher is located. + * The jar must be an executable jar. + * e.g. -startup myfolder/myJar.jar will cause the launcher to start + * the application: java -jar <launcher folder>/myfolder/myJar.jar + * <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> + * [-showsplash <splash time out>] + * [-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 "eclipseShm.h" +#include "eclipseConfig.h" + +#ifdef _WIN32 +#include <direct.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 Variables */ +_TCHAR* officialName = NULL; + +/* 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* jarFile = NULL; /* full pathname of the startup jar file to run */ +static _TCHAR* sharedID = NULL; /* ID for the shared memory */ + +/* Define the special exit codes returned from Eclipse. */ +#define RESTART_LAST_EC 23 +#define RESTART_NEW_EC 24 + +/* Define the maximum time (in seconds) for the splash window to remain visible. */ +static _TCHAR* splashTimeout = _T_ECLIPSE("600"); /* 10 minutes */ + +/* Define error messages. (non-NLS) */ +static _TCHAR* exitMsg = _T_ECLIPSE("JVM terminated. Exit code=%d\n%s"); +static _TCHAR* goVMMsg = _T_ECLIPSE("Start VM: %s\n"); +static _TCHAR* pathMsg = _T_ECLIPSE("%s\n'%s' in your current PATH"); +static _TCHAR* showMsg = _T_ECLIPSE("Could not load splash bitmap:\n%s"); +static _TCHAR* shareMsg = _T_ECLIPSE("No shared 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* homeMsg = +_T_ECLIPSE("The %s executable launcher was unable to locate its \n\ +companion startup.jar file (in the same directory as the executable)."); + +#define DEFAULT_STARTUP _T_ECLIPSE("startup.jar") + +/* 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 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 _TCHAR* osArg = _T_ECLIPSE(DEFAULT_OS); +static _TCHAR* osArchArg = _T_ECLIPSE(DEFAULT_OS_ARCH); +static _TCHAR* showSplashArg = NULL; /* showsplash data (main launcher window) */ +static _TCHAR* exitDataArg = NULL; +static _TCHAR * startupArg = DEFAULT_STARTUP; /* 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* wsArg = _T_ECLIPSE(DEFAULT_WS); /* the SWT supported GUI to be used */ +static _TCHAR* name = NULL; /* program name */ +static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */ + +/* Define a table for processing command line options. */ +typedef struct +{ + _TCHAR* name; /* the option recognized by the launcher */ + _TCHAR** value; /* the variable where the option value is saved */ + int* flag; /* the variable that is set if the option is defined */ + int remove; /* the number of argments to remove from the list */ +} Option; + +static Option options[] = { + { CONSOLE, NULL, &needConsole, 0 }, + { CONSOLELOG, NULL, &needConsole, 0 }, + { DEBUG, NULL, &debug, 0 }, + { NOSPLASH, NULL, &noSplash, 1 }, + { OS, &osArg, NULL, 2 }, + { OSARCH, &osArchArg, NULL, 2 }, + { SHOWSPLASH, &showSplashArg, NULL, 2 }, + { EXITDATA, &exitDataArg, NULL, 2 }, + { STARTUP, &startupArg, NULL, 2 }, + { VM, &vmName, NULL, 2 }, + { NAME, &name, NULL, 2 }, + { WS, &wsArg, NULL, 2 } }; +static int optionsSize = (sizeof(options) / sizeof(options[0])); + +static int configArgc = 0; +static _TCHAR** configArgv = NULL; + +/* Define the required VM arguments (all platforms). */ +static _TCHAR* jar = _T_ECLIPSE("-jar"); +static _TCHAR** reqVMarg[] = { &jar, &jarFile, NULL }; + +/* Local methods */ +static int createUserArgs(int configArgc, _TCHAR **configArgv, int *argc, _TCHAR ***argv); +static void parseArgs( int* argc, _TCHAR* argv[] ); +static _TCHAR** parseArgList( _TCHAR *data ); +static void freeArgList( _TCHAR** data ); +static _TCHAR** getVMCommand( int argc, _TCHAR* argv[] ); + _TCHAR* findCommand( _TCHAR* command ); +static _TCHAR* formatVmCommandMsg( _TCHAR* args[] ); + _TCHAR* getProgramDir(); +static _TCHAR* getDefaultOfficialName(); +static int isMainEclipse( int argc, _TCHAR **argv ); + +#ifdef _WIN32 +#ifdef UNICODE +extern int main(int, char**); +int mainW(int, wchar_t**); +int wmain( int argc, wchar_t** argv ) { + OSVERSIONINFOW info; + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + /* + * If the OS supports UNICODE functions, run the UNICODE version + * of the main function. Otherwise, convert the arguments to + * MBCS and run the ANSI version of the main function. + */ + if (!GetVersionExW (&info)) { + int i, result; + char **newArgv = malloc(argc * sizeof(char *)); + for (i=0; i<argc; i++) { + wchar_t *oldArg = argv[i]; + int byteCount = WideCharToMultiByte (CP_ACP, 0, oldArg, -1, NULL, 0, NULL, NULL); + char *newArg = malloc(byteCount+1); + newArg[byteCount] = 0; + WideCharToMultiByte (CP_ACP, 0, oldArg, -1, newArg, byteCount, NULL, NULL); + newArgv[i] = newArg; + } + result = main(argc, newArgv); + for (i=0; i<argc; i++) { + free(newArgv[i]); + } + free(newArgv); + return result; + } + return mainW(argc, argv); +} +#define main mainW +#endif /* UNICODE */ +#endif /* _WIN32 */ + +int main( int argc, _TCHAR* argv[] ) +{ + _TCHAR* splashBitmap; + _TCHAR* ch; + _TCHAR* data; + _TCHAR* shippedVM = NULL; + _TCHAR* vmSearchPath = NULL; + _TCHAR** vmCommand = NULL; + _TCHAR** vmCommandList = NULL; + _TCHAR** vmCommandArgs = NULL; + _TCHAR* vmCommandMsg = NULL; + _TCHAR* errorMsg; + int exitCode; + struct _stat stats; + + setlocale(LC_ALL, ""); + + /* + * 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 = findCommand( argv[0] ); + if (program == NULL) + { +#ifdef _WIN32 + program = malloc( MAX_PATH_LENGTH + 1 ); + GetModuleFileName( NULL, program, MAX_PATH_LENGTH ); +#else + program = malloc( strlen( argv[0] ) + 1 ); + strcpy( program, argv[0] ); +#endif + } + + /* Parse configuration file arguments */ + if (isMainEclipse(argc, argv) && readConfigFile(program, argv[0], &configArgc, &configArgv) == 0) + { + parseArgs (&configArgc, configArgv); + } + + /* Parse command line arguments (looking for the VM to use). */ + /* Override 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 > 1) + { + createUserArgs(configArgc, configArgv, &argc, &argv); + } + + /* Initialize official program name */ + officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName(); + + /* Initialize the window system. */ + initWindowSystem( &argc, argv, (showSplashArg != NULL) ); + + /* 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 ); + displayMessage( officialName, errorMsg ); + free( errorMsg ); + exit( 1 ); + } + + /* If the exit data option was given, set exit data */ + if (exitDataArg != NULL) + { + /* If an extra argument was given, use it as the exit data, otherwise clear exit data */ + data = argc > 1 ? argv[1] : NULL; + if (data != NULL && _tcslen( data ) > MAX_SHARED_LENGTH - 1) + { + exitCode = EINVAL; + } + else { + exitCode = setSharedData( exitDataArg, data ); + } + if (exitCode != 0 && debug) displayMessage( officialName, shareMsg ); + exit( exitCode ); + } + + /* If the showsplash option was given */ + if (showSplashArg != NULL && argc > 1) + { + splashBitmap = argv[1]; + exitCode = showSplash( showSplashArg, splashBitmap ); + if (exitCode && debug) + { + errorMsg = malloc( (_tcslen(showMsg) + _tcslen(splashBitmap) + 10) * sizeof(_TCHAR) ); + _stprintf( errorMsg, showMsg, splashBitmap ); + displayMessage( officialName, errorMsg ); + free( errorMsg ); + } + exit( exitCode ); + } + + /* If the user did not specify a VM to be used */ + if (vmName == NULL) + { + /* Determine which type of VM should be used. */ + vmName = ((debug || needConsole) ? consoleVM : defaultVM); + + /* Try to find the VM shipped with eclipse. */ + shippedVM = malloc( (_tcslen( programDir ) + _tcslen( shippedVMDir ) + _tcslen( vmName ) + 10) * sizeof(_TCHAR) ); + _stprintf( shippedVM, _T_ECLIPSE("%s%s%s"), programDir, shippedVMDir, vmName ); + javaVM = findCommand( shippedVM ); + + /* Format a message to indicate the default VM search path. */ + vmSearchPath = malloc( (_tcslen( pathMsg ) + _tcslen( shippedVM ) + _tcslen( vmName ) + 10) * sizeof(_TCHAR) ); + _stprintf( vmSearchPath, pathMsg, shippedVM, vmName ); + free( shippedVM ); + shippedVM = NULL; + } + + /* If a Java VM has not been found yet */ + if (javaVM == NULL) + { + /* Either verify the VM specified by the user or + attempt to find the VM in the user's PATH. */ + javaVM = findCommand( vmName ); + + /* If the VM was not found, display a message and exit. */ + if (javaVM == NULL) + { + if (vmSearchPath != NULL) vmName = vmSearchPath; /* used default VM searching */ + errorMsg = malloc( (_tcslen(noVMMsg) + _tcslen(officialName) + _tcslen(vmName) + 10) * sizeof(_TCHAR) ); + _stprintf( errorMsg, noVMMsg, officialName, vmName ); + displayMessage( officialName, errorMsg ); + free( errorMsg ); + exit(1); + } + } + + if (createSharedData( &sharedID, MAX_SHARED_LENGTH )) { + if (debug) { + if (debug) displayMessage( officialName, shareMsg ); + } + } + + /* Construct the absolute name of the startup jar */ + jarFile = malloc( (_tcslen( programDir ) + _tcslen( startupArg ) + 1) * sizeof( _TCHAR ) ); + jarFile = _tcscpy( jarFile, programDir ); + jarFile = _tcscat( jarFile, startupArg ); + + /* If the file does not exist, treat the argument as an absolute path */ + if (_tstat( jarFile, &stats ) != 0) + { + free( jarFile ); + jarFile = malloc( (_tcslen( startupArg ) + 1) * sizeof( _TCHAR ) ); + jarFile = _tcscpy( jarFile, startupArg ); + } + + /* Get the command to start the Java VM. */ + vmCommandArgs = getVMCommand( argc, argv ); + + /* While the Java VM should be restarted */ + vmCommand = vmCommandArgs; + while (vmCommand != NULL) + { + vmCommandMsg = formatVmCommandMsg( vmCommand ); + if (debug) _tprintf( goVMMsg, vmCommandMsg ); + exitCode = startJavaVM( vmCommand ); + switch( exitCode ) { + case 0: + vmCommand = NULL; + break; + case RESTART_LAST_EC: + break; + case RESTART_NEW_EC: + if (getSharedData( sharedID, &data ) == 0) { + if (vmCommandList != NULL) freeArgList( vmCommandList ); + vmCommand = vmCommandList = parseArgList( data ); + } else { + vmCommand = NULL; + if (debug) displayMessage( officialName, shareMsg ); + } + break; + default: { + _TCHAR *title = _tcsdup(officialName); + vmCommand = NULL; + errorMsg = NULL; + if (getSharedData( sharedID, &errorMsg ) == 0) { + if (_tcslen( errorMsg ) == 0) { + free( errorMsg ); + errorMsg = NULL; + } else { + _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) displayMessage( title, shareMsg ); + } + if (errorMsg == NULL) { + errorMsg = malloc( (_tcslen(exitMsg) + _tcslen(vmCommandMsg) + 10) * sizeof(_TCHAR) ); + _stprintf( errorMsg, exitMsg, exitCode, vmCommandMsg ); + } + displayMessage( title, errorMsg ); + free( title ); + free( errorMsg ); + break; + } + } + free( vmCommandMsg ); + } + + /* Cleanup time. */ + free( jarFile ); + free( programDir ); + free( program ); + if ( vmSearchPath != NULL ) free( vmSearchPath ); + if ( vmCommandList != NULL ) freeArgList( vmCommandList ); + if ( configArgv != NULL ) freeConfig( configArgv ); + if (configArgc > 1) free( argv ); + free( officialName ); + if ( sharedID != NULL ) { + if (destroySharedData( sharedID ) != 0) { + if (debug) displayMessage( officialName, shareMsg ); + } + free( sharedID ); + } + + return 0; +} + +/* Return 1 if the current Eclipse is the process that starts the java IDE + * Return 0 if it is an Eclipse used to display a splash screen or to write + * data to a shared memory segment. + * The main Eclipse is the only one that reads the eclipse.ini file. + */ +static int isMainEclipse( int argc, _TCHAR **argv ) +{ + /* It is the main eclipse if the argument 3 is neither SHOWSPLASH nor EXITDATA */ + if (argc < 4) return 1; + return (_tcsicmp( argv[3], SHOWSPLASH ) != 0 && _tcsicmp( argv[3], EXITDATA ) != 0); +} + +/* + * Parse arguments of the command. + */ +static void parseArgs( int* pArgc, _TCHAR* argv[] ) +{ + Option* option; + int remArgs; + int index; + int i; + + /* Ensure the list of user argument is NULL terminated. */ + argv[ *pArgc ] = NULL; + + /* 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 ]; + } + + /* If the option is recognized by the launcher */ + if (option != NULL) + { + /* If the option requires a value and there is one, extract the value. */ + if (option->value != NULL && (index+1) < *pArgc) + *option->value = argv[ index+1 ]; + + /* If the option requires a flag to be set, set it. */ + if (option->flag != NULL) + *option->flag = 1; + remArgs = option->remove; + } + + /* All of the remaining arguments are user VM args. */ + else if (_tcsicmp( argv[ index ], VMARGS ) == 0) + { + userVMarg = &argv[ index+1 ]; + argv[ index ] = NULL; + *pArgc = index; + } + + /* 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; + } + } +} + +/* + * 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) * sizeof(_TCHAR *)); + + memcpy(newArray, configArgv, configArgc * sizeof(_TCHAR *)); + + /* Skip the argument zero (program path and name) */ + memcpy(newArray + configArgc, *argv + 1, (*argc - 1) * sizeof(_TCHAR *)); + + /* Null terminate the new list of arguments and return it. */ + *argv = newArray; + *argc += configArgc - 1; + (*argv)[*argc] = NULL; + + return 0; +} + +/* + * Free the memory allocated by parseArgList(). + */ +static void freeArgList( _TCHAR** data ) { + if (data == NULL) return; + free( data [0] ); + free( data ); +} + +/* + * Parse the data into a list of arguments separarted by \n. + * + * The list of strings returned by this function must be freed with + * freeArgList(). + */ +static _TCHAR** parseArgList( _TCHAR* data ) { + int totalArgs = 0, dst = 0, 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; +} + +/* + * 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 ) +{ + _TCHAR* cmdPath; + int length; + _TCHAR* ch; + _TCHAR* dir; + _TCHAR* path; + struct _stat stats; + + /* If the command was an abolute pathname, use it as is. */ + if (command[0] == dirSeparator || + (_tcslen( command ) > 2 && command[1] == _T_ECLIPSE(':'))) + { + 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 (_tcschr( command, dirSeparator ) != NULL) + { + /* It must be relative to the current directory. */ + length = MAX_PATH_LENGTH + EXTRA + _tcslen( command ); + cmdPath = malloc( length * sizeof (_TCHAR)); + _tgetcwd( cmdPath, length ); + if (cmdPath[ _tcslen( cmdPath ) - 1 ] != dirSeparator) + { + length = _tcslen( cmdPath ); + 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") ); + 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) + { + int i = 0, j = 0, 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 (cmdPath[0] == _T_ECLIPSE('.') && + (_tcslen(cmdPath) == 1 || (_tcslen(cmdPath) == 2 && cmdPath[1] == dirSeparator))) + { + _tgetcwd( cmdPath, MAX_PATH_LENGTH ); + } + if (cmdPath[ _tcslen( cmdPath ) - 1 ] != dirSeparator) + { + length = _tcslen( cmdPath ); + 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 the absolute command pathname. */ + return cmdPath; +} + +/* + * 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. + */ +static _TCHAR** getVMCommand( int argc, _TCHAR* argv[] ) +{ + _TCHAR** defVMarg; + int nDefVMarg = 0; + int nReqVMarg = 0; + int nUserVMarg = 0; + int totalArgs; + _TCHAR** execArg; + int src; + int dst; + + /* Calculate the number of user VM arguments. */ + if (userVMarg != NULL) + { + while (userVMarg[ nUserVMarg ] != NULL) + nUserVMarg++; + } + + /* Calculate the number of default VM arguments. */ + defVMarg = getArgVM( javaVM ); + while (defVMarg[ nDefVMarg ] != NULL) + nDefVMarg++; + + /* Calculate the number of required VM arguments. */ + while (reqVMarg[ nReqVMarg ] != NULL) + nReqVMarg++; + + /* Allocate the arg list for the exec call. + * (VM + userVMargs + defaultVMargs + requiredVMargs + OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> + + * + SHOWSPLASH <cmd> + EXITDATA <cmd> + argv[] + VM + <vm> + VMARGS + userVMargs + defaultVMargs + requiredVMargs + * + NULL) + */ + totalArgs = 1 + nUserVMarg + nDefVMarg + nReqVMarg + 2 + 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nUserVMarg + nDefVMarg + nReqVMarg + 1; + execArg = malloc( totalArgs * sizeof( _TCHAR* ) ); + dst = 0; + execArg[ dst++ ] = javaVM; + + /* If the user specified "-vmargs", add them instead of the default VM args. */ + if (userVMarg != NULL) + { + for (src = 0; src < nUserVMarg; src++) + execArg[ dst++ ] = userVMarg[ src ]; + } + else + { + for (src = 0; src < nDefVMarg; src++) + execArg[ dst++ ] = defVMarg[ src ]; + } + + /* For each required VM arg */ + for (src = 0; src < nReqVMarg; src++) + execArg[ dst++ ] = *(reqVMarg[ src ]); + + /* Append the required options. */ + execArg[ dst++ ] = OS; + execArg[ dst++ ] = osArg; + execArg[ dst++ ] = WS; + execArg[ dst++ ] = wsArg; + if (_tcslen(osArchArg) > 0) { + execArg[ dst++ ] = OSARCH; + execArg[ dst++ ] = osArchArg; + } + + /* Append the launcher command */ + execArg[ dst++ ] = LAUNCHER; + execArg[ dst++ ] = program; + + /* Append the name command */ + execArg[ dst++ ] = NAME; + execArg[ dst++ ] = officialName; + + /* Append the show splash window command, if defined. */ + if (!noSplash) + { + execArg[ dst++ ] = SHOWSPLASH; + execArg[ dst++ ] = splashTimeout; + } + + /* Append the exit data command. */ + if (sharedID) { + execArg[ dst++ ] = EXITDATA; + execArg[ dst++ ] = sharedID; + } + + /* Append the remaining user defined arguments. */ + for (src = 1; src < argc; src++) + { + execArg[ dst++ ] = argv[ src ]; + } + + /* Append VM and VMARGS to be able to relaunch using exit data. */ + execArg[ dst++ ] = VM; + execArg[ dst++ ] = javaVM; + execArg[ dst++ ] = VMARGS; + /* If the user specified "-vmargs", add them instead of the default VM args. */ + if (userVMarg != NULL) + { + for (src = 0; src < nUserVMarg; src++) + execArg[ dst++ ] = userVMarg[ src ]; + } + else + { + for (src = 0; src < nDefVMarg; src++) + execArg[ dst++ ] = defVMarg[ src ]; + } + /* For each required VM arg */ + for (src = 0; src < nReqVMarg; src++) + execArg[ dst++ ] = *(reqVMarg[ src ]); + + execArg[ dst++ ] = NULL; + + return execArg; + } + + /* 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. + */ +static _TCHAR* formatVmCommandMsg( _TCHAR* args[] ) +{ + int index; + int length; + _TCHAR* ch; + _TCHAR* message; + + /* Determine the length of the message buffer. */ + length = 0; + for (index = 0; args[index] != NULL; index++) + { + length += _tcslen(args[index]) + 1; + } + 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; + for (index = 0; args[index] != NULL; index++) + { + if (args[index][0] == _T_ECLIPSE('-') && *(ch-1) == _T_ECLIPSE(' ')) + *(ch-1) = _T_ECLIPSE('\n'); + _tcscpy( ch, args[index] ); + ch += _tcslen( args[index] ); + *ch++ = _T_ECLIPSE(' '); + } + *ch = _T_ECLIPSE('\0'); + + return message; +} + +/* + * 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 = _tcsrchr( program, dirSeparator ); + 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; + + programDir = malloc( (_tcslen( program ) + 1) * sizeof(_TCHAR) ); + _tcscpy( programDir, program ); + ch = _tcsrchr( programDir, dirSeparator ); + if (ch != NULL) + { + *(ch+1) = _T_ECLIPSE('\0'); + return programDir; + } + + free( programDir ); + return NULL; +} + diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseConfig.c b/bundles/org.eclipse.equinox.launcher/library/eclipseConfig.c new file mode 100644 index 000000000..a7b3a3dd2 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseConfig.c @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 "eclipseOS.h" +#include "eclipseConfig.h" + +#ifdef _WIN32 + +#include <stdio.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 readConfigFile(_TCHAR* program, _TCHAR* arg0, int *argc, _TCHAR ***argv) +{ + _TCHAR* config_file = NULL; + _TCHAR buffer[1024]; + _TCHAR argument[1024]; + FILE *file = NULL; + int maxArgs = 128; + int index; + + if (program == NULL || argc == NULL || argv == NULL) return -1; + + /* Get a copy */ + config_file = _tcsdup(program); + +#ifdef _WIN32 + { + /* Search for the extension .exe and replace it with .ini */ + _TCHAR *extension = _tcsrchr(config_file, _T_ECLIPSE('.')); + if (extension == NULL || _tcslen(extension) < 4) + { + free(config_file); + return -2; + } + _tcscpy(extension, _T_ECLIPSE(".ini")); + } +#else + /* Append the extension */ + config_file = (char*)realloc(config_file, strlen(config_file) + 5); + strcat(config_file, ".ini"); +#endif + + /* 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. + */ + file = _tfopen(config_file, _T_ECLIPSE("rt")); + if (file == NULL) return -3; + + *argv = (_TCHAR **)malloc(1 + maxArgs * sizeof(_TCHAR*)); + + /* Make it look like a regular list of arguments that starts with the executable location and name */ + (*argv)[0] = _tcsdup(arg0); + index = 1; + + /* Parse every line */ + while (_fgetts(buffer, 1024, file) != NULL) + { + /* 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) + { + (*argv)[index] = _tcsdup(argument); + 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(config_file); + 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/bundles/org.eclipse.equinox.launcher/library/eclipseConfig.h b/bundles/org.eclipse.equinox.launcher/library/eclipseConfig.h new file mode 100644 index 000000000..10189ba81 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseConfig.h @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 + +#ifdef UNICODE +#define readConfigFile readConfigFileW +#define freeConfig freeConfigW +#endif + +/* 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" + * + * The argument arg0 corresponds to the first argument received by + * the main function. It will be duplicated and set in the first + * position of the resulting list of arguments. + * + * The argument args 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 nArgs contains the number of string allocated. + * + * Returns 0 if success. + */ +extern int readConfigFile(_TCHAR* program, _TCHAR* arg0, int *nArgs, _TCHAR ***args); + +/** + * Free the memory allocated by readConfigFile(). + */ +extern void freeConfig(_TCHAR **args); + +#endif /* ECLIPSE_CONFIG_H */ diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseMozilla.c b/bundles/org.eclipse.equinox.launcher/library/eclipseMozilla.c new file mode 100644 index 000000000..4d270eb24 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseMozilla.c @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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> + + +/* Filter function used by fixEnvForMozilla() for finding directories + * with a desired prefix. + */ +int filter(const struct dirent *dir) +{ + char* prefixes[] = { + "xulrunner-", + "mozilla-", + "firefox-", + NULL + }; + int XULRUNNER_INDEX = 0; + char* root = "/usr/lib/"; + char* testlib = "/components/libwidget_gtk2.so"; + struct stat buf; + int index = 0; + char* dirname = (char *)dir->d_name; + + char* prefix = prefixes [index]; + while (prefix != NULL) + { + if (strncmp(dirname, prefix, strlen(prefix)) == 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 */ + char* testpath = malloc (strlen(root) + strlen(dirname) + 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 */ +} + +/* 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__) + 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) + { + grePath = strdup(path); + break; + } + } + fclose(file); + } + } + + /* Try some common installation locations. */ + if (grePath == NULL) + { + /* some other typical installation locations */ + char* dirs[] = { + "/usr/lib/mozilla/", + "/usr/local/mozilla/", + "/opt/mozilla/", + "/usr/lib/firefox/", + "/usr/local/firefox/", + "/opt/firefox/", + "/usr/lib/MozillaFirebird/", + "/usr/local/MozillaFirebird/", + "/opt/MozillaFirebird/", + NULL + }; + char* testlib = "components/libwidget_gtk2.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++]; + } + + if (grePath == NULL) + { + /* now try xulrunner-*, mozilla-*, firefox-* directories in /usr/lib/ */ + char* dir = "/usr/lib/"; + struct dirent **namelist; + int i; + + int count = scandir(dir, &namelist, filter, alphasort); + if (count > 0) + { + /* count-1 is used below in an attempt to get the matched directory + * with the latest version number. + */ + char* name = namelist [count - 1]->d_name; + grePath = malloc (strlen(dir) + strlen(name) + 1); + strcpy(grePath, dir); + strcat(grePath, name); + for (i = 0; i < count; i++) { + free(namelist [i]); + } + free(namelist); + } + } + } + + if (grePath != NULL) + { + 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/bundles/org.eclipse.equinox.launcher/library/eclipseMozilla.h b/bundles/org.eclipse.equinox.launcher/library/eclipseMozilla.h new file mode 100644 index 000000000..42b4f00a0 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseMozilla.h @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h b/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h new file mode 100644 index 000000000..3f6dd4860 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 "eclipseUnicode.h" + +#ifdef UNICODE +#define shippedVMDir shippedVMDirW +#define defaultVM defaultVMW +#define consoleVM consoleVMW +#define pathSeparator pathSeparatorW +#define dirSeparator dirSeparatorW +#define displayMessage displayMessageW +#define initWindowSystem initWindowSystemW +#define showSplash showSplashW +#define getArgVM getArgVMW +#define startJavaVM startJavaVMW +#define findCommand findCommandW +#define getProgramDir getProgramDirW +#define officialName officialNameW +#endif + +/* Operating System Dependent Information */ + +/*** See eclipse.c for information on the launcher runtime architecture ***/ + +/* Global Variables */ + +extern _TCHAR dirSeparator; /* '/' or '\\' */ +extern _TCHAR pathSeparator; /* separator used in PATH variable */ +extern _TCHAR* consoleVM; /* name of VM to use for debugging */ +extern _TCHAR* defaultVM; /* name of VM to use normally */ +extern _TCHAR* shippedVMDir; /* VM bin directory with separator */ +extern _TCHAR* officialName; /* Program official name */ + +/* 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 void 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( _TCHAR* splashId, _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 ); + + +/* 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 int startJavaVM( _TCHAR* args[] ); + +#endif /* ECLIPSE_OS_H */ + diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseShm.c b/bundles/org.eclipse.equinox.launcher/library/eclipseShm.c new file mode 100644 index 000000000..9e21aee35 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseShm.c @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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" + +#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)); + _stprintf(*id, _T_ECLIPSE("%lx_%lx"), GetCurrentProcessId(), (DWORD) mapHandle); + } + return 0; +} + +static int getShmID(_TCHAR* id, LPDWORD processID, LPHANDLE handle) { + if (id != NULL && _tcslen(id) > 0) { + DWORD i1, i2; + 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 (data != NULL) { + int 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(_TCHAR* id, _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) { + int 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); + } + return 0; +} + +static int getShmID(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; + 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(char* id, 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/bundles/org.eclipse.equinox.launcher/library/eclipseShm.h b/bundles/org.eclipse.equinox.launcher/library/eclipseShm.h new file mode 100644 index 000000000..861615d4f --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseShm.h @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 + +#ifdef UNICODE +#define createSharedData createSharedDataW +#define destroySharedData destroySharedDataW +#define getSharedData getSharedDataW +#define setSharedData setSharedDataW +#endif + +/* 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(_TCHAR* id, _TCHAR* data); + +#endif /* ECLIPSE_SHM_H */ + + diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseUnicode.h b/bundles/org.eclipse.equinox.launcher/library/eclipseUnicode.h new file mode 100644 index 000000000..84c20f9b3 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseUnicode.h @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 */ +# else /* UNICODE */ +# ifndef _TCHAR +# define _TCHAR char +# endif /* _TCHAR */ +# ifndef _tgetcwd +# define _tgetcwd getcwd +# endif /* _tgetcwd */ +# ifndef _tstat +# define _tstat _stat +# endif /* _tstat */ +# 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 _stscanf sscanf +#define _tcscat strcat +#define _tcschr strchr +#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 +#ifndef LINUX +#define _totupper toupper +#endif /* LINUX */ +#define _tprintf printf +#define _tstat stat +#define _tcsncmp strncmp +#define _tcsstr strstr + +#endif /* _WIN32 */ + +#endif /* ECLIPSE_UNICODE_H */ diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseUtil.c b/bundles/org.eclipse.equinox.launcher/library/eclipseUtil.c new file mode 100644 index 000000000..052bd9b8e --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseUtil.c @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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) + *******************************************************************************/ + +/* Eclipse Launcher Utility Methods */ + +#include "eclipseOS.h" +#include "eclipseUtil.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#ifndef _WIN32 +#include <strings.h> +#endif + +#define MAX_LINE_LENGTH 256 + +/* Is the given VM J9 */ +int isJ9VM( _TCHAR* vm ) +{ + _TCHAR *ch = _tcsrchr( vm, dirSeparator ); + if (ch == NULL) + ch = vm; + else + ch++; + return (_tcsicmp( ch, _T_ECLIPSE("j9") ) == 0); +} + + +#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; +} + +/* 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) ); +} +#endif /* AIX */ diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseUtil.h b/bundles/org.eclipse.equinox.launcher/library/eclipseUtil.h new file mode 100644 index 000000000..484b9d5aa --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/eclipseUtil.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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_UTIL_H +#define ECLIPSE_UTIL_H + +#ifdef UNICODE +#define isJ9VM isJ9VMW +#endif + +/* Eclipse Launcher Utility Methods */ + +/* Is the given Java VM J9 */ +extern int isJ9VM( _TCHAR* vm ); + + +#ifdef AIX +/* Get the version of the VM */ +extern char* getVMVersion( char* vm ); + +/* Compare JVM Versions */ +extern int versionCmp( char* ver1, char* ver2 ); +#endif + +#endif /* ECLIPSE_UTIL_H */ diff --git a/bundles/org.eclipse.equinox.launcher/library/gtk/.cvsignore b/bundles/org.eclipse.equinox.launcher/library/gtk/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/gtk/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.launcher/library/gtk/build.sh b/bundles/org.eclipse.equinox.launcher/library/gtk/build.sh new file mode 100644 index 000000000..aca00675e --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/gtk/build.sh @@ -0,0 +1,140 @@ +#!/bin/sh +#******************************************************************************* +# Copyright (c) 2000, 2005 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="" +defaultOSArch="" +defaultWS="gtk" +makefile="" +if [ "$OS" = "" ]; then + OS=`uname -s` +fi +if [ "$MODEL" = "" ]; then + MODEL=`uname -m` +fi +if [ "${CC}" = "" ]; then + CC=gcc + export CC +fi + +case $OS in + "Linux") + makefile="make_linux.mak" + defaultOS="linux" + case $MODEL in + "x86_64") + defaultOSArch="x86_64" + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + i?86) + defaultOSArch="x86" + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + "ppc") + defaultOSArch="ppc" + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + "ppc64") + defaultOSArch="ppc64" + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + "ia64") + defaultOSArch="ia64" + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + *) + echo "*** Unknown MODEL <${MODEL}>" + ;; + esac + ;; + "SunOS") + makefile="make_solaris.mak" + defaultOS="solaris" + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + PATH=/usr/ccs/bin:/usr/local/bin:$PATH + export PATH + if [ "$PROC" = "" ]; then + PROC=`uname -p` + fi + case ${PROC} in + "i386") + defaultOSArch="x86" + ;; + "sparc") + defaultOSArch="sparc" + ;; + *) + echo "*** Unknown processor type <${PROC}>" + ;; + 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 + 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" + +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/bundles/org.eclipse.equinox.launcher/library/gtk/build.xml b/bundles/org.eclipse.equinox.launcher/library/gtk/build.xml new file mode 100644 index 000000000..65a05c0ee --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/gtk/build.xml @@ -0,0 +1,30 @@ +<?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> + <eclipse.refreshLocal resource="platform-launcher" depth="infinite" /> +</target> + +<target name="build_eclipse_ppc"> + <exec dir="." executable="sh"> + <env key="MODEL" value="ppc"/> + <arg line="${basedir}/build.sh"/> + <arg line="install"/> + </exec> + <eclipse.refreshLocal resource="platform-launcher" depth="infinite" /> +</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/bundles/org.eclipse.equinox.launcher/library/gtk/eclipseGtk.c b/bundles/org.eclipse.equinox.launcher/library/gtk/eclipseGtk.c new file mode 100644 index 000000000..53f9b03b9 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/gtk/eclipseGtk.c @@ -0,0 +1,337 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 "eclipseOS.h" +#include "eclipseUtil.h" + +#include <signal.h> +#include <unistd.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 <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> + +#include <gtk/gtk.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +/* Global Variables */ +char dirSeparator = '/'; +char pathSeparator = ':'; +char* consoleVM = "java"; +char* defaultVM = "java"; +char* shippedVMDir = "jre/bin/"; + +/* Define the special arguments for the various Java VMs. */ +static char* argVM_JAVA[] = { NULL }; +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 . */ +static int saveArgc = 0; +static char** saveArgv = 0; +static gboolean gtkInitialized = FALSE; + +static GtkWidget *label = NULL, *progress = NULL; +static GdkColor foreground = {0, 0, 0, 0}; +static GdkRectangle progressRect = {0, 0, 0, 0}, messageRect = {0, 0, 0, 0}; +static int value = 0, maximum = 100; + +/* Local functions */ +static gboolean splashTimeout(gpointer data); + +/* Display a Message */ +void displayMessage(char* title, char* message) +{ + GtkWidget* dialog; + + /* If GTK has not been initialized yet, do it now. */ + if (!gtkInitialized) + { + initWindowSystem( &saveArgc, saveArgv, 1 ); + } + + dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "%s", message); + gtk_window_set_title(GTK_WINDOW (dialog), title); + gtk_dialog_run(GTK_DIALOG (dialog)); + gtk_widget_destroy(dialog); +} + + +/* Initialize the Window System */ +void initWindowSystem(int* pArgc, char* argv[], int showSplash) +{ + + /* Save the arguments in case displayMessage() is called in the main launcher. */ + if (saveArgv == 0) + { + saveArgc = *pArgc; + saveArgv = argv; + } + + + /* If the splash screen is going to be displayed by this process */ + if (showSplash) + { + /* Initialize GTK. */ + gtk_set_locale(); + gtk_init(pArgc, &argv); + gdk_set_program_class(officialName); + gtkInitialized = TRUE; + } +} + +static void readRect(char *str, GdkRectangle *rect) { + int x, y, width, height; + char *temp = str, *comma; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + x = atoi(temp); + temp = comma + 1; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + y = atoi(temp); + temp = comma + 1; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + width = atoi(temp); + temp = comma + 1; + height = atoi(temp); + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; +} + +static void readColor(char *str, GdkColor *color) { + int value = atoi(str); + color->red = ((value & 0xFF0000) >> 16) * 0xFF; + color->green = ((value & 0xFF00) >> 8) * 0xFF; + color->blue = ((value & 0xFF) >> 0) * 0xFF; +} + +static void readInput() { + int available; + FILE *fd = stdin; + char *buffer = NULL, *equals = NULL, *end, *line; + ioctl(fileno(fd), FIONREAD, &available); + if (available <= 0) return; + buffer = malloc(available + 1); + available = fread(buffer, 1, available, fd); + buffer[available] = 0; + line = buffer; + while (line != NULL) { + end = strchr(line, '\n'); + equals = strchr(line, '='); + if (end != NULL) end[0] = 0; + if (equals != NULL) { + char *str = (char *)equals + 1; + equals[0] = 0; + if (strcmp(line, "maximum") == 0) { + maximum = atoi(str); + if (progress) { + double fraction = maximum == 0 ? 1 : (double)(value / maximum); + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), fraction); + } + } else if (strcmp(line, "value") == 0) { + value = atoi(str); + if (progress) { + double fraction = maximum == 0 ? 1 : (double)value / maximum; + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), fraction); + } + } else if (strcmp(line, "progressRect") == 0) { + readRect(str, &progressRect); + if (progress) { + gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(progress)), progress, progressRect.x, progressRect.y); + gtk_widget_set_size_request(GTK_WIDGET(progress), progressRect.width, progressRect.height); + } + } else if (strcmp(line, "messageRect") == 0) { + readRect(str, &messageRect); + if (label) { + gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(label)), label, messageRect.x, messageRect.y); + gtk_widget_set_size_request(GTK_WIDGET(label), messageRect.width, messageRect.height); + } + } else if (strcmp(line, "foreground") == 0) { + readColor(str, &foreground); + if (label) { + gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &foreground); + } + } else if (strcmp(line, "message") == 0) { + if (label) { + gtk_label_set_text(GTK_LABEL(label), str); + } + } + + } + if (end != NULL) line = end + 1; + else line = NULL; + } + free(buffer); +} + +static gboolean timerProc(gpointer data) { + readInput(); + return TRUE; +} + +/* Create and Display the Splash Window */ +int showSplash( char* timeoutString, char* featureImage ) +{ + GdkPixbuf* imageData = NULL; + GtkWidget* image, *fixed; + GtkWindow* main; + int timeout = 0; + + /* Determine the splash timeout value (in seconds). */ + if (timeoutString != NULL && strlen( timeoutString ) > 0) + { + sscanf( timeoutString, "%d", &timeout ); + } + + /* Load the feature specific splash image data if defined. */ + if (featureImage != NULL) + { + imageData = gdk_pixbuf_new_from_file(featureImage, NULL); + } + + /* If the splash image data could not be loaded, return an error. */ + if (imageData == NULL) + return ENOENT; + + /* Create the image from its data. */ + fixed = gtk_fixed_new(); + image = gtk_image_new_from_pixbuf(imageData); + label = gtk_label_new(""); + progress = gtk_progress_bar_new(); + + /* Create a top level window for the image. */ + main = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); + gtk_window_set_title(main, officialName); + + gtk_container_add(GTK_CONTAINER(main), GTK_WIDGET(fixed)); + gtk_container_add(GTK_CONTAINER(fixed), GTK_WIDGET(image)); + gtk_container_add(GTK_CONTAINER(fixed), GTK_WIDGET(label)); + gtk_container_add(GTK_CONTAINER(fixed), GTK_WIDGET(progress)); + + gtk_misc_set_alignment (GTK_MISC(label), 0.0f, 0.0f); + gtk_label_set_justify (GTK_LABEL(label), GTK_JUSTIFY_LEFT); + gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &foreground); + + readInput(); + gtk_timeout_add(50, timerProc, NULL); + + gtk_fixed_move(GTK_FIXED(fixed), label, messageRect.x, messageRect.y); + gtk_widget_set_size_request(GTK_WIDGET(label), messageRect.width, messageRect.height); + gtk_fixed_move(GTK_FIXED(fixed), progress, progressRect.x, progressRect.y); + gtk_widget_set_size_request(GTK_WIDGET(progress), progressRect.width, progressRect.height); + gtk_widget_set_size_request(GTK_WIDGET(fixed), gdk_pixbuf_get_width(imageData), gdk_pixbuf_get_height(imageData)); + + /* Remove window decorations and centre the window on the display. */ + gtk_window_set_decorated(main, FALSE); + gtk_window_set_position(main, GTK_WIN_POS_CENTER); + gtk_window_set_resizable(main, FALSE); + + /* Set the background pixmap to NULL to avoid a gray flash when the image appears. */ + gtk_widget_realize(GTK_WIDGET(main)); + gdk_window_set_back_pixmap(GTK_WIDGET(main)->window, NULL, FALSE); + + /* If a timeout for the splash window was given */ + if (timeout != 0) + { + /* Add a timeout (in milliseconds) to bring down the splash screen. */ + gtk_timeout_add((timeout * 1000), splashTimeout, (gpointer) main); + } + + /* Show the window and wait for the timeout (or until the process is terminated). */ + gtk_widget_show_all(GTK_WIDGET (main)); + gtk_main (); + + label = progress = NULL; + + return 0; +} + + +/* Get the window system specific VM arguments */ +char** getArgVM( char* vm ) +{ + char** result; + char* version; + + if (isJ9VM( vm )) + return argVM_J9; + + /* Use the default arguments for a standard Java VM */ + result = argVM_JAVA; + return result; +} + + +/* 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 jvmExitCode = 1; + pid_t jvmProcess; + 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. */ + _exit(errno); + } + + /* If the JVM is still running, wait for it to terminate. */ + if (jvmProcess != 0) + { + wait(&exitCode); + if (WIFEXITED(exitCode)) + jvmExitCode = WEXITSTATUS(exitCode); + } + + return jvmExitCode; +} + +/* Splash Timeout - Hide the main window and exit the main loop. */ +static gboolean splashTimeout(gpointer data) +{ + GtkWidget* main = GTK_WIDGET(data); + gtk_widget_hide(main); + gtk_main_quit(); + return FALSE; +} diff --git a/bundles/org.eclipse.equinox.launcher/library/gtk/make_linux.mak b/bundles/org.eclipse.equinox.launcher/library/gtk/make_linux.mak new file mode 100644 index 000000000..bb074aa98 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/gtk/make_linux.mak @@ -0,0 +1,66 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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.) +#******************************************************************************* + +# 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 + +# Define the object modules to be compiled and flags. +CC=gcc +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseMozilla.o eclipseGtk.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 +CFLAGS = -O -s \ + -fpic \ + -DLINUX \ + -DMOZILLA_FIX \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I. \ + -I.. \ + `pkg-config --cflags gtk+-2.0` + +all: $(EXEC) + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o + +eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseShm.c -o eclipseShm.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 + +$(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/bundles/org.eclipse.equinox.launcher/library/gtk/make_solaris.mak b/bundles/org.eclipse.equinox.launcher/library/gtk/make_solaris.mak new file mode 100644 index 000000000..7389d6bff --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/gtk/make_solaris.mak @@ -0,0 +1,61 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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.) +#******************************************************************************* + +# 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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseGtk.o +EXEC = $(PROGRAM_OUTPUT) +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 +CFLAGS = -O -s \ + -DSOLARIS \ + -K PIC \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I. \ + -I.. \ + `pkg-config --cflags gtk+-2.0` + +all: $(EXEC) + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o + +eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseShm.c -o eclipseShm.o + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseConfig.c -o eclipseConfig.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/bundles/org.eclipse.equinox.launcher/library/motif/.cvsignore b/bundles/org.eclipse.equinox.launcher/library/motif/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.launcher/library/motif/NgCommon.c b/bundles/org.eclipse.equinox.launcher/library/motif/NgCommon.c new file mode 100644 index 000000000..89ecdf47b --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgCommon.c @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/motif/NgCommon.h b/bundles/org.eclipse.equinox.launcher/library/motif/NgCommon.h new file mode 100644 index 000000000..a4c2589f4 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgCommon.h @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/motif/NgImage.c b/bundles/org.eclipse.equinox.launcher/library/motif/NgImage.c new file mode 100644 index 000000000..04ffbe701 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgImage.c @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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" + +/** + * Return the nbr of entries in the default color palette + */ +int getNbrColorsXPalette(Display *xDisplay) +{ + Visual *visual = XDefaultVisual (xDisplay, 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 = XDefaultColormap (xDisplay, XDefaultScreen(xDisplay)); + for (i = 0; i < numColors; i++) + { + color.pixel = i; + 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 << XDefaultDepthOfScreen (XDefaultScreenOfDisplay (xDisplay)); + screenDirect = 0; + } else + { + destRedMask = visual->red_mask; + destGreenMask = visual->green_mask; + destBlueMask = visual->blue_mask; + screenDirect = 1; + } + + xImagePtr = 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*) 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 = XCreateGC (xDisplay, drawable, 0, NULL); + XPutImage(xDisplay, drawable, tempGC, xImagePtr, 0, 0, 0, 0, srcWidth, srcHeight); + + XDestroyImage (xImagePtr); + 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 = XDefaultVisual(xDisplay, XDefaultScreen(xDisplay)); + *pixmap = 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) + { + 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 = XDefaultRootWindow (display); + ng_stream_t in; + ng_bitmap_image_t image; + ng_err_t err = ERR_OK; + int screenDepth = XDefaultDepthOfScreen (screen); + Pixmap pixmap; + + NgInit(); + + 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/bundles/org.eclipse.equinox.launcher/library/motif/NgImage.h b/bundles/org.eclipse.equinox.launcher/library/motif/NgImage.h new file mode 100644 index 000000000..9f1b1320a --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgImage.h @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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> + +/** + * 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/bundles/org.eclipse.equinox.launcher/library/motif/NgImageData.c b/bundles/org.eclipse.equinox.launcher/library/motif/NgImageData.c new file mode 100644 index 000000000..d19f1dc22 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgImageData.c @@ -0,0 +1,490 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/motif/NgImageData.h b/bundles/org.eclipse.equinox.launcher/library/motif/NgImageData.h new file mode 100644 index 000000000..df3c9013d --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgImageData.h @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/motif/NgWinBMPFileFormat.c b/bundles/org.eclipse.equinox.launcher/library/motif/NgWinBMPFileFormat.c new file mode 100644 index 000000000..cf8b77f28 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgWinBMPFileFormat.c @@ -0,0 +1,367 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/motif/NgWinBMPFileFormat.h b/bundles/org.eclipse.equinox.launcher/library/motif/NgWinBMPFileFormat.h new file mode 100644 index 000000000..3ff010db1 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/NgWinBMPFileFormat.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/motif/build.sh b/bundles/org.eclipse.equinox.launcher/library/motif/build.sh new file mode 100644 index 000000000..86ea1eab2 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/build.sh @@ -0,0 +1,134 @@ +#!/bin/sh +#******************************************************************************* +# Copyright (c) 2000, 2005 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) +#******************************************************************************* +# +# 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="" +defaultOSArch="" +defaultWS="" +makefile="" +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="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + "Linux") + makefile="make_linux.mak" + defaultOS="linux" + defaultOSArch="x86" + defaultWS="motif" + X11_HOME=/usr/X11R6 + MOTIF_HOME=/bluebird/teamswt/swt-builddir/motif21 + OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + "SunOS") + makefile="make_solaris.mak" + defaultOS="solaris" + defaultOSArch="sparc" + defaultWS="motif" + OS="Solaris" + X11_HOME=/usr/openwin + MOTIF_HOME=/usr/dt + OUTPUT_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="../../bin/$defaultWS/$defaultOS/$defaultOSArch" + ;; + *) + makefile="make_hpux_PA_RISC.mak" + defaultOS="hpux" + defaultOSArch="PA_RISC" + defaultWS="motif" + OUTPUT_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 + 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" + +export OUTPUT_DIR PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS X11_HOME MOTIF_HOME + +# 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/bundles/org.eclipse.equinox.launcher/library/motif/build.xml b/bundles/org.eclipse.equinox.launcher/library/motif/build.xml new file mode 100644 index 000000000..b4308a9a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/build.xml @@ -0,0 +1,21 @@ +<?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> + <eclipse.refreshLocal resource="platform-launcher" depth="infinite" /> +</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/bundles/org.eclipse.equinox.launcher/library/motif/eclipseMotif.c b/bundles/org.eclipse.equinox.launcher/library/motif/eclipseMotif.c new file mode 100644 index 000000000..56c3fd21a --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/eclipseMotif.c @@ -0,0 +1,626 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 "eclipseMozilla.h" +#include "eclipseOS.h" +#include "eclipseUtil.h" +#include "NgImage.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> + +#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> + +#ifndef NO_XINERAMA_EXTENSIONS +#include <X11/extensions/Xinerama.h> +#endif + +/* Global Variables */ +char dirSeparator = '/'; +char pathSeparator = ':'; +char* consoleVM = "java"; +char* defaultVM = "java"; +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. */ +static XtAppContext appContext = 0; +static Widget topWindow = 0; +static int saveArgc = 0; +static char** saveArgv = 0; + +/* Define local variables for running the JVM and detecting its exit. */ +static pid_t jvmProcess = 0; +static int jvmExitCode; + +/* Define local variables for handling the splash window and its image. */ +static Widget splashShell = 0; +static Widget label = NULL; +static Widget progress = NULL; +static XColor foreground = {0, 0, 0, 0, 0, 0}; +static XRectangle progressRect = {0, 0, 0, 0}, messageRect = {0, 0, 0, 0}; +static int value = 0, maximum = 100; + +/* Local functions */ +static void bringDownSplashWindow( int ); +static void centreShell( Widget widget, Widget expose ); +static void splashTimeout( XtPointer data, XtIntervalId* id ); +#ifdef NETSCAPE_FIX +static void fixEnvForNetscape(); +#endif /* NETSCAPE_FIX */ + +/* 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, just print the error and return. */ + displayName = getenv("DISPLAY"); + if (displayName == NULL || strlen(displayName) == 0) + { + printf( "%s: %s\n", title, message ); + return; + } + + /* If Xt has not been initialized yet, do it now. */ + if (topWindow == 0) + { + initWindowSystem( &saveArgc, saveArgv, 1 ); + } + + msg = XmStringGenerate( message, NULL, XmCHARSET_TEXT, NULL ); + + /* Output a simple message box. */ + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNdialogType, XmDIALOG_MESSAGE ); nArgs++; + XtSetArg( arg[ nArgs ], XmNtitle, title ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmessageString, msg ); nArgs++; + msgBox = XmCreateMessageDialog( topWindow, officialName, arg, nArgs ); + XtUnmanageChild( XmMessageBoxGetChild( msgBox, XmDIALOG_CANCEL_BUTTON ) ); + XtUnmanageChild( XmMessageBoxGetChild( msgBox, XmDIALOG_HELP_BUTTON ) ); + XtManageChild( msgBox ); + centreShell( msgBox, msgBox ); + if (msg != 0) XmStringFree (msg); + + /* Wait for the OK button to be pressed. */ + while (XtIsRealized( msgBox ) && XtIsManaged( msgBox )) + { + XtAppNextEvent( appContext, &event ); + XtDispatchEvent( &event ); + } + XtDestroyWidget( msgBox ); +} + + +/* Initialize Window System + * + * Initialize the Xt and Xlib. + */ +void initWindowSystem( int* pArgc, char* argv[], int showSplash ) +{ + Arg arg[20]; + + /* Save the arguments in case displayMessage() is called in the main launcher. */ + if (saveArgv == 0) + { + saveArgc = *pArgc; + saveArgv = argv; + } + + /* If the splash screen is going to be displayed by this process */ + if (showSplash) + { + /* Create the top level shell that will not be used other than + to initialize the application. */ + XtSetLanguageProc (NULL, NULL, NULL); + topWindow = XtAppInitialize( &appContext, officialName, NULL, 0, + pArgc, argv, NULL, NULL, 0 ); + XtSetArg( arg[ 0 ], XmNmappedWhenManaged, False ); + XtSetValues( topWindow, arg, 1 ); + XtRealizeWidget( topWindow ); + } +} + + +static void readRect(char *str, XRectangle *rect) { + int x, y, width, height; + char *temp = str, *comma; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + x = atoi(temp); + temp = comma + 1; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + y = atoi(temp); + temp = comma + 1; + comma = strchr(temp, ','); + if (comma == NULL) return; + comma[0] = 0; + width = atoi(temp); + temp = comma + 1; + height = atoi(temp); + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; +} + +static void readColor(char *str, XColor *color) { + int value = atoi(str); + color->red = ((value & 0xFF0000) >> 16) * 0xFF; + color->green = ((value & 0xFF00) >> 8) * 0xFF; + color->blue = ((value & 0xFF) >> 0) * 0xFF; +} + +static void readInput() { + int available; + FILE *fd = stdin; + char *buffer = NULL, *equals = NULL, *end, *line; + ioctl(fileno(fd), FIONREAD, &available); + if (available <= 0) return; + buffer = malloc(available + 1); + available = fread(buffer, 1, available, fd); + buffer[available] = 0; + line = buffer; + while (line != NULL) { + end = strchr(line, '\n'); + equals = strchr(line, '='); + if (end != NULL) end[0] = 0; + if (equals != NULL) { + char *str = (char *)equals + 1; + equals[0] = 0; + if (strcmp(line, "maximum") == 0) { + maximum = atoi(str); + if (progress) { + Arg argList[1]; + XtSetArg(argList[0], XmNmaximum, maximum); + XtSetValues (progress, argList, 1); + } + } else if (strcmp(line, "value") == 0) { + value = atoi(str); + if (progress) { + Arg argList[1]; + XtSetArg(argList[0], XmNvalue, value); + XtSetValues (progress, argList, 1); + } + } else if (strcmp(line, "progressRect") == 0) { + readRect(str, &progressRect); + if (progress) { + XtConfigureWidget (progress, progressRect.x, progressRect.y, progressRect.width, progressRect.height, 0); + } + } else if (strcmp(line, "messageRect") == 0) { + readRect(str, &messageRect); + if (label) { + XtConfigureWidget (label, messageRect.x, messageRect.y, messageRect.width, messageRect.height, 0); + } + } else if (strcmp(line, "foreground") == 0) { + Arg argList[1]; + Display *xDisplay = XtDisplay(topWindow); + readColor(str, &foreground); + XAllocColor(xDisplay, XDefaultColormap(xDisplay, XDefaultScreen(xDisplay)), &foreground); + XtSetArg(argList[0], XmNforeground, foreground.pixel); + if (label) XtSetValues (label, argList, 1); + } else if (strcmp(line, "message") == 0) { + if (label) { + Arg argList[2]; + XmString xmString = XmStringGenerate(str, NULL, XmCHARSET_TEXT, NULL); + XtSetArg(argList[0], XmNlabelType, XmSTRING); + XtSetArg(argList[1], XmNlabelString, xmString); + XtSetValues (label, argList, 2); + XmStringFree (xmString); + } + } + + } + if (end != NULL) line = end + 1; + else line = NULL; + } + free(buffer); +} + +static void timerProc( XtPointer data, XtIntervalId* id ) { + readInput(); + XtAppAddTimeOut( appContext, 50, timerProc, 0 ); +} + +/* Show the Splash Window + * + * Create the splash window, load the pixmap and display the splash window. + */ +int showSplash( char* timeoutString, char* featureImage ) +{ + int timeout = 0; + Pixmap splashPixmap = 0; + Widget image, drawingArea; + Display *xDisplay; + Window root; + Screen* screen; + Arg arg[20]; + int nArgs; + unsigned int width, height, depth, border; + int x, y; + XEvent event; + XSetWindowAttributes attributes; + + /* 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). */ + /* Note: On Linux when the splash window process is started by the 1.3.0 IBM JVM, + the USR1 signal does not get sent to our signal handler. Hence, the splash + window will stay displayed if the JVM exits during initialization. However, + USR2 appears to work. + */ + signal( SIGUSR2, bringDownSplashWindow ); + + /* Load the feature specific splash image if defined. */ + xDisplay = XtDisplay( topWindow ); + screen = XDefaultScreenOfDisplay( xDisplay ); + if (featureImage != NULL) + { + splashPixmap = loadBMPImage(xDisplay, screen, featureImage); + } + + /* If the splash image could not be found, return an error. */ + if (splashPixmap == 0) + return ENOENT; + + XGetGeometry (xDisplay, splashPixmap, &root, &x, &y, &width, &height, &border, &depth); + + /* Create an application shell with no decorations. + * Do not use an overrideShell because it is not known to the + * window manager. As a result, when the error message box is + * displayed on top of the splash window (overrideShell) button + * events in the message box are sent to the splash window instead. + * On Linux, this brings the splash window on top of the message + * box which can no longer be accessed or terminated. + */ + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNborderWidth, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmappedWhenManaged, False ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmwmDecorations, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmwmFunctions, MWM_FUNC_MOVE ); nArgs++; + XtSetArg( arg[ nArgs ], XmNwidth, width ); nArgs++; + XtSetArg( arg[ nArgs ], XmNheight, height ); nArgs++; + splashShell = XtCreatePopupShell( officialName, transientShellWidgetClass, topWindow, arg, nArgs ); + + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNborderWidth, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmarginWidth, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmarginHeight, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNresizePolicy, XmRESIZE_NONE ); nArgs++; + drawingArea = XmCreateDrawingArea (splashShell, NULL, arg, nArgs ); + XtManageChild( drawingArea ); + + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNslidingMode, XmTHERMOMETER ); nArgs++; + XtSetArg( arg[ nArgs ], XmNeditable, False ); nArgs++; + XtSetArg( arg[ nArgs ], XmNshadowThickness, 1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNorientation, XmHORIZONTAL ); nArgs++; + XtSetArg( arg[ nArgs ], XmNsliderVisual, XmFOREGROUND_COLOR); nArgs++; + XtSetArg( arg[ nArgs ], XmNhighlightThickness, 0); nArgs++; + XtSetArg( arg[ nArgs ], XmNborderWidth, 0); nArgs++; + XtSetArg( arg[ nArgs ], XmNtraversalOn, 0); nArgs++; + XtSetArg( arg[ nArgs ], XmNx, -1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNy, -1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNwidth, 1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNheight, 1 ); nArgs++; + progress = XmCreateScale ( drawingArea, "", arg, nArgs ); + XtManageChild( progress ); + + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNlabelType, XmPIXMAP ); nArgs++; + XtSetArg( arg[ nArgs ], XmNlabelPixmap, splashPixmap ); nArgs++; + XtSetArg( arg[ nArgs ], XmNwidth, width ); nArgs++; + XtSetArg( arg[ nArgs ], XmNheight, height ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmarginHeight, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmarginWidth, 0 ); nArgs++; + image = XmCreateLabelGadget ( drawingArea, "", arg, nArgs ); + XtManageChild( image ); + + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNlabelType, XmSTRING ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmarginHeight, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNmarginWidth, 0 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNx, -1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNy, -1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNwidth, 1 ); nArgs++; + XtSetArg( arg[ nArgs ], XmNheight, 1 ); nArgs++; + label = XmCreateLabelGadget ( drawingArea, "", arg, nArgs ); + XtManageChild( label ); + + /* Set the background pixmap to None to avoid a gray flash when the image appears. */ + XtRealizeWidget( splashShell ); + attributes.background_pixmap = None; + XChangeWindowAttributes( XtDisplay( drawingArea ), XtWindow( drawingArea ), CWBackPixmap, &attributes ); + + readInput(); + XtAppAddTimeOut( appContext, 50, timerProc, 0 ); + + /* Centre the splash screen and display it. */ + centreShell( splashShell, drawingArea ); + + /* If a timeout for the splash window was given */ + if (timeout != 0) + { + /* Add a timeout (in milliseconds) to bring down the splash screen. */ + XtAppAddTimeOut( appContext, (timeout * 1000), splashTimeout, 0 ); + } + + /* Process messages until the splash window is closed or process is terminated. */ + while (XtIsRealized( splashShell )) + { + XtAppNextEvent( appContext, &event ); + XtDispatchEvent( &event ); + } + + /* Clean up. */ + XFreePixmap( XtDisplay(splashShell), splashPixmap ); + 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; +} + + +/* 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; + +#ifdef NETSCAPE_FIX + fixEnvForNetscape(); +#endif /* NETSCAPE_FIX */ +#ifdef MOZILLA_FIX + fixEnvForMozilla(); +#endif /* MOZILLA_FIX */ + + /* 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 (splashShell != 0) + { + XtUnrealizeWidget( splashShell ); + XFlush( XtDisplay( splashShell ) ); + } +} + +/* Splash Window Timeout */ +static void splashTimeout( XtPointer data, XtIntervalId* id ) +{ + bringDownSplashWindow(0); +} + +/* Centre the shell on the screen. */ +static 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. */ + XtRealizeWidget( widget ); + + /* Get the desired dimensions of the shell. */ + nArgs = 0; + XtSetArg( arg[ nArgs ], XmNwidth, &width ); nArgs++; + XtSetArg( arg[ nArgs ], XmNheight, &height ); nArgs++; + XtSetArg( arg[ nArgs ], XmNscreen, &screen ); nArgs++; + XtGetValues( widget, arg, nArgs ); + + screenWidth = screen->width; + screenHeight = screen->height; +#ifndef NO_XINERAMA_EXTENSIONS + display = XtDisplay( widget ); + if (XineramaIsActive( display )) { + info = XineramaQueryScreens( display, &monitorCount ); + if (info != 0) { + if (monitorCount > 1) { + screenWidth = info->width; + screenHeight = info->height; + } + 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; + XtSetArg( arg[ nArgs ], XmNx, x ); nArgs++; + XtSetArg( arg[ nArgs ], XmNy, y ); nArgs++; + XtSetValues( widget, arg, nArgs ); + 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 = XtWidgetToApplicationContext( widget ); + waiting = True; + while (waiting) + { + XtAppNextEvent( context, &event ); + if (event.xany.type == Expose && event.xany.window == XtWindow( expose )) + { + waiting = False; + } + XtDispatchEvent( &event ); + } + XFlush( XtDisplay( widget ) ); +} +#ifdef NETSCAPE_FIX +extern char* findCommand( char*); +static const char* XFILESEARCHPATH = "XFILESEARCHPATH"; + +static 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 */ diff --git a/bundles/org.eclipse.equinox.launcher/library/motif/make_aix.mak b/bundles/org.eclipse.equinox.launcher/library/motif/make_aix.mak new file mode 100644 index 000000000..592731b81 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/make_aix.mak @@ -0,0 +1,63 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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 AIX/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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseMotif.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = -L$(MOTIF_HOME)/lib -lXm -lXt -lX11 +CFLAGS = -O -s \ + -DNO_XINERAMA_EXTENSIONS \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -DAIX \ + -I./ \ + -I../ \ + -I$(MOTIF_HOME)/include + +all: $(EXEC) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -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/bundles/org.eclipse.equinox.launcher/library/motif/make_hpux_PA_RISC.mak b/bundles/org.eclipse.equinox.launcher/library/motif/make_hpux_PA_RISC.mak new file mode 100644 index 000000000..d43f88416 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/make_hpux_PA_RISC.mak @@ -0,0 +1,66 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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 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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseMotif.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lXm -lXt -lX11 +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 \ + +DAportable + +all: $(EXEC) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipse.c -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.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 $@ + +$(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/bundles/org.eclipse.equinox.launcher/library/motif/make_hpux_ia64_32.mak b/bundles/org.eclipse.equinox.launcher/library/motif/make_hpux_ia64_32.mak new file mode 100644 index 000000000..64b701298 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/make_hpux_ia64_32.mak @@ -0,0 +1,66 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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) +#******************************************************************************* + +# 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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseMotif.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lXm -lXt -lX11 +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 + +all: $(EXEC) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipse.c -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.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 $@ + +$(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/bundles/org.eclipse.equinox.launcher/library/motif/make_linux.mak b/bundles/org.eclipse.equinox.launcher/library/motif/make_linux.mak new file mode 100644 index 000000000..fc64bcaef --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/make_linux.mak @@ -0,0 +1,68 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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 Linux/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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseMozilla.o eclipseMotif.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = -Xlinker -rpath -Xlinker . -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lXm -lXt -lX11 -lXinerama +CFLAGS = -O -s -Wall \ + -DLINUX \ + -DMOZILLA_FIX \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -fPIC \ + -I./ \ + -I../ \ + -I$(MOTIF_HOME)/include \ + -I$(X11_HOME)/include + +all: $(EXEC) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseOS.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 $@ + +$(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/bundles/org.eclipse.equinox.launcher/library/motif/make_solaris.mak b/bundles/org.eclipse.equinox.launcher/library/motif/make_solaris.mak new file mode 100644 index 000000000..2bcdd5af0 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/motif/make_solaris.mak @@ -0,0 +1,65 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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 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 + +# Define the object modules to be compiled and flags. +OBJS = eclipse.o eclipseUtil.o eclipseShm.o eclipseConfig.o eclipseMotif.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o +EXEC = $(PROGRAM_OUTPUT) +LIBS = -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lXm -lXt -lX11 -lintl +CFLAGS = -O -s \ + -DSOLARIS \ + -DNO_XINERAMA_EXTENSIONS \ + -DNETSCAPE_FIX \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I./ \ + -I../ \ + -I$(MOTIF_HOME)/include \ + -I$(X11_HOME)/include + +all: $(EXEC) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +eclipse.o: ../eclipse.c ../eclipseOS.h + $(CC) $(CFLAGS) -c $^ -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $^ -o $@ + +eclipseShm.o: ../eclipseShm.c ../eclipseShm.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $^ -o $@ + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -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/bundles/org.eclipse.equinox.launcher/library/photon/.cvsignore b/bundles/org.eclipse.equinox.launcher/library/photon/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/photon/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.launcher/library/photon/build.sh b/bundles/org.eclipse.equinox.launcher/library/photon/build.sh new file mode 100644 index 000000000..2166d19ff --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/photon/build.sh @@ -0,0 +1,78 @@ +#!/bin/sh +#******************************************************************************* +# Copyright (c) 2000, 2005 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" +OUTPUT_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/bundles/org.eclipse.equinox.launcher/library/photon/build.xml b/bundles/org.eclipse.equinox.launcher/library/photon/build.xml new file mode 100644 index 000000000..b4308a9a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/photon/build.xml @@ -0,0 +1,21 @@ +<?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> + <eclipse.refreshLocal resource="platform-launcher" depth="infinite" /> +</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/bundles/org.eclipse.equinox.launcher/library/photon/eclipsePhoton.c b/bundles/org.eclipse.equinox.launcher/library/photon/eclipsePhoton.c new file mode 100644 index 000000000..e45e2c0e2 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/photon/eclipsePhoton.c @@ -0,0 +1,290 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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* consoleVM = "java"; +char* defaultVM = "java"; +char* shippedVMDir = "jre/bin/"; +#else +char* consoleVM = "j9"; +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, officialName, ~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/bundles/org.eclipse.equinox.launcher/library/photon/make_qnx.mak b/bundles/org.eclipse.equinox.launcher/library/photon/make_qnx.mak new file mode 100644 index 000000000..fac6918db --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/photon/make_qnx.mak @@ -0,0 +1,57 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/win32/.cvsignore b/bundles/org.eclipse.equinox.launcher/library/win32/.cvsignore new file mode 100644 index 000000000..ef22704b6 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/.cvsignore @@ -0,0 +1,3 @@ +*.obj +eclipse.exe +eclipse.res diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/build.bat b/bundles/org.eclipse.equinox.launcher/library/win32/build.bat new file mode 100644 index 000000000..9f7371e5a --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/build.bat @@ -0,0 +1,109 @@ +@rem ******************************************************************************* +@rem Copyright (c) 2000, 2005 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 -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 +@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 not "%MSVC_HOME%" == "" goto MAKE +set MSVC_HOME=k:\dev\products\msvc60\vc98 +call %MSVC_HOME%\bin\vcvars32.bat +if not "%mssdk%" == "" goto MAKE +set mssdk=K:\dev\PRODUCTS\PLATSDK\feb2003 +call %mssdk%\setenv.bat + +:MAKE + +rem -------------------------- +rem Define default values for environment variables used in the makefiles. +rem -------------------------- +set programOutput=eclipse.exe +set defaultOS=win32 +set defaultOSArch=x86 +set defaultWS=win32 +set makefile=make_win32.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 ) + +: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 DEFAULT_OS=%defaultOS% +set DEFAULT_OS_ARCH=%defaultOSArch% +set DEFAULT_WS=%defaultWS% +set OUTPUT_DIR=..\..\bin\%defaultWS%\%defaultOS%\%defaultOSArch% + +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/bundles/org.eclipse.equinox.launcher/library/win32/build.sh b/bundles/org.eclipse.equinox.launcher/library/win32/build.sh new file mode 100644 index 000000000..386f81d59 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/build.sh @@ -0,0 +1,76 @@ +#!/bin/sh +#******************************************************************************* +# Copyright (c) 2000, 2005 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" +OUTPUT_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/bundles/org.eclipse.equinox.launcher/library/win32/build.xml b/bundles/org.eclipse.equinox.launcher/library/win32/build.xml new file mode 100644 index 000000000..a5a99abbd --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/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="platform-launcher" 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/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.exe.manifest b/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.exe.manifest new file mode 100644 index 000000000..51cdc24f6 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/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="X86" 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="X86" publicKeyToken="6595b64144ccf1df" language="*"/> + </dependentAssembly> + </dependency> +</assembly> +
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.ico b/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.ico Binary files differnew file mode 100644 index 000000000..5b2f132dd --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.ico diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.rc b/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.rc new file mode 100644 index 000000000..723baa714 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/eclipse.rc @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c b/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c new file mode 100644 index 000000000..35e8089d7 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c @@ -0,0 +1,450 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 <windows.h> +#include <commctrl.h> +#include <process.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#ifdef __MINGW32__ +#include <stdlib.h> +#endif + +#define ECLIPSE_ICON 401 + +/* Global Variables */ +_TCHAR dirSeparator = _T('\\'); +_TCHAR pathSeparator = _T(';'); +_TCHAR* consoleVM = _T("java.exe"); +_TCHAR* defaultVM = _T("javaw.exe"); +_TCHAR* shippedVMDir = _T("jre\\bin\\"); + +/* Define the window system arguments for the Java VM. */ +static _TCHAR* argVM[] = { NULL }; + +/* Define local variables for the main window. */ +static HWND topWindow = 0; +static WNDPROC oldProc; + +/* Define local variables for running the JVM and detecting its exit. */ +static int jvmProcess = 0; +static int jvmExitCode = 0; +static int jvmExitTimeout = 100; +static int jvmExitTimerId = 99; + +/* Define local variables for handling the splash window and its image. */ +static int splashTimerId = 88, inputTimerId = 89; + +static HWND label = NULL, progress = NULL; +static COLORREF foreground = 0; +static RECT progressRect = {0, 0, 0, 0}, messageRect = {0, 0, 0, 0}; +static int value = 0, maximum = 100; + +/* Local functions */ +static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime ); +static HBITMAP loadSplashImage(_TCHAR *baseDir, _TCHAR *fileName); +static void CALLBACK splashTimeout( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime ); +static LRESULT WINAPI WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + +/* Display a Message */ +void displayMessage( _TCHAR* title, _TCHAR* message ) +{ + 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. + * + */ +void initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash ) +{ + /* Create a window that has no decorations. */ + InitCommonControls(); + topWindow = CreateWindowEx (0, + _T("STATIC"), + officialName, + SS_BITMAP | WS_POPUP, + 0, + 0, + 0, + 0, + NULL, + NULL, + GetModuleHandle (NULL), + NULL); + SetClassLong(topWindow, GCL_HICON, (LONG)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(ECLIPSE_ICON))); + oldProc = (WNDPROC) GetWindowLong (topWindow, GWL_WNDPROC); + SetWindowLong (topWindow, GWL_WNDPROC, (LONG) WndProc); +} + + +static void readRect(_TCHAR *str, RECT *rect) { + int x, y, width, height; + _TCHAR *temp = str, *comma; + comma = _tcschr(temp, _T(',')); + if (comma == NULL) return; + comma[0] = 0; + x = _ttoi(temp); + temp = comma + 1; + comma = _tcschr(temp, _T(',')); + if (comma == NULL) return; + comma[0] = 0; + y = _ttoi(temp); + temp = comma + 1; + comma = _tcschr(temp, _T(',')); + if (comma == NULL) return; + comma[0] = 0; + width = _ttoi(temp); + temp = comma + 1; + height = _ttoi(temp); + rect->left = x; + rect->top = y; + rect->right = x + width; + rect->bottom = y + height; +} + +static void readColor(_TCHAR *str, COLORREF *color) { + int value = _ttoi(str); + *color = ((value & 0xFF0000) >> 16) | (value & 0xFF00) | ((value & 0xFF) << 16); +} + +static void readInput() { + int available; + FILE *fd = stdin; +#ifdef _UNICODE + WCHAR *buffer1 = NULL; +#endif + char *buffer = NULL; + _TCHAR *equals = NULL, *end, *line; + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + available = GetFileSize (hStdin, NULL) - SetFilePointer (hStdin, 0, NULL, FILE_CURRENT); + if (available <= 0) return; + buffer = malloc(available + 1); + if (!ReadFile(hStdin, buffer, available, &available, NULL)) { + return; + } + if (available <= 0) { + free(buffer); + return; + } + buffer[available] = 0; +#ifdef _UNICODE + { + buffer1 = malloc((available + 1) * sizeof(TCHAR)); + available = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)buffer, available, (LPWSTR)buffer1, available); + buffer1[available] = 0; + line = buffer1; + } +#else + line = buffer; +#endif + while (line != NULL) { + end = _tcschr(line, _T('\n')); + equals = _tcschr(line, _T('=')); + if (end != NULL) end[0] = 0; + if (equals != NULL) { + _TCHAR *str = (_TCHAR *)equals + 1; + equals[0] = 0; + if (_tcscmp(line, _T("maximum")) == 0) { + maximum = _ttoi(str); + if (progress) { + SendMessage (progress, PBM_SETRANGE32, 0, maximum); + } + } else if (_tcscmp(line, _T("value")) == 0) { + value = _ttoi(str); + if (progress) { + SendMessage (progress, PBM_SETPOS, value, 0); + } + } else if (_tcscmp(line, _T("progressRect")) == 0) { + readRect(str, &progressRect); + if (progress) { + int flags = SWP_NOZORDER | SWP_DRAWFRAME | SWP_NOACTIVATE; + SetWindowPos (progress, 0, progressRect.left, progressRect.top, progressRect.right - progressRect.left, progressRect.bottom - progressRect.top, flags); + } + } else if (_tcscmp(line, _T("messageRect")) == 0) { + readRect(str, &messageRect); + if (label) { + int flags = SWP_NOZORDER | SWP_DRAWFRAME | SWP_NOACTIVATE; + SetWindowPos (label, 0, messageRect.left, messageRect.top, messageRect.right - messageRect.left, messageRect.bottom - messageRect.top, flags); + } + } else if (_tcscmp(line, _T("foreground")) == 0) { + readColor(str, &foreground); + if (label) { + RECT rect; + GetWindowRect (label, &rect); + MapWindowPoints (0, topWindow, (POINT *)&rect, 2); + InvalidateRect (topWindow, &rect, 1); + } + } else if (_tcscmp(line, _T("message")) == 0) { + if (label) { + RECT rect; + SetWindowText (label, str); + GetWindowRect (label, &rect); + MapWindowPoints (0, topWindow, (POINT *)&rect, 2); + InvalidateRect (topWindow, &rect, 1); + } + } + + } + if (end != NULL) line = end + 1; + else line = NULL; + } + free(buffer); +#ifdef _UNICODE + if (buffer1 != NULL) free(buffer1); +#endif +} + +static void CALLBACK timerProc( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime ) { + readInput(); +} + +/* Show the Splash Window + * + * Open the bitmap, insert into the splash window and display it. + * + */ +int showSplash( _TCHAR* timeoutString, _TCHAR* featureImage ) +{ + int timeout = 0; + RECT rect; + HBITMAP hBitmap = 0; + HDC hDC; + int depth; + int x, y; + int width, height; + MSG msg; + + /* Determine the splash timeout value (in seconds). */ + if (timeoutString != NULL && _tcslen( timeoutString ) > 0) + { + _stscanf( timeoutString, _T("%d"), &timeout ); + } + + /* 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; + + /* Load the bitmap into the splash popup window. */ + SendMessage( topWindow, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBitmap ); + + progress = CreateWindowEx (0, _T("msctls_progress32"), + _T(""), + WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, + 0, + 0, + 0, + 0, + topWindow, + NULL, + GetModuleHandle (NULL), + NULL); + label = CreateWindowEx (0, _T("STATIC"), + _T(""), + WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, + 0, + 0, + 0, + 0, + topWindow, + NULL, + GetModuleHandle (NULL), + NULL); + SendMessage (label, WM_SETFONT, (WPARAM)GetStockObject (DEFAULT_GUI_FONT), (LPARAM)1); + + readInput(); + SetTimer( topWindow, inputTimerId, 50, timerProc ); + + /* Centre the splash window and display it. */ + GetWindowRect (topWindow, &rect); + width = GetSystemMetrics (SM_CXSCREEN); + height = GetSystemMetrics (SM_CYSCREEN); + x = (width - (rect.right - rect.left)) / 2; + y = (height - (rect.bottom - rect.top)) / 2; + SetWindowPos (topWindow, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + ShowWindow( topWindow, SW_SHOW ); + BringWindowToTop( topWindow ); + + /* If a timeout for the splash window was given */ + if (timeout != 0) + { + /* Add a timeout (in milliseconds) to bring down the splash screen. */ + SetTimer( topWindow, splashTimerId, (timeout * 1000), splashTimeout ); + } + + /* Process messages until the splash window is closed or process is terminated. */ + while (GetMessage( &msg, NULL, 0, 0 )) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + return 0; +} + + +/* Get the window system specific VM args */ +_TCHAR** getArgVM( _TCHAR *vm ) +{ + return argVM; +} + + +/* 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( _TCHAR* args[] ) +{ + MSG msg; + int index, length; + _TCHAR *commandLine, *ch, *space; + + /* + * Build the command line. Any argument with spaces must be in + * double quotes in the command line. + */ + length = 0; + for (index = 0; args[index] != NULL; index++) + { + /* String length plus space character */ + length += _tcslen( args[ index ] ) + 1; + /* Quotes */ + if (_tcschr( args[ index ], _T(' ') ) != NULL) length += 2; + } + commandLine = ch = malloc ( (length + 1) * sizeof(_TCHAR) ); + 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) *ch++ = _T('\"'); + *ch++ = _T(' '); + } + *ch = _T('\0'); + + /* + * 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. */ + jvmExitCode = errno; + jvmProcess = 0; + } + + /* else */ + else + { + /* 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 jvmExitCode; +} + +/* Local functions */ + +/* 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 startJavaVM() to exit. */ + jvmExitCode = exitCode; + jvmProcess = 0; + } +} + +/* Splash Timeout */ +static void CALLBACK splashTimeout( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime ) +{ + /* Kill the timer. */ + KillTimer( topWindow, id ); + PostMessage( topWindow, WM_QUIT, 0, 0 ); +} + +/* Window Procedure for the Spash window. + * + * A special WndProc is needed to return the proper vlaue for WM_NCHITTEST. + * It must also detect the message from the splash window process. + */ +static LRESULT WINAPI WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_NCHITTEST: return HTCLIENT; + case WM_CLOSE: + PostQuitMessage( 0 ); + break; + case WM_CTLCOLORSTATIC: + if ((HWND)lParam == label) { + SetTextColor((HDC)wParam, foreground); + SetBkMode((HDC)wParam, TRANSPARENT); + return (LRESULT)GetStockObject (NULL_BRUSH); + } + break; + } + return CallWindowProc (oldProc, hwnd, uMsg, wParam, lParam); +} + diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak b/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak new file mode 100644 index 000000000..5b38f9172 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak @@ -0,0 +1,104 @@ +#******************************************************************************* +# Copyright (c) 2000, 2005 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) +#******************************************************************************* + +# Makefile for creating the 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 + +# 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 +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. +OBJS = eclipse.o eclipseWin.o eclipseShm.o eclipseConfig.o eclipseUtil.o \ + aeclipse.o aeclipseWin.o aeclipseShm.o aeclipseConfig.o aeclipseUtil.o +LIBS = -lkernel32 -luser32 -lgdi32 -lcomctl32 -lmsvcrt +LDFLAGS = -mwindows -mno-cygwin +RES = eclipse.res +EXEC = $(PROGRAM_OUTPUT) +DEBUG = $(CDEBUG) +CFLAGS = -O -s -Wall \ + -I. $(SYSINC) \ + -D_WIN32 \ + -DWIN32_LEAN_AND_MEAN \ + -mno-cygwin +ACFLAGS = -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + $(DEBUG) $(CFLAGS) +WCFLAGS = -DUNICODE $(ACFLAGS) + +all: $(EXEC) + +eclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c ../eclipseShm.h + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipse.c + +eclipseUtil.o: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseUtil.c + +eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseShm.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 + +aeclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c ../eclipseShm.h + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipse.c + +aeclipseUtil.o: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseUtil.c + +aeclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseShm.c + +aeclipseConfig.o: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseConfig.c + +aeclipseWin.o: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ eclipseWin.c + +$(RES): eclipse.rc + $(RC) --output-format=coff --include-dir=.. -o $@ $< + +$(EXEC): $(OBJS) $(RES) + $(CC) $(LDFLAGS) -o $(EXEC) $(OBJS) $(RES) $(LIBS) + +install: all + cp $(EXEC) $(OUTPUT_DIR) + rm -f $(EXEC) $(OBJS) $(RES) + +clean: + $(RM) $(EXEC) $(OBJS) $(RES) diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/make_win32.mak b/bundles/org.eclipse.equinox.launcher/library/win32/make_win32.mak new file mode 100644 index 000000000..33a768b08 --- /dev/null +++ b/bundles/org.eclipse.equinox.launcher/library/win32/make_win32.mak @@ -0,0 +1,81 @@ +#******************************************************************************* +#****************************************************************************** +# Copyright (c) 2000, 2005 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 +# 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 + +!include <ntwin32.mak> + +# Define the object modules to be compiled and flags. +OBJS = eclipse.obj eclipseWin.obj eclipseShm.obj eclipseConfig.obj eclipseUtil.obj aeclipse.obj aeclipseWin.obj aeclipseShm.obj aeclipseConfig.obj aeclipseUtil.obj +LIBS = kernel32.lib user32.lib gdi32.lib comctl32.lib +LFLAGS = /INCREMENTAL:NO /NOLOGO -subsystem:windows,4.0 -entry:wmainCRTStartup +RES = eclipse.res +EXEC = eclipse.exe +DEBUG = #$(cdebug) +acflags = -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + $(cflags) +wcflags = -DUNICODE $(acflags) + +all: $(EXEC) + +eclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c ../eclipseShm.h + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipse.c + +eclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseUtil.c + +eclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseShm.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 + +aeclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c ../eclipseShm.h + $(cc) $(DEBUG) $(acflags) $(cvars) /Foaeclipse.obj ../eclipse.c + +aeclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseUtil.obj ../eclipseUtil.c + +aeclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseShm.obj ../eclipseShm.c + +aeclipseConfig.obj: ../eclipseConfig.h ../eclipseConfig.h ../eclipseConfig.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseConfig.obj ../eclipseConfig.c + +aeclipseWin.obj: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseWin.obj eclipseWin.c + +$(EXEC): $(OBJS) $(RES) + $(link) $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(OBJS) $(RES) $(LIBS) + +$(RES): eclipse.rc + $(rc) -r -fo $(RES) eclipse.rc + +install: all + copy $(EXEC) $(OUTPUT_DIR) + del -f $(EXEC) $(OBJS) $(RES) + +clean: + del $(EXEC) $(OBJS) $(RES) |