Exemple #1
0
 def get_screen_sizes(self, xscale=1, yscale=1):
     def xs(v):
         return iround(v/xscale)
     def ys(v):
         return iround(v/yscale)
     def swork(*workarea):
         return xs(workarea[0]), ys(workarea[1]), xs(workarea[2]), ys(workarea[3])
     display = display_get_default()
     i=0
     screen_sizes = []
     n_screens = display.get_n_screens()
     screenlog("get_screen_sizes(%f, %f) found %s screens", xscale, yscale, n_screens)
     while i<n_screens:
         screen = display.get_screen(i)
         j = 0
         monitors = []
         workareas = []
         #native "get_workareas()" is only valid for a single screen (but describes all the monitors)
         #and it is only implemented on win32 right now
         #other platforms only implement "get_workarea()" instead, which is reported against the screen
         n_monitors = screen.get_n_monitors()
         screenlog(" screen %s has %s monitors", i, n_monitors)
         if n_screens==1:
             workareas = get_workareas()
             if len(workareas)!=n_monitors:
                 screenlog(" workareas: %s", workareas)
                 screenlog(" number of monitors does not match number of workareas!")
                 workareas = []
         while j<screen.get_n_monitors():
             geom = screen.get_monitor_geometry(j)
             plug_name = ""
             if hasattr(screen, "get_monitor_plug_name"):
                 plug_name = screen.get_monitor_plug_name(j) or ""
             wmm = -1
             if hasattr(screen, "get_monitor_width_mm"):
                 wmm = screen.get_monitor_width_mm(j)
             hmm = -1
             if hasattr(screen, "get_monitor_height_mm"):
                 hmm = screen.get_monitor_height_mm(j)
             monitor = [plug_name, xs(geom.x), ys(geom.y), xs(geom.width), ys(geom.height), wmm, hmm]
             screenlog(" monitor %s: %s", j, monitor)
             if workareas:
                 w = workareas[j]
                 monitor += list(swork(*w))
             monitors.append(tuple(monitor))
             j += 1
         work_x, work_y, work_width, work_height = swork(0, 0, screen.get_width(), screen.get_height())
         workarea = get_workarea()
         if workarea:
             work_x, work_y, work_width, work_height = swork(*workarea)
         screenlog(" workarea=%s", workarea)
         item = (screen.make_display_name(), xs(screen.get_width()), ys(screen.get_height()),
                     screen.get_width_mm(), screen.get_height_mm(),
                     monitors,
                     work_x, work_y, work_width, work_height)
         screenlog(" screen %s: %s", i, item)
         screen_sizes.append(item)
         i += 1
     return screen_sizes
 def update(self):
     old_hash = self.hash
     self.query_xkbmap()
     try:
         self.keyboard.update_modifier_map(display_get_default(), self.xkbmap_mod_meanings)
     except:
         log.error("error querying modifier map", exc_info=True)
     log("do_keys_changed() modifier_map=%s, old hash=%s, new hash=%s", self.keyboard.modifier_map, old_hash, self.hash)
     return old_hash!=self.hash
Exemple #3
0
 def process_ui_capabilities(self, capabilities):
     UIXpraClient.process_ui_capabilities(self, capabilities)
     if self.server_randr:
         display = display_get_default()
         i=0
         while i<display.get_n_screens():
             screen = display.get_screen(i)
             screen.connect("size-changed", self.screen_size_changed)
             i += 1
Exemple #4
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     if len(cursor_data)>=9 and cursor_types:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name, gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels)<w*h*4:
         import binascii
         cursorlog.warn("not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)", w*h*4, len(pixels), binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w*4)
     x = max(0, min(xhot, w-1))
     y = max(0, min(yhot, h-1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data)>=11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog("new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s", xhot,yhot, serial, w,h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw>0 and fh>0 and (w!=fw or h!=fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w<=fw and h<=fh:
             cursorlog("pasting cursor of size %ix%i onto clear pixbuf of size %ix%i", w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0"*fw*fh*4, True, fw, fh, fw*4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i", w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w)/fw, float(h)/fh
             x, y = int(x/xratio), int(y/yratio)
     elif w>cmaxw or h>cmaxh or (csize>0 and (csize<w or csize<h)):
         ratio = max(float(w)/cmaxw, float(h)/cmaxh, float(max(w,h))/csize)
         x, y, w, h = int(x/ratio), int(y/ratio), int(w/ratio), int(h/ratio)
         cursorlog("downscaling cursor %s by %.2f: %sx%s", pixbuf, ratio, w, h)
         cursor_pixbuf = pixbuf.scale_simple(w, h, INTERP_BILINEAR)
     else:
         cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w-1))
     y = max(0, min(y, h-1))
     return new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)
