contentLister/src/programManager.c File Reference

content lister - eReader program manager More...

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <memory.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <liberregxml/erregapi.h>
#include <liberipc/eripctoolbar.h>
#include <libermanifest/ermanifest.h>
#include "contentListerLog.h"
#include "erbusy.h"
#include "displayUpdate.h"
#include "programManager.h"
#include "regValue.h"
#include "button.h"
#include "erConnect.h"
#include "erMSDisk.h"
#include "system.h"
#include "gtkPincodeScreen.h"
#include "control.h"
#include "toolbar.h"
#include "languages.h"
#include "timedids.h"

Go to the source code of this file.

Classes

struct  signal_data_t

Defines

#define PIPE_READ   0
#define PIPE_WRITE   1

Functions

static int pm_XErrorHandler (Display *display, XErrorEvent *event)
static int pm_UpdateState ()
static gboolean pm_InitProgramTable (void)
static void pm_InitExtTable (void)
static int pm_GetClientList (Display *display, Window window, Atom atom, Window **windowList)
static void pm_PatchProgramTable ()
static void pm_UpdateXClientReference (gpointer key, gpointer value, gpointer user_data)
static void pm_IconifyUserApp (gpointer key, gpointer value, gpointer user_data)
static void pm_TerminateUserApp (gpointer key, gpointer value, gpointer user_data)
static void pm_AddExtensionsToTable (gpointer key, gpointer value, gpointer user_data)
static GString * pm_CreateCommand (char *szExec, char *szArgMask, char *filename, char *manifest, char *options)
static Time pm_fake_timestamp ()
static int pm_getWinOnTop ()
static void pm_setLastStartedUa (gchar *uaID)
void pt_key_destroy (gpointer key)
void pt_value_destroy (gpointer value)
void et_value_destroy (gpointer value)
static void signals_init (void)
static void on_signal (int signal)
static gboolean on_signal_gtk (GIOChannel *source, GIOCondition cond, gpointer p)
static void on_sigchld (int signo, pid_t pid, int status)
static void pm_DisplayXClientInfo (GArray *clientInfo)
gboolean pm_InitProgramManager (void)
void pm_SetMyWindow (Window window)
void pm_DestroyProgramManager (void)
char * pm_getUaID (char *extension)
char * pm_getIcon (char *extension)
gboolean pm_RaiseContentLister ()
gboolean pm_RaiseUserApp (gchar *uaId)
gboolean pm_IsActive (gchar *uaId)
void pm_SendKey (KeySym keysym)
gchar * pm_getUaOnTop ()
void pm_setUaOnTop (gchar *uaID)
int pm_RunViewer (gchar *uaID, char *filename, char *manifest, char *options, int reuse)

Variables

static GArray * g_xClientInfo = NULL
static Window g_myWin
static GHashTable * g_programInfo = NULL
static GHashTable * g_extensionInfo = NULL
static gchar g_uaOnTop [UAID_MAX_SIZE]
static gchar g_lastStartedUa [UAID_MAX_SIZE]
static int signal_pipe [2]


Detailed Description

content lister - eReader program manager

<File description>="">

Manages the programs running on the eReader spawns processes and sends keys

Definition in file programManager.c.


Define Documentation

#define PIPE_READ   0

Definition at line 1308 of file programManager.c.

#define PIPE_WRITE   1

Definition at line 1309 of file programManager.c.


Function Documentation

void et_value_destroy ( gpointer  value  ) 

Definition at line 1237 of file programManager.c.

01238 {
01239     erExtInfo_t *theExtInfo;
01240 
01241     if (value)
01242     {
01243         theExtInfo = (erExtInfo_t *) value;
01244 
01245         CL_PMPRINTF("%s", theExtInfo->uaID);
01246 
01247         if (theExtInfo->iconLocation)
01248         {
01249             g_free(theExtInfo->iconLocation);
01250         }
01251 
01252         g_free(theExtInfo);
01253         theExtInfo = NULL;
01254     }
01255 }

static void on_sigchld ( int  signo,
pid_t  pid,
int  status 
) [static]

Definition at line 174 of file programManager.c.

00175 {
00176     listerState_t lister_state = getListerState();
00177 
00178     CL_WARNPRINTF("entry: signo [%d] pid [%d] status [0x%04X]", signo, pid, status);
00179 
00180     if (pid == erConnectPid())
00181     {
00182         // connection manager has exited -> did it terminate normally?
00183         if (WIFEXITED(status))
00184         {
00185             CL_WARNPRINTF("ConnectionMgr terminated with return value %d", WEXITSTATUS(status));
00186         }
00187         else if (WIFSIGNALED(status))
00188         {
00189             CL_WARNPRINTF("ConnectionMgr terminated by signal [%d]", WTERMSIG(status));
00190         }
00191 
00192         // it's possible downloadMgr changes pincode
00193         ctrl_pincode_setting_init();
00194 
00195         // check if this is a timed-iDS connection
00196         timed_ids_handle_connmgr_quit();
00197     }
00198     else
00199     {
00200         // Note: Searching hash table on g_lastStartedUa only works when at most one viewer/application running.
00201         //       When contentLister keeps two or more viewers/applications alive, search the hash table on pid.
00202         erApplicationInfo_t *theAppInfo = (erApplicationInfo_t *) g_hash_table_lookup(g_programInfo, g_lastStartedUa);
00203         if (theAppInfo)
00204         {
00205             CL_WARNPRINTF("last started [%s] pid [%d]", g_lastStartedUa, theAppInfo->pid);
00206             
00207             // check which process has died and free resources
00208             if (theAppInfo->pid == pid) 
00209             {
00210                 // Remember application not running anymore;
00211                 theAppInfo->pid = -1;
00212                 if (lister_state != STATE_DOWNLOADMGR)
00213                 {
00214                     pm_setUaOnTop(CONTENTLISTER_UAID);
00215                 }
00216 
00217                 // restore toolbar to contentLister layout
00218                 toolbar_restore();
00219 
00220                 // Hack to rescan the language etc. when SETUP app finishes
00221                 if (strncmp(g_lastStartedUa, SETUP_APP, UAID_MAX_SIZE) == 0)
00222                 {
00223                     CL_PMPRINTF("Setup app was on top, do languagesInit() and mdsInit()");
00224 
00225                     // reload registry data
00226                     reload_registry();
00227 
00228                     // 
00229                     languagesInit();
00230                     mdsInit();
00231                     flipbarDirectionSettingInit();
00232                     keybufferingSettingInit();
00233                     ctrlSetScreenTexts();
00234                     ctrl_pincode_setting_init();
00235                     if (getListerState() == STATE_LANG_SEL)
00236                     {
00237                         CL_PMPRINTF("Exiting setup for language selection.");
00238                         setListerState(STATE_NORMAL);
00239                         ctrl_startup();
00240                     }
00241                     // (re)start background-connect
00242                     ctrl_background_connect_timeout_start(TRUE);
00243 
00244                     // allow USB connect again
00245                     erMSDisk_handle_reread_settings();
00246                     
00247                     // (re)start timed-iDS connect
00248                     timed_ids_handle_reread_settings();
00249                 }
00250 
00251                 // allow USB connect again
00252                 if (   lister_state != STATE_PINCODE
00253                     && lister_state != STATE_DOWNLOADMGR)
00254                 {
00255                     erStartMSDiskApp();
00256                 }
00257                 
00258                 // rescan the current folder
00259                 if (getListerState() != STATE_USB_CONNECTED)
00260                 {
00261                     ctrl_rescan_current();
00262                 }
00263             }
00264         }
00265     }
00266     
00267     CL_WARNPRINTF("end");
00268 }

