/[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 1199 - (hide annotations)
Mon Mar 27 08:17:34 2006 UTC (18 years, 3 months ago) by astrand
File MIME type: text/plain
File size: 8204 byte(s)
Added SeamlessRDP support: Merged seamlessrdp-branch

1 astrand 1199 /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.
3     Seamless Windows support
4     Copyright (C) Peter Astrand <astrand@cendio.se> 2005-2006
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "rdesktop.h"
22     #include <stdarg.h>
23     #include <assert.h>
24    
25     /* #define WITH_DEBUG_SEAMLESS */
26    
27     #ifdef WITH_DEBUG_SEAMLESS
28     #define DEBUG_SEAMLESS(args) printf args;
29     #else
30     #define DEBUG_SEAMLESS(args)
31     #endif
32    
33     extern BOOL g_seamless_rdp;
34     static VCHANNEL *seamless_channel;
35     static unsigned int seamless_serial;
36    
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     static BOOL
62     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     else if (!strcmp("SETICON", tok1))
124     {
125     unimpl("SeamlessRDP SETICON1\n");
126     }
127     else if (!strcmp("POSITION", tok1))
128     {
129     int x, y, width, height;
130    
131     if (!tok8)
132     return False;
133    
134     id = strtoul(tok3, &endptr, 0);
135     if (*endptr)
136     return False;
137    
138     x = strtol(tok4, &endptr, 0);
139     if (*endptr)
140     return False;
141     y = strtol(tok5, &endptr, 0);
142     if (*endptr)
143     return False;
144    
145     width = strtol(tok6, &endptr, 0);
146     if (*endptr)
147     return False;
148     height = strtol(tok7, &endptr, 0);
149     if (*endptr)
150     return False;
151    
152     flags = strtoul(tok8, &endptr, 0);
153     if (*endptr)
154     return False;
155    
156     ui_seamless_move_window(id, x, y, width, height, flags);
157     }
158     else if (!strcmp("ZCHANGE", tok1))
159     {
160     unsigned long behind;
161    
162     id = strtoul(tok3, &endptr, 0);
163     if (*endptr)
164     return False;
165    
166     behind = strtoul(tok4, &endptr, 0);
167     if (*endptr)
168     return False;
169    
170     flags = strtoul(tok5, &endptr, 0);
171     if (*endptr)
172     return False;
173    
174     ui_seamless_restack_window(id, behind, flags);
175     }
176     else if (!strcmp("TITLE", tok1))
177     {
178     if (!tok5)
179     return False;
180    
181     id = strtoul(tok3, &endptr, 0);
182     if (*endptr)
183     return False;
184    
185     flags = strtoul(tok5, &endptr, 0);
186     if (*endptr)
187     return False;
188    
189     ui_seamless_settitle(id, tok4, flags);
190     }
191     else if (!strcmp("STATE", tok1))
192     {
193     unsigned int state;
194    
195     if (!tok5)
196     return False;
197    
198     id = strtoul(tok3, &endptr, 0);
199     if (*endptr)
200     return False;
201    
202     state = strtoul(tok4, &endptr, 0);
203     if (*endptr)
204     return False;
205    
206     flags = strtoul(tok5, &endptr, 0);
207     if (*endptr)
208     return False;
209    
210     ui_seamless_setstate(id, state, flags);
211     }
212     else if (!strcmp("DEBUG", tok1))
213     {
214     printf("SeamlessRDP:%s\n", line);
215     }
216     else if (!strcmp("SYNCBEGIN", tok1))
217     {
218     if (!tok3)
219     return False;
220    
221     flags = strtoul(tok3, &endptr, 0);
222     if (*endptr)
223     return False;
224    
225     ui_seamless_syncbegin(flags);
226     }
227     else if (!strcmp("SYNCEND", tok1))
228     {
229     if (!tok3)
230     return False;
231    
232     flags = strtoul(tok3, &endptr, 0);
233     if (*endptr)
234     return False;
235    
236     /* do nothing, currently */
237     }
238     else if (!strcmp("HELLO", tok1))
239     {
240     if (!tok3)
241     return False;
242    
243     flags = strtoul(tok3, &endptr, 0);
244     if (*endptr)
245     return False;
246    
247     ui_seamless_begin(!!(flags & SEAMLESSRDP_HELLO_HIDDEN));
248     }
249     else if (!strcmp("ACK", tok1))
250     {
251     unsigned int serial;
252    
253     serial = strtoul(tok3, &endptr, 0);
254     if (*endptr)
255     return False;
256    
257     ui_seamless_ack(serial);
258     }
259     else if (!strcmp("HIDE", tok1))
260     {
261     if (!tok3)
262     return False;
263    
264     flags = strtoul(tok3, &endptr, 0);
265     if (*endptr)
266     return False;
267    
268     ui_seamless_hide_desktop();
269     }
270     else if (!strcmp("UNHIDE", tok1))
271     {
272     if (!tok3)
273     return False;
274    
275     flags = strtoul(tok3, &endptr, 0);
276     if (*endptr)
277     return False;
278    
279     ui_seamless_unhide_desktop();
280     }
281    
282    
283     xfree(l);
284     return True;
285     }
286    
287    
288     static BOOL
289     seamless_line_handler(const char *line, void *data)
290     {
291     if (!seamless_process_line(line, data))
292     {
293     warning("SeamlessRDP: Invalid request:%s\n", line);
294     }
295     return True;
296     }
297    
298    
299     static void
300     seamless_process(STREAM s)
301     {
302     unsigned int pkglen;
303     static char *rest = NULL;
304     char *buf;
305    
306     pkglen = s->end - s->p;
307     /* str_handle_lines requires null terminated strings */
308     buf = xmalloc(pkglen + 1);
309     STRNCPY(buf, (char *) s->p, pkglen + 1);
310     #if 0
311     printf("seamless recv:\n");
312     hexdump(s->p, pkglen);
313     #endif
314    
315     str_handle_lines(buf, &rest, seamless_line_handler, NULL);
316    
317     xfree(buf);
318     }
319    
320    
321     BOOL
322     seamless_init(void)
323     {
324     if (!g_seamless_rdp)
325     return False;
326    
327     seamless_serial = 0;
328    
329     seamless_channel =
330     channel_register("seamrdp", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
331     seamless_process);
332     return (seamless_channel != NULL);
333     }
334    
335    
336     static unsigned int
337     seamless_send(const char *command, const char *format, ...)
338     {
339     STREAM s;
340     size_t len;
341     va_list argp;
342     char buf[1025];
343    
344     len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
345    
346     assert(len < (sizeof(buf) - 1));
347    
348     va_start(argp, format);
349     len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
350     va_end(argp);
351    
352     assert(len < (sizeof(buf) - 1));
353    
354     buf[len] = '\n';
355     buf[len + 1] = '\0';
356    
357     len++;
358    
359     s = channel_init(seamless_channel, len);
360     out_uint8p(s, buf, len) s_mark_end(s);
361    
362     DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
363    
364     #if 0
365     printf("seamless send:\n");
366     hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
367     #endif
368    
369     channel_send(s, seamless_channel);
370    
371     return seamless_serial++;
372     }
373    
374    
375     unsigned int
376     seamless_send_sync()
377     {
378     if (!g_seamless_rdp)
379     return (unsigned int) -1;
380    
381     return seamless_send("SYNC", "");
382     }
383    
384    
385     unsigned int
386     seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
387     {
388     if (!g_seamless_rdp)
389     return (unsigned int) -1;
390    
391     return seamless_send("STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
392     }
393    
394    
395     unsigned int
396     seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
397     {
398     return seamless_send("POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height,
399     flags);
400     }
401    
402    
403     /* Update select timeout */
404     void
405     seamless_select_timeout(struct timeval *tv)
406     {
407     struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
408    
409     if (g_seamless_rdp)
410     {
411     if (timercmp(&ourtimeout, tv, <))
412     {
413     tv->tv_sec = ourtimeout.tv_sec;
414     tv->tv_usec = ourtimeout.tv_usec;
415     }
416     }
417     }
418    
419    
420     unsigned int
421     seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
422     {
423     if (!g_seamless_rdp)
424     return (unsigned int) -1;
425    
426     return seamless_send("ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
427     }
428    
429    
430    
431     unsigned int
432     seamless_send_focus(unsigned long id, unsigned long flags)
433     {
434     if (!g_seamless_rdp)
435     return (unsigned int) -1;
436    
437     return seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags);
438     }

  ViewVC Help
Powered by ViewVC 1.1.26