Kernel/VTerm - Minor cleanup to VT input (remove logging)
[tpg/acess2.git] / KernelLand / Kernel / drv / vterm_input.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * drv/vterm_input.c
6  * - Virtual Terminal - Input code
7  */
8 #include "vterm.h"
9 #include <api_drv_keyboard.h>
10 #define DEBUG   1
11
12 // === GLOBALS ===
13 // --- Key States --- (Used for VT Switching/Magic Combos)
14  int    gbVT_CtrlDown = 0;
15  int    gbVT_AltDown = 0;
16  int    gbVT_SysrqDown = 0;
17
18 // === CODE ===
19 /**
20  * \fn void VT_InitInput()
21  * \brief Initialises the input
22  */
23 void VT_InitInput()
24 {
25         giVT_InputDevHandle = VFS_Open(gsVT_InputDevice, VFS_OPENFLAG_READ);
26         if(giVT_InputDevHandle == -1) {
27                 Log_Warning("VTerm", "Can't open the input device '%s'", gsVT_InputDevice);
28                 return ;
29         }
30         VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack);
31         LOG("VTerm input initialised");
32 }
33
34 /**
35  * \fn void VT_KBCallBack(Uint32 Codepoint)
36  * \brief Called on keyboard interrupt
37  * \param Codepoint     Pseudo-UTF32 character
38  * 
39  * Handles a key press and sends the key code to the user's buffer.
40  * If the code creates a kernel-magic sequence, it is not passed to the
41  * user and is handled in-kernel.
42  */
43 void VT_KBCallBack(Uint32 Codepoint)
44 {
45         tVTerm  *term = gpVT_CurTerm;
46
47         // Catch VT binds
48         switch( Codepoint & KEY_ACTION_MASK )
49         {
50         case KEY_ACTION_RAWSYM:
51                 term->RawScancode = Codepoint & KEY_CODEPOINT_MASK;
52                 break;
53         case KEY_ACTION_RELEASE:
54                 switch(term->RawScancode)
55                 {
56                 case KEYSYM_LEFTALT:    gbVT_AltDown &= ~1;     break;
57                 case KEYSYM_RIGHTALT:   gbVT_AltDown &= ~2;     break;
58                 case KEYSYM_LEFTCTRL:   gbVT_CtrlDown &= ~1;    break;
59                 case KEYSYM_RIGHTCTRL:  gbVT_CtrlDown &= ~2;    break;
60                 }
61                 break;
62         
63         case KEY_ACTION_PRESS:
64                 switch(term->RawScancode)
65                 {
66                 case KEYSYM_LEFTALT:    gbVT_AltDown |= 1;      break;
67                 case KEYSYM_RIGHTALT:   gbVT_AltDown |= 2;      break;
68                 case KEYSYM_LEFTCTRL:   gbVT_CtrlDown |= 1;     break;
69                 case KEYSYM_RIGHTCTRL:  gbVT_CtrlDown |= 2;     break;
70                 }
71                 
72                 // Check if the magic keys are held
73                 if(!gbVT_AltDown || !gbVT_CtrlDown)
74                         break;
75                 
76                 switch(term->RawScancode)
77                 {
78                 case KEYSYM_DELETE:
79                         // TODO: Reboot, or poke secure registered app
80                         return;
81                 case KEYSYM_F1 :        VT_SetTerminal(0);      return;
82                 case KEYSYM_F2 :        VT_SetTerminal(1);      return;
83                 case KEYSYM_F3 :        VT_SetTerminal(2);      return;
84                 case KEYSYM_F4 :        VT_SetTerminal(3);      return;
85                 case KEYSYM_F5 :        VT_SetTerminal(4);      return;
86                 case KEYSYM_F6 :        VT_SetTerminal(5);      return;
87                 case KEYSYM_F7 :        VT_SetTerminal(6);      return;
88                 case KEYSYM_F8 :        VT_SetTerminal(7);      return;
89                 case KEYSYM_F9 :        VT_SetTerminal(8);      return;
90                 case KEYSYM_F10:        VT_SetTerminal(9);      return;
91                 case KEYSYM_F11:        VT_SetTerminal(10);     return;
92                 case KEYSYM_F12:        VT_SetTerminal(11);     return;
93                 }
94                 
95                 // Scrolling is only valid in text mode
96                 if(term->Mode != TERM_MODE_TEXT)
97                         break;
98                 
99 //              Log_Debug("VTerm", "Magic Ctrl-Alt-0x%x", term->RawScancode);   
100
101                 const unsigned int scroll_step = term->TextHeight / 2;
102                 // Note the lack of giVT_Scrollback+1, view top can't go above size-onescreen
103                 const unsigned int scroll_max = term->TextHeight * giVT_Scrollback;
104                 switch(term->RawScancode)
105                 {
106                 // VTerm scrolling
107                 // - Scrolls half a screen at a time
108                 // - View up (text goes down)
109                 case KEYSYM_PGUP:
110                         if( term->Flags & VT_FLAG_ALTBUF )
111                                 return ;
112                         term->ViewTopRow = (term->ViewTopRow > scroll_step ? term->ViewTopRow - scroll_step : 0);
113                         VT_int_UpdateScreen(term, 1);
114                         return;
115                 // - View down (text goes up)
116                 case KEYSYM_PGDN:
117                         if( term->Flags & VT_FLAG_ALTBUF )
118                                 return ;
119                         
120                         term->ViewTopRow = MIN(term->ViewTopRow + scroll_step, scroll_max);
121                         VT_int_UpdateScreen(term, 1);
122                         return;
123                 }
124                 break;
125         }
126         
127         // Encode key
128         if(term->Mode == PTYBUFFMT_TEXT)
129         {
130                 Uint8   buf[6] = {0};
131                  int    len = 0;
132         
133                 // Ignore anything that isn't a press or refire
134                 if( (Codepoint & KEY_ACTION_MASK) != KEY_ACTION_PRESS
135                  && (Codepoint & KEY_ACTION_MASK) != KEY_ACTION_REFIRE
136                     )
137                 {
138                         return ;
139                 }
140         
141                 Codepoint &= KEY_CODEPOINT_MASK;
142
143                 // Get UTF-8/ANSI Encoding
144                 if( Codepoint == 0 )
145                 {
146                         // Non-printable keys
147                         switch(term->RawScancode)
148                         {
149                         case KEYSYM_LEFTARROW:
150                         case KEYSYM_KP4:
151                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'D';
152                                 len = 3;
153                                 break;
154                         case KEYSYM_RIGHTARROW:
155                         case KEYSYM_KP6:
156                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'C';
157                                 len = 3;
158                                 break;
159                         case KEYSYM_UPARROW:
160                         case KEYSYM_KP8:
161                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'A';
162                                 len = 3;
163                                 break;
164                         case KEYSYM_DOWNARROW:
165                         case KEYSYM_KP2:
166                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'B';
167                                 len = 3;
168                                 break;
169                         
170                         case KEYSYM_PGUP:
171                         case KEYSYM_KP9:        // If Codepoint=0, It's page up
172                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '5'; buf[3] = '~';
173                                 len = 4;
174                                 break;
175                         case KEYSYM_PGDN:
176                         case KEYSYM_KP3:        // If Codepoint=0, It's page down
177                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '6'; buf[3] = '~';
178                                 len = 4;
179                                 break;
180                         
181                         case KEYSYM_HOME:
182                         case KEYSYM_KP7:        // Codepoint==0, then it's home (not translated)
183                                 buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'H';
184                                 len = 3;
185                                 break;
186                         case KEYSYM_END:
187                         case KEYSYM_KP1:        // You get the drill
188                                 buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'F';
189                                 len = 3;
190                                 break;
191                         
192                         case KEYSYM_INSERT:
193                         case KEYSYM_KP0:        // See above
194                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '2'; buf[3] = '~';
195                                 len = 4;
196                                 break;
197                         case KEYSYM_DELETE:
198                         case KEYSYM_KPPERIOD:   // Are you that dumb? Look up
199                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '3'; buf[3] = '~';
200                                 len = 4;
201                                 break;
202                         }
203                 }
204                 else if( gbVT_CtrlDown )
205                 {
206                         len = 1;
207                         switch( term->RawScancode )
208                         {
209                         case KEYSYM_2:
210                                 buf[0] = '\0';
211                                 break;
212                         case KEYSYM_3 ... KEYSYM_7:
213                                 buf[0] = 0x1b + (term->RawScancode - KEYSYM_3);
214                                 break;
215                         case KEYSYM_8:
216                                 buf[0] = 0x7f;
217                                 break;
218                         // - Ctrl-A = \1, Ctrl-Z = \x1a
219                         case KEYSYM_a ... KEYSYM_z:
220                                 buf[0] = 0x01 + (term->RawScancode - KEYSYM_a);
221                                 break;
222                         default:
223                                 goto utf_encode;
224                         }
225                 }
226                 else
227                 {
228                 utf_encode:
229                         // Attempt to encode in UTF-8
230                         len = WriteUTF8( buf, Codepoint );
231                         if(len == 0) {
232                                 Warning("Codepoint (%x) is unrepresentable in UTF-8", Codepoint);
233                         }
234                 }
235                 
236                 if(len == 0) {
237                         // Unprintable / Don't Pass
238                         return;
239                 }
240
241                 PTY_SendInput(term->PTY, (void*)buf, len);
242         }
243         else
244         {
245                 PTY_SendInput(term->PTY, (void*)&Codepoint, sizeof(Codepoint));
246         }
247 }
248

UCC git Repository :: git.ucc.asn.au