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

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

revision 1160 by ossman_, Fri Mar 17 16:23:08 2006 UTC revision 1412 by ossman_, Mon Jun 18 11:59:38 2007 UTC
# Line 4  Line 4 
4    
5     Based on code copyright (C) 2004-2005 Martin Wickett     Based on code copyright (C) 2004-2005 Martin Wickett
6    
7     Copyright (C) Peter Åstrand <astrand@cendio.se> 2005-2006     Copyright 2005-2006 Peter Åstrand <astrand@cendio.se> for Cendio AB
8     Copyright (C) Pierre Ossman <ossman@cendio.se> 2006     Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
9    
10     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 22  Line 22 
22     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */  */
24    
25    #include <assert.h>
26  #include <stdio.h>  #include <stdio.h>
27  #include <stdarg.h>  #include <stdarg.h>
28    
# Line 45  Line 46 
46  int g_instance_count SHARED = 0;  int g_instance_count SHARED = 0;
47    
48  // blocks for locally generated events  // blocks for locally generated events
49    HWND g_block_move_hwnd SHARED = NULL;
50    unsigned int g_block_move_serial SHARED = 0;
51  RECT g_block_move SHARED = { 0, 0, 0, 0 };  RECT g_block_move SHARED = { 0, 0, 0, 0 };
52    
53    unsigned int g_blocked_zchange_serial SHARED = 0;
54  HWND g_blocked_zchange[2] SHARED = { NULL, NULL };  HWND g_blocked_zchange[2] SHARED = { NULL, NULL };
55    
56    unsigned int g_blocked_focus_serial SHARED = 0;
57  HWND g_blocked_focus SHARED = NULL;  HWND g_blocked_focus SHARED = NULL;
58    
59    unsigned int g_blocked_state_serial SHARED = 0;
60    HWND g_blocked_state_hwnd SHARED = NULL;
61  int g_blocked_state SHARED = -1;  int g_blocked_state SHARED = -1;
62    
63  #pragma data_seg ()  #pragma data_seg ()
# Line 69  static void Line 79  static void
79  update_position(HWND hwnd)  update_position(HWND hwnd)
80  {  {
81          RECT rect, blocked;          RECT rect, blocked;
82            HWND blocked_hwnd;
83            unsigned int serial;
84    
85            WaitForSingleObject(g_mutex, INFINITE);
86            blocked_hwnd = g_block_move_hwnd;
87            serial = g_block_move_serial;
88            memcpy(&blocked, &g_block_move, sizeof(RECT));
89            ReleaseMutex(g_mutex);
90    
91            vchannel_block();
92    
93          if (!GetWindowRect(hwnd, &rect))          if (!GetWindowRect(hwnd, &rect))
94          {          {
95                  debug("GetWindowRect failed!\n");                  debug("GetWindowRect failed!\n");
96                  return;                  goto end;
97          }          }
98    
99            if ((hwnd == blocked_hwnd) && (rect.left == blocked.left) && (rect.top == blocked.top)
100                && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))
101                    goto end;
102    
103            vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x",
104                           hwnd,
105                           rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
106    
107          end:
108            vchannel_unblock();
109    }
110    
111    static void
112    update_zorder(HWND hwnd)
113    {
114            HWND behind;
115            HWND block_hwnd, block_behind;
116            unsigned int serial;
117    
118          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
119          memcpy(&blocked, &g_block_move, sizeof(RECT));          serial = g_blocked_zchange_serial;
120            block_hwnd = g_blocked_zchange[0];
121            block_behind = g_blocked_zchange[1];
122          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
123    
124          if ((rect.left == blocked.left) && (rect.top == blocked.top)          vchannel_block();
125              && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))  
126            behind = GetNextWindow(hwnd, GW_HWNDPREV);
127            while (behind)
128            {
129                    LONG style;
130    
131                    style = GetWindowLong(behind, GWL_STYLE);
132    
133                    if ((!(style & WS_CHILD) || (style & WS_POPUP)) && (style & WS_VISIBLE))
134                            break;
135    
136                    behind = GetNextWindow(behind, GW_HWNDPREV);
137            }
138    
139            if ((hwnd == block_hwnd) && (behind == block_behind))
140                    vchannel_write("ACK", "%u", serial);
141            else
142                    vchannel_write("ZCHANGE", "0x%08lx,0x%08lx,0x%08x", hwnd, behind, 0);
143    
144            vchannel_unblock();
145    }
146    
147    static HWND
148    get_parent(HWND hwnd)
149    {
150            LONG style;
151            HWND parent;
152    
153            style = GetWindowLong(hwnd, GWL_STYLE);
154    
155            if (style & (WS_POPUP | DS_MODALFRAME))
156            {
157                    parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
158    
159                    if (parent)
160                    {
161                            style = GetWindowLong(parent, GWL_STYLE);
162                            if (((style & WS_CHILD) && !(style & WS_POPUP)) || !(style & WS_VISIBLE))
163                                    parent = NULL;
164                    }
165    
166                    if (!parent)
167                            parent = GetWindow(hwnd, GW_OWNER);
168    
169                    if (parent)
170                    {
171                            style = GetWindowLong(parent, GWL_STYLE);
172                            if (((style & WS_CHILD) && !(style & WS_POPUP)) || !(style & WS_VISIBLE))
173                                    parent = NULL;
174                    }
175    
176                    if (!parent)
177                            parent = (HWND) - 1;
178            }
179            else
180                    parent = NULL;
181    
182            return parent;
183    }
184    
185    static HICON
186    get_icon(HWND hwnd, int large)
187    {
188            HICON icon;
189    
190            if (!SendMessageTimeout(hwnd, WM_GETICON, large ? ICON_BIG : ICON_SMALL,
191                                    0, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR) & icon))
192                    return NULL;
193    
194            if (icon)
195                    return icon;
196    
197            /*
198             * Modern versions of Windows uses the voodoo value of 2 instead of 0
199             * for the small icons.
200             */
201            if (!large)
202            {
203                    if (!SendMessageTimeout(hwnd, WM_GETICON, 2,
204                                            0, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR) & icon))
205                            return NULL;
206            }
207    
208            if (icon)
209                    return icon;
210    
211            icon = (HICON) GetClassLong(hwnd, large ? GCL_HICON : GCL_HICONSM);
212    
213            if (icon)
214                    return icon;
215    
216            return NULL;
217    }
218    
219    static int
220    extract_icon(HICON icon, char *buffer, int maxlen)
221    {
222            ICONINFO info;
223            HDC hdc;
224            BITMAP mask_bmp, color_bmp;
225            BITMAPINFO bmi;
226            int size, i;
227            char *mask_buf, *color_buf;
228            char *o, *m, *c;
229            int ret = -1;
230    
231            assert(buffer);
232            assert(maxlen > 0);
233    
234            if (!GetIconInfo(icon, &info))
235                    goto fail;
236    
237            if (!GetObject(info.hbmMask, sizeof(BITMAP), &mask_bmp))
238                    goto free_bmps;
239            if (!GetObject(info.hbmColor, sizeof(BITMAP), &color_bmp))
240                    goto free_bmps;
241    
242            if (mask_bmp.bmWidth != color_bmp.bmWidth)
243                    goto free_bmps;
244            if (mask_bmp.bmHeight != color_bmp.bmHeight)
245                    goto free_bmps;
246    
247            if ((mask_bmp.bmWidth * mask_bmp.bmHeight * 4) > maxlen)
248                    goto free_bmps;
249    
250            size = (mask_bmp.bmWidth + 3) / 4 * 4;
251            size *= mask_bmp.bmHeight;
252            size *= 4;
253    
254            mask_buf = malloc(size);
255            if (!mask_buf)
256                    goto free_bmps;
257            color_buf = malloc(size);
258            if (!color_buf)
259                    goto free_mbuf;
260    
261            memset(&bmi, 0, sizeof(BITMAPINFO));
262    
263            bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
264            bmi.bmiHeader.biWidth = mask_bmp.bmWidth;
265            bmi.bmiHeader.biHeight = -mask_bmp.bmHeight;
266            bmi.bmiHeader.biPlanes = 1;
267            bmi.bmiHeader.biBitCount = 32;
268            bmi.bmiHeader.biCompression = BI_RGB;
269            bmi.bmiHeader.biSizeImage = size;
270    
271            hdc = CreateCompatibleDC(NULL);
272            if (!hdc)
273                    goto free_cbuf;
274    
275            if (!GetDIBits(hdc, info.hbmMask, 0, mask_bmp.bmHeight, mask_buf, &bmi, DIB_RGB_COLORS))
276                    goto del_dc;
277            if (!GetDIBits(hdc, info.hbmColor, 0, color_bmp.bmHeight, color_buf, &bmi, DIB_RGB_COLORS))
278                    goto del_dc;
279    
280            o = buffer;
281            m = mask_buf;
282            c = color_buf;
283            for (i = 0; i < size / 4; i++)
284            {
285                    o[0] = c[2];
286                    o[1] = c[1];
287                    o[2] = c[0];
288    
289                    o[3] = ((int) (unsigned char) m[0] + (unsigned char) m[1] +
290                            (unsigned char) m[2]) / 3;
291                    o[3] = 0xff - o[3];
292    
293                    o += 4;
294                    m += 4;
295                    c += 4;
296            }
297    
298            ret = size;
299    
300          del_dc:
301            DeleteDC(hdc);
302    
303          free_cbuf:
304            free(color_buf);
305          free_mbuf:
306            free(mask_buf);
307    
308          free_bmps:
309            DeleteObject(info.hbmMask);
310            DeleteObject(info.hbmColor);
311    
312          fail:
313            return ret;
314    }
315    
316    #define ICON_CHUNK 400
317    
318    static void
319    update_icon(HWND hwnd, HICON icon, int large)
320    {
321            int i, j, size, chunks;
322            char buf[32 * 32 * 4];
323            char asciibuf[ICON_CHUNK * 2 + 1];
324    
325            size = extract_icon(icon, buf, sizeof(buf));
326            if (size <= 0)
327                  return;                  return;
328    
329          vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",          if ((!large && size != 16 * 16 * 4) || (large && size != 32 * 32 * 4))
330                         hwnd,          {
331                         rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);                  debug("Unexpected icon size.");
332                    return;
333            }
334    
335            chunks = (size + ICON_CHUNK - 1) / ICON_CHUNK;
336            for (i = 0; i < chunks; i++)
337            {
338                    for (j = 0; j < ICON_CHUNK; j++)
339                    {
340                            if (i * ICON_CHUNK + j >= size)
341                                    break;
342                            sprintf(asciibuf + j * 2, "%02x",
343                                    (int) (unsigned char) buf[i * ICON_CHUNK + j]);
344                    }
345    
346                    vchannel_write("SETICON", "0x%08lx,%d,RGBA,%d,%d,%s", hwnd, i,
347                                   large ? 32 : 16, large ? 32 : 16, asciibuf);
348            }
349  }  }
350    
351  static LRESULT CALLBACK  static LRESULT CALLBACK
# Line 114  wndproc_hook_proc(int code, WPARAM cur_t Line 373  wndproc_hook_proc(int code, WPARAM cur_t
373          if ((style & WS_CHILD) && !(style & WS_POPUP))          if ((style & WS_CHILD) && !(style & WS_POPUP))
374                  goto end;                  goto end;
375    
376          if (style & WS_POPUP)          parent = get_parent(hwnd);
         {  
                 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);  
                 if (!parent)  
                         parent = (HWND) - 1;  
         }  
         else  
                 parent = NULL;  
