* 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

View File

@ -9,6 +9,11 @@
#include <File.h>
#include "MasterServerDevice.h"
static ssize_t kHeaderSize = 8;
// constructor
DeviceReader::DeviceReader()
@ -39,9 +44,9 @@ DeviceReader::SetTo(const char* path)
if (ret >= B_OK) {
// read 8 bytes from the file and initialize
// the rest of the object variables
uint8 buffer[8];
ret = fDeviceFile->Read(buffer, 8);
if (ret == 8) {
uint8 buffer[kHeaderSize];
ret = fDeviceFile->Read(buffer, kHeaderSize);
if (ret == kHeaderSize) {
ret = B_OK;
uint16* ids = (uint16*)buffer;
fVendorID = ids[0];
@ -99,33 +104,43 @@ DeviceReader::MaxPacketSize() const
}
// ReadData
status_t
DeviceReader::ReadData(uint8* data, size_t size) const
ssize_t
DeviceReader::ReadData(uint8* data, const size_t size) const
{
status_t ret = B_NO_INIT;
if (fDeviceFile) {
ret = fDeviceFile->InitCheck();
if (ret >= B_OK) {
uint8* buffer = new uint8[fMaxPackedSize + 8];
ret = fDeviceFile->Read(buffer, fMaxPackedSize + 8);
if (ret == (ssize_t)(fMaxPackedSize + 8)) {
// make sure we don't copy too many bytes
size_t length = min_c(size, fMaxPackedSize);
memcpy(data, buffer + 8, length);
// zero out any remaining bytes
if (size > fMaxPackedSize)
memset(data + length, 0, size - fMaxPackedSize);
// operation could be considered successful
ret = length;
} else if (ret == 8 || ret == B_TIMED_OUT) {
// it's ok if the operation timed out
memset(data, 0, size);
ret = B_OK;
}
delete[] buffer;
}
if (!fDeviceFile || fMaxPackedSize <= 0 || fMaxPackedSize > 128)
return B_NO_INIT;
status_t ret = fDeviceFile->InitCheck();
if (ret < B_OK)
return (ssize_t)ret;
ssize_t requested = fMaxPackedSize + kHeaderSize;
uint8 buffer[requested];
ssize_t read = fDeviceFile->Read(buffer, requested);
if (read > kHeaderSize) {
// make sure we don't copy too many bytes
size_t bytesToCopy = min_c(size, read - (size_t)kHeaderSize);
PRINT(("requested: %ld, read: %ld, user wants: %lu, copy bytes: %ld\n",
requested, read, size, bytesToCopy));
memcpy(data, buffer + kHeaderSize, bytesToCopy);
// zero out any remaining bytes
if (size > bytesToCopy)
memset(data + bytesToCopy, 0, size - bytesToCopy);
// operation could be considered successful
// read = bytesToCopy;
// 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

View File

@ -45,8 +45,10 @@ class DeviceReader {
size_t MaxPacketSize() const;
// trigger an interrupt transfer and write the data in the buffer
// it should be save to call this function with size != MaxPacketSize
status_t ReadData(uint8* data, size_t size) const;
// it should be save to call this function with
// size != MaxPacketSize, remaining bytes will be zero'd out
ssize_t ReadData(uint8* data,
const size_t size) const;
protected:
void _Unset();

View File

@ -25,15 +25,9 @@
#define DEFAULT_CLICK_SPEED 250000
#define DEBUG 0
static const char* kWatchFolder = "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";
// instantiate_input_device
@ -50,7 +44,6 @@ MasterServerDevice::MasterServerDevice()
: BInputServerDevice(),
fDevices(1),
fActive(false),
fLogString(""),
fDblClickSpeed(DEFAULT_CLICK_SPEED),
fPS2DisablerThread(B_ERROR),
fDeviceLock("device list lock")
@ -96,10 +89,7 @@ MasterServerDevice::SystemShuttingDown()
_StopAll();
#if DEBUG
fLogString << "---------------------------------\n\n";
DumpLogString(kLogFilePath);
#endif
PRINT(("---------------------------------\n\n"));
return (BInputServerDevice::SystemShuttingDown());
}
@ -170,30 +160,6 @@ MasterServerDevice::Control(const char* device, void* cookie, uint32 code, BMess
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 -
// _SearchDevices
@ -208,12 +174,8 @@ MasterServerDevice::_SearchDevices()
// entry of that device still exists
entry_ref ref;
while (dir.GetNextRef(&ref) >= B_OK) {
PRINT(("examining devfs entry '%s'\n", ref.name));
// don't add the control device
#if DEBUG
fLogString << "examining devfs entry '" << ref.name << "'\n";
#endif
if (strcmp(ref.name, "control") != 0) {
BPath path(&ref);
if (path.InitCheck() >= B_OK) {
@ -221,24 +183,11 @@ MasterServerDevice::_SearchDevices()
_AddDevice(path.Path());
}
}
#if DEBUG
fLogString << "\n";
#endif
}
} else {
} else
PRINT(("folder '%s' not found\n", kDeviceFolder));
#if DEBUG
fLogString << "folder '" << kDeviceFolder <<"' not found\n";
#endif
}
#if DEBUG
fLogString << "done examing devfs\n";
DumpLogString("kLogFilePath");
#endif
PRINT(("done examing devfs\n"));
_UnlockDevices();
}
}
@ -265,27 +214,17 @@ MasterServerDevice::_AddDevice(const char* path)
// add it to our list
if (device && device->InitCheck() >= B_OK
&& fDevices.AddItem((void*)device)) {
#if DEBUG
fLogString << "pointing device added (" << path << ")\n";
// DumpLogString("kLogFilePath");
#endif
PRINT(("pointing device added (%s)\n", path));
// start device polling only if we're started
if (fActive)
device->Start();
} else {
#if DEBUG
fLogString << "pointing device not added (" << path << ")\n";
if (device) {
char temp[256];
sprintf(temp, " vendor: %0*x, product: %0*x\n", 4, device->VendorID(),
4, device->ProductID());
fLogString << temp;
}
// DumpLogString("kLogFilePath");
#endif
PRINT(("pointing device not added (%s)\n", path));
if (device) {
PRINT((" vendor: %0*x, product: %0*x\n", 4, device->VendorID(),
4, device->ProductID()));
}
delete device;
}
@ -348,9 +287,7 @@ MasterServerDevice::_HandleNodeMonitor(BMessage* message)
// remove the device if the devfs entry was not found
if (!found) {
#if DEBUG
fLogString << "removing device '" << pointingDevice->DevicePath() << "'\n";
#endif
PRINT(("removing device '%s'\n", pointingDevice->DevicePath()));
if (_LockDevices()) {
if (fDevices.RemoveItem((void*)pointingDevice))

View File

@ -5,6 +5,8 @@
#ifndef MASTER_SERVER_DEVICE_H
#define MASTER_SERVER_DEVICE_H
#include <stdio.h>
#include <add-ons/input_server/InputServerDevice.h>
#include <List.h>
#include <Locker.h>
@ -35,12 +37,6 @@ class MasterServerDevice : public BInputServerDevice {
const float* AccelerationTable() const
{ return fAccelerationTable; }
// debugging
inline BString& LogString()
{ return fLogString; }
void LogDataBytes(uchar* data, int bytes);
void DumpLogString(const char* path);
private:
void _SearchDevices();
@ -63,9 +59,6 @@ private:
BList fDevices;
volatile bool fActive;
// debugging
BString fLogString;
// global stuff for all mice objects
int32 fSpeed;
int32 fAcceleration;
@ -77,4 +70,25 @@ private:
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

View File

@ -31,8 +31,6 @@
#define JITTER_Y .0007
#define ACCELERATION_KICK_IN 2.3
#define DEBUG 0
// constructor
TabletDevice::TabletDevice(MasterServerDevice* parent, DeviceReader* reader)
: PointingDevice(parent, reader),
@ -40,7 +38,6 @@ TabletDevice::TabletDevice(MasterServerDevice* parent, DeviceReader* reader)
fDeviceMode(DEVICE_UNKOWN),
fMaxX(1.0),
fMaxY(1.0),
fDataBytes(10),
fPosX(0.5),
fPosY(0.5),
fFakeMouseX(0.5),
@ -69,7 +66,7 @@ TabletDevice::InitCheck()
{
status_t status = PointingDevice::InitCheck();
if (status >= B_OK)
status = DetectDevice(fReader->ProductID());
status = DetectDevice(fReader);
return status;
}
@ -110,35 +107,35 @@ TabletDevice::Stop()
// DetectDevice
status_t
TabletDevice::DetectDevice(uint16 product)
TabletDevice::DetectDevice(const DeviceReader* reader)
{
status_t status = B_OK;
switch (product) {
switch (reader->ProductID()) {
case 0x00:
SetDevice(5040.0, 3780.0, DEVICE_PENPARTNER, 7);
SetDevice(5040.0, 3780.0, DEVICE_PENPARTNER);
break;
case 0x03:
SetDevice(2048.0, 15360.0, DEVICE_PL500, 8);
SetDevice(2048.0, 15360.0, DEVICE_PL500);
break;
case 0x10:
case 0x11:
case 0x13:
SetDevice(10206.0, 7422.0, DEVICE_GRAPHIRE, 8);
SetDevice(10206.0, 7422.0, DEVICE_GRAPHIRE);
break;
case 0x12: // Graphire 3 4x5
SetDevice(13918.0, 10206.0, DEVICE_GRAPHIRE, 8);
SetDevice(13918.0, 10206.0, DEVICE_GRAPHIRE);
break;
case 0x14: // Graphire 3 6x8
SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE, 8);
SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE);
break;
case 0x15: // Graphire 4 4x5 (tested)
SetDevice(10208.0, 7024.0, DEVICE_GRAPHIRE, 8);
SetDevice(10208.0, 7024.0, DEVICE_GRAPHIRE);
break;
case 0x16: // Graphire 4 6x8 (tested)
SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE, 8);
SetDevice(16704.0, 12064.0, DEVICE_GRAPHIRE);
break;
case 0x20:
SetDevice(12700.0, 10600.0);
SetDevice(12700.0, 10600.0, DEVICE_INTUOS);
break;
case 0x21:
SetDevice(20320.0, 16240.0);
@ -153,25 +150,25 @@ TabletDevice::DetectDevice(uint16 product)
SetDevice(45720.0, 31680.0);
break;
case 0x30:
SetDevice(5408.0, 4056.0, DEVICE_PL500, 8);
SetDevice(5408.0, 4056.0, DEVICE_PL500);
break;
case 0x31:
SetDevice(6144.0, 4608.0, DEVICE_PL500, 8);
SetDevice(6144.0, 4608.0, DEVICE_PL500);
break;
case 0x32:
SetDevice(6126.0, 4604.0, DEVICE_PL500, 8);
SetDevice(6126.0, 4604.0, DEVICE_PL500);
break;
case 0x33:
SetDevice(6260.0, 5016.0, DEVICE_PL500, 8);
SetDevice(6260.0, 5016.0, DEVICE_PL500);
break;
case 0x34:
SetDevice(6144.0, 4608.0, DEVICE_PL500, 8);
SetDevice(6144.0, 4608.0, DEVICE_PL500);
break;
case 0x35:
SetDevice(7220.0, 5780.0, DEVICE_PL500, 8);
SetDevice(7220.0, 5780.0, DEVICE_PL500);
break;
case 0x3F:
SetDevice(87200.0, 65600.0, DEVICE_CINTIQ, 10);
SetDevice(87200.0, 65600.0, DEVICE_CINTIQ);
break;
case 0x41:
SetDevice(12700.0, 10600.0);
@ -192,30 +189,30 @@ TabletDevice::DetectDevice(uint16 product)
SetDevice(20320.0, 16240.0);
break;
case 0x60:
SetDevice(5104.0, 3712.0, DEVICE_GRAPHIRE, 8);
SetDevice(5104.0, 3712.0, DEVICE_GRAPHIRE);
break;
case 0x61: // PenStation
// SetDevice(3403.0, 2475.0, DEVICE_GRAPHIRE, 8); // this version was untested
SetDevice(3248.0, 2320.0, DEVICE_PENSTATION, 8); // this version came from "beer"
// SetDevice(3403.0, 2475.0, DEVICE_GRAPHIRE); // this version was untested
SetDevice(3248.0, 2320.0, DEVICE_PENSTATION); // this version came from "beer"
break;
case 0x62: // Volito
SetDevice(5040.0, 3712.0, DEVICE_VOLITO, 8);
SetDevice(5040.0, 3712.0, DEVICE_VOLITO);
break;
case 0x64: // PenPartner.1
// SetDevice(3450.0, 2100.0, DEVICE_PENSTATION, 8);
SetDevice(3248.0, 2320.0, DEVICE_PENSTATION, 8);
// SetDevice(3450.0, 2100.0, DEVICE_PENSTATION);
SetDevice(3248.0, 2320.0, DEVICE_PENSTATION);
break;
case 0xB0:
SetDevice(25400.0, 20320.0, DEVICE_INTUOS3, 10);
SetDevice(25400.0, 20320.0, DEVICE_INTUOS3);
break;
case 0xB1:
// tested:
SetDevice(20320.0, 15230.0, DEVICE_INTUOS3, 10);
SetDevice(20320.0, 15230.0, DEVICE_INTUOS3);
// Frans:
// SetDevice(40640.0, 30480.0, DEVICE_INTUOS3, 10);
// SetDevice(40640.0, 30480.0, DEVICE_INTUOS3);
break;
case 0xB2:
SetDevice(60960.0, 45720.0, DEVICE_INTUOS3, 10);
SetDevice(60960.0, 45720.0, DEVICE_INTUOS3);
break;
default:
status = B_BAD_VALUE;
@ -226,19 +223,18 @@ TabletDevice::DetectDevice(uint16 product)
// SetDevice
void
TabletDevice::SetDevice(float maxX, float maxY, uint32 mode, int dataBytes)
TabletDevice::SetDevice(float maxX, float maxY, uint32 mode)
{
fDeviceMode = mode;
fMaxX = maxX;
fMaxY = maxY;
fDataBytes = dataBytes;
fJitterX = JITTER_X;
fJitterY = JITTER_Y;
}
// ReadData
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,
int32& clicks, int32& eraser, float& wheelX, float& wheelY,
float& tiltX, float& tiltY) const
@ -513,7 +509,9 @@ event->AddFloat("tablet y", tabletY);
} else if (what == B_MOUSE_UP)
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
fPosX = x;
@ -555,54 +553,59 @@ TabletDevice::poll_usb_device(void* arg)
TabletDevice* tabletDevice = (TabletDevice*)arg;
DeviceReader* reader = tabletDevice->fReader;
if (reader && reader->InitCheck() >= B_OK) {
if (!reader || reader->InitCheck() < B_OK)
return B_BAD_VALUE;
int dataBytes = tabletDevice->DataBytes();
uchar* data = new uchar[max_c(12, dataBytes)];
int dataBytes = reader->MaxPacketSize();
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) {
// data we read from the wacom device
uint32 mode;
bool hasContact = false;
uint32 buttons = 0;
float x = 0.0;
float y = 0.0;
float pressure = 0.0;
int32 clicks = 0;
int32 eraser = 0;
float wheelX = 0.0;
float wheelY = 0.0;
float tiltX = 0.0;
float tiltY = 0.0;
// let the device extract all information from the data
tabletDevice->ReadData(data, hasContact, mode, buttons,
x, y, pressure, clicks, eraser,
wheelX, wheelY, tiltX, tiltY);
if (hasContact) {
// apply the changes to the device
tabletDevice->SetStatus(mode, buttons, x, y, pressure,
clicks, modifiers(), eraser,
wheelX, wheelY, tiltX, tiltY, data);
}
tabletDevice->SetContact(hasContact);
} else {
if (ret < B_OK) {
if (ret == B_TIMED_OUT)
snooze(SNOOZE_AMOUNT);
else if (ret == B_INTERRUPTED)
snooze(SNOOZE_AMOUNT);
else {
delete[] data;
return ret;
}
status_t ret = reader->ReadData(data, dataBytes);
if (ret == dataBytes) {
// data we read from the wacom device
uint32 mode;
bool hasContact = false;
uint32 buttons = 0;
float x = 0.0;
float y = 0.0;
float pressure = 0.0;
int32 clicks = 0;
int32 eraser = 0;
float wheelX = 0.0;
float wheelY = 0.0;
float tiltX = 0.0;
float tiltY = 0.0;
// let the device extract all information from the data
tabletDevice->ReadData(data, hasContact, mode, buttons,
x, y, pressure, clicks, eraser,
wheelX, wheelY, tiltX, tiltY);
if (hasContact) {
// apply the changes to the device
tabletDevice->SetStatus(mode, buttons, x, y, pressure,
clicks, modifiers(), eraser,
wheelX, wheelY, tiltX, tiltY, data);
} else
PRINT(("device has no contact\n"));
tabletDevice->SetContact(hasContact);
} else {
PRINT(("failed to read %ld bytes, read: %ld or %s\n",
dataBytes, ret, strerror(ret)));
if (ret < B_OK) {
if (ret == B_TIMED_OUT)
snooze(SNOOZE_AMOUNT);
else if (ret == B_INTERRUPTED)
snooze(SNOOZE_AMOUNT);
else {
return ret;
}
}
}
delete[] data;
}
return B_OK;

View File

@ -25,16 +25,12 @@ class TabletDevice : public PointingDevice {
virtual status_t Start();
virtual status_t Stop();
inline int DataBytes() const
{ return fDataBytes; }
status_t DetectDevice(uint16 productID);
status_t DetectDevice(const DeviceReader* reader);
void SetDevice(float maxX, float maxY,
uint32 mode = DEVICE_INTUOS,
int dataBytes = 10);
uint32 mode = DEVICE_INTUOS);
void ReadData(uchar* data,
void ReadData(const uchar* data,
bool& hasContact,
uint32& mode,
uint32& buttons,