xresize
changeset 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 |
files | Makefile xresize.c |
diffstat | 2 files changed, 274 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/Makefile Thu Mar 10 14:58:46 2011 +0200 1.3 @@ -0,0 +1,13 @@ 1.4 +obj = xresize.o 1.5 +bin = xresize 1.6 + 1.7 +CC = gcc 1.8 +CFLAGS = -pedantic -Wall -g -I/usr/X11R6/include -DUSE_XRANDR -DUSE_XF86VM 1.9 +LDFLAGS = -L/usr/X11R6/lib -lX11 -lXrandr -lXxf86vm 1.10 + 1.11 +$(bin): $(obj) 1.12 + $(CC) -o $@ $(obj) $(LDFLAGS) 1.13 + 1.14 +.PHONY: clean 1.15 +clean: 1.16 + rm -f $(obj) $(bin)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/xresize.c Thu Mar 10 14:58:46 2011 +0200 2.3 @@ -0,0 +1,261 @@ 2.4 +#include <stdio.h> 2.5 +#include <stdlib.h> 2.6 +#include <string.h> 2.7 +#include <ctype.h> 2.8 +#include <X11/Xlib.h> 2.9 + 2.10 +#ifdef USE_XRANDR 2.11 +#include <X11/extensions/Xrandr.h> 2.12 + 2.13 +char *randr_err_msg[] = { 2.14 + "RRSetConfigSuccess", 2.15 + "RRSetConfigInvalidConfigTime", 2.16 + "RRSetConfigInvalidTime", 2.17 + "RRSetConfigFailed" 2.18 +}; 2.19 +#endif 2.20 + 2.21 +#ifdef USE_XF86VM 2.22 +#include <X11/extensions/xf86vmode.h> 2.23 +#endif 2.24 + 2.25 +int get_size(Display *dpy, int scr, int *xsz, int *ysz); 2.26 +int set_size(Display *dpy, int scr, int xsz, int ysz); 2.27 + 2.28 +const char *usage = "usage: %s [options]\n" 2.29 + "options:\n" 2.30 + " -s <w>x<h> set specified screen size\n" 2.31 + " -f force size change without current size detection\n" 2.32 + " -h this usage information\n"; 2.33 + 2.34 +int use_xrandr = 1; 2.35 +int use_xf86vm = 1; 2.36 + 2.37 +int main(int argc, char **argv) 2.38 +{ 2.39 + int i, cur_xres, cur_yres, xres = -1, yres = -1; 2.40 + int force = 0; 2.41 + Display *dpy; 2.42 + int scr; 2.43 + 2.44 + for(i=1; i<argc; i++) { 2.45 + if(argv[i][0] == '-' && (argv[i][2] == 0 || argv[i][1] == '-')) { 2.46 + char *sep; 2.47 + 2.48 + switch(argv[i][1]) { 2.49 + case 's': 2.50 + if(!isdigit(argv[++i][0]) || !(sep = strchr(argv[i], 'x')) || !isdigit(*(sep + 1))) { 2.51 + fputs("-s must be followed by something like \"640x480\"\n", stderr); 2.52 + return EXIT_FAILURE; 2.53 + } 2.54 + xres = atoi(argv[i]); 2.55 + yres = atoi(sep + 1); 2.56 + break; 2.57 + 2.58 + case 'f': 2.59 + force = 1; 2.60 + break; 2.61 + 2.62 + case 'h': 2.63 + printf(usage, argv[0]); 2.64 + return 0; 2.65 + 2.66 + case '-': 2.67 + if(strcmp(argv[i], "--no-xrandr") == 0) { 2.68 + use_xrandr = 0; 2.69 + break; 2.70 + } else if(strcmp(argv[i], "--no-xf86vm") == 0) { 2.71 + use_xf86vm = 0; 2.72 + break; 2.73 + } 2.74 + /* fallthrough to invalid arg */ 2.75 + default: 2.76 + fprintf(stderr, "unrecognized option: %s, try -h for usage\n", argv[i]); 2.77 + return 1; 2.78 + } 2.79 + } else { 2.80 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 2.81 + return 1; 2.82 + } 2.83 + } 2.84 + 2.85 + if(!(dpy = XOpenDisplay(0))) { 2.86 + fprintf(stderr, "failed to connect to the X server\n"); 2.87 + return 1; 2.88 + } 2.89 + scr = DefaultScreen(dpy); 2.90 + 2.91 + if(get_size(dpy, scr, &cur_xres, &cur_yres) == -1) { 2.92 + fprintf(stderr, "failed to retreive current screen size\n"); 2.93 + XCloseDisplay(dpy); 2.94 + return 1; 2.95 + } 2.96 + printf("current size: %dx%d\n", cur_xres, cur_yres); 2.97 + 2.98 + if(xres != -1) { /* size change requested */ 2.99 + if(xres != cur_xres || yres != cur_yres || force) { 2.100 + if(set_size(dpy, scr, xres, yres) == -1) { 2.101 + fprintf(stderr, "set_size failed\n"); 2.102 + XCloseDisplay(dpy); 2.103 + return 1; 2.104 + } 2.105 + printf("size updated sucessfully\n"); 2.106 + } else { 2.107 + printf("already at requested size! do nothing (use -f to force change).\n"); 2.108 + } 2.109 + } 2.110 + XCloseDisplay(dpy); 2.111 + return 0; 2.112 +} 2.113 + 2.114 +int get_size(Display *dpy, int scr, int *xsz, int *ysz) 2.115 +{ 2.116 + Window root; 2.117 + int event_base, error_base; 2.118 + 2.119 + scr = DefaultScreen(dpy); 2.120 + root = RootWindow(dpy, scr); 2.121 + 2.122 + /* first try r&r */ 2.123 +#ifdef USE_XRANDR 2.124 + if(use_xrandr && XRRQueryExtension(dpy, &event_base, &error_base)) { 2.125 + XRRScreenConfiguration *xrr_config; 2.126 + XRRScreenSize *ssizes; 2.127 + Rotation rot; 2.128 + int ssize_count, curr; 2.129 + 2.130 + if(!(xrr_config = XRRGetScreenInfo(dpy, root))) { 2.131 + fprintf(stderr, "failed to retrieve screen configuration\n"); 2.132 + return -1; 2.133 + } 2.134 + ssizes = XRRConfigSizes(xrr_config, &ssize_count); 2.135 + curr = XRRConfigCurrentConfiguration(xrr_config, &rot); 2.136 + 2.137 + *xsz = ssizes[curr].width; 2.138 + *ysz = ssizes[curr].height; 2.139 + 2.140 + XRRFreeScreenConfigInfo(xrr_config); 2.141 + return 0; 2.142 + } 2.143 +#endif 2.144 + 2.145 + /* then try xf86vm */ 2.146 +#ifdef USE_XF86VM 2.147 + if(use_xf86vm && XF86VidModeQueryExtension(dpy, &event_base, &error_base)) { 2.148 + XF86VidModeModeLine modeline; 2.149 + int dot_clock; 2.150 + 2.151 + if(!XF86VidModeGetModeLine(dpy, scr, &dot_clock, &modeline)) { 2.152 + fprintf(stderr, "failed to get current video mode\n"); 2.153 + return -1; 2.154 + } 2.155 + 2.156 + *xsz = modeline.hdisplay; 2.157 + *ysz = modeline.vdisplay; 2.158 + 2.159 + if(modeline.privsize) { 2.160 + XFree(modeline.private); 2.161 + } 2.162 + return 0; 2.163 + } 2.164 +#endif 2.165 + 2.166 + fprintf(stderr, "can't get any size information\n"); 2.167 + return -1; 2.168 +} 2.169 + 2.170 + 2.171 +int set_size(Display *dpy, int scr, int xsz, int ysz) 2.172 +{ 2.173 + int i, event_base, error_base; 2.174 + Window root; 2.175 + 2.176 + root = RootWindow(dpy, scr); 2.177 + 2.178 + /* first try r&r */ 2.179 +#ifdef USE_XRANDR 2.180 + if(use_xrandr && XRRQueryExtension(dpy, &event_base, &error_base)) { 2.181 + Status st; 2.182 + XRRScreenConfiguration *xrr_config; 2.183 + XRRScreenSize *ssizes; 2.184 + Rotation rot; 2.185 + int ssize_count, curr; 2.186 + Time timestamp, cfg_timestamp; 2.187 + 2.188 + if(!(xrr_config = XRRGetScreenInfo(dpy, root))) { 2.189 + fprintf(stderr, "failed to retrieve screen configuration\n"); 2.190 + return -1; 2.191 + } 2.192 + ssizes = XRRConfigSizes(xrr_config, &ssize_count); 2.193 + curr = XRRConfigCurrentConfiguration(xrr_config, &rot); 2.194 + timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp); 2.195 + 2.196 + if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) { 2.197 + XRRFreeScreenConfigInfo(xrr_config); 2.198 + return 0; 2.199 + } 2.200 + 2.201 + for(i=0; i<ssize_count; i++) { 2.202 + if(ssizes[i].width == xsz && ssizes[i].height == ysz) { 2.203 + break; 2.204 + } 2.205 + } 2.206 + if(i == ssize_count) { 2.207 + fprintf(stderr, "requested size unsuppored by the X server configuration\n"); 2.208 + XRRFreeScreenConfigInfo(xrr_config); 2.209 + return -1; 2.210 + } 2.211 + 2.212 + if((st = XRRSetScreenConfig(dpy, xrr_config, root, i, rot, timestamp)) != 0) { 2.213 + fprintf(stderr, "failed to set resolution with r-and-r, error: %d (%s)\n", st, randr_err_msg[st]); 2.214 + XRRFreeScreenConfigInfo(xrr_config); 2.215 +#ifdef USE_XF86VM 2.216 + printf("retrying with xf86vm...\n"); 2.217 + goto retry_with_xf86vm; 2.218 +#endif 2.219 + return -1; 2.220 + } 2.221 + 2.222 + XRRFreeScreenConfigInfo(xrr_config); 2.223 + return 0; 2.224 + } 2.225 +#endif 2.226 + 2.227 + /*try xf86vm */ 2.228 +#ifdef USE_XF86VM 2.229 +retry_with_xf86vm: 2.230 + if(use_xf86vm && XF86VidModeQueryExtension(dpy, &event_base, &error_base)) { 2.231 + XF86VidModeModeInfo **modes; 2.232 + int mode_count; 2.233 + 2.234 + if(!XF86VidModeGetAllModeLines(dpy, scr, &mode_count, &modes)) { 2.235 + fprintf(stderr, "failed to get list of available video modes\n"); 2.236 + return -1; 2.237 + } 2.238 + 2.239 + for(i=0; i<mode_count; i++) { 2.240 + if(modes[i]->hdisplay == xsz && modes[i]->vdisplay == ysz) { 2.241 + break; 2.242 + } 2.243 + } 2.244 + if(i == mode_count) { 2.245 + fprintf(stderr, "requested size unsuppored by the X server configuration\n"); 2.246 + XFree(modes); 2.247 + return -1; 2.248 + } 2.249 + 2.250 + if(!XF86VidModeSwitchToMode(dpy, scr, modes[i])) { 2.251 + fprintf(stderr, "failed to set requested size with xf86vm\n"); 2.252 + XFree(modes); 2.253 + return -1; 2.254 + } 2.255 + XF86VidModeSetViewPort(dpy, scr, 0, 0); 2.256 + 2.257 + XFree(modes); 2.258 + return 0; 2.259 + } 2.260 +#endif 2.261 + 2.262 + fprintf(stderr, "not possible to change display size\n"); 2.263 + return -1; 2.264 +}