1 /* $Id: eyes.c 2397 2007-01-17 17:46:35Z nick $
3 * Copyright (c) Benedikt Meurer <benedikt.meurer@unix-ag.uni-siegen.de>>
4 * Copyright (c) Danny Milosavljevic <danny_milo@gmx.net>
5 * Copyright (c) Dave Camp
6 * Copyright (c) Davyd Madeley <davyd@madeley.id.au>
7 * Copyright (c) Nick Schermer <nick@xfce.org>
8 * Copyright (c) Mikko Vartiainen <mvartiainen@gmail.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * You should have received a copy of the GNU General Public License along with
21 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22 * Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <sys/types.h>
37 #include <libhildondesktop/libhildondesktop.h>
38 #include <mce/dbus-names.h>
39 #include <mce/mode-names.h>
43 #include "accelerometer.h"
46 #define EYES_ROOT "Eyes"
47 #define DEFAULTTHEME "Default"
48 #define UPDATE_TIMEOUT 100
50 #define EYES_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE (obj, \
51 EYES_TYPE_HOME_PLUGIN, \
54 HD_DEFINE_PLUGIN_MODULE (EyesPlugin, eyes_plugin, HD_TYPE_HOME_PLUGIN_ITEM)
56 static void eyes_check_display(DBusGProxy *object, const char *status, EyesPluginContent *eyes);
58 /*****************************
59 *** Eyes Plugin Functions ***
60 *****************************/
62 calculate_pupil_xy (EyesPluginContent *eyes_applet,
64 gint *pupil_x, gint *pupil_y, GtkWidget* widget)
72 gfloat xalign, yalign;
75 width = GTK_WIDGET(widget)->allocation.width;
76 height = GTK_WIDGET(widget)->allocation.height;
77 gtk_misc_get_alignment(GTK_MISC(widget), &xalign, &yalign);
84 if ( nx*nx/((eyes_applet->eye_width/2.0 - eyes_applet->pupil_width / 2)*(eyes_applet->eye_width/2.0 - eyes_applet->pupil_width/2)) + ny*ny/((eyes_applet->eye_height/2 - eyes_applet->pupil_height/2)*(eyes_applet->eye_height/2 - eyes_applet->pupil_height/2)) < 1 )
86 *pupil_x = nx + eyes_applet->eye_width / 2;
87 *pupil_y = ny + eyes_applet->eye_height / 2;
94 temp = hypot ((eyes_applet->eye_width / 2) * sina, (eyes_applet->eye_height / 2) * cosa);
95 temp -= hypot ((eyes_applet->pupil_width / 2) * sina, (eyes_applet->pupil_height / 2) * cosa);
96 temp -= hypot ((eyes_applet->wall_thickness / 2) * sina, (eyes_applet->wall_thickness / 2) * cosa);
98 *pupil_x = temp * sina + (eyes_applet->eye_width / 2);
99 *pupil_y = temp * cosa + (eyes_applet->eye_height / 2);
103 draw_eye (EyesPluginContent *eyes,
109 GdkRectangle rect, r1, r2;
111 pixbuf = gdk_pixbuf_copy (eyes->eye_image);
112 r1.x = pupil_x - eyes->pupil_width / 2;
113 r1.y = pupil_y - eyes->pupil_height / 2;
114 r1.width = eyes->pupil_width;
115 r1.height = eyes->pupil_height;
118 r2.width = eyes->eye_width;
119 r2.height = eyes->eye_height;
120 if (gdk_rectangle_intersect (&r1, &r2, &rect))
122 gdk_pixbuf_composite (eyes->pupil_image, pixbuf,
127 pupil_x - eyes->pupil_width / 2,
128 pupil_y - eyes->pupil_height / 2, 1.0, 1.0,
131 gtk_image_set_from_pixbuf (GTK_IMAGE (eyes->eyes[eye_num]),
134 g_object_unref (G_OBJECT (pixbuf));
138 timer_cb(EyesPluginContent *eyes)
141 gint pupil_x, pupil_y;
144 for (i = 0; i < eyes->num_eyes; i++)
146 if (GTK_WIDGET_REALIZED(eyes->eyes[i]))
148 accel_read(&x, &y, &z);
149 calculate_pupil_xy (eyes, -x, -y, &pupil_x, &pupil_y, eyes->eyes[i]);
151 if ((pupil_x != eyes->pointer_last_x[i]) || (pupil_y != eyes->pointer_last_y[i]))
154 draw_eye (eyes, i, pupil_x, pupil_y);
156 eyes->pointer_last_x[i] = pupil_x;
157 eyes->pointer_last_y[i] = pupil_y;
166 properties_load(EyesPluginContent *eyes)
170 if (eyes->active_theme)
171 path = g_build_filename(THEMESDIR, eyes->active_theme, NULL);
173 path = g_build_filename(THEMESDIR, DEFAULTTHEME, NULL);
175 load_theme(eyes, path);
183 setup_eyes(EyesPluginContent *eyes)
185 g_warning ("setup_eyes");
188 if (eyes->hbox != NULL)
190 gtk_widget_destroy(eyes->hbox);
194 eyes->hbox = gtk_hbox_new(FALSE, 0);
195 gtk_container_add(GTK_CONTAINER(eyes->align), GTK_WIDGET(eyes->hbox));
197 eyes->eyes = g_new0 (GtkWidget *, eyes->num_eyes);
198 eyes->pointer_last_x = g_new0 (gint, eyes->num_eyes);
199 eyes->pointer_last_y = g_new0 (gint, eyes->num_eyes);
201 for (i = 0; i < eyes->num_eyes; i++)
203 eyes->eyes[i] = gtk_image_new ();
205 gtk_widget_set_size_request(GTK_WIDGET(eyes->eyes[i]),
209 gtk_widget_show(eyes->eyes[i]);
211 gtk_box_pack_start(GTK_BOX(eyes->hbox), eyes->eyes[i],
214 if ((eyes->num_eyes != 1) && (i == 0))
215 gtk_misc_set_alignment (GTK_MISC (eyes->eyes[i]), 1.0, 0.5);
216 else if ((eyes->num_eyes != 1) && (i == eyes->num_eyes - 1))
217 gtk_misc_set_alignment (GTK_MISC (eyes->eyes[i]), 0.0, 0.5);
219 gtk_misc_set_alignment (GTK_MISC (eyes->eyes[i]), 0.5, 0.5);
221 eyes->pointer_last_x[i] = G_MAXINT;
222 eyes->pointer_last_y[i] = G_MAXINT;
226 eyes->eye_height / 2);
229 gtk_widget_show(eyes->hbox);
235 eyes_applet_fill(EyesPluginContent *eyes)
237 gtk_widget_show_all(GTK_WIDGET(eyes->align));
239 if (eyes->timeout_id == 0)
241 eyes->timeout_id = g_timeout_add (UPDATE_TIMEOUT,
242 (GtkFunction)timer_cb, eyes);
248 /******************************
249 *** Panel Plugin Functions ***
250 ******************************/
252 eyes_free_data(EyesPluginContent *eyes)
254 g_warning("eyes_free_data");
255 g_return_if_fail(eyes != NULL);
257 if (eyes->timeout_id != 0)
258 g_source_remove (eyes->timeout_id);
261 g_free (eyes->pointer_last_x);
262 g_free (eyes->pointer_last_y);
264 if (eyes->active_theme != NULL)
265 g_free (eyes->active_theme);
267 if (eyes->eye_image != NULL)
268 g_object_unref (G_OBJECT (eyes->eye_image));
270 if (eyes->pupil_image != NULL)
271 g_object_unref (G_OBJECT (eyes->pupil_image));
273 if (eyes->theme_dir != NULL)
274 g_free(eyes->theme_dir);
276 if (eyes->theme_name != NULL)
277 g_free(eyes->theme_name);
279 if (eyes->eye_filename != NULL)
280 g_free(eyes->eye_filename);
282 if (eyes->pupil_filename != NULL)
283 g_free(eyes->pupil_filename);
285 if (eyes->proxy != NULL)
286 dbus_g_proxy_disconnect_signal (eyes->proxy, MCE_DISPLAY_SIG, G_CALLBACK(eyes_check_display), eyes);
292 eyes_read_rc_file (EyesPluginContent *eyes)
294 g_warning ("eyes_read_rc");
295 if (eyes->active_theme == NULL)
296 eyes->active_theme = g_strdup (DEFAULTTHEME);
299 static EyesPluginContent *
302 g_warning ("eyes_plugin_new");
303 EyesPluginContent *eyes;
305 eyes = g_new0(EyesPluginContent, 1);
307 eyes->align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
309 gtk_widget_show(GTK_WIDGET(eyes->align));
311 eyes_read_rc_file (eyes);
313 properties_load(eyes);
315 eyes_applet_fill(eyes);
317 eyes->visible = TRUE;
323 eyes_check_desktop (GObject *gobject, GParamSpec *pspec, EyesPluginContent *eyes)
326 g_warning ("eyes_check_desktop");
327 gchar *name = pspec->name;
329 g_object_get (gobject, name, &status, NULL);
331 eyes_applet_fill(eyes);
332 eyes->visible = TRUE;
333 } else if (eyes->timeout_id != 0) {
334 g_source_remove (eyes->timeout_id);
335 eyes->timeout_id = 0;
336 eyes->visible = FALSE;
341 eyes_check_display(DBusGProxy *object, const char *status, EyesPluginContent *eyes)
343 if (strncmp(status, MCE_DISPLAY_ON_STRING,
344 strlen(MCE_DISPLAY_ON_STRING) + 1) == 0
347 eyes_applet_fill(eyes);
349 else if (strncmp(status, MCE_DISPLAY_OFF_STRING,
350 strlen(MCE_DISPLAY_OFF_STRING) + 1) == 0)
352 if (eyes->timeout_id != 0)
354 g_source_remove (eyes->timeout_id);
355 eyes->timeout_id = 0;
362 eyes_plugin_dispose (GObject *object)
364 g_warning ("eyes_plugin_dispose");
366 G_OBJECT_CLASS (eyes_plugin_parent_class)->dispose (object);
369 static void eyes_plugin_finalize (GObject *object)
371 g_warning ("eyes_plugin_finalize");
372 EyesPlugin *self = EYES_HOME_PLUGIN (object);
374 eyes_free_data(self->priv);
376 G_OBJECT_CLASS (eyes_plugin_parent_class)->finalize (object);
380 eyes_plugin_realize (GtkWidget *widget)
382 g_warning ("eyes_plugin_realize");
383 GdkScreen *screen = gtk_widget_get_screen (widget);
384 gtk_widget_set_colormap (widget, gdk_screen_get_rgba_colormap (screen));
385 gtk_widget_set_app_paintable (widget, TRUE);
387 GTK_WIDGET_CLASS (eyes_plugin_parent_class)->realize (widget);
391 eyes_plugin_expose_event (GtkWidget *widget, GdkEventExpose *event)
393 g_warning ("eyes_plugin_expose_event");
396 cr = gdk_cairo_create (GDK_DRAWABLE (widget->window));
397 gdk_cairo_region (cr, event->region);
400 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
401 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
406 return GTK_WIDGET_CLASS (eyes_plugin_parent_class)->expose_event (widget, event);
410 eyes_plugin_init (EyesPlugin *desktop_plugin)
412 g_warning ("eyes_plugin_init");
413 EyesPluginContent *eyes;
415 eyes = eyes_plugin_new (desktop_plugin);
416 desktop_plugin->priv = eyes;
418 g_signal_connect (desktop_plugin, "notify::is-on-current-desktop",
419 G_CALLBACK (eyes_check_desktop), eyes);
421 eyes->dbus_conn = NULL;
424 eyes->dbus_conn = hd_home_plugin_item_get_dbus_g_connection ( &desktop_plugin->hitem, DBUS_BUS_SYSTEM, NULL );
425 if (eyes->dbus_conn != NULL)
427 eyes->proxy = dbus_g_proxy_new_for_name(eyes->dbus_conn, MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF);
428 dbus_g_proxy_add_signal (eyes->proxy, MCE_DISPLAY_SIG, G_TYPE_STRING, G_TYPE_INVALID );
429 dbus_g_proxy_connect_signal(eyes->proxy, MCE_DISPLAY_SIG, G_CALLBACK(eyes_check_display),eyes,NULL);
432 gtk_container_add (GTK_CONTAINER (desktop_plugin), eyes->align);
436 eyes_plugin_class_init (EyesPluginClass *klass) {
437 g_warning ("eyes_plugin_class_init");
438 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
439 GObjectClass *object_class = G_OBJECT_CLASS (klass);
441 object_class->dispose = eyes_plugin_dispose;
442 object_class->finalize = eyes_plugin_finalize;
444 widget_class->realize = eyes_plugin_realize;
445 widget_class->expose_event = eyes_plugin_expose_event;
446 g_type_class_add_private (klass, sizeof (EyesPluginContent));
450 eyes_plugin_class_finalize (EyesPluginClass *class) {}