Exemplo n.º 1
0
void do_housekeeping(void) {
	int do_housekeeping_now = 0;
	int do_perminute_housekeeping_now = 0;
	time_t now;

	/*
	 * We do it this way instead of wrapping the whole loop in an
	 * S_HOUSEKEEPING critical section because it eliminates the need to
	 * potentially have multiple concurrent mutexes in progress.
	 */
	begin_critical_section(S_HOUSEKEEPING);
	if (housekeeping_in_progress == 0) {
		do_housekeeping_now = 1;
		housekeeping_in_progress = 1;
	}
	end_critical_section(S_HOUSEKEEPING);

	if (do_housekeeping_now == 0) {
		return;
	}

	/*
	 * Ok, at this point we've made the decision to run the housekeeping
	 * loop.  Everything below this point is real work.
	 */

	now = time(NULL);
	if ( (now - last_timer) > (time_t)60 ) {
		do_perminute_housekeeping_now = 1;
		last_timer = time(NULL);
	}

	/* First, do the "as often as needed" stuff... */
	JournalRunQueue();
	PerformSessionHooks(EVT_HOUSE);

	/* Then, do the "once per minute" stuff... */
	if (do_perminute_housekeeping_now) {
		cdb_check_handles();			/* suggested by Justin Case */
		PerformSessionHooks(EVT_TIMER);		/* Run any timer hooks */
	}

	/*
	 * All done.
	 */
	begin_critical_section(S_HOUSEKEEPING);
	housekeeping_in_progress = 0;
	end_critical_section(S_HOUSEKEEPING);
}
Exemplo n.º 2
0
int look_for_open_group_data(char *to) {
    int i,found;
    char temp1[MAX_CALLSIGN+1];
    char *temp_ptr;


begin_critical_section(&send_message_dialog_lock, "messages.c:look_for_open_group_data" );

    found = FALSE;
     for(i = 0; i < MAX_MESSAGE_WINDOWS; i++) {
        /* find station  */
        if(mw[i].send_message_dialog != NULL) {

            temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data);
            xastir_snprintf(temp1,
                sizeof(temp1),
                "%s",
                temp_ptr);
            XtFree(temp_ptr);

            (void)to_upper(temp1);
            /*fprintf(stderr,"Looking at call <%s> for <%s>\n",temp1,to);*/
            if(strcmp(temp1,to)==0) {
                found=(int)TRUE;
                break;
            }
        }
    }

end_critical_section(&send_message_dialog_lock, "messages.c:look_for_open_group_data" );

    return(found);
}
Exemplo n.º 3
0
/*
 * This function is called by the XMPP service's async loop.
 * If the client session has instant messages waiting, it outputs
 * unsolicited XML stanzas containing them.
 */
void xmpp_output_incoming_messages(void) {

	struct ExpressMessage *ptr;
	char xmlbuf1[4096];
	char xmlbuf2[4096];

	while (CC->FirstExpressMessage != NULL) {

		begin_critical_section(S_SESSION_TABLE);
		ptr = CC->FirstExpressMessage;
		CC->FirstExpressMessage = CC->FirstExpressMessage->next;
		end_critical_section(S_SESSION_TABLE);

		cprintf("<message to=\"%s\" from=\"%s\" type=\"chat\">",
			xmlesc(xmlbuf1, XMPP->client_jid, sizeof xmlbuf1),
			xmlesc(xmlbuf2, ptr->sender_email, sizeof xmlbuf2)
		);
		if (ptr->text != NULL) {
			striplt(ptr->text);
			cprintf("<body>%s</body>", xmlesc(xmlbuf1, ptr->text, sizeof xmlbuf1));
			free(ptr->text);
		}
		cprintf("</message>");
		free(ptr);
	}
}
Exemplo n.º 4
0
void clear_message_windows(void) {
    int i;

begin_critical_section(&send_message_dialog_lock, "messages.c:clear_message_windows" );

    for (i = 0;  i < MAX_MESSAGE_WINDOWS; i++) {

        if (mw[i].send_message_dialog)
            XtDestroyWidget(mw[i].send_message_dialog);

        mw[i].send_message_dialog = (Widget)NULL;
        mw[i].to_call_sign[0] = '\0';
        mw[i].send_message_call_data = (Widget)NULL;
        mw[i].D700_mode = (Widget)NULL;
        mw[i].D7_mode = (Widget)NULL;
        mw[i].HamHUD_mode = (Widget)NULL;
        mw[i].message_data_line1 = (Widget)NULL;
        mw[i].message_data_line2 = (Widget)NULL;
        mw[i].message_data_line3 = (Widget)NULL;
        mw[i].message_data_line4 = (Widget)NULL;
        mw[i].send_message_text = (Widget)NULL;
    }

end_critical_section(&send_message_dialog_lock, "messages.c:clear_message_windows" );

}
Exemplo n.º 5
0
/*
 * Hand off a copy of a message to be journalized.
 */
void JournalBackgroundSubmit(struct CtdlMessage *msg,
			StrBuf *saved_rfc822_version,
			recptypes *recps) {

	struct jnlq *jptr = NULL;

	/* Avoid double journaling! */
	if (!CM_IsEmpty(msg, eJournal)) {
		FreeStrBuf(&saved_rfc822_version);
		return;
	}

	jptr = (struct jnlq *)malloc(sizeof(struct jnlq));
	if (jptr == NULL) {
		FreeStrBuf(&saved_rfc822_version);
		return;
	}
	memset(jptr, 0, sizeof(struct jnlq));
	if (recps != NULL) memcpy(&jptr->recps, recps, sizeof(recptypes));
	if (!CM_IsEmpty(msg, eAuthor)) jptr->from = strdup(msg->cm_fields[eAuthor]);
	if (!CM_IsEmpty(msg, eNodeName)) jptr->node = strdup(msg->cm_fields[eNodeName]);
	if (!CM_IsEmpty(msg, erFc822Addr)) jptr->rfca = strdup(msg->cm_fields[erFc822Addr]);
	if (!CM_IsEmpty(msg, eMsgSubject)) jptr->subj = strdup(msg->cm_fields[eMsgSubject]);
	if (!CM_IsEmpty(msg, emessageId)) jptr->msgn = strdup(msg->cm_fields[emessageId]);
	jptr->rfc822 = SmashStrBuf(&saved_rfc822_version);

	/* Add to the queue */
	begin_critical_section(S_JOURNAL_QUEUE);
	jptr->next = jnlq;
	jnlq = jptr;
	end_critical_section(S_JOURNAL_QUEUE);
}
Exemplo n.º 6
0
/*
 * Poll room for incoming chat messages
 */
