3727 lines
91 KiB
C
Raw Normal View History

/*******************************************************************************
* 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 "xilm.h"
#include "xiutils.h"
#include "xvtmenu.h"
#include "xi_int.h"
#if XIWS == MTFWS
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#endif
#if XIWS == MTFWS
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#endif
#if XI_IS_CH
#undef strcmp
#define strcmp(a, b) strcmp(a, b)
#endif
#define MAXPIX 6000
#define VRCT_TO_PRCT(rp) \
(rp)->left -= cur_delta_x; \
(rp)->right -= cur_delta_x; \
(rp)->top -= cur_delta_y; \
(rp)->bottom -= cur_delta_y;
/* ERROR CODES 20000-20089 */
/********************************* CONSTANTS *******************************/
/********************************* DATA TYPES *******************************/
/******************************* STATIC DATA ********************************/
WINDOW xi_modal_win = NULL_WIN;
BOOLEAN xi_false = FALSE;
/******************************** FUNCTIONS *********************************/
#ifndef NO_PRIMARY_SELECTION
#if XIWS == MTFWS
static XI_OBJ *rp_xi_obj = NULL;
static void
receive_primesel(Widget widget, XtPointer data, Atom *selection,
Atom *type, XtPointer value, unsigned long *length, int *format)
{
char *s;
WINDOW win;
char *p;
/* printf("receive_primesel: ENTERED, widget %d, selection %d, type %d\n",
widget, *selection, *type); */
/* printf(" length %d, format %d\n",
*length, *format); */
/* check if request for primary selection was successful */
if (*selection != XA_PRIMARY || *type != XA_STRING || *format != 8)
{
/* printf("receive_primesel: get primary selection failed\n"); */
return;
}
/* allocate space and fill in text from selection value */
s = xvt_mem_alloc(*length + 1);
/* Assertion for out of memory? */
strncpy(s, (char *)value, *length);
s[*length] = '\0';
/* printf("receive_primesel: primary selection text = '%s'\n", s); */
XtFree((char *)value); /* this must be freed with XtFree */
/* xvt_dm_post_note("Text from Primary selection is '%s'", s); */
win = xi_get_window(rp_xi_obj);
rp_xi_obj = NULL;
for (p = s; *p != '\0'; ++p)
{
EVENT ev;
MEMCLEAR(ev);
ev.type = E_CHAR;
ev.v.chr.ch = (unsigned char)*p;
xi_event(win, &ev);
xvt_dwin_update(win);
}
xvt_mem_free(s);
}
static void
get_primary_selection(XI_OBJ *itf, WINDOW win)
{
Widget widget;
rp_xi_obj = itf;
/* printf("get_primary_selection: ENTERED, win %d\n", win); */
/* request PRIMARY selection */
widget = (Widget) xvt_vobj_get_attr(win, ATTR_X_WIDGET);
XtGetSelectionValue(widget, XA_PRIMARY, XA_STRING, receive_primesel, NULL,
XtLastTimestampProcessed(XtDisplay(widget)));
/* printf("get_primary_selection: returning\n"); */
}
#endif
#endif
BOOLEAN call_cb(XI_OBJ *itf, XI_EVENT *xiev)
{
XI_ITF_DATA *itf_data;
itf_data = itf->v.itf;
itf_data->in_callback++;
#if XI_IS_CH
CTOS_IS_CH;
xi_coalesce_invalidates(itf, TRUE);
CTOS_END;
#endif
(*itf_data->xi_eh)((struct _xi_obj *)itf, xiev);
#ifdef WINRUNNER
xir_record(itf, xiev);
#endif
if (xi_is_itf(itf))
{
#if XI_IS_CH
CTOS_IS_CH;
xi_coalesce_invalidates(itf, FALSE);
CTOS_END;
#endif
itf_data->in_callback--;
if (itf_data->closing)
{
itf_data->closing = FALSE;
xi_close_window_internal(itf);
return FALSE;
}
}
return TRUE;
}
static long near
event_to_longchar(EVENT *ep)
{
long c = ep->v.chr.ch;
if (ep->v.chr.control)
c |= XI_MOD_CONTROL;
if (ep->v.chr.shift)
c |= XI_MOD_SHIFT;
return(c);
}
void xi_column_set_pixel_width( XI_OBJ * column, int width )
{
int i;
XI_LIST_DATA * list;
LM_DATA* lm_data;
list = column->parent->v.list;
lm_data = (LM_DATA *)list->lm;
xvt_errmsg_sig_if(!(column->type == XIT_COLUMN), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20010", 20010,
"Non-column object sent to xi_column_set_pixel_width");
lm_column_set_pixel_width( list->lm, xi_obj_to_idx(column),
width );
if (list->sb_win && (! list->width))
xi_move_list_scroll_bar(column->parent);
i = xi_obj_to_idx(column);
if (i < lm_data->fixed_columns && list->hsb_win)
xi_move_list_hscroll_bar(column->parent);
}
void xi_set_column_width(XI_OBJ * column, int width)
{
int width_in_chars;
if (xi_get_xil_pref((XI_OBJ*)column->itf))
width_in_chars = width;
else
width_in_chars = width / XI_FU_MULTIPLE;
xi_column_set_pixel_width( column, width_in_chars
* ((LM_DATA *)column->parent->v.list->lm)
->pix_char_width );
}
static XI_OBJ *
xi_get_default(XI_OBJ *obj)
{
XI_OBJ * *objlist;
XI_OBJ *temp;
int n;
temp = obj->itf->v.itf->focus_obj;
if ( temp != NULL && temp->type == XIT_BTN )
return temp;
if (obj->type == XIT_BTN && obj->v.btn->dflt)
return(obj);
switch (obj->type)
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
return(NULL);
default:
break;
}
/* search in child list */
objlist = xi_get_member_list(obj, &n);
for (; n > 0; n--, objlist++)
{
/* call recursively for generality in future versions */
if ((temp = xi_get_default(*objlist)) != NULL)
return(temp);
}
return(NULL);
}
void
xi_hscroll_internal(XI_OBJ *xi_obj, int nbr_lines, int pos)
{
XI_OBJ *itf, *focus;
LM lm = xi_obj->v.list->lm;
itf = xi_obj->parent;
focus = xi_get_focus(itf);
if (focus && focus->parent == xi_obj)
{
if (xi_get_pref(XI_PREF_UNUSED_PREFERENCE))
{
lm_hscroll(lm, nbr_lines, pos);
}
else
{
if (xi_move_focus(itf))
lm_hscroll(lm, nbr_lines, pos);
}
}
else
lm_hscroll(lm, nbr_lines, pos);
}
void
xi_hscroll(XI_OBJ *xi_obj, int nbr_lines)
{
xi_hscroll_internal(xi_obj, nbr_lines, 0);
}
static void
control_event_hscroll(XI_OBJ *xi_obj, int nbr_lines, int pos)
{
XI_LIST_DATA *list_data;
XI_OBJ *other_list;
list_data = xi_obj->v.list;
xi_hscroll_internal(xi_obj, nbr_lines, pos);
if (list_data->horz_sync_list &&
! list_data->scrolling_in_progress)
{
list_data->scrolling_in_progress = TRUE;
other_list = xi_get_obj(xi_obj->itf,
list_data->horz_sync_list);
if (other_list)
xi_hscroll_internal(other_list, nbr_lines, pos);
list_data->scrolling_in_progress = FALSE;
}
}
static void
control_event_scroll( XI_OBJ *xi_obj, int nbr_lines, int percent,
BOOLEAN same_cell )
{
XI_LIST_DATA *list_data;
XI_OBJ *other_list;
list_data = xi_obj->v.list;
xi_scroll_internal( xi_obj, nbr_lines, percent, same_cell );
if (list_data->vert_sync_list &&
! list_data->scrolling_in_progress)
{
list_data->scrolling_in_progress = TRUE;
other_list = xi_get_obj(xi_obj->itf,
list_data->vert_sync_list);
if (other_list)
xi_scroll_internal(other_list, nbr_lines, percent, same_cell );
list_data->scrolling_in_progress = FALSE;
}
}
static void
control_event(XI_OBJ *itf, WINDOW win, EVENT *ep)
{
XI_ITF_DATA *itf_data;
XI_OBJ *xi_obj;
itf_data = itf->v.itf;
win = itf_data->xvt_win;
if ((xi_obj = xi_get_obj(itf, ep->v.ctl.id)) != NULL)
{
switch (xi_obj->type)
{
case XIT_BTN:
{
XI_EVENT xiev;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
call_cb(itf, &xiev);
if (xi_is_itf(itf) && xi_is_window(win)
&& xi_get_focus(itf) != xi_obj)
{
WINDOW front_win = xvt_scr_get_focus_vobj();
if (win)
xvt_scr_set_focus_vobj(win);
xvt_vobj_raise(win);
if (front_win != win && front_win)
xvt_scr_set_focus_vobj(front_win);
xvt_vobj_raise(front_win);
}
break;
}
case XIT_LIST:
{
switch (ep->v.ctl.ci.v.scroll.what)
{
case SC_LINE_UP:
control_event_scroll(xi_obj, -1, 0, TRUE );
break;
case SC_LINE_DOWN:
control_event_scroll(xi_obj, 1, 0, TRUE );
break;
case SC_PAGE_UP:
control_event_scroll(xi_obj, XI_SCROLL_PGUP, 0, TRUE );
break;
case SC_PAGE_DOWN:
control_event_scroll(xi_obj, XI_SCROLL_PGDOWN, 0, TRUE );
break;
case SC_THUMB:
{
int percent = ep->v.ctl.ci.v.scroll.pos;
if (xvt_sbar_get_proportion(ep->v.ctl.ci.win, HVSCROLL)
+ percent == 100)
control_event_scroll(xi_obj, XI_SCROLL_LAST, 0, TRUE );
else
control_event_scroll(xi_obj, XI_SCROLL_FIRST, percent, TRUE );
break;
}
}
break;
}
}
}
if (xi_is_itf(itf) &&
(xi_obj = xi_get_obj(itf, ep->v.ctl.id - HSCROLL_CID_CONST)) != NULL)
{
switch (xi_obj->type)
{
case XIT_LIST:
switch (ep->v.ctl.ci.v.scroll.what)
{
case SC_LINE_UP:
control_event_hscroll(xi_obj, -1, 0);
break;
case SC_LINE_DOWN:
control_event_hscroll(xi_obj, 1, 0);
break;
case SC_PAGE_UP:
control_event_hscroll(xi_obj, XI_SCROLL_PGUP, 0);
break;
case SC_PAGE_DOWN:
control_event_hscroll(xi_obj, XI_SCROLL_PGDOWN, 0);
break;
case SC_THUMB:
{
int prop;
int rng1, rng2;
int pos;
prop = xvt_sbar_get_proportion(ep->v.ctl.ci.win, HVSCROLL);
xvt_sbar_get_range(ep->v.ctl.ci.win, HVSCROLL, &rng1, &rng2);
pos = (rng2 - rng1 - prop) ?
(int)(ep->v.ctl.ci.v.scroll.pos * 100L / (rng2 - rng1 - prop)) : 0;
control_event_hscroll(xi_obj, XI_SCROLL_FIRST, pos);
break;
}
}
break;
}
}
}
void
xi_set_trap_obj(XI_OBJ *xi_obj)
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
itf = xi_obj->itf;
itf_data = itf->v.itf;
itf_data->trap_obj = xi_obj;
itf_data->trap_explicit = TRUE;
}
static void
destroy_controls(XI_OBJ *xi_obj)
{
XI_OBJ * *objp;
int i;
switch (xi_obj->type)
{
case XIT_LIST:
lm_remove_all_rows( (LM_DATA *) xi_obj->v.list->lm, TRUE );
break;
}
objp = xi_obj->children;
for (i = xi_obj->nbr_children; i > 0; i--, objp++)
destroy_controls(*objp);
}
static void
copy_to_clip(XI_OBJ *focus_obj)
{
int b, e;
char *buff;
xi_get_sel(focus_obj, &b, &e);
if (b != e)
{
char *p;
long len;
len = e - b;
buff = xi_get_text(focus_obj, NULL, 0);
if (xvt_cb_open(TRUE))
{
if ((p = xvt_cb_alloc_data(len + 1)) != NULL)
{
gstrncpy(p, &buff[b], (int)len);
p[(int)len] = '\0';
xvt_cb_put_data(CB_TEXT, NULL, len, (PICTURE)NULL);
xvt_cb_free_data();
}
xvt_cb_close();
}
}
}
static void
update_menus(void)
{
BOOLEAN paste_enable;
BOOLEAN cut_or_copy_enable = FALSE;
XI_OBJ *itf;
XI_ITF_DATA *itfdata;
WINDOW win;
win = xvt_scr_get_focus_vobj();
if (win == NULL_WIN || ! xi_is_window(win))
return;
itf = xi_get_itf(win);
itfdata = itf->v.itf;
if (itfdata->menu_win != NULL_WIN)
win = itfdata->menu_win;
if (itfdata->edit_menu)
{
XI_OBJ *focus_obj;
paste_enable = xvt_cb_has_format(CB_TEXT, NULL);
xvt_menu_set_item_enabled(win, M_EDIT_PASTE, paste_enable);
focus_obj = xi_get_focus(itf);
if ((focus_obj && (focus_obj->type == XIT_CELL)) ||
(focus_obj && (focus_obj->type == XIT_FIELD)))
{
int s, e;
xi_get_sel(focus_obj, &s, &e);
if (s != e)
cut_or_copy_enable = TRUE;
}
if (paste_enable != itfdata->paste_enable)
{
xvt_menu_set_item_enabled(win, M_EDIT_PASTE, paste_enable);
itfdata->paste_enable = paste_enable;
}
if (cut_or_copy_enable != itfdata->cut_or_copy_enable)
{
xvt_menu_set_item_enabled(win, M_EDIT_CUT, cut_or_copy_enable);
xvt_menu_set_item_enabled(win, M_EDIT_COPY, cut_or_copy_enable);
xvt_menu_set_item_enabled(win, M_EDIT_CLEAR, cut_or_copy_enable);
itfdata->cut_or_copy_enable = cut_or_copy_enable;
}
}
}
static void
do_edit_menu(XI_OBJ *itf, EVENT *ep)
{
XI_OBJ *focus_obj;
unsigned long attrib = 0L;
focus_obj = xi_get_focus(itf);
if (focus_obj && focus_obj->type != XIT_ITF)
{
switch (focus_obj->type)
{
case XIT_FIELD:
attrib = xi_get_attrib(focus_obj);
break;
case XIT_CELL:
{
XI_OBJ *list, *column;
XI_OBJ * *members;
int col_nbr, nbr_members;
list = focus_obj->parent;
members = xi_get_member_list(list, &nbr_members);
col_nbr = focus_obj->v.cell.column;
column = members[col_nbr];
attrib = xi_get_attrib(column);
break;
}
}
if (attrib & XI_ATR_EDITMENU)
{
int b, e;
switch (ep->v.cmd.tag)
{
case M_EDIT_CUT:
copy_to_clip(focus_obj);
/* fall through */
case M_EDIT_CLEAR:
xi_get_sel(focus_obj, &b, &e);
if (b != e)
{
EVENT ev;
MEMCLEAR(ev);
ev.type = E_CHAR;
ev.v.chr.ch = K_DEL;
xi_event(xi_get_window(itf), &ev);
}
update_menus();
break;
case M_EDIT_COPY:
copy_to_clip(focus_obj);
update_menus();
break;
case M_EDIT_PASTE:
if (focus_obj->type == XIT_FIELD)
if (xi_get_txedit(focus_obj) != BAD_TXEDIT)
if (xi_get_pref(XI_PREF_MULTILINE_QUICK_PASTE))
break;
if (xvt_cb_open(FALSE))
{
char *p;
long size;
if ((p = xvt_cb_get_data(CB_TEXT, NULL, &size)) != NULL)
{
WINDOW win;
win = xi_get_window(itf);
itf->v.itf->pasting = TRUE;
while ( size-- > 0 )
{
EVENT ev;
MEMCLEAR(ev);
ev.type = E_CHAR;
ev.v.chr.ch = (unsigned char)*p++;
xi_event(win, &ev);
xvt_dwin_update(win);
}
itf->v.itf->pasting = FALSE;
}
xvt_cb_close();
}
update_menus();
break;
}
}
}
}
#define RALEN 32
#define RCT_TOP 0
#define RCT_LEFT 1
#define RCT_BOTTOM 2
#define RCT_RIGHT 3
static BOOLEAN
bound_rct(RCT *ra, int ra_len, RCT *rct, int which)
{
int i;
BOOLEAN b;
switch (which)
{
case RCT_TOP:
{
for (i = 0; i < ra_len; ++i)
{
if (ra->bottom < rct->bottom && ra->bottom >= rct->top)
rct->top = ra->bottom;
++ra;
}
break;
}
case RCT_LEFT:
{
for (i = 0; i < ra_len; ++i)
{
if (ra->right < rct->right && ra->right >= rct->left)
rct->left = ra->right;
++ra;
}
break;
}
case RCT_BOTTOM:
{
for (i = 0; i < ra_len; ++i)
{
if (ra->top > rct->top && ra->top <= rct->bottom)
rct->bottom = ra->top;
++ra;
}
break;
}
case RCT_RIGHT:
{
for (i = 0; i < ra_len; ++i)
{
if (ra->left > rct->left && ra->left <= rct->right)
rct->right = ra->left;
++ra;
}
break;
}
}
b = (rct->top < rct->bottom && rct->left < rct->right);
return b;
}
static void
draw_all_rects(XI_OBJ *itf)
{
RCT ra[RALEN];
RCT rct;
int list_len, ra_len, i;
XI_OBJ * *child;
XI_ITF_DATA *itf_data;
int cur_delta_x, cur_delta_y;
#if XIWS == XOLWS || XIWS == MTFWS
/* X GRAY SCALE HACK */
xi_set_xvt_back_color(itf->v.itf->xvt_win, COLOR_WHITE);
{
DRAW_CTOOLS ct;
WINDOW win = itf->v.itf->xvt_win;
xi_get_draw_ctools(win, &ct);
ct.opaque_text = FALSE;
xi_set_draw_ctools(win, &ct);
xi_draw_text(win, 0, 0, " ", -1);
}
#endif
itf_data = itf->v.itf;
cur_delta_x = itf_data->delta_x;
cur_delta_y = itf_data->delta_y;
list_len = 0;
for (i = 0, child = itf->children; i < itf->nbr_children; ++i, ++child)
{
if ((*child)->type == XIT_LIST && (xi_get_attrib(*child) & XI_ATR_VISIBLE))
{
if (list_len < (RALEN - 1))
{
xi_get_rect((*child), &ra[list_len]);
++list_len;
}
}
}
ra_len = list_len;
if (list_len)
{
int cnt;
for (cnt = 0; cnt < list_len; ++cnt)
{
RCT lr;
lr = ra[cnt];
/* do left rect */
rct.left = 0;
rct.top = 0;
rct.bottom = MAXPIX;
rct.right = lr.left;
if (bound_rct(ra, ra_len, &rct, RCT_LEFT))
{
VRCT_TO_PRCT(&rct);
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
}
/* do top rect */
rct.left = 0;
rct.top = 0;
rct.bottom = lr.top;
rct.right = MAXPIX;
if (bound_rct(ra, ra_len, &rct, RCT_TOP))
VRCT_TO_PRCT(&rct);
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
/* do right rect */
rct.left = lr.right;
rct.top = 0;
rct.bottom = MAXPIX;
rct.right = MAXPIX;
if (bound_rct(ra, ra_len, &rct, RCT_RIGHT))
VRCT_TO_PRCT(&rct);
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
/* do bottom rect */
rct.left = 0;
rct.top = lr.bottom;
rct.bottom = MAXPIX;
rct.right = MAXPIX;
if (bound_rct(ra, ra_len, &rct, RCT_BOTTOM))
VRCT_TO_PRCT(&rct);
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
}
}
else
{
rct.top = 0;
rct.left = 0;
rct.bottom = MAXPIX;
rct.right = MAXPIX;
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
}
}
static void
draw_background(XI_OBJ *itf)
{
XI_ITF_DATA *itf_data = itf->v.itf;
WINDOW win = itf_data->xvt_win;
if (itf_data->back_color)
{
DRAW_CTOOLS t;
CBRUSH cbrush;
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
CBRUSH hollow_cbrush;
RCT rct;
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
xvt_app_get_default_ctools(&t);
xvt_dwin_set_draw_ctools(win, &t);
hollow_cbrush.color = COLOR_WHITE;
hollow_cbrush.pat = PAT_HOLLOW;
xvt_dwin_set_cbrush(win, &hollow_cbrush);
rct.top = 0;
rct.left = 0;
rct.bottom = 0;
rct.right = 0;
xvt_dwin_draw_rect(win, &rct);
#endif
#if XIWS == XOLWS || XIWS == MTFWS
/* X GRAY SCALE HACK */
xi_set_xvt_back_color(win, COLOR_WHITE);
{
DRAW_CTOOLS ct;
xi_get_draw_ctools(win, &ct);
ct.opaque_text = FALSE;
xi_set_draw_ctools(win, &ct);
xi_draw_text(win, 0, 0, " ", -1);
}
#endif
xvt_app_get_default_ctools(&t);
xi_set_draw_ctools(win, &t);
xvt_dwin_set_cpen(win, &hollow_cpen);
cbrush.pat = PAT_SOLID;
cbrush.color = itf_data->back_color;
#if XI_IS_CH
CTOS_IS_CH;
xi_fix_color(&cbrush.color);
CTOS_END;
#endif
xvt_dwin_set_cbrush(win, &cbrush);
xvt_dwin_set_clip(win, NULL);
draw_all_rects(itf);
}
}
static void
do_post_event(XI_OBJ *itf, EVENT *ep)
{
XI_EVENT xiev;
if (xi_is_itf(itf))
{
/* send XVT event */
MEMCLEAR(xiev);
xiev.type = XIE_XVT_POST_EVENT;
xiev.v.xvte = *ep;
xiev.refused = FALSE;
call_cb(itf, &xiev);
}
}
/* ------------------------------------------------------------------------ */
/* get_text_ctools */
/* ------------------------------------------------------------------------ */
static DRAW_CTOOLS * near
get_text_ctools(XI_ITF_DATA *itf_data, DRAW_CTOOLS *ct, FONT_OBJ *font)
{
xvt_app_get_default_ctools(ct);
ct->pen.color = ct->fore_color = COLOR_BLACK;
ct->opaque_text = FALSE;
if (itf_data->font)
*font = *itf_data->font;
else
*font = xi_sysfont;
return(ct);
}
/* ------------------------------------------------------------------------ */
/* xi_draw_obj */
/* ------------------------------------------------------------------------ */
static void near
xi_draw_obj(XI_OBJ *xi_obj)
{
WINDOW win;
XI_ITF_DATA *itf_data;
itf_data = xi_obj->itf->v.itf;
win = itf_data->xvt_win;
switch (xi_obj->type)
{
case XIT_TEXT:
{
XI_TEXT_DATA *text;
DRAW_CTOOLS ct;
FONT_OBJ font;
text = xi_obj->v.text;
get_text_ctools(itf_data, &ct, &font);
ct.back_color = itf_data->back_color;
ct.fore_color = COLOR_BLACK;
if (text->fore_color)
ct.fore_color = text->fore_color;
if (text->back_color)
{
ct.opaque_text = TRUE;
ct.back_color = text->back_color;
}
xi_set_xvt_font(win, &font, TRUE);
if (text->font)
xi_set_xvt_font(win, text->font, FALSE);
xi_set_draw_ctools(win, &ct);
if ((text->attrib & XI_ATR_ENABLED))
xi_set_xvt_fore_color(win, ct.fore_color);
else
xi_set_xvt_fore_color( win,
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
xi_set_xvt_back_color(win, ct.back_color);
xi_draw_clipped_text(win, text->text, &text->rct, &text->rct,
text->attrib | XI_ATR_VCENTER, FALSE, 0, -1);
break;
}
case XIT_LINE:
{
XI_LINE_DATA *line;
PNT pnt1, pnt2;
line = xi_obj->v.line;
if (line->attrib & XI_ATR_VISIBLE)
{
pnt1 = line->pnt1;
pnt2 = line->pnt2;
if ((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
xi_draw_3d_line(win, pnt1, pnt2, line->well);
else
{
CPEN cpen;
cpen = black_cpen;
if (line->fore_color)
cpen.color = line->fore_color;
xi_set_cpen(win, &cpen);
if (line->back_color)
xi_set_xvt_back_color(win, line->back_color);
xi_move_to(win, pnt1);
xi_draw_line(win, pnt2);
}
}
break;
}
case XIT_RECT:
{
XI_RECT_DATA *rect;
RCT rct;
rect = xi_obj->v.rect;
if (rect->attrib & XI_ATR_VISIBLE)
{
rct = rect->rct;
if ((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
{
xi_draw_3d_rect(win, &rct, rect->well, 1,
rect->hilight_color, rect->back_color,
rect->shadow_color);
if (rect->ridge)
{
xi_inflate_rect(&rct, -1);
xi_draw_3d_rect(win, &rct, (BOOLEAN)(! rect->well), 1,
rect->hilight_color, rect->back_color,
rect->shadow_color);
}
}
else
{
CPEN cpen;
CBRUSH cbrush;
cpen = black_cpen;
if (rect->fore_color)
cpen.color = rect->fore_color;
xi_set_cpen(win, &cpen);
cbrush.pat = PAT_SOLID;
cbrush.color = COLOR_WHITE;
if (rect->back_color)
cbrush.color = rect->back_color;
xi_set_cbrush(win, &cbrush);
xi_draw_rect(win, &rct);
}
}
break;
}
default:
break;
}
}
/* ------------------------------------------------------------------------ */
/* draw_field_button */
/* ------------------------------------------------------------------------ */
static void
draw_field_button(XI_OBJ *xi_obj)
{
XI_FIELD_DATA *fd;
unsigned long attrib;
STX_DATA *stxd;
#if XI_IS_NOT_CH
int x, y;
RCT cr, r;
#endif
WINDOW win;
attrib = xi_get_attrib(xi_obj);
if (! (attrib & XI_ATR_VISIBLE))
return;
fd = xi_obj->v.field;
stxd = (STX_DATA *)fd->stx;
win = xi_obj->itf->v.itf->xvt_win;
xi_set_draw_mode(win, M_COPY);
xi_set_clip(win, NULL);
#if XI_IS_NOT_CH
CTOS_IS_PM;
r = fd->btn_rct;
r.top++;
r.left++;
r.bottom--;
r.right--;
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
{
CBRUSH hollow_cbrush;
RCT rct;
DRAW_CTOOLS t;
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
xvt_app_get_default_ctools(&t);
xvt_dwin_set_draw_ctools(win, &t);
hollow_cbrush.color = COLOR_WHITE;
hollow_cbrush.pat = PAT_HOLLOW;
xvt_dwin_set_cbrush(win, &hollow_cbrush);
rct.top = 0;
rct.left = 0;
rct.bottom = 0;
rct.right = 0;
xvt_dwin_draw_rect(win, &rct);
}
#endif
if ((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
{
const COLOR color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
const COLOR color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
const COLOR color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
xi_draw_3d_rect(win, &r, fd->down, 2, color_light, color_ctrl, color_dark);
}
else
{
xi_set_cbrush(win, &white_cbrush);
xi_set_cpen(win, &hollow_cpen);
xi_draw_rect(win, &r);
}
x = r.left + 3;
y = r.top + 2;
cr = r;
cr.top += 2;
cr.left += 2;
cr.bottom -= 2;
cr.right -= 2;
xi_set_clip(win, &cr);
#if XIWS == PMWS
/* Hack for OS2 - Icons are drawn differenty depending on whether
opaque_text is set or not in the DRAW_CTOOLS */
{
DRAW_CTOOLS ct;
xi_get_draw_ctools(win, &ct);
ct.opaque_text = TRUE;
ct.back_color = xi_get_pref(XI_PREF_COLOR_CTRL);
ct.fore_color = COLOR_BLACK;
xi_set_draw_ctools(win, &ct);
}
#endif
{
int icon_rid;
icon_rid = fd->icon_rid;
if (icon_rid == 0)
icon_rid = (int) xi_get_pref( XI_PREF_COMBO_ICON );
if (fd->down)
xi_draw_icon( win, x, y + 1, icon_rid, COLOR_BLACK,
xi_get_pref(XI_PREF_COLOR_CTRL));
else
xi_draw_icon( win, x, y, icon_rid, COLOR_BLACK,
xi_get_pref(XI_PREF_COLOR_CTRL));
}
xi_set_clip(win, NULL);
xi_set_cpen(win, &black_cpen);
xi_set_cbrush(win, &hollow_cbrush);
xi_draw_rect(win, &fd->btn_rct);
CTOS_END;
#endif
#if XI_IS_CH
CTOS_IS_CH;
NOREF(stxd);
{
CBRUSH black_cbrush;
black_cbrush = white_cbrush;
black_cbrush.color = COLOR_BLACK;
xi_set_clip(win, NULL);
xi_set_cpen(win, &hollow_cpen);
xi_set_cbrush(win, &black_cbrush);
xi_draw_rect(win, &fd->btn_rct);
}
CTOS_END;
#endif
}
/* ------------------------------------------------------------------------ */
/* field_event */
/* ------------------------------------------------------------------------ */
static void
field_event(XI_OBJ *xi_obj, EVENT *ep)
{
XI_FIELD_DATA *field_data;
RCT rct;
#if XIWS == MACWS
RCT irct;
WINDOW win;
#endif
field_data = xi_obj->v.field;
rct = field_data->btn_rct;
#if XIWS == MACWS
irct = rct;
xi_inflate_rect(&irct, -1);
win = xi_obj->itf->v.itf->xvt_win;
#endif
switch (ep->type)
{
case E_CHAR:
{
long button_key;
BOOLEAN shift, control;
button_key = xi_get_pref(XI_PREF_BUTTON_KEY);
shift = (BOOLEAN)((button_key & XI_MOD_SHIFT) != 0);
control = (BOOLEAN)((button_key & XI_MOD_CONTROL) != 0);
button_key &= 0xffffffL;
if (button_key == ep->v.chr.ch &&
shift == ep->v.chr.shift &&
control == ep->v.chr.control)
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb(itf, &xiev);
}
break;
}
case E_UPDATE:
if (field_data->button)
draw_field_button(xi_obj);
break;
case E_MOUSE_DOWN:
{
unsigned long attrib;
attrib = stx_get_attrib(xi_obj->v.field->stx);
attrib &= (XI_ATR_ENABLED | XI_ATR_VISIBLE);
if (field_data->button &&
attrib == (XI_ATR_ENABLED | XI_ATR_VISIBLE))
{
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
{
field_data->down = TRUE;
field_data->down_in_btn = TRUE;
#if XIWS == MACWS
xi_invalidate_rect(win, &irct);
#else
draw_field_button(xi_obj);
#endif
xi_set_trap_obj(xi_obj);
xi_trap_mouse(xi_obj->itf->v.itf->xvt_win);
}
}
break;
}
case E_MOUSE_MOVE:
if (field_data->button && field_data->down_in_btn)
{
if (xvt_rect_has_point(&rct, ep->v.mouse.where) && ! field_data->down)
{
field_data->down = TRUE;
#if XIWS == MACWS
xi_invalidate_rect(win, &irct);
#else
draw_field_button(xi_obj);
#endif
}
if (! xvt_rect_has_point(&rct, ep->v.mouse.where) && field_data->down)
{
field_data->down = FALSE;
#if XIWS == MACWS
xi_invalidate_rect(win, &irct);
#else
draw_field_button(xi_obj);
#endif
}
}
break;
case E_MOUSE_UP:
if (field_data->button && field_data->down_in_btn)
{
xi_release_mouse();
if (field_data->down)
{
field_data->down = FALSE;
#if XIWS == MACWS
xi_invalidate_rect(win, &irct);
#else
draw_field_button(xi_obj);
#endif
}
field_data->down_in_btn = FALSE;
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
{
if (xi_move_focus(xi_obj))
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb(itf, &xiev);
}
}
}
break;
}
}
/* ------------------------------------------------------------------------ */
/* form_event */
/* ------------------------------------------------------------------------ */
static BOOLEAN near
form_event(XI_OBJ *xi_obj, EVENT *ep)
{
BOOLEAN retval = FALSE;
XI_OBJ *focus_obj = xi_obj->itf->v.itf->focus_obj;
switch(ep->type)
{
case E_COMMAND:
/* TODO -- navigation */
break;
case E_CHAR:
{
long c = event_to_longchar(ep);
XI_OBJ *next_obj = NULL;
/* navigation character event */
if ( c == '\r' && xi_obj->itf->v.itf->tab_on_enter
&& xi_obj->type != XIT_BTN )
c = xi_get_pref( XI_PREF_FORM_TAB_CHAR );
if ( c == xi_get_pref(XI_PREF_FORM_TAB_CHAR) || c == K_DOWN )
{
next_obj = xi_find_next_obj(focus_obj, XI_NEXT_FORM_TAB, c);
}
else
if (c == xi_get_pref(XI_PREF_FORM_BACKTAB_CHAR) ||
c == K_UP)
{
next_obj = focus_obj;
do {
next_obj = xi_find_next_obj(next_obj, XI_NEXT_FORM_BACKTAB, c);
} while (next_obj != NULL && next_obj != focus_obj &&
(next_obj->type == XIT_FORM || next_obj->type == XIT_CONTAINER));
}
if (next_obj != NULL)
{
xi_move_focus_internal(next_obj, TRUE, TRUE,
((c == xi_get_pref(XI_PREF_FORM_TAB_CHAR)) || (c == K_DOWN)) ? 1 : 2);
retval = TRUE;
}
break;
}
default:
break;
}
return retval;
}
/* ------------------------------------------------------------------------ */
/* invalidate_button_rect */
/* ------------------------------------------------------------------------ */
static void near
invalidate_button_rect(XI_OBJ *xi_obj, XI_BTN_DATA *bd, RCT *rct)
{
if ((bd->type == XIBT_BUTTON || bd->type == XIBT_BUTTON_CHECKBOX ||
bd->type == XIBT_RADIOBTN) && bd->drawable)
{
RCT r;
WINDOW win;
r = *rct;
xi_inflate_rect(&r, -4);
win = xi_get_window(xi_obj->itf);
xi_invalidate_rect(win, &r);
xvt_dwin_update(win);
}
}
/* ------------------------------------------------------------------------ */
/* btn_event */
/* ------------------------------------------------------------------------ */
static BOOLEAN near
btn_event(XI_OBJ *xi_obj, EVENT *ep)
{
BOOLEAN enabled;
BOOLEAN visible;
BOOLEAN focus;
BOOLEAN dflt;
BOOLEAN send_to_form = TRUE;
BOOLEAN ret_val;
RCT rct;
unsigned long attrib;
XI_BTN_DATA *bd;
if (! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS))
{
attrib = xi_get_attrib(xi_obj);
enabled = ((attrib & XI_ATR_ENABLED) != 0);
visible = ((attrib & XI_ATR_VISIBLE) != 0);
focus = (xi_get_focus(xi_obj->itf) == xi_obj);
bd = xi_obj->v.btn;
dflt = bd->dflt;
rct = bd->rct;
switch (ep->type)
{
case E_TIMER:
return FALSE;
case E_CHAR:
if (ep->v.chr.ch == ' ' && focus)
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb(itf, &xiev);
if (! xi_is_itf(itf))
send_to_form = FALSE;
}
break;
case E_UPDATE:
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
bd->up_icon_rid, bd->disabled_icon_rid, enabled,
visible, focus, bd->down, dflt, bd->checked, FALSE);
break;
case E_MOUSE_DBL:
if (! xi_get_pref(XI_PREF_DBL_PRESSES_BUTTON))
break;
/* else fall through */
case E_MOUSE_DOWN:
{
RCT hit_rct;
if ((enabled == FALSE)||(visible == FALSE))
break;
hit_rct = rct;
if (bd->packed == TRUE)
xi_inflate_rect(&hit_rct,
-((int)xi_get_pref(XI_PREF_CONTAINER_GRID_WIDTH)));
if (xvt_rect_has_point(&hit_rct, ep->v.mouse.where))
{
bd->down = TRUE;
bd->down_in_btn = TRUE;
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
bd->up_icon_rid, bd->disabled_icon_rid, enabled,
visible, focus, bd->down, dflt, bd->checked, FALSE);
invalidate_button_rect(xi_obj, bd, &rct);
xi_set_trap_obj(xi_obj);
xi_trap_mouse(xi_get_window(xi_obj->itf));
}
break;
}
case E_MOUSE_MOVE:
if (bd->down_in_btn)
{
if (xvt_rect_has_point(&rct, ep->v.mouse.where) && ! bd->down)
{
bd->down = TRUE;
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
bd->up_icon_rid, bd->disabled_icon_rid,
enabled, visible, focus, bd->down, dflt,
bd->checked, FALSE);
invalidate_button_rect(xi_obj, bd, &rct);
}
else if (! xvt_rect_has_point(&rct, ep->v.mouse.where) &&
bd->down)
{
bd->down = FALSE;
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
bd->up_icon_rid, bd->disabled_icon_rid,
enabled, visible, focus, bd->down, dflt,
bd->checked, FALSE);
invalidate_button_rect(xi_obj, bd, &rct);
}
}
break;
case E_MOUSE_UP:
if (bd->down_in_btn)
{
bd->down_in_btn = FALSE;
if (bd->down)
{
bd->down = FALSE;
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
bd->up_icon_rid, bd->disabled_icon_rid,
enabled, visible, focus, bd->down, dflt,
bd->checked, FALSE);
invalidate_button_rect(xi_obj, bd, &rct);
}
xi_release_mouse();
if (ep->type == E_MOUSE_UP &&
xvt_rect_has_point(&rct, ep->v.mouse.where))
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb(itf, &xiev);
if (! xi_is_itf(itf))
send_to_form = FALSE;
}
}
break;
}
}
ret_val = TRUE;
if (send_to_form)
ret_val = form_event(xi_obj, ep);
return ret_val;
}
/* ------------------------------------------------------------------------ */
/* draw_list_button */
/* ------------------------------------------------------------------------ */
#define P_OFFSET 3
static void
draw_list_button(WINDOW win, RCT *rct, BOOLEAN down)
{
#if XI_IS_NOT_CH
int x, y, plus_width, plus_height;
PNT p;
RCT r;
BOOLEAN x2;
CTOS_IS_PM;
r = *rct;
xi_set_cpen(win, &black_cpen);
xi_set_cbrush(win, &hollow_cbrush);
xi_draw_rect(win, &r);
r.top++;
r.left++;
r.bottom--;
r.right--;
if ((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
{
const COLOR color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
const COLOR color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
const COLOR color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
xi_draw_3d_rect(win, &r, down, 2, color_light, color_ctrl, color_dark);
}
else
{
xi_set_cbrush(win, &white_cbrush);
xi_draw_rect(win, &r);
}
p.h = rct->left;
p.v = rct->top - 1;
xi_set_cpen(win, &black_cpen);
xi_move_to(win, p);
p.h = rct->right;
xi_draw_line(win, p);
plus_width = r.right - r.left;
plus_height = plus_width + 4;
x = r.left + plus_width / 2;
y = r.top + plus_height / 2;
x2 = ! ((r.right + r.left) % 2);
if (x2)
x--;
y--;
xi_set_cpen(win, &black_cpen);
/*
draw vertical lines
*/
p.h = x;
p.v = r.top + P_OFFSET + down;
xi_move_to(win, p);
p.v = r.top + plus_height - P_OFFSET + down;
xi_draw_line(win, p);
p.h = x + 1;
p.v = r.top + P_OFFSET + down;
xi_move_to(win, p);
p.v = r.top + plus_height - P_OFFSET + down;
xi_draw_line(win, p);
/*
draw horizontal lines
*/
p.v = y + down;
p.h = r.left + P_OFFSET;
xi_move_to(win, p);
p.h = r.left + plus_width - P_OFFSET;
xi_draw_line(win, p);
p.v = y + down + 1;
p.h = r.left + P_OFFSET;
xi_move_to(win, p);
p.h = r.left + plus_width - P_OFFSET;
xi_draw_line(win, p);
CTOS_END;
#endif
NOREF(rct);
NOREF(down);
NOREF(win);
}
/* ------------------------------------------------------------------------ */
/* list_event */
/* ------------------------------------------------------------------------ */
static void
list_event(XI_OBJ *xi_obj, EVENT *ep)
{
XI_LIST_DATA *list_data;
RCT rct;
LM_DATA *lmp;
list_data = xi_obj->v.list;
lmp = (LM_DATA *)list_data->lm;
if (lmp->attrib & XI_ATR_VISIBLE)
{
rct = list_data->sbb_rct;
switch (ep->type)
{
case E_UPDATE:
if (list_data->scroll_bar_button)
draw_list_button(lmp->win, &rct, list_data->down);
break;
case E_MOUSE_DOWN:
if (list_data->scroll_bar_button)
{
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
{
list_data->down = TRUE;
list_data->down_in_btn = TRUE;
draw_list_button(lmp->win, &rct, TRUE);
xi_set_trap_obj(xi_obj);
xi_trap_mouse(xi_obj->itf->v.itf->xvt_win);
}
}
break;
case E_MOUSE_MOVE:
if (list_data->scroll_bar_button && list_data->down_in_btn)
{
if (xvt_rect_has_point(&rct, ep->v.mouse.where) && ! list_data->down)
{
list_data->down = TRUE;
draw_list_button(lmp->win, &rct, TRUE);
}
if (! xvt_rect_has_point(&rct, ep->v.mouse.where) && list_data->down)
{
list_data->down = FALSE;
draw_list_button(lmp->win, &rct, FALSE);
}
}
break;
case E_MOUSE_UP:
if (list_data->scroll_bar_button && list_data->down_in_btn)
{
xi_release_mouse();
if (list_data->down)
{
list_data->down = FALSE;
draw_list_button(lmp->win, &rct, FALSE);
}
list_data->down_in_btn = FALSE;
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb(itf, &xiev);
}
}
break;
}
}
}
/* ------------------------------------------------------------------------ */
/* itf_event */
/* ------------------------------------------------------------------------ */
static BOOLEAN near
itf_event(XI_OBJ *xi_obj, EVENT *ep)
{
BOOLEAN retval = FALSE;
XI_ITF_DATA *itf_data;
XI_OBJ *focus_obj;
itf_data = xi_obj->itf->v.itf;
focus_obj = itf_data->focus_obj;
switch(ep->type)
{
case E_COMMAND:
/* TODO -- navigation */
break;
case E_CHAR:
{
long c = event_to_longchar(ep);
XI_OBJ *next_obj = NULL;
xvt_errmsg_sig_if(!(focus_obj->itf == xi_obj), NULL_WIN,
SEV_FATAL, ERR_ASSERT_4, "20030", 20030,
"Internal focus error");
/* navigation character event */
if (c == xi_get_pref(XI_PREF_ITF_TAB_CHAR))
next_obj = xi_find_next_obj(focus_obj, XI_NEXT_ITF_TAB, c);
else
if (c == xi_get_pref(XI_PREF_ITF_BACKTAB_CHAR))
next_obj = xi_find_next_obj(focus_obj, XI_NEXT_ITF_BACKTAB,
c);
else
if (c == xi_get_pref(XI_PREF_FORM_TAB_CHAR) &&
focus_obj->type == XIT_ITF)
next_obj = xi_search_itf(focus_obj, XI_SEARCH_FOR_FOCUSABLE,
0);
if (c == '\r')
{
XI_OBJ *dflt_obj;
dflt_obj = xi_get_default(xi_obj->itf);
if (dflt_obj && (xi_get_attrib(dflt_obj) & (XI_ATR_ENABLED
| XI_ATR_VISIBLE)) == (XI_ATR_ENABLED | XI_ATR_VISIBLE))
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR(xiev);
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = dflt_obj;
itf = xi_obj->itf;
call_cb(itf, &xiev);
retval = TRUE;
}
}
if (next_obj != NULL)
{
xi_move_focus_internal(next_obj, TRUE, FALSE, 0);
retval = TRUE;
}
break;
}
default:
break;
}
return(retval);
}
/* ------------------------------------------------------------------------ */
/* xi_send_event */
/* ------------------------------------------------------------------------ */
static int
xi_send_event(XI_OBJ *xi_obj, EVENT *ep, BOOLEAN do_subtree)
{
int n;
XI_OBJ * *objlist;
BOOLEAN send_to_parent = FALSE;
int retval = 0;
switch(xi_obj->type)
{
case XIT_RECT:
case XIT_TEXT:
case XIT_LINE:
if (ep->type == E_UPDATE)
xi_draw_obj(xi_obj);
break;
case XIT_FIELD:
field_event(xi_obj, ep);
retval = stx_event(xi_obj->v.field->stx, ep);
send_to_parent = !retval;
/* don't send any character events (for navigation to the parent if pasting */
if (ep->type == E_CHAR && xi_obj->itf->v.itf->pasting)
send_to_parent = FALSE;
break;
case XIT_CONTAINER:
send_to_parent = TRUE;
break;
case XIT_FORM:
send_to_parent = !form_event(xi_obj, ep);
break;
case XIT_BTN:
send_to_parent = !btn_event(xi_obj, ep);
break;
case XIT_LIST:
{
XI_OBJ *itf;
itf = xi_obj->itf;
if (xi_obj->itf->v.itf->update_obj)
{
lm_event(xi_obj->v.list->lm, ep);
send_to_parent = FALSE;
do_subtree = FALSE;
}
else
{
list_event(xi_obj, ep);
retval = lm_event(xi_obj->v.list->lm, ep);
send_to_parent = !retval;
/* Don't broadcast events to columns */
do_subtree = FALSE;
}
if (xi_is_itf(itf))
if (xi_obj->itf->v.itf->pasting)
send_to_parent = FALSE;
break;
}
case XIT_ITF:
itf_event(xi_obj, ep);
break;
case XIT_CELL:
/* Send events to list as there is no handler for individual cells */
send_to_parent = TRUE;
break;
case XIT_COLUMN:
default:
/* ignored */
break;
}
if (do_subtree && xi_obj->type != XIT_GROUP)
{
int retval;
/* loop over sub-objects */
objlist = xi_get_member_list(xi_obj, &n);
for (; n > 0; n--, objlist++)
{
retval = xi_send_event(*objlist, ep, do_subtree);
if (retval)
{
return retval;
}
}
}
if (send_to_parent)
{
retval = xi_send_event(xi_obj->parent, ep, FALSE);
return retval;
}
return retval;
}
void
xi_event(WINDOW win, EVENT *ep)
{
XI_OBJ *itf;
XI_EVENT xiev;
XI_ITF_DATA *itf_data;
BOOLEAN retval;
CURSOR new_cursor;
if (win == NULL_WIN)
win = xvt_scr_get_focus_vobj();
if (win == NULL_WIN || ((itf = xi_get_itf(win)) == NULL))
return;
itf_data = itf->v.itf;
/* send XVT event */
MEMCLEAR(xiev);
xiev.type = XIE_XVT_EVENT;
xiev.v.xvte = *ep;
xiev.refused = FALSE;
if (!call_cb(itf, &xiev))
return;
if (xiev.refused)
return;
*ep = xiev.v.xvte;
if (ep->type == E_MOUSE_UP)
xi_release_mouse();
if (! xi_eh(win, ep))
return;
if (ep->type == E_UPDATE)
xi_dequeue();
#if (XIWS == PMWS) || (XIWS == MTFWS) || (XIWS == XOLWS) || (XIWS == WMWS) || (XIWS == GRWS) || (XIWS == MACWS)
#if (XIWS == MACWS)
if (xi_modal_win && ep->type == E_FOCUS && (! ep->v.active) && win == xi_modal_win)
{
xvt_scr_set_focus_vobj(xi_modal_win);
xvt_vobj_raise(xi_modal_win);
}
#else
if (xi_modal_win && ep->type == E_FOCUS && ep->v.active && win != xi_modal_win)
{
xvt_scr_set_focus_vobj(xi_modal_win);
xvt_vobj_raise(xi_modal_win);
}
#endif
if (xi_modal_win && win != xi_modal_win && xvt_vobj_get_parent(win) != xi_modal_win && ep->type != E_UPDATE && ep->type != E_TIMER)
return;
#endif
MEMCLEAR(xiev);
switch (ep->type)
{
case E_TIMER:
{
xi_send_event(itf, ep, TRUE);
break;
}
case E_UPDATE:
{
if (itf_data->update_obj)
{
xi_send_event(itf_data->update_obj, ep, FALSE);
itf_data->update_obj = NULL;
}
else
{
itf->v.itf->half_baked = FALSE;
draw_background(itf);
xi_send_event(itf, ep, TRUE);
}
break;
}
case E_MOUSE_DOWN:
case E_MOUSE_DBL:
{
XI_OBJ *itf2;
itf2 = itf;
itf_data->mouse_is_down = TRUE;
xi_send_event(itf, ep, TRUE);
if (xi_is_itf(itf2))
if (! itf_data->trap_explicit)
itf_data->trap_obj = itf_data->focus_obj;
break;
}
case E_CHAR:
#if XIWS == WINWS
if (ep->v.chr.ch == '\t' && ep->v.chr.shift)
/* ignore bogus shift-tab from XVT */
break;
#endif
#if XVT_OS != XVT_OS_CTOS
#if XIWS == WMWS
/* TODO ep->v.chr.shift and ep->v.chr.control are not set properly for XVT/CH */
ep->v.chr.shift = FALSE;
ep->v.chr.control = FALSE;
#endif
#endif
if (ep->v.chr.ch == K_BTAB)
ep->v.chr.shift = FALSE;
if (itf_data->focus_obj != NULL)
xi_send_event(itf_data->focus_obj, ep, FALSE);
update_menus();
break;
case E_SIZE:
xi_send_event(itf, ep, TRUE);
break;
case E_MOUSE_UP:
#ifndef NO_PRIMARY_SELECTION
#if XIWS == MTFWS
if (ep->v.mouse.button == 2)
get_primary_selection(itf, win);
#endif
#endif
itf_data->mouse_is_down = FALSE;
if (itf_data->trap_obj != NULL)
xi_send_event(itf_data->trap_obj, ep, FALSE);
if (xi_is_itf(itf))
{
itf_data->trap_obj = NULL;
itf_data->trap_explicit = FALSE;
update_menus();
}
break;
case E_MOUSE_MOVE:
if (itf_data->trap_obj != NULL)
xi_send_event(itf_data->trap_obj, ep, FALSE);
else
{
if (! itf_data->mouse_is_down)
{
retval = xi_send_event(itf, ep, TRUE);
switch(retval)
{
case 0:
new_cursor = CURSOR_ARROW;
break;
case 1:
new_cursor = CURSOR_IBEAM;
break;
case 2:
new_cursor =
(CURSOR)xi_get_pref(XI_PREF_SIZE_CURSOR_RID);
break;
case 3:
new_cursor =
(CURSOR)xi_get_pref(XI_PREF_HAND_CURSOR_RID);
break;
case 4:
new_cursor = CURSOR_CROSS;
break;
case 5:
new_cursor = CURSOR_ARROW;
break;
case 6:
new_cursor =
(CURSOR)xi_get_pref(XI_PREF_VSIZE_CURSOR_RID);
break;
}
if (itf_data->cursor != new_cursor)
{
#if XI_IS_NOT_CH
CTOS_IS_PM;
xvt_win_set_cursor(itf_data->xvt_win, new_cursor);
CTOS_END;
#endif
itf_data->cursor = new_cursor;
}
}
}
break;
case E_COMMAND:
{
WINDOW win;
xiev.v.cmd.tag = ep->v.cmd.tag;
xiev.v.cmd.shift = ep->v.cmd.shift;
xiev.v.cmd.control = ep->v.cmd.control;
xiev.type = XIE_COMMAND;
win = itf_data->xvt_win;
call_cb(itf, &xiev);
if (xi_is_window(win))
if (itf_data->focus_obj != NULL)
xi_send_event(itf_data->focus_obj, ep, FALSE);
}
if (xi_is_itf(itf))
do_edit_menu(itf, ep);
break;
case E_ACTIVATE:
update_menus();
break;
case E_KILL_WINDOW:
{
XI_ITF_DATA *itf_data;
int i;
destroy_controls(itf);
xvt_tx_process_event(win, ep);
xiev.type = XIE_CLEANUP;
xiev.v.xi_obj = itf;
call_cb(itf, &xiev);
xi_remove_window_from_list(win);
itf_data = itf->v.itf;
for (i = 0; i < itf_data->nbr_font_ids; ++i)
xvt_font_destroy(itf_data->font_ids[i]);
/* free the whole interface tree */
xi_tree_free((char *)itf);
break;
}
case E_CLOSE:
xiev.type = XIE_CLOSE;
xiev.v.xi_obj = itf;
call_cb(itf, &xiev);
if (!xiev.refused)
xi_close_window_internal(itf);
break;
case E_QUIT:
if (ep->v.query)
xvt_app_allow_quit();
else
xi_terminate();
break;
case E_HSCROLL:
case E_VSCROLL:
/* handle E_HSCROLL, etc if list is using window scroll bars */
break;
case E_CONTROL:
control_event(itf, win, ep);
update_menus();
break;
}
if (ep->type == E_UPDATE)
{
/* send XVT event */
MEMCLEAR(xiev);
xiev.type = XIE_UPDATE;
xiev.v.xvte = *ep;
xiev.refused = FALSE;
call_cb(itf, &xiev);
xvt_dwin_set_clip(xi_get_window(itf), NULL);
}
do_post_event(itf, ep);
}
long
xi_get_app_data(XI_OBJ *xi_obj)
{
return(xi_obj->app_data);
}
long
xi_get_app_data2(XI_OBJ *xi_obj)
{
return(xi_obj->app_data2);
}
unsigned long xi_get_attrib(XI_OBJ *xi_obj)
{
switch(xi_obj->type)
{
case XIT_COLUMN:
return (lm_get_attrib(xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx(xi_obj), 0, FALSE));
case XIT_LIST:
return (lm_get_attrib(xi_obj->v.list->lm, LM_LIST, 0, 0, FALSE));
case XIT_ROW:
return (lm_get_attrib(xi_obj->parent->v.list->lm, LM_ROW,
xi_obj->v.row, 0, FALSE));
case XIT_CELL:
return (lm_get_attrib( xi_obj->parent->v.list->lm, LM_CELL,
xi_obj->v.cell.row, xi_obj->v.cell.column,
xi_obj->v.cell.is_vert_scrolled ));
case XIT_BTN:
return(xi_obj->v.btn->attrib);
case XIT_CONTAINER:
/*
pretend that containers have attributes, and that they are always
visible and enabled
*/
return XI_ATR_ENABLED | XI_ATR_VISIBLE;
case XIT_FORM:
return(xi_obj->v.form->attrib);
case XIT_FIELD:
return(stx_get_attrib(xi_obj->v.field->stx));
case XIT_TEXT:
return(xi_obj->v.text->attrib);
case XIT_LINE:
return(xi_obj->v.line->attrib);
case XIT_RECT:
return(xi_obj->v.rect->attrib);
case XIT_GROUP:
default:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20018", 20018,
"Invalid object passed to xi_get_attrib");
}
return 0L;
}
XI_OBJ *
xi_get_focus(XI_OBJ *itf)
{
WINDOW win;
if (itf != NULL)
return(itf->v.itf->focus_obj);
else if ((win = xvt_scr_get_focus_vobj()) == NULL_WIN)
return(NULL);
else if (xi_is_window(win))
{
XI_OBJ *itf;
itf = xi_get_itf(win);
return(itf->v.itf->focus_obj);
}
else
return(NULL);
}
long *
xi_get_list_info(XI_OBJ *xi_obj, int *nbr_recs)
{
xvt_errmsg_sig_if(!(xi_obj->type == XIT_LIST), NULL_WIN,
SEV_FATAL, ERR_ASSERT_4, "20020", 20020,
"Non-list object passed to xi_get_list_info");
return lm_get_list_info(xi_obj->v.list->lm, nbr_recs);
}
XI_OBJ * *
xi_get_member_list(XI_OBJ *xi_obj, int *nbr_members)
{
int i;
XI_OBJ *obj;
XI_GROUP_DATA *groupdata;
if (xi_obj->type == XIT_GROUP)
{
groupdata = xi_obj->v.group;
if (groupdata->objlist != NULL)
xi_tree_free(groupdata->objlist);
groupdata->objlist =
(XI_OBJ * *)xi_tree_malloc(sizeof(XI_OBJ *) * groupdata->nbr_cids, xi_obj);
*nbr_members = 0;
for (i = 0; i < groupdata->nbr_cids; i++)
{
obj = xi_get_obj(xi_obj->itf, groupdata->cidlist[i]);
if (obj != NULL)
{
groupdata->objlist[*nbr_members] = obj;
(*nbr_members)++;
}
}
return(groupdata->objlist);
}
else
{
*nbr_members = xi_obj->nbr_children;
return(xi_obj->children);
}
}
/*
xi_get_obj: retrieve an XI_OBJ from the interface tree given its cid.
Although externally documented to work only on XIT_ITF,
this will start searching at any point in the interface tree.
xi_get_obj will ignore NULL objects so it can be used in the middle
of creating an interface tree.
*/
XI_OBJ *
xi_get_obj(XI_OBJ *obj, int cid)
{
XI_OBJ * *objlist;
XI_OBJ *temp;
int n;
if (obj->cid == cid)
return(obj);
switch (obj->type)
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
return(NULL);
default:
break;
}
/* search in child list */
objlist = xi_get_member_list(obj, &n);
for (; n > 0; n--, objlist++)
{
/* call recursively for generality in future versions */
if ((temp = xi_get_obj(*objlist, cid)) != NULL)
return(temp);
}
xvt_errmsg_sig_if(!(!(BOOLEAN)xi_get_pref(XI_PREF_ASSERT_ON_NULL_CID)),
NULL_WIN, SEV_FATAL, ERR_ASSERT_4,"30207", 30207,
"xi_get_obj: Invalid cid");
return(NULL);
}
RCT *
xi_get_rect(XI_OBJ *xi_obj, RCT *rctp)
{
return xi_get_rect_internal(xi_obj, rctp, NULL, NULL);
}
RCT *
xi_get_rect_internal(XI_OBJ *xi_obj, RCT *rctp, RCT *old_win_rct, RCT *new_win_rct)
{
XI_OBJ * *objp;
RCT rct;
int i, n;
switch(xi_obj->type)
{
case XIT_CONTAINER:
*rctp = xi_obj->v.container->rct;
break;
case XIT_BTN:
*rctp = xi_obj->v.btn->rct;
break;
case XIT_COLUMN:
lm_get_rect(xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx(xi_obj), rctp);
break;
case XIT_ROW:
lm_get_rect(xi_obj->parent->v.list->lm, LM_ROW,
xi_obj->v.row, rctp);
break;
case XIT_LIST:
lm_get_rect(xi_obj->v.list->lm, LM_LIST, 0, rctp);
if (xi_obj->v.list->scroll_bar)
{
xi_get_sb_rect(xi_obj, &rct);
rctp->right = rct.right;
}
if (xi_obj->v.list->width)
{
xi_get_hsb_rect(xi_obj, &rct);
rctp->bottom = rct.bottom;
}
if (old_win_rct)
{
rctp->bottom = (int)((long)rctp->bottom * new_win_rct->bottom / old_win_rct->bottom);
rctp->right = (int)((long)rctp->right * new_win_rct->right / old_win_rct->right);
}
break;
case XIT_ITF:
case XIT_FORM:
{
BOOLEAN first_rect = TRUE;
objp = xi_obj->children;
n = xi_obj->nbr_children;
for (i = 0; i < n; objp++, i++)
{
if (xi_get_rect_internal(*objp, &rct, old_win_rct, new_win_rct) != NULL)
{
if (first_rect)
{
first_rect = FALSE;
*rctp = rct;
}
else
xi_get_enclosing_rect(rctp, &rct, rctp);
}
}
break;
}
case XIT_FIELD:
{
XI_FIELD_DATA *fd;
fd = xi_obj->v.field;
stx_get_rect(fd->stx, rctp);
if (fd->button)
{
if (fd->button_on_left)
rctp->left = fd->btn_rct.left;
else
rctp->right = fd->btn_rct.right;
}
break;
}
case XIT_TEXT:
*rctp = xi_obj->v.text->rct;
break;
case XIT_RECT:
*rctp = xi_obj->v.rect->rct;
break;
case XIT_LINE:
{
XI_LINE_DATA *line;
line = xi_obj->v.line;
rctp->top = min(line->pnt1.v, line->pnt2.v);
rctp->bottom = max(line->pnt1.v, line->pnt2.v);
rctp->left = min(line->pnt1.h, line->pnt2.h);
rctp->right = max(line->pnt1.h, line->pnt2.h);
break;
}
case XIT_GROUP:
/* bounding rect is undefined */
return(NULL);
case XIT_CELL:
{
XI_OBJ row;
XI_OBJ *col;
XI_OBJ * *members;
int nbr_members;
int row_nbr, col_nbr;
RCT row_rct, col_rct;
if (xi_obj->v.cell.is_vert_scrolled)
memset( (char *)rctp, 0, sizeof(*rctp) );
else
{
row_nbr = xi_obj->v.cell.row;
col_nbr = xi_obj->v.cell.column;
XI_MAKE_ROW(&row, xi_obj->parent, row_nbr);
xi_get_rect_internal(&row, &row_rct, old_win_rct, new_win_rct);
members = xi_get_member_list(xi_obj->parent, &nbr_members);
col = members[col_nbr];
xi_get_rect_internal(col, &col_rct, old_win_rct, new_win_rct);
xi_rect_intersect(rctp, &row_rct, &col_rct);
}
break;
}
default:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20021", 20021,
"xi_get_rect: Invalid XI_OBJ_TYPE in tree");
}
return(rctp);
}
void xi_get_sel(XI_OBJ *xi_obj, int *selstart, int *selstop)
{
XI_OBJ *focus_obj;
BOOLEAN is_focus;
focus_obj = xi_get_focus(xi_obj->itf);
/* check if the passed object is the focus object */
if ( focus_obj == NULL )
is_focus = FALSE; /* no focus */
else if ( focus_obj == xi_obj )
is_focus = TRUE; /* object is the focus object */
else if ( focus_obj->type != XIT_CELL || xi_obj->type != XIT_CELL )
is_focus = FALSE; /* objects are not both cells */
else /* both objects are temporary cell objects */
is_focus = ( xi_obj->v.cell.row == focus_obj->v.cell.row
&& xi_obj->v.cell.column == focus_obj->v.cell.column
&& !focus_obj->v.cell.is_vert_scrolled );
/* it's the focus if the row & column are */
/* the same */
if ( !is_focus )
{
/* selection is only valid for focus object */
*selstart = *selstop = 0;
return;
}
switch(xi_obj->type)
{
case XIT_CELL:
lm_get_sel(xi_obj->parent->v.list->lm, selstart, selstop);
break;
case XIT_FIELD:
stx_get_sel(xi_obj->v.field->stx, selstart, selstop);
break;
case XIT_COLUMN:
case XIT_ITF:
case XIT_LIST:
case XIT_ROW:
case XIT_BTN:
case XIT_FORM:
case XIT_GROUP:
case XIT_TEXT:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20022", 20022,
"Invalid object passed to xi_get_sel");
break;
}
}
TXEDIT
xi_get_txedit(XI_OBJ *xi_obj)
{
return stx_get_txedit(xi_obj->v.field->stx);
}
char* xi_get_text(XI_OBJ *xi_obj, char *s, int len)
{
static char buf[100];
char *b;
b = NULL;
switch(xi_obj->type)
{
case XIT_CELL:
b = lm_get_text(xi_obj->parent->v.list->lm, s, len,
xi_obj->v.cell.row, xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled);
break;
case XIT_COLUMN:
b = lm_get_text( xi_obj->parent->v.list->lm, s, len,
LM_HEADING_TEXT, xi_obj_to_idx(xi_obj), FALSE );
break;
case XIT_ITF:
xvt_vobj_get_title(xi_obj->v.itf->xvt_win, buf, sizeof(buf));
b = buf;
break;
case XIT_ROW:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20023", 20023,
"xi_get_text not implemented for XIT_ROW");
case XIT_BTN:
b = xi_obj->v.btn->text;
break;
case XIT_FIELD:
b = stx_get_text(xi_obj->v.field->stx, s, len);
break;
case XIT_TEXT:
{
XI_TEXT_DATA *text_data;
text_data = xi_obj->v.text;
b = text_data->text;
}
break;
case XIT_LIST:
case XIT_GROUP:
case XIT_FORM:
if (s)
*s = '\0';
break;
}
if (s && b)
tgstrncpy(s, b, len);
return b;
}
WINDOW
xi_get_window(XI_OBJ *xi_obj)
{
return(xi_obj->itf->v.itf->xvt_win);
}
/*-------------------------------------------------------------------------
function: xi_scroll_rec
xi_obj: list object to scroll. Must be a list object.
rec: first record to go to
color: color of row
attrib: attribute of row
-------------------------------------------------------------------------*/
int
xi_scroll_rec(XI_OBJ *xi_obj, long rec, COLOR color, unsigned long attrib, int row_height)
{
LM_SCROLL_ARG arg;
xvt_errmsg_sig_if(!(xi_obj->type == XIT_LIST), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20024",
20024, "Invalidate object passed to xi_scroll_rec");
xi_obj->v.list->done_initial_xi_scroll = TRUE;
MEMCLEAR(arg);
arg.lm = xi_obj->v.list->lm;
/*
arg.nbr_lines = 0;
arg.percent = 0;
arg.same_cell = 0;
*/
arg.rec = rec;
arg.have_rec = TRUE;
arg.color = color;
arg.attrib = attrib;
arg.row_height = row_height;
arg.rec_at_top = TRUE;
return lm_scroll(&arg);
}
/*
typedef struct _xi_scroll_record_arg
{
XI_OBJ *xi_obj;
long record;
COLOR row_color;
unsigned long attrib;
int row_height;
BOOLEAN rec_at_top;
} XI_SCROLL_RECORD_ARG;
*/
int
xi_scroll_record(XI_SCROLL_RECORD_ARG *arg)
{
LM_SCROLL_ARG lm_scroll_arg;
XI_OBJ *xi_obj = arg->xi_obj;
xi_obj->v.list->done_initial_xi_scroll = TRUE;
MEMCLEAR(lm_scroll_arg);
lm_scroll_arg.lm = xi_obj->v.list->lm;
/*
lm_scroll_arg.nbr_lines = 0;
lm_scroll_arg.percent = 0;
lm_scroll_arg.same_cell = 0;
*/
lm_scroll_arg.rec = arg->record;
lm_scroll_arg.have_rec = TRUE;
lm_scroll_arg.color = arg->row_color;
lm_scroll_arg.attrib = arg->attrib;
lm_scroll_arg.row_height = arg->row_height;
lm_scroll_arg.rec_at_top = arg->rec_at_top;
return lm_scroll(&lm_scroll_arg);
}
/*-------------------------------------------------------------------------
function: xi_scroll_internal
xi_obj: list object to scroll. Must be a list object.
nbr_lines: nbr of lines to scroll, may be positive or negative, may be set
to XI_SCROLL_FIRST, XI_SCROLL_LAST, XI_SCROLL_PGUP, or XI_SCROLL_PGDN
percent: passed with XI_SCROLL_FIRST event
same_cell: sometimes the focus goes back onto the same cell. In other cases,
for instance, XI_SCROLL_FIRST, XI_SCROLL_LAST, XI_SCROLL_PGUP, and
XI_SCROLL_PGDN, we don't want to put the focus back on the same cell,
but instead, want to put the focus on the first or last fully visible
row.
invalidate: indicates whether to invalidate the list. This is only set to FALSE when xi_scroll_internal is
called when the interface is created.
-------------------------------------------------------------------------*/
int
xi_scroll_internal(XI_OBJ *xi_obj, int nbr_lines, int percent,
BOOLEAN same_cell )
{
LM_SCROLL_ARG arg;
xvt_errmsg_sig_if(!(xi_obj->type == XIT_LIST), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20037",
20037, "Invalidate object passed to xi_scroll_internal");
xi_obj->v.list->done_initial_xi_scroll = TRUE;
MEMCLEAR(arg);
arg.lm = xi_obj->v.list->lm;
arg.nbr_lines = nbr_lines;
arg.percent = percent;
arg.same_cell = same_cell;
arg.rec_at_top = TRUE;
/*
arg.rec = 0;
arg.have_rec = FALSE;
arg.color = 0L;
arg.attrib = 0L;
arg.row_height = 0;
*/
return lm_scroll(&arg);
}
BOOLEAN
xi_delete_row(XI_OBJ *xi_obj)
{
int row;
XI_OBJ *list_obj;
BOOLEAN rv;
xvt_errmsg_sig_if(!(xi_obj->type == XIT_ROW), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20025",
20025, "Invalidate object passed to xi_delete_row");
list_obj = xi_obj->parent;
row = xi_obj->v.row;
rv = lm_delete_row(list_obj->v.list->lm, row);
return rv;
}
BOOLEAN
xi_insert_row(XI_OBJ *list, int row)
{
BOOLEAN rv;
xvt_errmsg_sig_if(!(list->type == XIT_LIST), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20026",
20026, "Invalidate object passed to xi_insert_row");
rv = lm_insert_row(list->v.list->lm, row);
return rv;
}
int
xi_scroll(XI_OBJ *xi_obj, int nbr_lines)
{
return(xi_scroll_internal(xi_obj, nbr_lines, 0, (BOOLEAN)(nbr_lines < 1000)));
}
int
xi_scroll_percent(XI_OBJ *xi_obj, int percent)
{
return(xi_scroll_internal(xi_obj, XI_SCROLL_FIRST, percent, FALSE ));
}
void
xi_set_app_data(XI_OBJ *xi_obj, long app_data)
{
xi_obj->app_data = app_data;
}
void
xi_set_app_data2(XI_OBJ *xi_obj, long app_data)
{
xi_obj->app_data2 = app_data;
}
void
xi_set_fore_color(XI_OBJ *xi_obj, COLOR color)
{
RCT rct;
switch (xi_obj->type)
{
case XIT_ROW:
lm_set_color(xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row,
0, FALSE, color, FALSE);
break;
case XIT_CELL:
{
LM_DATA far *lmp = LMP(xi_obj->parent->v.list->lm);
int idx = xi_obj->v.cell.row;
int idx2 = xi_obj->v.cell.column;
BOOLEAN do_redraw = (lmp->cell_data[idx][idx2].color != color);
lm_set_color( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled, color,
FALSE);
if (do_redraw)
{
xi_get_rect(xi_obj, &rct);
xi_invalidate_rect(xi_get_window(xi_obj->itf), &rct);
}
break;
}
}
}
void
xi_set_attrib(XI_OBJ *xi_obj, unsigned long attrib)
{
int n;
XI_OBJ * *objlist;
unsigned long attrib_diff;
WINDOW win = xi_obj->itf->v.itf->xvt_win;
attrib_diff = xi_get_attrib(xi_obj) ^ attrib;
switch(xi_obj->type)
{
case XIT_BTN:
if (! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS))
{
XI_BTN_DATA *bd;
RCT r;
bd = xi_obj->v.btn;
r = bd->rct;
if (bd->type == XIBT_TABBTN)
r.bottom += 2;
xi_invalidate_rect(win, &r);
}
else
{
if (attrib_diff & XI_ATR_VISIBLE)
{
WINDOW btn_win;
btn_win = xi_obj->v.btn->btnctl;
xvt_vobj_set_visible(btn_win, (BOOLEAN)((attrib & XI_ATR_VISIBLE)
!= 0));
xi_invalidate_rect(win, &xi_obj->v.btn->rct);
}
if (attrib_diff & XI_ATR_ENABLED)
xvt_vobj_set_enabled(xi_obj->v.btn->btnctl,
(BOOLEAN)((attrib & XI_ATR_ENABLED) != 0));
}
xi_obj->v.btn->attrib = attrib;
break;
case XIT_FORM:
/* loop over sub-objects */
objlist = xi_get_member_list(xi_obj, &n);
for (; n > 0; n--, objlist++)
xi_set_attrib(*objlist, attrib);
break;
case XIT_FIELD:
{
RCT rct;
XI_FIELD_DATA *fd;
stx_set_attrib(xi_obj->v.field->stx, attrib);
fd = xi_obj->v.field;
rct = fd->rct;
if (fd->button)
if (! fd->button_on_left)
rct.right = fd->btn_rct.right;
xi_invalidate_rect(win, &rct);
break;
}
case XIT_GROUP:
/* it is not clear how to get the proper behaviour here */
break;
case XIT_LINE:
{
RCT rct;
XI_LINE_DATA *ld;
ld = xi_obj->v.line;
rct.top = min(ld->pnt1.v, ld->pnt2.v);
rct.bottom = max(ld->pnt1.v, ld->pnt2.v);
rct.left = min(ld->pnt1.h, ld->pnt2.h);
rct.right = max(ld->pnt1.h, ld->pnt2.h);
--rct.top;
rct.bottom += 3;
--rct.left;
rct.right += 3;
xi_obj->v.line->attrib = attrib;
xi_invalidate_rect(win, &rct);
break;
}
case XIT_RECT:
xi_obj->v.rect->attrib = attrib;
xi_invalidate_rect(win, &xi_obj->v.rect->rct);
break;
case XIT_TEXT:
xi_obj->v.text->attrib = attrib;
xi_invalidate_rect(win, &xi_obj->v.text->rct);
break;
case XIT_ITF:
/* it is not clear how to get the proper behaviour here */
break;
case XIT_COLUMN:
lm_set_attrib( xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx(xi_obj), 0, FALSE, attrib, FALSE);
break;
case XIT_LIST:
{
XI_LIST_DATA *ld;
ld = xi_obj->v.list;
if (attrib & XI_ATR_VISIBLE && ! ld->done_initial_xi_scroll)
{
ld->done_initial_xi_scroll = TRUE;
xi_scroll_internal(xi_obj, XI_SCROLL_FIRST, ld->start_percent, FALSE );
}
lm_set_attrib(ld->lm, LM_LIST, 0, 0, FALSE, attrib, FALSE);
if (ld->sb_win)
{
xvt_vobj_set_visible(ld->sb_win, (BOOLEAN)((attrib & XI_ATR_VISIBLE) != 0));
xvt_vobj_set_enabled(ld->sb_win, (BOOLEAN)((attrib & XI_ATR_ENABLED) != 0));
}
if (ld->hsb_win)
{
xvt_vobj_set_visible(ld->hsb_win, (BOOLEAN)((attrib & XI_ATR_VISIBLE) != 0));
xvt_vobj_set_enabled(ld->hsb_win, (BOOLEAN)((attrib & XI_ATR_ENABLED) != 0));
}
break;
}
case XIT_ROW:
lm_set_attrib( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row, 0, FALSE,
attrib, FALSE);
break;
case XIT_CELL:
lm_set_attrib( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
attrib, FALSE);
break;
default:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20027", 20027,
"Invalid object passed to xi_set_attrib");
break;
}
}
void
xi_set_bufsize(XI_OBJ *xi_obj, int size)
{
XI_OBJ * *objp;
int i;
switch(xi_obj->type)
{
case XIT_FIELD:
stx_set_bufsize(xi_obj->v.field->stx, (short)size);
break;
case XIT_COLUMN:
lm_set_buf_size(xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx(xi_obj), size);
break;
case XIT_LIST:
case XIT_FORM:
objp = xi_obj->children;
for (i = xi_obj->nbr_children; i > 0; i--, objp++)
xi_set_bufsize(*objp, size);
break;
}
}
void xi_set_sel(XI_OBJ *xi_obj, int selstart, int selstop)
{
switch(xi_obj->type)
{
case XIT_CELL:
xi_set_focus(xi_obj);
lm_set_sel( xi_obj->parent->v.list->lm, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
selstart, selstop);
break;
case XIT_FIELD:
xi_set_focus(xi_obj);
stx_set_sel(xi_obj->v.field->stx, selstart, selstop);
break;
case XIT_BTN:
case XIT_FORM:
case XIT_GROUP:
case XIT_TEXT:
case XIT_COLUMN:
case XIT_ITF:
case XIT_LIST:
case XIT_ROW:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20028", 20028,
"Invalid object passed to xi_set_sel");
break;
}
}
void
xi_set_text(XI_OBJ *xi_obj, char *s)
{
char *buf;
size_t buf_size = 256;
BOOLEAN ddd;
if ( xi_obj == xi_obj->itf->v.itf->focus_obj )
xi_obj->itf->v.itf->chg_flag = FALSE;
buf = xvt_mem_alloc(buf_size);
xi_get_text(xi_obj, buf, buf_size);
if (! strcmp(s, buf))
{
xvt_mem_free(buf);
return;
}
xvt_mem_free(buf);
ddd = ! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS);
switch(xi_obj->type)
{
case XIT_BTN:
{
XI_BTN_DATA *btn;
btn = xi_obj->v.btn;
btn->text = (char *)xi_tree_realloc(btn->text, strlen(s) + 1);
strcpy(btn->text, s);
if (ddd)
{
if ((xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE) != 0)
xi_invalidate_rect( xi_obj->itf->v.itf->xvt_win, &btn->rct);
}
else
xvt_vobj_set_title(btn->btnctl, s);
break;
}
case XIT_CELL:
lm_set_text( xi_obj->parent->v.list->lm, s, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled );
break;
case XIT_COLUMN:
lm_set_text( xi_obj->parent->v.list->lm, s, LM_HEADING_TEXT,
xi_obj_to_idx(xi_obj), FALSE );
break;
case XIT_FIELD:
{
/*
RCT rct;
*/
stx_set_text(xi_obj->v.field->stx, s);
/*
TODO change approach, simply draw text
xi_get_rect(xi_obj, &rct);
xi_invalidate_rect(xi_obj->itf->v.itf->xvt_win, &rct);
*/
break;
}
case XIT_ITF:
xvt_vobj_set_title(xi_obj->v.itf->xvt_win, s);
break;
case XIT_ROW:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20029", 20029,
"xi_set_text not implemented for XIT_ROW");
case XIT_TEXT:
{
XI_TEXT_DATA *text_data;
RCT rct;
text_data = xi_obj->v.text;
text_data->text = (char *)xi_tree_realloc(text_data->text, strlen(s) + 1);
strcpy(text_data->text, s);
if ((xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE) != 0)
{
xi_get_rect(xi_obj, &rct);
xi_invalidate_rect(xi_obj->itf->v.itf->xvt_win, &rct);
}
break;
}
case XIT_GROUP:
case XIT_FORM:
case XIT_LIST:
break;
}
}
void
xi_draw_button(XI_OBJ *xi_obj, RCT *rct, char *text,
int down_icon_rid, int up_icon_rid, int disabled_icon_rid,
BOOLEAN enabled, BOOLEAN visible, BOOLEAN focus, BOOLEAN down, BOOLEAN dflt,
BOOLEAN checked, BOOLEAN box_only)
{
XI_BTN_DATA *bd;
COLOR fore_color;
CPEN fore_cp;
WINDOW win;
XI_OBJ *itf;
XI_ITF_DATA *id;
COLOR color_light = 0L;
COLOR color_ctrl = 0L;
COLOR color_dark = 0L;
if (! visible)
return;
itf = xi_obj->itf;
id = itf->v.itf;
if (id->half_baked)
return;
win = xi_get_window(itf);
xvt_dwin_set_clip( win, NULL );
bd = xi_obj->v.btn;
if (bd->type == XIBT_BUTTON)
{
color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
}
fore_color = COLOR_BLACK;
fore_cp = black_cpen;
if (bd->fore_color)
{
fore_cp.color = bd->fore_color;
fore_color = bd->fore_color;
}
switch (bd->type)
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
{
int grid_width;
RCT r;
r = *rct;
if (xi_obj->v.btn->packed == TRUE)
{
grid_width = (int)xi_get_pref(XI_PREF_CONTAINER_GRID_WIDTH);
xi_inflate_rect(&r, -grid_width);
}
else
{
XI_BTN_TYPE bt;
bt = xi_obj->v.btn->type;
if (bt == XIBT_BUTTON || bt == XIBT_BUTTON_CHECKBOX ||
bt == XIBT_BUTTON_RADIOBTN)
xi_inflate_rect(&r, -3);
}
xi_set_draw_mode(win, M_COPY);
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
{
CBRUSH hollow_cbrush;
RCT rct;
DRAW_CTOOLS t;
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
xvt_app_get_default_ctools(&t);
xvt_dwin_set_draw_ctools(win, &t);
hollow_cbrush.color = COLOR_WHITE;
hollow_cbrush.pat = PAT_HOLLOW;
xvt_dwin_set_cbrush(win, &hollow_cbrush);
rct.top = 0;
rct.left = 0;
rct.bottom = 0;
rct.right = 0;
xvt_dwin_draw_rect(win, &rct);
}
#endif
xi_draw_3d_rect(win, &r, (BOOLEAN)(down || bd->checked), 2, color_light, color_ctrl, color_dark);
if (up_icon_rid)
{
int x, y;
RCT r2;
x = r.left + 2 + bd->icon_x;
y = r.top + 2 + bd->icon_y;
r2 = r;
xi_inflate_rect(&r2, -2);
xi_set_clip(win, &r2);
if (down)
xi_draw_icon(win, x, y + 1, down_icon_rid, COLOR_BLACK, color_ctrl);
else
{
if (enabled || ! disabled_icon_rid)
xi_draw_icon(win, x, y, up_icon_rid, COLOR_BLACK, color_ctrl);
else
xi_draw_icon(win, x, y, disabled_icon_rid, COLOR_BLACK, color_ctrl);
}
xi_set_clip(win, NULL);
}
else
{
unsigned long attrib;
RCT text_rect;
// COLOR color;
FONT_OBJ* fontp;
attrib = XI_ATR_VCENTER | XI_ATR_HCENTER | XI_ATR_VISIBLE;
if (enabled)
xi_set_xvt_fore_color(win, fore_color);
else
xi_set_xvt_fore_color( win,
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
text_rect = r;
if (down)
text_rect.top += 2;
fontp = xi_obj->itf->v.itf->font;
if (fontp)
xi_set_xvt_font(win, fontp, FALSE);
else
xi_set_xvt_font(win, &xi_sysfont, FALSE);
xi_set_xvt_back_color(win, color_ctrl);
xi_draw_clipped_text(win, text, &text_rect, &text_rect, attrib, FALSE, 0, -1);
}
if ((focus) || (xi_obj->v.btn->packed))
{
int width;
RCT rct2;
width = (xi_obj->v.btn->packed) ? grid_width : 2;
rct2 = r;
rct2.top -= width;
rct2.left -= width;
rct2.bottom += width;
rct2.right += width;
xi_set_cpen(win, &black_cpen);
xi_set_cbrush(win, &hollow_cbrush);
xi_draw_thick_rect(win, &rct2, width);
}
else
{
RCT rct2;
CPEN cpen;
rct2 = r;
rct2.top--;
rct2.left--;
rct2.bottom++;
rct2.right++;
xi_set_cpen(win, &black_cpen);
xi_set_cbrush(win, &hollow_cbrush);
xi_draw_rect(win, &rct2);
rct2.top--;
rct2.left--;
rct2.bottom++;
rct2.right++;
if (id->back_color)
{
cpen = black_cpen;
cpen.color = id->back_color;
xi_set_cpen(win, &cpen);
xi_draw_rect(win, &rct2);
}
if (dflt)
{
rct2.top--;
rct2.left--;
rct2.bottom++;
rct2.right++;
xi_set_cpen(win, &black_cpen);
xi_draw_rect(win, &rct2);
}
}
break;
}
case XIBT_RADIOBTN:
{
RCT rbrct, rct2;
unsigned long attrib;
RCT text_rect;
COLOR color;
rbrct = *rct;
rbrct.bottom -= 4;
rct2 = rbrct;
rct2.right = rct2.left + (rct2.bottom - rct2.top);
xi_set_draw_mode(win, M_COPY);
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
{
CBRUSH hollow_cbrush;
RCT rct;
DRAW_CTOOLS t;
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
xvt_app_get_default_ctools(&t);
xvt_dwin_set_draw_ctools(win, &t);
hollow_cbrush.color = COLOR_WHITE;
hollow_cbrush.pat = PAT_HOLLOW;
xvt_dwin_set_cbrush(win, &hollow_cbrush);
rct.top = 0;
rct.left = 0;
rct.bottom = 0;
rct.right = 0;
xvt_dwin_draw_rect(win, &rct);
}
#endif
xi_draw_3d_diamond(win, &rct2, checked, down, down ? 2 : 1,
down ? bd->fore_color : 0L);
if (checked)
{
RCT rct;
rct = rct2;
rct.top += 4;
rct.left += 4;
rct.bottom -= 4;
rct.right -= 4;
xi_draw_3d_diamond(win, &rct, FALSE, TRUE, rct.right - rct.left,
enabled ? bd->fore_color : xi_get_pref(XI_PREF_COLOR_DISABLED));
}
if (! box_only)
{
CPEN cpen;
FONT_OBJ *fontp;
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
if (enabled)
xi_set_xvt_fore_color(win, fore_color);
else
xi_set_xvt_fore_color( win,
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
text_rect = *rct;
text_rect.left = rct2.right + (rct2.right - rct2.left) / 2;
fontp = xi_obj->itf->v.itf->font;
if (fontp)
xi_set_xvt_font(win, fontp, FALSE);
else
xi_set_xvt_font(win, &xi_sysfont, FALSE);
color = (COLOR)xi_get_pref(XI_PREF_COLOR_CTRL);
xi_set_xvt_back_color(win, color);
xi_draw_clipped_text(win, text, &text_rect, &text_rect, attrib, FALSE, 0, -1);
if (focus)
{
cpen = black_cpen;
cpen.pat = PAT_RUBBER;
xi_set_cpen(win, &cpen);
xi_set_cbrush(win, &hollow_cbrush);
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
xi_draw_rect(win, &text_rect);
}
else
{
if (id->back_color)
{
cpen = black_cpen;
cpen.color = id->back_color;
xi_set_cpen(win, &cpen);
xi_set_cbrush(win, &hollow_cbrush);
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
xi_draw_rect(win, &text_rect);
}
}
}
break;
}
case XIBT_TABBTN:
{
RCT tbrct;
unsigned long attrib;
CPEN line_cpen;
PNT p;
COLOR color;
CPEN cpen;
int leading, ascent, descent, height, width, hdiff, vdiff;
RCT r;
char s[100];
FONT_OBJ *fontp;
tbrct = *rct;
height = tbrct.bottom - tbrct.top;
xi_set_draw_mode(win, M_COPY);
line_cpen = black_cpen;
/* Draw background color, one line at a time */
line_cpen.color = xi_get_pref( XI_PREF_COLOR_CTRL );
xi_set_cpen(win, &line_cpen);
for ( hdiff = 1, vdiff = height / 2; hdiff < height; hdiff++ )
{
p.h = tbrct.left + vdiff;
p.v = tbrct.top + hdiff;
xi_move_to( win, p );
p.h = tbrct.right - vdiff;
xi_draw_line( win, p );
if ( hdiff % 2 )
vdiff--;
}
/* Draw bottom line, adjust color if checked. */
if (checked)
line_cpen.color = xi_get_pref(XI_PREF_COLOR_CTRL);
else
line_cpen.color = xi_get_pref( XI_PREF_COLOR_LIGHT );
xi_set_cpen(win, &line_cpen);
p.h = tbrct.left + 1;
p.v = tbrct.bottom;
xi_move_to(win, p);
p.h = tbrct.right - 1;
xi_draw_line(win, p);
line_cpen.color = xi_get_pref(XI_PREF_COLOR_LIGHT);
xi_set_cpen(win, &line_cpen);
/* Draw left, slanted line */
p.h = tbrct.left;
p.v = tbrct.bottom;
xi_move_to(win, p);
p.h = tbrct.left + height / 2;
p.v = tbrct.top;
xi_draw_line(win, p);
/* Draw top line */
xi_move_to(win, p);
p.h = tbrct.right - height / 2;
p.v = tbrct.top;
xi_draw_line(win, p);
/* Draw right, slanted line */
line_cpen.color = xi_get_pref(XI_PREF_COLOR_DARK);
xi_set_cpen(win, &line_cpen);
p.v = tbrct.top + 1;
xi_move_to(win, p);
p.h = tbrct.right;
p.v = tbrct.bottom;
xi_draw_line(win, p);
/* Draw text */
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE | XI_ATR_HCENTER;
if (enabled)
xi_set_xvt_fore_color(win, fore_color);
else
xi_set_xvt_fore_color( win,
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
fontp = xi_obj->itf->v.itf->font;
if ( !fontp )
fontp = &xi_sysfont;
if ( checked )
{
XVT_FNTID font_id = xvt_font_create();
xvt_font_copy( font_id, *fontp, (unsigned long)XVT_FA_ALL );
xvt_font_set_style( font_id, XVT_FS_BOLD );
xvt_dwin_set_font( win, font_id );
xvt_font_destroy( font_id );
} else
xi_set_xvt_font(win, fontp, FALSE);
{
DRAW_CTOOLS ct;
xi_get_draw_ctools(win, &ct);
ct.opaque_text = FALSE;
xi_set_draw_ctools(win, &ct);
}
xi_draw_clipped_text(win, text, &tbrct, &tbrct, attrib, FALSE, 0, -1);
/* Draw focus line, or erase focus line */
if (focus)
{
cpen = black_cpen;
cpen.pat = PAT_RUBBER;
}
else
{
cpen = black_cpen;
cpen.color = xi_get_pref( XI_PREF_COLOR_CTRL );
}
xi_get_font_metrics(win, &leading, &ascent, &descent);
height = leading + ascent + descent;
gstrncpy(s, text, sizeof(s));
s[sizeof(s) - 1] = '\0';
width = xi_xvt_get_text_width(win, s, -1);
vdiff = (tbrct.bottom - tbrct.top - height) / 2 - 1;
hdiff = (tbrct.right - tbrct.left - width) / 2 - 2;
r = tbrct;
r.top += vdiff;
#if XIWS != GRWS
r.top++;
#endif
r.bottom -= vdiff;
r.left += hdiff;
r.right -= hdiff;
xi_set_cpen(win, &cpen);
xi_set_cbrush(win, &hollow_cbrush);
xi_draw_rect(win, &r);
break;
}
case XIBT_CHECKBOX:
{
RCT cbrct, rct2;
unsigned long attrib;
RCT text_rect;
COLOR color;
cbrct = *rct;
cbrct.bottom -= 4;
rct2 = cbrct;
rct2.right = rct2.left + (rct2.bottom - rct2.top);
xi_set_draw_mode(win, M_COPY);
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
{
CBRUSH hollow_cbrush;
RCT rct;
DRAW_CTOOLS t;
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
xvt_app_get_default_ctools(&t);
xvt_dwin_set_draw_ctools(win, &t);
hollow_cbrush.color = COLOR_WHITE;
hollow_cbrush.pat = PAT_HOLLOW;
xvt_dwin_set_cbrush(win, &hollow_cbrush);
rct.top = 0;
rct.left = 0;
rct.bottom = 0;
rct.right = 0;
xvt_dwin_draw_rect(win, &rct);
}
#endif
if (down)
{
xi_set_cpen(win, &fore_cp);
xi_set_cbrush(win, &hollow_cbrush);
xi_draw_thick_rect(win, &rct2, 2);
}
else
xi_draw_3d_rect(win, &rct2, down, 1, 0L, 0L, 0L);
if (! enabled)
fore_cp.color = xi_get_pref(XI_PREF_COLOR_DISABLED);
if (checked)
{
PNT pnt1, pnt2;
xi_set_cpen(win, &fore_cp);
pnt1.h = rct2.left + 2;
pnt1.v = rct2.bottom - 7;
xi_move_to(win, pnt1);
pnt2.h = pnt1.h;
pnt2.v = pnt1.v + 5;
xi_draw_line(win, pnt2);
pnt1.h++;
pnt1.v--;
xi_move_to(win, pnt1);
pnt2.h++;
xi_draw_line(win, pnt2);
pnt1.h++;
pnt1.v = rct2.bottom - 5;
pnt2 = pnt1;
pnt2.v += 2;
while (pnt1.v >= (rct2.top + 3) && pnt1.h <= (rct2.right - 4))
{
xi_move_to(win, pnt1);
xi_draw_line(win, pnt2);
pnt1.h++;
pnt1.v--;
pnt2.h++;
pnt2.v--;
}
pnt1.v++;
xi_move_to(win, pnt1);
xi_draw_line(win, pnt2);
}
if (! box_only)
{
FONT_OBJ *fontp;
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
if (enabled)
xi_set_xvt_fore_color(win, fore_color);
else
xi_set_xvt_fore_color( win,
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
text_rect = *rct;
text_rect.left = rct2.right + (rct2.right - rct2.left) / 2;
fontp = xi_obj->itf->v.itf->font;
if (fontp)
xi_set_xvt_font(win, fontp, FALSE);
else
xi_set_xvt_font(win, &xi_sysfont, FALSE);
color = (COLOR)xi_get_pref(XI_PREF_COLOR_CTRL);
xi_set_xvt_back_color(win, color);
xi_draw_clipped_text(win, text, &text_rect, &text_rect, attrib, FALSE, 0, -1);
if (focus)
{
CPEN cpen;
cpen = black_cpen;
cpen.pat = PAT_RUBBER;
xi_set_cpen(win, &cpen);
xi_set_cbrush(win, &hollow_cbrush);
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
xi_draw_rect(win, &text_rect);
}
else
{
if (id->back_color)
{
CPEN cpen;
cpen = black_cpen;
cpen.color = id->back_color;
xi_set_cpen(win, &cpen);
xi_set_cbrush(win, &hollow_cbrush);
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
xi_draw_rect(win, &text_rect);
}
}
}
break;
}
}
}
/* -------------------------------------------------------------------------*/
/* xi_set_fixed_columns */
/* -------------------------------------------------------------------------*/
void xi_set_fixed_columns( XI_OBJ* list, int new_fixed_count )
{
xvt_errmsg_sig_if(!(list->type == XIT_LIST), NULL_WIN,
SEV_FATAL, ERR_ASSERT_4, "20031", 20031,
"Non-list object sent to xi_set_fixed_columns");
lm_set_fixed_columns( list->v.list->lm, new_fixed_count );
}
/* -------------------------------------------------------------------------*/
/* xi_get_fixed_columns */
/* -------------------------------------------------------------------------*/
int xi_get_fixed_columns( XI_OBJ* list )
{
xvt_errmsg_sig_if(!( list->type == XIT_LIST), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4,"20038", 20038,
"Non-list object sent to xi_get_fixed_columns");
return lm_get_fixed_columns( list->v.list->lm );
}
/* -------------------------------------------------------------------------*/
/* xi_get_handle */
/* -------------------------------------------------------------------------*/
long xi_get_handle( XI_OBJ* list, XI_OBJ* child )
{
LM_DATA* lm_data;
if (list->type != XIT_LIST)
return -1L;
lm_data = (LM_DATA*)list->v.list->lm;
switch (child->type)
{
case XIT_ROW:
{
int row = child->v.row;
if ( row >= 0 && row < lm_data->nbr_realized_rows)
return lm_data->recs[row];
break;
}
case XIT_CELL:
{
int row;
if (child->v.cell.is_vert_scrolled)
return lm_data->focus_rec;
row = child->v.cell.row;
if ( row >= 0 && row < lm_data->nbr_realized_rows)
return lm_data->recs[row];
break;
}
}
return -1L;
}
/* -------------------------------------------------------------------------*/
/* xi_field_calc_height_font_id */
/* -------------------------------------------------------------------------*/
int xi_field_calc_height_font_id( XVT_FNTID font )
{
if (font == 0)
font = xi_sysfont;
return xi_get_fu_height_font( &font );
}
/* -------------------------------------------------------------------------*/
/* xi_button_calc_height_font_id */
/* -------------------------------------------------------------------------*/
int xi_button_calc_height_font_id( XVT_FNTID font )
{
return xi_field_calc_height_font_id( font );
}
/* -------------------------------------------------------------------------*/
/* xi_field_calc_width_font_id */
/* -------------------------------------------------------------------------*/
int xi_field_calc_width_font_id( XVT_FNTID font, char* string )
{
WINDOW win;
XI_RCT rct = {-1000,-1000,-900,-900};
int result;
if (font == 0)
font = xi_sysfont;
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
xvt_dwin_set_font(win, font);
result = xvt_dwin_get_text_width( win, string, -1 ) + 4;
xvt_vobj_destroy(win);
return result;
}
/* -------------------------------------------------------------------------*/
/* xi_list_def_get_rows */
/* -------------------------------------------------------------------------*/
int xi_list_def_get_rows( XI_OBJ_DEF* list_def )
{
int pix_row_spacing, height, pix_row1_top, title_height;
if (list_def->v.list->one_row_list)
return 1;
lm_get_vertical_metrics( list_def, &pix_row1_top, &pix_row_spacing, &height,
&title_height );
return height / pix_row_spacing;
}
/* -------------------------------------------------------------------------*/
/* xi_list_def_get_height */
/* -------------------------------------------------------------------------*/
int xi_list_def_get_client_height( XI_OBJ_DEF* list_def, int rows )
{
int pix_row_spacing, height, pix_row1_top, title_height;
lm_get_vertical_metrics( list_def, &pix_row1_top, &pix_row_spacing, &height,
&title_height );
return title_height + rows * pix_row_spacing + (BORDER_WIDTH - RULE_WIDTH_H);
}
/* -------------------------------------------------------------------------*/
/* xi_list_def_get_height */
/* -------------------------------------------------------------------------*/
int xi_list_def_get_outer_height( XI_OBJ_DEF* list_def, int rows )
{
int result;
result = xi_list_def_get_client_height( list_def, rows );
return result + (int)xi_get_pref( XI_PREF_SB_HEIGHT );
}
/* -------------------------------------------------------------------------*/
/* button_get_horz_padding */
/* -------------------------------------------------------------------------*/
static int button_get_horz_padding( int type, int height, BOOLEAN packed )
{
switch (type)
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
if (packed)
return (int)xi_get_pref(XI_PREF_CONTAINER_GRID_WIDTH) * 2;
return 6;
case XIBT_RADIOBTN:
return height + height / 2 - 6;
case XIBT_TABBTN:
return height + 4;
case XIBT_CHECKBOX:
return height + height / 2 - 6;
}
return 0;
}
/* -------------------------------------------------------------------------*/
/* xi_button_calc_height */
/* -------------------------------------------------------------------------*/
int xi_button_calc_pixel_height( int height )
{
return height + 6;
}
/* -------------------------------------------------------------------------*/
/* xi_button_calc_height */
/* -------------------------------------------------------------------------*/
int xi_button_calc_pixel_width( int width )
{
return width + 6;
}
/* -------------------------------------------------------------------------*/
/* xi_button_def_get_width */
/* -------------------------------------------------------------------------*/
int xi_button_def_get_width( XI_OBJ_DEF* obj_def )
{
FONT_OBJ* font;
XI_RCT rct = {-1000,-1000,-900,-900};
WINDOW win;
int width;
XI_BTN_DEF* button;
if ( obj_def->type != XIT_BTN)
return 0;
font = xi_def_get_font( obj_def );
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
xvt_dwin_set_font(win, *font);
button = obj_def->v.btn;
width = xvt_dwin_get_text_width( win, button->text, -1 );
xvt_vobj_destroy( win );
width += button_get_horz_padding( button->type, xi_get_fu_height_font( font ),
FALSE );
return width;
}
/* -------------------------------------------------------------------------*/
/* xi_container_def_get_btn_width */
/* -------------------------------------------------------------------------*/
int xi_container_def_get_btn_width( XI_OBJ_DEF* obj_def )
{
int i;
FONT_OBJ* font;
XI_RCT rct = {-1000,-1000,-900,-900};
WINDOW win;
int max_width;
XI_CONTAINER_DEF* container;
BOOLEAN packed;
if ( obj_def->type != XIT_CONTAINER || obj_def->nbr_children <= 0)
return 0;
font = xi_def_get_font( obj_def );
max_width = 0;
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
xvt_dwin_set_font(win, *font);
for (i = 0; i < obj_def->nbr_children; ++i)
{
XI_BTN_DEF* button;
int width;
button = obj_def->children[i]->v.btn;
width = xvt_dwin_get_text_width( win, button->text, -1 );
max_width = max( width, max_width );
}
xvt_vobj_destroy( win );
container = obj_def->v.container;
packed = ((container->orientation == XI_GRID_HORIZONTAL
|| container->orientation == XI_GRID_VERTICAL)
&& container->packed);
max_width += button_get_horz_padding( obj_def->children[0]->v.btn->type,
xi_get_fu_height_font( font ),
packed );
return max_width;
}
/* -------------------------------------------------------------------------*/
/* xi_container_def_get_width */
/* -------------------------------------------------------------------------*/
int xi_container_def_get_width( XI_OBJ_DEF* obj_def )
{
XI_CONTAINER_DEF* container;
container = obj_def->v.container;
switch (container->orientation)
{
case XI_STACK_HORIZONTAL:
{
int horz_spacing;
if (container->packed)
horz_spacing = 0;
else if ((horz_spacing = (int)xi_get_pref(XI_PREF_HORZ_PIXEL_SPACING))
== 0)
{
FONT_OBJ* font;
font = xi_def_get_font( obj_def );
horz_spacing = (short)((xi_get_pref(XI_PREF_HORZ_SPACING)
* xi_get_fu_width_font(font)) / XI_FU_MULTIPLE);
}
return xi_container_def_get_btn_width( obj_def ) * obj_def->nbr_children +
(obj_def->nbr_children - 1) * horz_spacing;
}
case XI_STACK_VERTICAL:
return xi_container_def_get_btn_width( obj_def );
}
return 0;
}
/* -------------------------------------------------------------------------*/
/* xi_container_def_get_height */
/* -------------------------------------------------------------------------*/
int xi_container_def_get_height( XI_OBJ_DEF* obj_def )
{
XI_CONTAINER_DEF* container;
FONT_OBJ* font;
int height;
int vert_spacing;
int top_offset;
if (obj_def->nbr_children == 0)
return 0;
container = obj_def->v.container;
font = xi_def_get_font( obj_def );
height = xi_button_calc_height_font_id( *font );
if (container->orientation == XI_STACK_HORIZONTAL)
return height;
if (container->orientation != XI_STACK_VERTICAL)
return 0;
switch (obj_def->children[0]->v.btn->type)
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
case XIBT_TABBTN:
if (container->packed)
vert_spacing = 0;
else if ((vert_spacing = (int)xi_get_pref( XI_PREF_VERT_PIXEL_SPACING))
== 0)
vert_spacing = (int)((xi_get_pref(XI_PREF_VERT_SPACING)
* height ) / XI_FU_MULTIPLE );
top_offset = vert_spacing / 2;
break;
case XIBT_CHECKBOX:
case XIBT_RADIOBTN:
vert_spacing = 0;
top_offset = 0;
break;
}
return height * obj_def->nbr_children + vert_spacing
* (obj_def->nbr_children - 1) + top_offset;
}