xresize
diff xresize.c @ 0:8555f3aabbc7
created hg repository for xresize, useful little bugger
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 10 Mar 2011 14:58:46 +0200 |
parents | |
children | a2c94df7f405 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xresize.c Thu Mar 10 14:58:46 2011 +0200 1.3 @@ -0,0 +1,261 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <ctype.h> 1.8 +#include <X11/Xlib.h> 1.9 + 1.10 +#ifdef USE_XRANDR 1.11 +#include <X11/extensions/Xrandr.h> 1.12 + 1.13 +char *randr_err_msg[] = { 1.14 + "RRSetConfigSuccess", 1.15 + "RRSetConfigInvalidConfigTime", 1.16 + "RRSetConfigInvalidTime", 1.17 + "RRSetConfigFailed" 1.18 +}; 1.19 +#endif 1.20 + 1.21 +#ifdef USE_XF86VM 1.22 +#include <X11/extensions/xf86vmode.h> 1.23 +#endif 1.24 + 1.25 +int get_size(Display *dpy, int scr, int *xsz, int *ysz); 1.26 +int set_size(Display *dpy, int scr, int xsz, int ysz); 1.27 + 1.28 +const char *usage = "usage: %s [options]\n" 1.29 + "options:\n" 1.30 + " -s <w>x<h> set specified screen size\n" 1.31 + " -f force size change without current size detection\n" 1.32 + " -h this usage information\n"; 1.33 + 1.34 +int use_xrandr = 1; 1.35 +int use_xf86vm = 1; 1.36 + 1.37 +int main(int argc, char **argv) 1.38 +{ 1.39 + int i, cur_xres, cur_yres, xres = -1, yres = -1; 1.40 + int force = 0; 1.41 + Display *dpy; 1.42 + int scr; 1.43 + 1.44 + for(i=1; i<argc; i++) { 1.45 + if(argv[i][0] == '-' && (argv[i][2] == 0 || argv[i][1] == '-')) { 1.46 + char *sep; 1.47 + 1.48 + switch(argv[i][1]) { 1.49 + case 's': 1.50 + if(!isdigit(argv[++i][0]) || !(sep = strchr(argv[i], 'x')) || !isdigit(*(sep + 1))) { 1.51 + fputs("-s must be followed by something like \"640x480\"\n", stderr); 1.52 + return EXIT_FAILURE; 1.53 + } 1.54 + xres = atoi(argv[i]); 1.55 + yres = atoi(sep + 1); 1.56 + break; 1.57 + 1.58 + case 'f': 1.59 + force = 1; 1.60 + break; 1.61 + 1.62 + case 'h': 1.63 + printf(usage, argv[0]); 1.64 + return 0; 1.65 + 1.66 + case '-': 1.67 + if(strcmp(argv[i], "--no-xrandr") == 0) { 1.68 + use_xrandr = 0; 1.69 + break; 1.70 + } else if(strcmp(argv[i], "--no-xf86vm") == 0) { 1.71 + use_xf86vm = 0; 1.72 + break; 1.73 + } 1.74 + /* fallthrough to invalid arg */ 1.75 + default: 1.76 + fprintf(stderr, "unrecognized option: %s, try -h for usage\n", argv[i]); 1.77 + return 1; 1.78 + } 1.79 + } else { 1.80 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.81 + return 1; 1.82 + } 1.83 + } 1.84 + 1.85 + if(!(dpy = XOpenDisplay(0))) { 1.86 + fprintf(stderr, "failed to connect to the X server\n"); 1.87 + return 1; 1.88 + } 1.89 + scr = DefaultScreen(dpy); 1.90 + 1.91 + if(get_size(dpy, scr, &cur_xres, &cur_yres) == -1) { 1.92 + fprintf(stderr, "failed to retreive current screen size\n"); 1.93 + XCloseDisplay(dpy); 1.94 + return 1; 1.95 + } 1.96 + printf("current size: %dx%d\n", cur_xres, cur_yres); 1.97 + 1.98 + if(xres != -1) { /* size change requested */ 1.99 + if(xres != cur_xres || yres != cur_yres || force) { 1.100 + if(set_size(dpy, scr, xres, yres) == -1) { 1.101 + fprintf(stderr, "set_size failed\n"); 1.102 + XCloseDisplay(dpy); 1.103 + return 1; 1.104 + } 1.105 + printf("size updated sucessfully\n"); 1.106 + } else { 1.107 + printf("already at requested size! do nothing (use -f to force change).\n"); 1.108 + } 1.109 + } 1.110 + XCloseDisplay(dpy); 1.111 + return 0; 1.112 +} 1.113 + 1.114 +int get_size(Display *dpy, int scr, int *xsz, int *ysz) 1.115 +{ 1.116 + Window root; 1.117 + int event_base, error_base; 1.118 + 1.119 + scr = DefaultScreen(dpy); 1.120 + root = RootWindow(dpy, scr); 1.121 + 1.122 + /* first try r&r */ 1.123 +#ifdef USE_XRANDR 1.124 + if(use_xrandr && XRRQueryExtension(dpy, &event_base, &error_base)) { 1.125 + XRRScreenConfiguration *xrr_config; 1.126 + XRRScreenSize *ssizes; 1.127 + Rotation rot; 1.128 + int ssize_count, curr; 1.129 + 1.130 + if(!(xrr_config = XRRGetScreenInfo(dpy, root))) { 1.131 + fprintf(stderr, "failed to retrieve screen configuration\n"); 1.132 + return -1; 1.133 + } 1.134 + ssizes = XRRConfigSizes(xrr_config, &ssize_count); 1.135 + curr = XRRConfigCurrentConfiguration(xrr_config, &rot); 1.136 + 1.137 + *xsz = ssizes[curr].width; 1.138 + *ysz = ssizes[curr].height; 1.139 + 1.140 + XRRFreeScreenConfigInfo(xrr_config); 1.141 + return 0; 1.142 + } 1.143 +#endif 1.144 + 1.145 + /* then try xf86vm */ 1.146 +#ifdef USE_XF86VM 1.147 + if(use_xf86vm && XF86VidModeQueryExtension(dpy, &event_base, &error_base)) { 1.148 + XF86VidModeModeLine modeline; 1.149 + int dot_clock; 1.150 + 1.151 + if(!XF86VidModeGetModeLine(dpy, scr, &dot_clock, &modeline)) { 1.152 + fprintf(stderr, "failed to get current video mode\n"); 1.153 + return -1; 1.154 + } 1.155 + 1.156 + *xsz = modeline.hdisplay; 1.157 + *ysz = modeline.vdisplay; 1.158 + 1.159 + if(modeline.privsize) { 1.160 + XFree(modeline.private); 1.161 + } 1.162 + return 0; 1.163 + } 1.164 +#endif 1.165 + 1.166 + fprintf(stderr, "can't get any size information\n"); 1.167 + return -1; 1.168 +} 1.169 + 1.170 + 1.171 +int set_size(Display *dpy, int scr, int xsz, int ysz) 1.172 +{ 1.173 + int i, event_base, error_base; 1.174 + Window root; 1.175 + 1.176 + root = RootWindow(dpy, scr); 1.177 + 1.178 + /* first try r&r */ 1.179 +#ifdef USE_XRANDR 1.180 + if(use_xrandr && XRRQueryExtension(dpy, &event_base, &error_base)) { 1.181 + Status st; 1.182 + XRRScreenConfiguration *xrr_config; 1.183 + XRRScreenSize *ssizes; 1.184 + Rotation rot; 1.185 + int ssize_count, curr; 1.186 + Time timestamp, cfg_timestamp; 1.187 + 1.188 + if(!(xrr_config = XRRGetScreenInfo(dpy, root))) { 1.189 + fprintf(stderr, "failed to retrieve screen configuration\n"); 1.190 + return -1; 1.191 + } 1.192 + ssizes = XRRConfigSizes(xrr_config, &ssize_count); 1.193 + curr = XRRConfigCurrentConfiguration(xrr_config, &rot); 1.194 + timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp); 1.195 + 1.196 + if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) { 1.197 + XRRFreeScreenConfigInfo(xrr_config); 1.198 + return 0; 1.199 + } 1.200 + 1.201 + for(i=0; i<ssize_count; i++) { 1.202 + if(ssizes[i].width == xsz && ssizes[i].height == ysz) { 1.203 + break; 1.204 + } 1.205 + } 1.206 + if(i == ssize_count) { 1.207 + fprintf(stderr, "requested size unsuppored by the X server configuration\n"); 1.208 + XRRFreeScreenConfigInfo(xrr_config); 1.209 + return -1; 1.210 + } 1.211 + 1.212 + if((st = XRRSetScreenConfig(dpy, xrr_config, root, i, rot, timestamp)) != 0) { 1.213 + fprintf(stderr, "failed to set resolution with r-and-r, error: %d (%s)\n", st, randr_err_msg[st]); 1.214 + XRRFreeScreenConfigInfo(xrr_config); 1.215 +#ifdef USE_XF86VM 1.216 + printf("retrying with xf86vm...\n"); 1.217 + goto retry_with_xf86vm; 1.218 +#endif 1.219 + return -1; 1.220 + } 1.221 + 1.222 + XRRFreeScreenConfigInfo(xrr_config); 1.223 + return 0; 1.224 + } 1.225 +#endif 1.226 + 1.227 + /*try xf86vm */ 1.228 +#ifdef USE_XF86VM 1.229 +retry_with_xf86vm: 1.230 + if(use_xf86vm && XF86VidModeQueryExtension(dpy, &event_base, &error_base)) { 1.231 + XF86VidModeModeInfo **modes; 1.232 + int mode_count; 1.233 + 1.234 + if(!XF86VidModeGetAllModeLines(dpy, scr, &mode_count, &modes)) { 1.235 + fprintf(stderr, "failed to get list of available video modes\n"); 1.236 + return -1; 1.237 + } 1.238 + 1.239 + for(i=0; i<mode_count; i++) { 1.240 + if(modes[i]->hdisplay == xsz && modes[i]->vdisplay == ysz) { 1.241 + break; 1.242 + } 1.243 + } 1.244 + if(i == mode_count) { 1.245 + fprintf(stderr, "requested size unsuppored by the X server configuration\n"); 1.246 + XFree(modes); 1.247 + return -1; 1.248 + } 1.249 + 1.250 + if(!XF86VidModeSwitchToMode(dpy, scr, modes[i])) { 1.251 + fprintf(stderr, "failed to set requested size with xf86vm\n"); 1.252 + XFree(modes); 1.253 + return -1; 1.254 + } 1.255 + XF86VidModeSetViewPort(dpy, scr, 0, 0); 1.256 + 1.257 + XFree(modes); 1.258 + return 0; 1.259 + } 1.260 +#endif 1.261 + 1.262 + fprintf(stderr, "not possible to change display size\n"); 1.263 + return -1; 1.264 +}