2 * Copyright 2008-2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
15 #include <Application.h>
18 #include "ScreenMode.h"
21 static struct option
const kLongOptions
[] = {
22 {"fall-back", no_argument
, 0, 'f'},
23 {"dont-confirm", no_argument
, 0, 'q'},
24 {"modeline", no_argument
, 0, 'm'},
25 {"short", no_argument
, 0, 's'},
26 {"list", no_argument
, 0, 'l'},
27 {"help", no_argument
, 0, 'h'},
31 extern const char *__progname
;
32 static const char *kProgramName
= __progname
;
36 color_space_for_depth(int32 depth
)
55 print_mode(const screen_mode
& mode
, bool shortOutput
)
58 = shortOutput
? "%ld %ld %ld %g\n" : "%ld %ld, %ld bits, %g Hz\n";
59 printf(format
, mode
.width
, mode
.height
, mode
.BitsPerPixel(), mode
.refresh
);
64 print_mode(const display_mode
& displayMode
, const screen_mode
& mode
)
66 const display_timing
& timing
= displayMode
.timing
;
68 printf("%lu %u %u %u %u %u %u %u %u ", timing
.pixel_clock
/ 1000,
69 timing
.h_display
, timing
.h_sync_start
, timing
.h_sync_end
,
70 timing
.h_total
, timing
.v_display
, timing
.v_sync_start
,
71 timing
.v_sync_end
, timing
.v_total
);
74 if ((timing
.flags
& B_POSITIVE_HSYNC
) != 0)
76 if ((timing
.flags
& B_POSITIVE_VSYNC
) != 0)
78 if ((timing
.flags
& B_TIMING_INTERLACED
) != 0)
80 printf(" %lu\n", mode
.BitsPerPixel());
88 "Usage: %s [options] <mode>\n"
89 "Sets the specified screen mode. When no screen mode has been chosen,\n"
90 "the current one is printed. <mode> takes the form: <width> <height>\n"
91 "<depth> <refresh-rate>, or <width>x<height>, etc.\n"
92 " --fall-back\tchanges to the standard fallback mode, and "
94 "\t\t\tnotification requester.\n"
95 " -s --short\t\twhen no mode is given the current screen mode is\n"
96 "\t\t\tprinted in short form.\n"
97 " -l --list\t\tdisplay a list of the available modes.\n"
98 " -q --dont-confirm\tdo not confirm the mode after setting it.\n"
99 " -m --modeline\taccept and print X-style modeline modes:\n"
100 "\t\t\t <pclk> <h-display> <h-sync-start> <h-sync-end> <h-total>\n"
101 "\t\t\t <v-disp> <v-sync-start> <v-sync-end> <v-total> [flags] "
103 "\t\t\t(supported flags are: +/-HSync, +/-VSync, Interlace)\n",
111 main(int argc
, char** argv
)
113 bool fallbackMode
= false;
114 bool setMode
= false;
115 bool shortOutput
= false;
116 bool listModes
= false;
117 bool modeLine
= false;
125 // TODO: add a possibility to set a virtual screen size in addition to
126 // the display resolution!
129 while ((c
= getopt_long(argc
, argv
, "shlfqm", kLongOptions
, NULL
)) != -1) {
159 if (argc
- optind
> 0) {
162 // arguments to specify the mode are following
165 int parsed
= sscanf(argv
[optind
], "%dx%dx%d", &width
, &height
,
168 depthIndex
= optind
+ 1;
169 else if (parsed
== 1) {
170 if (argc
- optind
> 1) {
171 height
= strtol(argv
[optind
+ 1], NULL
, 0);
172 depthIndex
= optind
+ 2;
175 } else if (parsed
!= 3)
178 if (depthIndex
> 0 && depthIndex
< argc
)
179 depth
= strtol(argv
[depthIndex
], NULL
, 0);
180 if (depthIndex
+ 1 < argc
)
181 refresh
= strtod(argv
[depthIndex
+ 1], NULL
);
184 if (argc
- optind
< 9)
187 mode
.timing
.pixel_clock
= strtol(argv
[optind
], NULL
, 0) * 1000;
188 mode
.timing
.h_display
= strtol(argv
[optind
+ 1], NULL
, 0);
189 mode
.timing
.h_sync_start
= strtol(argv
[optind
+ 2], NULL
, 0);
190 mode
.timing
.h_sync_end
= strtol(argv
[optind
+ 3], NULL
, 0);
191 mode
.timing
.h_total
= strtol(argv
[optind
+ 4], NULL
, 0);
192 mode
.timing
.v_display
= strtol(argv
[optind
+ 5], NULL
, 0);
193 mode
.timing
.v_sync_start
= strtol(argv
[optind
+ 6], NULL
, 0);
194 mode
.timing
.v_sync_end
= strtol(argv
[optind
+ 7], NULL
, 0);
195 mode
.timing
.v_total
= strtol(argv
[optind
+ 8], NULL
, 0);
196 mode
.timing
.flags
= 0;
197 mode
.space
= B_RGB32
;
201 if (!strcasecmp(argv
[i
], "+HSync"))
202 mode
.timing
.flags
|= B_POSITIVE_HSYNC
;
203 else if (!strcasecmp(argv
[i
], "+VSync"))
204 mode
.timing
.flags
|= B_POSITIVE_VSYNC
;
205 else if (!strcasecmp(argv
[i
], "Interlace"))
206 mode
.timing
.flags
|= B_TIMING_INTERLACED
;
207 else if (!strcasecmp(argv
[i
], "-VSync")
208 || !strcasecmp(argv
[i
], "-HSync")) {
209 // okay, but nothing to do
210 } else if (isdigit(argv
[i
][0]) && i
+ 1 == argc
) {
213 = color_space_for_depth(strtoul(argv
[i
], NULL
, 0));
215 fprintf(stderr
, "Unknown flag: %s\n", argv
[i
]);
222 mode
.virtual_width
= mode
.timing
.h_display
;
223 mode
.virtual_height
= mode
.timing
.v_display
;
224 mode
.h_display_start
= 0;
225 mode
.v_display_start
= 0;
231 BApplication
application("application/x-vnd.Haiku-screenmode");
233 ScreenMode
screenMode(NULL
);
234 screen_mode currentMode
;
235 screenMode
.Get(currentMode
);
238 // List all reported modes
240 printf("Available screen modes:\n");
242 for (int index
= 0; index
< screenMode
.CountModes(); index
++) {
244 print_mode(screenMode
.DisplayModeAt(index
),
245 screenMode
.ModeAt(index
));
247 print_mode(screenMode
.ModeAt(index
), shortOutput
);
254 // Just print the current mode
257 screenMode
.Get(mode
);
258 print_mode(mode
, currentMode
);
261 printf("Resolution: ");
262 print_mode(currentMode
, shortOutput
);
267 screen_mode newMode
= currentMode
;
270 if (currentMode
.width
== 800 && currentMode
.height
== 600) {
272 newMode
.height
= 480;
273 newMode
.space
= B_CMAP8
;
274 newMode
.refresh
= 60;
277 newMode
.height
= 600;
278 newMode
.space
= B_RGB16
;
279 newMode
.refresh
= 60;
281 } else if (modeLine
) {
282 display_mode currentDisplayMode
;
283 if (screenMode
.Get(currentDisplayMode
) == B_OK
)
284 mode
.flags
= currentDisplayMode
.flags
;
286 newMode
.width
= width
;
287 newMode
.height
= height
;
290 newMode
.space
= color_space_for_depth(depth
);
292 newMode
.space
= B_RGB32
;
295 newMode
.refresh
= refresh
;
297 newMode
.refresh
= 60;
302 status
= screenMode
.Set(mode
);
304 status
= screenMode
.Set(newMode
);
306 if (status
== B_OK
) {
308 printf("Is this mode okay (Y/n - will revert after 10 seconds)? ");
311 int flags
= fcntl(STDIN_FILENO
, F_GETFL
, 0);
312 fcntl(STDIN_FILENO
, F_SETFL
, flags
| O_NONBLOCK
);
314 bigtime_t end
= system_time() + 10000000LL;
316 while (system_time() < end
) {
324 if (c
!= '\n' && tolower(c
) != 'y')
328 fprintf(stderr
, "%s: Could not set screen mode %ldx%ldx%ld: %s\n",
329 kProgramName
, newMode
.width
, newMode
.height
, newMode
.BitsPerPixel(),
335 // display notification requester
336 BAlert
* alert
= new BAlert("screenmode",
337 "You have used the shortcut <Command><Ctrl><Escape> to reset the "
338 "screen mode to a safe fallback.", "Keep", "Revert");
339 alert
->SetShortcut(1, B_ESCAPE
);
340 if (alert
->Go() == 1)