xrandrb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "xrandrb"
3
+ require "xrandrb/cli"
4
+ Xrandrb::Cli.new(ARGV)._run
@@ -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
@@ -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
@@ -0,0 +1,10 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
4
+ require "xrandrb"
5
+
6
+ class Test::Unit::TestCase
7
+ def fixture(name)
8
+ File.read(File.dirname(__FILE__) + "/fixtures/" + name)
9
+ end
10
+ end
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
+