Archived
2
0

xorg refactor.

This commit is contained in:
Miroslav Šedivý
2022-09-13 21:40:40 +02:00
parent 478984e944
commit 4c1c96b163
15 changed files with 467 additions and 252 deletions

View File

@ -1,8 +1,7 @@
package xorg
/*
#cgo CFLAGS: -I/usr/local/include/
#cgo LDFLAGS: -lX11 -lXtst -lXrandr -lxcb
#cgo LDFLAGS: -lX11 -lXrandr -lXtst -lXfixes
#include "xorg.h"
*/
@ -10,6 +9,8 @@ import "C"
import (
"fmt"
"image"
"image/color"
"sync"
"time"
"unsafe"
@ -17,24 +18,44 @@ import (
"m1k1o/neko/internal/types"
)
//go:generate ./keysymdef.sh
type KbdMod uint8
const (
KbdModCapsLock KbdMod = 2
KbdModNumLock KbdMod = 16
)
var ScreenConfigurations = make(map[int]types.ScreenConfiguration)
var debounce_button = make(map[int]time.Time)
var debounce_key = make(map[uint64]time.Time)
var debounce_button = make(map[uint32]time.Time)
var debounce_key = make(map[uint32]time.Time)
var mu = sync.Mutex{}
func init() {
func GetScreenConfigurations() {
mu.Lock()
defer mu.Unlock()
C.XGetScreenConfigurations()
}
func Display(display string) {
func DisplayOpen(display string) bool {
mu.Lock()
defer mu.Unlock()
displayUnsafe := C.CString(display)
defer C.free(unsafe.Pointer(displayUnsafe))
C.XDisplaySet(displayUnsafe)
ok := C.XDisplayOpen(displayUnsafe)
return int(ok) == 1
}
func DisplayClose() {
mu.Lock()
defer mu.Unlock()
C.XDisplayClose()
}
func Move(x, y int) {
@ -44,6 +65,17 @@ func Move(x, y int) {
C.XMove(C.int(x), C.int(y))
}
func GetCursorPosition() (int, int) {
mu.Lock()
defer mu.Unlock()
var x C.int
var y C.int
C.XCursorPosition(&x, &y)
return int(x), int(y)
}
func Scroll(x, y int) {
mu.Lock()
defer mu.Unlock()
@ -51,7 +83,7 @@ func Scroll(x, y int) {
C.XScroll(C.int(x), C.int(y))
}
func ButtonDown(code int) error {
func ButtonDown(code uint32) error {
mu.Lock()
defer mu.Unlock()
@ -65,7 +97,7 @@ func ButtonDown(code int) error {
return nil
}
func KeyDown(code uint64) error {
func KeyDown(code uint32) error {
mu.Lock()
defer mu.Unlock()
@ -79,7 +111,7 @@ func KeyDown(code uint64) error {
return nil
}
func ButtonUp(code int) error {
func ButtonUp(code uint32) error {
mu.Lock()
defer mu.Unlock()
@ -93,7 +125,7 @@ func ButtonUp(code int) error {
return nil
}
func KeyUp(code uint64) error {
func KeyUp(code uint32) error {
mu.Lock()
defer mu.Unlock()
@ -108,60 +140,52 @@ func KeyUp(code uint64) error {
}
func ResetKeys() {
for code := range debounce_button {
_ = ButtonUp(code)
mu.Lock()
defer mu.Unlock()
for code := range debounce_button {
C.XButton(C.uint(code), C.int(0))
delete(debounce_button, code)
}
for code := range debounce_key {
_ = KeyUp(code)
for code := range debounce_key {
C.XKey(C.KeySym(code), C.int(0))
delete(debounce_key, code)
}
}
func CheckKeys(duration time.Duration) {
mu.Lock()
defer mu.Unlock()
t := time.Now()
for code, start := range debounce_button {
if t.Sub(start) < duration {
continue
}
_ = ButtonUp(code)
C.XButton(C.uint(code), C.int(0))
delete(debounce_button, code)
}
for code, start := range debounce_key {
if t.Sub(start) < duration {
continue
}
_ = KeyUp(code)
C.XKey(C.KeySym(code), C.int(0))
delete(debounce_key, code)
}
}
func ValidScreenSize(width int, height int, rate int) bool {
for _, size := range ScreenConfigurations {
if size.Width == width && size.Height == height {
for _, fps := range size.Rates {
if int16(rate) == fps {
return true
}
}
}
}
return false
}
func ChangeScreenSize(width int, height int, rate int) error {
func ChangeScreenSize(width int, height int, rate int16) error {
mu.Lock()
defer mu.Unlock()
for index, size := range ScreenConfigurations {
if size.Width == width && size.Height == height {
for _, fps := range size.Rates {
if int16(rate) == fps {
if rate == fps {
C.XSetScreenConfiguration(C.int(index), C.short(fps))
return nil
}
@ -169,7 +193,7 @@ func ChangeScreenSize(width int, height int, rate int) error {
}
}
return fmt.Errorf("unknown configuration")
return fmt.Errorf("unknown screen configuration %dx%d@%d", width, height, rate)
}
func GetScreenSize() *types.ScreenSize {
@ -190,11 +214,88 @@ func GetScreenSize() *types.ScreenSize {
return nil
}
func SetKeyboardModifiers(num_lock int, caps_lock int, scroll_lock int) {
func SetKeyboardModifier(mod KbdMod, active bool) {
mu.Lock()
defer mu.Unlock()
C.SetKeyboardModifiers(C.int(num_lock), C.int(caps_lock), C.int(scroll_lock))
num := C.int(0)
if active {
num = C.int(1)
}
C.XSetKeyboardModifier(C.int(mod), num)
}
func GetKeyboardModifiers() KbdMod {
mu.Lock()
defer mu.Unlock()
return KbdMod(C.XGetKeyboardModifiers())
}
func GetCursorImage() *types.CursorImage {
mu.Lock()
defer mu.Unlock()
cur := C.XGetCursorImage()
defer C.XFree(unsafe.Pointer(cur))
width := int(cur.width)
height := int(cur.height)
// Xlib stores 32-bit data in longs, even if longs are 64-bits long.
pixels := C.GoBytes(unsafe.Pointer(cur.pixels), C.int(width*height*8))
img := image.NewRGBA(image.Rect(0, 0, width, height))
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
pos := ((y * width) + x) * 8
img.SetRGBA(x, y, color.RGBA{
A: pixels[pos+3],
R: pixels[pos+2],
G: pixels[pos+1],
B: pixels[pos+0],
})
}
}
return &types.CursorImage{
Width: uint16(width),
Height: uint16(height),
Xhot: uint16(cur.xhot),
Yhot: uint16(cur.yhot),
Serial: uint64(cur.cursor_serial),
Image: img,
}
}
func GetScreenshotImage() *image.RGBA {
mu.Lock()
defer mu.Unlock()
var w, h C.int
pixelsUnsafe := C.XGetScreenshot(&w, &h)
pixels := C.GoBytes(unsafe.Pointer(pixelsUnsafe), w*h*3)
defer C.free(unsafe.Pointer(pixelsUnsafe))
width := int(w)
height := int(h)
img := image.NewRGBA(image.Rect(0, 0, width, height))
for row := 0; row < height; row++ {
for col := 0; col < width; col++ {
pos := ((row * width) + col) * 3
img.SetRGBA(col, row, color.RGBA{
R: uint8(pixels[pos]),
G: uint8(pixels[pos+1]),
B: uint8(pixels[pos+2]),
A: 0xFF,
})
}
}
return img
}
//export goCreateScreenSize
@ -207,6 +308,13 @@ func goCreateScreenSize(index C.int, width C.int, height C.int, mwidth C.int, mh
}
//export goSetScreenRates
func goSetScreenRates(index C.int, rate_index C.int, rate C.short) {
ScreenConfigurations[int(index)].Rates[int(rate_index)] = int16(rate)
func goSetScreenRates(index C.int, rate_index C.int, rateC C.short) {
rate := int16(rateC)
// filter out all irrelevant rates
if rate > 60 || (rate > 30 && rate%10 != 0) {
return
}
ScreenConfigurations[int(index)].Rates[int(rate_index)] = rate
}