ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

engwindow.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:         See COPYING in the top level directory
00003  * PROJECT:           ReactOS kernel
00004  * PURPOSE:           GDI WNDOBJ Functions
00005  * FILE:              subsystems/win32/win32k/eng/engwindow.c
00006  * PROGRAMER:         Gregor Anich
00007  */
00008 
00009 /* TODO: Check how the WNDOBJ implementation should behave with a driver on windows.
00010  */
00011 
00012 #include <win32k.h>
00013 
00014 #define NDEBUG
00015 #include <debug.h>
00016 
00017 INT gcountPWO = 0;
00018 
00019 /*
00020  * Calls the WNDOBJCHANGEPROC of the given WNDOBJ
00021  */
00022 VOID
00023 FASTCALL
00024 IntEngWndCallChangeProc(
00025   IN WNDOBJ *pwo,
00026   IN FLONG   flChanged)
00027 {
00028   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
00029 
00030   if (WndObjInt->ChangeProc == NULL)
00031     {
00032       return;
00033     }
00034 
00035   /* check flags of the WNDOBJ */
00036   flChanged &= WndObjInt->Flags;
00037   if (flChanged == 0)
00038     {
00039       return;
00040     }
00041 
00042   /* Call the WNDOBJCHANGEPROC */
00043   if (flChanged == WOC_CHANGED)
00044     {
00045       pwo = NULL;
00046     }
00047 
00048   DPRINT("Calling WNDOBJCHANGEPROC (0x%x), Changed = 0x%x\n",
00049          WndObjInt->ChangeProc, flChanged);
00050   WndObjInt->ChangeProc(pwo, flChanged);
00051 }
00052 
00053 /*
00054  * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
00055  */
00056 BOOLEAN
00057 FASTCALL
00058 IntEngWndUpdateClipObj(
00059   WNDGDI *WndObjInt,
00060   PWND Window)
00061 {
00062   HRGN hVisRgn;
00063   PROSRGNDATA visRgn;
00064   CLIPOBJ *ClipObj = NULL;
00065   CLIPOBJ *OldClipObj;
00066 
00067   DPRINT("IntEngWndUpdateClipObj\n");
00068 
00069   hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
00070   if (hVisRgn != NULL)
00071   {
00072     NtGdiOffsetRgn(hVisRgn, Window->rcClient.left, Window->rcClient.top);
00073     visRgn = RGNOBJAPI_Lock(hVisRgn, NULL);
00074     if (visRgn != NULL)
00075     {
00076       if (visRgn->rdh.nCount > 0)
00077       {
00078         ClipObj = IntEngCreateClipRegion(visRgn->rdh.nCount, visRgn->Buffer,
00079                                          &visRgn->rdh.rcBound);
00080         DPRINT("Created visible region with %d rects\n", visRgn->rdh.nCount);
00081         DPRINT("  BoundingRect: %d, %d  %d, %d\n",
00082                visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
00083                visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
00084         {
00085           ULONG i;
00086           for (i = 0; i < visRgn->rdh.nCount; i++)
00087           {
00088             DPRINT("  Rect #%d: %d,%d  %d,%d\n", i+1,
00089                    visRgn->Buffer[i].left, visRgn->Buffer[i].top,
00090                    visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
00091           }
00092         }
00093       }
00094       RGNOBJAPI_Unlock(visRgn);
00095     }
00096     else
00097     {
00098       DPRINT1("Warning: Couldn't lock visible region of window DC\n");
00099     }
00100     GreDeleteObject(hVisRgn);
00101   }
00102   else
00103   {
00104     DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");
00105   }
00106 
00107   if (ClipObj == NULL)
00108   {
00109     /* Fall back to client rect */
00110     ClipObj = IntEngCreateClipRegion(1, &Window->rcClient,
00111                                      &Window->rcClient);
00112   }
00113 
00114   if (ClipObj == NULL)
00115   {
00116     DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");
00117     return FALSE;
00118   }
00119 
00120   RtlCopyMemory(&WndObjInt->WndObj.coClient, ClipObj, sizeof (CLIPOBJ));
00121   RtlCopyMemory(&WndObjInt->WndObj.rclClient, &Window->rcClient, sizeof (RECT));
00122   OldClipObj = InterlockedExchangePointer((PVOID*)&WndObjInt->ClientClipObj, ClipObj);
00123   if (OldClipObj != NULL)
00124     IntEngDeleteClipRegion(OldClipObj);
00125 
00126   return TRUE;
00127 }
00128 
00129 /*
00130  * Updates all WNDOBJs of the given WND and calls the change-procs.
00131  */
00132 VOID
00133 FASTCALL
00134 IntEngWindowChanged(
00135   PWND  Window,
00136   FLONG           flChanged)
00137 {
00138   PPROPERTY pprop;
00139   WNDGDI *Current;
00140   HWND hWnd;
00141 
00142   ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL);
00143 
00144   hWnd = Window->head.h;
00145   pprop = IntGetProp(Window, AtomWndObj);
00146   if (!pprop)
00147   {
00148      return;
00149   }
00150   Current = (WNDGDI *)pprop->Data;
00151   if ( gcountPWO &&
00152        Current &&
00153        Current->Hwnd == hWnd &&
00154        Current->WndObj.pvConsumer != NULL )
00155   {
00156      /* Update the WNDOBJ */
00157      switch (flChanged)
00158      {
00159         case WOC_RGN_CLIENT:
00160         /* Update the clipobj and client rect of the WNDOBJ */
00161            IntEngWndUpdateClipObj(Current, Window);
00162            break;
00163 
00164         case WOC_DELETE:
00165         /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
00166            break;
00167      }
00168 
00169      /* Call the change proc */
00170      IntEngWndCallChangeProc(&Current->WndObj, flChanged);
00171 
00172      /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
00173      if (flChanged == WOC_RGN_CLIENT)
00174      {
00175         IntEngWndCallChangeProc(&Current->WndObj, WOC_CHANGED);
00176      }
00177   }
00178 }
00179 
00180 /*
00181  * @implemented
00182  */
00183 WNDOBJ*
00184 APIENTRY
00185 EngCreateWnd(
00186   SURFOBJ          *pso,
00187   HWND              hWnd,
00188   WNDOBJCHANGEPROC  pfn,
00189   FLONG             fl,
00190   int               iPixelFormat)
00191 {
00192   WNDGDI *WndObjInt = NULL;
00193   WNDOBJ *WndObjUser = NULL;
00194   PWND Window;
00195   BOOL calledFromUser;
00196   DECLARE_RETURN(WNDOBJ*);
00197 
00198   DPRINT("EngCreateWnd: pso = 0x%x, hwnd = 0x%x, pfn = 0x%x, fl = 0x%x, pixfmt = %d\n",
00199          pso, hWnd, pfn, fl, iPixelFormat);
00200 
00201   calledFromUser = UserIsEntered();
00202   if (!calledFromUser){
00203      UserEnterShared();
00204   }
00205 
00206   /* Get window object */
00207   Window = UserGetWindowObject(hWnd);
00208   if (Window == NULL)
00209     {
00210       RETURN( NULL);
00211     }
00212 
00213   /* Create WNDOBJ */
00214   WndObjInt = EngAllocMem(0, sizeof (WNDGDI), GDITAG_WNDOBJ);
00215   if (WndObjInt == NULL)
00216     {
00217       DPRINT1("Failed to allocate memory for a WND structure!\n");
00218       RETURN( NULL);
00219     }
00220 
00221   /* Fill the clipobj */
00222   WndObjInt->ClientClipObj = NULL;
00223   if (!IntEngWndUpdateClipObj(WndObjInt, Window))
00224     {
00225       EngFreeMem(WndObjInt);
00226       RETURN( NULL);
00227     }
00228 
00229   /* Fill user object */
00230   WndObjUser = GDIToObj(WndObjInt, WND);
00231   WndObjUser->psoOwner = pso;
00232   WndObjUser->pvConsumer = NULL;
00233 
00234   /* Fill internal object */
00235   WndObjInt->Hwnd = hWnd;
00236   WndObjInt->ChangeProc = pfn;
00237   WndObjInt->Flags = fl;
00238   WndObjInt->PixelFormat = iPixelFormat;
00239 
00240   /* associate object with window */
00241   IntSetProp(Window, AtomWndObj, WndObjInt);
00242   ++gcountPWO;
00243 
00244   DPRINT("EngCreateWnd: SUCCESS!\n");
00245 
00246   RETURN( WndObjUser);
00247 
00248 CLEANUP:
00249 
00250   if (!calledFromUser){
00251     UserLeave();
00252   }
00253 
00254   END_CLEANUP;
00255 }
00256 
00257 
00258 /*
00259  * @implemented
00260  */
00261 VOID
00262 APIENTRY
00263 EngDeleteWnd(
00264   IN WNDOBJ *pwo)
00265 {
00266   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
00267   PWND Window;
00268   BOOL calledFromUser;
00269 
00270   DPRINT("EngDeleteWnd: pwo = 0x%x\n", pwo);
00271 
00272   calledFromUser = UserIsEntered();
00273   if (!calledFromUser){
00274      UserEnterExclusive();
00275   }
00276 
00277   /* Get window object */
00278   Window = UserGetWindowObject(WndObjInt->Hwnd);
00279   if (Window == NULL)
00280   {
00281      DPRINT1("Warning: Couldnt get window object for WndObjInt->Hwnd!!!\n");
00282   }
00283   else
00284   {
00285     /* Remove object from window */
00286     IntRemoveProp(Window, AtomWndObj);
00287     --gcountPWO;
00288   }
00289 
00290   if (!calledFromUser){
00291      UserLeave();
00292   }
00293 
00294   /* Free resources */
00295   IntEngDeleteClipRegion(WndObjInt->ClientClipObj);
00296   EngFreeMem(WndObjInt);
00297 }
00298 
00299 
00300 /*
00301  * @implemented
00302  */
00303 BOOL
00304 APIENTRY
00305 WNDOBJ_bEnum(
00306   IN WNDOBJ  *pwo,
00307   IN ULONG  cj,
00308   OUT ULONG  *pul)
00309 {
00310   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
00311   BOOL Ret;
00312 
00313   DPRINT("WNDOBJ_bEnum: pwo = 0x%x, cj = %d, pul = 0x%x\n", pwo, cj, pul);
00314   Ret = CLIPOBJ_bEnum(WndObjInt->ClientClipObj, cj, pul);
00315 
00316   DPRINT("WNDOBJ_bEnum: Returning %s\n", Ret ? "True" : "False");
00317   return Ret;
00318 }
00319 
00320 
00321 /*
00322  * @implemented
00323  */
00324 ULONG
00325 APIENTRY
00326 WNDOBJ_cEnumStart(
00327   IN WNDOBJ  *pwo,
00328   IN ULONG  iType,
00329   IN ULONG  iDirection,
00330   IN ULONG  cLimit)
00331 {
00332   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
00333   ULONG Ret;
00334 
00335   DPRINT("WNDOBJ_cEnumStart: pwo = 0x%x, iType = %d, iDirection = %d, cLimit = %d\n",
00336          pwo, iType, iDirection, cLimit);
00337 
00338   /* FIXME: Should we enumerate all rectangles or not? */
00339   Ret = CLIPOBJ_cEnumStart(WndObjInt->ClientClipObj, FALSE, iType, iDirection, cLimit);
00340 
00341   DPRINT("WNDOBJ_cEnumStart: Returning 0x%x\n", Ret);
00342   return Ret;
00343 }
00344 
00345 
00346 /*
00347  * @implemented
00348  */
00349 VOID
00350 APIENTRY
00351 WNDOBJ_vSetConsumer(
00352   IN WNDOBJ  *pwo,
00353   IN PVOID  pvConsumer)
00354 {
00355   BOOL Hack;
00356 
00357   DPRINT("WNDOBJ_vSetConsumer: pwo = 0x%x, pvConsumer = 0x%x\n", pwo, pvConsumer);
00358 
00359   Hack = (pwo->pvConsumer == NULL);
00360   pwo->pvConsumer = pvConsumer;
00361 
00362   /* HACKHACKHACK
00363    *
00364    * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
00365    * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
00366    * in the callback to identify the WNDOBJ I think.
00367    *
00368    *  - blight
00369    */
00370   if (Hack)
00371     {
00372       IntEngWndCallChangeProc(pwo, WOC_RGN_CLIENT);
00373       IntEngWndCallChangeProc(pwo, WOC_CHANGED);
00374       IntEngWndCallChangeProc(pwo, WOC_DRAWN);
00375     }
00376 }
00377 
00378 /* EOF */
00379 

Generated on Sat May 26 2012 04:37:08 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.