From f20d14c915524a896e261cb30c46439a2aa749f8 Mon Sep 17 00:00:00 2001 From: Thiago Mendes Date: Mon, 10 Jul 2017 14:01:45 -0500 Subject: [PATCH 3/3] Converting Vd_interfaces.odt to Asciidoc https://bugs.freedesktop.org/show_bug.cgi?id=95258 --- docs/Makefile.am | 8 +- docs/Vd_interfaces.adoc | 643 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 649 insertions(+), 2 deletions(-) create mode 100644 docs/Vd_interfaces.adoc diff --git a/docs/Makefile.am b/docs/Makefile.am index d8ee4cb7..9c743aae 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -6,12 +6,13 @@ EXTRA_DIST = \ spice_style.txt \ Spice_for_newbies.adoc \ Spice_protocol.adoc \ + Vd_interfaces.adoc \ $(NULL) if BUILD_MANUAL SUBDIRS = manual -all-local: spice_style.html Spice_for_newbies.html Spice_protocol.html +all-local: spice_style.html Spice_for_newbies.html Spice_protocol.html Vd_interfaces.html spice_style.html: spice_style.txt $(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $< @@ -22,7 +23,10 @@ Spice_for_newbies.html: Spice_for_newbies.adoc Spice_protocol.html: Spice_protocol.adoc $(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $< +Vd_interfaces.html: Vd_interfaces.adoc + $(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $< + endif clean-local: - rm -f spice_style.html Spice_for_newbies.html Spice_protocol.html + rm -f spice_style.html Spice_for_newbies.html Spice_protocol.html Vd_interfaces.html diff --git a/docs/Vd_interfaces.adoc b/docs/Vd_interfaces.adoc new file mode 100644 index 00000000..8d7b03c8 --- /dev/null +++ b/docs/Vd_interfaces.adoc @@ -0,0 +1,643 @@ += VD Interfaces V0.1: Red Hat, Inc +:revnumber: v1.0 +:revdate: 01.01.2009 +:revremark: Draft 1 + +Copyright (C) 2009 Red Hat, Inc. +· +Licensed under a Creative Commons Attribution-Share Alike 3.0 +· +United States License (see +http://creativecommons.org/licenses/by-sa/3.0/us/legalcode). +· + +:toc: + +== Introduction + +Virtual Device Interfaces (VDI) provide a standard way to publish interfaces of +virtual devices by a software component. This enables other software components +to interact with these devices. This also enables other software components to +interact with these devices. Going forward, the first component will be called +the back-end and the second component will be called the front-end. An example +for using Virtual Device Interfaces is as part of a virtual machine system, +where the back-end will be the hardware emulation layer. The back-end will +expose interfaces like display port, mouse input etc. The front-end will plug +into the display output and will render its output according to it's specific +implementation. The front-end will also plug into the mouse input and send +mouse events to be processed by the back-end. In addition many other interface +types can be exposed by the back-end. Another example of back-end is a remote +display system in a physical machine environment. Here, the back-and is +implemented using known techniques for interacting with the native OS for the +purpose of receiving display updates and pushing inputs. The back-end exposes +interfaces like display output, mouse input etc. The front-end can be exactly +the same as in the previous example. + +By using VDI one back-end can use many types of front-ends without any special +code modification. It is also possible for the back-end to dynamically switch +front-ends, and improve back-end usability and flexibility. The use of +front-ends by many back-ends allows for a better sharing of development, +maintenance, and overall product quality. + +== Basic operation + +Back-end to front-end interaction is initiated by back-end. Back-end uses +VDI_init symbol to pass its Core interface to the front-end. In addition to +core interface, back-end also passes options argument to the front-end. Options +argument is a string holding initialization argument specific to front-end +implementation. Core interface, like every other interface in VDI, is +represented as a data structure containing data members and member functions. +Every interface starts with a common base structure “VDInterface”. The common +structure contains information for identifying the type of the interface and +the instance within the type group (i.e. The actual unique is {type, id}). Core +interface provides basic functionality for attaching with other interfaces that +the back-end implements. Core interface provides methods for receiving +interface change events (i.e. interface added event and removing interface +event) and for enumerating registers. Using these services, the front-end can +find and interact with other interfaces that back-end publishes. The front-end +uses VDI type for knowing what functionality the interface provides and the +means to interact with the interface (i.e interface specific logic function and +data members). + +== Front-end public symbols + +VDI defines a minimal set of external symbols for enabling back-end to initiate +with the front-end. The back-end can load front-end and retrieve front-end +external symbols dynamically at run-time using native platform services. +Alternatively, the front-end static or shared library can be linked to the +back-end during back-end build process. + +[source,c] +---- +int VDI_init(const char *args, CoreInterface *core) +---- + +Front-and initialization function. The first parameter is options argument, the +content of which depends on the specific front-end. The second parameter is +core interface that provides the basic communication channel between front-end +and back-end, core interface will be explained later on. VDI_init return value +is VDI_ERROR_? + +[source,c] +---- +const char **VDI_get_usage() +---- + +This function return array of strings in human readable form for displaying the +available options argument that can be pass in args parameter of VDI_init call. + +== Front-end termination + +No explicit symbol is defined for front-end termination. Removing core +interface by back-end implicitly instructs front end to terminate itself. + +== Common Definition + +[source,c] +---- +VDI_ERROR_OK = 0 +VDI_ERROR_ERROR = -1 +VM_INTERFACE_VERSION = 2 /*Current VDI version, front-end an back-end must have +the same VDI version for proper operation. */ +---- +---- +VDIObjectRef – opaque object reference that passes between back-end and +front-end +---- +[source,c] +---- +VDI_INVALID_OBJECT_REF = 0 +---- +== Base structure of VD interface. + +The following is definition of VD Interface, all VDI interfaces are derived +from VD Interface. + +[source,c] +---- +UINT32 version; /* VDI version must be VM_INTERFACE_VERSION */ +CONST CHAR *type; /* type of the interface */ +UNSIGNED INT id; /* unique id of the interface */ +CONST CHAR *description; /* interface human readable interface description* +UINT32 major_version; /* interface major version. Front-end and back-end +interfaces having different major_version are not compatible. */ +UINT32 minor_version; /* interface minor version. Minor version increments on +changes that add functionality but do not break compatible and will be reset on +major version increment. */ +---- + +== Core Interface + +Core interface is the main interface for front-end to back-end communication. +It is not allowed to have more the one interface with this type. Removal of +Core interface by the back-end is explicit front-end termination. + +. VDInterface members value ++ +---- +type = “core” +major_version = 1 +minor_version = 0 +id = 0 +---- ++ +. Types ++ +[source,c] +---- +VDI_CHANGE_NEW = 0 +VDI_CHANGE_REMOVING = 1 +---- ++ +[source,c] +---- +void (*vdi_interface_change_notifier_t)(void *opaque, VDInterface *interface, +VDInterfaceChangeType change) +---- ++ +Callback for receiving notification event on adding and removing VDI +interfaces. ++ +* opaque – back-end passes front-end's opaque value that was passed during +notifier registration. +* interface - the relevant interface +* change – type of change VDI_CHANGE_NEW or VDI_CHANGE_REMOVING + ++ +[source,c] +---- +void (*timer_callback_t)(void *opaque) +---- ++ +Callback for receiving timer event. ++ +* opaque – back-end passes front-end's opaque value that was passed during +timer registration. + ++ +---- +VDI_LOG_LEVEL_ERROR = 1 +VDI_LOG_LEVEL_WARN = 2 +VDI_LOG_LEVEL_INFO = 3 +---- ++ +[source,c] +---- +VDInterface specific extension +VDInterface *(* next)(CoreInterface *core, VDInterface *prev) +---- ++ +Get next interface – return interface following prev. If prev is NULL return +first interface. If next return NULL then prev is the last interface. The +function is used for interfaces discovery. ++ +[source,c] +---- +VDIObjectRef (*register_change_notifier)(CoreInterface *core, void *opaque, +vdi_interface_change_notifier_t in_notifier) +---- ++ +Register in_notifier to be called on interface change events. opaque will be +pushed back by back-end in notify call. On success the function return notifier +object ref otherwise VDI_INVALID_OBJECT_REF is returned. ++ +[source,c] +---- +void (*unregister_change_notifiers)(CoreInterface *core, VDObjectRef notifier) +---- ++ +Unregister interface change notifier hat was registered using +register_change_notifiers. ++ +[source,c] +---- +VDIObjectRef (*create_timer)(CoreInterface *core, timer_callback_t callback, +void* opaque) +---- ++ +Create timer object. The timer handler will call callback on time expiration. +opaque will be pushed back by back-end in callback call. On success the +function return timer object ref otherwise VDI_INVALID_OBJECT_REF is returned ++ +[source,c] +---- +void (*arm_timer)(CoreInterface *core, VDIObjectRef timer, uint32_t ms) +---- ++ +Schedule timer object to fire it's callback after ms. Timer is VDI ref object +returned by create_timer and ms is time in millisecond. ++ +[source,c] +---- +void (*disarm_timer)(CoreInterface *core, VDIObjectRef timer) +---- ++ +Cancel previous arm_timer scheduling. Timer is VDI ref object returned by +create_timer ++ +[source,c] +---- +void (*destroy_timer)(CoreInterface *core, VDIObjectRef timer) +---- ++ +Destroy timer object. Timer is vdi ref object returned by create_timer. ++ +[source,c] +---- +int (*set_file_handlers)(CoreInterface *core, int fd, void (*on_read)(void *), +void (*on_write)(void *), void *opaque) +---- ++ +Request notification on file descriptor for non blocking operation. Fd is the +target file descriptor. Back-end will call on_read, if not NULL, on read events +passing opaque as first argument. Back-end will call on_write, if not NULL, on +write events passing opaque as first argument. On success VDI_ERROR_OK is +return. ++ +[source,c] +---- +void (*term_printf)(CoreInterface *core, const char* format, ...) +---- ++ +Send message to back-end interactive terminal if exist. format is printf +format, following format are variable arguments list that are format +arguments. ++ +[source,c] +---- +void (*log)(CoreInterface *core, LogLevel level, const char* component, const +char* format, ...) +---- ++ +Send message to be logged using back-end logging service. Level is one of +VDI_LOG_LEVEL_?. Component is component name that will be attached as prefix +to the message. Format is printf format, following format are variable +arguments list that are format arguments. +Callback + +== Other interfaces + +Core interface is the only interface that is an integral part of VDI +specifications. Any other interface can be defined independently of this +specification. It's required that both the back-and the front-end know specific +interface definitions for proper operation. The only restriction for defining +new interface is to ensure the uniqueness of VD Interface type. The following +interfaces are known VD interfaces that discussed here as a reference for +better understanding of the specification. + +== Keyboard interface + +Keyboard interface exposes standard keyboard functionally. It enables pushing +scan-code set 1 codes and getting keyboard LED information by query or change +notifications mechanism. + +. VDInterface members value ++ +[source,c] +---- +type = “keyboard” +major_version = 1 +minor_version = 0 +id = keyboard instance id +---- ++ +. Types ++ +[source,c] +---- +VDI_KEYBOARD_LED_SCROLL_LOCK 0 +VDI_KEYBOARD_LED_NUM_LOCK 1 +VDI_KEYBOARD_LED_CAPS_LOCK 2 +---- ++ +[source,c] +---- +void (*keyboard_leads_notifier_t)(void *opaque, uint8_t leds) +---- ++ +Callback for receiving notification event on keyboard LED changes. ++ +* opaque – back-end passed front-end's opaque value that was passed during +notifier registration. +* leds – current LED state mask. LED X is on if bit VDI_KEYBOARD_LED_X is set. + ++ +. VDInterface specific extension ++ +[source,c] +---- +void (*push_scan_freg)(KeyboardInterface *keyboard, uint8_t frag) +---- ++ +Push scan-code code fragment to the keyboard. Frag is part of scan code. +For example calling: ++ +[source,c] +---- +push_scan_freg(0xe0); +push_scan_freg(0x1d); +---- ++ +will result with Right CTRL. ++ +[source,c] +---- +uint8_t (*get_leds)(KeyboardInterface *keyboard) +---- ++ +Get current keyboard lads mask. Return lads mask ++ +[source,c] +---- +VDIObjectRef (*register_leds_notifier)(KeyboardInterface *keyboard, +keyboard_leads_notifier_t notifier, void *opaque) +---- ++ +Register for LED notification. Back-end will call notifier on every keyboard +LED change. Opaque will be pushed back as notifier argument. On success, the +function return notifier object ref otherwise VDI_INVALID_OBJECT_REF is +returned. ++ +[source,c] +---- +void (*unregister_leds_notifier)(KeyboardInterface *keyboard, VDObjectRef +notifier) +---- ++ +Unregister LED change notifier that was registered using +register_leds_notifier. + +== Mouse interface + +Mouse interface for pushing mouse motion and mouse buttons state events. + +. VDInterface members value ++ +[source,c] +---- +type = “mouse” +major_version = 1 +minor_version = 0 +id = mouse instance id +---- ++ +. Types ++ +[source,c] +---- +VDI_MOUSE_BUTTON_LEFT 0 +VDI_MOUSE_BUTTON_RIGHT 1 +VDI_MOUSE_BUTTON_MIDEL 2 +---- ++ +. VDInterface specific extension ++ +[source,c] +---- +void (*motion)(MouseInterface* mouse, int dx, int dy, int dz, uint32_t +buttons_state) +---- ++ +Push mouse motion and buttons state. dx and dy are mouse motion in pixels in x +and y axis, positive dx is rightward motion and positive dy is downward motion. +dz is scroll wheel ticks, positive value is scroll down. buttons_state is +buttons state mask. Button X is press if bit VDI_MOUSE_BUTTON_X is set. ++ +[source,c] +---- +void (*buttons)(MouseInterface* mouse, uint32_t buttons_state) +---- ++ +Push mouse buttons state. buttons_state is the same as in the motion call + +== Tablet interface + +Tablet interface for supporting absolute mouse pointing. + +. Interface members value ++ +[source,c] +---- +type = “tablet” +major_version = 1 +minor_version = 0 +id = tablet instance id +---- ++ +. Types ++ +[source,c] +---- +VDI_TABLET_BUTTON_LEFT 0 +VDI_TABLET_BUTTON_RIGHT 1 +VDI_TABLET_BUTTON_MIDEL 2 +---- ++ +. VDInterface specific extension ++ +[source,c] +---- +void (*set_logical_size)(TabletInterface* tablet, int width, int height) +---- ++ +Set logical dimension of the tablet. The logical dimension will be used by the +tablet device for mapping position to local coordinate system. ++ +[source,c] +---- +void (*position)(TabletInterface* tablet, int x, int y, uint32_t buttons_state) +---- ++ +Push mouse position and mouse button state. {x, y} position is relative to the +upper left corner. Positive value on x axis advances rightward and positive +value on y axis advances downward. buttons_state is buttons state mask. Button +X is press if bit VDI_TABLET_BUTTON_X is set. ++ +[source,c] +---- +void (*wheel)(TabletInterface* tablet, int wheel_motion, uint32_t +buttons_state) +---- ++ +Push scroll wheel motion and buttons state. wheel_motion is scroll sicks. +positive wheel_motion is for scroll down. buttons_state is as in “position” ++ +[source,c] +---- +void (*buttons)(TabletInterface* tablet, uint32_t buttons_state) +---- ++ +Push buttons state. buttons_state is as in “position” + +== Playback interface + +Playback interface for receiving audio stream for playback. Playback use fix +audio configuration, channels = 2, frequency = 44100 and channel sample +format signed 16bit. + +. VDInterface members value ++ +[source,c] +---- +type = “playback” +major_version = 1 +minor_version = 0 +id = playback instance id +---- ++ +. PlaybackPlug ++ +[source,c] +---- +uint32_t major_version +---- ++ +plug major version. Changing major version breaks compatibility. ++ +[source,c] +---- +uint32_t minor_version +---- ++ +interface minor version. Minor version increments on changes that add +functionality but do not break compatible and will be reset on major version +increment. ++ +[source,c] +---- +void (*start)(PlaybackPlug *plug) +---- ++ +back-end will call this callback while staring audio playback ++ +[source,c] +---- +void (*stop)(PlaybackPlug *plug) +---- ++ +back-end will call this callback while stopping audio playback ++ +[source,c] +---- +void (*get_frame)(PlaybackPlug *plug, uint32_t **frame, uint32_t *samples) +---- ++ +back-end will call this callback for getting audio frame. On return *frame will +point to audio frame capable of holding *samples samples (i.e frame size is +samples * 4). The frame will be pushed back filled with audio samples by the +back-end. If no frame is available *frame will be NULL. ++ +[source,c] +---- +void (*put_frame)(PlaybackPlug *plug, uint32_t *frame) +---- ++ +back-end will call this callback to deliver audio frame for playback. Frame is +one that was returns by get_frame. This call also moves frame ownership back to +the front-end. + +. VDInterface specific extension ++ +[source,c] +---- +VDIObjectRef (*plug)(PlaybackInterface *playback, PlaybackPlug* plug, int +*active) +---- ++ +Attach playback plug to playback interface instance. Plug is the plug to +attach. On return, active will be 0 if playback is stopped and 1 if playback is +running. On success, the function return object ref otherwise +VDI_INVALID_OBJECT_REF is returned. ++ +[source,c] +---- +void (*unplug)(PlaybackInterface *playback, VDIObjectRef) +---- ++ +Unplug playback that was plugged using plug. + +== Record interface + +Record interface for pushing audio capture to back-end. Record use fix audio +configuration, channels = 2, frequency = 44100 and channel sample format +signed 16bit. + +. VDInterface members value ++ +[source,c] +---- +type = “record” +major_version = 1 +minor_version = 0 +id = record instance id +---- + +. RecordPlug ++ +[source,c] +---- +uint32_t minor_version +---- ++ +plug major version. Changing major version breaks compatibility. ++ +[source,c] +---- +uint32_t major_version +---- ++ +interface minor version. Minor version increments on changes that add +functionality but do not break compatible and will be reset on major version +increment. ++ +[source,c] +---- +void (*start)(RecordPlug *plug) +---- ++ +back-end will call this callback for staring audio capture ++ +[source,c] +---- +void (*stop)(RecordPlug *plug) +---- ++ +back-end will call this callback to stop audio capture ++ +[source,c] +---- +uint32_t (*read)(RecordPlug *plug, uint32_t num_samples, uint32_t *samples) +---- ++ +back-end will call this callback to receive audio capture samples. num_samples +is the requested number samples. Samples is buffer for receiving samples (i.e +samples size is num_samples * 4). Read return number of samples returned. + +. VDInterface specific extension ++ +[source,c] +---- +VDIObjectRef (*plug)(RecordInterface *recorder, RecordPlug* plug, int *active) +---- ++ +Attach record plug to interface instance. Plug is the plug to attach. On +return, active will be 0 if record is stopped and 1 if record is running. On +success, the function return object ref otherwise VDI_INVALID_OBJECT_REF is +returned. ++ +[source,c] +---- +void (*unplug)(RecordInterface *recorder, VDIObjectRef) +---- ++ +Unplug record plug that was plugged using plug. + +== Additional registered interfaces + +* QXL interface "qxl" – QXL interface enable front-end to plug into QXL display +device in order to receive QXL and to render it's output locally or remotely. +* VDI port interface "vdi_port" – interface for plugging, reading and writing +to vdi_port. vdi_port is used for communication with an agent residing on gust +machine. +* Migration interface "migration" - interface for integrating with back-end +migration process. This interface enable registering for pre and post migration +hooks. +* Qemu terminal interface "qemu_terminal" – interface for integrating with +QEMU style terminal. -- 2.13.2