/[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 384 by forsberg, Fri Jun 6 09:22:25 2003 UTC revision 393 by forsberg, Fri Jun 6 09:30:48 2003 UTC
# Line 25  Line 25 
25  extern BOOL encryption;  extern BOOL encryption;
26  extern Display *display;  extern Display *display;
27  extern Window wnd;  extern Window wnd;
28  extern Time last_keyrelease;  extern Time last_gesturetime;
29    
30    // static Time selection_timestamp;
31  static Atom clipboard_atom, primary_atom, targets_atom, timestamp_atom;  static Atom clipboard_atom, primary_atom, targets_atom, timestamp_atom;
32    static Atom rdesktop_clipboard_target_atom, incr_atom;
33  static cliprdr_dataformat *server_formats = NULL;  static cliprdr_dataformat *server_formats = NULL;
34  static uint16 num_server_formats = 0;  static uint16 num_server_formats = 0;
35  static XSelectionEvent selection_event;  static XSelectionEvent selection_event;
36    static uint16 clipboard_channelno;
37    static Atom targets[NUM_TARGETS];
38    
39  static void  static void
40  cliprdr_print_server_formats(void)  cliprdr_print_server_formats(void)
# Line 49  cliprdr_print_server_formats(void) Line 53  cliprdr_print_server_formats(void)
53          DEBUG_CLIPBOARD(("There were %d server formats.\n", i));          DEBUG_CLIPBOARD(("There were %d server formats.\n", i));
54  #endif  #endif
55  }  }
56    /*
57    static void
58    cliprdr_set_selection_timestamp(void)
59    {
60            XEvent xev;
61            DEBUG_CLIPBOARD(("Changing a property in order to get a timestamp\n"));
62            fflush(stdout);
63            XChangeProperty(display, wnd, rdesktop_clipboard_target_atom,
64                            XA_ATOM, 32, PropModeAppend, 0, 0);
65            DEBUG_CLIPBOARD(("Waiting for PropertyChange on wnd\n"));
66            fflush(stdout);
67            XWindowEvent(display, wnd,
68                         PropertyChangeMask, &xev);
69            DEBUG_CLIPBOARD(("Setting selection_timestamp\n"));
70            fflush(stdout);
71            selection_timestamp = xev.xproperty.time;
72    }      
73    */      
74    
75    static void
76    cliprdr_send_format_announce(void)
77    {
78            DEBUG_CLIPBOARD(("Sending format announce\n"));
79    
80            STREAM s;
81            int number_of_formats = 1;
82            s = sec_init(encryption ? SEC_ENCRYPT : 0, number_of_formats*36+12+4+4);
83            out_uint32_le(s, number_of_formats*36+12);
84            out_uint32_le(s, 0x13);
85            out_uint16_le(s, 2);
86            out_uint16_le(s, 0);
87            out_uint32_le(s, number_of_formats*36);
88            
89            //      out_uint32_le(s, 0xd); // FIXME: This is a rather bogus unicode text description..
90            //      rdp_out_unistr(s, "", 16);
91            //      out_uint8s(s, 32);
92    
93    
94            out_uint32_le(s, 1); // FIXME: This is a rather bogus text description..
95            out_uint8s(s, 32);
96    
97            out_uint32_le(s, 0);
98    
99            s_mark_end(s);
100            sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,
101                                clipboard_channelno);
102    }
103    
104    
105    static void
106    cliprdr_send_empty_datapacket(void)
107    {
108            STREAM out;
109            out =  sec_init(encryption ? SEC_ENCRYPT : 0,
110                            20);
111            out_uint32_le(out, 12);
112            out_uint32_le(out, 0x13);
113            out_uint16_le(out, 5);
114            out_uint16_le(out, 1);
115            out_uint32_le(out, 0);
116            /* Insert null string here? */
117            out_uint32_le(out, 0);
118            s_mark_end(out);
119            
120            sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,
121                                clipboard_channelno);
122    }
123    
124    
125  void  void
126  cliprdr_handle_SelectionNotify(void)  cliprdr_handle_SelectionNotify(XSelectionEvent *event)
127  {  {
128    
129            unsigned char   *data, *datap;
130            unsigned long   nitems, bytes_left;
131            
132            unsigned long bytes_left_to_transfer;
133            int res, i;
134    
135            int format;
136            Atom type_return;
137            Atom best_target;
138            Atom *supported_targets;
139    
140            STREAM out;
141            
142          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));
143    
144            if (None == event->property) {
145                    cliprdr_send_empty_datapacket();
146                    return; /* Selection failed */
147            }
148    
149            DEBUG_CLIPBOARD(("selection: %s, target: %s, property: %s\n",
150                             XGetAtomName(display, event->selection),
151                             XGetAtomName(display, event->target),
152                             XGetAtomName(display, event->property)));
153    
154            if (targets_atom == event->target) {
155                    /* Response to TARGETS request. Let's find the target
156                       we want and request that */
157                    res = XGetWindowProperty(display, wnd,
158                                             rdesktop_clipboard_target_atom,
159                                             0L, 4096L, False, AnyPropertyType,
160                                             &type_return,
161                                             &format, &nitems, &bytes_left, &data);
162    
163                    if (Success != res)
164                    {
165                            DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
166                            cliprdr_send_empty_datapacket();
167                            return;
168                    }
169    
170                    if (None == type_return)
171                            /* The owner might no support TARGETS. Just try
172                               STRING */
173                            best_target = XA_STRING;
174                    else
175                    {
176                            /* FIXME: We should choose format here based
177                               on what the server wanted */
178                            supported_targets = (Atom *)data;
179                            for (i=0;i<nitems;i++)
180                            {
181                                    DEBUG_CLIPBOARD(("Target %d: %s\n",
182                                                     i, XGetAtomName(display,
183                                                                     supported_targets[i])));
184                            }
185                            best_target = XInternAtom(display, "TEXT", False);
186                            
187                            
188                    }
189    
190                    XConvertSelection(display, primary_atom,
191                                      best_target,
192                                      rdesktop_clipboard_target_atom,
193                                      wnd, event->time);
194    
195            }
196            else  /* Other clipboard data */
197            {
198                    
199                    res = XGetWindowProperty(display, wnd,
200                                             rdesktop_clipboard_target_atom,
201                                             0L, 0x1FFFFFF,
202                                             True, AnyPropertyType,
203                                             &type_return,
204                                             &format, &nitems, &bytes_left, &data);
205    
206    
207                    /* FIXME: We need to handle INCR as well,
208                     this is a temporary solution. */
209    
210                    if (incr_atom == type_return)
211                    {
212                            warning("We don't support INCR transfers at this time. Try cutting less data\n");
213                            cliprdr_send_empty_datapacket();
214                    }
215    
216    
217                    if (Success != res)
218                    {
219                            DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
220                            cliprdr_send_empty_datapacket();
221                            return;
222                    }
223    
224                    DEBUG_CLIPBOARD(("Received %d bytes of clipboard data from X, there is %d remaining\n",
225                                     nitems, bytes_left));
226                    DEBUG_CLIPBOARD(("type_return is %s\n",
227                                     XGetAtomName(display, type_return)));
228    
229                    datap = data;
230    
231                    if (nitems+1 <= MAX_CLIPRDR_STANDALONE_DATASIZE)
232                    {
233                            out =  sec_init(encryption ? SEC_ENCRYPT : 0,
234                                            20+nitems+1);
235                            out_uint32_le(out, 12+nitems+1);
236                            out_uint32_le(out, 0x13);
237                            out_uint16_le(out, 5);
238                            out_uint16_le(out, 1);
239                            out_uint32_le(out, nitems+1);
240                            out_uint8p(out, datap, nitems+1);
241                            out_uint32_le(out, 0);
242                            s_mark_end(out);
243            
244                            sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,
245                                                clipboard_channelno);
246    
247                    }
248                    else
249                    {
250                            DEBUG_CLIPBOARD(("Sending %d bytes of data\n",
251                                             16+MAX_CLIPRDR_STANDALONE_DATASIZE));
252                            out =  sec_init(encryption ? SEC_ENCRYPT : 0,
253                                            16+MAX_CLIPRDR_STANDALONE_DATASIZE);
254                            out_uint32_le(out, nitems+12);
255                            out_uint32_le(out, 0x11);
256                            out_uint16_le(out, 5);
257                            out_uint16_le(out, 1);
258                            out_uint32_le(out, nitems);
259                            out_uint8p(out, datap,
260                                       MAX_CLIPRDR_STANDALONE_DATASIZE);
261                            s_mark_end(out);
262            
263                            sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,
264                                                clipboard_channelno);
265    
266                            bytes_left_to_transfer = nitems - MAX_CLIPRDR_STANDALONE_DATASIZE;
267                            datap+=MAX_CLIPRDR_STANDALONE_DATASIZE;
268    
269                            while (bytes_left_to_transfer > MAX_CLIPRDR_STANDALONE_DATASIZE)
270                            {
271                                    DEBUG_CLIPBOARD(("Sending %d bytes of data\n",
272                                             16+MAX_CLIPRDR_CONTINUATION_DATASIZE));
273                                    out =  sec_init(encryption ? SEC_ENCRYPT : 0,
274                                                    8+MAX_CLIPRDR_CONTINUATION_DATASIZE);
275                                    out_uint32_le(out, nitems);
276                                    out_uint32_le(out, 0x10);
277                                    out_uint8p(out, datap,
278                                               MAX_CLIPRDR_CONTINUATION_DATASIZE);
279                                    s_mark_end(out);
280    
281                                    sec_send_to_channel(out,
282                                                        encryption ? SEC_ENCRYPT : 0,
283                                                        clipboard_channelno);
284                                    bytes_left_to_transfer-= MAX_CLIPRDR_CONTINUATION_DATASIZE;
285                                    datap+=MAX_CLIPRDR_CONTINUATION_DATASIZE;
286                                    
287                            }
288                            DEBUG_CLIPBOARD(("Sending %d bytes of data\n",
289                                             12+bytes_left_to_transfer));
290                            out =  sec_init(encryption ? SEC_ENCRYPT : 0,
291                                            12+bytes_left_to_transfer);
292                            out_uint32_le(out, nitems);
293                            out_uint32_le(out, 0x12);
294                            out_uint8p(out, datap,
295                                       bytes_left_to_transfer);
296                            out_uint32_le(out, 0x0);
297                            s_mark_end(out);
298            
299                            sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0,
300                                                clipboard_channelno);
301    
302                    }
303    
304    
305                    XFree(data);
306                    cliprdr_send_format_announce();
307                    
308            }
309            
310            
311  }  }
312    
313  void  void
314  cliprdr_handle_SelectionClear(void)  cliprdr_handle_SelectionClear(void)
315  {  {
316          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionClear\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionClear\n"));
317            cliprdr_send_format_announce();
318  }  }
319    
 void print_X_error(int res)  
 {  
         switch(res) {  
         case Success:  
                 DEBUG_CLIPBOARD(("Success\n"));  
                 break;  
   
         case BadAtom:  
                 DEBUG_CLIPBOARD(("BadAtom\n"));  
                 break;  
   
         case BadRequest:  
                 DEBUG_CLIPBOARD(("BadRequest\n"));  
                 break;  
   
         case BadAlloc:  
                 DEBUG_CLIPBOARD(("BadAlloc\n"));  
                 break;  
   
         case BadMatch:  
                 DEBUG_CLIPBOARD(("BadMatch\n"));  
                 break;  
   
         case BadValue:  
                 DEBUG_CLIPBOARD(("BadValue\n"));  
                 break;  
   
         case BadWindow:  
                 DEBUG_CLIPBOARD(("BadWindow\n"));  
                 break;  
   
         default:  
                 DEBUG_CLIPBOARD(("Unknown X error code %d\n", res));  
         }  
 }  
