| #include "installOS.h" | |
| #include <signal.h> | |
| #include <unistd.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <sys/wait.h> | |
| #include <sys/ioctl.h> | |
| #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 dirSeparator = '/'; | |
| char pathSeparator = ':'; | |
| char* consoleVM = "java"; | |
| char* defaultVM = "java"; | |
| char* shippedVMDir = "jre/bin/"; | |
| /* Define the special arguments for the various Java VMs. */ | |
| static char* argVM_JAVA[] = { NULL }; | |
| /* Define local variables . */ | |
| static int saveArgc = 0; | |
| static char** saveArgv = 0; | |
| static gboolean gtkInitialized = FALSE; | |
| static GtkWidget *label = NULL, *progress = NULL; | |
| static GdkColor foreground = {0, 0, 0, 0}; | |
| static GdkRectangle progressRect = {0, 0, 0, 0}, messageRect = {0, 0, 0, 0}; | |
| static int value = 0, maximum = 100; | |
| /* Local functions */ | |
| static gboolean splashTimeout(gpointer data); | |
| #ifdef MOZILLA_FIX | |
| static void fixEnvForMozilla(); | |
| #endif /* MOZILLA_FIX */ | |
| /* Display a Message */ | |
| void displayMessage(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_dialog_run(GTK_DIALOG (dialog)); | |
| gtk_widget_destroy(dialog); | |
| } | |
| /* Initialize the Window System */ | |
| void initWindowSystem(int* pArgc, char* argv[], int showSplash) | |
| { | |
| /* Save the arguments in case displayMessage() is called in the main launcher. */ | |
| if (saveArgv == 0) | |
| { | |
| saveArgc = *pArgc; | |
| saveArgv = argv; | |
| } | |
| /* If the splash screen is going to be displayed by this process */ | |
| if (showSplash) | |
| { | |
| /* Initialize GTK. */ | |
| gtk_set_locale(); | |
| gtk_init(pArgc, &argv); | |
| gdk_set_program_class(officialName); | |
| gtkInitialized = TRUE; | |
| } | |
| } | |
| static void readRect(char *str, GdkRectangle *rect) { | |
| int x, y, width, height; | |
| char *temp = str, *comma; | |
| comma = strchr(temp, ','); | |
| if (comma == NULL) return; | |
| comma[0] = 0; | |
| x = atoi(temp); | |
| temp = comma + 1; | |
| comma = strchr(temp, ','); | |
| if (comma == NULL) return; | |
| comma[0] = 0; | |
| y = atoi(temp); | |
| temp = comma + 1; | |
| comma = strchr(temp, ','); | |
| if (comma == NULL) return; | |
| comma[0] = 0; | |
| width = atoi(temp); | |
| temp = comma + 1; | |
| height = atoi(temp); | |
| rect->x = x; | |
| rect->y = y; | |
| rect->width = width; | |
| rect->height = height; | |
| } | |
| static void readColor(char *str, GdkColor *color) { | |
| int value = atoi(str); | |
| color->red = ((value & 0xFF0000) >> 16) * 0xFF; | |
| color->green = ((value & 0xFF00) >> 8) * 0xFF; | |
| color->blue = ((value & 0xFF) >> 0) * 0xFF; | |
| } | |
| static void readInput() { | |
| int available; | |
| FILE *fd = stdin; | |
| char *buffer = NULL, *equals = NULL, *end, *line; | |
| ioctl(fileno(fd), FIONREAD, &available); | |
| if (available <= 0) return; | |
| buffer = malloc(available + 1); | |
| available = fread(buffer, 1, available, fd); | |
| buffer[available] = 0; | |
| line = buffer; | |
| while (line != NULL) { | |
| end = strchr(line, '\n'); | |
| equals = strchr(line, '='); | |
| if (end != NULL) end[0] = 0; | |
| if (equals != NULL) { | |
| char *str = (char *)equals + 1; | |
| equals[0] = 0; | |
| if (strcmp(line, "maximum") == 0) { | |
| maximum = atoi(str); | |
| if (progress) { | |
| double fraction = maximum == 0 ? 1 : (double)(value / maximum); | |
| gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), fraction); | |
| } | |
| } else if (strcmp(line, "value") == 0) { | |
| value = atoi(str); | |
| if (progress) { | |
| double fraction = maximum == 0 ? 1 : (double)value / maximum; | |
| gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), fraction); | |
| } | |
| } else if (strcmp(line, "progressRect") == 0) { | |
| readRect(str, &progressRect); | |
| if (progress) { | |
| gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(progress)), progress, progressRect.x, progressRect.y); | |
| gtk_widget_set_size_request(GTK_WIDGET(progress), progressRect.width, progressRect.height); | |
| } | |
| } else if (strcmp(line, "messageRect") == 0) { | |
| readRect(str, &messageRect); | |
| if (label) { | |
| gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(label)), label, messageRect.x, messageRect.y); | |
| gtk_widget_set_size_request(GTK_WIDGET(label), messageRect.width, messageRect.height); | |
| } | |
| } else if (strcmp(line, "foreground") == 0) { | |
| readColor(str, &foreground); | |
| if (label) { | |
| gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &foreground); | |
| } | |
| } else if (strcmp(line, "message") == 0) { | |
| if (label) { | |
| gtk_label_set_text(GTK_LABEL(label), str); | |
| } | |
| } | |
| } | |
| if (end != NULL) line = end + 1; | |
| else line = NULL; | |
| } | |
| free(buffer); | |
| } | |
| static gboolean timerProc(gpointer data) { | |
| readInput(); | |
| return TRUE; | |
| } | |
| /* Create and DIsplay the Splash Window */ | |
| int showSplash( char* timeoutString, char* featureImage ) | |
| { | |
| GdkPixbuf* imageData = NULL; | |
| GtkWidget* image, *fixed; | |
| GtkWindow* main; | |
| int timeout = 0; | |
| /* Determine the splash timeout value (in seconds). */ | |
| if (timeoutString != NULL && strlen( timeoutString ) > 0) | |
| { | |
| sscanf( timeoutString, "%d", &timeout ); | |
| } | |
| /* Load the feature specific splash image data if defined. */ | |
| if (featureImage != NULL) | |
| { | |
| imageData = gdk_pixbuf_new_from_file(featureImage, NULL); | |
| } | |
| /* If the splash image data could not be loaded, return an error. */ | |
| if (imageData == NULL) | |
| return ENOENT; | |
| /* Create the image from its data. */ | |
| fixed = gtk_fixed_new(); | |
| image = gtk_image_new_from_pixbuf(imageData); | |
| label = gtk_label_new(""); | |
| progress = gtk_progress_bar_new(); | |
| /* Create a top level window for the image. */ | |
| main = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); | |
| gtk_window_set_title(main, officialName); | |
| gtk_container_add(GTK_CONTAINER(main), GTK_WIDGET(fixed)); | |
| gtk_container_add(GTK_CONTAINER(fixed), GTK_WIDGET(image)); | |
| gtk_container_add(GTK_CONTAINER(fixed), GTK_WIDGET(label)); | |
| gtk_container_add(GTK_CONTAINER(fixed), GTK_WIDGET(progress)); | |
| gtk_misc_set_alignment (GTK_MISC(label), 0.0f, 0.0f); | |
| gtk_label_set_justify (GTK_LABEL(label), GTK_JUSTIFY_LEFT); | |
| gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &foreground); | |
| readInput(); | |
| gtk_timeout_add(50, timerProc, NULL); | |
| gtk_fixed_move(GTK_FIXED(fixed), label, messageRect.x, messageRect.y); | |
| gtk_widget_set_size_request(GTK_WIDGET(label), messageRect.width, messageRect.height); | |
| gtk_fixed_move(GTK_FIXED(fixed), progress, progressRect.x, progressRect.y); | |
| gtk_widget_set_size_request(GTK_WIDGET(progress), progressRect.width, progressRect.height); | |
| gtk_widget_set_size_request(GTK_WIDGET(fixed), gdk_pixbuf_get_width(imageData), gdk_pixbuf_get_height(imageData)); | |
| /* Remove window decorations and centre the window on the display. */ | |
| gtk_window_set_decorated(main, FALSE); | |
| gtk_window_set_position(main, GTK_WIN_POS_CENTER); | |
| gtk_window_set_resizable(main, FALSE); | |
| /* Set the background pixmap to NULL to avoid a gray flash when the image appears. */ | |
| gtk_widget_realize(GTK_WIDGET(main)); | |
| gdk_window_set_back_pixmap(GTK_WIDGET(main)->window, NULL, FALSE); | |
| /* If a timeout for the splash window was given */ | |
| if (timeout != 0) | |
| { | |
| /* Add a timeout (in milliseconds) to bring down the splash screen. */ | |
| gtk_timeout_add((timeout * 1000), splashTimeout, (gpointer) main); | |
| } | |
| /* Show the window and wait for the timeout (or until the process is terminated). */ | |
| gtk_widget_show_all(GTK_WIDGET (main)); | |
| gtk_main (); | |
| label = progress = NULL; | |
| return 0; | |
| } | |
| /* Get the window system specific VM arguments */ | |
| char** getArgVM( char* vm ) | |
| { | |
| char** result; | |
| char* version; | |
| /* Use the default arguments for a standard Java VM */ | |
| result = argVM_JAVA; | |
| return result; | |
| } | |
| /* 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 jvmExitCode = 1; | |
| pid_t jvmProcess; | |
| int exitCode; | |
| #ifdef MOZILLA_FIX | |
| fixEnvForMozilla(); | |
| #endif /* MOZILLA_FIX */ | |
| 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. */ | |
| _exit(errno); | |
| } | |
| /* If the JVM is still running, wait for it to terminate. */ | |
| if (jvmProcess != 0) | |
| { | |
| wait(&exitCode); | |
| if (WIFEXITED(exitCode)) | |
| jvmExitCode = WEXITSTATUS(exitCode); | |
| } | |
| return jvmExitCode; | |
| } | |
| /* Splash Timeout - Hide the main window and exit the main loop. */ | |
| static gboolean splashTimeout(gpointer data) | |
| { | |
| GtkWidget* main = GTK_WIDGET(data); | |
| gtk_widget_hide(main); | |
| gtk_main_quit(); | |
| return FALSE; | |
| } | |
| /* 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. | |
| */ | |
| #ifdef MOZILLA_FIX | |
| 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 */ | |
| char *XPCOM_LIB = "libxpcom.so"; | |
| 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); | |
| } | |
| } | |
| 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 */ | |
| _TCHAR* getTempPath() | |
| { | |
| _TCHAR* buffer = malloc(MAX_PATH*sizeof(_TCHAR)); | |
| _TCHAR* tmp; | |
| tmp = _ttempnam(_T_INSTALL("/tmp"),_T_INSTALL("_RITMP")); | |
| _tcscpy(buffer,tmp); | |
| _tcscat(buffer,_T_INSTALL("/")); | |
| free(tmp); | |
| return buffer; | |
| } |