#ifndef _KPILOT_KPILOTDEVICELINKPRIVATE_H #define _KPILOT_KPILOTDEVICELINKPRIVATE_H /* ** ** Copyright (C) 2007 by Jason 'vanRijn' Kasper ** */ /* ** 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 #include #include #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.tqcontains(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("")) << "]" << endl; } }; class Messages { public: Messages(KPilotDeviceLink *tqparent) : fDeviceLink(tqparent) { 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