Here is the call graph for this function:

static void on_signal ( int  signal  )  [static]

Definition at line 1365 of file programManager.c.

01366 {
01367     int            bytes_written;
01368     int            status;
01369     signal_data_t  data;
01370     pid_t          pid;
01371     gboolean       done;
01372     gboolean       do_write;
01373 
01374     CL_LOGPRINTF("entry: signal [%d]", signal);
01375     
01376     done        = FALSE;
01377     data.signo  = signal;
01378     data.pid    = 0;
01379     data.status = 0;
01380     while (!done)
01381     {
01382         do_write = FALSE;
01383         if (signal == SIGCHLD)
01384         {
01385             // SIGCHLD signal: query child process and forward these to GTK thread
01386 
01387             // find out which process has ended
01388             pid = waitpid(-1, &status, WNOHANG);
01389             if (pid > 0)
01390             {
01391                 CL_PMPRINTF("child died: pid [%d] exited [%d] signaled [%d]",
01392                              pid, WIFEXITED(status), WIFSIGNALED(status) );
01393 
01394                 // process status received: check it
01395                 if ( WIFEXITED(status)  ||  WIFSIGNALED(status) )
01396                 {
01397                     // process has terminated: report to GTK thread
01398                     data.pid    = pid;
01399                     data.status = status;
01400                     do_write = TRUE;
01401 
01402                     // temporarily block all keys
01403                     // this prevents sending keys to an application that is no longer present
01404                     button_block_all_keys(TRUE);
01405                 }
01406             }
01407             else
01408             {
01409                 // no more process: stop querying processes
01410                 done = TRUE;
01411             }
01412         }
01413         else
01414         {
01415             // other signal: forward this to GTK thread
01416             done = TRUE;
01417         }
01418         
01419         if (do_write)
01420         {
01421             bytes_written = write(signal_pipe[PIPE_WRITE], &data, sizeof(data));
01422             fsync(signal_pipe[PIPE_WRITE]);  // just to be sure
01423             if (bytes_written != sizeof(data))
01424             {
01425                 CL_ERRORPRINTF("unix signal [%d] [%d] lost\n", data.signo, data.pid);
01426             }
01427         }
01428     }
01429 }

Here is the call graph for this function:

static gboolean on_signal_gtk ( GIOChannel *  source,
GIOCondition  cond,
gpointer  p 
) [static]

Definition at line 1432 of file programManager.c.

01433 {
01434     CL_LOGPRINTF("entry");
01435 
01436     signal_data_t data;
01437     GIOStatus     status;             // save the reading status
01438     gsize         bytes_read;         // save the number of chars read
01439     gboolean      done;
01440     GError*       error = NULL;
01441 
01442     // Read from the pipe as long as data is available.
01443     // The reading end is in non-blocking mode, so once we have consumed all unix signals, 
01444     // the read returns G_IO_STATUS_AGAIN. 
01445     done = FALSE;
01446     while (done == FALSE)
01447     {
01448         status = g_io_channel_read_chars(source, (char*)&data, sizeof(data), &bytes_read, &error);
01449         if (status == G_IO_STATUS_NORMAL)
01450         {
01451             g_assert(error == NULL);  // no error if reading returns normal
01452 
01453             if (bytes_read == sizeof(data))
01454             {
01455                 // Got the expected number of bytes, consider this a valid signal
01456                 CL_LOGPRINTF("signal read from pipe: [%d] [%d] [%d]", data.signo, data.pid, data.status);
01457                 if (data.signo == SIGCHLD)
01458                 {
01459                     CL_LOGPRINTF("read a SIGCHLD signal");
01460                     on_sigchld(data.signo, data.pid, data.status);
01461 
01462                     // terminated application has been incorparated in our administration,
01463                     // so from now on we can allow sending keys to applications again.
01464                     // but first check if iLiad is waken up by RTC alarm
01465                     if (get_timedids_connect_reason() != connect_after_wakeup)
01466                     {
01467                         button_block_all_keys(FALSE);
01468                     }
01469                 }
01470                 else
01471                 {
01472                     CL_ERRORPRINTF("Unexpected signal [%d] [%d]", data.signo, data.pid);
01473                 }
01474             }
01475             else
01476             {
01477                 // Incorrect number of bytes: discard garbage and keep fingers crossed
01478                 CL_ERRORPRINTF("incomplete read from pipe: requested [%d] received [%d]", sizeof(data), bytes_read);
01479                 done = TRUE;
01480             }
01481         }
01482         else if (status == G_IO_STATUS_AGAIN)
01483         {
01484             // Nothing more to read from pipe
01485             CL_LOGPRINTF("pipe empty");
01486             done = TRUE;
01487         }
01488         else
01489         {
01490             CL_ERRORPRINTF("unexpected return g_io_channel_read_chars [%d]", status);
01491             done = TRUE;
01492         }
01493     }
01494   
01495     return (TRUE);  // Please call again
01496 }

Here is the call graph for this function:

static void pm_AddExtensionsToTable ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 1139 of file programManager.c.

01140 {
01141     int     index;
01142     erApplicationInfo_t *theApplicationInfo = (erApplicationInfo_t *) value;
01143     regExtInfoList_t *theRegExtInfoList = (regExtInfoList_t *) user_data;
01144     erExtInfo_t *theExtInfo;
01145 
01146     // Only need to check the applications enabled.
01147     if ((theApplicationInfo) && (theRegExtInfoList) && (theApplicationInfo->enabled))
01148     {
01149         // Need to compare every extension name that input application supports with the 
01150         // extension list from registry to decide which application is the best one to 
01151         // open the document with the certain extension name.
01152         for (index = 0; index < theApplicationInfo->userApp->extensionArraySize; index++)
01153         {
01154             theExtInfo = g_new0(erExtInfo_t, 1);
01155 
01156             if (theRegExtInfoList)
01157             {
01158                 // Choose the smallest associate order with same extension name.
01159                 // It's faster than using xpath.
01160                 int i = 0, order = INT_MAX, pos = -1;
01161                 for(; i < theRegExtInfoList->extArraySize; ++i)
01162                 {
01163                     // Compare extension from ExtInfoList with those from theApplicationInfo 
01164                     if ((theRegExtInfoList->extArray[i].extName) && 
01165                         (strcmp(theApplicationInfo->userApp->extensionArray[index], 
01166                                 theRegExtInfoList->extArray[i].extName) == 0))
01167                     {                                
01168                         if (order > theRegExtInfoList->extArray[i].associateOrder)
01169                         {
01170                             order = theRegExtInfoList->extArray[i].associateOrder;
01171                             pos = i;
01172                         }
01173                     }
01174                 }
01175                 // If an association is found, use it. Otherwise use the application that referenced this extension.
01176                 if (pos != -1)
01177                 {
01178                     theExtInfo->uaID = g_strdup(theRegExtInfoList->extArray[pos].associateApp);
01179                     theExtInfo->iconLocation = g_strdup(theRegExtInfoList->extArray[pos].iconLocation);
01180                 }
01181                 else
01182                 {
01183                     CL_WARNPRINTF("Program %s associated with [%s] without extensionInfo entry in registry. Consider fixing this!", 
01184                                 theApplicationInfo->uaID, theApplicationInfo->userApp->extensionArray[index]);
01185                     theExtInfo->uaID = theApplicationInfo->uaID;
01186                     theExtInfo->iconLocation = NULL;
01187                 }
01188             }
01189             else
01190             {
01191                 theExtInfo->uaID = theApplicationInfo->uaID;
01192             }
01193 
01194             CL_PMPRINTF("add %s - %s - %s", theApplicationInfo->userApp->extensionArray[index],
01195                          theApplicationInfo->uaID,
01196                          (theExtInfo->iconLocation == NULL) ? "NULL" : theExtInfo->iconLocation);
01197 
01198             g_hash_table_insert(g_extensionInfo, theApplicationInfo->userApp->extensionArray[index], theExtInfo);
01199         }
01200     }
01201 }

