func XMain(callbacks Callbacks) { dpy := C.XOpenDisplay(nil) w := C.XCreateSimpleWindow(dpy, C.XDefaultRootWindow(dpy), 0, 0, 600, 400, 0, 0, 0) C.XSelectInput(dpy, w, C.StructureNotifyMask|C.SubstructureNotifyMask|C.ExposureMask) C.XMapWindow(dpy, w) win := Window{dpy: dpy, xw: w} visual := C.XDefaultVisual(dpy, 0) surf := cairo.XlibSurfaceCreate(unsafe.Pointer(dpy), uint64(win.xw), unsafe.Pointer(visual), 10, 10) for { var e C.XEvent C.XNextEvent(dpy, &e) typ := XEventType(*(*C.int)(unsafe.Pointer(&e))) // log.Printf("X event: %s", typ) switch typ { case C.ConfigureNotify: e := (*C.XConfigureEvent)(unsafe.Pointer(&e)) surf.SetSize(int(e.width), int(e.height)) case C.Expose: cr := cairo.Create(surf.Surface) callbacks.Draw(cr, surf) default: // log.Printf("unknown X event %s", typ) } } }
func (window *XWindow) Peek() bool { var xev C.XEvent events := C.XCheckWindowEvent(window.dpy) fmt.Println(events) if events != 0 { fmt.Println("Get Event") C.XNextEvent(window.dpy, &xev) if C.GetEventType(&xev) == C.Expose { return false } window.Callback(window, uint32(C.GetEventType(&xev)), 0, 0) return true } return false /* ev, xerr := window.x.PollForEvent() if(ev != nil) { //window.Callback(window, ev.) return true; } if(xerr != nil) { return true; } */ return false }
func handleEvents() bool { C.XNextEvent(dpy, eventPtr) fmt.Println(event.message_type) if event._type == C.ClientMessage { C.XCloseDisplay(dpy) return false } return true }
func main() { var dpy *C.Display var attr C.XWindowAttributes var start C.XButtonEvent var ev C.XEvent var ch *C.char if dpy != C.XOpenDisplay(ch) { return } C.XGrabKey( dpy, C.int(C.XKeysymToKeycode(dpy, C.XStringToKeysym(C.CString("F1")))), C.Mod1Mask, C.XDefaultRootWindow(dpy), 1, C.GrabModeAsync, C.GrabModeAsync, ) C.XGrabButton( dpy, 1, C.Mod1Mask, C.XDefaultRootWindow(dpy), 1, C.ButtonPressMask|C.ButtonReleaseMask|C.PointerMotionMask, C.GrabModeAsync, C.GrabModeAsync, C.None, C.None, ) C.XGrabButton( dpy, 3, C.Mod1Mask, C.XDefaultRootWindow(dpy), 1, C.ButtonPressMask|C.ButtonReleaseMask|C.PointerMotionMask, C.GrabModeAsync, C.GrabModeAsync, C.None, C.None, ) start.subwindow = C.None for { C.XNextEvent(dpy, &ev) if unionToInt(ev) == C.KeyPress && unionToXKeyEvent(ev).subwindow != C.None { C.XRaiseWindow(dpy, unionToXKeyEvent(ev).subwindow) } else if unionToInt(ev) == C.ButtonPress && unionToXButtonEvent(ev).subwindow != C.None { C.XGetWindowAttributes(dpy, unionToXButtonEvent(ev).subwindow, &attr) start = *unionToXButtonEvent(ev) } else if unionToInt(ev) == C.MotionNotify && start.subwindow != C.None { xdiff := unionToXButtonEvent(ev).x_root - start.x_root ydiff := unionToXButtonEvent(ev).y_root - start.y_root var toDiffX C.int var toDiffY C.int if start.button == 1 { toDiffX = xdiff toDiffY = ydiff } var toWidth C.int var toHeight C.int if start.button == 3 { toWidth = xdiff toHeight = ydiff } C.XMoveResizeWindow( dpy, start.subwindow, attr.x+toDiffX, attr.y+toDiffY, max(1, attr.width+toWidth), max(1, attr.height+toHeight)) } else if unionToInt(ev) == C.ButtonRelease { start.subwindow = C.None } } }
// processXEvents does one read from the X fd, then processes all pending // events. func (dpy *Display) processXEvents(win *Window) { var event C.XEvent events := C.XEventsQueued(dpy.dpy, C.QueuedAfterReading) for i := 0; i < int(events); i++ { C.XNextEvent(dpy.dpy, &event) e := &event typ := xEventType(*(*C.int)(unsafe.Pointer(e))) // log.Printf("typ %s", typ.String()) switch typ { case C.ConfigureNotify: e := (*C.XConfigureEvent)(unsafe.Pointer(e)) win.resize(int(e.width), int(e.height)) case C.Expose: e := (*C.XExposeEvent)(unsafe.Pointer(e)) win.repaint(int(e.x), int(e.y), int(e.width), int(e.height)) case C.KeyPress: e := (*C.XKeyEvent)(unsafe.Pointer(e)) key := keys.Key{} if e.state&C.ControlMask != 0 { key.Mods |= keys.ModControl } if e.state&C.Mod1Mask != 0 { key.Mods |= keys.ModMeta } var buf [8]byte var keysym C.KeySym C.XLookupString(e, (*C.char)(unsafe.Pointer(&buf)), 8, &keysym, nil) nulpos := bytes.Index(buf[:], []byte{0}) if nulpos > 0 { if nulpos > 1 { log.Printf("xlib: overlong key %q", buf[:nulpos]) } key.Sym = keys.Sym(buf[0]) if key.Mods&keys.ModControl != 0 { // Undo Ctl-A => "ASCII control character" mapping. key.Sym += 'a' - 1 } } else { // See /usr/include/X11/keysymdef.h switch keysym { case C.XK_Left: key.Sym = keys.Left case C.XK_Right: key.Sym = keys.Right case C.XK_Up: key.Sym = keys.Up case C.XK_Down: key.Sym = keys.Down case C.XK_Shift_L, C.XK_Shift_R: case C.XK_Control_L, C.XK_Control_R: case C.XK_Meta_L, C.XK_Meta_R: case C.XK_Alt_L, C.XK_Alt_R: case C.XK_Super_L, C.XK_Super_R: case C.XK_Hyper_L, C.XK_Hyper_R: case C.XK_Caps_Lock: // ignore for now default: log.Printf("xlib: unhandled keysym %#v: %#v", keysym, e) } } win.delegate.Key(key) case C.KeyRelease: // ignore case C.ButtonPress: e := (*C.XButtonEvent)(unsafe.Pointer(e)) switch e.button { case 4, 5: dy := -1 if e.button == 5 { dy = 1 } win.delegate.Scroll(dy) case 6, 7: // TODO horizontal scroll. default: log.Printf("unhandled button %#v", e) } case C.MapNotify: win.delegate.Mapped() case C.ReparentNotify: // ignore default: if typ > C.GenericEvent { // Cairo triggers shm events, which show up as extension // events with greater ids than C.GenericEvent. continue } log.Printf("unhandled ev %s", typ.String()) } } C.XFlush(dpy.dpy) }
func sendEvents() { // var tst bool tst = true tst = false // var typ C.int var ev *C.XEvent if C.XCheckMaskEvent(display, C.ExposureMask+C.StructureNotifyMask+C.SubstructureNotifyMask, &actualEvent) == C.True { aT := C.typ(&actualEvent) switch aT { case C.Expose, C.ConfigureNotify: for C.XCheckTypedEvent(display, C.int(aT), &actualEvent) == C.True { ev = &actualEvent typ = C.typ(ev) if tst { println("... got " + txt[typ] + " event") } // pp2ff () // C.XFlush (display) if typ != C.ConfigureNotify { println("init sendEvents " + txt[typ]) } } // pp2ff () } } var event Event xM, yM = 0, 0 // println ("sendEvents before for-loop") for { // if tst { println ("x is waiting for next event ...") } C.XNextEvent(display, &actualEvent) event.C, event.S = 0, 0 ev = &actualEvent typ = C.typ(ev) if tst { println("... got " + txt[typ] + " event") } switch typ { case KeyPress: event.C, event.S = uint(C.xKeyCode(ev)), uint(C.xKeyState(ev)) case KeyRelease: event.C, event.S = uint(C.xKeyCode(ev)), uint(C.xKeyState(ev)) case ButtonPress: event.C, event.S = uint(C.xButtonButton(ev)), uint(C.xButtonState(ev)) xM, yM = int(C.xButtonX(ev)), int(C.xButtonY(ev)) if xM < int(xMin) || xM > int(xMax) || yM < int(yMin) || yM > int(yMax) { event.C, event.S, xM, yM, typ = 0, 0, 0, 0, C.LASTEvent } case ButtonRelease: event.C, event.S = uint(C.xButtonButton(ev)), uint(C.xButtonState(ev)) xM, yM = int(C.xButtonX(ev)), int(C.xButtonY(ev)) if xM < int(xMin) || xM > int(xMax) || yM < int(yMin) || yM > int(yMax) { event.C, event.S, xM, yM, typ = 0, 0, 0, 0, C.LASTEvent } case MotionNotify: event.C, event.S = uint(0), uint(C.xMotionState(ev)) xM, yM = int(C.xMotionX(ev)), int(C.xMotionY(ev)) if xM < int(xMin) || xM > int(xMax) || yM < int(yMin) || yM > int(yMax) { event.C, event.S, xM, yM, typ = 0, 0, 0, 0, C.LASTEvent } case EnterNotify: // pp2ff () // println (txt [typ]) case LeaveNotify: // println (txt [typ]) case FocusIn: // println (txt [typ]) case FocusOut: // println (txt [typ]) case KeymapNotify: // println (txt [typ]) case Expose: pp2ff() // println (txt [typ]) case GraphicsExpose: // println (txt [typ]) case NoExpose: // println (txt [typ]) case VisibilityNotify: println(txt[typ]) case CreateNotify: // println (txt [typ]) case DestroyNotify: // println (txt [typ]) case UnmapNotify: // println (txt [typ]) case MapNotify: // C.XSync (display, C.False) // C.XSync (display, C.True) // pp2ff () case MapRequest: // println (txt [typ]) case ReparentNotify: // println (txt [typ]) case ConfigureNotify: // println (txt [typ]) case ConfigureRequest: // println (txt [typ]) case GravityNotify: // println (txt [typ]) case ResizeRequest: // pp2ff () // println (txt [typ]) case CirculateNotify: // println (txt [typ]) case CirculateRequest: // println (txt [typ]) case PropertyNotify: // println (txt [typ]) case SelectionClear: // println (txt [typ]) case SelectionRequest: // println (txt [typ]) case SelectionNotify: // println (txt [typ]) case ColormapNotify: // println (txt [typ]) case ClientMessage: println(txt[typ]) // mT:= C.mT (ev) // if mT != naviAtom { println ("unknown xclient.message_type ", uint32(mT)) } case MappingNotify: println(txt[typ]) case GenericEvent: println(txt[typ]) default: println("strange sort of XEvent: ", typ) } switch typ { case KeyPress, ButtonPress, ButtonRelease, MotionNotify: event.T = uint(typ) Eventpipe <- event } } }
func Init(w, h uint, cF, cB col.Colour) (uint, uint, uint) { // initialized = false // maxX, maxY, bitdepth = Screen() bdp := uint(bitdepth) switch bdp { case 15, 16, 24, 32: col.SetColourDepth(bdp) default: panic("strange colourdepth") /* Terminate (); */ os.Exit(1) } colourdepth := (bdp + 1) / 8 col.ScreenF, col.ScreenB = cF, cB xx, yy = C.uint(w), C.uint(h) window = C.XCreateSimpleWindow(display, C.Window(window0), 0, 0, xx, yy, C.uint(0), C.ulong(0), cc(col.ScreenB)) // var E C.XEvent // C.XNextEvent (display, &E) // XCreate... did not produce an XEvent C.initialize(display, screen, window) t := C.CString(env.Par(0)) defer C.free(unsafe.Pointer(t)) C.XStoreName(display, window, t) C.XMapRaised(display, window) const inputmask = (C.KeyPressMask + // C.KeyReleaseMask + C.ButtonPressMask + C.ButtonReleaseMask + C.PointerMotionMask + C.ExposureMask + C.StructureNotifyMask) C.XSelectInput(display, window, inputmask) cursor := C.XCreateFontCursor(display, C.XC_gumby) C.XDefineCursor(display, window, cursor) graphicsContext = C.XDefaultGC(display, screen) // C.XFlushGC (display graphicsContext) C.XSetGraphicsExposures(display, graphicsContext, C.False) SetFontsize(16) initialized = true Colours(cF, cB) C.XSetForeground(display, graphicsContext, cc(col.ScreenB)) C.XFillRectangle(display, C.Drawable(window), graphicsContext, 0, 0, xx, yy) pixmap = C.XCreatePixmap(display, C.Drawable(window), xx, yy, bitdepth) pixmap1 = C.XCreatePixmap(display, C.Drawable(window), maxX, maxY, bitdepth) C.XFillRectangle(display, C.Drawable(pixmap), graphicsContext, 0, 0, xx, yy) C.XFillRectangle(display, C.Drawable(pixmap1), graphicsContext, 0, 0, xx, yy) C.XSetForeground(display, graphicsContext, cc(col.ScreenF)) MouseDef(0, 0, int(xx-1), int(yy-1)) var E C.XEvent C.XNextEvent(display, &E) var et C.int = C.typ(&E) // et == *E.type switch et { case C.Expose, C.ConfigureNotify: // zur Erstausgabe for C.XCheckTypedEvent(display, et, &E) == C.True { } // pp2ff () case KeyPress, KeyRelease, ButtonPress, ButtonRelease, MotionNotify: C.XPutBackEvent(display, &E) case C.ReparentNotify: // at Switch (?) // ignore default: // for test purposes // println ("at initializing x:" + txt [et]) } p := C.CString("WM_PROTOCOLS") defer C.free(unsafe.Pointer(p)) wm_protocols := C.XInternAtom(display, p, C.False) C.XSetWMProtocols(display, window, &wm_protocols, 1) s := C.CString("_NET_WM_STATE") defer C.free(unsafe.Pointer(s)) netwm_state = C.XInternAtom(display, s, C.False) f := C.CString("_NET_WM_STATE_FULLSCREEN") defer C.free(unsafe.Pointer(f)) fullscreen = C.XInternAtom(display, f, C.False) m := C.CString("navi") defer C.free(unsafe.Pointer(m)) naviAtom = C.XInternAtom(display, m, C.False) Eventpipe = make(chan Event) go sendEvents() // C.XFlush (display) // println ("init ok") return uint(maxX), uint(maxY), colourdepth }
func main() { window, err := CreateXWindow(500, 500) if err != nil { panic(err) } defer C.XCloseDisplay(window.Display) DB, err := initDB() if err != nil { panic(err) } //getTwitterData(DB) tweetsList, err := regenerateViewData(window, DB, 20) if err != nil { panic(err) } wmDeleteMessage := C.XInternAtom(window.Display, C.CString("WM_DELETE_WINDOW"), 0) C.XSetWMProtocols(window.Display, window.Window, &wmDeleteMessage, 1) mouseClick := [2]int{-1, -1} var event C.XEvent for { pendingRedraws := false processedOneEvent := false for !processedOneEvent || C.XPending(window.Display) != 0 { C.XNextEvent(window.Display, &event) processedOneEvent = true switch C.getXEventType(event) { case C.Expose: pendingRedraws = true case C.KeyPress: ke := C.eventAsKeyEvent(event) //fmt.Println("Key pressed", ke.keycode) switch ke.keycode { case 116: // down window.Scroll -= 10 case 111: // up window.Scroll += 10 } pendingRedraws = true case C.ButtonPress: b := C.eventAsButtonEvent(event) switch b.button { case 4: // scroll up window.Scroll += 10 case 5: // scroll down window.Scroll -= 10 case 1: // left mouse down butEv := (*C.XButtonEvent)(unsafe.Pointer(&event)) mouseClick[0] = int(butEv.x) mouseClick[1] = int(butEv.y) } pendingRedraws = true case C.ClientMessage: if C.clientMessageType(event) == C.long(wmDeleteMessage) { return } } } if pendingRedraws { RedrawWindow(window, tweetsList, mouseClick) mouseClick[0] = -1 mouseClick[1] = -1 } } }