/[rdesktop]/sourceforge.net/trunk/rdesktop/cliprdr.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/cliprdr.c

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

revision 395 by forsberg, Fri Jun 6 09:32:15 2003 UTC revision 396 by forsberg, Fri Jun 6 09:32:56 2003 UTC
# Line 40  static int have_primary = 0; Line 40  static int have_primary = 0;
40  static int rdesktop_is_selection_owner = 0;  static int rdesktop_is_selection_owner = 0;
41    
42  static void  static void
43  cliprdr_print_server_formats(void)  cliprdr_print_server_formats(void)
44  {  {
45  #ifdef WITH_DEBUG_CLIPBOARD  #ifdef WITH_DEBUG_CLIPBOARD
46          cliprdr_dataformat *this;          cliprdr_dataformat *this;
47          uint16 i = 0;          uint16 i = 0;
48          this = server_formats;          this = server_formats;
49          DEBUG_CLIPBOARD(("There should be %d server formats.\n", num_server_formats));          DEBUG_CLIPBOARD(("There should be %d server formats.\n", num_server_formats));
50          while (NULL != this)          while (NULL != this)
51          {          {
52                  DEBUG_CLIPBOARD(("Format code %d\n", this->identifier));                  DEBUG_CLIPBOARD(("Format code %d\n", this->identifier));
53                  i++;                  i++;
# Line 56  cliprdr_print_server_formats(void) Line 56  cliprdr_print_server_formats(void)
56          DEBUG_CLIPBOARD(("There were %d server formats.\n", i));          DEBUG_CLIPBOARD(("There were %d server formats.\n", i));
57  #endif  #endif
58  }  }
59    
60  /*  /*
61  static void  static void
62  cliprdr_set_selection_timestamp(void)  cliprdr_set_selection_timestamp(void)
# Line 73  cliprdr_set_selection_timestamp(void) Line 74  cliprdr_set_selection_timestamp(void)
74          fflush(stdout);          fflush(stdout);
75          selection_timestamp = xev.xproperty.time;          selection_timestamp = xev.xproperty.time;
76  }        }      
77  */        */
78    
79  static void  static void
80  cliprdr_send_format_announce(void)  cliprdr_send_format_announce(void)
81  {  {
82          STREAM s;          STREAM s;
83    
84          DEBUG_CLIPBOARD(("Sending (empty) format announce\n"));          DEBUG_CLIPBOARD(("Sending (empty) format announce\n"));
85          int number_of_formats = 1;          int number_of_formats = 1;
86          s = sec_init(encryption ? SEC_ENCRYPT : 0, number_of_formats*36+12+4+4);          s = sec_init(encryption ? SEC_ENCRYPT : 0, number_of_formats * 36 + 12 + 4 + 4);
87          out_uint32_le(s, number_of_formats*36+12);          out_uint32_le(s, number_of_formats * 36 + 12);
88          out_uint32_le(s, 0x13);          out_uint32_le(s, 0x13);
89          out_uint16_le(s, 2);          out_uint16_le(s, 2);
90          out_uint16_le(s, 0);          out_uint16_le(s, 0);
91          out_uint32_le(s, number_of_formats*36);          out_uint32_le(s, number_of_formats * 36);
92            
93          //      out_uint32_le(s, 0xd); // FIXME: This is a rather bogus unicode text description..          //      out_uint32_le(s, 0xd); // FIXME: This is a rather bogus unicode text description..
94          //      rdp_out_unistr(s, "", 16);          //      rdp_out_unistr(s, "", 16);
95          //      out_uint8s(s, 32);          //      out_uint8s(s, 32);
96    
97    
98          out_uint32_le(s, 1); // FIXME: This is a rather bogus text description..          out_uint32_le(s, 1);    // FIXME: This is a rather bogus text description..
99          out_uint8s(s, 32);          out_uint8s(s, 32);
100    
101          out_uint32_le(s, 0);          out_uint32_le(s, 0);
102    
103          s_mark_end(s);          s_mark_end(s);
104          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                             clipboard_channelno);  
105  }  }
106    
107  void cliprdr_ipc_format_announce(unsigned char *data, uint16 length)  void
108    cliprdr_ipc_format_announce(unsigned char *data, uint16 length)
109  {  {
110          STREAM s;          STREAM s;
111          rdesktop_is_selection_owner = 1;          rdesktop_is_selection_owner = 1;
112          DEBUG_CLIPBOARD(("cliprdr_ipc_format_announce called, length is %d, data is %s, sending native format announce\n", length, data));          DEBUG_CLIPBOARD(("cliprdr_ipc_format_announce called, length is %d, data is %s, sending native format announce\n", length, data));
113    
114          s = sec_init(encryption ? SEC_ENCRYPT : 0, length+12+4+4);          s = sec_init(encryption ? SEC_ENCRYPT : 0, length + 12 + 4 + 4);
115          out_uint32_le(s, length+12);          out_uint32_le(s, length + 12);
116          out_uint32_le(s, 0x13);          out_uint32_le(s, 0x13);
117          out_uint16_le(s, 2);          out_uint16_le(s, 2);
118          out_uint16_le(s, 0);          out_uint16_le(s, 0);
119          out_uint32_le(s, length);          out_uint32_le(s, length);
120          out_uint8p(s, data, length);          out_uint8p(s, data, length);
121          out_uint32_le(s, 0); // Pad          out_uint32_le(s, 0);    // Pad
122          s_mark_end(s);          s_mark_end(s);
123    
124          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                             clipboard_channelno);  
125  }  }
126    
127    
# Line 131  static void Line 131  static void
131  cliprdr_send_empty_datapacket(void)  cliprdr_send_empty_datapacket(void)
132  {  {
133          STREAM out;          STREAM out;
134          out =  sec_init(encryption ? SEC_ENCRYPT : 0,          out = sec_init(encryption ? SEC_ENCRYPT : 0, 20);
                         20);  
135          out_uint32_le(out, 12);          out_uint32_le(out, 12);
136          out_uint32_le(out, 0x13);          out_uint32_le(out, 0x13);
137          out_uint16_le(out, 5);          out_uint16_le(out, 5);
# Line 141  cliprdr_send_empty_datapacket(void) Line 140  cliprdr_send_empty_datapacket(void)
140          /* Insert null string here? */          /* Insert null string here? */
141          out_uint32_le(out, 0);          out_uint32_le(out, 0);
142          s_mark_end(out);          s_mark_end(out);
143            
144          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                             clipboard_channelno);  
145  }  }
146    
147    
148  void  void
149  cliprdr_handle_SelectionNotify(XSelectionEvent *event)  cliprdr_handle_SelectionNotify(XSelectionEvent * event)
150  {  {
151    
152          unsigned char   *data, *datap;          unsigned char *data, *datap;
153          unsigned long   nitems, bytes_left;          unsigned long nitems, bytes_left;
154            
155          unsigned long bytes_left_to_transfer;          unsigned long bytes_left_to_transfer;
156          int res, i;          int res, i;
157    
# Line 163  cliprdr_handle_SelectionNotify(XSelectio Line 161  cliprdr_handle_SelectionNotify(XSelectio
161          Atom *supported_targets;          Atom *supported_targets;
162    
163          STREAM out;          STREAM out;
164            
165          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));
166    
167          if (None == event->property) {          if (None == event->property)
168            {
169                  cliprdr_send_empty_datapacket();                  cliprdr_send_empty_datapacket();
170                  return; /* Selection failed */                  return;         /* Selection failed */
171          }          }
172    
173          DEBUG_CLIPBOARD(("selection: %s, target: %s, property: %s\n",          DEBUG_CLIPBOARD(("selection: %s, target: %s, property: %s\n",
174                           XGetAtomName(display, event->selection),                           XGetAtomName(display, event->selection),
175                           XGetAtomName(display, event->target),                           XGetAtomName(display, event->target),
176                           XGetAtomName(display, event->property)));                           XGetAtomName(display, event->property)));
177    
178          if (targets_atom == event->target) {          if (targets_atom == event->target)
179            {
180                  /* Response to TARGETS request. Let's find the target                  /* Response to TARGETS request. Let's find the target
181                     we want and request that */                     we want and request that */
182                  res = XGetWindowProperty(display, wnd,                  res = XGetWindowProperty(display, wnd,
183                                           rdesktop_clipboard_target_atom,                                           rdesktop_clipboard_target_atom,
184                                           0L, 4096L, False, AnyPropertyType,                                           0L, 4096L, False, AnyPropertyType,
185                                           &type_return,                                           &type_return, &format, &nitems, &bytes_left, &data);
                                          &format, &nitems, &bytes_left, &data);  
186    
187                  if (Success != res)                  if (Success != res)
188                  {                  {
189                          DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));                          DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
190                          cliprdr_send_empty_datapacket();                          cliprdr_send_empty_datapacket();
191                          return;                          return;
192                  }                  }
193    
194                  if (None == type_return)                  if (None == type_return)
195                          /* The owner might no support TARGETS. Just try                          /* The owner might no support TARGETS. Just try
196                             STRING */                             STRING */
197                          best_target = XA_STRING;                          best_target = XA_STRING;
198                  else                  else
199                  {                  {
200                          /* FIXME: We should choose format here based                          /* FIXME: We should choose format here based
201                             on what the server wanted */                             on what the server wanted */
202                          supported_targets = (Atom *)data;                          supported_targets = (Atom *) data;
203                          for (i=0;i<nitems;i++)                          for (i = 0; i < nitems; i++)
204                          {                          {
205                                  DEBUG_CLIPBOARD(("Target %d: %s\n",                                  DEBUG_CLIPBOARD(("Target %d: %s\n",
206                                                   i, XGetAtomName(display,                                                   i, XGetAtomName(display, supported_targets[i])));
                                                                  supported_targets[i])));  
207                          }                          }
208                          best_target = XInternAtom(display, "TEXT", False);                          best_target = XInternAtom(display, "TEXT", False);
209                            
210                            
211                  }                  }
212    
213                  XConvertSelection(display, primary_atom,                  XConvertSelection(display, primary_atom,
214                                    best_target,                                    best_target, rdesktop_clipboard_target_atom, wnd, event->time);
                                   rdesktop_clipboard_target_atom,  
                                   wnd, event->time);  
