Last active
January 11, 2023 16:55
-
-
Save bellbind/27220148ea752335259dfce63f43bd5d to your computer and use it in GitHub Desktop.
[macos][c]commandline for display and switch display mode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// clang displaymode.c -o displaymode -framework CoreGraphics | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <CoreGraphics/CGDirectDisplay.h> | |
#include <CoreGraphics/CGDisplayConfiguration.h> | |
// https://github.com/robbertkl/ResolutionMenu/blob/master/Resolution%20Menu/DisplayModeMenuItem.m | |
// CoreGraphics DisplayMode struct used in private APIs | |
typedef struct { | |
uint32_t modeNumber; | |
uint32_t flags; | |
uint32_t width; | |
uint32_t height; | |
uint32_t depth; | |
uint8_t unknown[170]; | |
uint16_t freq; | |
uint8_t more_unknown[16]; | |
float density; | |
} CGSDisplayMode; | |
// CoreGraphics private APIs with support for scaled (retina) display modes | |
void CGSGetCurrentDisplayMode(CGDirectDisplayID display, int* modeNum); | |
void CGSConfigureDisplayMode( | |
CGDisplayConfigRef config, CGDirectDisplayID display, int modeNum); | |
void CGSGetNumberOfDisplayModes(CGDirectDisplayID display, int* nModes); | |
void CGSGetDisplayModeDescriptionOfLength( | |
CGDirectDisplayID display, int idx, CGSDisplayMode* mode, int length); | |
int main(int argc, char* argv[]) { | |
CGDirectDisplayID display = CGMainDisplayID(); | |
int count; | |
CGSGetNumberOfDisplayModes(display, &count); | |
//printf("%d\n", modeCount); | |
if (argc == 2) { | |
char* endp = argv[1]; | |
const int mode = strtol(argv[1], &endp, 10); | |
if (*argv[1] == '\0' || *endp != '\0') { | |
fprintf(stderr, "Error: mode should be integer: %s\n", argv[1]); | |
return 1; | |
} | |
if (mode < 0 || count <= mode) { | |
fprintf(stderr, "Error: mode should be 0-%d: %d\n", count - 1, mode); | |
return 1; | |
} | |
CGDisplayConfigRef config; | |
CGBeginDisplayConfiguration(&config); | |
CGSConfigureDisplayMode(config, display, mode); | |
CGCompleteDisplayConfiguration(config, kCGConfigurePermanently); | |
} | |
int currentMode; | |
CGSGetCurrentDisplayMode(display, ¤tMode); | |
//printf("%d\n", currentMode); | |
for (int i = 0; i < count; i++) { | |
const int size = sizeof (CGSDisplayMode); | |
CGSDisplayMode mode; | |
CGSGetDisplayModeDescriptionOfLength(display, i, &mode, size); | |
const char* mark = i == currentMode ? "(current)" : ""; | |
printf("mode %2d: %5d x %-5d %s\n", | |
mode.modeNumber, mode.width, mode.height, mark); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env swift | |
// swiftc displaymode1.swift | |
import Foundation | |
import CoreGraphics | |
let display = CGMainDisplayID() | |
guard let dmodes = CGDisplayCopyAllDisplayModes(display, nil) as? [CGDisplayMode] else {exit(1)} | |
let argv = CommandLine.arguments | |
if argv.count == 2 { | |
guard let modeNum = Int(argv[1]) else { | |
fputs("mode num should be integer but: \(argv[1])\n", stderr); | |
exit(1); | |
} | |
if modeNum < 0 || dmodes.count <= modeNum { | |
fputs("mode num should be in 0-\(dmodes.count - 1) but: \(argv[1])\n", stderr); | |
exit(1); | |
} | |
let config = UnsafeMutablePointer<CGDisplayConfigRef?>.allocate(capacity: 1) | |
defer {config.deallocate()} | |
CGBeginDisplayConfiguration(config) | |
CGConfigureDisplayWithDisplayMode(config.pointee, display, dmodes[modeNum], nil) | |
CGCompleteDisplayConfiguration(config.pointee, CGConfigureOption.permanently) | |
} | |
if let current = CGDisplayCopyDisplayMode(display) { | |
//print("current: \(current.width) x \(current.height)") | |
print(String(format: "current: %5d x %-5d", current.width, current.height)) | |
for (i, dmode) in dmodes.enumerated() { | |
let mark = dmode.ioDisplayModeID == current.ioDisplayModeID ? "(current)" : "" | |
print(String(format: "mode %2d: %5d x %-5d \(mark)", i, dmode.width, dmode.height)) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// clang displaymode0.c -o displaymode0 -framework CoreGraphics -framework CoreFoundation | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <CoreFoundation/CFBase.h> | |
#include <CoreFoundation/CFArray.h> | |
#include <CoreGraphics/CGDirectDisplay.h> | |
#include <CoreGraphics/CGDisplayConfiguration.h> | |
// With Standard CoreGrahics API | |
int main(int argc, char* argv[]) { | |
CGDirectDisplayID display = CGMainDisplayID(); | |
CFArrayRef modes = CGDisplayCopyAllDisplayModes(display, NULL); | |
CFIndex count = CFArrayGetCount(modes); | |
if (argc == 2) { | |
char* endp = argv[1]; | |
const CFIndex id = strtol(argv[1], &endp, 10); | |
if (*argv[1] == '\0' || *endp != '\0') { | |
fprintf(stderr, "Error: mode should be integer: %s\n", argv[1]); | |
return 1; | |
} | |
if (id < 0 || count <= id) { | |
fprintf(stderr, "Error: mode should be 0-%ld: %ld\n", count - 1, id); | |
return 1; | |
} | |
const void* const m = CFArrayGetValueAtIndex(modes, id); | |
CGDisplayModeRef const mode = (CGDisplayModeRef) m; | |
CGDisplayConfigRef config; | |
CGBeginDisplayConfiguration(&config); | |
CGConfigureDisplayWithDisplayMode(config, display, mode, NULL); | |
CGCompleteDisplayConfiguration(config, kCGConfigurePermanently); | |
} | |
CGDisplayModeRef current = CGDisplayCopyDisplayMode(display); | |
const int32_t current_id = CGDisplayModeGetIODisplayModeID(current); | |
printf("current: %5zu x %-5zu (desktop: %-5s)\n", | |
CGDisplayModeGetWidth(current), CGDisplayModeGetHeight(current), | |
CGDisplayModeIsUsableForDesktopGUI(current) ? "true" : "false"); | |
CFRelease(current); | |
for (CFIndex i = 0; i < count; i++) { | |
const void* const m = CFArrayGetValueAtIndex(modes, i); | |
CGDisplayModeRef const mode = (CGDisplayModeRef) m; | |
const int32_t mode_id = CGDisplayModeGetIODisplayModeID(mode); | |
printf("mode %2ld: %5zu x %-5zu (desktop: %-5s) %s\n", i, | |
CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode), | |
CGDisplayModeIsUsableForDesktopGUI(mode) ? "true" : "false", | |
mode_id == current_id ? "(current)" : ""); | |
} | |
CFRelease(modes); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment