1 // Copyright 2022 The TCell Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tcell 16 17 // Screen represents the physical (or emulated) screen. 18 // This can be a terminal window or a physical console. Platforms implement 19 // this differently. 20 type Screen interface { 21 // Init initializes the screen for use. 22 Init() error 23 24 // Fini finalizes the screen also releasing resources. 25 Fini() 26 27 // Clear logically erases the screen. 28 // This is effectively a short-cut for Fill(' ', StyleDefault). 29 Clear() 30 31 // Fill fills the screen with the given character and style. 32 // The effect of filling the screen is not visible until Show 33 // is called (or Sync). 34 Fill(rune, Style) 35 36 // SetCell is an older API, and will be removed. Please use 37 // SetContent instead; SetCell is implemented in terms of SetContent. 38 SetCell(x int, y int, style Style, ch ...rune) 39 40 // GetContent returns the contents at the given location. If the 41 // coordinates are out of range, then the values will be 0, nil, 42 // StyleDefault. Note that the contents returned are logical contents 43 // and may not actually be what is displayed, but rather are what will 44 // be displayed if Show() or Sync() is called. The width is the width 45 // in screen cells; most often this will be 1, but some East Asian 46 // characters and emoji require two cells. 47 GetContent(x, y int) (primary rune, combining []rune, style Style, width int) 48 49 // SetContent sets the contents of the given cell location. If 50 // the coordinates are out of range, then the operation is ignored. 51 // 52 // The first rune is the primary non-zero width rune. The array 53 // that follows is a possible list of combining characters to append, 54 // and will usually be nil (no combining characters.) 55 // 56 // The results are not displayed until Show() or Sync() is called. 57 // 58 // Note that wide (East Asian full width and emoji) runes occupy two cells, 59 // and attempts to place character at next cell to the right will have 60 // undefined effects. Wide runes that are printed in the 61 // last column will be replaced with a single width space on output. 62 SetContent(x int, y int, primary rune, combining []rune, style Style) 63 64 // SetStyle sets the default style to use when clearing the screen 65 // or when StyleDefault is specified. If it is also StyleDefault, 66 // then whatever system/terminal default is relevant will be used. 67 SetStyle(style Style) 68 69 // ShowCursor is used to display the cursor at a given location. 70 // If the coordinates -1, -1 are given or are otherwise outside the 71 // dimensions of the screen, the cursor will be hidden. 72 ShowCursor(x int, y int) 73 74 // HideCursor is used to hide the cursor. It's an alias for 75 // ShowCursor(-1, -1).sim 76 HideCursor() 77 78 // SetCursorStyle is used to set the cursor style. If the style 79 // is not supported (or cursor styles are not supported at all), 80 // then this will have no effect. 81 SetCursorStyle(CursorStyle) 82 83 // Size returns the screen size as width, height. This changes in 84 // response to a call to Clear or Flush. 85 Size() (width, height int) 86 87 // ChannelEvents is an infinite loop that waits for an event and 88 // channels it into the user provided channel ch. Closing the 89 // quit channel and calling the Fini method are cancellation 90 // signals. When a cancellation signal is received the method 91 // returns after closing ch. 92 // 93 // This method should be used as a goroutine. 94 // 95 // NOTE: PollEvent should not be called while this method is running. 96 ChannelEvents(ch chan<- Event, quit <-chan struct{}) 97 98 // PollEvent waits for events to arrive. Main application loops 99 // must spin on this to prevent the application from stalling. 100 // Furthermore, this will return nil if the Screen is finalized. 101 PollEvent() Event 102 103 // HasPendingEvent returns true if PollEvent would return an event 104 // without blocking. If the screen is stopped and PollEvent would 105 // return nil, then the return value from this function is unspecified. 106 // The purpose of this function is to allow multiple events to be collected 107 // at once, to minimize screen redraws. 108 HasPendingEvent() bool 109 110 // PostEvent tries to post an event into the event stream. This 111 // can fail if the event queue is full. In that case, the event 112 // is dropped, and ErrEventQFull is returned. 113 PostEvent(ev Event) error 114 115 // Deprecated: PostEventWait is unsafe, and will be removed 116 // in the future. 117 // 118 // PostEventWait is like PostEvent, but if the queue is full, it 119 // blocks until there is space in the queue, making delivery 120 // reliable. However, it is VERY important that this function 121 // never be called from within whatever event loop is polling 122 // with PollEvent(), otherwise a deadlock may arise. 123 // 124 // For this reason, when using this function, the use of a 125 // Goroutine is recommended to ensure no deadlock can occur. 126 PostEventWait(ev Event) 127 128 // EnableMouse enables the mouse. (If your terminal supports it.) 129 // If no flags are specified, then all events are reported, if the 130 // terminal supports them. 131 EnableMouse(...MouseFlags) 132 133 // DisableMouse disables the mouse. 134 DisableMouse() 135 136 // EnablePaste enables bracketed paste mode, if supported. 137 EnablePaste() 138 139 // DisablePaste disables bracketed paste mode. 140 DisablePaste() 141 142 // HasMouse returns true if the terminal (apparently) supports a 143 // mouse. Note that the return value of true doesn't guarantee that 144 // a mouse/pointing device is present; a false return definitely 145 // indicates no mouse support is available. 146 HasMouse() bool 147 148 // Colors returns the number of colors. All colors are assumed to 149 // use the ANSI color map. If a terminal is monochrome, it will 150 // return 0. 151 Colors() int 152 153 // Show makes all the content changes made using SetContent() visible 154 // on the display. 155 // 156 // It does so in the most efficient and least visually disruptive 157 // manner possible. 158 Show() 159 160 // Sync works like Show(), but it updates every visible cell on the 161 // physical display, assuming that it is not synchronized with any 162 // internal model. This may be both expensive and visually jarring, 163 // so it should only be used when believed to actually be necessary. 164 // 165 // Typically, this is called as a result of a user-requested redraw 166 // (e.g. to clear up on-screen corruption caused by some other program), 167 // or during a resize event. 168 Sync() 169 170 // CharacterSet returns information about the character set. 171 // This isn't the full locale, but it does give us the input/output 172 // character set. Note that this is just for diagnostic purposes, 173 // we normally translate input/output to/from UTF-8, regardless of 174 // what the user's environment is. 175 CharacterSet() string 176 177 // RegisterRuneFallback adds a fallback for runes that are not 178 // part of the character set -- for example one could register 179 // o as a fallback for ΓΈ. This should be done cautiously for 180 // characters that might be displayed ordinarily in language 181 // specific text -- characters that could change the meaning of 182 // written text would be dangerous. The intention here is to 183 // facilitate fallback characters in pseudo-graphical applications. 184 // 185 // If the terminal has fallbacks already in place via an alternate 186 // character set, those are used in preference. Also, standard 187 // fallbacks for graphical characters in the alternate character set 188 // terminfo string are registered implicitly. 189 // 190 // The display string should be the same width as original rune. 191 // This makes it possible to register two character replacements 192 // for full width East Asian characters, for example. 193 // 194 // It is recommended that replacement strings consist only of 195 // 7-bit ASCII, since other characters may not display everywhere. 196 RegisterRuneFallback(r rune, subst string) 197 198 // UnregisterRuneFallback unmaps a replacement. It will unmap 199 // the implicit ASCII replacements for alternate characters as well. 200 // When an unmapped char needs to be displayed, but no suitable 201 // glyph is available, '?' is emitted instead. It is not possible 202 // to "disable" the use of alternate characters that are supported 203 // by your terminal except by changing the terminal database. 204 UnregisterRuneFallback(r rune) 205 206 // CanDisplay returns true if the given rune can be displayed on 207 // this screen. Note that this is a best-guess effort -- whether 208 // your fonts support the character or not may be questionable. 209 // Mostly this is for folks who work outside of Unicode. 210 // 211 // If checkFallbacks is true, then if any (possibly imperfect) 212 // fallbacks are registered, this will return true. This will 213 // also return true if the terminal can replace the glyph with 214 // one that is visually indistinguishable from the one requested. 215 CanDisplay(r rune, checkFallbacks bool) bool 216 217 // Resize does nothing, since it's generally not possible to 218 // ask a screen to resize, but it allows the Screen to implement 219 // the View interface. 220 Resize(int, int, int, int) 221 222 // HasKey returns true if the keyboard is believed to have the 223 // key. In some cases a keyboard may have keys with this name 224 // but no support for them, while in others a key may be reported 225 // as supported but not actually be usable (such as some emulators 226 // that hijack certain keys). Its best not to depend to strictly 227 // on this function, but it can be used for hinting when building 228 // menus, displayed hot-keys, etc. Note that KeyRune (literal 229 // runes) is always true. 230 HasKey(Key) bool 231 232 // Suspend pauses input and output processing. It also restores the 233 // terminal settings to what they were when the application started. 234 // This can be used to, for example, run a sub-shell. 235 Suspend() error 236 237 // Resume resumes after Suspend(). 238 Resume() error 239 240 // Beep attempts to sound an OS-dependent audible alert and returns an error 241 // when unsuccessful. 242 Beep() error 243 244 // SetSize attempts to resize the window. It also invalidates the cells and 245 // calls the resize function. Note that if the window size is changed, it will 246 // not be restored upon application exit. 247 // 248 // Many terminals cannot support this. Perversely, the "modern" Windows Terminal 249 // does not support application-initiated resizing, whereas the legacy terminal does. 250 // Also, some emulators can support this but may have it disabled by default. 251 SetSize(int, int) 252 } 253 254 // NewScreen returns a default Screen suitable for the user's terminal 255 // environment. 256 func NewScreen() (Screen, error) { 257 // Windows is happier if we try for a console screen first. 258 if s, _ := NewConsoleScreen(); s != nil { 259 return s, nil 260 } else if s, e := NewTerminfoScreen(); s != nil { 261 return s, nil 262 } else { 263 return nil, e 264 } 265 } 266 267 // MouseFlags are options to modify the handling of mouse events. 268 // Actual events can be ORed together. 269 type MouseFlags int 270 271 const ( 272 MouseButtonEvents = MouseFlags(1) // Click events only 273 MouseDragEvents = MouseFlags(2) // Click-drag events (includes button events) 274 MouseMotionEvents = MouseFlags(4) // All mouse events (includes click and drag events) 275 ) 276 277 // CursorStyle represents a given cursor style, which can include the shape and 278 // whether the cursor blinks or is solid. Support for changing this is not universal. 279 type CursorStyle int 280 281 const ( 282 CursorStyleDefault = CursorStyle(iota) // The default 283 CursorStyleBlinkingBlock 284 CursorStyleSteadyBlock 285 CursorStyleBlinkingUnderline 286 CursorStyleSteadyUnderline 287 CursorStyleBlinkingBar 288 CursorStyleSteadyBar 289 ) 290