Skip to content

Instantly share code, notes, and snippets.

@scottbyrns
Created April 18, 2016 19:05
Show Gist options
  • Save scottbyrns/821878405a05eb226f5f7425526619ed to your computer and use it in GitHub Desktop.
Save scottbyrns/821878405a05eb226f5f7425526619ed to your computer and use it in GitHub Desktop.
#!/usr/bin/env xcrun swift
//
// res.swift
//
//
// Created by John Liu on 2014/10/02.
//0. Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret ./scres.swift -target x86_64-apple-darwin13.4.0 -target-cpu core2 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -color-diagnostics -module-name scres -- -s 0 1440
//
import Foundation
import ApplicationServices
import CoreVideo
// Swift String is quite powerless at the moment
// http://stackoverflow.com/questions/24044851
// http://openradar.appspot.com/radar?id=6373877630369792
extension String {
func substringFromLastOcurrenceOf( needle:String) -> String {
var str = self
while let range = str.range(of: needle) {
let index2 = range.startIndex.advanced(by: 1)
let range2 = index2..<str.endIndex //Range<String.Index>(start: index2, end: str.endIndex)
str = str.substring(with: range2)
}
return str
}
func toUInt() -> UInt? {
if let num = Int(self) {
return UInt(num)
}
return nil
}
}
// assume at most 8 display connected
var maxDisplays:UInt32 = 8
// actual number of display
var displayCount32:UInt32 = 0
// store displayID in an raw array
var onlineDisplayIDs = UnsafeMutablePointer<CGDirectDisplayID>(allocatingCapacity: Int(maxDisplays))
func main () -> Void {
let error:CGError = CGGetOnlineDisplayList(maxDisplays, onlineDisplayIDs, &displayCount32)
if (error != CGError.success) {
print("Error on getting online display List.");
return
}
let displayCount:Int = Int(displayCount32)
// strip path and leave filename
let binary_name = Process.arguments[0].substringFromLastOcurrenceOf(needle: "/")
// help message
// let help_msg = ([
// "usage: ",
//// "\(binary_name) ",
// "[-h|--help] [-l|--list] [-m|--mode displayIndex] \n",
// "[-s|--set displayIndex width]",
// "\n\n",
//
// "Here are some examples:\n",
// " -h get help\n",
// " -l list displays\n",
// " -m 0 list all mode from a certain display\n",
// " -s 0 800 set resolution of display 0 to 800*600\n",
// ]).join(seperator:"")
let help_display_list = "List all available displays by:\n \(binary_name) -l"
let argc = Process.arguments.count
if argc > 1 {
if Process.arguments[1] == "-l" || Process.arguments[1] == "--list" {
listDisplays(displayIDs: onlineDisplayIDs, count:displayCount)
return
}
if Process.arguments[1] == "-m" || Process.arguments[1] == "--mode" {
if argc < 3 {
print("Specify a display to see its supported modes. \(help_display_list)")
return
}
if let displayIndex = Int(Process.arguments[2]) {
if displayIndex < displayCount {
let _info = listModesByDisplayID(_displayID: onlineDisplayIDs[displayIndex])
displayModes(_display: onlineDisplayIDs[displayIndex], index:displayIndex, _modes:_info)
} else {
print("Display index: \(displayIndex) not found. \(help_display_list)")
}
} else {
print("Display index should be a number. \(help_display_list)")
}
return
}
if Process.arguments[1] == "-s" || Process.arguments[1] == "--set" {
if argc < 3 {
print("Specify a display to set its mode. \(help_display_list)")
return
}
if argc < 4 {
print("Specify display width")
return
}
if let displayIndex = Int(Process.arguments[2]) {
if displayIndex < displayCount {
if let designatedWidth = Process.arguments[3].toUInt() {
if let modesArray = listModesByDisplayID(_displayID: onlineDisplayIDs[displayIndex]) {
var designatedWidthIndex:Int?
for i in 0..<modesArray.count {
let di = displayInfo(display: onlineDisplayIDs[displayIndex], mode:modesArray[i])
if di.width == designatedWidth {
designatedWidthIndex = i
break
}
}
if designatedWidthIndex != nil {
print("setting display mode")
setDisplayMode(display: onlineDisplayIDs[displayIndex], mode:modesArray[designatedWidthIndex!], designatedWidth:designatedWidth)
}
else {
print("This mode is unavailable for current desktop GUI")
}
}
}
} else {
print("Display index: \(displayIndex) not found. \(help_display_list)")
}
}
return
}
}
// print(help_msg)
}
func setDisplayMode( display:CGDirectDisplayID, mode:CGDisplayMode, designatedWidth:UInt) -> Void {
if mode.isUsableForDesktopGUI() {
let config = UnsafeMutablePointer<CGDisplayConfigRef?>(allocatingCapacity: 1);
let error = CGBeginDisplayConfiguration(config)
if error == CGError.success {
// if nil != config {
let option:CGConfigureOption = CGConfigureOption(rawValue:2) //XXX: permanently
CGConfigureDisplayWithDisplayMode(config.pointee, display, mode, nil)
let afterCheck = CGCompleteDisplayConfiguration(config.pointee, option)
if afterCheck != CGError.success {
CGCancelDisplayConfiguration(config.pointee)
}
// } else {
// print("Setting display mode failed")
// }
}
} else {
print("This mode is unavailable for current desktop GUI")
}
}
// list mode by display id
func listModesByDisplayID( _displayID:CGDirectDisplayID?) -> [CGDisplayMode]? {
if let displayID = _displayID {
if let modeList = CGDisplayCopyAllDisplayModes(displayID, nil) {
var modesArray = [CGDisplayMode]()
let count = CFArrayGetCount(modeList)
for i in 0..<count {
let modeRaw = CFArrayGetValueAtIndex(modeList, i)
// https://github.com/FUKUZAWA-Tadashi/FHCCommander
let mode = unsafeBitCast(modeRaw, to: CGDisplayMode.self)
modesArray.append(mode)
}
return modesArray
}
}
return nil
}
func displayModes( _display:CGDirectDisplayID?, index:Int, _modes:[CGDisplayMode]?) -> Void {
if let display = _display {
if let modes = _modes {
print("Supported Modes for Display \(index):")
let nf = NSNumberFormatter()
nf.paddingPosition = NSNumberFormatterPadPosition.beforePrefix
nf.paddingCharacter = " " // XXX: Swift does not support padding yet
nf.minimumIntegerDigits = 3 // XXX
for i in 0..<modes.count {
let di = displayInfo(display: display, mode:modes[i])
print(" \(di.width) * \(di.height) @ \(di.frequency)Hz")
}
}
}
}
// print a list of all displays
// used by -l
func listDisplays( displayIDs:UnsafeMutablePointer<CGDirectDisplayID>, count:Int) -> Void {
for i in 0..<count {
let di = displayInfo(display: displayIDs[i], mode:nil)
print("Display \(i): \(di.width) * \(di.height) @ \(di.frequency)Hz")
}
}
struct DisplayInfo {
var width:UInt, height:UInt, frequency:UInt
}
// return with, height and frequency info for corresponding displayID
func displayInfo( display:CGDirectDisplayID, mode:CGDisplayMode?) -> DisplayInfo {
var mode = mode
if mode == nil {
mode = CGDisplayCopyDisplayMode(display)!
}
let width = UInt( mode!.width )
let height = UInt( mode!.height )
var frequency = UInt( mode!.refreshRate )
if frequency == 0 {
var link:CVDisplayLink?
CVDisplayLinkCreateWithCGDisplay(display, &link)
let time:CVTime = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link!)
// timeValue is in fact already in Int64
let timeValue = time.timeValue as Int64
// a hack-y way to do ceil
let timeScale = Int64(time.timeScale) + timeValue / 2
frequency = UInt( timeScale / timeValue )
}
return DisplayInfo(width:width, height:height, frequency:frequency)
}
// run it
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment