Support for VMware video drivers
[reactos.git] / reactos / subsys / win32k / objects / line.c
1 // Some code from the WINE project source (www.winehq.com)
2
3 #undef WIN32_LEAN_AND_MEAN
4 #include <windows.h>
5 #include <ddk/ntddk.h>
6 #include <win32k/dc.h>
7 #include <win32k/line.h>
8 #include <win32k/path.h>
9 #include <win32k/pen.h>
10 #include <win32k/region.h>
11 #include <include/inteng.h>
12
13 #define NDEBUG
14 #include <win32k/debug1.h>
15
16
17 BOOL
18 STDCALL
19 W32kAngleArc(HDC hDC,
20 int X,
21 int Y,
22 DWORD Radius,
23 FLOAT StartAngle,
24 FLOAT SweepAngle)
25 {
26 UNIMPLEMENTED;
27 }
28
29 BOOL
30 STDCALL
31 W32kArc(HDC hDC,
32 int LeftRect,
33 int TopRect,
34 int RightRect,
35 int BottomRect,
36 int XStartArc,
37 int YStartArc,
38 int XEndArc,
39 int YEndArc)
40 {
41 DC *dc = DC_HandleToPtr(hDC);
42 if(!dc) return FALSE;
43
44 if(PATH_IsPathOpen(dc->w.path))
45 return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
46 XStartArc, YStartArc, XEndArc, YEndArc);
47
48 DC_ReleasePtr( hDC );
49 // EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
50 // XStartArc, YStartArc, XEndArc, YEndArc);
51 }
52
53 BOOL
54 STDCALL
55 W32kArcTo(HDC hDC,
56 int LeftRect,
57 int TopRect,
58 int RightRect,
59 int BottomRect,
60 int XRadial1,
61 int YRadial1,
62 int XRadial2,
63 int YRadial2)
64 {
65 BOOL result;
66 DC *dc = DC_HandleToPtr(hDC);
67 if(!dc) return FALSE;
68
69 // Line from current position to starting point of arc
70 W32kLineTo(hDC, XRadial1, YRadial1);
71
72 // Then the arc is drawn.
73 result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
74 XRadial1, YRadial1, XRadial2, YRadial2);
75
76 // If no error occured, the current position is moved to the ending point of the arc.
77 if(result)
78 {
79 W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
80 }
81 DC_ReleasePtr( hDC );
82 return result;
83 }
84
85 INT
86 STDCALL
87 W32kGetArcDirection(HDC hDC)
88 {
89 PDC dc;
90 int ret;
91
92 dc = DC_HandleToPtr (hDC);
93 if (!dc)
94 {
95 return 0;
96 }
97
98 ret = dc->w.ArcDirection;
99 DC_ReleasePtr( hDC );
100 return ret;
101 }
102
103 BOOL
104 STDCALL
105 W32kLineTo(HDC hDC,
106 int XEnd,
107 int YEnd)
108 {
109 DC *dc = DC_HandleToPtr(hDC);
110 SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface);
111 BOOL ret;
112 PPENOBJ pen;
113 PROSRGNDATA reg;
114 #ifndef TODO
115 RECT defaultrect;
116 #endif
117
118 if(!dc) return FALSE;
119
120 if(PATH_IsPathOpen(dc->w.path)) {
121 ret = PATH_LineTo(hDC, XEnd, YEnd);
122 } else {
123 pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
124 reg = (PROSRGNDATA)GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
125
126 ASSERT( pen );
127 // not yet implemented ASSERT( reg );
128 #ifndef TODO
129 if (NULL == reg) {
130 defaultrect.left = 0;
131 defaultrect.top = 0;
132 defaultrect.right = 640;
133 defaultrect.bottom = 480;
134
135 reg = &defaultrect;
136 }
137 #endif
138
139 /* Draw the line according to the DC origin */
140 ret = IntEngLineTo(SurfObj,
141 NULL, // ClipObj
142 PenToBrushObj(dc, pen),
143 dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
144 dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
145 reg, // Bounding rectangle
146 dc->w.ROPmode); // MIX
147
148 GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC );
149 GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
150 }
151 if(ret) {
152 dc->w.CursPosX = XEnd;
153 dc->w.CursPosY = YEnd;
154 }
155 DC_ReleasePtr( hDC );
156 return ret;
157 }
158
159 BOOL
160 STDCALL
161 W32kMoveToEx(HDC hDC,
162 int X,
163 int Y,
164 LPPOINT Point)
165 {
166 DC *dc = DC_HandleToPtr( hDC );
167
168 if(!dc) return FALSE;
169
170 if(Point) {
171 Point->x = dc->w.CursPosX;
172 Point->y = dc->w.CursPosY;
173 }
174 dc->w.CursPosX = X;
175 dc->w.CursPosY = Y;
176
177 if(PATH_IsPathOpen(dc->w.path)){
178 DC_ReleasePtr( hDC );
179 return PATH_MoveTo(hDC);
180 }
181 DC_ReleasePtr( hDC );
182 return FALSE;
183 }
184
185 BOOL
186 STDCALL
187 W32kPolyBezier(HDC hDC,
188 CONST LPPOINT pt,
189 DWORD Count)
190 {
191 DC *dc = DC_HandleToPtr(hDC);
192 if(!dc) return FALSE;
193
194 if(PATH_IsPathOpen(dc->w.path)){
195 DC_ReleasePtr( hDC );
196 return PATH_PolyBezier(hDC, pt, Count);
197 }
198
199 /* We'll convert it into line segments and draw them using Polyline */
200 {
201 POINT *Pts;
202 INT nOut;
203 BOOL ret;
204
205 Pts = GDI_Bezier(pt, Count, &nOut);
206 if(!Pts) return FALSE;
207 DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
208 ret = W32kPolyline(dc->hSelf, Pts, nOut);
209 ExFreePool(Pts);
210 DC_ReleasePtr( hDC );
211 return ret;
212 }
213 }
214
215 BOOL
216 STDCALL
217 W32kPolyBezierTo(HDC hDC,
218 CONST LPPOINT pt,
219 DWORD Count)
220 {
221 DC *dc = DC_HandleToPtr(hDC);
222 BOOL ret;
223
224 if(!dc) return FALSE;
225
226 if(PATH_IsPathOpen(dc->w.path))
227 ret = PATH_PolyBezierTo(hDC, pt, Count);
228 else { /* We'll do it using PolyBezier */
229 POINT *npt;
230 npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
231 if(!npt) return FALSE;
232 npt[0].x = dc->w.CursPosX;
233 npt[0].y = dc->w.CursPosY;
234 memcpy(npt + 1, pt, sizeof(POINT) * Count);
235 ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
236 ExFreePool(npt);
237 }
238 if(ret) {
239 dc->w.CursPosX = pt[Count-1].x;
240 dc->w.CursPosY = pt[Count-1].y;
241 }
242 DC_ReleasePtr( hDC );
243 return ret;
244 }
245
246 BOOL
247 STDCALL
248 W32kPolyDraw(HDC hDC,
249 CONST LPPOINT pt,
250 CONST LPBYTE Types,
251 int Count)
252 {
253 UNIMPLEMENTED;
254 }
255
256 BOOL
257 STDCALL
258 W32kPolyline(HDC hDC,
259 CONST LPPOINT pt,
260 int Count)
261 {
262 UNIMPLEMENTED;
263 }
264
265 BOOL
266 STDCALL
267 W32kPolylineTo(HDC hDC,
268 CONST LPPOINT pt,
269 DWORD Count)
270 {
271 DC *dc = DC_HandleToPtr(hDC);
272 BOOL ret;
273
274 if(!dc) return FALSE;
275
276 if(PATH_IsPathOpen(dc->w.path))
277 {
278 ret = PATH_PolylineTo(hDC, pt, Count);
279 }
280 else { /* do it using Polyline */
281 POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
282 if(!pts) return FALSE;
283
284 pts[0].x = dc->w.CursPosX;
285 pts[0].y = dc->w.CursPosY;
286 memcpy( pts + 1, pt, sizeof(POINT) * Count);
287 ret = W32kPolyline(hDC, pts, Count + 1);
288 ExFreePool(pts);
289 }
290 if(ret) {
291 dc->w.CursPosX = pt[Count-1].x;
292 dc->w.CursPosY = pt[Count-1].y;
293 }
294 DC_ReleasePtr( hDC );
295 return ret;
296 }
297
298 BOOL
299 STDCALL
300 W32kPolyPolyline(HDC hDC,
301 CONST LPPOINT pt,
302 CONST LPDWORD PolyPoints,
303 DWORD Count)
304 {
305 UNIMPLEMENTED;
306 }
307
308 int
309 STDCALL
310 W32kSetArcDirection(HDC hDC,
311 int ArcDirection)
312 {
313 PDC dc;
314 INT nOldDirection;
315
316 dc = DC_HandleToPtr (hDC);
317 if (!dc)
318 {
319 return 0;
320 }
321 if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
322 {
323 // SetLastError(ERROR_INVALID_PARAMETER);
324 DC_ReleasePtr( hDC );
325 return 0;
326 }
327
328 nOldDirection = dc->w.ArcDirection;
329 dc->w.ArcDirection = ArcDirection;
330 DC_ReleasePtr( hDC );
331 return nOldDirection;
332 }