Logo Search packages:      
Sourcecode: galeon version File versions

galeon-automation.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 *  Copyright (C) 2000, 2001, 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-automation.h"
#include "galeon-shell.h"
#include "GaleonAutomation.h"
#include "galeon-embed.h"
#include "galeon-window.h"
#include "galeon-debug.h"
#include "gul-x11.h"

#include <string.h>
#include <bonobo/bonobo-generic-factory.h>
#include <bonobo/bonobo-main.h>
#include <bonobo/bonobo-context.h>

static void
galeon_automation_class_init (GaleonAutomationClass *klass);
static BonoboObject *
galeon_automation_factory (BonoboGenericFactory *this_factory,
                     const char *iid,
                     gpointer user_data);

static GObjectClass *galeon_automation_parent_class;

#define GALEON_FACTORY_OAFIID "OAFIID:GNOME_Galeon_Automation_Factory"

typedef struct {
      char *url;
      guint32 startup_id;
      guint open_in_existing_tab : 1;
      guint open_in_new_window : 1;
      guint open_in_new_tab : 1;
      guint fullscreen : 1;
      guint raise : 1;
} GaleonAutomationLoadurlData;

static GSList *postponed_loadurls = NULL;
static gboolean initialized = FALSE;

static BonoboObject *
galeon_automation_factory (BonoboGenericFactory *this_factory,
                     const char *iid,
                     gpointer user_data)
{
        GaleonAutomation *a;
        
        a  = g_object_new (GALEON_TYPE_AUTOMATION, NULL);

        return BONOBO_OBJECT(a);
}

BonoboGenericFactory *
galeon_automation_factory_new (void)
{
      BonoboGenericFactory   *factory;

      factory = bonobo_generic_factory_new (GALEON_FACTORY_OAFIID,
                                    galeon_automation_factory,
                                    NULL);

      if (factory == NULL)
      {
            g_warning ("Could not initialize GaleonAutomation factory");
      }
      
      return factory;
}

/**
 * galeon_automation_get_best_window:
 *
 * Loop throught the list of #GaleonWindow's stored in the #Session
 * and workout which is the best window to open a new tab in.
 * This will choose windows on the current workspace, followed
 * by windows on other workspaces. Windows on closer workspaces to
 * the current workspace are given priority.
 *
 * Inside a current workspace, we look at the state of windows and prefer:
 * 
 * on_top > fullscreen > maximised > normal > minimized
 *
 */
static GaleonWindow *
galeon_automation_get_best_window (gboolean only_current_workspace)
{
      gint best_score = G_MAXINT;
      GaleonWindow *best_window = NULL;
      Session *session;
      GList *li;

      session = galeon_shell_get_session (galeon_shell);
      
      for (li = session_get_windows (session); li ; li = li->next)
      {
            guint workspace, current;
            int score = 0;
            GdkWindowState state;
            GaleonWindow *window;

            window = li->data;

            g_return_val_if_fail (GALEON_IS_WINDOW (window), NULL);

            workspace = gul_x11_get_window_workspace (GTK_WINDOW (window));
            current   = gul_x11_get_current_workspace 
                              (gtk_widget_get_screen (GTK_WIDGET (window)));
            
            /* Ignore windows on different workspaces if we are told to */
            if (only_current_workspace &&
                workspace != GUL_X11_ALL_WORKSPACES &&
                workspace != current)
            {
                  continue;
            }

            /* FIXME: Ignore popup windows, but for this we need to add
             * properties to GaleonWindow to store the type of a window */

            /* Ignore chrome windows */
            if (galeon_window_get_chrome (window) & EMBED_CHROME_OPENASCHROME)
            {
                  continue;
            }

            /* Calculate the distance from the current workspace */
            if (workspace != GUL_X11_ALL_WORKSPACES)
            {
                  score += abs ((gint)current - (gint)workspace);
            }
            
            /* Prefer the windows on the current workspace */
            score *= 5;

            /* Add more scores based on the windows state */
            state = gdk_window_get_state (GTK_WIDGET (window)->window);

            if (state & GDK_WINDOW_STATE_ICONIFIED)
            {
                  score += 4;
            }
            else if (state & GDK_WINDOW_STATE_ABOVE)
            {
                  score += 0;
            }
            else if (state & GDK_WINDOW_STATE_FULLSCREEN)
            {
                  score += 1;
            }
            else if (state & GDK_WINDOW_STATE_MAXIMIZED)
            {
                  score += 2;
            }
            else
            {
                  score += 3;
            }

            /* Choose the window with the lowest score */
            if (score < best_score)
            {
                  best_score = score;
                  best_window = window;
            }
      }

      return best_window;
}


