/[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 462 by astrand, Tue Sep 2 10:42:16 2003 UTC revision 913 by astrand, Mon Jun 27 12:18:48 2005 UTC
# Line 36  static Atom targets[NUM_TARGETS]; Line 36  static Atom targets[NUM_TARGETS];
36  static int have_primary = 0;  static int have_primary = 0;
37  static int rdesktop_is_selection_owner = 0;  static int rdesktop_is_selection_owner = 0;
38    
39    static int g_waiting_for_INCR = 0;
40    static uint8 *g_clip_buffer = 0;
41    static uint32 g_clip_buflen = 0;
42    
43    /* Replace CR-LF to LF (well, rather removing all CR:s) This is done
44       in-place. The length is updated. Handles embedded nulls */
45    static void
46    crlf2lf(uint8 * data, uint32 * length)
47    {
48            uint8 *dst, *src;
49            src = dst = data;
50            while (src < data + *length)
51            {
52                    if (*src != '\x0d')
53                            *dst++ = *src;
54                    src++;
55            }
56            *length = dst - data;
57    }
58    
59    /* Translate LF to CR-LF. To do this, we must allocate more memory.  
60       The length is updated. */
61    static uint8 *
62    lf2crlf(uint8 * data, uint32 * length)
63    {
64            uint8 *result, *p, *o;
65    
66            /* Worst case: Every char is LF */
67            result = xmalloc(*length * 2);
68    
69            p = data;
70            o = result;
71    
72            while (p < data + *length)
73            {
74                    if (*p == '\x0a')
75                            *o++ = '\x0d';
76                    *o++ = *p++;
77            }
78            *length = o - result;
79    
80            /* Convenience */
81            *o++ = '\0';
82    
83            return result;
84    }
85    
86    
87  static void  static void
88  xclip_provide_selection(XSelectionRequestEvent * req, Atom type, unsigned int format, uint8 * data,  xclip_provide_selection(XSelectionRequestEvent * req, Atom type, unsigned int format, uint8 * data,
89                          uint32 length)                          uint32 length)
# Line 60  void Line 108  void
108  xclip_handle_SelectionNotify(XSelectionEvent * event)  xclip_handle_SelectionNotify(XSelectionEvent * event)
109  {  {
110          unsigned long nitems, bytes_left;          unsigned long nitems, bytes_left;
111            XWindowAttributes wa;
112          Atom type, best_target, text_target;          Atom type, best_target, text_target;
113          Atom *supported_targets;          Atom *supported_targets;
114          int res, i, format;          int res, i, format;
# Line 86  xclip_handle_SelectionNotify(XSelectionE Line 135  xclip_handle_SelectionNotify(XSelectionE
135                  goto fail;                  goto fail;
136          }          }
137    
138            /* Negotiate target format */
139          if (event->target == targets_atom)          if (event->target == targets_atom)
140          {          {
141                  /* FIXME: We should choose format here based on what the server wanted */                  /* FIXME: We should choose format here based on what the server wanted */
# Line 102  xclip_handle_SelectionNotify(XSelectionE Line 152  xclip_handle_SelectionNotify(XSelectionE
152                                  {                                  {
153                                          DEBUG_CLIPBOARD(("Other party supports TEXT, choosing that as best_target\n"));                                          DEBUG_CLIPBOARD(("Other party supports TEXT, choosing that as best_target\n"));
154                                          best_target = text_target;                                          best_target = text_target;
155                                            break;
156                                  }                                  }
157                          }                          }
158                          XFree(data);                          XFree(data);
# Line 114  xclip_handle_SelectionNotify(XSelectionE Line 165  xclip_handle_SelectionNotify(XSelectionE
165    
166          if (type == incr_atom)          if (type == incr_atom)
167          {          {
168                  warning("We don't support INCR transfers at this time. Try cutting less data.\n");                  DEBUG_CLIPBOARD(("Received INCR.\n"));
169                  goto fail;  
170                    XGetWindowAttributes(g_display, g_wnd, &wa);
171                    if ((wa.your_event_mask | PropertyChangeMask) != wa.your_event_mask)
172                    {
173                            XSelectInput(g_display, g_wnd, (wa.your_event_mask | PropertyChangeMask));
174                    }
175                    XDeleteProperty(g_display, g_wnd, type);
176                    XFree(data);
177                    g_waiting_for_INCR = 1;
178    
179                    if ((XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom, 0,
180                                            4096L, True, AnyPropertyType,
181                                            &type, &format, &nitems, &bytes_left, &data) != Success))
182                    {
183                            DEBUG_CLIPBOARD(("XGetWindowProperty failed.\n"));
184                            goto fail;
185                    }
186                    else
187                    {
188                            uint8 *translated_data;
189                            uint32 length = nitems;
190    
191                            translated_data = lf2crlf(data, &length);
192    
193                            g_clip_buffer = (uint8 *) xmalloc(length);
194                            strncpy(g_clip_buffer, translated_data, length);
195                            xfree(translated_data);
196                            g_clip_buflen = length;
197    
198                            XFree(data);
199                            return;
200                    }
201          }          }
202    
203          cliprdr_send_data(data, nitems + 1);          /* Translate linebreaks, but only if not getting data from
204               other rdesktop instance */
205            if (event->target != rdesktop_clipboard_formats_atom)
206            {
207                    uint8 *translated_data;
208                    uint32 length = nitems;
209    
210                    DEBUG_CLIPBOARD(("Translating linebreaks before sending data\n"));
211                    translated_data = lf2crlf(data, &length);
212                    cliprdr_send_data(translated_data, length + 1);
213                    xfree(translated_data); /* Not the same thing as XFree! */
214            }
215            else
216            {
217                    cliprdr_send_data(data, nitems + 1);
218            }
219          XFree(data);          XFree(data);
220    
221          if (!rdesktop_is_selection_owner)          if (!rdesktop_is_selection_owner)
# Line 133  void Line 230  void
230  xclip_handle_SelectionRequest(XSelectionRequestEvent * event)  xclip_handle_SelectionRequest(XSelectionRequestEvent * event)
231  {  {
232          unsigned long nitems, bytes_left;          unsigned long nitems, bytes_left;
233            unsigned char *prop_return;
234          uint32 *wanted_format;          uint32 *wanted_format;
235          int format, res;          int format, res;
236          Atom type;          Atom type;
# Line 156  xclip_handle_SelectionRequest(XSelection Line 254  xclip_handle_SelectionRequest(XSelection
254          {          {
255                  res = XGetWindowProperty(g_display, event->requestor,                  res = XGetWindowProperty(g_display, event->requestor,
256                                           rdesktop_clipboard_target_atom, 0, 1, True, XA_INTEGER,                                           rdesktop_clipboard_target_atom, 0, 1, True, XA_INTEGER,
257                                           &type, &format, &nitems, &bytes_left,                                           &type, &format, &nitems, &bytes_left, &prop_return);
258                                           (unsigned char **) &wanted_format);                  wanted_format = (uint32 *) prop_return;
259                  format = (res == Success) ? *wanted_format : CF_TEXT;                  format = (res == Success) ? *wanted_format : CF_TEXT;
260                    /* FIXME: Need to free returned data? */
261          }          }
262          else          else
263          {          {
# Line 184  xclip_handle_PropertyNotify(XPropertyEve Line 283  xclip_handle_PropertyNotify(XPropertyEve
283  {  {
284          unsigned long nitems, bytes_left;          unsigned long nitems, bytes_left;
285          int format, res;          int format, res;
286            XWindowAttributes wa;
287          uint8 *data;          uint8 *data;
288          Atom type;          Atom type;
289    
290            if (event->state == PropertyNewValue && g_waiting_for_INCR)
291            {
292                    DEBUG_CLIPBOARD(("x_clip_handle_PropertyNotify: g_waiting_for_INCR != 0\n"));
293                    if ((XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom, 0,
294                                            4096L, True, AnyPropertyType,
295                                            &type, &format, &nitems, &bytes_left, &data) != Success))
296                    {
297                            XFree(data);
298                            return;
299                    }
300    
301                    if (nitems == 0)
302                    {
303                            XGetWindowAttributes(g_display, g_wnd, &wa);
304                            XSelectInput(g_display, g_wnd, (wa.your_event_mask ^ PropertyChangeMask));
305                            XFree(data);
306                            g_waiting_for_INCR = 0;
307    
308                            if (g_clip_buflen > 0)
309                            {
310                                    cliprdr_send_data(g_clip_buffer, g_clip_buflen + 1);
311    
312                                    if (!rdesktop_is_selection_owner)
313                                            cliprdr_send_text_format_announce();
314    
315                                    xfree(g_clip_buffer);
316                                    g_clip_buffer = 0;
317                                    g_clip_buflen = 0;
318                            }
319                    }
320                    else
321                    {
322                            uint8 *translated_data;
323                            uint32 length = nitems;
324    
325                            DEBUG_CLIPBOARD(("Translating linebreaks before sending data\n"));
326                            translated_data = lf2crlf(data, &length);
327    
328                            uint8 *tmp = xmalloc(length + g_clip_buflen);
329                            strncpy(tmp, g_clip_buffer, g_clip_buflen);
330                            xfree(g_clip_buffer);
331    
332                            strncpy(tmp + g_clip_buflen, translated_data, length);
333                            xfree(translated_data);
334    
335                            g_clip_buffer = tmp;
336                            g_clip_buflen += length;
337    
338                            XFree(data);
339                            return;
340                    }
341            }
342    
343          if (event->atom != rdesktop_clipboard_formats_atom)          if (event->atom != rdesktop_clipboard_formats_atom)
344                  return;                  return;
345    
# Line 215  xclip_handle_PropertyNotify(XPropertyEve Line 368  xclip_handle_PropertyNotify(XPropertyEve
368    
369    
370  void  void
371  ui_clip_format_announce(char *data, uint32 length)  ui_clip_format_announce(uint8 * data, uint32 length)
372  {  {
373          XSetSelectionOwner(g_display, primary_atom, g_wnd, g_last_gesturetime);          XSetSelectionOwner(g_display, primary_atom, g_wnd, g_last_gesturetime);
374          if (XGetSelectionOwner(g_display, primary_atom) != g_wnd)          if (XGetSelectionOwner(g_display, primary_atom) != g_wnd)
# Line 236  ui_clip_format_announce(char *data, uint Line 389  ui_clip_format_announce(char *data, uint
389    
390    
391  void  void
392  ui_clip_handle_data(char *data, uint32 length)  ui_clip_handle_data(uint8 * data, uint32 length)
393  {  {
394            if (selection_request.target != rdesktop_clipboard_formats_atom)
395            {
396                    uint8 *firstnull;
397    
398                    /* translate linebreaks */
399                    crlf2lf(data, &length);
400    
401                    /* Only send data up to null byte, if any */
402                    firstnull = (uint8 *) strchr((char *) data, '\0');
403                    if (firstnull)
404                    {
405                            length = firstnull - data + 1;
406                    }
407            }
408    
409          xclip_provide_selection(&selection_request, XA_STRING, 8, data, length - 1);          xclip_provide_selection(&selection_request, XA_STRING, 8, data, length - 1);
410  }  }
411    
# Line 301  xclip_init(void) Line 469  xclip_init(void)
469          incr_atom = XInternAtom(g_display, "INCR", False);          incr_atom = XInternAtom(g_display, "INCR", False);
470          targets[0] = targets_atom;          targets[0] = targets_atom;
471          targets[1] = XInternAtom(g_display, "TEXT", False);          targets[1] = XInternAtom(g_display, "TEXT", False);
472          targets[2] = XInternAtom(g_display, "UTF8_STRING", False);          targets[2] = XInternAtom(g_display, "STRING", False);
473          targets[3] = XInternAtom(g_display, "text/unicode", False);          targets[3] = XInternAtom(g_display, "text/unicode", False);
474          targets[4] = XInternAtom(g_display, "TIMESTAMP", False);          targets[4] = XInternAtom(g_display, "TIMESTAMP", False);
475          targets[5] = XA_STRING;          targets[5] = XA_STRING;

Legend:
Removed from v.462  
changed lines
  Added in v.913

  ViewVC Help
Powered by ViewVC 1.1.26