xrandrb 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.textile +11 -0
- data/bin/xrandrb +4 -0
- data/lib/xrandrb/cli.rb +134 -0
- data/lib/xrandrb/mode.rb +16 -0
- data/lib/xrandrb/output.rb +39 -0
- data/lib/xrandrb.rb +29 -0
- data/test/test_helper.rb +10 -0
- metadata +68 -0
data/README.textile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
h2. xrandrb
|
2
|
+
|
3
|
+
Ruby wrapper and toolkit for xrandr.
|
4
|
+
|
5
|
+
h2. What is xrandr?
|
6
|
+
|
7
|
+
Xrandr is the low level utility that most Linux setups use to handle external displays. Xrandr can do anything the typical monitor management GUI can - setting the main display, toggle mirroring, turning displays on and off, position the displays, and so on.
|
8
|
+
|
9
|
+
h2. Why?
|
10
|
+
|
11
|
+
Xrandr itself lacks some basic features, such as providing one command for toggling a display on and off. This wrapper makes xrandr easily scriptable, so that hackers with terminals doesn't have to have a GUI to manage external monitors - xrandrb should suffice.
|
data/bin/xrandrb
ADDED
data/lib/xrandrb/cli.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
class Xrandrb
|
2
|
+
class Cli
|
3
|
+
COMMANDS = ["status", "on", "off", "toggle", "update"]
|
4
|
+
HELP_FLAGS = ["--help", "-h"]
|
5
|
+
|
6
|
+
def initialize(argv)
|
7
|
+
@command = argv.shift
|
8
|
+
@argv = argv
|
9
|
+
end
|
10
|
+
|
11
|
+
def _run(xrandr_output = nil)
|
12
|
+
@x = Xrandrb.new(xrandr_output)
|
13
|
+
|
14
|
+
case @command
|
15
|
+
when nil
|
16
|
+
status
|
17
|
+
when *HELP_FLAGS
|
18
|
+
help
|
19
|
+
when *COMMANDS
|
20
|
+
if HELP_FLAGS.include?(@argv[0])
|
21
|
+
help(@command)
|
22
|
+
else
|
23
|
+
__send__(@command)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
STDERR.puts "Unknown command '#{@command}'."
|
27
|
+
STDERR.puts "Available commands: #{COMMANDS.join(', ')}"
|
28
|
+
exit(1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def status
|
35
|
+
queried_output = @argv.shift
|
36
|
+
|
37
|
+
if queried_output
|
38
|
+
output = @x[queried_output]
|
39
|
+
if output
|
40
|
+
if output.connected?
|
41
|
+
[["Preferred", output.preferred], ["Current", output.current]].each do |label, mode|
|
42
|
+
if mode
|
43
|
+
puts "%s: %s (%s hz)" % [label, mode.resolution, mode.fps]
|
44
|
+
else
|
45
|
+
puts "%s: Unknown" % [label]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
else
|
49
|
+
puts "Disconnected."
|
50
|
+
end
|
51
|
+
else
|
52
|
+
STDERR.puts "Unknown output '#{queried_output}'."
|
53
|
+
exit(2)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
grouped = @x.outputs.group_by {|o| o.connected? }
|
57
|
+
[["Connected", true], ["Disconnected", false]].each do |label, group|
|
58
|
+
puts "#{label}:"
|
59
|
+
puts " " + grouped[group].map(&:name).join(", ")
|
60
|
+
end
|
61
|
+
|
62
|
+
# puts
|
63
|
+
# puts "Use 'xrandrb status [output]' for more info on that output."
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def on
|
68
|
+
with_queried_output(@argv.shift) do |output|
|
69
|
+
puts "Turning on #{output.name}"
|
70
|
+
xrandr "--output #{output.name} --auto"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def off
|
75
|
+
with_queried_output(@argv.shift) do |output|
|
76
|
+
puts "Turning off #{output.name}"
|
77
|
+
xrandr "--output #{output.name} --auto --off"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def toggle
|
82
|
+
name = @argv.shift
|
83
|
+
with_queried_output(name) do |output|
|
84
|
+
@argv.unshift(name)
|
85
|
+
output.sending? ? off : on
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def update
|
90
|
+
with_queried_output(@argv.shift) do |output|
|
91
|
+
xrandr "--output #{output.name}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Performs the call and proxies what's left in ARGV to the call.
|
96
|
+
def xrandr(options)
|
97
|
+
`xrandr #{options} #{@argv.join(' ')}`
|
98
|
+
end
|
99
|
+
|
100
|
+
def with_queried_output(name)
|
101
|
+
if name
|
102
|
+
output = @x[name]
|
103
|
+
if output
|
104
|
+
if output.connected?
|
105
|
+
yield(output)
|
106
|
+
else
|
107
|
+
STDOUT.puts "Output #{name} not connected."
|
108
|
+
exit(3)
|
109
|
+
end
|
110
|
+
else
|
111
|
+
STDOUT.puts "Unknown output '#{name}'."
|
112
|
+
exit(4)
|
113
|
+
end
|
114
|
+
else
|
115
|
+
STDOUT.puts "Please specify an output name. See 'xrandrb status' for a list of connected outputs."
|
116
|
+
exit(5)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def help(command)
|
121
|
+
if command
|
122
|
+
puts "Help texts for individual commands not implemented yet."
|
123
|
+
else
|
124
|
+
puts GLOBAL_HELP
|
125
|
+
puts "Usage: xrandrb COMMAND [ARGS]"
|
126
|
+
puts
|
127
|
+
puts "Available commands:"
|
128
|
+
puts " " + COMMANDS.join(', ')
|
129
|
+
puts
|
130
|
+
puts "'xrandrb COMMAND --help' for help on a particular command."
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/xrandrb/mode.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Xrandrb
|
2
|
+
class Mode
|
3
|
+
attr_reader :resolution, :fps
|
4
|
+
def initialize(resolution, fps, current, preferred)
|
5
|
+
@resolution, @fps, @current, @preferred = resolution, fps, current, preferred
|
6
|
+
end
|
7
|
+
|
8
|
+
def preferred?
|
9
|
+
@preferred == true
|
10
|
+
end
|
11
|
+
|
12
|
+
def current?
|
13
|
+
@current == true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Xrandrb
|
2
|
+
class Output
|
3
|
+
attr_reader :modes
|
4
|
+
attr_reader :name, :status, :current_resolution, :meta, :dimensions
|
5
|
+
def initialize(info)
|
6
|
+
@modes = []
|
7
|
+
@name, @status, @current_resolution, @meta, @dimensions =
|
8
|
+
*info.scan(/^([a-zA-Z0-9]+) (connected|disconnected) ?([0-9x\+]+)? \(([^\)]+)\) ?(.*)?$/)[0]
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_modes(mode_spec)
|
12
|
+
resolution, fpses = mode_spec.scan(/^ +([0-9x]+) +(.+)$/)[0]
|
13
|
+
fpses = fpses.split(/ {2,}/)
|
14
|
+
|
15
|
+
fpses.each do |f|
|
16
|
+
preferred = (f[-1..-1] == "+")
|
17
|
+
current = (f[-2..-2] == "*")
|
18
|
+
fps = f[/^([0-9\.]+)/]
|
19
|
+
@modes.push(Xrandrb::Mode.new(resolution, fps, current, preferred))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def connected?
|
24
|
+
@status == "connected"
|
25
|
+
end
|
26
|
+
|
27
|
+
def sending?
|
28
|
+
!!current
|
29
|
+
end
|
30
|
+
|
31
|
+
def preferred
|
32
|
+
@modes.find {|m| m.preferred? }
|
33
|
+
end
|
34
|
+
|
35
|
+
def current
|
36
|
+
@modes.find {|m| m.current? }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/xrandrb.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "xrandrb/output"
|
2
|
+
require "xrandrb/mode"
|
3
|
+
|
4
|
+
class Xrandrb
|
5
|
+
attr_reader :outputs
|
6
|
+
def initialize(xrandr_output = nil)
|
7
|
+
@xrandr = xrandr_output || `xrandr`
|
8
|
+
parse
|
9
|
+
end
|
10
|
+
|
11
|
+
# Gets output by name
|
12
|
+
def [](name)
|
13
|
+
@outputs.find {|o| o.name.downcase == name.downcase }
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def parse
|
19
|
+
lines = @xrandr.split("\n")
|
20
|
+
@outputs = []
|
21
|
+
lines[1..-1].each do |line|
|
22
|
+
if line =~ /^ /
|
23
|
+
@outputs[-1].add_modes(line)
|
24
|
+
else
|
25
|
+
@outputs.push(Xrandrb::Output.new(line))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xrandrb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- August Lilleaas
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-21 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email: august.lilleaas@gmail.com
|
23
|
+
executables:
|
24
|
+
- xrandrb
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- bin/xrandrb
|
31
|
+
- lib/xrandrb/output.rb
|
32
|
+
- lib/xrandrb/mode.rb
|
33
|
+
- lib/xrandrb/cli.rb
|
34
|
+
- lib/xrandrb.rb
|
35
|
+
- test/test_helper.rb
|
36
|
+
- README.textile
|
37
|
+
has_rdoc: true
|
38
|
+
homepage:
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
segments:
|
51
|
+
- 0
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.6
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Ruby wrapper/enhancer for xrandrb, the Linux CLI monitor manager.
|
67
|
+
test_files: []
|
68
|
+
|