/[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 383 by forsberg, Fri Jun 6 09:20:53 2003 UTC revision 386 by forsberg, Fri Jun 6 09:24:15 2003 UTC
# Line 28  extern Window wnd; Line 28  extern Window wnd;
28  extern Time last_keyrelease;  extern Time last_keyrelease;
29    
30  static Atom clipboard_atom, primary_atom, targets_atom, timestamp_atom;  static Atom clipboard_atom, primary_atom, targets_atom, timestamp_atom;
31    static Atom rdesktop_clipboard_target_atom;
32  static cliprdr_dataformat *server_formats = NULL;  static cliprdr_dataformat *server_formats = NULL;
33  static uint16 num_server_formats = 0;  static uint16 num_server_formats = 0;
34    static XSelectionEvent selection_event;
35    
36  static void  static void
37  cliprdr_print_server_formats(void)  cliprdr_print_server_formats(void)
# Line 45  cliprdr_print_server_formats(void) Line 47  cliprdr_print_server_formats(void)
47                  i++;                  i++;
48                  this = this->next;                  this = this->next;
49          }          }
50          DEBUG_CLIPBOARD(("There was %d server formats.\n", i));          DEBUG_CLIPBOARD(("There were %d server formats.\n", i));
51  #endif  #endif
52  }  }
53    
54    static void
55    cliprdr_send_empty_datapacket(void)
56    {
57            STREAM out;
58            out =  sec_init(encryption ? SEC_ENCRYPT : 0,
59                            20);
60            out_uint32_le(out, 12);
61            out_uint32_le(out, 0x13);
62            out_uint16_le(out, 5);
63            out_uint16_le(out, 1);
64            out_uint32_le(out, 0);
65            /* Insert null string here? */
66            out_uint32_le(out, 0);
67            s_mark_end(out);
68            
69            sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!  
70    }
71    
72    
73  void  void
74  cliprdr_handle_SelectionNotify(void)  cliprdr_handle_SelectionNotify(XSelectionEvent *event)
75  {  {
76    
77            unsigned char   *data;
78            unsigned long   nitems, bytes_left;
79            int res;
80    
81            int format;
82            Atom type_return;
83            Atom best_target;
84    
85            STREAM out;
86            
87          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));
88    
89            if (None == event->property) {
90                    cliprdr_send_empty_datapacket();
91                    return; /* Selection failed */
92            }
93    
94            DEBUG_CLIPBOARD(("selection: %s, target: %s, property: %s\n",
95                             XGetAtomName(display, event->selection),
96                             XGetAtomName(display, event->target),
97                             XGetAtomName(display, event->property)));
98    
99            if (targets_atom == event->target) {
100                    /* Response to TARGETS request. Let's find the target
101                       we want and request that */
102                    res = XGetWindowProperty(display, wnd,
103                                             rdesktop_clipboard_target_atom,
104                                             0L, 4096L, False, AnyPropertyType,
105                                             &type_return,
106                                             &format, &nitems, &bytes_left, &data);
107    
108                    if (Success != res)
109                    {
110                            DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
111                            cliprdr_send_empty_datapacket();
112                            return;
113                    }
114    
115                    if (None == type_return)
116                            /* The owner might no support TARGETS. Just try
117                               STRING */
118                            best_target = XA_STRING;
119                    else
120                    {
121                            /* FIXME: We should choose format here based
122                               on what the server wanted */
123                            best_target = XInternAtom(display, "TEXT", False);
124                            
125                            
126                    }
127    
128                    XConvertSelection(display, primary_atom,
129                                      best_target,
130                                      rdesktop_clipboard_target_atom,
131                                      wnd, event->time);
132    
133            }
134            else  /* Other clipboard data */
135            {
136                    
137                    res = XGetWindowProperty(display, wnd,
138                                             rdesktop_clipboard_target_atom,
139                                             0L, 4096L, False, AnyPropertyType,
140                                             &type_return,
141                                             &format, &nitems, &bytes_left, &data);
142    
143                    if (Success != res)
144                    {
145                            DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
146                            cliprdr_send_empty_datapacket();
147                            return;
148                    }
149    
150                    /* We need to handle INCR as well */
151    
152                    out =  sec_init(encryption ? SEC_ENCRYPT : 0,
153                                    20+nitems);
154                    out_uint32_le(out, 12+nitems);
155                    out_uint32_le(out, 0x13);
156                    out_uint16_le(out, 5);
157                    out_uint16_le(out, 1);
158                    out_uint32_le(out, nitems);
159                    out_uint8p(out, data, nitems);
160                    /* Insert null string here? */
161                    out_uint32_le(out, 0);
162                    s_mark_end(out);
163            
164                    sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!  
165                    
166            }
167            
168            
169  }  }
170    
171  void  void
# Line 89  void print_X_error(int res) Line 202  void print_X_error(int res)
202                  break;                  break;
203    
204          case BadWindow:          case BadWindow:
205                  DEBUG_CLIPBOARD(("BadWindo\n"));                  DEBUG_CLIPBOARD(("BadWindow\n"));
206                  break;                  break;
207    
208          default:          default:
# Line 97  void print_X_error(int res) Line 210  void print_X_error(int res)
210          }          }
211  }  }
212    
213    static void
214    cliprdr_request_clipboard_data(uint32 formatcode)
215    {
216            STREAM s;
217            s = sec_init(encryption ? SEC_ENCRYPT : 0, 24);
218            out_uint32_le(s, 16);
219            out_uint32_le(s, 0x13);
220            out_uint16_le(s, 4);
221            out_uint16_le(s, 0);
222            out_uint32_le(s, 4); // Remaining length
223            out_uint32_le(s, formatcode);
224            out_uint32_le(s, 0); // Unknown. Garbage pad?
225    
226            s_mark_end(s);
227    
228            sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!
229    }
230    
231    
232  void  void
233  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)
234  {  {
235    
         Atom type_return;  
236          Atom *targets;          Atom *targets;
         int format_return;  
         long nitems_return;  
         long bytes_after_return;  
         char **prop_return;  
237          int res;          int res;
238    
239          XSelectionEvent xev;          XSelectionEvent xev;
240          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));
241          DEBUG_CLIPBOARD(("Requestor window id 0x%x ", xevent->requestor));          DEBUG_CLIPBOARD(("Requestor window id 0x%x ",
242                             (unsigned)xevent->requestor));
243          if (clipboard_atom == xevent->selection) {          if (clipboard_atom == xevent->selection) {
244                  DEBUG_CLIPBOARD(("wants CLIPBOARD\n"));                  DEBUG_CLIPBOARD(("wants CLIPBOARD\n"));
245          }          }
# Line 120  cliprdr_handle_SelectionRequest(XSelecti Line 248  cliprdr_handle_SelectionRequest(XSelecti
248          }            }  
249          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",
250                           XGetAtomName(display, xevent->target),                           XGetAtomName(display, xevent->target),
251                           xevent->target,                           (unsigned)xevent->target,
252                           XGetAtomName(display, xevent->property),                           XGetAtomName(display, xevent->property),
253                           xevent->property));                           (unsigned)xevent->property));
254    
255          xev.type = SelectionNotify;          xev.type = SelectionNotify;
256          xev.serial = 0;          xev.serial = 0;
# Line 161  cliprdr_handle_SelectionRequest(XSelecti Line 289  cliprdr_handle_SelectionRequest(XSelecti
289          } else if (timestamp_atom == xevent->target)          } else if (timestamp_atom == xevent->target)
290          {          {
291                  DEBUG_CLIPBOARD(("TIMESTAMP requested... sending 0x%x\n",                  DEBUG_CLIPBOARD(("TIMESTAMP requested... sending 0x%x\n",
292                                   last_keyrelease));                                   (unsigned)last_keyrelease));
293                  res = XChangeProperty(display,                  res = XChangeProperty(display,
294                                        xevent->requestor,                                        xevent->requestor,
295                                        xevent->property,                                        xevent->property,
# Line 177  cliprdr_handle_SelectionRequest(XSelecti Line 305  cliprdr_handle_SelectionRequest(XSelecti
305                                   (XEvent *)&xev);                                   (XEvent *)&xev);
306          } else /* Some other target */          } else /* Some other target */
307          {          {
308                  res = XChangeProperty(display,                  cliprdr_request_clipboard_data(CF_TEXT);
309                                        xevent->requestor,                  memcpy(&selection_event, &xev, sizeof(xev));
310                                        xevent->property,                  /* Return and wait for data, handled by
311                                        XInternAtom(display, "STRING", False),                     cliprdr_handle_server_data */
312                                        8,          }
313                                        PropModeAppend,  }
                                       "krattoflabkat",  
                                       13);  