void roomchat_poll(char *argbuf) {
	int newer_than = 0;
	struct chatmsg *found = NULL;
	struct chatmsg *ptr = NULL;

	newer_than = extract_int(argbuf, 1);

	if ((CC->cs_flags & CS_CHAT) == 0) {
		cprintf("%d Session is not in chat mode.\n", ERROR);
		return;
	}

	begin_critical_section(S_CHATQUEUE);
	for (ptr = first_chat_msg; ((ptr != NULL) && (found == NULL)); ptr = ptr->next) {
		if ((ptr->seq > newer_than) && (ptr->roomnum == CC->room.QRnumber)) {
			found = ptr;
		}
	}
	end_critical_section(S_CHATQUEUE);

	if (found == NULL) {
		cprintf("%d no messages\n", ERROR + MESSAGE_NOT_FOUND);
		return;
	}

	cprintf("%d %d|%ld|%s\n", LISTING_FOLLOWS, found->seq, found->timestamp, found->sender);
	cprintf("%s\n", found->msgtext);
	cprintf("000\n");
}
Exemplo n.º 7
0
void popup_time_out_check(int curr_sec) {
    int i;

    // Check only every two minutes or so
    if (popup_time_out_check_last + 120 < curr_sec) {
        popup_time_out_check_last = curr_sec;

        for (i=0;i<MAX_POPUPS;i++) {
            if (pw[i].popup_message_dialog!=NULL) {
                if ((sec_now()-pw[i].sec_opened)>MAX_POPUPS_TIME) {
                    XtPopdown(pw[i].popup_message_dialog);

begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_time_out_check" );

                    XtDestroyWidget(pw[i].popup_message_dialog);
                    pw[i].popup_message_dialog = (Widget)NULL;
                    pw[i].popup_message_data = (Widget)NULL;

end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_time_out_check" );

                }

            }
        }
    }
}
Exemplo n.º 8
0
/*
 * Request client termination
 */
void cmd_reqt(char *argbuf) {
	struct CitContext *ccptr;
	int sessions = 0;
	int which_session;
	struct ExpressMessage *newmsg;

	if (CtdlAccessCheck(ac_aide)) return;
	which_session = extract_int(argbuf, 0);

	begin_critical_section(S_SESSION_TABLE);
	for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
		if ((ccptr->cs_pid == which_session) || (which_session == 0)) {

			newmsg = (struct ExpressMessage *)
				malloc(sizeof (struct ExpressMessage));
			memset(newmsg, 0,
				sizeof (struct ExpressMessage));
			time(&(newmsg->timestamp));
			safestrncpy(newmsg->sender, CC->user.fullname,
				    sizeof newmsg->sender);
			newmsg->flags |= EM_GO_AWAY;
			newmsg->text = strdup("Automatic logoff requested.");

			add_xmsg_to_context(ccptr, newmsg);
			++sessions;

		}
	}
	end_critical_section(S_SESSION_TABLE);
	cprintf("%d Sent termination request to %d sessions.\n", CIT_OK, sessions);
}
Exemplo n.º 9
0
/*
 * Retrieve instant messages
 */
void cmd_gexp(char *argbuf) {
	struct ExpressMessage *ptr;

	if (CC->FirstExpressMessage == NULL) {
		cprintf("%d No instant messages waiting.\n", ERROR + MESSAGE_NOT_FOUND);
		return;
	}

	begin_critical_section(S_SESSION_TABLE);
	ptr = CC->FirstExpressMessage;
	CC->FirstExpressMessage = CC->FirstExpressMessage->next;
	end_critical_section(S_SESSION_TABLE);

	cprintf("%d %d|%ld|%d|%s|%s|%s\n",
		LISTING_FOLLOWS,
		((ptr->next != NULL) ? 1 : 0),		/* more msgs? */
		(long)ptr->timestamp,			/* time sent */
		ptr->flags,				/* flags */
		ptr->sender,				/* sender of msg */
		config.c_nodename,			/* static for now (and possibly deprecated) */
		ptr->sender_email			/* email or jid of sender */
	);

	if (ptr->text != NULL) {
		memfmout(ptr->text, "\n");
		free(ptr->text);
	}

	cprintf("000\n");
	free(ptr);
}
Exemplo n.º 10
0
/*
 * CtdlGetCurrentMessageNumber()  -  Obtain the current highest message number in the system
 * This provides a quick way to initialise a variable that might be used to indicate
 * messages that should not be processed. EG. a new Sieve script will use this
 * to record determine that messages older than this should not be processed.
 */
long CtdlGetCurrentMessageNumber(void)
{
	long retval = 0L;
	begin_critical_section(S_CONTROL);
	get_control();
	retval = CitControl.MMhighest;
	end_critical_section(S_CONTROL);
	return(retval);
}
Exemplo n.º 11
0
/*
 * get_new_message_number()  -  Obtain a new, unique ID to be used for a message.
 */
