Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendclife.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * PURPOSE: Functions for creation and destruction of DCs 00005 * FILE: subsystem/win32/win32k/objects/dclife.c 00006 * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org) 00007 */ 00008 00009 #include <win32k.h> 00010 00011 #define NDEBUG 00012 #include <debug.h> 00013 00014 // FIXME: Windows uses 0x0012009f 00015 #define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL 00016 00017 PSURFACE psurfDefaultBitmap = NULL; 00018 PBRUSH pbrDefaultBrush = NULL; 00019 00020 static const MATRIX gmxWorldToDeviceDefault = 00021 { 00022 FLOATOBJ_16, FLOATOBJ_0, 00023 FLOATOBJ_0, FLOATOBJ_16, 00024 FLOATOBJ_0, FLOATOBJ_0, 00025 0, 0, 0x4b 00026 }; 00027 00028 static const MATRIX gmxDeviceToWorldDefault = 00029 { 00030 FLOATOBJ_1_16, FLOATOBJ_0, 00031 FLOATOBJ_0, FLOATOBJ_1_16, 00032 FLOATOBJ_0, FLOATOBJ_0, 00033 0, 0, 0x53 00034 }; 00035 00036 static const MATRIX gmxWorldToPageDefault = 00037 { 00038 FLOATOBJ_1, FLOATOBJ_0, 00039 FLOATOBJ_0, FLOATOBJ_1, 00040 FLOATOBJ_0, FLOATOBJ_0, 00041 0, 0, 0x63 00042 }; 00043 00044 // HACK!! Fix XFORMOBJ then use 1:16 / 16:1 00045 #define gmxWorldToDeviceDefault gmxWorldToPageDefault 00046 #define gmxDeviceToWorldDefault gmxWorldToPageDefault 00047 00050 INIT_FUNCTION 00051 NTSTATUS 00052 NTAPI 00053 InitDcImpl() 00054 { 00055 psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]); 00056 if (!psurfDefaultBitmap) 00057 return STATUS_UNSUCCESSFUL; 00058 00059 pbrDefaultBrush = BRUSH_ShareLockBrush(StockObjects[BLACK_BRUSH]); 00060 if (!pbrDefaultBrush) 00061 return STATUS_UNSUCCESSFUL; 00062 00063 return STATUS_SUCCESS; 00064 } 00065 00066 00067 PDC 00068 NTAPI 00069 DC_AllocDcWithHandle() 00070 { 00071 PDC pdc; 00072 00073 pdc = (PDC)GDIOBJ_AllocateObject(GDIObjType_DC_TYPE, 00074 sizeof(DC), 00075 BASEFLAG_LOOKASIDE); 00076 if (!pdc) 00077 { 00078 DPRINT1("Could not allocate a DC.\n"); 00079 return NULL; 00080 } 00081 00082 if (!GDIOBJ_hInsertObject(&pdc->BaseObject, GDI_OBJ_HMGR_POWNED)) 00083 { 00084 DPRINT1("Could not insert DC into handle table.\n"); 00085 GDIOBJ_vFreeObject(&pdc->BaseObject); 00086 return NULL; 00087 } 00088 00089 pdc->pdcattr = &pdc->dcattr; 00090 00091 return pdc; 00092 } 00093 00094 00095 void 00096 DC_InitHack(PDC pdc) 00097 { 00098 HRGN hVisRgn; 00099 00100 TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL); 00101 pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0); 00102 00103 /* This should never fail */ 00104 ASSERT(pdc->dclevel.ppal); 00105 00106 /* Select regions */ 00107 pdc->rosdc.hClipRgn = NULL; 00108 pdc->rosdc.hGCClipRgn = NULL; 00109 00110 hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1); 00111 ASSERT(hVisRgn); 00112 GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn); 00113 GreDeleteObject(hVisRgn); 00114 } 00115 00116 VOID 00117 NTAPI 00118 DC_vInitDc( 00119 PDC pdc, 00120 DCTYPE dctype, 00121 PPDEVOBJ ppdev) 00122 { 00123 /* Setup some basic fields */ 00124 pdc->dctype = dctype; 00125 pdc->ppdev = ppdev; 00126 pdc->dhpdev = ppdev->dhpdev; 00127 pdc->hsem = ppdev->hsemDevLock; 00128 pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps; 00129 pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2; 00130 pdc->fs = DC_DIRTY_RAO; 00131 00132 /* Setup dc attribute */ 00133 pdc->pdcattr = &pdc->dcattr; 00134 pdc->dcattr.pvLDC = NULL; 00135 pdc->dcattr.ulDirty_ = DIRTY_DEFAULT; 00136 if (ppdev == gppdevPrimary) 00137 pdc->dcattr.ulDirty_ |= DC_PRIMARY_DISPLAY; 00138 00139 /* Setup the DC size */ 00140 if (dctype == DCTYPE_MEMORY) 00141 { 00142 /* Memory DCs have a 1 x 1 bitmap by default */ 00143 pdc->dclevel.sizl.cx = 1; 00144 pdc->dclevel.sizl.cy = 1; 00145 } 00146 else 00147 { 00148 /* Other DC's are as big as the related PDEV */ 00149 pdc->dclevel.sizl.cx = ppdev->gdiinfo.ulHorzRes; 00150 pdc->dclevel.sizl.cy = ppdev->gdiinfo.ulVertRes; 00151 } 00152 00153 /* Setup Window rect based on DC size */ 00154 pdc->erclWindow.left = 0; 00155 pdc->erclWindow.top = 0; 00156 pdc->erclWindow.right = pdc->dclevel.sizl.cx; 00157 pdc->erclWindow.bottom = pdc->dclevel.sizl.cy; 00158 00159 if (dctype == DCTYPE_DIRECT) 00160 { 00161 /* Direct DCs get the surface from the PDEV */ 00162 pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev); 00163 00164 pdc->erclBounds.left = 0x7fffffff; 00165 pdc->erclBounds.top = 0x7fffffff; 00166 pdc->erclBounds.right = 0x80000000; 00167 pdc->erclBounds.bottom = 0x80000000; 00168 pdc->erclBoundsApp.left = 0xffffffff; 00169 pdc->erclBoundsApp.top = 0xfffffffc; 00170 pdc->erclBoundsApp.right = 0x00007ffc; // FIXME 00171 pdc->erclBoundsApp.bottom = 0x00000333; // FIXME 00172 pdc->erclClip = pdc->erclBounds; 00173 // pdc->co 00174 00175 pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY; 00176 } 00177 else 00178 { 00179 /* Non-direct DCs don't have a surface by default */ 00180 pdc->dclevel.pSurface = NULL; 00181 00182 // FIXME: HACK, because our code expects a surface 00183 pdc->dclevel.pSurface = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]); 00184 00185 pdc->erclBounds.left = 0; 00186 pdc->erclBounds.top = 0; 00187 pdc->erclBounds.right = 0; 00188 pdc->erclBounds.bottom = 0; 00189 pdc->erclBoundsApp = pdc->erclBounds; 00190 pdc->erclClip = pdc->erclWindow; 00191 //pdc->co = NULL 00192 } 00193 00194 //pdc->dcattr.VisRectRegion: 00195 00196 /* Setup coordinate transformation data */ 00197 pdc->dclevel.mxWorldToDevice = gmxWorldToDeviceDefault; 00198 pdc->dclevel.mxDeviceToWorld = gmxDeviceToWorldDefault; 00199 pdc->dclevel.mxWorldToPage = gmxWorldToPageDefault; 00200 pdc->dclevel.efM11PtoD = gef16; 00201 pdc->dclevel.efM22PtoD = gef16; 00202 pdc->dclevel.efDxPtoD = gef0; 00203 pdc->dclevel.efDyPtoD = gef0; 00204 pdc->dclevel.efM11_TWIPS = gef0; 00205 pdc->dclevel.efM22_TWIPS = gef0; 00206 pdc->dclevel.efPr11 = gef0; 00207 pdc->dclevel.efPr22 = gef0; 00208 pdc->dcattr.mxWorldToDevice = pdc->dclevel.mxWorldToDevice; 00209 pdc->dcattr.mxDeviceToWorld = pdc->dclevel.mxDeviceToWorld; 00210 pdc->dcattr.mxWorldToPage = pdc->dclevel.mxWorldToPage; 00211 pdc->dcattr.efM11PtoD = pdc->dclevel.efM11PtoD; 00212 pdc->dcattr.efM22PtoD = pdc->dclevel.efM22PtoD; 00213 pdc->dcattr.efDxPtoD = pdc->dclevel.efDxPtoD; 00214 pdc->dcattr.efDyPtoD = pdc->dclevel.efDyPtoD; 00215 pdc->dcattr.iMapMode = MM_TEXT; 00216 pdc->dcattr.dwLayout = 0; 00217 pdc->dcattr.flXform = PAGE_TO_DEVICE_SCALE_IDENTITY | 00218 PAGE_TO_DEVICE_IDENTITY | 00219 WORLD_TO_PAGE_IDENTITY; 00220 00221 /* Setup more coordinates */ 00222 pdc->ptlDCOrig.x = 0; 00223 pdc->ptlDCOrig.y = 0; 00224 pdc->dcattr.lWindowOrgx = 0; 00225 pdc->dcattr.ptlWindowOrg.x = 0; 00226 pdc->dcattr.ptlWindowOrg.y = 0; 00227 pdc->dcattr.szlWindowExt.cx = 1; 00228 pdc->dcattr.szlWindowExt.cy = 1; 00229 pdc->dcattr.ptlViewportOrg.x = 0; 00230 pdc->dcattr.ptlViewportOrg.y = 0; 00231 pdc->dcattr.szlViewportExt.cx = 1; 00232 pdc->dcattr.szlViewportExt.cy = 1; 00233 pdc->dcattr.szlVirtualDevicePixel.cx = ppdev->gdiinfo.ulHorzRes; 00234 pdc->dcattr.szlVirtualDevicePixel.cy = ppdev->gdiinfo.ulVertRes; 00235 pdc->dcattr.szlVirtualDeviceMm.cx = ppdev->gdiinfo.ulHorzSize; 00236 pdc->dcattr.szlVirtualDeviceMm.cy = ppdev->gdiinfo.ulVertSize; 00237 pdc->dcattr.szlVirtualDeviceSize.cx = 0; 00238 pdc->dcattr.szlVirtualDeviceSize.cy = 0; 00239 00240 /* Setup regions */ 00241 pdc->prgnAPI = NULL; 00242 pdc->prgnRao = NULL; 00243 /* Allocate a Vis region */ 00244 pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); 00245 ASSERT(pdc->prgnVis); 00246 00247 /* Setup palette */ 00248 pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE]; 00249 pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal); 00250 00251 /* Setup path */ 00252 pdc->dclevel.hPath = NULL; 00253 pdc->dclevel.flPath = 0; 00254 // pdc->dclevel.lapath: 00255 00256 /* Setup colors */ 00257 pdc->dcattr.crBackgroundClr = RGB(0xff, 0xff, 0xff); 00258 pdc->dcattr.ulBackgroundClr = RGB(0xff, 0xff, 0xff); 00259 pdc->dcattr.crForegroundClr = RGB(0, 0, 0); 00260 pdc->dcattr.ulForegroundClr = RGB(0, 0, 0); 00261 pdc->dcattr.crBrushClr = RGB(0xff, 0xff, 0xff); 00262 pdc->dcattr.ulBrushClr = RGB(0xff, 0xff, 0xff); 00263 pdc->dcattr.crPenClr = RGB(0, 0, 0); 00264 pdc->dcattr.ulPenClr = RGB(0, 0, 0); 00265 00266 /* Select the default fill and line brush */ 00267 pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH]; 00268 pdc->dcattr.hpen = StockObjects[BLACK_PEN]; 00269 pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush); 00270 pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen); 00271 pdc->dclevel.ptlBrushOrigin.x = 0; 00272 pdc->dclevel.ptlBrushOrigin.y = 0; 00273 pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin; 00274 00275 /* Initialize EBRUSHOBJs */ 00276 EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc); 00277 EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc); 00278 EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc); 00279 EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc); 00280 00281 /* Setup fill data */ 00282 pdc->dcattr.jROP2 = R2_COPYPEN; 00283 pdc->dcattr.jBkMode = 2; 00284 pdc->dcattr.lBkMode = 2; 00285 pdc->dcattr.jFillMode = ALTERNATE; 00286 pdc->dcattr.lFillMode = 1; 00287 pdc->dcattr.jStretchBltMode = 1; 00288 pdc->dcattr.lStretchBltMode = 1; 00289 pdc->ptlFillOrigin.x = 0; 00290 pdc->ptlFillOrigin.y = 0; 00291 00292 /* Setup drawing position */ 00293 pdc->dcattr.ptlCurrent.x = 0; 00294 pdc->dcattr.ptlCurrent.y = 0; 00295 pdc->dcattr.ptfxCurrent.x = 0; 00296 pdc->dcattr.ptfxCurrent.y = 0; 00297 00298 /* Setup ICM data */ 00299 pdc->dclevel.lIcmMode = 0; 00300 pdc->dcattr.lIcmMode = 0; 00301 pdc->dcattr.hcmXform = NULL; 00302 pdc->dcattr.flIcmFlags = 0; 00303 pdc->dcattr.IcmBrushColor = CLR_INVALID; 00304 pdc->dcattr.IcmPenColor = CLR_INVALID; 00305 pdc->dcattr.pvLIcm = NULL; 00306 pdc->dcattr.hColorSpace = NULL; // FIXME: 0189001f 00307 pdc->dclevel.pColorSpace = NULL; // FIXME 00308 pdc->pClrxFormLnk = NULL; 00309 // pdc->dclevel.ca = 00310 00311 /* Setup font data */ 00312 pdc->hlfntCur = NULL; // FIXME: 2f0a0cf8 00313 pdc->pPFFList = NULL; 00314 pdc->flSimulationFlags = 0; 00315 pdc->lEscapement = 0; 00316 pdc->prfnt = NULL; 00317 pdc->dcattr.flFontMapper = 0; 00318 pdc->dcattr.flTextAlign = 0; 00319 pdc->dcattr.lTextAlign = 0; 00320 pdc->dcattr.lTextExtra = 0; 00321 pdc->dcattr.lRelAbs = 1; 00322 pdc->dcattr.lBreakExtra = 0; 00323 pdc->dcattr.cBreak = 0; 00324 pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT]; 00325 // pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew); 00326 00327 /* Other stuff */ 00328 pdc->hdcNext = NULL; 00329 pdc->hdcPrev = NULL; 00330 pdc->ipfdDevMax = 0x0000ffff; 00331 pdc->ulCopyCount = -1; 00332 pdc->ptlDoBanding.x = 0; 00333 pdc->ptlDoBanding.y = 0; 00334 pdc->dclevel.lSaveDepth = 1; 00335 pdc->dclevel.hdcSave = NULL; 00336 pdc->dcattr.iGraphicsMode = GM_COMPATIBLE; 00337 pdc->dcattr.iCS_CP = 0; 00338 pdc->pSurfInfo = NULL; 00339 00340 if (defaultDCstate == NULL) 00341 { 00342 defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC); 00343 RtlZeroMemory(defaultDCstate, sizeof(DC)); 00344 defaultDCstate->pdcattr = &defaultDCstate->dcattr; 00345 DC_vCopyState(pdc, defaultDCstate, TRUE); 00346 } 00347 } 00348 00349 BOOL 00350 NTAPI 00351 DC_Cleanup(PVOID ObjectBody) 00352 { 00353 PDC pdc = (PDC)ObjectBody; 00354 00355 /* Free DC_ATTR */ 00356 DC_vFreeDcAttr(pdc); 00357 00358 /* Delete saved DCs */ 00359 DC_vRestoreDC(pdc, 1); 00360 00361 /* Deselect dc objects */ 00362 DC_vSelectSurface(pdc, NULL); 00363 DC_vSelectFillBrush(pdc, NULL); 00364 DC_vSelectLineBrush(pdc, NULL); 00365 DC_vSelectPalette(pdc, NULL); 00366 00367 /* Cleanup the dc brushes */ 00368 EBRUSHOBJ_vCleanup(&pdc->eboFill); 00369 EBRUSHOBJ_vCleanup(&pdc->eboLine); 00370 EBRUSHOBJ_vCleanup(&pdc->eboText); 00371 EBRUSHOBJ_vCleanup(&pdc->eboBackground); 00372 00373 /* Free regions */ 00374 if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn)) 00375 GreDeleteObject(pdc->rosdc.hClipRgn); 00376 if (pdc->prgnVis) 00377 { 00378 REGION_Delete(pdc->prgnVis); 00379 } 00380 if (pdc->rosdc.hGCClipRgn && GreIsHandleValid(pdc->rosdc.hGCClipRgn)) 00381 { 00382 GreDeleteObject(pdc->rosdc.hGCClipRgn); 00383 } 00384 if (NULL != pdc->rosdc.CombinedClip) 00385 IntEngDeleteClipRegion(pdc->rosdc.CombinedClip); 00386 00387 PATH_Delete(pdc->dclevel.hPath); 00388 00389 if(pdc->dclevel.pSurface) 00390 SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); 00391 00392 PDEVOBJ_vRelease(pdc->ppdev) ; 00393 00394 return TRUE; 00395 } 00396 00397 VOID 00398 NTAPI 00399 DC_vSetOwner(PDC pdc, ULONG ulOwner) 00400 { 00401 00402 if (pdc->rosdc.hClipRgn) 00403 { 00404 IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner); 00405 } 00406 00407 if (pdc->rosdc.hGCClipRgn) 00408 { 00409 IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner); 00410 } 00411 00412 if (pdc->dclevel.hPath) 00413 { 00414 GreSetObjectOwner(pdc->dclevel.hPath, ulOwner); 00415 } 00416 00417 /* Dereference current brush and pen */ 00418 BRUSH_ShareUnlockBrush(pdc->dclevel.pbrFill); 00419 BRUSH_ShareUnlockBrush(pdc->dclevel.pbrLine); 00420 00421 /* Select the default fill and line brush */ 00422 pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH]; 00423 pdc->dcattr.hpen = StockObjects[BLACK_PEN]; 00424 pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush); 00425 pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen); 00426 00427 /* Update the EBRUSHOBJs */ 00428 EBRUSHOBJ_vUpdate(&pdc->eboFill, pdc->dclevel.pbrFill, pdc); 00429 EBRUSHOBJ_vUpdate(&pdc->eboLine, pdc->dclevel.pbrLine, pdc); 00430 00431 /* Allocate or free DC attribute */ 00432 if (ulOwner == GDI_OBJ_HMGR_PUBLIC || ulOwner == GDI_OBJ_HMGR_NONE) 00433 { 00434 if (pdc->pdcattr != &pdc->dcattr) 00435 DC_vFreeDcAttr(pdc); 00436 } 00437 else if (ulOwner == GDI_OBJ_HMGR_POWNED) 00438 { 00439 if (pdc->pdcattr == &pdc->dcattr) 00440 DC_bAllocDcAttr(pdc); 00441 } 00442 00443 /* Set the DC's ownership */ 00444 GDIOBJ_vSetObjectOwner(&pdc->BaseObject, ulOwner); 00445 } 00446 00447 BOOL 00448 NTAPI 00449 GreSetDCOwner(HDC hdc, ULONG ulOwner) 00450 { 00451 PDC pdc; 00452 00453 pdc = DC_LockDc(hdc); 00454 if (!pdc) 00455 { 00456 DPRINT1("GreSetDCOwner: Could not lock DC\n"); 00457 return FALSE; 00458 } 00459 00460 /* Call the internal DC function */ 00461 DC_vSetOwner(pdc, ulOwner); 00462 00463 DC_UnlockDc(pdc); 00464 return TRUE; 00465 } 00466 00467 static 00468 void 00469 DC_vUpdateDC(PDC pdc) 00470 { 00471 HRGN hVisRgn ; 00472 PPDEVOBJ ppdev = pdc->ppdev ; 00473 00474 pdc->dhpdev = ppdev->dhpdev; 00475 00476 SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); 00477 pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev); 00478 00479 PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl); 00480 hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); 00481 ASSERT(hVisRgn); 00482 GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn); 00483 GreDeleteObject(hVisRgn); 00484 00485 pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps; 00486 pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2; 00487 00488 /* Mark EBRUSHOBJs as dirty */ 00489 pdc->pdcattr->ulDirty_ |= DIRTY_DEFAULT ; 00490 } 00491 00492 /* Prepare a blit for up to 2 DCs */ 00493 /* rc1 and rc2 are the rectangles where we want to draw or 00494 * from where we take pixels. */ 00495 VOID 00496 FASTCALL 00497 DC_vPrepareDCsForBlit(PDC pdc1, 00498 RECT rc1, 00499 PDC pdc2, 00500 RECT rc2) 00501 { 00502 PDC pdcFirst, pdcSecond; 00503 PRECT prcFirst, prcSecond; 00504 00505 /* Update brushes */ 00506 if (pdc1->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) 00507 DC_vUpdateFillBrush(pdc1); 00508 if (pdc1->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) 00509 DC_vUpdateLineBrush(pdc1); 00510 if(pdc1->pdcattr->ulDirty_ & DIRTY_TEXT) 00511 DC_vUpdateTextBrush(pdc1); 00512 00513 /* Lock them in good order */ 00514 if(pdc2) 00515 { 00516 if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock) 00517 { 00518 pdcFirst = pdc1; 00519 prcFirst = &rc1; 00520 pdcSecond = pdc2; 00521 prcSecond = &rc2; 00522 } 00523 else 00524 { 00525 pdcFirst = pdc2; 00526 prcFirst = &rc2; 00527 pdcSecond = pdc1; 00528 prcSecond = &rc1; 00529 } 00530 } 00531 else 00532 { 00533 pdcFirst = pdc1 ; 00534 prcFirst = &rc1; 00535 pdcSecond = NULL; 00536 prcSecond = NULL; 00537 } 00538 00539 if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT) 00540 { 00541 EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock); 00542 MouseSafetyOnDrawStart(pdcFirst->ppdev, 00543 prcFirst->left, 00544 prcFirst->top, 00545 prcFirst->right, 00546 prcFirst->bottom) ; 00547 /* Update surface if needed */ 00548 if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface) 00549 { 00550 DC_vUpdateDC(pdcFirst); 00551 } 00552 } 00553 if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT) 00554 { 00555 EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock); 00556 MouseSafetyOnDrawStart(pdcSecond->ppdev, 00557 prcSecond->left, 00558 prcSecond->top, 00559 prcSecond->right, 00560 prcSecond->bottom) ; 00561 /* Update surface if needed */ 00562 if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface) 00563 { 00564 DC_vUpdateDC(pdcSecond); 00565 } 00566 } 00567 } 00568 00569 /* Finishes a blit for one or two DCs */ 00570 VOID 00571 FASTCALL 00572 DC_vFinishBlit(PDC pdc1, PDC pdc2) 00573 { 00574 if(pdc1->dctype == DCTYPE_DIRECT) 00575 { 00576 MouseSafetyOnDrawEnd(pdc1->ppdev); 00577 EngReleaseSemaphore(pdc1->ppdev->hsemDevLock); 00578 } 00579 00580 if(pdc2) 00581 { 00582 if(pdc2->dctype == DCTYPE_DIRECT) 00583 { 00584 MouseSafetyOnDrawEnd(pdc2->ppdev); 00585 EngReleaseSemaphore(pdc2->ppdev->hsemDevLock); 00586 } 00587 } 00588 } 00589 00590 HDC 00591 NTAPI 00592 GreOpenDCW( 00593 PUNICODE_STRING pustrDevice, 00594 DEVMODEW *pdmInit, 00595 PUNICODE_STRING pustrLogAddr, 00596 ULONG iType, 00597 BOOL bDisplay, 00598 HANDLE hspool, 00599 VOID *pDriverInfo2, 00600 VOID *pUMdhpdev) 00601 { 00602 PPDEVOBJ ppdev; 00603 PDC pdc; 00604 HDC hdc; 00605 00606 DPRINT("GreOpenDCW(%S, iType=%ld)\n", 00607 pustrDevice ? pustrDevice->Buffer : NULL, iType); 00608 00609 /* Get a PDEVOBJ for the device */ 00610 ppdev = EngpGetPDEV(pustrDevice); 00611 if (!ppdev) 00612 { 00613 DPRINT1("Didn't find a suitable PDEV\n"); 00614 return NULL; 00615 } 00616 00617 DPRINT("GreOpenDCW - ppdev = %p\n", ppdev); 00618 00619 pdc = DC_AllocDcWithHandle(); 00620 if (!pdc) 00621 { 00622 DPRINT1("Could not Allocate a DC\n"); 00623 PDEVOBJ_vRelease(ppdev); 00624 return NULL; 00625 } 00626 hdc = pdc->BaseObject.hHmgr; 00627 00628 /* Lock ppdev and initialize the new DC */ 00629 DC_vInitDc(pdc, iType, ppdev); 00630 /* FIXME: HACK! */ 00631 DC_InitHack(pdc); 00632 00633 DC_bAllocDcAttr(pdc); 00634 00635 DC_UnlockDc(pdc); 00636 00637 DPRINT("Returning hdc = %p\n", hdc); 00638 00639 return hdc; 00640 } 00641 00642 HDC 00643 APIENTRY 00644 NtGdiOpenDCW( 00645 PUNICODE_STRING pustrDevice, 00646 DEVMODEW *pdmInit, 00647 PUNICODE_STRING pustrLogAddr, 00648 ULONG iType, 00649 BOOL bDisplay, 00650 HANDLE hspool, 00651 VOID *pDriverInfo2, 00652 VOID *pUMdhpdev) 00653 { 00654 UNICODE_STRING ustrDevice; 00655 WCHAR awcDevice[CCHDEVICENAME]; 00656 DEVMODEW dmInit; 00657 PVOID dhpdev; 00658 HDC hdc; 00659 00660 /* Only if a devicename is given, we need any data */ 00661 if (pustrDevice) 00662 { 00663 /* Initialize destination string */ 00664 RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); 00665 00666 _SEH2_TRY 00667 { 00668 /* Probe the UNICODE_STRING and the buffer */ 00669 ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); 00670 ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); 00671 00672 /* Copy the string */ 00673 RtlCopyUnicodeString(&ustrDevice, pustrDevice); 00674 00675 if (pdmInit) 00676 { 00677 /* FIXME: could be larger */ 00678 ProbeForRead(pdmInit, sizeof(DEVMODEW), 1); 00679 RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW)); 00680 } 00681 00682 if (pUMdhpdev) 00683 { 00684 ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1); 00685 } 00686 } 00687 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00688 { 00689 SetLastNtError(_SEH2_GetExceptionCode()); 00690 _SEH2_YIELD(return NULL); 00691 } 00692 _SEH2_END 00693 } 00694 else 00695 { 00696 pdmInit = NULL; 00697 pUMdhpdev = NULL; 00698 } 00699 00700 /* FIXME: HACK! */ 00701 if (pustrDevice) 00702 { 00703 UNICODE_STRING ustrDISPLAY = RTL_CONSTANT_STRING(L"DISPLAY"); 00704 if (RtlEqualUnicodeString(&ustrDevice, &ustrDISPLAY, TRUE)) 00705 { 00706 pustrDevice = NULL; 00707 } 00708 } 00709 00710 /* Call the internal function */ 00711 hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL, 00712 pdmInit ? &dmInit : NULL, 00713 NULL, // FIXME: pwszLogAddress 00714 iType, 00715 bDisplay, 00716 hspool, 00717 NULL, // FIXME: pDriverInfo2 00718 pUMdhpdev ? &dhpdev : NULL); 00719 00720 /* If we got a HDC and a UM dhpdev is requested,... */ 00721 if (hdc && pUMdhpdev) 00722 { 00723 /* Copy dhpdev to caller (FIXME: use dhpdev?) */ 00724 _SEH2_TRY 00725 { 00726 /* Pointer was already probed */ 00727 *(HANDLE*)pUMdhpdev = dhpdev; 00728 } 00729 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00730 { 00731 /* Ignore error */ 00732 } 00733 _SEH2_END 00734 } 00735 00736 return hdc; 00737 } 00738 00739 00740 HDC 00741 APIENTRY 00742 NtGdiCreateCompatibleDC(HDC hdc) 00743 { 00744 HDC hdcNew; 00745 PPDEVOBJ ppdev; 00746 PDC pdc, pdcNew; 00747 00748 DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc); 00749 00750 /* Did the caller provide a DC? */ 00751 if (hdc) 00752 { 00753 /* Yes, try to lock it */ 00754 pdc = DC_LockDc(hdc); 00755 if (!pdc) 00756 { 00757 DPRINT1("Could not lock source DC %p\n", hdc); 00758 return NULL; 00759 } 00760 00761 /* Get the pdev from the DC */ 00762 ppdev = pdc->ppdev; 00763 InterlockedIncrement(&ppdev->cPdevRefs); 00764 00765 /* Unlock the source DC */ 00766 DC_UnlockDc(pdc); 00767 } 00768 else 00769 { 00770 /* No DC given, get default device */ 00771 ppdev = EngpGetPDEV(NULL); 00772 } 00773 00774 if (!ppdev) 00775 { 00776 DPRINT1("Didn't find a suitable PDEV\n"); 00777 return NULL; 00778 } 00779 00780 /* Allocate a new DC */ 00781 pdcNew = DC_AllocDcWithHandle(); 00782 if (!pdcNew) 00783 { 00784 DPRINT1("Could not allocate a new DC\n"); 00785 PDEVOBJ_vRelease(ppdev); 00786 return NULL; 00787 } 00788 hdcNew = pdcNew->BaseObject.hHmgr; 00789 00790 /* Lock ppdev and initialize the new DC */ 00791 DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev); 00792 /* FIXME: HACK! */ 00793 DC_InitHack(pdcNew); 00794 00795 /* Allocate a dc attribute */ 00796 DC_bAllocDcAttr(pdcNew); 00797 00798 // HACK! 00799 DC_vSelectSurface(pdcNew, psurfDefaultBitmap); 00800 00801 DC_UnlockDc(pdcNew); 00802 00803 DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew); 00804 00805 return hdcNew; 00806 } 00807 00808 BOOL 00809 FASTCALL 00810 IntGdiDeleteDC(HDC hDC, BOOL Force) 00811 { 00812 PDC DCToDelete = DC_LockDc(hDC); 00813 00814 if (DCToDelete == NULL) 00815 { 00816 EngSetLastError(ERROR_INVALID_HANDLE); 00817 return FALSE; 00818 } 00819 00820 if (!Force) 00821 { 00822 /* Windows permits NtGdiDeleteObjectApp to delete a permanent DC 00823 * For some reason, it's still a valid handle, pointing to some kernel data. 00824 * Not sure if this is a bug, a feature, some cache stuff... Who knows? 00825 * See NtGdiDeleteObjectApp test for details */ 00826 if (DCToDelete->fs & DC_FLAG_PERMANENT) 00827 { 00828 DC_UnlockDc(DCToDelete); 00829 if(UserReleaseDC(NULL, hDC, FALSE)) 00830 { 00831 /* ReactOS feature: Call UserReleaseDC 00832 * I don't think Windows does it. 00833 * Still, complain, no one should ever call DeleteDC 00834 * on a window DC */ 00835 DPRINT1("No, you naughty application!\n"); 00836 return TRUE; 00837 } 00838 else 00839 { 00840 /* This is not a window owned DC. 00841 * Force its deletion */ 00842 return IntGdiDeleteDC(hDC, TRUE); 00843 } 00844 } 00845 } 00846 00847 DC_UnlockDc(DCToDelete); 00848 00849 if (GreIsHandleValid(hDC)) 00850 { 00851 if (!GreDeleteObject(hDC)) 00852 { 00853 DPRINT1("DC_FreeDC failed\n"); 00854 } 00855 } 00856 else 00857 { 00858 DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC); 00859 } 00860 00861 return TRUE; 00862 } 00863 00864 BOOL 00865 APIENTRY 00866 NtGdiDeleteObjectApp(HANDLE hobj) 00867 { 00868 /* Complete all pending operations */ 00869 NtGdiFlushUserBatch(); // FIXME: We shouldn't need this 00870 00871 if (GDI_HANDLE_IS_STOCKOBJ(hobj)) return TRUE; 00872 00873 if (GreGetObjectOwner(hobj) != GDI_OBJ_HMGR_POWNED) 00874 { 00875 EngSetLastError(ERROR_INVALID_HANDLE); 00876 return FALSE; 00877 } 00878 00879 if (GDI_HANDLE_GET_TYPE(hobj) != GDI_OBJECT_TYPE_DC) 00880 return GreDeleteObject(hobj); 00881 00882 // FIXME: Everything should be callback based 00883 return IntGdiDeleteDC(hobj, FALSE); 00884 } 00885 00886 BOOL 00887 FASTCALL 00888 MakeInfoDC(PDC pdc, BOOL bSet) 00889 { 00890 PSURFACE pSurface; 00891 SIZEL sizl; 00892 00893 /* Can not be a display DC. */ 00894 if (pdc->fs & DC_FLAG_DISPLAY) return FALSE; 00895 if (bSet) 00896 { 00897 if (pdc->fs & DC_FLAG_TEMPINFODC || pdc->dctype == DC_TYPE_DIRECT) 00898 return FALSE; 00899 00900 pSurface = pdc->dclevel.pSurface; 00901 pdc->fs |= DC_FLAG_TEMPINFODC; 00902 pdc->pSurfInfo = pSurface; 00903 pdc->dctype = DC_TYPE_INFO; 00904 pdc->dclevel.pSurface = NULL; 00905 00906 PDEVOBJ_sizl(pdc->ppdev, &sizl); 00907 00908 if ( sizl.cx == pdc->dclevel.sizl.cx && 00909 sizl.cy == pdc->dclevel.sizl.cy ) 00910 return TRUE; 00911 00912 pdc->dclevel.sizl.cx = sizl.cx; 00913 pdc->dclevel.sizl.cy = sizl.cy; 00914 } 00915 else 00916 { 00917 if (!(pdc->fs & DC_FLAG_TEMPINFODC) || pdc->dctype != DC_TYPE_INFO) 00918 return FALSE; 00919 00920 pSurface = pdc->pSurfInfo; 00921 pdc->fs &= ~DC_FLAG_TEMPINFODC; 00922 pdc->dclevel.pSurface = pSurface; 00923 pdc->dctype = DC_TYPE_DIRECT; 00924 pdc->pSurfInfo = NULL; 00925 00926 if ( !pSurface || 00927 (pSurface->SurfObj.sizlBitmap.cx == pdc->dclevel.sizl.cx && 00928 pSurface->SurfObj.sizlBitmap.cy == pdc->dclevel.sizl.cy) ) 00929 return TRUE; 00930 00931 pdc->dclevel.sizl.cx = pSurface->SurfObj.sizlBitmap.cx; 00932 pdc->dclevel.sizl.cy = pSurface->SurfObj.sizlBitmap.cy; 00933 } 00934 return IntSetDefaultRegion(pdc); 00935 } 00936 00937 /* 00938 * @implemented 00939 */ 00940 BOOL 00941 APIENTRY 00942 NtGdiMakeInfoDC( 00943 IN HDC hdc, 00944 IN BOOL bSet) 00945 { 00946 BOOL Ret; 00947 PDC pdc = DC_LockDc(hdc); 00948 if (pdc) 00949 { 00950 Ret = MakeInfoDC(pdc, bSet); 00951 DC_UnlockDc(pdc); 00952 return Ret; 00953 } 00954 return FALSE; 00955 } 00956 00957 00958 HDC FASTCALL 00959 IntGdiCreateDC( 00960 PUNICODE_STRING Driver, 00961 PUNICODE_STRING pustrDevice, 00962 PVOID pUMdhpdev, 00963 CONST PDEVMODEW pdmInit, 00964 BOOL CreateAsIC) 00965 { 00966 HDC hdc; 00967 00968 hdc = GreOpenDCW(pustrDevice, 00969 pdmInit, 00970 NULL, 00971 CreateAsIC ? DCTYPE_INFO : 00972 (Driver ? DC_TYPE_DIRECT : DC_TYPE_DIRECT), 00973 TRUE, 00974 NULL, 00975 NULL, 00976 pUMdhpdev); 00977 00978 return hdc; 00979 } 00980 00981 HDC FASTCALL 00982 IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC) 00983 { 00984 HDC hDC; 00985 UNIMPLEMENTED; 00986 ASSERT(FALSE); 00987 00988 if (DcType == DC_TYPE_MEMORY) 00989 hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth! 00990 else 00991 hDC = IntGdiCreateDC(NULL, NULL, NULL, NULL, (DcType == DC_TYPE_INFO)); 00992 00993 return hDC; 00994 } 00995 Generated on Mon May 28 2012 04:38:10 for ReactOS by
1.7.6.1
|