// Copyright 2014-2025 Jesper Larsson
//
// This file is part of Klipspringer, <https://klipspringer.avadeaux.net/>
//
// Klipspringer 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.
//
// Klipspringer 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 Klipspringer. If
// not, see <https://www.gnu.org/licenses/>.

import { listenForEvents } from './device_input.js';
import { log } from './log.js';

const exec = (callable, cmd, args) => {
    if (callable && callable[cmd]) {
        let qs = "cmd="+cmd;
        if (args) {
            for (const [k, v] of Object.entries(args)) { qs += "&"+k+"="+v }
        }
        try {
            callable[cmd](qs, args);
        } catch(err) { log.debug("Error in "+cmd+": "+err) }
    }
}

// Set up to control players from my Rega CD remote control. Edit it to make it
// work for some other remote.
export const setupRemote = (opts, getCallable) => {
    const KEY_PROGRAM = 0x16a;
    const KEY_CLEAR = 0x163;
    const KEY_TIME = 0x167;
    const KEY_MEDIA_REPEAT = 0x1b7;
    const KEY_DISPLAYTOGGLE = 0x1af;
    const KEY_SHUFFLE = 0x19a;
    const KEY_PREVIOUSSONG = 165;
    const KEY_PLAYPAUSE = 164;
    const KEY_NEXTSONG = 163;
    const KEY_REWIND = 168;
    const KEY_STOPCD = 166;
    const KEY_FASTFORWARD = 208;
    const KEY_CHANNELUP = 0x192;
    const KEY_CHANNELDOWN = 0x193;

    let lastPrevTime = 0;

    listenForEvents(opts.remote, opts.eventsizes, getCallable, [
        [1, KEY_NEXTSONG, 1, callable => exec(callable, 'next')],
        [1, KEY_NEXTSONG, 2, callable => exec(callable, 'next')],
        [1, KEY_PREVIOUSSONG, 1, callable => {
            if (callable && callable.prev) {
                const now = Date.now();
                exec(callable, 'prev', { rept: now - lastPrevTime });
                lastPrevTime = now;
            }
        }],
        [1, KEY_PREVIOUSSONG, 2, callable => exec(callable, 'prev', { rept: 0 })],
        [4, 4, 0x6e13, callable => exec(callable, 'toggle_pause')],
            // This strange line is to compensate for the fact that the
            // pause/play button on my Rega remote generates (type=EV_KEY,
            // code=KEY_PLAYPAUSE) events for only the second and the following
            // even-numbered key presses. Odd-numbered keypresses can be
            // detected by (type=EV_MSC=4, code=4, value=0x6e25), where
            // EV_MSC=4. (Other keys also generate (4, 4, <value>) events with
            // various but not unique values.) This may be a quirk only
            // applicable for my kind of remote, but it doesn't seem likely
            // that placing this line here will disturb anyone else.
        [1, KEY_PLAYPAUSE, 1, callable => exec(callable, 'toggle_pause')],
        [1, KEY_STOPCD, 1, callable => exec(callable, 'quit')],
        [1, KEY_FASTFORWARD, 1, callable => exec(callable, 'seekr', { time: 5 })],
        [1, KEY_FASTFORWARD, 2, callable => exec(callable, 'seekr', { time: 5 })],
        [1, KEY_REWIND, 1, callable => exec(callable, 'seekr', { time: -5 })],
        [1, KEY_REWIND, 2, callable => exec(callable, 'seekr', { time: -5 })],
        [1, KEY_CHANNELUP, 1, callable => exec(callable, 'channel_up')],
        [1, KEY_CHANNELDOWN, 1, callable => exec(callable, 'channel_down')],
        [1, KEY_SHUFFLE, 1, callable => exec(callable, 'shuffle')],
        [1, KEY_CLEAR, 1, callable => exec(callable, 'clear')],
        [1, KEY_PROGRAM, 1, callable => exec(callable, 'program')],
        [1, KEY_MEDIA_REPEAT, 1, callable => exec(callable, 'repeat')]
    ]);
}

Version: v4.3.2.2 (2026-05-16T17:03:34+02:00)
Raw file
Source code overview
Klipspringer home