long get_new_message_number(void)
{
	long retval = 0L;
	begin_critical_section(S_CONTROL);
	get_control();
	retval = ++CitControl.MMhighest;
	put_control();
	end_critical_section(S_CONTROL);
	return(retval);
}
Exemplo n.º 12
0
/*
 * get_new_room_number()  -  Obtain a new, unique ID to be used for a room.
 */
long get_new_room_number(void)
{
	long retval = 0L;
	begin_critical_section(S_CONTROL);
	get_control();
	retval = ++CitControl.MMnextroom;
	put_control();
	end_critical_section(S_CONTROL);
	return(retval);
}
Exemplo n.º 13
0
void Download_trail_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
    Widget shell = (Widget) clientData;
    XtPopdown(shell);

begin_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail_destroy_shell" );

    XtDestroyWidget(shell);
    download_findu_dialog = (Widget)NULL;

end_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail_destroy_shell" );
}
Exemplo n.º 14
0
/* 
 * This is the back end to the instant message sending function.  
 * Returns the number of users to which the message was sent.
 * Sending a zero-length message tests for recipients without sending messages.
 */
int send_instant_message(char *lun, char *lem, char *x_user, char *x_msg)
{
	int message_sent = 0;		/* number of successful sends */
	struct CitContext *ccptr;
	struct ExpressMessage *newmsg = NULL;
	char *un;
	int do_send = 0;		/* 1 = send message; 0 = only check for valid recipient */
	static int serial_number = 0;	/* this keeps messages from getting logged twice */

	if (strlen(x_msg) > 0) {
		do_send = 1;
	}

	/* find the target user's context and append the message */
	begin_critical_section(S_SESSION_TABLE);
	++serial_number;
	for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {

		if (ccptr->fake_username[0]) {
			un = ccptr->fake_username;
		}
		else {
			un = ccptr->user.fullname;
		}

		if ( ((!strcasecmp(un, x_user))
		    || (!strcasecmp(x_user, "broadcast")))
		    && (ccptr->can_receive_im)
		    && ((ccptr->disable_exp == 0)
		    || (CC->user.axlevel >= AxAideU)) ) {
			if (do_send) {
				newmsg = (struct ExpressMessage *) malloc(sizeof (struct ExpressMessage));
				memset(newmsg, 0, sizeof (struct ExpressMessage));
				time(&(newmsg->timestamp));
				safestrncpy(newmsg->sender, lun, sizeof newmsg->sender);
				safestrncpy(newmsg->sender_email, lem, sizeof newmsg->sender_email);
				if (!strcasecmp(x_user, "broadcast")) {
					newmsg->flags |= EM_BROADCAST;
				}
				newmsg->text = strdup(x_msg);

				add_xmsg_to_context(ccptr, newmsg);

				/* and log it ... */
				if (ccptr != CC) {
					log_instant_message(CC, ccptr, newmsg->text, serial_number);
				}
			}
			++message_sent;
		}
	}
	end_critical_section(S_SESSION_TABLE);
	return (message_sent);
}
Exemplo n.º 15
0
void track_station_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
    Widget shell = (Widget) clientData;
    XtPopdown(shell);

begin_critical_section(&track_station_dialog_lock, "track_gui.c:track_station_destroy_shell" );

    XtDestroyWidget(shell);
    track_station_dialog = (Widget)NULL;

end_critical_section(&track_station_dialog_lock, "track_gui.c:track_station_destroy_shell" );

}
Exemplo n.º 16
0
/*
 * Delete any remaining instant messages
 */
void delete_instant_messages(void) {
	struct ExpressMessage *ptr;

	begin_critical_section(S_SESSION_TABLE);
	while (CC->FirstExpressMessage != NULL) {
		ptr = CC->FirstExpressMessage->next;
		if (CC->FirstExpressMessage->text != NULL)
			free(CC->FirstExpressMessage->text);
		free(CC->FirstExpressMessage);
		CC->FirstExpressMessage = ptr;
	}
	end_critical_section(S_SESSION_TABLE);
}
Exemplo n.º 17
0
/*
 * Run the queue.
 */
void JournalRunQueue(void) {
	struct jnlq *jptr = NULL;

	while (jnlq != NULL) {
		begin_critical_section(S_JOURNAL_QUEUE);
		if (jnlq != NULL) {
			jptr = jnlq;
			jnlq = jnlq->next;
		}
		end_critical_section(S_JOURNAL_QUEUE);
		JournalRunQueueMsg(jptr);
	}
}
Exemplo n.º 18
0
void CtdlDisableHouseKeeping(void)
{
	int ActiveBackgroundJobs;
	int do_housekeeping_now = 0;
	struct CitContext *nptr;
	int nContexts, i;

retry_block_housekeeping:
	syslog(LOG_INFO, "trying to disable housekeeping services");
	begin_critical_section(S_HOUSEKEEPING);
	if (housekeeping_in_progress == 0) {
		do_housekeeping_now = 1;
		housekeeping_in_progress = 1;
	}
	end_critical_section(S_HOUSEKEEPING);
	if (do_housekeeping_now == 0) {
		usleep(1000000);
		goto retry_block_housekeeping;
	}
	
	syslog(LOG_INFO, "checking for running server Jobs");

retry_wait_for_contexts:
	/* So that we don't keep the context list locked for a long time
	 * we create a copy of it first
	 */
	ActiveBackgroundJobs = 0;
	nptr = CtdlGetContextArray(&nContexts) ;
	if (nptr)
	{
		for (i=0; i<nContexts; i++) 
		{
			if ((nptr[i].state != CON_SYS) || (nptr[i].IO == NULL) || (nptr[i].lastcmd == 0))
				continue;
			ActiveBackgroundJobs ++;
			syslog(LOG_INFO, "Job CC[%d] active; use TERM if you don't want to wait for it",nptr[i].cs_pid);
		
		}
	
		free(nptr);

	}
	if (ActiveBackgroundJobs != 0) {
		syslog(LOG_INFO, "found %d running jobs, need to wait", ActiveBackgroundJobs);
		usleep(5000000);
		goto retry_wait_for_contexts;
	}
	syslog(LOG_INFO, "Housekeeping disabled now.");
}
Exemplo n.º 19
0
void clear_popup_message_windows(void) {
    int i;

begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:clear_popup_message_windows" );

    for (i=0;i<MAX_POPUPS;i++) {
        pw[i].popup_message_dialog=(Widget)NULL;
        pw[i].popup_message_data=(Widget)NULL;
    }

end_critical_section(&popup_message_dialog_lock, "popup_gui.c:clear_popup_message_windows" );

    pwb.popup_message_dialog=(Widget)NULL;
    pwb.popup_message_data=(Widget)NULL;
}
Exemplo n.º 20
0
static void popup_message_destroy_shell(/*@unused@*/ Widget w,
                                XtPointer clientData,
                                /*@unused@*/ XtPointer callData) {
    int i;

    i=atoi((char *)clientData);
    XtPopdown(pw[i].popup_message_dialog);

begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message_destroy_shell" );

    XtDestroyWidget(pw[i].popup_message_dialog);
    pw[i].popup_message_dialog = (Widget)NULL;
    pw[i].popup_message_data = (Widget)NULL;

end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message_destroy_shell" );

}
Exemplo n.º 21
0
/*
 * Check the size of our thread pool.  If all threads are executing, spawn another.
 */
