Ejemplo n.º 1
0
/* input_delete_character: deletes a character from the input line */
void input_delete_character(char unused, char *not_used)
{
    cursor_to_input();
    if (THIS_CHAR) {
	char *ptr = NULL;
	int pos;

	malloc_strcpy(&ptr, &(NEXT_CHAR));
	strcpy(&(THIS_CHAR), ptr);
	new_free(&ptr);
	if (term_delete())
	    update_input(UPDATE_FROM_CURSOR);
	else {
	    pos = str_start + term_cols - 1;
	    pos += count_ansi(&(current_screen->input_buffer[str_start]), zone);
	    if (pos < strlen(INPUT_BUFFER)) {
		term_move_cursor(term_cols - 1, input_line);
		term_putchar(INPUT_BUFFER[pos]);
		term_move_cursor(cursor, input_line);
	    }
	    update_input(NO_UPDATE);
	}
    }
    in_completion = STATE_NORMAL;
}
Ejemplo n.º 2
0
/*
 * term_ALDL_scroll: should be used for scrolling if the term has AL and DL
 * by setting the term_scroll function to it
 */
static	int
term_ALDL_scroll(int line1, int line2, int n)
{
	int	i;

	if (n > 0)
	{
		term_move_cursor(0, line1);
		for (i = 0; i < n; i++)
			tputs_x(DL);
		term_move_cursor(0, line2 - n + 1);
		for (i = 0; i < n; i++)
			tputs_x(AL);
	}
	else if (n < 0)
	{
		n = -n;
		term_move_cursor(0, line2-n+1);
		for (i = 0; i < n; i++)
			tputs_x(DL);
		term_move_cursor(0, line1);
		for (i = 0; i < n; i++)
			tputs_x(AL);
	}
	return (0);
}
Ejemplo n.º 3
0
/*
 * term_CS_scroll: should be used if the terminal has the CS capability by
 * setting term_scroll equal to it
 */
static	int
term_CS_scroll(int line1, int line2, int n)
{
	int	i;
	u_char	*thing;

	if (n > 0)
		thing = UP(SF ? SF : NL);
	else if (n < 0)
	{
		if (SR)
			thing = UP(SR);
		else
			return 1;
	}
	else
		return 0;
	tputs_x(tgoto(CS, line2, line1));  /* shouldn't do this each time */
	if (n < 0)
	{
		term_move_cursor(0, line1);
		n = -n;
	}
	else
		term_move_cursor(0, line2);
	for (i = 0; i < n; i++)
		tputs_x(CP(thing));
	tputs_x(tgoto(CS, get_li() - 1, 0));	/* shouldn't do this each time */
	return (0);
}
Ejemplo n.º 4
0
/* input_backspace: does a backspace in the input buffer */
void input_backspace(char key, char *blah)
{
    cursor_to_input();
    if (THIS_POS > MIN_POS) {
	char *ptr = NULL;
	int pos;

	malloc_strcpy(&ptr, &(THIS_CHAR));
	strcpy(&(PREV_CHAR), ptr);
	new_free(&ptr);
	THIS_POS--;
	term_cursor_left();
	if (THIS_CHAR) {
	    if (term_delete())
		update_input(UPDATE_FROM_CURSOR);
	    {
		pos = str_start + term_cols - 1;
		pos += count_ansi(&(current_screen->input_buffer[str_start]), zone);
		if (pos < strlen(INPUT_BUFFER)) {
		    term_move_cursor(term_cols - 1, input_line);
		    term_putchar(INPUT_BUFFER[pos]);
		}
		update_input(UPDATE_JUST_CURSOR);
	    }
	} else {
	    term_putchar(' ');
	    term_cursor_left();
	    update_input(NO_UPDATE);
	}
    }
    in_completion = STATE_NORMAL;
    *new_nick = 0;
}
Ejemplo n.º 5
0
/*
 * input_clear_line: clears entire input line
 */
void input_clear_line(char unused, char *not_used)
{
    cursor_to_input();
    malloc_strcpy(&cut_buffer, INPUT_BUFFER + MIN_POS);
    MIN_CHAR = (char) 0;
    THIS_POS = MIN_POS;
    term_move_cursor(current_screen->buffer_min_pos - count_ansi(current_screen->input_buffer, zone), input_line);
    term_clear_to_eol();
    update_input(NO_UPDATE);
}
Ejemplo n.º 6
0
void gui_entry_set_active(GUI_ENTRY_REC *entry)
{
	active_entry = entry;

	if (entry != NULL) {
		term_move_cursor(entry->xpos + entry->scrpos +
				 entry->promptlen, entry->ypos);
		term_refresh(NULL);
	}
}
Ejemplo n.º 7
0
/*
 * term_param_ALDL_scroll: Uses the parameterized version of AL and DL
 */
