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