Changeset 111 for trunk/src/kernel32/console.cpp
- Timestamp:
- Jun 17, 1999, 8:22:43 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/console.cpp
r100 r111 1 /* $Id: console.cpp,v 1. 5 1999-06-10 20:47:55phaller Exp $ */1 /* $Id: console.cpp,v 1.6 1999-06-17 18:21:39 phaller Exp $ */ 2 2 3 3 /* … … 64 64 #include <os2.h> 65 65 #include <builtin.h> 66 67 66 #include <stdlib.h> 68 67 #include <string.h> 69 #include "win32type.h" 70 #include "misc.h" 68 69 #include <win32type.h> 70 #include <misc.h> 71 72 #include "conwin.h" // Windows Header for console only 73 #include "HandleManager.h" 74 #include "HMDevice.h" 75 71 76 #include "console.h" 72 77 #include "console2.h" 78 #include "conin.h" 79 #include "conout.h" 80 #include "conbuffer.h" 81 73 82 #include "conprop.h" 74 83 #include "unicode.h" 75 #include "HandleManager.h"76 84 77 85 … … 97 105 _O32_SetLastError(a); 98 106 SetFS(sel); 99 } 107 } 100 108 101 109 inline DWORD GetLastError() … … 108 116 109 117 return yyrc; 110 } 118 } 111 119 112 120 inline LPSTR GetCommandLine() … … 119 127 120 128 return yyrc; 121 } 129 } 122 130 123 131 inline void ExitProcess(UINT a) … … 127 135 _O32_ExitProcess(a); 128 136 SetFS(sel); 129 } 137 } 130 138 131 139 inline HANDLE GetStdHandle(DWORD a) … … 138 146 139 147 return yyrc; 140 } 148 } 141 149 142 150 inline DWORD GetFileType(HANDLE a) … … 149 157 150 158 return yyrc; 151 } 152 153 } 154 155 #define INVALID_HANDLE_VALUE ((HANDLE)-1) 156 #define STD_INPUT_HANDLE ((DWORD)-10) 157 #define STD_OUTPUT_HANDLE ((DWORD)-11) 158 #define STD_ERROR_HANDLE ((DWORD)-12) 159 #define GENERIC_READ 0x80000000 160 #define GENERIC_WRITE 0x40000000 161 #define FILE_SHARE_READ 0x00000001 162 #define FILE_SHARE_WRITE 0x00000002 163 164 159 } 160 161 } 165 162 166 163 /***************************************************************************** … … 168 165 *****************************************************************************/ 169 166 170 #define SZ_CONSOLE_CLASS "WIN32CONSOLECLASS"171 172 173 /* according to the updated AVIO documentation of Warp 4 */174 #define MAX_OS2_ROWS 255175 #define MAX_OS2_COLUMNS 255176 #define FORMAT_CGA 1177 #define CONSOLE_TIMER_ID 1178 #define CONSOLE_INPUTQUEUESIZE 256179 180 181 #define CONSOLECURSOR_HIDE 1182 #define CONSOLECURSOR_SHOW 2183 #define CONSOLECURSOR_BLINK 3184 #define CONSOLECURSOR_OVERWRITTEN 4185 186 #define UM_CONSOLE_CREATE WM_USER + 0x1000187 188 189 /* device request codes for use in the pseudo-device handlers */190 #define DRQ_CONSOLE 0x00010000191 #define DRQ_FILLCONSOLEOUTPUTATTRIBUTE DRQ_CONSOLE + 0192 #define DRQ_FILLCONSOLEOUTPUTCHARACTERA DRQ_CONSOLE + 1193 #define DRQ_FILLCONSOLEOUTPUTCHARACTERW DRQ_CONSOLE + 2194 #define DRQ_FLUSHCONSOLEINPUTBUFFER DRQ_CONSOLE + 3195 #define DRQ_GETCONSOLECURSORINFO DRQ_CONSOLE + 4196 #define DRQ_GETCONSOLEMODE DRQ_CONSOLE + 5197 #define DRQ_GETCONSOLESCREENBUFFERINFO DRQ_CONSOLE + 6198 #define DRQ_GETLARGESTCONSOLEWINDOWSIZE DRQ_CONSOLE + 7199 #define DRQ_GETNUMBEROFCONSOLEINPUTEVENTS DRQ_CONSOLE + 8200 #define DRQ_PEEKCONSOLEINPUTW DRQ_CONSOLE + 9201 #define DRQ_PEEKCONSOLEINPUTA DRQ_CONSOLE + 10202 #define DRQ_READCONSOLEA DRQ_CONSOLE + 11203 #define DRQ_READCONSOLEW DRQ_CONSOLE + 12204 #define DRQ_READCONSOLEINPUTA DRQ_CONSOLE + 14205 #define DRQ_READCONSOLEINPUTW DRQ_CONSOLE + 15206 #define DRQ_READCONSOLEOUTPUTA DRQ_CONSOLE + 16207 #define DRQ_READCONSOLEOUTPUTW DRQ_CONSOLE + 17208 #define DRQ_READCONSOLEOUTPUTATTRIBUTE DRQ_CONSOLE + 18209 #define DRQ_READCONSOLEOUTPUTCHARACTERA DRQ_CONSOLE + 19210 #define DRQ_READCONSOLEOUTPUTCHARACTERW DRQ_CONSOLE + 20211 #define DRQ_SCROLLCONSOLESCREENBUFFERA DRQ_CONSOLE + 21212 #define DRQ_SCROLLCONSOLESCREENBUFFERW DRQ_CONSOLE + 22213 #define DRQ_SETCONSOLEACTIVESCREENBUFFER DRQ_CONSOLE + 23214 #define DRQ_SETCONSOLECURSORINFO DRQ_CONSOLE + 24215 #define DRQ_SETCONSOLECURSORPOSITION DRQ_CONSOLE + 25216 #define DRQ_SETCONSOLEMODE DRQ_CONSOLE + 26217 #define DRQ_SETCONSOLESCREENBUFFERSIZE DRQ_CONSOLE + 27218 #define DRQ_SETCONSOLETEXTATTRIBUTE DRQ_CONSOLE + 28219 #define DRQ_SETCONSOLEWINDOWINFO DRQ_CONSOLE + 29220 #define DRQ_WRITECONSOLEA DRQ_CONSOLE + 30221 #define DRQ_WRITECONSOLEW DRQ_CONSOLE + 31222 #define DRQ_WRITECONSOLEINPUTA DRQ_CONSOLE + 32223 #define DRQ_WRITECONSOLEINPUTW DRQ_CONSOLE + 33224 #define DRQ_WRITECONSOLEOUTPUTA DRQ_CONSOLE + 34225 #define DRQ_WRITECONSOLEOUTPUTW DRQ_CONSOLE + 35226 #define DRQ_WRITECONSOLEOUTPUTATTRIBUTE DRQ_CONSOLE + 36227 #define DRQ_WRITECONSOLEOUTPUTCHARACTERA DRQ_CONSOLE + 37228 #define DRQ_WRITECONSOLEOUTPUTCHARACTERW DRQ_CONSOLE + 38229 #define DRQ_INTERNAL_CONSOLEBUFFERMAP DRQ_CONSOLE + 39230 #define DRQ_INTERNAL_CONSOLECURSORSHOW DRQ_CONSOLE + 40231 #define DRQ_INTERNAL_CONSOLEADJUSTWINDOW DRQ_CONSOLE + 41232 233 234 #define COORD2ULONG(c) ((ULONG)( ((ULONG)c.X << 16) + (ULONG)c.Y))235 #define ULONG2COORD(c,u) c.X = u >> 16; c.Y = u & 0x0000FFFF;236 237 238 167 /***************************************************************************** 239 168 * Structures * … … 242 171 243 172 /***************************************************************************** 244 * Local Prototypes *245 *****************************************************************************/246 247 248 static APIRET ConsoleTerminate(void);/* termination of the console subsystem */249 250 /* console message thread */251 static VOID _Optlink ConsoleMsgThread (void *pParameters);252 253 static MRESULT EXPENTRY ConsoleWindowProc(HWND hwnd, /* window procedure */254 ULONG msg,255 MPARAM mp1,256 MPARAM mp2);257 258 static MRESULT EXPENTRY ConsoleFrameWindowProc(HWND hwnd,259 ULONG msg,260 MPARAM mp1,261 MPARAM mp2);262 263 static void ConsoleBufferMap (PCONSOLEBUFFER pConsoleBuffer);264 265 static void ConsoleBufferScrollUp (PCONSOLEBUFFER pConsoleBuffer,266 ULONG ulLines);267 268 static void ConsoleBufferFillLine (ULONG ulPattern,269 PUSHORT pusTarget,270 ULONG ulSize);271 272 static APIRET ConsoleInputEventPush (PINPUT_RECORD pInputRecord);273 274 static APIRET ConsoleInputEventPop (PINPUT_RECORD pInputRecord);275 276 static APIRET ConsoleInputEventPushKey (MPARAM mp1,277 MPARAM mp2);278 279 static APIRET ConsoleInputEventPushMouse (ULONG ulMessage,280 MPARAM mp1,281 MPARAM mp2);282 283 static APIRET ConsoleInputEventPushWindow(COORD coordWindowSize);284 285 static APIRET ConsoleInputEventPushMenu (DWORD dwCommandId);286 287 static APIRET ConsoleInputEventPushFocus (BOOL bSetFocus);288 289 static ULONG ConsoleInputQueryEvents (void);290 291 static void ConsoleCursorShow (PCONSOLEBUFFER pConsoleBuffer,292 ULONG ulCursorMode);293 294 static APIRET ConsoleFontQuery (void);295 296 static void ConsoleAdjustWindow (PCONSOLEBUFFER pConsoleBuffer);297 298 299 /*****************************************************************************300 173 * Process Global Structures * 301 174 *****************************************************************************/ 302 175 303 304 struct _ConsoleGlobals 305 { 306 public: 307 TID tidConsole; /* console message thread */ 308 HEV hevConsole; /* console event semaphore */ 309 APIRET rcConsole; /* initialization status of the console */ 310 HAB hab; /* anchor block handle */ 311 HMQ hmq; /* message queue handle for the console window */ 312 QMSG qmsg; /* message for the console window */ 313 ULONG flFrameFlags; /* frame window creation flags */ 314 PSZ pszWindowTitle; /* name of the window */ 315 HWND hwndFrame; /* frame window handle */ 316 HWND hwndClient; /* client window handle */ 317 318 HWND hwndHorzScroll; /* handle of horizontal scroll bar */ 319 HWND hwndVertScroll; /* handle of vertical scroll bar */ 320 BOOL fHasVertScroll; /* indicates if scrollbars are visible */ 321 BOOL fHasHorzScroll; 322 323 HDC hdcConsole; /* console device context */ 324 PFNWP pfnwpFrameOriginal; /* original frame window procedure */ 325 326 HWND hwndMenuConsole; /* console popup menu */ 327 HMODULE hmodResource; /* resources are stored in KERNEL32.DLL */ 328 HPOINTER hPtrConsole; /* console icon */ 329 330 HANDLE hConsoleBuffer; /* handle of the active console buffer */ 331 HANDLE hConsoleBufferDefault; /* handle of the default console buffer */ 332 333 HVPS hvpsConsole; /* console AVIO presentation space */ 334 335 COORD coordMaxWindowPels; /* maximum window size in pixels */ 336 COORD coordWindowSize; /* current console window size */ 337 COORD coordWindowPos; /* scroller's positions */ 338 339 SHORT sCellCX; /* height and width of a avio cell with the current font */ 340 SHORT sCellCY; 341 342 BOOL fUpdateRequired; /* set to TRUE if next WM_TIMER shall update the */ 343 /* AVIO presentation space from the consolebuffer */ 344 345 ULONG idTimer; /* Timer identifier */ 346 ULONG ulTimerFrequency; /* cursor + blitter timer frequency */ 347 ULONG ulTimerCursor; /* cursor loop counter for divisor */ 348 349 CONSOLEOPTIONS Options; /* the console's options / properties */ 350 351 } ConsoleGlobals; 352 353 354 struct _ConsoleInput 355 { 356 INPUT_RECORD arrInputRecord[CONSOLE_INPUTQUEUESIZE]; /* packet queue */ 357 HEV hevInputQueue; /* becomes posted if input arrives */ 358 359 /* HMUTEX hmtxInputQueue; if queue corruption should occur ... */ 360 361 ULONG ulIndexFree; /* index of first free event record */ 362 ULONG ulIndexEvent; /* index of first valid event in queue */ 363 ULONG ulEvents; /* number of events in queue */ 364 DWORD dwConsoleMode; /* input console mode */ 365 } ConsoleInput; 176 static ICONSOLEGLOBALS ConsoleGlobals; 177 static ICONSOLEINPUT ConsoleInput; 366 178 367 179 … … 383 195 *****************************************************************************/ 384 196 385 APIRET ConsoleInit(void)/* creation of the console subsystem */197 APIRET iConsoleInit(void) /* creation of the console subsystem */ 386 198 { 387 199 APIRET rc; /* API return code */ … … 418 230 ***************************************************************************/ 419 231 420 rc = ConsoleDevicesRegister();/* ensure devices are there */232 rc = iConsoleDevicesRegister(); /* ensure devices are there */ 421 233 if (rc != NO_ERROR) /* check for errors */ 422 234 { … … 433 245 /* OK, we're about to initialize the console subsystem for this process. */ 434 246 /* start message thread for console object window */ 435 ConsoleGlobals.tidConsole = _beginthread( ConsoleMsgThread,247 ConsoleGlobals.tidConsole = _beginthread(iConsoleMsgThread, 436 248 NULL, 437 1 6384,249 12288, 438 250 NULL); 439 251 /* has the thread been created properly ? */ … … 486 298 *****************************************************************************/ 487 299 488 APIRET ConsoleDevicesRegister(void)300 APIRET iConsoleDevicesRegister(void) 489 301 { 490 302 DWORD dwType; /* device handle type */ … … 580 392 /* create devices and register devices with handlemanager */ 581 393 582 pHMDeviceConsoleIn = new HMDeviceConsoleInClass("CONIN$"); 394 pHMDeviceConsoleIn = new HMDeviceConsoleInClass("CONIN$", 395 &ConsoleInput, 396 &ConsoleGlobals); 583 397 rc = HMDeviceRegister ("CONIN$", 584 398 pHMDeviceConsoleIn); … … 588 402 589 403 590 pHMDeviceConsoleOut = new HMDeviceConsoleOutClass("CONOUT$"); 404 pHMDeviceConsoleOut = new HMDeviceConsoleOutClass("CONOUT$", 405 &ConsoleInput, 406 &ConsoleGlobals); 591 407 rc = HMDeviceRegister ("CONOUT$", 592 408 pHMDeviceConsoleOut); … … 596 412 597 413 598 pHMDeviceConsoleBuffer = new HMDeviceConsoleBufferClass("CONBUFFER$"); 414 pHMDeviceConsoleBuffer = new HMDeviceConsoleBufferClass("CONBUFFER$", 415 &ConsoleInput, 416 &ConsoleGlobals); 599 417 rc = HMDeviceRegister ("CONBUFFER$", 600 418 pHMDeviceConsoleBuffer); … … 675 493 *****************************************************************************/ 676 494 677 static APIRETConsoleTerminate(VOID)495 APIRET iConsoleTerminate(VOID) 678 496 { 679 497 APIRET rc; … … 707 525 *****************************************************************************/ 708 526 709 void ConsoleWaitClose(void)527 void iConsoleWaitClose(void) 710 528 { 711 529 CHAR szBuffer[128]; /* buffer for the title */ … … 713 531 714 532 /* check if there is a console window at all */ 715 if ( ConsoleIsActive() == FALSE)533 if (iConsoleIsActive() == FALSE) 716 534 return; /* nope */ 717 535 … … 745 563 *****************************************************************************/ 746 564 747 BOOL ConsoleIsActive(void)565 BOOL iConsoleIsActive(void) 748 566 { 749 567 return (NULLHANDLE != ConsoleGlobals.hevConsole); … … 763 581 *****************************************************************************/ 764 582 765 static VOIDConsoleMsgThread(PVOID pParameters)583 VOID iConsoleMsgThread(PVOID pParameters) 766 584 { 767 585 APIRET rc; /* API return code */ … … 787 605 if (WinRegisterClass(ConsoleGlobals.hab, /* register our class with PM */ 788 606 SZ_CONSOLE_CLASS, 789 ConsoleWindowProc,607 iConsoleWindowProc, 790 608 CS_SIZEREDRAW, 791 609 0) … … 870 688 *****************************************************************************/ 871 689 872 static MRESULT EXPENTRYConsoleWindowProc(HWND hwnd,873 874 875 690 MRESULT EXPENTRY iConsoleWindowProc(HWND hwnd, 691 ULONG msg, 692 MPARAM mp1, 693 MPARAM mp2) 876 694 { 877 695 static RECTL rcl; /* window rectangle */ … … 900 718 hwndFrame = ConsoleGlobals.hwndFrame; 901 719 ConsoleGlobals.pfnwpFrameOriginal = WinSubclassWindow(hwndFrame, 902 ConsoleFrameWindowProc);720 iConsoleFrameWindowProc); 903 721 904 722 ConsoleGlobals.hwndMenuConsole … … 958 776 rc); 959 777 960 ConsoleFontQuery();/* query current cell sizes */778 iConsoleFontQuery(); /* query current cell sizes */ 961 779 962 780 /* adjust window size and position */ … … 1222 1040 1223 1041 case WM_CHAR: 1224 ConsoleInputEventPushKey(mp1,/* push event into queue */1225 mp2);1042 iConsoleInputEventPushKey(mp1, /* push event into queue */ 1043 mp2); 1226 1044 break; /* enable further processing ! */ 1227 1045 … … 1232 1050 1233 1051 case WM_SETFOCUS: 1234 ConsoleInputEventPushFocus((BOOL)mp2);/* push event into queue */1052 iConsoleInputEventPushFocus((BOOL)mp2); /* push event into queue */ 1235 1053 break; /* enable further processing ! */ 1236 1054 … … 1250 1068 case WM_BUTTON2DBLCLK: 1251 1069 case WM_BUTTON3DBLCLK: 1252 ConsoleInputEventPushMouse(msg,1253 mp1,/* push event into queue */1254 mp2);1070 iConsoleInputEventPushMouse(msg, 1071 mp1, /* push event into queue */ 1072 mp2); 1255 1073 break; /* enable further processing ! */ 1256 1074 } … … 1278 1096 *****************************************************************************/ 1279 1097 1280 static MRESULT EXPENTRYConsoleFrameWindowProc(HWND hwnd,1281 1282 1283 1098 MRESULT EXPENTRY iConsoleFrameWindowProc(HWND hwnd, 1099 ULONG msg, 1100 MPARAM mp1, 1101 MPARAM mp2) 1284 1102 { 1285 1103 switch(msg) … … 1331 1149 *****************************************************************************/ 1332 1150 1333 static voidConsoleBufferMap(PCONSOLEBUFFER pConsoleBuffer)1151 void iConsoleBufferMap(PCONSOLEBUFFER pConsoleBuffer) 1334 1152 { 1335 1153 ULONG ulLine; … … 1374 1192 *****************************************************************************/ 1375 1193 1376 static voidConsoleBufferFillLine(ULONG ulPattern,1377 1378 1194 void iConsoleBufferFillLine(ULONG ulPattern, 1195 PUSHORT pusTarget, 1196 ULONG ulSize) 1379 1197 { 1380 1198 ULONG ulCounter; … … 1405 1223 *****************************************************************************/ 1406 1224 1407 static voidConsoleBufferScrollUp(PCONSOLEBUFFER pConsoleBuffer,1408 1225 void iConsoleBufferScrollUp(PCONSOLEBUFFER pConsoleBuffer, 1226 ULONG ulLines) 1409 1227 { 1410 1228 ULONG ulLine; … … 1449 1267 ulLine < pConsoleBuffer->coordBufferSize.Y; 1450 1268 ulLine++) 1451 ConsoleBufferFillLine(ulPosition,1452 (PUSHORT)(pConsoleBuffer->ppszLine[ulLine]),1453 pConsoleBuffer->coordBufferSize.X);1269 iConsoleBufferFillLine(ulPosition, 1270 (PUSHORT)(pConsoleBuffer->ppszLine[ulLine]), 1271 pConsoleBuffer->coordBufferSize.X); 1454 1272 1455 1273 /* this code ensures frequent screen updating, even if the timer prooves */ … … 1459 1277 { 1460 1278 ulUpdateCounter = 0; /* reset the counter */ 1461 ConsoleBufferMap(pConsoleBuffer);1279 iConsoleBufferMap(pConsoleBuffer); 1462 1280 VioShowPS(ConsoleGlobals.coordWindowSize.Y, 1463 1281 ConsoleGlobals.coordWindowSize.X, … … 1481 1299 *****************************************************************************/ 1482 1300 1483 static APIRETConsoleInputEventPush(PINPUT_RECORD pInputRecord)1301 APIRET iConsoleInputEventPush(PINPUT_RECORD pInputRecord) 1484 1302 { 1485 1303 PINPUT_RECORD pirFree; /* pointer to free record */ … … 1524 1342 *****************************************************************************/ 1525 1343 1526 static APIRETConsoleInputEventPop(PINPUT_RECORD pInputRecord)1344 APIRET iConsoleInputEventPop(PINPUT_RECORD pInputRecord) 1527 1345 { 1528 1346 PINPUT_RECORD pirEvent; /* pointer to event record */ … … 1725 1543 1726 1544 1727 static APIRETConsoleInputEventPushKey(MPARAM mp1,1728 1545 APIRET iConsoleInputEventPushKey(MPARAM mp1, 1546 MPARAM mp2) 1729 1547 { 1730 1548 INPUT_RECORD InputRecord; /* the input record structure */ … … 1831 1649 #endif 1832 1650 1833 rc = ConsoleInputEventPush(&InputRecord);/* add it to the queue */1651 rc = iConsoleInputEventPush(&InputRecord); /* add it to the queue */ 1834 1652 return (rc); /* OK */ 1835 1653 } … … 1848 1666 *****************************************************************************/ 1849 1667 1850 static APIRETConsoleInputEventPushMouse(ULONG ulMessage,1851 1852 1668 APIRET iConsoleInputEventPushMouse(ULONG ulMessage, 1669 MPARAM mp1, 1670 MPARAM mp2) 1853 1671 { 1854 1672 INPUT_RECORD InputRecord; /* the input record structure */ … … 1947 1765 InputRecord.Event.MouseEvent.dwButtonState |= RIGHTMOST_BUTTON_PRESSED; 1948 1766 1949 rc = ConsoleInputEventPush(&InputRecord);/* add it to the queue */1767 rc = iConsoleInputEventPush(&InputRecord); /* add it to the queue */ 1950 1768 return (rc); /* OK */ 1951 1769 } … … 1964 1782 *****************************************************************************/ 1965 1783 1966 static APIRETConsoleInputEventPushWindow(COORD coordWindowSize)1784 APIRET iConsoleInputEventPushWindow(COORD coordWindowSize) 1967 1785 { 1968 1786 INPUT_RECORD InputRecord; /* the input record structure */ … … 1981 1799 InputRecord.Event.WindowBufferSizeEvent.dwSize = coordWindowSize; 1982 1800 1983 rc = ConsoleInputEventPush(&InputRecord);/* add it to the queue */1801 rc = iConsoleInputEventPush(&InputRecord); /* add it to the queue */ 1984 1802 return (rc); /* OK */ 1985 1803 } … … 1998 1816 *****************************************************************************/ 1999 1817 2000 static APIRETConsoleInputEventPushMenu(DWORD dwCommandId)1818 APIRET iConsoleInputEventPushMenu(DWORD dwCommandId) 2001 1819 { 2002 1820 INPUT_RECORD InputRecord; /* the input record structure */ … … 2015 1833 InputRecord.Event.MenuEvent.dwCommandId = dwCommandId; 2016 1834 2017 rc = ConsoleInputEventPush(&InputRecord);/* add it to the queue */1835 rc = iConsoleInputEventPush(&InputRecord); /* add it to the queue */ 2018 1836 return (rc); /* OK */ 2019 1837 } … … 2032 1850 *****************************************************************************/ 2033 1851 2034 static APIRETConsoleInputEventPushFocus(BOOL bSetFocus)1852 APIRET iConsoleInputEventPushFocus(BOOL bSetFocus) 2035 1853 { 2036 1854 INPUT_RECORD InputRecord; /* the input record structure */ … … 2049 1867 InputRecord.Event.FocusEvent.bSetFocus = bSetFocus; 2050 1868 2051 rc = ConsoleInputEventPush(&InputRecord);/* add it to the queue */1869 rc = iConsoleInputEventPush(&InputRecord); /* add it to the queue */ 2052 1870 return (rc); /* OK */ 2053 1871 } … … 2066 1884 *****************************************************************************/ 2067 1885 2068 static ULONGConsoleInputQueryEvents (void)1886 ULONG iConsoleInputQueryEvents (void) 2069 1887 { 2070 1888 return (ConsoleInput.ulEvents); /* return number of events in queue */ … … 2084 1902 *****************************************************************************/ 2085 1903 2086 static voidConsoleCursorShow (PCONSOLEBUFFER pConsoleBuffer,2087 1904 void iConsoleCursorShow (PCONSOLEBUFFER pConsoleBuffer, 1905 ULONG ulCursorMode) 2088 1906 { 2089 1907 HPS hps; /* presentation space handle */ … … 2162 1980 *****************************************************************************/ 2163 1981 2164 static APIRETConsoleFontQuery (void)1982 APIRET iConsoleFontQuery (void) 2165 1983 { 2166 1984 return(VioGetDeviceCellSize(&ConsoleGlobals.sCellCY, /* query VIO manager */ … … 2182 2000 *****************************************************************************/ 2183 2001 2184 static voidConsoleAdjustWindow (PCONSOLEBUFFER pConsoleBuffer)2002 void iConsoleAdjustWindow (PCONSOLEBUFFER pConsoleBuffer) 2185 2003 { 2186 2004 LONG lX, lY; /* temporary long values */ … … 2368 2186 #endif 2369 2187 2370 rc = ConsoleInit();/* initialize subsystem if required */2188 rc = iConsoleInit(); /* initialize subsystem if required */ 2371 2189 if (rc != NO_ERROR) /* check for errors */ 2372 2190 { … … 2420 2238 dwDesiredAccess, 2421 2239 dwShareMode, 2422 lpSecurityAttributes,2240 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes, 2423 2241 0, 2424 2242 dwFlags, … … 2604 2422 #endif 2605 2423 2606 rc = ConsoleTerminate();/* terminate subsystem if required */2424 rc = iConsoleTerminate(); /* terminate subsystem if required */ 2607 2425 if (rc != NO_ERROR) /* check for errors */ 2608 2426 { … … 4200 4018 return fResult; 4201 4019 } 4202 4203 4204 /*****************************************************************************4205 * Name : DWORD HMDeviceConsoleInClass::CreateFile4206 * Purpose : this is called from the handle manager if a CreateFile() is4207 * performed on a handle4208 * Parameters: LPCSTR lpFileName name of the file / device4209 * PHMHANDLEDATA pHMHandleData data of the NEW handle4210 * PVOID lpSecurityAttributes ignored4211 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle4212 * Variables :4213 * Result :4214 * Remark : @@@PH CONIN$ handles should be exclusive4215 * reject other requests to this device4216 * Status : NO_ERROR - API succeeded4217 * other - what is to be set in SetLastError4218 *4219 * Author : Patrick Haller [Wed, 1998/02/11 20:44]4220 *****************************************************************************/4221 4222 DWORD HMDeviceConsoleInClass::CreateFile (LPCSTR lpFileName,4223 PHMHANDLEDATA pHMHandleData,4224 PVOID lpSecurityAttributes,4225 PHMHANDLEDATA pHMHandleDataTemplate)4226 {4227 #ifdef DEBUG_LOCAL4228 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass::CreateFile %s(%s,%08x,%08x,%08x)\n",4229 lpHMDeviceName,4230 lpFileName,4231 pHMHandleData->hHandle,4232 lpSecurityAttributes,4233 pHMHandleDataTemplate);4234 #endif4235 4236 pHMHandleData->dwType = FILE_TYPE_CHAR; /* we're a character device */4237 4238 return(NO_ERROR);4239 }4240 4241 4242 /*****************************************************************************4243 * Name :4244 * Purpose :4245 * Parameters:4246 * Variables :4247 * Result :4248 * Remark :4249 * Status :4250 *4251 * Author : Patrick Haller [Wed, 1998/02/11 20:44]4252 *****************************************************************************/4253 4254 DWORD HMDeviceConsoleInClass::ReadFile(PHMHANDLEDATA pHMHandleData,4255 LPCVOID lpBuffer,4256 DWORD nNumberOfBytesToRead,4257 LPDWORD lpNumberOfBytesRead,4258 LPOVERLAPPED lpOverlapped)4259 {4260 ULONG ulCounter; /* character counter for the queue loop */4261 PSZ pszTarget; /* pointer to target buffer */4262 APIRET rc; /* API returncode */4263 INPUT_RECORD InputRecord; /* buffer for the event to be read */4264 ULONG ulPostCounter; /* semaphore post counter */4265 4266 #ifdef DEBUG_LOCAL4267 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",4268 lpHMDeviceName,4269 pHMHandleData->hHandle,4270 lpBuffer,4271 nNumberOfBytesToRead,4272 lpNumberOfBytesRead,4273 lpOverlapped);4274 #endif4275 4276 ulCounter = 0; /* read ascii chars from queue */4277 pszTarget = (PSZ)lpBuffer;4278 4279 /* @@@PH: ConsoleMode: ENABLE_LINE_INPUT - blocks until CR is read */4280 4281 /* block if no key events are in the queue */4282 for (;ulCounter==0;) /* until we got some characters */4283 {4284 if (ConsoleInputQueryEvents() == 0) /* if queue is currently empty */4285 {4286 rc = DosWaitEventSem(ConsoleInput.hevInputQueue, /* wait for input */4287 SEM_INDEFINITE_WAIT);4288 DosResetEventSem(ConsoleInput.hevInputQueue, /* reset semaphore */4289 &ulPostCounter); /* post counter - ignored */4290 }4291 4292 do4293 {4294 rc = ConsoleInputEventPop(&InputRecord); /* get event from queue */4295 if (rc == NO_ERROR) /* if we've got a valid event in the queue */4296 {4297 if (InputRecord.EventType == KEY_EVENT) /* check event type */4298 {4299 *pszTarget = InputRecord.Event.KeyEvent.uChar.AsciiChar;4300 pszTarget++;4301 ulCounter++;4302 4303 /* local echo enabled ? */4304 if (ConsoleInput.dwConsoleMode & ENABLE_ECHO_INPUT)4305 HMWriteFile(ConsoleGlobals.hConsoleBuffer,4306 &InputRecord.Event.KeyEvent.uChar.AsciiChar,4307 1,4308 &ulPostCounter, /* dummy result */4309 NULL);4310 4311 if (ulCounter >= nNumberOfBytesToRead) /* at buffer's end ? */4312 goto __readfile_exit;4313 }4314 /* Note: other events are discarded */4315 }4316 }4317 while (rc == NO_ERROR);4318 }4319 4320 __readfile_exit:4321 4322 *lpNumberOfBytesRead = ulCounter; /* write result */4323 4324 return(TRUE); /* OK */4325 }4326 4327 4328 /*****************************************************************************4329 * Name :4330 * Purpose :4331 * Parameters:4332 * Variables :4333 * Result :4334 * Remark :4335 * Status :4336 *4337 * Author : Patrick Haller [Wed, 1998/02/11 20:44]4338 *****************************************************************************/4339 4340 DWORD HMDeviceConsoleInClass::WriteFile(PHMHANDLEDATA pHMHandleData,4341 LPCVOID lpBuffer,4342 DWORD nNumberOfBytesToWrite,4343 LPDWORD lpNumberOfBytesWritten,4344 LPOVERLAPPED lpOverlapped)4345 {4346 4347 #ifdef DEBUG_LOCAL4348 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",4349 lpHMDeviceName,4350 pHMHandleData->hHandle,4351 lpBuffer,4352 nNumberOfBytesToWrite,4353 lpNumberOfBytesWritten,4354 lpOverlapped);4355 #endif4356 4357 return(ERROR_ACCESS_DENIED);4358 }4359 4360 4361 /*****************************************************************************4362 * Name :4363 * Purpose :4364 * Parameters:4365 * Variables :4366 * Result :4367 * Remark :4368 * Status :4369 *4370 * Author : Patrick Haller [Wed, 1998/02/11 20:44]4371 *****************************************************************************/4372 4373 DWORD HMDeviceConsoleInClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,4374 ULONG ulRequestCode,4375 ULONG arg1,4376 ULONG arg2,4377 ULONG arg3,4378 ULONG arg4)4379 {4380 switch (ulRequestCode)4381 {4382 case DRQ_FLUSHCONSOLEINPUTBUFFER:4383 return (HMDeviceConsoleInClass::4384 FlushConsoleInputBuffer(pHMHandleData));4385 4386 case DRQ_GETNUMBEROFCONSOLEINPUTEVENTS:4387 return (HMDeviceConsoleInClass::4388 GetNumberOfConsoleInputEvents(pHMHandleData,4389 (LPDWORD)arg1));4390 4391 case DRQ_PEEKCONSOLEINPUTA:4392 return (HMDeviceConsoleInClass::4393 PeekConsoleInputA(pHMHandleData,4394 (PINPUT_RECORD)arg1,4395 (DWORD) arg2,4396 (LPDWORD) arg3));4397 4398 case DRQ_PEEKCONSOLEINPUTW:4399 return (HMDeviceConsoleInClass::4400 PeekConsoleInputW(pHMHandleData,4401 (PINPUT_RECORD)arg1,4402 (DWORD) arg2,4403 (LPDWORD) arg3));4404 4405 4406 case DRQ_READCONSOLEA:4407 return (HMDeviceConsoleInClass::4408 ReadConsoleA(pHMHandleData,4409 (CONST VOID*) arg1,4410 (DWORD) arg2,4411 (LPDWORD) arg3,4412 (LPVOID) arg4));4413 4414 case DRQ_READCONSOLEW:4415 return (HMDeviceConsoleInClass::4416 ReadConsoleW(pHMHandleData,4417 (CONST VOID*) arg1,4418 (DWORD) arg2,4419 (LPDWORD) arg3,4420 (LPVOID) arg4));4421 4422 case DRQ_READCONSOLEINPUTA:4423 return (HMDeviceConsoleInClass::4424 ReadConsoleInputA(pHMHandleData,4425 (PINPUT_RECORD)arg1,4426 (DWORD)arg2,4427 (LPDWORD)arg3));4428 4429 case DRQ_READCONSOLEINPUTW:4430 return (HMDeviceConsoleInClass::4431 ReadConsoleInputW(pHMHandleData,4432 (PINPUT_RECORD)arg1,4433 (DWORD)arg2,4434 (LPDWORD)arg3));4435 4436 case DRQ_WRITECONSOLEINPUTA:4437 return (HMDeviceConsoleInClass::4438 WriteConsoleInputA(pHMHandleData,4439 (PINPUT_RECORD)arg1,4440 (DWORD)arg2,4441 (LPDWORD)arg3));4442 4443 case DRQ_WRITECONSOLEINPUTW:4444 return (HMDeviceConsoleInClass::4445 WriteConsoleInputW(pHMHandleData,4446 (PINPUT_RECORD)arg1,4447 (DWORD)arg2,4448 (LPDWORD)arg3));4449 4450 }4451 4452 #ifdef DEBUG_LOCAL4453 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x) unknown request\n",4454 lpHMDeviceName,4455 pHMHandleData->hHandle,4456 ulRequestCode,4457 arg1,4458 arg2,4459 arg3,4460 arg4);4461 #endif4462 4463 SetLastError(ERROR_INVALID_FUNCTION); /* request not implemented */4464 return(FALSE); /* we assume this indicates API call failed */4465 }4466 4467 4468 /*****************************************************************************4469 * Name : BOOL HMDeviceConsoleInClass::FlushConsoleInputBuffer4470 * Purpose : flushes all events from the input queue4471 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data4472 * Variables :4473 * Result :4474 * Remark :4475 * Status : UNTESTED4476 *4477 * Author : Patrick Haller [Wed, 1998/02/16 11:46]4478 *****************************************************************************/4479 4480 BOOL HMDeviceConsoleInClass::FlushConsoleInputBuffer(PHMHANDLEDATA pHMHandleData)4481 {4482 ULONG ulCounter; /* loop counter */4483 4484 #ifdef DEBUG_LOCAL24485 WriteLog("KERNEL32/CONSOLE: CONIN$::FlushConsoleInputBuffer(%08x).\n",4486 pHMHandleData);4487 #endif4488 4489 ConsoleInput.ulIndexFree = 0;4490 ConsoleInput.ulIndexEvent = 0;4491 ConsoleInput.ulEvents = 0;4492 4493 for (ulCounter = 0;4494 ulCounter < CONSOLE_INPUTQUEUESIZE;4495 ulCounter++)4496 ConsoleInput.arrInputRecord[ulCounter].EventType = 0x0000; /* free event */4497 4498 return (TRUE);4499 }4500 4501 4502 /*****************************************************************************4503 * Name : DWORD HMDeviceConsoleInClass::GetConsoleMode4504 * Purpose : queries the current console mode4505 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data4506 * LPDWORD lpMode4507 * Variables :4508 * Result :4509 4510 * Remark :4511 * Status : UNTESTED4512 *4513 * Author : Patrick Haller [Wed, 1998/02/16 11:46]4514 *****************************************************************************/4515 4516 DWORD HMDeviceConsoleInClass::GetConsoleMode(PHMHANDLEDATA pHMHandleData,4517 LPDWORD lpMode)4518 {4519 #ifdef DEBUG_LOCAL24520 WriteLog("KERNEL32/CONSOLE: CONIN$::GetConsoleMode(%08x,%08x).\n",4521 pHMHandleData,4522 lpMode);4523 #endif4524 4525 *lpMode = ConsoleInput.dwConsoleMode; /* return current console mode */4526 4527 return (TRUE);4528 }4529 4530 4531 /*****************************************************************************4532 * Name : DWORD HMDeviceConsoleInClass::GetNumberOfConsoleInputEvents4533 * Purpose : queries the current number of events in the input queue4534 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data4535 * LPDWORD lpNumberOfEvents - return number of events4536 * Variables :4537 * Result :4538 * Remark :4539 * Status : UNTESTED4540 *4541 * Author : Patrick Haller [Wed, 1998/02/16 11:46]4542 *****************************************************************************/4543 4544 BOOL HMDeviceConsoleInClass::GetNumberOfConsoleInputEvents(PHMHANDLEDATA pHMHandleData,4545 LPDWORD lpNumberOfEvents)4546 {4547 #ifdef DEBUG_LOCAL24548 WriteLog("KERNEL32/CONSOLE: CONIN$::GetNumberOfConsoleInputEvents(%08x,%08x).\n",4549 pHMHandleData,4550 lpNumberOfEvents);4551 #endif4552 4553 *lpNumberOfEvents = ConsoleInput.ulEvents; /* return number of events */4554 4555 return (TRUE);4556 }4557 4558 4559 /*****************************************************************************4560 * Name : DWORD HMDeviceConsoleInClass::PeekConsoleInputA4561 * Purpose : peeks events placed in the console input queue4562 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data4563 * PINPUT_RECORD pirBuffer - target buffer for events4564 * DWORD cInRecords - number of input records4565 * LPDWORD lpcRead - returns number of events stored4566 * Variables :4567 * Result : TRUE if successful, FALSE otherwise4568 * Remark : if queue is completely filled and no event is free,4569 * loop will scan over queue multiple times, until target4570 * buffer is filled. It does not check ulCounter to stop4571 * when one scan of the queue is complete.4572 * Status : UNTESTED4573 *4574 * Author : Patrick Haller [Tue, 1998/02/10 01:55]4575 *****************************************************************************/4576 4577 DWORD HMDeviceConsoleInClass::PeekConsoleInputA(PHMHANDLEDATA pHMHandleData,4578 PINPUT_RECORD pirBuffer,4579 DWORD cInRecords,4580 LPDWORD lpcRead)4581 {4582 ULONG ulCounter; /* loop counter */4583 ULONG ulCurrentEvent; /* index of current event in the queue */4584 PINPUT_RECORD pirEvent; /* pointer to current queue element */4585 4586 #ifdef DEBUG_LOCAL24587 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::PeekConsoleInputA(%08x,%08x,%08x,%08x).\n",4588 pHMHandleData,4589 pirBuffer,4590 cInRecords,4591 lpcRead);4592 #endif4593 4594 if (ConsoleInputQueryEvents() == 0) /* if queue is currently empty */4595 {4596 *lpcRead = 0; /* no events read from queue */4597 return (TRUE); /* OK, we're done */4598 }4599 4600 4601 for (ulCounter = 0,4602 ulCurrentEvent = ConsoleInput.ulIndexEvent,4603 pirEvent = &ConsoleInput.arrInputRecord[ConsoleInput.ulIndexEvent];4604 4605 ulCounter < cInRecords;4606 4607 ulCounter++,4608 ulCurrentEvent++,4609 pirEvent++,4610 pirBuffer++)4611 {4612 if (ulCurrentEvent > CONSOLE_INPUTQUEUESIZE) /* reaching after end of que*/4613 {4614 ulCurrentEvent = 0; /* then start over from beginning of queue */4615 pirEvent = ConsoleInput.arrInputRecord;4616 }4617 4618 if (pirEvent->EventType == 0x0000) /* no more events ? */4619 break; /* leave loop then */4620 4621 memcpy(pirEvent, /* copy event data */4622 pirBuffer,4623 sizeof(INPUT_RECORD));4624 }4625 4626 *lpcRead = ulCounter; /* return number of events read */4627 return (TRUE); /* OK, we're done */4628 }4629 4630 4631 /*****************************************************************************4632 * Name : DWORD HMDeviceConsoleInClass::PeekConsoleInputW4633 * Purpose : peeks events placed in the console input queue4634 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data4635 * PINPUT_RECORD pirBuffer - target buffer for events4636 * DWORD cInRecords - number of input records4637 * LPDWORD lpcRead - returns number of events stored4638 * Variables :4639 * Result : TRUE if successful, FALSE otherwise4640 * Remark : if queue is completely filled and no event is free,4641 * loop will scan over queue multiple times, until target4642 * buffer is filled. It does not check ulCounter to stop4643 * when one scan of the queue is complete.4644 * Status : UNTESTED4645 *4646 * Author : Patrick Haller [Tue, 1998/02/10 01:55]4647 *****************************************************************************/4648 4649 DWORD HMDeviceConsoleInClass::PeekConsoleInputW(PHMHANDLEDATA pHMHandleData,4650 PINPUT_RECORD pirBuffer,4651 DWORD cInRecords,4652 LPDWORD lpcRead)4653 {4654 ULONG ulCounter; /* loop counter */4655 ULONG ulCurrentEvent; /* index of current event in the queue */4656 PINPUT_RECORD pirEvent; /* pointer to current queue element */4657 4658 #ifdef DEBUG_LOCAL24659 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::PeekConsoleInputW(%08x,%08x,%08x,%08x).\n",4660 pHMHandleData,4661 pirBuffer,4662 cInRecords,4663 lpcRead);4664 #endif4665 4666 if (ConsoleInputQueryEvents() == 0) /* if queue is currently empty */4667 {4668 *lpcRead = 0; /* no events read from queue */4669 return (TRUE); /* OK, we're done */4670 }4671 4672 4673 for (ulCounter = 0,4674 ulCurrentEvent = ConsoleInput.ulIndexEvent,4675 pirEvent = &ConsoleInput.arrInputRecord[ConsoleInput.ulIndexEvent];4676 4677 ulCounter < cInRecords;4678 4679 ulCounter++,4680 ulCurrentEvent++,4681 pirEvent++,4682 pirBuffer++)4683 {4684 if (ulCurrentEvent > CONSOLE_INPUTQUEUESIZE) /* reaching after end of que*/4685 {4686 ulCurrentEvent = 0; /* then start over from beginning of queue */4687 pirEvent = ConsoleInput.arrInputRecord;4688 }4689 4690 if (pirEvent->EventType == 0x0000) /* no more events ? */4691 break; /* leave loop then */4692 4693 memcpy(pirEvent, /* copy event data */4694 pirBuffer,4695 sizeof(INPUT_RECORD));4696 }4697 4698 *lpcRead = ulCounter; /* return number of events read */4699 return (TRUE); /* OK, we're done */4700 }4701 4702 4703 /*****************************************************************************4704 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleA4705 * Purpose : read a string from the console4706 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data4707 * LPWORD lpwAttribute4708 * DWORD cWriteCells4709 * COORD dwWriteCoord4710 * LPDWORD lpcWritten4711 * Variables :4712 * Result :4713 * Remark :4714 * Status : UNTESTED4715 *4716 * Author : Patrick Haller [Wed, 1998/02/16 11:46]4717 *****************************************************************************/4718 4719 DWORD HMDeviceConsoleInClass::ReadConsoleA(PHMHANDLEDATA pHMHandleData,4720 CONST VOID* lpvBuffer,4721 DWORD cchToRead,4722 LPDWORD lpcchRead,4723 LPVOID lpvReserved)4724 {4725 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;4726 4727 #ifdef DEBUG_LOCAL24728 WriteLog("KERNEL32/CONSOLE: CONIN$::ReadConsoleA(%08x,%08x,%u,%08x,%08x).\n",4729 pHMHandleData,4730 lpvBuffer,4731 cchToRead,4732 lpcchRead,4733 lpvReserved);4734 #endif4735 4736 /* simply forward the request to that routine */4737 return (HMDeviceConsoleInClass::ReadFile(pHMHandleData,4738 lpvBuffer,4739 cchToRead,4740 lpcchRead,4741 NULL));4742 }4743 4744 4745 /*****************************************************************************4746 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleW4747 * Purpose : write a string to the console4748 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data4749 * LPWORD lpwAttribute4750 * DWORD cWriteCells4751 * COORD dwWriteCoord4752 * LPDWORD lpcWritten4753 * Variables :4754 * Result :4755 * Remark :4756 * Status : UNTESTED4757 *4758 * Author : Patrick Haller [Wed, 1998/02/16 11:46]4759 *****************************************************************************/4760 4761 DWORD HMDeviceConsoleInClass::ReadConsoleW(PHMHANDLEDATA pHMHandleData,4762 CONST VOID* lpvBuffer,4763 DWORD cchToRead,4764 LPDWORD lpcchRead,4765 LPVOID lpvReserved)4766 {4767 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;4768 DWORD dwResult;4769 4770 #ifdef DEBUG_LOCAL24771 WriteLog("KERNEL32/CONSOLE: CONIN$::ReadConsoleW(%08x,%08x,%u,%08x,%08x).\n",4772 pHMHandleData,4773 lpvBuffer,4774 cchToRead,4775 lpcchRead,4776 lpvReserved);4777 #endif4778 4779 /* simply forward the request to that routine */4780 dwResult = HMDeviceConsoleInClass::ReadFile(pHMHandleData,4781 lpvBuffer,4782 cchToRead,4783 lpcchRead,4784 NULL);4785 /* @@@PH AScii -> unicode translation */4786 4787 return (dwResult); /* deliver return code */4788 }4789 4790 4791 /*****************************************************************************4792 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleInputA4793 * Purpose : read events placed in the console input queue4794 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data4795 * PINPUT_RECORD pirBuffer - target buffer for events4796 * DWORD cInRecords - number of input records4797 * LPDWORD lpcRead - returns number of events stored4798 * Variables :4799 * Result : TRUE if successful, FALSE otherwise4800 * Remark :4801 * Status : UNTESTED4802 *4803 * Author : Patrick Haller [Tue, 1998/02/10 01:55]4804 *****************************************************************************/4805 4806 DWORD HMDeviceConsoleInClass::ReadConsoleInputA(PHMHANDLEDATA pHMHandleData,4807 PINPUT_RECORD pirBuffer,4808 DWORD cInRecords,4809 LPDWORD lpcRead)4810 {4811 ULONG ulPostCounter; /* semaphore post counter - ignored */4812 APIRET rc; /* API returncode */4813 4814 #ifdef DEBUG_LOCAL24815 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::ReadConsoleInputA(%08x,%08x,%08x,%08x).\n",4816 pHMHandleData,4817 pirBuffer,4818 cInRecords,4819 lpcRead);4820 #endif4821 4822 if (ConsoleInputQueryEvents() == 0) /* if queue is currently empty */4823 {4824 rc = DosWaitEventSem(ConsoleInput.hevInputQueue, /* wait for input */4825 SEM_INDEFINITE_WAIT);4826 DosResetEventSem(ConsoleInput.hevInputQueue, /* reset semaphore */4827 &ulPostCounter); /* post counter - ignored */4828 }4829 4830 4831 /* now read events into target buffer */4832 for (ulPostCounter = 0;4833 ulPostCounter < cInRecords;4834 ulPostCounter++,4835 pirBuffer++)4836 {4837 rc = ConsoleInputEventPop(pirBuffer); /* get event from queue */4838 if (rc != NO_ERROR) /* if read error occurs, break look */4839 break;4840 }4841 4842 *lpcRead = ulPostCounter; /* return number of records read */4843 return (TRUE); /* OK */4844 }4845 4846 4847 /*****************************************************************************4848 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleInputW4849 * Purpose : read events placed in the console input queue4850 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data4851 * PINPUT_RECORD pirBuffer - target buffer for events4852 * DWORD cInRecords - number of input records4853 * LPDWORD lpcRead - returns number of events stored4854 * Variables :4855 * Result : TRUE if successful, FALSE otherwise4856 * Remark :4857 * Status : UNTESTED4858 *4859 * Author : Patrick Haller [Tue, 1998/02/10 01:55]4860 *****************************************************************************/4861 4862 DWORD HMDeviceConsoleInClass::ReadConsoleInputW(PHMHANDLEDATA pHMHandleData,4863 PINPUT_RECORD pirBuffer,4864 DWORD cInRecords,4865 LPDWORD lpcRead)4866 {4867 ULONG ulPostCounter; /* semaphore post counter - ignored */4868 APIRET rc; /* API returncode */4869 4870 #ifdef DEBUG_LOCAL24871 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::ReadConsoleInputW(%08x,%08x,%08x,%08x).\n",4872 pHMHandleData,4873 pirBuffer,4874 cInRecords,4875 lpcRead);4876 #endif4877 4878 if (ConsoleInputQueryEvents() == 0) /* if queue is currently empty */4879 {4880 rc = DosWaitEventSem(ConsoleInput.hevInputQueue, /* wait for input */4881 SEM_INDEFINITE_WAIT);4882 DosResetEventSem(ConsoleInput.hevInputQueue, /* reset semaphore */4883 &ulPostCounter); /* post counter - ignored */4884 }4885 4886 4887 /* now read events into target buffer */4888 for (ulPostCounter = 0;4889 ulPostCounter < cInRecords;4890 ulPostCounter++,4891 pirBuffer++)4892 {4893 rc = ConsoleInputEventPop(pirBuffer); /* get event from queue */4894 if (rc != NO_ERROR) /* if read error occurs, break look */4895 break;4896 }4897 4898 *lpcRead = ulPostCounter; /* return number of records read */4899 return (TRUE); /* OK */4900 }4901 4902 4903 /*****************************************************************************4904 * Name : DWORD HMDeviceConsoleInClass::SetConsoleMode4905 * Purpose : sets the current console mode4906 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data4907 * DWORD dwMode - console mode4908 * Variables :4909 * Result :4910 * Remark :4911 * Status : UNTESTED4912 *4913 * Author : Patrick Haller [Wed, 1998/02/16 11:46]4914 *****************************************************************************/4915 4916 DWORD HMDeviceConsoleInClass::SetConsoleMode(PHMHANDLEDATA pHMHandleData,4917 DWORD dwMode)4918 {4919 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;4920 4921 #ifdef DEBUG_LOCAL24922 WriteLog("KERNEL32/CONSOLE: CONIN$::SetConsoleMode(%08x,%08x).\n",4923 pHMHandleData,4924 dwMode);4925 #endif4926 4927 ConsoleInput.dwConsoleMode = dwMode; /* set current console mode */4928 4929 return (TRUE);4930 }4931 4932 4933 /*****************************************************************************4934 * Name : DWORD HMDeviceConsoleInClass::WriteConsoleInputA4935 * Purpose : this writes event records directly into the queue4936 * Parameters: PHMHANDLEDATA pHMHandleData4937 * PINPUT_RECORD pirBuffer4938 * DWORD cInRecords4939 * LPDWORD lpcWritten4940 * Variables :4941 * Result :4942 * Remark :4943 * Status : NO_ERROR - API succeeded4944 * other - what is to be set in SetLastError4945 *4946 * Author : Patrick Haller [Wed, 1998/02/11 20:44]4947 *****************************************************************************/4948 4949 DWORD HMDeviceConsoleInClass::WriteConsoleInputA (PHMHANDLEDATA pHMHandleData,4950 PINPUT_RECORD pirBuffer,4951 DWORD cInRecords,4952 LPDWORD lpcWritten)4953 {4954 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;4955 APIRET rc; /* API returncode */4956 ULONG ulCounter; /* loop counter */4957 4958 #ifdef DEBUG_LOCAL24959 WriteLog("KERNEL32/CONSOLE: CONIN$::WriteConsoleInputA(%08x,%08x,%u,%08x).\n",4960 pHMHandleData,4961 pirBuffer,4962 cInRecords,4963 lpcWritten);4964 #endif4965 4966 for (ulCounter = 0;4967 ulCounter < cInRecords;4968 ulCounter++,4969 pirBuffer++)4970 {4971 rc = ConsoleInputEventPush(pirBuffer); /* push current event */4972 if (rc != NO_ERROR) /* oops ? queue full ? problem ? */4973 break;4974 }4975 4976 *lpcWritten = ulCounter; /* return number of events written */4977 return (TRUE); /* OK */4978 }4979 4980 4981 /*****************************************************************************4982 * Name : DWORD HMDeviceConsoleInClass::WriteConsoleInputW4983 * Purpose : this writes event records directly into the queue4984 * Parameters: PHMHANDLEDATA pHMHandleData4985 * PINPUT_RECORD pirBuffer4986 * DWORD cInRecords4987 * LPDWORD lpcWritten4988 * Variables :4989 * Result :4990 * Remark :4991 * Status : NO_ERROR - API succeeded4992 * other - what is to be set in SetLastError4993 *4994 * Author : Patrick Haller [Wed, 1998/02/11 20:44]4995 *****************************************************************************/4996 4997 DWORD HMDeviceConsoleInClass::WriteConsoleInputW (PHMHANDLEDATA pHMHandleData,4998 PINPUT_RECORD pirBuffer,4999 DWORD cInRecords,5000 LPDWORD lpcWritten)5001 {5002 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;5003 APIRET rc; /* API returncode */5004 ULONG ulCounter; /* loop counter */5005 5006 #ifdef DEBUG_LOCAL25007 WriteLog("KERNEL32/CONSOLE: CONIN$::WriteConsoleInputW(%08x,%08x,%u,%08x).\n",5008 pHMHandleData,5009 pirBuffer,5010 cInRecords,5011 lpcWritten);5012 #endif5013 5014 for (ulCounter = 0;5015 ulCounter < cInRecords;5016 ulCounter++,5017 pirBuffer++)5018 {5019 rc = ConsoleInputEventPush(pirBuffer); /* push current event */5020 if (rc != NO_ERROR) /* oops ? queue full ? problem ? */5021 break;5022 }5023 5024 *lpcWritten = ulCounter; /* return number of events written */5025 return (TRUE); /* OK */5026 }5027 5028 5029 5030 /*****************************************************************************5031 * Name : DWORD HMDeviceConsoleOutClass::CreateFile5032 * Purpose : this is called from the handle manager if a CreateFile() is5033 * performed on a handle5034 * Parameters: LPCSTR lpFileName name of the file / device5035 * PHMHANDLEDATA pHMHandleData data of the NEW handle5036 * PVOID lpSecurityAttributes ignored5037 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle5038 * Variables :5039 * Result :5040 * Remark :5041 * Status : NO_ERROR - API succeeded5042 * other - what is to be set in SetLastError5043 *5044 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5045 *****************************************************************************/5046 5047 DWORD HMDeviceConsoleOutClass::CreateFile (LPCSTR lpFileName,5048 PHMHANDLEDATA pHMHandleData,5049 PVOID lpSecurityAttributes,5050 PHMHANDLEDATA pHMHandleDataTemplate)5051 {5052 APIRET rc;5053 BOOL fResult;5054 HANDLE hConsole;5055 5056 #ifdef DEBUG_LOCAL25057 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass %s(%s,%08x,%08x,%08x)\n",5058 lpHMDeviceName,5059 lpFileName,5060 pHMHandleData->hHandle,5061 lpSecurityAttributes,5062 pHMHandleDataTemplate);5063 #endif5064 5065 pHMHandleData->dwType = FILE_TYPE_CHAR; /* we're a character device */5066 5067 5068 /* if no default buffer is available, then do default setup */5069 if (ConsoleGlobals.hConsoleBuffer == INVALID_HANDLE_VALUE)5070 {5071 /* now we need a default screen buffer with the default size */5072 hConsole = CreateConsoleScreenBuffer(0,5073 0,5074 NULL,5075 CONSOLE_TEXTMODE_BUFFER,5076 NULL);5077 if (hConsole == INVALID_HANDLE_VALUE)5078 {5079 #ifdef DEBUG_LOCAL5080 WriteLog("KERNEL32/CONSOLE:OS2CreateConsoleScreenBuffer = %u.\n",5081 GetLastError());5082 #endif5083 return INVALID_HANDLE_VALUE; /* abort further processing immediately */5084 }5085 5086 fResult = SetConsoleTextAttribute(hConsole,5087 ConsoleGlobals.Options.ucDefaultAttribute);5088 #ifdef DEBUG_LOCAL5089 if (fResult == FALSE) /* check errors */5090 WriteLog("KERNEL32/CONSOLE:OS2SetConsoleTextAttribute=%u.\n",5091 GetLastError());5092 #endif5093 5094 fResult = SetConsoleScreenBufferSize(hConsole,5095 ConsoleGlobals.Options.coordDefaultSize);5096 if (fResult == FALSE)5097 {5098 #ifdef DEBUG_LOCAL5099 WriteLog("KERNEL32/CONSOLE:OS2SetConsoleScreenBufferSize=%u.\n",5100 GetLastError());5101 #endif5102 HMCloseHandle(hConsole); /* free handle again */5103 return (INVALID_HANDLE_VALUE); /* abort further processing */5104 }5105 5106 fResult = SetConsoleActiveScreenBuffer(hConsole);5107 if (fResult == FALSE)5108 {5109 #ifdef DEBUG_LOCAL5110 WriteLog("KERNEL32/CONSOLE:OS2SetConsoleActiveScreenBuffer=%u.\n",5111 GetLastError());5112 #endif5113 HMCloseHandle(hConsole); /* free handle again */5114 return (INVALID_HANDLE_VALUE); /* abort further processing */5115 }5116 else5117 {5118 ConsoleGlobals.hConsoleBufferDefault = hConsole; /* save handle */5119 ConsoleGlobals.hConsoleBuffer = hConsole;5120 }5121 }5122 5123 return(NO_ERROR);5124 }5125 5126 5127 /*****************************************************************************5128 * Name :5129 * Purpose :5130 * Parameters:5131 * Variables :5132 * Result :5133 * Remark :5134 * Status :5135 *5136 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5137 *****************************************************************************/5138 5139 DWORD HMDeviceConsoleOutClass::ReadFile(PHMHANDLEDATA pHMHandleData,5140 LPCVOID lpBuffer,5141 DWORD nNumberOfBytesToRead,5142 LPDWORD lpNumberOfBytesRead,5143 LPOVERLAPPED lpOverlapped)5144 {5145 5146 #ifdef DEBUG_LOCAL5147 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",5148 lpHMDeviceName,5149 pHMHandleData->hHandle,5150 lpBuffer,5151 nNumberOfBytesToRead,5152 lpNumberOfBytesRead,5153 lpOverlapped);5154 #endif5155 5156 return(ERROR_ACCESS_DENIED);5157 }5158 5159 5160 /*****************************************************************************5161 * Name :5162 * Purpose :5163 * Parameters:5164 * Variables :5165 * Result :5166 * Remark :5167 * Status :5168 *5169 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5170 *****************************************************************************/5171 5172 DWORD HMDeviceConsoleOutClass::WriteFile(PHMHANDLEDATA pHMHandleData,5173 LPCVOID lpBuffer,5174 DWORD nNumberOfBytesToWrite,5175 LPDWORD lpNumberOfBytesWritten,5176 LPOVERLAPPED lpOverlapped)5177 {5178 DWORD dwResult; /* result from subsequent WriteFile */5179 5180 #ifdef DEBUG_LOCAL25181 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",5182 lpHMDeviceName,5183 pHMHandleData->hHandle,5184 lpBuffer,5185 nNumberOfBytesToWrite,5186 lpNumberOfBytesWritten,5187 lpOverlapped);5188 #endif5189 5190 /* just prevent an endless loop, although this condition might never */5191 /* be true ! */5192 if (pHMHandleData->hHandle != ConsoleGlobals.hConsoleBuffer)5193 {5194 #if 05195 HMDeviceRequest(ConsoleGlobals.hConsoleBuffer, /* hide the cursor */5196 DRQ_INTERNAL_CONSOLECURSORSHOW,5197 CONSOLECURSOR_HIDE,5198 0,5199 0,5200 0);5201 #endif5202 5203 dwResult = HMWriteFile(ConsoleGlobals.hConsoleBuffer,5204 lpBuffer,5205 nNumberOfBytesToWrite,5206 lpNumberOfBytesWritten,5207 lpOverlapped);5208 5209 #if 05210 HMDeviceRequest(ConsoleGlobals.hConsoleBuffer, /* show the cursor */5211 DRQ_INTERNAL_CONSOLECURSORSHOW,5212 CONSOLECURSOR_SHOW,5213 0,5214 0,5215 0);5216 #endif5217 5218 return (dwResult); /* return result code */5219 }5220 else5221 return (ERROR_SYS_INTERNAL); /* raise error condition */5222 }5223 5224 5225 /*****************************************************************************5226 * Name : DWORD HMDeviceConsoleOutClass::_DeviceRequest5227 * Purpose : we just forward those device requests to the console buffer5228 * currently associated with the console itself.5229 * Parameters:5230 * Variables :5231 * Result :5232 * Remark :5233 * Status : UNTESTED5234 *5235 * Author : Patrick Haller [Wed, 1998/03/35 20:44]5236 *****************************************************************************/5237 5238 DWORD HMDeviceConsoleOutClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,5239 ULONG ulRequestCode,5240 ULONG arg1,5241 ULONG arg2,5242 ULONG arg3,5243 ULONG arg4)5244 {5245 #ifdef DEBUG_LOCAL25246 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x)\n",5247 lpHMDeviceName,5248 pHMHandleData->hHandle,5249 ulRequestCode,5250 arg1,5251 arg2,5252 arg3,5253 arg4);5254 #endif5255 /* just prevent an endless loop, although this condition might never */5256 /* be true ! */5257 if (pHMHandleData->hHandle != ConsoleGlobals.hConsoleBuffer)5258 return (HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,5259 ulRequestCode,5260 arg1,5261 arg2,5262 arg3,5263 arg4));5264 else5265 return (ERROR_SYS_INTERNAL); /* raise error condition */5266 }5267 5268 5269 /*****************************************************************************5270 * Name : DWORD HMDeviceConsoleBufferClass::CreateFile5271 * Purpose : this is called from the handle manager if a CreateFile() is5272 * performed on a handle5273 * Parameters: LPCSTR lpFileName name of the file / device5274 * PHMHANDLEDATA pHMHandleData data of the NEW handle5275 * PVOID lpSecurityAttributes ignored5276 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle5277 * Variables :5278 * Result :5279 * Remark :5280 * Status : NO_ERROR - API succeeded5281 * other - what is to be set in SetLastError5282 *5283 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5284 *****************************************************************************/5285 5286 DWORD HMDeviceConsoleBufferClass::CreateFile (LPCSTR lpFileName,5287 PHMHANDLEDATA pHMHandleData,5288 PVOID lpSecurityAttributes,5289 PHMHANDLEDATA pHMHandleDataTemplate)5290 {5291 PCONSOLEBUFFER pConsoleBuffer; /* console buffer structure */5292 5293 #ifdef DEBUG_LOCAL5294 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass %s(%s,%08x,%08x,%08x)\n",5295 lpHMDeviceName,5296 lpFileName,5297 pHMHandleData->hHandle,5298 lpSecurityAttributes,5299 pHMHandleDataTemplate);5300 #endif5301 5302 pHMHandleData->dwType = FILE_TYPE_CHAR; /* we're a character device */5303 5304 pHMHandleData->lpHandlerData = malloc ( sizeof(CONSOLEBUFFER) );5305 5306 #ifdef DEBUG_LOCAL5307 WriteLog("KERNEL32/CONSOLE:CheckPoint1: %s pHMHandleData=%08xh, lpHandlerData=%08xh\n",5308 lpFileName,5309 pHMHandleData,5310 pHMHandleData->lpHandlerData);5311 #endif5312 5313 5314 if (pHMHandleData->lpHandlerData == NULL) /* check allocation */5315 {5316 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* set error information */5317 return (INVALID_HANDLE_VALUE); /* raise error condition */5318 }5319 else5320 {5321 pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;5322 5323 memset(pHMHandleData->lpHandlerData, /* initialize structure */5324 0,5325 sizeof (CONSOLEBUFFER) );5326 5327 /* set buffer defaults */5328 pConsoleBuffer->dwConsoleMode = ENABLE_PROCESSED_OUTPUT |5329 ENABLE_WRAP_AT_EOL_OUTPUT;5330 5331 pConsoleBuffer->CursorInfo.dwSize = 2; /* 2 scanlines */5332 pConsoleBuffer->CursorInfo.bVisible = TRUE;5333 }5334 5335 return(NO_ERROR);5336 }5337 5338 5339 /*****************************************************************************5340 * Name :5341 * Purpose :5342 * Parameters:5343 * Variables :5344 * Result :5345 * Remark :5346 * Status :5347 *5348 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5349 *****************************************************************************/5350 5351 DWORD HMDeviceConsoleBufferClass::CloseHandle(PHMHANDLEDATA pHMHandleData)5352 {5353 5354 #ifdef DEBUG_LOCAL5355 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass::CloseHandle %s(%08x)\n",5356 lpHMDeviceName,5357 pHMHandleData);5358 #endif5359 5360 if (pHMHandleData->lpHandlerData != NULL) /* check pointer */5361 {5362 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;5363 5364 5365 if (pConsoleBuffer->ppszLine != NULL) /* free line buffer array ! */5366 free (pConsoleBuffer->ppszLine);5367 5368 free (pHMHandleData->lpHandlerData); /* free device object data */5369 pHMHandleData->lpHandlerData = NULL;5370 }5371 5372 return(NO_ERROR);5373 }5374 5375 5376 /*****************************************************************************5377 * Name :5378 * Purpose :5379 * Parameters:5380 * Variables :5381 * Result :5382 * Remark :5383 * Status :5384 *5385 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5386 *****************************************************************************/5387 5388 DWORD HMDeviceConsoleBufferClass::ReadFile(PHMHANDLEDATA pHMHandleData,5389 LPCVOID lpBuffer,5390 DWORD nNumberOfBytesToRead,5391 LPDWORD lpNumberOfBytesRead,5392 LPOVERLAPPED lpOverlapped)5393 {5394 5395 #ifdef DEBUG_LOCAL5396 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",5397 lpHMDeviceName,5398 pHMHandleData->hHandle,5399 lpBuffer,5400 nNumberOfBytesToRead,5401 lpNumberOfBytesRead,5402 lpOverlapped);5403 #endif5404 5405 return(ERROR_ACCESS_DENIED);5406 }5407 5408 5409 /*****************************************************************************5410 * Name :5411 * Purpose :5412 * Parameters:5413 * Variables :5414 * Result :5415 * Remark :5416 * Status :5417 *5418 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5419 *****************************************************************************/5420 5421 DWORD HMDeviceConsoleBufferClass::WriteFile(PHMHANDLEDATA pHMHandleData,5422 LPCVOID lpBuffer,5423 DWORD nNumberOfBytesToWrite,5424 LPDWORD lpNumberOfBytesWritten,5425 LPOVERLAPPED lpOverlapped)5426 {5427 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;5428 ULONG ulCounter; /* counter for the byte transfer */5429 PSZ pszBuffer = (PSZ)lpBuffer;5430 register UCHAR ucChar;5431 5432 #ifdef DEBUG_LOCAL25433 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",5434 lpHMDeviceName,5435 pHMHandleData->hHandle,5436 lpBuffer,5437 nNumberOfBytesToWrite,5438 lpNumberOfBytesWritten,5439 lpOverlapped);5440 #endif5441 5442 /* check if we're called with non-existing line buffer */5443 if (pConsoleBuffer->ppszLine == NULL)5444 return (ERROR_SYS_INTERNAL);5445 5446 for (ulCounter = 0;5447 ulCounter < nNumberOfBytesToWrite;5448 ulCounter++)5449 {5450 ucChar = pszBuffer[ulCounter]; /* map to register */5451 5452 if ( (pConsoleBuffer->dwConsoleMode & ENABLE_PROCESSED_OUTPUT) &&5453 (ucChar < 32) ) /* this is faster than a large switch statement */5454 {5455 switch (ucChar)5456 {5457 case 7: /* BEL */5458 if (ConsoleGlobals.Options.fSpeakerEnabled == TRUE)5459 DosBeep(ConsoleGlobals.Options.ulSpeakerFrequency,5460 ConsoleGlobals.Options.ulSpeakerDuration);5461 break;5462 5463 case 8: /* Backspace */5464 if (pConsoleBuffer->coordCursorPosition.X > 0)5465 pConsoleBuffer->coordCursorPosition.X--;5466 break;5467 5468 case 9: /* Tab */5469 pConsoleBuffer->coordCursorPosition.X =5470 (pConsoleBuffer->coordCursorPosition.X5471 / ConsoleGlobals.Options.ulTabSize5472 + 1)5473 * ConsoleGlobals.Options.ulTabSize;5474 5475 if (pConsoleBuffer->coordCursorPosition.X >=5476 pConsoleBuffer->coordBufferSize.X)5477 {5478 pConsoleBuffer->coordCursorPosition.X = 0;5479 pConsoleBuffer->coordCursorPosition.Y++;5480 5481 if (pConsoleBuffer->coordCursorPosition.Y >=5482 pConsoleBuffer->coordBufferSize.Y)5483 {5484 if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)5485 {5486 ConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */5487 1);5488 pConsoleBuffer->coordCursorPosition.Y--;5489 }5490 }5491 }5492 break;5493 5494 case 10: /* LINEFEED */5495 pConsoleBuffer->coordCursorPosition.Y++;5496 5497 if (pConsoleBuffer->coordCursorPosition.Y >=5498 pConsoleBuffer->coordBufferSize.Y)5499 {5500 ConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */5501 1);5502 pConsoleBuffer->coordCursorPosition.Y--;5503 }5504 break;5505 5506 case 13: /* CARRIAGE RETURN */5507 pConsoleBuffer->coordCursorPosition.X = 0;5508 break;5509 5510 default:5511 break;5512 }5513 }5514 else5515 {5516 /* write character */5517 *(pConsoleBuffer->ppszLine[pConsoleBuffer->coordCursorPosition.Y] +5518 pConsoleBuffer->coordCursorPosition.X * 2) = pszBuffer[ulCounter];5519 5520 pConsoleBuffer->coordCursorPosition.X++;5521 5522 if (pConsoleBuffer->coordCursorPosition.X >=5523 pConsoleBuffer->coordBufferSize.X)5524 {5525 pConsoleBuffer->coordCursorPosition.X = 0;5526 pConsoleBuffer->coordCursorPosition.Y++;5527 5528 if (pConsoleBuffer->coordCursorPosition.Y >=5529 pConsoleBuffer->coordBufferSize.Y)5530 {5531 if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)5532 {5533 ConsoleBufferScrollUp(pConsoleBuffer, /* scroll one line up */5534 1);5535 pConsoleBuffer->coordCursorPosition.Y--;5536 }5537 else5538 {5539 /* just stay on last character */5540 pConsoleBuffer->coordCursorPosition.X = pConsoleBuffer->coordBufferSize.X - 1;5541 pConsoleBuffer->coordCursorPosition.Y = pConsoleBuffer->coordBufferSize.Y - 1;5542 }5543 }5544 }5545 }5546 }5547 5548 /* update screen if active console */5549 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)5550 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */5551 5552 *lpNumberOfBytesWritten = ulCounter;5553 5554 return(ulCounter);5555 }5556 5557 5558 /*****************************************************************************5559 * Name :5560 * Purpose :5561 * Parameters:5562 * Variables :5563 * Result :5564 * Remark :5565 * Status :5566 *5567 * Author : Patrick Haller [Wed, 1998/02/11 20:44]5568 *****************************************************************************/5569 5570 DWORD HMDeviceConsoleBufferClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,5571 ULONG ulRequestCode,5572 ULONG arg1,5573 ULONG arg2,5574 ULONG arg3,5575 ULONG arg4)5576 {5577 switch (ulRequestCode)5578 {5579 case DRQ_FILLCONSOLEOUTPUTATTRIBUTE:5580 {5581 COORD coordWrite;5582 5583 ULONG2COORD(coordWrite,arg3);5584 5585 return (HMDeviceConsoleBufferClass5586 ::FillConsoleOutputAttribute(pHMHandleData,5587 (WORD)arg1,5588 (DWORD)arg2,5589 coordWrite,5590 (LPDWORD)arg4));5591 }5592 5593 5594 case DRQ_FILLCONSOLEOUTPUTCHARACTERA:5595 {5596 COORD coordWrite;5597 5598 ULONG2COORD(coordWrite,arg3);5599 5600 return (HMDeviceConsoleBufferClass5601 ::FillConsoleOutputCharacterA(pHMHandleData,5602 (UCHAR)arg1,5603 (DWORD)arg2,5604 coordWrite,5605 (LPDWORD)arg4));5606 }5607 5608 5609 case DRQ_FILLCONSOLEOUTPUTCHARACTERW:5610 {5611 COORD coordWrite;5612 5613 ULONG2COORD(coordWrite,arg3);5614 5615 return (HMDeviceConsoleBufferClass5616 ::FillConsoleOutputCharacterW(pHMHandleData,5617 (WCHAR)arg1,5618 (DWORD)arg2,5619 coordWrite,5620 (LPDWORD)arg4));5621 }5622 5623 5624 case DRQ_GETCONSOLECURSORINFO:5625 return (HMDeviceConsoleBufferClass5626 ::GetConsoleCursorInfo(pHMHandleData,5627 (PCONSOLE_CURSOR_INFO)arg1));5628 5629 5630 case DRQ_GETCONSOLEMODE:5631 return (HMDeviceConsoleBufferClass5632 ::GetConsoleMode(pHMHandleData,5633 (LPDWORD)arg1));5634 5635 5636 case DRQ_GETCONSOLESCREENBUFFERINFO:5637 return (HMDeviceConsoleBufferClass5638 ::GetConsoleScreenBufferInfo(pHMHandleData,5639 (PCONSOLE_SCREEN_BUFFER_INFO)arg1));5640 5641 5642 case DRQ_GETLARGESTCONSOLEWINDOWSIZE:5643 return (HMDeviceConsoleBufferClass5644 ::GetLargestConsoleWindowSize(pHMHandleData));5645 5646 5647 case DRQ_READCONSOLEOUTPUTA:5648 {5649 COORD coordDestBufferSize;5650 COORD coordDestBufferCoord;5651 5652 ULONG2COORD(coordDestBufferSize, arg2);5653 ULONG2COORD(coordDestBufferCoord, arg3);5654 5655 return (HMDeviceConsoleBufferClass5656 ::ReadConsoleOutputA(pHMHandleData,5657 (PCHAR_INFO)arg1,5658 coordDestBufferSize,5659 coordDestBufferCoord,5660 (PSMALL_RECT)arg4));5661 }5662 5663 5664 case DRQ_READCONSOLEOUTPUTW:5665 {5666 COORD coordDestBufferSize;5667 COORD coordDestBufferCoord;5668 5669 ULONG2COORD(coordDestBufferSize, arg2);5670 ULONG2COORD(coordDestBufferCoord, arg3);5671 5672 return (HMDeviceConsoleBufferClass5673 ::ReadConsoleOutputW(pHMHandleData,5674 (PCHAR_INFO)arg1,5675 coordDestBufferSize,5676 coordDestBufferCoord,5677 (PSMALL_RECT)arg4));5678 }5679 5680 5681 case DRQ_READCONSOLEOUTPUTATTRIBUTE:5682 {5683 COORD coordReadCoord;5684 5685 ULONG2COORD(coordReadCoord, arg3);5686 5687 return (HMDeviceConsoleBufferClass5688 ::ReadConsoleOutputAttribute(pHMHandleData,5689 (LPWORD)arg1,5690 (DWORD)arg2,5691 coordReadCoord,5692 (LPDWORD)arg4));5693 }5694 5695 5696 case DRQ_READCONSOLEOUTPUTCHARACTERA:5697 {5698 COORD coordReadCoord;5699 5700 ULONG2COORD(coordReadCoord, arg3);5701 5702 return (HMDeviceConsoleBufferClass5703 ::ReadConsoleOutputCharacterA(pHMHandleData,5704 (LPTSTR)arg1,5705 (DWORD)arg2,5706 coordReadCoord,5707 (LPDWORD)arg4));5708 }5709 5710 5711 case DRQ_READCONSOLEOUTPUTCHARACTERW:5712 {5713 COORD coordReadCoord;5714 5715 ULONG2COORD(coordReadCoord, arg3);5716 5717 return (HMDeviceConsoleBufferClass5718 ::ReadConsoleOutputCharacterW(pHMHandleData,5719 (LPWSTR)arg1,5720 (DWORD)arg2,5721 coordReadCoord,5722 (LPDWORD)arg4));5723 }5724 5725 5726 case DRQ_SCROLLCONSOLESCREENBUFFERA:5727 {5728 COORD coordDestOrigin;5729 5730 ULONG2COORD(coordDestOrigin, arg3);5731 5732 return (HMDeviceConsoleBufferClass5733 ::ScrollConsoleScreenBufferA(pHMHandleData,5734 (PSMALL_RECT)arg1,5735 (PSMALL_RECT)arg2,5736 coordDestOrigin,5737 (PCHAR_INFO)arg4));5738 }5739 5740 5741 case DRQ_SCROLLCONSOLESCREENBUFFERW:5742 {5743 COORD coordDestOrigin;5744 5745 ULONG2COORD(coordDestOrigin, arg3);5746 5747 return (HMDeviceConsoleBufferClass5748 ::ScrollConsoleScreenBufferW(pHMHandleData,5749 (PSMALL_RECT)arg1,5750 (PSMALL_RECT)arg2,5751 coordDestOrigin,5752 (PCHAR_INFO)arg4));5753 }5754 5755 5756 case DRQ_SETCONSOLEACTIVESCREENBUFFER:5757 return (HMDeviceConsoleBufferClass5758 ::SetConsoleActiveScreenBuffer(pHMHandleData));5759 5760 5761 case DRQ_SETCONSOLECURSORINFO:5762 return (HMDeviceConsoleBufferClass5763 ::SetConsoleCursorInfo(pHMHandleData,5764 (PCONSOLE_CURSOR_INFO)arg1));5765 5766 5767 case DRQ_SETCONSOLECURSORPOSITION:5768 {5769 COORD coordCursor;5770 5771 ULONG2COORD(coordCursor, arg1);5772 5773 return (HMDeviceConsoleBufferClass5774 ::SetConsoleCursorPosition(pHMHandleData,5775 coordCursor));5776 }5777 5778 5779 case DRQ_SETCONSOLEMODE:5780 return (HMDeviceConsoleBufferClass5781 ::SetConsoleMode(pHMHandleData,5782 (DWORD)arg1));5783 5784 5785 case DRQ_SETCONSOLESCREENBUFFERSIZE:5786 {5787 COORD coordSize;5788 5789 ULONG2COORD(coordSize,arg1);5790 5791 return (HMDeviceConsoleBufferClass::5792 SetConsoleScreenBufferSize(pHMHandleData,5793 coordSize));5794 }5795 5796 5797 case DRQ_SETCONSOLETEXTATTRIBUTE:5798 return (HMDeviceConsoleBufferClass::5799 SetConsoleTextAttribute(pHMHandleData,5800 (WORD)arg1));5801 5802 5803 case DRQ_SETCONSOLEWINDOWINFO:5804 return (HMDeviceConsoleBufferClass5805 ::SetConsoleWindowInfo(pHMHandleData,5806 (BOOL)arg1,5807 (PSMALL_RECT)arg2));5808 5809 5810 case DRQ_WRITECONSOLEA:5811 return (HMDeviceConsoleBufferClass5812 ::WriteConsoleA(pHMHandleData,5813 (CONST VOID*)arg1,5814 (DWORD)arg2,5815 (LPDWORD)arg3,5816 (LPVOID)arg4));5817 5818 5819 case DRQ_WRITECONSOLEW:5820 return (HMDeviceConsoleBufferClass5821 ::WriteConsoleW(pHMHandleData,5822 (CONST VOID*)arg1,5823 (DWORD)arg2,5824 (LPDWORD)arg3,5825 (LPVOID)arg4));5826 5827 5828 case DRQ_WRITECONSOLEOUTPUTA:5829 {5830 COORD coordSrcBufferSize;5831 COORD coordSrcBufferCoord;5832 5833 ULONG2COORD(coordSrcBufferSize, arg2);5834 ULONG2COORD(coordSrcBufferCoord, arg3);5835 5836 return (HMDeviceConsoleBufferClass5837 ::WriteConsoleOutputA(pHMHandleData,5838 (PCHAR_INFO)arg1,5839 coordSrcBufferSize,5840 coordSrcBufferCoord,5841 (PSMALL_RECT)arg4));5842 }5843 5844 5845 case DRQ_WRITECONSOLEOUTPUTW:5846 {5847 COORD coordSrcBufferSize;5848 COORD coordSrcBufferCoord;5849 5850 ULONG2COORD(coordSrcBufferSize, arg2);5851 ULONG2COORD(coordSrcBufferCoord, arg3);5852 5853 return (HMDeviceConsoleBufferClass5854 ::WriteConsoleOutputA(pHMHandleData,5855 (PCHAR_INFO)arg1,5856 coordSrcBufferSize,5857 coordSrcBufferCoord,5858 (PSMALL_RECT)arg4));5859 }5860 5861 5862 case DRQ_WRITECONSOLEOUTPUTATTRIBUTE:5863 {5864 COORD coordWriteCoord;5865 5866 ULONG2COORD(coordWriteCoord, arg3);5867 5868 return (HMDeviceConsoleBufferClass5869 ::WriteConsoleOutputAttribute(pHMHandleData,5870 (LPWORD)arg1,5871 (DWORD)arg2,5872 coordWriteCoord,5873 (LPDWORD)arg4));5874 }5875 5876 5877 case DRQ_WRITECONSOLEOUTPUTCHARACTERA:5878 {5879 COORD coordWriteCoord;5880 5881 ULONG2COORD(coordWriteCoord, arg3);5882 5883 return (HMDeviceConsoleBufferClass5884 ::WriteConsoleOutputCharacterA(pHMHandleData,5885 (LPTSTR)arg1,5886 (DWORD)arg2,5887 coordWriteCoord,5888 (LPDWORD)arg4));5889 }5890 5891 5892 case DRQ_WRITECONSOLEOUTPUTCHARACTERW:5893 {5894 COORD coordWriteCoord;5895 5896 ULONG2COORD(coordWriteCoord, arg3);5897 5898 return (HMDeviceConsoleBufferClass5899 ::WriteConsoleOutputCharacterW(pHMHandleData,5900 (LPWSTR)arg1,5901 (DWORD)arg2,5902 coordWriteCoord,5903 (LPDWORD)arg4));5904 }5905 5906 5907 case DRQ_INTERNAL_CONSOLEBUFFERMAP:5908 ConsoleBufferMap((PCONSOLEBUFFER)pHMHandleData->lpHandlerData);5909 return (NO_ERROR);5910 5911 5912 case DRQ_INTERNAL_CONSOLECURSORSHOW:5913 ConsoleCursorShow((PCONSOLEBUFFER)pHMHandleData->lpHandlerData,5914 (ULONG)arg1);5915 return (NO_ERROR);5916 5917 5918 case DRQ_INTERNAL_CONSOLEADJUSTWINDOW:5919 ConsoleAdjustWindow((PCONSOLEBUFFER)pHMHandleData->lpHandlerData);5920 return (NO_ERROR);5921 }5922 5923 5924 #ifdef DEBUG_LOCAL5925 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x) unknown request\n",5926 lpHMDeviceName,5927 pHMHandleData->hHandle,5928 ulRequestCode,5929 arg1,5930 arg2,5931 arg3,5932 arg4);5933 #endif5934 5935 SetLastError(ERROR_INVALID_FUNCTION); /* request not implemented */5936 return(FALSE); /* we assume this indicates API call failed */5937 }5938 5939 5940 /*****************************************************************************5941 * Name : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputAttribute5942 * Purpose : fills the console buffer with a specified attribute5943 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data5944 * WORD wAttribute5945 * DWORD nLength5946 * COORD dwWriteCoord5947 * LPDWORD lpNumberOfAttrsWritten5948 * Variables :5949 * Result :5950 * Remark :5951 * Status : UNTESTED5952 *5953 * Author : Patrick Haller [Wed, 1998/02/16 11:46]5954 *****************************************************************************/5955 5956 DWORD HMDeviceConsoleBufferClass::FillConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,5957 WORD wAttribute,5958 DWORD nLength,5959 COORD dwWriteCoord,5960 LPDWORD lpNumberOfAttrsWritten)5961 {5962 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;5963 ULONG ulCounter; /* current character counter */5964 5965 #ifdef DEBUG_LOCAL25966 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputAttribute(%08x,attr=%04x,%u,x=%u y=%u,res=%08x).\n",5967 pHMHandleData,5968 wAttribute,5969 nLength,5970 dwWriteCoord.X,5971 dwWriteCoord.Y,5972 lpNumberOfAttrsWritten);5973 #endif5974 5975 if ( (dwWriteCoord.X < 0) ||5976 (dwWriteCoord.Y < 0) )5977 {5978 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */5979 *lpNumberOfAttrsWritten = 0; /* complete error handling */5980 5981 SetLastError(ERROR_INVALID_PARAMETER);5982 return (FALSE);5983 }5984 5985 /* check if dwWriteCoord is within specs */5986 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||5987 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )5988 {5989 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */5990 *lpNumberOfAttrsWritten = 0; /* complete error handling */5991 5992 SetLastError(ERROR_INVALID_PARAMETER);5993 return (FALSE);5994 }5995 5996 5997 /* OK, now write the attribute lines */5998 for (ulCounter = 0;5999 ulCounter < nLength;6000 ulCounter++)6001 {6002 /* write attribute into cell */6003 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +6004 (dwWriteCoord.X * 2 + 1)6005 ) = (UCHAR)(wAttribute & 0xFF);6006 /* write attribute, don't change characters */6007 6008 dwWriteCoord.X++; /* move write position */6009 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)6010 {6011 dwWriteCoord.X = 0; /* skip to next line */6012 dwWriteCoord.Y++;6013 6014 /* oops, we're at the end of the buffer. Abort now. */6015 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)6016 {6017 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */6018 *lpNumberOfAttrsWritten = ulCounter;6019 6020 /* update screen if active console */6021 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)6022 ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */6023 6024 return (TRUE);6025 }6026 }6027 }6028 6029 /* update screen if active console */6030 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)6031 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */6032 6033 if (lpNumberOfAttrsWritten != NULL) /* ensure pointer is valid */6034 *lpNumberOfAttrsWritten = nLength;6035 6036 return (TRUE);6037 }6038 6039 6040 /*****************************************************************************6041 * Name : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA6042 * Purpose : fills the console buffer with a specified ASCII character6043 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6044 * UCHAR ucCharacter6045 * DWORD nLength6046 * COORD dwWriteCoord6047 * LPDWORD lpNumberOfCharsWritten6048 * Variables :6049 * Result :6050 * Remark :6051 * Status : UNTESTED6052 *6053 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6054 *****************************************************************************/6055 6056 DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,6057 UCHAR ucCharacter,6058 DWORD nLength,6059 COORD dwWriteCoord,6060 LPDWORD lpNumberOfCharsWritten)6061 {6062 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6063 ULONG ulCounter; /* current character counter */6064 6065 #ifdef DEBUG_LOCAL26066 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputCharacterA(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",6067 pHMHandleData,6068 ucCharacter,6069 nLength,6070 dwWriteCoord.X,6071 dwWriteCoord.Y,6072 lpNumberOfCharsWritten);6073 #endif6074 6075 if ( (dwWriteCoord.X < 0) ||6076 (dwWriteCoord.Y < 0) )6077 {6078 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6079 *lpNumberOfCharsWritten = 0; /* complete error handling */6080 6081 SetLastError(ERROR_INVALID_PARAMETER);6082 return (FALSE);6083 }6084 6085 6086 /* check if dwWriteCoord is within specs */6087 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||6088 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )6089 {6090 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6091 *lpNumberOfCharsWritten = 0; /* complete error handling */6092 6093 SetLastError(ERROR_INVALID_PARAMETER);6094 return (FALSE);6095 }6096 6097 6098 /* OK, now write the attribute lines */6099 for (ulCounter = 0;6100 ulCounter < nLength;6101 ulCounter++)6102 {6103 /* write character into cell */6104 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +6105 (dwWriteCoord.X * 2)6106 ) = ucCharacter;6107 6108 dwWriteCoord.X++; /* move write position */6109 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)6110 {6111 dwWriteCoord.X = 0; /* skip to next line */6112 dwWriteCoord.Y++;6113 6114 /* oops, we're at the end of the buffer. Abort now. */6115 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)6116 {6117 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6118 *lpNumberOfCharsWritten = ulCounter;6119 6120 /* update screen if active console */6121 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)6122 ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */6123 6124 return (TRUE);6125 }6126 }6127 }6128 6129 /* update screen if active console */6130 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)6131 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */6132 6133 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6134 *lpNumberOfCharsWritten = nLength;6135 6136 return (TRUE);6137 }6138 6139 6140 /*****************************************************************************6141 * Name : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterW6142 * Purpose : fills the console buffer with a specified ASCII character6143 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6144 * WCHAR wcCharacter6145 * DWORD nLength6146 * COORD dwWriteCoord6147 * LPDWORD lpNumberOfCharsWritten6148 * Variables :6149 * Result :6150 * Remark :6151 * Status : UNTESTED6152 *6153 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6154 *****************************************************************************/6155 6156 DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,6157 WCHAR wcCharacter,6158 DWORD nLength,6159 COORD dwWriteCoord,6160 LPDWORD lpNumberOfCharsWritten)6161 {6162 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6163 ULONG ulCounter; /* current character counter */6164 6165 #ifdef DEBUG_LOCAL26166 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputCharacterW(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",6167 pHMHandleData,6168 wcCharacter,6169 nLength,6170 dwWriteCoord.X,6171 dwWriteCoord.Y,6172 lpNumberOfCharsWritten);6173 #endif6174 6175 if ( (dwWriteCoord.X < 0) ||6176 (dwWriteCoord.Y < 0) )6177 {6178 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6179 *lpNumberOfCharsWritten = 0; /* complete error handling */6180 6181 SetLastError(ERROR_INVALID_PARAMETER);6182 return (FALSE);6183 }6184 6185 6186 /* check if dwWriteCoord is within specs */6187 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||6188 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )6189 {6190 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6191 *lpNumberOfCharsWritten = 0; /* complete error handling */6192 6193 SetLastError(ERROR_INVALID_PARAMETER);6194 return (FALSE);6195 }6196 6197 6198 /* OK, now write the attribute lines */6199 for (ulCounter = 0;6200 ulCounter < nLength;6201 ulCounter++)6202 {6203 /* write character into cell */6204 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +6205 (dwWriteCoord.X * 2)6206 ) = (UCHAR)wcCharacter; /* @@@PH unicode to ascii conversion ! */6207 6208 dwWriteCoord.X++; /* move write position */6209 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)6210 {6211 dwWriteCoord.X = 0; /* skip to next line */6212 dwWriteCoord.Y++;6213 6214 /* oops, we're at the end of the buffer. Abort now. */6215 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)6216 {6217 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6218 *lpNumberOfCharsWritten = ulCounter;6219 6220 /* update screen if active console */6221 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)6222 ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */6223 6224 return (TRUE);6225 }6226 }6227 }6228 6229 /* update screen if active console */6230 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)6231 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */6232 6233 if (lpNumberOfCharsWritten != NULL) /* ensure pointer is valid */6234 *lpNumberOfCharsWritten = nLength;6235 6236 return (TRUE);6237 }6238 6239 6240 6241 /*****************************************************************************6242 * Name : DWORD HMDeviceConsoleBufferClass::GetConsoleMode6243 * Purpose : queries the current console mode6244 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6245 * LPDWORD lpMode6246 * Variables :6247 * Result :6248 * Remark :6249 * Status : UNTESTED6250 *6251 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6252 *****************************************************************************/6253 6254 DWORD HMDeviceConsoleBufferClass::GetConsoleMode(PHMHANDLEDATA pHMHandleData,6255 LPDWORD lpMode)6256 {6257 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6258 6259 #ifdef DEBUG_LOCAL26260 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleMode(%08x,%08x).\n",6261 pHMHandleData,6262 lpMode);6263 #endif6264 6265 *lpMode = pConsoleBuffer->dwConsoleMode; /* return current console mode */6266 6267 return (TRUE);6268 }6269 6270 6271 /*****************************************************************************6272 * Name : DWORD HMDeviceConsoleBufferClass::GetConsoleCursorInfo6273 * Purpose : queries the current console's cursor information6274 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6275 * PCONSOLE_CURSOR_INFO pCCI6276 * Variables :6277 * Result :6278 * Remark :6279 * Status : UNTESTED6280 *6281 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6282 *****************************************************************************/6283 6284 DWORD HMDeviceConsoleBufferClass::GetConsoleCursorInfo(PHMHANDLEDATA pHMHandleData,6285 PCONSOLE_CURSOR_INFO pCCI)6286 {6287 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6288 6289 #ifdef DEBUG_LOCAL26290 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleCursorInfo(%08x,%08x).\n",6291 pHMHandleData,6292 pCCI);6293 #endif6294 6295 memcpy(pCCI, /* just copy the whole information block */6296 &pConsoleBuffer->CursorInfo,6297 sizeof (pConsoleBuffer->CursorInfo) );6298 6299 return (TRUE);6300 }6301 6302 6303 /*****************************************************************************6304 * Name : DWORD HMDeviceConsoleBufferClass::GetConsoleScreenBufferInfo6305 * Purpose : queries the current console screen buffer's info6306 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6307 * PCONSOLE_SCREEN_BUFFER_INFO pCSBI6308 * Variables :6309 * Result :6310 * Remark :6311 * Status : UNTESTED6312 *6313 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6314 *****************************************************************************/6315 6316 DWORD HMDeviceConsoleBufferClass::GetConsoleScreenBufferInfo(PHMHANDLEDATA pHMHandleData,6317 PCONSOLE_SCREEN_BUFFER_INFO pCSBI)6318 {6319 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6320 6321 #ifdef DEBUG_LOCAL26322 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleScreenBufferInfo(%08x,%08x).\n",6323 pHMHandleData,6324 pCSBI);6325 #endif6326 6327 pCSBI->dwSize = pConsoleBuffer->coordBufferSize;6328 pCSBI->dwCursorPosition = pConsoleBuffer->coordCursorPosition;6329 pCSBI->wAttributes = (USHORT)pConsoleBuffer->ucDefaultAttribute;6330 6331 /* @@@PH unsure, but should be OK */6332 pCSBI->srWindow.Left = pConsoleBuffer->coordWindowPosition.X;6333 pCSBI->srWindow.Top = pConsoleBuffer->coordWindowPosition.Y;6334 pCSBI->srWindow.Right = pConsoleBuffer->coordWindowPosition.X +6335 pConsoleBuffer->coordWindowSize.X - 1;6336 pCSBI->srWindow.Bottom = pConsoleBuffer->coordWindowPosition.Y +6337 pConsoleBuffer->coordWindowSize.Y - 1;6338 6339 pCSBI->dwMaximumWindowSize = pConsoleBuffer->coordBufferSize;6340 6341 return (TRUE);6342 }6343 6344 6345 /*****************************************************************************6346 * Name : DWORD HMDeviceConsoleBufferClass::GetLargestConsoleWindowSize6347 * Purpose : Determine maximum AVIO size6348 * Parameters:6349 * Variables :6350 * Result :6351 * Remark :6352 * Status :6353 *6354 * Author : Patrick Haller [Tue, 1998/02/10 01:55]6355 *****************************************************************************/6356 6357 DWORD HMDeviceConsoleBufferClass::GetLargestConsoleWindowSize(PHMHANDLEDATA pHMHandleData)6358 {6359 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6360 COORD coordSize; /* maximum avio size */6361 LONG lScreenCX; /* width and height of display */6362 LONG lScreenCY;6363 APIRET rc; /* API returncode */6364 6365 6366 #ifdef DEBUG_LOCAL6367 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetLargestConsoleWindowSize(%08x).\n",6368 pHMHandleData);6369 #endif6370 6371 /* @@@PH determine maximum console window size in characters6372 based on display size and current avio font */6373 6374 lScreenCX = WinQuerySysValue(HWND_DESKTOP, /* query PM for that */6375 SV_CXSCREEN);6376 6377 lScreenCY = WinQuerySysValue(HWND_DESKTOP, /* query PM for that */6378 SV_CYFULLSCREEN);6379 6380 if (rc != NO_ERROR)6381 {6382 WriteLog("KERNEL32/CONSOLE: VioGetDeviceCellSize failed with #%u.\n",6383 rc);6384 6385 return (FALSE); /* say API failed */6386 }6387 6388 if ( (ConsoleGlobals.sCellCX == 0) || /* prevent division by zero */6389 (ConsoleGlobals.sCellCY == 0) )6390 {6391 WriteLog("KERNEL32/CONSOLE: VioGetDeviceCellSize returned 0 value.\n");6392 6393 return (FALSE); /* say API failed */6394 }6395 6396 coordSize.X = lScreenCX / ConsoleGlobals.sCellCX; /* calculate */6397 coordSize.Y = lScreenCY / ConsoleGlobals.sCellCY;6398 6399 /* these limitations are due to OS/2's current VIO subsystem */6400 coordSize.X = min(coordSize.X, MAX_OS2_COLUMNS);6401 coordSize.Y = min(coordSize.Y, MAX_OS2_ROWS);6402 6403 return (COORD2ULONG(coordSize)); /* return value */6404 }6405 6406 6407 /*****************************************************************************6408 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputA6409 * Purpose : reads character and color attribute data from screen rectangle6410 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6411 * PCHAR_INFO pchiDestBuffer6412 * COORD coordDestBufferSize6413 * COORD coordDestBufferCoord6414 * PSMALL_RECT psrctSourceRect6415 * Variables :6416 * Result :6417 * Remark :6418 * Status : UNTESTED6419 *6420 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6421 *****************************************************************************/6422 6423 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputA(PHMHANDLEDATA pHMHandleData,6424 PCHAR_INFO pchiDestBuffer,6425 COORD coordDestBufferSize,6426 COORD coordDestBufferCoord,6427 PSMALL_RECT psrctSourceRect)6428 {6429 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6430 ULONG ulX, ulY; /* current coordinate to be read */6431 ULONG ulCX, ulCY; /* width and height of target area */6432 ULONG ulReadX, ulReadY; /* position data is read from */6433 WORD wCell; /* currently read data */6434 6435 PCHAR_INFO pchi;6436 6437 #ifdef DEBUG_LOCAL26438 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",6439 pHMHandleData,6440 pchiDestBuffer,6441 coordDestBufferSize.X,6442 coordDestBufferSize.Y,6443 coordDestBufferCoord.X,6444 coordDestBufferCoord.Y,6445 psrctSourceRect);6446 #endif6447 6448 6449 /* verify psrctSourceRect first */6450 psrctSourceRect->Left = max(psrctSourceRect->Left, 0);6451 psrctSourceRect->Top = max(psrctSourceRect->Top, 0);6452 psrctSourceRect->Right = min(psrctSourceRect->Right, pConsoleBuffer->coordBufferSize.X - 1);6453 psrctSourceRect->Bottom= min(psrctSourceRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);6454 6455 /* verify target buffer */6456 if ( (coordDestBufferSize.X < coordDestBufferCoord.X) ||6457 (coordDestBufferSize.Y < coordDestBufferCoord.Y) )6458 {6459 SetLastError(ERROR_INVALID_PARAMETER); /* set detailed error info */6460 return (FALSE); /* API failed */6461 }6462 6463 ulCX = coordDestBufferSize.X - coordDestBufferCoord.X;6464 ulCY = coordDestBufferSize.Y - coordDestBufferCoord.Y;6465 6466 ulCX = min(ulCX, (psrctSourceRect->Right - psrctSourceRect->Left));6467 ulCY = min(ulCY, (psrctSourceRect->Bottom - psrctSourceRect->Top));6468 6469 /* final calculation of the copy rectangle */6470 psrctSourceRect->Right = psrctSourceRect->Left + ulCX;6471 psrctSourceRect->Bottom = psrctSourceRect->Top + ulCY;6472 6473 6474 for (ulY = 0,6475 ulReadY = psrctSourceRect->Top;6476 6477 ulY <= ulCY;6478 6479 ulY++,6480 ulReadY++)6481 {6482 pchi = pchiDestBuffer + sizeof(CHAR_INFO) * coordDestBufferCoord.X6483 + sizeof(CHAR_INFO) * (coordDestBufferCoord.Y + ulY)6484 * coordDestBufferSize.X;6485 for (ulX = 0,6486 ulReadX = psrctSourceRect->Left;6487 6488 ulX <= ulCX;6489 6490 ulX++,6491 ulReadX++,6492 pchi++)6493 {6494 /* read character */6495 wCell = *(pConsoleBuffer->ppszLine[ulReadY] + ulReadX * 2);6496 6497 pchi->Char.AsciiChar = (UCHAR)(wCell & 0x00FF);6498 pchi->Attributes = wCell >> 8;6499 }6500 }6501 6502 return (TRUE); /* OK, that's it */6503 }6504 6505 6506 /*****************************************************************************6507 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputW6508 * Purpose : reads character and color attribute data from screen rectangle6509 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6510 * PCHAR_INFO pchiDestBuffer6511 * COORD coordDestBufferSize6512 * COORD coordDestBufferCoord6513 * PSMALL_RECT psrctSourceRect6514 * Variables :6515 * Result :6516 * Remark :6517 * Status : UNTESTED6518 *6519 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6520 *****************************************************************************/6521 6522 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputW(PHMHANDLEDATA pHMHandleData,6523 PCHAR_INFO pchiDestBuffer,6524 COORD coordDestBufferSize,6525 COORD coordDestBufferCoord,6526 PSMALL_RECT psrctSourceRect)6527 {6528 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6529 ULONG ulX, ulY; /* current coordinate to be read */6530 ULONG ulCX, ulCY; /* width and height of target area */6531 ULONG ulReadX, ulReadY; /* position data is read from */6532 WORD wCell; /* currently read data */6533 6534 PCHAR_INFO pchi;6535 6536 #ifdef DEBUG_LOCAL26537 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",6538 pHMHandleData,6539 pchiDestBuffer,6540 coordDestBufferSize.X,6541 coordDestBufferSize.Y,6542 coordDestBufferCoord.X,6543 coordDestBufferCoord.Y,6544 psrctSourceRect);6545 #endif6546 6547 6548 /* verify psrctSourceRect first */6549 psrctSourceRect->Left = max(psrctSourceRect->Left, 0);6550 psrctSourceRect->Top = max(psrctSourceRect->Top, 0);6551 psrctSourceRect->Right = min(psrctSourceRect->Right, pConsoleBuffer->coordBufferSize.X - 1);6552 psrctSourceRect->Bottom= min(psrctSourceRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);6553 6554 /* verify target buffer */6555 if ( (coordDestBufferSize.X < coordDestBufferCoord.X) ||6556 (coordDestBufferSize.Y < coordDestBufferCoord.Y) )6557 {6558 SetLastError(ERROR_INVALID_PARAMETER); /* set detailed error info */6559 return (FALSE); /* API failed */6560 }6561 6562 ulCX = coordDestBufferSize.X - coordDestBufferCoord.X;6563 ulCY = coordDestBufferSize.Y - coordDestBufferCoord.Y;6564 6565 ulCX = min(ulCX, (psrctSourceRect->Right - psrctSourceRect->Left));6566 ulCY = min(ulCY, (psrctSourceRect->Bottom - psrctSourceRect->Top));6567 6568 /* final calculation of the copy rectangle */6569 psrctSourceRect->Right = psrctSourceRect->Left + ulCX;6570 psrctSourceRect->Bottom = psrctSourceRect->Top + ulCY;6571 6572 6573 for (ulY = 0,6574 ulReadY = psrctSourceRect->Top;6575 6576 ulY <= ulCY;6577 6578 ulY++,6579 ulReadY++)6580 {6581 pchi = pchiDestBuffer + sizeof(CHAR_INFO) * coordDestBufferCoord.X6582 + sizeof(CHAR_INFO) * (coordDestBufferCoord.Y + ulY)6583 * coordDestBufferSize.X;6584 for (ulX = 0,6585 ulReadX = psrctSourceRect->Left;6586 6587 ulX <= ulCX;6588 6589 ulX++,6590 ulReadX++,6591 pchi++)6592 {6593 /* read character */6594 wCell = *(pConsoleBuffer->ppszLine[ulReadY] + ulReadX * 2);6595 6596 /* @@@PH Ascii->Unicode */6597 pchi->Char.UnicodeChar = (UCHAR)(wCell & 0x00FF);6598 pchi->Attributes = wCell >> 8;6599 }6600 }6601 6602 return (TRUE); /* OK, that's it */6603 }6604 6605 6606 /*****************************************************************************6607 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputAttribute6608 * Purpose : read an array with specified attributes from the console6609 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6610 * LPWORD lpwAttribute6611 * DWORD cReadCells6612 * COORD dwReadCoord6613 * LPDWORD lpcNumberRead6614 * Variables :6615 * Result :6616 * Remark :6617 * Status : UNTESTED6618 *6619 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6620 *****************************************************************************/6621 6622 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,6623 LPWORD lpwAttribute,6624 DWORD cReadCells,6625 COORD dwReadCoord,6626 LPDWORD lpcNumberRead)6627 {6628 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6629 ULONG ulCounter; /* current character counter */6630 6631 #ifdef DEBUG_LOCAL26632 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",6633 pHMHandleData,6634 lpwAttribute,6635 cReadCells,6636 dwReadCoord.X,6637 dwReadCoord.Y,6638 lpcNumberRead);6639 #endif6640 6641 if ( (dwReadCoord.X < 0) ||6642 (dwReadCoord.Y < 0) )6643 {6644 if (lpcNumberRead != NULL) /* ensure pointer is valid */6645 *lpcNumberRead = 0; /* complete error handling */6646 6647 SetLastError(ERROR_INVALID_PARAMETER);6648 return (FALSE);6649 }6650 6651 /* check if dwReadCoord is within specs */6652 if ( (dwReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||6653 (dwReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )6654 {6655 if (lpcNumberRead != NULL) /* ensure pointer is valid */6656 *lpcNumberRead = 0; /* complete error handling */6657 6658 SetLastError(ERROR_INVALID_PARAMETER);6659 return (FALSE);6660 }6661 6662 6663 /* OK, now write the attribute lines */6664 for (ulCounter = 0;6665 ulCounter < cReadCells;6666 ulCounter++,6667 lpwAttribute++)6668 {6669 /* write attribute into cell */6670 *lpwAttribute = (UCHAR)6671 *(pConsoleBuffer->ppszLine[dwReadCoord.Y] +6672 (dwReadCoord.X * 2 + 1));6673 6674 dwReadCoord.X++; /* move write position */6675 if (dwReadCoord.X >= pConsoleBuffer->coordBufferSize.X)6676 {6677 dwReadCoord.X = 0; /* skip to next line */6678 dwReadCoord.Y++;6679 6680 /* oops, we're at the end of the buffer. Abort now. */6681 if (dwReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)6682 {6683 if (lpcNumberRead != NULL) /* ensure pointer is valid */6684 *lpcNumberRead = ulCounter;6685 6686 return (TRUE);6687 }6688 }6689 }6690 6691 if (lpcNumberRead != NULL) /* ensure pointer is valid */6692 *lpcNumberRead = cReadCells;6693 6694 return (TRUE);6695 }6696 6697 6698 /*****************************************************************************6699 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterA6700 * Purpose : read an array with specified characters from the console6701 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6702 * LPWORD lpReadBuffer6703 * DWORD cRead6704 * COORD coordReadCoord6705 * LPDWORD lpcNumberRead6706 * Variables :6707 * Result :6708 * Remark :6709 * Status : UNTESTED6710 *6711 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6712 *****************************************************************************/6713 6714 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,6715 LPTSTR lpwReadBuffer,6716 DWORD cchRead,6717 COORD coordReadCoord,6718 LPDWORD lpcNumberRead)6719 {6720 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6721 ULONG ulCounter; /* current character counter */6722 6723 #ifdef DEBUG_LOCAL26724 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputCharacterA(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",6725 pHMHandleData,6726 lpwReadBuffer,6727 cchRead,6728 coordReadCoord.X,6729 coordReadCoord.Y,6730 lpcNumberRead);6731 #endif6732 6733 if ( (coordReadCoord.X < 0) ||6734 (coordReadCoord.Y < 0) )6735 {6736 if (lpcNumberRead != NULL) /* ensure pointer is valid */6737 *lpcNumberRead = 0; /* complete error handling */6738 6739 SetLastError(ERROR_INVALID_PARAMETER);6740 return (FALSE);6741 }6742 6743 /* check if coordReadCoord is within specs */6744 if ( (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||6745 (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )6746 {6747 if (lpcNumberRead != NULL) /* ensure pointer is valid */6748 *lpcNumberRead = 0; /* complete error handling */6749 6750 SetLastError(ERROR_INVALID_PARAMETER);6751 return (FALSE);6752 }6753 6754 6755 /* OK, now write the attribute lines */6756 for (ulCounter = 0;6757 ulCounter < cchRead;6758 ulCounter++,6759 lpwReadBuffer++)6760 {6761 /* write character into cell */6762 *lpwReadBuffer =6763 *(pConsoleBuffer->ppszLine[coordReadCoord.Y] +6764 (coordReadCoord.X * 2));6765 6766 coordReadCoord.X++; /* move write position */6767 if (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X)6768 {6769 coordReadCoord.X = 0; /* skip to next line */6770 coordReadCoord.Y++;6771 6772 /* oops, we're at the end of the buffer. Abort now. */6773 if (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)6774 {6775 if (lpcNumberRead != NULL) /* ensure pointer is valid */6776 *lpcNumberRead = ulCounter;6777 6778 return (TRUE);6779 }6780 }6781 }6782 6783 if (lpcNumberRead != NULL) /* ensure pointer is valid */6784 *lpcNumberRead = cchRead;6785 6786 return (TRUE);6787 }6788 6789 6790 /*****************************************************************************6791 * Name : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterW6792 * Purpose : read an array with specified characters from the console6793 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6794 * LPWORD lpReadBuffer6795 * DWORD cRead6796 * COORD coordReadCoord6797 * LPDWORD lpcNumberRead6798 * Variables :6799 * Result :6800 * Remark :6801 * Status : UNTESTED6802 *6803 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6804 *****************************************************************************/6805 6806 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,6807 LPWSTR lpwReadBuffer,6808 DWORD cchRead,6809 COORD coordReadCoord,6810 LPDWORD lpcNumberRead)6811 {6812 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6813 ULONG ulCounter; /* current character counter */6814 6815 #ifdef DEBUG_LOCAL26816 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputCharacterW(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",6817 pHMHandleData,6818 lpwReadBuffer,6819 cchRead,6820 coordReadCoord.X,6821 coordReadCoord.Y,6822 lpcNumberRead);6823 #endif6824 6825 if ( (coordReadCoord.X < 0) ||6826 (coordReadCoord.Y < 0) )6827 {6828 if (lpcNumberRead != NULL) /* ensure pointer is valid */6829 *lpcNumberRead = 0; /* complete error handling */6830 6831 SetLastError(ERROR_INVALID_PARAMETER);6832 return (FALSE);6833 }6834 6835 /* check if coordReadCoord is within specs */6836 if ( (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||6837 (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )6838 {6839 if (lpcNumberRead != NULL) /* ensure pointer is valid */6840 *lpcNumberRead = 0; /* complete error handling */6841 6842 SetLastError(ERROR_INVALID_PARAMETER);6843 return (FALSE);6844 }6845 6846 6847 /* OK, now write the attribute lines */6848 for (ulCounter = 0;6849 ulCounter < cchRead;6850 ulCounter++,6851 lpwReadBuffer++)6852 {6853 /* @@@PH Ascii -> Unicode translation */6854 /* write character into cell */6855 *lpwReadBuffer =6856 *(pConsoleBuffer->ppszLine[coordReadCoord.Y] +6857 (coordReadCoord.X * 2));6858 6859 coordReadCoord.X++; /* move write position */6860 if (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X)6861 {6862 coordReadCoord.X = 0; /* skip to next line */6863 coordReadCoord.Y++;6864 6865 /* oops, we're at the end of the buffer. Abort now. */6866 if (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)6867 {6868 if (lpcNumberRead != NULL) /* ensure pointer is valid */6869 *lpcNumberRead = ulCounter;6870 6871 return (TRUE);6872 }6873 }6874 }6875 6876 if (lpcNumberRead != NULL) /* ensure pointer is valid */6877 *lpcNumberRead = cchRead;6878 6879 return (TRUE);6880 }6881 6882 6883 /*****************************************************************************6884 * Name : DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferA6885 * Purpose : move a block of data within the screen buffer6886 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data6887 * PSMALL_RECT psrctSourceRect - source rectangle6888 * PSMALL_RECT psrctClipRect - clipping rectangle6889 * COORD coordDestOrigin - destination coordinate6890 * PCHAR_INFO pchiFill - fill character6891 * Variables :6892 * Result :6893 * Remark : Routine is subject to optimizations.6894 * @@@PH rewrite -> faster, better handling of overlapped buffers6895 * copy srctSource to buffer, fill it with fill character6896 * copy buffer to srctDest ?6897 * Status : UNTESTED6898 *6899 * Author : Patrick Haller [Wed, 1998/02/16 11:46]6900 *****************************************************************************/6901 6902 DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferA(PHMHANDLEDATA pHMHandleData,6903 PSMALL_RECT psrctSourceRect,6904 PSMALL_RECT psrctClipRect,6905 COORD coordDestOrigin,6906 PCHAR_INFO pchiFill)6907 {6908 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;6909 SMALL_RECT srctView; /* the actual rectangle of "happening" */6910 SMALL_RECT srctSource; /* the clipped source and dest rectangles */6911 SMALL_RECT srctDest;6912 int iX, iY; /* scan loop counters */6913 PUSHORT pusTarget, pusSource; /* pointer to source, dest cells */6914 WORD wAttr; /* fill character and attribute */6915 int iBlitDirection; /* to handle overlapped buffers */6916 6917 #ifdef DEBUG_LOCAL26918 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ScrollConsoleScreenBufferA(%08x,%08x,%08x,x=%u y=%u,%08x).\n",6919 pHMHandleData,6920 psrctSourceRect,6921 psrctClipRect,6922 coordDestOrigin.X,6923 coordDestOrigin.Y,6924 pchiFill);6925 #endif6926 6927 /* calculate effective clipping rectangle */6928 if (psrctClipRect != NULL) /* if clipping rectangle was specified */6929 {6930 memcpy(&srctView,6931 psrctClipRect,6932 sizeof (SMALL_RECT) );6933 6934 /* check boundary with buffer size */6935 srctView.Left = max(0, srctView.Left);6936 srctView.Top = max(0, srctView.Top );6937 srctView.Right = min(srctView.Right, pConsoleBuffer->coordBufferSize.X);6938 srctView.Bottom = min(srctView.Bottom, pConsoleBuffer->coordBufferSize.Y);6939 }6940 else6941 {6942 srctView.Left = 0; /* buffer size is the maximum clipping rectangle */6943 srctView.Top = 0;6944 srctView.Right = pConsoleBuffer->coordBufferSize.X;6945 srctView.Bottom = pConsoleBuffer->coordBufferSize.Y;6946 }6947 6948 memcpy(&srctSource, /* copy source rectangle */6949 psrctSourceRect,6950 sizeof (srctSource) );6951 /* check boundary with clipping rectangle */6952 srctSource.Left = max(srctSource.Left, srctView.Left );6953 srctSource.Top = max(srctSource.Top, srctView.Top );6954 srctSource.Right = min(srctSource.Right, srctView.Right );6955 srctSource.Bottom = min(srctSource.Bottom,srctView.Bottom);6956 6957 srctDest.Left = max(srctView.Left, coordDestOrigin.X);6958 srctDest.Top = max(srctView.Top, coordDestOrigin.Y);6959 srctDest.Right = min(srctView.Right, srctDest.Left + srctSource.Right - srctSource.Left);6960 srctDest.Bottom= min(srctView.Bottom, srctDest.Top + srctSource.Bottom - srctSource.Top);6961 6962 /****************************6963 * first copy the rectangle *6964 ****************************/6965 6966 if (srctDest.Left > srctSource.Left) iBlitDirection = 0;6967 else iBlitDirection = 1;6968 if (srctDest.Top > srctSource.Top) iBlitDirection += 2;6969 6970 /* this leaves us with three different cases: */6971 /* */6972 /* 0 - dest is to upper left of the source */6973 /* 1 - dest is to upper right of the source */6974 /* 2 - dest is to lower left of the source */6975 /* 3 - dest is to lower right of the source */6976 6977 switch (iBlitDirection)6978 {6979 /**************6980 * upper left *6981 **************/6982 case 0:6983 for (iY = 0;6984 iY <= srctDest.Bottom - srctDest.Top;6985 iY++)6986 {6987 /* calculate pointer to start of target screen line */6988 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +6989 (srctDest.Left << 1) );6990 6991 /* calculate pointer to start of source screen line */6992 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +6993 (srctSource.Left << 1) );6994 6995 for (iX = srctDest.Left;6996 iX <= srctDest.Right;6997 iX++,6998 pusTarget++,6999 pusSource++)7000 *pusTarget = *pusSource; /* copy character */7001 }7002 break;7003 7004 /***************7005 * upper right *7006 ***************/7007 case 1:7008 for (iY = 0;7009 iY <= srctDest.Bottom - srctDest.Top;7010 iY++)7011 {7012 /* calculate pointer to end of target screen line */7013 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +7014 ( srctDest.Right << 1) );7015 7016 /* calculate pointer to end of source screen line */7017 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +7018 ( srctSource.Right << 1) );7019 7020 for (iX = srctDest.Right;7021 iX >= srctDest.Left;7022 iX--,7023 pusTarget--,7024 pusSource--)7025 *pusTarget = *pusSource; /* copy character */7026 }7027 break;7028 7029 /***************7030 * lower left *7031 ***************/7032 case 2:7033 for (iY = srctDest.Bottom - srctDest.Top;7034 iY >= 0;7035 iY--)7036 {7037 /* calculate pointer to start of target screen line */7038 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +7039 (srctDest.Left << 1) );7040 7041 /* calculate pointer to start of source screen line */7042 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +7043 (srctSource.Left << 1) );7044 7045 for (iX = srctDest.Left;7046 iX <= srctDest.Right;7047 iX++,7048 pusTarget++,7049 pusSource++)7050 *pusTarget = *pusSource; /* copy character */7051 }7052 break;7053 7054 /****************7055 * lower right *7056 ****************/7057 case 3:7058 for (iY = srctDest.Bottom - srctDest.Top;7059 iY >= 0;7060 iY--)7061 {7062 /* calculate pointer to end of target screen line */7063 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +7064 ( srctDest.Right << 1) );7065 7066 /* calculate pointer to end of source screen line */7067 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +7068 (srctSource.Right << 1) );7069 7070 for (iX = srctDest.Right;7071 iX >= srctDest.Left;7072 iX--,7073 pusTarget--,7074 pusSource--)7075 *pusTarget = *pusSource; /* copy character */7076 }7077 break;7078 }7079 7080 7081 /* this is the character and attribute for the uncovered cells */7082 wAttr = (pchiFill->Char.AsciiChar) + (pchiFill->Attributes << 8);7083 7084 for (iY = srctSource.Top; /* now fill uncovered area with pchi */7085 iY < srctSource.Bottom;7086 iY++)7087 {7088 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY] + srctSource.Left);7089 7090 for (iX = srctSource.Left;7091 iX < srctSource.Right;7092 iX++,7093 pusTarget++)7094 /* check if covered by srctDest or not */7095 if ( (iY >= srctDest.Top) &&7096 (iY <= srctDest.Bottom) &&7097 (iX >= srctDest.Left) &&7098 (iX <= srctDest.Right)7099 )7100 ; /* should be faster for the optimizer */7101 else7102 *pusTarget = wAttr; /* write fill character and attribute */7103 }7104 7105 /* update screen if active console */7106 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7107 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7108 7109 return (TRUE);7110 }7111 7112 7113 /*****************************************************************************7114 * Name : DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferW7115 * Purpose : move a block of data within the screen buffer7116 7117 7118 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7119 * PSMALL_RECT psrctSourceRect - source rectangle7120 * PSMALL_RECT psrctClipRect - clipping rectangle7121 * COORD coordDestOrigin - destination coordinate7122 * PCHAR_INFO pchiFill - fill character7123 * Variables :7124 * Result :7125 * Remark : Routine is subject to optimizations.7126 * Status : UNTESTED7127 *7128 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7129 *****************************************************************************/7130 7131 DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferW(PHMHANDLEDATA pHMHandleData,7132 PSMALL_RECT psrctSourceRect,7133 PSMALL_RECT psrctClipRect,7134 COORD coordDestOrigin,7135 PCHAR_INFO pchiFill)7136 {7137 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7138 SMALL_RECT srctView; /* the actual rectangle of "happening" */7139 SMALL_RECT srctSource; /* the clipped source and dest rectangles */7140 SMALL_RECT srctDest;7141 ULONG ulX, ulY; /* scan loop counters */7142 PUSHORT pusTarget, pusSource; /* pointer to source, dest cells */7143 WORD wAttr; /* fill character and attribute */7144 7145 #ifdef DEBUG_LOCAL27146 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ScrollConsoleScreenBufferW(%08x,%08x,%08x,x=%u y=%u,%08x).\n",7147 pHMHandleData,7148 psrctSourceRect,7149 psrctClipRect,7150 coordDestOrigin.X,7151 coordDestOrigin.Y,7152 pchiFill);7153 #endif7154 7155 /* calculate effective clipping rectangle */7156 if (psrctClipRect != NULL) /* if clipping rectangle was specified */7157 {7158 memcpy(&srctView,7159 psrctClipRect,7160 sizeof (SMALL_RECT) );7161 7162 /* check boundary with buffer size */7163 srctView.Left = max(0, srctView.Left);7164 srctView.Top = max(0, srctView.Top );7165 srctView.Right = min(srctView.Right, pConsoleBuffer->coordBufferSize.X);7166 srctView.Bottom = min(srctView.Bottom, pConsoleBuffer->coordBufferSize.Y);7167 }7168 else7169 {7170 srctView.Left = 0; /* buffer size is the maximum clipping rectangle */7171 srctView.Top = 0;7172 srctView.Right = pConsoleBuffer->coordBufferSize.X;7173 srctView.Bottom = pConsoleBuffer->coordBufferSize.Y;7174 }7175 7176 memcpy(&srctSource, /* copy source rectangle */7177 psrctSourceRect,7178 sizeof (srctSource) );7179 /* check boundary with clipping rectangle */7180 srctSource.Left = max(srctSource.Left, srctView.Left );7181 srctSource.Top = max(srctSource.Top, srctView.Top );7182 srctSource.Right = min(srctSource.Right, srctView.Right );7183 srctSource.Bottom = min(srctSource.Bottom,srctView.Bottom);7184 7185 srctDest.Left = max(srctView.Left, coordDestOrigin.X);7186 srctDest.Top = max(srctView.Top, coordDestOrigin.Y);7187 srctDest.Right = min(srctView.Right, srctDest.Left + srctSource.Right - srctSource.Left);7188 srctDest.Bottom= min(srctView.Bottom, srctDest.Top + srctSource.Bottom - srctSource.Top);7189 7190 /* first copy the rectangle */7191 for (ulY = 0;7192 ulY < srctDest.Bottom - srctDest.Top;7193 ulY++)7194 {7195 /* calculate pointer to start of target screen line */7196 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[ulY + srctDest.Top] +7197 srctDest.Left);7198 7199 /* calculate pointer to start of source screen line */7200 pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[ulY + srctSource.Top] +7201 srctSource.Left);7202 7203 for (ulX = srctDest.Left;7204 ulX < srctDest.Right;7205 ulX++,7206 pusTarget++,7207 pusSource++)7208 *pusTarget = *pusSource; /* copy character */7209 }7210 7211 7212 /* this is the character and attribute for the uncovered cells */7213 /* @@@PH Unicode->Ascii translation */7214 wAttr = (pchiFill->Char.UnicodeChar) + (pchiFill->Attributes << 8);7215 7216 for (ulY = srctSource.Top; /* now fill uncovered area with pchi */7217 ulY < srctSource.Bottom;7218 ulY++)7219 {7220 pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[ulY] + srctSource.Left);7221 7222 for (ulX = srctSource.Left;7223 ulX < srctSource.Right;7224 ulX++,7225 pusTarget++)7226 *pusTarget = wAttr; /* write fill character and attribute */7227 }7228 7229 /* update screen if active console */7230 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7231 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7232 7233 return (TRUE);7234 }7235 7236 7237 /*****************************************************************************7238 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleCursorInfo7239 * Purpose : sets the current console's cursor information7240 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7241 * PCONSOLE_CURSOR_INFO pCCI7242 * Variables :7243 * Result :7244 * Remark :7245 * Status : UNTESTED7246 *7247 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7248 *****************************************************************************/7249 7250 DWORD HMDeviceConsoleBufferClass::SetConsoleCursorInfo(PHMHANDLEDATA pHMHandleData,7251 PCONSOLE_CURSOR_INFO pCCI)7252 {7253 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7254 7255 #ifdef DEBUG_LOCAL27256 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleCursorInfo(%08x,%08x).\n",7257 pHMHandleData,7258 pCCI);7259 #endif7260 7261 /* validate structure */7262 if ( (pCCI->dwSize < 1) ||7263 (pCCI->dwSize > 100) )7264 {7265 SetLastError(ERROR_INVALID_PARAMETER); /* set extended error info */7266 return (FALSE); /* API failed */7267 }7268 7269 /* if we're the active buffer, remove cursor from screen first */7270 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7271 ConsoleCursorShow(pConsoleBuffer,7272 CONSOLECURSOR_HIDE);7273 7274 memcpy(&pConsoleBuffer->CursorInfo, /* copy the whole information block */7275 pCCI,7276 sizeof (pConsoleBuffer->CursorInfo) );7277 7278 return (TRUE);7279 }7280 7281 7282 /*****************************************************************************7283 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleCursorPosition7284 * Purpose : sets the current console's cursor position7285 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7286 * COORD coordCursorPosition7287 * Variables :7288 * Result :7289 * Remark :7290 * Status : UNTESTED7291 *7292 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7293 *****************************************************************************/7294 7295 DWORD HMDeviceConsoleBufferClass::SetConsoleCursorPosition(PHMHANDLEDATA pHMHandleData,7296 COORD coordCursorPosition)7297 {7298 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7299 7300 #ifdef DEBUG_LOCAL27301 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleCursorPosition(%08x,x=%u.y=%u).\n",7302 pHMHandleData,7303 coordCursorPosition.X,7304 coordCursorPosition.Y);7305 #endif7306 7307 /* @@@PH remove cursor from screen first ! */7308 pConsoleBuffer->coordCursorPosition = coordCursorPosition;7309 7310 return (TRUE);7311 }7312 7313 7314 /*****************************************************************************7315 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleMode7316 * Purpose : sets the current console mode7317 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7318 * DWORD dwMode - console mode7319 * Variables :7320 * Result :7321 * Remark :7322 * Status : UNTESTED7323 *7324 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7325 *****************************************************************************/7326 7327 DWORD HMDeviceConsoleBufferClass::SetConsoleMode(PHMHANDLEDATA pHMHandleData,7328 DWORD dwMode)7329 {7330 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7331 7332 #ifdef DEBUG_LOCAL27333 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleMode(%08x,%08x).\n",7334 pHMHandleData,7335 dwMode);7336 #endif7337 7338 pConsoleBuffer->dwConsoleMode = dwMode; /* set current console mode */7339 7340 return (TRUE);7341 }7342 7343 7344 /*****************************************************************************7345 * Name : DWORD HMDeviceConsoleBufferClass::SetConsoleScreenBufferSize7346 * Purpose : allocate or re-allocate the screenbuffer and transform the7347 * old buffer as required7348 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7349 * COORD coordSize - the new buffer size7350 * Variables :7351 * Result :7352 * Remark :7353 * Status : UNTESTED7354 *7355 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7356 *****************************************************************************/7357 7358 DWORD HMDeviceConsoleBufferClass::SetConsoleScreenBufferSize (PHMHANDLEDATA pHMHandleData,7359 COORD coordSize)7360 {7361 ULONG ulSize; /* calculated size of the new buffer */7362 PSZ *ppszNew; /* pointer to the new array */7363 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7364 ULONG ulLine; /* line index counter */7365 7366 #ifdef DEBUG_LOCAL27367 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleScreenBufferSize(%u,%u).\n",7368 coordSize.X,7369 coordSize.Y);7370 #endif7371 7372 7373 /* re-allocate the whole line-pointer array */7374 ulSize = coordSize.Y * (coordSize.X * 2 + sizeof (PSZ) );7375 if (ulSize == 0) /* set new buffer size to zero ? */7376 {7377 if (pConsoleBuffer->ppszLine != NULL) /* if old buffer is present */7378 free (pConsoleBuffer->ppszLine); /* free old buffer */7379 7380 pConsoleBuffer->ppszLine = NULL;7381 pConsoleBuffer->coordBufferSize.X = 0;7382 pConsoleBuffer->coordBufferSize.Y = 0;7383 pConsoleBuffer->coordWindowSize.X = 0;7384 pConsoleBuffer->coordWindowSize.Y = 0;7385 pConsoleBuffer->coordWindowPosition.X = 0;7386 pConsoleBuffer->coordWindowPosition.Y = 0;7387 7388 return (TRUE); /* OK */7389 }7390 7391 7392 ppszNew = (PSZ *) malloc(ulSize); /* allocate array */7393 if (ppszNew == NULL) /* check proper allocation */7394 {7395 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* set error information */7396 return (FALSE); /* raise error condition */7397 }7398 7399 7400 for (ulLine = 0; /* setup line pointer array */7401 ulLine < coordSize.Y;7402 ulLine++)7403 {7404 /* calculate line pointer */7405 ulSize = (ULONG)ppszNew + (coordSize.Y * sizeof(PSZ) )7406 + (coordSize.X * ulLine * 2);7407 ppszNew[ulLine] = (PSZ)ulSize; /* OK, write index pointer */7408 }7409 7410 ulSize = ( ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 8) +7411 ((ULONG)' ') +7412 ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 24) +7413 ((ULONG)' ' << 16) );7414 7415 /* scroll the line index */7416 for (ulLine = 0;7417 ulLine < coordSize.Y;7418 ulLine++)7419 ConsoleBufferFillLine(ulSize,7420 (PUSHORT)(ppszNew[ulLine]),7421 coordSize.X);7422 7423 7424 7425 /* copy lines as required */7426 if (pConsoleBuffer->ppszLine != NULL) /* previous buffer present ? */7427 {7428 ULONG x, y;7429 7430 /* copy old characters as required */7431 x = min(pConsoleBuffer->coordBufferSize.X, coordSize.X);7432 y = min(pConsoleBuffer->coordBufferSize.Y, coordSize.Y);7433 7434 for (ulLine = 0; /* copy line by line */7435 ulLine < y;7436 ulLine++)7437 memcpy(ppszNew[ulLine],7438 pConsoleBuffer->ppszLine[ulLine],7439 x * 2);7440 7441 free (pConsoleBuffer->ppszLine); /* free previous screen buffer array */7442 }7443 7444 7445 pConsoleBuffer->ppszLine = ppszNew; /* poke in the new values */7446 pConsoleBuffer->coordBufferSize.X = coordSize.X;7447 pConsoleBuffer->coordBufferSize.Y = coordSize.Y;7448 pConsoleBuffer->coordCursorPosition.X = 0;7449 pConsoleBuffer->coordCursorPosition.Y = 0;7450 7451 /* @@@PH to be changed ! */7452 pConsoleBuffer->coordWindowSize.X = coordSize.X; /* default */7453 pConsoleBuffer->coordWindowSize.Y = coordSize.Y;7454 pConsoleBuffer->coordWindowPosition.X = 0;7455 pConsoleBuffer->coordWindowPosition.Y = 0;7456 7457 /* update screen if active console */7458 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7459 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7460 7461 return TRUE;7462 }7463 7464 7465 /*****************************************************************************7466 * Name :7467 * Purpose :7468 * Parameters:7469 * Variables :7470 * Result :7471 * Remark :7472 * Status :7473 *7474 * Author : Patrick Haller [Tue, 1998/02/10 01:55]7475 *****************************************************************************/7476 7477 DWORD HMDeviceConsoleBufferClass::SetConsoleTextAttribute(PHMHANDLEDATA pHMHandleData,7478 WORD wAttr)7479 {7480 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7481 7482 #ifdef DEBUG_LOCAL27483 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleTextAttribute(%u).\n",7484 wAttr);7485 #endif7486 7487 pConsoleBuffer->ucDefaultAttribute = (UCHAR)wAttr;7488 return (TRUE);7489 }7490 7491 7492 /*****************************************************************************7493 * Name :7494 * Purpose :7495 * Parameters:7496 * Variables :7497 * Result :7498 * Remark :7499 * Status :7500 *7501 * Author : Patrick Haller [Tue, 1998/02/10 01:55]7502 *****************************************************************************/7503 7504 DWORD HMDeviceConsoleBufferClass::SetConsoleActiveScreenBuffer(PHMHANDLEDATA pHMHandleData)7505 {7506 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7507 7508 #ifdef DEBUG_LOCAL7509 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleActiveScreenBuffer().\n");7510 #endif7511 7512 /* set new buffer handle to the global console */7513 ConsoleGlobals.hConsoleBuffer = pHMHandleData->hHandle;7514 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7515 7516 return (TRUE);7517 }7518 7519 7520 /*****************************************************************************7521 * Name : BOOL HMDeviceConsoleBufferClass::SetConsoleWindowInfo7522 * Purpose : set a new size to the console window7523 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7524 * BOOL fAbsolute7525 * PSMALL_RECT psrctWindowRect7526 * Variables :7527 * Result :7528 * Remark :7529 * Status : UNTESTED7530 *7531 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7532 *****************************************************************************/7533 7534 BOOL HMDeviceConsoleBufferClass::SetConsoleWindowInfo(PHMHANDLEDATA pHMHandleData,7535 BOOL fAbsolute,7536 PSMALL_RECT psrctWindowRect)7537 {7538 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7539 7540 #ifdef DEBUG_LOCAL27541 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleWindowInfo(%08x,%u,%08x).\n",7542 pHMHandleData,7543 fAbsolute,7544 psrctWindowRect);7545 #endif7546 7547 if (fAbsolute == TRUE) /* absolute coordinates provided ? */7548 {7549 if ( (psrctWindowRect->Left < 0) || /* check parameters first */7550 (psrctWindowRect->Top < 0) ||7551 (psrctWindowRect->Right < 0) ||7552 (psrctWindowRect->Bottom < 0) ||7553 (psrctWindowRect->Right <= psrctWindowRect->Left) ||7554 (psrctWindowRect->Bottom <= psrctWindowRect->Top)7555 )7556 {7557 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */7558 return (FALSE); /* error */7559 }7560 7561 /* check we don't go beyond screen buffer ! */7562 if ( ((psrctWindowRect->Right - psrctWindowRect->Left) > pConsoleBuffer->coordBufferSize.X) ||7563 ((psrctWindowRect->Bottom - psrctWindowRect->Top ) > pConsoleBuffer->coordBufferSize.Y) ||7564 (psrctWindowRect->Left >= pConsoleBuffer->coordBufferSize.X) ||7565 (psrctWindowRect->Top >= pConsoleBuffer->coordBufferSize.Y)7566 )7567 {7568 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */7569 return (FALSE); /* error */7570 }7571 7572 pConsoleBuffer->coordWindowSize.X = psrctWindowRect->Right -7573 psrctWindowRect->Left;7574 pConsoleBuffer->coordWindowSize.Y = psrctWindowRect->Bottom -7575 psrctWindowRect->Top;7576 7577 pConsoleBuffer->coordWindowPosition.X = psrctWindowRect->Left;7578 pConsoleBuffer->coordWindowPosition.Y = psrctWindowRect->Top;7579 }7580 else7581 {7582 int iSizeX; /* relative coordinates */7583 int iSizeY;7584 int iPosX;7585 int iPosY;7586 7587 iSizeX = pConsoleBuffer->coordWindowSize.X + psrctWindowRect->Left + psrctWindowRect->Right;7588 iSizeY = pConsoleBuffer->coordWindowSize.Y + psrctWindowRect->Top + psrctWindowRect->Bottom;7589 iPosX = pConsoleBuffer->coordWindowPosition.X + psrctWindowRect->Left;7590 iPosY = pConsoleBuffer->coordWindowPosition.Y + psrctWindowRect->Top;7591 7592 /* check we don't go beyond screen buffer ! */7593 if ( (iSizeX > pConsoleBuffer->coordBufferSize.X) ||7594 (iSizeY > pConsoleBuffer->coordBufferSize.Y) ||7595 (iPosX >= pConsoleBuffer->coordBufferSize.X) ||7596 (iPosY >= pConsoleBuffer->coordBufferSize.Y) ||7597 (iSizeX < 0) ||7598 (iSizeY < 0) ||7599 (iPosX < 0) ||7600 (iPosY < 0)7601 )7602 {7603 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */7604 return (FALSE); /* error */7605 }7606 7607 /* Values are verified for being OK ! */7608 pConsoleBuffer->coordWindowPosition.X = iPosX;7609 pConsoleBuffer->coordWindowPosition.Y = iPosY;7610 pConsoleBuffer->coordWindowSize.X = iSizeX;7611 pConsoleBuffer->coordWindowSize.Y = iSizeY;7612 }7613 7614 /* update window */7615 /* @@@PH7616 7617 ConsoleWindowResize(COORD coordWindowSize,7618 COORD coordWindowPos,7619 7620 */7621 7622 /* update window contents (scroll) */7623 /* update screen if active console */7624 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7625 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7626 7627 return (TRUE); /* OK */7628 }7629 7630 7631 /*****************************************************************************7632 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleA7633 * Purpose : write a string to the console7634 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7635 * LPWORD lpwAttribute7636 * DWORD cWriteCells7637 * COORD dwWriteCoord7638 * LPDWORD lpcWritten7639 * Variables :7640 * Result :7641 * Remark :7642 * Status : UNTESTED7643 *7644 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7645 *****************************************************************************/7646 7647 DWORD HMDeviceConsoleBufferClass::WriteConsoleA(PHMHANDLEDATA pHMHandleData,7648 CONST VOID* lpvBuffer,7649 DWORD cchToWrite,7650 LPDWORD lpcchWritten,7651 LPVOID lpvReserved)7652 {7653 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7654 7655 #ifdef DEBUG_LOCAL27656 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleA(%08x,%08x,%u,%08x,%08x).\n",7657 pHMHandleData,7658 lpvBuffer,7659 cchToWrite,7660 lpcchWritten,7661 lpvReserved);7662 #endif7663 7664 /* simply forward the request to that routine */7665 return (HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,7666 lpvBuffer,7667 cchToWrite,7668 lpcchWritten,7669 NULL));7670 }7671 7672 7673 /*****************************************************************************7674 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleW7675 * Purpose : write a string to the console7676 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7677 * LPWORD lpwAttribute7678 * DWORD cWriteCells7679 * COORD dwWriteCoord7680 * LPDWORD lpcWritten7681 * Variables :7682 * Result :7683 * Remark :7684 * Status : UNTESTED7685 *7686 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7687 *****************************************************************************/7688 7689 DWORD HMDeviceConsoleBufferClass::WriteConsoleW(PHMHANDLEDATA pHMHandleData,7690 CONST VOID* lpvBuffer,7691 DWORD cchToWrite,7692 LPDWORD lpcchWritten,7693 LPVOID lpvReserved)7694 {7695 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7696 7697 #ifdef DEBUG_LOCAL27698 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleW(%08x,%08x,%u,%08x,%08x).\n",7699 pHMHandleData,7700 lpvBuffer,7701 cchToWrite,7702 lpcchWritten,7703 lpvReserved);7704 #endif7705 7706 /* @@@PH AScii -> unicode translation */7707 7708 /* simply forward the request to that routine */7709 return (HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,7710 lpvBuffer,7711 cchToWrite,7712 lpcchWritten,7713 NULL));7714 }7715 7716 7717 /*****************************************************************************7718 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA7719 * Purpose : write character and color attribute data to screen rectangle7720 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7721 * PCHAR_INFO pchiSrcBuffer7722 * COORD coordSrcBufferSize7723 * COORD coordSrcBufferCoord7724 * PSMALL_RECT psrctDestRect7725 * Variables :7726 * Result :7727 * Remark :7728 * Status : UNTESTED7729 *7730 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7731 *****************************************************************************/7732 7733 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA(PHMHANDLEDATA pHMHandleData,7734 PCHAR_INFO pchiSrcBuffer,7735 COORD coordSrcBufferSize,7736 COORD coordSrcBufferCoord,7737 PSMALL_RECT psrctDestRect)7738 {7739 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7740 ULONG ulX, ulY; /* current coordinate to be read */7741 ULONG ulCX, ulCY; /* width and height of target area */7742 ULONG ulWriteX, ulWriteY; /* position data is read from */7743 WORD wCell; /* currently read data */7744 7745 PCHAR_INFO pchi;7746 PSZ pszTarget;7747 7748 #ifdef DEBUG_LOCAL27749 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",7750 pHMHandleData,7751 pchiSrcBuffer,7752 coordSrcBufferSize.X,7753 coordSrcBufferSize.Y,7754 coordSrcBufferCoord.X,7755 coordSrcBufferCoord.Y,7756 psrctDestRect);7757 #endif7758 7759 7760 /* verify psrctDestRect first */7761 psrctDestRect->Left = max(psrctDestRect->Left, 0);7762 psrctDestRect->Top = max(psrctDestRect->Top, 0);7763 psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);7764 psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);7765 7766 /* verify target buffer */7767 if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||7768 (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )7769 {7770 SetLastError(ERROR_INVALID_PARAMETER); /* set detailed error info */7771 return (FALSE); /* API failed */7772 }7773 7774 ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;7775 ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;7776 7777 ulCX = min(ulCX, (psrctDestRect->Right - psrctDestRect->Left));7778 ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));7779 7780 /* final calculation of the copy rectangle */7781 psrctDestRect->Right = psrctDestRect->Left + ulCX;7782 psrctDestRect->Bottom = psrctDestRect->Top + ulCY;7783 7784 7785 for (ulY = 0,7786 ulWriteY = psrctDestRect->Top;7787 7788 ulY <= ulCY;7789 7790 ulY++,7791 ulWriteY++)7792 {7793 pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X7794 + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)7795 * coordSrcBufferSize.X;7796 7797 /* calculate pointer to start of screen line */7798 pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + psrctDestRect->Left;7799 7800 for (ulX = 0,7801 ulWriteX = psrctDestRect->Left;7802 7803 ulX <= ulCX;7804 7805 ulX++,7806 ulWriteX++,7807 pchi++)7808 {7809 /* write character and attribute */7810 *pszTarget++ = (UCHAR)pchi->Char.AsciiChar;7811 *pszTarget++ = (UCHAR)pchi->Attributes;7812 }7813 }7814 7815 /* update screen if active console */7816 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7817 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7818 7819 return (TRUE); /* OK, that's it */7820 }7821 7822 7823 /*****************************************************************************7824 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW7825 * Purpose : write character and color attribute data to screen rectangle7826 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7827 * PCHAR_INFO pchiSrcBuffer7828 * COORD coordSrcBufferSize7829 * COORD coordSrcBufferCoord7830 * PSMALL_RECT psrctDestRect7831 * Variables :7832 * Result :7833 * Remark :7834 * Status : UNTESTED7835 *7836 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7837 *****************************************************************************/7838 7839 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW(PHMHANDLEDATA pHMHandleData,7840 PCHAR_INFO pchiSrcBuffer,7841 COORD coordSrcBufferSize,7842 COORD coordSrcBufferCoord,7843 PSMALL_RECT psrctDestRect)7844 {7845 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7846 ULONG ulX, ulY; /* current coordinate to be read */7847 ULONG ulCX, ulCY; /* width and height of target area */7848 ULONG ulWriteX, ulWriteY; /* position data is read from */7849 WORD wCell; /* currently read data */7850 7851 PCHAR_INFO pchi;7852 PSZ pszTarget;7853 7854 #ifdef DEBUG_LOCAL27855 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",7856 pHMHandleData,7857 pchiSrcBuffer,7858 coordSrcBufferSize.X,7859 coordSrcBufferSize.Y,7860 coordSrcBufferCoord.X,7861 coordSrcBufferCoord.Y,7862 psrctDestRect);7863 #endif7864 7865 7866 /* verify psrctDestRect first */7867 psrctDestRect->Left = max(psrctDestRect->Left, 0);7868 psrctDestRect->Top = max(psrctDestRect->Top, 0);7869 psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);7870 psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);7871 7872 /* verify target buffer */7873 if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||7874 (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )7875 {7876 SetLastError(ERROR_INVALID_PARAMETER); /* set detailed error info */7877 return (FALSE); /* API failed */7878 }7879 7880 ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;7881 ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;7882 7883 ulCX = min(ulCX, (psrctDestRect->Right - psrctDestRect->Left));7884 ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));7885 7886 /* final calculation of the copy rectangle */7887 psrctDestRect->Right = psrctDestRect->Left + ulCX;7888 psrctDestRect->Bottom = psrctDestRect->Top + ulCY;7889 7890 7891 for (ulY = 0,7892 ulWriteY = psrctDestRect->Top;7893 7894 ulY <= ulCY;7895 7896 ulY++,7897 ulWriteY++)7898 {7899 pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X7900 + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)7901 * coordSrcBufferSize.X;7902 7903 /* calculate pointer to start of screen line */7904 pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + psrctDestRect->Left;7905 7906 for (ulX = 0,7907 ulWriteX = psrctDestRect->Left;7908 7909 ulX <= ulCX;7910 7911 ulX++,7912 ulWriteX++,7913 pchi++)7914 {7915 /* write character and attribute */7916 *pszTarget++ = (UCHAR)pchi->Char.UnicodeChar; /* @@@PH unicode->ascii */7917 *pszTarget++ = (UCHAR)pchi->Attributes;7918 }7919 }7920 7921 /* update screen if active console */7922 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)7923 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */7924 7925 return (TRUE); /* OK, that's it */7926 }7927 7928 7929 /*****************************************************************************7930 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute7931 * Purpose : write an array with specified attributes to the console7932 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data7933 * LPWORD lpwAttribute7934 * DWORD cWriteCells7935 * COORD dwWriteCoord7936 * LPDWORD lpcWritten7937 * Variables :7938 * Result :7939 * Remark :7940 * Status : UNTESTED7941 *7942 * Author : Patrick Haller [Wed, 1998/02/16 11:46]7943 *****************************************************************************/7944 7945 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,7946 LPWORD lpwAttribute,7947 DWORD cWriteCells,7948 COORD dwWriteCoord,7949 LPDWORD lpcWritten)7950 {7951 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;7952 ULONG ulCounter; /* current character counter */7953 7954 #ifdef DEBUG_LOCAL27955 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",7956 pHMHandleData,7957 lpwAttribute,7958 7959 7960 cWriteCells,7961 dwWriteCoord.X,7962 dwWriteCoord.Y,7963 lpcWritten);7964 #endif7965 7966 if ( (dwWriteCoord.X < 0) ||7967 (dwWriteCoord.Y < 0) )7968 {7969 if (lpcWritten != NULL) /* ensure pointer is valid */7970 *lpcWritten = 0; /* complete error handling */7971 7972 SetLastError(ERROR_INVALID_PARAMETER);7973 return (FALSE);7974 }7975 7976 /* check if dwWriteCoord is within specs */7977 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||7978 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )7979 {7980 if (lpcWritten != NULL) /* ensure pointer is valid */7981 *lpcWritten = 0; /* complete error handling */7982 7983 SetLastError(ERROR_INVALID_PARAMETER);7984 return (FALSE);7985 }7986 7987 7988 /* OK, now write the attribute lines */7989 for (ulCounter = 0;7990 ulCounter < cWriteCells;7991 ulCounter++,7992 lpwAttribute++)7993 {7994 /* write attribute into cell */7995 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +7996 (dwWriteCoord.X * 2 + 1)7997 ) = (UCHAR)*lpwAttribute; /* write attribute and skip to next */7998 7999 dwWriteCoord.X++; /* move write position */8000 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)8001 {8002 dwWriteCoord.X = 0; /* skip to next line */8003 dwWriteCoord.Y++;8004 8005 /* oops, we're at the end of the buffer. Abort now. */8006 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)8007 {8008 if (lpcWritten != NULL) /* ensure pointer is valid */8009 *lpcWritten = ulCounter;8010 8011 /* update screen if active console */8012 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)8013 ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */8014 8015 return (TRUE);8016 }8017 }8018 }8019 8020 /* update screen if active console */8021 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)8022 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */8023 8024 if (lpcWritten != NULL) /* ensure pointer is valid */8025 *lpcWritten = cWriteCells;8026 8027 return (TRUE);8028 }8029 8030 8031 /*****************************************************************************8032 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA8033 * Purpose : fills the console buffer with a specified attribute8034 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data8035 * LPTSTR lpWriteBuffer8036 * DWORD cchWrite8037 * COORD dwWriteCoord8038 * LPDWORD lpcWritten8039 * Variables :8040 * Result :8041 * Remark :8042 * Status : UNTESTED8043 *8044 * Author : Patrick Haller [Wed, 1998/02/16 11:46]8045 *****************************************************************************/8046 8047 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,8048 LPTSTR lpWriteBuffer,8049 DWORD cchWrite,8050 COORD dwWriteCoord,8051 LPDWORD lpcWritten)8052 {8053 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;8054 ULONG ulCounter; /* current character counter */8055 8056 #ifdef DEBUG_LOCAL28057 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterA(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",8058 pHMHandleData,8059 lpWriteBuffer,8060 cchWrite,8061 dwWriteCoord.X,8062 dwWriteCoord.Y,8063 lpcWritten);8064 #endif8065 8066 if ( (dwWriteCoord.X < 0) ||8067 (dwWriteCoord.Y < 0) )8068 {8069 if (lpcWritten != NULL) /* ensure pointer is valid */8070 *lpcWritten = 0; /* complete error handling */8071 8072 SetLastError(ERROR_INVALID_PARAMETER);8073 return (FALSE);8074 }8075 8076 /* check if dwWriteCoord is within specs */8077 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||8078 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )8079 {8080 if (lpcWritten != NULL) /* ensure pointer is valid */8081 *lpcWritten = 0; /* complete error handling */8082 8083 SetLastError(ERROR_INVALID_PARAMETER);8084 return (FALSE);8085 }8086 8087 8088 /* OK, now write the character lines */8089 for (ulCounter = 0;8090 ulCounter < cchWrite;8091 ulCounter++,8092 lpWriteBuffer++)8093 {8094 /* write character into cell */8095 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +8096 (dwWriteCoord.X * 2)8097 ) = (UCHAR)*lpWriteBuffer; /* write character and skip to next */8098 8099 dwWriteCoord.X++; /* move write position */8100 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)8101 {8102 dwWriteCoord.X = 0; /* skip to next line */8103 dwWriteCoord.Y++;8104 8105 /* oops, we're at the end of the buffer. Abort now. */8106 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)8107 {8108 if (lpcWritten != NULL) /* ensure pointer is valid */8109 *lpcWritten = ulCounter;8110 8111 /* update screen if active console */8112 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)8113 ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */8114 8115 return (TRUE);8116 }8117 }8118 }8119 8120 /* update screen if active console */8121 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)8122 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */8123 8124 if (lpcWritten != NULL) /* ensure pointer is valid */8125 *lpcWritten = cchWrite;8126 8127 return (TRUE);8128 }8129 8130 8131 /*****************************************************************************8132 * Name : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW8133 * Purpose : fills the console buffer with a specified attribute8134 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data8135 * LPWSTR lpWriteBuffer8136 * DWORD cchWrite8137 * COORD dwWriteCoord8138 * LPDWORD lpcWritten8139 * Variables :8140 * Result :8141 * Remark :8142 * Status : UNTESTED8143 *8144 * Author : Patrick Haller [Wed, 1998/02/16 11:46]8145 *****************************************************************************/8146 8147 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,8148 LPWSTR lpWriteBuffer,8149 DWORD cchWrite,8150 COORD dwWriteCoord,8151 LPDWORD lpcWritten)8152 {8153 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;8154 ULONG ulCounter; /* current character counter */8155 8156 #ifdef DEBUG_LOCAL28157 WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterW(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",8158 pHMHandleData,8159 lpWriteBuffer,8160 cchWrite,8161 dwWriteCoord.X,8162 dwWriteCoord.Y,8163 lpcWritten);8164 #endif8165 8166 if ( (dwWriteCoord.X < 0) ||8167 (dwWriteCoord.Y < 0) )8168 {8169 if (lpcWritten != NULL) /* ensure pointer is valid */8170 *lpcWritten = 0; /* complete error handling */8171 8172 SetLastError(ERROR_INVALID_PARAMETER);8173 return (FALSE);8174 }8175 8176 /* check if dwWriteCoord is within specs */8177 if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||8178 (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )8179 {8180 if (lpcWritten != NULL) /* ensure pointer is valid */8181 *lpcWritten = 0; /* complete error handling */8182 8183 SetLastError(ERROR_INVALID_PARAMETER);8184 return (FALSE);8185 }8186 8187 8188 /* OK, now write the character lines */8189 for (ulCounter = 0;8190 ulCounter < cchWrite;8191 ulCounter++,8192 lpWriteBuffer++)8193 {8194 /* write character into cell */8195 *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +8196 (dwWriteCoord.X * 2)8197 ) = (UCHAR)*lpWriteBuffer; /* write character and skip to next */8198 /* @@@PH unicode to ascii translation */8199 8200 dwWriteCoord.X++; /* move write position */8201 if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)8202 {8203 dwWriteCoord.X = 0; /* skip to next line */8204 dwWriteCoord.Y++;8205 8206 /* oops, we're at the end of the buffer. Abort now. */8207 if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)8208 {8209 if (lpcWritten != NULL) /* ensure pointer is valid */8210 *lpcWritten = ulCounter;8211 8212 /* update screen if active console */8213 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)8214 ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */8215 8216 return (TRUE);8217 }8218 }8219 }8220 8221 /* update screen if active console */8222 if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)8223 ConsoleGlobals.fUpdateRequired = TRUE; /* update with next WM_TIMER */8224 8225 if (lpcWritten != NULL) /* ensure pointer is valid */8226 *lpcWritten = cchWrite;8227 8228 return (TRUE);8229 }8230
Note:
See TracChangeset
for help on using the changeset viewer.