Exemple #5
0
 def get_ui_cursor_info(self):
     #(from UI thread)
     #now cursor size info:
     display = display_get_default()
     pos = display.get_default_screen().get_root_window().get_pointer(
     )[-3:-1]
     cinfo = {"position": pos}
     for prop, size in {
             "default": display.get_default_cursor_size(),
             "max": tuple(display.get_maximal_cursor_size()),
     }.items():
         if size is None:
             continue
         cinfo["%s_size" % prop] = size
     return cinfo
Exemple #6
0
 def make_hello(self, source):
     capabilities = ServerBase.make_hello(self, source)
     if source.wants_display:
         display = display_get_default()
         max_size = tuple(display.get_maximal_cursor_size())
         capabilities.update({
             "display":
             display.get_name(),
             "cursor.default_size":
             display.get_default_cursor_size(),
             "cursor.max_size":
             max_size,
         })
     if source.wants_versions:
         capabilities.update(flatten_dict(get_gtk_version_info()))
     return capabilities
Exemple #7
0
 def load_existing_windows(self):
     #at present, just one  window is forwarded:
     #the root window covering the whole display
     display = display_get_default()
     screens = display.get_n_screens()
     with xsync:
         for n in range(screens):
             screen = display.get_screen(n)
             root = screen.get_root_window()
             model = DesktopModel(root, self.randr_exact_size)
             model.setup()
             windowlog("adding root window model %s", model)
             super(XpraDesktopServer, self)._add_new_window_common(model)
             model.managed_connect("client-contents-changed",
                                   self._contents_changed)
             model.managed_connect("resized", self._window_resized_signaled)
Exemple #8
0
def get_gtk_keymap(ignore_keys=(None, "VoidSymbol", "0xffffff")):
    """
        Augment the keymap we get from gtk.gdk.keymap_get_default()
        by adding the keyval_name.
        We can also ignore some keys
    """
    from xpra.gtk_common.gtk_util import keymap_get_for_display, display_get_default, import_gdk, is_gtk3
    gdk = import_gdk()
    display = display_get_default()
    if not display:
        return ()
    keymap = keymap_get_for_display(display)
    log(
        "keymap_get_for_display(%s)=%s, direction=%s, bidirectional layouts: %s",
        display, keymap, keymap.get_direction(), keymap.have_bidi_layouts())
    keycodes = []
    for i in range(0, 2**8):
        entries = keymap.get_entries_for_keycode(i)
        log("get_entries_for_keycode(%s)=%s", i, entries)
        if not entries:
            continue
        if is_gtk3():
            found, keys, keyvals = entries
            if not found:
                continue
            for j, key in enumerate(keys):
                keyval = keyvals[j]
                keycode = key.keycode
                name = gdk.keyval_name(keyval)
                name = KEY_TRANSLATIONS.get((name, keyval, keycode), name)
                group = key.group or 0
                if name not in ignore_keys:
                    keycodes.append((keyval or 0, name or "", keycode
                                     or 0, group, key.level or 0))
        else:
            #gtk2:
            for keyval, keycode, group, level in entries:
                #assert keycode==i
                name = gdk.keyval_name(keyval)
                name = KEY_TRANSLATIONS.get((name, keyval, keycode), name)
                if name not in ignore_keys:
                    keycodes.append((keyval or 0, name or "", keycode
                                     or 0, group or 0, level or 0))
    log("get_gtk_keymap(%s)=%s (keymap=%s)", ignore_keys, keycodes, keymap)
    return keycodes
Exemple #9
0
 def do_run(self):
     if UI_THREAD_WATCHER:
         from xpra.platform.ui_thread_watcher import get_UI_watcher
         self.ui_watcher = get_UI_watcher(glib.timeout_add,
                                          glib.source_remove)
         self.ui_watcher.start()
     if server_features.windows:
         display = display_get_default()
         i = 0
         while i < display.get_n_screens():
             screen = display.get_screen(i)
             screen.connect("size-changed", self._screen_size_changed)
             screen.connect("monitors-changed", self._monitors_changed)
             i += 1
     gtk_main_quit_on_fatal_exceptions_enable()
     log("do_run() calling %s", gtk_main)
     gtk_main()
     log("do_run() end of gtk.main()")
