xref: /haiku/src/add-ons/input_server/devices/wacom/DeviceReader.cpp (revision 29ae0e0f61022017dc3af1c46a59bc8a7259b83b)
1dc1bdabbSStephan Aßmus /*
2*29ae0e0fSCodeforEvolution  * Copyright 2005-2008 Stephan Aßmus <superstippi@gmx.de>
3*29ae0e0fSCodeforEvolution  * Copyright 2020 Jacob Secunda <secundaja@gmail.com>
4*29ae0e0fSCodeforEvolution  * All rights reserved. Distributed under the terms of the MIT license.
5dc1bdabbSStephan Aßmus  */
6*29ae0e0fSCodeforEvolution 
7*29ae0e0fSCodeforEvolution 
8dc1bdabbSStephan Aßmus #include "DeviceReader.h"
9dc1bdabbSStephan Aßmus 
10dc1bdabbSStephan Aßmus #include <malloc.h>
11dc1bdabbSStephan Aßmus #include <string.h>
12dc1bdabbSStephan Aßmus 
13dc1bdabbSStephan Aßmus #include <File.h>
14dc1bdabbSStephan Aßmus 
15*29ae0e0fSCodeforEvolution #include <wacom_driver.h>
16*29ae0e0fSCodeforEvolution 
17d4122828SStephan Aßmus #include "MasterServerDevice.h"
18d4122828SStephan Aßmus 
19d4122828SStephan Aßmus 
20*29ae0e0fSCodeforEvolution static ssize_t kHeaderSize = sizeof(wacom_device_header);
21dc1bdabbSStephan Aßmus 
22dc1bdabbSStephan Aßmus // constructor
DeviceReader()23dc1bdabbSStephan Aßmus DeviceReader::DeviceReader()
24*29ae0e0fSCodeforEvolution 	:
25*29ae0e0fSCodeforEvolution 	fDevicePath(NULL),
26dc1bdabbSStephan Aßmus 	fDeviceFile(NULL),
27dc1bdabbSStephan Aßmus 	fVendorID(0),
28dc1bdabbSStephan Aßmus 	fProductID(0),
29*29ae0e0fSCodeforEvolution 	fMaxPacketSize(0)
30dc1bdabbSStephan Aßmus {
31dc1bdabbSStephan Aßmus }
32dc1bdabbSStephan Aßmus 
33dc1bdabbSStephan Aßmus // destructor
~DeviceReader()34dc1bdabbSStephan Aßmus DeviceReader::~DeviceReader()
35dc1bdabbSStephan Aßmus {
36dc1bdabbSStephan Aßmus 	_Unset();
37dc1bdabbSStephan Aßmus }
38dc1bdabbSStephan Aßmus 
39dc1bdabbSStephan Aßmus // SetTo
40dc1bdabbSStephan Aßmus status_t
SetTo(const char * path)41dc1bdabbSStephan Aßmus DeviceReader::SetTo(const char* path)
42dc1bdabbSStephan Aßmus {
43dc1bdabbSStephan Aßmus 	status_t ret = B_BAD_VALUE;
44*29ae0e0fSCodeforEvolution 	if (path != NULL) {
45dc1bdabbSStephan Aßmus 		_Unset();
46dc1bdabbSStephan Aßmus 		fDevicePath = strdup(path);
47dc1bdabbSStephan Aßmus 		fDeviceFile = new BFile(path, B_READ_ONLY);
48dc1bdabbSStephan Aßmus 		ret = fDeviceFile->InitCheck();
49dc1bdabbSStephan Aßmus 		if (ret >= B_OK) {
50*29ae0e0fSCodeforEvolution 			// read the wacom_device_header from the file and initialize
51dc1bdabbSStephan Aßmus 			// the rest of the object variables
52*29ae0e0fSCodeforEvolution 			wacom_device_header device_header;
53*29ae0e0fSCodeforEvolution 			ret = fDeviceFile->Read(&device_header, kHeaderSize);
54d4122828SStephan Aßmus 			if (ret == kHeaderSize) {
55dc1bdabbSStephan Aßmus 				ret = B_OK;
56*29ae0e0fSCodeforEvolution 				fVendorID = device_header.vendor_id;
57*29ae0e0fSCodeforEvolution 				fProductID = device_header.product_id;
58*29ae0e0fSCodeforEvolution 				fMaxPacketSize = device_header.max_packet_size;
59dc1bdabbSStephan Aßmus 			} else {
60dc1bdabbSStephan Aßmus 				_Unset();
61dc1bdabbSStephan Aßmus 			}
62dc1bdabbSStephan Aßmus 		}
63dc1bdabbSStephan Aßmus 	}
64dc1bdabbSStephan Aßmus 	return ret;
65dc1bdabbSStephan Aßmus }
66dc1bdabbSStephan Aßmus 
67dc1bdabbSStephan Aßmus // InitCheck
68dc1bdabbSStephan Aßmus status_t
InitCheck() const69dc1bdabbSStephan Aßmus DeviceReader::InitCheck() const
70dc1bdabbSStephan Aßmus {
71dc1bdabbSStephan Aßmus 	return fDeviceFile && fDevicePath ? fDeviceFile->InitCheck() : B_NO_INIT;
72dc1bdabbSStephan Aßmus }
73dc1bdabbSStephan Aßmus 
74dc1bdabbSStephan Aßmus // DevicePath
75dc1bdabbSStephan Aßmus const char*
DevicePath() const76dc1bdabbSStephan Aßmus DeviceReader::DevicePath() const
77dc1bdabbSStephan Aßmus {
78dc1bdabbSStephan Aßmus 	return fDevicePath;
79dc1bdabbSStephan Aßmus }
80dc1bdabbSStephan Aßmus 
81dc1bdabbSStephan Aßmus // DeviceFile
82dc1bdabbSStephan Aßmus BFile*
DeviceFile() const83dc1bdabbSStephan Aßmus DeviceReader::DeviceFile() const
84dc1bdabbSStephan Aßmus {
85dc1bdabbSStephan Aßmus 	return fDeviceFile;
86dc1bdabbSStephan Aßmus }
87dc1bdabbSStephan Aßmus 
88dc1bdabbSStephan Aßmus // VendorID
89dc1bdabbSStephan Aßmus uint16
VendorID() const90dc1bdabbSStephan Aßmus DeviceReader::VendorID() const
91dc1bdabbSStephan Aßmus {
92dc1bdabbSStephan Aßmus 	return fVendorID;
93dc1bdabbSStephan Aßmus }
94dc1bdabbSStephan Aßmus 
95dc1bdabbSStephan Aßmus // ProductID
96dc1bdabbSStephan Aßmus uint16
ProductID() const97dc1bdabbSStephan Aßmus DeviceReader::ProductID() const
98dc1bdabbSStephan Aßmus {
99dc1bdabbSStephan Aßmus 	return fProductID;
100dc1bdabbSStephan Aßmus }
101dc1bdabbSStephan Aßmus 
102dc1bdabbSStephan Aßmus // MaxPacketSize
103dc1bdabbSStephan Aßmus size_t
MaxPacketSize() const104dc1bdabbSStephan Aßmus DeviceReader::MaxPacketSize() const
105dc1bdabbSStephan Aßmus {
106*29ae0e0fSCodeforEvolution 	return fMaxPacketSize;
107dc1bdabbSStephan Aßmus }
108dc1bdabbSStephan Aßmus 
109dc1bdabbSStephan Aßmus // ReadData
110d4122828SStephan Aßmus ssize_t
ReadData(uint8 * data,const size_t size) const111d4122828SStephan Aßmus DeviceReader::ReadData(uint8* data, const size_t size) const
112dc1bdabbSStephan Aßmus {
113*29ae0e0fSCodeforEvolution 	if (!fDeviceFile || fMaxPacketSize <= 0 || fMaxPacketSize > 128)
114d4122828SStephan Aßmus 		return B_NO_INIT;
115d4122828SStephan Aßmus 	status_t ret = fDeviceFile->InitCheck();
116d4122828SStephan Aßmus 	if (ret < B_OK)
117d4122828SStephan Aßmus 		return (ssize_t)ret;
118d4122828SStephan Aßmus 
119*29ae0e0fSCodeforEvolution 	ssize_t requested = fMaxPacketSize + kHeaderSize;
120d4122828SStephan Aßmus 	uint8 buffer[requested];
121d4122828SStephan Aßmus 	ssize_t read = fDeviceFile->Read(buffer, requested);
122d4122828SStephan Aßmus 	if (read > kHeaderSize) {
123dc1bdabbSStephan Aßmus 		// make sure we don't copy too many bytes
124d4122828SStephan Aßmus 		size_t bytesToCopy = min_c(size, read - (size_t)kHeaderSize);
125d4122828SStephan Aßmus PRINT(("requested: %ld, read: %ld, user wants: %lu, copy bytes: %ld\n",
126d4122828SStephan Aßmus 	requested, read, size, bytesToCopy));
127d4122828SStephan Aßmus 		memcpy(data, buffer + kHeaderSize, bytesToCopy);
128dc1bdabbSStephan Aßmus 		// zero out any remaining bytes
129d4122828SStephan Aßmus 		if (size > bytesToCopy)
130d4122828SStephan Aßmus 			memset(data + bytesToCopy, 0, size - bytesToCopy);
131dc1bdabbSStephan Aßmus 		// operation could be considered successful
132d4122828SStephan Aßmus //		read = bytesToCopy;
133d4122828SStephan Aßmus //		if (read != (ssize_t)size)
134d4122828SStephan Aßmus //			PRINT(("user wanted: %lu, returning: %ld\n", size, read));
135d4122828SStephan Aßmus 		read = size;
136d4122828SStephan Aßmus 			// pretend we could read as many bytes as requested
137d4122828SStephan Aßmus 	} else if (read == kHeaderSize || (status_t)read == B_TIMED_OUT) {
138dc1bdabbSStephan Aßmus 		// it's ok if the operation timed out
139dc1bdabbSStephan Aßmus 		memset(data, 0, size);
140d4122828SStephan Aßmus 		read = (size_t)B_OK;
141d4122828SStephan Aßmus 	} else {
142d4122828SStephan Aßmus 		PRINT(("requested: %ld, read: %ld, user wants: %lu\n",
143d4122828SStephan Aßmus 			requested, read, size));
144dc1bdabbSStephan Aßmus 	}
145d4122828SStephan Aßmus 
146d4122828SStephan Aßmus 	return read;
147dc1bdabbSStephan Aßmus }
148dc1bdabbSStephan Aßmus 
149dc1bdabbSStephan Aßmus // _Unset
150dc1bdabbSStephan Aßmus void
_Unset()151dc1bdabbSStephan Aßmus DeviceReader::_Unset()
152dc1bdabbSStephan Aßmus {
153dc1bdabbSStephan Aßmus 	free(fDevicePath);
154dc1bdabbSStephan Aßmus 	fDevicePath = NULL;
155dc1bdabbSStephan Aßmus 	delete fDeviceFile;
156dc1bdabbSStephan Aßmus 	fDeviceFile = NULL;
157dc1bdabbSStephan Aßmus 	fVendorID = 0;
158dc1bdabbSStephan Aßmus 	fProductID = 0;
159*29ae0e0fSCodeforEvolution 	fMaxPacketSize = 0;
160dc1bdabbSStephan Aßmus }
161