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

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

preliminary work on overlapped serial comm IO

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