/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/seamless.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1163 - (show annotations)
Mon Mar 20 10:31:58 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 7399 byte(s)
Add serial numbers to protocol.

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 parent;
86 if (!tok5)
87 return False;
88
89 id = strtoul(tok3, &endptr, 0);
90 if (*endptr)
91 return False;
92
93 parent = strtoul(tok4, &endptr, 0);
94 if (*endptr)
95 return False;
96
97 flags = strtoul(tok5, &endptr, 0);
98 if (*endptr)
99 return False;
100
101 ui_seamless_create_window(id, parent, flags);
102 }
103 else if (!strcmp("DESTROY", tok1))
104 {
105 if (!tok4)
106 return False;
107
108 id = strtoul(tok3, &endptr, 0);
109 if (*endptr)
110 return False;
111
112 flags = strtoul(tok4, &endptr, 0);
113 if (*endptr)
114 return False;
115
116 ui_seamless_destroy_window(id, flags);
117
118 }
119 else if (!strcmp("SETICON", tok1))
120 {
121 unimpl("SeamlessRDP SETICON1\n");
122 }
123 else if (!strcmp("POSITION", tok1))
124 {
125 int x, y, width, height;
126
127 if (!tok8)
128 return False;
129
130 id = strtoul(tok3, &endptr, 0);
131 if (*endptr)
132 return False;
133
134 x = strtol(tok4, &endptr, 0);
135 if (*endptr)
136 return False;
137 y = strtol(tok5, &endptr, 0);
138 if (*endptr)
139 return False;
140
141 width = strtol(tok6, &endptr, 0);
142 if (*endptr)
143 return False;
144 height = strtol(tok7, &endptr, 0);
145 if (*endptr)
146 return False;
147
148 flags = strtoul(tok8, &endptr, 0);
149 if (*endptr)
150 return False;
151
152 ui_seamless_move_window(id, x, y, width, height, flags);
153 }
154 else if (!strcmp("ZCHANGE", tok1))
155 {
156 unsigned long behind;
157
158 id = strtoul(tok3, &endptr, 0);
159 if (*endptr)
160 return False;
161
162 behind = strtoul(tok4, &endptr, 0);
163 if (*endptr)
164 return False;
165
166 flags = strtoul(tok5, &endptr, 0);
167 if (*endptr)
168 return False;
169
170 ui_seamless_restack_window(id, behind, flags);
171 }
172 else if (!strcmp("TITLE", tok1))
173 {
174 if (!tok5)
175 return False;
176
177 id = strtoul(tok3, &endptr, 0);
178 if (*endptr)
179 return False;
180
181 flags = strtoul(tok5, &endptr, 0);
182 if (*endptr)
183 return False;
184
185 ui_seamless_settitle(id, tok4, flags);
186 }
187 else if (!strcmp("STATE", tok1))
188 {
189 unsigned int state;
190
191 if (!tok5)
192 return False;
193
194 id = strtoul(tok3, &endptr, 0);
195 if (*endptr)
196 return False;
197
198 state = strtoul(tok4, &endptr, 0);
199 if (*endptr)
200 return False;
201
202 flags = strtoul(tok5, &endptr, 0);
203 if (*endptr)
204 return False;
205
206 ui_seamless_setstate(id, state, flags);
207 }
208 else if (!strcmp("DEBUG", tok1))
209 {
210 printf("SeamlessRDP:%s\n", line);
211 }
212 else if (!strcmp("SYNCBEGIN", tok1))
213 {
214 if (!tok3)
215 return False;
216
217 flags = strtoul(tok3, &endptr, 0);
218 if (*endptr)
219 return False;
220
221 ui_seamless_syncbegin(flags);
222 }
223 else if (!strcmp("SYNCEND", tok1))
224 {
225 if (!tok3)
226 return False;
227
228 flags = strtoul(tok3, &endptr, 0);
229 if (*endptr)
230 return False;
231
232 /* do nothing, currently */
233 }
234 else if (!strcmp("HELLO", tok1))
235 {
236 if (!tok3)
237 return False;
238
239 flags = strtoul(tok3, &endptr, 0);
240 if (*endptr)
241 return False;
242
243 ui_seamless_begin();
244 }
245
246
247 xfree(l);
248 return True;
249 }
250
251
252 static BOOL
253 seamless_line_handler(const char *line, void *data)
254 {
255 if (!seamless_process_line(line, data))
256 {
257 warning("SeamlessRDP: Invalid request:%s\n", line);
258 }
259 return True;
260 }
261
262
263 static void
264 seamless_process(STREAM s)
265 {
266 unsigned int pkglen;
267 static char *rest = NULL;
268 char *buf;
269
270 pkglen = s->end - s->p;
271 /* str_handle_lines requires null terminated strings */
272 buf = xmalloc(pkglen + 1);
273 STRNCPY(buf, (char *) s->p, pkglen + 1);
274 #if 0
275 printf("seamless recv:\n");
276 hexdump(s->p, pkglen);
277 #endif
278
279 str_handle_lines(buf, &rest, seamless_line_handler, NULL);
280
281 xfree(buf);
282 }
283
284
285 BOOL
286 seamless_init(void)
287 {
288 if (!g_seamless_rdp)
289 return False;
290
291 seamless_serial = 0;
292
293 seamless_channel =
294 channel_register("seamrdp", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
295 seamless_process);
296 return (seamless_channel != NULL);
297 }
298
299
300 static void
301 seamless_send(const char *command, const char *format, ...)
302 {
303 STREAM s;
304 size_t len;
305 va_list argp;
306 char buf[1025];
307
308 len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
309
310 assert(len < (sizeof(buf) - 1));
311
312 va_start(argp, format);
313 len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
314 va_end(argp);
315
316 assert(len < (sizeof(buf) - 1));
317
318 buf[len] = '\n';
319 buf[len + 1] = '\0';
320
321 s = channel_init(seamless_channel, len);
322 out_uint8p(s, buf, len) s_mark_end(s);
323
324 seamless_serial++;
325
326 DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
327
328 #if 0
329 printf("seamless send:\n");
330 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
331 #endif
332
333 channel_send(s, seamless_channel);
334 }
335
336
337 void
338 seamless_send_sync()
339 {
340 if (!g_seamless_rdp)
341 return;
342
343 seamless_send("SYNC", "");
344 }
345
346
347 void
348 seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
349 {
350 if (!g_seamless_rdp)
351 return;
352
353 seamless_send("STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
354 }
355
356
357 void
358 seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
359 {
360 seamless_send("POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height, flags);
361 }
362
363
364 /* Update select timeout */
365 void
366 seamless_select_timeout(struct timeval *tv)
367 {
368 struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
369
370 if (g_seamless_rdp)
371 {
372 if (timercmp(&ourtimeout, tv, <))
373 {
374 tv->tv_sec = ourtimeout.tv_sec;
375 tv->tv_usec = ourtimeout.tv_usec;
376 }
377 }
378 }
379
380 void
381 seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
382 {
383 if (!g_seamless_rdp)
384 return;
385
386 seamless_send("ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
387 }
388
389
390 void
391 seamless_send_focus(unsigned long id, unsigned long flags)
392 {
393 if (!g_seamless_rdp)
394 return;
395
396 seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags);
397 }

  ViewVC Help
Powered by ViewVC 1.1.26