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

Last change on this file since 4461 was 4461, checked in by phaller, 25 years ago

Fix for left margin of console

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