static void wf_cliprdr_process_cb_monitor_ready_event(wfContext *wfc, RDP_CB_MONITOR_READY_EVENT *ready_event) { cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context; cliprdr->channel_initialized = TRUE; cliprdr_send_format_list(wfc->cliprdr_context); }
static int wf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONITOR_READY* monitorReady) { wfClipboard* clipboard = (wfClipboard*) context->custom; clipboard->sync = TRUE; wf_cliprdr_send_client_capabilities(clipboard); cliprdr_send_format_list(clipboard); return 1; }
static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { static cliprdrContext *cliprdr = NULL; switch (Msg) { case WM_CREATE: cliprdr = (cliprdrContext *)((CREATESTRUCT *)lParam)->lpCreateParams; cliprdr->hwndNextViewer = SetClipboardViewer(hWnd); if (cliprdr->hwndNextViewer == NULL && GetLastError() != 0) { DEBUG_CLIPRDR("error: SetClipboardViewer failed with 0x%0x.", GetLastError()); } cliprdr->hwndClipboard = hWnd; break; case WM_CLOSE: ChangeClipboardChain(hWnd, cliprdr->hwndNextViewer); break; case WM_CHANGECBCHAIN: if (cliprdr->hwndNextViewer == (HWND)wParam) { cliprdr->hwndNextViewer = (HWND)lParam; } else if (cliprdr->hwndNextViewer != NULL) { SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam); } break; case WM_DRAWCLIPBOARD: if (cliprdr->channel_initialized) { if (GetClipboardOwner() != cliprdr->hwndClipboard) { if (!cliprdr->hmem) { cliprdr->hmem = GlobalFree(cliprdr->hmem); } cliprdr_send_format_list(cliprdr); } } if (cliprdr->hwndNextViewer != NULL && cliprdr->hwndNextViewer != hWnd) SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam); break; case WM_RENDERALLFORMATS: /* discard all contexts in clipboard */ if (!OpenClipboard(cliprdr->hwndClipboard)) { DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError()); break; } EmptyClipboard(); CloseClipboard(); break; case WM_RENDERFORMAT: if (cliprdr_send_data_request(cliprdr, (UINT32)wParam) != 0) { DEBUG_CLIPRDR("error: cliprdr_send_data_request failed."); break; } if (SetClipboardData(wParam, cliprdr->hmem) == NULL) { DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError()); cliprdr->hmem = GlobalFree(cliprdr->hmem); } /* Note: GlobalFree() is not needed when success */ break; case WM_CLIPBOARDUPDATE: case WM_DESTROYCLIPBOARD: case WM_ASKCBFORMATNAME: case WM_HSCROLLCLIPBOARD: case WM_PAINTCLIPBOARD: case WM_SIZECLIPBOARD: case WM_VSCROLLCLIPBOARD: default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; }
static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { static wfClipboard* clipboard = NULL; switch (Msg) { case WM_CREATE: DEBUG_CLIPRDR("info: WM_CREATE"); clipboard = (wfClipboard*)((CREATESTRUCT*) lParam)->lpCreateParams; if (!AddClipboardFormatListener(hWnd)) { DEBUG_CLIPRDR("error: AddClipboardFormatListener failed with %#x.", GetLastError()); } clipboard->hwnd = hWnd; break; case WM_CLOSE: DEBUG_CLIPRDR("info: WM_CLOSE"); RemoveClipboardFormatListener(hWnd); break; case WM_CLIPBOARDUPDATE: DEBUG_CLIPRDR("info: WM_CLIPBOARDUPDATE"); if (clipboard->sync) { if ((GetClipboardOwner() != clipboard->hwnd) && (S_FALSE == OleIsCurrentClipboard(clipboard->data_obj))) { if (clipboard->hmem) { GlobalFree(clipboard->hmem); clipboard->hmem = NULL; } cliprdr_send_format_list(clipboard); } } break; case WM_RENDERALLFORMATS: DEBUG_CLIPRDR("info: WM_RENDERALLFORMATS"); /* discard all contexts in clipboard */ if (!OpenClipboard(clipboard->hwnd)) { DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError()); break; } EmptyClipboard(); CloseClipboard(); break; case WM_RENDERFORMAT: DEBUG_CLIPRDR("info: WM_RENDERFORMAT"); if (cliprdr_send_data_request(clipboard, (UINT32) wParam) != 0) { DEBUG_CLIPRDR("error: cliprdr_send_data_request failed."); break; } if (!SetClipboardData((UINT) wParam, clipboard->hmem)) { DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError()); if (clipboard->hmem) { GlobalFree(clipboard->hmem); clipboard->hmem = NULL; } } /* Note: GlobalFree() is not needed when success */ break; case WM_CLIPRDR_MESSAGE: DEBUG_CLIPRDR("info: WM_CLIPRDR_MESSAGE"); switch (wParam) { case OLE_SETCLIPBOARD: DEBUG_CLIPRDR("info: OLE_SETCLIPBOARD"); if (wf_create_file_obj(clipboard, &clipboard->data_obj)) { if (OleSetClipboard(clipboard->data_obj) != S_OK) { wf_destroy_file_obj(clipboard->data_obj); clipboard->data_obj = NULL; } } break; default: break; } break; case WM_DESTROYCLIPBOARD: case WM_ASKCBFORMATNAME: case WM_HSCROLLCLIPBOARD: case WM_PAINTCLIPBOARD: case WM_SIZECLIPBOARD: case WM_VSCROLLCLIPBOARD: default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; }
static void cliprdr_get_clipboard(XEvent* e) { Atom type; unsigned long len, bytes_left, dummy; int format, result; unsigned char *data; log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "New owner %i", e->xselection.requestor); XGetWindowProperty (e->xselection.display, e->xselection.requestor, e->xselection.property, 0, 0, False, AnyPropertyType, &type, &format, &len, &bytes_left, &data); // Check Format list if (type == XA_ATOM || format == 32) { result = XGetWindowProperty (e->xselection.display, e->xselection.requestor, e->xselection.property, 0, bytes_left, 0, XA_ATOM, &type, &format, &len, &dummy, &data); if (result == Success) { int i = 0; Atom atom; for (i = 0; i < len ; i++) { atom = ((Atom*)data)[i]; log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "format : %s", XGetAtomName(display, atom)); if (clipboard_format_supported(&clipboard, atom)) { clipboard_add_current_clipboard_format(&clipboard, atom); } } if (clipboard_current_clipboard_size(&clipboard) > 0) { atom = clipboard_get_current_clipboard_format(&clipboard, 0); log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "Request for format %s", XGetAtomName(display, atom)); XConvertSelection(display, clipboard_atom, atom, xrdp_clipboard, wclip, CurrentTime); XSync (e->xselectionclear.display, False); } return; } log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "Failed to parse atom list"); return; } // DATA is There log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "Data type : %s\n", XGetAtomName(e->xselection.display, e->xselection.property)); if (bytes_left > 0 && clipboard_format_supported(&clipboard, e->xselection.target)) { unsigned char* clipboard_data = NULL; int clipboard_size = 0; result = XGetWindowProperty(e->xselection.display, e->xselection.requestor, e->xselection.property, 0, bytes_left, 0, e->xselection.target, &type, &format, &len, &dummy, &data); if (result == Success) { log_message(l_config, LOG_LEVEL_DEBUG_PLUS, "vchannel_cliprdr[cliprdr_get_clipboard]: " "New data in clipboard: %s", data); int index = -1; index = clipboard_get_current_clipboard_format_index(&clipboard, e->xselection.target); // Don't forget the null terminated character clipboard_data = g_malloc(bytes_left + 1, 1); clipboard_size = bytes_left; g_memcpy(clipboard_data, data, bytes_left); log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "clipboard %s[%i] updated with '%s'", XGetAtomName(display, e->xselection.target), index, data); clipboard_add_current_clipboard_data(&clipboard, clipboard_data, clipboard_size, e->xselection.target); if (index < (clipboard_current_clipboard_size(&clipboard) - 1)) { Atom format = clipboard_get_current_clipboard_format(&clipboard, index + 1); log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "Request for format %s", XGetAtomName(display, format)); XConvertSelection(display, clipboard_atom, format, xrdp_clipboard, wclip, CurrentTime); XSync (e->xselectionclear.display, False); } else { XSetSelectionOwner(display, clipboard_atom, wclip, CurrentTime); XSync(display, False); // File content is not supported for now if ((! clipboard_current_clipboard_format_exist(&clipboard, format_file_gnome_atom)) && (! clipboard_current_clipboard_format_exist(&clipboard, format_file_text_uri_list_atom))) cliprdr_send_format_list(); } } else { log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[cliprdr_get_clipboard]: " "Failed to get clipboard content"); } XFree (data); } }