On recent kernels, backlight directory does not contain information about the device, but rather about the connector. In this case, matching device pci_id and connector device doesn't work.
This patch makes use of connector name, checks if the connector directory is present in the device's /sys path and matches it to the correct backlight interface, if any. It also fixes the safe_strtoint usage, so it doesn't fail when newline is present. Signed-off-by: Armin Krezović <[email protected]> --- Makefile.am | 8 +++-- libweston/compositor-drm.c | 49 ++++-------------------------- libweston/libbacklight.c | 31 +++++++++++++------ libweston/libbacklight.h | 1 + libweston/weston-drm-helpers.c | 48 ++++++++++++++++++++++++++++++ libweston/weston-drm-helpers.h | 67 ++++++++++++++++++++++++++++++++++++++++++ tests/setbacklight.c | 28 ++++++++++++------ 7 files changed, 169 insertions(+), 63 deletions(-) create mode 100644 libweston/weston-drm-helpers.c create mode 100644 libweston/weston-drm-helpers.h diff --git a/Makefile.am b/Makefile.am index cdf82ab4..f9a72319 100644 --- a/Makefile.am +++ b/Makefile.am @@ -378,7 +378,9 @@ drm_backend_la_SOURCES = \ shared/helpers.h \ shared/timespec-util.h \ libweston/libbacklight.c \ - libweston/libbacklight.h + libweston/libbacklight.h \ + libweston/weston-drm-helpers.c \ + libweston/weston-drm-helpers.h if ENABLE_VAAPI_RECORDER drm_backend_la_SOURCES += libweston/vaapi-recorder.c libweston/vaapi-recorder.h @@ -1465,7 +1467,9 @@ noinst_PROGRAMS += setbacklight setbacklight_SOURCES = \ tests/setbacklight.c \ libweston/libbacklight.c \ - libweston/libbacklight.h + libweston/libbacklight.h \ + libweston/weston-drm-helpers.c \ + libweston/weston-drm-helpers.h setbacklight_CFLAGS = $(AM_CFLAGS) $(SETBACKLIGHT_CFLAGS) setbacklight_LDADD = $(SETBACKLIGHT_LIBS) endif diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 2a80c6d7..418bd600 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -53,6 +53,7 @@ #include "shared/timespec-util.h" #include "gl-renderer.h" #include "weston-egl-ext.h" +#include "weston-drm-helpers.h" #include "pixman-renderer.h" #include "libbacklight.h" #include "libinput-seat.h" @@ -1798,45 +1799,6 @@ drm_set_dpms(struct weston_output *output_base, enum dpms_enum level) output->dpms = level; } -static const char * const connector_type_names[] = { - [DRM_MODE_CONNECTOR_Unknown] = "Unknown", - [DRM_MODE_CONNECTOR_VGA] = "VGA", - [DRM_MODE_CONNECTOR_DVII] = "DVI-I", - [DRM_MODE_CONNECTOR_DVID] = "DVI-D", - [DRM_MODE_CONNECTOR_DVIA] = "DVI-A", - [DRM_MODE_CONNECTOR_Composite] = "Composite", - [DRM_MODE_CONNECTOR_SVIDEO] = "SVIDEO", - [DRM_MODE_CONNECTOR_LVDS] = "LVDS", - [DRM_MODE_CONNECTOR_Component] = "Component", - [DRM_MODE_CONNECTOR_9PinDIN] = "DIN", - [DRM_MODE_CONNECTOR_DisplayPort] = "DP", - [DRM_MODE_CONNECTOR_HDMIA] = "HDMI-A", - [DRM_MODE_CONNECTOR_HDMIB] = "HDMI-B", - [DRM_MODE_CONNECTOR_TV] = "TV", - [DRM_MODE_CONNECTOR_eDP] = "eDP", -#ifdef DRM_MODE_CONNECTOR_DSI - [DRM_MODE_CONNECTOR_VIRTUAL] = "Virtual", - [DRM_MODE_CONNECTOR_DSI] = "DSI", -#endif -}; - -static char * -make_connector_name(const drmModeConnector *con) -{ - char name[32]; - const char *type_name = NULL; - - if (con->connector_type < ARRAY_LENGTH(connector_type_names)) - type_name = connector_type_names[con->connector_type]; - - if (!type_name) - type_name = "UNNAMED"; - - snprintf(name, sizeof name, "%s-%d", type_name, con->connector_type_id); - - return strdup(name); -} - static int find_crtc_for_connector(struct drm_backend *b, drmModeRes *resources, drmModeConnector *connector) @@ -2610,18 +2572,19 @@ create_output_for_connector(struct drm_backend *b, output->pipe = i; output->connector_id = connector->connector_id; - output->backlight = backlight_init(drm_device, - connector->connector_type); - output->base.enable = drm_output_enable; output->base.destroy = drm_output_destroy; output->base.disable = drm_output_disable; - output->base.name = make_connector_name(connector); + output->base.name = weston_make_drm_connector_name(connector); output->destroy_pending = 0; output->disable_pending = 0; output->original_crtc = NULL; + output->backlight = backlight_init(drm_device, + output->base.name, + connector->connector_type); + weston_output_init(&output->base, b->compositor); weston_compositor_add_pending_output(&output->base, b->compositor); diff --git a/libweston/libbacklight.c b/libweston/libbacklight.c index 4bbc6db4..da627abc 100644 --- a/libweston/libbacklight.c +++ b/libweston/libbacklight.c @@ -67,6 +67,9 @@ static long backlight_get(struct backlight *backlight, char *node) goto out; } + if (buffer[ret - 1] == '\n') + buffer[ret - 1] = '\0'; + if (!safe_strtoint(buffer, &value)) { ret = -1; goto out; @@ -151,10 +154,12 @@ void backlight_destroy(struct backlight *backlight) } struct backlight *backlight_init(struct udev_device *drm_device, + const char *connector_name, uint32_t connector_type) { const char *syspath = NULL; - char *pci_name = NULL; + char *connector = NULL; + char *connector_path = NULL; char *chosen_path = NULL; char *path = NULL; DIR *backlights = NULL; @@ -171,16 +176,20 @@ struct backlight *backlight_init(struct udev_device *drm_device, if (!syspath) return NULL; - if (asprintf(&path, "%s/%s", syspath, "device") < 0) + if (asprintf(&connector, "%s-%s", basename(syspath), connector_name) < 0) return NULL; - ret = readlink(path, buffer, sizeof(buffer) - 1); - free(path); - if (ret < 0) - return NULL; + if (asprintf(&connector_path, "%s/%s", syspath, connector) < 0) + goto err_conn; + + backlights = opendir(connector_path); + free(connector_path); - buffer[ret] = '\0'; - pci_name = basename(buffer); + if (!backlights) + goto err_conn; + + closedir(backlights); + backlights = NULL; if (connector_type <= 0) return NULL; @@ -271,7 +280,7 @@ struct backlight *backlight_init(struct udev_device *drm_device, platform backlights have to be assumed to match */ if (entry_type == BACKLIGHT_RAW || entry_type == BACKLIGHT_FIRMWARE) { - if (!(pci_name && !strcmp(pci_name, parent))) + if (!(connector && !strcmp(connector, parent))) goto out; } @@ -309,10 +318,14 @@ struct backlight *backlight_init(struct udev_device *drm_device, goto err; closedir(backlights); + free(connector); + return backlight; err: closedir(backlights); free (chosen_path); free (backlight); +err_conn: + free(connector); return NULL; } diff --git a/libweston/libbacklight.h b/libweston/libbacklight.h index 8717ab10..2a069353 100644 --- a/libweston/libbacklight.h +++ b/libweston/libbacklight.h @@ -55,6 +55,7 @@ struct backlight { * matching drm subsytem and with status of connected. */ struct backlight *backlight_init(struct udev_device *drm_device, + const char *connector_name, uint32_t connector_type); /* Free backlight resources */ diff --git a/libweston/weston-drm-helpers.c b/libweston/weston-drm-helpers.c new file mode 100644 index 00000000..1ab01aca --- /dev/null +++ b/libweston/weston-drm-helpers.c @@ -0,0 +1,48 @@ +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "shared/helpers.h" +#include "weston-drm-helpers.h" + +#include <stdio.h> +#include <xf86drm.h> + +char * +weston_make_drm_connector_name(const drmModeConnector *con) +{ + char name[32]; + const char *type_name = NULL; + + if (con->connector_type < ARRAY_LENGTH(connector_type_names)) + type_name = connector_type_names[con->connector_type]; + + if (!type_name) + type_name = "UNNAMED"; + + snprintf(name, sizeof name, "%s-%d", type_name, con->connector_type_id); + + return strdup(name); +} diff --git a/libweston/weston-drm-helpers.h b/libweston/weston-drm-helpers.h new file mode 100644 index 00000000..41442a3a --- /dev/null +++ b/libweston/weston-drm-helpers.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef WESTON_DRM_HELPERS_H +#define WESTON_DRM_HELPERS_H + +#include <stdint.h> +#include <string.h> +#include <xf86drmMode.h> + +#ifdef __cplusplus +extern "C" { +#endif + +static const char * const connector_type_names[] = { + [DRM_MODE_CONNECTOR_Unknown] = "Unknown", + [DRM_MODE_CONNECTOR_VGA] = "VGA", + [DRM_MODE_CONNECTOR_DVII] = "DVI-I", + [DRM_MODE_CONNECTOR_DVID] = "DVI-D", + [DRM_MODE_CONNECTOR_DVIA] = "DVI-A", + [DRM_MODE_CONNECTOR_Composite] = "Composite", + [DRM_MODE_CONNECTOR_SVIDEO] = "SVIDEO", + [DRM_MODE_CONNECTOR_LVDS] = "LVDS", + [DRM_MODE_CONNECTOR_Component] = "Component", + [DRM_MODE_CONNECTOR_9PinDIN] = "DIN", + [DRM_MODE_CONNECTOR_DisplayPort] = "DP", + [DRM_MODE_CONNECTOR_HDMIA] = "HDMI-A", + [DRM_MODE_CONNECTOR_HDMIB] = "HDMI-B", + [DRM_MODE_CONNECTOR_TV] = "TV", + [DRM_MODE_CONNECTOR_eDP] = "eDP", +#ifdef DRM_MODE_CONNECTOR_DSI + [DRM_MODE_CONNECTOR_VIRTUAL] = "Virtual", + [DRM_MODE_CONNECTOR_DSI] = "DSI", +#endif +}; + +char * +weston_make_drm_connector_name(const drmModeConnector *con); + +#ifdef __cplusplus +} +#endif + +#endif /* WESTON_DRM_HELPERS_H */ diff --git a/tests/setbacklight.c b/tests/setbacklight.c index 3bfc7d1e..b0f0a6a0 100644 --- a/tests/setbacklight.c +++ b/tests/setbacklight.c @@ -41,12 +41,19 @@ #include <xf86drmMode.h> #include "libbacklight.h" +#include "weston-drm-helpers.h" -static uint32_t -get_drm_connector_type(struct udev_device *drm_device, uint32_t connector_id) +struct setbacklight_connector { + char *name; + uint32_t type; +}; + +static int +get_drm_connector_name_and_type(struct udev_device *drm_device, uint32_t connector_id, + struct setbacklight_connector *c) { const char *filename; - int fd, i, connector_type; + int fd, i; drmModeResPtr res; drmModeConnectorPtr connector; @@ -75,12 +82,14 @@ get_drm_connector_type(struct udev_device *drm_device, uint32_t connector_id) continue; } - connector_type = connector->connector_type; + c->name = weston_make_drm_connector_name(connector); + c->type = connector->connector_type; + drmModeFreeConnector(connector); drmModeFreeResources(res); close(fd); - return connector_type; + return 0; } close(fd); @@ -107,21 +116,22 @@ get_normalized_backlight(struct backlight *backlight) static void set_backlight(struct udev_device *drm_device, int connector_id, int blight) { - int connector_type; long max_brightness, brightness, actual_brightness; struct backlight *backlight; long new_blight; + struct setbacklight_connector connector; - connector_type = get_drm_connector_type(drm_device, connector_id); - if (connector_type < 0) + if (get_drm_connector_name_and_type(drm_device, connector_id, &connector) < 0) return; - backlight = backlight_init(drm_device, connector_type); + backlight = backlight_init(drm_device, connector.name, connector.type); if (!backlight) { printf("backlight adjust failed\n"); return; } + free(connector.name); + max_brightness = backlight_get_max_brightness(backlight); printf("Max backlight: %ld\n", max_brightness); -- 2.11.1 _______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
