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

@@ -137,14 +137,17 @@ static void on_video_node(
uint8_t pflags, uint8_t is_capture,
void *ud)
{
(void)eflags; (void)pflags; (void)ud;
(void)eflags; (void)pflags;
int *idx = ud;
char caps[128];
caps_str(dcaps, caps, sizeof(caps));
printf(" video %.*s entity=%.*s type=0x%08x caps=[%s]%s\n",
printf(" [%d] video %.*s entity=%.*s type=0x%08x caps=[%s]%s\n",
*idx,
(int)path_len, path,
(int)ename_len, ename,
etype, caps,
is_capture ? " [capture]" : "");
(*idx)++;
}
static void on_standalone(
@@ -152,10 +155,12 @@ static void on_standalone(
const char *name, uint8_t name_len,
void *ud)
{
(void)ud;
printf(" standalone %.*s card=%.*s\n",
int *idx = ud;
printf(" [%d] standalone %.*s card=%.*s\n",
*idx,
(int)path_len, path,
(int)name_len, name);
(*idx)++;
}
static const char *scale_name(uint8_t s)
@@ -170,6 +175,7 @@ static const char *scale_name(uint8_t s)
}
static void on_display(
uint16_t device_id,
uint16_t stream_id,
int16_t win_x, int16_t win_y,
uint16_t win_w, uint16_t win_h,
@@ -177,8 +183,8 @@ static void on_display(
void *ud)
{
(void)ud;
printf(" display stream=%u pos=%d,%d size=%ux%u scale=%s anchor=%s\n",
stream_id, win_x, win_y, win_w, win_h,
printf(" [%u] display stream=%u pos=%d,%d size=%ux%u scale=%s anchor=%s\n",
device_id, stream_id, win_x, win_y, win_w, win_h,
scale_name(scale),
anchor == 0 ? "center" : "topleft");
}
@@ -231,9 +237,10 @@ static void on_frame(struct Transport_Conn *conn,
switch (cs->pending_cmd) {
case PROTO_CMD_ENUM_DEVICES: {
struct Proto_Response_Header hdr;
int dev_idx = 0;
struct App_Error e = proto_read_enum_devices_response(
frame->payload, frame->payload_length, &hdr,
on_media_device, on_video_node, on_standalone, on_display, NULL);
on_media_device, on_video_node, on_standalone, on_display, &dev_idx);
if (!APP_IS_OK(e)) { app_error_print(&e); }
else if (hdr.status != PROTO_STATUS_OK) {
fprintf(stderr, "ENUM_DEVICES: status=%u\n", hdr.status);