This file is indexed.

/usr/lib/python2.7/dist-packages/keysign/QRCode.py is in gnome-keysign 0.9-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
#!/usr/bin/env python
#    Copyright 2014 Tobias Mueller <muelli@cryptobitch.de>
#    Copyright 2015 Benjamin Berg <benjamin@sipsolutions.de>
#
#    This file is part of GNOME Keysign.
#
#    GNOME Keysign is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    GNOME Keysign is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with GNOME Keysign.  If not, see <http://www.gnu.org/licenses/>.
import logging

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk, Gtk, GObject
import qrcode
import cairo

log = logging.getLogger(__name__)

class QRImage(Gtk.DrawingArea):
    """An Image encoding data as a QR Code.
    The image tries to scale as big as possible.
    """
    
    def __init__(self, data='Default String', handle_events=True,
                       background=0xff, *args, **kwargs):
        """The QRImage widget inherits from Gtk.Image,
        but it probably cannot be used as one, as there
        is an event handler for resizing events which will
        overwrite to currently loaded image.
        
        You made set data now, or later simply via the property.
        
        handle_events can be set to False if the fullscreen
        window should not be created on click.
        
        The background can be set to 0x00 (or 0xff) creating a
        black (or white) background onto which the code is rendered.
        """
        super(QRImage, self).__init__(*args, **kwargs)
        self.log = logging.getLogger(__name__)

        self.background = background
        # We invert the background
        self.foreground = 0xff ^ background

        # The data to be rendered
        self._surface = None
        self.data = data
        self.set_app_paintable(True)

        self.handle_events = handle_events
        if handle_events:
            self.connect('button-release-event', self.on_button_released)
            self.add_events(
                Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)


    def on_button_released(self, widget, event):
        self.log.info('Event %s', dir(event))
        if event.button == 1:
            w = FullscreenQRImageWindow(data=self.data)
            top_level_window = self.get_toplevel()
            if top_level_window.is_toplevel():
                w.set_transient_for(top_level_window)


    def do_size_allocate(self, event):
        """This is the event handler for the resizing event, i.e.
        when window is resized. We then want to regenerate the QR code.
        """
        allocation = self.get_allocation()
        if allocation != event:
            self.queue_draw()
        Gtk.DrawingArea.do_size_allocate(self, event)

    def do_draw(self, cr):
        """This scales the QR Code up to the widget's
        size. You may define your own size, but you must
        be careful not to cause too many resizing events.
        When you request a too big size, it may loop to death
        trying to fit the image.
        """
        data = self.data
        box = self.get_allocation()
        width, height = box.width, box.height
        size = min(width, height)

        qrcode = self.qrcode
        img_size = qrcode.get_width()

        cr.save()

        background = self.background
        foreground = self.foreground

        # This seems to set tje background,
        # but I'm not sure...
        cr.set_source_rgb(background, background, background)
        #cr.fill()
        # And have it painted
        cr.paint()
        # Now, I think we set the colour of the turtle
        # paint whatever is coming next.
        cr.set_source_rgb(foreground, foreground, foreground)
        # All of the rest I do not really understand,
        # but it seems to work reasonably well, without
        # weird PIL to Pixbuf hacks.
        cr.translate(width / 2, height / 2)
        scale = max(1, size / img_size)
        cr.scale(scale, scale)
        cr.translate(-img_size / 2, -img_size / 2)

        pattern = cairo.SurfacePattern(qrcode)
        pattern.set_filter(cairo.FILTER_NEAREST)
        cr.mask(pattern)

        cr.restore()

    def create_qrcode(self, data):
        log.debug('Encoding %s', data)
        code = qrcode.QRCode()

        code.add_data(data)

        matrix = code.get_matrix()
        size = len(matrix)
        stride = (size + 3) / 4 * 4
        data = bytearray(stride * size)

        background = self.background
        foreground = self.foreground

        for x in range(size):
            for y in range(size):
                # Here we seem to be defining what
                # is going to be put on the surface.
                # I don't know what the semantic is,
                # though. Is 0 black? Or no modification
                # of the underlying background?
                # Anyway, this give us a nice white
                # QR Code.  Note that we do [y][x],
                # otherwise the generated code is diagonally
                # mirrored.
                if matrix[y][x]:
                    data[x + y * stride] = background
                else:
                    data[x + y * stride] = foreground

        surface = cairo.ImageSurface.create_for_data(data, cairo.FORMAT_A8, size, size, stride)

        return surface

    @property
    def qrcode(self):
        if self._surface is not None:
            return self._surface

        self._surface = self.create_qrcode(self.data)
        return self._surface

    def set_data(self, data):
        # FIXME: Full screen window is not updated in here ...
        self._data = data
        self._surface = None

        size = self.qrcode.get_width()
        self.set_size_request(size, size)

        self.queue_draw()
        
        self.set_tooltip_text(data)

    def get_data(self):
        return self._data

    data = GObject.property(getter=get_data, setter=set_data)


def fullscreen_at_monitor(window, n):
    """Fullscreens a given window on the n-th monitor

    This is because Gtk's fullscreen_on_monitor seems to
    be buggy.
    http://stackoverflow.com/a/39386341/2015768
    """
    screen = Gdk.Screen.get_default()

    monitor_n_geo = screen.get_monitor_geometry(n)
    x = monitor_n_geo.x
    y = monitor_n_geo.y

    window.move(x,y)

    window.fullscreen()


class FullscreenQRImageWindow(Gtk.Window):
    '''Displays a QRImage in a fullscreen window
    
    The window is supposed to close itself when a button is
    clicked.'''

    def __init__(self, data, *args, **kwargs):
        '''The data will be passed to the QRImage'''
        self.log = logging.getLogger(__name__)
        if issubclass(self.__class__, object):
            super(FullscreenQRImageWindow, self).__init__(*args, **kwargs)
        else:
            Gtk.Window.__init__(*args, **kwargs)

        self.fullscreen()
        
        self.qrimage = QRImage(data=data, handle_events=False)
        self.qrimage.set_has_tooltip(False)
        self.add(self.qrimage)
        
        self.connect('button-release-event', self.on_button_released)
        self.connect('key-release-event', self.on_key_released)
        self.add_events(
            Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK |
            Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK
            )

        self.show_all()


    def on_button_released(self, widget, event):
        '''Connected to the button-release-event and closes this
        window''' # It's unclear whether all resources are free()d
        self.log.info('Event on fullscreen: %s', event)
        if event.button == 1:
            self.unfullscreen()
            self.hide()
            self.close()

    def on_key_released(self, widget, event):
        self.log.info('Event on fullscreen: %s', dir(event))
        self.log.info('keycode: %s', event.get_keycode())
        self.log.info('keyval: %s', event.get_keyval())
        self.log.info('keyval: %s', Gdk.keyval_name(event.keyval))
        keyname = Gdk.keyval_name(event.keyval).lower()
        if keyname == 'escape' or keyname == 'f' or keyname == 'q':
            self.unfullscreen()
            self.hide()
            self.close()
        elif keyname == 'left' or keyname == 'right':
            # We're trying to switch monitors
            screen = self.get_screen()
            # Determines the monitor the window is currently most visible in
            n = screen.get_monitor_at_window(screen.get_active_window())
            n_monitors = screen.get_n_monitors()

            if keyname == 'left':
                delta = -1
            elif keyname == 'right':
                delta = 1
            else:
                raise ValueError()

            new_n = (n+delta) % n_monitors
            log.info("Moving from %d to %d/%d", n, new_n, n_monitors)
            if n != new_n:
                # This call would make it animate a little,
                # but it looks weird for me, so we don't unfullscreen.
                # self.unfullscreen()
                fullscreen_at_monitor(self, new_n)
                # The following call is broken, unfortunately.
                # https://bugzilla.gnome.org/show_bug.cgi?id=752677
                # self.fullscreen_on_monitor(self.get_screen(), new_n)


def main(data):
    w = Gtk.Window()
    w.connect("delete-event", Gtk.main_quit)
    w.set_default_size(100,100)
    qr = QRImage(data)

    global fullscreen
    fullscreen = False

    def on_released(widget, event):
        global fullscreen
 
        if event.button == 1:
            fullscreen = not fullscreen
            if fullscreen:
                w.fullscreen()
            else:
                w.unfullscreen()
        
    #qr.connect('button-release-event', on_released)
    #qr.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
    w.add(qr)
    w.show_all()
    Gtk.main()

if __name__ == '__main__':
    import sys
    logging.basicConfig(level=logging.DEBUG)
    data = sys.argv[1]
    main(data)