xgamma.c revision 7ed541ca
1/* 2 * Copyright 1999 The XFree86 Project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Written by David Bateman 23 */ 24 25#ifdef HAVE_CONFIG_H 26# include "config.h" 27#endif 28 29#include <stdio.h> 30#include <errno.h> 31#include <X11/Xos.h> 32#include <X11/Xlib.h> 33#include <X11/Xutil.h> 34#include <X11/extensions/xf86vmode.h> 35#include <ctype.h> 36#include <stdlib.h> 37 38#ifndef HAVE_STRTOF 39#define strtof(a, n) (float)atof(a) 40#endif 41 42static char *ProgramName; 43static int MajorVersion, MinorVersion; 44static int EventBase, ErrorBase; 45 46/* Minimum extension version required */ 47#define MINMAJOR 2 48#define MINMINOR 0 49 50/* Maximum and Minimum gamma values */ 51#define GAMMA_MIN 0.1f 52#define GAMMA_MAX 10.0f 53 54static void _X_NORETURN 55Syntax(const char *errmsg) 56{ 57 if (errmsg != NULL) 58 fprintf (stderr, "%s: %s\n\n", ProgramName, errmsg); 59 60 fprintf (stderr, "usage: %s [-options]\n\n%s", ProgramName, 61 "where the available options are:\n" 62 " -display host:dpy or -d\n" 63 " -quiet or -q\n" 64 " -screen or -s\n" 65 " -version or -v\n" 66 " -gamma f.f Gamma Value\n" 67 " -rgamma f.f Red Gamma Value\n" 68 " -ggamma f.f Green Gamma Value\n" 69 " -bgamma f.f Blue Gamma Value\n\n" 70 "If no gamma is specified, returns the current setting\n"); 71 exit (1); 72} 73 74 75/* 76 * The following is a hack until XrmParseCommand is ready. It determines 77 * whether or not the given string is an abbreviation of the arg. 78 */ 79 80static Bool 81isabbreviation(const char *arg, const char *s, size_t minslen) 82{ 83 size_t arglen; 84 size_t slen; 85 86 /* exact match */ 87 if (strcmp (arg, s) == 0) return (True); 88 89 arglen = strlen (arg); 90 slen = strlen (s); 91 92 /* too long or too short */ 93 if (slen >= arglen || slen < minslen) return (False); 94 95 /* abbreviation */ 96 if (strncmp (arg, s, slen) == 0) return (True); 97 98 /* bad */ 99 return (False); 100} 101 102int 103main(int argc, char *argv[]) 104{ 105 int ret = 2; 106 char *displayname = NULL; 107 Display *dpy; 108 float gam = -1.0f, rgam = -1.0f, ggam = -1.0f, bgam = -1.0f; 109 XF86VidModeGamma gamma; 110 Bool quiet = False; 111 int screen = -1; 112 113 ProgramName = argv[0]; 114 for (int i = 1; i < argc; i++) { 115 char *arg = argv[i]; 116 117 if (arg[0] == '-') { 118 if (isabbreviation ("-display", arg, 1)) { 119 if (++i >= argc) Syntax ("-display requires an argument"); 120 displayname = argv[i]; 121 continue; 122 } else if (isabbreviation ("-quiet", arg, 1)) { 123 quiet = True; 124 continue; 125 } else if (isabbreviation ("-version", arg, 1)) { 126 puts(PACKAGE_STRING); 127 exit(0); 128 } else if (isabbreviation ("-screen", arg, 1)) { 129 if (++i >= argc) Syntax ("-screen requires an argument"); 130 screen = atoi(argv[i]); 131 continue; 132 } else if (isabbreviation ("-gamma", arg, 2)) { 133 if (++i >= argc) Syntax ("-gamma requires an argument"); 134 if ((rgam >= 0.0f) || (ggam >= 0.0f) || (bgam >= 0.0f)) 135 Syntax ("-gamma cannot be used with -rgamma, -ggamma, or -bgamma"); 136 gam = strtof(argv[i], NULL); 137 if ((gam < GAMMA_MIN) || (gam > GAMMA_MAX)) { 138 fprintf(stderr, 139 "Gamma values must be between %6.3f and %6.3f\n", 140 (double)GAMMA_MIN, (double)GAMMA_MAX); 141 exit(1); 142 } 143 continue; 144 } else if (isabbreviation ("-rgamma", arg, 2)) { 145 if (++i >= argc) Syntax ("-rgamma requires an argument"); 146 if (gam >= 0.0f) Syntax ("cannot set both -gamma and -rgamma"); 147 rgam = strtof(argv[i], NULL); 148 if ((rgam < GAMMA_MIN) || (rgam > GAMMA_MAX)) { 149 fprintf(stderr, 150 "Gamma values must be between %6.3f and %6.3f\n", 151 (double)GAMMA_MIN, (double)GAMMA_MAX); 152 exit(1); 153 } 154 continue; 155 } else if (isabbreviation ("-ggamma", arg, 2)) { 156 if (++i >= argc) Syntax ("-ggamma requires an argument"); 157 if (gam >= 0.0f) Syntax ("cannot set both -gamma and -ggamma"); 158 ggam = strtof(argv[i], NULL); 159 if ((ggam < GAMMA_MIN) || (ggam > GAMMA_MAX)) { 160 fprintf(stderr, 161 "Gamma values must be between %6.3f and %6.3f\n", 162 (double)GAMMA_MIN, (double)GAMMA_MAX); 163 exit(1); 164 } 165 continue; 166 } else if (isabbreviation ("-bgamma", arg, 2)) { 167 if (++i >= argc) Syntax ("-bgamma requires an argument"); 168 if (gam >= 0.0f) Syntax ("cannot set both -gamma and -bgamma"); 169 bgam = strtof(argv[i], NULL); 170 if ((bgam < GAMMA_MIN) || (bgam > GAMMA_MAX)) { 171 fprintf(stderr, 172 "Gamma values must be between %6.3f and %6.3f\n", 173 (double)GAMMA_MIN, (double)GAMMA_MAX); 174 exit(1); 175 } 176 continue; 177 } else { 178 if (!isabbreviation ("-help", arg, 1)) 179 fprintf (stderr, "%s: unrecognized argument %s\n\n", 180 ProgramName, arg); 181 Syntax (NULL); 182 } 183 } else { 184 fprintf (stderr, "%s: unrecognized argument %s\n\n", 185 ProgramName, arg); 186 Syntax (NULL); 187 } 188 } 189 190 if ((dpy = XOpenDisplay(displayname)) == NULL) { 191 fprintf (stderr, "%s: unable to open display '%s'\n", 192 ProgramName, XDisplayName (displayname)); 193 exit(1); 194 } else if (screen == -1) 195 screen = DefaultScreen(dpy); 196 197 if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 198 fprintf(stderr, "Unable to query video extension version\n"); 199 goto finish; 200 } 201 202 if (!XF86VidModeQueryExtension(dpy, &EventBase, &ErrorBase)) { 203 fprintf(stderr, "Unable to query video extension information\n"); 204 goto finish; 205 } 206 207 /* Fail if the extension version in the server is too old */ 208 if (MajorVersion < MINMAJOR || 209 (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { 210 fprintf(stderr, 211 "Xserver is running an old XFree86-VidModeExtension version" 212 " (%d.%d)\n", MajorVersion, MinorVersion); 213 fprintf(stderr, "Minimum required version is %d.%d\n", 214 MINMAJOR, MINMINOR); 215 goto finish; 216 } 217 218 if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 219 fprintf(stderr, "Unable to query gamma correction\n"); 220 goto finish; 221 } else if (!quiet) 222 fprintf(stderr, "-> Red %6.3f, Green %6.3f, Blue %6.3f\n", 223 (double)gamma.red, (double)gamma.green, (double)gamma.blue); 224 225 if (gam >= 0.0f) { 226 gamma.red = gam; 227 gamma.green = gam; 228 gamma.blue = gam; 229 } else if ((rgam >= 0.0f) || (ggam >= 0.0f) || (bgam >= 0.0f)) { 230 if (rgam >= 0.0f) gamma.red = rgam; 231 if (ggam >= 0.0f) gamma.green = ggam; 232 if (bgam >= 0.0f) gamma.blue = bgam; 233 } else { 234 /* Not changing gamma, all done */ 235 ret = 0; 236 goto finish; 237 } 238 239 /* Change gamma now */ 240 if (!XF86VidModeSetGamma(dpy, screen, &gamma)) { 241 fprintf(stderr, "Unable to set gamma correction\n"); 242 } else { 243 if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 244 fprintf(stderr, "Unable to query gamma correction\n"); 245 } else { 246 ret = 0; /* Success! */ 247 if (!quiet) { 248 fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n", 249 (double)gamma.red, (double)gamma.green, 250 (double)gamma.blue); 251 } 252 } 253 } 254 255 finish: 256 XCloseDisplay (dpy); 257 exit (ret); 258} 259 260