/[rdesktop]/sourceforge.net/trunk/rdesktop/xclip.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/xclip.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1209 by ossman_, Mon Mar 27 11:10:09 2006 UTC revision 1213 by ossman_, Tue Mar 28 13:24:48 2006 UTC
# Line 48  Line 48 
48  #define RDP_CF_TEXT CF_TEXT  #define RDP_CF_TEXT CF_TEXT
49  #endif  #endif
50    
51  #define MAX_TARGETS 7  #define MAX_TARGETS 8
52    
53  extern Display *g_display;  extern Display *g_display;
54  extern Window g_wnd;  extern Window g_wnd;
# Line 65  static Atom clipboard_atom, primary_atom Line 65  static Atom clipboard_atom, primary_atom
65  static Atom targets_atom;  static Atom targets_atom;
66  /* Atom of the TIMESTAMP clipboard target */  /* Atom of the TIMESTAMP clipboard target */
67  static Atom timestamp_atom;  static Atom timestamp_atom;
68  /* Atom _RDESKTOP_CLIPBOARD_TARGET which has multiple uses:  /* Atom _RDESKTOP_CLIPBOARD_TARGET which is used as the 'property' argument in
69     - The 'property' argument in XConvertSelection calls: This is the property of our     XConvertSelection calls: This is the property of our window into which
70       window into which XConvertSelection will store the received clipboard data.     XConvertSelection will store the received clipboard data. */
    - In a clipboard request of target _RDESKTOP_CLIPBOARD_FORMATS, an XA_INTEGER-typed  
      property carrying the Windows native (CF_...) format desired by the requestor.  
      Requestor set this property (e.g. requestor_wnd[_RDESKTOP_CLIPBOARD_TARGET] = CF_TEXT)  
      before requesting clipboard data from a fellow rdesktop using  
      the _RDESKTOP_CLIPBOARD_FORMATS target. */  
71  static Atom rdesktop_clipboard_target_atom;  static Atom rdesktop_clipboard_target_atom;
72  /* Atoms _RDESKTOP_PRIMARY_TIMESTAMP_TARGET and _RDESKTOP_CLIPBOARD_TIMESTAMP_TARGET  /* Atoms _RDESKTOP_PRIMARY_TIMESTAMP_TARGET and _RDESKTOP_CLIPBOARD_TIMESTAMP_TARGET
73     are used to store the timestamps for when a window got ownership of the selections.     are used to store the timestamps for when a window got ownership of the selections.
# Line 80  static Atom rdesktop_clipboard_target_at Line 75  static Atom rdesktop_clipboard_target_at
75  static Atom rdesktop_primary_timestamp_target_atom, rdesktop_clipboard_timestamp_target_atom;  static Atom rdesktop_primary_timestamp_target_atom, rdesktop_clipboard_timestamp_target_atom;
76  /* Storage for timestamps since we get them in two separate notifications. */  /* Storage for timestamps since we get them in two separate notifications. */
77  static Time primary_timestamp, clipboard_timestamp;  static Time primary_timestamp, clipboard_timestamp;
78  /* Atom _RDESKTOP_CLIPBOARD_FORMATS which has multiple uses:  /* Clipboard target for getting a list of native Windows clipboard formats. The
79     - The clipboard target (X jargon for "clipboard format") for rdesktop-to-rdesktop interchange     presence of this target indicates that the selection owner is another rdesktop. */
      of Windows native clipboard data.  
      This target cannot be used standalone; the requestor must keep the  
      _RDESKTOP_CLIPBOARD_TARGET property on his window denoting  
      the Windows native clipboard format being requested.  
    - The root window property set by rdesktop when it owns the clipboard,  
      denoting all Windows native clipboard formats it offers via  
      requests of the _RDESKTOP_CLIPBOARD_FORMATS target. */  
