Пример #1
0
    def _set_wm_state(self, *states):
        # Set property
        net_wm_state = xlib.XInternAtom(self._x_display, '_NET_WM_STATE', False)
        atoms = []
        for state in states:
            atoms.append(xlib.XInternAtom(self._x_display, state, False))
        atom_type = xlib.XInternAtom(self._x_display, 'ATOM', False)
        if len(atoms):
            atoms_ar = (xlib.Atom * len(atoms))(*atoms)
            xlib.XChangeProperty(self._x_display, self._window,
                net_wm_state, atom_type, 32, xlib.PropModePrepend,
                cast(pointer(atoms_ar), POINTER(c_ubyte)), len(atoms))
        else:
            xlib.XDeleteProperty(self._x_display, self._window, net_wm_state)

        # Nudge the WM
        e = xlib.XEvent()
        e.xclient.type = xlib.ClientMessage
        e.xclient.message_type = net_wm_state
        e.xclient.display = cast(self._x_display, POINTER(xlib.Display))
        e.xclient.window = self._window
        e.xclient.format = 32
        e.xclient.data.l[0] = xlib.PropModePrepend
        for i, atom in enumerate(atoms):
            e.xclient.data.l[i + 1] = atom
        xlib.XSendEvent(self._x_display, self._get_root(),
            False, xlib.SubstructureRedirectMask, byref(e))
Пример #2
0
 def _event_clientmessage(self, ev):
     atom = ev.xclient.data.l[0]
     if atom == xlib.XInternAtom(ev.xclient.display,
                                 asbytes('WM_DELETE_WINDOW'), False):
         self.dispatch_event('on_close')
     elif (self._enable_xsync and atom == xlib.XInternAtom(
             ev.xclient.display, asbytes('_NET_WM_SYNC_REQUEST'), False)):
         lo = ev.xclient.data.l[2]
         hi = ev.xclient.data.l[3]
         self._current_sync_value = xsync.XSyncValue(hi, lo)
Пример #3
0
 def _set_atoms_property(self, name, values, mode=xlib.PropModeReplace):
     name_atom = xlib.XInternAtom(self._x_display, asbytes(name), False)
     atoms = []
     for value in values:
         atoms.append(xlib.XInternAtom(self._x_display, asbytes(value), False))
     atom_type = xlib.XInternAtom(self._x_display, asbytes('ATOM'), False)
     if len(atoms):
         atoms_ar = (xlib.Atom * len(atoms))(*atoms)
         xlib.XChangeProperty(self._x_display, self._window,
             name_atom, atom_type, 32, mode,
             cast(pointer(atoms_ar), POINTER(c_ubyte)), len(atoms))
     else:
         xlib.XDeleteProperty(self._x_display, self._window, net_wm_state)
Пример #4
0
    def set_icon(self, *images):
        # Careful!  XChangeProperty takes an array of long when data type
        # is 32-bit (but long can be 64 bit!), so pad high bytes of format if
        # necessary.

        import sys
        format = {
            ('little', 4): 'BGRA',
            ('little', 8): 'BGRAAAAA',
            ('big', 4):    'ARGB',
            ('big', 8):    'AAAAARGB'
        }[(sys.byteorder, sizeof(c_ulong))]

        data = ''
        for image in images:
            image = image.get_image_data()
            pitch = -(image.width * len(format))
            s = c_buffer(sizeof(c_ulong) * 2)
            memmove(s, cast((c_ulong * 2)(image.width, image.height), 
                            POINTER(c_ubyte)), len(s))
            data += s.raw + image.get_data(format, pitch)
        buffer = (c_ubyte * len(data))()
        memmove(buffer, data, len(data))
        atom = xlib.XInternAtom(self._x_display, '_NET_WM_ICON', False)
        xlib.XChangeProperty(self._x_display, self._window, atom, XA_CARDINAL,
            32, xlib.PropModeReplace, buffer, len(data)/sizeof(c_ulong))
