Esempio n. 1
0
func main() {
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Get the window id of the root window.
	setup := xproto.Setup(X)
	root := setup.DefaultScreen(X).Root

	// Get the atom id (i.e., intern an atom) of "_NET_ACTIVE_WINDOW".
	aname := "_NET_ACTIVE_WINDOW"
	activeAtom, err := xproto.InternAtom(X, true, uint16(len(aname)),
		aname).Reply()
	if err != nil {
		log.Fatal(err)
	}

	// Get the atom id (i.e., intern an atom) of "_NET_WM_NAME".
	aname = "_NET_WM_NAME"
	nameAtom, err := xproto.InternAtom(X, true, uint16(len(aname)),
		aname).Reply()
	if err != nil {
		log.Fatal(err)
	}

	// Get the actual value of _NET_ACTIVE_WINDOW.
	// Note that 'reply.Value' is just a slice of bytes, so we use an
	// XGB helper function, 'Get32', to pull an unsigned 32-bit integer out
	// of the byte slice. We then convert it to an X resource id so it can
	// be used to get the name of the window in the next GetProperty request.
	reply, err := xproto.GetProperty(X, false, root, activeAtom.Atom,
		xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		log.Fatal(err)
	}
	windowId := xproto.Window(xgb.Get32(reply.Value))
	fmt.Printf("Active window id: %X\n", windowId)

	// Now get the value of _NET_WM_NAME for the active window.
	// Note that this time, we simply convert the resulting byte slice,
	// reply.Value, to a string.
	reply, err = xproto.GetProperty(X, false, windowId, nameAtom.Atom,
		xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Active window name: %s\n", string(reply.Value))
}
Esempio 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)
	}
}
Esempio n. 3
0
func (s *screenImpl) internAtom(name string) (xproto.Atom, error) {
	r, err := xproto.InternAtom(s.xc, false, uint16(len(name)), name).Reply()
	if err != nil {
		return 0, fmt.Errorf("x11driver: xproto.InternAtom failed: %v", err)
	}
	if r == nil {
		return 0, fmt.Errorf("x11driver: xproto.InternAtom failed")
	}
	return r.Atom, nil
}
Esempio n. 4
0
func internAtom(name string) xp.Atom {
	r, err := xp.InternAtom(xConn, false, uint16(len(name)), name).Reply()
	if err != nil {
		log.Fatal(err)
	}
	if r == nil {
		return 0
	}
	return r.Atom
}
Esempio n. 5
0
func (logger *WindowLogger) getCurWindowTitle() (name string, err error) {
	// Get the window id of the root window.
	setup := xproto.Setup(logger.X11Connection)
	root := setup.DefaultScreen(logger.X11Connection).Root

	// Get the atom id (i.e., intern an atom) of "_NET_ACTIVE_WINDOW".
	aname := "_NET_ACTIVE_WINDOW"
	activeAtom, err := xproto.InternAtom(logger.X11Connection, true, uint16(len(aname)),
		aname).Reply()
	if err != nil {
		return "", err
	}

	// Get the atom id (i.e., intern an atom) of "_NET_WM_NAME".
	aname = "_NET_WM_NAME"
	nameAtom, err := xproto.InternAtom(logger.X11Connection, true, uint16(len(aname)),
		aname).Reply()
	if err != nil {
		return "", err
	}

	// Get the actual value of _NET_ACTIVE_WINDOW.
	// Note that 'reply.Value' is just a slice of bytes, so we use an
	// XGB helper function, 'Get32', to pull an unsigned 32-bit integer out
	// of the byte slice. We then convert it to an X resource id so it can
	// be used to get the name of the window in the next GetProperty request.
	reply, err := xproto.GetProperty(logger.X11Connection, false, root, activeAtom.Atom,
		xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		return "", err
	}
	windowId := xproto.Window(xgb.Get32(reply.Value))

	// Now get the value of _NET_WM_NAME for the active window.
	// Note that this time, we simply convert the resulting byte slice,
	// reply.Value, to a string.
	reply, err = xproto.GetProperty(logger.X11Connection, false, windowId, nameAtom.Atom,
		xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		return "", err
	}
	return string(reply.Value), nil
}
Esempio n. 6
0
func (a *atomic) atom(name string, onlyIfExists bool) (xproto.Atom, error) {
	if aid, ok := a.atomGet(name); ok {
		return aid, nil
	}

	reply, err := xproto.InternAtom(a.c, onlyIfExists, uint16(len(name)), name).Reply()
	if err != nil {
		return 0, AtomInternError(name, err)
	}

	a.cacheAtom(name, reply.Atom)

	return reply.Atom, nil
}
Esempio n. 7
0
File: main.go Progetto: tejohnso/xgb
func main() {
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	names := seqNames(flagRequests)

	fcpu, err := os.Create(flagCpuProfName)
	if err != nil {
		log.Fatal(err)
	}
	defer fcpu.Close()
	pprof.StartCPUProfile(fcpu)
	defer pprof.StopCPUProfile()

	start := time.Now()
	cookies := make([]xproto.InternAtomCookie, flagRequests)
	for i := 0; i < flagRequests; i++ {
		cookies[i] = xproto.InternAtom(X,
			false, uint16(len(names[i])), names[i])
	}
	for _, cookie := range cookies {
		cookie.Reply()
	}
	fmt.Printf("Exec time: %s\n\n", time.Since(start))

	fmem, err := os.Create(flagMemProfName)
	if err != nil {
		log.Fatal(err)
	}
	defer fmem.Close()
	pprof.WriteHeapProfile(fmem)

	memStats := &runtime.MemStats{}
	runtime.ReadMemStats(memStats)

	// This isn't right. I'm not sure what's wrong.
	lastGcTime := time.Unix(int64(memStats.LastGC/1000000000),
		int64(memStats.LastGC-memStats.LastGC/1000000000))

	fmt.Printf("Alloc: %d\n", memStats.Alloc)
	fmt.Printf("TotalAlloc: %d\n", memStats.TotalAlloc)
	fmt.Printf("LastGC: %s\n", lastGcTime)
	fmt.Printf("PauseTotalNs: %d\n", memStats.PauseTotalNs)
	fmt.Printf("PauseNs: %d\n", memStats.PauseNs)
	fmt.Printf("NumGC: %d\n", memStats.NumGC)
}
Esempio n. 8
0
// Atom interns an atom and panics if there is any error.
func Atom(xu *xgbutil.XUtil, name string,
	onlyIfExists bool) (xproto.Atom, error) {

	// Check the cache first
	if aid, ok := atomGet(xu, name); ok {
		return aid, nil
	}

	reply, err := xproto.InternAtom(xu.Conn(), onlyIfExists,
		uint16(len(name)), name).Reply()
	if err != nil {
		return 0, fmt.Errorf("Atom: Error interning atom '%s': %s", name, err)
	}

	// If we're here, it means we didn't have this atom cached. So cache it!
	cacheAtom(xu, name, reply.Atom)

	return reply.Atom, nil
}
Esempio n. 9
0
func newBrightness(Xu *xgbutil.XUtil) (*brightness, error) {
	const atomName = "Backlight"
	atomReply, err := xproto.InternAtom(Xu.Conn(), true, uint16(len(atomName)), atomName).Reply()
	if err != nil {
		return nil, fmt.Errorf("no backlight: %v", err)
	}

	b := &brightness{
		prop: atomReply.Atom,
	}

	if err := bind(Xu,
		binding{"XF86MonBrightnessUp", b.up},
		binding{"XF86MonBrightnessDown", b.down},
	); err != nil {
		return nil, err
	}

	return b, nil
}
Esempio n. 10
0
func main() {

	var serve *bool = flag.Bool("serve", false, "Listen for connections")

	flag.Usage = usage
	flag.Parse()

	if remote := os.Getenv("SSH_CONNECTION"); remote == "" && len(flag.Args()) != 0 {
		invoked_as := os.Args[0]
		actual_binary, err := os.Readlink("/proc/self/exe")
		if err != nil {
			log.Panic("/proc/self/exe doesn't exist!")
		}
		log.Print("Invoked as: '", invoked_as, "' (actual=", actual_binary, ")")
		log.Panic("Not yet implemented: Would have run locally")
		return
	}

	c, err := xgb.NewConn()
	if err != nil {
		log.Panic("cannot connect: %v\n", err)
	}
	s := xproto.Setup(c).DefaultScreen(c)

	rl_execute_reply, err := xproto.InternAtom(c, false, uint16(len(atomname)), atomname).Reply()
	if err != nil {
		panic(err)
	}
	rl_execute_atom := rl_execute_reply.Atom

	if *serve {
		//log.Printf("c = %v, s = %v, a = %v", c, s, rl_execute_atom)
		start_server(c, s, rl_execute_atom)
	} else {
		if len(flag.Args()) == 0 {
			usage()
		}
		connect(c, s, rl_execute_atom, fixup_args(flag.Args()))
	}
}
Esempio n. 11
0
// Listen ...
func Listen(fn func(e Event)) error {
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	setup := xproto.Setup(X)
	root := setup.DefaultScreen(X).Root

	var prevWindowID xproto.Window
	var prevClasses []string

	for {
		<-time.After(msRefresh * time.Millisecond)

		// From one of the xgb examples.
		aname := "_NET_ACTIVE_WINDOW"
		activeAtom, err := xproto.InternAtom(X, true, uint16(len(aname)),
			aname).Reply()
		if err != nil {
			log.Println(err)
			continue
		}

		reply, err := xproto.GetProperty(X, false, root, activeAtom.Atom,
			xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
		if err != nil {
			log.Println(err)
			continue
		}

		windowID := xproto.Window(xgb.Get32(reply.Value))

		aname = "WM_CLASS"
		nameAtom, err := xproto.InternAtom(X, true, uint16(len(aname)),
			aname).Reply()
		if err != nil {
			log.Println(err)
			continue
		}

		reply, err = xproto.GetProperty(X, false, windowID, nameAtom.Atom,
			xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
		if err != nil {
			log.Println(err)
			continue
		}

		classes := stringSlice(reply.Value)

		// Check if active window has changed since last time.
		if windowID != prevWindowID {
			fn(Lost{
				WMClass: prevClasses,
			})
			fn(Gained{
				WMClass: classes,
			})
			prevWindowID = windowID
			prevClasses = classes
		}
	}
}
Esempio n. 12
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
}
Esempio n. 13
0
func main() {
	sleepy := time.Millisecond
	X, _ := xgbutil.NewConn()
	conn := X.Conn()

	aDesktop := "_NET_WM_DESKTOP"
	aActive := "_NET_ACTIVE_WINDOW"

	xwindow.Listen(X, X.RootWin(), xproto.EventMaskPropertyChange)
	xevent.PropertyNotifyFun(
		func(X *xgbutil.XUtil, ev xevent.PropertyNotifyEvent) {
			for i := 0; i < 1; i++ {
				log.Println("PROPERTY CHANGE")
			}
		}).Connect(X, X.RootWin())

	go func() {
		for {
			reply, err := xproto.InternAtom(conn, true, uint16(len(aDesktop)),
				aDesktop).Reply()
			if err != nil {
				log.Fatal(err)
			}

			log.Println("A1-299", reply.Sequence, reply.Atom)
			time.Sleep(sleepy)
		}
	}()

	go func() {
		for {
			reply, err := xproto.InternAtom(conn, true, uint16(len(aActive)),
				aActive).Reply()
			if err != nil {
				log.Fatal(err)
			}

			log.Println("A2-294", reply.Sequence, reply.Atom)
			time.Sleep(sleepy)
		}
	}()

	go func() {
		for {
			reply, err := xproto.GetGeometry(conn, 0x1).Reply()
			if err != nil {
				log.Println("0x1:", err)
			} else {
				log.Println("0x1:", reply)
			}
			time.Sleep(sleepy)
		}
	}()

	go func() {
		for {
			reply, err := xproto.GetGeometry(conn, 0x2).Reply()
			if err != nil {
				log.Println("0x2:", err)
			} else {
				log.Println("0x2:", reply)
			}
			time.Sleep(sleepy)
		}
	}()

	go xevent.Main(X)
	select {}
}
Esempio n. 14
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)
}
Esempio n. 15
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
}