static void
galeon_automation_loadurl (const char *url,
                     gboolean fullscreen,
                     gboolean open_in_existing_tab,
                     gboolean open_in_new_window,
                     gboolean open_in_new_tab,
                     gboolean raise,
                     guint32 user_time)
{
      GaleonNewTabFlags flags = 0;
      const char *load_page = NULL;
      GaleonWindow *window;
      
      window = galeon_automation_get_best_window (!open_in_new_tab);
      
      if (open_in_existing_tab && window != NULL)
      {
            gul_x11_window_update_user_time (GTK_WIDGET (window), user_time);
            galeon_window_load_url (window, url);
            return;
      }
      
      if (*url == '\0')
      {
            flags = GALEON_NEW_TAB_HOMEPAGE;
      }
      else
      {
            load_page = url;
      }

      if (open_in_new_window)
      {
            flags |= GALEON_NEW_TAB_IN_NEW_WINDOW;
      }
      
      if (open_in_new_tab)
      {
            flags |= GALEON_NEW_TAB_IN_EXISTING_WINDOW;
      }

      if (fullscreen)
      {
            flags |= GALEON_NEW_TAB_FULLSCREEN;
      }
      
      if (raise)
      {
            flags |= GALEON_NEW_TAB_RAISE_WINDOW;
      }
      
      flags |= GALEON_NEW_TAB_APPEND;
      galeon_shell_new_tab_full (galeon_shell, window, NULL, load_page, 
                           flags, user_time);
}

static CORBA_boolean 
impl_galeon_automation_loadUrlWithStartupId (PortableServer_Servant _servant,
                                   const CORBA_char * url,
                                   const CORBA_char * geometry,
                                   const CORBA_boolean fullscreen,
                                   const CORBA_boolean open_in_existing_tab,
                                   const CORBA_boolean open_in_new_window,
                                   const CORBA_boolean open_in_new_tab,
                                   const CORBA_boolean raise,
                                   const CORBA_unsigned_long startup_id,
                                   CORBA_Environment * ev)
{
      if (initialized) {
            galeon_automation_loadurl (url, fullscreen, open_in_existing_tab,
                                 open_in_new_window, 
                                 open_in_new_tab, raise, startup_id);
      } else {
            GaleonAutomationLoadurlData *data = g_new (GaleonAutomationLoadurlData, 1);

            data->url                  = g_strdup (url);
            data->open_in_existing_tab = open_in_existing_tab;
            data->open_in_new_window   = open_in_new_window;
            data->open_in_new_tab      = open_in_new_tab;
            data->fullscreen           = fullscreen;
            data->raise                = raise;
            data->startup_id           = startup_id;

            postponed_loadurls = g_slist_prepend (postponed_loadurls, data);
      }
      return TRUE;
}

static CORBA_boolean 
impl_galeon_automation_loadurl (PortableServer_Servant _servant,
                        const CORBA_char * url,
                        const CORBA_char * geometry,
                        const CORBA_boolean fullscreen,
                        const CORBA_boolean open_in_existing_tab,
                        const CORBA_boolean open_in_new_window,
                        const CORBA_boolean open_in_new_tab,
                        const CORBA_boolean raise,
                        CORBA_Environment * ev)
{
      return impl_galeon_automation_loadUrlWithStartupId (_servant,
                                              url,
                                              geometry,
                                              fullscreen,
                                              open_in_existing_tab,
                                              open_in_new_window,
                                              open_in_new_tab,
                                              raise,
                                              0u,
                                              ev);
}


