Exemple #1
1
func (s *screenImpl) NewTexture(size image.Point) (screen.Texture, error) {
	w, h := int64(size.X), int64(size.Y)
	if w < 0 || maxShmSide < w || h < 0 || maxShmSide < h || maxShmSize < 4*w*h {
		return nil, fmt.Errorf("x11driver: invalid texture size %v", size)
	}

	xm, err := xproto.NewPixmapId(s.xc)
	if err != nil {
		return nil, fmt.Errorf("x11driver: xproto.NewPixmapId failed: %v", err)
	}
	xp, err := render.NewPictureId(s.xc)
	if err != nil {
		return nil, fmt.Errorf("x11driver: xproto.NewPictureId failed: %v", err)
	}

	t := &textureImpl{
		s:    s,
		size: size,
		xm:   xm,
		xp:   xp,
	}

	xproto.CreatePixmap(s.xc, textureDepth, xm, xproto.Drawable(s.window32), uint16(w), uint16(h))
	render.CreatePicture(s.xc, xp, xproto.Drawable(xm), s.pictformat32, 0, nil)
	render.SetPictureFilter(s.xc, xp, uint16(len("bilinear")), "bilinear", nil)
	return t, nil
}
// adjustSize takes a client and dimensions, and adjust them so that they'll
// account for window decorations. For example, if you want a window to be
// 200 pixels wide, a window manager will typically determine that as
// you wanting the *client* to be 200 pixels wide. The end result is that
// the client plus decorations ends up being
// (200 + left decor width + right decor width) pixels wide. Which is probably
// not what you want. Therefore, transform 200 into
// 200 - decoration window width - client window width.
// Similarly for height.
func adjustSize(xu *xgbutil.XUtil, win xproto.Window,
	w, h int) (int, int, error) {

	// raw client geometry
	cGeom, err := RawGeometry(xu, xproto.Drawable(win))
	if err != nil {
		return 0, 0, err
	}

	// geometry with decorations
	pGeom, err := RawGeometry(xu, xproto.Drawable(win))
	if err != nil {
		return 0, 0, err
	}

	neww := w - (pGeom.Width() - cGeom.Width())
	newh := h - (pGeom.Height() - cGeom.Height())
	if neww < 1 {
		neww = 1
	}
	if newh < 1 {
		newh = 1
	}
	return neww, newh, nil
}
Exemple #3
0
// NewIcccmIcon converts two pixmap ids (icon_pixmap and icon_mask in the
// WM_HINTS properts) to a single xgraphics.Image.
// It is okay for one of iconPixmap or iconMask to be 0, but not both.
// You should probably use xgraphics.FindIcon instead of this directly.
func NewIcccmIcon(X *xgbutil.XUtil, iconPixmap,
	iconMask xproto.Pixmap) (*Image, error) {

	if iconPixmap == 0 && iconMask == 0 {
		return nil, fmt.Errorf("NewIcccmIcon: At least one of iconPixmap or " +
			"iconMask must be non-zero, but both are 0.")
	}

	var pximg, mximg *Image
	var err error

	// Get the xgraphics.Image for iconPixmap.
	if iconPixmap != 0 {
		pximg, err = NewDrawable(X, xproto.Drawable(iconPixmap))
		if err != nil {
			return nil, err
		}
	}

	// Now get the xgraphics.Image for iconMask.
	if iconMask != 0 {
		mximg, err = NewDrawable(X, xproto.Drawable(iconMask))
		if err != nil {
			return nil, err
		}
	}

	// Now merge them together if both were specified.
	switch {
	case pximg != nil && mximg != nil:
		r := pximg.Bounds()

		var x, y int
		var bgra, maskBgra BGRA
		for x = r.Min.X; x < r.Max.X; x++ {
			for y = r.Min.Y; y < r.Max.Y; y++ {
				maskBgra = mximg.At(x, y).(BGRA)
				bgra = pximg.At(x, y).(BGRA)
				if maskBgra.A == 0 {
					pximg.SetBGRA(x, y, BGRA{
						B: bgra.B,
						G: bgra.G,
						R: bgra.R,
						A: 0,
					})
				}
			}
		}
		return pximg, nil
	case pximg != nil:
		return pximg, nil
	case mximg != nil:
		return mximg, nil
	}

	panic("unreachable")
}
Exemple #4
0
// XExpPaint achieves a similar result as XPaint and XSurfaceSet, but
// uses CopyArea instead of setting a background pixmap and using ClearArea.
// CreatePixmap must be called before using XExpPaint.
// XExpPaint can be called on sub-images.
// x and y correspond to the destination x and y to copy the image to.
//
// This should not be used on the same image with XSurfaceSet and XPaint.
func (im *Image) XExpPaint(wid xproto.Window, x, y int) {
	if im.Pixmap == 0 {
		return
	}
	xproto.CopyArea(im.X.Conn(),
		xproto.Drawable(im.Pixmap), xproto.Drawable(wid), im.X.GC(),
		int16(im.Rect.Min.X), int16(im.Rect.Min.Y),
		int16(x), int16(y),
		uint16(im.Rect.Dx()), uint16(im.Rect.Dy()))
}
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)
}
Exemple #6
0
func (m *MotionRecorder) update() {
	geo, _ := xproto.GetGeometry(m.Window.Conn, xproto.Drawable(m.root)).Reply()

	if geo != nil {
		m.Resize(geo.Width, geo.Height)
	}
}
func (m *TrayManager) addTrayIcon(xid xproto.Window) {
	m.checkValid()
	for _, id := range m.TrayIcons {
		if xproto.Window(id) == xid {
			return
		}
	}

	if d, err := damage.NewDamageId(TrayXU.Conn()); err != nil {
		return
	} else {
		m.dmageInfo[xid] = d
		if err := damage.CreateChecked(TrayXU.Conn(), d, xproto.Drawable(xid), damage.ReportLevelRawRectangles).Check(); err != nil {
			logger.Debug("DamageCreate Failed:", err)
			return
		}
	}
	composite.RedirectWindow(TrayXU.Conn(), xid, composite.RedirectAutomatic)

	m.TrayIcons = append(m.TrayIcons, uint32(xid))
	icon := xwindow.New(TrayXU, xid)
	icon.Listen(xproto.EventMaskVisibilityChange | damage.Notify | xproto.EventMaskStructureNotify)
	icon.Change(xproto.CwBackPixel, 0)

	name, err := ewmh.WmNameGet(TrayXU, xid)
	if err != nil {
		logger.Debug("WmNameGet failed:", err, xid)
	}
	m.nameInfo[xid] = name
	m.notifyInfo[xid] = true
	dbus.Emit(m, "Added", uint32(xid))
	logger.Infof("Added try icon: \"%s\"(%d)", name, uint32(xid))
}
Exemple #8
0
func (s *screenImpl) initWindow32() error {
	visualid, err := findVisual(s.xsi, 32)
	if err != nil {
		return err
	}
	colormap, err := xproto.NewColormapId(s.xc)
	if err != nil {
		return fmt.Errorf("x11driver: xproto.NewColormapId failed: %v", err)
	}
	if err := xproto.CreateColormapChecked(
		s.xc, xproto.ColormapAllocNone, colormap, s.xsi.Root, visualid).Check(); err != nil {
		return fmt.Errorf("x11driver: xproto.CreateColormap failed: %v", err)
	}
	s.window32, err = xproto.NewWindowId(s.xc)
	if err != nil {
		return fmt.Errorf("x11driver: xproto.NewWindowId failed: %v", err)
	}
	s.gcontext32, err = xproto.NewGcontextId(s.xc)
	if err != nil {
		return fmt.Errorf("x11driver: xproto.NewGcontextId failed: %v", err)
	}
	const depth = 32
	xproto.CreateWindow(s.xc, depth, s.window32, s.xsi.Root,
		0, 0, 1, 1, 0,
		xproto.WindowClassInputOutput, visualid,
		// The CwBorderPixel attribute seems necessary for depth == 32. See
		// http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32
		xproto.CwBorderPixel|xproto.CwColormap,
		[]uint32{0, uint32(colormap)},
	)
	xproto.CreateGC(s.xc, s.gcontext32, xproto.Drawable(s.window32), 0, nil)
	return nil
}
// RootGeometry gets the geometry of the root window. It will panic on failure.
func RootGeometry(xu *xgbutil.XUtil) xrect.Rect {
	geom, err := RawGeometry(xu, xproto.Drawable(xu.RootWin()))
	if err != nil {
		panic(err)
	}
	return geom
}
Exemple #10
0
// BufferSwapCompleteEventNew constructs a BufferSwapCompleteEvent value that implements xgb.Event from a byte slice.
func BufferSwapCompleteEventNew(buf []byte) xgb.Event {
	v := BufferSwapCompleteEvent{}
	b := 1 // don't read event number

	b += 1 // padding

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.EventType = xgb.Get16(buf[b:])
	b += 2

	b += 2 // padding

	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
	b += 4

	v.UstHi = xgb.Get32(buf[b:])
	b += 4

	v.UstLo = xgb.Get32(buf[b:])
	b += 4

	v.MscHi = xgb.Get32(buf[b:])
	b += 4

	v.MscLo = xgb.Get32(buf[b:])
	b += 4

	v.Sbc = xgb.Get32(buf[b:])
	b += 4

	return v
}
Exemple #11
0
// NewDrawable converts an X drawable into a xgraphics.Image.
// This is used in NewIcccmIcon.
func NewDrawable(X *xgbutil.XUtil, did xproto.Drawable) (*Image, error) {
	// Get the geometry of the pixmap for use in the GetImage request.
	pgeom, err := xwindow.RawGeometry(X, xproto.Drawable(did))
	if err != nil {
		return nil, err
	}

	// Get the image data for each pixmap.
	pixmapData, err := xproto.GetImage(X.Conn(), xproto.ImageFormatZPixmap,
		did,
		0, 0, uint16(pgeom.Width()), uint16(pgeom.Height()),
		(1<<32)-1).Reply()
	if err != nil {
		return nil, err
	}

	// Now create the xgraphics.Image and populate it with data from
	// pixmapData and maskData.
	ximg := New(X, image.Rect(0, 0, pgeom.Width(), pgeom.Height()))

	// We'll try to be a little flexible with the image format returned,
	// but not completely flexible.
	err = readDrawableData(X, ximg, did, pixmapData,
		pgeom.Width(), pgeom.Height())
	if err != nil {
		return nil, err
	}

	return ximg, nil
}
Exemple #12
0
// CompletionEventNew constructs a CompletionEvent value that implements xgb.Event from a byte slice.
func CompletionEventNew(buf []byte) xgb.Event {
	v := CompletionEvent{}
	b := 1 // don't read event number

	b += 1 // padding

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
	b += 4

	v.MinorEvent = xgb.Get16(buf[b:])
	b += 2

	v.MajorEvent = buf[b]
	b += 1

	b += 1 // padding

	v.Shmseg = Seg(xgb.Get32(buf[b:]))
	b += 4

	v.Offset = xgb.Get32(buf[b:])
	b += 4

	return v
}
Exemple #13
0
// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice.
func NotifyEventNew(buf []byte) xgb.Event {
	v := NotifyEvent{}
	b := 1 // don't read event number

	v.Level = buf[b]
	b += 1

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
	b += 4

	v.Damage = Damage(xgb.Get32(buf[b:]))
	b += 4

	v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:]))
	b += 4

	v.Area = xproto.Rectangle{}
	b += xproto.RectangleRead(buf[b:], &v.Area)

	v.Geometry = xproto.Rectangle{}
	b += xproto.RectangleRead(buf[b:], &v.Geometry)

	return v
}
// Geometry retrieves an up-to-date version of the this window's geometry.
// It also loads the geometry into the Geom member of Window.
func (w *Window) Geometry() (xrect.Rect, error) {
	geom, err := RawGeometry(w.X, xproto.Drawable(w.Id))
	if err != nil {
		return nil, err
	}
	w.Geom = geom
	return geom, err
}
Exemple #15
0
func (k *workspace) drawFrameBorders() {
	if k.fullscreen || k.listing == listWorkspaces {
		return
	}
	setForeground(colorUnfocused)
	rects := k.mainFrame.appendRectangles(nil)
	check(xp.PolyRectangleChecked(xConn, xp.Drawable(desktopXWin), desktopXGC, rects))
	setForeground(colorFocused)
	k.focusedFrame.drawBorder()
}
Exemple #16
0
func NewScreenSaver() *ScreenSaver {
	s := &ScreenSaver{inhibitors: make(map[uint32]inhibitor)}
	s.xu, _ = xgbutil.NewConn()
	screensaver.Init(s.xu.Conn())
	screensaver.QueryVersion(s.xu.Conn(), 1, 0)
	screensaver.SelectInput(s.xu.Conn(), xproto.Drawable(s.xu.RootWin()), screensaver.EventNotifyMask|screensaver.EventCycleMask)
	dpms.Init(s.xu.Conn())

	go s.loop()
	return s
}
Exemple #17
0
// DecorGeometry retrieves the client's width and height including decorations.
// This can be tricky. In a non-parenting window manager, the width/height of
// a client can be found by inspecting the client directly. In a reparenting
// window manager like Openbox, the parent of the client reflects the true
// width/height. Still yet, in KWin, it's the parent of the parent of the
// client that reflects the true width/height.
// The idea then is to traverse up the tree until we hit the root window.
// Therefore, we're at a top-level window which should accurately reflect
// the width/height.
func (w *Window) DecorGeometry() (xrect.Rect, error) {
	parent := w
	for {
		tempParent, err := parent.Parent()
		if err != nil || tempParent.Id == w.X.RootWin() {
			break
		}
		parent = tempParent
	}
	return RawGeometry(w.X, xproto.Drawable(parent.Id))
}
Exemple #18
0
// InvalidateBuffersEventNew constructs a InvalidateBuffersEvent value that implements xgb.Event from a byte slice.
func InvalidateBuffersEventNew(buf []byte) xgb.Event {
	v := InvalidateBuffersEvent{}
	b := 1 // don't read event number

	b += 1 // padding

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
	b += 4

	return v
}
Exemple #19
0
func (w *Window) Redraw() {
	/* Hide X11 borders */
	var mask uint16 = xproto.ConfigWindowBorderWidth
	values := make([]uint32, 1)
	values[0] = 0
	xproto.ConfigureWindow(w.conn, w.id, mask, values)

	wdt, hgh := int16(w.geom.W), int16(w.geom.H)
	/* Drawing background */
	bg := xproto.Rectangle{0, 0, uint16(wdt), uint16(hgh)}
	bgs := make([]xproto.Rectangle, 1)
	bgs[0] = bg
	xproto.PolyFillRectangle(w.conn, xproto.Drawable(w.id), w.gc.bg, bgs)

	/* Drawing borders */
	vertices := make([]xproto.Point, 5)
	vertices[0].X = 0
	vertices[0].Y = 0
	vertices[1].X = wdt
	vertices[1].Y = 0
	vertices[2].X = wdt
	vertices[2].Y = hgh
	vertices[3].X = 0
	vertices[3].Y = hgh
	vertices[4].X = 0
	vertices[4].Y = 0
	xproto.PolyLine(w.conn, xproto.CoordModeOrigin, xproto.Drawable(w.id), w.gc.bc, vertices)

	/* Drawing text */
	hline := int16(w.gc.fontHeight)
	x, y := int16(w.gc.border), int16(w.gc.border+w.gc.fontUp)
	for _, line := range w.lines {
		xproto.ImageText8(w.conn, byte(len(line)), xproto.Drawable(w.id),
			w.gc.fg, x, y, line)
		y += hline
	}
}
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
	}
}
Exemple #21
0
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)
}
Exemple #22
0
func main() {
	X, _ := xgbutil.NewConn()

	heads, err := xinerama.PhysicalHeads(X)
	if err != nil {
		fmt.Printf("ERROR: %v\n", err)
	}

	// Test intersection
	r1 := xrect.New(0, 0, 100, 100)
	r2 := xrect.New(100, 100, 100, 100)
	fmt.Println(xrect.IntersectArea(r1, r2))

	// Test largest overlap
	window := xrect.New(1800, 0, 300, 200)
	fmt.Println(xrect.LargestOverlap(window, heads))

	// Test ApplyStrut
	rgeom, _ := xwindow.RawGeometry(X, xproto.Drawable(X.RootWin()))
	fmt.Println("---------------------------")
	for i, head := range heads {
		fmt.Printf("%d - %v\n", i, head)
	}

	// Let's actually apply struts to the current environment
	clients, _ := ewmh.ClientListGet(X)
	for _, client := range clients {
		strut, err := ewmh.WmStrutPartialGet(X, client)
		if err == nil {
			xrect.ApplyStrut(heads, rgeom.Width(), rgeom.Height(),
				strut.Left, strut.Right, strut.Top, strut.Bottom,
				strut.LeftStartY, strut.LeftEndY,
				strut.RightStartY, strut.RightEndY,
				strut.TopStartX, strut.TopEndX,
				strut.BottomStartX, strut.BottomEndX)
		}
	}

	fmt.Println("---------------------------")
	fmt.Println("After applying struts...")
	for i, head := range heads {
		fmt.Printf("%d - %v\n", i, head)
	}
}
func main() {

	//	os.Setenv("DISPLAY", "localhost:6080")

	c, err := xgb.NewConn()
	if err != nil {
		fmt.Println(err)
		return
	}
	screen := xproto.Setup(c).DefaultScreen(c)

	rect := image.Rect(0, 0, int(screen.WidthInPixels), int(screen.HeightInPixels))

	x, y := rect.Dx(), rect.Dy()

	xImg, err := xproto.GetImage(c,
		xproto.ImageFormatZPixmap,
		xproto.Drawable(screen.Root),
		int16(rect.Min.X),
		int16(rect.Min.Y),
		uint16(x),
		uint16(y),
		0xffffffff).Reply()

	if err != nil {
		fmt.Println("Error: %s\r\n", err)
	}

	data := xImg.Data
	for i := 0; i < len(data); i += 4 {
		data[i], data[i+2], data[i+3] = data[i+2], data[i], 255
	}

	img := &image.RGBA{
		data, 4 * x, image.Rect(0, 0, x, y)}

	z.FcheckParents("screen")
	f := z.FileW("screen")
	defer f.Close()

	png := jpeg.Encode(f, img, &jpeg.Options{90})

	fmt.Printf("End with png: %v", png)
}
Exemple #24
0
// 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)

}
Exemple #25
0
// CreatePixmap allocates an X resource identifier for a pixmap. (It does not
// do any drawing.) You only need to call this if you're using XDraw/XExpPaint.
// If you're using XSurfaceSet/XDraw/XPaint, then CreatePixmap is called for
// you automatically.
func (im *Image) CreatePixmap() error {
	// Generate the pixmap id.
	pid, err := xproto.NewPixmapId(im.X.Conn())
	if err != nil {
		return err
	}

	// Now actually create the pixmap.
	err = xproto.CreatePixmapChecked(im.X.Conn(), im.X.Screen().RootDepth,
		pid, xproto.Drawable(im.X.RootWin()),
		uint16(im.Bounds().Dx()), uint16(im.Bounds().Dy())).Check()
	if err != nil {
		return err
	}

	// Now give it to the image.
	im.Pixmap = pid
	return nil
}
Exemple #26
0
// 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 CaptureRect(rect image.Rectangle) (*image.RGBA, error) {
	c, err := xgb.NewConn()
	if err != nil {
		return nil, err
	}
	defer c.Close()

	screen := xproto.Setup(c).DefaultScreen(c)
	x, y := rect.Dx(), rect.Dy()
	xImg, err := xproto.GetImage(c, xproto.ImageFormatZPixmap, xproto.Drawable(screen.Root), int16(rect.Min.X), int16(rect.Min.Y), uint16(x), uint16(y), 0xffffffff).Reply()
	if err != nil {
		return nil, err
	}

	data := xImg.Data
	for i := 0; i < len(data); i += 4 {
		data[i], data[i+2], data[i+3] = data[i+2], data[i], 255
	}

	img := &image.RGBA{data, 4 * x, image.Rect(0, 0, x, y)}
	return img, nil
}
Exemple #28
0
func (s *screenImpl) NewWindow(opts *screen.NewWindowOptions) (screen.Window, error) {
	// TODO: look at opts.
	const width, height = 1024, 768

	xw, err := xproto.NewWindowId(s.xc)
	if err != nil {
		return nil, fmt.Errorf("x11driver: xproto.NewWindowId failed: %v", err)
	}
	xg, err := xproto.NewGcontextId(s.xc)
	if err != nil {
		return nil, fmt.Errorf("x11driver: xproto.NewGcontextId failed: %v", err)
	}
	xp, err := render.NewPictureId(s.xc)
	if err != nil {
		return nil, fmt.Errorf("x11driver: render.NewPictureId failed: %v", err)
	}
	pictformat := render.Pictformat(0)
	switch s.xsi.RootDepth {
	default:
		return nil, fmt.Errorf("x11driver: unsupported root depth %d", s.xsi.RootDepth)
	case 24:
		pictformat = s.pictformat24
	case 32:
		pictformat = s.pictformat32
	}

	w := &windowImpl{
		s:       s,
		xw:      xw,
		xg:      xg,
		xp:      xp,
		pump:    pump.Make(),
		xevents: make(chan xgb.Event),
	}

	s.mu.Lock()
	s.windows[xw] = w
	s.mu.Unlock()

	xproto.CreateWindow(s.xc, s.xsi.RootDepth, xw, s.xsi.Root,
		0, 0, width, height, 0,
		xproto.WindowClassInputOutput, s.xsi.RootVisual,
		xproto.CwEventMask,
		[]uint32{0 |
			xproto.EventMaskKeyPress |
			xproto.EventMaskKeyRelease |
			xproto.EventMaskButtonPress |
			xproto.EventMaskButtonRelease |
			xproto.EventMaskPointerMotion |
			xproto.EventMaskExposure |
			xproto.EventMaskStructureNotify |
			xproto.EventMaskFocusChange,
		},
	)
	s.setProperty(xw, s.atomWMProtocols, s.atomWMDeleteWindow, s.atomWMTakeFocus)
	xproto.CreateGC(s.xc, xg, xproto.Drawable(xw), 0, nil)
	render.CreatePicture(s.xc, xp, xproto.Drawable(xw), pictformat, 0, nil)
	xproto.MapWindow(s.xc, xw)

	return w, nil
}
Exemple #29
0
func (f *frame) drawBorder() {
	check(xp.PolyRectangleChecked(xConn, xp.Drawable(desktopXWin), desktopXGC,
		[]xp.Rectangle{f.rect}))
}
Exemple #30
0
func main() {
	X, err := xgb.NewConn()
	if err != nil {
		fmt.Println(err)
		return
	}

	wid, _ := xproto.NewWindowId(X)
	screen := xproto.Setup(X).DefaultScreen(X)
	xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root,
		0, 0, 240, 240, 0,
		xproto.WindowClassInputOutput,
		screen.RootVisual,
		xproto.CwBackPixel|xproto.CwEventMask,
		[]uint32{ // values must be in the order defined by the protocol
			0xffffffff,
			xproto.EventMaskStructureNotify |
				xproto.EventMaskKeyPress |
				xproto.EventMaskKeyRelease})

	xproto.MapWindow(X, wid)
	fmt.Printf("%d %d\n", screen.AllowedDepths[0].Visuals[0].VisualId, screen.RootVisual)

	var (
		ux, uy float64 = 1, 1

		fe                   cairo.FontExtents
		te                   cairo.TextExtents
		text                 = "joy"
		x, y, px, dashlength float64
	)

	surface := cairo.NewSurfaceFromXCB(xproto.Drawable(wid), screen.AllowedDepths[0].Visuals[0], 240, 240)
	surface.Scale(240, 240)
	surface.SetFontSize(0.5)

	/* Drawing code goes here */
	surface.SetSourceRGB(0.0, 0.0, 0.0)
	surface.SelectFontFace("Georgia", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
	surface.FontExtents(&fe)

	ux, uy = surface.DeviceToUserDistance(ux, uy)
	if ux > uy {
		px = ux
	} else {
		px = uy
	}

	surface.FontExtents(&fe)
	surface.TextExtents(text, &te)
	x = 0.5 - te.X_bearing - te.Width/2
	y = 0.5 - fe.Descent + fe.Height/2

	/* baseline, descent, ascent, height */
	surface.SetLineWidth(4 * px)
	dashlength = 9 * px
	surface.SetDash([]float64{dashlength}, 0)
	surface.SetSourceRGBA(0, 0.6, 0, 0.5)
	surface.MoveTo(x+te.X_bearing, y)
	surface.RelLineTo(te.Width, 0)
	surface.MoveTo(x+te.X_bearing, y+fe.Descent)
	surface.RelLineTo(te.Width, 0)
	surface.MoveTo(x+te.X_bearing, y-fe.Ascent)
	surface.RelLineTo(te.Width, 0)
	surface.MoveTo(x+te.X_bearing, y-fe.Height)
	surface.RelLineTo(te.Width, 0)
	surface.Stroke()

	/* extents: width & height */
	surface.SetSourceRGBA(0, 0, 0.75, 0.5)
	surface.SetLineWidth(px)
	dashlength = 3 * px
	surface.SetDash([]float64{dashlength}, 0)
	surface.Rectangle(x+te.X_bearing, y+te.Y_bearing, te.Width, te.Height)
	surface.Stroke()

	/* text */
	surface.MoveTo(x, y)
	surface.SetSourceRGB(0, 0, 0)
	surface.ShowText(text)

	/* bearing */
	surface.SetDash(nil, 0)
	surface.SetLineWidth(2 * px)
	surface.SetSourceRGBA(0, 0, 0.75, 0.5)
	surface.MoveTo(x, y)
	surface.RelLineTo(te.X_bearing, te.Y_bearing)
	surface.Stroke()

	/* text's advance */
	surface.SetSourceRGBA(0, 0, 0.75, 0.5)
	surface.Arc(x+te.X_advance, y+te.Y_advance, 5*px, 0, 2*math.Pi)
	surface.Fill()

	/* reference point */
	surface.Arc(x, y, 5*px, 0, 2*math.Pi)
	surface.SetSourceRGBA(0.75, 0, 0, 0.5)
	surface.Fill()

	surface.Finish()
	surface.Destroy()

	for {
		ev, xerr := X.WaitForEvent()
		if ev == nil && xerr == nil {
			// fmt.Println("Both event and error are nil. Exiting...")
			return
		}

		if ev != nil {
			// fmt.Printf("Event: %s\n", ev)
		}
		if xerr != nil {
			// fmt.Printf("Error: %s\n", xerr)
		}
	}
}