/[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 1232 - (hide annotations)
Fri Apr 28 07:55:36 2006 UTC (18 years, 1 month ago) by ossman_
File MIME type: text/plain
File size: 8467 byte(s)
Add a destroy group command to SeamlessRDP for when entire groups of windows
get killed off in one go.

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 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     unimpl("SeamlessRDP SETICON1\n");
141     }
142     else if (!strcmp("POSITION", tok1))
143     {
144     int x, y, width, height;
145    
146     if (!tok8)
147     return False;
148    
149     id = strtoul(tok3, &endptr, 0);
150     if (*endptr)
151     return False;
152    
153     x = strtol(tok4, &endptr, 0);
154     if (*endptr)
155     return False;
156     y = strtol(tok5, &endptr, 0);
157     if (*endptr)
158     return False;
159    
160     width = strtol(tok6, &endptr, 0);
161     if (*endptr)
162     return False;
163     height = strtol(tok7, &endptr, 0);
164     if (*endptr)
165     return False;
166    
167     flags = strtoul(tok8, &endptr, 0);
168     if (*endptr)
169     return False;
170    
171     ui_seamless_move_window(id, x, y, width, height, flags);
172     }
173     else if (!strcmp("ZCHANGE", tok1))
174     {
175     unsigned long behind;
176    
177     id = strtoul(tok3, &endptr, 0);
178     if (*endptr)
179     return False;
180    
181     behind = strtoul(tok4, &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_restack_window(id, behind, flags);
190     }
191     else if (!strcmp("TITLE", tok1))
192     {
193     if (!tok5)
194     return False;
195    
196     id = strtoul(tok3, &endptr, 0);
197     if (*endptr)
198     return False;
199    
200     flags = strtoul(tok5, &endptr, 0);
201     if (*endptr)
202     return False;
203    
204     ui_seamless_settitle(id, tok4, flags);
205     }
206     else if (!strcmp("STATE", tok1))
207     {
208     unsigned int state;
209    
210     if (!tok5)
211     return False;
212    
213     id = strtoul(tok3, &endptr, 0);
214     if (*endptr)
215     return False;
216    
217     state = strtoul(tok4, &endptr, 0);
218     if (*endptr)
219     return False;
220    
221     flags = strtoul(tok5, &endptr, 0);
222     if (*endptr)
223     return False;
224    
225     ui_seamless_setstate(id, state, flags);
226     }
227     else if (!strcmp("DEBUG", tok1))
228     {
229 ossman_ 1231 DEBUG_SEAMLESS(("SeamlessRDP:%s\n", line));
230 astrand 1199 }
231     else if (!strcmp("SYNCBEGIN", tok1))
232     {
233     if (!tok3)
234     return False;
235    
236     flags = strtoul(tok3, &endptr, 0);
237     if (*endptr)
238     return False;
239    
240     ui_seamless_syncbegin(flags);
241     }
242     else if (!strcmp("SYNCEND", tok1))
243     {
244     if (!tok3)
245     return False;
246    
247     flags = strtoul(tok3, &endptr, 0);
248     if (*endptr)
249     return False;
250    
251     /* do nothing, currently */
252     }
253     else if (!strcmp("HELLO", tok1))
254     {
255     if (!tok3)
256     return False;
257    
258     flags = strtoul(tok3, &endptr, 0);
259     if (*endptr)
260     return False;
261    
262     ui_seamless_begin(!!(flags & SEAMLESSRDP_HELLO_HIDDEN));
263     }
264     else if (!strcmp("ACK", tok1))
265     {
266     unsigned int serial;
267    
268     serial = strtoul(tok3, &endptr, 0);
269     if (*endptr)
270     return False;
271    
272     ui_seamless_ack(serial);
273     }
274     else if (!strcmp("HIDE", tok1))
275     {
276     if (!tok3)
277     return False;
278    
279     flags = strtoul(tok3, &endptr, 0);
280     if (*endptr)
281     return False;
282    
283     ui_seamless_hide_desktop();
284     }
285     else if (!strcmp("UNHIDE", tok1))
286     {
287     if (!tok3)
288     return False;
289    
290     flags = strtoul(tok3, &endptr, 0);
291     if (*endptr)
292     return False;
293    
294     ui_seamless_unhide_desktop();
295     }
296    
297    
298     xfree(l);
299     return True;
300     }
301    
302    
303     static BOOL
304     seamless_line_handler(const char *line, void *data)
305     {
306     if (!seamless_process_line(line, data))
307     {
308     warning("SeamlessRDP: Invalid request:%s\n", line);
309     }
310     return True;
311     }
312    
313    
314     static void
315     seamless_process(STREAM s)
316     {
317     unsigned int pkglen;
318     static char *rest = NULL;
319     char *buf;
320    
321     pkglen = s->end - s->p;
322     /* str_handle_lines requires null terminated strings */
323     buf = xmalloc(pkglen + 1);
324     STRNCPY(buf, (char *) s->p, pkglen + 1);
325     #if 0
326     printf("seamless recv:\n");
327     hexdump(s->p, pkglen);
328     #endif
329    
330     str_handle_lines(buf, &rest, seamless_line_handler, NULL);
331    
332     xfree(buf);
333     }
334    
335    
336     BOOL
337     seamless_init(void)
338     {
339     if (!g_seamless_rdp)
340     return False;
341    
342     seamless_serial = 0;
343    
344     seamless_channel =
345     channel_register("seamrdp", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
346     seamless_process);
347     return (seamless_channel != NULL);
348     }
349    
350    
351     static unsigned int
352     seamless_send(const char *command, const char *format, ...)
353     {
354     STREAM s;
355     size_t len;
356     va_list argp;
357     char buf[1025];
358    
359     len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
360    
361     assert(len < (sizeof(buf) - 1));
362    
363     va_start(argp, format);
364     len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
365     va_end(argp);
366    
367     assert(len < (sizeof(buf) - 1));
368    
369     buf[len] = '\n';
370     buf[len + 1] = '\0';
371    
372     len++;
373    
374     s = channel_init(seamless_channel, len);
375     out_uint8p(s, buf, len) s_mark_end(s);
376    
377     DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
378    
379     #if 0
380     printf("seamless send:\n");
381     hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
382     #endif
383    
384     channel_send(s, seamless_channel);
385    
386     return seamless_serial++;
387     }
388    
389    
390     unsigned int
391     seamless_send_sync()
392     {
393     if (!g_seamless_rdp)
394     return (unsigned int) -1;
395    
396     return seamless_send("SYNC", "");
397     }
398    
399    
400     unsigned int
401     seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
402     {
403     if (!g_seamless_rdp)
404     return (unsigned int) -1;
405    
406     return seamless_send("STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
407     }
408    
409    
410     unsigned int
411     seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
412     {
413     return seamless_send("POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height,
414     flags);
415     }
416    
417    
418     /* Update select timeout */
419     void
420     seamless_select_timeout(struct timeval *tv)
421     {
422     struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
423    
424     if (g_seamless_rdp)
425     {
426     if (timercmp(&ourtimeout, tv, <))
427     {
428     tv->tv_sec = ourtimeout.tv_sec;
429     tv->tv_usec = ourtimeout.tv_usec;
430     }
431     }
432     }
433    
434    
435     unsigned int
436     seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
437     {
438     if (!g_seamless_rdp)
439     return (unsigned int) -1;
440    
441     return seamless_send("ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
442     }
443    
444    
445    
446     unsigned int
447     seamless_send_focus(unsigned long id, unsigned long flags)
448     {
449     if (!g_seamless_rdp)
450     return (unsigned int) -1;
451    
452     return seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags);
453     }

  ViewVC Help
Powered by ViewVC 1.1.26