Project: OSMain

TaskCmdStruct *TaskRequestQueue(TaskStruct *servant,TaskStruct *master,
                     U1 *data,U8 flags)
{
  TaskCmdStruct *result;
  if (!data || !TaskValidate(servant) ||
      master && !TaskValidate(master) ||
      servant->popup_task && !Bt(&servant->task_flags,TASKf_FILTER_INPUT))
    return NULL;
  result=AMAlloc(sizeof(TaskCmdStruct));
  result->master_task=master;
  result->cmd_code=TASKCT_EXECUTE_STR;
  result->flags=flags;
  result->data=AStrNew(data);
  result->result=NULL;

  PushFD;
  Cli;
  while (LBts(&servant->locked_flags,TASKLf_TASK_LOCK))
    Pause;
  if (!TaskValidate(servant)) {
    PopFD;
    Free(result->data);
    Free(result);
    return NULL;
  } else {
    LBtr(&servant->task_flags,TASKf_IDLE);
    LBtr(&servant->task_flags,TASKf_AWAITING_MSG);
    InsQue(result,servant->last_servant_cmd);
    LBtr(&servant->locked_flags,TASKLf_TASK_LOCK);
    if (Bt(&flags,TASKCf_WAKE_MASTER) &&
      TaskValidate(master)) {
      LBts(&master->task_flags,TASKf_SUSPENDED);
      TaskNext;
    }
  }
  PopFD;
  return result;
}

TaskCmdStruct *TextInputQueue(TaskStruct *servant,TaskStruct *master,
                     U1 *data,U8 flags)
{
  BoolI1 old_preempt=Preempt(OFF);
  TaskCmdStruct *result;
  TaskStruct *task;
  if (!data || !TaskValidate(servant) ||
      master && !TaskValidate(master) ||
      servant->popup_task && !Bt(&servant->task_flags,TASKf_FILTER_INPUT)) {
    Preempt(old_preempt);
    return NULL;
  }
  result=AMAlloc(sizeof(TaskCmdStruct));
  result->master_task=master; //in case somebody cares
  result->cmd_code=TASKCT_TEXT_INPUT;
  result->flags=flags;
  result->data=AStrNew(data);
  result->result=NULL;

  PushFD;
  if (flags&1<<TASKCf_HIGHEST_PRIORITY ||
      servant->next_input_filter_task==servant) {
    task=Spawn(&InputFilterTask,NULL,
        "Input Filter",servant);
    Cli;
    task->next_input_filter_task=servant->next_input_filter_task;
    task->last_input_filter_task=servant;
    servant->next_input_filter_task=task;
    task->next_input_filter_task->last_input_filter_task=task;
  } else
    task=servant->next_input_filter_task;
  Cli;
  while (LBts(&task->locked_flags,TASKLf_TASK_LOCK))
    Pause;
  if (!TaskValidate(task)) {
    Free(result->data);
    Free(result);
    result=NULL;
  } else {
    LBtr(&task->task_flags,TASKf_IDLE);
    LBtr(&task->task_flags,TASKf_AWAITING_MSG);
    InsQue(result,task->last_servant_cmd);
    LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
  }
  PopFD;
  Preempt(old_preempt);
  return result;
}

TaskCmdStruct *QueueMsg(TaskStruct *_servant,TaskStruct *master,
                     I8 msg_code,I8 p1,I8 p2,U8 flags)
{
  TaskCmdStruct *tempc1,*tempc;
  TaskStruct *servant=_servant;
  if (!TaskValidate(servant) ||
      master && !TaskValidate(master)||
      servant->popup_task && !Bt(&servant->task_flags,TASKf_FILTER_INPUT))
    return NULL;
  tempc=AMAlloc(sizeof(TaskCmdStruct));
  tempc->master_task=master;
  tempc->cmd_code=TASKCT_MSG;
  tempc->msg_code=AbsI8(msg_code); //negative means do a down and up
  tempc->p1=p1;
  tempc->p2=p2;
  tempc->flags=flags;
  tempc->data=NULL;
  tempc->result=NULL;
  PushFD;
  if (Bt(&sys_semas[SYS_SEMA_RECORD_MACRO],0) &&
      servant!=macro_util_task &&
      msg_code==MSG_KEY_DOWN) {
    tempc1=AMAllocIdentical(tempc);
    Cli;
    InsQue(tempc1,sys_macro_queue.last);
  }
  Cli;
  while (Bt(&servant->task_flags,TASKf_FILTER_INPUT) &&
      !Bt(&flags,TASKCf_DONT_FILTER))
    servant=servant->next_input_filter_task;
  while (LBts(&servant->locked_flags,TASKLf_TASK_LOCK))
    Pause;
  if (!TaskValidate(servant)) {
    Free(tempc);
    tempc=NULL;
  } else {
    LBtr(&servant->task_flags,TASKf_IDLE);
    LBtr(&servant->task_flags,TASKf_AWAITING_MSG);
    InsQue(tempc,servant->last_servant_cmd);
    LBtr(&servant->locked_flags,TASKLf_TASK_LOCK);
  }
  PopFD;
  if (msg_code<0) //Down-Up
    QueueMsg(_servant,master,-msg_code+1,p1,p2,flags);
  return tempc;
}

