#!/usr/bin/env python import gtk, telnetlib, ftplib def handle_events(): while gtk.events_pending (): gtk.main_iteration () class DboxConnection: def __init__ (self, ip, user, pw=""): self.prompt = "/var # " self.tn = telnetlib.Telnet (ip) self.tn.read_until ("login: ") self.tn.write (user + '\n') self.tn.read_until ("Password: ") self.tn.write (pw + '\n') self.tn.read_until (self.prompt) self.ftp = ftplib.FTP (ip, user, pw) def do_shell (self, cmd): self.tn.write (cmd + '\n') handle_events () r = "" while r[-len(self.prompt):] != self.prompt: r += self.tn.read_eager() handle_events () return r def get_file (self, filename): def getpart (lst, data): handle_events () lst.append (data) blocks = [] self.ftp.retrbinary ("RETR " + filename, lambda x : getpart (blocks, x)) return "".join (blocks) def get_screenshot (self): self.do_shell ("cat /dev/fb0 > /tmp/screenshot") handle_events () ss = self.get_file ("/tmp/screenshot") return ss class DboxWindow: def __init__ (self): self.data = None self.width = 720 self.height = 576 self.palette = {} setup_palette (self.palette) win = gtk.Window () win.set_name ("Dbox Framebuffer") win.connect ("destroy", gtk.mainquit) drawing_area = gtk.DrawingArea () drawing_area.set_size_request (self.width, self.height) win.add (drawing_area) drawing_area.connect("expose_event", self._expose) drawing_area.connect("button_press_event", self._button_press) drawing_area.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.BUTTON_PRESS_MASK ) drawing_area.show () win.show () self.da = drawing_area def _expose (self, widget, event): if not self.data: return gtk.FALSE rowstride = self.width * 3 x, y, width, height = event.area gc = widget.get_style().fg_gc[gtk.STATE_NORMAL] widget.window.draw_rgb_image (gc, x, y, width, height, gtk.gdk.RGB_DITHER_NONE, self.data[y * rowstride + x*3:], rowstride) return gtk.FALSE def _button_press (self, widget, event): x = int (event.x) y = int (event.y) if not self.data: return gtk.TRUE print "%d, %d: %d" % (x, y, ord (self.raw [y * self.width + x])) return gtk.TRUE def put_image (self, data): self.data = "".join ([self.palette[i] for i in data[:720*576]]) self.da.queue_draw () def setup_palette (palette): def blend (palette, startindex, col1, col2, steps): for i in range (steps): f = float(i) / (steps - 1) r = int (2.55 * (col1[0] * (1-f) + col2[0] * f)) g = int (2.55 * (col1[1] * (1-f) + col2[1] * f)) b = int (2.55 * (col1[2] * (1-f) + col2[2] * f)) palette [chr (startindex + i)] = "%c%c%c" % (r, g, b) # colors from radiomode.pal palettefile = '\x00\x00\x11\x02\x08\x1c\x00\x07(\x08\x10$\x00\x073\x00\x0e,\x00\x0e3\x00\x153\t\x11,\x00\x07;\x00\x07B\x00\x0e;\x00\x0eB\x00\x15;\x00\x15B\x07\x0e;\x07\x153\n\x156\x0e\x15;\x00\x07I\x00\x07P\x07\x0eB\x00\x0eI\x07\x0eI\x00\x0eP\x07\x0eP\x07\x15B\x0e\x15B\x00\x15I\x00\x15P\x00\x1dB\x00\x1dI\x00\x1dP\x00$P\x07\x19F\x07\x1dI\x0e\x19I\x00\x07Y\x00\x0eY\x00\x0e`\x00\x0eg\x07\x15P\x0e\x15P\x00\x15Y\x07\x15Y\x0e\x15Y\x00\x15`\x07\x15`\x0e\x15`\x00\x15g\x07\x1dP\x0e\x1dP\x00\x1d\\\x00\x1dg\x00$`\x08 \\\x00\x0en\x00\x0ev\x00\x15n\x00\x15v\n\x15k\x00\x1dn\x08\x1dl\x00$n\x01,l\x00\x15}\x03\x1dz\x00\x15\x85\x00\x1d\x85\x00*z\x00\x15\x8c\x00!\x88\x00/\x88\x00\x1f\xa1\x005\xa3&\x1a\x1f\x1c\x180/!0\x1f\x1c;/$;C \x1a@)&J/\x1c;\x1f5C,2`(\x11a6\x16v0\x11rC\x0fS\')e*%],-Y8,n>&\x15\x15B\x15\x19F\x1a\x18G\x1d\x1dB\x1d\x1dI\x18\x15S\x12#S\x15"Z\x12\'p$\x1dB\x1d\x1d[(!B%\x1dR8!D$&ME,A"0hPZ\x81\x81I\x00\x88M\x00\x91I\x00\x94P\x00\x9fC\x00\x9bP\x00\x94Y\x00\x9bY\x00\x9bc\x00\xaaF\x00\xadP\x00\xa2\\\x00\xaaY\x00\xb5Y\x00\xa2g\x00\xaac\x00\xb2`\x00\xb2g\x00\xb2n\x00\x85@\x07\x96:\x07\x95I\x07\x88Y\x07\x96V\x07\xa4I\x07\xacZ\x04\x9bc\x07\xa2c\x07\xb3g\x01\x85A\x0e\x965\x0e\x99B\x0e\x8eU\x0e\xa2a\x0b\x856\x15\x84I\x15\x8eI\x16\x85jd\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01' for i in range (256): palette[chr(i)] = palettefile[i*3:(i+1)*3] # predefined "low index" colors r = [0x00, 0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff] g = [0x00, 0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff] b = [0x00, 0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff] for i in range(17): palette[chr(i)] = chr(r[i]) + chr(g[i]) + chr(b[i]) # colors from a theme. menu_head = (0x00, 0x0a, 0x19) menu_head_text = (0x5f, 0x46, 0x00) menu_content = (0x00, 0x0f, 0x23) menu_content_dark = (0x00, 0x09, 0x15) menu_content_text = (0x64, 0x64, 0x64) menu_content_selected = (0x19, 0x37, 0x64) menu_content_selected_text = (0x00, 0x00, 0x00) menu_content_inactive = (0x00, 0x0f, 0x23) menu_content_inactive_text = (55, 70, 85) info_bar = (0x00, 0x0e, 0x23) info_bar_shadow = (0x00, 0x05, 0x0e) info_bar_text = (0x64, 0x64, 0x64) blend (palette, 254-8*7, info_bar_shadow, info_bar_text, 8) blend (palette, 254-8*6, info_bar, info_bar_text, 8) blend (palette, 254-8*5, menu_head, menu_head_text, 8) blend (palette, 254-8*4, menu_content, menu_content_text, 8) blend (palette, 254-8*3, menu_content_dark, menu_content_text, 8) blend (palette, 254-8*2, menu_content_selected, menu_content_selected_text, 8) blend (palette, 254-8*1, menu_content_inactive, menu_content_inactive_text, 8) def fetchput_image (): data = dbox.get_screenshot () win.put_image (data) return gtk.TRUE if __name__ == '__main__': dbox = DboxConnection ("192.168.23.74", "root") win = DboxWindow () gtk.timeout_add (1000, fetchput_image) gtk.mainloop ()