// 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/>.

package net.avadeaux.klipspringer;

import java.io.*;
import net.avadeaux.klipspringer.codec.*;

/**
 * Keypress interface of the device player.
 */
public class DeviceKeyInterface {
    private final DeviceFeeder feeder;
    private final Device.Player.Factory serverOutFact;
    private final DeviceTerminalDisplay display;

    /** Creates a command interface with text input and output, acting on the given feeder and
      * querying the given state service for current state.
      */
    public DeviceKeyInterface(DeviceFeeder feeder, Device.Player.Factory serverOutFact, DeviceTerminalDisplay display) {
        this.feeder = feeder;
        this.serverOutFact = serverOutFact;
        this.display = display;
    }

    public void runUntilQuit(DeviceFeeder.Play playing) throws IOException {
        DeviceFeeder.Play play = playing;
        Terminal.startKeyListen();
        try {
            boolean recording = false;
            while (true) {
                int ch = Terminal.getChar();
                long now = System.currentTimeMillis();
                switch (ch) {
                case ' ':
                    if (recording) { break; }
                    if (play == null) {
                        if (serverOutFact != null) {
                            play = feeder.fetchStream(serverOutFact);
                            if (display != null) { display.startPlay(play); }
                        }
                    } else {
                        play.close();
                        if (display != null) { display.stopPlay(); }
                        play = null;
                    }
                    break;
                case 'r':
                    if (recording) {
                        feeder.stopRecord();
                        if (display != null) { display.stopRecord(); }
                        recording = false;
                    } else {
                        DeviceFeeder.Play state = feeder.startRecord();
                        if (display != null) { display.startRecord(state); }
                        recording = true;
                    }
                    break;
                case 'q':
                    return;
                case 0x1b:                      // ESC
                    if (Terminal.getChar() != '[') { break; }
                case 0x9b:                      // C1 CSI
                    // No constrol sequences used, just gobble to end.
                    while (true) {
                        ch = Terminal.getChar();
                        if (ch >= 0x40 && ch <= 0x7E) { break; }
                    }
                    break;
                default:
                    // ignore
                }
            }
        } finally {
            try {
                Terminal.stopKeyListen();
            } catch (IOException ex) {
                if (System.getProperty("klipspringer.debug") != null) {
                    System.err.println("Error resetting terminal: "+ex);
                    ex.printStackTrace();
                }
            }
        }
    }
}

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