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