[maemo-commits] [maemo-commits] r8839 - in projects/haf/branches/maemo-af-desktop/hildon-desktop: . background-manager
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Wed Dec 20 15:02:11 EET 2006
- Previous message: [maemo-commits] r8838 - in projects/haf/trunk/hildon-theme-layout-3: . rc
- Next message: [maemo-commits] r8840 - in projects/haf/branches/gtk+/maemo-gtk-2-10: . gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: jobi Date: 2006-12-20 15:02:10 +0200 (Wed, 20 Dec 2006) New Revision: 8839 Added: projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/ projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/Makefile.am projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.c projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.h projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.xml projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/main.c Modified: projects/haf/branches/maemo-af-desktop/hildon-desktop/Makefile.am projects/haf/branches/maemo-af-desktop/hildon-desktop/configure.ac Log: 2006-12-19 Johan Bilien <johan.bilien at nokia.com> * background-manager/*: - added - simple and dummy DBus service to composite and set the background Modified: projects/haf/branches/maemo-af-desktop/hildon-desktop/Makefile.am =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/Makefile.am 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/Makefile.am 2006-12-20 13:02:10 UTC (rev 8839) @@ -1 +1 @@ -SUBDIRS = data libhildonwm libhildondesktop src +SUBDIRS = data libhildonwm libhildondesktop background-manager src Added: projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/Makefile.am =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/Makefile.am 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/Makefile.am 2006-12-20 13:02:10 UTC (rev 8839) @@ -0,0 +1,26 @@ +bin_PROGRAMS = hildon-background-manager + +BUILT_SOURCES = background-manager-glue.h +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = background-manager.xml + +background-manager-glue.h: + $(LIBTOOL) --mode=execute $(DBUS_BINDING_TOOL) --prefix=background_manager \ + --mode=glib-server --output=background-manager-glue.h \ + background-manager.xml + +hildon_background_manager_CPPFLAGS = @GNOME_VFS_CFLAGS@ \ + @GCONF_CFLAGS@ \ + @DBUS_GLIB_CFLAGS@ \ + @OSSO_CFLAGS@ \ + @GTK_CFLAGS@ +hildon_background_manager_LDFLAGS = @GNOME_VFS_LIBS@ \ + @GCONF_LIBS@ \ + @DBUS_GLIB_LIBS@ \ + @OSSO_LIBS@ \ + @GTK_LIBS@ + +hildon_background_manager_SOURCES = $(BUILT_SOURCES) \ + background-manager.c \ + background-manager.h \ + main.c Added: projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.c =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.c 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.c 2006-12-20 13:02:10 UTC (rev 8839) @@ -0,0 +1,929 @@ +/* -*- mode:C; c-file-style:"gnu"; -*- */ +/* + * This file is part of maemo-af-desktop + * + * Copyright (C) 2006 Nokia Corporation. + * + * Contact: Karoliina Salminen <karoliina.t.salminen at nokia.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "background-manager.h" +#include "background-manager-glue.h" + +#include <gdk-pixbuf/gdk-pixbuf.h> + +/*SAW (allocation watchdog facilities)*/ +#include <osso-mem.h> + +#include <libgnomevfs/gnome-vfs.h> +#include <gconf/gconf-client.h> + +#include <hildon-widgets/hildon-banner.h> +#include <hildon-widgets/hildon-note.h> + + +#define HILDON_HOME_IMAGE_FORMAT "png" +#define HILDON_HOME_IMAGE_ALPHA_FULL 255 +#define HILDON_HOME_GCONF_MMC_COVER_OPEN "/system/osso/af/mmc-cover-open" +#define HILDON_HOME_TASKNAV_WIDTH 80 +#define HILDON_HOME_TITLEBAR_HEIGHT 60 + +#define HILDON_HOME_ENV_MMC_MOUNTPOINT "MMC_MOUNTPOINT" + + +GQuark +background_manager_error_quark (void) +{ + return g_quark_from_static_string ("background-manager-error-quark"); +} + +GType +background_mode_get_type (void) +{ + static GType etype = 0; + + if (!etype) + { + static const GEnumValue values[] = + { + { BACKGROUND_CENTERED, "BACKGROUND_CENTERED", "centered" }, + { BACKGROUND_SCALED, "BACKGROUND_SCALED", "scaled" }, + { BACKGROUND_STRETCHED, "BACKGROUND_STRETCHED", "stretched" }, + { BACKGROUND_TILED, "BACKGROUND_TILED", "tiled" }, + { 0, NULL, NULL } + }; + + etype = g_enum_register_static ("BackgroundMode", values); + } + + return etype; +} + +#define BACKGROUND_MANAGER_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_BACKGROUND_MANAGER, BackgroundManagerPrivate)) + +typedef struct _BackgroundData +{ + gchar *image_uri; + gchar *left_bar; + gchar *top_bar; + GdkColor *color; + GdkWindow *window; +} BackgroundData; + +struct _BackgroundManagerPrivate +{ + BackgroundData *current; + + guint is_screen_singleton : 1; + GdkScreen *screen; + + guint bg_timeout; + guint loading_note_update_timeout; + GtkWidget *loading_note; +}; + +static BackgroundData * +background_data_new () +{ + BackgroundData *data; + + data = g_new0 (BackgroundData, 1); + data->color = g_new0 (GdkColor, 1); + return data; +} + +static void +background_data_free (BackgroundData *data) +{ + g_free (data->color); + g_free (data); +} + +G_DEFINE_TYPE (BackgroundManager, background_manager, G_TYPE_OBJECT); + +static void +background_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +background_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +background_manager_finalize (GObject *object) +{ + BackgroundManager *manager = BACKGROUND_MANAGER (object); + BackgroundManagerPrivate *priv = manager->priv; + + background_data_free (priv->current); + priv->current = NULL; + + G_OBJECT_CLASS (background_manager_parent_class)->finalize (object); +} + +static void +load_image_oom_cb (size_t current_size, + size_t max_size, + void *context) +{ + *(gboolean *) context = TRUE; +} + +#define BUFFER_SIZE 8192 + +static GdkPixbuf * +load_image_from_uri (const gchar *uri, + gboolean oom_check, + gboolean cancellable, + GError **error) +{ + GConfClient *client; + GdkPixbufLoader *loader; + GdkPixbuf *retval = NULL; + GnomeVFSHandle *handle = NULL; + GnomeVFSResult result; + guchar buffer[BUFFER_SIZE]; + gchar *mmc_mount_point; + gboolean image_from_mmc = FALSE; + gboolean mmc_cover_open = FALSE; + gboolean oom = FALSE; + + g_return_val_if_fail (uri != NULL, NULL); + + client = gconf_client_get_default (); + g_assert (GCONF_IS_CLIENT (client)); + + mmc_mount_point = g_strconcat ("file://", + g_getenv (HILDON_HOME_ENV_MMC_MOUNTPOINT), + NULL); + if (g_str_has_prefix (uri, mmc_mount_point)) + { + GError *gconf_error = NULL; + + image_from_mmc = TRUE; + + mmc_cover_open = gconf_client_get_bool (client, + HILDON_HOME_GCONF_MMC_COVER_OPEN, + &gconf_error); + if (gconf_error) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_SYSTEM_RESOURCES, + "Unable to check key `%s' from GConf: %s", + HILDON_HOME_GCONF_MMC_COVER_OPEN, + gconf_error->message); + + g_error_free (gconf_error); + g_object_unref (client); + + return NULL; + } + + if (mmc_cover_open) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_MMC_OPEN, + "MMC cover is open"); + + g_object_unref (client); + + return NULL; + } + } + + g_free (mmc_mount_point); + + result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_UNREADABLE, + "Unable to open `%s': %s", + uri, + gnome_vfs_result_to_string (result)); + + g_object_unref (client); + + return NULL; + } + + if (!oom_check && + osso_mem_saw_enable (3 << 20, 32767, load_image_oom_cb, (void *) &oom)) + { + oom = TRUE; + } + + loader = gdk_pixbuf_loader_new (); + + result = GNOME_VFS_OK; + while (!oom && (result == GNOME_VFS_OK) && (!image_from_mmc || !mmc_cover_open)) + { + GnomeVFSFileSize bytes_read; + + result = gnome_vfs_read (handle, buffer, BUFFER_SIZE, &bytes_read); + if (result == GNOME_VFS_ERROR_IO) + { + gdk_pixbuf_loader_close (loader, NULL); + gnome_vfs_close (handle); + + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_IO, + "Unable to load `%s': read failed", + uri); + g_debug ((*error)->message); + + g_object_unref (loader); + g_object_unref (client); + + retval = NULL; + break; + } + + if ((result == GNOME_VFS_ERROR_EOF) || (bytes_read == 0)) + { + g_debug ("Reached EOF of `%s', building the pixbuf", uri); + + gdk_pixbuf_loader_close (loader, NULL); + gnome_vfs_close (handle); + + retval = gdk_pixbuf_loader_get_pixbuf (loader); + if (!retval) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_CORRUPT, + "Unable to load `%s': loader failed", + uri); + + g_object_unref (loader); + g_object_unref (client); + + retval = NULL; + break; + } + else + { + GdkPixbufFormat *format; + gchar *name; + + format = gdk_pixbuf_loader_get_format (loader); + name = gdk_pixbuf_format_get_name (format); + + g_debug ("we got the pixbuf (w:%d, h:%d), format: %s", + gdk_pixbuf_get_width (retval), + gdk_pixbuf_get_height (retval), + name); + + g_free (name); + + g_object_ref (retval); + + g_object_unref (client); + g_object_unref (loader); + + break; + } + } + + if (!oom) + { + GError *load_error = NULL; + + gdk_pixbuf_loader_write (loader, buffer, bytes_read, &load_error); + if (load_error && + (load_error->domain == GDK_PIXBUF_ERROR) && + ((load_error->code == GDK_PIXBUF_ERROR_CORRUPT_IMAGE) || + (load_error->code == GDK_PIXBUF_ERROR_UNKNOWN_TYPE))) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_CORRUPT, + "Unable to load `%s': %s", + uri, + load_error->message); + + g_error_free (load_error); + g_object_unref (client); + + retval = NULL; + break; + } + } + + if (!oom && image_from_mmc) + { + GError *gconf_error = NULL; + + g_debug ("checking if the mmc cover has been opened"); + + mmc_cover_open = gconf_client_get_bool (client, + HILDON_HOME_GCONF_MMC_COVER_OPEN, + &gconf_error); + if (gconf_error) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_SYSTEM_RESOURCES, + "Unable to check key `%s' from GConf: %s", + HILDON_HOME_GCONF_MMC_COVER_OPEN, + gconf_error->message); + + g_error_free (gconf_error); + gdk_pixbuf_loader_close (loader, NULL); + gnome_vfs_close (handle); + g_object_unref (client); + + retval = NULL; + break; + } + + if (mmc_cover_open) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_MMC_OPEN, + "MMC cover is open"); + + gdk_pixbuf_loader_close (loader, NULL); + gnome_vfs_close (handle); + g_object_unref (client); + + retval = NULL; + break; + } + } + } + + if (oom_check) + osso_mem_saw_disable (); + + return retval; +} + +static GdkPixbuf * +load_image_from_file (const gchar *filename, + gboolean cancellable, + GError **error) +{ + gchar *filename_uri; + GdkPixbuf *retval; + GError *uri_error; + GError *load_error; + + uri_error = NULL; + filename_uri = g_filename_to_uri (filename, NULL, &uri_error); + if (uri_error) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_UNKNOWN, + "Unable to convert `%s' to a valid URI: %s", + filename, + uri_error->message); + g_error_free (uri_error); + + return NULL; + } + + load_error = NULL; + retval = load_image_from_uri (filename_uri, TRUE, cancellable, &load_error); + if (load_error) + { + g_propagate_error (error, load_error); + } + + g_free (filename_uri); + + return retval; +} + + +static GdkPixbuf * +create_background_from_color (const GdkColor *src, + gint width, + gint height) +{ + GdkPixbuf *dest; + guint32 color = 0; + + g_return_val_if_fail (src != NULL, NULL); + + color = (guint8) (src->red >> 8) << 24 | + (guint8) (src->green >> 8) << 16 | + (guint8) (src->blue >> 8) << 8 | + 0xff; + + dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); + gdk_pixbuf_fill (dest, color); + + return dest; +} + +/* this gets rather convoluted because we want to create a background + * pixbuf of the same size of the screen and we must account the white + * space left for the task navigator; so, we must shift the image of + * HILDON_HOME_TASKNAV_WIDTH pixels on the x axis. + */ +static GdkPixbuf * +create_background_from_pixbuf (const GdkPixbuf *src, + const GdkColor *fill, + BackgroundMode mode, + gint width, + gint height, + GError **error) +{ + GdkPixbuf *dest = NULL; + gint src_width, src_height; + gint dest_x, dest_y; + gdouble scaling_ratio; + gdouble off_x, off_y; + + g_return_val_if_fail (src != NULL, NULL); + g_return_val_if_fail (fill != NULL, NULL); + + dest = create_background_from_color (fill, width, height); + if (!dest) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_SYSTEM_RESOURCES, + "Unable to create background color"); + + return NULL; + } + + src_width = gdk_pixbuf_get_width (src); + src_height = gdk_pixbuf_get_height (src); + + g_debug ("*** background: (w:%d, h:%d), mode: %d", + src_width, + src_height, + mode); + + if (src_width == (width - HILDON_HOME_TASKNAV_WIDTH) && + src_height == height) + { + gdk_pixbuf_composite (src, + dest, + 0, 0, + width, height, + HILDON_HOME_TASKNAV_WIDTH, 0, + 1.0, 1.0, + GDK_INTERP_NEAREST, + 0xFF); + if (!dest) + { + g_set_error (error, BACKGROUND_MANAGER_ERROR, + BACKGROUND_MANAGER_ERROR_SYSTEM_RESOURCES, + "Unable to composite the background color with the image"); + + return NULL; + } + + g_debug ("*** We got a background pixbuf"); + + return dest; + } + + switch (mode) + { + case BACKGROUND_CENTERED: + if (src_width < (width - HILDON_HOME_TASKNAV_WIDTH)) + { + dest_x = MAX (HILDON_HOME_TASKNAV_WIDTH, + (width - HILDON_HOME_TASKNAV_WIDTH - src_width) + / 2 + + HILDON_HOME_TASKNAV_WIDTH); + } + else + { + dest_x = MAX (HILDON_HOME_TASKNAV_WIDTH, + (width - HILDON_HOME_TASKNAV_WIDTH - src_width) + / 2 + + HILDON_HOME_TASKNAV_WIDTH); + } + + if (src_height < height) + { + dest_y = MAX (0, (height - src_height) / 2); + } + else + { + dest_y = MAX (0, (height - src_height) / 2); + } + + off_x = (width - HILDON_HOME_TASKNAV_WIDTH - src_width) + / 2 + + HILDON_HOME_TASKNAV_WIDTH; + off_y = (height-src_height) / 2; + + gdk_pixbuf_composite (src, dest, + dest_x, dest_y, + MIN (src_width, width - HILDON_HOME_TASKNAV_WIDTH), + MIN (src_height, height), + off_x, off_y, + 1.0, 1.0, + GDK_INTERP_NEAREST, + HILDON_HOME_IMAGE_ALPHA_FULL); + break; + case BACKGROUND_SCALED: + scaling_ratio = MIN ((gdouble) ((gdouble) (width - HILDON_HOME_TASKNAV_WIDTH) / src_width), + (gdouble) height / src_height); + dest_x = (gint) (MAX (HILDON_HOME_TASKNAV_WIDTH, + HILDON_HOME_TASKNAV_WIDTH + + (width + - HILDON_HOME_TASKNAV_WIDTH + - scaling_ratio + * src_width) / 2)); + dest_y = (gint) (MAX (0, + (height + - scaling_ratio + * src_height) / 2)); + + gdk_pixbuf_composite (src, dest, + dest_x, dest_y, + scaling_ratio * src_width, + scaling_ratio * src_height, + MAX (HILDON_HOME_TASKNAV_WIDTH, + HILDON_HOME_TASKNAV_WIDTH + + (width + - HILDON_HOME_TASKNAV_WIDTH + - scaling_ratio + * src_width) / 2), + MAX (0, + (height + - scaling_ratio + * src_height) / 2), + scaling_ratio, scaling_ratio, + GDK_INTERP_NEAREST, + HILDON_HOME_IMAGE_ALPHA_FULL); + break; + case BACKGROUND_TILED: + for (dest_x = HILDON_HOME_TASKNAV_WIDTH; + dest_x < width; + dest_x += src_width) + { + for (dest_y = 0; + dest_y < height; + dest_y += src_height) + { + gdk_pixbuf_composite (src, dest, + dest_x, dest_y, + MIN (src_width, width - dest_x), + MIN (src_height, height - dest_y), + dest_x, dest_y, + 1.0, 1.0, + GDK_INTERP_NEAREST, + HILDON_HOME_IMAGE_ALPHA_FULL); + } + } + break; + case BACKGROUND_STRETCHED: + gdk_pixbuf_composite (src, dest, + HILDON_HOME_TASKNAV_WIDTH, 0, + width - HILDON_HOME_TASKNAV_WIDTH, height, + HILDON_HOME_TASKNAV_WIDTH, 0, + (gdouble) (width-HILDON_HOME_TASKNAV_WIDTH) / src_width, + ((gdouble) height) / src_height, + GDK_INTERP_NEAREST, + HILDON_HOME_IMAGE_ALPHA_FULL); + break; + default: + g_assert_not_reached (); + break; + } + + return dest; +} + +/* We create the cached pixbuf compositing the sidebar and the titlebar + * pixbufs from their relative files; we use a child process to retain + * some interactivity; we use a pipe to move the error messages from + * the child process to the background manager. the child process saves + * the composed image to the cache file and we read it inside the + * child notification callback + */ +static GdkPixbuf * +composite_background (const GdkPixbuf *bg_image, + const GdkColor *bg_color, + BackgroundMode mode, + const gchar *sidebar_path, + const gchar *titlebar_path, + gint window_width, + gint window_height, + gboolean cancellable, + GError **error) +{ + GError *bg_error; + GdkPixbuf *pixbuf; + GdkPixbuf *compose; + + g_debug ("Compositing background image..."); + + bg_error = NULL; + + if (bg_image) + { + pixbuf = create_background_from_pixbuf (bg_image, + bg_color, + mode, + window_width, + window_height, + &bg_error); + } + else + { + pixbuf = create_background_from_color (bg_color, + window_width, + window_height + ); + + g_return_val_if_fail (pixbuf, NULL); + } + + if (bg_error) + { + g_propagate_error (error, bg_error); + + return NULL; + } + + compose = load_image_from_file (titlebar_path, cancellable, &bg_error); + + if (bg_error) + { + g_warning ("Unable to load titlebar pixbuf: %s", bg_error->message); + + g_error_free (bg_error); + bg_error = NULL; + } + else if (!compose) + { + g_debug ("Assuming loading of titlebar cancelled"); + if (pixbuf) + g_object_unref (pixbuf); + return NULL; + } + else + { + g_debug ("Compositing titlebar"); + + gdk_pixbuf_composite (compose, + pixbuf, + HILDON_HOME_TASKNAV_WIDTH, 0, + gdk_pixbuf_get_width (compose), + gdk_pixbuf_get_height (compose), + HILDON_HOME_TASKNAV_WIDTH, 0, + 1.0, 1.0, + GDK_INTERP_NEAREST, + HILDON_HOME_IMAGE_ALPHA_FULL); + + g_object_unref (compose); + compose = NULL; + } + + compose = load_image_from_file (sidebar_path, cancellable, &bg_error); + if (bg_error) + { + g_warning ("Unable to load sidebar pixbuf: %s", bg_error->message); + + g_error_free (bg_error); + bg_error = NULL; + } + else if (!compose) + { + g_debug ("Assuming loading of sidebar cancelled"); + if (pixbuf) + g_object_unref (pixbuf); + return NULL; + } + else + { + gint width = gdk_pixbuf_get_width (compose); + gint height = gdk_pixbuf_get_height (compose); + gint sidebar_height; + + g_debug ("Compositing sidebar (w:%d, h:%d)", + width, height); + + sidebar_height = window_height + - HILDON_HOME_TITLEBAR_HEIGHT; + if (height != sidebar_height) + { + GdkPixbuf *scaled; + gint i; + + scaled = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, + width, sidebar_height); + for (i = 0; i < (sidebar_height - height); i += height) + { + gdk_pixbuf_copy_area (compose, + 0, 0, + width, height, + scaled, + 0, i + height); + } + + g_object_unref (compose); + compose = scaled; + } + + gdk_pixbuf_composite (compose, + pixbuf, + HILDON_HOME_TASKNAV_WIDTH, + HILDON_HOME_TITLEBAR_HEIGHT, + gdk_pixbuf_get_width (compose), + gdk_pixbuf_get_height (compose), + HILDON_HOME_TASKNAV_WIDTH, + 0, + 1.0, 1.0, + GDK_INTERP_NEAREST, + HILDON_HOME_IMAGE_ALPHA_FULL); + + g_object_unref (compose); + compose = NULL; + } + + return pixbuf; +} + + +static void +background_manager_class_init (BackgroundManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GError *error = NULL; + + gobject_class->set_property = background_manager_set_property; + gobject_class->get_property = background_manager_get_property; + gobject_class->finalize = background_manager_finalize; + g_type_class_add_private (gobject_class, sizeof (BackgroundManagerPrivate)); + + klass->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + + if (error) + { + klass->connection = NULL; + g_warning ("Could not get DBus connection"); + g_error_free (error); + return; + } + + dbus_g_object_type_install_info (TYPE_BACKGROUND_MANAGER, + &dbus_glib_background_manager_object_info); +} + +static void +background_manager_init (BackgroundManager *manager) +{ + BackgroundManagerPrivate *priv; + BackgroundManagerClass *klass; + + manager->priv = priv = BACKGROUND_MANAGER_GET_PRIVATE (manager); + + klass = BACKGROUND_MANAGER_GET_CLASS (manager); + if (klass->connection) + dbus_g_connection_register_g_object (klass->connection, + BACKGROUND_MANAGER_DBUS_OBJECT_PATH, + G_OBJECT (manager)); + +} + +/* RPC method */ +gboolean +background_manager_set_background (BackgroundManager *manager, + gint window_xid, + const gchar *filename, + const gchar *top_bar, + const gchar *left_bar, + guint16 red, + guint16 green, + guint16 blue, + BackgroundMode mode, + GError **error) +{ + BackgroundManagerPrivate *priv; + BackgroundData *data; + GdkWindow *window; + GdkPixbuf *image = NULL; + GdkPixbuf *background = NULL; + GdkColormap *colormap; + GdkPixmap *pixmap = NULL; + GdkBitmap *bitmask = NULL; + GError *local_error = NULL; + gint width, height; + + window = gdk_window_foreign_new (window_xid); + + if (!window) + { + g_set_error (error, + background_manager_error_quark (), + BACKGROUND_MANAGER_ERROR_WINDOW, + "Window not found"); + return FALSE; + } + + priv = BACKGROUND_MANAGER_GET_PRIVATE (manager); + + background_data_free (priv->current); + priv->current = data = background_data_new (); + + data->color->red = red; + data->color->blue = blue; + data->color->green = green; + + data->window = window; + + data->image_uri = g_strdup (filename); + data->top_bar = g_strdup (top_bar); + data->left_bar = g_strdup (left_bar); + + if (data->image_uri) + { + image = load_image_from_uri (data->image_uri, + TRUE, + TRUE, + &local_error); + if (local_error) + { + g_propagate_error (error, local_error); + return FALSE; + } + } + + gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height); + + background = composite_background (image, + data->color, + mode, + data->top_bar, + data->left_bar, + width, + height, + TRUE, + &local_error); + + if (image) + g_object_unref (image); + + if (local_error) + { + g_propagate_error (error, local_error); + return FALSE; + } + + colormap = gdk_drawable_get_colormap (GDK_DRAWABLE (window)); + + gdk_pixbuf_render_pixmap_and_mask_for_colormap (background, + colormap, + &pixmap, + &bitmask, + 0); + if (pixmap) + { + gdk_window_set_back_pixmap (window, pixmap, FALSE); + g_object_unref (pixmap); + } + + if (bitmask) + g_object_unref (bitmask); + + if (background) + g_object_unref (background); + + gdk_flush (); + return TRUE; +} Added: projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.h =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.h 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.h 2006-12-20 13:02:10 UTC (rev 8839) @@ -0,0 +1,110 @@ +/* -*- mode:C; c-file-style:"gnu"; -*- */ +/* + * This file is part of maemo-af-desktop + * + * Copyright (C) 2006 Nokia Corporation. + * + * Contact: Karoliina Salminen <karoliina.t.salminen at nokia.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __BACKGROUND_MANAGER_H__ +#define __BACKGROUND_MANAGER_H__ + +#include <glib-object.h> +#include <gdk/gdkcolor.h> +#include <gdk/gdkwindow.h> + +#include <dbus/dbus-glib-bindings.h> + +#define TYPE_BACKGROUND_MODE (background_mode_get_type ()) +#define TYPE_BACKGROUND_MANAGER (background_manager_get_type ()) +#define BACKGROUND_MANAGER_ERROR (background_manager_error_quark ()) + +#define BACKGROUND_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BACKGROUND_MANAGER, BackgroundManager)) +#define IS_BACKGROUND_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BACKGROUND_MANAGER)) +#define BACKGROUND_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BACKGROUND_MANAGER, BackgroundManagerClass)) +#define IS_BACKGROUND_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BACKGROUND_MANAGER)) +#define BACKGROUND_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BACKGROUND_MANAGER, BackgroundManagerClass)) + +#define BACKGROUND_MANAGER_DBUS_OBJECT_PATH "/org/maemo/hildon/background_manager" + + +G_BEGIN_DECLS + +typedef struct _BackgroundManager BackgroundManager; +typedef struct _BackgroundManagerPrivate BackgroundManagerPrivate; +typedef struct _BackgroundManagerClass BackgroundManagerClass; + +typedef enum { + BACKGROUND_CENTERED, + BACKGROUND_SCALED, + BACKGROUND_STRETCHED, + BACKGROUND_TILED +} BackgroundMode; + +GType background_mode_get_type (void) G_GNUC_CONST; + +typedef enum { + BACKGROUND_MANAGER_ERROR_MEMORY, + BACKGROUND_MANAGER_ERROR_CONNECTIVITY, + BACKGROUND_MANAGER_ERROR_CORRUPT, + BACKGROUND_MANAGER_ERROR_UNREADABLE, + BACKGROUND_MANAGER_ERROR_MMC_OPEN, + BACKGROUND_MANAGER_ERROR_SYSTEM_RESOURCES, + BACKGROUND_MANAGER_ERROR_FLASH_FULL, + BACKGROUND_MANAGER_ERROR_IO, + BACKGROUND_MANAGER_ERROR_WINDOW, + + BACKGROUND_MANAGER_ERROR_UNKNOWN +} BackgroundManagerError; + +GQuark background_manager_error_quark (void); + + +struct _BackgroundManager +{ + GObject parent_instance; + + BackgroundManagerPrivate *priv; +}; + +struct _BackgroundManagerClass +{ + GObjectClass parent_class; + + DBusGConnection *connection; +}; + +GType background_manager_get_type (void) G_GNUC_CONST; + +gboolean background_manager_set_background + (BackgroundManager *manager, + gint window_xid, + const gchar *filename, + const gchar *top_bar, + const gchar *left_bar, + guint16 red, + guint16 green, + guint16 blue, + BackgroundMode mode, + GError **error); + + +G_END_DECLS + +#endif /* __BACKGROUND_MANAGER_H__ */ Added: projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.xml =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.xml 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/background-manager.xml 2006-12-20 13:02:10 UTC (rev 8839) @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<node name="/"> + <interface name="com.nokia.HildonBackgroundManager"> + <method name="SetBackground"> + <arg type="i"/> + <arg type="s"/> + <arg type="s"/> + <arg type="s"/> + <arg type="i"/> + <arg type="i"/> + <arg type="i"/> + <arg type="i"/> + </method> + </interface> +</node> Added: projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/main.c =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/main.c 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/background-manager/main.c 2006-12-20 13:02:10 UTC (rev 8839) @@ -0,0 +1,72 @@ +/* + * This file is part of hildon-desktop + * + * Copyright (C) 2006 Nokia Corporation. + * + * Author: Johan Bilien <johan.bilien at nokia.com> + * Contact: Karoliina Salminen <karoliina.t.salminen at nokia.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "background-manager.h" + +#include <dbus/dbus-glib.h> +#include <gtk/gtkmain.h> + +#define BACKGROUND_MANAGER_SERVICE_NAME "org.maemo.hildon" + +int +main (int argc, char **argv) +{ + GObject *bm; + DBusGConnection *connection; + DBusGProxy *driver_proxy; + GError *error = NULL; + gint request_ret; + + gtk_init (&argc, &argv); + + connection = dbus_g_bus_get (DBUS_BUS_STARTER, &error); + if (error) + { + g_warning ("Could not get the DBus connection: %s", error->message); + g_error_free (error); + return 1; + } + + bm = g_object_new (TYPE_BACKGROUND_MANAGER, NULL); + + /* Get the proxy for the DBus object */ + driver_proxy = dbus_g_proxy_new_for_name (connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + if(!org_freedesktop_DBus_request_name (driver_proxy, + BACKGROUND_MANAGER_SERVICE_NAME, + 0, + &request_ret, + &error)) + { + g_warning ("Unable to register service: %s", error->message); + g_error_free (error); + return -1; + } + + gtk_main (); + return 0; +} Modified: projects/haf/branches/maemo-af-desktop/hildon-desktop/configure.ac =================================================================== --- projects/haf/branches/maemo-af-desktop/hildon-desktop/configure.ac 2006-12-20 12:39:29 UTC (rev 8838) +++ projects/haf/branches/maemo-af-desktop/hildon-desktop/configure.ac 2006-12-20 13:02:10 UTC (rev 8839) @@ -30,6 +30,7 @@ AC_HEADER_STDC AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal) +AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool) if test foobar${hildon_use_timestamping} = foobaryes then @@ -76,6 +77,10 @@ AC_SUBST(OSSO_LIBS) AC_SUBST(OSSO_CFLAGS) +PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1) +AC_SUBST(DBUS_GLIB_LIBS) +AC_SUBST(DBUS_GLIB_CFLAGS) + PKG_CHECK_MODULES(HILDONBASELIB, hildon-base-lib >= 0.7.4) AC_SUBST(HILDONBASELIB_LIBS) AC_SUBST(HILDONBASELIB_CFLAGS) @@ -88,6 +93,10 @@ AC_SUBST(GCONF_LIBS) AC_SUBST(GCONF_CFLAGS) +PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6) +AC_SUBST(GTK_LIBS) +AC_SUBST(GTK_CFLAGS) + PKG_CHECK_MODULES(GNOME_VFS, gnome-vfs-2.0 >= 2.8.3) AC_SUBST(GNOME_VFS_CFLAGS) AC_SUBST(GNOME_VFS_LIBS) @@ -141,5 +150,6 @@ libhildonwm/libhildonwm.pc \ libhildondesktop/Makefile \ libhildondesktop/libhildondesktop.pc \ + background-manager/Makefile \ data/Makefile \ src/Makefile)
- Previous message: [maemo-commits] r8838 - in projects/haf/trunk/hildon-theme-layout-3: . rc
- Next message: [maemo-commits] r8840 - in projects/haf/branches/gtk+/maemo-gtk-2-10: . gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]