platform-launcher/library/win32/eclipseWin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (download) (annotate)
Mon Mar 24 19:02:04 2003 UTC (6 years, 8 months ago) by ggayed
Branch: MAIN
CVS Tags: v20030908, v20030731, v20031111, v20040223, v3012, R2_1_3, R2_1_2, R2_1_1, v20030825, v20040209, v20040202, v20040113, v2133d, v20040210, v20040216, v20030708, v20030714, v20030813, v20030812, v20030729, v20030728, v20030722, v20030721, v20031021, v20030530, v20030819, v3001, R2_1, v20030422, v20030428
Changes since 1.11: +8 -6 lines
update copyrights
/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Kevin Cornell (Rational Software Corporation)
 *******************************************************************************/
 
#include "eclipseOS.h"
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

/* Global Variables */
char   dirSeparator  = '\\';
char   pathSeparator = ';';
char*  consoleVM     = "java.exe";
char*  defaultVM     = "javaw.exe";
char*  shippedVMDir  = "jre\\bin\\";
char*  guiList[] = { "win32", NULL };

/* Define the window system arguments for the Java VM. */
static char*  argVM[] = { NULL };

/* Define local variables for the main window. */
static HWND    topWindow  = 0;
static WNDPROC oldProc;

/* Define local variables for running the JVM and detecting its exit. */
static char*   javaVM         = NULL;
static int     jvmProcess     = 0;
static int     jvmExitCode    = 0;
static int     jvmExitTimeout = 100;
static int     jvmExitTimerId = 99;

/* Define local variables for handling the splash window and its image. */
static char*   loResSplash = "splash_basic.bmp";
static char*   hiResSplash = "splash_full.bmp";
static int     splashTimerId  = 88;
#define LO_RES_DEPTH 8

/* Local functions */
static void CALLBACK  detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime );
static HBITMAP        loadSplashImage(char *baseDir, char *fileName);
static void CALLBACK  splashTimeout( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime );
static LRESULT WINAPI WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);


/* Display a Message */
void displayMessage( char* message ) 
{
	MessageBox( topWindow, message, getOfficialName(), MB_OK );
}

/* Initialize Window System
 *
 * Create a pop window to display the bitmap image.
 */
void initWindowSystem( int* pArgc, char* argv[], int showSplash )
{
    /* Create a window that has no decorations. */
    topWindow = CreateWindowEx (0,
		"STATIC",
		(char *) getOfficialName(),
		SS_BITMAP | WS_POPUP,
		0,
		0,
		0,
		0,
		NULL,
		NULL,
		GetModuleHandle (NULL),
		NULL);
    oldProc = (WNDPROC) GetWindowLong (topWindow, GWL_WNDPROC);
    SetWindowLong (topWindow, GWL_WNDPROC, (LONG) WndProc);
}


/* Show the Splash Window
 *
 * Open the bitmap, insert into the splash window and display it.
 *
 */
