VirtualBox

source: vbox/trunk/src/VBox/RDP/client/seamless.c@ 8497

最後變更 在這個檔案從8497是 7826,由 vboxsync 提交於 17 年 前

Export modified rdesktop version including USB support to OSE. It's GPL anyway.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.3 KB
 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Seamless Windows support
4 Copyright (C) Peter Astrand <[email protected]> 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
33extern BOOL g_seamless_rdp;
34static VCHANNEL *seamless_channel;
35static unsigned int seamless_serial;
36
37static char *
38seamless_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
61static BOOL
62seamless_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
303static BOOL
304seamless_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
314static void
315seamless_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
336BOOL
337seamless_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
351static unsigned int
352seamless_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
390unsigned int
391seamless_send_sync()
392{
393 if (!g_seamless_rdp)
394 return (unsigned int) -1;
395
396 return seamless_send("SYNC", "");
397}
398
399
400unsigned int
401seamless_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
410unsigned int
411seamless_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 */
419void
420seamless_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
435unsigned int
436seamless_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
446unsigned int
447seamless_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}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette