#!/usr/bin/python # x11_server.py is the server (linux) part of RusticVNC # (C) 2007 Michele Andreoli, GPL """ ======================================================== vnc_server.py create (and advertise) a bluetooth service called VNC, on the linux box. Using the client part, vnc_client.py, a Symbian S60 phone can connect to this service ed requires mouse mouvements, sound control, shell commands, periodic screenshots, etc. Requimentes: pyBluez (bluetooth for Python), stream.py, python-xlib ======================================================== """ from version import VERSION import traceback,sys,os,time # some required external modules is in the dir ./ext for p in ('.', './ext', '/usr/local/vnc60/ext'): if os.path.isdir(p): sys.path.append(p) try: from Xlib import X, display from Xlib.protocol import request display = display.Display() screen=display.screen() root=screen.root window=root except: print "withou python-Xlib, mouse will works!" root=window=display=0 X='boh?' import traceback try: from Xlib.ext.xtest import FakeInput except: FakeInput=lambda *args: "fakeinput unsupported %s" % args[0] print "Xlib.ext.xtest missing: the SELECT button will not works" try: from stream import Stream except: print "stream.py module is required. Abort." #------------------- # amarok commands #------------------- playing='dcop amarok player nowPlaying' vol='dcop amarok player getVolume' amarok={ 'PLAY':"dcop amarok player playPause; %s"%playing, 'PREVIOUS':"dcop amarok player prev; %s"%playing, 'NEXT':"dcop amarok player next; %s"%playing, 'STOP':"dcop amarok player prev; %s"%playing, 'VOLUME-UP':"dcop amarok player volumeUp; %s"%vol, 'VOLUME-DOWN':"dcop amarok player volumeDown; %s"%vol, } #------------------------- # execute a linux command, returning the stdout #------------------------- def execute(cmd): f=os.popen(cmd,'r') r=f.read() f.close() if len(r)<=1: r='ok\n' return r.strip() #-------------------- # get the absolute pointer coordinate (x,y) #-------------------- def get_pointer(): info = request.QueryPointer(display = display.display, window = root) x=info._data['root_x']; y=info._data['root_y'] print "pointer x=%d y=%d" %(x,y) return (x,y) #-------------------------------- # send fake input to XWindow #-------------------------------- def x11_input(pos,cmd=X.ButtonPress): (x,y)=pos FakeInput(display = display.display, opcode = display.display.get_extension_major('XTEST'), event_type = cmd, detail = X.Button1, time = X.CurrentTime, root = root, x = x, y =y ) #-------------------------------- # check requirements on the linux box #-------------------------------- check_list={ 'ImageMagick not found (suggested)':'r=`which import 2>/dev/null`; [ "$r" ]', 'xhost not foun (required)':'r=`which xhost 2>/dev/null`; [ "$r" ]', 'dcop not found (required)':'r=`which dcop 2>/dev/null`; [ "$r" ]', 'amarok not found (suggested)':'r=`which amarok 2>/dev/null`; [ "$r" ]', 'uname not found (suggested)':'r=`which uname 2>/dev/null`; [ "$r" ]', 'XWindows is not running (strongly required)':' [ "$DISPLAY" ]', } def check_requirements(): print "Checking requiments ..." for k in check_list.keys(): r=os.system(check_list[k]) if r>0: print "\tAttention,please: %s" % k #============================== # MAIN #============================= print '='*40 print "vnc_server.py for Linux v%s" % VERSION print '='*40 check_requirements() image={'x11':"/tmp/x11.jpg", 'phone':"/tmp/phone.jpg"} image={'x11':"/tmp/x11.jpg", 'phone':"/srv/www/htdocs/reserved/n70/webcam.jpg"} os.system("xhost +localhost") def main(): global conn conn=Stream(mode='BT'); conn.accept(service='VNC') print "Connection enstablished with the phone" while 1: data=None data=conn.read() if data==None: continue if len(data)!=0: #print "received [%s]" % data pass if data=="END": print "client finished" break if data=="PING": print "PING received" #--------------- # amarok control #---------------- if data=='PLAY': r=execute(amarok['PLAY']) conn.write(r) if data=='NEXT': r=execute(amarok['NEXT']) conn.write(r) if data=='PREVIOUS': r=execute(amarok['PREVIOUS']) conn.write(r) if data=='STOP': r=execute(amarok['STOP']) conn.write(r) if data=='VOLUME-UP': r=execute(amarok['VOLUME-UP']) conn.write(r) if data=='VOLUME-DOWN': r=execute(amarok['VOLUME-DOWN']) conn.write(r) #------------------------------------------ # shell commands request. Protocol: CMD,cmd #------------------------------------------ if data[:4]=="CMD,": (op,cmd)=data.split(',') # execute linux commands and return stdout result=execute(cmd) print "command %s -> result [%s]" %(cmd,result) conn.write(result) #------------------------------------------------------ # X11->Phone screen request. Protocol: GET_SCREEN,width,height,rotation #------------------------------------------------------- if data[:11]=="GET_SCREEN,": # read resolution, etc (op,w,h,rot)=data.split(',') print "screenshot required %sx%s, rot=%s .." %(w,h,rot) g='800x600' cmd="import -silent -window root -depth 8 -geometry %s \ -rotate %s -resize %sx%s %s" %(g,rot,w,h,image['x11']) os.system(cmd) print "sendind X11 screenshot [%s] ..." % image['x11'] conn.sendfile(image['x11']) print "screen shot sent." continue #------------------------------------------------------ # Phone->X11 screen request. Protocol: SEND_SCREEN #------------------------------------------------------- # currently disabled in vnc_client.py, because not useful if data[:11]=="SEND_SCREEN": print "screenshot from phone incoming ..." conn.recfile(image['phone']) print "screenshot received [%s]" % image['phone'] continue #------------------------------------ # Mouse motion commands #------------------------------------ if data=="UP": print "UP" display.warp_pointer(0,-3) display.sync() if data=="LEFT": print "LEFT" display.warp_pointer(-3,0) display.sync() if data=="RIGHT": print "RIGHT" display.warp_pointer(3,0) display.sync() if data=="DOWN": print "DOWN" display.warp_pointer(0,3) display.sync() if data=="SELECT": position=get_pointer() print "SELECT %s" % str(position) x11_input(position,X.ButtonPress) time.sleep(0.1) x11_input(position,X.ButtonRelease) display.sync() conn.close() conn.shutdown() if __name__=='__main__': stop=False while not stop : try: main() except KeyboardInterrupt: print "control-C received" stop=True conn.close() conn.shutdown() except: conn.close() conn.shutdown() pass # End