source: protocols/purple/purple.c @ 860ba6a

Last change on this file since 860ba6a was 860ba6a, checked in by Wilmer van der Gaast <wilmer@…>, at 2009-10-05T23:32:34Z

Moved some stuff around, got something that logs in and reports status now.

  • Property mode set to 100644
File size: 8.6 KB
RevLine 
[796da03]1/***************************************************************************\
2*                                                                           *
3*  BitlBee - An IRC to IM gateway                                           *
4*  libpurple module - Main file                                             *
5*                                                                           *
6*  Copyright 2009 Wilmer van der Gaast <wilmer@gaast.net>                   *
7*                                                                           *
8*  This program is free software; you can redistribute it and/or modify     *
9*  it under the terms of the GNU General Public License as published by     *
10*  the Free Software Foundation; either version 2 of the License, or        *
11*  (at your option) any later version.                                      *
12*                                                                           *
13*  This program is distributed in the hope that it will be useful,          *
14*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
15*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
16*  GNU General Public License for more details.                             *
17*                                                                           *
18*  You should have received a copy of the GNU General Public License along  *
19*  with this program; if not, write to the Free Software Foundation, Inc.,  *
20*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
21*                                                                           *
22\***************************************************************************/
23
24#include <glib.h>
25#include <purple.h>
26
27#include "bitlbee.h"
28
29GSList *purple_connections;
30
31#undef g_io_add_watch
32#undef g_io_add_watch_full
33#undef g_timeout_add
34#undef g_source_remove
35
36/**
37 * The following eventloop functions are used in both pidgin and purple-text. If your
38 * application uses glib mainloop, you can safely use this verbatim.
39 */
40#define PURPLE_GLIB_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)
41#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
42
43typedef struct _PurpleGLibIOClosure {
44        PurpleInputFunction function;
45        guint result;
46        gpointer data;
47} PurpleGLibIOClosure;
48
[860ba6a]49static struct im_connection *purple_ic_by_gc( PurpleConnection *gc )
50{
51        PurpleAccount *pa = purple_connection_get_account( gc );
52        GSList *i;
53       
54        for( i = purple_connections; i; i = i->next )
55                if( ((struct im_connection *)i->data)->proto_data == pa )
56                        return i->data;
57       
58        return NULL;
59}
60
[796da03]61static void purple_glib_io_destroy(gpointer data)
62{
63        g_free(data);
64}
65
66static gboolean purple_glib_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
67{
68        PurpleGLibIOClosure *closure = data;
69        PurpleInputCondition purple_cond = 0;
70
71        if (condition & PURPLE_GLIB_READ_COND)
72                purple_cond |= PURPLE_INPUT_READ;
73        if (condition & PURPLE_GLIB_WRITE_COND)
74                purple_cond |= PURPLE_INPUT_WRITE;
75
76        closure->function(closure->data, g_io_channel_unix_get_fd(source),
77                          purple_cond);
78
79        return TRUE;
80}
81
82static guint glib_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function,
83                                                           gpointer data)
84{
85        PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);
86        GIOChannel *channel;
87        GIOCondition cond = 0;
88
89        closure->function = function;
90        closure->data = data;
91
92        if (condition & PURPLE_INPUT_READ)
93                cond |= PURPLE_GLIB_READ_COND;
94        if (condition & PURPLE_INPUT_WRITE)
95                cond |= PURPLE_GLIB_WRITE_COND;
96
97        channel = g_io_channel_unix_new(fd);
98        closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
99                                              purple_glib_io_invoke, closure, purple_glib_io_destroy);
100
101        g_io_channel_unref(channel);
102        return closure->result;
103}
104
105static PurpleEventLoopUiOps glib_eventloops = 
106{
107        g_timeout_add,
108        g_source_remove,
109        glib_input_add,
110        g_source_remove,
111        NULL,
112#if GLIB_CHECK_VERSION(2,14,0)
113        g_timeout_add_seconds,
114#else
115        NULL,
116#endif
117
118        /* padding */
119        NULL,
120        NULL,
121        NULL
122};
123
124static void purple_init( account_t *acc )
125{
[860ba6a]126        /* TODO: Figure out variables to export via set. */
[796da03]127}
128
129static void purple_login( account_t *acc )
130{
131        struct im_connection *ic = imcb_new( acc );
[860ba6a]132        PurpleAccount *pa;
133        PurpleSavedStatus *ps;
[796da03]134       
135        /* For now this is needed in the _connected() handlers if using
136           GLib event handling, to make sure we're not handling events
137           on dead connections. */
138        purple_connections = g_slist_prepend( purple_connections, ic );
139       
[860ba6a]140        pa = purple_account_new( acc->user, acc->prpl->name );
141        purple_account_set_password( pa, acc->pass );
142       
143        ic->proto_data = pa;
144       
145        purple_account_set_enabled( pa, "BitlBee", TRUE );
146       
147        //ps = purple_savedstatus_new( NULL, PURPLE_STATUS_AVAILABLE );
148        //purple_savedstatus_activate_for_account( ps, pa );
[796da03]149}
150
151static void purple_logout( struct im_connection *ic )
152{
153        purple_connections = g_slist_remove( purple_connections, ic );
154}
155
156static int purple_buddy_msg( struct im_connection *ic, char *who, char *message, int flags )
157{
158}
159
160static GList *purple_away_states( struct im_connection *ic )
161{
[860ba6a]162        return NULL;
[796da03]163}
164
165static void purple_set_away( struct im_connection *ic, char *state_txt, char *message )
166{
167}
168
169static void purple_add_buddy( struct im_connection *ic, char *who, char *group )
170{
171}
172
173static void purple_remove_buddy( struct im_connection *ic, char *who, char *group )
174{
175}
176
177static void purple_keepalive( struct im_connection *ic )
178{
179}
180
181static int purple_send_typing( struct im_connection *ic, char *who, int typing )
182{
183}
184
[860ba6a]185static void purple_ui_init();
186
187static PurpleCoreUiOps bee_core_uiops = 
188{
189        NULL,
190        NULL,
191        purple_ui_init,
192        NULL,
193
194        /* padding */
195        NULL,
196        NULL,
197        NULL,
198        NULL
199};
200
201static void prplcb_conn_progress( PurpleConnection *gc, const char *text, size_t step, size_t step_count )
202{
203        imcb_log( purple_ic_by_gc( gc ), "%s", text );
204}
205
206static void prplcb_conn_connected( PurpleConnection *gc )
207{
208        imcb_connected( purple_ic_by_gc( gc ) );
209}
210
211static void prplcb_conn_disconnected( PurpleConnection *gc )
212{
213        imc_logout( purple_ic_by_gc( gc ), TRUE );
214}
215
216static void prplcb_conn_notice( PurpleConnection *gc, const char *text )
217{
218        imcb_log( purple_ic_by_gc( gc ), "%s", text );
219}
220
221static void prplcb_conn_report_disconnect_reason( PurpleConnection *gc, PurpleConnectionError reason, const char *text )
222{
223        /* PURPLE_CONNECTION_ERROR_NAME_IN_USE means concurrent login,
224           should probably handle that. */
225        imcb_error( purple_ic_by_gc( gc ), "%s", text );
226}
227
228static PurpleConnectionUiOps bee_conn_uiops =
229{
230        prplcb_conn_progress,
231        prplcb_conn_connected,
232        prplcb_conn_disconnected,
233        prplcb_conn_notice,
234        NULL,
235        NULL,
236        NULL,
237        prplcb_conn_report_disconnect_reason,
238};
239
240static PurpleConversationUiOps bee_conv_uiops = 
241{
242        NULL,                      /* create_conversation  */
243        NULL,                      /* destroy_conversation */
244        NULL,                      /* write_chat           */
245        NULL,                      /* write_im             */
246        NULL, //null_write_conv,           /* write_conv           */
247        NULL,                      /* chat_add_users       */
248        NULL,                      /* chat_rename_user     */
249        NULL,                      /* chat_remove_users    */
250        NULL,                      /* chat_update_user     */
251        NULL,                      /* present              */
252        NULL,                      /* has_focus            */
253        NULL,                      /* custom_smiley_add    */
254        NULL,                      /* custom_smiley_write  */
255        NULL,                      /* custom_smiley_close  */
256        NULL,                      /* send_confirm         */
257        NULL,
258        NULL,
259        NULL,
260        NULL
261};
262
263static void purple_ui_init()
264{
265        purple_connections_set_ui_ops( &bee_conn_uiops );
266        purple_conversations_set_ui_ops( &bee_conv_uiops );
267}
268
[796da03]269void purple_initmodule()
270{
271        GList *prots;
272       
273        purple_util_set_user_dir("/tmp");
274        purple_debug_set_enabled(FALSE);
275        purple_core_set_ui_ops(&bee_core_uiops);
276        purple_eventloop_set_ui_ops(&glib_eventloops);
277        if( !purple_core_init( "BitlBee") )
278        {
279                /* Initializing the core failed. Terminate. */
280                fprintf( stderr, "libpurple initialization failed.\n" );
281                abort();
282        }
283       
284        /* This seems like stateful shit we don't want... */
285        purple_set_blist(purple_blist_new());
286        purple_blist_load();
287       
288        /* Meh? */
289        purple_prefs_load();
290       
291        for( prots = purple_plugins_get_protocols(); prots; prots = prots->next )
292        {
293                struct prpl *ret = g_new0( struct prpl, 1 );
294                PurplePlugin *prot = prots->data;
295               
296                ret->name = prot->info->id;
297                ret->login = purple_login;
298                ret->init = purple_init;
299                ret->logout = purple_logout;
300                ret->buddy_msg = purple_buddy_msg;
301                ret->away_states = purple_away_states;
302                ret->set_away = purple_set_away;
303                ret->add_buddy = purple_add_buddy;
304                ret->remove_buddy = purple_remove_buddy;
305                ret->keepalive = purple_keepalive;
306                ret->send_typing = purple_send_typing;
307                ret->handle_cmp = g_strcasecmp;
308               
309                register_protocol( ret );
310        }
311}
Note: See TracBrowser for help on using the repository browser.