luxos/Kernel/debug/console-in.c

163 lines
3.4 KiB
C

#include <debugio.h>
#include <stdio.h>
#include <ctype.h>
#include "../hal/keyboard/keyboard.h"
// extern uint8* VideoPtr;
extern UPoint ConsoleCursor;
// extern UPoint ConsoleSize;
// extern uint8 ConsoleDefaultColor;
extern void _write_char (char c);
extern void _write_string (string s);
int _next_word_index (string s, int32 direction, int32 current, int32 len)
{
int32 tmp = current;
if (direction < 0) {
--tmp;
while ((isspace((unsigned char)s[tmp]) || ispunct((unsigned char)s[tmp])) && tmp > 0) --tmp;
while (isalnum((unsigned char)s[tmp]) && tmp > 0) --tmp;
if (tmp != 0) tmp++;
}
else {
++tmp;
while (isalnum((unsigned char)s[tmp]) && tmp < len) ++tmp;
while ((isspace((unsigned char)s[tmp]) || ispunct((unsigned char)s[tmp])) && tmp < len) ++tmp;
}
return tmp;
}
void _string_crop (string s, int32 start, int32 end, int32* len)
{
int32 i;
for (i = end; i < *len; i++)
s[i-(end-start)] = s[i];
*len = *len - (end - start);
s[*len] = 0;
}
void _string_insert (string s, char what, int32 position, int32* len)
{
int32 i;
for (i = *len; i > position; i--)
s[i] = s[i-1];
s[position] = what;
*len = *len + 1;
s[*len] = 0;
}
void ConsoleReadString (string s, int32 buffer_size, char end_char)
{
Key key;
int32 cursor=0, length = 0, old_length = 0;
UPoint cursor_original = ConsoleCursor;
s[0] = 0;
do {
// Read a key from keyboard
key = ReadKey();
// Process scancode
switch (key.Scancode)
{
// Left arrow
case KeyboardKeyLeft:
if (cursor > 0)
{
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
cursor = _next_word_index(s, -1, cursor, length);
else --cursor;
}
break;
// Right arrow
case KeyboardKeyRight:
if (cursor < length)
{
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
cursor = _next_word_index(s, 1, cursor, length);
else ++cursor;
}
break;
// Delete key
case KeyboardKeyDelete:
{
if (cursor == length) break;
int32 start_d = cursor, end_d;
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
end_d = _next_word_index(s, 1, cursor, length);
else end_d = cursor + 1;
_string_crop(s, start_d, end_d, &length);
break;
}
// Backspace key
case KeyboardKeyBackspace:
{
if (cursor == 0) break;
int32 end = cursor;
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
cursor = _next_word_index(s, -1, cursor, length);
else cursor --;
_string_crop(s, cursor, end, &length);
break;
}
// Home key
case KeyboardKeyHome:
cursor = 0; break;
// End key
case KeyboardKeyEnd:
cursor = length; break;
// Rest of keys
default:
// Ignore non-character keys
if (key.Character == 0 || iscntrl(key.Character)) break;
_string_insert(s, key.Character, cursor, &length);
++cursor;
break;
}
// Redraw string
ConsoleCursor = cursor_original;
// Remove old string if still there
int32 i;
if (old_length > length)
for (i = 0; i < old_length; i++)
_write_char(' ');
old_length = length;
ConsoleCursor = cursor_original;
_write_string(s);
ConsoleCursor = cursor_original;
ConsoleCursorIncreasePos(cursor);
ConsoleCursorUpdateHardware();
} while (key.Character != end_char && length < buffer_size);
ConsoleWriteChar('\n');
}