xresize

annotate xresize.c @ 1:a2c94df7f405

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 04 Sep 2012 05:07:29 +0300
parents 8555f3aabbc7
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <string.h>
nuclear@0 4 #include <ctype.h>
nuclear@0 5 #include <X11/Xlib.h>
nuclear@0 6
nuclear@0 7 #ifdef USE_XRANDR
nuclear@0 8 #include <X11/extensions/Xrandr.h>
nuclear@0 9
nuclear@0 10 char *randr_err_msg[] = {
nuclear@0 11 "RRSetConfigSuccess",
nuclear@0 12 "RRSetConfigInvalidConfigTime",
nuclear@0 13 "RRSetConfigInvalidTime",
nuclear@0 14 "RRSetConfigFailed"
nuclear@0 15 };
nuclear@0 16 #endif
nuclear@0 17
nuclear@0 18 #ifdef USE_XF86VM
nuclear@0 19 #include <X11/extensions/xf86vmode.h>
nuclear@0 20 #endif
nuclear@0 21
nuclear@0 22 int get_size(Display *dpy, int scr, int *xsz, int *ysz);
nuclear@0 23 int set_size(Display *dpy, int scr, int xsz, int ysz);
nuclear@0 24
nuclear@0 25 const char *usage = "usage: %s [options]\n"
nuclear@0 26 "options:\n"
nuclear@0 27 " -s <w>x<h> set specified screen size\n"
nuclear@0 28 " -f force size change without current size detection\n"
nuclear@1 29 " --no-xrandr do not use the xrandr extension\n"
nuclear@1 30 " --no-xf86vm do not use the xf86-vidmode extension\n"
nuclear@0 31 " -h this usage information\n";
nuclear@0 32
nuclear@0 33 int use_xrandr = 1;
nuclear@0 34 int use_xf86vm = 1;
nuclear@0 35
nuclear@0 36 int main(int argc, char **argv)
nuclear@0 37 {
nuclear@0 38 int i, cur_xres, cur_yres, xres = -1, yres = -1;
nuclear@0 39 int force = 0;
nuclear@0 40 Display *dpy;
nuclear@0 41 int scr;
nuclear@0 42
nuclear@0 43 for(i=1; i<argc; i++) {
nuclear@0 44 if(argv[i][0] == '-' && (argv[i][2] == 0 || argv[i][1] == '-')) {
nuclear@0 45 char *sep;
nuclear@0 46
nuclear@0 47 switch(argv[i][1]) {
nuclear@0 48 case 's':
nuclear@0 49 if(!isdigit(argv[++i][0]) || !(sep = strchr(argv[i], 'x')) || !isdigit(*(sep + 1))) {
nuclear@0 50 fputs("-s must be followed by something like \"640x480\"\n", stderr);
nuclear@0 51 return EXIT_FAILURE;
nuclear@0 52 }
nuclear@0 53 xres = atoi(argv[i]);
nuclear@0 54 yres = atoi(sep + 1);
nuclear@0 55 break;
nuclear@0 56
nuclear@0 57 case 'f':
nuclear@0 58 force = 1;
nuclear@0 59 break;
nuclear@0 60
nuclear@0 61 case 'h':
nuclear@0 62 printf(usage, argv[0]);
nuclear@0 63 return 0;
nuclear@0 64
nuclear@0 65 case '-':
nuclear@0 66 if(strcmp(argv[i], "--no-xrandr") == 0) {
nuclear@0 67 use_xrandr = 0;
nuclear@0 68 break;
nuclear@0 69 } else if(strcmp(argv[i], "--no-xf86vm") == 0) {
nuclear@0 70 use_xf86vm = 0;
nuclear@0 71 break;
nuclear@0 72 }
nuclear@0 73 /* fallthrough to invalid arg */
nuclear@0 74 default:
nuclear@0 75 fprintf(stderr, "unrecognized option: %s, try -h for usage\n", argv[i]);
nuclear@0 76 return 1;
nuclear@0 77 }
nuclear@0 78 } else {
nuclear@0 79 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
nuclear@0 80 return 1;
nuclear@0 81 }
nuclear@0 82 }
nuclear@0 83
nuclear@0 84 if(!(dpy = XOpenDisplay(0))) {
nuclear@0 85 fprintf(stderr, "failed to connect to the X server\n");
nuclear@0 86 return 1;
nuclear@0 87 }
nuclear@0 88 scr = DefaultScreen(dpy);
nuclear@0 89
nuclear@0 90 if(get_size(dpy, scr, &cur_xres, &cur_yres) == -1) {
nuclear@0 91 fprintf(stderr, "failed to retreive current screen size\n");
nuclear@0 92 XCloseDisplay(dpy);
nuclear@0 93 return 1;
nuclear@0 94 }
nuclear@0 95 printf("current size: %dx%d\n", cur_xres, cur_yres);
nuclear@0 96
nuclear@0 97 if(xres != -1) { /* size change requested */
nuclear@0 98 if(xres != cur_xres || yres != cur_yres || force) {
nuclear@0 99 if(set_size(dpy, scr, xres, yres) == -1) {
nuclear@0 100 fprintf(stderr, "set_size failed\n");
nuclear@0 101 XCloseDisplay(dpy);
nuclear@0 102 return 1;
nuclear@0 103 }
nuclear@0 104 printf("size updated sucessfully\n");
nuclear@0 105 } else {
nuclear@0 106 printf("already at requested size! do nothing (use -f to force change).\n");
nuclear@0 107 }
nuclear@0 108 }
nuclear@0 109 XCloseDisplay(dpy);
nuclear@0 110 return 0;
nuclear@0 111 }
nuclear@0 112
nuclear@0 113 int get_size(Display *dpy, int scr, int *xsz, int *ysz)
nuclear@0 114 {
nuclear@0 115 Window root;
nuclear@0 116 int event_base, error_base;
nuclear@0 117
nuclear@0 118 scr = DefaultScreen(dpy);
nuclear@0 119 root = RootWindow(dpy, scr);
nuclear@0 120
nuclear@0 121 /* first try r&r */
nuclear@0 122 #ifdef USE_XRANDR
nuclear@0 123 if(use_xrandr && XRRQueryExtension(dpy, &event_base, &error_base)) {
nuclear@0 124 XRRScreenConfiguration *xrr_config;
nuclear@0 125 XRRScreenSize *ssizes;
nuclear@0 126 Rotation rot;
nuclear@0 127 int ssize_count, curr;
nuclear@0 128
nuclear@0 129 if(!(xrr_config = XRRGetScreenInfo(dpy, root))) {
nuclear@0 130 fprintf(stderr, "failed to retrieve screen configuration\n");
nuclear@0 131 return -1;
nuclear@0 132 }
nuclear@0 133 ssizes = XRRConfigSizes(xrr_config, &ssize_count);
nuclear@0 134 curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
nuclear@0 135
nuclear@0 136 *xsz = ssizes[curr].width;
nuclear@0 137 *ysz = ssizes[curr].height;
nuclear@0 138
nuclear@0 139 XRRFreeScreenConfigInfo(xrr_config);
nuclear@0 140 return 0;
nuclear@0 141 }
nuclear@0 142 #endif
nuclear@0 143
nuclear@0 144 /* then try xf86vm */
nuclear@0 145 #ifdef USE_XF86VM
nuclear@0 146 if(use_xf86vm && XF86VidModeQueryExtension(dpy, &event_base, &error_base)) {
nuclear@0 147 XF86VidModeModeLine modeline;
nuclear@0 148 int dot_clock;
nuclear@0 149
nuclear@0 150 if(!XF86VidModeGetModeLine(dpy, scr, &dot_clock, &modeline)) {
nuclear@0 151 fprintf(stderr, "failed to get current video mode\n");
nuclear@0 152 return -1;
nuclear@0 153 }
nuclear@0 154
nuclear@0 155 *xsz = modeline.hdisplay;
nuclear@0 156 *ysz = modeline.vdisplay;
nuclear@0 157
nuclear@0 158 if(modeline.privsize) {
nuclear@0 159 XFree(modeline.private);
nuclear@0 160 }
nuclear@0 161 return 0;
nuclear@0 162 }
nuclear@0 163 #endif
nuclear@0 164
nuclear@0 165 fprintf(stderr, "can't get any size information\n");
nuclear@0 166 return -1;
nuclear@0 167 }
nuclear@0 168
nuclear@0 169
nuclear@0 170 int set_size(Display *dpy, int scr, int xsz, int ysz)
nuclear@0 171 {
nuclear@0 172 int i, event_base, error_base;
nuclear@0 173 Window root;
nuclear@0 174
nuclear@0 175 root = RootWindow(dpy, scr);
nuclear@0 176
nuclear@0 177 /* first try r&r */
nuclear@0 178 #ifdef USE_XRANDR
nuclear@0 179 if(use_xrandr && XRRQueryExtension(dpy, &event_base, &error_base)) {
nuclear@0 180 Status st;
nuclear@0 181 XRRScreenConfiguration *xrr_config;
nuclear@0 182 XRRScreenSize *ssizes;
nuclear@0 183 Rotation rot;
nuclear@0 184 int ssize_count, curr;
nuclear@0 185 Time timestamp, cfg_timestamp;
nuclear@0 186
nuclear@0 187 if(!(xrr_config = XRRGetScreenInfo(dpy, root))) {
nuclear@0 188 fprintf(stderr, "failed to retrieve screen configuration\n");
nuclear@0 189 return -1;
nuclear@0 190 }
nuclear@0 191 ssizes = XRRConfigSizes(xrr_config, &ssize_count);
nuclear@0 192 curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
nuclear@0 193 timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp);
nuclear@0 194
nuclear@0 195 if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) {
nuclear@0 196 XRRFreeScreenConfigInfo(xrr_config);
nuclear@0 197 return 0;
nuclear@0 198 }
nuclear@0 199
nuclear@0 200 for(i=0; i<ssize_count; i++) {
nuclear@0 201 if(ssizes[i].width == xsz && ssizes[i].height == ysz) {
nuclear@0 202 break;
nuclear@0 203 }
nuclear@0 204 }
nuclear@0 205 if(i == ssize_count) {
nuclear@0 206 fprintf(stderr, "requested size unsuppored by the X server configuration\n");
nuclear@0 207 XRRFreeScreenConfigInfo(xrr_config);
nuclear@0 208 return -1;
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 if((st = XRRSetScreenConfig(dpy, xrr_config, root, i, rot, timestamp)) != 0) {
nuclear@0 212 fprintf(stderr, "failed to set resolution with r-and-r, error: %d (%s)\n", st, randr_err_msg[st]);
nuclear@0 213 XRRFreeScreenConfigInfo(xrr_config);
nuclear@0 214 #ifdef USE_XF86VM
nuclear@0 215 printf("retrying with xf86vm...\n");
nuclear@0 216 goto retry_with_xf86vm;
nuclear@0 217 #endif
nuclear@0 218 return -1;
nuclear@0 219 }
nuclear@0 220
nuclear@0 221 XRRFreeScreenConfigInfo(xrr_config);
nuclear@0 222 return 0;
nuclear@0 223 }
nuclear@0 224 #endif
nuclear@0 225
nuclear@0 226 /*try xf86vm */
nuclear@0 227 #ifdef USE_XF86VM
nuclear@0 228 retry_with_xf86vm:
nuclear@0 229 if(use_xf86vm && XF86VidModeQueryExtension(dpy, &event_base, &error_base)) {
nuclear@0 230 XF86VidModeModeInfo **modes;
nuclear@0 231 int mode_count;
nuclear@0 232
nuclear@0 233 if(!XF86VidModeGetAllModeLines(dpy, scr, &mode_count, &modes)) {
nuclear@0 234 fprintf(stderr, "failed to get list of available video modes\n");
nuclear@0 235 return -1;
nuclear@0 236 }
nuclear@0 237
nuclear@0 238 for(i=0; i<mode_count; i++) {
nuclear@0 239 if(modes[i]->hdisplay == xsz && modes[i]->vdisplay == ysz) {
nuclear@0 240 break;
nuclear@0 241 }
nuclear@0 242 }
nuclear@0 243 if(i == mode_count) {
nuclear@0 244 fprintf(stderr, "requested size unsuppored by the X server configuration\n");
nuclear@0 245 XFree(modes);
nuclear@0 246 return -1;
nuclear@0 247 }
nuclear@0 248
nuclear@0 249 if(!XF86VidModeSwitchToMode(dpy, scr, modes[i])) {
nuclear@0 250 fprintf(stderr, "failed to set requested size with xf86vm\n");
nuclear@0 251 XFree(modes);
nuclear@0 252 return -1;
nuclear@0 253 }
nuclear@0 254 XF86VidModeSetViewPort(dpy, scr, 0, 0);
nuclear@0 255
nuclear@0 256 XFree(modes);
nuclear@0 257 return 0;
nuclear@0 258 }
nuclear@0 259 #endif
nuclear@0 260
nuclear@0 261 fprintf(stderr, "not possible to change display size\n");
nuclear@0 262 return -1;
nuclear@0 263 }