Пример #1
0
Файл: main.c Проект: bgee/twilc
void move_next(WINDOW *win, struct status_node *current, int direction) {
    if(!current)
        return;

    struct status_node *next = 0;
    struct status_node *boundary = 0;
    if(direction > 0) {
        next = current->next;
        boundary = timelines[current_tl_index]->current_bottom;
    }
    else {
        next = current->prev;
        boundary = timelines[current_tl_index]->current_top;
    }
    if(!next) { // reached the bottom
        if(direction > 0)
            notify_state_change(states[STATE_REACHED_BOTTOM]);
        else
            notify_state_change(states[STATE_REACHED_TOP]);
        return;
    }

    if(current != boundary) {
        wmove(win,current->y_min,0);
        show_status(win,current);
    }
    else
        move_next_page(win,current,direction);

    highlight_status(win,next);
    timelines[current_tl_index]->current = next;
}
Пример #2
0
Файл: main.c Проект: bgee/twilc
int compose_new_tweet(WINDOW *win,status *in_reply_to, int if_reply_to_all) {
    memset(newtext,'\0',(1+TWEET_MAX_LEN)*sizeof(wchar_t));
    if(in_reply_to) {
        if(in_reply_to->retweeted_status)
            in_reply_to = in_reply_to->retweeted_status;
        wchar_t *ptr = newtext;
        *ptr ++ = '@';
        mbstowcs(ptr,in_reply_to->composer->screen_name,strlen(in_reply_to->composer->screen_name));
        ptr += wcslen(ptr);
        *ptr ++ = ' ';
        if(if_reply_to_all) {
            wchar_t wscreenname[ID_MAX_LEN+2];
            wscreenname[0] = '@';
            mbstowcs(wscreenname+1,me->screen_name,ID_MAX_LEN+1);
            for(entity *et = in_reply_to->entities; et; et = et->next) {
                if(et->type == ENTITY_TYPE_MENTION && wcscmp(et->text,wscreenname)) {
                    wcscpy(ptr,et->text);
                    ptr += wcslen(ptr);
                    *ptr++ = ' ';
                }
            }
        }
    }
    int count = input_new_tweet(win);
    if(count > 0) {
        char text[TWEET_MAX_LEN * 4];
        char *in_reply_to_status_id = NULL;
        if(in_reply_to)
            in_reply_to_status_id = in_reply_to->id;
        wcstombs(text,newtext,TWEET_MAX_LEN * 4);
        if(count <=140)
            notify_state_change("Sending......");
        else
            notify_state_change("Longer than 140. Will be truncated.");
        update_status(text,in_reply_to_status_id);
        notify_state_change("Successfully updated.");
    }
    else
        notify_state_change("");
    return 0;
}
Пример #3
0
void JoinPBX::bridge(void)
{
	struct join_relation *relation;
	struct lcr_msg *message;
	int numconnect = 0, relations = 0;
	class Endpoint *epoint;
	struct port_list *portlist;
	class Port *port;
	unsigned int bridge_id;
	class Join *join_3pty;
	class JoinPBX *joinpbx_3pty;
#ifdef DEBUG_COREBRIDGE
	int allmISDN = 0; // never set for debug purpose
#else
	int allmISDN = 1; // set until a non-mISDN relation is found
#endif

	/* bridge id is the serial of join
	 * if we have a 3pty with another join, we always use the lowest brigde id.
	 * this way we use common ids, so both joins share same bridge */
	if (j_3pty && j_3pty < j_serial)
		bridge_id = j_3pty;
	else
		bridge_id = j_serial;

	relation = j_relation;
	while(relation) {
		/* count all relations */
		relations++;

		/* check for relation's objects */
		epoint = find_epoint_id(relation->epoint_id);
		if (!epoint) {
			PERROR("software error: relation without existing endpoints.\n");
			relation = relation->next;
			continue;
		}
		portlist = epoint->ep_portlist;
		if (!portlist) {
			PDEBUG(DEBUG_JOIN, "join%d ignoring relation without port object.\n", j_serial);
//#warning testing: keep on hold until single audio stream available
			relation->channel_state = 0;
			relation = relation->next;
			continue;
		}
		if (portlist->next) {
			PDEBUG(DEBUG_JOIN, "join%d ignoring relation with ep%d due to port_list.\n", j_serial, epoint->ep_serial);
//#warning testing: keep on hold until single audio stream available
			relation->channel_state = 0;
			relation = relation->next;
			continue;
		}
		port = find_port_id(portlist->port_id);
		if (!port) {
			PDEBUG(DEBUG_JOIN, "join%d ignoring relation without existing port object.\n", j_serial);
			relation = relation->next;
			continue;
		}
		if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN) {
			PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port is not mISDN.\n", j_serial, epoint->ep_serial);
			if (allmISDN) {
				PDEBUG(DEBUG_JOIN, "join%d not all endpoints are mISDN.\n", j_serial);
				allmISDN = 0;
			}
			relation = relation->next;
			continue;
		}

		relation = relation->next;
	}

	/* check if 3pty members have no mISDN, so bridging via mISDN/lcr will be selected correctly */
	join_3pty = find_join_id(j_3pty);
	if (join_3pty && join_3pty->j_type == JOIN_TYPE_PBX) {
		joinpbx_3pty = (class JoinPBX *)join_3pty;
		relation = joinpbx_3pty->j_relation;
		while(relation) {

#if 0
no need to count, because j_3pty is taken into account below when checking relations
			/* count all relations */
			relations++;
#endif

			/* check for relation's objects */
			epoint = find_epoint_id(relation->epoint_id);
			if (!epoint) {
				PERROR("software error: relation without existing endpoints.\n");
				relation = relation->next;
				continue;
			}
			portlist = epoint->ep_portlist;
			if (!portlist) {
				PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation without port object.\n", joinpbx_3pty->j_serial);
//#warning testing: keep on hold until single audio stream available
				relation->channel_state = 0;
				relation = relation->next;
				continue;
			}
			if (portlist->next) {
				PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation with ep%d due to port_list.\n", joinpbx_3pty->j_serial, epoint->ep_serial);
//#warning testing: keep on hold until single audio stream available
				relation->channel_state = 0;
				relation = relation->next;
				continue;
			}
			port = find_port_id(portlist->port_id);
			if (!port) {
				PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation without existing port object.\n", joinpbx_3pty->j_serial);
				relation = relation->next;
				continue;
			}
			if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN) {
				PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation ep%d because it's port is not mISDN.\n", joinpbx_3pty->j_serial, epoint->ep_serial);
				if (allmISDN) {
					PDEBUG(DEBUG_JOIN, "other 3pty join %d: not all endpoints are mISDN.\n", joinpbx_3pty->j_serial);
					allmISDN = 0;
				}
				relation = relation->next;
				continue;
			}

			relation = relation->next;
		}
	}

	PDEBUG(DEBUG_JOIN, "join%d members=%d %s\n", j_serial, relations, (allmISDN)?"(all are mISDN-members)":"(not all are mISDN-members)");
	/* we notify all relations about rxdata. */
	relation = j_relation;
	while(relation) {
		/* count connected relations */
		if ((relation->channel_state == 1)
		 && (relation->rx_state != NOTIFY_STATE_SUSPEND)
		 && (relation->rx_state != NOTIFY_STATE_HOLD))
			numconnect ++;

		/* remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed. */

		/* mISDN */
		if (relation->channel_state == 1
		 && relation->rx_state != NOTIFY_STATE_HOLD
		 && relation->rx_state != NOTIFY_STATE_SUSPEND
		 && relations>1 // no conf with one member
		 && allmISDN) { // no conf if any member is not mISDN
			message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
			message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
			message->param.mISDNsignal.conf = (bridge_id << 16) | j_pid;
			PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf);
			message_put(message);
		} else {
			message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
			message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
			message->param.mISDNsignal.conf = 0;
			PDEBUG(DEBUG_JOIN, "join%d EP%d +off+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf);
			message_put(message);
		}

		/* core bridge */
		if (relation->channel_state == 1
		 && relation->rx_state != NOTIFY_STATE_HOLD
		 && relation->rx_state != NOTIFY_STATE_SUSPEND
		 && relations>1 // no bridge with one member
		 && !allmISDN) { // no bridge if all members are mISDN
			message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE);
			message->param.bridge_id = bridge_id;
			PDEBUG(DEBUG_JOIN, "join%u EP%u requests bridge=%u\n", j_serial, relation->epoint_id, bridge_id);
			message_put(message);
		} else {
			message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE);
			message->param.bridge_id = 0;
			PDEBUG(DEBUG_JOIN, "join%u EP%u drop bridge=%u\n", j_serial, relation->epoint_id, bridge_id);
			message_put(message);
		}

		relation = relation->next;
	}

	/* two people just exchange their states */
	if (!j_3pty && relations==2 && !j_partyline) {
		PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", j_serial);
		relation = j_relation;
		relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state);
		relation->next->tx_state = notify_state_change(j_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state);
	} else
	/* one member in a join, so we put her on hold */
	if (!j_3pty && (relations==1 || numconnect==1)/* && !j_partyline_jingle*/) {
		PDEBUG(DEBUG_JOIN, "join%d 1 member or only 1 connected, put on hold\n", j_serial);
		relation = j_relation;
		while(relation) {
			if ((relation->channel_state == 1)
			 && (relation->rx_state != NOTIFY_STATE_SUSPEND)
			 && (relation->rx_state != NOTIFY_STATE_HOLD))
				relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_HOLD);
			relation = relation->next;
		}
	} else {
	/* if conference/partyline (or more than two members and more than one is connected), so we set conference state */ 
		PDEBUG(DEBUG_JOIN, "join%d %d members, %d connected, signal conference\n", j_serial, relations, numconnect);
		relation = j_relation;
		while(relation) {
			if ((relation->channel_state == 1)
			 && (relation->rx_state != NOTIFY_STATE_SUSPEND)
			 && (relation->rx_state != NOTIFY_STATE_HOLD))
				relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_CONFERENCE);
			relation = relation->next;
		}
	}
}
Пример #4
0
Файл: main.c Проект: bgee/twilc
/**
 * Commands:
 * a --
 * b --
 * c -- conversation
 * d -- delete a tweet
 * e --
 * f -- fav/unfav a tweet
 * g --
 * h --
 * i --
 * j -- move down one tweet
 * J -- move down one page
 * k -- move up one tweet
 * K -- move up one page
 * l -- list
 * m -- direct message
 * n -- compose a new tweet
 * o --
 * p --
 * q -- quit
 * r -- reply
 * R -- reply to all
 * s -- search
 * t -- retweet
 * u --
 * v -- move to the last viewed tweet
 * w --
 * x --
 * y --
 * z --
 * ? -- show shortcuts help
 * . -- refresh
 */
