void *FXTerminal::worker_thread(void *arg) #endif { signal(SIGINT, sigint_handler); #ifdef SIGBREAK signal(SIGBREAK, sigbreak_handler); #endif term = (FXTerminal *)arg; // set proper initial state for all the locks. LockMutex(term->mutex1); LockMutex(term->mutex2); term->sync_even = 1; // run the application code. returncode = (*fwin_main1)(term->argc, term->argv); wake_up_terminal(WORKER_EXITING); #ifdef WIN32 ExitThread(returncode); return returncode; #else pthread_exit(&returncode); // between these two lines I think return &returncode; // I must certainly exit! #endif }
void fwin_minimize() { if (!windowed) return; fflush(stdout); wake_up_terminal(FXTerminal::MINIMIZE_MAIN); // I do not feel any need to get the threads into lockstep here. }
void fwin_refresh_switches(char **switches, char **packages) { if (!windowed) return; switches_list = switches; modules_list = packages; wake_up_terminal(FXTerminal::REFRESH_SWITCHES); regain_lockstep(); }
void fwin_set_prompt(const char *s) { strncpy(fwin_prompt_string, s, sizeof(fwin_prompt_string)); fwin_prompt_string[sizeof(fwin_prompt_string)-1] = 0; if (!windowed) return; wake_up_terminal(FXTerminal::SET_PROMPT); regain_lockstep(); }
void fwin_menus(char **modules, char **switches, review_switch_settings_function *f) { if (!windowed) return; modules_list = modules; switches_list = switches; wake_up_terminal(FXTerminal::SET_MENUS); regain_lockstep(); review_switch_settings = f; }
int fwin_getchar() { if (!windowed) return fwin_plain_getchar(); // In general I have a line of stuff ready sitting in a buffer. So on // most calls to here I can just return what is in it. if (term->inputBufferP < term->inputBufferLen) return term->inputBuffer[term->inputBufferP++]; // Now however a new line of input is needed, so I have to request it from // the user-interface thread. if (update_next_time && review_switch_settings != NULL) { (*review_switch_settings)(); update_next_time = 0; } if (delay_callback != NULL) (*delay_callback)(1); wake_up_terminal(FXTerminal::REQUEST_INPUT); // Wait until the signal that I just sent has been received // and processed. regain_lockstep(); if (delay_callback != NULL) (*delay_callback)(0); // I will try a convention that if inputBufferLen is zero that indicates // a dodgy state. Eg the user is sending an EOF or interrupt. int n = term->inputBufferLen; if (n == 0) return EOF; const char *p = &term->inputBuffer[term->inputBufferP]; while (n>0 && isspace(*p)) { n--; p++; } // The next line is pretty shameless and is there to help REDUCE while not // getting too much in the way of anybody else. If an input line is // entered starting with the text "load_package" I make a callback to // review_switch_settings fairly soon. Ditto "on" and "off". if (n>12 && strncmp(p, "load_package", 12) == 0) update_next_time = 1; else if (n>3 && (strncmp(p, "on", 2) == 0 || strncmp(p, "off", 3) == 0)) update_next_time = 1; // And ANYWAY I will try to trigger a review every second or so... Note that // until the user asks for more input from the keyboard this will not happen // so things can get out of step, but should eventually recover. else { clock_t now = clock(); if (now > review_time) { update_next_time = 1; review_time = now + CLOCKS_PER_SEC; } } int ch = term->inputBuffer[term->inputBufferP++]; if (ch == (0x1f & 'D')) return EOF; else return ch; }
void fwin_showmath(const char *s) { if (!windowed) return; fwin_ensure_screen(); // get regular text up to date first. fwin_maths = s; LockMutex(term->pauseMutex); // here I have to do real inter-thread communication. if (delay_callback != NULL) (*delay_callback)(1); wake_up_terminal(FXTerminal::SHOW_MATH); // here I need to wait until the signal that I just sent has been received // and processed. regain_lockstep(); if (delay_callback != NULL) (*delay_callback)(0); UnlockMutex(term->pauseMutex); }
void fwin_ensure_screen() { if (!windowed) { fflush(stdout); return; } if (term->fwin_in == term->fwin_out) return; LockMutex(term->pauseMutex); // here I have to do real inter-thread communication. if (delay_callback != NULL) (*delay_callback)(1); wake_up_terminal(FXTerminal::FLUSH_BUFFER); // here I need to wait until the signal that I just sent has been received // and processed. regain_lockstep(); if (delay_callback != NULL) (*delay_callback)(0); UnlockMutex(term->pauseMutex); }
void fwin_exit(int return_code) { if (windowed) { wake_up_terminal(FXTerminal::WORKER_EXITING); returncode = return_code; #ifdef WIN32 ExitThread(returncode); #else pthread_exit(&returncode); #endif } if (using_termed) { input_history_end(); term_close(); } exit(return_code); }
static void rewrite_title_bar() { // Just at present this does not cope with cases where the width of the window // has been changed... int ll = strlen(left_stuff), lm = strlen(mid_stuff), lr = strlen(right_stuff); int i, j; for (i=0; i<80; i++) full_title[i] = SPACER_CHAR; strncpy(full_title, left_stuff, ll); j = 80 - strlen(right_stuff); strncpy(&full_title[j], right_stuff, lr); j = 40-(lm/2); strncpy(&full_title[j], mid_stuff, lm); full_title[80] = 0; wake_up_terminal(FXTerminal::REFRESH_TITLE); regain_lockstep(); }
static void fwin_ensure_buffer_space() { if (!windowed) return; if (term->fwin_in == term->fwin_out) return; LockMutex(term->pauseMutex); if (delay_callback != NULL) (*delay_callback)(1); wake_up_terminal(FXTerminal::FLUSH_BUFFER); if (term->sync_even) { UnlockMutex(term->mutex1); LockMutex(term->mutex3); term->fwin_in = term->fwin_out = 0; UnlockMutex(term->mutex2); LockMutex(term->mutex4); } else { UnlockMutex(term->mutex3); LockMutex(term->mutex1); term->fwin_in = term->fwin_out = 0; UnlockMutex(term->mutex4); LockMutex(term->mutex2); } if (delay_callback != NULL) (*delay_callback)(0); UnlockMutex(term->pauseMutex); }
void prompt_input(const char*s) { wake_up_terminal(); tprint(s); term_input(); }
void fwin_restore() { if (!windowed) return; fflush(stdout); wake_up_terminal(FXTerminal::RESTORE_MAIN); }