Skip to content

Commit a765dcf

Browse files
committed
Add necessary API definitions for APIs used by downstream owner-draw code
Most of these definitions concern GDI+ and UXTheme. In those cases I also replaced most of the hand-rolled syscall wrappers with auto-generated ones via mkwinsyscall. Signed-off-by: Aaron Klotz <[email protected]>
1 parent e8ccca0 commit a765dcf

12 files changed

+1180
-305
lines changed

gdi32.go

+8
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,14 @@ type RECT struct {
897897
Left, Top, Right, Bottom int32
898898
}
899899

900+
func (r *RECT) Width() int32 {
901+
return r.Right - r.Left
902+
}
903+
904+
func (r *RECT) Height() int32 {
905+
return r.Bottom - r.Top
906+
}
907+
900908
type SIZE struct {
901909
CX, CY int32
902910
}

gdiplus.go

+237-73
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
//go:build windows
56
// +build windows
67

8+
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zgdiplus_windows.go gdiplus.go
9+
//go:generate go run golang.org/x/tools/cmd/goimports -w zgdiplus_windows.go
10+
711
package win
812

913
import (
10-
"golang.org/x/sys/windows"
14+
"math"
1115
"syscall"
1216
"unsafe"
1317
)
@@ -123,102 +127,262 @@ type GdiplusStartupOutput struct {
123127
NotificationUnhook uintptr
124128
}
125129

130+
type GpBitmap GpImage
131+
type GpBrush struct{}
132+
type GpFont struct{}
133+
type GpFontCollection struct{}
134+
type GpFontFamily struct{}
135+
type GpGraphics struct{}
126136
type GpImage struct{}
137+
type GpImageAttributes struct{}
138+
type GpPath struct{}
139+
type GpSolidFill GpBrush
140+
type GpStringFormat struct{}
141+
142+
type GpRect struct {
143+
X int32
144+
Y int32
145+
Width int32
146+
Height int32
147+
}
127148

128-
type GpBitmap GpImage
149+
type GpRectF struct {
150+
X float32
151+
Y float32
152+
Width float32
153+
Height float32
154+
}
129155

130156
type ARGB uint32
131157

