Logo Search packages:      
Sourcecode: galeon version File versions

galeon-main.c

/*
 *  Copyright (C) 2000-2002 Marco Pesenti Gritti
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "galeon-shell.h"
#include "galeon-automation.h"
#include "galeon-window.h"
#include "gul-state.h"
#include "galeon-debug.h"
#include "gul-x11.h"
#include "hig-alert.h"
#include "GaleonAutomation.h"

#include <libbonoboui.h>
#include <libgnome/gnome-program.h>
#include <libgnomeui/gnome-ui-init.h>
#include <libgnomeui/gnome-app-helper.h>
#include <libgnomevfs/gnome-vfs-init.h>
#include <gtk/gtkwindow.h>
#include <gdk/gdkx.h>
#include <string.h>
#ifdef ENABLE_NLS
# include <locale.h>
#endif

#define GALEON_FACTORY_OAFIID "OAFIID:GNOME_Galeon_Automation_Factory"

static gint
galeon_main_translate_url_arguments (poptContext context, gchar ***urls);
static void
galeon_main_start (guint32 user_time);

/* FIXME */
CORBA_Environment corba_env;              /* Global for downloader      */
static gboolean open_in_existing      = FALSE;  /* load in existing window?     */
static gboolean open_in_new_tab       = FALSE;  /* force open in a new tab?     */
static gboolean noraise               = FALSE;  /* no raise                     */
static gboolean open_in_new_window    = FALSE;  /* force open in a new window?  */
static gboolean open_fullscreen       = FALSE;  /* open galeon in full screen ? */
static gchar   *session_filename      = NULL;   /* the session filename         */
static gchar   *geometry_string       = NULL;   /* the geometry string          */
static gchar   *bookmark_url          = NULL;   /* the temp bookmark to add     */
static gboolean close_option          = FALSE;  /* --close                      */
static gboolean quit_option           = FALSE;  /* --quit                       */
static gboolean galeon_server_mode    = FALSE;
static gboolean open_as_nautilus_view = FALSE;

static gint n_urls; 
static gchar **url;

/* command line argument parsing structure */
static struct poptOption popt_options[] =
{
      { NULL, '\0', POPT_ARG_INCLUDE_TABLE, &bonobo_activation_popt_options, 0, NULL,
        NULL },
      { "new-tab", 'n', POPT_ARG_NONE, &open_in_new_tab, 0,
        N_("Open a new tab in an existing Galeon window"),
        NULL },
      { "new-window", 'w', POPT_ARG_NONE, &open_in_new_window, 0,
        N_("Open a new window in an existing Galeon process"),
        NULL },
      { "noraise", '\0', POPT_ARG_NONE, &noraise, 0,
        N_("Do not raise the window when opening a page in an existing Galeon process"),
        NULL },
      { "fullscreen", 'f', POPT_ARG_NONE, &open_fullscreen, 0,
        N_("Run Galeon in full screen mode"),
        NULL },
      { "existing", 'x', POPT_ARG_NONE, &open_in_existing, 0,
        N_("Attempt to load URL in existing Galeon window"),
        NULL },
      { "load-session", 'l', POPT_ARG_STRING, &session_filename, 0,
        N_("Load the given session file"),
        N_("FILE") },
      { "server", 's', POPT_ARG_NONE, &galeon_server_mode, 0,
        N_("Don't open any windows; instead act as a server "
           "for quick startup of new Galeon instances"),
        NULL },           
      { "add-bookmark", 't', POPT_ARG_STRING, &bookmark_url,
        0, N_("Add a bookmark (don't open any window)"), 
        N_("URL")},
      { "geometry", 'g', POPT_ARG_STRING, &geometry_string,
        0, N_("Create the initial window with the given geometry, "
            "see X(1) for the GEOMETRY format"),
        N_("GEOMETRY")},
      { "close", 'c', POPT_ARG_NONE, &close_option, 0,
        N_("Close all Galeon windows"),
        NULL },
      { "quit", 'q', POPT_ARG_NONE, &quit_option, 0,
        N_("Same as --close, but exits server mode too"),
        NULL },
#ifdef ENABLE_NAUTILUS_VIEW
      { "nautilus-view", 'v', POPT_ARG_NONE, &open_as_nautilus_view, 0,
        N_("Used internally by the nautilus view"),
        NULL },
#endif

      /* terminator, must be last */
      { NULL, 0, 0, NULL, 0, NULL, NULL }
};

