diff --git a/lib/X11.rb b/lib/X11.rb index 8e8324d..12bca7c 100644 --- a/lib/X11.rb +++ b/lib/X11.rb @@ -8,5 +8,7 @@ require 'hexdump' require 'X11/protocol' require 'X11/auth' require 'X11/display' +require 'X11/screen' require 'X11/type' require 'X11/packet' +require 'X11/packets/display' diff --git a/lib/X11/display.rb b/lib/X11/display.rb index 04250fc..eb539ba 100644 --- a/lib/X11/display.rb +++ b/lib/X11/display.rb @@ -24,6 +24,12 @@ module X11 authorize(host, family, display_id) end + def screens + @internal[:screens].map do |s| + Screen.new(self, s) + end + end + private def authorize(host, family, display_id) @@ -49,14 +55,11 @@ module X11 when X11::Auth::AUTHENTICATE raise AuthorizationError, "Connection requires authentication" when X11::Auth::SUCCESS - puts "SUCCESS" + @socket.read(7) # skip unused bytes + @internal = Packet::DisplayInfo.read(@socket) else raise AuthorizationError, "Received unknown opcode #{type}" end - - @socket.read(7) - - puts Packet::DisplayInfo.read(@socket).inspect end end end diff --git a/lib/X11/packet.rb b/lib/X11/packet.rb index 0835898..7e079cb 100644 --- a/lib/X11/packet.rb +++ b/lib/X11/packet.rb @@ -5,22 +5,22 @@ module X11 include X11::Type class << self - def create(*values) - lengths = lengths_for(values) + def create(*parameters) + lengths = lengths_for(parameters) packet = @structs.map do |s| case s.type when :field - s.encode.pack(values.shift) + s.type_klass.pack(parameters.shift) when :unused "\x00" * s.size when :length - s.encode.pack(lengths[s.name]) - when :data - if s.encode == X11::Type::String8 - X11::Type::String8.pack(values.shift) - else - vals = s.encode.create(values.shift) + s.type_klass.pack(lengths[s.name]) + when :string + s.type_klass.pack(parameters.shift) + when :list + parameters.shift.each do |obj| + s.type_klass.create(*obj) end end end @@ -35,20 +35,17 @@ module X11 @structs.each do |s| case s.type when :field - values[s.name] = s.encode.unpack( socket.read(s.encode.size) ) + values[s.name] = s.type_klass.unpack( socket.read(s.type_klass.size) ) when :unused socket.read(s.size) when :length - size = s.encode.unpack( socket.read(s.encode.size) ) + size = s.type_klass.unpack( socket.read(s.type_klass.size) ) lengths[s.name] = size - when :data - if s.encode == X11::Type::String8 - values[s.name] = X11::Type::String8.unpack(socket, s.size) - else - puts lengths[s.name] - values[s.name] = lengths[s.name].times.collect do - s.encode.read(socket) - end + when :string + values[s.name] = s.type_klass.unpack(socket, lengths[s.name]) + when :list + values[s.name] = lengths[s.name].times.collect do + s.type_klass.read(socket) end end end @@ -57,12 +54,11 @@ module X11 end def field(*args) - name, encode, type = args - puts name - s = Struct.new(:name, :encode, :type).new + name, type_klass, type = args + s = Struct.new(:name, :type_klass, :type).new s.name = name s.type = (type == nil ? :field : type) - s.encode = encode + s.type_klass = type_klass @structs ||= [] @structs << s @@ -85,7 +81,7 @@ module X11 fields.each do |s| value = args.shift - lengths[s.name] = value.size if s.type == :data + lengths[s.name] = value.size if s.type == :list or s.type == :string end return lengths @@ -100,97 +96,5 @@ module X11 end end - # Information sent by the client at connection setup - # - # 1 byte-order - # #x42 MSB first - # #x6C LSB first - # 1 unused - # 2 CARD16 protocol-major-version - # 2 CARD16 protocol-minor-version - # 2 n length of authorization-protocol-name - # 2 d length of authorization-protocol-data - # 2 unused - # n STRING8 authorization-protocol-name - # p unused, p=pad(n) - # d STRING8 authorization-protocol-data - # q unused, q=pad(d) - - class ClientHandshake < BasePacket - field :byte_order, Uint8 - unused 1 - field :protocol_major_version, Uint16 - field :protocol_minor_version, Uint16 - field :auth_proto_name, Uint16, :length - field :auth_proto_data, Uint16, :length - unused 2 - field :auth_proto_name, String8, :data - field :auth_proto_data, String8, :data - end - - class FormatInfo < BasePacket - field :depth, Uint8 - field :bits_per_pixel, Uint8 - field :scanline_pad, Uint8 - unused 5 - end - - class VisualInfo < BasePacket - field :visual_id, VisualID - field :qlass, Uint8 - field :bits_per_rgb_value, Uint8 - field :colormap_entries, Uint16 - field :red_mask, Uint32 - field :green_mask, Uint32 - field :blue_mask, Uint32 - unused 4 - end - - class DepthInfo < BasePacket - field :depth, Uint8 - unused 1 - field :visuals, Uint16, :length - unused 4 - field :visuals, VisualInfo, :data - end - - class ScreenInfo < BasePacket - field :root, Window - field :default_colormap, Colormap - field :white_pixel, Colornum - field :black_pixel, Colornum - field :current_input_masks, EventMask - field :size_in_pixels, Uint16 - field :size_in_millimeters, Uint16 - field :min_installed_maps, Uint16 - field :max_installed_maps, Uint16 - field :root_visual, VisualID - field :backing_stores, Uint8 - field :save_unders, Bool - field :root_depth, Uint8 - field :depths, Uint8,:length - field :depths, DepthInfo, :data - end - - class DisplayInfo < BasePacket - field :release_number, Uint32 - field :resource_id_base, Uint32 - field :resource_id_mask, Uint32 - field :motion_buffer_size, Uint32 - field :vendor, Uint16, :length - field :maximum_request_length, Uint16 - field :screens, Uint8, :length - field :formats, Uint8, :length - field :image_byte_order, Signifigance - field :bitmap_bit_order, Signifigance - field :bitmap_format_scanline_unit, Uint8 - field :bitmap_format_scanline_pad, Uint8 - field :min_keycode, KeyCode - field :max_keycode, KeyCode - field :vendor, String8, :data - field :formats, FormatInfo, :data - field :screens, ScreenInfo, :data - end - end end diff --git a/lib/X11/packets/display.rb b/lib/X11/packets/display.rb new file mode 100644 index 0000000..2ad1ec8 --- /dev/null +++ b/lib/X11/packets/display.rb @@ -0,0 +1,84 @@ +module X11 + module Packet + + class ClientHandshake < BasePacket + field :byte_order, Uint8 + unused 1 + field :protocol_major_version, Uint16 + field :protocol_minor_version, Uint16 + field :auth_proto_name, Uint16, :length + field :auth_proto_data, Uint16, :length + unused 2 + field :auth_proto_name, String8, :string + field :auth_proto_data, String8, :string + end + + class FormatInfo < BasePacket + field :depth, Uint8 + field :bits_per_pixel, Uint8 + field :scanline_pad, Uint8 + unused 5 + end + + class VisualInfo < BasePacket + field :visual_id, VisualID + field :qlass, Uint8 + field :bits_per_rgb_value, Uint8 + field :colormap_entries, Uint16 + field :red_mask, Uint32 + field :green_mask, Uint32 + field :blue_mask, Uint32 + unused 4 + end + + class DepthInfo < BasePacket + field :depth, Uint8 + unused 1 + field :visuals, Uint16, :length + unused 4 + field :visuals, VisualInfo, :list + end + + class ScreenInfo < BasePacket + field :root, Window + field :default_colormap, Colormap + field :white_pixel, Colornum + field :black_pixel, Colornum + field :current_input_masks, EventMask + field :width_in_pixels, Uint16 + field :height_in_pixels, Uint16 + field :width_in_millimeters, Uint16 + field :height_in_millimeters, Uint16 + field :min_installed_maps, Uint16 + field :max_installed_maps, Uint16 + field :root_visual, VisualID + field :backing_stores, Uint8 + field :save_unders, Bool + field :root_depth, Uint8 + field :depths, Uint8,:length + field :depths, DepthInfo, :list + end + + class DisplayInfo < BasePacket + field :release_number, Uint32 + field :resource_id_base, Uint32 + field :resource_id_mask, Uint32 + field :motion_buffer_size, Uint32 + field :vendor, Uint16, :length + field :maximum_request_length, Uint16 + field :screens, Uint8, :length + field :formats, Uint8, :length + field :image_byte_order, Signifigance + field :bitmap_bit_order, Signifigance + field :bitmap_format_scanline_unit, Uint8 + field :bitmap_format_scanline_pad, Uint8 + field :min_keycode, KeyCode + field :max_keycode, KeyCode + unused 4 + field :vendor, String8, :string + field :formats, FormatInfo, :list + field :screens, ScreenInfo, :list + end + + end +end diff --git a/lib/X11/screen.rb b/lib/X11/screen.rb new file mode 100644 index 0000000..1efefcc --- /dev/null +++ b/lib/X11/screen.rb @@ -0,0 +1,18 @@ +module X11 + class Screen + attr_reader :display + + def initialize(display, data) + @display = display + @internal = data + end + + def width + @internal[:width_in_pixels] + end + + def height + @internal[:height_in_pixels] + end + end +end diff --git a/lib/X11/type.rb b/lib/X11/type.rb index f1669e4..6254bff 100644 --- a/lib/X11/type.rb +++ b/lib/X11/type.rb @@ -35,7 +35,6 @@ module X11 KeyCode = Uint8 Signifigance = Uint8 Bool = Uint8 - Bitmask = Uint32 Window = Uint32 Pixmap = Uint32 @@ -50,8 +49,8 @@ module X11 VisualID = Uint32 EventMask = Uint32 - # Strings are "Special" in X11 they are a list - # data type but their padded + # Strings are "Special" in X11 they need + # their own class unfortunately since strings are padded class String8 def self.pack(x) x + "\x00"*(-x.length & 3) @@ -65,15 +64,5 @@ module X11 end end - # List.of(Foo) - # In this document the List.of notation strictly means some number of - # repetitions of the FOO encoding; the actual length of the list is encoded - # elsewhere - - class List - def self.of(type) - end - end - end end