/[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 1231 - (show annotations)
Thu Apr 20 13:01:45 2006 UTC (18 years, 1 month ago) by ossman_
File MIME type: text/plain
File size: 8214 byte(s)
Don't print server side debug messages unless WITH_DEBUG_SEAMLESS is defined.

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("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 DEBUG_SEAMLESS(("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