[dasher] Reorganise input coordinates.



commit 99bfeca23208e83db3bf23b8ce815e93a54dc663
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Sat Nov 20 18:24:35 2010 +0000

    Reorganise input coordinates.
    
    Remove CDasherInput from CDasherView; pass to DecorateView, Timer, Key{Up,Down}
    CDasherInput::Get{Screen,Dasher}Coords return bool=coord availability
    (both abstract; C{Dasher,Screen}CoordInput each provide one conversion method)
    Coords are always 2d; for 1d, set dasherx=0.
    
    CDefaultFilter pauses if coords unavailable.
    Also make CDefaultFilter::m_iLast{X,Y} protected; CStylusFilter sets them to
    zoom target upon click => better mouse line.
    
    Updated Win32, MacOSX, Gtk2, iPhone. TODO: socket input needs testing!

 Src/DasherCore/AlternatingDirectMode.cpp  |    2 +-
 Src/DasherCore/AlternatingDirectMode.h    |    2 +-
 Src/DasherCore/ButtonMode.cpp             |   14 ++--
 Src/DasherCore/ButtonMode.h               |    6 +-
 Src/DasherCore/ButtonMultiPress.cpp       |    4 +-
 Src/DasherCore/ButtonMultiPress.h         |    2 +-
 Src/DasherCore/CircleStartHandler.cpp     |   11 +--
 Src/DasherCore/CircleStartHandler.h       |    2 +-
 Src/DasherCore/ClickFilter.cpp            |   12 ++--
 Src/DasherCore/ClickFilter.h              |    6 +-
 Src/DasherCore/CompassMode.cpp            |    2 +-
 Src/DasherCore/CompassMode.h              |    2 +-
 Src/DasherCore/DasherButtons.cpp          |    8 +-
 Src/DasherCore/DasherButtons.h            |    6 +-
 Src/DasherCore/DasherInput.h              |   62 ++++++++++++++++----
 Src/DasherCore/DasherInterfaceBase.cpp    |   16 ++----
 Src/DasherCore/DasherView.cpp             |   94 +----------------------------
 Src/DasherCore/DasherView.h               |   21 -------
 Src/DasherCore/DefaultFilter.cpp          |   19 ++++---
 Src/DasherCore/DefaultFilter.h            |   10 ++--
 Src/DasherCore/DynamicFilter.cpp          |    8 +-
 Src/DasherCore/DynamicFilter.h            |    7 +-
 Src/DasherCore/InputFilter.h              |   17 +++---
 Src/DasherCore/OneButtonDynamicFilter.cpp |   14 ++--
 Src/DasherCore/OneButtonDynamicFilter.h   |    8 +-
 Src/DasherCore/OneButtonFilter.cpp        |    6 +-
 Src/DasherCore/OneButtonFilter.h          |    6 +-
 Src/DasherCore/OneDimensionalFilter.cpp   |    4 +-
 Src/DasherCore/OneDimensionalFilter.h     |    2 +-
 Src/DasherCore/SocketInputBase.cpp        |    2 +-
 Src/DasherCore/SocketInputBase.h          |   42 ++++++-------
 Src/DasherCore/StartHandler.h             |    2 +-
 Src/DasherCore/StylusFilter.cpp           |   14 ++--
 Src/DasherCore/StylusFilter.h             |    6 +-
 Src/DasherCore/TwoBoxStartHandler.cpp     |   12 +---
 Src/DasherCore/TwoBoxStartHandler.h       |    2 +-
 Src/DasherCore/TwoButtonDynamicFilter.cpp |   14 ++--
 Src/DasherCore/TwoButtonDynamicFilter.h   |    6 +-
 Src/DasherCore/TwoPushDynamicFilter.cpp   |   14 ++--
 Src/DasherCore/TwoPushDynamicFilter.h     |    6 +-
 Src/Gtk2/mouse_input.h                    |   35 ++++-------
 Src/MacOSX/COSXMouseInput.h               |   52 ++++------------
 Src/Win32/BTSocketInput.cpp               |   10 ++--
 Src/Win32/BTSocketInput.h                 |   12 +---
 Src/Win32/DasherMouseInput.cpp            |   10 ++--
 Src/Win32/DasherMouseInput.h              |   10 +---
 Src/iPhone/Classes/EAGLView.mm            |    2 +
 Src/iPhone/Classes/IPhoneFilters.cpp      |   10 ++--
 Src/iPhone/Classes/IPhoneFilters.h        |    6 +-
 Src/iPhone/Classes/IPhoneInputs.h         |   26 +++------
 Src/iPhone/Classes/IPhoneInputs.mm        |   13 ++---
 51 files changed, 267 insertions(+), 412 deletions(-)
---
diff --git a/Src/DasherCore/AlternatingDirectMode.cpp b/Src/DasherCore/AlternatingDirectMode.cpp
index f251bbf..0aa0117 100644
--- a/Src/DasherCore/AlternatingDirectMode.cpp
+++ b/Src/DasherCore/AlternatingDirectMode.cpp
@@ -71,7 +71,7 @@ void CAlternatingDirectMode::SetupBoxes()
   m_iLastBox = -1;
 }
 
