add wdget system

This commit is contained in:
citronneur
2014-07-27 21:03:48 +02:00
parent 3f854bd18b
commit dca9613707
3 changed files with 150 additions and 128 deletions

View File

@@ -29,10 +29,20 @@ sys.path.insert(1, os.path.join(sys.path[0], '..'))
from rdpy.base import log, error from rdpy.base import log, error
from rdpy.protocol.rdp import rdp from rdpy.protocol.rdp import rdp
from rdpy.network.proxy import IProxyClient from rdpy.ui import widget
from twisted.internet import reactor from twisted.internet import reactor
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
class IProxyClient(object):
def getColorDepth(self):
pass
def sendKeyEventScancode(self, code, isPressed):
pass
def sendKeyEventUnicode(self, code, isPressed):
pass
def sendPointerEvent(self, x, y, button, isPressed):
pass
class ProxyServer(rdp.RDPServerObserver): class ProxyServer(rdp.RDPServerObserver):
""" """
Server side of proxy Server side of proxy
@@ -62,7 +72,7 @@ class ProxyServer(rdp.RDPServerObserver):
domain, username, password = self._controller.getCredentials() domain, username, password = self._controller.getCredentials()
if self._credentialProvider.isAdmin(domain, username, password): if self._credentialProvider.isAdmin(domain, username, password):
self.clientConnected(AdminGUI(self)) self.clientConnected(ProxyAdmin(self))
return return
try: try:
@@ -126,29 +136,6 @@ class ProxyClient(rdp.RDPClientObserver, IProxyClient):
rdp.RDPClientObserver.__init__(self, controller) rdp.RDPClientObserver.__init__(self, controller)
self._server = server self._server = server
def getColorDepth(self):
"""
@return: color depth of session (15,16,24,32)
"""
return self._controller.getColorDepth()
def sendKeyEventScancode(self, code, isPressed):
"""
Send key event with scan code
@param code: scan code
@param isPressed: True if keyboard key is pressed
"""
self._controller.sendKeyEventScancode(code, isPressed)
def sendPointerEvent(self, x, y, button, isPressed):
"""
Send Pointer event
@param x: x position
@param y: y position
@param button: mouse button 1|2|3
"""
self._controller.sendPointerEvent(x, y, button, isPressed)
def onReady(self): def onReady(self):
""" """
Event use to signal that RDP stack is ready Event use to signal that RDP stack is ready
@@ -172,6 +159,14 @@ class ProxyClient(rdp.RDPClientObserver, IProxyClient):
@param data: bitmap data @param data: bitmap data
""" """
self._server._controller.sendUpdate(destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data) self._server._controller.sendUpdate(destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data)
def getColorDepth(self):
return self._controller.getColorDepth()
def sendKeyEventScancode(self, code, isPressed):
self._controller.sendKeyEventScancode(code, isPressed)
def sendKeyEventUnicode(self, code, isPressed):
self._controller.sendKeyEventUnicode(code, isPressed)
def sendPointerEvent(self, x, y, button, isPressed):
self._controller.sendPointerEvent(x, y, button, isPressed)
class ProxyServerFactory(rdp.ServerFactory): class ProxyServerFactory(rdp.ServerFactory):
""" """
@@ -182,7 +177,7 @@ class ProxyServerFactory(rdp.ServerFactory):
@param config: rdp-proxy configuration @param config: rdp-proxy configuration
@param credentialProvider: CredentialProvider @param credentialProvider: CredentialProvider
""" """
rdp.ServerFactory.__init__(self, "/home/speyrefitte/dev/certificate/rdpy.key", "/home/speyrefitte/dev/certificate/rdpy.crt", 16) rdp.ServerFactory.__init__(self, "/home/sylvain/dev/certificate/rdpy.key", "/home/sylvain/dev/certificate/rdpy.crt", 16)
self._credentialProvider = credentialProvider self._credentialProvider = credentialProvider
def buildObserver(self, controller): def buildObserver(self, controller):
@@ -281,62 +276,24 @@ class CredentialProvider(object):
""" """
return self._config['admin']['domain'] == domain and self._config['admin']['username'] == username and self._config['admin']['password'] == password return self._config['admin']['domain'] == domain and self._config['admin']['username'] == username and self._config['admin']['password'] == password
class AdminGUI(IProxyClient): class ProxyAdmin(IProxyClient):
"""
Simple Administration GUI
"""
def __init__(self, server): def __init__(self, server):
"""
@param server: ProxyServer
@param colorDepth: color depth use to generate screen
"""
self._server = server self._server = server
self._colorDepth = self._server._controller.getColorDepth() #self._list = widget.List(ProxyClientFactory._CLIENT_PROXY_.keys(), 100, 100, self.onSelect, widget.Anchor(0, 0, widget.RDPWidgetListener(self._server._controller)))
self._activeSessions = [ (x, y) for x, y in ProxyClientFactory._CLIENT_PROXY_.iteritems() ] self._list = widget.List(["salut les copains"], 300, 300, self.onSelect, widget.Anchor(0, 0, widget.RDPWidgetListener(self._server._controller)))
self._current = 0
self.display()
def getColorDepth(self): def getColorDepth(self):
return self._colorDepth return 16
def sendKeyEventScancode(self, code, isPressed): def sendKeyEventScancode(self, code, isPressed):
#enter key if isPressed:
if code == 28: self._list.keyEvent(code)
clientController = self._activeSessions[self._current][1]._controller def sendKeyEventUnicode(self, code, isPressed):
self._server.clientConnected(ProxyClient(clientController, self._server)) pass
#force refresh for new admin screen
width, height = self._server._controller.getScreen()
clientController.sendRefreshOrder(0, 0, width, height)
def sendPointerEvent(self, x, y, button, isPressed): def sendPointerEvent(self, x, y, button, isPressed):
pass pass
def onSelect(self, name):
def display(self): if ProxyClientFactory._CLIENT_PROXY_.has_key(name):
""" self._server.clientConnected(ProxyClient(ProxyClientFactory._CLIENT_PROXY_[name]._controller, self._server))
Draw GUI that list active session
"""
i = 0
for name, session in self._activeSessions:
screen = QtGui.QImage(200, 20, QtGui.QImage.Format_RGB16)
if i == self._current:
screen.fill(QtCore.Qt.darkGray)
else:
screen.fill(QtCore.Qt.black)
with QtGui.QPainter(screen) as qp:
if i == self._current:
qp.setPen(QtCore.Qt.black)
else:
qp.setPen(QtCore.Qt.gray)
qp.setFont(QtGui.QFont('arial', 12))
qp.drawText(screen.rect(), QtCore.Qt.AlignCenter, name)
ptr = screen.bits()
ptr.setsize(screen.byteCount())
self._server._controller.sendUpdate(0, i*25, 199, 19, 200, 20, self._colorDepth, False, ptr.asstring())
i+= 1
def help(): def help():
""" """
Print help in console Print help in console

