Update copyright notices.
[stopish] / src / stopish.c
1 //      stopish.c
2 //
3 //      Copyright 2010 Michael Cronenworth <mike@cchtml.com>
4 //
5 //      This program is free software; you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation; either version 2 of the License, or
8 //      (at your option) any later version.
9 //
10 //      This program is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with this program; if not, write to the Free Software
17 //      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 //      MA 02110-1301, USA.
19
20 #include <string.h>
21 #include <stdlib.h>
22 #include <sys/time.h>
23 #include <gtk/gtk.h>
24 #include <libosso.h>
25 #include <hildon/hildon.h>
26 #include <dbus/dbus.h>
27 #include <mce/mode-names.h>
28 #include <mce/dbus-names.h>
29 #define MCE_SIGNAL_MATCH "type='signal'," \
30         "interface='" MCE_SIGNAL_IF   "'," \
31         "member='" MCE_DEVICE_ORIENTATION_SIG "'"
32
33 #include "stopish.h"
34
35 // Application data struct
36 typedef struct _AppData AppData;
37 struct _AppData {
38     GtkWindow *main_window;
39     osso_context_t *osso_context;
40     DBusConnection *system_bus;
41 };
42
43 typedef struct timerData {
44     GtkWidget *vBox;
45     GtkWidget *label;
46     GtkWidget *labelHour;
47     GtkWidget *labelMinute;
48     GtkWidget *labelSecond;
49 };
50
51 static AppData appdata;
52 static struct timerData timerdata;
53 static GtkWidget *timerHistoryLabel1 = NULL;
54 static GtkWidget *timerHistoryLabel2 = NULL;
55 static GtkWidget *timerHistoryLabel3 = NULL;
56 static GtkWidget *timerHistoryLabel4 = NULL;
57 static GSList *historyList = NULL;
58 static int stopishMode = STOPISH_MODE_START;
59 static int stopishOrientation = STOPISH_LANDSCAPE;
60 static int timerHandle = -1;
61
62
63 //Prototypes
64 gint dbus_callback( const gchar *interface, const gchar *method,
65                         GArray *arguments, gpointer data, osso_rpc_t *retval );
66 static GtkWindow *stopish_new( void );
67 static void main_menu( GtkWindow *window );
68 static void label_timer_landscape( void );
69 static void label_timer_portrait( void );
70 static gint timeout_cb( gpointer data );
71 static void start_cb( GtkButton* button, gpointer data );
72 static void reset_cb( GtkButton* button, gpointer data );
73 static void close_cb( GtkButton* button, gpointer data );
74 static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event,
75                              gpointer data );
76 static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event,
77                               gpointer data );
78 static void preference_timer_hour( GtkRadioButton* radio, GtkLabel *label );
79 static void preference_timer_minute( GtkRadioButton* radio, GtkLabel *label );
80 static void accelerometer_enable( void );
81 static void accelerometer_disable( void );
82 static DBusHandlerResult mce_filter_func( DBusConnection * connection,
83                                           DBusMessage * message,
84                                           void *data );
85
86
87 int main( int argc, char *argv[] )
88 {
89     osso_return_t ret;
90     HildonProgram *program;
91
92     appdata.osso_context = osso_initialize( "com.nokia.stopish",
93                                             PACKAGE_VERSION, TRUE, NULL );
94     if ( appdata.osso_context == NULL ) {
95         fprintf( stderr, "osso_initialize failed.\n" );
96         exit( 1 );
97     }
98
99     // initialize Hildonized GTK libraries
100     hildon_gtk_init( &argc, &argv );
101     program = hildon_program_get_instance(  );
102
103     // create main window
104     appdata.main_window = stopish_new(  );
105     hildon_program_add_window( program, HILDON_WINDOW( appdata.main_window ) );
106
107     // Connect to session bus, add a match rule, install filter callback
108     appdata.system_bus = osso_get_sys_dbus_connection( appdata.osso_context );
109     if ( appdata.system_bus ) {
110         dbus_bus_add_match( appdata.system_bus, MCE_SIGNAL_MATCH, NULL );
111         dbus_connection_add_filter( appdata.system_bus,
112                                     mce_filter_func,
113                                     NULL, NULL );
114     }
115     else
116         g_printerr( "ERROR: Cannot connect to system dbus.\n" );
117
118     ret = osso_rpc_set_default_cb_f( appdata.osso_context,
119                                      dbus_callback, appdata.main_window );
120     if ( ret != OSSO_OK ) {
121         fprintf( stderr, "osso_rpc_set_default_cb_f failed: %d.\n", ret );
122         exit( 1 );
123     }
124
125     gtk_main(  );
126
127     return 0;
128 }
129
130
131 gint dbus_callback( const gchar *interface, const gchar *method,
132                     GArray *arguments, gpointer data, osso_rpc_t *retval )
133 {
134     //printf( "stopish dbus: %s, %s\n", interface, method );
135
136     if ( !strcmp( method, "top_application" ) )
137         gtk_window_present( GTK_WINDOW( data ) );
138
139     retval->type = DBUS_TYPE_INVALID;
140
141     return OSSO_OK;
142 }
143
144
145 int stopish_get_mode( void )
146 {
147     return stopishMode;
148 }
149
150
151 static GtkWindow *stopish_new( void )
152 {
153     GtkWidget *window, *button, *button0, *label;
154     GtkWidget *vBoxMain, *vBox0, *hBox0;
155
156     window = hildon_stackable_window_new(  );
157
158     gtk_container_set_border_width( GTK_CONTAINER( window ), 20 );
159
160     gtk_window_set_title( GTK_WINDOW( window ), "Stopish" );
161
162     // attach signals to main window
163     g_signal_connect( G_OBJECT( window ), "destroy",
164                       G_CALLBACK( close_cb ), window );
165     g_signal_connect( G_OBJECT( window ), "focus-in-event",
166                       G_CALLBACK( focus_in_cb ), NULL );
167     g_signal_connect( G_OBJECT( window ), "focus-out-event",
168                       G_CALLBACK( focus_out_cb ), NULL );
169
170     // setup main menu
171     main_menu( window );
172
173     vBoxMain = gtk_vbox_new( FALSE, 10 );
174
175     // separator
176     label = gtk_label_new( NULL );
177     gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
178
179     vBox0 = gtk_vbox_new( FALSE, 5 );
180
181     // stop watch area
182     timerdata.vBox = gtk_vbox_new( FALSE, 0 );
183     gtk_container_add( GTK_CONTAINER( vBox0 ), timerdata.vBox );
184     label_timer_landscape(  );
185
186     // history area
187     timerHistoryLabel1 = gtk_label_new( NULL );
188     gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ),
189                           "<span size=\"large\"> </span>" );
190     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel1, FALSE, FALSE, 0 );
191     timerHistoryLabel2 = gtk_label_new( NULL );
192     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel2, FALSE, FALSE, 0 );
193     timerHistoryLabel3 = gtk_label_new( NULL );
194     gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ),
195                           "<span size=\"small\"> </span>" );
196     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 );
197     timerHistoryLabel4 = gtk_label_new( NULL );
198     gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ),
199                           "<span size=\"x-small\"> </span>" );
200     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel4, FALSE, FALSE, 0 );
201
202     gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 );
203
204     // separator
205     label = gtk_label_new( NULL );
206     gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
207
208     // button area
209     hBox0 = gtk_hbox_new( FALSE, 15 );
210     gtk_widget_set_size_request( hBox0, -1, 80 );
211
212     // start/pause stopwatch button
213     button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
214                                           HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
215                                           "Start", NULL );
216     button0 = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
217                                            HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
218                                            "Reset", NULL );
219     g_signal_connect( G_OBJECT( button ), "clicked",
220                       G_CALLBACK( start_cb ), button0 );
221     gtk_container_add( GTK_CONTAINER( hBox0 ), button );
222
223     // reset button
224     gtk_widget_set_sensitive( button0, FALSE );
225     g_signal_connect( G_OBJECT( button0 ), "clicked",
226                       G_CALLBACK( reset_cb ), button );
227     gtk_container_add( GTK_CONTAINER( hBox0 ), button0 );
228
229     gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 );
230
231     gtk_container_add( GTK_CONTAINER( window ), vBoxMain );
232
233     gtk_widget_show_all( window );
234
235     return GTK_WINDOW( window );
236 }
237
238
239 static void main_menu( GtkWindow *window )
240 {
241     GtkWidget *menu, *radio;
242
243     menu = hildon_app_menu_new(  );
244
245     // Hour preference
246     radio = gtk_radio_button_new_with_label( NULL, "Hour" );
247     gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON( radio ), FALSE );
248     g_signal_connect_after( radio, "clicked",
249                             G_CALLBACK( preference_timer_hour ), NULL );
250     hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) );
251
252     // Minute preference
253     radio = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radio ), "Minute" );
254     gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON ( radio ), FALSE );
255     g_signal_connect_after( radio, "clicked",
256                             G_CALLBACK( preference_timer_minute ), NULL );
257     hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) );
258
259     // default to minute
260     gtk_toggle_button_set_active( radio, TRUE );
261
262     gtk_widget_show_all( menu );
263
264     hildon_window_set_app_menu( HILDON_WINDOW( window ), menu );
265 }
266
267
268 static void label_timer_landscape( void )
269 {
270     gtk_widget_set_size_request( timerdata.vBox, 800, -1 );
271
272     gtk_widget_destroy( timerdata.label );
273     timerdata.label = gtk_label_new( NULL );
274     if ( stopish_timer_get_precision(  ) == TIMER_PRECISION_MINUTE )
275         gtk_label_set_markup( GTK_LABEL( timerdata.label ),
276                               "<span font_family=\"monospace\" "
277                               "size=\"70000\" weight=\"ultrabold\">"
278                               "00:00.0</span>" );
279     else
280         gtk_label_set_markup( GTK_LABEL( timerdata.label ),
281                               "<span font_family=\"monospace\" "
282                               "size=\"70000\" weight=\"ultrabold\">"
283                               "00:00:00.0</span>" );
284     gtk_misc_set_alignment( GTK_MISC( timerdata.label ), 0.5f, 0.5f );
285     gtk_container_add( GTK_CONTAINER( timerdata.vBox ), timerdata.label );
286     gtk_widget_show( timerdata.label );
287 }
288
289
290 static void label_timer_portrait( void )
291 {
292     GtkWidget *vBox, *hBox, *label;
293
294     gtk_widget_set_size_request( timerdata.vBox, 480, -1 );
295
296     gtk_widget_destroy( timerdata.label );
297     vBox = gtk_vbox_new( FALSE, 10 );
298
299     if ( stopish_timer_get_precision(  ) == TIMER_PRECISION_HOUR ) {
300         hBox = gtk_hbox_new( FALSE, 10 );
301         label = gtk_label_new( "Hours" );
302         gtk_widget_set_size_request( label, 100, -1 );
303         gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f );
304         gtk_container_add( GTK_CONTAINER( hBox ), label );
305         timerdata.labelHour = gtk_label_new( NULL );
306         gtk_widget_set_size_request( timerdata.labelHour, 350, -1 );
307         gtk_misc_set_alignment( GTK_MISC( timerdata.labelHour ), 0.0f, 0.5f );
308         gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ),
309                               "<span font_family=\"monospace\" "
310                               "size=\"80000\" weight=\"ultrabold\">"
311                               "00</span>" );
312         gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelHour );
313         gtk_container_add( GTK_CONTAINER( vBox ), hBox );
314     }
315
316     hBox = gtk_hbox_new( FALSE, 10 );
317     label = gtk_label_new( "Minutes" );
318     gtk_widget_set_size_request( label, 100, -1 );
319     gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f );
320     gtk_container_add( GTK_CONTAINER( hBox ), label );
321     timerdata.labelMinute = gtk_label_new( NULL );
322     gtk_widget_set_size_request( timerdata.labelMinute, 350, -1 );
323     gtk_misc_set_alignment( GTK_MISC( timerdata.labelMinute ), 0.0f, 0.5f );
324     gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ),
325                           "<span font_family=\"monospace\" "
326                           "size=\"80000\" weight=\"ultrabold\">"
327                           "00</span>" );
328     gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelMinute );
329     gtk_container_add( GTK_CONTAINER( vBox ), hBox );
330
331     hBox = gtk_hbox_new( FALSE, 10 );
332     label = gtk_label_new( "Seconds" );
333     gtk_widget_set_size_request( label, 100, -1 );
334     gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f );
335     gtk_container_add( GTK_CONTAINER( hBox ), label );
336     timerdata.labelSecond = gtk_label_new( NULL );
337     gtk_widget_set_size_request( timerdata.labelSecond, 350, -1 );
338     gtk_misc_set_alignment( GTK_MISC( timerdata.labelSecond ), 0.0f, 0.5f );
339     gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ),
340                           "<span font_family=\"monospace\" "
341                           "size=\"80000\" weight=\"ultrabold\">"
342                           "00.0</span>" );
343     gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelSecond );
344     gtk_container_add( GTK_CONTAINER( vBox ), hBox );
345
346     timerdata.label = vBox;
347     gtk_container_add( GTK_CONTAINER( timerdata.vBox ), vBox );
348     gtk_widget_show_all( vBox );
349 }
350
351
352 //
353 // Timer callback
354 //
355 static gint timeout_cb( gpointer data )
356 {
357     char formatBuffer[128], tempBuffer[8];
358     char *tempString;
359
360     // print to screen
361     tempString = stopish_get_time_string(  );
362     if ( stopishOrientation == STOPISH_LANDSCAPE ) {
363         sprintf( formatBuffer, "<span font_family=\"monospace\" "
364                                "size=\"70000\" weight=\"ultrabold\">"
365                                "%s</span>", tempString );
366         gtk_label_set_markup( GTK_LABEL( timerdata.label ), formatBuffer );
367     }
368     else {
369         if ( stopish_timer_get_precision(  ) == TIMER_PRECISION_HOUR ) {
370             sprintf( tempBuffer, "%.2s", tempString );
371             sprintf( formatBuffer, "<span font_family=\"monospace\" "
372                                    "size=\"80000\" weight=\"ultrabold\">"
373                                    "%s</span>", tempBuffer );
374             gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ),
375                                   formatBuffer );
376         }
377         if ( stopish_timer_get_precision(  ) == TIMER_PRECISION_HOUR )
378             sprintf( tempBuffer, "%.2s", tempString + 3 );
379         else
380             sprintf( tempBuffer, "%.2s", tempString );
381         sprintf( formatBuffer, "<span font_family=\"monospace\" "
382                                "size=\"80000\" weight=\"ultrabold\">"
383                                "%s</span>", tempBuffer );
384         gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ),
385                               formatBuffer );
386         if ( stopish_timer_get_precision(  ) == TIMER_PRECISION_HOUR )
387             sprintf( tempBuffer, "%.4s", tempString + 6 );
388         else
389             sprintf( tempBuffer, "%.4s", tempString + 3 );
390         sprintf( formatBuffer, "<span font_family=\"monospace\" "
391                                "size=\"80000\" weight=\"ultrabold\">"
392                                "%s</span>", tempBuffer );
393         gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ),
394                               formatBuffer );
395     }
396     free( tempString );
397
398     return TRUE;
399 }
400
401
402 static void start_cb( GtkButton* button, gpointer data )
403 {
404     if ( stopishMode == STOPISH_MODE_START ) {
405         // set label text and add timer handle
406         gtk_button_set_label( button, "Pause" );
407         stopishMode = STOPISH_MODE_PAUSE;
408         stopish_set_time_start( stopish_current_time(  ) );
409         timerHandle = g_timeout_add( 100, timeout_cb, NULL );
410     }
411     else if ( stopishMode == STOPISH_MODE_RESUME ) {
412         // resume timer
413         gtk_button_set_label( button, "Pause" );
414         stopishMode = STOPISH_MODE_PAUSE;
415         stopish_timer_resume(  );
416         timerHandle = g_timeout_add( 100, timeout_cb, NULL );
417     }
418     else {
419         // pause timer, remove timeout
420         gtk_button_set_label( button, "Resume" );
421         stopishMode = STOPISH_MODE_RESUME;
422         g_source_remove( timerHandle );
423         stopish_timer_save(  );
424     }
425
426     // allow user to reset timer
427     gtk_widget_set_sensitive( GTK_WIDGET( data ), TRUE );
428 }
429
430
431 static void reset_cb( GtkButton* button, gpointer data )
432 {
433     GSList *tempList;
434     char *tempString;
435     char formatString[128];
436
437     if ( stopishMode == STOPISH_MODE_RESUME )
438         stopish_timer_resume(  );
439
440     // set label text and remove timer handle
441     gtk_button_set_label( GTK_BUTTON( data ), "Start" );
442     stopishMode = STOPISH_MODE_START;
443     if ( stopish_timer_get_precision(  ) == TIMER_PRECISION_MINUTE )
444         gtk_label_set_markup( GTK_LABEL( timerdata.label ),
445                               "<span font_family=\"monospace\" "
446                               "size=\"70000\" weight=\"ultrabold\">"
447                               "00:00.0</span>" );
448     else
449         gtk_label_set_markup( GTK_LABEL( timerdata.label ),
450                               "<span font_family=\"monospace\" "
451                               "size=\"70000\" weight=\"ultrabold\">"
452                               "00:00:00.0</span>" );
453     g_source_remove( timerHandle );
454
455     // add current time to history
456     historyList = g_slist_prepend( historyList,
457                                    ( gpointer ) stopish_get_time_string(  ) );
458     sprintf( formatString, "<span size=\"large\">%s</span>",
459              ( char * ) historyList->data );
460     gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ),
461                           formatString );
462     tempList = historyList;
463     tempList = g_slist_next( tempList );
464     if ( tempList ) {
465         gtk_label_set_text( GTK_LABEL( timerHistoryLabel2 ),
466                             ( char * ) tempList->data );
467     }
468     tempList = g_slist_next( tempList );
469     if ( tempList ) {
470         sprintf( formatString, "<span size=\"small\">%s</span>",
471                  ( char * ) tempList->data );
472         gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ),
473                               formatString );
474     }
475     tempList = g_slist_next( tempList );
476     if ( tempList ) {
477         sprintf( formatString, "<span size=\"x-small\">%s</span>",
478                  ( char * ) tempList->data );
479         gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ),
480                               formatString );
481     }
482
483     // remove the history time after the 4th
484     tempList = g_slist_next( tempList );
485     if ( tempList ) {
486         tempString = tempList->data;
487         historyList = g_slist_remove( historyList, tempList->data );
488         free( tempString );
489     }
490
491     // reset start time
492     stopish_set_time_start( 0 );
493
494     // disallow user to reset timer
495     gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
496 }
497
498
499 static void close_cb( GtkButton* button, gpointer data )
500 {
501     // disable accelerometer for battery savings
502     accelerometer_disable(  );
503
504     // destroy main window and exit gtk main loop
505     gtk_widget_destroy( GTK_WIDGET( data ) );
506     gtk_main_quit(  );
507 }
508
509
510 static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event,
511                              gpointer data )
512 {
513     // enable accelerometer hardware for portrait mode support
514     accelerometer_enable(  );
515
516     return FALSE;
517 }
518
519
520 static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event,
521                               gpointer data )
522 {
523     // disable accelerometer for battery savings
524     accelerometer_disable(  );
525
526     return FALSE;
527 }
528
529
530 static void preference_timer_hour( GtkRadioButton* radio, GtkLabel *label )
531 {
532     stopish_timer_set_precision( TIMER_PRECISION_HOUR );
533     if ( stopishOrientation == STOPISH_LANDSCAPE )
534         label_timer_landscape(  );
535     else
536         label_timer_portrait(  );
537 }
538
539
540 static void preference_timer_minute( GtkRadioButton* radio, GtkLabel *label )
541 {
542     stopish_timer_set_precision( TIMER_PRECISION_MINUTE );
543     if ( stopishOrientation == STOPISH_LANDSCAPE )
544         label_timer_landscape(  );
545     else
546         label_timer_portrait(  );
547 }
548
549
550 static void accelerometer_enable( void )
551 {
552     if ( osso_rpc_run_system( appdata.osso_context, MCE_SERVICE,
553                               MCE_REQUEST_PATH, MCE_REQUEST_IF,
554                               "req_accelerometer_enable", NULL,
555                               DBUS_TYPE_INVALID ) != OSSO_OK ) {
556         g_printerr("WARN: Cannot enable accelerometers\n");
557     }
558 }
559
560
561 static void accelerometer_disable( void )
562 {
563     if ( osso_rpc_run_system( appdata.osso_context, MCE_SERVICE,
564                               MCE_REQUEST_PATH, MCE_REQUEST_IF,
565                               "req_accelerometer_disable", NULL,
566                               DBUS_TYPE_INVALID ) != OSSO_OK ) {
567         g_printerr("WARN: Cannot disable accelerometers\n");
568     }
569 }
570
571
572 static DBusHandlerResult mce_filter_func( DBusConnection * connection,
573                                           DBusMessage * message,
574                                           void *data )
575 {
576     DBusMessageIter iter;
577     char *rotation = NULL;
578
579     if ( dbus_message_is_signal( message, MCE_SIGNAL_IF,
580                                  MCE_DEVICE_ORIENTATION_SIG ) ) {
581         // here if we received an orientation dbus signal
582         if ( dbus_message_iter_init( message, &iter ) ) {
583             dbus_message_iter_get_basic( &iter, &rotation );
584
585             // Rotate main window
586             if ( !strcmp( rotation, MCE_ORIENTATION_PORTRAIT ) ) {
587                 hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ),
588                                                       HILDON_PORTRAIT_MODE_REQUEST );
589                 label_timer_portrait(  );
590                 stopishOrientation = STOPISH_PORTRAIT;
591             }
592             else {
593                 hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ),
594                                                       ~HILDON_PORTRAIT_MODE_REQUEST );
595                 label_timer_landscape(  );
596                 stopishOrientation = STOPISH_LANDSCAPE;
597             }
598         }
599         else
600             g_printerr( "ERROR: dbus_message_iter_init() failed.\n" );
601     }
602
603     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
604 }