mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
colorpick/screenshot: make color-format aware
This commit is contained in:
@@ -178,7 +178,7 @@ func runScreenshot(config screenshot.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Stdout {
|
if config.Stdout {
|
||||||
if err := writeImageToStdout(result.Buffer, config.Format, config.Quality); err != nil {
|
if err := writeImageToStdout(result.Buffer, config.Format, config.Quality, result.Format); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error writing to stdout: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Error writing to stdout: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ func runScreenshot(config screenshot.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
filePath = filepath.Join(outputDir, filename)
|
filePath = filepath.Join(outputDir, filename)
|
||||||
if err := screenshot.WriteToFile(result.Buffer, filePath, config.Format, config.Quality); err != nil {
|
if err := screenshot.WriteToFileWithFormat(result.Buffer, filePath, config.Format, config.Quality, result.Format); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error writing file: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Error writing file: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,7 @@ func runScreenshot(config screenshot.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Clipboard {
|
if config.Clipboard {
|
||||||
if err := copyImageToClipboard(result.Buffer, config.Format, config.Quality); err != nil {
|
if err := copyImageToClipboard(result.Buffer, config.Format, config.Quality, result.Format); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error copying to clipboard: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Error copying to clipboard: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ func runScreenshot(config screenshot.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Notify {
|
if config.Notify {
|
||||||
thumbData, thumbW, thumbH := bufferToRGBThumbnail(result.Buffer, 256)
|
thumbData, thumbW, thumbH := bufferToRGBThumbnail(result.Buffer, 256, result.Format)
|
||||||
screenshot.SendNotification(screenshot.NotifyResult{
|
screenshot.SendNotification(screenshot.NotifyResult{
|
||||||
FilePath: filePath,
|
FilePath: filePath,
|
||||||
Clipboard: config.Clipboard,
|
Clipboard: config.Clipboard,
|
||||||
@@ -228,11 +228,11 @@ func runScreenshot(config screenshot.Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyImageToClipboard(buf *screenshot.ShmBuffer, format screenshot.Format, quality int) error {
|
func copyImageToClipboard(buf *screenshot.ShmBuffer, format screenshot.Format, quality int, pixelFormat uint32) error {
|
||||||
var mimeType string
|
var mimeType string
|
||||||
var data bytes.Buffer
|
var data bytes.Buffer
|
||||||
|
|
||||||
img := screenshot.BufferToImage(buf)
|
img := screenshot.BufferToImageWithFormat(buf, pixelFormat)
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case screenshot.FormatJPEG:
|
case screenshot.FormatJPEG:
|
||||||
@@ -252,8 +252,8 @@ func copyImageToClipboard(buf *screenshot.ShmBuffer, format screenshot.Format, q
|
|||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeImageToStdout(buf *screenshot.ShmBuffer, format screenshot.Format, quality int) error {
|
func writeImageToStdout(buf *screenshot.ShmBuffer, format screenshot.Format, quality int, pixelFormat uint32) error {
|
||||||
img := screenshot.BufferToImage(buf)
|
img := screenshot.BufferToImageWithFormat(buf, pixelFormat)
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case screenshot.FormatJPEG:
|
case screenshot.FormatJPEG:
|
||||||
@@ -263,7 +263,7 @@ func writeImageToStdout(buf *screenshot.ShmBuffer, format screenshot.Format, qua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func bufferToRGBThumbnail(buf *screenshot.ShmBuffer, maxSize int) ([]byte, int, int) {
|
func bufferToRGBThumbnail(buf *screenshot.ShmBuffer, maxSize int, pixelFormat uint32) ([]byte, int, int) {
|
||||||
srcW, srcH := buf.Width, buf.Height
|
srcW, srcH := buf.Width, buf.Height
|
||||||
scale := 1.0
|
scale := 1.0
|
||||||
if srcW > maxSize || srcH > maxSize {
|
if srcW > maxSize || srcH > maxSize {
|
||||||
@@ -285,6 +285,7 @@ func bufferToRGBThumbnail(buf *screenshot.ShmBuffer, maxSize int) ([]byte, int,
|
|||||||
|
|
||||||
data := buf.Data()
|
data := buf.Data()
|
||||||
rgb := make([]byte, dstW*dstH*3)
|
rgb := make([]byte, dstW*dstH*3)
|
||||||
|
swapRB := pixelFormat == uint32(screenshot.FormatARGB8888) || pixelFormat == uint32(screenshot.FormatXRGB8888) || pixelFormat == 0
|
||||||
|
|
||||||
for y := 0; y < dstH; y++ {
|
for y := 0; y < dstH; y++ {
|
||||||
srcY := int(float64(y) / scale)
|
srcY := int(float64(y) / scale)
|
||||||
@@ -299,9 +300,15 @@ func bufferToRGBThumbnail(buf *screenshot.ShmBuffer, maxSize int) ([]byte, int,
|
|||||||
si := srcY*buf.Stride + srcX*4
|
si := srcY*buf.Stride + srcX*4
|
||||||
di := (y*dstW + x) * 3
|
di := (y*dstW + x) * 3
|
||||||
if si+2 < len(data) {
|
if si+2 < len(data) {
|
||||||
rgb[di+0] = data[si+2] // R
|
if swapRB {
|
||||||
rgb[di+1] = data[si+1] // G
|
rgb[di+0] = data[si+2]
|
||||||
rgb[di+2] = data[si+0] // B
|
rgb[di+1] = data[si+1]
|
||||||
|
rgb[di+2] = data[si+0]
|
||||||
|
} else {
|
||||||
|
rgb[di+0] = data[si+0]
|
||||||
|
rgb[di+1] = data[si+1]
|
||||||
|
rgb[di+2] = data[si+2]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ type LayerSurface struct {
|
|||||||
viewport *wp_viewporter.WpViewport
|
viewport *wp_viewporter.WpViewport
|
||||||
wlPool *client.ShmPool
|
wlPool *client.ShmPool
|
||||||
wlBuffer *client.Buffer
|
wlBuffer *client.Buffer
|
||||||
|
bufferBusy bool
|
||||||
|
oldPool *client.ShmPool
|
||||||
|
oldBuffer *client.Buffer
|
||||||
|
scopyBuffer *client.Buffer
|
||||||
configured bool
|
configured bool
|
||||||
hidden bool
|
hidden bool
|
||||||
}
|
}
|
||||||
@@ -463,6 +467,12 @@ func (p *Picker) captureForSurface(ls *LayerSurface) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ls.scopyBuffer != nil {
|
||||||
|
ls.scopyBuffer.Destroy()
|
||||||
|
}
|
||||||
|
ls.scopyBuffer = wlBuffer
|
||||||
|
wlBuffer.SetReleaseHandler(func(e client.BufferReleaseEvent) {})
|
||||||
|
|
||||||
if err := frame.Copy(wlBuffer); err != nil {
|
if err := frame.Copy(wlBuffer); err != nil {
|
||||||
log.Error("failed to copy frame", "err", err)
|
log.Error("failed to copy frame", "err", err)
|
||||||
}
|
}
|
||||||
@@ -489,7 +499,6 @@ func (p *Picker) captureForSurface(ls *LayerSurface) {
|
|||||||
func (p *Picker) redrawSurface(ls *LayerSurface) {
|
func (p *Picker) redrawSurface(ls *LayerSurface) {
|
||||||
var renderBuf *ShmBuffer
|
var renderBuf *ShmBuffer
|
||||||
if ls.hidden {
|
if ls.hidden {
|
||||||
// When hidden, just show the screenshot without overlay
|
|
||||||
renderBuf = ls.state.RedrawScreenOnly()
|
renderBuf = ls.state.RedrawScreenOnly()
|
||||||
} else {
|
} else {
|
||||||
renderBuf = ls.state.Redraw()
|
renderBuf = ls.state.Redraw()
|
||||||
@@ -498,14 +507,19 @@ func (p *Picker) redrawSurface(ls *LayerSurface) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ls.wlPool != nil {
|
if ls.oldBuffer != nil {
|
||||||
ls.wlPool.Destroy()
|
ls.oldBuffer.Destroy()
|
||||||
|
ls.oldBuffer = nil
|
||||||
|
}
|
||||||
|
if ls.oldPool != nil {
|
||||||
|
ls.oldPool.Destroy()
|
||||||
|
ls.oldPool = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ls.oldPool = ls.wlPool
|
||||||
|
ls.oldBuffer = ls.wlBuffer
|
||||||
ls.wlPool = nil
|
ls.wlPool = nil
|
||||||
}
|
|
||||||
if ls.wlBuffer != nil {
|
|
||||||
ls.wlBuffer.Destroy()
|
|
||||||
ls.wlBuffer = nil
|
ls.wlBuffer = nil
|
||||||
}
|
|
||||||
|
|
||||||
pool, err := p.shm.CreatePool(renderBuf.Fd(), int32(renderBuf.Size()))
|
pool, err := p.shm.CreatePool(renderBuf.Fd(), int32(renderBuf.Size()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -513,12 +527,18 @@ func (p *Picker) redrawSurface(ls *LayerSurface) {
|
|||||||
}
|
}
|
||||||
ls.wlPool = pool
|
ls.wlPool = pool
|
||||||
|
|
||||||
wlBuffer, err := pool.CreateBuffer(0, int32(renderBuf.Width), int32(renderBuf.Height), int32(renderBuf.Stride), uint32(FormatARGB8888))
|
wlBuffer, err := pool.CreateBuffer(0, int32(renderBuf.Width), int32(renderBuf.Height), int32(renderBuf.Stride), uint32(ls.state.ScreenFormat()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ls.wlBuffer = wlBuffer
|
ls.wlBuffer = wlBuffer
|
||||||
|
|
||||||
|
lsRef := ls
|
||||||
|
wlBuffer.SetReleaseHandler(func(e client.BufferReleaseEvent) {
|
||||||
|
lsRef.bufferBusy = false
|
||||||
|
})
|
||||||
|
ls.bufferBusy = true
|
||||||
|
|
||||||
logicalW, logicalH := ls.state.LogicalSize()
|
logicalW, logicalH := ls.state.LogicalSize()
|
||||||
if logicalW == 0 || logicalH == 0 {
|
if logicalW == 0 || logicalH == 0 {
|
||||||
logicalW = int(ls.output.width)
|
logicalW = int(ls.output.width)
|
||||||
@@ -533,30 +553,13 @@ func (p *Picker) redrawSurface(ls *LayerSurface) {
|
|||||||
if ls.viewport != nil {
|
if ls.viewport != nil {
|
||||||
srcW := float64(renderBuf.Width) / float64(scale)
|
srcW := float64(renderBuf.Width) / float64(scale)
|
||||||
srcH := float64(renderBuf.Height) / float64(scale)
|
srcH := float64(renderBuf.Height) / float64(scale)
|
||||||
if err := ls.viewport.SetSource(0, 0, srcW, srcH); err != nil {
|
_ = ls.viewport.SetSource(0, 0, srcW, srcH)
|
||||||
log.Warn("failed to set viewport source", "err", err)
|
_ = ls.viewport.SetDestination(int32(logicalW), int32(logicalH))
|
||||||
}
|
|
||||||
if err := ls.viewport.SetDestination(int32(logicalW), int32(logicalH)); err != nil {
|
|
||||||
log.Warn("failed to set viewport destination", "err", err)
|
|
||||||
}
|
|
||||||
if err := ls.wlSurface.SetBufferScale(scale); err != nil {
|
|
||||||
log.Warn("failed to set buffer scale", "err", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := ls.wlSurface.SetBufferScale(scale); err != nil {
|
|
||||||
log.Warn("failed to set buffer scale", "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ls.wlSurface.Attach(wlBuffer, 0, 0); err != nil {
|
|
||||||
log.Warn("failed to attach buffer", "err", err)
|
|
||||||
}
|
|
||||||
if err := ls.wlSurface.Damage(0, 0, int32(logicalW), int32(logicalH)); err != nil {
|
|
||||||
log.Warn("failed to damage surface", "err", err)
|
|
||||||
}
|
|
||||||
if err := ls.wlSurface.Commit(); err != nil {
|
|
||||||
log.Warn("failed to commit surface", "err", err)
|
|
||||||
}
|
}
|
||||||
|
_ = ls.wlSurface.SetBufferScale(scale)
|
||||||
|
_ = ls.wlSurface.Attach(wlBuffer, 0, 0)
|
||||||
|
_ = ls.wlSurface.Damage(0, 0, int32(logicalW), int32(logicalH))
|
||||||
|
_ = ls.wlSurface.Commit()
|
||||||
|
|
||||||
ls.state.SwapBuffers()
|
ls.state.SwapBuffers()
|
||||||
}
|
}
|
||||||
@@ -599,9 +602,14 @@ func (p *Picker) setupPointerHandlers() {
|
|||||||
log.Debug("failed to hide cursor", "err", err)
|
log.Debug("failed to hide cursor", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if e.Surface == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
p.activeSurface = nil
|
p.activeSurface = nil
|
||||||
|
surfaceID := e.Surface.ID()
|
||||||
for _, ls := range p.surfaces {
|
for _, ls := range p.surfaces {
|
||||||
if ls.wlSurface.ID() == e.Surface.ID() {
|
if ls.wlSurface.ID() == surfaceID {
|
||||||
p.activeSurface = ls
|
p.activeSurface = ls
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -610,7 +618,6 @@ func (p *Picker) setupPointerHandlers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If surface was hidden, mark it as visible again
|
|
||||||
if p.activeSurface.hidden {
|
if p.activeSurface.hidden {
|
||||||
p.activeSurface.hidden = false
|
p.activeSurface.hidden = false
|
||||||
}
|
}
|
||||||
@@ -620,8 +627,12 @@ func (p *Picker) setupPointerHandlers() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
p.pointer.SetLeaveHandler(func(e client.PointerLeaveEvent) {
|
p.pointer.SetLeaveHandler(func(e client.PointerLeaveEvent) {
|
||||||
|
if e.Surface == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
surfaceID := e.Surface.ID()
|
||||||
for _, ls := range p.surfaces {
|
for _, ls := range p.surfaces {
|
||||||
if ls.wlSurface.ID() == e.Surface.ID() {
|
if ls.wlSurface.ID() == surfaceID {
|
||||||
p.hideSurface(ls)
|
p.hideSurface(ls)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -654,6 +665,15 @@ func (p *Picker) setupKeyboardHandlers() {
|
|||||||
|
|
||||||
func (p *Picker) cleanup() {
|
func (p *Picker) cleanup() {
|
||||||
for _, ls := range p.surfaces {
|
for _, ls := range p.surfaces {
|
||||||
|
if ls.scopyBuffer != nil {
|
||||||
|
ls.scopyBuffer.Destroy()
|
||||||
|
}
|
||||||
|
if ls.oldBuffer != nil {
|
||||||
|
ls.oldBuffer.Destroy()
|
||||||
|
}
|
||||||
|
if ls.oldPool != nil {
|
||||||
|
ls.oldPool.Destroy()
|
||||||
|
}
|
||||||
if ls.wlBuffer != nil {
|
if ls.wlBuffer != nil {
|
||||||
ls.wlBuffer.Destroy()
|
ls.wlBuffer.Destroy()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ func CreateShmBuffer(width, height, stride int) (*ShmBuffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetPixelColor(buf *ShmBuffer, x, y int) Color {
|
func GetPixelColor(buf *ShmBuffer, x, y int) Color {
|
||||||
|
return GetPixelColorWithFormat(buf, x, y, FormatARGB8888)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPixelColorWithFormat(buf *ShmBuffer, x, y int, format PixelFormat) Color {
|
||||||
if x < 0 || x >= buf.Width || y < 0 || y >= buf.Height {
|
if x < 0 || x >= buf.Width || y < 0 || y >= buf.Height {
|
||||||
return Color{}
|
return Color{}
|
||||||
}
|
}
|
||||||
@@ -19,6 +23,14 @@ func GetPixelColor(buf *ShmBuffer, x, y int) Color {
|
|||||||
return Color{}
|
return Color{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if format == FormatABGR8888 || format == FormatXBGR8888 {
|
||||||
|
return Color{
|
||||||
|
R: data[offset],
|
||||||
|
G: data[offset+1],
|
||||||
|
B: data[offset+2],
|
||||||
|
A: data[offset+3],
|
||||||
|
}
|
||||||
|
}
|
||||||
return Color{
|
return Color{
|
||||||
B: data[offset],
|
B: data[offset],
|
||||||
G: data[offset+1],
|
G: data[offset+1],
|
||||||
|
|||||||
@@ -100,6 +100,12 @@ func (s *SurfaceState) ScreenBuffer() *ShmBuffer {
|
|||||||
return s.screenBuf
|
return s.screenBuf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SurfaceState) ScreenFormat() PixelFormat {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
return s.screenFormat
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SurfaceState) OnScreencopyFlags(flags uint32) {
|
func (s *SurfaceState) OnScreencopyFlags(flags uint32) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
s.yInverted = (flags & 1) != 0
|
s.yInverted = (flags & 1) != 0
|
||||||
@@ -263,7 +269,7 @@ func (s *SurfaceState) Redraw() *ShmBuffer {
|
|||||||
px = clamp(px, 0, dst.Width-1)
|
px = clamp(px, 0, dst.Width-1)
|
||||||
py = clamp(py, 0, dst.Height-1)
|
py = clamp(py, 0, dst.Height-1)
|
||||||
|
|
||||||
picked := GetPixelColor(s.screenBuf, px, py)
|
picked := GetPixelColorWithFormat(s.screenBuf, px, py, s.screenFormat)
|
||||||
|
|
||||||
drawMagnifier(
|
drawMagnifier(
|
||||||
dst.Data(), dst.Stride, dst.Width, dst.Height,
|
dst.Data(), dst.Stride, dst.Width, dst.Height,
|
||||||
@@ -313,7 +319,7 @@ func (s *SurfaceState) PickColor() (Color, bool) {
|
|||||||
sy = s.screenBuf.Height - 1 - sy
|
sy = s.screenBuf.Height - 1 - sy
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetPixelColor(s.screenBuf, sx, sy), true
|
return GetPixelColorWithFormat(s.screenBuf, sx, sy, s.screenFormat), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SurfaceState) Destroy() {
|
func (s *SurfaceState) Destroy() {
|
||||||
|
|||||||
@@ -13,8 +13,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func BufferToImage(buf *ShmBuffer) *image.RGBA {
|
func BufferToImage(buf *ShmBuffer) *image.RGBA {
|
||||||
|
return BufferToImageWithFormat(buf, uint32(FormatARGB8888))
|
||||||
|
}
|
||||||
|
|
||||||
|
func BufferToImageWithFormat(buf *ShmBuffer, format uint32) *image.RGBA {
|
||||||
img := image.NewRGBA(image.Rect(0, 0, buf.Width, buf.Height))
|
img := image.NewRGBA(image.Rect(0, 0, buf.Width, buf.Height))
|
||||||
data := buf.Data()
|
data := buf.Data()
|
||||||
|
|
||||||
|
swapRB := format == uint32(FormatARGB8888) || format == uint32(FormatXRGB8888) || format == 0
|
||||||
|
|
||||||
for y := 0; y < buf.Height; y++ {
|
for y := 0; y < buf.Height; y++ {
|
||||||
srcOff := y * buf.Stride
|
srcOff := y * buf.Stride
|
||||||
dstOff := y * img.Stride
|
dstOff := y * img.Stride
|
||||||
@@ -24,10 +31,16 @@ func BufferToImage(buf *ShmBuffer) *image.RGBA {
|
|||||||
if si+3 >= len(data) || di+3 >= len(img.Pix) {
|
if si+3 >= len(data) || di+3 >= len(img.Pix) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
img.Pix[di+0] = data[si+2] // R
|
if swapRB {
|
||||||
img.Pix[di+1] = data[si+1] // G
|
img.Pix[di+0] = data[si+2]
|
||||||
img.Pix[di+2] = data[si+0] // B
|
img.Pix[di+1] = data[si+1]
|
||||||
img.Pix[di+3] = 255 // A
|
img.Pix[di+2] = data[si+0]
|
||||||
|
} else {
|
||||||
|
img.Pix[di+0] = data[si+0]
|
||||||
|
img.Pix[di+1] = data[si+1]
|
||||||
|
img.Pix[di+2] = data[si+2]
|
||||||
|
}
|
||||||
|
img.Pix[di+3] = 255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return img
|
return img
|
||||||
@@ -162,13 +175,17 @@ func expandHome(path string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WriteToFile(buf *ShmBuffer, path string, format Format, quality int) error {
|
func WriteToFile(buf *ShmBuffer, path string, format Format, quality int) error {
|
||||||
|
return WriteToFileWithFormat(buf, path, format, quality, uint32(FormatARGB8888))
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteToFileWithFormat(buf *ShmBuffer, path string, format Format, quality int, pixelFormat uint32) error {
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
img := BufferToImage(buf)
|
img := BufferToImageWithFormat(buf, pixelFormat)
|
||||||
switch format {
|
switch format {
|
||||||
case FormatJPEG:
|
case FormatJPEG:
|
||||||
return EncodeJPEG(f, img, quality)
|
return EncodeJPEG(f, img, quality)
|
||||||
|
|||||||
@@ -160,14 +160,17 @@ func (r *RegionSelector) Run() (*CaptureResult, bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
yInverted := false
|
yInverted := false
|
||||||
|
var format uint32
|
||||||
if r.selection.surface != nil {
|
if r.selection.surface != nil {
|
||||||
yInverted = r.selection.surface.yInverted
|
yInverted = r.selection.surface.yInverted
|
||||||
|
format = r.selection.surface.screenFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CaptureResult{
|
return &CaptureResult{
|
||||||
Buffer: r.capturedBuffer,
|
Buffer: r.capturedBuffer,
|
||||||
Region: r.result, // Global coords for saving last region
|
Region: r.result,
|
||||||
YInverted: yInverted,
|
YInverted: yInverted,
|
||||||
|
Format: format,
|
||||||
}, false, nil
|
}, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,9 +98,10 @@ func (r *RegionSelector) setupPointerHandlers() {
|
|||||||
case 0x110: // BTN_LEFT
|
case 0x110: // BTN_LEFT
|
||||||
switch e.State {
|
switch e.State {
|
||||||
case 1: // pressed
|
case 1: // pressed
|
||||||
|
r.preSelect = Region{}
|
||||||
r.selection.hasSelection = true
|
r.selection.hasSelection = true
|
||||||
r.selection.dragging = true
|
r.selection.dragging = true
|
||||||
r.selection.surface = r.activeSurface // Lock to this surface
|
r.selection.surface = r.activeSurface
|
||||||
r.selection.anchorX = r.pointerX
|
r.selection.anchorX = r.pointerX
|
||||||
r.selection.anchorY = r.pointerY
|
r.selection.anchorY = r.pointerY
|
||||||
r.selection.currentX = r.pointerX
|
r.selection.currentX = r.pointerX
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ type CaptureResult struct {
|
|||||||
Buffer *ShmBuffer
|
Buffer *ShmBuffer
|
||||||
Region Region
|
Region Region
|
||||||
YInverted bool
|
YInverted bool
|
||||||
|
Format uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type Screenshoter struct {
|
type Screenshoter struct {
|
||||||
@@ -206,6 +207,7 @@ func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) {
|
|||||||
|
|
||||||
composite.Clear()
|
composite.Clear()
|
||||||
|
|
||||||
|
var format uint32
|
||||||
for _, output := range outputs {
|
for _, output := range outputs {
|
||||||
result, err := s.captureWholeOutput(output)
|
result, err := s.captureWholeOutput(output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -213,6 +215,9 @@ func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if format == 0 {
|
||||||
|
format = result.Format
|
||||||
|
}
|
||||||
s.blitBuffer(composite, result.Buffer, int(output.x-minX), int(output.y-minY), result.YInverted)
|
s.blitBuffer(composite, result.Buffer, int(output.x-minX), int(output.y-minY), result.YInverted)
|
||||||
result.Buffer.Close()
|
result.Buffer.Close()
|
||||||
}
|
}
|
||||||
@@ -220,6 +225,7 @@ func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) {
|
|||||||
return &CaptureResult{
|
return &CaptureResult{
|
||||||
Buffer: composite,
|
Buffer: composite,
|
||||||
Region: Region{X: minX, Y: minY, Width: totalW, Height: totalH},
|
Region: Region{X: minX, Y: minY, Width: totalW, Height: totalH},
|
||||||
|
Format: format,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,6 +385,7 @@ func (s *Screenshoter) processFrame(frame *wlr_screencopy.ZwlrScreencopyFrameV1,
|
|||||||
Buffer: buf,
|
Buffer: buf,
|
||||||
Region: region,
|
Region: region,
|
||||||
YInverted: yInverted,
|
YInverted: yInverted,
|
||||||
|
Format: uint32(format),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user