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

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

YD: Changes for header updates

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