checking all view on display
[livewp] / applet / src / livewp-home-widget.c
1 /*vim: set sw=4 ts=4 et: */
2 /*
3  * This file is part of Live Wallpaper (livewp)
4  * 
5  * Copyright (C) 2010 Vlad Vasiliev
6  * Copyright (C) 2010 Tanya Makova
7  *       for the code
8  * 
9  * This software is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  * 
14  * This software is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  * 
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this software; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23 */
24 /*******************************************************************************/
25 #include "livewp-common.h" 
26 #include "livewp-home-widget.h"
27 #include <gconf/gconf-client.h>
28 #include "livewp-rules.h"
29 #include "livewp-scene.h"
30 #include <sys/time.h>
31 #include <stdlib.h>
32
33 #define GCONF_KEY_POSITION "/apps/osso/hildon-desktop/applets/livewp-home-widget.desktop-%i/position"
34 #define GCONF_KEY_MODIFIED "/apps/osso/hildon-desktop/applets/livewp-home-widget.desktop-%i/modified"
35 #define GCONF_KEY_VIEW     "/apps/osso/hildon-desktop/applets/livewp-home-widget.desktop-%i/view"
36
37 HD_DEFINE_PLUGIN_MODULE (AWallpaperPlugin, animation_wallpaper_plugin, HD_TYPE_HOME_PLUGIN_ITEM)
38 #define Animation_Wallpaper_HOME_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE (obj,\
39                                                           Animation_Wallpaper_TYPE_HOME_PLUGIN,\
40                                                           Animation_WallpaperPrivate))
41 static void
42 lw_applet_realize (GtkWidget *widget)
43 {
44       GdkScreen *screen;
45
46   fprintf(stderr,"ddddddddddddd %s\n", hd_plugin_item_get_plugin_id (HD_PLUGIN_ITEM (widget)));
47       screen = gtk_widget_get_screen (widget);
48       gtk_widget_set_colormap (widget,
49                                 gdk_screen_get_rgba_colormap (screen));
50       gtk_widget_set_app_paintable (widget,
51                                 TRUE);
52       GTK_WIDGET_CLASS (animation_wallpaper_plugin_parent_class)->realize (widget);
53 }
54
55
56 static gboolean
57 lw_applet_expose_event(GtkWidget      *widget,
58                                         GdkEventExpose *event)
59 {
60   cairo_t *cr;
61
62   /* Create cairo context */
63   cr = gdk_cairo_create (GDK_DRAWABLE (widget->window));
64   gdk_cairo_region (cr, event->region);
65   cairo_clip (cr);
66
67   /* Draw alpha background */
68   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
69   cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
70   cairo_paint (cr);
71
72   /* Free context */
73   cairo_destroy (cr);
74
75   return GTK_WIDGET_CLASS (animation_wallpaper_plugin_parent_class)->expose_event (widget,
76                                                                                   event);
77 }
78
79 static gboolean
80 expose_event (GtkWidget *widget,GdkEventExpose *event,
81      gpointer data)
82 {
83     cairo_t *cr;
84     GdkPixbuf *pixbuf = (GdkPixbuf *) data;
85         
86     cr = gdk_cairo_create(widget->window);
87     if (cr){
88         gdk_cairo_region(cr, event->region);
89         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
90         gdk_cairo_set_source_pixbuf(cr, pixbuf, 0.0, 0.0);
91         cairo_paint(cr);
92         cairo_destroy(cr);
93     }
94     return TRUE;
95 }
96
97 static void
98 realize (GtkWidget *widget)
99 {
100     GdkScreen *screen;
101     screen = gtk_widget_get_screen (widget);
102     gtk_widget_set_colormap (widget, gdk_screen_get_rgba_colormap (screen));
103 }
104 /* Set position of widget on desktop */
105 static void
106 init_applet_position(gint *xapplet, gint *yapplet)
107 {
108   GSList *position = NULL;
109   gchar *position_key;
110   gchar *modified_key;
111   gchar *modified;
112   GError *error = NULL;
113   gint i;
114   GConfClient   *gconf_client = gconf_client_get_default ();
115   for (i=0;i<4;i++){
116       position_key = g_strdup_printf (GCONF_KEY_POSITION, i);
117       position = gconf_client_get_list (gconf_client,
118                                         position_key,
119                                         GCONF_VALUE_INT,
120                                         NULL);
121       if (position && position->data && position->next->data){
122         *xapplet = GPOINTER_TO_INT (position->data);
123         *yapplet = GPOINTER_TO_INT (position->next->data);
124       }else{
125         position = g_slist_prepend (g_slist_prepend (NULL,
126                                           GINT_TO_POINTER (Ystartposition)),
127                               GINT_TO_POINTER (Xstartposition));
128         gconf_client_set_list (gconf_client,
129                                    position_key,
130                                    GCONF_VALUE_INT,
131                                position,
132                        &error);
133         *xapplet = Xstartposition;
134         *yapplet = Ystartposition;
135       }
136       g_free (position_key);
137       modified = g_strdup_printf ("%i", 0);
138       modified_key = g_strdup_printf (GCONF_KEY_MODIFIED, i);
139       gconf_client_set_string (gconf_client,
140                                modified_key,
141                                modified,
142                                &error);
143       g_free(modified);
144       g_free(modified_key);
145       modified_key = g_strdup_printf (GCONF_KEY_VIEW, i);
146       gconf_client_set_int (gconf_client,
147                                modified_key,
148                                (i+1),
149                                &error);
150       g_free(modified_key);
151
152   }
153   gconf_client_clear_cache(gconf_client);
154   g_object_unref(gconf_client);
155 }
156 #if 0
157 void
158 actor_set_position_full(GtkWidget *actor, gint x, gint y, gint z)
159 {
160 /*  fprintf(stderr, "actor_set_position_full z=%d\n", z); */
161     hildon_animation_actor_set_position_full (HILDON_ANIMATION_ACTOR (actor),x-0, y-0, z);
162 }
163 #endif
164
165 void
166 destroy_hildon_actor(Actor *actor)
167 {
168     //fprintf(stderr, "destroy_hildon_actor %s\n",actor->name);
169     gtk_widget_destroy(actor->widget);
170     actor->widget = NULL;
171 }
172
173 void
174 create_hildon_actor_text(Actor *actor, AWallpaperPlugin *desktop_plugin) 
175 {
176   GtkWidget *ha = NULL;
177   GdkPixbuf *pixbuf = NULL;
178   GtkWidget *image = NULL;
179   GtkWidget *label = NULL;
180
181   ha = hildon_animation_actor_new();
182   label = gtk_label_new(NULL);  
183
184   if (label){
185     //g_signal_connect(G_OBJECT(label), "expose_event", G_CALLBACK(expose_event), NULL);
186
187     gtk_container_add (GTK_CONTAINER (ha), label);
188   }  
189   realize(ha);
190   gtk_widget_show(label);
191   gtk_widget_show_all(ha);
192   
193   /* TO DO check it */
194   /*  gdk_flush (); */
195
196   //g_object_set_data(G_OBJECT(ha), "image", image);
197   actor->image = label;
198   hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (ha), GTK_WINDOW(desktop_plugin));
199   actor->widget = ha;
200   set_actor_position(actor, actor->x, actor->y, actor->z, desktop_plugin);
201   set_actor_scale(actor, (double)actor->scale/100, (double)actor->scale/100);
202   set_actor_visible(actor, actor->visible);
203 }
204
205
206
207 void
208 create_hildon_actor(Actor *actor, AWallpaperPlugin *desktop_plugin) 
209 {
210   GtkWidget *ha = NULL;
211   GdkPixbuf *pixbuf = NULL;
212   GtkWidget *image = NULL;
213   gchar     *str = NULL;
214
215   ha = hildon_animation_actor_new();
216   str = g_strdup_printf( "%s/%s/%s", THEME_PATH, 
217                         desktop_plugin->priv->theme, actor->filename);
218   pixbuf = gdk_pixbuf_new_from_file_at_size (str, 
219                                              actor->width, 
220                                              actor->height, 
221                                              NULL);
222   /*fprintf(stderr, "create_hildon_actor %s %s\n", actor->name, str);*/
223   if (str)
224       g_free(str);
225   if (pixbuf){
226       image = gtk_image_new_from_pixbuf (pixbuf);
227       g_object_unref(G_OBJECT(pixbuf));
228   }
229   if (image){
230     g_signal_connect(G_OBJECT(image), "expose_event",
231                            G_CALLBACK(expose_event), pixbuf);
232     gtk_container_add (GTK_CONTAINER (ha), image);
233   }  
234   realize(ha);
235   gtk_widget_show_all(ha);
236   
237   /* TO DO check it */
238   /*  gdk_flush (); */
239
240   //g_object_set_data(G_OBJECT(ha), "image", image);
241   actor->image = image;
242   hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (ha), GTK_WINDOW(desktop_plugin));
243
244   actor->widget = ha;
245   set_actor_position(actor, actor->x, actor->y, actor->z, desktop_plugin);
246   set_actor_scale(actor, (double)actor->scale/100, (double)actor->scale/100);
247   set_actor_visible(actor, actor->visible);
248 }
249
250
251 void
252 change_hildon_actor(Actor *actor, AWallpaperPlugin *desktop_plugin)
253 {
254     GtkWidget *image = NULL;
255     GdkPixbuf *pixbuf = NULL;
256     gchar     *str = NULL;
257
258     str = g_strdup_printf( "%s/%s/%s", THEME_PATH, 
259                             desktop_plugin->priv->theme, actor->filename);
260  
261     pixbuf = gdk_pixbuf_new_from_file_at_size (str, 
262                                                actor->width, 
263                                                actor->height, 
264                                                NULL);
265     if(str)
266         g_free(str);
267     if (pixbuf){
268         image = gtk_image_new_from_pixbuf (pixbuf);
269         g_object_unref(G_OBJECT(pixbuf));
270     }
271     if (image){ 
272         g_signal_connect(G_OBJECT(image), "expose_event",
273                                        G_CALLBACK(expose_event), pixbuf);
274         //if (g_object_get_data(G_OBJECT(actor->widget), "image")){
275         if (actor->image){
276             gtk_container_remove(GTK_CONTAINER(actor->widget), actor->image);  
277         }
278         //g_object_set_data(G_OBJECT(actor->widget), "image", image);
279         actor->image = image;
280         gtk_container_add (GTK_CONTAINER (actor->widget), image);
281         realize(actor->widget);
282         gtk_widget_show_all(actor->widget);
283         /* TO DO check it */
284        /*  gdk_flush (); */
285
286
287     }
288
289 }
290
291
292 static gboolean
293 short_timeout (AWallpaperPlugin *desktop_plugin)
294 {
295     //gint daytime = get_daytime();
296     GSList * tmp;
297     void (*pfunc)(gpointer, gpointer);
298     time_t now;
299     Actor *actor;
300     gboolean stop_flag = TRUE;
301
302 if (!desktop_plugin->priv->visible || !desktop_plugin->priv->rich_animation){
303         desktop_plugin->priv->short_timer = 0;
304         return FALSE;
305     }
306
307     now = time(NULL);
308     //scene.daytime = daytime;
309     /* fprintf(stderr, "Short timer %d\n", now); */
310     tmp = desktop_plugin->priv->scene->actors;
311     while (tmp != NULL){
312            actor = tmp->data;
313            if (now >= actor->time_start_animation  
314                && actor->time_start_animation > 0
315                /* && now - actor->time_start_animation <= actor->duration_animation*/){
316                 pfunc = actor->func_change;
317                 if (pfunc){ 
318                     (*pfunc)(actor, desktop_plugin);
319                     stop_flag = FALSE;
320                 }
321             }
322             tmp = g_slist_next(tmp);
323     }
324     if (stop_flag){
325          desktop_plugin->priv->short_timer = 0;
326          return FALSE;
327     }else
328          return TRUE; /* keep running this event */
329 }
330
331 void
332 run_long_timeout(AWallpaperPlugin *desktop_plugin)
333 {
334
335     gint daytime = get_daytime();
336     GSList * tmp;
337     void (*pfunc)(gpointer, gpointer);
338     time_t now;
339     Actor *actor;
340
341     if (!desktop_plugin->priv->scene)
342         return;
343     //fprintf(stderr, "!!!run long timeout short_timer=%d\n", desktop_plugin->priv->short_timer);
344     if (desktop_plugin->priv->scene->daytime != daytime){
345         desktop_plugin->priv->scene->daytime = daytime;
346         tmp = desktop_plugin->priv->scene->actors;
347         while (tmp != NULL){
348             //change_actor(tmp->data);
349             pfunc =((Actor*)tmp->data)->func_change;
350             if (pfunc){
351                 (*pfunc)(tmp->data, desktop_plugin);
352             }
353             tmp = g_slist_next(tmp);
354         }
355     }
356    
357     now = time(NULL);
358     //fprintf(stderr, "Now  %d\n", now);
359     tmp = desktop_plugin->priv->scene->actors;
360     while (tmp != NULL){
361         actor = tmp->data;
362         if (now >= actor->time_start_animation  
363             && actor->time_start_animation > 0
364             && desktop_plugin->priv->short_timer == 0){
365             /* fprintf(stderr, "start short timer act = %s %d\n", actor->name, now); */
366             if (desktop_plugin->priv->rich_animation){
367                 actor->time_start_animation = now;
368                 desktop_plugin->priv->short_timer = g_timeout_add(SHORT_TIMER, (GtkFunction)short_timeout, desktop_plugin);
369             }
370             else {
371                 (*actor->func_change)(actor, desktop_plugin);
372             }
373         }
374         tmp = g_slist_next(tmp);
375     }
376  
377 }
378
379 static gboolean
380 long_timeout (AWallpaperPlugin *desktop_plugin)
381 {
382     /* fprintf(stderr, "long_timeout %i\n", desktop_plugin->priv->long_timer); */
383     if (desktop_plugin->priv->long_timer == 0 )
384         return FALSE;
385     if (!desktop_plugin->priv->visible){
386         if(desktop_plugin->priv->short_timer != 0){
387             g_source_remove(desktop_plugin->priv->short_timer);
388             desktop_plugin->priv->short_timer = 0;
389         }
390         desktop_plugin->priv->long_timer = 0;
391         return FALSE;
392     }
393   
394
395     run_long_timeout(desktop_plugin);
396     return TRUE; /* keep running this event */
397 }
398
399 static void
400 desktop_plugin_visible_notify (GObject    *object,
401                                           GParamSpec *spec,
402                                           AWallpaperPlugin *desktop_plugin)
403 {
404     gboolean visible;
405     g_object_get (object, "is-on-current-desktop", &visible, NULL);
406     /* fprintf (stderr, "is-on-current-desktop changed. visible: %u", visible); */
407     if (visible){
408         desktop_plugin->priv->visible = TRUE;
409         if (desktop_plugin->priv->long_timer == 0 ){
410             desktop_plugin->priv->long_timer = g_timeout_add(LONG_TIMER, (GtkFunction)long_timeout, desktop_plugin);
411             run_long_timeout(desktop_plugin);
412         }
413     }else{
414         desktop_plugin->priv->visible = FALSE;
415         if (desktop_plugin->priv->long_timer != 0 ){
416             g_source_remove(desktop_plugin->priv->long_timer);
417             desktop_plugin->priv->long_timer = 0;
418         }
419     }
420 }
421 gboolean
422 rich_animation_press(GtkWidget *widget, GdkEvent *event,
423                                             gpointer user_data){
424     fprintf(stderr,"gggggggggggggggggggg2222\n");
425     return FALSE;
426 }    
427 static void
428 animation_wallpaper_plugin_init (AWallpaperPlugin *desktop_plugin)
429 {
430     GtkWidget *rich_animation;
431     gchar           buffer[2048];
432     gchar str[128];
433
434     //fprintf(stderr, "!!!!!!!plugin init \n");
435     Animation_WallpaperPrivate *priv =  Animation_Wallpaper_HOME_PLUGIN_GET_PRIVATE (desktop_plugin);
436     desktop_plugin->priv =  Animation_Wallpaper_HOME_PLUGIN_GET_PRIVATE (desktop_plugin);
437     priv->osso = osso_initialize(PACKAGE, VERSION, TRUE, NULL);
438
439     /* Load config */
440     read_config(priv);
441     /* Initialize DBUS */
442     livewp_initialize_dbus(priv);
443
444     priv->desktop_plugin = desktop_plugin;
445     priv->visible = TRUE;
446     priv->short_timer = 0;
447     priv->xapplet = 0;
448     priv->yapplet = 0;
449     priv->scene = NULL;
450 //    priv->theme = g_strdup("Modern");
451 //#if 0 
452     priv->hash_scene_func = g_hash_table_new(g_str_hash, g_str_equal);
453     
454     g_hash_table_insert(priv->hash_scene_func, g_strdup("Berlin"), (gpointer)&init_scene_Berlin);
455     g_hash_table_insert(priv->hash_scene_func, g_strdup("Modern"), (gpointer)&init_scene_Modern);
456     g_hash_table_insert(priv->hash_scene_func, g_strdup("Matrix"), (gpointer)&init_scene_Matrix);
457 //#endif
458     //priv->theme = g_strdup("Modern");
459     desktop_plugin->priv->main_widget = gtk_fixed_new();
460
461     gtk_widget_set_size_request(desktop_plugin->priv->main_widget, 100, 32);
462     desktop_plugin->priv->right_corner = NULL;
463     snprintf(buffer, sizeof(buffer) - 1, "%s/%s/%s", THEME_PATH, desktop_plugin->priv->theme, "town0_right_corner.png");
464     desktop_plugin->priv->right_corner = gtk_image_new_from_file (buffer);
465     if (desktop_plugin->priv->right_corner){
466         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), desktop_plugin->priv->right_corner, 0, 0);
467         gtk_widget_show (desktop_plugin->priv->right_corner);
468     }
469     /* Create rich animation event */
470     rich_animation = gtk_event_box_new();
471     if(rich_animation){
472         gtk_widget_set_events(rich_animation, GDK_BUTTON_PRESS_MASK);
473         gtk_event_box_set_visible_window(GTK_EVENT_BOX(rich_animation), FALSE);
474         gtk_widget_set_size_request(rich_animation, 100, 32);
475         gtk_widget_show (rich_animation);
476         g_signal_connect(rich_animation, "button-press-event", G_CALLBACK(rich_animation_press), desktop_plugin);
477         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), rich_animation, 0, 0);
478     }
479 #if 0
480     GtkWidget *label = gtk_label_new ("1111ddddddddd");
481     gtk_widget_set_size_request(label, 95, 30);
482     gtk_widget_show (label);
483     gtk_container_add (GTK_CONTAINER (desktop_plugin), label);
484 #endif
485     hd_home_plugin_item_set_settings (HD_HOME_PLUGIN_ITEM (desktop_plugin), TRUE);
486     g_signal_connect (desktop_plugin, "show-settings",
487                              G_CALLBACK (show_settings), priv);
488     gtk_widget_show (desktop_plugin->priv->main_widget);
489     gtk_container_add (GTK_CONTAINER (desktop_plugin), desktop_plugin->priv->main_widget);
490     init_applet_position(&(priv->xapplet), &(priv->yapplet));
491
492     
493     //fprintf(stderr, "!!!theme = %s\n", priv->theme);
494     //snprintf(str, sizeof(str) - 1, "%s", "init_scene2");
495     //fprintf(stderr, " str = %s\n", str);
496     priv->scene = NULL;
497 #if 0
498     if (!strcmp(priv->theme,"Modern"))
499         init_scene_Modern(desktop_plugin);
500     else if (!strcmp(priv->theme,"Berlin")) 
501         init_scene_Berlin(desktop_plugin);
502     else if (!strcmp(priv->theme, "Matrix"))
503         init_scene_Matrix(desktop_plugin);
504 #endif
505     init_scene_theme(desktop_plugin);
506         
507     priv->long_timer = g_timeout_add(LONG_TIMER, (GtkFunction)long_timeout, desktop_plugin);
508     /* TODO Move scene to priv */
509     //scene.timer_type = LONG_TIMER_TYPE;
510     g_signal_connect (desktop_plugin, "notify::is-on-current-desktop",
511                    G_CALLBACK (desktop_plugin_visible_notify), desktop_plugin);
512
513    
514     //sleep(2);
515 }
516
517 static void
518 lw_applet_finalize (GObject *object)
519 {
520 fprintf(stderr,"lw_applet_finalize\n");
521 /*
522      AWallpaperPlugin *desktop_plugin = Animation_Wallpaper_HOME_PLUGIN (object);
523      Animation_WallpaperPrivate *priv = desktop_plugin->priv;
524      
525      if (priv){
526              livewp_deinitialize_dbus(priv);
527              fprintf(stderr,"finalaze %i\n", priv->long_timer);
528              if (priv->long_timer){
529                 g_source_remove(priv->long_timer);
530                 priv->long_timer = 0;
531              }
532              if (priv->short_timer){
533                 g_source_remove(priv->short_timer);
534                 priv->short_timer = 0;
535              }
536
537              destroy_scene(desktop_plugin);
538      }
539 */
540 }
541
542 static void
543 desktop_widget_finalize (GObject *object)
544 {
545      AWallpaperPlugin *desktop_plugin = Animation_Wallpaper_HOME_PLUGIN (object);
546      Animation_WallpaperPrivate *priv = desktop_plugin->priv;
547      
548      if (priv){
549              livewp_deinitialize_dbus(priv);
550              fprintf(stderr,"finalaze %i\n", priv->long_timer);
551              if (priv->long_timer){
552                 g_source_remove(priv->long_timer);
553                 priv->long_timer = 0;
554              }
555              if (priv->short_timer){
556                 g_source_remove(priv->short_timer);
557                 priv->short_timer = 0;
558              }
559
560              destroy_scene(desktop_plugin);
561      }
562       /* Call the base class's implementation: */
563       G_OBJECT_CLASS (animation_wallpaper_plugin_parent_class)->finalize (object);
564 }
565
566 static void
567 animation_wallpaper_plugin_class_init (AWallpaperPluginClass *klass) {
568
569     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
570     GtkObjectClass *gobject_class = GTK_OBJECT_CLASS (klass);
571     GObjectClass *object_class = G_OBJECT_CLASS (klass);
572
573     /* gobject */
574     gobject_class->destroy = (gpointer)lw_applet_finalize;
575     object_class->finalize = desktop_widget_finalize;
576     widget_class->realize = lw_applet_realize;
577     widget_class->expose_event = lw_applet_expose_event;
578
579     g_type_class_add_private (klass, sizeof (Animation_WallpaperPrivate));
580
581 }
582
583 static void
584 animation_wallpaper_plugin_class_finalize (AWallpaperPluginClass *class) {
585 }
586
587 Animation_WallpaperPrivate*
588 animation_wallpaper_plugin_new (void)
589 {
590   return g_object_new (Animation_Wallpaper_TYPE_HOME_PLUGIN , NULL);
591 }
592