void wait_command(WINDOW *win) {
    char ch = '\0';
    while((ch = getch()) != 'q') {
        switch(ch) {
        case 'n':
            // Compose new tweet
            notify_state_change(states[STATE_NORMAL]);
            compose_new_tweet(win,NULL,0);
            return_to_current_timeline(win);
            break;
        case 'J':
            // move down one page
            notify_state_change(states[STATE_NORMAL]);
            if(move_next_page(win,timelines[current_tl_index]->current_bottom,1) != -1) {
                timelines[current_tl_index]->current = timelines[current_tl_index]->current_top;
                highlight_status(win, timelines[current_tl_index]->current);
            }
            else
                notify_error_state();
            break;
        case 'K':
            // move up one page
            notify_state_change(states[STATE_NORMAL]);
            if(move_next_page(win,timelines[current_tl_index]->current_top,-1)!= -1) {
                timelines[current_tl_index]->current = timelines[current_tl_index]->current_top;
                highlight_status(win, timelines[current_tl_index]->current);
            }
            else
                notify_error_state();
            break;
        case 'j':
            // move down one tweet
            notify_state_change(states[STATE_NORMAL]);
            move_next(win, timelines[current_tl_index]->current,1);
            break;
        case 'k':
            // move up one tweet
            notify_state_change(states[STATE_NORMAL]);
            move_next(win, timelines[current_tl_index]->current,-1);
            break;
        case '.':
            // refresh the current timeline
            /*
            notify_state_change(states[STATE_RETRIEVING_UPDATES]);
            struct status_node *to_status = timelines[current_tl_index]->head;
            int res = update_timeline(current_tl_index,NULL,to_status);
            if(res >= 0){
                char *state_str = malloc(20*sizeof(char));
                memset(state_str,'\0',20);
                if(res == 0)
                    sprintf(state_str,"%s","No updates.");
                else if(res == 1)
                    sprintf(state_str,"%d new tweet.",res);
                else
                    sprintf(state_str,"%d new tweets.",res);
                notify_state_change(state_str);
                free(state_str);
            }
            else
                notify_error_state();
            */
            merge_timeline_updates(current_tl_index);

            timelines[current_tl_index]->last_viewed = timelines[current_tl_index]->current;
            move_top(win);
            notify_timeline_updates(current_tl_index,0);
            break;
        case 'v':
            notify_state_change(states[STATE_NORMAL]);
            if(timelines[current_tl_index]->last_viewed) {
                int y,x;
                struct status_node *last_viewed = timelines[current_tl_index]->last_viewed;
                getmaxyx(win,y,x);
                timelines[current_tl_index]->current = last_viewed;
                timelines[current_tl_index]->current_top = last_viewed;
                timelines[current_tl_index]->current_bottom = show_timeline(win,last_viewed,y,x);
                highlight_status(win,last_viewed);
            }
            else
                notify_state_change(states[STATE_NO_LAST_VIEWED]);
            break;
        case 'r':
            compose_new_tweet(win,timelines[current_tl_index]->current->st,0);
            return_to_current_timeline(win);
            break;
        case 'R':
            compose_new_tweet(win,timelines[current_tl_index]->current->st,1);
            return_to_current_timeline(win);
            break;
        case 't':
            if(timelines[current_tl_index]->current->st) {
                status *st = timelines[current_tl_index]->current->st;
                if(st->retweeted_status)
                    st = st->retweeted_status;
                if(IS_PROTECTED(st->composer->extra_info))
                    notify_state_change("This user is protected. Cannot retweet.");
                else
                    retweet_status(st->id);
            }
            break;
        }
    }
}