View File

@@ -1,53 +0,0 @@
#
# 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 <http://www.gnu.org/licenses/>.
#
"""
Proxy Interface
client -> ProxyServer | ProxyClient -> server
"""
from rdpy.base.error import CallPureVirtualFuntion
class IProxyClient(object):
"""
Proxy interface for client side
"""
def getColorDepth(self):
"""
@return: color depth of session (15,16,24,32)
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onUpdate", "IProxyClient"))
def sendKeyEventScancode(self, code, isPressed):
"""
Send key event with scan code
@param code: scan code
@param isPressed: True if keyboard key is pressed
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onUpdate", "IProxyClient"))
def sendPointerEvent(self, x, y, button, isPressed):
"""
Send Pointer event
@param x: x position
@param y: y position
@param button: mouse button 1|2|3
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onUpdate", "IProxyClient"))

118
rdpy/ui/widget.py Normal file
View File

@@ -0,0 +1,118 @@
#
# 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 <http://www.gnu.org/licenses/>.
#
"""
Fake widget
"""
from rdpy.base.error import CallPureVirtualFuntion
from PyQt4 import QtGui, QtCore
class IWidgetLister(object):
"""
Listener for object
"""
def onUpdate(self, x, y, image):
"""
Event call by widget when it need to be updated
@param x: x position
@param y: y position
@param image: QImage
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onUpdate", "IWidgetLister"))
class IWidget(object):
def keyEvent(self, code):
pass
def pointerEvent(self, x, y, button):
pass
class Anchor(IWidgetLister):
def __init__(self, x, y, listener):
self._x = x
self._y = y
self._listener = listener
def onUpdate(self, x, y, image):
self._listener.onUpdate(x + self._x, y + self._y, image)
class List(IWidget):
"""
List widget simulate by QT painter
"""
def __init__(self, labels, width, height, callback, listener):
self._labels = labels
self._width = width
self._height = height
self._current = 0
self._listener = listener
self.update()
self._callback = callback
def keyEvent(self, code):
#enter key
if code == 28 and len(self._labels) > 0:
self._callback(self._labels[self._current])
def pointerEvent(self, x, y, button):
pass
def update(self):
"""
Draw GUI that list active session
"""
i = 0
drawArea = QtGui.QImage(self._width, self._height, QtGui.QImage.Format_RGB16)
drawArea.fill(QtCore.Qt.blue)
with QtGui.QPainter(drawArea) as qp:
for label in self._labels:
if i == self._current:
qp.setPen(QtCore.Qt.darkGreen)
qp.drawRoundedRect(0, i * 25, self._width, 25, 0.2, 0.2)
qp.setPen(QtCore.Qt.black)
else:
qp.setPen(QtCore.Qt.gray)
qp.setFont(QtGui.QFont('courier', 12))
qp.drawText(0, 0, label)
self._listener.onUpdate(0, 25 * i, drawArea)
class RDPWidgetListener(IWidgetLister):
def __init__(self, server):
"""
@param server: RDPServerController
"""
self._server = server
def onUpdate(self, x, y, image):
"""
Event call by widget when it need to be updated
@param x: x position
@param y: y position
@param image: QImage
"""
nbWidth = image.width() / 64 + 1
nbHeight = image.height() / 64 + 1
for i in range(0, nbWidth):
for j in range(0, nbHeight):
tmp = image.copy(i * 64, j * 64, 64, 64)
ptr = tmp.bits()
ptr.setsize(tmp.byteCount())
self._server.sendUpdate(i*64 + x, j*64 + y, i*64 + x + tmp.width() - 1, j*64 + y + tmp.height() - 1, tmp.width(), tmp.height(), 16, False, ptr.asstring())