refactor xorg race condition.

This commit is contained in:
Miroslav Šedivý 2020-11-04 00:09:52 +01:00
parent 51c6e0091f
commit b0ae758d7b
4 changed files with 32 additions and 48 deletions

View File

@ -3,6 +3,7 @@ package desktop
import ( import (
"time" "time"
"github.com/kataras/go-events"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -26,10 +27,15 @@ func New(display string) *DesktopManagerCtx {
} }
func (manager *DesktopManagerCtx) Start() { func (manager *DesktopManagerCtx) Start() {
xorg.Display(manager.display) if err := xorg.DisplayOpen(manager.display); err != nil {
manager.logger.Warn().Err(err).Msg("unable to open dispaly")
}
xorg.GetScreenConfigurations()
go func() { go func() {
defer func() { defer func() {
xorg.DisplayClose()
manager.logger.Info().Msg("shutdown") manager.logger.Info().Msg("shutdown")
}() }()

View File

@ -1,47 +1,18 @@
#include "xorg.h" #include "xorg.h"
static Display *DISPLAY = NULL; static Display *DISPLAY = NULL;
static char *NAME = ":0.0";
static int REGISTERED = 0;
static int DIRTY = 0;
Display *getXDisplay(void) { 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) {
fputs("Could not open main display\n", stderr);
} else if (!REGISTERED) {
atexit(&XDisplayClose);
REGISTERED = 1;
}
}
return DISPLAY; return DISPLAY;
} }
void XDisplayClose(void) { int XDisplayOpen(char *name) {
if (DISPLAY != NULL) { DISPLAY = XOpenDisplay(name);
XCloseDisplay(DISPLAY); return DISPLAY == NULL;
DISPLAY = NULL;
}
} }
void XDisplaySet(char *input) { void XDisplayClose(void) {
NAME = strdup(input); XCloseDisplay(DISPLAY);
DIRTY = 1;
} }
void XMove(int x, int y) { void XMove(int x, int y) {

View File

@ -24,18 +24,32 @@ var debounce_button = make(map[int]time.Time)
var debounce_key = make(map[uint64]time.Time) var debounce_key = make(map[uint64]time.Time)
var mu = sync.Mutex{} var mu = sync.Mutex{}
func init() { func GetScreenConfigurations() {
C.XGetScreenConfigurations() C.XGetScreenConfigurations()
} }
func Display(display string) { func DisplayOpen(display string) error {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
displayUnsafe := C.CString(display) displayUnsafe := C.CString(display)
defer C.free(unsafe.Pointer(displayUnsafe)) defer C.free(unsafe.Pointer(displayUnsafe))
C.XDisplaySet(displayUnsafe) var err C.int
err = C.XDisplayOpen(displayUnsafe)
if int(err) == 1 {
return fmt.Errorf("Could not open display %s.", display)
}
return nil
}
func DisplayClose() {
mu.Lock()
defer mu.Unlock()
C.XDisplayClose()
} }
func Move(x, y int) { func Move(x, y int) {

View File

@ -9,18 +9,14 @@
#include <X11/extensions/XTest.h> #include <X11/extensions/XTest.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> /* For fputs() */ #include <string.h>
#include <string.h> /* For strdup() */
extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight); extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight);
extern void goSetScreenRates(int index, int rate_index, short rate); extern void goSetScreenRates(int index, int rate_index, short rate);
/* 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); Display *getXDisplay(void);
int XDisplayOpen(char *input);
void XDisplayClose(void);
void XMove(int x, int y); void XMove(int x, int y);
void XScroll(int x, int y); void XScroll(int x, int y);
@ -32,9 +28,6 @@ void XSetScreenConfiguration(int index, short rate);
int XGetScreenSize(); int XGetScreenSize();
short XGetScreenRate(); short XGetScreenRate();
void XDisplayClose(void);
void XDisplaySet(char *input);
void SetKeyboardLayout(char *layout); void SetKeyboardLayout(char *layout);
void SetKeyboardModifiers(int num_lock, int caps_lock, int scroll_lock); void SetKeyboardModifiers(int num_lock, int caps_lock, int scroll_lock);