static GString * pm_CreateCommand ( char *  szExec,
char *  szArgMask,
char *  filename,
char *  manifest,
char *  options 
) [static]

Definition at line 866 of file programManager.c.

00867 {
00868     GString *theCommand = NULL;
00869     char   *file_ptr;
00870     char   *manifest_ptr;
00871     int     location = 0;
00872 
00873     if ((szExec) && (szArgMask))
00874     {
00875         theCommand = g_string_sized_new(COMMAND_MAX_SIZE);
00876 
00877         if (theCommand)
00878         {
00879             g_string_printf(theCommand, "%s", szExec);
00880             g_string_append_printf(theCommand, " ");
00881             g_string_append_printf(theCommand, "%s", szArgMask);
00882 
00883             CL_PMPRINTF("theCommand %s", theCommand->str);
00884 
00885             file_ptr = g_strstr_len(theCommand->str, theCommand->len, FILENAME_ARG);
00886 
00887             if (file_ptr && filename)
00888             {
00889                 location = file_ptr - theCommand->str;
00890 
00891                 CL_PMPRINTF("%s location %d", FILENAME_ARG, location);
00892 
00893                 g_string_erase(theCommand, location, strlen(FILENAME_ARG));
00894                 g_string_insert(theCommand, location, "\"\"");
00895                 g_string_insert(theCommand, location + 1, filename);
00896 
00897                 CL_PMPRINTF("inserted filename => %s", theCommand->str);
00898             }
00899             else
00900             {
00901                 CL_PMPRINTF("file_ptr %s - filename %s", (file_ptr == NULL) ? "NULL" : file_ptr,
00902                             (filename == NULL) ? "NULL" : filename);
00903             }
00904 
00905             manifest_ptr = g_strstr_len(theCommand->str, theCommand->len, MANIFEST_ARG);
00906             if (manifest_ptr && manifest)
00907             {
00908                 location = manifest_ptr - theCommand->str;
00909 
00910                 CL_PMPRINTF("%s location %d", MANIFEST_ARG, location);
00911 
00912                 g_string_erase(theCommand, location, strlen(FILENAME_ARG));
00913                 g_string_insert(theCommand, location, "\"\"");
00914                 g_string_insert(theCommand, location + 1, manifest);
00915 
00916                 CL_PMPRINTF("inserted manifest => %s", theCommand->str);
00917             }
00918             else
00919             {
00920                 CL_PMPRINTF("manifest_ptr %s - manifest %s", (manifest_ptr == NULL) ? "NULL" : manifest_ptr,
00921                             (filename == NULL) ? "NULL" : manifest);
00922             }
00923 
00924             if (options)
00925             {
00926                 g_string_append_printf(theCommand, " ");
00927                 g_string_append_printf(theCommand, "%s", options);
00928                 CL_PMPRINTF("inserted extra options => %s", theCommand->str);
00929             }
00930         }                       // theCommand
00931     }
00932     return theCommand;
00933 }

void pm_DestroyProgramManager ( void   ) 

Destroy the global data used by the program manager module

Returns:
TRUE in case of succes

Definition at line 162 of file programManager.c.

00163 {
00164     CL_PMPRINTF("entry");
00165     signal(SIGCHLD, SIG_IGN);
00166 
00167     // Do NOT destroy data, these are used even after pm_DestroyProgramManager()
00168     // Let's rely on the OS to free all memory when the contentLister exits.
00169     // g_hash_table_destroy(g_extensionInfo);
00170     // g_hash_table_destroy(g_programInfo);
00171     // g_array_free(g_xClientInfo, TRUE);
00172 }

static void pm_DisplayXClientInfo ( GArray *  clientInfo  )  [static]

Definition at line 1011 of file programManager.c.

01012 {
01013     int     index;
01014     erXClient_t *client;
01015 
01016     CL_PMPRINTF("entry");
01017 
01018     for (index = 0; index < clientInfo->len; index++)
01019     {
01020         client = &g_array_index(clientInfo, erXClient_t, index);
01021 
01022         CL_PMPRINTF("");
01023         CL_PMPRINTF("clientInfo[%d] address 0x%x", index, (unsigned int)client);
01024         CL_PMPRINTF("resName %s", client->resName);
01025         CL_PMPRINTF("window id 0x%x", (unsigned int)client->win);
01026 //        CL_PMPRINTF("state %ld", client->winState);
01027     }
01028 }

static Time pm_fake_timestamp (  )  [static]

Definition at line 534 of file programManager.c.

00535 {
00536     int     tint;
00537     struct timeval tv;
00538 
00539     gettimeofday(&tv, NULL);
00540     tint = (int) tv.tv_sec * 1000;
00541     tint = tint / 1000 * 1000;
00542     tint = tint + tv.tv_usec / 1000;
00543     return (Time) tint;
00544 }

static int pm_GetClientList ( Display *  display,
Window  window,
Atom  atom,
Window **  windowList 
) [static]

Definition at line 1031 of file programManager.c.

01032 {
01033     unsigned char *data;
01034     int     real_format;
01035     Atom    real_type;
01036     unsigned long itemsRead, itemsLeft;
01037 
01038     CL_PMPRINTF("entry");
01039 
01040     if (XGetWindowProperty(display, window, atom, 0, 0x7fffffff,
01041                            False, XA_WINDOW, &real_type, &real_format, &itemsRead, &itemsLeft,
01042                            (unsigned char **) &data) == Success && itemsRead >= 1)
01043     {
01044 
01045         CL_PMPRINTF("%ld top level windows", itemsRead);
01046         *windowList = (Window *) data;
01047         return itemsRead;
01048     }
01049     return -1;
01050 }

