2a70916ae3ce62657ab4f9b248476c22eaae48f8
[livewp] / applet / src / livewp-main.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-common.h"
26 #include "livewp-scene.h"
27 #include "livewp-settings.h"
28 #include "livewp-home-widget.h"
29 /*******************************************************************************/
30
31 void set_live_bg (Display *display, Window xwindow, int mode);
32 void quit_from_program (Animation_WallpaperPrivate *priv);
33 void view_state_changed (Animation_WallpaperPrivate *priv);
34 static gboolean short_timeout (AWallpaperPlugin *desktop_plugin);
35 void run_long_timeout(AWallpaperPlugin *desktop_plugin);
36 gboolean long_timeout (AWallpaperPlugin *desktop_plugin);
37 void conky_visible(AWallpaperPlugin *desktop_plugin);
38 void flash_visible(AWallpaperPlugin *desktop_plugin);
39
40 void 
41 set_live_bg (Display *display, Window xwindow, int mode){
42    Atom atom;
43    atom = XInternAtom (display, "_HILDON_LIVE_DESKTOP_BACKGROUND", False);
44    fprintf (stderr, "XID: 0x%x\n", (unsigned)xwindow);
45
46    XChangeProperty (display,
47                  xwindow,
48                   atom,
49                   XA_INTEGER, 32, PropModeReplace,
50                   (unsigned char *) &mode, 1);
51 }
52 /*******************************************************************************/
53 gboolean
54 delayed_pause_video (AWallpaperPlugin *desktop_plugin){
55
56     if (!desktop_plugin->priv->visible){
57         gst_element_set_state (desktop_plugin->priv->pipeline, GST_STATE_PAUSED);
58     }
59     return FALSE;
60 }
61 /*******************************************************************************/
62 void
63 view_state_changed (Animation_WallpaperPrivate *priv)
64 {
65    fprintf(stderr," VIew %i State %i\n", priv->view, priv->visible);
66    if (priv->visible){  
67        /* ToDo  make undependent function */
68        /* For Video */
69        if (!strcmp(priv->theme,"Video")){
70            if (priv->pipeline){
71                gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
72            }else{
73                init_scene_Video(priv->desktop_plugin);
74            }
75        }
76        /* For Conky */
77        if (!strcmp(priv->theme,"Conky")&& priv->running){
78            conky_visible(priv->desktop_plugin);
79            return;
80        }
81        /* For Flash */
82        if (!strcmp(priv->theme,"Flash")&& priv->running){
83            flash_visible(priv->desktop_plugin);
84            return;
85        }
86
87        if (!priv->running){
88             if (priv->hash_theme && g_hash_table_lookup(priv->hash_theme, "exec_path")){
89                 init_scene_External(priv->desktop_plugin);
90             }
91        }
92        if (priv->long_timer == 0 ){
93             priv->long_timer = g_timeout_add(LONG_TIMER, (GtkFunction)long_timeout, priv->desktop_plugin);
94             run_long_timeout(priv->desktop_plugin);
95        }else {
96             run_long_timeout(priv->desktop_plugin);
97        }
98    }else{
99         /* For Video */
100         if (priv->pipeline){
101            if (priv->one_in_all_view)
102                 g_timeout_add(200, (GtkFunction)delayed_pause_video, priv->desktop_plugin);
103            else
104                 gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
105            return;
106         }
107         /* For Conky */
108         if (!strcmp(priv->theme,"Conky")){
109            conky_visible(priv->desktop_plugin);
110            return;
111         }
112         if (priv->long_timer != 0 ){
113             g_source_remove(priv->long_timer);
114             priv->long_timer = 0;
115         }
116    }
117 }
118 /*******************************************************************************/
119 gboolean
120 check_alive_event(Animation_WallpaperPrivate *priv) 
121 {
122     if ( time(NULL) - priv->last_alive_event > 10*60) /* If last event later 10 minute */
123         quit_from_program(priv);
124     return TRUE;
125 }
126
127 /*******************************************************************************/
128 void
129 view_changed (GConfClient *client, guint cnxn_id,
130                  GConfEntry *entry, Animation_WallpaperPrivate *priv)
131 {
132    if (entry->value->type == GCONF_VALUE_INT) {
133         if (priv->view == gconf_value_get_int(entry->value)){
134             if (priv->visible != TRUE){
135                 priv->visible = TRUE;
136                 view_state_changed(priv);
137             }
138         }else{
139             if (priv->visible != FALSE){
140                 priv->visible = FALSE;
141                 view_state_changed(priv);
142             }
143         }
144     }
145 }
146 /*******************************************************************************/
147 void
148 quit_from_program (Animation_WallpaperPrivate *priv)
149 {
150      fprintf(stderr,"quit_from_program\n");
151      if (priv){
152              livewp_deinitialize_dbus(priv);
153          if (priv->view_notify != 0) { 
154             gconf_client_notify_remove (gconf_client_get_default (), priv->view_notify);
155             priv->view_notify = 0;
156          }
157              if (priv->long_timer){
158                     g_source_remove(priv->long_timer);
159                 priv->long_timer = 0;
160              }
161              if (priv->short_timer){
162                     g_source_remove(priv->short_timer);
163                     priv->short_timer = 0;
164              }
165              destroy_scene(priv->desktop_plugin);
166          osso_deinitialize(priv->osso);
167          //g_hash_table_destroy(priv->hash_scene_func);
168          g_free(priv->desktop_plugin);
169          priv->desktop_plugin = NULL;
170          g_free(priv);
171          priv = NULL;
172      } 
173      fprintf(stderr,"end of quit_from_program\n");
174      gtk_main_quit();;
175 }
176 /*******************************************************************************/
177 static gboolean
178 short_timeout (AWallpaperPlugin *desktop_plugin)
179 {
180     //gint daytime = get_daytime();
181     GSList * tmp;
182     void (*pfunc)(gpointer, gpointer);
183     time_t now;
184     Actor *actor;
185     gboolean stop_flag = TRUE;
186
187     if (!desktop_plugin->priv->visible || !desktop_plugin->priv->rich_animation){
188         desktop_plugin->priv->short_timer = 0;
189         return FALSE;
190     }
191
192     now = time(NULL);
193     //scene.daytime = daytime;
194     /* fprintf(stderr, "Short timer %d\n", now); */
195     tmp = desktop_plugin->priv->scene->actors;
196     while (tmp != NULL){
197            actor = tmp->data;
198            if (now >= actor->time_start_animation  
199                && actor->time_start_animation > 0
200                /* && now - actor->time_start_animation <= actor->duration_animation*/){
201                 pfunc = actor->func_change;
202                 if (pfunc){ 
203                     (*pfunc)(actor, desktop_plugin);
204                     stop_flag = FALSE;
205                 }
206             }
207             tmp = g_slist_next(tmp);
208     }
209     if (stop_flag){
210          desktop_plugin->priv->short_timer = 0;
211          return FALSE;
212     }else
213          return TRUE; /* keep running this event */
214 }
215 /*******************************************************************************/
216 void
217 run_long_timeout(AWallpaperPlugin *desktop_plugin)
218 {
219
220     gint daytime = get_daytime();
221     GSList * tmp;
222     void (*pfunc)(gpointer, gpointer);
223     time_t now;
224     Actor *actor;
225
226     if (!desktop_plugin->priv->scene)
227         return;
228     /*ifprintf(stderr, "!!!run long timeout short_timer=%d\n", desktop_plugin->priv->short_timer); */
229     if (desktop_plugin->priv->scene->daytime != daytime){
230         desktop_plugin->priv->scene->daytime = daytime;
231         tmp = desktop_plugin->priv->scene->actors;
232         while (tmp != NULL){
233             //change_actor(tmp->data);
234             pfunc =((Actor*)tmp->data)->func_change;
235             if (pfunc){
236                 (*pfunc)(tmp->data, desktop_plugin);
237             }
238             tmp = g_slist_next(tmp);
239         }
240     }
241    
242     now = time(NULL);
243     //fprintf(stderr, "Now  %d\n", now);
244     tmp = desktop_plugin->priv->scene->actors;
245     while (tmp != NULL){
246         actor = tmp->data;
247         if (now >= actor->time_start_animation  
248             && actor->time_start_animation > 0
249             && desktop_plugin->priv->short_timer == 0){
250             /* fprintf(stderr, "start short timer act = %s %d\n", actor->name, now); */
251             if (desktop_plugin->priv->rich_animation){
252                 actor->time_start_animation = now;
253                 desktop_plugin->priv->short_timer = g_timeout_add(SHORT_TIMER, (GtkFunction)short_timeout, desktop_plugin);
254             }
255             else {
256                 (*actor->func_change)(actor, desktop_plugin);
257             }
258         }
259         tmp = g_slist_next(tmp);
260     }
261  
262 }
263 /*******************************************************************************/
264 gboolean
265 long_timeout (AWallpaperPlugin *desktop_plugin)
266 {
267     GstFormat fmt = GST_FORMAT_TIME;
268     gint64 p;
269
270     /*fprintf(stderr, "long_timeout %i\n", desktop_plugin->priv->long_timer); */
271     if (desktop_plugin->priv->pipeline){
272         if (!desktop_plugin->priv->visible && !desktop_plugin->priv->theme_bool_parametr1){
273                 gst_element_query_position(desktop_plugin->priv->pipeline, &fmt, &p);
274                 desktop_plugin->priv->theme_int_parametr1 = p / GST_SECOND;
275                 gst_element_set_state (desktop_plugin->priv->pipeline, GST_STATE_NULL);
276                 gst_object_unref (GST_OBJECT (desktop_plugin->priv->pipeline));
277                 desktop_plugin->priv->pipeline = NULL;
278         }
279         return TRUE;  
280     }
281
282     if (desktop_plugin->priv->long_timer == 0 )
283         return FALSE;
284     if (!desktop_plugin->priv->visible){
285         if(desktop_plugin->priv->short_timer != 0){
286             g_source_remove(desktop_plugin->priv->short_timer);
287             desktop_plugin->priv->short_timer = 0;
288         }
289         desktop_plugin->priv->long_timer = 0;
290         return FALSE;
291     }
292
293     run_long_timeout(desktop_plugin);
294     return TRUE; /* keep running this event */
295 }
296 /*******************************************************************************/
297 void
298 create_xwindow (Animation_WallpaperPrivate *priv){
299     GtkWidget *main_widget = NULL;
300     GtkWidget *label = NULL;
301
302     /* Create Main GUI */
303     main_widget = hildon_window_new ();
304     priv->window = main_widget;
305     gtk_window_set_title(GTK_WINDOW(main_widget), PACKAGE);
306     gtk_window_fullscreen(GTK_WINDOW(main_widget));
307
308     /* Check parametr 'gtk_socket_id'. It use in flash player for example */
309     if (g_hash_table_lookup(priv->hash_theme, "gtk_socket_id")){
310         priv->video_socket = gtk_socket_new ();
311         gtk_container_add (GTK_CONTAINER (priv->window), priv->video_socket);
312     }else{
313         label = gtk_label_new(_("Loading Livewallpaper scene ..."));
314         gtk_container_add (GTK_CONTAINER (main_widget), label);
315     }
316
317     gtk_widget_show_all(GTK_WIDGET(main_widget));
318
319     /* Set window to background mode */
320     if (priv->one_in_all_view)
321         set_live_bg(GDK_WINDOW_XDISPLAY (main_widget->window), GDK_WINDOW_XID (main_widget->window), -1);
322     else
323         set_live_bg(GDK_WINDOW_XDISPLAY (main_widget->window), GDK_WINDOW_XID (main_widget->window), priv->view);
324 }
325 /*******************************************************************************/
326 int
327 main(int argc, char *argv[])
328 {
329     HildonProgram       *app;
330     int view = 1;
331
332      
333     if (argc == 2) 
334         view = atoi(argv[1]);
335     if (view < 1 || view > 4)
336         view = 1;
337
338     AWallpaperPlugin *desktop_plugin = g_new0 (AWallpaperPlugin, 1);
339     Animation_WallpaperPrivate *priv = g_new0 (Animation_WallpaperPrivate, 1);
340     desktop_plugin->priv = priv; 
341
342
343     /* Ininitializing */
344     hildon_gtk_init (&argc, &argv);
345     app = HILDON_PROGRAM (hildon_program_get_instance());
346     g_set_application_name (PACKAGE);
347  
348     priv->osso = osso_initialize("org.maemo.livewp", VERSION, TRUE, NULL);
349     if(!priv->osso){
350         fprintf(stderr,"osso_initialize failed\n");
351         return 1;
352     }
353
354 #ifdef ENABLE_NLS
355     setlocale(LC_ALL, "");
356     bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
357     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
358     textdomain(GETTEXT_PACKAGE);
359 #endif
360
361     priv->scene = NULL;
362     priv->pipeline = NULL;
363     priv->podpid = -1;
364     priv->running = FALSE;
365     /* fprintf(stderr,"XWINDOW %i\n",GDK_WINDOW_XID (main_widget->window)); */
366     priv->desktop_plugin = desktop_plugin;
367
368
369     priv->view = view;
370     fill_priv(priv);
371     fprintf(stderr,"THEME %s\n", priv->theme);
372
373     /* Check activity of opition "One theme in all views" */
374     if (priv->one_in_all_view && view >1)
375         return -1;   
376
377
378     if (current_active_view() == view && !priv->one_in_all_view) 
379         priv->visible = TRUE;
380     else 
381         priv->visible = FALSE;
382
383
384     create_xwindow(priv);
385     /* Initialize DBUS */
386     livewp_initialize_dbus(priv);
387         
388     priv->view_notify = 0; 
389     /* fprintf(stderr,"VISIBLE %i %i\n",priv->visible, current_active_view()); */
390     gconf_client_add_dir(gconf_client_get_default (), "/apps/osso/hildon-desktop/views", GCONF_CLIENT_PRELOAD_NONE, NULL);
391     priv->view_notify = gconf_client_notify_add(gconf_client_get_default (),"/apps/osso/hildon-desktop/views/current",
392                                                 (GConfClientNotifyFunc)view_changed, priv, NULL, NULL);
393
394     /* Set start position of Video to zero */
395     if (!strcmp(priv->theme,"Video")){
396         gst_init (NULL, NULL);
397         priv->theme_int_parametr1 = 0;
398     }
399
400     init_scene_theme(desktop_plugin);
401         
402     priv->long_timer = g_timeout_add(LONG_TIMER, (GtkFunction)long_timeout, desktop_plugin);
403
404     priv->alive_timer = g_timeout_add(60000*10, (GtkFunction)check_alive_event, priv);  /* One per 10 minute */ 
405     gtk_main();
406     return 0;
407 }