Added bertrand landry hetu's mac OS X port to date.

This commit is contained in:
crs 2004-05-15 19:41:46 +00:00
parent 242050d0f2
commit d9387dbed7
17 changed files with 5370 additions and 110 deletions

View File

@ -27,6 +27,7 @@ EXTRA_DIST = \
TODO \ TODO \
all.dsp \ all.dsp \
synergy.dsw \ synergy.dsw \
synergy.xcode/project.pbxproj \
doc/doxygen.cfg.in \ doc/doxygen.cfg.in \
examples/synergy.conf \ examples/synergy.conf \
$(NULL) $(NULL)

View File

@ -38,8 +38,7 @@ case $host in
;; ;;
*-*-darwin*) *-*-darwin*)
acx_host_arch="UNIX" acx_host_arch="UNIX"
acx_host_winapi="XWINDOWS" acx_host_winapi="CARBON"
# acx_host_winapi="CARBON"
;; ;;
*) *)
acx_host_arch="UNIX" acx_host_arch="UNIX"
@ -65,8 +64,7 @@ dnl our files end in .cpp not .C so tests should also end in .cpp
ac_ext=cpp ac_ext=cpp
dnl enable debugging or disable asserts dnl enable debugging or disable asserts
AC_ARG_ENABLE([debug], AC_ARG_ENABLE([debug], [ --enable-debug enable debugging])
AC_HELP_STRING([--enable-debug], [enable debugging]))
if test "x$enable_debug" != xno; then if test "x$enable_debug" != xno; then
CXXFLAGS="$CXXFLAGS -g" CXXFLAGS="$CXXFLAGS -g"
else else
@ -111,22 +109,29 @@ if test x"$acx_host_winapi" = xXWINDOWS; then
CPPFLAGS="$X_CFLAGS $CPPFLAGS" CPPFLAGS="$X_CFLAGS $CPPFLAGS"
AC_CHECK_LIB(Xtst, AC_CHECK_LIB(Xtst,
XTestQueryExtension, XTestQueryExtension,
AC_CHECK_HEADERS([X11/extensions/XTest.h],
[X_LIBS="$X_LIBS -lXtst"], [X_LIBS="$X_LIBS -lXtst"],
AC_MSG_ERROR(Your must have the XTest headers to compile synergy)),
AC_MSG_ERROR(You must have the XTest library to build synergy), AC_MSG_ERROR(You must have the XTest library to build synergy),
[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS]) [$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
AC_CHECK_HEADERS([X11/extensions/XTest.h],,
AC_MSG_ERROR(You must have the XTest headers to compile synergy))
AC_CHECK_LIB(Xinerama, AC_CHECK_LIB(Xinerama,
XineramaQueryExtension, XineramaQueryExtension,
AC_CHECK_HEADERS([X11/extensions/Xinerama.h], [X_LIBS="$X_LIBS -lXinerama"],
[X_LIBS="$X_LIBS -lXinerama"]), [acx_xinerama_lib_ok=no],
,
[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS]) [$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
if test x"$acx_xinerama_lib_ok" != xno; then
AC_CHECK_HEADERS([X11/extensions/Xinerama.h],,,
[#include <X11/Xlib.h>])
fi
AC_CHECK_LIB(Xext, AC_CHECK_LIB(Xext,
DPMSQueryExtension, DPMSQueryExtension,
AC_CHECK_HEADERS([X11/extensions/dpms.h]), [acx_dpms_lib_ok=yes],
, [acx_dpms_lib_ok=no],
[$X_LIBS -lX11 $X_EXTRA_LIBS]) [$X_LIBS -lX11 $X_EXTRA_LIBS])
if test x"$acx_dpms_lib_ok" = xyes; then
AC_CHECK_HEADERS([X11/extensions/dpms.h],,,
[#include <X11/Xlib.h>])
fi
CPPFLAGS="$save_CPPFLAGS" CPPFLAGS="$save_CPPFLAGS"
ARCH_LIBS="$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS $ARCH_LIBS" ARCH_LIBS="$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS $ARCH_LIBS"
ARCH_CFLAGS="$ARCH_CFLAGS $X_CFLAGS" ARCH_CFLAGS="$ARCH_CFLAGS $X_CFLAGS"

View File

@ -24,6 +24,56 @@
# if defined(_WIN32) # if defined(_WIN32)
# define SYSAPI_WIN32 1 # define SYSAPI_WIN32 1
# define WINAPI_MSWINDOWS 1 # define WINAPI_MSWINDOWS 1
# endif
// we may not have run configure on OS X
# if defined(__APPLE__)
# define SYSAPI_UNIX 1
# define WINAPI_CARBON 1
# define HAVE_ALLOCA_H 1
# define HAVE_CXX_BOOL 1
# define HAVE_CXX_CASTS 1
# define HAVE_CXX_EXCEPTIONS 1
# define HAVE_CXX_MUTABLE 1
# define HAVE_CXX_STDLIB 1
# define HAVE_GETPWUID_R 1
# define HAVE_GMTIME_R 1
# define HAVE_INET_ATON 1
# define HAVE_INTTYPES_H 1
# define HAVE_ISTREAM 1
# define HAVE_MEMORY_H 1
# define HAVE_NANOSLEEP 1
# define HAVE_OSTREAM 1
# define HAVE_POLL 1
# define HAVE_POSIX_SIGWAIT 1
# define HAVE_PTHREAD 1
# define HAVE_PTHREAD_SIGNAL 1
# define HAVE_SOCKLEN_T 1
# define HAVE_SSTREAM 1
# define HAVE_STDINT_H 1
# define HAVE_STDLIB_H 1
# define HAVE_STRINGS_H 1
# define HAVE_STRING_H 1
# define HAVE_SYS_SELECT_H 1
# define HAVE_SYS_STAT_H 1
# define HAVE_SYS_TIME_H 1
# define HAVE_SYS_TYPES_H 1
# define HAVE_UNISTD_H 1
# define HAVE_VSNPRINTF 1
# define HAVE_WCHAR_H 1
# define HAVE_SYS_SOCKET_H 1
# define SELECT_TYPE_ARG1 int
# define SELECT_TYPE_ARG234 (fd_set *)
# define SELECT_TYPE_ARG5 (struct timeval *)
# define SIZEOF_CHAR 1
# define SIZEOF_INT 4
# define SIZEOF_LONG 4
# define SIZEOF_SHORT 2
# define STDC_HEADERS 1
# define TIME_WITH_SYS_TIME 1
# define X_DISPLAY_MISSING 1
# endif # endif
#endif #endif

View File

@ -13,58 +13,205 @@
*/ */
#include "COSXClipboard.h" #include "COSXClipboard.h"
#include <Carbon/Carbon.h> #include "COSXClipboardUTF16Converter.h"
#include "COSXClipboardTextConverter.h"
// FIXME -- implement this #include "CLog.h"
#include "XArch.h"
// //
// COSXClipboard // COSXClipboard
// //
COSXClipboard::COSXClipboard() COSXClipboard::COSXClipboard() :
m_time(0),
m_scrap(NULL)
{ {
m_converters.push_back(new COSXClipboardUTF16Converter);
m_converters.push_back(new COSXClipboardTextConverter);
} }
COSXClipboard::~COSXClipboard() COSXClipboard::~COSXClipboard()
{ {
clearConverters();
} }
bool bool
COSXClipboard::empty() COSXClipboard::empty()
{ {
LOG((CLOG_DEBUG "empty clipboard"));
assert(m_scrap != NULL);
OSStatus err = ClearScrap(&m_scrap);
// XXX -- check err?
err = PutScrapFlavor(
m_scrap,
getOwnershipFlavor(),
kScrapFlavorMaskNone,
0,
0);
if (err != noErr) {
LOG((CLOG_DEBUG "failed to grab clipboard"));
return false;
}
return true; return true;
} }
void void
COSXClipboard::add(EFormat, const CString&) COSXClipboard::add(EFormat format, const CString & data)
{ {
LOG((CLOG_DEBUG "add %d bytes to clipboard format: %d", data.size(), format));
for (ConverterList::const_iterator index = m_converters.begin();
index != m_converters.end(); ++index) {
IOSXClipboardConverter* converter = *index;
// skip converters for other formats
if (converter->getFormat() == format) {
CString osXData = converter->fromIClipboard(data);
ScrapFlavorType flavorType = converter->getOSXFormat();
PutScrapFlavor(
m_scrap,
flavorType,
kScrapFlavorMaskNone,
osXData.size(),
osXData.data());
}
}
} }
bool bool
COSXClipboard::open(Time) const COSXClipboard::open(Time time) const
{ {
return false; LOG((CLOG_DEBUG "open clipboard"));
m_time = time;
OSStatus err = GetCurrentScrap(&m_scrap);
return (err == noErr);
} }
void void
COSXClipboard::close() const COSXClipboard::close() const
{ {
LOG((CLOG_DEBUG "close clipboard"));
m_scrap = NULL;
} }
IClipboard::Time IClipboard::Time
COSXClipboard::getTime() const COSXClipboard::getTime() const
{ {
return 0; return m_time;
} }
bool bool
COSXClipboard::has(EFormat) const COSXClipboard::has(EFormat format) const
{ {
assert(m_scrap != NULL);
for (ConverterList::const_iterator index = m_converters.begin();
index != m_converters.end(); ++index) {
IOSXClipboardConverter* converter = *index;
if (converter->getFormat() == format) {
ScrapFlavorFlags flags;
ScrapFlavorType type = converter->getOSXFormat();
if (GetScrapFlavorFlags(m_scrap, type, &flags) == noErr) {
return true;
}
}
}
return false; return false;
} }
CString CString
COSXClipboard::get(EFormat) const COSXClipboard::get(EFormat format) const
{ {
return ""; CString result;
// find the converter for the first clipboard format we can handle
IOSXClipboardConverter* converter = NULL;
for (ConverterList::const_iterator index = m_converters.begin();
index != m_converters.end(); ++index) {
converter = *index;
ScrapFlavorFlags flags;
ScrapFlavorType type = converter->getOSXFormat();
if (converter->getFormat() == format &&
GetScrapFlavorFlags(m_scrap, type, &flags) == noErr) {
break;
}
converter = NULL;
}
// if no converter then we don't recognize any formats
if (converter == NULL) {
return result;
}
// get the clipboard data.
char* buffer = NULL;
try {
Size flavorSize;
OSStatus err = GetScrapFlavorSize(m_scrap,
converter->getOSXFormat(), &flavorSize);
if (err != noErr) {
throw err;
}
buffer = new char[flavorSize];
if (buffer == NULL) {
throw memFullErr;
}
err = GetScrapFlavorData(m_scrap,
converter->getOSXFormat(), &flavorSize, buffer);
if (err != noErr) {
throw err;
}
result = CString(buffer, flavorSize);
}
catch (OSStatus err) {
LOG((CLOG_DEBUG "exception thrown in COSXClipboard::get MacError (%d)", err));
}
catch (...) {
LOG((CLOG_DEBUG "unknown exception in COSXClipboard::get"));
RETHROW_XTHREAD
}
delete[] buffer;
return converter->toIClipboard(result);
}
void
COSXClipboard::clearConverters()
{
for (ConverterList::iterator index = m_converters.begin();
index != m_converters.end(); ++index) {
delete *index;
}
m_converters.clear();
}
bool
COSXClipboard::isOwnedBySynergy()
{
ScrapFlavorFlags flags;
ScrapRef scrap;
OSStatus err = GetCurrentScrap(&scrap);
if (err == noErr) {
err = GetScrapFlavorFlags(scrap, getOwnershipFlavor() , &flags);
}
return (err == noErr);
}
ScrapFlavorType
COSXClipboard::getOwnershipFlavor()
{
return 'Syne';
} }

View File

@ -16,6 +16,10 @@
#define COSXCLIPBOARD_H #define COSXCLIPBOARD_H
#include "IClipboard.h" #include "IClipboard.h"
#include <vector>
#include <Carbon/Carbon.h>
class IOSXClipboardConverter;
//! OS X clipboard implementation //! OS X clipboard implementation
class COSXClipboard : public IClipboard { class COSXClipboard : public IClipboard {
@ -23,6 +27,9 @@ public:
COSXClipboard(); COSXClipboard();
virtual ~COSXClipboard(); virtual ~COSXClipboard();
//! Test if clipboard is owned by synergy
static bool isOwnedBySynergy();
// IClipboard overrides // IClipboard overrides
virtual bool empty(); virtual bool empty();
virtual void add(EFormat, const CString& data); virtual void add(EFormat, const CString& data);
@ -31,6 +38,57 @@ public:
virtual Time getTime() const; virtual Time getTime() const;
virtual bool has(EFormat) const; virtual bool has(EFormat) const;
virtual CString get(EFormat) const; virtual CString get(EFormat) const;
private:
void clearConverters();
static ScrapFlavorType
getOwnershipFlavor();
private:
typedef std::vector<IOSXClipboardConverter*> ConverterList;
mutable Time m_time;
ConverterList m_converters;
mutable ScrapRef m_scrap;
};
//! Clipboard format converter interface
/*!
This interface defines the methods common to all Scrap book format
*/
class IOSXClipboardConverter : public IInterface {
public:
//! @name accessors
//@{
//! Get clipboard format
/*!
Return the clipboard format this object converts from/to.
*/
virtual IClipboard::EFormat
getFormat() const = 0;
//! returns the scrap flavor type that this object converts from/to
virtual ScrapFlavorType
getOSXFormat() const = 0;
//! Convert from IClipboard format
/*!
Convert from the IClipboard format to the Carbon scrap format.
The input data must be in the IClipboard format returned by
getFormat(). The return data will be in the scrap
format returned by getOSXFormat().
*/
virtual CString fromIClipboard(const CString&) const = 0;
//! Convert to IClipboard format
/*!
Convert from the carbon scrap format to the IClipboard format
(i.e., the reverse of fromIClipboard()).
*/
virtual CString toIClipboard(const CString&) const = 0;
//@}
}; };
#endif #endif

View File

@ -0,0 +1,85 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package 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.
*/
#include "COSXClipboardAnyTextConverter.h"
#include <algorithm>
//
// COSXClipboardAnyTextConverter
//
COSXClipboardAnyTextConverter::COSXClipboardAnyTextConverter()
{
// do nothing
}
COSXClipboardAnyTextConverter::~COSXClipboardAnyTextConverter()
{
// do nothing
}
IClipboard::EFormat
COSXClipboardAnyTextConverter::getFormat() const
{
return IClipboard::kText;
}
CString
COSXClipboardAnyTextConverter::fromIClipboard(const CString& data) const
{
// convert linefeeds and then convert to desired encoding
return doFromIClipboard(convertLinefeedToMacOS(data));
}
CString
COSXClipboardAnyTextConverter::toIClipboard(const CString& data) const
{
// convert text then newlines
return convertLinefeedToUnix(doToIClipboard(data));
}
static
bool
isLF(char ch)
{
return (ch == '\n');
}
static
bool
isCR(char ch)
{
return (ch == '\r');
}
CString
COSXClipboardAnyTextConverter::convertLinefeedToMacOS(const CString& src)
{
// note -- we assume src is a valid UTF-8 string
CString copy = src;
std::replace_if(copy.begin(), copy.end(), isLF, '\r');
return copy;
}
CString
COSXClipboardAnyTextConverter::convertLinefeedToUnix(const CString& src)
{
CString copy = src;
std::replace_if(copy.begin(), copy.end(), isCR, '\n');
return copy;
}

View File

@ -0,0 +1,52 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package 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.
*/
#ifndef COSXCLIPBOARDANYTEXTCONVERTER_H
#define COSXCLIPBOARDANYTEXTCONVERTER_H
#include "COSXClipboard.h"
//! Convert to/from some text encoding
class COSXClipboardAnyTextConverter : public IOSXClipboardConverter {
public:
COSXClipboardAnyTextConverter();
virtual ~COSXClipboardAnyTextConverter();
// IOSXClipboardConverter overrides
virtual IClipboard::EFormat
getFormat() const;
virtual ScrapFlavorType
getOSXFormat() const = 0;
virtual CString fromIClipboard(const CString &) const;
virtual CString toIClipboard(const CString &) const;
protected:
//! Convert from IClipboard format
/*!
Do UTF-8 conversion and linefeed conversion.
*/
virtual CString doFromIClipboard(const CString&) const = 0;
//! Convert to IClipboard format
/*!
Do UTF-8 conversion and Linefeed conversion.
*/
virtual CString doToIClipboard(const CString&) const = 0;
private:
static CString convertLinefeedToMacOS(const CString&);
static CString convertLinefeedToUnix(const CString&);
};
#endif

View File

@ -0,0 +1,48 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package 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.
*/
#include "COSXClipboardTextConverter.h"
#include "CUnicode.h"
//
// COSXClipboardTextConverter
//
COSXClipboardTextConverter::COSXClipboardTextConverter()
{
// do nothing
}
COSXClipboardTextConverter::~COSXClipboardTextConverter()
{
// do nothing
}
ScrapFlavorType
COSXClipboardTextConverter::getOSXFormat() const
{
return kScrapFlavorTypeText;
}
CString
COSXClipboardTextConverter::doFromIClipboard(const CString& data) const
{
return CUnicode::UTF8ToText(data);
}
CString
COSXClipboardTextConverter::doToIClipboard(const CString& data) const
{
return CUnicode::textToUTF8(data);
}

View File

@ -0,0 +1,37 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package 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.
*/
#ifndef COSXCLIPBOARDTEXTCONVERTER_H
#define COSXCLIPBOARDTEXTCONVERTER_H
#include "COSXClipboardAnyTextConverter.h"
//! Convert to/from locale text encoding
class COSXClipboardTextConverter : public COSXClipboardAnyTextConverter {
public:
COSXClipboardTextConverter();
virtual ~COSXClipboardTextConverter();
// IOSXClipboardAnyTextConverter overrides
virtual ScrapFlavorType
getOSXFormat() const;
protected:
// COSXClipboardAnyTextConverter overrides
virtual CString doFromIClipboard(const CString&) const;
virtual CString doToIClipboard(const CString&) const;
};
#endif

View File

@ -0,0 +1,50 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package 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.
*/
#include "COSXClipboardUTF16Converter.h"
#include "CUnicode.h"
//
// COSXClipboardUTF16Converter
//
COSXClipboardUTF16Converter::COSXClipboardUTF16Converter()
{
// do nothing
}
COSXClipboardUTF16Converter::~COSXClipboardUTF16Converter()
{
// do nothing
}
ScrapFlavorType
COSXClipboardUTF16Converter::getOSXFormat() const
{
return kScrapFlavorTypeUnicode;
}
CString
COSXClipboardUTF16Converter::doFromIClipboard(const CString& data) const
{
// convert and add nul terminator
return CUnicode::UTF8ToUTF16(data);
}
CString
COSXClipboardUTF16Converter::doToIClipboard(const CString& data) const
{
// convert and strip nul terminator
return CUnicode::UTF16ToUTF8(data);
}

View File

@ -0,0 +1,36 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package 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.
*/
#ifndef COSXCLIPBOARDUTF16CONVERTER_H
#define COSXCLIPBOARDUTF16CONVERTER_H
#include "COSXClipboardAnyTextConverter.h"
//! Convert to/from UTF-16 encoding
class COSXClipboardUTF16Converter : public COSXClipboardAnyTextConverter {
public:
COSXClipboardUTF16Converter();
virtual ~COSXClipboardUTF16Converter();
// IOSXClipboardAnyTextConverter overrides
virtual ScrapFlavorType
getOSXFormat() const;
protected:
// COSXClipboardAnyTextConverter overrides
virtual CString doFromIClipboard(const CString&) const;
virtual CString doToIClipboard(const CString&) const;
};
#endif

View File

@ -13,19 +13,28 @@
*/ */
#include "COSXEventQueueBuffer.h" #include "COSXEventQueueBuffer.h"
#include "CEvent.h"
#include "IEventQueue.h"
//
// CEventQueueTimer
//
class CEventQueueTimer { };
// //
// COSXEventQueueBuffer // COSXEventQueueBuffer
// //
COSXEventQueueBuffer::COSXEventQueueBuffer() COSXEventQueueBuffer::COSXEventQueueBuffer() :
m_event(NULL)
{ {
// FIXME // do nothing
} }
COSXEventQueueBuffer::~COSXEventQueueBuffer() COSXEventQueueBuffer::~COSXEventQueueBuffer()
{ {
// FIXME setOSXEvent(NULL);
} }
void void
@ -38,18 +47,51 @@ COSXEventQueueBuffer::waitForEvent(double timeout)
IEventQueueBuffer::Type IEventQueueBuffer::Type
COSXEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID) COSXEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID)
{ {
// FIXME EventRef carbonEvent = NULL;
(void)event; OSStatus error = ReceiveNextEvent(0, NULL, 0.0, true, &carbonEvent);
(void)dataID; setOSXEvent(carbonEvent);
if (error == eventLoopQuitErr) {
event = CEvent(CEvent::kQuit);
return kSystem;
}
else if (error != noErr) {
return kNone; return kNone;
} }
else {
UInt32 eventClass = GetEventClass(m_event);
switch (eventClass) {
case 'Syne':
dataID = GetEventKind(m_event);
return kUser;
default:
event = CEvent(CEvent::kSystem,
IEventQueue::getSystemTarget(), &m_event);
return kNone;
}
}
}
bool bool
COSXEventQueueBuffer::addEvent(UInt32 dataID) COSXEventQueueBuffer::addEvent(UInt32 dataID)
{ {
// FIXME EventRef event;
(void)dataID; OSStatus error = CreateEvent(
return false; kCFAllocatorDefault,
'Syne',
dataID,
0,
kEventAttributeNone,
&event);
if (error == noErr) {
error = PostEventToQueue(GetMainEventQueue(), event,
kEventPriorityStandard);
ReleaseEvent(event);
}
return (error == noErr);
} }
bool bool
@ -57,20 +99,26 @@ COSXEventQueueBuffer::isEmpty() const
{ {
EventRef event; EventRef event;
OSStatus status = ReceiveNextEvent(0, NULL, 0.0, false, &event); OSStatus status = ReceiveNextEvent(0, NULL, 0.0, false, &event);
return (status != eventLoopTimedOutErr); return (status == eventLoopTimedOutErr);
} }
CEventQueueTimer* CEventQueueTimer*
COSXEventQueueBuffer::newTimer(double duration, bool oneShot) const COSXEventQueueBuffer::newTimer(double, bool) const
{ {
// FIXME return new CEventQueueTimer;
(void)duration;
(void)oneShot;
return NULL;
} }
void void
COSXEventQueueBuffer::deleteTimer(CEventQueueTimer*) const COSXEventQueueBuffer::deleteTimer(CEventQueueTimer* timer) const
{ {
// FIXME delete timer;
}
void
COSXEventQueueBuffer::setOSXEvent(EventRef event)
{
if (m_event != NULL) {
ReleaseEvent(m_event);
}
m_event = RetainEvent(event);
} }

View File

@ -33,8 +33,11 @@ public:
newTimer(double duration, bool oneShot) const; newTimer(double duration, bool oneShot) const;
virtual void deleteTimer(CEventQueueTimer*) const; virtual void deleteTimer(CEventQueueTimer*) const;
protected:
void setOSXEvent(EventRef event);
private: private:
// FIXME EventRef m_event;
}; };
#endif #endif

View File

@ -34,7 +34,8 @@ COSXScreen::COSXScreen(bool isPrimary) :
m_keyState(NULL), m_keyState(NULL),
m_sequenceNumber(0), m_sequenceNumber(0),
m_screensaver(NULL), m_screensaver(NULL),
m_screensaverNotify(false) m_screensaverNotify(false),
m_ownClipboard(false)
{ {
try { try {
m_displayID = CGMainDisplayID(); m_displayID = CGMainDisplayID();
@ -145,6 +146,30 @@ COSXScreen::getCursorCenter(SInt32& x, SInt32& y) const
y = m_yCenter; y = m_yCenter;
} }
void
COSXScreen::postMouseEvent(const CGPoint & pos) const
{
// synthesize event. CGPostMouseEvent is a particularly good
// example of a bad API. we have to shadow the mouse state to
// use this API and if we want to support more buttons we have
// to recompile.
//
// the order of buttons on the mac is:
// 1 - Left
// 2 - Right
// 3 - Middle
// Whatever the USB device defined.
// It is a bit weird that the behaviour of buttons over 3 are dependent
// on currently plugged in USB devices.
CGPostMouseEvent(pos, true, sizeof(m_buttons) / sizeof(m_buttons[0]),
m_buttons[0],
m_buttons[2],
m_buttons[1],
m_buttons[3],
m_buttons[4]);
}
void void
COSXScreen::fakeMouseButton(ButtonID id, bool press) const COSXScreen::fakeMouseButton(ButtonID id, bool press) const
{ {
@ -157,10 +182,6 @@ COSXScreen::fakeMouseButton(ButtonID id, bool press) const
// update state // update state
m_buttons[index] = press; m_buttons[index] = press;
// synthesize event. CGPostMouseEvent is a particularly good
// example of a bad API. we have to shadow the mouse state to
// use this API and if we want to support more buttons we have
// to recompile.
CGPoint pos; CGPoint pos;
if (!m_cursorPosValid) { if (!m_cursorPosValid) {
SInt32 x, y; SInt32 x, y;
@ -168,12 +189,7 @@ COSXScreen::fakeMouseButton(ButtonID id, bool press) const
} }
pos.x = m_xCursor; pos.x = m_xCursor;
pos.y = m_yCursor; pos.y = m_yCursor;
CGPostMouseEvent(pos, false, sizeof(m_buttons) / sizeof(m_buttons[0]), postMouseEvent(pos);
m_buttons[0],
m_buttons[1],
m_buttons[2],
m_buttons[3],
m_buttons[4]);
} }
void void
@ -183,8 +199,7 @@ COSXScreen::fakeMouseMove(SInt32 x, SInt32 y) const
CGPoint pos; CGPoint pos;
pos.x = x; pos.x = x;
pos.y = y; pos.y = y;
// FIXME -- is it okay to pass no buttons here? postMouseEvent(pos);
CGPostMouseEvent(pos, true, 0, m_buttons[0]);
// save new cursor position // save new cursor position
m_xCursor = x; m_xCursor = x;
@ -208,8 +223,7 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
CGPoint pos; CGPoint pos;
pos.x = oldPos.h + dx; pos.x = oldPos.h + dx;
pos.y = oldPos.v + dy; pos.y = oldPos.v + dy;
// FIXME -- is it okay to pass no buttons here? postMouseEvent(pos);
CGPostMouseEvent(pos, true, 0, m_buttons[0]);
// we now assume we don't know the current cursor position // we now assume we don't know the current cursor position
m_cursorPosValid = false; m_cursorPosValid = false;
@ -218,7 +232,32 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
void void
COSXScreen::fakeMouseWheel(SInt32 delta) const COSXScreen::fakeMouseWheel(SInt32 delta) const
{ {
CGPostScrollWheelEvent(1, delta / 120); CFPropertyListRef pref = ::CFPreferencesCopyValue(
CFSTR("com.apple.scrollwheel.scaling"),
kCFPreferencesAnyApplication,
kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
int32_t wheelIncr = 10;
if (pref != NULL) {
CFTypeID id = CFGetTypeID(pref);
if (id == CFNumberGetTypeID()) {
CFNumberRef value = static_cast<CFNumberRef>(pref);
double scaling;
if (CFNumberGetValue(value, kCFNumberDoubleType, &scaling)) {
wheelIncr = (int32_t)(8 * scaling);
}
}
CFRelease(pref);
}
if (delta < 0) {
wheelIncr = -wheelIncr;
}
CGPostScrollWheelEvent(1, wheelIncr);
} }
void void
@ -332,6 +371,7 @@ bool
COSXScreen::setClipboard(ClipboardID, const IClipboard* src) COSXScreen::setClipboard(ClipboardID, const IClipboard* src)
{ {
COSXClipboard dst; COSXClipboard dst;
m_ownClipboard = true;
if (src != NULL) { if (src != NULL) {
// save clipboard data // save clipboard data
return CClipboard::copy(&dst, src); return CClipboard::copy(&dst, src);
@ -350,7 +390,18 @@ COSXScreen::setClipboard(ClipboardID, const IClipboard* src)
void void
COSXScreen::checkClipboards() COSXScreen::checkClipboards()
{ {
// FIXME -- do nothing if we're always up to date if (m_ownClipboard && !COSXClipboard::isOwnedBySynergy()) {
static ScrapRef sScrapbook = NULL;
ScrapRef currentScrap;
GetCurrentScrap(&currentScrap);
if (sScrapbook != currentScrap) {
m_ownClipboard = false;
sendClipboardEvent(getClipboardGrabbedEvent(), kClipboardClipboard);
sendClipboardEvent(getClipboardGrabbedEvent(), kClipboardSelection);
sScrapbook = currentScrap;
}
}
} }
void void
@ -406,9 +457,64 @@ COSXScreen::isPrimary() const
} }
void void
COSXScreen::handleSystemEvent(const CEvent&, void*) COSXScreen::sendEvent(CEvent::Type type, void* data)
{ {
// FIXME EVENTQUEUE->addEvent(CEvent(type, getEventTarget(), data));
}
void
COSXScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id)
{
CClipboardInfo* info = (CClipboardInfo*)malloc(sizeof(CClipboardInfo));
info->m_id = id;
info->m_sequenceNumber = m_sequenceNumber;
sendEvent(type, info);
}
void
COSXScreen::handleSystemEvent(const CEvent& event, void*)
{
/*
EventRef * carbonEvent = reinterpret_cast<EventRef *>(event.getData());
assert(carbonEvent != NULL);
UInt32 eventClass = GetEventClass( *carbonEvent );
switch( eventClass )
{
case kEventClassMouse:
{
UInt32 eventKind = GetEventKind( *carbonEvent );
switch( eventKind )
{
case kEventMouseMoved:
{
HIPoint point;
GetEventParameter( *carbonEvent,
kEventParamMouseDelta,
typeHIPoint,
NULL,
sizeof(point),
NULL,
&point);
} break;
}
}break;
case kEventClassKeyboard:
{
}
default:
{
} break;
}
*/
} }
void void
@ -426,15 +532,49 @@ COSXScreen::getKeyState() const
void void
COSXScreen::updateScreenShape() COSXScreen::updateScreenShape()
{ {
// FIXME -- handle multiple monitors // get info for each display
CGDisplayCount displayCount = 0;
if (CGGetActiveDisplayList(0, NULL, &displayCount) != CGDisplayNoErr) {
return;
}
if (displayCount == 0) {
return;
}
CGDirectDisplayID* displays =
(CGDirectDisplayID*)malloc(displayCount * sizeof(CGDirectDisplayID));
if (displays == NULL) {
return;
}
if (CGGetActiveDisplayList(displayCount,
displays, &displayCount) != CGDisplayNoErr) {
free(displays);
return;
}
// get smallest rect enclosing all display rects
CGRect totalBounds = CGRectZero;
for (CGDisplayCount i = 0; i < displayCount; ++i) {
CGRect bounds = CGDisplayBounds(displays[i]);
totalBounds = CGRectUnion(totalBounds, bounds);
}
// get shape of default screen // get shape of default screen
m_x = 0; m_x = (SInt32)totalBounds.origin.x;
m_y = 0; m_y = (SInt32)totalBounds.origin.y;
m_w = CGDisplayPixelsWide(m_displayID); m_w = (SInt32)totalBounds.size.width;
m_h = CGDisplayPixelsHigh(m_displayID); m_h = (SInt32)totalBounds.size.height;
// get center of default screen // get center of default screen
// XXX -- this should compute the center of displays[0]
m_xCenter = m_x + (m_w >> 1); m_xCenter = m_x + (m_w >> 1);
m_yCenter = m_y + (m_h >> 1); m_yCenter = m_y + (m_h >> 1);
LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d on %u %s", m_x, m_y, m_w, m_h, displayCount, (displayCount == 1) ? "display" : "displays"));
free(displays);
} }

View File

@ -76,6 +76,11 @@ protected:
private: private:
void updateScreenShape(); void updateScreenShape();
void postMouseEvent(const CGPoint &) const;
// convenience function to send events
void sendEvent(CEvent::Type type, void* = NULL);
void sendClipboardEvent(CEvent::Type type, ClipboardID id);
private: private:
// true if screen is being used as a primary screen, false otherwise // true if screen is being used as a primary screen, false otherwise
@ -107,6 +112,9 @@ private:
// screen saver stuff // screen saver stuff
COSXScreenSaver* m_screensaver; COSXScreenSaver* m_screensaver;
bool m_screensaverNotify; bool m_screensaverNotify;
// clipboard stuff
bool m_ownClipboard;
}; };
#endif #endif

View File

@ -71,11 +71,17 @@ MSWINDOWS_HOOK_SOURCE_FILES = \
$(NULL) $(NULL)
CARBON_SOURCE_FILES = \ CARBON_SOURCE_FILES = \
COSXClipboard.cpp \ COSXClipboard.cpp \
COSXClipboardAnyTextConverter.cpp \
COSXClipboardTextConverter.cpp \
COSXClipboardUTF16Converter.cpp \
COSXEventQueueBuffer.cpp \ COSXEventQueueBuffer.cpp \
COSXKeyState.cpp \ COSXKeyState.cpp \
COSXScreen.cpp \ COSXScreen.cpp \
COSXScreenSaver.cpp \ COSXScreenSaver.cpp \
COSXClipboard.h \ COSXClipboard.h \
COSXClipboardAnyTextConverter.h \
COSXClipboardTextConverter.h \
COSXClipboardUTF16Converter.h \
COSXEventQueueBuffer.h \ COSXEventQueueBuffer.h \
COSXKeyState.h \ COSXKeyState.h \
COSXScreen.h \ COSXScreen.h \

File diff suppressed because it is too large Load Diff