char* pm_getIcon ( char *  extension  ) 

Returns the READ ONLY icon location for this extension.

returned value is READ ONLY

Definition at line 289 of file programManager.c.

00290 {
00291     erExtInfo_t *theExtInfo = NULL;
00292 
00293     if (extension)
00294     {
00295         theExtInfo = g_hash_table_lookup(g_extensionInfo, extension);
00296 
00297         if (theExtInfo)
00298         {
00299             CL_PMPRINTF("iconLocation %s - extension %s",
00300                         (theExtInfo->iconLocation == NULL) ? "NULL" : theExtInfo->iconLocation, extension);
00301             return theExtInfo->iconLocation;
00302         }
00303     }
00304 
00305     return NULL;
00306 }

char* pm_getUaID ( char *  extension  ) 

Returns the READ ONLY uaID assocaited with this extension.

returned value is READ ONLY

Definition at line 270 of file programManager.c.

00271 {
00272     erExtInfo_t *theExtInfo = NULL;
00273 
00274     CL_PMPRINTF("entry");
00275 
00276     if (extension)
00277     {
00278         theExtInfo = g_hash_table_lookup(g_extensionInfo, extension);
00279 
00280         if (theExtInfo)
00281         {
00282             CL_PMPRINTF("uaID %s - extension %s", (theExtInfo->uaID == NULL) ? "NULL" : theExtInfo->uaID, extension);
00283             return theExtInfo->uaID;
00284         }
00285     }
00286     return NULL;
00287 }

gchar* pm_getUaOnTop ( void   ) 

Returns the uaID of the user application currently on top of the window stack.

returned value is READ ONLY

Definition at line 528 of file programManager.c.

00529 {
00530     CL_PMPRINTF("return UaID [%s]", g_uaOnTop);
00531     return g_uaOnTop;
00532 }

static int pm_getWinOnTop (  )  [static]

Definition at line 630 of file programManager.c.

00631 {
00632     int     nmbrOfXClients;
00633     char   *uaId;
00634     Window  win = -1;
00635     erApplicationInfo_t *theAppInfo;
00636 
00637     CL_PMPRINTF("entry");
00638 
00639     uaId = pm_getUaOnTop();
00640 
00641     if (strncmp(uaId, CONTENTLISTER_UAID, UAID_MAX_SIZE) == 0)
00642     {
00643         // My own window 
00644         win = g_myWin;
00645     }
00646     else
00647     {
00648         // Update the view on XClients
00649         nmbrOfXClients = pm_UpdateState();
00650         if (nmbrOfXClients < 0)
00651         {
00652             CL_ERRORPRINTF("Failed to update state");
00653         }
00654         else
00655         {
00656             // Patch the program table with the info retrieved on the XClients
00657             pm_PatchProgramTable();
00658             
00659             theAppInfo = (erApplicationInfo_t *) g_hash_table_lookup(g_programInfo, uaId);
00660             if (theAppInfo != NULL  &&  theAppInfo->xclient != NULL)
00661             {
00662                 // application info found and xclient present -> this is the one
00663                 win = theAppInfo->xclient->win;
00664                 CL_PMPRINTF("window with id (0x%x)", (unsigned int)win);
00665             }
00666             else
00667             {
00668                 // app-info or xclient problem -> error
00669                 CL_ERRORPRINTF("theAppInfo [%p]", theAppInfo);
00670                 if (theAppInfo)
00671                 {
00672                     CL_ERRORPRINTF("theAppInfo->xclient [%p]", theAppInfo->xclient);
00673                 }
00674                 return -1;
00675             }
00676         }
00677     }
00678     return win;
00679 }

Here is the call graph for this function:

static void pm_IconifyUserApp ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 547 of file programManager.c.

00548 {
00549     erApplicationInfo_t *theAppInfo = (erApplicationInfo_t *) value;
00550     Display *display = (Display *) user_data;
00551 
00552     CL_PMPRINTF("entry");
00553 
00554     if ((theAppInfo) && (user_data))
00555     {
00556         int     screen = gdk_x11_get_default_screen();
00557 
00558         if (theAppInfo->xclient != NULL)
00559         {
00560             CL_PMPRINTF("Lower window %s", theAppInfo->userApp->xResName);
00561             XIconifyWindow(display, theAppInfo->xclient->win, screen);
00562         }
00563     }
00564 }

static void pm_InitExtTable ( void   )  [static]

going to load extension information from registry file.

Definition at line 1118 of file programManager.c.

01119 {
01120     CL_PMPRINTF("entry");
01121 
01122     g_extensionInfo = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, et_value_destroy);
01123 
01125     regExtInfoList_t *theRegExtInfoList = 0;    
01126     theRegExtInfoList = erRegGetExtInfoList(NULL);
01127     if (theRegExtInfoList)
01128     {
01129         g_hash_table_foreach(g_programInfo, pm_AddExtensionsToTable, theRegExtInfoList);
01130         erRegFreeExtInfoList(theRegExtInfoList);
01131     }
01132     else
01133     {
01134         CL_ERRORPRINTF("erRegGetExtInfoList returns NULL");
01135     }
01136     // pm_DisplayExtensionInfo(g_extensionInfo);
01137 }

Here is the call graph for this function:

gboolean pm_InitProgramManager ( void   ) 

create and init the global data used by the program manager module

Returns:
TRUE in case of succes

Definition at line 119 of file programManager.c.

00120 {
00121     gboolean returnValue = TRUE;
00122 
00123     CL_PMPRINTF("entry");
00124 
00125     // Install Unix signal handlers
00126     signals_init();
00127 
00128     strncpy(g_uaOnTop, CONTENTLISTER_UAID, UAID_MAX_SIZE);
00129     strncpy(g_lastStartedUa, CONTENTLISTER_UAID, UAID_MAX_SIZE);
00130     g_myWin = -1; // Set this to the correct value when available with pm_SetMyWindow()
00131     g_xClientInfo = g_array_sized_new(FALSE, TRUE, sizeof(erXClient_t), XCLIENT_ARRAY_RESERVED_SIZE);
00132 
00133     returnValue = pm_InitProgramTable();
00134     if (returnValue)
00135     {
00136         pm_InitExtTable();
00137     }
00138 
00139     // install our own handler for X errors
00140     XSetErrorHandler(pm_XErrorHandler);
00141 
00142     return returnValue;
00143 }

Here is the call graph for this function:

static gboolean pm_InitProgramTable ( void   )  [static]

Definition at line 1059 of file programManager.c.

