/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1232 - (show annotations)
Fri Apr 28 07:55:36 2006 UTC (18 years 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 /* -*- 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("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 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 DEBUG_SEAMLESS(("SeamlessRDP:%s\n", line));
230 }
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