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