init
commit
26e0bf5bb5
@ -0,0 +1,10 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# GitHub Copilot persisted chat sessions
|
||||||
|
/copilot/chatSessions
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.idea/copilot/chatSessions" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/clipboard.iml" filepath="$PROJECT_DIR$/.idea/clipboard.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,112 @@
|
|||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Text FileType = "text"
|
||||||
|
File FileType = "file"
|
||||||
|
Image FileType = "image"
|
||||||
|
HTML FileType = "html"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Clipboard struct {
|
||||||
|
winOriginTypes []string
|
||||||
|
plateform string
|
||||||
|
date time.Time
|
||||||
|
secondaryOriType string
|
||||||
|
secondaryType FileType
|
||||||
|
secondaryData []byte
|
||||||
|
|
||||||
|
primaryOriType string
|
||||||
|
primaryType FileType
|
||||||
|
primaryData []byte
|
||||||
|
hash string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) PrimaryType() FileType {
|
||||||
|
return c.primaryType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) AvailableTypes() []FileType {
|
||||||
|
var res = make([]FileType, 0, 2)
|
||||||
|
if c.primaryType != "" {
|
||||||
|
res = append(res, c.primaryType)
|
||||||
|
}
|
||||||
|
if c.secondaryType != "" {
|
||||||
|
res = append(res, c.secondaryType)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) IsText() bool {
|
||||||
|
return c.primaryType == Text || c.secondaryType == Text
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) Text() string {
|
||||||
|
if c.primaryType == Text {
|
||||||
|
return string(c.primaryData)
|
||||||
|
}
|
||||||
|
if c.secondaryType == Text {
|
||||||
|
return string(c.secondaryData)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) IsHTML() bool {
|
||||||
|
return (c.primaryType == HTML || c.secondaryType == HTML) || c.IsText()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) HTML() string {
|
||||||
|
var htmlBytes []byte
|
||||||
|
if c.primaryType == HTML {
|
||||||
|
htmlBytes = c.primaryData
|
||||||
|
} else if c.secondaryType == HTML {
|
||||||
|
htmlBytes = c.secondaryData
|
||||||
|
} else {
|
||||||
|
return c.Text()
|
||||||
|
}
|
||||||
|
formats := strings.SplitN(string(htmlBytes), "\n", 7)
|
||||||
|
if len(formats) < 7 {
|
||||||
|
return string(htmlBytes)
|
||||||
|
}
|
||||||
|
return formats[6]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) FilePaths() []string {
|
||||||
|
if c.primaryType == File {
|
||||||
|
return strings.Split(string(c.primaryData), "|")
|
||||||
|
}
|
||||||
|
if c.secondaryType == File {
|
||||||
|
return strings.Split(string(c.secondaryData), "|")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) FirstFilePath() string {
|
||||||
|
if c.primaryType == File {
|
||||||
|
return strings.Split(string(c.primaryData), "|")[0]
|
||||||
|
}
|
||||||
|
if c.secondaryType == File {
|
||||||
|
return strings.Split(string(c.secondaryData), "|")[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) Image() []byte {
|
||||||
|
if c.primaryType == Image {
|
||||||
|
return c.primaryData
|
||||||
|
}
|
||||||
|
if c.secondaryType == Image {
|
||||||
|
return c.secondaryData
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clipboard) IsImage() bool {
|
||||||
|
return c.primaryType == Image || c.secondaryType == Image
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGet(t *testing.T) {
|
||||||
|
c, err := Get()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
fmt.Println(c.plateform)
|
||||||
|
fmt.Println(c.winOriginTypes)
|
||||||
|
fmt.Println(c.PrimaryType())
|
||||||
|
fmt.Println(c.AvailableTypes())
|
||||||
|
fmt.Println(c.Text())
|
||||||
|
fmt.Println(c.HTML())
|
||||||
|
fmt.Println(c.FilePaths())
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"b612.me/win32api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var winformat = map[win32api.DWORD]string{
|
||||||
|
1: "CF_TEXT",
|
||||||
|
2: "CF_BITMAP",
|
||||||
|
3: "CF_METAFILEPICT",
|
||||||
|
4: "CF_SYLK",
|
||||||
|
5: "CF_DIF",
|
||||||
|
6: "CF_TIFF",
|
||||||
|
7: "CF_OEMTEXT",
|
||||||
|
8: "CF_DIB",
|
||||||
|
9: "CF_PALETTE",
|
||||||
|
10: "CF_PENDATA",
|
||||||
|
11: "CF_RIFF",
|
||||||
|
12: "CF_WAVE",
|
||||||
|
13: "CF_UNICODETEXT",
|
||||||
|
14: "CF_ENHMETAFILE",
|
||||||
|
15: "CF_HDROP",
|
||||||
|
16: "CF_LOCALE",
|
||||||
|
17: "CF_DIBV5",
|
||||||
|
130: "CF_DSPBITMAP",
|
||||||
|
129: "CF_DSPTEXT",
|
||||||
|
131: "CF_DSPMETAFILEPICT",
|
||||||
|
142: "CF_DSPENHMETAFILE",
|
||||||
|
0x03FF: "CF_GDIOBJLAST",
|
||||||
|
0x0200: "CF_PRIVATEFIRST",
|
||||||
|
}
|
||||||
|
|
||||||
|
var formatRank = map[string]int{
|
||||||
|
"CF_UNICODETEXT": 1,
|
||||||
|
"CF_DIBV5": 2,
|
||||||
|
//"CF_DIB": 2,
|
||||||
|
"PNG": 2,
|
||||||
|
"HTML Format": 3,
|
||||||
|
"CF_HDROP": 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get() (Clipboard, error) {
|
||||||
|
return innerGetClipboard()
|
||||||
|
}
|
||||||
|
|
||||||
|
func innerGetClipboard() (Clipboard, error) {
|
||||||
|
var c = Clipboard{
|
||||||
|
plateform: "windows",
|
||||||
|
}
|
||||||
|
err := win32api.OpenClipboard(0)
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
defer win32api.CloseClipboard()
|
||||||
|
formats, err := win32api.GetUpdatedClipboardFormatsAll()
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
var firstFormatName, secondFormatName string
|
||||||
|
var firstFormat, secondFormat int = 65535, 65535
|
||||||
|
for _, format := range formats {
|
||||||
|
if d, ok := winformat[format]; ok {
|
||||||
|
if formatRank[d] > 0 {
|
||||||
|
if formatRank[d] < firstFormat {
|
||||||
|
secondFormat = firstFormat
|
||||||
|
secondFormatName = firstFormatName
|
||||||
|
firstFormat = formatRank[d]
|
||||||
|
firstFormatName = d
|
||||||
|
} else if formatRank[d] != firstFormat && formatRank[d] < secondFormat {
|
||||||
|
secondFormat = formatRank[d]
|
||||||
|
secondFormatName = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.winOriginTypes = append(c.winOriginTypes, d)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
d, e := win32api.GetClipboardFormatName(format)
|
||||||
|
if e != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if formatRank[d] > 0 {
|
||||||
|
if formatRank[d] < firstFormat {
|
||||||
|
secondFormat = firstFormat
|
||||||
|
secondFormatName = firstFormatName
|
||||||
|
firstFormat = formatRank[d]
|
||||||
|
firstFormatName = d
|
||||||
|
} else if formatRank[d] != firstFormat && formatRank[d] < secondFormat {
|
||||||
|
secondFormat = formatRank[d]
|
||||||
|
secondFormatName = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.winOriginTypes = append(c.winOriginTypes, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.primaryOriType = firstFormatName
|
||||||
|
switch c.primaryOriType {
|
||||||
|
case "CF_UNICODETEXT":
|
||||||
|
c.primaryType = Text
|
||||||
|
case "HTML Format":
|
||||||
|
c.primaryType = HTML
|
||||||
|
case "PNG", "CF_DIBV5", "CF_DIB":
|
||||||
|
c.primaryType = Image
|
||||||
|
case "CF_HDROP":
|
||||||
|
c.primaryType = File
|
||||||
|
}
|
||||||
|
c.primaryData, err = AutoFetcher(firstFormatName)
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
if secondFormatName != "" {
|
||||||
|
switch secondFormatName {
|
||||||
|
case "CF_UNICODETEXT":
|
||||||
|
c.secondaryType = Text
|
||||||
|
case "HTML Format":
|
||||||
|
c.secondaryType = HTML
|
||||||
|
case "PNG", "CF_DIBV5", "CF_DIB":
|
||||||
|
c.secondaryType = Image
|
||||||
|
case "CF_HDROP":
|
||||||
|
c.secondaryType = File
|
||||||
|
}
|
||||||
|
c.secondaryOriType = secondFormatName
|
||||||
|
c.secondaryData, err = AutoFetcher(secondFormatName)
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTopMatch() {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
module b612.me/clipboard
|
||||||
|
|
||||||
|
go 1.21.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
b612.me/win32api v0.0.0-20240326080749-ad19f5cd4247
|
||||||
|
golang.org/x/image v0.15.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.18.0 // indirect
|
@ -0,0 +1,6 @@
|
|||||||
|
b612.me/win32api v0.0.0-20240326080749-ad19f5cd4247 h1:fDTZ1HzVtVpEcXqlsQB9O2AbtrbqiAruaRX1Yd7M9Z8=
|
||||||
|
b612.me/win32api v0.0.0-20240326080749-ad19f5cd4247/go.mod h1:sj66sFJDKElEjOR+0YhdSW6b4kq4jsXu4T5/Hnpyot0=
|
||||||
|
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
|
||||||
|
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
@ -0,0 +1,215 @@
|
|||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"b612.me/win32api"
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"golang.org/x/image/bmp"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fetchClipboardData(uFormat win32api.DWORD, fn func(p unsafe.Pointer, size uint32) ([]byte, error)) ([]byte, error) {
|
||||||
|
mem, err := win32api.GetClipboardData(uFormat)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p, err := win32api.GlobalLock(mem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer win32api.GlobalUnlock(mem)
|
||||||
|
size, err := win32api.GlobalSize(mem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if fn == nil {
|
||||||
|
return defaultFetchFn(p, uint32(size))
|
||||||
|
}
|
||||||
|
return fn(p, uint32(size))
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultFetchFn(p unsafe.Pointer, size uint32) ([]byte, error) {
|
||||||
|
var buf []byte
|
||||||
|
for i := 0; i < int(size); i++ {
|
||||||
|
buf = append(buf, *(*byte)(unsafe.Pointer(uintptr(p) + uintptr(i))))
|
||||||
|
}
|
||||||
|
return buf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AutoFetcher(uFormat string) ([]byte, error) {
|
||||||
|
switch uFormat {
|
||||||
|
case "CF_TEXT", "CF_UNICODETEXT":
|
||||||
|
return fetchClipboardData(win32api.CF_UNICODETEXT, textFetcher)
|
||||||
|
case "HTML Format":
|
||||||
|
return fetchClipboardData(win32api.RegisterClipboardFormat("HTML Format"), nil)
|
||||||
|
case "CF_HDROP":
|
||||||
|
return fetchClipboardData(win32api.CF_HDROP, filedropFetcher)
|
||||||
|
case "CF_DIBV5":
|
||||||
|
return fetchClipboardData(win32api.CF_DIBV5, cfDIBv5Fetcher)
|
||||||
|
case "CF_DIB":
|
||||||
|
return fetchClipboardData(win32api.CF_DIB, cfDIBFetcher)
|
||||||
|
case "PNG":
|
||||||
|
return fetchClipboardData(win32api.RegisterClipboardFormat("PNG"), nil)
|
||||||
|
}
|
||||||
|
return nil, errors.New("not support uFormat:" + uFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
func textFetcher(p unsafe.Pointer, size uint32) ([]byte, error) {
|
||||||
|
var buf []uint16
|
||||||
|
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*((*uint16)(unsafe.Pointer(p))))) {
|
||||||
|
buf = append(buf, *(*uint16)(ptr))
|
||||||
|
}
|
||||||
|
return []byte(syscall.UTF16ToString(buf)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func filedropFetcher(p unsafe.Pointer, size uint32) ([]byte, error) {
|
||||||
|
var res []string
|
||||||
|
c, err := win32api.DragQueryFile(win32api.HDROP(p), 0xFFFFFFFF, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
count := int(c)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
c, err = win32api.DragQueryFile(win32api.HDROP(p), win32api.DWORD(i), nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
length := int(c)
|
||||||
|
buffer := make([]uint16, length+1)
|
||||||
|
|
||||||
|
_, err = win32api.DragQueryFile(win32api.HDROP(p), win32api.DWORD(i),
|
||||||
|
&buffer[0], win32api.DWORD(len(buffer)))
|
||||||
|
res = append(res, syscall.UTF16ToString(buffer))
|
||||||
|
}
|
||||||
|
return []byte(strings.Join(res, "|")), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cfDIBv5Fetcher(p unsafe.Pointer, size uint32) ([]byte, error) {
|
||||||
|
// inspect header information
|
||||||
|
info := (*bitmapV5Header)(unsafe.Pointer(p))
|
||||||
|
// maybe deal with other formats?
|
||||||
|
if info.BitCount != 32 {
|
||||||
|
return nil, errors.New("not support image format")
|
||||||
|
}
|
||||||
|
|
||||||
|
var data []byte
|
||||||
|
sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
||||||
|
sh.Data = uintptr(p)
|
||||||
|
sh.Cap = int(info.Size + 4*uint32(info.Width)*uint32(info.Height))
|
||||||
|
sh.Len = int(info.Size + 4*uint32(info.Width)*uint32(info.Height))
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, int(info.Width), int(info.Height)))
|
||||||
|
offset := int(info.Size)
|
||||||
|
stride := int(info.Width)
|
||||||
|
for y := 0; y < int(info.Height); y++ {
|
||||||
|
for x := 0; x < int(info.Width); x++ {
|
||||||
|
idx := offset + 4*(y*stride+x)
|
||||||
|
xhat := (x + int(info.Width)) % int(info.Width)
|
||||||
|
yhat := int(info.Height) - 1 - y
|
||||||
|
r := data[idx+2]
|
||||||
|
g := data[idx+1]
|
||||||
|
b := data[idx+0]
|
||||||
|
a := data[idx+3]
|
||||||
|
img.SetRGBA(xhat, yhat, color.RGBA{r, g, b, a})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// always use PNG encoding.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := png.Encode(&buf, img)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cfDIBFetcher(p unsafe.Pointer, size uint32) ([]byte, error) {
|
||||||
|
// 函数意外报错,待修正
|
||||||
|
const (
|
||||||
|
fileHeaderLen = 14
|
||||||
|
infoHeaderLen = 40
|
||||||
|
)
|
||||||
|
bmpHeader := (*bitmapHeader)(p)
|
||||||
|
dataSize := bmpHeader.SizeImage + fileHeaderLen + infoHeaderLen
|
||||||
|
|
||||||
|
if bmpHeader.SizeImage == 0 && bmpHeader.Compression == 0 {
|
||||||
|
iSizeImage := bmpHeader.Height * ((bmpHeader.Width*uint32(bmpHeader.BitCount)/8 + 3) &^ 3)
|
||||||
|
dataSize += iSizeImage
|
||||||
|
}
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
binary.Write(buf, binary.LittleEndian, uint16('B')|(uint16('M')<<8))
|
||||||
|
binary.Write(buf, binary.LittleEndian, uint32(dataSize))
|
||||||
|
binary.Write(buf, binary.LittleEndian, uint32(0))
|
||||||
|
const sizeof_colorbar = 0
|
||||||
|
binary.Write(buf, binary.LittleEndian, uint32(fileHeaderLen+infoHeaderLen+sizeof_colorbar))
|
||||||
|
j := 0
|
||||||
|
for i := fileHeaderLen; i < int(dataSize); i++ {
|
||||||
|
binary.Write(buf, binary.BigEndian, *(*byte)(unsafe.Pointer(uintptr(p) + uintptr(j))))
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
return bmpToPng(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bmpToPng(bmpBuf *bytes.Buffer) (buf []byte, err error) {
|
||||||
|
var f bytes.Buffer
|
||||||
|
original_image, err := bmp.Decode(bmpBuf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = png.Encode(&f, original_image)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type bitmapV5Header struct {
|
||||||
|
Size uint32
|
||||||
|
Width int32
|
||||||
|
Height int32
|
||||||
|
Planes uint16
|
||||||
|
BitCount uint16
|
||||||
|
Compression uint32
|
||||||
|
SizeImage uint32
|
||||||
|
XPelsPerMeter int32
|
||||||
|
YPelsPerMeter int32
|
||||||
|
ClrUsed uint32
|
||||||
|
ClrImportant uint32
|
||||||
|
RedMask uint32
|
||||||
|
GreenMask uint32
|
||||||
|
BlueMask uint32
|
||||||
|
AlphaMask uint32
|
||||||
|
CSType uint32
|
||||||
|
Endpoints struct {
|
||||||
|
CiexyzRed, CiexyzGreen, CiexyzBlue struct {
|
||||||
|
CiexyzX, CiexyzY, CiexyzZ int32 // FXPT2DOT30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GammaRed uint32
|
||||||
|
GammaGreen uint32
|
||||||
|
GammaBlue uint32
|
||||||
|
Intent uint32
|
||||||
|
ProfileData uint32
|
||||||
|
ProfileSize uint32
|
||||||
|
Reserved uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type bitmapHeader struct {
|
||||||
|
Size uint32
|
||||||
|
Width uint32
|
||||||
|
Height uint32
|
||||||
|
PLanes uint16
|
||||||
|
BitCount uint16
|
||||||
|
Compression uint32
|
||||||
|
SizeImage uint32
|
||||||
|
XPelsPerMeter uint32
|
||||||
|
YPelsPerMeter uint32
|
||||||
|
ClrUsed uint32
|
||||||
|
ClrImportant uint32
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package clipboard
|
||||||
|
|
||||||
|
func Listen() (<-chan Clipboard, error)
|
||||||
|
res := make(chan Clipboard)
|
||||||
|
}
|
Loading…
Reference in New Issue