Ejemplo n.º 1
0
// Map is a simple alias to map the window.
func (w *Window) Map() {
	if w == nil {
		return
	}

	xproto.MapWindow(w.X.Conn(), w.Id)
}
Ejemplo n.º 2
0
// Replace existing window manager
func usurpWM(X *xgb.Conn, screen *xproto.ScreenInfo) {
	wmName := fmt.Sprintf("WM_S%d", X.DefaultScreen)
	managerAtom, err := xproto.InternAtom(X, true, uint16(len(wmName)), wmName).Reply()
	if err != nil {
		log.Fatal(err)
	}

	fakeWindow, _ := xproto.NewWindowId(X)
	xproto.CreateWindow(X, // Connection
		screen.RootDepth, // Depth
		fakeWindow,       // Window Id
		screen.Root,      // Parent Window
		-1000, -1000,     // x, y
		1, 1, // width, height
		0, // border_width
		xproto.WindowClassInputOutput, // class
		screen.RootVisual,             // visual
		xproto.CwEventMask|xproto.CwOverrideRedirect,
		[]uint32{1, xproto.EventMaskPropertyChange}) // masks
	xproto.MapWindow(X, fakeWindow)
	err = xproto.SetSelectionOwnerChecked(X, fakeWindow, managerAtom.Atom, xproto.TimeCurrentTime).Check()
	if err != nil {
		log.Fatal(err)
	}
}
Ejemplo n.º 3
0
func (w *Window) setVisibility(v bool) {
	xproto.ChangeWindowAttributesChecked(w.Conn, w.root, xproto.CwEventMask, windowOff)
	if v {
		xproto.MapWindow(w.Conn, w.Window)
	} else {
		xproto.UnmapWindow(w.Conn, w.Window)
	}
	xproto.ChangeWindowAttributesChecked(w.Conn, w.root, xproto.CwEventMask, windowOn)
}
Ejemplo n.º 4
0
func newGradientWindow(width, height int) {
	win := createWindow()
	xproto.ConfigureWindow(
		X.Conn(), win, xproto.ConfigWindowWidth|xproto.ConfigWindowHeight,
		[]uint32{uint32(width), uint32(height)})
	xwindow.Listen(X, win, xproto.EventMaskStructureNotify)

	xproto.MapWindow(X.Conn(), win)

	xgraphics.PaintImg(X, win, gradient(width, height))

	xevent.ConfigureNotifyFun(
		func(X *xgbutil.XUtil, ev xevent.ConfigureNotifyEvent) {
			img := gradient(int(ev.Width), int(ev.Height))
			log.Printf("Painting new image (%d, %d)", ev.Width, ev.Height)
			xgraphics.PaintImg(X, win, img)
		}).Connect(X, win)
}
Ejemplo n.º 5
0
func default1() {

	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, 500, 500, 0,
		xproto.WindowClassInputOutput, screen.RootVisual,
		xproto.CwBackPixel|xproto.CwEventMask,
		[]uint32{
			0xffffffff,
			xproto.EventMaskStructureNotify |
				xproto.EventMaskKeyPress |
				xproto.EventMaskKeyRelease})

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

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

	}

}
Ejemplo n.º 6
0
func mkMotion(s *xproto.ScreenInfo, c *xgb.Conn) (xproto.Window, error) {
	motion, err := xproto.NewWindowId(c)
	if err != nil {
		return motion, err
	}
	xproto.CreateWindow(
		c,
		s.RootDepth,
		motion,
		s.Root,
		0,
		0,
		s.WidthInPixels,
		s.HeightInPixels,
		0,
		xproto.WindowClassInputOnly,
		s.RootVisual,
		xproto.CwEventMask,
		[]uint32{xproto.EventMaskPointerMotion},
	)
	xproto.MapWindow(c, motion)
	return motion, nil
}
Ejemplo n.º 7
0
func mkMeta(s *xproto.ScreenInfo, c *xgb.Conn) (xproto.Window, error) {
	meta, err := xproto.NewWindowId(c)
	if err != nil {
		return meta, err
	}

	xproto.CreateWindow(
		c,
		s.RootDepth,
		meta,
		s.Root,
		-1,
		-1,
		1,
		1,
		0,
		xproto.WindowClassInputOnly,
		s.RootVisual,
		0,          //xproto.CwEventMask|xproto.CwOverrideRedirect,
		[]uint32{}, //nil, //[]uint32{1, xproto.EventMaskPropertyChange},
	)
	xproto.MapWindow(c, meta)
	return meta, nil
}
Ejemplo n.º 8
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
}
Ejemplo n.º 9
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)
		}
	}
}
Ejemplo n.º 10
0
// NewConnXgb use the specific xgb.Conn to create a new XUtil.
//
//  NewConn, NewConnDisplay are wrapper of this function.
func NewConnXgb(c *xgb.Conn) (*XUtil, error) {
	setup := xproto.Setup(c)
	screen := setup.DefaultScreen(c)

	// Initialize our central struct that stores everything.
	xu := &XUtil{
		conn:             c,
		Quit:             false,
		Evqueue:          make([]EventOrError, 0, 1000),
		EvqueueLck:       &sync.RWMutex{},
		setup:            setup,
		screen:           screen,
		root:             screen.Root,
		eventTime:        xproto.Timestamp(0), // last event time
		Atoms:            make(map[string]xproto.Atom, 50),
		AtomsLck:         &sync.RWMutex{},
		AtomNames:        make(map[xproto.Atom]string, 50),
		AtomNamesLck:     &sync.RWMutex{},
		Callbacks:        make(map[int]map[xproto.Window][]Callback, 33),
		CallbacksLck:     &sync.RWMutex{},
		Hooks:            make([]CallbackHook, 0),
		HooksLck:         &sync.RWMutex{},
		Keymap:           nil, // we don't have anything yet
		Modmap:           nil,
		KeyRedirect:      0,
		Keybinds:         make(map[KeyKey][]CallbackKey, 10),
		KeybindsLck:      &sync.RWMutex{},
		Keygrabs:         make(map[KeyKey]int, 10),
		Keystrings:       make([]KeyString, 0, 10),
		Mousebinds:       make(map[MouseKey][]CallbackMouse, 10),
		MousebindsLck:    &sync.RWMutex{},
		Mousegrabs:       make(map[MouseKey]int, 10),
		InMouseDrag:      false,
		MouseDragStepFun: nil,
		MouseDragEndFun:  nil,
		ErrorHandler:     func(err xgb.Error) { Logger.Println(err) },
	}

	var err error = nil
	// Create a general purpose graphics context
	xu.gc, err = xproto.NewGcontextId(xu.conn)
	if err != nil {
		return nil, err
	}
	xproto.CreateGC(xu.conn, xu.gc, xproto.Drawable(xu.root),
		xproto.GcForeground, []uint32{xu.screen.WhitePixel})

	// Create a dummy window
	xu.dummy, err = xproto.NewWindowId(xu.conn)
	if err != nil {
		return nil, err
	}
	xproto.CreateWindow(xu.conn, xu.Screen().RootDepth, xu.dummy, xu.RootWin(),
		-1000, -1000, 1, 1, 0,
		xproto.WindowClassInputOutput, xu.Screen().RootVisual,
		xproto.CwEventMask|xproto.CwOverrideRedirect,
		[]uint32{1, xproto.EventMaskPropertyChange})
	xproto.MapWindow(xu.conn, xu.dummy)

	// Register the Xinerama extension... because it doesn't cost much.
	err = xinerama.Init(xu.conn)

	// If we can't register Xinerama, that's okay. Output something
	// and move on.
	if err != nil {
		Logger.Printf("WARNING: %s\n", err)
		Logger.Printf("MESSAGE: The 'xinerama' package cannot be used " +
			"because the XINERAMA extension could not be loaded.")
	}

	return xu, nil
}
Ejemplo n.º 11
0
func (w *Window) Map() {
	xproto.MapWindow(w.conn, w.id)
}
Ejemplo n.º 12
0
// Map is a simple alias to map the window.
func (w *Window) Map() {
	xproto.MapWindow(w.X.Conn(), w.Id)
}
Ejemplo n.º 13
0
func main() {
	// Open the connection to the X server
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	defer X.Close()

	setup := xproto.Setup(X)
	// Get the first screen
	screen := setup.DefaultScreen(X)

	// Replace existing window manager
	wmName := fmt.Sprintf("WM_S%d", X.DefaultScreen)
	managerAtom, err := xproto.InternAtom(X, true, uint16(len(wmName)), wmName).Reply()
	if err != nil {
		log.Fatal(err)
	}

	fakeWindow, _ := xproto.NewWindowId(X)
	xproto.CreateWindow(X, // Connection
		screen.RootDepth, // Depth
		fakeWindow,       // Window Id
		screen.Root,      // Parent Window
		-1000, -1000,     // x, y
		1, 1, // width, height
		0, // border_width
		xproto.WindowClassInputOutput, // class
		screen.RootVisual,             // visual
		xproto.CwEventMask|xproto.CwOverrideRedirect,
		[]uint32{1, xproto.EventMaskPropertyChange}) // masks
	xproto.MapWindow(X, fakeWindow)
	err = xproto.SetSelectionOwnerChecked(X, fakeWindow, managerAtom.Atom, xproto.TimeCurrentTime).Check()
	if err != nil {
		fmt.Println("foo")
		log.Fatal(err)
	}

	arcs := []xproto.Arc{
		{10, 100, 60, 40, 0, 90 << 6},
		{90, 100, 55, 40, 0, 270 << 6}}

	// Create black (foreground) graphic context
	foreground, _ := xproto.NewGcontextId(X)
	mask := uint32(xproto.GcForeground | xproto.GcGraphicsExposures)
	values := []uint32{screen.BlackPixel, 0}
	xproto.CreateGC(X, foreground, xproto.Drawable(screen.Root), mask, values)

	// Ask for our window's Id
	win, _ := xproto.NewWindowId(X)
	winDrawable := xproto.Drawable(win)

	// Create the window
	mask = uint32(xproto.CwBackPixel | xproto.CwEventMask)
	values = []uint32{screen.WhitePixel, xproto.EventMaskExposure}
	xproto.CreateWindow(X, // Connection
		screen.RootDepth, // Depth
		win,              // Window Id
		screen.Root,      // Parent Window
		0, 0,             // x, y
		150, 150, // width, height
		10, // border_width
		xproto.WindowClassInputOutput, // class
		screen.RootVisual,             // visual
		mask, values)                  // masks

	// Map the window on the screen
	xproto.MapWindow(X, win)

	// Obey the window-delete protocol
	tp := "WM_PROTOCOLS"
	prp := "WM_DELETE_WINDOW"
	typeAtom, _ := xproto.InternAtom(X, true, uint16(len(tp)), tp).Reply()
	propertyAtom, _ := xproto.InternAtom(X, true, uint16(len(prp)), prp).Reply()

	data := make([]byte, 4)
	xgb.Put32(data, uint32(propertyAtom.Atom))
	xproto.ChangeProperty(X, xproto.PropModeReplace, win, typeAtom.Atom, xproto.AtomAtom, 32, 1, data)

	// Main loop
	for {
		evt, err := X.WaitForEvent()
		fmt.Printf("An event of type %T occured.\n", evt)

		if evt == nil && err == nil {
			fmt.Println("Exiting....")
			return
		} else if err != nil {
			log.Fatal(err)
		}

		switch event := evt.(type) {
		case xproto.ExposeEvent:
			/* We draw the arcs */
			xproto.PolyArc(X, winDrawable, foreground, arcs)
		case xproto.ClientMessageEvent:
			if len(event.Data.Data32) > 0 {
				data := xproto.Atom(event.Data.Data32[0])
				if data == propertyAtom.Atom {
					return
				} else {
					atomName, _ := xproto.GetAtomName(X, data).Reply()
					fmt.Println(atomName.Name)
				}
			} else {
				atomName, _ := xproto.GetAtomName(X, event.Type).Reply()
				fmt.Println(atomName.Name)
			}
		default:
			/* Unknown event type, ignore it */
		}
	}
	return
}
Ejemplo n.º 14
0
func main() {
	// Open the connection to the X server
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// geometric objects
	points := []xproto.Point{
		{10, 10},
		{10, 20},
		{20, 10},
		{20, 20}}

	polyline := []xproto.Point{
		{50, 10},
		{5, 20}, // rest of points are relative
		{25, -20},
		{10, 10}}

	segments := []xproto.Segment{
		{100, 10, 140, 30},
		{110, 25, 130, 60}}

	rectangles := []xproto.Rectangle{
		{10, 50, 40, 20},
		{80, 50, 10, 40}}

	arcs := []xproto.Arc{
		{10, 100, 60, 40, 0, 90 << 6},
		{90, 100, 55, 40, 0, 270 << 6}}

	setup := xproto.Setup(X)
	// Get the first screen
	screen := setup.DefaultScreen(X)

	// Create black (foreground) graphic context
	foreground, _ := xproto.NewGcontextId(X)
	mask := uint32(xproto.GcForeground | xproto.GcGraphicsExposures)
	values := []uint32{screen.BlackPixel, 0}
	xproto.CreateGC(X, foreground, xproto.Drawable(screen.Root), mask, values)

	// Ask for our window's Id
	win, _ := xproto.NewWindowId(X)
	winDrawable := xproto.Drawable(win)

	// Create the window
	mask = uint32(xproto.CwBackPixel | xproto.CwEventMask)
	values = []uint32{screen.WhitePixel, xproto.EventMaskExposure}
	xproto.CreateWindow(X, // Connection
		screen.RootDepth, // Depth
		win,              // Window Id
		screen.Root,      // Parent Window
		0, 0,             // x, y
		150, 150, // width, height
		10, // border_width
		xproto.WindowClassInputOutput, // class
		screen.RootVisual,             // visual
		mask, values)                  // masks

	// Map the window on the screen
	xproto.MapWindow(X, win)

	for {
		evt, err := X.WaitForEvent()
		switch evt.(type) {
		case xproto.ExposeEvent:
			/* We draw the points */
			xproto.PolyPoint(X, xproto.CoordModeOrigin, winDrawable, foreground, points)

			/* We draw the polygonal line */
			xproto.PolyLine(X, xproto.CoordModePrevious, winDrawable, foreground, polyline)

			/* We draw the segments */
			xproto.PolySegment(X, winDrawable, foreground, segments)

			/* We draw the rectangles */
			xproto.PolyRectangle(X, winDrawable, foreground, rectangles)

			/* We draw the arcs */
			xproto.PolyArc(X, winDrawable, foreground, arcs)

		default:
			/* Unknown event type, ignore it */
		}

		if err != nil {
			log.Fatal(err)
		}
	}
	return
}
Ejemplo n.º 15
0
func xwmInit(fd uintptr) {

	X := fromFd(fd)
	defer X.Conn().Close()

	root := xwindow.New(X, X.RootWin())

	if _, err := root.Geometry(); err != nil {
		panic(err)
	}

	// if names, _ := ewmh.DesktopNamesGet(X); len(names) > 0 {
	// 	println(names)
	// }

	composite.Init(X.Conn())

	atomNames := []string{
		"WL_SURFACE_ID",
		"WM_DELETE_WINDOW",
		"WM_PROTOCOLS",
		"WM_S0",
		"WM_NORMAL_HINTS",
		"WM_TAKE_FOCUS",
		"WM_STATE",
		"WM_CLIENT_MACHINE",
		"_NET_WM_CM_S0",
		"_NET_WM_NAME",
		"_NET_WM_PID",
		"_NET_WM_ICON",
		"_NET_WM_STATE",
		"_NET_WM_STATE_FULLSCREEN",
		"_NET_WM_USER_TIME",
		"_NET_WM_ICON_NAME",
		"_NET_WM_WINDOW_TYPE",
		"_NET_WM_WINDOW_TYPE_DESKTOP",
		"_NET_WM_WINDOW_TYPE_DOCK",
		"_NET_WM_WINDOW_TYPE_TOOLBAR",
		"_NET_WM_WINDOW_TYPE_MENU",
		"_NET_WM_WINDOW_TYPE_UTILITY",
		"_NET_WM_WINDOW_TYPE_SPLASH",
		"_NET_WM_WINDOW_TYPE_DIALOG",
		"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
		"_NET_WM_WINDOW_TYPE_POPUP_MENU",
		"_NET_WM_WINDOW_TYPE_TOOLTIP",
		"_NET_WM_WINDOW_TYPE_NOTIFICATION",
		"_NET_WM_WINDOW_TYPE_COMBO",
		"_NET_WM_WINDOW_TYPE_DND",
		"_NET_WM_WINDOW_TYPE_NORMAL",
		"_NET_WM_MOVERESIZE",
		"_NET_SUPPORTING_WM_CHECK",
		"_NET_SUPPORTED",
		"_MOTIF_WM_HINTS",
		"CLIPBOARD",
		"CLIPBOARD_MANAGER",
		"TARGETS",
		"UTF8_STRING",
		"_WL_SELECTION",
		"INCR",
		"TIMESTAMP",
		"MULTIPLE",
		"UTF8_STRING",
		"COMPOUND_TEXT",
		"TEXT",
		"STRING",
		"text/plain;charset=utf-8",
		"text/plain",
		"XdndSelection",
		"XdndAware",
		"XdndEnter",
		"XdndLeave",
		"XdndDrop",
		"XdndStatus",
		"XdndFinished",
		"XdndTypeList",
		"XdndActionCopy",
	}

	cookies := make([]xproto.InternAtomCookie, len(atomNames))

	for i := 0; i < len(atomNames); i++ {
		cookies[i] = xproto.InternAtom(X.Conn(),
			false, uint16(len(atomNames[i])), atomNames[i])
	}

	/* Try to select for substructure redirect. */
	evMasks := xproto.EventMaskPropertyChange |
		xproto.EventMaskFocusChange |
		xproto.EventMaskButtonPress |
		xproto.EventMaskButtonRelease |
		xproto.EventMaskStructureNotify |
		xproto.EventMaskSubstructureNotify |
		xproto.EventMaskSubstructureRedirect

	root.Listen(evMasks)

	composite.RedirectSubwindows(X.Conn(), root.Id,
		composite.RedirectManual)

	// change config
	// data := []byte{1}
	// propAtom, _ := xprop.Atm(X, "_NET_SUPPORTED")
	// var format byte = 32
	// xproto.ChangePropertyChecked(X.Conn(), xproto.PropModeReplace,
	// 	root.Id, propAtom, xproto.AtomAtom, format,
	// 	uint32(len(data)/(int(format)/8)), data)

	ewmh.SupportedSet(X, []string{
		"_NET_SUPPORTED",
		"_NET_CLIENT_LIST",
		"_NET_NUMBER_OF_DESKTOPS",
		"_NET_DESKTOP_GEOMETRY",
		"_NET_CURRENT_DESKTOP",
		"_NET_VISIBLE_DESKTOPS",
		"_NET_DESKTOP_NAMES",
		"_NET_ACTIVE_WINDOW",
		"_NET_SUPPORTING_WM_CHECK",
		"_NET_CLOSE_WINDOW",
		"_NET_MOVERESIZE_WINDOW",
		"_NET_RESTACK_WINDOW",
		"_NET_WM_NAME",
		"_NET_WM_DESKTOP",
		"_NET_WM_WINDOW_TYPE",
		"_NET_WM_WINDOW_TYPE_DESKTOP",
		"_NET_WM_WINDOW_TYPE_DOCK",
		"_NET_WM_WINDOW_TYPE_TOOLBAR",
		"_NET_WM_WINDOW_TYPE_MENU",
		"_NET_WM_WINDOW_TYPE_UTILITY",
		"_NET_WM_WINDOW_TYPE_SPLASH",
		"_NET_WM_WINDOW_TYPE_DIALOG",
		"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
		"_NET_WM_WINDOW_TYPE_POPUP_MENU",
		"_NET_WM_WINDOW_TYPE_TOOLTIP",
		"_NET_WM_WINDOW_TYPE_NOTIFICATION",
		"_NET_WM_WINDOW_TYPE_COMBO",
		"_NET_WM_WINDOW_TYPE_DND",
		"_NET_WM_WINDOW_TYPE_NORMAL",
		"_NET_WM_STATE",
		"_NET_WM_STATE_STICKY",
		"_NET_WM_STATE_MAXIMIZED_VERT",
		"_NET_WM_STATE_MAXIMIZED_HORZ",
		"_NET_WM_STATE_SKIP_TASKBAR",
		"_NET_WM_STATE_SKIP_PAGER",
		"_NET_WM_STATE_HIDDEN",
		"_NET_WM_STATE_FULLSCREEN",
		"_NET_WM_STATE_ABOVE",
		"_NET_WM_STATE_BELOW",
		"_NET_WM_STATE_DEMANDS_ATTENTION",
		"_NET_WM_STATE_FOCUSED",
		"_NET_WM_ALLOWED_ACTIONS",
		"_NET_WM_ACTION_MOVE",
		"_NET_WM_ACTION_RESIZE",
		"_NET_WM_ACTION_MINIMIZE",
		"_NET_WM_ACTION_STICK",
		"_NET_WM_ACTION_MAXIMIZE_HORZ",
		"_NET_WM_ACTION_MAXIMIZE_VERT",
		"_NET_WM_ACTION_FULLSCREEN",
		"_NET_WM_ACTION_CHANGE_DESKTOP",
		"_NET_WM_ACTION_CLOSE",
		"_NET_WM_ACTION_ABOVE",
		"_NET_AM_ACTION_BELOW",
		"_NET_WM_STRUT_PARTIAL",
		"_NET_WM_ICON",
		"_NET_FRAME_EXTENTS",
		"WM_TRANSIENT_FOR",
	})

	// create wm window
	win, _ := xwindow.Create(X, root.Id)

	xproto.MapWindow(X.Conn(), win.Id)

	atomValues := make([]xproto.Atom, len(atomNames))
	for num, cookie := range cookies {
		reply, _ := cookie.Reply()
		atomValues[num] = reply.Atom
	}

	/* take WM_S0 selection last, which
	 * signals to Xwayland that we're done with setup. */
	xproto.SetSelectionOwner(X.Conn(), win.Id,
		atomValues[3],
		xproto.TimeCurrentTime,
	)

	mapResquest := func(event xgb.Event) {
		ev, _ := event.(xproto.MapRequestEvent)
		log.Info("MapRequest: ", ev)

		xproto.MapWindow(X.Conn(), ev.Window)
		icccm.WmStateSet(X, ev.Window, &icccm.WmState{
			State: icccm.StateNormal,
			Icon:  ev.Window,
		})
		// TODO: set _net_wm_state
	}

	for {
		x := X.Conn()
		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)
		}

		switch ev.(type) {
		case xproto.CreateNotifyEvent:
			createNotify(X, ev)
			fmt.Printf("Event: %s\n", ev)
		case xproto.DestroyNotifyEvent:
			destroyNotify(X, ev)
			fmt.Printf("Event: %s\n", ev)
		case xproto.MapRequestEvent:
			mapResquest(ev)
		case xproto.ConfigureNotifyEvent:
			configureNotify(X, ev)
		case xproto.PropertyNotifyEvent:
			fmt.Printf("Event: %s\n", ev)
		case xproto.ClientMessageEvent:
			clientMessage(X, ev)
		case xproto.ConfigureRequestEvent:
			configureRequest(X, ev)
		case xproto.UnmapNotifyEvent:
			unmapNotify(X, ev)
		default:
			log.Info("Event:", ev)
		}

	}

	// xevent.MapRequestFun(
	// 	func(X *xgbutil.XUtil, e xevent.MapRequestEvent) {
	// 		println(e.Window)
	// 	}).Connect(X, root.Id)

	// xevent.ConfigureNotifyFun(
	// 	func(X *xgbutil.XUtil, e xevent.ConfigureNotifyEvent) {
	// 		fmt.Printf("(%d, %d) %dx%d\n", e.X, e.Y, e.Width, e.Height)
	// 	}).Connect(X, root.Id)

	// xevent.FocusInFun(
	// 	func(X *xgbutil.XUtil, e xevent.FocusInEvent) {
	// 		fmt.Printf("(%v, %v)\n", e.Mode, e.Detail)
	// 	}).Connect(X, root.Id)

	// xevent.Main(X)
}
Ejemplo n.º 16
0
func main() {
	// Open the connection to the X server
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	defer X.Close()

	// geometric objects
	points := []xproto.Point{
		{10, 10},
		{10, 20},
		{20, 10},
		{20, 20}}

	polyline := []xproto.Point{
		{50, 10},
		{5, 20}, // rest of points are relative
		{25, -20},
		{10, 10}}

	segments := []xproto.Segment{
		{100, 10, 140, 30},
		{110, 25, 130, 60}}

	rectangles := []xproto.Rectangle{
		{10, 50, 40, 20},
		{80, 50, 10, 40}}

	arcs := []xproto.Arc{
		{10, 100, 60, 40, 0, 90 << 6},
		{90, 100, 55, 40, 0, 270 << 6}}

	setup := xproto.Setup(X)
	// Get the first screen
	screen := setup.DefaultScreen(X)

	// Create black (foreground) graphic context
	foreground, _ := xproto.NewGcontextId(X)
	mask := uint32(xproto.GcForeground | xproto.GcGraphicsExposures)
	values := []uint32{screen.BlackPixel, 0}
	xproto.CreateGC(X, foreground, xproto.Drawable(screen.Root), mask, values)

	// Ask for our window's Id
	win, _ := xproto.NewWindowId(X)
	winDrawable := xproto.Drawable(win)

	// Create the window
	mask = uint32(xproto.CwBackPixel | xproto.CwEventMask)
	values = []uint32{screen.WhitePixel, xproto.EventMaskExposure}
	xproto.CreateWindow(X, // Connection
		screen.RootDepth, // Depth
		win,              // Window Id
		screen.Root,      // Parent Window
		0, 0,             // x, y
		150, 150, // width, height
		10, // border_width
		xproto.WindowClassInputOutput, // class
		screen.RootVisual,             // visual
		mask, values)                  // masks

	// Map the window on the screen
	xproto.MapWindow(X, win)

	// Obey the window-delete protocol
	tp := "WM_PROTOCOLS"
	prp := "WM_DELETE_WINDOW"
	typeAtom, _ := xproto.InternAtom(X, true, uint16(len(tp)), tp).Reply()
	propertyAtom, _ := xproto.InternAtom(X, true, uint16(len(prp)), prp).Reply()

	// It turns out that we need the window ID as a byte-stream... WTF!!
	// xprop.ChangeProp(xu, win, 8, "WM_NAME", "STRING", ([]byte)(name))
	// ChangeProp(xu *xgbutil.XUtil, win xproto.Window, format byte, prop string, typ string, data []byte)
	data := make([]byte, 4)
	xgb.Put32(data, uint32(propertyAtom.Atom))
	xproto.ChangeProperty(X, xproto.PropModeReplace, win, typeAtom.Atom, xproto.AtomAtom, 32, 1, data)

	for {
		evt, err := X.WaitForEvent()
		fmt.Printf("An event of type %T occured.\n", evt)

		if evt == nil && err == nil {
			fmt.Println("Exiting....")
			return
		} else if err != nil {
			log.Fatal(err)
		}

		switch event := evt.(type) {
		case xproto.ExposeEvent:
			/* We draw the points */
			xproto.PolyPoint(X, xproto.CoordModeOrigin, winDrawable, foreground, points)

			/* We draw the polygonal line */
			xproto.PolyLine(X, xproto.CoordModePrevious, winDrawable, foreground, polyline)

			/* We draw the segments */
			xproto.PolySegment(X, winDrawable, foreground, segments)

			/* We draw the rectangles */
			xproto.PolyRectangle(X, winDrawable, foreground, rectangles)

			/* We draw the arcs */
			xproto.PolyArc(X, winDrawable, foreground, arcs)
		case xproto.ClientMessageEvent:
			if len(event.Data.Data32) > 0 {
				data := xproto.Atom(event.Data.Data32[0])
				if data == propertyAtom.Atom {
					return
				} else {
					atomName, _ := xproto.GetAtomName(X, data).Reply()
					fmt.Println(atomName.Name)
				}
			} else {
				atomName, _ := xproto.GetAtomName(X, event.Type).Reply()
				fmt.Println(atomName.Name)
			}
		default:
			/* Unknown event type, ignore it */
		}
	}
	return
}