Author: fireball
Date: Sat Oct 31 21:55:25 2009
New Revision: 43887

URL: http://svn.reactos.org/svn/reactos?rev=43887&view=rev
Log:
- Start working on proper window managing: Implement a very simple window 
manager, responsible for redrawing top-level windows (Swm* APIs in win32k).
- Remove all previous hacks related to window redrawing in events of move or 
focus change. They couldn't work properly.
- Wine's win32 engine really expects mouse events to be tagged by a 
corresponding window's handle. Make it so using SWM.
- All these changes make arwinss usability actually regress (mostly due to 
removing unnecessary hacks and problems in other components).

Added:
    branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h   (with 
props)
    branches/arwinss/reactos/subsystems/win32/win32k/swm/   (with props)
    branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c   (with props)
Modified:
    branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c
    branches/arwinss/reactos/dll/win32/winent.drv/mouse.c
    branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
    branches/arwinss/reactos/dll/win32/winent.drv/wnd.c
    branches/arwinss/reactos/include/reactos/win32k/rosuser.h
    branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h
    branches/arwinss/reactos/subsystems/win32/win32k/main/init.c
    branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db
    branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild
    branches/arwinss/reactos/subsystems/win32/win32k/wine/window.c

Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] Sat Oct 
31 21:55:25 2009
@@ -71,6 +71,9 @@
     /* Update brush origin */
     GetBrushOrgEx(physDevDst->hUserDC, &ptBrush);
     RosGdiSetBrushOrg(physDevDst->hKernelDC, ptBrush.x, ptBrush.y);
+
+    //FIXME("xDst %d, yDst %d, widthDst %d, heightDst %d, src x %d y %d\n",
+    //    xDst, yDst, width, height, xSrc, ySrc);
 
     return RosGdiBitBlt(physDevDst->hKernelDC, xDst, yDst, width, height,
         physDevSrc->hKernelDC, xSrc, ySrc, rop);
@@ -669,6 +672,8 @@
     HRGN dc_rgn;
     DWORD size;
 
+    //FIXME("SetDeviceClipping hdc %x\n", physDev->hUserDC);
+
     /* Create a dummy region (FIXME: create it once!) */
     dc_rgn = CreateRectRgn(0,0,0,0);
     if (!dc_rgn) return;

Modified: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/mouse.c?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/mouse.c [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/mouse.c [iso-8859-1] Sat Oct 
31 21:55:25 2009
@@ -188,6 +188,10 @@
     {
                GetCursorPos(&pt);
     }
+
+    hwnd = SwmGetWindowFromPoint(pt.x, pt.y);
+
+    FIXME("hwnd %x\n", hwnd);
 
     if (flags & MOUSEEVENTF_MOVE)
     {

Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Sat 
Oct 31 21:55:25 2009
@@ -58,9 +58,9 @@
         hdc_src = hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE );
     }
 
-    //ERR( "copying bits for win %p (parent %p)/ %s -> %s\n",
-    //       data->hwnd, parent,
-    //       wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) );
+    FIXME( "copying bits for win %p (parent %p)/ %s -> %s\n",
+           data->hwnd, parent,
+           wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) );
     BitBlt( hdc_dst, dst_rect.left, dst_rect.top,
             dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top,
             hdc_src, src_rect.left, src_rect.top, SRCCOPY );
@@ -723,10 +723,9 @@
 
 void CDECL RosDrv_SetFocus( HWND hwnd )
 {
-    RECT rc;
-    //UNIMPLEMENTED;
-    GetWindowRect(hwnd, &rc);
-    RosDrv_UpdateZOrder(hwnd, &rc);
+    TRACE("SetFocus %x, desk %x\n", hwnd, GetDesktopWindow());
+    if (GetDesktopWindow() != hwnd)
+        SwmSetForeground(hwnd);
 }
 
 void CDECL RosDrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE 
alpha, DWORD flags )
@@ -765,7 +764,7 @@
             !(data = NTDRV_create_win_data( hwnd ))) return;
 
         /* Do some magic... */
-        TRACE("Window %x is being made visible\n", hwnd);
+        FIXME("Window %x is being made visible1\n", hwnd);
     }
 
     if (offset == GWL_STYLE && (changed & WS_DISABLED))
@@ -787,7 +786,7 @@
 
 UINT CDECL RosDrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
 {
-    TRACE( "win %p cmd %d at %s flags %08x\n",
+    FIXME( "win %p cmd %d at %s flags %08x\n",
            hwnd, cmd, wine_dbgstr_rect(rect), swp );
 
     return swp;
@@ -819,6 +818,11 @@
         if (!(data = NTDRV_create_win_data( hwnd ))) return;
     }
 
+    SwmPosChanging(hwnd, window_rect);
+
+    TRACE( "win %x pos is changing. vis rect %s, win rect %s\n",
+           hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(window_rect) 
);
+
     *visible_rect = *window_rect;
 }
 
@@ -833,6 +837,9 @@
     struct ntdrv_win_data *data = NTDRV_get_win_data(hwnd);
 
     if (!data) return;
+
+    TRACE( "win %x pos changed. new vis rect %s, old whole rect %s\n",
+           hwnd, wine_dbgstr_rect(visible_rect), 
wine_dbgstr_rect(&data->whole_rect) );
 
     old_whole_rect  = data->whole_rect;
     old_client_rect = data->client_rect;
@@ -855,11 +862,12 @@
             old_client_rect.bottom - data->client_rect.bottom == y_offset &&
             !memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) ))
         {
-             move_window_bits( data, &old_whole_rect, &data->whole_rect, 
&old_client_rect );
+             //move_window_bits( data, &old_whole_rect, &data->whole_rect, 
&old_client_rect );
+            SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect);
         }
         else
         {
-            move_window_bits( data, &valid_rects[1], &valid_rects[0], 
&old_client_rect );
+            //move_window_bits( data, &valid_rects[1], &valid_rects[0], 
&old_client_rect );
         }
     }
 

Modified: branches/arwinss/reactos/dll/win32/winent.drv/wnd.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/wnd.c?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/wnd.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/wnd.c [iso-8859-1] Sat Oct 31 
21:55:25 2009
@@ -18,6 +18,7 @@
 #define NTOS_USER_MODE
 #include <ndk/ntndk.h>
 #include "ntrosgdi.h"
+#include "win32k/rosuser.h"
 #include "winent.h"
 #include "wine/server.h"
 #include "wine/debug.h"
@@ -94,7 +95,15 @@
         TRACE( "win %p window %s whole %s client %s\n",
                hwnd, wine_dbgstr_rect( &data->window_rect ),
                wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( 
&data->client_rect ));
+
+        /* Inform window manager about window rect in screen coords */
+        SwmAddWindow(hwnd, &data->window_rect);
     }
+
+    /* Add desktop window too */
+    if (hwnd == GetDesktopWindow())
+        SwmAddWindow(hwnd, &data->window_rect);
+
     return data;
 }
 
@@ -111,6 +120,9 @@
     /* Remove property */
     RemovePropA( hwnd, window_data_prop );
 
+    /* Inform window manager */
+    SwmRemoveWindow( hwnd );
+
     /* Free window data */
     HeapFree( GetProcessHeap(), 0, data );
 }

Modified: branches/arwinss/reactos/include/reactos/win32k/rosuser.h
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/include/reactos/win32k/rosuser.h?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/include/reactos/win32k/rosuser.h [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/include/reactos/win32k/rosuser.h [iso-8859-1] Sat 
Oct 31 21:55:25 2009
@@ -136,4 +136,23 @@
 VOID NTAPI
 RosUserConnectCsrss(VOID);
 
+VOID NTAPI
+SwmAddWindow(HWND hWnd, RECT *WindowRect);
+
+VOID NTAPI
+SwmRemoveWindow(HWND hWnd);
+
+VOID NTAPI
+SwmSetForeground(HWND hWnd);
+
+VOID NTAPI
+SwmPosChanging(HWND hWnd, const RECT *WindowRect);
+
+VOID NTAPI
+SwmPosChanged(HWND hWnd, const RECT *WindowRect, const RECT *OldRect);
+
+HWND NTAPI
+SwmGetWindowFromPoint(LONG x, LONG y);
+
+
 #endif /* __WIN32K_NTUSER_H */

Added: branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h?rev=43887&view=auto
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h (added)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h [iso-8859-1] 
Sat Oct 31 21:55:25 2009
@@ -1,0 +1,6 @@
+#ifndef SWM__H
+#define SWM__H
+
+VOID NTAPI SwmInitialize();
+
+#endif

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h 
[iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h 
[iso-8859-1] Sat Oct 31 21:55:25 2009
@@ -53,6 +53,7 @@
 #include <xlateobj.h>
 #include <gre.h>
 #include <monitor.h>
+#include <swm.h>
 
 #include "winesup.h"
 

Modified: branches/arwinss/reactos/subsystems/win32/win32k/main/init.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/main/init.c?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/main/init.c [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/main/init.c [iso-8859-1] 
Sat Oct 31 21:55:25 2009
@@ -329,6 +329,9 @@
     /* Initialize handle-mapping */
     GDI_InitHandleMapping();
 
+    /* Initialize window manager */
+    SwmInitialize();
+
     /* Create stock objects */
     CreateStockBitmap();
     PALETTE_Init();

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/swm/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Sat Oct 31 21:55:25 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/swm/
------------------------------------------------------------------------------
    bugtraq:message = See issue #%BUGID% for more details.

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/swm/
------------------------------------------------------------------------------
    bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/swm/
------------------------------------------------------------------------------
    tsvn:logminsize = 10

Added: branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c?rev=43887&view=auto
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c (added)
+++ branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] 
Sat Oct 31 21:55:25 2009
@@ -1,0 +1,719 @@
+/*
+ * PROJECT:         ReactOS Win32K
+ * LICENSE:         LGPL - See COPYING in the top level directory
+ * FILE:            subsystems/win32/win32k/swm/winman.c
+ * PURPOSE:         Simple Window Manager
+ * PROGRAMMERS:     Aleksey Bragin ([email protected])
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <win32k.h>
+
+#include "object.h"
+#include "handle.h"
+#include "user.h"
+
+#define NDEBUG
+#include <debug.h>
+
+typedef struct _SWM_WINDOW
+{
+    HWND hwnd;
+    rectangle_t Window;
+    struct region *Visible;
+    struct region *Invisible;
+
+    LIST_ENTRY Entry;
+} SWM_WINDOW, *PSWM_WINDOW;
+
+/*static*/ inline struct window *get_window( user_handle_t handle );
+void redraw_window( struct window *win, struct region *region, int frame, 
unsigned int flags );
+void req_update_window_zorder( const struct update_window_zorder_request *req, 
struct update_window_zorder_reply *reply );
+
+VOID NTAPI SwmDumpRegion(struct region *Region);
+VOID NTAPI SwmDumpWindows();
+VOID NTAPI SwmDebugDrawWindows();
+VOID NTAPI SwmTest();
+
+
+/* GLOBALS *******************************************************************/
+
+LIST_ENTRY SwmWindows;
+ERESOURCE SwmLock;
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+SwmAcquire(VOID)
+{
+    /* Acquire user resource exclusively */
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite(&SwmLock, TRUE);
+}
+
+VOID
+NTAPI
+SwmRelease(VOID)
+{
+    /* Release user resource */
+    ExReleaseResourceLite(&SwmLock);
+    KeLeaveCriticalRegion();
+}
+
+VOID
+NTAPI
+SwmInvalidateRegion(PSWM_WINDOW Window, struct region *Region, rectangle_t 
*Rect)
+{
+    struct window *Win;
+    struct update_window_zorder_request req;
+    //struct update_window_zorder_reply reply;
+    struct region *ClientRegion;
+
+    ClientRegion = create_empty_region();
+    copy_region(ClientRegion, Region);
+
+    /* Calculate what areas to paint */
+    UserEnterExclusive();
+
+    DPRINT1("SwmInvalidateRegion hwnd %x, region:\n", Window->hwnd);
+    SwmDumpRegion(Region);
+    Win = get_window((UINT_PTR)Window->hwnd);
+    if (!Win)
+    {
+        UserLeave();
+        return;
+    }
+
+    /* Convert region to client coordinates */
+    offset_region(ClientRegion, -Window->Window.left, -Window->Window.top);
+
+    //DPRINT1("rect (%d,%d)-(%d,%d)\n", TmpRect.left, TmpRect.top, 
TmpRect.right, TmpRect.bottom);
+
+    /* Update zorder */
+    if (Rect)
+    {
+        req.rect = *Rect;
+        req.rect.left -= Window->Window.left;  req.rect.top -= 
Window->Window.top;
+        req.rect.right -= Window->Window.left; req.rect.bottom -= 
Window->Window.left;
+        req.window = (UINT_PTR)Window->hwnd;
+        //req_update_window_zorder(&req, &reply);
+    }
+
+    /* Redraw window */
+    redraw_window(Win, ClientRegion, 1, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME 
| RDW_ALLCHILDREN );
+
+    UserLeave();
+
+    free_region(ClientRegion);
+}
+
+VOID
+NTAPI
+SwmMarkInvisible(struct region *Region)
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+    struct region *WindowRegion;
+    struct region *InvisibleRegion;
+
+    /* Make a copy of the invisible region */
+    InvisibleRegion = create_empty_region();
+    copy_region(InvisibleRegion, Region);
+
+    /* Traverse the list to find our window */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        /* Get window's region */
+        WindowRegion = create_empty_region();
+        set_region_rect(WindowRegion, &Window->Window);
+
+        //DPRINT1("Window region ext:\n");
+        //SwmDumpRegion(WindowRegion);
+        //DPRINT1("Region to mark invisible ext:\n");
+        //SwmDumpRegion(Region);
+
+        /* Region to mark invisible for this window = Update region X Window 
region */
+        intersect_region(WindowRegion, WindowRegion, InvisibleRegion);
+
+        /* Check if it's empty */
+        if (!is_region_empty(WindowRegion))
+        {
+            //DPRINT1("Subtracting region\n");
+            //SwmDumpRegion(WindowRegion);
+            //DPRINT1("From visible region\n");
+            //SwmDumpRegion(Window->Visible);
+
+            /* If it's not empty, subtract it from visible region */
+            subtract_region(Window->Visible, Window->Visible, WindowRegion);
+
+            /* And subtract that part from our invisible region */
+            subtract_region(InvisibleRegion, InvisibleRegion, WindowRegion);
+        }
+
+        free_region(WindowRegion);
+
+        /* Break if our whole invisible region is mapped to underlying windows 
*/
+        if (is_region_empty(InvisibleRegion)) break;
+
+        /* Advance to the next window */
+        Current = Current->Flink;
+    }
+
+    free_region(InvisibleRegion);
+}
+
+/* NOTE: It alters the passed region! */
+VOID
+NTAPI
+SwmMarkVisible(struct region *Region)
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+    struct region *WindowRegion;
+
+    /* Go through every window from nearest to farthest */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        /* Get window's region */
+        WindowRegion = create_empty_region();
+        set_region_rect(WindowRegion, &Window->Window);
+
+        /* Region to mark invisible for this window = Update region X Window 
region */
+        intersect_region(WindowRegion, WindowRegion, Region);
+
+        /* Check if it's empty */
+        if (!is_region_empty(WindowRegion))
+        {
+            DPRINT1("Invalidating region\n");
+            SwmDumpRegion(WindowRegion);
+            DPRINT1("of window %x\n", Window->hwnd);
+
+            /* If it's not empty, subtract it from the source region */
+            subtract_region(Region, Region, WindowRegion);
+
+            /* And add it to this window's visible region */
+            union_region(Window->Visible, Window->Visible, WindowRegion);
+
+            /* Invalidate this region of target window */
+            SwmInvalidateRegion(Window, WindowRegion, NULL);
+
+            DPRINT1("Rest of the update region is:\n");
+            SwmDumpRegion(Region);
+        }
+
+        free_region(WindowRegion);
+
+        /* If region to update became empty, quit */
+        if (is_region_empty(Region)) break;
+
+        /* Advance to the next window */
+        Current = Current->Flink;
+    }
+}
+
+VOID
+NTAPI
+SwmRecalculateVisibility(PSWM_WINDOW CalcWindow)
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+    struct region *Region = create_empty_region();
+    struct region *WindowRegion = create_empty_region();
+
+    set_region_rect(WindowRegion, &CalcWindow->Window);
+
+    /* Compile a total region of visible regions of "higher" windows */
+    Current = &CalcWindow->Entry;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        union_region(Region, Region, Window->Visible);
+
+        /* Advance to the previous window */
+        Current = Current->Blink;
+    }
+
+    /* Crop the region against target window */
+    intersect_region(Region, Region, WindowRegion);
+
+    /* Subtract result from target window's visible region */
+    subtract_region(CalcWindow->Visible, WindowRegion, Region);
+
+    /* Free allocated temporary regions */
+    free_region(Region);
+    free_region(WindowRegion);
+}
+
+VOID
+NTAPI
+SwmAddWindow(HWND hWnd, RECT *WindowRect)
+{
+    PSWM_WINDOW Win;
+
+    DPRINT1("SwmAddWindow %x\n", hWnd);
+    DPRINT1("rect (%d,%d)-(%d,%d)\n", WindowRect->left, WindowRect->top, 
WindowRect->right, WindowRect->bottom);
+
+    /* Acquire the lock */
+    SwmAcquire();
+
+    /* Allocate entry */
+    Win = ExAllocatePool(PagedPool, sizeof(SWM_WINDOW));
+    RtlZeroMemory(Win, sizeof(SWM_WINDOW));
+    Win->hwnd = hWnd;
+    Win->Window.left = WindowRect->left;
+    Win->Window.top = WindowRect->top;
+    Win->Window.right = WindowRect->right;
+    Win->Window.bottom = WindowRect->bottom;
+
+    Win->Visible = create_empty_region();
+    set_region_rect(Win->Visible, &Win->Window);
+
+    /* Now go through the list and remove this rect from all underlying 
windows visible region */
+    SwmMarkInvisible(Win->Visible);
+
+    InsertHeadList(&SwmWindows, &Win->Entry);
+
+    /* Now ensure it is visible on screen */
+    SwmInvalidateRegion(Win, Win->Visible, &Win->Window);
+
+    //SwmDumpWindows();
+    //SwmDebugDrawWindows();
+
+    /* Release the lock */
+    SwmRelease();
+}
+
+PSWM_WINDOW
+NTAPI
+SwmFindByHwnd(HWND hWnd)
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+
+    /* Traverse the list to find our window */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        /* Check if it's our entry */
+        if (Window->hwnd == hWnd)
+        {
+            /* Found it, save it and break out of the loop */
+            return Window;
+        }
+
+        /* Advance to the next window */
+        Current = Current->Flink;
+    }
+
+    return NULL;
+}
+
+VOID
+NTAPI
+SwmRemoveWindow(HWND hWnd)
+{
+    PSWM_WINDOW Win;
+
+    /* Acquire the lock */
+    SwmAcquire();
+
+    DPRINT1("SwmRemoveWindow %x\n", hWnd);
+
+    /* Allocate entry */
+    Win = SwmFindByHwnd(hWnd);
+    //ASSERT(Win != NULL);
+    if (!Win)
+    {
+        /* Release the lock */
+        SwmRelease();
+
+        return;
+    }
+
+    RemoveEntryList(&Win->Entry);
+
+    /* Mark this region as visible in other window */
+    SwmMarkVisible(Win->Visible);
+
+    /* Free the entry */
+    free_region(Win->Visible);
+    ExFreePool(Win);
+
+    /* Release the lock */
+    SwmRelease();
+}
+
+VOID
+NTAPI
+SwmSetForeground(HWND hWnd)
+{
+    PSWM_WINDOW SwmWin, Previous;
+    struct region *OldVisible;
+
+    /* Acquire the lock */
+    SwmAcquire();
+
+    /* Allocate entry */
+    SwmWin = SwmFindByHwnd(hWnd);
+    //ASSERT(SwmWin != NULL);
+    if (!SwmWin)
+    {
+        /* Release the lock */
+        SwmRelease();
+        return;
+    }
+
+    /* Save previous focus window */
+    Previous = CONTAINING_RECORD(SwmWindows.Flink, SWM_WINDOW, Entry);
+
+    /* It's already on top */
+    if (Previous->hwnd == hWnd)
+    {
+        DPRINT1("hwnd %x is already on top\n", hWnd);
+        /* Release the lock */
+        SwmRelease();
+        return;
+    }
+
+    DPRINT1("Setting %x as foreground, previous window was %x\n", hWnd, 
Previous->hwnd);
+
+    /* Remove it from the list */
+    RemoveEntryList(&SwmWin->Entry);
+
+    /* Add it to the head of the list */
+    InsertHeadList(&SwmWindows, &SwmWin->Entry);
+
+    /* Make it fully visible */
+    OldVisible = create_empty_region();
+    copy_region(OldVisible, SwmWin->Visible);
+
+    free_region(SwmWin->Visible);
+    SwmWin->Visible = create_empty_region();
+    set_region_rect(SwmWin->Visible, &SwmWin->Window);
+
+    /* Intersect new visible and old visible to find region for updating */
+    intersect_region(OldVisible, OldVisible, SwmWin->Visible);
+
+    /* If it's not empty - draw missing parts */
+    if (!is_region_empty(OldVisible))
+        SwmInvalidateRegion(SwmWin, OldVisible, NULL);
+
+    free_region(OldVisible);
+
+    /* Update previous window's visible region */
+    SwmRecalculateVisibility(Previous);
+
+    /* Release the lock */
+    SwmRelease();
+}
+
+VOID
+NTAPI
+SwmPosChanging(HWND hWnd, const RECT *WindowRect)
+{
+}
+
+VOID
+NTAPI
+SwmPosChanged(HWND hWnd, const RECT *WindowRect, const RECT *OldRect)
+{
+    PSWM_WINDOW SwmWin;
+    struct region *NewRegion;
+    rectangle_t WinRect;
+
+    /* Acquire the lock */
+    SwmAcquire();
+
+    /* Allocate entry */
+    SwmWin = SwmFindByHwnd(hWnd);
+    if (!SwmWin)
+    {
+        /* Release the lock */
+        SwmRelease();
+        return;
+    }
+
+    SwmWin->Window.left = WindowRect->left;
+    SwmWin->Window.top = WindowRect->top;
+    SwmWin->Window.right = WindowRect->right;
+    SwmWin->Window.bottom = WindowRect->bottom;
+
+    //SwmDebugDrawWindows();
+
+    /* Assure the moving window is foreground */
+    ASSERT(SwmWindows.Flink == &SwmWin->Entry);
+
+    /* Create a region describing new position */
+    NewRegion = create_empty_region();
+    WinRect.left = WindowRect->left; WinRect.top = WindowRect->top;
+    WinRect.right = WindowRect->right; WinRect.bottom = WindowRect->bottom;
+    set_region_rect(NewRegion, &WinRect);
+
+    /* Intersect it with the old region */
+    intersect_region(NewRegion, NewRegion, SwmWin->Visible);
+
+    /* This window's visibility region will just move, because it
+       really equals window's rect. */
+    offset_region(SwmWin->Visible,
+                  WindowRect->left - OldRect->left,
+                  WindowRect->top - OldRect->top);
+
+    /* NewRegion now holds the difference. Mark it visible. */
+    SwmMarkVisible(NewRegion);
+    free_region(NewRegion);
+
+    /* Redraw window itself too */
+    //SwmInvalidateRegion(SwmWin, SwmWin->Visible, NULL);
+
+    /* Release the lock */
+    SwmRelease();
+}
+
+HWND
+NTAPI
+SwmGetWindowFromPoint(LONG x, LONG y)
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+
+    /* Acquire the lock */
+    SwmAcquire();
+
+    /* Traverse the list to find our window */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        if (point_in_region(Window->Visible, x, y))
+        {
+            /* Release the lock */
+            SwmRelease();
+
+            return Window->hwnd;
+        }
+
+        /* Advance to the next window */
+        Current = Current->Flink;
+    }
+
+    /* Release the lock */
+    SwmRelease();
+
+    return 0;
+}
+
+
+VOID
+NTAPI
+SwmInitialize()
+{
+    NTSTATUS Status;
+
+    /* Initialize handles list and a spinlock */
+    InitializeListHead(&SwmWindows);
+
+    /* Initialize SWM access resource */
+    Status = ExInitializeResourceLite(&SwmLock);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failure initializing SWM resource!\n");
+    }
+
+    SwmTest();
+}
+
+// haaaaaaaaaaaaaaaaaaack
+struct region
+{
+    int size;
+    int num_rects;
+    rectangle_t *rects;
+    rectangle_t extents;
+};
+
+VOID
+NTAPI
+SwmDumpRegion(struct region *Region)
+{
+    ULONG i;
+
+    //get_region_extents(Region, &ExtRect);
+
+    for (i=0; i<Region->num_rects; i++)
+    {
+        DbgPrint("(%d,%d)-(%d,%d) ", Region->rects[i].left, 
Region->rects[i].top,
+            Region->rects[i].right, Region->rects[i].bottom);
+    }
+
+    DbgPrint("\n");
+}
+
+VOID
+NTAPI
+SwmDumpWindows()
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+
+    DPRINT1("Windows in z order: ");
+
+    /* Traverse the list to find our window */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        DbgPrint("%x regions: \n", Window->hwnd);
+        SwmDumpRegion(Window->Visible);
+
+        /* Advance to the next window */
+        Current = Current->Flink;
+    }
+
+    DbgPrint("\n");
+}
+
+VOID
+NTAPI
+SwmDebugDrawRect(HDC hDC, rectangle_t *Rect, ULONG Color)
+{
+    PDC pDC;
+    ULONG Scale = 4;
+
+    /* Get a pointer to the DC */
+    pDC = DC_Lock(hDC);
+
+    pDC->pLineBrush->BrushObj.iSolidColor = Color;
+
+    GreRectangle(pDC, Rect->left / Scale, Rect->top / Scale, Rect->right / 
Scale, Rect->bottom / Scale);
+
+    /* Release the object */
+    DC_Unlock(pDC);
+}
+
+VOID
+NTAPI
+SwmDebugDrawRegion(HDC hDC, struct region *Region, ULONG Color)
+{
+    PDC pDC;
+    ULONG Scale = 4, i;
+
+    if (is_region_empty(Region)) return;
+
+    /* Get a pointer to the DC */
+    pDC = DC_Lock(hDC);
+
+    pDC->pLineBrush->BrushObj.iSolidColor = Color;
+
+    for (i=0; i<Region->num_rects; i++)
+        GreRectangle(pDC, Region->rects[i].left / Scale, Region->rects[i].top 
/ Scale,
+            Region->rects[i].right / Scale, Region->rects[i].bottom / Scale);
+
+    /* Release the object */
+    DC_Unlock(pDC);
+}
+
+VOID
+NTAPI
+SwmDebugDrawWindows()
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+    HDC ScreenDc = 0;
+    ROS_DCINFO RosDc = {0};
+    PBRUSHGDI Brush, BrushBack;
+    PDC pDC;
+    RECTL rcSafeBounds;
+
+    /* Create a dc */
+    RosGdiCreateDC(&RosDc, &ScreenDc, L"", L"", L"", NULL);
+
+    /* Create a pen and select it */
+    Brush = GreCreateSolidBrush(RGB(0xFF, 0, 0));
+
+    /* Get a pointer to the DC */
+    pDC = DC_Lock(ScreenDc);
+    GreFreeBrush(pDC->pLineBrush);
+    pDC->pLineBrush = Brush;
+
+    /* Set the clipping object */
+    IntEngDeleteClipRegion(pDC->CombinedClip);
+    RECTL_vSetRect(&rcSafeBounds,
+                   0,
+                   0,
+                   640,
+                   480);
+
+    pDC->CombinedClip = IntEngCreateClipRegion(1, &rcSafeBounds, 
&rcSafeBounds);
+
+    /* Clear the area */
+    BrushBack = pDC->pFillBrush;
+    pDC->pFillBrush = GreCreateSolidBrush(RGB(0,0,0));
+    GreRectangle(pDC, 0, 0, 800/4, 600/4);
+    GreFreeBrush(pDC->pFillBrush);
+    pDC->pFillBrush = BrushBack;
+
+    DC_Unlock(pDC);
+
+    /* Traverse the list to find our window */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        SwmDebugDrawRect(ScreenDc, &Window->Window, RGB(0,0,255));
+        SwmDebugDrawRegion(ScreenDc, Window->Visible, RGB(255,0,0));
+
+        /* Advance to the next window */
+        Current = Current->Flink;
+    }
+
+    /* Delete screen dc */
+    GreFreeBrush(Brush);
+    RosGdiDeleteDC(ScreenDc);
+}
+
+VOID
+NTAPI
+SwmTest()
+{
+#if 0
+    RECT rect;
+    HWND hwnd;
+
+    /* "desktop" */
+    hwnd = (HWND)1;
+    rect.left = 0; rect.top = 0;
+    rect.right = 100; rect.bottom = 100;
+    SwmAddWindow(hwnd, &rect);
+
+    /* win1 */
+    hwnd = (HWND)2;
+    rect.left = 40; rect.top = 40;
+    rect.right = 60; rect.bottom = 60;
+    SwmAddWindow(hwnd, &rect);
+
+    /* win2 */
+    hwnd = (HWND)3;
+    rect.left = 50; rect.top = 50;
+    rect.right = 70; rect.bottom = 70;
+    SwmAddWindow(hwnd, &rect);
+
+    SwmDumpWindows();
+#endif
+}
+
+/* EOF */

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] 
Sat Oct 31 21:55:25 2009
@@ -81,4 +81,10 @@
 RosUserGetKeyNameText              3
 RosUserToUnicodeEx                 7
 RosUserMapVirtualKeyEx             4
