erbrowser/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 erbrowser.
00007  *
00008  * erbrowser 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  * erbrowser 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) 2009 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 #include "config.h"
00032 
00033 // system include files, between < >
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <gdk/gdkx.h>
00037 #include <unistd.h>
00038 
00039 // ereader include files, between < >
00040 #include <liberipc/eripc.h>
00041 #include <liberipc/eripc_support.h>
00042 
00043 // local include files, between " "
00044 #include "log.h"
00045 #include "i18n.h"
00046 #include "ipc.h"
00047 #include "main.h"
00048 #include "menu.h"
00049 #include "view.h"
00050 
00051 
00052 //----------------------------------------------------------------------------
00053 // Type Declarations
00054 //----------------------------------------------------------------------------
00055 
00056 //----------------------------------------------------------------------------
00057 // Constants
00058 //----------------------------------------------------------------------------
00059 
00060 // IPC application
00061 #define DBUS_APPL_NAME                  PACKAGE
00062 #define DBUS_SERVICE                     "com.irexnet." DBUS_APPL_NAME
00063 #define DBUS_PATH                       "/com/irexnet/" DBUS_APPL_NAME
00064 #define DBUS_INTERFACE                   "com.irexnet." DBUS_APPL_NAME
00065 
00066 // IPC system control
00067 #define DBUS_SERVICE_SYSTEM_CONTROL     "com.irexnet.sysd"
00068 
00069 // IPC popup menu
00070 #define DBUS_SERVICE_POPUP_MENU         "com.irexnet.popupmenu"
00071 
00072 
00073 //----------------------------------------------------------------------------
00074 // Static Variables
00075 //----------------------------------------------------------------------------
00076 
00077 static eripc_client_context_t *eripcClient = NULL;
00078 
00079 static ipc_callback_t g_connect_cb         = NULL;
00080 static ipc_callback_t g_disconnect_cb      = NULL;
00081 static ipc_callback_t g_locale_cb          = NULL;
00082 
00083 
00084 //============================================================================
00085 // Local Function Definitions
00086 //============================================================================
00087 
00088 static void on_menu_item         ( eripc_context_t          *context,
00089                                    const eripc_event_info_t *info,
00090                                    void                     *user_data );
00091 
00092 static void on_mounted           ( eripc_context_t          *context,
00093                                    const eripc_event_info_t *info,
00094                                    void                     *user_data );
00095 
00096 static void on_file_open         ( eripc_context_t          *context,
00097                                    const eripc_event_info_t *info,
00098                                    void                     *user_data );
00099                                  
00100 static void on_file_close        ( eripc_context_t          *context,
00101                                    const eripc_event_info_t *info,
00102                                    void                     *user_data );
00103                                  
00104 static void on_window_activated  ( eripc_context_t          *context,
00105                                    const eripc_event_info_t *info,
00106                                    void                     *user_data );
00107                                  
00108 static void on_window_deactivated( eripc_context_t          *context,
00109                                    const eripc_event_info_t *info,
00110                                    void                     *user_data );
00111 
00112 static void on_connection_status ( eripc_context_t          *context,
00113                                    const eripc_event_info_t *info,
00114                                    void                     *user_data );
00115                                    
00116 static void on_prepare_unmount   ( eripc_context_t          *context,
00117                                    const eripc_event_info_t *info,
00118                                    void                     *user_data );
00119                                  
00120 static void on_unmounted         ( eripc_context_t          *context,
00121                                    const eripc_event_info_t *info,
00122                                    void                     *user_data );
00123 
00124 static void on_changed_locale    ( eripc_context_t          *context,
00125                                    const eripc_event_info_t *info,
00126                                    void                     *user_data );
00127 
00128 // Exported DBUS API list
00129 static eripc_callback_function_t service_functions[] = {
00130     // message handlers (method calls to this service)
00131     { on_menu_item,           "menuItemActivated",      NULL                        , 0},
00132     { on_mounted,             "sysVolumeMounted",       NULL                        , 0},
00133     { on_file_open,           "openFile",               NULL                        , 0},
00134     { on_file_close,          "closeFile",              NULL                        , 0},
00135     { on_window_activated,    "activatedWindow",        NULL                        , 0},
00136     { on_window_deactivated,  "deactivatedWindow",      NULL                        , 0},
00137     { on_connection_status,   "connConnectionStatus",   NULL                        , 0},
00138     // signal handlers (broadcasted from given service)
00139     { on_mounted,             "sysVolumeMounted",       DBUS_SERVICE_SYSTEM_CONTROL , 0},
00140     { on_prepare_unmount,     "sysPrepareUnmount",      DBUS_SERVICE_SYSTEM_CONTROL , 0},
00141     { on_unmounted,           "sysVolumeUnmounted",     DBUS_SERVICE_SYSTEM_CONTROL , 0},
00142     { on_changed_locale,      "sysChangedLocale",       DBUS_SERVICE_SYSTEM_CONTROL , 0},
00143     { on_connection_status,   "connConnectionStatus",   DBUS_SERVICE_SYSTEM_CONTROL , 0},
00144     { NULL, NULL, NULL, 0 }
00145 };
00146 
00147 
00148 //============================================================================
00149 // Functions Implementation
00150 //============================================================================
00151 
00152 
00153 //----------------------------------------------------------------------------
00154 // Generic
00155 //----------------------------------------------------------------------------
00156 
00157 void ipc_set_services (ipc_callback_t connect_cb, ipc_callback_t disconnect_cb, ipc_callback_t locale_cb)
00158 {
00159     LOGPRINTF("entry");
00160     eripcClient = eripc_client_context_new(
00161                     DBUS_APPL_NAME, 
00162                     "1.0",
00163                     DBUS_SERVICE, 
00164                     DBUS_PATH,
00165                     DBUS_INTERFACE,
00166                     service_functions);
00167 
00168     g_connect_cb    = connect_cb;
00169     g_disconnect_cb = disconnect_cb;
00170     g_locale_cb     = locale_cb;
00171 
00172     // start without mountpoint
00173     g_mountpoint = NULL;
00174 }
00175 
00176 
00177 void ipc_unset_services (void)
00178 {
00179     LOGPRINTF("entry");
00180     eripc_client_context_free(eripcClient, service_functions);
00181 }
00182 
00183 
00184 //----------------------------------------------------------------------------
00185 // System control
00186 //----------------------------------------------------------------------------
00187 
00188 void ipc_sys_startup_complete ( void )
00189 {
00190     LOGPRINTF("entry");
00191     const int xid = GDK_WINDOW_XID(g_main_window->window);
00192     eripc_sysd_startup_complete( eripcClient, getpid(), TRUE, xid);
00193 }
00194 
00195 
00196 gboolean ipc_sys_bg_busy ( gboolean on )
00197 {
00198     LOGPRINTF("entry [%d]", on);
00199     if (on)
00200         return eripc_sysd_set_bg_busy(eripcClient);
00201     else
00202         return eripc_sysd_reset_bg_busy(eripcClient);
00203 }
00204 
00205 
00206 gboolean ipc_sys_set_busy ( gboolean on, const gchar *message )
00207 {
00208     LOGPRINTF("entry [%d]", on);
00209     if (on)
00210         return eripc_sysd_set_busy(eripcClient, "delaydialog", message);
00211     else
00212         return eripc_sysd_reset_busy(eripcClient);
00213 }
00214 
00215 
00216 gboolean ipc_sys_set_busy_nodialog ( gboolean on )
00217 {
00218     LOGPRINTF("entry [%d]", on);
00219     if (on)
00220         return eripc_sysd_set_busy(eripcClient, "nodialog", NULL);
00221     else
00222         return eripc_sysd_reset_busy(eripcClient);
00223 }
00224 
00225 
00226 gboolean ipc_sys_connect ( void )
00227 {
00228     LOGPRINTF("entry");
00229     return eripc_sysd_conn_connect(eripcClient, NULL, NULL);
00230 }
00231 
00232 
00233 gboolean ipc_sys_disconnect ( void )
00234 {
00235     LOGPRINTF("entry");
00236     return eripc_sysd_conn_disconnect(eripcClient);
00237 }
00238 
00239 
00240 gint ipc_sys_start_task ( const gchar  *cmd_line,
00241                           const gchar  *work_dir,
00242                           const gchar  *label,
00243                           const gchar  *thumbnail_path,
00244                           gchar        **err_message )
00245 {
00246     LOGPRINTF("entry");
00247     return eripc_sysd_start_task(eripcClient, 
00248                                  cmd_line, 
00249                                  work_dir, 
00250                                  label, 
00251                                  thumbnail_path, 
00252                                  err_message);
00253 }
00254 
00255 
00256 //----------------------------------------------------------------------------
00257 // Popup menu
00258 //----------------------------------------------------------------------------
00259 
00260 gboolean ipc_menu_add_menu( const char *name,
00261                             const char *group1,
00262                             const char *group2,
00263                             const char *group3 )
00264 {
00265     LOGPRINTF("entry");
00266     return eripc_menu_add_menu(eripcClient, name, group1, group2, group3, "");
00267 }
00268 
00269 
00270 gboolean ipc_menu_add_group( const char *name,
00271                              const char *parent, 
00272                              const char *image )
00273 {
00274     //LOGPRINTF("entry");
00275     return eripc_menu_add_group(eripcClient, name, parent, image);
00276 }
00277 
00278 
00279 gboolean ipc_menu_add_item( const char *name,
00280                             const char *parent, 
00281                             const char *image  )
00282 {
00283     //LOGPRINTF("entry");
00284     return eripc_menu_add_item(eripcClient, name, parent, image);
00285 }
00286 
00287 
00288 gboolean ipc_menu_set_menu_label ( const char *name,
00289                                    const char *label )
00290 {
00291     //LOGPRINTF("entry");
00292     return eripc_menu_set_menu_label(eripcClient, name, label);
00293 }
00294 
00295 
00296 gboolean ipc_menu_set_group_label ( const char *name,
00297                                     const char *label )
00298 {
00299     //LOGPRINTF("entry");
00300     return eripc_menu_set_group_label(eripcClient, name, label);
00301 }
00302 
00303 
00304 gboolean ipc_menu_set_item_label ( const char *name,
00305                                    const char *parent, 
00306                                    const char *label )
00307 {
00308     //LOGPRINTF("entry");
00309     return eripc_menu_set_item_label(eripcClient, name, parent, label);
00310 }
00311 
00312 
00313 gboolean ipc_menu_show_menu( const char *name )
00314 {
00315     LOGPRINTF("entry");
00316     return eripc_menu_show_menu(eripcClient, name);
00317 }
00318 
00319 
00320 gboolean ipc_remove_menu( const char *name )
00321 {
00322     LOGPRINTF("entry");
00323     return eripc_menu_remove_menu(eripcClient, name);
00324 }
00325 
00326 
00327 gboolean ipc_menu_set_group_state( const char *name,
00328                                    const char *state )
00329 {
00330     LOGPRINTF("entry");
00331     return eripc_menu_set_group_state(eripcClient, name, state);
00332 }
00333 
00334 
00335 gboolean ipc_menu_set_item_state( const char *name,
00336                                   const char *parent,
00337                                   const char *state  )
00338 {
00339     //LOGPRINTF("entry");
00340     return eripc_menu_set_item_state(eripcClient, name, parent, state);
00341 }
00342 
00343 
00344 const device_caps_t* ipc_sys_get_device_capabilities ( void )
00345 {
00346     static device_caps_t dev_caps;
00347 
00348     eripc_device_caps_t er_dev_caps;
00349 
00350     eripc_sysd_get_device_capabilities( eripcClient, &er_dev_caps );
00351 
00352     dev_caps.has_stylus = er_dev_caps.has_stylus;
00353     dev_caps.has_wifi = er_dev_caps.has_wifi;
00354     dev_caps.has_bluetooth = er_dev_caps.has_bluetooth;
00355     dev_caps.has_3g = er_dev_caps.has_3g;
00356 
00357     return &dev_caps;
00358 }
00359 
00360 
00361 //============================================================================
00362 // Local Function Implementation
00363 //============================================================================
00364 
00365 //----------------------------------------------------------------------------
00366 // Signal/message handlers
00367 //----------------------------------------------------------------------------
00368 
00369 /* @brief Called when a menu items is activated in Popup menu
00370  *
00371  * Application (callee) should handle the item depending on the current state.
00372  */
00373 static void on_menu_item ( eripc_context_t          *context,
00374                            const eripc_event_info_t *info,
00375                            void                     *user_data )
00376 {
00377     LOGPRINTF("entry");
00378     const eripc_arg_t *arg_array = info->args;
00379 
00380     if ((arg_array[0].type == ERIPC_TYPE_STRING) && 
00381         (arg_array[1].type == ERIPC_TYPE_STRING) && 
00382         (arg_array[2].type == ERIPC_TYPE_STRING) && 
00383         (arg_array[3].type == ERIPC_TYPE_STRING))
00384     {
00385         const char        *item      = arg_array[0].value.s;
00386         const char        *group     = arg_array[1].value.s;
00387         const char        *menu      = arg_array[2].value.s;
00388         const char        *state     = arg_array[3].value.s;
00389         
00390         if (item && group && menu && state)
00391         {
00392             menu_on_item_activated( item, group, menu, state );
00393         }
00394     }
00395 }
00396 
00397 
00398 /* @brief Called after a window was activated (set to the foreground)
00399  *
00400  * Application (callee) should set its context for the given window and set the 
00401  * Popupmenu menu context.
00402  */
00403 static void on_window_activated( eripc_context_t          *context,
00404                                  const eripc_event_info_t *info,
00405                                  void                     *user_data )
00406 {
00407     LOGPRINTF("entry");
00408     gboolean          result      = FALSE; 
00409     const eripc_arg_t *arg_array  = info->args;
00410 
00411     if (arg_array[0].type == ERIPC_TYPE_INT)
00412     {
00413         menu_show();
00414         result = TRUE;
00415     }
00416 
00417     // return result to caller
00418     eripc_reply_bool(context, info->message_id, result);
00419 }
00420 
00421 
00422 /* @brief Called after a window was deactivated (set to the background)
00423  *
00424  * Application (callee) may adapt its context and free resources.
00425  */  
00426 static void on_window_deactivated( eripc_context_t          *context,
00427                                    const eripc_event_info_t *info,
00428                                    void                     *user_data )
00429 {
00430     LOGPRINTF("entry");
00431     gboolean          result      = FALSE; 
00432     const eripc_arg_t *arg_array  = info->args;
00433 
00434     if (arg_array[0].type == ERIPC_TYPE_INT)
00435     {
00436 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00437         view_deactivated();
00438 #endif        
00439         result = TRUE;
00440     }
00441    
00442     // return result to caller
00443     eripc_reply_bool(context, info->message_id, result);
00444 }
00445 
00446 
00447 /* @brief Called after network connection state was requested, or the state has changed
00448  *
00449  */  
00450 static void on_connection_status ( eripc_context_t          *context,
00451                                    const eripc_event_info_t *info,
00452                                    void                     *user_data )
00453 {
00454     LOGPRINTF("entry");
00455     const eripc_arg_t *arg_array  = info->args;
00456 
00457     if ((arg_array[0].type == ERIPC_TYPE_BOOL) && 
00458         (arg_array[1].type == ERIPC_TYPE_STRING) && 
00459         (arg_array[2].type == ERIPC_TYPE_STRING) && 
00460         (arg_array[3].type == ERIPC_TYPE_STRING))
00461     {
00462         gboolean    is_connected = arg_array[0].value.b;
00463       //const gchar *medium      = arg_array[1].value.s;
00464       //const gchar *profile     = arg_array[2].value.s;
00465       //const gchar *reason      = arg_array[3].value.s;
00466 
00467         if (is_connected)
00468         {
00469             LOGPRINTF("Network connection established");
00470             g_connect_cb();
00471         }
00472         else
00473         {
00474             LOGPRINTF("Network connection terminated - reason [%s]", arg_array[3].value.s);
00475             g_disconnect_cb();
00476         }
00477     }
00478 }
00479 
00480 
00481 /* @brief Called when a file, document or url is to be opened by the application
00482  *
00483  * Application (callee) should create and realise, or reuse an existing window 
00484  * for the given file and return the X window id in the method reply. The X window 
00485  * can be obtained using GDK_WINDOW_XID(widget->window). When the file is already 
00486  * opened by the callee, it may just return its X window id. This call implies that
00487  * the window is activated (set to the foreground) so callee should also set its 
00488  * context for the given window and set the Popupmenu menu context. 
00489  * System Daemon adds a task to Task Manager of Popupmenu, or replaces the task 
00490  * when an existing window is returned.
00491  */
00492 static void on_file_open ( eripc_context_t          *context,
00493                            const eripc_event_info_t *info,
00494                            void                     *user_data )
00495 {
00496     LOGPRINTF("entry");
00497     gchar             *error_msg  = NULL;
00498     gint              my_xid      = -1; 
00499 
00500     const eripc_arg_t *arg_array  = info->args;
00501     
00502     if (arg_array[0].type == ERIPC_TYPE_STRING)
00503     {
00504         const char *file = arg_array[0].value.s;
00505         if (file)
00506         {
00507             menu_show();
00508             my_xid = GDK_WINDOW_XID(g_main_window->window);
00509             view_open_uri(file);
00510         }
00511     }
00512     
00513     // return result to caller
00514     eripc_reply_varargs(context, info->message_id, 
00515                         ERIPC_TYPE_INT, my_xid,
00516                         ERIPC_TYPE_STRING, error_msg,
00517                         ERIPC_TYPE_INVALID);
00518     g_free(error_msg);
00519 }
00520 
00521 
00522 /* @brief Called when a file, document or url is to be closed by the application
00523  *
00524  * Application (callee) should close the file and may destroy its window and free 
00525  * other resources. System Daemon removes the task from the Task Manager of Popupmenu.
00526  */
00527 static void on_file_close ( eripc_context_t          *context,
00528                             const eripc_event_info_t *info,
00529                             void                     *user_data )
00530 {
00531     LOGPRINTF("entry");
00532     
00533     // return result to caller
00534     eripc_reply_bool(context, info->message_id, TRUE);
00535     
00536     main_quit();
00537 }
00538 
00539 
00540 /* @brief Called just after a volume is mounted
00541  *
00542  * Application may use this to add/open the new volume.
00543  */
00544 static void on_mounted ( eripc_context_t          *context,
00545                          const eripc_event_info_t *info,
00546                          void                     *user_data )
00547 {
00548     LOGPRINTF("entry");
00549     const eripc_arg_t *arg_array  = info->args;
00550 
00551     if (arg_array[0].type == ERIPC_TYPE_STRING)
00552     {
00553         const char *mountpoint = arg_array[0].value.s;
00554         if (mountpoint)
00555         {
00556             LOGPRINTF("Device mounted: %s", mountpoint);
00557             g_free(g_mountpoint);
00558             g_mountpoint = g_strdup(mountpoint);
00559         }
00560     }
00561 }
00562 
00563 
00564 /* @brief Called just before unmounting the volume
00565  *
00566  * Application must close all its open files on the given volume. Failing to 
00567  * this signal may result in unsaved data or currupt files.
00568  */
00569 static void on_prepare_unmount ( eripc_context_t          *context,
00570                                  const eripc_event_info_t *info,
00571                                  void                     *user_data )
00572 {
00573     LOGPRINTF("entry");
00574     const eripc_arg_t *arg_array  = info->args;
00575 
00576     if (arg_array[0].type == ERIPC_TYPE_STRING)
00577     {
00578         const char *mountpoint = arg_array[0].value.s;
00579         if (mountpoint)
00580         {
00581             g_free(g_mountpoint);
00582             g_mountpoint = NULL;
00583             main_quit();
00584         }
00585     }
00586 }
00587 
00588 
00589 /* @brief Called just after unmounting the volume
00590  *
00591  * Typically an application should have responded to a prior sysPrepareUnmount 
00592  * signal, but when a device with volumes was removed unexpectedly it may need 
00593  * to act on this signal.
00594  */  
00595 static void on_unmounted ( eripc_context_t          *context,
00596                            const eripc_event_info_t *info,
00597                            void                     *user_data )
00598 {
00599     LOGPRINTF("entry");
00600     const eripc_arg_t *arg_array  = info->args;
00601 
00602     if (arg_array[0].type == ERIPC_TYPE_STRING)
00603     {
00604         const char  *mountpoint = arg_array[0].value.s;
00605         if (mountpoint)
00606         {
00607             main_quit();
00608         }
00609     }
00610 }
00611 
00612 
00613 /* @brief Called when the system's locale has changed
00614  *
00615  * Application should load language dependent screen texts and probably set new 
00616  * labels for its menu items; to activate a new locale application should call:
00617  *             g_setenv("LANG", new_locale, TRUE);
00618  *             setlocale(LC_ALL, "");
00619  */
00620 static void on_changed_locale ( eripc_context_t          *context,
00621                                 const eripc_event_info_t *info,
00622                                 void                     *user_data )
00623 {
00624     LOGPRINTF("entry");
00625     const eripc_arg_t *arg_array = info->args;
00626 
00627     if (arg_array[0].type == ERIPC_TYPE_STRING)
00628     {
00629         const char *locale = arg_array[0].value.s;
00630         if (locale)
00631         {
00632             const char *old_locale = g_getenv("LANG");
00633             if (!old_locale || (strcmp(old_locale, locale) != 0))
00634             {
00635                 g_setenv("LANG", locale, TRUE);
00636                 setlocale(LC_ALL, "");
00637                 
00638                 g_locale_cb();
00639             }
00640         }
00641     }
00642 }
Generated by  doxygen 1.6.2-20100208