Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collected patches + update build to support Apple Silicon; add help string; update README #36

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
version.h
*.o
screenreader
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
# -convert test target to a shell script
# -figure out of lipo is the best way to make a universal binary on cmdline

uname_m := $(shell uname -m)

PREFIX=/usr/local

ORIG_RES=1920x1200x32
Expand All @@ -17,7 +19,7 @@ VERSION=1.7dev

CC=clang
PACKAGE_BUILD=/usr/bin/pkgbuild
ARCH_FLAGS=-arch i386 -arch x86_64
ARCH_FLAGS=-arch $(uname_m)

.PHONY: build
build: screenresolution
Expand Down
11 changes: 7 additions & 4 deletions README
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
This is a tool that can be used to determine current resolution,
list available resolutions and set resolutions for active displays
on Mac OS 10.6, and possibly above. I have only tested 10.6.
on Mac OS 10.6 through at least 13.1.

I used clang for development, but the code seems to compile
just fine with gcc. The code might not be as well layed out
Expand All @@ -9,12 +9,15 @@ as it could be, feel free to send a pull request.
Build+Install
====================
Running the following commands in Terminal.app will result in
dmg with a pkg file being created if the system has Xcode 4.
dmg with a pkg file being created if the system has Xcode 4+.

git clone github.com:jhford/screenresolution
cd screenresolution
make dmg

By default, screenreader will build for the target architecture
of the host machine.

At this point, I'd recommend testing that things work! I have
written a 'test' makefile target. Because this script expects two
monitors that both use the same resolution, it mightn't work
Expand Down Expand Up @@ -42,8 +45,8 @@ install make target with DESTDIR to specify an alternate root.

Running
====================
There are three commands that this program supports: get, list
and set. All three modes operate on active displays [1].
This program supports the following commands: get, getMax, list
and set. All modes operate on active displays [1].

The get mode will show you the resolution of all active displays

Expand Down
5 changes: 1 addition & 4 deletions cg_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,8 @@ unsigned int parseStringConfig(const char *string, struct config *out) {
return rc;
}

CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef *mode1Ptr, CGDisplayModeRef *mode2Ptr, void *context)
CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef mode1, CGDisplayModeRef mode2, void *context)
{
CGDisplayModeRef mode1 = (CGDisplayModeRef)mode1Ptr;
CGDisplayModeRef mode2 = (CGDisplayModeRef)mode2Ptr;

size_t width1 = CGDisplayModeGetWidth(mode1);
size_t width2 = CGDisplayModeGetWidth(mode2);

Expand Down
2 changes: 1 addition & 1 deletion cg_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ unsigned int configureDisplay(CGDirectDisplayID display,
int displayNum);
unsigned int parseStringConfig(const char *string, struct config *out);
size_t bitDepth(CGDisplayModeRef mode);
CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef *mode1Ptr, CGDisplayModeRef *mode2Ptr, void *context);
CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef mode1, CGDisplayModeRef mode2, void *context);

#endif
56 changes: 52 additions & 4 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

#include "version.h"
#include "cg_utils.h"
#include <sys/param.h>

// Number of modes to list per line.
#define MODES_PER_LINE 3

Expand All @@ -30,6 +28,7 @@

unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum);
unsigned int listCurrentMode(CGDirectDisplayID display, int displayNum);
unsigned int listMaxSupported(CGDirectDisplayID display, int displayNum);

int main(int argc, const char *argv[]) {
// http://developer.apple.com/library/IOs/#documentation/CoreFoundation/Conceptual/CFStrings/Articles/MutableStrings.html
Expand Down Expand Up @@ -71,12 +70,22 @@ int main(int argc, const char *argv[]) {
return 1;
}

if (strcmp(argv[1], "help") == 0) {
printf("Usage: Run screenreader with one of the following: get, getMax, list, or set [resolution].\n");
return(0);
}


// This loop should probably be in another function.
for (d = 0; d < displayCount && keepgoing; d++) {
if (strcmp(argv[1], "get") == 0) {
if (!listCurrentMode(activeDisplays[d], d)) {
exitcode++;
}
} else if (strcmp(argv[1], "getMax") == 0) {
if (!listMaxSupported(activeDisplays[d], d)) {
exitcode++;
}
} else if (strcmp(argv[1], "list") == 0) {
if (!listAvailableModes(activeDisplays[d], d)) {
exitcode++;
Expand Down Expand Up @@ -108,7 +117,7 @@ int main(int argc, const char *argv[]) {
free(activeDisplays);
activeDisplays = NULL;
} else {
NSLog(CFSTR("%s"), "Incorrect command line");
NSLog(CFSTR("%s"), "Invalid command. Run screenreader with get, getMax, list, or set [resolution].");
exitcode++;
}
return exitcode > 0;
Expand All @@ -131,6 +140,42 @@ unsigned int listCurrentMode(CGDirectDisplayID display, int displayNum) {
return returncode;
}

unsigned int listMaxSupported(CGDirectDisplayID display, int displayNum) {
unsigned int returncode = 1;
CGDisplayModeRef maxSupportedMode = CGDisplayCopyDisplayMode(display);

CFStringRef keys[1] = { kCGDisplayShowDuplicateLowResolutionModes };
CFBooleanRef values[1] = { kCFBooleanTrue };
CFDictionaryRef options = CFDictionaryCreate(
kCFAllocatorDefault, (const void**) keys, (const void**) values, 1,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, options);
if (allModes == NULL) {
NSLog(CFSTR("Error: failed trying to look up modes for display %u"), displayNum);
}

CFIndex displayModeCount = CFArrayGetCount(allModes);
for (int i = 0; i < displayModeCount; ++i) {
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
CFComparisonResult result = _compareCFDisplayModes(mode, maxSupportedMode, NULL);
if (result == kCFCompareGreaterThan) {
maxSupportedMode = CGDisplayModeRetain(mode);
}
}

NSLog(CFSTR("Display %d: %ux%ux%u@%.0f"),
displayNum,
CGDisplayModeGetWidth(maxSupportedMode),
CGDisplayModeGetHeight(maxSupportedMode),
bitDepth(maxSupportedMode),
CGDisplayModeGetRefreshRate(maxSupportedMode));

CFRelease(allModes);
CFRelease(options);
CGDisplayModeRelease(maxSupportedMode);
return returncode;
}

unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) {
unsigned int returncode = 1;
int numModes = 0;
Expand All @@ -155,7 +200,7 @@ unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) {
CFRangeMake(0, CFArrayGetCount(allModesSorted)),
(CFComparatorFunction) _compareCFDisplayModes,
NULL
);
);

#ifndef LIST_DEBUG
if(displayNum != 0)
Expand Down Expand Up @@ -227,6 +272,9 @@ unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) {
#endif
}

if (numModes % MODES_PER_LINE)
printf("\n");

CFRelease(allModes);
CFRelease(allModesSorted);

Expand Down