377    
378          switch (msg)          switch (msg)
379          {          {
# Line 133  wndproc_hook_proc(int code, WPARAM cur_t Line 385  wndproc_hook_proc(int code, WPARAM cur_t
385                                  {                                  {
386                                          unsigned short title[150];                                          unsigned short title[150];
387                                          int state;                                          int state;
388                                            DWORD pid;
389                                          vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);                                          int flags;
390                                            HICON icon;
391    
392                                            GetWindowThreadProcessId(hwnd, &pid);
393    
394                                            flags = 0;
395                                            if (style & DS_MODALFRAME)
396                                                    flags |= SEAMLESS_CREATE_MODAL;
397    
398                                            vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x",
399                                                           (long) hwnd, (long) pid, (long) parent,
400                                                           flags);
401    
402                                          GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));                                          GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
403    
404                                          vchannel_write("TITLE,0x%x,%s,0x%x", hwnd,                                          vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd,
405                                                         vchannel_strfilter_unicode(title), 0);                                                         vchannel_strfilter_unicode(title), 0);
406    
407                                            icon = get_icon(hwnd, 1);
408                                            if (icon)
409                                            {
410                                                    update_icon(hwnd, icon, 1);
411                                                    DeleteObject(icon);
412                                            }
413    
414                                            icon = get_icon(hwnd, 0);
415                                            if (icon)
416                                            {
417                                                    update_icon(hwnd, icon, 0);
418                                                    DeleteObject(icon);
419                                            }
420    
421                                          if (style & WS_MAXIMIZE)                                          if (style & WS_MAXIMIZE)
422                                                  state = 2;                                                  state = 2;
423                                          else if (style & WS_MINIMIZE)                                          else if (style & WS_MINIMIZE)
# Line 150  wndproc_hook_proc(int code, WPARAM cur_t Line 427  wndproc_hook_proc(int code, WPARAM cur_t
427    
428                                          update_position(hwnd);                                          update_position(hwnd);
429    
430                                          vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);                                          vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd,
431                                                           state, 0);
432                                  }                                  }
433    
434                                  if (wp->flags & SWP_HIDEWINDOW)                                  if (wp->flags & SWP_HIDEWINDOW)
435                                          vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);                                          vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0);
436    
437                                  if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))                                  if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
438                                          break;                                          break;
# Line 162  wndproc_hook_proc(int code, WPARAM cur_t Line 440  wndproc_hook_proc(int code, WPARAM cur_t
440                                  if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))                                  if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
441                                          update_position(hwnd);                                          update_position(hwnd);
442    
443                                  if (!(wp->flags & SWP_NOZORDER))                                  break;
444                                  {                          }
                                         HWND block_hwnd, block_behind;  
                                         WaitForSingleObject(g_mutex, INFINITE);  
                                         block_hwnd = g_blocked_zchange[0];  
                                         block_behind = g_blocked_zchange[1];  
                                         ReleaseMutex(g_mutex);  
   
                                         if ((hwnd != block_hwnd)  
                                             || (wp->hwndInsertAfter != block_behind))  
                                         {  
                                                 vchannel_write("ZCHANGE,0x%p,0x%p,0x%x",  
                                                                hwnd,  
                                                                wp->flags & SWP_NOACTIVATE ? wp->  
                                                                hwndInsertAfter : 0, 0);  
                                         }  
                                 }  
445    
446                    case WM_SETICON:
447                            if (!(style & WS_VISIBLE))
448                                  break;                                  break;
449    
450                            switch (wparam)
451                            {
452                                    case ICON_BIG:
453                                            if (lparam)
454                                                    update_icon(hwnd, (HICON) lparam, 1);
455                                            else
456                                                    vchannel_write("DELICON", "0x%08lx,RGBA,32,32",
457                                                                   hwnd);
458                                            break;
459                                    case ICON_SMALL:
460                                    case 2:
461                                            if (lparam)
462                                                    update_icon(hwnd, (HICON) lparam, 0);
463                                            else
464                                                    vchannel_write("DELICON", "0x%08lx,RGBA,16,16",
465                                                                   hwnd);
466                                            break;
467                                    default:
468                                            debug("Weird icon size %d", (int) wparam);
469                          }                          }
470    
471                            break;
472    
473                  case WM_SIZE:                  case WM_SIZE:
474                          if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))                          if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
475                                  break;                                  break;
# Line 198  wndproc_hook_proc(int code, WPARAM cur_t Line 485  wndproc_hook_proc(int code, WPARAM cur_t
485                  case WM_DESTROY:                  case WM_DESTROY:
486                          if (!(style & WS_VISIBLE))                          if (!(style & WS_VISIBLE))
487                                  break;                                  break;
488                          vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);                          vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0);
489                          break;                          break;
490    
491                  default:                  default:
# Line 234  wndprocret_hook_proc(int code, WPARAM cu Line 521  wndprocret_hook_proc(int code, WPARAM cu
521          if ((style & WS_CHILD) && !(style & WS_POPUP))          if ((style & WS_CHILD) && !(style & WS_POPUP))
522                  goto end;                  goto end;
523    
524          if (style & WS_POPUP)          parent = get_parent(hwnd);
         {  
                 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);  
                 if (!parent)  
                         parent = (HWND) - 1;  
         }  
         else  
                 parent = NULL;  
