[maemo-commits] [maemo-commits] r11505 - in projects/haf/trunk/hildon-desktop: . libhildondesktop
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Mon May 7 18:08:54 EEST 2007
- Previous message: [maemo-commits] r11504 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r11506 - projects/haf/hafbuildbot
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: jobi Date: 2007-05-07 18:08:53 +0300 (Mon, 07 May 2007) New Revision: 11505 Added: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.c projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.h Modified: projects/haf/trunk/hildon-desktop/ChangeLog projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am Log: 2007-05-07 Johan Bilien <johan.bilien at nokia.com> * libhildondesktop/hildon-desktop-toggle-button.[ch]: - added - ToggleButton which implements its own painting, and supports alpha in the pressed and focused states Modified: projects/haf/trunk/hildon-desktop/ChangeLog =================================================================== --- projects/haf/trunk/hildon-desktop/ChangeLog 2007-05-07 13:43:29 UTC (rev 11504) +++ projects/haf/trunk/hildon-desktop/ChangeLog 2007-05-07 15:08:53 UTC (rev 11505) @@ -1,5 +1,12 @@ 2007-05-07 Johan Bilien <johan.bilien at nokia.com> + * libhildondesktop/hildon-desktop-toggle-button.[ch]: + - added + - ToggleButton which implements its own painting, and supports + alpha in the pressed and focused states + +2007-05-07 Johan Bilien <johan.bilien at nokia.com> + * configure.ac: 0.0.12 2007-05-07 Johan Bilien <johan.bilien at nokia.com> Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am 2007-05-07 13:43:29 UTC (rev 11504) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am 2007-05-07 15:08:53 UTC (rev 11505) @@ -19,6 +19,7 @@ hildon-desktop-multiscreen.h \ hildon-desktop-panel-expandable.h \ hildon-desktop-notification-manager.h \ + hildon-desktop-toggle-button.h\ statusbar-item.h \ statusbar-item-socket.h \ tasknavigator-item.h \ @@ -103,6 +104,8 @@ hildon-desktop-multiscreen.c \ hildon-desktop-notification-manager.h \ hildon-desktop-notification-manager.c \ + hildon-desktop-toggle-button.h \ + hildon-desktop-toggle-button.c \ statusbar-item.h \ statusbar-item.c \ statusbar-item-socket.h \ Added: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.c =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.c 2007-05-07 13:43:29 UTC (rev 11504) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.c 2007-05-07 15:08:53 UTC (rev 11505) @@ -0,0 +1,406 @@ +/* + * This file is part of hildon-desktop + * + * Copyright (C) 2007 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_X_COMPOSITE +#include <X11/extensions/Xrender.h> +#include <gdk/gdkx.h> +#include <stdlib.h> /* malloc */ +#endif + +#include "hildon-desktop-toggle-button.h" + +#ifdef HAVE_X_COMPOSITE +static gboolean hildon_desktop_toggle_button_expose (GtkWidget *widget, + GdkEventExpose *event); +static void hildon_desktop_toggle_button_style_set (GtkWidget *widget, + GtkStyle *old_style); + +static void hildon_desktop_toggle_button_realize (GtkWidget *widget); +#endif + +G_DEFINE_TYPE (HildonDesktopToggleButton, hildon_desktop_toggle_button, GTK_TYPE_TOGGLE_BUTTON); + +struct _HildonDesktopToggleButtonPrivate +{ +#ifdef HAVE_X_COMPOSITE + Picture focus_picture; + Picture focus_picture_mask; + Picture pressed_picture; + Picture pressed_picture_mask; +#endif + +}; + +static void +hildon_desktop_toggle_button_init (HildonDesktopToggleButton *button) +{ + button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button, + HILDON_DESKTOP_TYPE_TOGGLE_BUTTON, + HildonDesktopToggleButtonPrivate); +} + +static void +hildon_desktop_toggle_button_class_init (HildonDesktopToggleButtonClass *klass) +{ +#ifdef HAVE_X_COMPOSITE + GtkWidgetClass *widget_class; + + widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->expose_event = hildon_desktop_toggle_button_expose; + widget_class->style_set = hildon_desktop_toggle_button_style_set; + widget_class->realize = hildon_desktop_toggle_button_realize; +#endif + + g_type_class_add_private (klass, sizeof (HildonDesktopToggleButtonPrivate)); + +} + +#ifdef HAVE_X_COMPOSITE +static gboolean +hildon_desktop_toggle_button_expose (GtkWidget *widget, GdkEventExpose *event) +{ + if (GTK_WIDGET_DRAWABLE (widget)) + { + HildonDesktopToggleButtonPrivate *priv; + GtkButton *button; + GdkDrawable *drawable; + GdkVisual *visual; + gint x_offset, y_offset; + Picture picture; + XRenderPictFormat *format; + XRenderPictureAttributes pa = {0}; + + button = GTK_BUTTON (widget); + priv = HILDON_DESKTOP_TOGGLE_BUTTON (widget)->priv; + + gdk_window_get_internal_paint_info (widget->window, + &drawable, + &x_offset, + &y_offset); + + visual = gdk_drawable_get_visual (drawable); + + format = XRenderFindVisualFormat (GDK_DISPLAY (), + GDK_VISUAL_XVISUAL (visual)); + + if (format == None) + return FALSE; + + picture = XRenderCreatePicture (GDK_DISPLAY (), + GDK_DRAWABLE_XID (drawable), + format, + 0, + &pa); + + g_debug ("Got picture: %i", (gint)picture); + g_debug ("focus picture: %i", (gint)priv->focus_picture); + g_debug ("pressed picture: %i", (gint)priv->pressed_picture); + + if (priv->pressed_picture != None && button->depressed) + XRenderComposite (GDK_DISPLAY (), + PictOpOver, + priv->pressed_picture, + priv->pressed_picture_mask, + picture, + event->area.x, event->area.y, + event->area.x, event->area.y, + event->area.x - x_offset, event->area.y - y_offset, + event->area.width, event->area.height); + + if (priv->focus_picture != None && GTK_WIDGET_HAS_FOCUS (widget)) + { + g_debug ("painting focus"); + XRenderComposite (GDK_DISPLAY (), + PictOpOver, + priv->focus_picture, + priv->focus_picture_mask, + picture, + event->area.x, event->area.y, + event->area.x, event->area.y, + event->area.x - x_offset, event->area.y - y_offset, + event->area.width, event->area.height); + } + + XRenderFreePicture (GDK_DISPLAY (), + picture); + + return GTK_WIDGET_CLASS (hildon_desktop_toggle_button_parent_class)-> + expose_event (widget, event); + + } + + return FALSE; +} + +static void +load_picture (const gchar *filename, + Window window, + Picture *picture, + Picture *mask) +{ + XRenderPictureAttributes pa = {}; + XRenderPictFormat *format; + GdkPixbuf *pixbuf; + GError *error = NULL; + gboolean alpha; + XImage *image, *mask_image = NULL; + Pixmap pixmap, mask_pixmap = None; + GC gc; + XGCValues gc_values = {0}; + gint pw, ph; + guchar *pdata; + gchar *data, *mask_data = NULL; + guint i; + + *picture = *mask = None; + + if (!filename) + return; + + pixbuf = gdk_pixbuf_new_from_file (filename, &error); + + if (error) + { + g_warning (error->message); + g_error_free (error); + return; + } + + alpha = gdk_pixbuf_get_has_alpha (pixbuf); + pw = gdk_pixbuf_get_width (pixbuf); + ph = gdk_pixbuf_get_height (pixbuf); + pdata = gdk_pixbuf_get_pixels (pixbuf); + + g_debug ("loaded pixbuf %s: \n%ix%i alpha: %i", filename, pw, ph, alpha); + + pixmap = XCreatePixmap (GDK_DISPLAY (), + window, + pw, + ph, + 32); + + if (alpha) + mask_pixmap = XCreatePixmap (GDK_DISPLAY (), + window, + pw, + ph, + 8); + + /* Use malloc here because it is freed by Xlib */ + data = (gchar *) malloc (pw*ph*4); + + image = XCreateImage (GDK_DISPLAY (), + None, + 32, + ZPixmap, + 0, /* offset */ + data, + pw, + ph, + 8, + pw * 4); + + format = XRenderFindStandardFormat (GDK_DISPLAY (), + PictStandardARGB32); + + if (alpha) + { + mask_data = (gchar *) malloc (pw*ph); + mask_image = XCreateImage (GDK_DISPLAY (), + None, + 8, /* depth */ + ZPixmap, + 0, /* offset */ + mask_data, + pw, + ph, + 8, + pw); + } + + for (i = 0; i < pw * ph; i++) + { + +#define r ((guint32)(pdata[(alpha?4:3)*i])) +#define g ((guint32)(pdata[(alpha?4:3)*i+1])) +#define b ((guint32)(pdata[(alpha?4:3)*i+2])) +#define a ((pdata[4*i+3])) + guint32 pixel = + ((r << 16) & 0x00FF0000 ) | + ((g << 8) & 0x0000FF00) | + ((b) & 0x000000FF ); + + +#if 0 + /* FIXME: Treat non-RGBA visuals */ + if (visual->depth == 32) + pixel |= ((a << 24) & 0xFF000000); +#endif + + ((guint32 *)data)[i] = pixel; + + if (alpha) + mask_data[i] = a; +#undef r +#undef g +#undef b +#undef a + + } + + gc = XCreateGC (GDK_DISPLAY (), + pixmap, + 0, + &gc_values); + + XPutImage (GDK_DISPLAY (), + pixmap, + gc, + image, + 0, 0, + 0, 0, + pw, ph); + + XFreeGC (GDK_DISPLAY (), gc); + XDestroyImage (image); + + if (alpha) + { + gc = XCreateGC (GDK_DISPLAY (), + mask_pixmap, + 0, + &gc_values); + + XPutImage (GDK_DISPLAY (), + mask_pixmap, + gc, + mask_image, + 0, 0, + 0, 0, + pw, ph); + + XFreeGC (GDK_DISPLAY (), gc); + XDestroyImage (mask_image); + } + + g_object_unref (pixbuf); + pa.repeat = True; + *picture = XRenderCreatePicture (GDK_DISPLAY (), + pixmap, + format, + CPRepeat, + &pa); + + XFreePixmap (GDK_DISPLAY (), + pixmap); + + if (alpha) + { + XRenderPictFormat *mask_format; + + mask_format = XRenderFindStandardFormat (GDK_DISPLAY(), + PictStandardA8); + + *mask = XRenderCreatePicture (GDK_DISPLAY (), + mask_pixmap, + mask_format, + CPRepeat, + &pa); + + XFreePixmap (GDK_DISPLAY (), + mask_pixmap); + + } + +} + +static void +hildon_desktop_toggle_button_style_set (GtkWidget *widget, GtkStyle *old_style) +{ + HildonDesktopToggleButtonPrivate *priv = + HILDON_DESKTOP_TOGGLE_BUTTON (widget)->priv; + + if (!GTK_IS_STYLE (widget->style) || !GDK_IS_WINDOW (widget->window) || + !widget->style->rc_style) + return; + + if (priv->focus_picture != None) + { + XRenderFreePicture (GDK_DISPLAY (), + priv->focus_picture); + priv->focus_picture = None; + } + + if (priv->focus_picture_mask != None) + { + XRenderFreePicture (GDK_DISPLAY (), + priv->focus_picture_mask); + priv->focus_picture_mask = None; + } + + load_picture (widget->style->rc_style->bg_pixmap_name[GTK_STATE_PRELIGHT], + GDK_WINDOW_XID (widget->window), + &priv->focus_picture, + &priv->focus_picture_mask); + + + if (priv->pressed_picture != None) + { + XRenderFreePicture (GDK_DISPLAY (), + priv->pressed_picture); + priv->pressed_picture = None; + } + + if (priv->pressed_picture_mask != None) + { + XRenderFreePicture (GDK_DISPLAY (), + priv->pressed_picture_mask); + priv->pressed_picture_mask = None; + } + + load_picture (widget->style->rc_style->bg_pixmap_name[GTK_STATE_ACTIVE], + GDK_WINDOW_XID (widget->window), + &priv->pressed_picture, + &priv->pressed_picture_mask); +} + +static void +hildon_desktop_toggle_button_realize (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (hildon_desktop_toggle_button_parent_class)->realize (widget); + + hildon_desktop_toggle_button_style_set (widget, widget->style); +} +#endif + +GtkWidget * +hildon_desktop_toggle_button_new () +{ + return GTK_WIDGET (g_object_new (HILDON_DESKTOP_TYPE_TOGGLE_BUTTON, NULL)); +} Added: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.h =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.h 2007-05-07 13:43:29 UTC (rev 11504) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-toggle-button.h 2007-05-07 15:08:53 UTC (rev 11505) @@ -0,0 +1,61 @@ +/* + * This file is part of hildon-desktop + * + * Copyright (C) 2007 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 + * + */ + +#ifndef __HILDON_DESKTOP_TOGGLE_BUTTON_H__ +#define __HILDON_DESKTOP_TOGGLE_BUTTON_H__ + +#include <gtk/gtktogglebutton.h> + +G_BEGIN_DECLS + +typedef struct _HildonDesktopToggleButton HildonDesktopToggleButton; +typedef struct _HildonDesktopToggleButtonClass HildonDesktopToggleButtonClass; +typedef struct _HildonDesktopToggleButtonPrivate HildonDesktopToggleButtonPrivate; + +#define HILDON_DESKTOP_TYPE_TOGGLE_BUTTON (hildon_desktop_toggle_button_get_type ()) +#define HILDON_DESKTOP_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_DESKTOP_TYPE_TOGGLE_BUTTON, HildonDesktopToggleButton)) +#define HILDON_DESKTOP_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_DESKTOP_TYPE_TOGGLE_BUTTON, HildonDesktopToggleButtonClass)) +#define HD_IS_DESKTOP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_DESKTOP_TYPE_TOGGLE_BUTTON)) +#define HD_IS_DESKTOP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_DESKTOP_TYPE_TOGGLE_BUTTON)) +#define HILDON_DESKTOP_TOGGLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HILDON_DESKTOP_TYPE_TOGGLE_BUTTON, HildonDesktopToggleButtonClass)) + +struct _HildonDesktopToggleButton +{ + GtkToggleButton parent; + + HildonDesktopToggleButtonPrivate *priv; +}; + +struct _HildonDesktopToggleButtonClass +{ + GtkToggleButtonClass parent_class; +}; + +GType hildon_desktop_toggle_button_get_type (void); + +GtkWidget* hildon_desktop_toggle_button_new (void); + +G_END_DECLS + +#endif /* __HILDON_DESKTOP_TOGGLE_BUTTON_H__ */
- Previous message: [maemo-commits] r11504 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r11506 - projects/haf/hafbuildbot
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]