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