You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kpilot/lib/kpilotdevicelinkPrivate.h

332 lines
6.4 KiB

#ifndef _KPILOT_KPILOTDEVICELINKPRIVATE_H
#define _KPILOT_KPILOTDEVICELINKPRIVATE_H
/*
**
** Copyright (C) 2007 by Jason 'vanRijn' Kasper <vR@movingparts.net>
**
*/
/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/
/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include <errno.h>
#include <tqstringlist.h>
#include <tqthread.h>
#include "kpilotdevicelink.h"
#include "options.h"
class TQTimer;
class TQSocketNotifier;
// singleton helper class
class DeviceMap
{
public:
static DeviceMap *self()
{
if (!mThis)
mThis = new DeviceMap();
return mThis;
}
bool canBind(const TQString &device)
{
FUNCTIONSETUPL(5);
DEBUGKPILOT << fname << ": device: ["
<< device << "]" << endl;
showList();
return !mBoundDevices.contains(device);
}
void bindDevice(const TQString &device)
{
FUNCTIONSETUPL(5);
DEBUGKPILOT << fname << ": device: ["
<< device << "]" << endl;
mBoundDevices.append(device);
showList();
}
void unbindDevice(const TQString &device)
{
FUNCTIONSETUPL(5);
DEBUGKPILOT << fname << ": device: ["
<< device << "]" << endl;
mBoundDevices.remove(device);
showList();
}
protected:
DeviceMap()
{
mBoundDevices.clear();
}
~DeviceMap()
{
}
TQStringList mBoundDevices;
static DeviceMap *mThis;
private:
void showList() const
{
FUNCTIONSETUPL(5);
if ( !(mBoundDevices.count() > 0))
return;
DEBUGKPILOT << fname << ": Bound devices: ["
<< ((mBoundDevices.count() > 0) ?
mBoundDevices.join(CSL1(", ")) : CSL1("<none>"))
<< "]" << endl;
}
};
class Messages
{
public:
Messages(KPilotDeviceLink *parent) :
fDeviceLink(parent)
{
reset();
}
void reset()
{
messages = 0;
messagesMask = ~messageIsError; // Never block errors
}
void block(unsigned int m, bool force=false)
{
if (force)
{
// Force blocking this message, even if it's an error msg.
messages |= m;
}
else
{
messages |= (m & messagesMask);
}
}
/**
* Some messages are only printed once and are suppressed
* after that. These are indicated by flag bits in
* messages. The following enum is a bitfield.
*/
enum
{
OpenMessage=1, ///< Trying to open device ..
OpenFailMessage=2 ///< Failed to open device ...
};
int messages;
int messagesMask;
static const int messageIsError = 0;
/** Determines whether message @p s which has an id of @p msgid (one of
* the enum values mentioned above) should be printed, which is only if that
* message has not been suppressed through messagesMask.
* If return is true, this method also adds it to the messagesMask.
*/
bool shouldPrint(int msgid)
{
if (!(messages & msgid))
{
block(msgid);
return true;
}
else
{
return false;
}
}
protected:
KPilotDeviceLink *fDeviceLink;
};
class DeviceCommEvent : public TQEvent
{
public:
DeviceCommEvent(DeviceCustomEvents type, TQString msg = TQString(),
int progress = 0) :
TQEvent( (TQEvent::Type)type ), fMessage(msg), fProgress(progress),
fPilotSocket(-1)
{
}
TQString message() const
{
return fMessage;
}
int progress()
{
return fProgress;
}
inline void setCurrentSocket(int i)
{
fPilotSocket = i;
}
inline int currentSocket()
{
return fPilotSocket;
}
private:
TQString fMessage;
int fProgress;
/**
* Pilot-link library handles for the device once it's opened.
*/
int fPilotSocket;
};
/** Class that handles all device communications. We do this
in a different thread so that we do not block the main TQt
Event thread (similar to Swing's AWT event dispatch thread).
*/
class DeviceCommThread : public TQObject, public TQThread
{
friend class KPilotDeviceLink;
Q_OBJECT
TQ_OBJECT
public:
DeviceCommThread(KPilotDeviceLink *d);
virtual ~DeviceCommThread();
virtual void run();
void setDone(bool b)
{
FUNCTIONSETUP;
fDone = b;
}
protected:
void close();
void reset();
/**
* Does the low-level opening of the device and handles the
* pilot-link library initialisation.
*/
bool open(const TQString &device = TQString());
protected slots:
/**
* Attempt to open the device. Called regularly to check
* if the device exists (to handle USB-style devices).
*/
void openDevice();
/**
* Called when the device is opened *and* activity occurs on the
* device. This indicates the beginning of a hotsync.
*/
void acceptDevice();
/**
* This slot fires whenever we've been trying to establish a hotsync with
* the device for longer than a given amount of time. When this slot is
* fired, we will tear down the communications process and start over again.
*/
void workaroundUSB();
private:
volatile bool fDone;
KPilotDeviceLink *fHandle;
inline KPilotDeviceLink *link()
{
if (fHandle)
{
return fHandle;
}
else
{
FUNCTIONSETUP;
WARNINGKPILOT << "Link asked for, but either I'm "
<< "done or I don't have a valid handle. "
<< "Shutting down comm thread." << endl;
TQThread::exit();
return 0;
}
}
/**
* Timers and Notifiers for detecting activity on the device.
*/
TQTimer *fOpenTimer;
TQSocketNotifier *fSocketNotifier;
bool fSocketNotifierActive;
/** Timer used to check for a badly-connected Z31/72 */
TQTimer *fWorkaroundUSBTimer;
/**
* Pilot-link library handles for the device once it's opened.
*/
int fPilotSocket;
int fTempSocket;
inline TQString errorMessage(int e)
{
switch (e)
{
case ENOENT:
return i18n(" The port does not exist.");
break;
case ENODEV:
return i18n(" There is no such device.");
break;
case EPERM:
return i18n(" You do not have permission to open the "
"Pilot device.");
break;
default:
return i18n(" Check Pilot path and permissions.");
}
}
/**
* Handle cases where we can't accept or open the device,
* and data remains available on the pilot socket.
*/
int fAcceptedCount;
};
#endif