blob: 5accbbd613089a676ac660865cba0efac64abf8f [file] [log] [blame]
Andrew MacIntyre41d97d62002-02-17 05:23:30 +00001/* 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 */
28typedef 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 */
40int PythonRC;
41
42extern DL_EXPORT(int) Py_Main(int, char **);
43void PythonThread(void *);
44
45int
46main(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
103void 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}