/[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 1177 - (show annotations)
Tue Mar 21 14:42:25 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 7824 byte(s)
Support for window groups and modal windows.

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 printf("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();
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
260
261 xfree(l);
262 return True;
263 }
264
265
266 static BOOL
267 seamless_line_handler(const char *line, void *data)
268 {
269 if (!seamless_process_line(line, data))
270 {
271 warning("SeamlessRDP: Invalid request:%s\n", line);
272 }
273 return True;
274 }
275
276
277 static void
278 seamless_process(STREAM s)
279 {
280 unsigned int pkglen;
281 static char *rest = NULL;
282 char *buf;
283
284 pkglen = s->end - s->p;
285 /* str_handle_lines requires null terminated strings */
286 buf = xmalloc(pkglen + 1);
287 STRNCPY(buf, (char *) s->p, pkglen + 1);
288 #if 0
289 printf("seamless recv:\n");
290 hexdump(s->p, pkglen);
291 #endif
292
293 str_handle_lines(buf, &rest, seamless_line_handler, NULL);
294
295 xfree(buf);
296 }
297
298
299 BOOL
300 seamless_init(void)
301 {
302 if (!g_seamless_rdp)
303 return False;
304
305 seamless_serial = 0;
306
307 seamless_channel =
308 channel_register("seamrdp", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
309 seamless_process);
310 return (seamless_channel != NULL);
311 }
312
313
314 static unsigned int
315 seamless_send(const char *command, const char *format, ...)
316 {
317 STREAM s;
318 size_t len;
319 va_list argp;
320 char buf[1025];
321
322 len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
323
324 assert(len < (sizeof(buf) - 1));
325
326 va_start(argp, format);
327 len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
328 va_end(argp);
329
330 assert(len < (sizeof(buf) - 1));
331
332 buf[len] = '\n';
333 buf[len + 1] = '\0';
334
335 len++;
336
337 s = channel_init(seamless_channel, len);
338 out_uint8p(s, buf, len) s_mark_end(s);
339
340 DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
341
342 #if 0
343 printf("seamless send:\n");
344 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
345 #endif
346
347 channel_send(s, seamless_channel);
348
349 return seamless_serial++;
350 }
351
352
353 unsigned int
354 seamless_send_sync()
355 {
356 if (!g_seamless_rdp)
357 return (unsigned int) -1;
358
359 return seamless_send("SYNC", "");
360 }
361
362
363 unsigned int
364 seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
365 {
366 if (!g_seamless_rdp)
367 return (unsigned int) -1;
368
369 return seamless_send("STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
370 }
371
372
373 unsigned int
374 seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
375 {
376 return seamless_send("POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height,
377 flags);
378 }
379
380
381 /* Update select timeout */
382 void
383 seamless_select_timeout(struct timeval *tv)
384 {
385 struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
386
387 if (g_seamless_rdp)
388 {
389 if (timercmp(&ourtimeout, tv, <))
390 {
391 tv->tv_sec = ourtimeout.tv_sec;
392 tv->tv_usec = ourtimeout.tv_usec;
393 }
394 }
395 }
396
397
398 unsigned int
399 seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
400 {
401 if (!g_seamless_rdp)
402 return (unsigned int) -1;
403
404 return seamless_send("ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
405 }
406
407
408
409 unsigned int
410 seamless_send_focus(unsigned long id, unsigned long flags)
411 {
412 if (!g_seamless_rdp)
413 return (unsigned int) -1;
414
415 return seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags);
416 }

  ViewVC Help
Powered by ViewVC 1.1.26