This patch adds libvirt_domain_send_key_api which calls to virDomainSendKey libvirt API function to send key press events to a domain. The PHP bindings already have libvirt_domain_send_keys function which uses VNC to provide similar functionality but that has limited use cases and depends on a command line VNC client as well as VNC server being present which is not always the case. --- src/libvirt-php.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/libvirt-php.h | 1 + 2 files changed, 77 insertions(+) diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 8602b93..bf73f43 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -405,6 +405,14 @@ ZEND_ARG_INFO(0, server) ZEND_ARG_INFO(0, scancode) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_domain_send_key_api, 0, 0, 4) +ZEND_ARG_INFO(0, conn) +ZEND_ARG_INFO(0, codeset) +ZEND_ARG_INFO(0, holdime) +ZEND_ARG_INFO(0, keycodes) +ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_domain_send_pointer_event, 0, 0, 5) ZEND_ARG_INFO(0, conn) ZEND_ARG_INFO(0, server) @@ -624,6 +632,7 @@ static zend_function_entry libvirt_functions[] = { PHP_FE(libvirt_domain_get_screenshot_api, arginfo_libvirt_domain_get_screenshot_api) PHP_FE(libvirt_domain_get_screen_dimensions, arginfo_libvirt_domain_get_screen_dimensions) PHP_FE(libvirt_domain_send_keys, arginfo_libvirt_domain_send_keys) + PHP_FE(libvirt_domain_send_key_api, arginfo_libvirt_domain_send_key_api) PHP_FE(libvirt_domain_send_pointer_event, arginfo_libvirt_domain_send_pointer_event) PHP_FE(libvirt_domain_update_device, arginfo_libvirt_domain_update_device) /* Domain snapshot functions */ @@ -1988,6 +1997,18 @@ PHP_MINIT_FUNCTION(libvirt) /* Connect flags */ REGISTER_LONG_CONSTANT("VIR_CONNECT_FLAG_SOUNDHW_GET_NAMES", CONNECT_FLAG_SOUNDHW_GET_NAMES, CONST_CS | CONST_PERSISTENT); + /* Keycodeset constants */ + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_LINUX", VIR_KEYCODE_SET_LINUX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_XT", VIR_KEYCODE_SET_XT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_ATSET1", VIR_KEYCODE_SET_ATSET1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_ATSET2", VIR_KEYCODE_SET_ATSET2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_ATSET3", VIR_KEYCODE_SET_ATSET3, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_OSX", VIR_KEYCODE_SET_OSX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_XT_KBD", VIR_KEYCODE_SET_XT_KBD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_USB", VIR_KEYCODE_SET_USB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_WIN32", VIR_KEYCODE_SET_WIN32, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VIR_KEYCODE_SET_RFB", VIR_KEYCODE_SET_RFB, CONST_CS | CONST_PERSISTENT); + REGISTER_INI_ENTRIES(); /* Initialize libvirt and set up error callback */ @@ -5061,6 +5082,61 @@ PHP_FUNCTION(libvirt_domain_send_keys) } /* + * Function name: libvirt_domain_send_key_api + * Since version: 0.5.3 + * Description: Function sends keys to domain via libvirt API + * Arguments: @res[resource]: libvirt domain resource, e.g. from libvirt_domaing_lookup_by_*() + * @codeset [int]: the codeset of keycodes, from virKeycodeSet + * @holdtime [int]: the duration (in miliseconds) that the keys will be held + * @keycodes [array]: array of keycodes + * @flags [int]: extra flags; not used yet so callers should alway pass 0 + * Returns: TRUE for success, FALSE for failure + */ +PHP_FUNCTION(libvirt_domain_send_key_api) +{ + php_libvirt_domain *domain = NULL; + zval *zdomain; + zend_long codeset; + zend_long holdtime = 0; + zend_long flags = 0; + zval *zkeycodes, *data = NULL; + HashTable *arr_hash = NULL; + HashPosition pointer; + int count, i; + uint *keycodes = NULL; + + GET_DOMAIN_FROM_ARGS("rlla|l", &zdomain, &codeset, &holdtime, &zkeycodes, + &flags); + + arr_hash = Z_ARRVAL_P(zkeycodes); + count = zend_hash_num_elements(arr_hash); + + keycodes = (uint *) emalloc(count * sizeof(uint)); + + i = 0; + for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); +#if PHP_MAJOR_VERSION >= 7 + (data = zend_hash_get_current_data_ex(arr_hash, &pointer)) != NULL; +#else + zend_hash_get_current_data_ex(arr_hash, (void **) &data, &pointer) == SUCCESS; +#endif + zend_hash_move_forward_ex(arr_hash, &pointer)) { + if (Z_TYPE_P(data) == IS_LONG) { + keycodes[i++] = (uint) Z_LVAL_P(data); + } + } + + if (virDomainSendKey(domain->domain, codeset, holdtime, keycodes, count, + flags) != 0) { + efree(keycodes); + RETURN_FALSE; + } + + efree(keycodes); + RETURN_TRUE; +} + +/* * Function name: libvirt_domain_send_pointer_event * Since version: 0.4.2 * Description: Function sends keys to the domain's VNC window diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 9f89ddd..eac3ed5 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -440,6 +440,7 @@ PHP_FUNCTION(libvirt_domain_set_autostart); PHP_FUNCTION(libvirt_domain_is_active); PHP_FUNCTION(libvirt_domain_get_next_dev_ids); PHP_FUNCTION(libvirt_domain_send_keys); +PHP_FUNCTION(libvirt_domain_send_key_api); PHP_FUNCTION(libvirt_domain_send_pointer_event); PHP_FUNCTION(libvirt_domain_get_metadata); PHP_FUNCTION(libvirt_domain_set_metadata); -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list