1 /******************************************************************************* 2 3 Provides the current size of the terminal. Updates the values when 4 the size changes. 5 6 Copyright: 7 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 8 All rights reserved. 9 10 License: 11 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 12 Alternatively, this file may be distributed under the terms of the Tango 13 3-Clause BSD License (see LICENSE_BSD.txt for details). 14 15 *******************************************************************************/ 16 17 module ocean.io.Terminal; 18 19 /******************************************************************************* 20 21 C functions and structures to get terminal information 22 23 ******************************************************************************/ 24 25 import ocean.meta.types.Qualifiers; 26 27 import core.sys.posix.signal; 28 29 debug(Term) import ocean.io.Stdout; 30 31 32 private 33 { 34 static immutable TIOCGWINSZ = 0x5413; 35 static immutable SIGWINCH = 28; 36 37 /*************************************************************************** 38 39 Function to get information about the terminal, taken from the C header 40 41 ***************************************************************************/ 42 43 extern (C) int ioctl ( int d, int request, ... ); 44 45 struct winsize 46 { 47 ushort ws_row; 48 ushort ws_col; 49 ushort ws_xpixel; 50 ushort ws_ypixel; 51 } 52 } 53 54 /******************************************************************************* 55 56 Struct containing information and helpers to handle terminals 57 58 Most of the control sequences can be prefixed with a ASCII digit string 59 (referred to by 'n' from now on) representing usually how often the 60 command should be executed. 61 62 Cases where this is not the case are documented. 63 64 Example: 65 ----- 66 // Move the cursor four lines up 67 Stdout.formatln("{}4{}", Terminal.CSI, Terminal.CURSOR_UP); 68 ----- 69 70 ******************************************************************************/ 71 72 struct Terminal 73 { 74 /*************************************************************************** 75 76 Amount of columns available in the terminal 77 78 ***************************************************************************/ 79 80 public static ushort columns; 81 82 /*************************************************************************** 83 84 Amount of rows (lines) available in the terminal 85 86 ***************************************************************************/ 87 88 public static ushort rows; 89 90 /*************************************************************************** 91 92 Start Sequence 93 94 ***************************************************************************/ 95 96 public enum istring CSI = "\x1B["; 97 98 /*************************************************************************** 99 100 Colours 101 102 ***************************************************************************/ 103 104 public struct Foreground 105 { 106 public enum istring BLACK = "30m"; 107 public enum istring RED = "31m"; 108 public enum istring GREEN = "32m"; 109 public enum istring YELLOW = "33m"; 110 public enum istring BLUE = "34m"; 111 public enum istring MAGENTA = "35m"; 112 public enum istring CYAN = "36m"; 113 public enum istring WHITE = "37m"; 114 public enum istring DEFAULT_UNDERSCORE = "38m"; 115 public enum istring DEFAULT = "39m"; 116 } 117 118 public struct Background 119 { 120 public enum istring BLACK = "40m"; 121 public enum istring RED = "41m"; 122 public enum istring GREEN = "42m"; 123 public enum istring YELLOW = "43m"; 124 public enum istring BLUE = "44m"; 125 public enum istring MAGENTA = "45m"; 126 public enum istring CYAN = "46m"; 127 public enum istring WHITE = "47m"; 128 public enum istring DEFAULT = "49m"; 129 } 130 131 132 /*************************************************************************** 133 134 Colour arrays, one for foreground and one for background colours 135 Each uses the Colour enum values as index 136 137 The enum can be useful for passing to functions in order to specify 138 one of the colours defined in this module with validation 139 (as opposed to accepting a generic string). 140 141 ***************************************************************************/ 142 143 public enum Colour 144 { 145 Black, 146 Red, 147 Green, 148 Yellow, 149 Blue, 150 Magenta, 151 Cyan, 152 White, 153 Default 154 } 155 156 public static immutable(istring[]) fg_colour_codes = [ 157 Colour.Black: Foreground.BLACK, 158 Colour.Red: Foreground.RED, 159 Colour.Green: Foreground.GREEN, 160 Colour.Yellow: Foreground.YELLOW, 161 Colour.Blue: Foreground.BLUE, 162 Colour.Magenta: Foreground.MAGENTA, 163 Colour.Cyan: Foreground.CYAN, 164 Colour.White: Foreground.WHITE, 165 Colour.Default: Foreground.DEFAULT 166 ]; 167 168 public static immutable(istring[]) bg_colour_codes = [ 169 Colour.Black: Background.BLACK, 170 Colour.Red: Background.RED, 171 Colour.Green: Background.GREEN, 172 Colour.Yellow: Background.YELLOW, 173 Colour.Blue: Background.BLUE, 174 Colour.Magenta: Background.MAGENTA, 175 Colour.Cyan: Background.CYAN, 176 Colour.White: Background.WHITE, 177 Colour.Default: Background.DEFAULT 178 ]; 179 180 181 /*************************************************************************** 182 183 Bold / non-bold text. 184 185 ***************************************************************************/ 186 187 public enum istring BOLD = "1m"; 188 189 public enum istring NON_BOLD = "22m"; 190 191 /*************************************************************************** 192 193 Command for cursor up 194 195 ***************************************************************************/ 196 197 public enum istring CURSOR_UP = "A"; 198 199 /*************************************************************************** 200 201 Moves the cursor n lines up and places it at the beginning of the line 202 203 ***************************************************************************/ 204 205 public enum istring LINE_UP = "F"; 206 207 /*************************************************************************** 208 209 Command for scrolling up 210 211 ***************************************************************************/ 212 213 public enum istring SCROLL_UP = "S"; 214 215 /*************************************************************************** 216 217 Command for inserting a line 218 219 ***************************************************************************/ 220 221 public enum istring INSERT_LINE = "L"; 222 223 /*************************************************************************** 224 225 Command for erasing the rest of the line 226 227 Erases part of the line. 228 If n is zero (or missing), clear from cursor to the end of the line. 229 If n is one, clear from cursor to beginning of the line. 230 If n is two, clear entire line. Cursor position does not change. 231 232 ***************************************************************************/ 233 234 public enum istring ERASE_REST_OF_LINE = "K"; 235 236 /*************************************************************************** 237 238 Command for erasing everything below and right of the cursor 239 240 Clears part of the screen. 241 If n is zero (or missing), clear from cursor to end of screen. 242 If n is one, clear from cursor to beginning of the screen. 243 If n is two, clear entire screen (and moves cursor to upper 244 left on MS-DOS ANSI.SYS). 245 246 ***************************************************************************/ 247 248 public enum istring ERASE_REST_OF_SCREEN = "J"; 249 250 /*************************************************************************** 251 252 Command for hiding the cursor 253 254 ***************************************************************************/ 255 256 public enum istring HIDE_CURSOR = "?25l"; 257 258 /*************************************************************************** 259 260 Command for showing the cursor 261 262 ***************************************************************************/ 263 264 public enum istring SHOW_CURSOR = "?25h"; 265 266 /*************************************************************************** 267 268 Moves the cursor to column n. 269 270 ***************************************************************************/ 271 272 public enum istring HORIZONTAL_MOVE_CURSOR = "G"; 273 } 274 275 /******************************************************************************* 276 277 Static Constructor. 278 279 Registers the signal handler for window size changes and gets the size 280 the first time. 281 282 ******************************************************************************/ 283 284 static this ( ) 285 { 286 sigaction_t act; 287 with (act) 288 { 289 sa_flags = SA_SIGINFO; 290 sa_sigaction = &window_size_changed; 291 } 292 293 sigaction(SIGWINCH, &act, null); 294 window_size_changed(0, null, null); 295 296 debug(Term) Stdout.formatln("Termsize: {} {}", Terminal.rows, Terminal.columns); 297 } 298 299 /******************************************************************************* 300 301 Signal handler. 302 303 Updates TermInfo with the current terminal size 304 305 Params: 306 signal = the signal that caused the call (should always be SIGWINCH)(unused) 307 info = information about the signal (unused) 308 data = context information (unused) 309 310 *******************************************************************************/ 311 312 extern (C) private void window_size_changed ( int signal, siginfo_t* info, 313 void* data ) 314 { 315 winsize max; 316 ioctl(0, TIOCGWINSZ, &max); 317 318 Terminal.columns = max.ws_col; 319 Terminal.rows = max.ws_row; 320 }