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

📄 textsw_seln_svc.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)textsw_seln_svc.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986, 1987 by Sun Microsystems, Inc. *//* * Textsw interface to selection service. */#include <errno.h>#include <suntool/primal.h>#include <suntool/textsw_impl.h>#include <suntool/alert.h>#include <suntool/frame.h>#include "sunwindow/sv_malloc.h"extern int	 errno;extern Es_status	es_copy();static Seln_result	textsw_seln_yield();char		*shelf_name = "/tmp/textsw_shelf";#define	SAME_HOLDER(folio, holder)				\	seln_holder_same_client(holder, folio->first_view)typedef struct continuation {	int		in_use, type;	Es_index	current, first, last_plus_one;	unsigned	span_level;} Continuation_object;typedef Continuation_object *	Continuation;static Continuation_object	fast_continuation; /* Default init to zeros */pkg_private voidtextsw_clear_secondary_selection(textsw, type)	register Textsw_folio	textsw;	unsigned		type;{	if (type & EV_SEL_SECONDARY) {	    if (type & TFS_IS_OTHER) {		Seln_holder	holder;		holder = seln_inquire(SELN_SECONDARY);		if (holder.state != SELN_NONE)		    (void) seln_ask(&holder,				    SELN_REQ_YIELD, 0,				    0);	    } else {		textsw_set_selection(VIEW_REP_TO_ABS(textsw->first_view),				     ES_INFINITY, ES_INFINITY, type);	    }	}}static unsignedholder_flag_from_seln_rank(rank)	register Seln_rank	rank;{	switch (rank) {	  case SELN_CARET:	    return(TXTSW_HOLDER_OF_CARET);	  case SELN_PRIMARY:	    return(TXTSW_HOLDER_OF_PSEL);	  case SELN_SECONDARY:	    return(TXTSW_HOLDER_OF_SSEL);	  case SELN_SHELF:	    return(TXTSW_HOLDER_OF_SHELF);	  case SELN_UNSPECIFIED:	    return(0);	  default:	    LINT_IGNORE(ASSUME(0));	    return(0);	}}static unsignedev_sel_type_from_seln_rank(rank)	register Seln_rank	rank;{	switch (rank) {	  case SELN_CARET:	    return(EV_SEL_CARET);	  case SELN_PRIMARY:	    return(EV_SEL_PRIMARY);	  case SELN_SECONDARY:	    return(EV_SEL_SECONDARY);	  case SELN_SHELF:	    return(EV_SEL_SHELF);	  default:	    LINT_IGNORE(ASSUME(0));	    return(0);	}}static unsignedholder_flag_from_textsw_info(type)	register unsigned	type;{	if (type & EV_SEL_CARET)	    return(TXTSW_HOLDER_OF_CARET);	if (type & EV_SEL_PRIMARY)	    return(TXTSW_HOLDER_OF_PSEL);	if (type & EV_SEL_SECONDARY)	    return(TXTSW_HOLDER_OF_SSEL);	if (type & EV_SEL_SHELF)	    return(TXTSW_HOLDER_OF_SHELF);	return(0);}pkg_private Seln_rankseln_rank_from_textsw_info(type)	register unsigned	type;{	if (type & EV_SEL_CARET)	    return(SELN_CARET);	if (type & EV_SEL_PRIMARY)	    return(SELN_PRIMARY);	if (type & EV_SEL_SECONDARY)	    return(SELN_SECONDARY);	if (type & EV_SEL_SHELF)	    return(SELN_SHELF);	return(SELN_UNKNOWN);}/* The following acquires the selection of the specified rank unless the *   textsw already holds it. */pkg_private Seln_ranktextsw_acquire_seln(textsw, rank)	register Textsw_folio	textsw;	register Seln_rank	rank;{	unsigned		holder_flag;	if (textsw_should_ask_seln_svc(textsw, TRUE)) {	    if ((textsw->holder_state & holder_flag_from_seln_rank(rank)) == 0) {		rank = seln_acquire(textsw->selection_client, rank);	    }	} else if (rank == SELN_UNSPECIFIED) {	    textsw->holder_state |= TXTSW_HOLDER_OF_ALL;	    return(SELN_UNKNOWN);		/* Don't fall through as that will bump time-of-death */	}	holder_flag = holder_flag_from_seln_rank(rank);	if (holder_flag) {	    textsw->holder_state |= holder_flag;	} else {            Event   alert_event;	    int	result;	    /* Assume svc temporarily dead, but make sure timer is set before	     * calling textsw_post_error because it will result in a recursive	     * call on this routine via textsw_may_win_exit if the timer is	     * clear.	     */	    gettimeofday(&textsw->selection_died, (struct timezone *)0);             result = alert_prompt(                    (Frame)window_get(WINDOW_FROM_VIEW(textsw), WIN_OWNER),                    &alert_event,                    ALERT_MESSAGE_STRINGS,                        "Cannot contact Selection Service - pressing",                        " on but selections across windows may not work.",                        0,                        ALERT_BUTTON_YES, "Continue",                    0);            if (result == ALERT_FAILED) {                    fprintf(stderr,                        "ALERT_FAILED!\nCannot contact Selection Service - pressing on but selections across windows may not work.\n");            }	    textsw->holder_state |= TXTSW_HOLDER_OF_ALL;	}	return(rank);}/*	========================================================== * *	Routines to support the use of selections. * *	========================================================== */#define	TXTSW_NEED_SELN_CLIENT	(Seln_client)1#define MIN_SELN_TIMEOUT        0#define DEFAULT_SELN_TIMEOUT    10		/* 10 seconds */#define MAX_SELN_TIMEOUT        300		/* 5 minutes */static inttextsw_should_ask_seln_svc(textsw, retry_okay)	register Textsw_folio	textsw;	int			retry_okay;{	pkg_private void	textsw_seln_svc_function();	pkg_private Seln_result	textsw_seln_svc_reply();	struct timeval		now;	int     		result;	Event   		alert_event;	int          selection_timeout;	if (textsw->state & TXTSW_DELAY_SEL_INQUIRE) {	    textsw->state &= ~TXTSW_DELAY_SEL_INQUIRE;	    return(textsw_sync_with_seln_svc(textsw));	}		if (textsw->selection_client == 0)	    return(FALSE);	if (timerisset(&textsw->selection_died)) {	    if (!retry_okay)		return(FALSE);	    /* Retry if contact lost at least 60 seconds ago */	    gettimeofday(&now, (struct timezone *)0);	    if (now.tv_sec < textsw->selection_died.tv_sec + 60)		return(FALSE);	    /* textsw_post_error will eventually call textsw_may_win_exit	     * which will call textsw_should_ask_seln_svc (with retry_okay set	     * to FALSE), but we must make sure that the timer is still set	     * on that recursive call, so don't clear it until AFTER	     * textsw_post_error returns!	     */            result = alert_prompt(                    (Frame)window_get(WINDOW_FROM_VIEW(textsw), WIN_OWNER),                    &alert_event,                    ALERT_MESSAGE_STRINGS,                        "textsw: attempting to re-contact Selection Service",                        " - selections may be temporarily incorrect.",                        0,                    ALERT_BUTTON_YES, "Continue",                    0);            if (result == ALERT_FAILED) {		    fprintf(stderr,"ALERT_FAILED!\ntextsw: attempting to re-contact Selection Service - selections may be temporarily incorrect.\n");            }	    timerclear(&textsw->selection_died);	}			if (textsw->selection_client == TXTSW_NEED_SELN_CLIENT) {    	    	   	    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 */	    /* Try to establish the initial connection with Seln. Svc. */	    textsw->selection_client = seln_create(		textsw_seln_svc_function, textsw_seln_svc_reply,		(caddr_t)LINT_CAST(textsw->first_view));	    if (textsw->selection_client == 0) {                int     result;                Event   alert_event; 		/* Set up to retry later and then tell user we lost. */		textsw->selection_client = TXTSW_NEED_SELN_CLIENT;		gettimeofday(&textsw->selection_died, (struct timezone *)0);                    result = alert_prompt(                        (Frame)window_get(WINDOW_FROM_VIEW(textsw), WIN_OWNER),                        &alert_event,                        ALERT_MESSAGE_STRINGS,                            "textsw: cannot initiate contact with Selection",                            " Service; pressing on and will retry later",                            0,                        ALERT_BUTTON_YES, "Continue",                        0);                if (result == ALERT_FAILED) {		    fprintf(stderr,"ALERT_FAILED!\ntextsw: cannot initiate contact with Selection Service; pressing on and will retry later\n");                }		return(FALSE);	    }	}	return(TRUE);}pkg_private unsignedtextsw_determine_selection_type(textsw, acquire)	register Textsw_folio	textsw;	int			acquire;{	register unsigned	result;	register int		ask_svc =				textsw_should_ask_seln_svc(textsw, TRUE);	register Seln_rank	rank;	Seln_holder		holder;	if (textsw->holder_state & TXTSW_HOLDER_OF_SSEL) {	    if ((textsw->holder_state & TXTSW_HOLDER_OF_ALL) ==	        TXTSW_HOLDER_OF_ALL) {		ask_svc = 0;	    } else {		Firm_event	focus;		int		shift;		if (!win_get_focus_event(WIN_FD_FOR_VIEW(textsw->first_view),					 &focus, &shift)) {		    ask_svc = (focus.id != LOC_WINENTER);		}	    }	    if (!ask_svc)		result = (textsw->track_state & TXTSW_TRACK_SECONDARY)			 ? EV_SEL_SECONDARY : EV_SEL_PRIMARY;	}#ifdef DEBUG_SVCfprintf(stderr, "Holders: %d%s", textsw->holder_state & TXTSW_HOLDER_OF_ALL,	(ask_svc) ? "\t" : "\n");#endif	if (ask_svc) {	    if (acquire == 0) {		holder = seln_inquire(SELN_UNSPECIFIED);		result = (holder.rank == SELN_SECONDARY)			 ? EV_SEL_SECONDARY : EV_SEL_PRIMARY;	    } else {		rank = textsw_acquire_seln(textsw, SELN_UNSPECIFIED);#ifdef DEBUG_SVCfprintf(stderr, "textsw_acquire_seln returned rank = %d\n", (int)rank);#endif		switch (rank) {		  case SELN_PRIMARY:		    result = EV_SEL_PRIMARY;		    textsw->track_state &= ~TXTSW_TRACK_SECONDARY;		    break;		  case SELN_SECONDARY:		    result = EV_SEL_SECONDARY;		    textsw->track_state |= TXTSW_TRACK_SECONDARY;		    if (textsw->func_state) {		    } else if (seln_get_function_state(SELN_FN_DELETE)) {			/* Act as if it was local DELETE down */			textsw->func_state |=			    TXTSW_FUNC_DELETE|			    TXTSW_FUNC_SVC_SAW(TXTSW_FUNC_DELETE);			if (!TXTSW_IS_READ_ONLY(textsw))			    textsw->state |= TXTSW_PENDING_DELETE;		    } else if (seln_get_function_state(SELN_FN_PUT)) {			/* Act as if it was local PUT down */			textsw_begin_put(textsw->first_view, 0);			textsw->func_state |=			    TXTSW_FUNC_SVC_SAW(TXTSW_FUNC_PUT);		    }		    break;		  default:		/* Assume svc temporarily dead */		    result = EV_SEL_PRIMARY;		    break;		}	    }	} else if (textsw->selection_client == 0) {	    textsw->holder_state |= TXTSW_HOLDER_OF_ALL;	}	if (textsw->state & TXTSW_PENDING_DELETE) {	    result |= (textsw->track_state & TXTSW_TRACK_SECONDARY)			? EV_SEL_PD_SECONDARY : EV_SEL_PD_PRIMARY;	}	return(result);}/* For function keys that deal with selections, the following cases must be *   considered as plausible: * No primary selection *    (See below for subcases) * Primary selection in window A (our window) *    FN key DOWN in window A *	No secondary selection *	  FN key UP in window A *	  FN key UP in window B (some other window) *	Secondary selection in window A *	  FN key UP in window A *	  FN key UP in window B *	Secondary selection in window B *	  FN key UP in window A *	  FN key UP in window B *    FN key DOWN in window B *	No secondary selection *	  FN key UP in window A *	  FN key UP in window B *	Secondary selection in window A *	  FN key UP in window A *	  FN key UP in window B *	Secondary selection in window B *	  FN key UP in window A *	  FN key UP in window B * Primary selection in window B *    (See above for subcases) * * On the FN key UP, the cases can be viewed as: *    DOWN in same window  => inform service iff informed it about DOWN *    DOWN in other window => inform other window via service * * Window that is to process FN key (assumed to be holder of Primary *   selection) has three UP cases to deal with: *    UP in this window, service not informed => *	process directly/locally, any Secondary selection is local *    UP in this window, service informed (by this window) || *    UP in other window =>

⌨️ 快捷键说明

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