tem_safe.c revision b6bd4f488cd95b4b547777e8a8ca2045ebb34fad
1010N/A * The contents of this file are subject to the terms of the 1010N/A * Common Development and Distribution License (the "License"). 1010N/A * You may not use this file except in compliance with the License. 1010N/A * See the License for the specific language governing permissions 1010N/A * and limitations under the License. 1010N/A * When distributing Covered Code, include this CDDL HEADER in each 1010N/A * If applicable, add the following below this CDDL HEADER, with the 1010N/A * fields enclosed by brackets "[]" replaced with your own identifying 1010N/A * information: Portions Copyright [yyyy] [name of copyright owner] 1010N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 1010N/A * Use is subject to license terms. 1879N/A * Copyright 2016 Joyent, Inc. 1010N/A * Polled I/O safe ANSI terminal emulator module; 1010N/A * Supporting TERM types 'sun' and 'sun-color, parsing 1010N/A * ANSI x3.64 escape sequences, and the like. (See wscons(7d) 1379N/A * The functions in this file *must* be able to function in 1010N/A * standalone mode, ie. on a quiesced system. In that state, 1010N/A * access is single threaded, only one CPU is running. 1379N/A * System services are NOT available. 1379N/A * The following restrictions pertain to every function 1010N/A * - CANNOT use the DDI or LDI interfaces 1010N/A * - CANNOT call system services 1431N/A * - CANNOT wait for interrupts 1010N/A * All non-static functions in this file which: 1010N/A * - Operates on tems and tem_vt_state 1010N/A * - Not only called from standalone mode, i.e. has 1010N/A * should assert this at the beginning: 1010N/A * ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) || 1010N/A * called_from == CALLED_FROM_STANDALONE); 1010N/A/* Bk Rd Gr Br Bl Mg Cy Wh */ 1010N/A/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1010N/A Wh+ Bk Bl Gr Cy Rd Mg Br Wh Bk+ Bl+ Gr+ Cy+ Rd+ Mg+ Yw */ 1010N/A 0xff,
0x00,
0x00,
0x00,
0x00,
0x80,
0x80,
0x80,
0x80,
0x40,
0x00,
0x00,
0x00,
0xff,
0xff,
0xff,
1010N/A 0xff,
0x00,
0x00,
0x80,
0x80,
0x00,
0x00,
0x80,
0x80,
0x40,
0x00,
0xff,
0xff,
0x00,
0x00,
0xff,
1010N/A 0xff,
0x00,
0x80,
0x00,
0x80,
0x00,
0x80,
0x00,
0x80,
0x40,
0xff,
0x00,
0xff,
0x00,
0xff,
0x00 1010N/A * Fonts are statically linked with this module. At some point an 1010N/A * RFE might be desireable to allow dynamic font loading. The 1010N/A * original intention to facilitate dynamic fonts can be seen 1010N/A * by examining the data structures and set_font(). As much of 1010N/A * the original code is retained but modified to be suited to 1010N/A * traversing a list of static fonts. 1010N/A * Must be sorted by font size in descending order * Realign the console cursor. We did this in tem_init(). * However, drivers in the console stream may emit additional * messages before we are ready. This causes text overwrite * on the screen. This is a workaround. * This entry point handles output requests from restricted contexts like * kmdb, where services like mutexes are not available. This function * is entered when OBP or when a kernel debugger (such as kmdb) * are generating console output. In those cases, power management * concerns are handled by the abort sequence initiation (ie. when * the user hits L1+A or the equivalent to enter OBP or the debugger.). * It is also entered when the kernel is panicing. * This is the main entry point into the terminal emulator. * For each data message coming downstream, ANSI assumes that it is composed * of ASCII characters, which are treated as a byte-stream input to the * parsing state machine. All data is parsed immediately -- there is * Send the data we just got to the framebuffer. * Display an rectangular image on the frame buffer using the * mechanism appropriate for the system state being called * from quiesced or normal (ie. use polled I/O vs. layered ioctls) * Copy a rectangle from one location to another on the frame buffer * using the mechanism appropriate for the system state being called * from, quiesced or normal (ie. use polled I/O vs. layered ioctls) * Display or hide a rectangular block text cursor of a specificsize * at a specific location on frame buffer* using the mechanism * appropriate for the system state being called from, quisced or * normal (ie. use polled I/O vs. layered ioctls). * send the appropriate control message or set state based on the * value of the control character ch * tem_safe_send_data(tem, credp, called_from); * tem_safe_new_line(tem, credp, called_from); /* clear the parameters */ * if parameters [0..count - 1] are not set, set them to the value for (i = 0; i <
count; i++) {
* select graphics mode based on the param vals stored in a_params /* reset to initial normal settings */ case 1:
/* Bold Intense */ case 2:
/* Faint Intense */ case 7:
/* Reverse video */ case 30:
/* black (grey) foreground */ case 31:
/* red (light red) foreground */ case 32:
/* green (light green) foreground */ case 33:
/* brown (yellow) foreground */ case 34:
/* blue (light blue) foreground */ case 35:
/* magenta (light magenta) foreground */ case 36:
/* cyan (light cyan) foreground */ case 37:
/* white (bright white) foreground */ * Reset the foreground colour and brightness. case 40:
/* black (grey) background */ case 41:
/* red (light red) background */ case 42:
/* green (light green) background */ case 43:
/* brown (yellow) background */ case 44:
/* blue (light blue) background */ case 45:
/* magenta (light magenta) background */ case 46:
/* cyan (light cyan) background */ case 47:
/* white (bright white) background */ * Reset the background colour and brightness. case 90:
/* black (grey) foreground */ case 91:
/* red (light red) foreground */ case 92:
/* green (light green) foreground */ case 93:
/* brown (yellow) foreground */ case 94:
/* blue (light blue) foreground */ case 95:
/* magenta (light magenta) foreground */ case 96:
/* cyan (light cyan) foreground */ case 97:
/* white (bright white) foreground */ case 100:
/* black (grey) background */ case 101:
/* red (light red) background */ case 102:
/* green (light green) background */ case 103:
/* brown (yellow) background */ case 104:
/* blue (light blue) background */ case 105:
/* magenta (light magenta) background */ case 106:
/* cyan (light cyan) background */ case 107:
/* white (bright white) background */ * perform the appropriate action for the escape sequence * General rule: This code does not validate the arguments passed. * It assumes that the next lower level will do so. case 'm':
/* select terminal graphics mode */ case '@':
/* insert char */ case 'A':
/* cursor up */ case 'd':
/* VPA - vertical position absolute */ case 'e':
/* VPR - vertical position relative */ case 'B':
/* cursor down */ case 'a':
/* HPR - horizontal position relative */ case 'C':
/* cursor right */ case '`':
/* HPA - horizontal position absolute */ case 'D':
/* cursor left */ case 'E':
/* CNL cursor next line */ case 'F':
/* CPL cursor previous line */ case 'G':
/* cursor horizontal position */ case 'g':
/* clear tabs */ case 'f':
/* HVP Horizontal and Vertical Position */ case 'H':
/* CUP position cursor */ case 'I':
/* CHT - Cursor Horizontal Tab */ case 'J':
/* ED - Erase in Display */ /* erase cursor to end of screen */ /* FIRST erase cursor to end of line */ /* THEN erase lines below the cursor */ /* erase beginning of screen to cursor */ /* FIRST erase lines above the cursor */ /* THEN erase beginning of line to cursor */ case 'K':
/* EL - Erase in Line */ /* erase cursor to end of line */ /* erase beginning of line to cursor */ case 'L':
/* insert line */ case 'M':
/* delete line */ case 'P':
/* DCH - delete char */ case 'S':
/* scroll up */ case 'T':
/* scroll down */ case 'X':
/* erase char */ case 'Z':
/* cursor backward tabulation */ * Rule exception - We do sanity checking here. * Restrict the count to a sane value to keep from * looping for a long time. There can't be more than one * tab stop per column, so use that as a limit. * Gather the parameters of an ANSI escape sequence if (
ch >=
'0' &&
ch <=
'9') {
return;
/* Return immediately */ /* get the parameter value */ /* Restart parameter search */ /* Handle escape sequence */ * Add character to internal buffer. * When its full, send it to the next layer. /* buffer up the character until later */ * . a_nscroll was validated when it was set. * . Regardless of that, tem_safe_scroll and tem_safe_mv_cursor * will prevent anything bad from happening. * implement Esc[#r when # is zero. This means no * scroll but just return cursor to top of screen, /* erase rest of cursor line */ * Call the primitive to render this data. * We have just done something to the current output point. Reset the start * point for the buffered data in a_outbuf. There shouldn't be any data * State machine parser based on the current state and character input * major terminations are to control character or normal character * As defined below, this sequence * saves the cursor. However, Sun * defines ESC[s as reset. We resolved * the conflict by selecting reset as it * is exported in the termcap file for * sun-mon, while the "save cursor" * definition does not exist anywhere in * However, having no coherent * definition of reset, we have not * tem->tvs_r_cursor.row = tem->tvs_c_cursor.row; * tem->tvs_state = A_STATE_START; * Don't set anything if we are * already as we want to be. * If we have switched the characters to be the * inverse from the screen, then switch them as * well to keep them the inverse of the screen. * Don't set anything if we are * already where as we want to be. * If we have switched the characters to be the * inverse from the screen, then switch them as * well to keep them the inverse of the screen. * Rule exception: check for validity here. /* Previous char was <ESC> */ /* clear the parameters */ }
else if (
ch ==
'Q') {
/* <ESC>Q ? */ }
else if (
ch ==
'C') {
/* <ESC>C ? */ /* ESC c resets display */ /* ESC 7 Save Cursor position */ /* ESC 8 Restore Cursor position */ /* check for control chars */ * Note that very large values of "count" could cause col+count * to overflow, so we check "count" independently. * This function is used to blit a rectangular color image, * unperturbed on the underlying framebuffer, to render * icons and pictures. The data is a pixel pattern that * fills a rectangle bounded to the width and height parameters. * The color pixel data must to be pre-adjusted by the caller * for the current video depth. * This function is unused now. for (i = 0; i <
count; i++) {
* Clear OBP output above our kernel console term * when our kernel console term begins to scroll up, * we hope it is user friendly. * (Also see comments on tem_safe_pix_clear_prom_output) * This is only one time call. * Check if we're in process of clearing OBP's columns area, * which only happens when term scrolls up a whole line. * We need to clear OBP's columns area outside our kernel * console term. So that we set ma.e_col to entire row here. /* We have scrolled up (s_row - t_row) rows. */ /* All OBP rows have been cleared. */ unsigned char fg,
unsigned char bg)
unsigned char,
unsigned char);
* This function only clears count of columns in one row * This function clears OBP output above our kernel console term area * because OBP's term may have a bigger terminal window than that of * our kernel console term. So we need to clear OBP output garbage outside * of our kernel console term at a proper time, which is when the first * row output of our kernel console term scrolls at the first screen line. * _________________________________ * | _____________________ | ---> OBP's bigger term window * |_|_|___________________|_______| * | |___________________|---> our kernel console term window * |---> columns area to be cleared * This function only takes care of the output above our kernel console term, * and tem_prom_scroll_up takes care of columns area outside of our kernel * clear the whole screen for pixel mode, just clear the * Since the whole screen is cleared, we don't need * to clear OBP output later. * clear the whole screen, including the virtual screen buffer, * and reset the cursor to start point. case 3:
/* clear all tabs */ case 0:
/* clr tab at cursor */ * Sanity check and bounds enforcement. Out of bounds requests are * clipped to the screen boundaries. This seems to be what SPARC /* use initial settings */ * set up the initial tab stops * Find best font for these dimensions, or use default * A 1 pixel border is the absolute minimum we could have * as a border around the text window (BORDER_PIXELS = 2), * however a slightly larger border not only looks better * but for the fonts currently statically built into the * emulator causes much better font selection for the * normal range of screen resolutions. * The minus 2 is to make sure we have at least a 1 pixel * boarder around the entire screen. * bit_to_pix4 is for 4-bit frame buffers. It will write one output byte * for each 2 bits of input bitmap. It inverts the input bits before * doing the output translation, for reverse video. * Assuming foreground is 0001 and background is 0000... * An input data byte of 0x53 will output the bit pattern * 00000001 00000001 00000000 00010001. for (i = 0; i <
4; i++) {
* bit_to_pix8 is for 8-bit frame buffers. It will write one output byte * for each bit of input bitmap. It inverts the input bits before * doing the output translation, for reverse video. * Assuming foreground is 00000001 and background is 00000000... * An input data byte of 0x53 will output the bit pattern * 0000000 000000001 00000000 00000001 00000000 00000000 00000001 00000001. for (i = 0; i <
nbits; i++) {
* bit_to_pix24 is for 24-bit frame buffers. It will write four output bytes * for each bit of input bitmap. It inverts the input bits before * doing the output translation, for reverse video. Note that each * 24-bit RGB value is finally stored in a 32-bit unsigned int, with the * high-order byte set to zero. * Assuming foreground is 00000000 11111111 11111111 11111111 * and background is 00000000 00000000 00000000 00000000 * An input data byte of 0x53 will output the bit pattern * 00000000 00000000 00000000 00000000 * 00000000 11111111 11111111 11111111 * 00000000 00000000 00000000 00000000 * 00000000 11111111 11111111 11111111 * 00000000 00000000 00000000 00000000 * 00000000 00000000 00000000 00000000 * 00000000 11111111 11111111 11111111 * 00000000 11111111 11111111 11111111 for (i = 0; i <
nbits; i++) {
* flag: TEM_ATTR_SCREEN_REVERSE or TEM_ATTR_REVERSE * Clear a rectangle of screen for pixel mode. * nrows: the number of rows to clear * offset_y: the offset of height in pixels to begin clear * ncols: the number of cols to clear * offset_x: the offset of width in pixels to begin clear * scroll_up: whether this function is called during sroll up, * which is called only once. for (j = 0; j <
ncols; j++) {
* virtual screen operations for (i = 0; i <
count; i++) {
* Offset to the end of the region and copy backwards. /* More sanity checks. */ /* text_color_t is the same size as char */ * only blank screen, not clear our screen buffer * unblank screen with associated tem from its screen buffer * Display data in tvs_screen_buf to the actual framebuffer in a * When dealing with one row, output data with the same foreground * and background color all together. * Call the primitive to render this data. * Call the primitive to render this data.