Experimental support for vnc

This commit is contained in:
Emanuele 2020-05-29 00:01:51 +01:00
parent ab5c81129f
commit 527674cf27
2 changed files with 101 additions and 38 deletions

View file

@ -1,4 +1,4 @@
WIDTH = 1408
WIDTH = 1404
HEIGHT = 1872
PIXELS_NUM = WIDTH * HEIGHT
TOTAL_BYTES = PIXELS_NUM * 2

View file

@ -13,7 +13,12 @@ import os
import logging
log = logging.getLogger('rmview')
from lz4framed import Decompressor, Lz4FramedNoDataError
from twisted.internet.protocol import Protocol
from twisted.internet import protocol
from twisted.application import internet, service
from vncdotool.rfb import *
try:
GRAY16 = QImage.Format_Grayscale16
@ -28,6 +33,53 @@ class FBWSignals(QObject):
onFatalError = pyqtSignal(Exception)
onNewFrame = pyqtSignal(QImage)
class RFBTest(RFBClient):
img = QImage(WIDTH, HEIGHT, GRAY16)
# bla = 0
def vncConnectionMade(self):
self.signals = self.factory.signals
self.setEncodings([RAW_ENCODING])
self.framebufferUpdateRequest()
def commitUpdate(self, rectangles=None):
self.signals.onNewFrame.emit(self.img)
self.framebufferUpdateRequest(incremental=1)
def updateRectangle(self, x, y, width, height, data):
# print("RECT: ", x, y, width, height, data[:20])
# c = qRgb(self.bla,self.bla,self.bla)
# self.bla += 5
# print(width, WIDTH , height, HEIGHT, (width == WIDTH) and (height == HEIGHT))
if (width == WIDTH) and (height == HEIGHT):
print("bulk")
self.img = QImage(data, WIDTH, HEIGHT, WIDTH * 2, GRAY16)
else:
for a in range(width):
for b in range(height):
# print(a,b,data[:10])
c = data[2*(a+(b*width))] + data[2*(a+(b*width))+1]
self.img.setPixel(x+a,y+b,qRgb(c,c,c)) # data[a+(b*width)]
class RFBTestFactory(RFBFactory):
"""test factory"""
protocol = RFBTest
def __init__(self, signals):
super(RFBTestFactory, self).__init__()
self.signals = signals
def clientConnectionLost(self, connector, reason):
print(reason)
# connector.connect()
def clientConnectionFailed(self, connector, reason):
print("connection failed:", reason)
from twisted.internet import reactor
reactor.callFromThread(reactor.stop)
class FrameBufferWorker(QRunnable):
@ -42,50 +94,61 @@ class FrameBufferWorker(QRunnable):
lz4_path=lz4_path or "$HOME/lz4")
self.ssh = ssh
self.img_format = img_format
host = "192.168.1.111"
port = 5900
self.signals = FBWSignals()
self.vncClient = internet.TCPClient(host, port, RFBTestFactory(self.signals))
def stop(self):
from twisted.internet import reactor
print("Stopping")
reactor.callFromThread(reactor.stop)
print("Stopped")
self._stop = True
@pyqtSlot()
def run(self):
from twisted.internet import reactor
self.vncClient.startService()
reactor.run(installSignalHandlers=0)
_, rmstream, rmerr = self.ssh.exec_command(self._read_loop)
# _, rmstream, rmerr = self.ssh.exec_command(self._read_loop)
data = b''
if SHOW_FPS:
f = 0
t = time.perf_counter()
fps = 0
# data = b''
# if SHOW_FPS:
# f = 0
# t = time.perf_counter()
# fps = 0
try:
for chunk in Decompressor(rmstream):
data += chunk
while len(data) >= TOTAL_BYTES:
pix = data[:TOTAL_BYTES]
data = data[TOTAL_BYTES:]
self.signals.onNewFrame.emit(QImage(pix, WIDTH, HEIGHT, WIDTH * 2, self.img_format))
if SHOW_FPS:
f += 1
if f % 10 == 0:
fps = 10 / (time.perf_counter() - t)
t = time.perf_counter()
print("FRAME %d | FPS %.3f\r" % (f, fps), end='')
if self._stop:
log.debug('Stopping framebuffer worker')
break
except Lz4FramedNoDataError:
e = rmerr.read().decode('ascii')
s = rmstream.channel.recv_exit_status()
if s == 127:
log.info("Check if your remarkable has lz4 installed! %s", e)
self.signals.onFatalError.emit(Exception(e))
else:
log.warning("Frame data stream is empty.\nExit status: %d %s", s, e)
# try:
# for chunk in Decompressor(rmstream):
# data += chunk
# while len(data) >= TOTAL_BYTES:
# pix = data[:TOTAL_BYTES]
# data = data[TOTAL_BYTES:]
# self.signals.onNewFrame.emit(QImage(pix, WIDTH, HEIGHT, WIDTH * 2, self.img_format))
# if SHOW_FPS:
# f += 1
# if f % 10 == 0:
# fps = 10 / (time.perf_counter() - t)
# t = time.perf_counter()
# print("FRAME %d | FPS %.3f\r" % (f, fps), end='')
# if self._stop:
# log.debug('Stopping framebuffer worker')
# break
# except Lz4FramedNoDataError:
# e = rmerr.read().decode('ascii')
# s = rmstream.channel.recv_exit_status()
# if s == 127:
# log.info("Check if your remarkable has lz4 installed! %s", e)
# self.signals.onFatalError.emit(Exception(e))
# else:
# log.warning("Frame data stream is empty.\nExit status: %d %s", s, e)
except Exception as e:
log.error("Error: %s %s", type(e), e)
self.signals.onFatalError.emit(e)
# except Exception as e:
# log.error("Error: %s %s", type(e), e)
# self.signals.onFatalError.emit(e)
@ -128,7 +191,7 @@ class PointerWorker(QRunnable):
except struct.error:
return
except Exception as e:
log.error('Error in pointer worker: %s %s', type(e), e)
# log.error('Error in pointer worker: %s %s', type(e), e)
return
# decoding adapted from remarkable_mouse
@ -149,12 +212,12 @@ class PointerWorker(QRunnable):
if e_code == e_code_stylus_pressure:
if e_value > self.threshold:
if state == LIFTED:
log.debug('PRESS')
# log.debug('PRESS')
state = PRESSED
self.signals.onPenPress.emit()
else:
if state == PRESSED:
log.debug('RELEASE')
# log.debug('RELEASE')
state = LIFTED
self.signals.onPenLift.emit()