X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Frenderers%2Frichtext.c;h=edf3c7dea1ca9c2303471c543e00f19268cc2877;hb=5f8480455a9e2172b15dfc7fb96480a68506c30d;hp=17d55cc0130ae09f155b3dc4a1939bc617fa86d6;hpb=8c20de5e4ec260d9a7ee6d737b7601fba1c871c0;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c index 17d55cc0..edf3c7de 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c @@ -59,6 +59,7 @@ void Renderer_RichText_Destroy(tWindow *Window); void Renderer_RichText_Redraw(tWindow *Window); int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data); int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data); + int Renderer_RichText_HandleIPC_ScrollRange(tWindow *Window, size_t Len, const void *Data); int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === @@ -71,7 +72,8 @@ tWMRenderer gRenderer_RichText = { .nIPCHandlers = N_IPC_RICHTEXT, .IPCHandlers = { [IPC_RICHTEXT_SETATTR] = Renderer_RichText_HandleIPC_SetAttr, - [IPC_RICHTEXT_WRITELINE] = Renderer_RichText_HandleIPC_WriteLine + [IPC_RICHTEXT_WRITELINE] = Renderer_RichText_HandleIPC_WriteLine, + [IPC_RICHTEXT_SCROLLRANGE] = Renderer_RichText_HandleIPC_ScrollRange } }; @@ -321,9 +323,12 @@ void Renderer_RichText_int_UpdateCursorOfs(tRichText_Window *Info) { tRichText_Line *line = Info->CursorLine; size_t ofs = 0; - for( int i = 0; i < Info->CursorCol && ofs < line->ByteLength; i ++ ) + if( line ) { - ofs += ReadUTF8(line->Data + ofs, NULL); + for( int i = 0; i < Info->CursorCol && ofs < line->ByteLength; i ++ ) + { + ofs += ReadUTF8(line->Data + ofs, NULL); + } } Info->CursorBytePos = ofs; } @@ -381,40 +386,42 @@ int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const voi tRichText_Line *prev = NULL; tRichText_Line *line = Renderer_RichText_int_GetLine(Window, msg->Line, &prev); - int reqspace = ((Len - sizeof(*msg)) + LINE_SPACE_UNIT-1) & ~(LINE_SPACE_UNIT-1); + size_t data_bytes = Len - sizeof(*msg); + int reqspace = (data_bytes + LINE_SPACE_UNIT-1) & ~(LINE_SPACE_UNIT-1); + tRichText_Line *new = NULL; if( !line ) { // New line! - tRichText_Line *new = malloc(sizeof(*line) + reqspace); - // TODO: Bookkeeping on how much memory each window uses + new = malloc(sizeof(*line) + reqspace); new->Next = (prev ? prev->Next : NULL); new->Prev = prev; new->Num = msg->Line; - new->Space = reqspace; - *(prev ? &prev->Next : &info->FirstLine) = new; - if(new->Next) new->Next->Prev = new; - line = new; } else if( line->Space < reqspace ) { // Need to allocate more space - tRichText_Line *new = realloc(line, sizeof(*line) + reqspace); + new = realloc(line, sizeof(*line) + reqspace); + } + else + { + // It fits :) + } + if( new ) + { // TODO: Bookkeeping on how much memory each window uses new->Space = reqspace; - if(new->Prev) new->Prev->Next = new; else info->FirstLine = new; if(new->Next) new->Next->Prev = new; line = new; } - else - { - // It fits :) - } - line->ByteLength = Len - sizeof(*msg) - 1; - memcpy(line->Data, msg->LineData, Len - sizeof(*msg)); + line->ByteLength = data_bytes - 1; + memcpy(line->Data, msg->LineData, data_bytes); line->bIsClean = 0; + _SysDebug("RichText: %p - Write %i %i'%.*s'", Window, line->Num, line->ByteLength, + line->ByteLength, line->Data); + if( line->Num == info->CursorRow ) { info->CursorLine = line; info->CursorBytePos = MIN(info->CursorBytePos, line->ByteLength); @@ -425,6 +432,74 @@ int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const voi return 0; } +int Renderer_RichText_HandleIPC_ScrollRange(tWindow *Window, size_t Len, const void *Data) +{ + tRichText_Window *info = Window->RendererInfo; + const struct sRichTextIPC_ScrollRange *msg = Data; + if( Len < sizeof(*msg) ) return -1; + + if( msg->First >= info->nLines ) + return 1; // Bad start + if( msg->Count > info->nLines - msg->First ) + return 1; // Bad count + if( msg->Count == 0 ) { + // No-op + return 0; + } + + // Find the range start + tRichText_Line *line = info->FirstLine; + tRichText_Line *prev = NULL; + while( line && line->Num < msg->First ) { + prev = line; + line = line->Next; + } + if( !line ) { + _SysDebug("RichText ScrollRange: Search for %i ran off end, nlines=%i", + msg->First, info->nLines); + } + + if( msg->Count < 0 ) + { + _SysDebug("TODO: RichText ScrollRange -ve"); + } + else + { + if( msg->First <= info->FirstVisRow && info->FirstVisRow < msg->First+msg->Range ) + info->FirstVisLine = NULL; + + // Remove 'msg->Count' lines from beginning of the range, ... + while( line && line->Num < msg->First + msg->Count ) + { + tRichText_Line *next = line->Next; + _SysDebug("- RichText ScrollRange: Remove %i '%.*s'", + line->Num, line->ByteLength, line->Data); + free(line); + line = next; + } + // Fix up list + if( prev ) + prev->Next = line; + else + info->FirstLine = line; + if(line) + line->Prev = prev; + // ... and shift ->Num down for the rest + for( ; line && line->Num < msg->First + msg->Range; line = line->Next ) + { + line->Num -= msg->Count; + if( line->Num >= info->FirstVisRow && !info->FirstVisLine ) + info->FirstVisLine = line; + } + + info->nLines -= msg->Count; + } + + info->bNeedsFullRedraw = 1; + + return 0; +} + void Renderer_RichText_HandleKeyFire(tWindow *Window, tRichText_Window *Info, const struct sWndMsg_KeyAction *Msg) { tRichText_Line *line = Info->CursorLine;