def restore_layout(self, data):
        """ Restores saved layout """

        data = json.loads(data.decode("utf-8"))

        # restore keymap
        for l, layer in enumerate(data["layout"]):
            for r, row in enumerate(layer):
                for c, code in enumerate(row):
                    if (l, r, c) in self.layout:
                        self.set_key(l, r, c, Keycode.deserialize(code))

        # restore encoders
        for l, layer in enumerate(data["encoder_layout"]):
            for e, encoder in enumerate(layer):
                self.set_encoder(l, e, 0, Keycode.deserialize(encoder[0]))
                self.set_encoder(l, e, 1, Keycode.deserialize(encoder[1]))

        self.set_layout_options(data["layout_options"])

        # we need to unlock the keyboard before we can restore the macros, lock it afterwards
        # only do that if it's different from current macros
        macro = base64.b64decode(data["macro"])
        if macro != self.macro:
            Unlocker.unlock(self)
            self.set_macro(macro)
            self.lock()
Beispiel #2
0
 def restore_macros(self, macros):
     if not isinstance(macros, list):
         return
     tag_to_action = {
         "down": ActionDown,
         "up": ActionUp,
         "tap": ActionTap,
         "text": ActionText,
         "delay": ActionDelay,
     }
     full_macro = []
     for macro in macros:
         actions = []
         for act in macro:
             if act[0] in tag_to_action:
                 obj = tag_to_action[act[0]]()
                 obj.restore(act)
                 actions.append(obj)
         full_macro.append(actions)
     if len(full_macro) < self.macro_count:
         full_macro += [[]
                        for x in range(self.macro_count - len(full_macro))]
     full_macro = full_macro[:self.macro_count]
     # TODO: log a warning if macro is cutoff
     data = self.macros_serialize(full_macro)[0:self.macro_memory]
     if data != self.macro:
         Unlocker.unlock(self)
         self.set_macro(data)
         self.lock()
Beispiel #3
0
    def set_key(self, layer, row, col, code):
        if code < 0:
            return

        key = (layer, row, col)
        if self.layout[key] != code:
            if code == RESET_KEYCODE:
                Unlocker.unlock(self)

            self.usb_send(self.dev, struct.pack(">BBBBH", CMD_VIA_SET_KEYCODE, layer, row, col, code), retries=20)
            self.layout[key] = code
Beispiel #4
0
 def start_poller(self):
     if not self.polling:
         Unlocker.unlock(self.keyboard)
         self.startButtonWidget.setText("Stop testing")
         self.timer.start(20)
         self.polling = True
     else:
         self.timer.stop()
         self.keyboard.lock()
         self.startButtonWidget.setText("Start testing")
         self.polling = False
Beispiel #5
0
    def rebuild(self):
        # don't show "Security" menu for bootloader mode, as the bootloader is inherently insecure
        self.security_menu.menuAction().setVisible(isinstance(self.current_device, VialKeyboard))

        # if unlock process was interrupted, we must finish it first
        if isinstance(self.current_device, VialKeyboard) and self.current_device.keyboard.get_unlock_in_progress():
            Unlocker.unlock(self.current_device.keyboard)
            self.current_device.keyboard.reload()

        for e in [self.layout_editor, self.keymap_editor, self.firmware_flasher, self.macro_recorder]:
            e.rebuild(self.current_device)
Beispiel #6
0
    def set_encoder(self, layer, index, direction, code):
        if code < 0:
            return

        key = (layer, index, direction)
        if self.encoder_layout[key] != code:
            if code == RESET_KEYCODE:
                Unlocker.unlock(self)

            self.usb_send(self.dev, struct.pack(">BBBBBH", CMD_VIA_VIAL_PREFIX, CMD_VIAL_SET_ENCODER,
                                                layer, index, direction, code), retries=20)
            self.encoder_layout[key] = code
Beispiel #7
0
    def on_click_flash(self):
        if not self.selected_firmware_path:
            self.log("Error: Please select a firmware update package")
            return

        with open(self.selected_firmware_path, "rb") as inf:
            firmware = inf.read()

        if len(firmware) > 10 * 1024 * 1024:
            self.log("Error: Firmware is too large. Check you've selected the correct file")
            return

        self.log("Preparing to flash...")
        self.lock_ui()

        self.layout_restore = self.uid_restore = None

        if isinstance(self.device, VialKeyboard):
            # back up current layout
            if self.chk_restore_keymap.isChecked():
                self.log("Backing up current layout...")
                self.layout_restore = self.device.keyboard.save_layout()

            # keep track of which keyboard we should restore saved layout to
            self.uid_restore = self.device.keyboard.get_uid()
            firmware_uid = firmware[8:16]
            if self.uid_restore != firmware_uid:
                self.log("Error: Firmware UID does not match keyboard UID. Check that you have the correct file")
                self.unlock_ui(False)
                return

            Unlocker.unlock(self.device.keyboard)

            self.log("Restarting in bootloader mode...")
            self.device.keyboard.reset()

            # watch for bootloaders to appear and ask them for their UID, return one that matches the keyboard
            found = None
            while found is None:
                self.log("Looking for devices...")
                QCoreApplication.processEvents()
                time.sleep(1)
                found = self.find_device_with_uid(VialBootloader, self.uid_restore)

            self.log("Found Vial Bootloader device at {}".format(found.desc["path"].decode("utf-8")))
            found.open()
            self.device = found

        threading.Thread(target=lambda: cmd_flash(
            self.device, firmware, self.layout_restore is not None,
            self.on_log, self.on_progress, self.on_complete, self.on_error)).start()
Beispiel #8
0
 def reboot_to_bootloader(self):
     if isinstance(self.current_device, VialKeyboard):
         Unlocker.unlock(self.current_device.keyboard)
         self.current_device.keyboard.reset()
Beispiel #9
0
 def unlock_keyboard(self):
     if isinstance(self.current_device, VialKeyboard):
         Unlocker.unlock(self.current_device.keyboard)
Beispiel #10
0
 def unlock(self):
     Unlocker.unlock(self.keyboard)
Beispiel #11
0
 def on_save(self):
     Unlocker.unlock(self.device.keyboard)
     self.keyboard.set_macro(self.serialize())
     self.on_change()