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

Last change on this file since 3830 was 2984, checked in by sandervl, 25 years ago

moved registry apis into kernel32 + cleanup

File size: 110.1 KB
Line 
1/* $Id: conbuffer.cpp,v 1.10 2000-03-03 11:15:56 sandervl Exp $ */
2
3/*
4 * Win32 Console API Translation for OS/2
5 *
6 * 1998/02/10 Patrick Haller (haller@zebra.fh-weingarten.de)
7 *
8 * @(#) console.cpp 1.0.0 1998/02/10 PH Start from scratch
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14
15#ifdef DEBUG
16#define DEBUG_LOCAL
17#define DEBUG_LOCAL2
18#endif
19
20//#undef DEBUG_LOCAL
21//#undef DEBUG_LOCAL2
22
23
24/*****************************************************************************
25 * Remark *
26 *****************************************************************************
27
28 - DWORD HandlerRoutine (DWORD dwCtrlType)
29 basically an exception handler routine. handles a few signals / excpts.
30 should be somewhere near the exception handling code ... :)
31
32 Hmm, however as PM applications don't really get a ctrl-c signal,
33 I'll have to do this on my own ...
34
35 - supply unicode<->ascii conversions for all the _A and _W function pairs.
36
37 - problem: we can't prevent thread1 from blocking the message queue ?
38 what will happen if a WinTerminate() is issued there ?
39 will the message queue be closed and provide smooth tasking ?
40 how will open32 react on this ?
41
42 - ECHO_LINE_INPUT / ReadFile blocks till CR
43
44 - scrollbars
45 * do some flowchart to exactly determine WHEN to use WHICH setting
46 and perform WHAT action
47
48 - clipboard support
49*/
50
51
52/*****************************************************************************
53 * Includes *
54 *****************************************************************************/
55
56#define INCL_WIN
57#define INCL_DOSMEMMGR
58#define INCL_DOSSEMAPHORES
59#define INCL_DOSERRORS
60#define INCL_DOSPROCESS
61#define INCL_DOSMODULEMGR
62#define INCL_VIO
63#define INCL_AVIO
64#include <os2wrap.h> //Odin32 OS/2 api wrappers
65
66#include <win32api.h>
67#include <misc.h>
68#include <string.h>
69#include <stdlib.h>
70
71#include "conwin.h" // Windows Header for console only
72#include "HandleManager.h"
73#include "HMDevice.h"
74#include "ConBuffer.H"
75#include "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 < 0) ||
2372 (psrctWindowRect->Bottom < 0) ||
2373 (psrctWindowRect->Right <= psrctWindowRect->Left) ||
2374 (psrctWindowRect->Bottom <= psrctWindowRect->Top)
2375 )
2376 {
2377 SetLastError(ERROR_INVALID_PARAMETER_W); /* set error information */
2378 return (FALSE); /* error */
2379 }
2380
2381 /* check we don't go beyond screen buffer ! */
2382 if ( ((psrctWindowRect->Right - psrctWindowRect->Left) > pConsoleBuffer->coordBufferSize.X) ||
2383 ((psrctWindowRect->Bottom - psrctWindowRect->Top ) > pConsoleBuffer->coordBufferSize.Y) ||
2384 (psrctWindowRect->Left >= pConsoleBuffer->coordBufferSize.X) ||
2385 (psrctWindowRect->Top >= pConsoleBuffer->coordBufferSize.Y)
2386 )
2387 {
2388 SetLastError(ERROR_INVALID_PARAMETER_W); /* set error information */
2389 return (FALSE); /* error */
2390 }
2391
2392 pConsoleBuffer->coordWindowSize.X = psrctWindowRect->Right -
2393 psrctWindowRect->Left;
2394 pConsoleBuffer->coordWindowSize.Y = psrctWindowRect->Bottom -
2395 psrctWindowRect->Top;
2396
2397 pConsoleBuffer->coordWindowPosition.X = psrctWindowRect->Left;
2398 pConsoleBuffer->coordWindowPosition.Y = psrctWindowRect->Top;
2399 }
2400 else
2401 {
2402 int iSizeX; /* relative coordinates */
2403 int iSizeY;
2404 int iPosX;
2405 int iPosY;
2406
2407 iSizeX = pConsoleBuffer->coordWindowSize.X + psrctWindowRect->Left + psrctWindowRect->Right;
2408 iSizeY = pConsoleBuffer->coordWindowSize.Y + psrctWindowRect->Top + psrctWindowRect->Bottom;
2409 iPosX = pConsoleBuffer->coordWindowPosition.X + psrctWindowRect->Left;
2410 iPosY = pConsoleBuffer->coordWindowPosition.Y + psrctWindowRect->Top;
2411
2412 /* check we don't go beyond screen buffer ! */
2413 if ( (iSizeX > pConsoleBuffer->coordBufferSize.X) ||
2414 (iSizeY > pConsoleBuffer->coordBufferSize.Y) ||
2415 (iPosX >= pConsoleBuffer->coordBufferSize.X) ||
2416 (iPosY >= pConsoleBuffer->coordBufferSize.Y) ||
2417 (iSizeX < 0) ||
2418 (iSizeY < 0) ||
2419 (iPosX < 0) ||
2420 (iPosY < 0)
2421 )
2422 {
2423 SetLastError(ERROR_INVALID_PARAMETER_W); /* set error information */
2424 return (FALSE); /* error */
2425 }
2426
2427 /* Values are verified for being OK ! */
2428 pConsoleBuffer->coordWindowPosition.X = iPosX;
2429 pConsoleBuffer->coordWindowPosition.Y = iPosY;
2430 pConsoleBuffer->coordWindowSize.X = iSizeX;
2431 pConsoleBuffer->coordWindowSize.Y = iSizeY;
2432 }
2433
2434 /* update window */
2435 /* @@@PH
2436
2437 ConsoleWindowResize(COORD coordWindowSize,
2438 COORD coordWindowPos,
2439
2440 */
2441
2442 /* update window contents (scroll) */
2443 /* update screen if active console */
2444 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2445 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2446
2447 return (TRUE); /* OK */
2448}
2449
2450
2451/*****************************************************************************
2452 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleA
2453 * Purpose : write a string to the console
2454 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2455 * LPWORD lpwAttribute
2456 * DWORD cWriteCells
2457 * COORD dwWriteCoord
2458 * LPDWORD lpcWritten
2459 * Variables :
2460 * Result :
2461 * Remark :
2462 * Status : UNTESTED
2463 *
2464 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2465 *****************************************************************************/
2466
2467DWORD HMDeviceConsoleBufferClass::WriteConsoleA(PHMHANDLEDATA pHMHandleData,
2468 CONST VOID* lpvBuffer,
2469 DWORD cchToWrite,
2470 LPDWORD lpcchWritten,
2471 LPVOID lpvReserved)
2472{
2473 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2474
2475#ifdef DEBUG_LOCAL2
2476 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleA(%08x,%08x,%u,%08x,%08x).\n",
2477 pHMHandleData,
2478 lpvBuffer,
2479 cchToWrite,
2480 lpcchWritten,
2481 lpvReserved);
2482#endif
2483
2484 /* simply forward the request to that routine */
2485 return (HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,
2486 lpvBuffer,
2487 cchToWrite,
2488 lpcchWritten,
2489 NULL));
2490}
2491
2492
2493/*****************************************************************************
2494 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleW
2495 * Purpose : write a string to the console
2496 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2497 * LPWORD lpwAttribute
2498 * DWORD cWriteCells
2499 * COORD dwWriteCoord
2500 * LPDWORD lpcWritten
2501 * Variables :
2502 * Result :
2503 * Remark :
2504 * Status : UNTESTED
2505 *
2506 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2507 *****************************************************************************/
2508
2509DWORD HMDeviceConsoleBufferClass::WriteConsoleW(PHMHANDLEDATA pHMHandleData,
2510 CONST VOID* lpvBuffer,
2511 DWORD cchToWrite,
2512 LPDWORD lpcchWritten,
2513 LPVOID lpvReserved)
2514{
2515 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2516 DWORD rc;
2517 LPSTR pszAscii;
2518
2519#ifdef DEBUG_LOCAL2
2520 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleW(%08x,%08x,%u,%08x,%08x).\n",
2521 pHMHandleData,
2522 lpvBuffer,
2523 cchToWrite,
2524 lpcchWritten,
2525 lpvReserved);
2526#endif
2527
2528 /* Ascii -> unicode translation */
2529 pszAscii = (LPSTR)HEAP_malloc(cchToWrite);
2530 if (pszAscii == NULL)
2531 return ERROR_NOT_ENOUGH_MEMORY;
2532
2533 lstrcpynWtoA(pszAscii, (LPWSTR)lpvBuffer, cchToWrite);
2534
2535 /* simply forward the request to that routine */
2536 rc = HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,
2537 pszAscii,
2538 cchToWrite,
2539 lpcchWritten,
2540 NULL);
2541 // free memory again
2542 HEAP_free(pszAscii);
2543 return (rc);
2544}
2545
2546
2547/*****************************************************************************
2548 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA
2549 * Purpose : write character and color attribute data to screen rectangle
2550 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2551 * PCHAR_INFO pchiSrcBuffer
2552 * COORD coordSrcBufferSize
2553 * COORD coordSrcBufferCoord
2554 * PSMALL_RECT psrctDestRect
2555 * Variables :
2556 * Result :
2557 * Remark :
2558 * Status : UNTESTED
2559 *
2560 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2561 *****************************************************************************/
2562
2563DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA(PHMHANDLEDATA pHMHandleData,
2564 PCHAR_INFO pchiSrcBuffer,
2565 COORD coordSrcBufferSize,
2566 COORD coordSrcBufferCoord,
2567 PSMALL_RECT psrctDestRect)
2568{
2569 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2570 ULONG ulX, ulY; /* current coordinate to be read */
2571 ULONG ulCX, ulCY; /* width and height of target area */
2572 ULONG ulWriteX, ulWriteY; /* position data is read from */
2573 WORD wCell; /* currently read data */
2574
2575 PCHAR_INFO pchi;
2576 PSZ pszTarget;
2577
2578#ifdef DEBUG_LOCAL2
2579 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
2580 pHMHandleData,
2581 pchiSrcBuffer,
2582 coordSrcBufferSize.X,
2583 coordSrcBufferSize.Y,
2584 coordSrcBufferCoord.X,
2585 coordSrcBufferCoord.Y,
2586 psrctDestRect);
2587#endif
2588
2589
2590 /* verify psrctDestRect first */
2591 psrctDestRect->Left = max(psrctDestRect->Left, 0);
2592 psrctDestRect->Top = max(psrctDestRect->Top, 0);
2593 psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
2594 psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
2595
2596 /* verify target buffer */
2597 if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||
2598 (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )
2599 {
2600 SetLastError(ERROR_INVALID_PARAMETER_W); /* set detailed error info */
2601 return (FALSE); /* API failed */
2602 }
2603
2604 ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;
2605 ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;
2606
2607 ulCX = min(ulCX, (psrctDestRect->Right - psrctDestRect->Left));
2608 ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));
2609
2610 /* final calculation of the copy rectangle */
2611 psrctDestRect->Right = psrctDestRect->Left + ulCX;
2612 psrctDestRect->Bottom = psrctDestRect->Top + ulCY;
2613
2614
2615 for (ulY = 0,
2616 ulWriteY = psrctDestRect->Top;
2617
2618 ulY <= ulCY;
2619
2620 ulY++,
2621 ulWriteY++)
2622 {
2623 pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X
2624 + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)
2625 * coordSrcBufferSize.X;
2626
2627 /* calculate pointer to start of screen line */
2628 pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + psrctDestRect->Left;
2629
2630 for (ulX = 0,
2631 ulWriteX = psrctDestRect->Left;
2632
2633 ulX <= ulCX;
2634
2635 ulX++,
2636 ulWriteX++,
2637 pchi++)
2638 {
2639 /* write character and attribute */
2640 *pszTarget++ = (UCHAR)pchi->Char.AsciiChar;
2641 *pszTarget++ = (UCHAR)pchi->Attributes;
2642 }
2643 }
2644
2645 /* update screen if active console */
2646 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2647 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2648
2649 return (TRUE); /* OK, that's it */
2650}
2651
2652
2653/*****************************************************************************
2654 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW
2655 * Purpose : write character and color attribute data to screen rectangle
2656 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2657 * PCHAR_INFO pchiSrcBuffer
2658 * COORD coordSrcBufferSize
2659 * COORD coordSrcBufferCoord
2660 * PSMALL_RECT psrctDestRect
2661 * Variables :
2662 * Result :
2663 * Remark :
2664 * Status : UNTESTED
2665 *
2666 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2667 *****************************************************************************/
2668
2669DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW(PHMHANDLEDATA pHMHandleData,
2670 PCHAR_INFO pchiSrcBuffer,
2671 COORD coordSrcBufferSize,
2672 COORD coordSrcBufferCoord,
2673 PSMALL_RECT psrctDestRect)
2674{
2675 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2676 ULONG ulX, ulY; /* current coordinate to be read */
2677 ULONG ulCX, ulCY; /* width and height of target area */
2678 ULONG ulWriteX, ulWriteY; /* position data is read from */
2679 WORD wCell; /* currently read data */
2680
2681 PCHAR_INFO pchi;
2682 PSZ pszTarget;
2683
2684#ifdef DEBUG_LOCAL2
2685 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
2686 pHMHandleData,
2687 pchiSrcBuffer,
2688 coordSrcBufferSize.X,
2689 coordSrcBufferSize.Y,
2690 coordSrcBufferCoord.X,
2691 coordSrcBufferCoord.Y,
2692 psrctDestRect);
2693#endif
2694
2695
2696 /* verify psrctDestRect first */
2697 psrctDestRect->Left = max(psrctDestRect->Left, 0);
2698 psrctDestRect->Top = max(psrctDestRect->Top, 0);
2699 psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
2700 psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
2701
2702 /* verify target buffer */
2703 if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||
2704 (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )
2705 {
2706 SetLastError(ERROR_INVALID_PARAMETER_W); /* set detailed error info */
2707 return (FALSE); /* API failed */
2708 }
2709
2710 ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;
2711 ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;
2712
2713 ulCX = min(ulCX, (psrctDestRect->Right - psrctDestRect->Left));
2714 ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));
2715
2716 /* final calculation of the copy rectangle */
2717 psrctDestRect->Right = psrctDestRect->Left + ulCX;
2718 psrctDestRect->Bottom = psrctDestRect->Top + ulCY;
2719
2720
2721 for (ulY = 0,
2722 ulWriteY = psrctDestRect->Top;
2723
2724 ulY <= ulCY;
2725
2726 ulY++,
2727 ulWriteY++)
2728 {
2729 pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X
2730 + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)
2731 * coordSrcBufferSize.X;
2732
2733 /* calculate pointer to start of screen line */
2734 pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + psrctDestRect->Left;
2735
2736 for (ulX = 0,
2737 ulWriteX = psrctDestRect->Left;
2738
2739 ulX <= ulCX;
2740
2741 ulX++,
2742 ulWriteX++,
2743 pchi++)
2744 {
2745 /* write character and attribute */
2746 *pszTarget++ = (UCHAR)pchi->Char.UnicodeChar; /* @@@PH unicode->ascii */
2747 *pszTarget++ = (UCHAR)pchi->Attributes;
2748 }
2749 }
2750
2751 /* update screen if active console */
2752 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2753 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2754
2755 return (TRUE); /* OK, that's it */
2756}
2757
2758
2759/*****************************************************************************
2760 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute
2761 * Purpose : write an array with specified attributes to the console
2762 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2763 * LPWORD lpwAttribute
2764 * DWORD cWriteCells
2765 * COORD dwWriteCoord
2766 * LPDWORD lpcWritten
2767 * Variables :
2768 * Result :
2769 * Remark :
2770 * Status : UNTESTED
2771 *
2772 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2773 *****************************************************************************/
2774
2775DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
2776 LPWORD lpwAttribute,
2777 DWORD cWriteCells,
2778 COORD dwWriteCoord,
2779 LPDWORD lpcWritten)
2780{
2781 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2782 ULONG ulCounter; /* current character counter */
2783
2784#ifdef DEBUG_LOCAL2
2785 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
2786 pHMHandleData,
2787 lpwAttribute,
2788
2789
2790 cWriteCells,
2791 dwWriteCoord.X,
2792 dwWriteCoord.Y,
2793 lpcWritten);
2794#endif
2795
2796 if ( (dwWriteCoord.X < 0) ||
2797 (dwWriteCoord.Y < 0) )
2798 {
2799 if (lpcWritten != NULL) /* ensure pointer is valid */
2800 *lpcWritten = 0; /* complete error handling */
2801
2802 SetLastError(ERROR_INVALID_PARAMETER_W);
2803 return (FALSE);
2804 }
2805
2806 /* check if dwWriteCoord is within specs */
2807 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
2808 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
2809 {
2810 if (lpcWritten != NULL) /* ensure pointer is valid */
2811 *lpcWritten = 0; /* complete error handling */
2812
2813 SetLastError(ERROR_INVALID_PARAMETER_W);
2814 return (FALSE);
2815 }
2816
2817
2818 /* OK, now write the attribute lines */
2819 for (ulCounter = 0;
2820 ulCounter < cWriteCells;
2821 ulCounter++,
2822 lpwAttribute++)
2823 {
2824 /* write attribute into cell */
2825 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
2826 (dwWriteCoord.X * 2 + 1)
2827 ) = (UCHAR)*lpwAttribute; /* write attribute and skip to next */
2828
2829 dwWriteCoord.X++; /* move write position */
2830 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
2831 {
2832 dwWriteCoord.X = 0; /* skip to next line */
2833 dwWriteCoord.Y++;
2834
2835 /* oops, we're at the end of the buffer. Abort now. */
2836 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
2837 {
2838 if (lpcWritten != NULL) /* ensure pointer is valid */
2839 *lpcWritten = ulCounter;
2840
2841 /* update screen if active console */
2842 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2843 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
2844
2845 return (TRUE);
2846 }
2847 }
2848 }
2849
2850 /* update screen if active console */
2851 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2852 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2853
2854 if (lpcWritten != NULL) /* ensure pointer is valid */
2855 *lpcWritten = cWriteCells;
2856
2857 return (TRUE);
2858}
2859
2860
2861/*****************************************************************************
2862 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA
2863 * Purpose : fills the console buffer with a specified attribute
2864 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2865 * LPTSTR lpWriteBuffer
2866 * DWORD cchWrite
2867 * COORD dwWriteCoord
2868 * LPDWORD lpcWritten
2869 * Variables :
2870 * Result :
2871 * Remark :
2872 * Status : UNTESTED
2873 *
2874 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2875 *****************************************************************************/
2876
2877DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
2878 LPTSTR lpWriteBuffer,
2879 DWORD cchWrite,
2880 COORD dwWriteCoord,
2881 LPDWORD lpcWritten)
2882{
2883 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2884 ULONG ulCounter; /* current character counter */
2885
2886#ifdef DEBUG_LOCAL2
2887 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterA(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",
2888 pHMHandleData,
2889 lpWriteBuffer,
2890 cchWrite,
2891 dwWriteCoord.X,
2892 dwWriteCoord.Y,
2893 lpcWritten);
2894#endif
2895
2896 if ( (dwWriteCoord.X < 0) ||
2897 (dwWriteCoord.Y < 0) )
2898 {
2899 if (lpcWritten != NULL) /* ensure pointer is valid */
2900 *lpcWritten = 0; /* complete error handling */
2901
2902 SetLastError(ERROR_INVALID_PARAMETER_W);
2903 return (FALSE);
2904 }
2905
2906 /* check if dwWriteCoord is within specs */
2907 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
2908 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
2909 {
2910 if (lpcWritten != NULL) /* ensure pointer is valid */
2911 *lpcWritten = 0; /* complete error handling */
2912
2913 SetLastError(ERROR_INVALID_PARAMETER_W);
2914 return (FALSE);
2915 }
2916
2917
2918 /* OK, now write the character lines */
2919 for (ulCounter = 0;
2920 ulCounter < cchWrite;
2921 ulCounter++,
2922 lpWriteBuffer++)
2923 {
2924 /* write character into cell */
2925 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
2926 (dwWriteCoord.X * 2)
2927 ) = (UCHAR)*lpWriteBuffer; /* write character and skip to next */
2928
2929 dwWriteCoord.X++; /* move write position */
2930 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
2931 {
2932 dwWriteCoord.X = 0; /* skip to next line */
2933 dwWriteCoord.Y++;
2934
2935 /* oops, we're at the end of the buffer. Abort now. */
2936 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
2937 {
2938 if (lpcWritten != NULL) /* ensure pointer is valid */
2939 *lpcWritten = ulCounter;
2940
2941 /* update screen if active console */
2942 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2943 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
2944
2945 return (TRUE);
2946 }
2947 }
2948 }
2949
2950 /* update screen if active console */
2951 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
2952 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
2953
2954 if (lpcWritten != NULL) /* ensure pointer is valid */
2955 *lpcWritten = cchWrite;
2956
2957 return (TRUE);
2958}
2959
2960
2961/*****************************************************************************
2962 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW
2963 * Purpose : fills the console buffer with a specified attribute
2964 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
2965 * LPWSTR lpWriteBuffer
2966 * DWORD cchWrite
2967 * COORD dwWriteCoord
2968 * LPDWORD lpcWritten
2969 * Variables :
2970 * Result :
2971 * Remark :
2972 * Status : UNTESTED
2973 *
2974 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
2975 *****************************************************************************/
2976
2977DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
2978 LPWSTR lpWriteBuffer,
2979 DWORD cchWrite,
2980 COORD dwWriteCoord,
2981 LPDWORD lpcWritten)
2982{
2983 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
2984 ULONG ulCounter; /* current character counter */
2985
2986#ifdef DEBUG_LOCAL2
2987 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterW(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",
2988 pHMHandleData,
2989 lpWriteBuffer,
2990 cchWrite,
2991 dwWriteCoord.X,
2992 dwWriteCoord.Y,
2993 lpcWritten);
2994#endif
2995
2996 if ( (dwWriteCoord.X < 0) ||
2997 (dwWriteCoord.Y < 0) )
2998 {
2999 if (lpcWritten != NULL) /* ensure pointer is valid */
3000 *lpcWritten = 0; /* complete error handling */
3001
3002 SetLastError(ERROR_INVALID_PARAMETER_W);
3003 return (FALSE);
3004 }
3005
3006 /* check if dwWriteCoord is within specs */
3007 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
3008 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
3009 {
3010 if (lpcWritten != NULL) /* ensure pointer is valid */
3011 *lpcWritten = 0; /* complete error handling */
3012
3013 SetLastError(ERROR_INVALID_PARAMETER_W);
3014 return (FALSE);
3015 }
3016
3017
3018 /* OK, now write the character lines */
3019 for (ulCounter = 0;
3020 ulCounter < cchWrite;
3021 ulCounter++,
3022 lpWriteBuffer++)
3023 {
3024 /* write character into cell */
3025 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
3026 (dwWriteCoord.X * 2)
3027 ) = (UCHAR)*lpWriteBuffer; /* write character and skip to next */
3028 /* @@@PH unicode to ascii translation */
3029
3030 dwWriteCoord.X++; /* move write position */
3031 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
3032 {
3033 dwWriteCoord.X = 0; /* skip to next line */
3034 dwWriteCoord.Y++;
3035
3036 /* oops, we're at the end of the buffer. Abort now. */
3037 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
3038 {
3039 if (lpcWritten != NULL) /* ensure pointer is valid */
3040 *lpcWritten = ulCounter;
3041
3042 /* update screen if active console */
3043 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
3044 pConsoleGlobals->fUpdateRequired = TRUE;/* update with next WM_TIMER */
3045
3046 return (TRUE);
3047 }
3048 }
3049 }
3050
3051 /* update screen if active console */
3052 if (pHMHandleData->hHMHandle == pConsoleGlobals->hConsoleBuffer)
3053 pConsoleGlobals->fUpdateRequired = TRUE; /* update with next WM_TIMER */
3054
3055 if (lpcWritten != NULL) /* ensure pointer is valid */
3056 *lpcWritten = cchWrite;
3057
3058 return (TRUE);
3059}
3060
Note: See TracBrowser for help on using the repository browser.