Added bertrand landry hetu's mac OS X port to date.
This commit is contained in:
parent
242050d0f2
commit
d9387dbed7
|
@ -27,6 +27,7 @@ EXTRA_DIST = \
|
|||
TODO \
|
||||
all.dsp \
|
||||
synergy.dsw \
|
||||
synergy.xcode/project.pbxproj \
|
||||
doc/doxygen.cfg.in \
|
||||
examples/synergy.conf \
|
||||
$(NULL)
|
||||
|
|
27
configure.in
27
configure.in
|
@ -38,8 +38,7 @@ case $host in
|
|||
;;
|
||||
*-*-darwin*)
|
||||
acx_host_arch="UNIX"
|
||||
acx_host_winapi="XWINDOWS"
|
||||
# acx_host_winapi="CARBON"
|
||||
acx_host_winapi="CARBON"
|
||||
;;
|
||||
*)
|
||||
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
|
||||
|
||||
dnl enable debugging or disable asserts
|
||||
AC_ARG_ENABLE([debug],
|
||||
AC_HELP_STRING([--enable-debug], [enable debugging]))
|
||||
AC_ARG_ENABLE([debug], [ --enable-debug enable debugging])
|
||||
if test "x$enable_debug" != xno; then
|
||||
CXXFLAGS="$CXXFLAGS -g"
|
||||
else
|
||||
|
@ -111,22 +109,29 @@ if test x"$acx_host_winapi" = xXWINDOWS; then
|
|||
CPPFLAGS="$X_CFLAGS $CPPFLAGS"
|
||||
AC_CHECK_LIB(Xtst,
|
||||
XTestQueryExtension,
|
||||
AC_CHECK_HEADERS([X11/extensions/XTest.h],
|
||||
[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),
|
||||
[$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,
|
||||
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])
|
||||
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,
|
||||
DPMSQueryExtension,
|
||||
AC_CHECK_HEADERS([X11/extensions/dpms.h]),
|
||||
,
|
||||
[acx_dpms_lib_ok=yes],
|
||||
[acx_dpms_lib_ok=no],
|
||||
[$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"
|
||||
ARCH_LIBS="$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS $ARCH_LIBS"
|
||||
ARCH_CFLAGS="$ARCH_CFLAGS $X_CFLAGS"
|
||||
|
|
|
@ -24,6 +24,56 @@
|
|||
# if defined(_WIN32)
|
||||
# define SYSAPI_WIN32 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
|
||||
|
||||
|
|
|
@ -13,58 +13,205 @@
|
|||
*/
|
||||
|
||||
#include "COSXClipboard.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
// FIXME -- implement this
|
||||
#include "COSXClipboardUTF16Converter.h"
|
||||
#include "COSXClipboardTextConverter.h"
|
||||
#include "CLog.h"
|
||||
#include "XArch.h"
|
||||
|
||||
//
|
||||
// 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()
|
||||
{
|
||||
clearConverters();
|
||||
}
|
||||
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
COSXClipboard::close() const
|
||||
{
|
||||
LOG((CLOG_DEBUG "close clipboard"));
|
||||
m_scrap = NULL;
|
||||
}
|
||||
|
||||
IClipboard::Time
|
||||
COSXClipboard::getTime() const
|
||||
{
|
||||
return 0;
|
||||
return m_time;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#define COSXCLIPBOARD_H
|
||||
|
||||
#include "IClipboard.h"
|
||||
#include <vector>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
class IOSXClipboardConverter;
|
||||
|
||||
//! OS X clipboard implementation
|
||||
class COSXClipboard : public IClipboard {
|
||||
|
@ -23,6 +27,9 @@ public:
|
|||
COSXClipboard();
|
||||
virtual ~COSXClipboard();
|
||||
|
||||
//! Test if clipboard is owned by synergy
|
||||
static bool isOwnedBySynergy();
|
||||
|
||||
// IClipboard overrides
|
||||
virtual bool empty();
|
||||
virtual void add(EFormat, const CString& data);
|
||||
|
@ -31,6 +38,57 @@ public:
|
|||
virtual Time getTime() const;
|
||||
virtual bool has(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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -13,19 +13,28 @@
|
|||
*/
|
||||
|
||||
#include "COSXEventQueueBuffer.h"
|
||||
#include "CEvent.h"
|
||||
#include "IEventQueue.h"
|
||||
|
||||
//
|
||||
// CEventQueueTimer
|
||||
//
|
||||
|
||||
class CEventQueueTimer { };
|
||||
|
||||
//
|
||||
// COSXEventQueueBuffer
|
||||
//
|
||||
|
||||
COSXEventQueueBuffer::COSXEventQueueBuffer()
|
||||
COSXEventQueueBuffer::COSXEventQueueBuffer() :
|
||||
m_event(NULL)
|
||||
{
|
||||
// FIXME
|
||||
// do nothing
|
||||
}
|
||||
|
||||
COSXEventQueueBuffer::~COSXEventQueueBuffer()
|
||||
{
|
||||
// FIXME
|
||||
setOSXEvent(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -38,18 +47,51 @@ COSXEventQueueBuffer::waitForEvent(double timeout)
|
|||
IEventQueueBuffer::Type
|
||||
COSXEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID)
|
||||
{
|
||||
// FIXME
|
||||
(void)event;
|
||||
(void)dataID;
|
||||
EventRef carbonEvent = NULL;
|
||||
OSStatus error = ReceiveNextEvent(0, NULL, 0.0, true, &carbonEvent);
|
||||
setOSXEvent(carbonEvent);
|
||||
|
||||
if (error == eventLoopQuitErr) {
|
||||
event = CEvent(CEvent::kQuit);
|
||||
return kSystem;
|
||||
}
|
||||
else if (error != noErr) {
|
||||
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
|
||||
COSXEventQueueBuffer::addEvent(UInt32 dataID)
|
||||
{
|
||||
// FIXME
|
||||
(void)dataID;
|
||||
return false;
|
||||
EventRef event;
|
||||
OSStatus error = CreateEvent(
|
||||
kCFAllocatorDefault,
|
||||
'Syne',
|
||||
dataID,
|
||||
0,
|
||||
kEventAttributeNone,
|
||||
&event);
|
||||
|
||||
if (error == noErr) {
|
||||
error = PostEventToQueue(GetMainEventQueue(), event,
|
||||
kEventPriorityStandard);
|
||||
ReleaseEvent(event);
|
||||
}
|
||||
|
||||
return (error == noErr);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -57,20 +99,26 @@ COSXEventQueueBuffer::isEmpty() const
|
|||
{
|
||||
EventRef event;
|
||||
OSStatus status = ReceiveNextEvent(0, NULL, 0.0, false, &event);
|
||||
return (status != eventLoopTimedOutErr);
|
||||
return (status == eventLoopTimedOutErr);
|
||||
}
|
||||
|
||||
CEventQueueTimer*
|
||||
COSXEventQueueBuffer::newTimer(double duration, bool oneShot) const
|
||||
COSXEventQueueBuffer::newTimer(double, bool) const
|
||||
{
|
||||
// FIXME
|
||||
(void)duration;
|
||||
(void)oneShot;
|
||||
return NULL;
|
||||
return new CEventQueueTimer;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,11 @@ public:
|
|||
newTimer(double duration, bool oneShot) const;
|
||||
virtual void deleteTimer(CEventQueueTimer*) const;
|
||||
|
||||
protected:
|
||||
void setOSXEvent(EventRef event);
|
||||
|
||||
private:
|
||||
// FIXME
|
||||
EventRef m_event;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,8 @@ COSXScreen::COSXScreen(bool isPrimary) :
|
|||
m_keyState(NULL),
|
||||
m_sequenceNumber(0),
|
||||
m_screensaver(NULL),
|
||||
m_screensaverNotify(false)
|
||||
m_screensaverNotify(false),
|
||||
m_ownClipboard(false)
|
||||
{
|
||||
try {
|
||||
m_displayID = CGMainDisplayID();
|
||||
|
@ -145,6 +146,30 @@ COSXScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
|||
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
|
||||
COSXScreen::fakeMouseButton(ButtonID id, bool press) const
|
||||
{
|
||||
|
@ -157,10 +182,6 @@ COSXScreen::fakeMouseButton(ButtonID id, bool press) const
|
|||
// update state
|
||||
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;
|
||||
if (!m_cursorPosValid) {
|
||||
SInt32 x, y;
|
||||
|
@ -168,12 +189,7 @@ COSXScreen::fakeMouseButton(ButtonID id, bool press) const
|
|||
}
|
||||
pos.x = m_xCursor;
|
||||
pos.y = m_yCursor;
|
||||
CGPostMouseEvent(pos, false, sizeof(m_buttons) / sizeof(m_buttons[0]),
|
||||
m_buttons[0],
|
||||
m_buttons[1],
|
||||
m_buttons[2],
|
||||
m_buttons[3],
|
||||
m_buttons[4]);
|
||||
postMouseEvent(pos);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -183,8 +199,7 @@ COSXScreen::fakeMouseMove(SInt32 x, SInt32 y) const
|
|||
CGPoint pos;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
// FIXME -- is it okay to pass no buttons here?
|
||||
CGPostMouseEvent(pos, true, 0, m_buttons[0]);
|
||||
postMouseEvent(pos);
|
||||
|
||||
// save new cursor position
|
||||
m_xCursor = x;
|
||||
|
@ -208,8 +223,7 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
|
|||
CGPoint pos;
|
||||
pos.x = oldPos.h + dx;
|
||||
pos.y = oldPos.v + dy;
|
||||
// FIXME -- is it okay to pass no buttons here?
|
||||
CGPostMouseEvent(pos, true, 0, m_buttons[0]);
|
||||
postMouseEvent(pos);
|
||||
|
||||
// we now assume we don't know the current cursor position
|
||||
m_cursorPosValid = false;
|
||||
|
@ -218,7 +232,32 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
|
|||
void
|
||||
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
|
||||
|
@ -332,6 +371,7 @@ bool
|
|||
COSXScreen::setClipboard(ClipboardID, const IClipboard* src)
|
||||
{
|
||||
COSXClipboard dst;
|
||||
m_ownClipboard = true;
|
||||
if (src != NULL) {
|
||||
// save clipboard data
|
||||
return CClipboard::copy(&dst, src);
|
||||
|
@ -350,7 +390,18 @@ COSXScreen::setClipboard(ClipboardID, const IClipboard* src)
|
|||
void
|
||||
COSXScreen::checkClipboards()
|
||||
{
|
||||
// FIXME -- do nothing if we're always up to date
|
||||
if (m_ownClipboard && !COSXClipboard::isOwnedBySynergy()) {
|
||||
static ScrapRef sScrapbook = NULL;
|
||||
ScrapRef currentScrap;
|
||||
GetCurrentScrap(¤tScrap);
|
||||
|
||||
if (sScrapbook != currentScrap) {
|
||||
m_ownClipboard = false;
|
||||
sendClipboardEvent(getClipboardGrabbedEvent(), kClipboardClipboard);
|
||||
sendClipboardEvent(getClipboardGrabbedEvent(), kClipboardSelection);
|
||||
sScrapbook = currentScrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -406,9 +457,64 @@ COSXScreen::isPrimary() const
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -426,15 +532,49 @@ COSXScreen::getKeyState() const
|
|||
void
|
||||
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
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_w = CGDisplayPixelsWide(m_displayID);
|
||||
m_h = CGDisplayPixelsHigh(m_displayID);
|
||||
m_x = (SInt32)totalBounds.origin.x;
|
||||
m_y = (SInt32)totalBounds.origin.y;
|
||||
m_w = (SInt32)totalBounds.size.width;
|
||||
m_h = (SInt32)totalBounds.size.height;
|
||||
|
||||
// get center of default screen
|
||||
// XXX -- this should compute the center of displays[0]
|
||||
m_xCenter = m_x + (m_w >> 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);
|
||||
}
|
||||
|
|
|
@ -76,6 +76,11 @@ protected:
|
|||
|
||||
private:
|
||||
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:
|
||||
// true if screen is being used as a primary screen, false otherwise
|
||||
|
@ -107,6 +112,9 @@ private:
|
|||
// screen saver stuff
|
||||
COSXScreenSaver* m_screensaver;
|
||||
bool m_screensaverNotify;
|
||||
|
||||
// clipboard stuff
|
||||
bool m_ownClipboard;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,11 +71,17 @@ MSWINDOWS_HOOK_SOURCE_FILES = \
|
|||
$(NULL)
|
||||
CARBON_SOURCE_FILES = \
|
||||
COSXClipboard.cpp \
|
||||
COSXClipboardAnyTextConverter.cpp \
|
||||
COSXClipboardTextConverter.cpp \
|
||||
COSXClipboardUTF16Converter.cpp \
|
||||
COSXEventQueueBuffer.cpp \
|
||||
COSXKeyState.cpp \
|
||||
COSXScreen.cpp \
|
||||
COSXScreenSaver.cpp \
|
||||
COSXClipboard.h \
|
||||
COSXClipboardAnyTextConverter.h \
|
||||
COSXClipboardTextConverter.h \
|
||||
COSXClipboardUTF16Converter.h \
|
||||
COSXEventQueueBuffer.h \
|
||||
COSXKeyState.h \
|
||||
COSXScreen.h \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue