changeset 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 e6c7d67c1f3a
children 0b64f386a7b8
files src/protocols/oscar/aim.h src/protocols/oscar/ft.c src/protocols/oscar/icon.c src/protocols/oscar/info.c src/protocols/oscar/oscar.c
diffstat 5 files changed, 64 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/oscar/aim.h	Sat Mar 22 23:28:49 2003 +0000
+++ b/src/protocols/oscar/aim.h	Sun Mar 23 07:38:55 2003 +0000
@@ -1004,7 +1004,7 @@
 faim_export fu32_t aim_oft_checksum_file(char *filename);
 faim_export int aim_handlerendconnect(aim_session_t *sess, aim_conn_t *cur);
 faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing);
-faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding);
+faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg);
 faim_export const char *aim_odc_getsn(aim_conn_t *conn);
 faim_export aim_conn_t *aim_odc_getconn(aim_session_t *sess, const char *sn);
 faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn);
--- a/src/protocols/oscar/ft.c	Sat Mar 22 23:28:49 2003 +0000
+++ b/src/protocols/oscar/ft.c	Sun Mar 23 07:38:55 2003 +0000
@@ -306,7 +306,8 @@
  *
  * @param sess The session.
  * @param conn The already-connected ODC connection.
- * @param typing If true, notify user has started typing; if false, notify user has stopped.
+ * @param typing If 0x0002, sends a "typing" message, 0x0001 sends "typed," and 
+ *        0x0000 sends "stopped."
  * @return Return 0 if no errors, otherwise return the error number.
  */
 faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing)
@@ -320,7 +321,7 @@
 	if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS))
 		return -EINVAL;
 
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, 0)))
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0001, 0)))
 		return -ENOMEM;
 	memcpy(fr->hdr.rend.magic, "ODC2", 4);
 	fr->hdr.rend.hdrlen = hdrlen;
@@ -345,8 +346,12 @@
 	aimbs_put16(hdrbs, 0x0000);
 	aimbs_put16(hdrbs, 0x0000);
 
-	/* flags -- 0x000e for "started typing", 0x0002 for "stopped typing */
-	aimbs_put16(hdrbs, ( typing ? 0x000e : 0x0002));
+	if (typing == 0x0002)
+		aimbs_put16(hdrbs, 0x0002 | 0x0008);
+	else if (typing == 0x0001)
+		aimbs_put16(hdrbs, 0x0002 | 0x0004);
+	else
+		aimbs_put16(hdrbs, 0x0002);
 
 	aimbs_put16(hdrbs, 0x0000);
 	aimbs_put16(hdrbs, 0x0000);
@@ -380,9 +385,10 @@
  * @param msg Null-terminated string to send.
  * @param len The length of the message to send, including binary data.
  * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1.
+ * @param isawaymsg 0 if this is not an auto-response, 1 if it is.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding)
+faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg)
 {
 	aim_frame_t *fr;
 	aim_bstream_t *hdrbs;
@@ -419,8 +425,8 @@
 	aimbs_put16(hdrbs, 0x0000);
 	aimbs_put16(hdrbs, 0x0000);
 
-	/* flags -- 0x000e for "started typing", 0x0002 for "stopped typing, 0x0000 for message */
-	aimbs_put16(hdrbs, 0x0000);
+	/* flags - used for typing notification and to mark if this is an away message */
+	aimbs_put16(hdrbs, 0x0000 | isawaymsg);
 
 	aimbs_put16(hdrbs, 0x0000);
 	aimbs_put16(hdrbs, 0x0000);
@@ -624,6 +630,7 @@
 static int handlehdr_odc(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *frr, aim_bstream_t *bs)
 {
 	aim_frame_t fr;
+	int ret = 0;
 	aim_rxcallback_t userfunc;
 	fu32_t payloadlength;
 	fu16_t flags, encoding;
@@ -647,54 +654,48 @@
 
 	faimdprintf(sess, 2, "faim: OFT frame: handlehdr_odc: %04x / %04x / %s\n", payloadlength, flags, snptr);
 
-	if (flags & 0x0002) {
-		int ret = 0;
-
-		if (flags & 0x000c) {
-			if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
-				ret = userfunc(sess, &fr, snptr, 1);
-			return ret;
-		}
-
+	if (flags & 0x0008) {
+		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
+			ret = userfunc(sess, &fr, snptr, 2);
+	} else if (flags & 0x0004) {
+		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
+			ret = userfunc(sess, &fr, snptr, 1);
+	} else {
 		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
 			ret = userfunc(sess, &fr, snptr, 0);
-
-		return ret;
+	}
 
-	} else if (((flags & 0x000f) == 0x0000) && payloadlength) {
-		char *msg, *msg2;
-		int ret = 0;
+	if (payloadlength) {
+		char *msg;
 		int recvd = 0;
-		int i;
+		int i, isawaymsg;
+
+		isawaymsg = flags & 0x0001;
 
 		if (!(msg = calloc(1, payloadlength+1)))
-			return -1;
-		msg2 = msg;
-		
+			return -ENOMEM;
+
 		while (payloadlength - recvd) {
 			if (payloadlength - recvd >= 1024)
-				i = aim_recv(conn->fd, msg2, 1024);
+				i = aim_recv(conn->fd, &msg[recvd], 1024);
 			else 
-				i = aim_recv(conn->fd, msg2, payloadlength - recvd);
+				i = aim_recv(conn->fd, &msg[recvd], payloadlength - recvd);
 			if (i <= 0) {
 				free(msg);
 				return -1;
 			}
 			recvd = recvd + i;
-			msg2 = msg2 + i;
 			if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER)))
-				userfunc(sess, &fr, snptr, (double)recvd / payloadlength);
+				ret = userfunc(sess, &fr, snptr, (double)recvd / payloadlength);
 		}
 		
-		if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)) )
-			ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding);
+		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)))
+			ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding, isawaymsg);
 
 		free(msg);
