Mercurial > pidgin.yaz
comparison src/protocols/oscar/oscar.c @ 2191:657dbe515608
[gaim-migrate @ 2201]
genericize buddy icon stuff
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Wed, 29 Aug 2001 23:41:43 +0000 |
parents | cdf43acb5b83 |
children | 177397ceac57 |
comparison
equal
deleted
inserted
replaced
2190:24d947eff811 | 2191:657dbe515608 |
---|---|
24 #include <config.h> | 24 #include <config.h> |
25 #endif | 25 #endif |
26 | 26 |
27 | 27 |
28 #include <netdb.h> | 28 #include <netdb.h> |
29 #include <gtk/gtk.h> | |
30 #include <unistd.h> | 29 #include <unistd.h> |
31 #include <errno.h> | 30 #include <errno.h> |
32 #include <netinet/in.h> | 31 #include <netinet/in.h> |
33 #include <arpa/inet.h> | 32 #include <arpa/inet.h> |
34 #include <string.h> | 33 #include <string.h> |
41 #include "prpl.h" | 40 #include "prpl.h" |
42 #include "gaim.h" | 41 #include "gaim.h" |
43 #include "aim.h" | 42 #include "aim.h" |
44 #include "proxy.h" | 43 #include "proxy.h" |
45 | 44 |
46 #if USE_PIXBUF | |
47 #include <gdk-pixbuf/gdk-pixbuf.h> | |
48 #include <gdk-pixbuf/gdk-pixbuf-loader.h> | |
49 #define SCALE 48 | |
50 #endif | |
51 | |
52 /*#include "pixmaps/cancel.xpm"*/ | 45 /*#include "pixmaps/cancel.xpm"*/ |
53 #include "pixmaps/admin_icon.xpm" | 46 #include "pixmaps/admin_icon.xpm" |
54 #include "pixmaps/aol_icon.xpm" | 47 #include "pixmaps/aol_icon.xpm" |
55 #include "pixmaps/away_icon.xpm" | 48 #include "pixmaps/away_icon.xpm" |
56 #include "pixmaps/dt_icon.xpm" | 49 #include "pixmaps/dt_icon.xpm" |
120 struct gaim_connection *gc; | 113 struct gaim_connection *gc; |
121 char *sn; | 114 char *sn; |
122 struct aim_directim_priv *priv; | 115 struct aim_directim_priv *priv; |
123 }; | 116 }; |
124 | 117 |
125 #if USE_PIXBUF | |
126 struct icon_req { | 118 struct icon_req { |
127 char *user; | 119 char *user; |
128 time_t timestamp; | 120 time_t timestamp; |
129 unsigned long length; | 121 unsigned long checksum; |
130 gpointer data; | |
131 gboolean request; | 122 gboolean request; |
132 GdkPixbufAnimation *anim; | |
133 GdkPixbuf *unanim; | |
134 struct conversation *cnv; | |
135 GtkWidget *pix; | |
136 int curframe; | |
137 int timer; | |
138 }; | 123 }; |
139 #endif | |
140 | 124 |
141 static struct direct_im *find_direct_im(struct oscar_data *od, char *who) { | 125 static struct direct_im *find_direct_im(struct oscar_data *od, char *who) { |
142 GSList *d = od->direct_ims; | 126 GSList *d = od->direct_ims; |
143 char *n = g_strdup(normalize(who)); | 127 char *n = g_strdup(normalize(who)); |
144 struct direct_im *m = NULL; | 128 struct direct_im *m = NULL; |
475 g_free(n); | 459 g_free(n); |
476 } | 460 } |
477 #if USE_PIXBUF | 461 #if USE_PIXBUF |
478 while (odata->hasicons) { | 462 while (odata->hasicons) { |
479 struct icon_req *n = odata->hasicons->data; | 463 struct icon_req *n = odata->hasicons->data; |
480 if (n->anim) | |
481 gdk_pixbuf_animation_unref(n->anim); | |
482 if (n->unanim) | |
483 gdk_pixbuf_unref(n->unanim); | |
484 if (n->timer) | |
485 g_source_remove(n->timer); | |
486 if (n->cnv && n->pix) | |
487 gtk_container_remove(GTK_CONTAINER(n->cnv->bbox), n->pix); | |
488 g_free(n->user); | 464 g_free(n->user); |
489 if (n->data) | |
490 g_free(n->data); | |
491 odata->hasicons = g_slist_remove(odata->hasicons, n); | 465 odata->hasicons = g_slist_remove(odata->hasicons, n); |
492 g_free(n); | 466 g_free(n); |
493 } | 467 } |
494 #endif | 468 #endif |
495 if (gc->inpa > 0) | 469 if (gc->inpa > 0) |
1264 cancel_direct_im(w, d); | 1238 cancel_direct_im(w, d); |
1265 | 1239 |
1266 return TRUE; | 1240 return TRUE; |
1267 } | 1241 } |
1268 | 1242 |
1269 #if USE_PIXBUF | |
1270 static gboolean redraw_anim(gpointer data) | |
1271 { | |
1272 int delay; | |
1273 struct icon_req *ir = data; | |
1274 GList *frames; | |
1275 GdkPixbufFrame *frame; | |
1276 GdkPixbuf *buf; | |
1277 GdkPixbuf *scale; | |
1278 GdkPixmap *pm; GdkBitmap *bm; | |
1279 GdkPixmap *src; | |
1280 GdkGC *gc; | |
1281 | |
1282 if (!ir->cnv || !g_list_find(conversations, ir->cnv)) { | |
1283 debug_printf("I think this is a bug.\n"); | |
1284 return FALSE; | |
1285 } | |
1286 | |
1287 frames = gdk_pixbuf_animation_get_frames(ir->anim); | |
1288 frame = g_list_nth_data(frames, ir->curframe); | |
1289 switch (gdk_pixbuf_frame_get_action(frame)) { | |
1290 case GDK_PIXBUF_FRAME_RETAIN: | |
1291 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
1292 scale = gdk_pixbuf_scale_simple(buf, | |
1293 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
1294 gdk_pixbuf_animation_get_width(ir->anim), 1), | |
1295 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
1296 gdk_pixbuf_animation_get_height(ir->anim), 1), | |
1297 GDK_INTERP_NEAREST); | |
1298 gdk_pixbuf_render_pixmap_and_mask(scale, &src, NULL, 0); | |
1299 gdk_pixbuf_unref(scale); | |
1300 gtk_pixmap_get(GTK_PIXMAP(ir->pix), &pm, &bm); | |
1301 gc = gdk_gc_new(pm); | |
1302 gdk_draw_pixmap(pm, gc, src, 0, 0, | |
1303 MAX(gdk_pixbuf_frame_get_x_offset(frame) * SCALE / | |
1304 gdk_pixbuf_animation_get_width(ir->anim), 1), | |
1305 MAX(gdk_pixbuf_frame_get_y_offset(frame) * SCALE / | |
1306 gdk_pixbuf_animation_get_height(ir->anim), 1), | |
1307 -1, -1); | |
1308 gdk_pixmap_unref(src); | |
1309 gtk_widget_queue_draw(ir->pix); | |
1310 gdk_gc_unref(gc); | |
1311 break; | |
1312 case GDK_PIXBUF_FRAME_DISPOSE: | |
1313 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
1314 scale = gdk_pixbuf_scale_simple(buf, | |
1315 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
1316 gdk_pixbuf_animation_get_width(ir->anim), 1), | |
1317 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
1318 gdk_pixbuf_animation_get_height(ir->anim), 1), | |
1319 GDK_INTERP_NEAREST); | |
1320 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
1321 gdk_pixbuf_unref(scale); | |
1322 gtk_pixmap_set(GTK_PIXMAP(ir->pix), pm, bm); | |
1323 gdk_pixmap_unref(pm); | |
1324 if (bm) | |
1325 gdk_bitmap_unref(bm); | |
1326 break; | |
1327 case GDK_PIXBUF_FRAME_REVERT: | |
1328 frame = frames->data; | |
1329 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
1330 scale = gdk_pixbuf_scale_simple(buf, | |
1331 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
1332 gdk_pixbuf_animation_get_width(ir->anim), 1), | |
1333 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
1334 gdk_pixbuf_animation_get_height(ir->anim), 1), | |
1335 GDK_INTERP_NEAREST); | |
1336 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
1337 gdk_pixbuf_unref(scale); | |
1338 gtk_pixmap_set(GTK_PIXMAP(ir->pix), pm, bm); | |
1339 gdk_pixmap_unref(pm); | |
1340 if (bm) | |
1341 gdk_bitmap_unref(bm); | |
1342 break; | |
1343 } | |
1344 ir->curframe = (ir->curframe + 1) % g_list_length(frames); | |
1345 delay = MAX(gdk_pixbuf_frame_get_delay_time(frame), 13); | |
1346 ir->timer = g_timeout_add(delay * 10, redraw_anim, ir); | |
1347 return FALSE; | |
1348 } | |
1349 #endif | |
1350 | |
1351 int gaim_parse_incoming_im(struct aim_session_t *sess, | 1243 int gaim_parse_incoming_im(struct aim_session_t *sess, |
1352 struct command_rx_struct *command, ...) { | 1244 struct command_rx_struct *command, ...) { |
1353 int channel; | 1245 int channel; |
1354 struct aim_userinfo_s *userinfo; | 1246 struct aim_userinfo_s *userinfo; |
1355 va_list ap; | 1247 va_list ap; |
1365 struct aim_incomingim_ch1_args *args; | 1257 struct aim_incomingim_ch1_args *args; |
1366 | 1258 |
1367 args = va_arg(ap, struct aim_incomingim_ch1_args *); | 1259 args = va_arg(ap, struct aim_incomingim_ch1_args *); |
1368 va_end(ap); | 1260 va_end(ap); |
1369 | 1261 |
1370 #if USE_PIXBUF | |
1371 if (args->icbmflags & AIM_IMFLAGS_HASICON) { | 1262 if (args->icbmflags & AIM_IMFLAGS_HASICON) { |
1372 struct oscar_data *od = gc->proto_data; | 1263 struct oscar_data *od = gc->proto_data; |
1373 struct icon_req *ir = NULL; | 1264 struct icon_req *ir = NULL; |
1374 GSList *h = od->hasicons; | 1265 GSList *h = od->hasicons; |
1375 char *who = normalize(userinfo->sn); | 1266 char *who = normalize(userinfo->sn); |
1387 } | 1278 } |
1388 if (args->iconstamp > ir->timestamp) | 1279 if (args->iconstamp > ir->timestamp) |
1389 ir->request = TRUE; | 1280 ir->request = TRUE; |
1390 ir->timestamp = args->iconstamp; | 1281 ir->timestamp = args->iconstamp; |
1391 } | 1282 } |
1392 #endif | |
1393 | 1283 |
1394 /* | 1284 /* |
1395 * Quickly convert it to eight bit format, replacing | 1285 * Quickly convert it to eight bit format, replacing |
1396 * non-ASCII UNICODE characters with their equivelent | 1286 * non-ASCII UNICODE characters with their equivelent |
1397 * HTML entity. | 1287 * HTML entity. |
1432 g_free(name); | 1322 g_free(name); |
1433 } else if (args->reqclass & AIM_CAPS_SENDFILE) { | 1323 } else if (args->reqclass & AIM_CAPS_SENDFILE) { |
1434 } else if (args->reqclass & AIM_CAPS_GETFILE) { | 1324 } else if (args->reqclass & AIM_CAPS_GETFILE) { |
1435 } else if (args->reqclass & AIM_CAPS_VOICE) { | 1325 } else if (args->reqclass & AIM_CAPS_VOICE) { |
1436 } else if (args->reqclass & AIM_CAPS_BUDDYICON) { | 1326 } else if (args->reqclass & AIM_CAPS_BUDDYICON) { |
1437 #if USE_PIXBUF | 1327 set_icon_data(gc, normalize(userinfo->sn), args->info.icon.icon, |
1438 struct oscar_data *od = gc->proto_data; | 1328 args->info.icon.length); |
1439 GSList *h = od->hasicons; | |
1440 struct icon_req *ir = NULL; | |
1441 char *who; | |
1442 struct conversation *c; | |
1443 | |
1444 GdkPixbufLoader *load; | |
1445 GList *frames; | |
1446 GdkPixbuf *buf; | |
1447 GdkPixbuf *scale; | |
1448 GdkPixmap *pm; | |
1449 GdkBitmap *bm; | |
1450 | |
1451 who = normalize(userinfo->sn); | |
1452 | |
1453 while (h) { | |
1454 ir = h->data; | |
1455 if (!strcmp(who, ir->user)) | |
1456 break; | |
1457 h = h->next; | |
1458 | |
1459 } | |
1460 | |
1461 if (!h || ((c = find_conversation(userinfo->sn)) == NULL) || (c->gc != gc)) { | |
1462 debug_printf("got buddy icon for %s but didn't want it\n", userinfo->sn); | |
1463 return 1; | |
1464 } | |
1465 | |
1466 if (ir->pix && ir->cnv) | |
1467 gtk_container_remove(GTK_CONTAINER(ir->cnv->bbox), ir->pix); | |
1468 ir->pix = NULL; | |
1469 ir->cnv = NULL; | |
1470 if (ir->data) | |
1471 g_free(ir->data); | |
1472 if (ir->anim) | |
1473 gdk_pixbuf_animation_unref(ir->anim); | |
1474 ir->anim = NULL; | |
1475 if (ir->unanim) | |
1476 gdk_pixbuf_unref(ir->unanim); | |
1477 ir->unanim = NULL; | |
1478 if (ir->timer) | |
1479 g_source_remove(ir->timer); | |
1480 ir->timer = 0; | |
1481 | |
1482 ir->length = args->info.icon.length; | |
1483 | |
1484 if (!ir->length) | |
1485 return 1; | |
1486 | |
1487 ir->data = g_memdup(args->info.icon.icon, args->info.icon.length); | |
1488 | |
1489 load = gdk_pixbuf_loader_new(); | |
1490 gdk_pixbuf_loader_write(load, ir->data, ir->length); | |
1491 ir->anim = gdk_pixbuf_loader_get_animation(load); | |
1492 | |
1493 if (ir->anim) { | |
1494 frames = gdk_pixbuf_animation_get_frames(ir->anim); | |
1495 buf = gdk_pixbuf_frame_get_pixbuf(frames->data); | |
1496 scale = gdk_pixbuf_scale_simple(buf, | |
1497 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
1498 gdk_pixbuf_animation_get_width(ir->anim), 1), | |
1499 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
1500 gdk_pixbuf_animation_get_height(ir->anim), 1), | |
1501 GDK_INTERP_NEAREST); | |
1502 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
1503 gdk_pixbuf_unref(scale); | |
1504 | |
1505 if (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1) { | |
1506 int delay = | |
1507 MAX(gdk_pixbuf_frame_get_delay_time(frames->data), 13); | |
1508 ir->curframe = 1; | |
1509 ir->timer = g_timeout_add(delay * 10, redraw_anim, ir); | |
1510 } | |
1511 } else { | |
1512 ir->unanim = gdk_pixbuf_loader_get_pixbuf(load); | |
1513 if (!ir->unanim) { | |
1514 gdk_pixbuf_loader_close(load); | |
1515 return 1; | |
1516 } | |
1517 scale = gdk_pixbuf_scale_simple(ir->unanim, SCALE, SCALE, | |
1518 GDK_INTERP_NEAREST); | |
1519 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
1520 gdk_pixbuf_unref(scale); | |
1521 } | |
1522 | |
1523 ir->cnv = c; | |
1524 ir->pix = gtk_pixmap_new(pm, bm); | |
1525 gtk_box_pack_start(GTK_BOX(c->bbox), ir->pix, FALSE, FALSE, 5); | |
1526 if (ir->anim && (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1)) | |
1527 gtk_widget_set_usize(ir->pix, SCALE, SCALE); | |
1528 gtk_widget_show(ir->pix); | |
1529 gdk_pixmap_unref(pm); | |
1530 if (bm) | |
1531 gdk_bitmap_unref(bm); | |
1532 | |
1533 gdk_pixbuf_loader_close(load); | |
1534 | |
1535 #endif | |
1536 } else if (args->reqclass & AIM_CAPS_IMIMAGE) { | 1329 } else if (args->reqclass & AIM_CAPS_IMIMAGE) { |
1537 struct ask_direct *d = g_new0(struct ask_direct, 1); | 1330 struct ask_direct *d = g_new0(struct ask_direct, 1); |
1538 char buf[256]; | 1331 char buf[256]; |
1539 | 1332 |
1540 debug_printf("%s received direct im request from %s (%s)\n", | 1333 debug_printf("%s received direct im request from %s (%s)\n", |
2883 aim_auth_changepasswd(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), | 2676 aim_auth_changepasswd(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), |
2884 new, old); | 2677 new, old); |
2885 } | 2678 } |
2886 } | 2679 } |
2887 | 2680 |
2888 static void oscar_insert_convo(struct gaim_connection *gc, struct conversation *c) | |
2889 { | |
2890 #if USE_PIXBUF | |
2891 struct oscar_data *od = gc->proto_data; | |
2892 GSList *h = od->hasicons; | |
2893 struct icon_req *ir = NULL; | |
2894 char *who = normalize(c->name); | |
2895 | |
2896 GdkPixbufLoader *load; | |
2897 GList *frames; | |
2898 GdkPixbuf *buf; | |
2899 GdkPixbuf *scale; | |
2900 GdkPixmap *pm; | |
2901 GdkBitmap *bm; | |
2902 | |
2903 while (h) { | |
2904 ir = h->data; | |
2905 if (!strcmp(who, ir->user)) | |
2906 break; | |
2907 h = h->next; | |
2908 } | |
2909 if (!h || !ir->data) | |
2910 return; | |
2911 | |
2912 ir->cnv = c; | |
2913 | |
2914 load = gdk_pixbuf_loader_new(); | |
2915 gdk_pixbuf_loader_write(load, ir->data, ir->length); | |
2916 ir->anim = gdk_pixbuf_loader_get_animation(load); | |
2917 | |
2918 if (ir->anim) { | |
2919 frames = gdk_pixbuf_animation_get_frames(ir->anim); | |
2920 buf = gdk_pixbuf_frame_get_pixbuf(frames->data); | |
2921 scale = gdk_pixbuf_scale_simple(buf, | |
2922 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
2923 gdk_pixbuf_animation_get_width(ir->anim), 1), | |
2924 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
2925 gdk_pixbuf_animation_get_height(ir->anim), 1), | |
2926 GDK_INTERP_NEAREST); | |
2927 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
2928 gdk_pixbuf_unref(scale); | |
2929 | |
2930 if (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1) { | |
2931 int delay = MAX(gdk_pixbuf_frame_get_delay_time(frames->data), 13); | |
2932 ir->curframe = 1; | |
2933 ir->timer = g_timeout_add(delay * 10, redraw_anim, ir); | |
2934 } | |
2935 } else { | |
2936 ir->unanim = gdk_pixbuf_loader_get_pixbuf(load); | |
2937 if (!ir->unanim) { | |
2938 gdk_pixbuf_loader_close(load); | |
2939 return; | |
2940 } | |
2941 scale = gdk_pixbuf_scale_simple(ir->unanim, SCALE, SCALE, | |
2942 GDK_INTERP_NEAREST); | |
2943 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
2944 gdk_pixbuf_unref(scale); | |
2945 } | |
2946 | |
2947 ir->pix = gtk_pixmap_new(pm, bm); | |
2948 gtk_box_pack_start(GTK_BOX(c->bbox), ir->pix, FALSE, FALSE, 5); | |
2949 if (ir->anim && (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1)) | |
2950 gtk_widget_set_usize(ir->pix, gdk_pixbuf_animation_get_width(ir->anim), | |
2951 gdk_pixbuf_animation_get_height(ir->anim)); | |
2952 gtk_widget_show(ir->pix); | |
2953 gdk_pixmap_unref(pm); | |
2954 if (bm) | |
2955 gdk_bitmap_unref(bm); | |
2956 | |
2957 gdk_pixbuf_loader_close(load); | |
2958 #endif | |
2959 } | |
2960 | |
2961 static void oscar_remove_convo(struct gaim_connection *gc, struct conversation *c) | |
2962 { | |
2963 #if USE_PIXBUF | |
2964 struct oscar_data *od = gc->proto_data; | |
2965 GSList *h = od->hasicons; | |
2966 struct icon_req *ir = NULL; | |
2967 char *who = normalize(c->name); | |
2968 | |
2969 while (h) { | |
2970 ir = h->data; | |
2971 if (!strcmp(who, ir->user)) | |
2972 break; | |
2973 h = h->next; | |
2974 } | |
2975 if (!h || !ir->data) | |
2976 return; | |
2977 | |
2978 if (ir->cnv && ir->pix) { | |
2979 gtk_container_remove(GTK_CONTAINER(ir->cnv->bbox), ir->pix); | |
2980 ir->pix = NULL; | |
2981 ir->cnv = NULL; | |
2982 } | |
2983 | |
2984 if (ir->anim) { | |
2985 gdk_pixbuf_animation_unref(ir->anim); | |
2986 ir->anim = NULL; | |
2987 } else if (ir->unanim) { | |
2988 gdk_pixbuf_unref(ir->unanim); | |
2989 ir->unanim = NULL; | |
2990 } | |
2991 | |
2992 ir->curframe = 0; | |
2993 | |
2994 if (ir->timer) | |
2995 g_source_remove(ir->timer); | |
2996 ir->timer = 0; | |
2997 #endif | |
2998 } | |
2999 | |
3000 static struct prpl *my_protocol = NULL; | 2681 static struct prpl *my_protocol = NULL; |
3001 | 2682 |
3002 void oscar_init(struct prpl *ret) { | 2683 void oscar_init(struct prpl *ret) { |
3003 ret->protocol = PROTO_OSCAR; | 2684 ret->protocol = PROTO_OSCAR; |
3004 ret->options = OPT_PROTO_HTML | OPT_PROTO_CORRECT_TIME; | 2685 ret->options = OPT_PROTO_HTML | OPT_PROTO_CORRECT_TIME; |
3009 ret->do_action = oscar_do_action; | 2690 ret->do_action = oscar_do_action; |
3010 ret->buddy_menu = oscar_buddy_menu; | 2691 ret->buddy_menu = oscar_buddy_menu; |
3011 ret->user_opts = oscar_user_opts; | 2692 ret->user_opts = oscar_user_opts; |
3012 ret->draw_new_user = oscar_draw_new_user; | 2693 ret->draw_new_user = oscar_draw_new_user; |
3013 ret->do_new_user = oscar_do_new_user; | 2694 ret->do_new_user = oscar_do_new_user; |
3014 ret->insert_convo = oscar_insert_convo; | |
3015 ret->remove_convo = oscar_remove_convo; | |
3016 ret->login = oscar_login; | 2695 ret->login = oscar_login; |
3017 ret->close = oscar_close; | 2696 ret->close = oscar_close; |
3018 ret->send_im = oscar_send_im; | 2697 ret->send_im = oscar_send_im; |
3019 ret->set_info = oscar_set_info; | 2698 ret->set_info = oscar_set_info; |
3020 ret->get_info = oscar_get_info; | 2699 ret->get_info = oscar_get_info; |