Index: /trunk/MagicSoft/Cosy/Changelog
===================================================================
--- /trunk/MagicSoft/Cosy/Changelog	(revision 2517)
+++ /trunk/MagicSoft/Cosy/Changelog	(revision 2518)
@@ -1,3 +1,98 @@
                                                                   -*-*- END -*-*-
+ 2003/11/17 - Thomas Bretz (La Palma)
+ 
+   * Makefile.conf.general:
+     - added libThread.a
+     
+   * prepos_magic.txt:
+     - exchanged order
+     - fixed positions
+     
+   * stars.txt:
+     - added many sources taken from the CC input file
+     
+   * base/MTimeout.[h,cc]:
+     - changed to use check system time (using timers
+       always resulted in trouble)
+       
+   * base/msgqueue.[h,cc]:
+     - replaced Posix mutex by TMutex
+     
+   * base/timer.cc:
+     - display hour with two digits
+     
+   * candrv/canopen.[h,cc]:
+     - replaced Posix semaphores bt TCondition
+     
+   * candrv/network.cc:
+     - minor change to output
+     
+   * candrv/nodedrv.[h,cc]:
+     - removed old timer stuff, replaced by a watch-dog thread
+     - added MGuard
+     - removed HandleTimer
+     - added argument to SetZombie
+     - nodedrv don't derive from TObject anymore
+     
+   * candrv/sdolist.[h,cc]:
+     - replaced Posix sempahores by TMutex
+     
+   * candrv/vmodican.cc:
+     - minor change to Send()
+     
+   * devdrv/macs.cc:
+     - added to HandleSDO: 0x100c, 0x100d
+     - added to HandleSDOOk: 0x1000, 0x100c, 0x100d, 0x1800, 0x6000,
+       0x6002, 0x6003 
+     - Enabled Guarding for Macs
+     
+   * devdrv/shaftencoder.cc:
+     - added HandleSDOOk: 0x1802, 0x6001, 0x6002, 0x6003
+
+   * gui/MGAccuracy.[h,cc]:
+     - added fBar
+
+   * gui/MGCosy.cc:
+     - added button for Endswitch alignment printout
+     - merged Move and Resize to MoveResize
+     - fixed UpdateZdAz (uses Slalib now)
+     
+   * gui/MGImage.[h,cc]:
+     - replaced Posix sempahores by TMutex
+     - added DrawColImg16
+
+   * main/MCosy.[h,cc]:
+     - some changes to output
+     - some changes to state transmission
+     - fixed (hopefully) treating of endswitch positions
+     - fixed positioning mode for tracking
+     - do not display weird values in case of Zombie
+       Shaftencoders anymore
+     
+   * main/MStarguider.cc:
+     - if display is not set locally use 125 avaraged pictures
+       by default.
+       
+   * tcpip/MCeCoCom.[h,cc]:
+     - some small fixes
+     - some changes to output
+     - read 30 instead of 29 dummy tokens
+     - added solar radiation and wind speed
+     - moved corresponding code to InterpreteReport
+     
+   * tcpip/MDriveCom.[h,cc]:
+     - added ReadAngle for interpretation of Angle in CC commands
+     - added ReadPosition
+     - added Command*
+     - implemented CC commands
+     
+   * tcpip/MTcpIpIO.cc:
+     - Stop thread before deleting data members
+     - replace -1 for fRxSocket by 0
+     
+   * videodev/Camera.[h,cc]:
+     - replaced Posix sempahores by TMutex and TCondition
+
+
  2003/11/14 - Thomas Bretz (La Palma)
 
Index: /trunk/MagicSoft/Cosy/Makefile.conf.general
===================================================================
--- /trunk/MagicSoft/Cosy/Makefile.conf.general	(revision 2517)
+++ /trunk/MagicSoft/Cosy/Makefile.conf.general	(revision 2518)
@@ -4,6 +4,6 @@
 
 ROOTVER    =  `root-config --version`
-ROOTLIBS   =  `root-config --libs`
-ROOTGLIBS  =  `root-config --glibs`
+ROOTLIBS   =  `root-config --libs` -lThread
+ROOTGLIBS  =  `root-config --glibs` -lThread
 ROOTCFLAGS =  `root-config --cflags`
 
Index: /trunk/MagicSoft/Cosy/base/MTimeout.cc
===================================================================
--- /trunk/MagicSoft/Cosy/base/MTimeout.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/base/MTimeout.cc	(revision 2518)
@@ -1,1 +1,21 @@
 #include "MTimeout.h"
+
+#include <TSystem.h>
+
+MTimeout::MTimeout(unsigned long ms=500) : fTimeout((ULong_t)gSystem->Now()+ms)
+{
+    // Use SetTime to change the timing
+    // if (ms) TurnOn(); // Add to system list
+}
+
+bool MTimeout::HasTimedOut()
+{
+    return fTimeout<(ULong_t)gSystem->Now();
+}
+
+void MTimeout::Start(unsigned long ms=500)
+{
+    fTimeout = (ULong_t)gSystem->Now()+ms;
+    //Reset();  // reset before adding
+    //TurnOn(); // Add to system list
+}
Index: /trunk/MagicSoft/Cosy/base/MTimeout.h
===================================================================
--- /trunk/MagicSoft/Cosy/base/MTimeout.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/base/MTimeout.h	(revision 2518)
@@ -1,9 +1,10 @@
-#ifndef MTIMEOUT_H
-#define MTIMEOUT_H
+#ifndef COSY_MTimeout
+#define COSY_MTimeout
 
-#include <TTimer.h>
+//#include <TTimer.h>
 
-class MTimeout : public TTimer
+class MTimeout// : public TTimer
 {
+    /*
     Bool_t Notify()
     {
@@ -11,17 +12,13 @@
         return kFALSE;
     }
+     */
+    unsigned long fTimeout;
 
 public:
-    MTimeout(Long_t ms=500) : TTimer(ms, kFALSE)
-    {
-        // Use SetTime to change the timing
-        if (ms) TurnOn(); // Add to system list
-    }
+    MTimeout(unsigned long ms=500);
 
-    void Start()
-    {
-        Reset();  // reset before adding
-        TurnOn(); // Add to system list
-    }
+    bool HasTimedOut();
+
+    void Start(unsigned long ms=500);
 };
 
Index: /trunk/MagicSoft/Cosy/base/msgqueue.cc
===================================================================
--- /trunk/MagicSoft/Cosy/base/msgqueue.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/base/msgqueue.cc	(revision 2518)
@@ -89,7 +89,7 @@
         // a PostMsg is processed correctly
         //
-        pthread_mutex_lock(&fMuxMsg);
+        fMuxMsg.Lock();
         fBreak = 0;
-        pthread_mutex_unlock(&fMuxMsg);
+        fMuxMsg.UnLock();
 
 #ifdef DEBUG
@@ -130,5 +130,5 @@
     cout << "MsgQueue::PostMsg: Locking MsgQueue mutex..." << flush;
 #endif
-    pthread_mutex_lock(&fMuxMsg);
+    fMuxMsg.Lock();
 #ifdef DEBUG
     cout << "done." << endl;
@@ -145,5 +145,5 @@
     if (fBreak)
     {
-        pthread_mutex_unlock(&fMuxMsg);
+        fMuxMsg.UnLock();
 #ifdef DEBUG
         cout << "------------> MsgQueue::PostMsg: Proc still pending... Message IGNORED." << endl;
@@ -176,5 +176,5 @@
 #endif
     fStart = 1;
-    pthread_mutex_unlock(&fMuxMsg);
+    fMuxMsg.UnLock();
 #ifdef DEBUG
     cout << "done." << endl;
Index: /trunk/MagicSoft/Cosy/base/msgqueue.h
===================================================================
--- /trunk/MagicSoft/Cosy/base/msgqueue.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/base/msgqueue.h	(revision 2518)
@@ -6,4 +6,8 @@
 #define WM_NULL 0x0000
 #define WM_QUIT 0xffff
+
+#ifndef ROOT_TMutex
+#include <TMutex.h>
+#endif
 
 class MsgQueue
@@ -19,9 +23,6 @@
     void *fRc;    // Proc return code
 
-    pthread_t       fThread;
-    pthread_mutex_t fMuxMsg;
-    pthread_cond_t  fCondMsg;
-    pthread_mutex_t fMuxRc;
-    pthread_cond_t  fCondRc;
+    pthread_t fThread;
+    TMutex    fMuxMsg;
 
     static void *MapThread(void *arg);
@@ -36,6 +37,8 @@
 
     virtual void *Proc(int msg, void *mp1);
+    void *Proc(int msg) { return Proc(msg, 0); }
 
     void *PostMsg(int msg, void *mp1, int size);
+    void *PostMsg(int msg) { return PostMsg(msg, 0, 0); }
 };
 
