source: trunk/src/kernel32/conbuffer.cpp

Last change on this file was 22052, checked in by dmik, 13 years ago

kernel32: Properly handle backspace and tab characters in console input/output mode.

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