Cleaned up assumptions about WS_CHILD flag so that we can allow it to
[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    atexit(CONSOLE_Close);
91
92    /* For now, always return TRUE */
93    return TRUE;
94 }
95
96 void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute)
97 {
98    if (!console_initialized)
99       console_initialized = CONSOLE_Init();
100       
101    if (driver.write)
102    {
103       driver.write(out, fg_color, bg_color, attribute);
104       if (!driver.norefresh)
105          CONSOLE_Refresh();
106    }
107 }
108
109 void CONSOLE_Close(void)
110 {
111    if (driver.close)
112       driver.close();
113 }
114
115 void CONSOLE_MoveCursor(char row, char col)
116 {
117    if (!console_initialized)
118       console_initialized = CONSOLE_Init();
119       
120    if (driver.moveCursor)
121    {
122       driver.moveCursor(row, col);
123       if (!driver.norefresh)
124          CONSOLE_Refresh();
125    }
126 }
127
128 void CONSOLE_ClearWindow(char row1, char col1, char row2, char col2, 
129    int bg_color, int attribute)
130 {
131    if (!console_initialized)
132       console_initialized = CONSOLE_Init();
133       
134    if (driver.clearWindow)
135    {
136       driver.clearWindow(row1, col1, row2, col2, bg_color, attribute);
137       if (!driver.norefresh)
138          CONSOLE_Refresh();
139    }
140 }
141
142 void CONSOLE_ScrollUpWindow(char row1, char col1, char row2, char col2, 
143    char lines, int bg_color, int attribute)
144 {
145    if (!console_initialized)
146       console_initialized = CONSOLE_Init();
147       
148    if (driver.scrollUpWindow)
149    {
150       driver.scrollUpWindow(row1, col1, row2, col2, lines, bg_color, 
151          attribute);
152       if (!driver.norefresh)
153          CONSOLE_Refresh();
154    }
155 }
156
157 void CONSOLE_ScrollDownWindow(char row1, char col1, char row2, char col2, 
158    char lines, int bg_color, int attribute)
159 {
160    if (!console_initialized)
161       console_initialized = CONSOLE_Init();
162       
163    if (driver.scrollDownWindow)
164    {
165       driver.scrollDownWindow(row1, col1, row2, col2, lines, bg_color, 
166          attribute);
167       if (!driver.norefresh)
168          CONSOLE_Refresh();
169    }
170 }
171
172 int CONSOLE_CheckForKeystroke(char *scan, char *ascii)
173 /* These functions need to go through a conversion layer. Scancodes
174    should *not* be determined by the driver, rather they should have
175    a conv_* function in int16.c. Yuck. */
176 {
177    if (!console_initialized)
178       console_initialized = CONSOLE_Init();
179       
180    if (driver.checkForKeystroke)
181       return driver.checkForKeystroke(scan, ascii);
182    else
183       return FALSE;
184 }
185
186 void CONSOLE_GetKeystroke(char *scan, char *ascii)
187 {
188    if (!console_initialized)
189       console_initialized = CONSOLE_Init();
190       
191    if (driver.getKeystroke)
192       driver.getKeystroke(scan, ascii);
193 }
194
195 void CONSOLE_GetCursorPosition(char *row, char *col)
196 {
197    if (!console_initialized)
198       console_initialized = CONSOLE_Init();
199       
200    if (driver.getCursorPosition)
201       driver.getCursorPosition(row, col);
202 }
203
204 void CONSOLE_GetCharacterAtCursor(char *ch, int *fg, int *bg, int *a)
205 {
206    if (!console_initialized)
207       console_initialized = CONSOLE_Init();
208       
209    if (driver.getCharacterAtCursor)
210       driver.getCharacterAtCursor(ch, fg, bg, a);
211 }
212
213 void CONSOLE_Refresh()
214 {
215    if (!console_initialized)
216       console_initialized = CONSOLE_Init();
217       
218    if (driver.refresh)
219       driver.refresh();
220 }
221
222 int CONSOLE_AllocColor(int color)
223 {
224    if (!console_initialized)
225       console_initialized = CONSOLE_Init();
226       
227    if (driver.allocColor)
228       return driver.allocColor(color);
229    else 
230       return 0;
231 }
232
233 void CONSOLE_ClearScreen()
234 {
235    if (!console_initialized)
236       console_initialized = CONSOLE_Init();
237       
238    if (driver.clearScreen)
239    {
240       driver.clearScreen();
241       if (!driver.norefresh)
242          CONSOLE_Refresh();
243    }
244 }
245
246 char CONSOLE_GetCharacter()
247 {
248    if (!console_initialized)
249       console_initialized = CONSOLE_Init();
250       
251    /* I'm not sure if we need this really. This is a function that can be
252       accelerated that returns the next *non extended* keystroke */
253    if (driver.getCharacter)
254       return driver.getCharacter();
255    else
256       return (char) 0; /* Sure, this will probably break programs... */
257 }
258
259 void CONSOLE_ResizeScreen(int x, int y)
260 {
261    if (!console_initialized)
262       console_initialized = CONSOLE_Init();
263       
264    if (driver.resizeScreen)
265       driver.resizeScreen(x, y);
266 }
267
268 void CONSOLE_NotifyResizeScreen(int x, int y)
269 {
270    if (driver.notifyResizeScreen)
271       driver.notifyResizeScreen(x, y);
272 }
273
274 void CONSOLE_SetBackgroundColor(int fg, int bg)
275 {
276    if (!console_initialized)
277       console_initialized = CONSOLE_Init();
278       
279    if (driver.setBackgroundColor)
280       driver.setBackgroundColor(fg, bg);
281 }
282
283 void CONSOLE_GetBackgroundColor(int *fg, int *bg)
284 {
285    if (!console_initialized)
286       console_initialized = CONSOLE_Init();
287       
288    if (driver.getBackgroundColor)
289       driver.getBackgroundColor(fg, bg);
290 }
291
292 void CONSOLE_WriteRawString(char *str)
293 {
294    if (!console_initialized)
295       console_initialized = CONSOLE_Init();
296       
297    /* This is a special function that is only for internal use and 
298       does not actually call any of the console drivers. It's 
299       primary purpose is to provide a way for higher-level drivers
300       to write directly to the underlying terminal without worry that
301       there will be any retranslation done by the assorted drivers. Care
302       should be taken to ensure that this only gets called when the thing
303       written does not actually produce any output or a CONSOLE_Redraw()
304       is called immediately afterwards.
305       CONSOLE_Redraw() is not yet implemented.
306    */
307    fprintf(driver.console_out, "%s", str);
308 }
309
310 /* This function is only at the CONSOLE level. */
311 /* Admittably, calling the variable norefresh might be a bit dumb...*/
312 void CONSOLE_SetRefresh(int setting)
313 {
314    if (setting)
315       driver.norefresh = FALSE;
316    else
317       driver.norefresh = TRUE;
318 }
319
320 /* This function is only at the CONSOLE level. */
321 int CONSOLE_GetRefresh()
322 {
323    if (driver.norefresh)
324       return FALSE;
325    else 
326       return TRUE;
327 }
328
329
330 /* Utility functions... */
331
332 int pop_driver(char **drivers, char **single, int *length)
333 {
334    /* Take the string in drivers and extract the first "driver" entry */
335    /* Advance the pointer in drivers to the next entry, put the origional
336       pointer in single, and put the length in length. */
337    /* Return TRUE if we found one */
338
339    if (!*drivers)
340       return FALSE;
341
342    *single = *drivers;
343    *length = 0;
344
345    while ((*drivers[0] != '\0') && (*drivers[0] != '+'))
346    {
347       (*drivers)++;
348       (*length)++;
349    }
350    
351    while (*drivers[0] == '+')
352       (*drivers)++;
353
354    if (*length)
355       return TRUE;
356    else
357       return FALSE;
358       
359 }