Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

py_vmd.C

Go to the documentation of this file.
00001 
00002 #include "py_commands.h"
00003 #include "vmd.h"
00004 #include "DisplayDevice.h"
00005 #include "UIText.h"
00006 
00007 #include <tcl.h>
00008 
00009 extern "C" {
00010   void initvmd();
00011 }
00012 
00013 static PyObject *py_vmdupdate(PyObject *self, PyObject *args) {
00014   VMDApp *app = get_vmdapp();
00015   if (!app) {
00016     fprintf(stderr, "no app!!\n");
00017     Py_INCREF(Py_None);
00018     return Py_None; 
00019   }
00020   return Py_BuildValue("i", app->VMDupdate(1));
00021 }
00022 
00023 static PyObject *py_vmdexit(PyObject *self, PyObject *args) {
00024   char *msg;
00025   int code = 0;
00026   int pauseseconds = 0;
00027   if (!PyArg_ParseTuple(args, "s|ii", &msg, &code, &pauseseconds))
00028     return NULL;
00029   VMDApp *app = get_vmdapp();
00030   app->VMDexit(msg, code, pauseseconds);
00031   // don't call VMDshutdown, because calling Tcl_Finalize() crashes Tkinter
00032   // Maybe add a callback to the Python atexit module?
00033   Py_INCREF(Py_None);
00034   return Py_None; 
00035 }
00036 
00037 static PyObject *py_evaltcl(PyObject *self, PyObject *args) {
00038   char *cmd;
00039   if (!PyArg_ParseTuple(args, "s", &cmd)) return NULL;
00040   VMDApp *app = get_vmdapp();
00041   Tcl_Interp *interp = app->uiText->get_tcl_interp();
00042   if (Tcl_Eval(interp, cmd) != TCL_OK) {
00043     PyErr_SetString(PyExc_ValueError, Tcl_GetStringResult(interp));
00044     return NULL;
00045   }
00046   return PyString_FromString(Tcl_GetStringResult(interp));
00047 }
00048 
00049 static PyMethodDef VMDAppMethods [] = {
00050     { (char *)"VMDupdate", py_vmdupdate, METH_VARARGS },
00051     { (char *)"VMDexit", py_vmdexit, METH_VARARGS },
00052     { (char *)"VMDevaltcl", py_evaltcl, METH_VARARGS },
00053     { NULL, NULL }
00054 };
00055 
00056 static VMDApp *the_app=NULL;
00057 static PyThreadState *event_tstate = NULL;
00058 
00059 static int vmd_input_hook() {
00060   if (the_app) {
00061     the_app->VMDupdate(1);
00062   }
00063   PyEval_RestoreThread(event_tstate);
00064   PyRun_SimpleString(
00065       "try:\n"
00066       "\timport Tkinter\n"
00067       "\twhile Tkinter.tkinter.dooneevent(Tkinter.tkinter.DONT_WAIT):\n"
00068       "\t\tpass\n"
00069       "except:\n"
00070       "\tpass\n");
00071   PyEval_SaveThread();
00072   return 0;
00073 }
00074 
00075 void initvmd() {
00076   // If there's already a VMDapp in get_vmdapp, then we must be running
00077   // inside a standalone VMD instead of being loaded as a python extension.
00078   // Don't throw an error - just load the methods for interoperability
00079   // in case vmd.so is in the PYTHONPATH of the standalone application.
00080   if (get_vmdapp() != NULL) {
00081     (void)Py_InitModule((char *)"vmd", VMDAppMethods);
00082     return;
00083   }
00084 
00085   int argc=1;
00086   char *argv[1];
00087   argv[0] = Py_GetProgramFullPath();
00088   if (!VMDinitialize(&argc, (char ***) &argv)) {
00089     return;
00090   }
00091 
00092   // XXX this is a hack, and it would be better to tie this into 
00093   //     VMDApp more directly at some later point, but the regular
00094   //     VMD startup code is similarly lame, so we'll use it for now.
00095   const char *disp = getenv("VMDDISPLAYDEVICE");
00096   if (!disp) disp="text";
00097 
00098   int loc[2] = { 50, 50 };
00099   int size[2] = { 400, 400 };
00100   VMDgetDisplayFrame(loc, size);
00101 
00102   VMDApp *app = new VMDApp(1, argv);
00103   app->VMDinit(1, argv, disp, loc, size);
00104 
00105   // read application defaults
00106   VMDreadInit(app);
00107 
00108   // read user-defined startup files
00109   VMDreadStartup(app);
00110 
00111   set_vmdapp(app);
00112 
00113   // set my local static
00114   the_app = app;
00115 
00116   PyObject *vmdmodule = Py_InitModule((char *)"vmd", VMDAppMethods);
00117 
00118   initanimate();
00119   initatomsel();
00120   initaxes();
00121   initcolor();
00122   initdisplay();
00123   initgraphics();
00124   initimd();
00125   initlabel();
00126   initmaterial();
00127   initmolecule();
00128   initmolrep();
00129   initmouse();
00130   initrender();
00131   inittrans();
00132   initvmdmenu();
00133 
00134 #ifdef VMDNUMPY
00135   initvmdnumpy();
00136 #endif
00137 
00138   if (PyErr_Occurred()) return;
00139 
00140   static const char *modules[] = {
00141     "animate", "atomsel", "axes", "color", "display", "graphics",
00142     "imd", "label", "material", "molecule", "molrep", "mouse", 
00143     "render", "trans", "vmdmenu", "vmdnumpy"
00144   };
00145   for (unsigned i=0; i<sizeof(modules)/sizeof(const char *); i++) {
00146     const char *m = modules[i];
00147 #if (PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION < 5)
00148 #define CAST_HACK (char *)
00149 #else 
00150 #define CAST_HACK
00151 #endif
00152     PyModule_AddObject(vmdmodule, CAST_HACK m, PyImport_ImportModule( CAST_HACK m));
00153   }
00154   event_tstate = PyThreadState_Get();
00155 #if defined(VMD_SHARED)
00156   PyOS_InputHook = vmd_input_hook;
00157 #endif
00158 }
00159 

Generated on Thu May 24 01:51:26 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002