132-
var (
133-
// Library
134-
libgdiplus *windows.LazyDLL
158+
type CombineMode int32
135159

136-
// Functions
137-
gdipCreateBitmapFromFile *windows.LazyProc
138-
gdipCreateBitmapFromHBITMAP *windows.LazyProc
139-
gdipCreateHBITMAPFromBitmap *windows.LazyProc
140-
gdipDisposeImage *windows.LazyProc
141-
gdiplusShutdown *windows.LazyProc
142-
gdiplusStartup *windows.LazyProc
160+
const (
161+
CombineModeReplace = CombineMode(0)
162+
CombineModeIntersect = CombineMode(1)
163+
CombineModeUnion = CombineMode(2)
164+
CombineModeXor = CombineMode(3)
165+
CombineModeExclude = CombineMode(4)
166+
CombineModeCompliment = CombineMode(5)
143167
)
144168

145-
var (
146-
token uintptr
169+
type CompositingMode int32
170+
171+
const (
172+
CompositingModeSourceOver = CompositingMode(0)
173+
CompositingModeSourceCopy = CompositingMode(1)
147174
)
148175

149-
func init() {
150-
// Library
151-
libgdiplus = windows.NewLazySystemDLL("gdiplus.dll")
176+
type CompositingQuality int32
152177

153-
// Functions
154-
gdipCreateBitmapFromFile = libgdiplus.NewProc("GdipCreateBitmapFromFile")
155-
gdipCreateBitmapFromHBITMAP = libgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
156-
gdipCreateHBITMAPFromBitmap = libgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
157-
gdipDisposeImage = libgdiplus.NewProc("GdipDisposeImage")
158-
gdiplusShutdown = libgdiplus.NewProc("GdiplusShutdown")
159-
gdiplusStartup = libgdiplus.NewProc("GdiplusStartup")
160-
}
178+
const (
179+
CompositingQualityInvalid = CompositingQuality(-1)
180+
CompositingQualityDefault = CompositingQuality(0)
181+
CompositingQualityHighSpeed = CompositingQuality(1)
182+
CompositingQualityHighQuality = CompositingQuality(2)
183+
CompositingQualityGammaCorrected = CompositingQuality(3)
184+
CompositingQualityAssumeLinear = CompositingQuality(4)
185+
)
161186

162-
func GdipCreateBitmapFromFile(filename *uint16, bitmap **GpBitmap) GpStatus {
163-
ret, _, _ := syscall.Syscall(gdipCreateBitmapFromFile.Addr(), 2,
164-
uintptr(unsafe.Pointer(filename)),
165-
uintptr(unsafe.Pointer(bitmap)),
166-
0)
187+
type FillMode int32
167188

168-
return GpStatus(ret)
169-
}
189+
const (
190+
FillModeAlternate = FillMode(0)
191+
FillModeWinding = FillMode(1)
192+
)
170193

171-
func GdipCreateBitmapFromHBITMAP(hbm HBITMAP, hpal HPALETTE, bitmap **GpBitmap) GpStatus {
172-
ret, _, _ := syscall.Syscall(gdipCreateBitmapFromHBITMAP.Addr(), 3,
173-
uintptr(hbm),
174-
uintptr(hpal),
175-
uintptr(unsafe.Pointer(bitmap)))
194+
type FontStyle int32
176195

177-
return GpStatus(ret)
178-
}
196+
const (
197+
FontStyleRegular = FontStyle(0)
198+
FontStyleBold = FontStyle(1)
199+
FontStyleItalic = FontStyle(2)
200+
FontStyleBoldItalic = FontStyle(3)
201+
FontStyleUnderline = FontStyle(4)
202+
FontStyleStrikeout = FontStyle(8)
203+
)
179204

180-
func GdipCreateHBITMAPFromBitmap(bitmap *GpBitmap, hbmReturn *HBITMAP, background ARGB) GpStatus {
181-
ret, _, _ := syscall.Syscall(gdipCreateHBITMAPFromBitmap.Addr(), 3,
182-
uintptr(unsafe.Pointer(bitmap)),
183-
uintptr(unsafe.Pointer(hbmReturn)),
184-
uintptr(background))
205+
type InterpolationMode int32
185206

186-
return GpStatus(ret)
187-
}
207+
const (
208+
InterpolationModeInvalid = InterpolationMode(-1)
209+
InterpolationModeDefault = InterpolationMode(0)
210+
InterpolationModeLowQuality = InterpolationMode(1)
211+
InterpolationModeHighQuality = InterpolationMode(2)
212+
InterpolationModeBilinear = InterpolationMode(3)
213+
InterpolationModeBicubic = InterpolationMode(4)
214+
InterpolationModeNearestNeighbor = InterpolationMode(5)
215+
InterpolationModeHighQualityBilinear = InterpolationMode(6)
216+
InterpolationModeHighQualityBicubic = InterpolationMode(7)
217+
)
188218

189-
func GdipDisposeImage(image *GpImage) GpStatus {
190-
ret, _, _ := syscall.Syscall(gdipDisposeImage.Addr(), 1,
191-
uintptr(unsafe.Pointer(image)),
192-
0,
193-
0)
219+
type PixelFormat int32
194220

195-
return GpStatus(ret)
196-
}
221+
const (
222+
PixelFormatIndexed = 0x00010000
223+
PixelFormatGDI = 0x00020000
224+
PixelFormatAlpha = 0x00040000
225+
PixelFormatPAlpha = 0x00080000
226+
PixelFormatExtended = 0x00100000
227+
PixelFormatCanonical = 0x00200000
228+
229+
PixelFormatUndefined = 0
230+
PixelFormatDontCare = 0
231+
232+
PixelFormat1bppIndexed = (1 | (1 << 8) | PixelFormatIndexed | PixelFormatGDI)
233+
PixelFormat4bppIndexed = (2 | (4 << 8) | PixelFormatIndexed | PixelFormatGDI)
234+
PixelFormat8bppIndexed = (3 | (8 << 8) | PixelFormatIndexed | PixelFormatGDI)
235+
PixelFormat16bppGrayScale = (4 | (16 << 8) | PixelFormatExtended)
236+
PixelFormat16bppRGB555 = (5 | (16 << 8) | PixelFormatGDI)
237+
PixelFormat16bppRGB565 = (6 | (16 << 8) | PixelFormatGDI)
238+
PixelFormat16bppARGB1555 = (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI)
239+
PixelFormat24bppRGB = (8 | (24 << 8) | PixelFormatGDI)
240+
PixelFormat32bppRGB = (9 | (32 << 8) | PixelFormatGDI)
241+
PixelFormat32bppARGB = (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
242+
PixelFormat32bppPARGB = (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI)
243+
PixelFormat48bppRGB = (12 | (48 << 8) | PixelFormatExtended)
244+
PixelFormat64bppARGB = (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended)
245+
PixelFormat64bppPARGB = (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended)
246+
PixelFormat32bppCMYK = (15 | (32 << 8))
247+
)
197248

198-
func GdiplusShutdown() {
199-
syscall.Syscall(gdiplusShutdown.Addr(), 1,
200-
token,
201-
0,
202-
0)
203-
}
249+
type PixelOffsetMode int32
250+
251+
const (
252+
PixelOffsetModeInvalid = PixelOffsetMode(-1)
253+
PixelOffsetModeDefault = PixelOffsetMode(0)
254+
PixelOffsetModeHighSpeed = PixelOffsetMode(1)
255+
PixelOffsetModeHighQuality = PixelOffsetMode(2)
256+
PixelOffsetModeNone = PixelOffsetMode(3)
257+
PixelOffsetModeHalf = PixelOffsetMode(4)
258+
)
259+
260+
type SmoothingMode int32
261+
262+
const (
263+
SmoothingModeInvalid = SmoothingMode(-1)
264+
SmoothingModeDefault = SmoothingMode(0)
265+
SmoothingModeHighSpeed = SmoothingMode(1)
266+
SmoothingModeHighQuality = SmoothingMode(2)
267+
SmoothingModeNone = SmoothingMode(3)
268+
SmoothingModeAntiAlias8x4 = SmoothingMode(4)
269+
SmoothingModeAntiAlias = SmoothingModeAntiAlias8x4
270+
SmoothingModeAntiAlias8x8 = SmoothingMode(5)
271+
)
272+
273+
type StringAlignment int32
274+
275+
const (
276+
StringAlignmentNear = StringAlignment(0)
277+
StringAlignmentCenter = StringAlignment(1)
278+
StringAlignmentFar = StringAlignment(2)
279+
)
280+
281+
type StringFormatFlags int32
282+
283+
const (
284+
StringFormatFlagsDirectionRightToLeft = StringFormatFlags(0x00000001)
285+
StringFormatFlagsDirectionVertical = StringFormatFlags(0x00000002)
286+
StringFormatFlagsNoFitBlackBox = StringFormatFlags(0x00000004)
287+
StringFormatFlagsDisplayFormatControl = StringFormatFlags(0x00000020)
288+
StringFormatFlagsNoFontFallback = StringFormatFlags(0x00000400)
289+
StringFormatFlagsMeasureTrailingSpaces = StringFormatFlags(0x00000800)
290+
StringFormatFlagsNoWrap = StringFormatFlags(0x00001000)
291+
StringFormatFlagsLineLimit = StringFormatFlags(0x00002000)
292+
StringFormatFlagsNoClip = StringFormatFlags(0x00004000)
293+
StringFormatFlagsBypassGDI = StringFormatFlags(-((0x80000000 ^ 0xFFFFFFFF) + 1))
294+
)
295+
296+
type TextRenderingHint int32
297+
298+
const (
299+
TextRenderingHintSystemDefault = TextRenderingHint(0)
300+
TextRenderingHintSingleBitPerPixelGridFit = TextRenderingHint(1)
301+
TextRenderingHintSingleBitPerPixel = TextRenderingHint(2)
302+
TextRenderingHintAntiAliasGridFit = TextRenderingHint(3)
303+
TextRenderingHintAntiAlias = TextRenderingHint(4)
304+
TextRenderingHintClearTypeGridFit = TextRenderingHint(5)
305+
)
306+
307+
type Unit int32
204308

205-
func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) GpStatus {
206-
ret, _, _ := syscall.Syscall(gdiplusStartup.Addr(), 3,
207-
uintptr(unsafe.Pointer(&token)),
208-
uintptr(unsafe.Pointer(input)),
209-
uintptr(unsafe.Pointer(output)))
309+
const (
310+
UnitWorld = Unit(0)
311+
UnitDisplay = Unit(1)
312+
UnitPixel = Unit(2)
313+
UnitPoint = Unit(3)
314+
UnitInch = Unit(4)
315+
UnitDocument = Unit(5)
316+
UnitMillimeter = Unit(6)
317+
)
318+
319+
var (
320+
gdipBitmapSetResolution = modgdiplus.NewProc("GdipBitmapSetResolution")
321+
gdipCreateFont = modgdiplus.NewProc("GdipCreateFont")
322+
)
323+
324+
func GdipBitmapSetResolution(bitmap *GpBitmap, xdpi float32, ydpi float32) GpStatus {
325+
ret, _, _ := syscall.SyscallN(gdipBitmapSetResolution.Addr(),
326+
uintptr(unsafe.Pointer(bitmap)),
327+
uintptr(math.Float32bits(xdpi)),
328+
uintptr(math.Float32bits(ydpi)),
329+
)
210330

211331
return GpStatus(ret)
212332
}
213333

214-
/*GdipSaveImageToFile(image *GpImage, filename *uint16, clsidEncoder *CLSID, encoderParams *EncoderParameters) GpStatus {
215-
ret, _, _ := syscall.Syscall6(gdipSaveImageToFile.Addr(), 4,
216-
uintptr(unsafe.Pointer(image)),
217-
uintptr(unsafe.Pointer(filename)),
218-
uintptr(unsafe.Pointer(clsidEncoder)),
219-
uintptr(unsafe.Pointer(encoderParams)),
220-
0,
221-
0)
334+
func GdipCreateFont(fontFamily *GpFontFamily, emSize float32, style FontStyle, unit Unit, font **GpFont) GpStatus {
335+
ret, _, _ := syscall.SyscallN(gdipCreateFont.Addr(),
336+
uintptr(unsafe.Pointer(fontFamily)),
337+
uintptr(math.Float32bits(emSize)),
338+
uintptr(style),
339+
uintptr(unit),
340+
uintptr(unsafe.Pointer(font)),
341+
)
222342

223343
return GpStatus(ret)
224-
}*/
344+
}
345+
346+
//sys GdipAddPathEllipseI(path *GpPath, x int32, y int32, width int32, height int32) (ret GpStatus) = gdiplus.GdipAddPathEllipseI
347+
//sys GdipCreateBitmapFromFile(filename *uint16, bitmap **GpBitmap) (ret GpStatus) = gdiplus.GdipCreateBitmapFromFile
348+
//sys GdipCreateBitmapFromGraphics(width int32, height int32, graphics *GpGraphics, bitmap **GpBitmap) (ret GpStatus) = gdiplus.GdipCreateBitmapFromGraphics
349+
//sys GdipCreateBitmapFromHBITMAP(hbm HBITMAP, hpal HPALETTE, bitmap **GpBitmap) (ret GpStatus) = gdiplus.GdipCreateBitmapFromHBITMAP
350+
//sys GdipCreateBitmapFromScan0(width int32, height int32, stride int32, format PixelFormat, scan0 *byte, bitmap **GpBitmap) (ret GpStatus) = gdiplus.GdipCreateBitmapFromScan0
351+
//sys GdipCreateBitmapFromStream(stream *com.IStreamABI, bitmap **GpBitmap) (ret GpStatus) = gdiplus.GdipCreateBitmapFromStream
352+
//sys GdipCreateFontFamilyFromName(name *uint16, collection *GpFontCollection, family **GpFontFamily) (ret GpStatus) = gdiplus.GdipCreateFontFamilyFromName
353+
//sys GdipCreateFromHDC(hdc HDC, graphics **GpGraphics) (ret GpStatus) = gdiplus.GdipCreateFromHDC
354+
//sys GdipCreateHBITMAPFromBitmap(bitmap *GpBitmap, hbmReturn *HBITMAP, background ARGB) (ret GpStatus) = gdiplus.GdipCreateHBITMAPFromBitmap
355+
//sys GdipCreatePath(fillMode FillMode, path **GpPath) (ret GpStatus) = gdiplus.GdipCreatePath
356+
//sys GdipCreateSolidFill(color ARGB, brush **GpSolidFill) (ret GpStatus) = gdiplus.GdipCreateSolidFill
357+
//sys GdipCreateStringFormat(flags StringFormatFlags, language LANGID, format **GpStringFormat) (ret GpStatus) = gdiplus.GdipCreateStringFormat
358+
//sys GdipDeleteBrush(brush *GpBrush) (ret GpStatus) = gdiplus.GdipDeleteBrush
359+
//sys GdipDeleteFont(font *GpFont) (ret GpStatus) = gdiplus.GdipDeleteFont
360+
//sys GdipDeleteFontFamily(family *GpFontFamily) (ret GpStatus) = gdiplus.GdipDeleteFontFamily
361+
//sys GdipDeleteGraphics(graphics *GpGraphics) (ret GpStatus) = gdiplus.GdipDeleteGraphics
362+
//sys GdipDeletePath(path *GpPath) (ret GpStatus) = gdiplus.GdipDeletePath
363+
//sys GdipDeleteStringFormat(format *GpStringFormat) (ret GpStatus) = gdiplus.GdipDeleteStringFormat
364+
//sys GdipDisposeImage(image *GpImage) (ret GpStatus) = gdiplus.GdipDisposeImage
365+
//sys GdipDrawImageRectI(graphics *GpGraphics, image *GpImage, x int32, y int32, width int32, height int32) (ret GpStatus) = gdiplus.GdipDrawImageRectI
366+
//sys GdipDrawImageRectRectI(graphics *GpGraphics, image *GpImage, dstX int32, dstY int32, dstWidth int32, dstHeight int32, srcX int32, srcY int32, srcWidth int32, srcHeight int32, srcUnit Unit, imgAttrs *GpImageAttributes, callback uintptr, callbackData uintptr) (ret GpStatus) = gdiplus.GdipDrawImageRectRectI
367+
//sys GdipDrawString(graphics *GpGraphics, text *uint16, textLength int32, font *GpFont, rectf *GpRectF, strFmt *GpStringFormat, brush *GpBrush) (ret GpStatus) = gdiplus.GdipDrawString
368+
//sys GdipFillEllipseI(graphics *GpGraphics, brush *GpBrush, x int32, y int32, width int32, height int32) (ret GpStatus) = gdiplus.GdipFillEllipseI
369+
//sys GdipGetGenericFontFamilyMonospace(family **GpFontFamily) (ret GpStatus) = gdiplus.GdipGetGenericFontFamilyMonospace
370+
//sys GdipGetGenericFontFamilySansSerif(family **GpFontFamily) (ret GpStatus) = gdiplus.GdipGetGenericFontFamilySansSerif
371+
//sys GdipGetGenericFontFamilySerif(family **GpFontFamily) (ret GpStatus) = gdiplus.GdipGetGenericFontFamilySerif
372+
//sys GdipGetImageDimension(image *GpImage, width *float32, height *float32) (ret GpStatus) = gdiplus.GdipGetImageDimension
373+
//sys GdipGetImageGraphicsContext(image *GpImage, graphics **GpGraphics) (ret GpStatus) = gdiplus.GdipGetImageGraphicsContext
374+
//sys GdipGetImageHorizontalResolution(image *GpImage, resolution *float32) (ret GpStatus) = gdiplus.GdipGetImageHorizontalResolution
375+
//sys GdipGetImageVerticalResolution(image *GpImage, resolution *float32) (ret GpStatus) = gdiplus.GdipGetImageVerticalResolution
376+
//sys GdipGetCompositingMode(graphics *GpGraphics, compositingMode *CompositingMode) (ret GpStatus) = gdiplus.GdipGetCompositingMode
377+
//sys GdipGraphicsClear(graphics *GpGraphics, color ARGB) (ret GpStatus) = gdiplus.GdipGraphicsClear
378+
//sys GdiplusStartup(token *uintptr, input *GdiplusStartupInput, output *GdiplusStartupOutput) (ret GpStatus) = gdiplus.GdiplusStartup
379+
//sys GdipResetClip(graphics *GpGraphics) (ret GpStatus) = gdiplus.GdipResetClip
380+
//sys GdipSetClipPath(graphics *GpGraphics, path *GpPath, combineMode CombineMode) (ret GpStatus) = gdiplus.GdipSetClipPath
381+
//sys GdipSetCompositingMode(graphics *GpGraphics, compositingMode CompositingMode) (ret GpStatus) = gdiplus.GdipSetCompositingMode
382+
//sys GdipSetCompositingQuality(graphics *GpGraphics, compositingQuality CompositingQuality) (ret GpStatus) = gdiplus.GdipSetCompositingQuality
383+
//sys GdipSetInterpolationMode(graphics *GpGraphics, interpolationMode InterpolationMode) (ret GpStatus) = gdiplus.GdipSetInterpolationMode
384+
//sys GdipSetPixelOffsetMode(graphics *GpGraphics, pixelOffsetMode PixelOffsetMode) (ret GpStatus) = gdiplus.GdipSetPixelOffsetMode
385+
//sys GdipSetSmoothingMode(graphics *GpGraphics, smoothingMode SmoothingMode) (ret GpStatus) = gdiplus.GdipSetSmoothingMode
386+
//sys GdipSetStringFormatAlign(format *GpStringFormat, align StringAlignment) (ret GpStatus) = gdiplus.GdipSetStringFormatAlign
387+
//sys GdipSetStringFormatLineAlign(format *GpStringFormat, align StringAlignment) (ret GpStatus) = gdiplus.GdipSetStringFormatLineAlign
388+
//sys GdipSetTextRenderingHint(graphics *GpGraphics, mode TextRenderingHint) (ret GpStatus) = gdiplus.GdipSetTextRenderingHint

go.mod

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module github.com/tailscale/win
22

3-
go 1.12
3+
go 1.19
44

5-
require golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13
5+
require (
6+
github.com/dblohm7/wingoes v0.0.0-20230131214643-2b26ab7fb5f9
7+
golang.org/x/sys v0.4.0
8+
)

go.sum

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
github.com/dblohm7/wingoes v0.0.0-20230131214643-2b26ab7fb5f9 h1:BHpX4mgaPLK+6K0ByiQ3fJH9ZrwmHfPJWPIO3et9j6g=
2+
github.com/dblohm7/wingoes v0.0.0-20230131214643-2b26ab7fb5f9/go.mod h1:54MIJVGBIdbHuav7/YRAAhRxZvpEV9Z9p6jCKPLJ2lw=
3+
golang.org/x/exp v0.0.0-20230127140709-cafedaf64729 h1:H2kBA039yqxDv2DScpuC0knhZXO6Evfmt7mN8sGMh/4=
4+
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
5+
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

0 commit comments

Comments
 (0)