func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Use the "NewDrawable" constructor to create an xgraphics.Image value // from a drawable. (Usually this is done with pixmaps, but drawables // can also be windows.) ximg, err := xgraphics.NewDrawable(X, xproto.Drawable(X.RootWin())) if err != nil { log.Fatal(err) } // Shows the screenshot in a window. ximg.XShowExtra("Screenshot", true) // If you'd like to save it as a png, use: // err = ximg.SavePng("screenshot.png") // if err != nil { // log.Fatal(err) // } xevent.Main(X) }
func (self *SessionModule) WriteWindowImage(window_id string, w io.Writer) error { if id, err := self.toX11WindowId(window_id); err == nil { drawable := xproto.Drawable(id) if image, err := xgraphics.NewDrawable(self.X, drawable); err == nil { image.XSurfaceSet(id) image.XDraw() return image.WritePng(w) } else { return err } } else { return err } }
func icon2md5(xid xproto.Window) []byte { pixmap, _ := xproto.NewPixmapId(TrayXU.Conn()) defer xproto.FreePixmap(TrayXU.Conn(), pixmap) if err := composite.NameWindowPixmapChecked(TrayXU.Conn(), xid, pixmap).Check(); err != nil { logger.Warning("NameWindowPixmap failed:", err, xid) return nil } im, err := xgraphics.NewDrawable(TrayXU, xproto.Drawable(pixmap)) if err != nil { logger.Warning("Create xgraphics.Image failed:", err, pixmap) return nil } buf := bytes.NewBuffer(nil) im.WritePng(buf) hasher := md5.New() hasher.Write(buf.Bytes()) return hasher.Sum(nil) }
// Draws a single point on the window in the window (rather then plot) // coordinate system. // This routine is slow because it is essentially performing a buffer flip for // each point. // // This routine should be avoided. This is here as an assistance function rather // then the intended routine to be used for plotting. Prefer the 'Plot' data // functions over this function in almost all circumstances. func (plot *PlotWindow) DrawPoint(x, y int, pixelColor color.Color) { if plot == nil { return } ximg, err := xgraphics.NewDrawable(system.X, xproto.Drawable(plot.window.Id)) if err != nil { return } defer ximg.Destroy() ximg.Set(x, y, pixelColor) ximg.XSurfaceSet(plot.window.Id) ximg.XDraw() ximg.XPaint(plot.window.Id) }
// Draws a array of points on the window in the window (rather then plot) // coordinate system. // This routine is faster then the single point system because it performs only // one buffer flip per Point array rather then per point. // // This routine should be avoided. This is here as an assistance function rather // then the intended routine to be used for plotting. Prefer the 'Plot' data // functions over this function in almost all circumstances. func (plot *PlotWindow) DrawPoints(points []image.Point, pixelColor color.Color) { if plot == nil { return } ximg, err := xgraphics.NewDrawable(system.X, xproto.Drawable(plot.window.Id)) if err != nil { return } defer ximg.Destroy() // for index, _ := range points { ximg.Set(points[index].X, points[index].Y, pixelColor) } ximg.XSurfaceSet(plot.window.Id) ximg.XDraw() ximg.XPaint(plot.window.Id) }
func updater() { for { img, err := xgraphics.NewDrawable(X, xproto.Drawable(HexWindow.Id)) if err != nil { log.Fatal(err) } if crumbs == nil { crumbs = make([][]int, img.Rect.Max.X) for i := 0; i < len(crumbs); i++ { crumbs[i] = make([]int, img.Rect.Max.Y) } } centerx := img.Rect.Max.X / 2 centery := img.Rect.Max.Y / 2 cr, cg, cb, _ := img.At(centerx, centery).RGBA() center := int(cr+cg+cb) / 0xFF mindiff := 0 ringy := 0 for y := centery; y > 0; y-- { r, g, b, _ := img.At(centerx, y).RGBA() diff := int(r+g+b)/0xFF - center if diff < 0 { diff = -diff } if diff > 5 { mindiff = diff ringy = y break } } for i := 0; i < len(img.Pix); i += 4 { col := int(img.Pix[i]) + int(img.Pix[i+1]) + int(img.Pix[i+2]) diff := col - center if diff < 0 { diff = -diff } if diff >= mindiff-60 { img.Pix[i] = 255 img.Pix[i+1] = 255 img.Pix[i+2] = 255 } else { img.Pix[i] = 0 img.Pix[i+1] = 0 img.Pix[i+2] = 0 } } iteration++ floodFill(img, centerx, ringy, func(x, y int) bool { if (x-centerx)*(x-centerx)+(y-centery)*(y-centery) < 6400 { img.Pix[x*4+y*img.Stride] = 0 img.Pix[x*4+y*img.Stride+1] = 0 // img.Pix[x*4+y*img.Stride+2] = 0 return true } return false }) iteration++ found := false pointerAngle := 0.0 Search: for r := 40.0; r < 100; r += 3 { for a := 0.0; a < 256; a++ { dx := math.Cos(a * math.Pi / 128) dy := math.Sin(a * math.Pi / 128) x := centerx + int(dx*r) y := centery + int(dy*r) if img.Pix[x*4+y*img.Stride] != 0 && crumbs[x][y] != iteration { size := 0 sumx := 0 sumy := 0 floodFill(img, x, y, func(x, y int) bool { size++ sumx += x sumy += y return (x-centerx)*(x-centerx)+(y-centery)*(y-centery) < 10000 }) if size <= 200 { iteration++ floodFill(img, x, y, func(x, y int) bool { // img.Pix[x*4+y*img.Stride] = 0 img.Pix[x*4+y*img.Stride+1] = 0 img.Pix[x*4+y*img.Stride+2] = 0 return true }) pointerAngle = math.Atan2(float64(sumy)/float64(size)-float64(centery), float64(sumx)/float64(size)-float64(centerx)) dx = math.Cos(pointerAngle) dy = math.Sin(pointerAngle) for ; r > 0; r-- { x := centerx + int(dx*r) y := centery + int(dy*r) img.Pix[x*4+y*img.Stride] = 255 } found = true break Search } } } } if !found { fmt.Println("missing pointer!", time.Now()) } imageMap := mapImage(img, centerx, centery) for r, safe := range imageMap { for _, area := range safe { a := (area[0] + area[1]) / 2 dx := math.Cos(float64(a) * math.Pi / 128) dy := math.Sin(float64(a) * math.Pi / 128) x := centerx + int(dx*float64(50+r*10)) y := centery + int(dy*float64(50+r*10)) img.Pix[x*4+y*img.Stride+1] = 255 // for a := area[0]; a < area[1]; a++ { // dx := math.Cos(float64(a) * math.Pi / 128) // dy := math.Sin(float64(a) * math.Pi / 128) // x := centerx + int(dx*float64(50+r*10)) // y := centery + int(dy*float64(50+r*10)) // if x < 0 || x >= img.Rect.Dx() || y < 0 || y >= img.Rect.Dy() { // continue // } // img.Pix[x*4+y*img.Stride+1] = 255 // } } // if len(safe) == 0 { // for a := 0.0; a < 256; a++ { // dx := math.Cos(a * math.Pi / 128) // dy := math.Sin(a * math.Pi / 128) // x := centerx + int(dx*float64(50+r*10)) // y := centery + int(dy*float64(50+r*10)) // if x < 0 || x >= img.Rect.Dx() || y < 0 || y >= img.Rect.Dy() { // continue // } // img.Pix[x*4+y*img.Stride+1] = 255 // } // } } // for i := 0; i < len(img.Pix); i += 4 { // if img.Pix[i] != 0 && img.Pix[i+1] != 0 && img.Pix[i+2] != 0 { // img.Pix[i] = 0 // img.Pix[i+1] = 0 // } // img.Pix[i+2] = 0 // } err = img.XSurfaceSet(DisplayWindow.Id) if err != nil { log.Printf("Error while setting window surface to image %d: %s\n", DisplayWindow, err) } img.XDraw() img.XPaint(DisplayWindow.Id) img.Destroy() } }
func main() { x11, err := xgbutil.NewConn() //connect to X if err != nil { log.Fatal(err) } var board [4][4]uint16 img, err := xgraphics.NewDrawable(x11, xproto.Drawable(x11.RootWin())) //get screen if err != nil { log.Fatal(err) } imgRect := img.Bounds() boardX, boardY := 0, 0 OuterLoop: //search screen for upper left corner of board for x := imgRect.Min.X; x < imgRect.Max.X; x++ { for y := imgRect.Min.Y; y < imgRect.Max.Y; y++ { if img.At(x, y) == bgGrey { //board might be found x0, x1, x2, x3, x4, x5 := x, x+1, x+2, x+3, x+4, x+5 y0, y1, y2, y3, y4, y5 := y-5, y-4, y-3, y-2, y-1, y if img.At(x0, y0) == offWhite && //check corner pixel and board pixel colors img.At(x0, y1) == offWhite && img.At(x0, y2) == offWhite && img.At(x1, y0) == offWhite && img.At(x2, y0) == offWhite && img.At(x5, y0) == bgGrey && img.At(x5, y1) == bgGrey && img.At(x5, y2) == bgGrey && img.At(x5, y3) == bgGrey && img.At(x5, y4) == bgGrey && img.At(x5, y5) == bgGrey && img.At(x0, y5) == bgGrey && img.At(x1, y5) == bgGrey && img.At(x2, y5) == bgGrey && img.At(x3, y5) == bgGrey && img.At(x4, y5) == bgGrey && img.At(x5, y5) == bgGrey { boardX, boardY = x0, y0 fmt.Println("Board corner at", boardX, ",", boardY) break OuterLoop } } } } tileX, tileY := boardX+63, boardY+39 lastBoard := board ImgLoop: for i := 0; true; i++ { img, err := xgraphics.NewDrawable(x11, xproto.Drawable(x11.RootWin())) //get screen if err != nil { log.Fatal(err) } for y := 0; y < 4; y++ { for x := 0; x < 4; x++ { board[y][x], err = colorNum(img.At(tileX+(121*x), tileY+(121*y))) if err != nil { fmt.Println(err, " at ", tileX+(121*x), tileY+(121*y)) time.Sleep(1 * time.Second) continue ImgLoop } //fmt.Print(board[x][y], " ") } //fmt.Println() } if lastBoard != board { fmt.Println(string(findMove(board)), i) } lastBoard = board time.Sleep(1 * time.Second) } }