def remapRemoteControl(self, device):
		filename = rc_model.getRcPositions()
		domRemote = self.loadRemoteControl(filename)
		logRemaps = []
		remapButtons = {}
		if domRemote is not None:
			rc = domRemote.find("rc")
			if rc is not None:
				for button in rc.findall("button"):
					keyid = KEYIDS.get(button.attrib.get("keyid"))
					remap = KEYIDS.get(button.attrib.get("remap"))
					if keyid is not None and remap is not None:
						logRemaps.append((button.attrib.get("keyid"), button.attrib.get("remap")))
						remapButtons[keyid] = remap
		if len(logRemaps):
			print("[InputDevice] Remapping remote control buttons for '%s':" % filename)
			for remap in logRemaps:
				print("[InputDevice] Remapping '%s' to '%s'." % (remap[0], remap[1]))
			for evdev, evdevinfo in iInputDevices.Devices.items():
				if evdevinfo["type"] == "remote":
					res = eRCInput.getInstance().setKeyMapping(evdevinfo["name"], remapButtons)
					resStr = {
						eRCInput.remapOk: "Remap completed okay.",
						eRCInput.remapUnsupported: "Error: Remapping not supported on device!",
						eRCInput.remapFormatErr: "Error: Remap map in incorrect format!",
						eRCInput.remapNoSuchDevice: "Error: Unknown device!",
					}.get(res, "Error: Unknown error!")
					print("[InputDevice] Remote remap evdev='%s', name='%s': %s" % (evdev, evdevinfo["name"], resStr))
Example #2
0
 def __init__(self):
     self["rc"] = Pixmap()
     self.rcPosition = None
     buttonImages = 16
     rcHeights = (500, ) * 2
     self.selectPics = []
     for indicator in range(buttonImages):
         self.selectPics.append(
             self.KeyIndicator(
                 self, rcHeights,
                 ("indicatorU%d" % indicator, "indicatorL%d" % indicator)))
     self.nSelectedKeys = 0
     self.oldNSelectedKeys = 0
     self.clearSelectedKeys()
     self.wizardConversion = {  # This dictionary converts named buttons in the Wizards to keyIds.
         "OK": KEYIDS.get("KEY_OK"),
         "EXIT": KEYIDS.get("KEY_EXIT"),
         "LEFT": KEYIDS.get("KEY_LEFT"),
         "RIGHT": KEYIDS.get("KEY_RIGHT"),
         "UP": KEYIDS.get("KEY_UP"),
         "DOWN": KEYIDS.get("KEY_DOWN"),
         "RED": KEYIDS.get("KEY_RED"),
         "GREEN": KEYIDS.get("KEY_GREEN"),
         "YELLOW": KEYIDS.get("KEY_YELLOW"),
         "BLUE": KEYIDS.get("KEY_BLUE")
     }
     self.onLayoutFinish.append(self.initRemoteControl)
