ROOT logo
// $Id: TabletReader.cxx 2499 2011-07-03 01:27:58Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

#include "TabletReader.h"
#include "TabletStroke.h"
#include "TabletStrokeList.h"
#include "TabletReader.c7"


// TabletReader

//______________________________________________________________________________
//
//

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)
{
  // Bool_t prev = get_button(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");
    // printf("Button %s %s, was %s\n", name, val ? "DOWN" : "UP", prev ? "DOWN" : "UP");
  }
  return val;
}

Bool_t TabletReader::check_pen_buttons(Int_t buttons_delta)
{
  // Check for changes in pen-related buttons.
  // Returns true if there was a change.

  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)
{
  // Check for changes in pad-related buttons.
  // Returns true if there was a change.

  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);
  // Default handler is ok ... just interrupt reading.

  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];

    // printf("t=%d, bv=%d\n", tool, buttons_valid);

    if (tool == T_None)
    {
      // This is tricky ... we get these events both for
      // pad-button-up and for proximity-out.
      // Then, there are also dummy events like this, usually in batches
      // of four, sometimes on proximity-in.
      // It took me a while to figure it out.
      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);
}
 TabletReader.cxx:1
 TabletReader.cxx:2
 TabletReader.cxx:3
 TabletReader.cxx:4
 TabletReader.cxx:5
 TabletReader.cxx:6
 TabletReader.cxx:7
 TabletReader.cxx:8
 TabletReader.cxx:9
 TabletReader.cxx:10
 TabletReader.cxx:11
 TabletReader.cxx:12
 TabletReader.cxx:13
 TabletReader.cxx:14
 TabletReader.cxx:15
 TabletReader.cxx:16
 TabletReader.cxx:17
 TabletReader.cxx:18
 TabletReader.cxx:19
 TabletReader.cxx:20
 TabletReader.cxx:21
 TabletReader.cxx:22
 TabletReader.cxx:23
 TabletReader.cxx:24
 TabletReader.cxx:25
 TabletReader.cxx:26
 TabletReader.cxx:27
 TabletReader.cxx:28
 TabletReader.cxx:29
 TabletReader.cxx:30
 TabletReader.cxx:31
 TabletReader.cxx:32
 TabletReader.cxx:33
 TabletReader.cxx:34
 TabletReader.cxx:35
 TabletReader.cxx:36
 TabletReader.cxx:37
 TabletReader.cxx:38
 TabletReader.cxx:39
 TabletReader.cxx:40
 TabletReader.cxx:41
 TabletReader.cxx:42
 TabletReader.cxx:43
 TabletReader.cxx:44
 TabletReader.cxx:45
 TabletReader.cxx:46
 TabletReader.cxx:47
 TabletReader.cxx:48
 TabletReader.cxx:49
 TabletReader.cxx:50
 TabletReader.cxx:51
 TabletReader.cxx:52
 TabletReader.cxx:53
 TabletReader.cxx:54
 TabletReader.cxx:55
 TabletReader.cxx:56
 TabletReader.cxx:57
 TabletReader.cxx:58
 TabletReader.cxx:59
 TabletReader.cxx:60
 TabletReader.cxx:61
 TabletReader.cxx:62
 TabletReader.cxx:63
 TabletReader.cxx:64
 TabletReader.cxx:65
 TabletReader.cxx:66
 TabletReader.cxx:67
 TabletReader.cxx:68
 TabletReader.cxx:69
 TabletReader.cxx:70
 TabletReader.cxx:71
 TabletReader.cxx:72
 TabletReader.cxx:73
 TabletReader.cxx:74
 TabletReader.cxx:75
 TabletReader.cxx:76
 TabletReader.cxx:77
 TabletReader.cxx:78
 TabletReader.cxx:79
 TabletReader.cxx:80
 TabletReader.cxx:81
 TabletReader.cxx:82
 TabletReader.cxx:83
 TabletReader.cxx:84
 TabletReader.cxx:85
 TabletReader.cxx:86
 TabletReader.cxx:87
 TabletReader.cxx:88
 TabletReader.cxx:89
 TabletReader.cxx:90
 TabletReader.cxx:91
 TabletReader.cxx:92
 TabletReader.cxx:93
 TabletReader.cxx:94
 TabletReader.cxx:95
 TabletReader.cxx:96
 TabletReader.cxx:97
 TabletReader.cxx:98
 TabletReader.cxx:99
 TabletReader.cxx:100
 TabletReader.cxx:101
 TabletReader.cxx:102
 TabletReader.cxx:103
 TabletReader.cxx:104
 TabletReader.cxx:105
 TabletReader.cxx:106
 TabletReader.cxx:107
 TabletReader.cxx:108
 TabletReader.cxx:109
 TabletReader.cxx:110
 TabletReader.cxx:111
 TabletReader.cxx:112
 TabletReader.cxx:113
 TabletReader.cxx:114
 TabletReader.cxx:115
 TabletReader.cxx:116
 TabletReader.cxx:117
 TabletReader.cxx:118
 TabletReader.cxx:119
 TabletReader.cxx:120
 TabletReader.cxx:121
 TabletReader.cxx:122
 TabletReader.cxx:123
 TabletReader.cxx:124
 TabletReader.cxx:125
 TabletReader.cxx:126
 TabletReader.cxx:127
 TabletReader.cxx:128
 TabletReader.cxx:129
 TabletReader.cxx:130
 TabletReader.cxx:131
 TabletReader.cxx:132
 TabletReader.cxx:133
 TabletReader.cxx:134
 TabletReader.cxx:135
 TabletReader.cxx:136
 TabletReader.cxx:137
 TabletReader.cxx:138
 TabletReader.cxx:139
 TabletReader.cxx:140
 TabletReader.cxx:141
 TabletReader.cxx:142
 TabletReader.cxx:143
 TabletReader.cxx:144
 TabletReader.cxx:145
 TabletReader.cxx:146
 TabletReader.cxx:147
 TabletReader.cxx:148
 TabletReader.cxx:149
 TabletReader.cxx:150
 TabletReader.cxx:151
 TabletReader.cxx:152
 TabletReader.cxx:153
 TabletReader.cxx:154
 TabletReader.cxx:155
 TabletReader.cxx:156
 TabletReader.cxx:157
 TabletReader.cxx:158
 TabletReader.cxx:159
 TabletReader.cxx:160
 TabletReader.cxx:161
 TabletReader.cxx:162
 TabletReader.cxx:163
 TabletReader.cxx:164
 TabletReader.cxx:165
 TabletReader.cxx:166
 TabletReader.cxx:167
 TabletReader.cxx:168
 TabletReader.cxx:169
 TabletReader.cxx:170
 TabletReader.cxx:171
 TabletReader.cxx:172
 TabletReader.cxx:173
 TabletReader.cxx:174
 TabletReader.cxx:175
 TabletReader.cxx:176
 TabletReader.cxx:177
 TabletReader.cxx:178
 TabletReader.cxx:179
 TabletReader.cxx:180
 TabletReader.cxx:181
 TabletReader.cxx:182
 TabletReader.cxx:183
 TabletReader.cxx:184
 TabletReader.cxx:185
 TabletReader.cxx:186
 TabletReader.cxx:187
 TabletReader.cxx:188
 TabletReader.cxx:189
 TabletReader.cxx:190
 TabletReader.cxx:191
 TabletReader.cxx:192
 TabletReader.cxx:193
 TabletReader.cxx:194
 TabletReader.cxx:195
 TabletReader.cxx:196
 TabletReader.cxx:197
 TabletReader.cxx:198
 TabletReader.cxx:199
 TabletReader.cxx:200
 TabletReader.cxx:201
 TabletReader.cxx:202
 TabletReader.cxx:203
 TabletReader.cxx:204
 TabletReader.cxx:205
 TabletReader.cxx:206
 TabletReader.cxx:207
 TabletReader.cxx:208
 TabletReader.cxx:209
 TabletReader.cxx:210
 TabletReader.cxx:211
 TabletReader.cxx:212
 TabletReader.cxx:213
 TabletReader.cxx:214
 TabletReader.cxx:215
 TabletReader.cxx:216
 TabletReader.cxx:217
 TabletReader.cxx:218
 TabletReader.cxx:219
 TabletReader.cxx:220
 TabletReader.cxx:221
 TabletReader.cxx:222
 TabletReader.cxx:223
 TabletReader.cxx:224
 TabletReader.cxx:225
 TabletReader.cxx:226
 TabletReader.cxx:227
 TabletReader.cxx:228
 TabletReader.cxx:229
 TabletReader.cxx:230
 TabletReader.cxx:231
 TabletReader.cxx:232
 TabletReader.cxx:233
 TabletReader.cxx:234
 TabletReader.cxx:235
 TabletReader.cxx:236
 TabletReader.cxx:237
 TabletReader.cxx:238
 TabletReader.cxx:239
 TabletReader.cxx:240
 TabletReader.cxx:241
 TabletReader.cxx:242
 TabletReader.cxx:243
 TabletReader.cxx:244
 TabletReader.cxx:245
 TabletReader.cxx:246
 TabletReader.cxx:247
 TabletReader.cxx:248
 TabletReader.cxx:249
 TabletReader.cxx:250
 TabletReader.cxx:251
 TabletReader.cxx:252
 TabletReader.cxx:253
 TabletReader.cxx:254
 TabletReader.cxx:255
 TabletReader.cxx:256
 TabletReader.cxx:257
 TabletReader.cxx:258
 TabletReader.cxx:259
 TabletReader.cxx:260
 TabletReader.cxx:261
 TabletReader.cxx:262
 TabletReader.cxx:263
 TabletReader.cxx:264
 TabletReader.cxx:265
 TabletReader.cxx:266
 TabletReader.cxx:267
 TabletReader.cxx:268
 TabletReader.cxx:269
 TabletReader.cxx:270
 TabletReader.cxx:271
 TabletReader.cxx:272
 TabletReader.cxx:273
 TabletReader.cxx:274
 TabletReader.cxx:275
 TabletReader.cxx:276
 TabletReader.cxx:277
 TabletReader.cxx:278
 TabletReader.cxx:279
 TabletReader.cxx:280
 TabletReader.cxx:281
 TabletReader.cxx:282
 TabletReader.cxx:283
 TabletReader.cxx:284
 TabletReader.cxx:285
 TabletReader.cxx:286
 TabletReader.cxx:287
 TabletReader.cxx:288
 TabletReader.cxx:289
 TabletReader.cxx:290
 TabletReader.cxx:291
 TabletReader.cxx:292
 TabletReader.cxx:293
 TabletReader.cxx:294
 TabletReader.cxx:295
 TabletReader.cxx:296
 TabletReader.cxx:297
 TabletReader.cxx:298
 TabletReader.cxx:299
 TabletReader.cxx:300
 TabletReader.cxx:301
 TabletReader.cxx:302
 TabletReader.cxx:303
 TabletReader.cxx:304
 TabletReader.cxx:305
 TabletReader.cxx:306
 TabletReader.cxx:307
 TabletReader.cxx:308
 TabletReader.cxx:309
 TabletReader.cxx:310
 TabletReader.cxx:311
 TabletReader.cxx:312
 TabletReader.cxx:313
 TabletReader.cxx:314
 TabletReader.cxx:315
 TabletReader.cxx:316
 TabletReader.cxx:317
 TabletReader.cxx:318
 TabletReader.cxx:319
 TabletReader.cxx:320
 TabletReader.cxx:321
 TabletReader.cxx:322
 TabletReader.cxx:323
 TabletReader.cxx:324
 TabletReader.cxx:325
 TabletReader.cxx:326
 TabletReader.cxx:327
 TabletReader.cxx:328
 TabletReader.cxx:329
 TabletReader.cxx:330
 TabletReader.cxx:331
 TabletReader.cxx:332
 TabletReader.cxx:333
 TabletReader.cxx:334
 TabletReader.cxx:335
 TabletReader.cxx:336
 TabletReader.cxx:337
 TabletReader.cxx:338
 TabletReader.cxx:339
 TabletReader.cxx:340
 TabletReader.cxx:341
 TabletReader.cxx:342
 TabletReader.cxx:343
 TabletReader.cxx:344
 TabletReader.cxx:345
 TabletReader.cxx:346
 TabletReader.cxx:347
 TabletReader.cxx:348
 TabletReader.cxx:349
 TabletReader.cxx:350
 TabletReader.cxx:351
 TabletReader.cxx:352
 TabletReader.cxx:353
 TabletReader.cxx:354
 TabletReader.cxx:355
 TabletReader.cxx:356
 TabletReader.cxx:357
 TabletReader.cxx:358
 TabletReader.cxx:359
 TabletReader.cxx:360
 TabletReader.cxx:361
 TabletReader.cxx:362
 TabletReader.cxx:363
 TabletReader.cxx:364
 TabletReader.cxx:365
 TabletReader.cxx:366
 TabletReader.cxx:367
 TabletReader.cxx:368
 TabletReader.cxx:369
 TabletReader.cxx:370
 TabletReader.cxx:371
 TabletReader.cxx:372
 TabletReader.cxx:373
 TabletReader.cxx:374
 TabletReader.cxx:375
 TabletReader.cxx:376
 TabletReader.cxx:377
 TabletReader.cxx:378
 TabletReader.cxx:379
 TabletReader.cxx:380
 TabletReader.cxx:381
 TabletReader.cxx:382
 TabletReader.cxx:383
 TabletReader.cxx:384
 TabletReader.cxx:385
 TabletReader.cxx:386
 TabletReader.cxx:387
 TabletReader.cxx:388
 TabletReader.cxx:389
 TabletReader.cxx:390
 TabletReader.cxx:391
 TabletReader.cxx:392
 TabletReader.cxx:393
 TabletReader.cxx:394
 TabletReader.cxx:395
 TabletReader.cxx:396
 TabletReader.cxx:397
 TabletReader.cxx:398
 TabletReader.cxx:399
 TabletReader.cxx:400
 TabletReader.cxx:401
 TabletReader.cxx:402
 TabletReader.cxx:403
 TabletReader.cxx:404
 TabletReader.cxx:405
 TabletReader.cxx:406
 TabletReader.cxx:407
 TabletReader.cxx:408
 TabletReader.cxx:409
 TabletReader.cxx:410
 TabletReader.cxx:411
 TabletReader.cxx:412
 TabletReader.cxx:413
 TabletReader.cxx:414
 TabletReader.cxx:415
 TabletReader.cxx:416
 TabletReader.cxx:417
 TabletReader.cxx:418
 TabletReader.cxx:419
 TabletReader.cxx:420
 TabletReader.cxx:421
 TabletReader.cxx:422
 TabletReader.cxx:423
 TabletReader.cxx:424
 TabletReader.cxx:425
 TabletReader.cxx:426