418{
419 unsigned long nitems, bytes_left;
420 XWindowAttributes wa;
422 Atom *supported_targets;
425
427 goto fail;
428
429 DEBUG_CLIPBOARD((
"xclip_handle_SelectionNotify: selection=%s, target=%s, property=%s\n",
430 XGetAtomName(
This->display,
event->selection),
431 XGetAtomName(
This->display,
event->target),
432 XGetAtomName(
This->display,
event->property)));
433
434 if (
event->target ==
This->xclip.timestamp_atom)
435 {
436 if (
event->selection ==
This->xclip.primary_atom)
437 {
439 This->xclip.rdesktop_primary_timestamp_target_atom, 0,
440 XMaxRequestSize(
This->display),
False, AnyPropertyType,
442 }
443 else
444 {
446 This->xclip.rdesktop_clipboard_timestamp_target_atom, 0,
447 XMaxRequestSize(
This->display),
False, AnyPropertyType,
449 }
450
451
453 {
455 goto fail;
456 }
457
458 if (
event->selection ==
This->xclip.primary_atom)
459 {
461 if (
This->xclip.primary_timestamp == 0)
462 This->xclip.primary_timestamp++;
463 XDeleteProperty(
This->display,
This->wnd,
This->xclip.rdesktop_primary_timestamp_target_atom);
465 (
unsigned)
This->xclip.primary_timestamp));
466 }
467 else
468 {
470 if (
This->xclip.clipboard_timestamp == 0)
471 This->xclip.clipboard_timestamp++;
472 XDeleteProperty(
This->display,
This->wnd,
This->xclip.rdesktop_clipboard_timestamp_target_atom);
474 (
unsigned)
This->xclip.clipboard_timestamp));
475 }
476
478
479 if (
This->xclip.primary_timestamp &&
This->xclip.clipboard_timestamp)
480 {
481 if (
This->xclip.primary_timestamp >
This->xclip.clipboard_timestamp)
482 {
484 XConvertSelection(
This->display,
This->xclip.primary_atom,
This->xclip.targets_atom,
485 This->xclip.rdesktop_clipboard_target_atom,
This->wnd,
487 }
488 else
489 {
491 XConvertSelection(
This->display,
This->xclip.clipboard_atom,
This->xclip.targets_atom,
492 This->xclip.rdesktop_clipboard_target_atom,
This->wnd,
494 }
495 }
496
497 return;
498 }
499
500 if (
This->xclip.probing_selections &&
This->xclip.reprobe_selections)
501 {
504 return;
505 }
506
507 res = XGetWindowProperty(
This->display,
This->wnd,
This->xclip.rdesktop_clipboard_target_atom,
508 0, XMaxRequestSize(
This->display),
False, AnyPropertyType,
510
512
514 {
516 goto fail;
517 }
518
520 {
522
523 XGetWindowAttributes(
This->display,
This->wnd, &wa);
524 if ((wa.your_event_mask | PropertyChangeMask) != wa.your_event_mask)
525 {
526 XSelectInput(
This->display,
This->wnd, (wa.your_event_mask | PropertyChangeMask));
527 }
529 This->xclip.incr_target =
event->target;
530 This->xclip.waiting_for_INCR = 1;
532 }
533
534
535 if (
event->target ==
This->xclip.targets_atom)
536 {
537
538
539
540
541 int text_target_satisfaction = 0;
542 Atom best_text_target = 0;
544 {
546 for (
i = 0;
i < nitems;
i++)
547 {
549 XGetAtomName(
This->display, supported_targets[
i])));
550 if (supported_targets[
i] ==
This->xclip.format_string_atom)
551 {
552 if (text_target_satisfaction < 1)
553 {
554 DEBUG_CLIPBOARD((
"Other party supports STRING, choosing that as best_target\n"));
555 best_text_target = supported_targets[
i];
556 text_target_satisfaction = 1;
557 }
558 }
559#ifdef USE_UNICODE_CLIPBOARD
560 else if (supported_targets[
i] ==
This->xclip.format_unicode_atom)
561 {
562 if (text_target_satisfaction < 2)
563 {
564 DEBUG_CLIPBOARD((
"Other party supports text/unicode, choosing that as best_target\n"));
565 best_text_target = supported_targets[
i];
566 text_target_satisfaction = 2;
567 }
568 }
569 else if (supported_targets[
i] ==
This->xclip.format_utf8_string_atom)
570 {
571 if (text_target_satisfaction < 3)
572 {
573 DEBUG_CLIPBOARD((
"Other party supports UTF8_STRING, choosing that as best_target\n"));
574 best_text_target = supported_targets[
i];
575 text_target_satisfaction = 3;
576 }
577 }
578#endif
579 else if (supported_targets[
i] ==
This->xclip.rdesktop_clipboard_formats_atom)
580 {
581 if (
This->xclip.probing_selections && (text_target_satisfaction < 4))
582 {
583 DEBUG_CLIPBOARD((
"Other party supports native formats, choosing that as best_target\n"));
584 best_text_target = supported_targets[
i];
585 text_target_satisfaction = 4;
586 }
587 }
588 }
589 }
590
591
592
593
594 if ((best_text_target != 0)
595 && (!
This->xclip.probing_selections
596 || (best_text_target ==
This->xclip.rdesktop_clipboard_formats_atom)))
597 {
598 XConvertSelection(
This->display,
event->selection, best_text_target,
599 This->xclip.rdesktop_clipboard_target_atom,
This->wnd,
event->time);
601 }
602 else
603 {
604 DEBUG_CLIPBOARD((
"Unable to find a textual target to satisfy RDP clipboard text request\n"));
605 goto fail;
606 }
607 }
608 else
609 {
610 if (
This->xclip.probing_selections)
611 {
612 Window primary_owner, clipboard_owner;
613
614
615
616
617
618
619
620 clipboard_owner = XGetSelectionOwner(
This->display,
This->xclip.clipboard_atom);
621
622 if (
This->xclip.auto_mode)
623 primary_owner = XGetSelectionOwner(
This->display,
This->xclip.primary_atom);
624 else
625 primary_owner = clipboard_owner;
626
627 if (primary_owner != clipboard_owner)
628 goto fail;
629
632 This->xclip.rdesktop_is_selection_owner =
True;
634 }
636 {
637 goto fail;
638 }
639 }
640
644
645 return;
646
647 fail:
649 if (
This->xclip.probing_selections)
650 {
651 DEBUG_CLIPBOARD((
"Unable to find suitable target. Using default text format.\n"));
653 This->xclip.rdesktop_is_selection_owner =
False;
654
655
656
657
658
660 }
661 else
662 {
664 }
666}
void cliprdr_send_simple_native_format_announce(uint32 format)
void cliprdr_send_native_format_announce(uint8 *formats_data, uint32 formats_data_length)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
static PLARGE_INTEGER Time
static void xclip_clear_target_props(RDPCLIENT *This)