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

Last change on this file since 7549 was 7549, checked in by sandervl, 24 years ago

preliminary changes for new overlapped io framework

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