hs-term-emulator-0.1.0.0: src/System/Terminal/Emulator/KeyboardInput/KeyPressToPty.hs
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module System.Terminal.Emulator.KeyboardInput.KeyPressToPty
( keyPressToPty,
)
where
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Char (isControl)
import System.Terminal.Emulator.KeyboardInput (KeyModifiers (..), KeyPress (..), KeyboardState (..), SpecialKey (..))
keyPressToPty :: KeyboardState -> KeyPress -> ByteString
keyPressToPty KeyboardState {keyboardState_Locked = True} _ = ""
keyPressToPty _ (KeyPress_Char c modifiers)
| isControl c = error $ "Invalid Control Char for KeyPress: " ++ show c
| otherwise = keyToPty c modifiers
keyPressToPty keyboardState (KeyPress_SpecialKey specialKey modifiers) = specialKeyToPty keyboardState specialKey modifiers
keyToPty :: Char -> KeyModifiers -> ByteString
keyToPty 'a' KeyModifiers {ctrl = True} = "\1"
keyToPty 'b' KeyModifiers {ctrl = True} = "\2"
keyToPty 'c' KeyModifiers {ctrl = True} = "\3"
keyToPty 'd' KeyModifiers {ctrl = True} = "\4"
keyToPty 'e' KeyModifiers {ctrl = True} = "\5"
keyToPty 'f' KeyModifiers {ctrl = True} = "\6"
keyToPty 'r' KeyModifiers {ctrl = True} = "\18"
keyToPty char _ = charToByteString char
specialKeyToPty :: KeyboardState -> SpecialKey -> KeyModifiers -> ByteString
specialKeyToPty keyboardState specialKey KeyModifiers {alt, ctrl, shift, capsLock} =
case specialKey of
SpecialKey_Escape
| alt -> "\ESC\ESC"
| otherwise -> "\ESC"
SpecialKey_F1
| alt -> "\ESC[1;3P"
| ctrl -> "\ESC[1;5P"
| shift -> "\ESC[1;2P"
| otherwise -> "\ESCOP"
SpecialKey_F2
| alt -> "\ESC[1;3Q"
| ctrl -> "\ESC[1;5Q"
| shift -> "\ESC[1;2Q"
| otherwise -> "\ESCOQ"
SpecialKey_F3
| alt -> "\ESC[1;3R"
| ctrl -> "\ESC[1;5R"
| shift -> "\ESC[1;2R"
| otherwise -> "\ESCOR"
SpecialKey_F4
| alt -> "\ESC[1;3S"
| ctrl -> "\ESC[1;5S"
| shift -> "\ESC[1;2S"
| otherwise -> "\ESCOS"
SpecialKey_F5
| alt -> "\ESC[15;3~"
| ctrl -> "\ESC[15;5~"
| shift -> "\ESC[15;2~"
| otherwise -> "\ESC[15~"
SpecialKey_F6
| alt -> "\ESC[17;3~"
| ctrl -> "\ESC[17;5~"
| shift -> "\ESC[17;2~"
| otherwise -> "\ESC[17~"
SpecialKey_F7
| alt -> "\ESC[18;3~"
| ctrl -> "\ESC[18;5~"
| shift -> "\ESC[18;2~"
| otherwise -> "\ESC[18~"
SpecialKey_F8
| alt -> "\ESC[19;3~"
| ctrl -> "\ESC[19;5~"
| shift -> "\ESC[19;2~"
| otherwise -> "\ESC[19~"
SpecialKey_F9
| alt -> "\ESC[20;3~"
| ctrl -> "\ESC[20;5~"
| shift -> "\ESC[20;2~"
| otherwise -> "\ESC[20~"
SpecialKey_F10
| alt -> "\ESC[21;3~"
| ctrl -> "\ESC[21;5~"
| shift -> "\ESC[21;2~"
| otherwise -> "\ESC[21~"
SpecialKey_F11
| alt -> "\ESC[23;3~"
| ctrl -> "\ESC[23;5~"
| shift -> "\ESC[23;2~"
| otherwise -> "\ESC[23~"
SpecialKey_F12
| alt -> "\ESC[24;3~"
| ctrl -> "\ESC[24;5~"
| shift -> "\ESC[24;2~"
| otherwise -> "\ESC[24~"
SpecialKey_Insert -> error "TODO"
SpecialKey_Delete -> "\ESC[3~"
SpecialKey_Home -> error "TODO"
SpecialKey_End -> error "TODO"
SpecialKey_PageUp -> error "TODO"
SpecialKey_PageDown -> error "TODO"
SpecialKey_Tab -> "\t" -- TODO modifiers
SpecialKey_Enter
| alt && not shift && not ctrl && not capsLock -> "\ESC\r"
| otherwise -> "\r"
SpecialKey_Backspace
| alt && shift -> "\ESC\b"
| alt && ctrl -> "\ESC\b"
| alt -> "\ESC\DEL"
| shift -> "\b"
| ctrl -> "\b"
| capsLock -> "\b"
| otherwise -> "\DEL"
SpecialKey_ArrowLeft
| keyboardState_DECCKM keyboardState -> "\ESCOD"
| otherwise -> "\ESC[D"
SpecialKey_ArrowRight
| keyboardState_DECCKM keyboardState -> "\ESCOC"
| otherwise -> "\ESC[C"
SpecialKey_ArrowUp
| keyboardState_DECCKM keyboardState -> "\ESCOA"
| otherwise -> "\ESC[A"
SpecialKey_ArrowDown
| keyboardState_DECCKM keyboardState -> "\ESCOB"
| otherwise -> "\ESC[B"
charToByteString :: Char -> ByteString
charToByteString =
-- TODO Encode as UTF-8
B.singleton . fromIntegral . fromEnum