215    
216          }          }
217    
218          else  /* Other clipboard data */          else                    /* Other clipboard data */
219          {          {
220                    
221                  res = XGetWindowProperty(display, wnd,                  res = XGetWindowProperty(display, wnd,
222                                           rdesktop_clipboard_target_atom,                                           rdesktop_clipboard_target_atom,
223                                           0L, 0x1FFFFFF,                                           0L, 0x1FFFFFF,
224                                           True, AnyPropertyType,                                           True, AnyPropertyType,
225                                           &type_return,                                           &type_return, &format, &nitems, &bytes_left, &data);
                                          &format, &nitems, &bytes_left, &data);  
226    
227    
228                  /* FIXME: We need to handle INCR as well,                  /* FIXME: We need to handle INCR as well,
229                   this is a temporary solution. */                     this is a temporary solution. */
230    
231                  if (incr_atom == type_return)                  if (incr_atom == type_return)
232                  {                  {
233                          warning("We don't support INCR transfers at this time. Try cutting less data\n");                          warning("We don't support INCR transfers at this time. Try cutting less data\n");
234                          cliprdr_send_empty_datapacket();                          cliprdr_send_empty_datapacket();
235                  }                  }
236    
237    
238                  if (Success != res)                  if (Success != res)
239                  {                  {
240                          DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));                          DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
241                          cliprdr_send_empty_datapacket();                          cliprdr_send_empty_datapacket();
# Line 249  cliprdr_handle_SelectionNotify(XSelectio Line 244  cliprdr_handle_SelectionNotify(XSelectio
244    
245                  datap = data;                  datap = data;
246    
247                  if (nitems+1 <= MAX_CLIPRDR_STANDALONE_DATASIZE)                  if (nitems + 1 <= MAX_CLIPRDR_STANDALONE_DATASIZE)
248                  {                  {
249                          out =  sec_init(encryption ? SEC_ENCRYPT : 0,                          out = sec_init(encryption ? SEC_ENCRYPT : 0, 20 + nitems + 1);
250                                          20+nitems+1);                          out_uint32_le(out, 12 + nitems + 1);
                         out_uint32_le(out, 12+nitems+1);  
251                          out_uint32_le(out, 0x13);                          out_uint32_le(out, 0x13);
252                          out_uint16_le(out, 5);                          out_uint16_le(out, 5);
253                          out_uint16_le(out, 1);                          out_uint16_le(out, 1);
254                          out_uint32_le(out, nitems+1);                          out_uint32_le(out, nitems + 1);
255                          out_uint8p(out, datap, nitems+1);                          out_uint8p(out, datap, nitems + 1);
256                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
257                          s_mark_end(out);                          s_mark_end(out);
           
                         sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,  
                                             clipboard_channelno);  
258    
259                  }                          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
260    
261                    }
262                  else                  else
263                  {                  {
264                          DEBUG_CLIPBOARD(("Sending %d bytes of data\n",                          DEBUG_CLIPBOARD(("Sending %d bytes of data\n",
265                                           16+MAX_CLIPRDR_STANDALONE_DATASIZE));                                           16 + MAX_CLIPRDR_STANDALONE_DATASIZE));
266                          out =  sec_init(encryption ? SEC_ENCRYPT : 0,                          out = sec_init(encryption ? SEC_ENCRYPT : 0,
267                                          16+MAX_CLIPRDR_STANDALONE_DATASIZE);                                         16 + MAX_CLIPRDR_STANDALONE_DATASIZE);
268                          out_uint32_le(out, nitems+12);                          out_uint32_le(out, nitems + 12);
269                          out_uint32_le(out, 0x11);                          out_uint32_le(out, 0x11);
270                          out_uint16_le(out, 5);                          out_uint16_le(out, 5);
271                          out_uint16_le(out, 1);                          out_uint16_le(out, 1);
272                          out_uint32_le(out, nitems);                          out_uint32_le(out, nitems);
273                          out_uint8p(out, datap,                          out_uint8p(out, datap, MAX_CLIPRDR_STANDALONE_DATASIZE);
                                    MAX_CLIPRDR_STANDALONE_DATASIZE);  
274                          s_mark_end(out);                          s_mark_end(out);
275            
276                          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,                          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                                             clipboard_channelno);  
277    
278                          bytes_left_to_transfer = nitems - MAX_CLIPRDR_STANDALONE_DATASIZE;                          bytes_left_to_transfer = nitems - MAX_CLIPRDR_STANDALONE_DATASIZE;
279                          datap+=MAX_CLIPRDR_STANDALONE_DATASIZE;                          datap += MAX_CLIPRDR_STANDALONE_DATASIZE;
280    
281                          while (bytes_left_to_transfer > MAX_CLIPRDR_STANDALONE_DATASIZE)                          while (bytes_left_to_transfer > MAX_CLIPRDR_STANDALONE_DATASIZE)
282                          {                          {
283                                  DEBUG_CLIPBOARD(("Sending %d bytes of data\n",                                  DEBUG_CLIPBOARD(("Sending %d bytes of data\n",
284                                           16+MAX_CLIPRDR_CONTINUATION_DATASIZE));                                                   16 + MAX_CLIPRDR_CONTINUATION_DATASIZE));
285                                  out =  sec_init(encryption ? SEC_ENCRYPT : 0,                                  out = sec_init(encryption ? SEC_ENCRYPT : 0,
286                                                  8+MAX_CLIPRDR_CONTINUATION_DATASIZE);                                                 8 + MAX_CLIPRDR_CONTINUATION_DATASIZE);
287                                  out_uint32_le(out, nitems);                                  out_uint32_le(out, nitems);
288                                  out_uint32_le(out, 0x10);                                  out_uint32_le(out, 0x10);
289                                  out_uint8p(out, datap,                                  out_uint8p(out, datap, MAX_CLIPRDR_CONTINUATION_DATASIZE);
                                            MAX_CLIPRDR_CONTINUATION_DATASIZE);  
290                                  s_mark_end(out);                                  s_mark_end(out);
291    
292                                  sec_send_to_channel(out,                                  sec_send_to_channel(out,
293                                                      encryption ? SEC_ENCRYPT : 0,                                                      encryption ? SEC_ENCRYPT : 0,
294                                                      clipboard_channelno);                                                      clipboard_channelno);
295                                  bytes_left_to_transfer-= MAX_CLIPRDR_CONTINUATION_DATASIZE;                                  bytes_left_to_transfer -= MAX_CLIPRDR_CONTINUATION_DATASIZE;
296                                  datap+=MAX_CLIPRDR_CONTINUATION_DATASIZE;                                  datap += MAX_CLIPRDR_CONTINUATION_DATASIZE;
297                                    
298                          }                          }
299                          DEBUG_CLIPBOARD(("Sending %u bytes of data\n",                          DEBUG_CLIPBOARD(("Sending %u bytes of data\n",
300                                           12+bytes_left_to_transfer));                                           12 + bytes_left_to_transfer));
301                          out =  sec_init(encryption ? SEC_ENCRYPT : 0,                          out = sec_init(encryption ? SEC_ENCRYPT : 0, 12 + bytes_left_to_transfer);
                                         12+bytes_left_to_transfer);  
302                          out_uint32_le(out, nitems);                          out_uint32_le(out, nitems);
303                          out_uint32_le(out, 0x12);                          out_uint32_le(out, 0x12);
304                          out_uint8p(out, datap,                          out_uint8p(out, datap, bytes_left_to_transfer);
                                    bytes_left_to_transfer);  
305                          out_uint32_le(out, 0x0);                          out_uint32_le(out, 0x0);
306                          s_mark_end(out);                          s_mark_end(out);
307            
308                          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,                          sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                                             clipboard_channelno);  
309    
310                  }                  }
311    
# Line 326  cliprdr_handle_SelectionNotify(XSelectio Line 313  cliprdr_handle_SelectionNotify(XSelectio
313                  XFree(data);                  XFree(data);
314                  if (!rdesktop_clipboard_target_atom)                  if (!rdesktop_clipboard_target_atom)
315                          cliprdr_send_format_announce();                          cliprdr_send_format_announce();
316                    
317          }          }
318            
319            
320  }  }
321    
322  void  void
# Line 337  cliprdr_handle_SelectionClear(void) Line 324  cliprdr_handle_SelectionClear(void)
324  {  {
325          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionClear\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionClear\n"));
326          have_primary = 0;          have_primary = 0;
327          ipc_send_message(RDESKTOP_IPC_CLIPRDR_PRIMARY_LOST,          ipc_send_message(RDESKTOP_IPC_CLIPRDR_PRIMARY_LOST, "", 0);
                          "", 0);  
328          cliprdr_send_format_announce();          cliprdr_send_format_announce();
329  }  }
330    
331    
332  static void  static void
333  cliprdr_request_clipboard_data(uint32 formatcode)  cliprdr_request_clipboard_data(uint32 formatcode)
334  {  {
335          STREAM s;          STREAM s;
336          s = sec_init(encryption ? SEC_ENCRYPT : 0, 24);          s = sec_init(encryption ? SEC_ENCRYPT : 0, 24);
# Line 352  cliprdr_request_clipboard_data(uint32 fo Line 338  cliprdr_request_clipboard_data(uint32 fo
338          out_uint32_le(s, 0x13);          out_uint32_le(s, 0x13);
339          out_uint16_le(s, 4);          out_uint16_le(s, 4);
340          out_uint16_le(s, 0);          out_uint16_le(s, 0);
341          out_uint32_le(s, 4); // Remaining length          out_uint32_le(s, 4);    // Remaining length
342          out_uint32_le(s, formatcode);          out_uint32_le(s, formatcode);
343          out_uint32_le(s, 0); // Unknown. Garbage pad?          out_uint32_le(s, 0);    // Unknown. Garbage pad?
344    
345          s_mark_end(s);          s_mark_end(s);
346    
347          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                             clipboard_channelno);  
348  }  }
349    
350    
351  void  void
352  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)  cliprdr_handle_SelectionRequest(XSelectionRequestEvent * xevent)
353  {  {
354    
355          XSelectionEvent xev;          XSelectionEvent xev;
356          unsigned long   nitems, bytes_left;          unsigned long nitems, bytes_left;
357          Atom type_return;                Atom type_return;
358          uint32 *wanted_formatcode;          uint32 *wanted_formatcode;
359          int format;          int format;
360            
361          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));
362          DEBUG_CLIPBOARD(("Requestor window id 0x%x ",          DEBUG_CLIPBOARD(("Requestor window id 0x%x ", (unsigned) xevent->requestor));
363                           (unsigned)xevent->requestor));          if (clipboard_atom == xevent->selection)
364          if (clipboard_atom == xevent->selection) {          {
365                  DEBUG_CLIPBOARD(("wants CLIPBOARD\n"));                  DEBUG_CLIPBOARD(("wants CLIPBOARD\n"));
366          }          }
367          if (primary_atom == xevent->selection) {          if (primary_atom == xevent->selection)
368            {
369                  DEBUG_CLIPBOARD(("wants PRIMARY\n"));                  DEBUG_CLIPBOARD(("wants PRIMARY\n"));
370          }            }
371          DEBUG_CLIPBOARD(("Target is %s (0x%x), property is %s (0x%x)\n",          DEBUG_CLIPBOARD(("Target is %s (0x%x), property is %s (0x%x)\n",
372                           XGetAtomName(display, xevent->target),                           XGetAtomName(display, xevent->target),
373                           (unsigned)xevent->target,                           (unsigned) xevent->target,
374                           XGetAtomName(display, xevent->property),                           XGetAtomName(display, xevent->property), (unsigned) xevent->property));
                          (unsigned)xevent->property));  