static	int
term_param_ALDL_scroll(int line1, int line2, int n)
{
	if (n > 0)
	{
		term_move_cursor(0, line1);
		tputs_x(tgoto(DL, n, n));
		term_move_cursor(0, line2 - n + 1);
		tputs_x(tgoto(AL, n, n));
	}
	else if (n < 0)
	{
		n = -n;
		term_move_cursor(0, line2-n+1);
		tputs_x(tgoto(DL, n, n));
		term_move_cursor(0, line1);
		tputs_x(tgoto(AL, n, n));
	}
	return (0);
}
Ejemplo n.º 8
0
static void gui_entry_draw(GUI_ENTRY_REC *entry)
{
	if (entry->redraw_needed_from >= 0) {
		gui_entry_draw_from(entry, entry->redraw_needed_from);
                entry->redraw_needed_from = -1;
	}

	term_move_cursor(entry->xpos + entry->scrpos + entry->promptlen,
			 entry->ypos);
	term_refresh(NULL);
}
Ejemplo n.º 9
0
static void	input_delete_char_from_screen (void)
{
	/*
	 * Remove the current character from the screen's display.
	 *
	 * If we cannot do a character delete then we do a wholesale
	 * redraw of the input line (ugh). 
	 */
	if (!(termfeatures & TERM_CAN_DELETE))
		update_input(UPDATE_FROM_CURSOR);
	else
	{
		int	pos;

		/*
		 * Delete the character.  This is the simple part.
		 */
		term_delete(1);

		/*
		 * So right now we have a blank space at the right of the
		 * screen.  If there is a character in the input buffer that
		 * is out in that position, we need to find it and display it.
		 */
		if (INPUT_ONSCREEN == 0)		/* UGH! */
			pos = last_input_screen->co - INPUT_PROMPT_LEN - 1;
		else
			pos = INPUT_ONSCREEN + last_input_screen->co - 1;

		if (pos < (int)strlen(INPUT_BUFFER))
		{
			term_move_cursor(last_input_screen->co - 1, INPUT_LINE);
			term_putchar(INPUT_BUFFER[pos]);
			term_move_cursor(INPUT_CURSOR, INPUT_LINE);
			cursor_not_in_display(last_input_screen);
		}

		/* XXX - Very possibly, this is pointless */
		update_input(NO_UPDATE);
	}
}
Ejemplo n.º 10
0
/* init_windows:  */
int init_screen (void)
{
extern int term_initialized;
	term_initialized = 1;
	term_clear_screen();
	term_resize();
	create_new_screen();
	new_window(main_screen);
	update_all_windows();
	term_move_cursor(0, 0);
	return 0;
}
Ejemplo n.º 11
0
/*
 * term_reset: sets terminal attributed back to what they were before the
 * program started
 */
void
term_reset(void)
{
	tcsetattr(tty_des, TCSADRAIN, &oldb);

	if (CS)
		tputs_x(tgoto(CS, get_li() - 1, 0));
	if (!use_termcap_enterexit() && TE)
		tputs_x(TE);
	term_move_cursor(0, get_li() - 1);
	term_reset_flag = 1;
	term_flush();
}
Ejemplo n.º 12
0
/* cursor_to_input: move the cursor to the input line, if not there already */
void
cursor_to_input(void)
{
	if (screen_get_alive(get_current_screen()) && is_cursor_in_display())
	{
		ScreenInputData *inputdata = screen_get_inputdata(get_current_screen());

		term_move_cursor(inputdata->cursor_x, inputdata->cursor_y);
		Debug(DB_CURSOR, "cursor_to_input: moving cursor to input for screen %d",
		       screen_get_screennum(get_current_screen()));
		cursor_not_in_display();
		term_flush();
	}
}
Ejemplo n.º 13
0
/* cursor_to_input: move the cursor to the input line, if not there already */
void cursor_to_input(void)
{
    Screen *old_current_screen;

    old_current_screen = current_screen;
    for (current_screen = screen_list; current_screen; current_screen = current_screen->next) {
	if (current_screen->alive && is_cursor_in_display(NULL)) {
	    term_move_cursor(cursor, input_line);
	    cursor_not_in_display();
	    term_flush();
	}
    }
    set_current_screen(old_current_screen);
}
Ejemplo n.º 14
0
/*
 * input_clear_to_bol: clears from the cursor to the beginning of the input
 * buffer 
 */
