xresize

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