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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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