Пример #5
0
 def _set_text_property(self, name, value, allow_utf8=True):
     atom = xlib.XInternAtom(self._x_display, asbytes(name), False)
     if not atom:
         raise XlibException('Undefined atom "%s"' % name)
     assert type(value) in (str, unicode)
     property = xlib.XTextProperty()
     if _have_utf8 and allow_utf8:
         buf = create_string_buffer(value.encode('utf8'))
         result = xlib.Xutf8TextListToTextProperty(self._x_display,
             cast(pointer(buf), c_char_p), 1, xlib.XUTF8StringStyle, 
             byref(property))
         if result < 0:
             raise XlibException('Could not create UTF8 text property')
     else:
         buf = create_string_buffer(value.encode('ascii', 'ignore'))
         result = xlib.XStringListToTextProperty(
             cast(pointer(buf), c_char_p), 1, byref(property))
         if result < 0:
             raise XlibException('Could not create text property')
     xlib.XSetTextProperty(self._x_display,
         self._window, byref(property), atom)
Пример #6
0
    def _create(self):
        # Unmap existing window if necessary while we fiddle with it.
        if self._window and self._mapped:
            self._unmap()

        self._x_display = self.display._display
        self._x_screen_id = self.display.x_screen


        # Create X window if not already existing.
        if not self._window:
            root = xlib.XRootWindow(self._x_display, self._x_screen_id)

            visual_info = self.config.get_visual_info()

            visual = visual_info.visual
            visual_id = xlib.XVisualIDFromVisual(visual)
            default_visual = xlib.XDefaultVisual(
                self._x_display, self._x_screen_id)
            default_visual_id = xlib.XVisualIDFromVisual(default_visual)
            window_attributes = xlib.XSetWindowAttributes()
            if visual_id != default_visual_id:
                window_attributes.colormap = xlib.XCreateColormap(
                    self._x_display, root, visual, xlib.AllocNone)
            else:
                window_attributes.colormap = xlib.XDefaultColormap(
                    self._x_display, self._x_screen_id)
            window_attributes.bit_gravity = xlib.StaticGravity

            # Issue 287: Compiz on Intel/Mesa doesn't draw window decoration
            #            unless CWBackPixel is given in mask.  Should have
            #            no effect on other systems, so it's set
            #            unconditionally.
            mask = xlib.CWColormap | xlib.CWBitGravity | xlib.CWBackPixel

            if self._fullscreen:
                width, height = self.screen.width, self.screen.height
                self._view_x = (width - self._width) // 2
                self._view_y = (height - self._height) // 2
            else:
                width, height = self._width, self._height
                self._view_x = self._view_y = 0

            self._window = xlib.XCreateWindow(self._x_display, root,
                0, 0, width, height, 0, visual_info.depth,
                xlib.InputOutput, visual, mask,
                byref(window_attributes))
            self._view = xlib.XCreateWindow(self._x_display, 
                self._window, self._view_x, self._view_y, 
                self._width, self._height, 0, visual_info.depth, 
                xlib.InputOutput, visual, mask, 
                byref(window_attributes));
            xlib.XMapWindow(self._x_display, self._view)
            xlib.XSelectInput(
                self._x_display, self._view, self._default_event_mask)

            self.display._window_map[self._window] = \
                self.dispatch_platform_event
            self.display._window_map[self._view] = \
                self.dispatch_platform_event_view

            self.canvas = XlibCanvas(self.display, self._view)

            self.context.attach(self.canvas)
            self.context.set_vsync(self._vsync) # XXX ?

            # Setting null background pixmap disables drawing the background,
            # preventing flicker while resizing (in theory).
            #
            # Issue 287: Compiz on Intel/Mesa doesn't draw window decoration if
            #            this is called.  As it doesn't seem to have any
            #            effect anyway, it's just commented out.
            #xlib.XSetWindowBackgroundPixmap(self._x_display, self._window, 0)

            self._enable_xsync = (pyglet.options['xsync'] and
                                  self.display._enable_xsync and
                                  self.config.double_buffer)

            # Set supported protocols
            protocols = []
            protocols.append(xlib.XInternAtom(self._x_display,
                                              asbytes('WM_DELETE_WINDOW'), False))
            if self._enable_xsync:
                protocols.append(xlib.XInternAtom(self._x_display,
                                                  asbytes('_NET_WM_SYNC_REQUEST'),
                                                  False))
            protocols = (c_ulong * len(protocols))(*protocols)
            xlib.XSetWMProtocols(self._x_display, self._window,
                                 protocols, len(protocols))

            # Create window resize sync counter
            if self._enable_xsync:
                value = xsync.XSyncValue()
                self._sync_counter = xlib.XID(
                    xsync.XSyncCreateCounter(self._x_display, value))
                atom = xlib.XInternAtom(self._x_display,
                                        asbytes('_NET_WM_SYNC_REQUEST_COUNTER'), False)
                ptr = pointer(self._sync_counter)

                xlib.XChangeProperty(self._x_display, self._window,
                                     atom, XA_CARDINAL, 32,
                                     xlib.PropModeReplace,
                                     cast(ptr, POINTER(c_ubyte)), 1)
        # Set window attributes
        attributes = xlib.XSetWindowAttributes()
        attributes_mask = 0

        self._override_redirect = False
        if self._fullscreen:
            if pyglet.options['xlib_fullscreen_override_redirect']:
                # Try not to use this any more, it causes problems; disabled
                # by default in favour of _NET_WM_STATE_FULLSCREEN.
                attributes.override_redirect = self._fullscreen
                attributes_mask |= xlib.CWOverrideRedirect
                self._override_redirect = True
            else:
                self._set_wm_state('_NET_WM_STATE_FULLSCREEN')

        if self._fullscreen:
            xlib.XMoveResizeWindow(self._x_display, self._window, 
                self.screen.x, self.screen.y, 
                self.screen.width, self.screen.height)
        else:
            xlib.XResizeWindow(self._x_display, self._window, 
                self._width, self._height)

        xlib.XChangeWindowAttributes(self._x_display, self._window, 
            attributes_mask, byref(attributes))

        # Set style
        styles = {
            self.WINDOW_STYLE_DEFAULT: '_NET_WM_WINDOW_TYPE_NORMAL',
            self.WINDOW_STYLE_DIALOG: '_NET_WM_WINDOW_TYPE_DIALOG',
            self.WINDOW_STYLE_TOOL: '_NET_WM_WINDOW_TYPE_UTILITY',
        }
        if self._style in styles:
            self._set_atoms_property('_NET_WM_WINDOW_TYPE', 
                                     (styles[self._style],))
        elif self._style == self.WINDOW_STYLE_BORDERLESS:
            MWM_HINTS_DECORATIONS = 1 << 1
            PROP_MWM_HINTS_ELEMENTS = 5
            mwmhints = mwmhints_t()
            mwmhints.flags = MWM_HINTS_DECORATIONS
            mwmhints.decorations = 0
            name = xlib.XInternAtom(self._x_display, '_MOTIF_WM_HINTS', False)
            xlib.XChangeProperty(self._x_display, self._window,
                name, name, 32, xlib.PropModeReplace, 
                cast(pointer(mwmhints), POINTER(c_ubyte)),
                PROP_MWM_HINTS_ELEMENTS)

        # Set resizeable
        if not self._resizable and not self._fullscreen:
            self.set_minimum_size(self._width, self._height)
            self.set_maximum_size(self._width, self._height)

        # Set caption
        self.set_caption(self._caption)

        # Create input context.  A good but very outdated reference for this
        # is http://www.sbin.org/doc/Xlib/chapt_11.html
        if _have_utf8 and not self._x_ic:
            if not self.display._x_im:
                xlib.XSetLocaleModifiers(asbytes('@im=none'))
                self.display._x_im = \
                    xlib.XOpenIM(self._x_display, None, None, None)

            xlib.XFlush(self._x_display);

            # Need to set argtypes on this function because it's vararg,
            # and ctypes guesses wrong.
            xlib.XCreateIC.argtypes = [xlib.XIM,    
                                       c_char_p, c_int,
                                       c_char_p, xlib.Window,
                                       c_char_p, xlib.Window,
                                       c_void_p]
            self._x_ic = xlib.XCreateIC(self.display._x_im, 
                asbytes('inputStyle'), xlib.XIMPreeditNothing|xlib.XIMStatusNothing,
                asbytes('clientWindow'), self._window,
                asbytes('focusWindow'), self._window,
                None)

            filter_events = c_ulong()
            xlib.XGetICValues(self._x_ic,
                              'filterEvents', byref(filter_events),
                              None)
            self._default_event_mask |= filter_events.value
            xlib.XSetICFocus(self._x_ic)

        self.switch_to()
        if self._visible:
            self.set_visible(True)

        self.set_mouse_platform_visible()
        self._applied_mouse_exclusive = None
        self._update_exclusivity()