Commit a075daa2 authored by Tor Lillqvist's avatar Tor Lillqvist Committed by Tor Lillqvist

Add gimpcolorspace object.

2000-01-04  Tor Lillqvist  <tml@iki.fi>

* libgimp/makefile.{cygwin.msc}: Add gimpcolorspace object.

* libgimp/gimp.def: Add functions from it.

Fixes from Hans Breuer:

* app/datafiles.c: redefine the executable flag for Win32
to _S_IREAD, to get _all_ files from the plug-in dirs as
executables (including scripts)

* app/main.c: Win32-specific changes to allow building Gimp as a
console application, with all its benefits (like inheriting the
console), but hide it if the user doesn't want it. Also, if stdout
goes to a console, give the user a chance to read the help or
version messages. (tml: I am not convinced that it is better to
build gimp as a console application, but let's try it this way for
a while.)

* app/makefile.{cygwin,msc}: Build as console application, and
link with shell32 library.

* app/paint_core.c (paint_core_motion): Pass the value of a call
to the function gimage_active_drawable() to the paint_func,
instead of just passing the address of gimage_active_drawable...

(tml: This code is only called when the TOOL_TRACES_ON_WINDOW flag
is on, and only the clone tool sets that, and the clone tool's
paint_func doesn't use the drawable argument, so this hasn't
caused any trouble.)

* app/plug_in.c: On Win32, to support scripts, use new function
xspawn() instead of _spawnv. Add some more code to properly kill
plug-ins.

