source: trunk/src/kernel32/conbuffer.cpp@ 5120

Last change on this file since 5120 was 4525, checked in by sandervl, 25 years ago

lstrcpynAtoW/WtoA fixes (Wine depends on 0 terminating of these functions) + console changes for methods that depended on the old behaviour

File size: 110.4 KB
Line 
1/* $Id: conbuffer.cpp,v 1.14 2000-10-23 19:35:09 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
71#include "conwin.h" // Windows Header for console only
72#include "HandleManager.h"
73#include "HMDevice.h"
74#include "ConBuffer.H"
75#include "console.h"
76#include "Console2.h"
77#include <heapstring.h>
78
79#define DBG_LOCALLOG DBG_conbuffer
80#include "dbglocal.h"
81
82
83/*****************************************************************************
84 * Name : DWORD HMDeviceConsoleBufferClass::CreateFile
85 * Purpose : this is called from the handle manager if a CreateFile() is
86 * performed on a handle
87 * Parameters: LPCSTR lpFileName name of the file / device
88 * PHMHANDLEDATA pHMHandleData data of the NEW handle
89 * PVOID lpSecurityAttributes ignored
90 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
91 * Variables :
92 * Result :
93 * Remark :
94 * Status : NO_ERROR - API succeeded
95 * other - what is to be set in SetLastError
96 *
97 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
98 *****************************************************************************/
99
100DWORD HMDeviceConsoleBufferClass::CreateFile (LPCSTR lpFileName,
101 PHMHANDLEDATA pHMHandleData,
102 PVOID lpSecurityAttributes,
103 PHMHANDLEDATA pHMHandleDataTemplate)
104{
105 PCONSOLEBUFFER pConsoleBuffer; /* console buffer structure */
106
107#ifdef DEBUG_LOCAL
108 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass %s(%s,%08x,%08x,%08x)\n",
109 lpHMDeviceName,
110 lpFileName,
111 pHMHandleData->hHMHandle,
112 lpSecurityAttributes,
113 pHMHandleDataTemplate);
114#endif
115
116 pHMHandleData->dwType = FILE_TYPE_CHAR; /* we're a character device */
117
118 pHMHandleData->lpHandlerData = malloc ( sizeof(CONSOLEBUFFER) );
119
120#ifdef DEBUG_LOCAL
121 WriteLog("KERNEL32/CONSOLE:CheckPoint1: %s pHMHandleData=%08xh, lpHandlerData=%08xh\n",
122 lpFileName,
123 pHMHandleData,
124 pHMHandleData->lpHandlerData);
125#endif
126
127
128 if (pHMHandleData->lpHandlerData == NULL) /* check allocation */
129 {
130 SetLastError(ERROR_NOT_ENOUGH_MEMORY_W); /* set error information */
131 return (INVALID_HANDLE_VALUE); /* raise error condition */
132 }
133 else
134 {
135 pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
136
137 memset(pHMHandleData->lpHandlerData, /* initialize structure */
138 0,
139 sizeof (CONSOLEBUFFER) );
140
141 /* set buffer defaults */
142 pConsoleBuffer->dwConsoleMode = ENABLE_PROCESSED_OUTPUT |
143 ENABLE_WRAP_AT_EOL_OUTPUT;
144
145 pConsoleBuffer->CursorInfo.dwSize = 20; /* 20% cell height */
146 pConsoleBuffer->CursorInfo.bVisible = TRUE;
147 }
148
149 return(NO_ERROR);
150}
151
152
153/*****************************************************************************
154 * Name :
155 * Purpose :
156 * Parameters:
157 * Variables :
158 * Result :
159 * Remark :
160 * Status :
161 *
162 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
163 *****************************************************************************/
164
165DWORD HMDeviceConsoleBufferClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
166{
167
168#ifdef DEBUG_LOCAL
169 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass::CloseHandle %s(%08x)\n",
170 lpHMDeviceName,
171 pHMHandleData);
172#endif
173
174 if (pHMHandleData->lpHandlerData != NULL) /* check pointer */
175 {
176 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
177
178
179 if (pConsoleBuffer->ppszLine != NULL) /* free line buffer array ! */
180 free (pConsoleBuffer->ppszLine);
181
182 free (pHMHandleData->lpHandlerData); /* free device object data */
183 pHMHandleData->lpHandlerData = NULL;
184 }
185
186 return(NO_ERROR);
187}
188
189
190/*****************************************************************************
191 * Name :
192 * Purpose :
193 * Parameters:
194 * Variables :
195 * Result :
196 * Remark :
197 * Status :
198 *
199 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
200 *****************************************************************************/
201
202BOOL HMDeviceConsoleBufferClass::ReadFile(PHMHANDLEDATA pHMHandleData,
203 LPCVOID lpBuffer,
204 DWORD nNumberOfBytesToRead,
205 LPDWORD lpNumberOfBytesRead,
206 LPOVERLAPPED lpOverlapped)
207{
208
209#ifdef DEBUG_LOCAL
210 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",
211 lpHMDeviceName,
212 pHMHandleData->hHMHandle,
213 lpBuffer,
214 nNumberOfBytesToRead,
215 lpNumberOfBytesRead,
216 lpOverlapped);
217#endif
218
219 SetLastError(ERROR_ACCESS_DENIED_W);
220 return FALSE;
221}
222
223
224/*****************************************************************************
225 * Name :
226 * Purpose :
227 * Parameters:
228 * Variables :
229 * Result :
230 * Remark :
231 * Status :
232 *
233 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
234 *****************************************************************************/
235
236BOOL HMDeviceConsoleBufferClass::WriteFile(PHMHANDLEDATA pHMHandleData,
237 LPCVOID lpBuffer,
238 DWORD nNumberOfBytesToWrite,
239 LPDWORD lpNumberOfBytesWritten,
240 LPOVERLAPPED lpOverlapped)
241{
242 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
243 ULONG ulCounter; /* counter for the byte transfer */
244 PSZ pszBuffer = (PSZ)lpBuffer;
245 register UCHAR ucChar;
246
247#ifdef DEBUG_LOCAL2
248 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",
249 lpHMDeviceName,
250 pHMHandleData->hHMHandle,
251 lpBuffer,
252 nNumberOfBytesToWrite,
253 lpNumberOfBytesWritten,
254 lpOverlapped);
255#endif
256
257 /* check if we're called with non-existing line buffer */
258 if (pConsoleBuffer->ppszLine == NULL) {
259 SetLastError(ERROR_OUTOFMEMORY_W);
260 return FALSE;
261 }
262 for (ulCounter = 0;
263 ulCounter < nNumberOfBytesToWrite;
264 ulCounter++)
265 {
266 ucChar = pszBuffer[ulCounter]; /* map to register */
267
268 if ( (pConsoleBuffer->dwConsoleMode & ENABLE_PROCESSED_OUTPUT) &&
269 (ucChar < 32) ) /* this is faster than a large switch statement */
270 {
271 switch (ucChar)
272 {
273 case 7: /* BEL */
274 if (pConsoleGlobals->Options.fSpeakerEnabled == TRUE)
275 DosBeep(pConsoleGlobals->Options.ulSpeakerFrequency,
276 pConsoleGlobals->Options.ulSpeakerDuration);
277 break;
278
279 case 8: /* Backspace */
280 // not correct if deleting expanded tab character
281 if (pConsoleBuffer->coordCursorPosition.X > 0)
282 pConsoleBuffer->coordCursorPosition.X--;
283
284 //@@@PH overwrite old character
285 *(pConsoleBuffer->ppszLine[pConsoleBuffer->coordCursorPosition.Y] +
286 pConsoleBuffer->coordCursorPosition.X * 2) = 0x20;
287 break;
288
289 case 9: /* Tab */
290 pConsoleBuffer->coordCursorPosition.X =
291 (pConsoleBuffer->coordCursorPosition.X
292 / pConsoleGlobals->Options.ulTabSize
293 + 1)
294 * pConsoleGlobals->Options.ulTabSize;
295
296 if (pConsoleBuffer->coordCursorPosition.X >=
297 pConsoleBuffer->coordBufferSize.X)
298 {
299 pConsoleBuffer->coordCursorPosition.X = 0;
300 pConsoleBuffer->coordCursorPosition.Y++;
301
302 if (pConsoleBuffer->coordCursorPosition.Y >=
303 pConsoleBuffer->coordBufferSize.Y)
304 {
305 if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)
306 {
307 iConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */
308 1);
309 pConsoleBuffer->coordCursorPosition.Y--;
310 }
311 }
312 }
313 break;
314
315 case 13: /* CARRIAGE RETURN */
316 pConsoleBuffer->coordCursorPosition.X = 0;
317 break;
318
319 case 10: /* LINEFEED */
320 pConsoleBuffer->coordCursorPosition.Y++;
321
322 if (pConsoleBuffer->coordCursorPosition.Y >=
323 pConsoleBuffer->coordBufferSize.Y)
324 {
325 iConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */
326 1);
327 pConsoleBuffer->coordCursorPosition.Y--;
328 }
329 break;
330
331 default:
332 break;
333 }
334 }
335 else
336 {
337 /* write character */
338 *(pConsoleBuffer->ppszLine[pConsoleBuffer->coordCursorPosition.Y] +
339 pConsoleBuffer->coordCursorPosition.X * 2) = ucChar;
340
341 pConsoleBuffer->coordCursorPosition.X++;
342
343 if (pConsoleBuffer->coordCursorPosition.X >=
344 pConsoleBuffer->coordBufferSize.X)
345 {
346 pConsoleBuffer->coordCursorPosition.X = 0;
347 pConsoleBuffer->coordCursorPosition.Y++;
348
349 if (pConsoleBuffer->coordCursorPosition.Y >=
350 pConsoleBuffer->coordBufferSize.Y)
351 {
352 if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)
353 {
354 iConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */
355 1);
356 pConsoleBuffer->coordCursorPosition.Y--;
357 }
358 else
359 {
360 /* just stay on last character */
361 pConsoleBuffer->coordCursorPosition.X = pConsoleBuffer->coordBufferSize.X - 1;
362 pConsoleBuffer->coordCursorPosition.Y = pConsoleBuffer->coordBufferSize.Y - 1;
363 }
364 }
365 }
366 }
367 }
368
369 /* update screen if active console */
370 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
371 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
372
373 *lpNumberOfBytesWritten = ulCounter;
374
375 return TRUE;
376}
377
378
379/*****************************************************************************
380 * Name :
381 * Purpose :
382 * Parameters:
383 * Variables :
384 * Result :
385 * Remark :
386 * Status :
387 *
388 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
389 *****************************************************************************/
390
391DWORD HMDeviceConsoleBufferClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,
392 ULONG ulRequestCode,
393 ULONG arg1,
394 ULONG arg2,
395 ULONG arg3,
396 ULONG arg4)
397{
398 switch (ulRequestCode)
399 {
400 case DRQ_FILLCONSOLEOUTPUTATTRIBUTE:
401 {
402 COORD coordWrite;
403
404 ULONG2COORD(coordWrite,arg3);
405
406 return (HMDeviceConsoleBufferClass
407 ::FillConsoleOutputAttribute(pHMHandleData,
408 (WORD)arg1,
409 (DWORD)arg2,
410 coordWrite,
411 (LPDWORD)arg4));
412 }
413
414
415 case DRQ_FILLCONSOLEOUTPUTCHARACTERA:
416 {
417 COORD coordWrite;
418
419 ULONG2COORD(coordWrite,arg3);
420
421 return (HMDeviceConsoleBufferClass
422 ::FillConsoleOutputCharacterA(pHMHandleData,
423 (UCHAR)arg1,
424 (DWORD)arg2,
425 coordWrite,
426 (LPDWORD)arg4));
427 }
428
429
430 case DRQ_FILLCONSOLEOUTPUTCHARACTERW:
431 {
432 COORD coordWrite;
433
434 ULONG2COORD(coordWrite,arg3);
435
436 return (HMDeviceConsoleBufferClass
437 ::FillConsoleOutputCharacterW(pHMHandleData,
438 (WCHAR)arg1,
439 (DWORD)arg2,
440 coordWrite,
441 (LPDWORD)arg4));
442 }
443
444
445 case DRQ_GETCONSOLECURSORINFO:
446 return (HMDeviceConsoleBufferClass
447 ::GetConsoleCursorInfo(pHMHandleData,
448 (PCONSOLE_CURSOR_INFO)arg1));
449
450
451 case DRQ_GETCONSOLEMODE:
452 return (HMDeviceConsoleBufferClass
453 ::GetConsoleMode(pHMHandleData,
454 (LPDWORD)arg1));
455
456
457 case DRQ_GETCONSOLESCREENBUFFERINFO:
458 return (HMDeviceConsoleBufferClass
459 ::GetConsoleScreenBufferInfo(pHMHandleData,
460 (PCONSOLE_SCREEN_BUFFER_INFO)arg1));
461
462
463 case DRQ_GETLARGESTCONSOLEWINDOWSIZE:
464 return (HMDeviceConsoleBufferClass
465 ::GetLargestConsoleWindowSize(pHMHandleData));
466
467
468 case DRQ_READCONSOLEOUTPUTA:
469 {
470 COORD coordDestBufferSize;
471 COORD coordDestBufferCoord;
472
473 ULONG2COORD(coordDestBufferSize, arg2);
474 ULONG2COORD(coordDestBufferCoord, arg3);
475
476 return (HMDeviceConsoleBufferClass
477 ::ReadConsoleOutputA(pHMHandleData,
478 (PCHAR_INFO)arg1,
479 coordDestBufferSize,
480 coordDestBufferCoord,
481 (PSMALL_RECT)arg4));
482 }
483
484
485 case DRQ_READCONSOLEOUTPUTW:
486 {
487 COORD coordDestBufferSize;
488 COORD coordDestBufferCoord;
489
490 ULONG2COORD(coordDestBufferSize, arg2);
491 ULONG2COORD(coordDestBufferCoord, arg3);
492
493 return (HMDeviceConsoleBufferClass
494 ::ReadConsoleOutputW(pHMHandleData,
495 (PCHAR_INFO)arg1,
496 coordDestBufferSize,
497 coordDestBufferCoord,
498 (PSMALL_RECT)arg4));
499 }
500
501
502 case DRQ_READCONSOLEOUTPUTATTRIBUTE:
503 {
504 COORD coordReadCoord;
505
506 ULONG2COORD(coordReadCoord, arg3);
507
508 return (HMDeviceConsoleBufferClass
509 ::ReadConsoleOutputAttribute(pHMHandleData,
510 (LPWORD)arg1,
511 (DWORD)arg2,
512 coordReadCoord,
513 (LPDWORD)arg4));
514 }
515
516
517 case DRQ_READCONSOLEOUTPUTCHARACTERA:
518 {
519 COORD coordReadCoord;
520
521 ULONG2COORD(coordReadCoord, arg3);
522
523 return (HMDeviceConsoleBufferClass
524 ::ReadConsoleOutputCharacterA(pHMHandleData,
525 (LPTSTR)arg1,
526 (DWORD)arg2,
527 coordReadCoord,
528 (LPDWORD)arg4));
529 }
530
531
532 case DRQ_READCONSOLEOUTPUTCHARACTERW:
533 {
534 COORD coordReadCoord;
535
536 ULONG2COORD(coordReadCoord, arg3);
537
538 return (HMDeviceConsoleBufferClass
539 ::ReadConsoleOutputCharacterW(pHMHandleData,
540 (LPWSTR)arg1,
541 (DWORD)arg2,
542 coordReadCoord,
543 (LPDWORD)arg4));
544 }
545
546
547 case DRQ_SCROLLCONSOLESCREENBUFFERA:
548 {
549 COORD coordDestOrigin;
550
551 ULONG2COORD(coordDestOrigin, arg3);
552
553 return (HMDeviceConsoleBufferClass
554 ::ScrollConsoleScreenBufferA(pHMHandleData,
555 (PSMALL_RECT)arg1,
556 (PSMALL_RECT)arg2,
557 coordDestOrigin,
558 (PCHAR_INFO)arg4));
559 }
560
561
562 case DRQ_SCROLLCONSOLESCREENBUFFERW:
563 {
564 COORD coordDestOrigin;
565
566 ULONG2COORD(coordDestOrigin, arg3);
567
568 return (HMDeviceConsoleBufferClass
569 ::ScrollConsoleScreenBufferW(pHMHandleData,
570 (PSMALL_RECT)arg1,
571 (PSMALL_RECT)arg2,
572 coordDestOrigin,
573 (PCHAR_INFO)arg4));
574 }
575
576
577 case DRQ_SETCONSOLEACTIVESCREENBUFFER:
578 return (HMDeviceConsoleBufferClass
579 ::SetConsoleActiveScreenBuffer(pHMHandleData));
580
581
582 case DRQ_SETCONSOLECURSORINFO:
583 return (HMDeviceConsoleBufferClass
584 ::SetConsoleCursorInfo(pHMHandleData,
585 (PCONSOLE_CURSOR_INFO)arg1));
586
587
588 case DRQ_SETCONSOLECURSORPOSITION:
589 {
590 COORD coordCursor;
591
592 ULONG2COORD(coordCursor, arg1);
593
594 return (HMDeviceConsoleBufferClass
595 ::SetConsoleCursorPosition(pHMHandleData,
596 coordCursor));
597 }
598
599
600 case DRQ_SETCONSOLEMODE:
601 return (HMDeviceConsoleBufferClass
602 ::SetConsoleMode(pHMHandleData,
603 (DWORD)arg1));
604
605
606 case DRQ_SETCONSOLESCREENBUFFERSIZE:
607 {
608 COORD coordSize;
609
610 ULONG2COORD(coordSize,arg1);
611
612 return (HMDeviceConsoleBufferClass::
613 SetConsoleScreenBufferSize(pHMHandleData,
614 coordSize));
615 }
616
617
618 case DRQ_SETCONSOLETEXTATTRIBUTE:
619 return (HMDeviceConsoleBufferClass::
620 SetConsoleTextAttribute(pHMHandleData,
621 (WORD)arg1));
622
623
624 case DRQ_SETCONSOLEWINDOWINFO:
625 return (HMDeviceConsoleBufferClass
626 ::SetConsoleWindowInfo(pHMHandleData,
627 (BOOL)arg1,
628 (PSMALL_RECT)arg2));
629
630
631 case DRQ_WRITECONSOLEA:
632 return (HMDeviceConsoleBufferClass
633 ::WriteConsoleA(pHMHandleData,
634 (CONST VOID*)arg1,
635 (DWORD)arg2,
636 (LPDWORD)arg3,
637 (LPVOID)arg4));
638
639
640 case DRQ_WRITECONSOLEW:
641 return (HMDeviceConsoleBufferClass
642 ::WriteConsoleW(pHMHandleData,
643 (CONST VOID*)arg1,
644 (DWORD)arg2,
645 (LPDWORD)arg3,
646 (LPVOID)arg4));
647
648
649 case DRQ_WRITECONSOLEOUTPUTA:
650 {
651 COORD coordSrcBufferSize;
652 COORD coordSrcBufferCoord;
653
654 ULONG2COORD(coordSrcBufferSize, arg2);
655 ULONG2COORD(coordSrcBufferCoord, arg3);
656
657 return (HMDeviceConsoleBufferClass
658 ::WriteConsoleOutputA(pHMHandleData,
659 (PCHAR_INFO)arg1,
660 coordSrcBufferSize,
661 coordSrcBufferCoord,
662 (PSMALL_RECT)arg4));
663 }
664
665
666 case DRQ_WRITECONSOLEOUTPUTW:
667 {
668 COORD coordSrcBufferSize;
669 COORD coordSrcBufferCoord;
670
671 ULONG2COORD(coordSrcBufferSize, arg2);
672 ULONG2COORD(coordSrcBufferCoord, arg3);
673
674 return (HMDeviceConsoleBufferClass
675 ::WriteConsoleOutputA(pHMHandleData,
676 (PCHAR_INFO)arg1,
677 coordSrcBufferSize,
678 coordSrcBufferCoord,
679 (PSMALL_RECT)arg4));
680 }
681
682
683 case DRQ_WRITECONSOLEOUTPUTATTRIBUTE:
684 {
685 COORD coordWriteCoord;
686
687 ULONG2COORD(coordWriteCoord, arg3);
688
689 return (HMDeviceConsoleBufferClass
690 ::WriteConsoleOutputAttribute(pHMHandleData,
691 (LPWORD)arg1,
692 (DWORD)arg2,
693 coordWriteCoord,
694 (LPDWORD)arg4));
695 }
696
697
698 case DRQ_WRITECONSOLEOUTPUTCHARACTERA:
699 {
700 COORD coordWriteCoord;
701
702 ULONG2COORD(coordWriteCoord, arg3);
703
704 return (HMDeviceConsoleBufferClass
705 ::WriteConsoleOutputCharacterA(pHMHandleData,
706 (LPTSTR)arg1,
707 (DWORD)arg2,
708 coordWriteCoord,
709 (LPDWORD)arg4));
710 }
711
712
713 case DRQ_WRITECONSOLEOUTPUTCHARACTERW:
714 {
715 COORD coordWriteCoord;
716
717 ULONG2COORD(coordWriteCoord, arg3);
718
719 return (HMDeviceConsoleBufferClass
720 ::WriteConsoleOutputCharacterW(pHMHandleData,
721 (LPWSTR)arg1,
722 (DWORD)arg2,
723 coordWriteCoord,
724 (LPDWORD)arg4));
725 }
726
727
728 case DRQ_INTERNAL_CONSOLEBUFFERMAP:
729 iConsoleBufferMap((PCONSOLEBUFFER)pHMHandleData->lpHandlerData);
730 return (NO_ERROR);
731
732
733 case DRQ_INTERNAL_CONSOLECURSORSHOW:
734 iConsoleCursorShow((PCONSOLEBUFFER)pHMHandleData->lpHandlerData,
735 (ULONG)arg1);
736 return (NO_ERROR);
737
738
739 case DRQ_INTERNAL_CONSOLEADJUSTWINDOW:
740 iConsoleAdjustWindow((PCONSOLEBUFFER)pHMHandleData->lpHandlerData);
741 return (NO_ERROR);
742 }
743
744
745#ifdef DEBUG_LOCAL
746 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x) unknown request\n",
747 lpHMDeviceName,
748 pHMHandleData->hHMHandle,
749 ulRequestCode,
750 arg1,
751 arg2,
752 arg3,
753 arg4);
754#endif
755
756 SetLastError(ERROR_INVALID_FUNCTION_W); /* request not implemented */
757 return(FALSE); /* we assume this indicates API call failed */
758}
759
760
761/*****************************************************************************
762 * Name : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputAttribute
763 * Purpose : fills the console buffer with a specified attribute
764 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
765 * WORD wAttribute
766 * DWORD nLength
767 * COORD dwWriteCoord
768 * LPDWORD lpNumberOfAttrsWritten
769 * Variables :
770 * Result :
771 * Remark :
772 * Status : UNTESTED
773 *
774 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
775 *****************************************************************************/
776
777DWORD HMDeviceConsoleBufferClass::FillConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
778 WORD wAttribute,
779 DWORD nLength,
780 COORD dwWriteCoord,
781 LPDWORD lpNumberOfAttrsWritten)
782{
783 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
784 ULONG ulCounter; /* current character counter */
785
786#ifdef DEBUG_LOCAL2
787 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputAttribute(%08x,attr=%04x,%u,x=%u y=%u,res=%08x).\n",
788 pHMHandleData,
789 wAttribute,
790 nLength,
791 dwWriteCoord.X,
792 dwWriteCoord.Y,
793 lpNumberOfAttrsWritten);
794#endif
795
796 if ( (dwWriteCoord.X < 0) ||
797 (dwWriteCoord.Y < 0) )
798 {
799 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */
800 *lpNumberOfAttrsWritten = 0; /* complete error handling */
801
802 SetLastError(ERROR_INVALID_PARAMETER_W);
803 return (FALSE);
804 }
805
806 /* check if dwWriteCoord is within specs */
807 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
808 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
809 {
810 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */
811 *lpNumberOfAttrsWritten = 0; /* complete error handling */
812
813 SetLastError(ERROR_INVALID_PARAMETER_W);
814 return (FALSE);
815 }
816
817
818 /* OK, now write the attribute lines */
819 for (ulCounter = 0;
820 ulCounter < nLength;
821 ulCounter++)
822 {
823 /* write attribute into cell */
824 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
825 (dwWriteCoord.X * 2 + 1)
826 ) = (UCHAR)(wAttribute & 0xFF);
827 /* write attribute, don't change characters */
828
829 dwWriteCoord.X++; /* move write position */
830 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
831 {
832 dwWriteCoord.X = 0; /* skip to next line */
833 dwWriteCoord.Y++;
834
835 /* oops, we're at the end of the buffer. Abort now. */
836 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
837 {
838 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */
839 *lpNumberOfAttrsWritten = ulCounter;
840
841 /* update screen if active console */
842 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
843 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
844
845 return (TRUE);
846 }
847 }
848 }
849
850 /* update screen if active console */
851 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
852 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
853
854 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */
855 *lpNumberOfAttrsWritten = nLength;
856
857 return (TRUE);
858}
859
860
861/*****************************************************************************
862 * Name : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA
863 * Purpose : fills the console buffer with a specified ASCII character
864 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
865 * UCHAR ucCharacter
866 * DWORD nLength
867 * COORD dwWriteCoord
868 * LPDWORD lpNumberOfCharsWritten
869 * Variables :
870 * Result :
871 * Remark :
872 * Status : UNTESTED
873 *
874 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
875 *****************************************************************************/
876
877DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
878 UCHAR ucCharacter,
879 DWORD nLength,
880 COORD dwWriteCoord,
881 LPDWORD lpNumberOfCharsWritten)
882{
883 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
884 ULONG ulCounter; /* current character counter */
885
886#ifdef DEBUG_LOCAL2
887 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputCharacterA(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",
888 pHMHandleData,
889 ucCharacter,
890 nLength,
891 dwWriteCoord.X,
892 dwWriteCoord.Y,
893 lpNumberOfCharsWritten);
894#endif
895
896 if ( (dwWriteCoord.X < 0) ||
897 (dwWriteCoord.Y < 0) )
898 {
899 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
900 *lpNumberOfCharsWritten = 0; /* complete error handling */
901
902 SetLastError(ERROR_INVALID_PARAMETER_W);
903 return (FALSE);
904 }
905
906
907 /* check if dwWriteCoord is within specs */
908 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
909 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
910 {
911 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
912 *lpNumberOfCharsWritten = 0; /* complete error handling */
913
914 SetLastError(ERROR_INVALID_PARAMETER_W);
915 return (FALSE);
916 }
917
918
919 /* OK, now write the attribute lines */
920 for (ulCounter = 0;
921 ulCounter < nLength;
922 ulCounter++)
923 {
924 /* write character into cell */
925 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
926 (dwWriteCoord.X * 2)
927 ) = ucCharacter;
928
929 dwWriteCoord.X++; /* move write position */
930 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
931 {
932 dwWriteCoord.X = 0; /* skip to next line */
933 dwWriteCoord.Y++;
934
935 /* oops, we're at the end of the buffer. Abort now. */
936 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
937 {
938 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
939 *lpNumberOfCharsWritten = ulCounter;
940
941 /* update screen if active console */
942 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
943 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
944
945 return (TRUE);
946 }
947 }
948 }
949
950 /* update screen if active console */
951 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
952 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
953
954 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
955 *lpNumberOfCharsWritten = nLength;
956
957 return (TRUE);
958}
959
960
961/*****************************************************************************
962 * Name : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterW
963 * Purpose : fills the console buffer with a specified ASCII character
964 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
965 * WCHAR wcCharacter
966 * DWORD nLength
967 * COORD dwWriteCoord
968 * LPDWORD lpNumberOfCharsWritten
969 * Variables :
970 * Result :
971 * Remark :
972 * Status : UNTESTED
973 *
974 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
975 *****************************************************************************/
976
977DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
978 WCHAR wcCharacter,
979 DWORD nLength,
980 COORD dwWriteCoord,
981 LPDWORD lpNumberOfCharsWritten)
982{
983 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
984 ULONG ulCounter; /* current character counter */
985
986#ifdef DEBUG_LOCAL2
987 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputCharacterW(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",
988 pHMHandleData,
989 wcCharacter,
990 nLength,
991 dwWriteCoord.X,
992 dwWriteCoord.Y,
993 lpNumberOfCharsWritten);
994#endif
995
996 if ( (dwWriteCoord.X < 0) ||
997 (dwWriteCoord.Y < 0) )
998 {
999 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
1000 *lpNumberOfCharsWritten = 0; /* complete error handling */
1001
1002 SetLastError(ERROR_INVALID_PARAMETER_W);
1003 return (FALSE);
1004 }
1005
1006
1007 /* check if dwWriteCoord is within specs */
1008 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
1009 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
1010 {
1011 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
1012 *lpNumberOfCharsWritten = 0; /* complete error handling */
1013
1014 SetLastError(ERROR_INVALID_PARAMETER_W);
1015 return (FALSE);
1016 }
1017
1018
1019 /* OK, now write the attribute lines */
1020 for (ulCounter = 0;
1021 ulCounter < nLength;
1022 ulCounter++)
1023 {
1024 /* write character into cell */
1025 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
1026 (dwWriteCoord.X * 2)
1027 ) = (UCHAR)wcCharacter; /* @@@PH unicode to ascii conversion ! */
1028
1029 dwWriteCoord.X++; /* move write position */
1030 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
1031 {
1032 dwWriteCoord.X = 0; /* skip to next line */
1033 dwWriteCoord.Y++;
1034
1035 /* oops, we're at the end of the buffer. Abort now. */
1036 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
1037 {
1038 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
1039 *lpNumberOfCharsWritten = ulCounter;
1040
1041 /* update screen if active console */
1042 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
1043 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
1044
1045 return (TRUE);
1046 }
1047 }
1048 }
1049
1050 /* update screen if active console */
1051 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
1052 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
1053
1054 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */
1055 *lpNumberOfCharsWritten = nLength;
1056
1057 return (TRUE);
1058}
1059
1060
1061
1062/*****************************************************************************
1063 * Name : DWORD HMDeviceConsoleBufferClass::GetConsoleMode
1064 * Purpose : queries the current console mode
1065 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1066 * LPDWORD lpMode
1067 * Variables :
1068 * Result :
1069 * Remark :
1070 * Status : UNTESTED
1071 *
1072 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1073 *****************************************************************************/
1074
1075DWORD HMDeviceConsoleBufferClass::GetConsoleMode(PHMHANDLEDATA pHMHandleData,
1076 LPDWORD lpMode)
1077{
1078 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1079
1080#ifdef DEBUG_LOCAL2
1081 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleMode(%08x,%08x).\n",
1082 pHMHandleData,
1083 lpMode);
1084#endif
1085
1086 *lpMode = pConsoleBuffer->dwConsoleMode; /* return current console mode */
1087
1088 return (TRUE);
1089}
1090
1091
1092/*****************************************************************************
1093 * Name : DWORD HMDeviceConsoleBufferClass::GetConsoleCursorInfo
1094 * Purpose : queries the current console's cursor information
1095 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1096 * PCONSOLE_CURSOR_INFO pCCI
1097 * Variables :
1098 * Result :
1099 * Remark :
1100 * Status : UNTESTED
1101 *
1102 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1103 *****************************************************************************/
1104
1105DWORD HMDeviceConsoleBufferClass::GetConsoleCursorInfo(PHMHANDLEDATA pHMHandleData,
1106 PCONSOLE_CURSOR_INFO pCCI)
1107{
1108 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1109
1110#ifdef DEBUG_LOCAL2
1111 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleCursorInfo(%08x,%08x).\n",
1112 pHMHandleData,
1113 pCCI);
1114#endif
1115
1116 memcpy(pCCI, /* just copy the whole information block */
1117 &pConsoleBuffer->CursorInfo,
1118 sizeof (pConsoleBuffer->CursorInfo) );
1119
1120 return (TRUE);
1121}
1122
1123
1124/*****************************************************************************
1125 * Name : DWORD HMDeviceConsoleBufferClass::GetConsoleScreenBufferInfo
1126 * Purpose : queries the current console screen buffer's info
1127 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1128 * PCONSOLE_SCREEN_BUFFER_INFO pCSBI
1129 * Variables :
1130 * Result :
1131 * Remark :
1132 * Status : UNTESTED
1133 *
1134 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1135 *****************************************************************************/
1136
1137DWORD HMDeviceConsoleBufferClass::GetConsoleScreenBufferInfo(PHMHANDLEDATA pHMHandleData,
1138 PCONSOLE_SCREEN_BUFFER_INFO pCSBI)
1139{
1140 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1141
1142#ifdef DEBUG_LOCAL2
1143 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleScreenBufferInfo(%08x,%08x).\n",
1144 pHMHandleData,
1145 pCSBI);
1146#endif
1147
1148 pCSBI->dwSize = pConsoleBuffer->coordBufferSize;
1149 pCSBI->dwCursorPosition = pConsoleBuffer->coordCursorPosition;
1150 pCSBI->wAttributes = (USHORT)pConsoleBuffer->ucDefaultAttribute;
1151
1152 /* @@@PH unsure, but should be OK */
1153 pCSBI->srWindow.Left = pConsoleBuffer->coordWindowPosition.X;
1154 pCSBI->srWindow.Top = pConsoleBuffer->coordWindowPosition.Y;
1155 pCSBI->srWindow.Right = pConsoleBuffer->coordWindowPosition.X +
1156 pConsoleBuffer->coordWindowSize.X - 1;
1157 pCSBI->srWindow.Bottom = pConsoleBuffer->coordWindowPosition.Y +
1158 pConsoleBuffer->coordWindowSize.Y - 1;
1159
1160 pCSBI->dwMaximumWindowSize = pConsoleBuffer->coordBufferSize;
1161
1162 return (TRUE);
1163}
1164
1165
1166/*****************************************************************************
1167 * Name : DWORD HMDeviceConsoleBufferClass::GetLargestConsoleWindowSize
1168 * Purpose : Determine maximum AVIO size
1169 * Parameters:
1170 * Variables :
1171 * Result :
1172 * Remark :
1173 * Status :
1174 *
1175 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
1176 *****************************************************************************/
1177
1178DWORD HMDeviceConsoleBufferClass::GetLargestConsoleWindowSize(PHMHANDLEDATA pHMHandleData)
1179{
1180 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1181 COORD coordSize; /* maximum avio size */
1182 LONG lScreenCX; /* width and height of display */
1183 LONG lScreenCY;
1184 APIRET rc; /* API returncode */
1185
1186
1187#ifdef DEBUG_LOCAL
1188 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetLargestConsoleWindowSize(%08x).\n",
1189 pHMHandleData);
1190#endif
1191
1192 /* @@@PH determine maximum console window size in characters
1193 based on display size and current avio font */
1194
1195 lScreenCX = WinQuerySysValue(HWND_DESKTOP, /* query PM for that */
1196 SV_CXSCREEN);
1197
1198 lScreenCY = WinQuerySysValue(HWND_DESKTOP, /* query PM for that */
1199 SV_CYFULLSCREEN);
1200
1201 if (rc != NO_ERROR)
1202 {
1203 WriteLog("KERNEL32/CONSOLE: VioGetDeviceCellSize failed with #%u.\n",
1204 rc);
1205
1206 return (FALSE); /* say API failed */
1207 }
1208
1209 if ( (pConsoleGlobals->sCellCX == 0) || /* prevent division by zero */
1210 (pConsoleGlobals->sCellCY == 0) )
1211 {
1212 WriteLog("KERNEL32/CONSOLE: VioGetDeviceCellSize returned 0 value.\n");
1213
1214 return (FALSE); /* say API failed */
1215 }
1216
1217 coordSize.X = lScreenCX / pConsoleGlobals->sCellCX; /* calculate */
1218 coordSize.Y = lScreenCY / pConsoleGlobals->sCellCY;
1219
1220 /* these limitations are due to OS/2's current VIO subsystem */
1221 coordSize.X = min(coordSize.X, MAX_OS2_COLUMNS);
1222 coordSize.Y = min(coordSize.Y, MAX_OS2_ROWS);
1223
1224 return (COORD2ULONG(coordSize)); /* return value */
1225}
1226
1227
1228/*****************************************************************************
1229 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputA
1230 * Purpose : reads character and color attribute data from screen rectangle
1231 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1232 * PCHAR_INFO pchiDestBuffer
1233 * COORD coordDestBufferSize
1234 * COORD coordDestBufferCoord
1235 * PSMALL_RECT psrctSourceRect
1236 * Variables :
1237 * Result :
1238 * Remark :
1239 * Status : UNTESTED
1240 *
1241 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1242 *****************************************************************************/
1243
1244DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputA(PHMHANDLEDATA pHMHandleData,
1245 PCHAR_INFO pchiDestBuffer,
1246 COORD coordDestBufferSize,
1247 COORD coordDestBufferCoord,
1248 PSMALL_RECT psrctSourceRect)
1249{
1250 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1251 ULONG ulX, ulY; /* current coordinate to be read */
1252 ULONG ulCX, ulCY; /* width and height of target area */
1253 ULONG ulReadX, ulReadY; /* position data is read from */
1254 WORD wCell; /* currently read data */
1255
1256 PCHAR_INFO pchi;
1257
1258#ifdef DEBUG_LOCAL2
1259 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
1260 pHMHandleData,
1261 pchiDestBuffer,
1262 coordDestBufferSize.X,
1263 coordDestBufferSize.Y,
1264 coordDestBufferCoord.X,
1265 coordDestBufferCoord.Y,
1266 psrctSourceRect);
1267#endif
1268
1269
1270 /* verify psrctSourceRect first */
1271 psrctSourceRect->Left = max(psrctSourceRect->Left, 0);
1272 psrctSourceRect->Top = max(psrctSourceRect->Top, 0);
1273 psrctSourceRect->Right = min(psrctSourceRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
1274 psrctSourceRect->Bottom= min(psrctSourceRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
1275
1276 /* verify target buffer */
1277 if ( (coordDestBufferSize.X < coordDestBufferCoord.X) ||
1278 (coordDestBufferSize.Y < coordDestBufferCoord.Y) )
1279 {
1280 SetLastError(ERROR_INVALID_PARAMETER_W); /* set detailed error info */
1281 return (FALSE); /* API failed */
1282 }
1283
1284 ulCX = coordDestBufferSize.X - coordDestBufferCoord.X;
1285 ulCY = coordDestBufferSize.Y - coordDestBufferCoord.Y;
1286
1287 ulCX = min(ulCX, (psrctSourceRect->Right - psrctSourceRect->Left));
1288 ulCY = min(ulCY, (psrctSourceRect->Bottom - psrctSourceRect->Top));
1289
1290 /* final calculation of the copy rectangle */
1291 psrctSourceRect->Right = psrctSourceRect->Left + ulCX;
1292 psrctSourceRect->Bottom = psrctSourceRect->Top + ulCY;
1293
1294
1295 for (ulY = 0,
1296 ulReadY = psrctSourceRect->Top;
1297
1298 ulY <= ulCY;
1299
1300 ulY++,
1301 ulReadY++)
1302 {
1303 pchi = pchiDestBuffer + sizeof(CHAR_INFO) * coordDestBufferCoord.X
1304 + sizeof(CHAR_INFO) * (coordDestBufferCoord.Y + ulY)
1305 * coordDestBufferSize.X;
1306 for (ulX = 0,
1307 ulReadX = psrctSourceRect->Left;
1308
1309 ulX <= ulCX;
1310
1311 ulX++,
1312 ulReadX++,
1313 pchi++)
1314 {
1315 /* read character */
1316 wCell = *(pConsoleBuffer->ppszLine[ulReadY] + ulReadX * 2);
1317
1318 pchi->Char.AsciiChar = (UCHAR)(wCell & 0x00FF);
1319 pchi->Attributes = wCell >> 8;
1320 }
1321 }
1322
1323 return (TRUE); /* OK, that's it */
1324}
1325
1326
1327/*****************************************************************************
1328 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputW
1329 * Purpose : reads character and color attribute data from screen rectangle
1330 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1331 * PCHAR_INFO pchiDestBuffer
1332 * COORD coordDestBufferSize
1333 * COORD coordDestBufferCoord
1334 * PSMALL_RECT psrctSourceRect
1335 * Variables :
1336 * Result :
1337 * Remark :
1338 * Status : UNTESTED
1339 *
1340 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1341 *****************************************************************************/
1342
1343DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputW(PHMHANDLEDATA pHMHandleData,
1344 PCHAR_INFO pchiDestBuffer,
1345 COORD coordDestBufferSize,
1346 COORD coordDestBufferCoord,
1347 PSMALL_RECT psrctSourceRect)
1348{
1349 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1350 ULONG ulX, ulY; /* current coordinate to be read */
1351 ULONG ulCX, ulCY; /* width and height of target area */
1352 ULONG ulReadX, ulReadY; /* position data is read from */
1353 WORD wCell; /* currently read data */
1354
1355 PCHAR_INFO pchi;
1356
1357#ifdef DEBUG_LOCAL2
1358 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
1359 pHMHandleData,
1360 pchiDestBuffer,
1361 coordDestBufferSize.X,
1362 coordDestBufferSize.Y,
1363 coordDestBufferCoord.X,
1364 coordDestBufferCoord.Y,
1365 psrctSourceRect);
1366#endif
1367
1368
1369 /* verify psrctSourceRect first */
1370 psrctSourceRect->Left = max(psrctSourceRect->Left, 0);
1371 psrctSourceRect->Top = max(psrctSourceRect->Top, 0);
1372 psrctSourceRect->Right = min(psrctSourceRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
1373 psrctSourceRect->Bottom= min(psrctSourceRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
1374
1375 /* verify target buffer */
1376 if ( (coordDestBufferSize.X < coordDestBufferCoord.X) ||
1377 (coordDestBufferSize.Y < coordDestBufferCoord.Y) )
1378 {
1379 SetLastError(ERROR_INVALID_PARAMETER_W); /* set detailed error info */
1380 return (FALSE); /* API failed */
1381 }
1382
1383 ulCX = coordDestBufferSize.X - coordDestBufferCoord.X;
1384 ulCY = coordDestBufferSize.Y - coordDestBufferCoord.Y;
1385
1386 ulCX = min(ulCX, (psrctSourceRect->Right - psrctSourceRect->Left));
1387 ulCY = min(ulCY, (psrctSourceRect->Bottom - psrctSourceRect->Top));
1388
1389 /* final calculation of the copy rectangle */
1390 psrctSourceRect->Right = psrctSourceRect->Left + ulCX;
1391 psrctSourceRect->Bottom = psrctSourceRect->Top + ulCY;
1392
1393
1394 for (ulY = 0,
1395 ulReadY = psrctSourceRect->Top;
1396
1397 ulY <= ulCY;
1398
1399 ulY++,
1400 ulReadY++)
1401 {
1402 pchi = pchiDestBuffer + sizeof(CHAR_INFO) * coordDestBufferCoord.X
1403 + sizeof(CHAR_INFO) * (coordDestBufferCoord.Y + ulY)
1404 * coordDestBufferSize.X;
1405 for (ulX = 0,
1406 ulReadX = psrctSourceRect->Left;
1407
1408 ulX <= ulCX;
1409
1410 ulX++,
1411 ulReadX++,
1412 pchi++)
1413 {
1414 /* read character */
1415 wCell = *(pConsoleBuffer->ppszLine[ulReadY] + ulReadX * 2);
1416
1417 /* @@@PH Ascii->Unicode */
1418 pchi->Char.UnicodeChar = (UCHAR)(wCell & 0x00FF);
1419 pchi->Attributes = wCell >> 8;
1420 }
1421 }
1422
1423 return (TRUE); /* OK, that's it */
1424}
1425
1426
1427/*****************************************************************************
1428 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputAttribute
1429 * Purpose : read an array with specified attributes from the console
1430 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1431 * LPWORD lpwAttribute
1432 * DWORD cReadCells
1433 * COORD dwReadCoord
1434 * LPDWORD lpcNumberRead
1435 * Variables :
1436 * Result :
1437 * Remark :
1438 * Status : UNTESTED
1439 *
1440 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1441 *****************************************************************************/
1442
1443DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
1444 LPWORD lpwAttribute,
1445 DWORD cReadCells,
1446 COORD dwReadCoord,
1447 LPDWORD lpcNumberRead)
1448{
1449 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1450 ULONG ulCounter; /* current character counter */
1451
1452#ifdef DEBUG_LOCAL2
1453 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
1454 pHMHandleData,
1455 lpwAttribute,
1456 cReadCells,
1457 dwReadCoord.X,
1458 dwReadCoord.Y,
1459 lpcNumberRead);
1460#endif
1461
1462 if ( (dwReadCoord.X < 0) ||
1463 (dwReadCoord.Y < 0) )
1464 {
1465 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1466 *lpcNumberRead = 0; /* complete error handling */
1467
1468 SetLastError(ERROR_INVALID_PARAMETER_W);
1469 return (FALSE);
1470 }
1471
1472 /* check if dwReadCoord is within specs */
1473 if ( (dwReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
1474 (dwReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
1475 {
1476 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1477 *lpcNumberRead = 0; /* complete error handling */
1478
1479 SetLastError(ERROR_INVALID_PARAMETER_W);
1480 return (FALSE);
1481 }
1482
1483
1484 /* OK, now write the attribute lines */
1485 for (ulCounter = 0;
1486 ulCounter < cReadCells;
1487 ulCounter++,
1488 lpwAttribute++)
1489 {
1490 /* write attribute into cell */
1491 *lpwAttribute = (UCHAR)
1492 *(pConsoleBuffer->ppszLine[dwReadCoord.Y] +
1493 (dwReadCoord.X * 2 + 1));
1494
1495 dwReadCoord.X++; /* move write position */
1496 if (dwReadCoord.X >= pConsoleBuffer->coordBufferSize.X)
1497 {
1498 dwReadCoord.X = 0; /* skip to next line */
1499 dwReadCoord.Y++;
1500
1501 /* oops, we're at the end of the buffer. Abort now. */
1502 if (dwReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
1503 {
1504 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1505 *lpcNumberRead = ulCounter;
1506
1507 return (TRUE);
1508 }
1509 }
1510 }
1511
1512 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1513 *lpcNumberRead = cReadCells;
1514
1515 return (TRUE);
1516}
1517
1518
1519/*****************************************************************************
1520 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterA
1521 * Purpose : read an array with specified characters from the console
1522 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1523 * LPWORD lpReadBuffer
1524 * DWORD cRead
1525 * COORD coordReadCoord
1526 * LPDWORD lpcNumberRead
1527 * Variables :
1528 * Result :
1529 * Remark :
1530 * Status : UNTESTED
1531 *
1532 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1533 *****************************************************************************/
1534
1535DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
1536 LPTSTR lpwReadBuffer,
1537 DWORD cchRead,
1538 COORD coordReadCoord,
1539 LPDWORD lpcNumberRead)
1540{
1541 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1542 ULONG ulCounter; /* current character counter */
1543
1544#ifdef DEBUG_LOCAL2
1545 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputCharacterA(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
1546 pHMHandleData,
1547 lpwReadBuffer,
1548 cchRead,
1549 coordReadCoord.X,
1550 coordReadCoord.Y,
1551 lpcNumberRead);
1552#endif
1553
1554 if ( (coordReadCoord.X < 0) ||
1555 (coordReadCoord.Y < 0) )
1556 {
1557 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1558 *lpcNumberRead = 0; /* complete error handling */
1559
1560 SetLastError(ERROR_INVALID_PARAMETER_W);
1561 return (FALSE);
1562 }
1563
1564 /* check if coordReadCoord is within specs */
1565 if ( (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
1566 (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
1567 {
1568 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1569 *lpcNumberRead = 0; /* complete error handling */
1570
1571 SetLastError(ERROR_INVALID_PARAMETER_W);
1572 return (FALSE);
1573 }
1574
1575
1576 /* OK, now write the attribute lines */
1577 for (ulCounter = 0;
1578 ulCounter < cchRead;
1579 ulCounter++,
1580 lpwReadBuffer++)
1581 {
1582 /* write character into cell */
1583 *lpwReadBuffer =
1584 *(pConsoleBuffer->ppszLine[coordReadCoord.Y] +
1585 (coordReadCoord.X * 2));
1586
1587 coordReadCoord.X++; /* move write position */
1588 if (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X)
1589 {
1590 coordReadCoord.X = 0; /* skip to next line */
1591 coordReadCoord.Y++;
1592
1593 /* oops, we're at the end of the buffer. Abort now. */
1594 if (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
1595 {
1596 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1597 *lpcNumberRead = ulCounter;
1598
1599 return (TRUE);
1600 }
1601 }
1602 }
1603
1604 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1605 *lpcNumberRead = cchRead;
1606
1607 return (TRUE);
1608}
1609
1610
1611/*****************************************************************************
1612 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterW
1613 * Purpose : read an array with specified characters from the console
1614 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1615 * LPWORD lpReadBuffer
1616 * DWORD cRead
1617 * COORD coordReadCoord
1618 * LPDWORD lpcNumberRead
1619 * Variables :
1620 * Result :
1621 * Remark :
1622 * Status : UNTESTED
1623 *
1624 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1625 *****************************************************************************/
1626
1627DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
1628 LPWSTR lpwReadBuffer,
1629 DWORD cchRead,
1630 COORD coordReadCoord,
1631 LPDWORD lpcNumberRead)
1632{
1633 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1634 ULONG ulCounter; /* current character counter */
1635
1636#ifdef DEBUG_LOCAL2
1637 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputCharacterW(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
1638 pHMHandleData,
1639 lpwReadBuffer,
1640 cchRead,
1641 coordReadCoord.X,
1642 coordReadCoord.Y,
1643 lpcNumberRead);
1644#endif
1645
1646 if ( (coordReadCoord.X < 0) ||
1647 (coordReadCoord.Y < 0) )
1648 {
1649 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1650 *lpcNumberRead = 0; /* complete error handling */
1651
1652 SetLastError(ERROR_INVALID_PARAMETER_W);
1653 return (FALSE);
1654 }
1655
1656 /* check if coordReadCoord is within specs */
1657 if ( (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
1658 (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
1659 {
1660 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1661 *lpcNumberRead = 0; /* complete error handling */
1662
1663 SetLastError(ERROR_INVALID_PARAMETER_W);
1664 return (FALSE);
1665 }
1666
1667
1668 /* OK, now write the attribute lines */
1669 for (ulCounter = 0;
1670 ulCounter < cchRead;
1671 ulCounter++,
1672 lpwReadBuffer++)
1673 {
1674 /* @@@PH Ascii -> Unicode translation */
1675 /* write character into cell */
1676 *lpwReadBuffer =
1677 *(pConsoleBuffer->ppszLine[coordReadCoord.Y] +
1678 (coordReadCoord.X * 2));
1679
1680 coordReadCoord.X++; /* move write position */
1681 if (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X)
1682 {
1683 coordReadCoord.X = 0; /* skip to next line */
1684 coordReadCoord.Y++;
1685
1686 /* oops, we're at the end of the buffer. Abort now. */
1687 if (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
1688 {
1689 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1690 *lpcNumberRead = ulCounter;
1691
1692 return (TRUE);
1693 }
1694 }
1695 }
1696
1697 if (lpcNumberRead != NULL) /* ensure pointer is valid */
1698 *lpcNumberRead = cchRead;
1699
1700 return (TRUE);
1701}
1702
1703
1704/*****************************************************************************
1705 * Name : DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferA
1706 * Purpose : move a block of data within the screen buffer
1707 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1708 * PSMALL_RECT psrctSourceRect - source rectangle
1709 * PSMALL_RECT psrctClipRect - clipping rectangle
1710 * COORD coordDestOrigin - destination coordinate
1711 * PCHAR_INFO pchiFill - fill character
1712 * Variables :
1713 * Result :
1714 * Remark : Routine is subject to optimizations.
1715 * @@@PH rewrite -> faster, better handling of overlapped buffers
1716 * copy srctSource to buffer, fill it with fill character
1717 * copy buffer to srctDest ?
1718 * Status : UNTESTED
1719 *
1720 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1721 *****************************************************************************/
1722
1723DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferA(PHMHANDLEDATA pHMHandleData,
1724 PSMALL_RECT psrctSourceRect,
1725 PSMALL_RECT psrctClipRect,
1726 COORD coordDestOrigin,
1727 PCHAR_INFO pchiFill)
1728{
1729 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1730 SMALL_RECT srctView; /* the actual rectangle of "happening" */
1731 SMALL_RECT srctSource; /* the clipped source and dest rectangles */
1732 SMALL_RECT srctDest;
1733 int iX, iY; /* scan loop counters */
1734 PUSHORT pusTarget, pusSource; /* pointer to source, dest cells */
1735 WORD wAttr; /* fill character and attribute */
1736 int iBlitDirection; /* to handle overlapped buffers */
1737
1738#ifdef DEBUG_LOCAL2
1739 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ScrollConsoleScreenBufferA(%08x,%08x,%08x,x=%u y=%u,%08x).\n",
1740 pHMHandleData,
1741 psrctSourceRect,
1742 psrctClipRect,
1743 coordDestOrigin.X,
1744 coordDestOrigin.Y,
1745 pchiFill);
1746#endif
1747
1748 /* calculate effective clipping rectangle */
1749 if (psrctClipRect != NULL) /* if clipping rectangle was specified */
1750 {
1751 memcpy(&srctView,
1752 psrctClipRect,
1753 sizeof (SMALL_RECT) );
1754
1755 /* check boundary with buffer size */
1756 srctView.Left = max(0, srctView.Left);
1757 srctView.Top = max(0, srctView.Top );
1758 srctView.Right = min(srctView.Right, pConsoleBuffer->coordBufferSize.X);
1759 srctView.Bottom = min(srctView.Bottom, pConsoleBuffer->coordBufferSize.Y);
1760 }
1761 else
1762 {
1763 srctView.Left = 0; /* buffer size is the maximum clipping rectangle */
1764 srctView.Top = 0;
1765 srctView.Right = pConsoleBuffer->coordBufferSize.X;
1766 srctView.Bottom = pConsoleBuffer->coordBufferSize.Y;
1767 }
1768
1769 memcpy(&srctSource, /* copy source rectangle */
1770 psrctSourceRect,
1771 sizeof (srctSource) );
1772 /* check boundary with clipping rectangle */
1773 srctSource.Left = max(srctSource.Left, srctView.Left );
1774 srctSource.Top = max(srctSource.Top, srctView.Top );
1775 srctSource.Right = min(srctSource.Right, srctView.Right );
1776 srctSource.Bottom = min(srctSource.Bottom,srctView.Bottom);
1777
1778 srctDest.Left = max(srctView.Left, coordDestOrigin.X);
1779 srctDest.Top = max(srctView.Top, coordDestOrigin.Y);
1780 srctDest.Right = min(srctView.Right, srctDest.Left + srctSource.Right - srctSource.Left);
1781 srctDest.Bottom= min(srctView.Bottom, srctDest.Top + srctSource.Bottom - srctSource.Top);
1782
1783 /****************************
1784 * first copy the rectangle *
1785 ****************************/
1786
1787 if (srctDest.Left > srctSource.Left) iBlitDirection = 0;
1788 else iBlitDirection = 1;
1789 if (srctDest.Top > srctSource.Top) iBlitDirection += 2;
1790
1791 /* this leaves us with three different cases: */
1792 /* */
1793 /* 0 - dest is to upper left of the source */
1794 /* 1 - dest is to upper right of the source */
1795 /* 2 - dest is to lower left of the source */
1796 /* 3 - dest is to lower right of the source */
1797
1798 switch (iBlitDirection)
1799 {
1800 /**************
1801 * upper left *
1802 **************/
1803 case 0:
1804 for (iY = 0;
1805 iY < srctDest.Bottom - srctDest.Top;
1806 iY++)
1807 {
1808 /* calculate pointer to start of target screen line */
1809 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
1810 (srctDest.Left << 1) );
1811
1812 /* calculate pointer to start of source screen line */
1813 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
1814 (srctSource.Left << 1) );
1815
1816 for (iX = srctDest.Left;
1817 iX <= srctDest.Right;
1818 iX++,
1819 pusTarget++,
1820 pusSource++)
1821 *pusTarget = *pusSource; /* copy character */
1822 }
1823 break;
1824
1825 /***************
1826 * upper right *
1827 ***************/
1828 case 1:
1829 for (iY = 0;
1830 iY < srctDest.Bottom - srctDest.Top;
1831 iY++)
1832 {
1833 /* calculate pointer to end of target screen line */
1834 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
1835 ( srctDest.Right << 1) );
1836
1837 /* calculate pointer to end of source screen line */
1838 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
1839 ( srctSource.Right << 1) );
1840
1841 for (iX = srctDest.Right;
1842 iX >= srctDest.Left;
1843 iX--,
1844 pusTarget--,
1845 pusSource--)
1846 *pusTarget = *pusSource; /* copy character */
1847 }
1848 break;
1849
1850 /***************
1851 * lower left *
1852 ***************/
1853 case 2:
1854 for (iY = srctDest.Bottom - srctDest.Top - 1;
1855 iY >= 0;
1856 iY--)
1857 {
1858 /* calculate pointer to start of target screen line */
1859 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
1860 (srctDest.Left << 1) );
1861
1862 /* calculate pointer to start of source screen line */
1863 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
1864 (srctSource.Left << 1) );
1865
1866 for (iX = srctDest.Left;
1867 iX <= srctDest.Right;
1868 iX++,
1869 pusTarget++,
1870 pusSource++)
1871 *pusTarget = *pusSource; /* copy character */
1872 }
1873 break;
1874
1875 /****************
1876 * lower right *
1877 ****************/
1878 case 3:
1879 for (iY = srctDest.Bottom - srctDest.Top - 1;
1880 iY >= 0;
1881 iY--)
1882 {
1883 /* calculate pointer to end of target screen line */
1884 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
1885 ( srctDest.Right << 1) );
1886
1887 /* calculate pointer to end of source screen line */
1888 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
1889 (srctSource.Right << 1) );
1890
1891 for (iX = srctDest.Right;
1892 iX >= srctDest.Left;
1893 iX--,
1894 pusTarget--,
1895 pusSource--)
1896 *pusTarget = *pusSource; /* copy character */
1897 }
1898 break;
1899 }
1900
1901
1902 /* this is the character and attribute for the uncovered cells */
1903 wAttr = (pchiFill->Char.AsciiChar) + (pchiFill->Attributes << 8);
1904
1905 for (iY = srctSource.Top; /* now fill uncovered area with pchi */
1906 iY < srctSource.Bottom;
1907 iY++)
1908 {
1909 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY] + srctSource.Left);
1910
1911 for (iX = srctSource.Left;
1912 iX < srctSource.Right;
1913 iX++,
1914 pusTarget++)
1915 /* check if covered by srctDest or not */
1916 if ( (iY >= srctDest.Top) &&
1917 (iY <= srctDest.Bottom) &&
1918 (iX >= srctDest.Left) &&
1919 (iX <= srctDest.Right)
1920 )
1921 ; /* should be faster for the optimizer */
1922 else
1923 *pusTarget = wAttr; /* write fill character and attribute */
1924 }
1925
1926 /* update screen if active console */
1927 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
1928 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
1929
1930 return (TRUE);
1931}
1932
1933
1934/*****************************************************************************
1935 * Name : DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferW
1936 * Purpose : move a block of data within the screen buffer
1937
1938
1939 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
1940 * PSMALL_RECT psrctSourceRect - source rectangle
1941 * PSMALL_RECT psrctClipRect - clipping rectangle
1942 * COORD coordDestOrigin - destination coordinate
1943 * PCHAR_INFO pchiFill - fill character
1944 * Variables :
1945 * Result :
1946 * Remark : Routine is subject to optimizations.
1947 * Status : UNTESTED
1948 *
1949 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
1950 *****************************************************************************/
1951
1952DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferW(PHMHANDLEDATA pHMHandleData,
1953 PSMALL_RECT psrctSourceRect,
1954 PSMALL_RECT psrctClipRect,
1955 COORD coordDestOrigin,
1956 PCHAR_INFO pchiFill)
1957{
1958 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
1959 SMALL_RECT srctView; /* the actual rectangle of "happening" */
1960 SMALL_RECT srctSource; /* the clipped source and dest rectangles */
1961 SMALL_RECT srctDest;
1962 ULONG ulX, ulY; /* scan loop counters */
1963 PUSHORT pusTarget, pusSource; /* pointer to source, dest cells */
1964 WORD wAttr; /* fill character and attribute */
1965
1966#ifdef DEBUG_LOCAL2
1967 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ScrollConsoleScreenBufferW(%08x,%08x,%08x,x=%u y=%u,%08x).\n",
1968 pHMHandleData,
1969 psrctSourceRect,
1970 psrctClipRect,
1971 coordDestOrigin.X,
1972 coordDestOrigin.Y,
1973 pchiFill);
1974#endif
1975
1976 /* calculate effective clipping rectangle */
1977 if (psrctClipRect != NULL) /* if clipping rectangle was specified */
1978 {
1979 memcpy(&srctView,
1980 psrctClipRect,
1981 sizeof (SMALL_RECT) );
1982
1983 /* check boundary with buffer size */
1984 srctView.Left = max(0, srctView.Left);
1985 srctView.Top = max(0, srctView.Top );
1986 srctView.Right = min(srctView.Right, pConsoleBuffer->coordBufferSize.X);
1987 srctView.Bottom = min(srctView.Bottom, pConsoleBuffer->coordBufferSize.Y);
1988 }
1989 else
1990 {
1991 srctView.Left = 0; /* buffer size is the maximum clipping rectangle */
1992 srctView.Top = 0;
1993 srctView.Right = pConsoleBuffer->coordBufferSize.X;
1994 srctView.Bottom = pConsoleBuffer->coordBufferSize.Y;
1995 }
1996
1997 memcpy(&srctSource, /* copy source rectangle */
1998 psrctSourceRect,
1999 sizeof (srctSource) );
2000 /* check boundary with clipping rectangle */
2001 srctSource.Left = max(srctSource.Left, srctView.Left );
2002 srctSource.Top = max(srctSource.Top, srctView.Top );
2003 srctSource.Right = min(srctSource.Right, srctView.Right );
2004 srctSource.Bottom = min(srctSource.Bottom,srctView.Bottom);
2005
2006 srctDest.Left = max(srctView.Left, coordDestOrigin.X);
2007 srctDest.Top = max(srctView.Top, coordDestOrigin.Y);
2008 srctDest.Right = min(srctView.Right, srctDest.Left + srctSource.Right - srctSource.Left);
2009 srctDest.Bottom= min(srctView.Bottom, srctDest.Top + srctSource.Bottom - srctSource.Top);
2010
2011 /* first copy the rectangle */
2012 for (ulY = 0;
2013 ulY < srctDest.Bottom - srctDest.Top;
2014 ulY++)
2015 {
2016 /* calculate pointer to start of target screen line */
2017 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[ulY + srctDest.Top] +
2018 srctDest.Left);
2019
2020 /* calculate pointer to start of source screen line */
2021 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[ulY + srctSource.Top] +
2022 srctSource.Left);
2023
2024 for (ulX = srctDest.Left;
2025 ulX < srctDest.Right;
2026 ulX++,
2027 pusTarget++,
2028 pusSource++)
2029 *pusTarget = *pusSource; /* copy character */
2030 }
2031
2032
2033 /* this is the character and attribute for the uncovered cells */
2034 /* @@@PH Unicode->Ascii translation */
2035 wAttr = (pchiFill->Char.UnicodeChar) + (pchiFill->Attributes << 8);
2036
2037 for (ulY = srctSource.Top; /* now fill uncovered area with pchi */
2038 ulY < srctSource.Bottom;
2039 ulY++)
2040 {
2041 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[ulY] + srctSource.Left);
2042
2043 for (ulX = srctSource.Left;
2044 ulX < srctSource.Right;
2045 ulX++,
2046 pusTarget++)
2047 *pusTarget = wAttr; /* write fill character and attribute */
2048 }
2049
2050 /* update screen if active console */
2051 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2052 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2053
2054 return (TRUE);
2055}
2056
2057
2058/*****************************************************************************
2059 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleCursorInfo
2060 * Purpose : sets the current console's cursor information
2061 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2062 * PCONSOLE_CURSOR_INFO pCCI
2063 * Variables :
2064 * Result :
2065 * Remark :
2066 * Status : UNTESTED
2067 *
2068 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2069 *****************************************************************************/
2070
2071DWORD HMDeviceConsoleBufferClass::SetConsoleCursorInfo(PHMHANDLEDATA pHMHandleData,
2072 PCONSOLE_CURSOR_INFO pCCI)
2073{
2074 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2075
2076#ifdef DEBUG_LOCAL2
2077 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleCursorInfo(%08x,%08x).\n",
2078 pHMHandleData,
2079 pCCI);
2080#endif
2081
2082 /* validate structure */
2083 if ( (pCCI->dwSize < 1) ||
2084 (pCCI->dwSize > 100) )
2085 {
2086 SetLastError(ERROR_INVALID_PARAMETER_W); /* set extended error info */
2087 return (FALSE); /* API failed */
2088 }
2089
2090 /* if we're the active buffer, remove cursor from screen first */
2091 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2092 iConsoleCursorShow(pConsoleBuffer,
2093 CONSOLECURSOR_HIDE);
2094
2095 memcpy(&pConsoleBuffer->CursorInfo, /* copy the whole information block */
2096 pCCI,
2097 sizeof (pConsoleBuffer->CursorInfo) );
2098
2099 return (TRUE);
2100}
2101
2102
2103/*****************************************************************************
2104 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleCursorPosition
2105 * Purpose : sets the current console's cursor position
2106 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2107 * COORD coordCursorPosition
2108 * Variables :
2109 * Result :
2110 * Remark :
2111 * Status : UNTESTED
2112 *
2113 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2114 *****************************************************************************/
2115
2116DWORD HMDeviceConsoleBufferClass::SetConsoleCursorPosition(PHMHANDLEDATA pHMHandleData,
2117 COORD coordCursorPosition)
2118{
2119 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2120
2121#ifdef DEBUG_LOCAL2
2122 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleCursorPosition(%08x,x=%u.y=%u).\n",
2123 pHMHandleData,
2124 coordCursorPosition.X,
2125 coordCursorPosition.Y);
2126#endif
2127
2128 /* @@@PH remove cursor from screen first ! */
2129 pConsoleBuffer->coordCursorPosition = coordCursorPosition;
2130
2131 return (TRUE);
2132}
2133
2134
2135/*****************************************************************************
2136 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleMode
2137 * Purpose : sets the current console mode
2138 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2139 * DWORD dwMode - console mode
2140 * Variables :
2141 * Result :
2142 * Remark :
2143 * Status : UNTESTED
2144 *
2145 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2146 *****************************************************************************/
2147
2148DWORD HMDeviceConsoleBufferClass::SetConsoleMode(PHMHANDLEDATA pHMHandleData,
2149 DWORD dwMode)
2150{
2151 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2152
2153#ifdef DEBUG_LOCAL2
2154 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleMode(%08x,%08x).\n",
2155 pHMHandleData,
2156 dwMode);
2157#endif
2158
2159 pConsoleBuffer->dwConsoleMode = dwMode; /* set current console mode */
2160
2161 return (TRUE);
2162}
2163
2164
2165/*****************************************************************************
2166 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleScreenBufferSize
2167 * Purpose : allocate or re-allocate the screenbuffer and transform the
2168 * old buffer as required
2169 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2170 * COORD coordSize - the new buffer size
2171 * Variables :
2172 * Result :
2173 * Remark :
2174 * Status : UNTESTED
2175 *
2176 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2177 *****************************************************************************/
2178
2179DWORD HMDeviceConsoleBufferClass::SetConsoleScreenBufferSize (PHMHANDLEDATA pHMHandleData,
2180 COORD coordSize)
2181{
2182 ULONG ulSize; /* calculated size of the new buffer */
2183 PSZ *ppszNew; /* pointer to the new array */
2184 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2185 ULONG ulLine; /* line index counter */
2186
2187#ifdef DEBUG_LOCAL2
2188 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleScreenBufferSize(%u,%u).\n",
2189 coordSize.X,
2190 coordSize.Y);
2191#endif
2192
2193
2194 /* re-allocate the whole line-pointer array */
2195 ulSize = coordSize.Y * (coordSize.X * 2 + sizeof (PSZ) );
2196 if (ulSize == 0) /* set new buffer size to zero ? */
2197 {
2198 if (pConsoleBuffer->ppszLine != NULL) /* if old buffer is present */
2199 free (pConsoleBuffer->ppszLine); /* free old buffer */
2200
2201 pConsoleBuffer->ppszLine = NULL;
2202 pConsoleBuffer->coordBufferSize.X = 0;
2203 pConsoleBuffer->coordBufferSize.Y = 0;
2204 pConsoleBuffer->coordWindowSize.X = 0;
2205 pConsoleBuffer->coordWindowSize.Y = 0;
2206 pConsoleBuffer->coordWindowPosition.X = 0;
2207 pConsoleBuffer->coordWindowPosition.Y = 0;
2208
2209 return (TRUE); /* OK */
2210 }
2211
2212
2213 ppszNew = (PSZ *) malloc(ulSize); /* allocate array */
2214 if (ppszNew == NULL) /* check proper allocation */
2215 {
2216 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* set error information */
2217 return (FALSE); /* raise error condition */
2218 }
2219
2220
2221 for (ulLine = 0; /* setup line pointer array */
2222 ulLine < coordSize.Y;
2223 ulLine++)
2224 {
2225 /* calculate line pointer */
2226 ulSize = (ULONG)ppszNew + (coordSize.Y * sizeof(PSZ) )
2227 + (coordSize.X * ulLine * 2);
2228 ppszNew[ulLine] = (PSZ)ulSize; /* OK, write index pointer */
2229 }
2230
2231 ulSize = ( ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 8) +
2232 ((ULONG)' ') +
2233 ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 24) +
2234 ((ULONG)' ' << 16) );
2235
2236 /* scroll the line index */
2237 for (ulLine = 0;
2238 ulLine < coordSize.Y;
2239 ulLine++)
2240 iConsoleBufferFillLine(ulSize,
2241 (PUSHORT)(ppszNew[ulLine]),
2242 coordSize.X);
2243
2244
2245
2246 /* copy lines as required */
2247 if (pConsoleBuffer->ppszLine != NULL) /* previous buffer present ? */
2248 {
2249 ULONG x, y;
2250
2251 /* copy old characters as required */
2252 x = min(pConsoleBuffer->coordBufferSize.X, coordSize.X);
2253 y = min(pConsoleBuffer->coordBufferSize.Y, coordSize.Y);
2254
2255 for (ulLine = 0; /* copy line by line */
2256 ulLine < y;
2257 ulLine++)
2258 memcpy(ppszNew[ulLine],
2259 pConsoleBuffer->ppszLine[ulLine],
2260 x * 2);
2261
2262 free (pConsoleBuffer->ppszLine); /* free previous screen buffer array */
2263 }
2264
2265
2266 pConsoleBuffer->ppszLine = ppszNew; /* poke in the new values */
2267 pConsoleBuffer->coordBufferSize.X = coordSize.X;
2268 pConsoleBuffer->coordBufferSize.Y = coordSize.Y;
2269 if (flVioConsole) {
2270 USHORT Row = 0;
2271 USHORT Column = 0;
2272 APIRET rc;
2273
2274 rc = VioGetCurPos(&Row, &Column, 0);
2275 dprintf(("Current cursor position (%d,%d)", Column, Row));
2276 pConsoleBuffer->coordCursorPosition.Y = Row;
2277 pConsoleBuffer->coordCursorPosition.X = Column;
2278 }
2279 else {
2280 pConsoleBuffer->coordCursorPosition.X = 0;
2281 pConsoleBuffer->coordCursorPosition.Y = 0;
2282 }
2283
2284 /* @@@PH to be changed ! */
2285 pConsoleBuffer->coordWindowSize.X = coordSize.X; /* default */
2286 pConsoleBuffer->coordWindowSize.Y = coordSize.Y;
2287 pConsoleBuffer->coordWindowPosition.X = 0;
2288 pConsoleBuffer->coordWindowPosition.Y = 0;
2289
2290 /* update screen if active console */
2291 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2292 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2293
2294 return TRUE;
2295}
2296
2297
2298/*****************************************************************************
2299 * Name :
2300 * Purpose :
2301 * Parameters:
2302 * Variables :
2303 * Result :
2304 * Remark :
2305 * Status :
2306 *
2307 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
2308 *****************************************************************************/
2309
2310DWORD HMDeviceConsoleBufferClass::SetConsoleTextAttribute(PHMHANDLEDATA pHMHandleData,
2311 WORD wAttr)
2312{
2313 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2314
2315#ifdef DEBUG_LOCAL2
2316 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleTextAttribute(%u).\n",
2317 wAttr);
2318#endif
2319
2320 pConsoleBuffer->ucDefaultAttribute = (UCHAR)wAttr;
2321 return (TRUE);
2322}
2323
2324
2325/*****************************************************************************
2326 * Name :
2327 * Purpose :
2328 * Parameters:
2329 * Variables :
2330 * Result :
2331 * Remark :
2332 * Status :
2333 *
2334 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
2335 *****************************************************************************/
2336
2337DWORD HMDeviceConsoleBufferClass::SetConsoleActiveScreenBuffer(PHMHANDLEDATA pHMHandleData)
2338{
2339 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2340
2341#ifdef DEBUG_LOCAL
2342 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleActiveScreenBuffer().\n");
2343#endif
2344
2345 /* set new buffer handle to the global console */
2346 pConsoleGlobals->hConsoleBuffer = pHMHandleData->hHMHandle;
2347 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2348
2349 return (TRUE);
2350}
2351
2352
2353/*****************************************************************************
2354 * Name : BOOL HMDeviceConsoleBufferClass::SetConsoleWindowInfo
2355 * Purpose : set a new size to the console window
2356 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2357 * BOOL fAbsolute
2358 * PSMALL_RECT psrctWindowRect
2359 * Variables :
2360 * Result :
2361 * Remark :
2362 * Status : UNTESTED
2363 *
2364 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2365 *****************************************************************************/
2366
2367BOOL HMDeviceConsoleBufferClass::SetConsoleWindowInfo(PHMHANDLEDATA pHMHandleData,
2368 BOOL fAbsolute,
2369 PSMALL_RECT psrctWindowRect)
2370{
2371 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2372
2373#ifdef DEBUG_LOCAL2
2374 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleWindowInfo(%08x,%u,%08x).\n",
2375 pHMHandleData,
2376 fAbsolute,
2377 psrctWindowRect);
2378#endif
2379
2380 if (fAbsolute == TRUE) /* absolute coordinates provided ? */
2381 {
2382 if ( (psrctWindowRect->Left < 0) || /* check parameters first */
2383 (psrctWindowRect->Top < 0) ||
2384 (psrctWindowRect->Right <= psrctWindowRect->Left) ||
2385 (psrctWindowRect->Bottom <= psrctWindowRect->Top)
2386 )
2387 {
2388 SetLastError(ERROR_INVALID_PARAMETER_W); /* set error information */
2389 return (FALSE); /* error */
2390 }
2391
2392 /* check we don't go beyond screen buffer ! */
2393 if ( ((psrctWindowRect->Right - psrctWindowRect->Left) > pConsoleBuffer->coordBufferSize.X) ||
2394 ((psrctWindowRect->Bottom - psrctWindowRect->Top ) > pConsoleBuffer->coordBufferSize.Y) ||
2395 (psrctWindowRect->Left >= pConsoleBuffer->coordBufferSize.X) ||
2396 (psrctWindowRect->Top >= pConsoleBuffer->coordBufferSize.Y)
2397 )
2398 {
2399 SetLastError(ERROR_INVALID_PARAMETER_W); /* set error information */
2400 return (FALSE); /* error */
2401 }
2402
2403 pConsoleBuffer->coordWindowSize.X = psrctWindowRect->Right -
2404 psrctWindowRect->Left;
2405 pConsoleBuffer->coordWindowSize.Y = psrctWindowRect->Bottom -
2406 psrctWindowRect->Top;
2407
2408 pConsoleBuffer->coordWindowPosition.X = psrctWindowRect->Left;
2409 pConsoleBuffer->coordWindowPosition.Y = psrctWindowRect->Top;
2410 }
2411 else
2412 {
2413 int iSizeX; /* relative coordinates */
2414 int iSizeY;
2415 int iPosX;
2416 int iPosY;
2417
2418 iSizeX = pConsoleBuffer->coordWindowSize.X + psrctWindowRect->Left + psrctWindowRect->Right;
2419 iSizeY = pConsoleBuffer->coordWindowSize.Y + psrctWindowRect->Top + psrctWindowRect->Bottom;
2420 iPosX = pConsoleBuffer->coordWindowPosition.X + psrctWindowRect->Left;
2421 iPosY = pConsoleBuffer->coordWindowPosition.Y + psrctWindowRect->Top;
2422
2423 /* check we don't go beyond screen buffer ! */
2424 if ( (iSizeX > pConsoleBuffer->coordBufferSize.X) ||
2425 (iSizeY > pConsoleBuffer->coordBufferSize.Y) ||
2426 (iPosX >= pConsoleBuffer->coordBufferSize.X) ||
2427 (iPosY >= pConsoleBuffer->coordBufferSize.Y) ||
2428 (iSizeX < 0) ||
2429 (iSizeY < 0) ||
2430 (iPosX < 0) ||
2431 (iPosY < 0)
2432 )
2433 {
2434 SetLastError(ERROR_INVALID_PARAMETER_W); /* set error information */
2435 return (FALSE); /* error */
2436 }
2437
2438 /* Values are verified for being OK ! */
2439 pConsoleBuffer->coordWindowPosition.X = iPosX;
2440 pConsoleBuffer->coordWindowPosition.Y = iPosY;
2441 pConsoleBuffer->coordWindowSize.X = iSizeX;
2442 pConsoleBuffer->coordWindowSize.Y = iSizeY;
2443 }
2444
2445 /* update window */
2446 /* @@@PH
2447
2448 ConsoleWindowResize(COORD coordWindowSize,
2449 COORD coordWindowPos,
2450
2451 */
2452
2453 /* update window contents (scroll) */
2454 /* update screen if active console */
2455 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2456 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2457
2458 return (TRUE); /* OK */
2459}
2460
2461
2462/*****************************************************************************
2463 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleA
2464 * Purpose : write a string to the console
2465 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2466 * LPWORD lpwAttribute
2467 * DWORD cWriteCells
2468 * COORD dwWriteCoord
2469 * LPDWORD lpcWritten
2470 * Variables :
2471 * Result :
2472 * Remark :
2473 * Status : UNTESTED
2474 *
2475 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2476 *****************************************************************************/
2477
2478DWORD HMDeviceConsoleBufferClass::WriteConsoleA(PHMHANDLEDATA pHMHandleData,
2479 CONST VOID* lpvBuffer,
2480 DWORD cchToWrite,
2481 LPDWORD lpcchWritten,
2482 LPVOID lpvReserved)
2483{
2484 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2485
2486#ifdef DEBUG_LOCAL2
2487 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleA(%08x,%08x,%u,%08x,%08x).\n",
2488 pHMHandleData,
2489 lpvBuffer,
2490 cchToWrite,
2491 lpcchWritten,
2492 lpvReserved);
2493#endif
2494
2495 /* simply forward the request to that routine */
2496 return (HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,
2497 lpvBuffer,
2498 cchToWrite,
2499 lpcchWritten,
2500 NULL));
2501}
2502
2503
2504/*****************************************************************************
2505 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleW
2506 * Purpose : write a string to the console
2507 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2508 * LPWORD lpwAttribute
2509 * DWORD cWriteCells
2510 * COORD dwWriteCoord
2511 * LPDWORD lpcWritten
2512 * Variables :
2513 * Result :
2514 * Remark :
2515 * Status : UNTESTED
2516 *
2517 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2518 *****************************************************************************/
2519
2520DWORD HMDeviceConsoleBufferClass::WriteConsoleW(PHMHANDLEDATA pHMHandleData,
2521 CONST VOID* lpvBuffer,
2522 DWORD cchToWrite,
2523 LPDWORD lpcchWritten,
2524 LPVOID lpvReserved)
2525{
2526 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2527 DWORD rc;
2528 LPSTR pszAscii;
2529
2530#ifdef DEBUG_LOCAL2
2531 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleW(%08x,%08x,%u,%08x,%08x).\n",
2532 pHMHandleData,
2533 lpvBuffer,
2534 cchToWrite,
2535 lpcchWritten,
2536 lpvReserved);
2537#endif
2538
2539 /* Ascii -> unicode translation */
2540 pszAscii = (LPSTR)HEAP_malloc(cchToWrite+1);
2541 if (pszAscii == NULL)
2542 return ERROR_NOT_ENOUGH_MEMORY;
2543
2544 lstrcpynWtoA(pszAscii, (LPWSTR)lpvBuffer, cchToWrite+1);
2545
2546 /* simply forward the request to that routine */
2547 rc = HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,
2548 pszAscii,
2549 cchToWrite,
2550 lpcchWritten,
2551 NULL);
2552 // free memory again
2553 HEAP_free(pszAscii);
2554 return (rc);
2555}
2556
2557
2558/*****************************************************************************
2559 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA
2560 * Purpose : write character and color attribute data to screen rectangle
2561 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2562 * PCHAR_INFO pchiSrcBuffer
2563 * COORD coordSrcBufferSize
2564 * COORD coordSrcBufferCoord
2565 * PSMALL_RECT psrctDestRect
2566 * Variables :
2567 * Result :
2568 * Remark :
2569 * Status : UNTESTED
2570 *
2571 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2572 *****************************************************************************/
2573
2574DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA(PHMHANDLEDATA pHMHandleData,
2575 PCHAR_INFO pchiSrcBuffer,
2576 COORD coordSrcBufferSize,
2577 COORD coordSrcBufferCoord,
2578 PSMALL_RECT psrctDestRect)
2579{
2580 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2581 ULONG ulX, ulY; /* current coordinate to be read */
2582 ULONG ulCX, ulCY; /* width and height of target area */
2583 ULONG ulWriteX, ulWriteY; /* position data is read from */
2584 WORD wCell; /* currently read data */
2585
2586 PCHAR_INFO pchi;
2587 PSZ pszTarget;
2588
2589#ifdef DEBUG_LOCAL2
2590 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
2591 pHMHandleData,
2592 pchiSrcBuffer,
2593 coordSrcBufferSize.X,
2594 coordSrcBufferSize.Y,
2595 coordSrcBufferCoord.X,
2596 coordSrcBufferCoord.Y,
2597 psrctDestRect);
2598#endif
2599
2600
2601 /* verify psrctDestRect first */
2602 psrctDestRect->Left = max(psrctDestRect->Left, 0);
2603 psrctDestRect->Top = max(psrctDestRect->Top, 0);
2604 psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
2605 psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
2606
2607 /* verify target buffer */
2608 if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||
2609 (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )
2610 {
2611 SetLastError(ERROR_INVALID_PARAMETER_W); /* set detailed error info */
2612 return (FALSE); /* API failed */
2613 }
2614
2615 ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;
2616 ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;
2617
2618 ulCX = min(ulCX, (psrctDestRect->Right - psrctDestRect->Left));
2619 ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));
2620
2621 /* final calculation of the copy rectangle */
2622 psrctDestRect->Right = psrctDestRect->Left + ulCX;
2623 psrctDestRect->Bottom = psrctDestRect->Top + ulCY;
2624
2625
2626 for (ulY = 0,
2627 ulWriteY = psrctDestRect->Top;
2628
2629 ulY <= ulCY;
2630
2631 ulY++,
2632 ulWriteY++)
2633 {
2634 pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X
2635 + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)
2636 * coordSrcBufferSize.X;
2637
2638 /* calculate pointer to start of screen line */
2639 pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + ((int)psrctDestRect->Left << 1);
2640
2641 for (ulX = 0,
2642 ulWriteX = psrctDestRect->Left;
2643
2644 ulX <= ulCX;
2645
2646 ulX++,
2647 ulWriteX++,
2648 pchi++)
2649 {
2650 /* write character and attribute */
2651 *pszTarget++ = (UCHAR)pchi->Char.AsciiChar;
2652 *pszTarget++ = (UCHAR)pchi->Attributes;
2653 }
2654 }
2655
2656 /* update screen if active console */
2657 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2658 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2659
2660 return (TRUE); /* OK, that's it */
2661}
2662
2663
2664/*****************************************************************************
2665 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW
2666 * Purpose : write character and color attribute data to screen rectangle
2667 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2668 * PCHAR_INFO pchiSrcBuffer
2669 * COORD coordSrcBufferSize
2670 * COORD coordSrcBufferCoord
2671 * PSMALL_RECT psrctDestRect
2672 * Variables :
2673 * Result :
2674 * Remark :
2675 * Status : UNTESTED
2676 *
2677 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2678 *****************************************************************************/
2679
2680DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW(PHMHANDLEDATA pHMHandleData,
2681 PCHAR_INFO pchiSrcBuffer,
2682 COORD coordSrcBufferSize,
2683 COORD coordSrcBufferCoord,
2684 PSMALL_RECT psrctDestRect)
2685{
2686 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2687 ULONG ulX, ulY; /* current coordinate to be read */
2688 ULONG ulCX, ulCY; /* width and height of target area */
2689 ULONG ulWriteX, ulWriteY; /* position data is read from */
2690 WORD wCell; /* currently read data */
2691
2692 PCHAR_INFO pchi;
2693 PSZ pszTarget;
2694
2695#ifdef DEBUG_LOCAL2
2696 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
2697 pHMHandleData,
2698 pchiSrcBuffer,
2699 coordSrcBufferSize.X,
2700 coordSrcBufferSize.Y,
2701 coordSrcBufferCoord.X,
2702 coordSrcBufferCoord.Y,
2703 psrctDestRect);
2704#endif
2705
2706
2707 /* verify psrctDestRect first */
2708 psrctDestRect->Left = max(psrctDestRect->Left, 0);
2709 psrctDestRect->Top = max(psrctDestRect->Top, 0);
2710 psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
2711 psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
2712
2713 /* verify target buffer */
2714 if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||
2715 (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )
2716 {
2717 SetLastError(ERROR_INVALID_PARAMETER_W); /* set detailed error info */
2718 return (FALSE); /* API failed */
2719 }
2720
2721 ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;
2722 ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;
2723
2724 ulCX = min(ulCX, (psrctDestRect->Right - psrctDestRect->Left));
2725 ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));
2726
2727 /* final calculation of the copy rectangle */
2728 psrctDestRect->Right = psrctDestRect->Left + ulCX;
2729 psrctDestRect->Bottom = psrctDestRect->Top + ulCY;
2730
2731
2732 for (ulY = 0,
2733 ulWriteY = psrctDestRect->Top;
2734
2735 ulY <= ulCY;
2736
2737 ulY++,
2738 ulWriteY++)
2739 {
2740 pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X
2741 + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)
2742 * coordSrcBufferSize.X;
2743
2744 /* calculate pointer to start of screen line */
2745 pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + ((int)psrctDestRect->Left << 1);
2746
2747 for (ulX = 0,
2748 ulWriteX = psrctDestRect->Left;
2749
2750 ulX <= ulCX;
2751
2752 ulX++,
2753 ulWriteX++,
2754 pchi++)
2755 {
2756 /* write character and attribute */
2757 *pszTarget++ = (UCHAR)pchi->Char.UnicodeChar; /* @@@PH unicode->ascii */
2758 *pszTarget++ = (UCHAR)pchi->Attributes;
2759 }
2760 }
2761
2762 /* update screen if active console */
2763 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2764 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2765
2766 return (TRUE); /* OK, that's it */
2767}
2768
2769
2770/*****************************************************************************
2771 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute
2772 * Purpose : write an array with specified attributes to the console
2773 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2774 * LPWORD lpwAttribute
2775 * DWORD cWriteCells
2776 * COORD dwWriteCoord
2777 * LPDWORD lpcWritten
2778 * Variables :
2779 * Result :
2780 * Remark :
2781 * Status : UNTESTED
2782 *
2783 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2784 *****************************************************************************/
2785
2786DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
2787 LPWORD lpwAttribute,
2788 DWORD cWriteCells,
2789 COORD dwWriteCoord,
2790 LPDWORD lpcWritten)
2791{
2792 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2793 ULONG ulCounter; /* current character counter */
2794
2795#ifdef DEBUG_LOCAL2
2796 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
2797 pHMHandleData,
2798 lpwAttribute,
2799
2800
2801 cWriteCells,
2802 dwWriteCoord.X,
2803 dwWriteCoord.Y,
2804 lpcWritten);
2805#endif
2806
2807 if ( (dwWriteCoord.X < 0) ||
2808 (dwWriteCoord.Y < 0) )
2809 {
2810 if (lpcWritten != NULL) /* ensure pointer is valid */
2811 *lpcWritten = 0; /* complete error handling */
2812
2813 SetLastError(ERROR_INVALID_PARAMETER_W);
2814 return (FALSE);
2815 }
2816
2817 /* check if dwWriteCoord is within specs */
2818 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
2819 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
2820 {
2821 if (lpcWritten != NULL) /* ensure pointer is valid */
2822 *lpcWritten = 0; /* complete error handling */
2823
2824 SetLastError(ERROR_INVALID_PARAMETER_W);
2825 return (FALSE);
2826 }
2827
2828
2829 /* OK, now write the attribute lines */
2830 for (ulCounter = 0;
2831 ulCounter < cWriteCells;
2832 ulCounter++,
2833 lpwAttribute++)
2834 {
2835 /* write attribute into cell */
2836 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
2837 (dwWriteCoord.X * 2 + 1)
2838 ) = (UCHAR)*lpwAttribute; /* write attribute and skip to next */
2839
2840 dwWriteCoord.X++; /* move write position */
2841 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
2842 {
2843 dwWriteCoord.X = 0; /* skip to next line */
2844 dwWriteCoord.Y++;
2845
2846 /* oops, we're at the end of the buffer. Abort now. */
2847 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
2848 {
2849 if (lpcWritten != NULL) /* ensure pointer is valid */
2850 *lpcWritten = ulCounter;
2851
2852 /* update screen if active console */
2853 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2854 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
2855
2856 return (TRUE);
2857 }
2858 }
2859 }
2860
2861 /* update screen if active console */
2862 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2863 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2864
2865 if (lpcWritten != NULL) /* ensure pointer is valid */
2866 *lpcWritten = cWriteCells;
2867
2868 return (TRUE);
2869}
2870
2871
2872/*****************************************************************************
2873 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA
2874 * Purpose : fills the console buffer with a specified attribute
2875 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2876 * LPTSTR lpWriteBuffer
2877 * DWORD cchWrite
2878 * COORD dwWriteCoord
2879 * LPDWORD lpcWritten
2880 * Variables :
2881 * Result :
2882 * Remark :
2883 * Status : UNTESTED
2884 *
2885 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2886 *****************************************************************************/
2887
2888DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
2889 LPTSTR lpWriteBuffer,
2890 DWORD cchWrite,
2891 COORD dwWriteCoord,
2892 LPDWORD lpcWritten)
2893{
2894 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2895 ULONG ulCounter; /* current character counter */
2896
2897#ifdef DEBUG_LOCAL2
2898 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterA(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",
2899 pHMHandleData,
2900 lpWriteBuffer,
2901 cchWrite,
2902 dwWriteCoord.X,
2903 dwWriteCoord.Y,
2904 lpcWritten);
2905#endif
2906
2907 if ( (dwWriteCoord.X < 0) ||
2908 (dwWriteCoord.Y < 0) )
2909 {
2910 if (lpcWritten != NULL) /* ensure pointer is valid */
2911 *lpcWritten = 0; /* complete error handling */
2912
2913 SetLastError(ERROR_INVALID_PARAMETER_W);
2914 return (FALSE);
2915 }
2916
2917 /* check if dwWriteCoord is within specs */
2918 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
2919 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
2920 {
2921 if (lpcWritten != NULL) /* ensure pointer is valid */
2922 *lpcWritten = 0; /* complete error handling */
2923
2924 SetLastError(ERROR_INVALID_PARAMETER_W);
2925 return (FALSE);
2926 }
2927
2928
2929 /* OK, now write the character lines */
2930 for (ulCounter = 0;
2931 ulCounter < cchWrite;
2932 ulCounter++,
2933 lpWriteBuffer++)
2934 {
2935 /* write character into cell */
2936 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
2937 (dwWriteCoord.X * 2)
2938 ) = (UCHAR)*lpWriteBuffer; /* write character and skip to next */
2939
2940 dwWriteCoord.X++; /* move write position */
2941 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
2942 {
2943 dwWriteCoord.X = 0; /* skip to next line */
2944 dwWriteCoord.Y++;
2945
2946 /* oops, we're at the end of the buffer. Abort now. */
2947 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
2948 {
2949 if (lpcWritten != NULL) /* ensure pointer is valid */
2950 *lpcWritten = ulCounter;
2951
2952 /* update screen if active console */
2953 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2954 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
2955
2956 return (TRUE);
2957 }
2958 }
2959 }
2960
2961 /* update screen if active console */
2962 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2963 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2964
2965 if (lpcWritten != NULL) /* ensure pointer is valid */
2966 *lpcWritten = cchWrite;
2967
2968 return (TRUE);
2969}
2970
2971
2972/*****************************************************************************
2973 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW
2974 * Purpose : fills the console buffer with a specified attribute
2975 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2976 * LPWSTR lpWriteBuffer
2977 * DWORD cchWrite
2978 * COORD dwWriteCoord
2979 * LPDWORD lpcWritten
2980 * Variables :
2981 * Result :
2982 * Remark :
2983 * Status : UNTESTED
2984 *
2985 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2986 *****************************************************************************/
2987
2988DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
2989 LPWSTR lpWriteBuffer,
2990 DWORD cchWrite,
2991 COORD dwWriteCoord,
2992 LPDWORD lpcWritten)
2993{
2994 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2995 ULONG ulCounter; /* current character counter */
2996
2997#ifdef DEBUG_LOCAL2
2998 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterW(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",
2999 pHMHandleData,
3000 lpWriteBuffer,
3001 cchWrite,
3002 dwWriteCoord.X,
3003 dwWriteCoord.Y,
3004 lpcWritten);
3005#endif
3006
3007 if ( (dwWriteCoord.X < 0) ||
3008 (dwWriteCoord.Y < 0) )
3009 {
3010 if (lpcWritten != NULL) /* ensure pointer is valid */
3011 *lpcWritten = 0; /* complete error handling */
3012
3013 SetLastError(ERROR_INVALID_PARAMETER_W);
3014 return (FALSE);
3015 }
3016
3017 /* check if dwWriteCoord is within specs */
3018 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
3019 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
3020 {
3021 if (lpcWritten != NULL) /* ensure pointer is valid */
3022 *lpcWritten = 0; /* complete error handling */
3023
3024 SetLastError(ERROR_INVALID_PARAMETER_W);
3025 return (FALSE);
3026 }
3027
3028
3029 /* OK, now write the character lines */
3030 for (ulCounter = 0;
3031 ulCounter < cchWrite;
3032 ulCounter++,
3033 lpWriteBuffer++)
3034 {
3035 /* write character into cell */
3036 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
3037 (dwWriteCoord.X * 2)
3038 ) = (UCHAR)*lpWriteBuffer; /* write character and skip to next */
3039 /* @@@PH unicode to ascii translation */
3040
3041 dwWriteCoord.X++; /* move write position */
3042 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
3043 {
3044 dwWriteCoord.X = 0; /* skip to next line */
3045 dwWriteCoord.Y++;
3046
3047 /* oops, we're at the end of the buffer. Abort now. */
3048 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
3049 {
3050 if (lpcWritten != NULL) /* ensure pointer is valid */
3051 *lpcWritten = ulCounter;
3052
3053 /* update screen if active console */
3054 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
3055 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
3056
3057 return (TRUE);
3058 }
3059 }
3060 }
3061
3062 /* update screen if active console */
3063 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
3064 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
3065
3066 if (lpcWritten != NULL) /* ensure pointer is valid */
3067 *lpcWritten = cchWrite;
3068
3069 return (TRUE);
3070}
3071
Note: See TracBrowser for help on using the repository browser.