/[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 1157 - (show annotations)
Fri Mar 17 12:39:09 2006 UTC (18 years, 2 months ago) by astrand
File MIME type: text/plain
File size: 7068 byte(s)
Send back our local positions upon changes, but only after a small timeout.

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

  ViewVC Help
Powered by ViewVC 1.1.26