Пример #1
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
}
Пример #2
0
func initDesktop(xScreen *xp.ScreenInfo) {
	xFont, err := xp.NewFontId(xConn)
	if err != nil {
		log.Fatal(err)
	}
	xCursor, err := xp.NewCursorId(xConn)
	if err != nil {
		log.Fatal(err)
	}
	err = xp.OpenFontChecked(xConn, xFont, uint16(len("cursor")), "cursor").Check()
	if err != nil {
		log.Fatal(err)
	}
	const xcLeftPtr = 68 // XC_left_ptr from cursorfont.h.
	err = xp.CreateGlyphCursorChecked(
		xConn, xCursor, xFont, xFont, xcLeftPtr, xcLeftPtr+1,
		0xffff, 0xffff, 0xffff, 0, 0, 0).Check()
	if err != nil {
		log.Fatal(err)
	}
	err = xp.CloseFontChecked(xConn, xFont).Check()
	if err != nil {
		log.Fatal(err)
	}

	desktopXWin, err = xp.NewWindowId(xConn)
	if err != nil {
		log.Fatal(err)
	}
	desktopXGC, err = xp.NewGcontextId(xConn)
	if err != nil {
		log.Fatal(err)
	}
	desktopWidth = xScreen.WidthInPixels
	desktopHeight = xScreen.HeightInPixels

	if err := xp.CreateWindowChecked(
		xConn, xScreen.RootDepth, desktopXWin, xScreen.Root,
		0, 0, desktopWidth, desktopHeight, 0,
		xp.WindowClassInputOutput,
		xScreen.RootVisual,
		xp.CwOverrideRedirect|xp.CwEventMask,
		[]uint32{
			1,
			xp.EventMaskExposure,
		},
	).Check(); err != nil {
		log.Fatal(err)
	}

	if len(xSettings) != 0 {
		initXSettings()
	}

	if err := xp.ConfigureWindowChecked(
		xConn,
		desktopXWin,
		xp.ConfigWindowStackMode,
		[]uint32{
			xp.StackModeBelow,
		},
	).Check(); err != nil {
		log.Fatal(err)
	}

	if err := xp.ChangeWindowAttributesChecked(
		xConn,
		desktopXWin,
		xp.CwBackPixel|xp.CwCursor,
		[]uint32{
			xScreen.BlackPixel,
			uint32(xCursor),
		},
	).Check(); err != nil {
		log.Fatal(err)
	}

	if err := xp.CreateGCChecked(
		xConn,
		desktopXGC,
		xp.Drawable(xScreen.Root),
		0,
		nil,
	).Check(); err != nil {
		log.Fatal(err)
	}

	if err := xp.MapWindowChecked(xConn, desktopXWin).Check(); err != nil {
		log.Fatal(err)
	}
}
Пример #3
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
}
Пример #4
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
}
Пример #5
0
func loadGC(name string, c *xgb.Conn, scr *xproto.ScreenInfo) error {
	var gc gcontext

	/* Foreground GC */
	id, err := xproto.NewGcontextId(c)
	if err != nil {
		return err
	}
	var mask uint32 = xproto.GcForeground | xproto.GcBackground |
		xproto.GcLineWidth | xproto.GcFont
	values := defaultGCValues(c)
	{
		cl, e := config.String(name + ".gc.fg")
		if e == nil {
			values[0], e = openColor(c, scr, readColor(cl))
			if e != nil {
				return e
			}
		}
		cl, e = config.String(name + ".gc.bg")
		if e == nil {
			values[1], e = openColor(c, scr, readColor(cl))
			if e != nil {
				return e
			}
		}
		wd, e := config.Int(name + ".gc.width")
		if e == nil {
			values[2] = uint32(wd)
		}
		cl, e = config.String(name + ".gc.font")
		if e == nil {
			fn, e := openFont(c, cl)
			if e != nil {
				return e
			}
			values[3] = uint32(fn)
		}
	}
	err = xproto.CreateGCChecked(c, id, xproto.Drawable(scr.Root), mask, values).Check()
	if err != nil {
		return err
	}
	gc.fg = id
	gc.font = xproto.Font(values[3])
	gc.border = values[2]

	/* Query the font height */
	{
		rep, e := xproto.QueryFont(c, xproto.Fontable(gc.font)).Reply()
		if e != nil {
			return e
		}
		gc.fontHeight = uint32(rep.FontAscent) + uint32(rep.FontDescent)
		gc.fontUp = uint32(rep.FontAscent)
	}

	/* Background GC */
	id, err = xproto.NewGcontextId(c)
	if err != nil {
		return err
	}
	mask = xproto.GcForeground | xproto.GcBackground | xproto.GcLineWidth
	values[0], values[1] = values[1], values[0]
	err = xproto.CreateGCChecked(c, id, xproto.Drawable(scr.Root), mask, values).Check()
	if err != nil {
		return err
	}
	gc.bg = id

	/* Border GC */
	id, err = xproto.NewGcontextId(c)
	if err != nil {
		return err
	}
	{
		cl, e := config.String(name + ".gc.bc")
		if e == nil {
			values[0], e = openColor(c, scr, readColor(cl))
			if e != nil {
				return e
			}
		} else {
			values[0] = defaultgc.bc
		}
	}
	values[1] = values[0]
	err = xproto.CreateGCChecked(c, id, xproto.Drawable(scr.Root), mask, values).Check()
	if err != nil {
		return err
	}
	gc.bc = id

	/* Width */
	{
		wd, e := config.Int(name + ".width")
		if e == nil {
			gc.width = uint32(wd)
		} else {
			gc.width = defaultgc.width
		}
	}

	ctxs[name] = &gc
	return nil
}
Пример #6
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
}
Пример #7
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
}
Пример #8
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
}