01060 {
01061     gboolean returnValue = TRUE;
01062     regUserApp_t *theUserApp = NULL;
01063     regUserAppList_t *theUserAppList = NULL;
01064     erApplicationInfo_t *theApplicationInfo = NULL;
01065     char   *key = NULL;
01066     int     i;
01067     struct stat file_stat;
01068 
01069     CL_PMPRINTF("entry");
01070 
01071     theUserAppList = erRegGetUserAppList();
01072     if (theUserAppList)
01073     {
01074         CL_PMPRINTF("erRegReadUserAppList returned %d values", theUserAppList->uaIDArraySize);
01075         g_programInfo = g_hash_table_new_full(g_str_hash, g_str_equal, pt_key_destroy, pt_value_destroy);
01076         for (i = 0; i < theUserAppList->uaIDArraySize; i++)
01077         {
01078             theUserApp = erRegGetUserApp(theUserAppList->uaIDArray[i]);
01079             if (theUserApp)
01080             {
01081                 theApplicationInfo = g_new0(erApplicationInfo_t, 1);
01082 
01083                 theApplicationInfo->userApp = theUserApp;
01084                 strncpy(theApplicationInfo->uaID, theUserAppList->uaIDArray[i], UAID_MAX_SIZE);
01085                 theApplicationInfo->pid = -1;
01086                 
01087                 // Check if application executable exists
01088                 if (stat(theApplicationInfo->userApp->szExec, &file_stat) == 0)
01089                 {
01090                     theApplicationInfo->enabled = TRUE;
01091                 }
01092                 else
01093                 {
01094                     CL_WARNPRINTF("Application [%s] executable [%s] is not found: disabled it", theApplicationInfo->uaID, theApplicationInfo->userApp->szExec);
01095                     theApplicationInfo->enabled = FALSE;
01096                 }
01097 
01098                 CL_PMPRINTF("g_hash_table_insert %s", theUserAppList->uaIDArray[i]);
01099 
01100                 key = g_strdup(theUserAppList->uaIDArray[i]);
01101 
01102                 g_hash_table_insert(g_programInfo, key, theApplicationInfo);
01103             }
01104         }
01105         erRegFreeUserAppList(theUserAppList);
01106         // pm_DisplayProgramInfo(g_programInfo);
01107     }
01108     else
01109     {
01110         CL_ERRORPRINTF("erRegReadUserAppList returned NULL");
01111         returnValue = FALSE;
01112     }
01113         
01114     return returnValue;
01115 }

Here is the call graph for this function:

gboolean pm_IsActive ( gchar *  uaId  ) 

Checks whether a specified viewer is already active.

Returns:
TRUE when active

Definition at line 423 of file programManager.c.

00424 {
00425     int     nmbrOfXClients;
00426     erApplicationInfo_t *theAppInfo;
00427 
00428     CL_PMPRINTF("entry %s", (uaId == NULL) ? "NULL" : uaId);
00429 
00430     theAppInfo = (erApplicationInfo_t *) g_hash_table_lookup(g_programInfo, uaId);
00431 
00432     if (theAppInfo)
00433     {
00434         //Update the view on XClients
00435         nmbrOfXClients = pm_UpdateState();
00436         if (nmbrOfXClients < 0)
00437         {
00438             CL_ERRORPRINTF("Failed to update state");
00439             return FALSE;
00440         }
00441 
00442         // Patch the program table with the info retrieved on the XClients
00443         pm_PatchProgramTable();
00444 
00445         if (NULL != theAppInfo->xclient)
00446         {
00447             return TRUE;
00448         }
00449         else
00450         {
00451             return FALSE;
00452         }
00453     }
00454     else
00455     {
00456         CL_ERRORPRINTF("invalid uaID %s", (NULL == uaId) ? "NULL" : uaId);
00457         return FALSE;
00458     }
00459 }

Here is the call graph for this function:

static void pm_PatchProgramTable (  )  [static]

Definition at line 1257 of file programManager.c.

01258 {
01259     pm_DisplayXClientInfo(g_xClientInfo);
01260     g_hash_table_foreach(g_programInfo, pm_UpdateXClientReference, g_xClientInfo);
01261 }

Here is the call graph for this function:

gboolean pm_RaiseContentLister (  ) 

Raise the contentlister application

Returns:
TRUE in case of succes

Definition at line 308 of file programManager.c.

00309 {
00310     Window  win = 0;
00311     Display *display;
00312     int     nmbrOfXClients;
00313 
00314     CL_PMPRINTF("entry");
00315 
00316     //Update the view on XClients
00317     nmbrOfXClients = pm_UpdateState();
00318     if (nmbrOfXClients < 0)
00319     {
00320         CL_ERRORPRINTF("Failed to update state");
00321         return FALSE;
00322     }
00323 
00324     // Patch the program table with the info retrieved on the XClients
00325     pm_PatchProgramTable();
00326 
00327     // The contentLister window
00328     win = g_myWin;
00329     display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
00330 
00331     if (strcmp(pm_getUaOnTop(), CONTENTLISTER_UAID) != 0)
00332     {
00333         // minimize current application
00334         erApplicationInfo_t *theAppInfo= (erApplicationInfo_t *) 
00335             g_hash_table_lookup(g_programInfo, pm_getUaOnTop());
00336         pm_IconifyUserApp(NULL, theAppInfo, display);
00337         toolbar_restore();
00338     }
00339 
00340     // stop the user application that was on top,
00341     // in fact stop all user applications and viewers
00342     g_hash_table_foreach(g_programInfo, pm_TerminateUserApp, display);
00343 
00344     XRaiseWindow(display, win);
00345     XMapRaised(display, win);
00346     XFlush(display);
00347     pm_setUaOnTop(CONTENTLISTER_UAID);
00348 
00349     CL_PMPRINTF("end");
00350     return TRUE;
00351 }

Here is the call graph for this function:

gboolean pm_RaiseUserApp ( gchar *  uaId  ) 

Raise the specified used application

Returns:
TRUE in case of succes

Definition at line 353 of file programManager.c.

00354 {
00355     Window  win = 0;
00356     Window  CL_win = 0;
00357     Display *display;
00358     int     nmbrOfXClients;
00359     int     index;
00360     erApplicationInfo_t *theAppInfo;
00361     int     screen;
00362     erXClient_t *client;
00363 
00364     CL_PMPRINTF("entry: uaId [%s]", uaId);
00365 
00366     theAppInfo = (erApplicationInfo_t *) g_hash_table_lookup(g_programInfo, uaId);
00367 
00368     if (theAppInfo)
00369     {
00370         //Update the view on XClients
00371         nmbrOfXClients = pm_UpdateState();
00372         if (nmbrOfXClients < 0)
00373         {
00374             CL_ERRORPRINTF("Failed to update state");
00375             return FALSE;
00376         }
00377 
00378         // Patch the program table with the info retrieved on the XClients
00379         pm_PatchProgramTable();
00380 
00381         // find viewer and contentlister window
00382         for (index = 0; index < g_xClientInfo->len; index++)
00383         {
00384             client = &g_array_index(g_xClientInfo, erXClient_t, index);
00385 
00386             if (strcmp(CONTENTLISTER_RESNAME, client->resName) == 0)
00387             {
00388                 CL_win = client->win;
00389             }
00390             if (strcmp(theAppInfo->userApp->xResName, client->resName) == 0)
00391             {
00392                 win = client->win;
00393             }
00394         }
00395 
00396         if ((win != 0) && (CL_win != 0))
00397         {
00398             screen = gdk_x11_get_default_screen();
00399             display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
00400 
00401             CL_PMPRINTF("Lower CL window");
00402             XIconifyWindow(display, CL_win, screen);
00403             XRaiseWindow(display, win);
00404             XMapRaised(display, win);
00405             XFlush(display);
00406             pm_setUaOnTop(uaId);
00407             toolbar_clear();
00408             return TRUE;
00409         }
00410         else
00411         {
00412             CL_ERRORPRINTF("could not find window info");
00413             return FALSE;
00414         }
00415     }
00416     else
00417     {
00418         CL_ERRORPRINTF("invalid uaID %s", (NULL == uaId) ? "NULL" : uaId);
00419         return FALSE;
00420     }
00421 }

