Merge branch 'master' of https://vcs.maemo.org/git/livewp
[livewp] / applet / src / livewp-actor.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 General Public License
11  * as published by the Free Software Foundation; either version 2 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-actor.h"
26
27 static void
28 realize (GtkWidget *widget)
29 {
30     GdkScreen *screen;
31     screen = gtk_widget_get_screen (widget);
32     gtk_widget_set_colormap (widget, gdk_screen_get_rgba_colormap (screen));
33 }
34
35 static gboolean
36 expose_event (GtkWidget *widget,GdkEventExpose *event,
37      gpointer data)
38 {
39     cairo_t *cr;
40     GdkPixbuf *pixbuf = (GdkPixbuf *) data;
41         
42     cr = gdk_cairo_create(widget->window);
43     if (cr){
44         gdk_cairo_region(cr, event->region);
45         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
46         gdk_cairo_set_source_pixbuf(cr, pixbuf, 0.0, 0.0);
47         cairo_paint(cr);
48         cairo_destroy(cr);
49     }
50     return TRUE;
51 }
52
53 void
54 destroy_hildon_actor(Actor *actor)
55 {
56     //fprintf(stderr, "destroy_hildon_actor %s\n",actor->name);
57     gtk_widget_destroy(actor->widget);
58     actor->widget = NULL;
59 }
60
61 void
62 create_hildon_actor_text(Actor *actor, AWallpaperPlugin *desktop_plugin) 
63 {
64   GtkWidget *ha = NULL;
65   GtkWidget *label = NULL;
66
67   ha = hildon_animation_actor_new();
68   label = gtk_label_new(NULL);  
69
70   if (label){
71     //g_signal_connect(G_OBJECT(label), "expose_event", G_CALLBACK(expose_event), NULL);
72
73     gtk_container_add (GTK_CONTAINER (ha), label);
74   }  
75   realize(ha);
76   gtk_widget_show(label);
77   gtk_widget_show_all(ha);
78   
79   /* TO DO check it */
80   /*  gdk_flush (); */
81
82   //g_object_set_data(G_OBJECT(ha), "image", image);
83   actor->image = label;
84   hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (ha), GTK_WINDOW(desktop_plugin->priv->window));
85   actor->widget = ha;
86   set_actor_position(actor, actor->x, actor->y, actor->z, desktop_plugin);
87   set_actor_scale(actor, (double)actor->scale/100, (double)actor->scale/100);
88   set_actor_visible(actor, actor->visible);
89 }
90
91 void
92 create_hildon_actor(Actor *actor, AWallpaperPlugin *desktop_plugin) 
93 {
94   GtkWidget *ha = NULL;
95   GdkPixbuf *pixbuf = NULL;
96   GtkWidget *image = NULL;
97   gchar     *str = NULL;
98
99   ha = hildon_animation_actor_new();
100   if (!strcmp(actor->name, "original"))
101       str = g_strdup(actor->filename);
102   else 
103       str = g_strdup_printf( "%s/%s/%s", THEME_PATH, 
104                         desktop_plugin->priv->theme, actor->filename);
105   pixbuf = gdk_pixbuf_new_from_file_at_size (str, 
106                                              actor->width, 
107                                              actor->height, 
108                                              NULL);
109   if (str)
110       g_free(str);
111   if (pixbuf){
112       image = gtk_image_new_from_pixbuf (pixbuf);
113       g_object_unref(G_OBJECT(pixbuf));
114   }
115   if (image){
116     g_signal_connect(G_OBJECT(image), "expose_event",
117                            G_CALLBACK(expose_event), pixbuf);
118     gtk_container_add (GTK_CONTAINER (ha), image);
119   }  
120   realize(ha);
121   gtk_widget_show_all(ha);
122   
123   /* TO DO check it */
124   /*  gdk_flush (); */
125
126   //g_object_set_data(G_OBJECT(ha), "image", image);
127   actor->image = image;
128   hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (ha), GTK_WINDOW(desktop_plugin->priv->window));
129
130   actor->widget = ha;
131   set_actor_position(actor, actor->x, actor->y, actor->z, desktop_plugin);
132   set_actor_scale(actor, (double)actor->scale/100, (double)actor->scale/100);
133   set_actor_visible(actor, actor->visible);
134 }
135
136 void
137 change_hildon_actor(Actor *actor, AWallpaperPlugin *desktop_plugin)
138 {
139     GtkWidget *image = NULL;
140     GdkPixbuf *pixbuf = NULL;
141     gchar     *str = NULL;
142
143     str = g_strdup_printf( "%s/%s/%s", THEME_PATH, 
144                             desktop_plugin->priv->theme, actor->filename);
145  
146     pixbuf = gdk_pixbuf_new_from_file_at_size (str, 
147                                                actor->width, 
148                                                actor->height, 
149                                                NULL);
150     if(str)
151         g_free(str);
152     if (pixbuf){
153         image = gtk_image_new_from_pixbuf (pixbuf);
154         g_object_unref(G_OBJECT(pixbuf));
155     }
156     if (image){ 
157         g_signal_connect(G_OBJECT(image), "expose_event",
158                                        G_CALLBACK(expose_event), pixbuf);
159         //if (g_object_get_data(G_OBJECT(actor->widget), "image")){
160         if (actor->image){
161             gtk_container_remove(GTK_CONTAINER(actor->widget), actor->image);  
162         }
163         //g_object_set_data(G_OBJECT(actor->widget), "image", image);
164         actor->image = image;
165         gtk_container_add (GTK_CONTAINER (actor->widget), image);
166         realize(actor->widget);
167         gtk_widget_show_all(actor->widget);
168         /* TO DO check it */
169        /*  gdk_flush (); */
170
171
172     }
173 }
174
175 Actor* 
176 init_object(AWallpaperPlugin *desktop_plugin, 
177             gchar * name, 
178             gchar * filename, 
179             gint x, 
180             gint y, 
181             gint z, 
182             gint width, 
183             gint height, 
184             gboolean visible, 
185             gboolean load_image,
186             gint scale, 
187             gint opacity, 
188             void (*pfunc_change)(Actor*),
189             void (*pfunc_probability)(Actor*),
190             GPtrArray *child
191            )
192 {
193     Actor *actor = NULL;
194     actor = g_new0(Actor, 1);
195     actor->x = x;
196     actor->y = y;
197     actor->z = z;
198     actor->width = width;
199     actor->height = height;
200     actor->visible = visible;
201     actor->scale = scale;
202     actor->opacity = opacity;
203     actor->filename = g_strdup(filename);
204     actor->name = g_strdup(name);
205     actor->func_change = (gpointer)pfunc_change; 
206     actor->func_probability = (gpointer)pfunc_probability;
207     actor->child = child;
208     if (load_image){
209         create_hildon_actor(actor, desktop_plugin);
210     }
211     else 
212          actor->widget = NULL;
213     actor->time_start_animation = 0;
214     actor->duration_animation = 0;
215     return actor;
216 }
217
218 void 
219 destroy_actor(Actor *actor)
220 {
221     if (actor){
222         if (actor->child){
223             g_ptr_array_free(actor->child, TRUE);
224         }
225         if (actor->filename)
226             g_free(actor->filename);
227         if (actor->name)
228             g_free(actor->name);
229         gtk_widget_destroy(actor->widget);
230         //actor->widget = NULL;
231         g_free(actor);
232     }
233 }
234 static gint 
235 path_line(gint x0, gint x1, double t)
236 {
237     // уравниение прямой
238     return ((x1 - x0) * t + x0);
239 }
240 void
241 set_actor_scale(Actor *actor, double scalex, double scaley)
242 {
243     hildon_animation_actor_set_scale(
244             HILDON_ANIMATION_ACTOR(actor->widget), 
245             scalex, 
246             scaley
247     );
248
249 }
250 void
251 set_actor_rotation(Actor *actor, gint axis, double degrees, gint x, gint y, gint z)
252 {
253     hildon_animation_actor_set_rotation(
254             HILDON_ANIMATION_ACTOR(actor->widget),
255             axis,
256             degrees,
257             x,
258             y,
259             z
260     );
261 }
262 void 
263 set_actor_visible(Actor *actor, gboolean visible)
264 {
265     hildon_animation_actor_set_show(HILDON_ANIMATION_ACTOR(actor->widget), visible);
266 }
267
268 void
269 set_actor_position(Actor *actor, gint x, gint y, gint z, AWallpaperPlugin *desktop_plugin)
270 {
271     //fprintf(stderr, "set actor position %d, %d, %d\n", x, y, z);
272     hildon_animation_actor_set_position_full(HILDON_ANIMATION_ACTOR (actor->widget), 
273                                              x-desktop_plugin->priv->xapplet, 
274                                              y-desktop_plugin->priv->yapplet, 
275                                              z);
276 }
277
278 int get_notify_count(gchar *notify_type)
279 {
280     sqlite3 *db = NULL;
281     sqlite3_stmt *res = NULL;
282     gint rc = 0, result = 0;
283     gchar sql[1024];
284
285     rc = sqlite3_open("/home/user/.config/hildon-desktop/notifications.db", &db);
286     if (rc){
287         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
288     }else {
289         snprintf(sql, sizeof(sql)-1, "select count(id) from notifications where icon_name='%s'", notify_type);
290         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
291         if (rc != SQLITE_OK){
292             fprintf(stderr, "error prepare %d %s\n", rc, sql);
293         }
294         if (sqlite3_step(res) != SQLITE_ROW){
295             fprintf(stderr, "not sqlite_row\n");
296         }
297         result = sqlite3_column_int(res, 0);
298         //fprintf(stderr, "count missing calls = %d\n", call_count);
299         sqlite3_finalize(res);
300
301         sqlite3_close(db);
302     }
303     return result;
304 }
305 gchar * read_notification()
306 {
307     gchar *message = "";
308     gint count = 0;
309     
310     fprintf(stderr, "read notification \n");
311     count = get_notify_count("general_missed");
312     if (count > 0){
313         message = g_strdup_printf("%s: %d", _("Missed calls"), count);
314     }
315     count = get_notify_count("general_sms");
316     if (count > 0){
317         if (message){
318             message = g_strdup_printf("%s \n%s: %d", message, _("Missed sms"), count);
319         }else {
320             message = g_strdup_printf("%s: %d", _("Missed sms"), count);
321         }
322     }
323     count = get_notify_count("general_chat");
324     if (count > 0){
325         if (message){
326             message = g_strdup_printf("%s \n%s: %d", message, _("Missed chat"), count);
327         }else {
328             message = g_strdup_printf("%s: %d", _("Missed chat"), count);
329         }
330     }
331     count = get_notify_count("qgn_list_messagin");
332     if (count > 0){
333         if (message){
334             message = g_strdup_printf("%s \n%s: %d", message, _("Missed mail"), count);
335         }else {
336             message = g_strdup_printf("%s: %d", _("Missed mail"), count);
337         }
338     }
339     fprintf(stderr, "notify=%s\n", message);
340     return message;
341 }
342
343 void
344 change_obj(Actor *actor, AWallpaperPlugin *desktop_plugin)
345 {
346     char * accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord";
347     //char * accel_filename = "/home/tanya/coord";
348
349     FILE *fd = NULL;
350     int rs, ax, ay, az, dx, dy;
351     fd = fopen(accel_filename, "r");
352     if (fd == NULL){
353         fprintf(stderr, "cannot open file\n");
354         return;
355     }
356     rs = fscanf((FILE*)fd, "%i %i %i", &ax, &ay, &az);
357     fclose(fd);
358     if (rs != 3){
359         fprintf(stderr, "cannot read information from file\n");
360         return;
361     }
362
363     fprintf(stderr, "change obj %i %i %i\n", ax, ay, az);
364     dx = -ax / 100;
365     dy = -ay / 100;
366
367     actor->x = actor->x + dx;
368     actor->y = actor->y + dy;
369
370     if (actor->x > 800) actor->x = 0;
371     if (actor->x < 0) actor->x = 800;
372
373     if (actor->y > 480) actor->y = 0;
374     if (actor->y < 0) actor->y = 480;
375
376     set_actor_position(actor, actor->x, actor->y, actor->z, desktop_plugin);
377
378
379 }
380
381 void 
382 change_billboard(Actor * actor, AWallpaperPlugin *desktop_plugin)
383 {
384     gint count = 0;
385     Actor *a = NULL;
386      
387     //fprintf(stderr, "change_billboard\n");   
388     
389     if (desktop_plugin->priv->scene->notification < time(NULL)){
390         count = get_notify_count("general_missed");
391         a = g_ptr_array_index(actor->child, 0);
392         if (count > 0){
393             set_actor_visible(a, TRUE);            
394         }else {
395             set_actor_visible(a, FALSE);
396         }
397         count = get_notify_count("general_sms");
398         a = g_ptr_array_index(actor->child, 3);
399         if (count > 0){
400             set_actor_visible(a, TRUE);            
401         }else {
402             set_actor_visible(a, FALSE);
403         }
404         count = get_notify_count("general_chat");
405         a = g_ptr_array_index(actor->child, 1);
406         if (count > 0){
407             set_actor_visible(a, TRUE);            
408         }else {
409             set_actor_visible(a, FALSE);
410         }
411         count = get_notify_count("qgn_list_messagin");
412         a = g_ptr_array_index(actor->child, 2);
413         if (count > 0){
414             set_actor_visible(a, TRUE);            
415         }else {
416             set_actor_visible(a, FALSE);
417         }
418
419         desktop_plugin->priv->scene->notification = FALSE;
420     }
421     actor->time_start_animation = time(NULL) + 20;    
422 }
423
424 #if 0
425 void 
426 change_billboard1(Actor * actor, AWallpaperPlugin *desktop_plugin)
427 {
428     GtkWidget *label;
429     sqlite3 *db = NULL;
430     sqlite3_stmt *res = NULL;
431     gchar *errMsg = NULL, *message;
432     gchar sql[1024];
433     gint call_count=0, sms_count=0, rc=0;
434     GtkListStore *list = NULL;
435     PangoFontDescription *pfd = NULL;
436     
437     rc = sqlite3_open("/home/user/.rtcom-eventlogger/el.db", &db);
438     if (rc){
439         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
440     }else {
441         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d", 3);
442
443         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
444         if (rc != SQLITE_OK){
445             fprintf(stderr, "error prepare %d %s\n", rc, sql);
446         }
447         if (sqlite3_step(res) != SQLITE_ROW){
448             fprintf(stderr, "not sqlite_row\n");
449         }
450         call_count = sqlite3_column_int(res, 0);
451         //fprintf(stderr, "count missing calls = %d\n", call_count);
452         sqlite3_finalize(res);
453
454         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d and is_read=%d", 7, 0);
455         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
456         if (rc != SQLITE_OK){
457             fprintf(stderr, "error prepare %d %s\n", rc, sql);
458         }
459         if (sqlite3_step(res) != SQLITE_ROW){
460             fprintf(stderr, "not sqlite_row\n");
461         }
462         sms_count = sqlite3_column_int(res, 0);
463         //fprintf(stderr, "count sms = %d\n", sms_count);
464         sqlite3_finalize(res);
465
466
467         sqlite3_close(db);
468     }
469     label = actor->image;
470     message = g_markup_printf_escaped("<span bgcolor=\"%s\" foreground=\"%s\">Missed calls: %d Unread sms: %d</span>", "#FFFFFF", "#000000", call_count, sms_count);
471     gtk_label_set_markup(GTK_LABEL(label), message);
472     g_free(message);
473     pfd = pango_font_description_from_string("Sans 14");
474     gtk_widget_modify_font(GTK_WIDGET(label), NULL);
475     gtk_widget_modify_font(GTK_WIDGET(label), pfd);
476     pango_font_description_free(pfd);
477     actor->time_start_animation = time(NULL) + 20;    
478 }
479 #endif
480
481 void 
482 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
483 {
484     gint phase;
485     char *newfile;
486     gint x0 = 150,
487          x1 = 650, 
488          x, y;
489     struct timeval tvb;     
490     suseconds_t ms;
491     long sec;
492     double t;
493 #if 0
494     gint y0, y1, x2, y2;
495     double a, b, c;
496     a = (double)(y2 - (double)(x2*(y1-y0) + x1*y0 - x0*y1)/(x1-x0))/(x2*(x2-x0-x1)+x0*x1);
497     b = (double)(y1-y0)/(x1-x0) - (double)a*(x0+x1);
498     c = (double)(x1*y0 - x0*y1)/(x1-x0) + (double)a*x0*x1;
499     fprintf(stderr, "a=%f, b=%f, c=%f\n", a, b, c);
500 #endif
501     gettimeofday(&tvb, NULL);
502     
503     ms = tvb.tv_usec;
504     sec = tvb.tv_sec;
505
506     if (actor){
507         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
508             if (!actor->visible){
509                 actor->visible = TRUE;
510                 phase = get_moon_phase();
511                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
512                 if (actor->filename)
513                     g_free(actor->filename);
514                 actor->filename = newfile;
515                 actor->time_start_animation = sec - fast_rnd(60 * 60);
516                 actor->duration_animation = 1 * 60 * 60;
517                 create_hildon_actor(actor, desktop_plugin);
518
519             }
520             t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
521             if (t <= 1)
522                 x = path_line(x0, x1, t);
523             else 
524                 x = path_line(x1, x0, t-1);
525             y = 0.001920*x*x - 1.536*x + 337.2;
526             //y = a*x*x + b*x + c;
527
528             set_actor_position(actor, x, y, actor->z, desktop_plugin);
529
530             if (t>=2){
531                 actor->time_start_animation = sec;
532             }
533
534          }else if (actor->visible){
535             actor->visible = FALSE;
536             fprintf(stderr, "destroy moon \n");
537             destroy_hildon_actor(actor);
538             actor->time_start_animation = 0;
539         } 
540     }
541     
542 }
543
544 void 
545 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
546 {
547     double alt, azm;
548     gint x, y;
549
550     //fprintf(stderr, "change sun\n");
551     if (actor){
552         if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
553             if (!actor->visible){
554                 actor->visible = TRUE;
555                 create_hildon_actor(actor, desktop_plugin);
556             }
557             get_sun_pos(&alt, &azm);
558             get_sun_screen_pos(alt, azm, &x, &y);
559             actor->x = x;
560             actor->y = y;
561             set_actor_position(actor, x, y, actor->z, desktop_plugin);
562             actor->time_start_animation = time(NULL) + 60;
563          }else if (actor->visible){
564             actor->visible = FALSE;
565             destroy_hildon_actor(actor);
566             actor->time_start_animation = 0;
567         } 
568     }
569     
570 }
571
572 void 
573 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
574 {
575     gint x0 = -300, y0 = 225, scale0 = 100,
576          x1 = 800, y1 = 162, scale1 = 130, 
577          x, y, scale;
578     struct timeval tvb;     
579     suseconds_t ms;
580     long sec;
581     double t;
582
583     //fprintf(stderr, "change tram\n");
584     gettimeofday(&tvb, NULL);
585     
586     ms = tvb.tv_usec;
587     sec = tvb.tv_sec;
588     
589     if (!actor->visible){
590         actor->visible = TRUE;
591         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
592             if (actor->filename)
593                 g_free(actor->filename);
594             actor->filename = g_strdup("tram_dark.png");
595         } else{
596             if (actor->filename)
597                 g_free(actor->filename);
598             actor->filename = g_strdup("tram.png");
599         }
600         create_hildon_actor(actor, desktop_plugin);
601     }
602     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
603     x = path_line(x0, x1, t);
604     y = path_line(y0, y1, t);
605     scale = path_line(scale0, scale1, t);
606     set_actor_position(actor, x, y, actor->z, desktop_plugin);
607     set_actor_scale(actor, (double)scale/100, (double)scale/100);
608     if (t >= 1){
609         /* stop animation */
610         actor->visible = FALSE;
611         destroy_hildon_actor(actor);
612         actor->time_start_animation = sec + fast_rnd(60);
613     }
614 }
615
616 void
617 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
618 {
619     gint x0 = 620, y0 = 233,
620          x1 = 79, y1 = -146, 
621          x, y;
622     struct timeval tvb;     
623     suseconds_t ms;
624     long sec;
625     double t;
626
627     gettimeofday(&tvb, NULL);
628     
629     ms = tvb.tv_usec;
630     sec = tvb.tv_sec;
631 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
632    
633     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
634         if (actor->time_start_animation == 0){
635             actor->time_start_animation = sec + fast_rnd(180);
636             return;
637         }
638     }
639     if (!actor->visible){
640         actor->visible = TRUE;
641         create_hildon_actor(actor, desktop_plugin);
642     }
643     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
644     x = path_line(x0, x1, t);
645     y = path_line(y0, y1, t);
646     //scale = path_line(scale0, scale1, t);
647     set_actor_position(actor, x, y, actor->z, desktop_plugin);
648     if (t >= 1){
649         /* stop animation */
650         actor->visible = FALSE;
651         destroy_hildon_actor(actor);
652         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
653             actor->time_start_animation = 0;
654         else 
655             actor->time_start_animation = sec + fast_rnd(180);
656     }
657
658 }
659
660 void
661 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
662 {
663     gint x0 = -actor->width, y0 = 45,
664          x1 = 800, y1 = 20, 
665          x, y;
666     struct timeval tvb;     
667     suseconds_t ms;
668     long sec;
669     double t;
670
671     gettimeofday(&tvb, NULL);
672     
673     ms = tvb.tv_usec;
674     sec = tvb.tv_sec;
675 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
676     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
677         if (actor->time_start_animation == 0){
678             actor->time_start_animation = sec + fast_rnd(180);
679             return;
680         }
681     }
682     if (!actor->visible){
683         actor->visible = TRUE;
684         create_hildon_actor(actor, desktop_plugin);
685     }
686
687     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
688     x = path_line(x0, x1, t);
689     y = path_line(y0, y1, t);
690     //scale = path_line(scale0, scale1, t);
691     set_actor_position(actor, x, y, actor->z, desktop_plugin);
692     if (t >= 1){
693         /* stop animation */
694         actor->visible = FALSE;
695         destroy_hildon_actor(actor);
696         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
697             actor->time_start_animation = 0;
698         else 
699             actor->time_start_animation = sec + fast_rnd(180);
700     }
701
702 }
703
704 void
705 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
706 {
707     gint x0, y0 = 300, scale0 = 100,
708          x1, y1 = -actor->height, scale1 = 150, 
709          x, y, scale;
710     struct timeval tvb;     
711     suseconds_t ms;
712     long sec;
713     double t;
714     gchar *newfile;
715
716     //fprintf(stderr, "change cloud\n");
717     gettimeofday(&tvb, NULL);
718     
719     ms = tvb.tv_usec;
720     sec = tvb.tv_sec;
721    
722     if (!actor->visible){
723         actor->visible = TRUE;
724         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
725             newfile = g_strdup_printf("%s_dark.png", actor->name);
726         }else{
727             newfile = g_strdup_printf("%s.png", actor->name);
728         } 
729         if (actor->filename)
730             g_free(actor->filename);
731         actor->filename = newfile;
732          
733         create_hildon_actor(actor, desktop_plugin);
734     }
735     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
736     
737     if (desktop_plugin->priv->scene->wind_orientation == 1){
738         x0 = -actor->width;
739         x1 = 800;
740     }
741     else {
742         x0 = 800;
743         x1 = -actor->width;
744     }
745
746     x = path_line(x0, x1, t);    
747     y = -desktop_plugin->priv->scene->wind_angle * (x - x0) + actor->y;
748     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
749
750     set_actor_position(actor, x, y, actor->z, desktop_plugin);
751     set_actor_scale(actor, (double)scale/100, (double)scale/100);
752     if ((y < y1 || y > y0) || t >= 1){
753         /* stop animation */
754         actor->visible = FALSE;
755         destroy_hildon_actor(actor);
756         actor->time_start_animation = sec + fast_rnd(300);
757         actor->y = fast_rnd(300);
758     }
759
760 }
761
762 void
763 change_wind(Actor *actor, AWallpaperPlugin *desktop_plugin)
764 {
765     desktop_plugin->priv->scene->wind_orientation = fast_rnd(2);
766     if (desktop_plugin->priv->scene->wind_orientation == 0) desktop_plugin->priv->scene->wind_orientation = -1;
767     desktop_plugin->priv->scene->wind_angle = (double)(fast_rnd(200) - 100) / 100;
768     actor->time_start_animation = time(NULL) + (fast_rnd(10) + 10) * 60;
769     //fprintf(stderr, "change wind orient = %d angle = %f after = %d\n", scene.wind_orientation, scene.wind_angle, actor->time_start_animation-time(NULL));
770 }
771
772 void 
773 change_window1(Actor * actor, AWallpaperPlugin *desktop_plugin)
774 {
775     gint now = time(NULL);
776     if (desktop_plugin->priv->scene->daytime == TIME_DAY){
777         if (actor->widget){
778             actor->visible = FALSE;
779             destroy_hildon_actor(actor);
780         }
781         actor->time_start_animation = 0;
782         return;
783     }else {
784         if (!actor->widget)
785             create_hildon_actor(actor, desktop_plugin);
786         if (actor->time_start_animation == 0){
787             actor->time_start_animation = now + fast_rnd(30);
788             return;
789         }
790     }
791
792     if (!actor->visible)
793         actor->visible = TRUE;
794     else 
795         actor->visible = FALSE;
796     set_actor_visible(actor, actor->visible);
797     actor->time_start_animation = now + fast_rnd(60) + 10;
798
799 }
800
801 void 
802 change_signal(Actor * actor, AWallpaperPlugin *desktop_plugin)
803 {
804     gint now = time(NULL);
805     Actor *a;
806     a = g_ptr_array_index(actor->child, 0);
807     if (a->visible)
808         a->visible = FALSE;
809     else 
810         a->visible = TRUE;
811     set_actor_visible(a, a->visible);
812     
813     a = g_ptr_array_index(actor->child, 1);
814     if (a->visible)
815         a->visible = FALSE;
816     else 
817         a->visible = TRUE;
818     set_actor_visible(a, a->visible);
819
820     actor->time_start_animation = now + fast_rnd(30) + 10;
821 }
822
823 void
824 change_tape(Actor *actor, AWallpaperPlugin *desktop_plugin)
825 {
826     gint x, y, i;
827     Actor *a;
828
829     if (!desktop_plugin->priv->rich_animation) return;
830     
831     char * accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord";
832     //char * accel_filename = "/home/tanya/coord";
833
834     FILE *fd = NULL;
835     int rs, ax, ay, az;
836     fd = fopen(accel_filename, "r");
837     if (fd == NULL){
838         //fprintf(stderr, "cannot open file\n");
839         fd = fopen("/home/user/coord", "r"); 
840     }
841     rs = fscanf((FILE*)fd, "%i %i %i", &ax, &ay, &az);
842     fclose(fd);
843     if (rs != 3){
844         fprintf(stderr, "cannot read information from file\n");
845         return;
846
847     }
848
849     //fprintf(stderr, "change obj %i %i %i angle rad=%f, deg=%f\n", ax, ay, az, atan2(ax, -ay), atan2(ax, -ay)*180/M_PI);
850     int ang = (int)floor(atan2(ay, ax)*180/M_PI);
851     if (ang < 0) ang = 360+ang;
852
853     if (!desktop_plugin->priv->rich_animation) return;
854
855     for (i=0; i<16; i++){
856         a = g_ptr_array_index(actor->child, i);
857         if (a->scale == 100) a->scale = ang;
858         if (abs(a->scale - ang) > 10){
859             if (a->scale > ang){
860                 if ((a->scale - ang) < (ang + (360-a->scale))) a->scale--;
861                 else a->scale++;
862             }
863             if (a->scale < ang) {
864                 if (ang - a->scale < (a->scale+(360-ang))) a->scale++;
865                 else a->scale--;
866             }
867             if (a->scale > 360) a->scale = 0;
868             if (a->scale < 0) a->scale = 360;
869         }
870     
871         x = a->x - (float)cos(a->scale*M_PI/180)*a->z;
872         y = a->y - (float)sin(a->scale*M_PI/180)*a->z;
873         //x = round(a->x - (float)cos(a->scale*M_PI/180)*a->z);
874         //y = round(a->y - (float)sin(a->scale*M_PI/180)*a->z);
875         //x = a->x - cos(angle)*a->z;
876         //y = a->y - sin(angle)*a->z;
877         if ((a->scale > 270 || a->scale < 90) && x < -a->width*cos(a->scale*M_PI/180)){ 
878             x = 800; 
879             y = fast_rnd(480);
880         } 
881         if ((a->scale > 90 && a->scale < 270) && x > 800 - a->width*cos(a->scale*M_PI/180)){
882             x = 0;
883             y = fast_rnd(480);
884         }
885         if (a->scale > 0 && a->scale < 180 && y < -a->width*sin(a->scale*M_PI/180)){
886             y = 480;
887             x = fast_rnd(800);
888         }
889         if (a->scale < 360 && a->scale > 180 && y > 480 - a->width*sin(a->scale*M_PI/180)){
890             y = 0;
891             x = fast_rnd(800);
892         }
893         //if (i ==0) fprintf(stderr, "x=%d y=%d ang=%d speed=%d\n", x, y, a->scale, a->z);
894         set_actor_rotation(a, HILDON_AA_Z_AXIS, a->scale, 0, 0, 0);
895         set_actor_position(a, x, y, a->z, desktop_plugin);
896         a->x = x;
897         a->y = y;
898     }
899     
900 }
901
902 void
903 change_layer(Actor * actor, AWallpaperPlugin *desktop_plugin)
904 {
905     gint y, speed1 = 8, speed2 = 16;
906     Actor *a;
907
908     if (!desktop_plugin->priv->rich_animation) return;
909
910     a = g_ptr_array_index(actor->child, 0);
911     y = a->y + speed1;
912     if (y > 480) y = -480;
913     set_actor_position(a, a->x, y, a->z, desktop_plugin);
914     a->y = y;
915     
916     a = g_ptr_array_index(actor->child, 1);
917     y = a->y + speed1;
918     if (y > 480) y = -480;
919     set_actor_position(a, a->x, y, a->z, desktop_plugin);
920     a->y = y;
921
922     a = g_ptr_array_index(actor->child, 2);
923     y = a->y + speed2;
924     if (y > 480) y = -480;
925     set_actor_position(a, a->x, y, a->z, desktop_plugin);
926     a->y = y;
927
928     a = g_ptr_array_index(actor->child, 3);
929     y = a->y + speed2;
930     if (y > 480) y = -480;
931     set_actor_position(a, a->x, y, a->z, desktop_plugin);
932     a->y = y;
933 }
934
935 void 
936 change_static_actor(Actor * actor, AWallpaperPlugin *desktop_plugin)
937 {
938     gchar *newfile;
939     newfile = g_strdup_printf("%s%d.png", actor->name, desktop_plugin->priv->scene->daytime); 
940     if (actor->filename)
941             g_free(actor->filename);
942     actor->filename = newfile;
943     change_hildon_actor(actor, desktop_plugin);
944 }
945
946 void 
947 change_static_actor_with_corner(Actor * actor, AWallpaperPlugin *desktop_plugin)
948 {
949     gchar buffer[2048];
950
951     if (desktop_plugin->priv->right_corner)
952         gtk_widget_destroy(desktop_plugin->priv->right_corner);
953     snprintf(buffer, sizeof(buffer) - 1, "%s/%s/town%i_right_corner.png", \
954                                   THEME_PATH, desktop_plugin->priv->theme, desktop_plugin->priv->scene->daytime);
955     desktop_plugin->priv->right_corner = gtk_image_new_from_file (buffer);
956     if (desktop_plugin->priv->right_corner){
957         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), desktop_plugin->priv->right_corner, 0, 0);
958         gtk_widget_show (desktop_plugin->priv->right_corner);
959     }
960     change_static_actor(actor, desktop_plugin);
961
962 }