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