Here is the call graph for this function:

int pm_RunViewer ( gchar *  uaId,
char *  filename,
char *  manifest,
char *  options,
int  reuse 
)

Start/Show the specified viewer. In case the viewer supports re-displaying new content, this (generic) mechanism will be invoked

Parameters:
userApplication unique identifier
filename that needs to be passed to the viewer _FILENAME_ in registry [optional]
manifest that needs to be passed to the viewer _MANIFEST_ in regsitry [optional]
options that needs to be passed to the viewer [optional]
reuse if '1' a current instance of the viewer will gain focus and display the selected content. If no such instance is available a new instance will be created
Returns:
0 upon success. A negative value (ERR_INVALID_UAID, ERR_FORK, ERR_ARGUMENT ERR_STATE_UPDATE) in case of failure

Definition at line 681 of file programManager.c.

00682 {
00683     pid_t   pid;
00684     int     nmbrOfXClients;
00685     erApplicationInfo_t *theAppInfo;
00686     Display *display;
00687     Window  ownWin = 0;
00688     int     index;
00689     erXClient_t *client;
00690     int     screen;
00691     GString *theCommand;
00692 
00693     theAppInfo = (erApplicationInfo_t *) g_hash_table_lookup(g_programInfo, (const char*)uaID);
00694 
00695     if (theAppInfo)
00696     {
00697         CL_PMPRINTF("App %s", theAppInfo->uaID);
00698 
00699         toolbar_clear();
00700 
00701         //Update the view on XClients
00702         nmbrOfXClients = pm_UpdateState();
00703         if (nmbrOfXClients < 0)
00704         {
00705             CL_ERRORPRINTF("Failed to update state");
00706             return (ERR_STATE_UPDATE);
00707         }
00708 
00709         // Patch the program table with the info retrieved on the XClients
00710         pm_PatchProgramTable();
00711 
00712         if (reuse == 1)
00713         {
00714             CL_PMPRINTF("Re-use process branch");
00715 
00716             // Is there already a process running?
00717             if (theAppInfo->pid != -1)
00718             {
00719                 // TODO: Here I need to bring the selected app on top of the stack
00720                 // and inform it on the new content to display
00721                 CL_WARNPRINTF("TODO: Bring %s on top of window stack", uaID);
00722 
00723                 if (theAppInfo->xclient != NULL)
00724                 {
00725                     CL_PMPRINTF("Do something with %s 0x%xd",
00726                                 theAppInfo->xclient->resName,
00727                                 (unsigned int)theAppInfo->xclient->win);
00728 
00729                     CL_PMPRINTF("XRaiseWindow: 0x%x (window)", (unsigned int)theAppInfo->xclient->win);
00730 
00731                     display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
00732 
00733                     // Iconize contentLister
00734                     for (index = 0; index < g_xClientInfo->len; index++)
00735                     {
00736                         client = &g_array_index(g_xClientInfo, erXClient_t, index);
00737 
00738                         if (strcmp(CONTENTLISTER_RESNAME, client->resName) == 0)
00739                         {
00740                             ownWin = client->win;
00741                             break;
00742                         }
00743                     }
00744 
00745                     if (ownWin != 0)
00746                     {
00747                         screen = gdk_x11_get_default_screen();
00748 
00749                         CL_PMPRINTF("Lower window %s", client->resName);
00750                         XIconifyWindow(display, ownWin, screen);
00751                     }
00752 
00753                     XMapRaised(display, theAppInfo->xclient->win);
00754                     XRaiseWindow(display, theAppInfo->xclient->win);
00755                     XFlush(display);
00756                     pm_setUaOnTop(uaID);
00757 
00758                     // done
00759                     return (ERR_OK);
00760                 }
00761                 else
00762                 {
00763                     CL_ERRORPRINTF("Did not find xclient info on %s. Should I kill the process here????", uaID);
00764                 }
00765             }
00766             // The else branch is implicit. Just create the process
00767         }
00768         else
00769         {
00770             CL_PMPRINTF("Create new process branch");
00771 
00772             // Is there already a process running?
00773             if (theAppInfo->pid != -1)
00774             {
00775                 CL_WARNPRINTF("Process was already started, not starting it again!");
00776                 return (ERR_VIEWER_RUNNING);
00777             }
00778             // The else branch is implicit. Just create the process
00779         }
00780 
00781         //handle the argument information
00782         theCommand = pm_CreateCommand(theAppInfo->userApp->szExec, theAppInfo->userApp->szArgMask, filename, manifest, options);
00783 
00784         if (theCommand)
00785         {
00786             CL_PMPRINTF("szCommand %s", theCommand->str);
00787         }
00788         else
00789         {
00790             CL_ERRORPRINTF("pm_CreateArgument can't create command");
00791             return (ERR_ARGUMENT);
00792         }
00793 
00794         // Check if ARINC viewer, this is a special case
00795         if (strcmp(uaID, ARINC_APP) == 0)
00796         {
00797             // For Arinc application, exec it, so that contentLister will be
00798             // replaced by eFlyBook
00799 
00800             // Make sure the executable exists; not only the symlink. Otherwise the iLiad will crash.
00801             char *p = realpath(theAppInfo->userApp->szExec, NULL); // p will be allocated by realpath
00802             if (p == NULL) 
00803             {
00804                 CL_WARNPRINTF("Cannot find executable [%s]; not executing in place.", theAppInfo->userApp->szExec);
00805                 return (ERR_FORK);
00806             }
00807             else
00808             {
00809                 g_free(p); // free realpath allocated buffer
00810                 int     nRet;
00811                 CL_WARNPRINTF("Executing [%s] in place; replaces contentLister!", uaID);    
00812                 nRet = shell_exec(theCommand->str);
00813                 CL_ERRORPRINTF("shell_exec of [%s] failed!", uaID);
00814                 CL_ERRORPRINTF("shell exec command [%s]", theCommand->str);
00815                 CL_ERRORPRINTF("shell_exec returned %d", nRet);
00816                 perror("Error upon calling shell_exec");
00817                 fflush(stderr);
00818                 return (ERR_FORK);
00819             }
00820         }
00821         else
00822         {
00823             erStopMSDiskApp();
00824 
00825             switch (pid = fork())
00826             {
00827                 case 0:
00828                 {
00829                     // Here I am in the child process
00830                     int     nRet;
00831 
00832                     nRet = shell_exec(theCommand->str);
00833                     CL_ERRORPRINTF("shell_exec of [%s] failed, cleaning up child", uaID);
00834                     CL_ERRORPRINTF("shell exec command [%s]", theCommand->str);
00835                     CL_ERRORPRINTF("shell_exec returned %d", nRet);
00836                     perror("Error upon calling shell_exec");
00837                     fflush(stderr);
00838                     sleep(1);
00839                     _exit(1);
00840                 }
00841                 case -1:
00842                     // something went wrong with fork => this is the parent process
00843                     CL_ERRORPRINTF("pmRunViewer: can't fork %s", uaID);
00844                     g_string_free(theCommand, TRUE);
00845                     erStartMSDiskApp();
00846                     return (ERR_FORK);
00847             }
00848         }
00849 
00850         // Child process started with succes => here the parent process continues
00851         // Store the pid
00852         theAppInfo->pid = pid;
00853         pm_setUaOnTop(uaID);
00854         pm_setLastStartedUa(uaID);
00855         g_string_free(theCommand, TRUE);
00856         return (ERR_OK);
00857     }
00858     else
00859     {
00860         CL_WARNPRINTF("invalid uaID %s", (NULL == uaID) ? "NULL" : uaID);
00861         return (ERR_INVALID_UAID);
00862     }
00863 
00864 }

