blob: 4d5f8f1972c7bbf944101ff07357a678b547a30c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Kevin Cornell (Rational Software Corporation)
*******************************************************************************/
/* UNIX/Motif specific logic for displaying the splash screen. */
#include "eclipseCommon.h"
#include "eclipseMozilla.h"
#include "eclipseMotif.h"
#include "eclipseOS.h"
#include "eclipseUtil.h"
#include "NgImage.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#ifdef SOLARIS
#include <sys/filio.h>
#endif
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>
/* Global Variables */
char* defaultVM = "java";
char* vmLibrary = "libjvm.so";
char* shippedVMDir = "jre/bin/";
/* Define the special arguments for the various Java VMs. */
static char* argVM_JAVA[] = { NULL };
#if AIX
static char* argVM_JAVA_AIX131[] = { "-Xquickstart", NULL };
#endif
static char* argVM_J9[] = { "-jit", "-mca:1024", "-mco:1024", "-mn:256", "-mo:4096",
"-moi:16384", "-mx:262144", "-ms:16", "-mr:16", NULL };
/* Define local variables for the main window. */
extern XtAppContext appContext;
extern Widget topWindow;
static pid_t jvmProcess = 0;
static int jvmExitCode;
/* Define local variables for handling the splash window and its image. */
static Widget shellHandle = 0;
extern void centreShell( Widget widget, Widget expose );
#ifdef NETSCAPE_FIX
void fixEnvForNetscape();
#endif /* NETSCAPE_FIX */
void takeDownSplashCB( Widget shell, XtPointer app_data, XtPointer widget_data ) {
shellHandle = NULL;
}
/* Show the Splash Window
*
* Create the splash window, load the pixmap and display the splash window.
*/
int showSplash( const char* featureImage )
{
int x, y;
unsigned int width, height, depth, border;
ArgList args;
unsigned int nArgs;
Pixmap splashPixmap = 0;
Window root;
Display *xDisplay;
Screen* screen;
Widget scrolledHandle, drawingHandle, image;
if (shellHandle != 0)
return 0; /* already showing splash */
if (initialArgv == NULL)
initialArgc = 0;
if (initWindowSystem(&initialArgc, initialArgv, 1) != 0) {
return -1;
}
xDisplay = motif_XtDisplay(topWindow);
screen = motif.XDefaultScreenOfDisplay( xDisplay );
if (featureImage != NULL)
{
splashPixmap = loadBMPImage(xDisplay, screen, (char*)featureImage);
}
/* If the splash image could not be found, return an error. */
if (splashPixmap == 0)
return ENOENT;
motif.XGetGeometry (xDisplay, splashPixmap, &root, &x, &y, &width, &height, &border, &depth);
/* make sure we never pass more than 20 args */
args = malloc(10 * sizeof(Arg));
nArgs = 0;
/* Note that XtSetArg is a macro, and the 1st argument will be evaluated twice
* so increment nArgs on its own */
motif_XtSetArg(args[nArgs], XmNmwmDecorations, 0); nArgs++;
motif_XtSetArg(args[nArgs], XmNtitle, getOfficialName()); nArgs++;
motif_XtSetArg(args[nArgs], XmNwidth, width); nArgs++;
motif_XtSetArg(args[nArgs], XmNheight, height); nArgs++;
shellHandle = motif.XtAppCreateShell(getOfficialName(), "", *motif.applicationShellWidgetClass, xDisplay, args, nArgs);
motif.XtAddCallback(shellHandle, XmNdestroyCallback, (XtCallbackProc) takeDownSplashCB, NULL);
nArgs = 0;
motif_XtSetArg(args[nArgs++], XmNancestorSensitive, 1);
scrolledHandle = motif.XmCreateMainWindow(shellHandle, NULL, args, nArgs);
if(scrolledHandle == 0)
return -1;
motif.XtManageChild(scrolledHandle);
nArgs = 0;
motif_XtSetArg(args[nArgs], XmNancestorSensitive, 1); nArgs++;
motif_XtSetArg(args[nArgs], XmNborderWidth, 0); nArgs++;
/*motif_XtSetArg(args[nArgs], XmNbackground, 0xFF00FF); nArgs++; */
motif_XtSetArg(args[nArgs], XmNmarginWidth, 0); nArgs++;
motif_XtSetArg(args[nArgs], XmNmarginHeight, 0); nArgs++;
motif_XtSetArg(args[nArgs], XmNresizePolicy, XmRESIZE_NONE); nArgs++;
motif_XtSetArg(args[nArgs], XmNtraversalOn, 1); nArgs++;
drawingHandle = motif.XmCreateDrawingArea(scrolledHandle, NULL, args, nArgs);
if(drawingHandle == 0)
return -1;
motif.XtManageChild(drawingHandle);
nArgs = 0;
motif_XtSetArg(args[nArgs], XmNlabelType, XmPIXMAP); nArgs++;
motif_XtSetArg(args[nArgs], XmNlabelPixmap, splashPixmap); nArgs++;
motif_XtSetArg(args[nArgs], XmNwidth, width); nArgs++;
motif_XtSetArg(args[nArgs], XmNheight, height); nArgs++;
motif_XtSetArg(args[nArgs], XmNmarginWidth, 0); nArgs++;
motif_XtSetArg(args[nArgs], XmNmarginHeight, 0); nArgs++;
image = motif.XmCreateLabelGadget ( drawingHandle, "", args, nArgs );
motif.XtManageChild( image );
motif.XtRealizeWidget(shellHandle);
motif.XtSetMappedWhenManaged(shellHandle, 1);
if(motif_XtIsTopLevelShell(shellHandle))
motif_XtMapWidget(shellHandle);
else
motif.XtPopup(shellHandle, XtGrabNone);
/* Centre the splash screen and display it. */
centreShell( shellHandle, drawingHandle );
dispatchMessages();
free(args);
return 0;
}
/* Get the window system specific VM arguments */
char** getArgVM( char* vm )
{
char** result;
#ifdef AIX
char* version;
#endif
if (isJ9VM( vm ))
return argVM_J9;
/* Use the default arguments for a standard Java VM */
result = argVM_JAVA;
#ifdef AIX
/* Determine whether Java version is 1.3.1 or later */
version = getVMVersion( vm );
if (version != NULL)
{
if (versionCmp(version, "1.3.1") >= 0)
result = argVM_JAVA_AIX131;
free(version);
}
#endif
return result;
}
jlong getSplashHandle() {
return (jlong)shellHandle;
}
void dispatchMessages() {
XtInputMask mask;
if (appContext != NULL && motif.XtAppPending != 0) {
/* Process any outstanding messages */
while ((mask = motif.XtAppPending(appContext)) != 0) {
motif.XtAppProcessEvent(appContext, mask);
}
}
}
void takeDownSplash()
{
if (shellHandle != 0)
{
motif.XtDestroyWidget( shellHandle );
/*XFlush( XtDisplay( shellHandle ) );*/
shellHandle = NULL;
}
}
#ifdef NETSCAPE_FIX
extern char* findCommand( char*);
static const char* XFILESEARCHPATH = "XFILESEARCHPATH";
void fixEnvForNetscape()
{
char* netscapePath = NULL;
char* netscapeResource = NULL;
char* ch;
char* envValue;
struct stat stats;
/* If netscape appears to be installed */
netscapePath = findCommand("netscape");
if (netscapePath != NULL)
{
/* Look for the resource file Netscape.ad in the same directory as "netscape". */
netscapeResource = malloc( strlen(netscapePath) + 50 );
strcpy( netscapeResource, netscapePath );
ch = strrchr( netscapeResource, (int) dirSeparator );
ch =(ch == NULL ? netscapeResource : (ch+1));
strcpy( ch, "Netscape.ad" );
/* If it does not exist there, try "/opt/netscape/Netscape.ad". */
if (stat( netscapeResource, &stats ) != 0)
{
strcpy( netscapeResource, "/opt/netscape/Netscape.ad" );
}
/* If the resource file exists */
if (stat( netscapeResource, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
{
/* Either define XFILESEARCHPATH or append the Netscape resource file. */
envValue = getenv( XFILESEARCHPATH );
if (envValue == NULL)
{
ch = malloc( strlen(XFILESEARCHPATH) + strlen(netscapeResource) + 5 );
sprintf( ch, "%s=%s", XFILESEARCHPATH, netscapeResource );
}
else
{
ch = malloc( strlen(XFILESEARCHPATH) + strlen(netscapeResource) +
strlen(envValue) + 5 );
sprintf( ch, "%s=%s:%s", XFILESEARCHPATH, envValue, netscapeResource );
}
putenv( ch );
free( ch );
}
/* Clean up. */
free( netscapePath );
free( netscapeResource );
}
}
#endif /* NETSCAPE_FIX */
JavaResults* launchJavaVM( char* args[] )
{
JavaResults* jvmResults = NULL;
int exitCode;
#ifdef NETSCAPE_FIX
fixEnvForNetscape();
#endif /* NETSCAPE_FIX */
#ifdef MOZILLA_FIX
fixEnvForMozilla();
#endif /* MOZILLA_FIX */
#ifdef LINUX
{
/* put the root of eclipse on the LD_LIBRARY_PATH */
char * ldPath = (char*)getenv(_T_ECLIPSE("LD_LIBRARY_PATH"));
if (ldPath == NULL)
ldPath = _T_ECLIPSE("");
char * root = getProgramDir();
if (root != NULL) {
char * newPath = malloc((strlen(root) + strlen(ldPath) + 2) * sizeof(char));
sprintf(newPath, "%s%c%s", root, pathSeparator, ldPath);
setenv("LD_LIBRARY_PATH", newPath, 1);
free(newPath);
}
}
#endif
/* Create a child process for the JVM. */
jvmProcess = fork();
if (jvmProcess == 0)
{
/* Child process ... start the JVM */
execv( args[0], args );
/* The JVM would not start ... return error code to parent process. */
/* TODO, how to distinguish this as a launch problem to the other process? */
jvmExitCode = errno;
exit( jvmExitCode );
}
jvmResults = malloc(sizeof(JavaResults));
memset(jvmResults, 0, sizeof(JavaResults));
/* If the JVM is still running, wait for it to terminate. */
if (jvmProcess != 0)
{
waitpid(jvmProcess, &exitCode, 0);
/* TODO, this should really be a runResult if we could distinguish the launch problem above */
jvmResults->launchResult = ((exitCode & 0x00ff) == 0 ? (exitCode >> 8) : exitCode); /* see wait(2) */
}
/* Return the exit code from the JVM. */
return jvmResults;
}
int reuseWorkbench(_TCHAR** filePath, int timeout) {
/* not yet implemented on motif */
return -1;
}