4 设置低级驱动模式
设置低级驱动允许传入所有的输入驱动,一般调用原始模式(raw mode)。这么设置是因为高级输入驱动需要对任何传输来原始数据进行处理,打包后作为输入事件。低级驱动传输数据,高级驱动接受数据。低级驱动有不同的操作,所以必须在一个合适的模式。
/* Set device in mode to pass all data – raw mode */
ioctl (pDevice->inputDevice.fd, FIOSETOPTIONS, OPT_RAW);
/* Flush input queue of any stale data */
ioctl (pDevice->inputDevice.fd, FIOFLUSH,0);
/* Scan codes need to be sent verses processed key codes */
ioctl (pDevice->inputDevice.fd, CONIOCONVERTSCAN, FALSE);
/* Initialize the LED to the initialized value */
ioctl (pDevice->inputDevice.fd, CONIOLEDS, pDevice->ledValue);
5 返回驱动结构的指针。如果驱动成功打开,返回UGL_INPUT_DEV的指针return (&pDevice->inputDevice);失败返回NULL
执行驱动控制程序
驱动控制程序提供几种操作使用标准的ioctl函数,有三个参数
第1驱动操作控制块
第2需求类型
第3需求类型包含地参数
具体如下:图
Keyboard LED Control
switch (reqType)
{
.
.
.
case ICR_SET_LED: /* Set LED values */
case ICR_CLEAR_LED: /* Clear LED values */
{
UGL_UINT32 leds = *(UGL_UINT32 *)pArg;
int ledValue = 0;
/* generate a device dependent LED value */
if (leds & UGL_KBD_CAPS_LOCK)
ledValue |= UGL_PCKBD_LED_CAPS_LOCK;
if (leds & UGL_KBD_NUM_LOCK)
ledValue |= UGL_PCKBD_LED_NUM_LOCK;
if (leds & UGL_KBD_SCROLL_LOCK)
ledValue |= UGL_PCKBD_LED_SCROLL_LOCK;
/* Adjust representation if setting or clearing LEDs */
if (request == ICR_SET_LED)
pDevice->ledValue |= ledValue;
else
pDevice->ledValue &= ~ledValue;
/* Send request to low-level driver to change the LED values */
ioctl (pDevice->inputDevice.fd, CONIOLEDS, pDevice->ledValue);
}
break;
case ICR_GET_LED_STATE: /* Get state of LEDs */
{
UGL_UINT32 modifiers = 0;
/* Generate LED setting based on the modifier states */
if (pDevice->ledValue & UGL_PCKBD_LED_CAPS_LOCK)
modifiers |= UGL_KBD_CAPS_LOCK;
if (pDevice->ledValue & UGL_PCKBD_LED_NUM_LOCK)
modifiers |= UGL_KBD_NUM_LOCK;
if (pDevice->ledValue & UGL_PCKBD_LED_SCROLL_LOCK)
modifiers |= UGL_KBD_SCROLL_LOCK;
*(UGL_UINT32 *)pArg = modifiers;
}
break;
.
.
.
}
询问鼠标类型
鼠标类型的驱动必须由ICR_GET_PTR_TYPE指出类型例如:
switch (request)
{
.
.
.
case ICR_GET_PTR_TYPE: /* Pointer type query */
{
if(pArg != UGL_NULL)
{
*(int *)pArg = UGL_PTR_TYPE_MOUSE;
return(UGL_STATUS_OK);
}
else
return(UGL_STATUS_ERROR);
}
break;
.
.
.
}
读数据
所有高级输入设备必须响应数据读取要求。输入服务可被select挂起,等待数据被写入设备输入设备读队列。当低级设备驱动唤醒输入服务任务,任务调用合适的输入的设备控制通过ICR_READ请求。
当ICR_READ调用设备控制程序时,从低级驱动读取所有数据。例子如下:
switch (request)
{
case ICR_READ: /* read keyboard data */
{
int readCnt = 0;
/* Get data until no more data is present */
ioctl (pDevice->inputDevice.fd, FIONREAD, (int)&readCnt);
while (readCnt > 0)
{
unsigned char scanCode;
/* Read a code from the keyboard low-level driver */
if (read(pDevice->inputDevice.fd, &scanCode, 1) != 1)
return (UGL_STATUS_ERROR);
/* If received data signifies the start of an extended key,
* then mark that in the process of reading an extended key
* sequence */
if (scanCode == UGL_PCKBD_EXTENDED_KEY)
pDevice->extendedKey = UGL_TRUE;
else if (scanCode != 0x55) /* In test, ignore */
{
UGL_MSG kbdMsg;
/* Create raw keyboard message */
bzero ((char *)&kbdMsg, sizeof (kbdMsg));
kbdMsg.type = MSG_RAW_KBD;
kbdMsg.data.rawKbd.deviceId = &pDevice->inputDevice;
if (scanCode & UGL_PCKBD_MAKE_FLAG)
{
kbdMsg.data.rawKbd.isKeyDown = UGL_FALSE;
scanCode &= ~UGL_PCKBD_MAKE_FLAG;
}
else
kbdMsg.data.rawKbd.isKeyDown = UGL_TRUE;
if (pDevice->extendedKey)
{
kbdMsg.data.rawKbd.isExtended = UGL_TRUE;
pDevice->extendedKey = UGL_FALSE;
}
else
kbdMsg.data.rawKbd.isExtended = UGL_FALSE;
kbdMsg.data.rawKbd.isKeyCode = FALSE;
kbdMsg.data.rawKbd.value.scanCode = scanCode;
/* post message */
uglInputMsgPost (pDevice->inputDevice.inputServiceId,
&kbdMsg);
}
readCnt--;
}
}
break;
.
.
.
}
文章评论(0条评论)
登录后参与讨论