/* meanwhilesession.h - interface to the 'C' meanwhile session Copyright (c) 2005 by Jeremy Kerr <jk@ozlabs.org> ************************************************************************* * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ************************************************************************* */ #ifndef MEANWHILESESSION_H #define MEANWHILESESSION_H #include "meanwhileaccount.h" #include "meanwhilecontact.h" #include <kextendedsocket.h> #include <mw_session.h> #include <mw_service.h> #include <mw_srvc_aware.h> #include <mw_srvc_im.h> #include <mw_srvc_resolve.h> struct MeanwhileClientID { int id; const char *name; }; /** * A class to handle libmeanwhile session management. */ class MeanwhileSession : public TQObject { TQ_OBJECT public: /** * Create a session. By default, the session is not connected - you will * need to call login() to initiate the connection process. * @param account The account that the connection is for */ MeanwhileSession(MeanwhileAccount *account); /** * Destroy the session */ ~MeanwhileSession(); /** * Connect to the server. This will open a socket and start login. Note that * the connection process is ascychronous - a loginDone() signal will be * emitted when sucessfully logged in. */ void connect(TQString password); /** * Disconnect from the server. */ void disconnect(); /** * Set our (the local contact's) online status. The internalStatus of the * state argument will be used to define the state message we send - it * should be one of the Status enum fields (and not Offline) * @param state the new state of the local user * @param msg a custom message to use, if required */ void setStatus(Kopete::OnlineStatus status, const TQString msg = TQString()); /** * Add a single contact to be registered for status updates * @param contact The contact to register */ void addContact(const Kopete::Contact *contact); /** * Add a list of contacts to be registered for status updates * @param contact The list of contacts to register */ void addContacts(const TQDict<Kopete::Contact>& contacts); /** * Send a message (with recipient specified). * @param message The message to send * @return non-zero if the message could be sent */ int sendMessage(Kopete::Message &message); /** * Send a typing notification to a contact * @param contact The contact to notify * @param isTyping If true, the typing notification is set */ void sendTyping(MeanwhileContact *contact, bool isTyping); /** * Determine if the session is connected to the server * @return true if the session is connected */ bool isConnected(); /** * Determine if the session is in the process of connecting to the server * @return true if the session is connecting */ bool isConnecting(); static const struct MeanwhileClientID *getClientIDs(); static void getDefaultClientIDParams(int *clientID, int *verMajor, int *verMinor); signals: /** * Emitted when the status of the connection changes * @param status The new status of the session */ void sessionStateChange(Kopete::OnlineStatus status); /** * Emitted when a notification is received from the server, or other * out-of-band data (eg, the password is incorrect). * @param mesgString A description of the notification */ void serverNotification(const TQString &mesgString); private: /** Main libmeanwhile session object */ struct mwSession *session; /** Session handler */ struct mwSessionHandler sessionHandler; /** Aware service */ struct mwServiceAware *awareService; /** Aware handler */ struct mwAwareHandler awareHandler; /** Aware List Handler */ struct mwAwareListHandler awareListHandler; /** The aware list */ struct mwAwareList *awareList; /** Aware service */ struct mwServiceIm *imService; /** Aware handler */ struct mwImHandler imHandler; /** Resolve service */ struct mwServiceResolve *resolveService; /** Storage service, for contact list */ struct mwServiceStorage *storageService; /** Last recorded meanwhile state */ enum mwSessionState state; /** The kopete account that this library is for */ MeanwhileAccount *account; /** socket to the server */ KExtendedSocket *socket; /* These structures are stored in the libmeanwhile 'ClientData' fields */ /** Stored in the mwConversation struct */ struct ConversationData { MeanwhileContact *contact; Kopete::ChatSession *chat; TQValueList<Kopete::Message> *queue; }; /** (To be) stored in the mwConference struct */ struct ConferenceData { Kopete::ChatSession *chatsession; }; /** * Initialise the conversation data struct for a conversation, and store it * in the meanwhile conversation object * @param conv the meanwhile conversation object * @param contact the contact that the conversation is with * @param createQueue whether a message queue is required for this * conversation * @return The created conversation data struct */ struct ConversationData *createConversationData( struct mwConversation *conv, MeanwhileContact *contact, bool createQueue = false); /** * Get the contact for a conversation * @param conv the meanwhile conversation * @return the contact that this conversation is held with */ MeanwhileContact *conversationContact(struct mwConversation *conv); /** * Convert a libmeanwhile-type status into one of the MeanwhileProtocol * statuses * @param mstatus The internal status to convert * @return The Meanwhile status */ Kopete::OnlineStatus convertStatus(int mstatus); /** * Parse the nickname of a libmeanwhile contact. From what I've seen, * usernames are in the format: * <userid> - <name>/<domain>/<domain> * @param name the extened username to parse * @return just the name part of the username info */ TQString getNickName(TQString name); /** * Convenience method to call the above from a mwLoginInfo struct. All is * checked for null. * @param logininfo the login info for a contact * @return just the name part of the login info data */ TQString getNickName(struct mwLoginInfo *logininfo); /** * Resolve a contact to find (and set) the display name. This requires the * session to be connected to use the meanwhile resolve service. * @param contact The contact to resolve */ void resolveContactNickname(MeanwhileContact *contact); public: void syncContactsToServer(); void syncContactsFromServer(); private slots: /** Notify the library that data is available on the socket */ void slotSocketDataAvailable(); /** * Notify the library that the socket has been closed * @param reason the reason for closing */ void slotSocketClosed(int reason); private: /* ugly callbacks for libmeanwhile interface. These declare a static method * to proxy the callback from libmeanwhile to a call to the MeanwhileSession */ #define declare_session_handler_type(type, func, args, ...) \ static type _handleSession ## func ( \ struct mwSession *mwsession, __VA_ARGS__) { \ MeanwhileSession *session = \ (MeanwhileSession *)mwSession_getClientData(mwsession); \ return session->handleSession ## func args; \ }; \ type handleSession ## func(__VA_ARGS__) #define declare_session_handler(func, args, ...) \ static void _handleSession ## func ( \ struct mwSession *mwsession, ## __VA_ARGS__) { \ MeanwhileSession *session = \ (MeanwhileSession *)mwSession_getClientData(mwsession); \ session->handleSession ## func args; \ }; \ void handleSession ## func(__VA_ARGS__) declare_session_handler_type(int, IOWrite, (buf, len), const guchar *buf, gsize len); declare_session_handler(IOClose,()); declare_session_handler(Clear,()); declare_session_handler(StateChange, (state, info), enum mwSessionState state, gpointer info); declare_session_handler(SetPrivacyInfo,()); declare_session_handler(SetUserStatus,()); declare_session_handler(Admin, (text), const char *text); declare_session_handler(Announce, (from, may_reply, text), struct mwLoginInfo *from, gboolean may_reply, const char *text); #define declare_aware_handler(func, args, ...) \ static void _handleAware ## func ( \ struct mwServiceAware *srvc, ## __VA_ARGS__) { \ MeanwhileSession *session = (MeanwhileSession *) \ mwService_getClientData((struct mwService *)srvc); \ return session->handleAware ## func args; \ }; \ void handleAware ## func(__VA_ARGS__) declare_aware_handler(Attrib, (attrib), struct mwAwareAttribute *attrib); declare_aware_handler(Clear,()); #define declare_aware_list_handler(func, args, ...) \ static void _handleAwareList ## func ( \ struct mwAwareList *list, ## __VA_ARGS__){ \ MeanwhileSession *session = (MeanwhileSession *) \ mwAwareList_getClientData(list); \ return session->handleAwareList ## func args; \ }; \ void handleAwareList ## func(__VA_ARGS__) declare_aware_list_handler(Aware, (snapshot), struct mwAwareSnapshot *snapshot); declare_aware_list_handler(Attrib, (id, attrib), struct mwAwareIdBlock *id, struct mwAwareAttribute *attrib); declare_aware_list_handler(Clear,()); #define declare_im_handler(func, args, ...) \ static void _handleIm ## func ( \ struct mwConversation *conv, ## __VA_ARGS__) { \ MeanwhileSession *session = (MeanwhileSession *) \ mwService_getClientData( \ (struct mwService *)mwConversation_getService(conv)); \ return session->handleIm ## func args; \ }; \ void handleIm ## func (struct mwConversation *conv, ## __VA_ARGS__) declare_im_handler(ConvOpened, (conv)); declare_im_handler(ConvClosed, (conv, err), guint32 err); declare_im_handler(ConvReceived, (conv, type, msg), enum mwImSendType type, gconstpointer msg); /* resolve service */ static void _handleResolveLookupResults(struct mwServiceResolve *srvc, guint32 id, guint32 code, GList *results, gpointer data) { MeanwhileSession *session = (MeanwhileSession *) mwService_getClientData(MW_SERVICE(srvc)); session->handleResolveLookupResults(srvc, id, code, results, data); }; void handleResolveLookupResults(struct mwServiceResolve *srvc, guint32 id, guint32 code, GList *results, gpointer data); /* storage service */ static void _handleStorageLoad(struct mwServiceStorage *srvc, guint32 result, struct mwStorageUnit *item, gpointer data) { MeanwhileSession *session = (MeanwhileSession *) mwService_getClientData(MW_SERVICE(srvc)); session->handleStorageLoad(srvc, result, item, data); }; void handleStorageLoad(struct mwServiceStorage *srvc, guint32 result, struct mwStorageUnit *item, gpointer data); }; #endif