Exemple #10
0
 def get_screen_sizes(self):
     display = display_get_default()
     i = 0
     screen_sizes = []
     while i < display.get_n_screens():
         screen = display.get_screen(i)
         j = 0
         monitors = []
         while j < screen.get_n_monitors():
             geom = screen.get_monitor_geometry(j)
             plug_name = ""
             if hasattr(screen, "get_monitor_plug_name"):
                 plug_name = screen.get_monitor_plug_name(j) or ""
             wmm = -1
             if hasattr(screen, "get_monitor_width_mm"):
                 wmm = screen.get_monitor_width_mm(j)
             hmm = -1
             if hasattr(screen, "get_monitor_height_mm"):
                 hmm = screen.get_monitor_height_mm(j)
             monitor = plug_name, geom.x, geom.y, geom.width, geom.height, wmm, hmm
             monitors.append(monitor)
             j += 1
         work_x, work_y = 0, 0
         work_width, work_height = screen.get_width(), screen.get_height()
         if not sys.platform.startswith("win"):
             try:
                 p = gtk.gdk.atom_intern('_NET_WORKAREA')
                 root = screen.get_root_window()
                 work_x, work_y, work_width, work_height = root.property_get(
                     p)[2][:4]
             except:
                 pass
         item = (screen.make_display_name(), screen.get_width(),
                 screen.get_height(), screen.get_width_mm(),
                 screen.get_height_mm(), monitors, work_x, work_y,
                 work_width, work_height)
         screen_sizes.append(item)
         i += 1
     return screen_sizes
Exemple #11
0
 def get_screen_sizes(self):
     display = display_get_default()
     i=0
     screen_sizes = []
     while i<display.get_n_screens():
         screen = display.get_screen(i)
         j = 0
         monitors = []
         while j<screen.get_n_monitors():
             geom = screen.get_monitor_geometry(j)
             plug_name = ""
             if hasattr(screen, "get_monitor_plug_name"):
                 plug_name = screen.get_monitor_plug_name(j) or ""
             wmm = -1
             if hasattr(screen, "get_monitor_width_mm"):
                 wmm = screen.get_monitor_width_mm(j)
             hmm = -1
             if hasattr(screen, "get_monitor_height_mm"):
                 hmm = screen.get_monitor_height_mm(j)
             monitor = plug_name, geom.x, geom.y, geom.width, geom.height, wmm, hmm
             monitors.append(monitor)
             j += 1
         work_x, work_y = 0, 0
         work_width, work_height = screen.get_width(), screen.get_height()
         if not sys.platform.startswith("win"):
             try:
                 p = gtk.gdk.atom_intern('_NET_WORKAREA')
                 root = screen.get_root_window()
                 work_x, work_y, work_width, work_height = root.property_get(p)[2][:4]
             except:
                 pass
         item = (screen.make_display_name(), screen.get_width(), screen.get_height(),
                     screen.get_width_mm(), screen.get_height_mm(),
                     monitors,
                     work_x, work_y, work_width, work_height)
         screen_sizes.append(item)
         i += 1
     return screen_sizes
Exemple #12
0
def wm_check(wm_name, upgrading=False):
    with xsync:
        display = display_get_default()
        #there should only be one screen... but let's check all of them
        for i in range(display.get_n_screens()):
            screen = display.get_screen(i)
            root = screen.get_root_window()
            wm_prop = "WM_S%s" % i
            cwm_prop = "_NEW_WM_CM_S%s" % i
            wm_so = X11Window.XGetSelectionOwner(wm_prop)
            cwm_so = X11Window.XGetSelectionOwner(cwm_prop)
            log("ewmh selection owner for %s: %s", wm_prop, wm_so)
            log("compositing window manager %s: %s", cwm_prop, cwm_so)

            ewmh_wm = prop_get(root,
                               "_NET_SUPPORTING_WM_CHECK",
                               "window",
                               ignore_errors=True,
                               raise_xerrors=False)

            def xid(w):
                if w:
                    return "%#x" % get_xwindow(w)
                return None

            log("_NET_SUPPORTING_WM_CHECK for screen %i: %s (root=%s)", i,
                xid(ewmh_wm), xid(root))
            if not ewmh_wm:
                continue
            name = prop_get(ewmh_wm,
                            "_NET_WM_NAME",
                            "utf8",
                            ignore_errors=True,
                            raise_xerrors=False)
            if upgrading and name and name == wm_name:
                log.info("found previous Xpra instance")
            else:
                log.warn("Warning: found an existing window manager")
                log.warn(" on screen %s using window %#x: %s", i,
                         get_xwindow(ewmh_wm), name or "unknown")
            if (wm_so is None or wm_so == 0) and (cwm_so is None
                                                  or cwm_so == 0):
                if FORCE_REPLACE_WM:
                    log.warn(
                        "XPRA_FORCE_REPLACE_WM is set, replacing it forcibly")
                else:
                    log.error("it does not own the selection '%s' or '%s'",
                              wm_prop, cwm_prop)
                    log.error("so we cannot take over and make it exit")
                    log.error(
                        "please stop %s so you can run xpra on this display",
                        name or "the existing window manager")
                    log.warn(
                        "if you are certain that the window manager is already gone,"
                    )
                    log.warn(
                        " you may set XPRA_FORCE_REPLACE_WM=1 to force xpra to continue"
                    )
                    log.warn(" at your own risk")
                    return False
    return True
