void menu::render(size_t i, bool replace) { auto size = current_size(); if(i < 0 || i >= size) { return; } auto &item = current_at(i); IDType id; if(replace) { itemDtors.at(i) = engine->add(id); } else { itemDtors.emplace_back(engine->add(id)); } Decimal scale = glm::min(actual_height() / Decimal(size), actual_scale()); Decimal spacing = uiTextHeight * scale; Point2 origin = Point2(60, 50 + spacing * (size - i - 1)); engine->add<component::text>(id, font, item.value); engine->add<component::screenposition>(id, origin); engine->add<component::scale>(id, Point3(scale)); if(int(i) == current) { engine->add<component::color>(id, Point4(1, 1, selectionAlpha, 1)); } if(item.control) { IDType controlID; auto offset = Point2(uiTextWidth / uiBase * scale, 0); offset.y -= 12 * scale; controlDtors[(int)i] = item.control->render(engine, controlID, origin + offset, 8 * scale); } }
void menu::navigate_to(int to) { if(to == current) { return; } debugmanager()->debug(to, ' ', current); auto sz = current_size(); auto previous = current; current = to; if(current < 0) { current += sz; } else { current %= sz; } render(previous, true); beep(); }
void menu::on_cursor(int y) { auto size = current_size(); auto scale = glm::min(actual_height() / Decimal(size), actual_scale()); auto spacing = uiTextHeight * scale; auto height = engine->get<renderer::base>().lock()->getheight(); auto origin = height - y; /* origin = 50 + spacing * (size - i - 1); * spacing * (size - i - 1) = origin - 50 * size - i - 1 = (origin - 50) / spacing * i = size - (origin - 50) / spacing - 1 */ auto i = int(glm::floor(size - (origin - 50) / spacing)); if(i >= 0 && i < int(size)) { navigate_to(i); } }
static void tape_rdwr_request(struct scsi_cmd *cmd) { struct ssc_info *ssc = dtype_priv(cmd->dev); struct blk_header_info *h = &ssc->c_blk; int ret, code; uint32_t length, i, transfer_length, residue; int result = SAM_STAT_GOOD; uint8_t *buf; int32_t count; int8_t fixed; int8_t sti; uint32_t block_length = ssc_get_block_length(cmd->dev); ret = 0; length = 0; i = 0; transfer_length = 0; residue = 0; code = 0; ssc = dtype_priv(cmd->dev); switch (cmd->scb[0]) { case REZERO_UNIT: dprintf("**** Rewind ****\n"); if (resp_rewind(cmd->dev)) { sense_data_build(cmd, MEDIUM_ERROR, ASC_SEQUENTIAL_POSITION_ERR); result = SAM_STAT_CHECK_CONDITION; } break; case WRITE_FILEMARKS: ret = get_unaligned_be24(&cmd->scb[2]); dprintf("*** Write %d filemark%s ***\n", ret, ((ret > 1) || (ret < 0)) ? "s" : ""); for (i = 0; i < ret; i++) append_blk(cmd, scsi_get_out_buffer(cmd), 0, 0, BLK_FILEMARK); fsync(cmd->dev->fd); break; case READ_6: fixed = cmd->scb[1] & 1; sti = cmd->scb[1] & 2; if (fixed && sti) { sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB); result = SAM_STAT_CHECK_CONDITION; break; } length = scsi_get_in_length(cmd); count = get_unaligned_be24(&cmd->scb[2]); buf = scsi_get_in_buffer(cmd); dprintf("*** READ_6: length %d, count %d, fixed block %s," " %" PRIu64 " %d\n", length, count, (fixed) ? "Yes" : "No", h->curr, sti); if (fixed) result = resp_fixed_read(cmd, buf, length, &ret); else result = resp_var_read(cmd, buf, length, &ret); eprintf("Executed READ_6, Read %d bytes, %" PRIu64 "\n", ret, h->curr); break; case WRITE_6: fixed = cmd->scb[1] & 1; buf = scsi_get_out_buffer(cmd); count = get_unaligned_be24(&cmd->scb[2]); length = scsi_get_out_length(cmd); if (!fixed) { block_length = length; count = 1; } for (i = 0, ret = 0; i < count; i++) { if (append_blk(cmd, buf, block_length, block_length, BLK_UNCOMPRESS_DATA)) { sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR); result = SAM_STAT_CHECK_CONDITION; break; } buf += block_length; ret += block_length; } dprintf("*** WRITE_6 count: %d, length: %d, ret: %d, fixed: %s," " ssc->blk_sz: %d\n", count, length, ret, (fixed) ? "Yes" : "No", block_length); /* Check for end of media */ if (current_size(cmd) > ssc->mam.max_capacity) { sense_data_build(cmd, NO_SENSE|SENSE_EOM, NO_ADDITIONAL_SENSE); result = SAM_STAT_CHECK_CONDITION; break; } if (ret != length) { sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR); result = SAM_STAT_CHECK_CONDITION; } break; case SPACE: code = cmd->scb[1] & 0xf; count = be24_to_2comp(&cmd->scb[2]); if (code == 0) { /* Logical Blocks */ result = space_blocks(cmd, count); break; } else if (code == 1) { /* Filemarks */ result = space_filemark(cmd, count); break; } else if (code == 3) { /* End of data */ while (h->blk_type != BLK_EOD) if (skip_next_header(cmd->dev)) { sense_data_build(cmd, MEDIUM_ERROR, ASC_MEDIUM_FORMAT_CORRUPT); result = SAM_STAT_CHECK_CONDITION; break; } } else { /* Unsupported */ sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB); result = SAM_STAT_CHECK_CONDITION; } break; case READ_POSITION: { int service_action = cmd->scb[1] & 0x1f; uint8_t *data = scsi_get_in_buffer(cmd); int len = scsi_get_in_length(cmd); dprintf("Size of in_buffer = %d\n", len); dprintf("Sizeof(buf): %zd\n", sizeof(buf)); dprintf("service action: 0x%02x\n", service_action); if (service_action == 0) { /* Short form - block ID */ memset(data, 0, 20); data[0] = 20; } else if (service_action == 1) { /* Short form - vendor uniq */ memset(data, 0, 20); data[0] = 20; } else if (service_action == 6) { /* Long form */ memset(data, 0, 32); data[0] = 32; } else { sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB); result = SAM_STAT_CHECK_CONDITION; } break; } default: eprintf("Unknown op code - should never see this\n"); sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE); result = SAM_STAT_CHECK_CONDITION; break; } dprintf("io done %p %x %d %u\n", cmd, cmd->scb[0], ret, length); scsi_set_result(cmd, result); if (result != SAM_STAT_GOOD) eprintf("io error %p %x %d %d %" PRIu64 ", %m\n", cmd, cmd->scb[0], ret, length, cmd->offset); }