customize start script
This commit is contained in:
@@ -3,19 +3,21 @@
|
|||||||
'''
|
'''
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
from rdpy.protocol.rfb.rfb import RfbObserver
|
from rdpy.protocol.rfb.rfb import RfbObserver
|
||||||
|
from rdpy.protocol.rdp.rdp import RDPObserver
|
||||||
|
|
||||||
class QAdaptor(object):
|
class QAdaptor(object):
|
||||||
'''
|
'''
|
||||||
adaptor model with link beetween protocol
|
adaptor model with link beetween protocol
|
||||||
and qt widget
|
and qt widget
|
||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self, qRemoteDesktop):
|
||||||
'''
|
'''
|
||||||
constructor
|
constructor
|
||||||
must set qRemoteDesktop attribute
|
must set qRemoteDesktop attribute
|
||||||
'''
|
'''
|
||||||
#qwidget use for render
|
#qwidget use for render
|
||||||
self._qRemoteDesktop = None
|
self._qRemoteDesktop = qRemoteDesktop
|
||||||
|
self._qRemoteDesktop._adaptor = self
|
||||||
|
|
||||||
def sendMouseEvent(self, e):
|
def sendMouseEvent(self, e):
|
||||||
'''
|
'''
|
||||||
@@ -39,14 +41,21 @@ class RfbAdaptor(RfbObserver, QAdaptor):
|
|||||||
QAdaptor for specific RFB protocol stack
|
QAdaptor for specific RFB protocol stack
|
||||||
is to an RFB observer
|
is to an RFB observer
|
||||||
'''
|
'''
|
||||||
def __init__(self, rfb):
|
def __init__(self, qRemoteDesktop):
|
||||||
'''
|
'''
|
||||||
ctor
|
ctor
|
||||||
@param rfb: RFB protocol stack
|
@param qRemoteDesktop: widget use for render
|
||||||
|
'''
|
||||||
|
QAdaptor.__init__(self, qRemoteDesktop)
|
||||||
|
self._rfb = None
|
||||||
|
|
||||||
|
def setProtocol(self, rfb):
|
||||||
|
'''
|
||||||
|
inherit from RfbObserver
|
||||||
|
init protocol settings
|
||||||
'''
|
'''
|
||||||
self._rfb = rfb
|
|
||||||
#set RFB observer to
|
#set RFB observer to
|
||||||
self._rfb.addObserver(self)
|
self._rfb = rfb
|
||||||
|
|
||||||
def notifyFramebufferUpdate(self, width, height, x, y, pixelFormat, encoding, data):
|
def notifyFramebufferUpdate(self, width, height, x, y, pixelFormat, encoding, data):
|
||||||
'''
|
'''
|
||||||
@@ -92,23 +101,60 @@ class RfbAdaptor(RfbObserver, QAdaptor):
|
|||||||
@param e: qKeyEvent
|
@param e: qKeyEvent
|
||||||
'''
|
'''
|
||||||
self._rfb.sendKeyEvent(True, e.nativeVirtualKey())
|
self._rfb.sendKeyEvent(True, e.nativeVirtualKey())
|
||||||
|
|
||||||
|
class RDPAdaptor(RDPObserver, QAdaptor):
|
||||||
|
'''
|
||||||
|
Adaptor for RDP client
|
||||||
|
'''
|
||||||
|
def __init__(self, qRemoteDesktop):
|
||||||
|
'''
|
||||||
|
constructor
|
||||||
|
@param qRemoteDesktop: widget use for render
|
||||||
|
'''
|
||||||
|
QAdaptor.__init__(self, qRemoteDesktop)
|
||||||
|
|
||||||
|
def notifyBitmapUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
|
||||||
|
'''
|
||||||
|
notify bitmap update
|
||||||
|
@param destLeft: xmin position
|
||||||
|
@param destTop: ymin position
|
||||||
|
@param destRight: xmax position because RDP can send bitmap with padding
|
||||||
|
@param destBottom: ymax position because RDP can send bitmap with padding
|
||||||
|
@param width: width of bitmap
|
||||||
|
@param height: height of bitmap
|
||||||
|
@param bitsPerPixel: number of bit per pixel
|
||||||
|
@param isCompress: use RLE compression
|
||||||
|
@param data: bitmap data
|
||||||
|
'''
|
||||||
|
#TODO
|
||||||
|
if isCompress:
|
||||||
|
return
|
||||||
|
|
||||||
|
imageFormat = None
|
||||||
|
if bitsPerPixel == 16:
|
||||||
|
imageFormat = QtGui.QImage.Format_RGB16
|
||||||
|
elif bitsPerPixel == 24:
|
||||||
|
imageFormat = QtGui.QImage.Format_RGB888
|
||||||
|
elif bitsPerPixel == 32:
|
||||||
|
imageFormat = QtGui.QImage.Format_RGB32
|
||||||
|
else:
|
||||||
|
print "Receive image in bad format"
|
||||||
|
return
|
||||||
|
|
||||||
|
image = QtGui.QImage(data, width, height, imageFormat)
|
||||||
|
self._qRemoteDesktop.notifyImage(destLeft, destTop, image)
|
||||||
|
|
||||||
class QRemoteDesktop(QtGui.QWidget):
|
class QRemoteDesktop(QtGui.QWidget):
|
||||||
'''
|
'''
|
||||||
qt display widget
|
qt display widget
|
||||||
'''
|
'''
|
||||||
def __init__(self, adaptor):
|
def __init__(self):
|
||||||
'''
|
'''
|
||||||
constructor
|
constructor
|
||||||
@param adaptor: any object which inherit
|
|
||||||
from QAdaptor (RfbAdaptor | RdpAdaptor)
|
|
||||||
'''
|
'''
|
||||||
super(QRemoteDesktop, self).__init__()
|
super(QRemoteDesktop, self).__init__()
|
||||||
#set adaptor
|
#set by adaptor
|
||||||
self._adaptor = adaptor
|
self._adaptor = None
|
||||||
#set widget attribute of adaptor
|
|
||||||
self._adaptor._qRemoteDesktop = self
|
|
||||||
#refresh stack of image
|
#refresh stack of image
|
||||||
#because we can update image only in paint
|
#because we can update image only in paint
|
||||||
#event function. When protocol receive image
|
#event function. When protocol receive image
|
||||||
@@ -153,6 +199,8 @@ class QRemoteDesktop(QtGui.QWidget):
|
|||||||
call when mouse move
|
call when mouse move
|
||||||
@param event: qMouseEvent
|
@param event: qMouseEvent
|
||||||
'''
|
'''
|
||||||
|
if self._adaptor is None:
|
||||||
|
print "No adaptor to send mouse move event"
|
||||||
self._adaptor.sendMouseEvent(event)
|
self._adaptor.sendMouseEvent(event)
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
@@ -160,6 +208,8 @@ class QRemoteDesktop(QtGui.QWidget):
|
|||||||
call when button mouse is pressed
|
call when button mouse is pressed
|
||||||
@param event: qMouseEvent
|
@param event: qMouseEvent
|
||||||
'''
|
'''
|
||||||
|
if self._adaptor is None:
|
||||||
|
print "No adaptor to send mouse press event"
|
||||||
self._adaptor.sendMouseEvent(event)
|
self._adaptor.sendMouseEvent(event)
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
@@ -167,4 +217,6 @@ class QRemoteDesktop(QtGui.QWidget):
|
|||||||
call when button key is pressed
|
call when button key is pressed
|
||||||
@param event: qKeyEvent
|
@param event: qKeyEvent
|
||||||
'''
|
'''
|
||||||
|
if self._adaptor is None:
|
||||||
|
print "No adaptor to send key press event"
|
||||||
self._adaptor.sendKeyEvent(event)
|
self._adaptor.sendKeyEvent(event)
|
||||||
0
rdpy/examples/__init__.py
Normal file
0
rdpy/examples/__init__.py
Normal file
36
rdpy/examples/client.py
Normal file
36
rdpy/examples/client.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
'''
|
||||||
|
@author: citronneur
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
# Change path so we find rdpy
|
||||||
|
sys.path.insert(1, os.path.join(sys.path[0], '../..'))
|
||||||
|
|
||||||
|
from PyQt4 import QtGui
|
||||||
|
from rdpy.display.qt import RDPAdaptor, RfbAdaptor, QRemoteDesktop
|
||||||
|
from rdpy.protocol.rdp import rdp
|
||||||
|
from rdpy.protocol.rfb import rfb
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
#create application
|
||||||
|
app = QtGui.QApplication(sys.argv)
|
||||||
|
|
||||||
|
#add qt4 reactor
|
||||||
|
import qt4reactor
|
||||||
|
qt4reactor.install()
|
||||||
|
|
||||||
|
#create widget
|
||||||
|
w = QRemoteDesktop()
|
||||||
|
w.resize(1024, 800)
|
||||||
|
w.setWindowTitle('rdpyclient')
|
||||||
|
w.show()
|
||||||
|
|
||||||
|
if sys.argv[3] == 'rdp':
|
||||||
|
factory = rdp.Factory(RDPAdaptor(w))
|
||||||
|
else:
|
||||||
|
factory = rfb.ClientFactory(RfbAdaptor(w))
|
||||||
|
|
||||||
|
from twisted.internet import reactor
|
||||||
|
reactor.connectTCP(sys.argv[1], int(sys.argv[2]), factory)
|
||||||
|
reactor.run()
|
||||||
|
sys.exit(app.exec_())
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
# Change path so we find rdpy
|
# Change path so we find rdpy
|
||||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
sys.path.insert(1, os.path.join(sys.path[0], '../..'))
|
||||||
|
|
||||||
from rdpy.protocol.rdp import rdp
|
from rdpy.protocol.rdp import rdp
|
||||||
from rdpy.network.layer import LayerMode
|
from rdpy.network.layer import LayerMode
|
||||||
@@ -701,7 +701,7 @@ class PDU(LayerAutomata):
|
|||||||
Global channel for mcs that handle session
|
Global channel for mcs that handle session
|
||||||
identification user, licensing management, and capabilities exchange
|
identification user, licensing management, and capabilities exchange
|
||||||
'''
|
'''
|
||||||
def __init__(self, mode):
|
def __init__(self, mode, dispatcher):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
'''
|
'''
|
||||||
@@ -742,6 +742,9 @@ class PDU(LayerAutomata):
|
|||||||
#share id between client and server
|
#share id between client and server
|
||||||
self._shareId = UInt32Le()
|
self._shareId = UInt32Le()
|
||||||
|
|
||||||
|
#rdp observer
|
||||||
|
self._dispatcher = dispatcher
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
'''
|
'''
|
||||||
connect event in client mode send logon info
|
connect event in client mode send logon info
|
||||||
@@ -793,9 +796,9 @@ class PDU(LayerAutomata):
|
|||||||
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU:
|
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU:
|
||||||
return dataPDU
|
return dataPDU
|
||||||
|
|
||||||
message = "Unknown code %s"%hex(dataPDU.pduData.errorInfo.value)
|
message = "Unknown code %s"%hex(dataPDU.pduData._value.errorInfo.value)
|
||||||
if ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo):
|
if ErrorInfo._MESSAGES_.has_key(dataPDU.pduData._value.errorInfo):
|
||||||
message = ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo]
|
message = ErrorInfo._MESSAGES_[dataPDU.pduData._value.errorInfo]
|
||||||
|
|
||||||
raise ErrorReportedFromPeer("Receive PDU Error info : %s"%message)
|
raise ErrorReportedFromPeer("Receive PDU Error info : %s"%message)
|
||||||
|
|
||||||
@@ -867,6 +870,9 @@ class PDU(LayerAutomata):
|
|||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
'''
|
'''
|
||||||
dataPDU = self.readDataPDU(data)
|
dataPDU = self.readDataPDU(data)
|
||||||
|
if dataPDU.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_UPDATE and dataPDU.pduData._value.updateType == UpdateType.UPDATETYPE_BITMAP:
|
||||||
|
self._dispatcher.recvBitmapUpdateDataPDU(dataPDU.pduData._value.updateData._value)
|
||||||
|
|
||||||
|
|
||||||
def sendConfirmActivePDU(self):
|
def sendConfirmActivePDU(self):
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -3,15 +3,51 @@
|
|||||||
'''
|
'''
|
||||||
from twisted.internet import protocol
|
from twisted.internet import protocol
|
||||||
import tpkt, tpdu, mcs, pdu
|
import tpkt, tpdu, mcs, pdu
|
||||||
|
from rdpy.network.layer import LayerMode
|
||||||
|
|
||||||
|
class RDP(object):
|
||||||
|
'''
|
||||||
|
use to decode and dispatch to observer PDU message and orders
|
||||||
|
'''
|
||||||
|
def __init__(self):
|
||||||
|
'''
|
||||||
|
ctor
|
||||||
|
'''
|
||||||
|
#list of observer
|
||||||
|
self._observers = []
|
||||||
|
|
||||||
|
def addObserver(self, observer):
|
||||||
|
'''
|
||||||
|
add observer to rdp protocol
|
||||||
|
@param observer: new observer to add
|
||||||
|
'''
|
||||||
|
self._observers.append(observer)
|
||||||
|
|
||||||
|
def recvBitmapUpdateDataPDU(self, bitmapUpdateData):
|
||||||
|
'''
|
||||||
|
call when a bitmap data is received from update pdu
|
||||||
|
@param bitmapData: pdu.BitmapData struct
|
||||||
|
'''
|
||||||
|
for observer in self._observers:
|
||||||
|
#for each rectangle in update PDU
|
||||||
|
for rectangle in bitmapUpdateData.rectangles._array:
|
||||||
|
observer.notifyBitmapUpdate(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, rectangle.bitmapDataStream.value)
|
||||||
|
|
||||||
class Factory(protocol.Factory):
|
class Factory(protocol.Factory):
|
||||||
'''
|
'''
|
||||||
Factory of RDP protocol
|
Factory of Client RDP protocol
|
||||||
'''
|
'''
|
||||||
def __init__(self, mode):
|
def __init__(self, observer):
|
||||||
self._mode = mode
|
'''
|
||||||
|
ctor
|
||||||
|
@param observer: observer use by rdp protocol to handle events
|
||||||
|
'''
|
||||||
|
self._observer = observer
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
return tpkt.TPKT(tpdu.TPDU(mcs.MCS(pdu.PDU(self._mode))));
|
rdp = RDP()
|
||||||
|
rdp.addObserver(self._observer)
|
||||||
|
return tpkt.TPKT(tpdu.TPDU(mcs.MCS(pdu.PDU(LayerMode.CLIENT, rdp))));
|
||||||
|
|
||||||
def startedConnecting(self, connector):
|
def startedConnecting(self, connector):
|
||||||
print 'Started to connect.'
|
print 'Started to connect.'
|
||||||
@@ -20,4 +56,23 @@ class Factory(protocol.Factory):
|
|||||||
print 'Lost connection. Reason:', reason
|
print 'Lost connection. Reason:', reason
|
||||||
|
|
||||||
def clientConnectionFailed(self, connector, reason):
|
def clientConnectionFailed(self, connector, reason):
|
||||||
print 'Connection failed. Reason:', reason
|
print 'Connection failed. Reason:', reason
|
||||||
|
|
||||||
|
class RDPObserver(object):
|
||||||
|
'''
|
||||||
|
class use to inform all rdp event handle by RDPY
|
||||||
|
'''
|
||||||
|
def notifyBitmapUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
|
||||||
|
'''
|
||||||
|
notify bitmap update
|
||||||
|
@param destLeft: xmin position
|
||||||
|
@param destTop: ymin position
|
||||||
|
@param destRight: xmax position because RDP can send bitmap with padding
|
||||||
|
@param destBottom: ymax position because RDP can send bitmap with padding
|
||||||
|
@param width: width of bitmap
|
||||||
|
@param height: height of bitmap
|
||||||
|
@param bitsPerPixel: number of bit per pixel
|
||||||
|
@param isCompress: use RLE compression
|
||||||
|
@param data: bitmap data
|
||||||
|
'''
|
||||||
|
pass
|
||||||
@@ -357,6 +357,7 @@ class Rfb(RawLayer):
|
|||||||
'''
|
'''
|
||||||
for observer in self._observer:
|
for observer in self._observer:
|
||||||
observer.notifyFramebufferUpdate(self._currentRect.width.value, self._currentRect.height.value, self._currentRect.x.value, self._currentRect.y.value, self._pixelFormat, self._currentRect.encoding, data.getvalue())
|
observer.notifyFramebufferUpdate(self._currentRect.width.value, self._currentRect.height.value, self._currentRect.x.value, self._currentRect.y.value, self._pixelFormat, self._currentRect.encoding, data.getvalue())
|
||||||
|
|
||||||
self._nbRect = self._nbRect - 1
|
self._nbRect = self._nbRect - 1
|
||||||
#if there is another rect to read
|
#if there is another rect to read
|
||||||
if self._nbRect == 0:
|
if self._nbRect == 0:
|
||||||
@@ -410,15 +411,26 @@ class Rfb(RawLayer):
|
|||||||
'''
|
'''
|
||||||
self.send((ClientToServerMessages.CUT_TEXT, ClientCutText(text)))
|
self.send((ClientToServerMessages.CUT_TEXT, ClientCutText(text)))
|
||||||
|
|
||||||
class Factory(protocol.Factory):
|
class ClientFactory(protocol.Factory):
|
||||||
'''
|
'''
|
||||||
Factory of RFB protocol
|
Factory of RFB protocol
|
||||||
'''
|
'''
|
||||||
def __init__(self, mode):
|
def __init__(self, observer):
|
||||||
self._protocol = Rfb(mode)
|
'''
|
||||||
|
save mode and adapter
|
||||||
|
@param adapter: graphic client adapter
|
||||||
|
'''
|
||||||
|
self._observer = observer
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
return self._protocol;
|
'''
|
||||||
|
function call by twisted on connection
|
||||||
|
@param addr: adresse where client try to connect
|
||||||
|
'''
|
||||||
|
protocol = Rfb(LayerMode.CLIENT)
|
||||||
|
protocol.addObserver(self._observer)
|
||||||
|
self._observer.setProtocol(protocol)
|
||||||
|
return protocol
|
||||||
|
|
||||||
def startedConnecting(self, connector):
|
def startedConnecting(self, connector):
|
||||||
print 'Started to connect.'
|
print 'Started to connect.'
|
||||||
@@ -444,4 +456,11 @@ class RfbObserver(object):
|
|||||||
@param encoding : encoding struct from rfb.types
|
@param encoding : encoding struct from rfb.types
|
||||||
@param data : in respect of dataFormat and pixelFormat
|
@param data : in respect of dataFormat and pixelFormat
|
||||||
'''
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def setProtocol(self, rfbLayer):
|
||||||
|
'''
|
||||||
|
call when observer is added to an rfb layer
|
||||||
|
@param: rfbLayer layer inform the observer
|
||||||
|
'''
|
||||||
pass
|
pass
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
'''
|
|
||||||
Created on 4 sept. 2013
|
|
||||||
|
|
||||||
@author: sylvain
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys, os
|
|
||||||
# Change path so we find rdpy
|
|
||||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
|
||||||
|
|
||||||
from rdpy.protocol.rdp import rdp
|
|
||||||
from rdpy.network.layer import LayerMode
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
from twisted.internet import reactor
|
|
||||||
reactor.connectTCP("192.168.135.59", 3389, rdp.Factory(LayerMode.CLIENT))
|
|
||||||
reactor.run()
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
'''
|
'''
|
||||||
import sys, os
|
import sys, os
|
||||||
# Change path so we find rdpy
|
# Change path so we find rdpy
|
||||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
sys.path.insert(1, os.path.join(sys.path[0], '../..'))
|
||||||
import unittest, rdpy.tests.network.type, rdpy.tests.network.const, rdpy.tests.network.layer
|
import unittest, rdpy.tests.network.type, rdpy.tests.network.const, rdpy.tests.network.layer
|
||||||
|
|
||||||
def headerTest(name):
|
def headerTest(name):
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
'''
|
|
||||||
@author: sylvain
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
# Change path so we find rdpy
|
|
||||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
|
||||||
|
|
||||||
from PyQt4 import QtGui
|
|
||||||
from rdpy.display.qt import RfbAdaptor, QRemoteDesktop
|
|
||||||
from rdpy.protocol.rfb import rfb
|
|
||||||
from rdpy.network.layer import LayerMode
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
#create application
|
|
||||||
app = QtGui.QApplication(sys.argv)
|
|
||||||
|
|
||||||
#add qt4 reactor
|
|
||||||
import qt4reactor
|
|
||||||
qt4reactor.install()
|
|
||||||
|
|
||||||
#create rfb protocol
|
|
||||||
factory = rfb.Factory(LayerMode.CLIENT)
|
|
||||||
w = QRemoteDesktop(RfbAdaptor(factory._protocol))
|
|
||||||
w.resize(1000, 700)
|
|
||||||
w.setWindowTitle('vncclient')
|
|
||||||
w.show()
|
|
||||||
from twisted.internet import reactor
|
|
||||||
reactor.connectTCP("127.0.0.1", 5903, factory)
|
|
||||||
reactor.run()
|
|
||||||
sys.exit(app.exec_())
|
|
||||||
Reference in New Issue
Block a user