Exemple #13
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     cursorlog("make_cursor: has-name=%s, has-cursor-types=%s, xscale=%s, yscale=%s, USE_LOCAL_CURSORS=%s", len(cursor_data)>=9, bool(cursor_types), self.xscale, self.yscale, USE_LOCAL_CURSORS)
     #named cursors cannot be scaled (round to 10 to compare so 0.95 and 1.05 are considered the same as 1.0, no scaling):
     if len(cursor_data)>=9 and cursor_types and iround(self.xscale*10)==10 and iround(self.yscale*10)==10:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name and USE_LOCAL_CURSORS:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name, gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels)<w*h*4:
         import binascii
         cursorlog.warn("not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)", w*h*4, len(pixels), binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w*4)
     x = max(0, min(xhot, w-1))
     y = max(0, min(yhot, h-1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data)>=11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog("new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s", xhot,yhot, serial, w,h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw>0 and fh>0 and (w!=fw or h!=fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w<=fw and h<=fh:
             cursorlog("pasting cursor of size %ix%i onto clear pixbuf of size %ix%i", w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0"*fw*fh*4, True, fw, fh, fw*4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i", w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w)/fw, float(h)/fh
             x, y = iround(x/xratio), iround(y/yratio)
     else:
         sx, sy, sw, sh = x, y, w, h
         #scale the cursors:
         if self.xscale!=1 or self.yscale!=1:
             sx, sy, sw, sh = self.srect(x, y, w, h)
         sw = max(1, sw)
         sh = max(1, sh)
         #ensure we honour the max size if there is one:
         if (cmaxw>0 and sw>cmaxw) or (cmaxh>0 and sh>cmaxh):
             ratio = 1.0
             if cmaxw>0:
                 ratio = max(ratio, float(w)/cmaxw)
             if cmaxh>0:
                 ratio = max(ratio, float(h)/cmaxh)
             cursorlog("clamping cursor size to %ix%i using ratio=%s", cmaxw, cmaxh, ratio)
             sx, sy, sw, sh = iround(x/ratio), iround(y/ratio), min(cmaxw, iround(w/ratio)), min(cmaxh, iround(h/ratio))
         if sw!=w or sh!=h:
             cursorlog("scaling cursor from %ix%i hotspot at %ix%i to %ix%i hotspot at %ix%i", w, h, x, y, sw, sh, sx, sy)
             cursor_pixbuf = pixbuf.scale_simple(sw, sh, INTERP_BILINEAR)
             x, y = sx, sy
         else:
             cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w-1))
     y = max(0, min(y, h-1))
     try:
         c = new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)
     except RuntimeError as e:
         log.error("Error: failed to create cursor:")
         log.error(" %s", e)
         log.error(" using %s of size %ix%i with hotspot at %ix%i", cursor_pixbuf, w, h, x, y)
         c = None
     return c
Exemple #14
0
 def send_initial_cursors(self, ss, _sharing=False):
     #cursors: get sizes and send:
     display = display_get_default()
     self.cursor_sizes = display.get_default_cursor_size(), display.get_maximal_cursor_size()
     cursorlog("send_initial_cursors() cursor_sizes=%s", self.cursor_sizes)
     ss.send_cursor()
Exemple #15
0
 def get_cursor_sizes(self):
     display = display_get_default()
     return display.get_default_cursor_size(
     ), display.get_maximal_cursor_size()
