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

dclife.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 doxygen 1.7.6.1

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