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, col in enumerate(row): if (l, r, c) in self.layout: self.set_key(l, r, c, col) # restore encoders for l, layer in enumerate(data["encoder_layout"]): for e, encoder in enumerate(layer): self.set_encoder(l, e, 0, encoder[0]) self.set_encoder(l, e, 1, 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.get().perform_unlock(self) self.set_macro(macro) self.lock()
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.get().perform_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)
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() Unlocker.get().perform_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( )
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.get().perform_unlock(self) self.usb_send(self.dev, struct.pack(">BBBBH", CMD_VIA_SET_KEYCODE, layer, row, col, code), retries=20) self.layout[key] = code
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.get().perform_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
def on_save(self): Unlocker.get().perform_unlock(self.device.keyboard) self.keyboard.set_macro(self.serialize()) self.on_change()