[libvirt] [libvirt-php PATCH 3/4] implement libvirt_domain_send_key_api

Dawid Zamirski dzamirski at datto.com
Wed Jun 29 16:29:59 UTC 2016


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




More information about the libvir-list mailing list