@@ -1810,16 +1810,25 @@ static uint8_t keycodes[MAX_KEYCODES];
static int nb_pending_keycodes;
static QEMUTimer *key_timer;
-static void release_keys(void *opaque)
+static void keydown(uint8_t keycode)
{
- int keycode;
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode & 0x7f);
+}
+static void keyup(uint8_t keycode)
+{
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80);
+}
+
+static void release_keys(void *opaque)
+{
while (nb_pending_keycodes > 0) {
nb_pending_keycodes--;
- keycode = keycodes[nb_pending_keycodes];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80);
+ keyup(keycodes[nb_pending_keycodes]);
}
}
@@ -1866,17 +1875,41 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
}
nb_pending_keycodes = i;
/* key down events */
- for (i = 0; i < nb_pending_keycodes; i++) {
- keycode = keycodes[i];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f);
- }
+ for (i = 0; i < nb_pending_keycodes; i++)
+ keydown(keycodes[i]);
/* delayed key up events */
qemu_mod_timer(key_timer, qemu_get_clock(vm_clock) +
muldiv64(get_ticks_per_sec(), hold_time, 1000));
}
+static int qmp_keyaction(const QDict *qdict, int down)
+{
+ int keycode = qdict_get_int(qdict, "keycode");
+
+ if (keycode < 0 || keycode >= 256) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "keycode",
+ "a valid keycode");
+ return -1;
+ }
+
+ if (down)
+ keydown(keycode);
+ else
+ keyup(keycode);
+
+ return 0;
+}
+
+static int qmp_keydown(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+ return qmp_keyaction(qdict, 1);
+}
+
+static int qmp_keyup(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+ return qmp_keyaction(qdict, 0);
+}
+
static int mouse_button_state;
static void do_mouse_move(Monitor *mon, const QDict *qdict)
@@ -338,6 +338,58 @@ Example:
EQMP
{
+ .name = "keydown",
+ .args_type = "keycode:i",
+ .params = "keycode",
+ .help = "press down a key",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = qmp_keydown,
+ },
+
+SQMP
+keydown
+---
+
+Press down a key.
+
+Arguments:
+
+- "keycode": the code of the key to press down (json-int)
+
+Example:
+
+-> { "execute": "keydown", "arguments": { "keycode": 16 } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "keyup",
+ .args_type = "keycode:i",
+ .params = "keycode",
+ .help = "release a key",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = qmp_keyup,
+ },
+
+SQMP
+keyup
+---
+
+Release a key.
+
+Arguments:
+
+- "keycode": the code of the key to release (json-int)
+
+Example:
+
+-> { "execute": "keyup", "arguments": { "keycode": 16 } }
+<- { "return": {} }
+
+EQMP
+
+ {
.name = "cpu",
.args_type = "index:i",
.params = "index",