Exemple #16
0
    def __init__(self, alpha=False):
        display = display_get_default()
        screen = display.get_default_screen()
        bpc = 8
        attrs = c_attrs({
            GLX.GLX_RGBA: True,
            GLX.GLX_RED_SIZE: bpc,
            GLX.GLX_GREEN_SIZE: bpc,
            GLX.GLX_BLUE_SIZE: bpc,
            GLX.GLX_ALPHA_SIZE: int(alpha) * bpc,
            GLX.GLX_DOUBLEBUFFER: int(DOUBLE_BUFFERED),
        })
        self.props = {}
        self.xdisplay = get_xdisplay()
        xvinfo = GLX.glXChooseVisual(self.xdisplay, screen.get_number(), attrs)

        def getconfig(attrib):
            value = c_int()
            r = GLX.glXGetConfig(self.xdisplay, xvinfo, attrib, byref(value))
            assert r == 0, "glXGetConfig returned %i" % r
            return value.value

        assert getconfig(
            GLX.GLX_USE_GL), "OpenGL is not supported by this visual!"
        major = c_int()
        minor = c_int()
        assert GLX.glXQueryVersion(self.xdisplay, byref(major), byref(minor))
        log("found GLX version %i.%i", major.value, minor.value)
        self.props["GLX"] = (major.value, minor.value)
        self.bit_depth = getconfig(GLX.GLX_RED_SIZE) + getconfig(
            GLX.GLX_GREEN_SIZE) + getconfig(GLX.GLX_BLUE_SIZE) + getconfig(
                GLX.GLX_ALPHA_SIZE)
        self.props["depth"] = self.bit_depth
        self.props["has-depth-buffer"] = getconfig(GLX.GLX_DEPTH_SIZE) > 0
        self.props["has-stencil-buffer"] = getconfig(GLX.GLX_STENCIL_SIZE) > 0
        self.props["has-alpha"] = getconfig(GLX.GLX_ALPHA_SIZE) > 0
        for attrib, name in {
                GLX.GLX_ACCUM_RED_SIZE: "accum-red-size",
                GLX.GLX_ACCUM_GREEN_SIZE: "accum-green-size",
                GLX.GLX_ACCUM_BLUE_SIZE: "accum-blue-size",
                GLX.GLX_ACCUM_ALPHA_SIZE: "accum-alpha-size",
                GLX.GLX_RED_SIZE: "red-size",
                GLX.GLX_GREEN_SIZE: "green-size",
                GLX.GLX_BLUE_SIZE: "blue-size",
                GLX.GLX_ALPHA_SIZE: "alpha-size",
                GLX.GLX_DEPTH_SIZE: "depth-size",
                GLX.GLX_STENCIL_SIZE: "stencil-size",
                GLX.GLX_BUFFER_SIZE: "buffer-size",
                GLX.GLX_AUX_BUFFERS: "aux-buffers",
                GLX.GLX_DOUBLEBUFFER: "double-buffered",
                GLX.GLX_LEVEL: "level",
                GLX.GLX_STEREO: "stereo",
                GLX.GLX_RGBA: "rgba",
        }.items():
            v = getconfig(attrib)
            if name in ("stereo", "double-buffered", "rgba"):
                v = bool(v)
            self.props[name] = v
        #attribute names matching gtkgl:
        display_mode = []
        if getconfig(GLX.GLX_RGBA):
            #this particular context may not have alpha channel support...
            #but if we have RGBA then it's almost guaranteed that we can do ALPHA
            display_mode.append("ALPHA")
        if getconfig(GLX.GLX_DOUBLEBUFFER):
            display_mode.append("DOUBLE")
        else:
            display_mode.append("SINGLE")
        self.props["display_mode"] = display_mode
        self.context = GLX.glXCreateContext(self.xdisplay, xvinfo, None, True)
        self.props["direct"] = bool(
            GLX.glXIsDirect(self.xdisplay, self.context))
        self.props["vendor"] = glGetString(GL_VENDOR)
        self.props["renderer"] = glGetString(GL_RENDERER)
        log("GLXContext(%s) context=%s, props=%s", alpha, self.context,
            self.props)
Exemple #17
0
 def _move_pointer(self, _wid, pos, *_args):
     x, y = pos
     display = display_get_default()
     display.warp_pointer(display.get_default_screen(), x, y)
