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