1 /*
2    Copyright (C) 2009 Red Hat, Inc.
3 
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions are
6    met:
7 
8        * Redistributions of source code must retain the above copyright
9          notice, this list of conditions and the following disclaimer.
10        * Redistributions in binary form must reproduce the above copyright
11          notice, this list of conditions and the following disclaimer in
12          the documentation and/or other materials provided with the
13          distribution.
14        * Neither the name of the copyright holder nor the names of its
15          contributors may be used to endorse or promote products derived
16          from this software without specific prior written permission.
17 
18    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
19    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 #ifndef _H_VD_AGENT
32 #define _H_VD_AGENT
33 
34 #include <spice/types.h>
35 
36 #include <spice/start-packed.h>
37 
38 enum {
39     VDP_CLIENT_PORT = 1,
40     VDP_SERVER_PORT,
41     VDP_END_PORT
42 };
43 
44 typedef struct SPICE_ATTR_PACKED VDIChunkHeader {
45     uint32_t port;
46     uint32_t size;
47 } VDIChunkHeader;
48 
49 typedef struct SPICE_ATTR_PACKED VDAgentMessage {
50     /* Should be VD_AGENT_PROTOCOL */
51     uint32_t protocol;
52     /* One of VD_AGENT_xxx in the enumeration below */
53     uint32_t type;
54     uint64_t opaque;
55     /* Size of data following */
56     uint32_t size;
57     uint8_t data[0];
58 } VDAgentMessage;
59 
60 #define VD_AGENT_PROTOCOL 1
61 #define VD_AGENT_MAX_DATA_SIZE 2048
62 
63 /*
64  * Messages and types for guest agent.
65  * These messages are sent through the virtio port "com.redhat.spice.0"
66  * (agent <-> server) or embedded in "agent_data" SPICE protocol message in
67  * the "MainChannel" (server <-> client)
68  */
69 enum {
70     /* server -> agent
71      * See VDAgentMouseState structure.
72      */
73     VD_AGENT_MOUSE_STATE = 1,
74     /* client -> agent|server.
75      * Acknowledged by the agent using VD_AGENT_REPLY.
76      * See VDAgentMonitorsConfig structure.
77      */
78     VD_AGENT_MONITORS_CONFIG,
79     /* agent -> client.
80      * See VDAgentReply structure.
81      */
82     VD_AGENT_REPLY,
83     /* Set clipboard data (both directions).
84      * Message comes with type and data.
85      * See VDAgentClipboard structure.
86      */
87     VD_AGENT_CLIPBOARD,
88     /* client -> agent.
89      * Acknowledged by Windows agent using VD_AGENT_REPLY.
90      * See VDAgentDisplayConfig structure.
91     */
92     VD_AGENT_DISPLAY_CONFIG,
93     /* See VDAgentAnnounceCapabilities structure. */
94     VD_AGENT_ANNOUNCE_CAPABILITIES,
95     /* Asks to listen for clipboard changes (both directions).
96      * Remote should empty clipboard and wait for one
97      * of the types passed.
98      * See VDAgentClipboardGrab structure.
99      */
100     VD_AGENT_CLIPBOARD_GRAB,
101     /* Asks for clipboard data (both directions).
102      * Request comes with a specific type.
103      * See VDAgentClipboardRequest structure.
104      */
105     VD_AGENT_CLIPBOARD_REQUEST,
106     /* See VDAgentClipboardRelease structure. */
107     VD_AGENT_CLIPBOARD_RELEASE,
108     /* See VDAgentFileXferStartMessage structure. */
109     VD_AGENT_FILE_XFER_START,
110     /* See VDAgentFileXferStatusMessage structure. */
111     VD_AGENT_FILE_XFER_STATUS,
112     /* See VDAgentFileXferDataMessage structure. */
113     VD_AGENT_FILE_XFER_DATA,
114     /* Empty message */
115     VD_AGENT_CLIENT_DISCONNECTED,
116     /* See VDAgentMaxClipboard structure. */
117     VD_AGENT_MAX_CLIPBOARD,
118     /* See VDAgentAudioVolumeSync structure. */
119     VD_AGENT_AUDIO_VOLUME_SYNC,
120     /* See VDAgentGraphicsDeviceInfo structure. */
121     VD_AGENT_GRAPHICS_DEVICE_INFO,
122     VD_AGENT_END_MESSAGE,
123 };
124 
125 enum {
126     VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA,
127     VD_AGENT_FILE_XFER_STATUS_CANCELLED,
128     VD_AGENT_FILE_XFER_STATUS_ERROR,
129     VD_AGENT_FILE_XFER_STATUS_SUCCESS,
130     VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE,
131     VD_AGENT_FILE_XFER_STATUS_SESSION_LOCKED,
132     VD_AGENT_FILE_XFER_STATUS_VDAGENT_NOT_CONNECTED,
133     VD_AGENT_FILE_XFER_STATUS_DISABLED,
134 };
135 
136 typedef struct SPICE_ATTR_PACKED VDAgentFileXferStatusMessage {
137     uint32_t id;
138     uint32_t result;
139     /* Used to send additional data for detailed error messages
140      * to clients with VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS capability.
141      * Type of data varies with the result:
142      * result : data type (NULL if no data)
143      * VD_AGENT_FILE_XFER_STATUS_ERROR : VDAgentFileXferStatusError
144      * VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE : VDAgentFileXferStatusNotEnoughSpace
145      * VD_AGENT_FILE_XFER_STATUS_SESSION_LOCKED : NULL
146      * VD_AGENT_FILE_XFER_STATUS_VDAGENT_NOT_CONNECTED : NULL
147      * VD_AGENT_FILE_XFER_STATUS_DISABLED : NULL
148      */
149     uint8_t data[0];
150 } VDAgentFileXferStatusMessage;
151 
152 /* Detailed error for VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE.
153  * Only present if VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS is
154  * negotiated and the size of the message can contain it.
155  */
156 typedef struct SPICE_ATTR_PACKED VDAgentFileXferStatusNotEnoughSpace {
157     /* Disk free space in bytes. */
158     uint64_t disk_free_space;
159 } VDAgentFileXferStatusNotEnoughSpace;
160 
161 enum {
162     /* Error number is a G_IO_ERROR_xxx defined in
163      * https://developer.gnome.org/gio/stable/gio-GIOError.html
164      */
165     VD_AGENT_FILE_XFER_STATUS_ERROR_GLIB_IO,
166 };
167 
168 /* Detailed error for VD_AGENT_FILE_XFER_STATUS_ERROR.
169  * Only present if VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS is
170  * negotiated and the size of the message can contain it.
171  * Otherwise a generic error should be assumed and reported.
172  */
173 typedef struct SPICE_ATTR_PACKED VDAgentFileXferStatusError {
174     /* One of VD_AGENT_FILE_XFER_STATUS_ERROR_xxx enumeration
175      */
176     uint8_t error_type;
177     /* An error code which enumeration depends on error_type
178      */
179     uint32_t error_code;
180 } VDAgentFileXferStatusError;
181 
182 typedef struct SPICE_ATTR_PACKED VDAgentFileXferStartMessage {
183     uint32_t id;
184     uint8_t data[0];
185 } VDAgentFileXferStartMessage;
186 
187 typedef struct SPICE_ATTR_PACKED VDAgentFileXferDataMessage {
188     uint32_t id;
189     uint64_t size;
190     uint8_t data[0];
191 } VDAgentFileXferDataMessage;
192 
193 typedef struct SPICE_ATTR_PACKED VDAgentMonConfig {
194     /*
195      * Note a width and height of 0 can be used to indicate a disabled
196      * monitor, this may only be used with agents with the
197      * VD_AGENT_CAP_SPARSE_MONITORS_CONFIG capability.
198      */
199     uint32_t height;
200     uint32_t width;
201     uint32_t depth;
202     int32_t x;
203     int32_t y;
204 } VDAgentMonConfig;
205 
206 enum {
207     VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS = (1 << 0),
208     VD_AGENT_CONFIG_MONITORS_FLAG_PHYSICAL_SIZE = (1 << 1),
209 };
210 
211 typedef struct SPICE_ATTR_PACKED VDAgentMonitorsConfig {
212     uint32_t num_of_monitors;
213     uint32_t flags;
214     VDAgentMonConfig monitors[0];
215     /* only sent if the FLAG_PHYSICAL_SIZE is present: */
216     /* VDAgentMonitorMM physical_sizes[0]; */
217 } VDAgentMonitorsConfig;
218 
219 
220 /* Physical size of the monitor in millimeters.
221  * Having this information, the remote/guest display can configure itself with
222  * appropriate font & scaling to maintain readability. */
223 typedef struct SPICE_ATTR_PACKED VDAgentMonitorMM {
224     /*
225      * Note a width and height of 0 can be used to indicate a disabled
226      * monitor or no size information is present.
227      */
228     uint16_t height;
229     uint16_t width;
230 } VDAgentMonitorMM;
231 
232 enum {
233     VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_WALLPAPER = (1 << 0),
234     VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_FONT_SMOOTH = (1 << 1),
235     VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_ANIMATION = (1 << 2),
236     VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH = (1 << 3),
237 };
238 
239 typedef struct SPICE_ATTR_PACKED VDAgentDisplayConfig {
240     uint32_t flags;
241     uint32_t depth;
242 } VDAgentDisplayConfig;
243 
244 #define VD_AGENT_LBUTTON_MASK (1 << 1)
245 #define VD_AGENT_MBUTTON_MASK (1 << 2)
246 #define VD_AGENT_RBUTTON_MASK (1 << 3)
247 #define VD_AGENT_UBUTTON_MASK (1 << 4)
248 #define VD_AGENT_DBUTTON_MASK (1 << 5)
249 #define VD_AGENT_SBUTTON_MASK (1 << 6)
250 #define VD_AGENT_EBUTTON_MASK (1 << 7)
251 
252 typedef struct SPICE_ATTR_PACKED VDAgentMouseState {
253     uint32_t x;
254     uint32_t y;
255     uint32_t buttons;
256     uint8_t display_id;
257 } VDAgentMouseState;
258 
259 typedef struct SPICE_ATTR_PACKED VDAgentReply {
260     uint32_t type;
261     uint32_t error;
262 } VDAgentReply;
263 
264 enum {
265     VD_AGENT_SUCCESS = 1,
266     VD_AGENT_ERROR,
267 };
268 
269 typedef struct SPICE_ATTR_PACKED VDAgentClipboard {
270 #if 0 /* VD_AGENT_CAP_CLIPBOARD_SELECTION */
271     uint8_t selection;
272     uint8_t __reserved[sizeof(uint32_t) - 1 * sizeof(uint8_t)];
273 #endif
274     uint32_t type;
275     uint8_t data[0];
276 } VDAgentClipboard;
277 
278 enum {
279     VD_AGENT_CLIPBOARD_NONE = 0,
280     VD_AGENT_CLIPBOARD_UTF8_TEXT,
281     VD_AGENT_CLIPBOARD_IMAGE_PNG,  /* All clients with image support should support this one */
282     VD_AGENT_CLIPBOARD_IMAGE_BMP,  /* optional */
283     VD_AGENT_CLIPBOARD_IMAGE_TIFF, /* optional */
284     VD_AGENT_CLIPBOARD_IMAGE_JPG,  /* optional */
285     /* identifies a list of absolute paths in phodav server
286      * that is associated with the "org.spice-space.webdav.0" webdav channel;
287      * the items are encoded in UTF-8 and separated by '\0';
288      * the first item must be either "copy" or "cut" (without the quotes)
289      * to indicate what action should be performed with the files that follow */
290     VD_AGENT_CLIPBOARD_FILE_LIST,
291 };
292 
293 enum {
294     VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD = 0,
295     VD_AGENT_CLIPBOARD_SELECTION_PRIMARY,
296     VD_AGENT_CLIPBOARD_SELECTION_SECONDARY,
297 };
298 
299 typedef struct SPICE_ATTR_PACKED VDAgentClipboardGrab {
300 #if 0 /* VD_AGENT_CAP_CLIPBOARD_SELECTION */
301     uint8_t selection;
302     uint8_t __reserved[sizeof(uint32_t) - 1 * sizeof(uint8_t)];
303 #endif
304 #if 0 /* VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL */
305     uint32_t serial;
306 #endif
307     uint32_t types[0];
308 } VDAgentClipboardGrab;
309 
310 typedef struct SPICE_ATTR_PACKED VDAgentClipboardRequest {
311 #if 0 /* VD_AGENT_CAP_CLIPBOARD_SELECTION */
312     uint8_t selection;
313     uint8_t __reserved[sizeof(uint32_t) - 1 * sizeof(uint8_t)];
314 #endif
315     uint32_t type;
316 } VDAgentClipboardRequest;
317 
318 typedef struct SPICE_ATTR_PACKED VDAgentClipboardRelease {
319 #if 0 /* VD_AGENT_CAP_CLIPBOARD_SELECTION */
320     uint8_t selection;
321     uint8_t __reserved[sizeof(uint32_t) - 1 * sizeof(uint8_t)];
322 #endif
323     uint8_t dummy_empty_field[0]; /* C/C++ compatibility */
324 } VDAgentClipboardRelease;
325 
326 typedef struct SPICE_ATTR_PACKED VDAgentMaxClipboard {
327     int32_t max;
328 } VDAgentMaxClipboard;
329 
330 typedef struct SPICE_ATTR_PACKED VDAgentAudioVolumeSync {
331     uint8_t is_playback;
332     uint8_t mute;
333     uint8_t nchannels;
334     uint16_t volume[0];
335 } VDAgentAudioVolumeSync;
336 
337 typedef struct SPICE_ATTR_PACKED VDAgentDeviceDisplayInfo {
338     uint32_t channel_id;
339     uint32_t monitor_id;
340     uint32_t device_display_id;
341     uint32_t device_address_len;
342     uint8_t device_address[0];  /* a zero-terminated string */
343 } VDAgentDeviceDisplayInfo;
344 
345 
346 /* This message contains the mapping of (channel_id, monitor_id) pair to a
347  * "physical" (virtualized) device and its monitor identified by device_address
348  * and device_display_id.
349  *
350  * It's used on the vd_agent to identify the guest monitors for the
351  * mouse_position and monitors_config messages.
352  */
353 typedef struct SPICE_ATTR_PACKED VDAgentGraphicsDeviceInfo {
354     uint32_t count;
355 #ifdef _MSC_VER
356     uint8_t display_info[0];
357 #else
358     VDAgentDeviceDisplayInfo display_info[0];
359 #endif
360 } VDAgentGraphicsDeviceInfo;
361 
362 
363 /* Capabilities definitions
364  */
365 enum {
366     VD_AGENT_CAP_MOUSE_STATE = 0,
367     VD_AGENT_CAP_MONITORS_CONFIG,
368     VD_AGENT_CAP_REPLY,
369     VD_AGENT_CAP_CLIPBOARD,
370     VD_AGENT_CAP_DISPLAY_CONFIG,
371     VD_AGENT_CAP_CLIPBOARD_BY_DEMAND,
372     VD_AGENT_CAP_CLIPBOARD_SELECTION,
373     VD_AGENT_CAP_SPARSE_MONITORS_CONFIG,
374     VD_AGENT_CAP_GUEST_LINEEND_LF,
375     VD_AGENT_CAP_GUEST_LINEEND_CRLF,
376     VD_AGENT_CAP_MAX_CLIPBOARD,
377     VD_AGENT_CAP_AUDIO_VOLUME_SYNC,
378     VD_AGENT_CAP_MONITORS_CONFIG_POSITION,
379     VD_AGENT_CAP_FILE_XFER_DISABLED,
380     VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS,
381     VD_AGENT_CAP_GRAPHICS_DEVICE_INFO,
382     VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB,
383     VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL,
384     VD_AGENT_END_CAP,
385 };
386 
387 typedef struct SPICE_ATTR_PACKED VDAgentAnnounceCapabilities {
388     uint32_t  request;
389     uint32_t caps[0];
390 } VDAgentAnnounceCapabilities;
391 
392 #define VD_AGENT_CAPS_SIZE_FROM_MSG_SIZE(msg_size) \
393     (((msg_size) - sizeof(VDAgentAnnounceCapabilities)) / sizeof(uint32_t))
394 
395 #define VD_AGENT_CAPS_SIZE ((VD_AGENT_END_CAP + 31) / 32)
396 
397 #define VD_AGENT_CAPS_BYTES (((VD_AGENT_END_CAP + 31) / 8) & ~3)
398 
399 #define VD_AGENT_HAS_CAPABILITY(caps, caps_size, index) \
400     ((index) < (caps_size * 32) && ((caps)[(index) / 32] & (1 << ((index) % 32))))
401 
402 #define VD_AGENT_SET_CAPABILITY(caps, index) \
403     { (caps)[(index) / 32] |= (1 << ((index) % 32)); }
404 
405 #define VD_AGENT_CLEAR_CAPABILITY(caps, index) \
406     { (caps)[(index) / 32] &= ~(1 << ((index) % 32)); }
407 
408 #include <spice/end-packed.h>
409 
410 #endif /* _H_VD_AGENT */
411