📄 ev_display.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)ev_display.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * Display of entity views. */#include <suntool/primal.h>#include <suntool/ev_impl.h>#include <sys/time.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <pixrect/pixfont.h>#include <suntool/tool.h>extern void ev_notify();extern int ev_remove_op_bdry();extern unsigned ev_op_bdry_info(), ev_op_bdry_info_merge();extern Es_index ev_line_start();extern Op_bdry_handle ev_add_op_bdry();extern struct ei_process_result ev_display_internal();/* ARGSUSED */extern voidev_note_esh_modified(views, first, last_plus_one, by) register Ev_chain views; Es_index first, last_plus_one; /* Currently unused */ int by; /* Currently unused *//* This routine must be called by clients who modify the esh associated with * the views directly, thereby allowing any cached information dependent on * the esh to be updated or invalidated. */{ register Ev_handle view; register Ev_pd_handle private; FORALLVIEWS(views, view) { private = EV_PRIVATE(view); /* For now, be overly conservative. */ private->cached_insert_info.edit_number = 0; private->cached_line_info.edit_number = 0; }}pkg_private intev_check_cached_pos_info(view, pos, cache) register Ev_handle view; register Es_index pos; register Ev_pos_info *cache;{ struct rect rect; if (!EV_CACHED_POS_INFO_IS_VALID(view, pos, cache)) { Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(view->view_chain); cache->index_of_first = EV_VIEW_FIRST(view); cache->pos = pos; cache->edit_number = chain_private->edit_number; if (pos == ES_CANNOT_SET) { cache->lt_index = EV_NOT_IN_VIEW_LT_INDEX; } else { switch (ev_xy_in_view(view, pos, &cache->lt_index, &rect)) { case EV_XY_VISIBLE: cache->pr_pos.x = rect.r_left; cache->pr_pos.y = rect_bottom(&rect); break; case EV_XY_RIGHT: cache->pr_pos.x = rect_right(&view->rect) + 1; cache->pr_pos.y = EV_NULL_DIM; break; default: cache->lt_index = EV_NOT_IN_VIEW_LT_INDEX; break; } } } return (cache->lt_index != EV_NOT_IN_VIEW_LT_INDEX);}extern intev_insert_visible_in_view(view) register Ev_handle view;{/* NOTE: EV_PRIVATE(view)->state is not updated so that calling this routine * will not invalidate the protocol for calls on ev_check_insert_visibility. */ Ev_pd_handle private = EV_PRIVATE(view); Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(view->view_chain); Es_index insert_pos; insert_pos = chain_private->insert_pos; return(ev_check_cached_pos_info(view, insert_pos, &private->cached_insert_info));}extern intev_insert_to_xy(view, x, y) register Ev_handle view; int *x, *y;{ Ev_pd_handle private = EV_PRIVATE(view); if (ev_insert_visible_in_view(view)) { *x = private->cached_insert_info.pr_pos.x; *y = private->cached_insert_info.pr_pos.y; return(TRUE); } else { return(FALSE); }}extern voidev_check_insert_visibility(views) register Ev_chain views;{/* This routine does not use ev_insert_visible_in_view to avoid procedure * call overhead, redundant field extraction and to make better use of * registers. */ register Ev_handle view; register Ev_pd_handle private; Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(views); Es_index insert_pos; insert_pos = chain_private->insert_pos; FORALLVIEWS(views, view) { private = EV_PRIVATE(view); if (ev_check_cached_pos_info(view, insert_pos, &private->cached_insert_info)) { private->state |= EV_VS_INSERT_WAS_IN_VIEW; if (rect_includespoint( &view->rect, private->cached_insert_info.pr_pos.x, private->cached_insert_info.pr_pos.y)) { private->state |= EV_VS_INSERT_WAS_IN_VIEW_RECT; } else { private->state &= ~EV_VS_INSERT_WAS_IN_VIEW_RECT; } } else { private->state &= ~(EV_VS_INSERT_WAS_IN_VIEW | EV_VS_INSERT_WAS_IN_VIEW_RECT); } }}extern voidev_blink_caret(views, on) register Ev_chain views; int on;{ struct pixrect *caret_pr; struct pr_pos hotpoint; register Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(views); register Ev_pd_handle private; register Ev_handle view; if (chain_private->caret_is_ghost) { caret_pr = chain_private->ghost_pr; hotpoint = chain_private->ghost_hotpoint; } else { caret_pr = chain_private->caret_pr; hotpoint = chain_private->caret_hotpoint; } if (on) { if (chain_private->insert_pos != ES_CANNOT_SET) { ev_check_insert_visibility(views); FORALLVIEWS(views, view) { private = EV_PRIVATE(view); if (private->state & EV_VS_INSERT_WAS_IN_VIEW_RECT) { private->caret_pr_pos.x = private->cached_insert_info.pr_pos.x - hotpoint.x; private->caret_pr_pos.y = private->cached_insert_info.pr_pos.y - hotpoint.y; pw_write(view->pw, private->caret_pr_pos.x, private->caret_pr_pos.y, caret_pr->pr_size.x, caret_pr->pr_size.y, PIX_SRC ^ PIX_DST, caret_pr, 0, 0); } } } } else { FORALLVIEWS(views, view) { private = EV_PRIVATE(view); if (private->caret_pr_pos.x != EV_NULL_DIM) { pw_write(view->pw, private->caret_pr_pos.x, private->caret_pr_pos.y, caret_pr->pr_size.x, caret_pr->pr_size.y, PIX_SRC ^ PIX_DST, caret_pr, 0, 0); private->caret_pr_pos.x = EV_NULL_DIM; private->caret_pr_pos.y = EV_NULL_DIM; } } }}#define EI_PR_OUT_OF_RANGE EI_PR_CLIENT_REASON(1)#ifdef DEBUGshort gray25[4] = { 0x8888, 0x2222, 0x4444, 0x1111 /* 25 % gray pattern */};mpr_static(gray25_pr, 16, 4, 1, gray25);#endifev_clear_rect(view, rect) Ev_handle view; register struct rect *rect;{ pw_writebackground(view->pw, rect->r_left, rect->r_top, rect->r_width, rect->r_height, PIX_SRC);}#ifdef DEBUGev_debug_clear_rect(view, rect) Ev_handle view; register struct rect *rect;{ pw_replrop(view->pw, rect->r_left, rect->r_top, rect->r_width, rect->r_height, PIX_SRC, &gray25_pr, 0, 0);}#endifev_clear_to_bottom(view, rect, new_top, clear_current_first) register Ev_handle view; register Rect *rect; int new_top; unsigned clear_current_first;{ register Ev_pd_handle private = EV_PRIVATE(view); pkg_private void ev_add_margins(); if (clear_current_first) ev_clear_rect(view, rect); rect->r_top = new_top; rect->r_left = view->rect.r_left; rect->r_width = view->rect.r_width; if (private->left_margin > 0) { ev_add_margins (view, rect); } if (private->right_margin > 0) { rect->r_width += private->right_margin; } ev_extend_to_view_bottom(view, rect); ev_clear_rect(view, rect);}/* just for ev_ft_for_rect and ev_display_internal ... */static struct ev_impl_line_data line_data = {-1, -1, -1, -1};Ev_line_tableev_ft_for_rect(eih, rect) Ei_handle eih; struct rect *rect;{ /* * The allocated line_table has an entry for every complete line in * the view, and an extra entry (hence the +1 below) for the first * entity not visible in the view (usually because it is on a * partial line, but possibly because it is below the view). */ extern Ev_line_table ft_create(); Ev_line_table result; result = FT_CLIENT_CREATE(ei_lines_in_rect(eih, rect)+1, struct ev_impl_line_seq); ft_set(result, 0, result.last_plus_one, 0, &line_data); return(result);}#define SELECTION_FOR_TYPE(chain_private, type) \ ((EV_SEL_BASE_TYPE(type) == EV_SEL_PRIMARY) \ ? (chain_private->selection) \ : (chain_private->secondary) )#define NO_SELECTION(ev_finger_id_pair) \ EV_MARK_IS_NULL(&(ev_finger_id_pair)[0])Ev_rangeev_get_selection_range(private, type, mode) Ev_chain_pd_handle private; unsigned type; int *mode;{ extern Op_bdry_handle ev_find_op_bdry(); register Op_bdry_handle obh; Ev_mark to_use; Ev_range result; /* Struct cannot be register */ ASSUME(0 < type && type < 0x34); to_use = SELECTION_FOR_TYPE(private, type); obh = ev_find_op_bdry(private->op_bdry, to_use[0]); if (obh == 0) goto BadReturn; result.first = obh->pos; if (mode) *mode = (obh->flags & EV_SEL_PENDING_DELETE); obh = ev_find_op_bdry(private->op_bdry, to_use[1]); if (obh == 0) goto BadReturn; result.last_plus_one = obh->pos; ASSERT(result.first <= result.last_plus_one); return(result);BadReturn: result.first = result.last_plus_one = ES_INFINITY; if (mode) *mode = 0; return(result);}ev_clear_selection(chain, type) Ev_chain chain; unsigned type;{ extern int ev_display_range(); register Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(chain); Ev_mark to_use; ASSUME(0 < type && type < 0x34); to_use = SELECTION_FOR_TYPE(private, type); if (!NO_SELECTION(to_use)) { Ev_range selection; selection = ev_get_selection_range(private, type, (int *)0); ev_remove_op_bdry( &private->op_bdry, selection.first, type, EV_BDRY_TYPE_ONLY); ev_remove_op_bdry( &private->op_bdry, selection.last_plus_one, type|EV_BDRY_END, EV_BDRY_TYPE_ONLY); ev_display_range( chain, selection.first, selection.last_plus_one); (void) ev_init_mark(&to_use[0]); /* Don't disturb [1] as it remembers the ids */ }}ev_view_range(view, first, last_plus_one) Ev_handle view; Es_index *first, *last_plus_one;{ register Ev_impl_line_seq seq = (Ev_impl_line_seq) view->line_table.seq; register int i; *first = seq[0].pos; if ((*last_plus_one = seq[view->line_table.last_plus_one-1].pos) == ES_INFINITY) { *last_plus_one = es_get_length(view->view_chain->esh); }}extern intev_xy_in_view(view, pos, lt_index, rect) register Ev_handle view; register Es_index pos; register int *lt_index; register Rect *rect;{ extern struct rect ev_rect_for_line(); register Ev_impl_line_seq seq = (Ev_impl_line_seq) view->line_table.seq; unsigned at_end_of_stream = 0; struct ei_process_result display_result; if (pos < seq[0].pos) return(EV_XY_ABOVE); if (pos > seq[view->line_table.last_plus_one-1].pos) return(EV_XY_BELOW); *lt_index = ft_bounding_index(&view->line_table, pos); if (pos == seq[*lt_index].pos) { if (*lt_index+1 < view->line_table.last_plus_one && seq[*lt_index+1].pos == ES_INFINITY) { at_end_of_stream = 1; } else if (*lt_index+1 == view->line_table.last_plus_one) { if (pos == es_get_length(view->view_chain->esh)) { at_end_of_stream = 1; } else { return(EV_XY_BELOW); } } if (at_end_of_stream && *lt_index > 0) (*lt_index)--; } *rect = ev_rect_for_line(view, *lt_index); if (pos != seq[*lt_index].pos || at_end_of_stream) { es_set_position(view->view_chain->esh, seq[*lt_index].pos); display_result = ev_display_internal( view, rect, *lt_index, pos, EI_OP_MEASURE, EV_QUIT); switch (display_result.break_reason) { case EI_PR_HIT_RIGHT: if (*lt_index+1 == view->line_table.last_plus_one) return(EV_XY_BELOW); else return(EV_XY_RIGHT); case EI_PR_NEWLINE: if (at_end_of_stream) { *lt_index += 1; rect->r_top += ei_line_height(view->view_chain->eih); if (rect_bottom(&view->rect) < rect_bottom(rect)) { return(EV_XY_BELOW); } break; } /* else fall through. */ default: { rect->r_width += rect->r_left - display_result.pos.x; rect->r_left = display_result.pos.x; } } } return(EV_XY_VISIBLE);}ev_display_range(chain, first, last_plus_one) Ev_chain chain; Es_index first, last_plus_one;{ register Ev_handle view; struct rect rect; int lt_index; /* Don't display a null range because * 1. We'll probably screw it up, and * 2. What's the point, anyway? */ if (first == last_plus_one) { return; } FORALLVIEWS(chain, view) { Ev_impl_line_seq line_table_seq = (Ev_impl_line_seq) view->line_table.seq; if (last_plus_one <= line_table_seq[0].pos) continue; /* Above view, nothing to do */ switch (ev_xy_in_view(view, first, <_index, &rect)) { case EV_XY_VISIBLE: { es_set_position(chain->esh, first); break; } case EV_XY_ABOVE: { rect = view->rect; lt_index = 0; es_set_position(chain->esh, line_table_seq[lt_index].pos); break; } case EV_XY_BELOW: continue; case EV_XY_RIGHT: { lt_index++; if (last_plus_one <= line_table_seq[lt_index].pos) continue; rect = ev_rect_for_line(view, lt_index); es_set_position(chain->esh, line_table_seq[lt_index].pos); break; } } ev_extend_to_view_bottom(view, &rect); (void) ev_display_internal( view, &rect, lt_index, last_plus_one, EI_OP_CLEAR_INTERIOR, 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -