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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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 (aleksey(a)reactos.org)
+ */
+
+/* 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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;