Changed the GDI driver interface to pass an opaque PHYSDEV pointer
[wine] / console / interface.c
1 /*
2  * Copyright 1999 - Joseph Pranevich
3  *
4  * The primary purpose of this function is to provide CONSOLE_*
5  * routines that immediately call the appropriate driver handler.
6  * This cleans up code in the individual modules considerably.
7  * This could be done using a macro, but additional functionality
8  * may be provided here in the future.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "windef.h"
32 #include "console.h"
33 #include "options.h"
34
35 CONSOLE_device driver;
36
37 static int pop_driver(char **, char **, int *);
38
39 static int console_initialized = FALSE;
40
41 static int CONSOLE_Init(void)
42 {
43       char buffer[256];
44       char *single, *drivers = buffer;
45       int length;
46       char initial_rows[5];
47       char initial_columns[5];
48
49       /* Suitable defaults... */
50       driver.console_out = stdout;
51       driver.console_in = stdin;
52
53       /* drivers should be a string that consists of driver names
54          followed by plus (+) signs to denote additions. 
55
56          For example:
57             drivers = tty                Load just the tty driver
58             drivers = ncurses+xterm      Load ncurses then xterm
59
60          The "default" value is just tty.
61       */
62       PROFILE_GetWineIniString( "console", "Drivers", CONSOLE_DEFAULT_DRIVER,
63                                 buffer, sizeof(buffer) );
64
65       while (pop_driver(&drivers, &single, &length))
66       {
67          if (!strncmp(single, "tty", length))
68             TTY_Start();
69 #ifdef WINE_NCURSES
70          else if (!strncmp(single, "ncurses", length))
71             NCURSES_Start();
72 #endif /* WINE_NCURSES */
73          else if (!strncmp(single, "xterm", length))
74             XTERM_Start();
75       }
76
77    /* Read in generic configuration */
78    /* This is primarily to work around a limitation in nxterm where
79       this information is not correctly passed to the ncurses layer
80       through the terminal. At least, I'm not doing it correctly if there
81       is a way. But this serves as a generic way to do the same anyway. */
82
83    /* We are setting this to 80x25 here which is *not* the default for
84       most xterm variants... It is however the standard VGA resolution */
85
86    /* FIXME: We need to be able to be able to specify that the window's
87       dimensions should be used. This is required for correct emulation
88       of Win32's console and Win32's DOS emulation */
89
90    PROFILE_GetWineIniString("console", "InitialRows",
91       "24", initial_rows, 5);
92    PROFILE_GetWineIniString("console", "InitialColumns",
93       "80", initial_columns, 5);
94
95    sscanf(initial_rows, "%d", &driver.y_res);
96    sscanf(initial_columns, "%d", &driver.x_res);
97    
98    GENERIC_Start();
99
100    if (driver.init)
101       driver.init();
102
103    /* Not all terminals let our programs know the proper resolution
104       if the resolution is set on the command-line... */
105    CONSOLE_NotifyResizeScreen(driver.x_res, driver.y_res);
106
107    atexit(CONSOLE_Close);
108
109    /* For now, always return TRUE */
110    return TRUE;
111 }
112
113 void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute)
114 {
115    if (!console_initialized)
116       console_initialized = CONSOLE_Init();
117       
118    if (driver.write)
119    {
120       driver.write(out, fg_color, bg_color, attribute);
121       if (!driver.norefresh)
122          CONSOLE_Refresh();
123    }
124 }
125
126 void CONSOLE_Close(void)
127 {
128    if (driver.close)
129       driver.close();
130 }
131
132 void CONSOLE_MoveCursor(char row, char col)
133 {
134    if (!console_initialized)
135       console_initialized = CONSOLE_Init();
136       
137    if (driver.moveCursor)
138    {
139       driver.moveCursor(row, col);
140       if (!driver.norefresh)
141          CONSOLE_Refresh();
142    }
143 }
144
145 void CONSOLE_ClearWindow(char row1, char col1, char row2, char col2, 
146    int bg_color, int attribute)
147 {
148    if (!console_initialized)
149       console_initialized = CONSOLE_Init();
150       
151    if (driver.clearWindow)
152    {
153       driver.clearWindow(row1, col1, row2, col2, bg_color, attribute);
154       if (!driver.norefresh)
155          CONSOLE_Refresh();
156    }
157 }
158
159 void CONSOLE_ScrollUpWindow(char row1, char col1, char row2, char col2, 
160    char lines, int bg_color, int attribute)
161 {
162    if (!console_initialized)
163       console_initialized = CONSOLE_Init();
164       
165    if (driver.scrollUpWindow)
166    {
167       driver.scrollUpWindow(row1, col1, row2, col2, lines, bg_color, 
168          attribute);
169       if (!driver.norefresh)
170          CONSOLE_Refresh();
171    }
172 }
173
174 void CONSOLE_ScrollDownWindow(char row1, char col1, char row2, char col2, 
175    char lines, int bg_color, int attribute)
176 {
177    if (!console_initialized)
178       console_initialized = CONSOLE_Init();
179       
180    if (driver.scrollDownWindow)
181    {
182       driver.scrollDownWindow(row1, col1, row2, col2, lines, bg_color, 
183          attribute);
184       if (!driver.norefresh)
185          CONSOLE_Refresh();
186    }
187 }
188
189 int CONSOLE_CheckForKeystroke(char *scan, char *ascii)
190 /* These functions need to go through a conversion layer. Scancodes
191    should *not* be determined by the driver, rather they should have
192    a conv_* function in int16.c. Yuck. */
193 {
194    if (!console_initialized)
195       console_initialized = CONSOLE_Init();
196       
197    if (driver.checkForKeystroke)
198       return driver.checkForKeystroke(scan, ascii);
199    else
200       return FALSE;
201 }
202
203 void CONSOLE_GetKeystroke(char *scan, char *ascii)
204 {
205    if (!console_initialized)
206       console_initialized = CONSOLE_Init();
207       
208    if (driver.getKeystroke)
209       driver.getKeystroke(scan, ascii);
210 }
211
212 void CONSOLE_GetCursorPosition(char *row, char *col)
213 {
214    if (!console_initialized)
215       console_initialized = CONSOLE_Init();
216       
217    if (driver.getCursorPosition)
218       driver.getCursorPosition(row, col);
219 }
220
221 void CONSOLE_GetCharacterAtCursor(char *ch, int *fg, int *bg, int *a)
222 {
223    if (!console_initialized)
224       console_initialized = CONSOLE_Init();
225       
226    if (driver.getCharacterAtCursor)
227       driver.getCharacterAtCursor(ch, fg, bg, a);
228 }
229
230 void CONSOLE_Refresh()
231 {
232    if (!console_initialized)
233       console_initialized = CONSOLE_Init();
234       
235    if (driver.refresh)
236       driver.refresh();
237 }
238
239 int CONSOLE_AllocColor(int color)
240 {
241    if (!console_initialized)
242       console_initialized = CONSOLE_Init();
243       
244    if (driver.allocColor)
245       return driver.allocColor(color);
246    else 
247       return 0;
248 }
249
250 void CONSOLE_ClearScreen()
251 {
252    if (!console_initialized)
253       console_initialized = CONSOLE_Init();
254       
255    if (driver.clearScreen)
256    {
257       driver.clearScreen();
258       if (!driver.norefresh)
259          CONSOLE_Refresh();
260    }
261 }
262
263 char CONSOLE_GetCharacter()
264 {
265    if (!console_initialized)
266       console_initialized = CONSOLE_Init();
267       
268    /* I'm not sure if we need this really. This is a function that can be
269       accelerated that returns the next *non extended* keystroke */
270    if (driver.getCharacter)
271       return driver.getCharacter();
272    else
273       return (char) 0; /* Sure, this will probably break programs... */
274 }
275
276 void CONSOLE_ResizeScreen(int x, int y)
277 {
278    if (!console_initialized)
279       console_initialized = CONSOLE_Init();
280       
281    if (driver.resizeScreen)
282       driver.resizeScreen(x, y);
283 }
284
285 void CONSOLE_NotifyResizeScreen(int x, int y)
286 {
287    if (driver.notifyResizeScreen)
288       driver.notifyResizeScreen(x, y);
289 }
290
291 void CONSOLE_SetBackgroundColor(int fg, int bg)
292 {
293    if (!console_initialized)
294       console_initialized = CONSOLE_Init();
295       
296    if (driver.setBackgroundColor)
297       driver.setBackgroundColor(fg, bg);
298 }
299
300 void CONSOLE_GetBackgroundColor(int *fg, int *bg)
301 {
302    if (!console_initialized)
303       console_initialized = CONSOLE_Init();
304       
305    if (driver.getBackgroundColor)
306       driver.getBackgroundColor(fg, bg);
307 }
308
309 void CONSOLE_WriteRawString(char *str)
310 {
311    if (!console_initialized)
312       console_initialized = CONSOLE_Init();
313       
314    /* This is a special function that is only for internal use and 
315       does not actually call any of the console drivers. It's 
316       primary purpose is to provide a way for higher-level drivers
317       to write directly to the underlying terminal without worry that
318       there will be any retranslation done by the assorted drivers. Care
319       should be taken to ensure that this only gets called when the thing
320       written does not actually produce any output or a CONSOLE_Redraw()
321       is called immediately afterwards.
322       CONSOLE_Redraw() is not yet implemented.
323    */
324    fprintf(driver.console_out, "%s", str);
325 }
326
327 /* This function is only at the CONSOLE level. */
328 /* Admittably, calling the variable norefresh might be a bit dumb...*/
329 void CONSOLE_SetRefresh(int setting)
330 {
331    if (setting)
332       driver.norefresh = FALSE;
333    else
334       driver.norefresh = TRUE;
335 }
336
337 /* This function is only at the CONSOLE level. */
338 int CONSOLE_GetRefresh()
339 {
340    if (driver.norefresh)
341       return FALSE;
342    else 
343       return TRUE;
344 }
345
346
347 /* Utility functions... */
348
349 int pop_driver(char **drivers, char **single, int *length)
350 {
351    /* Take the string in drivers and extract the first "driver" entry */
352    /* Advance the pointer in drivers to the next entry, put the origional
353       pointer in single, and put the length in length. */
354    /* Return TRUE if we found one */
355
356    if (!*drivers)
357       return FALSE;
358
359    *single = *drivers;
360    *length = 0;
361
362    while ((*drivers[0] != '\0') && (*drivers[0] != '+'))
363    {
364       (*drivers)++;
365       (*length)++;
366    }
367    
368    while (*drivers[0] == '+')
369       (*drivers)++;
370
371    if (*length)
372       return TRUE;
373    else
374       return FALSE;
375       
376 }