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

cliprgn.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:        GNU GPL, See COPYING in the top level directory
00003  * PROJECT:          ReactOS Win32k subsystem
00004  * PURPOSE:          Clip region functions
00005  * FILE:             subsystems/win32/win32k/objects/cliprgn.c
00006  * PROGRAMER:        Unknown
00007  */
00008 
00009 #include <win32k.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 int FASTCALL
00015 CLIPPING_UpdateGCRegion(DC* Dc)
00016 {
00017    PROSRGNDATA CombinedRegion;
00018    //HRGN hRgnVis;
00019    PREGION prgnClip, prgnGCClip;
00020 
00021     /* Would prefer this, but the rest of the code sucks... */
00022     //ASSERT(Dc->rosdc.hGCClipRgn);
00023     //ASSERT(Dc->rosdc.hClipRgn);
00024    ASSERT(Dc->prgnVis);
00025    //hRgnVis = Dc->prgnVis->BaseObject.hHmgr;
00026 
00027    if (Dc->rosdc.hGCClipRgn == NULL)
00028       Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
00029 
00030    prgnGCClip = REGION_LockRgn(Dc->rosdc.hGCClipRgn);
00031    ASSERT(prgnGCClip);
00032 
00033    if (Dc->rosdc.hClipRgn == NULL)
00034       IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, NULL, RGN_COPY);
00035    else
00036    {
00037       prgnClip = REGION_LockRgn(Dc->rosdc.hClipRgn); // FIXME: Locking order, ugh!
00038       IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, prgnClip, RGN_AND);
00039       REGION_UnlockRgn(prgnClip);
00040    }
00041    REGION_UnlockRgn(prgnGCClip);
00042 
00043    NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
00044 
00045    if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
00046    {
00047      CLIPOBJ *CombinedClip;
00048 
00049      CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
00050         CombinedRegion->Buffer,
00051         &CombinedRegion->rdh.rcBound);
00052 
00053      RGNOBJAPI_Unlock(CombinedRegion);
00054 
00055      if ( !CombinedClip )
00056      {
00057        DPRINT1("IntEngCreateClipRegion() failed\n");
00058        return ERROR;
00059      }
00060 
00061      if(Dc->rosdc.CombinedClip != NULL)
00062        IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
00063 
00064       Dc->rosdc.CombinedClip = CombinedClip ;
00065    }
00066 
00067    return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y);
00068 }
00069 
00070 INT FASTCALL
00071 GdiSelectVisRgn(HDC hdc, HRGN hrgn)
00072 {
00073   int retval;
00074   DC *dc;
00075   PREGION prgn;
00076 
00077   if (!hrgn)
00078   {
00079     EngSetLastError(ERROR_INVALID_PARAMETER);
00080     return ERROR;
00081   }
00082   if (!(dc = DC_LockDc(hdc)))
00083   {
00084     EngSetLastError(ERROR_INVALID_HANDLE);
00085     return ERROR;
00086   }
00087 
00088   dc->fs &= ~DC_FLAG_DIRTY_RAO;
00089 
00090   ASSERT (dc->prgnVis != NULL);
00091 
00092   prgn = RGNOBJAPI_Lock(hrgn, NULL);
00093   retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR;
00094   RGNOBJAPI_Unlock(prgn);
00095   if ( retval != ERROR )
00096   {
00097     IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
00098     CLIPPING_UpdateGCRegion(dc);
00099   }
00100   DC_UnlockDc(dc);
00101 
00102   return retval;
00103 }
00104 
00105 
00106 int FASTCALL GdiExtSelectClipRgn(PDC dc,
00107                                  HRGN hrgn,
00108                                  int fnMode)
00109 {
00110   // dc->fs &= ~DC_FLAG_DIRTY_RAO;
00111 
00112   if (!hrgn)
00113   {
00114     if (fnMode == RGN_COPY)
00115     {
00116       if (dc->rosdc.hClipRgn != NULL)
00117       {
00118         GreDeleteObject(dc->rosdc.hClipRgn);
00119         dc->rosdc.hClipRgn = NULL;
00120       }
00121     }
00122     else
00123     {
00124       EngSetLastError(ERROR_INVALID_PARAMETER);
00125       return ERROR;
00126     }
00127   }
00128   else
00129   {
00130     if (!dc->rosdc.hClipRgn)
00131     {
00132       RECTL rect;
00133       if(dc->prgnVis)
00134       {
00135         REGION_GetRgnBox(dc->prgnVis, &rect);
00136         dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect);
00137       }
00138       else
00139       {
00140         dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
00141       }
00142     }
00143     if(fnMode == RGN_COPY)
00144     {
00145       NtGdiCombineRgn(dc->rosdc.hClipRgn, hrgn, 0, fnMode);
00146     }
00147     else
00148       NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
00149   }
00150 
00151   return CLIPPING_UpdateGCRegion(dc);
00152 }
00153 
00154 
00155 int APIENTRY NtGdiExtSelectClipRgn(HDC  hDC,
00156                                 HRGN  hrgn,
00157                                int  fnMode)
00158 {
00159   int retval;
00160   DC *dc;
00161 
00162   if (!(dc = DC_LockDc(hDC)))
00163   {
00164     EngSetLastError(ERROR_INVALID_HANDLE);
00165     return ERROR;
00166   }
00167 
00168   retval = GdiExtSelectClipRgn ( dc, hrgn, fnMode );
00169 
00170   DC_UnlockDc(dc);
00171   return retval;
00172 }
00173 
00174 INT FASTCALL
00175 GdiGetClipBox(HDC hDC, PRECTL rc)
00176 {
00177    INT retval;
00178    PDC dc;
00179    PROSRGNDATA pRgnNew, pRgn = NULL;
00180    BOOL Unlock = FALSE; // Small HACK
00181 
00182    if (!(dc = DC_LockDc(hDC)))
00183    {
00184       return ERROR;
00185    }
00186 
00187    /* FIXME: Rao and Vis only! */
00188    if (dc->prgnAPI) // APIRGN
00189    {
00190       pRgn = dc->prgnAPI;
00191    }
00192    else if (dc->dclevel.prgnMeta) // METARGN
00193    {
00194       pRgn = dc->dclevel.prgnMeta;
00195    }
00196    else if (dc->rosdc.hClipRgn)
00197    {
00198        Unlock = TRUE ;
00199        pRgn = REGION_LockRgn(dc->rosdc.hClipRgn); // CLIPRGN
00200    }
00201 
00202    if (pRgn)
00203    {
00204       pRgnNew = IntSysCreateRectpRgn( 0, 0, 0, 0 );
00205 
00206       if (!pRgnNew)
00207       {
00208          DC_UnlockDc(dc);
00209          if(Unlock) REGION_UnlockRgn(pRgn);
00210          return ERROR;
00211       }
00212 
00213       IntGdiCombineRgn(pRgnNew, dc->prgnVis, pRgn, RGN_AND);
00214 
00215       retval = REGION_GetRgnBox(pRgnNew, rc);
00216 
00217       REGION_Delete(pRgnNew);
00218 
00219       DC_UnlockDc(dc);
00220       if(Unlock) REGION_UnlockRgn(pRgn);
00221       return retval;
00222    }
00223 
00224    retval = REGION_GetRgnBox(dc->prgnVis, rc);
00225    IntDPtoLP(dc, (LPPOINT)rc, 2);
00226    DC_UnlockDc(dc);
00227 
00228    return retval;
00229 }
00230 
00231 INT APIENTRY
00232 NtGdiGetAppClipBox(HDC hDC, PRECTL rc)
00233 {
00234   INT Ret;
00235   NTSTATUS Status = STATUS_SUCCESS;
00236   RECTL Saferect;
00237 
00238   Ret = GdiGetClipBox(hDC, &Saferect);
00239 
00240   _SEH2_TRY
00241   {
00242     ProbeForWrite(rc,
00243                   sizeof(RECT),
00244                   1);
00245     *rc = Saferect;
00246   }
00247   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00248   {
00249     Status = _SEH2_GetExceptionCode();
00250   }
00251   _SEH2_END;
00252 
00253   if(!NT_SUCCESS(Status))
00254   {
00255     SetLastNtError(Status);
00256     return ERROR;
00257   }
00258 
00259   return Ret;
00260 }
00261 
00262 int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
00263                          int  LeftRect,
00264                          int  TopRect,
00265                          int  RightRect,
00266                          int  BottomRect)
00267 {
00268    INT Result;
00269    RECTL Rect;
00270    PREGION prgnNew, prgnClip;
00271    PDC dc = DC_LockDc(hDC);
00272 
00273    if (!dc)
00274    {
00275       EngSetLastError(ERROR_INVALID_HANDLE);
00276       return ERROR;
00277    }
00278 
00279    Rect.left = LeftRect;
00280    Rect.top = TopRect;
00281    Rect.right = RightRect;
00282    Rect.bottom = BottomRect;
00283 
00284    IntLPtoDP(dc, (LPPOINT)&Rect, 2);
00285 
00286    prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
00287    if (!prgnNew)
00288    {
00289       Result = ERROR;
00290    }
00291    else
00292    {
00293       if (!dc->rosdc.hClipRgn)
00294       {
00295          dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
00296          prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
00297          IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
00298          REGION_UnlockRgn(prgnClip);
00299          Result = SIMPLEREGION;
00300       }
00301       else
00302       {
00303          prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
00304          Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF);
00305          REGION_UnlockRgn(prgnClip);
00306       }
00307       REGION_Delete(prgnNew);
00308    }
00309    if (Result != ERROR)
00310       CLIPPING_UpdateGCRegion(dc);
00311 
00312    DC_UnlockDc(dc);
00313 
00314    return Result;
00315 }
00316 
00317 int APIENTRY NtGdiIntersectClipRect(HDC  hDC,
00318                            int  LeftRect,
00319                            int  TopRect,
00320                            int  RightRect,
00321                            int  BottomRect)
00322 {
00323    INT Result;
00324    RECTL Rect;
00325    HRGN NewRgn;
00326    PDC dc = DC_LockDc(hDC);
00327 
00328    DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n",
00329       hDC, LeftRect, TopRect, RightRect, BottomRect);
00330 
00331    if (!dc)
00332    {
00333       EngSetLastError(ERROR_INVALID_HANDLE);
00334       return ERROR;
00335    }
00336 
00337    Rect.left = LeftRect;
00338    Rect.top = TopRect;
00339    Rect.right = RightRect;
00340    Rect.bottom = BottomRect;
00341 
00342    IntLPtoDP(dc, (LPPOINT)&Rect, 2);
00343 
00344    NewRgn = IntSysCreateRectRgnIndirect(&Rect);
00345    if (!NewRgn)
00346    {
00347       Result = ERROR;
00348    }
00349    else if (!dc->rosdc.hClipRgn)
00350    {
00351       dc->rosdc.hClipRgn = NewRgn;
00352       Result = SIMPLEREGION;
00353    }
00354    else
00355    {
00356       Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_AND);
00357       GreDeleteObject(NewRgn);
00358    }
00359    if (Result != ERROR)
00360       CLIPPING_UpdateGCRegion(dc);
00361 
00362    DC_UnlockDc(dc);
00363 
00364    return Result;
00365 }
00366 
00367 int APIENTRY NtGdiOffsetClipRgn(HDC  hDC,
00368                        int  XOffset,
00369                        int  YOffset)
00370 {
00371   INT Result;
00372   DC *dc;
00373 
00374   if(!(dc = DC_LockDc(hDC)))
00375   {
00376     EngSetLastError(ERROR_INVALID_HANDLE);
00377     return ERROR;
00378   }
00379 
00380   if(dc->rosdc.hClipRgn != NULL)
00381   {
00382     Result = NtGdiOffsetRgn(dc->rosdc.hClipRgn,
00383                             XOffset,
00384                             YOffset);
00385     CLIPPING_UpdateGCRegion(dc);
00386   }
00387   else
00388   {
00389     Result = NULLREGION;
00390   }
00391 
00392   DC_UnlockDc(dc);
00393   return Result;
00394 }
00395 
00396 BOOL APIENTRY NtGdiPtVisible(HDC  hDC,
00397                     int  X,
00398                     int  Y)
00399 {
00400   HRGN rgn;
00401   DC *dc;
00402 
00403   if(!(dc = DC_LockDc(hDC)))
00404   {
00405     EngSetLastError(ERROR_INVALID_HANDLE);
00406     return FALSE;
00407   }
00408 
00409   rgn = dc->rosdc.hGCClipRgn;
00410   DC_UnlockDc(dc);
00411 
00412   return (rgn ? NtGdiPtInRegion(rgn, X, Y) : FALSE);
00413 }
00414 
00415 BOOL APIENTRY NtGdiRectVisible(HDC  hDC,
00416                       LPRECT UnsafeRect)
00417 {
00418    NTSTATUS Status = STATUS_SUCCESS;
00419    PROSRGNDATA Rgn;
00420    PDC dc = DC_LockDc(hDC);
00421    BOOL Result = FALSE;
00422    RECTL Rect;
00423 
00424    if (!dc)
00425    {
00426       EngSetLastError(ERROR_INVALID_HANDLE);
00427       return FALSE;
00428    }
00429 
00430    _SEH2_TRY
00431    {
00432       ProbeForRead(UnsafeRect,
00433                    sizeof(RECT),
00434                    1);
00435       Rect = *UnsafeRect;
00436    }
00437    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00438    {
00439       Status = _SEH2_GetExceptionCode();
00440    }
00441    _SEH2_END;
00442 
00443    if(!NT_SUCCESS(Status))
00444    {
00445       DC_UnlockDc(dc);
00446       SetLastNtError(Status);
00447       return FALSE;
00448    }
00449 
00450    if (dc->rosdc.hGCClipRgn)
00451    {
00452       if((Rgn = (PROSRGNDATA)RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL)))
00453       {
00454          IntLPtoDP(dc, (LPPOINT)&Rect, 2);
00455          Result = REGION_RectInRegion(Rgn, &Rect);
00456          RGNOBJAPI_Unlock(Rgn);
00457       }
00458    }
00459    DC_UnlockDc(dc);
00460 
00461    return Result;
00462 }
00463 
00464 int
00465 FASTCALL
00466 IntGdiSetMetaRgn(PDC pDC)
00467 {
00468   INT Ret = ERROR;
00469   PROSRGNDATA TempRgn;
00470 
00471   if ( pDC->dclevel.prgnMeta )
00472   {
00473      if ( pDC->dclevel.prgnClip )
00474      {
00475         TempRgn = IntSysCreateRectpRgn(0,0,0,0);
00476         if (TempRgn)
00477         {
00478            Ret = IntGdiCombineRgn( TempRgn,
00479                      pDC->dclevel.prgnMeta,
00480                      pDC->dclevel.prgnClip,
00481                                    RGN_AND);
00482            if ( Ret )
00483            {
00484               GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject);
00485               if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount)
00486                  REGION_Delete(pDC->dclevel.prgnMeta);
00487 
00488               pDC->dclevel.prgnMeta = TempRgn;
00489 
00490               GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject);
00491               if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount)
00492                  REGION_Delete(pDC->dclevel.prgnClip);
00493 
00494               pDC->dclevel.prgnClip = NULL;
00495 
00496               IntGdiReleaseRaoRgn(pDC);
00497            }
00498            else
00499               REGION_Delete(TempRgn);
00500         }
00501      }
00502      else
00503         Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
00504   }
00505   else
00506   {
00507      if ( pDC->dclevel.prgnClip )
00508      {
00509         Ret = REGION_Complexity(pDC->dclevel.prgnClip);
00510         pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
00511         pDC->dclevel.prgnClip = NULL;
00512      }
00513      else
00514        Ret = SIMPLEREGION;
00515   }
00516   return Ret;
00517 }
00518 
00519 
00520 int APIENTRY NtGdiSetMetaRgn(HDC  hDC)
00521 {
00522   INT Ret;
00523   PDC pDC = DC_LockDc(hDC);
00524 
00525   if (!pDC)
00526   {
00527      EngSetLastError(ERROR_INVALID_PARAMETER);
00528      return ERROR;
00529   }
00530   Ret = IntGdiSetMetaRgn(pDC);
00531 
00532   DC_UnlockDc(pDC);
00533   return Ret;
00534 }
00535 
00536 INT FASTCALL
00537 NEW_CLIPPING_UpdateGCRegion(PDC pDC)
00538 {
00539   CLIPOBJ * co;
00540 
00541   /* Must have VisRgn set to a valid state! */
00542   ASSERT (pDC->prgnVis);
00543 
00544   if (pDC->prgnAPI)
00545   {
00546      REGION_Delete(pDC->prgnAPI);
00547      pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
00548   }
00549 
00550   if (pDC->prgnRao)
00551   {
00552      REGION_Delete(pDC->prgnRao);
00553      pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
00554   }
00555 
00556   if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip)
00557   {
00558      IntGdiCombineRgn( pDC->prgnAPI,
00559                        pDC->dclevel.prgnClip,
00560                        pDC->dclevel.prgnMeta,
00561                        RGN_AND);
00562   }
00563   else
00564   {
00565      if (pDC->dclevel.prgnClip)
00566      {
00567         IntGdiCombineRgn( pDC->prgnAPI,
00568                           pDC->dclevel.prgnClip,
00569                           NULL,
00570                           RGN_COPY);
00571      }
00572      else if (pDC->dclevel.prgnMeta)
00573      {
00574         IntGdiCombineRgn( pDC->prgnAPI,
00575                           pDC->dclevel.prgnMeta,
00576                           NULL,
00577                           RGN_COPY);
00578      }
00579   }
00580 
00581   IntGdiCombineRgn( pDC->prgnRao,
00582                     pDC->prgnVis,
00583                     pDC->prgnAPI,
00584                     RGN_AND);
00585 
00586   RtlCopyMemory(&pDC->erclClip,
00587                 &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
00588                 sizeof(RECTL));
00589 
00590   pDC->fs &= ~DC_FLAG_DIRTY_RAO;
00591 
00592   IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
00593 
00594   // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
00595   // the rects from region objects rects in pClipRgn->Buffer.
00596   // With pDC->co.pClipRgn->Buffer,
00597   // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
00598 
00599   co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount,
00600                                ((PROSRGNDATA)pDC->prgnRao)->Buffer,
00601                                  &pDC->erclClip);
00602   if (co)
00603   {
00604     if (pDC->rosdc.CombinedClip != NULL)
00605       IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
00606 
00607     pDC->rosdc.CombinedClip = co;
00608   }
00609 
00610   return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
00611 }
00612 
00613 /* EOF */

Generated on Sat May 26 2012 04:37:12 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.