/* $Id: conout.cpp,v 1.16 2003-08-06 10:02:19 sandervl Exp $ */ /* * Win32 Console API Translation for OS/2 * 1998/02/10 Patrick Haller (haller@zebra.fh-weingarten.de) * Project Odin Software License can be found in LICENSE.TXT */ #ifdef DEBUG #define DEBUG_LOCAL #define DEBUG_LOCAL2 #endif //#undef DEBUG_LOCAL //#undef DEBUG_LOCAL2 /***************************************************************************** * Remark * ***************************************************************************** - DWORD HandlerRoutine (DWORD dwCtrlType) basically an exception handler routine. handles a few signals / excpts. should be somewhere near the exception handling code ... :) Hmm, however as PM applications don't really get a ctrl-c signal, I'll have to do this on my own ... - supply unicode<->ascii conversions for all the _A and _W function pairs. - problem: we can't prevent thread1 from blocking the message queue ? what will happen if a WinTerminate() is issued there ? will the message queue be closed and provide smooth tasking ? how will open32 react on this ? - ECHO_LINE_INPUT / ReadFile blocks till CR - scrollbars * do some flowchart to exactly determine WHEN to use WHICH setting and perform WHAT action - clipboard support */ /***************************************************************************** * Includes * *****************************************************************************/ #define INCL_WIN #define INCL_DOSMEMMGR #define INCL_DOSSEMAPHORES #define INCL_DOSERRORS #define INCL_DOSPROCESS #define INCL_DOSMODULEMGR #define INCL_VIO #define INCL_AVIO #include //Odin32 OS/2 api wrappers #include #include #include #include #include #include "conwin.h" // Windows Header for console only #include "HandleManager.h" #include "HMDevice.h" #include "ConOut.H" #include "console2.h" #include "conprop.h" #include "unicode.h" #define DBG_LOCALLOG DBG_conout #include "dbglocal.h" /***************************************************************************** * Name : DWORD HMDeviceConsoleOutClass::CreateFile * Purpose : this is called from the handle manager if a CreateFile() is * performed on a handle * Parameters: LPCSTR lpFileName name of the file / device * PHMHANDLEDATA pHMHandleData data of the NEW handle * PVOID lpSecurityAttributes ignored * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle * Variables : * Result : * Remark : * Status : NO_ERROR - API succeeded * other - what is to be set in SetLastError * * Author : Patrick Haller [Wed, 1998/02/11 20:44] *****************************************************************************/ DWORD HMDeviceConsoleOutClass::CreateFile (LPCSTR lpFileName, PHMHANDLEDATA pHMHandleData, PVOID lpSecurityAttributes, PHMHANDLEDATA pHMHandleDataTemplate) { BOOL fResult; HANDLE hConsole; dprintf(("KERNEL32/CONSOLE:HMDeviceConsoleOutClass %s(%s,%08x,%08x,%08x)\n", lpHMDeviceName, lpFileName, pHMHandleData->hHMHandle, lpSecurityAttributes, pHMHandleDataTemplate)); /* if no default buffer is available, then do default setup */ if (pConsoleGlobals->hConsoleBuffer == INVALID_HANDLE_VALUE) { /* now we need a default screen buffer with the default size */ hConsole = CreateConsoleScreenBuffer(0, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); if (hConsole == INVALID_HANDLE_VALUE) { dprintf(("KERNEL32/CONSOLE:OS2CreateConsoleScreenBuffer = %u.\n", GetLastError())); return INVALID_HANDLE_VALUE; /* abort further processing immediately */ } fResult = SetConsoleTextAttribute(hConsole, pConsoleGlobals->Options.ucDefaultAttribute); #ifdef DEBUG_LOCAL if (fResult == FALSE) /* check errors */ WriteLog("KERNEL32/CONSOLE:OS2SetConsoleTextAttribute=%u.\n", GetLastError()); #endif fResult = SetConsoleScreenBufferSize(hConsole, pConsoleGlobals->coordWindowSize); if (fResult == FALSE) { dprintf(("KERNEL32/CONSOLE:OS2SetConsoleScreenBufferSize=%u.\n", GetLastError())); HMCloseHandle(hConsole); /* free handle again */ return (INVALID_HANDLE_VALUE); /* abort further processing */ } fResult = SetConsoleActiveScreenBuffer(hConsole); if (fResult == FALSE) { dprintf(("KERNEL32/CONSOLE:OS2SetConsoleActiveScreenBuffer=%u.\n", GetLastError())); HMCloseHandle(hConsole); /* free handle again */ return (INVALID_HANDLE_VALUE); /* abort further processing */ } else { pConsoleGlobals->hConsoleBufferDefault = hConsole; /* save handle */ pConsoleGlobals->hConsoleBuffer = hConsole; } } return(NO_ERROR); } /***************************************************************************** * Name : DWORD HMDeviceConsoleOutClass::GetFileType * Purpose : determine the handle type * Parameters: PHMHANDLEDATA pHMHandleData * Variables : * Result : API returncode * Remark : * Status : * * Author : Patrick Haller [Wed, 1998/02/11 20:44] *****************************************************************************/ DWORD HMDeviceConsoleOutClass::GetFileType(PHMHANDLEDATA pHMHandleData) { dprintf(("KERNEL32: HMDeviceConsoleOutClass::GetFileType %s(%08x)\n", lpHMDeviceName, pHMHandleData)); return FILE_TYPE_CHAR; } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : * * Author : Patrick Haller [Wed, 1998/02/11 20:44] *****************************************************************************/ BOOL HMDeviceConsoleOutClass::ReadFile(PHMHANDLEDATA pHMHandleData, LPCVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { #ifdef DEBUG_LOCAL WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n", lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); #endif SetLastError(ERROR_ACCESS_DENIED_W); return FALSE; } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : * * Author : Patrick Haller [Wed, 1998/02/11 20:44] *****************************************************************************/ BOOL HMDeviceConsoleOutClass::WriteFile(PHMHANDLEDATA pHMHandleData, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { BOOL dwResult; /* result from subsequent WriteFile */ #ifdef DEBUG_LOCAL2 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass:WriteFile %s(%08x,%s,%08x,%08x,%08x)\n", lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); #endif if(lpCompletionRoutine) { dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO")); } /* just prevent an endless loop, although this condition might never */ /* be true ! */ if (pHMHandleData->hHMHandle != pConsoleGlobals->hConsoleBuffer) { dwResult = HMWriteFile(pConsoleGlobals->hConsoleBuffer, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine); return (dwResult); /* return result code */ } else { return (FALSE); /* raise error condition */ } } /***************************************************************************** * Name : DWORD HMDeviceConsoleOutClass::_DeviceRequest * Purpose : we just forward those device requests to the console buffer * currently associated with the console itself. * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED * * Author : Patrick Haller [Wed, 1998/03/35 20:44] *****************************************************************************/ DWORD HMDeviceConsoleOutClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData, ULONG ulRequestCode, ULONG arg1, ULONG arg2, ULONG arg3, ULONG arg4) { #ifdef DEBUG_LOCAL2 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x)\n", lpHMDeviceName, pHMHandleData->hHMHandle, ulRequestCode, arg1, arg2, arg3, arg4); #endif /* just prevent an endless loop, although this condition might never */ /* be true ! */ if (pHMHandleData->hHMHandle != pConsoleGlobals->hConsoleBuffer) return (HMDeviceRequest(pConsoleGlobals->hConsoleBuffer, ulRequestCode, arg1, arg2, arg3, arg4)); else return (ERROR_SYS_INTERNAL); /* raise error condition */ }