ReactOS 0.4.15-dev-7907-g95bf896
seamless.c
Go to the documentation of this file.
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 along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
33static char *
35{
36 char *comma, *head;
37 head = *s;
38
39 if (!head)
40 return NULL;
41
42 comma = strchr(head, ',');
43 if (comma)
44 {
45 *comma = '\0';
46 *s = comma + 1;
47 }
48 else
49 {
50 *s = NULL;
51 }
52
53 return head;
54}
55
56
57static BOOL
59{
60 char *p, *l;
61 char *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
62 unsigned long id, flags;
63 char *endptr;
64
65 l = xstrdup(line);
66 p = l;
67
68 DEBUG_SEAMLESS(("seamlessrdp got:%s\n", p));
69
70 tok1 = seamless_get_token(&p);
71 tok2 = seamless_get_token(&p);
72 tok3 = seamless_get_token(&p);
73 tok4 = seamless_get_token(&p);
74 tok5 = seamless_get_token(&p);
75 tok6 = seamless_get_token(&p);
76 tok7 = seamless_get_token(&p);
77 tok8 = seamless_get_token(&p);
78
79 if (!strcmp("CREATE", tok1))
80 {
81 unsigned long group, parent;
82 if (!tok6)
83 return False;
84
85 id = strtoul(tok3, &endptr, 0);
86 if (*endptr)
87 return False;
88
89 group = strtoul(tok4, &endptr, 0);
90 if (*endptr)
91 return False;
92
93 parent = strtoul(tok5, &endptr, 0);
94 if (*endptr)
95 return False;
96
97 flags = strtoul(tok6, &endptr, 0);
98 if (*endptr)
99 return False;
100
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
117
118 }
119 else if (!strcmp("DESTROYGRP", tok1))
120 {
121 if (!tok4)
122 return False;
123
124 id = strtoul(tok3, &endptr, 0);
125 if (*endptr)
126 return False;
127
128 flags = strtoul(tok4, &endptr, 0);
129 if (*endptr)
130 return False;
131
133 }
134 else if (!strcmp("SETICON", tok1))
135 {
136 unimpl("SeamlessRDP SETICON1\n");
137 }
138 else if (!strcmp("POSITION", tok1))
139 {
140 int x, y, width, height;
141
142 if (!tok8)
143 return False;
144
145 id = strtoul(tok3, &endptr, 0);
146 if (*endptr)
147 return False;
148
149 x = strtol(tok4, &endptr, 0);
150 if (*endptr)
151 return False;
152 y = strtol(tok5, &endptr, 0);
153 if (*endptr)
154 return False;
155
156 width = strtol(tok6, &endptr, 0);
157 if (*endptr)
158 return False;
159 height = strtol(tok7, &endptr, 0);
160 if (*endptr)
161 return False;
162
163 flags = strtoul(tok8, &endptr, 0);
164 if (*endptr)
165 return False;
166
168 }
169 else if (!strcmp("ZCHANGE", tok1))
170 {
171 unsigned long behind;
172
173 id = strtoul(tok3, &endptr, 0);
174 if (*endptr)
175 return False;
176
177 behind = strtoul(tok4, &endptr, 0);
178 if (*endptr)
179 return False;
180
181 flags = strtoul(tok5, &endptr, 0);
182 if (*endptr)
183 return False;
184
186 }
187 else if (!strcmp("TITLE", tok1))
188 {
189 if (!tok5)
190 return False;
191
192 id = strtoul(tok3, &endptr, 0);
193 if (*endptr)
194 return False;
195
196 flags = strtoul(tok5, &endptr, 0);
197 if (*endptr)
198 return False;
199
200 ui_seamless_settitle(This, id, tok4, flags);
201 }
202 else if (!strcmp("STATE", tok1))
203 {
204 unsigned int state;
205
206 if (!tok5)
207 return False;
208
209 id = strtoul(tok3, &endptr, 0);
210 if (*endptr)
211 return False;
212
213 state = strtoul(tok4, &endptr, 0);
214 if (*endptr)
215 return False;
216
217 flags = strtoul(tok5, &endptr, 0);
218 if (*endptr)
219 return False;
220
222 }
223 else if (!strcmp("DEBUG", tok1))
224 {
225 DEBUG_SEAMLESS(("SeamlessRDP:%s\n", line));
226 }
227 else if (!strcmp("SYNCBEGIN", tok1))
228 {
229 if (!tok3)
230 return False;
231
232 flags = strtoul(tok3, &endptr, 0);
233 if (*endptr)
234 return False;
235
237 }
238 else if (!strcmp("SYNCEND", tok1))
239 {
240 if (!tok3)
241 return False;
242
243 flags = strtoul(tok3, &endptr, 0);
244 if (*endptr)
245 return False;
246
247 /* do nothing, currently */
248 }
249 else if (!strcmp("HELLO", tok1))
250 {
251 if (!tok3)
252 return False;
253
254 flags = strtoul(tok3, &endptr, 0);
255 if (*endptr)
256 return False;
257
259 }
260 else if (!strcmp("ACK", tok1))
261 {
262 unsigned int serial;
263
264 serial = strtoul(tok3, &endptr, 0);
265 if (*endptr)
266 return False;
267
269 }
270 else if (!strcmp("HIDE", tok1))
271 {
272 if (!tok3)
273 return False;
274
275 flags = strtoul(tok3, &endptr, 0);
276 if (*endptr)
277 return False;
278
280 }
281 else if (!strcmp("UNHIDE", tok1))
282 {
283 if (!tok3)
284 return False;
285
286 flags = strtoul(tok3, &endptr, 0);
287 if (*endptr)
288 return False;
289
291 }
292
293
294 xfree(l);
295 return True;
296}
297
298
299static BOOL
301{
303 {
304 warning("SeamlessRDP: Invalid request:%s\n", line);
305 }
306 return True;
307}
308
309
310static void
312{
313 unsigned int pkglen;
314 static char *rest = NULL;
315 char *buf;
316
317 pkglen = s->end - s->p;
318 /* str_handle_lines requires null terminated strings */
319 buf = xmalloc(pkglen + 1);
320 STRNCPY(buf, (char *) s->p, pkglen + 1);
321#if 0
322 printf("seamless recv:\n");
323 hexdump(s->p, pkglen);
324#endif
325
327
328 xfree(buf);
329}
330
331
332BOOL
334{
335 if (!This->seamless_rdp)
336 return False;
337
338 This->seamless.serial = 0;
339
340 This->seamless.channel =
343 return (This->seamless.channel != NULL);
344}
345
346
347static unsigned int
348seamless_send(RDPCLIENT * This, const char *command, const char *format, ...)
349{
350 STREAM s;
351 size_t len;
352 va_list argp;
353 char buf[1025];
354
355 len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, This->seamless.serial);
356
357 assert(len < (sizeof(buf) - 1));
358
359 va_start(argp, format);
360 len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
361 va_end(argp);
362
363 assert(len < (sizeof(buf) - 1));
364
365 buf[len] = '\n';
366 buf[len + 1] = '\0';
367
368 len++;
369
370 s = channel_init(This, This->seamless.channel, len);
372
373 DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
374
375#if 0
376 printf("seamless send:\n");
377 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
378#endif
379
380 channel_send(This, s, This->seamless.channel);
381
382 return This->seamless.serial++;
383}
384
385
386unsigned int
388{
389 if (!This->seamless_rdp)
390 return (unsigned int) -1;
391
392 return seamless_send(This, "SYNC", "");
393}
394
395
396unsigned int
397seamless_send_state(RDPCLIENT * This, unsigned long id, unsigned int state, unsigned long flags)
398{
399 if (!This->seamless_rdp)
400 return (unsigned int) -1;
401
402 return seamless_send(This, "STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
403}
404
405
406unsigned int
407seamless_send_position(RDPCLIENT * This, unsigned long id, int x, int y, int width, int height, unsigned long flags)
408{
409 return seamless_send(This, "POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height,
410 flags);
411}
412
413
414/* Update select timeout */
415void
417{
418 struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
419
420 if (This->seamless_rdp)
421 {
422 if (timercmp(&ourtimeout, tv, <))
423 {
424 tv->tv_sec = ourtimeout.tv_sec;
425 tv->tv_usec = ourtimeout.tv_usec;
426 }
427 }
428}
429
430
431unsigned int
432seamless_send_zchange(RDPCLIENT * This, unsigned long id, unsigned long below, unsigned long flags)
433{
434 if (!This->seamless_rdp)
435 return (unsigned int) -1;
436
437 return seamless_send(This, "ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
438}
439
440
441
442unsigned int
443seamless_send_focus(RDPCLIENT * This, unsigned long id, unsigned long flags)
444{
445 if (!This->seamless_rdp)
446 return (unsigned int) -1;
447
448 return seamless_send(This, "FOCUS", "0x%08lx,0x%lx", id, flags);
449}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
struct outqueuenode * head
Definition: adnsresfilter.c:66
static int state
Definition: maze.c:121
VCHANNEL * channel_register(char *name, uint32 flags, void(*callback)(STREAM))
Definition: channels.c:46
STREAM channel_init(VCHANNEL *channel, uint32 length)
Definition: channels.c:69
void channel_send(STREAM s, VCHANNEL *channel)
Definition: channels.c:79
#define SEAMLESSRDP_POSITION_TIMER
Definition: constants.h:570
#define CHANNEL_OPTION_ENCRYPT_RDP
Definition: constants.h:432
#define CHANNEL_OPTION_INITIALIZED
Definition: constants.h:431
#define SEAMLESSRDP_HELLO_HIDDEN
Definition: constants.h:576
#define s_mark_end(s)
Definition: parse.h:41
#define out_uint8p(s, v, n)
Definition: parse.h:93
void xfree(void *mem)
Definition: uimain.c:758
void ui_seamless_destroy_window(unsigned long id, unsigned long flags)
void ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent, unsigned long flags)
void ui_seamless_hide_desktop(void)
RD_BOOL seamless_init(void)
char * xstrdup(const char *s)
Definition: uimain.c:768
void ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
void ui_seamless_unhide_desktop(void)
void ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
void unimpl(char *format,...)
Definition: uimain.c:801
RD_BOOL str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
void ui_seamless_destroy_group(unsigned long id, unsigned long flags)
void ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long flags)
unsigned int seamless_send_sync(void)
void ui_seamless_ack(unsigned int serial)
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
void ui_seamless_begin(RD_BOOL hidden)
void * xmalloc(int size)
Definition: uimain.c:747
void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)
void ui_seamless_syncbegin(unsigned long flags)
#define timercmp(tvp, uvp, cmp)
Definition: rdesktop.h:184
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
#define False
Definition: types.h:25
#define True
Definition: types.h:24
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
#define assert(x)
Definition: debug.h:53
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
#define printf
Definition: freeldr.h:93
uint32_t serial
Definition: fsck.fat.h:29
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLboolean GLuint group
Definition: glext.h:11120
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define warning(s)
Definition: debug.h:83
unsigned int seamless_send_position(RDPCLIENT *This, unsigned long id, int x, int y, int width, int height, unsigned long flags)
Definition: seamless.c:407
static BOOL seamless_process_line(RDPCLIENT *This, const char *line, void *data)
Definition: seamless.c:58
#define DEBUG_SEAMLESS(args)
Definition: seamless.c:30
unsigned int seamless_send_focus(RDPCLIENT *This, unsigned long id, unsigned long flags)
Definition: seamless.c:443
unsigned int seamless_send_zchange(RDPCLIENT *This, unsigned long id, unsigned long below, unsigned long flags)
Definition: seamless.c:432
static BOOL seamless_line_handler(RDPCLIENT *This, const char *line, void *data)
Definition: seamless.c:300
static char * seamless_get_token(char **s)
Definition: seamless.c:34
unsigned int seamless_send_state(RDPCLIENT *This, unsigned long id, unsigned int state, unsigned long flags)
Definition: seamless.c:397
static unsigned int seamless_send(RDPCLIENT *This, const char *command, const char *format,...)
Definition: seamless.c:348
void seamless_select_timeout(RDPCLIENT *This, struct timeval *tv)
Definition: seamless.c:416
static void seamless_process(RDPCLIENT *This, STREAM s)
Definition: seamless.c:311
Definition: parser.c:49
Definition: parse.h:23
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739
#define vsnprintf
Definition: tif_win32.c:406
#define snprintf
Definition: wintirpc.h:48