diff options
Diffstat (limited to 'src/sna/sna_display.c')
-rw-r--r-- | src/sna/sna_display.c | 254 |
1 files changed, 39 insertions, 215 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 636217aa..83b043c7 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -44,6 +44,7 @@ #include "sna_reg.h" #include "fb/fbpict.h" #include "intel_options.h" +#include "backlight.h" #include <xf86Crtc.h> @@ -141,9 +142,8 @@ struct sna_output { uint32_t dpms_id; int dpms_mode; - char *backlight_iface; + struct backlight backlight; int backlight_active_level; - int backlight_max; int num_modes; struct drm_mode_modeinfo *modes; @@ -186,11 +186,6 @@ static bool sna_mode_wait_for_event(struct sna *sna) return poll(&pfd, 1, -1) == 1; } -#define BACKLIGHT_CLASS "/sys/class/backlight" - -/* Enough for 10 digits of backlight + '\n' + '\0' */ -#define BACKLIGHT_VALUE_LEN 12 - static inline uint32_t fb_id(struct kgem_bo *bo) { return bo->delta; @@ -298,193 +293,40 @@ static void gem_close(int fd, uint32_t handle) (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close); } -#ifdef __OpenBSD__ - -#include <dev/wscons/wsconsio.h> -#include <xf86Priv.h> +#define BACKLIGHT_NAME "Backlight" +#define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" +static Atom backlight_atom, backlight_deprecated_atom; static void sna_output_backlight_set(xf86OutputPtr output, int level) { struct sna_output *sna_output = output->driver_private; - struct wsdisplay_param param; - - DBG(("%s: level=%d, max=%d\n", __FUNCTION__, - level, sna_output->backlight_max)); - - if (!sna_output->backlight_iface) - return; - - if ((unsigned)level > sna_output->backlight_max) - level = sna_output->backlight_max; - VG_CLEAR(param); - param.param = WSDISPLAYIO_PARAM_BRIGHTNESS; - param.curval = level; + DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__, + output->name, level, sna_output->backlight.max)); - if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_SETPARAM, ¶m) == -1) { + if (backlight_set(&sna_output->backlight, level)) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "Failed to set backlight level: %s\n", - strerror(errno)); - } -} - -static int -sna_output_backlight_get(xf86OutputPtr output) -{ - struct wsdisplay_param param; - - VG_CLEAR(param); - param.param = WSDISPLAYIO_PARAM_BRIGHTNESS; - - if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, ¶m) == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "Failed to get backlight level: %s\n", - strerror(errno)); - return -1; - } - - DBG(("%s: level=%d (max=%d)\n", __FUNCTION__, param.curval, param.max)); - - return param.curval; -} - -static void -sna_output_backlight_init(xf86OutputPtr output) -{ - struct sna_output *sna_output = output->driver_private; - struct wsdisplay_param param; - - VG_CLEAR(param); - param.param = WSDISPLAYIO_PARAM_BRIGHTNESS; - - if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, ¶m) == -1) - return; - - DBG(("%s: found 'wscons'\n", __FUNCTION__)); - - sna_output->backlight_iface = strdup("wscons"); - sna_output->backlight_max = param.max; - sna_output->backlight_active_level = param.curval; -} - -#else - -static void -sna_output_backlight_set(xf86OutputPtr output, int level) -{ - struct sna_output *sna_output = output->driver_private; - char path[1024], val[BACKLIGHT_VALUE_LEN]; - int fd, len, ret; - - DBG(("%s: level=%d, max=%d\n", __FUNCTION__, - level, sna_output->backlight_max)); - - if (!sna_output->backlight_iface) - return; - - if ((unsigned)level > sna_output->backlight_max) - level = sna_output->backlight_max; - - len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level); - sprintf(path, "%s/%s/brightness", - BACKLIGHT_CLASS, sna_output->backlight_iface); - fd = open(path, O_RDWR); - if (fd == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s for backlight " - "control: %s\n", path, strerror(errno)); - return; - } - - ret = write(fd, val, len); - if (ret == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "write to %s for backlight " - "control failed: %s\n", path, strerror(errno)); + "Failed to set backlight %s for output %s to brightness level %d, disabling\n", + sna_output->backlight.iface, output->name, level); + backlight_disable(&sna_output->backlight); + if (output->randr_output) { + RRDeleteOutputProperty(output->randr_output, backlight_atom); + RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom); + } } - - close(fd); } static int sna_output_backlight_get(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; - char path[1024], val[BACKLIGHT_VALUE_LEN]; - int fd, level; - - sprintf(path, "%s/%s/actual_brightness", - BACKLIGHT_CLASS, sna_output->backlight_iface); - fd = open(path, O_RDONLY); - if (fd == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s " - "for backlight control: %s\n", path, strerror(errno)); - return -1; - } - - memset(val, 0, sizeof(val)); - if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) { - close(fd); - return -1; - } - - close(fd); - - level = atoi(val); - DBG(("%s: level=%d (max=%d)\n", - __FUNCTION__, level, sna_output->backlight_max)); - - if (level > sna_output->backlight_max) - level = sna_output->backlight_max; - else if (level < 0) - level = -1; + int level = backlight_get(&sna_output->backlight); + DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__, + output->name, level, sna_output->backlight.max)); return level; } -static int -sna_output_backlight_get_max(xf86OutputPtr output) -{ - struct sna_output *sna_output = output->driver_private; - char path[1024], val[BACKLIGHT_VALUE_LEN]; - struct stat st; - int fd, max = 0; - - /* We are used as an initial check to see if we can - * control the backlight, so first test if we can set values. - */ - sprintf(path, "%s/%s/brightness", - BACKLIGHT_CLASS, sna_output->backlight_iface); - if (access(path, R_OK | W_OK)) - return -1; - - if (stat(path, &st)) - return -1; - - if (major(st.st_dev)) /* is this a kernel psuedo filesystem? */ - return -1; - - sprintf(path, "%s/%s/max_brightness", - BACKLIGHT_CLASS, sna_output->backlight_iface); - fd = open(path, O_RDONLY); - if (fd == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s " - "for backlight control: %s\n", path, strerror(errno)); - return -1; - } - - memset(val, 0, sizeof(val)); - if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) { - close(fd); - return -1; - } - - close(fd); - - max = atoi(val); - if (max <= 0) - max = -1; - return max; -} - enum { PLATFORM, FIRMWARE, @@ -495,21 +337,16 @@ enum { static char * has_user_backlight_override(xf86OutputPtr output) { - struct sna_output *sna_output = output->driver_private; struct sna *sna = to_sna(output->scrn); const char *str; - int max; str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT); if (str == NULL) return NULL; - sna_output->backlight_iface = (char *)str; - max = sna_output_backlight_get_max(output); - sna_output->backlight_iface = NULL; - if (max <= 0) { + if (!backlight_exists(str)) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "unrecognised backlight control interface '%s'\n", + "Unrecognised backlight control interface '%s'\n", str); return NULL; } @@ -520,7 +357,6 @@ has_user_backlight_override(xf86OutputPtr output) static char * has_device_backlight(xf86OutputPtr output, int *best_type) { - struct sna_output *sna_output = output->driver_private; struct sna *sna = to_sna(output->scrn); struct pci_device *pci; char path[1024]; @@ -576,12 +412,8 @@ has_device_backlight(xf86OutputPtr output, int *best_type) if (v < *best_type) { char *copy; - int max; - sna_output->backlight_iface = de->d_name; - max = sna_output_backlight_get_max(output); - sna_output->backlight_iface = NULL; - if (max <= 0) + if (!backlight_exists(de->d_name)) continue; copy = strdup(de->d_name); @@ -615,7 +447,6 @@ has_backlight(xf86OutputPtr output, int *best_type) "acpi_video0", "intel_backlight", }; - struct sna_output *sna_output = output->driver_private; char *best_iface = NULL; DIR *dir; struct dirent *de; @@ -669,14 +500,10 @@ has_backlight(xf86OutputPtr output, int *best_type) if (v < *best_type) { char *copy; - int max; /* XXX detect right backlight for multi-GPU/panels */ - sna_output->backlight_iface = de->d_name; - max = sna_output_backlight_get_max(output); - sna_output->backlight_iface = NULL; - if (max <= 0) + if (!backlight_exists(de->d_name)) continue; copy = strdup(de->d_name); @@ -713,12 +540,15 @@ sna_output_backlight_init(xf86OutputPtr output) if (best_iface) goto done; - return; + best_type = PLATFORM; + best_iface = NULL; done: - sna_output->backlight_iface = best_iface; - sna_output->backlight_max = sna_output_backlight_get_max(output); - sna_output->backlight_active_level = sna_output_backlight_get(output); + sna_output->backlight_active_level = + backlight_open(&sna_output->backlight, best_iface); + if (sna_output->backlight_active_level < 0) + return; + switch (best_type) { case INT_MAX: best_iface = (char *)"user"; from = X_CONFIG; break; case FIRMWARE: best_iface = (char *)"firmware"; break; @@ -727,10 +557,9 @@ done: default: best_iface = (char *)"unknown"; break; } xf86DrvMsg(output->scrn->scrnIndex, from, - "found backlight control interface %s (type '%s')\n", - sna_output->backlight_iface, best_iface); + "Found backlight control interface %s (type '%s') for output %s\n", + sna_output->backlight.iface, best_iface, output->name); } -#endif static char *canonical_kmode_name(const struct drm_mode_modeinfo *kmode) { @@ -2585,7 +2414,7 @@ sna_output_destroy(xf86OutputPtr output) free(sna_output->prop_ids); free(sna_output->prop_values); - free(sna_output->backlight_iface); + backlight_close(&sna_output->backlight); free(sna_output); output->driver_private = NULL; @@ -2596,7 +2425,7 @@ sna_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode) { struct sna_output *sna_output = output->driver_private; - if (!sna_output->backlight_iface) + if (!sna_output->backlight.iface) return; DBG(("%s(%s) -- %d -> %d\n", __FUNCTION__, output->name, oldmode, mode)); @@ -2700,10 +2529,6 @@ sna_output_create_ranged_atom(xf86OutputPtr output, Atom *atom, "RRChangeOutputProperty error, %d\n", err); } -#define BACKLIGHT_NAME "Backlight" -#define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" -static Atom backlight_atom, backlight_deprecated_atom; - static void sna_output_create_resources(xf86OutputPtr output) { @@ -2775,20 +2600,20 @@ sna_output_create_resources(xf86OutputPtr output) } } - if (sna_output->backlight_iface) { + if (sna_output->backlight.iface) { /* Set up the backlight property, which takes effect * immediately and accepts values only within the * backlight_range. */ sna_output_create_ranged_atom(output, &backlight_atom, BACKLIGHT_NAME, 0, - sna_output->backlight_max, + sna_output->backlight.max, sna_output->backlight_active_level, FALSE); sna_output_create_ranged_atom(output, &backlight_deprecated_atom, BACKLIGHT_DEPRECATED_NAME, 0, - sna_output->backlight_max, + sna_output->backlight.max, sna_output->backlight_active_level, FALSE); } @@ -2813,8 +2638,8 @@ sna_output_set_property(xf86OutputPtr output, Atom property, val = *(INT32 *)value->data; DBG(("%s: setting backlight to %d (max=%d)\n", - __FUNCTION__, (int)val, sna_output->backlight_max)); - if (val < 0 || val > sna_output->backlight_max) + __FUNCTION__, (int)val, sna_output->backlight.max)); + if (val < 0 || val > sna_output->backlight.max) return FALSE; if (sna_output->dpms_mode == DPMSModeOn) @@ -2880,7 +2705,7 @@ sna_output_get_property(xf86OutputPtr output, Atom property) if (property == backlight_atom || property == backlight_deprecated_atom) { INT32 val; - if (!sna_output->backlight_iface) + if (!sna_output->backlight.iface) return FALSE; val = sna_output_backlight_get(output); @@ -2890,7 +2715,6 @@ sna_output_get_property(xf86OutputPtr output, Atom property) err = RRChangeOutputProperty(output->randr_output, property, XA_INTEGER, 32, PropModeReplace, 1, &val, FALSE, FALSE); - if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "RRChangeOutputProperty error, %d\n", err); |