xgamma.c revision 33dddc75
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 2533dddc75Smrg#ifdef HAVE_CONFIG_H 2633dddc75Smrg# include "config.h" 2733dddc75Smrg#endif 2833dddc75Smrg 2972b4363aSmrg#include <stdio.h> 3072b4363aSmrg#include <errno.h> 3172b4363aSmrg#include <X11/Xos.h> 3272b4363aSmrg#include <X11/Xlib.h> 3372b4363aSmrg#include <X11/Xutil.h> 3472b4363aSmrg#include <X11/extensions/xf86vmode.h> 3572b4363aSmrg#include <ctype.h> 3672b4363aSmrg#include <stdlib.h> 3772b4363aSmrg 38dd77ae96Smrgstatic char *ProgramName; 39dd77ae96Smrgstatic int MajorVersion, MinorVersion; 40dd77ae96Smrgstatic int EventBase, ErrorBase; 4172b4363aSmrg 4272b4363aSmrg/* Minimum extension version required */ 4372b4363aSmrg#define MINMAJOR 2 4472b4363aSmrg#define MINMINOR 0 4572b4363aSmrg 4672b4363aSmrg/* Maximum and Minimum gamma values */ 4772b4363aSmrg#define GAMMA_MIN 0.1 4872b4363aSmrg#define GAMMA_MAX 10.0 4972b4363aSmrg 5033dddc75Smrgstatic void _X_NORETURN 5133dddc75SmrgSyntax(const char *errmsg) 5272b4363aSmrg{ 5333dddc75Smrg if (errmsg != NULL) 5433dddc75Smrg fprintf (stderr, "%s: %s\n\n", ProgramName, errmsg); 5533dddc75Smrg 5633dddc75Smrg fprintf (stderr, "usage: %s [-options]\n\n%s", ProgramName, 5733dddc75Smrg "where the available options are:\n" 5833dddc75Smrg " -display host:dpy or -d\n" 5933dddc75Smrg " -quiet or -q\n" 6033dddc75Smrg " -screen or -s\n" 6133dddc75Smrg " -version or -v\n" 6233dddc75Smrg " -gamma f.f Gamma Value\n" 6333dddc75Smrg " -rgamma f.f Red Gamma Value\n" 6433dddc75Smrg " -ggamma f.f Green Gamma Value\n" 6533dddc75Smrg " -bgamma f.f Blue Gamma Value\n\n" 6633dddc75Smrg "If no gamma is specified, returns the current setting\n"); 6772b4363aSmrg exit (1); 6872b4363aSmrg} 6972b4363aSmrg 7072b4363aSmrg 7172b4363aSmrg/* 7272b4363aSmrg * The following is a hack until XrmParseCommand is ready. It determines 7372b4363aSmrg * whether or not the given string is an abbreviation of the arg. 7472b4363aSmrg */ 7572b4363aSmrg 7672b4363aSmrgstatic Bool 7733dddc75Smrgisabbreviation(const char *arg, const char *s, size_t minslen) 7872b4363aSmrg{ 7933dddc75Smrg size_t arglen; 8033dddc75Smrg size_t slen; 8172b4363aSmrg 8272b4363aSmrg /* exact match */ 8372b4363aSmrg if (strcmp (arg, s) == 0) return (True); 8472b4363aSmrg 8572b4363aSmrg arglen = strlen (arg); 8672b4363aSmrg slen = strlen (s); 8772b4363aSmrg 8872b4363aSmrg /* too long or too short */ 8972b4363aSmrg if (slen >= arglen || slen < minslen) return (False); 9072b4363aSmrg 9172b4363aSmrg /* abbreviation */ 9272b4363aSmrg if (strncmp (arg, s, slen) == 0) return (True); 9372b4363aSmrg 9472b4363aSmrg /* bad */ 9572b4363aSmrg return (False); 9672b4363aSmrg} 9772b4363aSmrg 9872b4363aSmrgint 9972b4363aSmrgmain(int argc, char *argv[]) 10072b4363aSmrg{ 10172b4363aSmrg int i, ret; 10272b4363aSmrg char *displayname = NULL; 10372b4363aSmrg Display *dpy; 10472b4363aSmrg float gam = -1., rgam = -1., ggam = -1., bgam = -1.; 10572b4363aSmrg XF86VidModeGamma gamma; 10672b4363aSmrg Bool quiet = False; 10772b4363aSmrg int screen = -1; 10872b4363aSmrg 10972b4363aSmrg ProgramName = argv[0]; 11072b4363aSmrg for (i = 1; i < argc; i++) { 11172b4363aSmrg char *arg = argv[i]; 11272b4363aSmrg 11372b4363aSmrg if (arg[0] == '-') { 11472b4363aSmrg if (isabbreviation ("-display", arg, 1)) { 11533dddc75Smrg if (++i >= argc) Syntax ("-display requires an argument"); 11672b4363aSmrg displayname = argv[i]; 11772b4363aSmrg continue; 11872b4363aSmrg } else if (isabbreviation ("-quiet", arg, 1)) { 11972b4363aSmrg quiet = True; 12072b4363aSmrg continue; 12133dddc75Smrg } else if (isabbreviation ("-version", arg, 1)) { 12233dddc75Smrg puts(PACKAGE_STRING); 12333dddc75Smrg exit(0); 12472b4363aSmrg } else if (isabbreviation ("-screen", arg, 1)) { 12533dddc75Smrg if (++i >= argc) Syntax ("-screen requires an argument"); 12672b4363aSmrg screen = atoi(argv[i]); 12772b4363aSmrg continue; 12872b4363aSmrg } else if (isabbreviation ("-gamma", arg, 2)) { 12933dddc75Smrg if (++i >= argc) Syntax ("-gamma requires an argument"); 13072b4363aSmrg if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.)) 13133dddc75Smrg Syntax ("-gamma cannot be used with -rgamma, -ggamma, or -bgamma"); 13272b4363aSmrg gam = (float)atof(argv[i]); 13372b4363aSmrg if ((gam < GAMMA_MIN) || (gam > GAMMA_MAX)) { 13472b4363aSmrg fprintf(stderr, 13572b4363aSmrg "Gamma values must be between %6.3f and %6.3f\n", 13672b4363aSmrg GAMMA_MIN, GAMMA_MAX); 13772b4363aSmrg exit(1); 13872b4363aSmrg } 13972b4363aSmrg continue; 14072b4363aSmrg } else if (isabbreviation ("-rgamma", arg, 2)) { 14133dddc75Smrg if (++i >= argc) Syntax ("-rgamma requires an argument"); 14233dddc75Smrg if (gam >= 0.) Syntax ("cannot set both -gamma and -rgamma"); 14372b4363aSmrg rgam = (float)atof(argv[i]); 14472b4363aSmrg if ((rgam < GAMMA_MIN) || (rgam > GAMMA_MAX)) { 14572b4363aSmrg fprintf(stderr, 14672b4363aSmrg "Gamma values must be between %6.3f and %6.3f\n", 14772b4363aSmrg GAMMA_MIN, GAMMA_MAX); 14872b4363aSmrg exit(1); 14972b4363aSmrg } 15072b4363aSmrg continue; 15172b4363aSmrg } else if (isabbreviation ("-ggamma", arg, 2)) { 15233dddc75Smrg if (++i >= argc) Syntax ("-ggamma requires an argument"); 15333dddc75Smrg if (gam >= 0.) Syntax ("cannot set both -gamma and -ggamma"); 15472b4363aSmrg ggam = (float)atof(argv[i]); 15572b4363aSmrg if ((ggam < GAMMA_MIN) || (ggam > GAMMA_MAX)) { 15672b4363aSmrg fprintf(stderr, 15772b4363aSmrg "Gamma values must be between %6.3f and %6.3f\n", 15872b4363aSmrg GAMMA_MIN, GAMMA_MAX); 15972b4363aSmrg exit(1); 16072b4363aSmrg } 16172b4363aSmrg continue; 16272b4363aSmrg } else if (isabbreviation ("-bgamma", arg, 2)) { 16333dddc75Smrg if (++i >= argc) Syntax ("-bgamma requires an argument"); 16433dddc75Smrg if (gam >= 0.) Syntax ("cannot set both -gamma and -bgamma"); 16572b4363aSmrg bgam = (float)atof(argv[i]); 16672b4363aSmrg if ((bgam < GAMMA_MIN) || (bgam > GAMMA_MAX)) { 16772b4363aSmrg fprintf(stderr, 16872b4363aSmrg "Gamma values must be between %6.3f and %6.3f\n", 16972b4363aSmrg GAMMA_MIN, GAMMA_MAX); 17072b4363aSmrg exit(1); 17172b4363aSmrg } 17272b4363aSmrg continue; 17333dddc75Smrg } else { 17433dddc75Smrg if (!isabbreviation ("-help", arg, 1)) 17533dddc75Smrg fprintf (stderr, "%s: unrecognized argument %s\n\n", 17633dddc75Smrg ProgramName, arg); 17733dddc75Smrg Syntax (NULL); 17833dddc75Smrg } 17933dddc75Smrg } else { 18033dddc75Smrg fprintf (stderr, "%s: unrecognized argument %s\n\n", 18133dddc75Smrg ProgramName, arg); 18233dddc75Smrg Syntax (NULL); 18333dddc75Smrg } 18472b4363aSmrg } 18572b4363aSmrg 18672b4363aSmrg if ((dpy = XOpenDisplay(displayname)) == NULL) { 18772b4363aSmrg fprintf (stderr, "%s: unable to open display '%s'\n", 18872b4363aSmrg ProgramName, XDisplayName (displayname)); 18972b4363aSmrg exit(1); 19072b4363aSmrg } else if (screen == -1) 19172b4363aSmrg screen = DefaultScreen(dpy); 19272b4363aSmrg 19372b4363aSmrg if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 19472b4363aSmrg fprintf(stderr, "Unable to query video extension version\n"); 19572b4363aSmrg exit(2); 19672b4363aSmrg } 19772b4363aSmrg 19872b4363aSmrg if (!XF86VidModeQueryExtension(dpy, &EventBase, &ErrorBase)) { 19972b4363aSmrg fprintf(stderr, "Unable to query video extension information\n"); 20072b4363aSmrg exit(2); 20172b4363aSmrg } 20272b4363aSmrg 20372b4363aSmrg /* Fail if the extension version in the server is too old */ 20472b4363aSmrg if (MajorVersion < MINMAJOR || 20572b4363aSmrg (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { 20672b4363aSmrg fprintf(stderr, 20772b4363aSmrg "Xserver is running an old XFree86-VidModeExtension version" 20872b4363aSmrg " (%d.%d)\n", MajorVersion, MinorVersion); 20972b4363aSmrg fprintf(stderr, "Minimum required version is %d.%d\n", 21072b4363aSmrg MINMAJOR, MINMINOR); 21172b4363aSmrg exit(2); 21272b4363aSmrg } 21372b4363aSmrg 21472b4363aSmrg if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 21572b4363aSmrg fprintf(stderr, "Unable to query gamma correction\n"); 21672b4363aSmrg XCloseDisplay (dpy); 21772b4363aSmrg exit (2); 21872b4363aSmrg } else if (!quiet) 21972b4363aSmrg fprintf(stderr, "-> Red %6.3f, Green %6.3f, Blue %6.3f\n", gamma.red, 22072b4363aSmrg gamma.green, gamma.blue); 22172b4363aSmrg 22272b4363aSmrg ret = 0; 22372b4363aSmrg if (gam >= 0.) { 22472b4363aSmrg gamma.red = gam; 22572b4363aSmrg gamma.green = gam; 22672b4363aSmrg gamma.blue = gam; 22772b4363aSmrg if (!XF86VidModeSetGamma(dpy, screen, &gamma)) { 22872b4363aSmrg fprintf(stderr, "Unable to set gamma correction\n"); 22972b4363aSmrg ret = 2; 23072b4363aSmrg } else { 23172b4363aSmrg if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 23272b4363aSmrg fprintf(stderr, "Unable to query gamma correction\n"); 23372b4363aSmrg ret = 2; 23472b4363aSmrg } else if (!quiet) 23572b4363aSmrg fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n", 23672b4363aSmrg gamma.red, gamma.green, gamma.blue); 23772b4363aSmrg } 23872b4363aSmrg } else if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.)) { 23972b4363aSmrg if (rgam >= 0.) gamma.red = rgam; 24072b4363aSmrg if (ggam >= 0.) gamma.green = ggam; 24172b4363aSmrg if (bgam >= 0.) gamma.blue = bgam; 24272b4363aSmrg if (!XF86VidModeSetGamma(dpy, screen, &gamma)) { 24372b4363aSmrg fprintf(stderr, "Unable to set gamma correction\n"); 24472b4363aSmrg ret = 2; 24572b4363aSmrg } else { 24672b4363aSmrg if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 24772b4363aSmrg fprintf(stderr, "Unable to query gamma correction\n"); 24872b4363aSmrg ret = 2; 24972b4363aSmrg } else if (!quiet) 25072b4363aSmrg fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n", 25172b4363aSmrg gamma.red, gamma.green, gamma.blue); 25272b4363aSmrg } 25372b4363aSmrg } 25472b4363aSmrg 25572b4363aSmrg XCloseDisplay (dpy); 25672b4363aSmrg exit (ret); 25772b4363aSmrg} 25872b4363aSmrg 259