void input_clear_to_bol(char unused, char *not_used)
{
    char *ptr = NULL;

    cursor_to_input();
    malloc_strcpy(&cut_buffer, &(MIN_CHAR));
    cut_buffer[THIS_POS - MIN_POS] = (char) 0;
    malloc_strcpy(&ptr, &(THIS_CHAR));
    MIN_CHAR = (char) 0;
    ADD_TO_INPUT(ptr);
    new_free(&ptr);
    THIS_POS = MIN_POS;
    term_move_cursor(MIN_POS, input_line);
    term_clear_to_eol();
    update_input(UPDATE_FROM_CURSOR);
}
Ejemplo n.º 15
0
/*
 * init_screen() sets up a full screen display for normal display mode.
 * It will fail if your TERM setting doesn't have all of the necessary
 * capabilities to run in full screen mode.  The client is expected to 
 * fail-over to dumb mode in this case.
 * This may only be called once, at initial startup (by main()).
 */
int	init_screen (void)
{
	/* Investigate TERM and put the console in full-screen mode */
	if (term_init())
		return -1;

	term_clear_screen();
	term_resize();

	/*
	 * System independant stuff
	 */
	create_new_screen();
	new_window(main_screen);
	update_all_windows();

	term_move_cursor(0, 0);
	return 0;
}
Ejemplo n.º 16
0
/* cursor_to_input: move the cursor to the input line, if not there already */
void 	cursor_to_input (void)
{
	Screen *oldscreen = last_input_screen;
	Screen *screen;

	if (!foreground)
		return;		/* Dont bother */

	for (screen = screen_list; screen; screen = screen->next)
	{
		if (screen->alive && is_cursor_in_display(screen))
		{
			output_screen = screen;
			last_input_screen = screen;
			term_move_cursor(INPUT_CURSOR, INPUT_LINE);
			term_flush();
			cursor_not_in_display(screen);
		}
	}
	output_screen = last_input_screen = oldscreen;
}
Ejemplo n.º 17
0
/* init_windows:  */
int	init_screen (void)
{
	/*
	 * System dependant stuff
	 */
	if (term_init())
		return -1;

	term_clear_screen();
	term_resize();

	/*
	 * System independant stuff
	 */
	create_new_screen();
	new_window(main_screen);
	update_all_windows();

	term_move_cursor(0, 0);
	return 0;
}
Ejemplo n.º 18
0
/*
 * This just sucked beyond words.  I was always planning on rewriting this,
 * but the crecendo of complaints with regards to this just got to be too 
 * irritating, so i fixed it early.
 */
