summaryrefslogtreecommitdiff
path: root/src/sna/sna_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/sna_display.c')
-rw-r--r--src/sna/sna_display.c254
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, &param) == -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, &param) == -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, &param) == -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);