summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Vignatti <tiago.vignatti@intel.com>2012-02-16 19:18:20 +0200
committerTiago Vignatti <tiago.vignatti@intel.com>2012-02-28 13:26:25 +0200
commite7cefb43d1a39753f475435acac39cd077ab0938 (patch)
tree33bc003c545c2bee42db9bb18239aca9115767f6
parent5f6a949a11020e8edd30444feb91b8e5916468ff (diff)
New backlight API relying on udevHEADmaster
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.ac2
-rw-r--r--include/libbacklight.h13
-rw-r--r--src/Makefile.am2
-rw-r--r--src/libbacklight.c65
-rw-r--r--test/Makefile.am6
-rw-r--r--test/setbacklight.c124
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;
}