Вы находитесь на странице: 1из 3

/*

Emulate the KBC Poker 3 keyboard layout on a standard keyboard by remapping the
Caps_Lock as the Poker 3 Fn key. This needs to be run as root and it's probably
a good idea to disable the regular function of the Caps_Lock key as well.

License: WTFPL
*/

package main

import (
"fmt"
"github.com/gvalkov/golang-evdev"
"github.com/ben-bensdevzone/uinput"
"os"
"syscall"
)

// Declare a global variable for whether or not caps lock is being held down.
var caps_on bool

// Use syscall to pass ioctl commands.


func ioctl(fd, cmd, ptr uintptr) error {

// I stole this from somewhere on github, and it seems to work.


_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)

// Spit out an error if there is one...


if e != 0 {
return e
}

// ...otherwise return nil on success.


return nil
}

// Returns a keystroke code in a usable format.


func read_code(ev *evdev.InputEvent) uint16 {
return ev.Code
}

// Returns a keystroke value in a usable format.


func read_value(ev *evdev.InputEvent) int32 {
return ev.Value
}

// Hooray for main() functions!


func main() {

// Declare some crap we'll use later.


var dev *evdev.InputDevice
var events []evdev.InputEvent
var err error
var fd uintptr

// Use UInput to create a virtual keyboard.


vk := uinput.VKeyboard{}
vk.Create("/dev/uinput")
// If there are 2 argument vars, then we proceed doing something
constructive.
if len(os.Args) == 2 {

// Open our argv as a device and a file so we can get the file
descriptor.
dev, err = evdev.Open(os.Args[1])
file, _ := os.Open(os.Args[1])
fd = uintptr(file.Fd())

// If the device can't be opened, spit out an error and exit.


if err != nil {
fmt.Printf("unable to open input device: %s\n", os.Args[1])
os.Exit(1)
}

// If there aren't 2 argument vars, print usage into and exit.


} else {
fmt.Printf("usage: poker3 <device>\n")
os.Exit(1)
}

// Run an infinite loop.


for {

// Read the device events.


events, err = dev.Read()

// Iterate through the events.


for i := range events {

// Get the keystroke code/value in a format we can use.


code := read_code(&events[i])
value := read_value(&events[i])

// If the keystroke code is 58 (Caps_Lock), we test the value and


then
// "grab" or "ungrab" the device to prevent unwanted input.
// TODO: Debug this. On value==1 all keyboard input stops.
if code == 58 {

// "Grab" the device when Caps_Lock is pressed.


if value == 1 {
ioctl(fd, evdev.EVIOCGRAB, 1)
//ioctl(fd, evdev.EVIOCGRAB, 0) // TEMP - Use for
debugging.
caps_on = true

// "Ungrab" the device wen Caps_Lock is released.


} else if value == 0 {
ioctl(fd, evdev.EVIOCGRAB, 0)
caps_on = false
}

// On any keystroke except 58, test for caps_on a value of 1 or


2.
} else if caps_on == true && (value == 1 || value == 2) {

// If the code matches a key from the Poker3 Fn layout, use


the virtual
// keyboard to issue the appropriate keystroke.
switch code {
case 22:
vk.SendKeyPress(uinput.KEY_PAGEUP)
vk.SendKeyRelease(uinput.KEY_PAGEUP)
case 23:
vk.SendKeyPress(uinput.KEY_UP)
vk.SendKeyRelease(uinput.KEY_UP)
case 24:
vk.SendKeyPress(uinput.KEY_PAGEDOWN)
vk.SendKeyRelease(uinput.KEY_PAGEDOWN)
case 35:
vk.SendKeyPress(uinput.KEY_HOME)
vk.SendKeyRelease(uinput.KEY_HOME)
case 36:
vk.SendKeyPress(uinput.KEY_LEFT)
vk.SendKeyRelease(uinput.KEY_LEFT)
case 37:
vk.SendKeyPress(uinput.KEY_DOWN)
vk.SendKeyRelease(uinput.KEY_DOWN)
case 38:
vk.SendKeyPress(uinput.KEY_RIGHT)
vk.SendKeyRelease(uinput.KEY_RIGHT)
case 49:
vk.SendKeyPress(uinput.KEY_END)
vk.SendKeyRelease(uinput.KEY_END)
}
}
}
}
}

Вам также может понравиться