375    
376          xev.type = SelectionNotify;          xev.type = SelectionNotify;
377          xev.serial = 0;          xev.serial = 0;
# Line 404  cliprdr_handle_SelectionRequest(XSelecti Line 389  cliprdr_handle_SelectionRequest(XSelecti
389                  DEBUG_CLIPBOARD(("Target atom is ipc_atom, getting INTEGER from requestor\n"));                  DEBUG_CLIPBOARD(("Target atom is ipc_atom, getting INTEGER from requestor\n"));
390                  XGetWindowProperty(display, xevent->requestor,                  XGetWindowProperty(display, xevent->requestor,
391                                     rdesktop_clipboard_target_atom,                                     rdesktop_clipboard_target_atom,
392                                     0,                                     0,
393                                     1,                                     1,
394                                     True, XA_INTEGER,                                     True, XA_INTEGER,
395                                     &type_return,                                     &type_return,
396                                     &format,                                     &format,
397                                     &nitems,                                     &nitems, &bytes_left, (unsigned char **) &wanted_formatcode);
398                                     &bytes_left,                  DEBUG_CLIPBOARD(("Got wanted formatcode %d, format is %d\n", *wanted_formatcode,
399                                     (unsigned char **)&wanted_formatcode);                                   format));
                 DEBUG_CLIPBOARD(("Got wanted formatcode %d, format is %d\n", *wanted_formatcode, format));  
