Mercurial > pidgin
comparison src/protocols/jabber/jabber.c @ 3340:f56b36347375
[gaim-migrate @ 3359]
Added support for Jabber invisibility.
committer: Tailor Script <tailor@pidgin.im>
author | Jim Seymour <jseymour> |
---|---|
date | Sat, 29 Jun 2002 12:13:25 +0000 |
parents | e77fcff466a1 |
children | 000546860da7 |
comparison
equal
deleted
inserted
replaced
3339:afa68a8feee2 | 3340:f56b36347375 |
---|---|
141 gboolean die; | 141 gboolean die; |
142 GHashTable *buddies; | 142 GHashTable *buddies; |
143 }; | 143 }; |
144 | 144 |
145 /* | 145 /* |
146 * Used in jabber_buddy_data.invisible, below | |
147 */ | |
148 #define JABBER_NOT_INVIS 0x00 | |
149 #define JABBER_SERV_INVIS 0x01 /* Invisible set on server */ | |
150 #define JABBER_BUD_INVIS 0x02 /* Invisible set on buddy */ | |
151 | |
152 /* | |
146 * It is *this* to which we point the buddy proto_data | 153 * It is *this* to which we point the buddy proto_data |
147 */ | 154 */ |
148 struct jabber_buddy_data { | 155 struct jabber_buddy_data { |
149 GSList *resources; | 156 GSList *resources; |
150 char *error_msg; | 157 char *error_msg; |
158 unsigned invisible; /* We've set presence type invisible for this buddy */ | |
151 }; | 159 }; |
152 | 160 |
153 /* | 161 /* |
154 * per-resource info | 162 * per-resource info |
155 */ | 163 */ |
971 gjab_send(gjc, x); | 979 gjab_send(gjc, x); |
972 xmlnode_free(x); | 980 xmlnode_free(x); |
973 } | 981 } |
974 } | 982 } |
975 | 983 |
984 /* | |
985 * Return pointer to jabber_buddy_data if buddy found. Create if necessary. | |
986 */ | |
976 static struct jabber_buddy_data* jabber_find_buddy(struct gaim_connection *gc, char *buddy) | 987 static struct jabber_buddy_data* jabber_find_buddy(struct gaim_connection *gc, char *buddy) |
977 { | 988 { |
978 struct jabber_data *jd = gc->proto_data; | 989 struct jabber_data *jd = gc->proto_data; |
979 gpointer val; | 990 gpointer val; |
980 char *realwho; | 991 char *realwho; |
989 | 1000 |
990 } else { | 1001 } else { |
991 struct jabber_buddy_data *jbd = g_new0(struct jabber_buddy_data, 1); | 1002 struct jabber_buddy_data *jbd = g_new0(struct jabber_buddy_data, 1); |
992 jbd->error_msg = NULL; | 1003 jbd->error_msg = NULL; |
993 jbd->resources = NULL; | 1004 jbd->resources = NULL; |
1005 jbd->invisible = JABBER_NOT_INVIS; | |
994 g_hash_table_insert(jd->buddies, g_strdup(realwho), jbd); | 1006 g_hash_table_insert(jd->buddies, g_strdup(realwho), jbd); |
995 g_free(realwho); | 1007 g_free(realwho); |
996 return jbd; | 1008 return jbd; |
997 } | 1009 } |
998 } | 1010 } |
2394 /* | 2406 /* |
2395 * Remove a buddy item from the roster entirely | 2407 * Remove a buddy item from the roster entirely |
2396 */ | 2408 */ |
2397 static void jabber_remove_buddy_roster_item(struct gaim_connection *gc, char *name) | 2409 static void jabber_remove_buddy_roster_item(struct gaim_connection *gc, char *name) |
2398 { | 2410 { |
2399 xmlnode x, y; | 2411 gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc; |
2400 char *realwho; | 2412 char *realwho; |
2413 | |
2414 if((realwho = get_realwho(gjc, name, FALSE, NULL)) != NULL) { | |
2415 xmlnode x = jutil_iqnew(JPACKET__SET, NS_ROSTER); | |
2416 xmlnode y = xmlnode_insert_tag(xmlnode_get_tag(x, "query"), "item"); | |
2417 xmlnode_put_attrib(y, "jid", realwho); | |
2418 xmlnode_put_attrib(y, "subscription", "remove"); | |
2419 gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x); | |
2420 g_free(realwho); | |
2421 xmlnode_free(x); | |
2422 } | |
2423 } | |
2424 | |
2425 /* | |
2426 * Unsubscribe a buddy from our presence | |
2427 */ | |
2428 static void jabber_unsubscribe_buddy_from_us(struct gaim_connection *gc, char *name) | |
2429 { | |
2401 gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc; | 2430 gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc; |
2402 | 2431 char *realwho; |
2403 if(!name || (realwho = get_realwho(gjc, name, FALSE, NULL)) == NULL) | 2432 |
2404 return; | 2433 if((realwho = get_realwho(gjc, name, FALSE, NULL)) != NULL) { |
2405 | 2434 xmlnode g = xmlnode_new_tag("presence"); |
2406 x = jutil_iqnew(JPACKET__SET, NS_ROSTER); | 2435 xmlnode_put_attrib(g, "to", realwho); |
2407 y = xmlnode_insert_tag(xmlnode_get_tag(x, "query"), "item"); | 2436 xmlnode_put_attrib(g, "type", "unsubscribed"); |
2408 xmlnode_put_attrib(y, "jid", realwho); | 2437 gjab_send(gjc, g); |
2409 xmlnode_put_attrib(y, "subscription", "remove"); | 2438 xmlnode_free(g); |
2410 gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x); | 2439 } |
2411 g_free(realwho); | 2440 } |
2412 xmlnode_free(x); | 2441 |
2442 /* | |
2443 * Common code for setting ourselves invisible/visible to buddy | |
2444 */ | |
2445 static void jabber_invisible_to_buddy_common(struct gaim_connection *gc, char *name, gboolean invisible) | |
2446 { | |
2447 gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc; | |
2448 char *realwho; | |
2449 | |
2450 if((realwho = get_realwho(gjc, name, FALSE, NULL)) != NULL) { | |
2451 struct jabber_buddy_data *jbd = jabber_find_buddy(gc, realwho); | |
2452 xmlnode g = xmlnode_new_tag("presence"); | |
2453 | |
2454 xmlnode_put_attrib(g, "to", realwho); | |
2455 | |
2456 if(invisible) | |
2457 xmlnode_put_attrib(g, "type", "invisible"); | |
2458 | |
2459 gjab_send(gjc, g); | |
2460 | |
2461 g_free(realwho); | |
2462 xmlnode_free(g); | |
2463 | |
2464 if(jbd) { | |
2465 if(invisible) { | |
2466 jbd->invisible |= JABBER_BUD_INVIS; | |
2467 } else { | |
2468 jbd->invisible &= ~JABBER_BUD_INVIS; | |
2469 } | |
2470 } | |
2471 } | |
2472 } | |
2473 | |
2474 /* | |
2475 * Make ourselves temporarily invisible to a buddy | |
2476 */ | |
2477 static void jabber_invisible_to_buddy(struct gaim_connection *gc, char *name) | |
2478 { | |
2479 jabber_invisible_to_buddy_common(gc, name, TRUE); | |
2480 } | |
2481 | |
2482 /* | |
2483 * Make ourselves visible to a buddy | |
2484 */ | |
2485 static void jabber_visible_to_buddy(struct gaim_connection *gc, char *name) | |
2486 { | |
2487 jabber_invisible_to_buddy_common(gc, name, FALSE); | |
2488 } | |
2489 | |
2490 /* | |
2491 * Function used by the g_hash_table_foreach() in invisible_to_all_buddies() to | |
2492 * actually set the status. | |
2493 * | |
2494 * key is unused | |
2495 * value is the pointer to the jabber_buddy_data struct | |
2496 * data is gboolean: TRUE (invisible) or FALSE (not invisible) | |
2497 */ | |
2498 static void set_invisible_to_buddy_status(gpointer key, gpointer val, gpointer data) { | |
2499 struct jabber_buddy_data *jbd = val; | |
2500 gboolean invisible = (gboolean) data; | |
2501 | |
2502 if(jbd) { | |
2503 if(invisible) { | |
2504 jbd->invisible = JABBER_SERV_INVIS | JABBER_BUD_INVIS; | |
2505 } else { | |
2506 /* | |
2507 * If we've asserted server-level invisibility, cancelling | |
2508 * it removes explicit buddy invisibility settings too. | |
2509 */ | |
2510 if(jbd->invisible & JABBER_SERV_INVIS) | |
2511 jbd->invisible = JABBER_NOT_INVIS; | |
2512 } | |
2513 } | |
2514 } | |
2515 | |
2516 /* | |
2517 * Show we've set ourselves invisible/visible to all buddies on the server | |
2518 * | |
2519 * Used when we set server-wide invisibility so that individual buddy menu | |
2520 * entries show the proper option. | |
2521 */ | |
2522 static void invisible_to_all_buddies(struct gaim_connection *gc, gboolean invisible) | |
2523 { | |
2524 struct jabber_data *jd = gc->proto_data; | |
2525 | |
2526 if(jd->buddies != NULL) | |
2527 g_hash_table_foreach(jd->buddies, set_invisible_to_buddy_status, (gpointer) invisible); | |
2413 } | 2528 } |
2414 | 2529 |
2415 static char **jabber_list_icon(int uc) | 2530 static char **jabber_list_icon(int uc) |
2416 { | 2531 { |
2417 switch (uc) { | 2532 switch (uc) { |
2865 pbm->label = _("View Error Msg"); | 2980 pbm->label = _("View Error Msg"); |
2866 pbm->callback = jabber_get_error_msg; | 2981 pbm->callback = jabber_get_error_msg; |
2867 pbm->gc = gc; | 2982 pbm->gc = gc; |
2868 m = g_list_append(m, pbm); | 2983 m = g_list_append(m, pbm); |
2869 } else { | 2984 } else { |
2985 gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc; | |
2986 char *realwho = get_realwho(gjc, who, FALSE, NULL); | |
2987 struct jabber_buddy_data *jbd = jabber_find_buddy(gc, realwho); | |
2988 | |
2989 g_free(realwho); | |
2990 | |
2870 pbm = g_new0(struct proto_buddy_menu, 1); | 2991 pbm = g_new0(struct proto_buddy_menu, 1); |
2871 pbm->label = _("Get Info"); | 2992 pbm->label = _("Get Info"); |
2872 pbm->callback = jabber_get_info; | 2993 pbm->callback = jabber_get_info; |
2873 pbm->gc = gc; | 2994 pbm->gc = gc; |
2874 m = g_list_append(m, pbm); | 2995 m = g_list_append(m, pbm); |
2875 pbm = g_new0(struct proto_buddy_menu, 1); | 2996 pbm = g_new0(struct proto_buddy_menu, 1); |
2876 pbm->label = _("Get Away Msg"); | 2997 pbm->label = _("Get Away Msg"); |
2877 pbm->callback = jabber_get_away_msg; | 2998 pbm->callback = jabber_get_away_msg; |
2878 pbm->gc = gc; | 2999 pbm->gc = gc; |
2879 m = g_list_append(m, pbm); | 3000 m = g_list_append(m, pbm); |
3001 | |
3002 pbm = g_new0(struct proto_buddy_menu, 1); | |
3003 if(jbd && (jbd->invisible & JABBER_BUD_INVIS)) { | |
3004 pbm->label = _("Un-hide From"); | |
3005 pbm->callback = jabber_visible_to_buddy; | |
3006 } else { | |
3007 pbm->label = _("Temporarily Hide From"); | |
3008 pbm->callback = jabber_invisible_to_buddy; | |
3009 } | |
3010 pbm->gc = gc; | |
3011 m = g_list_append(m, pbm); | |
2880 } | 3012 } |
2881 | 3013 |
2882 return m; | 3014 return m; |
2883 } | 3015 } |
2884 | 3016 |
2892 pbm = g_new0(struct proto_buddy_menu, 1); | 3024 pbm = g_new0(struct proto_buddy_menu, 1); |
2893 pbm->label = _("Remove From Roster"); | 3025 pbm->label = _("Remove From Roster"); |
2894 pbm->callback = jabber_remove_buddy_roster_item; | 3026 pbm->callback = jabber_remove_buddy_roster_item; |
2895 pbm->gc = gc; | 3027 pbm->gc = gc; |
2896 m = g_list_append(m, pbm); | 3028 m = g_list_append(m, pbm); |
3029 pbm = g_new0(struct proto_buddy_menu, 1); | |
3030 pbm->label = _("Cancel Presence Notification"); | |
3031 pbm->callback = jabber_unsubscribe_buddy_from_us; | |
3032 pbm->gc = gc; | |
3033 m = g_list_append(m, pbm); | |
2897 | 3034 |
2898 return m; | 3035 return m; |
2899 } | 3036 } |
2900 | 3037 |
2901 static GList *jabber_away_states(struct gaim_connection *gc) { | 3038 static GList *jabber_away_states(struct gaim_connection *gc) { |
2904 m = g_list_append(m, "Online"); | 3041 m = g_list_append(m, "Online"); |
2905 m = g_list_append(m, "Chatty"); | 3042 m = g_list_append(m, "Chatty"); |
2906 m = g_list_append(m, "Away"); | 3043 m = g_list_append(m, "Away"); |
2907 m = g_list_append(m, "Extended Away"); | 3044 m = g_list_append(m, "Extended Away"); |
2908 m = g_list_append(m, "Do Not Disturb"); | 3045 m = g_list_append(m, "Do Not Disturb"); |
3046 m = g_list_append(m, "Invisible"); | |
2909 | 3047 |
2910 return m; | 3048 return m; |
2911 } | 3049 } |
2912 | 3050 |
2913 static void jabber_set_away(struct gaim_connection *gc, char *state, char *message) | 3051 static void jabber_set_away(struct gaim_connection *gc, char *state, char *message) |
2916 struct jabber_data *jd = gc->proto_data; | 3054 struct jabber_data *jd = gc->proto_data; |
2917 gjconn gjc = jd->gjc; | 3055 gjconn gjc = jd->gjc; |
2918 GSList *jcs; | 3056 GSList *jcs; |
2919 struct jabber_chat *jc; | 3057 struct jabber_chat *jc; |
2920 char *chatname; | 3058 char *chatname; |
3059 gboolean invisible = FALSE; | |
2921 | 3060 |
2922 gc->away = NULL; /* never send an auto-response */ | 3061 gc->away = NULL; /* never send an auto-response */ |
2923 | 3062 |
2924 x = xmlnode_new_tag("presence"); | 3063 x = xmlnode_new_tag("presence"); |
2925 | 3064 |
2953 gc->away = ""; | 3092 gc->away = ""; |
2954 } else if (!strcmp(state, "Do Not Disturb")) { | 3093 } else if (!strcmp(state, "Do Not Disturb")) { |
2955 y = xmlnode_insert_tag(x, "show"); | 3094 y = xmlnode_insert_tag(x, "show"); |
2956 xmlnode_insert_cdata(y, "dnd", -1); | 3095 xmlnode_insert_cdata(y, "dnd", -1); |
2957 gc->away = ""; | 3096 gc->away = ""; |
3097 } else if (!strcmp(state, "Invisible")) { | |
3098 xmlnode_put_attrib(x, "type", "invisible"); | |
3099 gc->away = ""; | |
3100 invisible = TRUE; | |
2958 } | 3101 } |
2959 } | 3102 } |
2960 | 3103 |
2961 gjab_send(gjc, x); /* Notify "individuals" */ | 3104 gjab_send(gjc, x); /* Notify "individuals" */ |
2962 | 3105 |
2975 g_free(chatname); | 3118 g_free(chatname); |
2976 } | 3119 } |
2977 } | 3120 } |
2978 | 3121 |
2979 xmlnode_free(x); | 3122 xmlnode_free(x); |
3123 | |
3124 invisible_to_all_buddies(gc, invisible); | |
2980 } | 3125 } |
2981 | 3126 |
2982 static void jabber_set_idle(struct gaim_connection *gc, int idle) { | 3127 static void jabber_set_idle(struct gaim_connection *gc, int idle) { |
2983 struct jabber_data *jd = (struct jabber_data *)gc->proto_data; | 3128 struct jabber_data *jd = (struct jabber_data *)gc->proto_data; |
2984 debug_printf("jabber_set_idle: setting idle %i\n", idle); | 3129 debug_printf("jabber_set_idle: setting idle %i\n", idle); |