void DrawChar(I8 ch) //Raw I/O { BoolU4 old_preempt=Preempt(OFF); I8 i; U1 *ptr,*ptr2; if (ch=='$$') { if (dc_flags & DCF_IN_DOLLAR) { dc_flags&=~DCF_IN_DOLLAR; if (!(dc_flags & DCF_LAST_DOLLAR)) { dc_flags&=~DCF_LAST_DOLLAR; return; } } else { dc_flags|=DCF_IN_DOLLAR|DCF_LAST_DOLLAR; return; } } dc_flags&=~DCF_LAST_DOLLAR; if (dc_flags & DCF_IN_DOLLAR) return; if (ch==CH_TAB) { DrawChar(CH_SPACE); while (dc_col & 7) DrawChar(CH_SPACE); } else if (ch==CH_BACKSPACE) { dc_col--; DrawChar(CH_SPACE); dc_col--; } else if (ch==CH_CR) { DrawChar(CH_SPACE); while (dc_col % (GR_WIDTH/FONT_WIDTH)) DrawChar(CH_SPACE); } else if (Bt(SYS_DISPLAYABLE_CHARS_BITMAP,ch)||ch==0x7F) { OutP(VGA_SC_INDEX,VGA_MAP_MASK); OutP(VGA_SC_DATA,0x0F); ptr=0xA0000+(dc_col % (GR_WIDTH/FONT_WIDTH))+ (dc_col/(GR_WIDTH/FONT_WIDTH) % (GR_HEIGHT/FONT_HEIGHT))*GR_WIDTH; ptr2=&grfont[ch.u1[0]*8]; for (i=0;i<8;i++) { *ptr=reverse_bits_table[*ptr2++]; ptr+=GR_WIDTH>>3; } dc_col++; } Preempt(old_preempt); } void GrClear2(GrBitMap *base) { switch (base->type) { case BMT_COLOR4: MemSet(base->body,0,(base->internal_width*base->height)>>1); break; case BMT_MONO: MemSet(base->body,0,(base->internal_width*base->height)>>3); break; } } void GrClear(GrBitMap *base=NULL) { if (!base) GrClear2(Gs->grbase); else GrClear2(base); } void FillWinText(TssStruct *tss,U8 d) { I8 x,y; I8 t=(tss->win_top>0) ? tss->win_top : 0, b=(tss->win_bottomwin_bottom : TEXT_ROWS-1, l=(tss->win_left>0) ? tss->win_left : 0, r=(tss->win_rightwin_right : TEXT_COLS-1; U4 *ptr; for (y=t;y<=b;y++) { ptr=textbase+(y*TEXT_COLS+l)*4; for (x=l;x<=r;x++) { *ptr=d; ptr+=4; } } } void ClearWinText(TssStruct *tss) { FillWinText(tss,tss->text_attribute<<8); } void SetWinBkColor(TssStruct *tss,U8 c) { tss->text_attribute=tss->text_attribute&0x0F | c<<4; FillWinText(tss,c<<12); } void InitCrt() //Called when spawning new tasks { Fs->text_attribute=0xF1; Fs->border_attribute=0xF9; Fs->win_right=TEXT_COLS-2; Fs->win_left=1; Fs->win_top=1; Fs->win_bottom=TEXT_ROWS-2; } BoolU8 RawCrtPutKey(I8 ch,U8 scancode) { nounusedwarn scancode; if (IsRaw) { DrawChar(ch); return TRUE; } else return FALSE; } BoolU8 RawCrtPutS(I1 *st) { I1 ch; if (IsRaw) { while (ch=*st++) DrawChar(ch); return TRUE; } else return FALSE; } void WaitLastInputTskIdle(TssStruct *tss) { U8 old_flags=GetFlags; TssCmdStruct *tempc; Cli; do { tempc=&tss->last_input_filter_tss->next_servant_cmd; if (tempc==*tempc && Bt(&tss->last_input_filter_tss->task_flags,TSSf_IDLE)) break; SwapInNext; } while (TRUE); SetFlags(old_flags); } BoolU8 InputFilterPutKey(I8 ch,U8 scancode) { BoolU4 old_preempt; if (Bt(&Fs->task_flags,TSSf_INPUT_FILTER_TASK)) { old_preempt=Preempt(OFF); //This is for nestled autotypes //more trouble than it's worth // WaitLastInputTskIdle(Fs); Msg(MSG_KEY_DOWN,ch,scancode); Preempt(old_preempt); return TRUE; } else return FALSE; } BoolU8 InputFilterPutS(I1 *st) { I1 ch; BoolU4 old_preempt; if (Bt(&Fs->task_flags,TSSf_INPUT_FILTER_TASK)) { old_preempt=Preempt(OFF); //This is for nestled autotypes //more trouble than it's worth // WaitLastInputTskIdle(Fs); while (ch=*st++) Msg(MSG_KEY_DOWN,ch,0); Preempt(old_preempt); return TRUE; } else return FALSE; } void PutKey(I8 ch,U8 sc) { KeyDevStruct *tempp=sys_put_key_queue.next; if (!Bt(&Fs->crt_flags,CRTf_SILENT)) { if (sys_cur_scan_code & SCF_SCROLL) { if (sys_cur_focus_task==Fs) { while (sys_cur_scan_code & SCF_SCROLL) SwapInNext; } } while (tempp!=&sys_put_key_queue) { if (tempp->PutKey(ch,sc)) break; tempp=tempp->next; } } } asm {CP_PUT_CHAR::}; void PutChar(I8 ch) { PutKey(ch,0); } asm {CP_PUT_STR::}; void PutS(I1 *st) { I1 ch,*ptr; BoolU4 cont=TRUE; if (!st) return; KeyDevStruct *tempp=sys_put_key_queue.next; if (!Bt(&Fs->crt_flags,CRTf_SILENT)) { if (sys_cur_scan_code & SCF_SCROLL) { if (sys_cur_focus_task==Fs) { while (sys_cur_scan_code & SCF_SCROLL) SwapInNext; } } while (cont && tempp!=&sys_put_key_queue) { if (tempp->PutS) { if (tempp->PutS(st)) break; } else { ptr=st; while (ch=*ptr++) if (tempp->PutKey(ch,0)) cont=FALSE; } tempp=tempp->next; } } } KeyDevStruct *AddKeyDev(void *putkey_add,void *puts_add,U8 priority) //Places hook in StdOut chain { BoolU4 old_preempt=Preempt(OFF); KeyDevStruct *tempp,*tempp1=sys_put_key_queue.last; tempp=AMAllocZ(sizeof(KeyDevStruct)); tempp->PutKey=putkey_add; tempp->PutS=puts_add; tempp->priority=priority; while (tempp1->priority>priority) tempp1=tempp1->last; InsQue(tempp,tempp1); Preempt(old_preempt); return tempp; }