char * get_more_input (char *prompt, char *preinput, int history_id, completion_fn compl_fn) { /* Emacs 21 uses a 513 byte string to store the keysym name. */ char keysym_buf[513]; rp_screen *s = current_screen (); KeySym ch; unsigned int modifier; rp_input_line *line; char *final_input; edit_status status; Window focus; int revert, done = 0; history_reset(); /* Create our line structure */ line = input_line_new (prompt, preinput, history_id, compl_fn); /* We don't want to draw overtop of the program bar. */ hide_bar (s); /* Switch to the default colormap. */ if (current_window()) XUninstallColormap (dpy, current_window()->colormap); XInstallColormap (dpy, s->def_cmap); XMapWindow (dpy, s->input_window); XRaiseWindow (dpy, s->input_window); XClearWindow (dpy, s->input_window); /* Switch focus to our input window to read the next key events. */ XGetInputFocus (dpy, &focus, &revert); set_window_focus (s->input_window); XSync (dpy, False); update_input_window (s, line); while (!done) { read_key (&ch, &modifier, keysym_buf, sizeof (keysym_buf)); modifier = x11_mask_to_rp_mask (modifier); PRINT_DEBUG (("ch = %ld, modifier = %d, keysym_buf = %s", ch, modifier, keysym_buf)); status = execute_edit_action (line, ch, modifier, keysym_buf); switch (status) { case EDIT_COMPLETE: case EDIT_DELETE: case EDIT_INSERT: case EDIT_MOVE: /* If the text changed (and we didn't just complete something) then set the virgin bit. */ if (status != EDIT_COMPLETE) line->compl->virgin = 1; /* In all cases, we need to redisplay the input string. */ update_input_window (s, line); break; case EDIT_NO_OP: ring_bell (); break; case EDIT_ABORT: final_input = NULL; done = 1; break; case EDIT_DONE: final_input = xstrdup (line->buffer); done = 1; break; default: PRINT_ERROR (("Unhandled status %d; this is a *BUG*\n", status)); exit (EXIT_FAILURE); } } /* Clean up our line structure */ input_line_free (line); /* Revert focus. */ set_window_focus (focus); XUnmapWindow (dpy, s->input_window); /* Possibly restore colormap. */ if (current_window()) { XUninstallColormap (dpy, s->def_cmap); XInstallColormap (dpy, current_window()->colormap); } return final_input; }
/* Get a string of input at the statusbar prompt. This should only be * called from do_prompt(). */ functionptrtype get_prompt_string(int *actual, bool allow_tabs, #ifndef DISABLE_TABCOMP bool allow_files, bool *list, #endif const char *curranswer, #ifndef DISABLE_HISTORIES linestruct **history_list, #endif void (*refresh_func)(void)) { int kbinput = ERR; bool ran_func, finished; size_t curranswer_len; functionptrtype func; #ifndef DISABLE_TABCOMP bool tabbed = FALSE; /* Whether we've pressed Tab. */ #endif #ifndef DISABLE_HISTORIES char *history = NULL; /* The current history string. */ char *magichistory = NULL; /* The temporary string typed at the bottom of the history, if * any. */ #ifndef DISABLE_TABCOMP int last_kbinput = ERR; /* The key we pressed before the current key. */ size_t complete_len = 0; /* The length of the original string that we're trying to * tab complete, if any. */ #endif #endif /* !DISABLE_HISTORIES */ answer = mallocstrcpy(answer, curranswer); curranswer_len = strlen(answer); /* If reset_statusbar_x is TRUE, restore statusbar_x and * statusbar_pww to what they were before this prompt. Then, if * statusbar_x is uninitialized or past the end of curranswer, put * statusbar_x at the end of the string and update statusbar_pww * based on it. We do these things so that the cursor position * stays at the right place if a prompt-changing toggle is pressed, * or if this prompt was started from another prompt and we cancel * out of it. */ if (reset_statusbar_x) { statusbar_x = old_statusbar_x; statusbar_pww = old_pww; } if (statusbar_x == (size_t)-1 || statusbar_x > curranswer_len) { statusbar_x = curranswer_len; statusbar_pww = statusbar_xplustabs(); } #ifdef DEBUG fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %lu\n", answer, (unsigned long) statusbar_x); #endif update_statusbar_line(answer, statusbar_x); /* Refresh the edit window and the statusbar before getting * input. */ wnoutrefresh(edit); wnoutrefresh(bottomwin); /* If we're using restricted mode, we aren't allowed to change the * name of the current file once it has one, because that would * allow writing to files not specified on the command line. In * this case, disable all keys that would change the text if the * filename isn't blank and we're at the "Write File" prompt. */ while (TRUE) { kbinput = do_statusbar_input(&ran_func, &finished, refresh_func); assert(statusbar_x <= strlen(answer)); #ifndef NANO_TINY if (kbinput == KEY_WINCH) { refresh_func(); update_statusbar_line(answer, statusbar_x); continue; } #endif func = func_from_key(&kbinput); if (func == do_cancel || func == do_enter_void) break; #ifndef DISABLE_TABCOMP if (func != do_tab) tabbed = FALSE; if (func == do_tab) { #ifndef DISABLE_HISTORIES if (history_list != NULL) { if (last_kbinput != sc_seq_or(do_tab, NANO_CONTROL_I)) complete_len = strlen(answer); if (complete_len > 0) { answer = mallocstrcpy(answer, get_history_completion(history_list, answer, complete_len)); statusbar_x = strlen(answer); } } else #endif if (allow_tabs) answer = input_tab(answer, allow_files, &statusbar_x, &tabbed, refresh_func, list); update_statusbar_line(answer, statusbar_x); } else #endif /* !DISABLE_TABCOMP */ #ifndef DISABLE_HISTORIES if (func == get_history_older_void) { if (history_list != NULL) { /* If we're scrolling up at the bottom of the history list * and answer isn't blank, save answer in magichistory. */ if ((*history_list)->next == NULL && answer[0] != '\0') magichistory = mallocstrcpy(magichistory, answer); /* Get the older search from the history list and save it in * answer. If there is no older search, don't do anything. */ if ((history = get_history_older(history_list)) != NULL) { answer = mallocstrcpy(answer, history); statusbar_x = strlen(answer); } update_statusbar_line(answer, statusbar_x); /* This key has a shortcut-list entry when it's used to * move to an older search, which means that finished has * been set to TRUE. Set it back to FALSE here, so that * we aren't kicked out of the statusbar prompt. */ finished = FALSE; } } else if (func == get_history_newer_void) { if (history_list != NULL) { /* Get the newer search from the history list and save it in * answer. If there is no newer search, don't do anything. */ if ((history = get_history_newer(history_list)) != NULL) { answer = mallocstrcpy(answer, history); statusbar_x = strlen(answer); } /* If, after scrolling down, we're at the bottom of the * history list, answer is blank, and magichistory is set, * save magichistory in answer. */ if ((*history_list)->next == NULL && *answer == '\0' && magichistory != NULL) { answer = mallocstrcpy(answer, magichistory); statusbar_x = strlen(answer); } update_statusbar_line(answer, statusbar_x); /* This key has a shortcut-list entry when it's used to * move to a newer search, which means that finished has * been set to TRUE. Set it back to FALSE here, so that * we aren't kicked out of the statusbar prompt. */ finished = FALSE; } } else #endif /* !DISABLE_HISTORIES */ if (func == do_help_void) { update_statusbar_line(answer, statusbar_x); /* This key has a shortcut-list entry when it's used to go to * the help browser or display a message indicating that help * is disabled, which means that finished has been set to TRUE. * Set it back to FALSE here, so that we aren't kicked out of * the statusbar prompt. */ finished = FALSE; } /* If we have a shortcut with an associated function, break out if * we're finished after running or trying to run the function. */ if (finished) break; #if !defined(DISABLE_HISTORIES) && !defined(DISABLE_TABCOMP) last_kbinput = kbinput; #endif reset_statusbar_cursor(); wnoutrefresh(bottomwin); } #ifndef DISABLE_HISTORIES /* Set the current position in the history list to the bottom, * and free magichistory if we need to. */ if (history_list != NULL) { history_reset(*history_list); free(magichistory); } #endif /* We've finished putting in an answer or run a normal shortcut's * associated function, so reset statusbar_x and statusbar_pww. If * we've finished putting in an answer, reset the statusbar cursor * position too. */ if (func) { if (func == do_cancel || func == do_enter_void || ran_func) { statusbar_x = old_statusbar_x; statusbar_pww = old_pww; if (!ran_func) reset_statusbar_x = TRUE; /* Otherwise, we're still putting in an answer or a shortcut with * an associated function, so leave the statusbar cursor position * alone. */ } else reset_statusbar_x = FALSE; } *actual = kbinput; return func; }
void recv_boot_init(struct recv_boot *boot, const struct recv_model *m, const struct message *msgs, size_t nmsg, dsfmt_t * dsfmt) { size_t nsend = recv_model_send_count(m); size_t j, nrecv = recv_model_count(m); const struct design *r = recv_model_design(m); const struct design2 *d = recv_model_design2(m); struct history *hr = design_history(r); struct history *hd = design2_history(d); size_t imsg; size_t max_nto = nrecv; size_t *to = xcalloc(max_nto, sizeof(to[0])); double *p = xmalloc(nrecv * sizeof(p[0])); size_t maxntry = 100000000; history_init(&boot->history, nsend, nrecv); for (imsg = 0; imsg < nmsg; imsg++) { const struct message *msg = &msgs[imsg]; double t = msg->time; size_t from = msg->from; size_t nto = msg->nto; if (t < history_time(hr)) { history_reset(hr); } history_advance(hr, t); if (t < history_time(hd)) { history_reset(hd); } history_advance(hd, t); memset(p, 0, nrecv * sizeof(p[0])); axpy_probs(1.0, m, from, p); if (!sample_subset(p, nrecv, dsfmt, maxntry, to, nto)) { fprintf(stdout, "Failed to sample subset of size %zu\n", nto); fprintf(stderr, "Failed to sample subset of size %zu\n", nto); printf("probs:\n"); for (j = 0; j < nrecv; j++) { printf("%.10e, ", p[j]); } exit(1); } if (t < history_time(&boot->history)) { history_reset(&boot->history); } history_advance(&boot->history, t); history_add(&boot->history, from, to, nto, msg->attr); } free(p); free(to); }