Example #3
0
	def loadRemoteControl(self, filename):
		print("[InputDevice] Loading remote control '%s'." % filename)
		rcs = fileReadXML(filename, source=MODULE_NAME)
		rcButtons = {}
		if rcs:
			rc = rcs.find("rc")
			if rc:
				logRemaps = []
				remapButtons = {}
				placeHolder = 0
				rcButtons["keyIds"] = []
				rcButtons["image"] = rc.attrib.get("image")
				if config.crash.debugRemoteControls.value:
					print("[InputDevice] Remote control image file '%s'." % rcButtons["image"])
				for button in rc.findall("button"):
					id = button.attrib.get("id", "KEY_RESERVED")
					remap = button.attrib.get("remap")
					keyId = KEYIDS.get(id)
					remapId = KEYIDS.get(remap)
					if keyId is not None and remapId is not None:
						logRemaps.append((id, remap))
						remapButtons[keyId] = remapId
						keyId = remapId
					if keyId == 0:
						placeHolder -= 1
						keyId = placeHolder
					rcButtons["keyIds"].append(keyId)
					rcButtons[keyId] = {}
					rcButtons[keyId]["id"] = id
					rcButtons[keyId]["label"] = button.attrib.get("label")
					rcButtons[keyId]["pos"] = [int(x.strip()) for x in button.attrib.get("pos", "0").split(",")]
					rcButtons[keyId]["title"] = button.attrib.get("title")
					rcButtons[keyId]["shape"] = button.attrib.get("shape")
					rcButtons[keyId]["coords"] = [int(x.strip()) for x in button.attrib.get("coords", "0").split(",")]
					if config.crash.debugRemoteControls.value:
						print("[InputDevice] Remote control button id='%s', keyId='%s', label='%s', pos='%s', title='%s', shape='%s', coords='%s'." % (id, keyId, rcButtons[keyId]["label"], rcButtons[keyId]["pos"], rcButtons[keyId]["title"], rcButtons[keyId]["shape"], rcButtons[keyId]["coords"]))
				if logRemaps:
					for remap in logRemaps:
						print("[InputDevice] Remapping '%s' to '%s'." % (remap[0], remap[1]))
					for evdev, evdevinfo in sorted(inputDevices.devices.items()):
						if evdevinfo["type"] == "remote":
							result = eRCInput.getInstance().setKeyMapping(evdevinfo["name"], remapButtons)
							resStr = {
								eRCInput.remapOk: "Remap completed okay.",
								eRCInput.remapUnsupported: "Error: Remapping not supported on device!",
								eRCInput.remapFormatErr: "Error: Remap map in incorrect format!",
								eRCInput.remapNoSuchDevice: "Error: Unknown device!",
							}.get(result, "Error: Unknown error!")
							print("[InputDevice] Remote remap evdev='%s', name='%s': %s" % (evdev, evdevinfo["name"], resStr))
		return rcButtons
Example #4
0
 def selectionChanged(self):
     self.clearSelectedKeys()
     selection = self["list"].getCurrent()
     if selection:
         baseButtons = []
         longButtons = []
         shiftButtons = []
         buttonList = []
         for button in selection[3]:
             label = remoteControl.getRemoteControlKeyLabel(button[0])
             if label is None:
                 label = "Note: No button defined for this action!"
             if len(button) > 1:
                 if button[1] == "SHIFT":
                     self.selectKey(KEYIDS.get("KEY_SHIFT"))
                     shiftButtons.append(label)
                 elif button[1] == "LONG":
                     longButtons.append(label)
             else:
                 baseButtons.append(label)
             self.selectKey(button[0])
         if baseButtons:
             buttonList.append(
                 pgettext("Text list separator",
                          ", ").join(sorted(baseButtons)))
         if longButtons:
             buttonList.append(
                 _("Long press: %s") % pgettext(
                     "Text list separator", ", ").join(sorted(longButtons)))
         if shiftButtons:
             buttonList.append(
                 _("Shift: %s") % pgettext("Text list separator",
                                           ", ").join(sorted(shiftButtons)))
         self["buttonlist"].setText("; ".join(buttonList))
         helpText = selection[4]
         self["description"].setText(
             isinstance(helpText,
                        (list, tuple)) and len(helpText) > 1 and helpText[1]
             or "")
def getKeyDescription(key):
	for key_name, key_id in KEYIDS.items():
		if key_id != key: continue
		if key_name.startswith("KEY_"):
			return (key_name[4:],)
		return