int	make_status (Window *window, int must_redraw)
{
	int	status_line;
	u_char	buffer	    [BIG_BUFFER_SIZE + 1];
	u_char	lhs_buffer  [BIG_BUFFER_SIZE + 1];
	u_char	rhs_buffer  [BIG_BUFFER_SIZE + 1];
	Char	*func_value [MAX_FUNCTIONS];
	u_char	*ptr;
	size_t	save_size;

	/* We do NOT redraw status bars for hidden windows */
	if (!window->screen || !status_updates_permitted)
		return -1;

	for (status_line = 0; status_line < window->status.double_status + 1; status_line++)
	{
		u_char	lhs_fillchar[6],
			rhs_fillchar[6],
			*fillchar = lhs_fillchar,
			*lhp = lhs_buffer,
			*rhp = rhs_buffer,
			*cp,
			*start_rhs = 0,
			*str;
		int	in_rhs = 0,
			pr_lhs = 0,
			pr_rhs = 0,
			line,
			*prc = &pr_lhs, 
			i;

		fillchar[0] = fillchar[1] = 0;

		/*
		 * If status line gets to one, then that means that
		 * window->double_status is not zero.  That means that
		 * the status line we're working on is STATUS2.
		 */
		if (status_line)
			line = 2;

		/*
		 * If status_line is zero, and window->double_status is
		 * not zero (double status line is on) then we're working
		 * on STATUS1.
		 */
		else if (window->status.double_status)
			line = 1;

		/*
		 * So status_line is zero and window->double_status is zero.
		 * So we're working on STATUS (0).
		 */
		else
			line = 0;


		/*
		 * Sanity check:  If the status format doesnt exist, dont do
		 * anything for it.
		 */
		if (!window->status.line[line].format)
			continue;

		/*
		 * Run each of the status-generating functions from the the
		 * status list.  Note that the retval of the functions is no
		 * longer malloc()ed.  This saves 40-some odd malloc/free sets
		 * each time the status bar is updated, which is non-trivial.
		 */
		for (i = 0; i < MAX_FUNCTIONS; i++)
		{
			if (window->screen == NULL)
				return -1;

			if (window->status.line[line].func[i] == NULL)
				panic("status callback null.  Window [%d], line [%d], function [%d]", window->refnum, line, i);
			func_value[i] = window->status.line[line].func[i]
				(window, window->status.line[line].map[i],
				 window->status.line[line].key[i]);
		}

		/*
		 * If the REVERSE_STATUS_LINE var is on, then put a reverse
		 * character in the first position (itll get translated to
		 * the tcap code in the output code.
		 */
		if (get_int_var(REVERSE_STATUS_LINE_VAR))
			*buffer = REV_TOG , str = buffer + 1;
		else
			str = buffer;

		/*
		 * Now press the status line into "buffer".  The magic about
		 * setting status_format is handled elsewhere.
		 */
		snprintf(str, BIG_BUFFER_SIZE - 1, window->status.line[line].format,
		    func_value[0], func_value[1], func_value[2], 
		    func_value[3], func_value[4], func_value[5],
		    func_value[6], func_value[7], func_value[8], func_value[9],
		    func_value[10], func_value[11], func_value[12],
		    func_value[13], func_value[14], func_value[15],
		    func_value[16], func_value[17], func_value[18],
		    func_value[19], func_value[20], func_value[21],
		    func_value[22], func_value[23], func_value[24],
		    func_value[25], func_value[26], func_value[27],
		    func_value[28], func_value[29], func_value[30],
		    func_value[31], func_value[32], func_value[33],
		    func_value[34], func_value[35], func_value[36], 
		    func_value[37], func_value[38], func_value[39]); 

		/*
		 * If the user wants us to, pass the status bar through the
		 * expander to pick any variables/function calls.
		 * This is horribly expensive, but what do i care if you
		 * want to waste cpu cycles? ;-)
		 */
		if (get_int_var(STATUS_DOES_EXPANDOS_VAR))
		{
			int  af = 0;
			int  old_fs = from_server;
			Window *old = current_window;
			int	owd = window_display;

			current_window = window;
			from_server = current_window->server;
			window_display = 0;
			str = expand_alias(buffer, empty_string, &af, NULL);
			window_display = owd;
			from_server = old_fs;
			current_window = old;
			strlcpy(buffer, str, sizeof buffer);
			new_free(&str);
		}


		/*
		 * This converts away any ansi codes in the status line
		 * in accordance with the currenet settings.  This leaves us
		 * with nothing but logical characters, which are then easy
		 * to count. :-)
		 */
		str = normalize_string(buffer, 3);

		/*
		 * Count out the characters.
		 * Walk the entire string, looking for nonprintable
		 * characters.  We count all the printable characters
		 * on both sides of the %> tag.
		 */
		ptr = str;
		cp = lhp;
		lhs_buffer[0] = rhs_buffer[0] = 0;

		while (*ptr)
		{
			/*
			 * The FIRST such %> tag is used.
			 * Using multiple %>s is bogus.
			 */
			if (*ptr == '\f' && start_rhs == NULL)
			{
				ptr++;
				start_rhs = ptr;
				fillchar = rhs_fillchar;
				in_rhs = 1;
				*cp = 0;
				cp = rhp;
				prc = &pr_rhs;
			}

                        /*
                         * Skip over attribute changes, not useful.
                         */
                        else if (*ptr == '\006')
                        {
                                /* Copy the next 5 values */
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                        }

			/*
			 * XXXXX This is a bletcherous hack.
			 * If i knew what was good for me id not do this.
			 */
			else if (*ptr == 9)	/* TAB */
			{
				fillchar[0] = ' ';
				fillchar[1] = 0;
				do
					*cp++ = ' ';
				while (++(*prc) % 8);
				ptr++;
			}

			/*
			 * So it is a printable character.
			 */
			else
			{
				*prc += 1;
				fillchar[0] = *cp++ = *ptr++;
				fillchar[1] = 0;
			}

			/*
			 * Dont allow more than CO printable characters
			 */
			if (pr_lhs + pr_rhs >= window->screen->co)
			{
				*cp = 0;
				break;
			}
		}
		*cp = 0;

		/* What will we be filling with? */
		if (get_int_var(STATUS_NO_REPEAT_VAR))
		{
			lhs_fillchar[0] = ' ';
			lhs_fillchar[1] = 0;
			rhs_fillchar[0] = ' ';
			rhs_fillchar[1] = 0;
		}

		/*
		 * Now if we have a rhs, then we have to adjust it.
		 */
		if (start_rhs)
		{
			int numf = 0;

			numf = window->screen->co - pr_lhs - pr_rhs -1;
			while (numf-- >= 0)
				strlcat(lhs_buffer, lhs_fillchar, 
						sizeof lhs_buffer);
		}

		/*
		 * No rhs?  If the user wants us to pad it out, do so.
		 */
		else if (get_int_var(FULL_STATUS_LINE_VAR))
		{
			int chars = window->screen->co - pr_lhs - 1;

			while (chars-- >= 0)
				strlcat(lhs_buffer, lhs_fillchar, 
						sizeof lhs_buffer);
		}

		save_size = strlen(all_off());
		strlcpy(buffer, lhs_buffer, sizeof buffer - save_size);
		strlcat(buffer, rhs_buffer, sizeof buffer - save_size);
		strlcat(buffer, all_off(), sizeof buffer);
		new_free(&str);

		/*
		 * Ends up that BitchX always throws this hook and
		 * people seem to like having this thrown in standard
		 * mode, so i'll go along with that.
		 */
		do_hook(STATUS_UPDATE_LIST, "%d %d %s", 
			window->refnum, 
			status_line, 
			buffer);

		if (dumb_mode || !foreground)
			continue;

		/*
		 * Update the status line on the screen.
		 * First check to see if it has changed
		 * Remember this is only done in full screen mode.
		 */
		if (must_redraw || !window->status.line[status_line].result ||
			strcmp(buffer, window->status.line[status_line].result))
		{
			/*
			 * Roll the new back onto the old
			 */
			malloc_strcpy(&window->status.line[status_line].result,
					buffer);

			/*
			 * Output the status line to the screen
			 */
			output_screen = window->screen;
			term_move_cursor(0, window->bottom + status_line);
			output_with_count(buffer, 1, 1);
			cursor_in_display(window);
		}
	}

	cursor_to_input();
	return 0;
}
Ejemplo n.º 19
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void	update_input (int update)
{
	int	old_zone;
	char	*ptr, *ptr_free;
	int	len,
		free_it = 0,
		max;
	char	*prompt;
	int	do_echo = 1;
	Screen	*os = last_input_screen;
	Screen	*ns;
	Window	*saved_current_window = current_window;

	/*
	 * No input line in dumb or bg mode.
	 */
	if (dumb_mode || !foreground)
		return;

  for (ns = screen_list; ns; ns = ns->next)
  {
	if (!ns->alive)
		continue;	/* It's dead, Jim! */

	last_input_screen = ns;
	current_window = ns->current_window;

	/*
	 * Make sure the client thinks the cursor is on the input line.
	 */
	cursor_to_input();

	/*
	 * See if we're in a add_wait_prompt() call.  If we are, grab that
	 * current prompt, otherwise use the default input prompt.
	 */
	if (last_input_screen->promptlist)
		prompt = last_input_screen->promptlist->prompt;
	else
		prompt = input_prompt;

	/*
	 *
	 * GET THE INPUT PROMPT
	 *
	 */

	/*
	 * If we have a prompt, and we're supposed to update the input
	 * prompt, then we do need to expand the prompt.
	 */
	if (prompt && update != NO_UPDATE)
	{
		int	af;

		/*
		 * If the current window is query'ing an exec'd process,
		 * then we just get the current prompt for that process.
		 * Note that it is not malloced.
		 */
		if (is_valid_process(get_target_by_refnum(0)) != -1)
			ptr = get_prompt_by_refnum(0);

		/*
		 * Otherwise, we just expand the prompt as normal.
		 */
		else
		{
			ptr = expand_alias(prompt, empty_string, &af, NULL);
			free_it = 1;
		}

		/*
		 * If we're in an add_wait_prompt(), we see whether or not
		 * this is an "invisible" prompt.  If it is, we turn off the
		 * echo so what the user types doesnt show up.
		 */
		if (last_input_screen->promptlist)
			term_echo(last_input_screen->promptlist->echo);

		/*
		 * Mangle out any ansi chars or so forth.
		 */
		ptr_free = ptr;
		ptr = normalize_string(ptr, 0);	/* This should be ok */
		if (free_it)
			new_free(&ptr_free);
		free_it = 1;

		/*
		 * If the prompt has changed, or if there is no prompt...
		 */
		if (	(ptr && !INPUT_PROMPT) ||
			(!ptr && INPUT_PROMPT) ||
			strcmp(ptr, INPUT_PROMPT)	)
		{
			if (last_input_screen->input_prompt_malloc)
				new_free(&INPUT_PROMPT);

			last_input_screen->input_prompt_malloc = free_it;
			INPUT_PROMPT = ptr;
			INPUT_PROMPT_LEN = output_with_count(INPUT_PROMPT, 0, 0);
			update = UPDATE_ALL;
		}
		/*
		 * Prompt didnt change, so clean up our mess
		 */
		else
		{
			if (free_it)
				new_free(&ptr);
		}
	}


	/*
	 * 
	 * HAS THE SCREEN CHANGED SIZE SINCE THE LAST TIME?
	 *
	 */

	/*
	 * If the screen has resized, then we need to re-compute the
	 * side-to-side scrolling effect.
	 */
	if ((last_input_screen->li != last_input_screen->old_li) || 
	    (last_input_screen->co != last_input_screen->old_co))
	{
		/*
		 * The input line is always the bottom line
		 */
		INPUT_LINE = last_input_screen->li - 1;

		/*
		 * The "zone" is the range in which when you type, the
		 * input line does not scroll.  It is WIDTH chars in from
		 * either side of the display.
		 */
		ZONE = last_input_screen->co - (WIDTH * 2);
		if (ZONE < 10)
			ZONE = 10;		/* Take that! */
		START_ZONE = WIDTH;
		END_ZONE = last_input_screen->co - WIDTH;

		last_input_screen->old_co = last_input_screen->co;
		last_input_screen->old_li = last_input_screen->li;
	}

	/*
	 * About zones:
	 * The input line is divided into "zones".  A "zone" is set above,
	 * and is the width of the screen minus 20 (by default).  The input
	 * line, as displayed, is therefore composed of the current "zone",
	 * plus 10 characters from the previous zone, plus 10 characters 
	 * from the next zone.  When the cursor moves to an adjacent zone,
	 * (by going into column 9 from the right or left of the edge), the
	 * input line is redrawn.  There is one catch.  The first "zone"
	 * includes the first ten characters of the input line.
	 */
	old_zone = START_ZONE;

	/*
	 * The BEGINNING of the current "zone" is a calculated value:
	 *	The number of characters since the origin of the input buffer
	 *	is the number of printable chars in the input prompt plus the
	 *	current position in the input buffer.  We subtract from that
	 * 	the WIDTH delta to take off the first delta, which doesnt
	 *	count towards the width of the zone.  Then we divide that by
	 * 	the size of the zone, to get an integer, then we multiply it
	 * 	back.  This gives us the first character on the screen.  We
	 *	add WIDTH to the result in order to get the start of the zone
	 *	itself.
	 * The END of the current "zone" is just the beginning plus the width.
	 * If we have moved to an different "zone" since last time, we want to
	 * 	completely redraw the input line.
	 */
	START_ZONE = ((INPUT_PROMPT_LEN + THIS_POS - WIDTH) / ZONE) * ZONE + WIDTH;
	END_ZONE = START_ZONE + ZONE;

	if (old_zone != START_ZONE)
		update = UPDATE_ALL;

	/*
	 * Now that we know where the "zone" is in the input buffer, we can
	 * easily calculate where where we want to start displaying stuff
	 * from the INPUT_BUFFER.  If we're in the first "zone", then we will
	 * output from the beginning of the buffer.  If we're not in the first
	 * "zone", then we will begin to output from 10 characters to the
	 * left of the zone, after adjusting for the length of the prompt.
	 */
	if (START_ZONE == WIDTH)
	    INPUT_ONSCREEN = 0;
	else {
	    if ((INPUT_ONSCREEN = START_ZONE - WIDTH - INPUT_PROMPT_LEN) < 0)
		INPUT_ONSCREEN = 0;
	}

	/*
	 * And the cursor is simply how many characters away THIS_POS is
	 * from the first column on the screen.
	 */
	if (INPUT_ONSCREEN == 0)
		INPUT_CURSOR = INPUT_PROMPT_LEN + THIS_POS;
	else
		INPUT_CURSOR = THIS_POS - INPUT_ONSCREEN;

	/*
	 * If the cursor moved, or if we're supposed to do a full update,
	 * then redraw the entire input line.
	 */
	if (update == UPDATE_ALL)
	{
		/*
		 * Move the cursor to the start of the input line
		 */
		term_move_cursor(0, INPUT_LINE);

		/*
		 * If the input line is NOT empty, and we're starting the
		 * display at the beginning of the input buffer, then we
		 * output the prompt first.
		 */
		if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT)
		{
			/*
			 * Forcibly turn on echo.
			 */
			do_echo = term_echo(1);

			/*
			 * Crop back the input prompt so it does not extend
			 * past the end of the zone.
			 */
			if (INPUT_PROMPT_LEN > (last_input_screen->co - WIDTH))
				INPUT_PROMPT_LEN = last_input_screen->co - WIDTH - 1;

			/*
			 * Output the prompt.
			 */
			output_with_count(INPUT_PROMPT, 0, 1);

			/*
			 * Turn the echo back to what it was before,
			 * and output the rest of the input buffer.
			 */
			term_echo(do_echo);
			safe_puts(INPUT_BUFFER, last_input_screen->co - INPUT_PROMPT_LEN, do_echo);
		}

		/*
		 * Otherwise we just output whatever we have.
		 */
		else if (do_echo)
			safe_puts(&(INPUT_VISIBLE), last_input_screen->co, do_echo);

		/*
		 * Clear the rest of the input line and reset the cursor
		 * to the current input position.
		 */
		term_clear_to_eol();
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * If we're just supposed to refresh whats to the right of the
	 * current logical position...
	 */
	else if (update == UPDATE_FROM_CURSOR)
	{
		/*
		 * Move the cursor to where its supposed to be,
		 * Figure out how much we can output from here,
		 * and then output it.
		 */
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		max = last_input_screen->co - (THIS_POS - INPUT_ONSCREEN);
		if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT)
			max -= INPUT_PROMPT_LEN;

		if ((len = strlen(&(THIS_CHAR))) > max)
			len = max;
		safe_puts(&(THIS_CHAR), len, do_echo);
		term_clear_to_eol();
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * If we're just supposed to move the cursor back to the input
	 * line, then go ahead and do that.
	 */
	else if (update == UPDATE_JUST_CURSOR)
	{
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * Turn the terminal echo back on, and flush all of the output
	 * we may have done here.
	 */
	term_echo(1);
	term_flush();
    }
    last_input_screen = os;
    current_window = saved_current_window;
}
Ejemplo n.º 20
0
void
reattach_tty(char *tty, char *password)
{
	int s = -1;
	char *name;
	struct sockaddr_in addr;
	struct hostent *hp;
	int len = 0;
	fd_set rd_fd;
	struct timeval tm = {0};
	char chr_c[] = "\003";

/*
 * this buffer has to be big enough to handle a full screen of
 * information from the detached process.
 */
	unsigned char buffer[6 * BIG_BUFFER_SIZE + 1];
	char *p;
	int port = 0;

#if defined (TIOCGWINSZ)
	struct winsize window;

#endif
	memset(&parm, 0, sizeof(struct param));

	if (!(name = find_detach_socket(socket_path, tty))) {
		fprintf(stderr, "No detached process to attach to.\r\n");
		_exit(1);
	}
	strcpy(parm.cookie, get_cookie(name));
	if (!*parm.cookie)
		_exit(1);
	if ((p = strrchr(name, '/')))
		p++;
	sscanf(p, "%d.%*s.%*s", &port);
	displays = 1;
	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		displays = 0;
		_exit(1);
	}
	chmod(name, SOCKMODE);
	set_socket_options(s);
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_port = htons(port);
	addr.sin_family = AF_INET;
	if ((hp = gethostbyname("localhost")))
		memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
	else
		inet_aton("127.0.0.1", (struct in_addr *)&addr.sin_addr);
	if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		fprintf(stderr, "connection refused for %s\r\n", name);
		_exit(1);
	}
	parm.pid = getpid();
	parm.pgrp = getpgrp();
	parm.uid = getuid();
	strcpy(parm.tty, ttyname(0));
	strncpy(parm.termid, getenv("TERM"), 80);
	if (password)
		strncpy(parm.password, password, 60);
	fprintf(stderr, "attempting to wakeup %s\r\n", find_tty_name(name));
