// Map is a simple alias to map the window. func (w *Window) Map() { if w == nil { return } xproto.MapWindow(w.X.Conn(), w.Id) }
// 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) } }
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) }
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) }
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) } } }
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 }
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 }
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 }
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) } } }
// 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 }
func (w *Window) Map() { xproto.MapWindow(w.conn, w.id) }
// Map is a simple alias to map the window. func (w *Window) Map() { xproto.MapWindow(w.X.Conn(), w.Id) }
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 }
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 }
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) }
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 }