Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 1 | /* generic.c */ |
| 2 | |
| 3 | /* This is a driver to implement, when possible, "high-level" |
| 4 | routines using only low level calls. This is to make it possible |
| 5 | to have accelerated functions for the individual drivers... |
| 6 | or to simply not bother with them. */ |
| 7 | |
| 8 | /* When creating new drivers, you need to assign all the functions that |
| 9 | that driver supports into the driver struct. If it is a supplementary |
| 10 | driver, it should make sure to perserve the old values. */ |
| 11 | |
| 12 | #include <stdio.h> |
Joseph Pranevich | 5576838 | 1998-12-09 15:43:03 +0000 | [diff] [blame] | 13 | |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 14 | #include "console.h" |
| 15 | #include "config.h" |
| 16 | #include "debug.h" |
| 17 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 18 | static void GENERIC_MoveLine(char row1, char row2, char col1, char col2); |
| 19 | static void GENERIC_ClearLine(char row, char col1, char col2, int bgcolor, |
| 20 | int attribute); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 21 | void GENERIC_Start() |
| 22 | { |
| 23 | /* Here, we only want to add a driver if there is not one already |
| 24 | defined. */ |
| 25 | |
| 26 | TRACE(console, "GENERIC_Start\n"); |
| 27 | |
| 28 | if (!driver.clearWindow) |
| 29 | driver.clearWindow = GENERIC_ClearWindow; |
| 30 | |
| 31 | if (!driver.scrollUpWindow) |
| 32 | driver.scrollUpWindow = GENERIC_ScrollUpWindow; |
| 33 | |
| 34 | if (!driver.scrollDownWindow) |
| 35 | driver.scrollDownWindow = GENERIC_ScrollDownWindow; |
| 36 | |
| 37 | if (!driver.getCharacter) |
| 38 | driver.getCharacter = GENERIC_GetCharacter; |
| 39 | } |
| 40 | |
| 41 | void GENERIC_ClearWindow(char row1, char col1, char row2, char col2, |
| 42 | int bg_color, int attribute) |
| 43 | { |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 44 | char trow, tcol, x; |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 45 | int old_refresh; |
| 46 | |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 47 | /* Abort if we have only partial functionality */ |
| 48 | if (!(driver.getCursorPosition && driver.moveCursor && driver.write)) |
| 49 | return; |
| 50 | |
| 51 | old_refresh = CONSOLE_GetRefresh(); |
| 52 | CONSOLE_SetRefresh(FALSE); |
| 53 | |
| 54 | CONSOLE_GetCursorPosition(&trow, &tcol); |
| 55 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 56 | for (x = row1; x <= row2; x++) |
| 57 | GENERIC_ClearLine(x, col1, col2, bg_color, attribute); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 58 | |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 59 | CONSOLE_MoveCursor(trow, tcol); |
| 60 | |
| 61 | CONSOLE_SetRefresh(old_refresh); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 62 | } |
| 63 | |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 64 | void GENERIC_ScrollUpWindow(char row1, char col1, char row2, char col2, |
| 65 | char lines, int bg_color, int attribute) |
| 66 | { |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 67 | /* Scroll Up Window: Characters go down */ |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 68 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 69 | char trow, tcol; |
| 70 | int old_refresh, x; |
| 71 | |
| 72 | TRACE(console, "Scroll Up %d lines from %d to %d.\n", lines, row1, |
| 73 | row2); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 74 | |
| 75 | /* Abort if we have only partial functionality */ |
| 76 | if (!(driver.getCursorPosition && driver.moveCursor && driver.write |
| 77 | && driver.getCharacterAtCursor && driver.clearWindow)) |
| 78 | return; |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 79 | |
| 80 | /* Save initial state... */ |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 81 | old_refresh = CONSOLE_GetRefresh(); |
| 82 | CONSOLE_SetRefresh(FALSE); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 83 | CONSOLE_GetCursorPosition(&trow, &tcol); |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 84 | |
| 85 | for (x = row1 + lines; x <= row2; x++) |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 86 | { |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 87 | GENERIC_MoveLine(x, x - lines, col1, col2); |
| 88 | GENERIC_ClearLine(x, col1, col2, bg_color, attribute); |
| 89 | } |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 90 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 91 | /* Restore State */ |
| 92 | CONSOLE_MoveCursor(trow, tcol); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 93 | CONSOLE_SetRefresh(old_refresh); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | void GENERIC_ScrollDownWindow(char row1, char col1, char row2, char col2, |
| 97 | char lines, int bg_color, int attribute) |
| 98 | { |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 99 | /* Scroll Down Window: Characters go up */ |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 100 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 101 | char trow, tcol; |
| 102 | int old_refresh, x; |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 103 | |
| 104 | /* Abort if we have only partial functionality */ |
| 105 | if (!(driver.getCursorPosition && driver.moveCursor && driver.write |
| 106 | && driver.getCharacterAtCursor && driver.clearWindow)) |
| 107 | return; |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 108 | |
| 109 | /* Save initial state... */ |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 110 | old_refresh = CONSOLE_GetRefresh(); |
| 111 | CONSOLE_SetRefresh(FALSE); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 112 | CONSOLE_GetCursorPosition(&trow, &tcol); |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 113 | |
| 114 | for (x = row2; x >= row1 + lines; x--) |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 115 | { |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 116 | GENERIC_MoveLine(x, x + lines, col1, col2); |
| 117 | GENERIC_ClearLine(x, col1, col1, bg_color, attribute); |
| 118 | } |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 119 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 120 | /* Restore State */ |
| 121 | CONSOLE_MoveCursor(trow, tcol); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 122 | CONSOLE_SetRefresh(old_refresh); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | char GENERIC_GetCharacter() |
| 126 | { |
| 127 | /* Keep getting keys until we get one with a char value */ |
| 128 | char ch = (char) 0, scan; |
| 129 | |
| 130 | while (!ch) |
| 131 | { |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 132 | CONSOLE_GetKeystroke(&scan, &ch); |
Joseph Pranevich | 791cd6a | 1998-12-02 19:58:08 +0000 | [diff] [blame] | 133 | } |
| 134 | return ch; |
| 135 | } |
| 136 | |
Joseph Pranevich | d87fa94 | 1999-01-03 16:15:12 +0000 | [diff] [blame] | 137 | static void GENERIC_ClearLine(char row, char col1, char col2, int bgcolor, |
| 138 | int attribute) |
| 139 | { |
| 140 | /* This function is here to simplify the logic of the scroll and clear |
| 141 | functions but may be useful elsewhere. If it can be used from |
| 142 | outside here, it should be made non-static */ |
| 143 | |
| 144 | int x; |
| 145 | |
| 146 | TRACE(console, "Clear Line: %d from %d to %d.\n", row, col1, col2); |
| 147 | |
| 148 | for (x = col1; x <= col2; x++) |
| 149 | { |
| 150 | CONSOLE_MoveCursor(row, x); |
| 151 | CONSOLE_Write(' ', 0, 0, 0); |
| 152 | } |
| 153 | |
| 154 | /* Assume that the calling function will make sure that the cursor is |
| 155 | repositioned properly. If this becomes non-static, that will need to be |
| 156 | changed. */ |
| 157 | } |
| 158 | |
| 159 | static void GENERIC_MoveLine(char row1, char row2, char col1, char col2) |
| 160 | { |
| 161 | /* This function is here to simplify the logic of the scroll and clear |
| 162 | functions but may be useful elsewhere. If it can be used from |
| 163 | outside here, it should be made non-static */ |
| 164 | |
| 165 | int x; |
| 166 | int bg_color, fg_color, attribute; |
| 167 | char ch; |
| 168 | |
| 169 | TRACE(console, "Move Line: Move %d to %d.\n", row1, row2); |
| 170 | |
| 171 | for (x = col1; x <= col2; x++) |
| 172 | { |
| 173 | CONSOLE_MoveCursor(row1, x); |
| 174 | CONSOLE_GetCharacterAtCursor(&ch, &fg_color, &bg_color, &attribute); |
| 175 | CONSOLE_MoveCursor(row2, x); |
| 176 | CONSOLE_Write(ch, fg_color, bg_color, attribute); |
| 177 | } |
| 178 | |
| 179 | /* Assume that the calling function will make sure that the cursor is |
| 180 | repositioned properly. If this becomes non-static, that will need to be |
| 181 | changed. */ |
| 182 | } |