Ticket #7354: usb_hid.patch

File usb_hid.patch, 9.3 KB (added by lt_henry, 13 years ago)

usb hid with tablet support

  • HIDReportItem.h

    diff -Nuar usb_hid/HIDReportItem.h usb_hid.mine/HIDReportItem.h
    old new  
    2727
    2828        uint32                  UsageMinimum() { return fUsageMinimum; };
    2929        uint32                  UsageMaximum() { return fUsageMaximum; };
     30       
     31        uint32                  Minimum() { return fMinimum; };
     32        uint32                  Maximum() { return fMaximum; };
    3033
    3134        status_t                Extract();
    3235        status_t                Insert();
  • Jamfile

    diff -Nuar usb_hid/Jamfile usb_hid.mine/Jamfile
    old new  
    1212    HIDDevice.cpp
    1313    KeyboardDevice.cpp
    1414    MouseDevice.cpp
     15    TabletDevice.cpp
    1516    ProtocolHandler.cpp
    1617
    1718    HIDCollection.cpp
  • ProtocolHandler.cpp

    diff -Nuar usb_hid/ProtocolHandler.cpp usb_hid.mine/ProtocolHandler.cpp
    old new  
    1515// includes for the different protocol handlers
    1616#include "KeyboardDevice.h"
    1717#include "MouseDevice.h"
     18#include "TabletDevice.h"
    1819//#include "GenericDevice.h"
    1920
    2021
     
    8384        handler = KeyboardDevice::AddHandler(device, report);
    8485        if (handler != NULL)
    8586            (*handlerList)[usedCount++] = handler;
    86         handler = MouseDevice::AddHandler(device, report);
    87         if (handler != NULL)
    88             (*handlerList)[usedCount++] = handler;
     87           
     88        handler = TabletDevice::AddHandler(device, report);
     89        if (handler != NULL) {
     90            (*handlerList)[usedCount++] = handler;
     91        }
     92        else {
     93            handler = MouseDevice::AddHandler(device, report);
     94            if (handler != NULL) {
     95                (*handlerList)[usedCount++] = handler;
     96            }
     97        }
     98           
    8999    }
    90100
    91101    if (usedCount == 0) {
  • TabletDevice.cpp

    diff -Nuar usb_hid/TabletDevice.cpp usb_hid.mine/TabletDevice.cpp
    old new  
     1/*
     2 * Copyright 2010-2011 Enrique Medina Gremaldos <quiqueiii@gmail.com>
     3 * Distributed under the terms of the MIT license.
     4 */
     5
     6
     7//! Driver for USB Human Interface Devices.
     8
     9
     10#include "Driver.h"
     11#include "TabletDevice.h"
     12
     13#include "HIDDevice.h"
     14#include "HIDReport.h"
     15#include "HIDReportItem.h"
     16
     17#include <new>
     18#include <string.h>
     19#include <usb/USB_hid.h>
     20
     21#include <keyboard_mouse_driver.h>
     22
     23
     24TabletDevice::TabletDevice(HIDReport *report)
     25    :
     26    ProtocolHandler(report->Device(), "input/tablet/usb/", 512),
     27    fReport(report),
     28    fPressure(NULL),
     29    fXAxis(NULL),
     30    fYAxis(NULL),
     31    fWheel(NULL),
     32    fLastButtons(0),
     33    fClickCount(0),
     34    fLastClickTime(0),
     35    fClickSpeed(250000)
     36{
     37    uint32 buttonCount = 0;
     38    for (uint32 i = 0; i < report->CountItems(); i++) {
     39        HIDReportItem *item = report->ItemAt(i);
     40        if (!item->HasData())
     41            continue;
     42
     43        if (item->UsagePage() == B_HID_USAGE_PAGE_BUTTON
     44            && item->UsageID() - 1 < B_MAX_MOUSE_BUTTONS)
     45            fButtons[buttonCount++] = item;
     46    }
     47
     48    fButtons[buttonCount] = NULL;
     49
     50    fWheel = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,B_HID_UID_GD_WHEEL);
     51
     52    TRACE_ALWAYS("tablet device with %lu buttons and %swheel\n", buttonCount,
     53        fWheel == NULL ? "no " : "");
     54    TRACE_ALWAYS("report id: %u\n", report->ID());
     55   
     56    fRange = report->FindItem(B_HID_USAGE_PAGE_DIGITIZER,B_HID_UID_DIG_IN_RANGE);
     57    if(fRange!=NULL)
     58        TRACE_ALWAYS("TabletDevice: found range\n");
     59       
     60    fTip = report->FindItem(B_HID_USAGE_PAGE_DIGITIZER,B_HID_UID_DIG_TIP_SWITCH);
     61    if(fTip!=NULL)
     62        TRACE_ALWAYS("TabletDevice: found Tip\n");
     63
     64    fBarrelSwitch = report->FindItem(B_HID_USAGE_PAGE_DIGITIZER,B_HID_UID_DIG_BARREL_SWITCH);
     65    if(fBarrelSwitch!=NULL)
     66        TRACE_ALWAYS("TabletDevice: found Barrel Tip\n");
     67   
     68    fPressure = report->FindItem(B_HID_USAGE_PAGE_DIGITIZER,B_HID_UID_DIG_TIP_PRESSURE);
     69    if(fPressure!=NULL)
     70        TRACE_ALWAYS("TabletDevice: found pressure\n");
     71       
     72    fXAxis = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,B_HID_UID_GD_X);
     73    if (fXAxis != NULL)
     74        TRACE_ALWAYS("TabletDevice: found X\n");
     75   
     76    fYAxis = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,B_HID_UID_GD_Y);
     77    if (fYAxis != NULL)
     78        TRACE_ALWAYS("TabletDevice: found Y\n");
     79   
     80   
     81   
     82}
     83
     84
     85ProtocolHandler *
     86TabletDevice::AddHandler(HIDDevice *device, HIDReport *report)
     87{
     88   
     89    TRACE_ALWAYS("report type:%x\n",report->Type());
     90    TRACE_ALWAYS("report id:%x\n",report->ID());
     91    for(int n=0;n<report->CountItems();n++) {
     92        TRACE_ALWAYS("item usage page:%x id:%x\n",report->ItemAt(n)->UsagePage(),report->ItemAt(n)->UsageID());
     93    }
     94   
     95    HIDReportItem * x = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,B_HID_UID_GD_X);
     96    HIDReportItem * y = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,B_HID_UID_GD_Y);
     97   
     98    if(x!=NULL && y!=NULL) {
     99        if(x->Relative() || y->Relative())
     100            return NULL;   
     101    }else return NULL;
     102   
     103    return new(std::nothrow) TabletDevice(report);
     104}
     105
     106
     107status_t
     108TabletDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
     109{
     110    switch (op) {
     111        case MS_READ:
     112            while (RingBufferReadable() == 0) {
     113                status_t result = _ReadReport();
     114                if (result != B_OK)
     115                    return result;
     116            }
     117
     118            return RingBufferRead(buffer, sizeof(tablet_movement));
     119
     120        case MS_NUM_EVENTS:
     121        {
     122            int32 count = RingBufferReadable() / sizeof(tablet_movement);
     123            if (count == 0 && fReport->Device()->IsRemoved())
     124                return B_DEV_NOT_READY;
     125            return count;
     126        }
     127
     128        case MS_SET_CLICKSPEED:
     129#ifdef __HAIKU__
     130                return user_memcpy(&fClickSpeed, buffer, sizeof(bigtime_t));
     131#else
     132                fClickSpeed = *(bigtime_t *)buffer;
     133                return B_OK;
     134#endif
     135    }
     136
     137    return B_ERROR;
     138}
     139
     140
     141status_t
     142TabletDevice::_ReadReport()
     143{
     144   
     145    status_t result = fReport->WaitForReport(B_INFINITE_TIMEOUT);
     146   
     147   
     148    if (result != B_OK) {
     149   
     150        if (fReport->Device()->IsRemoved()) {
     151            TRACE("device has been removed\n");
     152            return B_DEV_NOT_READY;
     153        }
     154
     155        if (result != B_INTERRUPTED) {
     156            // interrupts happen when other reports come in on the same
     157            // input as ours
     158            TRACE_ALWAYS("error waiting for report: %s\n", strerror(result));
     159        }
     160        else TRACE_ALWAYS("Report %d has been interrumpted\n",fReport->ID());
     161       
     162
     163        // signal that we simply want to try again
     164        return B_OK;
     165    }//else TRACE_ALWAYS("Report ok for:%d\n",fReport->ID());
     166
     167    tablet_movement info;
     168    memset(&info, 0, sizeof(info));
     169    float usage_delta;
     170    info.pressure=0.0f;
     171   
     172   
     173    if (fXAxis->Extract() == B_OK && fXAxis->Valid()) {
     174        usage_delta = fXAxis->Maximum() - fXAxis->Minimum();
     175        info.xpos = (fXAxis->Data() - fXAxis->Minimum()) / usage_delta ;           
     176    }
     177   
     178    if (fYAxis->Extract() == B_OK && fYAxis->Valid()) {
     179        usage_delta = fYAxis->Maximum() - fYAxis->Minimum();
     180        info.ypos = (fYAxis->Data() - fYAxis->Minimum()) / usage_delta;         
     181    }
     182   
     183   
     184    if(fPressure!=NULL && fPressure->Extract() == B_OK && fPressure->Valid()) {
     185        usage_delta = fPressure->Maximum() - fPressure->Minimum();
     186        info.pressure = (fPressure->Data() - fPressure->Minimum()) / usage_delta;           
     187    }
     188       
     189
     190    if (fWheel != NULL && fWheel->Extract() == B_OK && fWheel->Valid())
     191        info.wheel_ydelta = -fWheel->Data();
     192
     193
     194    if(fTip!=NULL && fTip->Extract()==B_OK && fTip->Valid()) {
     195        info.buttons |= fTip->Data();
     196    }
     197   
     198    if(fBarrelSwitch!=NULL && fBarrelSwitch->Extract()==B_OK && fBarrelSwitch->Valid()) {
     199        info.buttons |= fBarrelSwitch->Data()<<1;
     200    }
     201   
     202
     203    for (uint32 i = 0; i < B_MAX_MOUSE_BUTTONS; i++) {
     204        HIDReportItem *button = fButtons[i];
     205        if (button == NULL)
     206            break;
     207
     208        if (button->Extract() == B_OK && button->Valid())
     209            info.buttons |= (button->Data() & 1) << (button->UsageID() - 1);
     210    }
     211
     212    fReport->DoneProcessing();
     213    //TRACE_ALWAYS("Sent tablet report:%d\n",fReport->ID());
     214    //TRACE("got mouse report\n");
     215
     216    bigtime_t timestamp = system_time();
     217    if (info.buttons != 0) {
     218        if (fLastButtons == 0) {
     219            if (fLastClickTime + fClickSpeed > timestamp)
     220                fClickCount++;
     221            else
     222                fClickCount = 1;
     223        }
     224
     225        fLastClickTime = timestamp;
     226        info.clicks = fClickCount;
     227    }
     228
     229    fLastButtons = info.buttons;
     230    info.timestamp = timestamp;
     231    return RingBufferWrite(&info, sizeof(tablet_movement));
     232}
  • TabletDevice.h

    diff -Nuar usb_hid/TabletDevice.h usb_hid.mine/TabletDevice.h
    old new  
     1/*
     2 * Copyright 20010-2011 Enrique Medina Gremaldos <quiqueiii@gmail.com>
     3 * Distributed under the terms of the MIT license.
     4 */
     5#ifndef USB_TABLET_DEVICE_H
     6#define USB_TABLET_DEVICE_H
     7
     8
     9#include <InterfaceDefs.h>
     10
     11#include "ProtocolHandler.h"
     12
     13
     14class HIDReportItem;
     15
     16
     17#ifndef B_MAX_MOUSE_BUTTONS
     18#   define B_MAX_MOUSE_BUTTONS      8
     19#endif
     20
     21
     22class TabletDevice : public ProtocolHandler {
     23public:
     24                                TabletDevice(HIDReport *report);
     25
     26    static  ProtocolHandler *   AddHandler(HIDDevice *device,
     27                                    HIDReport *report);
     28
     29    virtual status_t            Control(uint32 *cookie, uint32 op, void *buffer,
     30                                    size_t length);
     31
     32private:
     33            status_t            _ReadReport();
     34
     35private:
     36            HIDReport *         fReport;
     37
     38            HIDReportItem *     fPressure;
     39            HIDReportItem *     fXAxis;
     40            HIDReportItem *     fYAxis;
     41            HIDReportItem *     fWheel;
     42            HIDReportItem *     fButtons[B_MAX_MOUSE_BUTTONS];
     43            HIDReportItem *     fRange;
     44            HIDReportItem *     fTip;
     45            HIDReportItem *     fBarrelSwitch;
     46
     47            uint32              fLastButtons;
     48            uint32              fClickCount;
     49            bigtime_t           fLastClickTime;
     50            bigtime_t           fClickSpeed;
     51            uint32              fMaxButtons;
     52           
     53            uint32              lastX;
     54            uint32              lastY;
     55};
     56
     57#endif // USB_TABLET_DEVICE_H