525    
526          switch (msg)          switch (msg)
527          {          {
528                    case WM_WINDOWPOSCHANGED:
529                            {
530                                    WINDOWPOS *wp = (WINDOWPOS *) lparam;
531    
532                                    if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
533                                            break;
534    
535                                    if (!(wp->flags & SWP_NOZORDER))
536                                            update_zorder(hwnd);
537    
538                                    break;
539                            }
540    
541    
542                  case WM_SETTEXT:                  case WM_SETTEXT:
543                          {                          {
544                                  unsigned short title[150];                                  unsigned short title[150];
# Line 253  wndprocret_hook_proc(int code, WPARAM cu Line 547  wndprocret_hook_proc(int code, WPARAM cu
547                                  /* We cannot use the string in lparam because                                  /* We cannot use the string in lparam because
548                                     we need unicode. */                                     we need unicode. */
549                                  GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));                                  GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
550                                  vchannel_write("TITLE,0x%p,%s,0x%x", hwnd,                                  vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd,
551                                                 vchannel_strfilter_unicode(title), 0);                                                 vchannel_strfilter_unicode(title), 0);
552                                  break;                                  break;
553                          }                          }
554    
555                    case WM_SETICON:
556                            {
557                                    HICON icon;
558    
559                                    /*
560                                     * Somehow, we never get WM_SETICON for the small icon.
561                                     * So trigger a read of it every time the large one is
562                                     * changed.
563                                     */
564                                    icon = get_icon(hwnd, 0);
565                                    if (icon)
566                                    {
567                                            update_icon(hwnd, icon, 0);
568                                            DeleteObject(icon);
569                                    }
570                            }
571    
572                  default:                  default:
573                          break;                          break;
574          }          }
575    
576          if (msg == g_wm_seamless_focus)          if (msg == g_wm_seamless_focus)
577          {          {
578                  /* FIXME: SetActiveWindow() kills menus. Need to find a clean                  /* FIXME: SetForegroundWindow() kills menus. Need to find a
579                     way to solve this. */                     clean way to solve this. */
580                  if ((GetActiveWindow() != hwnd) && !parent)                  if ((GetForegroundWindow() != hwnd) && !parent)
581                          SetActiveWindow(hwnd);                          SetForegroundWindow(hwnd);
582    
583                    vchannel_write("ACK", "%u", g_blocked_focus_serial);
584          }          }
585    
586        end:        end:
# Line 285  cbt_hook_proc(int code, WPARAM wparam, L Line 598  cbt_hook_proc(int code, WPARAM wparam, L
598                  case HCBT_MINMAX:                  case HCBT_MINMAX:
599                          {                          {
600                                  int show, state, blocked;                                  int show, state, blocked;
601                                    HWND hwnd, blocked_hwnd;
602                                    unsigned int serial;
603                                    LONG style;
604    
605                                  WaitForSingleObject(g_mutex, INFINITE);                                  WaitForSingleObject(g_mutex, INFINITE);
606                                    blocked_hwnd = g_blocked_state_hwnd;
607                                    serial = g_blocked_state_serial;
608                                  blocked = g_blocked_state;                                  blocked = g_blocked_state;
609                                  ReleaseMutex(g_mutex);                                  ReleaseMutex(g_mutex);
610    
611                                    hwnd = (HWND) wparam;
612    
613                                    style = GetWindowLong(hwnd, GWL_STYLE);
614    
615                                    if (!(style & WS_VISIBLE))
616                                            break;
617    
618                                  show = LOWORD(lparam);                                  show = LOWORD(lparam);
619    
620                                  if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL)                                  if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL)
# Line 305  cbt_hook_proc(int code, WPARAM wparam, L Line 630  cbt_hook_proc(int code, WPARAM wparam, L
630                                          break;                                          break;
631                                  }                                  }
632    
633                                  if (blocked != state)                                  if ((blocked_hwnd == hwnd) && (blocked == state))
634                                          vchannel_write("STATE,0x%p,0x%x,0x%x", (HWND) wparam, state,                                          vchannel_write("ACK", "%u", serial);
635                                                         0);                                  else
636                                            vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x",
637                                                           hwnd, state, 0);
638    
639                                  break;                                  break;
640                          }                          }
# Line 348  RemoveHooks(void) Line 675  RemoveHooks(void)
675  }  }
676    
677  DLL_EXPORT void  DLL_EXPORT void
678  SafeMoveWindow(HWND hwnd, int x, int y, int width, int height)  SafeMoveWindow(unsigned int serial, HWND hwnd, int x, int y, int width, int height)
679  {  {
680            RECT rect;
681    
682          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
683            g_block_move_hwnd = hwnd;
684            g_block_move_serial = serial;
685          g_block_move.left = x;          g_block_move.left = x;
686          g_block_move.top = y;          g_block_move.top = y;
687          g_block_move.right = x + width;          g_block_move.right = x + width;
# Line 359  SafeMoveWindow(HWND hwnd, int x, int y, Line 690  SafeMoveWindow(HWND hwnd, int x, int y,
690    
691          SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);          SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);
692    
693            vchannel_write("ACK", "%u", serial);
694    
695            if (!GetWindowRect(hwnd, &rect))
696                    debug("GetWindowRect failed!\n");
697            else if ((rect.left != x) || (rect.top != y) || (rect.right != x + width)
698                     || (rect.bottom != y + height))
699                    update_position(hwnd);
700    
701          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
702            g_block_move_hwnd = NULL;
703          memset(&g_block_move, 0, sizeof(RECT));          memset(&g_block_move, 0, sizeof(RECT));
704          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
705  }  }
706    
707  DLL_EXPORT void  DLL_EXPORT void
708  SafeZChange(HWND hwnd, HWND behind)  SafeZChange(unsigned int serial, HWND hwnd, HWND behind)
709  {  {
         if (behind == NULL)  
                 behind = HWND_TOP;  
   
710          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
711            g_blocked_zchange_serial = serial;
712          g_blocked_zchange[0] = hwnd;          g_blocked_zchange[0] = hwnd;
713          g_blocked_zchange[1] = behind;          g_blocked_zchange[1] = behind;
714          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
715    
716            if (behind == NULL)
717                    behind = HWND_TOP;
718    
719          SetWindowPos(hwnd, behind, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);          SetWindowPos(hwnd, behind, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
720    
721          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
# Line 384  SafeZChange(HWND hwnd, HWND behind) Line 725  SafeZChange(HWND hwnd, HWND behind)
725  }  }
726    
727  DLL_EXPORT void  DLL_EXPORT void
728  SafeFocus(HWND hwnd)  SafeFocus(unsigned int serial, HWND hwnd)
729  {  {
730          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
731            g_blocked_focus_serial = serial;
732          g_blocked_focus = hwnd;          g_blocked_focus = hwnd;
733          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
734    
# Line 398  SafeFocus(HWND hwnd) Line 740  SafeFocus(HWND hwnd)
740  }  }
741    
742  DLL_EXPORT void  DLL_EXPORT void
743  SafeSetState(HWND hwnd, int state)  SafeSetState(unsigned int serial, HWND hwnd, int state)
744  {  {
745            LONG style;
746            int curstate;
747    
748            vchannel_block();
749    
750            style = GetWindowLong(hwnd, GWL_STYLE);
751    
752            if (style & WS_MAXIMIZE)
753                    curstate = 2;
754            else if (style & WS_MINIMIZE)
755                    curstate = 1;
756            else
757                    curstate = 0;
758    
759            if (state == curstate)
760            {
761                    vchannel_write("ACK", "%u", serial);
762                    vchannel_unblock();
763                    return;
764            }
765    
766          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
767            g_blocked_state_hwnd = hwnd;
768            g_blocked_state_serial = serial;
769          g_blocked_state = state;          g_blocked_state = state;
770          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
771    
772            vchannel_unblock();
773    
774          if (state == 0)          if (state == 0)
775                  ShowWindow(hwnd, SW_RESTORE);                  ShowWindow(hwnd, SW_RESTORE);
776          else if (state == 1)          else if (state == 1)
# Line 414  SafeSetState(HWND hwnd, int state) Line 781  SafeSetState(HWND hwnd, int state)
781                  debug("Invalid state %d sent.", state);                  debug("Invalid state %d sent.", state);
782    
783          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
784            g_blocked_state_hwnd = NULL;
785          g_blocked_state = -1;          g_blocked_state = -1;
786          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
787  }  }
# Line 454  DllMain(HINSTANCE hinstDLL, DWORD ul_rea Line 822  DllMain(HINSTANCE hinstDLL, DWORD ul_rea
822                          break;                          break;
823    
824                  case DLL_PROCESS_DETACH:                  case DLL_PROCESS_DETACH:
825                            vchannel_write("DESTROYGRP", "0x%08lx, 0x%08lx", GetCurrentProcessId(), 0);
826    
827                          WaitForSingleObject(g_mutex, INFINITE);                          WaitForSingleObject(g_mutex, INFINITE);
828                          --g_instance_count;                          --g_instance_count;
829                          ReleaseMutex(g_mutex);                          ReleaseMutex(g_mutex);

Legend:
Removed from v.1160  
changed lines
  Added in v.1412

  ViewVC Help
Powered by ViewVC 1.1.26