80  static Atom rdesktop_clipboard_formats_atom;  static Atom rdesktop_clipboard_formats_atom;
81    /* The clipboard target (X jargon for "clipboard format") for rdesktop-to-rdesktop
82       interchange of Windows native clipboard data. The requestor must supply the
83       desired native Windows clipboard format in the associated property. */
84    static Atom rdesktop_native_atom;
85    /* Local copy of the list of native Windows clipboard formats. */
86    static uint8 *formats_data = NULL;
87    static uint32 formats_data_length = 0;
88    /* We need to know when another rdesktop process gets or loses ownership of a
89       selection. Without XFixes we do this by touching a property on the root window
90       which will generate PropertyNotify notifications. */
91    static Atom rdesktop_selection_notify_atom;
92    /* State variables that indicate if we're currently probing the targets of the
93       selection owner. reprobe_selections indicate that the ownership changed in
94       the middle of the current probe so it should be restarted. */
95    static BOOL probing_selections, reprobe_selections;
96    /* Atoms _RDESKTOP_PRIMARY_OWNER and _RDESKTOP_CLIPBOARD_OWNER. Used as properties
97       on the root window to indicate which selections that are owned by rdesktop. */
98    static Atom rdesktop_primary_owner_atom, rdesktop_clipboard_owner_atom;
99  static Atom format_string_atom, format_utf8_string_atom, format_unicode_atom;  static Atom format_string_atom, format_utf8_string_atom, format_unicode_atom;
100  /* Atom of the INCR clipboard type (see ICCCM on "INCR Properties") */  /* Atom of the INCR clipboard type (see ICCCM on "INCR Properties") */
101  static Atom incr_atom;  static Atom incr_atom;
# Line 109  static int rdp_clipboard_request_format; Line 115  static int rdp_clipboard_request_format;
115  /* Array of offered clipboard targets that will be sent to fellow X clients upon a TARGETS request. */  /* Array of offered clipboard targets that will be sent to fellow X clients upon a TARGETS request. */
116  static Atom targets[MAX_TARGETS];  static Atom targets[MAX_TARGETS];
117  static int num_targets;  static int num_targets;
 /* Denotes that this client currently holds the PRIMARY selection. */  
 static int have_primary = 0;  
