update for HEAD-2003050101
[reactos.git] / subsys / win32k / ntuser / window.c
1 /* $Id$
2  *
3  * COPYRIGHT:        See COPYING in the top level directory
4  * PROJECT:          ReactOS kernel
5  * PURPOSE:          Windows
6  * FILE:             subsys/win32k/ntuser/window.c
7  * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
8  * REVISION HISTORY:
9  *       06-06-2001  CSH  Created
10  */
11 /* INCLUDES ******************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/safe.h>
15 #include <win32k/win32k.h>
16 #include <include/object.h>
17 #include <include/guicheck.h>
18 #include <include/window.h>
19 #include <include/class.h>
20 #include <include/error.h>
21 #include <include/winsta.h>
22 #include <include/winpos.h>
23 #include <include/callback.h>
24 #include <include/msgqueue.h>
25 #include <include/rect.h>
26
27 #define NDEBUG
28 #include <win32k/debug1.h>
29 #include <debug.h>
30
31 #define TAG_WNAM  TAG('W', 'N', 'A', 'M')
32
33 /* FUNCTIONS *****************************************************************/
34
35 HWND STDCALL
36 NtUserGetAncestor(HWND hWnd, UINT Flags)
37 {
38   if (W32kIsDesktopWindow(hWnd))
39     {
40       return(NULL);
41     }
42   if (Flags & GA_PARENT)
43     {
44       PWINDOW_OBJECT Window;
45       HWND hParent;
46
47       Window = W32kGetWindowObject(hWnd);
48       if (Window == NULL)
49         {
50           return(NULL);
51         }     
52
53       if (Window->Parent == NULL)
54         {
55           W32kReleaseWindowObject(Window);
56         }
57
58       hParent = Window->Parent->Self;
59
60       W32kReleaseWindowObject(Window);
61
62       return(hParent);
63     }
64   else
65     {
66       UNIMPLEMENTED;
67       return(NULL);
68     }
69 }
70
71 VOID
72 W32kSetFocusWindow(HWND hWnd)
73 {
74 }
75
76 BOOL
77 W32kIsChildWindow(HWND Parent, HWND Child)
78 {
79   PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Child);
80   PWINDOW_OBJECT Window = BaseWindow;
81   while (Window != NULL && Window->Style & WS_CHILD)
82     {
83       if (Window->Self == Parent)
84         {
85           W32kReleaseWindowObject(BaseWindow);
86           return(TRUE);
87         }
88       Window = Window->Parent;
89     }
90   W32kReleaseWindowObject(BaseWindow);
91   return(FALSE);  
92 }
93
94 BOOL
95 W32kIsWindowVisible(HWND Wnd)
96 {
97   PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Wnd);
98   PWINDOW_OBJECT Window = BaseWindow;
99   BOOLEAN Result = FALSE;
100   while (Window != NULL && Window->Style & WS_CHILD)
101     {
102       if (!(Window->Style & WS_VISIBLE))
103         {
104           W32kReleaseWindowObject(BaseWindow);
105           return(FALSE);
106         }
107       Window = Window->Parent;
108     }
109   if (Window != NULL && Window->Style & WS_VISIBLE)
110     {
111       Result = TRUE;
112     }
113   W32kReleaseWindowObject(BaseWindow);
114   return(Result);
115 }
116
117 BOOL
118 W32kIsDesktopWindow(HWND hWnd)
119 {
120   PWINDOW_OBJECT WindowObject;
121   BOOL IsDesktop;
122   WindowObject = W32kGetWindowObject(hWnd);
123   IsDesktop = WindowObject->Parent == NULL;
124   W32kReleaseWindowObject(WindowObject);
125   return(IsDesktop);
126 }
127
128 HWND W32kGetDesktopWindow()
129 {
130   return W32kGetActiveDesktop()->DesktopWindow;
131 }
132
133 HWND W32kGetParentWindow(HWND hWnd)
134 {
135   return W32kGetWindowObject(hWnd)->ParentHandle;
136 }
137
138 PWINDOW_OBJECT
139 W32kGetWindowObject(HWND hWnd)
140 {
141   PWINDOW_OBJECT WindowObject;
142   NTSTATUS Status;
143   Status = 
144     ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
145                                HandleTable,
146                                hWnd,
147                                otWindow,
148                                (PVOID*)&WindowObject);
149   if (!NT_SUCCESS(Status))
150     {
151       return(NULL);
152     }
153   return(WindowObject);
154 }
155
156 VOID
157 W32kReleaseWindowObject(PWINDOW_OBJECT Window)
158 {
159   ObmDereferenceObject(Window);
160 }
161
162 /*!
163  * Internal function.
164  * Returns client window rectangle relative to the upper-left corner of client area.
165  *
166  * \note Does not check the validity of the parameters
167 */
168 VOID
169 W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
170 {
171   ASSERT( WindowObject );
172   ASSERT( Rect );
173
174   Rect->left = Rect->top = 0;
175   Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
176   Rect->bottom = 
177     WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
178 }
179
180 /*!
181  * Internal Function.
182  * Return the dimension of the window in the screen coordinates.
183 */
184 BOOL STDCALL
185 W32kGetWindowRect(HWND hWnd, LPRECT Rect)
186 {
187   PWINDOW_OBJECT WindowObject;
188
189   ASSERT( Rect );
190
191   WindowObject = W32kGetWindowObject(hWnd);
192   if (WindowObject == NULL)
193     {
194       return(FALSE);
195     }
196   *Rect = WindowObject->WindowRect;
197   if (WindowObject->Style & WS_CHILD)
198     {
199       DbgBreakPoint();
200     }
201   W32kReleaseWindowObject(WindowObject);
202   return(TRUE);
203 }
204
205 /*!
206  * Return the dimension of the window in the screen coordinates.
207  * \param       hWnd    window handle.
208  * \param       Rect    pointer to the buffer where the coordinates are returned.
209 */
210 BOOL STDCALL
211 NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
212 {
213   RECT SafeRect;
214   BOOL bRet;
215
216   bRet = W32kGetWindowRect(hWnd, &SafeRect);
217   if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))){
218     return(FALSE);
219   }
220   return( bRet );
221 }
222
223 /*!
224  * Returns client window rectangle relative to the upper-left corner of client area.
225  *
226  * \param       hWnd    window handle.
227  * \param       Rect    pointer to the buffer where the coordinates are returned.
228  *
229 */
230 BOOL STDCALL
231 NtUserGetClientRect(HWND hWnd, LPRECT Rect)
232 {
233   PWINDOW_OBJECT WindowObject;
234   RECT SafeRect;
235
236   WindowObject = W32kGetWindowObject(hWnd);
237   if (WindowObject == NULL)
238     {
239       return(FALSE);
240     }
241   W32kGetClientRect(WindowObject, &SafeRect);
242   if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
243     {
244       return(FALSE);
245     }
246
247   W32kReleaseWindowObject(WindowObject);
248   return(TRUE);
249 }
250
251 HWND
252 W32kGetActiveWindow(VOID)
253 {
254   PUSER_MESSAGE_QUEUE Queue;
255   Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
256   if (Queue == NULL)
257     {
258       return(NULL);
259     }
260   else
261     {
262       return(Queue->ActiveWindow);
263     }
264 }
265
266 HWND
267 W32kGetFocusWindow(VOID)
268 {
269   PUSER_MESSAGE_QUEUE Queue;
270   PDESKTOP_OBJECT pdo = W32kGetActiveDesktop();
271
272   if( !pdo )
273         return NULL;
274
275   Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
276
277   if (Queue == NULL)
278       return(NULL);
279   else
280       return(Queue->FocusWindow);
281 }
282
283
284 WNDPROC
285 W32kGetWindowProc(HWND Wnd)
286 {
287   PWINDOW_OBJECT WindowObject;
288   WNDPROC WndProc;
289
290   WindowObject = W32kGetWindowObject(Wnd);
291   if( !WindowObject )
292         return NULL;
293
294   WndProc = WindowObject->Class->Class.lpfnWndProc;
295   W32kReleaseWindowObject(Wnd);
296   return(WndProc);
297 }
298
299 NTSTATUS
300 InitWindowImpl(VOID)
301 {
302   return(STATUS_SUCCESS);
303 }
304
305 NTSTATUS
306 CleanupWindowImpl(VOID)
307 {
308   return(STATUS_SUCCESS);
309 }
310
311
312 DWORD STDCALL
313 NtUserAlterWindowStyle(DWORD Unknown0,
314                        DWORD Unknown1,
315                        DWORD Unknown2)
316 {
317   UNIMPLEMENTED
318
319   return(0);
320 }
321
322 DWORD STDCALL
323 NtUserChildWindowFromPointEx(HWND Parent,
324                              LONG x,
325                              LONG y,
326                              UINT Flags)
327 {
328   UNIMPLEMENTED
329
330   return(0);
331 }
332
333 HWND STDCALL
334 W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
335                         PWNDCLASS_OBJECT DesktopClass,
336                         ULONG Width, ULONG Height)
337 {
338   PWSTR WindowName;
339   HWND Handle;
340   PWINDOW_OBJECT WindowObject;
341
342   /* Create the window object. */
343   WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable, 
344                                                  &Handle, 
345                                                  otWindow,
346                                                  sizeof(WINDOW_OBJECT));
347   if (!WindowObject) 
348     {
349       return((HWND)0);
350     }
351
352   /*
353    * Fill out the structure describing it.
354    */
355   WindowObject->Class = DesktopClass;
356   WindowObject->ExStyle = 0;
357   WindowObject->Style = WS_VISIBLE;
358   WindowObject->x = 0;
359   WindowObject->y = 0;
360   WindowObject->Width = Width;
361   WindowObject->Height = Height;
362   WindowObject->ParentHandle = NULL;
363   WindowObject->Parent = NULL;
364   WindowObject->Menu = NULL;
365   WindowObject->Instance = NULL;
366   WindowObject->Parameters = NULL;
367   WindowObject->Self = Handle;
368   WindowObject->MessageQueue = NULL;
369   WindowObject->ExtraData = NULL;
370   WindowObject->ExtraDataSize = 0;
371   WindowObject->WindowRect.left = 0;
372   WindowObject->WindowRect.top = 0;
373   WindowObject->WindowRect.right = Width;
374   WindowObject->WindowRect.bottom = Height;
375   WindowObject->ClientRect = WindowObject->WindowRect;
376   InitializeListHead(&WindowObject->ChildrenListHead);
377
378   WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
379   wcscpy(WindowName, L"DESKTOP");
380   RtlInitUnicodeString(&WindowObject->WindowName, WindowName);
381
382   return(Handle);
383 }
384
385 HWND STDCALL
386 NtUserCreateWindowEx(DWORD dwExStyle,
387                      PUNICODE_STRING lpClassName,
388                      PUNICODE_STRING lpWindowName,
389                      DWORD dwStyle,
390                      LONG x,
391                      LONG y,
392                      LONG nWidth,
393                      LONG nHeight,
394                      HWND hWndParent,
395                      HMENU hMenu,
396                      HINSTANCE hInstance,
397                      LPVOID lpParam,
398                      DWORD dwShowMode)
399 {
400   PWINSTATION_OBJECT WinStaObject;
401   PWNDCLASS_OBJECT ClassObject;
402   PWINDOW_OBJECT WindowObject;
403   PWINDOW_OBJECT ParentWindow;
404   UNICODE_STRING WindowName;
405   NTSTATUS Status;
406   HANDLE Handle;
407   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
408   CREATESTRUCTW Cs;
409   LRESULT Result;
410   DPRINT("NtUserCreateWindowEx\n");
411
412   /* Initialize gui state if necessary. */
413   W32kGuiCheck();
414   W32kGraphicsCheck(TRUE);
415
416   if (!RtlCreateUnicodeString(&WindowName, lpWindowName->Buffer))
417     {
418       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
419       return((HWND)0);
420     }
421
422   if (hWndParent != NULL)
423     {
424       ParentWindow = W32kGetWindowObject(hWndParent);
425     }
426   else
427     {
428       hWndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
429       ParentWindow = W32kGetWindowObject(hWndParent);
430     }
431
432   /* Check the class. */
433   Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
434   if (!NT_SUCCESS(Status))
435     {
436       RtlFreeUnicodeString(&WindowName);
437       return((HWND)0);
438     }
439
440   /* Check the window station. */
441   DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
442   DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION());
443   Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
444                                        KernelMode,
445                                        0,
446                                        &WinStaObject);
447   if (!NT_SUCCESS(Status))
448     {
449       RtlFreeUnicodeString(&WindowName);
450       ObmDereferenceObject(ClassObject);
451       DPRINT("Validation of window station handle (0x%X) failed\n",
452              PROCESS_WINDOW_STATION());
453       return (HWND)0;
454     }
455
456   /* Create the window object. */
457   WindowObject = (PWINDOW_OBJECT)
458     ObmCreateObject(PsGetWin32Process()->WindowStation->HandleTable, &Handle,
459                     otWindow, sizeof(WINDOW_OBJECT));
460   DPRINT("Created object with handle %X\n", Handle);
461   if (!WindowObject)
462     {
463       ObDereferenceObject(WinStaObject);
464       ObmDereferenceObject(ClassObject);
465       RtlFreeUnicodeString(&WindowName);
466       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
467       return (HWND)0;
468     }
469   ObDereferenceObject(WinStaObject);
470
471   /*
472    * Fill out the structure describing it.
473    */
474   WindowObject->Class = ClassObject;
475   WindowObject->ExStyle = dwExStyle;
476   WindowObject->Style = dwStyle | WIN_NCACTIVATED;
477   WindowObject->x = x;
478   WindowObject->y = y;
479   WindowObject->Width = nWidth;
480   WindowObject->Height = nHeight;
481   WindowObject->ParentHandle = hWndParent;
482   WindowObject->Menu = hMenu;
483   WindowObject->Instance = hInstance;
484   WindowObject->Parameters = lpParam;
485   WindowObject->Self = Handle;
486   WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
487   WindowObject->Parent = ParentWindow;
488   InsertHeadList(&ParentWindow->ChildrenListHead,
489                  &WindowObject->SiblingListEntry);
490   InitializeListHead(&WindowObject->ChildrenListHead);
491   InitializeListHead(&WindowObject->PropListHead);
492   ExInitializeFastMutex(&WindowObject->ChildrenListLock);
493
494   RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
495   RtlFreeUnicodeString(&WindowName);
496
497   if (ClassObject->Class.cbWndExtra != 0)
498     {
499       WindowObject->ExtraData =
500         ExAllocatePool(PagedPool,
501                        ClassObject->Class.cbWndExtra * sizeof(DWORD));
502       WindowObject->ExtraDataSize = ClassObject->Class.cbWndExtra;
503     }
504   else
505     {
506       WindowObject->ExtraData = NULL;
507       WindowObject->ExtraDataSize = 0;
508     }
509
510   /* Correct the window style. */
511   if (!(dwStyle & WS_CHILD))
512     {
513       WindowObject->Style |= WS_CLIPSIBLINGS;
514       if (!(dwStyle & WS_POPUP))
515         {
516           WindowObject->Style |= WS_CAPTION;
517           /* FIXME: Note the window needs a size. */ 
518         }
519     }
520
521   /* Insert the window into the process's window list. */
522   ExAcquireFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
523   InsertTailList (&PsGetWin32Thread()->WindowListHead, 
524                   &WindowObject->ThreadListEntry);
525   ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
526
527   /*
528    * Insert the window into the list of windows associated with the thread's
529    * desktop. 
530    */
531   InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
532                  &WindowObject->DesktopListEntry);
533   /* Allocate a DCE for this window. */
534   if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC);
535   /* FIXME:  Handle "CS_CLASSDC" */
536
537   /* Initialize the window dimensions. */
538   WindowObject->WindowRect.left = x;
539   WindowObject->WindowRect.top = y;
540   WindowObject->WindowRect.right = x + nWidth;
541   WindowObject->WindowRect.bottom = y + nHeight;
542   WindowObject->ClientRect = WindowObject->WindowRect;
543
544   /*
545    * Get the size and position of the window.
546    */
547   if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
548     {
549       WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
550                           &MaxTrack);
551       x = min(MaxSize.x, y);
552       y = min(MaxSize.y, y);
553       x = max(MinTrack.x, x);
554       y = max(MinTrack.y, y);
555     }
556
557   WindowObject->WindowRect.left = x;
558   WindowObject->WindowRect.top = y;
559   WindowObject->WindowRect.right = x + nWidth;
560   WindowObject->WindowRect.bottom = y + nHeight;
561   WindowObject->ClientRect = WindowObject->WindowRect;
562
563   /* FIXME: Initialize the window menu. */
564   
565   /* Initialize the window's scrollbars */
566   if (dwStyle & WS_VSCROLL)
567       SCROLL_CreateScrollBar(WindowObject, SB_VERT);
568   if (dwStyle & WS_HSCROLL)
569       SCROLL_CreateScrollBar(WindowObject, SB_HORZ);
570
571   /* Send a NCCREATE message. */
572   Cs.lpCreateParams = lpParam;
573   Cs.hInstance = hInstance;
574   Cs.hMenu = hMenu;
575   Cs.hwndParent = hWndParent;
576   Cs.cx = nWidth;
577   Cs.cy = nHeight;
578   Cs.x = x;
579   Cs.y = y;
580   Cs.style = dwStyle;
581   Cs.lpszName = lpWindowName->Buffer;
582   Cs.lpszClass = lpClassName->Buffer;
583   Cs.dwExStyle = dwExStyle;
584   DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
585   Result = W32kSendNCCREATEMessage(WindowObject->Self, &Cs);
586   if (!Result)
587     {
588       /* FIXME: Cleanup. */
589       DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n");
590       return(NULL);
591     }
592  
593   /* Calculate the non-client size. */
594   MaxPos.x = WindowObject->WindowRect.left;
595   MaxPos.y = WindowObject->WindowRect.top;
596   DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
597   Result = WinPosGetNonClientSize(WindowObject->Self, 
598                                   &WindowObject->WindowRect,
599                                   &WindowObject->ClientRect);
600   W32kOffsetRect(&WindowObject->WindowRect, 
601                  MaxPos.x - WindowObject->WindowRect.left,
602                  MaxPos.y - WindowObject->WindowRect.top);
603
604   /* Send the CREATE message. */
605   DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
606   Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
607   if (Result == (LRESULT)-1)
608     {
609       /* FIXME: Cleanup. */
610       DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
611       return(NULL);
612     } 
613
614   /* Send move and size messages. */
615   if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE))
616     {
617       LONG lParam;
618       
619       lParam = 
620         MAKE_LONG(WindowObject->ClientRect.right - 
621                   WindowObject->ClientRect.left,
622                   WindowObject->ClientRect.bottom - 
623                   WindowObject->ClientRect.top);
624  
625       DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
626       W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED, 
627                          lParam);
628       lParam = 
629         MAKE_LONG(WindowObject->ClientRect.left,
630                   WindowObject->ClientRect.top);
631       DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
632       W32kCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
633     }
634
635   /* Show or maybe minimize or maximize the window. */
636   if (WindowObject->Style & (WS_MINIMIZE | WS_MAXIMIZE))
637     {
638       RECT NewPos;
639       UINT16 SwFlag;
640
641       SwFlag = (WindowObject->Style & WS_MINIMIZE) ? SW_MINIMIZE : 
642         SW_MAXIMIZE;
643       WinPosMinMaximize(WindowObject, SwFlag, &NewPos);
644       SwFlag = 
645         ((WindowObject->Style & WS_CHILD) || W32kGetActiveWindow()) ?
646         SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
647         SWP_NOZORDER | SWP_FRAMECHANGED;
648       DPRINT("NtUserCreateWindow(): About to minimize/maximize\n");
649       WinPosSetWindowPos(WindowObject->Self, 0, NewPos.left, NewPos.top,
650                          NewPos.right, NewPos.bottom, SwFlag);
651     }
652
653   /* Notify the parent window of a new child. */
654   if ((WindowObject->Style & WS_CHILD) ||
655       (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
656     {
657       DPRINT("NtUserCreateWindow(): About to notify parent\n");
658       W32kCallWindowProc(NULL, WindowObject->Parent->Self,
659                          WM_PARENTNOTIFY, 
660                          MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
661                          (LPARAM)WindowObject->Self);
662     }
663
664   if (dwStyle & WS_VISIBLE)
665     {
666       DPRINT("NtUserCreateWindow(): About to show window\n");
667       WinPosShowWindow(WindowObject->Self, dwShowMode);
668     }
669
670   DPRINT("NtUserCreateWindow(): = %X\n", Handle);
671   return((HWND)Handle);
672 }
673
674 DWORD STDCALL
675 NtUserDeferWindowPos(HDWP WinPosInfo,
676                      HWND Wnd,
677                      HWND WndInsertAfter,
678                      LONG x,
679                      LONG y,
680                      LONG cx,
681                      LONG cy,
682                      UINT Flags)
683 {
684   UNIMPLEMENTED
685
686   return 0;
687 }
688
689 BOOLEAN STDCALL
690 NtUserDestroyWindow(HWND Wnd)
691 {
692   W32kGraphicsCheck(FALSE);
693
694   return 0;
695 }
696
697 DWORD STDCALL
698 NtUserEndDeferWindowPosEx(DWORD Unknown0,
699                           DWORD Unknown1)
700 {
701   UNIMPLEMENTED
702     
703   return 0;
704 }
705
706 DWORD STDCALL
707 NtUserFillWindow(DWORD Unknown0,
708                  DWORD Unknown1,
709                  DWORD Unknown2,
710                  DWORD Unknown3)
711 {
712   UNIMPLEMENTED
713
714   return 0;
715 }
716
717 HWND STDCALL
718 NtUserFindWindowEx(HWND hwndParent,
719                    HWND hwndChildAfter,
720                    PUNICODE_STRING ucClassName,
721                    PUNICODE_STRING ucWindowName,
722                    DWORD Unknown4)
723 {
724 #if 0
725   NTSTATUS status;
726   HWND windowHandle;
727   PWINDOW_OBJECT windowObject;
728   PLIST_ENTRY currentEntry;
729   PWNDCLASS_OBJECT classObject;
730   
731   W32kGuiCheck();
732   
733   status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer);
734   if (!NT_SUCCESS(status))
735     {
736       return (HWND)0;
737     }
738
739   ExAcquireFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
740   currentEntry = PsGetWin32Process()->WindowListHead.Flink;
741   while (currentEntry != &PsGetWin32Process()->WindowListHead)
742     {
743       windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT, 
744                                         ListEntry);
745
746       if (classObject == windowObject->Class &&
747           RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, 
748                                    TRUE) == 0)
749         {
750           ObmCreateHandle(PsGetWin32Process()->HandleTable,
751                           windowObject,
752                           &windowHandle);
753           ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
754           ObmDereferenceObject (classObject);
755       
756           return  windowHandle;
757         }
758       currentEntry = currentEntry->Flink;
759   }
760   ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
761   
762   ObmDereferenceObject (classObject);
763
764   return  (HWND)0;
765 #endif
766 }
767
768 DWORD STDCALL
769 NtUserFlashWindowEx(DWORD Unknown0)
770 {
771   UNIMPLEMENTED
772
773   return 0;
774 }
775
776 DWORD STDCALL
777 NtUserGetForegroundWindow(VOID)
778 {
779   UNIMPLEMENTED
780
781   return 0;
782 }
783
784 DWORD STDCALL
785 NtUserGetInternalWindowPos(DWORD Unknown0,
786                            DWORD Unknown1,
787                            DWORD Unknown2)
788 {
789   UNIMPLEMENTED
790
791   return 0;
792 }
793
794 DWORD STDCALL
795 NtUserGetOpenClipboardWindow(VOID)
796 {
797   UNIMPLEMENTED
798
799   return 0;
800 }
801
802 DWORD STDCALL
803 NtUserGetWindowDC(HWND hWnd)
804 {
805   return NtUserGetDCEx( hWnd, 0, DCX_USESTYLE | DCX_WINDOW );
806 }
807
808 DWORD STDCALL
809 NtUserGetWindowPlacement(DWORD Unknown0,
810                          DWORD Unknown1)
811 {
812   UNIMPLEMENTED
813
814   return 0;
815 }
816
817 DWORD STDCALL
818 NtUserInternalGetWindowText(DWORD Unknown0,
819                             DWORD Unknown1,
820                             DWORD Unknown2)
821 {
822   UNIMPLEMENTED
823
824   return 0;
825 }
826
827 DWORD STDCALL
828 NtUserLockWindowUpdate(DWORD Unknown0)
829 {
830   UNIMPLEMENTED
831
832   return 0;
833 }
834
835 BOOL STDCALL
836 NtUserMoveWindow(      
837     HWND hWnd,
838     int X,
839     int Y,
840     int nWidth,
841     int nHeight,
842     BOOL bRepaint)
843 {
844     PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
845     ULONG uStyle, uExStyle;
846     WINDOWPOS pWinPos;
847
848     if (!Window) return FALSE;
849     
850     uStyle = Window->Style;
851     uExStyle = Window->ExStyle;
852     pWinPos.hwnd = hWnd;
853     
854     pWinPos.x = X;
855     pWinPos.y = Y;
856     if (nWidth > NtUserGetSystemMetrics(SM_CXMIN))
857         pWinPos.cx = pWinPos.x + nWidth;
858     else
859         pWinPos.cx = pWinPos.x + NtUserGetSystemMetrics(SM_CXMIN);
860         
861     if (nHeight > NtUserGetSystemMetrics(SM_CYMIN))
862         pWinPos.cy = pWinPos.x + nHeight;
863     else
864         pWinPos.cy = pWinPos.y + NtUserGetSystemMetrics(SM_CYMIN);
865     NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pWinPos);
866     
867     Window->WindowRect.top = Window->ClientRect.top = pWinPos.y;
868     Window->WindowRect.left = Window->ClientRect.left = pWinPos.x;
869     Window->WindowRect.bottom = Window->ClientRect.bottom = pWinPos.cy;
870     Window->WindowRect.right = Window->ClientRect.right = pWinPos.cx;
871     
872     if (!(uStyle & WS_THICKFRAME))
873     {
874       Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYFIXEDFRAME);
875       Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYFIXEDFRAME);
876       Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXFIXEDFRAME);
877       Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXFIXEDFRAME);
878     }
879     else
880     {
881         Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYSIZEFRAME);
882         Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYSIZEFRAME);
883         Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXSIZEFRAME);
884         Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXSIZEFRAME);
885     }
886
887     if (uStyle & WS_CAPTION)
888        Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYCAPTION);
889     if ( Window->Class->Class.lpszMenuName)
890     {
891         Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYMENU);
892     }
893
894     NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pWinPos);
895     
896     NtUserSendMessage(hWnd, WM_MOVE, 0, MAKEWORD(Window->ClientRect.left,
897                                                  Window->ClientRect.top));
898                                                  
899     NtUserSendMessage(hWnd, WM_SIZE, 0, MAKEWORD(Window->ClientRect.right -
900                                                  Window->ClientRect.left,
901                                                  Window->ClientRect.bottom -
902                                                  Window->ClientRect.top));
903
904     /* FIXME:  Send WM_NCCALCSIZE */
905     W32kReleaseWindowObject(Window);
906     if (bRepaint) NtUserSendMessage(hWnd, WM_PAINT, 0, 0);
907     return TRUE;
908 }
909
910 DWORD STDCALL
911 NtUserQueryWindow(DWORD Unknown0,
912                   DWORD Unknown1)
913 {
914   UNIMPLEMENTED
915
916   return 0;
917 }
918
919 DWORD STDCALL
920 NtUserRealChildWindowFromPoint(DWORD Unknown0,
921                                DWORD Unknown1,
922                                DWORD Unknown2)
923 {
924   UNIMPLEMENTED
925
926   return 0;
927 }
928
929 NTSTATUS STDCALL
930 NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags)
931 {
932   RECT SafeUpdateRect;
933   NTSTATUS Status;
934
935   if (NULL != lprcUpdate)
936     {
937       Status = MmCopyFromCaller(&SafeUpdateRect, lprcUpdate, sizeof(RECT));
938       if (! NT_SUCCESS(Status))
939         {
940           return Status;
941         }
942     }
943
944   return PaintRedrawWindow(hWnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect, hrgnUpdate,
945                            flags, 0) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;
946 ;
947 }
948
949 UINT STDCALL
950 NtUserRegisterWindowMessage(LPCWSTR MessageName)
951 {
952   UNIMPLEMENTED
953
954   return(0);
955 }
956
957 DWORD STDCALL
958 NtUserScrollWindowEx(DWORD Unknown0,
959                      DWORD Unknown1,
960                      DWORD Unknown2,
961                      DWORD Unknown3,
962                      DWORD Unknown4,
963                      DWORD Unknown5,
964                      DWORD Unknown6,
965                      DWORD Unknown7)
966 {
967   UNIMPLEMENTED
968
969   return 0;
970 }
971
972 DWORD STDCALL
973 NtUserSetActiveWindow(DWORD Unknown0)
974 {
975   UNIMPLEMENTED
976
977   return 0;
978 }
979
980 DWORD STDCALL
981 NtUserSetImeOwnerWindow(DWORD Unknown0,
982                         DWORD Unknown1)
983 {
984   UNIMPLEMENTED
985
986   return 0;
987 }
988
989 DWORD STDCALL
990 NtUserSetInternalWindowPos(DWORD Unknown0,
991                            DWORD Unknown1,
992                            DWORD Unknown2,
993                            DWORD Unknown3)
994 {
995   UNIMPLEMENTED
996
997   return 0;
998
999 }
1000
1001 DWORD STDCALL
1002 NtUserSetLayeredWindowAttributes(DWORD Unknown0,
1003                                  DWORD Unknown1,
1004                                  DWORD Unknown2,
1005                                  DWORD Unknown3)
1006 {
1007   UNIMPLEMENTED
1008
1009   return 0;
1010 }
1011
1012 DWORD STDCALL
1013 NtUserSetLogonNotifyWindow(DWORD Unknown0)
1014 {
1015   UNIMPLEMENTED
1016
1017   return 0;
1018 }
1019
1020 DWORD STDCALL
1021 NtUserSetShellWindowEx(DWORD Unknown0,
1022                        DWORD Unknown1)
1023 {
1024   UNIMPLEMENTED
1025
1026   return 0;
1027 }
1028
1029 DWORD STDCALL
1030 NtUserSetWindowFNID(DWORD Unknown0,
1031                     DWORD Unknown1)
1032 {
1033   UNIMPLEMENTED
1034
1035   return 0;
1036 }
1037
1038 DWORD STDCALL
1039 NtUserGetWindowLong(HWND hWnd, DWORD Index)
1040 {
1041   PWINDOW_OBJECT WindowObject;
1042   NTSTATUS Status;
1043   DWORD Result;
1044
1045   W32kGuiCheck();
1046
1047   Status = 
1048     ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
1049                                hWnd,
1050                                otWindow,
1051                                (PVOID*)&WindowObject);
1052   if (!NT_SUCCESS(Status))
1053     {
1054       return(0);
1055     }
1056
1057   switch (Index)
1058     {
1059     case GWL_EXSTYLE:
1060       {
1061         Result = (DWORD)WindowObject->ExStyle;
1062         break;
1063       }
1064
1065     case GWL_STYLE:
1066       {
1067         Result = (DWORD)WindowObject->Style;
1068         break;
1069       }
1070
1071     case GWL_WNDPROC:
1072       {
1073         Result = (DWORD)WindowObject->Class->Class.lpfnWndProc; 
1074         break;
1075       }
1076     case GWL_ID:
1077     break;
1078     
1079     default:
1080       {
1081         DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
1082         Result = 0;
1083         break;
1084       }
1085     }
1086
1087   ObmDereferenceObject(WindowObject);
1088   return(Result);
1089 }
1090
1091 DWORD STDCALL
1092 NtUserSetWindowLong(DWORD Unknown0,
1093                     DWORD Unknown1,
1094                     DWORD Unknown2,
1095                     DWORD Unknown3)
1096 {
1097   UNIMPLEMENTED
1098
1099   return 0;
1100 }
1101
1102 DWORD STDCALL
1103 NtUserSetWindowPlacement(DWORD Unknown0,
1104                          DWORD Unknown1)
1105 {
1106   UNIMPLEMENTED
1107
1108   return 0;
1109 }
1110
1111 BOOL 
1112 STDCALL NtUserSetWindowPos(      
1113     HWND hWnd,
1114     HWND hWndInsertAfter,
1115     int X,
1116     int Y,
1117     int cx,
1118     int cy,
1119     UINT uFlags)
1120 {
1121   return WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
1122 }
1123
1124 DWORD STDCALL
1125 NtUserSetWindowRgn(DWORD Unknown0,
1126                    DWORD Unknown1,
1127                    DWORD Unknown2)
1128 {
1129   UNIMPLEMENTED
1130
1131   return 0;
1132 }
1133
1134 DWORD STDCALL
1135 NtUserSetWindowWord(DWORD Unknown0,
1136                     DWORD Unknown1,
1137                     DWORD Unknown2)
1138 {
1139   UNIMPLEMENTED
1140
1141   return 0;
1142 }
1143
1144 BOOL STDCALL
1145 NtUserShowWindow(HWND hWnd,
1146                  LONG nCmdShow)
1147 {
1148   W32kGuiCheck();
1149
1150   return(WinPosShowWindow(hWnd, nCmdShow));
1151 }
1152
1153 DWORD STDCALL
1154 NtUserShowWindowAsync(DWORD Unknown0,
1155                       DWORD Unknown1)
1156 {
1157   UNIMPLEMENTED
1158
1159   return 0;
1160 }
1161
1162 BOOL STDCALL NtUserUpdateWindow( HWND hWnd )
1163 {
1164     PWINDOW_OBJECT pWindow = W32kGetWindowObject( hWnd);
1165
1166     if (!pWindow)
1167         return FALSE;
1168     if (pWindow->UpdateRegion)
1169         NtUserSendMessage( hWnd, WM_PAINT,0,0);
1170     W32kReleaseWindowObject(pWindow);
1171     return TRUE;
1172 }
1173
1174 DWORD STDCALL
1175 NtUserUpdateLayeredWindow(DWORD Unknown0,
1176                           DWORD Unknown1,
1177                           DWORD Unknown2,
1178                           DWORD Unknown3,
1179                           DWORD Unknown4,
1180                           DWORD Unknown5,
1181                           DWORD Unknown6,
1182                           DWORD Unknown7,
1183                           DWORD Unknown8)
1184 {
1185   UNIMPLEMENTED
1186
1187   return 0;
1188 }
1189
1190 DWORD STDCALL
1191 NtUserWindowFromPoint(DWORD Unknown0,
1192                       DWORD Unknown1)
1193 {
1194   UNIMPLEMENTED
1195
1196   return 0;
1197 }
1198
1199 /* EOF */