update for HEAD-2003050101
[reactos.git] / subsys / win32k / ntuser / window.c
index e7d7757..863e685 100644 (file)
@@ -11,6 +11,7 @@
 /* INCLUDES ******************************************************************/
 
 #include <ddk/ntddk.h>
+#include <internal/safe.h>
 #include <win32k/win32k.h>
 #include <include/object.h>
 #include <include/guicheck.h>
 #include <include/msgqueue.h>
 #include <include/rect.h>
 
-//#define NDEBUG
+#define NDEBUG
+#include <win32k/debug1.h>
 #include <debug.h>
 
+#define TAG_WNAM  TAG('W', 'N', 'A', 'M')
+
 /* FUNCTIONS *****************************************************************/
 
 HWND STDCALL
@@ -155,20 +159,35 @@ W32kReleaseWindowObject(PWINDOW_OBJECT Window)
   ObmDereferenceObject(Window);
 }
 
+/*!
+ * Internal function.
+ * Returns client window rectangle relative to the upper-left corner of client area.
+ *
+ * \note Does not check the validity of the parameters
+*/
 VOID
 W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
 {
+  ASSERT( WindowObject );
+  ASSERT( Rect );
+
   Rect->left = Rect->top = 0;
   Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
   Rect->bottom = 
     WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
 }
 
+/*!
+ * Internal Function.
+ * Return the dimension of the window in the screen coordinates.
+*/
 BOOL STDCALL
 W32kGetWindowRect(HWND hWnd, LPRECT Rect)
 {
   PWINDOW_OBJECT WindowObject;
 
+  ASSERT( Rect );
+
   WindowObject = W32kGetWindowObject(hWnd);
   if (WindowObject == NULL)
     {
@@ -183,10 +202,50 @@ W32kGetWindowRect(HWND hWnd, LPRECT Rect)
   return(TRUE);
 }
 
+/*!
+ * Return the dimension of the window in the screen coordinates.
+ * \param      hWnd    window handle.
+ * \param      Rect    pointer to the buffer where the coordinates are returned.
+*/
 BOOL STDCALL
 NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
 {
-  return(W32kGetWindowRect(hWnd, Rect));
+  RECT SafeRect;
+  BOOL bRet;
+
+  bRet = W32kGetWindowRect(hWnd, &SafeRect);
+  if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))){
+    return(FALSE);
+  }
+  return( bRet );
+}
+
+/*!
+ * Returns client window rectangle relative to the upper-left corner of client area.
+ *
+ * \param      hWnd    window handle.
+ * \param      Rect    pointer to the buffer where the coordinates are returned.
+ *
+*/
+BOOL STDCALL
+NtUserGetClientRect(HWND hWnd, LPRECT Rect)
+{
+  PWINDOW_OBJECT WindowObject;
+  RECT SafeRect;
+
+  WindowObject = W32kGetWindowObject(hWnd);
+  if (WindowObject == NULL)
+    {
+      return(FALSE);
+    }
+  W32kGetClientRect(WindowObject, &SafeRect);
+  if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+    {
+      return(FALSE);
+    }
+
+  W32kReleaseWindowObject(WindowObject);
+  return(TRUE);
 }
 
 HWND
@@ -208,15 +267,17 @@ HWND
 W32kGetFocusWindow(VOID)
 {
   PUSER_MESSAGE_QUEUE Queue;
-  Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
+  PDESKTOP_OBJECT pdo = W32kGetActiveDesktop();
+
+  if( !pdo )
+       return NULL;
+
+  Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
+
   if (Queue == NULL)
-    {
       return(NULL);
-    }
   else
-    {
       return(Queue->FocusWindow);
-    }
 }
 
 
@@ -227,6 +288,9 @@ W32kGetWindowProc(HWND Wnd)
   WNDPROC WndProc;
 
   WindowObject = W32kGetWindowObject(Wnd);
+  if( !WindowObject )
+       return NULL;
+
   WndProc = WindowObject->Class->Class.lpfnWndProc;
   W32kReleaseWindowObject(Wnd);
   return(WndProc);
@@ -343,12 +407,11 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
   CREATESTRUCTW Cs;
   LRESULT Result;
-
   DPRINT("NtUserCreateWindowEx\n");
 
   /* Initialize gui state if necessary. */
   W32kGuiCheck();