#if defined (TIOCGWINSZ)
	if (ioctl(0, TIOCGWINSZ, &window) > -1) {
		parm.cols = window.ws_col;
		parm.rows = window.ws_row;
	} else
#endif
	{
		parm.cols = 79;
		parm.rows = 25;
	}
	write(s, &parm, sizeof(struct param));
	sleep(2);
	alarm(15);
	len = read(s, &parm, sizeof(struct param));
	alarm(0);
	if (len <= 0) {
		fprintf(stderr, "error reconnecting to %s\r\n", find_tty_name(name));
		displays = 0;
		chmod(name, SOCKMODE);
		exit(1);
	}
	unlink(name);

	term_init(parm.termid);
	set_term_eight_bit(1);
	charset_ibmpc();
	term_clear_screen();
	term_resize();
	term_move_cursor(0, 0);

	my_signal(SIGPIPE, handle_pipe, 0);
	my_signal(SIGINT, handle_ctrlc, 0);
	my_signal(SIGHUP, handle_hup, 0);

	/*
	 * according to MHacker we need to set errno to 0 under BSD.
	 * for some reason we get a address in use from a socket
	 *
	 */
	errno = 0;
	while (1) {
		FD_ZERO(&rd_fd);
		FD_SET(0, &rd_fd);
		FD_SET(s, &rd_fd);
		tm.tv_sec = 2;

		switch (select(s + 1, &rd_fd, NULL, NULL, &tm)) {
		case -1:
			if (ctrl_c) {
				write(s, chr_c, 1);
				ctrl_c = 0;
			} else if (errno != EINTR) {
				close(s);
				_exit(1);
			}
			break;
		case 0:
			break;
		default:
		{
			if (FD_ISSET(0, &rd_fd)) {
				len = read(0, buffer, sizeof(buffer) - 1);
				write(s, buffer, len);
			}
			if (FD_ISSET(s, &rd_fd)) {
				len = read(s, buffer, sizeof(buffer) - 1);
				write(1, buffer, len);
			}
		}
		}
	}
	close(s);
	fprintf(stderr, "Never should have got here");
	_exit(1);

	return;                         /* error return */
}
Ejemplo n.º 21
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void update_input(int update)
{
    int old_start;
    static int co = 0, li = 0;
    char *ptr;
    int len, free_it = 1, cnt, ansi_count, max;

    char *prompt;

    cursor_to_input();

    if (current_screen->promptlist)
	prompt = current_screen->promptlist->prompt;
    else
	prompt = input_prompt;
    if (prompt) {
	if (update != NO_UPDATE) {
	    char *inp_ptr = NULL;
	    int args_used;

	    if (is_process(get_target_by_refnum(0))) {
		ptr = (char *) get_prompt_by_refnum(0);
		free_it = 0;
	    } else if (!get_int_var(DISPLAY_ANSI_VAR))
		ptr = expand_alias(stripansicodes(prompt), empty_str, &args_used, NULL);
	    else
		ptr = expand_alias(prompt, empty_str, &args_used, NULL);
	    if (*ptr && ((my_strnicmp(ptr, "Password:"******"Operator Password:"******"Server Password:", 16) == 0)))
		term_echo(0);
	    else
		term_echo(1);
	    len = strlen(ptr);
	    if (strncmp(ptr, current_screen->input_buffer, len) || !len) {
		malloc_strcpy(&inp_ptr, INPUT_BUFFER + MIN_POS);
		strmcpy(INPUT_BUFFER, ptr, INPUT_BUFFER_SIZE);
		THIS_POS += (len - MIN_POS);
		MIN_POS = strlen(ptr);
		ADD_TO_INPUT(inp_ptr);
		new_free(&inp_ptr);
		update = UPDATE_ALL;
	    }

	    if (free_it)
		new_free(&ptr);
	}
    } else
	term_echo(1);

    if ((li != term_rows) || (co != term_cols)) {
	/* resized? Keep it simple and reset everything */
	input_line = term_rows - 1;
	zone = term_cols - (WIDTH * 2) + 4;
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	cursor = current_screen->buffer_min_pos;
	current_screen->buffer_pos = current_screen->buffer_min_pos;
	str_start = 0;
	li = term_rows;
	co = term_cols;
    }
    old_start = str_start;
    ansi_count = count_ansi(current_screen->input_buffer, zone);
    if (old_ansi != ansi_count || current_screen->buffer_pos - ansi_count > zone) {
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	str_start = 0;
    }
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);

    while ((current_screen->buffer_pos - ansi_count < lower_mark) && lower_mark > WIDTH) {
	upper_mark = lower_mark - ansi_count;
	lower_mark -= (zone + ansi_count);
	str_start -= (zone + ansi_count);
	if (str_start < zone) {
	    str_start = 0;
	    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
	    lower_mark -= ansi_count;
	    upper_mark -= ansi_count;
	}
    }
    while (current_screen->buffer_pos - ansi_count >= upper_mark) {
	lower_mark = upper_mark + ansi_count;
	upper_mark += zone + ansi_count;
	str_start += zone + ansi_count;
	if (ansi_count)
	    ansi_count = 0;
    }

    /* we need to count ansi characters again, this time in the part of the string we are gonna display in a few moments */
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
    old_ansi = count_ansi(current_screen->input_buffer, zone);
    /* we need to substract number of ansi characters from cursor position since those are not visible, otherwise we'd display cursor
     * in wrong place */
    cursor = current_screen->buffer_pos - str_start - ansi_count;
    if ((old_start != str_start) || (update == UPDATE_ALL)) {
	term_move_cursor(0, input_line);
	if ((str_start == 0) && (MIN_POS > 0)) {
	    int echo;

	    echo = term_echo(1);
	    if (MIN_POS > (term_cols - WIDTH))
		len = term_cols - WIDTH - 1 /* + ansi_count */ ;
	    else
		len = MIN_POS;
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), len);
	    term_echo(echo);
	    cnt += /* term_puts */ safe_puts(&(current_screen->input_buffer[
									       str_start + len]), term_cols - len + ansi_count);
	} else
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), term_cols);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_FROM_CURSOR) {
	term_move_cursor(cursor, input_line);
	cnt = cursor;
	max = term_cols - (current_screen->buffer_pos - str_start) + ansi_count;
	if ((len = strlen(&(THIS_CHAR))) > max)
	    len = max;
	cnt += /* term_puts */ safe_puts(&(THIS_CHAR), len);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_JUST_CURSOR)
	term_move_cursor(cursor, input_line);
    term_flush();
}