contentLister/inc/programManager.h File Reference

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#include "liberipc/eripc.h"
#include <liberregxml/erregapi.h>

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  erExtInfo_t
struct  erXClient_t
struct  erApplicationInfo_t

Defines

#define WM_NAME_MAX   256
#define PM_DOWNLOADMGR_LOCATION   "/usr/bin/downloadMgr"
#define XCLIENT_ARRAY_RESERVED_SIZE   32
#define CONTENTLISTER_UAID   "CONTENTLISTER"
#define CONTENTLISTER_RESNAME   "contentLister"
#define WINDOWMANAGER_NAME_MAX   256
#define UAID_MAX_SIZE   256
#define COMMAND_MAX_SIZE   1024
#define ERR_OK   ( 0)
#define ERR_STATE_UPDATE   (-1)
#define ERR_ARGUMENT   (-2)
#define ERR_FORK   (-3)
#define ERR_INVALID_UAID   (-4)
#define ERR_VIEWER_RUNNING   (-5)

Functions

gboolean pm_InitProgramManager (void)
void pm_SetMyWindow (Window window)
void pm_DestroyProgramManager (void)
gboolean pm_RaiseContentLister ()
gboolean pm_RaiseUserApp (gchar *uaId)
gboolean pm_IsActive (gchar *uaId)
char * pm_getUaOnTop (void)
void pm_setUaOnTop (char *uaID)
void pm_SendKey (KeySym keysym)
int pm_RunViewer (gchar *uaId, char *filename, char *manifest, char *options, int reuse)
char * pm_getUaID (char *extension)
char * pm_getIcon (char *extension)


Define Documentation

#define COMMAND_MAX_SIZE   1024

Definition at line 54 of file programManager.h.

#define CONTENTLISTER_RESNAME   "contentLister"

Definition at line 51 of file programManager.h.

#define CONTENTLISTER_UAID   "CONTENTLISTER"

Definition at line 50 of file programManager.h.

#define ERR_ARGUMENT   (-2)

Definition at line 58 of file programManager.h.

#define ERR_FORK   (-3)

Definition at line 59 of file programManager.h.

#define ERR_INVALID_UAID   (-4)

Definition at line 60 of file programManager.h.

#define ERR_OK   ( 0)

Definition at line 56 of file programManager.h.

#define ERR_STATE_UPDATE   (-1)

Definition at line 57 of file programManager.h.

#define ERR_VIEWER_RUNNING   (-5)

Definition at line 61 of file programManager.h.

#define PM_DOWNLOADMGR_LOCATION   "/usr/bin/downloadMgr"

Definition at line 47 of file programManager.h.

#define UAID_MAX_SIZE   256

Definition at line 53 of file programManager.h.

#define WINDOWMANAGER_NAME_MAX   256

Definition at line 52 of file programManager.h.

#define WM_NAME_MAX   256

Definition at line 45 of file programManager.h.

#define XCLIENT_ARRAY_RESERVED_SIZE   32

Definition at line 49 of file programManager.h.


Function Documentation

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 }

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 }

char* 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 }

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:

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:

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_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 ( char *  uaID  ) 

Sets the uaID of the user application that has just been started, and therefore is on top of the window stack now.

Parameters:
uaID - user application identifier as specified in the registry


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