📄 ev_edit.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)ev_edit.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * Initialization and finalization 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 void ev_clear_from_margins();extern void ev_check_insert_visibility();extern int ev_clear_rect();extern struct rect ev_rect_for_line();unsignedev_span(views, position, first, last_plus_one, group_spec) register Ev_chain views; Es_index position, *first, *last_plus_one; int group_spec;{ struct ei_span_result span_result; char buf[EV_BUFSIZE]; struct es_buf_object esbuf; esbuf.esh = views->esh; esbuf.buf = buf; esbuf.sizeof_buf = sizeof(buf); esbuf.first = esbuf.last_plus_one = 0; span_result = ei_span_of_group( views->eih, &esbuf, group_spec, position); *first = span_result.first; *last_plus_one = span_result.last_plus_one; return(span_result.flags);}Es_indexev_line_start(view, position) register Ev_handle view; register Es_index position;{ Es_index dummy, result; register Ev_impl_line_seq seq = (Ev_impl_line_seq) view->line_table.seq; if (position >= seq[0].pos) { /* Optimization: First try the view's line_table */ int lt_index = ft_bounding_index( &view->line_table, position); if (lt_index < view->line_table.last_plus_one - 1) return(seq[lt_index].pos); /* -1 is required to avoid mapping all large positions to the * hidden extra line entry. */ } ev_span(view->view_chain, position, &result, &dummy, EI_SPAN_LINE | EI_SPAN_LEFT_ONLY); if (result == ES_CANNOT_SET) { result = position; } return(result);}Es_indexev_get_insert(views) Ev_chain views;{ return((EV_CHAIN_PRIVATE(views))->insert_pos);}Es_indexev_set_insert(views, position) Ev_chain views; Es_index position;{ Es_handle esh = views->esh; Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); Es_index result; result = es_set_position(esh, position); if (result != ES_CANNOT_SET) { private->insert_pos = result; } return(result);}extern voidev_update_lt_after_edit(table, before_edit, delta) register Ev_line_table *table; Es_index before_edit; register long int delta;{/* * Modifies the entries in table as follows: * delta > 0 => (before_edit..EOS) incremented by delta * delta < 0 => (before_edit+delta..before_edit] mapped to before_edit+delta, * (before_edit..EOS) decremented by ABS(delta). */ register lt_index; Ev_impl_line_seq line_seq = (Ev_impl_line_seq) table->seq; if (delta == 0) return; if (delta > 0) { /* * Only entries greater than before_edit are affected. In * particular, entries at the original insertion position do not * extend. */ if (before_edit < line_seq[0].pos) { ft_add_delta(*table, 0, delta); } else { lt_index = ft_bounding_index(table, before_edit); if (lt_index < table->last_plus_one) ft_add_delta(*table, lt_index+1, delta); } } else { /* * Entries in the deleted range are set to the range's beginning. * Entries greater than before_edit are simply decremented. */ ft_set_esi_span( *table, before_edit+delta+1, before_edit, before_edit+delta, 0); /* For now, let the compiler do all the cross jumping */ if (before_edit-1 < line_seq[0].pos) { ft_add_delta(*table, 0, delta); } else { lt_index = ft_bounding_index(table, before_edit-1); if (lt_index < table->last_plus_one) ft_add_delta(*table, lt_index+1, delta); } }}/* Meaning of returned ei_span_result.flags>>16 is: * 0 success * 1 illegal edit_action * 2 unable to set insert */extern struct ei_span_resultev_span_for_edit(views, edit_action) Ev_chain views; int edit_action;{ Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); struct ei_span_result span_result; int group_spec = 0; char buf[EV_BUFSIZE]; struct es_buf_object esbuf; switch (edit_action) { case EV_EDIT_BACK_CHAR: { group_spec = EI_SPAN_CHAR | EI_SPAN_LEFT_ONLY; break; } case EV_EDIT_BACK_WORD: { group_spec = EI_SPAN_WORD | EI_SPAN_LEFT_ONLY; break; } case EV_EDIT_BACK_LINE: { group_spec = EI_SPAN_LINE | EI_SPAN_LEFT_ONLY; break; } case EV_EDIT_CHAR: { group_spec = EI_SPAN_CHAR | EI_SPAN_RIGHT_ONLY; break; } case EV_EDIT_WORD: { group_spec = EI_SPAN_WORD | EI_SPAN_RIGHT_ONLY; break; } case EV_EDIT_LINE: { group_spec = EI_SPAN_LINE | EI_SPAN_RIGHT_ONLY; break; } default: { span_result.flags = 1<<16; goto Return; } } esbuf.esh = views->esh; esbuf.buf = buf; esbuf.sizeof_buf = sizeof(buf); esbuf.first = esbuf.last_plus_one = 0; span_result = ei_span_of_group( views->eih, &esbuf, group_spec, private->insert_pos); if (span_result.first == ES_CANNOT_SET) { span_result.flags = 2<<16; goto Return; } if (((group_spec & EI_SPAN_CLASS_MASK) == EI_SPAN_WORD) && (span_result.flags & EI_SPAN_NOT_IN_CLASS) && (span_result.flags & EI_SPAN_HIT_NEXT_LEVEL) == 0) { /* * On a FORWARD/BACK_WORD, skip over preceding/trailing white * space and delete the preceding word. */ struct ei_span_result span2_result; span2_result = ei_span_of_group( views->eih, &esbuf, group_spec, (group_spec & EI_SPAN_LEFT_ONLY) ? span_result.first : span_result.last_plus_one); if (span2_result.first != ES_CANNOT_SET) { if (group_spec & EI_SPAN_LEFT_ONLY) span_result.first = span2_result.first; else span_result.last_plus_one = span2_result.last_plus_one; } }Return: return(span_result);}ev_delete_span(views, first, last_plus_one, delta) Ev_chain views; register Es_index first, last_plus_one; Es_index *delta;{ Es_handle esh = views->esh; register Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); register Es_index old_length = es_get_length(esh); Es_index new_insert_pos, private_insert_pos = private->insert_pos; int result, used; /* Since *delta depends on last_plus_one, normalize ES_INFINITY */ if (last_plus_one > old_length) { last_plus_one = old_length; } /* See if operation makes sense */ if (old_length == 0) { result = 1; goto Return; } /* We cannot assume where the esh is positioned, so position first. */ if (first != es_set_position(esh, first)) { result = 2; goto Return; } new_insert_pos = es_replace(esh, last_plus_one, 0, 0, &used); if (new_insert_pos == ES_CANNOT_SET) { result = 3; goto Return; } *delta = first - last_plus_one; private->insert_pos = new_insert_pos; /* Above assignment required to make following call work! */ ev_update_after_edit( views, last_plus_one, *delta, old_length, first); if (first < private_insert_pos) { if (last_plus_one < private_insert_pos) private->insert_pos = private_insert_pos + *delta; else /* Don't optimize out in case kludge above vanishes. */ private->insert_pos = new_insert_pos; } else private->insert_pos = private_insert_pos; if (private->notify_level & EV_NOTIFY_EDIT_DELETE) { ev_notify(views->first_view, EV_ACTION_EDIT, first, old_length, first, last_plus_one, 0, 0); } result = 0;Return: return(result);}static voidev_update_fingers_after_edit(ft, insert, delta) register Ev_finger_table *ft; register Es_index insert; register int delta;/* This routine differs from the similar ev_update_lt_after_edit in that it * makes use of the extra Ev_finger_info fields in order to potentially * adjust entries at the insert point.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -