diff --git a/rdpy/display/qt.py b/rdpy/display/qt.py index 0e90fb5..3e60b7e 100644 --- a/rdpy/display/qt.py +++ b/rdpy/display/qt.py @@ -62,9 +62,7 @@ class RFBClientQt(RFBClientObserver, QAdaptor): is to an RFB observer ''' def __init__(self): - ''' - ctor - ''' + RFBClientObserver.__init__(self) self._widget = QRemoteDesktop(self) def getWidget(self): @@ -121,9 +119,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor): Adaptor for RDP client ''' def __init__(self): - ''' - constructor - ''' + RDPClientObserver.__init__(self) self._widget = QRemoteDesktop(self) def getWidget(self): diff --git a/rdpy/examples/rdpclient.py b/rdpy/examples/rdpclient.py index d4a2a95..e28e0ac 100644 --- a/rdpy/examples/rdpclient.py +++ b/rdpy/examples/rdpclient.py @@ -31,7 +31,7 @@ from PyQt4 import QtGui from rdpy.display.qt import RDPClientQt from rdpy.protocol.rdp import rdp -class RDPClientQtFactory(rdp.ClientFactory): +class RDPClientQtFactory(rdp.Factory): ''' Factory create a RDP GUI client ''' diff --git a/rdpy/examples/vncclient.py b/rdpy/examples/vncclient.py index 737a9dc..82436d3 100644 --- a/rdpy/examples/vncclient.py +++ b/rdpy/examples/vncclient.py @@ -18,7 +18,7 @@ # """ -example of use rdpy as vnc client +example of use rdpy as VNC client """ import sys @@ -31,14 +31,14 @@ from PyQt4 import QtGui from rdpy.display.qt import RFBClientQt from rdpy.protocol.rfb import rfb -class RFBClientQtFactory(rfb.ClientFactory): - ''' +class RFBClientQtFactory(rfb.Factory): + """ Factory create a VNC GUI client - ''' + """ def buildObserver(self): - ''' - build RFB observer - ''' + """ + Build RFB Client observer + """ #create client observer client = RFBClientQt() #create qt widget @@ -52,21 +52,21 @@ class RFBClientQtFactory(rfb.ClientFactory): pass def clientConnectionLost(self, connector, reason): - ''' - connection lost event + """ + Connection lost event @param connector: twisted connector use for vnc connection (use reconnect to restart connection) @param reason: str use to advertise reason of lost connection - ''' + """ QtGui.QMessageBox.warning(self._w, "Warning", "Lost connection : %s"%reason) reactor.stop() app.exit() def clientConnectionFailed(self, connector, reason): - ''' - connection failed event + """ + Connection failed event @param connector: twisted connector use for vnc connection (use reconnect to restart connection) @param reason: str use to advertise reason of lost connection - ''' + """ QtGui.QMessageBox.warning(self._w, "Warning", "Connection failed : %s"%reason) reactor.stop() app.exit() diff --git a/rdpy/protocol/rdp/mcs.py b/rdpy/protocol/rdp/mcs.py index 5ad4cae..b0f2a46 100644 --- a/rdpy/protocol/rdp/mcs.py +++ b/rdpy/protocol/rdp/mcs.py @@ -3,7 +3,7 @@ ''' from rdpy.network.const import ConstAttributes, TypeAttributes -from rdpy.network.layer import LayerAutomata, Layer +from rdpy.network.layer import LayerAutomata, Layer, LayerMode from rdpy.network.type import sizeof, Stream, UInt8, UInt16Be from rdpy.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize from rdpy.protocol.rdp.ber import writeLength @@ -93,12 +93,13 @@ class MCS(LayerAutomata): return self._mcs._serverSettings - def __init__(self, presentation): + def __init__(self, mode, presentation): ''' ctor call base class ctor + @param mode: mode of mcs layer @param presentation: presentation layer ''' - LayerAutomata.__init__(self, presentation._mode, presentation) + LayerAutomata.__init__(self, mode, presentation) self._clientSettings = gcc.ClientSettings() self._serverSettings = gcc.ServerSettings() #default user Id @@ -334,5 +335,18 @@ class MCS(LayerAutomata): max_pdu_size = ber.readInteger(s) ber.readInteger(s) return (max_channels, max_users, max_tokens, max_pdu_size) - + +def createClient(controller): + """ + @param controller: RDP controller which initialized all channel layer + @return: MCS layer in client mode + """ + return MCS(LayerMode.CLIENT, controller.getPDULayer()) + +def createServer(controller): + """ + @param controller: RDP controller which initialized all channel layer + @return: MCS layer in server mode + """ + return MCS(LayerMode.SERVER, controller.getPDULayer()) \ No newline at end of file diff --git a/rdpy/protocol/rdp/pdu.py b/rdpy/protocol/rdp/pdu.py index 7b0010f..f5a0a8a 100644 --- a/rdpy/protocol/rdp/pdu.py +++ b/rdpy/protocol/rdp/pdu.py @@ -2,7 +2,7 @@ @author: citronneur ''' -from rdpy.network.layer import LayerAutomata +from rdpy.network.layer import LayerAutomata, LayerMode from rdpy.network.type import CompositeType, UniString, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType,\ FactoryType from rdpy.network.const import ConstAttributes, TypeAttributes @@ -702,10 +702,11 @@ class PDU(LayerAutomata): Global channel for mcs that handle session identification user, licensing management, and capabilities exchange ''' - def __init__(self, mode): + def __init__(self, mode, controller): ''' Constructor @param mode: LayerMode + @param controller: controller use to inform orders ''' LayerAutomata.__init__(self, mode, None) #logon info send from client to server @@ -745,14 +746,7 @@ class PDU(LayerAutomata): self._shareId = UInt32Le() #rdp controller - self._controller = rdp.RDPController(self) - - def getController(self): - ''' - Getter for RDP controller - @return: return rdp controller - ''' - return self._controller + self._controller = controller def connect(self): ''' diff --git a/rdpy/protocol/rdp/rdp.py b/rdpy/protocol/rdp/rdp.py index 6ebf813..19cc108 100644 --- a/rdpy/protocol/rdp/rdp.py +++ b/rdpy/protocol/rdp/rdp.py @@ -6,24 +6,31 @@ import tpkt, tpdu, mcs, pdu from rdpy.network.layer import LayerMode class RDPController(object): - ''' + """ use to decode and dispatch to observer PDU messages and orders - ''' - def __init__(self, pduLayer): + """ + def __init__(self, mode): ''' - ctor + @param mode: mode of generate layer by controller + @param observer: observer ''' #list of observer - self._observers = [] + self._clientObserver = [] #transport layer - self._pduLayer = pduLayer + self._pduLayer = pdu.PDU(mode, self) - def addObserver(self, observer): + def getPDULayer(self): + """ + @return: pdu layer use by controller + """ + return self._pduLayer + + def addClientObserver(self, observer): ''' add observer to rdp protocol @param observer: new observer to add ''' - self._observers.append(observer) + self._clientObserver.append(observer) observer._controller = self def recvBitmapUpdateDataPDU(self, bitmapUpdateData): @@ -31,12 +38,12 @@ class RDPController(object): call when a bitmap data is received from update pdu @param bitmapData: pdu.BitmapData struct ''' - for observer in self._observers: + for observer in self._clientObserver: #for each rectangle in update PDU for rectangle in bitmapUpdateData.rectangles._array: observer.onBitmapUpdate(rectangle.destLeft.value, rectangle.destTop.value, rectangle.destRight.value, rectangle.destBottom.value, rectangle.width.value, rectangle.height.value, rectangle.bitsPerPixel.value, (rectangle.flags & pdu.BitmapFlag.BITMAP_COMPRESSION).value, rectangle.bitmapDataStream.value) -class ClientFactory(protocol.Factory): +class Factory(protocol.Factory): ''' Factory of Client RDP protocol ''' @@ -45,9 +52,7 @@ class ClientFactory(protocol.Factory): Function call from twisted and build rdp protocol stack @param addr: destination address ''' - pduLayer = pdu.PDU(LayerMode.CLIENT) - pduLayer.getController().addObserver(self.buildObserver()) - return tpkt.TPKT(tpdu.createClient(mcs.MCS(pduLayer))); + return tpkt.TPKT(tpdu.createClient(mcs.createClient(self.buildObserver().getController()))); def buildObserver(self): ''' @@ -75,7 +80,7 @@ class ServerFactory(protocol.Factory): ''' pduLayer = pdu.PDU(LayerMode.SERVER) #pduLayer.getController().addObserver(self.buildObserver()) - return tpkt.TPKT(tpdu.createServer(mcs.MCS(pduLayer), self._privateKeyFileName, self._certificateFileName)); + return tpkt.TPKT(tpdu.createServer(mcs.createServer(pduLayer), self._privateKeyFileName, self._certificateFileName)); def buildObserver(self): ''' @@ -88,10 +93,14 @@ class RDPClientObserver(object): class use to inform all rdp event handle by RDPY ''' def __init__(self): - ''' - ctor - ''' - self._controller = None + self._controller = RDPController(LayerMode.CLIENT) + self._controller.addClientObserver(self) + + def getController(self): + """ + @return: RDP controller use by observer + """ + return self._controller def onBitmapUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data): ''' diff --git a/rdpy/protocol/rfb/rfb.py b/rdpy/protocol/rfb/rfb.py index 2896be4..930d7e6 100644 --- a/rdpy/protocol/rfb/rfb.py +++ b/rdpy/protocol/rfb/rfb.py @@ -1,6 +1,31 @@ -''' -@author: citronneur -''' +# +# Copyright (c) 2014 Sylvain Peyrefitte +# +# This file is part of rdpy. +# +# rdpy is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +""" +Implement Remote FrameBuffer protocol use in VNC client and server +@see: http://www.realvnc.com/docs/rfbproto.pdf + +@todo: server side of protocol +@todo: vnc security type +@todo: more encoding rectangle +""" + from twisted.internet import protocol from rdpy.network.layer import RawLayer, LayerMode from rdpy.network.type import UInt8, UInt16Be, UInt32Be, SInt32Be, String, CompositeType @@ -10,9 +35,9 @@ from rdpy.network.error import UnRegistredObject, InvalidValue @ConstAttributes @TypeAttributes(String) class ProtocolVersion(object): - ''' - different ptotocol version - ''' + """ + Different protocol version + """ UNKNOWN = "" RFB003003 = "RFB 003.003\n" RFB003007 = "RFB 003.007\n" @@ -21,11 +46,9 @@ class ProtocolVersion(object): @ConstAttributes @TypeAttributes(UInt8) class SecurityType(object): - ''' - security type supported - (or will be supported) - by rdpy - ''' + """ + Security type supported + """ INVALID = 0 NONE = 1 VNC = 2 @@ -33,11 +56,11 @@ class SecurityType(object): @ConstAttributes @TypeAttributes(UInt32Be) class Pointer(object): - ''' - mouse event code (which button) - actually in RFB specification only$ + """ + Mouse event code (which button) + actually in RFB specification only three buttons are supported - ''' + """ BUTTON1 = 0x1 BUTTON2 = 0x2 BUTTON3 = 0x4 @@ -45,17 +68,17 @@ class Pointer(object): @ConstAttributes @TypeAttributes(SInt32Be) class Encoding(object): - ''' - encoding types - ''' + """ + Encoding types of FrameBuffer update + """ RAW = 0 @ConstAttributes @TypeAttributes(UInt8) class ClientToServerMessages(object): - ''' - messages types - ''' + """ + Client to server messages types + """ PIXEL_FORMAT = 0 ENCODING = 2 FRAME_BUFFER_UPDATE_REQUEST = 3 @@ -64,9 +87,9 @@ class ClientToServerMessages(object): CUT_TEXT = 6 class PixelFormat(CompositeType): - ''' - pixel format structure - ''' + """ + Pixel format structure + """ def __init__(self): CompositeType.__init__(self) self.BitsPerPixel = UInt8(32) @@ -82,10 +105,10 @@ class PixelFormat(CompositeType): self.padding = (UInt16Be(), UInt8()) class ServerInit(CompositeType): - ''' - server init structure - framebuffer configuration - ''' + """ + Server init structure + FrameBuffer configuration + """ def __init__(self): CompositeType.__init__(self) self.width = UInt16Be() @@ -93,9 +116,11 @@ class ServerInit(CompositeType): self.pixelFormat = PixelFormat() class FrameBufferUpdateRequest(CompositeType): - ''' - fb update request send from client to server - ''' + """ + FrameBuffer update request send from client to server + Incremental means that server send update with a specific + order, and client must draw orders in same order + """ def __init__(self, incremental = False, x = 0, y = 0, width = 0, height = 0): CompositeType.__init__(self) self.incremental = UInt8(incremental) @@ -106,9 +131,9 @@ class FrameBufferUpdateRequest(CompositeType): class Rectangle(CompositeType): - ''' - header message of update rect - ''' + """ + Header message of update rectangle + """ def __init__(self): CompositeType.__init__(self) self.x = UInt16Be() @@ -118,9 +143,10 @@ class Rectangle(CompositeType): self.encoding = SInt32Be() class KeyEvent(CompositeType): - ''' - key event structure message - ''' + """ + Key event structure message + Use to send a keyboard event + """ def __init__(self): CompositeType.__init__(self) self.downFlag = UInt8(False) @@ -128,9 +154,10 @@ class KeyEvent(CompositeType): self.key = UInt32Be() class PointerEvent(CompositeType): - ''' - pointer event structure message - ''' + """ + Pointer event structure message + Use to send mouse event + """ def __init__(self): CompositeType.__init__(self) self.mask = UInt8() @@ -138,36 +165,36 @@ class PointerEvent(CompositeType): self.y = UInt16Be() class ClientCutText(CompositeType): - ''' - client cut text message message - ''' + """ + Client cut text message message + Use to simulate copy paste (ctrl-c ctrl-v) only for text + """ def __init__(self, text = ""): CompositeType.__init__(self) self.padding = (UInt16Be(), UInt8()) self.size = UInt32Be(len(text)) self.message = String(text) -class Rfb(RawLayer): - ''' - implements rfb protocol - ''' - - def __init__(self, mode): - ''' - constructor +class RFB(RawLayer): + """ + Implement RFB protocol + """ + def __init__(self, mode, controller): + """ @param mode: LayerMode client or server - ''' + @param controller: controller use to inform new orders + """ RawLayer.__init__(self, mode) - #usefull for rfb protocol + #useful for RFB protocol self._callbackBody = None - #protocol version negociated + #protocol version negotiated self._version = ProtocolVersion.RFB003008 - #nb security launch by server + #number security launch by server self._securityLevel = SecurityType.INVALID - #shared framebuffer client init message + #shared FrameBuffer client init message self._sharedFlag = UInt8(False) #server init message - #which contain framebuffer dim and pixel format + #which contain FrameBuffer dim and pixel format self._serverInit = ServerInit() #client pixel format self._pixelFormat = PixelFormat() @@ -178,33 +205,26 @@ class Rfb(RawLayer): #current rectangle header self._currentRect = Rectangle() #client or server adaptor - self._controller = RFBController(self) - - def getController(self): - ''' - Getter for controller - @return: RFBController use by rfb layer - ''' - return self._controller + self._controller = controller def expectWithHeader(self, expectedHeaderLen, callbackBody): - ''' + """ 2nd level of waiting event read expectedHeaderLen that contain body size - @param expectedHeaderLen: bytes read and use to compute bodylen - @param callbackBody: next state use when value read from header + @param expectedHeaderLen: contains the number of bytes, which body length needs to be encoded + @param callbackBody: next state use when expected date from expectedHeaderLen are received - ''' + """ self._callbackBody = callbackBody self.expect(expectedHeaderLen, self.expectedBody) def expectedBody(self, data): - ''' - read header and wait header value to call next state + """ + Read header and wait header value to call next state @param data: Stream that length are to header length (1|2|4 bytes) set next state to callBack body when length read from header are received - ''' + """ bodyLen = None if data.len == 1: bodyLen = UInt8() @@ -219,38 +239,36 @@ class Rfb(RawLayer): self.expect(bodyLen.value, self._callbackBody) def connect(self): - ''' - call when transport layer connection is made + """ + Call when transport layer connection is made in Client mode -> wait protocol version in Server mode -> send protocol version - ''' + """ if self._mode == LayerMode.CLIENT: self.expect(12, self.recvProtocolVersion) else: self.send(self._version) def readProtocolVersion(self, data): - ''' - read protocol version and set - self._version var member + """ + Read protocol version @param data: Stream may contain protocol version string (ProtocolVersion) - ''' + """ data.readType(self._version) if not self._version in [ProtocolVersion.RFB003003, ProtocolVersion.RFB003007, ProtocolVersion.RFB003008]: self._version = ProtocolVersion.UNKNOWN def recvProtocolVersion(self, data): - ''' - read handshake packet - protocol version nego - if protocol receive from client is unknow + """ + Read handshake packet + If protocol receive from client is unknown try best version of protocol version (ProtocolVersion.RFB003008) @param data: Stream - ''' + """ self.readProtocolVersion(data) if self._version == ProtocolVersion.UNKNOWN: print "Unknown protocol version %s send 003.008"%data.getvalue() - #protocol version is unknow try best version we can handle + #protocol version is unknown try best version we can handle self._version = ProtocolVersion.RFB003008 #send same version of self.send(self._version) @@ -262,16 +280,19 @@ class Rfb(RawLayer): self.expectWithHeader(1, self.recvSecurityList) def recvSecurityServer(self, data): - ''' - security handshake for 33 rfb version - server imposed security level - ''' + """ + Security handshake for 33 RFB version + Server imposed security level + @param data: well formed packet + """ #TODO!!! + pass def recvSecurityList(self, data): - ''' - read all security list - ''' + """ + Read security list packet send from server to client + @param data: Stream that contains well formed packet + """ securityList = [] while data.dataLen() > 0: securityElement = UInt8() @@ -287,9 +308,11 @@ class Rfb(RawLayer): self.expect(4, self.recvSecurityResult) def recvSecurityResult(self, data): - ''' + """ Read security result packet - ''' + Use by server to inform connection status of client + @param data: Stream that contain well formed packet + """ result = UInt32Be() data.readType(result) if result == UInt32Be(1): @@ -301,19 +324,25 @@ class Rfb(RawLayer): self.sendClientInit() def recvSecurityFailed(self, data): + """ + Send by server to inform reason of why it's refused client + @param data: Stream that contains well formed packet + """ print "Security failed cause to %s"%data.getvalue() def recvServerInit(self, data): - ''' - read server init packet - ''' + """ + Read server init packet + @param data: Stream that contains well formed packet + """ data.readType(self._serverInit) self.expectWithHeader(4, self.recvServerName) def recvServerName(self, data): - ''' - read server name from server init packet - ''' + """ + Read server name + @param data: Stream that contains well formed packet + """ data.readType(self._serverName) print "Server name %s"%str(self._serverName) #end of handshake @@ -326,18 +355,21 @@ class Rfb(RawLayer): self.expect(1, self.recvServerOrder) def recvServerOrder(self, data): - ''' - read order receive from server - ''' + """ + Read order receive from server + Main function for bitmap update from server to client + @param data: Stream that contains well formed packet + """ packet_type = UInt8() data.readType(packet_type) if packet_type == UInt8(0): self.expect(3, self.recvFrameBufferUpdateHeader) def recvFrameBufferUpdateHeader(self, data): - ''' - read frame buffer update packet header - ''' + """ + Read frame buffer update packet header + @param data: Stream that contains well formed packet + """ #padding nbRect = UInt16Be() self._nbRect = data.readType((UInt8(), nbRect)) @@ -345,17 +377,19 @@ class Rfb(RawLayer): self.expect(12, self.recvRectHeader) def recvRectHeader(self, data): - ''' - read rectangle header - ''' + """ + Read rectangle header + @param data: Stream that contains well formed packet + """ data.readType(self._currentRect) if self._currentRect.encoding == Encoding.RAW: self.expect(self._currentRect.width.value * self._currentRect.height.value * (self._pixelFormat.BitsPerPixel.value / 8), self.recvRectBody) def recvRectBody(self, data): - ''' - read body of rect - ''' + """ + Read body of rectangle update + @param data: Stream that contains well formed packet + """ self._controller.recvRectangle(self._currentRect, self._pixelFormat, data.getvalue()) self._nbRect = self._nbRect - 1 @@ -368,89 +402,97 @@ class Rfb(RawLayer): self.expect(12, self.recvRectHeader) def sendClientInit(self): - ''' - write client init packet - ''' + """ + Send client init packet + """ self.send(self._sharedFlag) self.expect(20, self.recvServerInit) def sendPixelFormat(self, pixelFormat): - ''' - send pixel format structure - ''' + """ + Send pixel format structure + Very important packet that inform the image struct supported by the client + @param pixelFormat: PixelFormat struct + """ self.send((ClientToServerMessages.PIXEL_FORMAT, UInt16Be(), UInt8(), pixelFormat)) def sendSetEncoding(self): - ''' - send set encoding packet - ''' + """ + Send set encoding packet + Actually only RAW bitmap encoding are used + """ self.send((ClientToServerMessages.ENCODING, UInt8(), UInt16Be(1), Encoding.RAW)) def sendFramebufferUpdateRequest(self, incremental, x, y, width, height): - ''' - request server the specified zone + """ + Request server the specified zone incremental means request only change before last update - ''' + """ self.send((ClientToServerMessages.FRAME_BUFFER_UPDATE_REQUEST, FrameBufferUpdateRequest(incremental, x, y, width, height))) def sendKeyEvent(self, keyEvent): - ''' - write key event packet + """ + Write key event packet @param keyEvent: KeyEvent struct to send - ''' + """ self.send((ClientToServerMessages.KEY_EVENT, keyEvent)) def sendPointerEvent(self, pointerEvent): - ''' - write pointer event packet + """ + Write pointer event packet @param pointerEvent: PointerEvent struct use - ''' + """ self.send((ClientToServerMessages.POINTER_EVENT, pointerEvent)) def sendClientCutText(self, text): - ''' + """ write client cut text event packet - ''' + """ self.send((ClientToServerMessages.CUT_TEXT, ClientCutText(text))) class RFBController(object): - ''' - class use to manage rfb order and dispatch throw observers - ''' - def __init__(self, rfbLayer): - ''' - ctor - @param rfbLayer: network layer - ''' - self._observers = [] + """ + Class use to manage RFB order and dispatch throw observers + """ + def __init__(self, mode): + """ + @param mode: mode of inner RFB layer + """ + self._clientObservers = [] #rfb layer to send client orders - self._rfbLayer = rfbLayer + self._rfbLayer = RFB(mode, self) - def addObserver(self, observer): - ''' + def getRFBLayer(self): + """ + @return: RFB layer build by controller + """ + return self._rfbLayer + + def addClientObserver(self, observer): + """ Add new observer for this protocol @param observer: new observer - ''' - self._observers.append(observer) + """ + self._clientObservers.append(observer) observer._controller = self def recvRectangle(self, rectangle, pixelFormat, data): - ''' - receive rectangle order + """ + Receive rectangle order Main update order type @param rectangle: Rectangle type header of packet @param pixelFormat: pixelFormat struct of current session @param data: image data - ''' - for observer in self._observers: + """ + for observer in self._clientObservers: observer.onUpdate(rectangle.width.value, rectangle.height.value, rectangle.x.value, rectangle.y.value, pixelFormat, rectangle.encoding, data) def sendKeyEvent(self, isDown, key): - ''' - send a key event throw RFB protocol + """ + Send a key event throw RFB protocol @param isDown: boolean notify if key is pressed or not (True if key is pressed) - @param key: ascii code of key - ''' + @param key: ASCII code of key + """ try: event = KeyEvent() event.downFlag.value = isDown @@ -461,12 +503,12 @@ class RFBController(object): print "Try to send an invalid key event" def sendPointerEvent(self, mask, x, y): - ''' - Send an pointer event throw RFB protocol + """ + Send a pointer event throw RFB protocol @param mask: mask of button if button 1 and 3 are pressed then mask is 00000101 @param x: x coordinate of mouse pointer @param y: y pointer of mouse pointer - ''' + """ try: event = PointerEvent() event.mask.value = mask @@ -478,54 +520,56 @@ class RFBController(object): print "Try to send an invalid pointer event" -class ClientFactory(protocol.Factory): - ''' - Factory of RFB protocol - ''' +class Factory(protocol.Factory): + """ + Twisted Factory of RFB protocol + """ def buildProtocol(self, addr): - ''' - function call by twisted on connection + """ + Function call by twisted on connection @param addr: address where client try to connect - ''' - protocol = Rfb(LayerMode.CLIENT) - protocol.getController().addObserver(self.buildObserver()) - return protocol + """ + return self.buildObserver().getController().getRFBLayer() def buildObserver(self): - ''' - build an RFB observer object - ''' + """ + Build an RFB observer object + """ pass class RFBClientObserver(object): - ''' + """ RFB client protocol observer - ''' + """ def __init__(self): - ''' - ctor - ''' - self._controller = None + self._controller = RFBController(LayerMode.CLIENT) + self._controller.addClientObserver(self) + + def getController(self): + """ + @return: RFB controller use by observer + """ + return self._controller def keyEvent(self, isPressed, key): - ''' - send a key event + """ + Send a key event @param isPressed: state of key @param key: ascii code of key - ''' + """ if self._controller is None: raise UnRegistredObject("RFBClientObserver need to be registred to a RFBController object") self._controller.sendKeyEvent(isPressed, key) def mouseEvent(self, button, x, y): - ''' - send a mouse event to RFB Layer + """ + Send a mouse event to RFB Layer @param button: button number which is pressed (0,1,2,3,4,5,6,7,8) @param x: x coordinate of mouse pointer @param y: y coordinate of mouse pointer - ''' + """ if self._controller is None: raise UnRegistredObject("RFBClientObserver need to be registred to a RFBController object") mask = 0 @@ -537,8 +581,8 @@ class RFBClientObserver(object): self._controller.sendPointerEvent(mask, x, y) def onUpdate(self, width, height, x, y, pixelFormat, encoding, data): - ''' - recv framebuffer update + """ + Receive FrameBuffer update @param width : width of image @param height : height of image @param x : x position @@ -546,5 +590,5 @@ class RFBClientObserver(object): @param pixelFormat : pixel format struct from rfb.types @param encoding : encoding struct from rfb.types @param data : in respect of dataFormat and pixelFormat - ''' + """ pass