/[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 387 by forsberg, Fri Jun 6 09:25:30 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_format_announce(void)
56    {
57            STREAM s;
58            int number_of_formats = 1;
59            s = sec_init(encryption ? SEC_ENCRYPT : 0, number_of_formats*36+12+4+4);
60            out_uint32_le(s, number_of_formats*36+12);
61            out_uint32_le(s, 0x13);
62            out_uint16_le(s, 2);
63            out_uint16_le(s, 0);
64            out_uint32_le(s, number_of_formats*36);
65            
66            //      out_uint32_le(s, 0xd); // FIXME: This is a rather bogus unicode text description..
67            //      rdp_out_unistr(s, "", 16);
68            //      out_uint8s(s, 32);
69    
70    
71            out_uint32_le(s, 1); // FIXME: This is a rather bogus text description..
72            out_uint8s(s, 32);
73    
74            out_uint32_le(s, 0);
75    
76            s_mark_end(s);
77            sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!
78    }
79    
80    
81    static void
82    cliprdr_send_empty_datapacket(void)
83    {
84            STREAM out;
85            out =  sec_init(encryption ? SEC_ENCRYPT : 0,
86                            20);
87            out_uint32_le(out, 12);
88            out_uint32_le(out, 0x13);
89            out_uint16_le(out, 5);
90            out_uint16_le(out, 1);
91            out_uint32_le(out, 0);
92            /* Insert null string here? */
93            out_uint32_le(out, 0);
94            s_mark_end(out);
95            
96            sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!  
97    }
98    
99    
100  void  void
101  cliprdr_handle_SelectionNotify(void)  cliprdr_handle_SelectionNotify(XSelectionEvent *event)
102  {  {
103    
104            unsigned char   *data;
105            unsigned long   nitems, bytes_left;
106            int res;
107    
108            int format;
109            Atom type_return;
110            Atom best_target;
111    
112            STREAM out;
113            
114          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionNotify\n"));
115    
116            if (None == event->property) {
117                    cliprdr_send_empty_datapacket();
118                    return; /* Selection failed */
119            }
120    
121            DEBUG_CLIPBOARD(("selection: %s, target: %s, property: %s\n",
122                             XGetAtomName(display, event->selection),
123                             XGetAtomName(display, event->target),
124                             XGetAtomName(display, event->property)));
125    
126            if (targets_atom == event->target) {
127                    /* Response to TARGETS request. Let's find the target
128                       we want and request that */
129                    res = XGetWindowProperty(display, wnd,
130                                             rdesktop_clipboard_target_atom,
131                                             0L, 4096L, False, AnyPropertyType,
132                                             &type_return,
133                                             &format, &nitems, &bytes_left, &data);
134    
135                    if (Success != res)
136                    {
137                            DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
138                            cliprdr_send_empty_datapacket();
139                            return;
140                    }
141    
142                    if (None == type_return)
143                            /* The owner might no support TARGETS. Just try
144                               STRING */
145                            best_target = XA_STRING;
146                    else
147                    {
148                            /* FIXME: We should choose format here based
149                               on what the server wanted */
150                            best_target = XInternAtom(display, "TEXT", False);
151                            
152                            
153                    }
154    
155                    XConvertSelection(display, primary_atom,
156                                      best_target,
157                                      rdesktop_clipboard_target_atom,
158                                      wnd, event->time);
159    
160            }
161            else  /* Other clipboard data */
162            {
163                    
164                    res = XGetWindowProperty(display, wnd,
165                                             rdesktop_clipboard_target_atom,
166                                             0L, 4096L, False, AnyPropertyType,
167                                             &type_return,
168                                             &format, &nitems, &bytes_left, &data);
169    
170                    if (Success != res)
171                    {
172                            DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n"));
173                            cliprdr_send_empty_datapacket();
174                            return;
175                    }
176    
177                    /* We need to handle INCR as well */
178    
179                    out =  sec_init(encryption ? SEC_ENCRYPT : 0,
180                                    20+nitems);
181                    out_uint32_le(out, 12+nitems);
182                    out_uint32_le(out, 0x13);
183                    out_uint16_le(out, 5);
184                    out_uint16_le(out, 1);
185                    out_uint32_le(out, nitems);
186                    out_uint8p(out, data, nitems);
187                    /* Insert null string here? */
188                    out_uint32_le(out, 0);
189                    s_mark_end(out);
190            
191                    sec_send_to_channel(out, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!  
192                    
193            }
194            
195            
196  }  }
197    
198  void  void
199  cliprdr_handle_SelectionClear(void)  cliprdr_handle_SelectionClear(void)
200  {  {
201          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionClear\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionClear\n"));
202            cliprdr_send_format_announce();
203  }  }
204    
205  void print_X_error(int res)  void print_X_error(int res)
# Line 89  void print_X_error(int res) Line 230  void print_X_error(int res)
230                  break;                  break;
231    
232          case BadWindow:          case BadWindow:
233                  DEBUG_CLIPBOARD(("BadWindo\n"));                  DEBUG_CLIPBOARD(("BadWindow\n"));
234                  break;                  break;
235    
236          default:          default:
# Line 97  void print_X_error(int res) Line 238  void print_X_error(int res)
238          }          }
239  }  }
240    
241    static void
242    cliprdr_request_clipboard_data(uint32 formatcode)
243    {
244            STREAM s;
245            s = sec_init(encryption ? SEC_ENCRYPT : 0, 24);
246            out_uint32_le(s, 16);
247            out_uint32_le(s, 0x13);
248            out_uint16_le(s, 4);
249            out_uint16_le(s, 0);
250            out_uint32_le(s, 4); // Remaining length
251            out_uint32_le(s, formatcode);
252            out_uint32_le(s, 0); // Unknown. Garbage pad?
253    
254            s_mark_end(s);
255    
256            sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!
257    }
258    
259    
260  void  void
261  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)  cliprdr_handle_SelectionRequest(XSelectionRequestEvent *xevent)
262  {  {
263    
         Atom type_return;  
264          Atom *targets;          Atom *targets;
         int format_return;  
         long nitems_return;  
         long bytes_after_return;  
         char **prop_return;  
265          int res;          int res;
266    
267          XSelectionEvent xev;          XSelectionEvent xev;
268          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));          DEBUG_CLIPBOARD(("cliprdr_handle_SelectionRequest\n"));
269          DEBUG_CLIPBOARD(("Requestor window id 0x%x ", xevent->requestor));          DEBUG_CLIPBOARD(("Requestor window id 0x%x ",
270                             (unsigned)xevent->requestor));
271          if (clipboard_atom == xevent->selection) {          if (clipboard_atom == xevent->selection) {
272                  DEBUG_CLIPBOARD(("wants CLIPBOARD\n"));                  DEBUG_CLIPBOARD(("wants CLIPBOARD\n"));
273          }          }
# Line 120  cliprdr_handle_SelectionRequest(XSelecti Line 276  cliprdr_handle_SelectionRequest(XSelecti
276          }            }  
277          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",
278                           XGetAtomName(display, xevent->target),                           XGetAtomName(display, xevent->target),
279                           xevent->target,                           (unsigned)xevent->target,
280                           XGetAtomName(display, xevent->property),                           XGetAtomName(display, xevent->property),
281                           xevent->property));                           (unsigned)xevent->property));
282    
283          xev.type = SelectionNotify;          xev.type = SelectionNotify;
284          xev.serial = 0;          xev.serial = 0;
# Line 161  cliprdr_handle_SelectionRequest(XSelecti Line 317  cliprdr_handle_SelectionRequest(XSelecti
317          } else if (timestamp_atom == xevent->target)          } else if (timestamp_atom == xevent->target)
318          {          {
319                  DEBUG_CLIPBOARD(("TIMESTAMP requested... sending 0x%x\n",                  DEBUG_CLIPBOARD(("TIMESTAMP requested... sending 0x%x\n",
320                                   last_keyrelease));                                   (unsigned)last_keyrelease));
321                  res = XChangeProperty(display,                  res = XChangeProperty(display,
322                                        xevent->requestor,                                        xevent->requestor,
323                                        xevent->property,                                        xevent->property,
# Line 177  cliprdr_handle_SelectionRequest(XSelecti Line 333  cliprdr_handle_SelectionRequest(XSelecti
333                                   (XEvent *)&xev);                                   (XEvent *)&xev);
334          } else /* Some other target */          } else /* Some other target */
335          {          {
336                  res = XChangeProperty(display,                  cliprdr_request_clipboard_data(CF_TEXT);
337                                        xevent->requestor,                  memcpy(&selection_event, &xev, sizeof(xev));
338                                        xevent->property,                  /* Return and wait for data, handled by
339                                        XInternAtom(display, "STRING", False),                     cliprdr_handle_server_data */
340                                        8,          }
341                                        PropModeAppend,  }
                                       "krattoflabkat",  
                                       13);  
342    
                 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;  
343    
344                  res = XSendEvent(display,  static void
345                                   xevent->requestor,  cliprdr_ack_format_list(void)
346                                   False,  {
347                                   NoEventMask,          STREAM s;
348                                   (XEvent *)&xev);          s = sec_init(encryption ? SEC_ENCRYPT : 0, 20);
349                    out_uint32_le(s, 12);
350                  DEBUG_CLIPBOARD(("res after XSendEvent is "));          out_uint32_le(s, 0x13);
351                  print_X_error(res);          out_uint16_le(s, 3);
352          }          out_uint16_le(s, 1);
353            out_uint32_le(s, 0);
354            out_uint32_le(s, 0x0000c0da);
355    
356            s_mark_end(s);
357    
358            sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!
359  }  }
360    
361                    
362    
363    
364    
365  static void  static void
366  cliprdr_register_server_formats(STREAM s)  cliprdr_register_server_formats(STREAM s)
# Line 238  cliprdr_register_server_formats(STREAM s Line 390  cliprdr_register_server_formats(STREAM s
390          while (1 < num_formats) {          while (1 < num_formats) {
391                  in_uint32_le(s, this->identifier);                  in_uint32_le(s, this->identifier);
392                  in_uint8a(s, this->textual_description, 32);                  in_uint8a(s, this->textual_description, 32);
393                  DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n", this->identifier));                  DEBUG_CLIPBOARD(("Stored format description with numeric id %d\n",
394                                     this->identifier));
395                  this-> next = xmalloc(sizeof(cliprdr_dataformat));                  this-> next = xmalloc(sizeof(cliprdr_dataformat));
396                  this = this->next;                  this = this->next;
397                  num_formats--;                  num_formats--;
# Line 267  cliprdr_select_X_clipboards(void) Line 420  cliprdr_select_X_clipboards(void)
420                    
421  }  }
422    
 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);  