-
-		return ret;
 	}
 
-	return 0;
+	return ret;
 }
 
 /**
--- a/src/protocols/oscar/icon.c	Sat Mar 22 23:28:49 2003 +0000
+++ b/src/protocols/oscar/icon.c	Sun Mar 23 07:38:55 2003 +0000
@@ -73,6 +73,7 @@
 	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
 		return userfunc(sess, rx, sn, iconcsum, iconcsumlen, icon, iconlen);
 
+	free(sn);
 	free(iconcsum);
 	free(icon);
 
--- a/src/protocols/oscar/info.c	Sat Mar 22 23:28:49 2003 +0000
+++ b/src/protocols/oscar/info.c	Sun Mar 23 07:38:55 2003 +0000
@@ -274,6 +274,9 @@
 	 {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 
 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
 
+	/*
+	 * Windows AIM calls this "Add-ins," which is probably more accurate
+	 */
 	{AIM_CAPS_SAVESTOCKS,
 	 {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1,
 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
--- a/src/protocols/oscar/oscar.c	Sat Mar 22 23:28:49 2003 +0000
+++ b/src/protocols/oscar/oscar.c	Sun Mar 23 07:38:55 2003 +0000
@@ -3390,6 +3390,7 @@
 		b16 = tobase16(iconcsum, iconcsumlen);
 		b = gaim_find_buddy(gc->account, sn);
 		gaim_buddy_set_setting(b, "icon_checksum", b16);
+		gaim_blist_save();
 		free(b16);
 	}
 
@@ -4081,7 +4082,12 @@
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 	struct direct_im *dim = find_direct_im(od, name);
 	if (dim)
-		aim_odc_send_typing(od->sess, dim->conn, typing);
+		if (typing == TYPING)
+			aim_odc_send_typing(od->sess, dim->conn, 0x0002);
+		else if (typing == TYPED)
+			aim_odc_send_typing(od->sess, dim->conn, 0x0001);
+		else
+			aim_odc_send_typing(od->sess, dim->conn, 0x0000);
 	else {
 		struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, normalize(name));
 		if (bi && bi->typingnot) {
@@ -4106,7 +4112,10 @@
 	if (dim && dim->connected) {
 		/* If we're directly connected, send a direct IM */
 		/* XXX - The last parameter below is the encoding.  Let Paco-Paco do something with it. */
-		ret =  aim_odc_send_im(od->sess, dim->conn, message, len == -1 ? strlen(message) : len, 0);
+		if (imflags & IM_FLAG_AWAY)
+			ret =  aim_odc_send_im(od->sess, dim->conn, message, len == -1 ? strlen(message) : len, 0, 1);
+		else
+			ret =  aim_odc_send_im(od->sess, dim->conn, message, len == -1 ? strlen(message) : len, 0, 0);
 	} else if (len != -1) {
 		/* Trying to send an IM image outside of a direct connection. */
 		oscar_ask_direct_im(gc, name);
@@ -5232,22 +5241,27 @@
 }
 
 static int gaim_odc_incoming(aim_session_t *sess, aim_frame_t *fr, ...) {
+	struct gaim_connection *gc = sess->aux_data;
+	int imflags = 0;
 	va_list ap;
-	char *msg, *sn;
-	int len, encoding;
-	struct gaim_connection *gc = sess->aux_data;
+	char *sn, *msg;
+	int len, encoding, isawaymsg;
 
 	va_start(ap, fr);
 	sn = va_arg(ap, char *);
 	msg = va_arg(ap, char *);
 	len = va_arg(ap, int);
 	encoding = va_arg(ap, int);
+	isawaymsg = va_arg(ap, int);
 	va_end(ap);
 
 	debug_printf("Got DirectIM message from %s\n", sn);
 
+	if (isawaymsg)
+		imflags |= IM_FLAG_AWAY;
+
 	/* XXX - I imagine Paco-Paco will want to do some voodoo with the encoding here */
-	serv_got_im(gc, sn, msg, 0, time(NULL), len);
+	serv_got_im(gc, sn, msg, imflags, time(NULL), len);
 
 	return 1;
 }
@@ -5263,11 +5277,13 @@
 	typing = va_arg(ap, int);
 	va_end(ap);
 
-	if (typing) {
+	if (typing == 0x0002) {
 		/* I had to leave this. It's just too funny. It reminds me of my sister. */
 		debug_printf("ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
 		serv_got_typing(gc, sn, 0, TYPING);
-	} else
+	} else if (typing == 0x0001)
+		serv_got_typing(gc, sn, 0, TYPED);
+	else
 		serv_got_typing_stopped(gc, sn);
 	return 1;
 }