void check_thread_pool_size(void)
{
	if (time_to_die) return;		/* don't expand the thread pool during shutdown */

	begin_critical_section(S_SPAWNER);	/* only one of these should run at a time */
	if (
		(num_threads_executing >= num_threads_existing)
		&& (num_threads_existing < MAX_WORKER_THREADS)
	) {
		syslog(LOG_DEBUG, "%d of %d threads are executing.  Adding another worker thread.",
			num_threads_executing,
			num_threads_existing
		);
		spawn_another_worker_thread();
	}
	end_critical_section(S_SPAWNER);
}
Exemplo n.º 22
0
/* 
 * Periodically called for housekeeping.  Expire old chat messages so they don't take up memory forever.
 */
void roomchat_timer(void) {
	struct chatmsg *ptr;

	begin_critical_section(S_CHATQUEUE);

	while ((first_chat_msg != NULL) && ((time(NULL) - first_chat_msg->timestamp) > 300)) {
		ptr = first_chat_msg->next;
		free(first_chat_msg->sender);
		free(first_chat_msg->msgtext);
		free(first_chat_msg);
		first_chat_msg = ptr;
		if (first_chat_msg == NULL) {
			last_chat_msg = NULL;
		}
	}

	end_critical_section(S_CHATQUEUE);
}
Exemplo n.º 23
0
void clear_outgoing_messages(void) {
    int i;

    for (i=0;i<MAX_OUTGOING_MESSAGES;i++)
        clear_outgoing_message(i);

begin_critical_section(&send_message_dialog_lock, "messages.c:clear_outgoing_messages" );

    /* clear message send buttons */
    for (i=0;i<MAX_MESSAGE_WINDOWS;i++) {
        /* find station  */
//        if (mw[i].send_message_dialog!=NULL) /* clear submit */
//            XtSetSensitive(mw[i].button_ok,TRUE);
    }

end_critical_section(&send_message_dialog_lock, "messages.c:clear_outgoing_messages" );

}
Exemplo n.º 24
0
/*
 * Get Next Unregistered User
 */
void cmd_gnur(char *argbuf)
{
	struct cdbdata *cdbus;
	struct ctdluser usbuf;

	if (CtdlAccessCheck(ac_aide)) {
		return;
	}

	if ((CtdlGetConfigInt("MMflags") & MM_VALID) == 0) {
		cprintf("%d There are no unvalidated users.\n", CIT_OK);
		return;
	}

	/* There are unvalidated users.  Traverse the user database,
	 * and return the first user we find that needs validation.
	 */
	cdb_rewind(CDB_USERS);
	while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
		memset(&usbuf, 0, sizeof(struct ctdluser));
		memcpy(&usbuf, cdbus->ptr,
		       ((cdbus->len > sizeof(struct ctdluser)) ?
			sizeof(struct ctdluser) : cdbus->len));
		cdb_free(cdbus);
		if ((usbuf.flags & US_NEEDVALID)
		    && (usbuf.axlevel > AxDeleted)) {
			cprintf("%d %s\n", MORE_DATA, usbuf.fullname);
			cdb_close_cursor(CDB_USERS);
			return;
		}
	}

	/* If we get to this point, there are no more unvalidated users.
	 * Therefore we clear the "users need validation" flag.
	 */

	begin_critical_section(S_CONTROL);
	int flags;
	flags = CtdlGetConfigInt("MMflags");
	flags = flags & (~MM_VALID);
	CtdlSetConfigInt("MMflags", flags);
	end_critical_section(S_CONTROL);
	cprintf("%d *** End of registration.\n", CIT_OK);
}
Exemplo n.º 25
0
void All_messages_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
    Widget shell = (Widget) clientData;
    char *temp_ptr;


    temp_ptr = XmTextFieldGetString(vm_dist_data);
    vm_range = atoi(temp_ptr);
    XtFree(temp_ptr);

    XtPopdown(shell);

begin_critical_section(&All_messages_dialog_lock, "view_message_gui.c:All_messages_destroy_shell" );

    XtDestroyWidget(shell);
    All_messages_dialog = (Widget)NULL;

end_critical_section(&All_messages_dialog_lock, "view_message_gui.c:All_messages_destroy_shell" );

}
Exemplo n.º 26
0
/*
 * Add a message into the chat queue
 */
