static void read_cb(Stream *stream, RBuffer *buf, void *data, bool at_eof) { if (at_eof) { input_eof = true; } assert(rbuffer_space(input_buffer) >= rbuffer_size(buf)); RBUFFER_UNTIL_EMPTY(buf, ptr, len) { (void)rbuffer_write(input_buffer, ptr, len); rbuffer_consumed(buf, len); }
size_t input_enqueue(String keys) { char *ptr = keys.data; char *end = ptr + keys.size; while (rbuffer_space(input_buffer) >= 6 && ptr < end) { uint8_t buf[6] = { 0 }; unsigned int new_size = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true, true); if (new_size) { new_size = handle_mouse_event(&ptr, buf, new_size); rbuffer_write(input_buffer, (char *)buf, new_size); continue; } if (*ptr == '<') { char *old_ptr = ptr; // Invalid or incomplete key sequence, skip until the next '>' or *end. do { ptr++; } while (ptr < end && *ptr != '>'); if (*ptr != '>') { // Incomplete key sequence, return without consuming. ptr = old_ptr; break; } ptr++; continue; } // copy the character, escaping CSI and K_SPECIAL if ((uint8_t)*ptr == CSI) { rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1); rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1); rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1); } else if ((uint8_t)*ptr == K_SPECIAL) { rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1); rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1); rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1); } else { rbuffer_write(input_buffer, ptr, 1); } ptr++; } size_t rv = (size_t)(ptr - keys.data); process_interrupts(); return rv; }