NtGdiGetObject
[reactos.git] / reactos / subsystems / win32 / win32k / objects / pen.c
1 /*
2 * ReactOS Win32 Subsystem
3 *
4 * Copyright (C) 1998 - 2004 ReactOS Team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id$
21 */
22
23 #include <w32k.h>
24
25 #define NDEBUG
26 #include <debug.h>
27
28 /* PRIVATE FUNCTIONS **********************************************************/
29
30 HPEN FASTCALL
31 IntGdiCreatePenIndirect(PLOGPEN LogPen)
32 {
33 HPEN hPen;
34 PGDIBRUSHOBJ PenObject;
35 static const WORD wPatternAlternate[] = {0x5555};
36 static const WORD wPatternDash[] = {0x0F0F};
37 static const WORD wPatternDot[] = {0x3333};
38
39 if (LogPen->lopnStyle > PS_INSIDEFRAME)
40 return 0;
41
42 hPen = PENOBJ_AllocPen();
43 if (!hPen)
44 {
45 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
46 DPRINT("Can't allocate pen\n");
47 return 0;
48 }
49
50 PenObject = PENOBJ_LockPen(hPen);
51 /* FIXME - Handle PenObject == NULL!!! */
52 PenObject->ptPenWidth = LogPen->lopnWidth;
53 PenObject->ulPenStyle = LogPen->lopnStyle;
54 PenObject->BrushAttr.lbColor = LogPen->lopnColor;
55 PenObject->flAttrs = GDIBRUSH_IS_OLDSTYLEPEN;
56 switch (LogPen->lopnStyle)
57 {
58 case PS_NULL:
59 PenObject->flAttrs |= GDIBRUSH_IS_NULL;
60 break;
61
62 case PS_SOLID:
63 PenObject->flAttrs |= GDIBRUSH_IS_SOLID;
64 break;
65
66 case PS_ALTERNATE:
67 PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
68 PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternAlternate);
69 break;
70
71 case PS_DOT:
72 PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
73 PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDot);
74 break;
75
76 case PS_DASH:
77 PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
78 PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDash);
79 break;
80
81 case PS_INSIDEFRAME:
82 /* FIXME: does it need some additional work? */
83 PenObject->flAttrs |= GDIBRUSH_IS_SOLID;
84 break;
85
86 default:
87 DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED pen %x\n",LogPen->lopnStyle);
88 }
89
90 PENOBJ_UnlockPen(PenObject);
91
92 return hPen;
93 }
94
95 INT STDCALL
96 PEN_GetObject(PGDIBRUSHOBJ PenObject, INT Count, PLOGPEN Buffer)
97 {
98
99 LOGPEN LogPen;
100
101 if( Buffer == NULL ) return sizeof(LOGPEN);
102 if (Count < sizeof(LOGPEN)) return 0;
103 if (Count > sizeof(LOGPEN)) Count = sizeof(LOGPEN);
104
105 if( Buffer == NULL ) return sizeof(LOGPEN);
106
107 LogPen.lopnWidth = PenObject->ptPenWidth;
108 LogPen.lopnStyle = PenObject->ulPenStyle;
109 LogPen.lopnColor = PenObject->BrushAttr.lbColor;
110 memcpy(Buffer, &LogPen, Count);
111
112 return Count;
113
114 }
115
116 /* PUBLIC FUNCTIONS ***********************************************************/
117
118 HPEN STDCALL
119 NtGdiCreatePen(
120 INT PenStyle,
121 INT Width,
122 COLORREF Color,
123 IN HBRUSH hbr)
124 {
125 LOGPEN LogPen;
126
127 LogPen.lopnStyle = PenStyle;
128 LogPen.lopnWidth.x = Width;
129 LogPen.lopnWidth.y = 0;
130 LogPen.lopnColor = Color;
131
132 return IntGdiCreatePenIndirect(&LogPen);
133 }
134
135 HPEN STDCALL
136 NtGdiCreatePenIndirect(CONST PLOGPEN LogPen)
137 {
138 LOGPEN SafeLogPen;
139 NTSTATUS Status = STATUS_SUCCESS;
140
141 _SEH_TRY
142 {
143 ProbeForRead(LogPen,
144 sizeof(LOGPEN),
145 1);
146 SafeLogPen = *LogPen;
147 }
148 _SEH_HANDLE
149 {
150 Status = _SEH_GetExceptionCode();
151 }
152 _SEH_END;
153
154 if (!NT_SUCCESS(Status))
155 {
156 SetLastNtError(Status);
157 return 0;
158 }
159
160 return IntGdiCreatePenIndirect(&SafeLogPen);
161 }
162
163 HPEN STDCALL
164 NtGdiExtCreatePen(
165 DWORD PenStyle,
166 DWORD Width,
167 IN ULONG iBrushStyle,
168 IN ULONG ulColor,
169 IN ULONG_PTR lClientHatch,
170 IN ULONG_PTR lHatch,
171 DWORD StyleCount,
172 PULONG Style,
173 IN ULONG cjDIB,
174 IN BOOL bOldStylePen,
175 IN OPTIONAL HBRUSH hbrush)
176 {
177 LOGPEN LogPen;
178
179 if (PenStyle & PS_USERSTYLE)
180 PenStyle = (PenStyle & ~PS_STYLE_MASK) | PS_SOLID;
181
182 LogPen.lopnStyle = PenStyle & PS_STYLE_MASK;
183 LogPen.lopnWidth.x = Width;
184 LogPen.lopnColor = ulColor;
185
186 return IntGdiCreatePenIndirect(&LogPen);
187 }
188
189 /* EOF */