BoolI8 GetRequestResult(TaskCmdStruct *rqst=NULL,U8 *result=NULL)
{
  TaskCmdStruct *tempc,*tempc1;
  PushFD;
  Cli;
  while (LBts(&Fs->locked_flags,TASKLf_TASK_LOCK))
    Pause;
  tempc1=&Fs->next_master_cmd;
  tempc=tempc1->next;
  while (tempc!=tempc1) {
    if (!rqst || rqst==tempc) {
      RemQue(tempc);
      LBtr(&Fs->locked_flags,TASKLf_TASK_LOCK);
      PopFD;
      if (result)
        *result=tempc->result;
      Free(tempc->data);
      Free(tempc);
      return TRUE;
    }
    tempc=tempc->next;
  }
  LBtr(&Fs->locked_flags,TASKLf_TASK_LOCK);
  PopFD;
  return FALSE;
}

U0 TaskWaitIdle(TaskStruct *task)
{
  TaskStruct *task1;
  TaskCmdStruct *tempc;
  if (TaskValidate(task)) {
    PushFD;
    Cli;
    while (TRUE) {
      task1=task->last_input_filter_task;
      tempc=&task1->next_servant_cmd;
      if (TaskValidate(task1) && tempc==*tempc &&
          Bt(&task1->task_flags,TASKf_IDLE))
        break;
      TaskNext;
    }
    PopFD;
  }
}

U0 PostMsg(TaskStruct *task,I8 msg_code,I8 p1,I8 p2,U8 flags=0)
{
  if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))
    QueueMsg(task->last_input_filter_task,NULL,msg_code,p1,p2,
        flags| 1<<TASKCf_DONT_FILTER);
  else
    QueueMsg(task,NULL,msg_code,p1,p2,flags);
}

U0 SendMsg(TaskStruct *task,I8 msg_code,I8 p1,I8 p2,U8 flags=0)
{
  PostMsg(task,msg_code,p1,p2,flags);
  TaskWaitIdle(task);
}

U0 Msg(I8 msg_code,I8 p1,I8 p2,U8 flags=0)
{
  PostMsg(Fs,msg_code,p1,p2,flags);
}

U8 ServantCmdsHandler(TaskStruct *task=NULL)
{
  U8 cnt=0,old_flags=GetFlags;
  TaskCmdStruct *tempc,*tempc1;
  TaskStruct *master;
  if (!task) task=Fs;
start_over:
  Cli;
  while (LBts(&task->locked_flags,TASKLf_TASK_LOCK))
    Pause;
  tempc1=&task->next_servant_cmd;
  while (tempc!=tempc1) {
    tempc=tempc1->next;
    if (tempc->cmd_code==TASKCT_EXECUTE_STR ||
    tempc->cmd_code==TASKCT_EXECUTE_FILE) {
      cnt++;
      RemQue(tempc);
      LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
      SetFlags(old_flags);
      try {
        if (tempc->cmd_code==TASKCT_EXECUTE_STR)
          tempc->result=ExePutS(tempc->data,sys_temp_filename);
        else
          tempc->result=ExeFile(tempc->data);
      } catch
        Fs->catch_except=TRUE;
      if (master=tempc->master_task) {
        if (!Bt(&tempc->flags,TASKCf_EXIT_ON_COMPLETE)) {
          Cli;
          while (LBts(&master->locked_flags,TASKLf_TASK_LOCK))
            Pause;
          InsQue(tempc,master->last_master_cmd);
          LBtr(&master->locked_flags,TASKLf_TASK_LOCK);
          SetFlags(old_flags);
        }
        if (Bt(&tempc->flags,TASKCf_FOCUS_MASTER) &&
        Bt(&master->task_flags,TASKf_LOCAL_USER))
          sys_cur_focus_task=master;
        if (Bt(&tempc->flags,TASKCf_WAKE_MASTER))
          LBtr(&master->task_flags,TASKf_SUSPENDED);
        if (!Bt(&tempc->flags,TASKCf_EXIT_ON_COMPLETE))
          goto start_over;
        else {
          Free(tempc->data);
          Free(tempc);
          Exit;
        }
      } else {
        if (!Bt(&tempc->flags,TASKCf_EXIT_ON_COMPLETE)) {
          Free(tempc->data);
          Free(tempc);
          goto start_over;
        } else {
          Free(tempc->data);
          Free(tempc);
          Exit;
        }
      }
    } else
      break;
  }
  LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
  SetFlags(old_flags);
  return cnt;
}

