Mejoras en general
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
260
lib/bgr233_palette.py
Normal file
260
lib/bgr233_palette.py
Normal file
@@ -0,0 +1,260 @@
|
||||
# BGR233 palette
|
||||
|
||||
palette = [
|
||||
0, 0, 0,
|
||||
36, 0, 0,
|
||||
73, 0, 0,
|
||||
109, 0, 0,
|
||||
146, 0, 0,
|
||||
182, 0, 0,
|
||||
219, 0, 0,
|
||||
255, 0, 0,
|
||||
0, 36, 0,
|
||||
36, 36, 0,
|
||||
73, 36, 0,
|
||||
109, 36, 0,
|
||||
146, 36, 0,
|
||||
182, 36, 0,
|
||||
219, 36, 0,
|
||||
255, 36, 0,
|
||||
0, 73, 0,
|
||||
36, 73, 0,
|
||||
73, 73, 0,
|
||||
109, 73, 0,
|
||||
146, 73, 0,
|
||||
182, 73, 0,
|
||||
219, 73, 0,
|
||||
255, 73, 0,
|
||||
0, 109, 0,
|
||||
36, 109, 0,
|
||||
73, 109, 0,
|
||||
109, 109, 0,
|
||||
146, 109, 0,
|
||||
182, 109, 0,
|
||||
219, 109, 0,
|
||||
255, 109, 0,
|
||||
0, 146, 0,
|
||||
36, 146, 0,
|
||||
73, 146, 0,
|
||||
109, 146, 0,
|
||||
146, 146, 0,
|
||||
182, 146, 0,
|
||||
219, 146, 0,
|
||||
255, 146, 0,
|
||||
0, 182, 0,
|
||||
36, 182, 0,
|
||||
73, 182, 0,
|
||||
109, 182, 0,
|
||||
146, 182, 0,
|
||||
182, 182, 0,
|
||||
219, 182, 0,
|
||||
255, 182, 0,
|
||||
0, 219, 0,
|
||||
36, 219, 0,
|
||||
73, 219, 0,
|
||||
109, 219, 0,
|
||||
146, 219, 0,
|
||||
182, 219, 0,
|
||||
219, 219, 0,
|
||||
255, 219, 0,
|
||||
0, 255, 0,
|
||||
36, 255, 0,
|
||||
73, 255, 0,
|
||||
109, 255, 0,
|
||||
146, 255, 0,
|
||||
182, 255, 0,
|
||||
219, 255, 0,
|
||||
255, 255, 0,
|
||||
0, 0, 85,
|
||||
36, 0, 85,
|
||||
73, 0, 85,
|
||||
109, 0, 85,
|
||||
146, 0, 85,
|
||||
182, 0, 85,
|
||||
219, 0, 85,
|
||||
255, 0, 85,
|
||||
0, 36, 85,
|
||||
36, 36, 85,
|
||||
73, 36, 85,
|
||||
109, 36, 85,
|
||||
146, 36, 85,
|
||||
182, 36, 85,
|
||||
219, 36, 85,
|
||||
255, 36, 85,
|
||||
0, 73, 85,
|
||||
36, 73, 85,
|
||||
73, 73, 85,
|
||||
109, 73, 85,
|
||||
146, 73, 85,
|
||||
182, 73, 85,
|
||||
219, 73, 85,
|
||||
255, 73, 85,
|
||||
0, 109, 85,
|
||||
36, 109, 85,
|
||||
73, 109, 85,
|
||||
109, 109, 85,
|
||||
146, 109, 85,
|
||||
182, 109, 85,
|
||||
219, 109, 85,
|
||||
255, 109, 85,
|
||||
0, 146, 85,
|
||||
36, 146, 85,
|
||||
73, 146, 85,
|
||||
109, 146, 85,
|
||||
146, 146, 85,
|
||||
182, 146, 85,
|
||||
219, 146, 85,
|
||||
255, 146, 85,
|
||||
0, 182, 85,
|
||||
36, 182, 85,
|
||||
73, 182, 85,
|
||||
109, 182, 85,
|
||||
146, 182, 85,
|
||||
182, 182, 85,
|
||||
219, 182, 85,
|
||||
255, 182, 85,
|
||||
0, 219, 85,
|
||||
36, 219, 85,
|
||||
73, 219, 85,
|
||||
109, 219, 85,
|
||||
146, 219, 85,
|
||||
182, 219, 85,
|
||||
219, 219, 85,
|
||||
255, 219, 85,
|
||||
0, 255, 85,
|
||||
36, 255, 85,
|
||||
73, 255, 85,
|
||||
109, 255, 85,
|
||||
146, 255, 85,
|
||||
182, 255, 85,
|
||||
219, 255, 85,
|
||||
255, 255, 85,
|
||||
0, 0, 170,
|
||||
36, 0, 170,
|
||||
73, 0, 170,
|
||||
109, 0, 170,
|
||||
146, 0, 170,
|
||||
182, 0, 170,
|
||||
219, 0, 170,
|
||||
255, 0, 170,
|
||||
0, 36, 170,
|
||||
36, 36, 170,
|
||||
73, 36, 170,
|
||||
109, 36, 170,
|
||||
146, 36, 170,
|
||||
182, 36, 170,
|
||||
219, 36, 170,
|
||||
255, 36, 170,
|
||||
0, 73, 170,
|
||||
36, 73, 170,
|
||||
73, 73, 170,
|
||||
109, 73, 170,
|
||||
146, 73, 170,
|
||||
182, 73, 170,
|
||||
219, 73, 170,
|
||||
255, 73, 170,
|
||||
0, 109, 170,
|
||||
36, 109, 170,
|
||||
73, 109, 170,
|
||||
109, 109, 170,
|
||||
146, 109, 170,
|
||||
182, 109, 170,
|
||||
219, 109, 170,
|
||||
255, 109, 170,
|
||||
0, 146, 170,
|
||||
36, 146, 170,
|
||||
73, 146, 170,
|
||||
109, 146, 170,
|
||||
146, 146, 170,
|
||||
182, 146, 170,
|
||||
219, 146, 170,
|
||||
255, 146, 170,
|
||||
0, 182, 170,
|
||||
36, 182, 170,
|
||||
73, 182, 170,
|
||||
109, 182, 170,
|
||||
146, 182, 170,
|
||||
182, 182, 170,
|
||||
219, 182, 170,
|
||||
255, 182, 170,
|
||||
0, 219, 170,
|
||||
36, 219, 170,
|
||||
73, 219, 170,
|
||||
109, 219, 170,
|
||||
146, 219, 170,
|
||||
182, 219, 170,
|
||||
219, 219, 170,
|
||||
255, 219, 170,
|
||||
0, 255, 170,
|
||||
36, 255, 170,
|
||||
73, 255, 170,
|
||||
109, 255, 170,
|
||||
146, 255, 170,
|
||||
182, 255, 170,
|
||||
219, 255, 170,
|
||||
255, 255, 170,
|
||||
0, 0, 255,
|
||||
36, 0, 255,
|
||||
73, 0, 255,
|
||||
109, 0, 255,
|
||||
146, 0, 255,
|
||||
182, 0, 255,
|
||||
219, 0, 255,
|
||||
255, 0, 255,
|
||||
0, 36, 255,
|
||||
36, 36, 255,
|
||||
73, 36, 255,
|
||||
109, 36, 255,
|
||||
146, 36, 255,
|
||||
182, 36, 255,
|
||||
219, 36, 255,
|
||||
255, 36, 255,
|
||||
0, 73, 255,
|
||||
36, 73, 255,
|
||||
73, 73, 255,
|
||||
109, 73, 255,
|
||||
146, 73, 255,
|
||||
182, 73, 255,
|
||||
219, 73, 255,
|
||||
255, 73, 255,
|
||||
0, 109, 255,
|
||||
36, 109, 255,
|
||||
73, 109, 255,
|
||||
109, 109, 255,
|
||||
146, 109, 255,
|
||||
182, 109, 255,
|
||||
219, 109, 255,
|
||||
255, 109, 255,
|
||||
0, 146, 255,
|
||||
36, 146, 255,
|
||||
73, 146, 255,
|
||||
109, 146, 255,
|
||||
146, 146, 255,
|
||||
182, 146, 255,
|
||||
219, 146, 255,
|
||||
255, 146, 255,
|
||||
0, 182, 255,
|
||||
36, 182, 255,
|
||||
73, 182, 255,
|
||||
109, 182, 255,
|
||||
146, 182, 255,
|
||||
182, 182, 255,
|
||||
219, 182, 255,
|
||||
255, 182, 255,
|
||||
0, 219, 255,
|
||||
36, 219, 255,
|
||||
73, 219, 255,
|
||||
109, 219, 255,
|
||||
146, 219, 255,
|
||||
182, 219, 255,
|
||||
219, 219, 255,
|
||||
255, 219, 255,
|
||||
0, 255, 255,
|
||||
36, 255, 255,
|
||||
73, 255, 255,
|
||||
109, 255, 255,
|
||||
146, 255, 255,
|
||||
182, 255, 255,
|
||||
219, 255, 255,
|
||||
255, 255, 255
|
||||
]
|
||||
@@ -16,5 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# at least, raw encoding is needed by the rfb protocol
|
||||
from . import common as enc
|
||||
from . import common
|
||||
from . import raw
|
||||
from . import zlib
|
||||
from . import cursor
|
||||
|
||||
@@ -15,5 +15,15 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
encodings = {}
|
||||
|
||||
class ENCODINGS:
|
||||
pass
|
||||
raw = 0
|
||||
zlib = 6
|
||||
# supported pseudo-encodings
|
||||
cursor = -239
|
||||
|
||||
encodings_priority = [
|
||||
ENCODINGS.zlib,
|
||||
ENCODINGS.raw
|
||||
]
|
||||
|
||||
@@ -16,5 +16,21 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import common
|
||||
from struct import *
|
||||
from lib import log
|
||||
import zlib
|
||||
|
||||
common.ENCODINGS.cursor = -239
|
||||
class Encoding:
|
||||
name = 'Cursor'
|
||||
id = -239
|
||||
description = 'Cursor pseudo encoding'
|
||||
enabled = True
|
||||
pseudoEncoding = True
|
||||
|
||||
cursor_sent = False
|
||||
|
||||
def __init__(self):
|
||||
log.debug("Initialized", __name__)
|
||||
|
||||
common.encodings[common.ENCODINGS.cursor] = Encoding
|
||||
log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))
|
||||
|
||||
@@ -17,16 +17,30 @@
|
||||
|
||||
from . import common
|
||||
from struct import *
|
||||
from lib import log
|
||||
|
||||
def send_image(x, y, w, h, image):
|
||||
_buff = bytearray()
|
||||
rectangles = 1
|
||||
_buff.extend(pack("!BxH", 0, rectangles))
|
||||
_buff.extend(pack("!HHHH", x, y, w, h))
|
||||
_buff.extend(pack(">i", common.ENCODINGS.raw))
|
||||
_buff.extend( image.tobytes() )
|
||||
class Encoding:
|
||||
_buff = None
|
||||
|
||||
return _buff
|
||||
name = 'raw'
|
||||
id = 0
|
||||
description = 'Raw VNC encoding'
|
||||
enabled = True
|
||||
firstUpdateSent = False
|
||||
|
||||
common.ENCODINGS.raw = 0
|
||||
common.ENCODINGS.raw_send_image = send_image
|
||||
def __init__(self):
|
||||
log.debug("Initialized", __name__)
|
||||
|
||||
def send_image(self, x, y, w, h, image):
|
||||
self._buff = bytearray()
|
||||
rectangles = 1
|
||||
self._buff.extend(pack("!BxH", 0, rectangles)) # message type 0 == FramebufferUpdate
|
||||
self._buff.extend(pack("!HHHH", x, y, w, h))
|
||||
self._buff.extend(pack(">i", self.id))
|
||||
self._buff.extend( image.tobytes() )
|
||||
|
||||
return self._buff
|
||||
|
||||
common.encodings[common.ENCODINGS.raw] = Encoding
|
||||
|
||||
log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))
|
||||
|
||||
54
lib/encodings/zlib.py
Normal file
54
lib/encodings/zlib.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from . import common
|
||||
from struct import *
|
||||
from lib import log
|
||||
import zlib
|
||||
|
||||
|
||||
class Encoding:
|
||||
name = 'zlib'
|
||||
id = 6
|
||||
description = 'zlib VNC encoding'
|
||||
enabled = True
|
||||
firstUpdateSent = False
|
||||
_compressObj = None
|
||||
|
||||
def __init__(self):
|
||||
log.debug("Initialized", __name__)
|
||||
self._compressObj = zlib.compressobj(
|
||||
zlib.Z_DEFAULT_COMPRESSION, # level: 0-9
|
||||
zlib.DEFLATED, # method: must be DEFLATED
|
||||
zlib.MAX_WBITS, # window size in bits:
|
||||
# -15..-8: negate, suppress header
|
||||
# 8..15: normal
|
||||
# 16..30: subtract 16, gzip header
|
||||
zlib.DEF_MEM_LEVEL, # mem level: 1..8/9
|
||||
zlib.Z_DEFAULT_STRATEGY # strategy:
|
||||
# 0 = Z_DEFAULT_STRATEGY
|
||||
# 1 = Z_FILTERED
|
||||
# 2 = Z_HUFFMAN_ONLY
|
||||
# 3 = Z_RLE
|
||||
# 4 = Z_FIXED
|
||||
)
|
||||
|
||||
def send_image(self, x, y, w, h, image):
|
||||
sendbuff = bytearray()
|
||||
|
||||
rectangles = 1
|
||||
sendbuff.extend(pack("!BxH", 0, rectangles)) # message type 0 == FramebufferUpdate
|
||||
sendbuff.extend(pack("!HHHH", x, y, w, h))
|
||||
sendbuff.extend(pack(">i", self.id))
|
||||
|
||||
#log.debug("Compressing...")
|
||||
zlibdata = self._compressObj.compress( image.tobytes() )
|
||||
zlibdata += self._compressObj.flush(zlib.Z_FULL_FLUSH)
|
||||
#log.debug("LEN", len(zlibdata))
|
||||
|
||||
l = pack("!I", len(zlibdata) )
|
||||
sendbuff.extend( l ) # send length
|
||||
sendbuff.extend( zlibdata ) # send compressed data
|
||||
|
||||
return sendbuff
|
||||
|
||||
common.encodings[common.ENCODINGS.zlib] = Encoding
|
||||
|
||||
log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))
|
||||
41
lib/imagegrab.py
Normal file
41
lib/imagegrab.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import sys
|
||||
from PIL import Image
|
||||
from lib import log
|
||||
|
||||
if sys.platform == "linux" or sys.platform == "linux2":
|
||||
log.debug("ImageGrab: running on Linux")
|
||||
from Xlib import display, X
|
||||
# take screen images, that's not the best way, so here
|
||||
# we use directly use xlib to take the screenshot.
|
||||
class ImageGrab():
|
||||
def grab():
|
||||
dsp = display.Display()
|
||||
root = dsp.screen().root
|
||||
geom = root.get_geometry()
|
||||
w = geom.width
|
||||
h = geom.height
|
||||
raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff)
|
||||
image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX")
|
||||
return image
|
||||
|
||||
elif sys.platform == "darwin":
|
||||
log.debug("ImageGrab: running on darwin")
|
||||
import Quartz.CoreGraphics as CG
|
||||
class ImageGrab():
|
||||
def grab():
|
||||
screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault)
|
||||
width = CG.CGImageGetWidth(screenshot)
|
||||
height = CG.CGImageGetHeight(screenshot)
|
||||
bytesperrow = CG.CGImageGetBytesPerRow(screenshot)
|
||||
|
||||
pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot))
|
||||
|
||||
i = Image.frombytes("RGBA", (width, height), pixeldata)
|
||||
(b, g, r, x) = i.split()
|
||||
i = Image.merge("RGBX", (r, g, b, x))
|
||||
|
||||
return i
|
||||
|
||||
else:
|
||||
log.debug("ImageGrab: running on Unknown!")
|
||||
from PIL import ImageGrab
|
||||
47
lib/kbdctrl.py
Normal file
47
lib/kbdctrl.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import sys
|
||||
from struct import pack, unpack
|
||||
from pynput import keyboard
|
||||
from lib import log
|
||||
from lib.kbdmap import *
|
||||
|
||||
class KeyboardController:
|
||||
kbdmap = kbdmap
|
||||
kbdkey = ''
|
||||
downflag = None
|
||||
key = None
|
||||
controller = None
|
||||
kbd = None
|
||||
|
||||
def __init__(self):
|
||||
self.kbd = keyboard
|
||||
self.controller = self.kbd.Controller()
|
||||
|
||||
def process_event(self, data):
|
||||
# B = U8, L = U32
|
||||
(self.downflag, self.key) = unpack("!BxxL", data)
|
||||
log.debug("KeyEvent", self.downflag, hex(self.key))
|
||||
|
||||
# special key
|
||||
if self.key in self.kbdmap:
|
||||
self.kbdkey = self.kbdmap[self.key]
|
||||
log.debug("SPECIAL KEY", self.kbdkey)
|
||||
else: # normal key
|
||||
try:
|
||||
self.kbdkey = self.kbd.KeyCode.from_char(chr(self.key))
|
||||
except:
|
||||
self.kbdkey = None
|
||||
|
||||
# debug keypress to stdout
|
||||
try:
|
||||
log.debug("KEY:", self.kbdkey)
|
||||
except:
|
||||
log.debug("KEY: (unprintable)")
|
||||
|
||||
# send the actual keyboard event
|
||||
try:
|
||||
if self.downflag:
|
||||
self.controller.press(self.kbdkey)
|
||||
else:
|
||||
self.controller.release(self.kbdkey)
|
||||
except:
|
||||
log.debug("Error sending key")
|
||||
79
lib/kbdmap.py
Normal file
79
lib/kbdmap.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import sys
|
||||
from pynput import keyboard
|
||||
|
||||
__all__ = ['kbdmap']
|
||||
|
||||
kbdmap = {
|
||||
0xff08: keyboard.Key.backspace,
|
||||
0xff09: keyboard.Key.tab,
|
||||
0xff0d: keyboard.Key.enter,
|
||||
0xff1b: keyboard.Key.esc,
|
||||
0xff63: keyboard.Key.insert if hasattr(keyboard.Key, "insert") else None,
|
||||
0xffff: keyboard.Key.delete,
|
||||
0xff50: keyboard.Key.home,
|
||||
0xff57: keyboard.Key.end,
|
||||
0xff55: keyboard.Key.page_up,
|
||||
0xff56: keyboard.Key.page_down,
|
||||
0xff51: keyboard.Key.left,
|
||||
0xff52: keyboard.Key.up,
|
||||
0xff53: keyboard.Key.right,
|
||||
0xff54: keyboard.Key.down,
|
||||
0xffbe: keyboard.Key.f1,
|
||||
0xffbf: keyboard.Key.f2,
|
||||
0xffc0: keyboard.Key.f3,
|
||||
0xffc1: keyboard.Key.f4,
|
||||
0xffc2: keyboard.Key.f5,
|
||||
0xffc3: keyboard.Key.f6,
|
||||
0xffc4: keyboard.Key.f7,
|
||||
0xffc5: keyboard.Key.f8,
|
||||
0xffc6: keyboard.Key.f9,
|
||||
0xffc7: keyboard.Key.f10,
|
||||
0xffc8: keyboard.Key.f11,
|
||||
0xffc9: keyboard.Key.f12,
|
||||
0xffca: keyboard.Key.f13,
|
||||
0xffcb: keyboard.Key.f14,
|
||||
0xffcc: keyboard.Key.f15,
|
||||
0xffcd: keyboard.Key.f16,
|
||||
0xffce: keyboard.Key.f17,
|
||||
0xffcf: keyboard.Key.f18,
|
||||
0xffd0: keyboard.Key.f19,
|
||||
0xffd1: keyboard.Key.f20,
|
||||
0xffe1: keyboard.Key.shift_l,
|
||||
0xffe2: keyboard.Key.shift_r,
|
||||
0xffe3: keyboard.Key.ctrl_l,
|
||||
0xffe4: keyboard.Key.ctrl_r,
|
||||
0xffe7: None, # "KEY_MetaLeft"
|
||||
0xffe8: None, # "KEY_MetaRight"
|
||||
#0xffe9: keyboard.Key.cmd_l,
|
||||
0xffe9: keyboard.Key.alt,
|
||||
0xffea: keyboard.Key.alt_gr, # "KEY_AltRight"
|
||||
0xff14: keyboard.Key.scroll_lock if hasattr(keyboard.Key, "scroll_lock") else None,
|
||||
0xff15: keyboard.Key.print_screen if hasattr(keyboard.Key, "print_screen") else None, # "KEY_Sys_Req"
|
||||
0xff7f: keyboard.Key.num_lock if hasattr(keyboard.Key, "num_lock") else None,
|
||||
0xffe5: keyboard.Key.caps_lock,
|
||||
0xff13: keyboard.Key.pause if hasattr(keyboard.Key, "pause") else None,
|
||||
0xffeb: keyboard.Key.cmd_r, # "KEY_Super_L"
|
||||
0xffec: keyboard.Key.cmd_r, # "KEY_Super_R"
|
||||
0xffed: None, # "KEY_Hyper_L"
|
||||
0xffee: None, # "KEY_Hyper_R"
|
||||
0xffb0: None, # "KEY_KP_0"
|
||||
0xffb1: None, # "KEY_KP_1"
|
||||
0xffb2: None, # "KEY_KP_2"
|
||||
0xffb3: None, # "KEY_KP_3"
|
||||
0xffb4: None, # "KEY_KP_4"
|
||||
0xffb5: None, # "KEY_KP_5"
|
||||
0xffb6: None, # "KEY_KP_6"
|
||||
0xffb7: None, # "KEY_KP_7"
|
||||
0xffb8: None, # "KEY_KP_8"
|
||||
0xffb9: None, # "KEY_KP_9"
|
||||
0xff8d: None, # "KEY_KP_Enter"
|
||||
0x002f: "/", # KEY_ForwardSlash
|
||||
0x005c: "\\", # KEY_BackSlash
|
||||
0x0020: keyboard.Key.space, # "KEY_SpaceBar"
|
||||
0xff7e: keyboard.Key.alt_gr, # altgr, at least on a mac (?)
|
||||
#0xfe03: keyboard.Key.alt_l,
|
||||
0xfe03: keyboard.Key.cmd_l,
|
||||
}
|
||||
|
||||
if sys.platform == "darwin":
|
||||
kbdmap[0xffe2] = keyboard.Key.shift
|
||||
60
lib/mousectrl.py
Normal file
60
lib/mousectrl.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from struct import pack, unpack
|
||||
from pynput import mouse
|
||||
from lib import log
|
||||
|
||||
class MouseController():
|
||||
def __init__(self):
|
||||
self.buttonmask = 0
|
||||
self.buttons = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
self.left_pressed = 0
|
||||
self.right_pressed = 0
|
||||
self.middle_pressed = 0
|
||||
|
||||
def process_event(self, data):
|
||||
(self.buttonmask, x, y) = unpack("!BHH", data)
|
||||
self.buttons[0] = self.buttonmask & int("0000001", 2) # left button
|
||||
self.buttons[1] = self.buttonmask & int("0000010", 2) # middle button
|
||||
self.buttons[2] = self.buttonmask & int("0000100", 2) # right button
|
||||
self.buttons[3] = self.buttonmask & int("0001000", 2) # scroll up
|
||||
self.buttons[4] = self.buttonmask & int("0010000", 2) # scroll down
|
||||
|
||||
# set mouse position
|
||||
mouse.Controller().position = (x, y)
|
||||
|
||||
# process mouse button events
|
||||
if self.buttons[0] and not self.left_pressed:
|
||||
log.debug("LEFT PRESSED")
|
||||
mouse.Controller().press(mouse.Button.left)
|
||||
self.left_pressed = 1
|
||||
elif not self.buttons[0] and self.left_pressed:
|
||||
log.debug("LEFT RELEASED")
|
||||
mouse.Controller().release(mouse.Button.left)
|
||||
self.left_pressed = 0
|
||||
|
||||
if self.buttons[1] and not self.middle_pressed:
|
||||
log.debug("MIDDLE PRESSED")
|
||||
mouse.Controller().press(mouse.Button.middle)
|
||||
self.middle_pressed = 1
|
||||
elif not self.buttons[1] and self.middle_pressed:
|
||||
log.debug("MIDDLE RELEASED")
|
||||
mouse.Controller().release(mouse.Button.middle)
|
||||
self.middle_pressed = 0
|
||||
|
||||
if self.buttons[2] and not self.right_pressed:
|
||||
log.debug("RIGHT PRESSED")
|
||||
mouse.Controller().press(mouse.Button.right)
|
||||
self.right_pressed = 1
|
||||
elif not self.buttons[2] and self.right_pressed:
|
||||
log.debug("RIGHT RELEASED")
|
||||
mouse.Controller().release(mouse.Button.right)
|
||||
self.right_pressed = 0
|
||||
|
||||
if self.buttons[3]:
|
||||
log.debug("SCROLLUP PRESSED")
|
||||
mouse.Controller().scroll(0, 2)
|
||||
|
||||
if self.buttons[4]:
|
||||
log.debug("SCROLLDOWN PRESSED")
|
||||
mouse.Controller().scroll(0, -2)
|
||||
|
||||
#log.debug("PointerEvent", buttonmask, x, y)
|
||||
31
lib/oshelpers/windows.py
Normal file
31
lib/oshelpers/windows.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import ctypes
|
||||
import sys
|
||||
from elevate import elevate
|
||||
|
||||
def is_admin():
|
||||
try:
|
||||
return ctypes.windll.shell32.IsUserAnAdmin()
|
||||
except:
|
||||
return False
|
||||
|
||||
def run_as_admin_old(argv=None):
|
||||
shell32 = ctypes.windll.shell32
|
||||
if argv is None and shell32.IsUserAnAdmin():
|
||||
return True
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
if hasattr(sys, '_MEIPASS'):
|
||||
# Support pyinstaller wrapped program.
|
||||
arguments = argv[1:]
|
||||
else:
|
||||
arguments = argv
|
||||
argument_line = u' '.join(arguments)
|
||||
executable = sys.executable
|
||||
ret = shell32.ShellExecuteW(None, u"runas", executable, argument_line, None, 1)
|
||||
if int(ret) <= 32:
|
||||
return False
|
||||
return None
|
||||
|
||||
def run_as_admin():
|
||||
elevate()
|
||||
Binary file not shown.
461
pyvncs/server.py
461
pyvncs/server.py
@@ -19,17 +19,24 @@ from struct import *
|
||||
from pyDes import *
|
||||
from time import sleep
|
||||
from pynput import mouse, keyboard
|
||||
from PIL import Image, ImageChops, ImageDraw, ImagePalette
|
||||
|
||||
import socket
|
||||
import select
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
import zlib
|
||||
import numpy as np
|
||||
|
||||
from lib.encodings import *
|
||||
from lib import mousectrl
|
||||
from lib import kbdctrl
|
||||
from lib.imagegrab import ImageGrab
|
||||
from lib import log
|
||||
from lib import bgr233_palette
|
||||
|
||||
# encodings support
|
||||
import lib.encodings as encs
|
||||
from lib.encodings.common import ENCODINGS
|
||||
|
||||
def hexdump(data):
|
||||
str = ""
|
||||
@@ -39,7 +46,7 @@ def hexdump(data):
|
||||
return str
|
||||
|
||||
def quantizetopalette(silf, palette, dither=False):
|
||||
"""Convert an RGB or L mode image to use a given P image's palette."""
|
||||
"""Converts an RGB or L mode image to use a given P image's palette."""
|
||||
|
||||
silf.load()
|
||||
|
||||
@@ -60,50 +67,13 @@ def quantizetopalette(silf, palette, dither=False):
|
||||
except AttributeError:
|
||||
return silf._makeself(im)
|
||||
|
||||
|
||||
from PIL import Image, ImageChops, ImageDraw, ImagePalette
|
||||
if sys.platform == "linux" or sys.platform == "linux2":
|
||||
from Xlib import display, X
|
||||
# take screen images, that's not the best way, so here
|
||||
# we use directly use xlib to take the screenshot.
|
||||
class ImageGrab():
|
||||
def grab():
|
||||
dsp = display.Display()
|
||||
root = dsp.screen().root
|
||||
geom = root.get_geometry()
|
||||
w = geom.width
|
||||
h = geom.height
|
||||
raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff)
|
||||
image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX")
|
||||
return image
|
||||
|
||||
elif sys.platform == "darwin":
|
||||
import Quartz.CoreGraphics as CG
|
||||
class ImageGrab():
|
||||
def grab():
|
||||
screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault)
|
||||
width = CG.CGImageGetWidth(screenshot)
|
||||
height = CG.CGImageGetHeight(screenshot)
|
||||
bytesperrow = CG.CGImageGetBytesPerRow(screenshot)
|
||||
|
||||
pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot))
|
||||
|
||||
i = Image.frombytes("RGBA", (width, height), pixeldata)
|
||||
(b, g, r, x) = i.split()
|
||||
i = Image.merge("RGBX", (r, g, b, x))
|
||||
|
||||
return i
|
||||
|
||||
else:
|
||||
from PIL import ImageGrab
|
||||
|
||||
|
||||
|
||||
class VncServer():
|
||||
|
||||
class CONFIG:
|
||||
_8bitdither = False
|
||||
|
||||
encoding_object = None
|
||||
|
||||
def __init__(self, socket, password):
|
||||
self.RFB_VERSION = '003.008'
|
||||
self.RFB_SECTYPES = [
|
||||
@@ -115,72 +85,7 @@ class VncServer():
|
||||
self.framebuffer = None
|
||||
self.password = password
|
||||
self.sectypes = self.RFB_SECTYPES
|
||||
self.remotecursor = False
|
||||
|
||||
self.BGR233 = [0, 0, 0, 0, 0, 85, 0, 0, 170, 0, 0, 255, 36, 0, 0,
|
||||
36, 0, 85, 36, 0, 170, 36, 0, 255, 73, 0, 0, 73, 0,
|
||||
85, 73, 0, 170, 73, 0, 255, 109, 0, 0, 109, 0, 85,
|
||||
109, 0, 170, 109, 0, 255, 146, 0, 0, 146, 0, 85, 146,
|
||||
0, 170, 146, 0, 255, 182, 0, 0, 182, 0, 85, 182, 0,
|
||||
170, 182, 0, 255, 219, 0, 0, 219, 0, 85, 219, 0, 170,
|
||||
219, 0, 255, 255, 0, 0, 255, 0, 85, 255, 0, 170, 255,
|
||||
0, 255, 0, 36, 0, 0, 36, 85, 0, 36, 170, 0, 36, 255,
|
||||
36, 36, 0, 36, 36, 85, 36, 36, 170, 36, 36, 255, 73,
|
||||
36, 0, 73, 36, 85, 73, 36, 170, 73, 36, 255, 109, 36,
|
||||
0, 109, 36, 85, 109, 36, 170, 109, 36, 255, 146, 36,
|
||||
0, 146, 36, 85, 146, 36, 170, 146, 36, 255, 182, 36,
|
||||
0, 182, 36, 85, 182, 36, 170, 182, 36, 255, 219, 36,
|
||||
0, 219, 36, 85, 219, 36, 170, 219, 36, 255, 255, 36,
|
||||
0, 255, 36, 85, 255, 36, 170, 255, 36, 255, 0, 73, 0,
|
||||
0, 73, 85, 0, 73, 170, 0, 73, 255, 36, 73, 0, 36, 73,
|
||||
85, 36, 73, 170, 36, 73, 255, 73, 73, 0, 73, 73, 85,
|
||||
73, 73, 170, 73, 73, 255, 109, 73, 0, 109, 73, 85,
|
||||
109, 73, 170, 109, 73, 255, 146, 73, 0, 146, 73, 85,
|
||||
146, 73, 170, 146, 73, 255, 182, 73, 0, 182, 73, 85,
|
||||
182, 73, 170, 182, 73, 255, 219, 73, 0, 219, 73, 85,
|
||||
219, 73, 170, 219, 73, 255, 255, 73, 0, 255, 73, 85,
|
||||
255, 73, 170, 255, 73, 255, 0, 109, 0, 0, 109, 85, 0,
|
||||
109, 170, 0, 109, 255, 36, 109, 0, 36, 109, 85, 36,
|
||||
109, 170, 36, 109, 255, 73, 109, 0, 73, 109, 85, 73,
|
||||
109, 170, 73, 109, 255, 109, 109, 0, 109, 109, 85, 109,
|
||||
109, 170, 109, 109, 255, 146, 109, 0, 146, 109, 85,
|
||||
146, 109, 170, 146, 109, 255, 182, 109, 0, 182, 109,
|
||||
85, 182, 109, 170, 182, 109, 255, 219, 109, 0, 219,
|
||||
109, 85, 219, 109, 170, 219, 109, 255, 255, 109, 0,
|
||||
255, 109, 85, 255, 109, 170, 255, 109, 255, 0, 146, 0,
|
||||
0, 146, 85, 0, 146, 170, 0, 146, 255, 36, 146, 0, 36,
|
||||
146, 85, 36, 146, 170, 36, 146, 255, 73, 146, 0, 73,
|
||||
146, 85, 73, 146, 170, 73, 146, 255, 109, 146, 0, 109,
|
||||
146, 85, 109, 146, 170, 109, 146, 255, 146, 146, 0, 146,
|
||||
146, 85, 146, 146, 170, 146, 146, 255, 182, 146, 0, 182,
|
||||
146, 85, 182, 146, 170, 182, 146, 255, 219, 146, 0, 219,
|
||||
146, 85, 219, 146, 170, 219, 146, 255, 255, 146, 0, 255,
|
||||
146, 85, 255, 146, 170, 255, 146, 255, 0, 182, 0, 0,
|
||||
182, 85, 0, 182, 170, 0, 182, 255, 36, 182, 0, 36, 182,
|
||||
85, 36, 182, 170, 36, 182, 255, 73, 182, 0, 73, 182,
|
||||
85, 73, 182, 170, 73, 182, 255, 109, 182, 0, 109, 182,
|
||||
85, 109, 182, 170, 109, 182, 255, 146, 182, 0, 146,
|
||||
182, 85, 146, 182, 170, 146, 182, 255, 182, 182, 0, 182,
|
||||
182, 85, 182, 182, 170, 182, 182, 255, 219, 182, 0, 219,
|
||||
182, 85, 219, 182, 170, 219, 182, 255, 255, 182, 0, 255,
|
||||
182, 85, 255, 182, 170, 255, 182, 255, 0, 219, 0, 20,
|
||||
219, 85, 0, 219, 170, 0, 219, 255, 36, 219, 0, 36, 219,
|
||||
85, 36, 219, 170, 36, 219, 255, 73, 219, 0, 73, 219,
|
||||
85, 73, 219, 170, 73, 219, 255, 109, 219, 0, 109, 219,
|
||||
85, 109, 219, 170, 109, 219, 255, 146, 219, 0, 146, 219,
|
||||
85, 146, 219, 170, 146, 219, 255, 182, 219, 0, 182, 219,
|
||||
85, 182, 219, 170, 182, 219, 255, 219, 219, 0, 219, 219,
|
||||
85, 219, 219, 170, 219, 219, 255, 255, 219, 0, 255, 219,
|
||||
85, 255, 219, 170, 255, 219, 255, 0, 255, 0, 0, 255, 85,
|
||||
0, 255, 170, 0, 255, 255, 36, 255, 0, 36, 255, 85, 36,
|
||||
255, 170, 36, 255, 255, 73, 255, 0, 73, 255, 85, 73,
|
||||
255, 170, 73, 255, 255, 109, 255, 0, 109, 255, 85, 109,
|
||||
255, 170, 109, 255, 255, 146, 255, 0, 146, 255, 85,
|
||||
146, 255, 170, 146, 255, 255, 182, 255, 0, 182, 255, 85,
|
||||
182, 255, 170, 182, 255, 255, 219, 255, 0, 219, 255, 85,
|
||||
219, 255, 170, 219, 255, 255, 255, 255, 0, 255, 255, 85,
|
||||
255, 255, 170, 255, 255, 255]
|
||||
|
||||
self.cursor_support = False
|
||||
|
||||
def __del__(self):
|
||||
log.debug("VncServer died")
|
||||
@@ -348,94 +253,18 @@ class VncServer():
|
||||
|
||||
def protocol(self):
|
||||
self.socket.settimeout(None) # set nonblocking socket
|
||||
|
||||
screen = ImageGrab.grab()
|
||||
size = screen.size
|
||||
width = size[0]
|
||||
height = size[1]
|
||||
del screen
|
||||
|
||||
mousecontroller = mousectrl.MouseController()
|
||||
kbdcontroller = kbdctrl.KeyboardController()
|
||||
|
||||
self.primaryOrder = "rgb"
|
||||
self.encoding = enc.ENCODINGS.raw
|
||||
buttonmask = 0
|
||||
buttons = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
left_pressed = 0
|
||||
right_pressed = 0
|
||||
middle_pressed = 0
|
||||
|
||||
|
||||
kbdmap = {
|
||||
0xff08: keyboard.Key.backspace,
|
||||
0xff09: keyboard.Key.tab,
|
||||
0xff0d: keyboard.Key.enter,
|
||||
0xff1b: keyboard.Key.esc,
|
||||
0xff63: keyboard.Key.insert if hasattr(keyboard.Key, "insert") else None,
|
||||
0xffff: keyboard.Key.delete,
|
||||
0xff50: keyboard.Key.home,
|
||||
0xff57: keyboard.Key.end,
|
||||
0xff55: keyboard.Key.page_up,
|
||||
0xff56: keyboard.Key.page_down,
|
||||
0xff51: keyboard.Key.left,
|
||||
0xff52: keyboard.Key.up,
|
||||
0xff53: keyboard.Key.right,
|
||||
0xff54: keyboard.Key.down,
|
||||
0xffbe: keyboard.Key.f1,
|
||||
0xffbf: keyboard.Key.f2,
|
||||
0xffc0: keyboard.Key.f3,
|
||||
0xffc1: keyboard.Key.f4,
|
||||
0xffc2: keyboard.Key.f5,
|
||||
0xffc3: keyboard.Key.f6,
|
||||
0xffc4: keyboard.Key.f7,
|
||||
0xffc5: keyboard.Key.f8,
|
||||
0xffc6: keyboard.Key.f9,
|
||||
0xffc7: keyboard.Key.f10,
|
||||
0xffc8: keyboard.Key.f11,
|
||||
0xffc9: keyboard.Key.f12,
|
||||
0xffca: keyboard.Key.f13,
|
||||
0xffcb: keyboard.Key.f14,
|
||||
0xffcc: keyboard.Key.f15,
|
||||
0xffcd: keyboard.Key.f16,
|
||||
0xffce: keyboard.Key.f17,
|
||||
0xffcf: keyboard.Key.f18,
|
||||
0xffd0: keyboard.Key.f19,
|
||||
0xffd1: keyboard.Key.f20,
|
||||
0xffe1: keyboard.Key.shift_l,
|
||||
0xffe2: keyboard.Key.shift_r,
|
||||
0xffe3: keyboard.Key.ctrl_l,
|
||||
0xffe4: keyboard.Key.ctrl_r,
|
||||
0xffe7: None, # "KEY_MetaLeft"
|
||||
0xffe8: None, # "KEY_MetaRight"
|
||||
0xffe9: keyboard.Key.cmd_l,
|
||||
0xffea: keyboard.Key.alt_gr, # "KEY_AltRight"
|
||||
0xff14: keyboard.Key.scroll_lock if hasattr(keyboard.Key, "scroll_lock") else None,
|
||||
0xff15: keyboard.Key.print_screen if hasattr(keyboard.Key, "print_screen") else None, # "KEY_Sys_Req"
|
||||
0xff7f: keyboard.Key.num_lock if hasattr(keyboard.Key, "num_lock") else None,
|
||||
0xffe5: keyboard.Key.caps_lock,
|
||||
0xff13: keyboard.Key.pause if hasattr(keyboard.Key, "pause") else None,
|
||||
0xffeb: keyboard.Key.cmd_r, # "KEY_Super_L"
|
||||
0xffec: keyboard.Key.cmd_r, # "KEY_Super_R"
|
||||
0xffed: None, # "KEY_Hyper_L"
|
||||
0xffee: None, # "KEY_Hyper_R"
|
||||
0xffb0: None, # "KEY_KP_0"
|
||||
0xffb1: None, # "KEY_KP_1"
|
||||
0xffb2: None, # "KEY_KP_2"
|
||||
0xffb3: None, # "KEY_KP_3"
|
||||
0xffb4: None, # "KEY_KP_4"
|
||||
0xffb5: None, # "KEY_KP_5"
|
||||
0xffb6: None, # "KEY_KP_6"
|
||||
0xffb7: None, # "KEY_KP_7"
|
||||
0xffb8: None, # "KEY_KP_8"
|
||||
0xffb9: None, # "KEY_KP_9"
|
||||
0xff8d: None, # "KEY_KP_Enter"
|
||||
0x002f: "/", # KEY_ForwardSlash
|
||||
0x005c: "\\", # KEY_BackSlash
|
||||
0x0020: keyboard.Key.space, # "KEY_SpaceBar"
|
||||
0xff7e: keyboard.Key.alt_gr, # altgr, at least on a mac (?)
|
||||
0xfe03: keyboard.Key.alt_l,
|
||||
}
|
||||
|
||||
if sys.platform == "darwin":
|
||||
kbdmap[0xffe2] = keyboard.Key.shift
|
||||
self.encoding = ENCODINGS.raw
|
||||
self.encoding_object = encs.common.encodings[self.encoding]()
|
||||
|
||||
while True:
|
||||
#log.debug(".", end='', flush=True)
|
||||
@@ -476,7 +305,7 @@ class VncServer():
|
||||
self.primaryOrder = "rgb"
|
||||
else:
|
||||
self.primaryOrder = "bgr"
|
||||
log.debug("Using order: ", self.primaryOrder)
|
||||
log.debug("Using order:", self.primaryOrder)
|
||||
|
||||
continue
|
||||
|
||||
@@ -488,16 +317,25 @@ class VncServer():
|
||||
data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL)
|
||||
#log.debug("len", len(data2))
|
||||
self.client_encodings = unpack("!%si" % nencodings, data2)
|
||||
#log.debug("data", repr(self.client_encodings), len(self.client_encodings))
|
||||
log.debug("client_encodings", repr(self.client_encodings), len(self.client_encodings))
|
||||
|
||||
if hasattr(enc.ENCODINGS, "cursor") and enc.ENCODINGS.cursor in self.client_encodings:
|
||||
log.debug("Remote cursor encoding present")
|
||||
self.remotecursor = True
|
||||
self.cursorchanged = True
|
||||
# cursor support?
|
||||
if ENCODINGS.cursor in self.client_encodings:
|
||||
log.debug("client cursor support")
|
||||
self.cursor_support = True
|
||||
|
||||
if hasattr(enc.ENCODINGS, "zlib") and enc.ENCODINGS.zlib in self.client_encodings:
|
||||
log.debug("Using zlib encoding")
|
||||
self.encoding = enc.ENCODINGS.zlib
|
||||
# which pixel encoding to use?
|
||||
log.debug("encs.common.encodings_priority", encs.common.encodings_priority)
|
||||
for e in encs.common.encodings_priority:
|
||||
log.debug("E", e)
|
||||
if e in self.client_encodings:
|
||||
if self.encoding == e:
|
||||
# don't initialize same encoding again
|
||||
break
|
||||
self.encoding = e
|
||||
log.debug("Using %s encoding" % self.encoding)
|
||||
self.encoding_object = encs.common.encodings[self.encoding]()
|
||||
break
|
||||
|
||||
continue
|
||||
|
||||
@@ -510,89 +348,14 @@ class VncServer():
|
||||
#log.debug("RFBU:", incremental, x, y, w, h)
|
||||
self.SendRectangles(sock, x, y, w, h, incremental)
|
||||
|
||||
if self.remotecursor and self.cursorchanged:
|
||||
# FIXME: send cursor to remote client
|
||||
self.cursorchanged = False
|
||||
continue
|
||||
|
||||
if data[0] == 4:
|
||||
kbdkey = ''
|
||||
data2 = sock.recv(7)
|
||||
# B = U8, L = U32
|
||||
(downflag, key) = unpack("!BxxL", data2)
|
||||
log.debug("KeyEvent", downflag, hex(key))
|
||||
|
||||
# special key
|
||||
if key in kbdmap:
|
||||
kbdkey = kbdmap[key]
|
||||
else: # normal key
|
||||
try:
|
||||
kbdkey = keyboard.KeyCode.from_char(chr(key))
|
||||
except:
|
||||
kbdkey = None
|
||||
|
||||
try:
|
||||
log.debug("KEY:", kbdkey)
|
||||
except:
|
||||
log.debug("KEY: (unprintable)")
|
||||
|
||||
try:
|
||||
if downflag:
|
||||
keyboard.Controller().press(kbdkey)
|
||||
else:
|
||||
keyboard.Controller().release(kbdkey)
|
||||
except:
|
||||
log.debug("Error sending key")
|
||||
|
||||
if data[0] == 4: # keyboard event
|
||||
kbdcontroller.process_event(sock.recv(7))
|
||||
continue
|
||||
|
||||
if data[0] == 5: # PointerEvent
|
||||
data2 = sock.recv(5, socket.MSG_WAITALL)
|
||||
(buttonmask, x, y) = unpack("!BHH", data2)
|
||||
buttons[0] = buttonmask & int("0000001", 2) # left button
|
||||
buttons[1] = buttonmask & int("0000010", 2) # middle button
|
||||
buttons[2] = buttonmask & int("0000100", 2) # right button
|
||||
buttons[3] = buttonmask & int("0001000", 2) # scroll up
|
||||
buttons[4] = buttonmask & int("0010000", 2) # scroll down
|
||||
|
||||
mouse.Controller().position = (x, y)
|
||||
|
||||
if buttons[0] and not left_pressed:
|
||||
log.debug("LEFT PRESSED")
|
||||
mouse.Controller().press(mouse.Button.left)
|
||||
left_pressed = 1
|
||||
elif not buttons[0] and left_pressed:
|
||||
log.debug("LEFT RELEASED")
|
||||
mouse.Controller().release(mouse.Button.left)
|
||||
left_pressed = 0
|
||||
|
||||
if buttons[1] and not middle_pressed:
|
||||
log.debug("MIDDLE PRESSED")
|
||||
mouse.Controller().press(mouse.Button.middle)
|
||||
middle_pressed = 1
|
||||
elif not buttons[1] and middle_pressed:
|
||||
log.debug("MIDDLE RELEASED")
|
||||
mouse.Controller().release(mouse.Button.middle)
|
||||
middle_pressed = 0
|
||||
|
||||
if buttons[2] and not right_pressed:
|
||||
log.debug("RIGHT PRESSED")
|
||||
mouse.Controller().press(mouse.Button.right)
|
||||
right_pressed = 1
|
||||
elif not buttons[2] and right_pressed:
|
||||
log.debug("RIGHT RELEASED")
|
||||
mouse.Controller().release(mouse.Button.right)
|
||||
right_pressed = 0
|
||||
|
||||
if buttons[3]:
|
||||
log.debug("SCROLLUP PRESSED")
|
||||
mouse.Controller().scroll(0, 2)
|
||||
|
||||
if buttons[4]:
|
||||
log.debug("SCROLLDOWN PRESSED")
|
||||
mouse.Controller().scroll(0, -2)
|
||||
|
||||
#log.debug("PointerEvent", buttonmask, x, y)
|
||||
mousecontroller.process_event(sock.recv(5, socket.MSG_WAITALL))
|
||||
continue
|
||||
|
||||
else:
|
||||
@@ -630,19 +393,20 @@ class VncServer():
|
||||
lastshot = rectangle
|
||||
sendbuff = bytearray()
|
||||
|
||||
firstUpdateSent = False
|
||||
self.encoding_object.firstUpdateSent = False
|
||||
|
||||
# try to send only the actual changes
|
||||
if self.framebuffer != None and incremental == 1:
|
||||
diff = ImageChops.difference(rectangle, self.framebuffer)
|
||||
if diff.getbbox() is None:
|
||||
# no changes...
|
||||
rectangles = 0
|
||||
sendbuff.extend(pack("!BxH", 0, rectangles))
|
||||
try:
|
||||
sock.sendall(sendbuff)
|
||||
except:
|
||||
return False
|
||||
sleep(0.3)
|
||||
sleep(0.1)
|
||||
return
|
||||
|
||||
if diff.getbbox() is not None:
|
||||
@@ -656,119 +420,70 @@ class VncServer():
|
||||
stimeout = sock.gettimeout()
|
||||
sock.settimeout(None)
|
||||
|
||||
if self.bpp == 32 or self.bpp == 8:
|
||||
if rectangle.mode is not "RGB":
|
||||
image = rectangle.convert("RGB")
|
||||
else:
|
||||
image = rectangle
|
||||
|
||||
b = np.asarray(image)
|
||||
a = b.copy()
|
||||
del b
|
||||
if self.bpp == 32 or self.bpp == 16 or self.bpp == 8:
|
||||
|
||||
if self.bpp == 32:
|
||||
redBits = 8
|
||||
greenBits = 8
|
||||
blueBits = 8
|
||||
elif self.bpp == 8:
|
||||
redBits = 4
|
||||
greenBits = 4
|
||||
blueBits = 4
|
||||
|
||||
#redMask = ((1 << redBits) - 1) << self.red_shift
|
||||
#greenMask = ((1 << greenBits) - 1) << self.green_shift
|
||||
#blueMask = ((1 << blueBits) - 1) << self.blue_shift
|
||||
#log.debug("redMask", redMask, greenMask, blueMask)
|
||||
# image array
|
||||
a = np.asarray(rectangle).copy()
|
||||
|
||||
if self.primaryOrder == "bgr":
|
||||
self.blue_shift = 0
|
||||
blueMask = (1 << blueBits) - 1
|
||||
self.green_shift = blueBits
|
||||
greenMask = ((1 << greenBits) - 1) << self.green_shift
|
||||
self.red_shift = self.green_shift + greenBits
|
||||
redMask = ((1 << redBits) - 1) << self.red_shift
|
||||
if self.primaryOrder == "bgr": # bit shifting
|
||||
blueMask = (1 << blueBits) - 1
|
||||
greenMask = ((1 << greenBits) - 1) << self.green_shift
|
||||
redMask = ((1 << redBits) - 1) << self.red_shift
|
||||
|
||||
else: # RGB
|
||||
self.red_shift = 0
|
||||
redMask = (1 << redBits) - 1
|
||||
self.green_shift = redBits
|
||||
greenMask = ((1 << greenBits) - 1) << self.green_shift
|
||||
self.blue_shift = self.green_shift + greenBits
|
||||
blueMask = ((1 << blueBits) - 1) << self.blue_shift
|
||||
a[..., 0] = ( a[..., 0] ) & blueMask >> self.blue_shift
|
||||
a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift
|
||||
a[..., 2] = ( a[..., 2] ) & redMask >> self.red_shift
|
||||
|
||||
a[..., 0] = ( a[..., 0] ) & redMask >> self.red_shift
|
||||
a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift
|
||||
a[..., 2] = ( a[..., 2] ) & blueMask >> self.blue_shift
|
||||
else: # RGB
|
||||
redMask = ((1 << redBits) - 1) << self.red_shift
|
||||
greenMask = ((1 << greenBits) - 1) << self.green_shift
|
||||
blueMask = ((1 << blueBits) - 1) << self.blue_shift
|
||||
a[..., 0] = ( a[..., 0] ) & redMask >> self.red_shift
|
||||
a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift
|
||||
a[..., 2] = ( a[..., 2] ) & blueMask >> self.blue_shift
|
||||
|
||||
image = Image.fromarray(a)
|
||||
del a
|
||||
|
||||
if self.primaryOrder == "rgb":
|
||||
(b, g, r) = image.split()
|
||||
image = Image.merge("RGB", (r, g, b))
|
||||
del b,g,r
|
||||
|
||||
if self.bpp == 32:
|
||||
image = Image.fromarray(a)
|
||||
if self.primaryOrder == "rgb":
|
||||
(b, g, r) = image.split()
|
||||
image = Image.merge("RGB", (r, g, b))
|
||||
del b,g,r
|
||||
image = image.convert("RGBX")
|
||||
|
||||
elif self.bpp == 8:
|
||||
#FIXME: improve 8 bit routines up!, image looks awful!
|
||||
if rectangle.mode is not "RGB":
|
||||
image = rectangle.convert("RGB")
|
||||
else:
|
||||
image = rectangle
|
||||
if self.bpp == 16: #BGR565
|
||||
greenBits = 5
|
||||
blueBits = 6
|
||||
redBits = 5
|
||||
|
||||
(r, g, b) = image.split()
|
||||
image = Image.merge("RGB", (g, r, b))
|
||||
del b,g,r
|
||||
image = rectangle
|
||||
if self.depth == 16:
|
||||
image = image.convert('BGR;16')
|
||||
if self.depth == 15:
|
||||
image = image.convert('BGR;15')
|
||||
|
||||
elif self.bpp == 8: #bgr233
|
||||
redBits = 3
|
||||
greenBits = 3
|
||||
blueBits = 2
|
||||
|
||||
image = rectangle
|
||||
|
||||
p = Image.new('P',(16,16))
|
||||
p.putpalette(bgr233_palette.palette)
|
||||
|
||||
p = Image.new("P",(16,16))
|
||||
p.putpalette(self.BGR233)
|
||||
image = quantizetopalette(image, p, dither=self.CONFIG._8bitdither)
|
||||
image.putpalette(self.BGR233)
|
||||
del p
|
||||
rectangles = 1
|
||||
sendbuff.extend(pack("!BxH", 0, rectangles))
|
||||
sendbuff.extend(pack("!HHHH", x, y, w, h))
|
||||
sendbuff.extend(pack(">i", self.encoding))
|
||||
sendbuff.extend( image.tobytes() )
|
||||
|
||||
#image = image.convert('RGB', colors=4).quantize(palette=p)
|
||||
#log.debug(image)
|
||||
|
||||
|
||||
if hasattr(enc.ENCODINGS, "zlib") and self.encoding == enc.ENCODINGS.zlib - 9998:
|
||||
if not firstUpdateSent:
|
||||
firstUpdateSent = True
|
||||
compress = zlib.compressobj(
|
||||
zlib.Z_DEFAULT_COMPRESSION, # level: 0-9
|
||||
zlib.DEFLATED, # method: must be DEFLATED
|
||||
-15, # window size in bits:
|
||||
# -15..-8: negate, suppress header
|
||||
# 8..15: normal
|
||||
# 16..30: subtract 16, gzip header
|
||||
1, # mem level: 1..8/9
|
||||
zlib.Z_DEFAULT_STRATEGY # strategy:
|
||||
# 0 = Z_DEFAULT_STRATEGY
|
||||
# 1 = Z_FILTERED
|
||||
# 2 = Z_HUFFMAN_ONLY
|
||||
# 3 = Z_RLE
|
||||
# 4 = Z_FIXED
|
||||
)
|
||||
|
||||
rectangles = 1
|
||||
sendbuff.extend(pack("!BxH", 0, rectangles))
|
||||
sendbuff.extend(pack("!HHHH", x, y, w, h))
|
||||
sendbuff.extend(pack(">i", self.encoding))
|
||||
|
||||
log.debug("Compressing...")
|
||||
zlibdata = compress.compress( image.tobytes() )
|
||||
zlibdata += compress.flush()
|
||||
l = pack("!I", len(zlibdata) )
|
||||
|
||||
sendbuff.extend( l ) # send length
|
||||
sendbuff.extend( zlibdata ) # send compressed data
|
||||
|
||||
else:
|
||||
# send with RAW encoding
|
||||
sendbuff.extend(enc.ENCODINGS.raw_send_image(x, y, w, h, image))
|
||||
# send image with client defined encoding
|
||||
sendbuff.extend(self.encoding_object.send_image(x, y, w, h, image))
|
||||
else:
|
||||
log.debug("[!] Unsupported BPP: %s" % self.bpp)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pydes
|
||||
pynput
|
||||
numpy
|
||||
|
||||
Pillow-PIL
|
||||
elevate
|
||||
|
||||
17
server.py
17
server.py
@@ -10,8 +10,8 @@ import socket
|
||||
import signal
|
||||
from lib import log
|
||||
|
||||
#_debug = log.debug
|
||||
_debug = print
|
||||
_debug = log.debug
|
||||
#_debug = print
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
_debug("Exiting on %s signal..." % signal)
|
||||
@@ -95,6 +95,19 @@ def main(argv):
|
||||
|
||||
_debug("Multithreaded Python server : Waiting for connections from TCP clients...")
|
||||
_debug("Runing on:", sys.platform)
|
||||
if sys.platform in ['win32', 'win64']:
|
||||
from lib.oshelpers import windows as win32
|
||||
if not win32.is_admin():
|
||||
ret = win32.run_as_admin()
|
||||
if ret is None:
|
||||
log.debug("Respawning with admin rights")
|
||||
sys.exit(0)
|
||||
elif ret is True:
|
||||
# admin rights
|
||||
log.debug("Running with admin rights!")
|
||||
else:
|
||||
print('Error(ret=%d): cannot elevate privilege.' % (ret))
|
||||
sys.exit(1)
|
||||
while True:
|
||||
sockServer.listen(4)
|
||||
(conn, (ip,port)) = sockServer.accept()
|
||||
|
||||
Reference in New Issue
Block a user