static void
default_window_icon_init (void)
{
      GdkPixbuf * icon;
      GList *icon_list = NULL;

      icon = gdk_pixbuf_new_from_file (DATADIR "/pixmaps/galeon.png", NULL);
      if (icon)
      {
            icon_list = g_list_prepend (icon_list, icon);

            gtk_window_set_default_icon_list (icon_list);
            
            g_object_unref (icon);
            g_list_free (icon_list);
      }
}


static gboolean
unref_when_idle (gpointer user_data)
{
      g_object_unref (user_data);
      return FALSE;
}

/* Copied from libnautilus/nautilus-program-choosing.c; Needed in case
 * we have no DESKTOP_STARTUP_ID (with its accompanying timestamp).
 */
static Time
slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
{
      Window xwindow;
      XEvent event;
      
      {
            XSetWindowAttributes attrs;
            Atom atom_name;
            Atom atom_type;
            char* name;
            
            attrs.override_redirect = True;
            attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
            
            xwindow =
                  XCreateWindow (xdisplay,
                               RootWindow (xdisplay, 0),
                               -100, -100, 1, 1,
                               0,
                               CopyFromParent,
                               CopyFromParent,
                               CopyFromParent,
                               CWOverrideRedirect | CWEventMask,
                               &attrs);
            
            atom_name = XInternAtom (xdisplay, "WM_NAME", TRUE);
            g_assert (atom_name != None);
            atom_type = XInternAtom (xdisplay, "STRING", TRUE);
            g_assert (atom_type != None);
            
            name = "Fake Window";
            XChangeProperty (xdisplay, 
                         xwindow, atom_name,
                         atom_type,
                         8, PropModeReplace, name, strlen (name));
      }
      
      XWindowEvent (xdisplay,
                  xwindow,
                  PropertyChangeMask,
                  &event);
      
      XDestroyWindow(xdisplay, xwindow);
      
      return event.xproperty.time;
}

int
main (int argc, char *argv[])
{
      poptContext context;
        GValue context_as_value = { 0 };
      GnomeProgram *program;
      CORBA_Object factory;
      guint32 user_time;

#ifdef ENABLE_NLS
      /* Initialize the i18n stuff */
      setlocale(LC_ALL, "");
      bindtextdomain(GETTEXT_PACKAGE, DATADIR "/locale");
      textdomain(GETTEXT_PACKAGE);
#endif
      /* set the application name manually until gnome handles the
       * GNOME_PARAM_HUMAN_READABLE_NAME in a sane fashion */
      g_set_application_name (_("Galeon"));

      /* get this early, since gdk will unset the env var */
      user_time = gul_x11_get_startup_id ();

      program = gnome_program_init (PACKAGE, VERSION,
                                      LIBGNOMEUI_MODULE, argc, argv,
                                      GNOME_PARAM_POPT_TABLE, popt_options,
                                      GNOME_PARAM_HUMAN_READABLE_NAME, _("Galeon"),
                              GNOME_PARAM_APP_DATADIR, DATADIR,
                                      NULL);

      /* Get a timestamp manually if need be */
      if (user_time == 0)
            user_time = slowly_and_stupidly_obtain_timestamp (gdk_display);        
#ifdef ENABLE_NLS
      bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
#endif

        g_object_get_property (G_OBJECT (program),
                               GNOME_PARAM_POPT_CONTEXT,
                               g_value_init (&context_as_value, G_TYPE_POINTER));

        context = g_value_get_pointer (&context_as_value);

      /* load arguments that aren't regular options (urls to load) */
        n_urls = galeon_main_translate_url_arguments (context, &url);

      g_value_unset (&context_as_value);

      factory = bonobo_activation_activate_from_id 
            (GALEON_FACTORY_OAFIID,
             Bonobo_ACTIVATION_FLAG_EXISTING_ONLY, 
             NULL, NULL);

      if (factory != NULL)
      {
            /* Connect to existing instance */
            galeon_main_start (user_time);
            gdk_notify_startup_complete ();
      }
      else
      {
            galeon_debug_init ();

            gul_state_init ();
            
            gnome_vfs_init ();
            
            default_window_icon_init ();
            
            galeon_shell_new ();
            
            /* Gdk will handle the user time itself */
            galeon_main_start (0u);

            /* Flush any pending GTK events, this works around crashes when
             * it takes a long time to startup. */
            while (gtk_events_pending())
                  gtk_main_iteration();
            
            galeon_automation_complete_initialization ();
            
            g_idle_add (unref_when_idle, galeon_shell);
            
            bonobo_main ();
            
            gul_state_shutdown ();

            gnome_accelerators_sync ();

            gnome_vfs_shutdown ();
      } 

      return 0;
}

