Class: VNCRec::RFB::Proxy

Inherits:
Object
  • Object
show all
Defined in:
lib/vncrec/rfb/proxy.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, rfbv, enc, pf, auth) ⇒ Proxy

  • Constant class e.g. VNCRec::Authentication::VncAuthentication

  • optional argument, e.g. password string

Parameters:

  • io (IO, #read, #sysread, #syswrite, #read_nonblock)

    string stream from VNC server.

  • rfbv (String)

    version of RFB protocol, 3.8 is the only supported by now

  • enc (Integer)

    encoding of video data used to transfer. One of the following:

  • pf (Hash)

    pixel format:

    • PIX_FMT_BGR8 - 8 bits per pixel

    • PIX_FMT_BGR32 - 32 bits per pixel

  • auth (Array)

    :



24
25
26
27
28
29
30
# File 'lib/vncrec/rfb/proxy.rb', line 24

def initialize(io, rfbv, enc, pf, auth)
  @io = io
  @version = rfbv
  @enc = enc
  @pf = pf
  @auth = auth.first.new(@io, *auth.drop(1))
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



10
11
12
# File 'lib/vncrec/rfb/proxy.rb', line 10

def data
  @data
end

#hObject

Returns the value of attribute h.



10
11
12
# File 'lib/vncrec/rfb/proxy.rb', line 10

def h
  @h
end

#ioObject

Returns the value of attribute io.



10
11
12
# File 'lib/vncrec/rfb/proxy.rb', line 10

def io
  @io
end

#nameObject

Returns the value of attribute name.



10
11
12
# File 'lib/vncrec/rfb/proxy.rb', line 10

def name
  @name
end

#wObject

Returns the value of attribute w.



10
11
12
# File 'lib/vncrec/rfb/proxy.rb', line 10

def w
  @w
end

Instance Method Details

#fb_update_request(inc, x, y, w, h) ⇒ Object

Request framebuffer update.

Parameters:

  • inc (Integer)

    incremental, request just difference between previous and current framebuffer state.

  • x (Integer)
  • y (Integer)
  • w (Integer)
  • h (Integer)


119
120
121
122
123
124
125
# File 'lib/vncrec/rfb/proxy.rb', line 119

def fb_update_request(inc, x, y, w, h)
  @inc = inc > 0
  msg = [3, inc, x, y, w, h].pack('CCS>S>S>S>')
  return @io.write msg
rescue
  return nil
end

#handle_colormap_updateArray

Returns palette.

Returns:

  • (Array)

    palette



166
167
168
169
170
171
172
173
174
175
# File 'lib/vncrec/rfb/proxy.rb', line 166

def handle_colormap_update
  _, first_color, noc = (@io.read 5).unpack('CS>S>')
  palette = []
  noc.times do
    palette << (@io.read 6).unpack('S>S>S>')
  end
  return palette
rescue
  return nil
end

#handle_fb_updateObject

Receives data and applies diffs(if incremental) to the @data



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/vncrec/rfb/proxy.rb', line 147

def handle_fb_update
  fail 'run #prepare_framebuffer first' unless @data
  enc = nil
  @encs ||= { 0 => VNCRec::RFB::EncRaw,
              5 => VNCRec::RFB::EncHextile,
              16 => VNCRec::RFB::EncZRLE
  }
  _, numofrect = @io.read(3).unpack('CS>')
  i = 0
  while i < numofrect
    hdr = @io.read 12
    x, y, w, h, enc = hdr.unpack('S>S>S>S>l>')
    mod = @encs.fetch(enc) { fail "Unsupported encoding #{enc}" }
    mod.read_rect @io, x, y, w, h, @bpp, @data, @wb, @h
    i += 1
  end
end

#handle_responseArray

Handle VNC server response. Call it right after fb_update_request.

Returns:

  • (Array)

    type, (either framebuffer, “bell”, handle_server_cuttext or handle_colormap_update results)



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/vncrec/rfb/proxy.rb', line 129

def handle_response
  t = (io.readpartial 1).ord
  case t
  when 0 then
    handle_fb_update
    return [t, @data]
  when 1 then
    return [t, handle_colormap_update]
  when 2 then
    return [t, 'bell']
  when 3 then
    return [t, handle_server_cuttext]
  else
    return [-1, nil]
  end
end

#handle_server_cuttextString

Returns server cut text.

Returns:

  • (String)

    server cut text



178
179
180
181
182
183
184
185
186
# File 'lib/vncrec/rfb/proxy.rb', line 178

def handle_server_cuttext
  begin
    _, _, _, len = (@io.read 7).unpack('C3L>')
    text = @io.read len
  rescue
    return nil
  end
  text
end

#handshakeObject

Perform handshake

Returns:

  • w,h,server_name or nil



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/vncrec/rfb/proxy.rb', line 46

def handshake
  # version
  version = @io.readpartial 12
  @io.syswrite(@version + "\n")

  @auth.handshake

  # client init
  @io.syswrite "\x01"

  # server init
  w = @io.readpartial(2).unpack('S>')[0]
  h = @io.readpartial(2).unpack('S>')[0]
  pf = @io.readpartial 16
  nlen = @io.readpartial(4).unpack('L>')[0]
  @name = @io.readpartial nlen
  return [w, h, @name]
end

#prepare_framebuffer(w, h, bpp) ⇒ Object

Parameters:

  • w

    width of the screen area

  • h

    height of the screen area

  • bpp

    bits per pixel



35
36
37
38
39
40
41
42
# File 'lib/vncrec/rfb/proxy.rb', line 35

def prepare_framebuffer(w, h, bpp)
  @w = w
  @h = h
  @bpp = bpp
  @bypp = (bpp / 8.0).to_i
  @wb = @w * @bypp
  @data = "\x00" * @wb * @h
end

#set_encodings(encodings) ⇒ Object

Set way of encoding video frames.

Parameters:



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/vncrec/rfb/proxy.rb', line 99

def set_encodings(encodings)
  num = encodings.size
  msg = [2, 0, num].pack('CCS>')
  begin
    @io.syswrite msg
    encodings.each do |e|
      @io.syswrite([e].pack('l>'))
    end
  rescue
    return nil
  end
end

#set_pixel_format(format) ⇒ Object

Set a way that server should use to represent pixel data

Parameters:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/vncrec/rfb/proxy.rb', line 69

def set_pixel_format(format)
  msg = [0, 0, 0, 0].pack('CC3')
  begin
    @io.syswrite msg

    msg = [
      format[:bpp],
      format[:depth],
      format[:bend],
      format[:tcol],
      format[:rmax],
      format[:gmax],
      format[:bmax],
      format[:rshif],
      format[:gshif],
      format[:bshif],
      0, 0, 0
    ].pack('CCCCS>S>S>CCCC3')
    return @io.syswrite msg

  rescue
    return nil
  end
end