source: trunk/src/kernel32/conbuffervio.cpp@ 10010

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

DF: Console updates

File size: 12.6 KB
Line 
1/* $Id: conbuffervio.cpp,v 1.7 2003-04-11 12:08:35 sandervl Exp $ */
2
3/*
4 * Win32 Console API Translation for OS/2
5 *
6 * 1998/02/10 Patrick Haller (haller@zebra.fh-weingarten.de)
7 *
8 * @(#) console.cpp 1.0.0 1998/02/10 PH Start from scratch
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14
15#ifdef DEBUG
16#define DEBUG_LOCAL
17#define DEBUG_LOCAL2
18#endif
19
20//#undef DEBUG_LOCAL
21//#undef DEBUG_LOCAL2
22
23
24/*****************************************************************************
25 * Remark *
26 *****************************************************************************
27
28 - DWORD HandlerRoutine (DWORD dwCtrlType)
29 basically an exception handler routine. handles a few signals / excpts.
30 should be somewhere near the exception handling code ... :)
31
32 Hmm, however as PM applications don't really get a ctrl-c signal,
33 I'll have to do this on my own ...
34
35 - supply unicode<->ascii conversions for all the _A and _W function pairs.
36
37 - problem: we can't prevent thread1 from blocking the message queue ?
38 what will happen if a WinTerminate() is issued there ?
39 will the message queue be closed and provide smooth tasking ?
40 how will open32 react on this ?
41
42 - ECHO_LINE_INPUT / ReadFile blocks till CR
43
44 - scrollbars
45 * do some flowchart to exactly determine WHEN to use WHICH setting
46 and perform WHAT action
47
48 - clipboard support
49*/
50
51
52/*****************************************************************************
53 * Includes *
54 *****************************************************************************/
55
56#define INCL_WIN
57#define INCL_DOSMEMMGR
58#define INCL_DOSSEMAPHORES
59#define INCL_DOSERRORS
60#define INCL_DOSPROCESS
61#define INCL_DOSMODULEMGR
62#define INCL_VIO
63#define INCL_AVIO
64#include <os2wrap.h> //Odin32 OS/2 api wrappers
65
66#include <win32api.h>
67#include <misc.h>
68#include <string.h>
69#include <stdlib.h>
70#include <stdio.h>
71#include <malloc.h>
72
73#include "conwin.h" // Windows Header for console only
74#include "HandleManager.h"
75#include "HMDevice.h"
76#include "ConBuffervio.H"
77#include "Console2.h"
78#include <heapstring.h>
79
80#define DBG_LOCALLOG DBG_conbuffer
81#include "dbglocal.h"
82
83/*****************************************************************************
84 * Name :
85 * Purpose :
86 * Parameters:
87 * Variables :
88 * Result :
89 * Remark :
90 * Status :
91 *
92 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
93 *****************************************************************************/
94
95BOOL HMDeviceConsoleVioBufferClass::WriteFile(PHMHANDLEDATA pHMHandleData,
96 LPCVOID lpBuffer,
97 DWORD nNumberOfBytesToWrite,
98 LPDWORD lpNumberOfBytesWritten,
99 LPOVERLAPPED lpOverlapped,
100 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
101{
102 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
103 ULONG ulCounter; /* counter for the byte transfer */
104 PSZ pszBuffer;
105 char filler[4] = {' ', 0x07, ' ', 0x07};
106 register UCHAR ucChar;
107 APIRET rc;
108 ULONG Row;
109 USHORT Column;
110 int numchar;
111
112#ifdef DEBUG_LOCAL2
113 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleVioBufferClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",
114 lpHMDeviceName,
115 pHMHandleData->hHMHandle,
116 lpBuffer,
117 nNumberOfBytesToWrite,
118 lpNumberOfBytesWritten,
119 lpOverlapped);
120#endif
121
122 if(lpCompletionRoutine) {
123 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
124 }
125
126 /* check if we're called with non-existing line buffer */
127 if (pConsoleBuffer->ppszLine == NULL) {
128 SetLastError(ERROR_OUTOFMEMORY_W);
129 return FALSE;
130 }
131
132 dprintf(("Current cursor position (%d,%d)", pConsoleBuffer->coordCursorPosition.X, pConsoleBuffer->coordCursorPosition.Y));
133
134 if(nNumberOfBytesToWrite > 1024)
135 {
136 int tmp = 0;
137 BOOL retcode;
138
139 while(nNumberOfBytesToWrite) {
140 *lpNumberOfBytesWritten = 0;
141 retcode = WriteFile(pHMHandleData, lpBuffer,
142 min(nNumberOfBytesToWrite, 512), lpNumberOfBytesWritten,
143 lpOverlapped, lpCompletionRoutine);
144 if(retcode != TRUE) break;
145
146 tmp += *lpNumberOfBytesWritten;
147 nNumberOfBytesToWrite -= *lpNumberOfBytesWritten;
148 lpBuffer = (LPCVOID)((char *)lpBuffer + *lpNumberOfBytesWritten);
149 }
150 *lpNumberOfBytesWritten = tmp;
151 return retcode;
152 }
153 pszBuffer = (PSZ)alloca(nNumberOfBytesToWrite);
154 if(pszBuffer == NULL) {
155 DebugInt3();
156 return FALSE;
157 }
158 memcpy(pszBuffer, lpBuffer, nNumberOfBytesToWrite);
159
160 ulCounter = 0;
161 while(ulCounter < nNumberOfBytesToWrite)
162 {
163 ucChar = pszBuffer[ulCounter]; /* map to register */
164
165 if ( (pConsoleBuffer->dwConsoleMode & ENABLE_PROCESSED_OUTPUT) &&
166 (ucChar < 32) ) /* this is faster than a large switch statement */
167 {
168 switch (ucChar)
169 {
170 case 7: /* BEL */
171 if (pConsoleGlobals->Options.fSpeakerEnabled == TRUE)
172 DosBeep(pConsoleGlobals->Options.ulSpeakerFrequency,
173 pConsoleGlobals->Options.ulSpeakerDuration);
174 break;
175#if 0
176 case 8: /* Backspace */
177 // not correct if deleting expanded tab character
178 rc = VioGetCurPos(&Row, &Column, 0);
179 if(!rc) {
180
181 }
182 if (pConsoleBuffer->coordCursorPosition.X > 0)
183 pConsoleBuffer->coordCursorPosition.X--;
184
185 //@@@PH overwrite old character
186 *(pConsoleBuffer->ppszLine[pConsoleBuffer->coordCursorPosition.Y] +
187 pConsoleBuffer->coordCursorPosition.X * 2) = 0x20;
188 break;
189
190 case 9: /* Tab */
191 {
192 rc = VioWrite
193 pConsoleBuffer->coordCursorPosition.X =
194 (pConsoleBuffer->coordCursorPosition.X
195 / pConsoleGlobals->Options.ulTabSize
196 + 1)
197 * pConsoleGlobals->Options.ulTabSize;
198
199 if (pConsoleBuffer->coordCursorPosition.X >=
200 pConsoleBuffer->coordBufferSize.X)
201 {
202 pConsoleBuffer->coordCursorPosition.X = 0;
203 pConsoleBuffer->coordCursorPosition.Y++;
204
205 if (pConsoleBuffer->coordCursorPosition.Y >=
206 pConsoleBuffer->coordBufferSize.Y)
207 {
208 if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)
209 {
210 iConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */
211 1);
212 pConsoleBuffer->coordCursorPosition.Y--;
213 }
214 }
215 }
216 break;
217#endif
218 case 13: /* CARRIAGE RETURN */
219 dprintf(("CR"));
220 pConsoleBuffer->coordCursorPosition.X = 0;
221 VioSetCurPos(pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
222 break;
223
224 case 10: /* LINEFEED */
225 {
226 dprintf(("LF"));
227 pConsoleBuffer->coordCursorPosition.Y++;
228 pConsoleBuffer->coordCursorPosition.X = 0;
229 if(pConsoleBuffer->coordCursorPosition.Y >= pConsoleBuffer->coordWindowSize.Y) {
230 dprintf(("scrollup"));
231 VioScrollUp(0, 0, pConsoleBuffer->coordWindowSize.Y-1, pConsoleBuffer->coordWindowSize.X-1,
232 1, &filler[0], 0);
233 pConsoleBuffer->coordCursorPosition.Y = pConsoleBuffer->coordWindowSize.Y-1;
234 }
235 VioSetCurPos(pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
236 break;
237 }
238 default:
239 break;
240 }
241 ulCounter++;
242 }
243 else
244 {
245//// dprintf(("Current cursor position (%d,%d)", pConsoleBuffer->coordCursorPosition.X, pConsoleBuffer->coordCursorPosition.Y));
246 numchar = ulCounter;
247 while(pszBuffer[numchar] >= 32 && numchar < nNumberOfBytesToWrite) {
248 numchar++;
249 }
250 numchar = numchar - ulCounter;
251
252 if(pConsoleBuffer->coordCursorPosition.X + numchar > pConsoleBuffer->coordWindowSize.X)
253 {
254 int tmp = pConsoleBuffer->coordWindowSize.X - pConsoleBuffer->coordCursorPosition.X;
255
256 VioWrtCharStr(&pszBuffer[ulCounter], tmp, pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
257 ulCounter += tmp;
258 numchar -= tmp;
259
260 pConsoleBuffer->coordCursorPosition.X = 0;
261 pConsoleBuffer->coordCursorPosition.Y++;
262 if(pConsoleBuffer->coordCursorPosition.Y >= pConsoleBuffer->coordWindowSize.Y) {
263 dprintf(("scrollup"));
264 VioScrollUp(0, 0, pConsoleBuffer->coordWindowSize.Y-1, pConsoleBuffer->coordWindowSize.X-1,
265 1, &filler[0], 0);
266 pConsoleBuffer->coordCursorPosition.Y = pConsoleBuffer->coordWindowSize.Y-1;
267 }
268 VioWrtCharStr(&pszBuffer[ulCounter], numchar, pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
269 pConsoleBuffer->coordCursorPosition.X += numchar;
270 VioSetCurPos(pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
271 }
272 else {
273 VioWrtCharStr(&pszBuffer[ulCounter], numchar, pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
274 pConsoleBuffer->coordCursorPosition.X += numchar;
275 VioSetCurPos(pConsoleBuffer->coordCursorPosition.Y, pConsoleBuffer->coordCursorPosition.X, 0);
276 }
277 ulCounter += numchar;
278 }
279 }
280
281 *lpNumberOfBytesWritten = ulCounter;
282
283 return TRUE;
284}
285
286DWORD HMDeviceConsoleVioBufferClass::FillConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
287 WORD wAttribute,
288 DWORD nLength,
289 COORD dwWriteCoord,
290 LPDWORD lpNumberOfAttrsWritten)
291{
292 APIRET rc;
293
294#ifdef DEBUG_LOCAL2
295 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleVioBufferClass::FillConsoleOutputAttribute(%08x,attr=%04x,%u,x=%u y=%u,res=%08x).\n",
296 pHMHandleData,
297 wAttribute,
298 nLength,
299 dwWriteCoord.X,
300 dwWriteCoord.Y,
301 lpNumberOfAttrsWritten);
302#endif
303
304 if (HMDeviceConsoleBufferClass::FillConsoleOutputAttribute(pHMHandleData,
305 wAttribute,
306 nLength,
307 dwWriteCoord,
308 lpNumberOfAttrsWritten))
309 {
310 rc = VioWrtNAttr((PBYTE)&wAttribute, *lpNumberOfAttrsWritten, dwWriteCoord.Y, dwWriteCoord.X,
311 0);
312 if (rc == NO_ERROR)
313 {
314 return TRUE;
315 } else
316 {
317 return FALSE;
318 }
319 } else
320 return FALSE;
321}
322
323DWORD HMDeviceConsoleVioBufferClass::FillConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
324 UCHAR ucCharacter,
325 DWORD nLength,
326 COORD dwWriteCoord,
327 LPDWORD lpNumberOfCharsWritten)
328{
329 APIRET rc;
330
331#ifdef DEBUG_LOCAL2
332 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleVioBufferClass::FillConsoleOutputCharacterA(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",
333 pHMHandleData,
334 ucCharacter,
335 nLength,
336 dwWriteCoord.X,
337 dwWriteCoord.Y,
338 lpNumberOfCharsWritten);
339#endif
340 if (HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA(pHMHandleData,
341 ucCharacter,
342 nLength,
343 dwWriteCoord,
344 lpNumberOfCharsWritten))
345 {
346 rc = VioWrtNChar((PCH)&ucCharacter, *lpNumberOfCharsWritten, dwWriteCoord.Y, dwWriteCoord.X,
347 0);
348 if (rc == NO_ERROR)
349 {
350 return TRUE;
351 } else
352 {
353 return FALSE;
354 }
355 } else
356 return FALSE;
357}
358
Note: See TracBrowser for help on using the repository browser.