xorg refactor.
This commit is contained in:
@ -1,97 +1,35 @@
|
||||
#include "xorg.h"
|
||||
|
||||
static Display *DISPLAY = NULL;
|
||||
static char *NAME = ":0.0";
|
||||
static int REGISTERED = 0;
|
||||
static int DIRTY = 0;
|
||||
|
||||
xkeys_t *xKeysHead = NULL;
|
||||
|
||||
void XKeysInsert(KeySym keysym, KeyCode keycode) {
|
||||
xkeys_t *node = (xkeys_t *) malloc(sizeof(xkeys_t));
|
||||
|
||||
node->keysym = keysym;
|
||||
node->keycode = keycode;
|
||||
node->next = xKeysHead;
|
||||
xKeysHead = node;
|
||||
}
|
||||
|
||||
KeyCode XKeysPop(KeySym keysym) {
|
||||
KeyCode keycode = 0;
|
||||
xkeys_t *node = xKeysHead,
|
||||
*previous = NULL;
|
||||
int i = 0;
|
||||
|
||||
while (node) {
|
||||
if (node->keysym == keysym) {
|
||||
keycode = node->keycode;
|
||||
|
||||
if (!previous)
|
||||
xKeysHead = node->next;
|
||||
else
|
||||
previous->next = node->next;
|
||||
|
||||
free(node);
|
||||
return keycode;
|
||||
}
|
||||
|
||||
previous = node;
|
||||
node = node->next;
|
||||
if (i++ > 120) {
|
||||
// this should NEVER HAPPEN
|
||||
fprintf(stderr, "[FATAL-ERROR] XKeysPop() in xorg.c: reached maximum loop limit! Something is wrong\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Display *getXDisplay(void) {
|
||||
/* Close the display if displayName has changed */
|
||||
if (DIRTY) {
|
||||
XDisplayClose();
|
||||
DIRTY = 0;
|
||||
}
|
||||
|
||||
if (DISPLAY == NULL) {
|
||||
/* First try the user set displayName */
|
||||
DISPLAY = XOpenDisplay(NAME);
|
||||
|
||||
/* Then try using environment variable DISPLAY */
|
||||
if (DISPLAY == NULL) {
|
||||
DISPLAY = XOpenDisplay(NULL);
|
||||
}
|
||||
|
||||
if (DISPLAY == NULL) {
|
||||
fprintf(stderr, "[FATAL-ERROR] XKeysPop() in xorg.c: Could not open main display!");
|
||||
} else if (!REGISTERED) {
|
||||
atexit(&XDisplayClose);
|
||||
REGISTERED = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return DISPLAY;
|
||||
}
|
||||
|
||||
void XDisplayClose(void) {
|
||||
if (DISPLAY != NULL) {
|
||||
XCloseDisplay(DISPLAY);
|
||||
DISPLAY = NULL;
|
||||
}
|
||||
int XDisplayOpen(char *name) {
|
||||
DISPLAY = XOpenDisplay(name);
|
||||
return DISPLAY == NULL;
|
||||
}
|
||||
|
||||
void XDisplaySet(char *input) {
|
||||
NAME = strdup(input);
|
||||
DIRTY = 1;
|
||||
void XDisplayClose(void) {
|
||||
XCloseDisplay(DISPLAY);
|
||||
}
|
||||
|
||||
void XMove(int x, int y) {
|
||||
Display *display = getXDisplay();
|
||||
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, x, y);
|
||||
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, x, y);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void XCursorPosition(int *x, int *y) {
|
||||
Display *display = getXDisplay();
|
||||
Window root = DefaultRootWindow(display);
|
||||
Window window;
|
||||
int i;
|
||||
unsigned mask;
|
||||
XQueryPointer(display, root, &root, &window, x, y, &i, &i, &mask);
|
||||
}
|
||||
|
||||
void XScroll(int x, int y) {
|
||||
int ydir = 4; /* Button 4 is up, 5 is down. */
|
||||
int xdir = 6;
|
||||
@ -123,15 +61,55 @@ void XScroll(int x, int y) {
|
||||
}
|
||||
|
||||
void XButton(unsigned int button, int down) {
|
||||
if (button != 0) {
|
||||
Display *display = getXDisplay();
|
||||
XTestFakeButtonEvent(display, button, down, CurrentTime);
|
||||
XSync(display, 0);
|
||||
}
|
||||
if (button == 0)
|
||||
return;
|
||||
|
||||
Display *display = getXDisplay();
|
||||
XTestFakeButtonEvent(display, button, down, CurrentTime);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
// From: https://github.com/TigerVNC/tigervnc/blob/0946e298075f8f7b6d63e552297a787c5f84d27c/unix/x0vncserver/XDesktop.cxx#L343-L379
|
||||
KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) {
|
||||
static xkeyentry_t *xKeysHead = NULL;
|
||||
|
||||
void XKeyEntryAdd(KeySym keysym, KeyCode keycode) {
|
||||
xkeyentry_t *entry = (xkeyentry_t *) malloc(sizeof(xkeyentry_t));
|
||||
if (entry == NULL)
|
||||
return;
|
||||
|
||||
entry->keysym = keysym;
|
||||
entry->keycode = keycode;
|
||||
entry->next = xKeysHead;
|
||||
xKeysHead = entry;
|
||||
}
|
||||
|
||||
KeyCode XKeyEntryGet(KeySym keysym) {
|
||||
xkeyentry_t *prev = NULL;
|
||||
xkeyentry_t *curr = xKeysHead;
|
||||
|
||||
KeyCode keycode = 0;
|
||||
while (curr != NULL) {
|
||||
if (curr->keysym == keysym) {
|
||||
keycode = curr->keycode;
|
||||
|
||||
if (prev == NULL) {
|
||||
xKeysHead = curr->next;
|
||||
} else {
|
||||
prev->next = curr->next;
|
||||
}
|
||||
|
||||
free(curr);
|
||||
return keycode;
|
||||
}
|
||||
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// From https://github.com/TigerVNC/tigervnc/blob/0946e298075f8f7b6d63e552297a787c5f84d27c/unix/x0vncserver/XDesktop.cxx#L343-L379
|
||||
KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym) {
|
||||
XkbDescPtr xkb;
|
||||
XkbStateRec state;
|
||||
unsigned int mods;
|
||||
@ -169,51 +147,52 @@ KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) {
|
||||
return keycode;
|
||||
}
|
||||
|
||||
void XKey(KeySym key, int down) {
|
||||
void XKey(KeySym keysym, int down) {
|
||||
if (keysym == 0)
|
||||
return;
|
||||
|
||||
Display *display = getXDisplay();
|
||||
KeyCode code = 0;
|
||||
KeyCode keycode = 0;
|
||||
|
||||
if (!down)
|
||||
code = XKeysPop(key);
|
||||
keycode = XKeyEntryGet(keysym);
|
||||
|
||||
if (!code)
|
||||
code = XkbKeysymToKeycode(display, key);
|
||||
if (keycode == 0)
|
||||
keycode = XkbKeysymToKeycode(display, keysym);
|
||||
|
||||
if (!code) {
|
||||
// Map non-existing keysyms to new keycodes
|
||||
if (keycode == 0) {
|
||||
int min, max, numcodes;
|
||||
XDisplayKeycodes(display, &min, &max);
|
||||
XGetKeyboardMapping(display, min, max-min, &numcodes);
|
||||
|
||||
code = (max-min+1)*numcodes;
|
||||
keycode = (max-min+1)*numcodes;
|
||||
KeySym keysym_list[numcodes];
|
||||
for (int i=0;i<numcodes;i++) keysym_list[i] = key;
|
||||
XChangeKeyboardMapping(display, code, numcodes, keysym_list, 1);
|
||||
for(int i=0;i<numcodes;i++) keysym_list[i] = keysym;
|
||||
XChangeKeyboardMapping(display, keycode, numcodes, keysym_list, 1);
|
||||
}
|
||||
|
||||
if (!code)
|
||||
return;
|
||||
|
||||
if (down)
|
||||
XKeysInsert(key, code);
|
||||
XKeyEntryAdd(keysym, keycode);
|
||||
|
||||
XTestFakeKeyEvent(display, code, down, CurrentTime);
|
||||
XTestFakeKeyEvent(display, keycode, down, CurrentTime);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void XGetScreenConfigurations() {
|
||||
Display *display = getXDisplay();
|
||||
Window root = RootWindow(display, 0);
|
||||
Display *display = getXDisplay();
|
||||
Window root = RootWindow(display, 0);
|
||||
XRRScreenSize *xrrs;
|
||||
int num_sizes;
|
||||
int num_sizes;
|
||||
|
||||
xrrs = XRRSizes(display, 0, &num_sizes);
|
||||
for(int i = 0; i < num_sizes; i ++) {
|
||||
for (int i = 0; i < num_sizes; i++) {
|
||||
short *rates;
|
||||
int num_rates;
|
||||
int num_rates;
|
||||
|
||||
goCreateScreenSize(i, xrrs[i].width, xrrs[i].height, xrrs[i].mwidth, xrrs[i].mheight);
|
||||
rates = XRRRates(display, 0, i, &num_rates);
|
||||
for (int j = 0; j < num_rates; j ++) {
|
||||
for (int j = 0; j < num_rates; j++) {
|
||||
goSetScreenRates(i, j, rates[j]);
|
||||
}
|
||||
}
|
||||
@ -227,34 +206,61 @@ void XSetScreenConfiguration(int index, short rate) {
|
||||
|
||||
int XGetScreenSize() {
|
||||
Display *display = getXDisplay();
|
||||
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, RootWindow(display, 0));
|
||||
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, RootWindow(display, 0));
|
||||
Rotation original_rotation;
|
||||
return XRRConfigCurrentConfiguration(conf, &original_rotation);
|
||||
}
|
||||
|
||||
short XGetScreenRate() {
|
||||
Display *display = getXDisplay();
|
||||
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, RootWindow(display, 0));
|
||||
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, RootWindow(display, 0));
|
||||
return XRRConfigCurrentRate(conf);
|
||||
}
|
||||
|
||||
void SetKeyboardModifiers(int num_lock, int caps_lock, int scroll_lock) {
|
||||
void XSetKeyboardModifier(int mod, int on) {
|
||||
Display *display = getXDisplay();
|
||||
|
||||
if (num_lock != -1) {
|
||||
XkbLockModifiers(display, XkbUseCoreKbd, 16, num_lock * 16);
|
||||
}
|
||||
|
||||
if (caps_lock != -1) {
|
||||
XkbLockModifiers(display, XkbUseCoreKbd, 2, caps_lock * 2);
|
||||
}
|
||||
|
||||
if (scroll_lock != -1) {
|
||||
XKeyboardControl values;
|
||||
values.led_mode = scroll_lock ? LedModeOn : LedModeOff;
|
||||
values.led = 3;
|
||||
XChangeKeyboardControl(display, KBLedMode, &values);
|
||||
}
|
||||
|
||||
XkbLockModifiers(display, XkbUseCoreKbd, mod, on ? mod : 0);
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
char XGetKeyboardModifiers() {
|
||||
XkbStateRec xkbState;
|
||||
Display *display = getXDisplay();
|
||||
XkbGetState(display, XkbUseCoreKbd, &xkbState);
|
||||
return xkbState.locked_mods;
|
||||
}
|
||||
|
||||
XFixesCursorImage *XGetCursorImage(void) {
|
||||
Display *display = getXDisplay();
|
||||
return XFixesGetCursorImage(display);
|
||||
}
|
||||
|
||||
char *XGetScreenshot(int *w, int *h) {
|
||||
Display *display = getXDisplay();
|
||||
Window root = DefaultRootWindow(display);
|
||||
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(display, root, &attr);
|
||||
int width = attr.width;
|
||||
int height = attr.height;
|
||||
|
||||
XImage *ximage = XGetImage(display, root, 0, 0, width, height, AllPlanes, ZPixmap);
|
||||
|
||||
*w = width;
|
||||
*h = height;
|
||||
char *pixels = (char *)malloc(width * height * 3);
|
||||
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
int pos = ((row * width) + col) * 3;
|
||||
unsigned long pixel = XGetPixel(ximage, col, row);
|
||||
|
||||
pixels[pos] = (pixel & ximage->red_mask) >> 16;
|
||||
pixels[pos+1] = (pixel & ximage->green_mask) >> 8;
|
||||
pixels[pos+2] = pixel & ximage->blue_mask;
|
||||
}
|
||||
}
|
||||
|
||||
XDestroyImage(ximage);
|
||||
return pixels;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,39 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/extensions/XTest.h>
|
||||
#include <stdlib.h> /* For free() */
|
||||
#include <stdio.h> /* For fputs() */
|
||||
#include <string.h> /* For strdup() */
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight);
|
||||
extern void goSetScreenRates(int index, int rate_index, short rate);
|
||||
|
||||
typedef struct xkeys_t {
|
||||
KeySym keysym;
|
||||
KeyCode keycode;
|
||||
struct xkeys_t *next;
|
||||
} xkeys_t;
|
||||
|
||||
/* Returns the main display, closed either on exit or when closeMainDisplay()
|
||||
* is invoked. This removes a bit of the overhead of calling XOpenDisplay() &
|
||||
* XCloseDisplay() everytime the main display needs to be used.
|
||||
*
|
||||
* Note that this is almost certainly not thread safe. */
|
||||
Display *getXDisplay(void);
|
||||
int XDisplayOpen(char *input);
|
||||
void XDisplayClose(void);
|
||||
|
||||
void XMove(int x, int y);
|
||||
void XCursorPosition(int *x, int *y);
|
||||
void XScroll(int x, int y);
|
||||
void XButton(unsigned int button, int down);
|
||||
void XKey(unsigned long key, int down);
|
||||
|
||||
typedef struct xkeyentry_t {
|
||||
KeySym keysym;
|
||||
KeyCode keycode;
|
||||
struct xkeyentry_t *next;
|
||||
} xkeyentry_t;
|
||||
|
||||
static void XKeyEntryAdd(KeySym keysym, KeyCode keycode);
|
||||
static KeyCode XKeyEntryGet(KeySym keysym);
|
||||
static KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym);
|
||||
void XKey(KeySym keysym, int down);
|
||||
|
||||
void XGetScreenConfigurations();
|
||||
void XSetScreenConfiguration(int index, short rate);
|
||||
int XGetScreenSize();
|
||||
short XGetScreenRate();
|
||||
|
||||
void XDisplayClose(void);
|
||||
void XDisplaySet(char *input);
|
||||
void XSetKeyboardModifier(int mod, int on);
|
||||
char XGetKeyboardModifiers();
|
||||
XFixesCursorImage *XGetCursorImage(void);
|
||||
|
||||
void SetKeyboardModifiers(int num_lock, int caps_lock, int scroll_lock);
|
||||
char *XGetScreenshot(int *w, int *h);
|
||||
|
Reference in New Issue
Block a user