如何进行spice agent 剪贴板共享机制的分析

85次阅读
没有评论

共计 2927 个字符,预计需要花费 8 分钟才能阅读完成。

本篇文章给大家分享的是有关如何进行 spice agent 剪贴板共享机制的分析,丸趣 TV 小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着丸趣 TV 小编一起来看看吧。

      spice 协议定义了一组用于 spice 客户端和 spice agent 之间通信的双向通信通道。spice 只提供了一个通信通道,具体的传输数据内容对协议而言是不透明的。此通道可用于各种用途,如客户端和客户机之间剪贴板共享,分辨率设置等。

spice 中的剪贴板数据共享的数据传输流程是一样的,以 win32-vd_agent 源码为例:当一方比如客户端进行复制的操作时,就会向 spice agent 发送 GRAB 数据,spice agent 收到客户端的 GRAB 数据时,就会调用该函数:

bool VDAgent::handle_clipboard_grab(VDAgentClipboardGrab* clipboard_grab, uint32_t size)
 std::set uint32_t  grab_formats;
 _grab_types.clear();
 for (uint32_t i = 0; i   size / sizeof(clipboard_grab- types[0]); i++) { vd_printf( grab type %u , clipboard_grab- types[i]);
 uint32_t format = get_clipboard_format(clipboard_grab- types[i]);
 //On first supported type, open and empty the clipboard
 if (format   grab_formats.empty()) { if (!OpenClipboard(_hwnd)) {
 return false;
 }
 EmptyClipboard();
 }
 //For all supported type set delayed rendering
 if (format) { _grab_types.insert(clipboard_grab- types[i]);
 if (grab_formats.insert(format).second) { SetClipboardData(format, NULL);
 }
 }
 }
 if (grab_formats.empty()) {
 vd_printf( No supported clipboard types in client grab 
 return true;
 }
 CloseClipboard();
 set_clipboard_owner(owner_client);
 return true;
}

该函数将 guest 的剪贴板清空,并通过 set_clipboard_owner(owner_client); 设置剪贴板的拥有者为 client。

当客户机(guest)端进行粘贴操作时,spice agent 就会调用 on_clipboard_request(UINT format) 函数向客户端发送 REQUEST 数据。

client 端收到 REQUEST 数据时,就会向客户机上的 agent 发送 CLIPBOARD 数据,即把剪贴板数据封装进 VDAgentClipboard 中。spice agent 收到数据后调用 handle_clipboard()函数将数据解析出来并写入到客户机的剪贴板。

bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size)
 HANDLE clip_data;
 UINT format;
 bool ret = false;
 if (_clipboard_owner != owner_client) {
 vd_printf( Received clipboard data from client while clipboard is not owned by client 
 goto fin;
 }
 if (clipboard- type == VD_AGENT_CLIPBOARD_NONE) {
 goto fin;
 }
 switch (clipboard- type) {
 case VD_AGENT_CLIPBOARD_UTF8_TEXT:
 clip_data = utf8_alloc((LPCSTR)clipboard- data, size);
 break;
 case VD_AGENT_CLIPBOARD_IMAGE_PNG:
 case VD_AGENT_CLIPBOARD_IMAGE_BMP: { DWORD cximage_format = get_cximage_format(clipboard- type);
 ASSERT(cximage_format);
 CxImage image(clipboard- data, size, cximage_format);
 clip_data = image.CopyToHandle();
 break;
 }
 default:
 vd_printf(Unsupported clipboard type %u , clipboard- type);
 goto fin;
 }
 format = get_clipboard_format(clipboard- type);
 if (format == 0) { vd_printf( Unknown clipboard format, type %u , clipboard- type);
 goto fin;
 }
 ret = !!SetClipboardData(format, clip_data);
 if (!ret) { DWORD err = GetLastError();
 if (err == ERROR_NOT_ENOUGH_MEMORY) { vd_printf( Not enough memory to set clipboard data, size %u bytes , size);
 } else { vd_printf( SetClipboardData failed: %lu , err);
 }
 }
 set_control_event(CONTROL_CLIPBOARD);
 return ret;
}

剪贴板数据共享流程如图 1.1 所示。客户机上的 agent 和客户端关于剪贴板数据的处理流程是对称的。所以当 Guest 机进行复制操作时也同理,先设置剪贴板拥有者为 guest,并向客户端发送 GRAB 数据。收到客户端的 REQUEST 数据请求时,将 CLIPBOARD 数据发给客户端。

图 1.1 client-guest 剪贴板数据传输

以上就是如何进行 spice agent 剪贴板共享机制的分析,丸趣 TV 小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注丸趣 TV 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2927字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)