/******************************************************************************* * 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 #define PX_IMAGE_MODULES #define PX_BMP_SUPPORT #include #include #include #include #include #include #include #include #include /* 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; }