diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 04c926d76f..4ec0623048 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -39,7 +39,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat mount_nfs mountvolume mv nc netstat nl nohup od open passwd paste patch pathchk pc ping play playfile playsound playwav pr prio printenv printf ps ptx pwd query quit rc readlink release renice rescan rlog rm rmattr rmindex - rmdir roster route safemode screen_blanker sed setdecor settype setversion + rmdir roster route safemode screen_blanker screenmode sed setdecor settype setversion setvolume seq sh sha1sum shar shred shuf shutdown sleep sort split stat strace stty su sum sync sysinfo tac tail tar tcpdump tcptester tee telnet telnetd test top touch tput tr traceroute diff --git a/src/bin/Jamfile b/src/bin/Jamfile index e89be6596d..104e8458ff 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -204,6 +204,7 @@ SubInclude HAIKU_TOP src bin playsound ; SubInclude HAIKU_TOP src bin rc ; SubInclude HAIKU_TOP src bin rmd160 ; SubInclude HAIKU_TOP src bin screen_blanker ; +SubInclude HAIKU_TOP src bin screenmode ; SubInclude HAIKU_TOP src bin sed ; SubInclude HAIKU_TOP src bin sharutils ; SubInclude HAIKU_TOP src bin strace ; diff --git a/src/bin/screenmode/Jamfile b/src/bin/screenmode/Jamfile new file mode 100644 index 0000000000..c57c3212b5 --- /dev/null +++ b/src/bin/screenmode/Jamfile @@ -0,0 +1,22 @@ +SubDir HAIKU_TOP src bin screenmode ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +UsePrivateHeaders [ FDirName graphics radeon ] ; + # for multimon.h + +SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src preferences screen ] ; + +BinCommand screenmode : + screenmode.cpp + + # from Screen preferences + ScreenMode.cpp + multimon.cpp + + : be +; + +#SEARCH on [ FGristFiles +# ScreenMode.cpp +# ] = [ FDirName $(HAIKU_TOP) src preferences screen ] ; diff --git a/src/bin/screenmode/screenmode.cpp b/src/bin/screenmode/screenmode.cpp new file mode 100644 index 0000000000..a8595de3a5 --- /dev/null +++ b/src/bin/screenmode/screenmode.cpp @@ -0,0 +1,187 @@ +/* + * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include + +#include +#include +#include + +#include "ScreenMode.h" + + +static struct option const kLongOptions[] = { + {"fall-back", no_argument, 0, 'f'}, + {"short", no_argument, 0, 's'}, + {"help", no_argument, 0, 'h'}, + {NULL} +}; + +extern const char *__progname; +static const char *kProgramName = __progname; + + +static color_space +color_space_for_depth(int32 depth) +{ + switch (depth) { + case 8: + return B_CMAP8; + case 15: + return B_RGB15; + case 16: + return B_RGB16; + case 24: + return B_RGB24; + case 32: + default: + return B_RGB32; + } +} + + +static void +usage(int status) +{ + fprintf(stderr, + "Usage: %s [options] \n" + "Sets the specified screen mode. When no screen mode has been chosen,\n" + "the current one is printed. takes the form: \n" + " , or x, etc.\n" + " --fall-back\tchanges to the standard fallback mode, and displays a\n" + "\t\t\tnotification requester.\n" + " -s --short\t\twhen no mode is given the current screen mode is\n" + "\t\t\tprinted in short form.\n", + kProgramName); + + exit(status); +} + + +int +main(int argc, char** argv) +{ + bool fallbackMode = false; + bool setMode = false; + bool shortOutput = false; + int width = -1; + int height = -1; + int depth = -1; + float refresh = -1; + + // TODO: add a possibility to set a virtual screen size in addition to + // the display resolution! + + int c; + while ((c = getopt_long(argc, argv, "sh", kLongOptions, NULL)) != -1) { + switch (c) { + case 0: + break; + case 'f': + fallbackMode = true; + setMode = true; + break; + case 's': + shortOutput = true; + break; + case 'h': + usage(0); + break; + default: + usage(1); + break; + } + } + + if (argc - optind > 0) { + int depthIndex = -1; + + // arguments to specify the mode are following + int parsed = sscanf(argv[optind], "%dx%dx%d", &width, &height, &depth); + if (parsed == 2) + depthIndex = optind + 1; + else if (parsed == 1) { + if (argc - optind > 1) { + height = strtol(argv[optind + 1], NULL, 0); + depthIndex = optind + 2; + } else + usage(1); + } else if (parsed != 3) + usage(1); + + if (depthIndex > 0 && depthIndex < argc) + depth = strtol(argv[depthIndex], NULL, 0); + if (depthIndex + 1 < argc) + refresh = strtod(argv[depthIndex + 1], NULL); + + setMode = true; + } + + BApplication application("application/x-vnd.Haiku-screenmode"); + + ScreenMode screenMode(NULL); + screen_mode currentMode; + screenMode.Get(currentMode); + + if (!setMode) { + const char* format = shortOutput + ? "%ld %ld %ld %g\n" : "Resolution: %ld %ld, %ld bits, %g Hz\n"; + printf(format, currentMode.width, currentMode.height, + currentMode.BitsPerPixel(), currentMode.refresh); + return 0; + } + + screen_mode newMode = currentMode; + + if (fallbackMode) { + if (currentMode.width == 800 && currentMode.height == 600) { + newMode.width = 640; + newMode.height = 480; + newMode.space = B_CMAP8; + newMode.refresh = 60; + } else { + newMode.width = 800; + newMode.height = 600; + newMode.space = B_RGB16; + newMode.refresh = 60; + } + } else { + newMode.width = width; + newMode.height = height; + + if (depth != -1) + newMode.space = color_space_for_depth(depth); + else + newMode.space = B_RGB32; + + if (refresh > 0) + newMode.refresh = refresh; + else + newMode.refresh = 60; + } + + status_t status = screenMode.Set(newMode); + if (status != B_OK) { + fprintf(stderr, "%s: Could not set screen mode %ldx%ldx%ldx: %s\n", + kProgramName, newMode.width, newMode.height, newMode.BitsPerPixel(), + strerror(status)); + return 1; + } + + if (fallbackMode) { + // display notification requester + BAlert* alert = new BAlert("screenmode", + "You have used the shortcut to reset the " + "screen mode to a safe fallback.", "Keep", "Revert"); + if (alert->Go() == 1) + screenMode.Revert(); + } + + return 0; +}