X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fvterm.c;h=1d4b367246507933e0219e86670eb5f14e373565;hb=5985944028ce18d8abf3bcf5208545a506526f0f;hp=bb658f2fc0f3058f911e00e9298290539e04ead6;hpb=7941d6b368acb0abc17e6a77ffaf7b4c306b67ab;p=tpg%2Facess2.git diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index bb658f2f..1d4b3672 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -5,14 +5,12 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include -#define USE_CTRL_ALT 1 - // === CONSTANTS === #define VERSION ((0<<8)|(50)) @@ -21,14 +19,17 @@ #define MAX_INPUT_CHARS8 (MAX_INPUT_CHARS32*4) //#define DEFAULT_OUTPUT "BochsGA" #define DEFAULT_OUTPUT "Vesa" +#define FALLBACK_OUTPUT "x86_VGAText" #define DEFAULT_INPUT "PS2Keyboard" #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 480 #define DEFAULT_SCROLLBACK 2 // 2 Screens of text + current screen +//#define DEFAULT_SCROLLBACK 0 #define DEFAULT_COLOUR (VT_COL_BLACK|(0xAAA<<16)) #define VT_FLAG_HIDECSR 0x01 #define VT_FLAG_ALTBUF 0x02 //!< Alternate screen buffer +#define VT_FLAG_RAWIN 0x04 //!< Don't handle ^Z/^C/^V #define VT_FLAG_HASFB 0x10 //!< Set if the VTerm has requested the Framebuffer enum eVT_InModes { @@ -109,7 +110,7 @@ const Uint16 caVT100Colours[] = { }; // === GLOBALS === -MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, DEFAULT_OUTPUT, DEFAULT_INPUT, NULL); +MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, DEFAULT_INPUT, FALLBACK_OUTPUT, NULL); tDevFS_Driver gVT_DrvInfo = { NULL, "VTerm", { @@ -169,11 +170,11 @@ int VT_Install(char **Arguments) Log_Debug("VTerm", "Argument '%s'", arg); if( strcmp(opt, "Video") == 0 ) { - if( !gsVT_OutputDevice && Modules_InitialiseBuiltin( val ) == 0 ) + if( !gsVT_OutputDevice ) gsVT_OutputDevice = strdup(val); } else if( strcmp(opt, "Input") == 0 ) { - if( !gsVT_InputDevice && Modules_InitialiseBuiltin( val ) == 0 ) + if( !gsVT_InputDevice ) gsVT_InputDevice = strdup(val); } else if( strcmp(opt, "Width") == 0 ) { @@ -189,16 +190,21 @@ int VT_Install(char **Arguments) } // Apply Defaults - if(!gsVT_OutputDevice) gsVT_OutputDevice = strdup(DEFAULT_OUTPUT); - if(!gsVT_InputDevice) gsVT_InputDevice = strdup(DEFAULT_INPUT); + if(!gsVT_OutputDevice) gsVT_OutputDevice = (char*)DEFAULT_OUTPUT; + else if( Module_EnsureLoaded( gsVT_OutputDevice ) ) gsVT_OutputDevice = (char*)DEFAULT_OUTPUT; + if( Module_EnsureLoaded( gsVT_OutputDevice ) ) gsVT_OutputDevice = (char*)FALLBACK_OUTPUT; + + if(!gsVT_InputDevice) gsVT_InputDevice = (char*)DEFAULT_INPUT; + else if( Module_EnsureLoaded( gsVT_InputDevice ) ) gsVT_InputDevice = (char*)DEFAULT_INPUT; - // Create paths + // Create device paths { char *tmp; tmp = malloc( 9 + strlen(gsVT_OutputDevice) + 1 ); strcpy(tmp, "/Devices/"); strcpy(&tmp[9], gsVT_OutputDevice); gsVT_OutputDevice = tmp; + tmp = malloc( 9 + strlen(gsVT_InputDevice) + 1 ); strcpy(tmp, "/Devices/"); strcpy(&tmp[9], gsVT_InputDevice); @@ -245,7 +251,6 @@ int VT_Install(char **Arguments) // Set kernel output to VT0 Debug_SetKTerminal("/Devices/VTerm/0"); - Log_Log("VTerm", "Returning %i", MODULE_ERR_OK); return MODULE_ERR_OK; } @@ -319,12 +324,15 @@ void VT_SetResolution(int Width, int Height) // Resize the text terminals giVT_RealWidth = mode.width; giVT_RealHeight = mode.height; + Log_Debug("VTerm", "Resizing terminals to %ix%i", + giVT_RealWidth/giVT_CharWidth, giVT_RealHeight/giVT_CharHeight); for( i = 0; i < NUM_VTS; i ++ ) { if( gVT_Terminals[i].Mode != TERM_MODE_TEXT ) continue; gVT_Terminals[i].TextWidth = giVT_RealWidth/giVT_CharWidth; gVT_Terminals[i].TextHeight = giVT_RealHeight/giVT_CharHeight; + gVT_Terminals[i].ScrollHeight = gVT_Terminals[i].TextHeight; gVT_Terminals[i].Text = realloc( gVT_Terminals[i].Text, @@ -426,7 +434,6 @@ int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data) } /** - * \fn Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) * \brief Read from a virtual terminal */ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) @@ -465,7 +472,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) // Other - UCS-4 default: VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "VT_Read (UCS-4)"); - + avail = term->InputWrite - term->InputRead; if(avail < 0) avail += MAX_INPUT_CHARS32; @@ -752,30 +759,20 @@ void VT_KBCallBack(Uint32 Codepoint) Codepoint &= 0x7FFFFFFF; switch(Codepoint) { - #if !USE_CTRL_ALT - case KEY_RSHIFT: gbVT_CtrlDown = 0; break; - case KEY_LSHIFT: gbVT_AltDown = 0; break; - #else case KEY_LALT: gbVT_AltDown &= ~1; break; case KEY_RALT: gbVT_AltDown &= ~2; break; case KEY_LCTRL: gbVT_CtrlDown &= ~1; break; case KEY_RCTRL: gbVT_CtrlDown &= ~2; break; - #endif } return; } switch(Codepoint) { - #if !USE_CTRL_ALT // HACK: Use both shifts instead of Ctrl-Alt - case KEY_RSHIFT: gbVT_CtrlDown = 1; break; - case KEY_LSHIFT: gbVT_AltDown = 1; break; - #else case KEY_LALT: gbVT_AltDown |= 1; break; case KEY_RALT: gbVT_AltDown |= 2; break; case KEY_LCTRL: gbVT_CtrlDown |= 1; break; case KEY_RCTRL: gbVT_CtrlDown |= 2; break; - #endif default: if(!gbVT_AltDown || !gbVT_CtrlDown) @@ -806,10 +803,10 @@ void VT_KBCallBack(Uint32 Codepoint) case KEY_PGDOWN: if( gpVT_CurTerm->Flags & VT_FLAG_ALTBUF ) return ; - if( gpVT_CurTerm->ViewPos < gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback-1) ) + if( gpVT_CurTerm->ViewPos < gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback) ) gpVT_CurTerm->ViewPos += gpVT_CurTerm->Width; else - gpVT_CurTerm->ViewPos = gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback-1); + gpVT_CurTerm->ViewPos = gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback); return; } } @@ -865,6 +862,19 @@ void VT_KBCallBack(Uint32 Codepoint) // Unprintable / Don't Pass return; } + +#if 0 + // Handle meta characters + if( !(term->Flags & VT_FLAG_RAWIN) ) + { + switch(buf[0]) + { + case '\3': // ^C + + break; + } + } +#endif // Write if( MAX_INPUT_CHARS8 - term->InputWrite >= len ) @@ -895,11 +905,6 @@ void VT_KBCallBack(Uint32 Codepoint) } VFS_MarkAvaliable(&term->Node, 1); - - // Wake up the thread waiting on us - //if( term->ReadingThread >= 0 ) { - // Threads_WakeTID(term->ReadingThread); - //} } /** @@ -959,7 +964,7 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer) } // Get Command - if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) + if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { if( bQuestionMark ) { @@ -984,6 +989,9 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer) break; } break; + default: + Log_Warning("VTerm", "Unknown control sequence '\\x1B[?%c'", c); + break; } } else @@ -1044,22 +1052,83 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer) break; } break; + + // Erase in line + case 'K': + switch(args[0]) + { + case 0: // Erase to right + if( Term->Flags & VT_FLAG_ALTBUF ) + { + int i, max; + max = Term->Width - Term->AltWritePos % Term->Width; + for( i = 0; i < max; i ++ ) + Term->AltBuf[Term->AltWritePos+i].Ch = 0; + } + else + { + int i, max; + max = Term->Width - Term->WritePos % Term->Width; + for( i = 0; i < max; i ++ ) + Term->Text[Term->WritePos+i].Ch = 0; + } + VT_int_UpdateScreen(Term, 0); + break; + case 1: // Erase to left + if( Term->Flags & VT_FLAG_ALTBUF ) + { + int i = Term->AltWritePos % Term->Width; + while( i -- ) + Term->AltBuf[Term->AltWritePos++].Ch = 0; + } + else + { + int i = Term->WritePos % Term->Width; + while( i -- ) + Term->Text[Term->WritePos++].Ch = 0; + } + VT_int_UpdateScreen(Term, 0); + break; + case 2: // Erase all + if( Term->Flags & VT_FLAG_ALTBUF ) + { + VT_int_ClearLine(Term, Term->AltWritePos / Term->Width); + } + else + { + VT_int_ClearLine(Term, Term->WritePos / Term->Width); + } + VT_int_UpdateScreen(Term, 0); + break; + } + break; + // Set cursor position case 'H': if( Term->Flags & VT_FLAG_ALTBUF ) Term->AltWritePos = args[0] + args[1]*Term->TextWidth; else Term->WritePos = args[0] + args[1]*Term->TextWidth; - Log_Debug("VTerm", "args = {%i, %i}", args[0], args[1]); + //Log_Debug("VTerm", "args = {%i, %i}", args[0], args[1]); break; // Scroll up `n` lines case 'S': tmp = -1; // Scroll down `n` lines - case 'P': + case 'T': if(argc == 1) tmp *= args[0]; - + if( Term->Flags & VT_FLAG_ALTBUF ) + VT_int_ScrollText(Term, tmp); + else + { + if(Term->ViewPos/Term->TextWidth + tmp < 0) + break; + if(Term->ViewPos/Term->TextWidth + tmp > Term->TextHeight * (giVT_Scrollback + 1)) + break; + + Term->ViewPos += Term->TextWidth*tmp; + } break; // Set Font flags @@ -1097,7 +1166,7 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer) break; default: - Log_Warning("VTerm", "Unknown control sequence"); + Log_Warning("VTerm", "Unknown control sequence '\\x1B[%c'", c); break; } } @@ -1183,13 +1252,15 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) write_pos -= write_pos % Term->TextWidth; break; - case '\t': + case '\t': { int tmp = write_pos / Term->TextWidth; + write_pos %= Term->TextWidth; do { buffer[ write_pos ].Ch = '\0'; buffer[ write_pos ].Colour = Term->CurColour; write_pos ++; } while(write_pos & 7); - break; + write_pos += tmp * Term->TextWidth; + break; } case '\b': // Backspace is invalid at Offset 0 @@ -1264,8 +1335,11 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch) // Update the last line Term->WritePos -= Term->TextWidth; VT_int_UpdateScreen( Term, 0 ); + Term->WritePos += Term->TextWidth; VT_int_ScrollText(Term, 1); + + Term->ViewPos += Term->TextWidth; } } @@ -1276,43 +1350,56 @@ void VT_int_ScrollText(tVTerm *Term, int Count) { tVT_Char *buf; int height, init_write_pos; - int base, len, i; - + int len, i; + int scroll_top, scroll_height; + + // Get buffer pointer and attributes if( Term->Flags & VT_FLAG_ALTBUF ) { buf = Term->AltBuf; height = Term->TextHeight; init_write_pos = Term->AltWritePos; + scroll_top = Term->ScrollTop; + scroll_height = Term->ScrollHeight; } else { buf = Term->Text; - height = Term->TextHeight*giVT_Scrollback; + height = Term->TextHeight*(giVT_Scrollback+1); init_write_pos = Term->WritePos; + scroll_top = 0; + scroll_height = height; } - + + // Scroll text downwards if( Count > 0 ) { - if(Count > Term->ScrollHeight) Count = Term->ScrollHeight; - base = Term->TextWidth*(Term->ScrollTop + Term->ScrollHeight - Count); - len = Term->TextWidth*(height - Term->ScrollHeight - Count - Term->ScrollTop); + int base; + + // Set up + if(Count > scroll_height) Count = scroll_height; + base = Term->TextWidth*(scroll_top + scroll_height - Count); + len = Term->TextWidth*(scroll_height - Count); // Scroll terminal cache - memcpy( - &buf[Term->TextWidth*Term->ScrollTop], - &buf[Term->TextWidth*(Term->ScrollTop+Count)], + memmove( + &buf[Term->TextWidth*scroll_top], + &buf[Term->TextWidth*(scroll_top+Count)], len*sizeof(tVT_Char) ); // Clear last rows for( i = 0; i < Term->TextWidth*Count; i ++ ) { - Term->AltBuf[ base + i ].Ch = 0; - Term->AltBuf[ base + i ].Colour = Term->CurColour; + buf[ base + i ].Ch = 0; + buf[ base + i ].Colour = Term->CurColour; } // Update Screen VT_int_ScrollFramebuffer( Term, Count ); - Term->WritePos = Term->ViewPos + Term->ScrollTop + (Term->ScrollHeight - Count); + if( Term->Flags & VT_FLAG_ALTBUF ) + Term->AltWritePos = base; + else + Term->WritePos = Term->ViewPos + Term->TextWidth*(Term->TextHeight - Count); for( i = 0; i < Count; i ++ ) { VT_int_UpdateScreen( Term, 0 ); @@ -1325,25 +1412,28 @@ void VT_int_ScrollText(tVTerm *Term, int Count) else { Count = -Count; - if(Count > Term->ScrollHeight) Count = Term->ScrollHeight; + if(Count > scroll_height) Count = scroll_height; - len = Term->TextWidth*(height - Term->ScrollHeight - Count - Term->ScrollTop); + len = Term->TextWidth*(scroll_height - Count); // Scroll terminal cache - memcpy( - &buf[Term->TextWidth*(Term->ScrollTop+Count)], - &buf[Term->TextWidth*Term->ScrollTop], + memmove( + &buf[Term->TextWidth*(scroll_top+Count)], + &buf[Term->TextWidth*scroll_top], len*sizeof(tVT_Char) ); // Clear preceding rows for( i = 0; i < Term->TextWidth*Count; i ++ ) { - Term->AltBuf[ i ].Ch = 0; - Term->AltBuf[ i ].Colour = Term->CurColour; + buf[ i ].Ch = 0; + buf[ i ].Colour = Term->CurColour; } VT_int_ScrollFramebuffer( Term, -Count ); - Term->WritePos = Term->ViewPos + Term->ScrollTop; + if( Term->Flags & VT_FLAG_ALTBUF ) + Term->AltWritePos = Term->TextWidth*scroll_top; + else + Term->WritePos = Term->ViewPos; for( i = 0; i < Count; i ++ ) { VT_int_UpdateScreen( Term, 0 ); @@ -1387,19 +1477,20 @@ void VT_int_ScrollFramebuffer( tVTerm *Term, int Count ) // BLIT to 0,0 from 0,giVT_CharHeight buf.Op = VIDEO_2DOP_BLIT; buf.SrcX = 0; buf.DstX = 0; + // TODO: Don't assume character dimensions buf.W = Term->TextWidth * giVT_CharWidth; if( Count > 0 ) { buf.SrcY = (Term->ScrollTop+Count) * giVT_CharHeight; buf.DstY = Term->ScrollTop * giVT_CharHeight; - buf.H = (Term->ScrollHeight-Count) * giVT_CharHeight; } else // Scroll up, move text down { + Count = -Count; buf.SrcY = Term->ScrollTop * giVT_CharHeight; buf.DstY = (Term->ScrollTop+Count) * giVT_CharHeight; - buf.H = (Term->ScrollHeight+Count) * giVT_CharHeight; } + buf.H = (Term->ScrollHeight-Count) * giVT_CharHeight; VFS_WriteAt(giVT_OutputDevHandle, 0, sizeof(buf), &buf); // Restore old mode (this function is only called during text mode) @@ -1558,6 +1649,7 @@ void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled) Term->Flags |= VT_FLAG_ALTBUF; else Term->Flags &= ~VT_FLAG_ALTBUF; + VT_int_UpdateScreen(Term, 1); } // ---