📄 textsw_selection.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)textsw_selection.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * User interface to selection within text subwindows. */#include <suntool/primal.h>#include <suntool/textsw_impl.h>extern Es_index ev_line_start(), ev_resolve_xy();extern void ev_make_visible();pkg_private Seln_rank textsw_acquire_seln();externtextsw_normalize_view(abstract, pos) Textsw abstract; Es_index pos;{ Textsw_view view = VIEW_ABS_TO_REP(abstract); register Textsw_folio folio = FOLIO_FOR_VIEW(view); int upper_context; upper_context = (int)LINT_CAST( ev_get(folio->views, EV_CHAIN_UPPER_CONTEXT) ); textsw_normalize_internal(VIEW_ABS_TO_REP(abstract), pos, pos, upper_context, 0, TXTSW_NI_DEFAULT);}externtextsw_possibly_normalize(abstract, pos) Textsw abstract; Es_index pos;{ Textsw_view view = VIEW_ABS_TO_REP(abstract); register Textsw_folio folio = FOLIO_FOR_VIEW(view); int upper_context; upper_context = (int)LINT_CAST( ev_get(folio->views, EV_CHAIN_UPPER_CONTEXT) ); textsw_normalize_internal(view, pos, pos, upper_context, 0, TXTSW_NI_NOT_IF_IN_VIEW|TXTSW_NI_MARK);}externtextsw_possibly_normalize_and_set_selection( abstract, first, last_plus_one, type) Textsw abstract; Es_index first, last_plus_one; unsigned type;{ int upper_context; Textsw_view view = VIEW_ABS_TO_REP(abstract); register Textsw_folio folio = FOLIO_FOR_VIEW(view); upper_context = (int)LINT_CAST( ev_get(folio->views, EV_CHAIN_UPPER_CONTEXT) ); textsw_normalize_internal(view, first, last_plus_one, upper_context, 0, TXTSW_NI_NOT_IF_IN_VIEW|TXTSW_NI_MARK|TXTSW_NI_SELECT(type));}pkg_private inttextsw_normalize_internal( view, first, last_plus_one, upper_context, lower_context, flags) register Textsw_view view; Es_index first, last_plus_one; int upper_context, lower_context; register unsigned flags;{ Rect rect; Es_index line_start, start; int lines_above, lt_index, lines_below; int normalize = TRUE; if (flags & TXTSW_NI_NOT_IF_IN_VIEW) { switch (ev_xy_in_view(view->e_view, first, <_index, &rect)) { case EV_XY_VISIBLE: normalize = FALSE; break; case EV_XY_RIGHT: normalize = FALSE; break; default: break; } } if (normalize) { if (flags & TXTSW_NI_MARK) textsw_set_scroll_mark(VIEW_REP_TO_ABS(view)); line_start = ev_line_start(view->e_view, first); lines_below = textsw_screen_line_count(VIEW_REP_TO_ABS(view)); if (flags & TXTSW_NI_AT_BOTTOM) { lines_above = (lines_below > lower_context) ? (lines_below - (lower_context + 1)) : (lines_below - 1); } else lines_above = (upper_context < lines_below) ? upper_context : 0; if (lines_above > 0) { ev_find_in_esh(view->folio->views->esh, "\n", 1, line_start, (unsigned)lines_above+1, EV_FIND_BACKWARD, &start, &line_start); if (start == ES_CANNOT_SET) line_start = 0; } /* Ensure no caret turds will leave behind */ textsw_take_down_caret(FOLIO_FOR_VIEW(view)); ev_set_start(view->e_view, line_start); /* ensure line_start really is visible now */ lines_below -= (lines_above + 1); ev_make_visible(view->e_view, first, lines_below, 0, 0); textsw_update_scrollbars(FOLIO_FOR_VIEW(view), view); } if (EV_SEL_BASE_TYPE(flags)) { textsw_set_selection(VIEW_REP_TO_ABS(view), first, last_plus_one, EV_SEL_BASE_TYPE(flags)); }}pkg_private Es_indextextsw_set_insert(folio, pos) register Textsw_folio folio; register Es_index pos;{ extern Es_index ev_get_insert(), ev_set_insert(); register Es_index set_to; Es_index boundary; if (TXTSW_IS_READ_ONLY(folio)) { return(ev_get_insert(folio->views)); } if (TXTSW_HAS_READ_ONLY_BOUNDARY(folio)) { boundary = textsw_find_mark_internal(folio, folio->read_only_boundary); if (pos < boundary) { if AN_ERROR(boundary == ES_INFINITY) { } else return(ev_get_insert(folio->views)); } } /* Ensure timer is set to fix caret display */ textsw_take_down_caret(folio); set_to = ev_set_insert(folio->views, pos); ASSUME((pos == ES_INFINITY) || (pos == set_to)); return(set_to);}extern caddr_ttextsw_checkpoint_undo(abstract, undo_mark) Textsw abstract; caddr_t undo_mark;{ register Textsw_folio folio = FOLIO_FOR_VIEW(VIEW_ABS_TO_REP(abstract)); caddr_t current_mark; /* AGAIN/UNDO support */ if (((int)undo_mark) < TEXTSW_INFINITY-1) { current_mark = undo_mark; } else { current_mark = es_get(folio->views->esh, ES_UNDO_MARK); } if (TXTSW_DO_UNDO(folio) && (((int)undo_mark) != TEXTSW_INFINITY)) { if (current_mark != folio->undo[0]) { /* Make room for, and then record the current mark. */ bcopy((char *)(&folio->undo[0]), (char *)(&folio->undo[1]), (int)(folio->undo_count-1)*sizeof(folio->undo[0])); folio->undo[0] = current_mark; } } return(current_mark);}externtextsw_checkpoint_again(abstract) Textsw abstract;{ register Textsw_folio folio = FOLIO_FOR_VIEW(VIEW_ABS_TO_REP(abstract)); /* AGAIN/UNDO support */ if (!TXTSW_DO_AGAIN(folio)) return; if (folio->func_state & TXTSW_FUNC_AGAIN) return; folio->again_first = ES_INFINITY; folio->again_last_plus_one = ES_INFINITY; folio->again_insert_length = 0; if (TXTSW_STRING_IS_NULL(&folio->again[0])) return; if (folio->again_count > 1) { /* Make room for this action sequence. */ textsw_free_again(folio, &folio->again[folio->again_count-1]); bcopy((char *)(&folio->again[0]), (char *)(&folio->again[1]), (int)(folio->again_count-1)*sizeof(folio->again[0])); } folio->again[0] = null_string; folio->state &= ~(TXTSW_AGAIN_HAS_FIND|TXTSW_AGAIN_HAS_MATCH); }externtextsw_set_selection(abstract, first, last_plus_one, type) Textsw abstract; Es_index first, last_plus_one; unsigned type;{ extern int ev_set_selection(); register Textsw_folio folio = FOLIO_FOR_VIEW(VIEW_ABS_TO_REP(abstract)); textsw_take_down_caret(folio); type &= EV_SEL_MASK; if ((first == ES_INFINITY) && (last_plus_one == ES_INFINITY)) { ev_clear_selection(folio->views, type); return; } ev_set_selection(folio->views, first, last_plus_one, type); (void) textsw_acquire_seln(folio, seln_rank_from_textsw_info(type)); if (type & EV_SEL_PRIMARY) { (void) textsw_checkpoint_undo(abstract, (caddr_t)TEXTSW_INFINITY-1); }}pkg_private Textsw_viewtextsw_view_for_entity_view(folio, e_view) Textsw_folio folio; Ev_handle e_view;/* It is okay for the caller to pass EV_NULL for e_view. */{ register Textsw_view textsw_view; FORALL_TEXT_VIEWS(folio, textsw_view) { if (textsw_view->e_view == e_view) return(textsw_view); } return((Textsw_view)0);}static intupdate_selection(view, ie) Textsw_view view; register Event *ie;{ register Textsw_folio folio = FOLIO_FOR_VIEW(view); register unsigned sel_type; register Es_index position; Es_index first, last_plus_one, ro_bdry; position = ev_resolve_xy(view->e_view, ie->ie_locx, ie->ie_locy); if (position == ES_INFINITY) return; sel_type = textsw_determine_selection_type(folio, TRUE); if (position == es_get_length(folio->views->esh)) { /* Check for and handle case of empty textsw. */ if (position == 0) { last_plus_one = 0; goto Do_Update; } position--; /* ev_span croaks if passed EOS */ } if (folio->track_state & TXTSW_TRACK_POINT) { if (folio->span_level == EI_SPAN_CHAR) { last_plus_one = position+1; } else { ev_span(folio->views, position, &first, &last_plus_one, (int)folio->span_level); ASSERT(first != ES_CANNOT_SET); position = first; } } else { unsigned save_span_level = folio->span_level; /* * Adjust */ if (event_action(ie) != LOC_MOVE) { (void) ev_get_selection(folio->views, &first, &last_plus_one, sel_type); if (first >= last_plus_one) { /* * Treat Adjust without prior selection as if it was * Point then Adjust. */ first = position; last_plus_one = position+1; } if ((position == first) || (position+1 == last_plus_one)) { folio->track_state |= TXTSW_TRACK_ADJUST_END; } else folio->track_state &= ~TXTSW_TRACK_ADJUST_END; folio->adjust_pivot = ( position < (last_plus_one+first)/2 ? last_plus_one: first); } if (folio->track_state & TXTSW_TRACK_ADJUST_END) /* Adjust-from-end is char-adjust */ folio->span_level = EI_SPAN_CHAR; if ((folio->state & TXTSW_ADJUST_IS_PD) && (sel_type & EV_SEL_PRIMARY)) { if (folio->state & TXTSW_CONTROL_DOWN) sel_type &= ~EV_SEL_PD_PRIMARY; else sel_type |= EV_SEL_PD_PRIMARY; } if (position < folio->adjust_pivot) { /* There is nothing to the left of position == 0! */ if (position > 0) { /* Note: * span left only finds the left portion of what * the entire span would be. * The position between lines is ambiguous: is it * at the end of the previous line or the beginning * of the next? * EI_SPAN_WORD treats it as being at the end of * the inter-word space terminated by newline. * EI_SPAN_LINE treats it as being at the start of * the following line. */ switch(folio->span_level) { case EI_SPAN_CHAR: break; case EI_SPAN_WORD: ev_span(folio->views, position+1, &first, &last_plus_one, (int)folio->span_level | EI_SPAN_LEFT_ONLY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -