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

Annotation of /sourceforge.net/trunk/rdesktop/seamless.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1475 - (hide annotations)
Fri Jul 11 03:51:23 2008 UTC (15 years, 11 months ago) by jsorg71
File MIME type: text/plain
File size: 9682 byte(s)
update the copyright year

1 astrand 1199 /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.
3     Seamless Windows support
4 jsorg71 1475 Copyright 2005-2008 Peter Astrand <astrand@cendio.se> for Cendio AB
5     Copyright 2007-2008 Pierre Ossman <ossman@cendio.se> for Cendio AB
6 jsorg71 1365
7 astrand 1199 This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 jsorg71 1365
12 astrand 1199 This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16 jsorg71 1365
17 astrand 1199 You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     */
21    
22     #include "rdesktop.h"
23     #include <stdarg.h>
24     #include <assert.h>
25    
26     #ifdef WITH_DEBUG_SEAMLESS
27     #define DEBUG_SEAMLESS(args) printf args;
28     #else
29     #define DEBUG_SEAMLESS(args)
30     #endif
31    
32 jsorg71 1372 extern RD_BOOL g_seamless_rdp;
33 astrand 1199 static VCHANNEL *seamless_channel;
34     static unsigned int seamless_serial;
35 ossman_ 1413 static char icon_buf[1024];
36 astrand 1199
37     static char *
38     seamless_get_token(char **s)
39     {
40     char *comma, *head;
41     head = *s;
42    
43     if (!head)
44     return NULL;
45    
46     comma = strchr(head, ',');
47     if (comma)
48     {
49     *comma = '\0';
50     *s = comma + 1;
51     }
52     else
53     {
54     *s = NULL;
55     }
56    
57     return head;
58     }
59    
60    
61 jsorg71 1372 static RD_BOOL
62 astrand 1199 seamless_process_line(const char *line, void *data)
63     {
64     char *p, *l;
65     char *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
66     unsigned long id, flags;
67     char *endptr;
68    
69     l = xstrdup(line);
70     p = l;
71    
72     DEBUG_SEAMLESS(("seamlessrdp got:%s\n", p));
73    
74     tok1 = seamless_get_token(&p);
75     tok2 = seamless_get_token(&p);
76     tok3 = seamless_get_token(&p);
77     tok4 = seamless_get_token(&p);
78     tok5 = seamless_get_token(&p);
79     tok6 = seamless_get_token(&p);
80     tok7 = seamless_get_token(&p);
81     tok8 = seamless_get_token(&p);
82    
83     if (!strcmp("CREATE", tok1))
84     {
85     unsigned long group, parent;
86     if (!tok6)
87     return False;
88    
89     id = strtoul(tok3, &endptr, 0);
90     if (*endptr)
91     return False;
92    
93     group = strtoul(tok4, &endptr, 0);
94     if (*endptr)
95     return False;
96    
97     parent = strtoul(tok5, &endptr, 0);
98     if (*endptr)
99     return False;
100    
101     flags = strtoul(tok6, &endptr, 0);
102     if (*endptr)
103     return False;
104    
105     ui_seamless_create_window(id, group, parent, flags);
106     }
107     else if (!strcmp("DESTROY", tok1))
108     {
109     if (!tok4)
110     return False;
111    
112     id = strtoul(tok3, &endptr, 0);
113     if (*endptr)
114     return False;
115    
116     flags = strtoul(tok4, &endptr, 0);
117     if (*endptr)
118     return False;
119    
120     ui_seamless_destroy_window(id, flags);
121    
122     }
123 ossman_ 1232 else if (!strcmp("DESTROYGRP", tok1))
124     {
125     if (!tok4)
126     return False;
127    
128     id = strtoul(tok3, &endptr, 0);
129     if (*endptr)
130     return False;
131    
132     flags = strtoul(tok4, &endptr, 0);
133     if (*endptr)
134     return False;
135    
136     ui_seamless_destroy_group(id, flags);
137     }
138 astrand 1199 else if (!strcmp("SETICON", tok1))
139     {
140 ossman_ 1413 int chunk, width, height, len;
141     char byte[3];
142    
143     if (!tok8)
144     return False;
145    
146     id = strtoul(tok3, &endptr, 0);
147     if (*endptr)
148     return False;
149    
150     chunk = strtoul(tok4, &endptr, 0);
151     if (*endptr)
152     return False;
153    
154     width = strtoul(tok6, &endptr, 0);
155     if (*endptr)
156     return False;
157    
158     height = strtoul(tok7, &endptr, 0);
159     if (*endptr)
160     return False;
161    
162     byte[2] = '\0';
163     len = 0;
164     while (*tok8 != '\0')
165     {
166     byte[0] = *tok8;
167     tok8++;
168     if (*tok8 == '\0')
169     return False;
170     byte[1] = *tok8;
171     tok8++;
172    
173     icon_buf[len] = strtol(byte, NULL, 16);
174     len++;
175     }
176    
177     ui_seamless_seticon(id, tok5, width, height, chunk, icon_buf, len);
178 astrand 1199 }
179 ossman_ 1413 else if (!strcmp("DELICON", tok1))
180     {
181     int width, height;
182    
183     if (!tok6)
184     return False;
185    
186     id = strtoul(tok3, &endptr, 0);
187     if (*endptr)
188     return False;
189    
190     width = strtoul(tok5, &endptr, 0);
191     if (*endptr)
192     return False;
193    
194     height = strtoul(tok6, &endptr, 0);
195     if (*endptr)
196     return False;
197    
198     ui_seamless_delicon(id, tok4, width, height);
199     }
200 astrand 1199 else if (!strcmp("POSITION", tok1))
201     {
202     int x, y, width, height;
203    
204     if (!tok8)
205     return False;
206    
207     id = strtoul(tok3, &endptr, 0);
208     if (*endptr)
209     return False;
210    
211     x = strtol(tok4, &endptr, 0);
212     if (*endptr)
213     return False;
214     y = strtol(tok5, &endptr, 0);
215     if (*endptr)
216     return False;
217    
218     width = strtol(tok6, &endptr, 0);
219     if (*endptr)
220     return False;
221     height = strtol(tok7, &endptr, 0);
222     if (*endptr)
223     return False;
224    
225     flags = strtoul(tok8, &endptr, 0);
226     if (*endptr)
227     return False;
228    
229     ui_seamless_move_window(id, x, y, width, height, flags);
230     }
231     else if (!strcmp("ZCHANGE", tok1))
232     {
233     unsigned long behind;
234    
235     id = strtoul(tok3, &endptr, 0);
236     if (*endptr)
237     return False;
238    
239     behind = strtoul(tok4, &endptr, 0);
240     if (*endptr)
241     return False;
242    
243     flags = strtoul(tok5, &endptr, 0);
244     if (*endptr)
245     return False;
246    
247     ui_seamless_restack_window(id, behind, flags);
248     }
249     else if (!strcmp("TITLE", tok1))
250     {
251     if (!tok5)
252     return False;
253    
254     id = strtoul(tok3, &endptr, 0);
255     if (*endptr)
256     return False;
257    
258     flags = strtoul(tok5, &endptr, 0);
259     if (*endptr)
260     return False;
261    
262     ui_seamless_settitle(id, tok4, flags);
263     }
264     else if (!strcmp("STATE", tok1))
265     {
266     unsigned int state;
267    
268     if (!tok5)
269     return False;
270    
271     id = strtoul(tok3, &endptr, 0);
272     if (*endptr)
273     return False;
274    
275     state = strtoul(tok4, &endptr, 0);
276     if (*endptr)
277     return False;
278    
279     flags = strtoul(tok5, &endptr, 0);
280     if (*endptr)
281     return False;
282    
283     ui_seamless_setstate(id, state, flags);
284     }
285     else if (!strcmp("DEBUG", tok1))
286     {
287 ossman_ 1231 DEBUG_SEAMLESS(("SeamlessRDP:%s\n", line));
288 astrand 1199 }
289     else if (!strcmp("SYNCBEGIN", tok1))
290     {
291     if (!tok3)
292     return False;
293    
294     flags = strtoul(tok3, &endptr, 0);
295     if (*endptr)
296     return False;
297    
298     ui_seamless_syncbegin(flags);
299     }
300     else if (!strcmp("SYNCEND", tok1))
301     {
302     if (!tok3)
303     return False;
304    
305     flags = strtoul(tok3, &endptr, 0);
306     if (*endptr)
307     return False;
308    
309     /* do nothing, currently */
310     }
311     else if (!strcmp("HELLO", tok1))
312     {
313     if (!tok3)
314     return False;
315    
316     flags = strtoul(tok3, &endptr, 0);
317     if (*endptr)
318     return False;
319    
320     ui_seamless_begin(!!(flags & SEAMLESSRDP_HELLO_HIDDEN));
321     }
322     else if (!strcmp("ACK", tok1))
323     {
324     unsigned int serial;
325    
326     serial = strtoul(tok3, &endptr, 0);
327     if (*endptr)
328     return False;
329    
330     ui_seamless_ack(serial);
331     }
332     else if (!strcmp("HIDE", tok1))
333     {
334     if (!tok3)
335     return False;
336    
337     flags = strtoul(tok3, &endptr, 0);
338     if (*endptr)
339     return False;
340    
341     ui_seamless_hide_desktop();
342     }
343     else if (!strcmp("UNHIDE", tok1))
344     {
345     if (!tok3)
346     return False;
347    
348     flags = strtoul(tok3, &endptr, 0);
349     if (*endptr)
350     return False;
351    
352     ui_seamless_unhide_desktop();
353     }
354    
355    
356     xfree(l);
357     return True;
358     }
359    
360    
361 jsorg71 1372 static RD_BOOL
362 astrand 1199 seamless_line_handler(const char *line, void *data)
363     {
364     if (!seamless_process_line(line, data))
365     {
366     warning("SeamlessRDP: Invalid request:%s\n", line);
367     }
368     return True;
369     }
370    
371    
372     static void
373     seamless_process(STREAM s)
374     {
375     unsigned int pkglen;
376     static char *rest = NULL;
377     char *buf;
378    
379     pkglen = s->end - s->p;
380     /* str_handle_lines requires null terminated strings */
381     buf = xmalloc(pkglen + 1);
382     STRNCPY(buf, (char *) s->p, pkglen + 1);
383     #if 0
384     printf("seamless recv:\n");
385     hexdump(s->p, pkglen);
386     #endif
387    
388     str_handle_lines(buf, &rest, seamless_line_handler, NULL);
389    
390     xfree(buf);
391     }
392    
393    
394 jsorg71 1372 RD_BOOL
395 astrand 1199 seamless_init(void)
396     {
397     if (!g_seamless_rdp)
398     return False;
399    
400     seamless_serial = 0;
401    
402     seamless_channel =
403     channel_register("seamrdp", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
404     seamless_process);
405     return (seamless_channel != NULL);
406     }
407    
408    
409     static unsigned int
410     seamless_send(const char *command, const char *format, ...)
411     {
412     STREAM s;
413     size_t len;
414     va_list argp;
415     char buf[1025];
416    
417     len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
418    
419     assert(len < (sizeof(buf) - 1));
420    
421     va_start(argp, format);
422     len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
423     va_end(argp);
424    
425     assert(len < (sizeof(buf) - 1));
426    
427     buf[len] = '\n';
428     buf[len + 1] = '\0';
429    
430     len++;
431    
432     s = channel_init(seamless_channel, len);
433     out_uint8p(s, buf, len) s_mark_end(s);
434    
435     DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
436    
437     #if 0
438     printf("seamless send:\n");
439     hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
440     #endif
441    
442     channel_send(s, seamless_channel);
443    
444     return seamless_serial++;
445     }
446    
447    
448     unsigned int
449     seamless_send_sync()
450     {
451     if (!g_seamless_rdp)
452     return (unsigned int) -1;
453    
454     return seamless_send("SYNC", "");
455     }
456    
457    
458     unsigned int
459     seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
460     {
461     if (!g_seamless_rdp)
462     return (unsigned int) -1;
463    
464     return seamless_send("STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
465     }
466    
467    
468     unsigned int
469     seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
470     {
471     return seamless_send("POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height,
472     flags);
473     }
474    
475    
476     /* Update select timeout */
477     void
478     seamless_select_timeout(struct timeval *tv)
479     {
480     struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
481    
482     if (g_seamless_rdp)
483     {
484     if (timercmp(&ourtimeout, tv, <))
485     {
486     tv->tv_sec = ourtimeout.tv_sec;
487     tv->tv_usec = ourtimeout.tv_usec;
488     }
489     }
490     }
491    
492    
493     unsigned int
494     seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
495     {
496     if (!g_seamless_rdp)
497     return (unsigned int) -1;
498    
499     return seamless_send("ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
500     }
501    
502    
503    
504     unsigned int
505     seamless_send_focus(unsigned long id, unsigned long flags)
506     {
507     if (!g_seamless_rdp)
508     return (unsigned int) -1;
509    
510     return seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags);
511     }
512 astrand 1447
513     /* Send client-to-server message to destroy process on the server. */
514     unsigned int
515     seamless_send_destroy(unsigned long id)
516     {
517     return seamless_send("DESTROY", "0x%08lx", id);
518     }

  ViewVC Help
Powered by ViewVC 1.1.26