Example #6
0
    def __init__(self, helpList, callback):
        List.__init__(self)
        self.callback = callback
        self.rcKeyIndex = None
        self.buttonMap = {}
        self.longSeen = False
        formatFlags = 0

        def actMapId():
            return getattr(actionmap, "description", None) or id(actionmap)

        headings, sortCmp, sortKey = {
            "headings+alphabetic": (True, None, self._sortKeyAlpha),
            "flat+alphabetic": (False, None, self._sortKeyAlpha),
            "flat+remotepos": (False, self._sortCmpPos, None),
            "flat+remotegroups": (False, self._sortCmpInd, None)
        }.get(config.usage.helpSortOrder.value, (False, None, None))
        if remoteControl is None:
            if sortCmp in (self._sortCmpPos, self._sortCmpInd):
                sortCmp = None
        else:
            if sortCmp == self._sortCmpInd:
                self.rcKeyIndex = dict((x[1], x[0]) for x in enumerate(
                    remoteControl.getRemoteControlKeyList()))
        buttonsProcessed = set()
        helpSeen = defaultdict(list)
        sortedHelpList = sorted(helpList, key=lambda hle: hle[0].prio)
        actionMapHelp = defaultdict(list)
        for (actionmap, context, actions) in sortedHelpList:
            # print("[HelpMenu] HelpMenuList DEBUG: actionmap='%s', context='%s', actions='%s'." % (str(actionmap), context, str(actions)))
            if not actionmap.enabled:
                # print("[HelpMenu] Action map disabled.")
                continue
            amId = actMapId()
            if headings and actionmap.description and not (formatFlags
                                                           & self.HEADINGS):
                # print("[HelpMenu] HelpMenuList DEBUG: Headings found.")
                formatFlags |= self.HEADINGS
            for (action, help) in actions:  # DEBUG: Should help be response?
                helpTags = [
                ]  # if mapFlag else [pgettext("Abbreviation of 'Disabled'", "Disabled")]
                if callable(help):
                    help = help()
                    helpTags.append(
                        pgettext("Abbreviation of 'Configurable'",
                                 "Configurable"))
                if help is None:
                    # print("[HelpMenu] HelpMenuList DEBUG: No help text found.")
                    # help = _("No help text available")
                    continue
                buttons = queryKeyBinding(context, action)
                # print("[HelpMenu] HelpMenuList DEBUG: queryKeyBinding buttons=%s." % str(buttons))
                if not buttons:  # Do not display entries which are not accessible from keys.
                    # print("[HelpMenu] HelpMenuList DEBUG: No buttons allocated.")
                    # helpTags.append(pgettext("Abbreviation of 'Unassigned'", "Unassigned"))
                    continue
                buttonLabels = []
                for keyId, flags in buttons:
                    if remoteControl.getRemoteControlKeyPos(keyId):
                        buttonLabels.append(
                            (keyId, "LONG") if flags & 8 else (keyId, )
                        )  # For long keypresses, make the second tuple item "LONG".
                if not buttonLabels:  # Only show entries with keys that are available on the used rc.
                    # print("[HelpMenu] HelpMenuList DEBUG: Button not available on current remote control.")
                    # helpTags.append(pgettext("Abbreviation of 'No Button'", "No Button"))
                    continue
                isExtended = isinstance(help, (list, tuple))
                if isExtended and not (formatFlags & self.EXTENDED):
                    # print("[HelpMenu] HelpMenuList DEBUG: Extended help entry found.")
                    formatFlags |= self.EXTENDED
                if helpTags:
                    helpStr = help[0] if isExtended else help
                    tagsStr = pgettext("Text list separator",
                                       ", ").join(helpTags)
                    helpStr = _("%s  (%s)") % (helpStr, tagsStr)
                    help = [helpStr, help[1]] if isExtended else helpStr
                entry = [(actionmap, context, action, buttonLabels, help),
                         help]
                if self._filterHelpList(entry, helpSeen):
                    actionMapHelp[actMapId()].append(entry)
        helpMenuList = []
        extendedPadding = (None, ) if formatFlags & self.EXTENDED else ()
        for (actionmap, context, actions) in helpList:
            amId = actMapId()
            if headings and amId in actionMapHelp and getattr(
                    actionmap, "description", None):
                if sortCmp:
                    actionMapHelp[amId].sort(key=cmp_to_key(sortCmp))
                elif sortKey:
                    actionMapHelp[amId].sort(key=sortKey)
                self.addListBoxContext(actionMapHelp[amId], formatFlags)
                helpMenuList.append((None, actionmap.description, None) +
                                    extendedPadding)
                helpMenuList.extend(actionMapHelp[amId])
                del actionMapHelp[amId]
        if actionMapHelp:
            if formatFlags & self.HEADINGS:  # Add a header if other actionmaps have descriptions.
                helpMenuList.append((None, _("Other Actions"), None) +
                                    extendedPadding)
            otherHelp = []
            for (actionmap, context, actions) in helpList:
                amId = actMapId()
                if amId in actionMapHelp:
                    otherHelp.extend(actionMapHelp[amId])
                    del actionMapHelp[amId]
            if sortCmp:
                otherHelp.sort(key=cmp_to_key(sortCmp))
            elif sortKey:
                otherHelp.sort(key=sortKey)
            self.addListBoxContext(otherHelp, formatFlags)
            helpMenuList.extend(otherHelp)
        ignoredKeyIds = (KEYIDS.get("KEY_OK"), KEYIDS.get("KEY_EXIT"))
        for index, entry in enumerate(helpMenuList):
            if entry[0] and entry[0][3]:  # This should not be required.
                for button in entry[0][3]:
                    if button[0] not in (
                            ignoredKeyIds
                    ):  # Ignore "break" events from OK and EXIT on return from help popup.
                        self.buttonMap[button] = index
        self.style = (
            "default",
            "default+headings",
            "extended",
            "extended+headings",
        )[formatFlags]
        # [(actionmap, context, [(action, help), (action, help), ...]), ...]
        # [((ActionMap, Context, Action, [(Button, Device/Long), ...], HelpText), HelpText), ...]
        self.list = helpMenuList
