Display device controls; device IDs in enum-devices; fix non-OK parse

Display controls (enum/get/set):
- Add PROTO_DISPLAY_CTRL_SCALE/ANCHOR/NO_SIGNAL_FPS constants to protocol.h
- handle_enum_controls: if device index maps to an active display slot,
  return the three display controls (scale, anchor, no_signal_fps)
- handle_get_control: read display control values from slot under mutex
- handle_set_control: write display control values to slot under mutex;
  scale/anchor are applied to the viewer by display_loop_tick each tick

Device IDs in enum-devices output:
- Proto_Display_Device_Info gains device_id field (wire format +2 bytes)
- handle_enum_devices computes device_id = total_v4l2 + display_index
- on_video_node/on_standalone callbacks take int* userdata to print [idx]
- on_display prints [device_id] from the wire field

Bug fix — protocol error on invalid device index:
- proto_read_enum_controls_response: early-return APP_OK after reading
  status if status != OK; error responses have no count/data fields, so
  the CUR_CHECK on count was failing with "payload too short"

Helpers added to main.c:
- count_v4l2_devices(): sum of media vnodes + standalone
- find_display_by_device_idx(): maps flat index to Display_Slot

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 22:02:42 +00:00
parent 1066f793e2
commit 8c4cd69443
4 changed files with 155 additions and 11 deletions

View File

@@ -414,6 +414,7 @@ struct App_Error proto_write_enum_devices_response(struct Transport_Conn *conn,
e = wbuf_u16(&b, display_count); if (!APP_IS_OK(e)) { goto fail; }
for (uint16_t i = 0; i < display_count; i++) {
const struct Proto_Display_Device_Info *d = &displays[i];
e = wbuf_u16(&b, d->device_id); if (!APP_IS_OK(e)) { goto fail; }
e = wbuf_u16(&b, d->stream_id); if (!APP_IS_OK(e)) { goto fail; }
e = wbuf_i16(&b, d->win_x); if (!APP_IS_OK(e)) { goto fail; }
e = wbuf_i16(&b, d->win_y); if (!APP_IS_OK(e)) { goto fail; }
@@ -791,6 +792,7 @@ struct App_Error proto_read_enum_devices_response(
uint16_t display_count = cur_u16(&c);
CUR_CHECK(c);
for (uint16_t i = 0; i < display_count; i++) {
uint16_t device_id = cur_u16(&c);
uint16_t stream_id = cur_u16(&c);
int16_t win_x = (int16_t)cur_u16(&c);
int16_t win_y = (int16_t)cur_u16(&c);
@@ -800,7 +802,7 @@ struct App_Error proto_read_enum_devices_response(
uint8_t anchor = cur_u8(&c);
CUR_CHECK(c);
if (on_display) {
on_display(stream_id, win_x, win_y,
on_display(device_id, stream_id, win_x, win_y,
win_w, win_h, scale, anchor, userdata);
}
}
@@ -830,6 +832,8 @@ struct App_Error proto_read_enum_controls_response(
header_out->request_id = cur_u16(&c);
header_out->status = cur_u16(&c);
CUR_CHECK(c);
if (header_out->status != PROTO_STATUS_OK) { return APP_OK; }
uint16_t count = cur_u16(&c);
CUR_CHECK(c);