BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) { int i; int fmt; Atom type; UINT32 format; XEvent* respond; UINT32 alt_format; BYTE* data = NULL; BOOL delay_respond; unsigned long length, bytes_left; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; DEBUG_X11_CLIPRDR("target=%d", (int) xevent->xselectionrequest.target); if (xevent->xselectionrequest.owner != xfi->drawable) { DEBUG_X11_CLIPRDR("not owner"); return FALSE; } delay_respond = FALSE; respond = (XEvent*) malloc(sizeof(XEvent)); ZeroMemory(respond, sizeof(XEvent)); respond->xselection.property = None; respond->xselection.type = SelectionNotify; respond->xselection.display = xevent->xselectionrequest.display; respond->xselection.requestor = xevent->xselectionrequest.requestor; respond->xselection.selection = xevent->xselectionrequest.selection; respond->xselection.target = xevent->xselectionrequest.target; respond->xselection.time = xevent->xselectionrequest.time; if (xevent->xselectionrequest.target == cb->targets[0]) /* TIMESTAMP */ { /* TODO */ DEBUG_X11_CLIPRDR("target: TIMESTAMP (unimplemented)"); } else if (xevent->xselectionrequest.target == cb->targets[1]) /* TARGETS */ { /* Someone else requests our available formats */ DEBUG_X11_CLIPRDR("target: TARGETS"); respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_targets(xfi, respond); } else { DEBUG_X11_CLIPRDR("target: other"); i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target); if (i >= 0 && xevent->xselectionrequest.requestor != xfi->drawable) { format = cb->format_mappings[i].format_id; alt_format = format; if (format == CB_FORMAT_RAW) { if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor, cb->property_atom, 0, 4, 0, XA_INTEGER, &type, &fmt, &length, &bytes_left, &data) != Success) { DEBUG_X11_CLIPRDR("XGetWindowProperty failed"); } if (data) { CopyMemory(&alt_format, data, 4); XFree(data); } } DEBUG_X11_CLIPRDR("provide format 0x%04x alt_format 0x%04x", format, alt_format); if ((cb->data != 0) && (format == cb->data_format) && (alt_format == cb->data_alt_format)) { /* Cached clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_data(xfi, respond); } else if (cb->respond) { DEBUG_X11_CLIPRDR("duplicated request"); } else { /** * Send clipboard data request to the server. * Response will be postponed after receiving the data */ if (cb->data) { free(cb->data); cb->data = NULL; } respond->xselection.property = xevent->xselectionrequest.property; cb->respond = respond; cb->data_format = format; cb->data_alt_format = alt_format; delay_respond = TRUE; xf_cliprdr_send_data_request(xfi, alt_format); } } } if (delay_respond == FALSE) { XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond); XFlush(xfi->display); free(respond); } return TRUE; }
static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent) { int fmt; Atom type; UINT32 formatId; XEvent* respond; UINT32 altFormatId; BYTE* data = NULL; BOOL delayRespond; unsigned long length; unsigned long bytes_left; xfCliprdrFormat* format; xfContext* xfc = clipboard->xfc; if (xevent->xselectionrequest.owner != xfc->drawable) return FALSE; delayRespond = FALSE; respond = (XEvent*) calloc(1, sizeof(XEvent)); respond->xselection.property = None; respond->xselection.type = SelectionNotify; respond->xselection.display = xevent->xselectionrequest.display; respond->xselection.requestor = xevent->xselectionrequest.requestor; respond->xselection.selection = xevent->xselectionrequest.selection; respond->xselection.target = xevent->xselectionrequest.target; respond->xselection.time = xevent->xselectionrequest.time; if (xevent->xselectionrequest.target == clipboard->targets[0]) /* TIMESTAMP */ { /* TODO */ } else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */ { /* Someone else requests our available formats */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_targets(clipboard, respond); } else { format = xf_cliprdr_get_format_by_atom(clipboard, xevent->xselectionrequest.target); if (format && (xevent->xselectionrequest.requestor != xfc->drawable)) { formatId = format->formatId; altFormatId = formatId; if (formatId == 0) { if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor, clipboard->property_atom, 0, 4, 0, XA_INTEGER, &type, &fmt, &length, &bytes_left, &data) != Success) { } if (data) { CopyMemory(&altFormatId, data, 4); XFree(data); } } if ((clipboard->data != 0) && (formatId == clipboard->data_format) && (altFormatId == clipboard->data_alt_format)) { /* Cached clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_data(clipboard, respond, clipboard->data, clipboard->data_length); } else if (clipboard->respond) { /* duplicate request */ } else { /** * Send clipboard data request to the server. * Response will be postponed after receiving the data */ if (clipboard->data) { free(clipboard->data); clipboard->data = NULL; } respond->xselection.property = xevent->xselectionrequest.property; clipboard->respond = respond; clipboard->data_format = formatId; clipboard->data_alt_format = altFormatId; delayRespond = TRUE; xf_cliprdr_send_data_request(clipboard, altFormatId); } } } if (!delayRespond) { XSendEvent(xfc->display, xevent->xselectionrequest.requestor, 0, 0, respond); XFlush(xfc->display); free(respond); } return TRUE; }
boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) { int i; int fmt; Atom type; uint32 format; XEvent* respond; uint32 alt_format; uint8* data = NULL; boolean delay_respond; unsigned long len, bytes_left; clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; DEBUG_X11("target=%d", (int)xevent->xselectionrequest.target); if (xevent->xselectionrequest.owner != xfi->window->handle) { DEBUG_X11("not owner"); return False; } delay_respond = False; respond = xnew(XEvent); respond->xselection.property = None; respond->xselection.type = SelectionNotify; respond->xselection.display = xevent->xselectionrequest.display; respond->xselection.requestor = xevent->xselectionrequest.requestor; respond->xselection.selection = xevent->xselectionrequest.selection; respond->xselection.target = xevent->xselectionrequest.target; respond->xselection.time = xevent->xselectionrequest.time; if (xevent->xselectionrequest.target == cb->targets[0]) /* TIMESTAMP */ { /* TODO */ } else if (xevent->xselectionrequest.target == cb->targets[1]) /* TARGETS */ { /* Someone else requests our available formats */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_targets(xfi, respond); } else { i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target); if (i >= 0 && xevent->xselectionrequest.requestor != xfi->window->handle) { format = cb->format_mappings[i].format_id; alt_format = format; if (format == CB_FORMAT_RAW) { if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor, cb->property_atom, 0, 4, 0, XA_INTEGER, &type, &fmt, &len, &bytes_left, &data) != Success) { DEBUG_X11("XGetWindowProperty failed"); } if (data) { memcpy(&alt_format, data, 4); XFree(data); } } DEBUG_X11("provide format 0x%04x alt_format 0x%04x", format, alt_format); if (cb->data != 0 && format == cb->data_format && alt_format == cb->data_alt_format) { /* Cached clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_data(xfi, respond); } else if (cb->respond) { DEBUG_X11("duplicated request"); } else { /** * Send clipboard data request to the server. * Response will be postponed after receiving the data */ if (cb->data) { xfree(cb->data); cb->data = NULL; } respond->xselection.property = xevent->xselectionrequest.property; cb->respond = respond; cb->data_format = format; cb->data_alt_format = alt_format; delay_respond = True; xf_cliprdr_send_data_request(xfi, alt_format); } } } if (!delay_respond) { XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond); XFlush(xfi->display); xfree(respond); } return True; }
static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent) { int fmt; Atom type; UINT32 formatId; const char* formatName; XEvent* respond; BYTE* data = NULL; BOOL delayRespond; BOOL rawTransfer; BOOL matchingFormat; unsigned long length; unsigned long bytes_left; CLIPRDR_FORMAT* format; xfContext* xfc = clipboard->xfc; if (xevent->xselectionrequest.owner != xfc->drawable) return FALSE; delayRespond = FALSE; if (!(respond = (XEvent*) calloc(1, sizeof(XEvent)))) { WLog_ERR(TAG, "failed to allocate XEvent data"); return FALSE; } respond->xselection.property = None; respond->xselection.type = SelectionNotify; respond->xselection.display = xevent->xselectionrequest.display; respond->xselection.requestor = xevent->xselectionrequest.requestor; respond->xselection.selection = xevent->xselectionrequest.selection; respond->xselection.target = xevent->xselectionrequest.target; respond->xselection.time = xevent->xselectionrequest.time; if (xevent->xselectionrequest.target == clipboard->targets[0]) /* TIMESTAMP */ { /* TODO */ } else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */ { /* Someone else requests our available formats */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_targets(clipboard, respond); } else { format = xf_cliprdr_get_server_format_by_atom(clipboard, xevent->xselectionrequest.target); if (format && (xevent->xselectionrequest.requestor != xfc->drawable)) { formatId = format->formatId; formatName = format->formatName; rawTransfer = FALSE; if (formatId == CF_RAW) { if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor, clipboard->property_atom, 0, 4, 0, XA_INTEGER, &type, &fmt, &length, &bytes_left, &data) != Success) { } if (data) { rawTransfer = TRUE; CopyMemory(&formatId, data, 4); XFree(data); } } /* We can compare format names by pointer value here as they are both * taken from the same clipboard->serverFormats array */ matchingFormat = (formatId == clipboard->data_format_id) && (formatName == clipboard->data_format_name); if (matchingFormat && (clipboard->data != 0) && !rawTransfer) { /* Cached converted clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_data(clipboard, respond, clipboard->data, clipboard->data_length); } else if (matchingFormat && (clipboard->data_raw != 0) && rawTransfer) { /* Cached raw clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_data(clipboard, respond, clipboard->data_raw, clipboard->data_raw_length); } else if (clipboard->respond) { /* duplicate request */ } else { /** * Send clipboard data request to the server. * Response will be postponed after receiving the data */ xf_cliprdr_clear_cached_data(clipboard); respond->xselection.property = xevent->xselectionrequest.property; clipboard->respond = respond; clipboard->data_format_id = formatId; clipboard->data_format_name = formatName; clipboard->data_raw_format = rawTransfer; delayRespond = TRUE; xf_cliprdr_send_data_request(clipboard, formatId); } } } if (!delayRespond) { XSendEvent(xfc->display, xevent->xselectionrequest.requestor, 0, 0, respond); XFlush(xfc->display); free(respond); } return TRUE; }