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) ⇒ Proxy

Returns a new instance of Proxy

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

  • w

    width of the screen area

  • h

    height of the screen area



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

def initialize(io, rfbv, enc, pf)
  @io = io
  @version = rfbv
  @enc = enc
  @pf = pf
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)


130
131
132
133
134
135
136
# File 'lib/vncrec/rfb/proxy.rb', line 130

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



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

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



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/vncrec/rfb/proxy.rb', line 158

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)



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/vncrec/rfb/proxy.rb', line 140

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



189
190
191
192
193
194
195
196
197
# File 'lib/vncrec/rfb/proxy.rb', line 189

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



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/vncrec/rfb/proxy.rb', line 41

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

  # security
  num_of_st = @io.readbyte
  if num_of_st == 0 # failed
    reason_len = @io.readpartial(4).unpack('L>')[0]
    reason = @io.readpartial(reason_len)
    fail reason
  else
    num_of_st.times do
      @io.readbyte
    end
  end

  reply = [1].pack('C') # security type:none
  @io.syswrite reply

  stype = (@io.readpartial 4).unpack('H' * 8)
  # client init
  @io.syswrite reply

  # 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]
rescue
  return nil
end

#prepare_framebuffer(w, h, bpp) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/vncrec/rfb/proxy.rb', line 30

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:



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/vncrec/rfb/proxy.rb', line 110

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:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/vncrec/rfb/proxy.rb', line 80

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