400                  cliprdr_request_clipboard_data(*wanted_formatcode);                  cliprdr_request_clipboard_data(*wanted_formatcode);
401          }          }
402    
403          else if (targets_atom == xevent->target)          else if (targets_atom == xevent->target)
404          {          {
405                  DEBUG_CLIPBOARD(("TARGETS requested, sending list..\n"));                  DEBUG_CLIPBOARD(("TARGETS requested, sending list..\n"));
406                  XChangeProperty(display,                  XChangeProperty(display,
407                                  xevent->requestor,                                  xevent->requestor,
408                                  xevent->property,                                  xevent->property,
409                                  XA_ATOM,                                  XA_ATOM,
410                                  32,                                  32, PropModeAppend, (unsigned char *) &targets, NUM_TARGETS);
411                                  PropModeAppend,  
412                                  (unsigned char *)&targets,                  XSendEvent(display, xevent->requestor, False, NoEventMask, (XEvent *) & xev);
                                 NUM_TARGETS);  
   
                 XSendEvent(display,  
                            xevent->requestor,  
                            False,  
                            NoEventMask,  
                            (XEvent *)&xev);  
413                  return;                  return;
414          } else if (timestamp_atom == xevent->target)          }
415            else if (timestamp_atom == xevent->target)
416          {          {
417                  DEBUG_CLIPBOARD(("Sending TIMESTAMP\n"));                  DEBUG_CLIPBOARD(("Sending TIMESTAMP\n"));
418                  XChangeProperty(display,                  XChangeProperty(display,
419                                  xevent->requestor,                                  xevent->requestor,
420                                  xevent->property,                                  xevent->property,
421                                  XA_INTEGER,                                  XA_INTEGER,
422                                  32,                                  32, PropModeAppend, (unsigned char *) &last_gesturetime, 1);
423                                  PropModeAppend,                  XSendEvent(display, xevent->requestor, False, NoEventMask, (XEvent *) & xev);
424                                  (unsigned char *)&last_gesturetime,          }
425                                  1);          else                    /* Some other target */
                 XSendEvent(display,  
                            xevent->requestor,  
                            False,  
                            NoEventMask,  
                            (XEvent *)&xev);  
         } else /* Some other target */  