320    
321  static void  static void
322  cliprdr_request_clipboard_data(uint32 formatcode)  cliprdr_request_clipboard_data(uint32 formatcode)
# Line 113  cliprdr_request_clipboard_data(uint32 fo Line 333  cliprdr_request_clipboard_data(uint32 fo
333    
334          s_mark_end(s);          s_mark_end(s);
335    
336          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,
337                                clipboard_channelno);
338  }  }
339    
340    
# Line 121  void Line 342  void
342  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)
343  {  {
344    
         Atom *targets;  
         int res;  
   
345          XSelectionEvent xev;          XSelectionEvent xev;
346          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));
347          DEBUG_CLIPBOARD(("Requestor window id 0x%x ",          DEBUG_CLIPBOARD(("Requestor window id 0x%x ",
# Line 152  cliprdr_handle_SelectionRequest(XSelecti Line 370  cliprdr_handle_SelectionRequest(XSelecti
370          if (targets_atom == xevent->target)          if (targets_atom == xevent->target)
371          {          {
372                  DEBUG_CLIPBOARD(("TARGETS requested, sending list..\n"));                  DEBUG_CLIPBOARD(("TARGETS requested, sending list..\n"));
373                  targets = xmalloc(4*sizeof(Atom));                  XChangeProperty(display,
374                  targets[0] = xevent->target;                                  xevent->requestor,
375                  targets[1] = XInternAtom(display, "TEXT", True);                                  xevent->property,
376                  targets[2] = XInternAtom(display, "UTF8_STRING", True);                                  XA_ATOM,
377                  targets[3] = XInternAtom(display, "TIMESTAMP", True);                                  32,
378                  res = XChangeProperty(display,                                  PropModeAppend,
379                                        xevent->requestor,                                  (unsigned char *)&targets,
380                                        xevent->property,                                  NUM_TARGETS);
381                                        XA_ATOM,  
382                                        32,                  XSendEvent(display,
383                                        PropModeAppend,                             xevent->requestor,
384                                        (unsigned char *)targets,                             False,
385                                        3);                             NoEventMask,
386                  DEBUG_CLIPBOARD(("res after XChangeProperty is "));                             (XEvent *)&xev);
                 print_X_error(res);      
   
                 res = XSendEvent(display,  
                                  xevent->requestor,  
                                  False,  
                                  NoEventMask,  
                                  (XEvent *)&xev);  
387                  return;                  return;
388          } else if (timestamp_atom == xevent->target)          } else if (timestamp_atom == xevent->target)
389          {          {
390                  DEBUG_CLIPBOARD(("TIMESTAMP requested... sending 0x%x\n",                  XChangeProperty(display,
391                                   (unsigned)last_keyrelease));                                  xevent->requestor,
392                  res = XChangeProperty(display,                                  xevent->property,
393                                        xevent->requestor,                                  XA_INTEGER,
394                                        xevent->property,                                  32,
395                                        XA_INTEGER,                                  PropModeAppend,
396                                        32,                                  (unsigned char *)&last_gesturetime,
397                                        PropModeAppend,                                  1);
398                                        (unsigned char *)&last_keyrelease,                  XSendEvent(display,
399                                        1);                             xevent->requestor,
400                  res = XSendEvent(display,                             False,
401                                   xevent->requestor,                             NoEventMask,
402                                   False,                             (XEvent *)&xev);
                                  NoEventMask,  
                                  (XEvent *)&xev);  
403          } else /* Some other target */          } else /* Some other target */
404          {          {
405                  cliprdr_request_clipboard_data(CF_TEXT);                  cliprdr_request_clipboard_data(CF_TEXT);
# Line 215  cliprdr_ack_format_list(void) Line 424  cliprdr_ack_format_list(void)
424    
425          s_mark_end(s);          s_mark_end(s);
426    
427          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0,
428                                clipboard_channelno);
429  }  }
430    
431                                    
# Line 267  cliprdr_register_server_formats(STREAM s Line 477  cliprdr_register_server_formats(STREAM s
477  static void  static void
478  cliprdr_select_X_clipboards(void)  cliprdr_select_X_clipboards(void)
479  {  {
480          XSetSelectionOwner(display, primary_atom, wnd, last_keyrelease);          XSetSelectionOwner(display, primary_atom, wnd, last_gesturetime);
481          if (wnd != XGetSelectionOwner(display, primary_atom))          if (wnd != XGetSelectionOwner(display, primary_atom))
482          {          {
483                  warning("Failed to aquire ownership of PRIMARY clipboard\n");                  warning("Failed to aquire ownership of PRIMARY clipboard\n");
484          }          }
485          XSetSelectionOwner(display, clipboard_atom, wnd, CurrentTime);          XSetSelectionOwner(display, clipboard_atom, wnd, last_gesturetime);
486          if (wnd != XGetSelectionOwner(display, clipboard_atom))          if (wnd != XGetSelectionOwner(display, clipboard_atom))
487          {          {
488                  warning("Failed to aquire ownership of CLIPBOARD clipboard\n");                  warning("Failed to aquire ownership of CLIPBOARD clipboard\n");
# Line 282  cliprdr_select_X_clipboards(void) Line 492  cliprdr_select_X_clipboards(void)
492    
493                    
494    
 static void  
 cliprdr_send_format_announce(void)  
 {  
         STREAM s;  
         int number_of_formats = 1;  
         s = sec_init(encryption ? SEC_ENCRYPT : 0, number_of_formats*36+12+4+4);  
         out_uint32_le(s, number_of_formats*36+12);  
         out_uint32_le(s, 0x13);  
         out_uint16_le(s, 2);  
         out_uint16_le(s, 0);  
         out_uint32_le(s, number_of_formats*36);  
           
         out_uint32_le(s, 0xd); // FIXME: This is a rather bogus unicode text description..  
         //      rdp_out_unistr(s, "", 16);  
         out_uint8s(s, 32);  
   
         out_uint32_le(s, 0);  
   
         s_mark_end(s);  
         sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!  
 }  
495    
496    
497  static void  static void
# Line 316  cliprdr_handle_first_handshake(STREAM s) Line 505  cliprdr_handle_first_handshake(STREAM s)
505          cliprdr_send_format_announce();          cliprdr_send_format_announce();
506  }  }
507    
508  void cliprdr_handle_server_data(uint32 length, STREAM s)  void cliprdr_handle_server_data(uint32 length, uint32 flags, STREAM s)
509  {  {
510            static uint32 remaining_length;
511            static char *data, *datap;
512            static uint32 bytes_left_to_read;
513            DEBUG_CLIPBOARD(("In cliprdr_handle_server_data, flags is %d\n",
514                             flags));
515            if (3 == flags)  /* One-op write, no packets follows */
516            {
517                    in_uint32_le(s, remaining_length);
518                    data = s->p;
519            } else if (1 == flags) /* First of several packets */
520            {      
521                    in_uint32_le(s, remaining_length);
522                    DEBUG_CLIPBOARD(("Remaining length is %d\n",
523                                     remaining_length));
524                    data = xmalloc(remaining_length);
525                    datap = data;
526                    DEBUG_CLIPBOARD(("Copying first %d bytes\n",
527                                     MAX_CLIPRDR_STANDALONE_DATASIZE));
528                    memcpy(datap, s->p, MAX_CLIPRDR_STANDALONE_DATASIZE);
529    
530                    datap+=MAX_CLIPRDR_STANDALONE_DATASIZE;
531                    bytes_left_to_read = remaining_length-MAX_CLIPRDR_STANDALONE_DATASIZE;
532                    return;
533            } else if (0 == flags)
534            {
535                    DEBUG_CLIPBOARD(("Copying %d middle bytes",
536                                     MAX_CLIPRDR_CONTINUATION_DATASIZE));
537                    memcpy(datap, s->p, MAX_CLIPRDR_CONTINUATION_DATASIZE);
538    
539                    datap+=MAX_CLIPRDR_CONTINUATION_DATASIZE;
540                    bytes_left_to_read-=MAX_CLIPRDR_CONTINUATION_DATASIZE;
541                    return;
542            } else if (2 == flags)
543            {
544                    DEBUG_CLIPBOARD(("Copying last %d bytes\n",
545                                     bytes_left_to_read));
546                    memcpy(datap, s->p, bytes_left_to_read);
547            }
548            XChangeProperty(display,
549                            selection_event.requestor,
550                            selection_event.property,
551                            XInternAtom(display, "STRING", False),
552                            8,
553                            PropModeAppend,
554                            data,
555                            remaining_length-1);
556    
557            XSendEvent(display,
558                       selection_event.requestor,
559                       False,
560                       NoEventMask,
561                       (XEvent *)&selection_event);
562    
563            if (2 == flags)
564                    xfree(data);
565    
566    }
567    
568    void cliprdr_handle_server_data_request(STREAM s)
569    {
570            Window selectionowner;
571          uint32 remaining_length;          uint32 remaining_length;
572          char *data;          uint32 wanted_formatcode, pad;
573          int res;  
574          in_uint32_le(s, remaining_length);          in_uint32_le(s, remaining_length);
575          data = s->p;          in_uint32_le(s, wanted_formatcode);
576          res = XChangeProperty(display,          in_uint32_le(s, pad);
577                                selection_event.requestor,  
578                                selection_event.property,          /* FIXME: Check that we support this formatcode */
579                                XInternAtom(display, "STRING", False),  
580                                8,          DEBUG_CLIPBOARD(("Request from server for format %d\n",
581                                PropModeAppend,                           wanted_formatcode));
582                                data,  
583                                remaining_length);          selectionowner = XGetSelectionOwner(display, primary_atom);
584    
585          DEBUG_CLIPBOARD(("res after XChangeProperty is "));          if (None != selectionowner)
586          print_X_error(res);              {
           
         res = XSendEvent(display,  
                          selection_event.requestor,  
                          False,  
                          NoEventMask,  
                          (XEvent *)&selection_event);  
587                    
588          DEBUG_CLIPBOARD(("res after XSendEvent is "));                  /* FIXME: Perhaps we should check if we are the owner? */
589          print_X_error(res);  
590                    XConvertSelection(display, primary_atom,
591                                      targets_atom,
592                                      rdesktop_clipboard_target_atom,
593                                      wnd, CurrentTime);
594    
595                    /* The rest of the transfer is handled in
596                       cliprdr_handle_SelectionNotify */
597    
598            } else
599            {
600                    DEBUG_CLIPBOARD(("There were no owner for PRIMARY, sending empty string\n")); // FIXME: Should we always send an empty string?
601    
602                    cliprdr_send_empty_datapacket();
603            }
604    
605    
606  }  }
607            
608    
609  void cliprdr_callback(STREAM s)  void cliprdr_callback(STREAM s, uint16 channelno)
610  {  {
611            static int failed_clipboard_acks = 0;
612            struct timeval timeval;
613          uint32 length, flags;          uint32 length, flags;
614          uint16 ptype0, ptype1;          uint16 ptype0, ptype1;
615          DEBUG_CLIPBOARD(("cliprdr_callback called, clipboard data:\n"));          clipboard_channelno = channelno;
616            DEBUG_CLIPBOARD(("cliprdr_callback called with channelno %d, clipboard data:\n", channelno));
617  #ifdef WITH_DEBUG_CLIPBOARD  #ifdef WITH_DEBUG_CLIPBOARD
618          hexdump(s->p, s->end - s->p);          //      hexdump(s->p, s->end - s->p);
619  #endif  #endif
620          in_uint32_le(s, length);          in_uint32_le(s, length);
621          in_uint32_le(s, flags);          in_uint32_le(s, flags);
622    
623          DEBUG_CLIPBOARD(("length is %d, flags are %d\n", length, flags));          DEBUG_CLIPBOARD(("length is %d, flags are %d\n", length, flags));
624    
625          if (flags & 0x03 || flags & 0x01) /* Single-write op or first-packet-of-several op */          if (3 == flags || 1 == flags) /* Single-write op or first-packet-of-several op */
626          {          {
627                  in_uint16_le(s, ptype0);                  in_uint16_le(s, ptype0);
628                  in_uint16_le(s, ptype1);                  in_uint16_le(s, ptype1);
# Line 373  void cliprdr_callback(STREAM s) Line 636  void cliprdr_callback(STREAM s)
636                          // 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,
637                          // but probably not.                          // but probably not.
638                          DEBUG_CLIPBOARD(("Received format announce ACK\n"));                          DEBUG_CLIPBOARD(("Received format announce ACK\n"));
639                            failed_clipboard_acks = 0;
640                          return;                          return;
641    
642                    } else if (3 == ptype0 && 2 == ptype1)
643                    {
644                            DEBUG_CLIPBOARD(("Received failed clipboard format announce ACK, retrying\n"));
645    
646                            /* This is a fairly portable way to sleep 1/10 of
647                               a second.. */
648                            timeval.tv_sec = 0;
649                            timeval.tv_usec = 100;
650                            select(0, NULL, NULL, NULL, &timeval);
651                            if (failed_clipboard_acks < 3)
652                            {
653                                    
654                                    cliprdr_send_format_announce();
655                                    /* Make sure we don't get stuck in this loop */
656                                    failed_clipboard_acks++;
657                            }
658                            else
659                            {
660                                    warning("Reached maximum number of clipboard format announce attempts. Pasting in Windows probably won't work well now.\n");
661                            }
662                  } else if (2 == ptype0 && 0 == ptype1)                  } else if (2 == ptype0 && 0 == ptype1)
663                  {                  {
664                          cliprdr_register_server_formats(s);                          cliprdr_register_server_formats(s);
# Line 383  void cliprdr_callback(STREAM s) Line 667  void cliprdr_callback(STREAM s)
667                          return;                          return;
668                  } else if (5 == ptype0 && 1 == ptype1)                  } else if (5 == ptype0 && 1 == ptype1)
669                  {                  {
670                          cliprdr_handle_server_data(length, s);                          cliprdr_handle_server_data(length, flags, s);
671                    } else if (4 == ptype0 && 0 == ptype1)
672                    {
673                            cliprdr_handle_server_data_request(s);
674                  }                  }
675    
676                                    
677            }
678            else
679            {
680                    DEBUG_CLIPBOARD(("Handling middle or last packet\n"));
681                    cliprdr_handle_server_data(length, flags, s);
682          }          }
683  }  }
684    
# Line 394  void cliprdr_init(void) Line 687  void cliprdr_init(void)
687  {  {
688          primary_atom = XInternAtom(display, "PRIMARY", False);          primary_atom = XInternAtom(display, "PRIMARY", False);
689          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);
690          targets_atom = XInternAtom(display, "TARGETS", True);          targets_atom = XInternAtom(display, "TARGETS", False);
691          timestamp_atom = XInternAtom(display, "TIMESTAMP", True);          timestamp_atom = XInternAtom(display, "TIMESTAMP", False);
692            rdesktop_clipboard_target_atom = XInternAtom(display, "_RDESKTOP_CLIPBOARD_TARGET", False);
693            incr_atom = XInternAtom(display, "INCR", False);
694            targets[0] = targets_atom;
695            targets[1] = XInternAtom(display, "TEXT", False);
696            targets[2] = XInternAtom(display, "UTF8_STRING", False);
697            targets[3] = XInternAtom(display, "text/unicode", False);
698            targets[4] = XInternAtom(display, "TIMESTAMP", False);
699            targets[5] = XInternAtom(display, "STRING", False);
700    
701  }  }

Legend:
Removed from v.384  
changed lines
  Added in v.393

  ViewVC Help
Powered by ViewVC 1.1.26