您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)如何進(jìn)行spice agent 剪貼板共享機(jī)制的分析,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
spice 協(xié)議定義了一組用于spice客戶端和spice agent之間通信的雙向通信通道。spice只提供了一個(gè)通信通道,具體的傳輸數(shù)據(jù)內(nèi)容對協(xié)議而言是不透明的。此通道可用于各種用途,如客戶端和客戶機(jī)之間剪貼板共享,分辨率設(shè)置等。
spice 中的剪貼板數(shù)據(jù)共享的數(shù)據(jù)傳輸流程是一樣的,以win32-vd_agent源碼為例:當(dāng)一方比如客戶端進(jìn)行復(fù)制的操作時(shí),就會向spice agent發(fā)送GRAB數(shù)據(jù),spice agent收到客戶端的GRAB數(shù)據(jù)時(shí),就會調(diào)用該函數(shù):
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; }
該函數(shù)將guest的剪貼板清空,并通過set_clipboard_owner(owner_client);設(shè)置剪貼板的擁有者為client。
當(dāng)客戶機(jī)(guest)端進(jìn)行粘貼操作時(shí),spice agent就會調(diào)用on_clipboard_request(UINT format)函數(shù)向客戶端發(fā)送REQUEST數(shù)據(jù)。
client端收到REQUEST數(shù)據(jù)時(shí),就會向客戶機(jī)上的agent發(fā)送CLIPBOARD數(shù)據(jù),即把剪貼板數(shù)據(jù)封裝進(jìn)VDAgentClipboard中。spice agent收到數(shù)據(jù)后調(diào)用handle_clipboard()函數(shù)將數(shù)據(jù)解析出來并寫入到客戶機(jī)的剪貼板。
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); } } fin: set_control_event(CONTROL_CLIPBOARD); return ret; }
剪貼板數(shù)據(jù)共享流程如圖1.1所示??蛻魴C(jī)上的agent和客戶端關(guān)于剪貼板數(shù)據(jù)的處理流程是對稱的。所以當(dāng)Guest機(jī)進(jìn)行復(fù)制操作時(shí)也同理,先設(shè)置剪貼板擁有者為guest,并向客戶端發(fā)送GRAB數(shù)據(jù)。收到客戶端的REQUEST數(shù)據(jù)請求時(shí),將CLIPBOARD數(shù)據(jù)發(fā)給客戶端。
圖1.1 client-guest 剪貼板數(shù)據(jù)傳輸
以上就是如何進(jìn)行spice agent 剪貼板共享機(jī)制的分析,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。