0 | module NCurses.Core.Input
  1 |
  2 | import NCurses.Core
  3 |
  4 | %foreign libncurses "cbreak"
  5 | prim__cBreak : PrimIO ()
  6 |
  7 | %foreign libncurses "nocbreak"
  8 | prim__noCBreak : PrimIO ()
  9 |
 10 | %foreign libncurses "echo"
 11 | prim__echo : PrimIO ()
 12 |
 13 | %foreign libncurses "noecho"
 14 | prim__noEcho : PrimIO ()
 15 |
 16 | %foreign libncurses "nodelay"
 17 | prim__noDelay : AnyPtr -> Int -> PrimIO ()
 18 |
 19 | %foreign libncurses "getch"
 20 | prim__getCh : PrimIO Char
 21 |
 22 | %foreign libncurses "wgetch"
 23 | prim__getChWindow : AnyPtr -> PrimIO Char
 24 |
 25 | %foreign libncurses "getch"
 26 | prim__safeGetCh : PrimIO Int
 27 |
 28 | %foreign libncurses "wgetch"
 29 | prim_safeGetChWindow  : AnyPtr -> PrimIO Int
 30 |
 31 | %foreign libncurses "curs_set"
 32 | prim__setCursorVisibility : Int -> PrimIO ()
 33 |
 34 | ||| Switch keyboard input to cbreak mode.
 35 | |||
 36 | ||| In cbreak mode, characters are sent to the program
 37 | ||| immediately instead of waiting for a newline to be
 38 | ||| entered. This is the opposite of how most terminals
 39 | ||| accept input by default during normal operation.
 40 | export
 41 | cBreak : HasIO io => io ()
 42 | cBreak = primIO $ prim__cBreak
 43 |
 44 | ||| Switch keyboard input out of cbreak mode.
 45 | |||
 46 | ||| In cbreak mode, characters are sent to the program
 47 | ||| immediately instead of waiting for a newline to be
 48 | ||| entered. This is the opposite of how most terminals
 49 | ||| accept input by default during normal operation.
 50 | export
 51 | noCBreak : HasIO io => io ()
 52 | noCBreak = primIO $ prim__noCBreak
 53 |
 54 | ||| Switch keyboard input to echo mode.
 55 | export
 56 | echo : HasIO io => io ()
 57 | echo = primIO $ prim__echo
 58 |
 59 | ||| Switch keyboard input to noecho mode.
 60 | export
 61 | noEcho : HasIO io => io ()
 62 | noEcho = primIO $ prim__noEcho
 63 |
 64 | ||| @noDelay'@ controls whether @getCh@ is blocking or not.
 65 | ||| When noDelay is False, @getCh@ will wait until the user types. Otherwise, @getCh@
 66 | ||| returns immediately and returns an error value. Use @safeGetCh@ with @noDelay@ on to
 67 | ||| turn those error values into @Nothing@.
 68 | export
 69 | noDelay' : HasIO io => Window -> Bool -> io ()
 70 | noDelay' (Win win) on = primIO $ prim__noDelay win (boolToInt on)
 71 |
 72 | ||| @noDelay@ controls whether @getCh@ is blocking or not.
 73 | ||| When noDelay is False, @getCh@ will wait until the user types. Otherwise, @getCh@
 74 | ||| returns immediately and returns an error value. Use @safeGetCh@ with @noDelay@ on to
 75 | ||| turn those error values into @Nothing@.
 76 | export
 77 | noDelay : HasIO io => Bool -> io ()
 78 | noDelay on = noDelay' !stdWindow on
 79 |
 80 | ||| Get a single character. 
 81 | |||
 82 | ||| If cbreak mode is on, the character is returned
 83 | ||| immediately. This contrasts with a read from
 84 | ||| the default shell `stdin` which will wait until a
 85 | ||| newline to flush its buffer and send input to a
 86 | ||| program.
 87 | export
 88 | getCh : HasIO io => io Char
 89 | getCh = primIO $ prim__getCh
 90 |
 91 | ||| Get a single character from the given window. 
 92 | |||
 93 | ||| If cbreak mode is on, the character is returned
 94 | ||| immediately. This contrasts with a read from
 95 | ||| the default shell `stdin` which will wait until a
 96 | ||| newline to flush its buffer and send input to a
 97 | ||| program.
 98 | export
 99 | getCh' : HasIO io => Window -> io Char
100 | getCh' (Win win) = primIO $ prim__getChWindow win
101 |
102 | ||| Get a single character or Nothing on error. 
103 | |||
104 | ||| If cbreak mode is on, the character is returned
105 | ||| immediately. This contrasts with a read from
106 | ||| the default shell `stdin` which will wait until a
107 | ||| newline to flush its buffer and send input to a
108 | ||| program.
109 | export
110 | safeGetCh : HasIO io => io (Maybe Char)
111 | safeGetCh = do
112 |   err <- primIO $ prim__err
113 |   ch <- primIO $ prim__safeGetCh
114 |   pure $
115 |     if ch == err
116 |        then Nothing
117 |        else Just (cast ch)
118 |
119 | ||| Get a single character from the given window or Nothing
120 | ||| on error. 
121 | |||
122 | ||| If cbreak mode is on, the character is returned
123 | ||| immediately. This contrasts with a read from
124 | ||| the default shell `stdin` which will wait until a
125 | ||| newline to flush its buffer and send input to a
126 | ||| program.
127 | export
128 | safeGetCh' : HasIO io => Window -> io (Maybe Char)
129 | safeGetCh' (Win win) = do
130 |   err <- primIO $ prim__err
131 |   ch <- primIO $ prim_safeGetChWindow win
132 |   pure $
133 |     if ch == err
134 |        then Nothing
135 |        else Just (cast ch)
136 |
137 | public export 
138 | data CursorVisibility = CInvisible | CNormal| CHighlyVisible
139 |
140 | ||| Set the visibility of the cursor.
141 | export
142 | setCursorVisibility : HasIO io => CursorVisibility -> io ()
143 | setCursorVisibility vis = primIO $ prim__setCursorVisibility $
144 |                                      case vis of
145 |                                           CInvisible     => 0
146 |                                           CNormal        => 1
147 |                                           CHighlyVisible => 2
148 |
149 |