Beispiel #1
0
    def configure_mirror(self, output=None):
        with self.lock:
            self.outputs = [
                o for o in get_randr_outputs(self.d, self.window)
                if o['connection']
            ]

        used_crtc = [o['crtc_id'] for o in self.outputs if o['crtc_id']]
        if output:
            free_crtc = [c for c in output['crtcs'] if c not in used_crtc]

            if len(free_crtc) < 1:
                # No crtc available, so we cannot enable this output
                return False

        # We need to find a mode that every connected output supports
        enabled_outputs = [o for o in self.outputs if o['crtc']]

        if len(enabled_outputs) == 0:
            return False

        if output:
            mode = output['mode_ids']
        else:
            mode = enabled_outputs[0]['mode_ids']
        for e in enabled_outputs:
            mode = [m for m in mode if m in e['mode_ids']]

        if not len(mode):
            # Outputs couldn't agree on mode
            return False

        if output:
            randr.set_crtc_config(self.d, free_crtc[0], 0, 0, 0, mode[0],
                                  randr.Rotate_0, [output['id']])

        for o in enabled_outputs:
            randr.set_crtc_config(self.d, o['crtc_id'], 0, 0, 0, mode[0],
                                  o['crtc'].rotation, [o['id']])

        with self.lock:
            self.outputs = [
                o for o in get_randr_outputs(self.d, self.window)
                if o['connection']
            ]
        enabled_outputs = [o for o in self.outputs if o['crtc']]
        # Everything worked (hopefully), so redraw the bar
        self.bar_needs_resize = [o['name'] for o in enabled_outputs]
        self.resize_randr_screen()
        if self.redraw_hook:
            run(self.redraw_hook, shell=True)
        return True
Beispiel #2
0
    def update(self, *args, **kwargs):
        od_out = self.outputs
        outs = get_randr_outputs(self.d, self.window)
        if outs == None:
            return None
        nw_out = [o for o in outs if o['connection']]

        old = [o['name'] for o in self.outputs]
        new = [o['name'] for o in nw_out]

        mg = [o for o in old if o in new]
        mg = [o for o in new if o in mg]

        change = not (len(mg) == len(old) and len(mg) == len(new))

        if change:
            if self.auto_update:
                for o in old:
                    if not o in mg:
                        self.disable_output(
                            [out for out in od_out if out['name'] == o][0])
                for o in new:
                    if not o in mg:
                        self.enable_output(
                            [out for out in nw_out if out['name'] == o][0])
            else:
                with self.lock:
                    self.outputs = nw_out
        return None
Beispiel #3
0
    def configure_extend(self, output=None):
        with self.lock:
            outs = get_randr_outputs(self.d, self.window)
            if outs == None:
                return False
            self.outputs = [o for o in outs if o['connection']]
        used_crtc = [o['crtc_id'] for o in self.outputs if o['crtc_id']]
        if output:
            free_crtc = [c for c in output['crtcs'] if c not in used_crtc]

            if len(free_crtc) < 1:
                # No crtc available, so we cannot enable this output
                return False

        enabled_outputs = [o for o in self.outputs if o['crtc']]

        if len(enabled_outputs) == 0:
            return False

        wd = 0
        for o in enabled_outputs:
            randr.set_crtc_config(self.d, o['crtc_id'], 0, wd, 0,
                                  o['mode_ids'][0], o['crtc'].rotation,
                                  [o['id']])
            wd += [
                m['width'] for m in o['modes'] if m['id'] == o['mode_ids'][0]
            ][0]

        if output:
            randr.set_crtc_config(self.d, free_crtc[0], 0, wd, 0,
                                  output['mode_ids'][0], randr.Rotate_0,
                                  [output['id']])

        with self.lock:
            outs = get_randr_outputs(self.d, self.window)
            if outs == None:
                return False
            self.outputs = [o for o in outs if o['connection']]
        enabled_outputs = [o for o in self.outputs if o['crtc']]
        # Everything worked (hopefully), so redraw the bar
        if not self.bar_needs_resize:
            self.bar_needs_resize = []
        self.bar_needs_resize += [o['name'] for o in enabled_outputs]
        self.resize_randr_screen()
        if self.redraw_hook:
            run(self.redraw_hook, shell=True)
        return True
Beispiel #4
0
    def set_state(self, auto_update=False, redraw_hook=None, **kwargs):
        self.d = display.Display()
        s = self.d.screen()
        self.window = s.root.create_window(0, 0, 1, 1, 1, s.root_depth)

        self.outputs = [
            o for o in get_randr_outputs(self.d, self.window)
            if o['connection']
        ]

        self.auto_update = auto_update

        self.redraw_hook = redraw_hook

        super(OutputSegment, self).set_state(**kwargs)
Beispiel #5
0
    def set_state(self, auto_update=False, redraw_hook=None, **kwargs):
        self.d = display.Display()
        s = self.d.screen()
        self.window = s.root.create_window(0, 0, 1, 1, 1, s.root_depth)

        outs = get_randr_outputs(self.d, self.window)
        if outs != None:
            self.outputs = [o for o in outs if o['connection']]

        prim = [o for o in self.outputs if o['primary'] != None]
        if len(prim) > 0:
            prim = prim[0]
            onaji = [
                o for o in self.outputs
                if o['x'] == prim['x'] and o['y'] == prim['y']
            ]
            if len(onaji) > 1:
                self.mirror_state = 1

        self.auto_update = auto_update

        self.redraw_hook = redraw_hook

        super(OutputSegment, self).set_state(**kwargs)
Beispiel #6
0
    def configure_mirror(self, output=None):
        with self.lock:
            outs = get_randr_outputs(self.d, self.window)
            if outs == None:
                return False
            self.outputs = [o for o in outs if o['connection']]

        used_crtc = [o['crtc_id'] for o in self.outputs if o['crtc_id']]
        if output:
            free_crtc = [c for c in output['crtcs'] if c not in used_crtc]

            if len(free_crtc) < 1:
                # No crtc available, so we cannot enable this output
                return False

        # We need to find a mode that every connected output supports
        enabled_outputs = [o for o in self.outputs if o['crtc']]

        # print([o['name'] for o in enabled_outputs])

        if len(enabled_outputs) == 0:
            return False

        def resolutions(modes):
            return {(m['width'], m['height']) for m in modes}

        ress = {}
        mode_map = {}
        if output:
            # print(output['modes'])
            ress = resolutions(output['modes'])
            # print(ress)
            mode_map.update({output['name']: output['modes']})
        else:
            ress = resolutions(enabled_outputs[0]['modes'])

        # print(ress)

        for e in enabled_outputs:
            mode_map.update({e['name']: e['modes']})
            ress = [m for m in ress if m in resolutions(e['modes'])]
        if len(ress) > 0:
            # Outputs could agree on a resolution, so pick the largest one
            ress = sorted(ress, reverse=True)
            # print(ress)
            if output:
                mode_map.update({output['name']: \
                    [o for o in output['modes'] if (o['width'], o['height']) == ress[0]]})
            for e in enabled_outputs:
                mode_map.update({e['name']: \
                    [o for o in e['modes'] if (o['width'], o['height']) == ress[0]]})

        if output:
            randr.set_crtc_config(self.d, free_crtc[0], 0, 0, 0,
                                  mode_map[output['name']][0]['id'],
                                  randr.Rotate_0, [output['id']])

        for o in enabled_outputs:
            randr.set_crtc_config(self.d, o['crtc_id'], 0, 0, 0,
                                  mode_map[o['name']][0]['id'],
                                  o['crtc'].rotation, [o['id']])

        with self.lock:
            outs = get_randr_outputs(self.d, self.window)
            if outs == None:
                return False
            self.outputs = [o for o in outs if o['connection']]
        enabled_outputs = [o for o in self.outputs if o['crtc']]
        # Everything worked (hopefully), so redraw the bar
        if not self.bar_needs_resize:
            self.bar_needs_resize = []
        self.bar_needs_resize += [o['name'] for o in enabled_outputs]
        self.resize_randr_screen()
        if self.redraw_hook:
            run(self.redraw_hook, shell=True)
        return True