* libgimp/color_display.h: Add G_MODULE_EXPORT declarations.
parent 39021e34
2000-01-04 Tor Lillqvist <tml@iki.fi>
* libgimp/makefile.{cygwin.msc}: Add gimpcolorspace object.
* libgimp/gimp.def: Add functions from it.
Fixes from Hans Breuer:
* app/datafiles.c: redefine the executable flag for Win32
to _S_IREAD, to get _all_ files from the plug-in dirs as
executables (including scripts)
* app/main.c: Win32-specific changes to allow building Gimp as a
console application, with all its benefits (like inheriting the
console), but hide it if the user doesn't want it. Also, if stdout
goes to a console, give the user a chance to read the help or
version messages. (tml: I am not convinced that it is better to
build gimp as a console application, but let's try it this way for
a while.)
* app/makefile.{cygwin,msc}: Build as console application, and
link with shell32 library.
* app/paint_core.c (paint_core_motion): Pass the value of a call
to the function gimage_active_drawable() to the paint_func,
instead of just passing the address of gimage_active_drawable...
(tml: This code is only called when the TOOL_TRACES_ON_WINDOW flag
is on, and only the clone tool sets that, and the clone tool's
paint_func doesn't use the drawable argument, so this hasn't
caused any trouble.)
* app/plug_in.c: On Win32, to support scripts, use new function
xspawn() instead of _spawnv. Add some more code to properly kill
plug-ins.
* libgimp/color_display.h: Add G_MODULE_EXPORT declarations.
Tue Jan 4 18:00:40 CET 2000 Sven Neumann <sven@gimp.org>
* plug-ins/script-fu/scripts/circuit.scm: someone didn't close a
......
......@@ -802,6 +802,59 @@ plug_in_destroy (PlugIn *plug_in)
}
}
#ifdef G_OS_WIN32
/* The Microsoft _spawnv() does not allow to run scripts. But
* this is essential to get scripting extension up and running.
* Following the replacement function xspawnv().
*/
int
xspawnv (int mode,
const char *cmdname,
const char *const *argv )
{
char sExecutable[_MAX_PATH*2];
char** sArgsList;
char sCmndLine[1024];
char* sPath;
HINSTANCE hInst;
int i;
int pid;
/* only use it if _spawnv fails */
pid = _spawnv(mode, cmdname, argv);
if (pid != -1) return pid;
/* stuff parameters into one cmndline */
sCmndLine[0] = 0;
for (i = 1; argv[i] != NULL; i++)
{
strcat(sCmndLine, argv[i]);
strcat(sCmndLine, " ");
}
/* remove last blank */
sCmndLine[strlen(sCmndLine)-1] = 0;
/* do we really need _spawnv (ShelExecute seems not to do it)*/
if (32 <= (int)FindExecutable (cmdname,
gimp_directory (),
sExecutable))
{
//g_print("_spawnlp %s %s %s", sExecutable, cmdname, sCmndLine);
pid = _spawnlp(mode, sExecutable, "-c", cmdname, sCmndLine, NULL);
}
else
{
g_warning("Execution error for: %s", cmdname);
return -1;
}
return pid;
}
#undef _spawnv
#define _spawnv xspawnv
#endif /* G_OS_WIN32 */
gint
plug_in_open (PlugIn *plug_in)
{
......@@ -989,7 +1042,26 @@ plug_in_close (PlugIn *plug_in,
waitpid (plug_in->pid, &status, 0);
#else
if (kill_it && plug_in->pid)
TerminateProcess ((HANDLE) plug_in->pid, 0);
{
/* Trying to avoid TerminateProcess (does mostly work).
* Otherwise some of our needed DLLs may get into an unstable state
* (see Win32 API docs).
*/
DWORD dwExitCode = STILL_ACTIVE;
DWORD dwTries = 10;
while ((STILL_ACTIVE == dwExitCode)
&& GetExitCodeProcess((HANDLE) plug_in->pid, &dwExitCode)
&& (dwTries > 0))
{
Sleep(10);
dwTries--;
}
if (STILL_ACTIVE == dwExitCode)
{
g_warning("Terminating %s ...", plug_in->args[0]);
TerminateProcess ((HANDLE) plug_in->pid, 0);
}
}
#endif
/* Remove the input handler.
......
......@@ -39,10 +39,10 @@
#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
#endif
#ifndef S_IXUSR
#define S_IXUSR _S_IEXEC
#endif
#endif
/* (Re)define S_IXUSR as _S_IREAD to get scripts, too. */
#undef S_IXUSR
#define S_IXUSR _S_IREAD
#endif /* G_OS_WIN32 */
#include "datafiles.h"
#include "errors.h"
......
......@@ -39,10 +39,10 @@
#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
#endif
#ifndef S_IXUSR
#define S_IXUSR _S_IEXEC
#endif
#endif
/* (Re)define S_IXUSR as _S_IREAD to get scripts, too. */
#undef S_IXUSR
#define S_IXUSR _S_IREAD
#endif /* G_OS_WIN32 */
#include "datafiles.h"
#include "errors.h"
......
......@@ -802,6 +802,59 @@ plug_in_destroy (PlugIn *plug_in)
}
}
#ifdef G_OS_WIN32
/* The Microsoft _spawnv() does not allow to run scripts. But
* this is essential to get scripting extension up and running.
* Following the replacement function xspawnv().
*/
int
xspawnv (int mode,
const char *cmdname,
const char *const *argv )
{
char sExecutable[_MAX_PATH*2];
char** sArgsList;
char sCmndLine[1024];
char* sPath;
HINSTANCE hInst;
int i;
int pid;
/* only use it if _spawnv fails */
pid = _spawnv(mode, cmdname, argv);
if (pid != -1) return pid;
/* stuff parameters into one cmndline */
sCmndLine[0] = 0;
for (i = 1; argv[i] != NULL; i++)
{
strcat(sCmndLine, argv[i]);
strcat(sCmndLine, " ");
}
/* remove last blank */
sCmndLine[strlen(sCmndLine)-1] = 0;
/* do we really need _spawnv (ShelExecute seems not to do it)*/
if (32 <= (int)FindExecutable (cmdname,
gimp_directory (),
sExecutable))
{
//g_print("_spawnlp %s %s %s", sExecutable, cmdname, sCmndLine);
pid = _spawnlp(mode, sExecutable, "-c", cmdname, sCmndLine, NULL);
}
else
{
g_warning("Execution error for: %s", cmdname);
return -1;
}
return pid;
}
#undef _spawnv
#define _spawnv xspawnv
#endif /* G_OS_WIN32 */
gint
plug_in_open (PlugIn *plug_in)
{
......@@ -989,7 +1042,26 @@ plug_in_close (PlugIn *plug_in,
waitpid (plug_in->pid, &status, 0);
#else
if (kill_it && plug_in->pid)
TerminateProcess ((HANDLE) plug_in->pid, 0);
{
/* Trying to avoid TerminateProcess (does mostly work).
* Otherwise some of our needed DLLs may get into an unstable state
* (see Win32 API docs).
*/
DWORD dwExitCode = STILL_ACTIVE;
DWORD dwTries = 10;
while ((STILL_ACTIVE == dwExitCode)
&& GetExitCodeProcess((HANDLE) plug_in->pid, &dwExitCode)
&& (dwTries > 0))
{
Sleep(10);
dwTries--;
}
if (STILL_ACTIVE == dwExitCode)
{
g_warning("Terminating %s ...", plug_in->args[0]);
TerminateProcess ((HANDLE) plug_in->pid, 0);
}
}
#endif
/* Remove the input handler.
......
......@@ -802,6 +802,59 @@ plug_in_destroy (PlugIn *plug_in)
}
}
#ifdef G_OS_WIN32
/* The Microsoft _spawnv() does not allow to run scripts. But
* this is essential to get scripting extension up and running.
* Following the replacement function xspawnv().
*/
int
xspawnv (int mode,
const char *cmdname,
const char *const *argv )
{
char sExecutable[_MAX_PATH*2];
char** sArgsList;
char sCmndLine[1024];
char* sPath;
HINSTANCE hInst;
int i;
int pid;
/* only use it if _spawnv fails */
pid = _spawnv(mode, cmdname, argv);
if (pid != -1) return pid;
/* stuff parameters into one cmndline */
sCmndLine[0] = 0;
for (i = 1; argv[i] != NULL; i++)
{
strcat(sCmndLine, argv[i]);
strcat(sCmndLine, " ");
}
/* remove last blank */
sCmndLine[strlen(sCmndLine)-1] = 0;
/* do we really need _spawnv (ShelExecute seems not to do it)*/
if (32 <= (int)FindExecutable (cmdname,
gimp_directory (),
sExecutable))
{
//g_print("_spawnlp %s %s %s", sExecutable, cmdname, sCmndLine);
pid = _spawnlp(mode, sExecutable, "-c", cmdname, sCmndLine, NULL);
}
else
{
g_warning("Execution error for: %s", cmdname);
return -1;
}
return pid;
}
#undef _spawnv
#define _spawnv xspawnv
#endif /* G_OS_WIN32 */
gint
plug_in_open (PlugIn *plug_in)
{
......@@ -989,7 +1042,26 @@ plug_in_close (PlugIn *plug_in,
waitpid (plug_in->pid, &status, 0);
#else
if (kill_it && plug_in->pid)
TerminateProcess ((HANDLE) plug_in->pid, 0);
{
/* Trying to avoid TerminateProcess (does mostly work).
* Otherwise some of our needed DLLs may get into an unstable state
* (see Win32 API docs).
*/
DWORD dwExitCode = STILL_ACTIVE;
DWORD dwTries = 10;
while ((STILL_ACTIVE == dwExitCode)
&& GetExitCodeProcess((HANDLE) plug_in->pid, &dwExitCode)
&& (dwTries > 0))
{
Sleep(10);
dwTries--;
}
if (STILL_ACTIVE == dwExitCode)
{
g_warning("Terminating %s ...", plug_in->args[0]);
TerminateProcess ((HANDLE) plug_in->pid, 0);
}
}
#endif
/* Remove the input handler.
......
......@@ -46,7 +46,9 @@
#include "libgimp/gimpintl.h"
#ifndef G_OS_WIN32
#ifdef G_OS_WIN32
#include <windows.h>
#else
static RETSIGTYPE on_signal (int);
#ifdef SIGCHLD
static RETSIGTYPE on_sig_child (int);
......@@ -285,6 +287,16 @@ main (int argc, char **argv)
}
}
#ifdef G_OS_WIN32
/* Common windoze apps don't have a console at all. So does Gimp
* - if appropiate. This allows to compile as console application
* with all it's benfits (like inheriting the console) but hide
* it, if the user doesn't want it.
*/
if (!show_help && !show_version && !be_verbose && !console_messages)
FreeConsole ();
#endif
if (show_version)
g_print ( "%s %s\n", _("GIMP version"), GIMP_VERSION);
......@@ -311,7 +323,25 @@ main (int argc, char **argv)
}
if (show_version || show_help)
exit (0);
{
#ifdef G_OS_WIN32
/* Give them time to read the message if it was printed in a
* separate console window. I would really love to have
* some way of asking for confirmation to close the console
* window.
*/
HANDLE console;
DWORD mode;
console = GetStdHandle (STD_OUTPUT_HANDLE);
if (GetConsoleMode (console, &mode) != 0)
{
g_print (_("(This console window will close in ten seconds)\n"));
Sleep(10000);
}
#endif
exit (0);
}
g_set_message_handler ((GPrintFunc) gimp_message_func);
......@@ -385,7 +415,10 @@ main (int argc, char **argv)
#endif
int _stdcall
WinMain (int hInstance, int hPrevInstance, char *lpszCmdLine, int nCmdShow)
WinMain (struct HINSTANCE__ *hInstance,
struct HINSTANCE__ *hPrevInstance,
char *lpszCmdLine,
int nCmdShow)
{
return main (__argc, __argv);
}
......
......@@ -269,11 +269,11 @@ gimp.def: gimp.sym
gimp.exe : ../config.h $(gimp_OBJECTS) libgimpim.a gimp.def gimpres.o
# This is sickening.
$(CC) $(CFLAGS) -Wl,--base-file,gimp.base -mwindows -o gimp.exe $(gimp_OBJECTS) -L . -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32
$(CC) $(CFLAGS) -Wl,--base-file,gimp.base -o gimp.exe $(gimp_OBJECTS) -L . -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32 -lshell32
$(DLLTOOL) --base-file gimp.base --input-def gimp.def --output-exp gimp.exp
$(CC) $(CFLAGS) -Wl,--base-file,gimp.base,gimp.exp -mwindows -o gimp.exe $(gimp_OBJECTS) -L . -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32
$(CC) $(CFLAGS) -Wl,--base-file,gimp.base,gimp.exp -o gimp.exe $(gimp_OBJECTS) -L . -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32 -lshell32
$(DLLTOOL) --base-file gimp.base --input-def gimp.def --output-exp gimp.exp
$(CC) $(CFLAGS) -Wl,gimp.exp -mwindows -o gimp.exe $(gimp_OBJECTS) -L. -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32
$(CC) $(CFLAGS) -Wl,gimp.exp -o gimp.exe $(gimp_OBJECTS) -L. -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32 -lshell32
$(DLLTOOL) --dllname gimp.exe gimp.def --output-lib libgimp.a $(gimp_OBJECTS)
.SUFFIXES: .c .o .i
......
......@@ -11,17 +11,17 @@ BIN = C:\gimp\bin
!IFNDEF DEBUG
# Full optimization:
OPTIMIZE = -Ox -MD
LINKDEBUG = /subsystem:windows
LINKDEBUG =
!ELSE
# Debugging:
OPTIMIZE = -Zi -MDd
LINKDEBUG = /subsystem:console /debug
LINKDEBUG = /debug
!ENDIF
# cl -? describes the options
CC = cl -GA -G5 -GF $(OPTIMIZE) -W3 -nologo
LDFLAGS = /link /machine:ix86 $(LINKDEBUG)
LDFLAGS = /link /subsystem:console /machine:ix86 $(LINKDEBUG)
INSTALL = copy
GIMP_VER = 1.1
......@@ -275,7 +275,7 @@ gimp.def: gimp.sym
copy /y $@+gimp.sym $@
gimp.exe : ..\config.h $(gimp_OBJECTS) gimpim.lib gimp.def gimp.res ..\libgimp\gimpi.lib
$(CC) $(CFLAGS) -Fegimp.exe $(gimp_OBJECTS) gimpim.lib ..\libgimp\gimpi.lib $(GTK)\gtk\gtk-$(GTK_VER).lib $(GTK)\gdk\gdk-$(GTK_VER).lib $(INTL)\gnu-intl.lib $(GLIB)\glib-$(GLIB_VER).lib $(GLIB)\gmodule-$(GLIB_VER).lib $(LDFLAGS) gimp.res gdi32.lib user32.lib /def:gimp.def
$(CC) $(CFLAGS) -Fegimp.exe $(gimp_OBJECTS) gimpim.lib ..\libgimp\gimpi.lib $(GTK)\gtk\gtk-$(GTK_VER).lib $(GTK)\gdk\gdk-$(GTK_VER).lib $(INTL)\gnu-intl.lib $(GLIB)\glib-$(GLIB_VER).lib $(GLIB)\gmodule-$(GLIB_VER).lib $(LDFLAGS) gimp.res gdi32.lib user32.lib shell32.lib /def:gimp.def
# General rule for building $(gimp_OBJECTS)
.c.obj:
......
......@@ -802,6 +802,59 @@ plug_in_destroy (PlugIn *plug_in)
}
}
#ifdef G_OS_WIN32
/* The Microsoft _spawnv() does not allow to run scripts. But
* this is essential to get scripting extension up and running.
* Following the replacement function xspawnv().
*/
int
xspawnv (int mode,
const char *cmdname,
const char *const *argv )
{
char sExecutable[_MAX_PATH*2];
char** sArgsList;
char sCmndLine[1024];
char* sPath;
HINSTANCE hInst;
int i;
int pid;
/* only use it if _spawnv fails */
pid = _spawnv(mode, cmdname, argv);
if (pid != -1) return pid;
/* stuff parameters into one cmndline */
sCmndLine[0] = 0;
for (i = 1; argv[i] != NULL; i++)
{
strcat(sCmndLine, argv[i]);
strcat(sCmndLine, " ");
}
/* remove last blank */
sCmndLine[strlen(sCmndLine)-1] = 0;
/* do we really need _spawnv (ShelExecute seems not to do it)*/
if (32 <= (int)FindExecutable (cmdname,
gimp_directory (),
sExecutable))
{
//g_print("_spawnlp %s %s %s", sExecutable, cmdname, sCmndLine);
pid = _spawnlp(mode, sExecutable, "-c", cmdname, sCmndLine, NULL);
}
else
{
g_warning("Execution error for: %s", cmdname);
return -1;
}
return pid;
}
#undef _spawnv
#define _spawnv xspawnv
#endif /* G_OS_WIN32 */
gint
plug_in_open (PlugIn *plug_in)
{
......@@ -989,7 +1042,26 @@ plug_in_close (PlugIn *plug_in,
waitpid (plug_in->pid, &status, 0);
#else
if (kill_it && plug_in->pid)
TerminateProcess ((HANDLE) plug_in->pid, 0);
{
/* Trying to avoid TerminateProcess (does mostly work).
* Otherwise some of our needed DLLs may get into an unstable state
* (see Win32 API docs).
*/
DWORD dwExitCode = STILL_ACTIVE;
DWORD dwTries = 10;
while ((STILL_ACTIVE == dwExitCode)
&& GetExitCodeProcess((HANDLE) plug_in->pid, &dwExitCode)
&& (dwTries > 0))
{
Sleep(10);
dwTries--;
}
if (STILL_ACTIVE == dwExitCode)
{
g_warning("Terminating %s ...", plug_in->args[0]);
TerminateProcess ((HANDLE) plug_in->pid, 0);
}
}
#endif
/* Remove the input handler.
......
......@@ -408,10 +408,10 @@ paint_core_motion (Tool *tool,
paint_core_interpolate (paint_core, gimage_active_drawable (gdisp->gimage));
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
(* paint_core->paint_func) (paint_core, gimage_active_drawable, PRETRACE_PAINT);
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), PRETRACE_PAINT);
gdisplay_flush_now (gdisp);
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
(* paint_core->paint_func) (paint_core, gimage_active_drawable, POSTTRACE_PAINT);
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), POSTTRACE_PAINT);
paint_core->lastx = paint_core->curx;
paint_core->lasty = paint_core->cury;
......
......@@ -802,6 +802,59 @@ plug_in_destroy (PlugIn *plug_in)
}
}
#ifdef G_OS_WIN32
/* The Microsoft _spawnv() does not allow to run scripts. But
* this is essential to get scripting extension up and running.
* Following the replacement function xspawnv().
*/
int
xspawnv (int mode,
const char *cmdname,
const char *const *argv )
{
char sExecutable[_MAX_PATH*2];
char** sArgsList;
char sCmndLine[1024];
char* sPath;
HINSTANCE hInst;
int i;
int pid;
/* only use it if _spawnv fails */
pid = _spawnv(mode, cmdname, argv);
if (pid != -1) return pid;
/* stuff parameters into one cmndline */
sCmndLine[0] = 0;
for (i = 1; argv[i] != NULL; i++)
{
strcat(sCmndLine, argv[i]);
strcat(sCmndLine, " ");
}
/* remove last blank */
sCmndLine[strlen(sCmndLine)-1] = 0;
/* do we really need _spawnv (ShelExecute seems not to do it)*/
if (32 <= (int)FindExecutable (cmdname,
gimp_directory (),
sExecutable))
{
//g_print("_spawnlp %s %s %s", sExecutable, cmdname, sCmndLine);
pid = _spawnlp(mode, sExecutable, "-c", cmdname, sCmndLine, NULL);
}
else
{
g_warning("Execution error for: %s", cmdname);
return -1;
}
return pid;
}
#undef _spawnv
#define _spawnv xspawnv
#endif /* G_OS_WIN32 */
gint
plug_in_open (PlugIn *plug_in)
{
......@@ -989,7 +1042,26 @@ plug_in_close (PlugIn *plug_in,
waitpid (plug_in->pid, &status, 0);
#else
if (kill_it && plug_in->pid)
TerminateProcess ((HANDLE) plug_in->pid, 0);
{
/* Trying to avoid TerminateProcess (does mostly work).
* Otherwise some of our needed DLLs may get into an unstable state
* (see Win32 API docs).
*/
DWORD dwExitCode = STILL_ACTIVE;
DWORD dwTries = 10;
while ((STILL_ACTIVE == dwExitCode)
&& GetExitCodeProcess((HANDLE) plug_in->pid, &dwExitCode)
&& (dwTries > 0))
{
Sleep(10);
dwTries--;
}
if (STILL_ACTIVE == dwExitCode)
{
g_warning("Terminating %s ...", plug_in->args[0]);
TerminateProcess ((HANDLE) plug_in->pid, 0);