/[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

Diff of /sourceforge.net/trunk/seamlessrdp/ServerExe/main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1074 by ossman_, Thu Mar 9 13:24:35 2006 UTC revision 1153 by ossman_, Fri Mar 17 09:55:35 2006 UTC
# Line 24  Line 24 
24    
25  #include <windows.h>  #include <windows.h>
26  #include <stdio.h>  #include <stdio.h>
27    #include <wtsapi32.h>
28    #include <cchannel.h>
29    
30  #include "vchannel.h"  #include "vchannel.h"
31    
# Line 31  Line 33 
33    
34  #define APP_NAME "SeamlessRDP Shell"  #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 */  /* Global data */
47  static HINSTANCE g_instance;  static HINSTANCE g_instance;
48    static HWND g_hwnd;
49    
50  typedef void (*set_hooks_proc_t) ();  typedef void (*set_hooks_proc_t) ();
51  typedef void (*remove_hooks_proc_t) ();  typedef void (*remove_hooks_proc_t) ();
52  typedef int (*get_instance_count_proc_t) ();  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  static void
59  message(const char *text)  message(const char *text)
60  {  {
61          MessageBox(GetDesktopWindow(), text, "SeamlessRDP Shell", MB_OK);          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    /*      if (!AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(hwnd, NULL), TRUE))
179            {
180                    debug("Failed to attach");
181                    return;
182            }
183            SetFocus(hwnd);
184            AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(hwnd, NULL), FALSE)*/
185            SendMessage(hwnd, g_wm_seamless_focus, 0, 0);
186    }
187    
188  static void  static void
189  process_cmds(void)  process_cmds(void)
190  {  {
191          char line[VCHANNEL_MAX_LINE];          char line[VCHANNEL_MAX_LINE];
192          int size;          int size;
193    
194          while ((size = vchannel_read(line, sizeof(line))) >= 0) {          char *p, *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
195                  debug("Got: %s", line);  
196            while ((size = vchannel_read(line, sizeof(line))) >= 0)
197            {
198                    p = line;
199    
200                    tok1 = get_token(&p);
201                    tok2 = get_token(&p);
202                    tok3 = get_token(&p);
203                    tok4 = get_token(&p);
204                    tok5 = get_token(&p);
205                    tok6 = get_token(&p);
206                    tok7 = get_token(&p);
207                    tok8 = get_token(&p);
208    
209                    if (strcmp(tok1, "SYNC") == 0)
210                            do_sync();
211                    else if (strcmp(tok1, "STATE") == 0)
212                            do_state((HWND) strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0));
213                    else if (strcmp(tok1, "POSITION") == 0)
214                            do_position((HWND) strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0),
215                                        strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL,
216                                                                                             0));
217                    else if (strcmp(tok1, "ZCHANGE") == 0)
218                            do_zchange((HWND) strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0));
219                    else if (strcmp(tok1, "FOCUS") == 0)
220                            do_focus((HWND) strtoul(tok2, NULL, 0));
221          }          }
222  }  }
223    
224    static LRESULT CALLBACK
225    wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
226    {
227            if (message == WM_WTSSESSION_CHANGE)
228            {
229                    if (wparam == WTS_REMOTE_CONNECT)
230                    {
231                            /* These get reset on each reconnect */
232                            SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
233                            SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
234                            vchannel_write("HELLO,0x%08x", 1);
235                    }
236            }
237    
238            return DefWindowProc(hwnd, message, wparam, lparam);
239    }
240    
241    static BOOL
242    register_class(void)
243    {
244            WNDCLASSEX wcx;
245    
246            memset(&wcx, 0, sizeof(wcx));
247    
248            wcx.cbSize = sizeof(wcx);
249            wcx.lpfnWndProc = wndproc;
250            wcx.hInstance = g_instance;
251            wcx.lpszClassName = "SeamlessClass";
252    
253            return RegisterClassEx(&wcx);
254    }
255    
256    static BOOL
257    create_wnd(void)
258    {
259            if (!register_class())
260                    return FALSE;
261    
262            g_hwnd = CreateWindow("SeamlessClass",
263                                  "Seamless Window",
264                                  WS_OVERLAPPEDWINDOW,
265                                  CW_USEDEFAULT,
266                                  CW_USEDEFAULT,
267                                  CW_USEDEFAULT,
268                                  CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL, g_instance, (LPVOID) NULL);
269    
270            if (!g_hwnd)
271                    return FALSE;
272    
273            return TRUE;
274    }
275    
276  int WINAPI  int WINAPI
277  WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)  WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
278  {  {
# Line 66  WinMain(HINSTANCE instance, HINSTANCE pr Line 284  WinMain(HINSTANCE instance, HINSTANCE pr
284    
285          g_instance = instance;          g_instance = instance;
286    
287          hookdll = LoadLibrary("hookdll.dll");          hookdll = LoadLibrary("seamlessrdp.dll");
288          if (!hookdll)          if (!hookdll)
289          {          {
290                  message("Could not load hook DLL. Unable to continue.");                  message("Could not load hook DLL. Unable to continue.");
# Line 76  WinMain(HINSTANCE instance, HINSTANCE pr Line 294  WinMain(HINSTANCE instance, HINSTANCE pr
294          set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");          set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
295          remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");          remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
296          instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");          instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
297            g_move_window_fn = (move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow");
298    
299          if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn)          if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn || !g_move_window_fn)
300          {          {
301                  FreeLibrary(hookdll);                  FreeLibrary(hookdll);
302                  message("Hook DLL doesn't contain the correct functions. Unable to continue.");                  message("Hook DLL doesn't contain the correct functions. Unable to continue.");
# Line 92  WinMain(HINSTANCE instance, HINSTANCE pr Line 311  WinMain(HINSTANCE instance, HINSTANCE pr
311                  return -1;                  return -1;
312          }          }
313    
314            if (!create_wnd())
315            {
316                    FreeLibrary(hookdll);
317                    message("Couldn't create a window to catch events.");
318                    return -1;
319            }
320    
321            g_wm_seamless_focus = RegisterWindowMessage(FOCUS_MSG_NAME);
322    
323            WTSRegisterSessionNotification(g_hwnd, NOTIFY_FOR_THIS_SESSION);
324    
325          vchannel_open();          vchannel_open();
326    
327            vchannel_write("HELLO,0x%08x", 0);
328    
329          set_hooks_fn();          set_hooks_fn();
330    
331            /* Since we don't see the entire desktop we must resize windows
332               immediatly. */
333            SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
334    
335            /* Disable screen saver since we cannot catch its windows. */
336            SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
337    
338          if (strlen(cmdline) == 0)          if (strlen(cmdline) == 0)
339          {          {
340                  message("No command line specified.");                  message("No command line specified.");
# Line 107  WinMain(HINSTANCE instance, HINSTANCE pr Line 346  WinMain(HINSTANCE instance, HINSTANCE pr
346                  DWORD exitcode;                  DWORD exitcode;
347                  PROCESS_INFORMATION proc_info;                  PROCESS_INFORMATION proc_info;
348                  STARTUPINFO startup_info;                  STARTUPINFO startup_info;
349                    MSG msg;
350    
351                  memset(&startup_info, 0, sizeof(STARTUPINFO));                  memset(&startup_info, 0, sizeof(STARTUPINFO));
352                  startup_info.cb = sizeof(STARTUPINFO);                  startup_info.cb = sizeof(STARTUPINFO);
# Line 118  WinMain(HINSTANCE instance, HINSTANCE pr Line 358  WinMain(HINSTANCE instance, HINSTANCE pr
358                  {                  {
359                          do                          do
360                          {                          {
361                                    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
362                                    {
363                                            TranslateMessage(&msg);
364                                            DispatchMessage(&msg);
365                                    }
366                                  process_cmds();                                  process_cmds();
367                                  Sleep(100);                                  Sleep(100);
368                                  GetExitCodeProcess(proc_info.hProcess, &exitcode);                                  GetExitCodeProcess(proc_info.hProcess, &exitcode);
# Line 138  WinMain(HINSTANCE instance, HINSTANCE pr Line 383  WinMain(HINSTANCE instance, HINSTANCE pr
383                  }                  }
384          }          }
385    
386            WTSUnRegisterSessionNotification(g_hwnd);
387    
388          remove_hooks_fn();          remove_hooks_fn();
389    
390          FreeLibrary(hookdll);          FreeLibrary(hookdll);

Legend:
Removed from v.1074  
changed lines
  Added in v.1153

  ViewVC Help
Powered by ViewVC 1.1.26