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

Last change on this file since 1484 was 1484, checked in by phaller, 26 years ago

Fix: console (unicode) updates

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