#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] |
<File description>="">
Manages the programs running on the eReader spawns processes and sends keys
Definition in file programManager.c.
#define PIPE_READ 0 |
Definition at line 1308 of file programManager.c.
#define PIPE_WRITE 1 |
Definition at line 1309 of file programManager.c.
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 }
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 }
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 }
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
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 }
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 }
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 }
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 }
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 }
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 }
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_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
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 }
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 }
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 }
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 }
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.