started fifteen again
[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 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-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     hildon_animation_actor_set_position_full(HILDON_ANIMATION_ACTOR (actor->widget), 
272                                              x-desktop_plugin->priv->xapplet, 
273                                              y-desktop_plugin->priv->yapplet, 
274                                              z);
275 }
276
277 int get_notify_count(gchar *notify_type)
278 {
279     sqlite3 *db = NULL;
280     sqlite3_stmt *res = NULL;
281     gint rc = 0, result = 0;
282     gchar sql[1024];
283
284     rc = sqlite3_open("/home/user/.config/hildon-desktop/notifications.db", &db);
285     if (rc){
286         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
287     }else {
288         snprintf(sql, sizeof(sql)-1, "select count(id) from notifications where icon_name='%s'", notify_type);
289         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
290         if (rc != SQLITE_OK){
291             fprintf(stderr, "error prepare %d %s\n", rc, sql);
292         }
293         if (sqlite3_step(res) != SQLITE_ROW){
294             fprintf(stderr, "not sqlite_row\n");
295         }
296         result = sqlite3_column_int(res, 0);
297         //fprintf(stderr, "count missing calls = %d\n", call_count);
298         sqlite3_finalize(res);
299
300         sqlite3_close(db);
301     }
302     return result;
303 }
304 gchar * read_notification()
305 {
306     gchar *message = "";
307     gint count = 0;
308     
309     fprintf(stderr, "read notification \n");
310     count = get_notify_count("general_missed");
311     if (count > 0){
312         message = g_strdup_printf("%s: %d", _("Missed calls"), count);
313     }
314     count = get_notify_count("general_sms");
315     if (count > 0){
316         if (message){
317             message = g_strdup_printf("%s \n%s: %d", message, _("Missed sms"), count);
318         }else {
319             message = g_strdup_printf("%s: %d", _("Missed sms"), count);
320         }
321     }
322     count = get_notify_count("general_chat");
323     if (count > 0){
324         if (message){
325             message = g_strdup_printf("%s \n%s: %d", message, _("Missed chat"), count);
326         }else {
327             message = g_strdup_printf("%s: %d", _("Missed chat"), count);
328         }
329     }
330     count = get_notify_count("qgn_list_messagin");
331     if (count > 0){
332         if (message){
333             message = g_strdup_printf("%s \n%s: %d", message, _("Missed mail"), count);
334         }else {
335             message = g_strdup_printf("%s: %d", _("Missed mail"), count);
336         }
337     }
338     fprintf(stderr, "notify=%s\n", message);
339     return message;
340 }
341
342 void
343 change_obj(Actor *actor, AWallpaperPlugin *desktop_plugin)
344 {
345     char * accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord";
346     //char * accel_filename = "/home/tanya/coord";
347
348     FILE *fd = NULL;
349     int rs, ax, ay, az, dx, dy;
350     fd = fopen(accel_filename, "r");
351     if (fd == NULL){
352         fprintf(stderr, "cannot open file\n");
353         return;
354     }
355     rs = fscanf((FILE*)fd, "%i %i %i", &ax, &ay, &az);
356     fclose(fd);
357     if (rs != 3){
358         fprintf(stderr, "cannot read information from file\n");
359         return;
360     }
361
362     fprintf(stderr, "change obj %i %i %i\n", ax, ay, az);
363     dx = -ax / 100;
364     dy = -ay / 100;
365
366     actor->x = actor->x + dx;
367     actor->y = actor->y + dy;
368
369     if (actor->x > 800) actor->x = 0;
370     if (actor->x < 0) actor->x = 800;
371
372     if (actor->y > 480) actor->y = 0;
373     if (actor->y < 0) actor->y = 480;
374
375     set_actor_position(actor, actor->x, actor->y, actor->z, desktop_plugin);
376
377
378 }
379
380 void 
381 change_billboard(Actor * actor, AWallpaperPlugin *desktop_plugin)
382 {
383     gint count = 0;
384     Actor *a = NULL;
385      
386     //fprintf(stderr, "change_billboard\n");   
387     
388     if (desktop_plugin->priv->scene->notification < time(NULL)){
389         count = get_notify_count("general_missed");
390         a = g_ptr_array_index(actor->child, 0);
391         if (count > 0){
392             set_actor_visible(a, TRUE);            
393         }else {
394             set_actor_visible(a, FALSE);
395         }
396         count = get_notify_count("general_sms");
397         a = g_ptr_array_index(actor->child, 3);
398         if (count > 0){
399             set_actor_visible(a, TRUE);            
400         }else {
401             set_actor_visible(a, FALSE);
402         }
403         count = get_notify_count("general_chat");
404         a = g_ptr_array_index(actor->child, 1);
405         if (count > 0){
406             set_actor_visible(a, TRUE);            
407         }else {
408             set_actor_visible(a, FALSE);
409         }
410         count = get_notify_count("qgn_list_messagin");
411         a = g_ptr_array_index(actor->child, 2);
412         if (count > 0){
413             set_actor_visible(a, TRUE);            
414         }else {
415             set_actor_visible(a, FALSE);
416         }
417
418         desktop_plugin->priv->scene->notification = FALSE;
419     }
420     actor->time_start_animation = time(NULL) + 20;    
421 }
422
423 #if 0
424 void 
425 change_billboard1(Actor * actor, AWallpaperPlugin *desktop_plugin)
426 {
427     GtkWidget *label;
428     sqlite3 *db = NULL;
429     sqlite3_stmt *res = NULL;
430     gchar *errMsg = NULL, *message;
431     gchar sql[1024];
432     gint call_count=0, sms_count=0, rc=0;
433     GtkListStore *list = NULL;
434     PangoFontDescription *pfd = NULL;
435     
436     rc = sqlite3_open("/home/user/.rtcom-eventlogger/el.db", &db);
437     if (rc){
438         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
439     }else {
440         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d", 3);
441
442         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
443         if (rc != SQLITE_OK){
444             fprintf(stderr, "error prepare %d %s\n", rc, sql);
445         }
446         if (sqlite3_step(res) != SQLITE_ROW){
447             fprintf(stderr, "not sqlite_row\n");
448         }
449         call_count = sqlite3_column_int(res, 0);
450         //fprintf(stderr, "count missing calls = %d\n", call_count);
451         sqlite3_finalize(res);
452
453         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d and is_read=%d", 7, 0);
454         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
455         if (rc != SQLITE_OK){
456             fprintf(stderr, "error prepare %d %s\n", rc, sql);
457         }
458         if (sqlite3_step(res) != SQLITE_ROW){
459             fprintf(stderr, "not sqlite_row\n");
460         }
461         sms_count = sqlite3_column_int(res, 0);
462         //fprintf(stderr, "count sms = %d\n", sms_count);
463         sqlite3_finalize(res);
464
465
466         sqlite3_close(db);
467     }
468     label = actor->image;
469     message = g_markup_printf_escaped("<span bgcolor=\"%s\" foreground=\"%s\">Missed calls: %d Unread sms: %d</span>", "#FFFFFF", "#000000", call_count, sms_count);
470     gtk_label_set_markup(GTK_LABEL(label), message);
471     g_free(message);
472     pfd = pango_font_description_from_string("Sans 14");
473     gtk_widget_modify_font(GTK_WIDGET(label), NULL);
474     gtk_widget_modify_font(GTK_WIDGET(label), pfd);
475     pango_font_description_free(pfd);
476     actor->time_start_animation = time(NULL) + 20;    
477 }
478 #endif
479
480 void 
481 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
482 {
483     gint phase;
484     char *newfile;
485     gint x0 = 150,
486          x1 = 650, 
487          x, y;
488     struct timeval tvb;     
489     suseconds_t ms;
490     long sec;
491     double t;
492 #if 0
493     gint y0, y1, x2, y2;
494     double a, b, c;
495     a = (double)(y2 - (double)(x2*(y1-y0) + x1*y0 - x0*y1)/(x1-x0))/(x2*(x2-x0-x1)+x0*x1);
496     b = (double)(y1-y0)/(x1-x0) - (double)a*(x0+x1);
497     c = (double)(x1*y0 - x0*y1)/(x1-x0) + (double)a*x0*x1;
498     fprintf(stderr, "a=%f, b=%f, c=%f\n", a, b, c);
499 #endif
500     gettimeofday(&tvb, NULL);
501     
502     ms = tvb.tv_usec;
503     sec = tvb.tv_sec;
504
505     if (actor){
506         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
507             if (!actor->visible){
508                 actor->visible = TRUE;
509                 phase = get_moon_phase();
510                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
511                 if (actor->filename)
512                     g_free(actor->filename);
513                 actor->filename = newfile;
514                 actor->time_start_animation = sec - fast_rnd(60 * 60);
515                 actor->duration_animation = 1 * 60 * 60;
516                 create_hildon_actor(actor, desktop_plugin);
517
518             }
519             t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
520             if (t <= 1)
521                 x = path_line(x0, x1, t);
522             else 
523                 x = path_line(x1, x0, t-1);
524             y = 0.001920*x*x - 1.536*x + 337.2;
525             //y = a*x*x + b*x + c;
526
527             set_actor_position(actor, x, y, actor->z, desktop_plugin);
528
529             if (t>=2){
530                 actor->time_start_animation = sec;
531             }
532
533          }else if (actor->visible){
534             actor->visible = FALSE;
535             fprintf(stderr, "destroy moon \n");
536             destroy_hildon_actor(actor);
537             actor->time_start_animation = 0;
538         } 
539     }
540     
541 }
542
543 void 
544 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
545 {
546     double alt, azm;
547     gint x, y;
548
549     //fprintf(stderr, "change sun\n");
550     if (actor){
551         if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
552             if (!actor->visible){
553                 actor->visible = TRUE;
554                 create_hildon_actor(actor, desktop_plugin);
555             }
556             get_sun_pos(&alt, &azm);
557             get_sun_screen_pos(alt, azm, &x, &y);
558             actor->x = x;
559             actor->y = y;
560             set_actor_position(actor, x, y, actor->z, desktop_plugin);
561             actor->time_start_animation = time(NULL) + 60;
562          }else if (actor->visible){
563             actor->visible = FALSE;
564             destroy_hildon_actor(actor);
565             actor->time_start_animation = 0;
566         } 
567     }
568     
569 }
570
571 void 
572 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
573 {
574     gint x0 = -300, y0 = 225, scale0 = 100,
575          x1 = 800, y1 = 162, scale1 = 130, 
576          x, y, scale;
577     struct timeval tvb;     
578     suseconds_t ms;
579     long sec;
580     double t;
581
582     //fprintf(stderr, "change tram\n");
583     gettimeofday(&tvb, NULL);
584     
585     ms = tvb.tv_usec;
586     sec = tvb.tv_sec;
587     
588     if (!actor->visible){
589         actor->visible = TRUE;
590         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
591             if (actor->filename)
592                 g_free(actor->filename);
593             actor->filename = g_strdup("tram_dark.png");
594         } else{
595             if (actor->filename)
596                 g_free(actor->filename);
597             actor->filename = g_strdup("tram.png");
598         }
599         create_hildon_actor(actor, desktop_plugin);
600     }
601     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
602     x = path_line(x0, x1, t);
603     y = path_line(y0, y1, t);
604     scale = path_line(scale0, scale1, t);
605     set_actor_position(actor, x, y, actor->z, desktop_plugin);
606     set_actor_scale(actor, (double)scale/100, (double)scale/100);
607     if (t >= 1){
608         /* stop animation */
609         actor->visible = FALSE;
610         destroy_hildon_actor(actor);
611         actor->time_start_animation = sec + fast_rnd(60);
612     }
613 }
614
615 void
616 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
617 {
618     gint x0 = 620, y0 = 233,
619          x1 = 79, y1 = -146, 
620          x, y;
621     struct timeval tvb;     
622     suseconds_t ms;
623     long sec;
624     double t;
625
626     gettimeofday(&tvb, NULL);
627     
628     ms = tvb.tv_usec;
629     sec = tvb.tv_sec;
630 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
631    
632     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
633         if (actor->time_start_animation == 0){
634             actor->time_start_animation = sec + fast_rnd(180);
635             return;
636         }
637     }
638     if (!actor->visible){
639         actor->visible = TRUE;
640         create_hildon_actor(actor, desktop_plugin);
641     }
642     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
643     x = path_line(x0, x1, t);
644     y = path_line(y0, y1, t);
645     //scale = path_line(scale0, scale1, t);
646     set_actor_position(actor, x, y, actor->z, desktop_plugin);
647     if (t >= 1){
648         /* stop animation */
649         actor->visible = FALSE;
650         destroy_hildon_actor(actor);
651         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
652             actor->time_start_animation = 0;
653         else 
654             actor->time_start_animation = sec + fast_rnd(180);
655     }
656
657 }
658
659 void
660 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
661 {
662     gint x0 = -actor->width, y0 = 45,
663          x1 = 800, y1 = 20, 
664          x, y;
665     struct timeval tvb;     
666     suseconds_t ms;
667     long sec;
668     double t;
669
670     gettimeofday(&tvb, NULL);
671     
672     ms = tvb.tv_usec;
673     sec = tvb.tv_sec;
674 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
675     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
676         if (actor->time_start_animation == 0){
677             actor->time_start_animation = sec + fast_rnd(180);
678             return;
679         }
680     }
681     if (!actor->visible){
682         actor->visible = TRUE;
683         create_hildon_actor(actor, desktop_plugin);
684     }
685
686     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
687     x = path_line(x0, x1, t);
688     y = path_line(y0, y1, t);
689     //scale = path_line(scale0, scale1, t);
690     set_actor_position(actor, x, y, actor->z, desktop_plugin);
691     if (t >= 1){
692         /* stop animation */
693         actor->visible = FALSE;
694         destroy_hildon_actor(actor);
695         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
696             actor->time_start_animation = 0;
697         else 
698             actor->time_start_animation = sec + fast_rnd(180);
699     }
700
701 }
702
703 void
704 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
705 {
706     gint x0, y0 = 300, scale0 = 100,
707          x1, y1 = -actor->height, scale1 = 150, 
708          x, y, scale;
709     struct timeval tvb;     
710     suseconds_t ms;
711     long sec;
712     double t;
713     gchar *newfile;
714
715     //fprintf(stderr, "change cloud\n");
716     gettimeofday(&tvb, NULL);
717     
718     ms = tvb.tv_usec;
719     sec = tvb.tv_sec;
720    
721     if (!actor->visible){
722         actor->visible = TRUE;
723         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
724             newfile = g_strdup_printf("%s_dark.png", actor->name);
725         }else{
726             newfile = g_strdup_printf("%s.png", actor->name);
727         } 
728         if (actor->filename)
729             g_free(actor->filename);
730         actor->filename = newfile;
731          
732         create_hildon_actor(actor, desktop_plugin);
733     }
734     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
735     
736     if (desktop_plugin->priv->scene->wind_orientation == 1){
737         x0 = -actor->width;
738         x1 = 800;
739     }
740     else {
741         x0 = 800;
742         x1 = -actor->width;
743     }
744
745     x = path_line(x0, x1, t);    
746     y = -desktop_plugin->priv->scene->wind_angle * (x - x0) + actor->y;
747     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
748
749     set_actor_position(actor, x, y, actor->z, desktop_plugin);
750     set_actor_scale(actor, (double)scale/100, (double)scale/100);
751     if ((y < y1 || y > y0) || t >= 1){
752         /* stop animation */
753         actor->visible = FALSE;
754         destroy_hildon_actor(actor);
755         actor->time_start_animation = sec + fast_rnd(300);
756         actor->y = fast_rnd(300);
757     }
758
759 }
760
761 void
762 change_wind(Actor *actor, AWallpaperPlugin *desktop_plugin)
763 {
764     desktop_plugin->priv->scene->wind_orientation = fast_rnd(2);
765     if (desktop_plugin->priv->scene->wind_orientation == 0) desktop_plugin->priv->scene->wind_orientation = -1;
766     desktop_plugin->priv->scene->wind_angle = (double)(fast_rnd(200) - 100) / 100;
767     actor->time_start_animation = time(NULL) + (fast_rnd(10) + 10) * 60;
768     //fprintf(stderr, "change wind orient = %d angle = %f after = %d\n", scene.wind_orientation, scene.wind_angle, actor->time_start_animation-time(NULL));
769 }
770
771 void 
772 change_window1(Actor * actor, AWallpaperPlugin *desktop_plugin)
773 {
774     gint now = time(NULL);
775     if (desktop_plugin->priv->scene->daytime == TIME_DAY){
776         if (actor->widget){
777             actor->visible = FALSE;
778             destroy_hildon_actor(actor);
779         }
780         actor->time_start_animation = 0;
781         return;
782     }else {
783         if (!actor->widget)
784             create_hildon_actor(actor, desktop_plugin);
785         if (actor->time_start_animation == 0){
786             actor->time_start_animation = now + fast_rnd(30);
787             return;
788         }
789     }
790
791     if (!actor->visible)
792         actor->visible = TRUE;
793     else 
794         actor->visible = FALSE;
795     set_actor_visible(actor, actor->visible);
796     actor->time_start_animation = now + fast_rnd(60) + 10;
797
798 }
799
800 void 
801 change_signal(Actor * actor, AWallpaperPlugin *desktop_plugin)
802 {
803     gint now = time(NULL);
804     Actor *a;
805     a = g_ptr_array_index(actor->child, 0);
806     if (a->visible)
807         a->visible = FALSE;
808     else 
809         a->visible = TRUE;
810     set_actor_visible(a, a->visible);
811     
812     a = g_ptr_array_index(actor->child, 1);
813     if (a->visible)
814         a->visible = FALSE;
815     else 
816         a->visible = TRUE;
817     set_actor_visible(a, a->visible);
818
819     actor->time_start_animation = now + fast_rnd(30) + 10;
820 }
821
822 void
823 change_tape(Actor *actor, AWallpaperPlugin *desktop_plugin)
824 {
825     gint x, y, i;
826     Actor *a;
827
828     if (!desktop_plugin->priv->rich_animation) return;
829     
830     char * accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord";
831     //char * accel_filename = "/home/tanya/coord";
832
833     FILE *fd = NULL;
834     int rs, ax, ay, az;
835     fd = fopen(accel_filename, "r");
836     if (fd == NULL){
837         //fprintf(stderr, "cannot open file\n");
838         fd = fopen("/home/user/coord", "r"); 
839     }
840     rs = fscanf((FILE*)fd, "%i %i %i", &ax, &ay, &az);
841     fclose(fd);
842     if (rs != 3){
843         fprintf(stderr, "cannot read information from file\n");
844         return;
845
846     }
847
848     //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);
849     int ang = (int)floor(atan2(ay, ax)*180/M_PI);
850     if (ang < 0) ang = 360+ang;
851
852     if (!desktop_plugin->priv->rich_animation) return;
853
854     for (i=0; i<16; i++){
855         a = g_ptr_array_index(actor->child, i);
856         if (a->scale == 100) a->scale = ang;
857         if (abs(a->scale - ang) > 10){
858             if (a->scale > ang){
859                 if ((a->scale - ang) < (ang + (360-a->scale))) a->scale--;
860                 else a->scale++;
861             }
862             if (a->scale < ang) {
863                 if (ang - a->scale < (a->scale+(360-ang))) a->scale++;
864                 else a->scale--;
865             }
866             if (a->scale > 360) a->scale = 0;
867             if (a->scale < 0) a->scale = 360;
868         }
869     
870         x = a->x - (float)cos(a->scale*M_PI/180)*a->z;
871         y = a->y - (float)sin(a->scale*M_PI/180)*a->z;
872         //x = round(a->x - (float)cos(a->scale*M_PI/180)*a->z);
873         //y = round(a->y - (float)sin(a->scale*M_PI/180)*a->z);
874         //x = a->x - cos(angle)*a->z;
875         //y = a->y - sin(angle)*a->z;
876         if ((a->scale > 270 || a->scale < 90) && x < -a->width*cos(a->scale*M_PI/180)){ 
877             x = 800; 
878             y = fast_rnd(480);
879         } 
880         if ((a->scale > 90 && a->scale < 270) && x > 800 - a->width*cos(a->scale*M_PI/180)){
881             x = 0;
882             y = fast_rnd(480);
883         }
884         if (a->scale > 0 && a->scale < 180 && y < -a->width*sin(a->scale*M_PI/180)){
885             y = 480;
886             x = fast_rnd(800);
887         }
888         if (a->scale < 360 && a->scale > 180 && y > 480 - a->width*sin(a->scale*M_PI/180)){
889             y = 0;
890             x = fast_rnd(800);
891         }
892         //if (i ==0) fprintf(stderr, "x=%d y=%d ang=%d speed=%d\n", x, y, a->scale, a->z);
893         set_actor_rotation(a, HILDON_AA_Z_AXIS, a->scale, 0, 0, 0);
894         set_actor_position(a, x, y, a->z, desktop_plugin);
895         a->x = x;
896         a->y = y;
897     }
898     
899 }
900
901 void
902 change_layer(Actor * actor, AWallpaperPlugin *desktop_plugin)
903 {
904     gint y, speed1 = 8, speed2 = 16;
905     Actor *a;
906
907     if (!desktop_plugin->priv->rich_animation) return;
908
909     a = g_ptr_array_index(actor->child, 0);
910     y = a->y + speed1;
911     if (y > 480) y = -480;
912     set_actor_position(a, a->x, y, a->z, desktop_plugin);
913     a->y = y;
914     
915     a = g_ptr_array_index(actor->child, 1);
916     y = a->y + speed1;
917     if (y > 480) y = -480;
918     set_actor_position(a, a->x, y, a->z, desktop_plugin);
919     a->y = y;
920
921     a = g_ptr_array_index(actor->child, 2);
922     y = a->y + speed2;
923     if (y > 480) y = -480;
924     set_actor_position(a, a->x, y, a->z, desktop_plugin);
925     a->y = y;
926
927     a = g_ptr_array_index(actor->child, 3);
928     y = a->y + speed2;
929     if (y > 480) y = -480;
930     set_actor_position(a, a->x, y, a->z, desktop_plugin);
931     a->y = y;
932 }
933
934 void 
935 change_static_actor(Actor * actor, AWallpaperPlugin *desktop_plugin)
936 {
937     gchar *newfile;
938     newfile = g_strdup_printf("%s%d.png", actor->name, desktop_plugin->priv->scene->daytime); 
939     if (actor->filename)
940             g_free(actor->filename);
941     actor->filename = newfile;
942     change_hildon_actor(actor, desktop_plugin);
943 }
944
945 void 
946 change_static_actor_with_corner(Actor * actor, AWallpaperPlugin *desktop_plugin)
947 {
948     gchar buffer[2048];
949
950     if (desktop_plugin->priv->right_corner)
951         gtk_widget_destroy(desktop_plugin->priv->right_corner);
952     snprintf(buffer, sizeof(buffer) - 1, "%s/%s/town%i_right_corner.png", \
953                                   THEME_PATH, desktop_plugin->priv->theme, desktop_plugin->priv->scene->daytime);
954     desktop_plugin->priv->right_corner = gtk_image_new_from_file (buffer);
955     if (desktop_plugin->priv->right_corner){
956         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), desktop_plugin->priv->right_corner, 0, 0);
957         gtk_widget_show (desktop_plugin->priv->right_corner);
958     }
959     change_static_actor(actor, desktop_plugin);
960
961 }