Changed the GDI driver interface to pass an opaque PHYSDEV pointer
[wine] / console / generic.c
1 /*
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  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 /* When creating new drivers, you need to assign all the functions that
25    that driver supports into the driver struct. If it is a supplementary
26    driver, it should make sure to preserve the old values. */
27
28 #include "config.h"
29
30 #include <stdio.h>
31
32 #include "console.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(console);
36
37 static void GENERIC_MoveLine(char row1, char row2, char col1, char col2);
38 static void GENERIC_ClearLine(char row, char col1, char col2, int bgcolor,
39    int attribute);
40 void GENERIC_Start(void)
41 {
42    /* Here, we only want to add a driver if there is not one already
43       defined. */
44
45    TRACE("GENERIC_Start\n");
46
47    if (!driver.clearWindow)
48       driver.clearWindow = GENERIC_ClearWindow;
49
50    if (!driver.scrollUpWindow)
51       driver.scrollUpWindow = GENERIC_ScrollUpWindow;
52
53    if (!driver.scrollDownWindow)
54       driver.scrollDownWindow = GENERIC_ScrollDownWindow;
55
56    if (!driver.getCharacter)
57       driver.getCharacter = GENERIC_GetCharacter;
58 }
59
60 void GENERIC_ClearWindow(char row1, char col1, char row2, char col2, 
61    int bg_color, int attribute)
62 {
63    char trow, tcol, x;
64    int old_refresh;
65
66    /* Abort if we have only partial functionality */
67    if (!(driver.getCursorPosition && driver.moveCursor && driver.write))
68       return;
69
70    old_refresh = CONSOLE_GetRefresh();
71    CONSOLE_SetRefresh(FALSE);
72
73    CONSOLE_GetCursorPosition(&trow, &tcol);
74    
75    for (x = row1; x <= row2; x++)
76       GENERIC_ClearLine(x, col1, col2, bg_color, attribute);
77
78    CONSOLE_MoveCursor(trow, tcol);
79
80    CONSOLE_SetRefresh(old_refresh);
81 }      
82
83 void GENERIC_ScrollUpWindow(char row1, char col1, char row2, char col2, 
84    char lines, int bg_color, int attribute)
85 {
86    /* Scroll Up Window: Characters go down */
87
88    char trow, tcol, x;
89    int old_refresh;
90
91    TRACE("Scroll Up %d lines from %d to %d.\n", lines, row1,
92       row2);
93
94    /* Abort if we have only partial functionality */
95    if (!(driver.getCursorPosition && driver.moveCursor && driver.write
96       && driver.getCharacterAtCursor && driver.clearWindow))
97       return;
98    
99    /* Save initial state... */
100    old_refresh = CONSOLE_GetRefresh();
101    CONSOLE_SetRefresh(FALSE);
102    CONSOLE_GetCursorPosition(&trow, &tcol);
103
104    for (x = row1 + lines; x <= row2; x++)
105    {
106       GENERIC_MoveLine(x, x - lines, col1, col2);
107       GENERIC_ClearLine(x, col1, col2, bg_color, attribute);
108    }
109
110    /* Restore State */
111    CONSOLE_MoveCursor(trow, tcol); 
112    CONSOLE_SetRefresh(old_refresh);
113 }
114
115 void GENERIC_ScrollDownWindow(char row1, char col1, char row2, char col2, 
116    char lines, int bg_color, int attribute)
117 {
118    /* Scroll Down Window: Characters go up */
119
120    char trow, tcol, x;
121    int old_refresh;
122
123    /* Abort if we have only partial functionality */
124    if (!(driver.getCursorPosition && driver.moveCursor && driver.write
125       && driver.getCharacterAtCursor && driver.clearWindow))
126       return;
127    
128    /* Save initial state... */
129    old_refresh = CONSOLE_GetRefresh();
130    CONSOLE_SetRefresh(FALSE);
131    CONSOLE_GetCursorPosition(&trow, &tcol);
132
133    for (x = row2; x >= row1 + lines; x--)
134    {
135       GENERIC_MoveLine(x, x + lines, col1, col2);
136       GENERIC_ClearLine(x, col1, col1, bg_color, attribute);
137    }
138
139    /* Restore State */
140    CONSOLE_MoveCursor(trow, tcol); 
141    CONSOLE_SetRefresh(old_refresh);
142 }
143
144 char GENERIC_GetCharacter()
145 {
146    /* Keep getting keys until we get one with a char value */
147    char ch = (char) 0, scan;
148    
149    while (!ch)
150    {
151       CONSOLE_GetKeystroke(&scan, &ch);
152    }
153    return ch;
154 }
155
156 static void GENERIC_ClearLine(char row, char col1, char col2, int bgcolor,
157    int attribute)
158 {
159    /* This function is here to simplify the logic of the scroll and clear
160       functions but may be useful elsewhere. If it can be used from
161       outside here, it should be made non-static */
162
163    char x;
164
165    TRACE("Clear Line: %d from %d to %d (unused: bgcolor %d, attrib %d).\n", row, col1, col2, bgcolor, attribute);
166
167    for (x = col1; x <= col2; x++)
168    {
169       CONSOLE_MoveCursor(row, x);
170       CONSOLE_Write(' ', 0, 0, 0);
171    }
172
173    /* Assume that the calling function will make sure that the cursor is
174    repositioned properly. If this becomes non-static, that will need to be
175    changed. */
176 }
177    
178 static void GENERIC_MoveLine(char row1, char row2, char col1, char col2)
179 {
180    /* This function is here to simplify the logic of the scroll and clear
181       functions but may be useful elsewhere. If it can be used from
182       outside here, it should be made non-static */
183
184    char x;
185    int bg_color, fg_color, attribute;
186    char ch;
187
188    TRACE("Move Line: Move %d to %d.\n", row1, row2);
189
190    for (x = col1; x <= col2; x++)
191    {
192       CONSOLE_MoveCursor(row1, x);
193       CONSOLE_GetCharacterAtCursor(&ch, &fg_color, &bg_color, &attribute);
194       CONSOLE_MoveCursor(row2, x);
195       CONSOLE_Write(ch, fg_color, bg_color, attribute);
196    }
197
198    /* Assume that the calling function will make sure that the cursor is
199    repositioned properly. If this becomes non-static, that will need to be
200    changed. */
201 }