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