+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;
+}
+