Exemple #18
0
    def __init__(self, alpha=False):
        self.props = {}
        self.xdisplay = None
        self.context = None
        self.bit_depth = 0
        display = display_get_default()
        if not display:
            log.warn("Warning: GLXContext: no default display")
            return
        screen = display.get_default_screen()
        bpc = 8
        pyattrs = {
            GLX.GLX_RGBA: None,
            GLX.GLX_RED_SIZE: bpc,
            GLX.GLX_GREEN_SIZE: bpc,
            GLX.GLX_BLUE_SIZE: bpc,
        }
        if alpha:
            pyattrs[GLX.GLX_ALPHA_SIZE] = int(alpha) * bpc
        if DOUBLE_BUFFERED:
            pyattrs[GLX.GLX_DOUBLEBUFFER] = None
        attrs = c_attrs(pyattrs)
        self.xdisplay = get_xdisplay()
        xvinfo = GLX.glXChooseVisual(self.xdisplay, screen.get_number(), attrs)

        def getconfig(attrib):
            value = c_int()
            r = GLX.glXGetConfig(self.xdisplay, xvinfo, attrib, byref(value))
            assert r == 0, "glXGetConfig returned %i" % r
            return value.value

        assert getconfig(
            GLX.GLX_USE_GL), "OpenGL is not supported by this visual!"
        major = c_int()
        minor = c_int()
        assert GLX.glXQueryVersion(self.xdisplay, byref(major), byref(minor))
        log("found GLX version %i.%i", major.value, minor.value)
        self.props["GLX"] = (major.value, minor.value)
        self.bit_depth = sum(
            getconfig(x) for x in (GLX.GLX_RED_SIZE, GLX.GLX_GREEN_SIZE,
                                   GLX.GLX_BLUE_SIZE, GLX.GLX_ALPHA_SIZE))
        self.props["depth"] = self.bit_depth
        self.props["has-depth-buffer"] = getconfig(GLX.GLX_DEPTH_SIZE) > 0
        self.props["has-stencil-buffer"] = getconfig(GLX.GLX_STENCIL_SIZE) > 0
        self.props["has-alpha"] = getconfig(GLX.GLX_ALPHA_SIZE) > 0
        for attrib, name in GLX_ATTRIBUTES.items():
            v = getconfig(attrib)
            if name in ("stereo", "double-buffered", "rgba"):
                v = bool(v)
            self.props[name] = v
        #attribute names matching gtkgl:
        display_mode = []
        if getconfig(GLX.GLX_RGBA):
            #this particular context may not have alpha channel support...
            #but if we have RGBA then it's almost guaranteed that we can do ALPHA
            display_mode.append("ALPHA")
        if getconfig(GLX.GLX_DOUBLEBUFFER):
            display_mode.append("DOUBLE")
        else:
            display_mode.append("SINGLE")
        self.props["display_mode"] = display_mode
        self.context = GLX.glXCreateContext(self.xdisplay, xvinfo, None, True)
        self.props["direct"] = bool(
            GLX.glXIsDirect(self.xdisplay, self.context))

        def getstr(k):
            try:
                return glGetString(k)
            except Exception as e:
                self.props["safe"] = False
                result = getattr(e, "result", None)
                if result and isinstance(result, str):
                    return result
                raise

        self.props["vendor"] = getstr(GL_VENDOR)
        self.props["renderer"] = getstr(GL_RENDERER)
        log("GLXContext(%s) context=%s, props=%s", alpha, self.context,
            self.props)
Exemple #19
0
 def compute_modifier_map(self):
     self.modifier_map = grok_modifier_map(display_get_default(),
                                           self.xkbmap_mod_meanings)
     log("modifier_map(%s)=%s", self.xkbmap_mod_meanings, self.modifier_map)
