/* 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 , 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 #include #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(); }