int showSplash( char* timeoutString, char* homeDir, char* featureImage )
{
	int     timeout = 0;
    RECT    rect;
    HBITMAP hBitmap = 0;
    HDC     hDC;
    int     depth;
    int     x, y;
    int     width, height;
    MSG     msg;
    
	/* Determine the splash timeout value (in seconds). */
	if (timeoutString != NULL && strlen( timeoutString ) > 0)
	{
	    sscanf( timeoutString, "%d", &timeout );
	}

    /* Load the bitmap for the feature. */
    hDC = GetDC( NULL);
    depth = GetDeviceCaps( hDC, BITSPIXEL ) * GetDeviceCaps( hDC, PLANES);
    ReleaseDC(NULL, hDC);
    if (featureImage != NULL) 
    	hBitmap = LoadImage(NULL, featureImage, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    
    /* If the bitmap could not be found, try again using the install directory. */
    if (hBitmap == 0)
    	hBitmap = loadSplashImage( homeDir, depth <= LO_RES_DEPTH ? loResSplash : hiResSplash );
    
    /* If the bitmap could not be found, return an error. */
    if (hBitmap == 0)
    	return ERROR_FILE_NOT_FOUND;

	/* Load the bitmap into the splash popup window. */    
    SendMessage( topWindow, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBitmap );

    /* Centre the splash window and display it. */
    GetWindowRect (topWindow, &rect);
    width = GetSystemMetrics (SM_CXSCREEN);
    height = GetSystemMetrics (SM_CYSCREEN);
    x = (width - (rect.right - rect.left)) / 2;
    y = (height - (rect.bottom - rect.top)) / 2;
    SetWindowPos (topWindow, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
    ShowWindow( topWindow, SW_SHOW );
    BringWindowToTop( topWindow );
	
	/* If a timeout for the splash window was given */
	if (timeout != 0)
	{
		/* Add a timeout (in milliseconds) to bring down the splash screen. */
        SetTimer( topWindow, splashTimerId, (timeout * 1000), splashTimeout );
	}

    /* Process messages until the splash window is closed or process is terminated. */
   	while (GetMessage( &msg, NULL, 0, 0 )) 
   	{
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
	
	return 0;
}


/* Get the window system specific VM args */
char** getArgVM( char *vm ) 
{ 
	return argVM; 
}


/* Start the Java VM 
 *
 * This method is called to start the Java virtual machine and to wait until it
 * terminates. The function returns the exit code from the JVM.
 */
int startJavaVM( char* args[] ) 
{
    MSG   msg;
	int   index;
	char* newArg;

	/* If this first time the VM was run */
	if (javaVM == NULL)
	{
		/* Make a copy of the JVM (before double quotes are added or else _spawnv() fails) */
	    javaVM = malloc( strlen(args[0]) + 1 );
	    strcpy( javaVM, args[0] );
		
		/* Any argument with spaces must be in double quotes. */
		for (index = 0; args[index] != NULL; index++) 
		{
			if (strchr( args[ index ], (int) ' ' ) != NULL) 
			{
				newArg = malloc( strlen( args[ index ] ) + 3 );
				sprintf( newArg, "\"%s\"", args[ index ] );
				args[ index ] = newArg;
			}
		}
	}

	/* Start the Java virtual machine */
	jvmProcess = _spawnv( _P_NOWAIT, javaVM, args );
	
	/* If the child process (JVM) would not start */
	if (jvmProcess == -1) 
	{
		/* Return the error number. */
		jvmExitCode = errno;
		jvmProcess  = 0;
	}
	
	/* else */
	else 
	{
        /* Set a timer to detect JVM process termination. */
        SetTimer( topWindow, jvmExitTimerId, jvmExitTimeout, detectJvmExit );

    	/* Process messages until the JVM terminates. 
    	   This launcher process must continue to process events until the JVM exits
    	   or else Windows 2K will hang if the desktop properties (e.g., background) are 
    	   changed by the user. Windows does a SendMessage() to every top level window 
    	   process, which blocks the caller until the process responds. */
   		while (jvmProcess != 0) 
   		{
   			GetMessage( &msg, NULL, 0, 0 );
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		
		/* Kill the timer. */
        KillTimer( topWindow, jvmExitTimerId );
	}
	
	/* Return the exit code from the JVM. */
	return jvmExitCode;
}

/* Local functions */
 
/* Detect JVM Process Termination */
static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime ) 
{
    DWORD   exitCode;
	
    /* If the JVM process has terminated */
    if (!GetExitCodeProcess( (HANDLE)jvmProcess, &exitCode ) || 
    		 exitCode != STILL_ACTIVE) 
    {
    	/* Save the JVM exit code. This should cause the loop in startJavaVM() to exit. */
        jvmExitCode = exitCode;
        jvmProcess = 0;
    }
}
 
/* Splash Timeout */
static void CALLBACK splashTimeout( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime ) 
{
	/* Kill the timer. */
    KillTimer( topWindow, id );
	PostMessage( topWindow, WM_QUIT, 0, 0 );
}


/* Load the splash image depending on the current locale.
 *
 * This is the search sequence for an USA english locale:
 * 
 *     1 - <homeDir>splash\en_US\<fileName>
 *     2 - <homeDir>splash\en\<fileName>
 *     3 - <homeDir>splash\<fileName>
 *
 * Returns an HBITMAP or NULL if the file can not be found.
 */
static HBITMAP loadSplashImage(char* baseDir, char *fileName) 
{
	HBITMAP hBitmap = NULL;
	LCID locale;
	char lang[4] = {0};
	char country[4] = {0};
	char *splashFile;

	locale = GetThreadLocale ();
	GetLocaleInfo(locale, LOCALE_SISO639LANGNAME, (LPTSTR) lang, 4);
	GetLocaleInfo(locale, LOCALE_SISO3166CTRYNAME, (LPTSTR) country, 4);
	
	splashFile = malloc ( strlen( baseDir ) + 256 );

    sprintf( splashFile, "%s\\splash\\%s_%s\\%s", baseDir, lang, country, fileName );
	hBitmap = LoadImage (NULL, splashFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	
	if (hBitmap == NULL) 
	{
		sprintf( splashFile, "%s\\splash\\%s\\%s", baseDir, lang, fileName );
		hBitmap = LoadImage (NULL, splashFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	}
    
	if (hBitmap == NULL) 
	{
		sprintf( splashFile, "%s\\splash\\%s", baseDir, fileName );
		hBitmap = LoadImage (NULL, splashFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	}

	free (splashFile);
	return hBitmap;
}


/* 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);
}