func testType(rl *ReadLine, inputs ...string) { for _, input := range inputs { mod := uint(0) if len(input) > 2 && input[:2] == "C-" { mod |= keys.ModControl input = input[2:] } for _, k := range input { rl.Key(keys.Key{keys.Sym(k), mod}) } } }
//export smashGoKey func smashGoKey(winKey unsafe.Pointer, gkey *C.GdkEventKey) { win := globalPointerStore.Get(winKey).(*Window) switch gkey.keyval { case C.GDK_KEY_Shift_L, C.GDK_KEY_Shift_R, C.GDK_KEY_Control_L, C.GDK_KEY_Control_R, C.GDK_KEY_Alt_L, C.GDK_KEY_Alt_R, C.GDK_KEY_Meta_L, C.GDK_KEY_Meta_R, C.GDK_KEY_Super_L, C.GDK_KEY_Super_R: return } rune := C.gdk_keyval_to_unicode(gkey.keyval) key := keys.Key{} key.Sym = keys.Sym(rune) if gkey.state&C.GDK_CONTROL_MASK != 0 { key.Mods |= keys.ModControl } if gkey.state&C.GDK_MOD1_MASK != 0 { key.Mods |= keys.ModMeta } win.delegate.Key(key) }
// 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) }