xgamma.c revision dd77ae96
172b4363aSmrg/*
272b4363aSmrg * Copyright 1999  The XFree86 Project
372b4363aSmrg *
472b4363aSmrg * Permission is hereby granted, free of charge, to any person obtaining a
572b4363aSmrg * copy of this software and associated documentation files (the "Software"),
672b4363aSmrg * to deal in the Software without restriction, including without limitation
772b4363aSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
872b4363aSmrg * and/or sell copies of the Software, and to permit persons to whom the
972b4363aSmrg * Software is furnished to do so, subject to the following conditions:
1072b4363aSmrg *
1172b4363aSmrg * The above copyright notice and this permission notice shall be included in
1272b4363aSmrg * all copies or substantial portions of the Software.
1372b4363aSmrg *
1472b4363aSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1572b4363aSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1672b4363aSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1772b4363aSmrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1872b4363aSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
1972b4363aSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2072b4363aSmrg * SOFTWARE.
2172b4363aSmrg *
2272b4363aSmrg * Written by David Bateman
2372b4363aSmrg */
2472b4363aSmrg/* $XFree86: xc/programs/xgamma/xgamma.c,v 1.3 1999/03/21 07:35:38 dawes Exp $ */
2572b4363aSmrg
2672b4363aSmrg#include <stdio.h>
2772b4363aSmrg#include <errno.h>
2872b4363aSmrg#include <X11/Xos.h>
2972b4363aSmrg#include <X11/Xlib.h>
3072b4363aSmrg#include <X11/Xutil.h>
3172b4363aSmrg#include <X11/extensions/xf86vmode.h>
3272b4363aSmrg#include <ctype.h>
3372b4363aSmrg#include <stdlib.h>
3472b4363aSmrg
35dd77ae96Smrgstatic char *ProgramName;
36dd77ae96Smrgstatic int MajorVersion, MinorVersion;
37dd77ae96Smrgstatic int EventBase, ErrorBase;
3872b4363aSmrg
3972b4363aSmrg/* Minimum extension version required */
4072b4363aSmrg#define MINMAJOR 2
4172b4363aSmrg#define MINMINOR 0
4272b4363aSmrg
4372b4363aSmrg/* Maximum and Minimum gamma values */
4472b4363aSmrg#define GAMMA_MIN 0.1
4572b4363aSmrg#define GAMMA_MAX 10.0
4672b4363aSmrg
4772b4363aSmrgstatic void
4872b4363aSmrgSyntax(void)
4972b4363aSmrg{
5072b4363aSmrg    fprintf (stderr, "usage:  %s [-options]\n\n",
5172b4363aSmrg    	     ProgramName);
5272b4363aSmrg    fprintf (stderr, "where the available options are:\n");
5372b4363aSmrg    fprintf (stderr, "    -display host:dpy       or -d\n");
5472b4363aSmrg    fprintf (stderr, "    -quiet                  or -q\n");
5572b4363aSmrg    fprintf (stderr, "    -screen                 or -s\n");
5672b4363aSmrg    fprintf (stderr, "    -gamma f.f              Gamma Value\n");
5772b4363aSmrg    fprintf (stderr, "    -rgamma f.f             Red Gamma Value\n");
5872b4363aSmrg    fprintf (stderr, "    -ggamma f.f             Green Gamma Value\n");
5972b4363aSmrg    fprintf (stderr, "    -bgamma f.f             Blue Gamma Value\n\n");
6072b4363aSmrg    fprintf (stderr, "If no gamma is specified, returns the current setting\n");
6172b4363aSmrg    exit (1);
6272b4363aSmrg}
6372b4363aSmrg
6472b4363aSmrg
6572b4363aSmrg/*
6672b4363aSmrg * The following is a hack until XrmParseCommand is ready.  It determines
6772b4363aSmrg * whether or not the given string is an abbreviation of the arg.
6872b4363aSmrg */
6972b4363aSmrg
7072b4363aSmrgstatic Bool
7172b4363aSmrgisabbreviation(char *arg, char *s, int minslen)
7272b4363aSmrg{
7372b4363aSmrg    int arglen;
7472b4363aSmrg    int slen;
7572b4363aSmrg
7672b4363aSmrg    /* exact match */
7772b4363aSmrg    if (strcmp (arg, s) == 0) return (True);
7872b4363aSmrg
7972b4363aSmrg    arglen = strlen (arg);
8072b4363aSmrg    slen = strlen (s);
8172b4363aSmrg
8272b4363aSmrg    /* too long or too short */
8372b4363aSmrg    if (slen >= arglen || slen < minslen) return (False);
8472b4363aSmrg
8572b4363aSmrg    /* abbreviation */
8672b4363aSmrg    if (strncmp (arg, s, slen) == 0) return (True);
8772b4363aSmrg
8872b4363aSmrg    /* bad */
8972b4363aSmrg    return (False);
9072b4363aSmrg}
9172b4363aSmrg
9272b4363aSmrgint
9372b4363aSmrgmain(int argc, char *argv[])
9472b4363aSmrg{
9572b4363aSmrg    int i, ret;
9672b4363aSmrg    char *displayname = NULL;
9772b4363aSmrg    Display *dpy;
9872b4363aSmrg    float gam = -1., rgam = -1., ggam = -1., bgam = -1.;
9972b4363aSmrg    XF86VidModeGamma gamma;
10072b4363aSmrg    Bool quiet = False;
10172b4363aSmrg    int screen = -1;
10272b4363aSmrg
10372b4363aSmrg    ProgramName = argv[0];
10472b4363aSmrg    for (i = 1; i < argc; i++) {
10572b4363aSmrg	char *arg = argv[i];
10672b4363aSmrg
10772b4363aSmrg	if (arg[0] == '-') {
10872b4363aSmrg	    if (isabbreviation ("-display", arg, 1)) {
10972b4363aSmrg		if (++i >= argc) Syntax ();
11072b4363aSmrg		displayname = argv[i];
11172b4363aSmrg		continue;
11272b4363aSmrg	    } else if (isabbreviation ("-quiet", arg, 1)) {
11372b4363aSmrg		quiet = True;
11472b4363aSmrg		continue;
11572b4363aSmrg	    } else if (isabbreviation ("-screen", arg, 1)) {
11672b4363aSmrg		if (++i >= argc) Syntax ();
11772b4363aSmrg		screen = atoi(argv[i]);
11872b4363aSmrg		continue;
11972b4363aSmrg	    } else if (isabbreviation ("-gamma", arg, 2)) {
12072b4363aSmrg		if (++i >= argc) Syntax ();
12172b4363aSmrg		if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.))
12272b4363aSmrg		    Syntax ();
12372b4363aSmrg		gam = (float)atof(argv[i]);
12472b4363aSmrg		if ((gam < GAMMA_MIN) || (gam > GAMMA_MAX)) {
12572b4363aSmrg		    fprintf(stderr,
12672b4363aSmrg			    "Gamma values must be between %6.3f and %6.3f\n",
12772b4363aSmrg			    GAMMA_MIN, GAMMA_MAX);
12872b4363aSmrg		    exit(1);
12972b4363aSmrg		}
13072b4363aSmrg		continue;
13172b4363aSmrg	    } else if (isabbreviation ("-rgamma", arg, 2)) {
13272b4363aSmrg		if (++i >= argc) Syntax ();
13372b4363aSmrg		if (gam >= 0.) Syntax ();
13472b4363aSmrg		rgam = (float)atof(argv[i]);
13572b4363aSmrg		if ((rgam < GAMMA_MIN) || (rgam > GAMMA_MAX)) {
13672b4363aSmrg		    fprintf(stderr,
13772b4363aSmrg			    "Gamma values must be between %6.3f and %6.3f\n",
13872b4363aSmrg			    GAMMA_MIN, GAMMA_MAX);
13972b4363aSmrg		    exit(1);
14072b4363aSmrg		}
14172b4363aSmrg		continue;
14272b4363aSmrg	    } else if (isabbreviation ("-ggamma", arg, 2)) {
14372b4363aSmrg		if (++i >= argc) Syntax ();
14472b4363aSmrg		if (gam >= 0.) Syntax ();
14572b4363aSmrg		ggam = (float)atof(argv[i]);
14672b4363aSmrg		if ((ggam < GAMMA_MIN) || (ggam > GAMMA_MAX)) {
14772b4363aSmrg		    fprintf(stderr,
14872b4363aSmrg			    "Gamma values must be between %6.3f and %6.3f\n",
14972b4363aSmrg			    GAMMA_MIN, GAMMA_MAX);
15072b4363aSmrg		    exit(1);
15172b4363aSmrg		}
15272b4363aSmrg		continue;
15372b4363aSmrg	    } else if (isabbreviation ("-bgamma", arg, 2)) {
15472b4363aSmrg		if (++i >= argc) Syntax ();
15572b4363aSmrg		if (gam >= 0.) Syntax ();
15672b4363aSmrg		bgam = (float)atof(argv[i]);
15772b4363aSmrg		if ((bgam < GAMMA_MIN) || (bgam > GAMMA_MAX)) {
15872b4363aSmrg		    fprintf(stderr,
15972b4363aSmrg			    "Gamma values must be between %6.3f and %6.3f\n",
16072b4363aSmrg			    GAMMA_MIN, GAMMA_MAX);
16172b4363aSmrg		    exit(1);
16272b4363aSmrg		}
16372b4363aSmrg		continue;
16472b4363aSmrg	    } else
16572b4363aSmrg		Syntax ();
16672b4363aSmrg	} else
16772b4363aSmrg	    Syntax ();
16872b4363aSmrg    }
16972b4363aSmrg
17072b4363aSmrg    if ((dpy = XOpenDisplay(displayname)) == NULL) {
17172b4363aSmrg	fprintf (stderr, "%s:  unable to open display '%s'\n",
17272b4363aSmrg		 ProgramName, XDisplayName (displayname));
17372b4363aSmrg	exit(1);
17472b4363aSmrg    } else if (screen == -1)
17572b4363aSmrg	screen = DefaultScreen(dpy);
17672b4363aSmrg
17772b4363aSmrg    if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
17872b4363aSmrg	fprintf(stderr, "Unable to query video extension version\n");
17972b4363aSmrg	exit(2);
18072b4363aSmrg    }
18172b4363aSmrg
18272b4363aSmrg    if (!XF86VidModeQueryExtension(dpy, &EventBase, &ErrorBase)) {
18372b4363aSmrg	fprintf(stderr, "Unable to query video extension information\n");
18472b4363aSmrg	exit(2);
18572b4363aSmrg    }
18672b4363aSmrg
18772b4363aSmrg    /* Fail if the extension version in the server is too old */
18872b4363aSmrg    if (MajorVersion < MINMAJOR ||
18972b4363aSmrg	(MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
19072b4363aSmrg	fprintf(stderr,
19172b4363aSmrg		"Xserver is running an old XFree86-VidModeExtension version"
19272b4363aSmrg		" (%d.%d)\n", MajorVersion, MinorVersion);
19372b4363aSmrg	fprintf(stderr, "Minimum required version is %d.%d\n",
19472b4363aSmrg		MINMAJOR, MINMINOR);
19572b4363aSmrg	exit(2);
19672b4363aSmrg    }
19772b4363aSmrg
19872b4363aSmrg    if (!XF86VidModeGetGamma(dpy, screen, &gamma)) {
19972b4363aSmrg	fprintf(stderr, "Unable to query gamma correction\n");
20072b4363aSmrg	XCloseDisplay (dpy);
20172b4363aSmrg	exit (2);
20272b4363aSmrg    } else if (!quiet)
20372b4363aSmrg	fprintf(stderr, "-> Red %6.3f, Green %6.3f, Blue %6.3f\n", gamma.red,
20472b4363aSmrg		gamma.green, gamma.blue);
20572b4363aSmrg
20672b4363aSmrg    ret = 0;
20772b4363aSmrg    if (gam >= 0.) {
20872b4363aSmrg	gamma.red = gam;
20972b4363aSmrg	gamma.green = gam;
21072b4363aSmrg	gamma.blue = gam;
21172b4363aSmrg	if (!XF86VidModeSetGamma(dpy, screen, &gamma)) {
21272b4363aSmrg	    fprintf(stderr, "Unable to set gamma correction\n");
21372b4363aSmrg	    ret = 2;
21472b4363aSmrg	} else {
21572b4363aSmrg	    if (!XF86VidModeGetGamma(dpy, screen, &gamma)) {
21672b4363aSmrg		fprintf(stderr, "Unable to query gamma correction\n");
21772b4363aSmrg		ret = 2;
21872b4363aSmrg	    } else if (!quiet)
21972b4363aSmrg		fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n",
22072b4363aSmrg		        gamma.red, gamma.green, gamma.blue);
22172b4363aSmrg	}
22272b4363aSmrg    } else if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.)) {
22372b4363aSmrg	if (rgam >= 0.) gamma.red = rgam;
22472b4363aSmrg	if (ggam >= 0.) gamma.green = ggam;
22572b4363aSmrg	if (bgam >= 0.) gamma.blue = bgam;
22672b4363aSmrg	if (!XF86VidModeSetGamma(dpy, screen, &gamma)) {
22772b4363aSmrg	    fprintf(stderr, "Unable to set gamma correction\n");
22872b4363aSmrg	    ret = 2;
22972b4363aSmrg	} else {
23072b4363aSmrg	    if (!XF86VidModeGetGamma(dpy, screen, &gamma)) {
23172b4363aSmrg		fprintf(stderr, "Unable to query gamma correction\n");
23272b4363aSmrg		ret = 2;
23372b4363aSmrg	    } else if (!quiet)
23472b4363aSmrg		fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n",
23572b4363aSmrg		        gamma.red, gamma.green, gamma.blue);
23672b4363aSmrg	}
23772b4363aSmrg    }
23872b4363aSmrg
23972b4363aSmrg    XCloseDisplay (dpy);
24072b4363aSmrg    exit (ret);
24172b4363aSmrg}
24272b4363aSmrg
243