ctb/src/ipc.c

Go to the documentation of this file.
00001 /*
00002  * File Name: ipc.c
00003  */
00004 
00005 /*
00006  * This file is part of ctb.
00007  *
00008  * ctb is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * ctb is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021  
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 #include "config.h"
00032 
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 
00036 #include <liberipc/eripc.h>
00037 #include <liberipc/eripc_support.h>
00038 #include <liberutils/er_error.h>
00039 #include <libermetadb/ermetadb.h>
00040 
00041 #include "ctb_log.h"
00042 #include "ipc.h"
00043 #include "menu.h"
00044 
00045 //----------------------------------------------------------------------------
00046 // Constants
00047 //----------------------------------------------------------------------------
00048 
00049 // IPC content browser
00050 #define DBUS_APPL_NAME                  PACKAGE_NAME
00051 #define DBUS_SERVICE                     "com.irexnet." DBUS_APPL_NAME
00052 #define DBUS_PATH                       "/com/irexnet/" DBUS_APPL_NAME
00053 #define DBUS_INTERFACE                   "com.irexnet." DBUS_APPL_NAME
00054 
00055 #define DBUS_SERVICE_SYSTEM_CONTROL     "com.irexnet.sysd"
00056 #define DBUS_SERVICE_POPUP_MENU         "com.irexnet.popupmenu"
00057 #define DBUS_SERVICE_SETTINGS           "com.irexnet.settings"
00058 
00059 //----------------------------------------------------------------------------
00060 // Static Variables
00061 //----------------------------------------------------------------------------
00062 
00063 static eripc_client_context_t *eripcClient = NULL;
00064 static quit_function g_quit_callback = NULL;
00065 static locale_function g_set_locale_callback = NULL;
00066 static gboolean g_in_portrait = TRUE;
00067 
00068 static gchar *g_storage_media = NULL;
00069 static mount_cb_t g_mount_cb = NULL;
00070 static unmount_cb_t g_unmount_cb = NULL;
00071 
00072 
00073 //============================================================================
00074 // Local Function Definitions
00075 //============================================================================
00076 
00077 static void on_goto_location     ( eripc_context_t          *context,
00078                                    const eripc_event_info_t *info,
00079                                    void                     *user_data );
00080                                  
00081 static void on_page_change       ( eripc_context_t          *context,
00082                                    const eripc_event_info_t *info,
00083                                    void                     *user_data );
00084 
00085 static void on_filesystem_change ( eripc_context_t          *context,
00086                                    const eripc_event_info_t *info,
00087                                    void                     *user_data );
00088 
00089 static void on_window_activated  ( eripc_context_t          *context,
00090                                    const eripc_event_info_t *info,
00091                                    void                     *user_data );
00092 
00093 static void on_window_deactivated( eripc_context_t          *context,
00094                                    const eripc_event_info_t *info,
00095                                    void                     *user_data );
00096 
00097 static void on_menu_item         ( eripc_context_t          *context,
00098                                    const eripc_event_info_t *info,
00099                                    void                     *user_data );
00100                                  
00101 static void on_mounted           ( eripc_context_t          *context,
00102                                    const eripc_event_info_t *info,
00103                                    void                     *user_data );
00104                                  
00105 static void on_unmounted         ( eripc_context_t          *context,
00106                                    const eripc_event_info_t *info,
00107                                    void                     *user_data );
00108 
00109 static void on_prepare_standby ( eripc_context_t          *context,
00110                                    const eripc_event_info_t *info,
00111                                    void                     *user_data );
00112 
00113 static void on_changed_locale    ( eripc_context_t          *context,
00114                                    const eripc_event_info_t *info,
00115                                    void                     *user_data );
00116 
00117 static void on_changed_orientation(eripc_context_t          *context,
00118                                    const eripc_event_info_t *info,
00119                                    void                     *user_data );
00120 
00121 static gboolean is_in_portrait_orientation();
00122 
00123 // Exported DBUS API list
00124 static eripc_callback_function_t service_functions[] = {
00125 //    handler               message_name           interface,                  id
00126     { on_goto_location,     "gotoLocation",        NULL                        ,0 },
00127     { on_menu_item,         "menuItemActivated",   NULL                        ,0 },
00128     { on_mounted,           "sysVolumeMounted",    NULL                        ,0 },
00129     { on_window_activated,  "activatedWindow",     NULL                        ,0 },
00130     { on_window_deactivated,"deactivatedWindow",   NULL                        ,0 },
00131     { on_mounted,           "sysVolumeMounted",    DBUS_SERVICE_SYSTEM_CONTROL ,0 },
00132     { on_unmounted,         "sysPrepareUnmount",   DBUS_SERVICE_SYSTEM_CONTROL ,0 },
00133     { on_unmounted,         "sysVolumeUnmounted",  DBUS_SERVICE_SYSTEM_CONTROL ,0 },
00134     { on_prepare_standby,   "sysPrepareStandby",   DBUS_SERVICE_SYSTEM_CONTROL ,0 },
00135     { on_changed_locale,    "sysChangedLocale",    DBUS_SERVICE_SYSTEM_CONTROL ,0 },
00136     { on_page_change,       "pageChange"    ,      NULL                        ,0 },
00137     { on_filesystem_change, "filesystemChanged",   NULL                        ,0 },
00138     { on_changed_orientation, "sysChangedOrientation",  DBUS_SERVICE_SYSTEM_CONTROL ,0 },
00139     { NULL, NULL, NULL, 0 }  // end of list
00140 };
00141 
00142 
00143 //============================================================================
00144 // Functions Implementation
00145 //============================================================================
00146 
00147 void ipc_init (quit_function quit_cb,
00148                locale_function set_locale_cb,
00149                mount_cb_t mount_cb,
00150                unmount_cb_t unmount_cb)
00151 {
00152     g_quit_callback = quit_cb;
00153     g_set_locale_callback = set_locale_cb;
00154     g_mount_cb = mount_cb;
00155     g_unmount_cb = unmount_cb;
00156 
00157     eripcClient = eripc_client_context_new(
00158                     DBUS_APPL_NAME, 
00159                     "1.0",
00160                     DBUS_SERVICE, 
00161                     DBUS_PATH,
00162                     DBUS_INTERFACE,
00163                     service_functions);
00164     g_in_portrait = is_in_portrait_orientation();
00165 }
00166 
00167 
00168 void ipc_sys_startup_complete()
00169 {
00170     eripc_sysd_startup_complete( eripcClient, getpid(), FALSE, fileview_get_xid());
00171 }
00172 
00173 
00174 gint ipc_sys_start_task ( const gchar  *cmd_line,
00175                           const gchar  *work_dir,
00176                           const gchar  *label,
00177                           const gchar  *thumbnail_path,
00178                           gchar        **err_message )
00179 {
00180     LOGPRINTF("entry: cmd_line [%s] work_dir [%s] label [%s] thumbnail_path [%s]",
00181                        cmd_line,     work_dir,     label,     thumbnail_path       );
00182     g_assert( cmd_line && *cmd_line );
00183     return eripc_sysd_start_task( eripcClient, 
00184                                   cmd_line, 
00185                                   work_dir, 
00186                                   label, 
00187                                   thumbnail_path, 
00188                                   err_message);
00189 }
00190 
00191 
00192 gboolean ipc_sys_stop_task ( const gchar  *cmd_line )
00193 {
00194     LOGPRINTF("entry: cmd_line [%s]", cmd_line );
00195     g_assert( cmd_line && *cmd_line );
00196     return eripc_sysd_stop_task( eripcClient, cmd_line );
00197 }
00198 
00199 
00200 gint ipc_sys_open_url ( const gchar  *url,
00201                         const gchar  *label,
00202                         const gchar  *back_text,
00203                         gchar        **err_message )
00204 {
00205     LOGPRINTF("entry: url [%s] label [%s] back_text [%s]",
00206                       url,     label,     back_text     );
00207     g_assert( url && *url );
00208     return eripc_sysd_open_url( eripcClient, url, label, back_text, err_message );
00209 }
00210 
00211 
00212 const device_caps_t* ipc_sys_get_device_capabilities()
00213 {
00214     static device_caps_t dev_caps;
00215 
00216     eripc_device_caps_t er_dev_caps;
00217 
00218     eripc_sysd_get_device_capabilities( eripcClient, &er_dev_caps );
00219 
00220     dev_caps.has_stylus = er_dev_caps.has_stylus;
00221     dev_caps.has_wifi = er_dev_caps.has_wifi;
00222     dev_caps.has_bluetooth = er_dev_caps.has_bluetooth;
00223     dev_caps.has_3g = er_dev_caps.has_3g;
00224 
00225     return &dev_caps;
00226 }
00227 
00228 
00229 //----------------------------------------------------------------------------
00230 // Popup menu
00231 //----------------------------------------------------------------------------
00232 
00233 gboolean ipc_menu_add_menu( const char *name,
00234                             const char *group1,
00235                             const char *group2,
00236                             const char *group3 )
00237 {
00238     return eripc_menu_add_menu(eripcClient, name, group1, group2, group3, "");
00239 }
00240 
00241 
00242 gboolean ipc_menu_add_group( const char *name,
00243                              const char *parent, 
00244                              const char *image )
00245 {
00246     return eripc_menu_add_group(eripcClient, name, parent, image);
00247 }
00248 
00249 
00250 gboolean ipc_menu_add_item( const char *name,
00251                             const char *parent, 
00252                             const char *image  )
00253 {
00254     return eripc_menu_add_item(eripcClient, name, parent, image);
00255 }
00256 
00257 
00258 gboolean ipc_menu_set_menu_label ( const char *name,
00259                                    const char *label )
00260 {
00261     return eripc_menu_set_menu_label(eripcClient, name, label);
00262 }
00263 
00264 
00265 gboolean ipc_menu_set_group_label ( const char *name,
00266                                     const char *label )
00267 {
00268     return eripc_menu_set_group_label(eripcClient, name, label);
00269 }
00270 
00271 
00272 gboolean ipc_menu_set_item_label ( const char *name,
00273                                    const char *parent, 
00274                                    const char *label )
00275 {
00276     return eripc_menu_set_item_label(eripcClient, name, parent, label);
00277 }
00278 
00279 
00280 gboolean ipc_menu_show_menu( const char *name )
00281 {
00282     return eripc_menu_show_menu(eripcClient, name);
00283 }
00284 
00285 
00286 gboolean ipc_menu_set_group_state( const char *name,
00287                                    const char *state )
00288 {
00289     return eripc_menu_set_group_state(eripcClient, name, state);
00290 }
00291 
00292 
00293 gboolean ipc_menu_set_item_state( const char *name,
00294                                   const char *parent,
00295                                   const char *state  )
00296 {
00297     return eripc_menu_set_item_state(eripcClient, name, parent, state);
00298 }
00299 
00300 
00301 gboolean ipc_menu_block( void )
00302 {
00303     return eripc_sysd_set_menu_state(eripcClient, "block");
00304 }
00305 
00306 
00307 gboolean ipc_menu_unblock( void )
00308 {
00309     return eripc_sysd_set_menu_state(eripcClient, "unblock");
00310 }
00311 
00312 
00313 void ipc_menu_updates_finished()
00314 {
00315     eripc_send_varargs(eripcClient->context, NULL, NULL, ERIPC_BUS_SESSION, DBUS_SERVICE_POPUP_MENU, "updatesFinished", ERIPC_TYPE_INVALID);
00316 }
00317 
00318 
00319 void ipc_menu_set_pagecounter(int cur_page, int num_pages, gboolean boundary_check)
00320 {
00321     eripc_menu_set_pagecounter(eripcClient, cur_page, num_pages, boundary_check);
00322 }
00323 
00324 
00325 gboolean ipc_sys_busy( gboolean look_busy )
00326 {
00327     if (look_busy)
00328         return eripc_sysd_set_busy(eripcClient, "delaydialog", NULL);
00329     else
00330         return eripc_sysd_reset_busy(eripcClient);
00331 }
00332 
00333 gboolean ipc_status_set_stylus( const char *state )
00334 {
00335     g_return_val_if_fail( (state != NULL), FALSE);
00336     return eripc_menu_set_statusitem_state(eripcClient, "statusbar_stylus", state);
00337 }
00338 
00339 
00340 gboolean ipc_sys_is_in_portrait_mode()
00341 {
00342     return g_in_portrait;
00343 }
00344 
00345 
00346 //============================================================================
00347 // Local Function Implementation
00348 //============================================================================
00349 
00350 static gboolean is_in_portrait_orientation()
00351 {
00352     gboolean result = TRUE;
00353 
00354     eripc_event_info_t* info = NULL;
00355     eripc_error_t retval = eripc_send_varargs_and_wait(eripcClient->context,
00356             &info,
00357             ERIPC_BUS_SESSION,
00358             DBUS_SERVICE_SYSTEM_CONTROL,
00359             "sysGetOrientation",
00360             ERIPC_TYPE_INVALID);
00361 
00362     if (retval != ERIPC_ERROR_SUCCESS)
00363     {
00364         ERRORPRINTF("Error launching eripc handler");
00365     }
00366     else if (info == NULL || info->args == NULL)
00367     {
00368         ERRORPRINTF("sysd returns OK but no reply structure");
00369     }
00370     else
00371     {
00372         const eripc_arg_t *arg_array = info->args;
00373 
00374         if (arg_array[0].type == ERIPC_TYPE_STRING
00375             && strcmp("portrait", arg_array[0].value.s) == 0)
00376         {
00377             result = TRUE;
00378         }
00379         else
00380         {
00381             result = FALSE;
00382         }
00383     }
00384     eripc_event_info_free(eripcClient->context, info);
00385     return result;
00386 }
00387 
00388 
00389 //----------------------------------------------------------------------------
00390 // Signal/message handlers
00391 //----------------------------------------------------------------------------
00392 
00393 // show specified location
00394 static void on_goto_location ( eripc_context_t          *context,
00395                                const eripc_event_info_t *info,
00396                                void                     *user_data )
00397 {
00398     g_return_if_fail(info->args);
00399     g_return_if_fail(info->args[0].type == ERIPC_TYPE_STRING);
00400 
00401     const eripc_arg_t *arg_array = info->args;
00402     const char        *location  = arg_array[0].value.s;
00403 
00404     if (location==NULL || location[0] == '\0') return;
00405 
00406     menu_on_goto_location( location );
00407 }
00408 
00409 
00410 static void on_page_change ( eripc_context_t          *context,
00411                              const eripc_event_info_t *info,
00412                              void                     *user_data )
00413 {
00414     const eripc_arg_t *arg_array = info->args;
00415     g_return_if_fail(arg_array[0].type == ERIPC_TYPE_STRING);
00416     gchar* direction = arg_array[0].value.s;
00417 
00418     if (strcmp(direction, "prev") == 0) fileview_show_prev_page();
00419     if (strcmp(direction, "next") == 0) fileview_show_next_page();
00420 }
00421 
00422 
00423 static void on_filesystem_change( eripc_context_t          *context,
00424                                  const eripc_event_info_t *info,
00425                                  void                     *user_data )
00426 {
00427     fileview_refresh(FALSE);
00428 }
00429 
00430 
00431 static void on_window_activated( eripc_context_t          *context,
00432                                  const eripc_event_info_t *info,
00433                                  void                     *user_data )
00434 {
00435     fileview_set_on_top(TRUE);
00436     fileview_stop_update_display();
00437     menu_show();
00438     fileview_grab_focus();
00439     fileview_refresh(FALSE);  // needed for icons + author
00440 }
00441 
00442 
00443 static void on_window_deactivated( eripc_context_t          *context,
00444                                  const eripc_event_info_t *info,
00445                                  void                     *user_data )
00446 {
00447     fileview_set_on_top(FALSE);
00448     menu_hide();
00449 }
00450 
00451 
00452 static void on_menu_item ( eripc_context_t          *context,
00453                            const eripc_event_info_t *info,
00454                            void                     *user_data )
00455 {
00456     g_return_if_fail(info->args);
00457     g_return_if_fail(info->args[0].type == ERIPC_TYPE_STRING);
00458     g_return_if_fail(info->args[1].type == ERIPC_TYPE_STRING);
00459     g_return_if_fail(info->args[2].type == ERIPC_TYPE_STRING);
00460     g_return_if_fail(info->args[3].type == ERIPC_TYPE_STRING);
00461 
00462     const eripc_arg_t *arg_array = info->args;
00463     const char        *item      = arg_array[0].value.s;
00464     const char        *group     = arg_array[1].value.s;
00465     const char        *menu      = arg_array[2].value.s;
00466     const char        *state     = arg_array[3].value.s;
00467 
00468     if (item && group && menu && state)
00469     {
00470         menu_on_item_activated( item, group, menu, state );
00471     }
00472 }
00473 
00474 
00475 // storage device has been mounted
00476 static void on_mounted ( eripc_context_t          *context,
00477                          const eripc_event_info_t *info,
00478                          void                     *user_data )
00479 {
00480     LOGPRINTF("entry");
00481     g_return_if_fail(info->args);
00482     g_return_if_fail(info->args[0].type == ERIPC_TYPE_STRING);
00483 
00484     const eripc_arg_t *arg_array  = info->args;
00485     const char        *mountpoint = arg_array[0].value.s;
00486 
00487     if (mountpoint && *mountpoint)
00488     {
00489         storage_media_mounted(mountpoint);
00490     }
00491 }
00492 
00493 
00494 static void on_unmounted ( eripc_context_t          *context,
00495                            const eripc_event_info_t *info,
00496                            void                     *user_data )
00497 {
00498     LOGPRINTF("entry");
00499     g_return_if_fail(info->args);
00500     g_return_if_fail(info->args[0].type == ERIPC_TYPE_STRING);
00501 
00502     const eripc_arg_t *arg_array  = info->args;
00503     const char        *mountpoint = arg_array[0].value.s;
00504 
00505     if (!mountpoint || !*mountpoint) return;
00506 
00507     if (g_storage_media) {
00508         if (strcmp(mountpoint, g_storage_media) == 0) {
00509             g_free(g_storage_media);
00510             g_storage_media = NULL;
00511             g_unmount_cb();
00512         } else {
00513             ERRORPRINTF("media mismatch, mountpoint=%s  need to unmount %s", g_storage_media, mountpoint);
00514         }
00515     } else {
00516         WARNPRINTF("storage not present [%s]", mountpoint);
00517     }
00518 }
00519 
00520 
00521 // system will be in standby mode
00522 static void on_prepare_standby ( eripc_context_t          *context,
00523                                  const eripc_event_info_t *info,
00524                                  void                     *user_data )
00525 {
00526     LOGPRINTF("entry");
00527 
00528     fileview_save_view_type();
00529 }
00530 
00531 
00532 // LOCALE setting (language) has changed
00533 static void on_changed_locale ( eripc_context_t          *context,
00534                                 const eripc_event_info_t *info,
00535                                 void                     *user_data )
00536 {
00537     LOGPRINTF("entry");
00538     g_return_if_fail(info->args);
00539     g_return_if_fail(info->args[0].type == ERIPC_TYPE_STRING);
00540 
00541     const eripc_arg_t *arg_array = info->args;
00542     const char        *locale    = arg_array[0].value.s;
00543 
00544     if (locale)
00545     {
00546         g_set_locale_callback(locale);
00547     }
00548 }
00549 
00550 /* Called when the display's orientation has changed
00551 *
00552 * Application may need to adapt its screen size, coordinates and/or origin.
00553 * Possible values: "portrait", "landscape_clockwise", "landscape_anticlockwise"
00554 */
00555 static void on_changed_orientation ( eripc_context_t          *context,
00556                                      const eripc_event_info_t *info,
00557                                      void                     *user_data )
00558 {
00559     LOGPRINTF("entry");
00560     const eripc_arg_t *arg_array = info->args;
00561 
00562     if (arg_array[0].type == ERIPC_TYPE_STRING)
00563     {   
00564         const char *orientation = arg_array[0].value.s;
00565         if (orientation)
00566         {
00567             if (strcasecmp("portrait", orientation) == 0)
00568             {
00569                 g_in_portrait = TRUE;
00570                 fileview_move_undo();
00571             }
00572             else 
00573             {
00574                 g_in_portrait = FALSE;
00575                 // call orientation change code
00576                 fileview_move_up( 5 ); // moveup 5 pixels to compensate for higher popupmenu in landscape
00577             }
00578         }
00579     }
00580 }
00581 
00582 
00583 const gchar* ipc_get_media()
00584 {
00585     return g_storage_media;
00586 }
00587 
00588 
00589 void storage_media_mounted ( const gchar *mountpoint )
00590 {
00591     LOGPRINTF("entry: mountpoint [%s]", mountpoint);
00592     g_assert(mountpoint && *mountpoint);
00593 
00594     if (g_storage_media) {
00595         ERRORPRINTF("storage already present %s (new %s)", g_storage_media, mountpoint);
00596     } else {
00597         g_storage_media = g_strdup(mountpoint);
00598         g_mount_cb(mountpoint);
00599     }
00600 }
00601 
00602 
00603 
Generated by  doxygen 1.6.2-20100208