Index: /trunk/MagicSoft/Cosy/base/timer.cc
===================================================================
--- /trunk/MagicSoft/Cosy/base/timer.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/base/timer.cc	(revision 2518)
@@ -136,5 +136,5 @@
 const char *Timer::GetTimeStr()
 {
-    sprintf(fDateStr, "%d/%02d/%02d %d:%02d:%02d.%06li",
+    sprintf(fDateStr, "%2d/%02d/%02d %d:%02d:%02d.%06li",
             fYea, fMon, fDay, fHor, fMin, fSec, (long)(1000000.0*fMs));
 
@@ -146,5 +146,5 @@
     char text[256];
 
-    sprintf(text, "%d/%02d/%02d %d:%02d:%02d.%01li",
+    sprintf(text, "%2d/%02d/%02d %d:%02d:%02d.%01li",
             t.fYea, t.fMon, t.fDay, t.fHor, t.fMin, t.fSec, (long)(10.0*t.fMs));
 
Index: /trunk/MagicSoft/Cosy/candrv/canopen.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/canopen.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/canopen.cc	(revision 2518)
@@ -32,8 +32,10 @@
 #include "canopen.h"
 
-#include <iostream.h> // cout
-#include <iomanip.h>  // setw, setfill
+#include <iostream> // cout
+#include <iomanip>  // setw, setfill
 
 ClassImp(CanOpen);
+
+using namespace std;
 
 // --------------------------------------------------------------------------
@@ -44,12 +46,4 @@
 CanOpen::CanOpen(const char *dev, const int baud, MLog &out) : VmodIcan(dev, baud, out)
 {
-    for (int i=0; i<32; i++)
-        for (int j=0; j<4; j++)
-        {
-            pthread_cond_init(&fPdoCond[i][j], NULL);
-            pthread_mutex_init(&fPdoMux[i][j], NULL);
-            pthread_mutex_lock(&fPdoMux[i][j]);
-        }
-
     lout << "- CanOpen initialized." << endl;
 }
@@ -61,10 +55,4 @@
 CanOpen::~CanOpen()
 {
-    for (int i=0; i<32; i++)
-        for (int j=0; j<4; j++)
-        {
-            pthread_cond_destroy(&fPdoCond[i][j]);
-            pthread_mutex_destroy(&fPdoMux[i][j]);
-        }
     lout << "- CanOpen destroyed." << endl;
 }
@@ -126,5 +114,5 @@
         {
             HandlePDO1(node, data, tv);
-            pthread_cond_broadcast(&fPdoCond[node-1][0]);
+            fPdoCond[node-1][0].Broadcast();
         }
         return;
@@ -133,5 +121,5 @@
         {
             HandlePDO2(node, data, tv);
-            pthread_cond_broadcast(&fPdoCond[node-1][1]);
+            fPdoCond[node-1][1].Broadcast();
         }
         return;
@@ -140,5 +128,5 @@
         {
             HandlePDO3(node, data, tv);
-            pthread_cond_broadcast(&fPdoCond[node-1][2]);
+            fPdoCond[node-1][2].Broadcast();
         }
         return;
@@ -147,5 +135,5 @@
         {
             HandlePDO4(node, data, tv);
-            pthread_cond_broadcast(&fPdoCond[node-1][3]);
+            fPdoCond[node-1][3].Broadcast();
         }
         return;
Index: /trunk/MagicSoft/Cosy/candrv/network.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/network.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/network.cc	(revision 2518)
@@ -269,5 +269,6 @@
         if (fNodes[i] && fNodeInitialized[i])
         {
-            lout << "- Stopping Node #" << dec << i << endl;
+            lout << "- Stopping Node #" << dec << i;
+            lout << " (" << fNodes[i]->GetNodeName() << ")" << endl;
             fNodes[i]->StopDevice();
         }
Index: /trunk/MagicSoft/Cosy/candrv/nodedrv.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/nodedrv.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/nodedrv.cc	(revision 2518)
@@ -61,5 +61,5 @@
 // and the node name. The name is a name for debug output.
 //
-NodeDrv::NodeDrv(BYTE_t nodeid, const char *name, MLog &out) : Log(out), fNetwork(NULL), fId(32), fError(0), fIsZombie(kTRUE)
+NodeDrv::NodeDrv(BYTE_t nodeid, const char *name, MLog &out) : Log(out), fNetwork(NULL), fId(32), fError(0), fIsZombie(kTRUE), fGuard(NULL)
 {
     if (nodeid>0x1f)
@@ -79,7 +79,4 @@
     }
 
-    fTimerOn = kFALSE;
-    fTimeout = new TTimer(this, 100, kFALSE); // 100ms, asynchronous
-
     lout << "- Node #" << (int)nodeid << " (" << name << ") initialized." << endl;
 
@@ -92,6 +89,4 @@
 NodeDrv::~NodeDrv()
 {
-    fTimerOn = kFALSE;
-    delete fTimeout;
 }
 
@@ -492,22 +487,74 @@
 // least one Nodeguard message was answered.
 //
+class NodeGuard : public MThread
+{
+    Double_t fTimeoutTime;
+    Double_t fGuardTime;
+    Int_t    fLifeTimeFactor;
+
+    Bool_t   fIsCanOpen;
+
+    NodeDrv *fDrv;
+
+public:
+    NodeGuard(NodeDrv *drv, Int_t guard, Int_t ltf, Bool_t canopen)
+        : MThread(false), fGuardTime(guard/1000.), fLifeTimeFactor(ltf), fIsCanOpen(canopen), fDrv(drv) { }
+
+    void Reset(timeval_t *tv=NULL)
+    {
+        Timer t;
+        if (tv)
+            t.SetTimer(tv);
+        else
+            t.Now();
+
+        fTimeoutTime = t + (fGuardTime*fLifeTimeFactor);
+    }
+
+    void *Thread()
+    {
+        Reset();
+
+        while (!HasStopFlag())
+        {
+            // Sending nodeguards seems to result in
+            // loosing CANbus messages or CANbus answers...
+            // strange. Also protecting VmodIcan::SendCanFrame
+            // by a Mutex doesn't help.
+            if (fIsCanOpen)
+                fDrv->SendNodeguard();
+
+            Timer t;
+            t.Now();
+
+            const Timer t0 = t+fGuardTime;
+
+            while (!HasStopFlag() && t<t0 && t<fTimeoutTime)
+            {
+                usleep(5);
+                t.Now();
+            }
+
+            //cout << "-d-> " << (Long_t)((fTimeoutTime-t)*1000) << endl;
+            //cout << "-o-> " << (ULong_t)((fTimeoutTime)*1000)<< " " << (ULong_t)((t)*1000) << endl;
+            //cout << "-g-> " << (Long_t)((t-t0)*1000)<< endl;
+
+            if (t<fTimeoutTime)
+                continue;
+
+            fDrv->SetZombie(false);
+            return 0;
+        }
+        return 0;
+    }
+};
+
 void NodeDrv::StartGuarding(Bool_t real=kTRUE)
 {
-    if (fTimerOn)
+    if (fGuard)
         return;
 
-    if (!real)
-        SendNodeguard();
-
-    fTimerOn = kTRUE;
-    fTimeout->SetTime(fGuardTime);
-    fTimeout->Reset();
-
-    Timer t;
-    fTimeoutTime = t.Now() + (fGuardTime*fLifeTimeFactor/1000.);
-    //cout << GetNodeName() << ": " << fmod(fTimeoutTime*10000, 10000)/10 << endl;
-
-    fTimeout->TurnOn();
-    //fTimeout->Start(fGuardTime, kTRUE);
+    fGuard = new NodeGuard(this, fGuardTime, fLifeTimeFactor, real);
+    fGuard->Start();
 
     lout << "- " << GetNodeName() << ": Guarding (" << dec;
@@ -517,9 +564,10 @@
 void NodeDrv::StartGuarding(Int_t ms, Int_t ltf, Bool_t real)
 {
-    if (fTimerOn)
+    if (fGuard)
     {
         lout << "- " << GetNodeName() << ": ERROR - Guarding already started." << endl;
         return;
     }
+
     fGuardTime      = ms;
     fLifeTimeFactor = ltf;
@@ -530,76 +578,11 @@
 void NodeDrv::StopGuarding()
 {
-    if (!fTimerOn)
+    if (!fGuard)
         return;
 
-    fTimeout->TurnOff();
-    fTimerOn = kFALSE;
+    delete fGuard;
+    fGuard=NULL;
 
     lout << "- " << GetNodeName() << ": Guarding stopped." << endl;
-}
-
-// --------------------------------------------------------------------------
-//
-// Handle the Nodeguard-Timer Event.
-// It checks whether the node timed out. If it timed out it is set to
-// the Zombie state.
-// A new Nodeguard request is send and a new timer event is triggered.
-//
-Bool_t NodeDrv::HandleTimer(TTimer *t)
-{
-    //
-    // WARNING:
-    //           It seems, that you should never access ANY output from
-    //           here. Neither the GUI, nor COUT. This can result in
-    //           'unexpected async reply'
-    //
-
-   /*
-     Fons:
-     -----
-
-     timers never trigger at the same time or when in a TTimer::Notify.
-     Little explanation:
-
-     - there are two types of timers synchronous and a-synchronous.
-     - synchronous timers are only handled via the ROOT eventloop
-       (see TUnixSystem::DispatchOneEvent()). If there are no mouse/keyboard
-       events then the synchronous timer queue is checked. So if the processing
-       of a mouse/keyboard event takes a long time synchronous timers are not
-       called for a while. To prevent this from happening one can call in long
-       procedures gSystem->ProcessEvents(). The system schedules only the
-       next timer in the queue when the current one's Notify() has finished.
-     - a-synchronous timers are triggered via SIGALARM, i.e. the program is
-       interupted and execution jumps to the Notify() function. When the
-       notify is finished the next a-sync timer is scheduled and the system
-       resumes from the place where it was initially interrupted. One of the
-       things to remember when using a-sync timers is don't make any graphics
-       calls in them. X11 is not re-entrant and it might be that the SIGALARM
-       signal interrupted the system while being in X11. A-sync timers are best
-       used to set flags that you can test at a convenient and controlled
-       time.
-       */
-    if (fIsZombie)
-        return kTRUE;
-
-    Timer time;
-    Double_t now = time.Now();
-    if (now > fTimeoutTime)
-    {
-        cout << GetNodeName() << ": " << "==out==> " << fmod(now*1000, 10000)/10 << " > " << fmod(fTimeoutTime*10000, 10000)/10 << endl;
-        //cout << "ERROR - " << GetNodeName() << " didn't respond in timeout window." << endl;
-        //lout << "ERROR - " << GetNodeName() << " didn't respond in timeout window." << endl;
-        //cout << dec << "+" << (int)GetId() << ": Handle: " << fmod(now, 500) << endl;
-        //cout << dec << "+" << (int)GetId() << ": Handle: " << fmod(fTimeoutTime, 500) << endl;
-        //cout << fGuardTime << endl;
-        fIsZombie = true;
-        //SetZombie();
-
-        return kTRUE;
-    }
-
-    SendNodeguard();
-
-    return kTRUE;
 }
 
@@ -611,12 +594,14 @@
 void NodeDrv::HandleNodeguard(timeval_t *tv)
 {
-    Timer t(tv);
-    fTimeoutTime = t + (fGuardTime*fLifeTimeFactor/1000.);
-    //cout << GetNodeName() << ": " << fmod(fTimeoutTime*10000, 10000)/10 << endl;
-}
-
-void NodeDrv::SetZombie()
+    if (fGuard)
+        fGuard->Reset(tv);
+}
+
+void NodeDrv::SetZombie(bool stopguard)
 {
     fIsZombie = true;
-    StopGuarding();
-}
+    if (stopguard)
+        StopGuarding();
+    else
+        lout << " - " << GetNodeName() << ": Zombie set due to timeout." << endl;
+}
Index: /trunk/MagicSoft/Cosy/candrv/nodedrv.h
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 2518)
@@ -19,6 +19,7 @@
 
 class Network;
+class NodeGuard;
 
-class NodeDrv : public Log, public TObject
+class NodeDrv : public Log
 {
 private:
@@ -30,13 +31,10 @@
     int fError;
 
-    Bool_t fIsZombie; // A Zombie node is a node which doesn't answer...
+    Bool_t  fIsZombie; // A Zombie node is a node which doesn't answer...
 
-    TTimer  *fTimeout;
-    Int_t    fGuardTime;      // Guardtime [ms]
-    Int_t    fLifeTimeFactor;
-    Double_t fTimeoutTime;
-    Bool_t   fTimerOn;
+    NodeGuard *fGuard;
 
-    Bool_t HandleTimer(TTimer *t);
+    Int_t   fGuardTime;      // Guardtime [ms]
+    Int_t   fLifeTimeFactor;
 
 protected:
@@ -46,6 +44,4 @@
     Int_t GetLifeTimeFactor() const { return fLifeTimeFactor; }
     Int_t GetGuardTime() const      { return fGuardTime; }
-
-    virtual void SetZombie();
 
 public:
@@ -67,4 +63,5 @@
 
     bool IsZombieNode() const { return fIsZombie; }
+    void SetZombie(bool stopguard=true);
 
     virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv);
Index: /trunk/MagicSoft/Cosy/candrv/sdolist.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/sdolist.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/sdolist.cc	(revision 2518)
@@ -10,21 +10,15 @@
     fFirst = new PendingSDO;
     fLast  = fFirst;
-
-    pthread_mutex_init(&fMux, NULL);
 }
 
 PendingSDOList::~PendingSDOList()
 {
-    // pthread_mutex_lock(&fMux);
-
     DelAll();
     delete fFirst;
-
-    pthread_mutex_destroy(&fMux);
 }
 
 void PendingSDOList::DelAll()
 {
-    pthread_mutex_lock(&fMux);
+    fMux.Lock();
 
     PendingSDO *prev = fFirst;
@@ -41,5 +35,5 @@
     fLast  = fFirst;
 
-    pthread_mutex_unlock(&fMux);
+    fMux.UnLock();
 }
 
@@ -48,5 +42,5 @@
     PendingSDO *sdo = fFirst;
 
-    pthread_mutex_lock(&fMux);
+    fMux.Lock();
     while ((sdo=sdo->Next))
         if (sdo->Node==node && sdo->Idx==idx && sdo->Subidx==subidx)
@@ -60,5 +54,5 @@
     fLast->Next = new PendingSDO(node, idx, subidx);
     fLast = fLast->Next;
-    pthread_mutex_unlock(&fMux);
+    fMux.UnLock();
 }
 
