/* * Look up the canonical ID for a queue */ Pipe::message_id Pipe::get_message_no(const std::string& func_name, message_id msg) const { if(msg == DEFAULT_MESSAGE) msg = default_msg(); else if(msg == LAST_MESSAGE) msg = message_count() - 1; if(msg >= message_count()) throw Invalid_Message_Number(func_name, msg); return msg; }
/* * Get a particular output queue */ SecureQueue* Output_Buffers::get(Pipe::message_id msg) const { if(msg < m_offset) return nullptr; BOTAN_ASSERT(msg < message_count(), "Message number is in range"); return m_buffers[msg-m_offset]; }
/* * Set the default read message */ void Pipe::set_default_msg(message_id msg) { if(msg >= message_count()) throw Invalid_Argument("Pipe::set_default_msg: msg number is too high"); default_read = msg; }
/* * Show previous messages to the user * * The screen format uses line 0 and 23 for headers and prompts, * skips line 1 and 22, and uses line 2 thru 21 for old messages. * * This command shows you which commands you are viewing, and allows * you to "search" for strings in the recall. * * Note that messages may be longer than 80 characters, but they are * displayed using "infinite" length, with a special sub-command to * "slide" the virtual display to the left or right. * * Attempt to only highlight the matching portions of the string. */ void do_cmd_messages(void) { ui_event ke; bool more = TRUE; int i, j, n, q; int wid, hgt; char shower[80] = ""; /* Total messages */ n = messages_num(); /* Start on first message */ i = 0; /* Start at leftmost edge */ q = 0; /* Get size */ Term_get_size(&wid, &hgt); /* Save screen */ screen_save(); /* Process requests until done */ while (more) { /* Clear screen */ Term_clear(); /* Dump messages */ for (j = 0; (j < hgt - 4) && (i + j < n); j++) { const char *msg; const char *str = message_str(i + j); byte attr = message_color(i + j); u16b count = message_count(i + j); if (count == 1) msg = str; else msg = format("%s <%dx>", str, count); /* Apply horizontal scroll */ msg = ((int)strlen(msg) >= q) ? (msg + q) : ""; /* Dump the messages, bottom to top */ Term_putstr(0, hgt - 3 - j, -1, attr, msg); /* Highlight "shower" */ if (shower[0]) { str = msg; /* Display matches */ while ((str = my_stristr(str, shower)) != NULL) { int len = strlen(shower); /* Display the match */ Term_putstr(str-msg, hgt - 3 - j, len, TERM_YELLOW, str); /* Advance */ str += len; } } } /* Display header */ prt(format("Message recall (%d-%d of %d), offset %d", i, i + j - 1, n, q), 0, 0); /* Display prompt (not very informative) */ if (shower[0]) prt("[Movement keys to navigate, '-' for next, '=' to find]", hgt - 1, 0); else prt("[Movement keys to navigate, '=' to find, or ESCAPE to exit]", hgt - 1, 0); /* Get a command */ ke = inkey_ex(); /* Scroll forwards or backwards using mouse clicks */ if (ke.type == EVT_MOUSE) { if (ke.mouse.y <= hgt / 2) { /* Go older if legal */ if (i + 20 < n) i += 20; } else { /* Go newer */ i = (i >= 20) ? (i - 20) : 0; } } else if (ke.type == EVT_KBRD) { switch (ke.key.code) { case ESCAPE: { more = FALSE; break; } case '=': { /* Get the string to find */ prt("Find: ", hgt - 1, 0); if (!askfor_aux(shower, sizeof shower, NULL)) continue; /* Set to find */ ke.key.code = '-'; break; } case ARROW_LEFT: case '4': q = (q >= wid / 2) ? (q - wid / 2) : 0; break; case ARROW_RIGHT: case '6': q = q + wid / 2; break; case ARROW_UP: case '8': if (i + 1 < n) i += 1; break; case ARROW_DOWN: case '2': case '\r': case '\n': i = (i >= 1) ? (i - 1) : 0; break; case KC_PGUP: case 'p': case ' ': if (i + 20 < n) i += 20; break; case KC_PGDOWN: case 'n': i = (i >= 20) ? (i - 20) : 0; break; } } /* Find the next item */ if (ke.key.code == '-' && shower[0]) { s16b z; /* Scan messages */ for (z = i + 1; z < n; z++) { /* Search for it */ if (my_stristr(message_str(z), shower)) { /* New location */ i = z; /* Done */ break; } } } } /* Load screen */ screen_load(); }