:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / eng / clip.c
1 /*
2  * COPYRIGHT:         See COPYING in the top level directory
3  * PROJECT:           ReactOS kernel
4  * PURPOSE:           GDI Clipping Functions
5  * FILE:              subsys/win32k/eng/clip.c
6  * PROGRAMER:         Jason Filby
7  * REVISION HISTORY:
8  *                 21/8/1999: Created
9  */
10
11 #include <ddk/winddi.h>
12 #include <ddk/ntddk.h>
13 #include "objects.h"
14 #include "clip.h"
15 #include <include/object.h>
16
17 #include <win32k/debug1.h>
18
19 VOID IntEngDeleteClipRegion(CLIPOBJ *ClipObj)
20 {
21   HCLIP HClip      = AccessHandleFromUserObject(ClipObj);
22   FreeGDIHandle(HClip);
23 }
24
25 CLIPOBJ * IntEngCreateClipRegion( ULONG count, PRECTL pRect, RECTL rcBounds )
26 {
27         HCLIP hClip;
28         CLIPGDI* clipInt;
29     CLIPOBJ* clipUser;
30         DPRINT("IntEngCreateClipRegion count: %d\n", count);
31         if( count > 1 ){
32                 hClip = (HCLIP)CreateGDIHandle( sizeof( CLIPGDI ) + count*sizeof(RECTL),
33                                                sizeof( CLIPOBJ ) );
34
35                 if( hClip ){
36                         clipInt = (CLIPGDI*)AccessInternalObject( hClip );
37                         RtlCopyMemory( clipInt->EnumRects.arcl, pRect, count*sizeof(RECTL));
38                         clipInt->EnumRects.c=count;
39
40                         clipUser = (CLIPOBJ*)AccessUserObject( hClip );
41                         ASSERT( clipUser );
42
43                         clipUser->iDComplexity = DC_COMPLEX;
44                         clipUser->iFComplexity = (count <= 4)? FC_RECT4: FC_COMPLEX;
45                         clipUser->iMode            = TC_RECTANGLES;
46                         RtlCopyMemory( &(clipUser->rclBounds), &rcBounds, sizeof( RECTL ) );
47
48                         return clipUser;
49                 }
50                 return NULL;
51         }
52         else{
53                 hClip = (HCLIP)CreateGDIHandle( sizeof( CLIPGDI ),
54                                                sizeof( CLIPOBJ ) );
55                 if( hClip ){
56                         clipInt = (CLIPGDI*)AccessInternalObject( hClip );
57                         RtlCopyMemory( clipInt->EnumRects.arcl, &rcBounds, sizeof( RECTL ));
58                         clipInt->EnumRects.c = 1;
59
60                         clipUser = (CLIPOBJ*)AccessUserObject( hClip );
61                         ASSERT( clipUser );
62
63                         clipUser->iDComplexity = ((rcBounds.top==rcBounds.bottom)&&(rcBounds.left==rcBounds.right))?
64                                                                                 DC_TRIVIAL:DC_RECT;
65                         clipUser->iFComplexity = FC_RECT;
66                         clipUser->iMode            = TC_RECTANGLES;
67                         DPRINT("IntEngCreateClipRegion: iDComplexity: %d\n", clipUser->iDComplexity);
68                         RtlCopyMemory( &(clipUser->rclBounds), &rcBounds, sizeof( RECTL ) );
69                         return clipUser;
70                 }
71         }
72         return NULL;
73 }
74
75 CLIPOBJ * STDCALL
76 EngCreateClip(VOID)
77 {
78   return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), 0);
79 }
80
81 VOID STDCALL
82 EngDeleteClip(CLIPOBJ *ClipRegion)
83 {
84   EngFreeMem(ClipRegion);
85 }
86
87 ULONG STDCALL
88 CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj,
89                    IN BOOL ShouldDoAll,
90                    IN ULONG ClipType,
91                    IN ULONG BuildOrder,
92                    IN ULONG MaxRects)
93 {
94   CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj);
95
96   ClipGDI->EnumPos     = 0;
97   ClipGDI->EnumMax = (MaxRects>0)? MaxRects : ClipGDI->EnumRects.c;
98
99   if( !((BuildOrder == CD_ANY) || (BuildOrder == CD_LEFTDOWN ))){
100         UNIMPLEMENTED;
101   }
102   ClipGDI->EnumOrder = BuildOrder;
103
104   // Return the number of rectangles enumerated
105   if( (MaxRects > 0) && (ClipGDI->EnumRects.c>MaxRects) )
106   {
107     return 0xFFFFFFFF;
108   }
109
110   return ClipGDI->EnumRects.c;
111 }
112
113 BOOL STDCALL
114 CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,
115               IN ULONG ObjSize,
116               OUT ULONG *EnumRects)
117 {
118   CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj);
119   ULONG nCopy;
120   PENUMRECTS pERects = (PENUMRECTS)EnumRects;
121
122   //calculate how many rectangles we should copy
123   nCopy = MIN( ClipGDI->EnumMax-ClipGDI->EnumPos,
124                                 MIN( ClipGDI->EnumRects.c, (ObjSize-sizeof(ULONG))/sizeof(RECTL)));
125
126   RtlCopyMemory( &(pERects->arcl), &(ClipGDI->EnumRects.arcl), nCopy*sizeof(RECTL) );
127   pERects->c = nCopy;
128
129   ClipGDI->EnumPos+=nCopy;
130
131   if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
132     return FALSE;
133   else
134     return TRUE;
135 }