/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/main.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/trunk/seamlessrdp/ServerExe/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1156 - (show annotations)
Fri Mar 17 10:48:55 2006 UTC (18 years, 1 month ago) by ossman_
File MIME type: text/plain
File size: 8634 byte(s)
Remove some commented code that never should have been checked in.

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Seamless windows - Remote server executable
4
5 Based on code copyright (C) 2004-2005 Martin Wickett
6
7 Copyright (C) Peter Åstrand <astrand@cendio.se> 2005-2006
8 Copyright (C) Pierre Ossman <ossman@cendio.se> 2006
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include <windows.h>
26 #include <stdio.h>
27 #include <wtsapi32.h>
28 #include <cchannel.h>
29
30 #include "vchannel.h"
31
32 #include "resource.h"
33
34 #define APP_NAME "SeamlessRDP Shell"
35
36 #define FOCUS_MSG_NAME "WM_SEAMLESS_FOCUS"
37 static UINT g_wm_seamless_focus;
38
39 #ifndef WM_WTSSESSION_CHANGE
40 #define WM_WTSSESSION_CHANGE 0x02B1
41 #endif
42 #ifndef WTS_REMOTE_CONNECT
43 #define WTS_REMOTE_CONNECT 0x3
44 #endif
45
46 /* Global data */
47 static HINSTANCE g_instance;
48 static HWND g_hwnd;
49
50 typedef void (*set_hooks_proc_t) ();
51 typedef void (*remove_hooks_proc_t) ();
52 typedef int (*get_instance_count_proc_t) ();
53
54 typedef void (*move_window_proc_t) (HWND hwnd, int x, int y, int width, int height);
55
56 static move_window_proc_t g_move_window_fn = NULL;
57
58 static void
59 message(const char *text)
60 {
61 MessageBox(GetDesktopWindow(), text, "SeamlessRDP Shell", MB_OK);
62 }
63
64 static char *
65 get_token(char **s)
66 {
67 char *comma, *head;
68 head = *s;
69
70 if (!head)
71 return NULL;
72
73 comma = strchr(head, ',');
74 if (comma)
75 {
76 *comma = '\0';
77 *s = comma + 1;
78 }
79 else
80 {
81 *s = NULL;
82 }
83
84 return head;
85 }
86
87 static BOOL CALLBACK
88 enum_cb(HWND hwnd, LPARAM lparam)
89 {
90 RECT rect;
91 unsigned short title[150];
92 LONG styles;
93 int state;
94 HWND parent;
95
96 styles = GetWindowLong(hwnd, GWL_STYLE);
97
98 if (!(styles & WS_VISIBLE))
99 return TRUE;
100
101 if (styles & WS_POPUP)
102 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
103 else
104 parent = NULL;
105
106 vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);
107
108 if (!GetWindowRect(hwnd, &rect))
109 {
110 debug("GetWindowRect failed!");
111 return TRUE;
112 }
113
114 vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",
115 hwnd,
116 rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
117
118 GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
119
120 vchannel_write("TITLE,0x%x,%s,0x%x", hwnd, vchannel_strfilter_unicode(title), 0);
121
122 if (styles & WS_MAXIMIZE)
123 state = 2;
124 else if (styles & WS_MINIMIZE)
125 state = 1;
126 else
127 state = 0;
128
129 vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);
130
131 return TRUE;
132 }
133
134 static void
135 do_sync(void)
136 {
137 vchannel_block();
138
139 vchannel_write("SYNCBEGIN,0x0");
140
141 EnumWindows(enum_cb, 0);
142
143 vchannel_write("SYNCEND,0x0");
144
145 vchannel_unblock();
146 }
147
148 static void
149 do_state(HWND hwnd, int state)
150 {
151 if (state == 0)
152 ShowWindow(hwnd, SW_RESTORE);
153 else if (state == 1)
154 ShowWindow(hwnd, SW_MINIMIZE);
155 else if (state == 2)
156 ShowWindow(hwnd, SW_MAXIMIZE);
157 else
158 debug("Invalid state %d sent.", state);
159 }
160
161 static void
162 do_position(HWND hwnd, int x, int y, int width, int height)
163 {
164 g_move_window_fn(hwnd, x, y, width, height);
165 }
166
167 static void
168 do_zchange(HWND hwnd, HWND behind)
169 {
170 if (behind == NULL)
171 behind = HWND_TOP;
172 SetWindowPos(hwnd, behind, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
173 }
174
175 static void
176 do_focus(HWND hwnd)
177 {
178 SendMessage(hwnd, g_wm_seamless_focus, 0, 0);
179 }
180
181 static void
182 process_cmds(void)
183 {
184 char line[VCHANNEL_MAX_LINE];
185 int size;
186
187 char *p, *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
188
189 while ((size = vchannel_read(line, sizeof(line))) >= 0)
190 {
191 p = line;
192
193 tok1 = get_token(&p);
194 tok2 = get_token(&p);
195 tok3 = get_token(&p);
196 tok4 = get_token(&p);
197 tok5 = get_token(&p);
198 tok6 = get_token(&p);
199 tok7 = get_token(&p);
200 tok8 = get_token(&p);
201
202 if (strcmp(tok1, "SYNC") == 0)
203 do_sync();
204 else if (strcmp(tok1, "STATE") == 0)
205 do_state((HWND) strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0));
206 else if (strcmp(tok1, "POSITION") == 0)
207 do_position((HWND) strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0),
208 strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL,
209 0));
210 else if (strcmp(tok1, "ZCHANGE") == 0)
211 do_zchange((HWND) strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0));
212 else if (strcmp(tok1, "FOCUS") == 0)
213 do_focus((HWND) strtoul(tok2, NULL, 0));
214 }
215 }
216
217 static LRESULT CALLBACK
218 wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
219 {
220 if (message == WM_WTSSESSION_CHANGE)
221 {
222 if (wparam == WTS_REMOTE_CONNECT)
223 {
224 /* These get reset on each reconnect */
225 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
226 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
227 vchannel_write("HELLO,0x%08x", 1);
228 }
229 }
230
231 return DefWindowProc(hwnd, message, wparam, lparam);
232 }
233
234 static BOOL
235 register_class(void)
236 {
237 WNDCLASSEX wcx;
238
239 memset(&wcx, 0, sizeof(wcx));
240
241 wcx.cbSize = sizeof(wcx);
242 wcx.lpfnWndProc = wndproc;
243 wcx.hInstance = g_instance;
244 wcx.lpszClassName = "SeamlessClass";
245
246 return RegisterClassEx(&wcx);
247 }
248
249 static BOOL
250 create_wnd(void)
251 {
252 if (!register_class())
253 return FALSE;
254
255 g_hwnd = CreateWindow("SeamlessClass",
256 "Seamless Window",
257 WS_OVERLAPPEDWINDOW,
258 CW_USEDEFAULT,
259 CW_USEDEFAULT,
260 CW_USEDEFAULT,
261 CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL, g_instance, (LPVOID) NULL);
262
263 if (!g_hwnd)
264 return FALSE;
265
266 return TRUE;
267 }
268
269 int WINAPI
270 WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
271 {
272 HMODULE hookdll;
273
274 set_hooks_proc_t set_hooks_fn;
275 remove_hooks_proc_t remove_hooks_fn;
276 get_instance_count_proc_t instance_count_fn;
277
278 g_instance = instance;
279
280 hookdll = LoadLibrary("seamlessrdp.dll");
281 if (!hookdll)
282 {
283 message("Could not load hook DLL. Unable to continue.");
284 return -1;
285 }
286
287 set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
288 remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
289 instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
290 g_move_window_fn = (move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow");
291
292 if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn || !g_move_window_fn)
293 {
294 FreeLibrary(hookdll);
295 message("Hook DLL doesn't contain the correct functions. Unable to continue.");
296 return -1;
297 }
298
299 /* Check if the DLL is already loaded */
300 if (instance_count_fn() != 1)
301 {
302 FreeLibrary(hookdll);
303 message("Another running instance of Seamless RDP detected.");
304 return -1;
305 }
306
307 if (!create_wnd())
308 {
309 FreeLibrary(hookdll);
310 message("Couldn't create a window to catch events.");
311 return -1;
312 }
313
314 g_wm_seamless_focus = RegisterWindowMessage(FOCUS_MSG_NAME);
315
316 WTSRegisterSessionNotification(g_hwnd, NOTIFY_FOR_THIS_SESSION);
317
318 vchannel_open();
319
320 vchannel_write("HELLO,0x%08x", 0);
321
322 set_hooks_fn();
323
324 /* Since we don't see the entire desktop we must resize windows
325 immediatly. */
326 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
327
328 /* Disable screen saver since we cannot catch its windows. */
329 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
330
331 if (strlen(cmdline) == 0)
332 {
333 message("No command line specified.");
334 return -1;
335 }
336 else
337 {
338 BOOL result;
339 DWORD exitcode;
340 PROCESS_INFORMATION proc_info;
341 STARTUPINFO startup_info;
342 MSG msg;
343
344 memset(&startup_info, 0, sizeof(STARTUPINFO));
345 startup_info.cb = sizeof(STARTUPINFO);
346
347 result = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0,
348 NULL, NULL, &startup_info, &proc_info);
349
350 if (result)
351 {
352 do
353 {
354 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
355 {
356 TranslateMessage(&msg);
357 DispatchMessage(&msg);
358 }
359 process_cmds();
360 Sleep(100);
361 GetExitCodeProcess(proc_info.hProcess, &exitcode);
362 }
363 while (exitcode == STILL_ACTIVE);
364
365 // Release handles
366 CloseHandle(proc_info.hProcess);
367 CloseHandle(proc_info.hThread);
368 }
369 else
370 {
371 // CreateProcess failed.
372 char msg[256];
373 _snprintf(msg, sizeof(msg),
374 "Unable to launch the requested application:\n%s", cmdline);
375 message(msg);
376 }
377 }
378
379 WTSUnRegisterSessionNotification(g_hwnd);
380
381 remove_hooks_fn();
382
383 FreeLibrary(hookdll);
384
385 vchannel_close();
386
387 return 1;
388 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26