Here is the call graph for this function:

void pm_SendKey ( KeySym  keysym  ) 

send button press signal to app on top.

Definition at line 461 of file programManager.c.

00462 {
00463     XKeyEvent xev;
00464     Display *display;
00465     Window  window, root;
00466     int     screen;
00467 
00468     display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
00469     root = gdk_x11_get_default_root_xwindow();
00470     window = pm_getWinOnTop();
00471     if (window == -1)
00472     {
00473         CL_ERRORPRINTF("Failed: no valid window found");
00474         return;
00475     }
00476 
00477     if (window == g_myWin)
00478     {
00479         CL_PMPRINTF("ContentLister window 0x%x", (unsigned int)window);
00480 
00481         display = XOpenDisplay(NULL);
00482         screen = DefaultScreen(display);
00483         root = RootWindow(display, screen);
00484     }
00485 
00486     // create and send a keypress event followed by a keyrelease event 
00487     xev.type = KeyPress;
00488     xev.display = display;
00489     xev.root = root;
00490     xev.window = window;
00491     xev.subwindow = None;
00492     xev.time = pm_fake_timestamp();
00493     xev.x = 1;
00494     xev.y = 1;
00495     xev.x_root = 1;
00496     xev.y_root = 1;
00497     xev.same_screen = 1;
00498     xev.state = 0;
00499     xev.keycode = XKeysymToKeycode(display, keysym);
00500 //    CL_ERRORPRINTF("Sending keypress....");
00501     XSendEvent(xev.display, window, 1, KeyPressMask, (XEvent *) & xev);
00502 
00503     // We check to see if this is the UP key
00504     // so we don't send the release event for that, because it
00505     // can crash the contentLister with a BadWindow error (req.code 25)
00506     if ( keysym == GDK_F5 )
00507     {
00508         CL_ERRORPRINTF("NOT Sending keyrelease for UP key....");
00509     }
00510     else
00511     {
00512 //        usleep(2000); // MvdW: this usleep doesn't seem to be nescessary
00513         xev.type = KeyRelease;
00514         xev.time = pm_fake_timestamp();
00515         XSendEvent(xev.display, window, 1, KeyReleaseMask, (XEvent *) & xev);
00516     }
00517 
00518     //XSync(xev.display, 1);
00519     XSync(xev.display, FALSE);
00520 
00521     if (window == g_myWin)
00522     {
00523         CL_PMPRINTF("Before XCloseDisplay()");
00524         XCloseDisplay(display);
00525     }
00526 }

Here is the call graph for this function:

void pm_setLastStartedUa ( gchar *  uaID  )  [static]

Definition at line 622 of file programManager.c.

00623 {
00624     CL_PMPRINTF("entry: uaID [%s]", uaID);
00625     strncpy(g_lastStartedUa, uaID, UAID_MAX_SIZE);
00626 }

void pm_SetMyWindow ( Window  window  ) 

set my own window ID

Parameters:
window - window of the contentLister application

Definition at line 157 of file programManager.c.

00158 {
00159     g_myWin = window;
00160 }

void pm_setUaOnTop ( gchar *  uaID  ) 

Definition at line 616 of file programManager.c.

00617 {
00618     CL_PMPRINTF("entry: uaID [%s]", uaID);
00619     strncpy(g_uaOnTop, uaID, UAID_MAX_SIZE);
00620 }

static void pm_TerminateUserApp ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 567 of file programManager.c.

00568 {
00569     int i;
00570     pid_t pid;
00571     erApplicationInfo_t *theAppInfo = (erApplicationInfo_t *) value;
00572 
00573     CL_PMPRINTF("entry: xResName [%s]", theAppInfo->userApp->xResName);
00574 
00575     if ((theAppInfo) && (user_data))
00576     {
00577         if (theAppInfo->pid != -1)
00578         {
00579             // stop application
00580             pid = theAppInfo->pid;
00581             CL_WARNPRINTF("Terminate process [%s] pid [%d]", theAppInfo->userApp->xResName, pid);
00582             kill(pid, SIGTERM);
00583             
00584             // wait for application to die
00585             i = 300;
00586             while (kill(pid, 0) == 0  &&  i > 0)
00587             {
00588                 // process still present: wait for application to die
00589                 usleep(100*1000);
00590                 i--;
00591             }
00592 
00593             if (i == 0)
00594             {
00595                 // oops, application is a die-hard: use brute force
00596                 kill(pid, SIGKILL);
00597                 i = 100;
00598                 while (kill(pid, 0) == 0  &&  i > 0)
00599                 {
00600                     // wait for application to die
00601                     usleep(100*1000);
00602                     i--;
00603                 }
00604 
00605                 if (i == 0)
00606                 {
00607                     // application won't die: declare it dead
00608                     theAppInfo->pid = -1;
00609                 }
00610             }
00611         }
00612     }
00613     CL_PMPRINTF("end");
00614 }

static int pm_UpdateState (  )  [static]

Definition at line 938 of file programManager.c.

