synergy_input: port of the µSynergy client
http://synergy-project.org/ Fixes #14
This commit is contained in:
committed by
Norman Feske
parent
cce6a99fc7
commit
9a0fead7ed
1
ports/synergy_micro.hash
Normal file
1
ports/synergy_micro.hash
Normal file
@@ -0,0 +1 @@
|
||||
96bc07a2a74638e198454cf6cee9cbb1176dd51e
|
||||
9
ports/synergy_micro.port
Normal file
9
ports/synergy_micro.port
Normal file
@@ -0,0 +1,9 @@
|
||||
LICENSE := GPLv2
|
||||
VERSION := 1.7.6
|
||||
DOWNLOADS := synergy_micro.archive
|
||||
|
||||
URL(synergy_micro) := https://github.com/symless/synergy/archive/v$(VERSION)-stable.tar.gz
|
||||
SHA(synergy_micro) := 01936476040b85c08d1077c4dd9614303c78f69b
|
||||
DIR(synergy_micro) := src/lib/synergy_micro
|
||||
|
||||
TAR_OPT(synergy_micro) := --strip-components 3 synergy-$(VERSION)-stable/src/micro
|
||||
83
run/synergy.inc
Normal file
83
run/synergy.inc
Normal file
@@ -0,0 +1,83 @@
|
||||
if ![have_installed synergys] {
|
||||
puts stderr "\nsynergy server not installed\n"
|
||||
exit -1
|
||||
}
|
||||
|
||||
proc append_synergy_build_components { } {
|
||||
global build_components
|
||||
append build_components { drivers/nic server/synergy_input }
|
||||
}
|
||||
|
||||
proc append_synergy_config { } {
|
||||
global config
|
||||
|
||||
append config {
|
||||
<start name="nic_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="synergy_input">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
<config addr="10.0.2.2" name="genode-up"/>
|
||||
</start>
|
||||
}
|
||||
}
|
||||
|
||||
proc append_synergy_boot_modules { } {
|
||||
global boot_modules
|
||||
append boot_modules { nic_drv libc.lib.so lwip.lib.so synergy_input }
|
||||
}
|
||||
|
||||
|
||||
proc write_synergy_host_config { } {
|
||||
set fh [ open "bin/synergy.conf" w]
|
||||
puts $fh {
|
||||
section: screens
|
||||
localhost:
|
||||
genode-up:
|
||||
genode-left:
|
||||
genode-right:
|
||||
genode-down:
|
||||
end
|
||||
|
||||
section: links
|
||||
|
||||
localhost:
|
||||
up = genode-up
|
||||
left = genode-left
|
||||
right = genode-right
|
||||
down = genode-down
|
||||
|
||||
genode-up:
|
||||
down = localhost
|
||||
|
||||
genode-left:
|
||||
up = localhost
|
||||
right = localhost
|
||||
down = localhost
|
||||
|
||||
genode-right:
|
||||
up = localhost
|
||||
left = localhost
|
||||
down = localhost
|
||||
|
||||
genode-down:
|
||||
up = localhost
|
||||
end
|
||||
}
|
||||
close $fh
|
||||
}
|
||||
|
||||
|
||||
proc remove_synergy_host_config { } {
|
||||
file delete "bin/synergy.conf"
|
||||
}
|
||||
|
||||
|
||||
proc start_synergy_host { } {
|
||||
puts stderr "spawning synergys"
|
||||
spawn synergys \
|
||||
-f -d DEBUG -n localhost -c bin/synergy.conf
|
||||
}
|
||||
95
run/synergy.run
Normal file
95
run/synergy.run
Normal file
@@ -0,0 +1,95 @@
|
||||
source ${genode_dir}/repos/emery/run/synergy.inc
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
test/input
|
||||
}
|
||||
|
||||
append_synergy_build_components
|
||||
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service>
|
||||
<parent/> <any-child/>
|
||||
</any-service>
|
||||
</default-route>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="test-input">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>}
|
||||
|
||||
append_synergy_config
|
||||
|
||||
append config {
|
||||
</config>}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init ld.lib.so
|
||||
timer
|
||||
test-input
|
||||
}
|
||||
|
||||
append_synergy_boot_modules
|
||||
|
||||
# platform-specific modules
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -net user"
|
||||
|
||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000"
|
||||
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118"
|
||||
|
||||
write_synergy_host_config
|
||||
start_synergy_host
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
remove_synergy_host_config
|
||||
281
run/synergy_nitpicker.run
Normal file
281
run/synergy_nitpicker.run
Normal file
@@ -0,0 +1,281 @@
|
||||
#
|
||||
# Instantiate two Synergy clients
|
||||
#
|
||||
|
||||
source ${genode_dir}/repos/emery/run/synergy.inc
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
server/nic_bridge
|
||||
drivers/framebuffer
|
||||
drivers/input/dummy
|
||||
server/nitpicker
|
||||
server/nit_fb
|
||||
test/nitpicker
|
||||
app/pointer
|
||||
}
|
||||
|
||||
append_synergy_build_components
|
||||
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
append config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service>
|
||||
<parent/>
|
||||
<child name="nic_bridge"/>
|
||||
<any-child/>
|
||||
</any-service>
|
||||
</default-route>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append_if [have_spec sdl] config {
|
||||
<start name="fb_sdl">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="Input"/>
|
||||
<service name="Framebuffer"/>
|
||||
</provides>
|
||||
<config width="640" height="480"/>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec framebuffer] config {
|
||||
<start name="fb_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<config buffered="yes" width="640" height="480"/>
|
||||
</start>}
|
||||
|
||||
append config {
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
|
||||
<!--
|
||||
<start name="testnit">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
-->
|
||||
|
||||
<start name="nic_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="nic_bridge">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<route>
|
||||
<any-service>
|
||||
<parent/> <child name="nic_drv"/> <any-child/>
|
||||
</any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="dummy_input_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Nitpicker"/></provides>
|
||||
<config>
|
||||
<domain name="left" layer="2" origin="top_left" />
|
||||
<domain name="right" layer="2" origin="top_right" xpos="-340"/>
|
||||
<domain name="" layer="1"/>
|
||||
|
||||
<policy label="left" domain="left"/>
|
||||
<policy label="right" domain="right"/>
|
||||
<policy label="" domain=""/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="left">
|
||||
<binary name="init"/>
|
||||
<resource name="RAM" quantum="24M"/>
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="CAP"/>
|
||||
<service name="SIGNAL"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Nitpicker"/>
|
||||
<service name="Nic"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service>
|
||||
<child name="synergy_input"/>
|
||||
<child name="nitpicker"/>
|
||||
<any-child/>
|
||||
<parent/>
|
||||
</any-service>
|
||||
</default-route>
|
||||
<start name="nit_fb">
|
||||
<resource name="RAM" quantum="8M" />
|
||||
<provides>
|
||||
<service name="Framebuffer" />
|
||||
<service name="Input" />
|
||||
</provides>
|
||||
<config width="340" height="480" />
|
||||
<route>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="synergy_input">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
<config addr="10.0.2.2" name="genode-left"/>
|
||||
</start>
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Nitpicker"/></provides>
|
||||
<config>
|
||||
<background color="#808080"/>
|
||||
<domain name="pointer" layer="1" xray="no" origin="pointer" />
|
||||
<domain name="" layer="2"/>
|
||||
<policy label="pointer" domain="pointer"/>
|
||||
<policy label="" domain=""/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="pointer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
<start name="testnit">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
<start name="right">
|
||||
<binary name="init"/>
|
||||
<resource name="RAM" quantum="24M"/>
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="CAP"/>
|
||||
<service name="SIGNAL"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Nitpicker"/>
|
||||
<service name="Nic"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service>
|
||||
<child name="synergy_input"/>
|
||||
<any-child/>
|
||||
<parent/>
|
||||
</any-service>
|
||||
</default-route>
|
||||
<start name="nit_fb">
|
||||
<resource name="RAM" quantum="8M" />
|
||||
<provides>
|
||||
<service name="Framebuffer" />
|
||||
<service name="Input" />
|
||||
</provides>
|
||||
<config width="340" height="480" />
|
||||
<route>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="synergy_input">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
<config addr="10.0.2.2" name="genode-right"/>
|
||||
</start>
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Nitpicker"/></provides>
|
||||
<config>
|
||||
<background color="#800000"/>
|
||||
<domain name="pointer" layer="1" xray="no" origin="pointer" />
|
||||
<domain name="" layer="2"/>
|
||||
<policy label="pointer" domain="pointer"/>
|
||||
<policy label="" domain=""/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="pointer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
<start name="testnit">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
</config>}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init ld.lib.so
|
||||
timer
|
||||
fb_drv
|
||||
dummy_input_drv
|
||||
nitpicker
|
||||
testnit
|
||||
nic_bridge nit_fb
|
||||
pointer
|
||||
}
|
||||
|
||||
append_synergy_boot_modules
|
||||
|
||||
# platform-specific modules
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -net user"
|
||||
|
||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000"
|
||||
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118"
|
||||
|
||||
write_synergy_host_config
|
||||
start_synergy_host
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
remove_synergy_host_config
|
||||
402
src/server/synergy_input/main.cc
Normal file
402
src/server/synergy_input/main.cc
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* \brief Synergy client
|
||||
* \author Emery Hemingway
|
||||
* \date 2015-06-14
|
||||
*
|
||||
* http://synergy-project.org/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/component.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/static_root.h>
|
||||
#include <os/signal_rpc_dispatcher.h>
|
||||
#include <os/config.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* Synergy includes */
|
||||
#include <uSynergy.h>
|
||||
|
||||
/* socket API */
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/ioctl.h>
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Timer::Session *timer()
|
||||
{
|
||||
static Timer::Connection _timer;
|
||||
return &_timer;
|
||||
}
|
||||
|
||||
struct Session_component : Input::Session_component
|
||||
{
|
||||
/* Array for tracking the current keyboard state */
|
||||
bool key_state[Input::KEY_MAX + 1];
|
||||
int socket_fd;
|
||||
uSynergyBool button_left;
|
||||
uSynergyBool button_right;
|
||||
uSynergyBool button_middle;
|
||||
|
||||
Session_component()
|
||||
: socket_fd(-1) { }
|
||||
|
||||
~Session_component()
|
||||
{
|
||||
::close(socket_fd);
|
||||
}
|
||||
|
||||
void reset_keys()
|
||||
{
|
||||
for (int i = 0; i <= Input::KEY_MAX; i++)
|
||||
key_state[i] = false;
|
||||
button_left = USYNERGY_FALSE;
|
||||
button_right = USYNERGY_FALSE;
|
||||
button_right = USYNERGY_FALSE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
** Synergy callbacks **
|
||||
***********************/
|
||||
|
||||
static uSynergyBool connect(uSynergyCookie cookie)
|
||||
{
|
||||
Session_component *session = (Session_component*)cookie;
|
||||
|
||||
/******************
|
||||
** Parse config **
|
||||
******************/
|
||||
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
unsigned long port = 24800;
|
||||
|
||||
Xml_node config_node = config()->xml_node();
|
||||
|
||||
try {
|
||||
config_node.attribute("addr").value(addr, sizeof(addr));
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
PERR("server address not set in config");
|
||||
return USYNERGY_FALSE;
|
||||
}
|
||||
|
||||
try {
|
||||
config_node.attribute("port").value(&port);
|
||||
} catch (...) { }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Open and connect socket **
|
||||
*****************************/
|
||||
|
||||
sockaddr_in sockaddr;
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_port = htons(port);
|
||||
if (inet_pton(AF_INET, addr, &sockaddr.sin_addr.s_addr) == 0) {
|
||||
PERR("bad IPv4 address %s for server", addr);
|
||||
return USYNERGY_FALSE;
|
||||
}
|
||||
|
||||
session->socket_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (session->socket_fd == -1)
|
||||
return USYNERGY_FALSE;
|
||||
|
||||
if (::connect(session->socket_fd, (struct sockaddr*) &sockaddr, sizeof(sockaddr))) {
|
||||
::close(session->socket_fd);
|
||||
return USYNERGY_FALSE;
|
||||
}
|
||||
return USYNERGY_TRUE;
|
||||
}
|
||||
|
||||
uSynergyBool send(uSynergyCookie cookie, const uint8_t *buffer, int length)
|
||||
{
|
||||
Session_component *session = (Session_component*)cookie;
|
||||
|
||||
return (length == ::write(session->socket_fd, buffer, length)) ?
|
||||
USYNERGY_TRUE : USYNERGY_FALSE;
|
||||
}
|
||||
|
||||
uSynergyBool receive(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
|
||||
{
|
||||
Session_component *session = (Session_component*)cookie;
|
||||
|
||||
*outLength = ::read(session->socket_fd, buffer, maxLength);
|
||||
if (!*outLength)
|
||||
return USYNERGY_FALSE;
|
||||
|
||||
return USYNERGY_TRUE;
|
||||
}
|
||||
|
||||
void sleep(uSynergyCookie, int timeMs) { timer()->msleep(timeMs); }
|
||||
|
||||
uint32_t get_time() { return timer()->elapsed_ms(); }
|
||||
|
||||
void trace_callback(uSynergyCookie cookie, const char *text) { PLOG("%s", text); }
|
||||
|
||||
void screen_active_callback(uSynergyCookie cookie, uSynergyBool active)
|
||||
{
|
||||
if (!active) {
|
||||
Session_component *session = (Session_component*)cookie;
|
||||
Input::Event_queue &queue = session->event_queue();
|
||||
queue.reset();
|
||||
queue.add(Input::Event(Input::Event::LEAVE, 0, 0, 0, 0, 0));
|
||||
session->reset_keys();
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_callback(uSynergyCookie cookie,
|
||||
uint16_t x, uint16_t y,
|
||||
int16_t wheelX, int16_t wheelY,
|
||||
uSynergyBool buttonLeft,
|
||||
uSynergyBool buttonRight,
|
||||
uSynergyBool buttonMiddle)
|
||||
{
|
||||
Session_component *session = (Session_component*)cookie;
|
||||
Input::Event_queue &queue = session->event_queue();
|
||||
|
||||
if (queue.avail_capacity() < 5)
|
||||
queue.reset();
|
||||
|
||||
/* Defer sending a signal until all conditions are processed */
|
||||
|
||||
queue.add(Input::Event(Input::Event::MOTION, 0, x, y, 0, 0), false);
|
||||
queue.add(Input::Event(Input::Event::WHEEL, 0, wheelX, wheelY, 0, 0), false);
|
||||
|
||||
if (buttonLeft != session->button_left)
|
||||
queue.add(Input::Event((session->button_left = buttonLeft) ?
|
||||
Input::Event::PRESS : Input::Event::RELEASE,
|
||||
Input::BTN_LEFT, 0, 0, 0, 0), false);
|
||||
|
||||
if (buttonRight != session->button_right)
|
||||
queue.add(Input::Event((session->button_right = buttonRight) ?
|
||||
Input::Event::PRESS : Input::Event::RELEASE,
|
||||
Input::BTN_RIGHT, 0, 0, 0, 0), false);
|
||||
|
||||
if (buttonMiddle != session->button_middle)
|
||||
queue.add(Input::Event((session->button_middle = buttonMiddle) ?
|
||||
Input::Event::PRESS : Input::Event::RELEASE,
|
||||
Input::BTN_MIDDLE, 0, 0, 0, 0), false);
|
||||
queue.submit_signal();
|
||||
}
|
||||
|
||||
void keyboard_callback(uSynergyCookie cookie,
|
||||
uint16_t key, uint16_t modifiers,
|
||||
uSynergyBool down, uSynergyBool repeat)
|
||||
{
|
||||
Session_component *session = (Session_component*)cookie;
|
||||
Input::Event_queue &queue = session->event_queue();
|
||||
|
||||
if (!queue.avail_capacity()) queue.reset();
|
||||
|
||||
key -= 8; // TODO what is <8?
|
||||
if (key > Input::KEY_MAX) return;
|
||||
|
||||
queue.add(Input::Event(((session->key_state[key] = !session->key_state[key]) ?
|
||||
Input::Event::PRESS : Input::Event::RELEASE),
|
||||
key, 0, 0, 0, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* void joystick_callback(uSynergyCookie cookie,
|
||||
* uint8_t joyNum,
|
||||
* uint16_t buttons,
|
||||
* int8_t leftStickX, int8_t leftStickY,
|
||||
* int8_t rightStickX, int8_t rightStickY);
|
||||
*/
|
||||
|
||||
|
||||
/*******************************
|
||||
** Network processing thread **
|
||||
*******************************/
|
||||
|
||||
struct Synergy_thread : Thread_base
|
||||
{
|
||||
|
||||
enum {
|
||||
MAX_NAME_LEN = 256,
|
||||
WEIGHT = Cpu_session::DEFAULT_WEIGHT,
|
||||
STACK_SIZE = 1024*sizeof(long)
|
||||
};
|
||||
|
||||
char screen_name[MAX_NAME_LEN];
|
||||
uSynergyContext context;
|
||||
Signal_receiver config_rec;
|
||||
Signal_context config_ctx;
|
||||
|
||||
Synergy_thread(Session_component &session)
|
||||
: Thread_base(WEIGHT, "synergy_ep", STACK_SIZE)
|
||||
{
|
||||
*screen_name = 0;
|
||||
uSynergyInit(&context);
|
||||
|
||||
context.m_connectFunc = &connect; /* Connect function */
|
||||
context.m_sendFunc = &send; /* Send data function */
|
||||
context.m_receiveFunc = &receive; /* Receive data function */
|
||||
context.m_sleepFunc = &sleep; /* Thread sleep function */
|
||||
context.m_getTimeFunc = &get_time; /* Get current time function */
|
||||
context.m_clientName = screen_name; /* Name of Synergy Screen */
|
||||
|
||||
context.m_cookie = (uSynergyCookie)&session; /* Cookie pointer passed to callback functions (can be NULL) */
|
||||
context.m_traceFunc = &trace_callback; /* Function for tracing status (can be NULL) */
|
||||
context.m_screenActiveCallback = &screen_active_callback; /* Callback for entering and leaving screen */
|
||||
context.m_mouseCallback = &mouse_callback; /* Callback for mouse events */
|
||||
context.m_keyboardCallback = &keyboard_callback; /* Callback for keyboard events */
|
||||
|
||||
config()->sigh(config_rec.manage(&config_ctx));
|
||||
}
|
||||
|
||||
~Synergy_thread()
|
||||
{
|
||||
config_rec.dissolve(&config_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration; return success state
|
||||
*/
|
||||
bool update_config()
|
||||
{
|
||||
/*
|
||||
* TODO: detect changes to network config
|
||||
* and trigger a reconnect if appropriate.
|
||||
*/
|
||||
Xml_node config_node = config()->xml_node();
|
||||
|
||||
try {
|
||||
config_node.attribute("addr");;
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
PERR("server address not set in config");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
config_node.attribute("name").value(screen_name, sizeof(screen_name));
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
PERR("client screen name not set in config, waiting for update");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: just get the capability for framebuffer or nitpicker,
|
||||
* then make a simple resolution client that wraps that.
|
||||
*/
|
||||
|
||||
try {
|
||||
Framebuffer::Connection conn;
|
||||
Framebuffer::Mode mode = conn.mode();
|
||||
|
||||
context.m_clientWidth = mode.width();
|
||||
context.m_clientHeight = mode.height();
|
||||
return true;
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
Nitpicker::Connection conn;
|
||||
Framebuffer::Mode mode = conn.mode();
|
||||
|
||||
context.m_clientWidth = mode.width();
|
||||
context.m_clientHeight = mode.height();
|
||||
return true;
|
||||
} catch (...) { }
|
||||
|
||||
/*
|
||||
* No real pointer space, but give the server a small holding area.
|
||||
*
|
||||
* XXX: drop pointer events without a screen?
|
||||
*/
|
||||
context.m_clientWidth = context.m_clientHeight = 64;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the config, then spin on the Synergy update function.
|
||||
*
|
||||
* If the config is not valid, block until it is updated.
|
||||
*/
|
||||
void entry()
|
||||
{
|
||||
while (!update_config()) {
|
||||
config_rec.wait_for_signal();
|
||||
config()->reload();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uSynergyUpdate(&context);
|
||||
if (config_rec.pending()) {
|
||||
while (!update_config())
|
||||
config_rec.wait_for_signal();
|
||||
config()->reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/******************
|
||||
** Main program **
|
||||
******************/
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
/*
|
||||
* Input session provided to our client
|
||||
*/
|
||||
Session_component session_component;
|
||||
|
||||
/*
|
||||
* Attach root interface to the entry point
|
||||
*/
|
||||
Static_root<Input::Session> input_root { ep.manage(session_component) };
|
||||
|
||||
/*
|
||||
* Additional thread for processing incoming events.
|
||||
*/
|
||||
Synergy_thread synergy_thread { session_component };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Main(Server::Entrypoint &ep) : ep(ep)
|
||||
{
|
||||
session_component.event_queue().enabled(true);
|
||||
|
||||
Genode::env()->parent()->announce(ep.manage(input_root));
|
||||
|
||||
synergy_thread.start();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
|
||||
char const *name() { return "synergy_client_ep"; }
|
||||
|
||||
size_t stack_size() { return 1; }
|
||||
|
||||
void construct(Entrypoint &ep) { static Main inst(ep); }
|
||||
}
|
||||
10
src/server/synergy_input/target.mk
Normal file
10
src/server/synergy_input/target.mk
Normal file
@@ -0,0 +1,10 @@
|
||||
SYNERGY_SRC_DIR = $(call select_from_ports,synergy_micro)/src/lib/synergy_micro
|
||||
|
||||
TARGET = synergy_input
|
||||
INC_DIR += $(SYNERGY_SRC_DIR)
|
||||
SRC_C = uSynergy.c
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server libc libc_lwip_nic_dhcp
|
||||
|
||||
vpath uSynergy.c $(SYNERGY_SRC_DIR)
|
||||
vpath main.cc $(PRG_DIR)
|
||||
Reference in New Issue
Block a user