426          {          {
427                  cliprdr_request_clipboard_data(CF_TEXT);                  cliprdr_request_clipboard_data(CF_TEXT);
428                  /* Return and wait for data, handled by                  /* Return and wait for data, handled by
# Line 459  cliprdr_handle_SelectionRequest(XSelecti Line 431  cliprdr_handle_SelectionRequest(XSelecti
431  }  }
432    
433    
434  static void  static void
435  cliprdr_ack_format_list(void)  cliprdr_ack_format_list(void)
436  {  {
437          STREAM s;          STREAM s;
438          s = sec_init(encryption ? SEC_ENCRYPT : 0, 20);          s = sec_init(encryption ? SEC_ENCRYPT : 0, 20);
# Line 473  cliprdr_ack_format_list(void) Line 445  cliprdr_ack_format_list(void)
445    
446          s_mark_end(s);          s_mark_end(s);
447    
448          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, clipboard_channelno);
                             clipboard_channelno);  
449  }  }
450    
451                    
452    
453    
454    
455  static void  static void
456  cliprdr_register_server_formats(STREAM s)  cliprdr_register_server_formats(STREAM s)
457  {  {
458          uint32 remaining_length, pad;          uint32 remaining_length, pad;
459          uint16 num_formats;          uint16 num_formats;
460          cliprdr_dataformat *this, *next;          cliprdr_dataformat *this, *next;
461    
462          in_uint32_le(s, remaining_length);          in_uint32_le(s, remaining_length);
463          DEBUG_CLIPBOARD(("cliprdr_register_server_formats, remaining_length is %d\n", remaining_length));          DEBUG_CLIPBOARD(("cliprdr_register_server_formats, remaining_length is %d\n",
464                             remaining_length));
465    
466    
467          num_formats = remaining_length / 36;          num_formats = remaining_length / 36;
468    
469          ipc_send_message(RDESKTOP_IPC_CLIPRDR_FORMAT_ANNOUNCE,          ipc_send_message(RDESKTOP_IPC_CLIPRDR_FORMAT_ANNOUNCE, s->p, remaining_length);
470                           s->p, remaining_length);          if (NULL != server_formats)
471          if (NULL != server_formats) {          {
472                  this = server_formats;                  this = server_formats;
473                  next = this->next;                  next = this->next;
474                  while (NULL != next) {                  while (NULL != next)
475                    {
476                          xfree(this);                          xfree(this);
477                          this = NULL;                          this = NULL;
478                          this = next;                          this = next;
479                          next = this->next;                          next = this->next;
480                  }                  }
481          }          }
482          this = xmalloc(sizeof(cliprdr_dataformat));          this = xmalloc(sizeof(cliprdr_dataformat));
483          this->next = NULL;          this->next = NULL;
484          server_formats = this;          server_formats = this;
485          num_server_formats = num_formats;          num_server_formats = num_formats;
486          while (1 < num_formats) {          while (1 < num_formats)
487            {
488                  in_uint32_le(s, this->identifier);                  in_uint32_le(s, this->identifier);
489                  in_uint8a(s, this->textual_description, 32);                  in_uint8a(s, this->textual_description, 32);
490                  DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n",                  DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n",
491                                   this->identifier));                                   this->identifier));
492                  this-> next = xmalloc(sizeof(cliprdr_dataformat));                  this->next = xmalloc(sizeof(cliprdr_dataformat));
493                  this = this->next;                  this = this->next;
494                  num_formats--;                  num_formats--;
495          }          }
496          in_uint32_le(s, this->identifier);          in_uint32_le(s, this->identifier);
497          DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n", this->identifier));          DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n", this->identifier));
498          in_uint8a(s, this->textual_description, 32);          in_uint8a(s, this->textual_description, 32);
499          this -> next = NULL;          this->next = NULL;
500          in_uint32_le(s, pad);          in_uint32_le(s, pad);
501          cliprdr_print_server_formats();          cliprdr_print_server_formats();
502  }  }
503    
504  static void  static void
505  cliprdr_select_X_clipboards(void)  cliprdr_select_X_clipboards(void)
506  {  {
507          XSetSelectionOwner(display, primary_atom, wnd, last_gesturetime);          XSetSelectionOwner(display, primary_atom, wnd, last_gesturetime);
508          if (wnd != XGetSelectionOwner(display, primary_atom))          if (wnd != XGetSelectionOwner(display, primary_atom))
509          {          {
510                  warning("Failed to aquire ownership of PRIMARY clipboard\n");                  warning("Failed to aquire ownership of PRIMARY clipboard\n");
511          }          }
512          else          else
513          {          {
514                  have_primary = 1;                  have_primary = 1;
515          }          }
516          XSetSelectionOwner(display, clipboard_atom, wnd, last_gesturetime);          XSetSelectionOwner(display, clipboard_atom, wnd, last_gesturetime);
517          if (wnd != XGetSelectionOwner(display, clipboard_atom))          if (wnd != XGetSelectionOwner(display, clipboard_atom))
518          {          {
519                  warning("Failed to aquire ownership of CLIPBOARD clipboard\n");                  warning("Failed to aquire ownership of CLIPBOARD clipboard\n");
520          }                        }
521            
522  }  }
523    
524    
525    
526  static void  static void
527  cliprdr_handle_first_handshake(STREAM s)  cliprdr_handle_first_handshake(STREAM s)
528  {  {
529          uint32 remaining_length, pad;          uint32 remaining_length, pad;
530          in_uint32_le(s, remaining_length);          in_uint32_le(s, remaining_length);
531          in_uint32_le(s, pad);          in_uint32_le(s, pad);
532          DEBUG_CLIPBOARD(("Remaining length in first handshake frm server is %d, pad is %d\n",          DEBUG_CLIPBOARD(("Remaining length in first handshake frm server is %d, pad is %d\n",
533                           remaining_length, pad));                           remaining_length, pad));
534          cliprdr_send_format_announce();          cliprdr_send_format_announce();
535  }  }
536    
537  void cliprdr_handle_server_data(uint32 length, uint32 flags, STREAM s)  void
538    cliprdr_handle_server_data(uint32 length, uint32 flags, STREAM s)
539  {  {
540          static uint32 remaining_length;          static uint32 remaining_length;
541          static char *data, *datap;          static char *data, *datap;
542          static uint32 bytes_left_to_read;          static uint32 bytes_left_to_read;
543          DEBUG_CLIPBOARD(("In cliprdr_handle_server_data, flags is %d\n",          DEBUG_CLIPBOARD(("In cliprdr_handle_server_data, flags is %d\n", flags));
544                           flags));          if (3 == flags)         /* One-op write, no packets follows */
         if (3 == flags)  /* One-op write, no packets follows */  
545          {          {
546                  in_uint32_le(s, remaining_length);                  in_uint32_le(s, remaining_length);
547                  data = s->p;                  data = s->p;
548          } else if (1 == flags) /* First of several packets */          }
549          {                else if (1 == flags)    /* First of several packets */
550            {
551                  in_uint32_le(s, remaining_length);                  in_uint32_le(s, remaining_length);
552                  DEBUG_CLIPBOARD(("Remaining length is %d\n",                  DEBUG_CLIPBOARD(("Remaining length is %d\n", remaining_length));
                                  remaining_length));  
553                  data = xmalloc(remaining_length);                  data = xmalloc(remaining_length);
554                  datap = data;                  datap = data;
555                  DEBUG_CLIPBOARD(("Copying first %d bytes\n",                  DEBUG_CLIPBOARD(("Copying first %d bytes\n", MAX_CLIPRDR_STANDALONE_DATASIZE));
                                  MAX_CLIPRDR_STANDALONE_DATASIZE));  
556                  memcpy(datap, s->p, MAX_CLIPRDR_STANDALONE_DATASIZE);                  memcpy(datap, s->p, MAX_CLIPRDR_STANDALONE_DATASIZE);
557    
558                  datap+=MAX_CLIPRDR_STANDALONE_DATASIZE;                  datap += MAX_CLIPRDR_STANDALONE_DATASIZE;
559                  bytes_left_to_read = remaining_length-MAX_CLIPRDR_STANDALONE_DATASIZE;                  bytes_left_to_read = remaining_length - MAX_CLIPRDR_STANDALONE_DATASIZE;
560                  return;                  return;
561          } else if (0 == flags)          }
562            else if (0 == flags)
563          {          {
564                  DEBUG_CLIPBOARD(("Copying %d middle bytes",                  DEBUG_CLIPBOARD(("Copying %d middle bytes", MAX_CLIPRDR_CONTINUATION_DATASIZE));
                                  MAX_CLIPRDR_CONTINUATION_DATASIZE));  
565                  memcpy(datap, s->p, MAX_CLIPRDR_CONTINUATION_DATASIZE);                  memcpy(datap, s->p, MAX_CLIPRDR_CONTINUATION_DATASIZE);
566    
567                  datap+=MAX_CLIPRDR_CONTINUATION_DATASIZE;                  datap += MAX_CLIPRDR_CONTINUATION_DATASIZE;
568                  bytes_left_to_read-=MAX_CLIPRDR_CONTINUATION_DATASIZE;                  bytes_left_to_read -= MAX_CLIPRDR_CONTINUATION_DATASIZE;
569                  return;                  return;
570          } else if (2 == flags)          }
571            else if (2 == flags)
572          {          {
573                  DEBUG_CLIPBOARD(("Copying last %d bytes\n",                  DEBUG_CLIPBOARD(("Copying last %d bytes\n", bytes_left_to_read));
                                  bytes_left_to_read));  
574                  memcpy(datap, s->p, bytes_left_to_read);                  memcpy(datap, s->p, bytes_left_to_read);
575          }          }
576          DEBUG_CLIPBOARD(("Setting target atom (%s) on %d\n",          DEBUG_CLIPBOARD(("Setting target atom (%s) on %d\n",
577                           XGetAtomName(display, selection_event.property),                           XGetAtomName(display, selection_event.property),
578                           selection_event.requestor));                           selection_event.requestor));
579          XChangeProperty(display,          XChangeProperty(display,
580                          selection_event.requestor,                          selection_event.requestor,
581                          selection_event.property,                          selection_event.property,
582                          XInternAtom(display, "STRING", False),                          XInternAtom(display, "STRING", False),
583                          8,                          8, PropModeAppend, data, remaining_length - 1);
584                          PropModeAppend,  
585                          data,          XSendEvent(display,
586                          remaining_length-1);                     selection_event.requestor, False, NoEventMask, (XEvent *) & selection_event);
   
         XSendEvent(display,  
                    selection_event.requestor,  
                    False,  
                    NoEventMask,  
                    (XEvent *)&selection_event);  
587    
588          if (2 == flags)          if (2 == flags)
589                  xfree(data);                  xfree(data);
590    
591  }  }
592    
593  void cliprdr_handle_server_data_request(STREAM s)  void
594    cliprdr_handle_server_data_request(STREAM s)
595  {  {
596          Window selectionowner;          Window selectionowner;
597          uint32 remaining_length;          uint32 remaining_length;
# Line 635  void cliprdr_handle_server_data_request( Line 603  void cliprdr_handle_server_data_request(
603    
604          /* FIXME: Check that we support this formatcode */          /* FIXME: Check that we support this formatcode */
605    
606          DEBUG_CLIPBOARD(("Request from server for format %d\n",          DEBUG_CLIPBOARD(("Request from server for format %d\n", wanted_formatcode));
                          wanted_formatcode));  
607    
608          selectionowner = XGetSelectionOwner(display, primary_atom);          selectionowner = XGetSelectionOwner(display, primary_atom);
609    
# Line 645  void cliprdr_handle_server_data_request( Line 612  void cliprdr_handle_server_data_request(
612                  DEBUG_CLIPBOARD(("XChangeProperty, rdesktop_is_selection_owner\n"));                  DEBUG_CLIPBOARD(("XChangeProperty, rdesktop_is_selection_owner\n"));
613                  XChangeProperty(display, wnd, rdesktop_clipboard_target_atom,                  XChangeProperty(display, wnd, rdesktop_clipboard_target_atom,
614                                  XA_INTEGER, 32, PropModeReplace,                                  XA_INTEGER, 32, PropModeReplace,
615                                  (unsigned char *)&wanted_formatcode, 1);                                  (unsigned char *) &wanted_formatcode, 1);
616    
617                  XConvertSelection(display, primary_atom,                  XConvertSelection(display, primary_atom,
618                                    ipc_atom,                                    ipc_atom, rdesktop_clipboard_target_atom, wnd, CurrentTime);
                                   rdesktop_clipboard_target_atom,  
                                   wnd, CurrentTime);  
619                  return;                  return;
620          }          }
621    
622    
623          if (None != selectionowner)          if (None != selectionowner)
624          {          {
625            
626                  /* FIXME: Perhaps we should check if we are the owner? */                  /* FIXME: Perhaps we should check if we are the owner? */
627    
628                  XConvertSelection(display, primary_atom,                  XConvertSelection(display, primary_atom,
629                                    targets_atom,                                    targets_atom, rdesktop_clipboard_target_atom, wnd, CurrentTime);
                                   rdesktop_clipboard_target_atom,  
                                   wnd, CurrentTime);  
630    
631                  /* The rest of the transfer is handled in                  /* The rest of the transfer is handled in
632                     cliprdr_handle_SelectionNotify */                     cliprdr_handle_SelectionNotify */
633    
634          } else          }
635            else
636          {          {
637                  DEBUG_CLIPBOARD(("There were no owner for PRIMARY, sending empty string\n")); // FIXME: Should we always send an empty string?                  DEBUG_CLIPBOARD(("There were no owner for PRIMARY, sending empty string\n"));   // FIXME: Should we always send an empty string?
638    
639                  cliprdr_send_empty_datapacket();                  cliprdr_send_empty_datapacket();
640          }          }
641    
642    
643  }  }
           
