Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sensors): always prefer greater sysnum cameras (ie: external ones) when present #101

Merged
merged 2 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
- [x] fix KWin_wl
- [x] update wiki pages (new object path + wlroots as default under `Wl` obj path)

### Camera
- [x] always prefer greater sysnum cameras (ie: external ones) when present (refs https://github.com/FedeDP/Clight/issues/241)
- [x] properly enumerate filtering by correct `ID_V4L_CAPABILITIES` being available (ie: `:capture:`)

### Generic
- [x] port CI to gh actions

Expand Down
2 changes: 1 addition & 1 deletion src/modules/sensors/als.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static void fetch_dev(const char *interface, void **dev) {
/* Check if any device exposes requested sysattr */
for (int i = 0; i < SIZE(ill_names) && !*dev; i++) {
/* Only check existence for needed sysattr */
const udev_match match = { ill_names[i] };
const udev_match match = { .sysattr_key = ill_names[i] };
get_udev_device(interface, ALS_SUBSYSTEM, &match, NULL, (struct udev_device **)dev);
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/modules/sensors/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#define CAMERA_NAME "Camera"
#define CAMERA_SUBSYSTEM "video4linux"
#define CAMERA_CAPTURE_PROP_NAME "ID_V4L_CAPABILITIES"
#define CAMERA_CAPTURE_PROP_VAL ":capture:"

struct buffer {
uint8_t *start;
Expand Down Expand Up @@ -63,7 +65,11 @@ static bool validate_dev(void *dev) {
}

static void fetch_dev(const char *interface, void **dev) {
get_udev_device(interface, CAMERA_SUBSYSTEM, NULL, NULL, (struct udev_device **)dev);
// Note: we only filer cameras with capture prop val,
// and always start from greater sysnum (so that /dev/video2 has precedence over /dev/video0, when present).
// This means that external webcam are always preferred to internal ones,
// as they tend to have better resolution and increased image quality.
get_udev_device(interface, CAMERA_SUBSYSTEM, &(udev_match){.prop_key=CAMERA_CAPTURE_PROP_NAME, .prop_val=CAMERA_CAPTURE_PROP_VAL, .last_added = true}, NULL, (struct udev_device **)dev);
}

static void fetch_props_dev(void *dev, const char **node, const char **action) {
Expand Down
2 changes: 1 addition & 1 deletion src/modules/sensors/yoctolight.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ static bool validate_dev(void *dev) {
}

static void fetch_dev(const char *interface, void **dev) {
const udev_match match = { YOCTO_PROPERTY, YOCTO_VENDORID };
const udev_match match = { .sysattr_key = YOCTO_PROPERTY, .sysattr_val = YOCTO_VENDORID };
get_udev_device(interface, YOCTO_SUBSYSTEM, &match, NULL, (struct udev_device **)dev);
}

Expand Down
35 changes: 32 additions & 3 deletions src/utils/udev.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,43 @@ static void get_first_matching_device(struct udev_device **dev, const char *subs
const udev_match *match) {
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, subsystem);
bool last_added =false;
if (match) {
udev_enumerate_add_match_sysattr(enumerate, match->sysattr_key, match->sysattr_val);
if (match->sysattr_key) {
udev_enumerate_add_match_sysattr(enumerate, match->sysattr_key, match->sysattr_val);
}
if (match->prop_key) {
udev_enumerate_add_match_property(enumerate, match->prop_key, match->prop_val);
}
last_added = match->last_added;
}
udev_enumerate_scan_devices(enumerate);
struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
if (devices) {
const char *path = udev_list_entry_get_name(devices);
*dev = udev_device_new_from_syspath(udev, path);
if (!last_added) {
// Return first found
const char *path = udev_list_entry_get_name(devices);
*dev = udev_device_new_from_syspath(udev, path);
} else {
// Return last found, ie: the one with greatest index
*dev = NULL;
struct udev_list_entry *entry = NULL;
int max_sysnum = -1;
udev_list_entry_foreach(entry, devices) {
const char *path = udev_list_entry_get_name(entry);
struct udev_device *d = udev_device_new_from_syspath(udev, path);
int sysnum = atoi(udev_device_get_sysnum(d));
if (sysnum > max_sysnum) {
if (*dev) {
udev_device_unref(*dev);
}
*dev = d;
max_sysnum = sysnum;
} else {
udev_device_unref(d);
}
}
}
}
/* Free the enumerator object */
udev_enumerate_unref(enumerate);
Expand Down
3 changes: 3 additions & 0 deletions src/utils/udev.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ typedef struct {
const char *sysattr_key;
const char *sysattr_val;
const char *sysname;
const char *prop_key;
const char *prop_val;
bool last_added;
} udev_match;

int init_udev_monitor(const char *subsystem, struct udev_monitor **mon);
Expand Down