From a6b04cf30d423b987e232a6bda555b63a8da3ae6 Mon Sep 17 00:00:00 2001 From: Michael Cronenworth Date: Tue, 15 Dec 2009 21:17:31 -0600 Subject: [PATCH] *Hildon-ize the app for better widget support. *Add orientation support (Portrait Mode) and restructure the UI to better handle it when in portrait. --- configure.ac | 8 ++ debian/changelog | 7 ++ debian/control | 8 +- src/Makefile.am | 6 +- src/stopish.c | 221 ++++++++++++++++++++++++++++++++++++++++++------------ src/timer.c | 6 +- 6 files changed, 202 insertions(+), 54 deletions(-) diff --git a/configure.ac b/configure.ac index 7192714..3f2b8fa 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,14 @@ PKG_CHECK_MODULES(DESKTOP, libhildondesktop-1) AC_SUBST(DESKTOP_LIBS) AC_SUBST(DESKTOP_CFLAGS) +PKG_CHECK_MODULES(DBUS, dbus-1) +AC_SUBST(DBUS_LIBS) +AC_SUBST(DBUS_CFLAGS) + +PKG_CHECK_MODULES(MCE, mce) +AC_SUBST(MCE_LIBS) +AC_SUBST(MCE_CFLAGS) + # Application icon install directories icon_16x16dir=$datadir/icons/hicolor/16x16/hildon icon_26x26dir=$datadir/icons/hicolor/26x26/hildon diff --git a/debian/changelog b/debian/changelog index 0724494..409350c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stopish (0.9.1-1) unstable; urgency=low + + * Hildon-ize me. + * Add orientation support. A.K.A. Portrait Mode + + -- Michael Cronenworth Tue, 15 Dec 2009 21:03:15 -0600 + stopish (0.9.0-3) unstable; urgency=low * Remove debug package. diff --git a/debian/control b/debian/control index 0ad101a..9fff40c 100644 --- a/debian/control +++ b/debian/control @@ -7,11 +7,13 @@ Build-Depends: debhelper (>= 4.0.0), libgtk2.0-dev, libosso-dev (>= 1), Standards-Version: 3.7.3 Package: stopish -Section: user/office +Section: user/utilities Architecture: any Depends: ${shlibs:Depends}, hildon-desktop, libgtk2.0-bin -Description: A stopwatch when you need to keep track of the length of - an important event. +Description: A basic stopwatch with portrait mode support. + Stopish is the beginning of what will become an advanced stopwatch and + countdown timer. With portrait support, you can use this app no matter + how you hold your device. Xsbc-Bugtracker: https://garage.maemo.org/tracker/?atid=4340&group_id=1158 Maemo-Icon-26: iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c diff --git a/src/Makefile.am b/src/Makefile.am index a6989ef..4d70453 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,5 +10,7 @@ bin_PROGRAMS = stopish stopish_SOURCES = stopish.c stopish.h timer.c -stopish_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) -stopish_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(DESKTOP_LIBS) +stopish_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) $(DESKTOP_CFLAGS) \ + $(DBUS_CFLAGS) $(MCE_CFLAGS) +stopish_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(DESKTOP_LIBS) $(DBUS_LIBS) \ + $(MCE_LIBS) diff --git a/src/stopish.c b/src/stopish.c index 9b8b494..e44879d 100644 --- a/src/stopish.c +++ b/src/stopish.c @@ -22,9 +22,25 @@ #include #include #include +#include +#include +#include +#include +#define MCE_SIGNAL_MATCH "type='signal'," \ + "interface='" MCE_SIGNAL_IF "'," \ + "member='" MCE_DEVICE_ORIENTATION_SIG "'" #include "stopish.h" +// Application data struct +typedef struct _AppData AppData; +struct _AppData { + GtkWindow *main_window; + osso_context_t *osso_context; + DBusConnection *system_bus; +}; + +static AppData appdata; static GtkWidget *timerLabel = NULL; static GtkWidget *timerHistoryLabel1 = NULL; static GtkWidget *timerHistoryLabel2 = NULL; @@ -41,27 +57,50 @@ static GtkWindow *stopish_new( void ); static void start_cb( GtkButton* button, gpointer data ); static void reset_cb( GtkButton* button, gpointer data ); static void close_cb( GtkButton* button, gpointer data ); +static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ); +static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ); +static void accelerometer_enable( void ); +static void accelerometer_disable( void ); +static DBusHandlerResult mce_filter_func( DBusConnection * connection, + DBusMessage * message, + void *data ); int main( int argc, char *argv[] ) { - osso_context_t *ctxt; osso_return_t ret; - GtkWindow *window; - - //printf( "stopish: starting up\n" ); + HildonProgram *program; - ctxt = osso_initialize( "com.nokia.stopish", PACKAGE_VERSION, TRUE, NULL ); - if ( ctxt == NULL ) { + appdata.osso_context = osso_initialize( "com.nokia.stopish", + PACKAGE_VERSION, TRUE, NULL ); + if ( appdata.osso_context == NULL ) { fprintf( stderr, "osso_initialize failed.\n" ); exit( 1 ); } - gtk_init( &argc, &argv ); - - window = stopish_new( ); + // initialize Hildonized GTK libraries + hildon_gtk_init( &argc, &argv ); + program = hildon_program_get_instance( ); + + // create main window + appdata.main_window = stopish_new( ); + hildon_program_add_window( program, HILDON_WINDOW( appdata.main_window ) ); + + // Connect to session bus, add a match rule, install filter callback + appdata.system_bus = osso_get_sys_dbus_connection( appdata.osso_context ); + if ( appdata.system_bus ) { + dbus_bus_add_match( appdata.system_bus, MCE_SIGNAL_MATCH, NULL ); + dbus_connection_add_filter( appdata.system_bus, + mce_filter_func, + NULL, NULL ); + } + else + g_printerr( "ERROR: Cannot connect to system dbus.\n" ); - ret = osso_rpc_set_default_cb_f( ctxt, dbus_callback, window ); + ret = osso_rpc_set_default_cb_f( appdata.osso_context, + dbus_callback, appdata.main_window ); if ( ret != OSSO_OK ) { fprintf( stderr, "osso_rpc_set_default_cb_f failed: %d.\n", ret ); exit( 1 ); @@ -95,74 +134,86 @@ int stopish_get_mode( void ) static GtkWindow *stopish_new( void ) { - GtkWidget *window, *hBox, *label, *button, *button0; - GtkWidget *vBox, *vBox0, *vBox1; + GtkWidget *window, *button, *button0, *label; + GtkWidget *vBoxMain, *vBox0, *hBox0; - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + window = hildon_stackable_window_new( ); gtk_container_set_border_width( GTK_CONTAINER( window ), 20 ); gtk_window_set_title( GTK_WINDOW( window ), "Stopish" ); + // attach signals to main window g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( close_cb ), window ); + g_signal_connect( G_OBJECT( window ), "focus-in-event", + G_CALLBACK( focus_in_cb ), NULL ); + g_signal_connect( G_OBJECT( window ), "focus-out-event", + G_CALLBACK( focus_out_cb ), NULL ); - vBox = gtk_vbox_new( FALSE, 20 ); - - label = gtk_label_new( "Stopish - The Stopwatch" ); - gtk_box_pack_start( GTK_BOX( vBox ), label, FALSE, FALSE, 0 ); + vBoxMain = gtk_vbox_new( FALSE, 10 ); - hBox = gtk_hbox_new( FALSE, 10 ); + // separator + label = gtk_label_new( NULL ); + gtk_container_add( GTK_CONTAINER( vBoxMain ), label ); // stop watch area vBox0 = gtk_vbox_new( FALSE, 5 ); - gtk_widget_set_size_request( vBox0, 250, -1 ); // main timer timerLabel = gtk_label_new( NULL ); - gtk_widget_set_size_request( timerLabel, -1, 150 ); gtk_label_set_markup( GTK_LABEL( timerLabel ), - "00:00:00.0" ); - gtk_box_pack_start( GTK_BOX( vBox0 ), timerLabel, FALSE, FALSE, 0 ); + "" + "00:00:00.0" ); + gtk_container_add( GTK_CONTAINER( vBox0 ), timerLabel ); // history area timerHistoryLabel1 = gtk_label_new( NULL ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ), + " " ); gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel1, FALSE, FALSE, 0 ); timerHistoryLabel2 = gtk_label_new( NULL ); gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel2, FALSE, FALSE, 0 ); timerHistoryLabel3 = gtk_label_new( NULL ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ), + " " ); gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 ); timerHistoryLabel4 = gtk_label_new( NULL ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ), + " " ); gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel4, FALSE, FALSE, 0 ); - label = gtk_label_new( NULL ); - gtk_container_add( GTK_CONTAINER( vBox0 ), label ); - gtk_container_add( GTK_CONTAINER( hBox ), vBox0 ); + gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 ); + + // separator + label = gtk_label_new( NULL ); + gtk_container_add( GTK_CONTAINER( vBoxMain ), label ); // button area - vBox1 = gtk_vbox_new( FALSE, 15 ); - gtk_widget_set_size_request( vBox1, 200, -1 ); + hBox0 = gtk_hbox_new( FALSE, 15 ); + gtk_widget_set_size_request( hBox0, -1, 80 ); // start/pause stopwatch button - button = gtk_button_new_with_label( "Start" ); - button0 = gtk_button_new_with_label( "Reset" ); - gtk_widget_set_size_request( button, -1, 60 ); + button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, + "Start", NULL ); + button0 = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, + "Reset", NULL ); g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( start_cb ), button0 ); - gtk_box_pack_start( GTK_BOX( vBox1 ), button, FALSE, FALSE, 0 ); + gtk_container_add( GTK_CONTAINER( hBox0 ), button ); // reset button gtk_widget_set_sensitive( button0, FALSE ); - gtk_widget_set_size_request( button0, -1, 60 ); g_signal_connect( G_OBJECT( button0 ), "clicked", G_CALLBACK( reset_cb ), button ); - gtk_box_pack_start( GTK_BOX( vBox1 ), button0, FALSE, FALSE, 0 ); + gtk_container_add( GTK_CONTAINER( hBox0 ), button0 ); - gtk_container_add( GTK_CONTAINER( hBox ), vBox1 ); + gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 ); - gtk_container_add( GTK_CONTAINER( vBox ), hBox ); - - gtk_container_add( GTK_CONTAINER( window ), vBox ); + gtk_container_add( GTK_CONTAINER( window ), vBoxMain ); gtk_widget_show_all( window ); @@ -203,7 +254,7 @@ static void reset_cb( GtkButton* button, gpointer data ) { GSList *tempList; char *tempString; - char formatString[64]; + char formatString[128]; if ( stopishMode == STOPISH_MODE_RESUME ) stopish_timer_resume( ); @@ -212,32 +263,34 @@ static void reset_cb( GtkButton* button, gpointer data ) gtk_button_set_label( GTK_BUTTON( data ), "Start" ); stopishMode = STOPISH_MODE_START; gtk_label_set_markup( GTK_LABEL( timerLabel ), - "00:00:00.0" ); + "" + "00:00:00.0" ); g_source_remove( timerHandle ); // add current time to history historyList = g_slist_prepend( historyList, ( gpointer ) stopish_get_time_string( ) ); - gtk_label_set_text( GTK_LABEL( timerHistoryLabel1 ), - ( char * ) historyList->data ); + sprintf( formatString, "%s", + ( char * ) historyList->data ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ), + formatString ); tempList = historyList; tempList = g_slist_next( tempList ); if ( tempList ) { - sprintf( formatString, "%s", - ( char * ) tempList->data ); - gtk_label_set_markup( GTK_LABEL( timerHistoryLabel2 ), - formatString ); + gtk_label_set_text( GTK_LABEL( timerHistoryLabel2 ), + ( char * ) tempList->data ); } tempList = g_slist_next( tempList ); if ( tempList ) { - sprintf( formatString, "%s", + sprintf( formatString, "%s", ( char * ) tempList->data ); gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ), formatString ); } tempList = g_slist_next( tempList ); if ( tempList ) { - sprintf( formatString, "%s", + sprintf( formatString, "%s", ( char * ) tempList->data ); gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ), formatString ); @@ -261,7 +314,81 @@ static void reset_cb( GtkButton* button, gpointer data ) static void close_cb( GtkButton* button, gpointer data ) { + // disable accelerometer for battery savings + accelerometer_disable( ); + // destroy main window and exit gtk main loop gtk_widget_destroy( GTK_WIDGET( data ) ); gtk_main_quit( ); } + + +static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ) +{ + // enable accelerometer hardware for portrait mode support + accelerometer_enable( ); + + return FALSE; +} + + +static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ) +{ + // disable accelerometer for battery savings + accelerometer_disable( ); + + return FALSE; +} + + +static void accelerometer_enable( void ) +{ + if ( osso_rpc_run_system( appdata.osso_context, MCE_SERVICE, + MCE_REQUEST_PATH, MCE_REQUEST_IF, + "req_accelerometer_enable", NULL, + DBUS_TYPE_INVALID ) != OSSO_OK ) { + g_printerr("WARN: Cannot enable accelerometers\n"); + } +} + + +static void accelerometer_disable( void ) +{ + if ( osso_rpc_run_system( appdata.osso_context, MCE_SERVICE, + MCE_REQUEST_PATH, MCE_REQUEST_IF, + "req_accelerometer_disable", NULL, + DBUS_TYPE_INVALID ) != OSSO_OK ) { + g_printerr("WARN: Cannot disable accelerometers\n"); + } +} + + +static DBusHandlerResult mce_filter_func( DBusConnection * connection, + DBusMessage * message, + void *data ) +{ + DBusMessageIter iter; + char *rotation = NULL; + + if ( dbus_message_is_signal( message, MCE_SIGNAL_IF, + MCE_DEVICE_ORIENTATION_SIG ) ) { + // here if we received an orientation dbus signal + if ( dbus_message_iter_init( message, &iter ) ) { + dbus_message_iter_get_basic( &iter, &rotation ); + + // Rotate main window + if ( !strcmp( rotation, MCE_ORIENTATION_PORTRAIT ) ) + hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ), + HILDON_PORTRAIT_MODE_REQUEST ); + else + hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ), + ~HILDON_PORTRAIT_MODE_REQUEST ); + } + else + g_printerr( "ERROR: dbus_message_iter_init() failed.\n" ); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} diff --git a/src/timer.c b/src/timer.c index ca1c41d..41f9f3a 100644 --- a/src/timer.c +++ b/src/timer.c @@ -35,7 +35,7 @@ static long int timerSave = 0; gint stopish_timeout_cb( gpointer data ) { GtkLabel *timerLabel; - char formatBuffer[64]; + char formatBuffer[128]; char *tempString; if ( !data ) @@ -45,7 +45,9 @@ gint stopish_timeout_cb( gpointer data ) // print to screen tempString = stopish_get_time_string( ); - sprintf( formatBuffer, "%s", tempString ); + sprintf( formatBuffer, "" + "%s", tempString ); free( tempString ); gtk_label_set_markup( GTK_LABEL( timerLabel ), formatBuffer ); -- 1.7.9.5