644    
645  void cliprdr_callback(STREAM s, uint16 channelno)  
646    void
647    cliprdr_callback(STREAM s, uint16 channelno)
648  {  {
649          static int failed_clipboard_acks = 0;          static int failed_clipboard_acks = 0;
650          struct timeval timeval;          struct timeval timeval;
651          uint32 length, flags;          uint32 length, flags;
652          uint16 ptype0, ptype1;          uint16 ptype0, ptype1;
653          clipboard_channelno = channelno;          clipboard_channelno = channelno;
654          DEBUG_CLIPBOARD(("cliprdr_callback called with channelno %d, clipboard data:\n", channelno));          DEBUG_CLIPBOARD(("cliprdr_callback called with channelno %d, clipboard data:\n",
655                             channelno));
656  #ifdef WITH_DEBUG_CLIPBOARD  #ifdef WITH_DEBUG_CLIPBOARD
657          //      hexdump(s->p, s->end - s->p);          //      hexdump(s->p, s->end - s->p);
658  #endif  #endif
659          in_uint32_le(s, length);          in_uint32_le(s, length);
660          in_uint32_le(s, flags);          in_uint32_le(s, flags);
661    
662          DEBUG_CLIPBOARD(("length is %d, flags are %d\n", length, flags));          DEBUG_CLIPBOARD(("length is %d, flags are %d\n", length, flags));
663    
664          if (3 == flags || 1 == flags) /* Single-write op or first-packet-of-several op */          if (3 == flags || 1 == flags)   /* Single-write op or first-packet-of-several op */
665          {          {
666                  in_uint16_le(s, ptype0);                  in_uint16_le(s, ptype0);
667                  in_uint16_le(s, ptype1);                  in_uint16_le(s, ptype1);
668                  DEBUG_CLIPBOARD(("ptype0 is %d, ptype1 is %d\n", ptype0, ptype1));                  DEBUG_CLIPBOARD(("ptype0 is %d, ptype1 is %d\n", ptype0, ptype1));
669                  if (1 == ptype0 && 0 == ptype1) {                  if (1 == ptype0 && 0 == ptype1)
670                    {
671                          cliprdr_handle_first_handshake(s);                          cliprdr_handle_first_handshake(s);
672                          return;                          return;
673                  } else if (3 == ptype0 && 1 == ptype1)                  }
674                    else if (3 == ptype0 && 1 == ptype1)
675                  {                  {
676                          // Acknowledgment on our format announce. Do we care? Not right now.                          // Acknowledgment on our format announce. Do we care? Not right now.
677                          // There is a strange pad in this packet that we might need some time,                          // There is a strange pad in this packet that we might need some time,
# Line 712  void cliprdr_callback(STREAM s, uint16 c Line 680  void cliprdr_callback(STREAM s, uint16 c
680                          failed_clipboard_acks = 0;                          failed_clipboard_acks = 0;
681                          return;                          return;
682    
683                  } else if (3 == ptype0 && 2 == ptype1)                  }
684                    else if (3 == ptype0 && 2 == ptype1)
685                  {                  {
686                          DEBUG_CLIPBOARD(("Received failed clipboard format announce ACK, retrying\n"));                          DEBUG_CLIPBOARD(("Received failed clipboard format announce ACK, retrying\n"));
687    
# Line 723  void cliprdr_callback(STREAM s, uint16 c Line 692  void cliprdr_callback(STREAM s, uint16 c
692                          select(0, NULL, NULL, NULL, &timeval);                          select(0, NULL, NULL, NULL, &timeval);
693                          if (failed_clipboard_acks < 3)                          if (failed_clipboard_acks < 3)
694                          {                          {
695                                    
696                                  cliprdr_send_format_announce();                                  cliprdr_send_format_announce();
697                                  /* Make sure we don't get stuck in this loop */                                  /* Make sure we don't get stuck in this loop */
698                                  failed_clipboard_acks++;                                  failed_clipboard_acks++;
699                          }                          }
700                          else                          else
701                          {                          {
702                                  warning("Reached maximum number of clipboard format announce attempts. Pasting in Windows probably won't work well now.\n");                                  warning("Reached maximum number of clipboard format announce attempts. Pasting in Windows probably won't work well now.\n");
703                          }                          }
704                  } else if (2 == ptype0 && 0 == ptype1)                  }
705                    else if (2 == ptype0 && 0 == ptype1)
706                  {                  {
707                          cliprdr_register_server_formats(s);                          cliprdr_register_server_formats(s);
708                          cliprdr_select_X_clipboards();                          cliprdr_select_X_clipboards();
709                          cliprdr_ack_format_list();                          cliprdr_ack_format_list();
710                          return;                          return;
711                  } else if (5 == ptype0 && 1 == ptype1)                  }
712                    else if (5 == ptype0 && 1 == ptype1)
713                  {                  {
714                          cliprdr_handle_server_data(length, flags, s);                          cliprdr_handle_server_data(length, flags, s);
715                  } else if (4 == ptype0 && 0 == ptype1)                  }
716                    else if (4 == ptype0 && 0 == ptype1)
717                  {                  {
718                          cliprdr_handle_server_data_request(s);                          cliprdr_handle_server_data_request(s);
719                  }                  }
720    
721                    
722          }          }
723          else          else
724          {          {
725                  DEBUG_CLIPBOARD(("Handling middle or last packet\n"));                  DEBUG_CLIPBOARD(("Handling middle or last packet\n"));
726                  cliprdr_handle_server_data(length, flags, s);                  cliprdr_handle_server_data(length, flags, s);
727          }          }
728  }  }
729    
730  void cliprdr_ipc_primary_lost(unsigned char *data, uint16 length)  void
731    cliprdr_ipc_primary_lost(unsigned char *data, uint16 length)
732  {  {
733          DEBUG_CLIPBOARD(("cliprdr_ipc_primary_lost called\n"));          DEBUG_CLIPBOARD(("cliprdr_ipc_primary_lost called\n"));
734          if (!have_primary)          if (!have_primary)
# Line 764  void cliprdr_ipc_primary_lost(unsigned c Line 737  void cliprdr_ipc_primary_lost(unsigned c
737  }  }
738    
739    
740  void cliprdr_init(void)  void
741    cliprdr_init(void)
742  {  {
743          primary_atom = XInternAtom(display, "PRIMARY", False);          primary_atom = XInternAtom(display, "PRIMARY", False);
744          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);
# Line 778  void cliprdr_init(void) Line 752  void cliprdr_init(void)
752          targets[3] = XInternAtom(display, "text/unicode", False);          targets[3] = XInternAtom(display, "text/unicode", False);
753          targets[4] = XInternAtom(display, "TIMESTAMP", False);          targets[4] = XInternAtom(display, "TIMESTAMP", False);
754          targets[5] = XInternAtom(display, "STRING", False);          targets[5] = XInternAtom(display, "STRING", False);
755          ipc_register_ipcnotify(RDESKTOP_IPC_CLIPRDR_FORMAT_ANNOUNCE,          ipc_register_ipcnotify(RDESKTOP_IPC_CLIPRDR_FORMAT_ANNOUNCE, cliprdr_ipc_format_announce);
756                                 cliprdr_ipc_format_announce);          ipc_register_ipcnotify(RDESKTOP_IPC_CLIPRDR_FORMAT_ANNOUNCE, cliprdr_ipc_primary_lost);
         ipc_register_ipcnotify(RDESKTOP_IPC_CLIPRDR_FORMAT_ANNOUNCE,  
                                cliprdr_ipc_primary_lost);  
757    
758    
759  }  }

Legend:
Removed from v.395  
changed lines
  Added in v.396

  ViewVC Help
Powered by ViewVC 1.1.26