aa517d9df69758af9832d6a905124c955f655d9f
[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_F1 :        VT_SetTerminal(0);      return;
79                 case KEYSYM_F2 :        VT_SetTerminal(1);      return;
80                 case KEYSYM_F3 :        VT_SetTerminal(2);      return;
81                 case KEYSYM_F4 :        VT_SetTerminal(3);      return;
82                 case KEYSYM_F5 :        VT_SetTerminal(4);      return;
83                 case KEYSYM_F6 :        VT_SetTerminal(5);      return;
84                 case KEYSYM_F7 :        VT_SetTerminal(6);      return;
85                 case KEYSYM_F8 :        VT_SetTerminal(7);      return;
86                 case KEYSYM_F9 :        VT_SetTerminal(8);      return;
87                 case KEYSYM_F10:        VT_SetTerminal(9);      return;
88                 case KEYSYM_F11:        VT_SetTerminal(10);     return;
89                 case KEYSYM_F12:        VT_SetTerminal(11);     return;
90                 }
91                 
92                 // Scrolling is only valid in text mode
93                 if(term->Mode != TERM_MODE_TEXT)
94                         break;
95                 
96 //              Log_Debug("VTerm", "Magic Ctrl-Alt-0x%x", term->RawScancode);   
97
98                 const unsigned int scroll_step = term->TextHeight / 2;
99                 // Note the lack of giVT_Scrollback+1, view top can't go above size-onescreen
100                 const unsigned int scroll_max = term->TextHeight * giVT_Scrollback;
101                 switch(term->RawScancode)
102                 {
103                 // VTerm scrolling
104                 // - Scrolls half a screen at a time
105                 // - View up (text goes down)
106                 case KEYSYM_PGUP:
107                         if( term->Flags & VT_FLAG_ALTBUF )
108                                 return ;
109                         Log_Debug("VTerm", "ScrollUp - Old=%i, step=%i", term->ViewTopRow, scroll_step);
110                         term->ViewTopRow = (term->ViewTopRow > scroll_step ? term->ViewTopRow - scroll_step : 0);
111                         Log_Debug("VTerm", "ScrollUp - New=%i", term->ViewTopRow);
112                         VT_int_UpdateScreen(term, 1);
113                         return;
114                 // - View down (text goes up)
115                 case KEYSYM_PGDN:
116                         if( term->Flags & VT_FLAG_ALTBUF )
117                                 return ;
118                         
119                         Log_Debug("VTerm", "ScrollDown - Old=%i, max=%i", term->ViewTopRow, scroll_max);
120                         term->ViewTopRow = MIN(term->ViewTopRow + scroll_step, scroll_max);
121                         Log_Debug("VTerm", "ScrollDown - New=%i", term->ViewTopRow);
122                         VT_int_UpdateScreen(term, 1);
123                         return;
124                 }
125                 break;
126         }
127         
128         // Encode key
129         if(term->Mode == PTYBUFFMT_TEXT)
130         {
131                 Uint8   buf[6] = {0};
132                  int    len = 0;
133         
134                 // Ignore anything that isn't a press or refire
135                 if( (Codepoint & KEY_ACTION_MASK) != KEY_ACTION_PRESS
136                  && (Codepoint & KEY_ACTION_MASK) != KEY_ACTION_REFIRE
137                     )
138                 {
139                         return ;
140                 }
141         
142                 Codepoint &= KEY_CODEPOINT_MASK;
143
144                 // Get UTF-8/ANSI Encoding
145                 if( Codepoint == 0 )
146                 {
147                         // Non-printable keys
148                         switch(term->RawScancode)
149                         {
150                         case KEYSYM_LEFTARROW:
151                         case KEYSYM_KP4:
152                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'D';
153                                 len = 3;
154                                 break;
155                         case KEYSYM_RIGHTARROW:
156                         case KEYSYM_KP6:
157                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'C';
158                                 len = 3;
159                                 break;
160                         case KEYSYM_UPARROW:
161                         case KEYSYM_KP8:
162                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'A';
163                                 len = 3;
164                                 break;
165                         case KEYSYM_DOWNARROW:
166                         case KEYSYM_KP2:
167                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'B';
168                                 len = 3;
169                                 break;
170                         
171                         case KEYSYM_PGUP:
172                         case KEYSYM_KP9:        // If Codepoint=0, It's page up
173                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '5'; buf[3] = '~';
174                                 len = 4;
175                                 break;
176                         case KEYSYM_PGDN:
177                         case KEYSYM_KP3:        // If Codepoint=0, It's page down
178                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '6'; buf[3] = '~';
179                                 len = 4;
180                                 break;
181                         
182                         case KEYSYM_HOME:
183                         case KEYSYM_KP7:        // Codepoint==0, then it's home (not translated)
184                                 buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'H';
185                                 len = 3;
186                                 break;
187                         case KEYSYM_END:
188                         case KEYSYM_KP1:        // You get the drill
189                                 buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'F';
190                                 len = 3;
191                                 break;
192                         
193                         case KEYSYM_INSERT:
194                         case KEYSYM_KP0:        // See above
195                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '2'; buf[3] = '~';
196                                 len = 4;
197                                 break;
198                         case KEYSYM_DELETE:
199                         case KEYSYM_KPPERIOD:   // Are you that dumb? Look up
200                                 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '3'; buf[3] = '~';
201                                 len = 4;
202                                 break;
203                         }
204                 }
205                 else if( gbVT_CtrlDown )
206                 {
207                         len = 1;
208                         switch( term->RawScancode )
209                         {
210                         case KEYSYM_2:
211                                 buf[0] = '\0';
212                                 break;
213                         case KEYSYM_3 ... KEYSYM_7:
214                                 buf[0] = 0x1b + (term->RawScancode - KEYSYM_3);
215                                 break;
216                         case KEYSYM_8:
217                                 buf[0] = 0x7f;
218                                 break;
219                         // - Ctrl-A = \1, Ctrl-Z = \x1a
220                         case KEYSYM_a ... KEYSYM_z:
221                                 buf[0] = 0x01 + (term->RawScancode - KEYSYM_a);
222                                 break;
223                         default:
224                                 goto utf_encode;
225                         }
226                 }
227                 else
228                 {
229                 utf_encode:
230                         // Attempt to encode in UTF-8
231                         len = WriteUTF8( buf, Codepoint );
232                         if(len == 0) {
233                                 Warning("Codepoint (%x) is unrepresentable in UTF-8", Codepoint);
234                         }
235                 }
236                 
237                 if(len == 0) {
238                         // Unprintable / Don't Pass
239                         return;
240                 }
241
242                 PTY_SendInput(term->PTY, (void*)buf, len);
243         }
244         else
245         {
246                 PTY_SendInput(term->PTY, (void*)&Codepoint, sizeof(Codepoint));
247         }
248 }
249

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