#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>
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 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.
void pm_DestroyProgramManager | ( | void | ) |
Destroy the global data used by the program manager module
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
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 }
gboolean pm_IsActive | ( | gchar * | uaId | ) |
Checks whether a specified viewer is already 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 }
gboolean pm_RaiseContentLister | ( | ) |
Raise the contentlister application
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 }
gboolean pm_RaiseUserApp | ( | gchar * | uaId | ) |
Raise the specified used application
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 }
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
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 |
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 }
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 }
void pm_SetMyWindow | ( | Window | window | ) |
set my own window ID
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.
uaID | - user application identifier as specified in the registry |