blob: c14cb9bb90665f1a15a027713951830b99b75393 [file] [log] [blame]
/*******************************************************************************
* 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* defaultVM = "java";
char* shippedVMDir = "jre/bin/";
#else
char* defaultVM = "j9";
char* shippedVMDir = "ive/bin/";
#endif
/* Define the window system arguments for the various Java VMs. */
static char* argVM_JAVA[] = { NULL };
static char* argVM_J9[] = { "-jit", "-ms:32", "-mso:256", NULL };
/* Define local variables for the main window. */
static PtWidget_t* topWindow = NULL;
/* Define local variables for running the JVM and detecting its exit. */
static pid_t jvmProcess = 0;
static int jvmExitCode;
/* Local functions */
static void bringDownSplashWindow( int );
static void centreWindow( PtWidget_t *widget, PtWidget_t *label);
static int splashTimeout( PtWidget_t* widget, void* data, PtCallbackInfo_t* id );
/* Display a Message */
void displayMessage( char* title, char* message )
{
if (topWindow == 0)
{
initWindowSystem( NULL, NULL, 0 );
}
PtNotice( NULL,NULL, title, NULL, message, NULL, NULL, NULL, Pt_CENTER | Pt_MODAL );
}
/* Initialize Window System
*
* Initialize Photon.
*/
void initWindowSystem( int* pArgc, char* argv[], int showSplash )
{
PtArg_t arg[5];
int nArgs;
/* Create a top level window with no decorations. */
setlocale(LC_ALL, "");
PtInit( NULL );
nArgs = 0;
PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_RENDER_FLAGS, 0, ~0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_MANAGED_FLAGS, Ph_WM_TASKBAR | Ph_WM_CLOSE, ~0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_STATE, Ph_WM_STATE_ISFRONT, ~0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_WINDOW_TITLE, getOfficialName(), ~0 );
topWindow = PtCreateWidget( PtWindow, Pt_NO_PARENT, nArgs, arg );
}
/* Show the Splash Window
*
* Create the splash window, load the bitmap and display the splash window.
*
*/
int showSplash( char* timeoutString, char* featureImage )
{
int timeout = 0;
PtWidget_t* label;
PtArg_t arg[10];
PhImage_t* image = NULL;
int nArgs;
int depth;
PgDisplaySettings_t settings;
PgVideoModeInfo_t mode_info;
/* Determine the splash timeout value (in seconds). */
if (timeoutString != NULL && strlen( timeoutString ) > 0)
{
sscanf( timeoutString, "%d", &timeout );
}
/* Install a signal handler to catch SIGUSR2 (which will shut down the window). */
signal( SIGUSR2, bringDownSplashWindow );
/* Load the splash image from the feature directory. */
PgGetVideoMode( &settings );
PgGetVideoModeInfo( settings.mode, &mode_info );
depth = mode_info.bits_per_pixel;
if (featureImage != NULL)
image = PxLoadImage( featureImage, NULL );
/* If the splash image could not be found, return an error. */
if (image == NULL)
return ENOENT;
/* Create a label widget (only child of top window) with the image. */
nArgs = 0;
image->flags |= Ph_RELEASE_IMAGE_ALL;
PtSetArg( &arg[ nArgs++ ], Pt_ARG_LABEL_TYPE, Pt_IMAGE, 0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_LABEL_IMAGE, image, 0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_TEXT_STRING, officialName, 0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_MARGIN_WIDTH, 0, 0 );
PtSetArg( &arg[ nArgs++ ], Pt_ARG_MARGIN_HEIGHT, 0, 0 );
label = PtCreateWidget( PtLabel, topWindow, nArgs, arg );
/* Free the image */
free( image );
/* Centre the splash window and display it. */
centreWindow( topWindow, label );
/* If a timeout for the splash window was given */
if (timeout != 0)
{
PtAddEventHandler( topWindow, Ph_EV_TIMER, splashTimeout, NULL );
PtTimerArm( topWindow, (timeout * 1000) );
}
/* Process messages until the splash window is closed or process is terminated. */
while (PtWidgetIsRealized( topWindow ))
{
PtProcessEvent();
}
/* Destroy the splash window. */
PtDestroyWidget( topWindow );
topWindow = 0;
return 0;
}
/* Get the window system specific VM arguments */
char** getArgVM( char* vm )
{
return (isJ9VM( vm ) ? argVM_J9 : argVM_JAVA);
}
void fixEnvForJ9( char* vm ) {
if (isJ9VM( vm )) {
char *ldpath;
char newpath[PATH_MAX+1];
ldpath = getenv( "LD_LIBRARY_PATH" );
/* Always dup the string so we can free later */
if( ldpath != NULL )
ldpath = strdup( ldpath );
else
ldpath = strdup( "" );
/* Get the j9 binary location */
strncpy( newpath, vm, PATH_MAX );
dirname( newpath );
/* Add j9 binary location to LD_LIBRARY_PATH */
ldpath = realloc( ldpath, strlen( ldpath ) + strlen( newpath ) + 2 );
if( ldpath != NULL )
{
strcat( ldpath, ":" );
strcat( ldpath, newpath );
}
setenv( "LD_LIBRARY_PATH", ldpath, 1 );
free( ldpath );
}
}
/* Start the Java VM
*
* This method is called to start the Java virtual machine and to wait until it
* terminates. The function returns the exit code from the JVM.
*/
int startJavaVM( char* args[] )
{
int exitCode;
fixEnvForJ9 (args [0]);
/* Create a child process for the JVM. */
jvmProcess = fork();
if (jvmProcess == 0)
{
/* Child process ... start the JVM */
execv( args[0], args );
/* The JVM would not start ... return error code to parent process. */
jvmExitCode = errno;
exit( jvmExitCode );
}
/* If the JVM is still running, wait for it to terminate. */
if (jvmProcess != 0)
{
wait( &exitCode );
jvmExitCode = ((exitCode & 0x00ff) == 0 ? (exitCode >> 8) : exitCode); /* see wait(2) */
}
/* Return the exit code from the JVM. */
return jvmExitCode;
}
/*------ Local functions -----*/
/* Catch a signal that indicates the splash window is to be brought down. */
static void bringDownSplashWindow( int sig )
{
if (topWindow != 0)
{
PtUnrealizeWidget( topWindow );
}
}
/* Centre the top window on the screen. */
static void centreWindow( PtWidget_t* window, PtWidget_t* expose )
{
PtArg_t arg[2];
int nArgs;
PhPoint_t pos;
PhArea_t area;
PhRect_t rect;
int width, height;
/* Realize the top window to calculate its width/height. */
PtExtentWidgetFamily( window );
/* Get the desired dimensions of the window. */
PtWidgetArea( window, &area );
/* Calculate the X and Y position for the window. */
PhWindowQueryVisible( Ph_QUERY_WORKSPACE, 0, PhInputGroup(0), &rect );
width = rect.lr.x - rect.ul.x + 1;
height = rect.lr.y - rect.ul.y + 1;
pos.x = rect.ul.x + (width - area.size.w) / 2;
pos.y = rect.ul.y + (height - area.size.h) / 2;
/* Set the new shell position and display it. */
nArgs = 0;
PtSetArg( &arg[ nArgs++ ], Pt_ARG_POS, &pos, 0 );
PtSetResources( window, nArgs, arg );
PtRealizeWidget( window );
}
/* Splash Timeout */
static int splashTimeout( PtWidget_t* widget, void* data, PtCallbackInfo_t* info )
{
bringDownSplashWindow( 0 );
return 1;
}