Files
Arquivotheca.SunOS-4.1.4/usr.lib/libsuntool/text/ev_attr.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

464 lines
12 KiB
C

#ifndef lint
#ifdef sccs
static char sccsid[] = "@(#)ev_attr.c 1.1 94/10/31";
#endif
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
/*
* Attribute set/get routines for entity views.
*/
#include <suntool/primal.h>
#include <suntool/ev_impl.h>
#include <varargs.h>
static Ev_status ev_set_internal();
static void ev_set_rect();
pkg_private void ev_flush_view_caches();
#define SET_BOOL_FLAG(flags, to_test, flag) \
if ((unsigned)(to_test) != 0) (flags) |= (flag); \
else (flags) &= ~(flag)
/* VARARGS */
extern caddr_t
ev_get(view, attribute, args1, args2, args3)
Ev_handle view;
Ev_attribute attribute;
caddr_t args1, args2, args3;
{
register Ev_pd_handle private = EV_PRIVATE(view);
Ev_chain chain;
Ev_chain_pd_handle chain_private;
switch (attribute) {
case EV_CHAIN_AUTO_SCROLL_BY:
case EV_CHAIN_CARET:
case EV_CHAIN_CARET_IS_GHOST:
case EV_CHAIN_DATA:
case EV_CHAIN_DELAY_UPDATE:
case EV_CHAIN_EDIT_NUMBER:
case EV_CHAIN_ESH:
case EV_CHAIN_GHOST:
case EV_CHAIN_LOWER_CONTEXT:
case EV_CHAIN_NOTIFY_LEVEL:
case EV_CHAIN_NOTIFY_PROC:
case EV_CHAIN_UPPER_CONTEXT:
chain = (Ev_chain)view;
chain_private = EV_CHAIN_PRIVATE(chain);
switch (attribute) {
case EV_CHAIN_AUTO_SCROLL_BY:
return((caddr_t)chain_private->auto_scroll_by);
case EV_CHAIN_DATA:
return((caddr_t)chain->client_data);
case EV_CHAIN_DELAY_UPDATE:
return((caddr_t)
((EV_PRIVATE(chain->first_view))->state &
EV_VS_DELAY_UPDATE));
case EV_CHAIN_EDIT_NUMBER:
return((caddr_t)chain_private->edit_number);
case EV_CHAIN_ESH:
return((caddr_t)chain->esh);
case EV_CHAIN_LOWER_CONTEXT:
return((caddr_t)chain_private->lower_context);
case EV_CHAIN_NOTIFY_LEVEL:
return((caddr_t)chain_private->notify_level);
case EV_CHAIN_NOTIFY_PROC:
return((caddr_t)LINT_CAST(chain_private->notify_proc));
case EV_CHAIN_UPPER_CONTEXT:
return((caddr_t)chain_private->upper_context);
case EV_CHAIN_CARET:
case EV_CHAIN_GHOST: {
struct pixrect **pr = (struct pixrect **)LINT_CAST(args1);
int *hotx = (int *)LINT_CAST(args2);
int *hoty = (int *)LINT_CAST(args3);
if (attribute == EV_CHAIN_CARET) {
*pr = chain_private->caret_pr;
*hotx = chain_private->caret_hotpoint.x;
*hoty = chain_private->caret_hotpoint.y;
} else {
*pr = chain_private->ghost_pr;
*hotx = chain_private->ghost_hotpoint.x;
*hoty = chain_private->ghost_hotpoint.y;
}
return(args1);
}
case EV_CHAIN_CARET_IS_GHOST:
return((caddr_t)chain_private->caret_is_ghost);
}
case EV_DISPLAY_START:
return((caddr_t)EV_VIEW_FIRST(view));
case EV_LEFT_MARGIN:
return((caddr_t)private->left_margin);
case EV_NO_REPAINT_TIL_EVENT : {
return((caddr_t)(private->state & EV_VS_NO_REPAINT_TIL_EVENT));
}
case EV_RECT: {
Rect *rect = (Rect *)LINT_CAST(args1);
*rect = view->rect;
return(args1);
}
case EV_RIGHT_BREAK:
return((caddr_t)private->right_break);
case EV_RIGHT_MARGIN:
return((caddr_t)private->right_margin);
default:
return((caddr_t)0);
}
}
/* VARARGS1 */
extern Ev_status
ev_set(view, va_alist)
Ev_handle view;
va_dcl
{
caddr_t attr_argv[ATTR_STANDARD_SIZE];
Ev_chain chain;
va_list args;
va_start(args);
if (view) {
chain = view->view_chain;
} else {
#ifndef lint
chain = va_arg(args, Ev_chain);
#endif
}
(void) attr_make(attr_argv, ATTR_STANDARD_SIZE, args);
va_end(args);
return(ev_set_internal(view, chain, attr_argv));
}
/*
* Private routines to support ev_get/set.
*/
static void
ev_adjust_start(chain, only_view, to, incremental)
register Ev_chain chain;
register Ev_handle only_view;
register Es_index to;
int incremental;
{
register Ev_handle next;
Es_index first, last_plus_one;
FORALLVIEWS(chain, next) {
if (!((only_view == EV_NULL) || (next == only_view)))
continue;
if (to & EV_START_SPECIAL) {
switch (to) {
case EV_START_CURRENT_POS:
ev_view_range(next, &first, &last_plus_one);
if (first < es_get_length(chain->esh)) {
break;
}
/* else fall through and reset */
default:
/* BUG ALERT! Don't do most specials yet. */
/* next->line_table.seq[0] = 0; */
ft_set(next->line_table, 0, 1, 0, NULL);
}
ev_display_view(next);
} else {
if (incremental) {
ev_set_start(next, to);
} else {
/* next->line_table.seq[0] = to; */
ft_set(next->line_table, 0, 1, to, NULL);
ev_display_view(next);
}
}
}
}
static Ev_status
ev_set_internal(view, chain, attrs)
register Ev_handle view;
Ev_chain chain;
register Attr_avlist attrs;
{
Ev_status status;
register int all_views = FALSE;
Rect *clip_rect = 0;
Ev_display_level display_level = EV_DISPLAY;
Es_index display_start = ES_CANNOT_SET;
Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(chain);
register int temp;
register Ev_pd_handle private;
register Ev_handle next;
status = EV_STATUS_OKAY;
if (view)
private = EV_PRIVATE(view);
for (; *attrs; attrs = attr_next(attrs)) {
switch ((Ev_attribute)(*attrs)) {
case EV_END_ALL_VIEWS:
all_views = FALSE;
break;
case EV_FOR_ALL_VIEWS:
all_views = TRUE;
break;
case EV_CHAIN_DATA: {
chain->client_data = attrs[1];
break;
}
case EV_CHAIN_DELAY_UPDATE: {
FORALLVIEWS(chain, next) {
if ((int)LINT_CAST(attrs[1])) {
EV_PRIVATE(next)->state |= EV_VS_DELAY_UPDATE;
} else {
EV_PRIVATE(next)->state &= ~EV_VS_DELAY_UPDATE;
}
}
break;
}
case EV_CHAIN_EDIT_NUMBER: {
chain_private->edit_number = (int)(attrs[1]);
break;
}
case EV_CHAIN_ESH: {
Es_index new_length;
chain->esh = (Es_handle)LINT_CAST(attrs[1]);
new_length = es_get_length(chain->esh);
if (chain_private->insert_pos > new_length)
chain_private->insert_pos = new_length;
if (display_level == EV_DISPLAY) {
FORALLVIEWS(chain, next) {
if (!(all_views || (next == view)))
continue;
ev_display_view(next);
}
}
/* Flush all of our cached information */
FORALLVIEWS(chain, next) {
ev_flush_view_caches(view);
}
chain_private->cache_pos_for_file_line.edit_number = 0;
break;
}
case EV_CHAIN_AUTO_SCROLL_BY: {
chain_private->auto_scroll_by = (int)(attrs[1]);
break;
}
case EV_CHAIN_LOWER_CONTEXT: {
chain_private->lower_context = (int)(attrs[1]);
break;
}
case EV_CHAIN_NOTIFY_LEVEL: {
chain_private->notify_level = (int)(attrs[1]);
break;
}
case EV_CHAIN_NOTIFY_PROC: {
chain_private->notify_proc = (int (*)())LINT_CAST(attrs[1]);
if (chain_private->notify_level == 0)
chain_private->notify_level = EV_NOTIFY_ALL;
break;
}
case EV_CHAIN_UPPER_CONTEXT: {
chain_private->upper_context = (int)(attrs[1]);
break;
}
case EV_CLIP_RECT:
clip_rect = (Rect *)LINT_CAST(attrs[1]);
break;
case EV_DATA:
ASSERT(view);
view->client_data = attrs[1];
break;
case EV_DISPLAY_LEVEL:
ASSERT(view);
switch ((Ev_display_level)(attrs[1])) {
case EV_DISPLAY:
if (display_level != EV_DISPLAY) {
ev_adjust_start(chain, (all_views) ? EV_NULL : view,
(display_start == ES_CANNOT_SET)
? EV_START_CURRENT_POS :
display_start,
FALSE);
}
/* Fall through */
case EV_DISPLAY_NONE:
case EV_DISPLAY_ONLY_CLEAR:
case EV_DISPLAY_NO_CLEAR:
display_level = (Ev_display_level)(attrs[1]);
break;
default:
status = EV_STATUS_BAD_ATTR_VALUE;
}
break;
case EV_DISPLAY_START: {
ASSERT(view);
display_start = (int)(attrs[1]);
if (display_level == EV_DISPLAY) {
ev_adjust_start(chain, (all_views) ? EV_NULL : view,
display_start, TRUE);
}
break;
}
case EV_LEFT_MARGIN:
/* BUG ALERT: does not support all_views */
ASSERT(view);
if ((int)(attrs[1]) >= 0) {
temp = private->left_margin;
private->left_margin = (int)(attrs[1]);
temp -= private->left_margin;
view->rect.r_left -= temp;
view->rect.r_width += temp;
ev_flush_view_caches(view);
}
break;
case EV_NO_REPAINT_TIL_EVENT: {
ASSERT(view);
if (attrs[1])
private->state |= EV_VS_NO_REPAINT_TIL_EVENT;
else
private->state &= ~EV_VS_NO_REPAINT_TIL_EVENT;
break;
}
case EV_RECT: {
ASSERT(view);
ev_set_rect(view, (Rect *)LINT_CAST(attrs[1]), clip_rect);
break;
}
case EV_RIGHT_BREAK:
ASSERT(view);
switch ((Ev_right_break)(attrs[1])) {
case EV_CLIP:
case EV_WRAP_AT_CHAR:
case EV_WRAP_AT_WORD:
private->right_break = (Ev_right_break)(attrs[1]);
ev_flush_view_caches(view);
break;
default:
status = EV_STATUS_BAD_ATTR_VALUE;
}
break;
case EV_RIGHT_MARGIN:
/* BUG ALERT: does not support all_views */
ASSERT(view);
if ((int)(attrs[1]) >= 0) {
temp = private->right_margin;
private->right_margin = (int)(attrs[1]);
temp -= private->right_margin;
view->rect.r_width += temp;
}
break;
case EV_SAME_AS: {
Ev_handle other_view = (Ev_handle)LINT_CAST(attrs[1]);
ASSERT(view);
if (other_view != EV_NULL) {
Ev_pd_handle other_private = EV_PRIVATE(other_view);
private->left_margin = other_private->left_margin;
private->right_break = other_private->right_break;
private->right_margin = other_private->right_margin;
}
break;
}
case EV_CHAIN_CARET: {
chain_private->caret_pr =
(struct pixrect *)LINT_CAST(attrs[1]);
chain_private->caret_hotpoint.x = (int)(attrs[2]);
chain_private->caret_hotpoint.y = (int)(attrs[3]);
break;
}
case EV_CHAIN_GHOST: {
chain_private->ghost_pr =
(struct pixrect *)LINT_CAST(attrs[1]);
chain_private->ghost_hotpoint.x = (int)(attrs[2]);
chain_private->ghost_hotpoint.y = (int)(attrs[3]);
break;
}
case EV_CHAIN_CARET_IS_GHOST: {
chain_private->caret_is_ghost = (int)(attrs[1]);
break;
}
default:
status = EV_STATUS_BAD_ATTR;
break;
}
}
return(status);
}
/* VARARGS1 */
pkg_private void
ev_notify(view, va_alist)
register Ev_handle view;
va_dcl
{
Ev_chain chain = view->view_chain;
Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(chain);
caddr_t attr_argv[ATTR_STANDARD_SIZE];
va_list args;
if (private->notify_proc == 0)
return;
va_start(args);
(void) attr_make(attr_argv+2, ATTR_STANDARD_SIZE-2, args);
va_end(args);
attr_argv[0] = (caddr_t)EV_ACTION_VIEW;
attr_argv[1] = (caddr_t)view;
private->notify_proc(chain->client_data, attr_argv);
}
pkg_private void
ev_flush_view_caches(view)
Ev_handle view;
{
register Ev_pd_handle private = EV_PRIVATE(view);
private->cached_insert_info.edit_number = 0;
private->cached_line_info.edit_number = 0;
}
static void
ev_set_rect(view, rect, intersect_rect)
register Ev_handle view;
register struct rect *rect,
*intersect_rect;
{
extern struct rect ev_rect_for_line();
int lines;
register int old_lines = view->line_table.last_plus_one;
struct rect clear_rect;
ev_flush_view_caches(view);
/* See note in ev_ft_for_rect about +1 */
lines = ei_lines_in_rect(view->view_chain->eih, rect) + 1;
if (EV_VIEW_FIRST(view) != ES_INFINITY) {
if ((view->rect.r_width == rect->r_width) &&
(view->rect.r_height >= rect->r_height)) {
clear_rect = ev_rect_for_line(view, (lines - 1));
} else
clear_rect = *rect;
ev_clear_rect(view, &clear_rect);
}
view->rect = *rect;
/* BUG ALERT! Not clear that this is really a safe way to get around
* problem of calling setting rect to be too small.
*/
if (view->rect.r_width < 24)
view->rect.r_width = 24;
ft_expand(&view->line_table, lines - old_lines);
ft_expand(&view->tmp_line_table, lines - old_lines);
if (intersect_rect &&
rect_intersectsrect(intersect_rect, &view->rect)) {
ev_display_in_rect(view, intersect_rect);
}
}