I had the same wish, and implemented a -mul option for multiplying the intensity by a number; as the number can be either >1 or <1, there's no need for separate options for increasing and decreasing. The patch is attached.
The patch also makes -set, -inc and -dec accept non-integer values without truncating them. Regards, Pieter-Tjerk
--- ./man/xbacklight.man.orig 2013-10-08 05:40:38.000000000 +0200 +++ ./man/xbacklight.man 2017-12-25 15:05:20.749299372 +0100 @@ -44,6 +44,10 @@ Increases brightness by the specified amount. .IP "\-dec \fIpercent\fP" Decreases brightness by the specified amount. +.IP "\-mul \fIfactor\fP" +Multiplies brightness by the specified amount. +If factor is not 1, the result is rounded such that the brightness does change, +so this can be bound safely to a hotkey without getting stuck at 0. .IP \-help Print out a summary of the usage and exit. .IP "\-time \fImilliseconds\fP" --- ./xbacklight.c.orig 2013-10-08 05:40:38.000000000 +0200 +++ ./xbacklight.c 2017-12-25 15:03:32.991542960 +0100 @@ -31,7 +31,7 @@ #include <string.h> #include <unistd.h> -typedef enum { Get, Set, Inc, Dec } op_t; +typedef enum { Get, Set, Inc, Dec, Mul } op_t; static char *program_name; @@ -47,6 +47,7 @@ " -set <percentage> or = <percentage>\n" " -inc <percentage> or + <percentage>\n" " -dec <percentage> or - <percentage>\n" + " -mul <factor> or * <factor> (note that the * may need a shell escape like \\* )\n" " -get\n" " -time <fade time in milliseconds>\n" " -steps <number of steps in fade>\n"); @@ -107,7 +108,7 @@ { char *dpy_name = NULL; op_t op = Get; - int value = 0; + double value = 0; int i; int total_time = 200; /* ms */ int steps = 20; @@ -137,39 +138,52 @@ { if (++i >= argc) usage(); op = Set; - value = atoi (argv[i]); + value = atof (argv[i]); continue; } if (argv[i][0] == '=' && isdigit (argv[i][1])) { op = Set; - value = atoi (argv[i] + 1); + value = atof (argv[i] + 1); continue; } if (!strcmp (argv[i], "-inc") || !strcmp (argv[i], "+")) { if (++i >= argc) usage(); op = Inc; - value = atoi (argv[i]); + value = atof (argv[i]); continue; } if (argv[i][0] == '+' && isdigit (argv[i][1])) { op = Inc; - value = atoi (argv[i] + 1); + value = atof (argv[i] + 1); continue; } if (!strcmp (argv[i], "-dec") || !strcmp (argv[i], "-")) { if (++i >= argc) usage(); op = Dec; - value = atoi (argv[i]); + value = atof (argv[i]); continue; } if (argv[i][0] == '-' && isdigit (argv[i][1])) { op = Dec; - value = atoi (argv[i] + 1); + value = atof (argv[i] + 1); + continue; + } + if (!strcmp (argv[i], "-mul") || !strcmp (argv[i], "*")) + { + if (++i >= argc) usage(); + op = Mul; + value = atof (argv[i]); + continue; + } + if (argv[i][0] == '*' && ( isdigit (argv[i][1]) || argv[i][1]=='.' )) + { + op = Mul; + value = atof (argv[i] + 1); continue; } if (!strcmp (argv[i], "-get") || !strcmp (argv[i], "-g")) @@ -295,6 +309,14 @@ case Dec: new = cur - set; break; + case Mul: + new = cur + (cur - min) * (value - 1); + if ((long)(new+0.5) == (long)(cur+0.5)) { + // ensure that there is some change after rounding + if (value>1) new++; + else if (value<1) new--; + } + break; default: xcb_aux_sync (conn); return 1; @@ -308,7 +330,7 @@ cur = new; else cur += step; - backlight_set (conn, output, (long) cur); + backlight_set (conn, output, (long) (cur+0.5)); // +0.5 for proper rounding xcb_flush (conn); usleep (total_time * 1000 / steps); }