pyremote.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  *
00005  * Gxsm Plugin Name: pyremote.C
00006  * ========================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* Please do not change the Begin/End lines of this comment section!
00029  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00030  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00031  * All "% PlugInXXX" commentary tags are mandatory
00032  * All "% OptPlugInXXX" tags are optional
00033  * --------------------------------------------------------------------------------
00034 % BeginPlugInDocuSection
00035 % PlugInDocuCaption: Python remote control
00036 % PlugInName: pyremote
00037 % PlugInAuthor: Stefan Schr\"oder
00038 % PlugInAuthorEmail: stefan_fkp@users.sf.net
00039 % PlugInMenuPath: Tools/Pyremote
00040 
00041 % PlugInDescription
00042  This plugin is an interface to an embedded Python
00043  Interpreter.
00044 
00045 % PlugInUsage
00046  Choose Pyremote from the \GxsmMenu{Tools} menu to execute your
00047  command script. In the appendix you will find a tutorial with
00048  examples and tips and tricks.
00049 
00050 % OptPlugInSection: Reference
00051 
00052 The following script shows you all commands that the emb-module supports:
00053 
00054 \begin{alltt}
00055 import emb
00056 print dir(emb)
00057 \end{alltt}
00058 
00059 The result will look like this:
00060 
00061 \begin{alltt}
00062 ['__doc__', '__name__', 'autodisplay', 'chmodea', 
00063 'chmodem', 'chmoden', 'chmodeno', 'chmodex', 
00064 'chview1d', 'chview2d', 'chview3d', 'da0', 'direct',
00065 'echo', 'gnuexport', 'gnuimport', 'load', 'log', 
00066 'logev', 'menupath', 'quick', 'save', 'saveas', 
00067 'scaninit', 'scanline', 'scanupdate', 'scanylookup', 
00068 'set', 'sleep', 'startscan', 'stopscan', 'unitbz', 
00069 'unitev', 'units', 'unitvolt', 'waitscan']
00070 \end{alltt}
00071 
00072 
00073 The following list shows a brief explanation of the commands, together with
00074 the signature (that is the type of arguments).
00075 
00076 '()' equals no argument. E.g. \verb+startscan()+
00077 
00078 '(N)' equals one Integer arument. E.g. \verb+chview1d(2)+
00079 
00080 '(X)' equals one Float argument. No example.
00081 
00082 '(S)' equals a string. Often numbers are evaluated as strings first. Like
00083 in \verb+set("RangeX", "234.12")+
00084 
00085 '(S,N)' equals two parameters. E.g. \verb+gnuexport("myfilename.nc", 1)+
00086 
00087 \begin{tabular}{ll} \hline
00088 Scan operation\\ 
00089 \texttt{startscan() }   &       Start a scan.\\ 
00090 \texttt{stopscan() }    &       Stop scanning.\\
00091 \texttt{waitscan}       &       is commented out in app\_remote.C\\
00092 \texttt{initscan() }    &       only initialize.\\
00093 \texttt{scanupdate() }  &       Set hardware parameters on DSP.\\
00094 \texttt{setylookup(N,X)}&       ?\\
00095 \texttt{scanline}       &       Not implemented.\\ \hline
00096 File operation\\
00097 \texttt{save() }        &       Save all.\\
00098 \texttt{saveas(S,N) }    &       Save channel N with filename S.\\
00099 \texttt{load(S,N)   }    &       Load file S to channel N.\\  
00100 \texttt{gnuimport(S,N) } &       Import file S to channel N.\\
00101 \texttt{gnuexport(S,N) } &       Export channel N to file S.\\ \hline
00102 Channel operation\\
00103 \texttt{chmodea(N)}      &       Set channel(N) as active.\\   
00104 \texttt{chmodex(N)}      &       Set channel(N) to X.\\        
00105 \texttt{chmodem(N)}      &       Set channel(N) to Math.\\     
00106 \texttt{chmoden(N),N}    &       Set channel(N) to mode(N).\\   
00107 \texttt{chmodeno(N)}     &       Set channel(N) to mode 'No'.\\
00108 \texttt{chview1d(N)}     &       View channel(N) in 1d-mode.\\
00109 \texttt{chview2d(N)}     &       View channel(N) in 2d-mode.\\
00110 \texttt{chview3d(N)}     &       View channel(N) in 3d-mode.\\ \hline
00111 Views\\
00112 \texttt{autodisplay()}  &       Autodisplay.\\ 
00113 \texttt{quick()}        &       Set active display to quickview.\\ 
00114 \texttt{direct()}       &       Set active display to directview.\\
00115 \texttt{log()}          &       Set active display to logview.\\ \hline
00116 Units\\
00117 \texttt{unitbz() }      &       Set units to BZ.\\  
00118 \texttt{unitvolt()}     &       Set units to Volt.\\
00119 \texttt{unitev()}       &       Set units to eV.\\
00120 \texttt{units()}        &       Set units to S.\\ \hline
00121 Others\\
00122 \texttt{set(S,S) }      &       Set parameter to value.\\
00123 \texttt{echo(S)  }      &       Print S to console.\\
00124 \texttt{logev(S) }      &       Print S to logfile.\\
00125 \texttt{sleep(N) }      &       Sleep N/10 seconds.\\
00126 \texttt{da0(X)   }      &       Set Analog Output channel 0 to X Volt. (not implemented).\\
00127 \texttt{menupath(S)}    &       Activate Menuentry 'S'\\
00128 \end{tabular}
00129 
00130 % OptPlugInSubSection: The set-command
00131 
00132 The set command can modify the following parameters:
00133 
00134 \begin{tabular}{ll}
00135 \texttt{ACAmp} & \texttt{ACFrq} \\
00136 \texttt{ACPhase} & \texttt{} \\
00137 \texttt{CPShigh} & \texttt{CPSlow} \\ 
00138 \texttt{Counter} & \texttt{Energy} \\ 
00139 \texttt{Gatetime} & \texttt{Layers} \\
00140 \texttt{LengthX} & \texttt{LengthY} \\
00141 \texttt{Offset00X} & \texttt{Offset00Y} \\
00142 \texttt{OffsetX} & \texttt{OffsetY} \\
00143 \texttt{PointsX} & \texttt{PointsY} \\
00144 \texttt{RangeX} & \texttt{RangeY} \\
00145 \texttt{Rotation} & \texttt{} \\
00146 \texttt{StepsX} & \texttt{StepsY} \\   
00147 \texttt{SubSmp} & \texttt{VOffsetZ} \\ 
00148 \texttt{VRangeZ} & \texttt{ValueEnd} \\
00149 \texttt{ValueStart} & \texttt{nAvg} \\
00150 \end{tabular}
00151 
00152 These parameters are case-sensitive.
00153 To help the python remote programmer to figure out the correct
00154 set-names of all remote enabled entry fields a nifty option
00155 was added to the Help menu to show tooltips with the correct "remote set name"
00156 if the mouse is hovering overthe entry.
00157 
00158 % OptPlugInSubSection: Menupath and Plugins
00159 
00160 Any plugin, that has a menuentry can be
00161 executed via the
00162 \GxsmTT{menupath}-command. Several of them, however, open a dialog and ask
00163 for a specific parameter, e.g. the diff-PI in \GxsmMenu{Math/Filter1D}.  
00164 This can become annoying, when you want to batch process a greater number
00165 of files. To execute a PI non-interactively it is possible to 
00166 call a plugin from scripts with default parameters and no user interaction.
00167 
00168 The \GxsmTT{diff}-PI can be called like this:
00169 
00170 \begin{alltt}
00171 import emb
00172 print "Welcome to Python."
00173 emb.logev('my logentry')
00174 emb.startscan()
00175 emb.action('diff_PI')
00176 \end{alltt}
00177 
00178 The \GxsmTT{diff}- and \GxsmTT{smooth}-function are, at the time of this
00179 writing, the only Math-PI, that have such an 'action'-callback. Others 
00180 will follow. See \GxsmFile{diff.C} to find out, how to extend your
00181 favourite PI with action-capabilities.
00182 
00183 The action-command can execute the following PI:
00184 
00185 \begin{tabular}{ll}
00186 \GxsmTT{diff\_PI} & kernel-size set to 5+1\\  
00187 \GxsmTT{smooth\_PI} & kernel-size set to 5+1\\
00188 \GxsmTT{print\_PI} & defaults are read from gconf\\
00189 \end{tabular}
00190 
00191 % OptPlugInSubSection: DSP-Control
00192 
00193 The DSP-Control is the heart of SPM activity. The following parameters
00194 can be set with \GxsmTT{set}. (DSP2 commands are available in Gxsm 2 only)
00195 
00196 \begin{tabular}{ll}
00197 \GxsmTT{DSP\_CI} & \GxsmTT{DSP2\_CI} \\
00198 \GxsmTT{DSP\_CP} & \GxsmTT{DSP2\_CP} \\
00199 \GxsmTT{DSP\_CS} & \GxsmTT{DSP2\_CS} \\
00200 \GxsmTT{DSP\_I} & \GxsmTT{DSP2\_I} \\
00201 \GxsmTT{DSP\_MoveLoops} & \GxsmTT{DSP2\_MoveLoops} \\
00202 \GxsmTT{DSP\_MoveSpd} & \GxsmTT{DSP2\_MoveSpd} \\
00203 \GxsmTT{DSP\_NAvg} & \GxsmTT{DSP2\_NAvg} \\
00204 \GxsmTT{DSP\_Pre} & \GxsmTT{DSP2\_Pre} \\
00205 \GxsmTT{DSP\_ScanLoops} & \GxsmTT{DSP2\_ScanLoops} \\
00206 \GxsmTT{DSP\_ScanSpd} & \GxsmTT{DSP2\_ScanSpd} \\
00207 \GxsmTT{DSP\_SetPoint} & \GxsmTT{DSP2\_SetPoint} \\
00208 \GxsmTT{DSP\_U} & \GxsmTT{DSP2\_U} \\
00209 \end{tabular}
00210 
00211 % OptPlugInSubSection: Peakfinder
00212 
00213 Another plugin allows remote control. The plugin-functions are commonly
00214 executed by a call of the \GxsmTT{action}-command. It is
00215 \GxsmFile{Peakfinder}:
00216 
00217 DSP Peak Find Plugin Commandset for the SPA-LEED peak finder:\\
00218 
00219 \begin{tabular}{lllll}
00220 \Mcol{Commands Plugin \filename{DSP Peak Find}:}\\ \\ \hline  
00221 Cmd & Arg. & \multicolumn{2}{l}{Values} & Description\\ \hline
00222 \hline
00223 action & DSPPeakFind\_XY0\_1 &&& Get fitted XY Position\\
00224 action & DSPPeakFind\_OffsetFromMain\_1 &&& Get Offset from Main\\
00225 action & DSPPeakFind\_OffsetToMain\_1 &&& Put Offset to Main\\
00226 action & DSPPeakFind\_EfromMain\_1 &&& Get Energy from Main\\
00227 action & DSPPeakFind\_RunPF\_1 &&& Run Peak Finder\\
00228 \hline
00229 action & DSPPeakFind\_XXX\_N &&& run action XXX (see above)\\
00230        &                    &&& on PF Folder N\\
00231 \end{tabular}
00232 
00233 The call is equivalent to the example above.
00234 
00235 % OptPlugInConfig
00236 Right now this plugin cannot be configured. The script that will be executed
00237 must be called \GxsmFile{remote.py}. The module with GXSM internal commands 
00238 is called \GxsmFile{emb}.
00239 
00240 To find the Python-script \GxsmFile{remote.py}, the environment-variable
00241 PYTHONPATH is evaluated. If it is not expliticly declared, GXSM will set
00242 PYTHONPATH to your current working directory. This is equivalent to the
00243 following call:
00244 
00245 \begin{alltt}
00246 $export PYTHONPATH='.'
00247 $gxsm2
00248 \end{alltt}
00249 
00250 Thus, the script in your current working directory will be found.
00251 
00252 If you want to put your script somewhere else than into the
00253 current directory, modify the environment variable
00254 \GxsmFile{PYTHONPATH}. Python
00255 will look into all directories, that are stored there.
00256 
00257 \begin{alltt}
00258 $export PYTHONPATH='/some/obscure/path/'
00259 $gxsm
00260 \end{alltt}
00261 
00262 Or you can link it from somewhere else. Or you can create a one line script,
00263 that executes another script or several scripts. Do whatever you like.
00264 
00265 
00266 % OptPlugInFiles
00267  Python precompiles your remote.py to remote.pyc. You can safely remove the
00268 file remote.pyc file at any time, Python will regenerate it upon start of
00269 the interpreter.
00270 
00271 % OptPlugInRefs
00272 See the appendix for more information. Don't know Python? Visit 
00273 \GxsmTT{python.org}.
00274 
00275 % OptPlugInKnownBugs
00276 
00277 The error handling is only basic. Your script may run if you give
00278 wrong parameters but not deliver the wanted results. You can crash
00279 Gxsm or even X! E.g. by selecting an illegal channel. Remember that channel
00280 counting in the scripts begins with 0. Gxsm's channel numbering begins with 1.
00281 
00282 The embedded functions return $-1$ as error value. It's a good idea
00283 to attach \texttt{print} to critical commands to check this.
00284 
00285 The \verb+remote_echo+ command is implemented via debug printing.
00286 Using Pythons \texttt{print} is recommended.
00287 
00288 The view functions \GxsmFile{quick}, \GxsmFile{direct}, \GxsmFile{log}  
00289 change the viewmode, but not the button in the main window, don't be
00290 confused.
00291 
00292 The waitscan and da0 function are not yet implemented and likely will never
00293 be. Priority: Very low.
00294 
00295 The library detection during compilation is amateurish. Needs work. 
00296 
00297 Python will check for the
00298 right type of your arguments. Remember, that all values in \GxsmTT{set} are strings
00299 and have to be quoted. Additionaly care for the case sensitivity.
00300 
00301 If you you want to pause script execution, use the embedded sleep command
00302 \GxsmTT{emb.sleep()} and not \GxsmTT{time.sleep()}, because the function from
00303 the time library will freeze GXSM totally during the sleep. 
00304 (This is not a bug, it's a feature.)
00305 
00306 % OptPlugInNotes
00307 TODO: Add more action-handlers in Math-PI.
00308 % and clean up inconsistent use of spaces and tabs.
00309 
00310 % OptPlugInHints
00311 If you write a particularly interesting remote-script, please give it back
00312 to the community. The GXSM-Forums always welcome input.
00313 
00314 % EndPlugInDocuSection
00315  * -------------------------------------------------------------------------------- 
00316  */
00317 
00318 
00319 #include <gtk/gtk.h>
00320 #include "config.h"
00321 #include "gxsm/plugin.h"
00322 
00323 /* This plugin was initially developed with Python 2.1, but
00324 it should run with Python 2.2, 2.3
00325 
00326 This must be done more elegantly, but had no time yet to think it
00327 over:
00328 */
00329  #ifdef HAVE_PYTHON2_1_PYTHON_H
00330  #include <python2.1/Python.h>
00331  #endif
00332  
00333  #ifdef HAVE_PYTHON2_2_PYTHON_H
00334  #include <python2.2/Python.h>
00335  #endif
00336 
00337  #ifdef HAVE_PYTHON2_3_PYTHON_H
00338  #include <python2.3/Python.h>
00339  #endif
00340 
00341  #ifdef HAVE_PYTHON2_4_PYTHON_H
00342  #include <python2.4/Python.h>
00343  #endif
00344 
00345 #include <sys/types.h>
00346 #include <signal.h>
00347 
00348 #include "action_id.h"
00349 #include "xsmtypes.h"
00350 
00351 //#include "app_remote.h"
00352 #include "pyremote.h"
00353 
00354 // Plugin Prototypes
00355 static void pyremote_init( void );
00356 static void pyremote_about( void );
00357 static void pyremote_configure( void );
00358 static void pyremote_cleanup( void );
00359 static void pyremote_run(GtkWidget *w, void *data);
00360 
00361 // Fill in the GxsmPlugin Description here
00362 GxsmPlugin pyremote_pi = {
00363   NULL,                   // filled in and used by Gxsm, don't touch !
00364   NULL,                   // filled in and used by Gxsm, don't touch !
00365   0,                      // filled in and used by Gxsm, don't touch !
00366   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00367                           // filled in here by Gxsm on Plugin load, 
00368                           // just after init() is called !!!
00369   // ----------------------------------------------------------------------
00370   // Plugins Name, CodeStly is like: Name-M1S[ND]|M2S-BG|F1D|F2D|ST|TR|Misc
00371   "Pyremote",
00372   NULL,
00373   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00374   "Remote control",
00375   // Author(s)
00376   "Stefan Schroeder",
00377   // Menupath to position where it is appended to
00378   "_Tools/",
00379   // Menuentry
00380   N_("Pyremote"),
00381   // help text shown on menu
00382   N_("Python Remote Control."),
00383   // more info...
00384   "See Manual.",
00385   NULL,          // error msg, plugin may put error status msg here later
00386   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00387   // init-function pointer, can be "NULL", 
00388   // called if present at plugin load
00389   pyremote_init,  
00390   // query-function pointer, can be "NULL", 
00391   // called if present after plugin init to let plugin manage it install itself
00392   NULL, // query should be "NULL" for Gxsm-Math-Plugin !!!
00393   // about-function, can be "NULL"
00394   // can be called by "Plugin Details"
00395   pyremote_about,
00396   // configure-function, can be "NULL"
00397   // can be called by "Plugin Details"
00398   pyremote_configure,
00399   // run-function, can be "NULL", if non-Zero and no query defined, 
00400   // it is called on menupath->"plugin"
00401   pyremote_run, // run should be "NULL" for Gxsm-Math-Plugin !!!
00402   // cleanup-function, can be "NULL"
00403   // called if present at plugin removeal
00404   pyremote_cleanup
00405 };
00406 
00407 // Text used in Aboutbox, please update!!a
00408 static const char *about_text = N_("Gxsm Plugin\n\n"
00409                                    "Python Remote Control.");
00410 
00411 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00412 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00413   pyremote_pi.description = g_strdup_printf(N_("Gxsm pyremote plugin %s"), VERSION);
00414   return &pyremote_pi; 
00415 }
00416 
00417 // 5.) Start here with the plugins code, vars def., etc.... here.
00418 // ----------------------------------------------------------------------
00419 //
00420 
00421 
00422 // TODO: 
00423 // more error-handling
00424 // cannot return int in run
00425 // fktname editable in preferences.
00426 // add numeric interface (LOW)
00427 // add image interface (LOW)
00428 // add i/o possibility (LOW)
00429 
00430 // init-Function
00431 static void pyremote_init(void)
00432 {
00433     /* Python will search for remote.py in the directories, defined 
00434        by PYTHONPATH. */
00435     PI_DEBUG(DBG_L2, "pyremote Plugin Init");
00436     if (!getenv("PYTHONPATH")){
00437         PI_DEBUG(DBG_L2, "pyremote: PYTHONPATH is not set.");
00438         PI_DEBUG(DBG_L2, "pyremote: Setting to '.'");
00439         setenv("PYTHONPATH", ".", 0);
00440     }
00441 }
00442 
00443 // about-Function
00444 static void pyremote_about(void)
00445 {
00446     const gchar *authors[] = { pyremote_pi.authors, NULL};
00447     gtk_widget_show(gnome_about_new ( pyremote_pi.name,
00448                                       VERSION,
00449                                       N_("(C) 2000 the Free Software Foundation"),
00450                                       about_text,
00451                                       authors,
00452                                       NULL,NULL,NULL
00453                         ));
00454 }
00455 
00456 // configure-Function
00457 static void pyremote_configure(void)
00458 {
00459     if(pyremote_pi.app)
00460         pyremote_pi.app->message("Pyremote Plugin Configuration");
00461 }
00462 
00463 // cleanup-Function
00464 static void pyremote_cleanup(void)
00465 {
00466     PI_DEBUG(DBG_L2, "Pyremote Plugin Cleanup");
00467 }
00468 
00469 #ifdef Py_PYTHON_H
00470 
00471 // BLOCK I
00472 // This block is highly gefrickelt.
00473 // grep AddEntry2RemoteList src/*.C
00474 // ACAmp
00475 // ACFrq
00476 // ACPhase
00477 // CPShigh
00478 // CPSlow
00479 // Energy
00480 // Gatetime
00481 // Layers
00482 // LengthX
00483 // LengthY
00484 // Offset00X
00485 // Offset00Y
00486 // OffsetX
00487 // OffsetY
00488 // PointsX
00489 // PointsY
00490 // RangeX
00491 // RangeY
00492 // Rotation
00493 // StepsX
00494 // StepsY
00495 // SubSmp
00496 // VOffsetZ
00497 // VRangeZ
00498 // ValueEnd
00499 // ValueStart
00500 // nAvg
00501 
00502 /* stolen from app_remote.C */
00503 static void Check_ec(Gtk_EntryControl* ec, gpointer arglist){
00504     ec->CheckRemoteCmd((gchar **)arglist);
00505 };
00506 
00507 static void CbAction_ra(remote_action_cb* ra, gpointer arglist){
00508     if(ra->cmd && ((gchar**)arglist)[1])
00509         if(! strcmp(((gchar**)arglist)[1], ra->cmd)){
00510 //            (*ra->RemoteCb) (ra->widget, ra->data);
00511             (*ra->RemoteCb) (ra->widget, arglist);
00512 // see above and pcs.h
00513         }
00514 };
00515 
00516 static PyObject* remote_set(PyObject *self, PyObject *args)
00517 {
00518     PI_DEBUG(DBG_L2, "pyremote: Setting ");
00519     gchar *parameter, *value;
00520 
00521     if (!PyArg_ParseTuple(args, "ss", &parameter, &value))
00522         return Py_BuildValue("i", -1);
00523 
00524     PI_DEBUG(DBG_L2, parameter << " to " << value );
00525 
00526     gchar *line3[] ={"set", parameter, value};
00527 
00528     g_slist_foreach(gapp->RemoteEntryList, (GFunc) Check_ec, (gpointer)line3);
00529 
00530     return Py_BuildValue("i", 0);
00531 }
00532 
00533 static PyObject* remote_action(PyObject *self, PyObject *args)
00534 {
00535     PI_DEBUG(DBG_L2, "pyremote: Action ") ;
00536     gchar *parameter, *value = "5.0";
00537 
00538     if (!PyArg_ParseTuple(args, "s|s", &parameter, &value))
00539         return Py_BuildValue("i", -1);
00540 
00541     PI_DEBUG(DBG_L2, parameter );
00542 
00543     PI_DEBUG(DBG_L2, "value:" << value);
00544 
00545     gchar *line3[] ={"action", parameter, value};
00546 
00547     g_slist_foreach(gapp->RemoteActionList, (GFunc) CbAction_ra, (gpointer)line3);
00548 
00549     return Py_BuildValue("i", 0);
00550 }
00551 
00553 // BLOCK II
00554 // startscan .          DONE
00555 // stopscan .           DONE
00556 // waitscan             DONE is commented out in app_remote
00557 // initscan .           DONE
00558 // scanupdate .         DONE
00559 // setylookup N,X       DONE
00560 // scanline     N,N,N   DONE
00562 
00563 static PyObject* remote_startscan(PyObject *self, PyObject *args)
00564 {
00565     PI_DEBUG(DBG_L2, "pyremote: Starting scan");
00566     gapp->action_toolbar_callback(NULL, (void*)"Toolbar_Scan_Start");
00567     return Py_BuildValue("i", 0);
00568 }
00569 
00570 static PyObject* remote_stopscan(PyObject *self, PyObject *args)
00571 {
00572     PI_DEBUG(DBG_L2, "pyremote: Stopping scan");
00573     gapp->action_toolbar_callback(NULL, (void*)"Toolbar_Scan_Stop"); 
00574     return Py_BuildValue("i", 0);
00575 }
00576 
00577 static PyObject* remote_waitscan(PyObject *self, PyObject *args)
00578 {
00579     PI_DEBUG(DBG_L2, "pyremote: Wait scan: commented out");
00580 //      if( gapp->xsm->ScanInProgress() ){
00581 //              PI_DEBUG(DBG_L2, "pyremote: Scan is in progress ");
00582 //      }
00583 //      else{
00584 //              PI_DEBUG(DBG_L2, "pyremote: Scan is finished ");
00585 //      }
00586     return Py_BuildValue("i", 0);
00587 }
00588 
00589 static PyObject* remote_scaninit(PyObject *self, PyObject *args)
00590 {
00591     PI_DEBUG(DBG_L2, "pyremote: Initializing scan");
00592     gapp->action_toolbar_callback(NULL, (void*)"Toolbar_Scan_Init"); 
00593     return Py_BuildValue("i", 0);
00594 }
00595 
00596 static PyObject* remote_scanupdate(PyObject *self, PyObject *args)
00597 {
00598     PI_DEBUG(DBG_L2, "pyremote: Updating scan (hardware)");
00599     gapp->action_toolbar_callback(NULL, (void*)"Toolbar_Scan_UpdateParam"); 
00600     return Py_BuildValue("i", 0);
00601 }
00602 
00603 static PyObject* remote_scanylookup(PyObject *self, PyObject *args)
00604 {
00605     PI_DEBUG(DBG_L2, "pyremote: Scanylookup");
00606     int value1 = 0;
00607     double value2 = 0.0;
00608     if (!PyArg_ParseTuple(args, "ld", &value1, &value2))
00609         return Py_BuildValue("i", -1);
00610     PI_DEBUG(DBG_L2,  value1 << " and " << value2 );
00611     if(value1 && value2){
00612         gchar *cmd = NULL;
00613         cmd = g_strdup_printf ("2 %d %g", value1, value2);
00614         gapp->PutPluginData (cmd);
00615         gapp->action_toolbar_callback (NULL, (void*)"Toolbar_Scan_SetYLookup"); 
00616         g_free (cmd);
00617     }
00618     return Py_BuildValue("i", 0);
00619 }
00620 
00621 static PyObject* remote_scanline(PyObject *self, PyObject *args)
00622 {
00623     PI_DEBUG(DBG_L2, "pyremote: Scan line");
00624     int value1 = 0, value2 = 0, value3 = 0;
00625     if (!PyArg_ParseTuple(args, "lll", &value1, &value2, &value3))
00626         return Py_BuildValue("i", -1);
00627     PI_DEBUG(DBG_L2,  value1 << " and " << value2 << " and " << value3);
00628     PI_DEBUG(DBG_L2, "pyremote: Warning toolbar NYI");
00629     if(value1){
00630         gchar *cmd = NULL;
00631         if(value2 && value3){
00632             cmd = g_strdup_printf ("3 %d %d %d",
00633                                    value1, 
00634                                    value2,
00635                                    value3);
00636             gapp->PutPluginData (cmd);
00637             gapp->action_toolbar_callback (NULL,(void*)"Toolbar_Scan_Partial_Line");
00638         }
00639         else{
00640             cmd = g_strdup_printf ("d %d",
00641                                    value1); 
00642             gapp->PutPluginData (cmd);
00643             gapp->action_toolbar_callback (NULL, (void*)"Toolbar_Scan_Line"); 
00644         }
00645         g_free (cmd);
00646     }
00647     return Py_BuildValue("i", 0);
00648 }
00649 
00651 // BLOCK III
00652 // save .                       DONE
00653 // saveas S,N                   DONE
00654 // load S,N                     DONE
00655 // gnuimport S,N                DONE
00656 // gnuexport S,N                DONE
00657 // renamed import and export to avoid nameclash in python.
00659 
00660 static PyObject* remote_save(PyObject *self, PyObject *args)
00661 {
00662     PI_DEBUG(DBG_L2, "pyremote: Save");
00663     gapp->xsm->save (TRUE);
00664     return Py_BuildValue("i", 0);
00665 }
00666 
00667 static PyObject* remote_saveas(PyObject *self, PyObject *args)
00668 {
00669     PI_DEBUG(DBG_L2, "pyremote: Save As ");
00670     gchar* zeile;
00671     long channel = 0;
00672     if (!PyArg_ParseTuple(args, "sl", &zeile, &channel))
00673         return Py_BuildValue("i", -1);
00674     PI_DEBUG(DBG_L2, zeile << " to Channel " << channel );
00675     if(zeile && channel)
00676         gapp->xsm->save(TRUE, zeile, channel);
00677     return Py_BuildValue("i", 0);
00678 }
00679 
00680 static PyObject* remote_load(PyObject *self, PyObject *args)
00681 {
00682     PI_DEBUG(DBG_L2, "pyremote: Loading ");
00683     gchar* zeile;
00684     long channel = 0;
00685     if (!PyArg_ParseTuple(args, "si", &zeile, &channel))
00686         return Py_BuildValue("i", -1);;
00687     PI_DEBUG(DBG_L2, zeile << " to Channel " << channel );
00688     if(zeile && channel){
00689         gapp->xsm->ActivateChannel( channel );
00690         gapp->xsm->load( zeile );
00691     }
00692     return Py_BuildValue("i", 0);
00693 }
00694 
00695 static PyObject* remote_import(PyObject *self, PyObject *args)
00696 {
00697     PI_DEBUG(DBG_L2, "pyremote: Importing ");
00698     gchar* zeile;
00699     long channel = 0;
00700     if (!PyArg_ParseTuple(args, "sl", &zeile, &channel))
00701         return Py_BuildValue("i", -1);
00702     PI_DEBUG(DBG_L2,  zeile << " to Channel " << channel);
00703     if(zeile && channel){
00704         gapp->xsm->ActivateChannel( channel );
00705         gapp->xsm->load( zeile );
00706     }
00707     return Py_BuildValue("i", 0);
00708 }
00709 
00710 static PyObject* remote_export(PyObject *self, PyObject *args)
00711 {
00712     PI_DEBUG(DBG_L2, "pyremote: Exporting ");
00713     gchar* zeile;
00714     long channel = 0;
00715     if (!PyArg_ParseTuple(args, "sl", &zeile, &channel))
00716         return Py_BuildValue("i", -1);
00717     PI_DEBUG(DBG_L2, zeile << " to Channel " << channel);
00718     if(zeile && channel){
00719         gapp->xsm->ActivateChannel( channel );
00720         gapp->xsm->gnuexport( zeile );
00721     }
00722 
00723     return Py_BuildValue("i", 0);
00724 }
00725 
00727 // BLOCK IV
00728 // autodisp .                   DONE
00729 // chmodea N                    DONE
00730 // chmodex N                    DONE
00731 // chmodem N                    DONE
00732 // chmoden N,N                  DONE
00733 // chmodeno N                   DONE
00734 // chview1d N                   DONE
00735 // chview2d N                   DONE
00736 // chview3d N                   DONE
00737 // quick .                      DONE
00738 // direct .                     DONE
00739 // log .                        DONE
00741 
00742 static PyObject* remote_autodisplay(PyObject *self, PyObject *args)
00743 {
00744     PI_DEBUG(DBG_L2, "pyremote: Autodisplay");
00745     gapp->xsm->AutoDisplay();
00746     return Py_BuildValue("i", 0);
00747 }
00748 
00749 static PyObject* remote_chmodea(PyObject *self, PyObject *args)
00750 {
00751     PI_DEBUG(DBG_L2, "pyremote: Chmode a ");
00752     long channel = 0;
00753     if (!PyArg_ParseTuple(args, "l", &channel))
00754         return Py_BuildValue("i", -1);
00755     PI_DEBUG(DBG_L2,  channel);
00756     if (channel) 
00757         gapp->xsm->ActivateChannel( channel );
00758     return Py_BuildValue("i", 0);
00759 }
00760 
00761 static PyObject* remote_chmodex(PyObject *self, PyObject *args)
00762 {
00763     PI_DEBUG(DBG_L2, "pyremote: Chmode x ");
00764     long channel = 0;
00765     if (!PyArg_ParseTuple(args, "l", &channel))
00766         return Py_BuildValue("i", -1);
00767     PI_DEBUG(DBG_L2, channel );
00768     if (channel)
00769         gapp->xsm->SetMode( channel, ID_CH_M_X );
00770     return Py_BuildValue("i", 0);
00771 }
00772 
00773 static PyObject* remote_chmodem(PyObject *self, PyObject *args)
00774 {
00775     PI_DEBUG(DBG_L2, "pyremote: Chmode m ");
00776     long channel = 0;
00777     if (!PyArg_ParseTuple(args, "l", &channel))
00778         return Py_BuildValue("i", -1);
00779     PI_DEBUG(DBG_L2,  channel );
00780     if (channel)
00781         gapp->xsm->SetMode( channel, ID_CH_M_MATH );
00782     return Py_BuildValue("i", 0);
00783 }
00784 
00785 static PyObject* remote_chmoden(PyObject *self, PyObject *args)
00786 {
00787     PI_DEBUG(DBG_L2, "pyremote: Chmode n ");
00788     long channel = 0;
00789     long mode = 0;
00790     if (!PyArg_ParseTuple(args, "ll", &channel, &mode))
00791         return Py_BuildValue("i", -1);
00792     PI_DEBUG(DBG_L2, channel << " to " << mode );
00793     if (channel && mode)
00794         gapp->xsm->SetMode(channel, ID_CH_M_X+mode);
00795     return Py_BuildValue("i", 0);
00796 }
00797 
00798 static PyObject* remote_chmodeno(PyObject *self, PyObject *args)
00799 {
00800     PI_DEBUG(DBG_L2, "pyremote: Chmode no ");
00801     long channel = 0;
00802     if (!PyArg_ParseTuple(args, "l", &channel))
00803         return Py_BuildValue("i", -1);
00804     PI_DEBUG(DBG_L2, channel );
00805     if (channel)
00806         gapp->xsm->SetView( channel, ID_CH_V_NO );
00807     return Py_BuildValue("i", 0);
00808 }
00809 
00810 static PyObject* remote_chview1d(PyObject *self, PyObject *args)
00811 {
00812     PI_DEBUG(DBG_L2, "pyremote: Chview 1d.");
00813     long channel;
00814     if (!PyArg_ParseTuple(args, "l", &channel))
00815         return Py_BuildValue("i", -1);
00816     PI_DEBUG(DBG_L2, channel );
00817     if (channel)
00818         gapp->xsm->SetView( channel, ID_CH_V_PROFILE );
00819     return Py_BuildValue("i", 0);
00820 }
00821 
00822 static PyObject* remote_chview2d(PyObject *self, PyObject *args)
00823 {
00824     PI_DEBUG(DBG_L2, "pyremote: Chview 2d");
00825     long channel;
00826     if (!PyArg_ParseTuple(args, "l", &channel))
00827         return Py_BuildValue("i", -1);
00828     PI_DEBUG(DBG_L2, channel );
00829     if (channel)
00830         gapp->xsm->SetView( channel, ID_CH_V_GREY );
00831     return Py_BuildValue("i", 0);
00832 }
00833 
00834 static PyObject* remote_chview3d(PyObject *self, PyObject *args)
00835 {
00836     PI_DEBUG(DBG_L2, "pyremote: Chview 3d.");
00837     long channel;
00838     if (!PyArg_ParseTuple(args, "l", &channel))
00839         return Py_BuildValue("i", -1);
00840     PI_DEBUG(DBG_L2, channel );
00841     if (channel)
00842         gapp->xsm->SetView( channel, ID_CH_V_SURFACE );
00843     return Py_BuildValue("i", 0);
00844 }
00845 
00846 static PyObject* remote_quick(PyObject *self, PyObject *args)
00847 {
00848     PI_DEBUG(DBG_L2, "pyremote: Quick");
00849     gapp->xsm->SetVM(SCAN_V_QUICK);
00850     return Py_BuildValue("i", 0);
00851 }
00852 
00853 static PyObject* remote_direct(PyObject *self, PyObject *args)
00854 {
00855     PI_DEBUG(DBG_L2, "pyremote: Direkt");
00856     gapp->xsm->SetVM(SCAN_V_DIRECT);
00857     return Py_BuildValue("i", 0);
00858 }
00859 
00860 static PyObject* remote_log(PyObject *self, PyObject *args)
00861 {
00862     PI_DEBUG(DBG_L2, "pyremote: Log");
00863     gapp->xsm->SetVM(SCAN_V_LOG);
00864     return Py_BuildValue("i", 0);
00865 }
00866 
00868 // BLOCK V
00869 // unitbz .     DONE
00870 // unitvolt .   DONE
00871 // unitev .     DONE
00872 // units .      DONE
00874 
00875 static PyObject* remote_unitbz(PyObject *self, PyObject *args)
00876 {
00877     PI_DEBUG(DBG_L2, "pyremote: unitbz");
00878     gapp->xsm->SetModeFlg(MODE_BZUNIT);
00879     gapp->xsm->ClrModeFlg(MODE_VOLTUNIT);
00880     return Py_BuildValue("i", 0);
00881 }
00882 static PyObject* remote_unitvolt(PyObject *self, PyObject *args)
00883 {
00884     PI_DEBUG(DBG_L2, "pyremote: unitvolt");
00885     gapp->xsm->SetModeFlg(MODE_VOLTUNIT);
00886     gapp->xsm->ClrModeFlg(MODE_BZUNIT);
00887     return Py_BuildValue("i", 0);
00888 }
00889 static PyObject* remote_unitev(PyObject *self, PyObject *args)
00890 {
00891     PI_DEBUG(DBG_L2, "pyremote: unitev");
00892     gapp->xsm->SetModeFlg(MODE_ENERGY_EV);
00893     gapp->xsm->ClrModeFlg(MODE_ENERGY_S);
00894     return Py_BuildValue("i", 0);
00895 }
00896 static PyObject* remote_units(PyObject *self, PyObject *args)
00897 {
00898     PI_DEBUG(DBG_L2, "pyremote: units");
00899     gapp->xsm->SetModeFlg(MODE_ENERGY_S);
00900     gapp->xsm->ClrModeFlg(MODE_ENERGY_EV);
00901     return Py_BuildValue("i", 0);
00902 }
00903 
00905 // BLOCK VI
00906 // echo S                       DONE
00907 // logev S                      DONE
00908 // da0 X                        DONE, commented out
00909 // menupath S                   DONE
00910 // more actions by plugins S    NYI
00912 
00913 static PyObject* remote_echo(PyObject *self, PyObject *args)
00914 {
00915 
00916     PI_DEBUG(DBG_L2, "pyremote: Echo.");
00917     gchar* line1;
00918     if (!PyArg_ParseTuple(args, "s", &line1))
00919         return Py_BuildValue("i", -1);
00920     /*Change the Debuglevel to: print always.*/
00921     PI_DEBUG(DBG_EVER, line1 );
00922     return Py_BuildValue("i", 0);
00923 }
00924 
00925 static PyObject* remote_logev(PyObject *self, PyObject *args)
00926 {
00927 
00928     PI_DEBUG(DBG_L2, "pyremote: Log ev.");
00929     gchar* zeile;
00930     if (!PyArg_ParseTuple(args, "s", &zeile))
00931         return Py_BuildValue("i", -1);
00932     if(zeile){
00933         gapp->monitorcontrol->LogEvent("RemoteLogEv", zeile);
00934     }else{
00935         gapp->monitorcontrol->LogEvent("RemoteLogEv", "--");
00936     }
00937     return Py_BuildValue("i", 0);
00938 }
00939 
00940 static PyObject* remote_da0(PyObject *self, PyObject *args)
00941 {
00942 
00943     PI_DEBUG(DBG_L2, "pyremote: da0 ");
00944     double channel;
00945     if (!PyArg_ParseTuple(args, "d", &channel))
00946         return Py_BuildValue("i", -1);
00947     if (channel){
00948         PI_DEBUG(DBG_L2, "Commented out.");
00949         //gapp->xsm->hardware->SetAnalog("da-name", channel);
00950     }
00951     return Py_BuildValue("i", 0);
00952 }
00953 
00954 static PyObject* remote_menupath(PyObject *self, PyObject *args)
00955 {
00956 
00957     PI_DEBUG(DBG_L2, "pyremote: Searching menupath ");
00958     gchar *menu1;
00959     if (!PyArg_ParseTuple(args, "s", &menu1))
00960         return Py_BuildValue("i", -1);
00961     PI_DEBUG(DBG_L2, menu1 );
00962     GtkWidget *menushell;
00963     GtkWidget *menuitem;
00964     gint pos;
00965     menushell = gnome_app_find_menu_pos (gapp->gxsmmenu, menu1, &pos);
00966     --pos;
00967     if (!menushell) 
00968         return 0;
00969     PI_DEBUG(DBG_L2, "pyremote: Menu Shell Found: " << pos << " Item=" << menushell);
00970     
00971     menuitem = (GtkWidget*)g_list_nth_data(GTK_MENU_SHELL (menushell) -> children, pos);
00972     
00973     if (!menuitem) 
00974         return 0;
00975     PI_DEBUG(DBG_L2, "pyremote: Menu Item Found: " << menuitem);
00976     
00977     GdkEvent event;
00978     gint return_val;
00979     gtk_signal_emit (GTK_OBJECT(GTK_MENU_ITEM (menuitem) ), 
00980                      gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (GTK_OBJECT(menuitem))),
00981                      &event, &return_val);
00982     
00983 //    PI_DEBUG(DBG_L2, "pyremote: Signal emitted to pos " << pos << " ! ret=" << return_val);
00984 
00985     return Py_BuildValue("i", 0);
00986 }
00987 
00988 
00989 
00990 /* stolen from somewhere*/
00991 static gboolean busy_sleep;
00992 gint ret_false()
00993 {
00994   gtk_main_quit();
00995   return FALSE;
00996 }
00997 
00998 void sleep_ms(int ms)
00999 {
01000   if (busy_sleep) return;          /* Don't allow more than 1 sleep_ms */
01001   busy_sleep=TRUE;
01002   gtk_timeout_add(ms,(GtkFunction)ret_false,0); /* Start time-out function*/
01003   gtk_main();                             /* wait */
01004   busy_sleep=FALSE;
01005 }
01006 
01007 static PyObject* remote_sleep(PyObject *self, PyObject *args)
01008 {
01009     PI_DEBUG(DBG_L2, "pyremote: Sleep ");
01010     long l;
01011     if (!PyArg_ParseTuple(args, "l", &l))
01012       return Py_BuildValue("i", -1);
01013     if (l){
01014         sleep_ms(l*100);
01015     }
01016     return Py_BuildValue("i", 0);
01017 }
01018 
01020 
01021 static PyMethodDef EmbMethods[] = {
01022     // BLOCK I
01023     {"set", remote_set, METH_VARARGS, "Set."},
01024     {"action", remote_action, METH_VARARGS, "Action."},
01025 
01026     // BLOCK II
01027     {"startscan", remote_startscan, METH_VARARGS, "Start Scan."},
01028     {"stopscan", remote_stopscan, METH_VARARGS, "Stop Scan."},
01029     {"waitscan", remote_waitscan, METH_VARARGS, "Wait Scan."},
01030     {"scaninit", remote_scaninit, METH_VARARGS, "Scaninit."},
01031     {"scanupdate", remote_scanupdate, METH_VARARGS, "Scanupdate."},
01032     {"scanylookup", remote_scanylookup, METH_VARARGS, "Scanylookup."},
01033     {"scanline", remote_scanline, METH_VARARGS, "Scan line."},
01034 
01035     // BLOCK III
01036     {"save", remote_save, METH_VARARGS, "Save."},
01037     {"saveas", remote_saveas, METH_VARARGS, "Save As."},
01038     {"load", remote_load, METH_VARARGS, "Load."},
01039     {"gnuexport", remote_export, METH_VARARGS, "Export."},
01040     {"gnuimport", remote_import, METH_VARARGS, "Import."},
01041 
01042     // BLOCK IV
01043     {"autodisplay", remote_autodisplay, METH_VARARGS, "Autodisplay."},
01044     {"chmodea", remote_chmodea, METH_VARARGS, "Chmode A."},
01045     {"chmodex", remote_chmodex, METH_VARARGS, "Chmode X."},
01046     {"chmodem", remote_chmodem, METH_VARARGS, "Chmode M."},
01047     {"chmoden", remote_chmoden, METH_VARARGS, "Chmode N."},
01048     {"chmodeno", remote_chmodeno, METH_VARARGS, "Chmode No."},
01049     {"chview1d", remote_chview1d, METH_VARARGS, "Chview 1d."},
01050     {"chview2d", remote_chview2d, METH_VARARGS, "Chview 2d."},
01051     {"chview3d", remote_chview3d, METH_VARARGS, "Chview 3d."},
01052     {"quick", remote_quick, METH_VARARGS, "Quick."},
01053     {"direct", remote_direct, METH_VARARGS, "Direct."},
01054     {"log", remote_log, METH_VARARGS, "Log."},
01055 
01056     // BLOCK V
01057     {"unitbz", remote_unitbz, METH_VARARGS, "UnitBZ."},
01058     {"unitvolt", remote_unitvolt, METH_VARARGS, "UnitVolt."},
01059     {"unitev", remote_unitev, METH_VARARGS, "UniteV."},
01060     {"units", remote_units, METH_VARARGS, "UnitS."},
01061 
01062     // BLOCK VI
01063     {"echo", remote_echo, METH_VARARGS, "Echo. "},
01064     {"logev", remote_logev, METH_VARARGS, "Logev. "},
01065     {"da0", remote_da0, METH_VARARGS, "Da0. "},
01066     {"menupath", remote_menupath, METH_VARARGS, "Menupath. "},
01067     {"sleep", remote_sleep, METH_VARARGS, "Sleep. "},
01068 
01069     {NULL, NULL, 0, NULL}
01070 };
01071 
01072 
01073 int ok_button_callback( GtkWidget *widget, gpointer data)
01074 {
01075 //    cout << getpid() << endl;
01076     kill (getpid(), SIGINT); 
01077 //    cout << "pressed" <<endl;
01078     return 0;
01079 }
01080 
01081 
01083 GtkWidget* create_gui_elements()
01084 {
01085  GtkWidget *mywin;
01086 // GtkWidget *clist;
01087  GtkWidget *button1;
01088 // GtkWidget *vbox;
01089 // GtkWidget *hbox
01090  GtkWidget *label1;
01091 
01092    mywin = gtk_dialog_new();
01093    gtk_window_set_title(GTK_WINDOW (mywin), "Press to Interrupt Python Script");
01094    label1 = gtk_label_new ("Press button to interrupt after current script-command.");
01095    button1 = gtk_button_new_with_label ("Interrupt");
01096 
01097    gtk_container_add (GTK_CONTAINER (GTK_DIALOG(mywin)->action_area),button1);
01098    gtk_container_add (GTK_CONTAINER (GTK_DIALOG(mywin)->vbox),label1);
01099    gtk_signal_connect (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC (ok_button_callback), NULL);
01100    gtk_signal_connect_object (GTK_OBJECT (button1), "clicked",
01101                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
01102                               GTK_OBJECT (mywin));
01103    gtk_widget_show_all (mywin);
01104 
01105    return(mywin);
01106 }
01108 
01109 
01110 
01111 // run-Function
01112 static void pyremote_run( GtkWidget *w, void *data )
01113 {
01114     GtkWidget *remote_window; 
01115     remote_window = create_gui_elements();
01116 
01117     PyObject *pName, *pModule; //, *pDict;
01118 
01119     Py_Initialize();
01120     Py_InitModule("emb", EmbMethods);
01121 
01122     pName = PyString_FromString("remote"); //this defines the module to load
01123 
01124     pModule = PyImport_Import(pName);
01125     Py_DECREF(pName);
01126 
01127     if (pModule == NULL) {
01128          PyErr_Print();
01129          fprintf(stderr, "Failed to execute Module. \n");
01130     }
01131 
01132     Py_Finalize();
01133     gtk_widget_destroy(remote_window);
01134     return;
01135 }
01136 #endif
01137 
01138 #ifndef Py_PYTHON_H
01139 static void pyremote_run( GtkWidget *w, void *data )
01140 {
01141     PI_DEBUG_ERROR(DBG_L1, "Python is not available on your system, sorry.");
01142     return;
01143 }
01144 #endif

Generated on Sat Apr 1 09:04:11 2006 for GXSM by  doxygen 1.4.6