Skip to content

Commit 27d3b1f

Browse files
Allow screen switching on local XInput
Allows to switch from client to server and vice versa if local input is detected, e.g. a touchscreen input or a mouse click if clients also have input devices
1 parent d186548 commit 27d3b1f

17 files changed

+338
-114
lines changed

src/lib/barrier/protocol_types.cpp

+24-23
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
* barrier -- mouse and keyboard sharing utility
33
* Copyright (C) 2012-2016 Symless Ltd.
44
* Copyright (C) 2002 Chris Schoeneman
5-
*
5+
*
66
* This package is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU General Public License
88
* found in the file LICENSE that should have accompanied this file.
9-
*
9+
*
1010
* This package is distributed in the hope that it will be useful,
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -20,34 +20,35 @@
2020

2121
const char* kMsgHello = "Barrier%2i%2i";
2222
const char* kMsgHelloBack = "Barrier%2i%2i%s";
23-
const char* kMsgCNoop = "CNOP";
24-
const char* kMsgCClose = "CBYE";
25-
const char* kMsgCEnter = "CINN%2i%2i%4i%2i";
26-
const char* kMsgCLeave = "COUT";
27-
const char* kMsgCClipboard = "CCLP%1i%4i";
23+
const char* kMsgCNoop = "CNOP";
24+
const char* kMsgCClose = "CBYE";
25+
const char* kMsgCEnter = "CINN%2i%2i%4i%2i";
26+
const char* kMsgCLeave = "COUT";
27+
const char* kMsgCClipboard = "CCLP%1i%4i";
2828
const char* kMsgCScreenSaver = "CSEC%1i";
2929
const char* kMsgCResetOptions = "CROP";
30-
const char* kMsgCInfoAck = "CIAK";
31-
const char* kMsgCKeepAlive = "CALV";
32-
const char* kMsgDKeyDown = "DKDN%2i%2i%2i";
33-
const char* kMsgDKeyDown1_0 = "DKDN%2i%2i";
34-
const char* kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i";
30+
const char* kMsgCInfoAck = "CIAK";
31+
const char* kMsgCKeepAlive = "CALV";
32+
const char* kMsgCLocalInput = "CLIN%2i%2i";
33+
const char* kMsgDKeyDown = "DKDN%2i%2i%2i";
34+
const char* kMsgDKeyDown1_0 = "DKDN%2i%2i";
35+
const char* kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i";
3536
const char* kMsgDKeyRepeat1_0 = "DKRP%2i%2i%2i";
36-
const char* kMsgDKeyUp = "DKUP%2i%2i%2i";
37+
const char* kMsgDKeyUp = "DKUP%2i%2i%2i";
3738
const char* kMsgDKeyUp1_0 = "DKUP%2i%2i";
38-
const char* kMsgDMouseDown = "DMDN%1i";
39-
const char* kMsgDMouseUp = "DMUP%1i";
40-
const char* kMsgDMouseMove = "DMMV%2i%2i";
39+
const char* kMsgDMouseDown = "DMDN%1i";
40+
const char* kMsgDMouseUp = "DMUP%1i";
41+
const char* kMsgDMouseMove = "DMMV%2i%2i";
4142
const char* kMsgDMouseRelMove = "DMRM%2i%2i";
42-
const char* kMsgDMouseWheel = "DMWM%2i%2i";
43-
const char* kMsgDMouseWheel1_0 = "DMWM%2i";
44-
const char* kMsgDClipboard = "DCLP%1i%4i%1i%s";
43+
const char* kMsgDMouseWheel = "DMWM%2i%2i";
44+
const char* kMsgDMouseWheel1_0 = "DMWM%2i";
45+
const char* kMsgDClipboard = "DCLP%1i%4i%1i%s";
4546
const char* kMsgDInfo = "DINF%2i%2i%2i%2i%2i%2i%2i";
46-
const char* kMsgDSetOptions = "DSOP%4I";
47+
const char* kMsgDSetOptions = "DSOP%4I";
4748
const char* kMsgDFileTransfer = "DFTR%1i%s";
4849
const char* kMsgDDragInfo = "DDRG%2i%s";
4950
const char* kMsgQInfo = "QINF";
5051
const char* kMsgEIncompatible = "EICV%2i%2i";
51-
const char* kMsgEBusy = "EBSY";
52-
const char* kMsgEUnknown = "EUNK";
53-
const char* kMsgEBad = "EBAD";
52+
const char* kMsgEBusy = "EBSY";
53+
const char* kMsgEUnknown = "EUNK";
54+
const char* kMsgEBad = "EBAD";

src/lib/barrier/protocol_types.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
// 1.4: adds crypto support
3030
// 1.5: adds file transfer and removes home brew crypto
3131
// 1.6: adds clipboard streaming
32+
// 1.7: adds focus/screen switch on local input
3233
// NOTE: with new version, barrier minor version should increment
3334
static const SInt16 kProtocolMajorVersion = 1;
34-
static const SInt16 kProtocolMinorVersion = 6;
35+
static const SInt16 kProtocolMinorVersion = 7;
3536

3637
// default contact port number
3738
static const UInt16 kDefaultPort = 24800;
@@ -172,6 +173,10 @@ extern const char* kMsgCInfoAck;
172173
// defined by an option.
173174
extern const char* kMsgCKeepAlive;
174175

176+
// Local input: secondary -> primary
177+
// Inform primary about local input to request focus
178+
extern const char* kMsgCLocalInput;
179+
175180
//
176181
// data codes
177182
//

src/lib/base/EventQueue.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
* barrier -- mouse and keyboard sharing utility
33
* Copyright (C) 2012-2016 Symless Ltd.
44
* Copyright (C) 2004 Chris Schoeneman
5-
*
5+
*
66
* This package is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU General Public License
88
* found in the file LICENSE that should have accompanied this file.
9-
*
9+
*
1010
* This package is distributed in the hope that it will be useful,
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -100,7 +100,7 @@ EventQueue::~EventQueue()
100100
delete m_buffer;
101101
delete m_readyCondVar;
102102
delete m_readyMutex;
103-
103+
104104
ARCH->setSignalHandler(Arch::kINTERRUPT, NULL, NULL);
105105
ARCH->setSignalHandler(Arch::kTERMINATE, NULL, NULL);
106106
}
@@ -121,7 +121,7 @@ EventQueue::loop()
121121
addEventToBuffer(event);
122122
m_pending.pop();
123123
}
124-
124+
125125
Event event;
126126
getEvent(event);
127127
while (event.getType() != Event::kQuit) {
@@ -298,7 +298,7 @@ EventQueue::addEvent(const Event& event)
298298
default:
299299
break;
300300
}
301-
301+
302302
if ((event.getFlags() & Event::kDeliverImmediately) != 0) {
303303
dispatchEvent(event);
304304
Event::deleteData(event);
@@ -315,10 +315,10 @@ void
315315
EventQueue::addEventToBuffer(const Event& event)
316316
{
317317
std::lock_guard<std::mutex> lock(m_mutex);
318-
318+
319319
// store the event's data locally
320320
UInt32 eventID = saveEvent(event);
321-
321+
322322
// add it
323323
if (!m_buffer->addEvent(eventID)) {
324324
// failed to send event
@@ -568,7 +568,7 @@ EventQueue::waitForReady() const
568568
{
569569
double timeout = ARCH->time() + 10;
570570
Lock lock(m_readyMutex);
571-
571+
572572
while (!m_readyCondVar->wait()) {
573573
if (ARCH->time() > timeout) {
574574
throw std::runtime_error("event queue is not ready within 5 sec");

src/lib/base/EventTypes.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ REGISTER_EVENT(IPrimaryScreen, fakeInputEnd)
177177

178178
REGISTER_EVENT(IScreen, error)
179179
REGISTER_EVENT(IScreen, shapeChanged)
180+
REGISTER_EVENT(IScreen, localInput)
180181
REGISTER_EVENT(IScreen, suspend)
181182
REGISTER_EVENT(IScreen, resume)
182183

src/lib/base/EventTypes.h

+10
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ class IScreenEvents : public EventTypes {
651651
IScreenEvents() :
652652
m_error(Event::kUnknown),
653653
m_shapeChanged(Event::kUnknown),
654+
m_localInput(Event::kUnknown),
654655
m_suspend(Event::kUnknown),
655656
m_resume(Event::kUnknown) { }
656657

@@ -671,6 +672,14 @@ class IScreenEvents : public EventTypes {
671672
*/
672673
Event::Type shapeChanged();
673674

675+
//! Get local input event type
676+
/*!
677+
Returns the local input event type. This is sent when the cursor
678+
is not on the current screen but a local input is detected (e.g.
679+
via touchscreen inputs or mouse movements).
680+
*/
681+
Event::Type localInput();
682+
674683
//! Get suspend event type
675684
/*!
676685
Returns the suspend event type. This is sent whenever the system goes
@@ -690,6 +699,7 @@ class IScreenEvents : public EventTypes {
690699
private:
691700
Event::Type m_error;
692701
Event::Type m_shapeChanged;
702+
Event::Type m_localInput;
693703
Event::Type m_suspend;
694704
Event::Type m_resume;
695705
};

src/lib/client/Client.cpp

+23-9
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
* barrier -- mouse and keyboard sharing utility
33
* Copyright (C) 2012-2016 Symless Ltd.
44
* Copyright (C) 2002 Chris Schoeneman
5-
*
5+
*
66
* This package is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU General Public License
88
* found in the file LICENSE that should have accompanied this file.
9-
*
9+
*
1010
* This package is distributed in the hope that it will be useful,
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -134,11 +134,11 @@ Client::connect()
134134
// being shuttled between various networks). patch by Brent
135135
// Priddy.
136136
m_serverAddress.resolve();
137-
137+
138138
// m_serverAddress will be null if the hostname address is not reolved
139139
if (m_serverAddress.getAddress() != NULL) {
140140
// to help users troubleshoot, show server host name (issue: 60)
141-
LOG((CLOG_NOTE "connecting to '%s': %s:%i",
141+
LOG((CLOG_NOTE "connecting to '%s': %s:%i",
142142
m_serverAddress.getHostname().c_str(),
143143
ARCH->addrToString(m_serverAddress.getAddress()).c_str(),
144144
m_serverAddress.getPort()));
@@ -255,7 +255,7 @@ Client::leave()
255255
m_active = false;
256256

257257
m_screen->leave();
258-
258+
259259
if (m_enableClipboard) {
260260
// send clipboards that we own and that have changed
261261
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
@@ -271,7 +271,7 @@ Client::leave()
271271
void
272272
Client::setClipboard(ClipboardID id, const IClipboard* clipboard)
273273
{
274-
m_screen->setClipboard(id, clipboard);
274+
m_screen->setClipboard(id, clipboard);
275275
m_ownClipboard[id] = false;
276276
m_sentClipboard[id] = false;
277277
}
@@ -508,6 +508,10 @@ Client::setupScreen()
508508
getEventTarget(),
509509
new TMethodEventJob<Client>(this,
510510
&Client::handleClipboardGrabbed));
511+
m_events->adoptHandler(m_events->forIScreen().localInput(),
512+
getEventTarget(),
513+
new TMethodEventJob<Client>(this,
514+
&Client::handleLocalInputEvent));
511515
}
512516

513517
void
@@ -564,6 +568,8 @@ Client::cleanupScreen()
564568
getEventTarget());
565569
m_events->removeHandler(m_events->forClipboard().clipboardGrabbed(),
566570
getEventTarget());
571+
m_events->removeHandler(m_events->forIScreen().localInput(),
572+
getEventTarget());
567573
delete m_server;
568574
m_server = NULL;
569575
}
@@ -767,6 +773,14 @@ Client::handleStopRetry(const Event&, void*)
767773
m_args.m_restartable = false;
768774
}
769775

776+
void
777+
Client::handleLocalInputEvent(const Event& event, void*)
778+
{
779+
IPlatformScreen::MotionInfo* info = static_cast<IPlatformScreen::MotionInfo*>(event.getData());
780+
LOG((CLOG_DEBUG "Trigger screen switching caused by local input, screen coordinates (%d, %d)", info->m_x, info->m_y));
781+
m_server->onLocalInput(info->m_x, info->m_y);
782+
}
783+
770784
void
771785
Client::writeToDropDirThread(void*)
772786
{
@@ -775,7 +789,7 @@ Client::writeToDropDirThread(void*)
775789
while (m_screen->isFakeDraggingStarted()) {
776790
ARCH->sleep(.1f);
777791
}
778-
792+
779793
DropHelper::writeToDir(m_screen->getDropTarget(), m_dragFileList,
780794
m_receivedFileData);
781795
}
@@ -790,7 +804,7 @@ Client::dragInfoReceived(UInt32 fileNum, std::string data)
790804
}
791805

792806
DragInformation::parseDragInfo(m_dragFileList, fileNum, data);
793-
807+
794808
m_screen->startDraggingFiles(m_dragFileList);
795809
}
796810

@@ -806,7 +820,7 @@ Client::sendFileToServer(const char* filename)
806820
if (m_sendFileThread != NULL) {
807821
StreamChunker::interruptFile();
808822
}
809-
823+
810824
m_sendFileThread = new Thread(
811825
new TMethodJob<Client>(
812826
this, &Client::sendFileThread,

src/lib/client/Client.h

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class Client : public IClient, public INode {
191191
void handleFileChunkSending(const Event&, void*);
192192
void handleFileRecieveCompleted(const Event&, void*);
193193
void handleStopRetry(const Event&, void*);
194+
void handleLocalInputEvent(const Event&, void*);
194195
void onFileRecieveCompleted();
195196
void sendClipboardThread(void*);
196197

src/lib/client/ServerProxy.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
* barrier -- mouse and keyboard sharing utility
33
* Copyright (C) 2012-2016 Symless Ltd.
44
* Copyright (C) 2002 Chris Schoeneman
5-
*
5+
*
66
* This package is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU General Public License
88
* found in the file LICENSE that should have accompanied this file.
9-
*
9+
*
1010
* This package is distributed in the hope that it will be useful,
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -367,6 +367,14 @@ ServerProxy::onClipboardChanged(ClipboardID id, const IClipboard* clipboard)
367367
StreamChunker::sendClipboard(data, data.size(), id, m_seqNum, m_events, this);
368368
}
369369

370+
void
371+
ServerProxy::onLocalInput(SInt32 x, SInt32 y)
372+
{
373+
// Coordinates as signed 32 bit integers don't make a lot of sense
374+
// but are used for compatibility with e.g. IPlatformScreen::MotionInfo
375+
ProtocolUtil::writef(m_stream, kMsgCLocalInput, x, y);
376+
}
377+
370378
void
371379
ServerProxy::flushCompressedMouse()
372380
{
@@ -553,7 +561,7 @@ ServerProxy::setClipboard()
553561
static std::string dataCached;
554562
ClipboardID id;
555563
UInt32 seq;
556-
564+
557565
int r = ClipboardChunk::assemble(m_stream, dataCached, id, seq);
558566

559567
if (r == kStart) {
@@ -562,7 +570,7 @@ ServerProxy::setClipboard()
562570
}
563571
else if (r == kFinish) {
564572
LOG((CLOG_DEBUG "received clipboard %d size=%d", id, dataCached.size()));
565-
573+
566574
// forward
567575
Clipboard clipboard;
568576
clipboard.unmarshall(dataCached, 0);

src/lib/client/ServerProxy.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
* barrier -- mouse and keyboard sharing utility
33
* Copyright (C) 2012-2016 Symless Ltd.
44
* Copyright (C) 2002 Chris Schoeneman
5-
*
5+
*
66
* This package is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU General Public License
88
* found in the file LICENSE that should have accompanied this file.
9-
*
9+
*
1010
* This package is distributed in the hope that it will be useful,
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -50,6 +50,7 @@ class ServerProxy {
5050
void onInfoChanged();
5151
bool onGrabClipboard(ClipboardID);
5252
void onClipboardChanged(ClipboardID, const IClipboard*);
53+
void onLocalInput(SInt32 x, SInt32 y);
5354

5455
//@}
5556

@@ -58,7 +59,7 @@ class ServerProxy {
5859

5960
// sending dragging information to server
6061
void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
61-
62+
6263
#ifdef TEST_ENV
6364
void handleDataForTest() { handleData(Event(), NULL); }
6465
#endif

0 commit comments

Comments
 (0)