spm_scancontrol.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: spm_scancontrol.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 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00029 
00030 /* Please do not change the Begin/End lines of this comment section!
00031  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00032  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00033  * All "% PlugInXXX" commentary tags are mandatory
00034  * All "% OptPlugInXXX" tags are optional
00035  * --------------------------------------------------------------------------------
00036 % BeginPlugInDocuSection
00037 % PlugInDocuCaption: SPM Scan Control
00038 % PlugInName: spm_scancontrol
00039 % PlugInAuthor: Percy Zahl
00040 % PlugInAuthorEmail: zahl@users.sf.net
00041 % PlugInMenuPath: Windows/SPM Scan Control
00042 
00043 % PlugInDescription
00044 Provides a SPM Scan Control Window and connects to the \Gxsm\ toolbar
00045 buttons \GxsmEmph{Scan, Movie, Stop} for quick access. The control
00046 panel offers in addition to \GxsmEmph{Scan, Movie, Stop} a
00047 \GxsmEmph{Pause} and \GxsmEmph{HS Capture} button. Use the
00048 \GxsmEmph{Pause} button to pause the scanning process and press it
00049 again for continuation. 
00050 
00051 The \GxsmEmph{HS Capture} button starts a contineous (movie) high
00052 speed (HS) frame capturing process on the DSP, a refresh is done after
00053 the whole scan data is received from the DSP. The scan size is limited
00054 by the available memory (SRAM) on the DSP platform. The \GxsmEmph{HS
00055 Capture} mode assures precise real time inter line timing on DSP level
00056 and allows maximum frame rates due to minimized communication between
00057 Gxsm and the DSP.
00058 
00059 Using this panel it is now possible to set the scan Y direction from
00060 \GxsmEmph{TopDown} (default, from Top to Bottom) to
00061 \GxsmEmph{TopDownBotUp} (alternating from Top to Bottom and vice
00062 versa) or \GxsmEmph{BotUp} (Botton to Top).
00063 
00064 This Gxsm PlugIn module actually provides not only the the scanning
00065 controls, it does the whole job of data acquisitation itself.
00066 
00067 % PlugInUsage
00068 Used for advanced SPM dataacquisitation control, open the control
00069 panel via \GxsmMenu{Windows/SPM Scan Control}.  
00070 
00071 \GxsmNote{The \GxsmEmph{HS Capture} scan mode is always in
00072 \GxsmEmph{TopDown} mode and no \GxsmEmph{Pause} will be accepted, use
00073 \GxsmEmph{Stop}.}
00074 
00075 \GxsmScreenShot{SPMScanControl}{The SPM Scan Control window.}
00076 
00077 % OptPlugInRefs
00078 %The internal used fast fourier transform is based on the FFTW library:\\
00079 %\GxsmWebLink{www.fftw.org}\\
00080 %Especially here:\\
00081 %\GxsmWebLink{www.fftw.org/doc/fftw\_2.html\#SEC5}\\
00082 About pthreads hacking, this is object of future use:\\
00083 \GxsmWebLink{java.icmc.sc.usp.br/library/books/ibm\_pthreads/}
00084 
00085 % OptPlugInNotes
00086 In \GxsmEmph{TopDownBotUp} mode always the last scan direction is
00087 remembered (even if the scan was stopped inbetween) and the opposide
00088 scan direction is used at next \GxsmEmph{Scan Start}.
00089 
00090 % OptPlugInHints
00091 You can switch the scan direction mode while running a movie or single
00092 scan, it will be used as soon as the next scan is started!
00093 
00094 % EndPlugInDocuSection
00095  * -------------------------------------------------------------------------------- 
00096  */
00097 
00098 
00099 #include <gtk/gtk.h>
00100 #include "config.h"
00101 #include "gxsm/plugin.h"
00102 
00103 #include "gxsm/unit.h"
00104 #include "gxsm/pcs.h"
00105 #include "gxsm/xsmtypes.h"
00106 #include "gxsm/glbvars.h"
00107 #include "gxsm/action_id.h"
00108 
00109 #include "include/dsp-pci32/xsm/xsmcmd.h"
00110 
00111 #include "plug-ins/control/spm_scancontrol.h"
00112 
00113 // Plugin Prototypes - default PlugIn functions
00114 static void spm_scancontrol_init (void); // PlugIn init
00115 static void spm_scancontrol_query (void); // PlugIn "self-install"
00116 static void spm_scancontrol_about (void); // About
00117 static void spm_scancontrol_configure (void); // Configure plugIn, called via PlugIn-Configurator
00118 static void spm_scancontrol_cleanup (void); // called on PlugIn unload, should cleanup PlugIn rescources
00119 
00120 // other PlugIn Functions and Callbacks (connected to Buttons, Toolbar, Menu)
00121 static void spm_scancontrol_show_callback (GtkWidget *w, void *data); // show ScanControl Window
00122 static void spm_scancontrol_start_callback (GtkWidget *w, void *data); // called on start scan
00123 static void spm_scancontrol_movie_callback (GtkWidget *w, void *data); // called on movie start
00124 static void spm_scancontrol_hscapture_callback (GtkWidget *w, void *data); // called on high speed capture start
00125 static void spm_scancontrol_pause_callback (GtkWidget *w, void *data); // called on pause/unpause
00126 static void spm_scancontrol_stop_callback (GtkWidget *w, void *data); // called on scan stop
00127 static void spm_scancontrol_SaveValues_callback ( gpointer );
00128 
00129 // Fill in the GxsmPlugin Description here -- see also: Gxsm/src/plugin.h
00130 GxsmPlugin spm_scancontrol_pi = {
00131         NULL,                   // filled in and used by Gxsm, don't touch !
00132         NULL,                   // filled in and used by Gxsm, don't touch !
00133         0,                      // filled in and used by Gxsm, don't touch !
00134         NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00135         // filled in here by Gxsm on Plugin load, 
00136         // just after init() is called !!!
00137         "Spm_ScanControl",
00138 //  "-rhkspmHARD +spmHARD +STM +AFM +SARLS +SNOM",                // PlugIn's Categorie, set to NULL for all, I just don't want this always to be loaded!
00139         "+ALL +noHARD +SRanger:SPMHARD +SRangerTest:SPMHARD +Innovative_DSP:SPMHARD +Innovative_DSP:SPAHARD +TC211-CCDHARD +video4linuxHARD +Comedi:SPMHARD -LAN_RHK:SPMHARD",
00140   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00141         "SPM scan control",
00142         "Percy Zahl",
00143         N_("_Windows/"),
00144         N_("SPM Scan Control"),
00145         N_("open SPM Scan Control Window"),
00146         "SPM Scan Control Window and Scan Generator PlugIn",
00147         NULL,          // error msg, plugin may put error status msg here later
00148         NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00149         spm_scancontrol_init,  
00150         spm_scancontrol_query,  
00151         // about-function, can be "NULL"
00152         // can be called by "Plugin Details"
00153         spm_scancontrol_about,
00154         // configure-function, can be "NULL"
00155         // can be called by "Plugin Details"
00156         spm_scancontrol_configure,
00157         // run-function, can be "NULL", if non-Zero and no query defined, 
00158         // it is called on menupath->"plugin"
00159         NULL,
00160         // cleanup-function, can be "NULL"
00161         // called if present at plugin removeal
00162         spm_scancontrol_cleanup
00163 };
00164 
00165 // Text used in Aboutbox, please update!!
00166 static const char *about_text = N_("Gxsm SPM Scan Generator and Control Plugin\n\n"
00167                                    "This plugin manages the SPM scanning process\n"
00168                                    "and multichannel/layer dataaquisitation."
00169         );
00170 
00171 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00172 // Essential Plugin Function!!
00173 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00174         spm_scancontrol_pi.description = g_strdup_printf(N_("Gxsm spm_scancontrol plugin %s"), VERSION);
00175         return &spm_scancontrol_pi; 
00176 }
00177 
00178 // data passed to "idle" function call, used to refresh/draw while waiting for data
00179 typedef struct {
00180         GSList *scan_list; // scans to update
00181         GFunc  UpdateFunc; // function to call for background updating
00182         gpointer data; // additional data (here: reference to the current SPM_ScanControl object)
00183 } IdleRefreshFuncData;
00184 
00185 SPM_ScanControl *spm_scancontrol = NULL;
00186 
00187 // Query Function, installs Plugin's in File/Import and Export Menupaths!
00188 // ----------------------------------------------------------------------
00189 // Import Menupath is "File/Import/abc import"
00190 // Export Menupath is "File/Export/abc import"
00191 // ----------------------------------------------------------------------
00192 // !!!! make sure the "spm_scancontrol_cleanup()" function (see below) !!!!
00193 // !!!! removes the correct menuentries !!!!
00194 
00195 // Add Menu Entries:
00196 // Windows/SPM Scan Control
00197 // Action/SPM Scan Start/Pause/Stop + Toolbar
00198 
00199 static void spm_scancontrol_query(void)
00200 {
00201         PI_DEBUG (DBG_L2, "spm_scancontrol_query" );
00202         static GnomeUIInfo menuinfo_windowcontrol[] = { 
00203                 { GNOME_APP_UI_ITEM, 
00204                   N_("SPM Scan Control"), N_("SPM Scan Control Window for advanced control"), 
00205                   (gpointer) spm_scancontrol_show_callback, NULL,
00206                   NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN,
00207                   0, GDK_CONTROL_MASK, NULL },
00208                 GNOMEUIINFO_END
00209         };
00210         
00211         gnome_app_insert_menus (
00212                 GNOME_APP(spm_scancontrol_pi.app->getApp()), 
00213                 N_("Windows/"), 
00214                 menuinfo_windowcontrol
00215                 );
00216         
00217         if(spm_scancontrol_pi.status) g_free(spm_scancontrol_pi.status); 
00218         spm_scancontrol_pi.status = g_strconcat (
00219                 N_("Plugin query has attached "),
00220                 spm_scancontrol_pi.name, 
00221                 N_(": File IO Filters are ready to use"),
00222                 NULL);
00223         
00224         PI_DEBUG (DBG_L2, "spm_scancontrol_query:new" );
00225         spm_scancontrol = new SPM_ScanControl;
00226         
00227         PI_DEBUG (DBG_L2, "spm_scancontrol_query:res" );
00228         spm_scancontrol->SetResName ("WindowSPMScanControl", "false", xsmres.geomsave);
00229         
00230         spm_scancontrol_pi.app->ConnectPluginToCDFSaveEvent (spm_scancontrol_SaveValues_callback);
00231 
00232 
00233         PI_DEBUG (DBG_L2, "spm_scancontrol_query:done" );
00234 }
00235 
00236 static void spm_scancontrol_SaveValues_callback ( gpointer gp_ncf ){
00237         gchar *tmp = NULL;
00238         if( spm_scancontrol )
00239                 tmp = strdup (spm_scancontrol->GetScanDir()==1 ? "TopDown " : "BottomUp");
00240         else
00241                 tmp = strdup ("N/A");
00242 
00243         NcFile *ncf = (NcFile *) gp_ncf;
00244         NcDim* spmscd  = ncf->add_dim("spm_scancontrol_dim", strlen(tmp));
00245         NcVar* spmsc   = ncf->add_var("spm_scancontrol", ncChar, spmscd);
00246         spmsc->add_att("long_name", "spm_scancontrol: scan direction");
00247         spmsc->put(tmp, strlen(tmp));
00248         g_free (tmp);
00249 }
00250 
00251 
00252 // 5.) Start here with the plugins code, vars def., etc.... here.
00253 // ----------------------------------------------------------------------
00254 //
00255 
00256 
00257 // init-Function
00258 static void spm_scancontrol_init(void)
00259 {
00260   PI_DEBUG (DBG_L2, "spm_scancontrol Plugin Init" );
00261 }
00262 
00263 // about-Function
00264 static void spm_scancontrol_about(void)
00265 {
00266   const gchar *authors[] = { spm_scancontrol_pi.authors, NULL};
00267   gtk_widget_show(gnome_about_new ( spm_scancontrol_pi.name,
00268                                     VERSION,
00269                                     N_("(C) 2001 the Free Software Foundation"),
00270                                     about_text,
00271                                     authors,
00272                                     NULL, NULL, NULL
00273                                     ));
00274 }
00275 
00276 // configure-Function
00277 static void spm_scancontrol_configure(void)
00278 {
00279         if(spm_scancontrol_pi.app)
00280                 spm_scancontrol_pi.app->message("spm_scancontrol Plugin Configuration");
00281 }
00282 
00283 // cleanup-Function, make sure the Menustrings are matching those above!!!
00284 static void spm_scancontrol_cleanup(void)
00285 {
00286         PI_DEBUG (DBG_L2, "spm_scancontrol Plugin Cleanup" );
00287         gnome_app_remove_menus (GNOME_APP (spm_scancontrol_pi.app->getApp()),
00288                                 N_("Windows/SPM Scan Control"), 1);
00289         // delete ...
00290         if( spm_scancontrol )
00291                 delete spm_scancontrol ;
00292 
00293         if(spm_scancontrol_pi.status) g_free(spm_scancontrol_pi.status); 
00294 }
00295 
00296 static void spm_scancontrol_show_callback( GtkWidget* widget, void* data){
00297         if( spm_scancontrol )
00298                 spm_scancontrol->show();
00299 }
00300 
00301 static void cb_setscandir( GtkWidget *widget, SPM_ScanControl *scc ){
00302         if (GTK_TOGGLE_BUTTON (widget)->active) 
00303                 scc->SetScanDir (widget);
00304         else
00305                 scc->ClrScanDir (widget);
00306 }
00307 
00308 SPM_ScanControl::SPM_ScanControl ()
00309 {
00310         GtkWidget *box, *hbox;
00311         GtkWidget *frame_param;
00312         GtkWidget *vbox_param, *hbox_param;
00313         GtkWidget *button;
00314 //      GtkWidget *input;
00315 //      Gtk_EntryControl *ec;
00316         
00317         GSList *EC_list=NULL;
00318         GSList **RemoteEntryList = new GSList *;
00319         *RemoteEntryList = NULL;
00320 
00321         master_scan      = NULL;
00322         master_probescan = NULL;
00323 
00324         xp_scan_list     = NULL;
00325         xp_2nd_scan_list = NULL;
00326         xp_prbscan_list  = NULL;
00327         xm_scan_list     = NULL;
00328         xm_2nd_scan_list = NULL;
00329         xm_prbscan_list  = NULL;
00330         scan_flag     = SCAN_FLAG_READY;
00331         scan_dir      = SCAN_DIR_TOPDOWN;
00332         last_scan_dir = SCAN_DIR_TOPDOWN;
00333         do_probe = FALSE;
00334         
00335         Unity    = new UnitObj(" "," ");
00336 
00337 //  XsmRescourceManager xrm("SPMScanControl");
00338 //  xrm.Get("SPMScanControl.Xorg", &Xorg, "0.");
00339 //      test = 13.;
00340 
00341         AppWidgetInit("SPM Scan Control");
00342 
00343         box = gtk_vbox_new (FALSE, 0);
00344         gtk_widget_show (box);
00345         gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0);
00346         
00347         hbox = gtk_hbox_new (FALSE, 0);
00348         gtk_widget_show (hbox);
00349         gtk_box_pack_start (GTK_BOX (box), hbox, TRUE, TRUE, 0);
00350 
00351 #define MYGTK_INPUT(L)  mygtk_create_input(L, vbox_param, hbox_param, 50, 70);
00352 
00353         frame_param = gtk_frame_new (N_("SPM Scan Control"));
00354         gtk_widget_show (frame_param);
00355         gtk_container_add (GTK_CONTAINER (hbox), frame_param);
00356         
00357         vbox_param = gtk_vbox_new (FALSE, 0);
00358         gtk_widget_show (vbox_param);
00359         gtk_container_add (GTK_CONTAINER (frame_param), vbox_param);
00360 
00361 //      input = MYGTK_INPUT("Test");
00362 //      ec = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &test, -10., 10., "5g", input);
00363 //      EC_list = g_slist_prepend( EC_list, ec);
00364 
00365 // Start, Pause, Stop Buttons
00366         hbox_param = gtk_hbox_new (FALSE, 0);
00367         gtk_widget_show (hbox_param);
00368         gtk_box_pack_start (GTK_BOX (vbox_param), hbox_param, TRUE, TRUE, 0);
00369 
00370         button = gtk_button_new_with_label("Start");
00371         gtk_widget_show (button);
00372         gtk_box_pack_start (GTK_BOX (hbox_param), button, TRUE, TRUE, 0);
00373         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00374                              GTK_SIGNAL_FUNC (spm_scancontrol_start_callback),
00375                              this);
00376         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Start");
00377 
00378         button = gtk_button_new_with_label("Movie");
00379         gtk_widget_show (button);
00380         gtk_box_pack_start (GTK_BOX (hbox_param), button, TRUE, TRUE, 0);
00381         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00382                              GTK_SIGNAL_FUNC (spm_scancontrol_movie_callback),
00383                              this);
00384         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Movie");
00385 
00386         button = gtk_button_new_with_label("HS Capture");
00387         gtk_widget_show (button);
00388         gtk_box_pack_start (GTK_BOX (hbox_param), button, TRUE, TRUE, 0);
00389         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00390                              GTK_SIGNAL_FUNC (spm_scancontrol_hscapture_callback),
00391                              this);
00392 //      gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_HsCapture");
00393 
00394         button = gtk_button_new_with_label("Pause");
00395         gtk_widget_show (button);
00396         gtk_box_pack_start (GTK_BOX (hbox_param), button, TRUE, TRUE, 0);
00397         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00398                              GTK_SIGNAL_FUNC (spm_scancontrol_pause_callback),
00399                              this);
00400         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Pause");
00401 
00402         button = gtk_button_new_with_label("Stop");
00403         gtk_widget_show (button);
00404         gtk_box_pack_start (GTK_BOX (hbox_param), button, TRUE, TRUE, 0);
00405         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00406                              GTK_SIGNAL_FUNC (spm_scancontrol_stop_callback),
00407                              this);
00408         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Stop");
00409 
00410         GtkWidget *radiobutton;
00411         GSList    *radiogroup;
00412 
00413         hbox_param = gtk_hbox_new (FALSE, 0);
00414         gtk_widget_show (hbox_param);
00415         gtk_box_pack_start (GTK_BOX (vbox_param), hbox_param, TRUE, TRUE, 0);
00416 
00417         // --------------------------------------------------
00418         radiobutton = gtk_radio_button_new_with_label( NULL, "TopDown");
00419         gtk_box_pack_start (GTK_BOX (hbox_param), radiobutton, TRUE, TRUE, 0);
00420         gtk_widget_show (radiobutton);
00421         gtk_object_set_data (GTK_OBJECT (radiobutton), "SCANDIR", (void*) SCAN_DIR_TOPDOWN);
00422         gtk_signal_connect (GTK_OBJECT (radiobutton), "clicked",
00423                             GTK_SIGNAL_FUNC (cb_setscandir), this);
00424         
00425         radiogroup = gtk_radio_button_group (GTK_RADIO_BUTTON (radiobutton));
00426         
00427         radiobutton = gtk_radio_button_new_with_label (radiogroup, "TopDown BotUp");
00428         gtk_box_pack_start (GTK_BOX (hbox_param), radiobutton, TRUE, TRUE, 0);
00429         gtk_widget_show (radiobutton);
00430         gtk_object_set_data (GTK_OBJECT (radiobutton), "SCANDIR", (void*) SCAN_DIR_TOPDOWN_BOTUP);
00431         gtk_signal_connect (GTK_OBJECT (radiobutton), "clicked",
00432                             GTK_SIGNAL_FUNC (cb_setscandir), this);
00433         
00434         radiogroup = gtk_radio_button_group (GTK_RADIO_BUTTON (radiobutton));
00435         
00436         radiobutton = gtk_radio_button_new_with_label (radiogroup, "BotUp");
00437         gtk_box_pack_start (GTK_BOX (hbox_param), radiobutton, TRUE, TRUE, 0);
00438         gtk_widget_show (radiobutton);
00439         gtk_object_set_data (GTK_OBJECT (radiobutton), "SCANDIR", (void*) SCAN_DIR_BOTUP);
00440         gtk_signal_connect (GTK_OBJECT (radiobutton), "clicked",
00441                             GTK_SIGNAL_FUNC (cb_setscandir), this);
00442         
00443   // save List away...
00444         gtk_object_set_data( GTK_OBJECT (widget), "SPMCONTROL_EC_list", EC_list);
00445 
00446 }
00447 
00448 // ToDo:
00449 //------> use gchar* gapp->GetPluginData() to get data [n x ..]
00450 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_SetYLookup"); [2 d g]
00451 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Line"); [1 d]
00452 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_PartialLine"); [3 d d d]
00453 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_UpdateParam");
00454 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Init");
00455 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Start_Add");
00456 // gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Movie_Add");
00457 
00458 
00459 SPM_ScanControl::~SPM_ScanControl (){
00460 
00461 //  XsmRescourceManager xrm("SPMScanControl");
00462 //  xrm.Put("SPMScanControl.Xorg", Xorg);
00463 
00464         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Start");
00465         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Movie");
00466         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Pause");
00467         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Stop");
00468 
00469         delete Unity;
00470         
00471         // remove assigned memory
00472         line = -1;
00473         do_scanline (TRUE);
00474 
00475 }
00476 
00477 //      gapp->xsm->hardware->SetScanMode(MEM_ADDTO);
00478 
00479 void SPM_ScanControl::update(){
00480         g_slist_foreach((GSList*)gtk_object_get_data( GTK_OBJECT (widget), "SPMCONTROL_EC_list"),
00481                         (GFunc) App::update_ec, NULL);
00482 }
00483 
00484 // Menu Call Back Fkte
00485 
00486 static void spm_scancontrol_start_callback (GtkWidget *w, void *data){
00487         if (((SPM_ScanControl*)data) ->  scan_in_progress())
00488                 return;
00489 
00490         gtk_widget_set_sensitive (w, FALSE);
00491         gtk_widget_set_sensitive ((GtkWidget*)gtk_object_get_data( GTK_OBJECT (w), "ToolbarButton"), FALSE);
00492         
00493         gapp->xsm->data.ui.SetDateOfScanNow();
00494         gapp->spm_update_all();
00495         gapp->xsm->hardware->SetScanMode();
00496 
00497         ((SPM_ScanControl*)data) -> do_scan();
00498         if(gapp->xsm->IsMode(MODE_AUTOSAVE))
00499                 gapp->xsm->save(1);
00500 
00501         gtk_widget_set_sensitive (w, TRUE);
00502         gtk_widget_set_sensitive ((GtkWidget*)gtk_object_get_data( GTK_OBJECT (w), "ToolbarButton"), TRUE);
00503 }
00504 
00505 /*
00506 http://java.icmc.sc.usp.br/library/books/ibm_pthreads/
00507 
00508 pthread_t     thread;
00509 rc = pthread_create(&thread, NULL, C_thread_func, data);
00510 void *C_thread_func(void *data) {
00511   doingsth();
00512   return (void*)0;
00513 }*/
00514 
00515 static void spm_scancontrol_movie_callback (GtkWidget *w, void *data){
00516         int nostop;
00517         if (((SPM_ScanControl*)data) ->  scan_in_progress())
00518                 return;
00519 
00520         gtk_widget_set_sensitive (w, FALSE);
00521         gtk_widget_set_sensitive ((GtkWidget*)gtk_object_get_data( GTK_OBJECT (w), "ToolbarButton"), FALSE);
00522 
00523         do {
00524                 time_t t; // Scan - Startzeit eintragen 
00525                 time(&t);
00526                 G_FREE_STRDUP_PRINTF(gapp->xsm->data.ui.dateofscan, ctime(&t));
00527                 gapp->spm_update_all();
00528                 gapp->xsm->hardware->SetScanMode();
00529 
00530                 nostop = ((SPM_ScanControl*)data) -> do_scan();
00531 
00532                 if(gapp->xsm->IsMode(MODE_AUTOSAVE))
00533                         gapp->xsm->save(1);
00534         } while (nostop);
00535 
00536         gtk_widget_set_sensitive (w, TRUE);
00537         gtk_widget_set_sensitive ((GtkWidget*)gtk_object_get_data( GTK_OBJECT (w), "ToolbarButton"), TRUE);
00538 }
00539 
00540 static void spm_scancontrol_hscapture_callback (GtkWidget *w, void *data){
00541         int nostop;
00542         if (((SPM_ScanControl*)data) ->  scan_in_progress())
00543                 return;
00544         do {
00545                 time_t t; // Scan - Startzeit eintragen 
00546                 time(&t);
00547                 G_FREE_STRDUP_PRINTF(gapp->xsm->data.ui.dateofscan, ctime(&t));
00548                 gapp->spm_update_all();
00549                 gapp->xsm->hardware->SetScanMode();
00550 
00551                 nostop = ((SPM_ScanControl*)data) -> do_hscapture();
00552 
00553                 if(gapp->xsm->IsMode(MODE_AUTOSAVE))
00554                         gapp->xsm->save(1);
00555         } while (nostop);
00556 }
00557 
00558 static void spm_scancontrol_pause_callback (GtkWidget *w, void *data){
00559         ((SPM_ScanControl*)data) -> pause_scan();
00560 }
00561 
00562 static void spm_scancontrol_stop_callback (GtkWidget *w, void *data){
00563         ((SPM_ScanControl*)data) -> stop_scan();
00564 }
00565 
00566 
00567 // ==================================================
00568 // Scan Control Routines
00569 // ==================================================
00570 
00571 
00572 // ========================================
00573 // DoScan
00574 // ========================================
00575 //
00576 // aktiviert automatisch alle vorherigen / bzw. einen neuen Scan Channel
00577 // setzt Channel-Zuordnung
00578 // SRCS MODES:
00579 // bit 0 1 2 3:   PID (Z), ... (calculated stuff (Z=Topo))
00580 // bit 4 5 6 7:   MUXA select PIDSRC (Force, I, dF, ..)   (mux A bei PC31, bei PCI32 alle auf A)
00581 // bit 8,9,10,11: MUXB select Analog Value (Friction, ..) (mux B bei PC31)
00582 // bit 12,13,14,15: AUX select C,D
00583 #define MSK_PID(X)  (1<<((X)&3))
00584 #define MSK_MUXA(X) (1<<(((X)&3)+4))
00585 #define MSK_MUXB(X) (1<<(((X)&3)+8))
00586 #define MSK_AUX(X)  (1<<(((X)&3)+12))
00587 
00588 
00589 int SPM_ScanControl::free_scan_lists (){
00590         if (xp_scan_list){
00591                 g_slist_free (xp_scan_list);
00592                 xp_scan_list = NULL;
00593         }
00594         if (xp_2nd_scan_list){
00595                 g_slist_free (xp_2nd_scan_list);
00596                 xp_2nd_scan_list = NULL;
00597         }
00598         if (xp_prbscan_list){
00599                 g_slist_free (xp_prbscan_list);
00600                 xp_prbscan_list = NULL;
00601         }
00602         if (xm_scan_list){
00603                 g_slist_free (xm_scan_list);
00604                 xm_scan_list = NULL;
00605         }
00606         if (xm_2nd_scan_list){
00607                 g_slist_free (xm_2nd_scan_list);
00608                 xm_2nd_scan_list = NULL;
00609         }
00610         if (xm_prbscan_list){
00611                 g_slist_free (xm_prbscan_list);
00612                 xm_prbscan_list = NULL;
00613         }
00614 
00615         return 0;
00616 }
00617 
00618 // analyse channelselections and setup scanlists and scans
00619 int SPM_ScanControl::initialize_scan_lists (){
00620         int i,ipid,idaq,i2nddaq,iprb,ch,sok,checks;
00621 
00622         if (xp_scan_list || xm_scan_list 
00623             || xp_2nd_scan_list || xm_2nd_scan_list 
00624             || xp_prbscan_list || xm_prbscan_list) // stop if scan lists are existing!
00625                 return -1;
00626   
00627         do_probe = FALSE;
00628         master_scan = NULL;
00629         master_probescan = NULL;
00630 
00631         sok=FALSE; // ScanOK = no 
00632         checks=2;    // only one second try!
00633         xp_srcs = xm_srcs = 0; // reset srcs, take care of PID default, to do!!!!
00634         xp_2nd_srcs = xm_2nd_srcs = 0; // reset srcs, take care of PID default, to do!!!!
00635 
00636         // analyze channel settings and create scan lists, and setup this scans
00637         do {
00638                 PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : do");
00639 
00640                 // Find and init Xp-Scans
00641                 for (ipid=idaq=i2nddaq=iprb=i=0; i < MAXSCANS; i++){
00642                         // PID src?  Find the first/next "Topo like" scan... 
00643                         // (ipid counts until all PID type scans are checked)
00644                         for (ch = -1; (ipid < PIDCHMAX) && ((ch=gapp->xsm->FindChan(xsmres.pidchno[ipid++])) < 0););
00645 
00646                         if(ch >= 0){ // got one!
00647                                 PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up XpScan - PID src found");
00648                                 // add bit to xp_srcs mask
00649                                 xp_srcs |= MSK_PID(ipid-1);
00650                                 // setup this scan
00651                                 setup_scan (ch, "X+", 
00652                                             xsmres.pidsrc[ipid-1], 
00653                                             xsmres.pidsrcZunit[ipid-1], 
00654                                             xsmres.pidsrcZlabel[ipid-1]
00655                                         );
00656                                 // and add to list
00657                                 xp_scan_list = g_slist_prepend (xp_scan_list, gapp->xsm->scan[ch]);
00658                                 // got already a master? If not used this one!
00659                                 if (!master_scan) master_scan = gapp->xsm->scan[ch];
00660                                 // got one valid scan, so we could finish if no more... "Scan-OK"
00661                                 sok=TRUE;
00662                         }
00663                         else{
00664                                 // DAQ src? Find additional scans/channels to aquire...
00665                                 // (idaq counts until all checked)
00666                                 for(ch = -1; (idaq < DAQCHMAX) && ((ch=gapp->xsm->FindChan(xsmres.daqchno[idaq++])) < 0););
00667                                 if(ch >= 0){ // got one!
00668                                         // add to xp_srcs mask... use "MUXA" (DA0..3)
00669                                         if(idaq <= 4)
00670                                                 xp_srcs |= MSK_MUXA(idaq-1);
00671                                         else{
00672                                                 // add to xp_srcs mask... use "MUXB" (DA4..7)
00673                                                 if(idaq <= 8)
00674                                                         xp_srcs |= MSK_MUXB(idaq-5);
00675                                                 else
00676                                                         // add to xp_srcs mask... use "AUX" (Auxillary DSP-Data)
00677                                                         xp_srcs |= MSK_AUX(idaq-9);
00678                                         }
00679                                         PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up XpScan - DAQ src found");
00680                                         // setup this scan
00681                                         setup_scan (ch, "X+",
00682                                                     xsmres.daqsrc[idaq-1], 
00683                                                     xsmres.daqZunit[idaq-1], 
00684                                                     xsmres.daqZlabel[idaq-1]
00685                                                 );
00686                                         // add to list...
00687                                         xp_scan_list = g_slist_prepend (xp_scan_list, gapp->xsm->scan[ch]);
00688                                         if (!master_scan) master_scan = gapp->xsm->scan[ch];
00689                                         sok=TRUE;
00690                                 }
00691                                 else{
00692                                         // 2nd DAQ src? Find additional scans/channels to aquire...
00693                                         // (idaq counts until all checked)
00694                                         for(ch = -1; (i2nddaq < DAQCHMAX) && ((ch=gapp->xsm->FindChan(ID_CH_M_2ND_OFFSET+xsmres.daqchno[i2nddaq++])) < 0););
00695                                         if(ch >= 0){ // got one!
00696                                                 // add to xp_srcs mask... use "MUXA" (DA0..3)
00697                                                 if(i2nddaq <= 4)
00698                                                         xp_2nd_srcs |= MSK_MUXA(i2nddaq-1);
00699                                                 else{
00700                                                         // add to xp_srcs mask... use "MUXB" (DA4..7)
00701                                                         if(i2nddaq <= 8)
00702                                                                 xp_2nd_srcs |= MSK_MUXB(i2nddaq-5);
00703                                                         else
00704                                                                 // add to xp_srcs mask... use "AUX" (Auxillary DSP-Data)
00705                                                                 xp_2nd_srcs |= MSK_AUX(i2nddaq-9);
00706                                                 }
00707                                                 PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up 2nd XpScan - DAQ src found");
00708                                                 // setup this scan
00709                                                 setup_scan (ch, "X2+",
00710                                                             xsmres.daqsrc[i2nddaq-1], 
00711                                                             xsmres.daqZunit[i2nddaq-1], 
00712                                                             xsmres.daqZlabel[i2nddaq-1]
00713                                                         );
00714                                                 // add to list...
00715                                                 xp_2nd_scan_list = g_slist_prepend (xp_2nd_scan_list, gapp->xsm->scan[ch]);
00716                                                 if (!master_scan) master_scan = gapp->xsm->scan[ch];
00717                                                 sok=TRUE;
00718                                         }
00719 //                                      else{
00720 //                                              // PRB src? Similar stuff for Probe type Scans...
00721 //                                              for(ch = -1; (iprb < PRBMODESMAX) && ((ch=gapp->xsm->FindChan(xsmres.prbchno[iprb++])) < 0););
00722 //                                              if(ch >= 0){
00723 //                                                      PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up XpScan - PRB src found");
00724                                                         
00725 //                                                      setup_scan (ch, "X+",
00726 //                                                                  xsmres.prbid[iprb-1], 
00727 //                                                                  xsmres.prbYunit[iprb-1], 
00728 //                                                                  xsmres.prbYlabel[iprb-1],
00729 //                                                                  xsmres.prbXunit[iprb-1], 
00730 //                                                                  xsmres.prbXlabel[iprb-1],
00731 //                                                                  xsmres.prbsrcs[iprb-1], 
00732 //                                                                  xsmres.prboutp[iprb-1]
00733 //                                                              );
00734 //                                                      xp_prbscan_list = g_slist_prepend (xp_prbscan_list, gapp->xsm->scan[ch]);
00735 //                                                      // if first probe scan found, use this as probe master
00736 //                                                      if (!master_probescan) master_probescan = gapp->xsm->scan[ch];
00737 //                                                      // note that we have to run in probe mode!
00738 //                                                      do_probe = TRUE;
00739 //                                                      sok=TRUE;
00740 //                                              }
00741 //                                      }
00742                                 }
00743                         }
00744                 }
00745     
00746                 // Find and init Xm-Scans
00747                 // similar channel analysis for all XM (<-) scans... -- no probing in this direction!
00748                 for (ipid=i2nddaq=idaq=i=0; i<MAXSCANS; i++){
00749                         // new PID src?
00750                         for(ch = -1; (ipid < PIDCHMAX) && ((ch=gapp->xsm->FindChan(-xsmres.pidchno[ipid++])) < 0););
00751 
00752                         if(ch >= 0){
00753                                 PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up XmScan - PID src found");
00754                                 xm_srcs |= MSK_PID(ipid-1);
00755 
00756                                 setup_scan (ch, "X-", 
00757                                             xsmres.pidsrc[ipid-1], 
00758                                             xsmres.pidsrcZunit[ipid-1], 
00759                                             xsmres.pidsrcZlabel[ipid-1]
00760                                         );
00761                                 xm_scan_list = g_slist_prepend (xm_scan_list, gapp->xsm->scan[ch]);
00762                                 if (!master_scan) master_scan = gapp->xsm->scan[ch];
00763                                 sok=TRUE;
00764                         }
00765                         else{
00766                                 for(ch = -1; (idaq < DAQCHMAX) && ((ch=gapp->xsm->FindChan(-xsmres.daqchno[idaq++])) < 0););
00767                                 if(ch >= 0){
00768                                         if(idaq <= 4)
00769                                                 xm_srcs |= MSK_MUXA(idaq-1);
00770                                         else{
00771                                                 if(idaq <= 8)
00772                                                         xm_srcs |= MSK_MUXB(idaq-5);
00773                                                 else
00774                                                         xm_srcs |= MSK_AUX(idaq-9);
00775                                         }
00776                                         
00777                                         PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up XmScan - DAQ src found");
00778                                         setup_scan (ch, "X-",
00779                                                     xsmres.daqsrc[idaq-1], 
00780                                                     xsmres.daqZunit[idaq-1], 
00781                                                     xsmres.daqZlabel[idaq-1]
00782                                                 );
00783                                         xm_scan_list = g_slist_prepend (xm_scan_list, gapp->xsm->scan[ch]);
00784                                         if (!master_scan) master_scan = gapp->xsm->scan[ch];
00785                                         sok=TRUE;
00786                                 }
00787                                 else{
00788                                         for(ch = -1; (i2nddaq < DAQCHMAX) && ((ch=gapp->xsm->FindChan(-ID_CH_M_2ND_OFFSET-xsmres.daqchno[i2nddaq++])) < 0););
00789                                         if(ch >= 0){
00790                                                 if(i2nddaq <= 4)
00791                                                         xm_2nd_srcs |= MSK_MUXA(i2nddaq-1);
00792                                                 else{
00793                                                         if(i2nddaq <= 8)
00794                                                                 xm_2nd_srcs |= MSK_MUXB(i2nddaq-5);
00795                                                         else
00796                                                                 xm_2nd_srcs |= MSK_AUX(i2nddaq-9);
00797                                                 }
00798                                         
00799                                                 PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up 2nd XmScan - DAQ src found");
00800                                                 setup_scan (ch, "X2-",
00801                                                             xsmres.daqsrc[i2nddaq-1], 
00802                                                             xsmres.daqZunit[i2nddaq-1], 
00803                                                             xsmres.daqZlabel[i2nddaq-1]
00804                                                         );
00805                                                 xm_2nd_scan_list = g_slist_prepend (xm_2nd_scan_list, gapp->xsm->scan[ch]);
00806                                                 if (!master_scan) master_scan = gapp->xsm->scan[ch];
00807                                                 sok=TRUE;
00808                                         }
00809 //                                      else{
00810 //                                              // PRB src?
00811 //                                              for(ch = -1; (iprb < PRBMODESMAX) && ((ch=gapp->xsm->FindChan(xsmres.prbchno[iprb++])) < 0););
00812 //                                              if(ch >= 0){
00813 //                                                      PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : Setting up XmScan - PRB src found");
00814 // #ifdef ____NO_PRB_IN_XM_DIR____
00815 //                                                      setup_scan (ch, "X-",
00816 //                                                                  xsmres.prbid[iprb-1], 
00817 //                                                                  xsmres.prbYunit[iprb-1], 
00818 //                                                                  xsmres.prbYlabel[iprb-1],
00819 //                                                                  xsmres.prbXunit[iprb-1], 
00820 //                                                                  xsmres.prbXlabel[iprb-1],
00821 //                                                                  TRUE
00822 //                                                              );
00823 //                                                      xm_prbscan_list = g_slist_prepend (xm_prbscan_list, gapp->xsm->scan[ch]);
00824 //                                                      if (!master_probescan) master_probescan = gapp->xsm->scan[ch];
00825 //                                                      do_probe = FALSE; // not allowed jet!!!
00826 //                                                      sok=TRUE;
00827 // #else
00828 //                                                      PI_DEBUG (DBG_L3, "Sorry: no Prb in X- direction!!!");
00829 // #endif
00830 //                                              }
00831 //                                      }
00832                                 }
00833                         }
00834                 }
00835                 
00836                 // Automatic mode:
00837                 // if no Scansrc specified -- find free channel and use pid-default ("Topo")
00838                 if(! sok){
00839                         PI_DEBUG (DBG_L3, "SPM_SCANCONTROL::initialize_scan_lists : No Srcs specified, setting up default!");
00840                         ch = gapp->xsm->FindChan(ID_CH_M_ACTIVE);
00841                         if(!(ch >= 0)){
00842                                 ch = gapp->xsm->FindChan(ID_CH_M_MATH);
00843                                 if(!(ch >= 0))
00844                                         ch = gapp->xsm->FindChan(ID_CH_M_OFF);
00845                                 else{
00846                                         scan_flag = SCAN_FLAG_RUN;
00847                                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"",1);
00848                                         return FALSE;
00849                                 }
00850                         }
00851                         gapp->channelselector->SetMode(ch, xsmres.piddefault);
00852                         gapp->xsm->ChannelMode[ch] =  xsmres.piddefault;
00853                         gapp->xsm->ChannelScanMode[ch] = gapp->xsm->ChannelScanMode[ch] < 0 ? -xsmres.piddefault : xsmres.piddefault;
00854                 }
00855         }while (! sok && --checks);
00856 
00857         // if sth, went wrong... (should never happen)
00858         if (!checks)
00859                 XSM_SHOW_ALERT (ERR_SORRY, ERR_NOSRCCHAN, "", 1);
00860 
00861         return 0;
00862 }
00863 
00864 int SPM_ScanControl::setup_scan (int ch, 
00865                                  const gchar *titleprefix, 
00866                                  const gchar *name,
00867                                  const gchar *unit,
00868                                  const gchar *label,
00869                                  const gchar *vunit,
00870                                  const gchar *vlabel,
00871                                  const gchar *prbsrcs,
00872                                  int prboutp
00873         ){
00874         PI_DEBUG (DBG_L2, "setup_scan");
00875         // did this scan already exists?
00876         if ( ! gapp->xsm->scan[ch]){ // make a new one ?
00877                 gapp->xsm->scan[ch] = gapp->xsm->NewScan (gapp->xsm->ChannelView[ch], 
00878                                                           gapp->xsm->data.display.ViewFlg, 
00879                                                           ch, 
00880                                                           &gapp->xsm->data);
00881                 // Error ?
00882                 if (!gapp->xsm->scan[ch]){
00883                         XSM_SHOW_ALERT (ERR_SORRY, ERR_NOMEM,"",1);
00884                         return FALSE;
00885                 }
00886         }
00887 
00888         // Setup correct Z unit
00889         UnitObj *u = gapp->xsm->MakeUnit (unit, label);
00890         gapp->xsm->scan[ch]->data.SetZUnit (u);
00891         delete u;
00892 
00893 //      // Probe stuff to do?
00894 //      if (prbsrcs){
00895 //              PI_DEBUG (DBG_L2, "setup_scan: analyse prbsrcs=" << prbsrcs);
00896 //              Mem2d *m=gapp->xsm->scan[ch]->mem2d;
00897 //              m->Resize (m->GetNx (), m->GetNy (), m->GetNv (), ZD_FLOAT);
00898 //              gapp->xsm->scan[ch]->create (TRUE, TRUE);
00899 //              gapp->xsm->scan[ch]->data.lp.srcs  = 0;
00900 //              gapp->xsm->scan[ch]->data.lp.nsrcs = 0;
00901 //              gapp->xsm->scan[ch]->data.lp.outp  = prboutp;
00902 //              for (int k = 0; k < (int)strlen (prbsrcs); ++k)
00903 //                      if (prbsrcs[k] == '1'){
00904 //                              gapp->xsm->scan[ch]->data.lp.srcs |= 1<<k;
00905 //                              gapp->xsm->scan[ch]->data.lp.nsrcs++;
00906 //                      }
00907 //              UnitObj *u = gapp->xsm->MakeUnit (vunit, vlabel);
00908 //              gapp->xsm->scan[ch]->data.SetVUnit (u);
00909 //              delete u;
00910 //              PI_DEBUG (DBG_L2, "PRB: nsrcs=" << gapp->xsm->scan[ch]->data.lp.nsrcs 
00911 //                   << "  srcs=" << gapp->xsm->scan[ch]->data.lp.srcs 
00912 //                   << "  outp=" << gapp->xsm->scan[ch]->data.lp.outp 
00913 //                   << "  nvalues=" << gapp->xsm->scan[ch]->data.lp.nvalues 
00914 //                   );
00915 //      }
00916 //      else
00917 //              gapp->xsm->scan[ch]->create (TRUE);
00918                 
00919         // uncomment this line if top is not uncommented!
00920         gapp->xsm->scan[ch]->create (TRUE);
00921 
00922         // setup dz from instrument definition
00923         gapp->xsm->scan[ch]->data.s.dz = gapp->xsm->Inst->ZResolution (unit);
00924 
00925         // set scan title, name, ... and draw it!
00926         gchar *scantitle = g_strdup_printf ("%s %s", titleprefix, name);
00927         gapp->xsm->scan[ch]->data.ui.SetName (scantitle);
00928         gapp->xsm->scan[ch]->data.ui.SetOriginalName ("unknown");
00929         gapp->xsm->scan[ch]->data.ui.SetTitle (scantitle);
00930         gapp->xsm->scan[ch]->data.ui.SetType (scantitle);
00931         g_free (scantitle);
00932         gapp->xsm->scan[ch]->draw ();
00933 
00934         return 0;
00935 }
00936 
00937 int SPM_ScanControl::prepare_to_start_scan (SCAN_DT_TYPE st){
00938         // which origin mode?
00939         if (IS_SPALEED_CTRL||xsmres.ScanOrgCenter)
00940           YOriginTop = FALSE; // Fix hier für SPA-LEED
00941         else 
00942           YOriginTop = TRUE;
00943         scan_flag = SCAN_FLAG_RUN;
00944 
00945         gapp->SetStatus ("Starting Scan: Ch.Setup");
00946         gapp->check_events ();
00947     
00948         // setup scan size
00949         gapp->xsm->hardware->SetDxDy (
00950                 R2INT (gapp->xsm->Inst->XA2Dig (gapp->xsm->data.s.dx)),
00951                 R2INT (gapp->xsm->Inst->YA2Dig (gapp->xsm->data.s.dy)));
00952         gapp->xsm->hardware->SetNxNy (gapp->xsm->data.s.nx, gapp->xsm->data.s.ny);
00953 
00954         gapp->xsm->data.s.dz = gapp->xsm->Inst->ZResolution ();
00955 
00956         gapp->SignalStartScanEventToPlugins ();
00957 
00958         // Init Scanobjects, do Channelsetup... some complex stuff...
00959         int result = initialize_scan_lists ();
00960 
00961         if (result){
00962                 XSM_SHOW_ALERT (ERR_SORRY, ERR_SCAN_CANCEL,
00963                                 "Channel setup failed.",
00964                                 1);
00965                 return result;
00966         }
00967 
00968         // count channels and check if total data amount fits into hardware/transferbuffer/etc. hard limits
00969         int ns_xp=0;
00970         int ns_xm=0;
00971         for (int i=0; i<16; ++i){
00972                 if (xp_srcs&(1<<i)) ++ns_xp;
00973                 if (xm_srcs&(1<<i)) ++ns_xm;
00974         }
00975 
00976         // Check Ranges/Sizes with Hardware/DSP Memory
00977         switch (st){
00978         case SCAN_LINESCAN:
00979                 if (gapp->xsm->data.s.nx*ns_xp >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
00980                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per line to\n"
00981                                                          "%ld in total for all channels (->)!",
00982                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
00983                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
00984                         g_free (maxtxt);
00985                         return -1;
00986                 }
00987                 if (gapp->xsm->data.s.nx*ns_xm >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
00988                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per line to\n"
00989                                                          "%ld in total for all channels (<-)!",
00990                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
00991                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
00992                         g_free (maxtxt);
00993                         return -1;
00994                 }
00995                 return 0;
00996         case SCAN_FRAMECAPTURE:
00997                 if (gapp->xsm->data.s.nx*gapp->xsm->data.s.ny*ns_xp >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
00998                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per frame to\n"
00999                                                          "%ld in total for all channels (->)!",
01000                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
01001                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
01002                         g_free (maxtxt);
01003                         return -1;
01004                 }
01005                 if (gapp->xsm->data.s.nx*gapp->xsm->data.s.ny*ns_xm >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
01006                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per frame to\n"
01007                                                          "%ld in total for all channels (<-)!",
01008                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
01009                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
01010                         g_free (maxtxt);
01011                         return -1;
01012                 }
01013                 return 0;
01014         default: return -1;
01015         }
01016 }
01017 
01018 // run "background" update function(s)
01019 void IdleRefreshFunc (gpointer data){
01020         g_slist_foreach ((GSList*) ((IdleRefreshFuncData*)data)->scan_list,
01021                          (GFunc) ((IdleRefreshFuncData*)data)->UpdateFunc,
01022                          ((IdleRefreshFuncData*)data)->data);
01023 }
01024 
01025 // execute a single scan line -- or if "line == -1" a HS 2D Area Capture/Scan
01026 void SPM_ScanControl::do_scanline (int init){
01027         static Mem2d **m2d_xp=NULL;
01028         static Mem2d **m2d_xm=NULL;
01029         static IdleRefreshFuncData idf_data;
01030 
01031         // if first time called/first line, do some local (static vars) initializations here!
01032         if (init){
01033                 int num; 
01034                 PI_DEBUG (DBG_L2, "SPM_ScanControl::do_scanline : init");
01035                 if (m2d_xp){
01036                         g_free (m2d_xp);
01037                         m2d_xp = NULL;
01038                 }
01039                 if (m2d_xm){
01040                         g_free (m2d_xm);
01041                         m2d_xm = NULL;
01042                 }
01043                 if( line < 0) 
01044                         return;
01045 
01046                 num = g_slist_length (xp_scan_list); 
01047                 if (num>0){
01048                         Mem2d **m;
01049                         m = m2d_xp = (Mem2d**) g_new (Mem2d*, num+1);
01050                         GSList* tmp = g_slist_copy (xp_scan_list);
01051                         GSList* rev = tmp = g_slist_reverse(tmp);
01052                         while (tmp){
01053                                 *m++ = ((Scan*)tmp->data)->mem2d;
01054                                 ((Scan*)tmp->data)->view->remove_events(); // clean up old events
01055                                 tmp = g_slist_next (tmp);
01056                         }
01057                         *m = NULL;
01058                         g_slist_free (rev);
01059                 }
01060 
01061                 num = g_slist_length (xm_scan_list); 
01062                 PI_DEBUG (DBG_L2, "SPM_ScanControl::do_scanline : init, num xm=" << num);
01063                 if (num > 0){
01064                         Mem2d **m;
01065                         m = m2d_xm = (Mem2d**) g_new (Mem2d*, num+1);
01066                         GSList* tmp = g_slist_copy (xm_scan_list);
01067                         GSList* rev = tmp = g_slist_reverse(tmp);
01068                         while (tmp){
01069                                 *m++ = ((Scan*)tmp->data)->mem2d;
01070                                 ((Scan*)tmp->data)->view->remove_events(); // clean up old events
01071                                 tmp = g_slist_next (tmp);
01072                         }
01073                         *m = NULL;
01074                         g_slist_free (rev);
01075                 }
01076                 idf_data.scan_list  = NULL;
01077                 idf_data.UpdateFunc = (GFunc) SPM_ScanControl::call_scan_draw_line;
01078                 idf_data.data = this;
01079                 PI_DEBUG (DBG_L2, "SPM_ScanControl::do_scanline : init done");
01080 
01081                 gapp->xsm->hardware->ScanLineM (-2,  1, xp_srcs, m2d_xp, 0);
01082                 gapp->xsm->hardware->ScanLineM (-2, -1, xm_srcs, m2d_xm, 0);
01083 
01084                 return;
01085         }
01086 
01087         if (line == -1){ // HS Capture -- Area Scan!!!
01088                 // do X+ Scan ?
01089                 if (m2d_xp)
01090                         gapp->xsm->hardware->ScanLineM (-1,  1, xp_srcs, m2d_xp, ix0off);
01091 
01092                 // do X- Scan ?
01093                 if (m2d_xm)
01094                         PI_DEBUG (DBG_L2, "Sorry -- not in HS Capture mode" );
01095 
01096                 return;
01097         }
01098 
01099         // do Scanline (XP (+))
01100         // and display new Data
01101         
01102         // do X+ Scan?
01103         if (m2d_xp){
01104                 // execute scanline
01105                 gapp->xsm->hardware->ScanLineM (line,  1, xp_srcs, m2d_xp, ix0off);
01106                 // setup idle func -- executed on next wait for data!
01107                 line2update = line;
01108                 idf_data.scan_list = xp_scan_list;
01109                 gapp->xsm->hardware->SetIdleFunc (&IdleRefreshFunc, &idf_data);
01110         }
01111                 
01112 
01113         // do X- Scan ?
01114         if (m2d_xm){
01115                 gapp->xsm->hardware->ScanLineM(line, -1, xm_srcs, m2d_xm, ix0off);
01116 
01117                 line2update = line;
01118                 idf_data.scan_list = xm_scan_list;
01119                 gapp->xsm->hardware->SetIdleFunc (&IdleRefreshFunc, &idf_data);
01120         } 
01121 
01122         autosave_check (update_status_info ());
01123 }
01124 
01125 void SPM_ScanControl::run_probe (int ipx, int ipy){
01126 
01127 }
01128 
01129 void SPM_ScanControl::set_subscan (int ix0, int num){
01130         int n;
01131         ix0off = ix0;
01132 //      if(ix0 >= 0 && num > 0){
01133 //              if (master_probescan){
01134 //                      n = master_probescan->data.hardpars.LS_nx2scan = num;
01135 //                      master_probescan->data.hardpars.LS_nx_pre = 0;
01136 //                      master_probescan->data.hardpars.SPA_Length = R2INT(gapp->xsm->Inst->XA2Dig(master_scan->data.s.rx*num/master_scan->data.s.nx));
01137 //                      gapp->xsm->hardware->PutParameter(&master_probescan->data.hardpars);
01138 //              } else { PI_DEBUG (DBG_L2, "ERROR not probing" ); return; }
01139 //      } else {
01140 //              gapp->xsm->hardware->PutParameter (&master_scan->data.hardpars);
01141 //              n = master_scan->data.s.nx;
01142 //      }
01143 
01144         PI_DEBUG (DBG_L2, "SPM_ScanControl::set_subscan" << ix0off << ":" << n);
01145 
01146         n = master_scan->data.s.nx;
01147 
01148         // Setup Copy Mode in mem2d...
01149         for (GSList* tmp = xp_scan_list; tmp; tmp = g_slist_next (tmp))
01150                 ((Scan*)tmp->data) -> mem2d->data->ZPutDataSetDest (ix0off, n);
01151         
01152         for (GSList* tmp = xm_scan_list; tmp; tmp = g_slist_next (tmp))
01153                 ((Scan*)tmp->data) -> mem2d->data->ZPutDataSetDest (ix0off, n);
01154 }       
01155 
01156 int SPM_ScanControl::do_scan (){
01157         PI_DEBUG (DBG_L2, "do_scan");
01158 
01159         if (scan_in_progress ()){
01160                 PI_DEBUG (DBG_L2, "do_scan scan in progress, exiting.");
01161                 return FALSE;
01162         }
01163 
01164         if (prepare_to_start_scan ()){
01165                 PI_DEBUG (DBG_L2, "prepare scan failed, exiting.");
01166                 stop_scan ();
01167                 free_scan_lists ();
01168                 return FALSE;
01169         }
01170 
01171         PI_DEBUG (DBG_L2, "do_scan precheck done.");
01172 
01173         // now freeze all scanparameters
01174         gapp->spm_freeze_scanparam();
01175     
01176         PI_DEBUG (DBG_L2, "do_scan SetOffsets.");
01177 
01178         if (!IS_SPALEED_CTRL)
01179                 gapp->xsm->hardware->SetOffset (R2INT (gapp->xsm->Inst->X0A2Dig (master_scan->data.s.x0)),
01180                                                 R2INT (gapp->xsm->Inst->Y0A2Dig (master_scan->data.s.y0)));
01181         else
01182                 gapp->xsm->hardware->SetOffset (R2INT(gapp->xsm->Inst->X0A2Dig (master_scan->data.s.x0) 
01183                                                       + master_scan->data.s.SPA_OrgX/gapp->xsm->Inst->XResolution ()),
01184                                                 R2INT(gapp->xsm->Inst->Y0A2Dig (master_scan->data.s.y0) 
01185                                                       + master_scan->data.s.SPA_OrgY/gapp->xsm->Inst->YResolution ()));
01186         
01187         switch (scan_dir){
01188         case SCAN_DIR_TOPDOWN: 
01189                 last_scan_dir = SCAN_DIR_TOPDOWN;
01190                 break;
01191         case SCAN_DIR_TOPDOWN_BOTUP: 
01192                 last_scan_dir = last_scan_dir == SCAN_DIR_TOPDOWN ? SCAN_DIR_BOTUP : SCAN_DIR_TOPDOWN;
01193                 break;
01194         case SCAN_DIR_BOTUP: 
01195                 last_scan_dir = SCAN_DIR_BOTUP;
01196                 break;
01197         }
01198 
01199         gapp->xsm->hardware->ScanDirection(last_scan_dir == SCAN_DIR_TOPDOWN? +1 : -1);
01200 
01201 // vorlaeufig...
01202         PI_DEBUG (DBG_L2, "do_scan Moveto 0,0, Rotate, Moveto.");
01203 
01204         if (last_scan_dir == SCAN_DIR_TOPDOWN){
01205                 if (!IS_SPALEED_CTRL)
01206                         yline = 0;
01207                 else{ // SPA_LEED: don't care
01208                         yline = R2INT(gapp->xsm->Inst->YA2Dig((-master_scan->data.s.ny/2)*master_scan->data.s.dy)); 
01209                 }
01210                 gapp->xsm->hardware->MovetoXY(0, yline);
01211                 PI_DEBUG (DBG_L2, "Moveto:0,"<<yline);
01212                 // Dies ist der Rotations-Invariante Punkt !!
01213                 // Jetzt, und nur hier !!!!! drehen !
01214                 gapp->xsm->hardware->SetAlpha(master_scan->data.s.alpha);
01215                 PI_DEBUG (DBG_L2, "Set alpha: "<<master_scan->data.s.alpha);
01216         }    
01217 
01218         // Set Start Time, notify scans about, initialisations...
01219         g_slist_foreach ((GSList*) xp_scan_list,
01220                         (GFunc) SPM_ScanControl::call_scan_start, this);
01221         g_slist_foreach ((GSList*) xm_scan_list,
01222                         (GFunc) SPM_ScanControl::call_scan_start, this);
01223 
01224         gapp->xsm->hardware->StartScan2D();
01225 
01226         line = 0;
01227         do_scanline (TRUE);
01228         update_status_info (TRUE);
01229         autosave_check (0., xsmres.AutosaveValue);
01230         set_subscan ();
01231 
01232         // copy muxsettings from other direction if not given
01233         // weird... to fix !!!
01234         if(!xm_srcs) xm_srcs = xp_srcs;
01235         if(!xp_srcs) xp_srcs = xm_srcs;
01236         
01237         PI_DEBUG (DBG_L3, "DoScan: Setup MUX");
01238     
01239         // MUX-Codierung:
01240 #ifdef XSM_DEBUG_OPTION
01241         PI_DEBUG (DBG_L3,  "xp_srcs: " << xp_srcs );
01242         for(int i=0; i<16; i++) PI_DEBUG_PLAIN (DBG_L2, (int)((xp_srcs&(1<<i))?1:0)); PI_DEBUG_PLAIN (DBG_L2, std::endl);
01243         PI_DEBUG (DBG_L3,  "xm_srcs: " << xm_srcs );
01244         for(int i=0; i<16; i++) PI_DEBUG_PLAIN (DBG_L2, (int)((xm_srcs&(1<<i))?1:0)); PI_DEBUG_PLAIN (DBG_L2, std::endl);
01245 #endif
01246     
01247         PI_DEBUG (DBG_L3, "DoScan: Start Scan now");
01248 
01249         {
01250                 gchar *muxcoding = g_strdup_printf ("xp_srcs: %2X  xm_srcs: %2X", xp_srcs, xm_srcs);
01251                 gapp->monitorcontrol->LogEvent ("*StartScan", muxcoding);
01252                 g_free (muxcoding);
01253         }
01254 
01255         // run scan now...
01256         for(line = last_scan_dir == SCAN_DIR_TOPDOWN ? 0 : master_scan->data.s.ny-1;
01257             (last_scan_dir == SCAN_DIR_TOPDOWN ? line < master_scan->data.s.ny : line >= 0)
01258                     && scan_flag != SCAN_FLAG_STOP;
01259                 ){
01260       
01261                 if (scan_flag == SCAN_FLAG_RUN){
01262                         // PI_DEBUG (DBG_L3, "Running Line" << line);
01263 
01264                         // calculate yline and move to scanline start position
01265 
01266                         if (YOriginTop)
01267                                 yline = R2INT (gapp->xsm->Inst->YA2Dig (
01268                                                        -line*master_scan->data.s.dy));
01269                         else
01270                                 yline = R2INT (gapp->xsm->Inst->YA2Dig (
01271                                                        -(line - master_scan->data.s.ny/2)*master_scan->data.s.dy));
01272                         
01273                         gapp->xsm->hardware->MovetoXY (
01274                                 R2INT (gapp->xsm->Inst->XA2Dig (
01275                                                master_scan->data.s.dx 
01276                                                * (ix0off - gapp->xsm->hardware->GetPreScanLineOffset () - master_scan->data.s.nx/2)
01277                                                )),
01278                                 yline);
01279 
01280 
01281                         // execute scan line
01282                         do_scanline ();
01283 
01284                         // skip to next line
01285                         last_scan_dir == SCAN_DIR_TOPDOWN ? ++line : --line;
01286                 }
01287                 gapp->check_events();
01288         }
01289         
01290         // finish scan
01291         gapp->xsm->hardware->EndScan2D ();
01292         gapp->xsm->hardware->CallIdleFunc ();
01293         gapp->xsm->hardware->SetIdleFunc (NULL, NULL);
01294 
01295         if( line < master_scan->data.s.ny && line&1) 
01296                 line++;
01297         
01298         // Set Scan End Time/trucate unfinished scans to save space
01299 
01300         g_slist_foreach ((GSList*) xp_scan_list,
01301                         (GFunc) SPM_ScanControl::call_scan_stop, this);
01302         g_slist_foreach ((GSList*) xm_scan_list,
01303                         (GFunc) SPM_ScanControl::call_scan_stop, this);
01304 
01305         return finish_scan ();
01306 }
01307 
01308 int SPM_ScanControl::do_hscapture (){
01309         if (scan_in_progress ()){
01310                 PI_DEBUG (DBG_L2, "do_scan scan in progress, exiting.");
01311                 return FALSE;
01312         }
01313 
01314         if (prepare_to_start_scan (SCAN_FRAMECAPTURE)){
01315                 PI_DEBUG (DBG_L2, "prepare scan failed, exiting.");
01316                 stop_scan ();
01317                 free_scan_lists ();
01318                 return FALSE;
01319         }
01320 
01321         // now freeze all scanparameters
01322         gapp->spm_freeze_scanparam();
01323 
01324         // move to origin
01325         if (!IS_SPALEED_CTRL)
01326                 gapp->xsm->hardware->SetOffset (R2INT (gapp->xsm->Inst->X0A2Dig (master_scan->data.s.x0)),
01327                                                 R2INT (gapp->xsm->Inst->Y0A2Dig (master_scan->data.s.y0)));
01328         else
01329                 gapp->xsm->hardware->SetOffset (R2INT(gapp->xsm->Inst->X0A2Dig (master_scan->data.s.x0) 
01330                                                       + master_scan->data.s.SPA_OrgX/gapp->xsm->Inst->XResolution ()),
01331                                                 R2INT(gapp->xsm->Inst->Y0A2Dig (master_scan->data.s.y0) 
01332                                                       + master_scan->data.s.SPA_OrgY/gapp->xsm->Inst->YResolution ()));
01333         
01334         // Auf Ursprung fahren: SPM: Mitte erste Scanzeile !!
01335         gapp->xsm->hardware->MovetoXY (0,0);
01336         gapp->xsm->hardware->SetAlpha (master_scan->data.s.alpha);
01337 
01338         // Set Start Time, notify scans about, initialisations...
01339         g_slist_foreach ((GSList*) xp_scan_list,
01340                         (GFunc) SPM_ScanControl::call_scan_start, this);
01341         g_slist_foreach ((GSList*) xm_scan_list,
01342                         (GFunc) SPM_ScanControl::call_scan_start, this);
01343 
01344         gapp->xsm->hardware->StartScan2D();
01345 
01346         line = 0;
01347         do_scanline (TRUE);
01348         update_status_info (TRUE);
01349 
01350         // copy muxsettings from other direction if not given
01351         // weird... to fix !!!
01352         if(!xm_srcs) xm_srcs = xp_srcs;
01353         if(!xp_srcs) xp_srcs = xm_srcs;
01354         
01355         // MUX-Codierung:
01356 #ifdef XSM_DEBUG_OPTION
01357         PI_DEBUG (DBG_L4,  "xp_srcs: " << xp_srcs );
01358         for(int i=0; i<16; i++) PI_DEBUG_PLAIN (DBG_L2, (int)((xp_srcs&(1<<i))?1:0)); PI_DEBUG_PLAIN (DBG_L2, std::endl );
01359         PI_DEBUG (DBG_L4,  "xm_srcs: " << xm_srcs );
01360         for(int i=0; i<16; i++) PI_DEBUG_PLAIN (DBG_L2, (int)((xm_srcs&(1<<i))?1:0)); PI_DEBUG_PLAIN (DBG_L2, std::endl );
01361 #endif
01362 
01363         {
01364                 gchar *muxcoding = g_strdup_printf ("xp_srcs: %2X  xm_srcs: %2X", xp_srcs, xm_srcs);
01365                 gapp->monitorcontrol->LogEvent ("*StartHSCapture", muxcoding);
01366                 g_free (muxcoding);
01367         }
01368 
01369         if (scan_flag != SCAN_FLAG_STOP ){
01370                 if (!YOriginTop){
01371                         int yline = R2INT (gapp->xsm->Inst->YA2Dig (
01372                                                    -(line - master_scan->data.s.ny/2)
01373                                                    *master_scan->data.s.dy));
01374                 gapp->xsm->hardware->MovetoXY (
01375                         R2INT (gapp->xsm->Inst->XA2Dig (
01376                                        master_scan->data.s.dx 
01377                                        * (ix0off - gapp->xsm->hardware->GetPreScanLineOffset ()
01378                                           - master_scan->data.s.nx/2)
01379                                        )), 
01380                         yline);
01381                 }
01382                 // execute high speed capture scan (line = -1 indicates this mode)
01383                 line = -1;
01384                 do_scanline ();
01385                 gapp->check_events ();
01386         }
01387 
01388         gapp->xsm->hardware->EndScan2D ();
01389         line = master_scan->data.s.ny;
01390         g_slist_foreach ((GSList*) xp_scan_list,
01391                         (GFunc) SPM_ScanControl::call_scan_stop, this);
01392         g_slist_foreach ((GSList*) xm_scan_list,
01393                         (GFunc) SPM_ScanControl::call_scan_stop, this);
01394 
01395         return finish_scan ();
01396 }
01397 
01398 int SPM_ScanControl::finish_scan (){
01399         int stopped;
01400         PI_DEBUG (DBG_L2, "finish_scan.");
01401 
01402         // Wieder auf Ursprung fahren: Mitte erste Scanzeile !!
01403         gapp->xsm->hardware->MovetoXY(0,0);
01404         PI_DEBUG (DBG_L2, "Return to (0,0) at the end of the scan.");
01405         /*      switch (scan_dir){
01406         case SCAN_DIR_TOPDOWN: 
01407                 gapp->xsm->hardware->MovetoXY (0,0);
01408                 // Dies ist der Rotations-Invariante Punkt !!
01409                 // Jetzt, und nur hier !!!!! auf 0° drehen !
01410                 gapp->xsm->hardware->SetAlpha(0);
01411                 break;
01412         default:
01413                 gapp->xsm->hardware->MovetoXY (0,0);
01414                 // Dies ist der Rotations-Invariante Punkt !!
01415                 // Jetzt, und nur hier !!!!! auf 0° drehen !
01416                 gapp->xsm->hardware->SetAlpha(0);
01417                 break;
01418                 }*/
01419 
01420         gapp->spm_thaw_scanparam();
01421 
01422         if ((stopped = scan_flag == SCAN_FLAG_STOP ? TRUE:FALSE)){
01423                 gapp->SetStatus("Scan interrupted");
01424                 gapp->monitorcontrol->LogEvent("*EndOfScan", "interrupted");
01425         }
01426         else{
01427                 gapp->SetStatus("Scan done, ready");
01428                 gapp->monitorcontrol->LogEvent("*EndOfScan", "OK");
01429         }
01430         
01431         free_scan_lists ();
01432         scan_flag = SCAN_FLAG_READY;
01433 
01434 
01435         return !stopped;
01436 }
01437 
01438 double SPM_ScanControl::update_status_info (int reset){
01439         static time_t tn, tnlog, t0;
01440         time_t t;
01441 
01442         if (reset){
01443                 time (&t0); 
01444                 tnlog=tn=t0;
01445                 return 0.;
01446         }
01447 
01448         time (&t);
01449         // update only of more than 2s old
01450         if ((t-tn) > 2){
01451                 double ss,s,m,h, sse,se,me,he;
01452                 double n_by_lines_to_do;
01453                 gchar *tt;
01454                 tn=t;
01455                 ss = s = tn-t0;
01456                 h = floor (s/3600.);
01457                 m = floor ((s-h*3600.)/60.);
01458                 s-= h*3600.+m*60.;
01459                 
01460                 n_by_lines_to_do = (double)master_scan->data.s.ny
01461                         / (double)(last_scan_dir == SCAN_DIR_TOPDOWN ?
01462                                    line+1 : master_scan->data.s.ny-line);
01463                 sse = se = (double)(tn-t0)*n_by_lines_to_do;
01464                 se -= ss; // ETA (Estimated Time left to Arrival at end of scan)
01465                 he  = floor (se/3600.);
01466                 me  = floor ((se-he*3600.)/60.);
01467                 se -= he*3600.+me*60.;
01468                 // 0123456789012345678901234567890
01469                 // Mon Apr 17 09:10:17 2000
01470                 if ((sse+ss) > 600){
01471                         time_t t_eta = t+(time_t)(sse-ss);
01472                         char *teos = ctime(&t_eta); 
01473                         teos[24]=0;
01474                         gapp->SetStatus ("ScanTime",
01475                                          tt=g_strdup_printf ("%.0f:%02.0f:%02.0f "
01476                                                                                  "| ETA:%.0f:%02.0f:%02.0f | %d%%\n"
01477                                                                                  "End of Scan: %s  %s",
01478                                                                                  h,m,s, he,me,se, 
01479                                                                                  (int)(100/n_by_lines_to_do), teos, 
01480                                                                                  gapp->xsm->hardware->GetStatusInfo()?gapp->xsm->hardware->GetStatusInfo():" "));
01481                 }else
01482                         gapp->SetStatus ("ScanTime",
01483                                          tt=g_strdup_printf ("%.0f:%02.0f:%02.0f "
01484                                                                                  "| ETA:%.0f:%02.0f:%02.0f | %d%%  %s",
01485                                                                                  h,m,s, he,me,se, 
01486                                                                                  (int)(100/n_by_lines_to_do),
01487                                                                                  gapp->xsm->hardware->GetStatusInfo()?gapp->xsm->hardware->GetStatusInfo():" "));
01488 
01489                 if ((t-tnlog) > 60 || (sse+ss) < 600){
01490                         tnlog=t;
01491                         gchar *nl;
01492                         if ((nl=strchr (tt, '\n'))) *nl=' '; // remove \n for logfile
01493                         gchar *mt = g_strdup_printf ("Scan Progress [%d]", line);
01494                         gapp->monitorcontrol->LogEvent (mt, tt);
01495                         g_free(mt);
01496                 }
01497                 g_free(tt);
01498 
01499                 t=tn+(time_t)sse; 
01500                 return ss;
01501         }
01502         return 0.;
01503 }
01504 
01505 void SPM_ScanControl::autosave_check (double sec, int initvalue){
01506         static int nextAutosaveEvent=0;
01507 
01508         if (initvalue > 0){
01509                 nextAutosaveEvent = initvalue;  
01510                 return;
01511         }
01512 
01513         if ( (( !strncasecmp(xsmres.AutosaveUnit, "percent",2)) 
01514               && ((100*line/master_scan->data.s.ny) >= nextAutosaveEvent))
01515              ||
01516              (( !strncasecmp(xsmres.AutosaveUnit, "lines"  ,2))
01517               && (line >= nextAutosaveEvent))
01518              ||
01519              ((!strncasecmp(xsmres.AutosaveUnit, "seconds",2))
01520               && (sec >= nextAutosaveEvent)) ){
01521 
01522                 nextAutosaveEvent += xsmres.AutosaveValue;
01523                 if(gapp->xsm->IsMode(MODE_AUTOSAVE)){
01524                         PI_DEBUG (DBG_L3, "Autosaveevent triggered.");
01525                         // check for overwritemode for autosave
01526                         if(!strncasecmp(xsmres.AutosaveOverwritemode, "true",2))
01527                                 gapp->xsm->save(2, NULL, -1, TRUE);
01528                         else
01529                                 gapp->xsm->save(2, NULL, -1, FALSE); 
01530                 }
01531         }
01532 }

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