Ticket #486: info-namespace.patch
File info-namespace.patch, 85.6 KB (added by , 6 years ago) |
---|
-
xpra/child_reaper.py
186 186 187 187 def get_info(self): 188 188 iv = list(self._proc_info) 189 info = {"children" : len(iv),190 "children.dead": len([x for x in iv if x.dead]),191 "children.ignored" : len([x for x in iv if x.ignore])}189 info = {"children" : {"" : len(iv), 190 "dead" : len([x for x in iv if x.dead]), 191 "ignored" : len([x for x in iv if x.ignore])}} 192 192 pi = sorted(self._proc_info, key=lambda x: x.pid, reverse=True) 193 cinfo = {} 193 194 for i, procinfo in enumerate(pi): 194 195 d = dict((k,getattr(procinfo,k)) for k in ("name", "command", "ignore", "forget", "returncode", "dead", "pid")) 195 updict(info, "child[%i]" % i, d) 196 cinfo[i] = d 197 updict(info, "child", cinfo) 196 198 return info -
xpra/client/gl/gtk_compat.py
27 27 28 28 def get_info(): 29 29 return { 30 "gdkgl .version" : GdkGLExt._version,31 "gtkgl .version" : GtkGLExt._version,30 "gdkgl" : {"version" : GdkGLExt._version}, 31 "gtkgl" : {"version" : GtkGLExt._version}, 32 32 } 33 33 gdkgl = GdkGLExt 34 34 gtkgl = GtkGLExt … … 74 74 return None 75 75 76 76 def get_info(): 77 def v(x): 78 return {"version" : x} 77 79 return { 78 "pygdkglext .version" : gdkgl.pygdkglext_version,79 "gtkglext .version" : gtkgl.gtkglext_version,80 "gdkglext .version" : gdkgl.gdkglext_version,81 "gdkgl .version" : gdkgl.query_version()80 "pygdkglext" : v(gdkgl.pygdkglext_version), 81 "gtkglext" : v(gtkgl.gtkglext_version), 82 "gdkglext" : v(gdkgl.gdkglext_version), 83 "gdkgl" : v(gdkgl.query_version()) 82 84 } 83 85 84 86 class GLContextManager(object): -
xpra/client/ui_client_base.py
2420 2420 ss.add_data(data, metadata) 2421 2421 if self.av_sync and self.server_av_sync: 2422 2422 info = ss.get_info() 2423 queue_used = info.get("queue.cur") 2423 queue_used = info.get("queue.cur") or info.get("queue", {}).get("cur") 2424 2424 if queue_used is None: 2425 2425 return 2426 2426 delta = (self.queue_used_sent or 0)-queue_used -
xpra/clipboard/clipboard_base.py
23 23 from xpra.gtk_common.gtk_util import GetClipboard, PROPERTY_CHANGE_MASK 24 24 from xpra.gtk_common.nested_main import NestedMainLoop 25 25 from xpra.net.compression import Uncompressed 26 from xpra.util import csv 26 from xpra.util import csv, updict 27 27 28 28 29 29 MIN_CLIPBOARD_COMPRESSION_SIZE = 512 … … 91 91 "want_targets" : self._want_targets, 92 92 } 93 93 for clipboard, proxy in self._clipboard_proxies.items(): 94 for k,v in proxy.get_info().items(): 95 info["%s.%s" % (clipboard, k)] = v 94 info[clipboard] = proxy.get_info() 96 95 return info 97 96 98 97 def cleanup(self): … … 463 462 "enabled" : self._enabled, 464 463 "greedy_client" : self._greedy_client, 465 464 "blocked_owner_change" : self._block_owner_change, 466 "event.selection_request" : self._selection_request_events,467 "event.selection_get" : self._selection_get_events,468 "event.selection_clear" : self._selection_clear_events,469 "event.got_token" : self._got_token_events,470 "event.sent_token" : self._sent_token_events,471 "event.get_contents" : self._get_contents_events,472 "event.request_contents" : self._request_contents_events,473 465 } 466 updict(info, "event", { 467 "selection_request" : self._selection_request_events, 468 "selection_get" : self._selection_get_events, 469 "selection_clear" : self._selection_clear_events, 470 "got_token" : self._got_token_events, 471 "sent_token" : self._sent_token_events, 472 "get_contents" : self._get_contents_events, 473 "request_contents" : self._request_contents_events}) 474 474 return info 475 475 476 476 def cleanup(self): -
xpra/codecs/enc_ffmpeg/__init__.py
1 # This file is part of Xpra. 2 # Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk> 3 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 4 # later version. See the file COPYING for details. -
xpra/codecs/enc_ffmpeg/encoder.pyx
1 # This file is part of Xpra. 2 # Copyright (C) 2012-2014 Antoine Martin <antoine@devloop.org.uk> 3 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 4 # later version. See the file COPYING for details. 5 6 import weakref 7 from xpra.log import Logger 8 log = Logger("decoder", "ffmpeg") 9 10 from xpra.codecs.codec_constants import get_subsampling_divs 11 from xpra.codecs.image_wrapper import ImageWrapper 12 from xpra.codecs.libav_common.av_log cimport override_logger, restore_logger #@UnresolvedImport 13 from xpra.util import bytestostr 14 15 16 ctypedef unsigned long size_t 17 ctypedef unsigned char uint8_t 18 19 20 cdef extern from "../../buffers/buffers.h": 21 object memory_as_pybuffer(void* ptr, Py_ssize_t buf_len, int readonly) 22 int object_as_buffer(object obj, const void ** buffer, Py_ssize_t * buffer_len) 23 int get_buffer_api_version() 24 25 cdef extern from "string.h": 26 void * memcpy(void * destination, void * source, size_t num) nogil 27 void * memset(void * ptr, int value, size_t num) nogil 28 void free(void * ptr) nogil 29 30 31 cdef extern from "../../inline.h": 32 pass 33 34 cdef extern from "../../buffers/memalign.h": 35 void *xmemalign(size_t size) 36 37 38 cdef extern from "libavutil/mem.h": 39 void av_free(void *ptr) 40 41 cdef extern from "libavutil/error.h": 42 int av_strerror(int errnum, char *errbuf, size_t errbuf_size) 43 44 cdef extern from "libavcodec/version.h": 45 int LIBAVCODEC_VERSION_MAJOR 46 int LIBAVCODEC_VERSION_MINOR 47 int LIBAVCODEC_VERSION_MICRO 48 49 #why can't we define this inside the avcodec.h section? (beats me) 50 ctypedef unsigned int AVCodecID 51 ctypedef long AVPixelFormat 52 53 54 cdef extern from "libavutil/pixfmt.h": 55 AVPixelFormat AV_PIX_FMT_NONE 56 AVPixelFormat AV_PIX_FMT_YUV420P 57 58 cdef extern from "libavcodec/avcodec.h": 59 int CODEC_FLAG2_FAST 60 61 ctypedef struct AVFrame: 62 uint8_t **data 63 int *linesize 64 int format 65 void *opaque 66 ctypedef struct AVCodec: 67 pass 68 ctypedef struct AVDictionary: 69 pass 70 ctypedef struct AVPacket: 71 uint8_t *data 72 int size 73 74 ctypedef struct AVCodecContext: 75 int width 76 int height 77 AVPixelFormat pix_fmt 78 int thread_safe_callbacks 79 int thread_count 80 int thread_type 81 int flags 82 int flags2 83 int refcounted_frames 84 85 AVCodecID AV_CODEC_ID_H264 86 AVCodecID AV_CODEC_ID_H265 87 AVCodecID AV_CODEC_ID_VP8 88 AVCodecID AV_CODEC_ID_VP9 89 AVCodecID AV_CODEC_ID_MPEG4 90 91 #init and free: 92 void avcodec_register_all() 93 AVCodec *avcodec_find_decoder(AVCodecID id) 94 AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) 95 int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) 96 AVFrame* av_frame_alloc() 97 void av_frame_free(AVFrame **frame) 98 int avcodec_close(AVCodecContext *avctx) 99 100 #actual decoding: 101 void av_init_packet(AVPacket *pkt) nogil 102 void avcodec_get_frame_defaults(AVFrame *frame) nogil 103 int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, 104 int *got_picture_ptr, const AVPacket *avpkt) nogil 105 106 void av_frame_unref(AVFrame *frame) nogil 107 108 109 FORMAT_TO_ENUM = { 110 "YUV420P" : AV_PIX_FMT_YUV420P, 111 "YUV422P" : AV_PIX_FMT_YUV422P, 112 "YUV444P" : AV_PIX_FMT_YUV444P, 113 "RGB" : AV_PIX_FMT_RGB24, 114 "XRGB" : AV_PIX_FMT_0RGB, 115 "BGRX" : AV_PIX_FMT_BGR0, 116 "ARGB" : AV_PIX_FMT_ARGB, 117 "BGRA" : AV_PIX_FMT_BGRA, 118 "GBRP" : AV_PIX_FMT_GBRP, 119 } 120 121 COLORSPACES = FORMAT_TO_ENUM.keys() 122 ENUM_TO_FORMAT = {} 123 for pix_fmt, av_enum in FORMAT_TO_ENUM.items(): 124 ENUM_TO_FORMAT[av_enum] = pix_fmt 125 126 def get_version(): 127 return (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) 128 129 avcodec_register_all() 130 CODECS = [] 131 if avcodec_find_decoder(AV_CODEC_ID_H264)!=NULL: 132 CODECS.append("h264") 133 if avcodec_find_decoder(AV_CODEC_ID_VP8)!=NULL: 134 CODECS.append("vp8") 135 if avcodec_find_decoder(AV_CODEC_ID_VP9)!=NULL: 136 CODECS.append("vp9") 137 if avcodec_find_decoder(AV_CODEC_ID_H265)!=NULL: 138 CODECS.append("h265") 139 if avcodec_find_decoder(AV_CODEC_ID_MPEG4)!=NULL: 140 CODECS.append("mpeg4") 141 log("enc_ffmpeg.init_module: CODECS=%s", CODECS) 142 143 144 def init_module(): 145 log("enc_ffmpeg.init_module()") 146 override_logger() 147 148 def cleanup_module(): 149 log("enc_ffmpeg.cleanup_module()") 150 restore_logger() 151 152 def get_type(): 153 return "ffmpeg" 154 155 def get_info(): 156 f = {} 157 for e in get_encodings(): 158 f["formats.%s" % e] = get_input_colorspaces(e) 159 return {"version" : get_version(), 160 "encodings" : get_encodings(), 161 "buffer_api" : get_buffer_api_version(), 162 "formats" : f, 163 } 164 165 def get_encodings(): 166 global CODECS 167 return CODECS 168 169 def get_input_colorspaces(encoding): 170 return ["YUV420P"] 171 172 def get_output_colorspace(encoding, csc): 173 if encoding not in CODECS: 174 return "" 175 return "YUV420P" 176 177 178 cdef void clear_frame(AVFrame *frame): 179 assert frame!=NULL, "frame is not set!" 180 for i in range(4): 181 frame.data[i] = NULL 182 183 184 cdef class AVFrameWrapper: 185 """ 186 Wraps an AVFrame so we can free it 187 once both xpra and avcodec are done with it. 188 """ 189 cdef AVCodecContext *avctx 190 cdef AVFrame *frame 191 cdef int xpra_freed 192 193 cdef set_context(self, AVCodecContext *avctx, AVFrame *frame): 194 self.avctx = avctx 195 self.frame = frame 196 log("%s.set_context(%#x, %#x)", self, <unsigned long> avctx, <unsigned long> frame) 197 198 def __dealloc__(self): 199 #By the time this wrapper is garbage collected, 200 #we must have freed it! 201 assert self.frame==NULL and self.avctx==NULL, "frame was freed by both, but not actually freed!" 202 203 def __str__(self): 204 if self.frame==NULL: 205 return "AVFrameWrapper(NULL)" 206 return "AVFrameWrapper(%#x)" % <unsigned long> self.frame 207 208 def xpra_free(self): 209 log("%s.xpra_free()", self) 210 self.free() 211 212 cdef free(self): 213 log("%s.free() context=%#x, frame=%#x", self, <unsigned long> self.avctx, <unsigned long> self.frame) 214 if self.avctx!=NULL and self.frame!=NULL: 215 av_frame_unref(self.frame) 216 self.frame = NULL 217 self.avctx = NULL 218 219 220 class AVImageWrapper(ImageWrapper): 221 """ 222 Wrapper which allows us to call xpra_free on the decoder 223 when the image is freed, or once we have made a copy of the pixels. 224 """ 225 226 def __repr__(self): #@DuplicatedSignature 227 return ImageWrapper.__repr__(self)+"-(%s)" % self.av_frame 228 229 def free(self): #@DuplicatedSignature 230 log("AVImageWrapper.free()") 231 ImageWrapper.free(self) 232 self.xpra_free_frame() 233 234 def clone_pixel_data(self): 235 log("AVImageWrapper.clone_pixel_data()") 236 ImageWrapper.clone_pixel_data(self) 237 self.xpra_free_frame() 238 239 def xpra_free_frame(self): 240 av_frame = self.av_frame 241 log("AVImageWrapper.xpra_free_frame() av_frame=%s", av_frame) 242 if av_frame: 243 self.av_frame = None 244 av_frame.xpra_free() 245 246 247 cdef class Encoder: 248 """ 249 This wraps the AVCodecContext and its configuration, 250 also tracks AVFrames. 251 It also handles reconstructing a single ImageWrapper 252 constructed from 3-pass decoding (see plane_sizes). 253 """ 254 cdef AVCodec *codec 255 cdef AVCodecContext *codec_ctx 256 cdef AVPixelFormat pix_fmt 257 cdef AVPixelFormat actual_pix_fmt 258 cdef object colorspace 259 cdef object weakref_images 260 cdef AVFrame *av_frame 261 #this is the actual number of images we have returned 262 cdef unsigned long frames 263 cdef int width 264 cdef int height 265 cdef object encoding 266 267 cdef object __weakref__ 268 269 def init_context(self, encoding, int width, int height, colorspace): 270 cdef int r 271 cdef int i 272 assert encoding in CODECS 273 self.encoding = encoding 274 self.width = width 275 self.height = height 276 assert colorspace in COLORSPACES, "invalid colorspace: %s" % colorspace 277 self.colorspace = "" 278 for x in COLORSPACES: 279 if x==colorspace: 280 self.colorspace = x 281 break 282 if not self.colorspace: 283 log.error("invalid pixel format: %s", colorspace) 284 return False 285 self.pix_fmt = FORMAT_TO_ENUM.get(colorspace, AV_PIX_FMT_NONE) 286 if self.pix_fmt==AV_PIX_FMT_NONE: 287 log.error("invalid pixel format: %s", colorspace) 288 return False 289 self.actual_pix_fmt = self.pix_fmt 290 291 avcodec_register_all() 292 293 cdef AVCodecID CodecID 294 if self.encoding=="h264": 295 CodecID = AV_CODEC_ID_H264 296 elif self.encoding=="h265": 297 CodecID = AV_CODEC_ID_H265 298 elif self.encoding=="vp8": 299 CodecID = AV_CODEC_ID_VP8 300 elif self.encoding=="vp9": 301 CodecID = AV_CODEC_ID_VP9 302 elif self.encoding=="mpeg4": 303 CodecID = AV_CODEC_ID_MPEG4 304 else: 305 raise Exception("invalid codec; %s" % self.encoding) 306 self.codec = avcodec_find_decoder(CodecID) 307 if self.codec==NULL: 308 log.error("codec %s not found!" % self.encoding) 309 return False 310 311 #from here on, we have to call clean_decoder(): 312 self.codec_ctx = avcodec_alloc_context3(self.codec) 313 if self.codec_ctx==NULL: 314 log.error("failed to allocate codec context!") 315 self.clean_decoder() 316 return False 317 318 self.codec_ctx.refcounted_frames = 1 319 self.codec_ctx.width = width 320 self.codec_ctx.height = height 321 self.codec_ctx.pix_fmt = self.pix_fmt 322 #self.codec_ctx.get_buffer2 = avcodec_get_buffer2 323 #self.codec_ctx.release_buffer = avcodec_release_buffer 324 self.codec_ctx.thread_safe_callbacks = 1 325 self.codec_ctx.thread_type = 2 #FF_THREAD_SLICE: allow more than one thread per frame 326 self.codec_ctx.thread_count = 0 #auto 327 self.codec_ctx.flags2 |= CODEC_FLAG2_FAST #may cause "no deblock across slices" - which should be fine 328 r = avcodec_open2(self.codec_ctx, self.codec, NULL) 329 if r<0: 330 log.error("could not open codec: %s", self.av_error_str(r)) 331 self.clean_decoder() 332 return False 333 #up to 3 AVFrame objects used: 334 self.av_frame = av_frame_alloc() 335 if self.av_frame==NULL: 336 log.error("could not allocate an AVFrame for decoding") 337 self.clean_decoder() 338 return False 339 self.frames = 0 340 #to keep track of images not freed yet: 341 #(we want a weakref.WeakSet() but this is python2.7+ only..) 342 self.weakref_images = [] 343 #register this decoder in the global dictionary: 344 log("dec_avcodec.Decoder.init_context(%s, %s, %s) self=%s", width, height, colorspace, self.get_info()) 345 return True 346 347 def clean(self): 348 self.clean_decoder() 349 self.codec = NULL 350 self.pix_fmt = 0 351 self.actual_pix_fmt = 0 352 self.colorspace = "" 353 self.weakref_images = [] 354 self.av_frame = NULL #should be redundant 355 self.frames = 0 356 self.width = 0 357 self.height = 0 358 self.encoding = "" 359 360 361 def clean_decoder(self): 362 cdef int r, i 363 log("%s.clean_decoder()", self) 364 #we may have images handed out, ensure we don't reference any memory 365 #that needs to be freed using avcodec_release_buffer(..) 366 #as this requires the context to still be valid! 367 #copying the pixels should ensure we free the AVFrameWrapper associated with it: 368 if self.weakref_images: 369 images = [y for y in [x() for x in self.weakref_images] if y is not None] 370 self.weakref_images = [] 371 log("clean_decoder() cloning pixels for images still in use: %s", images) 372 for img in images: 373 if not img.freed: 374 img.clone_pixel_data() 375 376 if self.av_frame!=NULL: 377 log("clean_decoder() freeing AVFrame: %#x", <unsigned long> self.av_frame) 378 av_frame_free(&self.av_frame) 379 #redundant: self.frame = NULL 380 381 cdef unsigned long ctx_key #@DuplicatedSignature 382 log("clean_decoder() freeing AVCodecContext: %#x", <unsigned long> self.codec_ctx) 383 if self.codec_ctx!=NULL: 384 r = avcodec_close(self.codec_ctx) 385 if r!=0: 386 log.warn("error closing decoder context %#x: %s", <unsigned long> self.codec_ctx, self.av_error_str(r)) 387 av_free(self.codec_ctx) 388 self.codec_ctx = NULL 389 log("clean_decoder() done") 390 391 cdef av_error_str(self, errnum): 392 cdef char[128] err_str 393 cdef int i = 0 394 if av_strerror(errnum, err_str, 128)==0: 395 while i<128 and err_str[i]!=0: 396 i += 1 397 return bytestostr(err_str[:i]) 398 return str(errnum) 399 400 def __repr__(self): #@DuplicatedSignature 401 if self.is_closed(): 402 return "dec_avcodec.Decoder(*closed*)" 403 return "dec_avcodec.Decoder(%s)" % self.get_info() 404 405 def get_info(self): #@DuplicatedSignature 406 info = {"version" : get_version(), 407 "encoding" : self.encoding, 408 "formats" : get_input_colorspaces(self.encoding), 409 "type" : self.get_type(), 410 "frames" : self.frames, 411 "width" : self.width, 412 "height" : self.height, 413 } 414 if self.colorspace: 415 info["colorspace"] = self.colorspace 416 info["actual_colorspace"] = self.get_actual_colorspace() 417 if not self.is_closed(): 418 info["decoder_width"] = self.codec_ctx.width 419 info["decoder_height"] = self.codec_ctx.height 420 else: 421 info["closed"] = True 422 return info 423 424 def is_closed(self): 425 return self.codec_ctx==NULL 426 427 def __dealloc__(self): #@DuplicatedSignature 428 self.clean() 429 430 def get_width(self): 431 return self.width 432 433 def get_height(self): 434 return self.height 435 436 def get_encoding(self): 437 return self.encoding 438 439 def get_type(self): #@DuplicatedSignature 440 return "avcodec" 441 442 def decompress_image(self, input, options): 443 cdef unsigned char * padded_buf = NULL 444 cdef const unsigned char * buf = NULL 445 cdef Py_ssize_t buf_len = 0 446 cdef int size 447 cdef int len = 0 448 cdef int nplanes 449 cdef int got_picture 450 cdef AVPacket avpkt 451 cdef unsigned long frame_key #@DuplicatedSignature 452 cdef AVFrameWrapper framewrapper 453 cdef AVFrame *av_frame 454 cdef object img 455 assert self.codec_ctx!=NULL, "no codec context! (not initialized or already closed)" 456 assert self.codec!=NULL 457 458 #copy the whole input buffer into a padded C buffer: 459 assert object_as_buffer(input, <const void**> &buf, &buf_len)==0 460 padded_buf = <unsigned char *> xmemalign(buf_len+128) 461 memcpy(padded_buf, buf, buf_len) 462 memset(padded_buf+buf_len, 0, 128) 463 464 #note: plain RGB output, will redefine those: 465 out = [] 466 strides = [] 467 outsize = 0 468 469 #ensure we can detect if the frame buffer got allocated: 470 clear_frame(self.av_frame) 471 #now safe to run without gil: 472 with nogil: 473 av_init_packet(&avpkt) 474 avpkt.data = <uint8_t *> (padded_buf) 475 avpkt.size = buf_len 476 len = avcodec_decode_video2(self.codec_ctx, self.av_frame, &got_picture, &avpkt) 477 if len<0: 478 av_frame_unref(self.av_frame) 479 log("%s.decompress_image(%s:%s, %s) avcodec_decode_video2 failure: %s", self, type(input), buf_len, options, self.av_error_str(len)) 480 log.error("avcodec_decode_video2 %s decoding failure:", self.encoding) 481 log.error(" %s", self.av_error_str(len)) 482 return None 483 if len==0: 484 av_frame_unref(self.av_frame) 485 log("%s.decompress_image(%s:%s, %s) avcodec_decode_video2 failed to decode the stream", self, type(input), buf_len, options) 486 log.error("avcodec_decode_video2 %s decoding failure - no stream", self.encoding) 487 return None 488 489 if self.actual_pix_fmt!=self.av_frame.format: 490 if self.av_frame.format==-1: 491 log.error("avcodec error decoding %i bytes of %s data", buf_len, self.encoding) 492 log.error(" frame %i", self.frames) 493 log.error(" options=%s", options) 494 log.error(" decoder state:") 495 for k,v in self.get_info().items(): 496 log.error(" %s = %s", k, v) 497 return None 498 self.actual_pix_fmt = self.av_frame.format 499 if self.actual_pix_fmt not in ENUM_TO_FORMAT: 500 av_frame_unref(self.av_frame) 501 log.error("unknown output pixel format: %s, expected %s (%s)", self.actual_pix_fmt, self.pix_fmt, self.colorspace) 502 return None 503 log("avcodec actual output pixel format is %s (%s), expected %s (%s)", self.actual_pix_fmt, self.get_actual_colorspace(), self.pix_fmt, self.colorspace) 504 505 cs = self.get_actual_colorspace() 506 if cs.endswith("P"): 507 divs = get_subsampling_divs(cs) 508 nplanes = 3 509 for i in range(3): 510 _, dy = divs[i] 511 if dy==1: 512 height = self.codec_ctx.height 513 elif dy==2: 514 height = (self.codec_ctx.height+1)>>1 515 else: 516 av_frame_unref(self.av_frame) 517 raise Exception("invalid height divisor %s" % dy) 518 stride = self.av_frame.linesize[i] 519 size = height * stride 520 outsize += size 521 522 out.append(memory_as_pybuffer(<void *>self.av_frame.data[i], size, True)) 523 strides.append(stride) 524 log("decompress_image() read back yuv plane %s: %s bytes", i, size) 525 else: 526 #RGB mode: "out" is a single buffer 527 strides = self.av_frame.linesize[0]+self.av_frame.linesize[1]+self.av_frame.linesize[2] 528 outsize = self.codec_ctx.height * strides 529 out = memory_as_pybuffer(<void *>self.av_frame.data[0], outsize, True) 530 nplanes = 0 531 log("decompress_image() read back rgb buffer: %s bytes", outsize) 532 533 #FIXME: we could lose track of framewrappers if an error occurs before the end: 534 framewrapper = AVFrameWrapper() 535 framewrapper.set_context(self.codec_ctx, self.av_frame) 536 537 if outsize==0: 538 av_frame_unref(self.av_frame) 539 raise Exception("output size is zero!") 540 541 free(padded_buf) 542 assert self.codec_ctx.width>=self.width, "codec width is smaller than our width: %s<%s" % (self.codec_ctx.width, self.width) 543 assert self.codec_ctx.height>=self.height, "codec height is smaller than our height: %s<%s" % (self.codec_ctx.height, self.height) 544 img = AVImageWrapper(0, 0, self.width, self.height, out, cs, 24, strides, nplanes, thread_safe=False) 545 img.av_frame = framewrapper 546 self.frames += 1 547 #add to weakref list after cleaning it up: 548 self.weakref_images = [x for x in self.weakref_images if x() is not None] 549 self.weakref_images.append(weakref.ref(img)) 550 log("%s.decompress_image(%s:%s, %s)=%s", self, type(input), buf_len, options, img) 551 return img 552 553 554 def get_colorspace(self): 555 return self.colorspace 556 557 def get_actual_colorspace(self): 558 return ENUM_TO_FORMAT.get(self.actual_pix_fmt, "unknown/invalid") 559 560 561 def selftest(full=False): 562 global CODECS 563 from xpra.codecs.codec_checks import testdecoder 564 from xpra.codecs.dec_avcodec2 import decoder 565 global CODECS 566 CODECS = testdecoder(decoder, full) -
xpra/codecs/mkv/__init__.py
1 # This file is part of Xpra. 2 # Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk> 3 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 4 # later version. See the file COPYING for details. -
xpra/codecs/mkv/muxer.pyx
1 # This file is part of Xpra. 2 # Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk> 3 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 4 # later version. See the file COPYING for details. 5 6 import time 7 import os 8 9 from xpra.log import Logger 10 log = Logger("encoder", "mkv") 11 12 from libc.stdint cimport int64_t 13 14 cdef extern from "string.h": 15 void *memset(void *ptr, int value, size_t num) nogil 16 void free(void *ptr) nogil 17 18 cdef extern from "../../buffers/memalign.h": 19 void *xmemalign(size_t size) 20 21 cdef extern from "../../buffers/buffers.h": 22 int object_as_buffer(object obj, const void ** buffer, Py_ssize_t * buffer_len) 23 int get_buffer_api_version() 24 25 26 cdef extern from "libmkv.h": 27 pass 28 29 cdef class Muxer: 30 cdef object __weakref__ 31 32 #init_context(w, h, src_format, encoding, quality, speed, scaling, options) 33 def init_context(self, int width, int height, src_format, dst_formats, encoding, int quality, int speed, scaling, options): #@DuplicatedSignature 34 pass -
xpra/codecs/nvenc4/encoder.pyx
1586 1586 "encoder_height" : self.encoder_height, 1587 1587 "bitrate" : self.target_bitrate, 1588 1588 "quality" : self.quality, 1589 "speed" : self.speed, 1590 "lossless" : self.lossless, 1591 "lossless.supported": LOSSLESS_ENABLED, 1592 "lossless.threshold": LOSSLESS_THRESHOLD, 1593 "yuv444.supported" : YUV444_ENABLED, 1594 "yuv444.threshold" : YUV444_THRESHOLD, 1589 "speed" : self.speed}) 1590 updict(info, "lossless", { 1591 "" : self.lossless, 1592 "supported" : LOSSLESS_ENABLED, 1593 "threshold" : LOSSLESS_THRESHOLD}) 1594 updict(info, "yuv444", { 1595 "supported" : YUV444_ENABLED, 1596 "threshold" : YUV444_THRESHOLD, 1595 1597 }) 1596 1598 if self.scaling!=(1,1): 1597 1599 info.update({ -
xpra/codecs/nvenc5/encoder.pyx
1625 1625 "bitrate" : self.target_bitrate, 1626 1626 "quality" : self.quality, 1627 1627 "speed" : self.speed, 1628 "lossless" : self.lossless,1629 "lossless.supported": LOSSLESS_ENABLED,1630 "lossless.threshold": LOSSLESS_THRESHOLD,1631 "yuv444.supported" : YUV444_ENABLED,1632 "yuv444.threshold" : YUV444_THRESHOLD,1633 1628 }) 1629 updict(info, "lossless", { 1630 "" : self.lossless, 1631 "supported" : LOSSLESS_ENABLED, 1632 "threshold" : LOSSLESS_THRESHOLD}) 1633 updict(info, "yuv444", { 1634 "supported" : YUV444_ENABLED, 1635 "threshold" : YUV444_THRESHOLD, 1636 }) 1634 1637 if self.scaling!=(1,1): 1635 1638 info.update({ 1636 1639 "input_width" : self.input_width, -
xpra/codecs/nvenc6/encoder.pyx
1696 1696 "bitrate" : self.target_bitrate, 1697 1697 "quality" : self.quality, 1698 1698 "speed" : self.speed, 1699 "lossless" : self.lossless,1700 "lossless.supported": LOSSLESS_ENABLED,1701 "lossless.threshold": LOSSLESS_THRESHOLD,1702 "yuv444.supported" : YUV444_ENABLED,1703 "yuv444.threshold" : YUV444_THRESHOLD,1704 1699 }) 1700 updict(info, "lossless", { 1701 "" : self.lossless, 1702 "supported" : LOSSLESS_ENABLED, 1703 "threshold" : LOSSLESS_THRESHOLD}) 1704 updict(info, "yuv444", { 1705 "supported" : YUV444_ENABLED, 1706 "threshold" : YUV444_THRESHOLD, 1707 }) 1705 1708 if self.scaling!=(1,1): 1706 1709 info.update({ 1707 1710 "input_width" : self.input_width, -
xpra/codecs/ogg/__init__.py
1 # This file is part of Xpra. 2 # Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk> 3 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 4 # later version. See the file COPYING for details. -
xpra/codecs/ogg/muxer.pyx
1 # This file is part of Xpra. 2 # Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk> 3 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 4 # later version. See the file COPYING for details. 5 6 import time 7 import os 8 9 from xpra.log import Logger 10 log = Logger("encoder", "mkv") 11 12 from libc.stdint cimport int64_t 13 14 cdef extern from "string.h": 15 void *memset(void *ptr, int value, size_t num) nogil 16 void free(void *ptr) nogil 17 18 cdef extern from "../../buffers/memalign.h": 19 void *xmemalign(size_t size) 20 21 cdef extern from "../../buffers/buffers.h": 22 int object_as_buffer(object obj, const void ** buffer, Py_ssize_t * buffer_len) 23 int get_buffer_api_version() 24 25 26 cdef extern from "ogg/ogg.h": 27 pass 28 29 cdef class Muxer: 30 cdef object __weakref__ 31 32 #init_context(w, h, src_format, encoding, quality, speed, scaling, options) 33 def init_context(self, int width, int height, src_format, dst_formats, encoding, int quality, int speed, scaling, options): #@DuplicatedSignature 34 pass -
xpra/net/bytestreams.py
215 215 d = Connection.get_info(self) 216 216 try: 217 217 d["type"] = "pipe" 218 d["pipe .read.fd"] = self._read_fd219 d["pipe.write.fd"] = self._write_fd218 d["pipe"] = {"read" : {"fd" : self._read_fd}, 219 "write" : {"fd" : self._write_fd}} 220 220 except: 221 221 pass 222 222 return d -
xpra/net/protocol.py
210 210 211 211 def get_info(self, alias_info=True): 212 212 info = { 213 "input.packetcount" : self.input_packetcount,214 "input.raw_packetcount" : self.input_raw_packetcount,215 "input.cipher" : self.cipher_in_name or "",216 "input.cipher.padding" : self.cipher_in_padding,217 "output.packetcount" : self.output_packetcount,218 "output.raw_packetcount": self.output_raw_packetcount,219 "output.cipher" : self.cipher_out_name or "",220 "output.cipher.padding" : self.cipher_out_padding,221 213 "large_packets" : self.large_packets, 222 214 "compression_level" : self.compression_level, 223 215 "max_packet_size" : self.max_packet_size} 224 updict(info, "input.count", self.input_stats) 225 updict(info, "output.count", self.output_stats) 216 updict(info, "input", { 217 "packetcount" : self.input_packetcount, 218 "raw_packetcount" : self.input_raw_packetcount, 219 "count" : self.input_stats, 220 "cipher" : {"": self.cipher_in_name or "", 221 "padding" : self.cipher_in_padding}, 222 }) 223 updict(info, "output", { 224 "packetcount" : self.output_packetcount, 225 "raw_packetcount" : self.output_raw_packetcount, 226 "count" : self.output_stats, 227 "cipher" : {"": self.cipher_out_name or "", 228 "padding" : self.cipher_out_padding}, 229 }) 226 230 c = self._compress 227 231 if c: 228 232 info["compressor"] = compression.get_compressor_name(self._compress) … … 233 237 else: 234 238 info["encoder"] = packet_encoding.get_encoder_name(self._encoder) 235 239 if alias_info: 236 for k,v in self.send_aliases.items(): 237 info["send_alias." + str(k)] = v 238 info["send_alias." + str(v)] = k 239 for k,v in self.receive_aliases.items(): 240 info["receive_alias." + str(k)] = v 241 info["receive_alias." + str(v)] = k 240 info["send_alias"] = self.send_aliases 241 info["receive_alias"] = self.receive_aliases 242 242 c = self._conn 243 243 if c: 244 244 try: … … 248 248 info["has_more"] = self._source_has_more.is_set() 249 249 for t in (self._write_thread, self._read_thread, self._read_parser_thread, self._write_format_thread): 250 250 if t: 251 info ["thread.%s" %t.name] = t.is_alive()251 info.setdefault("thread", {})[t.name] = t.is_alive() 252 252 return info 253 253 254 254 -
xpra/net/pycrypto_backend.py
20 20 pass 21 21 22 22 def get_info(): 23 caps = {"backend" : "pycrypto",24 "pycrypto" : "True",25 "pycrypto.version" : Crypto.__version__}26 23 try: 27 24 from Crypto.PublicKey import _fastmath 28 25 except: 29 26 _fastmath = None 30 caps["pycrypto.fastmath"] = _fastmath is not None 31 return caps 27 return {"backend" : "pycrypto", 28 "pycrypto" : {"" : True, 29 "version" : Crypto.__version__}, 30 "fastmath" : _fastmath is not None} 32 31 33 32 34 33 def get_key(password, key_salt, block_size, iterations): -
xpra/net/pycryptography_backend.py
65 65 import cryptography 66 66 return {"backend" : "python-cryptography", 67 67 "backends" : [ci(x) for x in getattr(backend, "_backends", [])], 68 "python-cryptography" : True, 69 "python-cryptography.version" : cryptography.__version__} 68 "python-cryptography" : {"" : True, 69 "version" : cryptography.__version__} 70 } 70 71 71 72 def get_key(password, key_salt, block_size, iterations): 72 73 global backend -
xpra/platform/darwin/shadow_server.py
113 113 114 114 def get_info(self, proto): 115 115 info = GTKServerBase.get_info(self, proto) 116 info ["features.shadow"] = True117 info ["server.type"] = "Python/gtk2/osx-shadow"116 info.setdefault("features", {})["shadow"] = True 117 info.setdefault("server", {})["type"] = "Python/gtk2/osx-shadow" 118 118 return info -
xpra/platform/gui.py
161 161 "desktops" : get_number_of_desktops(), 162 162 "desktop_names" : get_desktop_names(), 163 163 "vertical-refresh" : get_vrefresh(), 164 "double_click.time" : get_double_click_time(),165 "double_click.distance" : get_double_click_distance(),166 164 "fixed_cursor_size" : get_fixed_cursor_size(), 167 165 "cursor_size" : get_cursor_size(), 168 "dpi.x" : get_xdpi(),169 "dpi.y" : get_ydpi(),170 166 "icon_size" : get_icon_size(), 171 167 } 172 168 from xpra.util import updict 169 updict("double_click", { 170 "time" : get_double_click_time(), 171 "distance" : get_double_click_distance(), 172 }) 173 updict("dpi", { 174 "x" : get_xdpi(), 175 "y" : get_ydpi() 176 }) 173 177 updict(info, "antialias", get_antialias_info()) 174 178 updict(info, "window_frame", get_window_frame_sizes()) 175 179 return info -
xpra/platform/paths.py
206 206 207 207 def get_info(): 208 208 return { 209 "install .prefix" : get_install_prefix(),210 "default_conf .dirs" : get_default_conf_dirs(),211 "system_conf .dirs" : get_system_conf_dirs(),212 "user_conf .dirs" : get_user_conf_dirs(),213 "socket .dirs" : get_socket_dirs(),214 "log .dir" : get_default_log_dir(),215 "download .dir" : get_download_dir(),216 "app .dir" : get_app_dir(),217 "app .default.dir" : default_get_app_dir(),209 "install" : {"prefix" : get_install_prefix()}, 210 "default_conf" : {"dirs" : get_default_conf_dirs()}, 211 "system_conf" : {"dirs" : get_system_conf_dirs()}, 212 "user_conf" : {"dirs" : get_user_conf_dirs()}, 213 "socket" : {"dirs" : get_socket_dirs()}, 214 "log" : {"dir" : get_default_log_dir()}, 215 "download" : {"dir" : get_download_dir()}, 216 "app" : {"dir" : get_app_dir()}, 217 "app" : {"default" : {"dir" : default_get_app_dir()}}, 218 218 "resources" : get_resources_dir(), 219 219 "icons" : get_icon_dir(), 220 220 "home" : os.path.expanduser("~"), -
xpra/platform/printing.py
68 68 69 69 70 70 def get_info(): 71 return { 72 "mimetypes" : get_mimetypes(), 73 "mimetypes.default" : DEFAULT_MIMETYPES, 71 return {"mimetypes" : {"" : get_mimetypes(), 72 "default" : DEFAULT_MIMETYPES} 74 73 } 75 74 76 75 -
xpra/platform/pycups_printing.py
416 416 417 417 def get_info(): 418 418 from xpra.platform.printing import get_mimetypes, DEFAULT_MIMETYPES 419 return { 420 "mimetypes" : get_mimetypes(), 421 "mimetypes.default" : DEFAULT_MIMETYPES, 419 return {"mimetypes" : {"" : get_mimetypes(), 420 "default" : DEFAULT_MIMETYPES, 421 "printers" : MIMETYPE_TO_PRINTER, 422 "ppd" : MIMETYPE_TO_PPD}, 423 "mimetype" : {"default" : DEFAULT_MIMETYPE}, 422 424 "simulate-failure" : SIMULATE_PRINT_FAILURE, 423 425 "allow-user" : ALLOW, 424 426 "raw-mode" : RAW_MODE, 425 427 "generic" : GENERIC, 426 428 "tmpdir" : FORWARDER_TMPDIR, 427 "mimetype.default" : DEFAULT_MIMETYPE,428 429 "lpadmin" : LPADMIN, 429 430 "lpinfo" : LPINFO, 430 431 "forwarder" : FORWARDER_BACKEND, … … 431 432 "skipped-printers" : SKIPPED_PRINTERS, 432 433 "add-local-printers": ADD_LOCAL_PRINTERS, 433 434 "printer-prefix" : PRINTER_PREFIX, 434 "cups-dbus.default" : DEFAULT_CUPS_DBUS, 435 "cups-dbus" : CUPS_DBUS, 436 "cups-dbus.poll-delay" : POLLING_DELAY, 437 "mimetypes.printers": MIMETYPE_TO_PRINTER, 438 "mimetypes.ppd" : MIMETYPE_TO_PPD, 435 "cups-dbus" : {"" : CUPS_DBUS, 436 "default" : DEFAULT_CUPS_DBUS, 437 "poll-delay" : POLLING_DELAY}, 439 438 "cups.default-options" : DEFAULT_CUPS_OPTIONS, 440 "printers .predefined" : UNPROBED_PRINTER_DEFS,441 "printers" : get_printer_definitions(),439 "printers" : {"" : get_printer_definitions(), 440 "predefined" : UNPROBED_PRINTER_DEFS}, 442 441 } 443 442 444 443 -
xpra/platform/win32/keyboard_config.py
36 36 def __repr__(self): 37 37 return "win32.KeyboardConfig" 38 38 39 def get_info(self):40 info = KeyboardConfigBase.get_info(self)41 return info42 39 43 44 40 def parse_options(self, props): 45 41 return KeyboardConfigBase.parse_options(self, props) 46 42 … … 122 118 #no useful mapping: 123 119 "ICO_CLEAR" : "IcoClr", 124 120 "ICO_HELP" : "Help", 121 "DIVIDE" : "KP_Divide", 125 122 "MULTIPLY" : "KP_Multiply", 123 "SUBTRACT" : "KP_Substract", 124 "ADD" : "KP_Add", 126 125 "NONAME" : "NoSymbol", 127 126 "NUMPAD0" : "KP_0", 128 127 "NUMPAD1" : "KP_1", … … 167 166 "OEM_PA1" : "OemPa1", 168 167 "OEM_PA2" : "OemPa2", 169 168 "OEM_PA3" : "OemPa3", 170 "OEM_PLUS" : "plus",169 #"OEM_PLUS" : "equal", 171 170 "OEM_RESET" : "Reset", 172 171 "OEM_WSCTRL" : "WsCtrl", 173 172 "PA1" : "Pa1", 173 "OEM_102" : "backslash", 174 174 #missing:? 175 175 #"PACKET" : "Packet", 176 176 "PLAY" : "Play", … … 263 263 "VOLUME_UP" : "XF86AudioRaiseVolume", 264 264 "XBUTTON1" : "X1", 265 265 "XBUTTON2" : "X2", 266 "BRACKET_LEFT" : "bracketleft", 267 "BRACKET_RIGHT" : "bracketright", 268 "BRACE_LEFT" : "braceleft", 269 "BRACE_RIGHT" : "braceright", 270 "COLON" : "colon", 271 "SEMICOLON" : "semicolon", 272 "APOSTROPHE" : "apostrophe", 273 "AT" : "at", 274 "NUMBER_SIGN" : "numbersign", 275 "COMMA" : "comma", 276 "LESS" : "less", 277 "EQUAL" : "equal", 278 "GREATER" : "greater", 279 "PERIOD" : "period", 280 "SLASH" : "slash", 281 "QUESTION" : "question", 282 "BAR" : "bar", 283 "EXCLAM" : "exclam", 284 "QUOTEDBL" : "quotedbl", 285 "STERLING" : "sterling", 286 "DOLLAR" : "dollar", 287 "PERCENT" : "percent", 288 "ASCIICIRCUM" : "asciicircum", 289 "AMPERSAND" : "ampersand", 290 "ASTERISK" : "asterisk", 291 "PARENLEFT" : "parenleft", 292 "PARENRIGHT" : "parenright", 293 "UNDERSCORE" : "underscore", 294 "BACKSLASH" : "backslash", 295 "GRAVE" : "grave", 266 296 } 267 297 268 298 #these aren't defined in win32con... 269 299 DEFS = { 300 "EXCLAM" : 33, 301 "QUOTEDBL" : 34, 302 "NUMBER_SIGN" : 35, 303 "DOLLAR" : 36, 304 "PERCENT" : 37, 305 "AMPERSAND" : 38, 306 "APOSTROPHE" : 39, 307 "PARENLEFT" : 40, 308 "PARENRIGHT" : 41, 309 "ASTERISK" : 42, 310 "COMMA" : 44, 311 "PERIOD" : 46, 312 "SLASH" : 47, 313 "COLON" : 58, 314 "SEMICOLON" : 59, 315 "LESS" : 60, 316 "EQUAL" : 61, 317 "GREATER" : 62, 318 "QUESTION" : 63, 319 "AT" : 64, 320 "BRACKET_LEFT" : 91, 321 "BACKSLASH" : 92, 322 "BRACKET_RIGHT" : 93, 323 "ASCIICIRCUM" : 94, 324 "UNDERSCORE" : 95, 325 "GRAVE" : 96, 326 "BRACE_LEFT" : 123, 327 "BAR" : 124, 328 "BRACE_RIGHT" : 125, 329 "ASCIITILDE" : 126, 330 "STERLING" : 156, 270 331 "SLEEP" : 0x5F, 271 332 "OEM_FJ_JISHO" : 0x92, 272 333 "OEM_FJ_MASSHOU" : 0x93, … … 313 374 "OEM_FINISH" : 0xF1, 314 375 "OEM_ENLW" : 0xF4, 315 376 "OEM_BACKTAB" : 0xF5, 316 "ASCIITILDE" : 65107, #aka 0x00fe53 377 "ASCIITILDE" : 126, 378 #"ASCIITILDE" : 65107, #aka 0x00fe53 317 379 "DEAD_GRAVE" : 65104, #aka 0x00fe50 318 380 } 319 381 -
xpra/platform/win32/shadow_server.py
393 393 394 394 def get_info(self, proto): 395 395 info = GTKServerBase.get_info(self, proto) 396 info["features.shadow"] = True 397 info["server.type"] = "Python/gtk2/win32-shadow" 398 info["server.tray"] = self.tray 399 info["server.tray-icon"] = self.tray_icon or "" 396 info.setdefault("features", {})["shadow"] = True 397 info.setdefault("server", { 398 "type" : "Python/gtk2/win32-shadow", 399 "tray" : self.tray, 400 "tray-icon" :self.tray_icon or ""}) 400 401 return info 401 402 402 403 -
xpra/platform/xposix/gui.py
15 15 traylog = Logger("posix", "menu") 16 16 menulog = Logger("posix", "menu") 17 17 18 from xpra.util import iround 18 from xpra.util import iround, updict 19 19 from xpra.gtk_common.gobject_compat import get_xid, is_gtk3 20 20 21 21 device_bell = None … … 456 456 s = _get_xsettings() 457 457 if s: 458 458 serial, values = s 459 i["xsettings.serial"] = serial459 xi = {"serial" : serial} 460 460 for _,name,value,_ in values: 461 i["xsettings.%s" % name] = value 462 i["dpi.xsettings"] = _get_xsettings_dpi() 463 i["dpi.randr"] = _get_randr_dpi() 461 xi[name] = value 462 updict(i, "xsettings", xi) 463 i.setdefault("dpi", { 464 "xsettings" : _get_xsettings_dpi(), 465 "randr" : _get_randr_dpi()}) 464 466 return i 465 467 466 468 -
xpra/server/gtk_server_base.py
88 88 89 89 def do_get_info(self, proto, *args): 90 90 info = ServerBase.do_get_info(self, proto, *args) 91 updict(info, "server", get_gtk_version_info())92 info.update({93 "server.type" : "Python/gtk-x11",94 "features.randr" : self.randr})91 vi = get_gtk_version_info() 92 vi["type"] = "Python/gtk-x11" 93 info.setdefault("server", {}).update(vi) 94 info.setdefault("features", {})["randr"] = self.randr 95 95 return info 96 96 97 97 def get_root_window_size(self): -
xpra/server/proxy/proxy_server.py
257 257 i = 0 258 258 for p,v in self.processes.items(): 259 259 d,_ = v 260 info[ "proxy[%s].display" % i] = d261 info["proxy[%s].live" % i] = p.is_alive()262 info["proxy[%s].pid" % i] = p.pid260 info[i] = {"display" : d, 261 "live" : p.is_alive(), 262 "pid" : p.pid} 263 263 i += 1 264 264 info["proxies"] = len(self.processes) 265 265 return info -
xpra/server/server_base.py
1772 1772 "y" : self.ydpi 1773 1773 }) 1774 1774 updict(info, "antialias", self.antialias) 1775 info["cursor .size"] = self.cursor_size1775 info["cursor"] = {"size" : self.cursor_size} 1776 1776 log("get_info took %.1fms", 1000.0*(time.time()-start)) 1777 1777 return info 1778 1778 … … 1835 1835 "repeat.interval" : self.key_repeat_interval, 1836 1836 "keys_pressed" : self.keys_pressed.values(), 1837 1837 "modifiers" : self.xkbmap_mod_meanings} 1838 if self.keyboard_config: 1839 for k,v in self.keyboard_config.get_info().items(): 1840 if v is not None: 1841 info[k] = v 1838 kc = self.keyboard_config 1839 if kc: 1840 info.update(kc.get_info()) 1842 1841 return info 1843 1842 1844 1843 def get_clipboard_info(self): … … 1851 1850 "virtual-video-devices" : self.virtual_video_devices} 1852 1851 1853 1852 def do_get_info(self, proto, server_sources=None, window_ids=None): 1854 info = {"server .python.version" : python_platform.python_version()}1853 info = {"server" : {"python" : {"version" : python_platform.python_version()}}} 1855 1854 1856 1855 def up(prefix, d, suffix=""): 1857 1856 updict(info, prefix, d, suffix) … … 1870 1869 1871 1870 info["windows"] = len([window for window in list(self._id_to_window.values()) if window.is_managed()]) 1872 1871 # other clients: 1873 info["clients"] = len([p for p in self._server_sources.keys() if p!=proto])1874 info["clients.unauthenticated"] = len([p for p in self._potential_protocols if ((p is not proto) and (p not in self._server_sources.keys()))])1872 info["clients"] = {"" : len([p for p in self._server_sources.keys() if p!=proto]), 1873 "unauthenticated" : len([p for p in self._potential_protocols if ((p is not proto) and (p not in self._server_sources.keys()))])} 1875 1874 #find the server source to report on: 1876 1875 n = len(server_sources or []) 1877 1876 if n==1: … … 1879 1878 up("client", ss.get_info()) 1880 1879 info.update(ss.get_window_info(window_ids)) 1881 1880 elif n>1: 1881 cinfo = {} 1882 1882 for i, ss in enumerate(server_sources): 1883 up("client[%i]" % i, ss.get_info()) 1884 wi = ss.get_window_info(window_ids) 1885 up("client[%i]" % i, wi) 1886 #this means that the last source overrides previous ones 1887 #(bad decision was made on the namespace for this..) 1888 info.update(wi) 1883 sinfo = ss.get_info() 1884 sinfo.update(ss.get_window_info(window_ids)) 1885 cinfo[i] = sinfo 1886 up("client", cinfo) 1889 1887 return info 1890 1888 1891 1889 def add_windows_info(self, info, window_ids): 1890 winfo = {} 1892 1891 for wid, window in self._id_to_window.items(): 1893 1892 if window_ids is not None and wid not in window_ids: 1894 1893 continue 1895 for k,v in self.get_window_info(window).items(): 1896 wp = "window[%s]." % wid 1897 info[wp + k] = v 1894 winfo[wid] = self.get_window_info(window) 1895 updict(info, "window", winfo) 1898 1896 1899 1897 def get_window_info(self, window): 1900 1898 from xpra.server.source import make_window_metadata -
xpra/server/server_core.py
40 40 from xpra.make_thread import make_thread 41 41 from xpra.scripts.fdproxy import XpraProxy 42 42 from xpra.server.control_command import ControlError, HelloCommand, HelpCommand, DebugControl 43 from xpra.util import csv, typedict, updict, repr_ellipsized, dump_all_frames, \43 from xpra.util import csv, typedict, updict, flatten_dict, repr_ellipsized, dump_all_frames, \ 44 44 SERVER_SHUTDOWN, SERVER_UPGRADE, LOGIN_TIMEOUT, DONE, PROTOCOL_ERROR, SERVER_ERROR, VERSION_ERROR, CLIENT_REQUEST 45 45 46 46 main_thread = threading.current_thread() … … 877 877 self.get_all_info(self.do_send_info, proto) 878 878 879 879 def do_send_info(self, proto, info): 880 proto.send_now(("hello", info))880 proto.send_now(("hello", flatten_dict(info))) 881 881 882 882 def get_all_info(self, callback, proto=None, *args): 883 883 ui_info = self.get_ui_info(proto, *args) … … 928 928 "executable" : sys.executable, 929 929 }) 930 930 if self.session_name: 931 info["session .name"] = self.session_name931 info["session"] = {"name" : self.session_name} 932 932 if self.child_reaper: 933 933 info.update(self.child_reaper.get_info()) 934 934 return info -
xpra/server/source.py
41 41 from xpra.make_thread import make_thread 42 42 from xpra.os_util import platform_name, Queue, get_machine_id, get_user_uuid 43 43 from xpra.server.background_worker import add_work_item 44 from xpra.util import csv, std, typedict, updict, get_screen_info, CLIENT_PING_TIMEOUT, WORKSPACE_UNSET, DEFAULT_METADATA_SUPPORTED44 from xpra.util import csv, std, typedict, updict, flatten_dict, get_screen_info, CLIENT_PING_TIMEOUT, WORKSPACE_UNSET, DEFAULT_METADATA_SUPPORTED 45 45 46 46 47 47 NOYIELD = os.environ.get("XPRA_YIELD") is None … … 1350 1350 "suspended" : self.suspended, 1351 1351 } 1352 1352 if self.desktop_size_unscaled: 1353 info["desktop_size .unscaled"] = self.desktop_size_unscaled1353 info["desktop_size"] = {"unscaled" : self.desktop_size_unscaled} 1354 1354 1355 1355 def addattr(k, name): 1356 1356 v = getattr(self, name) … … 1360 1360 addattr(x, "client_"+x) 1361 1361 #encoding: 1362 1362 info.update({ 1363 "encodings" : self.encodings, 1364 "encodings.core" : self.core_encodings, 1365 "encoding.default" : self.default_encoding or "" 1363 "encodings" : {"" : self.encodings, 1364 "core" : self.core_encodings}, 1366 1365 }) 1366 info.setdefault("encoding", {})["default"] = self.default_encoding or "" 1367 1367 def up(prefix, d): 1368 1368 updict(info, prefix, d) 1369 1369 up("encoding", self.default_encoding_options) … … 1370 1370 up("encoding", self.encoding_options) 1371 1371 up("icons", self.icons_encoding_options) 1372 1372 up("connection", self.protocol.get_info()) 1373 up("av-sync", {"client .delay" : self.av_sync_delay,1373 up("av-sync", {"client" : {"delay" : self.av_sync_delay}, 1374 1374 "total" : self.av_sync_delay_total, 1375 1375 "delta" : self.av_sync_delta}) 1376 1376 if self.window_frame_sizes: 1377 up("window .frame-sizes", self.window_frame_sizes)1377 up("window", {"frame-sizes" : self.window_frame_sizes}) 1378 1378 if self.window_filters: 1379 1379 i = 0 1380 finfo = {} 1380 1381 for uuid, f in self.window_filters: 1381 1382 if uuid==self.uuid: 1382 info["window-filter[%i]" %i] = str(f)1383 finfo[i] = str(f) 1383 1384 i += 1 1385 up("window-filter", finfo) 1384 1386 info.update(self.get_sound_info()) 1385 1387 info.update(self.get_features_info()) 1386 1388 info.update(self.get_screen_info()) … … 1425 1427 v = getattr(self, prop) 1426 1428 if v is not None: 1427 1429 info[prop] = v 1428 for k,v in sound_info(self.supports_speaker, self.sound_source).items(): 1429 info["speaker.%s" % k] = v 1430 for k,v in sound_info(self.supports_microphone, self.sound_sink).items(): 1431 info["microphone.%s" % k] = v 1430 updict(info, "speaker", sound_info(self.supports_speaker, self.sound_source)) 1431 updict(info, "microphone", sound_info(self.supports_microphone, self.sound_sink)) 1432 1432 return info 1433 1433 1434 1434 def get_window_info(self, window_ids=[]): … … 1435 1435 """ 1436 1436 Adds encoding and window specific information 1437 1437 """ 1438 info = { 1439 "damage.compression_queue.size.current" : self.encode_work_queue.qsize(), 1440 "damage.packet_queue.size.current" : len(self.packet_queue), 1441 } 1438 info = {"damage" : { 1439 "compression_queue" : {"size" : {"current" : self.encode_work_queue.qsize()}}, 1440 "packet_queue" : {"size" : {"current" : len(self.packet_queue)}}, 1441 } 1442 } 1442 1443 qpixels = [x[2] for x in list(self.packet_queue)] 1443 1444 add_list_stats(info, "packet_queue_pixels", qpixels) 1444 1445 if len(qpixels)>0: 1445 info["packet_queue_pixels .current"] = qpixels[-1]1446 info["packet_queue_pixels"] = {"current" : qpixels[-1]} 1446 1447 1447 1448 info.update(self.statistics.get_info()) 1448 1449 … … 1450 1451 total_pixels = 0 1451 1452 total_time = 0.0 1452 1453 in_latencies, out_latencies = [], [] 1454 winfo = {} 1453 1455 for wid in window_ids: 1454 1456 ws = self.window_sources.get(wid) 1455 1457 if ws is None: 1456 1458 continue 1457 1459 #per-window source stats: 1458 updict(info, "window[%i]" % wid, ws.get_info())1460 winfo[wid] = ws.get_info() 1459 1461 #collect stats for global averages: 1460 1462 for _, _, pixels, _, _, encoding_time in list(ws.statistics.encoding_stats): 1461 1463 total_pixels += pixels … … 1462 1464 total_time += encoding_time 1463 1465 in_latencies += [x*1000 for _, _, _, x in list(ws.statistics.damage_in_latency)] 1464 1466 out_latencies += [x*1000 for _, _, _, x in list(ws.statistics.damage_out_latency)] 1467 updict(info, "window", winfo) 1465 1468 v = 0 1466 1469 if total_time>0: 1467 1470 v = int(total_pixels / total_time) 1468 info ["encoding.pixels_encoded_per_second"] = v1471 info.setdefault("encoding", {})["pixels_encoded_per_second"] = v 1469 1472 add_list_stats(info, "damage.in_latency", in_latencies, show_percentile=[9]) 1470 1473 add_list_stats(info, "damage.out_latency", out_latencies, show_percentile=[9]) 1471 1474 updict(info, "batch", self.global_batch_config.get_info()) … … 1473 1476 1474 1477 1475 1478 def send_info_response(self, info): 1476 self.send("info-response", info)1479 self.send("info-response", flatten_dict(info)) 1477 1480 1478 1481 1479 1482 def send_server_event(self, *args): -
xpra/server/source_stats.py
144 144 145 145 146 146 def get_info(self): 147 info = { 148 "damage.events" : self.damage_events_count, 149 "damage.packets_sent" : self.packet_count, 150 "encoding.decode_errors" : self.decode_errors, 147 info = {"damage" : { 148 "events" : self.damage_events_count, 149 "packets_sent" : self.packet_count, 150 }, 151 "encoding" : {"decode_errors" : self.decode_errors}, 151 152 } 152 153 qsizes = [x for _,x in list(self.compression_work_qsizes)] 153 154 add_list_stats(info, "damage.data_queue.size", qsizes) -
xpra/server/window/window_source.py
318 318 """ 319 319 info = { 320 320 "dimensions" : self.window_dimensions, 321 "encoding" : self.encoding,322 321 "suspended" : self.suspended or False 323 322 } 324 323 def up(prefix, d): … … 327 326 up("av-sync", {"current" : self.av_sync_delay, 328 327 "target" : self.av_sync_delay_target}) 329 328 #heuristics 330 up("encoding.lossless_threshold", { 331 "base" : self._lossless_threshold_base, 332 "pixel_boost" : self._lossless_threshold_pixel_boost}) 329 up("encoding", {"" : self.encoding, 330 "lossless_threshold" : { 331 "base" : self._lossless_threshold_base, 332 "pixel_boost" : self._lossless_threshold_pixel_boost} 333 }) 334 now = time.time() 335 buckets_info = {} 336 for i,x in enumerate(self.delta_pixel_data): 337 if x: 338 w, h, pixel_format, coding, store, buflen, _, hits, last_used = x 339 buckets_info[i] = w, h, pixel_format, coding, store, buflen, hits, int((now-last_used)*1000) 333 340 up("encoding", { 334 341 "rgb_threshold" : self._rgb_auto_threshold, 335 342 "mmap" : bool(self._mmap) and (self._mmap_size>0), … … 336 343 "last_used" : self.encoding_last_used or "", 337 344 "full-frames-only" : self.full_frames_only, 338 345 "supports-transparency" : self.supports_transparency, 339 "delta" : self.supports_delta, 340 "delta.buckets" : self.delta_buckets, 346 "delta" : {"" : self.supports_delta, 347 "buckets" : self.delta_buckets, 348 "bucket" : buckets_info, 349 }, 341 350 }) 342 351 if self.pixel_format: 343 352 info["pixel-format"] = self.pixel_format 344 now = time.time()345 for i,x in enumerate(self.delta_pixel_data):346 if x:347 w, h, pixel_format, coding, store, buflen, _, hits, last_used = x348 info["encoding.delta.bucket[%s]" % i] = w, h, pixel_format, coding, store, buflen, hits, int((now-last_used)*1000)349 353 up("encoding", self.get_quality_speed_info()) 350 354 try: 351 355 #ie: get_strict_encoding -> "strict_encoding" 352 info["encoding .selection"] = self.get_best_encoding.__name__.replace("get_", "")356 info["encoding"]["selection"] = self.get_best_encoding.__name__.replace("get_", "") 353 357 except: 354 358 pass 355 359 up("property", self.get_property_info()) … … 366 370 }) 367 371 larm = self.last_auto_refresh_message 368 372 if larm: 369 up("encodings.auto-refresh.last-event", { 370 "elapsed" : int(1000*(time.time()-larm[0])), 371 "message" : larm[1], 372 }) 373 up("encodings", {"auto-refresh" : {"last-event" : { 374 "elapsed" : int(1000*(time.time()-larm[0])), 375 "message" : larm[1], 376 } 377 } 378 }) 373 379 up("icons", self.icons_encoding_options) 374 380 idata = self.window_icon_data 375 381 if idata: -
xpra/server/window/window_stats.py
153 153 154 154 155 155 def get_info(self): 156 info = { 157 "damage.events" : self.damage_events_count,158 "damage.packets_sent" : self.packet_count}156 info = {"damage" : {"events" : self.damage_events_count, 157 "packets_sent" : self.packet_count} 158 } 159 159 #encoding stats: 160 160 if len(self.encoding_stats)>0: 161 161 estats = list(self.encoding_stats) -
xpra/server/window/window_video_source.py
158 158 if ve: 159 159 info["encoder"] = ve.get_type() 160 160 up("encoder", ve.get_info()) 161 up("encoding.pipeline_param", self.get_pipeline_info())162 info["encodings.non-video"] = self.non_video_encodings163 info["encodings.edge"] = self.edge_encoding or ""161 info["encodings"] = {"non-video" : self.non_video_encodings, 162 "edge" : self.edge_encoding or ""} 163 einfo = {"pipeline_param" : self.get_pipeline_info()} 164 164 if self._last_pipeline_check>0: 165 info["encoding.pipeline_last_check"] = int(1000*(time.time()-self._last_pipeline_check))165 einfo["pipeline_last_check"] = int(1000*(time.time()-self._last_pipeline_check)) 166 166 lps = self.last_pipeline_scores 167 167 if lps: 168 popts = {} 168 169 for i, lp in enumerate(lps): 169 up("encoding.pipeline_option[%s]" % i, self.get_pipeline_score_info(*lp)) 170 popts[i] = self.get_pipeline_score_info(*lp) 171 einfo["pipeline_option"] = popts 172 up("encoding", einfo) 170 173 return info 171 174 172 175 def get_pipeline_info(self): -
xpra/simple_stats.py
7 7 # Simple statistical functions 8 8 9 9 from math import sqrt, pow 10 from xpra.util import updict 10 11 11 12 def to_std_unit(v, unit=1000): 12 13 if v>=unit**3: … … 69 70 return values_to_scaled_values(absolute_to_diff_values(data), scale_unit=scale_unit, min_scaled_value=min_scaled_value, num_values=num_values) 70 71 71 72 def add_weighted_list_stats(info, basename, weighted_values, show_percentile=False): 73 updict(info, basename, get_weighted_list_stats(weighted_values, show_percentile)) 74 75 def get_weighted_list_stats(weighted_values, show_percentile=False): 72 76 values = [x for x, _ in weighted_values] 73 77 if len(values)==0: 74 return 75 info["%s.min" % basename] = int(min(values)) 76 info["%s.max" % basename] = int(max(values)) 78 return {} 77 79 #weighted mean: 78 80 tw = 0 79 81 tv = 0 … … 81 83 tw += w 82 84 tv += v * w 83 85 avg = tv/tw 84 info["%s.avg" % basename] = int(avg) 86 stats = { 87 "min" : int(min(values)), 88 "max" : int(max(values)), 89 "avg" : int(avg), 90 } 85 91 if show_percentile: 86 92 #percentile 87 93 svalues = sorted(values) … … 88 94 for i in range(1,10): 89 95 pct = i*10 90 96 index = len(values)*i//10 91 info["%s.%sp" % (basename, pct)] = int(svalues[index]) 97 stats["%ip" % pct] = int(svalues[index]) 98 return stats 92 99 100 93 101 def find_invpow(x, n): 94 102 """Finds the integer component of the n'th root of x, 95 103 an integer such that y ** n <= x < (y + 1) ** n. … … 109 117 return mid + 1 110 118 111 119 def add_list_stats(info, basename, in_values, show_percentile=[5, 8, 9], show_dev=False): 120 updict(info, basename, get_list_stats(in_values, show_percentile, show_dev)) 121 122 def get_list_stats(in_values, show_percentile=[5, 8, 9], show_dev=False): 112 123 #this may be backed by a deque/list whichi is used by other threads 113 124 #so make a copy before use: 114 125 values = list(in_values) 115 126 if len(values)==0: 116 return 117 info["%s.cur" % basename] = int(values[-1]) 118 info["%s.min" % basename] = int(min(values)) 119 info["%s.max" % basename] = int(max(values)) 127 return {} 120 128 #arithmetic mean 121 129 avg = sum(values)/len(values) 122 info["%s.avg" % basename] = int(avg) 130 lstats = { 131 "cur" : int(values[-1]), 132 "min" : int(min(values)), 133 "max" : int(max(values)), 134 "avg" : int(avg), 135 } 123 136 if show_dev: 124 137 p = 1 #geometric mean 125 138 h = 0 #harmonic mean … … 133 146 var += (x-avg)**2 134 147 #standard deviation: 135 148 std = sqrt(var/len(values)) 136 info["%s.std" % basename] = int(std)149 lstats["std"] = int(std) 137 150 if avg!=0: 138 151 #coefficient of variation 139 info["%s.cv_pct" % basename] = int(100.0*std/avg)152 lstats["cv_pct"] = int(100.0*std/avg) 140 153 if counter>0 and p<float('inf'): 141 154 #geometric mean 142 155 try: … … 143 156 v = int(pow(p, 1.0/counter)) 144 157 except OverflowError: 145 158 v = find_invpow(p, counter) 146 info["%s.gm" % basename] = v159 lstats["gm"] = v 147 160 if h!=0: 148 161 #harmonic mean 149 info["%s.h" % basename] = int(counter/h)162 lstats["h"] = int(counter/h) 150 163 if show_percentile: 151 164 #percentile 152 165 svalues = sorted(values) … … 153 166 for i in show_percentile: 154 167 pct = i*10 155 168 index = len(values)*i//10 156 info["%s.%sp" % (basename, pct)] = int(svalues[index]) 169 lstats["%ip" % pct] = int(svalues[index]) 170 return lstats -
xpra/sound/pulseaudio/pulseaudio_pactl_util.py
9 9 10 10 from xpra.sound.pulseaudio.pulseaudio_common_util import get_pulse_server_x11_property, get_pulse_id_x11_property 11 11 from xpra.scripts.exec_util import safe_exec 12 from xpra.util import nonl 12 from xpra.util import nonl, updict 13 13 14 14 from xpra.log import Logger 15 15 log = Logger("sound") … … 174 174 175 175 176 176 def get_info(): 177 info = { 178 "pulseaudio.wrapper": "pactl", 179 "pulseaudio.found" : has_pa(), 180 "pulseaudio.id" : get_pulse_id(), 181 "pulseaudio.server" : get_pulse_server(False), 182 } 177 info = {} 178 updict(info, "pulseaudio", { 179 "wrapper" : "pactl", 180 "found" : has_pa(), 181 "id" : get_pulse_id(), 182 "server" : get_pulse_server(False), 183 }) 183 184 i = 0 185 dinfo = {} 184 186 for monitors in (True, False): 185 187 for io in (True, False): 186 188 devices = get_pa_device_options(monitors, io, log_errors=False) 187 189 for d,name in devices.items(): 188 info["device.%s" %d] = name190 dinfo[d] = name 189 191 i += 1 192 info["device"] = dinfo 190 193 info["devices"] = i 191 194 return info 192 195 -
xpra/sound/src.py
173 173 if self.caps: 174 174 info["caps"] = self.caps 175 175 if self.queue: 176 info["queue .cur"] = self.queue.get_property("current-level-time")//MS_TO_NS176 info["queue"] = {"cur" : self.queue.get_property("current-level-time")//MS_TO_NS} 177 177 if self.buffer_latency: 178 178 for x in ("actual-buffer-time", "actual-latency-time"): 179 179 v = self.src.get_property(x) -
xpra/util.py
500 500 return int(v+0.5) 501 501 502 502 503 504 def flatten_dict(info): 505 to = {} 506 def add_dict(path, d): 507 for k,v in d.items(): 508 if path: 509 npath = path+"."+str(k) 510 else: 511 npath = str(k) 512 if isinstance(v, dict): 513 add_dict(npath, v) 514 elif v is not None: 515 to[npath] = v 516 add_dict(None, info) 517 return to 518 503 519 #used for merging dicts with a prefix and suffix 504 520 #non-None values get added to <todict> with a prefix and optional suffix 505 521 def updict(todict, prefix, d, suffix=""): -
xpra/x11/server.py
290 290 info["focused"] = self._has_focus 291 291 info["grabbed"] = self._has_grab 292 292 log("do_get_info: adding cursor=%s", self.last_cursor_data) 293 updict(info, "cursor", self.get_cursor_info()) 294 return info 295 296 def get_cursor_info(self): 297 #(NOT from UI thread) 293 298 #copy to prevent race: 294 299 cd = self.last_cursor_data 295 300 if cd is None: 296 info["cursor"] = "None" 297 else: 298 info["cursor.is_default"] = bool(self.default_cursor_data and len(self.default_cursor_data)>=8 and len(cd)>=8 and cd[7]==cd[7]) 299 #all but pixels: 300 for i, x in enumerate(("x", "y", "width", "height", "xhot", "yhot", "serial", None, "name")): 301 if x: 302 v = cd[i] or "" 303 info["cursor." + x] = v 304 return info 301 return {"" : "None"} 302 cinfo = {"is_default" : bool(self.default_cursor_data and len(self.default_cursor_data)>=8 and len(cd)>=8 and cd[7]==cd[7])} 303 #all but pixels: 304 for i, x in enumerate(("x", "y", "width", "height", "xhot", "yhot", "serial", None, "name")): 305 if x: 306 v = cd[i] or "" 307 cinfo[x] = v 308 return cinfo 305 309 306 310 def get_ui_info(self, proto, wids=None, *args): 307 311 info = X11ServerBase.get_ui_info(self, proto, wids, *args) … … 309 313 wm = self._wm 310 314 if wm: 311 315 info["window-manager-name"] = wm.get_net_wm_name() 316 info.setdefault("cursor", {}).update(self.get_ui_cursor_info()) 317 return info 318 319 def get_ui_cursor_info(self): 320 #(from UI thread) 312 321 #now cursor size info: 313 322 display = gtk.gdk.display_get_default() 314 323 pos = display.get_default_screen().get_root_window().get_pointer()[:2] 315 info["cursor.position"] = pos324 cinfo = {"position" : pos} 316 325 for prop, size in {"default" : display.get_default_cursor_size(), 317 326 "max" : display.get_maximal_cursor_size()}.items(): 318 327 if size is None: 319 328 continue 320 info["cursor.%s_size" % prop] = size321 return info329 cinfo["%s_size" % prop] = size 330 return cinfo 322 331 323 332 324 333 def get_window_info(self, window): 325 334 info = X11ServerBase.get_window_info(self, window) 326 info["focused"] = self._has_focus and self._window_to_id.get(window, -1)==self._has_focus 327 info["grabbed"] = self._has_grab and self._window_to_id.get(window, -1)==self._has_grab 328 info["geometry"] = window.get_property("geometry") 329 info["shown"] = self._desktop_manager.is_shown(window) 335 info.update({ 336 "focused" : self._has_focus and self._window_to_id.get(window, -1)==self._has_focus, 337 "grabbed" : self._has_grab and self._window_to_id.get(window, -1)==self._has_grab, 338 "geometry" : window.get_property("geometry"), 339 "shown" : self._desktop_manager.is_shown(window), 340 }) 330 341 try: 331 342 info["client-geometry"] = self._desktop_manager.window_geometry(window) 332 343 except: -
xpra/x11/server_keyboard_config.py
12 12 log = Logger("keyboard") 13 13 14 14 15 from xpra.util import csv 15 from xpra.util import csv, updict 16 16 from xpra.gtk_common.keymap import get_gtk_keymap 17 17 from xpra.x11.gtk_x11.keys import grok_modifier_map 18 18 from xpra.keyboard.mask import DEFAULT_MODIFIER_NUISANCE, DEFAULT_MODIFIER_NUISANCE_KEYNAMES, mask_to_names … … 65 65 66 66 def get_info(self): 67 67 info = KeyboardConfigBase.get_info(self) 68 info["modifiers.filter"] = self.modifiers_filter69 68 #keycodes: 70 69 if self.keycode_translation: 71 70 for kc, keycode in self.keycode_translation.items(): … … 82 81 info["keymap.%s" % i] = (keyval, name, keycode, group, level) 83 82 i += 1 84 83 #modifiers: 84 modinfo = {} 85 modsinfo = {} 86 modinfo["filter"] = self.modifiers_filter 85 87 if self.modifier_client_keycodes: 86 88 for mod, keys in self.modifier_client_keycodes.items(): 87 info["modifier." + mod + ".client_keys"] = keys89 modinfo.setdefault(mod, {})["client_keys"] = keys 88 90 if self.keynames_for_mod: 89 91 for mod, keys in self.keynames_for_mod.items(): 90 info["modifier." + mod + ".keys"] = tuple(keys)92 modinfo.setdefault(mod, {})["keys"] = tuple(keys) 91 93 if self.keycodes_for_modifier_keynames: 92 94 for mod, keys in self.keycodes_for_modifier_keynames.items(): 93 info["modifier." + mod + ".keycodes"] = tuple(keys)95 modinfo.setdefault(mod, {})["keycodes"] = tuple(keys) 94 96 if self.xkbmap_mod_meanings: 95 97 for mod, mod_name in self.xkbmap_mod_meanings.items(): 96 info["modifier." + mod ] = mod_name 97 if self.xkbmap_x11_keycodes: 98 for keycode, keysyms in self.xkbmap_x11_keycodes.items(): 99 info["x11_keycode." + str(keycode) ] = keysyms 98 modinfo[mod] = mod_name 99 updict(info, "x11_keycode", self.xkbmap_x11_keycodes) 100 100 for x in ("print", "layout", "variant"): 101 101 v = getattr(self, "xkbmap_"+x) 102 102 if v: … … 104 104 for x in ("nuisance", ): 105 105 v = getattr(self, "xkbmap_mod_"+x) 106 106 if v: 107 info["modifiers."+x] = list(v)107 modsinfo[x] = list(v) 108 108 for x in ("managed", "pointermissing"): 109 109 v = getattr(self, "xkbmap_mod_"+x) 110 110 if v: 111 info["modifiers."+x] = v 111 modsinfo[x] = v 112 updict(info, "modifier", modinfo) 113 updict(info, "modifiers", modsinfo) 112 114 log("keyboard info: %s", "\n".join(["%s=%s" % (k,v) for k,v in info.items()])) 113 115 return info 114 116 -
xpra/x11/shadow_x11_server.py
95 95 96 96 def get_info(self, proto): 97 97 info = X11ServerBase.get_info(self, proto) 98 info ["features.shadow"] = True99 info ["server.type"] = "Python/gtk2/x11-shadow"98 info.setdefault("features", {})["shadow"] = True 99 info.setdefault("server", {})["type"] = "Python/gtk2/x11-shadow" 100 100 return info -
xpra/x11/x11_server_base.py
127 127 v = parts[1].strip() 128 128 self.opengl_props[k] = v 129 129 else: 130 self.opengl_props["error"] = str(err) 130 self.opengl_props["error"] = str(err).strip("\n\r") 131 131 except Exception as e: 132 132 gllog.warn("Warning: failed to query OpenGL properties") 133 133 gllog.warn(" %s", e) … … 218 218 info = GTKServerBase.do_get_info(self, proto, server_sources, window_ids) 219 219 if self.opengl_props: 220 220 updict(info, "opengl", self.opengl_props) 221 info["server.type"] = "Python/gtk/x11" 221 #this is added here because the server keyboard config doesn't know about "keys_pressed".. 222 updict(info, "keyboard", { 223 "state" : {"keys_pressed" : list(self.keys_pressed.keys())}, 224 "fast-switching" : True, 225 }) 222 226 try: 227 fx = find_libfakeXinerama() 228 except: 229 fx = None 230 sinfo = {"type" : "Python/gtk/x11", 231 "fakeXinerama" : self.fake_xinerama and bool(fx), 232 "libfakeXinerama" : fx or "", 233 "Xkb" : X11Keyboard.hasXkb(), 234 "XTest" : X11Keyboard.hasXTest()} 235 try: 223 236 from xpra.x11.gtk2.composite import CompositeHelper 224 info["server.XShm"] = CompositeHelper.XShmEnabled237 sinfo["XShm"] = CompositeHelper.XShmEnabled 225 238 except: 226 239 pass 227 240 #randr: … … 228 241 try: 229 242 sizes = RandR.get_screen_sizes() 230 243 if self.randr and len(sizes)>=0: 231 info["server.randr.options"] = list(reversed(sorted(sizes)))244 sinfo["randr"] = {"options" : list(reversed(sorted(sizes)))} 232 245 except: 233 246 pass 234 try: 235 fx = find_libfakeXinerama() 236 except: 237 fx = None 238 info["server.fakeXinerama"] = self.fake_xinerama and bool(fx) 239 info["server.libfakeXinerama"] = fx or "" 240 #this is added here because the server keyboard config doesn't know about "keys_pressed".. 241 info["keyboard.state.keys_pressed"] = list(self.keys_pressed.keys()) 242 info["keyboard.fast-switching"] = True 243 info["server.Xkb"] = X11Keyboard.hasXkb() 244 info["server.XTest"] = X11Keyboard.hasXTest() 247 updict(info, "server", sinfo) 245 248 return info 246 249 247 250 def get_window_info(self, window):