diff options
author | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-02-16 19:18:20 +0200 |
---|---|---|
committer | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-02-28 13:26:25 +0200 |
commit | e7cefb43d1a39753f475435acac39cd077ab0938 (patch) | |
tree | 33bc003c545c2bee42db9bb18239aca9115767f6 | |
parent | 5f6a949a11020e8edd30444feb91b8e5916468ff (diff) |
libpciaccess was sending a handler to be used to find and match an appropriate
backlight. Non-PCI devices would have to rely on libpciaccess anyway or
alternatively use the DRM tripe (card id, connector_type and
connector_type_id) for doing so (and the DRM tripe was not working anyway when
card equals 0). Besides, find & match of devices is not the real intention of
libpciaccess and for such we have UDEV.
This commit removes the matching logic that uses libpciaccess and the DRM
tripe, using instead the UDEV handler of a connector device and the type. Such
alternative is quite flexible for configuration, and is inspired by systemd:
http://www.freedesktop.org/wiki/Software/systemd/multiseat
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/libbacklight.h | 13 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/libbacklight.c | 65 | ||||
-rw-r--r-- | test/Makefile.am | 6 | ||||
-rw-r--r-- | test/setbacklight.c | 124 |
6 files changed, 125 insertions, 87 deletions
diff --git a/configure.ac b/configure.ac index f1d0838..e9bb9b8 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ AM_SILENT_RULES([yes]) AC_PROG_CC AC_PROG_LIBTOOL PKG_CHECK_MODULES([DRM], [libdrm]) -PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10.0]) +PKG_CHECK_MODULES([UDEV], [libudev >= 136]) AC_CONFIG_FILES([Makefile include/Makefile src/Makefile diff --git a/include/libbacklight.h b/include/libbacklight.h index ff0e842..cea34c2 100644 --- a/include/libbacklight.h +++ b/include/libbacklight.h @@ -1,6 +1,7 @@ #ifndef LIBBACKLIGHT_H #define LIBBACKLIGHT_H -#include <pciaccess.h> +#include <libudev.h> +#include <stdint.h> #ifdef __cplusplus extern "C" { @@ -19,12 +20,12 @@ struct backlight { enum backlight_type type; }; -/* - * Find and set up a backlight for the given PCI device or card/connector - * combination. It is valid (and preferred) to provide both sets of information +/* + * Find and set up a backlight for a valid udev connector device, i.e. one + * matching drm subsytem and with status of connected. */ -struct backlight *backlight_init(struct pci_device *dev, int card, - int connector_type, int connector_type_id); +struct backlight *backlight_init(struct udev_device *drm_device, + uint32_t connector_type); /* Free backlight resources */ void backlight_destroy(struct backlight *backlight); diff --git a/src/Makefile.am b/src/Makefile.am index bebc103..96e1727 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,4 +3,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = libbacklight.la libbacklight_la_SOURCES = libbacklight.c libbacklight.h libbacklight_la_LDFLAGS = -version-number 0:0:1 -libatasmart_la_CFLAGS = $(PCIACCESS_CFLAGS) +libbacklight_la_CFLAGS = $(UDEV_CFLAGS) diff --git a/src/libbacklight.c b/src/libbacklight.c index fa78be2..b2e19bf 100644 --- a/src/libbacklight.c +++ b/src/libbacklight.c @@ -1,6 +1,7 @@ /* * libbacklight - userspace interface to Linux backlight control * + * Copyright © 2012 Intel Corporation * Copyright 2010 Red Hat <mjg@redhat.com> * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,22 +26,19 @@ * * Authors: * Matthew Garrett <mjg@redhat.com> + * Tiago Vignatti <vignatti@freedesktop.org> */ #define _GNU_SOURCE #include <libbacklight.h> #include <stdio.h> -#include <sys/types.h> #include <linux/types.h> #include <dirent.h> -#include <sys/stat.h> #include <drm/drm_mode.h> #include <fcntl.h> #include <malloc.h> #include <string.h> -#include <unistd.h> -#include <stdlib.h> #include <errno.h> static const char *output_names[] = { "Unknown", @@ -159,42 +157,49 @@ void backlight_destroy(struct backlight *backlight) free(backlight); } -struct backlight *backlight_init(struct pci_device *dev, int card, - int connector_type, int connector_type_id) +struct backlight *backlight_init(struct udev_device *drm_device, + uint32_t connector_type) { + const char *syspath = NULL; char *pci_name = NULL; - char *drm_name = NULL; char *chosen_path = NULL; + char *path = NULL; DIR *backlights; struct dirent *entry; enum backlight_type type = 0; char buffer[100]; struct backlight *backlight; - int err; + int err, ret; - if (dev) { - err = asprintf(&pci_name, "%04x:%02x:%02x.%d", dev->domain, - dev->bus, dev->dev, dev->func); - if (err < 0) - return NULL; - } + if (!drm_device) + return NULL; - if (card) { - err = asprintf(&drm_name, "card%d-%s-%d", card, - output_names[connector_type], connector_type_id); - if (err < 0) - return NULL; - } + syspath = udev_device_get_syspath(drm_device); + if (!syspath) + return NULL; - backlights = opendir("/sys/class/backlight"); + if (asprintf(&path, "%s/%s", syspath, "device") < 0) + return NULL; + ret = readlink(path, buffer, sizeof(buffer)); + free(path); + if (ret < 0) + return NULL; + + buffer[ret] = '\0'; + pci_name = basename(buffer); + + if (connector_type <= 0) + return NULL; + + backlights = opendir("/sys/class/backlight"); if (!backlights) return NULL; /* Find the "best" backlight for the device. Firmware interfaces are preferred over platform interfaces are preferred over raw interfaces. For raw interfaces we'll - match if either the pci ID or the output ID match, while + check if the device ID in the form of pci match, while for firmware interfaces we require the pci ID to match. It's assumed that platform interfaces always match, since we can't actually associate them with IDs. @@ -210,9 +215,8 @@ struct backlight *backlight_init(struct pci_device *dev, int card, while ((entry = readdir(backlights))) { char *backlight_path; char *parent; - char *path; enum backlight_type entry_type; - int fd, ret; + int fd; if (entry->d_name[0] == '.') continue; @@ -272,8 +276,7 @@ struct backlight *backlight_init(struct pci_device *dev, int card, platform backlights have to be assumed to match */ if (entry_type == BACKLIGHT_RAW || entry_type == BACKLIGHT_FIRMWARE) { - if (!((drm_name && !strcmp(drm_name, parent)) || - (pci_name && !strcmp(pci_name, parent)))) + if (!(pci_name && !strcmp(pci_name, parent))) goto out; } @@ -310,18 +313,8 @@ struct backlight *backlight_init(struct pci_device *dev, int card, if (backlight->brightness < 0) goto err; - if (pci_name) - free(pci_name); - - if (drm_name) - free(drm_name); - return backlight; err: - if (pci_name) - free(pci_name); - if (drm_name) - free(drm_name); if (chosen_path) free(chosen_path); free (backlight); diff --git a/test/Makefile.am b/test/Makefile.am index f168def..99b24d7 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -27,9 +27,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/include $(DRM_CFLAGS) LDADD = $(top_builddir)/src/libbacklight.la setbacklight_SOURCES = setbacklight.c -setbacklight_LDFLAGS = $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) -setbacklight_LDADD = $(DRM_LIBS) \ - $(PCIACCESS_LIBS) \ +setbacklight_LDFLAGS = $(UDEV_CFLAGS) $(DRM_CFLAGS) +setbacklight_LDADD = $(UDEV_LIBS) \ + $(DRM_LIBS) \ $(top_builddir)/src/libbacklight.la setdpms_SOURCES = setdpms.c diff --git a/test/setbacklight.c b/test/setbacklight.c index 73c1d5d..a3fe91b 100644 --- a/test/setbacklight.c +++ b/test/setbacklight.c @@ -21,45 +21,76 @@ * * Author: Tiago Vignatti */ +/* + * \file setbacklight.c + * Test program to get a backlight connector and set its brightness value. + * Queries for the connectors id can be performed using drm/tests/modeprint + * program. + */ #include <stdio.h> #include <xf86drm.h> #include <xf86drmMode.h> +#include <fcntl.h> #include "libbacklight.h" -static void -set_backlight(int fd, drmModeResPtr res, struct pci_device * dev, int blight) +static uint32_t +get_drm_connector_type(struct udev_device *drm_device, uint32_t connector_id) { + const char *filename; + int fd, i, connector_type; + drmModeResPtr res; drmModeConnectorPtr connector; - int i; - long max_brightness, brightness, actual_brightness; - struct backlight *backlight; + filename = udev_device_get_devnode(drm_device); + fd = open(filename, O_RDWR | O_CLOEXEC); + if (fd < 0) { + printf("couldn't open drm_device\n"); + return -1; + } + + res = drmModeGetResources(fd); + if (res == 0) { + printf("Failed to get resources from card\n"); + close(fd); + return -1; + } for (i = 0; i < res->count_connectors; i++) { connector = drmModeGetConnector(fd, res->connectors[i]); - if (!connector) continue; - if (connector->connection == DRM_MODE_DISCONNECTED) { + if ((connector->connection == DRM_MODE_DISCONNECTED) || + (connector->connector_id != connector_id)) { drmModeFreeConnector(connector); continue; } - fprintf(stderr, "setting up connetor type: %d, type_id: %d\n", - connector->connector_type, - connector->connector_type_id); - - backlight = backlight_init(dev, - 0, - connector->connector_type, - connector->connector_type_id); + connector_type = connector->connector_type; drmModeFreeConnector(connector); - break; + drmModeFreeResources(res); + + return connector_type; } + drmModeFreeResources(res); + return -1; +} + +static void +set_backlight(struct udev_device *drm_device, int connector_id, int blight) +{ + int connector_type, i; + long max_brightness, brightness, actual_brightness; + struct backlight *backlight; + + connector_type = get_drm_connector_type(drm_device, connector_id); + if (connector_type < 0) + return; + + backlight = backlight_init(drm_device, connector_type); if (!backlight) { printf("backlight adjust failed\n"); return; @@ -83,41 +114,54 @@ set_backlight(int fd, drmModeResPtr res, struct pci_device * dev, int blight) int main(int argc, char **argv) { - int fd, blight; - drmModeResPtr res; + int fd, blight, connector_id; const char *module_name = "i915"; - struct pci_id_match dev_match = { - PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, - (0x03 << 16), 0xff000, 0 }; - struct pci_device_iterator * iter; - struct pci_device * dev; - - if (argc < 2) { - printf("Please add a brightness value\n"); + const char *default_seat = "seat0"; + const char *path, *device_seat; + struct udev *udev; + struct udev_enumerate *e; + struct udev_list_entry *entry; + struct udev_device *device, *drm_device; + + if (argc < 3) { + printf("Please add connector_id and brightness values\n"); return 1; } - blight = atoi(argv[1]); + connector_id = atoi(argv[1]); + blight = atoi(argv[2]); - fd = drmOpen(module_name, NULL); - if (fd < 0) { - printf("Failed to open the card fd (%d)\n",fd); + udev = udev_new(); + if (udev == NULL) { + printf("failed to initialize udev context\n"); return 1; } - res = drmModeGetResources(fd); - if (res == 0) { - printf("Failed to get resources from card\n"); - drmClose(fd); - return 1; + e = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(e, "drm"); + udev_enumerate_add_match_sysname(e, "card[0-9]*"); + + udev_enumerate_scan_devices(e); + drm_device = NULL; + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { + path = udev_list_entry_get_name(entry); + device = udev_device_new_from_syspath(udev, path); + device_seat = + udev_device_get_property_value(device, "ID_SEAT"); + if (!device_seat) + device_seat = default_seat; + + drm_device = device; + break; } - pci_system_init(); - iter = pci_id_match_iterator_create(&dev_match); + if (drm_device == NULL) { + printf("no drm device found\n"); + return 1; + } - while ((dev = pci_device_next(iter)) != NULL) - set_backlight(fd, res, dev, blight); + set_backlight(drm_device, connector_id, blight); - drmModeFreeResources(res); + udev_device_unref(drm_device); return 0; } |