3 * - By John Hodge (thePowersGang)
6 * - Virtual Terminal - Input code
9 #include <api_drv_keyboard.h>
13 // --- Key States --- (Used for VT Switching/Magic Combos)
14 int gbVT_CtrlDown = 0;
16 int gbVT_SysrqDown = 0;
20 * \fn void VT_InitInput()
21 * \brief Initialises the input
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);
30 VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack);
31 LOG("VTerm input initialised");
35 * \fn void VT_KBCallBack(Uint32 Codepoint)
36 * \brief Called on keyboard interrupt
37 * \param Codepoint Pseudo-UTF32 character
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.
43 void VT_KBCallBack(Uint32 Codepoint)
45 tVTerm *term = gpVT_CurTerm;
48 switch( Codepoint & KEY_ACTION_MASK )
50 case KEY_ACTION_RAWSYM:
51 term->RawScancode = Codepoint & KEY_CODEPOINT_MASK;
53 case KEY_ACTION_RELEASE:
54 switch(term->RawScancode)
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;
63 case KEY_ACTION_PRESS:
64 switch(term->RawScancode)
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;
72 // Check if the magic keys are held
73 if(!gbVT_AltDown || !gbVT_CtrlDown)
76 switch(term->RawScancode)
79 // TODO: Reboot, or poke secure registered app
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;
95 // Scrolling is only valid in text mode
96 if(term->Mode != TERM_MODE_TEXT)
99 // Log_Debug("VTerm", "Magic Ctrl-Alt-0x%x", term->RawScancode);
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)
107 // - Scrolls half a screen at a time
108 // - View up (text goes down)
110 if( term->Flags & VT_FLAG_ALTBUF )
112 term->ViewTopRow = (term->ViewTopRow > scroll_step ? term->ViewTopRow - scroll_step : 0);
113 VT_int_UpdateScreen(term, 1);
115 // - View down (text goes up)
117 if( term->Flags & VT_FLAG_ALTBUF )
120 term->ViewTopRow = MIN(term->ViewTopRow + scroll_step, scroll_max);
121 VT_int_UpdateScreen(term, 1);
128 if(term->Mode == PTYBUFFMT_TEXT)
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
141 Codepoint &= KEY_CODEPOINT_MASK;
143 // Get UTF-8/ANSI Encoding
146 // Non-printable keys
147 switch(term->RawScancode)
149 case KEYSYM_LEFTARROW:
151 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'D';
154 case KEYSYM_RIGHTARROW:
156 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'C';
161 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'A';
164 case KEYSYM_DOWNARROW:
166 buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'B';
171 case KEYSYM_KP9: // If Codepoint=0, It's page up
172 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '5'; buf[3] = '~';
176 case KEYSYM_KP3: // If Codepoint=0, It's page down
177 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '6'; buf[3] = '~';
182 case KEYSYM_KP7: // Codepoint==0, then it's home (not translated)
183 buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'H';
187 case KEYSYM_KP1: // You get the drill
188 buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'F';
193 case KEYSYM_KP0: // See above
194 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '2'; buf[3] = '~';
198 case KEYSYM_KPPERIOD: // Are you that dumb? Look up
199 buf[0] = '\x1B'; buf[1] = '['; buf[2] = '3'; buf[3] = '~';
204 else if( gbVT_CtrlDown )
207 switch( term->RawScancode )
212 case KEYSYM_3 ... KEYSYM_7:
213 buf[0] = 0x1b + (term->RawScancode - KEYSYM_3);
218 // - Ctrl-A = \1, Ctrl-Z = \x1a
219 case KEYSYM_a ... KEYSYM_z:
220 buf[0] = 0x01 + (term->RawScancode - KEYSYM_a);
229 // Attempt to encode in UTF-8
230 len = WriteUTF8( buf, Codepoint );
232 Warning("Codepoint (%x) is unrepresentable in UTF-8", Codepoint);
237 // Unprintable / Don't Pass
241 PTY_SendInput(term->PTY, (void*)buf, len);
245 PTY_SendInput(term->PTY, (void*)&Codepoint, sizeof(Codepoint));