WinTabPressurePen Class Reference

Overrides the base pressure-sensitive pen class to provide support for WinTab pressure-sensitive tablet devices. When such a device is unavailable, this class returns control to the base-class to allow joysticks and mice to be used to simulate pens based on speed and/or direction of travel rather than real applied pressure. More...

#include <tablet.h>

Inheritance diagram for WinTabPressurePen:

CCPen CCObject SimpleCCObject List of all members.

Public Member Functions

 WinTabPressurePen ()
 Constructor. Initialises the pen.
 ~WinTabPressurePen ()
 Destructor. Deinitialises the pen.
void PenProximityChanged (BOOL LeavingTablet)
 Called by the CMainFrame window when it recieves a WinTab WT_PROXIMITY message. This indicates that the pen is moving in or out of the pen detection area over the tablet. We keep track of the proximity of the pen, so that if the user puts it down and starts drawing with their mouse, we realise this and revert to base-class simulated pressure.

Protected Member Functions

virtual BOOL ReadTabletPressureData (void)
 Records the latest pressure info from the pressure sensitive tablet Does nothing if this is not a "real" pen.
virtual void StartStroke (void)
 Informs the Pen class that you are starting a stroke (a drag operation for which you wish to record pressure information).
virtual void EndStroke (void)
 Informs the Pen class that you are completing a stroke (a drag operation for which you recorded pressure information).
void InitPressure (void)
 Sets up the pen ready for reading pressure information. Reads back the maximum pressure value we'll be given, etc.

Protected Attributes

HCTX hTab
UINT32 wActiveCsr
UINT32 wOldCsr
BYTE wPrsBtn
UINT32 ClickThreshold
BOOL PenNotOnTablet

Private Member Functions

 CC_DECLARE_DYNAMIC (WinTabPressurePen)

Detailed Description

Overrides the base pressure-sensitive pen class to provide support for WinTab pressure-sensitive tablet devices. When such a device is unavailable, this class returns control to the base-class to allow joysticks and mice to be used to simulate pens based on speed and/or direction of travel rather than real applied pressure.

Author:
Martin_Donelly (Xara Group Ltd) <camelotdev@xara.com> (& Jason)
Date:
24/1/97

Definition at line 130 of file tablet.h.


Constructor & Destructor Documentation

WinTabPressurePen::WinTabPressurePen  ) 
 

Constructor. Initialises the pen.

Author:
Martin_Donelly (Xara Group Ltd) <camelotdev@xara.com> & Jason
Date:
24/1/97

Definition at line 132 of file tablet.cpp.

00133 {
00134     // Initialise member vars to sensible defaults
00135     hTab            = NULL;
00136     wActiveCsr      = NULL;
00137     wOldCsr         = NULL;
00138     wPrsBtn         = 0;
00139     ClickThreshold  = 0;
00140     PressureMax     = MAXPRESSURE;
00141     PenNotOnTablet  = TRUE;
00142 
00143     // Read the tablet default settings as a basis for our settings
00144     LOGCONTEXT lcMine;      
00145     INT32 Result = WTInfo(WTI_DEFCONTEXT, 0, &lcMine);
00146     if (Result == 0)
00147     {
00148         TRACE( _T("Pressure sensitive tablet not detected\n"));
00149         return;
00150     }
00151 
00152     // Modify some of the flags in the block we read above
00153     wsprintf(lcMine.lcName, "Camelot");
00154     lcMine.lcOptions    |= CXO_SYSTEM;
00155     lcMine.lcPktData    = PACKETDATA;
00156     lcMine.lcPktMode    = PACKETMODE;
00157     lcMine.lcMoveMask   = PACKETDATA;
00158 
00159     hTab = WTOpen(hMainframeWnd, &lcMine, TRUE);
00160     if (hTab == NULL)
00161     {
00162         ERROR3("Failed to initialise pressure sensitive tablet");
00163         return;
00164     }
00165 
00166     PressureAvailable = TRUE;       // We initialised! Woo hoo!
00167 
00168     // Set the packet queue size we desire - Why? The default of 8 should be ample
00169 /*
00170     Result = WTQueueSizeGet(hTab);
00171     TRACE( _T("Q size is %ld\n"), Result);
00172 
00173     INT32 QSize = NPACKETQSIZE;
00174     Result = 0;
00175     while (QSize >= 1 && Result == 0)
00176     {
00177         Result = WTQueueSizeSet(hTab, QSize);
00178         QSize /= 2;
00179     }
00180 */
00181     // And initalise the tablet ready for use
00182     InitPressure();
00183 }

WinTabPressurePen::~WinTabPressurePen  ) 
 

Destructor. Deinitialises the pen.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/1/97

Definition at line 198 of file tablet.cpp.

00199 {
00200     // If we've got a context open, let's close it to be tidy
00201     if (hTab != NULL)
00202         WTClose(hTab);
00203 }