118  /* Denotes that an rdesktop (not this rdesktop) is owning the selection,  /* Denotes that an rdesktop (not this rdesktop) is owning the selection,
119     allowing us to interchange Windows native clipboard data directly. */     allowing us to interchange Windows native clipboard data directly. */
120  static int rdesktop_is_selection_owner = 0;  static BOOL rdesktop_is_selection_owner = False;
121    /* Time when we acquired the selection. */
122    static Time acquire_time = 0;
123    
124  /* Denotes that an INCR ("chunked") transfer is in progress. */  /* Denotes that an INCR ("chunked") transfer is in progress. */
125  static int g_waiting_for_INCR = 0;  static int g_waiting_for_INCR = 0;
# Line 212  xclip_provide_selection(XSelectionReques Line 218  xclip_provide_selection(XSelectionReques
218  {  {
219          XEvent xev;          XEvent xev;
220    
221            DEBUG_CLIPBOARD(("xclip_provide_selection: requestor=0x%08x, target=%s, property=%s, length=%u\n", (unsigned) req->requestor, XGetAtomName(g_display, req->target), XGetAtomName(g_display, req->property), (unsigned) length));
222    
223          XChangeProperty(g_display, req->requestor, req->property,          XChangeProperty(g_display, req->requestor, req->property,
224                          type, format, PropModeReplace, data, length);                          type, format, PropModeReplace, data, length);
225    
# Line 234  xclip_refuse_selection(XSelectionRequest Line 242  xclip_refuse_selection(XSelectionRequest
242  {  {
243          XEvent xev;          XEvent xev;
244    
245            DEBUG_CLIPBOARD(("xclip_refuse_selection: requestor=0x%08x, target=%s, property=%s\n",
246                             (unsigned) req->requestor, XGetAtomName(g_display, req->target),
247                             XGetAtomName(g_display, req->property)));
248    
249          xev.xselection.type = SelectionNotify;          xev.xselection.type = SelectionNotify;
250          xev.xselection.serial = 0;          xev.xselection.serial = 0;
251          xev.xselection.send_event = True;          xev.xselection.send_event = True;
# Line 273  helper_cliprdr_send_empty_response() Line 285  helper_cliprdr_send_empty_response()
285  static Bool  static Bool
286  xclip_send_data_with_convert(uint8 * source, size_t source_size, Atom target)  xclip_send_data_with_convert(uint8 * source, size_t source_size, Atom target)
287  {  {
288            DEBUG_CLIPBOARD(("xclip_send_data_with_convert: target=%s, size=%u\n",
289                             XGetAtomName(g_display, target), (unsigned) source_size));
290    
291  #ifdef USE_UNICODE_CLIPBOARD  #ifdef USE_UNICODE_CLIPBOARD
292          if (target == format_string_atom ||          if (target == format_string_atom ||
293              target == format_unicode_atom || target == format_utf8_string_atom)              target == format_unicode_atom || target == format_utf8_string_atom)
# Line 371  xclip_send_data_with_convert(uint8 * sou Line 386  xclip_send_data_with_convert(uint8 * sou
386                  return True;                  return True;
387          }          }
388  #endif  #endif
389          else if (target == rdesktop_clipboard_formats_atom)          else if (target == rdesktop_native_atom)
390          {          {
391                  helper_cliprdr_send_response(source, source_size + 1);                  helper_cliprdr_send_response(source, source_size + 1);
392    
# Line 391  xclip_clear_target_props() Line 406  xclip_clear_target_props()
406          XDeleteProperty(g_display, g_wnd, rdesktop_clipboard_timestamp_target_atom);          XDeleteProperty(g_display, g_wnd, rdesktop_clipboard_timestamp_target_atom);
407  }  }
408    
409    static void
410    xclip_notify_change()
411    {
412            XChangeProperty(g_display, DefaultRootWindow(g_display),
413                            rdesktop_selection_notify_atom, XA_INTEGER, 32, PropModeReplace, NULL, 0);
414    }
415    
416    static void
417    xclip_probe_selections()
418    {
419            Window primary_owner, clipboard_owner;
420    
421            if (probing_selections)
422            {
423                    DEBUG_CLIPBOARD(("Already probing selections. Scheduling reprobe.\n"));
424                    reprobe_selections = True;
425                    return;
426            }
427    
428            DEBUG_CLIPBOARD(("Probing selections.\n"));
429    
430            probing_selections = True;
431            reprobe_selections = False;
432    
433            xclip_clear_target_props();
434    
435            if (auto_mode)
436                    primary_owner = XGetSelectionOwner(g_display, primary_atom);
437            else
438                    primary_owner = None;
439    
440            clipboard_owner = XGetSelectionOwner(g_display, clipboard_atom);
441    
442            /* If we own all relevant selections then don't do anything. */
443            if (((primary_owner == g_wnd) || !auto_mode) && (clipboard_owner == g_wnd))
444                    goto end;
445    
446            /* Both available */
447            if ((primary_owner != None) && (clipboard_owner != None))
448            {
449                    primary_timestamp = 0;
450                    clipboard_timestamp = 0;
451                    XConvertSelection(g_display, primary_atom, timestamp_atom,
452                                      rdesktop_primary_timestamp_target_atom, g_wnd, CurrentTime);
453                    XConvertSelection(g_display, clipboard_atom, timestamp_atom,
454                                      rdesktop_clipboard_timestamp_target_atom, g_wnd, CurrentTime);
455                    return;
456            }
457    
458            /* Just PRIMARY */
459            if (primary_owner != None)
460            {
461                    XConvertSelection(g_display, primary_atom, targets_atom,
462                                      rdesktop_clipboard_target_atom, g_wnd, CurrentTime);
463                    return;
464            }
465    
466            /* Just CLIPBOARD */
467            if (clipboard_owner != None)
468            {
469                    XConvertSelection(g_display, clipboard_atom, targets_atom,
470                                      rdesktop_clipboard_target_atom, g_wnd, CurrentTime);
471                    return;
472            }
473    
474            DEBUG_CLIPBOARD(("No owner of any selection.\n"));
475    
476            /* FIXME:
477               Without XFIXES, we cannot reliably know the formats offered by an
478               upcoming selection owner, so we just lie about him offering
479               RDP_CF_TEXT. */
480            cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);
481    
482          end:
483            probing_selections = False;
484    }
485    
486  /* This function is called for SelectionNotify events.  /* This function is called for SelectionNotify events.
487     The SelectionNotify event is sent from the clipboard owner to the requestor     The SelectionNotify event is sent from the clipboard owner to the requestor
488     after his request was satisfied.     after his request was satisfied.
# Line 480  xclip_handle_SelectionNotify(XSelectionE Line 572  xclip_handle_SelectionNotify(XSelectionE
572                  return;                  return;
573          }          }
574    
575            if (probing_selections && reprobe_selections)
576            {
577                    probing_selections = False;
578                    xclip_probe_selections();
579                    return;
580            }
581    
582          res = XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom,          res = XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom,
583                                   0, XMaxRequestSize(g_display), False, AnyPropertyType,                                   0, XMaxRequestSize(g_display), False, AnyPropertyType,
584                                   &type, &format, &nitems, &bytes_left, &data);                                   &type, &format, &nitems, &bytes_left, &data);
# Line 504  xclip_handle_SelectionNotify(XSelectionE Line 603  xclip_handle_SelectionNotify(XSelectionE
603                  XFree(data);                  XFree(data);
604                  g_incr_target = event->target;                  g_incr_target = event->target;
605                  g_waiting_for_INCR = 1;                  g_waiting_for_INCR = 1;
606                  return;                  goto end;
607          }          }
608    
609          /* Negotiate target format */          /* Negotiate target format */
# Line 552  xclip_handle_SelectionNotify(XSelectionE Line 651  xclip_handle_SelectionNotify(XSelectionE
651                                          }                                          }
652                                  }                                  }
653  #endif  #endif
654                                    else if (supported_targets[i] == rdesktop_clipboard_formats_atom)
655                                    {
656                                            if (probing_selections && (text_target_satisfaction < 4))
657                                            {
658                                                    DEBUG_CLIPBOARD(("Other party supports native formats, choosing that as best_target\n"));
659                                                    best_text_target = supported_targets[i];
660                                                    text_target_satisfaction = 4;
661                                            }
662                                    }
663                          }                          }
664                  }                  }
665    
666                  /* Kickstarting the next step in the process of satisfying RDP's                  /* Kickstarting the next step in the process of satisfying RDP's
667                     clipboard request -- specifically, requesting the actual clipboard data.                     clipboard request -- specifically, requesting the actual clipboard data.
668                   */                   */
669                  if (best_text_target != 0)                  if ((best_text_target != 0)
670                        && (!probing_selections
671                            || (best_text_target == rdesktop_clipboard_formats_atom)))
672                  {                  {
673                          XConvertSelection(g_display, event->selection, best_text_target,                          XConvertSelection(g_display, event->selection, best_text_target,
674                                            rdesktop_clipboard_target_atom, g_wnd, event->time);                                            rdesktop_clipboard_target_atom, g_wnd, event->time);
675                          return;                          goto end;
676                  }                  }
677                  else                  else
678                  {                  {
# Line 572  xclip_handle_SelectionNotify(XSelectionE Line 682  xclip_handle_SelectionNotify(XSelectionE
682          }          }
683          else          else
684          {          {
685                  if (!xclip_send_data_with_convert(data, nitems, event->target))                  if (probing_selections)
686                    {
687                            Window primary_owner, clipboard_owner;
688    
689                            /* FIXME:
690                               Without XFIXES, we must make sure that the other
691                               rdesktop owns all relevant selections or we might try
692                               to get a native format from non-rdesktop window later
693                               on. */
694    
695                            clipboard_owner = XGetSelectionOwner(g_display, clipboard_atom);
696    
697                            if (auto_mode)
698                                    primary_owner = XGetSelectionOwner(g_display, primary_atom);
699                            else
700                                    primary_owner = clipboard_owner;
701    
702                            if (primary_owner != clipboard_owner)
703                                    goto fail;
704    
705                            DEBUG_CLIPBOARD(("Got fellow rdesktop formats\n"));
706                            probing_selections = False;
707                            rdesktop_is_selection_owner = True;
708                            cliprdr_send_native_format_announce(data, nitems);
709                    }
710                    else if (!xclip_send_data_with_convert(data, nitems, event->target))
711                  {                  {
712                          goto fail;                          goto fail;
713                  }                  }
714          }          }
715    
716          XFree(data);        end:
717            if (data)
718                    XFree(data);
719    
720          return;          return;
721    
722        fail:        fail:
723          xclip_clear_target_props();          xclip_clear_target_props();
724          if (data)          if (probing_selections)
725                  XFree(data);          {
726          helper_cliprdr_send_empty_response();                  DEBUG_CLIPBOARD(("Unable to find suitable target. Using default text format.\n"));
727                    probing_selections = False;
728                    rdesktop_is_selection_owner = False;
729    
730                    /* FIXME:
731                       Without XFIXES, we cannot reliably know the formats offered by an
732                       upcoming selection owner, so we just lie about him offering
733                       RDP_CF_TEXT. */
734                    cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);
735            }
736            else
737            {
738                    helper_cliprdr_send_empty_response();
739            }
740            goto end;
741  }  }
742    
743  /* This function is called for SelectionRequest events.  /* This function is called for SelectionRequest events.
# Line 598  xclip_handle_SelectionRequest(XSelection Line 749  xclip_handle_SelectionRequest(XSelection
749  {  {
750          unsigned long nitems, bytes_left;          unsigned long nitems, bytes_left;
751          unsigned char *prop_return;          unsigned char *prop_return;
         uint32 *wanted_format;  
752          int format, res;          int format, res;
753          Atom type;          Atom type;
754    
# Line 614  xclip_handle_SelectionRequest(XSelection Line 764  xclip_handle_SelectionRequest(XSelection
764          }          }
765          else if (event->target == timestamp_atom)          else if (event->target == timestamp_atom)
766          {          {
767                  xclip_provide_selection(event, XA_INTEGER, 32, (uint8 *) & g_last_gesturetime, 1);                  xclip_provide_selection(event, XA_INTEGER, 32, (uint8 *) & acquire_time, 1);
768                  return;                  return;
769          }          }
770            else if (event->target == rdesktop_clipboard_formats_atom)
771            {
772                    xclip_provide_selection(event, XA_STRING, 8, formats_data, formats_data_length);
773            }
774          else          else
775          {          {
776                  /* All the following targets require an async operation with the RDP server                  /* All the following targets require an async operation with the RDP server
# Line 628  xclip_handle_SelectionRequest(XSelection Line 782  xclip_handle_SelectionRequest(XSelection
782                          xclip_refuse_selection(event);                          xclip_refuse_selection(event);
783                          return;                          return;
784                  }                  }
785                  if (event->target == rdesktop_clipboard_formats_atom)                  if (event->target == rdesktop_native_atom)
786                  {                  {
787                          /* Before the requestor makes a request for the _RDESKTOP_CLIPBOARD_FORMATS target,                          /* Before the requestor makes a request for the _RDESKTOP_NATIVE target,
788                             he should declare requestor[_RDESKTOP_CLIPBOARD_TARGET] = CF_SOMETHING.                             he should declare requestor[property] = CF_SOMETHING. */
                            Otherwise, we default to RDP_CF_TEXT.  
                          */  
789                          res = XGetWindowProperty(g_display, event->requestor,                          res = XGetWindowProperty(g_display, event->requestor,
790                                                   rdesktop_clipboard_target_atom, 0, 1, True,                                                   event->property, 0, 1, True,
791                                                   XA_INTEGER, &type, &format, &nitems, &bytes_left,                                                   XA_INTEGER, &type, &format, &nitems, &bytes_left,
792                                                   &prop_return);                                                   &prop_return);
793                          wanted_format = (uint32 *) prop_return;                          if (res != Success)
794                          format = (res == Success) ? *wanted_format : RDP_CF_TEXT;                          {
795                                    DEBUG_CLIPBOARD(("Requested native format but didn't specifiy which.\n"));
796                                    xclip_refuse_selection(event);
797                                    return;
798                            }
799    
800                            format = *(uint32 *) prop_return;
801                          XFree(prop_return);                          XFree(prop_return);
802                  }                  }
803                  else if (event->target == format_string_atom || event->target == XA_STRING)                  else if (event->target == format_string_atom || event->target == XA_STRING)
# Line 687  void Line 845  void
845  xclip_handle_SelectionClear(void)  xclip_handle_SelectionClear(void)
846  {  {
847          DEBUG_CLIPBOARD(("xclip_handle_SelectionClear\n"));          DEBUG_CLIPBOARD(("xclip_handle_SelectionClear\n"));
848          have_primary = 0;          xclip_notify_change();
849          XDeleteProperty(g_display, DefaultRootWindow(g_display), rdesktop_clipboard_formats_atom);          xclip_probe_selections();
         /* FIXME:  
            Without XFIXES, we cannot reliably know the formats offered by the  
            new owner of the X11 clipboard, so we just lie about him  
            offering RDP_CF_TEXT. */  
         cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);  
850  }  }
851    
852  /* Called when any property changes in our window or the root window. */  /* Called when any property changes in our window or the root window. */
# Line 703  xclip_handle_PropertyNotify(XPropertyEve Line 856  xclip_handle_PropertyNotify(XPropertyEve
856          unsigned long nitems;          unsigned long nitems;
857          unsigned long offset = 0;          unsigned long offset = 0;
858          unsigned long bytes_left = 1;          unsigned long bytes_left = 1;
859          int format, res;          int format;
860          XWindowAttributes wa;          XWindowAttributes wa;
861          uint8 *data;          uint8 *data;
862          Atom type;          Atom type;
# Line 761  xclip_handle_PropertyNotify(XPropertyEve Line 914  xclip_handle_PropertyNotify(XPropertyEve
914                  return;                  return;
915          }          }
916    
917          if ((event->atom == rdesktop_clipboard_formats_atom) &&          if ((event->atom == rdesktop_selection_notify_atom) &&
918              (event->window == DefaultRootWindow(g_display)) &&              (event->window == DefaultRootWindow(g_display)))
919              !have_primary /* not interested in our own events */ )                  xclip_probe_selections();
         {  
                 if (event->state == PropertyNewValue)  
                 {  
                         DEBUG_CLIPBOARD(("xclip_handle_PropertyNotify: getting fellow rdesktop formats\n"));  
   
                         res = XGetWindowProperty(g_display, DefaultRootWindow(g_display),  
                                                  rdesktop_clipboard_formats_atom, 0,  
                                                  XMaxRequestSize(g_display), False, XA_STRING,  
                                                  &type, &format, &nitems, &bytes_left, &data);  
   
                         if ((res == Success) && (nitems > 0))  
                         {  
                                 cliprdr_send_native_format_announce(data, nitems);  
                                 rdesktop_is_selection_owner = 1;  
                                 return;  
                         }  
                 }  
   
                 /* For some reason, we couldn't announce the native formats */  
                 cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);  
                 rdesktop_is_selection_owner = 0;  
         }  
