Merge branch 'master' of https://vcs.maemo.org/git/livewp
[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 <sys/time.h>
30
31 #define PLUGIN_NAME "livewp-home-widget.desktop-0"
32 #define GCONF_KEY_POSITION "/apps/osso/hildon-desktop/applets/%s/position"
33 #define GCONF_KEY_MODIFIED "/apps/osso/hildon-desktop/applets/%s/modified"
34 #define GCONF_KEY_VIEW     "/apps/osso/hildon-desktop/applets/%s/view"
35
36 HD_DEFINE_PLUGIN_MODULE (AWallpaperPlugin, animation_wallpaper_plugin, HD_TYPE_HOME_PLUGIN_ITEM)
37 #define Animation_Wallpaper_HOME_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE (obj,\
38                                                           Animation_Wallpaper_TYPE_HOME_PLUGIN,\
39                                                           Animation_WallpaperPrivate))
40
41 /* Position of plugin on desktop */
42 #define Xstartposition 700 
43 #define Ystartposition 425 
44
45 gint xapplet = 0, yapplet = 0;
46 GSList * objects_list = NULL;
47 Scene scene;
48
49 static void
50 lw_applet_realize (GtkWidget *widget)
51 {
52       GdkScreen *screen;
53
54       screen = gtk_widget_get_screen (widget);
55       gtk_widget_set_colormap (widget,
56                                 gdk_screen_get_rgba_colormap (screen));
57       gtk_widget_set_app_paintable (widget,
58                                 TRUE);
59       GTK_WIDGET_CLASS (animation_wallpaper_plugin_parent_class)->realize (widget);
60 }
61
62
63 static gboolean
64 lw_applet_expose_event(GtkWidget      *widget,
65                                         GdkEventExpose *event)
66 {
67   cairo_t *cr;
68
69   /* Create cairo context */
70   cr = gdk_cairo_create (GDK_DRAWABLE (widget->window));
71   gdk_cairo_region (cr, event->region);
72   cairo_clip (cr);
73
74   /* Draw alpha background */
75   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
76   cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
77   cairo_paint (cr);
78
79   /* Free context */
80   cairo_destroy (cr);
81
82   return GTK_WIDGET_CLASS (animation_wallpaper_plugin_parent_class)->expose_event (widget,
83                                                                                   event);
84 }
85
86 static gboolean
87 expose_event (GtkWidget *widget,GdkEventExpose *event,
88      gpointer data)
89 {
90     cairo_t *cr;
91     GdkPixbuf *pixbuf = (GdkPixbuf *) data;
92         
93     cr = gdk_cairo_create(widget->window);
94     if (cr){
95         gdk_cairo_region(cr, event->region);
96         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
97         gdk_cairo_set_source_pixbuf(cr, pixbuf, 0.0, 0.0);
98         cairo_paint(cr);
99         cairo_destroy(cr);
100     }
101     return TRUE;
102 }
103
104 static void
105 realize (GtkWidget *widget)
106 {
107     GdkScreen *screen;
108     screen = gtk_widget_get_screen (widget);
109     gtk_widget_set_colormap (widget, gdk_screen_get_rgba_colormap (screen));
110 }
111
112 /* Set position of widget on desktop */
113 static void
114 init_applet_position(void)
115 {
116   GSList *position = NULL;
117   gchar *position_key;
118   gchar *modified_key;
119   gchar *modified;
120   GError *error = NULL;
121   GConfClient   *gconf_client = gconf_client_get_default ();
122   position_key = g_strdup_printf (GCONF_KEY_POSITION, PLUGIN_NAME);
123   position = gconf_client_get_list (gconf_client,
124                                     position_key,
125                                     GCONF_VALUE_INT,
126                                     NULL);
127   if (position && position->data && position->next->data){
128         xapplet = GPOINTER_TO_INT (position->data);
129         yapplet = GPOINTER_TO_INT (position->next->data);
130   }else{
131         position = g_slist_prepend (g_slist_prepend (NULL,
132                                       GINT_TO_POINTER (Ystartposition)),
133                                       GINT_TO_POINTER (Xstartposition));
134         gconf_client_set_list (gconf_client,
135                                position_key,
136                                GCONF_VALUE_INT,
137                                position,
138                                &error);
139         xapplet = Xstartposition;
140         yapplet = Ystartposition;
141   }
142   g_free (position_key);
143   modified = g_strdup_printf ("%i", 0);
144   modified_key = g_strdup_printf (GCONF_KEY_MODIFIED, PLUGIN_NAME);
145   gconf_client_set_string (gconf_client,
146                            modified_key,
147                            modified,
148                            &error);
149   g_free(modified);
150   g_free(modified_key);
151   gconf_client_clear_cache(gconf_client);
152   g_object_unref(gconf_client);
153 }
154
155 void
156 actor_set_position_full(GtkWidget *actor, gint x, gint y, gint z)
157 {
158 /*  fprintf(stderr, "actor_set_position_full z=%d\n", z); */
159     hildon_animation_actor_set_position_full (HILDON_ANIMATION_ACTOR (actor),x-xapplet, y-yapplet, z);
160 }
161
162 static gint 
163 path_line(gint x0, gint x1, double t)
164 {
165     // уравниение прямой
166     return ((x1 - x0) * t + x0);
167 }
168
169
170 void
171 destroy_hildon_actor(Actor *actor)
172 {
173     fprintf(stderr, "estroy_hildon_actor %p\n",actor->widget);
174     gtk_widget_destroy(actor->widget);
175     actor->widget = NULL;
176 }
177
178 static Actor* 
179 init_object(AWallpaperPlugin *desktop_plugin, 
180             gchar * name, 
181             gchar * filename, 
182             gint x, 
183             gint y, 
184             gint z, 
185             gint width, 
186             gint height, 
187             gboolean visible, 
188             gint scale, 
189             gint opacity, 
190             void (*pfunc_change)(Actor*),
191             void (*pfunc_probability)(Actor*)
192            )
193 {
194   Actor *actor = NULL;
195   actor = g_new0(Actor, 1);
196   actor->x = x;
197   actor->y = y;
198   actor->z = z;
199   actor->width = width;
200   actor->height = height;
201   actor->visible = visible;
202   actor->scale = scale;
203   actor->opacity = opacity;
204   actor->filename = g_strdup(filename);
205   actor->name = g_strdup(name);
206   actor->func_change = (gpointer)pfunc_change; 
207   actor->func_probability = (gpointer)pfunc_probability;
208   if (visible)
209     create_hildon_actor(actor, desktop_plugin);
210   else 
211     actor->widget = NULL;
212   actor->time_start_animation = 0;
213   actor->duration_animation = 0;
214   /*
215   a.widget = actor;
216   a.name = name;
217   a.x = x;
218   a.y = y;
219   a.z = z;
220   */
221   //objects_list = g_slist_append(objects_list, G_OBJECT(actor));
222   //objects_list = g_slist_append(objects_list, G_OBJECT(a));
223   return actor;
224 }
225
226 void 
227 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
228 {
229     gint phase;
230     char *newfile;
231
232     if (actor){
233         if (scene.daytime == TIME_NIGHT){
234             if (!actor->visible){
235                 actor->visible = TRUE;
236                 phase = get_moon_phase();
237                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
238                 if (actor->filename)
239                     g_free(actor->filename);
240                 actor->filename = newfile;
241                 create_hildon_actor(actor, desktop_plugin);
242
243             }
244             //actor->x = 400;
245             //actor->y = 10;
246            // actor_set_position_full(actor->widget, x, y, actor->z);
247             //probability_sun(actor);
248             //fprintf(stderr, "after change sun %d\n", actor->time_start_animation);
249          }else if (actor->visible){
250             actor->visible = FALSE;
251             fprintf(stderr, "destroy moon \n");
252             destroy_hildon_actor(actor);
253             /* TO DO make moonrise*/
254             actor->time_start_animation = get_next_sunset();
255         } 
256     }
257     
258 }
259
260 void 
261 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
262 {
263     double alt, azm;
264     gint x, y;
265
266     if (actor){
267         if (scene.daytime != TIME_NIGHT){
268             if (!actor->visible){
269                 actor->visible = TRUE;
270
271                 create_hildon_actor(actor, desktop_plugin);
272             }
273             get_sun_pos(&alt, &azm);
274             get_sun_screen_pos(alt, azm, &x, &y);
275             actor->x = x;
276             actor->y = y;
277             actor_set_position_full(actor->widget, x, y, actor->z);
278             probability_sun(actor);
279          }else if (actor->visible){
280             actor->visible = FALSE;
281             destroy_hildon_actor(actor);
282             actor->time_start_animation = get_next_sunrise();
283         } 
284     }
285     
286 }
287
288 static void 
289 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
290 {
291     gint x0 = -300, y0 = 225, scale0 = 100,
292          x1 = 800, y1 = 162, scale1 = 130, 
293          x, y, scale;
294     struct timeval tvb;     
295     suseconds_t ms;
296     long sec;
297     double t;
298
299     gettimeofday(&tvb, NULL);
300     
301     ms = tvb.tv_usec;
302     sec = tvb.tv_sec;
303 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
304    
305     if (!actor->visible){
306         actor->visible = TRUE;
307         if (scene.daytime == TIME_NIGHT){
308             if (actor->filename)
309                 g_free(actor->filename);
310             actor->filename = g_strdup("tram_dark.png");
311         } else{
312             if (actor->filename)
313                 g_free(actor->filename);
314             actor->filename = g_strdup("tram.png");
315         }
316         create_hildon_actor(actor, desktop_plugin);
317     }
318     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
319     x = path_line(x0, x1, t);
320     y = path_line(y0, y1, t);
321     scale = path_line(scale0, scale1, t);
322     //fprintf(stderr, "change tram t=%f x=%d y=%d scale=%d\n", t, x, y, scale);
323     actor_set_position_full(actor->widget, x, y, actor->z);
324     hildon_animation_actor_set_scale(HILDON_ANIMATION_ACTOR(actor->widget), (double)scale/100, (double)scale/100);
325     if (t >= 1){
326         /* stop animation */
327         actor->visible = FALSE;
328         destroy_hildon_actor(actor);
329         actor->time_start_animation = sec + 5*60;
330     }
331 }
332
333 void
334 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
335 {
336     gint x0 = 620, y0 = 233, scale0 = 100,
337          x1 = 79, y1 = -146, scale1 = 100, 
338          x, y, scale;
339     struct timeval tvb;     
340     suseconds_t ms;
341     long sec;
342     double t;
343
344     gettimeofday(&tvb, NULL);
345     
346     ms = tvb.tv_usec;
347     sec = tvb.tv_sec;
348 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
349    
350     if (!actor->visible){
351         actor->visible = TRUE;
352         if (scene.daytime == TIME_NIGHT){
353             if (actor->filename)
354                 g_free(actor->filename);
355             actor->filename = g_strdup("tu154.png");
356         }else{
357             if (actor->filename)
358                 g_free(actor->filename);
359             actor->filename = g_strdup("tu154.png");
360         }
361         create_hildon_actor(actor, desktop_plugin);
362     }
363     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
364     x = path_line(x0, x1, t);
365     y = path_line(y0, y1, t);
366     //scale = path_line(scale0, scale1, t);
367     //fprintf(stderr, "change tram t=%f x=%d y=%d scale=%d\n", t, x, y, scale);
368     actor_set_position_full(actor->widget, x, y, actor->z);
369     //hildon_animation_actor_set_scale(HILDON_ANIMATION_ACTOR(actor->widget), (double)scale/100, (double)scale/100);
370     if (t >= 1){
371         /* stop animation */
372         actor->visible = FALSE;
373         destroy_hildon_actor(actor);
374         actor->time_start_animation = sec + 5*60;
375     }
376
377 }
378
379 void
380 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
381 {
382     gint x0 = -actor->width, y0 = 45, scale0 = 100,
383          x1 = 800, y1 = 20, scale1 = 100, 
384          x, y, scale;
385     struct timeval tvb;     
386     suseconds_t ms;
387     long sec;
388     double t;
389
390     gettimeofday(&tvb, NULL);
391     
392     ms = tvb.tv_usec;
393     sec = tvb.tv_sec;
394 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
395    
396     if (!actor->visible){
397         actor->visible = TRUE;
398         if (scene.daytime == TIME_NIGHT){
399             if (actor->filename)
400                 g_free(actor->filename);
401         if (scene.daytime == TIME_NIGHT)
402             actor->filename = g_strdup("plane3.png");
403         }else{
404             if (actor->filename)
405                 g_free(actor->filename);
406             actor->filename = g_strdup("plane3.png");
407         }
408         create_hildon_actor(actor, desktop_plugin);
409     }
410     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
411     x = path_line(x0, x1, t);
412     y = path_line(y0, y1, t);
413     //scale = path_line(scale0, scale1, t);
414     //fprintf(stderr, "change tram t=%f x=%d y=%d scale=%d\n", t, x, y, scale);
415     actor_set_position_full(actor->widget, x, y, actor->z);
416     //hildon_animation_actor_set_scale(HILDON_ANIMATION_ACTOR(actor->widget), (double)scale/100, (double)scale/100);
417     if (t >= 1){
418         /* stop animation */
419         actor->visible = FALSE;
420         destroy_hildon_actor(actor);
421         actor->time_start_animation = sec + 5*60;
422     }
423
424 }
425
426 void
427 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
428 {
429     gint x0, y0 = 300, scale0 = 100,
430          x1, y1 = -actor->height, scale1 = 150, 
431          x, y, scale;
432     struct timeval tvb;     
433     suseconds_t ms;
434     long sec;
435     double t;
436
437     gettimeofday(&tvb, NULL);
438     
439     ms = tvb.tv_usec;
440     sec = tvb.tv_sec;
441 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
442    
443     if (!actor->visible){
444         actor->visible = TRUE;
445         if (scene.daytime == TIME_NIGHT)
446             actor->filename = actor->filename;
447         else
448             actor->filename = actor->filename;
449         create_hildon_actor(actor, desktop_plugin);
450     }
451     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
452     
453     if (scene.wind_orientation == 1){
454         x0 = -actor->width;
455         x1 = 800;
456     }
457     else {
458         x0 = 800;
459         x1 = -actor->width;
460     }
461
462     x = path_line(x0, x1, t);    
463     y = -scene.wind_angle * (x - x0) + actor->y;
464     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
465
466     //fprintf(stderr, "change cloud t=%f x=%d y=%d scale=%d\n", t, x, y, scale);
467     actor_set_position_full(actor->widget, x, y, actor->z);
468     hildon_animation_actor_set_scale(HILDON_ANIMATION_ACTOR(actor->widget), (double)scale/100, (double)scale/100);
469     if ((y < y1 || y > y0) || t >= 1){
470         /* stop animation */
471         actor->visible = FALSE;
472         destroy_hildon_actor(actor);
473         actor->time_start_animation = sec + 5*60;
474     }
475
476 }
477
478 void
479 create_hildon_actor(Actor *actor, AWallpaperPlugin *desktop_plugin) 
480 {
481   GtkWidget *ha = NULL;
482   GdkPixbuf *pixbuf = NULL;
483   GtkWidget *image = NULL;
484   gchar     *str = NULL;
485
486   /* fprintf(stderr, "create_hildon_actor %s\n", actor->name);*/
487   ha = hildon_animation_actor_new();
488   str = g_strdup_printf( "%s/%s/%s", THEME_PATH, 
489                         desktop_plugin->priv->theme, actor->filename);
490   pixbuf = gdk_pixbuf_new_from_file_at_size (str, 
491                                              actor->width, 
492                                              actor->height, 
493                                              NULL);
494   if (str)
495       g_free(str);
496   if (pixbuf){
497       image = gtk_image_new_from_pixbuf (pixbuf);
498       g_object_unref(G_OBJECT(pixbuf));
499   }
500   if (image){
501     g_signal_connect(G_OBJECT(image), "expose_event",
502                            G_CALLBACK(expose_event), pixbuf);
503     gtk_container_add (GTK_CONTAINER (ha), image);
504   }  
505   actor_set_position_full(ha, actor->x, actor->y, actor->z);
506   hildon_animation_actor_set_show (HILDON_ANIMATION_ACTOR(ha), actor->visible);
507   hildon_animation_actor_set_scale(HILDON_ANIMATION_ACTOR(ha), (double)actor->scale/100, (double)actor->scale/100);
508   realize(ha);
509   gtk_widget_show_all(ha);
510
511   //g_object_set_data(G_OBJECT(ha), "name", name);
512   //g_object_set_data(G_OBJECT(ha), "filename", filename);
513   g_object_set_data(G_OBJECT(ha), "image", image);
514   /*
515   g_object_set_data(G_OBJECT(ha), "x", x);
516   g_object_set_data(G_OBJECT(ha), "y", y);
517   g_object_set_data(G_OBJECT(ha), "z", z);
518   g_object_set_data(G_OBJECT(ha), "width", width);
519   g_object_set_data(G_OBJECT(ha), "height", height);
520   g_object_set_data(G_OBJECT(ha), "scale", scale);
521   g_object_set_data(G_OBJECT(ha), "visible", visible);
522   g_object_set_data(G_OBJECT(ha), "opacity", opacity);
523   g_object_set_data(G_OBJECT(ha), "func", pfunc);
524   */
525   hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (ha), GTK_WINDOW(desktop_plugin));
526   actor->widget = ha;
527 }
528
529
530 void
531 change_hildon_actor(Actor *actor, AWallpaperPlugin *desktop_plugin)
532 {
533     GtkWidget *image = NULL;
534     GdkPixbuf *pixbuf = NULL;
535     gchar     *str = NULL;
536
537     str = g_strdup_printf( "%s/%s/%s", THEME_PATH, 
538                             desktop_plugin->priv->theme, actor->filename);
539  
540     pixbuf = gdk_pixbuf_new_from_file_at_size (str, 
541                                                actor->width, 
542                                                actor->height, 
543                                                NULL);
544     if(str)
545         g_free(str);
546     if (pixbuf){
547         image = gtk_image_new_from_pixbuf (pixbuf);
548         g_object_unref(G_OBJECT(pixbuf));
549     }
550     if (image){ 
551         g_signal_connect(G_OBJECT(image), "expose_event",
552                                        G_CALLBACK(expose_event), pixbuf);
553         if (g_object_get_data(G_OBJECT(actor->widget), "image")){
554             gtk_container_remove(GTK_CONTAINER(actor->widget), g_object_get_data(G_OBJECT(actor->widget), "image"));  
555         }
556         g_object_set_data(G_OBJECT(actor->widget), "image", image);
557         gtk_container_add (GTK_CONTAINER (actor->widget), image);
558         realize(actor->widget);
559         gtk_widget_show_all(actor->widget);
560     }
561
562 }
563
564
565 void 
566 change_static_actor(Actor * actor, AWallpaperPlugin *desktop_plugin)
567 {
568     gint daytime;
569     gchar *newfile;
570     if (!actor) return;
571     daytime = get_daytime();
572     newfile = g_strdup_printf("%s%d.png", actor->name, daytime); 
573     if (actor->filename)
574             g_free(actor->filename);
575     actor->filename = newfile;
576     change_hildon_actor(actor, desktop_plugin);
577 }
578
579
580
581 /*
582 static gint 
583 get_time(gint t){
584     // уравнение изменения времени
585     return t*1.1;
586 }
587 */
588 static void 
589 destroy_scene(void){
590     GSList * tmp = scene.actors;
591     Actor *actor;
592     while (tmp != NULL){
593         actor = tmp->data;
594         if (actor){
595             if (actor->filename)
596                 g_free(actor->filename);
597             if (actor->name)
598                 g_free(actor->name);
599             gtk_widget_destroy(actor->widget);
600             //actor->widget = NULL;
601             g_free(actor);
602         }
603         tmp = g_slist_next(tmp);
604     }
605     g_slist_free(tmp);
606
607 }
608
609 void
610 reload_scene(AWallpaperPlugin *desktop_plugin)
611 {
612     fprintf(stderr,"Reload scene %s\n", desktop_plugin->priv->theme);  
613     destroy_scene();
614     if (!strcmp(desktop_plugin->priv->theme,"Modern"))
615         init_scene(desktop_plugin);
616     else if (!strcmp(desktop_plugin->priv->theme,"Berlin")) 
617         init_scene1(desktop_plugin);
618 }
619
620 void 
621 probability_sun(Actor *actor)
622 {
623     actor->time_start_animation += 20 * 1;
624     actor->duration_animation = G_MAXINT;
625 }
626 /* Init Modern Scene */
627 static void
628 init_scene(AWallpaperPlugin *desktop_plugin)
629 {
630   Actor *actor;
631
632   /* fprintf(stderr, "init scene \n");*/
633   scene.daytime = get_daytime();
634   scene.actors = NULL;
635
636   actor = init_object(desktop_plugin, "sky", "sky0.png", 0, 0, 5, 800, 480, 
637                       TRUE, 100, 255, (gpointer)&change_static_actor, NULL);
638   change_static_actor(actor, desktop_plugin);
639   scene.actors = g_slist_append(scene.actors, actor);
640
641   actor = init_object(desktop_plugin, "sun", "sun.png", 0, 0, 6, 88, 88, 
642                       TRUE, 100, 255, (gpointer)&change_sun, &probability_sun);
643   actor->time_start_animation = time(NULL);
644   actor->duration_animation = G_MAXINT;
645   change_sun(actor, desktop_plugin);
646   scene.actors = g_slist_append(scene.actors, actor);
647
648   actor = init_object(desktop_plugin, "dot", "dot1.png", 0, 0, 11, 50, 50, 
649                       TRUE, 100, 255, NULL, NULL);
650   scene.actors = g_slist_append(scene.actors, actor);
651
652
653   actor = init_object(desktop_plugin, "town", "town0.png", 0, 0, 7, 800, 480, 
654                       TRUE, 100, 255, (gpointer)&change_static_actor, NULL);
655   change_static_actor(actor, desktop_plugin);
656   scene.actors = g_slist_append(scene.actors, actor);
657
658
659   
660   actor = init_object(desktop_plugin, "tram", "tram.png", -300, 225, 8, 350, 210, 
661                       FALSE, 100, 255, (gpointer)&change_tram, NULL);
662   actor->time_start_animation = time(NULL) + 10;
663   actor->duration_animation = 60;
664   scene.actors = g_slist_append(scene.actors, actor);
665
666   actor = init_object(desktop_plugin, "border", "border0.png", 0, 480-79, 9, 800, 79,
667                       TRUE, 100, 255, (gpointer)&change_static_actor, NULL);
668   change_static_actor(actor, desktop_plugin);
669   scene.actors = g_slist_append(scene.actors, actor);
670   
671   actor = init_object(desktop_plugin, "moon", "moon1.png", 400, 20, 10, 60, 60, 
672                       FALSE, 100, 255, (gpointer)&change_moon, NULL);
673   change_moon(actor, desktop_plugin);
674   scene.actors = g_slist_append(scene.actors, actor);
675
676 #if 0    
677   anim = g_new0(Animation, 1);
678   anim->count = 1;
679   anim->actor = actor;
680   anim->func_change = &change_tram;
681   anim->func_time = NULL;
682   anim->timestart = time(NULL); 
683   anim->timeall = 10;
684   
685   scene.dynamic_actors = g_slist_append(scene.dynamic_actors, anim);
686 #endif  
687  }
688
689 /* Init Berlin Scene */
690 static void
691 init_scene1(AWallpaperPlugin *desktop_plugin)
692 {
693   Actor *actor;
694
695   scene.daytime = get_daytime();
696   scene.actors = NULL;
697   scene.wind_orientation = -1;
698   scene.wind_angle = 0.3;
699   
700   actor = init_object(desktop_plugin, "sky", "sky.png", 0, 0, 5, 800, 480, 
701                       TRUE, 100, 255, (gpointer)&change_static_actor, NULL);
702   change_static_actor(actor, desktop_plugin);
703   scene.actors = g_slist_append(scene.actors, actor);
704
705   
706   actor = init_object(desktop_plugin, "sun", "sun.png", 0, 0, 6, 88, 88, 
707                       TRUE, 100, 255, (gpointer)&change_sun, &probability_sun);
708   actor->time_start_animation = time(NULL);
709   actor->duration_animation = G_MAXINT;
710   change_sun(actor, desktop_plugin);
711   scene.actors = g_slist_append(scene.actors, actor);
712
713
714   actor = init_object(desktop_plugin, "dot", "dot1.png", 0, 0, 11, 50, 50, 
715                       TRUE, 100, 255, NULL, NULL);
716   scene.actors = g_slist_append(scene.actors, actor);
717
718
719   actor = init_object(desktop_plugin, "town", "town.png", 0, 0, 10, 800, 480, 
720                       TRUE, 100, 255, (gpointer)&change_static_actor, NULL);
721   change_static_actor(actor, desktop_plugin);
722   scene.actors = g_slist_append(scene.actors, actor);
723
724   actor = init_object(desktop_plugin, "moon", "moon1.png", 400, 15, 6, 60, 60, 
725                       FALSE, 100, 255, (gpointer)&change_moon, NULL);
726   change_moon(actor, desktop_plugin);
727   scene.actors = g_slist_append(scene.actors, actor);
728   
729   actor = init_object(desktop_plugin, "plane2", "plane3.png", 0, 45, 8, 160, 50, 
730                       FALSE, 100, 255, (gpointer)&change_plane2, NULL);
731   actor->time_start_animation = time(NULL) + 5;
732   actor->duration_animation = 60;
733   scene.actors = g_slist_append(scene.actors, actor);
734   
735   actor = init_object(desktop_plugin, "plane1", "tu154_small.png", 620, 233, 9, 300, 116, 
736                       FALSE, 100, 255, (gpointer)&change_plane1, NULL);
737   actor->time_start_animation = time(NULL) + 60;
738   actor->duration_animation = 30;
739   scene.actors = g_slist_append(scene.actors, actor);
740
741   actor = init_object(desktop_plugin, "cloud1", "cloud2.png", 0, 50, 7, 188, 75, 
742                       FALSE, 100, 255, (gpointer)&change_cloud, NULL);
743   actor->time_start_animation = time(NULL) + 5;
744   actor->duration_animation = 5*60;
745   scene.actors = g_slist_append(scene.actors, actor);
746
747 }
748
749
750 void 
751 get_sun_screen_pos(double alt, double azm, gint * x, gint * y)
752 {
753     gint y0 = 365;// - уровень горизонта
754     *x = (int)(azm * 800) - 64;
755     *y = (int)((1 - alt) * y0) - 64;
756     //fprintf(stderr, "sun pos alt=%f azm=%f x=%d y=%d\n", alt, azm, *x, *y);
757 }
758 #if 0
759 static void 
760 change_actor(GtkWidget * actor)
761 {
762     char * name;
763     gint x, y, daytime, scale;
764     gdouble sc;
765     double alt, azm;
766
767     GtkWidget *image;
768     GdkPixbuf *pixbuf;
769
770     void (*pfunc)(gpointer, gpointer);
771
772     name = g_object_get_data(G_OBJECT(actor), "name");
773     fprintf(stderr, "change actor %s\n", name);
774     if (name == "sun"){
775         pfunc = g_object_get_data(G_OBJECT(actor), "func");
776         if (pfunc)
777             (*pfunc)(actor, g_strdup(name));
778         daytime = get_daytime();
779         if (daytime != TIME_NIGHT){
780             hildon_animation_actor_set_show(actor, 1);
781             get_sun_pos(&alt, &azm);
782             get_sun_screen_pos(alt, azm, &x, &y);
783             actor_set_position_full(actor, x, y, g_object_get_data(G_OBJECT(actor), "z"));
784         }
785     }
786     
787     if (name == "cloud1"){
788         x = g_object_get_data(G_OBJECT(actor), "x");
789         y = g_object_get_data(G_OBJECT(actor), "y");
790         scale = g_object_get_data(G_OBJECT(actor), "scale");
791
792         /* Start */
793         image = g_object_get_data(G_OBJECT(actor), "image");
794         
795         gtk_container_remove(actor, image);  
796         pixbuf = gdk_pixbuf_new_from_file_at_size ("/usr/share/livewp/theme/Modern/sun.png", 
797                                              200, 
798                                              200, 
799                                              NULL);
800         if (pixbuf){
801               image = gtk_image_new_from_pixbuf (pixbuf);
802               g_object_unref(G_OBJECT(pixbuf));
803         }
804         g_signal_connect(G_OBJECT(image), "expose_event",
805                                    G_CALLBACK(expose_event), pixbuf);
806         gtk_container_add (GTK_CONTAINER (actor), image);
807         realize(actor);
808         gtk_widget_show_all(actor);
809         /* End*/
810
811             
812         x += 40;
813         y -= 20;
814         scale -= 10;
815         if (x > 500){
816             x = 400;
817             y = 150;
818             sc = 1;
819         }
820         sc = (double)scale / 100;
821         hildon_animation_actor_set_scale(actor, sc, sc);
822         fprintf(stderr, "cloud x=%d y=%d scale=%f", x, y, sc);
823         actor_set_position_full(actor, x, y, g_object_get_data(G_OBJECT(actor), "z"));
824         g_object_set_data(G_OBJECT(actor), "x", x);
825         g_object_set_data(G_OBJECT(actor), "y", y);
826         g_object_set_data(G_OBJECT(actor), "scale", scale);
827     }
828
829 }
830 #endif
831 static gboolean
832 short_timeout (AWallpaperPlugin *desktop_plugin)
833 {
834       gint daytime = get_daytime();
835       GSList * tmp;
836       void (*pfunc)(gpointer, gpointer);
837       time_t now;
838       Actor *actor;
839       gboolean stop_flag = TRUE;
840
841     if (!desktop_plugin->priv->visible)
842         return TRUE;
843
844     now = time(NULL);
845     /* fprintf(stderr, "Short timer %d\n", now); */
846     tmp = scene.actors;
847     while (tmp != NULL){
848            actor = tmp->data;
849            if (now >= actor->time_start_animation  
850                && actor->time_start_animation > 0
851                /* && now - actor->time_start_animation <= actor->duration_animation*/){
852                 pfunc = actor->func_change;
853                 if (pfunc){ 
854                     (*pfunc)(actor, desktop_plugin);
855                     stop_flag = FALSE;
856                 }
857             }
858             tmp = g_slist_next(tmp);
859     }
860     scene.daytime = daytime;
861     if (stop_flag){
862          desktop_plugin->priv->short_timer = 0;
863          return FALSE;
864     }else
865          return TRUE; /* keep running this event */
866 }
867
868
869 static gboolean
870 long_timeout (AWallpaperPlugin *desktop_plugin)
871 {
872       gint daytime = get_daytime();
873       GSList * tmp;
874       void (*pfunc)(gpointer, gpointer);
875       time_t now;
876       Actor *actor;
877
878     /* TODO  remove timeout */
879     if (!desktop_plugin->priv->visible)
880         return TRUE;
881   //fprintf(stderr, "timer daytime=%d\n", daytime);
882   if (scene.daytime != daytime){
883       tmp = scene.actors;
884       while (tmp != NULL){
885           //change_actor(tmp->data);
886           pfunc =((Actor*)tmp->data)->func_change;
887           if (pfunc){
888               (*pfunc)(tmp->data, desktop_plugin);
889           }
890           tmp = g_slist_next(tmp);
891       }
892    }
893    
894    now = time(NULL);
895 //fprintf(stderr, "Now  %d\n", now);
896    tmp = scene.actors;
897    while (tmp != NULL){
898        actor = tmp->data;
899        if (now >= actor->time_start_animation  
900            && actor->time_start_animation > 0
901            && desktop_plugin->priv->short_timer == 0){
902             actor->time_start_animation = now;
903             /* fprintf(stderr, "start short timer act = %s %d\n", actor->name, now); */
904             desktop_plugin->priv->short_timer = g_timeout_add(SHORT_TIMER, (GtkFunction)short_timeout, desktop_plugin);
905         }
906         tmp = g_slist_next(tmp);
907    }
908    
909  scene.daytime = daytime;
910
911  return TRUE; /* keep running this event */
912 }
913
914 static void
915 desktop_plugin_visible_notify (GObject    *object,
916                                           GParamSpec *spec,
917                                           AWallpaperPlugin *desktop_plugin)
918 {
919       gboolean visible;
920       g_object_get (object, "is-on-current-desktop", &visible, NULL);
921       if (visible)
922         desktop_plugin->priv->visible = TRUE;
923       else
924         desktop_plugin->priv->visible = FALSE;
925    /*   fprintf (stderr, "is-on-current-desktop changed. visible: %u", visible); */
926 }
927
928 static void
929 animation_wallpaper_plugin_init (AWallpaperPlugin *desktop_plugin)
930 {
931     GtkWidget *label;
932
933     fprintf(stderr, "!!!!!!!plugin init \n");
934     Animation_WallpaperPrivate *priv =  Animation_Wallpaper_HOME_PLUGIN_GET_PRIVATE (desktop_plugin);
935     desktop_plugin->priv =  Animation_Wallpaper_HOME_PLUGIN_GET_PRIVATE (desktop_plugin);
936     /* Load config */
937     read_config(priv);
938     priv->desktop_plugin = desktop_plugin;
939     label = gtk_label_new (""); 
940     gtk_widget_set_size_request(label, 95, 30);
941     gtk_widget_show (label);
942     hd_home_plugin_item_set_settings (HD_HOME_PLUGIN_ITEM (desktop_plugin), TRUE);
943     g_signal_connect (desktop_plugin, "show-settings",
944                              G_CALLBACK (lw_settings), priv);
945     g_signal_connect (desktop_plugin, "notify::is-on-current-desktop",
946                      G_CALLBACK (desktop_plugin_visible_notify), desktop_plugin);
947
948     gtk_container_add (GTK_CONTAINER (desktop_plugin), label);
949     init_applet_position();
950     fprintf(stderr, "!!!theme = %s\n", priv->theme);
951     if (!strcmp(priv->theme,"Modern"))
952         init_scene(desktop_plugin);
953     else if (!strcmp(priv->theme,"Berlin")) 
954         init_scene1(desktop_plugin);
955     priv->long_timer = g_timeout_add(LONG_TIMER, (GtkFunction)long_timeout, desktop_plugin);
956     priv->short_timer = 0;
957     /* TODO Move scene to priv */
958     scene.timer_type = LONG_TIMER_TYPE;
959
960     //sleep(2);
961 }
962
963 static void
964 lw_applet_finalize (GObject *object)
965 {
966      AWallpaperPlugin *desktop_plugin = Animation_Wallpaper_HOME_PLUGIN (object);
967      Animation_WallpaperPrivate *priv = desktop_plugin->priv;
968
969      if (priv->long_timer){
970         g_source_remove(priv->long_timer);
971         priv->long_timer = 0;
972      }
973      if (priv->short_timer){
974         g_source_remove(priv->short_timer);
975         priv->short_timer = 0;
976      }
977
978      destroy_scene();
979 }
980
981 static void
982 animation_wallpaper_plugin_class_init (AWallpaperPluginClass *klass) {
983
984     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
985     GtkObjectClass *gobject_class = GTK_OBJECT_CLASS (klass);
986
987     /* gobject */
988     gobject_class->destroy = (gpointer)lw_applet_finalize;
989     widget_class->realize = lw_applet_realize;
990     widget_class->expose_event = lw_applet_expose_event;
991
992     g_type_class_add_private (klass, sizeof (Animation_WallpaperPrivate));
993
994 }
995
996 static void
997 animation_wallpaper_plugin_class_finalize (AWallpaperPluginClass *class) {}