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 42 static char *ProgramName; 43 static int MajorVersion, MinorVersion; 44 static 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 54 static void _X_NORETURN 55 Syntax(const char *errmsg, int exitstatus) 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 (exitstatus); 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 80 static Bool 81 isabbreviation(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 102 int 103 main(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) 120 Syntax ("-display requires an argument", EXIT_FAILURE); 121 displayname = argv[i]; 122 continue; 123 } else if (isabbreviation ("-quiet", arg, 1)) { 124 quiet = True; 125 continue; 126 } else if (isabbreviation ("-version", arg, 1) || 127 !strcmp("--version", arg)) { 128 puts(PACKAGE_STRING); 129 exit(EXIT_SUCCESS); 130 } else if (isabbreviation ("-help", arg, 1) || 131 !strcmp("--help", arg)) { 132 Syntax(NULL, EXIT_SUCCESS); 133 } else if (isabbreviation ("-screen", arg, 1)) { 134 if (++i >= argc) 135 Syntax ("-screen requires an argument", EXIT_FAILURE); 136 screen = atoi(argv[i]); 137 continue; 138 } else if (isabbreviation ("-gamma", arg, 2)) { 139 if (++i >= argc) 140 Syntax ("-gamma requires an argument", EXIT_FAILURE); 141 if ((rgam >= 0.0f) || (ggam >= 0.0f) || (bgam >= 0.0f)) 142 Syntax ("-gamma cannot be used with -rgamma, -ggamma, or -bgamma", EXIT_FAILURE); 143 gam = strtof(argv[i], NULL); 144 if ((gam < GAMMA_MIN) || (gam > GAMMA_MAX)) { 145 fprintf(stderr, 146 "Gamma values must be between %6.3f and %6.3f\n", 147 (double)GAMMA_MIN, (double)GAMMA_MAX); 148 exit(EXIT_FAILURE); 149 } 150 continue; 151 } else if (isabbreviation ("-rgamma", arg, 2)) { 152 if (++i >= argc) 153 Syntax ("-rgamma requires an argument", EXIT_FAILURE); 154 if (gam >= 0.0f) 155 Syntax ("cannot set both -gamma and -rgamma", EXIT_FAILURE); 156 rgam = strtof(argv[i], NULL); 157 if ((rgam < GAMMA_MIN) || (rgam > GAMMA_MAX)) { 158 fprintf(stderr, 159 "Gamma values must be between %6.3f and %6.3f\n", 160 (double)GAMMA_MIN, (double)GAMMA_MAX); 161 exit(EXIT_FAILURE); 162 } 163 continue; 164 } else if (isabbreviation ("-ggamma", arg, 2)) { 165 if (++i >= argc) 166 Syntax ("-ggamma requires an argument", EXIT_FAILURE); 167 if (gam >= 0.0f) 168 Syntax ("cannot set both -gamma and -ggamma", EXIT_FAILURE); 169 ggam = strtof(argv[i], NULL); 170 if ((ggam < GAMMA_MIN) || (ggam > 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(EXIT_FAILURE); 175 } 176 continue; 177 } else if (isabbreviation ("-bgamma", arg, 2)) { 178 if (++i >= argc) 179 Syntax ("-bgamma requires an argument", EXIT_FAILURE); 180 if (gam >= 0.0f) 181 Syntax ("cannot set both -gamma and -bgamma", EXIT_FAILURE); 182 bgam = strtof(argv[i], NULL); 183 if ((bgam < GAMMA_MIN) || (bgam > GAMMA_MAX)) { 184 fprintf(stderr, 185 "Gamma values must be between %6.3f and %6.3f\n", 186 (double)GAMMA_MIN, (double)GAMMA_MAX); 187 exit(EXIT_FAILURE); 188 } 189 continue; 190 } else { 191 fprintf (stderr, "%s: unrecognized argument %s\n\n", 192 ProgramName, arg); 193 Syntax (NULL, EXIT_FAILURE); 194 } 195 } else { 196 fprintf (stderr, "%s: unrecognized argument %s\n\n", 197 ProgramName, arg); 198 Syntax (NULL, EXIT_FAILURE); 199 } 200 } 201 202 if ((dpy = XOpenDisplay(displayname)) == NULL) { 203 fprintf (stderr, "%s: unable to open display '%s'\n", 204 ProgramName, XDisplayName (displayname)); 205 exit(EXIT_FAILURE); 206 } else if (screen == -1) 207 screen = DefaultScreen(dpy); 208 209 if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 210 fprintf(stderr, "Unable to query video extension version\n"); 211 goto finish; 212 } 213 214 if (!XF86VidModeQueryExtension(dpy, &EventBase, &ErrorBase)) { 215 fprintf(stderr, "Unable to query video extension information\n"); 216 goto finish; 217 } 218 219 /* Fail if the extension version in the server is too old */ 220 if (MajorVersion < MINMAJOR || 221 (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { 222 fprintf(stderr, 223 "Xserver is running an old XFree86-VidModeExtension version" 224 " (%d.%d)\n", MajorVersion, MinorVersion); 225 fprintf(stderr, "Minimum required version is %d.%d\n", 226 MINMAJOR, MINMINOR); 227 goto finish; 228 } 229 230 if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 231 fprintf(stderr, "Unable to query gamma correction\n"); 232 goto finish; 233 } else if (!quiet) 234 fprintf(stderr, "-> Red %6.3f, Green %6.3f, Blue %6.3f\n", 235 (double)gamma.red, (double)gamma.green, (double)gamma.blue); 236 237 if (gam >= 0.0f) { 238 gamma.red = gam; 239 gamma.green = gam; 240 gamma.blue = gam; 241 } else if ((rgam >= 0.0f) || (ggam >= 0.0f) || (bgam >= 0.0f)) { 242 if (rgam >= 0.0f) gamma.red = rgam; 243 if (ggam >= 0.0f) gamma.green = ggam; 244 if (bgam >= 0.0f) gamma.blue = bgam; 245 } else { 246 /* Not changing gamma, all done */ 247 ret = EXIT_SUCCESS; 248 goto finish; 249 } 250 251 /* Change gamma now */ 252 if (!XF86VidModeSetGamma(dpy, screen, &gamma)) { 253 fprintf(stderr, "Unable to set gamma correction\n"); 254 } else { 255 if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { 256 fprintf(stderr, "Unable to query gamma correction\n"); 257 } else { 258 ret = EXIT_SUCCESS; /* Success! */ 259 if (!quiet) { 260 fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n", 261 (double)gamma.red, (double)gamma.green, 262 (double)gamma.blue); 263 } 264 } 265 } 266 267 finish: 268 XCloseDisplay (dpy); 269 exit (ret); 270 } 271 272