Beispiel #7
0
    def rotate(self, state):
        outs = get_randr_outputs(self.d, self.window)
        if outs == None:
            return False
        outs = [o for o in outs if o['crtc']]
        op = [o for o in outs if o['name'] == self.output]
        if not len(op):
            # The output to be rotated doesn't exist :(
            return False
        op = op[0]

        # Get all outputs that are mirrored to the output we shall rotate
        # (We must also rotate these outputs)
        current_mode = op['current_mode']

        mirrored_outs = [
            o for o in outs if o['x'] == op['x'] and o['y'] == op['y']
            and o['current_mode'] == op['current_mode']
        ]

        if (self.STATES[self.current_state] in [
                'left', 'right'
        ]) != (self.STATES[state] in ['left', 'right']):

            # If the user has some non-mirrored setup, only normal and inverted
            # layouts are implemented for now.
            # Anything else requires work . . .

            if len(outs) != len(mirrored_outs):
                return False

            # Disable all screens to be rotated
            for o in mirrored_outs:
                randr.set_crtc_config(self.d, o['crtc_id'], 0, 0, 0, 0, 1, [])

            mx_x = 0
            mx_y = 0
            mx_mm_x = 0.0
            mx_mm_y = 0.0

            ratio = 1

            for o in outs:
                if o['width']:
                    mx_x = max(mx_x, o['x'] + o['width'])
                if o['height']:
                    mx_y = max(mx_y, o['y'] + o['height'])
                if o['width'] and o['height']:
                    ratio = max(
                        ratio,
                        max(o['width'] / o['height'],
                            o['height'] / o['width']))
                if o in mirrored_outs and o['crtc'].rotation in [
                        xlib_rots['left'], xlib_rots['right']
                ]:
                    if o['mm_width'] and o['width']:
                        mx_mm_x = max(mx_mm_x,
                                      o['width'] * 1.0 / o['mm_width'])
                    if o['mm_height'] and o['height']:
                        mx_mm_y = max(mx_mm_y,
                                      o['height'] * 1.0 / o['mm_height'])
                else:
                    if o['mm_width'] and o['height']:
                        mx_mm_y = max(mx_mm_y,
                                      o['height'] * 1.0 / o['mm_width'])
                    if o['mm_height'] and o['width']:
                        mx_mm_x = max(mx_mm_x,
                                      o['width'] * 1.0 / o['mm_height'])

            if mx_x and mx_y and mx_mm_x and mx_mm_y:
                self.window.xrandr_set_screen_size(mx_y, mx_x,
                                                   int(mx_x / mx_mm_x * ratio),
                                                   int(mx_y / mx_mm_y * ratio))

        # Actually rotate these outputs, don't change anything besides the rotation
        for o in mirrored_outs:
            randr.set_crtc_config(self.d, o['crtc_id'], 0, o['x'], o['y'],
                                  current_mode, xlib_rots[self.STATES[state]],
                                  [o['id']])

        if (self.STATES[self.current_state] in [
                'left', 'right'
        ]) != (self.STATES[state] in ['left', 'right']):
            self.bar_needs_resize = self.output
            if self.rotation_hook:
                run(self.rotation_hook, shell=True)

        needs_map = [
            i.decode('utf-8') for i in self.devices
            if len([j for j in self.mapped_inputs if j in i.decode('utf-8')])
        ]

        ids = [
            check_output(['xinput', '--list', '--id-only',
                          i]).splitlines()[0].decode() for i in needs_map
        ]
        for i in ids:
            check_call(['xinput', '--map-to-output', i, self.touch_output])

        return True