@@ -68,5 +62,5 @@
     PendingSDO *sdo;
 
-    pthread_mutex_lock(&fMux);
+    fMux.Lock();
     while ((sdo=prev->Next))
     {
@@ -86,5 +80,5 @@
         break;
     }
-    pthread_mutex_unlock(&fMux);
+    fMux.UnLock();
 }
 
@@ -99,5 +93,5 @@
     PendingSDO *sdo = fFirst;
 
-    pthread_mutex_lock(&fMux);
+    fMux.Lock();
     while ((sdo=sdo->Next))
         if (sdo->Node==node)
@@ -106,5 +100,5 @@
             break;
         }
-    pthread_mutex_unlock(&fMux);
+    fMux.UnLock();
 
     return rc;
@@ -116,5 +110,5 @@
     PendingSDO *sdo = fFirst;
 
-    pthread_mutex_lock(&fMux);
+    fMux.Lock();
     while ((sdo=sdo->Next))
         if (sdo->Node==node && sdo->Idx==idx && sdo->Subidx==subidx)
@@ -123,5 +117,5 @@
             break;
         }
-    pthread_mutex_unlock(&fMux);
+    fMux.UnLock();
 
     return rc;
Index: /trunk/MagicSoft/Cosy/candrv/sdolist.h
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/sdolist.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/sdolist.h	(revision 2518)
@@ -1,10 +1,4 @@
-#ifndef SDOLIST_H
-#define SDOLIST_H
-
-#ifdef __CINT__
-struct pthread_mutex_t;
-#else
-#include <pthread.h>
-#endif
+#ifndef COSY_SdoList
+#define COSY_SdoList
 
 #ifdef __CINT__
@@ -14,4 +8,8 @@
 #include <TROOT.h>
 #include "gendef.h"
+#endif
+
+#ifndef ROOT_TMutex
+#include <TMutex.h>
 #endif
 
@@ -36,5 +34,5 @@
     PendingSDO *fLast;
 
-    pthread_mutex_t fMux;
+    TMutex fMux;
 
 public:
Index: /trunk/MagicSoft/Cosy/candrv/vmodican.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 2518)
@@ -783,8 +783,5 @@
     arg.pm = pm;
 
-    if (!Ioctl(DPM_WRITE_MBOX, &arg))
-        return FALSE;
-
-    return arg.rval;
+    return Ioctl(DPM_WRITE_MBOX, &arg) ? arg.rval : 0;
 }
 
Index: /trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- /trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 2518)
@@ -1,5 +1,5 @@
 #include "macs.h"
 
-#include <iostream.h>
+#include <iostream>
 #include <sys/time.h>   // timeval->tv_sec
 
@@ -9,4 +9,6 @@
 
 ClassImp(Macs);
+
+using namespace std;
 
 /*
@@ -66,4 +68,12 @@
         return;
 
+    case 0x100c:
+        lout << "- " << GetNodeName() << ": Guard time:" << dec << val << endl;
+        return;
+
+    case 0x100d:
+        lout << "- " << GetNodeName() << ": Life time factor:" << dec << val << endl;
+        return;
+
     case 0x2002:
         cout << GetNodeName() << ": Current velocity: " << dec << val << endl;
@@ -140,4 +150,48 @@
     switch (idx)
     {
+    case 0x1000:
+        switch (subidx)
+        {
+        case 1:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": State of node set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+    case 0x100c:
+        switch (subidx)
+        {
+        case 0:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Guard time set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+    case 0x100d:
+        switch (subidx)
+        {
+        case 0:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Life time factor set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+    case 0x1800:
+        switch (subidx)
+        {
+        case 1:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Status of PDO1 set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
     case 0x2002:
         switch (subidx)
@@ -189,4 +243,33 @@
         HandleNodeguard(tv);
         return;
+
+    case 0x6000:
+        //lout << ddev(MLog::eGui);
+        lout << "- " << GetNodeName() << ": Rotation direction set." << endl;
+        //lout << edev(MLog::eGui);
+        return;
+
+    case 0x6002:
+        //lout << ddev(MLog::eGui);
+        lout << "- " << GetNodeName() << ": Velocitz resolution set." << endl;
+        //lout << edev(MLog::eGui);
+        return;
+
+    case 0x6003:
+        switch (subidx)
+        {
+        case 0:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Absolute positioning started." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+
+        case 1:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Relative positioning started." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
 
     case 0x6004:
@@ -271,6 +354,4 @@
     StopGuarding();
 
-// ****FIXME***   usleep(2000*GetGuardTime());
-
     lout << "- " << GetNodeName() << ": Requesting Mac Software Version." << endl;
     RequestSDO(0x100a);
@@ -302,7 +383,7 @@
     //SetNoWait(TRUE);
 
-    // StartGuarding(200, 2, kFALSE); // Using PDO1 @ 100ms
-    // StartGuarding(250, 4);
-    // StartHostGuarding();
+    StartGuarding(250, 1, kFALSE); // Using PDO1 @ 100ms
+    //StartGuarding(250, 4);
+    //StartHostGuarding();
 
     StartNode();
@@ -478,10 +559,8 @@
 void Macs::HandlePDO1(BYTE_t *data, timeval_t *tv)
 {
-    // FIXME!!!!
+    // FIXME!!!! Only 0x4000 should do this to be
+    // CanOpen conform
     HandleNodeguard(tv);
-/*
-    Timer t(tv);
-    cout << GetNodeName()<< " " <<t.GetTimeStr() << endl;
-*/
+
     fPdoPos    = (data[4]<<24) | (data[5]<<16) | (data[6]<<8) | data[7];
 
@@ -656,5 +735,8 @@
         return;
 
-    lout << GetNodeName() << ": Status PDO3 = ";
+    Timer time;
+    time.Now();
+
+    lout << time << ": " << GetNodeName() << " - PDO3 = ";
     const Bool_t ready = data[3]&0x01;
     const Bool_t fuse  = data[3]&0x02;
Index: /trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc
===================================================================
--- /trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 2518)
@@ -4,14 +4,12 @@
 #include "network.h"
 
-#include <iostream.h>      // cout
-#include <iomanip.h>       // setw, setfill
-
-#include <TSystem.h>       // gSystem
+#include <iostream>        // cout
+#include <iomanip>         // setw, setfill
+
 #include <TGLabel.h>       // TGLabel->SetText
 
-#include <pthread.h>
-#include <sys/resource.h>  // PRIO_PROCESS
-
 ClassImp(ShaftEncoder);
+
+using namespace std;
 
 ShaftEncoder::ShaftEncoder(const BYTE_t nodeid, const char *name, MLog &out)
@@ -104,4 +102,55 @@
 }
 
