| 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@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 | } | 
|---|