-bool CAlternatingDirectMode::DecorateView(CDasherView *pView) {
+bool CAlternatingDirectMode::DecorateView(CDasherView *pView, CDasherInput *pInput) {
 
   if(m_iLastBox == 1) {
     NewDrawGoTo(pView, m_pBoxes[2].iDisplayTop, m_pBoxes[2].iDisplayBottom, false);
diff --git a/Src/DasherCore/AlternatingDirectMode.h b/Src/DasherCore/AlternatingDirectMode.h
index d154260..3ab6e4f 100644
--- a/Src/DasherCore/AlternatingDirectMode.h
+++ b/Src/DasherCore/AlternatingDirectMode.h
@@ -27,7 +27,7 @@ namespace Dasher {
  public:
   CAlternatingDirectMode(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, CDasherInterfaceBase *pInterface);
   
-  bool DecorateView(CDasherView *pView);
+  bool DecorateView(CDasherView *pView, CDasherInput *pInput);
 
   bool GetSettings(SModuleSettings **pSettings, int *iCount);
 
diff --git a/Src/DasherCore/ButtonMode.cpp b/Src/DasherCore/ButtonMode.cpp
index 176f746..2d12c59 100644
--- a/Src/DasherCore/ButtonMode.cpp
+++ b/Src/DasherCore/ButtonMode.cpp
@@ -166,7 +166,7 @@ void CButtonMode::SetupBoxes()
   m_pBoxes[m_iNumBoxes-1].iBottom = int(iDasherY * 1.5);
 }
 
-bool CButtonMode::DecorateView(CDasherView *pView) {
+bool CButtonMode::DecorateView(CDasherView *pView, CDasherInput *pInput) {
   for(int i(0); i < m_iNumBoxes; ++i) {
     if(i != iActiveBox)
       NewDrawGoTo(pView, m_pBoxes[i].iDisplayTop, m_pBoxes[i].iDisplayBottom, false);
@@ -178,35 +178,35 @@ bool CButtonMode::DecorateView(CDasherView *pView) {
   return bRV;
 }
 
-bool CButtonMode::Timer(int Time, CDasherView *pView, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
+bool CButtonMode::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
   bool m_bOldHighlight(m_bHighlight);
   m_bHighlight = (Time - m_iLastTime < 200);
   
   if(m_bOldHighlight != m_bHighlight)
     m_bDecorationChanged = true;  
 
-  return CDasherButtons::Timer(Time, pView, pModel, pAdded, pNumDeleted, pol);
+  return CDasherButtons::Timer(Time, pView, pInput, pModel, pAdded, pNumDeleted, pol);
 }
 
-void CButtonMode::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY)
+void CButtonMode::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY)
 {
   if (iId == 100 && !m_bMenu) {
     //Mouse!
     myint iDasherX, iDasherY;
-    pView->GetCoordinates(iDasherX, iDasherY);
+    pInput->GetDasherCoords(iDasherX, iDasherY, pView);
     for (int i = 0; i < m_iNumBoxes; i++)
     {
       if (iDasherY < m_pBoxes[i].iDisplayBottom &&
           iDasherY > m_pBoxes[i].iDisplayTop &&
           iDasherX < (m_pBoxes[i].iDisplayBottom - m_pBoxes[i].iDisplayTop)) {
         //user has clicked in box! Simulate press of appropriate (direct-mode) button...
-        CDasherButtons::KeyDown(iTime, (i==m_iNumBoxes-1) ? 1 : i+2, pView, pModel, pUserLog);
+        CDasherButtons::KeyDown(iTime, (i==m_iNumBoxes-1) ? 1 : i+2, pView, pInput, pModel, pUserLog);
         return;
       }
     }
     //not in any box. Fall through, just to be conservative...
   }
-  CInputFilter::KeyDown(iTime, iId, pView, pModel, pUserLog, bPos, iX, iY);
+  CInputFilter::KeyDown(iTime, iId, pView, pInput, pModel, pUserLog, bPos, iX, iY);
 }
 
 void CButtonMode::DirectKeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
diff --git a/Src/DasherCore/ButtonMode.h b/Src/DasherCore/ButtonMode.h
index 09bc820..db8cbcb 100644
--- a/Src/DasherCore/ButtonMode.h
+++ b/Src/DasherCore/ButtonMode.h
@@ -25,11 +25,11 @@ class CButtonMode : public CDasherButtons
   CButtonMode(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, CDasherInterfaceBase *pInterface, bool bMenu, int iID, const char *szName);
 
   virtual void HandleEvent(Dasher::CEvent * pEvent);
-  bool Timer(int Time, CDasherView *pView, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
-  bool DecorateView(CDasherView *pView);
+  bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  bool DecorateView(CDasherView *pView, CDasherInput *pInput);
 
   //override to get mouse clicks/taps back again
-  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
+  virtual void KeyDown(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
   
   bool GetSettings(SModuleSettings **pSettings, int *iCount);
  protected: 
diff --git a/Src/DasherCore/ButtonMultiPress.cpp b/Src/DasherCore/ButtonMultiPress.cpp
index 95e7da2..90fe40e 100644
--- a/Src/DasherCore/ButtonMultiPress.cpp
+++ b/Src/DasherCore/ButtonMultiPress.cpp
@@ -27,7 +27,7 @@ CButtonMultiPress::CButtonMultiPress(Dasher::CEventHandler * pEventHandler, CSet
   : CDynamicFilter(pEventHandler, pSettingsStore, pInterface, iID, szName) {
 }
 
-void CButtonMultiPress::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void CButtonMultiPress::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
 
   if (m_bKeyDown) return;
       
@@ -57,7 +57,7 @@ void CButtonMultiPress::KeyDown(int iTime, int iId, CDasherView *pView, CDasherM
   // Record press...
   m_deQueueTimes.push_back(iTime);
   // ... and process normally; if it changes the state, pause()/reverse()'ll clear the queue
-  CDynamicFilter::KeyDown(iTime, iId, pView, pModel, pUserLog);
+  CDynamicFilter::KeyDown(iTime, iId, pView, pInput, pModel, pUserLog);
 }
 
 void CButtonMultiPress::pause()
diff --git a/Src/DasherCore/ButtonMultiPress.h b/Src/DasherCore/ButtonMultiPress.h
index 89acd14..3da6077 100644
--- a/Src/DasherCore/ButtonMultiPress.h
+++ b/Src/DasherCore/ButtonMultiPress.h
@@ -33,7 +33,7 @@ class CButtonMultiPress : public CDynamicFilter {
  public:
   CButtonMultiPress(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, const char *szName);
   
-  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
+  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
 
  protected:
   virtual unsigned int maxClickCount()=0;
diff --git a/Src/DasherCore/CircleStartHandler.cpp b/Src/DasherCore/CircleStartHandler.cpp
index a8495ad..3155d13 100644
--- a/Src/DasherCore/CircleStartHandler.cpp
+++ b/Src/DasherCore/CircleStartHandler.cpp
@@ -22,6 +22,7 @@
 
 #include "CircleStartHandler.h"
 #include "Event.h"
+#include "DasherInput.h"
 
 using namespace Dasher;
 
@@ -65,18 +66,14 @@ bool CCircleStartHandler::DecorateView(CDasherView *pView) {
   return true;
 }
 
-void CCircleStartHandler::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel) {
-  myint iDasherX;
-  myint iDasherY;
-  m_pDasherView->GetCoordinates(iDasherX, iDasherY);
-
+void CCircleStartHandler::Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel) {
   screenint iCX;
   screenint iCY;
-  m_pDasherView->Dasher2Screen(2048, 2048, iCX, iCY);
+  pView->Dasher2Screen(2048, 2048, iCX, iCY);
   
   screenint iCursorX;
   screenint iCursorY;
-  m_pDasherView->Dasher2Screen(iDasherX, iDasherY, iCursorX, iCursorY);
+  pInput->GetScreenCoords(iCursorX, iCursorY, pView);
 
   double dR;
 
diff --git a/Src/DasherCore/CircleStartHandler.h b/Src/DasherCore/CircleStartHandler.h
index 21c2f55..be7e93d 100644
--- a/Src/DasherCore/CircleStartHandler.h
+++ b/Src/DasherCore/CircleStartHandler.h
@@ -10,7 +10,7 @@ public:
   CCircleStartHandler(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, CDasherInterfaceBase *pInterface);
 
   virtual bool DecorateView(CDasherView *pView);
-  virtual void Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel);
+  virtual void Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel);
   virtual void HandleEvent(Dasher::CEvent * pEvent);
 
 private:
diff --git a/Src/DasherCore/ClickFilter.cpp b/Src/DasherCore/ClickFilter.cpp
index 77d6a08..69aef54 100644
--- a/Src/DasherCore/ClickFilter.cpp
+++ b/Src/DasherCore/ClickFilter.cpp
@@ -19,11 +19,11 @@ static SModuleSettings sSettings[] = {
   {BP_CURVE_MOUSE_LINE, T_BOOL, -1, -1, -1, -1, _("Curve lines to follow the non-linearity of the view transform")},
 };
 
-bool CClickFilter::DecorateView(CDasherView *pView) {
+bool CClickFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
   bool bChanged(false);
   if (GetBoolParameter(BP_DRAW_MOUSE_LINE)) {
     myint mouseX, mouseY;
-    pView->GetCoordinates(mouseX, mouseY);
+    pInput->GetDasherCoords(mouseX, mouseY, pView);
     //unfortunately we have to copy the limit set by DasherModel::ScheduleZoom here
     // ....call for a refactor? but of some/what sort?
     if (mouseX<2) mouseX=2;
@@ -60,18 +60,18 @@ bool CClickFilter::DecorateView(CDasherView *pView) {
   return bChanged;
 }
 
-bool CClickFilter::Timer(int Time, CDasherView *pDasherView, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
+bool CClickFilter::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
   return pModel->NextScheduledStep(Time, pAdded, pNumDeleted);
 }
 
-void CClickFilter::KeyDown(int iTime, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
+void CClickFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
   switch(iId) {
   case 100: // Mouse clicks
-    if(pDasherView) {
+    {
       myint iDasherX;
       myint iDasherY;
 
-      pDasherView->GetCoordinates(iDasherX, iDasherY);
+      pInput->GetDasherCoords(iDasherX, iDasherY, pView);
 
       pModel->ScheduleZoom(iTime, iDasherX,iDasherY, GetLongParameter(LP_MAXZOOM));
     }
diff --git a/Src/DasherCore/ClickFilter.h b/Src/DasherCore/ClickFilter.h
index 4900b6e..e191e11 100644
--- a/Src/DasherCore/ClickFilter.h
+++ b/Src/DasherCore/ClickFilter.h
@@ -11,9 +11,9 @@ class CClickFilter : public CInputFilter {
   CClickFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface)
     : CInputFilter(pEventHandler, pSettingsStore, pInterface, 7, _("Click Mode")) { };
 
-  virtual bool DecorateView(CDasherView *pView);
-  virtual bool Timer(int Time, CDasherView *pDasherView, CDasherModel *pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
-  virtual void KeyDown(int iTime, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput);
+  virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
   virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
  private:
   //for mouse lines
diff --git a/Src/DasherCore/CompassMode.cpp b/Src/DasherCore/CompassMode.cpp
index 8e70f7c..1880ddf 100644
--- a/Src/DasherCore/CompassMode.cpp
+++ b/Src/DasherCore/CompassMode.cpp
@@ -72,7 +72,7 @@ void CCompassMode::SetupBoxes()
   m_pBoxes[3].iDisplayBottom = m_pBoxes[3].iBottom;
 }
 
-bool CCompassMode::DecorateView(CDasherView *pView) {
+bool CCompassMode::DecorateView(CDasherView *pView, CDasherInput *pInput) {
   CDasherScreen *pScreen(pView->Screen());
 
   int iPos(2048 - iTargetWidth / 2);
diff --git a/Src/DasherCore/CompassMode.h b/Src/DasherCore/CompassMode.h
index d4732f5..9fc984e 100644
--- a/Src/DasherCore/CompassMode.h
+++ b/Src/DasherCore/CompassMode.h
@@ -26,7 +26,7 @@ class CCompassMode : public CDasherButtons
 
   virtual void HandleEvent(Dasher::CEvent * pEvent);
   
-  bool DecorateView(CDasherView *pView);
+  bool DecorateView(CDasherView *pView, CDasherInput *pInput);
 
   bool GetSettings(SModuleSettings **pSettings, int *iCount);
 
diff --git a/Src/DasherCore/DasherButtons.cpp b/Src/DasherCore/DasherButtons.cpp
index bdb2358..6a9aaa3 100644
--- a/Src/DasherCore/DasherButtons.cpp
+++ b/Src/DasherCore/DasherButtons.cpp
@@ -41,7 +41,7 @@ void CDasherButtons::Activate() {
   m_iScanTime = std::numeric_limits<int>::min();
 }
 
-void CDasherButtons::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void CDasherButtons::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
 
   if(m_bMenu) {
     switch(iId) {
@@ -81,7 +81,7 @@ void CDasherButtons::DirectKeyDown(int iTime, int iId, CDasherView *pView, CDash
   pModel->ScheduleZoom(iTime, (m_pBoxes[iActiveBox].iBottom - m_pBoxes[iActiveBox].iTop)/2, (m_pBoxes[iActiveBox].iBottom + m_pBoxes[iActiveBox].iTop)/2);
 }
 
-bool CDasherButtons::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
+bool CDasherButtons::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
   if (m_bMenu && GetLongParameter(LP_BUTTON_SCAN_TIME) &&
       Time > m_iScanTime) {
     m_iScanTime = Time + GetLongParameter(LP_BUTTON_SCAN_TIME);
@@ -94,10 +94,10 @@ bool CDasherButtons::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m
   myint iDasherX;
   myint iDasherY;
 
-  m_pDasherView->GetCoordinates(iDasherX, iDasherY);
+  pInput->GetDasherCoords(iDasherX, iDasherY, pView);
   // ----
 
-  return m_pDasherModel->NextScheduledStep(Time, pAdded, pNumDeleted);
+  return pModel->NextScheduledStep(Time, pAdded, pNumDeleted);
 }
 
 void CDasherButtons::NewDrawGoTo(CDasherView *pView, myint iDasherMin, myint iDasherMax, bool bActive) {
diff --git a/Src/DasherCore/DasherButtons.h b/Src/DasherCore/DasherButtons.h
index fb321b2..d2d9e7a 100644
--- a/Src/DasherCore/DasherButtons.h
+++ b/Src/DasherCore/DasherButtons.h
@@ -26,10 +26,10 @@ class CDasherButtons : public CInputFilter
 
   ~CDasherButtons();
 
-  virtual bool DecorateView(CDasherView *pView)=0;
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput)=0;
   
-  void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
-  bool Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
+  bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
   void Activate();
   
   struct SBoxInfo {
diff --git a/Src/DasherCore/DasherInput.h b/Src/DasherCore/DasherInput.h
index b8332d0..0d1dec6 100644
--- a/Src/DasherCore/DasherInput.h
+++ b/Src/DasherCore/DasherInput.h
@@ -8,9 +8,12 @@
 #include "DasherTypes.h"
 #include "DasherModule.h"
 #include "ModuleManager.h"
+#include "DasherView.h"
 
 namespace Dasher {
   class CDasherInput;
+  class CDasherCoordInput;
+  class CScreenCoordInput;
   class CDasherInterfaceBase;
 }
 /// \defgroup Input Input devices
@@ -22,18 +25,21 @@ public:
   CDasherInput(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, ModuleID_t iID, const char *szName) 
     : CDasherModule(pEventHandler, pSettingsStore, iID, InputDevice, szName) {};
 
-  /// Set the maximum values for each of the coordinates. Minimum
-  /// values are assumed to be zero for now
-  virtual void SetMaxCoordinates(int iN, myint * iDasherMax) {};
+  /// Get the position of the input in Dasher coordinates.
+  /// \param iDasherX X-coordinate; if only one coordinate (axis) is available, this should be 0.
+  /// \param iDasherY Y-coordinate; if only one coordinate (axis) is available, this should be it.
+  /// \param pView view to use to convert Screen2Dasher, if necessary
+  /// \return true if coordinates were obtained; false if they could not be.
+  virtual bool GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView)=0;
 
-  /// Fill pCoordinates with iN coordinate values, return 0 if the
-  /// values were in screen coordinates or 1 if the values were in
-  /// Dasher coordinates.
-  virtual int GetCoordinates(int iN, myint * pCoordinates) = 0;
-
-  /// Get the number of co-ordinates that this device supplies
-  ///
-  virtual int GetCoordinateCount() = 0;
+  /// Get the position of the input in screen coordinates. If only one coordinate (axis) is available,
+  /// it should be returned in Y for left-to-right / right-to-left orientations, X for top-to-bottom/
+  /// bottom-to-top. (As would happen if performing Dasher2Screen on values obtained from GetDasherCoords!)
+  /// \param iX Screen X-coordinate
+  /// \param iY Screen Y-coordinate
+  /// \param pView view to use to convert Dasher2Screen, if necessary
+  /// \return true if coordinates were obtained; false if they could not be.
+  virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView)=0;
   
   /// Activate the device. If a helper thread needs to be started in
   /// order to listen for input then do it here.
@@ -51,5 +57,39 @@ public:
   /// Handle key up events
   virtual void KeyUp(int iTime, int iId) {};
 };
+///Abstract superclasses for CDasherInputs which natively provide screen coordinates;
+/// thus, when dasher-coordinates are requested, they will be converted
+/// via the views Screen2Dasher. (=>Subclasses must implement GetScreenCoords)
+class Dasher::CScreenCoordInput : public CDasherInput {
+public:
+  CScreenCoordInput(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, ModuleID_t iId, const char *szName)
+  : CDasherInput(pEventHandler, pSettingsStore, iId, szName) {
+  }
+  virtual bool GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView)  {
+    screenint iX, iY;
+    if (!GetScreenCoords(iX, iY, pView)) return false;
+    pView->Screen2Dasher(iX, iY, iDasherX, iDasherY);
+    return true;
+  }
+};
+
+///Abstract superclasses for CDasherInputs which natively provide dasher coordinates;
+/// thus, when screen-coordinates are requested, they will be converted
+/// via the views Dasher2Screen. (=>Subclasses must implement GetDasherCoords)
+class Dasher::CDasherCoordInput : public CDasherInput {
+public:
+  CDasherCoordInput(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, ModuleID_t iId, const char *szName)
+  : CDasherInput(pEventHandler, pSettingsStore, iId, szName) {
+  }
+  
+  virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
+    myint iDasherX, iDasherY;
+    if (!GetDasherCoords(iDasherX, iDasherY, pView)) return false;
+    pView->Dasher2Screen(iDasherX, iDasherY, iX, iY);
+    return true;
+  }
+  
+};
+
 /// \}
 #endif
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index 99c0907..e8da093 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -468,9 +468,6 @@ void CDasherInterfaceBase::CreateInput() {
   if(m_pInput) {
     m_pInput->Activate();
   }
-
-  if(m_pDasherView != 0)
-    m_pDasherView->SetInput(m_pInput);
 }
 
 void CDasherInterfaceBase::NewFrame(unsigned long iTime, bool bForceRedraw) {
@@ -501,7 +498,7 @@ void CDasherInterfaceBase::NewFrame(unsigned long iTime, bool bForceRedraw) {
 	int iNumDeleted = 0;
 
 	if(m_pInputFilter) {
-	  bChanged = m_pInputFilter->Timer(iTime, m_pDasherView, m_pDasherModel, &vAdded, &iNumDeleted, &pol);
+	  bChanged = m_pInputFilter->Timer(iTime, m_pDasherView, m_pInput, m_pDasherModel, &vAdded, &iNumDeleted, &pol);
 	}
 
 #ifndef _WIN32_WCE
@@ -514,7 +511,7 @@ void CDasherInterfaceBase::NewFrame(unsigned long iTime, bool bForceRedraw) {
       }
       else {
 	if(m_pInputFilter) {
-	  bChanged = m_pInputFilter->Timer(iTime, m_pDasherView, m_pDasherModel, 0, 0, &pol);
+	  bChanged = m_pInputFilter->Timer(iTime, m_pDasherView, m_pInput, m_pDasherModel, 0, 0, &pol);
 	}
       }
     }
@@ -571,7 +568,7 @@ void CDasherInterfaceBase::Redraw(bool bRedrawNodes, CExpansionPolicy &policy) {
   bool bDecorationsChanged(false);
 
   if(m_pInputFilter) {
-    bDecorationsChanged = m_pInputFilter->DecorateView(m_pDasherView);
+    bDecorationsChanged = m_pInputFilter->DecorateView(m_pDasherView, m_pInput);
   }
 
   bool bActionButtonsChanged(false);
@@ -646,9 +643,6 @@ void CDasherInterfaceBase::ChangeView() {
 
     m_pDasherView = new CDasherViewSquare(m_pEventHandler, m_pSettingsStore, m_DasherScreen);
 
-    if (m_pInput)
-      m_pDasherView->SetInput(m_pInput);
-
     // Tell the Teacher which view we are using
     if(GameMode::CDasherGameMode* pTeacher = GameMode::CDasherGameMode::GetTeacher())
 	pTeacher->SetDasherView(m_pDasherView);
@@ -754,7 +748,7 @@ void CDasherInterfaceBase::KeyDown(int iTime, int iId, bool bPos, int iX, int iY
     return;
 
   if(m_pInputFilter && !GetBoolParameter(BP_TRAINING)) {
-    m_pInputFilter->KeyDown(iTime, iId, m_pDasherView, m_pDasherModel, m_pUserLog, bPos, iX, iY);
+    m_pInputFilter->KeyDown(iTime, iId, m_pDasherView, m_pInput, m_pDasherModel, m_pUserLog, bPos, iX, iY);
   }
 
   if(m_pInput && !GetBoolParameter(BP_TRAINING)) {
@@ -767,7 +761,7 @@ void CDasherInterfaceBase::KeyUp(int iTime, int iId, bool bPos, int iX, int iY)
     return;
 
   if(m_pInputFilter && !GetBoolParameter(BP_TRAINING)) {
-    m_pInputFilter->KeyUp(iTime, iId, m_pDasherView, m_pDasherModel, bPos, iX, iY);
+    m_pInputFilter->KeyUp(iTime, iId, m_pDasherView, m_pInput, m_pDasherModel, bPos, iX, iY);
   }
 
   if(m_pInput && !GetBoolParameter(BP_TRAINING)) {
diff --git a/Src/DasherCore/DasherView.cpp b/Src/DasherCore/DasherView.cpp
index cc5e271..377fbed 100644
--- a/Src/DasherCore/DasherView.cpp
+++ b/Src/DasherCore/DasherView.cpp
@@ -43,7 +43,7 @@ static char THIS_FILE[] = __FILE__;
 /////////////////////////////////////////////////////////////////////////////
 
 CDasherView::CDasherView(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherScreen *DasherScreen)
-  :CDasherComponent(pEventHandler, pSettingsStore), m_pScreen(DasherScreen), m_pInput(0),
+  :CDasherComponent(pEventHandler, pSettingsStore), m_pScreen(DasherScreen),
    m_bDemoMode(false), m_bGameMode(false) {
 }
 
@@ -55,43 +55,6 @@ void CDasherView::ChangeScreen(CDasherScreen *NewScreen) {
 
 /////////////////////////////////////////////////////////////////////////////
 
-int CDasherView::GetCoordinateCount() {
-  // TODO: Do we really need support for co-ordinate counts other than 2?
-  if(m_pInput)
-    return m_pInput->GetCoordinateCount();
-  else
-    return 0;
-}
-
-int CDasherView::GetInputCoordinates(int iN, myint * pCoordinates) {
-  if(m_pInput)
-    return m_pInput->GetCoordinates(iN, pCoordinates);
-  else
-    return 0;
-}
-
-void CDasherView::SetInput(CDasherInput * _pInput) {
-  // TODO: Is it sensible to make this responsible for the input
-  // device - I guess it makes sense for now
-
-  DASHER_ASSERT_VALIDPTR_RW(_pInput);
-
-  // Don't delete the old input class; whoever is calling this method
-  // might want to keep several Input class instances around and
-  // change which one is currently driving dasher without deleting any
-
-  m_pInput = _pInput;
-
-  // Tell the new object about maximum values
-
-  myint iMaxCoordinates[2];
-
-  iMaxCoordinates[0] = GetLongParameter(LP_MAX_Y);
-  iMaxCoordinates[1] = GetLongParameter(LP_MAX_Y);
-
-  m_pInput->SetMaxCoordinates(2, iMaxCoordinates);
-}
-
 void CDasherView::DasherSpaceLine(myint x1, myint y1, myint x2, myint y2, int iWidth, int iColor) {
   if (!ClipLineToVisible(x1, y1, x2, y2)) return;
   vector<CDasherScreen::point> vPoints;
@@ -221,61 +184,6 @@ void CDasherView::DrawText(const std::string & str, myint x, myint y, int Size,
 }
 
 
-int CDasherView::GetCoordinates(myint &iDasherX, myint &iDasherY) {
-
-
-  // FIXME - Actually turn autocalibration on and off!
-  // FIXME - AutoCalibrate should use Dasher co-ordinates, not raw mouse co-ordinates?
-  // FIXME - Have I broken this by moving it before the offset is applied?
-  // FIXME - put ymap stuff back in 
-  // FIXME - optimise this
-  
-  int iCoordinateCount(GetCoordinateCount());
-
-  myint *pCoordinates(new myint[iCoordinateCount]);
-
-  int iType(GetInputCoordinates(iCoordinateCount, pCoordinates));
-
-  screenint mousex;
-  screenint mousey;
-
-  if(iCoordinateCount == 1) {
-    mousex = 0;
-    mousey = pCoordinates[0];
-  }
-  else {
-    mousex = pCoordinates[0];
-    mousey = pCoordinates[1];
-  }
-
-  delete[]pCoordinates;
-
-  switch(iType) {
-  case 0:
-    Screen2Dasher(mousex, mousey, iDasherX, iDasherY);
-    break;
-  case 1:
-    iDasherX = mousex;
-    iDasherY = mousey;
-    break;
-  default:
-    // TODO: Error
-    break;
-  }
-
-  ///GAME///
-  if(m_bGameMode)
-    {
-      using GameMode::CDasherGameMode;
-      if(m_bDemoMode)
-        CDasherGameMode::GetTeacher()->DemoModeGetCoordinates(iDasherX, iDasherY);
-      CDasherGameMode::GetTeacher()->SetUserMouseCoordinates(iDasherX, iDasherY);
-    }
-      
-  return iType;
-}
-
-
 void CDasherView::SetDemoMode(bool bDemoMode)
 {
   m_bDemoMode = bDemoMode;
diff --git a/Src/DasherCore/DasherView.h b/Src/DasherCore/DasherView.h
index 291493c..760ed87 100644
--- a/Src/DasherCore/DasherView.h
+++ b/Src/DasherCore/DasherView.h
@@ -6,7 +6,6 @@
 #define __DasherView_h_
 
 namespace Dasher {
-  class CDasherInput; // Why does DasherView care about input? - pconlon
   class CDasherComponent;
   class CDasherView;
   class CDasherNode;
@@ -54,24 +53,8 @@ public:
   virtual ~CDasherView() {
   }
 
-  /// @name Pointing device mappings 
-  /// @{
-
-  /// Set the input device class. Note that this class will now assume ownership of the pointer, ie it will delete the object when it's done with it.
-  /// \param _pInput Pointer to the new CDasherInput.
-  void SetInput(CDasherInput * _pInput);
   void SetDemoMode(bool);
   void SetGameMode(bool);
-  /// Translates the screen coordinates to Dasher coordinates
-  virtual int GetCoordinates(myint &iDasherX, myint &iDasherY);
-
-  
-  /// Get the co-ordinate count from the input device
-  
-  int GetCoordinateCount();
-
-
-  /// @}
 
   /// 
   /// @name Coordinate system conversion
@@ -189,10 +172,6 @@ protected:
 
 private:
   CDasherScreen *m_pScreen;    // provides the graphics (text, lines, rectangles):
-  CDasherInput *m_pInput;       // Input device abstraction
-
-  /// Get the co-ordinates from the input device
-  int GetInputCoordinates(int iN, myint * pCoordinates); 
 
   bool m_bDemoMode;
   bool m_bGameMode;
diff --git a/Src/DasherCore/DefaultFilter.cpp b/Src/DasherCore/DefaultFilter.cpp
index c14e1e1..7c8141b 100644
--- a/Src/DasherCore/DefaultFilter.cpp
+++ b/Src/DasherCore/DefaultFilter.cpp
@@ -39,13 +39,13 @@ CDefaultFilter::~CDefaultFilter() {
   delete m_pAutoSpeedControl;
 }
 
-bool CDefaultFilter::DecorateView(CDasherView *pView) {
+bool CDefaultFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
 
   bool bDidSomething(false);
 
   if (GetBoolParameter(BP_DASHER_PAUSED)) {
     //Timer() is not retrieving input coordinates, so we'd better do so here...
-    pView->GetCoordinates(m_iLastX, m_iLastY);
+    if (!pInput->GetDasherCoords(m_iLastX, m_iLastY, pView)) return false;
     ApplyTransform(m_iLastX, m_iLastY);
   }
 
@@ -106,11 +106,14 @@ bool CDefaultFilter::DecorateView(CDasherView *pView) {
   return bDidSomething;
 }
 
-bool CDefaultFilter::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
+bool CDefaultFilter::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
   bool bDidSomething = false;
   if (!GetBoolParameter(BP_DASHER_PAUSED))
   {
-    m_pDasherView->GetCoordinates(m_iLastX, m_iLastY);
+    if (!(pInput->GetDasherCoords(m_iLastX, m_iLastY, pView))) {
+      m_pInterface->Stop();
+      return false;
+    };
     ApplyTransform(m_iLastX, m_iLastY);
 
     if(GetBoolParameter(BP_STOP_OUTSIDE)) {
@@ -118,7 +121,7 @@ bool CDefaultFilter::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m
       myint iDasherMinY;
       myint iDasherMaxX;
       myint iDasherMaxY;
-      m_pDasherView->VisibleRegion(iDasherMinX, iDasherMinY, iDasherMaxX, iDasherMaxY);
+      pView->VisibleRegion(iDasherMinX, iDasherMinY, iDasherMaxX, iDasherMaxY);
   
       if((m_iLastX > iDasherMaxX) || (m_iLastX < iDasherMinX) || (m_iLastY > iDasherMaxY) || (m_iLastY < iDasherMinY)) {
         m_pInterface->Stop();
@@ -129,16 +132,16 @@ bool CDefaultFilter::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m
     m_pDasherModel->OneStepTowards(m_iLastX,m_iLastY, Time, pAdded, pNumDeleted);
     bDidSomething = true;
 
-    m_pAutoSpeedControl->SpeedControl(m_iLastX, m_iLastY, m_pDasherView);
+    m_pAutoSpeedControl->SpeedControl(m_iLastX, m_iLastY, pView);
   }
 	
   if(m_pStartHandler)
-    m_pStartHandler->Timer(Time, m_pDasherView, m_pDasherModel);
+    m_pStartHandler->Timer(Time, pView, pInput, m_pDasherModel);
 
   return bDidSomething;
 }
 
-void CDefaultFilter::KeyDown(int iTime, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void CDefaultFilter::KeyDown(int iTime, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
 
   switch(iId) {
   case 0: // Start on space
diff --git a/Src/DasherCore/DefaultFilter.h b/Src/DasherCore/DefaultFilter.h
index 3e2888f..3e97bf2 100644
--- a/Src/DasherCore/DefaultFilter.h
+++ b/Src/DasherCore/DefaultFilter.h
@@ -16,19 +16,19 @@ class CDefaultFilter : public CInputFilter {
 
   virtual void HandleEvent(Dasher::CEvent * pEvent);
 
-  virtual bool DecorateView(CDasherView *pView);
-  virtual bool Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
-  virtual void KeyDown(int iTime, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog);
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput);
+  virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  virtual void KeyDown(int iTime, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
   bool GetSettings(SModuleSettings **, int *);
  protected:
   virtual void CreateStartHandler();
   virtual void ApplyTransform(myint &iDasherX, myint &iDasherY);
   void ApplyOffset(myint &iDasherX, myint &iDasherY);
   
- private:
+protected:
   /// Last-known Dasher-coords of the target
   myint m_iLastX, m_iLastY;
-
+private:
   CAutoSpeedControl *m_pAutoSpeedControl;
   CStartHandler *m_pStartHandler;
   myint m_iSum;
diff --git a/Src/DasherCore/DynamicFilter.cpp b/Src/DasherCore/DynamicFilter.cpp
index bea055e..0e44f98 100644
--- a/Src/DasherCore/DynamicFilter.cpp
+++ b/Src/DasherCore/DynamicFilter.cpp
@@ -30,7 +30,7 @@ CDynamicFilter::CDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsS
   pause();
 }
 
-bool CDynamicFilter::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)
+bool CDynamicFilter::Timer(int iTime, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)
 {
   if(m_bKeyDown && !m_bKeyHandled && ((iTime - m_iKeyDownTime) > GetLongParameter(LP_HOLD_TIME))) {
     Event(iTime, m_iHeldId, 1, m_pDasherModel, m_pUserLog);
@@ -50,10 +50,10 @@ bool CDynamicFilter::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *
         SetLongParameter(LP_MAX_BITRATE, GetLongParameter(LP_MAX_BITRATE) * (1.0 + GetLongParameter(LP_DYNAMIC_SPEED_INC)/100.0));
 	  m_uSpeedControlTime = uTime + 1000*GetLongParameter(LP_DYNAMIC_SPEED_FREQ);
   }
-  return TimerImpl(iTime, m_pDasherView, m_pDasherModel, pAdded, pNumDeleted, pol);
+  return TimerImpl(iTime, pDasherView, m_pDasherModel, pAdded, pNumDeleted, pol);
 }
 
-void CDynamicFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void CDynamicFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
   
   m_pUserLog = pUserLog;
   
@@ -76,7 +76,7 @@ void CDynamicFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherMode
   m_bKeyHandled = false;
 }
 
-void CDynamicFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherModel *pModel) {
+void CDynamicFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel) {
   if (iId == m_iHeldId) m_bKeyDown = false;
 }
 
diff --git a/Src/DasherCore/DynamicFilter.h b/Src/DasherCore/DynamicFilter.h
index 8b0f1b9..509226c 100644
--- a/Src/DasherCore/DynamicFilter.h
+++ b/Src/DasherCore/DynamicFilter.h
@@ -34,11 +34,10 @@ class CDynamicFilter : public CInputFilter {
   virtual bool supportsPause() {return true;}
   
   ///when reversing, backs off; when paused, does nothing; when running, delegates to TimerImpl
-  virtual bool Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol); 
-
-  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
-  virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherModel *pModel);
+  virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol); 
 
+  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
+  virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel);
 
  protected:
   virtual void ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog) = 0;
diff --git a/Src/DasherCore/InputFilter.h b/Src/DasherCore/InputFilter.h
index 87832a8..552a613 100644
--- a/Src/DasherCore/InputFilter.h
+++ b/Src/DasherCore/InputFilter.h
@@ -5,6 +5,7 @@
 #include "DasherModel.h"
 #include "ModuleManager.h"
 #include "UserLogBase.h"
+#include "DasherInput.h"
 
 namespace Dasher {
   class CDasherInterfaceBase;
@@ -19,16 +20,16 @@ class CInputFilter : public CDasherModule {
     m_pInterface = pInterface;
   };
 
-  virtual bool DecorateView(CDasherView *pView) { return false; };
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput) { return false; };
 
-  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
-    KeyDown(Time, iId, pDasherView, pModel, pUserLog);
+  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
+    KeyDown(Time, iId, pDasherView, pInput, pModel, pUserLog);
   };
-  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY) {
-    KeyUp(Time, iId, pDasherView, pModel);
+  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY) {
+    KeyUp(Time, iId, pDasherView, pInput, pModel);
   };
 
-  virtual bool Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)=0;// { return false; };
+  virtual bool Timer(int Time, CDasherView *m_pDasherView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)=0;// { return false; };
 
   virtual void Activate() {};
   virtual void Deactivate() {};
@@ -43,8 +44,8 @@ class CInputFilter : public CDasherModule {
   CDasherInterfaceBase *m_pInterface;
 
  private:
-  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog) {};
-  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel) {};
+  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {};
+  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel) {};
 };
 }
 /// @}
diff --git a/Src/DasherCore/OneButtonDynamicFilter.cpp b/Src/DasherCore/OneButtonDynamicFilter.cpp
index 1ff85ca..3bdb1a4 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.cpp
+++ b/Src/DasherCore/OneButtonDynamicFilter.cpp
@@ -61,7 +61,7 @@ COneButtonDynamicFilter::~COneButtonDynamicFilter() {
   delete[] m_iTargetY;  
 }
 
-bool COneButtonDynamicFilter::DecorateView(CDasherView *pView) {
+bool COneButtonDynamicFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
 
   CDasherScreen *pScreen(pView->Screen());
 
@@ -97,22 +97,22 @@ bool COneButtonDynamicFilter::DecorateView(CDasherView *pView) {
   return bRV;
 }
 
-void COneButtonDynamicFilter::KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
+void COneButtonDynamicFilter::KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
   if (iId == 100 && !GetBoolParameter(BP_BACKOFF_BUTTON))
     //mouse click - will be ignored by superclass method.
     //simulate press of button 2...
-    CButtonMultiPress::KeyDown(Time, 2, pDasherView, pModel, pUserLog);
+    CButtonMultiPress::KeyDown(Time, 2, pDasherView, pInput, pModel, pUserLog);
   else
-    CInputFilter::KeyDown(Time, iId, pDasherView, pModel, pUserLog, bPos, iX, iY);
+    CInputFilter::KeyDown(Time, iId, pDasherView, pInput, pModel, pUserLog, bPos, iX, iY);
 }
 
-void COneButtonDynamicFilter::KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY) {
+void COneButtonDynamicFilter::KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY) {
   if (iId == 100 && !GetBoolParameter(BP_BACKOFF_BUTTON))
     //mouse click - will be ignored by superclass method.
     //simulate press of button 2...
-    CButtonMultiPress::KeyUp(Time, 2, pDasherView, pModel);
+    CButtonMultiPress::KeyUp(Time, 2, pDasherView, pInput, pModel);
   else
-    CInputFilter::KeyUp(Time, iId, pDasherView, pModel, bPos, iX, iY);
+    CInputFilter::KeyUp(Time, iId, pDasherView, pInput, pModel, bPos, iX, iY);
 }
 
 bool COneButtonDynamicFilter::TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
diff --git a/Src/DasherCore/OneButtonDynamicFilter.h b/Src/DasherCore/OneButtonDynamicFilter.h
index 8d084d6..0f1a81c 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.h
+++ b/Src/DasherCore/OneButtonDynamicFilter.h
@@ -31,17 +31,17 @@ class COneButtonDynamicFilter : public CButtonMultiPress {
   COneButtonDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface);
   ~COneButtonDynamicFilter();
 
-  virtual bool DecorateView(CDasherView *pView);
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput);
 
   virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
 
   //override to get mouse clicks / taps back again...
-  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
-  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY);
+  virtual void KeyDown(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
+  virtual void KeyUp(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY);
 
  private:
   unsigned int maxClickCount() {return 2;} //double-click to reverse
-  virtual bool TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  virtual bool TimerImpl(int Time, CDasherView *pView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
   virtual void ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
   
   int m_iTarget;
diff --git a/Src/DasherCore/OneButtonFilter.cpp b/Src/DasherCore/OneButtonFilter.cpp
index 67c4cda..cf72295 100644
--- a/Src/DasherCore/OneButtonFilter.cpp
+++ b/Src/DasherCore/OneButtonFilter.cpp
@@ -24,7 +24,7 @@ COneButtonFilter::COneButtonFilter(Dasher::CEventHandler * pEventHandler, CSetti
 COneButtonFilter::~COneButtonFilter() {
 }
 
-bool COneButtonFilter::DecorateView(CDasherView *pView) {
+bool COneButtonFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
 
   CDasherScreen *pScreen(pView->Screen());
 
@@ -52,7 +52,7 @@ bool COneButtonFilter::DecorateView(CDasherView *pView) {
   return true;
 }
 
-bool COneButtonFilter::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
+bool COneButtonFilter::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
 
   if(bStarted) {
     iLocation = (Time - iStartTime) * 4096 / GetLongParameter(LP_STATIC1B_TIME);
@@ -70,7 +70,7 @@ bool COneButtonFilter::Timer(int Time, CDasherView *m_pDasherView, CDasherModel
   return m_pDasherModel->NextScheduledStep(Time, pAdded, pNumDeleted);
 }
 
-void COneButtonFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void COneButtonFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
   if (bStarted) {
     if (iLocation == 0) {
       //back up by one zoom step.
diff --git a/Src/DasherCore/OneButtonFilter.h b/Src/DasherCore/OneButtonFilter.h
index f841714..35bc3ed 100644
--- a/Src/DasherCore/OneButtonFilter.h
+++ b/Src/DasherCore/OneButtonFilter.h
@@ -11,9 +11,9 @@ class COneButtonFilter : public CInputFilter {
   COneButtonFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface);
   ~COneButtonFilter();
 
-  virtual bool DecorateView(CDasherView *pView);
-  virtual bool Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
-  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput);
+  virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
   bool GetSettings(SModuleSettings **pSettings, int *iCount);
  private:
   ///true iff the scan line is moving down/up, or is in the 'reverse' stage
diff --git a/Src/DasherCore/OneDimensionalFilter.cpp b/Src/DasherCore/OneDimensionalFilter.cpp
index be80d6e..8367f94 100644
--- a/Src/DasherCore/OneDimensionalFilter.cpp
+++ b/Src/DasherCore/OneDimensionalFilter.cpp
@@ -11,10 +11,10 @@ COneDimensionalFilter::COneDimensionalFilter(Dasher::CEventHandler * pEventHandl
   : CDefaultFilter(pEventHandler, pSettingsStore, pInterface, iID, szName), forwardmax(GetLongParameter(LP_MAX_Y)/2.5) {
 }
 
-bool COneDimensionalFilter::Timer(int Time, CDasherView *pView, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
+bool COneDimensionalFilter::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
   myint iDasherMinX,iDasherMaxY,iDasherMinY;
   pView->VisibleRegion(iDasherMinX, iDasherMinY, m_iDasherMaxX, iDasherMaxY);
-  return CDefaultFilter::Timer(Time,pView,pModel,pAdded,pNumDeleted,pol);
+  return CDefaultFilter::Timer(Time,pView,pInput,pModel,pAdded,pNumDeleted,pol);
 }
 
 void COneDimensionalFilter::ApplyTransform(myint &iDasherX, myint &iDasherY) {
diff --git a/Src/DasherCore/OneDimensionalFilter.h b/Src/DasherCore/OneDimensionalFilter.h
index 6d21e1c..c2d6bb2 100644
--- a/Src/DasherCore/OneDimensionalFilter.h
+++ b/Src/DasherCore/OneDimensionalFilter.h
@@ -10,7 +10,7 @@ class COneDimensionalFilter : public CDefaultFilter {
  public:
 //  COneDimensionalFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, CDasherModel *m_pDasherModel);
   COneDimensionalFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface,  ModuleID_t iID = 4, const char *szName = _("One Dimensional Mode"));
-  bool Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
   ///Override to remove DefaultFilters BP_REMAP_XTREME, BP_AUTOCALIBRATE, LP_OFFSET
   bool GetSettings(SModuleSettings **pSettings, int *iCount);
  protected:
diff --git a/Src/DasherCore/SocketInputBase.cpp b/Src/DasherCore/SocketInputBase.cpp
index c21bf8d..330858a 100644
--- a/Src/DasherCore/SocketInputBase.cpp
+++ b/Src/DasherCore/SocketInputBase.cpp
@@ -35,7 +35,7 @@ static SModuleSettings sSettings[] = {
 };
 
 Dasher::CSocketInputBase::CSocketInputBase(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore) 
-  : CDasherInput(pEventHandler, pSettingsStore, 1, _("Socket Input")) {
+  : CDasherCoordInput(pEventHandler, pSettingsStore, 1, _("Socket Input")) {
   port = -1;
   debug_socket_input = false;
   readerRunning = false;
diff --git a/Src/DasherCore/SocketInputBase.h b/Src/DasherCore/SocketInputBase.h
index c90f459..c5cc2b0 100644
--- a/Src/DasherCore/SocketInputBase.h
+++ b/Src/DasherCore/SocketInputBase.h
@@ -22,7 +22,7 @@ namespace Dasher {
 using namespace std;
 /// \ingroup Input 
 /// \{
-class CSocketInputBase : public CDasherInput {
+class CSocketInputBase : public CDasherCoordInput {
 
 public:
 
@@ -53,28 +53,26 @@ public:
     coordinateCount = _coordinateCount;
   }
 
-  // Fills pCoordinates with iN coordinate values, return 0 if the
-  // values were in screen coordinates or 1 if the values were in
-  // Dasher coordinates.
-
-  int GetCoordinates(int iN, myint * pCoordinates) {
-
-    for(int i = 0; i < iN && i < coordinateCount; i++) {
-      pCoordinates[i] = dasherCoordinates[i];
-    }
-    return 1;
-  };
-
-  // Get the number of co-ordinates that this device supplies
-
-  int GetCoordinateCount() {
-    return coordinateCount;
-  };
-
-  void SetMaxCoordinates(int iN, myint * iDasherMax) {
-    for(int i = 0; i < iN && i < DASHER_SOCKET_INPUT_MAX_COORDINATE_COUNT; i++) {
-      dasherMaxCoordinateValues[i] = iDasherMax[i];
+  /// Gets the last coordinates received; if only one coordinate is being read, this is put
+  /// into iDasherY (and iDasherX set to 0).
+  bool GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+    
+    //update max values for reader thread...(note any changes here won't be incorporated
+    // until values are next received over socket, but never mind)
+    myint iDasherMinX, iDasherMinY;
+    pView->VisibleRegion(iDasherMinX, iDasherMinY, dasherMaxCoordinateValues[0], dasherMaxCoordinateValues[1]);
+    
+    if (coordinateCount==1) {
+      iDasherX = 0;
+      iDasherY = dasherCoordinates[0];
+    } else if (coordinateCount==2) {
+      iDasherX = dasherCoordinates[0];
+      iDasherY = dasherCoordinates[1];
+    } else {
+      //Aiieee, we're receiving >2 coords? Don't know what to do...
+      return false;
     }
+    return true;
   };
 
   void Activate() {
diff --git a/Src/DasherCore/StartHandler.h b/Src/DasherCore/StartHandler.h
index b413662..d693c34 100644
--- a/Src/DasherCore/StartHandler.h
+++ b/Src/DasherCore/StartHandler.h
@@ -14,7 +14,7 @@ public:
   };
 
   virtual bool DecorateView(CDasherView *pView) = 0;
-  virtual void Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel) = 0;
+  virtual void Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel) = 0;
 
 protected:
   CDasherInterfaceBase *m_pInterface;
diff --git a/Src/DasherCore/StylusFilter.cpp b/Src/DasherCore/StylusFilter.cpp
index 4267b8d..7dad760 100644
--- a/Src/DasherCore/StylusFilter.cpp
+++ b/Src/DasherCore/StylusFilter.cpp
@@ -9,7 +9,7 @@ CStylusFilter::CStylusFilter(Dasher::CEventHandler *pEventHandler, CSettingsStor
   : CDefaultFilter(pEventHandler, pSettingsStore, pInterface, iID, szName) {
 }
 
-bool CStylusFilter::Timer(int iTime, CDasherView *pView, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)
+bool CStylusFilter::Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)
 {
   //First, try to continue any zoom scheduled by a previous click...
   if (pModel->NextScheduledStep(iTime, pAdded, pNumDeleted)) {
@@ -18,10 +18,10 @@ bool CStylusFilter::Timer(int iTime, CDasherView *pView, CDasherModel *pModel, D
     //which we're not using anyway.
     return true;
   }
-  return CDefaultFilter::Timer(iTime, pView, pModel, pAdded, pNumDeleted, pol);
+  return CDefaultFilter::Timer(iTime, pView, pInput, pModel, pAdded, pNumDeleted, pol);
 }
 
-void CStylusFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void CStylusFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
   if(iId == 100) {
     pModel->ClearScheduledSteps();
     m_pInterface->Unpause(iTime);
@@ -29,12 +29,12 @@ void CStylusFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel
   }
 }
 
-void CStylusFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherModel *pModel) {
+void CStylusFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel) {
   if(iId == 100) {
     if (iTime - m_iKeyDownTime < GetLongParameter(LP_TAP_TIME)) {
-      myint iDasherX, iDasherY;
-      pView->GetCoordinates(iDasherX, iDasherY);
-      pModel->ScheduleZoom(iTime, iDasherX, iDasherY, GetLongParameter(LP_MAXZOOM));
+      pInput->GetDasherCoords(m_iLastX, m_iLastY, pView);
+      //Do not apply transform. (Could add extra virtual method, ApplyClickTransform?)
+      pModel->ScheduleZoom(iTime, m_iLastX, m_iLastY, GetLongParameter(LP_MAXZOOM));
     } else {
       m_pInterface->Stop();
     }
diff --git a/Src/DasherCore/StylusFilter.h b/Src/DasherCore/StylusFilter.h
index 3dd1905..905299f 100644
--- a/Src/DasherCore/StylusFilter.h
+++ b/Src/DasherCore/StylusFilter.h
@@ -12,9 +12,9 @@ class CStylusFilter : public CDefaultFilter {
   ///Override DefaultFilter (which supports pause), as we don't
   /// - motion requires continually holding stylus against screen
   virtual bool supportsPause() {return false;}
-  virtual bool Timer(int Time, CDasherView *pView, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
-  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
-  virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherModel *pModel);
+  virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+  virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
+  virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel);
  private:
   int m_iKeyDownTime;
 };
diff --git a/Src/DasherCore/TwoBoxStartHandler.cpp b/Src/DasherCore/TwoBoxStartHandler.cpp
index 796db99..53b3fce 100644
--- a/Src/DasherCore/TwoBoxStartHandler.cpp
+++ b/Src/DasherCore/TwoBoxStartHandler.cpp
@@ -30,24 +30,20 @@ bool CTwoBoxStartHandler::DecorateView(CDasherView *pView) {
   }
 }
 
-void CTwoBoxStartHandler::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel) { 
-  myint iDasherX;
-  myint iDasherY;
-  m_pDasherView->GetCoordinates(iDasherX, iDasherY);
-  
+void CTwoBoxStartHandler::Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel) { 
   screenint iNewScreenX;
   screenint iNewScreenY;
-  m_pDasherView->Dasher2Screen(iDasherX, iDasherY, iNewScreenX, iNewScreenY);
+  pInput->GetScreenCoords(iNewScreenX, iNewScreenY, pView);
 
   int iBoxMax(-1);
   int iBoxMin(0);
 
   if(GetLongParameter(LP_MOUSE_POS_BOX) == 1) {
-    iBoxMax = m_pDasherView->Screen()->GetHeight() / 2 - (int)GetLongParameter(LP_MOUSEPOSDIST) + 50;
+    iBoxMax = pView->Screen()->GetHeight() / 2 - (int)GetLongParameter(LP_MOUSEPOSDIST) + 50;
     iBoxMin = iBoxMax - 100;
   }
   else if(GetLongParameter(LP_MOUSE_POS_BOX) == 2) {
-    iBoxMin = m_pDasherView->Screen()->GetHeight() / 2 + (int)GetLongParameter(LP_MOUSEPOSDIST) - 50;
+    iBoxMin = pView->Screen()->GetHeight() / 2 + (int)GetLongParameter(LP_MOUSEPOSDIST) - 50;
     iBoxMax = iBoxMin + 100;
   }
 
diff --git a/Src/DasherCore/TwoBoxStartHandler.h b/Src/DasherCore/TwoBoxStartHandler.h
index 896d24a..7d8f6ef 100644
--- a/Src/DasherCore/TwoBoxStartHandler.h
+++ b/Src/DasherCore/TwoBoxStartHandler.h
@@ -11,7 +11,7 @@ public:
   CTwoBoxStartHandler(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, CDasherInterfaceBase *pInterface);
 
   virtual bool DecorateView(CDasherView *pView);
-  virtual void Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel);
+  virtual void Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *m_pDasherModel);
   virtual void HandleEvent(Dasher::CEvent * pEvent);
 
  private:
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.cpp b/Src/DasherCore/TwoButtonDynamicFilter.cpp
index 869613b..d85a14e 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.cpp
+++ b/Src/DasherCore/TwoButtonDynamicFilter.cpp
@@ -56,7 +56,7 @@ CTwoButtonDynamicFilter::CTwoButtonDynamicFilter(Dasher::CEventHandler * pEventH
   HandleEvent(&oEvent);
 }
 
-bool CTwoButtonDynamicFilter::DecorateView(CDasherView *pView) {
+bool CTwoButtonDynamicFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
   CDasherScreen *pScreen(pView->Screen());
 
   CDasherScreen::point p[2];
@@ -93,22 +93,22 @@ bool CTwoButtonDynamicFilter::DecorateView(CDasherView *pView) {
   return bRV;
 }
 
-void CTwoButtonDynamicFilter::KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
+void CTwoButtonDynamicFilter::KeyDown(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
 	if (iId == 100 && !GetBoolParameter(BP_BACKOFF_BUTTON))
 		//mouse click - will be ignored by superclass method.
 		//simulate press of button 2/3 according to whether click in top/bottom half
-		CButtonMultiPress::KeyDown(Time, (iY < pDasherView->Screen()->GetHeight()/2) ? 2 : 3, pDasherView, pModel, pUserLog);
+		CButtonMultiPress::KeyDown(Time, (iY < pView->Screen()->GetHeight()/2) ? 2 : 3, pView, pInput, pModel, pUserLog);
 	else
-		CInputFilter::KeyDown(Time, iId, pDasherView, pModel, pUserLog, bPos, iX, iY);
+		CInputFilter::KeyDown(Time, iId, pView, pInput, pModel, pUserLog, bPos, iX, iY);
 }
 
-void CTwoButtonDynamicFilter::KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY) {
+void CTwoButtonDynamicFilter::KeyUp(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY) {
 	if (iId == 100 && !GetBoolParameter(BP_BACKOFF_BUTTON))
 		//mouse click - will be ignored by superclass method.
 		//simulate press of button 2/3 according to whether click in top/bottom half
-		CButtonMultiPress::KeyUp(Time, (iY < pDasherView->Screen()->GetHeight()/2) ? 2 : 3, pDasherView, pModel);
+		CButtonMultiPress::KeyUp(Time, (iY < pView->Screen()->GetHeight()/2) ? 2 : 3, pView, pInput,pModel);
 	else
-		CInputFilter::KeyUp(Time, iId, pDasherView, pModel, bPos, iX, iY);
+		CInputFilter::KeyUp(Time, iId, pView, pInput, pModel, bPos, iX, iY);
 }
 
 bool CTwoButtonDynamicFilter::TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.h b/Src/DasherCore/TwoButtonDynamicFilter.h
index 8a62103..03b343d 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.h
+++ b/Src/DasherCore/TwoButtonDynamicFilter.h
@@ -33,7 +33,7 @@ class CTwoButtonDynamicFilter : public CButtonMultiPress {
   CTwoButtonDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface);
 
   // Inherited methods
-  virtual bool DecorateView(CDasherView *pView);
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput);
  
   virtual void Activate();
   virtual void Deactivate();
@@ -50,8 +50,8 @@ class CTwoButtonDynamicFilter : public CButtonMultiPress {
   virtual void reverse();
 
   //override to inspect x,y coords of mouse clicks/taps
-  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
-  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY);
+  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
+  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY);
 	
  private:
   unsigned int maxClickCount() {return GetBoolParameter(BP_2B_INVERT_DOUBLE) ? 3 : 2;}
diff --git a/Src/DasherCore/TwoPushDynamicFilter.cpp b/Src/DasherCore/TwoPushDynamicFilter.cpp
index 3a5ae90..89e3139 100644
--- a/Src/DasherCore/TwoPushDynamicFilter.cpp
+++ b/Src/DasherCore/TwoPushDynamicFilter.cpp
@@ -65,7 +65,7 @@ void GuideLine(CDasherView *pView, const myint iDasherY, const int iColour)
   pScreen->Polyline(p, 2, 3, iColour);
 }  
 
-bool CTwoPushDynamicFilter::DecorateView(CDasherView *pView)
+bool CTwoPushDynamicFilter::DecorateView(CDasherView *pView, CDasherInput *pInput)
 {  
   //outer guides (yellow rects)
   for (int i=0; i<2; i++)
@@ -171,22 +171,22 @@ void CTwoPushDynamicFilter::HandleEvent(Dasher::CEvent * pEvent)
   }
 }
 
-void CTwoPushDynamicFilter::KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
+void CTwoPushDynamicFilter::KeyDown(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY) {
   if (iId == 100 && !GetBoolParameter(BP_BACKOFF_BUTTON))
     //mouse click - will be ignored by superclass method.
     //simulate press of button 2...
-    CDynamicFilter::KeyDown(Time, 2, pDasherView, pModel, pUserLog);
+    CDynamicFilter::KeyDown(Time, 2, pView, pInput, pModel, pUserLog);
   else
-    CInputFilter::KeyDown(Time, iId, pDasherView, pModel, pUserLog, bPos, iX, iY);
+    CInputFilter::KeyDown(Time, iId, pView, pInput, pModel, pUserLog, bPos, iX, iY);
 }
 
-void CTwoPushDynamicFilter::KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY) {
+void CTwoPushDynamicFilter::KeyUp(int Time, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY) {
   if (iId == 100 && !GetBoolParameter(BP_BACKOFF_BUTTON))
   //mouse click - will be ignored by superclass method.
   //simulate press of button 2...
-    CDynamicFilter::KeyUp(Time, 2, pDasherView, pModel);
+    CDynamicFilter::KeyUp(Time, 2, pView, pInput, pModel);
   else
-    CInputFilter::KeyUp(Time, iId, pDasherView, pModel, bPos, iX, iY);
+    CInputFilter::KeyUp(Time, iId, pView, pInput, pModel, bPos, iX, iY);
 }
 
 void CTwoPushDynamicFilter::ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog) {
diff --git a/Src/DasherCore/TwoPushDynamicFilter.h b/Src/DasherCore/TwoPushDynamicFilter.h
index 4682343..c02c7b4 100644
--- a/Src/DasherCore/TwoPushDynamicFilter.h
+++ b/Src/DasherCore/TwoPushDynamicFilter.h
@@ -30,7 +30,7 @@ class CTwoPushDynamicFilter : public CDynamicFilter /*long push, but do our own
   CTwoPushDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface);
   
   // Inherited methods
-  virtual bool DecorateView(CDasherView *pView);
+  virtual bool DecorateView(CDasherView *pView, CDasherInput *pInput);
  
   virtual void Activate();
   virtual void Deactivate();
@@ -38,8 +38,8 @@ class CTwoPushDynamicFilter : public CDynamicFilter /*long push, but do our own
   virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
 
   //override to get mouse clicks / taps back again...
-  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
-  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherModel *pModel, bool bPos, int iX, int iY);
+  virtual void KeyDown(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
+  virtual void KeyUp(int Time, int iId, CDasherView *pDasherView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY);
 
  protected:
   virtual bool TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
diff --git a/Src/Gtk2/mouse_input.h b/Src/Gtk2/mouse_input.h
index 68b81a1..d5d8c04 100644
--- a/Src/Gtk2/mouse_input.h
+++ b/Src/Gtk2/mouse_input.h
@@ -9,10 +9,10 @@
 
 using namespace Dasher;
 
-class CDasherMouseInput : public CDasherInput {
+class CDasherMouseInput : public CScreenCoordInput {
 public:
   CDasherMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore) 
-    : CDasherInput(pEventHandler, pSettingsStore, 0, _("Mouse Input")) {
+    : CScreenCoordInput(pEventHandler, pSettingsStore, 0, _("Mouse Input")) {
 
     m_iX = 0;
     m_iY = 0;
@@ -22,18 +22,12 @@ public:
   // values were in screen coordinates or 1 if the values were in
   // Dasher coordinates.
 
-  virtual int GetCoordinates(int iN, myint * pCoordinates) {
+  virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
 
-    pCoordinates[0] = m_iX;
-    pCoordinates[1] = m_iY;
+    iX = m_iX;
+    iY = m_iY;
 
-    return 0;
-  };
-
-  // Get the number of co-ordinates that this device supplies
-
-  virtual int GetCoordinateCount() {
-    return 2;
+    return true;
   };
 
   void SetCoordinates(myint _iX, myint _iY) {
@@ -51,11 +45,11 @@ static SModuleSettings sSettings[] = {
   {LP_YSCALE, T_LONG, 10, 2000, 1, 1, _("Pixels covering Y range")}
 };
 
-class CDasher1DMouseInput:public CDasherInput {
+class CDasher1DMouseInput : public CDasherCoordInput {
 public:
   CDasher1DMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore) 
     /* TRANSLATORS: Only use the vertical mouse coordinate - this is prefered for some disabled users. */
-    : CDasherInput(pEventHandler, pSettingsStore, 2, _("One Dimensional Mouse Input")) {
+    : CDasherCoordInput(pEventHandler, pSettingsStore, 2, _("One Dimensional Mouse Input")) {
 
     m_iOffset = 0;
 
@@ -67,15 +61,10 @@ public:
   // values were in screen coordinates or 1 if the values were in
   // Dasher coordinates.
 
-  virtual int GetCoordinates(int iN, myint * pCoordinates) {
-    pCoordinates[0] = m_iY; 
-    return 1;
-  };
-
-  // Get the number of co-ordinates that this device supplies
-
-  virtual int GetCoordinateCount() {
-    return 1;
+  virtual bool GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+    iDasherX=0;
+    iDasherY = m_iY; 
+    return true;
   };
 
   virtual void SetMaxCoordinates(int iN, myint * iDasherMax) {
diff --git a/Src/MacOSX/COSXMouseInput.h b/Src/MacOSX/COSXMouseInput.h
index 623294c..2c02e42 100644
--- a/Src/MacOSX/COSXMouseInput.h
+++ b/Src/MacOSX/COSXMouseInput.h
@@ -14,29 +14,16 @@
 
 using namespace Dasher;
 
-class COSXMouseInput : public CDasherInput {
+class COSXMouseInput : public CScreenCoordInput {
 public:
   COSXMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore) 
-  : CDasherInput(pEventHandler, pSettingsStore, 0, "Mouse Input") {
-  };
-  
-  // Fill pCoordinates with iN coordinate values, return 0 if the
-  // values were in screen coordinates or 1 if the values were in
-  // Dasher coordinates.
-  
-  virtual int GetCoordinates(int iN, myint * pCoordinates) {
-    
-    pCoordinates[0] = m_iX;
-    pCoordinates[1] = m_iY;
-    
-    return 0;
-  };
-  
-  // Get the number of co-ordinates that this device supplies
-  
-  virtual int GetCoordinateCount() {
-    return 2;
+  : CScreenCoordInput(pEventHandler, pSettingsStore, 0, "Mouse Input") {
   };
+  virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
+    iX = m_iX;
+    iY = m_iY;
+    return true;
+  }
   
   void SetCoordinates(myint _iX, myint _iY) {
     m_iX = _iX;
@@ -53,31 +40,18 @@ static SModuleSettings sSettings[] = {
   {LP_YSCALE, T_LONG, 10, 2000, 1, 1, "Pixels covering Y range:"}
 };
 
-class COSX1DMouseInput:public CDasherInput {
+class COSX1DMouseInput:public CDasherCoordInput {
 public:
   COSX1DMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore) 
-  : CDasherInput(pEventHandler, pSettingsStore, 2, "One Dimensional Mouse Input") {
+  : CDasherCoordInput(pEventHandler, pSettingsStore, 2, "One Dimensional Mouse Input") {
     
     m_iOffset = 0;
   };
   
-  // Fill pCoordinates with iN coordinate values, return 0 if the
-  // values were in screen coordinates or 1 if the values were in
-  // Dasher coordinates.
-  
-  virtual int GetCoordinates(int iN, myint * pCoordinates) {
-    
-    pCoordinates[0] = m_iY - m_iOffset;// * m_iDasherMaxY / 1024;      // FIXME - hard coded screen resolution!!!!!!!!!!
-    
-    //    std::cout << m_iY << " " << pCoordinates[0] << std::endl;
-    
-    return 1;
-  };
-  
-  // Get the number of co-ordinates that this device supplies
-  
-  virtual int GetCoordinateCount() {
-    return 1;
+  virtual bool GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+    iDasherX = 0;
+    iDasherY = m_iY - m_iOffset;
+    return true;
   };
   
   virtual void SetMaxCoordinates(int iN, myint * iDasherMax) {
diff --git a/Src/Win32/BTSocketInput.cpp b/Src/Win32/BTSocketInput.cpp
index 77b22c8..16813cc 100644
--- a/Src/Win32/BTSocketInput.cpp
+++ b/Src/Win32/BTSocketInput.cpp
@@ -32,13 +32,13 @@ static const int ymax = -32;
 // TODO: Probably incompatable with the socket server module
 
 CBTSocketInput::CBTSocketInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore)
-: CDasherInput(pEventHandler, pSettingsStore, 100, "BT Tilt Socket"){
+: CDasherCoordInput(pEventHandler, pSettingsStore, 100, "BT Tilt Socket"){
 }
 
 CBTSocketInput::~CBTSocketInput(void) {
 }
 
-int CBTSocketInput::GetCoordinates(int iN, myint *pCoordinates) {
+bool CBTSocketInput::GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
     // Send the magic command...
 	const char *szCommand = "<message command=\"orientation\"></message>\r\n";
 	int iRetVal = send(m_oSocket, szCommand, strlen(szCommand), 0);
@@ -60,10 +60,10 @@ int CBTSocketInput::GetCoordinates(int iN, myint *pCoordinates) {
 	int xrange = xmax - xmin;
 	int yrange = ymax - ymin;
 
-	pCoordinates[0] = (atoi(szXStart) - xmin) * 4096 / xrange;
-	pCoordinates[1] = (atoi(szYStart) - ymin) * 4096 / yrange;
+	iDasherX = (atoi(szXStart) - xmin) * 4096 / xrange;
+	iDasherY = (atoi(szYStart) - ymin) * 4096 / yrange;
 
-	return 1;
+	return true;
 }
 
 void CBTSocketInput::Activate() {
diff --git a/Src/Win32/BTSocketInput.h b/Src/Win32/BTSocketInput.h
index 8507b39..0b69720 100644
--- a/Src/Win32/BTSocketInput.h
+++ b/Src/Win32/BTSocketInput.h
@@ -10,18 +10,12 @@ namespace Dasher {
   class CBTSocketInput;
 } 
 
-class Dasher::CBTSocketInput : public CDasherInput {
+class Dasher::CBTSocketInput : public CDasherCoordInput {
 public:
   CBTSocketInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore);
   ~CBTSocketInput(void);
 
-  virtual int GetCoordinates(int iN, myint * pCoordinates);
-
-  // Get the number of co-ordinates that this device supplies
-
-  virtual int GetCoordinateCount() {
-    return 2;
-  };
+  virtual bool GetDasherCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView);
 
   virtual void Activate();
   virtual void Deactivate();
@@ -29,4 +23,4 @@ public:
 private:
   SOCKET m_oSocket;
  
-};
\ No newline at end of file
+};
diff --git a/Src/Win32/DasherMouseInput.cpp b/Src/Win32/DasherMouseInput.cpp
index 42875b2..ccdd392 100644
--- a/Src/Win32/DasherMouseInput.cpp
+++ b/Src/Win32/DasherMouseInput.cpp
@@ -15,21 +15,21 @@ static char THIS_FILE[] = __FILE__;
 #endif
 
 CDasherMouseInput::CDasherMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, HWND _hwnd)
-: CDasherInput(pEventHandler, pSettingsStore, 0, "Mouse Input"), m_hwnd(_hwnd) {
+: CScreenCoordInput(pEventHandler, pSettingsStore, 0, "Mouse Input"), m_hwnd(_hwnd) {
 }
 
 CDasherMouseInput::~CDasherMouseInput(void) {
 }
 
-int CDasherMouseInput::GetCoordinates(int iN, myint *pCoordinates) {
+bool CDasherMouseInput::GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
 
   POINT mousepos;
   GetCursorPos(&mousepos);
 
   ScreenToClient(m_hwnd, &mousepos);
 
-  pCoordinates[0] = mousepos.x;
-  pCoordinates[1] = mousepos.y;
+  iX = mousepos.x;
+  iY = mousepos.y;
 
-  return 0;
+  return true;
 }
diff --git a/Src/Win32/DasherMouseInput.h b/Src/Win32/DasherMouseInput.h
index 3cb61df..23203bc 100644
--- a/Src/Win32/DasherMouseInput.h
+++ b/Src/Win32/DasherMouseInput.h
@@ -5,18 +5,12 @@ namespace Dasher {
   class CDasherMouseInput;
 } 
 
-class Dasher::CDasherMouseInput : public CDasherInput {
+class Dasher::CDasherMouseInput : public CScreenCoordInput {
 public:
   CDasherMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, HWND _hwnd);
   ~CDasherMouseInput(void);
 
-  virtual int GetCoordinates(int iN, myint * pCoordinates);
-
-  // Get the number of co-ordinates that this device supplies
-
-  virtual int GetCoordinateCount() {
-    return 2;
-  };
+  virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView);
 
 private:
   HWND m_hwnd;
diff --git a/Src/iPhone/Classes/EAGLView.mm b/Src/iPhone/Classes/EAGLView.mm
index 254a6d7..f0be848 100644
--- a/Src/iPhone/Classes/EAGLView.mm
+++ b/Src/iPhone/Classes/EAGLView.mm
@@ -89,6 +89,8 @@
 	dasherApp.dasherInterface->NotifyTouch(p.x,p.y);
 	anyDown = NO;
 	dasherApp.dasherInterface->KeyUp(get_time(), 100, true, p.x, p.y);
+  //finished dealing with touch-up event. Finger is now officially off the screen...
+  dasherApp.dasherInterface->NotifyTouch(-1, -1);
 }
 
 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
diff --git a/Src/iPhone/Classes/IPhoneFilters.cpp b/Src/iPhone/Classes/IPhoneFilters.cpp
index e829e60..388d94e 100644
--- a/Src/iPhone/Classes/IPhoneFilters.cpp
+++ b/Src/iPhone/Classes/IPhoneFilters.cpp
@@ -18,10 +18,10 @@
 CIPhone1DFilter::CIPhone1DFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID)
 : COneDimensionalFilter(pEventHandler, pSettingsStore, pInterface, iID, ONE_D_FILTER), m_iSlow(0), m_dRad(1.0) {};
 
-bool CIPhone1DFilter::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)
+bool CIPhone1DFilter::Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol)
 {
 	myint iDasherX,iDasherY;
-	m_pDasherView->GetCoordinates(iDasherX, iDasherY);
+	pInput->GetDasherCoords(iDasherX, iDasherY, pView);
 	if (iDasherX > 3072/*ICK*/) {
     //tilted to left; slow down to 0.25* speed (suddenly!)
     m_iSlow = -1; m_dRad = 0.25;
@@ -45,7 +45,7 @@ bool CIPhone1DFilter::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel
 			m_dRad = (iTime - m_iSlow) / (double)GetLongParameter(LP_SLOW_START_TIME);
 		}
 	}
-	return CDefaultFilter::Timer(iTime, m_pDasherView, m_pDasherModel, pAdded, pNumDeleted, pol);
+	return CDefaultFilter::Timer(iTime, pView, pInput, pModel, pAdded, pNumDeleted, pol);
 }
 			
 void CIPhone1DFilter::ApplyTransform(myint &iDasherX, myint &iDasherY) {
@@ -70,12 +70,12 @@ void CIPhonePolarFilter::ApplyTransform(myint &iDasherX, myint &iDasherY) {
 	iDasherY = (iDasherY - oy)*dRad + oy;	
 }
 
-void CIPhonePolarFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
+void CIPhonePolarFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
 	if(iId == 100)
 		m_pInterface->Unpause(iTime);
 }
 
-void CIPhonePolarFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherModel *pModel) {
+void CIPhonePolarFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel) {
 	if(iId == 100)
 		m_pInterface->Stop();
 }
\ No newline at end of file
diff --git a/Src/iPhone/Classes/IPhoneFilters.h b/Src/iPhone/Classes/IPhoneFilters.h
index 8f5ad4a..439f0a8 100644
--- a/Src/iPhone/Classes/IPhoneFilters.h
+++ b/Src/iPhone/Classes/IPhoneFilters.h
@@ -17,7 +17,7 @@ class CIPhone1DFilter : public COneDimensionalFilter {
 public:
 	CIPhone1DFilter(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID);
 
-	virtual bool Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+	virtual bool Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
 protected:
 	virtual void ApplyTransform(myint &iDasherX, myint &iDasherY);
 private:
@@ -29,8 +29,8 @@ class CIPhonePolarFilter : public COneDimensionalFilter {
 public:
 	CIPhonePolarFilter(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID);
 	
-	virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
-	virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherModel *pModel);
+	virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
+	virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel);
 protected:
 	virtual void ApplyTransform(myint &iDasherX, myint &iDasherY);
 };
diff --git a/Src/iPhone/Classes/IPhoneInputs.h b/Src/iPhone/Classes/IPhoneInputs.h
index fb4bc63..ef00b1b 100644
--- a/Src/iPhone/Classes/IPhoneInputs.h
+++ b/Src/iPhone/Classes/IPhoneInputs.h
@@ -20,23 +20,18 @@
 #define REVERSE_MIX "Reverse Mix"
 namespace Dasher {
 
-class CIPhoneInput : public CDasherInput {
+class CIPhoneInput : public CScreenCoordInput {
 public:
 	CIPhoneInput(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const char *name)
-	: CDasherInput(pEventHandler, pSettingsStore, 0, 0, name) {};
+	: CScreenCoordInput(pEventHandler, pSettingsStore, 0, 0, name) {};
 	void SetScreenBounds(int maxX, int maxY) {this->maxX=maxX; this->maxY=maxY;}
 		
-	int GetCoordinateCount() {return 2;}
-	
-	// Fill pCoordinates with iN coordinate values, return 0 if the
-	// values were in screen coordinates or 1 if the values were in
-	// Dasher coordinates.
-	virtual int GetCoordinates(int iN, myint * pCoordinates) {
-		
-		pCoordinates[0] = m_iX;
-		pCoordinates[1] = m_iY;
+	virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
+    if (m_iX==-1) return false;
+    iX = m_iX;
+		iY = m_iY;
 		
-		return 0;
+		return true;
 	};
 	
 protected:
@@ -87,12 +82,7 @@ public:
 				CDasherInput *pXinput, CDasherInput *pYinput, const char *name)
 	: CDasherInput(pEventHandler, pSettingsStore, 0, 0, name), m_pXinput(pXinput), m_pYinput(pYinput) {};
 	
-	int GetCoordinateCount() {return 2;}
-	
-	// Fill pCoordinates with iN coordinate values, return 0 if the
-	// values were in screen coordinates or 1 if the values were in
-	// Dasher coordinates.
-	virtual int GetCoordinates(int iN, myint * pCoordinates);
+	virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView);
 	void Activate();
 	void Deactivate();
 private:
diff --git a/Src/iPhone/Classes/IPhoneInputs.mm b/Src/iPhone/Classes/IPhoneInputs.mm
index 9876987..e42e564 100644
--- a/Src/iPhone/Classes/IPhoneInputs.mm
+++ b/Src/iPhone/Classes/IPhoneInputs.mm
@@ -95,14 +95,11 @@ CIPhoneMouseInput::CIPhoneMouseInput(CEventHandler * pEventHandler, CSettingsSto
 	: CIPhoneInput(pEventHandler, pSettingsStore, TOUCH_INPUT) {
 };
 
-int CMixedInput::GetCoordinates(int iN, myint * pCoordinates) {
-	DASHER_ASSERT(iN == 2);
-	myint pXCoords[2];
-	m_pYinput->GetCoordinates(2, pCoordinates);
-	m_pXinput->GetCoordinates(2, pXCoords);
-	pCoordinates[0] = pXCoords[0];
-	
-	return 0;
+bool CMixedInput::GetScreenCoords(screenint &iX, screenint &iY,CDasherView *pView) {
+  screenint temp;
+	if (!m_pYinput->GetScreenCoords(temp,iY,pView)) return false;
+  //got y; x coord stored into temp is not needed
+	return m_pXinput->GetScreenCoords(iX, temp,pView);
 };
 
 void CMixedInput::Activate() {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]