1
1
input/devi/hid/mouse.c

262 строки
9.3 KiB
C

/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*
* Предостережение:
*
* Предоставленный исходный код драйвера devi-hid рекомендуется использовать
* только для отладочных целей при разработке HID-драйверов. Для всех остальных
* задач следует использовать штатный системный драйвер devi-hid.
*
* В общем случае не существует задач, которые требуется решать в этом драйвере
* при поддержке нового оборудования (для этого должен быть написан/модифицирован
* отдельный драйвер ввода или HID-драйвер).
*/
/*
* mouse.c
*
* The HID USB mouse combined device/protocol module.
*
*/
#include <sys/devi.h>
#include "hid.h"
#include <assert.h>
#define FLAG_INIT 0x0100
#define FLAG_RESET 0x0200
/* Protocol module private data */
struct private_data {
int flags; /* see valid values before */
int nDev; /* USB device number */
void * hid_module_handle; /* HID module_handle */
};
/* forward declarations */
static int mouse_init(input_module_t *module);
static int mouse_devctrl(input_module_t *module, int event, void *ptr);
static int mouse_reset(input_module_t *module);
static int mouse_input(input_module_t *module, int num, void *arg);
static int mouse_parm(input_module_t *module, int opt, char *optarg);
static int mouse_shutdown(input_module_t *module, int delay);
/* Our protocol module is represented by the following input_module_t data structure */
input_module_t mouse = {
NULL,
NULL,
NULL,
0,
DEVI_CLASS_REL | DEVI_MODULE_TYPE_PROTO | DEVI_MODULE_TYPE_DEVICE,
"mouse",
__DATE__,
"u:",
NULL,
mouse_init,
mouse_reset,
mouse_input,
NULL,
NULL,
mouse_parm,
mouse_devctrl,
mouse_shutdown
};
/* Description: callback initialisation function; it is called when input module is */
/* initialising the input system */
/* Input : input_module_t * module - pointer to module descriptor */
/* Output : None */
/* Return : 0 if OK, otherwise - (-1) */
int mouse_init(input_module_t *module)
{
struct private_data *dp = module->data;
if(!module->data)
{
if(!(dp = module->data = _scalloc(sizeof *dp)))
{
return (-1);
}
}
dp -> nDev = HIDD_CONNECT_WILDCARD;
return (0);
}
/* Description: this is a callback function for DEVCTRL command processing */
/* Input : input_module_t * module - pointer to module descriptor */
/* int event - DEVCTRL command code */
/* void * ptr - pointer to data exchange block */
/* Output : None */
/* Return : 0 if OK, otherwise -1 */
int mouse_devctrl(input_module_t *module, int event, void *ptr)
{
struct private_data *dp = module->data;
unsigned wheel;
int rc = 0;
switch(event)
{
case DEVCTL_GETDEVFLAGS:
*(unsigned short *)ptr = (dp->flags & FLAGS_GLOBAL);
break;
case DEVCTL_GETPTRBTNS:
*(unsigned long *)ptr = 5L;
break;
case DEVCTL_GETPTRCOORD:
*(unsigned char *)ptr='\02';
break;
case DEVCTL_GETWHEEL:
if(NULL != ptr)
{
struct devctl_mouse_types devctl;
if(EOK == (rc = devi_hid_devctrl(dp -> hid_module_handle, DEVCTL_GETMOUSETYPE, &devctl, HIDD_CONNECT_WILDCARD)))
{
if(devctl.curtype == NO_WHEEL_MOUSE)
wheel = 2;
else
wheel = 3;
*(unsigned *)ptr= wheel;
}
}
else
rc = EINVAL;
break;
case DEVCTL_SETWHEEL:
if(NULL != ptr) {
struct devctl_mouse_types devctl;
devctl.type = devctl.curtype = *(unsigned *)ptr;
if(EOK == (rc = devi_hid_devctrl(dp -> hid_module_handle, DEVCTL_SETMOUSETYPE, &devctl, HIDD_CONNECT_WILDCARD)))
{
}
}
break;
case DEVCTL_SETMOUSETYPE: // Could be NO_WHEEL_MOUSE, WHEEL_3B_MOUSE or WHEEL_5B_MOUSE
case DEVCTL_GETMOUSETYPE:
default:
rc = devi_hid_devctrl(dp -> hid_module_handle, event, ptr, HIDD_CONNECT_WILDCARD );
break;
}
return (rc);
}
/* Description: this callback funtion is called when the module is linked into the */
/* event bus;it is used to set initial module state on the protocol */
/* level */
/* Input : input_module_t * module - pointer to module descriptor */
/* Output : None */
/* Return : 0 if OK, otherwise -1 */
int mouse_reset(input_module_t *module)
{
struct private_data *dp = module->data;
if(!(dp->flags & FLAG_INIT))
{
if(NULL == (dp -> hid_module_handle = devi_hid_register_client(module, dp -> nDev)))
return (-1);
}
dp->flags |= FLAG_INIT;
return (0);
}
/* Description: main protocol processing function. It will be called by the */
/* device layer to pass it data to process. Its job is to interpret */
/* the data according to the MS wheel mouse protocol, create a */
/* data structure, fill it in and hand it off to the filter layer */
/* module above it. The protocol is processed using simple state */
/* machine. State info is kept in module's private data */
/* Input : input_module_t * module - pointer to module descriptor */
/* int num - number of bytes to process */
/* void * arg - raw data to process */
/* Output : None */
/* Return : 0 if OK, otherwise -1 */
/* Comment : driver uses one of two input modules depending on device data */
/* protocol */
int mouse_input(input_module_t *module, int num, void *arg)
{
pMouse_raw_data_t pMouseRawData = (pMouse_raw_data_t)arg;
struct packet_rel mp; /* data buffer */
struct private_data *dp = module->data;
input_module_t *up = module->up;
assert(num == sizeof(mouse_raw_data_t)); // Desynchronized exchange format
if(dp->flags & FLAG_INIT)
{
mp.flags = PTR_Z_DATA; // Set it inall cases. If there are no wheel, z always == 0
mp.dx = pMouseRawData -> x;
mp.dy = -(pMouseRawData -> y); // '-' because HID specifies down as '+' and up as '-'
mp.dz = -(pMouseRawData -> z); // '-' because HID specifies down as '+' and up as '-'
mp.buttons = pMouseRawData -> btnStates;
( up->input)(up, 1, &mp);
}
return (0);
}
/* Description: this is a callback function for command line parameter processing */
/* (all valid parameters for device module are listed in mouse.args) */
/* Input : input_module_t * module - pointer to module descriptor */
/* int opt - parameter code */
/* char * optarg - optional parameter value */
/* Output : None */
/* Return : 0 if OK, otherwise -1 */
/* Comment : we don't accept any parameter for this module at the protocol level */
int mouse_parm(input_module_t *module, int opt, char *optarg)
{
/* Now empty */
struct private_data *dp = module->data;
switch (opt)
{
case 'u':
if(NULL != optarg)
dp -> nDev = atoi(optarg);
default:
break;
}
return (0);
}
/* Description: this is a callback function which is called when resourse manager */
/* is shutting down */
/* Input : input_module_t * module - pointer to module descriptor */
/* int ms - program doesn't use this parameter */
/* Output : None */
/* Return : 0 if OK, otherwise -1 */
/* Comment : Does nothing for the protocol level */
int mouse_shutdown(input_module_t *module, int delay)
{
struct private_data *dp = module->data;
if( (NULL != dp) && (NULL != dp -> hid_module_handle))
devi_unregister_hid_client(dp -> hid_module_handle);
return (0);
}