sync code with last improvements from OpenBSD
This commit is contained in:
commit
88965415ff
26235 changed files with 29195616 additions and 0 deletions
362
app/xbacklight/xbacklight.c
Normal file
362
app/xbacklight/xbacklight.c
Normal file
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
* Copyright © 2007 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_util.h>
|
||||
#include <xcb/xproto.h>
|
||||
#include <xcb/randr.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef enum { Get, Set, Inc, Dec } op_t;
|
||||
|
||||
static char *program_name;
|
||||
|
||||
static xcb_atom_t backlight, backlight_new, backlight_legacy;
|
||||
|
||||
static void
|
||||
usage (int exitcode)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [options]\n%s", program_name,
|
||||
" where options are:\n"
|
||||
" -display <display> or -d <display>\n"
|
||||
" -help\n"
|
||||
" -version\n"
|
||||
" -set <percentage> or = <percentage>\n"
|
||||
" -inc <percentage> or + <percentage>\n"
|
||||
" -dec <percentage> or - <percentage>\n"
|
||||
" -get\n"
|
||||
" -time <fade time in milliseconds>\n"
|
||||
" -steps <number of steps in fade>\n");
|
||||
exit (exitcode);
|
||||
}
|
||||
|
||||
static double
|
||||
atof_or_die (char *str)
|
||||
{
|
||||
double retval;
|
||||
char *endptr = NULL;
|
||||
errno = 0;
|
||||
retval = strtod(str, &endptr);
|
||||
if ((errno != 0) || (endptr == str)) {
|
||||
fprintf(stderr, "%s: invalid argument '%s'\n", program_name, str);
|
||||
usage(1);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
missing_arg (const char *option)
|
||||
{
|
||||
fprintf(stderr, "%s: %s requires an argument\n", program_name, option);
|
||||
usage(1);
|
||||
}
|
||||
|
||||
static long
|
||||
backlight_get (xcb_connection_t *conn, xcb_randr_output_t output)
|
||||
{
|
||||
xcb_generic_error_t *error;
|
||||
xcb_randr_get_output_property_reply_t *prop_reply = NULL;
|
||||
xcb_randr_get_output_property_cookie_t prop_cookie;
|
||||
long value;
|
||||
|
||||
backlight = backlight_new;
|
||||
if (backlight != XCB_ATOM_NONE) {
|
||||
prop_cookie = xcb_randr_get_output_property (conn, output,
|
||||
backlight, XCB_ATOM_NONE,
|
||||
0, 4, 0, 0);
|
||||
prop_reply = xcb_randr_get_output_property_reply (conn, prop_cookie, &error);
|
||||
if (error != NULL || prop_reply == NULL) {
|
||||
backlight = backlight_legacy;
|
||||
if (backlight != XCB_ATOM_NONE) {
|
||||
prop_cookie = xcb_randr_get_output_property (conn, output,
|
||||
backlight, XCB_ATOM_NONE,
|
||||
0, 4, 0, 0);
|
||||
prop_reply = xcb_randr_get_output_property_reply (conn, prop_cookie, &error);
|
||||
if (error != NULL || prop_reply == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop_reply == NULL ||
|
||||
prop_reply->type != XCB_ATOM_INTEGER ||
|
||||
prop_reply->num_items != 1 ||
|
||||
prop_reply->format != 32) {
|
||||
value = -1;
|
||||
} else {
|
||||
value = *((int32_t *) xcb_randr_get_output_property_data (prop_reply));
|
||||
}
|
||||
|
||||
free (prop_reply);
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
backlight_set (xcb_connection_t *conn, xcb_randr_output_t output, long value)
|
||||
{
|
||||
xcb_randr_change_output_property (conn, output, backlight, XCB_ATOM_INTEGER,
|
||||
32, XCB_PROP_MODE_REPLACE,
|
||||
1, (unsigned char *)&value);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *dpy_name = NULL;
|
||||
op_t op = Get;
|
||||
double value = 0;
|
||||
int i;
|
||||
int total_time = 200; /* ms */
|
||||
int steps = 20;
|
||||
|
||||
xcb_connection_t *conn;
|
||||
xcb_generic_error_t *error;
|
||||
|
||||
xcb_randr_query_version_cookie_t ver_cookie;
|
||||
xcb_randr_query_version_reply_t *ver_reply;
|
||||
|
||||
xcb_intern_atom_cookie_t backlight_cookie[2];
|
||||
xcb_intern_atom_reply_t *backlight_reply;
|
||||
|
||||
xcb_screen_iterator_t iter;
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (!strcmp (argv[i], "-display") || !strcmp ("-d", argv[i]))
|
||||
{
|
||||
if (++i >= argc) missing_arg (argv[i-1]);
|
||||
dpy_name = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-set") || !strcmp (argv[i], "="))
|
||||
{
|
||||
if (++i >= argc) missing_arg (argv[i-1]);
|
||||
op = Set;
|
||||
value = atof_or_die (argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (argv[i][0] == '=' && isdigit (argv[i][1]))
|
||||
{
|
||||
op = Set;
|
||||
value = atof_or_die (argv[i] + 1);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-inc") || !strcmp (argv[i], "+"))
|
||||
{
|
||||
if (++i >= argc) missing_arg (argv[i-1]);
|
||||
op = Inc;
|
||||
value = atof_or_die (argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (argv[i][0] == '+' && isdigit (argv[i][1]))
|
||||
{
|
||||
op = Inc;
|
||||
value = atof_or_die (argv[i] + 1);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-dec") || !strcmp (argv[i], "-"))
|
||||
{
|
||||
if (++i >= argc) missing_arg (argv[i-1]);
|
||||
op = Dec;
|
||||
value = atof_or_die (argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (argv[i][0] == '-' && isdigit (argv[i][1]))
|
||||
{
|
||||
op = Dec;
|
||||
value = atof_or_die (argv[i] + 1);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-get") || !strcmp (argv[i], "-g"))
|
||||
{
|
||||
op = Get;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-time"))
|
||||
{
|
||||
if (++i >= argc) missing_arg (argv[i-1]);
|
||||
total_time = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-steps"))
|
||||
{
|
||||
if (++i >= argc) missing_arg (argv[i-1]);
|
||||
steps = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (argv[i], "-help") || !strcmp (argv[i], "-?"))
|
||||
{
|
||||
usage (0);
|
||||
}
|
||||
if (!strcmp (argv[i], "-version"))
|
||||
{
|
||||
puts (PACKAGE_STRING);
|
||||
exit (0);
|
||||
}
|
||||
fprintf(stderr, "%s: unrecognized argument '%s'\n",
|
||||
program_name, argv[i]);
|
||||
usage (1);
|
||||
}
|
||||
conn = xcb_connect (dpy_name, NULL);
|
||||
ver_cookie = xcb_randr_query_version (conn, 1, 2);
|
||||
ver_reply = xcb_randr_query_version_reply (conn, ver_cookie, &error);
|
||||
if (error != NULL || ver_reply == NULL) {
|
||||
int ec = error ? error->error_code : -1;
|
||||
fprintf (stderr, "RANDR Query Version returned error %d\n", ec);
|
||||
exit (1);
|
||||
}
|
||||
if (ver_reply->major_version != 1 ||
|
||||
ver_reply->minor_version < 2) {
|
||||
fprintf (stderr, "RandR version %d.%d too old\n",
|
||||
ver_reply->major_version, ver_reply->minor_version);
|
||||
exit (1);
|
||||
}
|
||||
free (ver_reply);
|
||||
|
||||
backlight_cookie[0] = xcb_intern_atom (conn, 1, strlen("Backlight"), "Backlight");
|
||||
backlight_cookie[1] = xcb_intern_atom (conn, 1, strlen("BACKLIGHT"), "BACKLIGHT");
|
||||
|
||||
backlight_reply = xcb_intern_atom_reply (conn, backlight_cookie[0], &error);
|
||||
if (error != NULL || backlight_reply == NULL) {
|
||||
int ec = error ? error->error_code : -1;
|
||||
fprintf (stderr, "Intern Atom returned error %d\n", ec);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
backlight_new = backlight_reply->atom;
|
||||
free (backlight_reply);
|
||||
|
||||
backlight_reply = xcb_intern_atom_reply (conn, backlight_cookie[1], &error);
|
||||
if (error != NULL || backlight_reply == NULL) {
|
||||
int ec = error ? error->error_code : -1;
|
||||
fprintf (stderr, "Intern Atom returned error %d\n", ec);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
backlight_legacy = backlight_reply->atom;
|
||||
free (backlight_reply);
|
||||
|
||||
if (backlight_new == XCB_NONE && backlight_legacy == XCB_NONE) {
|
||||
fprintf (stderr, "No outputs have backlight property\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
iter = xcb_setup_roots_iterator (xcb_get_setup (conn));
|
||||
while (iter.rem) {
|
||||
xcb_screen_t *screen = iter.data;
|
||||
xcb_window_t root = screen->root;
|
||||
xcb_randr_output_t *outputs;
|
||||
|
||||
xcb_randr_get_screen_resources_current_cookie_t resources_cookie;
|
||||
xcb_randr_get_screen_resources_current_reply_t *resources_reply;
|
||||
|
||||
resources_cookie = xcb_randr_get_screen_resources_current (conn, root);
|
||||
resources_reply = xcb_randr_get_screen_resources_current_reply (conn, resources_cookie, &error);
|
||||
if (error != NULL || resources_reply == NULL) {
|
||||
int ec = error ? error->error_code : -1;
|
||||
fprintf (stderr, "RANDR Get Screen Resources returned error %d\n", ec);
|
||||
continue;
|
||||
}
|
||||
|
||||
outputs = xcb_randr_get_screen_resources_current_outputs (resources_reply);
|
||||
for (int o = 0; o < resources_reply->num_outputs; o++)
|
||||
{
|
||||
xcb_randr_output_t output = outputs[o];
|
||||
double cur, new, step;
|
||||
double min, max;
|
||||
double set;
|
||||
|
||||
cur = backlight_get (conn, output);
|
||||
if (cur != -1)
|
||||
{
|
||||
xcb_randr_query_output_property_cookie_t prop_cookie;
|
||||
xcb_randr_query_output_property_reply_t *prop_reply;
|
||||
|
||||
prop_cookie = xcb_randr_query_output_property (conn, output, backlight);
|
||||
prop_reply = xcb_randr_query_output_property_reply (conn, prop_cookie, &error);
|
||||
|
||||
if (error != NULL || prop_reply == NULL) continue;
|
||||
|
||||
if (prop_reply->range &&
|
||||
xcb_randr_query_output_property_valid_values_length (prop_reply) == 2) {
|
||||
int32_t *values = xcb_randr_query_output_property_valid_values (prop_reply);
|
||||
min = values[0];
|
||||
max = values[1];
|
||||
|
||||
if (op == Get) {
|
||||
printf ("%f\n", (cur - min) * 100 / (max - min));
|
||||
} else {
|
||||
set = value * (max - min) / 100;
|
||||
switch (op) {
|
||||
case Set:
|
||||
new = min + set;
|
||||
break;
|
||||
case Inc:
|
||||
new = cur + set;
|
||||
break;
|
||||
case Dec:
|
||||
new = cur - set;
|
||||
break;
|
||||
default:
|
||||
xcb_aux_sync (conn);
|
||||
return 1;
|
||||
}
|
||||
if (new > max) new = max;
|
||||
if (new < min) new = min;
|
||||
step = (new - cur) / steps;
|
||||
for (i = 0; i < steps && step != 0; i++)
|
||||
{
|
||||
if (i == steps - 1)
|
||||
cur = new;
|
||||
else
|
||||
cur += step;
|
||||
backlight_set (conn, output, (long) (cur + 0.5));
|
||||
xcb_flush (conn);
|
||||
usleep (total_time * 1000 / steps);
|
||||
}
|
||||
}
|
||||
}
|
||||
free (prop_reply);
|
||||
}
|
||||
}
|
||||
|
||||
free (resources_reply);
|
||||
xcb_screen_next (&iter);
|
||||
}
|
||||
xcb_aux_sync (conn);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue