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

Last change on this file since 10471 was 10471, checked in by sandervl, 22 years ago

DBCS fixes for console & resource functions

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