-  W32kGraphicsCheck();
+  W32kGraphicsCheck(TRUE);
 
   if (!RtlCreateUnicodeString(&WindowName, lpWindowName->Buffer))
     {
@@ -410,7 +473,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
    */
   WindowObject->Class = ClassObject;
   WindowObject->ExStyle = dwExStyle;
-  WindowObject->Style = dwStyle;
+  WindowObject->Style = dwStyle | WIN_NCACTIVATED;
   WindowObject->x = x;
   WindowObject->y = y;
   WindowObject->Width = nWidth;
@@ -426,6 +489,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
                 &WindowObject->SiblingListEntry);
   InitializeListHead(&WindowObject->ChildrenListHead);
   InitializeListHead(&WindowObject->PropListHead);
+  ExInitializeFastMutex(&WindowObject->ChildrenListLock);
 
   RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
   RtlFreeUnicodeString(&WindowName);
@@ -466,8 +530,9 @@ NtUserCreateWindowEx(DWORD dwExStyle,
    */
   InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
                 &WindowObject->DesktopListEntry);
-
-  /* FIXME: Maybe allocate a DCE for this window. */
+  /* Allocate a DCE for this window. */
+  if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC);
+  /* FIXME:  Handle "CS_CLASSDC" */
 
   /* Initialize the window dimensions. */
   WindowObject->WindowRect.left = x;
@@ -496,7 +561,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   WindowObject->ClientRect = WindowObject->WindowRect;
 
   /* FIXME: Initialize the window menu. */
-
+  
   /* Initialize the window's scrollbars */
   if (dwStyle & WS_VSCROLL)
       SCROLL_CreateScrollBar(WindowObject, SB_VERT);
@@ -556,6 +621,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
                  WindowObject->ClientRect.left,
                  WindowObject->ClientRect.bottom - 
                  WindowObject->ClientRect.top);
       DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
       W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED, 
                         lParam);
@@ -623,7 +689,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
 BOOLEAN STDCALL
 NtUserDestroyWindow(HWND Wnd)
 {
-  UNIMPLEMENTED
+  W32kGraphicsCheck(FALSE);
 
   return 0;
 }
@@ -734,11 +800,9 @@ NtUserGetOpenClipboardWindow(VOID)
 }
 
 DWORD STDCALL
-NtUserGetWindowDC(DWORD Unknown0)
+NtUserGetWindowDC(HWND hWnd)
 {
-  UNIMPLEMENTED
-
-  return 0;
+  return NtUserGetDCEx( hWnd, 0, DCX_USESTYLE | DCX_WINDOW );
 }
 
 DWORD STDCALL
@@ -768,17 +832,79 @@ NtUserLockWindowUpdate(DWORD Unknown0)
   return 0;
 }
 
-DWORD STDCALL
-NtUserMoveWindow(DWORD Unknown0,
-                DWORD Unknown1,
-                DWORD Unknown2,
-                DWORD Unknown3,
-                DWORD Unknown4,
-                DWORD Unknown5)
+BOOL STDCALL
+NtUserMoveWindow(      
+    HWND hWnd,
+    int X,
+    int Y,
+    int nWidth,
+    int nHeight,
+    BOOL bRepaint)
 {
-  UNIMPLEMENTED
+    PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
+    ULONG uStyle, uExStyle;
+    WINDOWPOS pWinPos;
 
-  return 0;
+    if (!Window) return FALSE;
+    
+    uStyle = Window->Style;
+    uExStyle = Window->ExStyle;
+    pWinPos.hwnd = hWnd;
+    
+    pWinPos.x = X;
+    pWinPos.y = Y;
+    if (nWidth > NtUserGetSystemMetrics(SM_CXMIN))
+        pWinPos.cx = pWinPos.x + nWidth;
+    else
+        pWinPos.cx = pWinPos.x + NtUserGetSystemMetrics(SM_CXMIN);
+        
+    if (nHeight > NtUserGetSystemMetrics(SM_CYMIN))
+        pWinPos.cy = pWinPos.x + nHeight;
+    else
+        pWinPos.cy = pWinPos.y + NtUserGetSystemMetrics(SM_CYMIN);
+    NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pWinPos);
+    
+    Window->WindowRect.top = Window->ClientRect.top = pWinPos.y;
+    Window->WindowRect.left = Window->ClientRect.left = pWinPos.x;
+    Window->WindowRect.bottom = Window->ClientRect.bottom = pWinPos.cy;
+    Window->WindowRect.right = Window->ClientRect.right = pWinPos.cx;
+    
+    if (!(uStyle & WS_THICKFRAME))
+    {
+      Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYFIXEDFRAME);
+      Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYFIXEDFRAME);
+      Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXFIXEDFRAME);
+      Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXFIXEDFRAME);
+    }
+    else
+    {
+        Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYSIZEFRAME);
+        Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYSIZEFRAME);
+        Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXSIZEFRAME);
+        Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXSIZEFRAME);
+    }
+
+    if (uStyle & WS_CAPTION)
+       Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYCAPTION);
+    if ( Window->Class->Class.lpszMenuName)
+    {
+        Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYMENU);
+    }
+
+    NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pWinPos);
+    
+    NtUserSendMessage(hWnd, WM_MOVE, 0, MAKEWORD(Window->ClientRect.left,
+                                                 Window->ClientRect.top));
+                                                 
+    NtUserSendMessage(hWnd, WM_SIZE, 0, MAKEWORD(Window->ClientRect.right -
+                                                 Window->ClientRect.left,
+                                                 Window->ClientRect.bottom -
+                                                 Window->ClientRect.top));
+
+    /* FIXME:  Send WM_NCCALCSIZE */
+    W32kReleaseWindowObject(Window);
+    if (bRepaint) NtUserSendMessage(hWnd, WM_PAINT, 0, 0);
+    return TRUE;
 }
 
 DWORD STDCALL
@@ -800,15 +926,24 @@ NtUserRealChildWindowFromPoint(DWORD Unknown0,
   return 0;
 }
 
-DWORD STDCALL
-NtUserRedrawWindow(DWORD Unknown0,
-                  DWORD Unknown1,
-                  DWORD Unknown2,
-                  DWORD Unknown3)
+NTSTATUS STDCALL
+NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags)
 {
-  UNIMPLEMENTED
+  RECT SafeUpdateRect;
+  NTSTATUS Status;
 
-  return 0;
+  if (NULL != lprcUpdate)
+    {
+      Status = MmCopyFromCaller(&SafeUpdateRect, lprcUpdate, sizeof(RECT));
+      if (! NT_SUCCESS(Status))
+       {
+         return Status;
+       }
+    }
+
+  return PaintRedrawWindow(hWnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect, hrgnUpdate,
+                           flags, 0) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;
+;
 }
 
 UINT STDCALL
@@ -938,7 +1073,9 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
        Result = (DWORD)WindowObject->Class->Class.lpfnWndProc; 
        break;
       }
-
+    case GWL_ID:
+    break;
+    
     default:
       {
        DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
@@ -971,18 +1108,17 @@ NtUserSetWindowPlacement(DWORD Unknown0,
   return 0;
 }
 
-DWORD STDCALL
-NtUserSetWindowPos(DWORD Unknown0,
-                  DWORD Unknown1,
-                  DWORD Unknown2,
-                  DWORD Unknown3,
-                  DWORD Unknown4,
-                  DWORD Unknown5,
-                  DWORD Unknown6)
+BOOL 
+STDCALL NtUserSetWindowPos(      
+    HWND hWnd,
+    HWND hWndInsertAfter,
+    int X,
+    int Y,
+    int cx,
+    int cy,
+    UINT uFlags)
 {
-  UNIMPLEMENTED
-
-  return 0;
+  return WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
 }
 
 DWORD STDCALL
@@ -1023,6 +1159,18 @@ NtUserShowWindowAsync(DWORD Unknown0,
   return 0;
 }
 
+BOOL STDCALL NtUserUpdateWindow( HWND hWnd )
+{
+    PWINDOW_OBJECT pWindow = W32kGetWindowObject( hWnd);
+
+    if (!pWindow)
+        return FALSE;
+    if (pWindow->UpdateRegion)
+        NtUserSendMessage( hWnd, WM_PAINT,0,0);
+    W32kReleaseWindowObject(pWindow);
+    return TRUE;
+}
+
 DWORD STDCALL
 NtUserUpdateLayeredWindow(DWORD Unknown0,
                          DWORD Unknown1,