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 }
|