| /* generic.c */ |
| /* Copyright 1999 - Joseph Pranevich */ |
| |
| /* This is a driver to implement, when possible, "high-level" |
| routines using only low level calls. This is to make it possible |
| to have accelerated functions for the individual drivers... |
| or to simply not bother with them. */ |
| |
| /* When creating new drivers, you need to assign all the functions that |
| that driver supports into the driver struct. If it is a supplementary |
| driver, it should make sure to perserve the old values. */ |
| |
| #include <stdio.h> |
| |
| #include "console.h" |
| #include "config.h" |
| #include "debugtools.h" |
| |
| DEFAULT_DEBUG_CHANNEL(console) |
| |
| static void GENERIC_MoveLine(char row1, char row2, char col1, char col2); |
| static void GENERIC_ClearLine(char row, char col1, char col2, int bgcolor, |
| int attribute); |
| void GENERIC_Start(void) |
| { |
| /* Here, we only want to add a driver if there is not one already |
| defined. */ |
| |
| TRACE("GENERIC_Start\n"); |
| |
| if (!driver.clearWindow) |
| driver.clearWindow = GENERIC_ClearWindow; |
| |
| if (!driver.scrollUpWindow) |
| driver.scrollUpWindow = GENERIC_ScrollUpWindow; |
| |
| if (!driver.scrollDownWindow) |
| driver.scrollDownWindow = GENERIC_ScrollDownWindow; |
| |
| if (!driver.getCharacter) |
| driver.getCharacter = GENERIC_GetCharacter; |
| } |
| |
| void GENERIC_ClearWindow(char row1, char col1, char row2, char col2, |
| int bg_color, int attribute) |
| { |
| char trow, tcol, x; |
| int old_refresh; |
| |
| /* Abort if we have only partial functionality */ |
| if (!(driver.getCursorPosition && driver.moveCursor && driver.write)) |
| return; |
| |
| old_refresh = CONSOLE_GetRefresh(); |
| CONSOLE_SetRefresh(FALSE); |
| |
| CONSOLE_GetCursorPosition(&trow, &tcol); |
| |
| for (x = row1; x <= row2; x++) |
| GENERIC_ClearLine(x, col1, col2, bg_color, attribute); |
| |
| CONSOLE_MoveCursor(trow, tcol); |
| |
| CONSOLE_SetRefresh(old_refresh); |
| } |
| |
| void GENERIC_ScrollUpWindow(char row1, char col1, char row2, char col2, |
| char lines, int bg_color, int attribute) |
| { |
| /* Scroll Up Window: Characters go down */ |
| |
| char trow, tcol, x; |
| int old_refresh; |
| |
| TRACE("Scroll Up %d lines from %d to %d.\n", lines, row1, |
| row2); |
| |
| /* Abort if we have only partial functionality */ |
| if (!(driver.getCursorPosition && driver.moveCursor && driver.write |
| && driver.getCharacterAtCursor && driver.clearWindow)) |
| return; |
| |
| /* Save initial state... */ |
| old_refresh = CONSOLE_GetRefresh(); |
| CONSOLE_SetRefresh(FALSE); |
| CONSOLE_GetCursorPosition(&trow, &tcol); |
| |
| for (x = row1 + lines; x <= row2; x++) |
| { |
| GENERIC_MoveLine(x, x - lines, col1, col2); |
| GENERIC_ClearLine(x, col1, col2, bg_color, attribute); |
| } |
| |
| /* Restore State */ |
| CONSOLE_MoveCursor(trow, tcol); |
| CONSOLE_SetRefresh(old_refresh); |
| } |
| |
| void GENERIC_ScrollDownWindow(char row1, char col1, char row2, char col2, |
| char lines, int bg_color, int attribute) |
| { |
| /* Scroll Down Window: Characters go up */ |
| |
| char trow, tcol, x; |
| int old_refresh; |
| |
| /* Abort if we have only partial functionality */ |
| if (!(driver.getCursorPosition && driver.moveCursor && driver.write |
| && driver.getCharacterAtCursor && driver.clearWindow)) |
| return; |
| |
| /* Save initial state... */ |
| old_refresh = CONSOLE_GetRefresh(); |
| CONSOLE_SetRefresh(FALSE); |
| CONSOLE_GetCursorPosition(&trow, &tcol); |
| |
| for (x = row2; x >= row1 + lines; x--) |
| { |
| GENERIC_MoveLine(x, x + lines, col1, col2); |
| GENERIC_ClearLine(x, col1, col1, bg_color, attribute); |
| } |
| |
| /* Restore State */ |
| CONSOLE_MoveCursor(trow, tcol); |
| CONSOLE_SetRefresh(old_refresh); |
| } |
| |
| char GENERIC_GetCharacter() |
| { |
| /* Keep getting keys until we get one with a char value */ |
| char ch = (char) 0, scan; |
| |
| while (!ch) |
| { |
| CONSOLE_GetKeystroke(&scan, &ch); |
| } |
| return ch; |
| } |
| |
| static void GENERIC_ClearLine(char row, char col1, char col2, int bgcolor, |
| int attribute) |
| { |
| /* This function is here to simplify the logic of the scroll and clear |
| functions but may be useful elsewhere. If it can be used from |
| outside here, it should be made non-static */ |
| |
| char x; |
| |
| TRACE("Clear Line: %d from %d to %d (unused: bgcolor %d, attrib %d).\n", row, col1, col2, bgcolor, attribute); |
| |
| for (x = col1; x <= col2; x++) |
| { |
| CONSOLE_MoveCursor(row, x); |
| CONSOLE_Write(' ', 0, 0, 0); |
| } |
| |
| /* Assume that the calling function will make sure that the cursor is |
| repositioned properly. If this becomes non-static, that will need to be |
| changed. */ |
| } |
| |
| static void GENERIC_MoveLine(char row1, char row2, char col1, char col2) |
| { |
| /* This function is here to simplify the logic of the scroll and clear |
| functions but may be useful elsewhere. If it can be used from |
| outside here, it should be made non-static */ |
| |
| char x; |
| int bg_color, fg_color, attribute; |
| char ch; |
| |
| TRACE("Move Line: Move %d to %d.\n", row1, row2); |
| |
| for (x = col1; x <= col2; x++) |
| { |
| CONSOLE_MoveCursor(row1, x); |
| CONSOLE_GetCharacterAtCursor(&ch, &fg_color, &bg_color, &attribute); |
| CONSOLE_MoveCursor(row2, x); |
| CONSOLE_Write(ch, fg_color, bg_color, attribute); |
| } |
| |
| /* Assume that the calling function will make sure that the cursor is |
| repositioned properly. If this becomes non-static, that will need to be |
| changed. */ |
| } |