| /* OS/2 PM main program - creates a hidden window, and starts Python | 
 |  * interpreter in a separate thread, so that Python scripts can be | 
 |  * run in PM process space without a console Window.  The interpreter | 
 |  * is incorporated by linking in the Python DLL. | 
 |  * | 
 |  * As it stands, I don't think this is adequate for supporting Python | 
 |  * GUI modules, as the Python thread doesn't have its own message | 
 |  * queue - which is required of threads that want to create/use | 
 |  * PM windows. | 
 |  * | 
 |  * This code owes a lot to "OS/2 Presentation Manager Programming", by | 
 |  * Charles Petzold. | 
 |  * | 
 |  * Andrew MacIntyre <andymac@bullseye.apana.org.au>, August 2001. | 
 |  * Released under the terms of the Python 2.1.1 licence - see the LICENCE | 
 |  * file in the Python v2.1.1 (or later) source distribution. | 
 |  * Copyright assigned to the Python Software Foundation, 2001. | 
 |  */ | 
 |  | 
 | #define INCL_DOS | 
 | #define INCL_WIN | 
 | #include <os2.h> | 
 | #include <process.h> | 
 |  | 
 | #include "Python.h" | 
 |  | 
 | /* use structure to pass command line to Python thread */ | 
 | typedef struct | 
 | { | 
 | 	int argc; | 
 | 	char **argv; | 
 | 	HWND Frame; | 
 | 	int running; | 
 | } arglist; | 
 |  | 
 | /* make this a global to simplify access. | 
 |  * it should only be set from the Python thread, or by the code that | 
 |  * initiates the Python thread when the thread cannot be created. | 
 |  */ | 
 | int PythonRC; | 
 |  | 
 | extern DL_EXPORT(int) Py_Main(int, char **); | 
 | void PythonThread(void *); | 
 |  | 
 | int | 
 | main(int argc, char **argv) | 
 | { | 
 | 	ULONG FrameFlags = FCF_TITLEBAR | | 
 | 			   FCF_SYSMENU | | 
 | 			   FCF_SIZEBORDER | | 
 | 			   FCF_HIDEBUTTON | | 
 | 			   FCF_SHELLPOSITION | | 
 | 			   FCF_TASKLIST; | 
 | 	HAB hab; | 
 | 	HMQ hmq; | 
 | 	HWND Client; | 
 | 	QMSG qmsg; | 
 | 	arglist args; | 
 | 	int python_tid; | 
 |  | 
 | 	/* init PM and create message queue */ | 
 | 	hab = WinInitialize(0); | 
 | 	hmq = WinCreateMsgQueue(hab, 0); | 
 |  | 
 | 	/* create a (hidden) Window to house the window procedure */ | 
 | 	args.Frame = WinCreateStdWindow(HWND_DESKTOP, | 
 | 					0, | 
 | 					&FrameFlags, | 
 | 					NULL, | 
 | 					"PythonPM", | 
 | 					0L, | 
 | 					0, | 
 | 					0, | 
 | 					&Client); | 
 |  | 
 | 	/* run Python interpreter in a thread */ | 
 | 	args.argc = argc; | 
 | 	args.argv = argv; | 
 | 	args.running = 0; | 
 | 	if (-1 == (python_tid = _beginthread(PythonThread, NULL, 1024 * 1024, &args))) | 
 | 	{ | 
 | 		/* couldn't start thread */ | 
 | 		WinAlarm(HWND_DESKTOP, WA_ERROR); | 
 | 		PythonRC = 1; | 
 | 	} | 
 | 	else | 
 | 	{ | 
 | 		/* process PM messages, until Python exits */ | 
 | 		while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0)) | 
 | 			WinDispatchMsg(hab, &qmsg); | 
 | 		if (args.running > 0) | 
 | 			DosKillThread(python_tid); | 
 | 	} | 
 | 		 | 
 | 	/* destroy window, shutdown message queue and PM */ | 
 | 	WinDestroyWindow(args.Frame); | 
 | 	WinDestroyMsgQueue(hmq); | 
 | 	WinTerminate(hab); | 
 |  | 
 | 	return PythonRC; | 
 | } | 
 |  | 
 | void PythonThread(void *argl) | 
 | { | 
 | 	HAB hab; | 
 | 	arglist *args; | 
 |  | 
 | 	/* PM initialisation */ | 
 | 	hab = WinInitialize(0); | 
 |  | 
 | 	/* start Python */ | 
 | 	args = (arglist *)argl; | 
 | 	args->running = 1; | 
 | 	PythonRC = Py_Main(args->argc, args->argv); | 
 |  | 
 | 	/* enter a critical section and send the termination message */ | 
 | 	DosEnterCritSec(); | 
 | 	args->running = 0; | 
 | 	WinPostMsg(args->Frame, WM_QUIT, NULL, NULL); | 
 |  | 
 | 	/* shutdown PM and terminate thread */ | 
 | 	WinTerminate(hab); | 
 | 	_endthread(); | 
 | } |