⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttyselect.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lint#ifdef sccsstatic char	    sccsid[] = "@(#)ttyselect.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc.  */#include <signal.h>#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/file.h>#include <sys/time.h>#include <sundev/kbd.h>#include <pixrect/pixrect.h>#include <pixrect/pixfont.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/cms.h>#include <sunwindow/pixwin.h>#include <sunwindow/win_input.h>#include <suntool/tool.h>#include <suntool/selection.h>#include <suntool/selection_svc.h>#include <suntool/selection_attributes.h>#include <suntool/ttysw.h>#include <suntool/ttysw_impl.h>#include <suntool/ttyansi.h>#include <suntool/charimage.h>#include <suntool/charscreen.h>#define MIN_SELN_TIMEOUT        0#define DEFAULT_SELN_TIMEOUT    10		/* 10 seconds */#define MAX_SELN_TIMEOUT        300		/* 5 minutes *//*	global which can be used to make a shell tool which *	doesn't talk to the service */int			ttysel_use_seln_service = 1;/*	global & private procedures	*/void			ttyhiliteselection();static void		tvsub(),			ttycountchars(),			ttyenumerateselection(),			ttyhiliteline(),			ttysel_empty(),			ttysel_resolve(),			ttysortextents(),			ttysel_read(),			ttysel_write(),			ttyputline(),			ttysel_function(),			ttysel_end_request();static int		ttysel_insel(),			ttysel_eq();static Seln_result	ttysel_copy_in(),			ttysel_copy_out(),			ttysel_reply();static struct ttyselection *			ttysel_from_rank();struct ttysel_context {    unsigned              continued;    struct ttysubwindow  *ttysw;    unsigned              bytes_left;};#define	SEL_NULLPOS	-1#define	TSE_NULL_EXTENT	{SEL_NULLPOS, SEL_NULLPOS}static struct textselpos tse_null_extent = TSE_NULL_EXTENT;static struct ttyselection ttysw_nullttysel = {   0, 0, SEL_CHAR, 0, TSE_NULL_EXTENT, TSE_NULL_EXTENT, {0, 0}};static struct ttysubwindow *ttysel_ttysw;	/* stash for ttysel_read   */static struct ttyselection *ttysel_ttysel;	/* stash for ttysel_write  */static struct timeval maxinterval = {0, 400000};	/* XXX - for now */static char		*ttysel_filename = "/tmp/ttyselection";intttysw_is_seln_nonzero(ttysw, rank)    register struct ttysubwindow  *ttysw;    Seln_rank	rank;{    Seln_holder 	holder;    Seln_request	*req_buf;    char		**argv;    int			bytesize = 0;    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	return 0;    }    holder = seln_inquire(rank);    if (holder.state != SELN_NONE) {	req_buf = seln_ask(&holder, SELN_REQ_BYTESIZE, 0, 0);	argv = (char **)LINT_CAST(req_buf->data);	if (*argv++ == (char *)SELN_REQ_BYTESIZE) {	    bytesize = (int)*argv;	}    }    return bytesize;}/* * init_client:  */voidttysel_init_client(ttysw)    register struct ttysubwindow  *ttysw;{   int          selection_timeout;    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	return;    }    ttysw->ttysw_caret = ttysw_nullttysel;    ttysw->ttysw_primary = ttysw_nullttysel;    ttysw->ttysw_secondary = ttysw_nullttysel;    ttysw->ttysw_shelf = ttysw_nullttysel;   selection_timeout = defaults_get_integer_check("/SunView/Selection_Timeout",		DEFAULT_SELN_TIMEOUT, MIN_SELN_TIMEOUT, MAX_SELN_TIMEOUT, 0);   seln_use_timeout(selection_timeout);		/* set selection timeout */    ttysw->ttysw_seln_client =	seln_create(ttysel_function, ttysel_reply, (char *) ttysw);    if (ttysw->ttysw_seln_client == (char *) NULL) {	(void)ttysw_setopt((caddr_t)ttysw, TTYOPT_SELSVC, FALSE);    }}voidttysel_destroy(ttysw)    register struct ttysubwindow  *ttysw;{    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	return;    }    if (ttysw->ttysw_seln_client != (char *) NULL) {	seln_destroy(ttysw->ttysw_seln_client);	ttysw->ttysw_seln_client = (char *) NULL;    }}/* * Make sure we have desired selection.  */voidttysel_acquire(ttysw, sel_desired)    register struct ttysubwindow  *ttysw;    register Seln_rank             sel_desired;{    register Seln_rank             sel_received;    register struct ttyselection  *ttysel;    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	return;    }    ttysel = ttysel_from_rank(ttysw, sel_desired);    if (!ttysel->sel_made) {	if (sel_desired == SELN_CARET) {	    Seln_holder		    holder;	    holder = seln_inquire(SELN_UNSPECIFIED);	    if (holder.rank != SELN_PRIMARY)		return;	}	sel_received = seln_acquire(ttysw->ttysw_seln_client, sel_desired);	if (sel_received == sel_desired) {	    ttysel->sel_made = TRUE;	    ttysel_empty(ttysel);	} else {	    (void)seln_done(ttysw->ttysw_seln_client, sel_received);	}    }}/* * Return rank of global selection state. */Seln_rankttysel_mode(ttysw)    struct ttysubwindow  *ttysw;{    Seln_holder             	   sel_holder;    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	return SELN_PRIMARY;    } else {        sel_holder = seln_inquire(SELN_UNSPECIFIED);	return sel_holder.rank;    }}/* * Make a new selection. If multi is set, check for multi-click.  */voidttysel_make(ttysw, event, multi)    register struct ttysubwindow  *ttysw;    register struct inputevent    *event;    int                   multi;{    register Seln_rank             sel_received;    register struct ttyselection  *ttysel;    struct textselpos     tspb, tspe;    struct timeval        td;    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	sel_received = SELN_PRIMARY;    } else {	sel_received =	    seln_acquire(ttysw->ttysw_seln_client, SELN_UNSPECIFIED);    }    if (sel_received == SELN_PRIMARY) {	ttysel = &ttysw->ttysw_primary;	if (ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC)) {	    ttysel_acquire(ttysw, SELN_CARET);	    	}	if (ttysw->ttysw_secondary.sel_made) {	    (void)ttysel_cancel(ttysw, SELN_SECONDARY);	/* insurance  */	}    } else if (sel_received == SELN_SECONDARY) {	ttysel = &ttysw->ttysw_secondary;    } else {	return;    }    ttysel_resolve(&tspb, &tspe, SEL_CHAR, event);    if (multi && ttysel->sel_made) {	tvsub(&td, &event->ie_time, &ttysel->sel_time);	if (ttysel_insel(ttysel, &tspe) && timercmp(&td, &maxinterval, <)) {	    (void)ttysel_adjust(ttysw, event, 1);	    return;	}    }    if (ttysel->sel_made)	ttysel_deselect(ttysel, sel_received);    ttysel->sel_made = TRUE;    ttysel->sel_begin = tspb;    ttysel->sel_end = tspe;    ttysel->sel_time = event->ie_time;    ttysel->sel_level = SEL_CHAR;    ttysel->sel_anchor = 0;    ttysel->sel_null = FALSE;    ttyhiliteselection(ttysel, sel_received);}/* * Move the current selection.  */voidttysel_move(ttysw, event)    register struct ttysubwindow  *ttysw;    register struct inputevent    *event;{    register Seln_rank             rank;    register struct ttyselection  *ttysel;    struct textselpos     tspb, tspe;    if (ttysw->ttysw_secondary.sel_made) {	rank = SELN_SECONDARY;	ttysel = &ttysw->ttysw_secondary;    } else if (ttysw->ttysw_primary.sel_made) {	rank = SELN_PRIMARY;	ttysel = &ttysw->ttysw_primary;    } else {	return;    }    ttysel_resolve(&tspb, &tspe, ttysel->sel_level, event);    ttyhiliteselection(ttysel, rank);    ttysel->sel_begin = tspb;    ttysel->sel_end = tspe;    ttysel->sel_time = event->ie_time;    ttysel->sel_anchor = 0;    ttysel->sel_null = FALSE;    ttyhiliteselection(ttysel, rank);}/* * Adjust the current selection according to the event. * If multi is set, check for multi-click.  */ttysel_adjust(ttysw, event, multi)    register struct ttysubwindow  *ttysw;    struct inputevent    *event;    int                   multi;{    register struct textselpos *tb;    register struct textselpos *te;    Seln_rank             rank;    int                   count;    int                   extend = 0;    struct textselpos     tspc, tspb, tspe, tt;    struct ttyselection  *ttysel;    struct timeval        td;    if (ttysw->ttysw_secondary.sel_made) {	rank = SELN_SECONDARY;	ttysel = &ttysw->ttysw_secondary;    } else if (ttysw->ttysw_primary.sel_made) {	rank = SELN_PRIMARY;	ttysel = &ttysw->ttysw_primary;    } else {	return;    }    tb = &ttysel->sel_begin;    te = &ttysel->sel_end;    if (!ttysel->sel_made || ttysel->sel_null)	return;    ttysel_resolve(&tspb, &tspc, SEL_CHAR, event);    if (multi) {	tvsub(&td, &event->ie_time, &ttysel->sel_time);	if (ttysel_insel(ttysel, &tspc) && timercmp(&td, &maxinterval, <)) {	    extend = 1;	    if (++ttysel->sel_level > SEL_MAX) {		ttysel->sel_level = SEL_CHAR;		extend = 0;	    }	}	ttysel->sel_time = event->ie_time;	ttysel->sel_anchor = 0;    }    ttysel_resolve(&tspb, &tspe, ttysel->sel_level, event);    /*     * If inside current selection, pull in closest end.      */    if (!extend && ttysel_insel(ttysel, &tspc)) {	int                   left_end, right_end;	if (ttysel->sel_anchor == 0) {	    /* count chars to left */	    count = 0;	    tt = *te;	    *te = tspc;	    ttyenumerateselection(ttysel, ttycountchars, (char *)(&count));	    *te = tt;	    left_end = count;	    /* count chars to right */	    count = 0;	    tt = *tb;	    *tb = tspc;	    ttyenumerateselection(ttysel, ttycountchars, (char *)(&count));	    *tb = tt;	    right_end = count;	    if (right_end <= left_end)		ttysel->sel_anchor = -1;	    else		ttysel->sel_anchor = 1;	}	if (ttysel->sel_anchor == -1) {	    if (!ttysel_eq(te, &tspe)) {		/* pull in right end */		tt = *tb;		*tb = tspe;		tb->tsp_col++;		ttyhiliteselection(ttysel, rank);		*tb = tt;		*te = tspe;	    }	} else {	    if (!ttysel_eq(tb, &tspb)) {		/* pull in left end */		tt = *te;		*te = tspb;		te->tsp_col--;		ttyhiliteselection(ttysel, rank);		*te = tt;		*tb = tspb;	    }	}    } else {	/*	 * Determine which end to extend. Both ends may extend if selection	 * level has increased. 	 */	int                   newanchor = 0;	if (tspe.tsp_row > te->tsp_row ||	    tspe.tsp_row == te->tsp_row && tspe.tsp_col > te->tsp_col) {	    /* extend right end */	    if (ttysel->sel_anchor == 1) {		ttysel->sel_anchor = -1;		ttyhiliteselection(ttysel, rank);		*tb = *te;		ttyhiliteselection(ttysel, rank);	    } else if (ttysel->sel_anchor == 0)		newanchor = -1;	    tt = *tb;	    *tb = *te;	    tb->tsp_col++;	       /* check for overflow? */	    *te = tspe;	    ttyhiliteselection(ttysel, rank);	    *tb = tt;	}	if (tspb.tsp_row < tb->tsp_row ||	    tspb.tsp_row == tb->tsp_row && tspb.tsp_col < tb->tsp_col) {	    /* extend left end */	    if (ttysel->sel_anchor == -1) {		ttysel->sel_anchor = 1;		ttyhiliteselection(ttysel, rank);		*te = *tb;		ttyhiliteselection(ttysel, rank);	    } else if (ttysel->sel_anchor == 0)		if (newanchor == 0)		    newanchor = 1;		else		    newanchor = 0;	    tt = *te;	    *te = *tb;	    te->tsp_col--;	       /* check for underflow? */	    *tb = tspb;	    ttyhiliteselection(ttysel, rank);	    *te = tt;	}	if (ttysel->sel_anchor == 0)	    ttysel->sel_anchor = newanchor;    }}/* * Clear out the current selection.  */ttysel_cancel(ttysw, rank)    register struct ttysubwindow  *ttysw;    Seln_rank             rank;{    struct ttyselection  *ttysel;    switch (rank)  {      case SELN_CARET:	ttysel = &ttysw->ttysw_caret;	break;      case SELN_PRIMARY:	ttysel = &ttysw->ttysw_primary;	break;      case SELN_SECONDARY:	ttysel = &ttysw->ttysw_secondary;	break;      case SELN_SHELF:	ttysel = &ttysw->ttysw_shelf;	break;      default:	return;    }    if (!ttysel->sel_made)	return;    ttysel_deselect(ttysel, rank);    ttysel->sel_made = FALSE;    if (!ttysw_getopt((caddr_t)ttysw, TTYOPT_SELSVC))	(void)seln_done(ttysw->ttysw_seln_client, rank);}/* XXX - compatibility kludge */voidttynullselection(ttysw)    struct ttysubwindow	*ttysw;{    (void)ttysel_cancel(ttysw, SELN_PRIMARY);}/* * Remove a selection from the screen  */voidttysel_deselect(ttysel, rank)    register struct ttyselection  *ttysel;    Seln_rank             rank;{    if (!ttysel->sel_made)	return;    ttyhiliteselection(ttysel, rank);    if (!ttysel->sel_null)	ttysel_empty(ttysel);}/* * check all selections, and hilite any that exist  */voidttysel_hilite(ttysw)    register struct ttysubwindow  *ttysw;{/*    struct ttyselection  *ttysel;  Delete this? */    if (ttysw->ttysw_primary.sel_made)	ttyhiliteselection(&ttysw->ttysw_primary, SELN_PRIMARY);    if (ttysw->ttysw_secondary.sel_made)	ttyhiliteselection(&ttysw->ttysw_secondary, SELN_SECONDARY);}/* * Hilite a selection. * Enumerate all the lines of the selection; hilite each one as appropriate.  */voidttyhiliteselection(ttysel, rank)    register struct ttyselection  *ttysel;    Seln_rank             rank;{    struct pr_size        offsets;    if (!ttysel->sel_made || ttysel->sel_null) {	return;    }    switch (rank) {      case SELN_SECONDARY:	offsets.x = (chrheight + chrbase) / 2;	offsets.y = 1;	break;      case SELN_PRIMARY:	offsets.x = 0;	offsets.y = chrheight;    }    ttyenumerateselection(ttysel, ttyhiliteline, (char *)(&offsets));}/* * Set local selection as global one.  */voidttysetselection(ttysw)    register struct ttysubwindow  *ttysw;{    int                   count;    struct selection      selection;    struct ttyselection  *ttysel;    if (ttysw->ttysw_secondary.sel_made ||	!ttysw->ttysw_primary.sel_made)	return;    ttysel = &ttysw->ttysw_primary;    ttysel_ttysel = ttysel;	       /* stash for ttysel_write	 */    selection = selnull;    selection.sel_type = SELTYPE_CHAR;    count = 0;    ttyenumerateselection(ttysel, ttycountchars, (char *)(&count));    selection.sel_items = count;    selection.sel_itembytes = 1;    selection.sel_pubflags = SEL_PRIMARY;    selection.sel_privdata = 0;    (void)selection_set(&selection, (int (*)())(LINT_CAST(ttysel_write)),     	(int (*)())0, ttysw->ttysw_wfd);}/* * Read global selection into input stream.  */voidttygetselection(ttysw)    struct ttysubwindow  *ttysw;{    ttysel_ttysw = ttysw;	       /* stash for ttysel_read	 */    (void)selection_get((int (*)())(LINT_CAST(ttysel_read)), ttysw->ttysw_wfd);}/* internal (static) routines	 *//* *	convert from a selection rank to a ttysel struct */static struct ttyselection *ttysel_from_rank(ttysw, rank)    struct ttysubwindow  *ttysw;    Seln_rank		  rank;{    switch (rank) {      case SELN_CARET:	return &ttysw->ttysw_caret;      case SELN_PRIMARY:	return &ttysw->ttysw_primary;      case SELN_SECONDARY:	return &ttysw->ttysw_secondary;      case SELN_SHELF:	return &ttysw->ttysw_shelf;      default:	break;    }    return (struct ttyselection *) NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -