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