I8 Adam(U1 *fmt,...)
//Sends text to the adam task which gets
//compiled and run.
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv);
  U8 result;
  BoolI1 old_preempt=Preempt(OFF);
  TaskCmdStruct *tempc;
  if (!Bt(&sys_run_level,RLf_ADAM_SERVER))
    Dbg("Adam Not Serving Yet");
  TaskWaitIdle(adam_task);
  tempc=TaskRequestQueue(adam_task,Fs,buf,1<<TASKCf_WAKE_MASTER);
  Preempt(old_preempt);
  GetRequestResult(tempc,&result);
  Free(buf);
  return result;
}

U0 AdamLog(U1 *fmt,...)
//Sends text to the adam task which gets
//displayed.
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv);
  if (Fs!=adam_task) {
    if (!IsSingleUser)
      Adam("PutS(\"%Q\");",buf);
  } else
    PutS(buf);
  Free(buf);
}

U0 AdamErr(U1 *fmt,...)
//Sends text to the adam task which gets
//displayed as red and blinking.
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv),
     *buf1=MSPrintF("%S%s",
       "ST_ERR",buf);
  if (Fs!=adam_task) {
    if (!IsSingleUser)
      Adam("PutS(\"%Q\");",buf1);
  }else
    PutS(buf1);
  Free(buf1);
  Free(buf);
}

U0 XTalk(TaskStruct *task,U1 *fmt,...)
//Sends text to another task's input
//buffer.
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv),
     *buf1=MSPrintF("PutS(\"%Q\");",buf);
  TextInputQueue(task,0,buf1,0);
  Free(buf1);
  Free(buf);
}

U0 XTalkWithWait(TaskStruct *task,U1 *fmt,...)
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv),
     *buf1=MSPrintF("PutS(\"%Q\");",buf);
  TextInputQueue(task,0,buf1,0);
  Free(buf1);
  Free(buf);
  TaskWaitIdle(task);
}

U0 Auto(U1 *fmt,...)
//Sends text to one's own input buffer
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv),
     *buf1=MSPrintF("PutS(\"%Q\");",buf);
  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK))
    ExePutS(buf1);
  else
    TextInputQueue(Fs,0,buf1,1<<TASKCf_HIGHEST_PRIORITY);
  Free(buf1);
  Free(buf);
}

I8 ServantUser(U1 *fmt,...)
//Spawns a visible task and sends text
//which gets compiled and run.
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv);
  U8 result=0;
  TaskCmdStruct *tempc;
  TaskStruct *task=Spawn(&ServantUserCmdLine,NULL,"Servant",Fs);
  Fs->popup_task=task;
  tempc=TaskRequestQueue(task,Fs,buf,1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
  GetRequestResult(tempc,&result);
  Fs->popup_task=NULL;
  Kill(task,FALSE);
  Free(buf);
  return result;
}

U0 AutoStr(U1 *fmt,...)
//Sends text in the nature of an AutoFile to one's
//own input buffer.
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv);
  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK))
    ExePutS(buf);
  else
    TextInputQueue(Fs,0,buf,1<<TASKCf_HIGHEST_PRIORITY);
  Free(buf);
}

U0 AutoFile(U1 *filename)
{
  U1 *name2=DefaultExtension(filename,"AUZ");
  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK))
    ExeFile(name2);
  else
    AutoStr("%F",name2);
  Free(name2);
}


//This sends text of an AutoFile nature to a
//task's input buffer.
U0 XTalkStr(TaskStruct *task,U1 *fmt,...)
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv);
  TextInputQueue(task,0,buf,0);
  Free(buf);
}

U0 XTalkStrWithWait(TaskStruct *task,U1 *fmt,...)
{
  U1 *buf=SPrintFJoin(NULL,fmt,argc,argv);
  TextInputQueue(task,0,buf,0);
  Free(buf);
  TaskWaitIdle(task);
}

Historical capture: 2010-01-31. Home | Power on LoseThos | Sources and changes