diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.executable/library')
63 files changed, 8119 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/.cvsignore b/bundles/org.eclipse.equinox.executable/library/carbon/.cvsignore new file mode 100644 index 000000000..f0fdae47c --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/carbon/.cvsignore @@ -0,0 +1,3 @@ +*.o +eclipse +*.so diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/build.sh b/bundles/org.eclipse.equinox.executable/library/carbon/build.sh new file mode 100644 index 000000000..c5454cdb3 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/carbon/build.xml b/bundles/org.eclipse.equinox.executable/library/carbon/build.xml new file mode 100644 index 000000000..b4308a9a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/carbon/eclipseCarbon.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c new file mode 100644 index 000000000..d509e23b6 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c @@ -0,0 +1,219 @@ +/* + * 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 "eclipseCommon.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 LAUNCHER "-launcher" +#define SPLASH_LAUNCHER "/Resources/Splash.app/Contents/" + +#define DEBUG 0 + +char *findCommand(char *command); + +static PixMapHandle loadBMPImage(const char *image); + +/* Global Variables */ +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 WindowRef window; +static ControlRef pane = NULL; +static long splashHandle = 0; + +int main() { +} + +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); + return result; +} + +/* Show the Splash Window + * + * Create the splash window, load the bitmap and display the splash window. + */ +int showSplash( const _TCHAR* featureImage ) +{ + Rect wRect; + int w, h, deviceWidth, deviceHeight; + PixMap *pm; + PixMapHandle pixmap; + EventTypeSpec draw = {kEventClassControl, kEventControlDraw}; + + /*debug("featureImage: %s\n", featureImage);*/ + + /*init();*/ + + 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(kSheetWindowClass, kWindowStandardHandlerAttribute | kWindowCompositingAttribute, &wRect, &window); + if (window != NULL) { + ControlRef root = NULL; + CreateRootControl(window, &root); + GetRootControl(window, &root); + SetRect(&wRect, 0, 0, w, h); + CreateUserPaneControl(window, &wRect, kControlSupportsEmbedding | kControlSupportsFocus | kControlGetsFocusOnClick, &pane); + EmbedControl(pane, root); + InstallEventHandler(GetControlEventTarget(pane), (EventHandlerUPP)drawProc, 1, &draw, pm, NULL); + ShowWindow(window); + splashHandle = (long)window; + dispatchMessages(); + } + + return 0; +} + +long getSplashHandle() { + return splashHandle; +} + +void takeDownSplash() { + if( splashHandle != 0) { + HideWindow(window); + DisposeWindow(window); + dispatchMessages(); + splashHandle = 0; + } +} +void dispatchMessages() { + EventRef event; + EventTargetRef target; + + target = GetEventDispatcherTarget(); + while( ReceiveNextEvent(0, NULL, kEventDurationNoWait, true, &event) == noErr ) { + SendEventToEventTarget(event, target); + ReleaseEvent(event); + } +} + +/* 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; +} + +/** + * 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; +} + +char * findVMLibrary( char* command ) { + return "/System/Library/Frameworks/JavaVM.framework/Versions/Current/JavaVM"; +} diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c new file mode 100644 index 000000000..6c04631a8 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseCommon.h" +#include "eclipseOS.h" + +#include <locale.h> +#include <dlfcn.h> +#include <unistd.h> +#include <CoreServices/CoreServices.h> +#include <Carbon/Carbon.h> +#include <mach-o/dyld.h> + +char dirSeparator = '/'; +char pathSeparator = ':'; + +void initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash ); + +int initialized = 0; + +static void init() { + if (!initialized) { + ProcessSerialNumber psn; + if (GetCurrentProcess(&psn) == noErr) { + 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); + + if (showSplash) + init(); +} + +/* 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); +} + +/* Load the specified shared library + */ +void * loadLibrary( char * library ){ + void * result= dlopen(library, RTLD_NOW); + if(result == 0) + printf("%s\n",dlerror()); + return result; +/* NSObjectFileImage *fileImage; + NSModule handle; + if(NSCreateObjectFileImageFromFile(library, &fileImage) == NSObjectFileImageSuccess) { + handle = NSLinkModule(fileImage,filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE); + NSDestroyObjectFileImage(fileImage); + } + + return handle; +*/} + +/* Unload the shared library + */ +void unloadLibrary( void * handle ){ + dlclose(handle); +/* NSUnlinkModule(handle, 0);*/ +} + +/* Find the given symbol in the shared library + */ +void * findSymbol( void * handle, char * symbol ){ + return dlsym(handle, symbol); + /*NSSymbol sym = NSLookupSymbolInModule(handle, symbol); + return NSAddressOfSymbol(sym);*/ +} diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonMain.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonMain.c new file mode 100644 index 000000000..aff31fb6c --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonMain.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + */ + +#include "eclipseCommon.h" + +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <ctype.h> +#include <pwd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include <CoreServices/CoreServices.h> +#include <Carbon/Carbon.h> +#include <mach-o/dyld.h> + + +#define APP_PACKAGE_PATTERN ".app/Contents/MacOS/" +#define APP_PACKAGE "APP_PACKAGE" +#define JAVAROOT "JAVAROOT" + +static void debug(const char *fmt, ...); +static void dumpArgs(char *tag, int argc, char* argv[]); +static char *append(char *buffer, const char *s); +static char *appendc(char *buffer, char c); +static char *expandShell(char *arg, const char *appPackage, const char *javaRoot); +static char *my_strcasestr(const char *big, const char *little); + +static FILE *fgConsoleLog; +static char *fgAppPackagePath; +static int fgPid; + +extern int original_main(int argc, char* argv[]); +int main( int argc, char* argv[] ) { + + SInt32 systemVersion= 0; + if (Gestalt(gestaltSystemVersion, &systemVersion) == noErr) { + systemVersion &= 0xffff; + 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; +} + +static void debug(const char *fmt, ...) { +#if DEBUG + va_list ap; + va_start(ap, fmt); + fprintf(fgConsoleLog, "%05d: ", fgPid); + vfprintf(fgConsoleLog, fmt, ap); + va_end(ap); +#endif +} + +static void dumpArgs(char *tag, int argc, char* argv[]) { +#if DEBUG + int i; + if (argc < 0) { + argc= 0; + for (i= 0; argv[i] != NULL; i++) + argc++; + } + debug(">>>> %s:", tag); + for (i= 0; i < argc && argv[i] != NULL; i++) + fprintf(fgConsoleLog, " <%s>", argv[i]); + fprintf(fgConsoleLog, "\n"); +#endif +} + +/* + * Expand $APP_PACKAGE, $JAVA_HOME, and does tilde expansion. + + A word beginning with an unquoted tilde character (~) is + subject to tilde expansion. All the characters up to a + slash (/) or the end of the word are treated as a username + and are replaced with the user's home directory. If the + username is missing (as in ~/foobar), the tilde is + replaced with the value of the HOME variable (the current + user's home directory). + */ +static char *expandShell(char *arg, const char *appPackage, const char *javaRoot) { + + if (index(arg, '~') == NULL && index(arg, '$') == NULL) + return arg; + + char *buffer= strdup(""); + char c, lastChar= ' '; + const char *cp= arg; + while ((c = *cp++) != 0) { + if (isspace(lastChar) && c == '~') { + char name[100], *dir= NULL; + int j= 0; + for (; (c = *cp) != 0; cp++) { + if (! isalnum(c)) + break; + name[j++]= c; + lastChar= c; + } + name[j]= '\0'; + if (j > 0) { + struct passwd *pw= getpwnam(name); + if (pw != NULL) + dir= pw->pw_dir; + } else { + dir= getenv("HOME"); + } + if (dir != NULL) + buffer= append(buffer, dir); + + } else if (c == '$') { + int l= strlen(APP_PACKAGE); + if (appPackage != NULL && strncmp(cp, APP_PACKAGE, l) == 0) { + cp+= l; + buffer= append(buffer, appPackage); + } else { + int l= strlen(JAVAROOT); + if (javaRoot != NULL && strncmp(cp, JAVAROOT, l) == 0) { + cp+= l; + buffer= append(buffer, javaRoot); + } else { + buffer= appendc(buffer, c); + } + } + } else + buffer= appendc(buffer, c); + lastChar= c; + } + return buffer; +} + +static char *my_strcasestr(const char *big, const char *little) { + char *cp, *s, *t; + for (cp= (char*) big; *cp; cp++) { + for (s= cp, t= (char*) little; *s && *t; s++, t++) + if (toupper(*s) != toupper(*t)) + break; + if (*t == '\0') + return cp; + } + return NULL; +} + +static char *append(char *buffer, const char *s) { + int bl= strlen(buffer); + int sl= strlen(s); + buffer= realloc(buffer, bl+sl+1); + strcpy(&buffer[bl], s); + return buffer; +} + +static char *appendc(char *buffer, char c) { + int bl= strlen(buffer); + buffer= realloc(buffer, bl+2); + buffer[bl++]= c; + buffer[bl]= '\0'; + return buffer; +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseMain.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseMain.c new file mode 100644 index 000000000..4d5425178 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseMain.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 "../eclipseMain.c" diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/make_macosx.mak b/bundles/org.eclipse.equinox.executable/library/carbon/make_macosx.mak new file mode 100644 index 000000000..e09dad0aa --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/carbon/make_macosx.mak @@ -0,0 +1,92 @@ +#********************************************************************** +# 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 + +#default value for PROGRAM_OUTPUT +ifeq ($(PROGRAM_OUTPUT),) + PROGRAM_OUTPUT=eclipse +endif +ifeq ($(PROGRAM_LIBRARY),) + PROGRAM_LIBRARY=$(PROGRAM_OUTPUT)_001.so +endif + +# 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 +MAIN_OBJS = eclipseMain.o eclipseCarbonMain.o +COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseCarbonCommon.o +DLL_OBJS = eclipse.o eclipseCarbon.o eclipseUtil.o eclipseJNI.o NgImageData.o NgWinBMPFileFormat.o NgCommon.o + +EXEC = $(PROGRAM_OUTPUT) +DLL = $(PROGRAM_OUTPUT)_001.so +LIBS = -framework Carbon +ARCHS = -arch i386 -arch ppc +CFLAGS = -g -s \ + -Wall \ + $(ARCHS) \ + -DMACOSX \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I.. -I../motif -I/System/Library/Frameworks/JavaVM.framework/Headers + +all: $(EXEC) $(DLL) + +eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c ../eclipse.c -o $@ + +eclipseCarbonMain.o : eclipseCarbonMain.c + $(CC) $(CFLAGS) -c eclipseCarbonMain.c -o $@ + +eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h eclipseMain.c ../eclipseMain.c + $(CC) $(CFLAGS) -c eclipseMain.c -o $@ + +eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c ../eclipseJNI.c -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.c -o $@ + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseConfig.c -o $@ + +eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(CC) $(CFLAGS) -c ../eclipseCommon.c -o $@ + +NgCommon.o: ../motif/NgCommon.c + $(CC) $(CFLAGS) -c ../motif/NgCommon.c -o $@ + +NgWinBMPFileFormat.o: ../motif/NgWinBMPFileFormat.c + $(CC) $(CFLAGS) -c ../motif/NgWinBMPFileFormat.c -o $@ + +NgImageData.o: ../motif/NgImageData.c + $(CC) $(CFLAGS) -c ../motif/NgImageData.c -o $@ + +$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) + $(CC) -o $(EXEC) $(ARCHS) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS) + +$(DLL): $(DLL_OBJS) $(COMMON_OBJS) + $(CC) -bundle -o $(DLL) $(ARCHS) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS) + +install: all + cp $(EXEC) $(PPC_OUTPUT_DIR) + cp $(EXEC) $(X86_OUTPUT_DIR) + rm -f $(EXEC) $(OBJS) + +clean: + rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) diff --git a/bundles/org.eclipse.equinox.executable/library/eclipse.c b/bundles/org.eclipse.equinox.executable/library/eclipse.c new file mode 100644 index 000000000..24ec891a3 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipse.c @@ -0,0 +1,890 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Kevin Cornell (Rational Software Corporation) + *******************************************************************************/ + +/* 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 "eclipseJNI.h" +#include "eclipseConfig.h" +#include "eclipseCommon.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 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 */ + +_TCHAR* exitData = NULL; /* exit data set from Java */ +int initialArgc; +_TCHAR** initialArgv; + + +/* Define the special exit codes returned from Eclipse. */ +#define RESTART_LAST_EC 23 +#define RESTART_NEW_EC 24 + +/* 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* shareMsg = _T_ECLIPSE("No exit data available."); +static _TCHAR* noVMMsg = +_T_ECLIPSE("A Java Runtime Environment (JRE) or Java Development Kit (JDK)\n\ +must be available in order to run %s. No Java virtual machine\n\ +was found after searching the following locations:\n\ +%s"); +static _TCHAR* startupMsg = +_T_ECLIPSE("The %s executable launcher was unable to locate its \n\ +companion startup jar file."); + +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_EQUINOX_STARTUP _T_ECLIPSE("org.eclipse.equinox.startup") +#define DEFAULT_STARTUP _T_ECLIPSE("startup.jar") +#define CLASSPATH_PREFIX _T_ECLIPSE("-Djava.class.path=") + +/* Define constants for the options recognized by the launcher. */ +#define CONSOLE _T_ECLIPSE("-console") +#define CONSOLELOG _T_ECLIPSE("-consoleLog") +#define DEBUG _T_ECLIPSE("-debug") +#define OS _T_ECLIPSE("-os") +#define OSARCH _T_ECLIPSE("-arch") +#define NOSPLASH _T_ECLIPSE("-nosplash") +#define LAUNCHER _T_ECLIPSE("-launcher") +#define SHOWSPLASH _T_ECLIPSE("-showsplash") +#define STARTUP _T_ECLIPSE("-startup") +#define VM _T_ECLIPSE("-vm") +#define WS _T_ECLIPSE("-ws") +#define NAME _T_ECLIPSE("-name") +#define VMARGS _T_ECLIPSE("-vmargs") /* special option processing required */ +#define CP _T_ECLIPSE("-cp") +#define CLASSPATH _T_ECLIPSE("-classpath") + +#define JAR _T_ECLIPSE("-jar") + +/* Define 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 * startupArg = NULL; /* path of the startup.jar the user wants to run relative to the program path */ +static _TCHAR* vmName = NULL; /* Java VM that the user wants to run */ +static _TCHAR* wsArg = _T_ECLIPSE(DEFAULT_WS); /* the SWT supported GUI to be used */ +static _TCHAR* name = NULL; /* program name */ + +/* 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 }, + { STARTUP, &startupArg, NULL, 2 }, + { VM, &vmName, NULL, 2 }, + { NAME, &name, NULL, 2 }, + { WS, &wsArg, NULL, 2 } }; +static int optionsSize = (sizeof(options) / sizeof(options[0])); + +/* Define the required VM arguments (all platforms). */ +static _TCHAR* cp = NULL; +static _TCHAR** reqVMarg[] = { &cp, NULL }; /* required VM args */ +static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */ + +/* Local methods */ +static void parseArgs( int* argc, _TCHAR* argv[] ); +static _TCHAR** parseArgList( _TCHAR *data ); +static void freeArgList( _TCHAR** data ); +static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] ); +static _TCHAR* formatVmCommandMsg( _TCHAR* args[] ); + _TCHAR* getProgramDir(); +static _TCHAR* getDefaultOfficialName(); +static _TCHAR* findStartupJar(); +static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand ); + + +/* Record the arguments that were used to start the original executable */ +JNIEXPORT void setInitialArgs(int argc, _TCHAR** argv) { + initialArgc = argc; + initialArgv = argv; +} + +/* this method must match the RunMethod typedef in eclipseMain.c */ +/* vmArgs must be NULL terminated */ +JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[]) +{ + _TCHAR* shippedVM = NULL; + _TCHAR* vmSearchPath = NULL; + _TCHAR** vmCommand = NULL; + _TCHAR** vmCommandList = NULL; + _TCHAR** vmCommandArgs = NULL; + _TCHAR** progCommandArgs = NULL; + _TCHAR* vmCommandMsg = NULL; + _TCHAR** relaunchCommand = NULL; + _TCHAR* errorMsg; + int exitCode; + + /* arg[0] should be the full pathname of this program. */ + program = _tcsdup( argv[0] ); + + /* Parse command line arguments (looking for the VM to use). */ + /* Override configuration file arguments */ + parseArgs( &argc, argv ); + + /* Initialize official program name */ + officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName(); + + /* Initialize the window system. */ + initWindowSystem( &argc, argv, !noSplash ); + + /* 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 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 ); + } + + javaVM = findVMLibrary( javaVM ); + /* 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); + } + + /* Find the startup.jar */ + jarFile = findStartupJar(); + if(jarFile == NULL) { + errorMsg = malloc( (_tcslen(startupMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) ); + _stprintf( errorMsg, startupMsg, officialName ); + displayMessage( officialName, errorMsg ); + free( errorMsg ); + exit( 1 ); + } + + /* If the showsplash option was given */ + if (!noSplash && showSplashArg) + { + showSplash(showSplashArg); + } + + /* the startup jarFile goes on the classpath */ + cp = malloc((_tcslen(CLASSPATH_PREFIX) + _tcslen(jarFile) + 1) * sizeof(_TCHAR)); + cp = _tcscpy(cp, CLASSPATH_PREFIX); + _tcscat(cp, jarFile); + + /* Get the command to start the Java VM. */ + userVMarg = vmArgs; + getVMCommand( argc, argv, &vmCommandArgs, &progCommandArgs ); + + /* While the Java VM should be restarted */ + vmCommand = vmCommandArgs; + vmCommandMsg = formatVmCommandMsg( vmCommand ); + if (debug) _tprintf( goVMMsg, vmCommandMsg ); + exitCode = startJavaVM(javaVM, vmCommandArgs, progCommandArgs ); + switch( exitCode ) { + case 0: /* normal exit */ + break; + case RESTART_LAST_EC: + relaunchCommand = getRelaunchCommand(initialArgv); + break; + case RESTART_NEW_EC: + if (exitData != 0) { + if (vmCommandList != NULL) freeArgList( vmCommandList ); + vmCommandList = parseArgList( exitData ); + relaunchCommand = getRelaunchCommand(vmCommandList); + } else { + if (debug) displayMessage( officialName, shareMsg ); + } + break; + default: { + _TCHAR *title = _tcsdup(officialName); + vmCommand = NULL; + errorMsg = NULL; + if (exitData != 0) { + errorMsg = exitData; + 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; + } + } + + if(relaunchCommand != NULL) + restartLauncher(program, relaunchCommand); + + /* Cleanup time. */ + free( vmCommandMsg ); + free( jarFile ); + free( cp ); + free( programDir ); + free( program ); + if ( vmSearchPath != NULL ) free( vmSearchPath ); + if ( vmCommandList != NULL ) freeArgList( vmCommandList ); + free( officialName ); + + return 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; + } + + /* 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; + } + } +} + +/* + * 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 separated 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; +} + +/* + * Get the command and arguments to start the Java VM. + * + * Memory allocated by this function is assumed to be + * deallocated when the program terminates. + * + * Some of the arguments returned by this function were + * passed directly from the main( argv ) array so they + * should not be deallocated. + * + * Arguments are split into 2: vm arguments and program arguments + */ +static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] ) +{ + _TCHAR** vmArg; + int nReqVMarg = 0; + int nVMarg = 0; + int totalVMArgs; + int totalProgArgs; + int src; + int dst; + + /* If the user specified "-vmargs", add them instead of the default VM args. */ + vmArg = (userVMarg != NULL) ? userVMarg : getArgVM( javaVM ); + + /* Calculate the number of VM arguments. */ + while (vmArg[ nVMarg ] != NULL) + nVMarg++; + + /* Calculate the number of required VM arguments. */ + while (reqVMarg[ nReqVMarg ] != NULL) + nReqVMarg++; + + /* VM argument list */ + totalVMArgs = nVMarg + nReqVMarg + 1; + *vmArgv = malloc( totalVMArgs * sizeof(_TCHAR*) ); + + dst = 0; + for (src = 0; src < nVMarg; src++){ + /*if the user specified a classpath, skip it */ + if(_tcscmp(vmArg[src], cp) == 0){ + src++; + continue; + } + (*vmArgv)[ dst++ ] = vmArg[ src ]; + } + + /* For each required VM arg */ + for (src = 0; src < nReqVMarg; src++) + (*vmArgv)[ dst++ ] = *(reqVMarg[ src ]); + + (*vmArgv)[dst] = NULL; + + /* Program arguments */ + /* OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> + + * + SHOWSPLASH <cmd> + argv[] + VM + <vm> + VMARGS + vmArg + requiredVMargs + * + NULL) + */ + totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nVMarg + nReqVMarg + 1; + *progArgv = malloc( totalProgArgs * sizeof( _TCHAR* ) ); + dst = 0; + + /* Append the required options. */ + (*progArgv)[ dst++ ] = OS; + (*progArgv)[ dst++ ] = osArg; + (*progArgv)[ dst++ ] = WS; + (*progArgv)[ dst++ ] = wsArg; + if (_tcslen(osArchArg) > 0) { + (*progArgv)[ dst++ ] = OSARCH; + (*progArgv)[ dst++ ] = osArchArg; + } + + /* Append the launcher command */ + (*progArgv)[ dst++ ] = LAUNCHER; + (*progArgv)[ dst++ ] = program; + + /* Append the name command */ + (*progArgv)[ dst++ ] = NAME; + (*progArgv)[ dst++ ] = officialName; + + /* Append the show splash window command, if defined. */ + if (!noSplash) + { + (*progArgv)[ dst++ ] = SHOWSPLASH; + } + + /* Append the remaining user defined arguments. */ + for (src = 1; src < argc; src++) + { + (*progArgv)[ dst++ ] = argv[ src ]; + } + + /* Append VM and VMARGS to be able to relaunch using exit data. */ + (*progArgv)[ dst++ ] = VM; + (*progArgv)[ dst++ ] = javaVM; + (*progArgv)[ dst++ ] = VMARGS; + + for (src = 0; src < nVMarg; src++) + (*progArgv)[ dst++ ] = vmArg[ src ]; + + /* For each required VM arg */ + for (src = 0; src < nReqVMarg; src++) + (*progArgv)[ dst++ ] = *(reqVMarg[ src ]); + + (*progArgv)[ dst++ ] = NULL; + + } + + /* Format the JVM start command for error messages + * + * This method formats a string with the JVM start command (and all arguments) + * that can be used in displaying error messages. The string returned from this + * method is probably not NLS compliant and must be deallocated by the caller. + */ +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; +} + +static _TCHAR* findStartupJar(){ + _TCHAR * file; + _TCHAR * pluginsPath; + struct _stat stats; + int pathLength; + + if( startupArg != NULL ) { + /* startup jar was specified on the command line */ + + /* Construct the absolute name of the startup jar */ + file = malloc( (_tcslen( programDir ) + _tcslen( startupArg ) + 1) * sizeof( _TCHAR ) ); + file = _tcscpy( file, programDir ); + file = _tcscat( file, startupArg ); + + /* If the file does not exist, treat the argument as an absolute path */ + if (_tstat( file, &stats ) != 0) + { + free( file ); + file = malloc( (_tcslen( startupArg ) + 1) * sizeof( _TCHAR ) ); + file = _tcscpy( file, startupArg ); + + /* still doesn't exit? */ + if (_tstat( file, &stats ) != 0) { + file = NULL; + } + } + /* TODO What should the policy here be, if we didn't find what they + * specified? (Its harder to specify equinox.startup on the mac.) */ + if(file != NULL) + return file; + } + + pathLength = _tcslen(programDir); +#ifdef MACOSX + pathLength += 9; +#endif + pluginsPath = malloc( (pathLength + 1 + 7) * sizeof(char)); + _tcscpy(pluginsPath, programDir); + if(pluginsPath[pathLength - 1] != dirSeparator) { + pluginsPath[pathLength] = dirSeparator; + pluginsPath[pathLength + 1] = 0; + } +#ifdef MACOSX + _tcscat(pluginsPath, _T_ECLIPSE("../../../")); +#endif + _tcscat(pluginsPath, _T_ECLIPSE("plugins")); + + /* equinox startup jar? */ + file = findFile(pluginsPath, _T_ECLIPSE("org.eclipse.equinox.startup")); + if(file != NULL) + return file; + + file = malloc( (_tcslen( DEFAULT_STARTUP ) + 1) * sizeof( _TCHAR ) ); + file = _tcscpy( file, DEFAULT_STARTUP ); + return file; +} + +/* + * Return the portion of the vmCommand that should be used for relaunching + * + * The memory allocated for the command array must be freed + */ +static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand ) +{ + int i = -1, req = 0, begin = -1; + int idx = 0; + _TCHAR ** relaunch; + + if (vmCommand == NULL) return NULL; + while(vmCommand[++i] != NULL){ + if ( begin == -1 && _tcsicmp( vmCommand[i], *reqVMarg[req] ) == 0) { + if(reqVMarg[++req] == NULL){ + begin = i + 1; + } + } + } + + relaunch = malloc((i + 1) * sizeof(_TCHAR *)); + for (i = begin; vmCommand[i] != NULL; i++){ + if (_tcsicmp(vmCommand[i], SHOWSPLASH) == 0) { + /* remove if the next argument is not the bitmap to show */ + if(vmCommand[i + 1] != NULL && vmCommand[i + 1][0] == _T_ECLIPSE('-')) { + i++; + continue; + } + } else if(_tcsicmp(vmCommand[i], JAR) == 0 ) { + /* skip -jar */ + i++; + continue; + } + relaunch[idx++] = vmCommand[i]; + } + relaunch[idx] = NULL; + return relaunch; +} diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseCommon.c b/bundles/org.eclipse.equinox.executable/library/eclipseCommon.c new file mode 100644 index 000000000..cde658660 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseCommon.c @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseCommon.h" +#include "eclipseUnicode.h" + +#ifdef _WIN32 +#include <direct.h> +#include <windows.h> +#else +#include <unistd.h> +#include <strings.h> +#include <dirent.h> +#endif +#include <stdlib.h> +#include <sys/stat.h> + +/* Global Variables */ +_TCHAR* officialName = NULL; + +/* Local Variables */ +#ifndef _WIN32 +static _TCHAR* filterPrefix = NULL; /* prefix for the find files filter */ +static int prefixLength = 0; +#endif + + +/** + * Convert a wide string to a narrow one + * Caller must free the null terminated string returned. + */ +char *toNarrow(_TCHAR* src) +{ +#ifdef UNICODE + int byteCount = WideCharToMultiByte (CP_ACP, 0, (wchar_t *)src, -1, NULL, 0, NULL, NULL); + char *dest = malloc(byteCount+1); + dest[byteCount] = 0; + WideCharToMultiByte (CP_UTF8, 0, (wchar_t *)src, -1, dest, byteCount, NULL, NULL); + return dest; +#else + return _tcsdup(src); +#endif +} + + + /* + * Find the absolute pathname to where a command resides. + * + * The string returned by the function must be freed. + */ +#define EXTRA 20 +_TCHAR* findCommand( _TCHAR* command ) +{ + _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; + } + +#if !defined(_WIN32) && !defined(MACOSX) + /* resolve symlinks */ + ch = cmdPath; + cmdPath = canonicalize_file_name(cmdPath); + free(ch); +#endif + + /* Return the absolute command pathname. */ + return cmdPath; +} + +#ifndef _WIN32 +#ifdef MACOSX +static int filter(struct dirent *dir) { +#else +static int filter(const struct dirent *dir) { +#endif + if(_tcslen(dir->d_name) <= prefixLength) + return 0; + return (_tcsncmp(dir->d_name, filterPrefix, prefixLength) == 0 && + dir->d_name[prefixLength] == _T_ECLIPSE('_')); +} +#endif + /* + * Looks for files of the form /path/prefix_version.<extension> and returns the full path to + * the file with the largest version number + */ +_TCHAR* findFile( _TCHAR* path, _TCHAR* prefix) +{ + struct _stat stats; + int pathLength; + _TCHAR* candidate = NULL; + _TCHAR* result = NULL; + +#ifdef _WIN32 + _TCHAR* fileName = NULL; + WIN32_FIND_DATA data; + HANDLE handle; +#else + struct dirent **files; + int count; +#endif + + /* does path exist? */ + if( _tstat(path, &stats) != 0 ) + return NULL; + + pathLength = _tcslen(path); + +#ifdef _WIN32 + fileName = malloc( (_tcslen(path) + 1 + _tcslen(prefix) + 3) * sizeof(_TCHAR)); + fileName = _tcscpy(fileName, path); + fileName[pathLength] = dirSeparator; + fileName[pathLength + 1] = 0; + _tcscat(fileName, prefix); + _tcscat(fileName, _T_ECLIPSE("_*")); + prefix = fileName; + + handle = FindFirstFile(prefix, &data); + if(handle != INVALID_HANDLE_VALUE) { + candidate = _tcsdup(data.cFileName); + while(FindNextFile(handle, &data) != 0) { + fileName = data.cFileName; + /* compare, take the highest version */ + if( _tcscmp(candidate, fileName) < 0) { + free(candidate); + candidate = _tcsdup(fileName); + } + } + FindClose(handle); + } +#else + filterPrefix = prefix; + prefixLength = _tcslen(prefix); + /* TODO should write out own comparator to better handle OSGi versions */ + count = scandir(path, &files, &filter, alphasort); + if(count > 0) { + candidate = _tcsdup(files[count - 1]->d_name); + } +#endif + + if(candidate != NULL) { + result = malloc((pathLength + 1 + _tcslen(candidate) + 1) * sizeof(_TCHAR)); + _tcscpy(result, path); + result[pathLength] = dirSeparator; + result[pathLength + 1] = 0; + _tcscat(result, candidate); + free(candidate); + return result; + } + return NULL; +} diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseCommon.h b/bundles/org.eclipse.equinox.executable/library/eclipseCommon.h new file mode 100644 index 000000000..ddae32a4a --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseCommon.h @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#ifndef ECLIPSE_COMMON_H +#define ECLIPSE_COMMON_H + +#include "eclipseUnicode.h" + +/* Variables and Methods that will be needed by both the executable and the library */ + +#define MAX_PATH_LENGTH 2000 + +#ifdef UNICODE +#define pathSeparator pathSeparatorW +#define dirSeparator dirSeparatorW +#define officialName officialNameW +#define parseArgs parseArgsW +#define displayMessage displayMessageW +#define getProgramDir getProgramDirW +#define findCommand findCommandW +#define findFile findFileW +#define loadLibrary loadLibraryW +#define unloadLibrary unloadLibraryW +#define findSymbol findSymbolW +#define run runW +#define setInitialArgs setInitialArgsW +#define toNarrow toNarrowW +#endif + +#ifdef UNICODE +#define RUN_METHOD _T_ECLIPSE("runW") +#define SET_INITIAL_ARGS _T_ECLIPSE("setInitialArgsW") +#else +#define RUN_METHOD _T_ECLIPSE("run") +#define SET_INITIAL_ARGS _T_ECLIPSE("setInitialArgs") +#endif + +extern _TCHAR dirSeparator; /* '/' or '\\' */ +extern _TCHAR pathSeparator; /* separator used in PATH variable */ +extern _TCHAR* officialName; /* Program official name */ + + +extern char *toNarrow(_TCHAR* src); + + /* + * Find the absolute pathname to where a command resides. + * + * The string returned by the function must be freed. + */ +extern _TCHAR* findCommand( _TCHAR* command ); + +extern _TCHAR* findFile( _TCHAR* path, _TCHAR* prefix); + +extern _TCHAR* getProgramDir(); + +/** Display a Message + * + * This method is called to display an error message to the user before exiting. + * The method should not return until the user has acknowledged + * the message. This method may be called before the window + * system has been initialized. The program should exit after calling this method. + */ +extern void displayMessage( _TCHAR* title, _TCHAR* message ); + +/* Load the specified shared library + */ +extern void * loadLibrary( _TCHAR * library ); + +/* Unload the shared library + */ +extern void unloadLibrary( void * handle ); + +/* Find the given symbol in the shared library + */ +extern void * findSymbol( void * handle, _TCHAR * symbol ); + +#endif diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseConfig.c b/bundles/org.eclipse.equinox.executable/library/eclipseConfig.c new file mode 100644 index 000000000..a7b3a3dd2 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/eclipseConfig.h b/bundles/org.eclipse.equinox.executable/library/eclipseConfig.h new file mode 100644 index 000000000..10189ba81 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/eclipseJNI.c b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.c new file mode 100644 index 000000000..9f7e55fe9 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.c @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseJNI.h" +#include "eclipseCommon.h" +#include "eclipseOS.h" + +#include <stdlib.h> +#include <string.h> + +static JNINativeMethod natives[] = {{"_update_splash", "()V", &update_splash}, + {"_get_splash_handle", "()J", &get_splash_handle}, + {"_set_exit_data", "(Ljava/lang/String;)V", &set_exit_data}, + {"_show_splash", "(Ljava/lang/String;)V", &show_splash}, + {"_takedown_splash", "()V", &takedown_splash}}; + +/* local methods */ +static jstring newJavaString(JNIEnv *env, _TCHAR * str); +static void setExitData(JNIEnv *env, jstring s); +static void splash(JNIEnv *env, jstring s); +static void registerNatives(JNIEnv *env); + +/* JNI Methods + * we only want one version of the JNI functions + * Because there are potentially ANSI and UNICODE versions of everything, we need to be + * able to call out to either, so we will set hooks depending on which version of + * registerNatives gets called. + */ +#ifndef UNICODE +void (* exitDataHook)(JNIEnv *env, jstring s); +void (* dispatchHook)(); +long (* splashHandleHook)(); +void (* showSplashHook)(JNIEnv *env, jstring s); +void (* takeDownHook)(); +#else +extern void (* exitDataHook)(JNIEnv *env, jstring s); +extern void (* dispatchHook)(); +extern long (* splashHandleHook)(); +extern void (* showSplashHook)(JNIEnv *env, jstring s); +extern void (* takeDownHook)(); +#endif + +#ifndef UNICODE +/* JNI Callback methods */ +JNIEXPORT void JNICALL set_exit_data(JNIEnv * env, jobject obj, jstring s){ + if(exitDataHook != NULL) + exitDataHook(env, s); + else /* hook was not set, just call the ANSI version */ + setExitData(env, s); +} + +JNIEXPORT void JNICALL update_splash(JNIEnv * env, jobject obj){ + if(dispatchHook != NULL) + dispatchHook(); + else + dispatchMessages(); +} + +JNIEXPORT jlong JNICALL get_splash_handle(JNIEnv * env, jobject obj){ + if(splashHandleHook != NULL) + return splashHandleHook(); + else + return getSplashHandle(); +} + +JNIEXPORT void JNICALL show_splash(JNIEnv * env, jobject obj, jstring s){ + if(showSplashHook != NULL) + showSplashHook(env, s); + else + splash(env, s); +} + +JNIEXPORT void JNICALL takedown_splash(JNIEnv * env, jobject obj){ + if(takeDownHook != NULL) + takeDownHook(); + else + takeDownSplash(); +} +#endif + +static void registerNatives(JNIEnv *env) { + jclass bridge = (*env)->FindClass(env, "org/eclipse/core/launcher/JNIBridge"); + if(bridge != NULL) { + int numNatives = sizeof(natives) / sizeof(natives[0]); + (*env)->RegisterNatives(env, bridge, natives, numNatives); + + if( (*env)->ExceptionOccurred(env) != 0 ){ + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + } + } + /*set hooks*/ + splashHandleHook = &getSplashHandle; + exitDataHook = &setExitData; + dispatchHook = &dispatchMessages; + showSplashHook = &splash; + takeDownHook = &takeDownSplash; +} + +static void splash(JNIEnv *env, jstring s) { + const _TCHAR* data; + data = JNI_GetStringChars(env, s); + showSplash(data); + JNI_ReleaseStringChars(env, s, data); +} + +static void setExitData(JNIEnv *env, jstring s){ + const _TCHAR* data; + int length; + + length = (*env)->GetStringLength(env, s); + data = JNI_GetStringChars(env, s); + + exitData = malloc((length + 1) * sizeof(_TCHAR*)); + _tcsncpy( exitData, data, length); + exitData[length] = 0; + JNI_ReleaseStringChars(env, s, data); +} + +static jstring newJavaString(JNIEnv *env, _TCHAR * str) +{ + jstring newString = 0; + int length = _tcslen(str); + +#ifdef UNICODE + newString = (*env)->NewString(env, str, length); +#else + jbyteArray bytes = (*env)->NewByteArray(env, length); + (*env)->SetByteArrayRegion(env, bytes, 0, length, str); + if (!(*env)->ExceptionOccurred(env)) { + jclass stringClass = (*env)->FindClass(env, "java/lang/String"); + jmethodID ctor = (*env)->GetMethodID(env, stringClass, "<init>", "([B)V"); + newString = (*env)->NewObject(env, stringClass, ctor, bytes); + } + (*env)->DeleteLocalRef(env, bytes); +#endif + + return newString; +} + +static jobjectArray createRunArgs( JNIEnv *env, _TCHAR * args[] ) { + int index = 0, length = -1; + jclass stringClass; + jobjectArray stringArray; + jstring string; + + /*count the number of elements first*/ + while(args[++length] != NULL); + + stringClass = (*env)->FindClass(env, "java/lang/String"); + stringArray = (*env)->NewObjectArray(env, length, stringClass, 0); + for( index = 0; index < length; index++) { + string = newJavaString(env, args[index]); + (*env)->SetObjectArrayElement(env, stringArray, index, string); + (*env)->DeleteLocalRef(env, string); + } + return stringArray; +} + +int startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[] ) +{ + int i; + int numVMArgs = -1; + int jvmExitCode = 0; + void * jniLibrary; + JNI_createJavaVM createJavaVM; + JavaVMInitArgs init_args; + JavaVMOption * options; + JavaVM * jvm; + JNIEnv *env; + + /* JNI reflection */ + jclass mainClass = NULL; /* The Main class to load */ + jmethodID mainConstructor = NULL; /* Main's default constructor Main() */ + jobject mainObject = NULL; /* An instantiation of the main class */ + jmethodID runMethod = NULL; /* Main.run(String[]) */ + jobjectArray methodArgs = NULL; /* Arguments to pass to run */ + + jniLibrary = loadLibrary(libPath); + if(jniLibrary == NULL) { + return -1; /*error*/ + } + + createJavaVM = findSymbol(jniLibrary, _T_ECLIPSE("JNI_CreateJavaVM")); + if(createJavaVM == NULL) { + return -1; /*error*/ + } + + /* count the vm args */ + while(vmArgs[++numVMArgs] != NULL) {} + + if(numVMArgs <= 0) { + /*error, we expect at least the required vm arg */ + return -1; + } + + options = malloc(numVMArgs * sizeof(JavaVMOption)); + for(i = 0; i < numVMArgs; i++){ + options[i].optionString = toNarrow(vmArgs[i]); + options[i].extraInfo = 0; + } + + init_args.version = JNI_VERSION_1_2; + init_args.options = options; + init_args.nOptions = numVMArgs; + init_args.ignoreUnrecognized = JNI_TRUE; + + if( createJavaVM(&jvm, &env, &init_args) == 0 ) { + registerNatives(env); + + mainClass = (*env)->FindClass(env, "org/eclipse/core/launcher/Main"); + if(mainClass != NULL) { + mainConstructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V"); + mainObject = (*env)->NewObject(env, mainClass, mainConstructor); + runMethod = (*env)->GetMethodID(env, mainClass, "run", "([Ljava/lang/String;)I"); + if(runMethod != NULL) { + methodArgs = createRunArgs(env, progArgs); + jvmExitCode = (*env)->CallIntMethod(env, mainObject, runMethod, methodArgs); + } + } else { + if((*env)->ExceptionOccurred(env)){ + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + } + } + /*(*jvm)->DestroyJavaVM(jvm);*/ + } + unloadLibrary(jniLibrary); + free(progArgs); + + /* toNarrow allocated new strings, free them */ + for(i = 0; i < numVMArgs; i++){ + free( options[i].optionString ); + } + free(options); + return jvmExitCode; +} + + + diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h new file mode 100644 index 000000000..e961f47f1 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +#ifndef ECLIPSE_JNI_H +#define ECLIPSE_JNI_H + +#include "eclipseUnicode.h" +#include <jni.h> + +#ifdef UNICODE +#define loadVMLibrary loadVMLibraryW +#define unloadVMLibrary unloadVMLibraryW +#define getInvocationFunction getInvocationFunctionW +#define launchJavaVM launchJavaVMW +#define startJavaVM startJavaVMW +#endif + +#ifdef UNICODE +#define JNI_GetStringChars(env, s) (*env)->GetStringChars(env, s, 0) +#define JNI_ReleaseStringChars(env, s, data) (*env)->ReleaseStringChars(env, s, data) +#else +#define JNI_GetStringChars(env, s) (*env)->GetStringUTFChars(env, s, 0) +#define JNI_ReleaseStringChars(env, s, data) (*env)->ReleaseStringUTFChars(env, s, data) +#endif + +typedef jint (JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args); + +/* JNI Callback methods */ +/* Use name mangling since we may be linking these from java with System.LoadLibrary */ +#define set_exit_data Java_org_eclipse_core_launcher_JNIBridge__1set_1exit_1data +#define update_splash Java_org_eclipse_core_launcher_JNIBridge__1update_1splash +#define show_splash Java_org_eclipse_core_launcher_JNIBridge__1show_1splash +#define get_splash_handle Java_org_eclipse_core_launcher_JNIBridge__1get_1splash_1handle +#define takedown_splash Java_org_eclipse_core_launcher_JNIBridge__1takedown_1splash + +#ifdef __cplusplus +extern "C" { +#endif +/* + * org_eclipse_core_launcher_JNIBridge#_set_exit_data + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL set_exit_data(JNIEnv *, jobject, jstring); + +/* + * org_eclipse_core_launcher_JNIBridge#_update_splash + * Signature: ()V + */ +JNIEXPORT void JNICALL update_splash(JNIEnv *, jobject); + +/* + * org_eclipse_core_launcher_JNIBridge#_get_splash_handle + * Signature: ()J + */ +JNIEXPORT jlong JNICALL get_splash_handle(JNIEnv *, jobject); + +/* + * org_eclipse_core_launcher_JNIBridge#_show_splash + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL show_splash(JNIEnv *, jobject, jstring); + +/* + * org_eclipse_core_launcher_JNIBridge#_takedown_splash + * Signature: ()V + */ +JNIEXPORT void JNICALL takedown_splash(JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif + +/* Start the Java VM and Wait For It to Terminate + * + * This method is responsible for starting the Java VM and for + * detecting its termination. The resulting JVM exit code should + * be returned to the main launcher, which will display a message if + * the termination was not normal. + */ +extern int startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[] ); +#endif diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseMain.c b/bundles/org.eclipse.equinox.executable/library/eclipseMain.c new file mode 100644 index 000000000..f1c42b690 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseMain.c @@ -0,0 +1,348 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseUnicode.h" +#include "eclipseCommon.h" +#include "eclipseConfig.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <locale.h> +#include <sys/stat.h> + +static _TCHAR* libraryMsg = +_T_ECLIPSE("The %s executable launcher was unable to locate its \n\ +companion shared library."); + +#define NAME _T_ECLIPSE("-name") +#define LIBRARY _T_ECLIPSE("-library") +#define VMARGS _T_ECLIPSE("-vmargs") /* special option processing required */ + +/* this typedef must match the run method in eclipse.c */ +typedef int (*RunMethod)(int argc, _TCHAR* argv[], _TCHAR* vmArgs[]); +typedef void (*SetInitialArgs)(int argc, _TCHAR*argv[]); + +static _TCHAR* name = NULL; /* program name */ +static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */ +static _TCHAR* programDir = NULL; /* directory where program resides */ +static _TCHAR* library = NULL; /* pathname of the eclipse shared library */ + +static int createUserArgs(int configArgc, _TCHAR **configArgv, int *argc, _TCHAR ***argv); +static void parseArgs( int* argc, _TCHAR* argv[] ); +static _TCHAR* getDefaultOfficialName(_TCHAR* program); +static _TCHAR* findLibrary(_TCHAR* program); + +static int initialArgc; +static _TCHAR** initialArgv; + +#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* errorMsg; + _TCHAR* program; + _TCHAR* ch; + _TCHAR** configArgv = NULL; + int configArgc = 0; + int exitCode = 0; + void * handle = 0; + RunMethod runMethod; + SetInitialArgs setArgs; + + setlocale(LC_ALL, ""); + + initialArgc = argc; + initialArgv = malloc((argc + 1) * sizeof(_TCHAR*)); + memcpy(initialArgv, argv, (argc + 1) * sizeof(_TCHAR*)); + + /* + * Strip off any extroneous <CR> from the last argument. If a shell script + * on Linux is created in DOS format (lines end with <CR><LF>), the C-shell + * does not strip off the <CR> and hence the argument is bogus and may + * not be recognized by the launcher or eclipse itself. + */ + ch = _tcschr( argv[ argc - 1 ], _T_ECLIPSE('\r') ); + if (ch != NULL) + { + *ch = _T_ECLIPSE('\0'); + } + + /* Determine the full pathname of this program. */ + program = 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 (readConfigFile(program, argv[0], &configArgc, &configArgv) == 0) + { + parseArgs (&configArgc, configArgv); + } + + /* Parse command line arguments */ + /* Overrides configuration file arguments */ + parseArgs( &argc, argv ); + + /* Special case - user arguments specified in the config file + * are appended to the user arguments passed from the command line. + */ + if (configArgc > 1) + { + createUserArgs(configArgc, configArgv, &argc, &argv); + } + + /* Initialize official program name */ + officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName(program); + + /* Find the directory where the Eclipse program is installed. */ + programDir = getProgramDir(program); + + /* Find the eclipse library */ + if(library == NULL) { + library = findLibrary(program); + } + if(library != NULL) + handle = loadLibrary(library); + if(handle == NULL) { + errorMsg = malloc( (_tcslen(libraryMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) ); + _stprintf( errorMsg, libraryMsg, officialName ); + displayMessage( officialName, errorMsg ); + free( errorMsg ); + exit( 1 ); + } + + setArgs = findSymbol(handle, SET_INITIAL_ARGS); + if(setArgs != NULL) + setArgs(initialArgc, initialArgv); + + runMethod = findSymbol(handle, RUN_METHOD); + exitCode = runMethod(argc, argv, userVMarg); + unloadLibrary(handle); + + free( library ); + free( programDir ); + free( officialName ); + + return exitCode; +} + +/* + * Parse arguments of the command. + */ +static void parseArgs( int* pArgc, _TCHAR* argv[] ) +{ + int index; + + /* Ensure the list of user argument is NULL terminated. */ + argv[ *pArgc ] = NULL; + + /* For each user defined argument (excluding the program) */ + for (index = 1; index < *pArgc; index++){ + if(_tcsicmp(argv[index], VMARGS) == 0) { + userVMarg = &argv[ index+1 ]; + argv[ index ] = NULL; + *pArgc = index; + } else if(_tcsicmp(argv[index], NAME) == 0) { + name = argv[++index]; + } else if(_tcsicmp(argv[index], LIBRARY) == 0) { + library = argv[++index]; + } + } +} + +/* + * 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; +} + +/* Determine the Program Directory + * + * This function takes the directory where program executable resides and + * determines the installation directory. + */ +_TCHAR* getProgramDir(_TCHAR* program) +{ + _TCHAR* ch; + + if(programDir != NULL) + return 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; + } + + /* Can't figure out from the program */ + free(programDir); + programDir = NULL; + return NULL; +} + +/* + * Determine the default official application name + * + * This function provides the default application name that appears in a variety of + * places such as: title of message dialog, title of splash screen window + * that shows up in Windows task bar. + * It is computed from the name of the launcher executable and + * by capitalizing the first letter. e.g. "c:/ide/eclipse.exe" provides + * a default name of "Eclipse". + */ +static _TCHAR* getDefaultOfficialName(_TCHAR* program) +{ + _TCHAR *ch = NULL; + + /* Skip the directory part */ + ch = _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; +} + +static _TCHAR* findLibrary(_TCHAR* program) +{ + _TCHAR* c; + _TCHAR* libraryPrefix; + _TCHAR* path; + _TCHAR* result; + int length; + + /* find the last segment */ + c = _tcsrchr(program, dirSeparator); + if(c == NULL) + libraryPrefix = _tcsdup(program); + else + libraryPrefix = _tcsdup(++c); /* next character is start of prefix */ + +#ifdef _WIN32 + { + /* Search for the extension .exe and remove it */ + _TCHAR *extension = _tcsrchr(libraryPrefix, _T_ECLIPSE('.')); + if (extension == NULL || _tcslen(extension) < 4) + { + free(libraryPrefix); + return NULL; + } + extension[0] = 0; + } +#endif + + length = _tcslen(programDir); + if(programDir[length - 1] == dirSeparator){ + path = _tcsdup(programDir); + path[length - 1] = 0; + } else { + path = programDir; + } + result = findFile(path, libraryPrefix); + + free(libraryPrefix); + if(path != programDir) + free(path); + + return result; +} diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseMozilla.c b/bundles/org.eclipse.equinox.executable/library/eclipseMozilla.c new file mode 100644 index 000000000..4d270eb24 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/eclipseMozilla.h b/bundles/org.eclipse.equinox.executable/library/eclipseMozilla.h new file mode 100644 index 000000000..42b4f00a0 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/eclipseOS.h b/bundles/org.eclipse.equinox.executable/library/eclipseOS.h new file mode 100644 index 000000000..61d57df62 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseOS.h @@ -0,0 +1,112 @@ +/******************************************************************************* + * 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 initWindowSystem initWindowSystemW +#define showSplash showSplashW +#define getArgVM getArgVMW +#define findCommand findCommandW +#define exitData exitDataW +#define vmLibrary vmLibraryW +#define findVMLibrary findVMLibraryW +#define dispatchMessages dispatchMessagesW +#define getSplashHandle getSplashHandleW +#define takeDownSplash takeDownSplashW +#define restartLauncher restartLauncherW +#endif + +/* Operating System Dependent Information */ + +/*** See eclipse.c for information on the launcher runtime architecture ***/ + +/* Global Variables */ +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* exitData; /* exit data set from Java */ +extern _TCHAR* vmLibrary; /* name of the VM shared library */ +extern int initialArgc; /* argc originally used to start launcher */ +extern _TCHAR** initialArgv; /* argv originally used to start launcher */ + +/* 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( const _TCHAR* featureImage ); + +/** Get List of Java VM Arguments + * + * A given Java VM might require a special set of arguments in order to + * optimize its performance. This method returns a NULL terminated array + * of strings, where each string is a separate VM argument. + */ +extern _TCHAR** getArgVM( _TCHAR *vm ); + +/* Find the vm shared library associated with the given java executable */ +extern _TCHAR * findVMLibrary( _TCHAR * command ); + +extern void dispatchMessages(); + +extern long getSplashHandle(); + +extern void takeDownSplash(); + +extern void restartLauncher( _TCHAR* program, _TCHAR* args[] ); + +#endif /* ECLIPSE_OS_H */ + diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseUnicode.h b/bundles/org.eclipse.equinox.executable/library/eclipseUnicode.h new file mode 100644 index 000000000..6f2013772 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseUnicode.h @@ -0,0 +1,109 @@ +/******************************************************************************* + * 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 */ +# ifndef _topendir +# define _topendir _wopendir +# endif /* _topendir */ +# ifndef _treaddir +# define _treaddir _wreaddir +# endif /* _treaddir */ +# ifndef _tclosedir +# define _tclosedir _wclosedir +# endif /* _tclosedir */ +# ifndef _tDIR +# define _tDIR _WDIR +# endif /* _tDIR */ +# else /* UNICODE */ +# ifndef _TCHAR +# define _TCHAR char +# endif /* _TCHAR */ +# ifndef _tgetcwd +# define _tgetcwd getcwd +# endif /* _tgetcwd */ +# ifndef _tstat +# define _tstat _stat +# endif /* _tstat */ +# ifndef _topendir +#error message! +# define _topendir opendir +# endif /* _topendir */ +# ifndef _treaddir +# define _treaddir readdir +# endif /* _treaddir */ +# ifndef _tclosedir +# define _tclosedir closedir +# endif /* _tclosedir */ +# ifndef _tDIR +# define _tDIR DIR +# endif /* _tDIR */ +# endif /* UNICODE */ +#endif /* __MINGW32__ */ + +#define _T_ECLIPSE _T + +#else /* Platforms other than Windows */ + +#define _TCHAR char +#define _T_ECLIPSE(s) s +#define _fgetts fgets +#define _stat stat +#define _stprintf sprintf +#define _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 +#define _topendir opendir +#define _treaddir readdir +#define _tclosedir closedir +#define _tDIR DIR +#endif /* _WIN32 */ + +#endif /* ECLIPSE_UNICODE_H */ diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c new file mode 100644 index 000000000..ac5b4ca66 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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 "eclipseCommon.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.executable/library/eclipseUtil.h b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h new file mode 100644 index 000000000..484b9d5aa --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/gtk/.cvsignore b/bundles/org.eclipse.equinox.executable/library/gtk/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/gtk/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.executable/library/gtk/build.sh b/bundles/org.eclipse.equinox.executable/library/gtk/build.sh new file mode 100644 index 000000000..aca00675e --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/gtk/build.xml b/bundles/org.eclipse.equinox.executable/library/gtk/build.xml new file mode 100644 index 000000000..65a05c0ee --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/gtk/eclipseGtk.c b/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c new file mode 100644 index 000000000..79c18fbf9 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c @@ -0,0 +1,280 @@ +/******************************************************************************* + * 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 "eclipseCommon.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> +#include <dlfcn.h> +#ifdef SOLARIS +#include <sys/filio.h> +#endif +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> + +#include <gtk/gtk.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +/* Global Variables */ +char* consoleVM = "java"; +char* defaultVM = "java"; +char* vmLibrary = "libjvm.so"; +char* shippedVMDir = "jre/bin/"; + +/* Define the special arguments for the various Java VMs. */ +static char* argVM_JAVA[] = { NULL }; +static char* argVM_J9[] = { "-jit", "-mca:1024", "-mco:1024", "-mn:256", "-mo:4096", + "-moi:16384", "-mx:262144", "-ms:16", "-mr:16", NULL }; + +/* TODO need a better way of doing this*/ +#ifdef i386 +#define JAVA_ARCH "i386" +#elif defined(__ppc__) +#define JAVA_ARCH "ppc" +#endif + +#define MAX_LOCATION_LENGTH 20 /* none of the jvmLocations strings should be longer than this */ +static const char* jvmLocations [] = { "j9vm", + "classic", + "../lib/" JAVA_ARCH "/client", + "../lib/" JAVA_ARCH "/server", + NULL }; + +/* Define local variables . */ +static int saveArgc = 0; +static char** saveArgv = 0; +static long splashHandle = 0; + +/* Local functions */ +static void adjustLibraryPath( char * vmLibrary ); +static char * findLib(char * command); + +/* Create and Display the Splash Window */ +int showSplash( const char* featureImage ) +{ + GtkAdjustment* vadj, *hadj; + int width, height; + GdkPixbuf * pixbuf; + GtkWidget * image; + GtkWidget * shellHandle, * vboxHandle, * scrolledHandle, * handle; + + initWindowSystem(&initialArgc, initialArgv, 1); + + shellHandle = gtk_window_new(GTK_WINDOW_POPUP); + vboxHandle = gtk_vbox_new(FALSE, 0); + if(vboxHandle == 0) + return -1; + + vadj = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10)); + hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10)); + if (vadj == 0 || hadj == 0) + return -1; + + scrolledHandle = gtk_scrolled_window_new(hadj, vadj); + + gtk_container_add(GTK_CONTAINER(vboxHandle), scrolledHandle); + gtk_box_set_child_packing(GTK_BOX(vboxHandle), scrolledHandle, TRUE, TRUE, 0, GTK_PACK_END); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledHandle), GTK_POLICY_NEVER, GTK_POLICY_NEVER); + gtk_widget_show(scrolledHandle); + + handle = gtk_fixed_new(); + gtk_fixed_set_has_window(GTK_FIXED(handle), TRUE); + GTK_WIDGET_SET_FLAGS(handle, GTK_CAN_FOCUS); + + /* TODO Avoid Warnings */ + gtk_container_add(GTK_CONTAINER(scrolledHandle), handle); + gtk_widget_show(handle); + + gtk_container_add(GTK_CONTAINER(shellHandle), vboxHandle); + + pixbuf = gdk_pixbuf_new_from_file(featureImage, NULL); + image = gtk_image_new_from_pixbuf(pixbuf); + gtk_container_add(GTK_CONTAINER(handle), image); + gtk_widget_show(image); + + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + gtk_window_resize(GTK_WINDOW(shellHandle), width, height); + gtk_window_set_position(GTK_WINDOW(shellHandle), GTK_WIN_POS_CENTER); + gtk_widget_show(shellHandle); + gtk_widget_show_all(GTK_WIDGET(shellHandle)); + splashHandle = (long)G_OBJECT(shellHandle); + dispatchMessages(); + return 0; +} + +void dispatchMessages() { + while(g_main_context_iteration(0,0) != 0) {} +} + +long getSplashHandle() { + return splashHandle; +} + +void takeDownSplash() { + if(splashHandle != 0) { + gtk_widget_destroy((GtkWidget*)splashHandle); + dispatchMessages(); + splashHandle = 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; +} + +char * findVMLibrary( char* command ) { + char * lib = findLib(command); + if( lib != NULL ) { + adjustLibraryPath(lib); + } + return lib; +} +static char * findLib(char * command) { + int i; + int pathLength; + struct stat stats; + char * path; /* path to resulting jvm shared library */ + char * location; /* points to begining of jvmLocations section of path */ + + if (command != NULL) { + location = strrchr( command, dirSeparator ) + 1; + + /*check first to see if command already points to the library */ + if (strcmp(location, vmLibrary) == 0) { + return command; + } + + pathLength = location - command; + path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + strlen(vmLibrary) + 1) * sizeof(char)); + strncpy(path, command, pathLength); + location = &path[pathLength]; + + /* + * We are trying base/jvmLocations[*]/vmLibrary + * where base is the directory containing the given java command, normally jre/bin + */ + i = -1; + while(jvmLocations[++i] != NULL) { + int length = strlen(jvmLocations[i]); + strcpy(location, jvmLocations[i]); + location[length] = dirSeparator; + location[length + 1] = 0; + strcat(location, vmLibrary); + if (stat( path, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0) + { /* found it */ + return path; + } + } + } + return NULL; +} + +/* adjust the LD_LIBRARY_PATH for the vmLibrary */ +static void adjustLibraryPath( char * vmLibrary ) { + char * buffer; + char * path; + char * c; + char * vmPath; + char * vmParent; + char * ldPath; + char * newPath; + int vmPathFound = 0; + int vmParentFound = 0; + int ldPathLength = 0; + +#ifdef MOZILLA_FIX + fixEnvForMozilla(); +#endif /* MOZILLA_FIX */ + + /* we want the directory containing the library, and the parent directory of that */ + buffer = strdup(vmLibrary); + c = strrchr(buffer, dirSeparator); + *c = 0; + vmPath = strdup(buffer); + + c = strrchr(buffer, dirSeparator); + *c = 0; + vmParent = strdup(buffer); + free(buffer); + + ldPath = (char*)getenv("LD_LIBRARY_PATH"); + if(!ldPath) + ldPath = ""; + buffer = malloc((strlen(ldPath) + 2) * sizeof(char)); + strcpy(buffer, ldPath); + strcat(buffer, ":"); + path = buffer; + while( (c = strchr(path, pathSeparator)) != NULL ) { + *c++ = 0; + if( !vmPathFound && strcmp(path, vmPath) == 0 ) { + vmPathFound = 1; + } else if( !vmParentFound && strcmp(path, vmParent) == 0 ) { + vmParentFound = 1; + } + if(vmPathFound && vmParentFound) + break; + path = c; + } + free(buffer); + + if( vmPathFound && vmParentFound ){ + /*found both on the LD_LIBRARY_PATH, don't need to set it */ + return; + } + + /* set the value for LD_LIBRARY_PATH */ + ldPathLength = strlen(ldPath); + /* ldPath + separator + vmPath + separator + vmParent + NULL */ + newPath = malloc((ldPathLength + 1 + strlen(vmPath) + 1 + strlen(vmParent) + 1) * sizeof(char)); + strcpy(newPath, vmPath); + strncat(newPath, &pathSeparator, 1); + strcat(newPath, vmParent); + strncat(newPath, &pathSeparator, 1); + strcat(newPath, ldPath); + setenv( "LD_LIBRARY_PATH", newPath, 1); + + free(vmPath); + free(vmParent); + + /* now we must restart for this to take affect */ + /* TODO what args do we restart with? */ + execv(initialArgv[0], initialArgv); +} + +void restartLauncher( char* program, char* args[] ) +{ + /* just restart in-place */ + execv(program, args); +} + diff --git a/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtkCommon.c b/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtkCommon.c new file mode 100644 index 000000000..04ce569ab --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtkCommon.c @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseCommon.h" +#include "eclipseOS.h" + +#include <locale.h> +#include <dlfcn.h> +#include <gtk/gtk.h> + +#define ECLIPSE_ICON 401 + +char dirSeparator = '/'; +char pathSeparator = ':'; + +void initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash ); + +/* Global Main Window*/ +/*#ifdef UNICODE +extern HWND topWindow; +#else +HWND topWindow = 0; +#endif*/ + +/* Define local variables for the main window. */ +static int saveArgc = 0; /* arguments after they were parsed, for window system */ +static char** saveArgv = 0; + +gboolean gtkInitialized = FALSE; + +/* 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) +{ + if(gtkInitialized) + return; + /* Save the arguments in case displayMessage() is called in the main launcher. */ + if (saveArgv == 0) + { + saveArgc = *pArgc; + saveArgv = argv; + } + + /* Initialize GTK. */ + gtk_set_locale(); + gtk_init_check(pArgc, &argv); + gdk_set_program_class(officialName); + gtkInitialized = TRUE; +} + +/* Load the specified shared library + */ +void * loadLibrary( char * library ){ + void * result= dlopen(library, RTLD_LAZY); + if(result == 0) + printf("%s\n",dlerror()); + return result; +} + +/* Unload the shared library + */ +void unloadLibrary( void * handle ){ + dlclose(handle); +} + +/* Find the given symbol in the shared library + */ +void * findSymbol( void * handle, char * symbol ){ + return dlsym(handle, symbol); +} + diff --git a/bundles/org.eclipse.equinox.executable/library/gtk/make_linux.mak b/bundles/org.eclipse.equinox.executable/library/gtk/make_linux.mak new file mode 100644 index 000000000..f5ba7ce8b --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/gtk/make_linux.mak @@ -0,0 +1,92 @@ +#******************************************************************************* +# 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 +# JAVA_JNI +#default value for PROGRAM_OUTPUT +ifeq ($(PROGRAM_OUTPUT),) + PROGRAM_OUTPUT=eclipse +endif +ifeq ($(PROGRAM_LIBRARY),) + PROGRAM_LIBRARY=$(PROGRAM_OUTPUT)_001.so +endif + +# Define the object modules to be compiled and flags. +CC=gcc +MAIN_OBJS = eclipseMain.o +COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseGtkCommon.o +DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o eclipseMozilla.o + +EXEC = $(PROGRAM_OUTPUT) +DLL = $(PROGRAM_LIBRARY) +LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lpthread +LFLAGS = -shared -fpic -Wl,--export-dynamic +CFLAGS = -g \ + -fpic \ + -DLINUX \ + -DMOZILLA_FIX \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I. \ + -I.. \ + -I$(JAVA_JNI) \ + `pkg-config --cflags gtk+-2.0` + +all: $(EXEC) $(DLL) + +eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o + +eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c + $(CC) $(CFLAGS) -c ../eclipseMain.c -o eclipseMain.o + +eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(CC) $(CFLAGS) -c ../eclipseCommon.c + +eclipseGtkCommon.o: ../eclipseCommon.h ../eclipseOS.h eclipseGtkCommon.c + $(CC) $(CFLAGS) -c eclipseGtkCommon.c -o eclipseGtkCommon.o + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o + +eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c ../eclipseJNI.c -o eclipseJNI.o + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseConfig.c -o eclipseConfig.o + +eclipseMozilla.o: ../eclipseMozilla.c ../eclipseMozilla.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseMozilla.c -o eclipseMozilla.o + +$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) + $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS) + +$(DLL): $(DLL_OBJS) $(COMMON_OBJS) + $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS) + +install: all + cp $(EXEC) $(DLL) $(OUTPUT_DIR) + rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) + +clean: + rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) diff --git a/bundles/org.eclipse.equinox.executable/library/gtk/make_solaris.mak b/bundles/org.eclipse.equinox.executable/library/gtk/make_solaris.mak new file mode 100644 index 000000000..9937e6903 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/gtk/make_solaris.mak @@ -0,0 +1,79 @@ +#******************************************************************************* +# 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 +# JAVA_JNI - the directory containing the Java JNI headers +# Define the object modules to be compiled and flags. +MAIN_OBJS = eclipseMain.o +COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseGtkCommon.o +DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o + +EXEC = $(PROGRAM_OUTPUT) +DLL = $(PROGRAM_LIBRARY) +LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lglib-2.0 -lpthread +LFLAGS = -shared -Wl--export-dynamic +CFLAGS = -O -s \ + -DSOLARIS \ + -K PIC \ + -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + -I. \ + -I.. \ + -I$(JAVA_JNI) \ + `pkg-config --cflags gtk+-2.0` + +all: $(EXEC) + +eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c ../eclipse.c -o eclipse.o + +eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c + $(CC) $(CFLAGS) -c ../eclipseMain.c -o eclipseMain.o + +eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(CC) $(CFLAGS) -c ../eclipseCommon.c + +eclipseGtkCommon.o: ../eclipseCommon.h ../eclipseOS.h eclipseGtkCommon.c + $(CC) $(CFLAGS) -c eclipseGtkCommon.c -o eclipseGtkCommon.o + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseUtil.c -o eclipseUtil.o + +eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c ../eclipseJNI.c -o eclipseJNI.o + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -c ../eclipseConfig.c -o eclipseConfig.o + +$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) + $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS) + +$(DLL): $(DLL_OBJS) $(COMMON_OBJS) + $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS) + +install: all + cp $(EXEC) $(DLL) $(OUTPUT_DIR) + rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) + +clean: + rm -f $(EXEC) $(DLL) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) diff --git a/bundles/org.eclipse.equinox.executable/library/motif/.cvsignore b/bundles/org.eclipse.equinox.executable/library/motif/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/motif/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.executable/library/motif/NgCommon.c b/bundles/org.eclipse.equinox.executable/library/motif/NgCommon.c new file mode 100644 index 000000000..89ecdf47b --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgCommon.h b/bundles/org.eclipse.equinox.executable/library/motif/NgCommon.h new file mode 100644 index 000000000..a4c2589f4 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgImage.c b/bundles/org.eclipse.equinox.executable/library/motif/NgImage.c new file mode 100644 index 000000000..04ffbe701 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgImage.h b/bundles/org.eclipse.equinox.executable/library/motif/NgImage.h new file mode 100644 index 000000000..9f1b1320a --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgImageData.c b/bundles/org.eclipse.equinox.executable/library/motif/NgImageData.c new file mode 100644 index 000000000..d19f1dc22 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgImageData.h b/bundles/org.eclipse.equinox.executable/library/motif/NgImageData.h new file mode 100644 index 000000000..df3c9013d --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgWinBMPFileFormat.c b/bundles/org.eclipse.equinox.executable/library/motif/NgWinBMPFileFormat.c new file mode 100644 index 000000000..cf8b77f28 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/NgWinBMPFileFormat.h b/bundles/org.eclipse.equinox.executable/library/motif/NgWinBMPFileFormat.h new file mode 100644 index 000000000..3ff010db1 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/build.sh b/bundles/org.eclipse.equinox.executable/library/motif/build.sh new file mode 100644 index 000000000..86ea1eab2 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/build.xml b/bundles/org.eclipse.equinox.executable/library/motif/build.xml new file mode 100644 index 000000000..b4308a9a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/eclipseMotif.c b/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c new file mode 100644 index 000000000..69aebdf1f --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c @@ -0,0 +1,266 @@ +/******************************************************************************* + * 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 "eclipseCommon.h" +#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> + +/* Global Variables */ +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. */ +extern XtAppContext appContext; +extern Widget topWindow; + +/* Define local variables for handling the splash window and its image. */ +static Widget shellHandle = 0; + +extern void centreShell( Widget widget, Widget expose ); + + +#ifdef NETSCAPE_FIX +static void fixEnvForNetscape(); +#endif /* NETSCAPE_FIX */ + +/* Show the Splash Window + * + * Create the splash window, load the pixmap and display the splash window. + */ +int showSplash( const char* featureImage ) +{ + int argc [] = {0}; + int x, y; + unsigned int width, height, depth, border; + ArgList args; + unsigned int nArgs; + Pixmap splashPixmap = 0; + Window root; + Display *xDisplay; + Screen* screen; + Widget scrolledHandle, drawingHandle, image; + + initWindowSystem(&initialArgc, initialArgv, 1); + + xDisplay = XtOpenDisplay(appContext, NULL, NULL, NULL, 0, 0, argc, 0); + screen = XDefaultScreenOfDisplay( xDisplay ); + if (featureImage != NULL) + { + splashPixmap = loadBMPImage(xDisplay, screen, (char*)featureImage); + } + /* If the splash image could not be found, return an error. */ + if (splashPixmap == 0) + return ENOENT; + + XGetGeometry (xDisplay, splashPixmap, &root, &x, &y, &width, &height, &border, &depth); + + /* make sure we never pass more than 20 args */ + args = malloc(10 * sizeof(Arg)); + + nArgs = 0; + /* Note that XtSetArg is a macro, and the 1st argument will be evaluated twice + * so increment nArgs on its own */ + XtSetArg(args[nArgs], XmNmwmDecorations, 0); nArgs++; + XtSetArg(args[nArgs], XmNtitle, officialName); nArgs++; + XtSetArg(args[nArgs], XmNwidth, width); nArgs++; + XtSetArg(args[nArgs], XmNheight, height); nArgs++; + shellHandle = XtAppCreateShell(officialName, "", applicationShellWidgetClass, xDisplay, args, nArgs); + + nArgs = 0; + XtSetArg(args[nArgs++], XmNancestorSensitive, 1); + scrolledHandle = XmCreateMainWindow(shellHandle, NULL, args, nArgs); + if(scrolledHandle == 0) + return -1; + XtManageChild(scrolledHandle); + + nArgs = 0; + XtSetArg(args[nArgs], XmNancestorSensitive, 1); nArgs++; + XtSetArg(args[nArgs], XmNborderWidth, 0); nArgs++; + XtSetArg(args[nArgs], XmNbackground, 0xFF00FF); nArgs++; + XtSetArg(args[nArgs], XmNmarginWidth, 0); nArgs++; + XtSetArg(args[nArgs], XmNmarginHeight, 0); nArgs++; + XtSetArg(args[nArgs], XmNresizePolicy, XmRESIZE_NONE); nArgs++; + XtSetArg(args[nArgs], XmNtraversalOn, 1); nArgs++; + drawingHandle = XmCreateDrawingArea(scrolledHandle, NULL, args, nArgs); + if(drawingHandle == 0) + return -1; + XtManageChild(drawingHandle); + + nArgs = 0; + XtSetArg(args[nArgs], XmNlabelType, XmPIXMAP); nArgs++; + XtSetArg(args[nArgs], XmNlabelPixmap, splashPixmap);nArgs++; + XtSetArg(args[nArgs], XmNwidth, width); nArgs++; + XtSetArg(args[nArgs], XmNheight, height); nArgs++; + XtSetArg(args[nArgs], XmNmarginWidth, 0); nArgs++; + XtSetArg(args[nArgs], XmNmarginHeight, 0); nArgs++; + image = XmCreateLabelGadget ( drawingHandle, "", args, nArgs ); + XtManageChild( image ); + + XtRealizeWidget(shellHandle); + XtSetMappedWhenManaged(shellHandle, 1); + + if(XtIsTopLevelShell(shellHandle)) + XtMapWidget(shellHandle); + else + XtPopup(shellHandle, XtGrabNone); + + /* Centre the splash screen and display it. */ + centreShell( shellHandle, drawingHandle ); + dispatchMessages(); + + free(args); + return 0; +} + +/* Get the window system specific VM arguments */ +char** getArgVM( char* vm ) +{ + char** result; + +#ifdef AIX + char* version; +#endif + + if (isJ9VM( vm )) + return argVM_J9; + + /* Use the default arguments for a standard Java VM */ + result = argVM_JAVA; + +#ifdef AIX + /* Determine whether Java version is 1.3.1 or later */ + version = getVMVersion( vm ); + if (version != NULL) + { + if (versionCmp(version, "1.3.1") >= 0) + result = argVM_JAVA_AIX131; + free(version); + } +#endif + + return result; +} + + +long getSplashHandle() { + return (long)shellHandle; +} + +void dispatchMessages() { + XtInputMask mask; + /* Process any outstanding messages */ + while ((mask = XtAppPending(appContext)) != 0) { + XtAppProcessEvent(appContext, mask); + } +} + +void takeDownSplash() +{ + if (shellHandle != 0) + { + XtUnrealizeWidget( shellHandle ); + XFlush( XtDisplay( shellHandle ) ); + } +} + +#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.executable/library/motif/eclipseMotifCommon.c b/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotifCommon.c new file mode 100644 index 000000000..3442ac985 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotifCommon.c @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseCommon.h" +#include "eclipseOS.h" + +#include <locale.h> +#include <dlfcn.h> +#include <stdlib.h> +#include <Xm/XmAll.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/IntrinsicP.h> +#include <X11/Intrinsic.h> +#include <X11/Shell.h> + +#ifndef NO_XINERAMA_EXTENSIONS +#include <X11/extensions/Xinerama.h> +#endif + +#define ECLIPSE_ICON 401 + +char dirSeparator = '/'; +char pathSeparator = ':'; + +void centreShell( Widget widget, Widget expose ); +void initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash ); + +/* Global Variables */ +XtAppContext appContext = 0; +Widget topWindow = 0; + +/* Define local variables for the main window. */ +static int saveArgc = 0; /* arguments after they were parsed, for window system */ +static char** saveArgv = 0; + +int motifInitialized = 0; + +/* Display a Message */ +void displayMessage( char* title, char* message ) +{ + char* displayName = NULL; + Widget msgBox = NULL; + XmString msg; + Arg arg[20]; + int nArgs; + XEvent event; + + /* If there is no associated display, 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]; + + if(motifInitialized == 1) + return; + /* Save the arguments in case displayMessage() is called in the main launcher. */ + if (saveArgv == 0) + { + saveArgc = *pArgc; + saveArgv = argv; + } + + /* 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 ); + motifInitialized = 1; +} + +/* Centre the shell on the screen. */ +void centreShell( Widget widget, Widget expose ) +{ + XtAppContext context; + XEvent event; + Arg arg[20]; + int nArgs; + Position x, y; + Dimension width, height; + Screen* screen; + int waiting; + short screenWidth, screenHeight; + +#ifndef NO_XINERAMA_EXTENSIONS + Display* display; + int monitorCount; + XineramaScreenInfo* info; +#endif + + /* Realize the shell to calculate its width/height. */ + 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 ) ); +} + +/* Load the specified shared library + */ +void * loadLibrary( char * library ){ + void * result= dlopen(library, RTLD_LAZY); + if(result == 0) + printf("%s\n",dlerror()); + return result; +} + +/* Unload the shared library + */ +void unloadLibrary( void * handle ){ + dlclose(handle); +} + +/* Find the given symbol in the shared library + */ +void * findSymbol( void * handle, char * symbol ){ + return dlsym(handle, symbol); +} + diff --git a/bundles/org.eclipse.equinox.executable/library/motif/make_aix.mak b/bundles/org.eclipse.equinox.executable/library/motif/make_aix.mak new file mode 100644 index 000000000..592731b81 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/make_hpux_PA_RISC.mak b/bundles/org.eclipse.equinox.executable/library/motif/make_hpux_PA_RISC.mak new file mode 100644 index 000000000..d43f88416 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/make_hpux_ia64_32.mak b/bundles/org.eclipse.equinox.executable/library/motif/make_hpux_ia64_32.mak new file mode 100644 index 000000000..64b701298 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/motif/make_linux.mak b/bundles/org.eclipse.equinox.executable/library/motif/make_linux.mak new file mode 100644 index 000000000..990c7f1dd --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/motif/make_linux.mak @@ -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 +# 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 +# PROGRAM_LIBRARY - the filename of the output library +# DEFAULT_OS - the default value of the "-os" switch +# DEFAULT_OS_ARCH - the default value of the "-arch" switch +# DEFAULT_WS - the default value of the "-ws" switch +# X11_HOME - the full path to X11 header files +# MOTIF_HOME - the full path to Motif header files +# JAVA_JNI - the full path to the java jni header files + +ifeq ($(PROGRAM_OUTPUT),) + PROGRAM_OUTPUT=eclipse +endif +ifeq ($(PROGRAM_LIBRARY),) + PROGRAM_LIBRARY=eclipse_001.so +endif + +# Define the object modules to be compiled and flags. +#OBJS = eclipse.o eclipseUtil.o eclipseJNI.o eclipseConfig.o eclipseMozilla.o eclipseMotif.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o + +MAIN_OBJS = eclipseMain.o +COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseMotifCommon.o +DLL_OBJS = eclipse.o eclipseMotif.o eclipseUtil.o eclipseJNI.o eclipseMozilla.o NgCommon.o NgImage.o NgImageData.o NgWinBMPFileFormat.o + + +EXEC = $(PROGRAM_OUTPUT) +DLL = $(PROGRAM_LIBRARY) +LIBS = -Xlinker -rpath -Xlinker . -L$(MOTIF_HOME)/lib -L$(X11_HOME)/lib -lXm -lXt -lX11 -lXinerama +LFLAGS = -shared -fpic -Wl,--export-dynamic +CFLAGS = -g -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 \ + -I$(JAVA_JNI) + +all: $(EXEC) $(DLL) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseMain.o: ../eclipseMain.c ../eclipseUnicode.h ../eclipseCommon.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipse.o: ../eclipse.c ../eclipseOS.h ../eclipseCommon.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseCommon.o: ../eclipseCommon.c ../eclipseCommon.h ../eclipseUnicode.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseUtil.o: ../eclipseUtil.c ../eclipseUtil.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseJNI.o: ../eclipseJNI.c ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseConfig.o: ../eclipseConfig.c ../eclipseConfig.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +eclipseMozilla.o: ../eclipseMozilla.c ../eclipseMozilla.h ../eclipseOS.h + $(CC) $(CFLAGS) -c $< -o $@ + +$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) + $(CC) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(LIBS) + +$(DLL): $(DLL_OBJS) $(COMMON_OBJS) + $(CC) $(LFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS) + +install: all + cp $(EXEC) $(DLL) $(OUTPUT_DIR) + rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) + +clean: + rm -f $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(DLL_OBJS) diff --git a/bundles/org.eclipse.equinox.executable/library/motif/make_solaris.mak b/bundles/org.eclipse.equinox.executable/library/motif/make_solaris.mak new file mode 100644 index 000000000..2bcdd5af0 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/photon/.cvsignore b/bundles/org.eclipse.equinox.executable/library/photon/.cvsignore new file mode 100644 index 000000000..5535df034 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/photon/.cvsignore @@ -0,0 +1,2 @@ +*.o +eclipse diff --git a/bundles/org.eclipse.equinox.executable/library/photon/build.sh b/bundles/org.eclipse.equinox.executable/library/photon/build.sh new file mode 100644 index 000000000..2166d19ff --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/photon/build.xml b/bundles/org.eclipse.equinox.executable/library/photon/build.xml new file mode 100644 index 000000000..b4308a9a2 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/photon/eclipsePhoton.c b/bundles/org.eclipse.equinox.executable/library/photon/eclipsePhoton.c new file mode 100644 index 000000000..e45e2c0e2 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/photon/make_qnx.mak b/bundles/org.eclipse.equinox.executable/library/photon/make_qnx.mak new file mode 100644 index 000000000..fac6918db --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/win32/.cvsignore b/bundles/org.eclipse.equinox.executable/library/win32/.cvsignore new file mode 100644 index 000000000..ef22704b6 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/.cvsignore @@ -0,0 +1,3 @@ +*.obj +eclipse.exe +eclipse.res diff --git a/bundles/org.eclipse.equinox.executable/library/win32/build.bat b/bundles/org.eclipse.equinox.executable/library/win32/build.bat new file mode 100644 index 000000000..ea748c0c5 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/build.bat @@ -0,0 +1,130 @@ +@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 -library <PROGRAM_LIBRARY>- dll filename (eclipse.dll) +@rem -os <DEFAULT_OS> - default Eclipse "-os" value (qnx) +@rem -arch <DEFAULT_OS_ARCH> - default Eclipse "-arch" value (x86) +@rem -ws <DEFAULT_WS> - default Eclipse "-ws" value (photon) +@rem -java <JAVA_HOME> - location of a Java SDK for JNI headers +@rem +@rem +@rem This script can also be invoked with the "clean" argument. +@rem +@rem NOTE: The C compiler needs to be setup. This script has been +@rem tested against Microsoft Visual C and C++ Compiler 6.0. +@rem +@rem Uncomment the lines below and edit MSVC_HOME to point to the +@rem correct root directory of the compiler installation, if you +@rem want this to be done by this script. +@rem +@rem ****** +@echo off + +IF NOT "%JAVA_HOME%"=="" GOTO MSVC +rem ***** +rem Javah +rem ***** +set JAVA_HOME=j:\teamswt\swt-builddir\ibm-jdk1.4.1 +set path=%JAVA_HOME%;%path% + +:MSVC +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 programLibrary=eclipse.dll +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 ) + if "%1" == "-library" ( + set programLibrary=%2 + shift + goto NEXT ) + if "%1" == "-java" ( + set javaHome=%2 + shift + goto NEXT ) +:LAST_ARG + set extraArgs=%extraArgs% %1 + +:NEXT + shift + goto WHILE +:WHILE_END + +rem -------------------------- +rem Set up environment variables needed by the makefile. +rem -------------------------- +set PROGRAM_OUTPUT=%programOutput% +set PROGRAM_LIBRARY=%programLibrary% +set DEFAULT_OS=%defaultOS% +set DEFAULT_OS_ARCH=%defaultOSArch% +set DEFAULT_WS=%defaultWS% +set OUTPUT_DIR=..\..\bin\%defaultWS%\%defaultOS%\%defaultOSArch% +set JAVA_HOME=%javaHome% + +rem -------------------------- +rem Run nmake to build the executable. +rem -------------------------- +if "%extraArgs%" == "" goto MAKE_ALL + +nmake -f %makefile% %extraArgs% +goto DONE + +:MAKE_ALL +echo Building %OS% launcher. Defaults: -os %DEFAULT_OS% -arch %DEFAULT_OS_ARCH% -ws %DEFAULT_WS% +nmake -f %makefile% clean +nmake -f %makefile% %1 %2 %3 %4 +goto DONE + + +:DONE diff --git a/bundles/org.eclipse.equinox.executable/library/win32/build.sh b/bundles/org.eclipse.equinox.executable/library/win32/build.sh new file mode 100644 index 000000000..386f81d59 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/win32/build.xml b/bundles/org.eclipse.equinox.executable/library/win32/build.xml new file mode 100644 index 000000000..a5a99abbd --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/win32/eclipse.exe.manifest b/bundles/org.eclipse.equinox.executable/library/win32/eclipse.exe.manifest new file mode 100644 index 000000000..51cdc24f6 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/win32/eclipse.ico b/bundles/org.eclipse.equinox.executable/library/win32/eclipse.ico Binary files differnew file mode 100644 index 000000000..5b2f132dd --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/eclipse.ico diff --git a/bundles/org.eclipse.equinox.executable/library/win32/eclipse.rc b/bundles/org.eclipse.equinox.executable/library/win32/eclipse.rc new file mode 100644 index 000000000..723baa714 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/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.executable/library/win32/eclipseWin.c b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c new file mode 100644 index 000000000..a1a5fa2b4 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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 "eclipseCommon.h" + +#include <windows.h> +#include <commctrl.h> +#include <process.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/stat.h> + +#ifdef __MINGW32__ +#include <stdlib.h> +#endif + +extern HWND topWindow; + +/* Global Variables */ +_TCHAR* consoleVM = _T("java.exe"); +_TCHAR* defaultVM = _T("javaw.exe"); +_TCHAR* vmLibrary = _T("jvm.dll"); +_TCHAR* shippedVMDir = _T("jre\\bin\\"); + +/* Define the window system arguments for the Java VM. */ +static _TCHAR* argVM[] = { NULL }; + +/* define default locations in which to find the jvm shared library + * these are paths relative to the java exe, the shared library is + * for example jvmLocations[0] + dirSeparator + vmLibrary */ +#define MAX_LOCATION_LENGTH 10 /* none of the jvmLocations strings should be longer than this */ +static const _TCHAR* jvmLocations [] = { _T("j9vm"), + _T("client"), + _T("server"), + _T("classic"), + NULL }; +/* Show the Splash Window + * + * Open the bitmap, insert into the splash window and display it. + * + */ +int showSplash( const _TCHAR* featureImage ) +{ + static int splashing = 0; + HBITMAP hBitmap = 0; + BITMAP bmp; + HDC hDC; + int depth; + int x, y; + int width, height; + + if(splashing) { + /*splash screen is already showing, do nothing */ + return 0; + } + + /* if Java was started first and is calling back to show the splash, we might not + * have initialized the window system yet + */ + initWindowSystem(0, NULL, 1); + + /* Load the bitmap for the feature. */ + hDC = GetDC( NULL); + depth = GetDeviceCaps( hDC, BITSPIXEL ) * GetDeviceCaps( hDC, PLANES); + ReleaseDC(NULL, hDC); + if (featureImage != NULL) + hBitmap = LoadImage(NULL, featureImage, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); + + /* If the bitmap could not be found, return an error. */ + if (hBitmap == 0) + return ERROR_FILE_NOT_FOUND; + + GetObject(hBitmap, sizeof(BITMAP), &bmp); + + /* figure out position */ + width = GetSystemMetrics (SM_CXSCREEN); + height = GetSystemMetrics (SM_CYSCREEN); + x = (width - bmp.bmWidth) / 2; + y = (height - bmp.bmHeight) / 2; + + /* Centre the splash window and display it. */ + SetWindowPos (topWindow, 0, x, y, bmp.bmWidth, bmp.bmHeight, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + SendMessage( topWindow, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBitmap ); + ShowWindow( topWindow, SW_SHOW ); + BringWindowToTop( topWindow ); + splashing = 1; + + /* Process messages */ + dispatchMessages(); + return 0; +} + +void dispatchMessages() { + MSG msg; + + if(topWindow == 0) + return; + while (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } +} + +long getSplashHandle() { + return (long)topWindow; +} + +void takeDownSplash() { + if(topWindow != NULL) { + DestroyWindow(topWindow); + dispatchMessages(); + } +} + +/* Get the window system specific VM args */ +_TCHAR** getArgVM( _TCHAR *vm ) +{ + return argVM; +} + +/* Local functions */ + +/* + * Find the VM shared library starting from the java executable + */ +_TCHAR* findVMLibrary( _TCHAR* command ) { + int i, j; + int pathLength; + struct _stat stats; + _TCHAR * path; /* path to resulting jvm shared library */ + _TCHAR * location; /* points to begining of jvmLocations section of path */ + + /* for looking in the registry */ + HKEY keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; + HKEY jreKey = NULL, subKey = NULL; + DWORD length = MAX_PATH; + _TCHAR keyName[MAX_PATH], lib[MAX_PATH]; + _TCHAR * jreKeyName; + + if (command != NULL) { + location = _tcsrchr( command, dirSeparator ) + 1; + + /*check first to see if command already points to the library */ + if (_tcscmp(location, vmLibrary) == 0) { + return command; + } + + pathLength = location - command; + path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + _tcslen(vmLibrary)) * sizeof(_TCHAR *)); + _tcsncpy(path, command, pathLength); + location = &path[pathLength]; + + /* + * We are trying base/jvmLocations[*]/vmLibrary + * where base is the directory containing the given java command, normally jre/bin + */ + i = -1; + while(jvmLocations[++i] != NULL) { + int length = _tcslen(jvmLocations[i]); + _tcscpy(location, jvmLocations[i]); + location[length] = dirSeparator; + location[length + 1] = _T('\0'); + _tcscat(location, vmLibrary); + if (_tstat( path, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0) + { /* found it */ + return path; + } + } + } + + /* Not found yet, try the registry, we will use the first 1.4 or 1.5 vm we can find*/ + jreKeyName = _T("Software\\JavaSoft\\Java Runtime Environment"); + for (i = 0; i < 2; i++) { + jreKey = NULL; + if (RegOpenKeyEx(keys[i], jreKeyName, 0, KEY_READ, &jreKey) == ERROR_SUCCESS) { + j = 0; + while (RegEnumKeyEx(jreKey, j++, keyName, &length, 0, 0, 0, 0) == ERROR_SUCCESS) { + /*look for a 1.4 or 1.5 vm*/ + if( _tcsncmp(_T("1.4"), keyName, 3) == 0 || _tcsncmp(_T("1.5"), keyName, 3) == 0) { + subKey = NULL; + if(RegOpenKeyEx(jreKey, keyName, 0, KEY_READ, &subKey) == ERROR_SUCCESS) { + length = MAX_PATH; + /*The RuntimeLib value should point to the library we want*/ + if(RegQueryValueEx(subKey, _T("RuntimeLib"), NULL, NULL, (void*)&lib, &length) == ERROR_SUCCESS) { + if (_tstat( lib, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0) + { /*library exists*/ + path = malloc( length * sizeof(TCHAR*)); + path[0] = _T('\0'); + _tcscat(path, lib); + + RegCloseKey(subKey); + RegCloseKey(jreKey); + return path; + } + } + RegCloseKey(subKey); + } + } + } + RegCloseKey(jreKey); + } + } + return NULL; +} + +void restartLauncher( _TCHAR* program, _TCHAR* args[] ) +{ + 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 = _tcslen(program) + 1; + 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) ); + _tcscpy(ch, program); + ch += _tcslen(program); + *ch++ = _T(' '); + for (index = 0; args[index] != NULL; index++) + { + space = _tcschr( args[ index ], _T(' ')); + if (space != NULL) *ch++ = _T('\"'); + _tcscpy( ch, args[index] ); + ch += _tcslen( args[index] ); + if (space != NULL) *ch++ = _T('\"'); + *ch++ = _T(' '); + } + *ch = _T('\0'); + + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + GetStartupInfo(&si); + if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { + CloseHandle( pi.hThread ); + } + } + free(commandLine); +} diff --git a/bundles/org.eclipse.equinox.executable/library/win32/eclipseWinCommon.c b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWinCommon.c new file mode 100644 index 000000000..bbc4ae5f9 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWinCommon.c @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseCommon.h" +#include "eclipseOS.h" + +#include <windows.h> +#include <stdlib.h> +#include <commctrl.h> + +#define ECLIPSE_ICON 401 + +_TCHAR dirSeparator = _T('\\'); +_TCHAR pathSeparator = _T(';'); + +void initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash ); +/*static LRESULT WINAPI WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);*/ + +/* Global Main Window*/ +#ifdef UNICODE +extern HWND topWindow; +#else +HWND topWindow = 0; +#endif + +/* Define local variables for the main window. */ +/*static WNDPROC oldProc;*/ + +static int initialized = 0; + +/* Display a Message */ +void displayMessage( _TCHAR* title, _TCHAR* message ) +{ + if(!initialized) + initWindowSystem(0, NULL, 0); + MessageBox( topWindow, message, title, MB_OK ); +} + +/* Initialize Window System + * + * Create a pop window to display the bitmap image. + * + * Return the window handle as the data for the splash command. + * + */ +void initWindowSystem( int* pArgc, _TCHAR* argv[], int showSplash ) +{ + if(initialized) + return; + /* Create a window that has no decorations. */ + + InitCommonControls(); + topWindow = CreateWindowEx (0, + _T("STATIC"), + officialName, + SS_BITMAP | WS_POPUP, + CW_USEDEFAULT, + 0, + CW_USEDEFAULT, + 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); +*/ + initialized = 1; +} + +/* 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; + } + return CallWindowProc (oldProc, hwnd, uMsg, wParam, lParam); +}*/ + +/* Load the specified shared library + */ +void * loadLibrary( _TCHAR * library ){ + return LoadLibrary(library); +} + +/* Unload the shared library + */ +void unloadLibrary( void * handle ){ + FreeLibrary(handle); +} + +/* Find the given symbol in the shared library + */ +void * findSymbol( void * handle, _TCHAR * symbol ){ + char * str = NULL; + void * result; + + str = toNarrow(symbol); + result = GetProcAddress(handle, str); + free(str); + return result; +} + diff --git a/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak b/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak new file mode 100644 index 000000000..9f5d0542f --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak @@ -0,0 +1,139 @@ +#******************************************************************************* +# 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 +# PROGRAM_LIBRARY - the file of the output shared library +# DEFAULT_OS - the default value of the "-os" switch +# DEFAULT_OS_ARCH - the default value of the "-arch" switch +# DEFAULT_WS - the default value of the "-ws" switch + +#if PROGRAM_OUTPUT is not set, assume eclipse.exe +ifeq ($(PROGRAM_OUTPUT),) + PROGRAM_OUTPUT=eclipse.exe + PROGRAM_LIBRARY=eclipse_1.dll +endif + +# 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. +MAIN_OBJS = eclipseMain.o aeclipseMain.o +COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseWinCommon.o\ + aeclipseConfig.o aeclipseCommon.o aeclipseWinCommon.o +DLL_OBJS = eclipse.o eclipseWin.o eclipseUtil.o eclipseJNI.o\ + aeclipse.o aeclipseWin.o aeclipseUtil.o aeclipseJNI.o + +LIBS = -lkernel32 -luser32 -lgdi32 -lcomctl32 -lmsvcrt +LDFLAGS = -mwindows -mno-cygwin +DLL_LDFLAGS = -mno-cygwin -shared -Wl,--export-all-symbols -Wl,--kill-at +RES = eclipse.res +EXEC = $(PROGRAM_OUTPUT) +DLL = $(PROGRAM_LIBRARY) +DEBUG = $(CDEBUG) +CFLAGS = -g -s -Wall \ + -I. -I$(JAVA_JNI) $(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) $(DLL) + +eclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseMain.c + +aeclipseMain.o: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseMain.c + +eclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseCommon.c + +aeclipseCommon.o: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseCommon.c + +eclipseWinCommon.o: ../eclipseCommon.h eclipseWinCommon.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ eclipseWinCommon.c + +aeclipseWinCommon.o: ../eclipseCommon.h eclipseWinCommon.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ eclipseWinCommon.c + +eclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipseJNI.h ../eclipseCommon.h ../eclipse.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipse.c + +eclipseUtil.o: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseUtil.c + +eclipseConfig.o: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseConfig.c + +eclipseWin.o: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ eclipseWin.c + +eclipseJNI.o: ../eclipseUnicode.h ../eclipseJNI.c + $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseJNI.c + +aeclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipseCommon.h ../eclipse.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipse.c + +aeclipseUtil.o: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseUtil.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 + +aeclipseJNI.o: ../eclipseUnicode.h ../eclipseJNI.c + $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseJNI.c + +$(RES): eclipse.rc + $(RC) --output-format=coff --include-dir=.. -o $@ $< + +$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES) + $(CC) $(LDFLAGS) -o $(EXEC) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS) + +$(DLL): $(DLL_OBJS) $(COMMON_OBJS) + $(CC) $(DLL_LDFLAGS) -o $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(LIBS) + +install: all + cp $(EXEC) $(DLL) $(OUTPUT_DIR) + rm -f $(EXEC) $(DLL_OBJS) $(COMMON_OBJS) $(MAIN_OBJS) $(RES) + +clean: + $(RM) $(EXEC) $(DLL) $(DLL_OBJS) $(COMMON_OBJS) $(MAIN_OBJS) $(RES) diff --git a/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak b/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak new file mode 100644 index 000000000..8e0c284ed --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak @@ -0,0 +1,112 @@ +#****************************************************************************** +# Copyright (c) 2000, 2006 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +# Kevin Cornell (Rational Software Corporation) +#******************************************************************************* + +# Makefile for creating the eclipse launcher program. + +# This makefile expects the following environment variables set: +# +# PROGRAM_OUTPUT - the filename of the output executable +# PROGRAM_LIBRARY - the filename of the output dll library +# DEFAULT_OS - the default value of the "-os" switch +# DEFAULT_OS_ARCH - the default value of the "-arch" switch +# DEFAULT_WS - the default value of the "-ws" switch +# JAVA_HOME - the location of the Java for JNI includes + +!include <ntwin32.mak> + +# Define the object modules to be compiled and flags. +MAIN_OBJS = eclipseMain.obj aeclipseMain.obj +COMMON_OBJS = eclipseConfig.obj eclipseCommon.obj eclipseWinCommon.obj\ + aeclipseConfig.obj aeclipseCommon.obj aeclipseWinCommon.obj +DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj\ + aeclipse.obj aeclipseWin.obj aeclipseUtil.obj aeclipseJNI.obj + +LIBS = kernel32.lib user32.lib comctl32.lib +DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib +LFLAGS = /INCREMENTAL:NO /DEBUG /NOLOGO -subsystem:windows,4.0 -entry:wmainCRTStartup +DLL_LFLAGS = /INCREMENTAL:NO /PDB:NONE /DEBUG /NOLOGO -entry:_DllMainCRTStartup@12 -dll /BASE:0x10000000 /DLL +RES = eclipse.res +EXEC = eclipse.exe +DLL = eclipse_1.exe +DEBUG = #$(cdebug) +acflags = -I.. -DDEFAULT_OS="\"$(DEFAULT_OS)\"" \ + -DDEFAULT_OS_ARCH="\"$(DEFAULT_OS_ARCH)\"" \ + -DDEFAULT_WS="\"$(DEFAULT_WS)\"" \ + /I$(JAVA_HOME)\include /I$(JAVA_HOME)\include\win32 \ + $(cflags) +wcflags = -DUNICODE $(acflags) +cvars = /Zi #/O1 +all: $(EXEC) $(DLL) + +eclipseMain.obj: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseMain.c + +eclipseCommon.obj: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseCommon.c + +eclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipse.c + +eclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseUtil.c + +eclipseConfig.obj: ../eclipseConfig.h ../eclipseUnicode.h ../eclipseConfig.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseConfig.c + +eclipseWin.obj: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj eclipseWin.c + +eclipseWinCommon.obj: ../eclipseCommon.h eclipseWinCommon.c + $(cc) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj eclipseWinCommon.c + +eclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c + $(CC) $(DEBUG) $(wcflags) $(cvars) /Fo$*.obj ../eclipseJNI.c + +aeclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseJNI.obj ../eclipseJNI.c + +aeclipseMain.obj: ../eclipseUnicode.h ../eclipseCommon.h ../eclipseMain.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseMain.obj ../eclipseMain.c + +aeclipseCommon.obj: ../eclipseCommon.h ../eclipseUnicode.h ../eclipseCommon.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseCommon.obj ../eclipseCommon.c + +aeclipse.obj: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c + $(cc) $(DEBUG) $(acflags) $(cvars) /Foaeclipse.obj ../eclipse.c + +aeclipseUtil.obj: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseUtil.obj ../eclipseUtil.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 + +aeclipseWinCommon.obj: ../eclipseCommon.h eclipseWinCommon.c + $(cc) $(DEBUG) $(acflags) $(cvars) /FoaeclipseWinCommon.obj eclipseWinCommon.c + +$(EXEC): $(MAIN_OBJS) $(COMMON_OBJS) $(RES) + $(link) $(LFLAGS) -out:$(PROGRAM_OUTPUT) $(MAIN_OBJS) $(COMMON_OBJS) $(RES) $(LIBS) + +$(DLL): $(DLL_OBJS) $(COMMON_OBJS) + $(link) $(DLL_LFLAGS) -out:$(PROGRAM_LIBRARY) $(DLL_OBJS) $(COMMON_OBJS) $(RES) $(DLL_LIBS) + +$(RES): eclipse.rc + $(rc) -r -fo $(RES) eclipse.rc + +install: all + copy $(EXEC) $(OUTPUT_DIR) + del -f $(EXEC) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES) + +clean: + del $(EXEC) $(MAIN_OBJS) $(DLL_OBJS) $(COMMON_OBJS) $(RES) |