1 /* OS/2 PM main program - creates a hidden window, and starts Python 2 * interpreter in a separate thread, so that Python scripts can be 3 * run in PM process space without a console Window. The interpreter 4 * is incorporated by linking in the Python DLL. 5 * 6 * As it stands, I don't think this is adequate for supporting Python 7 * GUI modules, as the Python thread doesn't have its own message 8 * queue - which is required of threads that want to create/use 9 * PM windows. 10 * 11 * This code owes a lot to "OS/2 Presentation Manager Programming", by 12 * Charles Petzold. 13 * 14 * Andrew MacIntyre <andymac (at) bullseye.apana.org.au>, August 2001. 15 * Released under the terms of the Python 2.1.1 licence - see the LICENCE 16 * file in the Python v2.1.1 (or later) source distribution. 17 * Copyright assigned to the Python Software Foundation, 2001. 18 */ 19 20 #define INCL_DOS 21 #define INCL_WIN 22 #include <os2.h> 23 #include <process.h> 24 25 #include "Python.h" 26 27 /* use structure to pass command line to Python thread */ 28 typedef struct 29 { 30 int argc; 31 char **argv; 32 HWND Frame; 33 int running; 34 } arglist; 35 36 /* make this a global to simplify access. 37 * it should only be set from the Python thread, or by the code that 38 * initiates the Python thread when the thread cannot be created. 39 */ 40 int PythonRC; 41 42 extern DL_EXPORT(int) Py_Main(int, char **); 43 void PythonThread(void *); 44 45 int 46 main(int argc, char **argv) 47 { 48 ULONG FrameFlags = FCF_TITLEBAR | 49 FCF_SYSMENU | 50 FCF_SIZEBORDER | 51 FCF_HIDEBUTTON | 52 FCF_SHELLPOSITION | 53 FCF_TASKLIST; 54 HAB hab; 55 HMQ hmq; 56 HWND Client; 57 QMSG qmsg; 58 arglist args; 59 int python_tid; 60 61 /* init PM and create message queue */ 62 hab = WinInitialize(0); 63 hmq = WinCreateMsgQueue(hab, 0); 64 65 /* create a (hidden) Window to house the window procedure */ 66 args.Frame = WinCreateStdWindow(HWND_DESKTOP, 67 0, 68 &FrameFlags, 69 NULL, 70 "PythonPM", 71 0L, 72 0, 73 0, 74 &Client); 75 76 /* run Python interpreter in a thread */ 77 args.argc = argc; 78 args.argv = argv; 79 args.running = 0; 80 if (-1 == (python_tid = _beginthread(PythonThread, NULL, 1024 * 1024, &args))) 81 { 82 /* couldn't start thread */ 83 WinAlarm(HWND_DESKTOP, WA_ERROR); 84 PythonRC = 1; 85 } 86 else 87 { 88 /* process PM messages, until Python exits */ 89 while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0)) 90 WinDispatchMsg(hab, &qmsg); 91 if (args.running > 0) 92 DosKillThread(python_tid); 93 } 94 95 /* destroy window, shutdown message queue and PM */ 96 WinDestroyWindow(args.Frame); 97 WinDestroyMsgQueue(hmq); 98 WinTerminate(hab); 99 100 return PythonRC; 101 } 102 103 void PythonThread(void *argl) 104 { 105 HAB hab; 106 arglist *args; 107 108 /* PM initialisation */ 109 hab = WinInitialize(0); 110 111 /* start Python */ 112 args = (arglist *)argl; 113 args->running = 1; 114 PythonRC = Py_Main(args->argc, args->argv); 115 116 /* enter a critical section and send the termination message */ 117 DosEnterCritSec(); 118 args->running = 0; 119 WinPostMsg(args->Frame, WM_QUIT, NULL, NULL); 120 121 /* shutdown PM and terminate thread */ 122 WinTerminate(hab); 123 _endthread(); 124 } 125