Member Function Documentation

WinTabPressurePen::CC_DECLARE_DYNAMIC WinTabPressurePen   )  [private]
 

void WinTabPressurePen::EndStroke void   )  [protected, virtual]
 

Informs the Pen class that you are completing a stroke (a drag operation for which you recorded pressure information).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/1/97
This function must be called to "cancel" out a call to StartStroke. It should be called in your drag completion routine, and should be called under all "end of drag" circumstances.

Reimplemented from CCPen.

Definition at line 422 of file tablet.cpp.

00423 {
00424     // Stop WinTab bothering to collect packets now - we don't want em
00425     if (hTab != NULL)
00426     {
00427 //      WTEnable(hTab, FALSE);          // Disable the pen
00428         WTPacketsGet(hTab, 1, NULL);    // And flush remaining packets
00429     }
00430 }

void WinTabPressurePen::InitPressure void   )  [protected]
 

Sets up the pen ready for reading pressure information. Reads back the maximum pressure value we'll be given, etc.

Author:
Martin_Donelly (Xara Group Ltd) <camelotdev@xara.com> & Jason
Date:
24/1/97

Definition at line 311 of file tablet.cpp.

00312 {
00313     /* browse WinTab's many info items to discover pressure handling. */
00314     AXIS np;
00315     LOGCONTEXT lc;
00316     BYTE logBtns[32];
00317     UINT32 btnMarks[2];
00318     UINT32 size;
00319 
00320     /* discover the LOGICAL button generated by the pressure channel. */
00321     /* get the PHYSICAL button from the cursor category and run it */
00322     /* through that cursor's button map (usually the identity map). */
00323     wPrsBtn = (BYTE)-1;
00324     WTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBUTTON, &wPrsBtn);
00325     size = WTInfo(WTI_CURSORS + wActiveCsr, CSR_BUTTONMAP, &logBtns);
00326     if ((UINT32)wPrsBtn < size)
00327         wPrsBtn = logBtns[wPrsBtn];
00328 
00329     /* get the current context for its device variable. */
00330     WTGet(hTab, &lc);
00331 
00332     /* get the size of the pressure axis. */
00333     WTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np);
00334     UINT32 prsNoBtnOrg = (UINT32)np.axMin;
00335     UINT32 prsNoBtnExt = (UINT32)np.axMax - (UINT32)np.axMin;
00336 
00337     /* get the button marks (up & down generation thresholds) */
00338     /* and calculate what pressure range we get when pressure-button is down. */
00339     btnMarks[1] = 0; /* default if info item not present. */
00340     WTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBTNMARKS, btnMarks);
00341     ClickThreshold = btnMarks[1];
00342 
00343     PressureMax = (UINT32)np.axMax - ClickThreshold;
00344 }

void WinTabPressurePen::PenProximityChanged BOOL  LeavingTablet  ) 
 

Called by the CMainFrame window when it recieves a WinTab WT_PROXIMITY message. This indicates that the pen is moving in or out of the pen detection area over the tablet. We keep track of the proximity of the pen, so that if the user puts it down and starts drawing with their mouse, we realise this and revert to base-class simulated pressure.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/1/97
Parameters:
LeavingTablet - TRUE if the pen is leaving the tablet detection area [INPUTS] FALSE if the pen is re-entering the tablet area

Definition at line 452 of file tablet.cpp.

00453 {
00454     PenNotOnTablet = LeavingTablet;
00455 }

BOOL WinTabPressurePen::ReadTabletPressureData void   )  [protected, virtual]
 

Records the latest pressure info from the pressure sensitive tablet Does nothing if this is not a "real" pen.

Author:
Martin_Donelly (Xara Group Ltd) <camelotdev@xara.com> & Jason
Date:
24/1/97
Returns:
TRUE if it read pressure successfully FALSE if it failed - in this case, the caller (base class) will default to calculating a faked pressure value from movement information. (e.g. if you stop getting pen pressure packets, revert to using movement rather than always returning zero!)
Does nothing in the base class.

Reimplemented from CCPen.

Definition at line 227 of file tablet.cpp.

