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

Last change on this file since 2893 was 2802, checked in by sandervl, 26 years ago

Added new logging feature

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