hschumann2/TempleOS-Source-Code
0838
1 2U0 InputFilterTask()3{4 CJob *tmpc,*tmpc1;5 Bool old_filter;6 I64 old_flags=GetRFlags;7 Fs->win_inhibit=WIG_USER_TASK_DFT;8 LBts(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);9 old_filter=LBts(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);10 LBEqu(&Fs->task_flags,TASKf_FILTER_INPUT,old_filter);11 while (TRUE) {12 CLI13 JobsHndlr(old_flags);14 tmpc1=&Fs->srv_ctrl.next_waiting;15 tmpc=tmpc1->next;16 if (tmpc==tmpc1)17 break;18 else {19 if (tmpc->job_code==JOBT_TEXT_INPUT) {20 QueRem(tmpc);21 SetRFlags(old_flags);22 try23 ExePrint("%s",tmpc->aux_str);24 catch25 Fs->catch_except=TRUE;26 JobDel(tmpc);27 } else28 break;29 }30 }31 Fs->next_input_filter_task->last_input_filter_task=Fs->last_input_filter_task;32 Fs->last_input_filter_task->next_input_filter_task=Fs->next_input_filter_task;33 if (!old_filter)34 LBtr(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);35 SetRFlags(old_flags);36}37 38I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)39{/*Check for a message of type specified by a one in the mask.40Throw-out messages not in mask.41If no message fit mask, return NULL immediately.42Remove desired message, return msg_code.43Note: This delivers messages from parent down to pop-up.44*/45 I64 res,old_flags;46 CJob *tmpc,*tmpc1;47 if (!task) task=Fs;48 old_flags=GetRFlags;49 tmpc1=&task->srv_ctrl.next_waiting;50 while (TRUE) {51 CLI52 if (task==Fs)53 JobsHndlr(old_flags);54 tmpc=tmpc1->next;55 if (tmpc==tmpc1)56 break;57 else {58 if (tmpc->job_code==JOBT_MSG) {59 QueRem(tmpc);60 SetRFlags(old_flags);61 res=tmpc->msg_code;62 if (_arg1)63 *_arg1=tmpc->aux1;64 if (_arg2)65 *_arg2=tmpc->aux2;66 JobDel(tmpc);67 if ((res!=MSG_KEY_DOWN || !(tmpc->aux2&SCF_KEY_DESC) ||68 !Bt(&task->win_inhibit,WIf_SELF_KEY_DESC)) && Bt(&mask,res))69 goto sm_done;70 }71 }72 SetRFlags(old_flags);73 }74 res=MSG_NULL;75 if (_arg1)76 *_arg1=0;77 if (_arg2)78 *_arg2=0;79 if (task->parent_task&&task->parent_task->popup_task==task) {80 SetRFlags(old_flags);81 return ScanMsg(_arg1,_arg2,mask,task->parent_task);82 }83sm_done:84 SetRFlags(old_flags);85 return res;86}87 88I64 FlushMsgs(CTask *task=NULL)89{//Throw away all messages. Return count.90 I64 res=0,arg1,arg2;91 while (ScanMsg(&arg1,&arg2,~1,task))92 res++;93 return res;94}95 96I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)97{//Wait for a message of type specified by a one in the mask.98//Throw-out all messages not in mask.99 //Returns msg_code. See ::/Demo/MsgLoop.HC.100 I64 res;101 if (!task) task=Fs;102 LBtr(&task->task_flags,TASKf_IDLE);103 while (!(res=ScanMsg(_arg1,_arg2,mask,task))) {104 LBts(&task->task_flags,TASKf_IDLE);105 Yield;106 }107 LBtr(&task->task_flags,TASKf_IDLE);108 return res;109}110 111I64 ScanChar()112{//Checks for MSG_KEY_DOWN and returns 0 immediately if no key.113//Waits for MSG_KEY_UP of non-zero ASCII key and returns ASCII if key.114 //ScanMsg() throws away other message types.115 I64 arg1a,arg2a,arg1b,arg2b;116 if (!ScanMsg(&arg1a,&arg2a,1<<MSG_KEY_DOWN)||!arg1a)117 return 0;118 else119 do GetMsg(&arg1b,&arg2b,1<<MSG_KEY_UP);120 while (!arg1b); //Be careful of SC_SHIFT and SC_CTRL, etc.121 return arg1a;122}123 124Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE)125{//Checks for MSG_KEY_DOWN and returns FALSE immediately if no key.126//Sets ASCII and scan_code.127 //Removes key message and returns TRUE.128 //ScanMsg() throws away other message types.129 I64 ch=0,sc=0;130 if (ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN)) {131 if (_ch) *_ch=ch;132 if (_scan_code) *_scan_code=sc;133 if (echo)134 PutKey(ch,sc);135 return TRUE;136 } else {137 if (_ch) *_ch=0;138 if (_scan_code) *_scan_code=0;139 return FALSE;140 }141}142 143I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE,Bool raw_cursor=FALSE)144{//Waits for MSG_KEY_DOWN message and returns ASCII.145//Sets scan_code.146 //ScanKey() throws away other message types.147 I64 ch,sc;148 Bool cursor_on=FALSE;149 while (!ScanKey(&ch,&sc,FALSE)) {150 if (IsRaw && raw_cursor) {151 if (!cursor_on && ToI64(GetTSC*5/cnts.time_stamp_freq)&1) {152 '.';153 cursor_on=TRUE;154 } else if (cursor_on && !(ToI64(GetTSC*5/cnts.time_stamp_freq)&1)) {155 '' CH_BACKSPACE;156 cursor_on=FALSE;157 }158 }159 LBts(&Fs->task_flags,TASKf_IDLE);160 if (IsDbgMode) {161//We don't want interrupt-driven keyboard when in debugger162 //because that could have side-effects or crash, so we poll163 //keyboard when in debugger with interrupts off.164 PUSHFD165 CLI166 KbdMsHndlr(TRUE,FALSE);167 KbdMsgsQue;168 POPFD169 } else {170 LBts(&Fs->task_flags,TASKf_AWAITING_MSG);171 Yield;172 }173 LBtr(&Fs->task_flags,TASKf_IDLE);174 }175 if (IsRaw && raw_cursor && cursor_on)176 '' CH_BACKSPACE;177 if (echo)178 PutKey(ch,sc);179 if (_scan_code) *_scan_code=sc;180 return ch;181}182 183I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE)184{//Waits for non-zero ASCII key.185//Sets scan_code.186 I64 ch1;187 do ch1=GetKey(_scan_code,FALSE,raw_cursor);188 while (!ch1);189 if (echo)190 "$PT$%c$FG$",ch1;191 return ch1;192}193 194U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0)195{//Returns a MAlloc()ed prompted string. See Flags.196 U8 *st;197 if (msg)198 "" msg,dft;199 st=(*fp_getstr2)(flags);200 if (!*st) {201 Free(st);202 if (dft)203 return StrNew(dft);204 else205 return StrNew("");206 }207 return st;208}209 210I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE)211{//Prompt into fixed length string. Size must include terminator.212 U8 *st;213 I64 ch,i=0;214 if (!size || !buf) return 0;215 if (allow_ext) {216 st=GetStr;217 if (StrLen(st)>size-1) {218 MemCpy(buf,st,size-1);219 buf[size-1]=0;220 } else221 StrCpy(buf,st);222 i=StrLen(buf);223 Free(st);224 } else {225 while (TRUE) {226 ch=GetChar(,FALSE,IsDbgMode);227 if (ch=='\n') {228 '' ch;229 break;230 } else if (ch==CH_BACKSPACE) {231 if (i>0) {232 i--;233 '' ch;234 }235 } else {236 if (i<size-1) {237 buf[i++]=ch;238 '' ch;239 }240 }241 }242 buf[i]=0;243 }244 return i;245}246 