diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index 23620046..ee5cac45 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -32,6 +32,12 @@ func New(config *config.Remote) *RemoteManager { emmiter: events.New(), config: config, streaming: false, + + keyboardModifierState: { + CapsLock: false, + NumLock: false, + ScrollLock: false, + } } } @@ -219,4 +225,8 @@ func (manager *RemoteManager) GetScreenSize() *types.ScreenSize { func (manager *RemoteManager) SetKeyboard(layout string) { xorg.SetKeyboard(layout) -} \ No newline at end of file +} + +func (manager *RemoteManager) SetKeyboard(NumLock int, CapsLock int, ScrollLock int) { + xorg.SetKeyboardModifiers(NumLock, CapsLock, ScrollLock) +} diff --git a/server/internal/types/remote.go b/server/internal/types/remote.go index 4b6453be..2a76392c 100644 --- a/server/internal/types/remote.go +++ b/server/internal/types/remote.go @@ -23,4 +23,5 @@ type RemoteManager interface { WriteClipboard(data string) ResetKeys() SetKeyboard(layout string) + SetKeyboard(NumLock int, CapsLock int, ScrollLock int) } diff --git a/server/internal/websocket/control.go b/server/internal/websocket/control.go index 447f4cf1..bdab4503 100644 --- a/server/internal/websocket/control.go +++ b/server/internal/websocket/control.go @@ -116,11 +116,6 @@ func (h *MessageHandler) controlClipboard(id string, session types.Session, payl return nil } -// TODO: Refactor -var CapsLock = false -var NumLock = false -var ScrollLock = false - func (h *MessageHandler) controlKeyboard(id string, session types.Session, payload *message.Keyboard) error { // check if session is host if !h.sessions.IsHost(id) { @@ -134,28 +129,29 @@ func (h *MessageHandler) controlKeyboard(id string, session types.Session, paylo } // set caps lock - if payload.CapsLock != nil && *payload.CapsLock != CapsLock { - h.remote.KeyDown(0xffe5) - h.remote.KeyUp(0xffe5) - - CapsLock = *payload.CapsLock + var CapsLock = 0 + if payload.CapsLock == nil { + CapsLock = -1 + } else if *payload.CapsLock { + CapsLock = 1 } // set num lock - if payload.NumLock != nil && *payload.NumLock != NumLock { - h.remote.KeyDown(0xff7f) - h.remote.KeyUp(0xff7f) - - NumLock = *payload.NumLock + var NumLock = 0 + if payload.NumLock == nil { + NumLock = -1 + } else if *payload.NumLock { + NumLock = 1 } // set scroll lock - if payload.ScrollLock != nil && *payload.ScrollLock != ScrollLock { - h.remote.KeyDown(0xff14) - h.remote.KeyUp(0xff14) - - ScrollLock = *payload.ScrollLock + var ScrollLock = 0 + if payload.ScrollLock == nil { + ScrollLock = -1 + } else if *payload.ScrollLock { + ScrollLock = 1 } + h.remote.SetKeyboardModifiers(CapsLock, NumLock, ScrollLock) return nil } diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 3868f5d2..2801f626 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -172,3 +172,35 @@ void SetKeyboard(char *layout) { strncat(cmd, layout, 2); system(cmd); } + +void SetKeyboardModifiers(int num_lock, int caps_lock, int scroll_lock) { + // TOOD: refactor, use native API. + // https://stackoverflow.com/questions/8427817/how-to-get-a-num-lock-state-using-c-c/8429021 + Display *display = getXDisplay(); + XKeyboardState x; + XGetKeyboardControl(display, &x); + + // set caps lock + //printf("CapsLock is %s\n", (x.led_mask & 1) ? "On" : "Off"); + if(caps_lock != -1 && x.led_mask & 1 != caps_lock) { + XKey(0xffe5, 1); + XKey(0xffe5, 0); + } + + // set num lock + //printf("NumLock is %s\n", (x.led_mask & 2) ? "On" : "Off"); + if(num_lock != -1 && x.led_mask & 2 != num_lock) { + XKey(0xff7f, 1); + XKey(0xff7f, 0); + } + + /* NOT SUPPORTED + // set scroll lock + //printf("ScrollLock is %s\n", (x.led_mask & 4) ? "On" : "Off"); + if(scroll_lock != -1 && x.led_mask & 4 != scroll_lock) { + XKey(0xff14, 1); + XKey(0xff14, 0); + } + */ +} + diff --git a/server/internal/xorg/xorg.go b/server/internal/xorg/xorg.go index 200294cc..ae96629d 100644 --- a/server/internal/xorg/xorg.go +++ b/server/internal/xorg/xorg.go @@ -225,6 +225,13 @@ func SetKeyboard(layout string) { C.SetKeyboard(layoutUnsafe) } +func SetKeyboardModifiers(num_lock int, caps_lock int, scroll_lock int) { + mu.Lock() + defer mu.Unlock() + + C.SetKeyboardModifiers(C.int(num_lock), C.int(caps_lock), C.int(scroll_lock)) +} + //export goCreateScreenSize func goCreateScreenSize(index C.int, width C.int, height C.int, mwidth C.int, mheight C.int) { ScreenConfigurations[int(index)] = types.ScreenConfiguration{ diff --git a/server/internal/xorg/xorg.h b/server/internal/xorg/xorg.h index 24384c48..fabaf15a 100644 --- a/server/internal/xorg/xorg.h +++ b/server/internal/xorg/xorg.h @@ -40,5 +40,6 @@ void XDisplaySet(char *input); void SetKeyboard(char *layout); + void SetKeyboardModifiers(int num_lock, int caps_lock, int scroll_lock); #endif