fix major bug on update handle
This commit is contained in:
@@ -172,7 +172,7 @@ class RDPClientQtFactory(rdp.ClientFactory):
|
|||||||
connector.connect()
|
connector.connect()
|
||||||
return
|
return
|
||||||
|
|
||||||
QtGui.QMessageBox.warning(self._w, "Warning", "Lost connection : %s"%reason)
|
log.info("Lost connection : %s"%reason)
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
app.exit()
|
app.exit()
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ class RDPClientQtFactory(rdp.ClientFactory):
|
|||||||
@param connector: twisted connector use for rdp connection (use reconnect to restart connection)
|
@param connector: twisted connector use for rdp connection (use reconnect to restart connection)
|
||||||
@param reason: str use to advertise reason of lost connection
|
@param reason: str use to advertise reason of lost connection
|
||||||
"""
|
"""
|
||||||
QtGui.QMessageBox.warning(self._w, "Warning", "Connection failed : %s"%reason)
|
log.info("Connection failed : %s"%reason)
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
app.exit()
|
app.exit()
|
||||||
|
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ class CompositeType(Type):
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
if not self._readLen is None and readLen < self._readLen.value:
|
if not self._readLen is None and readLen < self._readLen.value:
|
||||||
log.debug("Still have correct data in packet %s, read it as padding"%self.__class__)
|
log.debug("Still have correct data in packet %s, read %s bytes as padding"%(self.__class__, self._readLen.value - readLen))
|
||||||
s.read(self._readLen.value - readLen)
|
s.read(self._readLen.value - readLen)
|
||||||
|
|
||||||
def __write__(self, s):
|
def __write__(self, s):
|
||||||
|
|||||||
@@ -413,8 +413,6 @@ class ErrorInfo(object):
|
|||||||
ERRINFO_VCDATATOOLONG : "The size of a received Virtual Channel PDU (section 2.2.6.1) exceeds the chunking size specified in the Virtual Channel Capability Set (section 2.2.7.1.10).",
|
ERRINFO_VCDATATOOLONG : "The size of a received Virtual Channel PDU (section 2.2.6.1) exceeds the chunking size specified in the Virtual Channel Capability Set (section 2.2.7.1.10).",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ShareControlHeader(CompositeType):
|
class ShareControlHeader(CompositeType):
|
||||||
"""
|
"""
|
||||||
@summary: PDU share control header
|
@summary: PDU share control header
|
||||||
@@ -461,10 +459,10 @@ class PDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
for c in [DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU]:
|
for c in [DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU]:
|
||||||
if self.shareControlHeader.pduType.value == c._PDUTYPE_:
|
if self.shareControlHeader.pduType.value == c._PDUTYPE_:
|
||||||
return c()
|
return c(readLen = CallableValue(self.shareControlHeader.totalLength.value - sizeof(self.shareControlHeader)))
|
||||||
log.debug("unknown PDU type : %s"%hex(self.shareControlHeader.pduType.value))
|
log.debug("unknown PDU type : %s"%hex(self.shareControlHeader.pduType.value))
|
||||||
#read entire packet
|
#read entire packet
|
||||||
return String()
|
return String(readLen = CallableValue(self.shareControlHeader.totalLength.value - sizeof(self.shareControlHeader)))
|
||||||
|
|
||||||
if pduMessage is None:
|
if pduMessage is None:
|
||||||
pduMessage = FactoryType(PDUMessageFactory)
|
pduMessage = FactoryType(PDUMessageFactory)
|
||||||
@@ -481,8 +479,8 @@ class DemandActivePDU(CompositeType):
|
|||||||
#may declare the PDU type
|
#may declare the PDU type
|
||||||
_PDUTYPE_ = PDUType.PDUTYPE_DEMANDACTIVEPDU
|
_PDUTYPE_ = PDUType.PDUTYPE_DEMANDACTIVEPDU
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.shareId = UInt32Le()
|
self.shareId = UInt32Le()
|
||||||
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
|
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
|
||||||
self.lengthCombinedCapabilities = UInt16Le(lambda:(sizeof(self.numberCapabilities) + sizeof(self.pad2Octets) + sizeof(self.capabilitySets)))
|
self.lengthCombinedCapabilities = UInt16Le(lambda:(sizeof(self.numberCapabilities) + sizeof(self.pad2Octets) + sizeof(self.capabilitySets)))
|
||||||
@@ -500,8 +498,8 @@ class ConfirmActivePDU(CompositeType):
|
|||||||
#may declare the PDU type
|
#may declare the PDU type
|
||||||
_PDUTYPE_ = PDUType.PDUTYPE_CONFIRMACTIVEPDU
|
_PDUTYPE_ = PDUType.PDUTYPE_CONFIRMACTIVEPDU
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.shareId = UInt32Le()
|
self.shareId = UInt32Le()
|
||||||
self.originatorId = UInt16Le(0x03EA, constant = True)
|
self.originatorId = UInt16Le(0x03EA, constant = True)
|
||||||
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
|
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
|
||||||
@@ -519,10 +517,10 @@ class DeactiveAllPDU(CompositeType):
|
|||||||
#may declare the PDU type
|
#may declare the PDU type
|
||||||
_PDUTYPE_ = PDUType.PDUTYPE_DEACTIVATEALLPDU
|
_PDUTYPE_ = PDUType.PDUTYPE_DEACTIVATEALLPDU
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
#in old version this packet is empty i don't know
|
#in old version this packet is empty i don't know
|
||||||
#and not specified
|
#and not specified
|
||||||
CompositeType.__init__(self, optional = True)
|
CompositeType.__init__(self, optional = True, readLen = readLen)
|
||||||
self.shareId = UInt32Le()
|
self.shareId = UInt32Le()
|
||||||
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
|
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
|
||||||
self.sourceDescriptor = String("rdpy", readLen = self.lengthSourceDescriptor)
|
self.sourceDescriptor = String("rdpy", readLen = self.lengthSourceDescriptor)
|
||||||
@@ -534,8 +532,8 @@ class DataPDU(CompositeType):
|
|||||||
#may declare the PDU type
|
#may declare the PDU type
|
||||||
_PDUTYPE_ = PDUType.PDUTYPE_DATAPDU
|
_PDUTYPE_ = PDUType.PDUTYPE_DATAPDU
|
||||||
|
|
||||||
def __init__(self, pduData = None, shareId = 0):
|
def __init__(self, pduData = None, shareId = 0, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), lambda:self.pduData.__class__._PDUTYPE2_, shareId)
|
self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), lambda:self.pduData.__class__._PDUTYPE2_, shareId)
|
||||||
|
|
||||||
def PDUDataFactory():
|
def PDUDataFactory():
|
||||||
@@ -544,9 +542,9 @@ class DataPDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU, SupressOutputDataPDU, SaveSessionInfoPDU]:
|
for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU, SupressOutputDataPDU, SaveSessionInfoPDU]:
|
||||||
if self.shareDataHeader.pduType2.value == c._PDUTYPE2_:
|
if self.shareDataHeader.pduType2.value == c._PDUTYPE2_:
|
||||||
return c()
|
return c(readLen = CallableValue(self.shareDataHeader.uncompressedLength.value - 18))
|
||||||
log.debug("unknown PDU data type : %s"%hex(self.shareDataHeader.pduType2.value))
|
log.debug("unknown PDU data type : %s"%hex(self.shareDataHeader.pduType2.value))
|
||||||
return String()
|
return String(readLen = CallableValue(self.shareDataHeader.uncompressedLength.value - 18))
|
||||||
|
|
||||||
if pduData is None:
|
if pduData is None:
|
||||||
pduData = FactoryType(PDUDataFactory)
|
pduData = FactoryType(PDUDataFactory)
|
||||||
@@ -655,8 +653,8 @@ class PersistentListPDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
_PDUTYPE2_ = PDUType2.PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST
|
_PDUTYPE2_ = PDUType2.PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST
|
||||||
|
|
||||||
def __init__(self, userId = 0, shareId = 0):
|
def __init__(self, userId = 0, shareId = 0, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.numEntriesCache0 = UInt16Le()
|
self.numEntriesCache0 = UInt16Le()
|
||||||
self.numEntriesCache1 = UInt16Le()
|
self.numEntriesCache1 = UInt16Le()
|
||||||
self.numEntriesCache2 = UInt16Le()
|
self.numEntriesCache2 = UInt16Le()
|
||||||
@@ -679,8 +677,8 @@ class ClientInputEventPDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
_PDUTYPE2_ = PDUType2.PDUTYPE2_INPUT
|
_PDUTYPE2_ = PDUType2.PDUTYPE2_INPUT
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.numEvents = UInt16Le(lambda:len(self.slowPathInputEvents._array))
|
self.numEvents = UInt16Le(lambda:len(self.slowPathInputEvents._array))
|
||||||
self.pad2Octets = UInt16Le()
|
self.pad2Octets = UInt16Le()
|
||||||
self.slowPathInputEvents = ArrayType(SlowPathInputEvent, readLen = self.numEvents)
|
self.slowPathInputEvents = ArrayType(SlowPathInputEvent, readLen = self.numEvents)
|
||||||
@@ -691,8 +689,8 @@ class ShutdownRequestPDU(CompositeType):
|
|||||||
client -> server
|
client -> server
|
||||||
"""
|
"""
|
||||||
_PDUTYPE2_ = PDUType2.PDUTYPE2_SHUTDOWN_REQUEST
|
_PDUTYPE2_ = PDUType2.PDUTYPE2_SHUTDOWN_REQUEST
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
|
|
||||||
class ShutdownDeniedPDU(CompositeType):
|
class ShutdownDeniedPDU(CompositeType):
|
||||||
"""
|
"""
|
||||||
@@ -700,8 +698,8 @@ class ShutdownDeniedPDU(CompositeType):
|
|||||||
server -> client
|
server -> client
|
||||||
"""
|
"""
|
||||||
_PDUTYPE2_ = PDUType2.PDUTYPE2_SHUTDOWN_DENIED
|
_PDUTYPE2_ = PDUType2.PDUTYPE2_SHUTDOWN_DENIED
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
|
|
||||||
class InclusiveRectangle(CompositeType):
|
class InclusiveRectangle(CompositeType):
|
||||||
"""
|
"""
|
||||||
@@ -761,9 +759,15 @@ class UpdateDataPDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
for c in [BitmapUpdateDataPDU]:
|
for c in [BitmapUpdateDataPDU]:
|
||||||
if self.updateType.value == c._UPDATE_TYPE_:
|
if self.updateType.value == c._UPDATE_TYPE_:
|
||||||
return c()
|
if not readLen is None:
|
||||||
|
return c(readLen = CallableValue(readLen.value - 2))
|
||||||
|
else:
|
||||||
|
return c()
|
||||||
log.debug("unknown PDU update data type : %s"%hex(self.updateType.value))
|
log.debug("unknown PDU update data type : %s"%hex(self.updateType.value))
|
||||||
return String()
|
if not readLen is None:
|
||||||
|
return String(readLen = CallableValue(readLen.value - 2))
|
||||||
|
else:
|
||||||
|
return String()
|
||||||
|
|
||||||
if updateData is None:
|
if updateData is None:
|
||||||
updateData = FactoryType(UpdateDataFactory, conditional = lambda:(self.updateType.value != UpdateType.UPDATETYPE_SYNCHRONIZE))
|
updateData = FactoryType(UpdateDataFactory, conditional = lambda:(self.updateType.value != UpdateType.UPDATETYPE_SYNCHRONIZE))
|
||||||
@@ -801,9 +805,9 @@ class FastPathUpdatePDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
for c in [FastPathBitmapUpdateDataPDU]:
|
for c in [FastPathBitmapUpdateDataPDU]:
|
||||||
if (self.updateHeader.value & 0xf) == c._FASTPATH_UPDATE_TYPE_:
|
if (self.updateHeader.value & 0xf) == c._FASTPATH_UPDATE_TYPE_:
|
||||||
return c()
|
return c(readLen = self.size)
|
||||||
log.debug("unknown Fast Path PDU update data type : %s"%hex(self.updateHeader.value & 0xf))
|
log.debug("unknown Fast Path PDU update data type : %s"%hex(self.updateHeader.value & 0xf))
|
||||||
return String()
|
return String(readLen = self.size)
|
||||||
|
|
||||||
if updateData is None:
|
if updateData is None:
|
||||||
updateData = FactoryType(UpdateDataFactory)
|
updateData = FactoryType(UpdateDataFactory)
|
||||||
@@ -833,8 +837,8 @@ class OrderUpdateDataPDU(CompositeType):
|
|||||||
@see: http://msdn.microsoft.com/en-us/library/cc241571.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc241571.aspx
|
||||||
@todo: not implemented yet but need it
|
@todo: not implemented yet but need it
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.pad2OctetsA = UInt16Le()
|
self.pad2OctetsA = UInt16Le()
|
||||||
self.numberOrders = UInt16Le(lambda:len(self.orderData._array))
|
self.numberOrders = UInt16Le(lambda:len(self.orderData._array))
|
||||||
self.pad2OctetsB = UInt16Le()
|
self.pad2OctetsB = UInt16Le()
|
||||||
@@ -894,8 +898,8 @@ class FastPathBitmapUpdateDataPDU(CompositeType):
|
|||||||
"""
|
"""
|
||||||
_FASTPATH_UPDATE_TYPE_ = FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP
|
_FASTPATH_UPDATE_TYPE_ = FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.header = UInt16Le(FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP, constant = True)
|
self.header = UInt16Le(FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP, constant = True)
|
||||||
self.numberRectangles = UInt16Le(lambda:len(self.rectangles._array))
|
self.numberRectangles = UInt16Le(lambda:len(self.rectangles._array))
|
||||||
self.rectangles = ArrayType(BitmapData, readLen = self.numberRectangles)
|
self.rectangles = ArrayType(BitmapData, readLen = self.numberRectangles)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ In this layer are managed all mains bitmap update orders end user inputs
|
|||||||
|
|
||||||
from rdpy.core.layer import LayerAutomata
|
from rdpy.core.layer import LayerAutomata
|
||||||
from rdpy.core.error import CallPureVirtualFuntion
|
from rdpy.core.error import CallPureVirtualFuntion
|
||||||
|
from rdpy.core.type import ArrayType
|
||||||
import rdpy.core.log as log
|
import rdpy.core.log as log
|
||||||
import rdpy.protocol.rdp.tpkt as tpkt
|
import rdpy.protocol.rdp.tpkt as tpkt
|
||||||
import data, caps
|
import data, caps
|
||||||
@@ -266,15 +267,16 @@ class Client(PDULayer):
|
|||||||
@summary: Main receive function after connection sequence
|
@summary: Main receive function after connection sequence
|
||||||
@param s: Stream from transport layer
|
@param s: Stream from transport layer
|
||||||
"""
|
"""
|
||||||
pdu = data.PDU()
|
pdus = ArrayType(data.PDU)
|
||||||
s.readType(pdu)
|
s.readType(pdus)
|
||||||
if pdu.shareControlHeader.pduType.value == data.PDUType.PDUTYPE_DATAPDU:
|
for pdu in pdus:
|
||||||
self.readDataPDU(pdu.pduMessage)
|
if pdu.shareControlHeader.pduType.value == data.PDUType.PDUTYPE_DATAPDU:
|
||||||
elif pdu.shareControlHeader.pduType.value == data.PDUType.PDUTYPE_DEACTIVATEALLPDU:
|
self.readDataPDU(pdu.pduMessage)
|
||||||
#use in deactivation-reactivation sequence
|
elif pdu.shareControlHeader.pduType.value == data.PDUType.PDUTYPE_DEACTIVATEALLPDU:
|
||||||
#next state is either a capabilities re exchange or disconnection
|
#use in deactivation-reactivation sequence
|
||||||
#http://msdn.microsoft.com/en-us/library/cc240454.aspx
|
#next state is either a capabilities re exchange or disconnection
|
||||||
self.setNextState(self.recvDemandActivePDU)
|
#http://msdn.microsoft.com/en-us/library/cc240454.aspx
|
||||||
|
self.setNextState(self.recvDemandActivePDU)
|
||||||
|
|
||||||
def recvFastPath(self, secFlag, fastPathS):
|
def recvFastPath(self, secFlag, fastPathS):
|
||||||
"""
|
"""
|
||||||
@@ -283,11 +285,12 @@ class Client(PDULayer):
|
|||||||
@param fastPathS: {Stream} that contain fast path data
|
@param fastPathS: {Stream} that contain fast path data
|
||||||
@param secFlag: {SecFlags}
|
@param secFlag: {SecFlags}
|
||||||
"""
|
"""
|
||||||
fastPathPDU = data.FastPathUpdatePDU()
|
updates = ArrayType(data.FastPathUpdatePDU)
|
||||||
fastPathS.readType(fastPathPDU)
|
fastPathS.readType(updates)
|
||||||
if fastPathPDU.updateHeader.value == data.FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP:
|
for update in updates:
|
||||||
self._listener.onUpdate(fastPathPDU.updateData.rectangles._array)
|
if update.updateHeader.value == data.FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP:
|
||||||
|
self._listener.onUpdate(update.updateData.rectangles._array)
|
||||||
|
|
||||||
def readDataPDU(self, dataPDU):
|
def readDataPDU(self, dataPDU):
|
||||||
"""
|
"""
|
||||||
@summary: read a data PDU object
|
@summary: read a data PDU object
|
||||||
@@ -329,8 +332,8 @@ class Client(PDULayer):
|
|||||||
generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS
|
generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS
|
||||||
generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT
|
generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT
|
||||||
generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR | caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM
|
generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR | caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM
|
||||||
if not self._fastPathSender is None:
|
#if not self._fastPathSender is None:
|
||||||
generalCapability.extraFlags.value |= caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED
|
# generalCapability.extraFlags.value |= caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED
|
||||||
|
|
||||||
#init bitmap capability
|
#init bitmap capability
|
||||||
bitmapCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_BITMAP].capability
|
bitmapCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_BITMAP].capability
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
|
|||||||
self._widget = QRemoteDesktop(width, height, self)
|
self._widget = QRemoteDesktop(width, height, self)
|
||||||
#set widget screen to RDP stack
|
#set widget screen to RDP stack
|
||||||
controller.setScreen(width, height)
|
controller.setScreen(width, height)
|
||||||
|
self._i = 0
|
||||||
|
|
||||||
def getWidget(self):
|
def getWidget(self):
|
||||||
"""
|
"""
|
||||||
@@ -303,7 +304,9 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
|
|||||||
@param isCompress: {bool} use RLE compression
|
@param isCompress: {bool} use RLE compression
|
||||||
@param data: {str} bitmap data
|
@param data: {str} bitmap data
|
||||||
"""
|
"""
|
||||||
image = RDPBitmapToQtImage(width, height, bitsPerPixel, isCompress, data);
|
image = RDPBitmapToQtImage(width, height, bitsPerPixel, isCompress, data)
|
||||||
|
image.save("/tmp/%s.png"%self._i)
|
||||||
|
self._i += 1
|
||||||
#if image need to be cut
|
#if image need to be cut
|
||||||
#For bit alignement server may send more than image pixel
|
#For bit alignement server may send more than image pixel
|
||||||
self._widget.notifyImage(destLeft, destTop, image, destRight - destLeft + 1, destBottom - destTop + 1)
|
self._widget.notifyImage(destLeft, destTop, image, destRight - destLeft + 1, destBottom - destTop + 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user