920  }  }
921  #endif  #endif
922    
# Line 798  xclip_handle_PropertyNotify(XPropertyEve Line 929  xclip_handle_PropertyNotify(XPropertyEve
929  void  void
930  ui_clip_format_announce(uint8 * data, uint32 length)  ui_clip_format_announce(uint8 * data, uint32 length)
931  {  {
932          XSetSelectionOwner(g_display, primary_atom, g_wnd, g_last_gesturetime);          acquire_time = g_last_gesturetime;
933    
934            XSetSelectionOwner(g_display, primary_atom, g_wnd, acquire_time);
935          if (XGetSelectionOwner(g_display, primary_atom) != g_wnd)          if (XGetSelectionOwner(g_display, primary_atom) != g_wnd)
         {  
936                  warning("Failed to aquire ownership of PRIMARY clipboard\n");                  warning("Failed to aquire ownership of PRIMARY clipboard\n");
                 return;  
         }  
937    
938          have_primary = 1;          XSetSelectionOwner(g_display, clipboard_atom, g_wnd, acquire_time);
         XChangeProperty(g_display, DefaultRootWindow(g_display),  
                         rdesktop_clipboard_formats_atom, XA_STRING, 8, PropModeReplace, data,  
                         length);  
   
         XSetSelectionOwner(g_display, clipboard_atom, g_wnd, g_last_gesturetime);  
939          if (XGetSelectionOwner(g_display, clipboard_atom) != g_wnd)          if (XGetSelectionOwner(g_display, clipboard_atom) != g_wnd)
940                  warning("Failed to aquire ownership of CLIPBOARD clipboard\n");                  warning("Failed to aquire ownership of CLIPBOARD clipboard\n");
941    
942            if (formats_data)
943                    xfree(formats_data);
944            formats_data = xmalloc(length);
945            memcpy(formats_data, data, length);
946            formats_data_length = length;
947    
948            xclip_notify_change();
949  }  }
950    
951  /* Called when the RDP server responds with clipboard data (after we've requested it). */  /* Called when the RDP server responds with clipboard data (after we've requested it). */
# Line 876  ui_clip_handle_data(uint8 * data, uint32 Line 1009  ui_clip_handle_data(uint8 * data, uint32
1009                     for further conversions. */                     for further conversions. */
1010          }          }
1011  #endif  #endif
1012          else if (selection_request.target == rdesktop_clipboard_formats_atom)          else if (selection_request.target == rdesktop_native_atom)
1013          {          {
1014                  /* Pass as-is */                  /* Pass as-is */
1015          }          }
1016          else          else
1017          {          {
1018                    DEBUG_CLIPBOARD(("ui_clip_handle_data: BUG! I don't know how to convert selection target %s!\n", XGetAtomName(g_display, selection_request.target)));
1019                  xclip_refuse_selection(&selection_request);                  xclip_refuse_selection(&selection_request);
1020                  has_selection_request = False;                  has_selection_request = False;
1021                  return;                  return;
# Line 895  ui_clip_handle_data(uint8 * data, uint32 Line 1029  ui_clip_handle_data(uint8 * data, uint32
1029  }  }
1030    
1031  void  void
1032    ui_clip_request_failed()
1033    {
1034            xclip_refuse_selection(&selection_request);
1035            has_selection_request = False;
1036    }
1037    
1038    void
1039  ui_clip_request_data(uint32 format)  ui_clip_request_data(uint32 format)
1040  {  {
1041          Window primary_owner, clipboard_owner;          Window primary_owner, clipboard_owner;
# Line 902  ui_clip_request_data(uint32 format) Line 1043  ui_clip_request_data(uint32 format)
1043          DEBUG_CLIPBOARD(("Request from server for format %d\n", format));          DEBUG_CLIPBOARD(("Request from server for format %d\n", format));
1044          rdp_clipboard_request_format = format;          rdp_clipboard_request_format = format;
1045    
1046            if (probing_selections)
1047            {
1048                    DEBUG_CLIPBOARD(("ui_clip_request_data: Selection probe in progress. Cannot handle request.\n"));
1049                    helper_cliprdr_send_empty_response();
1050                    return;
1051            }
1052    
1053          xclip_clear_target_props();          xclip_clear_target_props();
1054    
1055          if (rdesktop_is_selection_owner)          if (rdesktop_is_selection_owner)
# Line 909  ui_clip_request_data(uint32 format) Line 1057  ui_clip_request_data(uint32 format)
1057                  XChangeProperty(g_display, g_wnd, rdesktop_clipboard_target_atom,                  XChangeProperty(g_display, g_wnd, rdesktop_clipboard_target_atom,
1058                                  XA_INTEGER, 32, PropModeReplace, (unsigned char *) &format, 1);                                  XA_INTEGER, 32, PropModeReplace, (unsigned char *) &format, 1);
1059    
1060                  XConvertSelection(g_display, primary_atom, rdesktop_clipboard_formats_atom,                  XConvertSelection(g_display, primary_atom, rdesktop_native_atom,
1061                                    rdesktop_clipboard_target_atom, g_wnd, CurrentTime);                                    rdesktop_clipboard_target_atom, g_wnd, CurrentTime);
1062                  return;                  return;
1063          }          }
# Line 956  ui_clip_request_data(uint32 format) Line 1104  ui_clip_request_data(uint32 format)
1104  void  void
1105  ui_clip_sync(void)  ui_clip_sync(void)
1106  {  {
1107          cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);          xclip_probe_selections();
1108  }  }
1109    
1110  void  void
# Line 1000  xclip_init(void) Line 1148  xclip_init(void)
1148          format_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False);          format_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False);
1149          format_unicode_atom = XInternAtom(g_display, "text/unicode", False);          format_unicode_atom = XInternAtom(g_display, "text/unicode", False);
1150    
1151          /* rdesktop sets _RDESKTOP_CLIPBOARD_FORMATS on the root window when acquiring the clipboard.          /* rdesktop sets _RDESKTOP_SELECTION_NOTIFY on the root window when acquiring the clipboard.
1152             Other interested rdesktops can use this to notify their server of the available formats. */             Other interested rdesktops can use this to notify their server of the available formats. */
1153            rdesktop_selection_notify_atom =
1154                    XInternAtom(g_display, "_RDESKTOP_SELECTION_NOTIFY", False);
1155            XSelectInput(g_display, DefaultRootWindow(g_display), PropertyChangeMask);
1156            probing_selections = False;
1157    
1158            rdesktop_native_atom = XInternAtom(g_display, "_RDESKTOP_NATIVE", False);
1159          rdesktop_clipboard_formats_atom =          rdesktop_clipboard_formats_atom =
1160                  XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_FORMATS", False);                  XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_FORMATS", False);
1161          XSelectInput(g_display, DefaultRootWindow(g_display), PropertyChangeMask);          rdesktop_primary_owner_atom = XInternAtom(g_display, "_RDESKTOP_PRIMARY_OWNER", False);
1162            rdesktop_clipboard_owner_atom = XInternAtom(g_display, "_RDESKTOP_CLIPBOARD_OWNER", False);
1163    
1164          num_targets = 0;          num_targets = 0;
1165          targets[num_targets++] = targets_atom;          targets[num_targets++] = targets_atom;
1166          targets[num_targets++] = timestamp_atom;          targets[num_targets++] = timestamp_atom;
1167            targets[num_targets++] = rdesktop_native_atom;
1168          targets[num_targets++] = rdesktop_clipboard_formats_atom;          targets[num_targets++] = rdesktop_clipboard_formats_atom;
1169  #ifdef USE_UNICODE_CLIPBOARD  #ifdef USE_UNICODE_CLIPBOARD
1170          targets[num_targets++] = format_utf8_string_atom;          targets[num_targets++] = format_utf8_string_atom;

Legend:
Removed from v.1209  
changed lines
  Added in v.1213

  ViewVC Help
Powered by ViewVC 1.1.26