def getKeyDescription(key):
    for key_name, key_id in KEYIDS.items():
        if key_id != key: continue
        if key_name.startswith("KEY_"):
            return (key_name[4:], )
        return
Example #8
0
def parseKeymap(filename, context, actionMapInstance, device, domKeys):
	unmapDict = {}
	error = False
	keyId = -1
	for key in domKeys.findall("key"):
		keyName = key.attrib.get("id")
		if keyName is None:
			print("[ActionMap] Error: Keymap attribute 'id' in context '%s' in file '%s' must be specified!" % (context, filename))
			error = True
		else:
			try:
				if len(keyName) == 1:
					keyId = ord(keyName) | 0x8000
				elif keyName[0] == "\\":
					if keyName[1].lower() == "x":
						keyId = int(keyName[2:], 16) | 0x8000
					elif keyName[1].lower() == "d":
						keyId = int(keyName[2:], 10) | 0x8000
					elif keyName[1].lower() == "o":
						keyId = int(keyName[2:], 8) | 0x8000
					elif keyName[1].lower() == "b":
						keyId = int(keyName[2:], 2) | 0x8000
					else:
						print("[ActionMap] Error: Keymap id '%s' in context '%s' in file '%s' is not a hex, decimal, octal or binary number!" % (keyName, context, filename))
						error = True
				else:
					keyId = KEYIDS.get(keyName, -1)
					if keyId is None:
						print("[ActionMap] Error: Keymap id '%s' in context '%s' in file '%s' is undefined/invalid!" % (keyName, context, filename))
						error = True
			except ValueError:
				print("[ActionMap] Error: Keymap id '%s' in context '%s' in file '%s' can not be evaluated!" % (keyName, context, filename))
				keyId = -1
				error = True
		mapto = key.attrib.get("mapto")
		unmap = key.attrib.get("unmap")
		if mapto is None and unamp is None:
			print("[ActionMap] Error: At least one of the attributes 'mapto' or 'unmap' in context '%s' id '%s' (%d) in file '%s' must be specified!" % (context, keyName, keyId, filename))
			error = True
		flags = key.attrib.get("flags")
		if flags is None:
			print("[ActionMap] Error: Attribute 'flag' in context '%s' id '%s' (%d) in file '%s' must be specified!" % (context, keyName, keyId, filename))
			error = True
		else:
			flagToValue = lambda x: {
				'm': 1,
				'b': 2,
				'r': 4,
				'l': 8
			}[x]
			newFlags = sum(map(flagToValue, flags))
			if not newFlags:
				print("[ActionMap] Error: Attribute 'flag' value '%s' in context '%s' id '%s' (%d) in file '%s' appears invalid!" % (flags, context, keyName, keyId, filename))
				errors += 1
			flags = newFlags
		if not error:
			if unmap is None:  # If a key was unmapped, it can only be assigned a new function in the same keymap file (avoid file parsing sequence dependency).
				if unmapDict.get((context, keyName, mapto)) in [filename, None]:
					if config.crash.debugActionMaps.value:
						print("[ActionMap] Context '%s' keyName '%s' (%d) mapped to '%s' (Device: %s)." % (context, keyName, keyId, mapto, device.capitalize()))
					actionMapInstance.bindKey(filename, device, keyId, flags, context, mapto)
					addKeyBinding(filename, keyId, context, mapto, flags)
			else:
				actionMapInstance.unbindPythonKey(context, keyId, unmap)
				unmapDict.update({(context, keyName, unmap): filename})