#include <glib.h>
#include <hal/libhal.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include "log.h"
#include "busy.h"
#include "devicelist.h"
#include "hal.h"
#include "ipc.h"
#include "process.h"
#include "system.h"
#include "tasks.h"
#include "xwindow.h"
Go to the source code of this file.
Data Structures | |
struct | task_t |
struct | request_t |
Defines | |
#define | FOLDER_XID -1 |
Functions | |
static gboolean | child_new (const char *command, const char *working_dir, const char *application, const char *document, const char *label, const char *image, eripc_context_t *context, const char *message_id) |
static gboolean | child_activate (task_t *task) |
static gboolean | child_close (task_t *task) |
static gboolean | child_window_open (task_t *task, request_t *request) |
static gboolean | child_window_close (task_t *task, request_t *request) |
static void | on_window_open_callback (eripc_context_t *context, const eripc_event_info_t *info, request_t *request) |
static void | on_window_close_callback (eripc_context_t *context, const eripc_event_info_t *info, request_t *request) |
static gboolean | on_check_child_window (gpointer data) |
static gboolean | on_child_new_timeout (gpointer data) |
static gboolean | on_child_term_timeout (gpointer data) |
static task_t * | tasklist_add (proc_t *proc, const char *application, const char *document, const char *label, const char *image, Window window) |
static gboolean | tasklist_set_first (task_t *task) |
static gboolean | tasklist_remove_pid (GPid pid) |
static gboolean | tasklist_remove_window (Window window) |
static task_t * | find_valid_task (task_t *task) |
static void | free_task (task_t *task) |
static task_t * | get_task (const char *application, const char *document) |
static task_t * | get_task_by_xid (Window xid) |
static gboolean | parse_commandline (const gchar *command_line, gchar **application, gchar **document, gchar **arguments) |
static request_t * | new_request (task_t *task, eripc_context_t *context, const char *message_id) |
static void | free_request (request_t *request) |
gboolean | task_start (const char *command_line, const char *working_dir, const char *label, const char *image, eripc_context_t *context, const char *message_id) |
Start a task. | |
gboolean | task_stop (const char *command_line, eripc_context_t *context, const char *message_id) |
Stop a running task. | |
gboolean | task_rename (int xid, const char *new_document, const char *new_label) |
void | task_activate_by_xid (int xid) |
gboolean | task_activate (const char *command_line) |
Activate a running task. | |
void | print_task_list () |
const gchar * | task_service_by_window (Window xid) |
Get service of task with given window. | |
gboolean | task_add (const char *application, const char *document, const char *label, const char *image, const char *ipc_service, gint pid, Window xid) |
Add a task which is already running. | |
gboolean | task_cleanup_pid (GPid pid) |
Cleanup tasks for process. | |
gboolean | task_cleanup_window (Window xid) |
Cleanup tasks for window. | |
gboolean | task_startup_completed (proc_t *proc, Window window) |
Call when a task has finished starting. | |
char * | testing_task_get_list () |
static void | check_num_tasks () |
Variables | |
static const gint | TIMEOUT_CHILD_NEW = 30 |
static const gint | TIMEOUT_CHILD_CLOSE = 5 |
static const gint | TIMEOUT_CHECK_RESTART_UDS = 5 |
static const gint | TIMER_CHECK_WINDOW_MS = 500 |
static const guint | MAX_TASKS = 4 |
static GSList * | g_tasklist = NULL |
static gboolean | g_forced_close = FALSE |
static gint | g_child_terminate_source = 0 |
static gint | g_check_child_window_source = 0 |
static gint | g_task_pending_source = 0 |
#define FOLDER_XID -1 |
Definition at line 91 of file tasks.c.
Referenced by task_activate_by_xid(), and taskbar_select_folder().
static void check_num_tasks | ( | ) | [static] |
Definition at line 718 of file tasks.c.
References child_close(), child_window_close(), g_forced_close, g_tasklist, proc_t::ipc_service, proc_t::is_multidoc, LOGPRINTF, MAX_TASKS, new_request(), and task_t::proc.
Referenced by on_check_child_window(), and on_window_open_callback().
00719 { 00720 if (g_slist_length(g_tasklist) > MAX_TASKS) 00721 { 00722 LOGPRINTF("maximum number of tasks reached, remove oldest"); 00723 00724 // get last task in list 00725 GSList *list_last_task = g_slist_last(g_tasklist); 00726 task_t *last_task = list_last_task->data; 00727 00728 g_forced_close = TRUE; 00729 00730 // close last task 00731 if (last_task->proc && last_task->proc->ipc_service 00732 && last_task->proc->is_multidoc) 00733 { 00734 request_t *request = new_request(last_task, NULL, NULL); 00735 child_window_close(last_task, request); 00736 } 00737 else 00738 { 00739 child_close(last_task); 00740 } 00741 } 00742 }
static gboolean child_activate | ( | task_t * | task | ) | [static] |
Definition at line 646 of file tasks.c.
References LOGPRINTF, tasklist_set_first(), task_t::window, and window_activate().
Referenced by on_window_open_callback(), task_activate(), task_activate_by_xid(), and task_start().
00647 { 00648 LOGPRINTF("entry"); 00649 00650 // set task to head of list 00651 tasklist_set_first(task); 00652 00653 // activate X11 window 00654 window_activate(task->window); 00655 00656 return TRUE; 00657 }
static gboolean child_close | ( | task_t * | task | ) | [static] |
Definition at line 660 of file tasks.c.
References g_child_terminate_source, LOGPRINTF, on_child_term_timeout(), proc_t::pid, task_t::proc, and TIMEOUT_CHILD_CLOSE.
Referenced by check_num_tasks(), and task_stop().
00661 { 00662 LOGPRINTF("entry"); 00663 00664 if (task->proc) 00665 { 00666 // terminate child 00667 kill(task->proc->pid, SIGTERM); 00668 } 00669 00670 // set maximum time to wait for child termination 00671 g_child_terminate_source = g_timeout_add_seconds(TIMEOUT_CHILD_CLOSE, on_child_term_timeout, task); 00672 00673 return TRUE; 00674 }
static gboolean child_new | ( | const char * | command, | |
const char * | working_dir, | |||
const char * | application, | |||
const char * | document, | |||
const char * | label, | |||
const char * | image, | |||
eripc_context_t * | context, | |||
const char * | message_id | |||
) | [static] |
Definition at line 526 of file tasks.c.
References busy_add_foreground(), BUSY_DIALOG_DELAYED, ERRORPRINTF, g_check_child_window_source, g_task_pending_source, LOGPRINTF, new_request(), on_check_child_window(), on_child_new_timeout(), process_start(), PS_WAIT_STARTED, tasklist_add(), TIMEOUT_CHILD_NEW, and TIMER_CHECK_WINDOW_MS.
Referenced by task_start().
00534 { 00535 LOGPRINTF("entry"); 00536 00537 gboolean retval = FALSE; 00538 00539 if ( g_check_child_window_source == 0 00540 && g_task_pending_source == 0 ) 00541 { 00542 00543 if (working_dir && working_dir[0]=='\0') 00544 { 00545 working_dir = NULL; 00546 } 00547 00548 proc_t *proc = process_start(command, working_dir, NULL, NULL, PS_WAIT_STARTED); 00549 if (proc != NULL) 00550 { 00551 task_t *task = tasklist_add(proc, application, document, label, image, 0); 00552 request_t *request = new_request(task, context, message_id); 00553 00554 // show busy indication 00555 busy_add_foreground(0, BUSY_DIALOG_DELAYED, NULL); 00556 00557 LOGPRINTF("pending task adding, wait for window id"); 00558 00559 // periodically check window list 00560 g_check_child_window_source = g_timeout_add(TIMER_CHECK_WINDOW_MS, on_check_child_window, request); 00561 00562 // set maximum time to wait for new window 00563 g_task_pending_source = g_timeout_add_seconds(TIMEOUT_CHILD_NEW, on_child_new_timeout, request); 00564 00565 retval = TRUE; 00566 } 00567 else 00568 { 00569 LOGPRINTF("error starting, return failure"); 00570 // return FAILED immediately 00571 } 00572 } 00573 else 00574 { 00575 ERRORPRINTF("still waiting for another task to be started, refusing task [%s]", label); 00576 } 00577 00578 return retval; 00579 }
Definition at line 629 of file tasks.c.
References task_t::document, ipc_send_close(), proc_t::ipc_service, LOGPRINTF, on_window_close_callback(), and task_t::proc.
Referenced by check_num_tasks(), and task_stop().
00631 { 00632 LOGPRINTF("entry"); 00633 00634 gboolean retval = FALSE; 00635 00636 if (task->proc && task->proc->ipc_service) 00637 { 00638 LOGPRINTF("wait for on_window_close_callback"); 00639 retval = ipc_send_close(task->proc->ipc_service, task->document, on_window_close_callback, request); 00640 } 00641 00642 return retval; 00643 }
Definition at line 582 of file tasks.c.
References task_t::document, ipc_send_open(), proc_t::ipc_service, LOGPRINTF, on_window_open_callback(), and task_t::proc.
Referenced by task_start().
00584 { 00585 LOGPRINTF("entry"); 00586 00587 gboolean retval = FALSE; 00588 00589 if (task->proc && task->proc->ipc_service) 00590 { 00591 LOGPRINTF("pending task added, wait for on_window_open_callback"); 00592 retval = ipc_send_open(task->proc->ipc_service, task->document, on_window_open_callback, request); 00593 } 00594 00595 return retval; 00596 }
Definition at line 1185 of file tasks.c.
References g_tasklist.
Referenced by on_check_child_window(), on_child_new_timeout(), on_window_close_callback(), and on_window_open_callback().
01186 { 01187 if (task == NULL) return NULL; 01188 01189 task_t *task_data = NULL; 01190 GSList *cur_task = g_tasklist; 01191 01192 while ( (cur_task != NULL) && (cur_task->data != NULL) ) 01193 { 01194 task_data = cur_task->data; 01195 if (task_data == task) 01196 { 01197 return task_data; 01198 } 01199 cur_task = cur_task->next; 01200 } 01201 01202 return NULL; 01203 }
static void free_request | ( | request_t * | request | ) | [static] |
Definition at line 619 of file tasks.c.
References LOGPRINTF, and request_t::message_id.
Referenced by on_check_child_window(), on_child_new_timeout(), on_window_close_callback(), and on_window_open_callback().
00620 { 00621 LOGPRINTF("entry"); 00622 00623 g_free(request->message_id); 00624 g_free(request); 00625 request = NULL; 00626 }
static void free_task | ( | task_t * | task | ) | [static] |
Definition at line 1048 of file tasks.c.
References task_t::application, task_t::document, task_t::image, and task_t::label.
Referenced by tasklist_remove_pid(), and tasklist_remove_window().
01049 { 01050 g_free(task->application); 01051 g_free(task->document); 01052 g_free(task->label); 01053 g_free(task->image); 01054 g_free(task); 01055 task = NULL; 01056 }
static task_t * get_task | ( | const char * | application, | |
const char * | document | |||
) | [static] |
Definition at line 1221 of file tasks.c.
References task_t::application, task_t::document, g_tasklist, and LOGPRINTF.
Referenced by task_activate(), task_add(), task_start(), and task_stop().
01222 { 01223 LOGPRINTF("entry"); 01224 01225 GSList *task_ptr = g_tasklist; 01226 gchar *baseapp = g_path_get_basename(application); 01227 01228 while (task_ptr) 01229 { 01230 task_t *cur_task = (task_t *) task_ptr->data; 01231 01232 if (baseapp && cur_task->application && (strcmp(cur_task->application, baseapp) == 0) && 01233 ((document == NULL) || (cur_task->document && (strcmp(cur_task->document, document) == 0)))) 01234 { 01235 g_free(baseapp); 01236 return cur_task; 01237 } 01238 task_ptr = task_ptr->next; 01239 } 01240 01241 g_free(baseapp); 01242 return NULL; 01243 }
static task_t * get_task_by_xid | ( | Window | xid | ) | [static] |
Definition at line 1206 of file tasks.c.
References g_tasklist, and task_t::window.
Referenced by task_activate_by_xid(), task_rename(), and task_service_by_window().
01207 { 01208 GSList *task_ptr = g_tasklist; 01209 01210 while (task_ptr) 01211 { 01212 task_t *cur_task = (task_t *) task_ptr->data; 01213 01214 if (cur_task->window == xid) return cur_task; 01215 task_ptr = task_ptr->next; 01216 } 01217 return NULL; 01218 }
static request_t * new_request | ( | task_t * | task, | |
eripc_context_t * | context, | |||
const char * | message_id | |||
) | [static] |
Definition at line 599 of file tasks.c.
References request_t::context, ERRORPRINTF, LOGPRINTF, request_t::message_id, and request_t::task.
Referenced by check_num_tasks(), child_new(), task_start(), and task_stop().
00602 { 00603 LOGPRINTF("entry"); 00604 00605 request_t *request = g_new0(request_t, 1); 00606 if (!request) 00607 { 00608 ERRORPRINTF("mem alloc failed"); 00609 return FALSE; 00610 } 00611 request->task = task; 00612 request->context = context; 00613 request->message_id = g_strdup(message_id); 00614 00615 return request; 00616 }
static gboolean on_check_child_window | ( | gpointer | data | ) | [static] |
Definition at line 745 of file tasks.c.
References task_t::application, busy_remove_foreground(), check_num_tasks(), request_t::context, find_valid_task(), free_request(), g_check_child_window_source, g_task_pending_source, get_application_window(), ipc_send_reply_task_start(), LOGPRINTF, request_t::message_id, request_t::task, WARNPRINTF, and task_t::window.
Referenced by child_new().
00746 { 00747 LOGPRINTF("entry"); 00748 00749 request_t *request = data; 00750 00751 if (request != NULL) 00752 { 00753 task_t *task = find_valid_task(request->task); 00754 if (task != NULL) 00755 { 00756 LOGPRINTF("looking for %s", task->application); 00757 00758 Window child_window = get_application_window(task->application); 00759 if (child_window == 0) 00760 { 00761 // do nothing (wait for next call) 00762 return TRUE; 00763 } 00764 else 00765 { 00766 check_num_tasks(); 00767 00768 // add window id to task info 00769 if (task->window == 0) { 00770 task->window = child_window; 00771 } 00772 00773 if (request->context && request->message_id) 00774 { 00775 // return success to caller 00776 ipc_send_reply_task_start(request->context, request->message_id, 0, NULL); 00777 } 00778 free_request(request); 00779 } 00780 } 00781 else 00782 { 00783 WARNPRINTF("task not found"); 00784 00785 if (request->context && request->message_id) 00786 { 00787 // return failed to caller 00788 ipc_send_reply_task_start(request->context, request->message_id, 3, NULL); 00789 } 00790 free_request(request); 00791 } 00792 } 00793 else 00794 { 00795 WARNPRINTF("request not found"); 00796 } 00797 00798 // stop and destroy timer 00799 g_check_child_window_source = 0; 00800 00801 // stop pending timeout 00802 if (g_task_pending_source) 00803 { 00804 g_source_remove(g_task_pending_source); 00805 g_task_pending_source = 0; 00806 } 00807 00808 // remove busy indication 00809 busy_remove_foreground(0); 00810 00811 return FALSE; 00812 }
static gboolean on_child_new_timeout | ( | gpointer | data | ) | [static] |
Definition at line 677 of file tasks.c.
References busy_remove_foreground(), request_t::context, find_valid_task(), free_request(), g_check_child_window_source, g_task_pending_source, ipc_send_reply_task_start(), LOGPRINTF, request_t::message_id, proc_t::pid, task_t::proc, request_t::task, and tasklist_remove_pid().
Referenced by child_new().
00678 { 00679 LOGPRINTF("entry"); 00680 00681 request_t *request = data; 00682 00683 g_return_val_if_fail(request != NULL, FALSE); 00684 00685 if (g_check_child_window_source) 00686 { 00687 g_source_remove(g_check_child_window_source); 00688 g_check_child_window_source = 0; 00689 } 00690 00691 if (g_task_pending_source) 00692 { 00693 g_source_remove(g_task_pending_source); 00694 g_task_pending_source = 0; 00695 } 00696 00697 task_t *task = find_valid_task(request->task); 00698 if (task != NULL) 00699 { 00700 tasklist_remove_pid(request->task->proc->pid); 00701 } 00702 00703 // return result to caller 00704 if (request->context && request->message_id) 00705 { 00706 ipc_send_reply_task_start(request->context, request->message_id, 2, NULL); 00707 } 00708 free_request(request); 00709 00710 // remove busy indication 00711 busy_remove_foreground(0); 00712 00713 // stop and destroy this timer 00714 return FALSE; 00715 }
static gboolean on_child_term_timeout | ( | gpointer | data | ) | [static] |
Definition at line 1001 of file tasks.c.
References g_child_terminate_source, LOGPRINTF, proc_t::pid, and task_t::proc.
Referenced by child_close().
01002 { 01003 LOGPRINTF("entry"); 01004 01005 task_t *task = data; 01006 01007 if (task->proc && (task->proc->pid > 0)) 01008 { 01009 // termination timed out, now do it the really hard way 01010 kill(task->proc->pid, SIGKILL); 01011 } 01012 01013 // reset terminated handler 01014 g_child_terminate_source = 0; 01015 01016 // stop and destroy timer 01017 return FALSE; 01018 }
static void on_window_close_callback | ( | eripc_context_t * | context, | |
const eripc_event_info_t * | info, | |||
request_t * | request | |||
) | [static] |
Definition at line 948 of file tasks.c.
References eripc_event_info_t::args, eripc_arg_t::b, request_t::context, ERIPC_EVENT_REPLY, ERIPC_TYPE_BOOL, eripc_event_info_t::event_type, find_valid_task(), free_request(), ipc_send_reply(), LOGPRINTF, request_t::message_id, request_t::task, tasklist_remove_window(), WARNPRINTF, and task_t::window.
Referenced by child_window_close().
00951 { 00952 LOGPRINTF("entry request [%p]", request); 00953 00954 gboolean retval = FALSE; 00955 const eripc_arg_t *arg_array = info->args; 00956 00957 if (request == NULL) 00958 { 00959 WARNPRINTF("request is null"); 00960 } 00961 if (find_valid_task(request->task) == NULL) 00962 { 00963 WARNPRINTF("task not found [%p]", request->task); 00964 } 00965 else if (info->event_type != ERIPC_EVENT_REPLY) 00966 { 00967 WARNPRINTF("invalid event: %d", info->event_type); 00968 } 00969 else if ((arg_array == NULL) || (arg_array[0].type != ERIPC_TYPE_BOOL)) 00970 { 00971 WARNPRINTF("invalid arguments in reply"); 00972 } 00973 else if (arg_array[0].value.b == FALSE) 00974 { 00975 LOGPRINTF("child returned failure"); 00976 } 00977 else 00978 { 00979 // TODO 00980 // - check if window is really closed 00981 00982 // remove task with this window from list 00983 tasklist_remove_window(request->task->window); 00984 retval = TRUE; 00985 } 00986 00987 if (request != NULL) 00988 { 00989 if (request->message_id != NULL) 00990 { 00991 // return result to caller 00992 LOGPRINTF("return result to caller [%d], message_id [%s]", retval, request->message_id); 00993 ipc_send_reply(request->context, request->message_id, retval); 00994 } 00995 free_request(request); 00996 } 00997 }
static void on_window_open_callback | ( | eripc_context_t * | context, | |
const eripc_event_info_t * | info, | |||
request_t * | request | |||
) | [static] |
Definition at line 815 of file tasks.c.
References task_t::application, eripc_event_info_t::args, check_num_tasks(), child_activate(), request_t::context, task_t::document, ERIPC_EVENT_REPLY, ERIPC_TYPE_INT, ERIPC_TYPE_STRING, eripc_event_info_t::event_type, find_valid_task(), free_request(), g_tasklist, eripc_arg_t::i, ipc_menu_add_task(), ipc_send_reply_task_start(), task_t::label, LOGPRINTF, request_t::message_id, eripc_arg_t::s, request_t::task, tasklist_remove_window(), eripc_arg_t::value, WARNPRINTF, task_t::window, and window_activate().
Referenced by child_window_open().
00818 { 00819 LOGPRINTF("entry request [%p]", request); 00820 00821 gboolean retval = FALSE; 00822 gchar *errmsg = NULL; 00823 const eripc_arg_t *arg_array = info->args; 00824 00825 g_return_if_fail(request != NULL); 00826 00827 if (info->event_type != ERIPC_EVENT_REPLY) 00828 { 00829 WARNPRINTF("invalid event: %d", info->event_type); 00830 } 00831 else if ((arg_array == NULL) || (arg_array[0].type != ERIPC_TYPE_INT)) 00832 { 00833 WARNPRINTF("invalid arguments in reply, task not added"); 00834 } 00835 else if (arg_array[0].value.i < 0) 00836 { 00837 LOGPRINTF("child returned failure, task not added"); 00838 00839 if (arg_array[1].type == ERIPC_TYPE_STRING) 00840 { 00841 LOGPRINTF("error message: %s", arg_array[1].value.s); 00842 errmsg = g_strdup(arg_array[1].value.s); 00843 } 00844 00845 task_t *new_task = find_valid_task(request->task); 00846 if (new_task) 00847 { 00848 tasklist_remove_window(new_task->window); 00849 } 00850 } 00851 else 00852 { 00853 task_t *old_task = NULL; 00854 task_t *task_data = NULL; 00855 GSList *task = g_tasklist; 00856 00857 Window child_window = arg_array[0].value.i; 00858 00859 // TODO 00860 // - add check if window exists in windowlist 00861 00862 LOGPRINTF("task started in window: %d", (int) child_window); 00863 00864 // check if window is already in tasklist 00865 // 00866 while ( (task != NULL) && (task->data != NULL) ) 00867 { 00868 task_data = task->data; 00869 00870 LOGPRINTF("check %s, %s; window %d", task_data->application, task_data->document, (int) task_data->window); 00871 00872 if (task_data->window == child_window) 00873 { 00874 // task with this window found 00875 old_task = task_data; 00876 break; 00877 } 00878 00879 task = task->next; 00880 } 00881 00882 task_t *new_task = find_valid_task(request->task); 00883 if (new_task && (child_window > 0)) 00884 { 00885 LOGPRINTF("task %s, %s; window %d", new_task->application, new_task->document, (int) child_window); 00886 00887 if (old_task == new_task) 00888 { 00889 // task is already in task manager, activate it 00890 child_activate(old_task); 00891 } 00892 else 00893 { 00894 if (old_task) 00895 { 00896 // new task will replace old task 00897 LOGPRINTF("remove old task %s, %s: window %d", old_task->application, old_task->document, (int) old_task->window); 00898 tasklist_remove_window(old_task->window); 00899 } 00900 else 00901 { 00902 // task is new, check current number of tasks 00903 check_num_tasks(); 00904 } 00905 00906 // add to task manager 00907 ipc_menu_add_task(child_window, new_task->label); 00908 00909 // save new window 00910 new_task->window = child_window; 00911 00912 if (old_task) 00913 { 00914 // activate existing window 00915 LOGPRINTF("reactivate existing window"); 00916 window_activate(child_window); 00917 } 00918 } 00919 } 00920 00921 // set success 00922 retval = TRUE; 00923 } 00924 00925 if (request != NULL) 00926 { 00927 if (request->message_id != NULL) 00928 { 00929 // return result to caller 00930 if (retval == TRUE) 00931 { 00932 LOGPRINTF("return result to caller [%d], message_id [%s]", 0, request->message_id); 00933 ipc_send_reply_task_start(request->context, request->message_id, 0, NULL); 00934 } 00935 else 00936 { 00937 LOGPRINTF("return result to caller [%d], message_id [%s]", 4, request->message_id); 00938 ipc_send_reply_task_start(request->context, request->message_id, 4, errmsg); 00939 } 00940 } 00941 free_request(request); 00942 } 00943 00944 g_free(errmsg); 00945 }
gboolean parse_commandline | ( | const gchar * | command_line, | |
gchar ** | application, | |||
gchar ** | document, | |||
gchar ** | arguments | |||
) | [static] |
Definition at line 1246 of file tasks.c.
References LOGPRINTF, and WARNPRINTF.
Referenced by task_activate(), task_start(), and task_stop().
01247 { 01248 char **argv_ptr = NULL; 01249 GError *error = NULL; 01250 gchar *app = NULL; 01251 gchar *doc = NULL; 01252 gchar *arg = NULL; 01253 gint argc = 0; 01254 01255 LOGPRINTF("enter"); 01256 01257 g_shell_parse_argv(command_line, &argc, &argv_ptr, &error); 01258 if (error) 01259 { 01260 WARNPRINTF("Execution of '%s' failed with error: %s", command_line, error->message); 01261 g_error_free(error); 01262 return FALSE; 01263 } 01264 01265 // split command line 01266 // 01267 app = g_path_get_basename(argv_ptr[0]); 01268 01269 if (argc > 1) 01270 { 01271 doc = g_strdup(argv_ptr[argc-1]); 01272 01273 // join all arguments except application 01274 arg = g_strjoinv(" ", &argv_ptr[1]); 01275 } 01276 01277 // return arguments 01278 // 01279 if (application != NULL) 01280 { 01281 LOGPRINTF("app `%s`", app); 01282 *application = app; 01283 } 01284 else 01285 { 01286 g_free(app); 01287 } 01288 01289 if (document != NULL) 01290 { 01291 LOGPRINTF("doc `%s`", doc); 01292 *document = doc; 01293 } 01294 else 01295 { 01296 g_free(doc); 01297 } 01298 01299 if (arguments != NULL) 01300 { 01301 LOGPRINTF("arg `%s`", arg); 01302 *arguments = arg; 01303 } 01304 else 01305 { 01306 g_free(arg); 01307 } 01308 01309 g_strfreev(argv_ptr); 01310 01311 return TRUE; 01312 }
void print_task_list | ( | ) |
Definition at line 363 of file tasks.c.
References task_t::application, task_t::document, g_tasklist, proc_t::pid, task_t::proc, and task_t::window.
Referenced by testing_list_tasks().
00364 { 00365 GSList *task_ptr = g_tasklist; 00366 00367 int i = 0; 00368 printf("%s() TASKS\n", __func__); 00369 while (task_ptr) 00370 { 00371 task_t *task = (task_t *) task_ptr->data; 00372 int pid = (task->proc) ? task->proc->pid : 0; 00373 printf(" [%d] proc_pid=%d window=%d app=%s doc=%s\n", i, pid, 00374 (guint)task->window, task->application, task->document); 00375 00376 task_ptr = task_ptr->next; 00377 i++; 00378 } 00379 }
gboolean task_activate | ( | const char * | command_line | ) |
Activate a running task.
---------------------------------------------------------------------------
Name : task_activate
command_line | Full command line of task, quoted as g_shell_quote |
--------------------------------------------------------------------------
Definition at line 331 of file tasks.c.
References child_activate(), get_task(), LOGPRINTF, parse_commandline(), WARNPRINTF, and task_t::window.
Referenced by cb_menu_item_activated(), and cb_status_item_activated().
00332 { 00333 LOGPRINTF("entry: `%s`", command_line); 00334 00335 gboolean retval = FALSE; 00336 gchar *application = NULL; 00337 gchar *document = NULL; 00338 00339 parse_commandline(command_line, &application, &document, NULL); 00340 00341 task_t *task = get_task(application, document); 00342 if (task) 00343 { 00344 LOGPRINTF("found task, activate window %d", (gint) task->window); 00345 retval = child_activate(task); 00346 } 00347 else 00348 { 00349 WARNPRINTF("task not found cmdline='%s'", command_line); 00350 } 00351 00352 // free allocated memory 00353 g_free(application); 00354 g_free(document); 00355 00356 LOGPRINTF("leave: retval %d", retval); 00357 00358 return retval; 00359 }
void task_activate_by_xid | ( | int | xid | ) |
Definition at line 310 of file tasks.c.
References child_activate(), FOLDER_XID, get_task_by_xid(), LOGPRINTF, process_activate_ctb(), WARNPRINTF, and task_t::window.
Referenced by cb_task_activate().
00311 { 00312 LOGPRINTF("entry xid=%d", xid); 00313 if (xid == FOLDER_XID) 00314 { 00315 process_activate_ctb(); 00316 return; 00317 } 00318 task_t *task = get_task_by_xid(xid); 00319 if (task) 00320 { 00321 LOGPRINTF("found task, activate window %d", (gint) task->window); 00322 child_activate(task); 00323 } 00324 else 00325 { 00326 WARNPRINTF("task not found, xid=%d", xid); 00327 } 00328 }
gboolean task_add | ( | const char * | application, | |
const char * | document, | |||
const char * | label, | |||
const char * | image, | |||
const char * | ipc_service, | |||
gint | pid, | |||
Window | xid | |||
) |
Add a task which is already running.
---------------------------------------------------------------------------
Name : task_add
application | Basename of the application | |
document | Full path of the document | |
label | Text label shown under icon in popup menu | |
image | Full path to icon shown in popup menu | |
ipc_service | IPC service name of the application | |
pid | Process ID | |
xid | Window ID |
--------------------------------------------------------------------------
Definition at line 396 of file tasks.c.
References get_task(), LOGPRINTF, process_get_by_pid(), and tasklist_add().
Referenced by cb_opened_window().
00403 { 00404 LOGPRINTF("entry"); 00405 00406 gboolean retval = FALSE; 00407 00408 task_t *task = get_task(application, document); 00409 proc_t *proc = process_get_by_pid(pid); 00410 if (proc && !task) 00411 { 00412 LOGPRINTF("task %s, %s, not found, add it...", application, document); 00413 task = tasklist_add(proc, application, document, label, image, xid); 00414 if (task) 00415 { 00416 retval = TRUE; 00417 } 00418 } 00419 00420 return retval; 00421 }
gboolean task_cleanup_pid | ( | GPid | pid | ) |
Cleanup tasks for process.
---------------------------------------------------------------------------
Name : task_cleanup_pid
pid | Process that has exited |
--------------------------------------------------------------------------
Definition at line 424 of file tasks.c.
References g_forced_close, LOGPRINTF, process_activate_ctb(), and tasklist_remove_pid().
Referenced by on_process_exit().
00425 { 00426 LOGPRINTF("entry: forced %d", g_forced_close); 00427 00428 gboolean result = tasklist_remove_pid(pid); 00429 00430 if (result && !g_forced_close) 00431 { 00432 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW 00433 // automatically return to application that was on top in the stack 00434 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW 00435 // return to folder in content browser 00436 process_activate_ctb(); 00437 #endif 00438 } 00439 00440 g_forced_close = FALSE; 00441 00442 return result; 00443 }
gboolean task_cleanup_window | ( | Window | xid | ) |
Cleanup tasks for window.
---------------------------------------------------------------------------
Name : task_cleanup_window
xid | Window that was closed |
--------------------------------------------------------------------------
Definition at line 446 of file tasks.c.
References g_forced_close, LOGPRINTF, process_activate_ctb(), and tasklist_remove_window().
Referenced by cb_closed_window().
00447 { 00448 LOGPRINTF("entry: xid %d, forced %d", (int) xid, g_forced_close); 00449 00450 gboolean result = tasklist_remove_window(xid); 00451 00452 if (result && !g_forced_close) 00453 { 00454 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW 00455 // automatically return to application that was on top in the stack 00456 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW 00457 // return to folder in content browser 00458 process_activate_ctb(); 00459 #endif 00460 } 00461 00462 g_forced_close = FALSE; 00463 00464 return result; 00465 }
gboolean task_rename | ( | int | xid, | |
const char * | new_document, | |||
const char * | new_label | |||
) |
Definition at line 293 of file tasks.c.
References task_t::document, ERRORPRINTF, get_task_by_xid(), ipc_menu_rename_task(), task_t::label, and LOGPRINTF.
Referenced by cb_task_rename().
00294 { 00295 LOGPRINTF("[%d] %s '%s'", xid, new_document, new_label); 00296 task_t *task = get_task_by_xid(xid); 00297 if (task == NULL) { 00298 ERRORPRINTF("unknown task: xid=%d", xid); 00299 return FALSE; 00300 } 00301 g_free(task->document); 00302 task->document = g_strdup(new_document); 00303 g_free(task->label); 00304 task->label = g_strdup(new_label); 00305 ipc_menu_rename_task(xid, task->label); 00306 return TRUE; 00307 }
const gchar* task_service_by_window | ( | Window | xid | ) |
Get service of task with given window.
---------------------------------------------------------------------------
Name : task_service_by_window
xid | Window ID |
--------------------------------------------------------------------------
Definition at line 383 of file tasks.c.
References get_task_by_xid(), proc_t::ipc_service, LOGPRINTF, and task_t::proc.
Referenced by parse_wm_messages().
00384 { 00385 LOGPRINTF("entry: %d", (gint) xid); 00386 00387 task_t *task = get_task_by_xid(xid); 00388 if (task && task->proc && task->proc->ipc_service) 00389 { 00390 return task->proc->ipc_service; 00391 } 00392 return NULL; 00393 }
gboolean task_start | ( | const char * | command_line, | |
const char * | working_dir, | |||
const char * | label, | |||
const char * | image, | |||
eripc_context_t * | context, | |||
const char * | message_id | |||
) |
Start a task.
Description: Task list handling functions Copyright (C) 2008 iRex Technologies B.V. All rights reserved.---------------------------------------------------------------------------
Name : task_start
command_line | Full command line to spawn, quoted as g_shell_quote | |
working_dir | Working directory or NULL to inherit from sysd | |
label | Text label shown under icon in popup menu | |
image | Full path to icon shown in popup menu |
--------------------------------------------------------------------------
Definition at line 168 of file tasks.c.
References child_activate(), child_new(), child_window_open(), get_task(), ipc_send_reply_task_start(), proc_t::ipc_service, proc_t::is_multidoc, LOGPRINTF, new_request(), parse_commandline(), task_t::proc, process_get_by_name(), and tasklist_add().
Referenced by cb_open_url(), cb_status_item_activated(), cb_task_start(), and start_demo_mode().
00174 { 00175 LOGPRINTF("entry: `%s`", command_line); 00176 00177 gboolean retval = FALSE; 00178 gchar *application = NULL; 00179 gchar *document = NULL; 00180 00181 parse_commandline(command_line, &application, &document, NULL); 00182 00183 LOGPRINTF("app [%s] wd [%s] doc [%s] label [%s] image [%s]", application, working_dir, document, label, image); 00184 00185 task_t *task = get_task(application, document); 00186 if (task) 00187 { 00188 LOGPRINTF("task exists, reopen or activate"); 00189 // task already exists, reopen or activate 00190 // 00191 if (task->proc && task->proc->ipc_service && task->proc->is_multidoc) 00192 { 00193 request_t *request = new_request(task, context, message_id); 00194 retval = child_window_open(task, request); 00195 } 00196 else 00197 { 00198 retval = child_activate(task); 00199 if (context && message_id) 00200 { 00201 // return result to caller 00202 ipc_send_reply_task_start(context, message_id, 0, NULL); 00203 } 00204 } 00205 } 00206 else 00207 { 00208 proc_t *proc = process_get_by_name(application); 00209 if (proc) 00210 { 00211 // process is running but no task yet, create new 00212 // 00213 if (proc->ipc_service && proc->is_multidoc) 00214 { 00215 LOGPRINTF("task %s, %s not found, create it...", application, document); 00216 task_t *task = tasklist_add(proc, application, document, label, image, 0); 00217 request_t *request = new_request(task, context, message_id); 00218 retval = child_window_open(task, request); 00219 } 00220 else 00221 { 00222 if (proc->is_multidoc) { 00223 LOGPRINTF("%s, %s is currently running but is not a task, ignored.", application, document); 00224 // process running, singledoc and no task found for it 00225 // this is either a window-less process or a system process 00226 // in either case; we ignore this start command. 00227 } else { 00228 // TODO REFACTOR (common code) 00229 // process not running, create new 00230 LOGPRINTF("process %s running, but not for current doc, start new", application); 00231 retval = child_new(command_line, working_dir, application, document, label, image, context, message_id); 00232 } 00233 } 00234 } 00235 else 00236 { 00237 // process not running, create new 00238 // 00239 LOGPRINTF("process %s, not currently running start new", application); 00240 retval = child_new(command_line, working_dir, application, document, label, image, context, message_id); 00241 } 00242 } 00243 00244 // free allocated memory 00245 g_free(application); 00246 g_free(document); 00247 00248 LOGPRINTF("leave: retval %d", retval); 00249 00250 return retval; 00251 }
gboolean task_startup_completed | ( | proc_t * | proc, | |
Window | xid | |||
) |
Call when a task has finished starting.
---------------------------------------------------------------------------
Name : task_startup_completed
proc | Process | |
xid | Window id |
--------------------------------------------------------------------------
Definition at line 468 of file tasks.c.
References task_t::application, task_t::document, g_tasklist, ipc_menu_add_task(), task_t::label, LOGPRINTF, task_t::proc, and task_t::window.
Referenced by post_process_startup().
00469 { 00470 LOGPRINTF("entry"); 00471 00472 GSList *task_ptr = g_tasklist; 00473 while (task_ptr) 00474 { 00475 task_t *task = (task_t *) task_ptr->data; 00476 00477 if (task->proc == proc) 00478 { 00479 if (window != 0) 00480 { 00481 task->window = window; 00482 LOGPRINTF("assigned window %d to %s, %s", (gint) task->window, task->application, task->document); 00483 } 00484 00485 // add to task manager 00486 ipc_menu_add_task((gint)task->window, task->label); 00487 00488 return TRUE; 00489 } 00490 task_ptr = task_ptr->next; 00491 } 00492 return FALSE; 00493 }
gboolean task_stop | ( | const char * | command_line, | |
eripc_context_t * | context, | |||
const char * | message_id | |||
) |
Stop a running task.
---------------------------------------------------------------------------
Name : task_stop
command_line | Full command line of task, quoted as g_shell_quote |
--------------------------------------------------------------------------
Definition at line 254 of file tasks.c.
References child_close(), child_window_close(), get_task(), ipc_send_reply(), proc_t::ipc_service, proc_t::is_multidoc, LOGPRINTF, new_request(), parse_commandline(), and task_t::proc.
Referenced by cb_task_stop().
00257 { 00258 LOGPRINTF("entry: `%s`", command_line); 00259 00260 gboolean retval = FALSE; 00261 gchar *application = NULL; 00262 gchar *document = NULL; 00263 00264 parse_commandline(command_line, &application, &document, NULL); 00265 00266 task_t *task = get_task(application, document); 00267 if (task) 00268 { 00269 if (task->proc && task->proc->ipc_service && task->proc->is_multidoc) 00270 { 00271 request_t *request = new_request(task, context, message_id); 00272 LOGPRINTF("found multidoc window, close child window"); 00273 retval = child_window_close(task, request); 00274 } 00275 else 00276 { 00277 LOGPRINTF("found singledoc window, close child"); 00278 retval = child_close(task); 00279 ipc_send_reply(context, message_id, retval); 00280 } 00281 } 00282 00283 // free allocated memory 00284 g_free(application); 00285 g_free(document); 00286 00287 LOGPRINTF("leave: retval %d", retval); 00288 00289 return retval; 00290 }
static task_t * tasklist_add | ( | proc_t * | proc, | |
const char * | application, | |||
const char * | document, | |||
const char * | label, | |||
const char * | image, | |||
Window | window | |||
) | [static] |
Definition at line 1021 of file tasks.c.
References task_t::application, task_t::document, ERRORPRINTF, g_tasklist, task_t::image, task_t::label, LOGPRINTF, task_t::proc, and task_t::window.
Referenced by child_new(), task_add(), and task_start().
01023 { 01024 LOGPRINTF("entry"); 01025 01026 task_t *task = g_new0 (task_t, 1); 01027 if (!task) 01028 { 01029 ERRORPRINTF("mem alloc failed"); 01030 return NULL; 01031 } 01032 01033 task->proc = proc; 01034 task->application = g_strdup(application); 01035 task->document = g_strdup(document); 01036 task->label = g_strdup(label); 01037 task->image = g_strdup(image); 01038 task->window = window; 01039 01040 g_tasklist = g_slist_prepend(g_tasklist, task); 01041 01042 LOGPRINTF("done. task %p [#tasks: %d]", task, g_slist_length(g_tasklist)); 01043 01044 return task; 01045 }
static gboolean tasklist_remove_pid | ( | GPid | pid | ) | [static] |
Definition at line 1087 of file tasks.c.
References free_task(), g_tasklist, ipc_menu_remove_task(), LOGPRINTF, proc_t::pid, task_t::proc, and task_t::window.
Referenced by on_child_new_timeout(), and task_cleanup_pid().
01088 { 01089 LOGPRINTF("entry"); 01090 01091 GSList *task = g_tasklist; 01092 gint npre = g_slist_length(g_tasklist); 01093 01094 while ( (task != NULL) && (task->data != NULL) ) 01095 { 01096 task_t *task_data = task->data; 01097 01098 if (task_data->proc && (task_data->proc->pid == pid)) 01099 { 01100 ipc_menu_remove_task(task_data->window); 01101 free_task(task_data); 01102 01103 g_tasklist = g_slist_delete_link(g_tasklist, task); 01104 01105 // start over iteration 01106 task = g_tasklist; 01107 } 01108 else 01109 { 01110 task = task->next; 01111 } 01112 } 01113 01114 gint npost = g_slist_length(g_tasklist); 01115 01116 if (npre != npost) 01117 { 01118 LOGPRINTF("removed %d tasks, %d remaining", npre-npost, npost); 01119 return TRUE; 01120 } 01121 else 01122 { 01123 LOGPRINTF("no tasks found for pid %d", pid); 01124 return FALSE; 01125 } 01126 }
static gboolean tasklist_remove_window | ( | Window | window | ) | [static] |
Definition at line 1129 of file tasks.c.
References task_t::application, free_task(), g_tasklist, ipc_menu_remove_task(), LOGPRINTF, and task_t::window.
Referenced by on_window_close_callback(), on_window_open_callback(), and task_cleanup_window().
01130 { 01131 LOGPRINTF("entry: xid %d", (int) window); 01132 01133 GSList *task = g_tasklist; 01134 gint npre = g_slist_length(g_tasklist); 01135 gboolean is_uds_task = FALSE; 01136 01137 while ( (task != NULL) && (task->data != NULL) ) 01138 { 01139 task_t *task_data = task->data; 01140 01141 if (task_data->window == window) 01142 { 01143 ipc_menu_remove_task(task_data->window); 01144 01145 if (strcmp(task_data->application, "uds") == 0) 01146 { 01147 is_uds_task = TRUE; 01148 } 01149 free_task(task_data); 01150 01151 g_tasklist = g_slist_delete_link(g_tasklist, task); 01152 01153 // start over iteration 01154 task = g_tasklist; 01155 } 01156 else 01157 { 01158 task = task->next; 01159 } 01160 } 01161 01162 gint npost = g_slist_length(g_tasklist); 01163 /* 01164 if (is_uds_task && !is_uds_in_use()) 01165 { 01166 // start timer to check if any windows for UDS remain 01167 LOGPRINTF("no task found for UDS, start timer"); 01168 g_timeout_add_seconds(TIMEOUT_CHECK_RESTART_UDS, on_check_restart_uds, NULL); 01169 } 01170 */ 01171 01172 if (npre != npost) 01173 { 01174 LOGPRINTF("removed %d tasks, %d remaining", npre-npost, npost); 01175 return TRUE; 01176 } 01177 else 01178 { 01179 LOGPRINTF("no tasks found for window %d", (int) window); 01180 return FALSE; 01181 } 01182 }
static gboolean tasklist_set_first | ( | task_t * | task | ) | [static] |
Definition at line 1059 of file tasks.c.
References g_tasklist, ipc_menu_set_first_task(), LOGPRINTF, and task_t::window.
Referenced by child_activate().
01060 { 01061 LOGPRINTF("entry"); 01062 01063 task_t *task_data = NULL; 01064 GSList *cur_task = g_tasklist; 01065 01066 while ( (cur_task != NULL) && (cur_task->data != NULL) ) 01067 { 01068 task_data = cur_task->data; 01069 if (task_data == task) 01070 { 01071 ipc_menu_set_first_task(task->window); 01072 01073 g_tasklist = g_slist_delete_link(g_tasklist, cur_task); 01074 g_tasklist = g_slist_prepend(g_tasklist, task); 01075 LOGPRINTF("task set to first [#tasks: %d]", g_slist_length(g_tasklist)); 01076 return TRUE; 01077 } 01078 01079 cur_task = cur_task->next; 01080 } 01081 01082 LOGPRINTF("no first task found [#tasks: %d]", g_slist_length(g_tasklist)); 01083 return FALSE; 01084 }
char* testing_task_get_list | ( | ) |
Definition at line 496 of file tasks.c.
References task_t::application, buffer, cp, task_t::document, and g_tasklist.
Referenced by testing_list_tasks().
00497 { 00498 #if (TESTING_ON) 00499 char buffer[1000]; 00500 char* cp = buffer; 00501 GSList *iter = g_tasklist; 00502 while (iter) 00503 { 00504 task_t* task = (task_t*) iter->data; 00505 strcpy(cp, task->application); 00506 cp += strlen(task->application); 00507 *cp++ = '|'; 00508 strcpy(cp, task->document); 00509 cp += strlen(task->document); 00510 *cp++ = '\n'; 00511 00512 iter = g_slist_next(iter); 00513 } 00514 *cp = 0; 00515 char* result = g_strdup(buffer); 00516 return result; 00517 #endif 00518 return g_strdup("no debug"); 00519 }
gint g_check_child_window_source = 0 [static] |
Definition at line 96 of file tasks.c.
Referenced by child_new(), on_check_child_window(), and on_child_new_timeout().
gint g_child_terminate_source = 0 [static] |
Definition at line 95 of file tasks.c.
Referenced by child_close(), and on_child_term_timeout().
gboolean g_forced_close = FALSE [static] |
Definition at line 94 of file tasks.c.
Referenced by check_num_tasks(), task_cleanup_pid(), and task_cleanup_window().
gint g_task_pending_source = 0 [static] |
Definition at line 97 of file tasks.c.
Referenced by child_new(), on_check_child_window(), and on_child_new_timeout().
GSList* g_tasklist = NULL [static] |
Definition at line 93 of file tasks.c.
Referenced by check_num_tasks(), find_valid_task(), get_task(), get_task_by_xid(), on_window_open_callback(), print_task_list(), task_startup_completed(), tasklist_add(), tasklist_remove_pid(), tasklist_remove_window(), tasklist_set_first(), and testing_task_get_list().
const guint MAX_TASKS = 4 [static] |
Definition at line 84 of file tasks.c.
Referenced by check_num_tasks().
const gint TIMEOUT_CHECK_RESTART_UDS = 5 [static] |
const gint TIMEOUT_CHILD_CLOSE = 5 [static] |
Definition at line 80 of file tasks.c.
Referenced by child_close().
const gint TIMEOUT_CHILD_NEW = 30 [static] |
Definition at line 79 of file tasks.c.
Referenced by child_new().
const gint TIMER_CHECK_WINDOW_MS = 500 [static] |
Definition at line 83 of file tasks.c.
Referenced by child_new().