00228 {
00229     // If we couldn't initialise the tablet, or the pen isn't physically present on
00230     // the tablet at the moment (meaning that mouse movements are being generated
00231     // by a mouse), then revert to using the mouse simulation modes.
00232     if (!PressureAvailable || PenNotOnTablet)
00233         return(FALSE);
00234 
00235     if (hTab == NULL)
00236     {
00237         ERROR3("No tablet in ReadTabletPressureData");
00238         return(FALSE);
00239     }
00240 
00241     // Make sure our tablet context is "on top" of all others
00242     WTOverlap(hTab, TRUE);
00243 
00244     PACKET localPacketBuf;
00245     INT32 nPackets = WTPacketsGet(hTab, 1, &localPacketBuf);
00246 
00247     // If there are no new packets, then return immediately, pretending to the base class
00248     // that we were happy, so that it doesn't add in mouse handling code at random while we draw!
00249     if (nPackets <= 0)
00250         return(TRUE);
00251 
00252     wActiveCsr = localPacketBuf.pkCursor;
00253 
00254     // If this cursor doesn't return pressure data we need to behave like a normal mouse...
00255     WTPKT pktflags = 0;
00256     WTInfo(WTI_CURSORS + wActiveCsr, CSR_PKTDATA, &pktflags);
00257     if ((pktflags & PK_NORMAL_PRESSURE) == 0)
00258         return FALSE;
00259 
00260     // Determine which cursor is active - note that a cursor in this sense is
00261     // an input device, such as the pen end/eraser end of the pen. I think.
00262     if (wActiveCsr != wOldCsr)
00263     {
00264         // re-init on cursor change.
00265         InitPressure();
00266         wOldCsr = wActiveCsr;
00267     }
00268 
00269     if (localPacketBuf.pkButtons & (1 << wPrsBtn))
00270     {
00271         // The user has pressed hard enough to pass the "click" threshold
00272         // so the "button" is effectively down. We subtract the click
00273         // threshold value from the pressure, and return that. It is automatically
00274         // scaled by the pen caller, using our GetPressureMax() value.
00275         // We must be careful not to return negative pressure, though, because
00276         // a second threshold is used to control "release" of the click, so
00277         // that the pen does not "flutter" between clicked/unclicked when it nears
00278         // the threshold.
00279         if (localPacketBuf.pkNormalPressure > ClickThreshold)
00280             PenPressure = localPacketBuf.pkNormalPressure - ClickThreshold;
00281         else
00282             PenPressure = 0;
00283     }
00284     else
00285     {
00286         // The user has not pressed hard enough to pass the "click" threshold
00287         // so the "button" is effectively up - we ignore any pressure in this case.
00288         PenPressure = 0;
00289     }
00290 
00291     // And flush any enqueued packets so the next one we get is vaguely related to
00292     // the mouse position at which it occurred.
00293     WTPacketsGet(hTab, 1, NULL);
00294     return(TRUE);
00295 }

void WinTabPressurePen::StartStroke void   )  [protected, virtual]
 

Informs the Pen class that you are starting a stroke (a drag operation for which you wish to record pressure information).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/1/97
If you do not call this method, then pressure information will be "faked" based on mouse speed/direction information.

It should be called when you start your drag (on button down)

When the stroke finishes, remember to call WinTabPressurePen::EndStroke

Reimplemented from CCPen.

Definition at line 367 of file tablet.cpp.

00368 {
00369     // Set the base class up to generate pressure in the correct way
00370     // In case we fail, set pressure to maximum, so if we fall through
00371     // to a mouse handler, we don't get "blank" strokes
00372     CurrentPressureMode = DefaultPressureMode;
00373     PenPressure = PressureMax;
00374 
00375     // If we're not currently configured to use the pen pressure, then
00376     // we don't need to do any more - let the base class handle everything.
00377     if (CurrentPressureMode != PressureMode_Pen)
00378         return;
00379     
00380     // DY - we no longer wish to fake pressure using mouse speed, so if we're not
00381     // on the tablet at the start of the stroke then we're not doing it
00382     if (PenNotOnTablet)
00383         CurrentPressureMode = PressureMode_None;
00384 
00385     // If we failed to initialise a tablet, then revert to speed mode
00386     if (hTab == NULL)
00387     {
00388         CurrentPressureMode = PressureMode_Speed;
00389         return;
00390     }
00391 
00392     // ****!!!!TODO
00393     // We should really check tablet proximity here. If the pen's not
00394     // near the tablet, the user must be dragging with a different input
00395     // device. This requires that our Mainframe watches out for WT_PROXIMITY
00396     // messages and tells us about them.
00397 
00398     // OK, turn that baby on!
00399 //  WTEnable(hTab, TRUE);
00400 
00401     PenPressure = 0;
00402 }


Member Data Documentation

UINT32 WinTabPressurePen::ClickThreshold [protected]
 

Definition at line 162 of file tablet.h.

HCTX WinTabPressurePen::hTab [protected]
 

Definition at line 155 of file tablet.h.

BOOL WinTabPressurePen::PenNotOnTablet [protected]
 

Definition at line 164 of file tablet.h.

UINT32 WinTabPressurePen::wActiveCsr [protected]
 

Definition at line 157 of file tablet.h.

UINT32 WinTabPressurePen::wOldCsr [protected]
 

Definition at line 158 of file tablet.h.

BYTE WinTabPressurePen::wPrsBtn [protected]
 

Definition at line 160 of file tablet.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:03:09 2007 for Camelot by  doxygen 1.4.4