Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -*- coding: utf-8 -*- 

2# This file is part of Xpra. 

3# Copyright (C) 2017-2018 Antoine Martin <antoine@xpra.org> 

4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any 

5# later version. See the file COPYING for details. 

6 

7import struct 

8from threading import Event 

9 

10from xpra.net.protocol import PACKET_JOIN_SIZE 

11from xpra.os_util import memoryview_to_bytes, strtobytes 

12from xpra.util import AtomicInteger 

13from xpra.log import Logger 

14 

15log = Logger("rfb") 

16 

17counter = AtomicInteger() 

18 

19 

20class RFBSource: 

21 

22 def __init__(self, protocol, share=False): 

23 self.protocol = protocol 

24 self.close_event = Event() 

25 self.log_disconnect = True 

26 self.ui_client = True 

27 self.counter = 0 

28 self.share = share 

29 self.uuid = "RFB%5i" % counter.increase() 

30 self.lock = False 

31 self.keyboard_config = None 

32 

33 def get_info(self) -> dict: 

34 return { 

35 "protocol" : "rfb", 

36 "uuid" : self.uuid, 

37 "share" : self.share, 

38 } 

39 

40 def get_window_info(self, _wids): 

41 return {} 

42 

43 def is_closed(self): 

44 return self.close_event.isSet() 

45 

46 def close(self): 

47 self.close_event.set() 

48 

49 def ping(self): 

50 pass 

51 

52 def keys_changed(self): 

53 pass 

54 

55 def set_default_keymap(self): 

56 log("set_default_keymap() keyboard_config=%s", self.keyboard_config) 

57 if self.keyboard_config: 

58 self.keyboard_config.set_default_keymap() 

59 return self.keyboard_config 

60 

61 def set_keymap(self, _current_keyboard_config, keys_pressed, _force=False, _translate_only=False): 

62 kc = self.keyboard_config 

63 kc.keys_pressed = keys_pressed 

64 kc.set_keymap(True) 

65 kc.owner = self.uuid 

66 

67 def send_server_event(self, *_args): 

68 pass 

69 

70 def send_cursor(self): 

71 pass 

72 

73 

74 def update_mouse(self, *args): 

75 log("update_mouse%s", args) 

76 

77 def damage(self, _wid, window, x, y, w, h, options=None): 

78 polling = options and options.get("polling", False) 

79 p = self.protocol 

80 if polling and p is None or p.queue_size()>=2: 

81 #very basic RFB update rate control, 

82 #if there are packets waiting already 

83 #we'll just process the next polling update instead: 

84 return 

85 img = window.get_image(x, y, w, h) 

86 window.acknowledge_changes() 

87 log("damage: %s", img) 

88 if not img or self.is_closed(): 

89 return 

90 fbupdate = struct.pack(b"!BBH", 0, 0, 1) 

91 encoding = 0 #Raw 

92 rect = struct.pack(b"!HHHHi", x, y, w, h, encoding) 

93 if img.get_rowstride()!=w*4: 

94 img.restride(w*4) 

95 pixels = img.get_pixels() 

96 assert len(pixels)>=4*w*h 

97 pixels = pixels[:4*w*h] 

98 if len(pixels)<=PACKET_JOIN_SIZE: 

99 self.send(fbupdate+rect+memoryview_to_bytes(pixels)) 

100 else: 

101 self.send(fbupdate+rect) 

102 self.send(pixels) 

103 

104 def send_clipboard(self, text): 

105 nocr = strtobytes(text.replace("\r", "")) 

106 msg = struct.pack(b"!BBBBI", 3, 0, 0, 0, len(nocr))+nocr 

107 self.send(msg) 

108 

109 def bell(self, *_args): 

110 msg = struct.pack(b"!B", 2) 

111 self.send(msg) 

112 

113 def send(self, msg): 

114 p = self.protocol 

115 if p: 

116 p.send(msg)