示例#1
0
// type a keysym, applying a slice of modifiers
func KeysymType(keysym C.KeySym, modifiers []string) error {
	// As XTestFakeKeyEvent does not use current keyboard layout,
	// we map each keysym to type to an unused keycode to circumvent this bug
	nkeysyms := C.int(5)
	keysyms := make([]C.KeySym, nkeysyms)
	for i, _ := range keysyms {
		keysyms[i] = keysym
	}

	var err error
	keycode, err := x.UnusedKeycode()
	if err != nil {
		return err
	}
	C.XChangeKeyboardMapping(x.dpy, C.int(keycode), nkeysyms, &keysyms[0], 1)
	x.XSync()

	// apply modifiers
	for _, modifier := range modifiers {
		bytes := []byte(modifier)
		mkeysym := C.XStringToKeysym((*C.char)(unsafe.Pointer(&bytes[0])))
		mkeycode := C.XKeysymToKeycode(x.dpy, mkeysym)
		C.XTestFakeKeyEvent(x.dpy, C.uint(mkeycode), 1, 0)
	}

	// hit/release the keycode associated to desired keysym
	C.XTestFakeKeyEvent(x.dpy, C.uint(keycode), 1, 0)
	C.XTestFakeKeyEvent(x.dpy, C.uint(keycode), 0, 0)

	// release modifiers
	for _, modifier := range modifiers {
		bytes := []byte(modifier)
		mkeysym := C.XStringToKeysym((*C.char)(unsafe.Pointer(&bytes[0])))
		mkeycode := C.XKeysymToKeycode(x.dpy, mkeysym)
		C.XTestFakeKeyEvent(x.dpy, C.uint(mkeycode), 0, 0)
	}
	x.XSync()

	// release unused keycode
	for i, _ := range keysyms {
		keysyms[i] = 0
	}
	C.XChangeKeyboardMapping(x.dpy, C.int(keycode), nkeysyms, &keysyms[0], 1)
	x.XSync()

	return nil
}
示例#2
0
func sendKey(disp *C.struct__XDisplay, strname string) {
	if disp == nil {
		fmt.Println("no X11 display available")
		return
	}

	var mod _Ctype_KeyCode

	if strings.HasPrefix(strname, "Ctrl+") {
		strname = strname[len("Ctrl+"):]
		modkey := "Control_L"
		mod = C.XKeysymToKeycode(disp, C.XStringToKeysym(C.CString(modkey)))
		if debug {
			fmt.Printf("send key %T (Control) code=%v\n", mod, mod)
		}
		C.XTestFakeKeyEvent(disp, C.uint(mod), 1, 0)
		C.XFlush(disp)
	}
	chstr := C.CString(strname)
	keysym := C.XStringToKeysym(chstr)
	keycode := C.XKeysymToKeycode(disp, keysym)
	if debug {
		fmt.Printf("send key (%s) sym=%v code=%v\n", strname, keysym, keycode)
	}
	C.XTestFakeKeyEvent(disp, C.uint(keycode), 1, 0)
	C.XFlush(disp)
	C.XTestFakeKeyEvent(disp, C.uint(keycode), 0, 0)
	C.XFlush(disp)
	if debug {
		fmt.Printf("hit key %v (keysym %v keycode %v)\n", strname, keysym, keycode)
	}
	fmt.Printf("mod is == %v\n", mod)
	if mod != 0 {
		C.XTestFakeKeyEvent(disp, C.uint(mod), 0, 0)
		C.XFlush(disp)
	}
}
示例#3
0
文件: tinywm.go 项目: mantyr/tinywm
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
		}
	}
}