void
galeon_automation_complete_initialization (void)
{
      Session *session;

      session = galeon_shell_get_session (galeon_shell);

      /* no window open, let's try to autoresume */
      if (session_get_windows (session) == NULL)
      {
            SessionResumeType res;
            res = session_autoresume (session);

            /* Don't load any windows, the user wants to abort this
             * instance */
            if ( res == SESSION_ABORT ) {
                  GSList * iterator;
                  for( iterator = postponed_loadurls ; iterator ; iterator = iterator->next) {
                        GaleonAutomationLoadurlData *data = iterator->data;
                        g_free (data->url);
                        g_free (data);
                  }
                  g_slist_free (postponed_loadurls);
                  galeon_shell_set_server_mode (galeon_shell, FALSE);
                  return;
            }
            
            /* no need to open the homepage,
             * we did already open session windows */
            if (res == SESSION_RESUMED && postponed_loadurls) {
                  GSList *last = g_slist_last (postponed_loadurls);
                  GaleonAutomationLoadurlData *data = last->data;
                  if (data->url == NULL || *data->url == 0) {
                        postponed_loadurls = g_slist_delete_link (postponed_loadurls, last);
                        g_free (data->url);
                        g_free (data);
                  }
            }
      }
      while (postponed_loadurls) {
            GSList *internal_postponed, *iterator;

            internal_postponed = g_slist_reverse (postponed_loadurls);
            postponed_loadurls = NULL;

            for (iterator = internal_postponed; iterator; iterator = iterator->next) {
                  GaleonAutomationLoadurlData *data = iterator->data;
                  galeon_automation_loadurl (data->url,
                                       data->fullscreen,
                                       data->open_in_existing_tab,
                                       data->open_in_new_window,
                                       data->open_in_new_tab,
                                       data->raise,
                                       data->startup_id);
                  g_free (data->url);
                  g_free (data);
            }
            g_slist_free (internal_postponed);
      }
      initialized = TRUE;
}
       
static CORBA_boolean 
impl_galeon_automation_add_bookmark (PortableServer_Servant _servant,
                             const CORBA_char * url,
                             CORBA_Environment * ev)
{
      CORBA_boolean retval = TRUE;
      GbBookmarkSet *set;
      GbSite *b;

      g_return_val_if_fail (galeon_shell != NULL, FALSE);

      set = galeon_shell_get_bookmark_set (galeon_shell);
      g_return_val_if_fail (set, FALSE);

      b = gb_site_new (set, NULL, url);
      gb_bookmark_set_add_default (set, GB_BOOKMARK (b));

      return retval;
}

static CORBA_boolean
impl_galeon_automation_quit (PortableServer_Servant _servant,
                             const CORBA_boolean disableServer,
                             CORBA_Environment * ev)
{
      CORBA_boolean retval = TRUE;

      Session *session;

      g_object_ref (galeon_shell);

      session = galeon_shell_get_session (galeon_shell);
      
      session_close (session);

      if (disableServer)
      {
            galeon_shell_set_server_mode (galeon_shell, FALSE);
      }

      g_object_unref (galeon_shell);

      return retval;
}

static CORBA_boolean 
impl_galeon_automation_load_sessionWithStartupId (PortableServer_Servant _servant,
                                      const CORBA_char * filename,
                                      const CORBA_unsigned_long startup_id,
                                      CORBA_Environment * ev)
{
      CORBA_boolean retval = TRUE;
      Session *session;

      session = galeon_shell_get_session (galeon_shell);
      session_load (session, filename, startup_id);

      return retval;
}


static CORBA_boolean 
impl_galeon_automation_load_session (PortableServer_Servant _servant,
                             const CORBA_char * filename,
                             CORBA_Environment * ev)
{
      return impl_galeon_automation_load_sessionWithStartupId (_servant, filename, 0, ev);
}


static CORBA_boolean 
impl_galeon_automation_set_server_mode (PortableServer_Servant _servant,
                              const CORBA_boolean mode,
                              CORBA_Environment * ev)
{
      CORBA_boolean retval = TRUE;

      galeon_shell_set_server_mode (galeon_shell, mode ? TRUE : FALSE);

      return retval;
}

static void
galeon_automation_class_init (GaleonAutomationClass *klass)
{
        POA_GNOME_GaleonAutomation__epv *epv = &klass->epv;

        galeon_automation_parent_class = g_type_class_peek_parent (klass);

        /* connect implementation callbacks */
        epv->loadurl = impl_galeon_automation_loadurl;
      epv->addBookmark = impl_galeon_automation_add_bookmark;
      epv->quit = impl_galeon_automation_quit;
      epv->loadSession = impl_galeon_automation_load_session;
      epv->setServerMode = impl_galeon_automation_set_server_mode;
      epv->loadSessionWithStartupId = impl_galeon_automation_load_sessionWithStartupId;
      epv->loadurlWithStartupId = impl_galeon_automation_loadUrlWithStartupId;
}

static void
galeon_automation_init (GaleonAutomation *c) 
{
}

BONOBO_TYPE_FUNC_FULL (
        GaleonAutomation,                    
        GNOME_GaleonAutomation, 
        BONOBO_TYPE_OBJECT,           
        galeon_automation);

Generated by  Doxygen 1.6.0   Back to index