314    
                 DEBUG_CLIPBOARD(("res after XChangeProperty is "));  
                 print_X_error(res);      
           
                 xev.type = SelectionNotify;  
                 xev.serial = 0;  
                 xev.send_event = True;  
                 xev.requestor = xevent->requestor;  
                 xev.selection = xevent->selection;  
                 xev.target = xevent->target;  
                 xev.property = xevent->property;  
                 xev.time = xevent->time;  
315    
316                  res = XSendEvent(display,  static void
317                                   xevent->requestor,  cliprdr_ack_format_list(void)
318                                   False,  {
319                                   NoEventMask,          STREAM s;
320                                   (XEvent *)&xev);          s = sec_init(encryption ? SEC_ENCRYPT : 0, 20);
321                    out_uint32_le(s, 12);
322                  DEBUG_CLIPBOARD(("res after XSendEvent is "));          out_uint32_le(s, 0x13);
323                  print_X_error(res);          out_uint16_le(s, 3);
324          }          out_uint16_le(s, 1);
325            out_uint32_le(s, 0);
326            out_uint32_le(s, 0x0000c0da);
327    
328            s_mark_end(s);
329    
330            sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!
331  }  }
332    
333                    
334    
335    
336    
337  static void  static void
338  cliprdr_register_server_formats(STREAM s)  cliprdr_register_server_formats(STREAM s)
# Line 238  cliprdr_register_server_formats(STREAM s Line 362  cliprdr_register_server_formats(STREAM s
362          while (1 < num_formats) {          while (1 < num_formats) {
363                  in_uint32_le(s, this->identifier);                  in_uint32_le(s, this->identifier);
364                  in_uint8a(s, this->textual_description, 32);                  in_uint8a(s, this->textual_description, 32);
365                  DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n", this->identifier));                  DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n",
366                                     this->identifier));
367                  this-> next = xmalloc(sizeof(cliprdr_dataformat));                  this-> next = xmalloc(sizeof(cliprdr_dataformat));
368                  this = this->next;                  this = this->next;
369                  num_formats--;                  num_formats--;
# Line 267  cliprdr_select_X_clipboards(void) Line 392  cliprdr_select_X_clipboards(void)
392                    
393  }  }
394    
395            
396    
397  static void  static void
398  cliprdr_send_format_announce(void)  cliprdr_send_format_announce(void)
399  {  {
# Line 279  cliprdr_send_format_announce(void) Line 406  cliprdr_send_format_announce(void)
406          out_uint16_le(s, 0);          out_uint16_le(s, 0);
407          out_uint32_le(s, number_of_formats*36);          out_uint32_le(s, number_of_formats*36);
408                    
409          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..
410          //      rdp_out_unistr(s, "", 16);          //      rdp_out_unistr(s, "", 16);
411            //      out_uint8s(s, 32);
412    
413    
414            out_uint32_le(s, 1); // FIXME: This is a rather bogus text description..
415          out_uint8s(s, 32);          out_uint8s(s, 32);
416    
417          out_uint32_le(s, 0);          out_uint32_le(s, 0);
# Line 288  cliprdr_send_format_announce(void) Line 419  cliprdr_send_format_announce(void)
419          s_mark_end(s);          s_mark_end(s);
420          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!          sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!
421  }  }
422                    
423    
424  static void  static void
425  cliprdr_handle_first_handshake(STREAM s)  cliprdr_handle_first_handshake(STREAM s)
# Line 301  cliprdr_handle_first_handshake(STREAM s) Line 432  cliprdr_handle_first_handshake(STREAM s)
432          cliprdr_send_format_announce();          cliprdr_send_format_announce();
433  }  }
434    
435    void cliprdr_handle_server_data(uint32 length, STREAM s)
436    {
437            uint32 remaining_length;
438            char *data;
439            int res;
440            in_uint32_le(s, remaining_length);
441            data = s->p;
442            res = XChangeProperty(display,
443                                  selection_event.requestor,
444                                  selection_event.property,
445                                  XInternAtom(display, "STRING", False),
446                                  8,
447                                  PropModeAppend,
448                                  data,
449                                  remaining_length);
450    
451            DEBUG_CLIPBOARD(("res after XChangeProperty is "));
452            print_X_error(res);    
453            
454            res = XSendEvent(display,
455                             selection_event.requestor,
456                             False,
457                             NoEventMask,
458                             (XEvent *)&selection_event);
459            
460            DEBUG_CLIPBOARD(("res after XSendEvent is "));
461            print_X_error(res);
462    
463    }
464    
465    void cliprdr_handle_server_data_request(STREAM s)
466    {
467            Window selectionowner;
468            uint32 remaining_length;
469            uint32 wanted_formatcode, pad;
470    
471            in_uint32_le(s, remaining_length);
472            in_uint32_le(s, wanted_formatcode);
473            in_uint32_le(s, pad);
474    
475            /* FIXME: Check that we support this formatcode */
476    
477            DEBUG_CLIPBOARD(("Request from server for format %d\n",
478                             wanted_formatcode));
479    
480            selectionowner = XGetSelectionOwner(display, primary_atom);
481    
482            if (None != selectionowner)
483            {
484            
485                    /* FIXME: Perhaps we should check if we are the owner? */
486    
487                    XConvertSelection(display, primary_atom,
488                                      targets_atom,
489                                      rdesktop_clipboard_target_atom,
490                                      wnd, CurrentTime);
491    
492                    /* The rest of the transfer is handled in
493                       cliprdr_handle_SelectionNotify */
494    
495            } else
496            {
497                    DEBUG_CLIPBOARD(("There were no owner for PRIMARY, sending empty string\n")); // FIXME: Should we always send an empty string?
498    
499                    cliprdr_send_empty_datapacket();
500            }
501    
502    
503    }
504            
505    
506  void cliprdr_callback(STREAM s)  void cliprdr_callback(STREAM s)
507  {  {
508          uint32 length, flags;          uint32 length, flags;
# Line 329  void cliprdr_callback(STREAM s) Line 531  void cliprdr_callback(STREAM s)
531                          // but probably not.                          // but probably not.
532                          DEBUG_CLIPBOARD(("Received format announce ACK\n"));                          DEBUG_CLIPBOARD(("Received format announce ACK\n"));
533                          return;                          return;
534    
535                  } else if (2 == ptype0 && 0 == ptype1)                  } else if (2 == ptype0 && 0 == ptype1)
536                  {                  {
537                          cliprdr_register_server_formats(s);                          cliprdr_register_server_formats(s);
538                          cliprdr_select_X_clipboards();                          cliprdr_select_X_clipboards();
539                            cliprdr_ack_format_list();
540                          return;                          return;
541                    } else if (5 == ptype0 && 1 == ptype1)
542                    {
543                            cliprdr_handle_server_data(length, s);
544                    } else if (4 == ptype0 && 0 == ptype1)
545                    {
546                            cliprdr_handle_server_data_request(s);
547                  }                  }
548    
549                                    
550          }          }
551  }  }
552    
553    
554  void cliprdr_init(void)  void cliprdr_init(void)
555  {  {
556          primary_atom = XInternAtom(display, "PRIMARY", False);          primary_atom = XInternAtom(display, "PRIMARY", False);
557          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);
558          targets_atom = XInternAtom(display, "TARGETS", True);          targets_atom = XInternAtom(display, "TARGETS", False);
559          timestamp_atom = XInternAtom(display, "TIMESTAMP", True);          timestamp_atom = XInternAtom(display, "TIMESTAMP", False);
560            rdesktop_clipboard_target_atom = XInternAtom(display, "_RDESKTOP_CLIPBOARD_TARGET", False);
561  }  }

Legend:
Removed from v.383  
changed lines
  Added in v.386

  ViewVC Help
Powered by ViewVC 1.1.26