-RosUserGetAsyncKeyState            1
+RosUserGetAsyncKeyState            1
+SwmAddWindow                       2
+SwmRemoveWindow                    1
+SwmSetForeground                   1
+SwmPosChanging                     2
+SwmPosChanged                      3
+SwmGetWindowFromPoint              2

Modified: branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] 
Sat Oct 31 21:55:25 2009
@@ -116,6 +116,9 @@
                <file>kbdlayout.c</file>
                <file>keyboard.c</file>
        </directory>
+       <directory name="swm">
+               <file>winman.c</file>
+       </directory>
        <directory name="wine">
                <file>atom.c</file>
                <file>class.c</file>

Modified: branches/arwinss/reactos/subsystems/win32/win32k/wine/window.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/wine/window.c?rev=43887&r1=43886&r2=43887&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/wine/window.c [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/wine/window.c [iso-8859-1] 
Sat Oct 31 21:55:25 2009
@@ -110,7 +110,7 @@
 #define WINPTR_NOTOPMOST ((struct window *)4L)
 
 /* retrieve a pointer to a window from its handle */
-static inline struct window *get_window( user_handle_t handle )
+/*static*/ inline struct window *get_window( user_handle_t handle )
 {
     struct window *ret = get_user_object( handle, USER_WINDOW );
     if (!ret) set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
@@ -1231,7 +1231,7 @@
 
 
 /* add/subtract a region (in client coordinates) to the update region of the 
window */
-static void redraw_window( struct window *win, struct region *region, int 
frame, unsigned int flags )
+/*static*/ void redraw_window( struct window *win, struct region *region, int 
frame, unsigned int flags )
 {
     struct region *tmp;
     struct window *child;


Reply via email to