| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | /* 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 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     int argc; | 
					
						
							|  |  |  |     char **argv; | 
					
						
							|  |  |  |     HWND Frame; | 
					
						
							|  |  |  |     int running; | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | } 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PythonThread(void *argl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     HAB hab; | 
					
						
							|  |  |  |     arglist *args; | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     /* PM initialisation */ | 
					
						
							|  |  |  |     hab = WinInitialize(0); | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     /* start Python */ | 
					
						
							|  |  |  |     args = (arglist *)argl; | 
					
						
							|  |  |  |     args->running = 1; | 
					
						
							|  |  |  |     PythonRC = Py_Main(args->argc, args->argv); | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     /* enter a critical section and send the termination message */ | 
					
						
							|  |  |  |     DosEnterCritSec(); | 
					
						
							|  |  |  |     args->running = 0; | 
					
						
							|  |  |  |     WinPostMsg(args->Frame, WM_QUIT, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     /* shutdown PM and terminate thread */ | 
					
						
							|  |  |  |     WinTerminate(hab); | 
					
						
							|  |  |  |     _endthread(); | 
					
						
							| 
									
										
										
										
											2002-02-17 05:23:30 +00:00
										 |  |  | } |