Home | History | Annotate | Download | only in os2emx
      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 (at) 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 }
    125