Mercurial > pidgin.yaz
comparison src/protocols/oscar/ft.c @ 4870:773135edda4a
[gaim-migrate @ 5200]
Added 3-stage typing notification for oscar direct connect
(incoming and outgoing). Previously Gaim only had "typing"
and "no text entered." I added support for "text typed."
Made Gaim correctly recognize and send the auto-response
flag for direct connections. So messages will probably show
up as "AUTO-REPLY" for you and your amigo.
Have gaim save your blist after recieving someone's icon,
which is a bugfix from my code from last night, I think.
Fixed a memleak in icon.c thanks to Nathan Walp.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 23 Mar 2003 07:38:55 +0000 |
parents | edfe778868e2 |
children | 26837f462a66 |
comparison
equal
deleted
inserted
replaced
4869:e6c7d67c1f3a | 4870:773135edda4a |
---|---|
304 /** | 304 /** |
305 * Send client-to-client typing notification over an established direct connection. | 305 * Send client-to-client typing notification over an established direct connection. |
306 * | 306 * |
307 * @param sess The session. | 307 * @param sess The session. |
308 * @param conn The already-connected ODC connection. | 308 * @param conn The already-connected ODC connection. |
309 * @param typing If true, notify user has started typing; if false, notify user has stopped. | 309 * @param typing If 0x0002, sends a "typing" message, 0x0001 sends "typed," and |
310 * 0x0000 sends "stopped." | |
310 * @return Return 0 if no errors, otherwise return the error number. | 311 * @return Return 0 if no errors, otherwise return the error number. |
311 */ | 312 */ |
312 faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing) | 313 faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing) |
313 { | 314 { |
314 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal; | 315 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal; |
318 int hdrlen = 0x44; | 319 int hdrlen = 0x44; |
319 | 320 |
320 if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS)) | 321 if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS)) |
321 return -EINVAL; | 322 return -EINVAL; |
322 | 323 |
323 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, 0))) | 324 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0001, 0))) |
324 return -ENOMEM; | 325 return -ENOMEM; |
325 memcpy(fr->hdr.rend.magic, "ODC2", 4); | 326 memcpy(fr->hdr.rend.magic, "ODC2", 4); |
326 fr->hdr.rend.hdrlen = hdrlen; | 327 fr->hdr.rend.hdrlen = hdrlen; |
327 | 328 |
328 if (!(hdr = calloc(1, hdrlen))) { | 329 if (!(hdr = calloc(1, hdrlen))) { |
343 aimbs_put32(hdrbs, 0x00000000); | 344 aimbs_put32(hdrbs, 0x00000000); |
344 aimbs_put16(hdrbs, 0x0000); | 345 aimbs_put16(hdrbs, 0x0000); |
345 aimbs_put16(hdrbs, 0x0000); | 346 aimbs_put16(hdrbs, 0x0000); |
346 aimbs_put16(hdrbs, 0x0000); | 347 aimbs_put16(hdrbs, 0x0000); |
347 | 348 |
348 /* flags -- 0x000e for "started typing", 0x0002 for "stopped typing */ | 349 if (typing == 0x0002) |
349 aimbs_put16(hdrbs, ( typing ? 0x000e : 0x0002)); | 350 aimbs_put16(hdrbs, 0x0002 | 0x0008); |
351 else if (typing == 0x0001) | |
352 aimbs_put16(hdrbs, 0x0002 | 0x0004); | |
353 else | |
354 aimbs_put16(hdrbs, 0x0002); | |
350 | 355 |
351 aimbs_put16(hdrbs, 0x0000); | 356 aimbs_put16(hdrbs, 0x0000); |
352 aimbs_put16(hdrbs, 0x0000); | 357 aimbs_put16(hdrbs, 0x0000); |
353 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); | 358 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); |
354 | 359 |
378 * @param sess The session. | 383 * @param sess The session. |
379 * @param conn The already-connected ODC connection. | 384 * @param conn The already-connected ODC connection. |
380 * @param msg Null-terminated string to send. | 385 * @param msg Null-terminated string to send. |
381 * @param len The length of the message to send, including binary data. | 386 * @param len The length of the message to send, including binary data. |
382 * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1. | 387 * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1. |
388 * @param isawaymsg 0 if this is not an auto-response, 1 if it is. | |
383 * @return Return 0 if no errors, otherwise return the error number. | 389 * @return Return 0 if no errors, otherwise return the error number. |
384 */ | 390 */ |
385 faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding) | 391 faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg) |
386 { | 392 { |
387 aim_frame_t *fr; | 393 aim_frame_t *fr; |
388 aim_bstream_t *hdrbs; | 394 aim_bstream_t *hdrbs; |
389 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal; | 395 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal; |
390 int hdrlen = 0x44; | 396 int hdrlen = 0x44; |
417 aimbs_put32(hdrbs, len); | 423 aimbs_put32(hdrbs, len); |
418 aimbs_put16(hdrbs, encoding); | 424 aimbs_put16(hdrbs, encoding); |
419 aimbs_put16(hdrbs, 0x0000); | 425 aimbs_put16(hdrbs, 0x0000); |
420 aimbs_put16(hdrbs, 0x0000); | 426 aimbs_put16(hdrbs, 0x0000); |
421 | 427 |
422 /* flags -- 0x000e for "started typing", 0x0002 for "stopped typing, 0x0000 for message */ | 428 /* flags - used for typing notification and to mark if this is an away message */ |
423 aimbs_put16(hdrbs, 0x0000); | 429 aimbs_put16(hdrbs, 0x0000 | isawaymsg); |
424 | 430 |
425 aimbs_put16(hdrbs, 0x0000); | 431 aimbs_put16(hdrbs, 0x0000); |
426 aimbs_put16(hdrbs, 0x0000); | 432 aimbs_put16(hdrbs, 0x0000); |
427 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); | 433 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); |
428 | 434 |
622 * @return Return 0 if no errors, otherwise return the error number. | 628 * @return Return 0 if no errors, otherwise return the error number. |
623 */ | 629 */ |
624 static int handlehdr_odc(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *frr, aim_bstream_t *bs) | 630 static int handlehdr_odc(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *frr, aim_bstream_t *bs) |
625 { | 631 { |
626 aim_frame_t fr; | 632 aim_frame_t fr; |
633 int ret = 0; | |
627 aim_rxcallback_t userfunc; | 634 aim_rxcallback_t userfunc; |
628 fu32_t payloadlength; | 635 fu32_t payloadlength; |
629 fu16_t flags, encoding; | 636 fu16_t flags, encoding; |
630 char *snptr = NULL; | 637 char *snptr = NULL; |
631 | 638 |
645 /* XXX - create an aimbs_getnullstr function? */ | 652 /* XXX - create an aimbs_getnullstr function? */ |
646 snptr = aimbs_getstr(bs, MAXSNLEN); | 653 snptr = aimbs_getstr(bs, MAXSNLEN); |
647 | 654 |
648 faimdprintf(sess, 2, "faim: OFT frame: handlehdr_odc: %04x / %04x / %s\n", payloadlength, flags, snptr); | 655 faimdprintf(sess, 2, "faim: OFT frame: handlehdr_odc: %04x / %04x / %s\n", payloadlength, flags, snptr); |
649 | 656 |
650 if (flags & 0x0002) { | 657 if (flags & 0x0008) { |
651 int ret = 0; | 658 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) |
652 | 659 ret = userfunc(sess, &fr, snptr, 2); |
653 if (flags & 0x000c) { | 660 } else if (flags & 0x0004) { |
654 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) | 661 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) |
655 ret = userfunc(sess, &fr, snptr, 1); | 662 ret = userfunc(sess, &fr, snptr, 1); |
656 return ret; | 663 } else { |
657 } | |
658 | |
659 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) | 664 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) |
660 ret = userfunc(sess, &fr, snptr, 0); | 665 ret = userfunc(sess, &fr, snptr, 0); |
661 | 666 } |
662 return ret; | 667 |
663 | 668 if (payloadlength) { |
664 } else if (((flags & 0x000f) == 0x0000) && payloadlength) { | 669 char *msg; |
665 char *msg, *msg2; | |
666 int ret = 0; | |
667 int recvd = 0; | 670 int recvd = 0; |
668 int i; | 671 int i, isawaymsg; |
672 | |
673 isawaymsg = flags & 0x0001; | |
669 | 674 |
670 if (!(msg = calloc(1, payloadlength+1))) | 675 if (!(msg = calloc(1, payloadlength+1))) |
671 return -1; | 676 return -ENOMEM; |
672 msg2 = msg; | 677 |
673 | |
674 while (payloadlength - recvd) { | 678 while (payloadlength - recvd) { |
675 if (payloadlength - recvd >= 1024) | 679 if (payloadlength - recvd >= 1024) |
676 i = aim_recv(conn->fd, msg2, 1024); | 680 i = aim_recv(conn->fd, &msg[recvd], 1024); |
677 else | 681 else |
678 i = aim_recv(conn->fd, msg2, payloadlength - recvd); | 682 i = aim_recv(conn->fd, &msg[recvd], payloadlength - recvd); |
679 if (i <= 0) { | 683 if (i <= 0) { |
680 free(msg); | 684 free(msg); |
681 return -1; | 685 return -1; |
682 } | 686 } |
683 recvd = recvd + i; | 687 recvd = recvd + i; |
684 msg2 = msg2 + i; | |
685 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER))) | 688 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER))) |
686 userfunc(sess, &fr, snptr, (double)recvd / payloadlength); | 689 ret = userfunc(sess, &fr, snptr, (double)recvd / payloadlength); |
687 } | 690 } |
688 | 691 |
689 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)) ) | 692 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING))) |
690 ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding); | 693 ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding, isawaymsg); |
691 | 694 |
692 free(msg); | 695 free(msg); |
693 | 696 } |
694 return ret; | 697 |
695 } | 698 return ret; |
696 | |
697 return 0; | |
698 } | 699 } |
699 | 700 |
700 /** | 701 /** |
701 * Creates a listener socket so the other dude can connect to us. | 702 * Creates a listener socket so the other dude can connect to us. |
702 * | 703 * |