From 5c29fcc13d3db145e00c01f88d0a584966c6bc38 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 19 May 2013 00:56:52 +0800 Subject: [PATCH] Kernel - Misc fixes and debug in VTerm/PTY, AxWin3 starts again - Added PW/PH fields to ptydims for pixel sizes - AxWin3 cursor is broken (new cursor API is unimplimented) --- KernelLand/Kernel/drv/pty.c | 18 +++-- KernelLand/Kernel/drv/vterm.c | 42 ++++++++-- Usermode/Applications/axwin3_src/WM/video.c | 81 +++++++++++++------ .../include_exp/acess/devices/pty.h | 6 ++ .../include_exp/acess/devices/pty_cmds.h | 11 ++- 5 files changed, 122 insertions(+), 36 deletions(-) diff --git a/KernelLand/Kernel/drv/pty.c b/KernelLand/Kernel/drv/pty.c index ace6c53b..abfd9d14 100644 --- a/KernelLand/Kernel/drv/pty.c +++ b/KernelLand/Kernel/drv/pty.c @@ -5,7 +5,7 @@ * drv/pty.c * - Pseudo Terminals */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include @@ -230,8 +230,7 @@ int PTY_SetAttrib(tPTY *PTY, const struct ptydims *Dims, const struct ptymode *M errno = EINVAL; return -1; } - PTY->Mode = *Mode; - if( !WasClient ) + if( WasClient ) { if( PTY->ModeSet && PTY->ModeSet(PTY->OutputHandle, Mode) ) { @@ -245,10 +244,17 @@ int PTY_SetAttrib(tPTY *PTY, const struct ptydims *Dims, const struct ptymode *M // ACK by server doing GETMODE } } + else + { + // Should the client be informed that the server just twiddled the modes? + } + LOG("PTY %p mode set to {0%o, 0%o}", PTY, Mode->InputMode, Mode->OutputMode); + PTY->Mode = *Mode; } if( Dims ) { - if( WasClient ) { + if( WasClient ) + { // Poke the server? if( PTY->ReqResize && PTY->ReqResize(PTY->OutputHandle, Dims) ) { @@ -260,9 +266,11 @@ int PTY_SetAttrib(tPTY *PTY, const struct ptydims *Dims, const struct ptymode *M // Inform server process... somehow } } - else { + else + { // SIGWINSZ to client } + LOG("PTY %p dims set to %ix%i", PTY, Dims->W, Dims->H); PTY->Dims = *Dims; } return 0; diff --git a/KernelLand/Kernel/drv/vterm.c b/KernelLand/Kernel/drv/vterm.c index a6cf771f..dc39cb30 100644 --- a/KernelLand/Kernel/drv/vterm.c +++ b/KernelLand/Kernel/drv/vterm.c @@ -5,7 +5,7 @@ * drv/vterm.c * - Virtual Terminal - Initialisation and VFS Interface */ -#define DEBUG 0 +#define DEBUG 1 #include "vterm.h" #include #include @@ -182,7 +182,13 @@ int VT_Install(char **Arguments) .OutputMode = PTYBUFFMT_TEXT, .InputMode = PTYIMODE_CANON|PTYIMODE_ECHO }; - PTY_SetAttrib(gVT_Terminals[i].PTY, NULL, &mode, 0); + struct ptydims dims = { + .W = giVT_RealWidth / giVT_CharWidth, + .H = giVT_RealHeight / giVT_CharHeight, + .PW = giVT_RealWidth, + .PH = giVT_RealHeight + }; + PTY_SetAttrib(gVT_Terminals[i].PTY, &dims, &mode, 0); } // Add to DevFS @@ -298,17 +304,24 @@ void VT_int_PutFBData(tVTerm *Term, size_t Offset, size_t Length, const void *Bu { size_t maxlen = Term->Width * Term->Height * 4; - if( Offset >= maxlen ) + ENTER("pTerm xOffset xLength pBuffer", Term, Offset, Length, Buffer); + + if( Offset >= maxlen ) { + LEAVE('-'); return ; + } + LOG("maxlen = 0x%x", maxlen); Length = MIN(Length, maxlen - Offset); // If the terminal is currently shown, write directly to the screen if( Term == gpVT_CurTerm ) { // Center the terminal vertically - if( giVT_RealHeight > Term->Height ) + if( giVT_RealHeight > Term->Height ) { Offset += (giVT_RealHeight - Term->Height) / 2 * Term->Width * 4; + LOG("Altered offset 0x%x", Offset); + } // If the terminal is not native width, center it horizontally if( giVT_RealWidth > Term->Width ) @@ -319,7 +332,9 @@ void VT_int_PutFBData(tVTerm *Term, size_t Offset, size_t Length, const void *Bu // TODO: Fix to handle the final line correctly? x = Offset/4; y = x / Term->Width; x %= Term->Width; w = Length/4+x; h = w / Term->Width; w %= Term->Width; - + + LOG("(%i,%i) %ix%i", x, y, w, h); + // Center x += (giVT_RealWidth - Term->Width) / 2; dst_ofs = (x + y * giVT_RealWidth) * 4; @@ -345,9 +360,11 @@ void VT_int_PutFBData(tVTerm *Term, size_t Offset, size_t Length, const void *Bu { if( !Term->Buffer ) Term->Buffer = malloc( Term->Width * Term->Height * 4 ); + LOG("Direct to cache"); // Copy to the local cache memcpy( (char*)Term->Buffer + Offset, Buffer, Length ); } + LEAVE('-'); } void VT_PTYOutput(void *Handle, size_t Length, const void *Data) @@ -386,6 +403,19 @@ int VT_PTYModeset(void *Handle, const struct ptymode *Mode) { tVTerm *term = Handle; term->Mode = (Mode->OutputMode & PTYOMODE_BUFFMT); + + if( term == gpVT_CurTerm ) { + switch(term->Mode) + { + case PTYBUFFMT_TEXT: + VT_SetMode(VIDEO_BUFFMT_TEXT); + break; + default: + VT_SetMode(VIDEO_BUFFMT_FRAMEBUFFER); + break; + } + } + return 0; } @@ -636,7 +666,7 @@ void VT_SetTerminal(int ID) LOG("Attempting VT_SetMode"); - if( gpVT_CurTerm->Mode == TERM_MODE_TEXT ) + if( gpVT_CurTerm->Mode == PTYBUFFMT_TEXT ) { VT_SetMode( VIDEO_BUFFMT_TEXT ); } diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index dfdd2e50..b3ce1d7c 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -7,7 +7,8 @@ */ #include #include -#include +#include +#include #include #include "resources/cursor.h" #include @@ -20,6 +21,7 @@ extern int giTerminalFD_Input; // === PROTOTYPES === void Video_Setup(void); +void Video_int_SetBufFmt(int NewFmt); void Video_SetCursorPos(short X, short Y); void Video_Update(void); void Video_FillRect(int X, int Y, int W, int H, uint32_t Color); @@ -34,7 +36,7 @@ uint32_t *gpScreenBuffer; // === CODE === void Video_Setup(void) { - int tmpInt; + int rv; // Open terminal #if 0 @@ -47,40 +49,49 @@ void Video_Setup(void) #else giTerminalFD = 1; giTerminalFD_Input = 0; - // Check that the console is a VT + // Check that the console is a PTY // - _SysIOCtl(..., 0, NULL) returns the type, which should be 2 - tmpInt = _SysIOCtl(1, 0, NULL); - if( tmpInt != 2 ) + rv = _SysIOCtl(1, DRV_IOCTL_TYPE, NULL); + if( rv != DRV_TYPE_TERMINAL ) { - fprintf(stderr, "stdout is not an Acess VT, can't start (2 exp, %i got)\n", tmpInt); - _SysDebug("stdout is not an Acess VT, can't start"); + fprintf(stderr, "stdout is not a PTY, can't start (%i exp, %i got)\n", + DRV_TYPE_TERMINAL, rv); + _SysDebug("stdout is not an PTY, can't start"); exit(-1); } #endif - + + // TODO: Check terminal echoback that it does support graphical modes + // And/or have terminal flags fetchable by the client + // Set mode to video - tmpInt = TERM_MODE_FB; - _SysIOCtl( giTerminalFD, TERM_IOCTL_MODETYPE, &tmpInt ); - + Video_int_SetBufFmt(PTYBUFFMT_FB); + // Get dimensions - giScreenWidth = _SysIOCtl( giTerminalFD, TERM_IOCTL_WIDTH, NULL ); - giScreenHeight = _SysIOCtl( giTerminalFD, TERM_IOCTL_HEIGHT, NULL ); + struct ptydims dims; + rv = _SysIOCtl( giTerminalFD, PTY_IOCTL_GETDIMS, &dims ); + if( rv ) { + perror("Can't get terminal dimensions (WTF?)"); + exit(-1); + } + giScreenWidth = dims.PW; + giScreenHeight = dims.PH; + _SysDebug("AxWin3 running at %ix%i", dims.PW, dims.PH); giVideo_LastDirtyLine = giScreenHeight; - // Force VT to be shown - _SysIOCtl( giTerminalFD, TERM_IOCTL_FORCESHOW, NULL ); - // Create local framebuffer (back buffer) gpScreenBuffer = malloc( giScreenWidth*giScreenHeight*4 ); // Set cursor position and bitmap - _SysIOCtl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap); + // TODO: This will require using the 2DCMD buffer format + //_SysIOCtl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap); Video_SetCursorPos( giScreenWidth/2, giScreenHeight/2 ); } void Video_Update(void) { + #if 0 int ofs = giVideo_FirstDirtyLine*giScreenWidth; int size = (giVideo_LastDirtyLine-giVideo_FirstDirtyLine)*giScreenWidth; @@ -94,17 +105,39 @@ void Video_Update(void) _SysDebug("Video_Update - Done"); giVideo_FirstDirtyLine = giScreenHeight; giVideo_LastDirtyLine = 0; + #else + size_t size = giScreenHeight * giScreenWidth; + Video_int_SetBufFmt(PTYBUFFMT_FB); + _SysWrite(giTerminalFD, gpScreenBuffer, size*4); + #endif +} + +void Video_int_SetBufFmt(int NewFmt) +{ + static int current_fmt; + + if( current_fmt == NewFmt ) + return ; + + struct ptymode mode = {.InputMode = 0, .OutputMode = NewFmt}; + int rv = _SysIOCtl( giTerminalFD, PTY_IOCTL_SETMODE, &mode ); + if( rv ) { + perror("Can't set PTY to framebuffer mode"); + exit(-1); + } + + current_fmt = NewFmt; } void Video_SetCursorPos(short X, short Y) { - struct { - uint16_t x; - uint16_t y; - } pos; - pos.x = giVideo_CursorX = X; - pos.y = giVideo_CursorY = Y; - _SysIOCtl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos); + struct ptycmd_setcursorpos cmd; + cmd.cmd = PTY2D_CMD_SETCURSORPOS; + cmd.x = giVideo_CursorX = X; + cmd.y = giVideo_CursorY = Y; + + Video_int_SetBufFmt(PTYBUFFMT_2DCMD); + _SysWrite(giTerminalFD, &cmd, sizeof(cmd)); } void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour) diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h index d6136b63..c929e9b5 100644 --- a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h +++ b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h @@ -20,10 +20,16 @@ #define PTYBUFFMT_2DCMD 0x002 #define PTYBUFFMT_3DCMD 0x003 +/* + * Note: When setting dimensions from a client, it is up to the server what fields are used. + * This is usually dependent on the current output mode. + */ struct ptydims { short W; short H; + short PW; + short PH; }; struct ptymode { diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty_cmds.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty_cmds.h index 942a9bad..4b28190a 100644 --- a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty_cmds.h +++ b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty_cmds.h @@ -8,6 +8,8 @@ #ifndef _ACESS_DEVICES_PTY_CMDS_H_ #define _ACESS_DEVICES_PTY_CMDS_H_ +#include + enum { PTY2D_CMD_NOP, @@ -18,7 +20,14 @@ enum PTY2D_CMD_BLIT, PTY2D_CMD_SEND, PTY2D_CMD_RECV, -} +}; + +struct ptycmd_setcursorpos +{ + uint16_t cmd; + uint16_t x; + uint16_t y; +}; #endif -- 2.20.1