* ecore_exe_win32: manage ADD and DEL events. It works more or
less, but that Windows stuff is a bit like voodoo magic * Ecore.h : we can use the Ecore_Exe events on Windows, now (at least ADD and DEL, but the others will follow) SVN revision: 43549
This commit is contained in:
parent
a206a8b183
commit
520c12f976
|
@ -195,7 +195,6 @@ extern "C" {
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
struct _Ecore_Exe_Event_Add /** Process add event */
|
||||
{
|
||||
Ecore_Exe *exe; /**< The handle to the added process */
|
||||
|
@ -211,7 +210,9 @@ extern "C" {
|
|||
unsigned int exited : 1; /** < set to 1 if the process exited of its own accord */
|
||||
unsigned int signalled : 1; /** < set to 1 id the process exited due to uncaught signal */
|
||||
void *ext_data; /**< Extension data - not used */
|
||||
#ifndef _WIN32
|
||||
siginfo_t data; /**< Signal info */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */
|
||||
|
@ -227,7 +228,6 @@ extern "C" {
|
|||
int size; /**< the size of this data in bytes */
|
||||
Ecore_Exe_Event_Data_Line *lines; /**< an array of line data if line buffered, the last one has it's line member set to NULL */
|
||||
};
|
||||
#endif
|
||||
|
||||
EAPI int ecore_init(void);
|
||||
EAPI int ecore_shutdown(void);
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Evil.h>
|
||||
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore.h"
|
||||
|
||||
|
@ -38,6 +40,7 @@ struct _Ecore_Exe
|
|||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
|
||||
HANDLE process2;
|
||||
HANDLE process; /* CloseHandle */
|
||||
HANDLE thread;
|
||||
DWORD process_id;
|
||||
|
@ -50,8 +53,18 @@ struct _Ecore_Exe
|
|||
};
|
||||
|
||||
static Ecore_Exe *exes = NULL;
|
||||
Ecore_Win32_Handler *h = NULL;
|
||||
Ecore_Win32_Handler *h2 = NULL;
|
||||
|
||||
static BOOL CALLBACK _ecore_exe_enum_windows_procedure(HWND window, LPARAM data);
|
||||
static void _ecore_exe_event_add_free(void *data, void *ev);
|
||||
static void _ecore_exe_event_del_free(void *data __UNUSED__, void *ev);
|
||||
static int _ecore_exe_close_cb(void *data, Ecore_Win32_Handler *wh);
|
||||
|
||||
EAPI int ECORE_EXE_EVENT_ADD = 0;
|
||||
EAPI int ECORE_EXE_EVENT_DEL = 0;
|
||||
EAPI int ECORE_EXE_EVENT_DATA = 0;
|
||||
EAPI int ECORE_EXE_EVENT_ERROR = 0;
|
||||
|
||||
void
|
||||
_ecore_exe_init(void)
|
||||
|
@ -86,6 +99,7 @@ EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, c
|
|||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
Ecore_Exe_Event_Add *e;
|
||||
Ecore_Exe *exe;
|
||||
char *ret = NULL;
|
||||
|
||||
|
@ -122,24 +136,39 @@ EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, c
|
|||
goto free_exe_cmd;
|
||||
|
||||
/* be sure that the child process is running */
|
||||
/* FIXME: This does not work if the child is an EFL-based app */
|
||||
if (WaitForInputIdle(pi.hProcess, INFINITE) != 0)
|
||||
goto free_exe_cmd;
|
||||
|
||||
ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
|
||||
exe->process = pi.hProcess;
|
||||
exe->thread = pi.hThread;
|
||||
exe->process_id = pi.dwProcessId;
|
||||
exe->thread_id = pi.dwThreadId;
|
||||
exe->data = (void *)data;
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
if (!(exe->process = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE | SYNCHRONIZE,
|
||||
if (!(exe->process2 = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE | SYNCHRONIZE,
|
||||
FALSE, pi.dwProcessId)))
|
||||
goto close_thread;
|
||||
|
||||
h = ecore_main_win32_handler_add(exe->process2, _ecore_exe_close_cb, exe);
|
||||
|
||||
exes = (Ecore_Exe *)eina_inlist_append(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
|
||||
|
||||
e = (Ecore_Exe_Event_Add *)calloc(1, sizeof(Ecore_Exe_Event_Add));
|
||||
if (!e) goto close_process2;
|
||||
|
||||
e->exe = exe;
|
||||
ecore_event_add(ECORE_EXE_EVENT_ADD, e,
|
||||
_ecore_exe_event_add_free, NULL);
|
||||
|
||||
return exe;
|
||||
|
||||
close_process2:
|
||||
CloseHandle(exe->process2);
|
||||
close_thread:
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
free_exe_cmd:
|
||||
free(exe->cmd);
|
||||
free_exe:
|
||||
|
@ -179,8 +208,9 @@ EAPI void *ecore_exe_free(Ecore_Exe *exe)
|
|||
|
||||
data = exe->data;
|
||||
|
||||
CloseHandle(exe->process);
|
||||
CloseHandle(exe->thread);
|
||||
CloseHandle(exe->process);
|
||||
CloseHandle(exe->process2);
|
||||
free(exe->cmd);
|
||||
exes = (Ecore_Exe *) eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
|
||||
ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
|
||||
|
@ -280,6 +310,7 @@ EAPI void ecore_exe_interrupt(Ecore_Exe *exe)
|
|||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->thread);
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGINT;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
|
@ -293,6 +324,7 @@ EAPI void ecore_exe_quit(Ecore_Exe *exe)
|
|||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->thread);
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGQUIT;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
|
@ -306,6 +338,7 @@ EAPI void ecore_exe_terminate(Ecore_Exe *exe)
|
|||
return;
|
||||
}
|
||||
|
||||
/* CloseHandle(exe->thread); */
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGTERM;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
|
@ -319,6 +352,7 @@ EAPI void ecore_exe_kill(Ecore_Exe *exe)
|
|||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->thread);
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGKILL;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
|
@ -369,29 +403,48 @@ _ecore_exe_enum_windows_procedure(HWND window, LPARAM data)
|
|||
if (CreateRemoteThread(exe->process, NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)_ecore_exe_thread_procedure, NULL,
|
||||
0, NULL))
|
||||
{
|
||||
printf ("remote thread\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((exe->sig == ECORE_EXE_WIN32_SIGINT) ||
|
||||
(exe->sig == ECORE_EXE_WIN32_SIGQUIT))
|
||||
{
|
||||
printf ("int or quit\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* WM_CLOSE message */
|
||||
PostMessage(window, WM_CLOSE, 0, 0);
|
||||
if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
|
||||
{
|
||||
printf ("CLOSE\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* WM_QUIT message */
|
||||
PostMessage(window, WM_QUIT, 0, 0);
|
||||
if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
|
||||
{
|
||||
printf ("QUIT\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Exit process */
|
||||
if (CreateRemoteThread(exe->process, NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)ExitProcess, NULL,
|
||||
0, NULL))
|
||||
{
|
||||
printf ("remote thread 2\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (exe->sig == ECORE_EXE_WIN32_SIGTERM)
|
||||
{
|
||||
printf ("term\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TerminateProcess(exe->process, 0);
|
||||
|
||||
|
@ -401,4 +454,61 @@ _ecore_exe_enum_windows_procedure(HWND window, LPARAM data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_exe_event_add_free(void *data __UNUSED__, void *ev)
|
||||
{
|
||||
Ecore_Exe_Event_Add *e;
|
||||
|
||||
e = ev;
|
||||
free(e);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
|
||||
{
|
||||
Ecore_Exe_Event_Del *e;
|
||||
|
||||
e = (Ecore_Exe_Event_Del *)ev;
|
||||
if (e->exe)
|
||||
ecore_exe_free(e->exe);
|
||||
free(e);
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_exe_close_cb(void *data, Ecore_Win32_Handler *wh)
|
||||
{
|
||||
Ecore_Exe_Event_Del *e;
|
||||
Ecore_Exe *exe;
|
||||
DWORD exit_code = 0;
|
||||
|
||||
printf ("closing...\n");
|
||||
|
||||
e = calloc(1, sizeof(Ecore_Exe_Event_Del));
|
||||
if (!e) return 0;
|
||||
|
||||
exe = (Ecore_Exe *)data;
|
||||
|
||||
if (GetExitCodeProcess(exe->process2, &exit_code))
|
||||
{
|
||||
printf ("exit code : %d\n", (int)exit_code);
|
||||
e->exit_code = exit_code;
|
||||
e->exited = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *msg;
|
||||
|
||||
msg = evil_last_error_get();
|
||||
printf("%s\n", msg);
|
||||
free(msg);
|
||||
}
|
||||
e->pid = exe->process_id;
|
||||
e->exe = exe;
|
||||
|
||||
_ecore_event_add(ECORE_EXE_EVENT_DEL, e,
|
||||
_ecore_exe_event_del_free, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue