library now succesfully connects to an X11 server :)

This commit is contained in:
Richard Ramsden 2012-03-11 14:18:30 -07:00
parent 88152ffee6
commit 3bee98236e
6 changed files with 79 additions and 30 deletions

View file

@ -4,10 +4,5 @@ require 'hexdump'
require 'X11/protocol'
require 'X11/auth'
require 'X11/display'
module X11
# Return a format string, suitable for pack(), for a string padded to a multiple
# of 4 bytes. For instance, C<pack(padded('Hello'), 'Hello')> gives
# C<"Hello\0\0\0">.
def self.pad(x); x + "\0"*(-x.length & 3); end
end
require 'X11/encode'
require 'X11/packet'

View file

@ -6,10 +6,9 @@
module X11
class Auth
FAILED = 0
AUTHENTICATE = 1
SUCCESS = 2
SUCCESS = 1
AUTHENTICATE = 2
ADDRESS_TYPES = {
256 => :Local,
@ -55,7 +54,12 @@ module X11
def read
auth_info = []
auth_info << ADDRESS_TYPES[ @file.read(2).unpack('n').first ]
4.times { length = @file.read(2).unpack('n').first; auth_info << @file.read(length).first }
4.times do
length = @file.read(2).unpack('n').first
auth_info << @file.read(length)
end
AuthInfo[*auth_info]
end

View file

@ -21,28 +21,21 @@ module X11
private
# authorization packet sent to X11 server:
# [:proto_major, Uint16],
# [:proto_minor, Uint16],
# [:auth_proto_name, Uint16, :length],
# [:auth_proto_data, Uint16, :length],
# [:auth_proto_name, String8],
# [:auth_proto_data, String8]
def authorize(host, family, display_id)
auth_info = Auth.new.get_by_hostname(host||"localhost", family, display_id)
auth_name, auth_data = auth_info.address, auth_info.auth_data
puts auth_name
puts auth_data
@socket.write([
handshake = Packet::ClientHandshake.create(
Protocol::BYTE_ORDER,
Protocol::MAJOR,
Protocol::MINOR,
auth_name.length,
auth_data.length,
X11::pad(auth_name),
X11::pad(auth_data)
].pack("A2 SS SS xx") + X11::pad(auth_name) + X11::pad(auth_data))
auth_name,
auth_data
)
@socket.write(handshake)
case @socket.read(1).unpack("w").first
when X11::Auth::FAILED
@ -53,10 +46,11 @@ private
when X11::Auth::AUTHENTICATE
raise "Connection requires authentication"
when X11::Auth::SUCCESS
raise "fix me"
puts "CONNECTION SUCCESS"
else
raise "received unknown opcode #{type}"
end
end
end
end

21
lib/X11/encode.rb Normal file
View file

@ -0,0 +1,21 @@
module X11
# used to encode plain data into
# binary data which the X11 protocol can read
module Encode
def self.pack(a)
lambda {|value| [value].pack(a)}
end
# X11 Protocol requires us to pad strings to a multiple of 4 bytes
# For instance, C<pack(padded('Hello'), 'Hello')> gives C<"Hello\0\0\0">.
def self.pad(x); x + "\0"*(-x.length & 3); end
Int8 = pack("c")
Int16 = pack("s")
Int32 = pack("l")
Uint8 = pack("C")
Uint16 = pack("S")
Uint32 = pack("L")
String8 = lambda {|a| pad(a)}
end
end

37
lib/X11/packet.rb Normal file
View file

@ -0,0 +1,37 @@
module X11
module Packet
class BasePacket
include X11::Encode
attr_reader :packet
@@fields = []
def self.create(*values)
@@fields.map do |name, type|
if :static == name
type
else
type.call(values.shift)
end
end.join
end
def self.field(name, type)
@@fields.push([name, type])
end
end
class ClientHandshake < BasePacket
field :byte_order, Uint8
field :static, "\x00"
field :proto_version_major, Uint16
field :proto_version_minor, Uint16
field :auth_proto_name_length, Uint16
field :auth_proto_data_length, Uint16
field :static, "\x00"
field :static, "\x00"
field :auth_proto_name, String8
field :auth_proto_data, String8
end
end
end

View file

@ -1,18 +1,16 @@
module X11
class Protocol
module Protocol
# endiness of your machine
BYTE_ORDER = case [1].pack("L")
when "\0\0\0\1"
"B"
"B".ord
when "\1\0\0\0"
"l"
"l".ord
else
raise "Cannot determine byte order"
end
MAJOR = 11
MINOR = 0
end
end