+void ShaftEncoder::HandleSDOOK(WORD_t idx, BYTE_t subidx, LWORD_t data, timeval_t *tv)
+{
+    switch (idx)
+    {
+    case 0x1802:
+        switch (subidx)
+        {
+        case 1:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": PDOs configured." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+    case 0x6001:
+        switch (subidx)
+        {
+        case 0:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Log.ticks/revolution set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+    case 0x6002:
+        switch (subidx)
+        {
+        case 0:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Max number of ticks set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+    case 0x6003:
+        switch (subidx)
+        {
+        case 0:
+            //lout << ddev(MLog::eGui);
+            lout << "- " << GetNodeName() << ": Preset value set." << endl;
+            //lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+    }
+    NodeDrv::HandleSDOOK(idx, subidx, data, tv);
+}
+
 void ShaftEncoder::DisplayVal()
 {
@@ -288,5 +337,5 @@
      */
 
-    //    StartGuarding(175, 2); // 175
+    // StartGuarding(200, 1, kTRUE); // 175
     // StartGuarding(10*GetId(), 2); // 175
 }
Index: /trunk/MagicSoft/Cosy/devdrv/shaftencoder.h
===================================================================
--- /trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 2518)
@@ -43,4 +43,5 @@
 
     void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv);
+    void HandleSDOOK(WORD_t idx, BYTE_t subidx, LWORD_t data, timeval_t *tv);
     /*
      void HandleSDOOK(WORD_t idx, BYTE_t subidx, timeval_t *tv) { NodeDrv::HandleSDOOK(idx, subidx, tv); }
Index: /trunk/MagicSoft/Cosy/gui/MGAccuracy.cc
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 2518)
@@ -149,4 +149,15 @@
 }
 
+void MGAccuracy::InitBar()
+{
+    fBar = new TLine(0, 0, 0, 0);
+    fBar->SetLineColor(kBlack);
+    fBar->SetLineStyle(1);
+    fBar->SetLineWidth(5);
+    fBar->Draw();
+
+    fList->Add(fBar);
+}
+
 void MGAccuracy::InitCross()
 {
@@ -176,4 +187,5 @@
     InitText();
     InitCross();
+    InitBar();
 
     InitCanvas();
@@ -215,7 +227,8 @@
     double dist = acos(d);
 
-    dist *= 3600./d2r;
+    dist *= 3600./d2r; // [min]
 
     int rs = (int)floor(fmod(dist, 60.));
+
     dist /= 60.;
     int rm = (int)dist;//floor(fmod(dist, 60.));
@@ -225,4 +238,13 @@
 
     fTxt->SetText(fTxt->GetX(), fTxt->GetY(), txt);
+
+    fBar->SetX2(dist*60);
+    if (dist*16384<1*360*60)
+        fBar->SetLineColor(kGreen);
+    else
+        if (dist*16384<2*360*60)
+            fBar->SetLineColor(kYellow);
+        else
+            fBar->SetLineColor(kRed);
 }
 
Index: /trunk/MagicSoft/Cosy/gui/MGAccuracy.h
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGAccuracy.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/gui/MGAccuracy.h	(revision 2518)
@@ -24,8 +24,11 @@
     TText  *fTxt;
 
+    TLine  *fBar;
+
     void DrawCoordinateSystem();
 
     void InitText();
     void InitCross();
+    void InitBar();
 
     void UpdateText(Float_t zd, Float_t x, Float_t y);
Index: /trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 2518)
@@ -53,4 +53,5 @@
     kPB_CALCALTAZ,
     kPB_TPOINT,
+    kPB_ENDSWITCH,
     kPB_START,
     kPB_DISPLAY1,
@@ -270,27 +271,15 @@
     fStopped->SetBackgroundColor(color);
 
-    fError   ->Move(10, 25);
-    fMoving  ->Move(10, 25+20);
-    fTracking->Move(10, 25+40);
-    fStopping->Move(10, 25+60);
-    fStopped ->Move(10, 25+80);
-    fAvailMac1->Move(10, 25+120);
-    fAvailMac2->Move(10, 25+140);
+    fError   ->MoveResize(10, 25, 60, 20);
+    fMoving  ->MoveResize(10, 25+20, 60, 20);
+    fTracking->MoveResize(10, 25+40, 60, 20);
+    fStopping->MoveResize(10, 25+60, 60, 20);
+    fStopped ->MoveResize(10, 25+80, 60, 20);
+    fAvailMac1->MoveResize(10, 25+120, 60, 20);
+    fAvailMac2->MoveResize(10, 25+140, 60, 20);
     //fAvailMac3->Move(10, 25+160);
-    fAvailSe1->Move(10, 25+180);
-    fAvailSe2->Move(10, 25+200);
-    fAvailSe3->Move(10, 25+220);
-
-    fError   ->Resize(60, 20);
-    fMoving  ->Resize(60, 20);
-    fTracking->Resize(60, 20);
-    fStopping->Resize(60, 20);
-    fStopped ->Resize(60, 20);
-    fAvailMac1->Resize(60, 20);
-    fAvailMac2->Resize(60, 20);
-    //fAvailMac3->Resize(60, 20);
-    fAvailSe1->Resize(60, 20);
-    fAvailSe2->Resize(60, 20);
-    fAvailSe3->Resize(60, 20);
+    fAvailSe1->MoveResize(10, 25+200, 60, 20);
+    fAvailSe2->MoveResize(10, 25+220, 60, 20);
+    fAvailSe3->MoveResize(10, 25+180, 60, 20);
 
     fList->Add(fError);
@@ -486,24 +475,20 @@
 
     but= new TGTextButton(tf2, "Ra -",  kPB_RAm);
-    but->Resize(50, 25);
-    but->Move(25, 210);
+    but->MoveResize(25, 210, 50, 25);
     but->SetToolTipText("Right ascension -= 1'");
     but->Associate(this);
     fList->Add(but);
     but= new TGTextButton(tf2, "RA +",  kPB_RAp);
-    but->Resize(50, 25);
-    but->Move(90, 210);
+    but->MoveResize(90, 210, 50, 25);
     but->SetToolTipText("Right ascension += 1'");
     but->Associate(this);
     fList->Add(but);
     but= new TGTextButton(tf2, "DEC +",  kPB_DECp);
-    but->Resize(50, 25);
-    but->Move(55, 185);
+    but->MoveResize(55, 185, 50, 25);
     but->SetToolTipText("Declination += 1'");
     but->Associate(this);
     fList->Add(but);
     but= new TGTextButton(tf2, "DEC -",  kPB_DECm);
-    but->Resize(50, 25);
-    but->Move(55, 235);
+    but->MoveResize(55, 235, 50, 25);
     but->SetToolTipText("Declination -= 1'");
     but->Associate(this);
@@ -511,6 +496,5 @@
 
     but = new TGTextButton(tf1, "Move'n'Track", kPB_TRACKPOS);
-    but->Resize(100, 25);
-    but->Move(25, 242);
+    but->MoveResize(25, 242, 100, 25);
     but->SetToolTipText("Move telescope to a Zd/Az position and start tracking.");
     but->Associate(this);
@@ -518,6 +502,5 @@
 
     but= new TGTextButton(tf2, "Calc Zd/Az",  kPB_CALCALTAZ);
-    but->Resize(80, 25);
-    but->Move(165, 197);
+    but->MoveResize(165, 197, 80, 25);
     but->SetToolTipText("Calculate Zd/Az corresponding to Ra/Dec.");
     but->Associate(this);
@@ -525,7 +508,12 @@
 
     but = new TGTextButton(tf4, "TPoint", kPB_TPOINT);
-    but->Resize(50, 25);
-    but->Move(176/*231*/, 213);
+    but->MoveResize(139, 213, 62, 25);
     but->SetToolTipText("Trigger writing a tpoint coordinate pair.");
+    but->Associate(this);
+    fList->Add(but);
+
+    but = new TGTextButton(tf4, "Endswitch", kPB_ENDSWITCH);
+    but->MoveResize(204, 213, 62, 25);
+    but->SetToolTipText("Print coordinates in 'Endswitch-Position' units.");
     but->Associate(this);
     fList->Add(but);
@@ -533,6 +521,5 @@
 #ifdef EXPERT
     but= new TGTextButton(tf1, "New Position",  kPB_SavePreDef);
-    but->Resize(80, 25);
-    but->Move(165, 197);
+    but->MoveResize(165, 197, 80, 25);
     but->SetToolTipText("Save new predefined position.");
     but->Associate(this);
@@ -540,6 +527,5 @@
 
     but= new TGTextButton(tf4, "New", kPB_SaveStar);
-    but->Resize(60, 23);
-    but->Move(211, 69);
+    but->MoveResize(211, 69, 60, 23);
     but->SetToolTipText("Save new Source position.");
     but->Associate(this);
@@ -547,6 +533,5 @@
 
     but = new TGTextButton(tf5, "Display", kPB_DISPLAY1);
-    but->Resize(80, 25);
-    but->Move(160, 197);
+    but->MoveResize(160, 197, 80, 25);
     but->SetToolTipText("Display Histogram.");
     but->Associate(this);
@@ -554,6 +539,5 @@
 
     but = new TGTextButton(tf6, "Display", kPB_DISPLAY2);
-    but->Resize(80, 25);
-    but->Move(160, 197);
+    but->MoveResize(160, 197, 80, 25);
     but->SetToolTipText("Display Histogram.");
     but->Associate(this);
@@ -561,6 +545,5 @@
 
     but = new TGTextButton(tf4, "Load", kPB_LoadBending);
-    but->Resize(50, 25);
-    but->Move(151, 185);
+    but->ResizeMove(151, 185, 50, 25);
     but->SetToolTipText("Load bending corrections from file 'bending.txt'");
     but->Associate(this);
@@ -568,6 +551,5 @@
 
     but = new TGTextButton(tf4, "Reset", kPB_ResetBending);
-    but->Resize(50, 25);
-    but->Move(206, 185);
+    but->MoveResize(206, 185, 50, 25);
     but->SetToolTipText("Reset bending correction (coefficients=0)");
     but->Associate(this);
@@ -575,24 +557,20 @@
 
     but= new TGTextButton(tf4, "Zd -",  kPB_ZDm);
-    but->Resize(50, 25);
-    but->Move(25, 210);
+    but->MoveResize(25, 210, 50, 25);
     but->SetToolTipText("Zenith Distance -= 1SE");
     but->Associate(this);
     fList->Add(but);
     but= new TGTextButton(tf4, "Zd +",  kPB_ZDp);
-    but->Resize(50, 25);
-    but->Move(90, 210);
+    but->MoveResize(90, 210, 50, 25);
     but->SetToolTipText("Zenith Distance += 1SE");
     but->Associate(this);
     fList->Add(but);
     but= new TGTextButton(tf4, "Az +",  kPB_AZp);
-    but->Resize(50, 25);
-    but->Move(55, 185);
+    but->MoveResize(55, 185, 50, 25);
     but->SetToolTipText("Azimuth += 1SE");
     but->Associate(this);
     fList->Add(but);
     but= new TGTextButton(tf4, "Az -",  kPB_AZm);
-    but->Resize(50, 25);
-    but->Move(55, 235);
+    but->MoveResize(55, 235, 50, 25);
     but->SetToolTipText("Azimuth -= 1SE");
     but->Associate(this);
@@ -605,6 +583,5 @@
     gClient->GetColorByName("Green", color);
     but->SetBackgroundColor(color);
-    but->Move(147, 295);
-    but->Resize(62, 25);
+    but->MoveResize(147, 295, 62, 25);
     but->SetToolTipText("Start a telescope movement.");
     fList->Add(but);
@@ -614,6 +591,5 @@
     gClient->GetColorByName("Red", color);
     but->SetBackgroundColor(color);
-    but->Move(212, 295);
-    but->Resize(62, 25);
+    but->MoveResize(212, 295, 62, 25);
     but->SetToolTipText("Stop any movement of telescope.");
     fList->Add(but);
@@ -989,6 +965,4 @@
 void MGCosy::UpdateZdAz(ZdAz &soll)
 {
-    soll *= kRad2Deg;
-
     static Int_t zd=~0;
     static Int_t az=~0;
@@ -996,10 +970,16 @@
     char text[21];
 
-    ZdAz test = soll*600;
-
+    UShort_t z, a;
+    Double_t zm, am;
+    Char_t   sz, sa;
+
+    Slalib::Rad2Dm(soll.Zd(), sz, z, zm);
+    Slalib::Rad2Dm(soll.Az(), sa, a, am);
+
+    const ZdAz test = soll*kRad2Deg*600;
     if (zd!=(int)test.Zd())
     {
         zd = (int)test.Zd();
-        sprintf(text, "%c%dd %.1fm", soll.Zd()<0?'-':'+', abs((int)soll.Zd()), 0.1*(abs((int)test.Zd())%600));
+        sprintf(text, "%c%dd %.1fm", sz, z, zm);
         fZdSoll->SetText(new TGString(text));
     }
@@ -1007,5 +987,5 @@
     {
         az = (int)test.Az();
-        sprintf(text, "%c%dd %.1fm", soll.Az()<0?'-':'+' , abs((int)soll.Az()), 0.1*(abs((int)test.Az())%600));
+        sprintf(text, "%c%dd %.1fm", sa, a, am);
         fAzSoll->SetText(new TGString(text));
     }
@@ -1113,5 +1093,5 @@
     // TGMainFrame::CloseWindow();
     cout << "Closing window - waiting until all nodes are stopped." << endl;
-    fQueue->PostMsg(WM_QUIT, 0, 0);
+    fQueue->PostMsg(WM_QUIT);
     cout << "Closing window - done." << endl;
     // gApplication->Terminate(0);
@@ -1376,9 +1356,9 @@
                 StopDemo();
 #endif
-                fQueue->PostMsg(WM_STOP, 0, 0);
+                fQueue->PostMsg(WM_STOP);
                 if (fTab->GetCurrent()==3)
-                    fQueue->Proc(WM_TESTSE, NULL);
+                    fQueue->Proc(WM_TESTSE);
                 if (fTab->GetCurrent()==4)
-                    fQueue->Proc(WM_GEAR, NULL);
+                    fQueue->Proc(WM_GEAR);
                 cout << "PostMsg (WM_Stop) returned." << endl;
                 return kTRUE;
@@ -1458,4 +1438,8 @@
                 StartTPoint();
                 return kTRUE;
+
+            case kPB_ENDSWITCH:
+                fQueue->Proc(WM_ENDSWITCH);
+                return kTRUE;
                 /*
             case kPB_CALIBSE:
@@ -1464,8 +1448,8 @@
                 */
             case kPB_LoadBending:
-                fQueue->Proc(WM_LOADBENDING, NULL);
+                fQueue->Proc(WM_LOADBENDING);
                 return kTRUE;
             case kPB_ResetBending:
-                fQueue->Proc(WM_RESETBENDING, NULL);
+                fQueue->Proc(WM_RESETBENDING);
                 return kTRUE;
                 /*
@@ -1479,5 +1463,5 @@
             case kPB_DISPLAY1:
             case kPB_DISPLAY2:
-                fQueue->PostMsg(WM_DISPLAY, 0, 0);
+                fQueue->PostMsg(WM_DISPLAY);
                 return kTRUE;
 
@@ -1493,5 +1477,5 @@
             case IDM_EXIT:
                 cout << "IDM_EXIT: Posting WM_QUIT." << endl;
-                fQueue->PostMsg(WM_QUIT, 0, 0);
+                fQueue->PostMsg(WM_QUIT);
                 cout << "IDM_EXIT: WM_QUIT done." << endl;
                 //cout << "Idm_Exit." << endl;
Index: /trunk/MagicSoft/Cosy/gui/MGImage.cc
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGImage.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/gui/MGImage.cc	(revision 2518)
@@ -9,15 +9,12 @@
 #include "MGImage.h"
 
-#include <iostream.h>
-#include <pthread.h>
-
-#include <X11/Xlib.h>
-
-#include <TTimer.h>
-#include <TSystem.h>
-#include <TVirtualX.h>
+#include <iostream>
+
 #include <TGX11.h>
+#include <TMutex.h>
 
 ClassImp(MGImage);
+
+using namespace std;
 /*
 class MyX11 : public TGX11
@@ -41,6 +38,5 @@
     // Creat drawing semaphore
     //
-    fMuxPixmap = new pthread_mutex_t;
-    pthread_mutex_init((pthread_mutex_t*)fMuxPixmap, NULL);
+    fMuxPixmap = new TMutex;
 
     Resize(w, h);
@@ -58,5 +54,5 @@
 MGImage::~MGImage()
 {
-    pthread_mutex_lock((pthread_mutex_t*)fMuxPixmap);
+    fMuxPixmap->Lock();
 
     cout << "Deleting MGImage..." << endl;
@@ -66,5 +62,5 @@
     gVirtualX->DeleteImage((Drawable_t)fImage);
 
-    pthread_mutex_destroy((pthread_mutex_t*)fMuxPixmap);
+    delete fMuxPixmap;
 
     cout << "MGImage destroyed." << endl;
@@ -73,5 +69,5 @@
 void MGImage::DoRedraw()
 {
-    pthread_mutex_lock((pthread_mutex_t*)fMuxPixmap);
+    fMuxPixmap->Lock();
 
     if (TestBit(kNeedRedraw))
@@ -81,5 +77,5 @@
     }
 
-    pthread_mutex_unlock((pthread_mutex_t*)fMuxPixmap);
+    fMuxPixmap->UnLock();
 }
 
@@ -91,4 +87,5 @@
     while (s<e)
     {
+        //      11111100    11111000      11111100
         *d++ = (*s&0xfc) | (*s&0xf8)<<5 | (*s&0xfc)<<11;
         s++;
@@ -107,4 +104,52 @@
         *d++ = *s++;
         d++;
+    }
+}
+
+void MGImage::DrawImg(const byte *buffer)
+{
+    if (fMuxPixmap->TryLock()==13)
+        return;
+
+    switch (gVirtualX->GetDepth())
+    {
+    case 8:
+        memcpy(fImage->data, buffer, fWidth*fHeight);
+        break;
+    case 16:
+        DrawImg16((unsigned short*)fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight));
+        break;
+    case 24:
+        DrawImg24(fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight));
+        break;
+    default:
+        cout << "Sorry, " << gVirtualX->GetDepth() << "bit color depth not yet implemented." << endl;
+    }
+
+    SetBit(kNeedRedraw);
+
+    fMuxPixmap->UnLock();
+}
+
+void MGImage::DrawColImg16(unsigned short *d, char *s1, char *s2, char *e)
+{
+    // d=destination, s1=source1, s2=source2, e=end
+    // d:  rrrrrggg gggbbbbb
+    // s2:          00rrggbb
+    //
+    while (s1<e)
+    {
+        if (*s2)
+        {    
+            //      00000011   00001100        00110000
+            *d++ = (*s2&0x3) | (*s2&0xb)<<3 | (*s2&0x30)<<7;
+            s1++;
+        }
+        else
+        {
+            //      11111100     11111000        11111100
+            *d++ = (*s1&0xfc) | (*s1&0xf8)<<5 | (*s1&0xfc)<<11;
+            s2++;
+        }
     }
 }
@@ -134,32 +179,7 @@
 }
 
-void MGImage::DrawImg(const byte *buffer)
-{
-    if (pthread_mutex_trylock((pthread_mutex_t*)fMuxPixmap))
-        return;
-
-    switch (gVirtualX->GetDepth())
-    {
-    case 8:
-        memcpy(fImage->data, buffer, fWidth*fHeight);
-        break;
-    case 16:
-        DrawImg16((unsigned short*)fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight));
-        break;
-    case 24:
-        DrawImg24(fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight));
-        break;
-    default:
-        cout << "Sorry, " << gVirtualX->GetDepth() << "bit color depth not yet implemented." << endl;
-    }
-
-    SetBit(kNeedRedraw);
-
-    pthread_mutex_unlock((pthread_mutex_t*)fMuxPixmap);
-}
-
 void MGImage::DrawColImg(const byte *gbuf, const byte *cbuf)
 {
-    if (pthread_mutex_trylock((pthread_mutex_t*)fMuxPixmap))
+    if (fMuxPixmap->TryLock()==13)
         return;
 
@@ -179,6 +199,9 @@
     switch (gVirtualX->GetDepth())
     {
+    case 16:
+        DrawColImg16((unsigned short*)fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight));
+        break;
     case 24:
-        DrawColImg32(fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight));
+        DrawColImg24(fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight));
         break;
     default:
@@ -188,4 +211,4 @@
     SetBit(kNeedRedraw);
 
-    pthread_mutex_unlock((pthread_mutex_t*)fMuxPixmap);
-}
+    fMuxPixmap->UnLock();
+}
Index: /trunk/MagicSoft/Cosy/gui/MGImage.h
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGImage.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/gui/MGImage.h	(revision 2518)
@@ -15,5 +15,5 @@
 #endif
 
-class TTimer;
+class TMutex;
 
 typedef unsigned char byte;
@@ -29,7 +29,5 @@
     UInt_t fHeight;
 
-    void *fMuxPixmap; //! test
-
-    TTimer *fTimer;
+    TMutex *fMuxPixmap; //! test
 
     enum { kNeedRedraw = BIT(17) };
@@ -37,4 +35,5 @@
     void DrawImg16(unsigned short *d, char *s, char *e);
     void DrawImg24(char *d, char *s, char *e);
+    void DrawColImg16(unsigned short *d, char *s1, char *s2, char *e);
     void DrawColImg24(char *d, char *s1, char *s2, char *e);
 
Index: /trunk/MagicSoft/Cosy/main/MBending.cc
===================================================================
--- /trunk/MagicSoft/Cosy/main/MBending.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/main/MBending.cc	(revision 2518)
@@ -68,4 +68,8 @@
 ClassImp(MBending);
 
+#undef DEBUG
+#define DEBUG(txt) txt
+//#define DEBUG(txt)
+
 const Int_t MBending::fNumPar=19;
 
@@ -286,4 +290,7 @@
     AltAz p = aa;
 
+    DEBUG(cout << setprecision(16));
+    DEBUG(cout << "Bend8: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz CRX(-fCrx*sin(p.Az()-p.Alt()),  fCrx*cos(p.Az()-p.Alt())/cos(p.Alt()));
     const AltAz CRY(-fCry*cos(p.Az()-p.Alt()), -fCry*sin(p.Az()-p.Alt())/cos(p.Alt()));
@@ -291,4 +298,6 @@
     p += CRY;
 
+    DEBUG(cout << "Bend7: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz NRX(fNrx*sin(p.Alt()), -fNrx);
     const AltAz NRY(fNry*cos(p.Alt()), -fNry*tan(p.Alt()));
@@ -296,4 +305,6 @@
     p += NRY;
 
+    DEBUG(cout << "Bend6: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz CES(-fEces*sin(p.Alt()), -fAces*sin(p.Az()));
     const AltAz CEC(-fEcec*cos(p.Alt()), -fAcec*cos(p.Az()));
@@ -301,8 +312,15 @@
     p += CEC;
 
+    DEBUG(cout << "Bend5: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz TX(Sign(fTx/tan(p.Alt()), p.Alt()), 0);
     const AltAz TF(Sign(fTf*cos(p.Alt()), p.Alt()), 0);
-    p += TX;
+    //p += TX;
     p += TF;
+
+    DEBUG(cout << "Bend4: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
+    cout << fAw << " " << cos(p.Az()) << " " << tan(p.Alt()) << endl;
+    cout << fAw* cos(p.Az())*tan(p.Alt())*180/3.1415 << endl;
 
     const AltAz AW( fAw*sin(p.Az()), -fAw*cos(p.Az())*tan(p.Alt()));
@@ -311,10 +329,16 @@
     p += AN;
 
+    DEBUG(cout << "Bend3: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz CA(0, -fCa/cos(p.Alt()));
     p += CA;
 
+    DEBUG(cout << "Bend2: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz NPAE(0, -fNpae*tan(p.Alt()));
     p += NPAE;
 
+    DEBUG(cout << "Bend1: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz FLOP(Sign(fFlop, p.Alt()), 0);
     p += FLOP;
@@ -323,8 +347,10 @@
     p += I;
 
+    DEBUG(cout << "Bend0: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     return p;
 }
 
-AltAz MBending::CorrectBack(const AltAz &aa) const
+AltAz MBending::AddOffsets(const AltAz &aa) const
 {
     // Correct [rad]
@@ -333,4 +359,19 @@
 
     const AltAz I(fIe, fIa);
+    p += I;
+
+    return p;
+}
+
+AltAz MBending::CorrectBack(const AltAz &aa) const
+{
+    // Correct [rad]
+    // zdaz    [rad]
+    AltAz p = aa;
+
+    DEBUG(cout << setprecision(16));
+    DEBUG(cout << "Back0: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
+    const AltAz I(fIe, fIa);
     p -= I;
 
@@ -338,9 +379,18 @@
     p -= FLOP;
 
+    DEBUG(cout << "Back1: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz NPAE(0, -fNpae*tan(p.Alt()));
     p -= NPAE;
 
+    DEBUG(cout << "Back2: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz CA(0, -fCa/cos(p.Alt()));
     p -= CA;
+
+    DEBUG(cout << "Back3: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
+    cout << fAw << " " << cos(p.Az()) << " " << tan(p.Alt()) << endl;
+    cout << fAw* cos(p.Az())*tan(p.Alt())*180/3.1415 << endl;
 
     const AltAz AN(-fAn*cos(p.Az()), -fAn*sin(p.Az())*tan(p.Alt()));
@@ -349,8 +399,12 @@
     p -= AW;
 
+    DEBUG(cout << "Back4: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz TF(Sign(fTf*cos(p.Alt()), p.Alt()), 0);
     const AltAz TX(Sign(fTx/tan(p.Alt()), p.Alt()), 0);
     p -= TF;
-    p -= TX;
+    //p -= TX;
+
+    DEBUG(cout << "Back5: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
 
     const AltAz CEC(-fEcec*cos(p.Alt()), -fAcec*cos(p.Az()));
@@ -359,4 +413,6 @@
     p -= CES;
 
+    DEBUG(cout << "Back6: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz NRY(fNry*cos(p.Alt()), -fNry*tan(p.Alt()));
     const AltAz NRX(fNrx*sin(p.Alt()), -fNrx);
@@ -364,4 +420,6 @@
     p -= NRX;
 
+    DEBUG(cout << "Back7: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     const AltAz CRY(-fCry*cos(p.Az()-p.Alt()), -fCry*sin(p.Az()-p.Alt())/cos(p.Alt()));
     const AltAz CRX(-fCrx*sin(p.Az()-p.Alt()),  fCrx*cos(p.Az()-p.Alt())/cos(p.Alt()));
@@ -369,6 +427,21 @@
     p -= CRX;
 
+    DEBUG(cout << "Back8: " << 90-p.Alt()*180/TMath::Pi() << " " << p.Az()*180/TMath::Pi() << endl);
+
     return p;
 }
+
+AltAz MBending::SubtractOffsets(const AltAz &aa) const
+{
+    // Correct [rad]
+    // zdaz    [rad]
+    AltAz p = aa;
+
+    const AltAz I(fIe, fIa);
+    p -= I;
+
+    return p;
+}
+
 
 ZdAz MBending::Correct(const ZdAz &zdaz) const
Index: /trunk/MagicSoft/Cosy/main/MBending.h
===================================================================
--- /trunk/MagicSoft/Cosy/main/MBending.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/main/MBending.h	(revision 2518)
@@ -91,4 +91,20 @@
     }
 
+    AltAz  AddOffsets(const AltAz &aa) const;
+    ZdAz   AddOffsets(const ZdAz &zdaz) const
+    {
+        AltAz p(TMath::Pi()/2-zdaz.Zd(), zdaz.Az());
+        AltAz c = AddOffsets(p);
+        return ZdAz(TMath::Pi()/2-c.Alt(), c.Az());
+    }
+
+    AltAz  SubtractOffsets(const AltAz &aa) const;
+    ZdAz   SubtractOffsets(const ZdAz &zdaz) const
+    {
+        AltAz p(TMath::Pi()/2-zdaz.Zd(), zdaz.Az());
+        AltAz c = SubtractOffsets(p);
+        return ZdAz(TMath::Pi()/2-c.Alt(), c.Az());
+    }
+
     void SetParameters(const Double_t *par, Int_t n=fNumPar);
     void GetParameters(Double_t *par, Int_t n=fNumPar) const;
Index: /trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- /trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 2518)
@@ -251,6 +251,4 @@
 }
 
-
-
 // --------------------------------------------------------------------------
 //
@@ -340,14 +338,17 @@
         usleep(1);
 
-    if (Break() || HasError() || HasZombie())
-    {
-        lout << "WaitForEndMovement aborted... ";
-        if (Break())
-            lout << "Break signal." << endl;
-        if (HasError())
-            lout << "Network has error." << endl;
-        if (HasZombie())
-            lout << "Network has zombie." << endl;
-    }
+    if (!Break() && !HasError() && !HasZombie())
+        return;
+
+    Timer t;
+    t.Now();
+    lout << t << " - MCosy::WaitForEndMovement aborted...";
+    if (Break())
+        lout << " Break signal...";
+    if (HasError())
+        lout << " Network has error...";
+    if (HasZombie())
+        lout << " Network has zombie...";
+    lout << endl;
 }
 
@@ -364,14 +365,18 @@
     // status is set to stopped.
     //
-    if (!HasError())
-    {
+    if (HasError() || HasZombie())
+    {
+        SetStatus(MDriveCom::kError);
+        return;
+    }
+
+    if (fMac1->IsPositioning() || fMac2->IsPositioning())
+        SetStatus(MDriveCom::kMoving);
+    else
         SetStatus(MDriveCom::kStopped);
-        return;
-    }
 
     //
     // If there is an error, the error status is set to Error.
     //
-    SetStatus(MDriveCom::kError);
 
     /*
@@ -399,19 +404,30 @@
 Bool_t MCosy::CheckRange(const ZdAz &d) const
 {
-    // d [deg]
-
-    if (d.Zd()<fMin.Zd() || d.Zd()>fMax.Zd())
-    {
-        lout << "ERROR: Requested Zenith Angle (" << d.Zd() << "deg, Az=";
-        lout << d.Az() << ") not inside allowed range." << endl;
+    // d [rad]
+
+    if (d.Zd()<fMin.Zd())
+    {
+        lout << "ERROR: Requested Zenith Angle below negative endswitch." << endl;
         return kFALSE;
     }
 
-    if (d.Az()<fMin.Az() || d.Az()>fMax.Az())
-    {
-        lout << "ERROR: Requested Azimuth Angle (" << d.Az() << "deg, Zd=";
-        lout << d.Zd() << ") not inside allowed range." << endl;
+    if (d.Zd()>fMax.Zd())
+    {
+        lout << "ERROR: Requested Zenith Angle behind positive endswitch." << endl;
         return kFALSE;
     }
+
+    if (d.Az()<fMin.Az())
+    {
+        lout << "ERROR: Requested Azimuth Angle below negative endswitch." << endl;
+        return kFALSE;
+    }
+
+    if (d.Az()>fMax.Az())
+    {
+        lout << "ERROR: Requested Azimuth Angle behind positive endswitch." << endl;
+        return kFALSE;
+    }
+
 
     return kTRUE;
@@ -437,7 +453,4 @@
     lout << t << " - Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl;
 
-    if (!CheckRange(d))
-        return kFALSE;
-
     //
     // Calculate new target position (shortest distance to go)
@@ -459,11 +472,18 @@
     // const ZdAz dest = CorrectTarget(src, dst);
     //
-    const ZdAz dest = fBending(dst)*16384/2/TMath::Pi(); // [se]
+    ZdAz bend = fBending(dst); // [rad]
+
+    const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
+
+    if (!CheckRange(bend))
+        return kFALSE;
+
+    bend *= kRad2Deg;
     fZdAzSoll = dst;
 
     cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
     cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
-    cout << "Bend'd Dest   Zd: " << Rad2SE(fZdAzSoll.Zd()) << "se  Az:" << Rad2SE(fZdAzSoll.Az())  << "se" << endl;
-    cout << "Shortest Dest Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
+    cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
+    cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
 
     //
@@ -476,5 +496,5 @@
     {
 
-        lout << "Step #" << i << endl;
+        lout << "- Step #" << i << endl;
         //
         // Get Shaft Encoder Positions
@@ -586,7 +606,14 @@
         //
 
-        lout << "Do Relative Positioning..." << endl;
+        lout << "- Do Relative Positioning..." << endl;
         DoRelPos(rd, cdzd, cdaz);
-        lout << "Relative Positioning Done" << endl;
+        lout << "- Relative Positioning Done" << endl;
+    }
+    if (i==1 && track && !(Break() || HasError() || HasZombie()))
+    {
+        t.Now();
+        lout << t << " - Positioning done." << endl;
+        SetStatus(MDriveCom::kStopped);
+        return TRUE;
     }
 
@@ -597,5 +624,5 @@
 
     t.Now();
-    lout << t << " - Warning: Requested position not reached (i=" << i << ")" << endl;
+    lout << t << " - Warning: Requested position not reached (i=" << dec << i << ")" << endl;
     return FALSE;
 }
@@ -759,5 +786,5 @@
         }
 }
-
+/*
 Bool_t MCosy::AlignTrackingPos(ZdAz pointing, ZdAz &za) const
 {
@@ -789,4 +816,41 @@
     return rc;
 }
+*/
+
+ZdAz MCosy::AlignTrackingPos(ZdAz pointing) const
+{
+    // pointing [rad]
+    // AlignTrackingPos [deg]
+
+    pointing *= kRad2Deg;
+
+    if (pointing.Zd()<0)
+    {
+        pointing.Zd(-pointing.Zd());
+        pointing.Az(pointing.Az()+180);
+    }
+
+    const ZdAz se = GetSePos()*2*TMath::Pi()/16384;   // [rad]
+    const ZdAz unbendedse = fBending.CorrectBack(se)*kRad2Deg; // ist pointing
+
+    do
+    {
+        const Double_t d = unbendedse.Az() - pointing.Az();
+        if (d>-180 && d<=180)
+            break;
+
+        pointing.Az(pointing.Az()+TMath::Sign(360., d));
+    } while (1);
+
+    return pointing/kRad2Deg;
+/*
+    const Bool_t rc = CheckRange(pointing);
+    za = pointing/kRad2Deg; // [rad]
+
+    if (!rc)
+        lout << "Error: Aligned position out of Range." << endl;
+
+    return rc;*/
+}
 
 Double_t MCosy::Starguider(Double_t mjd, ZdAz &dest) const
@@ -804,10 +868,13 @@
         return -1;
 
-    ZdAz point;
+    ZdAz point=AlignTrackingPos(ZdAz(zd, az)/kRad2Deg);
+    /*
     if (!AlignTrackingPos(ZdAz(zd, az), point))
     {
         cout << "Starguider position couldn't be aligned..." << endl;
         return -1;
-    }
+    }*/
+
+    // FIXME: Check Range missing!
 
     const ZdAz diff = (dest-point)*kRad2Deg;
@@ -854,4 +921,5 @@
 
     if (!SetPosition(dest, kTRUE))
+    //if (!SetPosition(dest, kFALSE))
     {
         lout << "Error: Cannot start tracking, positioning failed." << endl;
@@ -925,9 +993,12 @@
         //
         const Double_t mjd = sla.GetMjd()+dt/(60*60*24);
-        const ZdAz pointing = sla.CalcZdAz(fRaDec, mjd)*kRad2Deg; // soll pointing [deg]
-
+        const ZdAz pointing = sla.CalcZdAz(fRaDec, mjd); // soll pointing [deg]
+
+        /*
         ZdAz dest;
         if (!AlignTrackingPos(pointing, dest))
             break;
+            */
+        ZdAz dest = AlignTrackingPos(pointing);
 
         ZdAz vcalc = sla.GetApproxVel(fRaDec) * kGearRatio2*4./60.;  // [re/min]
@@ -940,4 +1011,8 @@
         {
             dest = fBending(dest);       // [rad]
+
+            if (!CheckRange(dest))
+                break;
+
             dest *= 16384/TMath::Pi()/2; // [se]
             dest *= kGearRatio;          // [re]
@@ -1021,4 +1096,5 @@
          */
         usleep(1000000); // 1s
+        cout << "." << flush;
         //usleep(50000); // 0.05s
     }
@@ -1138,4 +1214,6 @@
     //CheckConnections();
 
+    CheckForError();
+
     if (HasZombie())
     {
@@ -1157,4 +1235,5 @@
     }
 
+    CheckForError();
     return true;
 }
@@ -1274,6 +1353,6 @@
         cout << "WM_Position: start." << endl;
         {
-            if (!CheckNetwork())
-                return (void*)0xebb0;
+            //if (!CheckNetwork())
+            //    return (void*)0xebb0;
 
             ZdAz dest = *((ZdAz*)mp);
@@ -1387,13 +1466,14 @@
 
             ZdAz a1 = sla.CalcZdAz(rd*kDeg2Rad); // [rad]
-            const ZdAz a0 = a1*kRad2Deg;               // [deg]
 
             cout << "Ra/Dec source: " << xy.X()  << "h " << xy.Y()  << "°" << endl;
-            cout << "Zd/Az target:  " << a0.Zd() << "° " << a0.Az() << "°" << endl;
+            cout << "Zd/Az target:  " << a1.Zd()*kRad2Deg << "° " << a1.Az()*kRad2Deg << "°" << endl;
 
             if (fZd1 && fZd2 && fAz)
-                AlignTrackingPos(a0, a1);
-
-            a1 = fBending(a1)*kRad2Deg;
+                a1 = AlignTrackingPos(a1);
+
+            a1 = fBending(a1);
+            CheckRange(a1);
+            a1 *= kRad2Deg;
 
             const ZdAz a2 = a1*16384/360;
@@ -1403,4 +1483,15 @@
         }
         return (void*)0xa17a;
+
+    case WM_ENDSWITCH:
+        {
+            ZdAz pos = GetSePos()*TMath::Pi()*2/16384;
+            pos = fBending.SubtractOffsets(pos)*kRad2Deg;
+
+            cout << "Endswitch Position:  Zd=" << pos.Zd() << "°  Az=";
+            cout << pos.Az() << "°" << endl;
+        }
+
+        return (void*)0x1010;
 
     case WM_QUIT:
@@ -1436,11 +1527,17 @@
     fMin.Set(zmin, amin);
 
-    cout << " Min: " << zmin << "deg  " << amin << "deg" << endl;
-
     const Double_t amax = env.GetValue("Az_Max[deg]", 305.0);
     const Double_t zmax = env.GetValue("Zd_Max[deg]", 98.25);
     fMax.Set(zmax, amax);
-
-    cout << " Max: " << zmax << "deg  " << amax << "deg" << endl;
+    cout << "done." << endl;
+
+    cout << " * Min:  " << zmin << "deg  " << amin << "deg" << endl;
+    cout << " * Max:  " << zmax << "deg  " << amax << "deg" << endl;
+
+    fMin = fBending.AddOffsets(fMin/kRad2Deg);
+    fMax = fBending.AddOffsets(fMax/kRad2Deg);
+
+    cout << " * Min': " << fMin.Zd()*kRad2Deg << "deg  " << fMin.Az()*kRad2Deg << "deg" << endl;
+    cout << " * Max': " << fMax.Zd()*kRad2Deg << "deg  " << fMax.Az()*kRad2Deg << "deg" << endl;
 
     cout << "Reading gear ratios..." << flush;
@@ -1515,5 +1612,5 @@
         return;
 
-    lout << "Tracking Thread started..." << endl;
+    lout << "- Tracking Thread started..." << endl;
 
     SlaStars sla(fObservatory);
@@ -1616,5 +1713,5 @@
         ZdAz soll(sollzd.Zd(), sollaz.Az()); // [rad]
 
-        AlignTrackingPos(soll*kRad2Deg, fZdAzSoll);
+        fZdAzSoll = AlignTrackingPos(soll);
 
         ist *= TMath::Pi()*2/16384;
@@ -1628,5 +1725,5 @@
     }
 
-    lout << "Tracking Thread done." << endl;
+    lout << "- Tracking Thread done." << endl;
 
     //---        fout << endl << endl;
@@ -1818,7 +1915,17 @@
 ZdAz MCosy::GetPointingPos() const
 {
+    if (fZd1->IsZombieNode() || fZd2->IsZombieNode() || fAz->IsZombieNode())
+        return ZdAz(0, 0);
+
     // GetPointingPos [deg]
     const ZdAz seist = GetSePos()*2*TMath::Pi()/16384; // [se]
-    return fBending.CorrectBack(seist)*180/TMath::Pi();
+
+    cout << seist.Zd()*kRad2Deg << " " << seist.Az()*kRad2Deg << endl;
+
+    ZdAz back = fBending.CorrectBack(seist)*180/TMath::Pi();
+
+    cout << back.Zd() << " " << back.Az() << endl;
+
+    return back;
 }
 
@@ -1865,5 +1972,5 @@
     // FIXME: Not thread safe!
     static int i=0;
-    if (i++==8)
+    if (i++==7)
     {
         fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError);
@@ -2002,4 +2109,6 @@
     // Don't call this function twice!
     Network::Start();
+
+    CheckForError();
 
     ReadConfig();
@@ -2180,5 +2289,5 @@
     // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
 
-    fCom = new MDriveCom(out);
+    fCom = new MDriveCom(this, out);
     fCom->Start();
 }
Index: /trunk/MagicSoft/Cosy/main/MCosy.h
===================================================================
--- /trunk/MagicSoft/Cosy/main/MCosy.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/main/MCosy.h	(revision 2518)
@@ -31,4 +31,5 @@
 #define WM_TRACKPOS     0x100e
 #define WM_POSITION1    0x100f
+#define WM_ENDSWITCH    0x1010
 
 class ShaftEncoder;
@@ -115,5 +116,6 @@
     ofstream *tpout;
 
-    Bool_t AlignTrackingPos(ZdAz pointing, ZdAz &za) const;
+    //Bool_t AlignTrackingPos(ZdAz pointing, ZdAz &za) const;
+    ZdAz AlignTrackingPos(ZdAz pointing) const;
     Bool_t CheckRange(const ZdAz &d) const;
     Double_t Starguider(Double_t mjd, ZdAz &dest) const;
Index: /trunk/MagicSoft/Cosy/main/MStarguider.cc
===================================================================
--- /trunk/MagicSoft/Cosy/main/MStarguider.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/main/MStarguider.cc	(revision 2518)
@@ -176,9 +176,21 @@
     fInterpol->AddEntry("2",   IDM_kInterpol2);
     fInterpol->AddEntry("Off", IDM_kInterpol1);
-    fInterpol->CheckEntry(IDM_kInterpol1);
     fInterpol->Associate(this);
     fList->Add(fInterpol);
 
-    fIntRate = 1;
+    TString disp=gVirtualX->DisplayName();
+    if (disp.First(':')>0)
+        disp=disp(0, disp.First(':'));
+
+    if (disp.IsNull() || disp==(TString)"localhost")
+    {
+        fInterpol->CheckEntry(IDM_kInterpol1);
+        fIntRate = 1;
+    }
+    else
+    {
+        fInterpol->CheckEntry(IDM_kInterpol125);
+        fIntRate = 125;
+    }
 
     fSetup = new MGPopupMenu(p);
@@ -347,5 +359,5 @@
     gVirtualX->GrabButton(fId, kButton2, 0, 0, 0, 0, kTRUE);
 
-    fTimer=new TTimer(this, 1000/25); // 100ms
+    fTimer=new TTimer(this, 1000/25); // 40ms
     fTimer->TurnOn();
 
Index: /trunk/MagicSoft/Cosy/prepos_magic.txt
===================================================================
--- /trunk/MagicSoft/Cosy/prepos_magic.txt	(revision 2517)
+++ /trunk/MagicSoft/Cosy/prepos_magic.txt	(revision 2518)
@@ -1,5 +1,5 @@
-Camera-Access   98.05333333  -9.846666666
-Celestial-Pole  61.23817667   0
-Park            90           -9.846666666
-Roque-Lamp      90            180
-Zenith          4             0
+100.045      -8.869999999 Camera Access
+61.23817667   0           Celestial Pole
+94.125       -9.23        Park
+95.58527778 151.018055556 Roque Lamp
+4             0           Zenith
Index: /trunk/MagicSoft/Cosy/stars.txt
===================================================================
--- /trunk/MagicSoft/Cosy/stars.txt	(revision 2517)
+++ /trunk/MagicSoft/Cosy/stars.txt	(revision 2518)
@@ -1,2 +1,6 @@
+14 28 33   42 40 21  1ES1426+428
+20 00 00   65 08 55  1ES1959+650
+12 29 07   02 03 09  3C273
+12 56 11  -05 47 22  3C279
 12 54 02   55 57 35  Alioth (1.77)
 00 08 24   29 05 26  Alpheratz (2.06)
@@ -5,16 +9,26 @@
 14 15 40   19 10 57  Arcturus (-0.04)
 13 47 33   49 18 48  Benetnasch (1.86)
+22 02 43   42 16 40  BL-Lac
 00 09 11   59 08 59  Caph (2.27)
+12 59 49   27 58 50  Coma Cluster
+05 34 32   22 00 52  Crab
+20 32 26   40 57 28  Cygnus-X3
+21 45 41   31 43 09  Dark Patch 2
 20 41 26   45 16 49  Deneb (1.25)
 11 03 44   61 45 03  Dubhe (1.79)
+06 33 54   17 46 48  Geminga
 18 24 10  -34 23 05  Kaus Australis (1.85)
 05 34 32   22 00 52  M1 (8.4)
+22 22 08  -13 51 08  Mars
 13 23 56   54 55 31  Mizar A (2.23)
-16 53 52   39 45 37  Mkn 501
+11 04 26   38 12 36  Markarian-421
+16 53 52   39 45 37  Markarian-501
 02 31 49   89 15 51  Polaris (2.02)
 17 34 56   12 33 36  Ras Alhague (2.08)
 17 56 37   51 29 20  Rastaban (2.23)
+17 45 12  -28 48 18  Sagittarius-A
 18 55 16  -26 17 48  Sagittarius Sigma-34 (2.02)
 00 40 31   56 32 14  Schedar (2.23)
+15 02 22  -41 53 48  SN-1006
 13 25 13  -11 09 41  Spica (0.98)
 17 37 19  -42 59 52  Theta Scorpionis (1.87)
Index: /trunk/MagicSoft/Cosy/videodev/Camera.cc
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 2517)
+++ /trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 2518)
@@ -1,16 +1,9 @@
 #include "Camera.h"
 
