22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/smartware/drivers/user_interface/x11.rb', line 22
def screenshot
mine_pipe, xwd_pipe = IO.pipe
png = nil
begin
pid = Process.spawn({
"DISPLAY" => @display,
"XAUTHORITY" => "/home/#{@user}/.Xauthority"
}, "xwd", "-root", in: :close, out: xwd_pipe)
xwd_pipe.close
xwd_pipe = nil
, file_version,
pixmap_format, pixmap_depth, pixmap_width, pixmap_height,
xoffset, byteorder, bitmap_unit, bitmap_bit_order, bitmap_pad,
bits_per_pixel, bytes_per_line, visual_class,
red_mask, green_mask, blue_mask, bits_per_rgb,
number_of_colors, color_map_entires,
window_width, window_height, window_x, window_y, window_border_width =
mine_pipe.read(4 * 25).unpack("N*")
raise "Only direct color images are supported" if (visual_class != 5 && visual_class != 4)
mine_pipe.read(( + number_of_colors * 12) - 4 * 25)
initial = Array.new pixmap_width, pixmap_height
case bits_per_pixel
when 24
0.upto(pixmap_height - 1) do |y|
line = mine_pipe.read(bytes_per_line)
.slice(0, bits_per_pixel / 8 * pixmap_width)
0.upto(pixmap_width - 1) do |x|
initial[y * pixmap_width + x] =
(line.getbyte(x * 3 + 2) << 24) |
(line.getbyte(x * 3 + 1) << 16) |
(line.getbyte(x * 3 + 0) << 8) |
0xFF
end
end
when 32
0.upto(pixmap_height - 1) do |y|
line = mine_pipe.read(bytes_per_line)
.slice(0, bits_per_pixel / 8 * pixmap_width)
0.upto(pixmap_width - 1) do |x|
pix, = line.slice(x * 4, 4).unpack("V")
initial[y * pixmap_width + x] = ((pix & 0xFFFFFF) << 8) | 0xFF
end
end
else
raise "Unsupported bpp: #{bits_per_pixel}"
end
png = ChunkyPNG::Image.new pixmap_width, pixmap_height, initial
png.to_datastream.to_blob
rescue => e
"!error: #{e}"
ensure
mine_pipe.close
xwd_pipe.close unless xwd_pipe.nil?
end
end
|