Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenengwindow.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
1.7.6.1
|