Exemple #20
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     cursorlog(
         "make_cursor: has-name=%s, has-cursor-types=%s, xscale=%s, yscale=%s, USE_LOCAL_CURSORS=%s",
         len(cursor_data) >= 9, bool(cursor_types), self.xscale,
         self.yscale, USE_LOCAL_CURSORS)
     #named cursors cannot be scaled (round to 10 to compare so 0.95 and 1.05 are considered the same as 1.0, no scaling):
     if len(cursor_data) >= 9 and cursor_types and iround(
             self.xscale * 10) == 10 and iround(self.yscale * 10) == 10:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name and USE_LOCAL_CURSORS:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name,
                           gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels) < w * h * 4:
         import binascii
         cursorlog.warn(
             "not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)",
             w * h * 4, len(pixels),
             binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w * 4)
     x = max(0, min(xhot, w - 1))
     y = max(0, min(yhot, h - 1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data) >= 11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog(
         "new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s",
         xhot, yhot, serial, w, h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw > 0 and fh > 0 and (w != fw or h != fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w <= fw and h <= fh:
             cursorlog(
                 "pasting cursor of size %ix%i onto clear pixbuf of size %ix%i",
                 w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0" * fw * fh * 4, True,
                                                  fw, fh, fw * 4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i",
                       w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w) / fw, float(h) / fh
             x, y = iround(x / xratio), iround(y / yratio)
     else:
         sx, sy, sw, sh = x, y, w, h
         #scale the cursors:
         if self.xscale != 1 or self.yscale != 1:
             sx, sy, sw, sh = self.srect(x, y, w, h)
         sw = max(1, sw)
         sh = max(1, sh)
         #ensure we honour the max size if there is one:
         if (cmaxw > 0 and sw > cmaxw) or (cmaxh > 0 and sh > cmaxh):
             ratio = 1.0
             if cmaxw > 0:
                 ratio = max(ratio, float(w) / cmaxw)
             if cmaxh > 0:
                 ratio = max(ratio, float(h) / cmaxh)
             cursorlog("clamping cursor size to %ix%i using ratio=%s",
                       cmaxw, cmaxh, ratio)
             sx, sy, sw, sh = iround(x / ratio), iround(y / ratio), min(
                 cmaxw, iround(w / ratio)), min(cmaxh, iround(h / ratio))
         if sw != w or sh != h:
             cursorlog(
                 "scaling cursor from %ix%i hotspot at %ix%i to %ix%i hotspot at %ix%i",
                 w, h, x, y, sw, sh, sx, sy)
             cursor_pixbuf = pixbuf.scale_simple(sw, sh, INTERP_BILINEAR)
             x, y = sx, sy
         else:
             cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w - 1))
     y = max(0, min(y, h - 1))
     try:
         c = new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)
     except RuntimeError as e:
         log.error("Error: failed to create cursor:")
         log.error(" %s", e)
         log.error(" using %s of size %ix%i with hotspot at %ix%i",
                   cursor_pixbuf, w, h, x, y)
         c = None
     return c
Exemple #21
0
    def get_screen_sizes(self, xscale=1, yscale=1):
        def xs(v):
            return iround(v / xscale)

        def ys(v):
            return iround(v / yscale)

        def swork(*workarea):
            return xs(workarea[0]), ys(workarea[1]), xs(workarea[2]), ys(
                workarea[3])

        display = display_get_default()
        i = 0
        screen_sizes = []
        n_screens = display.get_n_screens()
        screenlog("get_screen_sizes(%f, %f) found %s screens", xscale, yscale,
                  n_screens)
        while i < n_screens:
            screen = display.get_screen(i)
            j = 0
            monitors = []
            workareas = []
            #native "get_workareas()" is only valid for a single screen (but describes all the monitors)
            #and it is only implemented on win32 right now
            #other platforms only implement "get_workarea()" instead, which is reported against the screen
            n_monitors = screen.get_n_monitors()
            screenlog(" screen %s has %s monitors", i, n_monitors)
            if n_screens == 1:
                workareas = get_workareas()
                if len(workareas) != n_monitors:
                    screenlog(" workareas: %s", workareas)
                    screenlog(
                        " number of monitors does not match number of workareas!"
                    )
                    workareas = []
            while j < screen.get_n_monitors():
                geom = screen.get_monitor_geometry(j)
                plug_name = ""
                if hasattr(screen, "get_monitor_plug_name"):
                    plug_name = screen.get_monitor_plug_name(j) or ""
                wmm = -1
                if hasattr(screen, "get_monitor_width_mm"):
                    wmm = screen.get_monitor_width_mm(j)
                hmm = -1
                if hasattr(screen, "get_monitor_height_mm"):
                    hmm = screen.get_monitor_height_mm(j)
                monitor = [
                    plug_name,
                    xs(geom.x),
                    ys(geom.y),
                    xs(geom.width),
                    ys(geom.height), wmm, hmm
                ]
                screenlog(" monitor %s: %s", j, monitor)
                if workareas:
                    w = workareas[j]
                    monitor += list(swork(*w))
                monitors.append(tuple(monitor))
                j += 1
            work_x, work_y, work_width, work_height = swork(
                0, 0, screen.get_width(), screen.get_height())
            workarea = get_workarea()
            if workarea:
                work_x, work_y, work_width, work_height = swork(*workarea)
            screenlog(" workarea=%s", workarea)
            item = (screen.make_display_name(), xs(screen.get_width()),
                    ys(screen.get_height()), screen.get_width_mm(),
                    screen.get_height_mm(), monitors, work_x, work_y,
                    work_width, work_height)
            screenlog(" screen %s: %s", i, item)
            screen_sizes.append(item)
            i += 1
        return screen_sizes
Exemple #22
0
 def watch_keymap_changes(self):
     ### Set up keymap change notification:
     display = display_get_default()
     keymap = keymap_get_for_display(display)
     keymap.connect("keys-changed", self._keys_changed)
