/******************************************************************************* * 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; }