source: trunk/src/msvcrt/console.c@ 10005

Last change on this file since 10005 was 10005, checked in by sandervl, 22 years ago

PF: MSVCRT update

File size: 6.7 KB
Line 
1/*
2 * msvcrt.dll console functions
3 *
4 * Copyright 2000 Jon Griffiths
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Note: init and free don't need MT locking since they are called at DLL
21 * (de)attachment time, which is syncronised for us
22 */
23#include "msvcrt.h"
24#include "wincon.h"
25
26#include "msvcrt/conio.h"
27#include "msvcrt/malloc.h"
28#include "msvcrt/stdio.h"
29#include "mtdll.h"
30
31#include <stdio.h>
32#include <string.h>
33
34#include "wine/debug.h"
35
36
37WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
38
39
40/* MT */
41#define LOCK_CONSOLE _mlock(_CONIO_LOCK)
42#define UNLOCK_CONSOLE _munlock(_CONIO_LOCK)
43
44static HANDLE MSVCRT_console_in = INVALID_HANDLE_VALUE;
45static HANDLE MSVCRT_console_out= INVALID_HANDLE_VALUE;
46static int __MSVCRT_console_buffer = MSVCRT_EOF;
47
48/* INTERNAL: Initialise console handles */
49void msvcrt_init_console(void)
50{
51 TRACE(":Opening console handles\n");
52
53 MSVCRT_console_in = GetStdHandle(STD_INPUT_HANDLE);
54
55 /* FIXME: Should be initialised with:
56 * CreateFileA("CONIN$", GENERIC_READ, FILE_SHARE_READ,
57 * NULL, OPEN_EXISTING, 0, (HANDLE)NULL);
58 */
59
60 MSVCRT_console_out= CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,
61 NULL, OPEN_EXISTING, 0, (HANDLE)NULL);
62
63 if ((MSVCRT_console_in == INVALID_HANDLE_VALUE) ||
64 (MSVCRT_console_out== INVALID_HANDLE_VALUE))
65 WARN(":Console handle Initialisation FAILED!\n");
66}
67
68/* INTERNAL: Free console handles */
69void msvcrt_free_console(void)
70{
71 TRACE(":Closing console handles\n");
72 CloseHandle(MSVCRT_console_in);
73 CloseHandle(MSVCRT_console_out);
74}
75
76/*********************************************************************
77 * _cputs (MSVCRT.@)
78 */
79int MSVCRT__cputs(const char* str)
80{
81 DWORD count;
82 int retval = MSVCRT_EOF;
83
84 LOCK_CONSOLE;
85 if (WriteConsoleA(MSVCRT_console_out, str, strlen(str), &count, NULL)
86 && count == 1)
87 retval = 0;
88 UNLOCK_CONSOLE;
89 return retval;
90}
91
92/*********************************************************************
93 * _getch (MSVCRT.@)
94 */
95int MSVCRT__getch(void)
96{
97 int retval = MSVCRT_EOF;
98
99 LOCK_CONSOLE;
100 if (__MSVCRT_console_buffer != MSVCRT_EOF)
101 {
102 retval = __MSVCRT_console_buffer;
103 __MSVCRT_console_buffer = MSVCRT_EOF;
104 }
105 else
106 {
107 INPUT_RECORD ir;
108 DWORD count;
109 DWORD mode = 0;
110
111 GetConsoleMode(MSVCRT_console_in, &mode);
112 if(mode)
113 SetConsoleMode(MSVCRT_console_in, 0);
114
115 do {
116 if (ReadConsoleInputA(MSVCRT_console_in, &ir, 1, &count))
117 {
118 /* Only interested in ASCII chars */
119 if (ir.EventType == KEY_EVENT &&
120 ir.Event.KeyEvent.bKeyDown &&
121 ir.Event.KeyEvent.uChar.AsciiChar)
122 {
123 retval = ir.Event.KeyEvent.uChar.AsciiChar;
124 break;
125 }
126 }
127 else
128 break;
129 } while(1);
130 if (mode)
131 SetConsoleMode(MSVCRT_console_in, mode);
132 }
133 UNLOCK_CONSOLE;
134 return retval;
135}
136
137/*********************************************************************
138 * _putch (MSVCRT.@)
139 */
140int MSVCRT__putch(int c)
141{
142 int retval = MSVCRT_EOF;
143 DWORD count;
144 LOCK_CONSOLE;
145 if (WriteConsoleA(MSVCRT_console_out, &c, 1, &count, NULL) && count == 1)
146 retval = c;
147 UNLOCK_CONSOLE;
148 return retval;
149}
150
151/*********************************************************************
152 * _getche (MSVCRT.@)
153 */
154int MSVCRT__getche(void)
155{
156 int retval;
157 LOCK_CONSOLE;
158 retval = MSVCRT__getch();
159 if (retval != MSVCRT_EOF)
160 retval = MSVCRT__putch(retval);
161 UNLOCK_CONSOLE;
162 return retval;
163}
164
165/*********************************************************************
166 * _cgets (MSVCRT.@)
167 */
168char* MSVCRT__cgets(char* str)
169{
170 char *buf = str + 2;
171 int c;
172 str[1] = 0; /* Length */
173 dprintf(("MSVCRT: _cgets"));
174 /* FIXME: No editing of string supported */
175 LOCK_CONSOLE;
176 do
177 {
178 if (str[1] >= str[0] || (str[1]++, c = MSVCRT__getche()) == MSVCRT_EOF || c == '\n')
179 break;
180 *buf++ = c & 0xff;
181 } while (1);
182 UNLOCK_CONSOLE;
183 *buf = '\0';
184 return str + 2;
185}
186
187/*********************************************************************
188 * _ungetch (MSVCRT.@)
189 */
190int MSVCRT__ungetch(int c)
191{
192 int retval = MSVCRT_EOF;
193 LOCK_CONSOLE;
194 if (c != MSVCRT_EOF && __MSVCRT_console_buffer == MSVCRT_EOF)
195 retval = __MSVCRT_console_buffer = c;
196 UNLOCK_CONSOLE;
197 return retval;
198}
199
200/*********************************************************************
201 * _kbhit (MSVCRT.@)
202 */
203int MSVCRT__kbhit(void)
204{
205 int retval = 0;
206 dprintf(("MSVCRT: kbhit()"));
207 LOCK_CONSOLE;
208 if (__MSVCRT_console_buffer != MSVCRT_EOF)
209 retval = 1;
210 else
211 {
212 /* FIXME: There has to be a faster way than this in Win32.. */
213 INPUT_RECORD *ir = NULL;
214 DWORD count = 0, i;
215
216 GetNumberOfConsoleInputEvents(MSVCRT_console_in, &count);
217
218 if (count && (ir = MSVCRT_malloc(count * sizeof(INPUT_RECORD))) &&
219 PeekConsoleInputA(MSVCRT_console_in, ir, count, &count))
220 for(i = 0; i < count - 1; i++)
221 {
222 if (ir[i].EventType == KEY_EVENT &&
223 ir[i].Event.KeyEvent.bKeyDown &&
224 ir[i].Event.KeyEvent.uChar.AsciiChar)
225 {
226 retval = 1;
227 break;
228 }
229 }
230 if (ir)
231 MSVCRT_free(ir);
232 }
233 UNLOCK_CONSOLE;
234 return retval;
235}
236
237
238/*********************************************************************
239 * _cprintf (MSVCRT.@)
240 */
241int MSVCRT__cprintf(const char* format, ...)
242{
243 char buf[2048], *mem = buf;
244 int written, resize = sizeof(buf), retval;
245 va_list valist;
246 dprintf(("MSVCRT: _cprintf %s",format));
247 va_start( valist, format );
248 /* There are two conventions for snprintf failing:
249 * Return -1 if we truncated, or
250 * Return the number of bytes that would have been written
251 * The code below handles both cases
252 */
253 while ((written = _snprintf( mem, resize, format, valist )) == -1 ||
254 written > resize)
255 {
256 resize = (written == -1 ? resize * 2 : written + 1);
257 if (mem != buf)
258 MSVCRT_free (mem);
259 if (!(mem = (char *)MSVCRT_malloc(resize)))
260 return MSVCRT_EOF;
261 va_start( valist, format );
262 }
263 va_end(valist);
264 LOCK_CONSOLE;
265 retval = MSVCRT__cputs( mem );
266 UNLOCK_CONSOLE;
267 if (mem != buf)
268 MSVCRT_free (mem);
269 return retval;
270}
Note: See TracBrowser for help on using the repository browser.