diff options
Diffstat (limited to 'tools/iso/kernel.soso/ttydriver.c')
-rw-r--r-- | tools/iso/kernel.soso/ttydriver.c | 598 |
1 files changed, 0 insertions, 598 deletions
diff --git a/tools/iso/kernel.soso/ttydriver.c b/tools/iso/kernel.soso/ttydriver.c deleted file mode 100644 index 755cda15..00000000 --- a/tools/iso/kernel.soso/ttydriver.c +++ /dev/null @@ -1,598 +0,0 @@ -#include "ttydriver.h" -#include "device.h" -#include "screen.h" -#include "serial.h" -#include "devfs.h" -#include "alloc.h" -#include "common.h" -#include "list.h" -#include "fifobuffer.h" -#include "gfx.h" -#include "debugprint.h" -#include "commonuser.h" -#include "termios.h" - -static List* gTtyList = NULL; - -static List* gReaderList = NULL; - -static Tty* gActiveTty = NULL; - -static uint8 gKeyModifier = 0; - -static uint32 gPseudoTerminalNameGenerator = 0; - -typedef enum KeyModifier { - KM_LeftShift = 1, - KM_RightShift = 2, - KM_Ctrl = 4, - KM_Alt = 8 -} KeyModifier; - -enum { - KEY_LEFTSHIFT = 0x2A, - KEY_RIGHTSHIFT = 0x36, - KEY_CTRL = 0x1D, - KEY_ALT = 0x38, - KEY_CAPSLOCK = 0x3A, - KEY_F1 = 0x3B, - KEY_F2 = 0x3C, - KEY_F3 = 0x3D -}; - -// PC keyboard interface constants - -#define KBSTATP 0x64 // kbd controller status port(I) -#define KBS_DIB 0x01 // kbd data in buffer -#define KBDATAP 0x60 // kbd data port(I) - -#define NO 0 - -#define SHIFT (1<<0) -#define CTL (1<<1) -#define ALT (1<<2) - -#define CAPSLOCK (1<<3) -#define NUMLOCK (1<<4) -#define SCROLLLOCK (1<<5) - -#define E0ESC (1<<6) - -// Special keycodes -#define KEY_HOME 0xE0 -#define KEY_END 0xE1 -#define KEY_UP 0xE2 -#define KEY_DOWN 0xE3 -#define KEY_LEFT 0xE4 -#define KEY_RIGHT 0xE5 -#define KEY_PAGEUP 0xE6 -#define KEY_PAGEDOWN 0xE7 -#define KEY_INSERT 0xE8 -#define KEY_DELETE 0xE9 - -// C('A') == Control-A -#define C(x) (x - '@') - - - - -static uint8 gKeyMap[256] = { - NO, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00 - '7', '8', '9', '0', '-', '=', '\b', '\t', - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10 - 'o', 'p', '[', ']', '\n', NO, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20 - '\'', '`', NO, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', NO, '*', // 0x30 - NO, ' ', NO, NO, NO, NO, NO, NO, - NO, NO, NO, NO, NO, NO, NO, '7', // 0x40 - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', NO, NO, NO, NO, // 0x50 - [0x49] = KEY_PAGEUP, - [0x51] = KEY_PAGEDOWN, - [0x47] = KEY_HOME, - [0x4F] = KEY_END, - [0x52] = KEY_INSERT, - [0x53] = KEY_DELETE, - [0x48] = KEY_UP, - [0x50] = KEY_DOWN, - [0x4B] = KEY_LEFT, - [0x4D] = KEY_RIGHT, - [0x9C] = '\n', // KP_Enter - [0xB5] = '/', // KP_Div - [0xC8] = KEY_UP, - [0xD0] = KEY_DOWN, - [0xC9] = KEY_PAGEUP, - [0xD1] = KEY_PAGEDOWN, - [0xCB] = KEY_LEFT, - [0xCD] = KEY_RIGHT, - [0x97] = KEY_HOME, - [0xCF] = KEY_END, - [0xD2] = KEY_INSERT, - [0xD3] = KEY_DELETE -}; - -static uint8 gKeyShiftMap[256] = { - NO, 033, '!', '@', '#', '$', '%', '^', // 0x00 - '&', '*', '(', ')', '_', '+', '\b', '\t', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10 - 'O', 'P', '{', '}', '\n', NO, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20 - '"', '~', NO, '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', NO, '*', // 0x30 - NO, ' ', NO, NO, NO, NO, NO, NO, - NO, NO, NO, NO, NO, NO, NO, '7', // 0x40 - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', NO, NO, NO, NO, // 0x50 - [0x49] = KEY_PAGEUP, - [0x51] = KEY_PAGEDOWN, - [0x47] = KEY_HOME, - [0x4F] = KEY_END, - [0x52] = KEY_INSERT, - [0x53] = KEY_DELETE, - [0x48] = KEY_UP, - [0x50] = KEY_DOWN, - [0x4B] = KEY_LEFT, - [0x4D] = KEY_RIGHT, - [0x9C] = '\n', // KP_Enter - [0xB5] = '/', // KP_Div - [0xC8] = KEY_UP, - [0xD0] = KEY_DOWN, - [0xC9] = KEY_PAGEUP, - [0xD1] = KEY_PAGEDOWN, - [0xCB] = KEY_LEFT, - [0xCD] = KEY_RIGHT, - [0x97] = KEY_HOME, - [0xCF] = KEY_END, - [0xD2] = KEY_INSERT, - [0xD3] = KEY_DELETE -}; - -static BOOL tty_open(File *file, uint32 flags); -static void tty_close(File *file); -static int32 tty_ioctl(File *file, int32 request, void * argp); -static int32 tty_read(File *file, uint32 size, uint8 *buffer); -static int32 tty_write(File *file, uint32 size, uint8 *buffer); -static int32 write(Tty* tty, uint32 size, uint8 *buffer); - -static uint8 getCharacterForScancode(KeyModifier modifier, uint8 scancode); -static void processScancode(uint8 scancode); - -void initializeTTYs(BOOL graphicMode) { - gTtyList = List_Create(); - - gReaderList = List_Create(); - - for (int i = 1; i <= 9; ++i) { - Tty* tty = NULL; - if (graphicMode) { - tty = createTty(768 / 16, 1024 / 9, Gfx_FlushFromTty); - } - else { - tty = createTty(25, 80, Screen_FlushFromTty); - } - - tty->color = 0x0A; - - List_Append(gTtyList, tty); - - Device device; - memset((uint8*)&device, 0, sizeof(Device)); - sprintf(device.name, "tty%d", i); - device.deviceType = FT_CharacterDevice; - device.open = tty_open; - device.close = tty_close; - device.ioctl = tty_ioctl; - device.read = tty_read; - device.write = tty_write; - device.privateData = tty; - registerDevice(&device); - } - - gActiveTty = List_GetFirstNode(gTtyList)->data; -} - -Tty* getActiveTTY() { - return gActiveTty; -} - -FileSystemNode* createPseudoTerminal() { - Tty* tty = createTty(768 / 16, 1024 / 9, Gfx_FlushFromTty); - - tty->color = 0x0A; - - Device device; - memset((uint8*)&device, 0, sizeof(Device)); - sprintf(device.name, "pts%d", gPseudoTerminalNameGenerator++); - device.deviceType = FT_CharacterDevice; - device.open = tty_open; - device.close = tty_close; - device.ioctl = tty_ioctl; - device.read = tty_read; - device.write = tty_write; - device.privateData = tty; - FileSystemNode* node = registerDevice(&device); - if (NULL == node) { - destroyTty(tty); - } - - return node; -} - -static void sendInputToKeyBuffer(Tty* tty, uint8 scancode, uint8 character) { - char seq[8]; - memset(seq, 0, 8); - - switch (character) { - case KEY_PAGEUP: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 53; - seq[3] = 126; - FifoBuffer_enqueue(tty->keyBuffer, seq, 4); - } - break; - case KEY_PAGEDOWN: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 54; - seq[3] = 126; - FifoBuffer_enqueue(tty->keyBuffer, seq, 4); - } - break; - case KEY_HOME: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 72; - FifoBuffer_enqueue(tty->keyBuffer, seq, 3); - } - break; - case KEY_END: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 70; - FifoBuffer_enqueue(tty->keyBuffer, seq, 3); - } - break; - case KEY_INSERT: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 50; - seq[3] = 126; - FifoBuffer_enqueue(tty->keyBuffer, seq, 4); - } - break; - case KEY_DELETE: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 51; - seq[3] = 126; - FifoBuffer_enqueue(tty->keyBuffer, seq, 4); - } - break; - case KEY_UP: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 65; - FifoBuffer_enqueue(tty->keyBuffer, seq, 3); - } - break; - case KEY_DOWN: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 66; - FifoBuffer_enqueue(tty->keyBuffer, seq, 3); - } - break; - case KEY_RIGHT: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 67; - FifoBuffer_enqueue(tty->keyBuffer, seq, 3); - } - break; - case KEY_LEFT: { - seq[0] = 27; - seq[1] = 91; - seq[2] = 68; - FifoBuffer_enqueue(tty->keyBuffer, seq, 3); - } - break; - default: - FifoBuffer_enqueue(tty->keyBuffer, &character, 1); - break; - } -} - -void sendKeyInputToTTY(Tty* tty, uint8 scancode) { - beginCriticalSection(); - - processScancode(scancode); - - uint8 character = getCharacterForScancode(gKeyModifier, scancode); - - uint8 keyRelease = (0x80 & scancode); //ignore release event - - if (character > 0 && keyRelease == 0) { - //enqueue for non-canonical readers - sendInputToKeyBuffer(tty, scancode, character); - //FifoBuffer_enqueue(tty->keyBuffer, &scancode, 1); - - if (tty->lineBufferIndex >= TTY_LINEBUFFER_SIZE - 1) { - tty->lineBufferIndex = 0; - } - - if (character == '\b') { - if (tty->lineBufferIndex > 0) { - tty->lineBuffer[--tty->lineBufferIndex] = '\0'; - - if ((tty->term.c_lflag & ECHO) == ECHO) { - write(tty, 1, &character); - } - } - } - else { - tty->lineBuffer[tty->lineBufferIndex++] = character; - - if ((tty->term.c_lflag & ECHO) == ECHO) { - write(tty, 1, &character); - } - } - } - - //Wake readers - List_Foreach(n, gReaderList) { - File* file = n->data; - - if (file->thread->state == TS_WAITIO) { - if (file->thread->state_privateData == tty) { - file->thread->state = TS_RUN; - file->thread->state_privateData = NULL; - } - } - } - - endCriticalSection(); -} - -static BOOL tty_open(File *file, uint32 flags) { - //printkf("tty_open: pid:%d\n", file->process->pid); - - Tty* tty = (Tty*)file->node->privateNodeData; - - FifoBuffer_clear(tty->keyBuffer); - - List_Append(gReaderList, file); - - return TRUE; -} - -static void tty_close(File *file) { - List_RemoveFirstOccurrence(gReaderList, file); -} - -static int32 tty_ioctl(File *file, int32 request, void * argp) { - Tty* tty = (Tty*)file->node->privateNodeData; - - switch (request) { - case 0: { - sendKeyInputToTTY(tty, (uint8)(uint32)argp); - - return 0; - } - break; - case 1: - return tty->columnCount * tty->lineCount * 2; - break; - case 2: { - //set - TtyUserBuffer* userTtyBuffer = (TtyUserBuffer*)argp; - memcpy(tty->buffer, (uint8*)userTtyBuffer->buffer, tty->columnCount * tty->lineCount * 2); - return 0; - } - break; - case 3: { - //get - TtyUserBuffer* userTtyBuffer = (TtyUserBuffer*)argp; - userTtyBuffer->columnCount = tty->columnCount; - userTtyBuffer->lineCount = tty->lineCount; - userTtyBuffer->currentColumn = tty->currentColumn; - userTtyBuffer->currentLine = tty->currentLine; - memcpy((uint8*)userTtyBuffer->buffer, tty->buffer, tty->columnCount * tty->lineCount * 2); - return 0; - } - break; - case TCGETS: { - struct termios* term = (struct termios*)argp; - - //Debug_PrintF("TCGETS\n"); - - memcpy((uint8*)term, (uint8*)&(tty->term), sizeof(struct termios)); - - return 0;//success - } - break; - case TCSETS: - case TCSETSW: - break; - case TCSETSF: { - struct termios* term = (struct termios*)argp; - - //Debug_PrintF("TCSETSF\n"); - - memcpy((uint8*)&(tty->term), (uint8*)term, sizeof(struct termios)); - - return 0;//success - } - break; - default: - break; - } - - return -1; -} - -static int32 tty_read(File *file, uint32 size, uint8 *buffer) { - enableInterrupts(); - - if (size > 0) { - Tty* tty = (Tty*)file->node->privateNodeData; - - if ((tty->term.c_lflag & ICANON) == ICANON) { - while (TRUE) { - for (int i = 0; i < tty->lineBufferIndex; ++i) { - char chr = tty->lineBuffer[i]; - - if (chr == '\n') { - int bytesToCopy = MIN(tty->lineBufferIndex, size); - - if (bytesToCopy >= tty->term.c_cc[VMIN]) { - tty->lineBufferIndex = 0; - memcpy(buffer, tty->lineBuffer, bytesToCopy); - - return bytesToCopy; - } - } - } - - file->thread->state = TS_WAITIO; - file->thread->state_privateData = tty; - halt(); - } - } - else { - while (TRUE) { - uint32 neededSize = tty->term.c_cc[VMIN]; - uint32 bufferLen = FifoBuffer_getSize(tty->keyBuffer); - - if (bufferLen >= neededSize) { - int readSize = FifoBuffer_dequeue(tty->keyBuffer, buffer, MIN(bufferLen, size)); - - return readSize; - } - - file->thread->state = TS_WAITIO; - file->thread->state_privateData = tty; - halt(); - } - } - } - - return -1; -} - -static int32 write(Tty* tty, uint32 size, uint8 *buffer) { - buffer[size] = '\0'; - - Tty_PutText(tty, (const char*)buffer); - - if (gActiveTty == tty) { - if (gActiveTty->flushScreen) { - gActiveTty->flushScreen(gActiveTty); - } - } - - return size; -} - -static int32 tty_write(File *file, uint32 size, uint8 *buffer) { - return write(file->node->privateNodeData, size, buffer); -} - -static void setActiveTty(Tty* tty) { - gActiveTty = tty; - - Gfx_Fill(0xFFFFFFFF); - - if (tty->flushScreen) { - tty->flushScreen(tty); - } - - //Serial_PrintF("line:%d column:%d\r\n", gActiveTty->currentLine, gActiveTty->currentColumn); -} - -BOOL isValidTTY(Tty* tty) { - List_Foreach(n, gTtyList) { - if (n->data == tty) { - return TRUE; - } - } - - return FALSE; -} - -static uint8 getCharacterForScancode(KeyModifier modifier, uint8 scancode) { - //return gKeyboardLayout[scancode]; - if ((modifier & KM_LeftShift) == KM_LeftShift || (modifier & KM_RightShift) == KM_RightShift) { - return gKeyShiftMap[scancode]; - } - - return gKeyMap[scancode]; -} - -static void applyModifierKeys(KeyModifier modifier, uint8 scancode) { - if ((modifier & KM_Ctrl) == KM_Ctrl) { - int ttyIndex = scancode - KEY_F1; - //printkf("TTY:%d\n", ttyIndex); - int ttyCount = List_GetCount(gTtyList); - if (ttyIndex >= 0 && ttyIndex < ttyCount) { - int i = 0; - List_Foreach(n, gTtyList) { - if (ttyIndex == i) { - setActiveTty(n->data); - break; - } - ++i; - } - } - } -} - -static void processScancode(uint8 scancode) { - uint8 lastBit = scancode & 0x80; - - scancode &= 0x7F; - - if (lastBit) { - //key release - - switch (scancode) { - case KEY_LEFTSHIFT: - gKeyModifier &= ~KM_LeftShift; - break; - case KEY_RIGHTSHIFT: - gKeyModifier &= ~KM_RightShift; - break; - case KEY_CTRL: - gKeyModifier &= ~KM_Ctrl; - break; - case KEY_ALT: - gKeyModifier &= ~KM_Alt; - break; - } - - //printkf("released: %x (%d)\n", scancode, scancode); - } - else { - //key pressed - - switch (scancode) { - case KEY_LEFTSHIFT: - gKeyModifier |= KM_LeftShift; - break; - case KEY_RIGHTSHIFT: - gKeyModifier |= KM_RightShift; - break; - case KEY_CTRL: - gKeyModifier |= KM_Ctrl; - break; - case KEY_ALT: - gKeyModifier |= KM_Alt; - break; - } - - //printkf("pressed: %x (%d)\n", scancode, scancode); - - applyModifierKeys(gKeyModifier, scancode); - } -} |