-#include <iostream.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <endian.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
+#include <iostream>
+#include <errno.h>     // errono
+#include <pthread.h>
+#include <sys/ioctl.h> // ioctl
+#include <sys/mman.h>  // PROT_READ
 
 #include "MStopwatch.h"
@@ -18,8 +11,7 @@
 #include "videodev.h"
 
-#include <sys/time.h>
-#include <sys/resource.h>
-
 ClassImp(Camera);
+
+using namespace std;
 
 inline int Camera::Ioctl(int req, void *opt, const char *str)
@@ -103,10 +95,11 @@
 }
 
-Camera::Camera(PixClient &client) : fd(-1), iBufferSize(0), fClient(client)
+Camera::Camera(PixClient &client) : fd(-1), iBufferSize(0), fClient(client), fMutex(), fCond(&fMutex)
 {
     cout << "Starting thread..." << flush;
-    pthread_cond_init(&fCond, NULL);
-    pthread_mutex_init(&fMux, NULL);
-    pthread_mutex_lock(&fMux);
+    //pthread_cond_init(&fCond, NULL);
+    //pthread_mutex_init(&fMux, NULL);
+    //pthread_mutex_lock(&fMux);
+    fMutex.Lock();
     pthread_create(&fThread, NULL, MapThread, this);
     cout << "done." << endl;
@@ -173,6 +166,6 @@
     cout << "Stopping thread..." << flush;
     pthread_cancel(fThread);
-    pthread_mutex_destroy(&fMux);
-    pthread_cond_destroy(&fCond);
+    //pthread_mutex_destroy(&fMux);
+    //pthread_cond_destroy(&fCond);
     cout << "done." << endl;
 
@@ -226,5 +219,7 @@
     while (1)
     {
-        pthread_cond_wait(&fCond, &fMux);
+        //pthread_cond_wait(&fCond, &fMux);
+        fCond.Wait();
+
         MStopwatch t;
         t.Start();
@@ -286,14 +281,17 @@
     // set new number of frames to process
     //
-    pthread_mutex_lock(&fMux);
+    fMutex.Lock();
+    //pthread_mutex_lock(&fMux);
     fNum     = nof;
     fStop    = 0;
     fRunning = 1;
-    pthread_mutex_unlock(&fMux);
+    fMutex.UnLock();
+    //pthread_mutex_unlock(&fMux);
 
     //
     // Start execution
     //
-    pthread_cond_signal(&fCond);
+    fCond.Broadcast();
+    //pthread_cond_signal(&fCond);
 }
 
Index: /trunk/MagicSoft/Cosy/videodev/Camera.h
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 2517)
+++ /trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 2518)
@@ -2,12 +2,15 @@
 #define CAMERA_H
 
+#ifndef ROOT_TMutex
+#include <TMutex.h>
+#endif
+#ifndef ROOT_TCondition
+#include <TCondition.h>
+#endif
+
 #ifdef __CINT__
 typedef unsigned long int pthread_t;
-struct pthread_mutex_t;
-struct pthread_cond_t;
 struct timeval;
 #else
-#include <TROOT.h>
-#include <pthread.h>
 #include <unistd.h>
 #include <sys/time.h>
@@ -47,9 +50,11 @@
     struct timeval fTime;
 
-    pthread_t       fThread;
-    pthread_mutex_t fMux;
-    pthread_cond_t  fCond;
+    PixClient &fClient;
 
-    PixClient &fClient;
+    pthread_t  fThread;
+    TMutex     fMutex;
+    TCondition fCond;
+    //pthread_mutex_t fMux;
+    //pthread_cond_t  fCond;
 
     //
