[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / window.c
index e8f98f2..7be4ef5 100644 (file)
@@ -15,9 +15,6 @@
 #define NDEBUG
 #include <debug.h>
 
-/* dialog resources appear to pass this in 16 bits, handle them properly */
-#define CW_USEDEFAULT16 (0x8000)
-
 #define POINT_IN_RECT(p, r) (((r.bottom >= p.y) && (r.top <= p.y))&&((r.left <= p.x )&&( r.right >= p.x )))
 
 /* PRIVATE FUNCTIONS **********************************************************/
@@ -201,7 +198,7 @@ IntWinListChildren(PWND Window)
    for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       ++NumChildren;
 
-   List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
+   List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
    if(!List)
    {
       DPRINT1("Failed to allocate memory for children array\n");
@@ -297,7 +294,7 @@ UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd)
     PCLIENTINFO ClientInfo = GetWin32ClientInfo();
 
     if (!Wnd) return;
-    
+
     if (ClientInfo->CallbackWnd.pWnd == DesktopHeapAddressToUser(Wnd))
     {
         ClientInfo->CallbackWnd.hWnd = NULL;
@@ -475,6 +472,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
    if(Window->hrgnClip)
    {
       GreDeleteObject(Window->hrgnClip);
+      Window->hrgnClip = NULL;
    }
 
 //   ASSERT(Window != NULL);
@@ -942,8 +940,8 @@ IntIsWindowVisible(PWND BaseWindow)
 }
 
 
-/* 
-   link the window into siblings list 
+/*
+   link the window into siblings list
    children and parent are kept in place.
 */
 VOID FASTCALL
@@ -975,14 +973,14 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
 {
     if (hWndPrev == HWND_NOTOPMOST)
     {
-        if (!(Wnd->ExStyle & WS_EX_TOPMOST) && 
+        if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
             (Wnd->ExStyle2 & WS_EX2_LINKED)) return;  /* nothing to do */
         Wnd->ExStyle &= ~WS_EX_TOPMOST;
         hWndPrev = HWND_TOP;  /* fallback to the HWND_TOP case */
     }
 
     IntUnlinkWindow(Wnd);  /* unlink it from the previous location */
-    
+
     if (hWndPrev == HWND_BOTTOM)
     {
         /* Link in the bottom of the list */
@@ -1042,7 +1040,7 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
         IntLinkWindow(Wnd, WndInsertAfter);
 
         /* Fix the WS_EX_TOPMOST flag */
-        if (!(WndInsertAfter->ExStyle & WS_EX_TOPMOST)) 
+        if (!(WndInsertAfter->ExStyle & WS_EX_TOPMOST))
         {
             Wnd->ExStyle &= ~WS_EX_TOPMOST;
         }
@@ -1253,13 +1251,13 @@ IntUnlinkWindow(PWND Wnd)
 {
    if (Wnd->spwndNext)
        Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
+
    if (Wnd->spwndPrev)
        Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
 
    if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
        Wnd->spwndParent->spwndChild = Wnd->spwndNext;
+
    Wnd->spwndPrev = Wnd->spwndNext = NULL;
 }
 
@@ -1556,7 +1554,7 @@ static void IntSendParentNotify( PWND pWindow, UINT msg )
         {
             co_IntSendMessage( pWindow->spwndParent->head.h,
                                WM_PARENTNOTIFY,
-                               MAKEWPARAM( msg, pWindow->IDMenu), 
+                               MAKEWPARAM( msg, pWindow->IDMenu),
                                (LPARAM)pWindow->head.h );
         }
     }
@@ -1645,8 +1643,8 @@ IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
 }
 
 /* Allocates and initializes a window*/
-PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, 
-                                        PLARGE_STRING WindowName, 
+PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
+                                        PLARGE_STRING WindowName,
                                         PCLS Class,
                                         PWND ParentWindow,
                                         PWND OwnerWindow)
@@ -1670,7 +1668,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
             Cs->dwExStyle |= WS_EX_LAYOUTRTL;
       }
       else
-      {/* 
+      {/*
         Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
 
         Dialog boxes and message boxes do not inherit layout, so you must
@@ -1684,7 +1682,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
                Cs->dwExStyle |= WS_EX_LAYOUTRTL;
             }
          }
-      }      
+      }
    }
 
    /* Automatically add WS_EX_WINDOWEDGE */
@@ -1762,7 +1760,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
       if (bUnicodeWindow)
       {
          if (GETPFNCLIENTA(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
-            pWnd->lpfnWndProc = GETPFNCLIENTW(pWnd->pcls->fnid);  
+            pWnd->lpfnWndProc = GETPFNCLIENTW(pWnd->pcls->fnid);
       }
       else
       {
@@ -1807,7 +1805,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    }
 
    /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
-      then my testing shows that windows (2k and XP) creates a CallProc for it immediately 
+      then my testing shows that windows (2k and XP) creates a CallProc for it immediately
       Dont understand why it does this. */
    if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
    {
@@ -1916,7 +1914,7 @@ AllocError:
 
    if(pWnd)
       UserDereferenceObject(pWnd);
-   
+
    SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
    return NULL;
 }
@@ -1995,17 +1993,17 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
         OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT);
 
    /* Fix the position and the size of the window */
-   if (ParentWindow) 
+   if (ParentWindow)
    {
        UserRefObjectCo(ParentWindow, &ParentRef);
        IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode);
    }
 
    /* Allocate and initialize the new window */
-   Window = IntCreateWindow(Cs, 
-                            WindowName, 
-                            Class, 
-                            ParentWindow, 
+   Window = IntCreateWindow(Cs,
+                            WindowName,
+                            Class,
+                            ParentWindow,
                             OwnerWindow);
    if(!Window)
    {
@@ -2075,7 +2073,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
             UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
             pszName = UserHeapAlloc(UnicodeString.MaximumLength);
             RtlZeroMemory(pszName, UnicodeString.MaximumLength);
-            UnicodeString.Buffer = (PWSTR)pszName; 
+            UnicodeString.Buffer = (PWSTR)pszName;
             RtlCopyUnicodeString(&UnicodeString, &Name);
          }
          if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName);
@@ -2124,13 +2122,12 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    Window->rcWindow.bottom = Cs->y + Size.cy;
    if (0 != (Window->style & WS_CHILD) && ParentWindow)
    {
-      RECTL_vOffsetRect(&Window->rcWindow, 
+      RECTL_vOffsetRect(&Window->rcWindow,
                         ParentWindow->rcClient.left,
                         ParentWindow->rcClient.top);
    }
    Window->rcClient = Window->rcWindow;
 
-
    /* Link the window*/
    if (NULL != ParentWindow)
    {
@@ -2140,7 +2137,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
       else
           IntLinkHwnd(Window, hwndInsertAfter);
    }
-   
+
    /* Send the NCCREATE message */
    Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
    if (!Result)
@@ -2244,7 +2241,7 @@ CLEANUP:
    {
        DPRINT("co_UserCreateWindowEx(): Error Created window!\n");
        /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */
-       if (Window) 
+       if (Window)
             co_UserDestroyWindow(Window);
        else if (Class)
            IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
@@ -2435,7 +2432,7 @@ cleanup:
 
    return hwnd;
 }
-    
+
 
 BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
 {
@@ -2662,7 +2659,7 @@ IntFindWindow(PWND Parent,
              CurrentWindowName.Buffer = Child->strName.Buffer;
              CurrentWindowName.Length = Child->strName.Length;
              CurrentWindowName.MaximumLength = Child->strName.MaximumLength;
-             if(!CheckWindowName || 
+             if(!CheckWindowName ||
                 (Child->strName.Length < 0xFFFF &&
                  !RtlCompareUnicodeString(WindowName, &CurrentWindowName, TRUE)))
              {
@@ -2839,8 +2836,8 @@ NtUserFindWindowEx(HWND hwndParent,
                 ustr.Buffer = TopLevelWindow->strName.Buffer;
                 ustr.Length = TopLevelWindow->strName.Length;
                 ustr.MaximumLength = TopLevelWindow->strName.MaximumLength;
-                WindowMatches = !CheckWindowName || 
-                                (TopLevelWindow->strName.Length < 0xFFFF && 
+                WindowMatches = !CheckWindowName ||
+                                (TopLevelWindow->strName.Length < 0xFFFF &&
                                  !RtlCompareUnicodeString(&WindowName, &ustr, TRUE));
                 ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
                                ClassAtom == TopLevelWindow->pcls->atomClassName;
@@ -3074,7 +3071,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
                         sizeof(POINT),
                         1);
        }
-       
+
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
@@ -3083,7 +3080,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
    }
    _SEH2_END;
 
-   wndpl.length = sizeof(WINDOWPLACEMENT);   
+   wndpl.length = sizeof(WINDOWPLACEMENT);
 
    if (IntGetWindowPlacement(Window, &wndpl) && !Hit)
    {
@@ -3097,7 +3094,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
           {
              RtlCopyMemory(ptIcon, &wndpl.ptMinPosition, sizeof(POINT));
           }
-       
+
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
@@ -3886,14 +3883,15 @@ NtUserSetWindowFNID(HWND hWnd,
 
    // From user land we only set these.
    if (fnID != FNID_DESTROY)
-   {
-      if ( ((fnID < FNID_BUTTON) && (fnID > FNID_IME)) ||
+   { //       Hacked so we can mark desktop~!
+      if ( (/*(fnID < FNID_BUTTON)*/ (fnID < FNID_FIRST) && (fnID > FNID_GHOST)) ||
            Wnd->fnid != 0 )
       {
+         EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN( FALSE);
       }
    }
-   
+
    Wnd->fnid |= fnID;
    RETURN( TRUE);
 
@@ -4019,83 +4017,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-
-INT FASTCALL
-IntGetWindowRgn(PWND Window, HRGN hRgn)
-{
-   INT Ret;
-   HRGN VisRgn;
-   ROSRGNDATA *pRgn;
-
-   if(!Window)
-   {
-      return ERROR;
-   }
-   if(!hRgn)
-   {
-      return ERROR;
-   }
-
-   /* Create a new window region using the window rectangle */
-   VisRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
-   NtGdiOffsetRgn(VisRgn, -Window->rcWindow.left, -Window->rcWindow.top);
-   /* if there's a region assigned to the window, combine them both */
-   if(Window->hrgnClip && !(Window->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
-   /* Copy the region into hRgn */
-   NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
-
-   if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
-   {
-      Ret = REGION_Complexity(pRgn);
-      RGNOBJAPI_Unlock(pRgn);
-   }
-   else
-      Ret = ERROR;
-
-   REGION_FreeRgnByHandle(VisRgn);
-
-   return Ret;
-}
-
-INT FASTCALL
-IntGetWindowRgnBox(PWND Window, RECTL *Rect)
-{
-   INT Ret;
-   HRGN VisRgn;
-   ROSRGNDATA *pRgn;
-
-   if(!Window)
-   {
-      return ERROR;
-   }
-   if(!Rect)
-   {
-      return ERROR;
-   }
-
-   /* Create a new window region using the window rectangle */
-   VisRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
-   NtGdiOffsetRgn(VisRgn, -Window->rcWindow.left, -Window->rcWindow.top);
-   /* if there's a region assigned to the window, combine them both */
-   if(Window->hrgnClip && !(Window->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
-
-   if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
-   {
-      Ret = REGION_Complexity(pRgn);
-      *Rect = pRgn->rdh.rcBound;
-      RGNOBJAPI_Unlock(pRgn);
-   }
-   else
-      Ret = ERROR;
-
-   REGION_FreeRgnByHandle(VisRgn);
-
-   return Ret;
-}
-
-
 /*
  * @implemented
  */
@@ -4107,6 +4028,8 @@ NtUserSetWindowRgn(
 {
    HRGN hrgnCopy;
    PWND Window;
+   INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE);
+   BOOLEAN Ret = FALSE;
    DECLARE_RETURN(INT);
 
    DPRINT("Enter NtUserSetWindowRgn\n");
@@ -4122,32 +4045,36 @@ NtUserSetWindowRgn(
       if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
       {
          hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
+
          NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
       }
       else
          RETURN( 0);
    }
    else
-      hrgnCopy = (HRGN) 1;
+   {
+      hrgnCopy = NULL;
+   }
 
    if (Window->hrgnClip)
    {
       /* Delete no longer needed region handle */
       GreDeleteObject(Window->hrgnClip);
    }
-   Window->hrgnClip = hrgnCopy;
 
-   /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
-
-   if(bRedraw)
+   if (hrgnCopy)
    {
-      USER_REFERENCE_ENTRY Ref;
-      UserRefObjectCo(Window, &Ref);
-      co_UserRedrawWindow(Window, NULL, NULL, RDW_INVALIDATE);
-      UserDerefObjectCo(Window);
+      if (Window->fnid != FNID_DESKTOP)
+         NtGdiOffsetRgn(hrgnCopy, Window->rcWindow.left, Window->rcWindow.top);
+
+      /* Set public ownership */
+      IntGdiSetRegionOwner(hrgnCopy, GDI_OBJ_HMGR_PUBLIC);
    }
+   Window->hrgnClip = hrgnCopy;
+
+   Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) );
 
-   RETURN( (INT)hRgn);
+   RETURN( (INT)Ret);
 
 CLEANUP:
    DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_);