423                    
         out_uint32_le(s, 0xd); // FIXME: This is a rather bogus unicode text description..  
         //      rdp_out_unistr(s, "", 16);  
         out_uint8s(s, 32);  
424    
         out_uint32_le(s, 0);  
425    
         s_mark_end(s);  
         sec_send_to_channel(s, encryption ? SEC_ENCRYPT : 0, 1005); // FIXME: Don't hardcode channel!  
 }  
                   
426    
427  static void  static void
428  cliprdr_handle_first_handshake(STREAM s)  cliprdr_handle_first_handshake(STREAM s)
# Line 301  cliprdr_handle_first_handshake(STREAM s) Line 435  cliprdr_handle_first_handshake(STREAM s)
435          cliprdr_send_format_announce();          cliprdr_send_format_announce();
436  }  }
437    
438    void cliprdr_handle_server_data(uint32 length, STREAM s)
439    {
440            uint32 remaining_length;
441            char *data;
442            int res;
443            in_uint32_le(s, remaining_length);
444            data = s->p;
445            res = XChangeProperty(display,
446                                  selection_event.requestor,
447                                  selection_event.property,
448                                  XInternAtom(display, "STRING", False),
449                                  8,
450                                  PropModeAppend,
451                                  data,
452                                  remaining_length);
453    
454            DEBUG_CLIPBOARD(("res after XChangeProperty is "));
455            print_X_error(res);    
456            
457            res = XSendEvent(display,
458                             selection_event.requestor,
459                             False,
460                             NoEventMask,
461                             (XEvent *)&selection_event);
462            
463            DEBUG_CLIPBOARD(("res after XSendEvent is "));
464            print_X_error(res);
465    
466    }
467    
468    void cliprdr_handle_server_data_request(STREAM s)
469    {
470            Window selectionowner;
471            uint32 remaining_length;
472            uint32 wanted_formatcode, pad;
473    
474            in_uint32_le(s, remaining_length);
475            in_uint32_le(s, wanted_formatcode);
476            in_uint32_le(s, pad);
477    
478            /* FIXME: Check that we support this formatcode */
479    
480            DEBUG_CLIPBOARD(("Request from server for format %d\n",
481                             wanted_formatcode));
482    
483            selectionowner = XGetSelectionOwner(display, primary_atom);
484    
485            if (None != selectionowner)
486            {
487            
488                    /* FIXME: Perhaps we should check if we are the owner? */
489    
490                    XConvertSelection(display, primary_atom,
491                                      targets_atom,
492                                      rdesktop_clipboard_target_atom,
493                                      wnd, CurrentTime);
494    
495                    /* The rest of the transfer is handled in
496                       cliprdr_handle_SelectionNotify */
497    
498            } else
499            {
500                    DEBUG_CLIPBOARD(("There were no owner for PRIMARY, sending empty string\n")); // FIXME: Should we always send an empty string?
501    
502                    cliprdr_send_empty_datapacket();
503            }
504    
505    
506    }
507            
508    
509  void cliprdr_callback(STREAM s)  void cliprdr_callback(STREAM s)
510  {  {
511          uint32 length, flags;          uint32 length, flags;
# Line 329  void cliprdr_callback(STREAM s) Line 534  void cliprdr_callback(STREAM s)
534                          // but probably not.                          // but probably not.
535                          DEBUG_CLIPBOARD(("Received format announce ACK\n"));                          DEBUG_CLIPBOARD(("Received format announce ACK\n"));
536                          return;                          return;
537    
538                  } else if (2 == ptype0 && 0 == ptype1)                  } else if (2 == ptype0 && 0 == ptype1)
539                  {                  {
540                          cliprdr_register_server_formats(s);                          cliprdr_register_server_formats(s);
541                          cliprdr_select_X_clipboards();                          cliprdr_select_X_clipboards();
542                            cliprdr_ack_format_list();
543                          return;                          return;
544                    } else if (5 == ptype0 && 1 == ptype1)
545                    {
546                            cliprdr_handle_server_data(length, s);
547                    } else if (4 == ptype0 && 0 == ptype1)
548                    {
549                            cliprdr_handle_server_data_request(s);
550                  }                  }
551    
552                                    
553          }          }
554  }  }
555    
556    
557  void cliprdr_init(void)  void cliprdr_init(void)
558  {  {
559          primary_atom = XInternAtom(display, "PRIMARY", False);          primary_atom = XInternAtom(display, "PRIMARY", False);
560          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);          clipboard_atom = XInternAtom(display, "CLIPBOARD", False);
561          targets_atom = XInternAtom(display, "TARGETS", True);          targets_atom = XInternAtom(display, "TARGETS", False);
562          timestamp_atom = XInternAtom(display, "TIMESTAMP", True);          timestamp_atom = XInternAtom(display, "TIMESTAMP", False);
563            rdesktop_clipboard_target_atom = XInternAtom(display, "_RDESKTOP_CLIPBOARD_TARGET", False);
564  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26