1 ///////////////////////////////////////////////////////////////////////////////
2 //Telnet Win32 : an ANSI telnet client.
3 //Copyright (C) 1998-2000 Paul Brannan
4 //Copyright (C) 1998 I.Ioannou
5 //Copyright (C) 1997 Brad Johnson
6 //
7 //This program is free software; you can redistribute it and/or
8 //modify it under the terms of the GNU General Public License
9 //as published by the Free Software Foundation; either version 2
10 //of the License, or (at your option) any later version.
11 //
12 //This program is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with this program; if not, write to the Free Software
19 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 //I.Ioannou
22 //roryt@hol.gr
23 //
24 ///////////////////////////////////////////////////////////////////////////
25 
26 ///////////////////////////////////////////////////////////////////
27 //      Key translations - I.Ioannou (roryt@hol.gr)              //
28 //          Athens - Greece    December 18, 1996 02:56am         //
29 //          Reads a .cfg file and keeps the definitions          //
30 //      modified for alternate keymap swiching                   //
31 //          by Andrey V. Smilianets (smile@head.aval.kiev.ua)    //
32 //          Kiev - Ukraine, December 1997.                       //
33 //      modified to work with MSVC and the Standard Template     //
34 //          library by Paul Brannan <pbranna@clemson.edu>,       //
35 //          May 25, 1998                                         //
36 //      updated June 7, 1998 by Paul Brannan to remove cout and  //
37 //          cerr statements                                      //
38 //      APP_KEY and APP2_Key added July 12, 1998 by Paul Brannan //
39 ///////////////////////////////////////////////////////////////////
40 //                class KeyTranslator                            //
41 //  Load          : loads or replaces the keymap                 //
42 //  TranslateKey  : returns a char * to the key def              //
43 //  AddKeyDef     : Changes or adds the key translation          //
44 //  DeleteKeyDef  : Deletes a key def from the list              //
45 ///////////////////////////////////////////////////////////////////
46 
47 #include "precomp.h"
48 
49 /////////////////////////////////////////////////////////////
50 //                class KeyTranslator                      //
51 //  Load          : loads or replaces the keymap           //
52 //  TranslateKey  : returns a sz to the key def            //
53 //  AddKeyDef     : Changes or adds the key translation    //
54 //  DeleteKeyDef  : Deletes a key def from the list        //
55 /////////////////////////////////////////////////////////////
56 
57 
KeyTranslator()58 KeyTranslator::KeyTranslator():
59 mapArray(0,0,sizeof(KeyMap)),
60 globals(0,0,sizeof(TKeyDef)) {
61 	ext_mode = 0;			// Paul Brannan 8/28/98
62 	currentKeyMap = mainKeyMap = -1;
63 };
64 
65 //AVS
66 // perform keymap switching
switchMap(TKeyDef & tk)67 int KeyTranslator::switchMap(TKeyDef& tk) {
68     if ( mapArray.IsEmpty() ) {
69 		return currentKeyMap = -1;
70     };
71     int i = mapArray.Find(KeyMap(tk));
72     if ( i != INT_MAX ) {
73 		if (currentKeyMap == i)
74             currentKeyMap = mainKeyMap; // restore to default
75 		else currentKeyMap = i;
76 		return 1;
77     };
78     return 0;
79 };
80 
81 // Let the calling function interpret the error code (Paul Brannan 12/17/98)
SwitchTo(int to)82 int KeyTranslator::SwitchTo(int to) {
83 
84     int max = mapArray.GetItemsInContainer();
85     if (max == 0) return -1;
86     if (to < 0 || to > (max-1)) return 0;
87 
88     currentKeyMap = to;
89     return 1;
90 };
91 
92 //AVS
93 // rewrited to support multiple keymaps
TranslateKey(WORD wVirtualKeyCode,DWORD dwControlKeyState)94 const char *KeyTranslator::TranslateKey(WORD wVirtualKeyCode,
95 											  DWORD dwControlKeyState)
96 {
97 	if ( mapArray.IsEmpty() ) return NULL;
98 
99 	TKeyDef ask(NULL, dwControlKeyState, wVirtualKeyCode);
100 
101 	// if a keymap switch pressed
102 	if ( switchMap(ask) > 0 ) return "";
103 
104 	int i = mapArray[currentKeyMap].map.Find(ask);
105 
106 	if ( i != INT_MAX) return mapArray[currentKeyMap].map[i].GetszKey();
107 
108 	// if not found in current keymap
109 	if ( currentKeyMap != mainKeyMap ) {
110 		i = mapArray[mainKeyMap].map.Find(ask);
111 		if ( i != INT_MAX)  return mapArray[mainKeyMap].map[i].GetszKey();
112 	};
113 	return NULL;
114 };
115 
116 
117 //AVS
118 // rewrited to support multiple keymaps
AddKeyDef(WORD wVirtualKeyCode,DWORD dwControlKeyState,char * lpzKeyDef)119 int KeyTranslator::AddKeyDef(WORD wVirtualKeyCode, DWORD dwControlKeyState,
120                              char*lpzKeyDef)
121 {
122 	if ( ! mapArray[currentKeyMap].map.IsEmpty() ) {
123 		int i = mapArray[currentKeyMap].map.Find(TKeyDef(NULL, dwControlKeyState, wVirtualKeyCode));
124 		if ( i != INT_MAX) {
125 			mapArray[currentKeyMap].map[i] = lpzKeyDef;
126 			return 1;
127 		}
128 	};
129 	return mapArray[currentKeyMap].map.Add( TKeyDef(lpzKeyDef, dwControlKeyState, wVirtualKeyCode));
130 }
131 
132 // Paul Brannan Feb. 22, 1999
AddKeyDef(WORD wVirtualKeyCode,DWORD dwControlKeyState,tn_ops the_op)133 int KeyTranslator::AddKeyDef(WORD wVirtualKeyCode, DWORD dwControlKeyState,
134                              tn_ops the_op)
135 {
136 	optype op;
137 	op.sendstr = 0;
138 	op.the_op = the_op;
139 	if ( ! mapArray[currentKeyMap].map.IsEmpty() ) {
140 		int i = mapArray[currentKeyMap].map.Find(TKeyDef(NULL, dwControlKeyState, wVirtualKeyCode));
141 		if ( i != INT_MAX) {
142 			mapArray[currentKeyMap].map[i] = op;
143 			return 1;
144 		}
145 	};
146 	return mapArray[currentKeyMap].map.Add( TKeyDef(op, dwControlKeyState, wVirtualKeyCode));
147 }
148 
149 // AVS
LookOnGlobal(char * vkey)150 int KeyTranslator::LookOnGlobal(char* vkey) {
151     if ( ! globals.IsEmpty() ) {
152 		int max = globals.GetItemsInContainer();
153 		for ( int i = 0; i < max ; i++ )
154 			if ( stricmp(globals[i].GetszKey(), vkey) == 0 )
155 				return i;
156     };
157     return INT_MAX;
158 };
159 
AddGlobalDef(WORD wVirtualKeyCode,char * lpzKeyDef)160 int KeyTranslator::AddGlobalDef(WORD wVirtualKeyCode, char*lpzKeyDef) {
161 	if ( ! globals.IsEmpty() ) {
162 		int max = globals.GetItemsInContainer();
163 		for ( int i = 0; i < max ; i++ ) {
164 			const char *s = globals[i].GetszKey();
165 			if ( stricmp(s, lpzKeyDef) == 0 ) {
166 				globals[i] = DWORD(wVirtualKeyCode);
167 				return 1;
168 			}
169 		}
170 	}
171 	return globals.Add( TKeyDef(lpzKeyDef, 0, wVirtualKeyCode));
172 }
173 
174 
175 //AVS
176 // rewrited to support multiple keymaps
DeleteKeyDef(WORD wVirtualKeyCode,DWORD dwControlKeyState)177 int KeyTranslator::DeleteKeyDef(WORD wVirtualKeyCode, DWORD dwControlKeyState)
178 {
179 	if ( mapArray.IsEmpty() || mapArray[currentKeyMap].map.IsEmpty() )
180 		return 0;
181 
182 	int i = mapArray[currentKeyMap].map.Find(TKeyDef(NULL, dwControlKeyState, wVirtualKeyCode));
183 
184 	if ( i != INT_MAX) {
185 		mapArray[currentKeyMap].map.Destroy(i);
186 		return 1;
187 	};
188 	return 0;
189 };
190 
191 //AVS
192 // rewritten to support multiple keymaps
DeleteAllDefs(void)193 void KeyTranslator::DeleteAllDefs(void)
194 {
195 	// This code wants to crash under the STL; Apparently the Destroy()
196 	// function actually deletes the entry, rather than simply releasing
197 	// memory.  I think flush() should do the same thing, at least the
198 	// way it is written with STL_BIDS (Paul Brannan 5/25/98).
199 	int max;
200 
201 	max = mapArray.GetItemsInContainer();
202 	if ( ! mapArray.IsEmpty() ) {
203 		for ( int i = 0; i < max; i++ ) {
204 			if ( !mapArray[i].map.IsEmpty() ) {
205 				mapArray[i].map.Flush();
206 			};
207 		};
208 	};
209 	globals.Flush();
210 	mapArray.Flush();
211 	currentKeyMap = -1;
212 	mainKeyMap    = -1;
213 };
214