void add_to_chat_queue(char *msg) {
	static int seq = 0;

	struct chatmsg *m = malloc(sizeof(struct chatmsg));
	if (!m) return;

	m->next = NULL;
	m->timestamp = time(NULL);
	m->roomnum = CC->room.QRnumber;
	m->sender = strdup(CC->user.fullname);
	m->msgtext = strdup(msg);

	if ((m->sender == NULL) || (m->msgtext == NULL)) {
		free(m->sender);
		free(m->msgtext);
		free(m);
		return;
	}

	begin_critical_section(S_CHATQUEUE);
	m->seq = ++seq;

	if (first_chat_msg == NULL) {
		assert(last_chat_msg == NULL);
		first_chat_msg = m;
		last_chat_msg = m;
	}
	else {
		assert(last_chat_msg != NULL);
		assert(last_chat_msg->next == NULL);
		last_chat_msg->next = m;
		last_chat_msg = m;
	}

	end_critical_section(S_CHATQUEUE);
}
Exemplo n.º 27
0
void Download_findu_trail( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
    static Widget pane, my_form, button_ok, button_cancel, call, sep;
    Atom delw;
    XmString x_str;


    if (!download_findu_dialog) {

begin_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_findu_trail" );

        download_findu_dialog = XtVaCreatePopupShell(langcode("WPUPTSP007"),
                xmDialogShellWidgetClass, appshell,
                XmNdeleteResponse,XmDESTROY,
                XmNdefaultPosition, FALSE,
                XmNfontList, fontlist1,
                NULL);

        pane = XtVaCreateWidget("Download_findu_trail pane",
                xmPanedWindowWidgetClass, 
                download_findu_dialog,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                NULL);

        my_form =  XtVaCreateWidget("Download_findu_trail my_form",
                xmFormWidgetClass, 
                pane,
                XmNfractionBase, 2,
                XmNautoUnmanage, FALSE,
                XmNshadowThickness, 1,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                NULL);

        call = XtVaCreateManagedWidget(langcode("WPUPTSP008"),
                xmLabelWidgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_FORM,
                XmNtopOffset, 10,
                XmNbottomAttachment, XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNleftOffset, 10,
                XmNrightAttachment, XmATTACH_NONE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        download_trail_station_data = XtVaCreateManagedWidget("download_trail_station_data", 
                xmTextFieldWidgetClass, 
                my_form,
                XmNeditable,   TRUE,
                XmNcursorPositionVisible, TRUE,
                XmNsensitive, TRUE,
                XmNshadowThickness,    1,
                XmNcolumns, 15,
                XmNwidth, ((15*7)+2),
                XmNmaxLength, 15,
                XmNbackground, colors[0x0f],
                XmNtopAttachment,XmATTACH_FORM,
                XmNtopOffset, 5,
                XmNbottomAttachment,XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_WIDGET,
                XmNleftWidget, call,
                XmNleftOffset, 10,
                XmNrightAttachment,XmATTACH_NONE,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                XmNfontList, fontlist1,
                NULL);

        x_str = XmStringCreateLocalized(langcode("WPUPTSP009"));
        posit_start_value = XtVaCreateManagedWidget("Start of Trail (hrs ago)", 
                xmScaleWidgetClass, 
                my_form,
                XmNtopAttachment,XmATTACH_WIDGET,
                XmNtopWidget, call,
                XmNtopOffset, 15,
                XmNbottomAttachment,XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNleftOffset, 10,
                XmNrightAttachment,XmATTACH_NONE,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                //XmNwidth, 190,
                XmNrightAttachment, XmATTACH_FORM,
                XmNrightOffset, 10,
                XmNsensitive, TRUE,
                XmNorientation, XmHORIZONTAL,
                XmNborderWidth, 1,
                XmNminimum, 1,
                XmNmaximum, MAX_FINDU_START_TIME,
                XmNshowValue, TRUE,
                XmNvalue, posit_start,
// Note:  Some versions of OpenMotif (distributed with Fedora,
// perhaps others) don't work properly with XtVaTypedArg() as used
// here, instead showing blank labels for the Scale widgets.
//                XtVaTypedArg, XmNtitleString, XmRString, langcode("WPUPTSP009"), 22,
                XmNtitleString, x_str,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);
        XmStringFree(x_str);

        x_str = XmStringCreateLocalized(langcode("WPUPTSP010"));
        posit_length_value = XtVaCreateManagedWidget("Length of trail (hrs)", 
                xmScaleWidgetClass, 
                my_form,
                XmNtopAttachment,XmATTACH_WIDGET,
                XmNtopWidget, posit_start_value,
                XmNtopOffset, 15,
                XmNbottomAttachment,XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNleftOffset, 10,
                XmNrightAttachment,XmATTACH_NONE,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                //XmNwidth, 190,
                XmNrightAttachment, XmATTACH_FORM,
                XmNrightOffset, 10,
                XmNsensitive, TRUE,
                XmNorientation, XmHORIZONTAL,
                XmNborderWidth, 1,
                XmNminimum, 1,
                XmNmaximum, MAX_FINDU_DURATION,
                XmNshowValue, TRUE,
                XmNvalue, posit_length,
// Note:  Some versions of OpenMotif (distributed with Fedora,
// perhaps others) don't work properly with XtVaTypedArg() as used
// here, instead showing blank labels for the Scale widgets.
//                XtVaTypedArg, XmNtitleString, XmRString, langcode("WPUPTSP010"), 19,
                XmNtitleString, x_str,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);
        XmStringFree(x_str);

        sep = XtVaCreateManagedWidget("Download_findu_trail sep", 
                xmSeparatorGadgetClass,
                my_form,
                XmNorientation, XmHORIZONTAL,
                XmNtopAttachment,XmATTACH_WIDGET,
                XmNtopWidget,posit_length_value,
                XmNtopOffset, 10,
                XmNbottomAttachment,XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNrightAttachment,XmATTACH_FORM,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        button_ok = XtVaCreateManagedWidget(langcode("WPUPTSP007"),
                xmPushButtonGadgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, sep,
                XmNtopOffset, 5,
                XmNbottomAttachment, XmATTACH_FORM,
                XmNbottomOffset, 5,
                XmNleftAttachment, XmATTACH_POSITION,
                XmNleftPosition, 0,
                XmNleftOffset, 5,
                XmNrightAttachment, XmATTACH_POSITION,
                XmNrightPosition, 1,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);
        if (fetching_findu_trail_now)
            XtSetSensitive(button_ok, FALSE);

        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
                xmPushButtonGadgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, sep,
                XmNtopOffset, 5,
                XmNbottomAttachment, XmATTACH_FORM,
                XmNbottomOffset, 5,
                XmNleftAttachment, XmATTACH_POSITION,
                XmNleftPosition, 1,
                XmNrightAttachment, XmATTACH_POSITION,
                XmNrightPosition, 2,
                XmNrightOffset, 5,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        XtAddCallback(button_ok, XmNactivateCallback, Download_trail_now, download_findu_dialog);
        XtAddCallback(button_cancel, XmNactivateCallback, Download_trail_destroy_shell, download_findu_dialog);
        XtAddCallback(posit_start_value, XmNvalueChangedCallback, Reset_posit_length_max, download_findu_dialog);

        pos_dialog(download_findu_dialog);

        delw = XmInternAtom(XtDisplay(download_findu_dialog),"WM_DELETE_WINDOW", FALSE);
        XmAddWMProtocolCallback(download_findu_dialog, delw, Download_trail_destroy_shell, (XtPointer)download_findu_dialog);

        XmTextFieldSetString(download_trail_station_data,download_trail_station_call);

        XtManageChild(my_form);
        XtManageChild(pane);

end_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail" );

        XtPopup(download_findu_dialog,XtGrabNone);
        fix_dialog_size(download_findu_dialog);

        // Move focus to the Cancel button.  This appears to highlight the
        // button fine, but we're not able to hit the <Enter> key to
        // have that default function happen.  Note:  We _can_ hit the
        // <SPACE> key, and that activates the option.
//        XmUpdateDisplay(download_findu_dialog);
        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);

    } else
        (void)XRaiseWindow(XtDisplay(download_findu_dialog), XtWindow(download_findu_dialog));
}
Exemplo n.º 28
0
void Track_station( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
    static Widget pane, my_form, button_ok, button_close, button_clear, call, sep;
    Atom delw;

    if (!track_station_dialog) {

begin_critical_section(&track_station_dialog_lock, "track_gui.c:Track_station" );

        track_station_dialog = XtVaCreatePopupShell(langcode("WPUPTSP001"),
                xmDialogShellWidgetClass, appshell,
                XmNdeleteResponse, XmDESTROY,
                XmNdefaultPosition, FALSE,
                XmNfontList, fontlist1,
                NULL);

        pane = XtVaCreateWidget("Track_station pane",
                xmPanedWindowWidgetClass, 
                track_station_dialog,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                NULL);

        my_form =  XtVaCreateWidget("Track_station my_form",
                xmFormWidgetClass, 
                pane,
                XmNfractionBase, 3,
                XmNautoUnmanage, FALSE,
                XmNshadowThickness, 1,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                NULL);

        call = XtVaCreateManagedWidget(langcode("WPUPTSP002"),
                xmLabelWidgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_FORM,
                XmNtopOffset, 10,
                XmNbottomAttachment, XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNleftOffset, 10,
                XmNrightAttachment, XmATTACH_NONE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        track_station_data = XtVaCreateManagedWidget("Track_station track locate data", 
                xmTextFieldWidgetClass, 
                my_form,
                XmNeditable,   TRUE,
                XmNcursorPositionVisible, TRUE,
                XmNsensitive, TRUE,
                XmNshadowThickness,    1,
                XmNcolumns, 15,
                XmNwidth, ((15*7)+2),
                XmNmaxLength, 15,
                XmNbackground, colors[0x0f],
                XmNtopAttachment,XmATTACH_FORM,
                XmNtopOffset, 5,
                XmNbottomAttachment,XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_WIDGET,
                XmNleftWidget, call,
                XmNleftOffset, 10,
                XmNrightAttachment,XmATTACH_NONE,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                XmNfontList, fontlist1,
                NULL);

        track_case_data  = XtVaCreateManagedWidget(langcode("WPUPTSP003"),
                xmToggleButtonWidgetClass,
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, call,
                XmNtopOffset, 20,
                XmNbottomAttachment, XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNleftOffset ,10,
                XmNrightAttachment, XmATTACH_NONE,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        track_match_data  = XtVaCreateManagedWidget(langcode("WPUPTSP004"),
                xmToggleButtonWidgetClass,
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, call,
                XmNtopOffset, 20,
                XmNbottomAttachment, XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_WIDGET,
                XmNleftWidget,track_case_data,
                XmNrightOffset ,20,
                XmNrightAttachment, XmATTACH_NONE,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        sep = XtVaCreateManagedWidget("Track_station sep", 
                xmSeparatorGadgetClass,
                my_form,
                XmNorientation, XmHORIZONTAL,
                XmNtopAttachment,XmATTACH_WIDGET,
                XmNtopWidget,track_case_data,
                XmNtopOffset, 10,
                XmNbottomAttachment,XmATTACH_NONE,
                XmNleftAttachment, XmATTACH_FORM,
                XmNrightAttachment,XmATTACH_FORM,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        button_ok = XtVaCreateManagedWidget(langcode("WPUPTSP005"),
                xmPushButtonGadgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, sep,
                XmNtopOffset, 5,
                XmNbottomAttachment, XmATTACH_FORM,
                XmNbottomOffset, 5,
                XmNleftAttachment, XmATTACH_POSITION,
                XmNleftPosition, 0,
                XmNleftOffset, 5,
                XmNrightAttachment, XmATTACH_POSITION,
                XmNrightPosition, 1,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        button_clear = XtVaCreateManagedWidget(langcode("WPUPTSP006"),
                xmPushButtonGadgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, sep,
                XmNtopOffset, 5,
                XmNbottomAttachment, XmATTACH_FORM,
                XmNbottomOffset, 5,
                XmNleftAttachment, XmATTACH_POSITION,
                XmNleftPosition, 1,
                XmNrightAttachment, XmATTACH_POSITION,
                XmNrightPosition, 2,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
                xmPushButtonGadgetClass, 
                my_form,
                XmNtopAttachment, XmATTACH_WIDGET,
                XmNtopWidget, sep,
                XmNtopOffset, 5,
                XmNbottomAttachment, XmATTACH_FORM,
                XmNbottomOffset, 5,
                XmNleftAttachment, XmATTACH_POSITION,
                XmNleftPosition, 2,
                XmNrightAttachment, XmATTACH_POSITION,
                XmNrightPosition, 3,
                XmNrightOffset, 5,
                XmNnavigationType, XmTAB_GROUP,
                XmNtraversalOn, TRUE,
                MY_FOREGROUND_COLOR,
                MY_BACKGROUND_COLOR,
                XmNfontList, fontlist1,
                NULL);

        XtAddCallback(button_ok, XmNactivateCallback, Track_station_now, track_station_dialog);
        XtAddCallback(button_close, XmNactivateCallback, track_station_destroy_shell, track_station_dialog);
        XtAddCallback(button_clear, XmNactivateCallback, Track_station_clear, track_station_dialog);

        XmToggleButtonSetState(track_case_data,FALSE,FALSE);
        XmToggleButtonSetState(track_match_data,TRUE,FALSE);

        pos_dialog(track_station_dialog);

        delw = XmInternAtom(XtDisplay(track_station_dialog),"WM_DELETE_WINDOW", FALSE);
        XmAddWMProtocolCallback(track_station_dialog, delw, track_station_destroy_shell, (XtPointer)track_station_dialog);

//        if (track_station_on==1)
            XmTextFieldSetString(track_station_data,tracking_station_call);

        XtManageChild(my_form);
        XtManageChild(pane);

end_critical_section(&track_station_dialog_lock, "track_gui.c:Track_station" );

        XtPopup(track_station_dialog,XtGrabNone);
        fix_dialog_size(track_station_dialog);

        // Move focus to the Cancel button.  This appears to highlight the
        // button fine, but we're not able to hit the <Enter> key to
        // have that default function happen.  Note:  We _can_ hit the
        // <SPACE> key, and that activates the option.
//        XmUpdateDisplay(track_station_dialog);
        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);

    } else
        (void)XRaiseWindow(XtDisplay(track_station_dialog), XtWindow(track_station_dialog));
}
Exemplo n.º 29
0
// Adds a message to the outgoing message queue.  Doesn't actually
// cause a transmit.  "check_and_transmit_messages()" is the
// function which actually gets things moving.
//
// We also stuff the message into the main message queue so that the
// queued messages will appear in the Send Message box.
//
void output_message(char *from, char *to, char *message, char *path) {
    int ok,i,j;
    char message_out[MAX_MESSAGE_OUTPUT_LENGTH+1+5+1]; // +'{' +msg_id +terminator
    int last_space, message_ptr, space_loc;
    int wait_on_first_ack;
    int error;
    long record;


//fprintf(stderr,"output_message:%s\n", message);

    message_ptr=0;
    last_space=0;
    ok=0;
    error=0;

    if (debug_level & 2)
        fprintf(stderr,"Output Message from <%s>  to <%s>\n",from,to);

    // Repeat until we process the entire message.  We'll process it
    // a chunk at a time, size of chunk to correspond to max APRS
    // message line length.
    //
    while (!error && (message_ptr < (int)strlen(message))) {
        ok=0;
        space_loc=0;

        // Break a long message into smaller chunks that can be
        // processed into APRS messages.  Break at a space character
        // if possible.
        //
        for (j=0; j<MAX_MESSAGE_OUTPUT_LENGTH; j++) {

            if(message[j+message_ptr] != '\0') {

                if(message[j+message_ptr]==' ') {
                    last_space=j+message_ptr+1;
                    space_loc=j;
                }

                if (j!=MAX_MESSAGE_OUTPUT_LENGTH) {
                    message_out[j]=message[j+message_ptr];
                    message_out[j+1] = '\0';
                }
                else {

                    if(space_loc!=0)
                        message_out[space_loc] = '\0';
                    else
                        last_space=j+message_ptr;
                }
            }
            else {
                j=MAX_MESSAGE_OUTPUT_LENGTH+1;
                last_space=strlen(message)+1;
            }
        }

//fprintf(stderr,"message_out: %s\n", message_out);

        if (debug_level & 2)
            fprintf(stderr,"MESSAGE <%s> %d %d\n",message_out,message_ptr,last_space);

        if (j >= MAX_MESSAGE_OUTPUT_LENGTH) {
            message_ptr = MAX_MESSAGE_OUTPUT_LENGTH;
        }
        else {
            message_ptr=last_space;
        }

        /* check for others in the queue */
        wait_on_first_ack=0;
        for (i=0; i<MAX_OUTGOING_MESSAGES; i++) {
            if (message_pool[i].active == MESSAGE_ACTIVE
                    && strcmp(to, message_pool[i].to_call_sign) == 0
                    && strcmp(from, "***") != 0) {
                wait_on_first_ack=1;
                i=MAX_OUTGOING_MESSAGES+1;  // Done with loop
            }
        }

        for (i=0; i<MAX_OUTGOING_MESSAGES && !ok ;i++) {
            /* Check for clear position*/
            if (message_pool[i].active==MESSAGE_CLEAR) {
                /* found a spot */
                ok=1;

                // Increment the message sequence ID variable
                if (bump_message_counter(message_counter)) 
		   fprintf(stderr, "!WARNING!: Wrap around Message Counter");


// Note that Xastir's messaging can lock up if we do a rollover and
// have unacked messages on each side of the rollover.  This is due
// to the logic in db.c that looks for the lowest numbered unacked
// message.  We get stuck on both sides of the fence at once.  To
// avoid this condition we could reduce the compare number (8100) to
// a smaller value, and only roll over when there are no unacked
// messages?  Another way to do it would be to write a "0" to the
// config file if we're more than 1000 when we quit Xastir?  That
// would probably be easier.  It's still possible to get to 8100
// messages during one runtime though.  Unlikely, but possible.

                message_pool[i].active = MESSAGE_ACTIVE;
                message_pool[i].wait_on_first_ack = wait_on_first_ack;
                xastir_snprintf(message_pool[i].to_call_sign,
                    sizeof(message_pool[i].to_call_sign),
                    "%s",
                    to);
                xastir_snprintf(message_pool[i].from_call_sign,
                    sizeof(message_pool[i].from_call_sign),
                    "%s",
                    from);
                xastir_snprintf(message_pool[i].message_line,
                    sizeof(message_pool[i].message_line),
                    "%s",
                    message_out);

                if (path != NULL)
                    xastir_snprintf(message_pool[i].path,
                        sizeof(message_pool[i].path),
                        "%s",
                        path);
                else
                    message_pool[i].path[0] = '\0';

//                // We compute the base-90 sequence number here
//                // This allows it to range from "!!" to "zz"
//                xastir_snprintf(message_pool[i].seq,
//                    sizeof(message_pool[i].seq),
//                    "%c%c",
//                    (char)(((message_counter / 90) % 90) + 33),
//                    (char)((message_counter % 90) + 33));

                xastir_snprintf(message_pool[i].seq,
                    sizeof(message_pool[i].seq),
                    "%c%c",
                    message_counter[0],
                    message_counter[1]);

                message_pool[i].active_time=0;
                message_pool[i].next_time = (time_t)7l;

                if (strcmp(from,"***")!= 0)
                    message_pool[i].tries = 0;
                else
                    message_pool[i].tries = MAX_TRIES-1;

                // Cause the message to get added to the main
                // message queue as well, with the proper sequence
                // number, so queued messages will appear in the
                // Send Message box as unacked messages.
                //

// We must get rid of the lock we already have for a moment, as
// update_messages(), which is called by msg_data_add(), also snags
// this lock.
end_critical_section(&send_message_dialog_lock, "db.c:update_messages" );

                (void)msg_data_add(to,
                    from,
                    message_out,
                    message_pool[i].seq,
                    MESSAGE_MESSAGE,
                    'L',    // From the Local system
                    &record);
/*
                fprintf(stderr,"msg_data_add %s %s %s %s\n",
                    to,
                    from,
                    message_out,
                    message_pool[i].seq);
*/

// Regain the lock we had before
begin_critical_section(&send_message_dialog_lock, "db.c:update_messages" );

            }
        }
        if(!ok) {
            fprintf(stderr,"Output message queue is full!\n");
            error=1;
        }
    }
}
Exemplo n.º 30
0
// What we wish to do here:  Check for an active Send Message dialog
// that contains the callsign of interest.  If one doesn't exist,
// create one and pop it up.  We don't want to do this for duplicate
// message lines or duplicate acks for any particular QSO.  To do so
// would cause the Send Message dialog to pop up on every such
// received message, which is VERY annoying (that was the default in
// Xastir for years, and nobody liked it!).
//
int check_popup_window(char *from_call_sign, int group) {
    int i,found,j,ret;
    char temp1[MAX_CALLSIGN+1];
    char *temp_ptr;


//fprintf(stderr,"\tcheck_popup_window()\n");

    ret = -1;
    found = -1;

begin_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window" );

    // Check for an already-created dialog for talking to this
    // particular call_sign.
    //
    for (i = 0; i < MAX_MESSAGE_WINDOWS; i++) {

        if (mw[i].send_message_dialog != NULL) { // If dialog created

            temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data);
            xastir_snprintf(temp1,
                sizeof(temp1),
                "%s",
                temp_ptr);
            XtFree(temp_ptr);

            /*fprintf(stderr,"Looking at call <%s> for <%s>\n",temp1,from_call_sign);*/
            if (strcasecmp(temp1, from_call_sign) == 0) {
                // Found a call_sign match in a Send Message dialog!

//fprintf(stderr,"\tFound a Send_message dialog match\n");

                found = i;
                break;
            }
        }
    }

end_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window" );

    // If found == -1 at this point, we haven't found a Send Message
    // dialog that contains the call_sign of interest.
    //
    if (found == -1 && (group == 2 || group_active(from_call_sign))) {
        /* no window found Open one! */

//fprintf(stderr,"\tNo Send Message dialog found, creating one\n");

begin_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window2" );

        i= -1;
        for (j=0; j<MAX_MESSAGE_WINDOWS; j++) {
            if (!mw[j].send_message_dialog) {
                i=j;
                break;
            }
        }

end_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window2" );

        if (i!= -1) {

            if (group == 1) {
                temp1[0] = '*';
                temp1[1] = '\0';
            }
            else {
                temp1[0] = '\0';
            }

            strncat(temp1,
                from_call_sign,
                sizeof(temp1) - 1 - strlen(temp1));

            if (!disable_all_popups) {
                Send_message(appshell, temp1, NULL);
            }

            update_messages(1);

            ret=i;
        }
        else {
            fprintf(stderr,"No open windows!\n");
        }
    }
    else {
        /* window open! */
        // Pop it up
        ret=found;
    }

    if (found != -1) {  // Already have a window
        XtPopup(mw[i].send_message_dialog,XtGrabNone);
    }

    return(ret);
}