#include #include #include #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'); }