mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-03 16:10:59 +00:00
server/terminal: API transition
The key repeat and flush handling was added by Norman Feske. Ref #1987
This commit is contained in:
parent
5e75ac4f87
commit
07cb4b2a4e
@ -12,19 +12,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/env.h>
|
#include <base/component.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
#include <framebuffer_session/connection.h>
|
#include <framebuffer_session/connection.h>
|
||||||
#include <input_session/connection.h>
|
#include <input_session/connection.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
#include <os/attached_ram_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
|
#include <base/attached_ram_dataspace.h>
|
||||||
#include <input/event.h>
|
#include <input/event.h>
|
||||||
#include <os/config.h>
|
|
||||||
#include <util/color.h>
|
#include <util/color.h>
|
||||||
#include <os/pixel_rgb565.h>
|
#include <os/pixel_rgb565.h>
|
||||||
|
#include <os/timer.h>
|
||||||
|
|
||||||
/* terminal includes */
|
/* terminal includes */
|
||||||
#include <terminal/decoder.h>
|
#include <terminal/decoder.h>
|
||||||
@ -37,6 +37,11 @@
|
|||||||
/* nitpicker graphic back end */
|
/* nitpicker graphic back end */
|
||||||
#include <nitpicker_gfx/text_painter.h>
|
#include <nitpicker_gfx/text_painter.h>
|
||||||
|
|
||||||
|
namespace Terminal {
|
||||||
|
using namespace Genode;
|
||||||
|
struct Main;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
using Genode::Pixel_rgb565;
|
using Genode::Pixel_rgb565;
|
||||||
typedef Text_painter::Font Font;
|
typedef Text_painter::Font Font;
|
||||||
@ -264,15 +269,22 @@ namespace Terminal {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Trigger_flush_callback
|
||||||
|
{
|
||||||
|
virtual void trigger_flush() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Session_component : public Genode::Rpc_object<Session, Session_component>,
|
class Session_component : public Genode::Rpc_object<Session, Session_component>,
|
||||||
public Flush_callback
|
public Flush_callback
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Read_buffer *_read_buffer;
|
Read_buffer &_read_buffer;
|
||||||
Framebuffer::Session *_framebuffer;
|
Framebuffer::Session &_framebuffer;
|
||||||
|
|
||||||
Flush_callback_registry &_flush_callback_registry;
|
Flush_callback_registry &_flush_callback_registry;
|
||||||
|
Trigger_flush_callback &_trigger_flush_callback;
|
||||||
|
|
||||||
Genode::Attached_ram_dataspace _io_buffer;
|
Genode::Attached_ram_dataspace _io_buffer;
|
||||||
|
|
||||||
@ -295,7 +307,7 @@ namespace Terminal {
|
|||||||
|
|
||||||
Terminal::Position _last_cursor_pos;
|
Terminal::Position _last_cursor_pos;
|
||||||
|
|
||||||
Font_family const *_font_family;
|
Font_family const &_font_family;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize framebuffer-related attributes
|
* Initialize framebuffer-related attributes
|
||||||
@ -307,7 +319,7 @@ namespace Terminal {
|
|||||||
return Genode::Dataspace_capability();
|
return Genode::Dataspace_capability();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _framebuffer->dataspace();
|
return _framebuffer.dataspace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -315,16 +327,20 @@ namespace Terminal {
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Session_component(Read_buffer *read_buffer,
|
Session_component(Genode::Env &env,
|
||||||
Framebuffer::Session *framebuffer,
|
Genode::Allocator &alloc,
|
||||||
|
Read_buffer &read_buffer,
|
||||||
|
Framebuffer::Session &framebuffer,
|
||||||
Genode::size_t io_buffer_size,
|
Genode::size_t io_buffer_size,
|
||||||
Flush_callback_registry &flush_callback_registry,
|
Flush_callback_registry &flush_callback_registry,
|
||||||
|
Trigger_flush_callback &trigger_flush_callback,
|
||||||
Font_family const &font_family)
|
Font_family const &font_family)
|
||||||
:
|
:
|
||||||
_read_buffer(read_buffer), _framebuffer(framebuffer),
|
_read_buffer(read_buffer), _framebuffer(framebuffer),
|
||||||
_flush_callback_registry(flush_callback_registry),
|
_flush_callback_registry(flush_callback_registry),
|
||||||
_io_buffer(Genode::env()->ram_session(), io_buffer_size),
|
_trigger_flush_callback(trigger_flush_callback),
|
||||||
_fb_mode(_framebuffer->mode()),
|
_io_buffer(env.ram(), env.rm(), io_buffer_size),
|
||||||
|
_fb_mode(_framebuffer.mode()),
|
||||||
_fb_ds_cap(_init_fb()),
|
_fb_ds_cap(_init_fb()),
|
||||||
|
|
||||||
/* take size of space character as character cell size */
|
/* take size of space character as character cell size */
|
||||||
@ -335,12 +351,12 @@ namespace Terminal {
|
|||||||
_columns(_fb_mode.width()/_char_width),
|
_columns(_fb_mode.width()/_char_width),
|
||||||
_lines(_fb_mode.height()/_char_height),
|
_lines(_fb_mode.height()/_char_height),
|
||||||
|
|
||||||
_fb_addr(Genode::env()->rm_session()->attach(_fb_ds_cap)),
|
_fb_addr(env.rm().attach(_fb_ds_cap)),
|
||||||
_char_cell_array(_columns, _lines, Genode::env()->heap()),
|
_char_cell_array(_columns, _lines, &alloc),
|
||||||
_char_cell_array_character_screen(_char_cell_array),
|
_char_cell_array_character_screen(_char_cell_array),
|
||||||
_decoder(_char_cell_array_character_screen),
|
_decoder(_char_cell_array_character_screen),
|
||||||
|
|
||||||
_font_family(&font_family)
|
_font_family(font_family)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -349,7 +365,7 @@ namespace Terminal {
|
|||||||
log(" character size is ", _char_width, "x", _char_height, " pixels");
|
log(" character size is ", _char_width, "x", _char_height, " pixels");
|
||||||
log(" terminal size is ", _columns, "x", _lines, " characters");
|
log(" terminal size is ", _columns, "x", _lines, " characters");
|
||||||
|
|
||||||
framebuffer->refresh(0, 0, _fb_mode.width(), _fb_mode.height());
|
framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height());
|
||||||
|
|
||||||
_flush_callback_registry.add(this);
|
_flush_callback_registry.add(this);
|
||||||
}
|
}
|
||||||
@ -367,7 +383,7 @@ namespace Terminal {
|
|||||||
(Pixel_rgb565 *)_fb_addr,
|
(Pixel_rgb565 *)_fb_addr,
|
||||||
_fb_mode.width(),
|
_fb_mode.width(),
|
||||||
_fb_mode.height(),
|
_fb_mode.height(),
|
||||||
*_font_family);
|
_font_family);
|
||||||
|
|
||||||
|
|
||||||
int first_dirty_line = 10000,
|
int first_dirty_line = 10000,
|
||||||
@ -384,9 +400,9 @@ namespace Terminal {
|
|||||||
|
|
||||||
int num_dirty_lines = last_dirty_line - first_dirty_line + 1;
|
int num_dirty_lines = last_dirty_line - first_dirty_line + 1;
|
||||||
if (num_dirty_lines > 0)
|
if (num_dirty_lines > 0)
|
||||||
_framebuffer->refresh(0, first_dirty_line*_char_height,
|
_framebuffer.refresh(0, first_dirty_line*_char_height,
|
||||||
_fb_mode.width(),
|
_fb_mode.width(),
|
||||||
num_dirty_lines*_char_height);
|
num_dirty_lines*_char_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -396,7 +412,7 @@ namespace Terminal {
|
|||||||
|
|
||||||
Size size() { return Size(_columns, _lines); }
|
Size size() { return Size(_columns, _lines); }
|
||||||
|
|
||||||
bool avail() { return !_read_buffer->empty(); }
|
bool avail() { return !_read_buffer.empty(); }
|
||||||
|
|
||||||
Genode::size_t _read(Genode::size_t dst_len)
|
Genode::size_t _read(Genode::size_t dst_len)
|
||||||
{
|
{
|
||||||
@ -404,9 +420,9 @@ namespace Terminal {
|
|||||||
unsigned num_bytes = 0;
|
unsigned num_bytes = 0;
|
||||||
unsigned char *dst = _io_buffer.local_addr<unsigned char>();
|
unsigned char *dst = _io_buffer.local_addr<unsigned char>();
|
||||||
Genode::size_t dst_size = Genode::min(_io_buffer.size(), dst_len);
|
Genode::size_t dst_size = Genode::min(_io_buffer.size(), dst_len);
|
||||||
do {
|
|
||||||
dst[num_bytes++] = _read_buffer->get();
|
while (!_read_buffer.empty() && num_bytes < dst_size)
|
||||||
} while (!_read_buffer->empty() && num_bytes < dst_size);
|
dst[num_bytes++] = _read_buffer.get();
|
||||||
|
|
||||||
return num_bytes;
|
return num_bytes;
|
||||||
}
|
}
|
||||||
@ -422,6 +438,7 @@ namespace Terminal {
|
|||||||
/* submit character to sequence decoder */
|
/* submit character to sequence decoder */
|
||||||
_decoder.insert(src[i]);
|
_decoder.insert(src[i]);
|
||||||
}
|
}
|
||||||
|
_trigger_flush_callback.trigger_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Dataspace_capability _dataspace()
|
Genode::Dataspace_capability _dataspace()
|
||||||
@ -441,7 +458,7 @@ namespace Terminal {
|
|||||||
|
|
||||||
void read_avail_sigh(Genode::Signal_context_capability cap)
|
void read_avail_sigh(Genode::Signal_context_capability cap)
|
||||||
{
|
{
|
||||||
_read_buffer->sigh(cap);
|
_read_buffer.sigh(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::size_t read(void *buf, Genode::size_t) { return 0; }
|
Genode::size_t read(void *buf, Genode::size_t) { return 0; }
|
||||||
@ -453,9 +470,11 @@ namespace Terminal {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Read_buffer *_read_buffer;
|
Genode::Env &_env;
|
||||||
Framebuffer::Session *_framebuffer;
|
Read_buffer &_read_buffer;
|
||||||
|
Framebuffer::Session &_framebuffer;
|
||||||
Flush_callback_registry &_flush_callback_registry;
|
Flush_callback_registry &_flush_callback_registry;
|
||||||
|
Trigger_flush_callback &_trigger_flush_callback;
|
||||||
Font_family const &_font_family;
|
Font_family const &_font_family;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -470,10 +489,12 @@ namespace Terminal {
|
|||||||
Genode::size_t io_buffer_size = 4096;
|
Genode::size_t io_buffer_size = 4096;
|
||||||
|
|
||||||
Session_component *session =
|
Session_component *session =
|
||||||
new (md_alloc()) Session_component(_read_buffer,
|
new (md_alloc()) Session_component(_env, *md_alloc(),
|
||||||
|
_read_buffer,
|
||||||
_framebuffer,
|
_framebuffer,
|
||||||
io_buffer_size,
|
io_buffer_size,
|
||||||
_flush_callback_registry,
|
_flush_callback_registry,
|
||||||
|
_trigger_flush_callback,
|
||||||
_font_family);
|
_font_family);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
@ -483,41 +504,175 @@ namespace Terminal {
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Root_component(Genode::Rpc_entrypoint *ep,
|
Root_component(Genode::Env &env,
|
||||||
Genode::Allocator *md_alloc,
|
Genode::Allocator &md_alloc,
|
||||||
Read_buffer *read_buffer,
|
Read_buffer &read_buffer,
|
||||||
Framebuffer::Session *framebuffer,
|
Framebuffer::Session &framebuffer,
|
||||||
Flush_callback_registry &flush_callback_registry,
|
Flush_callback_registry &flush_callback_registry,
|
||||||
|
Trigger_flush_callback &trigger_flush_callback,
|
||||||
Font_family const &font_family)
|
Font_family const &font_family)
|
||||||
:
|
:
|
||||||
Genode::Root_component<Session_component>(ep, md_alloc),
|
Genode::Root_component<Session_component>(env.ep(), md_alloc),
|
||||||
|
_env(env),
|
||||||
_read_buffer(read_buffer), _framebuffer(framebuffer),
|
_read_buffer(read_buffer), _framebuffer(framebuffer),
|
||||||
_flush_callback_registry(flush_callback_registry),
|
_flush_callback_registry(flush_callback_registry),
|
||||||
|
_trigger_flush_callback(trigger_flush_callback),
|
||||||
_font_family(font_family)
|
_font_family(font_family)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int, char **)
|
struct Terminal::Main
|
||||||
|
{
|
||||||
|
Genode::Env &_env;
|
||||||
|
|
||||||
|
Framebuffer::Connection _framebuffer { _env, Framebuffer::Mode() };
|
||||||
|
Input::Connection _input { _env };
|
||||||
|
Timer::Connection _timer_conection { _env };
|
||||||
|
Genode::Timer _timer { _timer_conection, _env.ep() };
|
||||||
|
|
||||||
|
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
|
||||||
|
|
||||||
|
/* input read buffer */
|
||||||
|
Read_buffer _read_buffer;
|
||||||
|
|
||||||
|
Terminal::Flush_callback_registry _flush_callback_registry;
|
||||||
|
|
||||||
|
/* create root interface for service */
|
||||||
|
Terminal::Root_component _root;
|
||||||
|
|
||||||
|
Terminal::Scancode_tracker _scancode_tracker;
|
||||||
|
|
||||||
|
/* state needed for key-repeat handling */
|
||||||
|
unsigned const _repeat_delay = 250;
|
||||||
|
unsigned const _repeat_rate = 25;
|
||||||
|
unsigned _repeat_next = 0;
|
||||||
|
|
||||||
|
void _handle_input();
|
||||||
|
|
||||||
|
Signal_handler<Main> _input_handler {
|
||||||
|
_env.ep(), *this, &Main::_handle_input };
|
||||||
|
|
||||||
|
void _handle_key_repeat(Time_source::Microseconds);
|
||||||
|
|
||||||
|
One_shot_timeout<Main> _key_repeat_timeout {
|
||||||
|
_timer, *this, &Main::_handle_key_repeat };
|
||||||
|
|
||||||
|
void _handle_flush(Time_source::Microseconds);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time in milliseconds between a change of the terminal content and the
|
||||||
|
* update of the pixels. By delaying the update, multiple intermediate
|
||||||
|
* changes result in only one rendering step.
|
||||||
|
*/
|
||||||
|
unsigned const _flush_delay = 5;
|
||||||
|
|
||||||
|
bool _flush_scheduled = false;
|
||||||
|
|
||||||
|
void _trigger_flush()
|
||||||
|
{
|
||||||
|
if (!_flush_scheduled) {
|
||||||
|
_flush_timeout.start(Time_source::Microseconds{1000*_flush_delay});
|
||||||
|
_flush_scheduled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback invoked if new terminal content appears
|
||||||
|
*/
|
||||||
|
struct Trigger_flush : Trigger_flush_callback
|
||||||
|
{
|
||||||
|
Main &_main;
|
||||||
|
void trigger_flush() override { _main._trigger_flush(); }
|
||||||
|
Trigger_flush(Main &main) : _main(main) { }
|
||||||
|
} _trigger_flush_callback { *this };
|
||||||
|
|
||||||
|
One_shot_timeout<Main> _flush_timeout {
|
||||||
|
_timer, *this, &Main::_handle_flush };
|
||||||
|
|
||||||
|
Main(Genode::Env &env,
|
||||||
|
Font_family &font_family,
|
||||||
|
unsigned char const *keymap,
|
||||||
|
unsigned char const *shift,
|
||||||
|
unsigned char const *altgr,
|
||||||
|
unsigned char const *control)
|
||||||
|
:
|
||||||
|
_env(env),
|
||||||
|
_root(_env, _sliced_heap,
|
||||||
|
_read_buffer, _framebuffer,
|
||||||
|
_flush_callback_registry,
|
||||||
|
_trigger_flush_callback,
|
||||||
|
font_family),
|
||||||
|
_scancode_tracker(keymap, shift, altgr, Terminal::control)
|
||||||
|
{
|
||||||
|
_input.sigh(_input_handler);
|
||||||
|
|
||||||
|
/* announce service at our parent */
|
||||||
|
_env.parent().announce(_env.ep().manage(_root));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Terminal::Main::_handle_input()
|
||||||
|
{
|
||||||
|
_input.for_each_event([&] (Input::Event const &event) {
|
||||||
|
bool press = (event.type() == Input::Event::PRESS ? true : false);
|
||||||
|
bool release = (event.type() == Input::Event::RELEASE ? true : false);
|
||||||
|
int keycode = event.code();
|
||||||
|
|
||||||
|
if (press || release)
|
||||||
|
_scancode_tracker.submit(keycode, press);
|
||||||
|
|
||||||
|
if (press) {
|
||||||
|
_scancode_tracker.emit_current_character(_read_buffer);
|
||||||
|
|
||||||
|
/* setup first key repeat */
|
||||||
|
_repeat_next = _repeat_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (release)
|
||||||
|
_repeat_next = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_repeat_next)
|
||||||
|
_key_repeat_timeout.start(Time_source::Microseconds{1000*_repeat_next});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Terminal::Main::_handle_key_repeat(Time_source::Microseconds)
|
||||||
|
{
|
||||||
|
if (_repeat_next) {
|
||||||
|
|
||||||
|
/* repeat current character or sequence */
|
||||||
|
_scancode_tracker.emit_current_character(_read_buffer);
|
||||||
|
|
||||||
|
_repeat_next = _repeat_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
_handle_input();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Terminal::Main::_handle_flush(Time_source::Microseconds)
|
||||||
|
{
|
||||||
|
_flush_scheduled = false;
|
||||||
|
_flush_callback_registry.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* built-in fonts */
|
||||||
|
extern char _binary_notix_8_tff_start;
|
||||||
|
extern char _binary_terminus_12_tff_start;
|
||||||
|
extern char _binary_terminus_16_tff_start;
|
||||||
|
|
||||||
|
|
||||||
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
log("--- terminal service started ---");
|
Attached_rom_dataspace config(env, "config");
|
||||||
|
|
||||||
static Framebuffer::Connection framebuffer;
|
|
||||||
static Input::Connection input;
|
|
||||||
static Timer::Connection timer;
|
|
||||||
static Cap_connection cap;
|
|
||||||
|
|
||||||
/* initialize entry point that serves the root interface */
|
|
||||||
enum { STACK_SIZE = 2*sizeof(addr_t)*1024 };
|
|
||||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "terminal_ep");
|
|
||||||
|
|
||||||
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
|
||||||
|
|
||||||
/* input read buffer */
|
|
||||||
static Terminal::Read_buffer read_buffer;
|
|
||||||
|
|
||||||
/* initialize color palette */
|
/* initialize color palette */
|
||||||
color_palette[0] = Color( 0, 0, 0); /* black */
|
color_palette[0] = Color( 0, 0, 0); /* black */
|
||||||
@ -536,17 +691,11 @@ int main(int, char **)
|
|||||||
color_palette[i + 8] = col;
|
color_palette[i + 8] = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* built-in fonts */
|
|
||||||
extern char _binary_notix_8_tff_start;
|
|
||||||
extern char _binary_terminus_12_tff_start;
|
|
||||||
extern char _binary_terminus_16_tff_start;
|
|
||||||
|
|
||||||
/* pick font according to config file */
|
/* pick font according to config file */
|
||||||
char const *font_data = &_binary_terminus_16_tff_start;
|
char const *font_data = &_binary_terminus_16_tff_start;
|
||||||
try {
|
try {
|
||||||
size_t font_size = 16;
|
size_t font_size = 16;
|
||||||
config()->xml_node().sub_node("font")
|
config.xml().sub_node("font").attribute("size").value(&font_size);
|
||||||
.attribute("size").value(&font_size);
|
|
||||||
|
|
||||||
switch (font_size) {
|
switch (font_size) {
|
||||||
case 8: font_data = &_binary_notix_8_tff_start; break;
|
case 8: font_data = &_binary_notix_8_tff_start; break;
|
||||||
@ -562,22 +711,6 @@ int main(int, char **)
|
|||||||
log("cell size is ", (int)font_family.cell_width(),
|
log("cell size is ", (int)font_family.cell_width(),
|
||||||
"x", (int)font_family.cell_height());
|
"x", (int)font_family.cell_height());
|
||||||
|
|
||||||
static Terminal::Flush_callback_registry flush_callback_registry;
|
|
||||||
|
|
||||||
/* create root interface for service */
|
|
||||||
static Terminal::Root_component root(&ep, &sliced_heap,
|
|
||||||
&read_buffer, &framebuffer,
|
|
||||||
flush_callback_registry,
|
|
||||||
font_family);
|
|
||||||
|
|
||||||
/* announce service at our parent */
|
|
||||||
env()->parent()->announce(ep.manage(&root));
|
|
||||||
|
|
||||||
/* state needed for key-repeat handling */
|
|
||||||
static int const repeat_delay = 170;
|
|
||||||
static int const repeat_rate = 25;
|
|
||||||
static int repeat_cnt = 0;
|
|
||||||
|
|
||||||
unsigned char *keymap = Terminal::usenglish_keymap;
|
unsigned char *keymap = Terminal::usenglish_keymap;
|
||||||
unsigned char *shift = Terminal::usenglish_shift;
|
unsigned char *shift = Terminal::usenglish_shift;
|
||||||
unsigned char *altgr = 0;
|
unsigned char *altgr = 0;
|
||||||
@ -586,7 +719,7 @@ int main(int, char **)
|
|||||||
* Read keyboard layout from config file
|
* Read keyboard layout from config file
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
if (config()->xml_node().sub_node("keyboard")
|
if (config.xml().sub_node("keyboard")
|
||||||
.attribute("layout").has_value("de")) {
|
.attribute("layout").has_value("de")) {
|
||||||
|
|
||||||
keymap = Terminal::german_keymap;
|
keymap = Terminal::german_keymap;
|
||||||
@ -595,47 +728,5 @@ int main(int, char **)
|
|||||||
}
|
}
|
||||||
} catch (...) { }
|
} catch (...) { }
|
||||||
|
|
||||||
static Terminal::Scancode_tracker
|
static Terminal::Main main(env, font_family, keymap, shift, altgr, Terminal::control);
|
||||||
scancode_tracker(keymap, shift, altgr, Terminal::control);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
flush_callback_registry.flush();
|
|
||||||
|
|
||||||
while (!input.pending()) {
|
|
||||||
enum { PASSED_MSECS = 10 };
|
|
||||||
timer.msleep(PASSED_MSECS);
|
|
||||||
|
|
||||||
flush_callback_registry.flush();
|
|
||||||
|
|
||||||
if (scancode_tracker.valid()) {
|
|
||||||
repeat_cnt -= PASSED_MSECS;
|
|
||||||
|
|
||||||
if (repeat_cnt < 0) {
|
|
||||||
|
|
||||||
/* repeat current character or sequence */
|
|
||||||
scancode_tracker.emit_current_character(read_buffer);
|
|
||||||
|
|
||||||
/* reset repeat counter according to repeat rate */
|
|
||||||
repeat_cnt = repeat_rate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input.for_each_event([&] (Input::Event const &event) {
|
|
||||||
bool press = (event.type() == Input::Event::PRESS ? true : false);
|
|
||||||
bool release = (event.type() == Input::Event::RELEASE ? true : false);
|
|
||||||
int keycode = event.code();
|
|
||||||
|
|
||||||
if (press || release)
|
|
||||||
scancode_tracker.submit(keycode, press);
|
|
||||||
|
|
||||||
if (press)
|
|
||||||
scancode_tracker.emit_current_character(read_buffer);
|
|
||||||
|
|
||||||
/* setup first key repeat */
|
|
||||||
repeat_cnt = repeat_delay;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TARGET = terminal
|
TARGET = terminal
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base config
|
LIBS = base timeout
|
||||||
SRC_BIN = $(notdir $(wildcard $(PRG_DIR)/*.tff))
|
SRC_BIN = $(notdir $(wildcard $(PRG_DIR)/*.tff))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user