static void
galeon_main_start (guint32 user_time)
{
      GNOME_GaleonAutomation gaserver;
      int i;

      CORBA_exception_init (&corba_env);
      
      gaserver = bonobo_activation_activate_from_id ("OAFIID:GNOME_Galeon_Automation",
                                           0, NULL, &corba_env);
      
      if (corba_env._major != CORBA_NO_EXCEPTION)
      {
            g_warning ("Error: unable to initialize corba: %s\n", 
                     CORBA_exception_id (&corba_env));
      } 

      if (gaserver == NULL)
      {
            /* At this point the galeon_shell will have initialized the
             * AutomationFactory, that obviously worked, so the .server file
             * exists, therefore this was probably because a previous instance
             * locked up */

            GtkWidget *dialog;
            dialog = hig_alert_new (NULL,
                              GTK_DIALOG_MODAL,
                              HIG_ALERT_ERROR,
                              _("Galeon failed to start."),
                              _("The existing Galeon instance is not responding. "
                                "Terminating the <tt>\"galeon\"</tt> processes "
                                "may fix the problem."),
                              GTK_STOCK_OK,
                              GTK_RESPONSE_OK,
                              NULL);
            gtk_dialog_run (GTK_DIALOG (dialog));
            gtk_widget_destroy (dialog);
            exit(1);
      }
      /* Server mode */
      if (galeon_server_mode && !close_option)
      {
            GNOME_GaleonAutomation_setServerMode (gaserver, TRUE, &corba_env);
      }

      /* load the session if requested */
      if (session_filename)
      {
            GNOME_GaleonAutomation_loadSessionWithStartupId
                  (gaserver, session_filename, user_time, &corba_env);
      }
      /* if found and we're given a bookmark to add... */
      else if (bookmark_url != NULL)
      {
            GNOME_GaleonAutomation_addBookmark 
                  (gaserver, bookmark_url, &corba_env);
      }
      else if (close_option || quit_option)
      {
            GNOME_GaleonAutomation_quit 
                  (gaserver, quit_option, &corba_env);
      }
      /* provided with urls? */
      else if (n_urls == 0 && 
             !open_as_nautilus_view &&
             !galeon_server_mode)
      {
            /* no, open a default window */
            GNOME_GaleonAutomation_loadurlWithStartupId 
                  (gaserver, "",
                   geometry_string ?
                   geometry_string : "",
                   open_fullscreen,
                   open_in_existing,
                   open_in_new_window,
                   open_in_new_tab,
                   !noraise,
                   user_time,
                   &corba_env);
      }
      else
      {
            /* open all of the urls */
            for (i = 0; i < n_urls; i++)
            {
                  GNOME_GaleonAutomation_loadurlWithStartupId
                        (gaserver, url[i],
                         geometry_string ?
                         geometry_string : "",
                         open_fullscreen,
                         open_in_existing,
                         open_in_new_window,
                         open_in_new_tab,
                         !noraise,
                         user_time,
                         &corba_env);
            }
      }

      if (gaserver)
      {
            bonobo_object_release_unref (gaserver, &corba_env);
      }

      CORBA_exception_free (&corba_env);
}

/**
 * translate_url_arguments: gather URL arguments and expand them fully
 * with realpath if they're filenames
 */
static gint
galeon_main_translate_url_arguments (poptContext context, gchar ***urls)
{
        gchar buffer[PATH_MAX];
        gchar **args;
        gint i, n;

        /* any context remaining? */
        if (context == NULL)
        {
                *urls = NULL;
                return 0;
        }

        /* get the args and check */
        args = (gchar **) poptGetArgs (context);
        if (args == NULL)
        {
                poptFreeContext (context);
                *urls = NULL;
                return 0;
        }

        /* count args */
        for (n = 0; args[n] != NULL; n++)
                /* nothing */;

        /* allocate pointer array */
        *urls = g_new0 (gchar *, n + 1);
        
        /* translate each one */
        for (i = 0; i < n; i++)
        {
                /* try to expand as files */
                if (realpath (args[i], buffer) != NULL)
                {
                        (*urls)[i] = g_strconcat ("file://", buffer, NULL);
                }
                else
                {
                        (*urls)[i] = g_strdup (args[i]);
                }
        }
        poptFreeContext (context);
        (*urls)[i] = NULL;

        /* return the number of urls */
        return n;
}

Generated by  Doxygen 1.6.0   Back to index