/* * desktop-plugin-example - Example Desktop Plugin with real transparency * Copyright (C) 2008 Tommi Saviranta * * 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 3 of the License, 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, see . */ #ifdef HAVE_CONFIG_H #include #endif #include "example.h" #include #include #include #include #include #include #ifdef HAVE_XCOMPOSITE #include #include #include #endif #define _(a) dgettext(GETTEXT_PACKAGE, (a)) #define IMAGEFILE MEDIAPATH "/pacman.png" HD_DEFINE_PLUGIN(Example, example, HILDON_DESKTOP_TYPE_HOME_ITEM) struct _ExamplePrivate { #ifdef HAVE_XCOMPOSITE Picture bg_picture, bg_mask; gint bg_width, bg_height; #endif GtkWidget *desktop; }; static gboolean cb_button_release(GtkWidget *widget, GdkEventButton *event) { if (widget->window != event->window) { return GTK_WIDGET_CLASS(example_parent_class) ->button_release_event(widget, event); } if (event->x < 0 || event->y < 0 || event->x >= widget->allocation.width || event->y >= widget->allocation.height) { return TRUE; } hildon_banner_show_information( EXAMPLE_GET_PRIVATE(widget)->desktop, NULL, _("Example Plugin clicked")); return GTK_WIDGET_CLASS(example_parent_class) ->button_release_event(widget, event); } #ifdef HAVE_XCOMPOSITE static void applet_destroy(GtkObject *widget) { ExamplePrivate *priv = EXAMPLE_GET_PRIVATE(EXAMPLE(widget)); if (priv->bg_picture != None) { XRenderFreePicture(GDK_DISPLAY(), priv->bg_picture); priv->bg_picture = None; } if (priv->bg_mask != None) { XRenderFreePicture(GDK_DISPLAY(), priv->bg_mask); priv->bg_mask = None; } } static void applet_size_request(GtkWidget *widget, GtkRequisition *requisition) { GTK_WIDGET_CLASS(example_parent_class)->size_request( widget, requisition); requisition->width = APPLET_WIDTH; requisition->height = APPLET_HEIGHT; } static void applet_style_set(GtkWidget *widget, GtkStyle *old_style) { Example *applet = EXAMPLE(widget); ExamplePrivate *priv = EXAMPLE_GET_PRIVATE(applet); GTK_WIDGET_CLASS(example_parent_class)->style_set(widget, old_style); if (! GTK_WIDGET_REALIZED(widget)) { return; } if (! GTK_IS_STYLE (widget->style) || ! GTK_IS_RC_STYLE (widget->style->rc_style)) { return; } if (GTK_IS_STYLE(old_style) && GTK_IS_RC_STYLE(old_style->rc_style) && old_style->rc_style->bg_pixmap_name[GTK_STATE_NORMAL] && g_str_equal(IMAGEFILE, old_style->rc_style->bg_pixmap_name [GTK_STATE_NORMAL])) { return; } if (priv->bg_picture) { XRenderFreePicture(GDK_DISPLAY(), priv->bg_picture); priv->bg_picture = None; } if (priv->bg_mask) { XRenderFreePicture(GDK_DISPLAY(), priv->bg_mask); priv->bg_mask = None; } hildon_desktop_picture_and_mask_from_file(IMAGEFILE, &priv->bg_picture, &priv->bg_mask, &priv->bg_width, &priv->bg_height); } static gint applet_expose(GtkWidget *widget, GdkEventExpose *event) { ExamplePrivate *priv = EXAMPLE_GET_PRIVATE(EXAMPLE(widget)); GdkDrawable *drawable; gint x_offset, y_offset; XRenderColor color; Picture picture; XRectangle clip; XserverRegion region; if (GTK_WIDGET_DRAWABLE(widget) == FALSE) { return FALSE; } gdk_window_get_internal_paint_info(widget->window, &drawable, &x_offset, &y_offset); picture = hildon_desktop_picture_from_drawable(drawable); if (picture == None) { return FALSE; } clip.x = event->area.x - x_offset; clip.y = event->area.y - y_offset; clip.width = event->area.width; clip.height = event->area.height; region = XFixesCreateRegion(GDK_DISPLAY(), &clip, 1); XFixesSetPictureClipRegion(GDK_DISPLAY(), picture, 0, 0, region); color.red = color.blue = color.green = 0; color.alpha = 0; XRenderFillRectangle(GDK_DISPLAY(), PictOpSrc, picture, &color, 0, 0, widget->allocation.width, widget->allocation.height); if (priv->bg_picture) { XRenderComposite(GDK_DISPLAY(), PictOpSrc, priv->bg_picture, priv->bg_mask, picture, 0, 0, 0, 0, -x_offset, -y_offset, priv->bg_width, priv->bg_height); } XFixesDestroyRegion(GDK_DISPLAY(), region); XRenderFreePicture(GDK_DISPLAY(), picture); return GTK_WIDGET_CLASS(example_parent_class)->expose_event( widget, event); } static void applet_realize(GtkWidget *widget) { GTK_WIDGET_CLASS(example_parent_class)->realize(widget); applet_style_set(widget, NULL); } #else static void create_ui(GtkContainer *plugin, int padding) { GtkWidget *image; image = gtk_image_new_from_file(IMAGEFILE); gtk_misc_set_padding(GTK_MISC(image), padding, padding); gtk_container_add(plugin, image); } #endif static void settings_popup(Example *plugin) { hildon_banner_show_information( EXAMPLE_GET_PRIVATE(plugin)->desktop, NULL, _("Example Plugin settings opened")); } GtkWidget * settings_menu_entry(HildonDesktopHomeItem *applet, GtkWidget *parent) { Example *plugin = EXAMPLE(applet); GtkWidget *item; EXAMPLE_GET_PRIVATE(plugin)->desktop = parent; item = gtk_menu_item_new_with_label(_("Desktop Plugin Example")); g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(settings_popup), plugin); return item; } static void example_init(Example *plugin) { #ifdef HAVE_XCOMPOSITE GdkColormap *cm; #endif plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE(plugin, TYPE_EXAMPLE, ExamplePrivate); bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); #ifdef HAVE_XCOMPOSITE cm = gdk_screen_get_rgba_colormap(gdk_screen_get_default()); if (cm != NULL) { gtk_widget_set_colormap(GTK_WIDGET(plugin), cm); g_object_unref(cm); } #endif hildon_desktop_home_item_set_resize_type( HILDON_DESKTOP_HOME_ITEM(plugin), HILDON_DESKTOP_HOME_ITEM_RESIZE_NONE); #ifndef HAVE_XCOMPOSITE create_ui(GTK_CONTAINER(plugin), 5); #endif gtk_widget_set_name(GTK_WIDGET(plugin), PACKAGE); gtk_widget_show_all(GTK_WIDGET(plugin)); } static void example_class_init(ExampleClass *klass) { HildonDesktopHomeItemClass *applet_class; GtkWidgetClass *widget_class; #ifdef HAVE_XCOMPOSITE GtkObjectClass *gtk_object_class; #endif g_type_class_add_private(klass, sizeof(ExamplePrivate)); applet_class = HILDON_DESKTOP_HOME_ITEM_CLASS(klass); widget_class = GTK_WIDGET_CLASS(klass); applet_class->settings = settings_menu_entry; #ifdef HAVE_XCOMPOSITE gtk_object_class = GTK_OBJECT_CLASS(klass); gtk_object_class->destroy = applet_destroy; widget_class->expose_event = applet_expose; widget_class->realize = applet_realize; widget_class->style_set = applet_style_set; widget_class->size_request = applet_size_request; #endif widget_class->button_release_event = cb_button_release; }