* Reworked debugging feature, it's now much more simple to use, copied

from the input_server implementation to create a log file.
* DeviceReader already provided the data byte count, since this is a USB
  only Wacom driver, we can simply use the max_packet_size from the endpoint
  descriptor. Changed TabledDevice accordingly to use the already existing
  DeviceReader::MaxPacketSize().
* Reworked DeviceReader::ReadData(). Renamed variables for clarity and
  removed the restriction to read exactly the requested ammount of bytes,
  reading more than the "header" (which contains vendor id, product id
  and max packet size) is already considered a successful read.
* Refactored TabledDevice::poll_usb_device().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24018 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-02-19 16:03:15 +00:00
parent b4c82732fb
commit d4122828d4
6 changed files with 164 additions and 197 deletions
@@ -9,6 +9,11 @@
#include <File.h> #include <File.h>
#include "MasterServerDevice.h"
static ssize_t kHeaderSize = 8;
// constructor // constructor
DeviceReader::DeviceReader() DeviceReader::DeviceReader()
@@ -39,9 +44,9 @@ DeviceReader::SetTo(const char* path)
if (ret >= B_OK) { if (ret >= B_OK) {
// read 8 bytes from the file and initialize // read 8 bytes from the file and initialize
// the rest of the object variables // the rest of the object variables
uint8 buffer[8]; uint8 buffer[kHeaderSize];
ret = fDeviceFile->Read(buffer, 8); ret = fDeviceFile->Read(buffer, kHeaderSize);
if (ret == 8) { if (ret == kHeaderSize) {
ret = B_OK; ret = B_OK;
uint16* ids = (uint16*)buffer; uint16* ids = (uint16*)buffer;
fVendorID = ids[0]; fVendorID = ids[0];
@@ -99,33 +104,43 @@ DeviceReader::MaxPacketSize() const
} }
// ReadData // ReadData
status_t ssize_t
DeviceReader::ReadData(uint8* data, size_t size) const DeviceReader::ReadData(uint8* data, const size_t size) const
{ {
status_t ret = B_NO_INIT; if (!fDeviceFile || fMaxPackedSize <= 0 || fMaxPackedSize > 128)
if (fDeviceFile) { return B_NO_INIT;
ret = fDeviceFile->InitCheck(); status_t ret = fDeviceFile->InitCheck();
if (ret >= B_OK) { if (ret < B_OK)
uint8* buffer = new uint8[fMaxPackedSize + 8]; return (ssize_t)ret;
ret = fDeviceFile->Read(buffer, fMaxPackedSize + 8);
if (ret == (ssize_t)(fMaxPackedSize + 8)) { ssize_t requested = fMaxPackedSize + kHeaderSize;
// make sure we don't copy too many bytes uint8 buffer[requested];
size_t length = min_c(size, fMaxPackedSize); ssize_t read = fDeviceFile->Read(buffer, requested);
memcpy(data, buffer + 8, length); if (read > kHeaderSize) {
// zero out any remaining bytes // make sure we don't copy too many bytes
if (size > fMaxPackedSize) size_t bytesToCopy = min_c(size, read - (size_t)kHeaderSize);
memset(data + length, 0, size - fMaxPackedSize); PRINT(("requested: %ld, read: %ld, user wants: %lu, copy bytes: %ld\n",
// operation could be considered successful requested, read, size, bytesToCopy));
ret = length; memcpy(data, buffer + kHeaderSize, bytesToCopy);
} else if (ret == 8 || ret == B_TIMED_OUT) { // zero out any remaining bytes
// it's ok if the operation timed out if (size > bytesToCopy)
memset(data, 0, size); memset(data + bytesToCopy, 0, size - bytesToCopy);
ret = B_OK; // operation could be considered successful
} // read = bytesToCopy;
delete[] buffer; // if (read != (ssize_t)size)
} // PRINT(("user wanted: %lu, returning: %ld\n", size, read));
read = size;
// pretend we could read as many bytes as requested
} else if (read == kHeaderSize || (status_t)read == B_TIMED_OUT) {
// it's ok if the operation timed out
memset(data, 0, size);
read = (size_t)B_OK;
} else {
PRINT(("requested: %ld, read: %ld, user wants: %lu\n",
requested, read, size));
} }
return ret;
return read;
} }
// _Unset // _Unset
@@ -45,8 +45,10 @@ class DeviceReader {
size_t MaxPacketSize() const; size_t MaxPacketSize() const;
// trigger an interrupt transfer and write the data in the buffer // trigger an interrupt transfer and write the data in the buffer
// it should be save to call this function with size != MaxPacketSize // it should be save to call this function with
status_t ReadData(uint8* data, size_t size) const; // size != MaxPacketSize, remaining bytes will be zero'd out
ssize_t ReadData(uint8* data,
const size_t size) const;
protected: protected:
void _Unset(); void _Unset();
@@ -25,15 +25,9 @@
#define DEFAULT_CLICK_SPEED 250000 #define DEFAULT_CLICK_SPEED 250000
#define DEBUG 0
static const char* kWatchFolder = "input/wacom/usb"; static const char* kWatchFolder = "input/wacom/usb";
static const char* kDeviceFolder = "/dev/input/wacom/usb"; static const char* kDeviceFolder = "/dev/input/wacom/usb";
#if DEBUG
static const char* kLogFilePath = "/tmp/wacom.log";
#endif
//static const char* kPS2MouseThreadName = "PS/2 Mouse"; //static const char* kPS2MouseThreadName = "PS/2 Mouse";
// instantiate_input_device // instantiate_input_device
@@ -50,7 +44,6 @@ MasterServerDevice::MasterServerDevice()
: BInputServerDevice(), : BInputServerDevice(),
fDevices(1), fDevices(1),
fActive(false), fActive(false),
fLogString(""),
fDblClickSpeed(DEFAULT_CLICK_SPEED), fDblClickSpeed(DEFAULT_CLICK_SPEED),
fPS2DisablerThread(B_ERROR), fPS2DisablerThread(B_ERROR),
fDeviceLock("device list lock") fDeviceLock("device list lock")
@@ -96,10 +89,7 @@ MasterServerDevice::SystemShuttingDown()
_StopAll(); _StopAll();
#if DEBUG PRINT(("---------------------------------\n\n"));
fLogString << "---------------------------------\n\n";
DumpLogString(kLogFilePath);
#endif
return (BInputServerDevice::SystemShuttingDown()); return (BInputServerDevice::SystemShuttingDown());
} }
@@ -170,30 +160,6 @@ MasterServerDevice::Control(const char* device, void* cookie, uint32 code, BMess
return B_OK; return B_OK;
} }
// LogDataBytes
void
MasterServerDevice::LogDataBytes(uchar* data, int bytes)
{
for (int32 i = 0; i < bytes; i += 2)
fLogString << (uint32)data[i] << " " << (uint32)data[i + 1] << " ";
fLogString << "\n";
}
// DumpLogString
void
MasterServerDevice::DumpLogString(const char* path)
{
if (fLogString.Length() > 0) {
BFile logFile(path, B_WRITE_ONLY | B_CREATE_FILE);
if (logFile.InitCheck() >= B_OK) {
logFile.Seek(0, SEEK_END);
logFile.Write(fLogString.String(), fLogString.Length());
fLogString.SetTo("");
}
logFile.Unset();
}
}
// #pragma mark - // #pragma mark -
// _SearchDevices // _SearchDevices
@@ -208,12 +174,8 @@ MasterServerDevice::_SearchDevices()
// entry of that device still exists // entry of that device still exists
entry_ref ref; entry_ref ref;
while (dir.GetNextRef(&ref) >= B_OK) { while (dir.GetNextRef(&ref) >= B_OK) {
PRINT(("examining devfs entry '%s'\n", ref.name));
// don't add the control device // don't add the control device
#if DEBUG
fLogString << "examining devfs entry '" << ref.name << "'\n";
#endif
if (strcmp(ref.name, "control") != 0) { if (strcmp(ref.name, "control") != 0) {
BPath path(&ref); BPath path(&ref);
if (path.InitCheck() >= B_OK) { if (path.InitCheck() >= B_OK) {
@@ -221,24 +183,11 @@ MasterServerDevice::_SearchDevices()
_AddDevice(path.Path()); _AddDevice(path.Path());
} }
} }
#if DEBUG
fLogString << "\n";
#endif
} }
} else { } else
PRINT(("folder '%s' not found\n", kDeviceFolder));
#if DEBUG PRINT(("done examing devfs\n"));
fLogString << "folder '" << kDeviceFolder <<"' not found\n";
#endif
}
#if DEBUG
fLogString << "done examing devfs\n";
DumpLogString("kLogFilePath");
#endif
_UnlockDevices(); _UnlockDevices();
} }
} }
@@ -265,27 +214,17 @@ MasterServerDevice::_AddDevice(const char* path)
// add it to our list // add it to our list
if (device && device->InitCheck() >= B_OK if (device && device->InitCheck() >= B_OK
&& fDevices.AddItem((void*)device)) { && fDevices.AddItem((void*)device)) {
PRINT(("pointing device added (%s)\n", path));
#if DEBUG
fLogString << "pointing device added (" << path << ")\n";
// DumpLogString("kLogFilePath");
#endif
// start device polling only if we're started // start device polling only if we're started
if (fActive) if (fActive)
device->Start(); device->Start();
} else { } else {
#if DEBUG PRINT(("pointing device not added (%s)\n", path));
fLogString << "pointing device not added (" << path << ")\n"; if (device) {
if (device) { PRINT((" vendor: %0*x, product: %0*x\n", 4, device->VendorID(),
char temp[256]; 4, device->ProductID()));
sprintf(temp, " vendor: %0*x, product: %0*x\n", 4, device->VendorID(), }
4, device->ProductID());
fLogString << temp;
}
// DumpLogString("kLogFilePath");
#endif
delete device; delete device;
} }
@@ -348,9 +287,7 @@ MasterServerDevice::_HandleNodeMonitor(BMessage* message)
// remove the device if the devfs entry was not found // remove the device if the devfs entry was not found
if (!found) { if (!found) {
#if DEBUG PRINT(("removing device '%s'\n", pointingDevice->DevicePath()));
fLogString << "removing device '" << pointingDevice->DevicePath() << "'\n";
#endif
if (_LockDevices()) { if (_LockDevices()) {
if (fDevices.RemoveItem((void*)pointingDevice)) if (fDevices.RemoveItem((void*)pointingDevice))
@@ -5,6 +5,8 @@
#ifndef MASTER_SERVER_DEVICE_H #ifndef MASTER_SERVER_DEVICE_H
#define MASTER_SERVER_DEVICE_H #define MASTER_SERVER_DEVICE_H
#include <stdio.h>
#include <add-ons/input_server/InputServerDevice.h> #include <add-ons/input_server/InputServerDevice.h>
#include <List.h> #include <List.h>
#include <Locker.h> #include <Locker.h>
@@ -35,12 +37,6 @@ class MasterServerDevice : public BInputServerDevice {
const float* AccelerationTable() const const float* AccelerationTable() const
{ return fAccelerationTable; } { return fAccelerationTable; }
// debugging
inline BString& LogString()
{ return fLogString; }
void LogDataBytes(uchar* data, int bytes);
void DumpLogString(const char* path);
private: private:
void _SearchDevices(); void _SearchDevices();
@@ -63,9 +59,6 @@ private:
BList fDevices; BList fDevices;
volatile bool fActive; volatile bool fActive;
// debugging
BString fLogString;
// global stuff for all mice objects // global stuff for all mice objects
int32 fSpeed; int32 fSpeed;
int32 fAcceleration; int32 fAcceleration;
@@ -77,4 +70,25 @@ private:
BLocker fDeviceLock; BLocker fDeviceLock;
}; };
#ifndef DEBUG
# define DEBUG 0
#endif
#if DEBUG
# undef PRINT
inline void _iprint(const char* fmt, ...) {
FILE* log = fopen("/var/log/wacom.log", "a");
va_list ap;
va_start(ap, fmt);
vfprintf(log, fmt, ap);
va_end(ap);
fflush(log);
fclose(log);
}
# define PRINT(x) _iprint x
#else
# define PRINT(x)
#endif
#endif // MASTER_SERVER_DEVICE_H #endif // MASTER_SERVER_DEVICE_H
@@ -31,8 +31,6 @@
#define JITTER_Y .0007 #define JITTER_Y .0007
#define ACCELERATION_KICK_IN 2.3 #define ACCELERATION_KICK_IN 2.3
#define DEBUG 0
// constructor // constructor
TabletDevice::TabletDevice(MasterServerDevice* parent, DeviceReader* reader) TabletDevice::TabletDevice(MasterServerDevice* parent, DeviceReader* reader)
: PointingDevice(parent, reader), : PointingDevice(parent, reader),
@@ -40,7 +38,6 @@ TabletDevice::TabletDevice(MasterServerDevice* parent, DeviceReader* reader)
fDeviceMode(DEVICE_UNKOWN), fDeviceMode(DEVICE_UNKOWN),
fMaxX(1.0), fMaxX(1.0),
fMaxY(1.0), fMaxY(1.0),
fDataBytes(10),
fPosX(0.5), fPosX(0.5),
fPosY(0.5), fPosY(0.5),
fFakeMouseX(0.5), fFakeMouseX(0.5),
@@ -69,7 +66,7 @@ TabletDevice::InitCheck()
{ {
status_t status = PointingDevice::InitCheck(); status_t status = PointingDevice::InitCheck();
if (status >= B_OK) if (status >= B_OK)
status = DetectDevice(fReader->ProductID()); status = DetectDevice(fReader);
return status; return status;
} }
@@ -110,35 +107,35 @@ TabletDevice::Stop()
// DetectDevice // DetectDevice
status_t status_t
TabletDevice::DetectDevice(uint16 product) TabletDevice::DetectDevice(const DeviceReader* reader)
{ {
status_t status = B_OK; status_t status = B_OK;
switch (product) { switch (reader->ProductID()) {
case 0x00: case 0x00:
SetDevice(5040.0, 3780.0, DEVICE_PENPARTNER, 7); SetDevice(5040.0, 3780.0, DEVICE_PENPARTNER);
break; break;
case 0x03: case 0x03:
SetDevice(2048.0, 15360.0, DEVICE_PL500, 8); SetDevice(2048.0, 15360.0, DEVICE_PL500);
break; break;
case 0x10: case 0x10:
case 0x11: case 0x11:
case 0x13: case 0x13:
SetDevice(10206.0, 7422.0, DEVICE_GRAPHIRE, 8); SetDevice(10206.0, 7422.0, DEVICE_GRAPHIRE);
break; break;
case 0x12: // Graphire 3 4x5 case 0x12: // Graphire 3 4x5
SetDevice(13918.0, 10206.0, DEVICE_GRAPHIRE, 8); SetDevice(13918.0, 10206.0, DEVICE_GRAPHIRE);
break; break;
case 0x14: // Graphire 3 6x8 case 0x14: // Graphire 3 6x8
SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE, 8); SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE);
break; break;
case 0x15: // Graphire 4 4x5 (tested) case 0x15: // Graphire 4 4x5 (tested)
SetDevice(10208.0, 7024.0, DEVICE_GRAPHIRE, 8); SetDevice(10208.0, 7024.0, DEVICE_GRAPHIRE);
break; break;
case 0x16: // Graphire 4 6x8 (tested) case 0x16: // Graphire 4 6x8 (tested)
SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE, 8); SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE);
break; break;
case 0x20: case 0x20:
SetDevice(12700.0, 10600.0); SetDevice(12700.0, 10600.0, DEVICE_INTUOS);
break; break;
case 0x21: case 0x21:
SetDevice(20320.0, 16240.0); SetDevice(20320.0, 16240.0);
@@ -153,25 +150,25 @@ TabletDevice::DetectDevice(uint16 product)
SetDevice(45720.0, 31680.0); SetDevice(45720.0, 31680.0);
break; break;
case 0x30: case 0x30:
SetDevice(5408.0, 4056.0, DEVICE_PL500, 8); SetDevice(5408.0, 4056.0, DEVICE_PL500);
break; break;
case 0x31: case 0x31:
SetDevice(6144.0, 4608.0, DEVICE_PL500, 8); SetDevice(6144.0, 4608.0, DEVICE_PL500);
break; break;
case 0x32: case 0x32:
SetDevice(6126.0, 4604.0, DEVICE_PL500, 8); SetDevice(6126.0, 4604.0, DEVICE_PL500);
break; break;
case 0x33: case 0x33:
SetDevice(6260.0, 5016.0, DEVICE_PL500, 8); SetDevice(6260.0, 5016.0, DEVICE_PL500);
break; break;
case 0x34: case 0x34:
SetDevice(6144.0, 4608.0, DEVICE_PL500, 8); SetDevice(6144.0, 4608.0, DEVICE_PL500);
break; break;
case 0x35: case 0x35:
SetDevice(7220.0, 5780.0, DEVICE_PL500, 8); SetDevice(7220.0, 5780.0, DEVICE_PL500);
break; break;
case 0x3F: case 0x3F:
SetDevice(87200.0, 65600.0, DEVICE_CINTIQ, 10); SetDevice(87200.0, 65600.0, DEVICE_CINTIQ);
break; break;
case 0x41: case 0x41:
SetDevice(12700.0, 10600.0); SetDevice(12700.0, 10600.0);
@@ -192,30 +189,30 @@ TabletDevice::DetectDevice(uint16 product)
SetDevice(20320.0, 16240.0); SetDevice(20320.0, 16240.0);
break; break;
case 0x60: case 0x60:
SetDevice(5104.0, 3712.0, DEVICE_GRAPHIRE, 8); SetDevice(5104.0, 3712.0, DEVICE_GRAPHIRE);
break; break;
case 0x61: // PenStation case 0x61: // PenStation
// SetDevice(3403.0, 2475.0, DEVICE_GRAPHIRE, 8); // this version was untested // SetDevice(3403.0, 2475.0, DEVICE_GRAPHIRE); // this version was untested
SetDevice(3248.0, 2320.0, DEVICE_PENSTATION, 8); // this version came from "beer" SetDevice(3248.0, 2320.0, DEVICE_PENSTATION); // this version came from "beer"
break; break;
case 0x62: // Volito case 0x62: // Volito
SetDevice(5040.0, 3712.0, DEVICE_VOLITO, 8); SetDevice(5040.0, 3712.0, DEVICE_VOLITO);
break; break;
case 0x64: // PenPartner.1 case 0x64: // PenPartner.1
// SetDevice(3450.0, 2100.0, DEVICE_PENSTATION, 8); // SetDevice(3450.0, 2100.0, DEVICE_PENSTATION);
SetDevice(3248.0, 2320.0, DEVICE_PENSTATION, 8); SetDevice(3248.0, 2320.0, DEVICE_PENSTATION);
break; break;
case 0xB0: case 0xB0:
SetDevice(25400.0, 20320.0, DEVICE_INTUOS3, 10); SetDevice(25400.0, 20320.0, DEVICE_INTUOS3);
break; break;
case 0xB1: case 0xB1:
// tested: // tested:
SetDevice(20320.0, 15230.0, DEVICE_INTUOS3, 10); SetDevice(20320.0, 15230.0, DEVICE_INTUOS3);
// Frans: // Frans:
// SetDevice(40640.0, 30480.0, DEVICE_INTUOS3, 10); // SetDevice(40640.0, 30480.0, DEVICE_INTUOS3);
break; break;
case 0xB2: case 0xB2:
SetDevice(60960.0, 45720.0, DEVICE_INTUOS3, 10); SetDevice(60960.0, 45720.0, DEVICE_INTUOS3);
break; break;
default: default:
status = B_BAD_VALUE; status = B_BAD_VALUE;
@@ -226,19 +223,18 @@ TabletDevice::DetectDevice(uint16 product)
// SetDevice // SetDevice
void void
TabletDevice::SetDevice(float maxX, float maxY, uint32 mode, int dataBytes) TabletDevice::SetDevice(float maxX, float maxY, uint32 mode)
{ {
fDeviceMode = mode; fDeviceMode = mode;
fMaxX = maxX; fMaxX = maxX;
fMaxY = maxY; fMaxY = maxY;
fDataBytes = dataBytes;
fJitterX = JITTER_X; fJitterX = JITTER_X;
fJitterY = JITTER_Y; fJitterY = JITTER_Y;
} }
// ReadData // ReadData
void void
TabletDevice::ReadData(uchar* data, bool& hasContact, uint32& mode, TabletDevice::ReadData(const uchar* data, bool& hasContact, uint32& mode,
uint32& buttons, float& x, float& y, float& pressure, uint32& buttons, float& x, float& y, float& pressure,
int32& clicks, int32& eraser, float& wheelX, float& wheelY, int32& clicks, int32& eraser, float& wheelX, float& wheelY,
float& tiltX, float& tiltY) const float& tiltX, float& tiltY) const
@@ -513,7 +509,9 @@ event->AddFloat("tablet y", tabletY);
} else if (what == B_MOUSE_UP) } else if (what == B_MOUSE_UP)
event->AddInt32("clicks", 0); event->AddInt32("clicks", 0);
fParent->EnqueueMessage(event); status_t ret = fParent->EnqueueMessage(event);
if (ret < B_OK)
PRINT(("EnqueueMessage(): %s\n", strerror(ret)));
// apply values to members // apply values to members
fPosX = x; fPosX = x;
@@ -555,54 +553,59 @@ TabletDevice::poll_usb_device(void* arg)
TabletDevice* tabletDevice = (TabletDevice*)arg; TabletDevice* tabletDevice = (TabletDevice*)arg;
DeviceReader* reader = tabletDevice->fReader; DeviceReader* reader = tabletDevice->fReader;
if (reader && reader->InitCheck() >= B_OK) { if (!reader || reader->InitCheck() < B_OK)
return B_BAD_VALUE;
int dataBytes = tabletDevice->DataBytes(); int dataBytes = reader->MaxPacketSize();
uchar* data = new uchar[max_c(12, dataBytes)]; if (dataBytes > 128)
return B_BAD_VALUE;
while (tabletDevice->IsActive()) { uchar data[max_c(12, dataBytes)];
status_t ret = reader->ReadData(data, dataBytes); while (tabletDevice->IsActive()) {
if (ret == dataBytes) { status_t ret = reader->ReadData(data, dataBytes);
// data we read from the wacom device
uint32 mode; if (ret == dataBytes) {
bool hasContact = false; // data we read from the wacom device
uint32 buttons = 0; uint32 mode;
float x = 0.0; bool hasContact = false;
float y = 0.0; uint32 buttons = 0;
float pressure = 0.0; float x = 0.0;
int32 clicks = 0; float y = 0.0;
int32 eraser = 0; float pressure = 0.0;
float wheelX = 0.0; int32 clicks = 0;
float wheelY = 0.0; int32 eraser = 0;
float tiltX = 0.0; float wheelX = 0.0;
float tiltY = 0.0; float wheelY = 0.0;
// let the device extract all information from the data float tiltX = 0.0;
tabletDevice->ReadData(data, hasContact, mode, buttons, float tiltY = 0.0;
x, y, pressure, clicks, eraser, // let the device extract all information from the data
wheelX, wheelY, tiltX, tiltY); tabletDevice->ReadData(data, hasContact, mode, buttons,
if (hasContact) { x, y, pressure, clicks, eraser,
// apply the changes to the device wheelX, wheelY, tiltX, tiltY);
tabletDevice->SetStatus(mode, buttons, x, y, pressure, if (hasContact) {
clicks, modifiers(), eraser, // apply the changes to the device
wheelX, wheelY, tiltX, tiltY, data); tabletDevice->SetStatus(mode, buttons, x, y, pressure,
} clicks, modifiers(), eraser,
tabletDevice->SetContact(hasContact); wheelX, wheelY, tiltX, tiltY, data);
} else { } else
if (ret < B_OK) { PRINT(("device has no contact\n"));
if (ret == B_TIMED_OUT) tabletDevice->SetContact(hasContact);
snooze(SNOOZE_AMOUNT); } else {
else if (ret == B_INTERRUPTED) PRINT(("failed to read %ld bytes, read: %ld or %s\n",
snooze(SNOOZE_AMOUNT); dataBytes, ret, strerror(ret)));
else {
delete[] data; if (ret < B_OK) {
return ret; if (ret == B_TIMED_OUT)
} snooze(SNOOZE_AMOUNT);
else if (ret == B_INTERRUPTED)
snooze(SNOOZE_AMOUNT);
else {
return ret;
} }
} }
} }
delete[] data;
} }
return B_OK; return B_OK;
@@ -25,16 +25,12 @@ class TabletDevice : public PointingDevice {
virtual status_t Start(); virtual status_t Start();
virtual status_t Stop(); virtual status_t Stop();
inline int DataBytes() const status_t DetectDevice(const DeviceReader* reader);
{ return fDataBytes; }
status_t DetectDevice(uint16 productID);
void SetDevice(float maxX, float maxY, void SetDevice(float maxX, float maxY,
uint32 mode = DEVICE_INTUOS, uint32 mode = DEVICE_INTUOS);
int dataBytes = 10);
void ReadData(uchar* data, void ReadData(const uchar* data,
bool& hasContact, bool& hasContact,
uint32& mode, uint32& mode,
uint32& buttons, uint32& buttons,