campo-sirio/xi/xistx.c
alex 97094231a5 Modifiche aga
git-svn-id: svn://10.65.10.50/trunk@5760 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-12-17 10:50:23 +00:00

1146 lines
28 KiB
C
Executable File

/*******************************************************************************
* Copyright 1991-1995 by ORCA Software, Inc. *
* *
* All rights reserved. May not be reproduced or distributed, in printed or *
* electronic form, without permission of ORCA Software, Inc. May not be *
* distributed as object code, separately or linked with other object modules, *
* without permission. *
*******************************************************************************/
#define XI_INTERNAL
#include "xi.h"
#include "xitext.h"
#include "xistx.h"
#include "xiutils.h"
#define tx_create
#define xvt_tx_process_event xvt_tx_process_event
/* error codes 30100 - 30104 */
#if XVT_OS == XVT_OS_CTOS
#define BORDER_WIDTH_X ((npctos_env == CHSERVICE) ? 8 : 1)
#define BORDER_WIDTH_Y ((npctos_env == CHSERVICE) ? 0 : 1)
#define BORDER_SPACE_X ((npctos_env == CHSERVICE) ? 0 : 1)
#define BORDER_SPACE_Y ((npctos_env == CHSERVICE) ? 0 : 1)
#define CHR_LEFTBRACKET "["
#define CHR_RIGHTBRACKET "]"
#else
#if XIWS != WMWS
#define BORDER_WIDTH_X 1
#define BORDER_WIDTH_Y 1
#define BORDER_SPACE_X 1
#define BORDER_SPACE_Y 1
#else
#define BORDER_WIDTH_X 8
#define BORDER_WIDTH_Y 0
#define BORDER_SPACE_X 0
#define BORDER_SPACE_Y 0
#define CHR_LEFTBRACKET "["
#define CHR_RIGHTBRACKET "]"
#endif
#endif
#define STXP(stx) ((STX_DATA *)(stx))
#define STX_IS_ENABLED(stx) ((STXP(stx)->attrib & STX_ATR_ENABLED) != 0)
#define STX_IS_VISIBLE(stx) ((STXP(stx)->attrib & STX_ATR_VISIBLE) != 0)
#define STX_HAS_BORDER(stx) ((STXP(stx)->attrib & STX_ATR_BORDER) != 0)
#define STX_REDRAW_ATR (STX_ATR_VISIBLE | STX_ATR_ENABLED | STX_ATR_RJUST | STX_ATR_PASSWORD)
static void near stx_stop_edit(STX stx);
static void draw_text_edit_border(STX_DATA *stxptr);
static void near
get_text_rect(STX stx, RCT *rct)
{
*rct = STXP(stx)->rct;
rct->top += BORDER_WIDTH_Y + BORDER_SPACE_Y;
rct->bottom -= BORDER_WIDTH_Y + BORDER_SPACE_Y;
rct->left += BORDER_WIDTH_X + BORDER_SPACE_X;
rct->right -= BORDER_WIDTH_X + BORDER_SPACE_X;
}
TXEDIT
stx_get_txedit(STX stx)
{
return STXP(stx)->txedit;
}
STX
stx_create(WINDOW win, STX_DEF *stx_def)
{
STX_DATA *stxd;
RCT rct;
int ascent, descent, leading, font_height;
short rct_r, rct_b, edit_height;
XI_OBJ *itf;
itf = xi_get_itf(win);
NOREF(itf);
xi_set_xvt_font(win, &stx_def->font, FALSE);
xi_get_font_metrics(win, &leading, &ascent, &descent);
font_height = ascent + leading + descent;
stxd = (STX_DATA *)xi_tree_malloc(sizeof(STX_DATA), stx_def->parent);
stxd->cid = stx_def->cid;
stxd->win = win;
stxd->attrib = stx_def->attrib;
rct_r = stx_def->pnt.h + stx_def->pixel_width + 2 *
BORDER_WIDTH_X + 2 * BORDER_SPACE_X;
edit_height = font_height + 2 * BORDER_WIDTH_Y + 2 * BORDER_SPACE_Y;
rct_b = stx_def->pnt.v + edit_height;
xvt_rect_set( &rct, stx_def->pnt.h, stx_def->pnt.v, rct_r, rct_b);
stxd->rct = rct;
stxd->font = stx_def->font;
stxd->back_color = stx_def->back_color;
stxd->enabled_color = stx_def->enabled_color;
stxd->disabled_color = stx_def->disabled_color;
stxd->active_color = stx_def->active_color;
stxd->active_back_color = stx_def->active_back_color;
stxd->disabled_back_color = stx_def->disabled_back_color;
stxd->hilight_color = stx_def->hilight_color;
stxd->shadow_color = stx_def->shadow_color;
stxd->stx_cb = stx_def->stx_cb;
stxd->text_size = stx_def->text_size;
stxd->app_data = stx_def->app_data;
stxd->text = (char *)xi_tree_malloc(stx_def->text_size, (char *)stxd);
stxd->text[0] = '\0';
stxd->has_focus = FALSE;
stxd->well = stx_def->well;
stxd->platform = stx_def->platform;
stxd->auto_tab = stx_def->auto_tab;
stxd->txedit = BAD_TXEDIT;
#ifndef XI_DONT_USE_TX_EDIT
if (stx_def->xi_rct.top || stx_def->xi_rct.left ||
stx_def->xi_rct.bottom || stx_def->xi_rct.right)
{
unsigned attrib;
RCT rct;
if ((stx_def->xi_rct.bottom - stx_def->xi_rct.top) <=
XI_FU_MULTIPLE)
{
rct = stx_def->xi_rct;
xi_fu_to_pu(xi_get_itf(win), (PNT *)&rct, 2);
rct.bottom = rct.top + edit_height;
stxd->rct = rct;
}
else
{
FONT_OBJ font;
attrib = TX_WRAP;
if (stxd->attrib & XI_ATR_READONLY)
attrib |= TX_READONLY;
if (stxd->attrib & XI_ATR_BORDER)
attrib |= TX_BORDER;
if (stxd->attrib & XI_ATR_AUTOSCROLL)
attrib |= TX_AUTOHSCROLL | TX_AUTOVSCROLL;
if (! itf->v.itf->edit_menu)
attrib |= TX_NOMENU;
stxd->use_text_edit = TRUE;
rct = stx_def->xi_rct;
xi_fu_to_pu(xi_get_itf(win), (PNT *)&rct, 2);
rct.bottom -= BORDER_SPACE_Y;
stxd->rct = rct;
if (((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
&&((stxd->well == TRUE) || (stxd->platform == TRUE)))
{
xi_inflate_rect(&rct, -2);
attrib &= ~TX_BORDER;
}
if ((stxd->attrib & XI_ATR_FOCUSBORDER) || ((stxd->attrib & XI_ATR_BORDER)))
xi_inflate_rect(&rct, -1);
font = stx_def->font;
stxd->txedit = xvt_tx_create(win, &rct, attrib,
font, rct.right - rct.left - 4, INT_MAX);
xvt_tx_set_colors(stxd->txedit, stxd->enabled_color,
stxd->enabled_color, stxd->back_color);
xvt_tx_add_par(stxd->txedit, 0, "");
/* the following line is a hack for ms-windows */
{ PNT _p; _p.h = -100; _p.v = -100;
xvt_win_set_caret_pos(win, _p); /*xvt_R3MIG caret_on*/
xvt_win_set_caret_visible(win, TRUE); };
xvt_win_set_caret_visible(win, FALSE );
}
}
#endif
xi_invalidate_rect(win, &stxd->rct);
return((STX)PTR_LONG(stxd));
}
void
stx_delete(STX stx)
{
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
xvt_tx_destroy(STXP(stx)->txedit);
else
#endif
{
if (STXP(stx)->has_focus)
stx_stop_edit(stx);
xi_invalidate_rect(STXP(stx)->win, &STXP(stx)->rct);
}
xi_tree_free((char *)stx);
}
static void near
redraw_stx(STX stx, BOOLEAN update, BOOLEAN inside_only)
{
RCT rct;
DRAW_CTOOLS ct;
FONT_OBJ *ct_font;
STX_DATA *stxp = STXP(stx);
#if XI_IS_NOT_CH
RCT rct2, rr;
#endif
#if XI_IS_CH
NOREF(inside_only);
#endif
if (STXP(stx)->use_text_edit)
return;
rct = stxp->rct;
if (update && !xi_needs_update(stxp->win, &rct))
return;
if (STX_IS_VISIBLE(stx))
{
xvt_app_get_default_ctools(&ct);
#if XI_IS_CH
CTOS_IS_CH;
ct.pen = hollow_cpen;
CTOS_END;
#endif
#if XI_IS_NOT_CH
CTOS_IS_PM;
if (STX_HAS_BORDER(stx) && !inside_only)
ct.pen = black_cpen;
else
ct.pen = hollow_cpen;
CTOS_END;
#endif
ct_font = &stxp->font;
if (STX_IS_ENABLED(stx))
{
ct.fore_color = ct.pen.color =
(stxp->has_focus ? stxp->active_color : stxp->enabled_color);
ct.brush.color =
(stxp->has_focus ? stxp->active_back_color : stxp->back_color);
}
else
{
/* draw disabled cells with grey background */
ct.fore_color = ct.pen.color = stxp->disabled_color;
ct.brush.color = stxp->disabled_back_color;
}
#if XI_IS_NOT_CH
CTOS_IS_PM;
rct2 = rct;
if ((stxp->attrib & XI_ATR_FOCUSBORDER) || (! (stxp->attrib & XI_ATR_BORDER)))
{
if (! stxp->has_focus)
{
static XI_OBJ *itf;
COLOR back_color;
ct.pen = black_cpen;
itf = xi_get_itf(stxp->win);
back_color = itf->v.itf->back_color;
if (back_color)
ct.pen.color = back_color;
else
ct.pen.color = xi_get_pref(XI_PREF_COLOR_CTRL);
}
}
/* TODO only draw inside only if not well or plat */
if (! stxp->well && ! stxp->platform)
if ((! (stxp->attrib & XI_ATR_FOCUSBORDER)) && (! (stxp->attrib & XI_ATR_BORDER)))
{
ct.pen = hollow_cpen;
inside_only = TRUE;
}
ct.opaque_text = FALSE;
xi_set_draw_ctools(stxp->win, &ct);
/* TODO moved following two lines down */
if (stxp->well || stxp->platform)
xi_set_cbrush(stxp->win, &hollow_cbrush);
xi_set_xvt_font(stxp->win, ct_font, FALSE);
if (inside_only)
xi_inflate_rect(&rct2, -1);
rr = rct2;
xi_set_clip(stxp->win, NULL);
xi_draw_rect(stxp->win, &rr);
if (stxp->well || stxp->platform)
{
RCT r;
r = rct2;
if (!inside_only)
xi_inflate_rect(&r, -1);
xi_draw_3d_rect(stxp->win, &r, stxp->well, 1, stxp->hilight_color,
stxp->attrib & XI_ATR_ENABLED ? stxp->back_color : stxp->disabled_back_color, stxp->shadow_color);
}
CTOS_END;
#endif
#if XI_IS_CH
CTOS_IS_CH;
ct.back_color = xi_get_itf(stxp->win)->v.itf->back_color;
xi_set_draw_ctools(stxp->win, &ct);
xi_set_xvt_font(stxp->win, ct_font, FALSE);
if (STX_HAS_BORDER(stx))
{
xi_draw_text(stxp->win, rct.left, rct.bottom, CHR_LEFTBRACKET, -1);
xi_draw_text(stxp->win, rct.right - 8, rct.bottom, CHR_RIGHTBRACKET, -1);
}
if (STX_IS_ENABLED(stx))
xi_set_xvt_back_color(stxp->win, stxp->back_color);
else
xi_set_xvt_back_color(stxp->win, stxp->disabled_back_color);
{
RCT r;
r = rct;
if (STX_HAS_BORDER(stx))
{
r.right -= 8;
r.left += 8;
}
xi_draw_rect(stxp->win, &r);
}
CTOS_END;
#endif
if (stxp->has_focus)
txt_redraw(stxp->txt, FALSE);
else
{
/* draw cell text */
const int old_bottom = rct.bottom;
get_text_rect(stx, &rct);
rct.bottom = old_bottom;
xi_draw_clipped_text(stxp->win, stxp->text, &rct, &rct, stxp->attrib,
TRUE, 0, -1);
}
}
}
/*
stx_start_edit: create a text core edit field in the position of the
field of interest, and copy in the necessary attributes and text from
the field.
*/
static void near
stx_start_edit(STX stx)
{
TXT_DATA *txt;
STXP(stx)->has_focus = TRUE;
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
xvt_tx_set_active(STXP(stx)->txedit);
xi_invalidate_rect(STXP(stx)->win, &STXP(stx)->rct);
}
else
#endif
{
txt = STXP(stx)->txt = (TXT_DATA *)xi_tree_malloc(sizeof(TXT_DATA),
(char *)stx);
txt->rct = STXP(stx)->rct;
txt->parent_obj = xi_get_obj(xi_get_itf(STXP(stx)->win), STXP(stx)->cid);
txt->attrib = STXP(stx)->attrib | TXT_ATR_VISIBLE;
txt->text = STXP(stx)->text;
txt->text_size = STXP(stx)->text_size;
txt->font = &(STXP(stx)->font);
txt->back_color = STXP(stx)->active_back_color;
txt->fore_color = STXP(stx)->active_color;
txt->hilight_color = STXP(stx)->hilight_color;
txt->shadow_color = STXP(stx)->shadow_color;
txt->well = STXP(stx)->well;
txt->platform = STXP(stx)->platform;
txt->auto_tab = STXP(stx)->auto_tab;
txt->win = STXP(stx)->win;
txt_reset(txt);
if (STXP(stx)->have_mouse)
{
if ((STXP(stx)->attrib & (STX_ATR_AUTOSELECT | STX_ATR_READONLY)) ==
(STX_ATR_AUTOSELECT | STX_ATR_READONLY))
txt_set_sel(txt, 0, SHRT_MAX);
if ((STXP(stx)->attrib & STX_ATR_AUTOSELECT) && xi_get_pref(XI_PREF_AUTOSEL_ON_MOUSE))
txt_set_sel(txt, 0, SHRT_MAX);
}
else
{
if (STXP(stx)->attrib & STX_ATR_AUTOSELECT)
txt_set_sel(txt, 0, SHRT_MAX);
else
txt_set_sel(txt, 0, 0);
}
txt_caret(txt, TRUE);
#if XI_IS_CH
CTOS_IS_CH;
if ((STXP(stx)->attrib & STX_ATR_AUTOSELECT) == 0)
txt_set_sel(txt, 0, 0);
CTOS_END;
#endif
}
}
static void near
stx_stop_edit(STX stx)
{
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
WINDOW win;
STXP(stx)->has_focus = FALSE;
win = STXP(stx)->win;
#if XVTWS == WINWS
{ PNT _p; _p.h = -100; _p.v = -100;
xvt_win_set_caret_pos(win, _p);
xvt_win_set_caret_visible(win, TRUE); };
#endif
xi_caret_off(win);
xi_invalidate_rect(win, &STXP(stx)->rct);
}
else
#endif
{
txt_hide_caret(STXP(stx)->txt);
txt_caret(STXP(stx)->txt, FALSE);
xi_tree_free((char *)STXP(stx)->txt);
STXP(stx)->txt = NULL;
STXP(stx)->has_focus = FALSE;
redraw_stx(stx, FALSE, FALSE);
}
}
/*
do_stx_cb: handles the STX_CB_CHAR, STX_CB_CHANGE, STX_CB_FOCUS cases.
*/
static BOOLEAN near
do_stx_cb(STX stx, STX_CB_TYPE cb_reason, EVENT *ep)
{
STX_CB_DATA stx_cb_data;
stx_cb_data.stx = stx;
stx_cb_data.cb_type = cb_reason;
stx_cb_data.cid = STXP(stx)->cid;
stx_cb_data.win = STXP(stx)->win;
if (cb_reason == STX_CB_CHAR)
{
stx_cb_data.v.chr.ch = ep->v.chr.ch;
stx_cb_data.v.chr.shift = ep->v.chr.shift;
stx_cb_data.v.chr.control = ep->v.chr.control;
stx_cb_data.v.chr.is_paste = FALSE;
stx_cb_data.v.chr.refused = FALSE;
} else
stx_cb_data.v.refused = FALSE;
(*STXP(stx)->stx_cb)(&stx_cb_data);
/* retval = FALSE if event refused */
if (cb_reason == STX_CB_CHAR)
{
if (! stx_cb_data.v.chr.refused)
ep->v.chr.ch = stx_cb_data.v.chr.ch;
return (! stx_cb_data.v.chr.refused);
}
else
return (! stx_cb_data.v.refused);
}
void
stx_focus_cb(long stx, BOOLEAN set)
{
if (set != STXP(stx)->has_focus)
{
if (set)
stx_start_edit(stx);
else
stx_stop_edit(stx);
}
}
/*
The parameter gaining_focus is here so that on an E_MOUSE_DOWN, if the
field is gaining the focus, and XI_PREF_AUTOSEL_ON_MOUSE is TRUE, then
txt_event knows to select the entire field, not set an insertion point.
*/
static BOOLEAN near
send_txt_event(STX stx, TXT_DATA *txt, EVENT *ep,
BOOLEAN gaining_focus)
{
BOOLEAN retval;
int ch;
if (ep->type == E_CHAR)
{
ch = ep->v.chr.ch;
if ((ch >= ' ' || ch == K_CLEAR || ch == K_DEL ||
ch == '\b') && ch != K_BTAB && ch != K_UP && ch != K_DOWN)
{
retval = do_stx_cb(stx, STX_CB_CHAR, ep);
/* retval = FALSE if event refused */
if (! retval)
return FALSE;
}
}
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
EVENT e;
e = *ep;
if (ep->type == E_CHAR && (ep->v.chr.ch == '\t' || ep->v.chr.ch == K_BTAB))
retval = FALSE;
else
{
if (xi_get_pref(XI_PREF_TRIPLE_CLICK_TIME))
{
if (ep->type == E_MOUSE_DBL)
{
STXP(stx)->timer_id = xvt_timer_create(STXP(stx)->win,
xi_get_pref(XI_PREF_TRIPLE_CLICK_TIME));
STXP(stx)->timer_set = TRUE;
}
}
if (ep->type == E_TIMER &&
ep->v.timer.id == STXP(stx)->timer_id)
{
xvt_timer_destroy(ep->v.timer.id);
STXP(stx)->timer_id = 0;
STXP(stx)->timer_set = FALSE;
}
if (ep->type == E_MOUSE_DOWN &&
STXP(stx)->timer_set)
{
xvt_timer_destroy(STXP(stx)->timer_id);
STXP(stx)->timer_set = FALSE;
STXP(stx)->timer_id = 0;
stx_set_sel(stx, 0, 32000);
return FALSE;
}
if (ep->type == E_UPDATE)
draw_text_edit_border(STXP(stx));
if (ep->type != E_COMMAND)
retval = xvt_tx_process_event(STXP(stx)->win, &e);
if (ep->type == E_COMMAND && xi_get_pref(XI_PREF_MULTILINE_QUICK_PASTE))
retval = xvt_tx_process_event(STXP(stx)->win, &e);
if ( retval )
{
((XI_OBJ*)STXP(stx)->app_data)->itf->v.itf->chg_flag = TRUE;
do_stx_cb( stx, STX_CB_CHANGE, ep );
}
}
}
else
#endif
{
retval = txt_event(txt, ep, gaining_focus);
/* check flags */
if (txt->flags & TXT_FLAG_TEXT)
{
((XI_OBJ*)STXP(stx)->app_data)->itf->v.itf->chg_flag = TRUE;
do_stx_cb(stx, STX_CB_CHANGE, ep);
}
/* reset flags */
txt->flags = 0;
}
return(retval);
}
BOOLEAN
stx_event(STX stx, EVENT *ep)
{
STX_DATA *stxp = STXP(stx);
BOOLEAN retval = TRUE;
switch(ep->type)
{
case E_SIZE:
retval = FALSE;
break;
case E_TIMER:
if (stxp->txt)
send_txt_event(stx, stxp->txt, ep, FALSE);
retval = FALSE;
break;
case E_UPDATE:
#ifndef XI_DONT_USE_TX_EDIT
if (stxp->use_text_edit)
{
if ((stxp->attrib & STX_ATR_VISIBLE) != 0)
{
EVENT e;
CBRUSH cbrush;
RCT r;
e = *ep;
if (ep->type == E_UPDATE)
draw_text_edit_border(STXP(stx));
cbrush.color = STXP(stx)->back_color;
cbrush.pat = PAT_SOLID;
xi_set_cbrush(STXP(stx)->win, &cbrush);
xi_set_cpen(STXP(stx)->win, &hollow_cpen);
r = STXP(stx)->rct;
if (STXP(stx)->attrib & XI_ATR_BORDER || STXP(stx)->attrib & XI_ATR_FOCUSBORDER)
xi_inflate_rect(&r, -1);
xi_inflate_rect(&r, -2);
xi_draw_rect(STXP(stx)->win, &r);
xvt_tx_process_event(stxp->win, &e);
}
}
else
#endif
redraw_stx(stx, TRUE, FALSE);
retval = FALSE;
break;
case E_MOUSE_DOWN:
case E_MOUSE_DBL:
{
BOOLEAN gaining_focus = FALSE;
/* check for focus acquisition */
if (xvt_rect_has_point(&stxp->rct, ep->v.mouse.where) &&
(stxp->attrib & (XI_ATR_ENABLED | XI_ATR_VISIBLE)) ==
(XI_ATR_ENABLED | XI_ATR_VISIBLE))
{
stxp->have_mouse = TRUE;
if (!STXP(stx)->has_focus)
{
if (!do_stx_cb(stx, STX_CB_FOCUS, ep))
{
stxp->have_mouse = FALSE;
break;
}
gaining_focus = TRUE;
}
/* the stx may have lost the focus, due to a field being
disabled, in which case, stxp->txt == NULL */
if (stxp->txt || stxp->use_text_edit)
{
send_txt_event(stx, stxp->txt, ep, gaining_focus);
if (stxp->txt)
xi_trap_mouse(stxp->win);
if (ep->type == E_MOUSE_DBL)
do_stx_cb(stx, STX_CB_DBL, ep);
}
}
else
retval = FALSE;
break;
}
case E_MOUSE_UP:
if (stxp->has_focus)
{
send_txt_event(stx, stxp->txt, ep, FALSE);
xi_release_mouse();
stxp->have_mouse = FALSE;
}
break;
case E_MOUSE_MOVE:
{
unsigned long attrib;
if (stxp->has_focus)
send_txt_event(stx, stxp->txt, ep, FALSE);
attrib = stxp->attrib & (XI_ATR_ENABLED | XI_ATR_VISIBLE);
if ((attrib != (XI_ATR_ENABLED | XI_ATR_VISIBLE)) ||
(! xvt_rect_has_point(&stxp->rct, ep->v.mouse.where)))
retval = FALSE;
break;
}
case E_CHAR:
retval = send_txt_event(stx, stxp->txt, ep, FALSE);
break;
case E_KILL_WINDOW:
retval = FALSE;
break;
case E_COMMAND:
retval = send_txt_event(stx, stxp->txt, ep, FALSE);
break;
}
return(retval);
}
unsigned long
stx_get_attrib(STX stx)
{
return(STXP(stx)->attrib);
}
int
stx_get_cid(STX stx)
{
return(STXP(stx)->cid);
}
void
stx_get_sel(STX stx, int *c1, int *c2)
{
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
int accum_cnt;
T_PNUM par;
T_PNUM start_par, end_par;
T_LNUM start_line, end_line;
T_CNUM start_char, end_char;
BOOLEAN ex;
accum_cnt = 0;
xvt_tx_get_sel(STXP(stx)->txedit, &start_par, &start_line, &start_char,
&end_par, &end_line, &end_char);
ex = FALSE;
for (par = 0; par <= start_par; par++)
{
T_LNUM nbr_lins, lin;
nbr_lins = xvt_tx_get_num_par_lines(STXP(stx)->txedit, par);
for (lin = 0; lin < nbr_lins; lin++)
{
if (par == start_par && lin == start_line)
{
accum_cnt += start_char;
ex = TRUE;
break;
}
accum_cnt += xvt_tx_get_num_chars(STXP(stx)->txedit, par, lin);
}
if (ex)
break;
accum_cnt += 1; /* add eol at end of paragraph */
}
*c1 = accum_cnt;
if (start_par == end_par && start_line == end_line &&
start_char == end_char)
{
*c2 = accum_cnt;
return;
}
ex = FALSE;
for (par = start_par; par <= end_par; par++)
{
T_LNUM nbr_lins, lin;
nbr_lins = xvt_tx_get_num_par_lines(STXP(stx)->txedit, par);
for (lin = 0; lin < nbr_lins; lin++)
{
if (par == end_par && lin == end_line)
{
accum_cnt += end_char;
if (par == start_par && lin == start_line)
accum_cnt -= start_char;
ex = TRUE;
break;
}
accum_cnt += xvt_tx_get_num_chars(STXP(stx)->txedit, par, lin);
if (par == start_par && lin == start_line)
accum_cnt -= start_char;
}
if (ex)
break;
accum_cnt += 1; /* add eol at end of paragraph */
}
*c2 = accum_cnt;
return;
}
#endif
if (STXP(stx)->has_focus)
{
*c1 = STXP(stx)->txt->selstart;
*c2 = STXP(stx)->txt->selstop;
}
else
*c1 = *c2 = 0;
}
RCT *
stx_get_rect(STX stx, RCT *rct)
{
*rct = STXP(stx)->rct;
return(rct);
}
#ifndef XI_DONT_USE_TX_EDIT
static void
tx_get_text(TXEDIT tx, char *string, int string_len)
{
char *s;
int slen, cnt, nbr_pars;
unsigned len;
slen = 0;
s = NULL;
nbr_pars = xvt_tx_get_num_pars(tx);
for (cnt = 0; cnt < nbr_pars; ++cnt)
{
int nbr_lines, cnt2;
nbr_lines = xvt_tx_get_num_par_lines(tx, (short)cnt);
for (cnt2 = 0; cnt2 < nbr_lines; ++cnt2)
{
char *str;
int old_len;
xvt_tx_get_line(tx, (short)cnt, A_LOCK, (short)cnt2, NULL);
str = xvt_tx_get_line(tx, (short)cnt, A_GET, (short)cnt2, &len);
old_len = slen;
slen = slen + len;
if (s)
s = (char *)xi_tree_realloc(s, slen + 2);
else
s = (char *)xi_tree_malloc(slen + 2, NULL);
gstrncpy(&s[old_len], str, len);
}
slen++;
#if XIWS == MACWS
s[slen - 1] = '\r';
#else
s[slen - 1] = '\n';
#endif
}
if (! slen)
string[0] = '\0';
else
{
s[slen - 1] = '\0';
gstrncpy(string, s, string_len);
string[string_len - 1] = '\0';
xi_tree_free(s);
}
}
static int
tx_get_len(TXEDIT tx)
{
int nbr_pars, cnt, charcnt;
charcnt = 0;
nbr_pars = xvt_tx_get_num_pars(tx);
for (cnt = 0; cnt < nbr_pars; ++cnt)
{
int nbr_lines, cnt2;
nbr_lines = xvt_tx_get_num_par_lines(tx, (short)cnt);
for (cnt2 = 0; cnt2 < nbr_lines; ++cnt2)
charcnt += (xvt_tx_get_num_chars(tx, (short)cnt, (short)cnt2) + 1);
}
return charcnt;
}
#endif
char *
stx_get_text(STX stx, char *s, int len)
{
char *b;
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
if (s)
{
tx_get_text(STXP(stx)->txedit, s, len);
b = s;
}
else
{
int len;
len = tx_get_len(STXP(stx)->txedit);
if (STXP(stx)->buf)
STXP(stx)->buf = (char*)xi_tree_realloc(STXP(stx)->buf, len);
else
STXP(stx)->buf = (char*)xi_tree_malloc(len, NULL);
tx_get_text(STXP(stx)->txedit, STXP(stx)->buf, len);
b = STXP(stx)->buf;
}
}
else
#endif
b = STXP(stx)->text;
if (s)
tgstrncpy(s, b, len);
return b;
}
void
stx_set_bufsize(STX stx, short size)
{
/*
TODO
if (STXP(stx)->use_text_edit)
set buffer size
*/
STXP(stx)->text = (char *)xi_tree_realloc(STXP(stx)->text, (size_t)size);
STXP(stx)->text[size - 1] = '\0';
STXP(stx)->text_size = size;
}
void
stx_set_attrib(STX stx, unsigned long attrib)
{
unsigned long do_redraw;
if (STXP(stx)->use_text_edit)
{
if (attrib & XI_ATR_VISIBLE)
{
if (!(STXP(stx)->attrib & XI_ATR_VISIBLE))
xvt_tx_resume(STXP(stx)->txedit);
} else
{
if (STXP(stx)->attrib & XI_ATR_VISIBLE)
xvt_tx_suspend(STXP(stx)->txedit);
}
}
do_redraw = ((STXP(stx)->attrib ^ attrib) & STX_REDRAW_ATR);
STXP(stx)->attrib = attrib;
if (do_redraw)
xi_invalidate_rect(STXP(stx)->win, &(STXP(stx)->rct));
}
void
stx_set_focus(STX stx)
{
if (xvt_scr_get_focus_vobj()!= STXP(stx)->win)
{
xvt_scr_set_focus_vobj(STXP(stx)->win);
}
if (!STXP(stx)->has_focus)
stx_start_edit(stx);
}
void
stx_set_pos(STX stx, PNT p)
{
int dh, dv;
dh = p.h - STXP(stx)->rct.left;
dv = p.v - STXP(stx)->rct.top;
STXP(stx)->rct.top += dv;
STXP(stx)->rct.left += dh;
STXP(stx)->rct.bottom += dv;
STXP(stx)->rct.right += dh;
}
void
stx_set_sel(STX stx, int c1, int c2)
{
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
int accum_cnt, selidx;
int sel[2];
T_PNUM parsel[2], par, nbr_pars;
T_LNUM linsel[2], lin, nbr_lins;
T_CNUM chrsel[2], nbr_chrs;
accum_cnt = 0;
selidx = 0;
sel[0] = c1;
sel[1] = c2;
nbr_pars = xvt_tx_get_num_pars(STXP(stx)->txedit);
for (par = 0; par < nbr_pars; par++)
{
nbr_lins = xvt_tx_get_num_par_lines(STXP(stx)->txedit, par);
for (lin = 0; lin < nbr_lins; lin++)
{
nbr_chrs = xvt_tx_get_num_chars(STXP(stx)->txedit, par, lin);
while ((int)(accum_cnt + nbr_chrs) >= sel[selidx])
{
parsel[selidx] = par;
linsel[selidx] = lin;
chrsel[selidx] = sel[selidx] - accum_cnt;
selidx++;
if (selidx >= 2)
goto set_sel;
}
accum_cnt += nbr_chrs;
}
accum_cnt += 1; /* add eol at end of paragraph */
}
while (selidx < 2)
{
parsel[selidx] = nbr_pars-1;
linsel[selidx] = nbr_lins-1;
chrsel[selidx] = nbr_chrs-1;
if (selidx == 1)
chrsel[selidx] = nbr_chrs;
selidx++;
}
set_sel:
xvt_tx_set_sel(STXP(stx)->txedit, parsel[0], linsel[0], chrsel[0],
parsel[1], linsel[1], chrsel[1]);
return;
}
#endif
if (!STXP(stx)->has_focus)
stx_start_edit(stx);
txt_set_sel(STXP(stx)->txt, c1, c2);
}
#ifndef XI_DONT_USE_TX_EDIT
static void do_tx_add_par(TXEDIT tx, int limit, char *text)
{
char *s, *bp, *ep;
int cnt, nbr_pars;
nbr_pars = xvt_tx_get_num_pars(tx);
xvt_tx_suspend(tx);
for (cnt = 0; cnt < nbr_pars; ++cnt)
xvt_tx_rem_par(tx, 0);
s = (char *)xi_tree_malloc(limit + 1, NULL);
bp = text;
if (text[0] == '\0')
{
xvt_tx_add_par(tx, (unsigned short)USHRT_MAX, s);
xvt_tx_resume(tx);
xi_tree_free(s);
return;
}
while (TRUE)
{
int cnt, min_cnt;
if (*bp == '\0')
break;
ep = bp;
cnt = 0;
while (*ep != '\r' && *ep != '\n' && *ep != '\0')
{
++ep;
++cnt;
}
min_cnt = min(limit, cnt);
gstrncpy(s, bp, min_cnt);
s[min_cnt] = '\0';
xvt_tx_add_par(tx, (unsigned short)USHRT_MAX, s);
if (*ep == '\0')
break;
bp = ep + 1;
}
xvt_tx_resume(tx);
xi_tree_free(s);
}
#endif
void
stx_set_text(STX stx, char *s)
{
#ifndef XI_DONT_USE_TX_EDIT
if (STXP(stx)->use_text_edit)
{
do_tx_add_par(STXP(stx)->txedit, STXP(stx)->text_size, s);
xvt_tx_set_sel(STXP(stx)->txedit, 0, 0, 0, 0, 0, 0);
}
else
#endif
{
if (STXP(stx)->has_focus)
txt_set_text(STXP(stx)->txt, s);
else
{
tgstrncpy(STXP(stx)->text, s, STXP(stx)->text_size);
if ((STXP(stx)->attrib & STX_ATR_VISIBLE) != 0
&& !xi_half_baked(STXP(stx)->win))
redraw_stx(stx, FALSE, TRUE);
}
}
}
void
stx_set_app_data(STX stx, long data)
{
STXP(stx)->app_data = data;
}
long
stx_get_app_data(STX stx)
{
return(STXP(stx)->app_data);
}
/*---------------------------------------------------------------------
function: draw_text_edit_border
stxptr:
process: TODO
---------------------------------------------------------------------*/
static void
draw_text_edit_border(STX_DATA *stxptr)
{
RCT rct;
xi_set_draw_mode(stxptr->win, M_COPY);
xi_set_cpen(stxptr->win, &black_cpen);
xi_set_cbrush(stxptr->win, &hollow_cbrush);
rct = stxptr->rct;
if (stxptr->attrib & XI_ATR_BORDER)
{
xi_draw_rect(stxptr->win, &rct);
xi_inflate_rect(&rct, -1);
}
else
{
if (stxptr->attrib & XI_ATR_FOCUSBORDER)
{
COLOR pen_color;
CPEN cpen;
if (stxptr->has_focus)
{
pen_color = COLOR_BLACK;
}
else
{
static XI_OBJ *itf;
COLOR back_color;
itf = xi_get_itf(stxptr->win);
back_color = itf->v.itf->back_color;
if (back_color)
pen_color = back_color;
else
pen_color = xi_get_pref(XI_PREF_COLOR_CTRL);
}
cpen.color = pen_color;
cpen.pat = PAT_SOLID;
cpen.width = 1;
cpen.style = P_SOLID;
xi_set_cpen(stxptr->win, &cpen);
xi_draw_rect(stxptr->win, &rct);
xi_inflate_rect(&rct, -1);
}
}
if (((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK) == FALSE)
||((stxptr->well == FALSE) && (stxptr->platform == FALSE)))
return;
xi_draw_3d_rect(stxptr->win, &rct, stxptr->well, 1, 0L, 0L, 0L);
}
RCT*
stx_get_inside_rect( STX stx, RCT* rect )
{
STX_DATA* stx_ptr = (STX_DATA*)stx;
*rect = stx_ptr->rct;
if (((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK)) &&
((stx_ptr->well == TRUE) || (stx_ptr->platform == TRUE)))
xi_inflate_rect(rect, -2);
return rect;
}