U8 ltf_display_types[1],ltf_nondisplay_invisible_types[1], ltf_form_types[1],ltf_data_types[1]; ltf_display_types[0]=1<bin_root.next; while (b!=&l->bin_root) { if (b->num==num) return b; b=b->next; } return NULL; } void LtfValidateBins(Ltf *l) { LtfBinEntry *b=l->bin_root.next,*b1; LtfEntry *cl=l->dummy.next; while (b!=&l->bin_root) { b->use_cnt=0; b=b->next; } while (cl!=l) { if (cl->flags & LTFLF_HAS_BIN) { if (cl->bin_data) cl->bin_data->use_cnt++; else { cl->bin_data=LtfFindBin(l,cl->bin_num); if (cl->bin_data) cl->bin_data->use_cnt++; } } cl=cl->next; } b=l->bin_root.next; l->cur_bin_num=1; while (b!=&l->bin_root) { b1=b->next; if (!b->use_cnt) { RemQue(b); Free(b->data,l->mem_tss); Free(b,l->mem_tss); } else { if (b->num>=l->cur_bin_num) l->cur_bin_num=b->num+1; } b=b1; } } void LtfDelBin(LtfBinEntry *b,TssStruct *tss) { b->use_cnt--; if (!b->use_cnt) { RemQue(b); Free(b->data,tss); Free(b,tss); } } void LtfDelEntry(LtfEntry *cl,TssStruct *tss) { if (Bt(ltf_display_types,cl->btype)) Free(cl->display,tss); if (cl->btype>=LTFT_DATA) Free(cl->plain_text,tss); if (cl->flags & LTFLF_LEFT_MACRO) Free(cl->left_macro,tss); if (cl->flags & LTFLF_RIGHT_MACRO) Free(cl->right_macro,tss); if (cl->flags & LTFLF_AUX_STRING) Free(cl->aux_string,tss); if (cl->flags & LTFLF_HAS_BIN) LtfDelBin(cl->bin_data,tss); Free(cl,tss); } LtfEntry *LtfCopyEntry(Ltf *l,LtfEntry *cl) { LtfEntry *nl; LtfBinEntry *tempb; TssStruct *tss=l->mem_tss; nl=MAllocIdentical(cl,tss); if (Bt(ltf_display_types,cl->btype)) nl->display=MAllocIdentical(cl->display,tss); if (cl->btype>=LTFT_DATA) nl->plain_text=NewString(cl->plain_text,tss); if (cl->flags & LTFLF_AUX_STRING) nl->aux_string=NewString(cl->aux_string,tss); if (cl->flags & LTFLF_LEFT_MACRO) nl->left_macro=MAllocIdentical(cl->left_macro,tss); if (cl->flags & LTFLF_RIGHT_MACRO) nl->right_macro=MAllocIdentical(cl->right_macro,tss); if (cl->flags & LTFLF_HAS_BIN) { tempb=MAllocIdentical(cl->bin_data,tss); tempb->data=MAllocIdentical(cl->bin_data->data,tss); nl->bin_num=l->cur_bin_num; tempb->num=l->cur_bin_num++; nl->bin_data=tempb; InsQue(tempb,l->bin_root.last); } return nl; } void LtfFormForward(Ltf *l) { LtfEntry *cl=l->cur_entry,*cl1=cl->last; if (l->flags & LTFF_FORM) { while (cl!=cl1 && !Bt(ltf_form_types,cl->btype)) { cl=cl->next; } l->cur_data_col=cl->min_col; l->cur_entry=cl; } } void LtfFormBackward(Ltf *l) { LtfEntry *cl=l->cur_entry,*cl1=cl->next; if (l->flags & LTFF_FORM) { while (cl!=cl1 && !Bt(ltf_form_types,cl->btype)) { cl=cl->last; } l->cur_data_col=cl->min_col; l->cur_entry=cl; } } public void LtfHome(Ltf *l) { if (!l) return; l->cur_entry=l->dummy.next; l->cur_data_col=l->cur_entry->min_col; l->x=0; l->y=0; l->line_start_col=0; l->cur_top_line_num=0; LtfFormForward(l); } public void LtfReset(Ltf *l,BoolU4 is_old,BoolU4 adam_mem=FALSE) { LtfEntry *cl,*cl1; if (!l) return; if (is_old) { cl=l->dummy.next; while (cl!=l) { cl1=cl->next; if (adam_mem) LtfDelEntry(cl,adam_tss); else LtfDelEntry(cl,l->mem_tss); cl=cl1; } } //Check $LK,"EditInsertLtf","MN:EditInsertLtf"$ l->text_attribute=(WHITE<<4)+BLUE; l->link_attribute=(WHITE<<4)+RED; l->macro_attribute=(WHITE<<4)+LTBLUE; l->anchor_attribute=(WHITE<<4)+BLACK; l->hidden_attribute=(WHITE<<4)+BLACK; l->tree_attribute=(WHITE<<4)+PURPLE; l->user_attribute=(WHITE<<4)+GREEN; l->flags=0; l->dummy.next=l; l->dummy.last=l; l->bin_root.next=&l->bin_root; l->bin_root.last=&l->bin_root; l->cur_bin_num=1; l->recalc_start=l; l->menu_ltf=NULL; l->dollar_buf_ptr=0; l->cmd_I1=CH_SPACE; l->indent=0; l->page_line_num=0; l->page_length=66; l->left_margin=LTF_DEFAULT; l->right_margin=LTF_DEFAULT; l->header=LTF_DEFAULT; l->footer=LTF_DEFAULT; cl=&l->dummy; cl->type=LTFT_ERROR; cl->flags=0; cl->x=0; cl->y=0; cl->min_col=0; cl->max_col=0; cl->indent=l->indent; cl->page_line_num=l->page_line_num; cl->left_margin=l->left_margin; cl->right_margin=l->right_margin; LtfHome(l); } public void LtfDel(Ltf *l,BoolU4 adam_mem=FALSE) { Ltf *m; if (!l) return; m=l->menu_ltf; LtfReset(l,TRUE,adam_mem); Free(l->find_replace,l->mem_tss); Free(l->dollar_buf,l->mem_tss); LtfDel(m,adam_mem); Free(l,l->mem_tss); } void LtfFormatData(LtfEntry *cl) { BoolU4 *b; U8 *d; I8 i; if (cl->btype==LTFT_DATA) { d=cl->data; if (cl->flags & LTFLF_DATA_IS_PTR) SPrintF(cl->display,cl->aux_string,*d,cl->my_format_data); else SPrintF(cl->display,cl->aux_string,d,cl->my_format_data); if (cl->flags & LTFLF_HAS_TERMINATOR) { i=StrLen(cl->display); cl->display[i++]='_'; cl->display[i]=0; } } else if (cl->btype==LTFT_CHECK_BOX) { if (cl->flags & LTFLF_DATA_IS_PTR) b=cl->data; else b=&cl->data; if (*b) cl->flags|=LTFLF_CHECKED; else cl->flags&=~LTFLF_CHECKED; } } void LtfGetData(LtfEntry *cl) { BoolU4 *b; I8 i; if (cl->btype==LTFT_DATA) { i=StrLen(cl->display); if (cl->flags & LTFLF_HAS_TERMINATOR) cl->display[--i]=0; if (i>cl->len+cl->min_col) cl->display[cl->len+cl->min_col]=0; if (cl->flags & LTFLF_DATA_IS_PTR) GetF(cl->display,cl->aux_string,cl->data,cl->my_format_data); else GetF(cl->display,cl->aux_string,&cl->data,cl->my_format_data); if (cl->flags & LTFLF_HAS_TERMINATOR) cl->display[i]='_'; } else if (cl->btype==LTFT_CHECK_BOX) { if (cl->flags & LTFLF_DATA_IS_PTR) b=cl->data; else b=&cl->data; if (cl->flags & LTFLF_CHECKED) *b=TRUE; else *b=FALSE; } } I8 LtfCharDist(Ltf *l,I8 x,I8 y) { I8 dx=(l->x-x)*FONT_WIDTH>>2,dy=(l->y-y)*FONT_HEIGHT; return MulI8(dx,dx)+MulI8(dy,dy); } public void LtfUpdateWindowJoin(Ltf *l,BoolU4 to_screen,BoolU4 has_cursor, BoolU4 recalc,BoolU4 find_cur_entry, LtfEntry *pg_found=NULL,I8 num_del_entries=0) { I8 i,ii,j,k,x,x0,y,y0,D,d2,col,col2,best_col=0,best_d=MAX_I8; I8 num_entries=0,cursor_y=MIN_I8; LtfEntry *cl,*cl2,*best_cl=l->cur_entry,*alias,*next_pg_found=NULL; I8 ijif; U8 w,w1; U1 *bptr; U1 ch,*ptr,buf[16]; BoolU4 del_cl,skipped_update,tree_collapsed; U8 hide_collapsed[2]; TssStruct *tss=l->tss,*mem_tss=l->mem_tss; BoolU4 resize=FALSE; BoolU4 extra_processing,same_window; BoolU4 revert_default_color_eol=FALSE; GrBitMap *base=GrNew(grbase2); I8 left_margin=tss->window_left,right_margin=tss->window_right; if (!l) return; if (to_screen || find_cur_entry) { recalc=TRUE; l->recalc_start=l; } if (has_cursor) { if (Btr(&tss->crt_flags,CRTf_HAS_BEEN_RESIZED)) resize=TRUE; if (Btr(&tss->crt_flags,CRTf_SCROLL_X)) l->line_start_col=(DivI8(MulI8(tss->scroll_x,l->max_x-l->min_x+1), right_margin-left_margin+4)+l->min_x) & -4; if (Btr(&tss->crt_flags,CRTf_SCROLL_Y)) l->cur_top_line_num=DivI8(MulI8(tss->scroll_y,l->max_y-l->min_y+1), tss->window_bottom-tss->window_top+1)+l->min_y; } x=0; y=0; l->indent=0; l->page_line_num=0; l->left_margin=LTF_DEFAULT; l->right_margin=LTF_DEFAULT; l->header=LTF_DEFAULT; l->footer=LTF_DEFAULT; same_window=tss->window_top==l->old_window_top && tss->window_bottom==l->old_window_bottom && tss->window_left==l->old_window_left && tss->window_right==l->old_window_right; w=l->text_attribute<<8; if (!find_cur_entry) { l->x=0; l->y=0; } l->flags&=~(LTFF_WORD_WRAP|LTFF_UNDERLINED|LTFF_INVERTED|LTFF_BLINK); l->shifted_x=0; l->shifted_y=0; if (recalc) { if (l->cur_data_col<=l->cur_entry->min_col) l->cur_data_col=l->cur_entry->min_col; if (!l->recalc_start) cl=l; //skip update else { cl=l->recalc_start; if (cl!=l) { i=l->ww_lines_back; ii=i/2; //Threshold for stopping on SOFT_CR while (i-- && cl->btype!=LTFT_CR && (i>ii || cl->btype!=LTFT_SOFT_CR) && cl->flags & LTFLF_WORD_WRAP && cl->last!=l) cl=cl->last; if (cl->flags & LTFLF_WORD_WRAP) l->flags|=LTFF_WORD_WRAP; else l->flags&=~LTFF_WORD_WRAP; if (cl->flags & LTFLF_UNDERLINED) { l->flags|=LTFF_UNDERLINED; w|=LTFLT_UNDERLINED; } else l->flags&=~LTFF_UNDERLINED; if (cl->flags & LTFLF_INVERTED) { l->flags|=LTFF_INVERTED; w|=LTFLT_INVERTED; } else l->flags&=~LTFF_INVERTED; if (cl->flags & LTFLF_BLINK) { l->flags|=LTFF_BLINK; w|=LTFLT_BLINK; } else l->flags&=~LTFF_BLINK; w|=(cl->type & 0x0C00FF00); x=cl->x; y=cl->y; l->indent=cl->indent; l->page_line_num=cl->page_line_num; l->left_margin=cl->left_margin; l->right_margin=cl->right_margin; } else cl=l->dummy.next; } } else cl=l->dummy.next; x0=l->line_start_col; y0=l->cur_top_line_num; if (l->dummy.next==l) { best_cl=l; best_col=0; l->cur_entry=l; l->cur_data_col=0; cl=l; } skipped_update=(cl==l && l->dummy.next!=l); extra_processing=recalc||find_cur_entry||resize; l->min_x=0x7FFFFFFC; l->min_y=MAX_I4; l->max_x=-0x7FFFFFFF; l->max_y=MIN_I4; while (cl!=l) { del_cl=FALSE; if (cl->flags & LTFLF_SKIP) { cl=cl->last; //for consistency handle skips the same goto skip; } if (cl->flags & LTFLF_DISPLAY_CB) { if (recalc || cl->flags & LTFLF_REFRESH_DATA) { Free(cl->display,mem_tss); cl->display=cl->display_cb(l,l->user_data,cl,mem_tss); cl->max_col=StrLen(cl->display); if (l->cur_entry==cl) { if (l->cur_data_col>=cl->max_col && cl->max_col) l->cur_data_col=cl->max_col-1; } } } if (extra_processing) { word_wrap_start: cl2=cl->next; if (cl2->btype==LTFT_SOFT_CR) { if (!same_window) { if (l->cur_entry==cl2) { l->cur_entry=cl2->next; l->cur_data_col=l->cur_entry->min_col; } if (best_cl==cl2) { best_cl=cl2->next; best_col=0; } RemQue(cl2); LtfDelEntry(cl2,mem_tss); goto word_wrap_start; } } if (cl->btype==LTFT_TEXT) { if (cl->flags==cl2->flags && cl->type==cl2->type) { i=StrLen(cl->display); j=StrLen(cl2->display); ptr=MAlloc(i+j+1,mem_tss); MemCpy(ptr,cl->display,i); MemCpy(ptr+i,cl2->display,j+1); Free(cl->display,mem_tss); cl->display=ptr; if (l->cur_entry==cl2) { l->cur_entry=cl; l->cur_data_col+=i; } if (best_cl==cl2) { best_cl=cl; best_col=0; } RemQue(cl2); LtfDelEntry(cl2,mem_tss); goto word_wrap_start; } } } if (cl->flags & LTFLF_SCROLLING_X) k=cl->scroll_len; else if (Bt(ltf_display_types,cl->btype)) k=StrLen(cl->display); else k=0; if (cl->flags & (LTFLF_LEFT_X|LTFLF_RIGHT_X|LTFLF_CENTER_X| LTFLF_TOP_Y|LTFLF_BOTTOM_Y|LTFLF_CENTER_Y)) { if (cl->flags & LTFLF_MARGIN_REL_X) { if (cl->flags & LTFLF_LEFT_X) x=left_margin-tss->window_left; else if (cl->flags & LTFLF_RIGHT_X) x=right_margin-(k-1)<<2-tss->window_left; else if (cl->flags & LTFLF_CENTER_X) x=((right_margin+left_margin)>>1-k>>1-tss->window_left) & -4; } else { if (cl->flags & LTFLF_LEFT_X) x=x0; else if (cl->flags & LTFLF_RIGHT_X) x=tss->window_right-tss->window_left+x0-(k-1)<<2; else if (cl->flags & LTFLF_CENTER_X) x=((tss->window_right-tss->window_left+x0)>>1-k<<1) & -4; } if (cl->flags & LTFLF_PAGE_REL_Y) { if (cl->flags & LTFLF_TOP_Y) y-=cl->page_line_num; else if (cl->flags & LTFLF_BOTTOM_Y) y+=l->page_length-cl->page_line_num; else if (cl->flags & LTFLF_CENTER_Y) y+=l->page_length>>1-cl->page_line_num; } else { if (cl->flags & LTFLF_TOP_Y) y=y0; else if (cl->flags & LTFLF_BOTTOM_Y) y=tss->window_bottom-tss->window_top+y0; else if (cl->flags & LTFLF_CENTER_Y) y=(tss->window_bottom-tss->window_top)>>1+y0; } } if (extra_processing && k>0) { if (l->flags & LTFF_WORD_WRAP) { i=(right_margin+4-(x+tss->window_left))>>2; //Space left ON line ii=(x+4-l->left_margin)>>2; if (cl->btype==LTFT_TEXT) { /* if (l->cur_entry==cl->next && l->cur_data_col==0 && k==i) i--; if (l->cur_entry==cl) { if (l->cur_data_col==i || (l->cur_data_col==i+1 && (cl->display[i]==CH_SPACE ||cl->display[i]==CH_SHIFT_SPACE))) i--; } */ if (k>i) { for (j=i;j>8-ii && j>=0;j--) if (cl->display[j]==CH_SPACE || cl->display==CH_SHIFT_SPACE) { i=j+1; break; } if (k>i && i>0) { cl2=MAllocIdentical(cl,mem_tss); cl2->display=NewString(cl->display+i,mem_tss); InsQue(cl2,cl); if (l->cur_entry==cl && l->cur_data_col>=i) { l->cur_entry=cl2; l->cur_data_col=l->cur_data_col-i; } cl->display[i]=0; ptr=NewString(cl->display,mem_tss); Free(cl->display,mem_tss); cl->display=ptr; cl2=MAllocZ(sizeof(LtfEntryBase),mem_tss); cl2->type=LTFT_SOFT_CR | cl->type & 0xFFFFFF00; cl2->flags=cl->flags; cl2->x=x; cl2->y=y; cl2->indent=l->indent; cl2->page_line_num=l->page_line_num; cl2->left_margin=l->left_margin; cl2->right_margin=l->right_margin; InsQue(cl2,cl); goto skip_soft_cr; } } if (k==i) goto skip_soft_cr; } if (k>=i && cl->btype!=LTFT_SOFT_CR && cl->btype!=LTFT_CR && cl->btype!=LTFT_CURSOR_MOVEMENT) { if (cl->last->btype!=LTFT_SOFT_CR && cl->last->btype!=LTFT_CR && cl->last->btype!=LTFT_CURSOR_MOVEMENT) { cl2=MAllocZ(sizeof(LtfEntryBase),mem_tss); cl2->type=LTFT_SOFT_CR | cl->type & 0xFFFFFF00; cl2->flags=LTFLF_WORD_WRAP | cl->flags & (LTFLF_INVERTED|LTFLF_UNDERLINED| LTFLF_BLINK|LTFLF_SKIP); cl2->x=x; cl2->y=y; cl2->indent=l->indent; cl2->page_line_num=l->page_line_num; cl2->left_margin=l->left_margin; cl2->right_margin=l->right_margin; InsQue(cl2,cl->last); if (l->left_margin==LTF_DEFAULT) x=l->indent; else x=l->left_margin+l->indent; y++; } } skip_soft_cr: } } if (cl==l->cur_entry) cursor_y=y; cl->x=x; cl->y=y; cl->indent=l->indent; cl->page_line_num=l->page_line_num; cl->left_margin=l->left_margin; cl->right_margin=l->right_margin; cl->type=w & 0xFF00 | cl->type & 0xFFFF00FF; if (l->flags & LTFF_WORD_WRAP) cl->flags|=LTFLF_WORD_WRAP; else cl->flags&=~LTFLF_WORD_WRAP; if (l->flags & LTFF_UNDERLINED) { cl->flags|=LTFLF_UNDERLINED; w|=LTFLT_UNDERLINED; } else { cl->flags&=~LTFLF_UNDERLINED; w&=~LTFLT_UNDERLINED; } if (l->flags & LTFF_INVERTED) { cl->flags|=LTFLF_INVERTED; w|=LTFLT_INVERTED; } else { cl->flags&=~LTFLF_INVERTED; w&=~LTFLT_INVERTED; } if (l->flags & LTFF_BLINK) { cl->flags|=LTFLF_BLINK; w|=LTFLT_BLINK; } else { cl->flags&=~LTFLF_BLINK; w&=~LTFLT_BLINK; } if (xmin_x) l->min_x=x; if (ymin_y) l->min_y=y; if (find_cur_entry) { D=LtfCharDist(l,x,y); col=0; } col2=0; w=w&0xFC00FF00|(l->shifted_x & 0x1F)<<16|(l->shifted_y & 0x1F)<<21; switch (cl->btype) { case LTFT_LINK: w1=w & 0xFFFF0000 | l->link_attribute<<8; break; case LTFT_MACRO: case LTFT_MENU_VALUE: w1=w & 0xFFFF0000 | l->macro_attribute<<8; break; case LTFT_ANCHOR: w1=w & 0xFFFF0000 | l->anchor_attribute<<8; break; case LTFT_TREE: w1=w & 0xFFFF0000 | l->tree_attribute<<8; break; case LTFT_HIDE_START: case LTFT_HIDE_END: w1=w & 0xFFFF0000 | l->hidden_attribute<<8; break; default: w1=w; } w1=w1 & 0xFFFFFF00 | cl->type & 0xF3FF0000; if (cl==l->cur_entry && cl->btype!=LTFT_TEXT) w1^=0xFF00; if (cl->flags & LTFLF_REFRESH_DATA) { if (cl->btype==LTFT_DATA || cl->btype==LTFT_CHECK_BOX) { LtfFormatData(cl); if (cl->btype==LTFT_DATA) cl->max_col=StrLen(cl->display); } } ptr=cl->display; if (cl->flags & LTFLF_TREE) { if (StrLen(ptr)>=2) { if (cl->flags & LTFLF_COLLAPSED) *ptr++='+'; else *ptr++='-'; *ptr++=']'; } } if (cl->btype==LTFT_CHECK_BOX) { if (StrLen(ptr)>=3) { *ptr++='['; if (cl->flags & LTFLF_CHECKED) *ptr++='X'; else *ptr++=' '; *ptr++=']'; } } else if (cl->btype==LTFT_HIDE_START) { if (StrLen(ptr)>=2) { *ptr++='<'; if (cl->flags & LTFLF_COLLAPSED) *ptr++='+'; else *ptr++='-'; } } else if (cl->btype==LTFT_HIDE_END) { if (StrLen(ptr)>=1) *ptr++='>'; } if (Bt(ltf_display_types,cl->btype)) { if (cl->flags & LTFLF_SCROLLING_X) { j=StrLen(cl->display); if (j && cl->scroll_len) { ijif=DivU8(MulU8(jiffies,MulU8(FONT_WIDTH,tss->scroll_speed)),JIFFY_FREQ); ijif=ModU8(ijif,j*FONT_WIDTH); w1=w1 & 0xFFE0FF00| ((FONT_WIDTH-1-ModU8(ijif,FONT_WIDTH))<<16); ijif=DivU8(ijif,FONT_WIDTH); ptr=cl->display; for (k=0;kscroll_len;k++) { ch=ptr[ModU8(ijif+k,j)]; if (!Bt(displayable_chars_bitmap,ch)) ch='.'; if (to_screen) { if (cl->flags & LTFLF_BORDER_PLOT) PlotBorderChar(w1+ch,x-x0,y-y0); else PlotWindowChar(w1+ch,x-x0,y-y0); } x+=4; } } if (find_cur_entry) { D=LtfCharDist(l,cl->x,cl->y); col=cl->min_col; } col2=cl->scroll_len; //TODO This is flawed } else { ptr=cl->display; if (cl->flags & LTFLF_PASSWORD) { while (ch=*ptr++) { if (ch!=CH_TAB) { if (ptr-1-cl->display>=cl->min_col) { if (!(cl->flags & LTFLF_HAS_TERMINATOR) || ptr-cl->display!=StrLen(cl->display)) ch='*'; } if (to_screen) { if (cl->flags & LTFLF_BORDER_PLOT) PlotBorderChar(w1+ch,x-x0,y-y0); else PlotWindowChar(w1+ch,x-x0,y-y0); } if (find_cur_entry) { d2=LtfCharDist(l,x,y); if (d2flags & LTFLF_BORDER_PLOT) PlotBorderChar(w1+CH_SPACE,x-x0,y-y0); else PlotWindowChar(w1+CH_SPACE,x-x0,y-y0); } if (find_cur_entry) { d2=LtfCharDist(l,x,y); if (d2flags & LTFLF_BORDER_PLOT) { while (ch=*ptr++) { if (ch!=CH_TAB) { if (to_screen) PlotBorderChar(w1+ch,x-x0,y-y0); if (find_cur_entry) { d2=LtfCharDist(l,x,y); if (d2btype) { case LTFT_TEXT: if (!col2) { if (!(cl->flags & LTFLF_TREE) && recalc) del_cl=TRUE; } break; case LTFT_HEX_EDIT: if (cl->flags & LTFLF_DATA_IS_PTR) bptr=cl->data; else bptr=&cl->data; k=cl->display; //columns for (i=0;ilen;i=i+k) { if (cl->flags & LTFLF_ZERO_BASED) SPrintF(buf,"%08X ",i); else SPrintF(buf,"%08X ",bptr); ptr=buf; while (ch=*ptr++) { if (to_screen) { if (cl->flags & LTFLF_BORDER_PLOT) PlotBorderChar(w1+ch,x-x0,y-y0); else PlotWindowChar(w1+ch,x-x0,y-y0); } if (find_cur_entry) { d2=LtfCharDist(l,x,y); if (d2cl->len) k=cl->len-i; for (j=0;jflags & LTFLF_BORDER_PLOT) PlotBorderChar(w1+ch,x-x0,y-y0); else PlotWindowChar(w1+ch,x-x0,y-y0); } if (find_cur_entry) { d2=LtfCharDist(l,x,y); if (d2display-k)*12; for (j=0;jflags & LTFLF_BORDER_PLOT) PlotBorderChar(w1+ch,x-x0,y-y0); else PlotWindowChar(w1+ch,x-x0,y-y0); } if (find_cur_entry) { d2=LtfCharDist(l,x,y); if (d2display*12+k<<2+36; } break; case LTFT_TAB: i=(x+32) & -0x20; if (cl->flags & LTFLF_BORDER_PLOT) { while (xtext_attribute<<8 & 0xF00; } if (l->left_margin==LTF_DEFAULT) x=l->indent; else x=l->indent+l->left_margin; y++; l->page_line_num++; if (l->footer==LTF_DEFAULT) { if (l->page_line_num>=l->page_length) { if (l->header==LTF_DEFAULT) l->page_line_num=0; else { l->page_line_num=l->header; y+=l->header; } } } else { if (l->page_line_num>=l->page_length-l->footer) { y+=l->footer; if (l->header==LTF_DEFAULT) l->page_line_num=0; else { l->page_line_num=l->header; y+=l->header; } } } break; case LTFT_CURSOR_MOVEMENT: x+=cl->cursor_x_offset<<2; y+=cl->cursor_y_offset; if (cl->flags & LTFLF_PAGE_REL_Y) { if (cl->flags & LTFLF_TOP_Y) l->page_line_num=0; else if (cl->flags & LTFLF_BOTTOM_Y) l->page_line_num=l->page_length; else if (cl->flags & LTFLF_CENTER_Y) l->page_line_num=l->page_length>>1; } //TODO: else l->page_line_num=(l->page_line_num+ cl->cursor_y_offset)%l->page_length; break; case LTFT_PAGE_BREAK: x=0; y+=l->page_length-cl->page_line_num; l->page_line_num=0; if (l->header!=LTF_DEFAULT) { y+=l->header; l->page_line_num=l->header; } break; case LTFT_INDENT: if (cl->flags & LTFLF_LEFT_X) l->indent=cl->attr<<2; else l->indent=l->indent+cl->attr<<2; x=l->indent; cl->indent=l->indent; cl->x=0; if (l->left_margin!=LTF_DEFAULT) { x+=l->left_margin; cl->x+=l->left_margin; } break; case LTFT_PAGE_LENGTH: l->page_length=cl->attr; break; case LTFT_LEFT_MARGIN: l->left_margin=cl->attr<<2; cl->left_margin=l->left_margin; left_margin=tss->window_left+l->left_margin; break; case LTFT_RIGHT_MARGIN: l->right_margin=cl->attr<<2; cl->right_margin=l->right_margin; right_margin=tss->window_left+l->right_margin; break; case LTFT_HEADER: l->header=cl->attr; break; case LTFT_FOOTER: l->footer=cl->attr; break; case LTFT_FOREGROUND_COLOR: if (cl->attr==LTF_DEFAULT) w=w & 0xF000 | l->text_attribute<<8 & 0xF00; else w=w & 0xF000 | cl->attr<<8; break; case LTFT_BACKGROUND_COLOR: if (cl->attr==LTF_DEFAULT) w=w & 0xF00 | l->text_attribute<<8 & 0xF000; else w=w & 0xF00 | cl->attr<<12; break; case LTFT_DEFAULT_FOREGROUND_COLOR: if (cl->attr==LTF_DEFAULT) w=w & 0xF000 | l->text_attribute<<8 & 0xF00; else w=w & 0xF000 | cl->attr <<8; l->text_attribute=l->text_attribute & 0xF0 | cl->attr; break; case LTFT_DEFAULT_BACKGROUND_COLOR: if (cl->attr==LTF_DEFAULT) w=w & 0xF00 | l->text_attribute<<8 & 0xF000; else w=w & 0xF00 | cl->attr <<12; l->text_attribute=l->text_attribute & 0xF | cl->attr<<4; break; case LTFT_LINK_FOREGROUND: l->link_attribute=l->link_attribute & 0xF0 | cl->attr; break; case LTFT_LINK_BACKGROUND: l->link_attribute=l->link_attribute & 0xF | cl->attr<<4; break; case LTFT_MACRO_FOREGROUND: l->macro_attribute=l->macro_attribute & 0xF0 | cl->attr; break; case LTFT_MACRO_BACKGROUND: l->macro_attribute=l->macro_attribute & 0xF | cl->attr<<4; break; case LTFT_ANCHOR_FOREGROUND: l->anchor_attribute=l->anchor_attribute & 0xF0 | cl->attr; break; case LTFT_ANCHOR_BACKGROUND: l->anchor_attribute=l->anchor_attribute & 0xF | cl->attr<<4; break; case LTFT_HIDDEN_FOREGROUND: l->hidden_attribute=l->hidden_attribute & 0xF0 | cl->attr; break; case LTFT_HIDDEN_BACKGROUND: l->hidden_attribute=l->hidden_attribute & 0xF | cl->attr<<4; break; case LTFT_TREE_FOREGROUND: l->tree_attribute=l->tree_attribute & 0xF0 | cl->attr; break; case LTFT_TREE_BACKGROUND: l->tree_attribute=l->tree_attribute & 0xF | cl->attr<<4; break; case LTFT_USER_FOREGROUND: if (cl->attr==LTF_DEFAULT) { w=w & 0xF000 | l->user_attribute<<8 & 0xF00; if (y==cursor_y) { l->cur_entry=cl->next; l->cur_data_col=l->cur_entry->min_col; } } else l->user_attribute=l->user_attribute & 0xF0 | cl->attr; break; case LTFT_USER_BACKGROUND: if (cl->attr==LTF_DEFAULT) { w=w & 0xF00 | l->user_attribute<<8 & 0xF000; if (y==cursor_y) { l->cur_entry=cl->next; l->cur_data_col=l->cur_entry->min_col; } } else l->user_attribute=l->user_attribute & 0xF | cl->attr<<4; break; case LTFT_WORD_WRAP: if (cl->attr) l->flags|=LTFF_WORD_WRAP; else l->flags&=~LTFF_WORD_WRAP; break; case LTFT_UNDERLINED: if (cl->attr) l->flags|=LTFF_UNDERLINED; else l->flags&=~LTFF_UNDERLINED; break; case LTFT_INVERTED: if (cl->attr) l->flags|=LTFF_INVERTED; else l->flags&=~LTFF_INVERTED; break; case LTFT_BLINK: if (cl->attr) l->flags|=LTFF_BLINK; else l->flags&=~LTFF_BLINK; break; case LTFT_SHIFTED_X: l->shifted_x=cl->attr; break; case LTFT_SHIFTED_Y: l->shifted_y=cl->attr; break; case LTFT_CURSOR: if (!find_cur_entry && !(l->flags & LTFF_NO_CURSOR)) { l->cur_entry=cl->next; l->cur_data_col=l->cur_entry->min_col; } del_cl=TRUE; break; case LTFT_PICTURE: if (!cl->bin_data) cl->bin_data=LtfFindBin(l,cl->bin_num); if (cl->bin_data) { GrReset(base); base->flags&=~(BMF_DONT_DRAW|BMF_LOCATE_NEAREST|BMF_TRANSFORMATION); if (!to_screen) base->flags|=BMF_DONT_DRAW; i=((w1>>12)&0xF)^0xF; if (w1 & LTFLT_SELECTED) i^=0xF; if (w1 & LTFLT_INVERTED) i^=0xF; base->color^=i; if (find_cur_entry) base->flags|=BMF_LOCATE_NEAREST; base->nearest_sub_GrElem=0; base->nearest_dist=MAX_I8; if (to_screen && (l->cur_GrElem==cl->bin_data->data)) { base->flags|=BMF_LOCATE_NEAREST; base->cur_x=ipx; base->cur_y=ipy; } else { base->cur_x=(l->x-x0)>>2*FONT_WIDTH; base->cur_y=(l->y-y0)*FONT_HEIGHT; } base->cur_z=0; GrElemsPlot(base,(x-x0)>>2*FONT_WIDTH, (y-y0)*FONT_HEIGHT,0,cl->bin_data->data,i); if (to_screen && (l->cur_GrElem==cl->bin_data->data)) l->cur_sub_GrElem=base->nearest_sub_GrElem; base->flags&=~(BMF_LOCATE_NEAREST|BMF_DONT_DRAW); D=base->nearest_dist; col=cl->min_col; } break; case LTFT_BPT: w=w & 0xF000 | RED<<8; revert_default_color_eol=TRUE; break; case LTFT_SONG: if (sys_cur_focus_task==tss && to_screen) { if (StrCmp(cur_song,cl->song)) { AFree(cur_song); ResetMusicSettings; cur_song=ANewString(cl->song); } } Bts(&tss->task_flags,TSSf_HAS_SONG); break; case LTFT_CLEAR: if (recalc && pg_found==cl) { del_cl=TRUE; pg_found=FALSE; } else next_pg_found=cl; break; } if (cl->flags & LTFLF_HAS_BORDER) { if (cl->flags & LTFLF_SOLID_BORDER) DrawBorder(1,cl->x-x0,x-x0-4,cl->y-y0,y-y0,w1.u1[1],TRUE); else DrawBorder(0,cl->x-x0,x-x0-4,cl->y-y0,y-y0,w1.u1[1],TRUE); } switch (cl->btype) { case LTFT_CHECK_BOX: case LTFT_HIDE_START: cl->max_col=2; break; case LTFT_TREE: case LTFT_BUTTON: case LTFT_LINK: case LTFT_MENU_VALUE: case LTFT_MACRO: case LTFT_HIDE_END: cl->max_col=1; break; default: cl->max_col=(cl->flags & LTFLF_TREE) ? 1:col2; } if (x>l->max_x) l->max_x=x; if (y>l->max_y) l->max_y=y; if (Dflags & LTFLF_TREE) { if (cl->flags & LTFLF_ALIAS) alias=cl; else alias=NULL; if (cl->flags & LTFLF_COLLAPSED) tree_collapsed=TRUE; else tree_collapsed=FALSE; cl2=cl->next; while (cl2!=l && cl2->btype!=LTFT_INDENT && !(cl2->flags & LTFLF_TREE)) cl2=cl2->next; if (cl2->btype==LTFT_INDENT) { i=l->indent; j=i; do { if (tree_collapsed) cl2->flags|=LTFLF_SKIP; else cl2->flags&=~LTFLF_SKIP; if (alias && cl2==l->cur_entry && Bt(ltf_display_types,cl2->btype)) { Free(alias->display,mem_tss); alias->display=MAlloc(StrLen(cl2->display)+4,mem_tss); alias->display[0]='+'; alias->display[1]=']'; alias->display[2]=CH_SPACE; StrCpy(alias->display+3,cl2->display); alias->max_col=cl2->max_col+3; } if (cl2->btype==LTFT_INDENT) { if (cl2->flags & LTFLF_LEFT_X) j=cl2->attr; else j+=cl2->attr; } cl2=cl2->next; } while (cl2!=l && j>i); } } if (cl->btype == LTFT_HIDE_START) { if (cl->flags & LTFLF_ALIAS) alias=cl; else alias=NULL; cl2=cl->next; Btr(hide_collapsed,0); j=1; AssignBit(hide_collapsed,j,cl->flags & LTFLF_COLLAPSED); while (cl2!=l && j>0) { if (Bt(hide_collapsed,j)) cl2->flags|=LTFLF_SKIP; else cl2->flags&=~LTFLF_SKIP; if (cl2->btype==LTFT_HIDE_START) { j++; AssignBit(hide_collapsed,j,cl2->flags & LTFLF_COLLAPSED); if (Bt(hide_collapsed,j-1)) Bts(hide_collapsed,j); } else if (cl2->btype==LTFT_HIDE_END) { j--; if (Bt(hide_collapsed,j)) cl2->flags|=LTFLF_SKIP; else cl2->flags&=~LTFLF_SKIP; } cl2=cl2->next; } } skip: cl2=cl->next; while (cl2!=l && cl2->flags & LTFLF_SKIP) { /* if (cl2==l->cur_entry) { l->cur_entry=cl2->next; l->cur_data_col=l->cur_entry->min_col; } */ cl2->x=x; cl2->y=y; cl2->indent=l->indent; cl2->page_line_num=l->page_line_num; cl2->left_margin=l->left_margin; cl2->right_margin=l->right_margin; cl2->type=w & 0xFF00 | cl2->type & 0xFFFF00FF; if (l->flags & LTFF_WORD_WRAP) cl2->flags|=LTFLF_WORD_WRAP; else cl2->flags&=~LTFLF_WORD_WRAP; if (l->flags & LTFF_UNDERLINED) { cl2->flags|=LTFLF_UNDERLINED; w|=LTFLT_UNDERLINED; } else { cl2->flags&=~LTFLF_UNDERLINED; w&=~LTFLT_UNDERLINED; } if (l->flags & LTFF_INVERTED) { cl2->flags|=LTFLF_INVERTED; w|=LTFLT_INVERTED; } else { cl2->flags&=~LTFLF_INVERTED; w&=~LTFLT_INVERTED; } if (l->flags & LTFF_BLINK) { cl2->flags|=LTFLF_BLINK; w|=LTFLT_BLINK; } else { cl2->flags&=~LTFLF_BLINK; w&=~LTFLT_BLINK; } cl2=cl2->next; } if (del_cl || pg_found || num_entriesflags & LTFLF_HOLD)) { if (cl==l->cur_entry) { l->cur_entry=cl2; l->cur_data_col=cl2->min_col; } if (best_cl==cl) { best_cl=cl2; best_col=0; } RemQue(cl); LtfDelEntry(cl,mem_tss); } } num_entries++; cl=cl2; } //Update header if (!skipped_update) { cl->x=x; cl->y=y; cl->indent=l->indent; cl->page_line_num=l->page_line_num; cl->left_margin=l->left_margin; cl->right_margin=l->right_margin; cl->type=w & 0xFF00 | cl->type & 0xFFFF00FF; if (find_cur_entry) { D=LtfCharDist(l,x,y); if (Dflags & LTFF_MIN_SIZE) { if (tss->window_right!=tss->window_left+l->max_x+4) { tss->window_right=tss->window_left+l->max_x-l->min_x+4; Bts(&sys_flags,SYSf_CLEAR_SCREEN_TEXT); } if (tss->window_bottom!=tss->window_top+l->max_y+1) { tss->window_bottom=tss->window_top+l->max_y-l->min_y+1; Bts(&sys_flags,SYSf_CLEAR_SCREEN_TEXT); } } if (find_cur_entry) { l->cur_entry=best_cl; l->cur_data_col=best_col; } if ((l->cur_entry->btype)!=LTFT_HEX_EDIT) { l->y=l->cur_entry->y; l->x=l->cur_entry->x+l->cur_data_col<<2; } else { l->y=l->cur_entry->y+l->cur_data_col/3/l->cur_entry->display; x=l->cur_data_col%(l->cur_entry->display*3); i=x/l->cur_entry->display; l->x=l->cur_entry->x+36; if (i<2) l->x+=x>>1*12+(x&1)<<2; else l->x+=l->cur_entry->display*12+(x-l->cur_entry->display<<1)<<2; } l->line=l->y+1; l->col=l->x>>2+1; if (has_cursor) { if (l->cur_top_line_num+tss->window_bottom-tss->window_top>l->max_y) l->cur_top_line_num=l->max_y-(tss->window_bottom-tss->window_top); if (l->cur_top_line_nummin_y) l->cur_top_line_num=l->min_y; if (l->y-l->cur_top_line_num>tss->window_bottom-tss->window_top) l->cur_top_line_num=l->y-(tss->window_bottom-tss->window_top); if (l->y-l->cur_top_line_num<0) l->cur_top_line_num=l->y; if (l->line_start_col+tss->window_right-tss->window_left>l->max_x) l->line_start_col=l->max_x-(tss->window_right-tss->window_left); if (l->line_start_colmin_x) l->line_start_col=l->min_x; if (l->x-l->line_start_col>tss->window_right-tss->window_left) l->line_start_col=l->x-(tss->window_right-tss->window_left); if (l->x-l->line_start_col<0) l->line_start_col=l->x; } if (recalc) l->recalc_start=NULL; if (to_screen && has_cursor) { tss->cursor_vert=l->y-l->cur_top_line_num+tss->window_top; tss->cursor_hor=l->x-l->line_start_col+tss->window_left; if (jiffies % (JIFFY_FREQ>>2) > (JIFFY_FREQ>>2)>>1) { Btr(&Fs->crt_flags,CRTf_CURSOR_ON); CursorOn; } i=l->max_x-l->min_x+1; tss->scroll_x=DivI8(MulI8(l->line_start_col-l->min_x, tss->window_right-tss->window_left+4)+i-1,i)&-4; i=l->max_y-l->min_y+1; tss->scroll_y=DivI8(MulI8(l->cur_top_line_num-l->min_y, tss->window_bottom-tss->window_top+1)+i-1,i); PlotBorderChar(140+(tss->border_attribute<<8), (tss->window_right-tss->window_left+4),tss->scroll_y); PlotBorderChar(140+(tss->border_attribute<<8), tss->scroll_x,(tss->window_bottom-tss->window_top+1)); } if (!same_window && extra_processing) { l->old_window_top=tss->window_top; l->old_window_bottom=tss->window_bottom; l->old_window_left=tss->window_left; l->old_window_right=tss->window_right; } GrDel(base); if (recalc) { i=num_entries-l->max_entries; if (i>1024 && !num_del_entries || next_pg_found) LtfUpdateWindowJoin(l,to_screen,has_cursor,recalc,find_cur_entry,next_pg_found,i); } } void LtfRemoveSoftCRs(Ltf *l,LtfEntry *cl=NULL) { LtfEntry *cl2,*saved_cl=cl; BoolU4 old_preempt=Preempt(OFF); if (!cl) cl=l->dummy.next; while (cl!=l) { cl2=cl->next; if (cl->btype==LTFT_SOFT_CR) { if (l->cur_entry==cl) { l->cur_entry=cl2; l->cur_data_col=l->cur_entry->min_col; } RemQue(cl); LtfDelEntry(cl,l->mem_tss); } else if (saved_cl && cl->btype==LTFT_CR) break; cl=cl2; } Preempt(old_preempt); } public void LtfRecalc(Ltf *l) { if (l->recalc_start!=l && l->recalc_start) LtfRemoveSoftCRs(l,l->recalc_start); LtfUpdateWindowJoin(l,FALSE,FALSE,TRUE,FALSE); } ext[EXT_LTF_RECALC]=&LtfRecalc; public void LtfCenter(Ltf *l) { TssStruct *tss=l->tss; LtfRecalc(l); l->cur_top_line_num=l->y-(tss->window_bottom-tss->window_top)>>1; } public void LtfBottom(Ltf *l) { l->cur_entry=l; l->cur_data_col=0; l->recalc_start=l; LtfRecalc(l); } public Ltf *LtfNew() { Ltf *l; l=MAllocZ(sizeof(Ltf)); StrCpy(l->filename.name,sys_temp_filename); l->file_attr=0; l->find_replace=MAllocZ(sizeof(EditFindTextStruct)); l->find_replace->scan_forward=1; l->find_replace->match_case=1; l->EditPlugIns=Fs->EditPlugIns; l->dollar_buf_size=84; l->dollar_buf=MAlloc(l->dollar_buf_size); l->max_entries=MAX_I4; l->ww_lines_back=32; l->tss=Fs; l->mem_tss=Fs; LtfReset(l,FALSE,FALSE); return l; } void ParseLtfFlags(LexStruct *l,U8 *flags,U4 *type) { I8 i; BoolU4 turn_on; while (l->token=='+' || l->token=='-') { turn_on=(l->token=='+'); if (Lex(l)==TK_IDENT) { i=MatchSysTextEntry(l->ident,"ST_LTF_FLAGS",MLE_EXACT); if (i<0) *type=LTFT_ERROR; else { AssignBit(flags,i,turn_on); if (i==LTFLf_SELECTED) AssignBit(type,30,turn_on); else if (i==LTFLf_UNDERLINED) AssignBit(type,31,turn_on); else if (i==LTFLf_INVERTED) AssignBit(type,29,turn_on); else if (i==LTFLf_BLINK) AssignBit(type,28,turn_on); } Lex(l); //skip flag } } } void LtfDefaultFlags(U4 *type,U8 *f1) { switch (*type & 255) {$AN,"default_flags","default_flags"$ case LTFT_TREE: *f1=LTFLF_COLLAPSED|LTFLF_TREE; *type=*type | LTFLT_UNDERLINED; break; case LTFT_DATA: *f1=LTFLF_DATA_IS_PTR | LTFLF_HAS_TERMINATOR | LTFLF_AUX_STRING; break; case LTFT_CURSOR_MOVEMENT: *f1=LTFLF_LEFT_EXP | LTFLF_RIGHT_EXP; break; case LTFT_LINK: *f1=LTFLF_AUX_STRING; *type=*type | LTFLT_UNDERLINED; break; case LTFT_ANCHOR: *f1=LTFLF_AUX_STRING; break; case LTFT_BUTTON: *f1=LTFLF_ESC | LTFLF_LEFT_EXP | LTFLF_HAS_BORDER; break; case LTFT_CHECK_BOX: *f1=LTFLF_DATA_IS_PTR; break; case LTFT_MACRO: *f1=LTFLF_ESC | LTFLF_LEFT_MACRO; *type=*type | LTFLT_UNDERLINED; break; case LTFT_MENU_VALUE: *f1=LTFLF_ESC | LTFLF_LEFT_EXP; *type=*type | LTFLT_UNDERLINED; break; case LTFT_HEX_EDIT: *f1=LTFLF_DATA_IS_PTR | LTFLF_ZERO_BASED; break; case LTFT_PICTURE: *f1=LTFLF_HAS_BIN; break; case LTFT_INSERT_BINARY: case LTFT_INSERT_BINARY_TYPE: case LTFT_INSERT_BINARY_SIZE: *f1=LTFLF_HAS_BIN; break; case LTFT_HIDE_START: *f1=LTFLF_COLLAPSED; *type=*type | LTFLT_UNDERLINED; break; case LTFT_SONG: *f1=LTFLF_LEFT_MACRO; break; } } I1 *LtfToPlainText(LtfEntry *ll) { I8 i,j; U8 type=ll->btype,f1=0,flags; I1 *buf,*buf2; if (ll->btype==LTFT_ERROR) return NewString(ll->plain_text); LtfDefaultFlags(&type,&f1); buf=NewString(SysTextSub(ll->btype,"ST_LTF_CMDS")); flags=ll->flags & ~(LTFLF_WORD_WRAP |LTFLF_UNDERLINED | LTFLF_INVERTED | LTFLF_BLINK | LTFLF_SKIP); for (i=0;i<64;i++) if (Bt(&f1,i)!=Bt(&flags,i)) { if (Bt(&flags,i)) buf=Add2String(buf,"+"); else buf=Add2String(buf,"-"); buf=Add2String(buf,SysTextSub(i,"ST_LTF_FLAGS")); } for (i=28;i<32;i++) if (Bt(&type,i)!=Bt(&ll->type,i)) { if (Bt(&ll->type,i)) buf=Add2String(buf,"+"); else buf=Add2String(buf,"-"); switch (i) { case 28: j=LTFLf_BLINK; break; case 29: j=LTFLf_INVERTED; break; case 30: j=LTFLf_SELECTED; break; case 31: j=LTFLf_UNDERLINED; break; } buf=Add2String(buf,SysTextSub(j,"ST_LTF_FLAGS")); } buf=Add2String(buf,","); switch (ll->btype) { case LTFT_TEXT: case LTFT_LINK: case LTFT_ANCHOR: case LTFT_MENU_VALUE: case LTFT_BUTTON: case LTFT_CHECK_BOX: case LTFT_TREE: case LTFT_PICTURE: case LTFT_INSERT_BINARY: case LTFT_INSERT_BINARY_TYPE: case LTFT_INSERT_BINARY_SIZE: case LTFT_SONG: buf=Add2String(buf,"\""); if (i==LTFT_CHECK_BOX) { buf=Add2String(buf,ll->display+4); } else { if (ll->flags & LTFLF_TREE) buf=Add2String(buf,ll->display+3); else buf=Add2String(buf,ll->display); } buf=Add2String(buf,"\","); break; case LTFT_DATA: buf2=MSPrintF("%s%d,",buf,ll->len); Free(buf); buf=buf2; break; case LTFT_HEX_EDIT: buf2=MSPrintF("%s%d,",buf,ll->len); Free(buf); buf=buf2; buf2=MSPrintF("%s%d,",buf,ll->display); Free(buf); buf=buf2; break; case LTFT_PAGE_LENGTH: case LTFT_LEFT_MARGIN: case LTFT_RIGHT_MARGIN: case LTFT_HEADER: case LTFT_FOOTER: case LTFT_INDENT: case LTFT_FOREGROUND_COLOR: case LTFT_BACKGROUND_COLOR: case LTFT_DEFAULT_FOREGROUND_COLOR: case LTFT_DEFAULT_BACKGROUND_COLOR: case LTFT_LINK_FOREGROUND: case LTFT_LINK_BACKGROUND: case LTFT_MACRO_FOREGROUND: case LTFT_MACRO_BACKGROUND: case LTFT_ANCHOR_FOREGROUND: case LTFT_ANCHOR_BACKGROUND: case LTFT_HIDDEN_FOREGROUND: case LTFT_HIDDEN_BACKGROUND: case LTFT_TREE_FOREGROUND: case LTFT_TREE_BACKGROUND: case LTFT_USER_FOREGROUND: case LTFT_USER_BACKGROUND: case LTFT_WORD_WRAP: case LTFT_UNDERLINED: case LTFT_INVERTED: case LTFT_BLINK: case LTFT_SHIFTED_X: case LTFT_SHIFTED_Y: if (ll->attr!=LTF_DEFAULT) { buf2=MSPrintF("%s%d,",buf,ll->attr); Free(buf); buf=buf2; } break; } flags=ll->flags& (LTFLF_SCROLLING_X|LTFLF_SHIFTED_X|LTFLF_SCROLLING_Y| LTFLF_AUX_STRING|LTFLF_LEFT_EXP|LTFLF_LEFT_MACRO| LTFLF_HAS_BIN|LTFLF_RIGHT_EXP|LTFLF_RIGHT_MACRO); while (flags) { j=Bsf(flags); Btr(&flags,j); switch (j) { case LTFLf_SCROLLING_X: buf2=MSPrintF("%s%d",buf,ll->scroll_len); Free(buf); buf=buf2; break; case LTFLf_SHIFTED_X: j=(ll->type.u2[1])&0x1F; if (j&0x10) j|=0xFFFFFFF0; buf2=MSPrintF("%s%d",buf,j); Free(buf); buf=buf2; break; case LTFLf_SHIFTED_Y: j=(ll->type>>21)&0x1F; if (j&0x10) j|=0xFFFFFFF0; buf2=MSPrintF("%s%d",buf,j); Free(buf); buf=buf2; break; case LTFLf_AUX_STRING: buf2=MSPrintF("%s\"%Q\"",buf,ll->aux_string); Free(buf); buf=buf2; break; case LTFLf_LEFT_EXP: buf2=MSPrintF("%s%d",buf,ll->left_exp); Free(buf); buf=buf2; break; case LTFLf_LEFT_MACRO: buf2=MSPrintF("%s\"%Q\"",buf,ll->left_macro); Free(buf); buf=buf2; break; case LTFLf_RIGHT_EXP: buf2=MSPrintF("%s%d",buf,ll->right_exp); Free(buf); buf=buf2; break; case LTFLf_RIGHT_MACRO: buf2=MSPrintF("%s\"%Q\"",buf,ll->right_macro); Free(buf); buf=buf2; break; case LTFLf_HAS_BIN: buf2=MSPrintF("%s%d",buf,ll->bin_num); Free(buf); buf=buf2; break; } buf=Add2String(buf,","); } buf[StrLen(buf)-1]=0; //Kill last comma buf2=NewString(buf); //exact allocation Free(buf); return buf2; } LtfEntry *ParseDollarCmd(I1 *st,TssStruct *tss) { I8 i,j,size,flags; I1 *ptr; LtfEntry *ll=NULL; LexStruct *l=LexNew(st,LF_DONT_FREE_BUFFER,NULL); Lex(l); if (l->token==TK_IDENT) { i=MatchSysTextEntry(l->ident,"ST_LTF_CMDS",MLE_IGNORE_CASE); if (i<0) i=LTFT_ERROR; Lex(l); //skip cmd code ll=MAllocZ(sizeof(LtfEntry),tss); ll->type=i; ll->plain_text=NewString(st,tss); LtfDefaultFlags(&ll->type,&ll->flags); ParseLtfFlags(l,&ll->flags,&ll->type); if (l->token==',') Lex(l); switch (i) { case LTFT_TEXT: case LTFT_LINK: case LTFT_ANCHOR: case LTFT_MENU_VALUE: case LTFT_BUTTON: case LTFT_CHECK_BOX: case LTFT_TREE: case LTFT_PICTURE: case LTFT_INSERT_BINARY: case LTFT_INSERT_BINARY_TYPE: case LTFT_INSERT_BINARY_SIZE: case LTFT_SONG: if (l->token==TK_STRING) { st=LexExtendString(l,&size); if (i==LTFT_CHECK_BOX) { ll->display=MSPrintF("[X] %s",st); ll->min_col=1; } else { if (ll->flags & LTFLF_TREE) { ll->display=MSPrintF("+] %s",st); ll->min_col=1; } else ll->display=st; } } else { if (i>=LTFT_PICTURE && i<=LTFT_INSERT_BINARY_SIZE || i==LTFT_SONG) ll->display=NewString(""); else { ll->display=0; ll->type=LTFT_ERROR; } } break; case LTFT_HIDE_START: ll->display=NewString("<-"); ll->min_col=1; break; case LTFT_HIDE_END: ll->display=NewString(">"); break; case LTFT_DATA: ll->flags|=LTFLF_AUX_STRING; //don't allow switched off ll->len=Expression(l); break; case LTFT_HEX_EDIT: ll->len=Expression(l); if (l->token==',') Lex(l); ll->display=Expression(l); //TODO union break; case LTFT_PAGE_LENGTH: case LTFT_LEFT_MARGIN: case LTFT_RIGHT_MARGIN: case LTFT_HEADER: case LTFT_FOOTER: case LTFT_INDENT: case LTFT_FOREGROUND_COLOR: case LTFT_BACKGROUND_COLOR: case LTFT_DEFAULT_FOREGROUND_COLOR: case LTFT_DEFAULT_BACKGROUND_COLOR: case LTFT_LINK_FOREGROUND: case LTFT_LINK_BACKGROUND: case LTFT_MACRO_FOREGROUND: case LTFT_MACRO_BACKGROUND: case LTFT_ANCHOR_FOREGROUND: case LTFT_ANCHOR_BACKGROUND: case LTFT_HIDDEN_FOREGROUND: case LTFT_HIDDEN_BACKGROUND: case LTFT_TREE_FOREGROUND: case LTFT_TREE_BACKGROUND: case LTFT_USER_FOREGROUND: case LTFT_USER_BACKGROUND: case LTFT_WORD_WRAP: case LTFT_UNDERLINED: case LTFT_INVERTED: case LTFT_BLINK: case LTFT_SHIFTED_X: case LTFT_SHIFTED_Y: if (!l->token) ll->attr=LTF_DEFAULT; else ll->attr=Expression(l); break; case LTFT_ERROR: ll->flags=0; ll->type=LTFT_ERROR; break; } flags=ll->flags& (LTFLF_SCROLLING_X|LTFLF_SHIFTED_X|LTFLF_SCROLLING_Y| LTFLF_AUX_STRING|LTFLF_LEFT_EXP|LTFLF_LEFT_MACRO| LTFLF_HAS_BIN|LTFLF_RIGHT_EXP|LTFLF_RIGHT_MACRO); while (flags) { j=Bsf(flags); Btr(&flags,j); while (l->token==',') Lex(l); switch (j) { //TODO: Might check for expression errors case LTFLf_SCROLLING_X: ll->scroll_len=Expression(l); break; case LTFLf_SHIFTED_X: ll->type|=((Expression(l) & 0x1F)<<16); break; case LTFLf_SHIFTED_Y: ll->type|=((Expression(l) & 0x1F)<<21); break; case LTFLf_AUX_STRING: if (l->token==TK_STRING) { ll->aux_string=LexExtendString(l,&size); if (i==LTFT_MACRO && !ll->display) ll->display=NewString(ll->aux_string,tss); if (i==LTFT_DATA) { if (ptr=StrStr(ll->aux_string,":")) ll->min_col=ptr-ll->aux_string+1; ll->display=MAlloc(ll->len+ll->min_col+2,tss); } } else ll->type=LTFT_ERROR; break; case LTFLf_LEFT_EXP: ll->left_exp=Expression(l); break; case LTFLf_LEFT_MACRO: if (l->token==TK_STRING) { ll->left_macro=LexExtendString(l,&size); if (i==LTFT_MACRO && !ll->display) ll->display=NewString(ll->left_macro,tss); } else ll->type=LTFT_ERROR; break; case LTFLf_RIGHT_EXP: ll->right_exp=Expression(l); break; case LTFLf_RIGHT_MACRO: if (l->token==TK_STRING) { ll->right_macro=LexExtendString(l,&size); if (i==LTFT_MACRO && !ll->display) ll->display=NewString(ll->right_macro,tss); } else ll->type=LTFT_ERROR; break; case LTFLf_HAS_BIN: if (!l->token) ll->bin_num=0; else ll->bin_num=Expression(l); break; } } } else if (!ll) { ll=MAllocZ(sizeof(LtfEntry),tss); ll->type=LTFT_ERROR; ll->plain_text=NewString(st,tss); } LexDel(l); return ll; } void LtfInsert(Ltf *l,LtfEntry *ll) { I1 *dst; LtfEntry *cl=l->cur_entry,*nl; ll->x=cl->x; ll->y=cl->y; ll->indent=cl->indent; ll->page_line_num=cl->page_line_num; ll->left_margin=cl->left_margin; ll->right_margin=cl->right_margin; if (l->cur_data_col>0 && cl->btype==LTFT_TEXT && l->cur_data_colmax_col) { nl=MAllocZ(sizeof(LtfEntryBase)+4,l->mem_tss); nl->type=LTFT_TEXT|cl->type&-0x100; nl->x=cl->x; nl->y=cl->y; nl->indent=cl->indent; nl->page_line_num=cl->page_line_num; nl->left_margin=cl->left_margin; nl->right_margin=cl->right_margin; nl->flags=cl->flags; dst=cl->display+l->cur_data_col; nl->display=NewString(dst,l->mem_tss); *dst=0; cl->max_col=l->cur_data_col; InsQue(nl,cl); l->cur_data_col=0; cl=nl; cl->max_col=StrLen(cl->display); } if (cl->btype==LTFT_TEXT && l->cur_data_col>=cl->max_col) { InsQue(ll,cl); l->cur_entry=ll->next; } else { InsQue(ll,cl->last); l->cur_entry=cl; } l->cur_data_col=l->cur_entry->min_col; LtfRemoveSoftCRs(l,l->cur_entry); } public LtfEntry *LtfPutS(Ltf *l,I1 *st) { I1 ch,*ptr=st,*ptr2,*st2,*ptr3,*ptr4,*src; BoolU4 old_preempt=Preempt(OFF); LtfEntry *ll=NULL,*result=NULL,*cl=l->cur_entry; l->recalc_start=l; //TODO:This might be optimized if (!st) { Preempt(old_preempt); return NULL; } while (*ptr) { ptr2=ptr; ch=*ptr++; while (TRUE) { if (l->flags & LTFF_PLAIN_TEXT_WITH_TABS) while (ch && ch!=CH_CR && ch!=CH_LINE_FEED && ch!=CH_CURSOR) ch=*ptr++; else if (l->flags & LTFF_PLAIN_TEXT) while (ch && ch!=CH_CR && ch!=CH_LINE_FEED && ch!=CH_TAB && ch!=CH_CURSOR && ch!=CH_FORM_FEED) ch=*ptr++; else while (ch && ch!=CH_CR && ch!=CH_LINE_FEED && ch!=CH_TAB && ch!=CH_CURSOR && ch!=CH_FORM_FEED && ch!='$$') ch=*ptr++; if (ch==CH_CURSOR) { if (l->flags & LTFF_NO_CURSOR) ch=*ptr++; else break; } else break; } ptr--; if (!ch) { if (ptr!=ptr2) { ll=MAllocZ(sizeof(LtfEntryBase)+4,l->mem_tss); ll->type=LTFT_TEXT | l->text_attribute << 8; if (l->flags & LTFF_NO_CURSOR) { src=NewString(ptr2); StringUtil(src,SU_REMOVE_CTRL_CHARS); } else src=ptr2; ll->display=NewString(src,l->mem_tss); ll->max_col=StrLen(src); LtfInsert(l,ll); if (l->flags & LTFF_NO_CURSOR) Free(src); } } else { if (ptr!=ptr2) { *ptr=0; ll=MAllocZ(sizeof(LtfEntryBase)+4,l->mem_tss); ll->type=LTFT_TEXT | l->text_attribute << 8; if (l->flags & LTFF_NO_CURSOR) { src=NewString(ptr2); StringUtil(src,SU_REMOVE_CTRL_CHARS); } else src=ptr2; ll->display=NewString(src,l->mem_tss); ll->max_col=StrLen(src); LtfInsert(l,ll); if (l->flags & LTFF_NO_CURSOR) Free(src); *ptr=ch; } if (ch==CH_CURSOR) { //cursor ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_CURSOR | l->text_attribute << 8; LtfInsert(l,ll); ptr++; } else if (ch==CH_FORM_FEED) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_PAGE_BREAK | l->text_attribute << 8; LtfInsert(l,ll); ptr++; } else if (ch==CH_TAB) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_TAB | l->text_attribute << 8; LtfInsert(l,ll); ptr++; } else if (ch=='$$') { ptr++; //skip first dollar ptr2=ptr; while (*ptr && *ptr!='$$') ptr++; if (*ptr) { *ptr=0; //zero second dollar if (ptr==ptr2) { ll=MAllocZ(sizeof(LtfEntryBase)+4,l->mem_tss); ll->type=LTFT_TEXT | l->text_attribute << 8; ll->max_col=1; if (l->flags & LTFF_DOUBLE_DOLLARS) ll->display=NewString("$$$$",l->mem_tss); else ll->display=NewString("$$",l->mem_tss); LtfInsert(l,ll); } else { st2=MAlloc(ptr-ptr2+1); ptr3=ptr2; ptr4=st2; while (*ptr3) { ch=*ptr3++; if (ch==CH_CURSOR) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_CURSOR | l->text_attribute << 8; LtfInsert(l,ll); } else if (ch==CH_FORM_FEED) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_PAGE_BREAK | l->text_attribute << 8; LtfInsert(l,ll); } else *ptr4++=ch; } *ptr4=0; if (ll=ParseDollarCmd(st2,l->mem_tss)) { result=ll; LtfInsert(l,ll); } Free(st2); } *ptr++='$$'; } } else { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_CR | l->text_attribute << 8; LtfInsert(l,ll); if (ch==CH_CR) while (*ptr==CH_CR) ptr++; if (*ptr==CH_LINE_FEED) ptr++; while (*ptr==CH_CR) ptr++; } } } Preempt(old_preempt); return result; } public LtfEntry *LtfPrintF(Ltf *l,I1 *src,...) { LtfEntry *result; I1 *buf=SPrintFJoin(NULL,src,argc,argv); result=LtfPutS(l,buf); Free(buf); return result; } public void LtfSetMax(U8 i) { Ltf *l=Fs->cur_ltf; l->max_entries=i; } public void LtfSafeInsert(Ltf *l,I1 *st) { //This is necessary when hidden text might screw-up //inserts. It does them all-at-once. BoolU4 old_preempt=Preempt(OFF); U8 old_flags=l->flags; l->flags|=LTFF_NO_CURSOR; LtfPutS(l,st); LtfRecalc(l); l->flags=old_flags; Preempt(old_preempt); } public void Type(I1 *name) { Ltf *l=LtfRead(name); EditInsertLtf(Fs->cur_ltf,l); LtfDel(l); } sys_clipboard_ltf=LtfNew;