On Mon, Jan 13, 2020 at 12:20:10PM +0100, Patrick Wildt wrote:
> The problem is that the last two values are 67 and 100. If you go
> 5% down, it's 95. The nearest will still be 100. The code then
> realizes that it's the same level as before, and does nlevel--.
> But nlevel-- is 99, and not 67, because nlevel is the value and
> not the index of the bcl array. So in essence the change needed
> is to decrease the index, not the value, and then look up the value.
Disucssing this over dinner again, patrick and I independently came up
with the very same diff below.
It makes acpivout_find_brightness() return an index instead a level for
the selected brightness.
Just works on my X230; I can go through every level with the function
keys and verify with xbacklight(1) that I am indeed not skipping any of
the 16 levels in either direction.
OK?
Index: acpivout.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.16
diff -u -p -r1.16 acpivout.c
--- acpivout.c 14 Dec 2019 10:57:48 -0000 1.16
+++ acpivout.c 14 Jan 2020 18:50:23 -0000
@@ -165,7 +165,7 @@ acpivout_brightness_cycle(struct acpivou
void
acpivout_brightness_step(struct acpivout_softc *sc, int dir)
{
- int level, nlevel;
+ int level, nindex;
if (sc->sc_bcl_len == 0)
return;
@@ -173,17 +173,17 @@ acpivout_brightness_step(struct acpivout
if (level == -1)
return;
- nlevel = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
- if (nlevel == level) {
- if (dir == 1 && (nlevel + 1 < sc->sc_bcl_len))
- nlevel++;
- else if (dir == -1 && (nlevel - 1 >= 0))
- nlevel--;
+ nindex = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
+ if (sc->sc_bcl[nindex] == level) {
+ if (dir == 1 && (nindex + 1 < sc->sc_bcl_len))
+ nindex++;
+ else if (dir == -1 && (nindex - 1 >= 0))
+ nindex--;
}
- if (nlevel == level)
+ if (sc->sc_bcl[nindex] == level)
return;
- acpivout_set_brightness(sc, nlevel);
+ acpivout_set_brightness(sc, sc->sc_bcl[nindex]);
}
void
@@ -219,14 +219,14 @@ acpivout_find_brightness(struct acpivout
for (i = 0; i < sc->sc_bcl_len - 1; i++) {
mid = sc->sc_bcl[i] + (sc->sc_bcl[i + 1] - sc->sc_bcl[i]) / 2;
if (sc->sc_bcl[i] <= level && level <= mid)
- return sc->sc_bcl[i];
+ return i;
if (mid < level && level <= sc->sc_bcl[i + 1])
- return sc->sc_bcl[i + 1];
+ return i + 1;
}
if (level < sc->sc_bcl[0])
- return sc->sc_bcl[0];
+ return 0;
else
- return sc->sc_bcl[i];
+ return i;
}
void
@@ -321,7 +321,7 @@ int
acpivout_set_param(struct wsdisplay_param *dp)
{
struct acpivout_softc *sc = NULL;
- int i, exact;
+ int i, nindex;
switch (dp->param) {
case WSDISPLAYIO_PARAM_BRIGHTNESS:
@@ -335,8 +335,8 @@ acpivout_set_param(struct wsdisplay_para
}
if (sc != NULL && sc->sc_bcl_len != 0) {
rw_enter_write(&sc->sc_acpi->sc_lck);
- exact = acpivout_find_brightness(sc, dp->curval);
- acpivout_set_brightness(sc, exact);
+ nindex = acpivout_find_brightness(sc, dp->curval);
+ acpivout_set_brightness(sc, sc->sc_bcl[nindex]);
rw_exit_write(&sc->sc_acpi->sc_lck);
return 0;
}