共計 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 行業資訊頻道。