X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Fvideo.c;h=2f6fff8345c28e08cd062bee089cafabb9292c82;hb=4239ff15de51d3eb299bbebf4f63077edcc0d2db;hp=a30dd3770e3147faa73801a8ef1e627c21f6f15e;hpb=bf0187772ecfb475eedf5e0e9b8460b4f1a3f445;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index a30dd377..2f6fff83 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -7,19 +7,22 @@ */ #include #include -#include +#include +#include #include #include "resources/cursor.h" #include #include #include #include +#include "include/lowlevel.h" // === IMPORTS === 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 +37,7 @@ uint32_t *gpScreenBuffer; // === CODE === void Video_Setup(void) { - int tmpInt; + int rv; // Open terminal #if 0 @@ -47,40 +50,64 @@ 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; + if( giScreenWidth < 640 || giScreenHeight < 480 ) { + Video_int_SetBufFmt(PTYBUFFMT_TEXT); + _SysDebug("Resoltion too small, 640x480 reqd but %ix%i avail", + giScreenWidth, giScreenHeight); + exit(-1); + } + _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 ); + //gpScreenBuffer = _SysMemMap( giTerminalFD, 0, giScreenWidth*giScreenHeight*4, NULL); // Set cursor position and bitmap - _SysIOCtl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap); + { + Video_int_SetBufFmt(PTYBUFFMT_2DCMD); + struct ptycmd_header hdr = {PTY2D_CMD_SETCURSORBMP,0,0}; + size_t size = sizeof(hdr) + sizeof(cCursorBitmap) + cCursorBitmap.W*cCursorBitmap.H*4; + hdr.len_low = size / 4; + hdr.len_hi = size / (256*4); + _SysWrite(giTerminalFD, &hdr, sizeof(hdr)); + _SysDebug("size = %i (%04x:%02x * 4)", size, hdr.len_hi, hdr.len_low); + _SysWrite(giTerminalFD, &cCursorBitmap, size-sizeof(hdr)); + } Video_SetCursorPos( giScreenWidth/2, giScreenHeight/2 ); } void Video_Update(void) { + #if 0 int ofs = giVideo_FirstDirtyLine*giScreenWidth; int size = (giVideo_LastDirtyLine-giVideo_FirstDirtyLine)*giScreenWidth; @@ -92,36 +119,58 @@ void Video_Update(void) _SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4); _SysWrite(giTerminalFD, gpScreenBuffer+ofs, size*4); _SysDebug("Video_Update - Done"); - giVideo_FirstDirtyLine = 0; + 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.hdr.cmd = PTY2D_CMD_SETCURSORPOS; + cmd.hdr.len_low = sizeof(cmd)/4; + cmd.hdr.len_hi = 0; + 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) { - uint32_t *dest; - int i; - if(X < 0 || Y < 0) return; + if(W < 0 || H < 0) return; if(W >= giScreenWidth) return; if(H >= giScreenHeight) return; if(X + W >= giScreenWidth) W = giScreenWidth - W; if(Y + H >= giScreenHeight) W = giScreenHeight - H; - dest = gpScreenBuffer + Y * giScreenWidth + X; + uint32_t *dest = gpScreenBuffer + Y * giScreenWidth + X; while(H --) { - for( i = W; i --; dest ++ ) *dest = Colour; + for( int i = W; i --; dest ++ ) *dest = Colour; dest += giScreenWidth - W; } } @@ -159,10 +208,8 @@ void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H) if( W <= 0 || H <= 0 ) return; - if( DstY < giVideo_FirstDirtyLine ) - giVideo_FirstDirtyLine = DstY; - if( DstY + H > giVideo_LastDirtyLine ) - giVideo_LastDirtyLine = DstY + H; + giVideo_FirstDirtyLine = MIN(DstY, giVideo_FirstDirtyLine); + giVideo_LastDirtyLine = MAX(DstY+H, giVideo_LastDirtyLine); buf = gpScreenBuffer + DstY*giScreenWidth + DstX; if(drawW != giScreenWidth || W != giScreenWidth)