00939 {
00940     Display *display;
00941     Window  rootWindow;
00942     Atom    net_client_list;
00943     int     nWindows;
00944     Window *windowList;
00945     int     i;
00946     erXClient_t xClient;
00947     
00948     GArray *clientInfo = g_xClientInfo;
00949 
00950     CL_PMPRINTF("entry");
00951 
00952     display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
00953     XSync(display, FALSE);
00954 
00955     net_client_list = XInternAtom(display, "_NET_CLIENT_LIST", False);
00956     rootWindow = gdk_x11_get_default_root_xwindow();
00957     nWindows = pm_GetClientList(display, rootWindow, net_client_list, &windowList);
00958     if (nWindows < 0)
00959     {
00960         CL_ERRORPRINTF("Failed to retrieve the number of clients");
00961         return -1;
00962     }
00963 
00964     // Clear the previously stored window information.
00965     if (clientInfo->len > 0)
00966     {
00967         clientInfo = g_array_remove_range(clientInfo, 0, clientInfo->len);
00968     }
00969 
00970     for (i = 0; i < nWindows; i++)
00971     {
00972         XClassHint classHints;
00973 
00974         CL_PMPRINTF("windowList[%d]: 0x%lx", i, windowList[i]);
00975 
00976         memset(&xClient, 0, sizeof(erXClient_t));
00977 
00978         // Store the window identifier
00979         xClient.win = windowList[i];
00980 
00981         // Fetch and Store the 'resource name'
00982         if (XGetClassHint(display, windowList[i], &classHints))
00983         {
00984             CL_PMPRINTF("Res Name: %s - Res Class: %s.", classHints.res_name, classHints.res_class);
00985             strncpy(xClient.resName, classHints.res_name, WM_NAME_MAX - 1);
00986             XFree(classHints.res_name);
00987             XFree(classHints.res_class);
00988         }
00989         else
00990         {
00991             CL_ERRORPRINTF("Failed to fetch class hint for window 0x%lx", windowList[i]);
00992         }
00993 
00994         // Fetch and Store the Window State
00995         //xClient.winState = pm_CheckWindowState(display, windowList[i]);
00996 
00997         //store the client information
00998         g_array_append_val(clientInfo, xClient);
00999     }
01000 
01001     //pm_DisplayXClientInfo(clientInfo);
01002     
01003     g_xClientInfo = clientInfo;
01004 
01005     // Free the windowList
01006     XFree(windowList);
01007     return nWindows;
01008 }

Here is the call graph for this function:

static void pm_UpdateXClientReference ( gpointer  key,
gpointer  value,
gpointer  user_data 
) [static]

Definition at line 1263 of file programManager.c.

01264 {
01265     int     index;
01266     erXClient_t *client;
01267     erApplicationInfo_t *theApplicationInfo = (erApplicationInfo_t *) value;
01268     GArray *clientInfo = (GArray *) user_data;
01269 
01270     CL_PMPRINTF("entry");
01271 
01272     if ((g_xClientInfo) && (theApplicationInfo))
01273     {
01274         // clear the obsolete client info
01275         theApplicationInfo->xclient = NULL;
01276         CL_PMPRINTF("App %s", theApplicationInfo->uaID);
01277 
01278         for (index = 0; index < g_xClientInfo->len; index++)
01279         {
01280             client = &g_array_index(clientInfo, erXClient_t, index);
01281 
01282             if (strcmp(theApplicationInfo->userApp->xResName, client->resName) == 0)
01283             {
01284                 CL_PMPRINTF("Updating [%s] with resname [%s] to windowid [0x%x]",
01285                             theApplicationInfo->uaID,
01286                             client->resName,
01287                             (unsigned int)client->win);
01288                 theApplicationInfo->xclient = client;
01289                 break;
01290             }
01291         }
01292     }
01293     else
01294     {
01295         CL_ERRORPRINTF("g_xClientInfo or theApplicationInfo is NULL");
01296     }
01297 }

static int pm_XErrorHandler ( Display *  display,
XErrorEvent *  event 
) [static]

Definition at line 145 of file programManager.c.

00146 {
00147     char buf[1000];
00148 
00149     XGetErrorText(display, event->error_code, buf, sizeof(buf));
00150     CL_ERRORPRINTF("X error: %s", buf);
00151 
00152     erbusy_off();
00153 
00154     return 0;  // TODO: what to return here, zero seems to work fine
00155 }

Here is the call graph for this function:

void pt_key_destroy ( gpointer  key  ) 

Definition at line 1204 of file programManager.c.

01205 {
01206     if (key)
01207     {
01208         CL_PMPRINTF("%s", (char*)key);
01209         g_free(key);
01210         key = NULL;
01211     }
01212 }

void pt_value_destroy ( gpointer  value  ) 

Definition at line 1217 of file programManager.c.

01218 {
01219     erApplicationInfo_t *theApplicationInfo = (erApplicationInfo_t*)value;
01220 
01221     if (theApplicationInfo)
01222     {
01223         CL_PMPRINTF("%s", theApplicationInfo->uaID);
01224 
01225         if (theApplicationInfo->userApp)
01226         {
01227             erRegFreeUserApp(theApplicationInfo->userApp);
01228         }
01229 
01230         g_free(theApplicationInfo);
01231         theApplicationInfo = NULL;
01232     }
01233 }

Here is the call graph for this function:

static void signals_init ( void   )  [static]

Definition at line 1321 of file programManager.c.

01322 {
01323     CL_LOGPRINTF("entry");
01324 
01325     int         i;
01326     long        fd_flags;
01327     GIOFlags    io_flags;
01328     GIOChannel* io_channel = NULL;
01329     GError*     error = NULL;
01330 
01331     // create pipe
01332     i = pipe(signal_pipe);
01333     g_assert(i == 0);
01334 
01335     // set write-end of pipe to non-blocking
01336     fd_flags = fcntl(signal_pipe[PIPE_WRITE], F_GETFL);
01337     g_assert(fd_flags != -1);
01338     i = fcntl(signal_pipe[PIPE_WRITE], F_SETFL, fd_flags | O_NONBLOCK);
01339     g_assert(i == 0);
01340 
01341     // convert read-end of pipe into a GIOChannel
01342     io_channel = g_io_channel_unix_new(signal_pipe[PIPE_READ]);
01343 
01344     // we only read raw binary data from the pipe, therefore clear any encoding on the channel
01345     g_io_channel_set_encoding(io_channel, NULL, &error);
01346     g_assert(error == NULL);
01347 
01348     // set the reading end also to non-blocking mode
01349     io_flags = g_io_channel_get_flags(io_channel);
01350     g_io_channel_set_flags(io_channel, io_flags | G_IO_FLAG_NONBLOCK, &error);
01351     g_assert(error == NULL);
01352 
01353     // register the reading end with the event loop
01354     g_io_add_watch(io_channel, G_IO_IN | G_IO_PRI, on_signal_gtk, NULL);
01355 
01356     // catch the unix SIGCHLD signal
01357     struct sigaction on_chld;
01358     memset(&on_chld, 0x00, sizeof(on_chld));
01359     on_chld.sa_handler = on_signal;
01360     on_chld.sa_flags   = SA_NOCLDSTOP;
01361     sigaction(SIGCHLD, &on_chld, NULL);
01362 }

Here is the call graph for this function:


Variable Documentation

GHashTable* g_extensionInfo = NULL [static]

Definition at line 77 of file programManager.c.

gchar g_lastStartedUa[UAID_MAX_SIZE] [static]

Definition at line 79 of file programManager.c.

Window g_myWin [static]

Definition at line 75 of file programManager.c.

GHashTable* g_programInfo = NULL [static]

Definition at line 76 of file programManager.c.

gchar g_uaOnTop[UAID_MAX_SIZE] [static]

Definition at line 78 of file programManager.c.

GArray* g_xClientInfo = NULL [static]

Definition at line 74 of file programManager.c.

int signal_pipe[2] [static]

Definition at line 1311 of file programManager.c.


Generated on Sun Dec 14 17:13:41 2008 by  doxygen 1.5.6