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

Last change on this file since 2050 was 2050, checked in by sandervl, 26 years ago

Read/WriteFile return value type changes

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