update for HEAD-2003050101
[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 #define NDEBUG
18 #include <win32k/debug1.h>
19
20 VOID IntEngDeleteClipRegion(CLIPOBJ *ClipObj)
21 {
22   HCLIP HClip      = AccessHandleFromUserObject(ClipObj);
23   FreeGDIHandle(HClip);
24 }
25
26 CLIPOBJ * IntEngCreateClipRegion( ULONG count, PRECTL pRect, RECTL rcBounds )
27 {
28         HCLIP hClip;
29         CLIPGDI* clipInt;
30     CLIPOBJ* clipUser;
31         DPRINT("IntEngCreateClipRegion count: %d\n", count);
32         if( count > 1 ){
33                 hClip = (HCLIP)CreateGDIHandle( sizeof( CLIPGDI ) + count*sizeof(RECTL),
34                                                sizeof( CLIPOBJ ) );
35
36                 if( hClip ){
37                         clipInt = (CLIPGDI*)AccessInternalObject( hClip );
38                         RtlCopyMemory( clipInt->EnumRects.arcl, pRect, count*sizeof(RECTL));
39                         clipInt->EnumRects.c=count;
40
41                         clipUser = (CLIPOBJ*)AccessUserObject( hClip );
42                         ASSERT( clipUser );
43
44                         clipUser->iDComplexity = DC_COMPLEX;
45                         clipUser->iFComplexity = (count <= 4)? FC_RECT4: FC_COMPLEX;
46                         clipUser->iMode            = TC_RECTANGLES;
47                         RtlCopyMemory( &(clipUser->rclBounds), &rcBounds, sizeof( RECTL ) );
48
49                         return clipUser;
50                 }
51                 return NULL;
52         }
53         else{
54                 hClip = (HCLIP)CreateGDIHandle( sizeof( CLIPGDI ),
55                                                sizeof( CLIPOBJ ) );
56                 if( hClip ){
57                         clipInt = (CLIPGDI*)AccessInternalObject( hClip );
58                         RtlCopyMemory( clipInt->EnumRects.arcl, &rcBounds, sizeof( RECTL ));
59                         clipInt->EnumRects.c = 1;
60
61                         clipUser = (CLIPOBJ*)AccessUserObject( hClip );
62                         ASSERT( clipUser );
63
64                         clipUser->iDComplexity = ((rcBounds.top==rcBounds.bottom)&&(rcBounds.left==rcBounds.right))?
65                                                                                 DC_TRIVIAL:DC_RECT;
66                         clipUser->iFComplexity = FC_RECT;
67                         clipUser->iMode            = TC_RECTANGLES;
68                         DPRINT("IntEngCreateClipRegion: iDComplexity: %d\n", clipUser->iDComplexity);
69                         RtlCopyMemory( &(clipUser->rclBounds), &rcBounds, sizeof( RECTL ) );
70                         return clipUser;
71                 }
72         }
73         return NULL;
74 }
75
76 CLIPOBJ * STDCALL
77 EngCreateClip(VOID)
78 {
79   return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), 0);
80 }
81
82 VOID STDCALL
83 EngDeleteClip(CLIPOBJ *ClipRegion)
84 {
85   EngFreeMem(ClipRegion);
86 }
87
88 ULONG STDCALL
89 CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj,
90                    IN BOOL ShouldDoAll,
91                    IN ULONG ClipType,
92                    IN ULONG BuildOrder,
93                    IN ULONG MaxRects)
94 {
95   CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj);
96
97   ClipGDI->EnumPos     = 0;
98   ClipGDI->EnumMax = (MaxRects>0)? MaxRects : ClipGDI->EnumRects.c;
99
100   if( !((BuildOrder == CD_ANY) || (BuildOrder == CD_LEFTDOWN ))){
101         UNIMPLEMENTED;
102   }
103   ClipGDI->EnumOrder = BuildOrder;
104
105   // Return the number of rectangles enumerated
106   if( (MaxRects > 0) && (ClipGDI->EnumRects.c>MaxRects) )
107   {
108     return 0xFFFFFFFF;
109   }
110
111   return ClipGDI->EnumRects.c;
112 }
113
114 BOOL STDCALL
115 CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,
116               IN ULONG ObjSize,
117               OUT ULONG *EnumRects)
118 {
119   CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj);
120   ULONG nCopy;
121   PENUMRECTS pERects = (PENUMRECTS)EnumRects;
122
123   //calculate how many rectangles we should copy
124   nCopy = MIN( ClipGDI->EnumMax - ClipGDI->EnumPos,
125                MIN( ClipGDI->EnumRects.c - ClipGDI->EnumPos,
126                     (ObjSize - sizeof(ULONG)) / sizeof(RECTL)));
127
128   RtlCopyMemory( pERects->arcl, ClipGDI->EnumRects.arcl + ClipGDI->EnumPos,
129                  nCopy * sizeof(RECTL) );
130   pERects->c = nCopy;
131
132   ClipGDI->EnumPos+=nCopy;
133
134   return ClipGDI->EnumPos < ClipGDI->EnumRects.c;
135 }