From 0e09609c6737893c283c2df464293fb5ec047b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Fri, 15 Jan 2021 16:53:03 +0100 Subject: [PATCH] KeyboardLayout to KeyboardMap. --- internal/api/room/handler.go | 3 ++- internal/api/room/keyboard.go | 28 +++++++++++++++++++----- internal/desktop/xorg.go | 30 ++++++++++++++++++++++++-- internal/types/desktop.go | 8 ++++++- internal/types/event/events.go | 2 +- internal/types/message/messages.go | 12 +++++------ internal/websocket/handler/handler.go | 8 +++---- internal/websocket/handler/keyboard.go | 7 ++++-- 8 files changed, 76 insertions(+), 22 deletions(-) diff --git a/internal/api/room/handler.go b/internal/api/room/handler.go index 13d06800..3d7026f7 100644 --- a/internal/api/room/handler.go +++ b/internal/api/room/handler.go @@ -43,7 +43,8 @@ func (h *RoomHandler) Route(r chi.Router) { }) r.Route("/keyboard", func(r chi.Router) { - r.With(auth.HostsOnly).Post("/layout", h.keyboardLayoutSet) + r.Get("/map", h.keyboardMapGet) + r.With(auth.HostsOnly).Post("/map", h.keyboardMapSet) r.Get("/modifiers", h.keyboardModifiersGet) r.With(auth.HostsOnly).Post("/modifiers", h.keyboardModifiersSet) diff --git a/internal/api/room/keyboard.go b/internal/api/room/keyboard.go index f2f89e2f..1a3bf8c9 100644 --- a/internal/api/room/keyboard.go +++ b/internal/api/room/keyboard.go @@ -7,7 +7,7 @@ import ( "demodesk/neko/internal/types" ) -type KeyboardLayoutData struct { +type KeyboardMapData struct { Layout string `json:"layout"` Variant string `json:"variant"` } @@ -17,21 +17,39 @@ type KeyboardModifiersData struct { CapsLock *bool `json:"capslock"` } -func (h *RoomHandler) keyboardLayoutSet(w http.ResponseWriter, r *http.Request) { - data := &KeyboardLayoutData{} +func (h *RoomHandler) keyboardMapSet(w http.ResponseWriter, r *http.Request) { + data := &KeyboardMapData{} if !utils.HttpJsonRequest(w, r, data) { return } - err := h.desktop.SetKeyboardLayout(data.Layout, data.Variant) + err := h.desktop.SetKeyboardMap(types.KeyboardMap{ + Layout: data.Layout, + Variant: data.Variant, + }) + if err != nil{ - utils.HttpInternalServerError(w, "Unable to change keyboard layout.") + utils.HttpInternalServerError(w, "Unable to change keyboard map.") return } utils.HttpSuccess(w) } +func (h *RoomHandler) keyboardMapGet(w http.ResponseWriter, r *http.Request) { + data, err := h.desktop.GetKeyboardMap() + + if err != nil{ + utils.HttpInternalServerError(w, "Unable to get keyboard map.") + return + } + + utils.HttpSuccess(w, KeyboardMapData{ + Layout: data.Layout, + Variant: data.Variant, + }) +} + func (h *RoomHandler) keyboardModifiersSet(w http.ResponseWriter, r *http.Request) { data := &KeyboardModifiersData{} if !utils.HttpJsonRequest(w, r, data) { diff --git a/internal/desktop/xorg.go b/internal/desktop/xorg.go index 3ab84b40..6fd2c8f2 100644 --- a/internal/desktop/xorg.go +++ b/internal/desktop/xorg.go @@ -1,6 +1,7 @@ package desktop import ( + "regexp" "os/exec" "demodesk/neko/internal/types" @@ -55,13 +56,38 @@ func (manager *DesktopManagerCtx) ChangeScreenSize(width int, height int, rate i return xorg.ChangeScreenSize(width, height, rate) } -func (manager *DesktopManagerCtx) SetKeyboardLayout(layout string, variant string) error { +func (manager *DesktopManagerCtx) SetKeyboardMap(kbd types.KeyboardMap) error { // TOOD: Use native API. - cmd := exec.Command("setxkbmap", "-layout", layout, "-variant", variant) + cmd := exec.Command("setxkbmap", "-layout", kbd.Layout, "-variant", kbd.Variant) _, err := cmd.Output() return err } +func (manager *DesktopManagerCtx) GetKeyboardMap() (*types.KeyboardMap, error) { + // TOOD: Use native API. + cmd := exec.Command("setxkbmap", "-query") + res, err := cmd.Output() + if err != nil { + return nil, err + } + + kbd := types.KeyboardMap{} + + re := regexp.MustCompile(`layout:\s+(.*)\n`) + arr := re.FindStringSubmatch(string(res)) + if len(arr) > 1 { + kbd.Layout = arr[1] + } + + re = regexp.MustCompile(`variant:\s+(.*)\n`) + arr = re.FindStringSubmatch(string(res)) + if len(arr) > 1 { + kbd.Variant = arr[1] + } + + return &kbd, nil +} + func (manager *DesktopManagerCtx) SetKeyboardModifiers(mod types.KeyboardModifiers) { if mod.NumLock != nil { xorg.SetKeyboardModifier(xorg.KBD_NUM_LOCK, *mod.NumLock) diff --git a/internal/types/desktop.go b/internal/types/desktop.go index ec1af1d3..0f1e646c 100644 --- a/internal/types/desktop.go +++ b/internal/types/desktop.go @@ -26,6 +26,11 @@ type KeyboardModifiers struct { CapsLock *bool } +type KeyboardMap struct { + Layout string + Variant string +} + type DesktopManager interface { Start() Shutdown() error @@ -43,7 +48,8 @@ type DesktopManager interface { ResetKeys() ScreenConfigurations() map[int]ScreenConfiguration GetScreenSize() *ScreenSize - SetKeyboardLayout(layout string, variant string) error + SetKeyboardMap(KeyboardMap) error + GetKeyboardMap() (*KeyboardMap, error) SetKeyboardModifiers(mod KeyboardModifiers) GetKeyboardModifiers() KeyboardModifiers GetCursorImage() *CursorImage diff --git a/internal/types/event/events.go b/internal/types/event/events.go index 48a6a6f9..09593304 100644 --- a/internal/types/event/events.go +++ b/internal/types/event/events.go @@ -41,7 +41,7 @@ const ( const ( KEYBOARD_MODIFIERS = "keyboard/modifiers" - KEYBOARD_LAYOUT = "keyboard/layout" + KEYBOARD_MAP = "keyboard/map" ) const ( diff --git a/internal/types/message/messages.go b/internal/types/message/messages.go index 9102dd91..c1fd0d13 100644 --- a/internal/types/message/messages.go +++ b/internal/types/message/messages.go @@ -132,6 +132,12 @@ type ClipboardData struct { // Keyboard ///////////////////////////// +type KeyboardMap struct { + Event string `json:"event,omitempty"` + Layout string `json:"layout"` + Variant string `json:"variant"` +} + type KeyboardModifiers struct { Event string `json:"event,omitempty"` CapsLock *bool `json:"caps_lock"` @@ -139,12 +145,6 @@ type KeyboardModifiers struct { ScrollLock *bool `json:"scroll_lock"` } -type KeyboardLayout struct { - Event string `json:"event,omitempty"` - Layout string `json:"layout"` - Variant string `json:"variant"` -} - ///////////////////////////// // Cursor ///////////////////////////// diff --git a/internal/websocket/handler/handler.go b/internal/websocket/handler/handler.go index 6f8c438d..22e109bb 100644 --- a/internal/websocket/handler/handler.go +++ b/internal/websocket/handler/handler.go @@ -76,12 +76,12 @@ func (h *MessageHandlerCtx) Message(session types.Session, raw []byte) bool { }) // Keyboard Events - case event.KEYBOARD_MODIFIERS: - payload := &message.KeyboardLayout{} + case event.KEYBOARD_MAP: + payload := &message.KeyboardMap{} err = utils.Unmarshal(payload, raw, func() error { - return h.keyboardLayout(session, payload) + return h.keyboardMap(session, payload) }) - case event.KEYBOARD_LAYOUT: + case event.KEYBOARD_MODIFIERS: payload := &message.KeyboardModifiers{} err = utils.Unmarshal(payload, raw, func() error { return h.keyboardModifiers(session, payload) diff --git a/internal/websocket/handler/keyboard.go b/internal/websocket/handler/keyboard.go index 563feb6d..867b28ff 100644 --- a/internal/websocket/handler/keyboard.go +++ b/internal/websocket/handler/keyboard.go @@ -6,13 +6,16 @@ import ( ) -func (h *MessageHandlerCtx) keyboardLayout(session types.Session, payload *message.KeyboardLayout) error { +func (h *MessageHandlerCtx) keyboardMap(session types.Session, payload *message.KeyboardMap) error { if !session.IsHost() { h.logger.Debug().Str("id", session.ID()).Msg("is not the host") return nil } - return h.desktop.SetKeyboardLayout(payload.Layout, payload.Variant) + return h.desktop.SetKeyboardMap(types.KeyboardMap{ + Layout: payload.Layout, + Variant: payload.Variant, + }) } func (h *MessageHandlerCtx) keyboardModifiers(session types.Session, payload *message.KeyboardModifiers) error {