ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tncon.cpp
Go to the documentation of this file.
00001 
00002 //Telnet Win32 : an ANSI telnet client.
00003 //Copyright (C) 1998-2000 Paul Brannan
00004 //Copyright (C) 1998 I.Ioannou
00005 //Copyright (C) 1997 Brad Johnson
00006 //
00007 //This program is free software; you can redistribute it and/or
00008 //modify it under the terms of the GNU General Public License
00009 //as published by the Free Software Foundation; either version 2
00010 //of the License, or (at your option) any later version.
00011 //
00012 //This program is distributed in the hope that it will be useful,
00013 //but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //GNU General Public License for more details.
00016 //
00017 //You should have received a copy of the GNU General Public License
00018 //along with this program; if not, write to the Free Software
00019 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 //
00021 //I.Ioannou
00022 //roryt@hol.gr
00023 //
00025 
00027 //
00028 // Module:      tncon.cpp
00029 //
00030 // Contents:    telnet console processing
00031 //
00032 // Product:     telnet
00033 //
00034 // Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu>
00035 //            July 29, 1998 Paul Brannan
00036 //            June 15, 1998 Paul Brannan
00037 //            May 16, 1998 Paul Brannan
00038 //            5.April.1997 jbj@nounname.com
00039 //            9.Dec.1996 jbj@nounname.com
00040 //            Version 2.0
00041 //
00042 //            02.Apr.1995   igor.milavec@uni-lj.si
00043 //                    Original code
00044 //
00046 
00047 #include "precomp.h"
00048 
00049 #define KEYEVENT InputRecord[i].Event.KeyEvent
00050 
00051 // Paul Brannan 6/25/98
00052 // #ifdef __MINGW32__
00053 // #define KEYEVENT_CHAR KEYEVENT.AsciiChar
00054 // #else
00055 #define KEYEVENT_CHAR KEYEVENT.uChar.AsciiChar
00056 // #endif
00057 
00058 #define KEYEVENT_PCHAR &KEYEVENT_CHAR
00059 
00060 // This is for local echo (Paul Brannan 5/16/98)
00061 inline void DoEcho(const char *p, int l, TConsole &Console,
00062                    TNetwork &Network, NetParams *pParams) {
00063     // Pause the console (Paul Brannan 8/24/98)
00064     if(Network.get_local_echo()) {
00065         ResetEvent(pParams->hUnPause);
00066         SetEvent(pParams->hPause);
00067         while (!*pParams->bNetPaused); // Pause
00068 
00069         Console.WriteCtrlString(p, l);
00070 
00071         SetEvent(pParams->hUnPause); // Unpause
00072     }
00073 }
00074 
00075 // This is for line mode (Paul Brannan 12/31/98)
00076 static char buffer[1024];
00077 static unsigned int bufptr = 0;
00078 
00079 // Line mode -- currently uses sga/echo to determine when to enter line mode
00080 // (as in RFC 858), but correct behaviour is as described in RFC 1184.
00081 // (Paul Brannan 12/31/98)
00082 // FIX ME!!  What to do with unflushed data when we change from line mode
00083 // to character mode?
00084 inline bool DoLineModeSpecial(char keychar, TConsole &Console, TNetwork &Network,
00085                        NetParams *pParams) {
00086     if(keychar == VK_BACK) {
00087         if(bufptr) bufptr--;
00088         DoEcho("\b \b", 3, Console, Network, pParams);
00089         return true;
00090     } else if(keychar == VK_RETURN) {
00091         Network.WriteString(buffer, bufptr);
00092         Network.WriteString("\012", 1);
00093         DoEcho("\r\n", 2, Console, Network, pParams);
00094         bufptr = 0;
00095         return true;
00096     }
00097     return false;
00098 }
00099 
00100 inline void DoLineMode(const char *p, int p_len, TConsole &Console,
00101                        TNetwork &Network) {
00102     if(Network.get_line_mode()) {
00103         if(bufptr < sizeof(buffer) + p_len - 1) {
00104             memcpy(buffer + bufptr, p, p_len);
00105             bufptr += p_len;
00106         } else {
00107             Console.Beep();
00108         }
00109     } else {
00110         Network.WriteString(p, p_len);
00111     }
00112 }
00113 
00114 // Paul Brannan 5/27/98
00115 // Fixed this code for use with appliation cursor keys
00116 // This should probably be optimized; it's pretty ugly as it is
00117 // Rewrite #1: now uses ClosestStateKey (Paul Brannan 12/9/98)
00118 const char *ClosestStateKey(WORD keyCode, DWORD keyState,
00119                             KeyTranslator &KeyTrans) {
00120     char const *p;
00121 
00122     if((p = KeyTrans.TranslateKey(keyCode, keyState))) return p;
00123 
00124     // Check numlock and scroll lock (Paul Brannan 9/23/98)
00125     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~NUMLOCK_ON))) return p;
00126     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY
00127         & ~NUMLOCK_ON))) return p;
00128     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~SCROLLLOCK_ON))) return p;
00129     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY
00130         & ~SCROLLLOCK_ON))) return p;
00131 
00132     //   John Ioannou (roryt@hol.gr)
00133     //   Athens 31/03/97 00:25am GMT+2
00134     //   fix for win95 CAPSLOCK bug
00135     //   first check if the user has keys with capslock and then we filter it
00136     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY))) return p;
00137     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~CAPSLOCK_ON))) return p;
00138     if((p = KeyTrans.TranslateKey(keyCode, keyState & ~ENHANCED_KEY
00139         & ~CAPSLOCK_ON))) return p;
00140 
00141     return 0; // we couldn't find a suitable key translation
00142 }
00143 
00144 const char *FindClosestKey(WORD keyCode, DWORD keyState,
00145                            KeyTranslator &KeyTrans) {
00146     char const *p;
00147 
00148     // Paul Brannan 7/20/98
00149     if(ini.get_alt_erase()) {
00150         if(keyCode == VK_BACK) {
00151             keyCode = VK_DELETE;
00152             keyState |= ENHANCED_KEY;
00153         } else if(keyCode == VK_DELETE && (keyState & ENHANCED_KEY)) {
00154             keyCode = VK_BACK;
00155             keyState &= ~ENHANCED_KEY;
00156         }
00157     }
00158 
00159     DWORD ext_mode = KeyTrans.get_ext_mode();
00160     if(ext_mode) {
00161         // Not as fast as an unrolled loop, but certainly more
00162         // compact (Paul Brannan 12/9/98)
00163         for(DWORD j = ext_mode; j >= APP_KEY; j -= APP_KEY) {
00164             if((j | ext_mode) == ext_mode) {
00165                 if((p = ClosestStateKey(keyCode, keyState | j,
00166                     KeyTrans))) return p;
00167             }
00168         }
00169     }
00170     return ClosestStateKey(keyCode, keyState, KeyTrans);
00171 }
00172 
00173 // Paul Brannan Feb. 22, 1999
00174 int do_op(tn_ops op, TNetwork &Network, Tnclip &Clipboard) {
00175     switch(op) {
00176     case TN_ESCAPE:
00177         return TNPROMPT;
00178     case TN_SCROLLBACK:
00179         return TNSCROLLBACK;
00180     case TN_DIAL:
00181         return TNSPAWN;
00182     case TN_PASTE:
00183         if(ini.get_keyboard_paste()) Clipboard.Paste();
00184         else return 0;
00185         break;
00186     case TN_NULL:
00187         Network.WriteString("", 1);
00188         return 0;
00189     case TN_CR:
00190         Network.WriteString("\r", 2); // CR must be followed by NUL
00191         return 0;
00192     case TN_CRLF:
00193         Network.WriteString("\r\n", 2);
00194         return 0;
00195     }
00196     return 0;
00197 }
00198 
00199 int telProcessConsole(NetParams *pParams, KeyTranslator &KeyTrans,
00200                       TConsole &Console, TNetwork &Network, TMouse &Mouse,
00201                       Tnclip &Clipboard, HANDLE hThread)
00202 {
00203     KeyDefType_const keydef;
00204     const char *p;
00205     int p_len;
00206     unsigned int i;
00207     int opval;
00208     HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
00209 
00210     SetConsoleMode(hConsole, ini.get_enable_mouse() ? ENABLE_MOUSE_INPUT : 0);
00211 
00212     const DWORD nHandle = 2;
00213     HANDLE hHandle[nHandle] = {hConsole, pParams->hExit};
00214 
00215     for (;;) {
00216         DWORD dwInput;
00217         switch (WaitForMultipleObjects(nHandle, hHandle, FALSE, INFINITE)) {
00218         case WAIT_OBJECT_0: {
00219 
00220             // Paul Brannan 7/29/98
00221             if(ini.get_input_redir()) {
00222                 char InputBuffer[10];
00223 
00224                 // Correction from Joe Manns <joe.manns@ardenenginneers.com>
00225                 // to fix race conditions (4/13/99)
00226                 int bResult;
00227                 bResult = ReadFile(hConsole, InputBuffer, 10, &dwInput, 0);
00228                 if(bResult && dwInput == 0) return TNNOCON;
00229 
00230                 // no key translation for redirected input
00231                 Network.WriteString(InputBuffer, dwInput);
00232                 break;
00233             }
00234 
00235             INPUT_RECORD InputRecord[11];
00236             if (!ReadConsoleInput(hConsole, &InputRecord[0], 10, &dwInput))
00237                 return TNPROMPT;
00238 
00239             for (i = 0; (unsigned)i < dwInput; i++){
00240                 switch (InputRecord[i].EventType) {
00241                 case KEY_EVENT:{
00242                     if (KEYEVENT.bKeyDown) {
00243 
00244                         WORD  keyCode  = KEYEVENT.wVirtualKeyCode;
00245                         DWORD keyState = KEYEVENT.dwControlKeyState;
00246 
00247                         // Paul Brannan 5/27/98
00248                         // Moved the code that was here to FindClosestKey()
00249                         keydef.szKeyDef = FindClosestKey(keyCode,
00250                             keyState, KeyTrans);
00251 
00252                         if(keydef.szKeyDef) {
00253                             if(!keydef.op->sendstr)
00254                                 if((opval = do_op(keydef.op->the_op, Network,
00255                                     Clipboard)) != 0)
00256                                     return opval;
00257                         }
00258 
00259                         if(Network.get_line_mode()) {
00260                             if(DoLineModeSpecial(KEYEVENT_CHAR, Console, Network, pParams))
00261                                 continue;
00262                         }
00263 
00264                         p = keydef.szKeyDef;
00265                         if (p == NULL) { // if we don't have a translator
00266                             if(!KEYEVENT_CHAR) continue;
00267                             p_len = 1;
00268                             p = KEYEVENT_PCHAR;
00269                         } else {
00270                             p_len = strlen(p);
00271                         }
00272 
00273                         // Local echo (Paul Brannan 5/16/98)
00274                         DoEcho(p, p_len, Console, Network, pParams);
00275                         // Line mode (Paul Brannan 12/31/98)
00276                         DoLineMode(p, p_len, Console, Network);
00277                     }
00278                                }
00279                     break;
00280 
00281                 case MOUSE_EVENT:
00282                     if(!InputRecord[i].Event.MouseEvent.dwEventFlags) {
00283                         ResetEvent(pParams->hUnPause);
00284                         SetEvent(pParams->hPause);
00285                         while (!*pParams->bNetPaused);  // thread paused
00286                         // SuspendThread(hThread);
00287 
00288                         // Put the mouse's X and Y coords back into the
00289                         // input buffer
00290                         DWORD Result;
00291                         WriteConsoleInput(hConsole, &InputRecord[i], 1,
00292                             &Result);
00293 
00294                         Mouse.doMouse();
00295 
00296                         SetEvent(pParams->hUnPause);
00297                         // ResumeThread(hThread);
00298                     }
00299                     break;
00300 
00301                 case FOCUS_EVENT:
00302                     break;
00303                 case WINDOW_BUFFER_SIZE_EVENT:
00304                     // FIX ME!!  This should take care of the window re-sizing bug
00305                     // Unfortunately, it doesn't.
00306                     Console.sync();
00307                     Network.do_naws(Console.GetWidth(), Console.GetHeight());
00308                     break;
00309                 }
00310 
00311             } // keep going until no more input
00312             break;
00313                             }
00314         default:
00315             return TNNOCON;
00316         }
00317     }
00318 }
00319 
00320 WORD scrollkeys() {
00321     HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
00322     INPUT_RECORD InputRecord;
00323     BOOL done = FALSE;
00324 
00325     while (!done) {
00326         DWORD dwInput;
00327         WaitForSingleObject( hConsole, INFINITE );
00328         if (!ReadConsoleInput(hConsole, &InputRecord, 1, &dwInput)){
00329             done = TRUE;
00330             continue;
00331         }
00332         if (InputRecord.EventType == KEY_EVENT &&
00333             InputRecord.Event.KeyEvent.bKeyDown ) {
00334             // Why not just return the key code?  (Paul Brannan 12/5/98)
00335             return InputRecord.Event.KeyEvent.wVirtualKeyCode;
00336         } else if(InputRecord.EventType == MOUSE_EVENT) {
00337             if(!InputRecord.Event.MouseEvent.dwEventFlags) {
00338                 // Put the mouse's X and Y coords back into the input buffer
00339                 WriteConsoleInput(hConsole, &InputRecord, 1, &dwInput);
00340                 return SC_MOUSE;
00341             }
00342         }
00343     }
00344     return SC_ESC;
00345 }
00346 
00347 // FIX ME!!  This is more evidence that tncon.cpp ought to have class structure
00348 // (Paul Brannan 12/10/98)
00349 
00350 // Bryan Montgomery 10/14/98
00351 static TNetwork net;
00352 void setTNetwork(TNetwork tnet) {
00353     net = tnet;
00354 }
00355 
00356 // Thomas Briggs 8/17/98
00357 BOOL WINAPI ControlEventHandler(DWORD event) {
00358     switch(event) {
00359     case CTRL_BREAK_EVENT:
00360         // Bryan Montgomery 10/14/98
00361         if(ini.get_control_break_as_c()) net.WriteString("\x3",1);
00362         return TRUE;
00363     default:
00364         return FALSE;
00365     }
00366 }

Generated on Fri May 25 2012 04:15:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.