#include "TabletReader.h"
#include "TabletStroke.h"
#include "TabletStrokeList.h"
#include "TabletReader.c7"
ClassImp(TabletReader);
void TabletReader::_init()
{
mStrokeType = SS_Absolute;
bInvertY = true;
bKeepStrokeInProximity = true;
mPosScale = mPrsScale = 0;
mOffX = mOffY = 0;
mButtons = 0;
bButton0 = bButton1 = bStylus1 = bStylus2 = false;
bInProximity = bInTouch = bInStroke = false;
bPrintButtEvs = false;
bPrintButtState = false;
bPrintPositions = false;
bPrintOther = true;
}
TabletReader::TabletReader(const Text_t* n, const Text_t* t) :
ZNode(n, t),
mTabletThread(0)
{
_init();
}
TabletReader::~TabletReader()
{}
const char* TabletReader::get_button_name(Int_t bb)
{
const char* name = "undef";
switch (bb)
{
case BB_Touch: name = "Touch"; break;
case BB_Stylus_1: name = "Stylus_1"; break;
case BB_Stylus_2: name = "Stylus_2"; break;
case BB_Button_0: name = "Button_0"; break;
case BB_Button_1: name = "Button_1"; break;
}
return name;
}
Bool_t TabletReader::flip_report_button(Int_t bb)
{
mButtons ^= bb;
Bool_t val = get_button(bb);
if (bPrintButtEvs)
{
const char* name = get_button_name(bb);
printf("Button %s %s\n", name, val ? "DOWN" : "UP");
}
return val;
}
Bool_t TabletReader::check_pen_buttons(Int_t buttons_delta)
{
Bool_t change = false;
if (buttons_delta & BB_Touch)
{
Bool_t down = flip_report_button(BB_Touch);
if ( ! bInStroke || ! bKeepStrokeInProximity)
{
if (down)
{
begin_stroke();
}
else
{
end_stroke();
}
}
bInTouch = down;
change = true;
}
if (buttons_delta & BB_Stylus_1)
{
bStylus1 = flip_report_button(BB_Stylus_1);
change = true;
}
if (buttons_delta & BB_Stylus_2)
{
bStylus2 = flip_report_button(BB_Stylus_2);
change = true;
}
return change;
}
void TabletReader::clear_pen_buttons()
{
if (bInStroke)
end_stroke();
mButtons &= ~BB_Pad_Buttons;
bInTouch = bStylus1 = bStylus2 = false;
}
Bool_t TabletReader::check_pad_buttons(Int_t buttons_delta)
{
Bool_t change = false;
if (buttons_delta & BB_Button_0)
{
bool down = flip_report_button(BB_Button_0);
if (down)
begin_stroke_list();
bButton0 = down;
change = true;
}
if (buttons_delta & BB_Button_1)
{
bool down = flip_report_button(BB_Button_1);
if (down)
end_stroke_list();
bButton1 = down;
change = true;
}
return change;
}
void TabletReader::begin_stroke_list()
{
static const Exc_t _eh("TabletReader::begin_stroke_list ");
GLensWriteHolder _wlck(this);
if (mStrokeList == 0)
{
mFirstStrokeStart = mStrokeStart = GTime();
TabletStrokeList *slist = new TabletStrokeList("StrokeList");
mQueen->CheckIn(slist);
SetStrokeList(slist);
Add(slist);
}
else
{
ISwarn(_eh + "Already active StrokeList.");
}
}
void TabletReader::end_stroke_list()
{
static const Exc_t _eh("TabletReader::end_stroke_list ");
GLensWriteHolder _wlck(this);
if (mStrokeList != 0)
{
end_stroke();
SetStrokeList(0);
}
else
{
ISwarn(_eh + "No active StrokeList.");
}
}
void TabletReader::begin_stroke()
{
GLensWriteHolder _wlck(this);
if (mFirstStrokeStart.IsZero())
mFirstStrokeStart = mEventTime;
mStrokeStart = mEventTime;
if (mStrokeList != 0 && mStroke == 0)
{
TabletStroke *stroke = new TabletStroke("Stroke");
stroke->SetStartTime((mStrokeStart - mFirstStrokeStart).ToFloat());
mQueen->CheckIn(stroke);
SetStroke(stroke);
bInStroke = true;
{
GLensReadHolder _rlck(*mStroke);
mStroke->BeginStroke();
}
auto_ptr<ZMIR> m(mStrokeList->S_Add(*mStroke));
mSaturn->ShootMIR(m);
}
}
void TabletReader::end_stroke()
{
GLensWriteHolder _wlck(this);
if (mStroke != 0)
{
{
GLensReadHolder _rlck(*mStroke);
mStroke->EndStroke(bKeepStrokeInProximity);
}
bInStroke = false;
SetStroke(0);
}
}
#include "Tmp1/TabletWacomDefines.h"
void TabletReader::StartRead()
{
static const Exc_t _eh("TabletReader::StartRead ");
{
GMutexHolder _lck(mTabletMutex);
if (mTabletThread != 0)
{
throw _eh + "Thread already running.";
}
mTabletThread = GThread::Self();
if (WacGledOpen("/dev/input/wacom", 1))
{
mTabletThread = 0;
throw _eh + "Spawning dumper failed.";
}
}
WACOMSTATEMINI s_min, s_max, s;
WacGledFetchMinMax(&s_min, &s_max);
printf("MIN x=%d y=%d p=%d\n", s_min.values[WACOMFIELD_POSITION_X], s_min.values[WACOMFIELD_POSITION_Y], s_min.values[WACOMFIELD_PRESSURE]);
printf("MAX x=%d y=%d p=%d\n", s_max.values[WACOMFIELD_POSITION_X], s_max.values[WACOMFIELD_POSITION_Y], s_max.values[WACOMFIELD_PRESSURE]);
mPosScale = 1.0f / s_max.values[WACOMFIELD_POSITION_X];
mOffX = s_max.values[WACOMFIELD_POSITION_X] / 2;
mOffY = s_max.values[WACOMFIELD_POSITION_Y] / 2;
mPrsScale = 1.0f / s_max.values[WACOMFIELD_PRESSURE];
Stamp(FID());
mButtons = 0;
bButton0 = bButton1 = bStylus1 = bStylus2 = false;
bInProximity = bInTouch = bInStroke = false;
mRawX = mRawY = mRawP = -1;
mPenXOff = mPenYOff = mPenTOff = 0;
GThread::UnblockSignal(GThread::SigUSR1);
GThread::ListSignalState();
while (!bReqStop)
{
if (WacGledFetch(&s))
{
printf("OGADUGA -- error fetching ... stopping acquisition.\n");
break;
}
mEventTime.SetNow();
Bool_t stamp_p = false;
Int_t tool = s.values[WACOMFIELD_TOOLTYPE];
Int_t buttons = s.values[WACOMFIELD_BUTTONS];
Int_t buttons_delta = buttons ^ mButtons;
Bool_t buttons_valid = s.valid & (1 << WACOMFIELD_BUTTONS);
Bool_t proximity = s.values[WACOMFIELD_PROXIMITY];
if (tool == T_None)
{
if (buttons_valid && check_pad_buttons(buttons_delta))
{
stamp_p = true;
}
else if ( ! proximity && bInProximity)
{
clear_pen_buttons();
mRawX = mRawY = mRawP = -1;
bInProximity = false;
stamp_p = true;
}
}
else if (tool == T_Pen || tool == T_Eraser)
{
stamp_p = true;
if ( ! bInProximity)
{
bInProximity = true;
}
if (buttons_valid)
{
check_pen_buttons(buttons_delta);
}
if (mRawX != s.values[WACOMFIELD_POSITION_X] ||
mRawY != s.values[WACOMFIELD_POSITION_Y] ||
mRawP != s.values[WACOMFIELD_PRESSURE])
{
mRawX = s.values[WACOMFIELD_POSITION_X];
mRawY = s.values[WACOMFIELD_POSITION_Y];
mRawP = s.values[WACOMFIELD_PRESSURE];
mPenX = mPosScale * (mRawX - mOffX);
mPenY = mPosScale * (mRawY - mOffY);
mPenP = mPrsScale * mRawP;
mPenT = (mEventTime - mStrokeStart).ToFloat();
if (bInvertY) mPenY = -mPenY;
if (bPrintPositions)
{
printf("PEN x=%d y=%d, p=%d, prox=%d\n",
s.values[WACOMFIELD_POSITION_X],
s.values[WACOMFIELD_POSITION_Y],
s.values[WACOMFIELD_PRESSURE],
s.values[WACOMFIELD_PROXIMITY]);
}
if (bInStroke)
{
GLensReadHolder _lck(*mStroke);
mStroke->AddPoint(mPenX, mPenY, mPenT, mPenP);
mStroke->StampReqTring(TabletStroke::FID());
}
}
}
else if (tool == T_Pad)
{
if (buttons_valid)
{
if (check_pad_buttons(buttons_delta))
stamp_p = true;
}
}
else
{
if (bPrintOther)
{
printf("tool= %d, 0x%x: x=%d y=%d, p=%d, prox=%d\n",
s.values[WACOMFIELD_TOOLTYPE], s.values[WACOMFIELD_TOOLTYPE],
s.values[WACOMFIELD_POSITION_X],
s.values[WACOMFIELD_POSITION_Y],
s.values[WACOMFIELD_PRESSURE],
s.values[WACOMFIELD_PROXIMITY]);
}
}
if (stamp_p)
{
if (bPrintButtState)
{
printf("S1:%d/%d, S2:%d/%d, B0:%d/%d, B1:%d/%d\n",
bStylus1, get_button(BB_Stylus_1),
bStylus2, get_button(BB_Stylus_2),
bButton0, get_button(BB_Button_0),
bButton1, get_button(BB_Button_1));
}
StampReqTring(FID());
}
}
{
GMutexHolder _lck(mTabletMutex);
printf("OGADUGA -- closing wacom\n");
WacGledClose();
printf("OGADUGA -- wacom closed\n");
bReqStop = false;
mTabletThread = 0;
}
}
void TabletReader::StopRead()
{
static const Exc_t _eh("TabletReader::StopRead ");
GMutexHolder _lck(mTabletMutex);
if (mTabletThread == 0)
throw _eh + "Thread not running.";
if (bReqStop)
throw _eh + "Already requested.";
bReqStop = true;
mTabletThread->Kill(GThread::SigUSR1);
}