1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* 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();
}
|