Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
cfb41c82
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
cfb41c82
编写于
2月 01, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'spice/usb.5' into staging
上级
e54b7f52
ea87e95f
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
282 addition
and
111 deletion
+282
-111
hw/hw.h
hw/hw.h
+10
-0
hw/usb-bus.c
hw/usb-bus.c
+23
-5
hw/usb-hid.c
hw/usb-hid.c
+218
-99
hw/usb-hub.c
hw/usb-hub.c
+24
-0
hw/usb.h
hw/usb.h
+5
-5
ui/vnc.c
ui/vnc.c
+2
-2
未找到文件。
hw/hw.h
浏览文件 @
cfb41c82
...
@@ -587,6 +587,16 @@ extern const VMStateDescription vmstate_i2c_slave;
...
@@ -587,6 +587,16 @@ extern const VMStateDescription vmstate_i2c_slave;
.offset = vmstate_offset_value(_state, _field, i2c_slave), \
.offset = vmstate_offset_value(_state, _field, i2c_slave), \
}
}
extern
const
VMStateDescription
vmstate_usb_device
;
#define VMSTATE_USB_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(USBDevice), \
.vmsd = &vmstate_usb_device, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, USBDevice), \
}
#define vmstate_offset_macaddr(_state, _field) \
#define vmstate_offset_macaddr(_state, _field) \
vmstate_offset_array(_state, _field.a, uint8_t, \
vmstate_offset_array(_state, _field.a, uint8_t, \
sizeof(typeof_field(_state, _field)))
sizeof(typeof_field(_state, _field)))
...
...
hw/usb-bus.c
浏览文件 @
cfb41c82
...
@@ -23,6 +23,22 @@ static struct BusInfo usb_bus_info = {
...
@@ -23,6 +23,22 @@ static struct BusInfo usb_bus_info = {
static
int
next_usb_bus
=
0
;
static
int
next_usb_bus
=
0
;
static
QTAILQ_HEAD
(,
USBBus
)
busses
=
QTAILQ_HEAD_INITIALIZER
(
busses
);
static
QTAILQ_HEAD
(,
USBBus
)
busses
=
QTAILQ_HEAD_INITIALIZER
(
busses
);
const
VMStateDescription
vmstate_usb_device
=
{
.
name
=
"USBDevice"
,
.
version_id
=
1
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_UINT8
(
addr
,
USBDevice
),
VMSTATE_INT32
(
state
,
USBDevice
),
VMSTATE_INT32
(
remote_wakeup
,
USBDevice
),
VMSTATE_INT32
(
setup_state
,
USBDevice
),
VMSTATE_INT32
(
setup_len
,
USBDevice
),
VMSTATE_INT32
(
setup_index
,
USBDevice
),
VMSTATE_UINT8_ARRAY
(
setup_buf
,
USBDevice
,
8
),
VMSTATE_END_OF_LIST
(),
}
};
void
usb_bus_new
(
USBBus
*
bus
,
DeviceState
*
host
)
void
usb_bus_new
(
USBBus
*
bus
,
DeviceState
*
host
)
{
{
qbus_create_inplace
(
&
bus
->
qbus
,
&
usb_bus_info
,
host
,
NULL
);
qbus_create_inplace
(
&
bus
->
qbus
,
&
usb_bus_info
,
host
,
NULL
);
...
@@ -282,20 +298,22 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
...
@@ -282,20 +298,22 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
{
{
USBDevice
*
dev
=
DO_UPCAST
(
USBDevice
,
qdev
,
qdev
);
USBDevice
*
dev
=
DO_UPCAST
(
USBDevice
,
qdev
,
qdev
);
char
*
fw_path
,
*
in
;
char
*
fw_path
,
*
in
;
int
pos
=
0
;
ssize_t
pos
=
0
,
fw_len
;
long
nr
;
long
nr
;
fw_path
=
qemu_malloc
(
32
+
strlen
(
dev
->
port
->
path
)
*
6
);
fw_len
=
32
+
strlen
(
dev
->
port
->
path
)
*
6
;
fw_path
=
qemu_malloc
(
fw_len
);
in
=
dev
->
port
->
path
;
in
=
dev
->
port
->
path
;
while
(
true
)
{
while
(
fw_len
-
pos
>
0
)
{
nr
=
strtol
(
in
,
&
in
,
10
);
nr
=
strtol
(
in
,
&
in
,
10
);
if
(
in
[
0
]
==
'.'
)
{
if
(
in
[
0
]
==
'.'
)
{
/* some hub between root port and device */
/* some hub between root port and device */
pos
+=
s
printf
(
fw_path
+
pos
,
"hub@%ld/"
,
nr
);
pos
+=
s
nprintf
(
fw_path
+
pos
,
fw_len
-
pos
,
"hub@%ld/"
,
nr
);
in
++
;
in
++
;
}
else
{
}
else
{
/* the device itself */
/* the device itself */
pos
+=
sprintf
(
fw_path
+
pos
,
"%s@%ld"
,
qdev_fw_name
(
qdev
),
nr
);
pos
+=
snprintf
(
fw_path
+
pos
,
fw_len
-
pos
,
"%s@%ld"
,
qdev_fw_name
(
qdev
),
nr
);
break
;
break
;
}
}
}
}
...
...
hw/usb-hid.c
浏览文件 @
cfb41c82
...
@@ -45,18 +45,27 @@
...
@@ -45,18 +45,27 @@
#define USB_TABLET 2
#define USB_TABLET 2
#define USB_KEYBOARD 3
#define USB_KEYBOARD 3
typedef
struct
USBPointerEvent
{
int32_t
xdx
,
ydy
;
/* relative iff it's a mouse, otherwise absolute */
int32_t
dz
,
buttons_state
;
}
USBPointerEvent
;
#define QUEUE_LENGTH 16
/* should be enough for a triple-click */
#define QUEUE_MASK (QUEUE_LENGTH-1u)
#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK)
typedef
struct
USBMouseState
{
typedef
struct
USBMouseState
{
int
dx
,
dy
,
dz
,
buttons_state
;
USBPointerEvent
queue
[
QUEUE_LENGTH
];
int
x
,
y
;
int
mouse_grabbed
;
int
mouse_grabbed
;
QEMUPutMouseEntry
*
eh_entry
;
QEMUPutMouseEntry
*
eh_entry
;
}
USBMouseState
;
}
USBMouseState
;
typedef
struct
USBKeyboardState
{
typedef
struct
USBKeyboardState
{
uint32_t
keycodes
[
QUEUE_LENGTH
];
uint16_t
modifiers
;
uint16_t
modifiers
;
uint8_t
leds
;
uint8_t
leds
;
uint8_t
key
[
16
];
uint8_t
key
[
16
];
int
keys
;
int
32_t
keys
;
}
USBKeyboardState
;
}
USBKeyboardState
;
typedef
struct
USBHIDState
{
typedef
struct
USBHIDState
{
...
@@ -65,8 +74,10 @@ typedef struct USBHIDState {
...
@@ -65,8 +74,10 @@ typedef struct USBHIDState {
USBMouseState
ptr
;
USBMouseState
ptr
;
USBKeyboardState
kbd
;
USBKeyboardState
kbd
;
};
};
uint32_t
head
;
/* index into circular queue */
uint32_t
n
;
int
kind
;
int
kind
;
int
protocol
;
int
32_t
protocol
;
uint8_t
idle
;
uint8_t
idle
;
int64_t
next_idle_clock
;
int64_t
next_idle_clock
;
int
changed
;
int
changed
;
...
@@ -433,40 +444,79 @@ static void usb_hid_changed(USBHIDState *hs)
...
@@ -433,40 +444,79 @@ static void usb_hid_changed(USBHIDState *hs)
usb_wakeup
(
&
hs
->
dev
);
usb_wakeup
(
&
hs
->
dev
);
}
}
static
void
usb_mouse_event
(
void
*
opaque
,
static
void
usb_pointer_event_clear
(
USBPointerEvent
*
e
,
int
buttons
)
{
int
dx1
,
int
dy1
,
int
dz1
,
int
buttons_state
)
e
->
xdx
=
e
->
ydy
=
e
->
dz
=
0
;
e
->
buttons_state
=
buttons
;
}
static
void
usb_pointer_event_combine
(
USBPointerEvent
*
e
,
int
xyrel
,
int
x1
,
int
y1
,
int
z1
)
{
if
(
xyrel
)
{
e
->
xdx
+=
x1
;
e
->
ydy
+=
y1
;
}
else
{
e
->
xdx
=
x1
;
e
->
ydy
=
y1
;
}
e
->
dz
+=
z1
;
}
static
void
usb_pointer_event
(
void
*
opaque
,
int
x1
,
int
y1
,
int
z1
,
int
buttons_state
)
{
{
USBHIDState
*
hs
=
opaque
;
USBHIDState
*
hs
=
opaque
;
USBMouseState
*
s
=
&
hs
->
ptr
;
USBMouseState
*
s
=
&
hs
->
ptr
;
unsigned
use_slot
=
(
hs
->
head
+
hs
->
n
-
1
)
&
QUEUE_MASK
;
s
->
dx
+=
dx1
;
unsigned
previous_slot
=
(
use_slot
-
1
)
&
QUEUE_MASK
;
s
->
dy
+=
dy1
;
s
->
dz
+=
dz1
;
/* We combine events where feasible to keep the queue small. We shouldn't
s
->
buttons_state
=
buttons_state
;
* combine anything with the first event of a particular button state, as
* that would change the location of the button state change. When the
* queue is empty, a second event is needed because we don't know if
* the first event changed the button state. */
if
(
hs
->
n
==
QUEUE_LENGTH
)
{
/* Queue full. Discard old button state, combine motion normally. */
s
->
queue
[
use_slot
].
buttons_state
=
buttons_state
;
}
else
if
(
hs
->
n
<
2
||
s
->
queue
[
use_slot
].
buttons_state
!=
buttons_state
||
s
->
queue
[
previous_slot
].
buttons_state
!=
s
->
queue
[
use_slot
].
buttons_state
)
{
/* Cannot or should not combine, so add an empty item to the queue. */
QUEUE_INCR
(
use_slot
);
hs
->
n
++
;
usb_pointer_event_clear
(
&
s
->
queue
[
use_slot
],
buttons_state
);
}
usb_pointer_event_combine
(
&
s
->
queue
[
use_slot
],
hs
->
kind
==
USB_MOUSE
,
x1
,
y1
,
z1
);
usb_hid_changed
(
hs
);
usb_hid_changed
(
hs
);
}
}
static
void
usb_tablet_event
(
void
*
opaque
,
static
void
usb_keyboard_event
(
void
*
opaque
,
int
keycode
)
int
x
,
int
y
,
int
dz
,
int
buttons_state
)
{
{
USBHIDState
*
hs
=
opaque
;
USBHIDState
*
hs
=
opaque
;
USBMouseState
*
s
=
&
hs
->
ptr
;
USBKeyboardState
*
s
=
&
hs
->
kbd
;
int
slot
;
s
->
x
=
x
;
s
->
y
=
y
;
s
->
dz
+=
dz
;
s
->
buttons_state
=
buttons_state
;
if
(
hs
->
n
==
QUEUE_LENGTH
)
{
fprintf
(
stderr
,
"usb-kbd: warning: key event queue full
\n
"
);
return
;
}
slot
=
(
hs
->
head
+
hs
->
n
)
&
QUEUE_MASK
;
hs
->
n
++
;
s
->
keycodes
[
slot
]
=
keycode
;
usb_hid_changed
(
hs
);
usb_hid_changed
(
hs
);
}
}
static
void
usb_keyboard_
event
(
void
*
opaque
,
int
keycode
)
static
void
usb_keyboard_
process_keycode
(
USBHIDState
*
hs
)
{
{
USBHIDState
*
hs
=
opaque
;
USBKeyboardState
*
s
=
&
hs
->
kbd
;
USBKeyboardState
*
s
=
&
hs
->
kbd
;
uint8_t
hid_code
,
key
;
uint8_t
hid_code
,
key
;
int
i
;
int
i
,
keycode
,
slot
;
if
(
hs
->
n
==
0
)
{
return
;
}
slot
=
hs
->
head
&
QUEUE_MASK
;
QUEUE_INCR
(
hs
->
head
);
hs
->
n
--
;
keycode
=
s
->
keycodes
[
slot
];
key
=
keycode
&
0x7f
;
key
=
keycode
&
0x7f
;
hid_code
=
usb_hid_usage_keys
[
key
|
((
s
->
modifiers
>>
1
)
&
(
1
<<
7
))];
hid_code
=
usb_hid_usage_keys
[
key
|
((
s
->
modifiers
>>
1
)
&
(
1
<<
7
))];
...
@@ -499,7 +549,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
...
@@ -499,7 +549,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
if
(
s
->
key
[
i
]
==
hid_code
)
{
if
(
s
->
key
[
i
]
==
hid_code
)
{
s
->
key
[
i
]
=
s
->
key
[
--
s
->
keys
];
s
->
key
[
i
]
=
s
->
key
[
--
s
->
keys
];
s
->
key
[
s
->
keys
]
=
0x00
;
s
->
key
[
s
->
keys
]
=
0x00
;
usb_hid_changed
(
hs
);
break
;
break
;
}
}
if
(
i
<
0
)
if
(
i
<
0
)
...
@@ -514,8 +563,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
...
@@ -514,8 +563,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
}
else
}
else
return
;
return
;
}
}
usb_hid_changed
(
hs
);
}
}
static
inline
int
int_clamp
(
int
val
,
int
vmin
,
int
vmax
)
static
inline
int
int_clamp
(
int
val
,
int
vmin
,
int
vmax
)
...
@@ -528,86 +575,96 @@ static inline int int_clamp(int val, int vmin, int vmax)
...
@@ -528,86 +575,96 @@ static inline int int_clamp(int val, int vmin, int vmax)
return
val
;
return
val
;
}
}
static
int
usb_
mouse
_poll
(
USBHIDState
*
hs
,
uint8_t
*
buf
,
int
len
)
static
int
usb_
pointer
_poll
(
USBHIDState
*
hs
,
uint8_t
*
buf
,
int
len
)
{
{
int
dx
,
dy
,
dz
,
b
,
l
;
int
dx
,
dy
,
dz
,
b
,
l
;
int
index
;
USBMouseState
*
s
=
&
hs
->
ptr
;
USBMouseState
*
s
=
&
hs
->
ptr
;
USBPointerEvent
*
e
;
if
(
!
s
->
mouse_grabbed
)
{
if
(
!
s
->
mouse_grabbed
)
{
qemu_activate_mouse_event_handler
(
s
->
eh_entry
);
qemu_activate_mouse_event_handler
(
s
->
eh_entry
);
s
->
mouse_grabbed
=
1
;
s
->
mouse_grabbed
=
1
;
}
}
dx
=
int_clamp
(
s
->
dx
,
-
127
,
127
);
/* When the buffer is empty, return the last event. Relative
dy
=
int_clamp
(
s
->
dy
,
-
127
,
127
);
movements will all be zero. */
dz
=
int_clamp
(
s
->
dz
,
-
127
,
127
);
index
=
(
hs
->
n
?
hs
->
head
:
hs
->
head
-
1
);
e
=
&
s
->
queue
[
index
&
QUEUE_MASK
];
s
->
dx
-=
dx
;
s
->
dy
-=
dy
;
s
->
dz
-=
dz
;
/* Appears we have to invert the wheel direction */
if
(
hs
->
kind
==
USB_MOUSE
)
{
dz
=
0
-
dz
;
dx
=
int_clamp
(
e
->
xdx
,
-
127
,
127
);
dy
=
int_clamp
(
e
->
ydy
,
-
127
,
127
);
e
->
xdx
-=
dx
;
e
->
ydy
-=
dy
;
}
else
{
dx
=
e
->
xdx
;
dy
=
e
->
ydy
;
}
dz
=
int_clamp
(
e
->
dz
,
-
127
,
127
);
e
->
dz
-=
dz
;
b
=
0
;
b
=
0
;
if
(
s
->
buttons_state
&
MOUSE_EVENT_LBUTTON
)
if
(
e
->
buttons_state
&
MOUSE_EVENT_LBUTTON
)
b
|=
0x01
;
b
|=
0x01
;
if
(
s
->
buttons_state
&
MOUSE_EVENT_RBUTTON
)
if
(
e
->
buttons_state
&
MOUSE_EVENT_RBUTTON
)
b
|=
0x02
;
b
|=
0x02
;
if
(
s
->
buttons_state
&
MOUSE_EVENT_MBUTTON
)
if
(
e
->
buttons_state
&
MOUSE_EVENT_MBUTTON
)
b
|=
0x04
;
b
|=
0x04
;
l
=
0
;
if
(
hs
->
n
&&
if
(
len
>
l
)
!
e
->
dz
&&
buf
[
l
++
]
=
b
;
(
hs
->
kind
==
USB_TABLET
||
(
!
e
->
xdx
&&
!
e
->
ydy
)))
{
if
(
len
>
l
)
/* that deals with this event */
buf
[
l
++
]
=
dx
;
QUEUE_INCR
(
hs
->
head
);
if
(
len
>
l
)
hs
->
n
--
;
buf
[
l
++
]
=
dy
;
if
(
len
>
l
)
buf
[
l
++
]
=
dz
;
return
l
;
}
static
int
usb_tablet_poll
(
USBHIDState
*
hs
,
uint8_t
*
buf
,
int
len
)
{
int
dz
,
b
,
l
;
USBMouseState
*
s
=
&
hs
->
ptr
;
if
(
!
s
->
mouse_grabbed
)
{
qemu_activate_mouse_event_handler
(
s
->
eh_entry
);
s
->
mouse_grabbed
=
1
;
}
}
dz
=
int_clamp
(
s
->
dz
,
-
127
,
127
);
s
->
dz
-=
dz
;
/* Appears we have to invert the wheel direction */
/* Appears we have to invert the wheel direction */
dz
=
0
-
dz
;
dz
=
0
-
dz
;
b
=
0
;
l
=
0
;
if
(
s
->
buttons_state
&
MOUSE_EVENT_LBUTTON
)
switch
(
hs
->
kind
)
{
b
|=
0x01
;
case
USB_MOUSE
:
if
(
s
->
buttons_state
&
MOUSE_EVENT_RBUTTON
)
if
(
len
>
l
)
b
|=
0x02
;
buf
[
l
++
]
=
b
;
if
(
s
->
buttons_state
&
MOUSE_EVENT_MBUTTON
)
if
(
len
>
l
)
b
|=
0x04
;
buf
[
l
++
]
=
dx
;
if
(
len
>
l
)
buf
[
l
++
]
=
dy
;
if
(
len
>
l
)
buf
[
l
++
]
=
dz
;
break
;
case
USB_TABLET
:
if
(
len
>
l
)
buf
[
l
++
]
=
b
;
if
(
len
>
l
)
buf
[
l
++
]
=
dx
&
0xff
;
if
(
len
>
l
)
buf
[
l
++
]
=
dx
>>
8
;
if
(
len
>
l
)
buf
[
l
++
]
=
dy
&
0xff
;
if
(
len
>
l
)
buf
[
l
++
]
=
dy
>>
8
;
if
(
len
>
l
)
buf
[
l
++
]
=
dz
;
break
;
buf
[
0
]
=
b
;
default:
buf
[
1
]
=
s
->
x
&
0xff
;
abort
();
buf
[
2
]
=
s
->
x
>>
8
;
}
buf
[
3
]
=
s
->
y
&
0xff
;
buf
[
4
]
=
s
->
y
>>
8
;
buf
[
5
]
=
dz
;
l
=
6
;
return
l
;
return
l
;
}
}
static
int
usb_keyboard_poll
(
USB
KeyboardState
*
s
,
uint8_t
*
buf
,
int
len
)
static
int
usb_keyboard_poll
(
USB
HIDState
*
h
s
,
uint8_t
*
buf
,
int
len
)
{
{
USBKeyboardState
*
s
=
&
hs
->
kbd
;
if
(
len
<
2
)
if
(
len
<
2
)
return
0
;
return
0
;
usb_keyboard_process_keycode
(
hs
);
buf
[
0
]
=
s
->
modifiers
&
0xff
;
buf
[
0
]
=
s
->
modifiers
&
0xff
;
buf
[
1
]
=
0
;
buf
[
1
]
=
0
;
if
(
s
->
keys
>
6
)
if
(
s
->
keys
>
6
)
...
@@ -643,12 +700,9 @@ static void usb_mouse_handle_reset(USBDevice *dev)
...
@@ -643,12 +700,9 @@ static void usb_mouse_handle_reset(USBDevice *dev)
{
{
USBHIDState
*
s
=
(
USBHIDState
*
)
dev
;
USBHIDState
*
s
=
(
USBHIDState
*
)
dev
;
s
->
ptr
.
dx
=
0
;
memset
(
s
->
ptr
.
queue
,
0
,
sizeof
(
s
->
ptr
.
queue
));
s
->
ptr
.
dy
=
0
;
s
->
head
=
0
;
s
->
ptr
.
dz
=
0
;
s
->
n
=
0
;
s
->
ptr
.
x
=
0
;
s
->
ptr
.
y
=
0
;
s
->
ptr
.
buttons_state
=
0
;
s
->
protocol
=
1
;
s
->
protocol
=
1
;
}
}
...
@@ -657,6 +711,11 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
...
@@ -657,6 +711,11 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
USBHIDState
*
s
=
(
USBHIDState
*
)
dev
;
USBHIDState
*
s
=
(
USBHIDState
*
)
dev
;
qemu_add_kbd_event_handler
(
usb_keyboard_event
,
s
);
qemu_add_kbd_event_handler
(
usb_keyboard_event
,
s
);
memset
(
s
->
kbd
.
keycodes
,
0
,
sizeof
(
s
->
kbd
.
keycodes
));
s
->
head
=
0
;
s
->
n
=
0
;
memset
(
s
->
kbd
.
key
,
0
,
sizeof
(
s
->
kbd
.
key
));
s
->
kbd
.
keys
=
0
;
s
->
protocol
=
1
;
s
->
protocol
=
1
;
}
}
...
@@ -708,12 +767,10 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value,
...
@@ -708,12 +767,10 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value,
}
}
break
;
break
;
case
GET_REPORT
:
case
GET_REPORT
:
if
(
s
->
kind
==
USB_MOUSE
)
if
(
s
->
kind
==
USB_MOUSE
||
s
->
kind
==
USB_TABLET
)
ret
=
usb_mouse_poll
(
s
,
data
,
length
);
ret
=
usb_pointer_poll
(
s
,
data
,
length
);
else
if
(
s
->
kind
==
USB_TABLET
)
ret
=
usb_tablet_poll
(
s
,
data
,
length
);
else
if
(
s
->
kind
==
USB_KEYBOARD
)
else
if
(
s
->
kind
==
USB_KEYBOARD
)
ret
=
usb_keyboard_poll
(
&
s
->
kbd
,
data
,
length
);
ret
=
usb_keyboard_poll
(
s
,
data
,
length
);
break
;
break
;
case
SET_REPORT
:
case
SET_REPORT
:
if
(
s
->
kind
==
USB_KEYBOARD
)
if
(
s
->
kind
==
USB_KEYBOARD
)
...
@@ -762,13 +819,13 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
...
@@ -762,13 +819,13 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
if
(
!
s
->
changed
&&
(
!
s
->
idle
||
s
->
next_idle_clock
-
curtime
>
0
))
if
(
!
s
->
changed
&&
(
!
s
->
idle
||
s
->
next_idle_clock
-
curtime
>
0
))
return
USB_RET_NAK
;
return
USB_RET_NAK
;
usb_hid_set_next_idle
(
s
,
curtime
);
usb_hid_set_next_idle
(
s
,
curtime
);
s
->
changed
=
0
;
if
(
s
->
kind
==
USB_MOUSE
||
s
->
kind
==
USB_TABLET
)
{
if
(
s
->
kind
==
USB_MOUSE
)
ret
=
usb_pointer_poll
(
s
,
p
->
data
,
p
->
len
);
ret
=
usb_mouse_poll
(
s
,
p
->
data
,
p
->
len
);
}
else
if
(
s
->
kind
==
USB_
TABLET
)
else
if
(
s
->
kind
==
USB_
KEYBOARD
)
{
ret
=
usb_
tablet
_poll
(
s
,
p
->
data
,
p
->
len
);
ret
=
usb_
keyboard
_poll
(
s
,
p
->
data
,
p
->
len
);
else
if
(
s
->
kind
==
USB_KEYBOARD
)
}
ret
=
usb_keyboard_poll
(
&
s
->
kbd
,
p
->
data
,
p
->
len
)
;
s
->
changed
=
s
->
n
>
0
;
}
else
{
}
else
{
goto
fail
;
goto
fail
;
}
}
...
@@ -803,13 +860,13 @@ static int usb_hid_initfn(USBDevice *dev, int kind)
...
@@ -803,13 +860,13 @@ static int usb_hid_initfn(USBDevice *dev, int kind)
s
->
kind
=
kind
;
s
->
kind
=
kind
;
if
(
s
->
kind
==
USB_MOUSE
)
{
if
(
s
->
kind
==
USB_MOUSE
)
{
s
->
ptr
.
eh_entry
=
qemu_add_mouse_event_handler
(
usb_
mouse
_event
,
s
,
s
->
ptr
.
eh_entry
=
qemu_add_mouse_event_handler
(
usb_
pointer
_event
,
s
,
0
,
"QEMU USB Mouse"
);
0
,
"QEMU USB Mouse"
);
}
else
if
(
s
->
kind
==
USB_TABLET
)
{
}
else
if
(
s
->
kind
==
USB_TABLET
)
{
s
->
ptr
.
eh_entry
=
qemu_add_mouse_event_handler
(
usb_
tablet
_event
,
s
,
s
->
ptr
.
eh_entry
=
qemu_add_mouse_event_handler
(
usb_
pointer
_event
,
s
,
1
,
"QEMU USB Tablet"
);
1
,
"QEMU USB Tablet"
);
}
}
/* Force poll routine to be run and grab input the first time. */
/* Force poll routine to be run and grab input the first time. */
s
->
changed
=
1
;
s
->
changed
=
1
;
return
0
;
return
0
;
...
@@ -838,12 +895,72 @@ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
...
@@ -838,12 +895,72 @@ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
s
->
datain
=
datain
;
s
->
datain
=
datain
;
}
}
static
int
usb_hid_post_load
(
void
*
opaque
,
int
version_id
)
{
USBHIDState
*
s
=
opaque
;
if
(
s
->
idle
)
{
usb_hid_set_next_idle
(
s
,
qemu_get_clock
(
vm_clock
));
}
return
0
;
}
static
const
VMStateDescription
vmstate_usb_ptr_queue
=
{
.
name
=
"usb-ptr-queue"
,
.
version_id
=
1
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_INT32
(
xdx
,
USBPointerEvent
),
VMSTATE_INT32
(
ydy
,
USBPointerEvent
),
VMSTATE_INT32
(
dz
,
USBPointerEvent
),
VMSTATE_INT32
(
buttons_state
,
USBPointerEvent
),
VMSTATE_END_OF_LIST
()
}
};
static
const
VMStateDescription
vmstate_usb_ptr
=
{
.
name
=
"usb-ptr"
,
.
version_id
=
1
,
.
minimum_version_id
=
1
,
.
post_load
=
usb_hid_post_load
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_USB_DEVICE
(
dev
,
USBHIDState
),
VMSTATE_STRUCT_ARRAY
(
ptr
.
queue
,
USBHIDState
,
QUEUE_LENGTH
,
0
,
vmstate_usb_ptr_queue
,
USBPointerEvent
),
VMSTATE_UINT32
(
head
,
USBHIDState
),
VMSTATE_UINT32
(
n
,
USBHIDState
),
VMSTATE_INT32
(
protocol
,
USBHIDState
),
VMSTATE_UINT8
(
idle
,
USBHIDState
),
VMSTATE_END_OF_LIST
()
}
};
static
const
VMStateDescription
vmstate_usb_kbd
=
{
.
name
=
"usb-kbd"
,
.
version_id
=
1
,
.
minimum_version_id
=
1
,
.
post_load
=
usb_hid_post_load
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_USB_DEVICE
(
dev
,
USBHIDState
),
VMSTATE_UINT32_ARRAY
(
kbd
.
keycodes
,
USBHIDState
,
QUEUE_LENGTH
),
VMSTATE_UINT32
(
head
,
USBHIDState
),
VMSTATE_UINT32
(
n
,
USBHIDState
),
VMSTATE_UINT16
(
kbd
.
modifiers
,
USBHIDState
),
VMSTATE_UINT8
(
kbd
.
leds
,
USBHIDState
),
VMSTATE_UINT8_ARRAY
(
kbd
.
key
,
USBHIDState
,
16
),
VMSTATE_INT32
(
kbd
.
keys
,
USBHIDState
),
VMSTATE_INT32
(
protocol
,
USBHIDState
),
VMSTATE_UINT8
(
idle
,
USBHIDState
),
VMSTATE_END_OF_LIST
()
}
};
static
struct
USBDeviceInfo
hid_info
[]
=
{
static
struct
USBDeviceInfo
hid_info
[]
=
{
{
{
.
product_desc
=
"QEMU USB Tablet"
,
.
product_desc
=
"QEMU USB Tablet"
,
.
qdev
.
name
=
"usb-tablet"
,
.
qdev
.
name
=
"usb-tablet"
,
.
usbdevice_name
=
"tablet"
,
.
usbdevice_name
=
"tablet"
,
.
qdev
.
size
=
sizeof
(
USBHIDState
),
.
qdev
.
size
=
sizeof
(
USBHIDState
),
.
qdev
.
vmsd
=
&
vmstate_usb_ptr
,
.
usb_desc
=
&
desc_tablet
,
.
usb_desc
=
&
desc_tablet
,
.
init
=
usb_tablet_initfn
,
.
init
=
usb_tablet_initfn
,
.
handle_packet
=
usb_generic_handle_packet
,
.
handle_packet
=
usb_generic_handle_packet
,
...
@@ -856,6 +973,7 @@ static struct USBDeviceInfo hid_info[] = {
...
@@ -856,6 +973,7 @@ static struct USBDeviceInfo hid_info[] = {
.
qdev
.
name
=
"usb-mouse"
,
.
qdev
.
name
=
"usb-mouse"
,
.
usbdevice_name
=
"mouse"
,
.
usbdevice_name
=
"mouse"
,
.
qdev
.
size
=
sizeof
(
USBHIDState
),
.
qdev
.
size
=
sizeof
(
USBHIDState
),
.
qdev
.
vmsd
=
&
vmstate_usb_ptr
,
.
usb_desc
=
&
desc_mouse
,
.
usb_desc
=
&
desc_mouse
,
.
init
=
usb_mouse_initfn
,
.
init
=
usb_mouse_initfn
,
.
handle_packet
=
usb_generic_handle_packet
,
.
handle_packet
=
usb_generic_handle_packet
,
...
@@ -868,6 +986,7 @@ static struct USBDeviceInfo hid_info[] = {
...
@@ -868,6 +986,7 @@ static struct USBDeviceInfo hid_info[] = {
.
qdev
.
name
=
"usb-kbd"
,
.
qdev
.
name
=
"usb-kbd"
,
.
usbdevice_name
=
"keyboard"
,
.
usbdevice_name
=
"keyboard"
,
.
qdev
.
size
=
sizeof
(
USBHIDState
),
.
qdev
.
size
=
sizeof
(
USBHIDState
),
.
qdev
.
vmsd
=
&
vmstate_usb_kbd
,
.
usb_desc
=
&
desc_keyboard
,
.
usb_desc
=
&
desc_keyboard
,
.
init
=
usb_keyboard_initfn
,
.
init
=
usb_keyboard_initfn
,
.
handle_packet
=
usb_generic_handle_packet
,
.
handle_packet
=
usb_generic_handle_packet
,
...
...
hw/usb-hub.c
浏览文件 @
cfb41c82
...
@@ -544,11 +544,35 @@ static int usb_hub_initfn(USBDevice *dev)
...
@@ -544,11 +544,35 @@ static int usb_hub_initfn(USBDevice *dev)
return
0
;
return
0
;
}
}
static
const
VMStateDescription
vmstate_usb_hub_port
=
{
.
name
=
"usb-hub-port"
,
.
version_id
=
1
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_UINT16
(
wPortStatus
,
USBHubPort
),
VMSTATE_UINT16
(
wPortChange
,
USBHubPort
),
VMSTATE_END_OF_LIST
()
}
};
static
const
VMStateDescription
vmstate_usb_hub
=
{
.
name
=
"usb-hub"
,
.
version_id
=
1
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_USB_DEVICE
(
dev
,
USBHubState
),
VMSTATE_STRUCT_ARRAY
(
ports
,
USBHubState
,
NUM_PORTS
,
0
,
vmstate_usb_hub_port
,
USBHubPort
),
VMSTATE_END_OF_LIST
()
}
};
static
struct
USBDeviceInfo
hub_info
=
{
static
struct
USBDeviceInfo
hub_info
=
{
.
product_desc
=
"QEMU USB Hub"
,
.
product_desc
=
"QEMU USB Hub"
,
.
qdev
.
name
=
"usb-hub"
,
.
qdev
.
name
=
"usb-hub"
,
.
qdev
.
fw_name
=
"hub"
,
.
qdev
.
fw_name
=
"hub"
,
.
qdev
.
size
=
sizeof
(
USBHubState
),
.
qdev
.
size
=
sizeof
(
USBHubState
),
.
qdev
.
vmsd
=
&
vmstate_usb_hub
,
.
usb_desc
=
&
desc_hub
,
.
usb_desc
=
&
desc_hub
,
.
init
=
usb_hub_initfn
,
.
init
=
usb_hub_initfn
,
.
handle_packet
=
usb_hub_handle_packet
,
.
handle_packet
=
usb_hub_handle_packet
,
...
...
hw/usb.h
浏览文件 @
cfb41c82
...
@@ -165,13 +165,13 @@ struct USBDevice {
...
@@ -165,13 +165,13 @@ struct USBDevice {
int
auto_attach
;
int
auto_attach
;
int
attached
;
int
attached
;
int
state
;
int
32_t
state
;
uint8_t
setup_buf
[
8
];
uint8_t
setup_buf
[
8
];
uint8_t
data_buf
[
1024
];
uint8_t
data_buf
[
1024
];
int
remote_wakeup
;
int
32_t
remote_wakeup
;
int
setup_state
;
int
32_t
setup_state
;
int
setup_len
;
int
32_t
setup_len
;
int
setup_index
;
int
32_t
setup_index
;
QLIST_HEAD
(,
USBDescString
)
strings
;
QLIST_HEAD
(,
USBDescString
)
strings
;
const
USBDescDevice
*
device
;
const
USBDescDevice
*
device
;
...
...
ui/vnc.c
浏览文件 @
cfb41c82
...
@@ -1504,7 +1504,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
...
@@ -1504,7 +1504,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
break
;
break
;
}
}
if
(
vs
->
vd
->
lock_key_sync
&&
if
(
down
&&
vs
->
vd
->
lock_key_sync
&&
keycode_is_keypad
(
vs
->
vd
->
kbd_layout
,
keycode
))
{
keycode_is_keypad
(
vs
->
vd
->
kbd_layout
,
keycode
))
{
/* If the numlock state needs to change then simulate an additional
/* If the numlock state needs to change then simulate an additional
keypress before sending this one. This will happen if the user
keypress before sending this one. This will happen if the user
...
@@ -1523,7 +1523,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
...
@@ -1523,7 +1523,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
}
}
}
}
if
(
vs
->
vd
->
lock_key_sync
&&
if
(
down
&&
vs
->
vd
->
lock_key_sync
&&
((
sym
>=
'A'
&&
sym
<=
'Z'
)
||
(
sym
>=
'a'
&&
sym
<=
'z'
)))
{
((
sym
>=
'A'
&&
sym
<=
'Z'
)
||
(
sym
>=
'a'
&&
sym
<=
'z'
)))
{
/* If the capslock state needs to change then simulate an additional
/* If the capslock state needs to change then simulate an additional
keypress before sending this one. This will happen if the user
keypress before sending this one. This will happen if the user
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录