Logo Search packages:      
Sourcecode: netbook-launcher version File versions

main.c

/*
 * Copyright (C) 2008 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as 
 * published by the Free Software Foundation.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
 *
 */


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

#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gio.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <gtk/gtk.h>
#include <gdk/gdkx.h>

#include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>

#include "launcher-app.h"
#include "launcher-config.h"
#include "launcher-defines.h"

#define SYSTEM_FAV_MENU PKGDATADIR"/Favorites.menu"
#define LOCAL_FAV_DIR  ".config/menus/applications-merged"
#define LOCAL_FAV_MENU ".config/menus/applications-merged/Favorites.menu"

/* Forwards */
static void     set_window_hints (ClutterStage *stage);
static void     size_changed     (GdkScreen *screen, ClutterActor *app);
static void     on_system_resume (LauncherConfig *config);
static gboolean on_delete_event  (ClutterActor *stage, ClutterEvent *event);

static gboolean windowed = FALSE;
static gint     width    = 1024;
static gint     height   = 600;

static GOptionEntry entries[] =
{
  {
    "windowed",
    'w', 0,
    G_OPTION_ARG_NONE,
    &windowed,
    "Launch in windowed mode (for testing - 1024x600)",
    NULL
  },
  {
    "width",
    'd', 0,
    G_OPTION_ARG_INT,
    &width,
    "width",
    NULL
  },
  {
    "height",
    'h', 0,
    G_OPTION_ARG_INT,
    &height,
    "height",
    NULL
  },   {
    NULL
  }
};

gint
main (gint argc, gchar *argv[])
{
  ClutterActor *stage, *app;
  ClutterColor black = { 0x00, 0x00, 0x00, 0xff };
  LauncherConfig *cfg;
  GdkScreen *screen;
  GError *error = NULL;
  gchar *local_apps;

  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);

  g_thread_init (NULL);
  g_set_application_name ("Ubuntu Launcher");

  gtk_init (&argc, &argv);
  clutter_init_with_args (&argc, &argv,
                          " - Ubuntu Launcher", entries,
                          NULL,
                          &error);
  if (error)
  {
      g_print ("Unable to run Ubuntu Launcher: %s", error->message);
      g_error_free (error);
      return EXIT_FAILURE;
  }

  /* FIXME: Some tests that shouldn't be in here */
  local_apps = g_build_filename (g_get_home_dir (), 
                                 ".local", "share", "applications", NULL);
  if (!g_file_test (local_apps, G_FILE_TEST_EXISTS))
  {
    /* As the local application dir doesn't exist, we assume this is first
     * run
     */
    g_mkdir_with_parents (local_apps, 0700);
    g_debug ("Created local applications directory at %s", local_apps);
  }
  g_free (local_apps);
  
  local_apps = g_build_filename (g_get_home_dir (), 
                                 ".config", "netbook-launcher", "icons", NULL);
  if (!g_file_test (local_apps, G_FILE_TEST_EXISTS))
  {
    g_mkdir_with_parents (local_apps, 0700);
    g_debug ("Created local icons directory at %s", local_apps);
  }
  g_free (local_apps);

  local_apps = g_build_filename (g_get_home_dir (), LOCAL_FAV_MENU, NULL);
  if (!g_file_test (local_apps, G_FILE_TEST_EXISTS))
  {
    GFile *from, *to;
    gchar *temp = g_build_filename (g_get_home_dir (), LOCAL_FAV_DIR, NULL);
    g_mkdir_with_parents (temp, 0700);

    from = g_file_new_for_path (SYSTEM_FAV_MENU);
    to = g_file_new_for_path (local_apps);

    g_file_copy (from, to, 0, NULL, NULL, NULL, NULL);

    g_object_unref (from);
    g_object_unref (to);
  }

  /* This stuff does belong here */
  stage = clutter_stage_get_default ();
  screen = gdk_screen_get_default ();

  if (windowed)
  {
    clutter_actor_set_size (stage, width, height);
    clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
    g_setenv ("LAUNCHER_WINDOWED", "1", TRUE);
  }
  else
  {
    clutter_actor_set_size (stage,
                          gdk_screen_get_width (screen),
                          gdk_screen_get_height(screen));
    set_window_hints (CLUTTER_STAGE (stage));
  }
  clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
  clutter_stage_set_use_fog (CLUTTER_STAGE (stage), FALSE);
  if (!windowed)
    g_signal_connect (stage, "event", G_CALLBACK (on_delete_event), NULL);

  /* Init() the main application */
  app = launcher_app_get_default ();

  cfg = launcher_config_get_default ();
  g_signal_connect (screen, "size-changed", 
                    G_CALLBACK (size_changed), app);
  g_signal_connect (cfg, "resume-event",
                    G_CALLBACK (on_system_resume), NULL);
 
  clutter_actor_show (stage);
  clutter_main ();  
  
  if (windowed)
    g_setenv ("LAUNCHER_WINDOWED", "0", TRUE);

  return EXIT_SUCCESS;
}

static gboolean
on_delete_event (ClutterActor *stage, ClutterEvent *event)
{
  if (event->type == CLUTTER_DELETE)
  {
    g_print ("Delete event\n");
    return TRUE;
  }
  return FALSE;
}

/*
 * Apply the 'desktop' window type to the clutter-stage window. Also, set the
 * 'panel' hints, to stop the windows from maximising the entire way.
 */
static void
set_window_hints (ClutterStage *stage)
{
  GdkDisplay *display = gdk_display_get_default (); 
  GtkIconTheme *theme;
  Display *xdisplay;
  Window stage_win;
  Atom atom;
  GdkPixbuf *pixbuf;
  GdkWindow *window;
  GList *list = NULL;
    
  xdisplay = GDK_DISPLAY_XDISPLAY (display);
  stage_win = clutter_x11_get_stage_window (stage);

  /* 
   * Make the clutter window a 'desktop' window, i.e maximised, but behind 
   * everything else
   */
  atom = gdk_x11_get_xatom_by_name_for_display (display,
                                                "_NET_WM_WINDOW_TYPE_DESKTOP");
  XChangeProperty (xdisplay, stage_win,
                   gdk_x11_get_xatom_by_name_for_display (display,
                                                "_NET_WM_WINDOW_TYPE"),
                   XA_ATOM , 32, PropModeReplace, 
                   (guchar *)&atom, 1);

  /*
   * The window icon 
   */
  theme = gtk_icon_theme_get_default ();
  pixbuf = gtk_icon_theme_load_icon (theme, "distributor-logo", 48, 0, NULL);
  list = g_list_append (list, pixbuf);
  window = gdk_window_foreign_new (stage_win);
  gdk_window_set_icon_list (window, list);

  gdk_window_set_title (window, _("Home"));
}


static void
restart_launcher ()
{
  gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
                                    "netbook-launcher", NULL);
  clutter_main_quit ();
}

static void
on_system_resume (LauncherConfig *config)
{
  restart_launcher ();
}

/*
 * What happens when the stage changes size 
 */
static void    
size_changed (GdkScreen    *screen,
              ClutterActor *app)
{
  static gboolean already_called = FALSE;

  if (CSW () == gdk_screen_get_width (screen) 
      && CSH () == gdk_screen_get_height (screen))
    return;

  if (already_called)
    return;

  already_called = TRUE;
  restart_launcher ();
}

Generated by  Doxygen 1.6.0   Back to index