added debug inaformation and redisigned dbus signals
[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 Actor* 
28 init_object(AWallpaperPlugin *desktop_plugin, 
29             gchar * name, 
30             gchar * filename, 
31             gint x, 
32             gint y, 
33             gint z, 
34             gint width, 
35             gint height, 
36             gboolean visible, 
37             gboolean load_image,
38             gint scale, 
39             gint opacity, 
40             void (*pfunc_change)(Actor*),
41             void (*pfunc_probability)(Actor*),
42             GPtrArray *child
43            )
44 {
45     Actor *actor = NULL;
46     actor = g_new0(Actor, 1);
47     actor->x = x;
48     actor->y = y;
49     actor->z = z;
50     actor->width = width;
51     actor->height = height;
52     actor->visible = visible;
53     actor->scale = scale;
54     actor->opacity = opacity;
55     actor->filename = g_strdup(filename);
56     actor->name = g_strdup(name);
57     actor->func_change = (gpointer)pfunc_change; 
58     actor->func_probability = (gpointer)pfunc_probability;
59     actor->child = child;
60     if (load_image)
61         create_hildon_actor(actor, desktop_plugin);
62     else 
63          actor->widget = NULL;
64     actor->time_start_animation = 0;
65     actor->duration_animation = 0;
66     return actor;
67 }
68
69 void 
70 destroy_actor(Actor *actor)
71 {
72     if (actor){
73         if (actor->child){
74             g_ptr_array_free(actor->child, TRUE);
75         }
76         if (actor->filename)
77             g_free(actor->filename);
78         if (actor->name)
79             g_free(actor->name);
80         gtk_widget_destroy(actor->widget);
81         //actor->widget = NULL;
82         g_free(actor);
83     }
84 }
85 static gint 
86 path_line(gint x0, gint x1, double t)
87 {
88     // уравниение прямой
89     return ((x1 - x0) * t + x0);
90 }
91 void
92 set_actor_scale(Actor *actor, double scalex, double scaley)
93 {
94     hildon_animation_actor_set_scale(
95             HILDON_ANIMATION_ACTOR(actor->widget), 
96             scalex, 
97             scaley
98     );
99
100 }
101
102 void 
103 set_actor_visible(Actor *actor, gboolean visible)
104 {
105     hildon_animation_actor_set_show(HILDON_ANIMATION_ACTOR(actor->widget), visible);
106 }
107
108 void
109 set_actor_position(Actor *actor, gint x, gint y, gint z, AWallpaperPlugin *desktop_plugin)
110 {
111     hildon_animation_actor_set_position_full(HILDON_ANIMATION_ACTOR (actor->widget), 
112                                              x-desktop_plugin->priv->xapplet, 
113                                              y-desktop_plugin->priv->yapplet, 
114                                              z);
115 }
116
117 int get_notify_count(gchar *notify_type)
118 {
119     sqlite3 *db = NULL;
120     sqlite3 *res = NULL;
121     gint rc = 0, result = 0;
122     gchar sql[1024];
123
124     rc = sqlite3_open("/home/user/.config/hildon-desktop/notifications.db", &db);
125     if (rc){
126         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
127     }else {
128         snprintf(sql, sizeof(sql)-1, "select count(id) from notifications where icon_name='general_%s'", notify_type);
129         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
130         if (rc != SQLITE_OK){
131             fprintf(stderr, "error prepare %d %s\n", rc, sql);
132         }
133         if (sqlite3_step(res) != SQLITE_ROW){
134             fprintf(stderr, "not sqlite_row\n");
135         }
136         result = sqlite3_column_int(res, 0);
137         //fprintf(stderr, "count missing calls = %d\n", call_count);
138         sqlite3_finalize(res);
139
140         sqlite3_close(db);
141     }
142     return result;
143 }
144 void read_notification(AWallpaperPlugin *desktop_plugin)
145 {
146     gchar *message = NULL;
147     gint count = 0;
148     
149     fprintf(stderr, "read notification \n");
150     count = get_notify_count("missed");
151     if (count > 0){
152         message = g_strdup_printf("%s: %d", _("Missed calls"), count);
153     }
154     count = get_notify_count("sms");
155     if (count > 0){
156         if (message){
157             message = g_strdup_printf("%s \n%s: %d", message, _("Missed sms"), count);
158         }else {
159             message = g_strdup_printf("%s: %d", _("Missed sms"), count);
160         }
161     }
162     count = get_notify_count("chat");
163     if (count > 0){
164         if (message){
165             message = g_strdup_printf("%s \n%s: %d", message, _("Missed chat"), count);
166         }else {
167             message = g_strdup_printf("%s: %d", _("Missed chat"), count);
168         }
169     }
170     count = get_notify_count("mail");
171     if (count > 0){
172         if (message){
173             message = g_strdup_printf("%s \n%s: %d", message, _("Missed mail"), count);
174         }else {
175             message = g_strdup_printf("%s: %d", _("Missed mail"), count);
176         }
177     }
178     desktop_plugin->priv->scene->notification = g_strdup(message);
179     g_free(message);
180 }
181
182 void 
183 change_billboard(Actor * actor, AWallpaperPlugin *desktop_plugin)
184 {
185     GtkWidget *label;
186     gchar *mes = NULL;
187     PangoFontDescription *pfd = NULL;
188      
189      fprintf(stderr, "change_billboard\n");   
190     if (desktop_plugin->priv->scene->notification){
191         label = actor->image;
192         mes = g_markup_printf_escaped("<span bgcolor=\"%s\" foreground=\"%s\">%s</span>", "#FFFFFF", "#000000", 
193                                       desktop_plugin->priv->scene->notification);
194         gtk_label_set_markup(GTK_LABEL(label), mes);
195         pfd = pango_font_description_from_string("Sans 16");
196         gtk_widget_modify_font(GTK_WIDGET(label), NULL);
197         gtk_widget_modify_font(GTK_WIDGET(label), pfd);
198         pango_font_description_free(pfd);
199     }
200     actor->time_start_animation = time(NULL) + 20;    
201 }
202
203
204 void 
205 change_billboard1(Actor * actor, AWallpaperPlugin *desktop_plugin)
206 {
207     GtkWidget *label;
208     sqlite3 *db = NULL;
209     sqlite3_stmt *res = NULL;
210     gchar *errMsg = NULL, *message;
211     gchar sql[1024];
212     gint call_count=0, sms_count=0, rc=0;
213     GtkListStore *list = NULL;
214     PangoFontDescription *pfd = NULL;
215     
216     rc = sqlite3_open("/home/user/.rtcom-eventlogger/el.db", &db);
217     if (rc){
218         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
219     }else {
220         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d", 3);
221 //#if 0
222         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
223         if (rc != SQLITE_OK){
224             fprintf(stderr, "error prepare %d %s\n", rc, sql);
225         }
226         if (sqlite3_step(res) != SQLITE_ROW){
227             fprintf(stderr, "not sqlite_row\n");
228         }
229         call_count = sqlite3_column_int(res, 0);
230         //fprintf(stderr, "count missing calls = %d\n", call_count);
231         sqlite3_finalize(res);
232
233         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d and is_read=%d", 7, 0);
234         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
235         if (rc != SQLITE_OK){
236             fprintf(stderr, "error prepare %d %s\n", rc, sql);
237         }
238         if (sqlite3_step(res) != SQLITE_ROW){
239             fprintf(stderr, "not sqlite_row\n");
240         }
241         sms_count = sqlite3_column_int(res, 0);
242         //fprintf(stderr, "count sms = %d\n", sms_count);
243         sqlite3_finalize(res);
244
245 //#endif
246         sqlite3_close(db);
247     }
248     label = actor->image;
249     message = g_markup_printf_escaped("<span bgcolor=\"%s\" foreground=\"%s\">Missed calls: %d Unread sms: %d</span>", "#FFFFFF", "#000000", call_count, sms_count);
250     gtk_label_set_markup(GTK_LABEL(label), message);
251     g_free(message);
252     pfd = pango_font_description_from_string("Sans 14");
253     gtk_widget_modify_font(GTK_WIDGET(label), NULL);
254     gtk_widget_modify_font(GTK_WIDGET(label), pfd);
255     pango_font_description_free(pfd);
256     actor->time_start_animation = time(NULL) + 20;    
257 }
258
259
260 void 
261 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
262 {
263     gint phase;
264     char *newfile;
265     gint x0 = 150,
266          x1 = 650, 
267          x, y;
268     struct timeval tvb;     
269     suseconds_t ms;
270     long sec;
271     double t;
272 #if 0
273     gint y0, y1, x2, y2;
274     double a, b, c;
275     a = (double)(y2 - (double)(x2*(y1-y0) + x1*y0 - x0*y1)/(x1-x0))/(x2*(x2-x0-x1)+x0*x1);
276     b = (double)(y1-y0)/(x1-x0) - (double)a*(x0+x1);
277     c = (double)(x1*y0 - x0*y1)/(x1-x0) + (double)a*x0*x1;
278     fprintf(stderr, "a=%f, b=%f, c=%f\n", a, b, c);
279 #endif
280     gettimeofday(&tvb, NULL);
281     
282     ms = tvb.tv_usec;
283     sec = tvb.tv_sec;
284
285     if (actor){
286         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
287             if (!actor->visible){
288                 actor->visible = TRUE;
289                 phase = get_moon_phase();
290                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
291                 if (actor->filename)
292                     g_free(actor->filename);
293                 actor->filename = newfile;
294                 actor->time_start_animation = sec - fast_rnd(60 * 60);
295                 actor->duration_animation = 1 * 60 * 60;
296                 create_hildon_actor(actor, desktop_plugin);
297
298             }
299             t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
300             if (t <= 1)
301                 x = path_line(x0, x1, t);
302             else 
303                 x = path_line(x1, x0, t-1);
304             y = 0.001920*x*x - 1.536*x + 337.2;
305             //y = a*x*x + b*x + c;
306
307             set_actor_position(actor, x, y, actor->z, desktop_plugin);
308
309             if (t>=2){
310                 actor->time_start_animation = sec;
311             }
312
313          }else if (actor->visible){
314             actor->visible = FALSE;
315             fprintf(stderr, "destroy moon \n");
316             destroy_hildon_actor(actor);
317             actor->time_start_animation = 0;
318         } 
319     }
320     
321 }
322
323 void 
324 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
325 {
326     double alt, azm;
327     gint x, y;
328
329     //fprintf(stderr, "change sun\n");
330     if (actor){
331         if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
332             if (!actor->visible){
333                 actor->visible = TRUE;
334                 create_hildon_actor(actor, desktop_plugin);
335             }
336             get_sun_pos(&alt, &azm);
337             get_sun_screen_pos(alt, azm, &x, &y);
338             actor->x = x;
339             actor->y = y;
340             set_actor_position(actor, x, y, actor->z, desktop_plugin);
341             actor->time_start_animation = time(NULL) + 60;
342          }else if (actor->visible){
343             actor->visible = FALSE;
344             destroy_hildon_actor(actor);
345             actor->time_start_animation = 0;
346         } 
347     }
348     
349 }
350
351 void 
352 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
353 {
354     gint x0 = -300, y0 = 225, scale0 = 100,
355          x1 = 800, y1 = 162, scale1 = 130, 
356          x, y, scale;
357     struct timeval tvb;     
358     suseconds_t ms;
359     long sec;
360     double t;
361
362     //fprintf(stderr, "change tram\n");
363     gettimeofday(&tvb, NULL);
364     
365     ms = tvb.tv_usec;
366     sec = tvb.tv_sec;
367     
368     if (!actor->visible){
369         actor->visible = TRUE;
370         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
371             if (actor->filename)
372                 g_free(actor->filename);
373             actor->filename = g_strdup("tram_dark.png");
374         } else{
375             if (actor->filename)
376                 g_free(actor->filename);
377             actor->filename = g_strdup("tram.png");
378         }
379         create_hildon_actor(actor, desktop_plugin);
380     }
381     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
382     x = path_line(x0, x1, t);
383     y = path_line(y0, y1, t);
384     scale = path_line(scale0, scale1, t);
385     set_actor_position(actor, x, y, actor->z, desktop_plugin);
386     set_actor_scale(actor, (double)scale/100, (double)scale/100);
387     if (t >= 1){
388         /* stop animation */
389         actor->visible = FALSE;
390         destroy_hildon_actor(actor);
391         actor->time_start_animation = sec + fast_rnd(60);
392     }
393 }
394
395 void
396 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
397 {
398     gint x0 = 620, y0 = 233,
399          x1 = 79, y1 = -146, 
400          x, y;
401     struct timeval tvb;     
402     suseconds_t ms;
403     long sec;
404     double t;
405
406     gettimeofday(&tvb, NULL);
407     
408     ms = tvb.tv_usec;
409     sec = tvb.tv_sec;
410 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
411    
412     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
413         if (actor->time_start_animation == 0){
414             actor->time_start_animation = sec + fast_rnd(180);
415             return;
416         }
417     }
418     if (!actor->visible){
419         actor->visible = TRUE;
420         create_hildon_actor(actor, desktop_plugin);
421     }
422     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
423     x = path_line(x0, x1, t);
424     y = path_line(y0, y1, t);
425     //scale = path_line(scale0, scale1, t);
426     set_actor_position(actor, x, y, actor->z, desktop_plugin);
427     if (t >= 1){
428         /* stop animation */
429         actor->visible = FALSE;
430         destroy_hildon_actor(actor);
431         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
432             actor->time_start_animation = 0;
433         else 
434             actor->time_start_animation = sec + fast_rnd(180);
435     }
436
437 }
438
439 void
440 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
441 {
442     gint x0 = -actor->width, y0 = 45,
443          x1 = 800, y1 = 20, 
444          x, y;
445     struct timeval tvb;     
446     suseconds_t ms;
447     long sec;
448     double t;
449
450     gettimeofday(&tvb, NULL);
451     
452     ms = tvb.tv_usec;
453     sec = tvb.tv_sec;
454 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
455     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
456         if (actor->time_start_animation == 0){
457             actor->time_start_animation = sec + fast_rnd(180);
458             return;
459         }
460     }
461     if (!actor->visible){
462         actor->visible = TRUE;
463         create_hildon_actor(actor, desktop_plugin);
464     }
465
466     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
467     x = path_line(x0, x1, t);
468     y = path_line(y0, y1, t);
469     //scale = path_line(scale0, scale1, t);
470     set_actor_position(actor, x, y, actor->z, desktop_plugin);
471     if (t >= 1){
472         /* stop animation */
473         actor->visible = FALSE;
474         destroy_hildon_actor(actor);
475         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
476             actor->time_start_animation = 0;
477         else 
478             actor->time_start_animation = sec + fast_rnd(180);
479     }
480
481 }
482
483 void
484 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
485 {
486     gint x0, y0 = 300, scale0 = 100,
487          x1, y1 = -actor->height, scale1 = 150, 
488          x, y, scale;
489     struct timeval tvb;     
490     suseconds_t ms;
491     long sec;
492     double t;
493     gchar *newfile;
494
495     //fprintf(stderr, "change cloud\n");
496     gettimeofday(&tvb, NULL);
497     
498     ms = tvb.tv_usec;
499     sec = tvb.tv_sec;
500    
501     if (!actor->visible){
502         actor->visible = TRUE;
503         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
504             newfile = g_strdup_printf("%s_dark.png", actor->name);
505         }else{
506             newfile = g_strdup_printf("%s.png", actor->name);
507         } 
508         if (actor->filename)
509             g_free(actor->filename);
510         actor->filename = newfile;
511          
512         create_hildon_actor(actor, desktop_plugin);
513     }
514     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
515     
516     if (desktop_plugin->priv->scene->wind_orientation == 1){
517         x0 = -actor->width;
518         x1 = 800;
519     }
520     else {
521         x0 = 800;
522         x1 = -actor->width;
523     }
524
525     x = path_line(x0, x1, t);    
526     y = -desktop_plugin->priv->scene->wind_angle * (x - x0) + actor->y;
527     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
528
529     set_actor_position(actor, x, y, actor->z, desktop_plugin);
530     set_actor_scale(actor, (double)scale/100, (double)scale/100);
531     if ((y < y1 || y > y0) || t >= 1){
532         /* stop animation */
533         actor->visible = FALSE;
534         destroy_hildon_actor(actor);
535         actor->time_start_animation = sec + fast_rnd(300);
536         actor->y = fast_rnd(300);
537     }
538
539 }
540
541 void
542 change_wind(Actor *actor, AWallpaperPlugin *desktop_plugin)
543 {
544     desktop_plugin->priv->scene->wind_orientation = fast_rnd(2);
545     if (desktop_plugin->priv->scene->wind_orientation == 0) desktop_plugin->priv->scene->wind_orientation = -1;
546     desktop_plugin->priv->scene->wind_angle = (double)(fast_rnd(200) - 100) / 100;
547     actor->time_start_animation = time(NULL) + (fast_rnd(10) + 10) * 60;
548     //fprintf(stderr, "change wind orient = %d angle = %f after = %d\n", scene.wind_orientation, scene.wind_angle, actor->time_start_animation-time(NULL));
549 }
550
551 void 
552 change_window1(Actor * actor, AWallpaperPlugin *desktop_plugin)
553 {
554     gint now = time(NULL);
555     if (desktop_plugin->priv->scene->daytime == TIME_DAY){
556         if (actor->widget){
557             actor->visible = FALSE;
558             destroy_hildon_actor(actor);
559         }
560         actor->time_start_animation = 0;
561         return;
562     }else {
563         if (!actor->widget)
564             create_hildon_actor(actor, desktop_plugin);
565         if (actor->time_start_animation == 0){
566             actor->time_start_animation = now + fast_rnd(30);
567             return;
568         }
569     }
570
571     if (!actor->visible)
572         actor->visible = TRUE;
573     else 
574         actor->visible = FALSE;
575     set_actor_visible(actor, actor->visible);
576     actor->time_start_animation = now + fast_rnd(60) + 10;
577
578 }
579
580 void 
581 change_signal(Actor * actor, AWallpaperPlugin *desktop_plugin)
582 {
583     gint now = time(NULL);
584     Actor *a;
585     a = g_ptr_array_index(actor->child, 0);
586     if (a->visible)
587         a->visible = FALSE;
588     else 
589         a->visible = TRUE;
590     set_actor_visible(a, a->visible);
591     
592     a = g_ptr_array_index(actor->child, 1);
593     if (a->visible)
594         a->visible = FALSE;
595     else 
596         a->visible = TRUE;
597     set_actor_visible(a, a->visible);
598
599     actor->time_start_animation = now + fast_rnd(30) + 10;
600 }
601
602 void
603 change_layer(Actor * actor, AWallpaperPlugin *desktop_plugin)
604 {
605     gint y, speed1 = 8, speed2 = 16;
606     Actor *a;
607
608     if (!desktop_plugin->priv->rich_animation) return;
609
610     a = g_ptr_array_index(actor->child, 0);
611     y = a->y + speed1;
612     if (y > 480) y = -480;
613     set_actor_position(a, a->x, y, a->z, desktop_plugin);
614     a->y = y;
615     
616     a = g_ptr_array_index(actor->child, 1);
617     y = a->y + speed1;
618     if (y > 480) y = -480;
619     set_actor_position(a, a->x, y, a->z, desktop_plugin);
620     a->y = y;
621
622     a = g_ptr_array_index(actor->child, 2);
623     y = a->y + speed2;
624     if (y > 480) y = -480;
625     set_actor_position(a, a->x, y, a->z, desktop_plugin);
626     a->y = y;
627
628     a = g_ptr_array_index(actor->child, 3);
629     y = a->y + speed2;
630     if (y > 480) y = -480;
631     set_actor_position(a, a->x, y, a->z, desktop_plugin);
632     a->y = y;
633 }
634
635 void 
636 change_static_actor(Actor * actor, AWallpaperPlugin *desktop_plugin)
637 {
638     gchar *newfile;
639     newfile = g_strdup_printf("%s%d.png", actor->name, desktop_plugin->priv->scene->daytime); 
640     if (actor->filename)
641             g_free(actor->filename);
642     actor->filename = newfile;
643     change_hildon_actor(actor, desktop_plugin);
644 }
645
646 void 
647 change_static_actor_with_corner(Actor * actor, AWallpaperPlugin *desktop_plugin)
648 {
649     gchar buffer[2048];
650
651     if (desktop_plugin->priv->right_corner)
652         gtk_widget_destroy(desktop_plugin->priv->right_corner);
653     snprintf(buffer, sizeof(buffer) - 1, "%s/%s/town%i_right_corner.png", \
654                                   THEME_PATH, desktop_plugin->priv->theme, desktop_plugin->priv->scene->daytime);
655     desktop_plugin->priv->right_corner = gtk_image_new_from_file (buffer);
656     if (desktop_plugin->priv->right_corner){
657         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), desktop_plugin->priv->right_corner, 0, 0);
658         gtk_widget_show (desktop_plugin->priv->right_corner);
659     }
660     change_static_actor(actor, desktop_plugin);
661
662 }