Exemple #23
0
    def __init__(self, replace_other_wm, wm_name, display=None):
        gobject.GObject.__init__(self)

        if display is None:
            display = display_get_default()
        self._display = display
        self._root = self._display.get_default_screen().get_root_window()
        self._wm_name = wm_name
        self._ewmh_window = None

        self._windows = {}
        # EWMH says we have to know the order of our windows oldest to
        # youngest...
        self._windows_in_order = []

        # Become the Official Window Manager of this year's display:
        self._wm_selection = ManagerSelection(self._display, "WM_S0")
        self._cm_wm_selection = ManagerSelection(self._display,
                                                 "_NET_WM_CM_S0")
        self._wm_selection.connect("selection-lost", self._lost_wm_selection)
        self._cm_wm_selection.connect("selection-lost",
                                      self._lost_wm_selection)
        # May throw AlreadyOwned:
        if replace_other_wm:
            mode = self._wm_selection.FORCE
        else:
            mode = self._wm_selection.IF_UNOWNED
        self._wm_selection.acquire(mode)
        self._cm_wm_selection.acquire(mode)

        # Set up the necessary EWMH properties on the root window.
        self._setup_ewmh_window()
        # Start with just one desktop:
        self.set_desktop_list((u"Main", ))
        self.set_current_desktop(0)
        # Start with the full display as workarea:
        root_w, root_h = get_default_root_window().get_geometry()[2:4]
        self.root_set("_NET_SUPPORTED", ["atom"], NET_SUPPORTED)
        self.set_workarea(0, 0, root_w, root_h)
        self.set_desktop_geometry(root_w, root_h)
        self.root_set("_NET_DESKTOP_VIEWPORT", ["u32"], [0, 0])

        self.size_constraints = DEFAULT_SIZE_CONSTRAINTS

        # Load up our full-screen widget
        self._world_window = None
        if not is_gtk3():
            self._world_window = WorldWindow(
                self._display.get_default_screen())
            self.notify("toplevel")
            self._world_window.show_all()

        # Okay, ready to select for SubstructureRedirect and then load in all
        # the existing clients.
        add_event_receiver(self._root, self)
        add_fallback_receiver("xpra-client-message-event", self)
        #when reparenting, the events may get sent
        #to a window that is already destroyed
        #and we don't want to miss those events, so:
        add_fallback_receiver("child-map-request-event", self)
        rxid = get_xwindow(self._root)
        X11Window.substructureRedirect(rxid)

        for w in get_children(self._root):
            # Checking for FOREIGN here filters out anything that we've
            # created ourselves (like, say, the world window), and checking
            # for mapped filters out any withdrawn windows.
            xid = get_xwindow(w)
            if (w.get_window_type() == GDKWINDOW_FOREIGN
                    and not X11Window.is_override_redirect(xid)
                    and X11Window.is_mapped(xid)):
                log("Wm managing pre-existing child window %#x", xid)
                self._manage_client(w)

        # Also watch for focus change events on the root window
        X11Window.selectFocusChange(rxid)
        X11Keyboard.selectBellNotification(True)
Exemple #24
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     if len(cursor_data) >= 9 and cursor_types:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name,
                           gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels) < w * h * 4:
         import binascii
         cursorlog.warn(
             "not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)",
             w * h * 4, len(pixels),
             binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w * 4)
     x = max(0, min(xhot, w - 1))
     y = max(0, min(yhot, h - 1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data) >= 11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog(
         "new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s",
         xhot, yhot, serial, w, h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw > 0 and fh > 0 and (w != fw or h != fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w <= fw and h <= fh:
             cursorlog(
                 "pasting cursor of size %ix%i onto clear pixbuf of size %ix%i",
                 w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0" * fw * fh * 4, True,
                                                  fw, fh, fw * 4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i",
                       w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w) / fw, float(h) / fh
             x, y = int(x / xratio), int(y / yratio)
     elif w > cmaxw or h > cmaxh or (csize > 0 and
                                     (csize < w or csize < h)):
         ratio = max(
             float(w) / cmaxw,
             float(h) / cmaxh,
             float(max(w, h)) / csize)
         x, y, w, h = int(x / ratio), int(y / ratio), int(w / ratio), int(
             h / ratio)
         cursorlog("downscaling cursor %s by %.2f: %sx%s", pixbuf, ratio, w,
                   h)
         cursor_pixbuf = pixbuf.scale_simple(w, h, INTERP_BILINEAR)
     else:
         cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w - 1))
     y = max(0, min(y, h - 1))
     return new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)