[haiku-commits] r41921 - haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 5 Jun 2011 02:10:08 +0200 (CEST)

Author: mmlr
Date: 2011-06-05 02:10:07 +0200 (Sun, 05 Jun 2011)
New Revision: 41921
Changeset: https://dev.haiku-os.org/changeset/41921

Added:
   haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.cpp
   haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.h
Modified:
   haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDataTypes.h
   haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/Jamfile
Log:
Implement a HIDWriter that provides a high and lower level interface for writing
report descriptors. These descriptors aren't optimized for efficiency (the
writer doesn't attempt to avoid writing unneeded global items for example) but
they will only serve as input for the HIDParser that parses them correctly
regardless.


Modified: haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDataTypes.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDataTypes.h 
2011-06-05 00:02:28 UTC (rev 41920)
+++ haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDataTypes.h 
2011-06-05 00:10:07 UTC (rev 41921)
@@ -115,6 +115,12 @@
 } _PACKED main_item_data;
 
 
+typedef union main_item_data_converter {
+       main_item_data  main_data;
+       uint16                  flat_data;
+} main_item_data_converter;
+
+
 typedef struct usage_value {
        union {
                struct {

Added: haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.cpp          
                (rev 0)
+++ haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.cpp  
2011-06-05 00:10:07 UTC (rev 41921)
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2011, Michael Lotz, mmlr@xxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#ifndef USERLAND_HID
+#include "Driver.h"
+#else
+#include "UserlandHID.h"
+#endif
+
+#include "HIDWriter.h"
+
+#include "HIDDataTypes.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+HIDWriter::HIDWriter(size_t blockSize)
+       :       fBlockSize(blockSize),
+               fBufferAllocated(0),
+               fBufferUsed(0),
+               fBuffer(NULL),
+               fStatus(B_OK)
+{
+}
+
+
+HIDWriter::~HIDWriter()
+{
+       free(fBuffer);
+}
+
+
+// #pragma mark - High Level
+
+
+status_t
+HIDWriter::DefineInputPadding(uint8 reportID, uint8 count, uint8 bitLength)
+{
+       SetReportID(reportID);
+       SetReportSize(bitLength);
+       SetReportCount(count);
+
+       main_item_data data;
+       data.data_constant = 1;
+       return Input(data);
+}
+
+
+status_t
+HIDWriter::DefineInputData(uint8 reportID, uint8 count, uint8 bitLength,
+       main_item_data data, uint32 logicalMinimum, uint32 logicalMaximum,
+       uint16 usagePage, uint16 usageMinimum, uint16 usageMaximum)
+{
+       SetReportID(reportID);
+       SetReportSize(bitLength);
+       SetReportCount(count);
+
+       SetLogicalMinimum(logicalMinimum);
+       SetLogicalMaximum(logicalMaximum);
+
+       SetUsagePage(usagePage);
+       LocalSetUsageMinimum(usageMinimum);
+       LocalSetUsageMaximum(
+               usageMaximum == 0xffff ? usageMinimum + count - 1 : 
usageMaximum);
+       return Input(data);
+}
+
+
+status_t
+HIDWriter::BeginCollection(uint8 collectionType, uint16 usagePage,
+       uint16 usageID)
+{
+       SetUsagePage(usagePage);
+       LocalSetUsageID(usageID);
+       return BeginCollection(collectionType);
+}
+
+
+status_t
+HIDWriter::EndCollection()
+{
+       return WriteShortItem(ITEM_TYPE_MAIN, ITEM_TAG_MAIN_END_COLLECTION, 0);
+}
+
+
+// #pragma mark - Low Level
+
+
+status_t
+HIDWriter::SetUsagePage(uint16 usagePage)
+{
+       return WriteShortItem(ITEM_TYPE_GLOBAL, ITEM_TAG_GLOBAL_USAGE_PAGE,
+               usagePage);
+}
+
+
+status_t
+HIDWriter::SetLogicalMinimum(uint32 logicalMinimum)
+{
+       return WriteShortItem(ITEM_TYPE_GLOBAL, ITEM_TAG_GLOBAL_LOGICAL_MINIMUM,
+               logicalMinimum);
+}
+
+
+status_t
+HIDWriter::SetLogicalMaximum(uint32 logicalMaximum)
+{
+       return WriteShortItem(ITEM_TYPE_GLOBAL, ITEM_TAG_GLOBAL_LOGICAL_MAXIMUM,
+               logicalMaximum);
+}
+
+
+status_t
+HIDWriter::SetReportSize(uint8 reportSize)
+{
+       return WriteShortItem(ITEM_TYPE_GLOBAL, ITEM_TAG_GLOBAL_REPORT_SIZE,
+               reportSize);
+}
+
+
+status_t
+HIDWriter::SetReportID(uint8 reportID)
+{
+       return WriteShortItem(ITEM_TYPE_GLOBAL, ITEM_TAG_GLOBAL_REPORT_ID,
+               reportID);
+}
+
+
+status_t
+HIDWriter::SetReportCount(uint8 reportCount)
+{
+       return WriteShortItem(ITEM_TYPE_GLOBAL, ITEM_TAG_GLOBAL_REPORT_COUNT,
+               reportCount);
+}
+
+
+status_t
+HIDWriter::LocalSetUsageID(uint16 usageID)
+{
+       return WriteShortItem(ITEM_TYPE_LOCAL, ITEM_TAG_LOCAL_USAGE, usageID);
+}
+
+
+status_t
+HIDWriter::LocalSetUsageMinimum(uint16 usageMinimum)
+{
+       return WriteShortItem(ITEM_TYPE_LOCAL, ITEM_TAG_LOCAL_USAGE_MINIMUM,
+               usageMinimum);
+}
+
+
+status_t
+HIDWriter::LocalSetUsageMaximum(uint16 usageMaximum)
+{
+       return WriteShortItem(ITEM_TYPE_LOCAL, ITEM_TAG_LOCAL_USAGE_MAXIMUM,
+               usageMaximum);
+}
+
+
+status_t
+HIDWriter::BeginCollection(uint8 collectionType)
+{
+       return WriteShortItem(ITEM_TYPE_MAIN, ITEM_TAG_MAIN_COLLECTION,
+               collectionType);
+}
+
+
+status_t
+HIDWriter::Input(main_item_data data)
+{
+       main_item_data_converter converter;
+       converter.main_data = data;
+       return WriteShortItem(ITEM_TYPE_MAIN, ITEM_TAG_MAIN_INPUT,
+               converter.flat_data);
+}
+
+
+status_t
+HIDWriter::Output(main_item_data data)
+{
+       main_item_data_converter converter;
+       converter.main_data = data;
+       return WriteShortItem(ITEM_TYPE_MAIN, ITEM_TAG_MAIN_OUTPUT,
+               converter.flat_data);
+}
+
+
+status_t
+HIDWriter::Feature(main_item_data data)
+{
+       main_item_data_converter converter;
+       converter.main_data = data;
+       return WriteShortItem(ITEM_TYPE_MAIN, ITEM_TAG_MAIN_FEATURE,
+               converter.flat_data);
+}
+
+
+// #pragma mark - Generic
+
+
+status_t
+HIDWriter::WriteShortItem(uint8 type, uint8 tag, uint32 value)
+{
+       short_item item;
+       item.prefix.size = 0;
+
+       if (value > 0) {
+               if (value <= 0xff)
+                       item.prefix.size = 1;
+               else if (value <= 0xffff)
+                       item.prefix.size = 2;
+               else
+                       item.prefix.size = 3; // actually means 4
+       }
+
+       item.prefix.type = type;
+       item.prefix.tag = tag;
+
+       switch (item.prefix.size) {
+               case 0:
+                       return Write(&item, sizeof(item_prefix));
+               case 1:
+                       item.data.as_uint8[0] = value;
+                       return Write(&item, sizeof(item_prefix) + 
sizeof(uint8));
+               case 2:
+                       item.data.as_uint16[0] = value;
+                       return Write(&item, sizeof(item_prefix) + 
sizeof(uint16));
+               case 3:
+                       item.data.as_uint32 = value;
+                       return Write(&item, sizeof(item_prefix) + 
sizeof(uint32));
+       }
+
+       return B_OK;
+}
+
+
+status_t
+HIDWriter::Write(const void *data, size_t length)
+{
+       if (fStatus != B_OK)
+               return fStatus;
+
+       size_t available = fBufferAllocated - fBufferUsed;
+       if (length > available) {
+               fBufferAllocated += length > fBlockSize ?  length : fBlockSize;
+               uint8 *newBuffer = (uint8 *)realloc(fBuffer, fBufferAllocated);
+               if (newBuffer == NULL) {
+                       fBufferAllocated -= fBlockSize;
+                       fStatus = B_NO_MEMORY;
+                       return fStatus;
+               }
+
+               fBuffer = newBuffer;
+       }
+
+       memcpy(fBuffer + fBufferUsed, data, length);
+       fBufferUsed += length;
+       return B_OK;
+}
+
+
+void
+HIDWriter::Reset()
+{
+       free(fBuffer);
+       fBuffer = NULL;
+       fBufferUsed = 0;
+       fBufferAllocated = 0;
+       fStatus = B_OK;
+}

Added: haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.h            
                (rev 0)
+++ haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDWriter.h    
2011-06-05 00:10:07 UTC (rev 41921)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011, Michael Lotz, mmlr@xxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef HID_WRITER_H
+#define HID_WRITER_H
+
+#include "HIDDataTypes.h"
+
+
+class HIDWriter {
+public:
+                                                               
HIDWriter(size_t blockSize = 20);
+                                                               ~HIDWriter();
+
+                       // High Level
+
+                       status_t                        
DefineInputPadding(uint8 reportID, uint8 count,
+                                                                       uint8 
bitLength);
+                       status_t                        DefineInputData(uint8 
reportID, uint8 count,
+                                                                       uint8 
bitLength, main_item_data data,
+                                                                       uint32 
logicalMinimum,
+                                                                       uint32 
logicalMaximum, uint16 usagePage,
+                                                                       uint16 
usageMinimum,
+                                                                       uint16 
usageMaximum = 0xffff);
+
+                       status_t                        BeginCollection(uint8 
collectionType,
+                                                                       uint16 
usagePage, uint16 usageID);
+                       status_t                        EndCollection();
+
+                       // Low Level
+
+                       status_t                        SetUsagePage(uint16 
usagePage);
+                       status_t                        
SetLogicalMinimum(uint32 logicalMinimum);
+                       status_t                        
SetLogicalMaximum(uint32 logicalMaximum);
+                       status_t                        SetReportSize(uint8 
reportSize);
+                       status_t                        SetReportID(uint8 
reportID);
+                       status_t                        SetReportCount(uint8 
reportCount);
+
+                       status_t                        LocalSetUsageID(uint16 
usageID);
+                       status_t                        
LocalSetUsageMinimum(uint16 usageMinimum);
+                       status_t                        
LocalSetUsageMaximum(uint16 usageMaximum);
+
+                       status_t                        BeginCollection(uint8 
collectionType);
+
+                       status_t                        Input(main_item_data 
data);
+                       status_t                        Output(main_item_data 
data);
+                       status_t                        Feature(main_item_data 
data);
+
+                       // Generic
+
+                       status_t                        WriteShortItem(uint8 
type, uint8 tag,
+                                                                       uint32 
value);
+                       status_t                        Write(const void *data, 
size_t length);
+
+                       size_t                          BufferLength() { return 
fBufferUsed; };
+                       const uint8 *           Buffer() { return fBuffer; };
+
+                       void                            Reset();
+
+private:
+                       size_t                          fBlockSize;
+                       size_t                          fBufferAllocated;
+                       size_t                          fBufferUsed;
+                       uint8 *                         fBuffer;
+                       status_t                        fStatus;
+};
+
+#endif // HID_WRITER_H

Modified: haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/Jamfile        
2011-06-05 00:02:28 UTC (rev 41920)
+++ haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/Jamfile        
2011-06-05 00:10:07 UTC (rev 41921)
@@ -15,6 +15,7 @@
        HIDParser.cpp
        HIDReport.cpp
        HIDReportItem.cpp
+       HIDWriter.cpp
 
        QuirkyDevices.cpp
 


Other related posts:

  • » [haiku-commits] r41921 - haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid - mmlr