campo-sirio/xi/xiutils.c
guy 50bf746c69 cosmesi
git-svn-id: svn://10.65.10.50/branches/R_10_00@23146 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-11-30 16:27:50 +00:00

4161 lines
110 KiB
C
Executable File

/*******************************************************************************
* Copyright 1991-1996 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
#define XI_R3_COMPAT
#include "xi.h"
#include "xiutils.h"
#include "xitext.h"
#include "xistx.h"
#include "xilm.h"
#include "xilmst.h"
#include "xiport.h"
#if XIWS == XIWS_WM
#define STX_VERT_FUDGE 0
//Gia' definito altrove! #define BORDER_WIDTH 8
#define EDIT_BORDER_WIDTH_Y 0
#define EDIT_BORDER_SPACE_Y 0
#define BORDER_WIDTH_X 8
#define BORDER_WIDTH_Y 0
#define BORDER_SPACE_X 0
#define BORDER_SPACE_Y 0
#else
#define STX_VERT_FUDGE 6
//Gia' definito altrove! #define BORDER_WIDTH 2
#define EDIT_BORDER_WIDTH_Y 1
#define EDIT_BORDER_SPACE_Y 1
#define BORDER_WIDTH_X 1
#define BORDER_WIDTH_Y 1
#define BORDER_SPACE_X 1
#define BORDER_SPACE_Y 1
#endif
XinFont *xi_sysfont = NULL;
static XI_OBJ *xi_drag_list_obj = NULL;
#define MAX_RADIO_BUTTONS 30
XinBrush ltgray_cbrush = {XinBrushSolid, XI_COLOR_LTGRAY};
XinBrush gray_cbrush = {XinBrushSolid, XI_COLOR_GRAY};
XinBrush hollow_cbrush = {XinBrushHollow, XI_COLOR_WHITE};
XinPen hollow_cpen = {0, XinPenHollow, XI_COLOR_WHITE};
XinPen black_cpen = {1, XinPenSolid, XI_COLOR_BLACK};
XinPen rubber_cpen = {1, XinPenDashed, XI_COLOR_BLACK};
XinBrush white_cbrush = {XinBrushSolid, XI_COLOR_WHITE};
static XinWindow cur_window;
static XI_OBJ *cur_itf;
static int cur_delta_x;
static int cur_delta_y;
static BOOLEAN font_set = FALSE;
static BOOLEAN update_pending = FALSE;
static int xi_sysvals[XI_NBR_SYSVALS];
static long xi_preferences[XI_NBR_PREFERENCES] =
{
1, /* XI_PREF_OVERLAP */
'\t', /* XI_PREF_FORM_TAB_CHAR */
XI_KEY_BTAB, /* XI_PREF_FORM_BACKTAB_CHAR */
1, /* XI_PREF_SCROLL_INC */
TRUE, /* XI_PREF_3D_LOOK */
FALSE, /* XI_PREF_USE_APP_DATA */
FALSE, /* XI_PREF_AUTOSEL_ON_MOUSE */
1, /* XI_PREF_CELL_BTN_ICON_X */
1, /* XI_PREF_CELL_BTN_ICON_Y */
FALSE, /* XI_PREF_R4_API */
'#', /* XI_PREF_PASSWORD_CHAR */
FALSE, /* XI_PREF_USE_TX_SUPPORT */
FALSE, /* XI_PREF_SINGLE_CLICK_COL_SELECT */
#if XIWS == XIWS_WM
0, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
8, /* XI_PREF_SB_WIDTH */
8, /* XI_PREF_SB_HEIGHT */
0, /* XI_PREF_SIZE_CURSOR_RID */
0, /* XI_PREF_HAND_CURSOR_RID */
0, /* XI_PREF_VSIZE_CURSOR_RID */
0, /* XI_PREF_COMBO_ICON */
XI_COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
XI_COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DARK */
FALSE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
K_F2, /* XI_PREF_BUTTON_KEY */
TRUE, /* XI_PREF_LIMIT_MIN_WIN_SIZE */
5, /* XI_PREF_DEFAULT_MAX_LINES_IN_CELL */
FALSE, /* XI_PREF_KEEP_FOCUS_FIXED */
TRUE, /* XI_PREF_NATIVE_CTRLS */
XI_KEY_F3, /* XI_PREF_ITF_TAB_CHAR */
XI_KEY_F4, /* XI_PREF_ITF_BACKTAB_CHAR */
16, /* XI_PREF_ITF_WS_RIGHT */
4, /* XI_PREF_ITF_WS_BOTTOM */
40, /* XI_PREF_VIR_SP_H */
20, /* XI_PREF_VIR_SP_V */
TRUE, /* XI_PREF_DBL_PRESSES_BUTTON */
1, /* XI_PREF_CONTAINER_GRID_WIDTH */
TRUE, /* XI_PREF_MULTILINE_QUICK_PASTE */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
24, /* XI_PREF_BUTTON_HEIGHT */
32, /* XI_PREF_BUTTON_PAD */
16, /* XI_PREF_HORZ_SPACING */
0, /* XI_PREF_VERT_SPACING */
0, /* XI_PREF_HORZ_PIXEL_SPACING */
0, /* XI_PREF_VERT_PIXEL_SPACING */
16, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
FALSE, /* XI_PREF_NO_BUTTON_SPACE */
#elif XIWS == XIWS_PM
2, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
16, /* XI_PREF_SB_WIDTH */
16, /* XI_PREF_SB_HEIGHT */
XI_CURSOR_RESIZE, /* XI_PREF_SIZE_CURSOR_RID */
XI_CURSOR_HAND, /* XI_PREF_HAND_CURSOR_RID */
XI_CURSOR_VRESIZE, /* XI_PREF_VSIZE_CURSOR_RID */
COMBO_ICON, /* XI_PREF_COMBO_ICON */
XI_COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
XI_COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DARK */
TRUE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
0, /* XI_PREF_BUTTON_KEY */
TRUE, /* XI_PREF_LIMIT_MIN_WIN_SIZE */
5, /* XI_PREF_DEFAULT_MAX_LINES_IN_CELL */
FALSE, /* XI_PREF_KEEP_FOCUS_FIXED */
TRUE, /* XI_PREF_NATIVE_CTRLS */
XI_KEY_F3, /* XI_PREF_ITF_TAB_CHAR */
XI_KEY_F4, /* XI_PREF_ITF_BACKTAB_CHAR */
16, /* XI_PREF_ITF_WS_RIGHT */
4, /* XI_PREF_ITF_WS_BOTTOM */
40, /* XI_PREF_VIR_SP_H */
20, /* XI_PREF_VIR_SP_V */
TRUE, /* XI_PREF_DBL_PRESSES_BUTTON */
1, /* XI_PREF_CONTAINER_GRID_WIDTH */
TRUE, /* XI_PREF_MULTILINE_QUICK_PASTE */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
12, /* XI_PREF_BUTTON_HEIGHT */
32, /* XI_PREF_BUTTON_PAD */
16, /* XI_PREF_HORZ_SPACING */
2, /* XI_PREF_VERT_SPACING */
0, /* XI_PREF_HORZ_PIXEL_SPACING */
0, /* XI_PREF_VERT_PIXEL_SPACING */
24, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
FALSE, /* XI_PREF_NO_BUTTON_SPACE */
#elif XIWS == XIWS_MAC
2, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
16, /* XI_PREF_SB_WIDTH */
16, /* XI_PREF_SB_HEIGHT */
XI_CURSOR_RESIZE, /* XI_PREF_SIZE_CURSOR_RID */
XI_CURSOR_HAND, /* XI_PREF_HAND_CURSOR_RID */
XI_CURSOR_VRESIZE, /* XI_PREF_VSIZE_CURSOR_RID */
COMBO_ICON, /* XI_PREF_COMBO_ICON */
XI_COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
XI_COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DARK */
TRUE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
0, /* XI_PREF_BUTTON_KEY */
TRUE, /* XI_PREF_LIMIT_MIN_WIN_SIZE */
5, /* XI_PREF_DEFAULT_MAX_LINES_IN_CELL */
FALSE, /* XI_PREF_KEEP_FOCUS_FIXED */
TRUE, /* XI_PREF_NATIVE_CTRLS */
XI_KEY_F3, /* XI_PREF_ITF_TAB_CHAR */
XI_KEY_F4, /* XI_PREF_ITF_BACKTAB_CHAR */
16, /* XI_PREF_ITF_WS_RIGHT */
4, /* XI_PREF_ITF_WS_BOTTOM */
40, /* XI_PREF_VIR_SP_H */
20, /* XI_PREF_VIR_SP_V */
TRUE, /* XI_PREF_DBL_PRESSES_BUTTON */
1, /* XI_PREF_CONTAINER_GRID_WIDTH */
TRUE, /* XI_PREF_MULTILINE_QUICK_PASTE */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
12, /* XI_PREF_BUTTON_HEIGHT */
32, /* XI_PREF_BUTTON_PAD */
16, /* XI_PREF_HORZ_SPACING */
2, /* XI_PREF_VERT_SPACING */
0, /* XI_PREF_HORZ_PIXEL_SPACING */
0, /* XI_PREF_VERT_PIXEL_SPACING */
40, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
FALSE /* XI_PREF_NO_BUTTON_SPACE */
/* Some compiler on the Mac won't accept a comma on the last entry, so don't
* put one. This means you have to put a comma after the old last entry when
* you add a new one. */
#elif XIWS == XIWS_XM || XIWS == XIWS_WXGTK
2, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
16, /* XI_PREF_SB_WIDTH */
16, /* XI_PREF_SB_HEIGHT */
XI_CURSOR_RESIZE, /* XI_PREF_SIZE_CURSOR_RID */
XI_CURSOR_HAND, /* XI_PREF_HAND_CURSOR_RID */
XI_CURSOR_VRESIZE, /* XI_PREF_VSIZE_CURSOR_RID */
COMBO_ICON, /* XI_PREF_COMBO_ICON */
XI_COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
XI_COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
XI_COLOR_DKGRAY, /* XI_PREF_COLOR_DARK */
TRUE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
0, /* XI_PREF_BUTTON_KEY */
TRUE, /* XI_PREF_LIMIT_MIN_WIN_SIZE */
5, /* XI_PREF_DEFAULT_MAX_LINES_IN_CELL */
FALSE, /* XI_PREF_KEEP_FOCUS_FIXED */
TRUE, /* XI_PREF_NATIVE_CTRLS */
XI_KEY_F3, /* XI_PREF_ITF_TAB_CHAR */
XI_KEY_F4, /* XI_PREF_ITF_BACKTAB_CHAR */
16, /* XI_PREF_ITF_WS_RIGHT */
4, /* XI_PREF_ITF_WS_BOTTOM */
40, /* XI_PREF_VIR_SP_H */
20, /* XI_PREF_VIR_SP_V */
TRUE, /* XI_PREF_DBL_PRESSES_BUTTON */
1, /* XI_PREF_CONTAINER_GRID_WIDTH */
TRUE, /* XI_PREF_MULTILINE_QUICK_PASTE */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
12, /* XI_PREF_BUTTON_HEIGHT */
32, /* XI_PREF_BUTTON_PAD */
16, /* XI_PREF_HORZ_SPACING */
2, /* XI_PREF_VERT_SPACING */
0, /* XI_PREF_HORZ_PIXEL_SPACING */
0, /* XI_PREF_VERT_PIXEL_SPACING */
0, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
FALSE, /* XI_PREF_NO_BUTTON_SPACE */
#elif XIWS == XIWS_WIN
2, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
16, /* XI_PREF_SB_WIDTH */
16, /* XI_PREF_SB_HEIGHT */
XI_CURSOR_RESIZE, /* XI_PREF_SIZE_CURSOR_RID */
XI_CURSOR_HAND, /* XI_PREF_HAND_CURSOR_RID */
XI_CURSOR_VRESIZE, /* XI_PREF_VSIZE_CURSOR_RID */
COMBO_ICON, /* XI_PREF_COMBO_ICON */
XI_COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
XI_COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DARK */
TRUE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
XI_KEY_DOWN | XI_MOD_ALT, /* XI_PREF_BUTTON_KEY */
TRUE, /* XI_PREF_LIMIT_MIN_WIN_SIZE */
5, /* XI_PREF_DEFAULT_MAX_LINES_IN_CELL */
FALSE, /* XI_PREF_KEEP_FOCUS_FIXED */
TRUE, /* XI_PREF_NATIVE_CTRLS */
XI_KEY_F3, /* XI_PREF_ITF_TAB_CHAR */
XI_KEY_F4, /* XI_PREF_ITF_BACKTAB_CHAR */
16, /* XI_PREF_ITF_WS_RIGHT */
4, /* XI_PREF_ITF_WS_BOTTOM */
40, /* XI_PREF_VIR_SP_H */
20, /* XI_PREF_VIR_SP_V */
TRUE, /* XI_PREF_DBL_PRESSES_BUTTON */
1, /* XI_PREF_CONTAINER_GRID_WIDTH */
TRUE, /* XI_PREF_MULTILINE_QUICK_PASTE */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
12, /* XI_PREF_BUTTON_HEIGHT */
32, /* XI_PREF_BUTTON_PAD */
16, /* XI_PREF_HORZ_SPACING */
2, /* XI_PREF_VERT_SPACING */
0, /* XI_PREF_HORZ_PIXEL_SPACING */
0, /* XI_PREF_VERT_PIXEL_SPACING */
30, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
FALSE, /* XI_PREF_NO_BUTTON_SPACE */
#else
2, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
16, /* XI_PREF_SB_WIDTH */
16, /* XI_PREF_SB_HEIGHT */
0, /* XI_PREF_SIZE_CURSOR_RID */
0, /* XI_PREF_HAND_CURSOR_RID */
0, /* XI_PREF_VSIZE_CURSOR_RID */
0, /* XI_PREF_COMBO_ICON */
XI_COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
XI_COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DARK */
TRUE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
0, /* XI_PREF_BUTTON_KEY */
TRUE, /* XI_PREF_LIMIT_MIN_WIN_SIZE */
5, /* XI_PREF_DEFAULT_MAX_LINES_IN_CELL */
FALSE, /* XI_PREF_KEEP_FOCUS_FIXED */
TRUE, /* XI_PREF_NATIVE_CTRLS */
XI_KEY_F3, /* XI_PREF_ITF_TAB_CHAR */
XI_KEY_F4, /* XI_PREF_ITF_BACKTAB_CHAR */
16, /* XI_PREF_ITF_WS_RIGHT */
4, /* XI_PREF_ITF_WS_BOTTOM */
40, /* XI_PREF_VIR_SP_H */
20, /* XI_PREF_VIR_SP_V */
TRUE, /* XI_PREF_DBL_PRESSES_BUTTON */
1, /* XI_PREF_CONTAINER_GRID_WIDTH */
TRUE, /* XI_PREF_MULTILINE_QUICK_PASTE */
XI_COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
12, /* XI_PREF_BUTTON_HEIGHT */
32, /* XI_PREF_BUTTON_PAD */
16, /* XI_PREF_HORZ_SPACING */
2, /* XI_PREF_VERT_SPACING */
0, /* XI_PREF_HORZ_PIXEL_SPACING */
0, /* XI_PREF_VERT_PIXEL_SPACING */
0, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
FALSE, /* XI_PREF_NO_BUTTON_SPACE */
#endif
};
static long aga_preferences[AGA_NBR_PREFERENCES] = { XI_COLOR_LTGRAY, XI_COLOR_GRAY, XI_COLOR_DKGRAY, XI_COLOR_BLACK };
XinRect big_clip = {
0, 0, 10000, 10000};
typedef struct
{
XinFont *font;
int leading;
int ascent;
int descent;
int char_width;
} FONT_INFO;
static FONT_INFO* font_info = NULL;
static int font_info_cnt = 0;
static void xi_caret_suspend( XinWindow win );
static void xi_caret_restore( XinWindow win );
static void recalc_metrics( XI_OBJ * xi_obj );
char* gstrncpy( char *dst, const char *src, int n )
{
char *p = dst;
while ( n > 0 && *src != 0 )
{
*p++ = *src++;
n--;
}
if ( n != 0 )
*p++ = '\0';
return ( dst );
}
char* tstrncpy( char *dst, const char *src, int n )
{
gstrncpy(dst, src, n);
dst[n - 1] = '\0';
return ( dst );
}
void order_ints( int *ip1, int *ip2 )
{
if ( *ip1 > *ip2 )
{
const int temp = *ip1;
*ip1 = *ip2;
*ip2 = temp;
}
}
XinRect *
xi_inflate_rect( XinRect * rct, int amount )
{
rct->bottom += amount;
rct->right += amount;
rct->left -= amount;
rct->top -= amount;
return ( rct );
}
void
xi_offset_rect( XinRect * rct, int delta_x, int delta_y )
{
rct->top += delta_y;
rct->bottom += delta_y;
rct->right += delta_x;
rct->left += delta_x;
}
int
clip( int val, int mn, int mx )
{
return ( val < mn ? mn : ( val > mx ? mx : val ) );
}
void
xi_realloc_array( void **ptr, int nbr, size_t sz, void *parent )
{
BOOLEAN is_zero = ( nbr * sz ) == 0;
if ( !*ptr )
{
if ( is_zero )
*ptr = NULL;
else
*ptr = ( void * ) xi_tree_malloc( nbr * sz, parent );
}
else
{
if ( is_zero )
{
xi_tree_free( *ptr );
*ptr = NULL;
}
else
*ptr = ( void * ) xi_tree_realloc( *ptr, nbr * sz );
}
}
static void
do_vir_pan_event( XI_OBJ * itf, int h, int v, BOOLEAN before )
{
XI_EVENT xiev;
MEMCLEAR( xiev );
xiev.type = XIE_VIR_PAN;
xiev.v.vir_pan.before_pan = before;
xiev.v.vir_pan.delta_x = h;
xiev.v.vir_pan.delta_y = v;
( *( XI_EH_TYPE ) itf->v.itf->xi_eh ) ( itf, &xiev );
}
static void
set_sb_positions( XI_OBJ * itf )
{
XI_ITF_DATA *itf_data;
XinWindow win;
int ps;
itf_data = itf->v.itf;
win = xi_get_window( itf );
if ( itf_data->max_xi_pnt.v - itf_data->win_xi_pnt.v )
ps = ( int ) ( 100L * ( long ) ( itf_data->phys_xi_pnt.v ) /
( ( long ) itf_data->max_xi_pnt.v -
( long ) itf_data->win_xi_pnt.v ) );
else
ps = 0;
XinScrollBarPositionSet( win, XinScrollBarTypeVertical, ps );
if ( itf_data->max_xi_pnt.h - itf_data->win_xi_pnt.h )
ps = ( int ) ( 100L * ( long ) ( itf_data->phys_xi_pnt.h ) /
( ( long ) itf_data->max_xi_pnt.h -
( long ) itf_data->win_xi_pnt.h ) );
else
ps = 0;
XinScrollBarPositionSet( win, XinScrollBarTypeHorizontal, ps );
}
void
xi_get_hsb_rect( XI_OBJ * xi_obj, XinRect * rctp )
{
XI_LIST_DATA *list_data;
LM_DATA *lmp;
XinRect rct1,
rct3;
XI_OBJ **members;
int nbr_members;
#if XIWS == XIWS_WIN
XinRect r;
#endif
list_data = xi_obj->v.list;
lmp = ( LM_DATA * ) list_data->lm;
if ( list_data->have_hsb_rct )
{
*rctp = list_data->hsb_rct;
return;
}
#if XIWS == XIWS_WIN
if ( list_data->hsb_win )
XinWindowRectGet( list_data->hsb_win, &r );
#endif
members = xi_get_member_list( xi_obj, &nbr_members );
if ( !lmp->nbr_columns )
{
rct3.left = lmp->rct.left;
rct1 = lmp->rct;
}
else
{
if ( lmp->fixed_columns )
{
xi_get_rect( members[lmp->fixed_columns - 1], &rct1 );
rct3.left = rct1.right;
}
else
{
xi_get_rect( members[0], &rct1 );
rct3.left = lmp->rct.left;
}
}
/* subtract one so that the top of the horizontal scroll bar overlaps the
* bottom of the list by one pixel. */
#if XIWS != XIWS_WM
rct3.top = rct1.bottom - 1;
rct3.right = lmp->rct.left + lmp->pixel_width + 2 * BORDER_WIDTH;
#else
rct3.top = rct1.bottom;
rct3.right = lmp->rct.left + lmp->pixel_width;
#endif
rct3.bottom = rct3.top + ( int ) xi_get_pref( XI_PREF_SB_HEIGHT );
#if XIWS == XIWS_WIN
if ( list_data->hsb_win )
rct3.bottom = rct3.top + r.bottom;
#endif
if ( rct3.left >= rct3.right )
rct3.right = rct3.left + 1;
*rctp = rct3;
list_data->hsb_rct = rct3;
list_data->have_hsb_rct = TRUE;
}
void
xi_get_sb_rect( XI_OBJ * xi_obj, XinRect * rctp )
{
XinRect rct;
int offset,
width;
XI_LIST_DATA *list_data;
LM_DATA *lmp;
#if XIWS == XIWS_WIN
XinRect r;
#endif
list_data = xi_obj->v.list;
lmp = ( LM_DATA * ) list_data->lm;
if ( list_data->have_sb_rct )
{
*rctp = list_data->sb_rct;
return;
}
#if XIWS == XIWS_WIN
if ( list_data->sb_win )
XinWindowRectGet( list_data->sb_win, &r );
#endif
lm_get_rect( list_data->lm, LM_LIST, 0, &rct );
list_data->sb_offset = offset = ( int ) xi_get_pref( XI_PREF_SB_OFFSET );
list_data->sb_width = width = ( int ) xi_get_pref( XI_PREF_SB_WIDTH );
/* subtract one from the left of the scroll bar rectangle, so that the left
* edge of the scroll bar overlaps the right double wide line, by one pixel. */
#if XIWS != XIWS_WM
if ( list_data->width )
rct.left = rct.left + lmp->pixel_width + offset + 2 * BORDER_WIDTH - 1;
else
rct.left = rct.right + offset - 1;
#else
if ( list_data->width )
rct.left = rct.left + lmp->pixel_width + offset;
else
rct.left = rct.right + offset;
#endif
rct.right = rct.left + width;
#if XIWS == XIWS_WIN
if ( list_data->sb_win )
rct.right = rct.left + r.right;
#endif
if ( list_data->scroll_bar_button )
{
LM_DATA *lm_data;
lm_data = ( LM_DATA * ) list_data->lm;
list_data->sbb_rct.top = rct.top + 1; /* Add one, so that there is
* room for the double line
* border */
list_data->sbb_rct.bottom = lm_data->pix_row1_top - BORDER_WIDTH + 1;
list_data->sbb_rct.left = rct.left;
list_data->sbb_rct.right = rct.right;
#if XIWS == XIWS_WIN
if ( list_data->sb_win )
list_data->sbb_rct.right = list_data->sbb_rct.left + r.right;
#endif
#if XIWS == XIWS_WM
rct.top = lm_data->pix_row1_top;
#else
rct.top = list_data->sbb_rct.bottom;
#endif
}
*rctp = rct;
list_data->sb_rct = rct;
list_data->have_sb_rct = TRUE;
}
void
xi_move_list_scroll_bar( XI_OBJ * xi_obj )
{
XinRect rct;
XinWindow win = xi_obj->itf->v.itf->xin_win;
XinWindow sb_win;
XI_LIST_DATA *list_data;
XI_ITF_DATA *itf_data;
list_data = xi_obj->v.list;
if ( list_data->scroll_bar_button )
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win,
&list_data->sbb_rct );
xi_get_sb_rect( xi_obj, &rct );
itf_data = xi_obj->itf->v.itf;
xi_offset_rect( &rct, -itf_data->delta_x, -itf_data->delta_y );
sb_win = list_data->sb_win;
if ( sb_win && rct.left < rct.right && rct.top < rct.bottom )
XinWindowRectSet( sb_win, &rct );
if ( list_data->scroll_bar_button )
xi_invalidate_rect( win, &list_data->sbb_rct );
}
void
xi_move_list_hscroll_bar( XI_OBJ * xi_obj )
{
XinRect rct;
XinWindow hsb_win;
XI_LIST_DATA *list_data;
XI_ITF_DATA *itf_data;
list_data = xi_obj->v.list;
xi_get_hsb_rect( xi_obj, &rct );
itf_data = xi_obj->itf->v.itf;
xi_offset_rect( &rct, -itf_data->delta_x, -itf_data->delta_y );
hsb_win = list_data->hsb_win;
if (hsb_win && rct.left < rct.right && rct.top < rct.bottom)
XinWindowRectSet( hsb_win, &rct );
}
BOOLEAN
xi_half_baked( XinWindow win )
{
XI_OBJ *itf;
itf = xi_get_itf( win );
if ( itf )
return itf->v.itf->half_baked;
return FALSE;
}
XinFont *
xi_get_system_font( void )
{
return xi_sysfont;
}
XI_OBJ *
xi_get_drag_list_obj( void )
{
return xi_drag_list_obj;
}
int
xi_get_sysval( XI_SV_TYPE valtype )
{
return ( xi_sysvals[valtype] );
}
void
xi_set_sysval( XI_SV_TYPE valtype, int value )
{
xi_sysvals[valtype] = value;
}
void
xi_clean_up( )
{
FONT_INFO* fi;
int num;
#ifndef NO_PRIMARY_SELECTION
#if XIWS == XIWS_XM
clean_primesel( );
#endif
#endif
if ( xi_sysfont != NULL )
XinFontDestroy( xi_sysfont );
for ( num = 0, fi = font_info; num < font_info_cnt; num++, fi++ )
XinFontDestroy( fi->font );
if ( font_info != NULL )
xi_tree_free( font_info );
font_info = NULL;
font_info_cnt = 0;
}
long
xi_get_pref( XI_PREF_TYPE pref_type )
{
return xi_preferences[pref_type];
}
void
xi_set_pref( XI_PREF_TYPE preftype, long value )
{
xi_preferences[preftype] = value;
}
long
aga_get_pref(AGA_PREF_TYPE preftype)
{
return aga_preferences[preftype];
}
void
aga_set_pref(AGA_PREF_TYPE preftype, long value)
{
aga_preferences[preftype] = value;
}
void
xi_set_font( XinFont * font )
{
font_set = TRUE;
if ( xi_sysfont != NULL )
XinFontDestroy( xi_sysfont );
XinFontCopy( &xi_sysfont, font );
}
void
xi_set_drag_list_obj( XI_OBJ * obj )
{
xi_drag_list_obj = obj;
}
void
xi_set_font_id( void *font_id )
{
#ifdef XI_USE_XVT
font_set = TRUE;
if ( xi_sysfont != NULL )
XinFontDestroy( xi_sysfont );
xi_sysfont = XinFontXvtConvert( font_id );
#endif
}
void
xi_init_sysvals( void )
{
int ascent,
descent,
leading,
height,
char_width;
if ( !font_set )
{
xi_sysfont = XinFontCreate( );
XinFontFamilySet( xi_sysfont, XinFontFamilyHelvetica );
XinFontSizeSet( xi_sysfont, 9 );
}
xi_get_font_metrics_font( xi_sysfont, &leading, &ascent, &descent,
&char_width );
xi_set_sysval( XI_SV_SYSFONT_ASCENT, ascent );
xi_set_sysval( XI_SV_SYSFONT_DESCENT, descent );
xi_set_sysval( XI_SV_SYSFONT_LEADING, leading );
height = ascent + descent + leading;
xi_set_sysval( XI_SV_FU_HEIGHT, height + STX_VERT_FUDGE );
xi_set_sysval( XI_SV_FU_WIDTH, char_width );
xi_set_sysval( XI_SV_SYSFONT_HEIGHT, height );
}
void
xi_fu_to_pu( XI_OBJ * itf, XinPoint * pnts, int nbr_pnts )
{
NOREF( itf );
while ( nbr_pnts != 0 )
{
pnts->v = ( short ) ( ( ( long ) pnts->v * ( long ) xi_get_fu_height( itf ) ) / ( long ) XI_FU_MULTIPLE );
pnts->h = ( short ) ( ( ( long ) pnts->h * ( long ) xi_get_fu_width( itf ) ) / ( long ) XI_FU_MULTIPLE );
pnts++;
nbr_pnts--;
}
}
void
xi_pu_to_fu( XI_OBJ * itf, XinPoint * pnts, int nbr_pnts )
{
long fu_h,
fu_w;
NOREF( itf );
fu_h = ( long ) xi_get_fu_height( itf );
fu_w = ( long ) xi_get_fu_width( itf );
while ( nbr_pnts != 0 )
{
pnts->v = ( short ) ( ( ( long ) pnts->v * ( long ) XI_FU_MULTIPLE ) / fu_h );
pnts->h = ( short ) ( ( ( long ) pnts->h * ( long ) XI_FU_MULTIPLE ) / fu_w );
pnts++;
nbr_pnts--;
}
}
/*
* xi_tree_realloc2() handles the degenerate case of passing in a NULL
* pointer for the old pointer.
*/
#ifdef TREEDEBUG
char *
xi_tree_realloc_d2( char *oldp, size_t size, char *parent, int line,
char *filename )
{
if ( oldp == NULL )
return ( ( char * ) xi_tree_malloc_d( size, parent, line, filename ) );
else
return ( ( char * ) xi_tree_realloc_d( oldp, size, line, filename ) );
}
#else
char *
xi_tree_realloc2( char *oldp, size_t size, char *parent )
{
if ( oldp == NULL )
return ( ( char * ) xi_tree_malloc( size, parent ) );
else
return ( ( char * ) xi_tree_realloc( oldp, size ) );
}
#endif
int
xi_get_text_width( XinFont * font, char *s, int len, unsigned long attrib )
{
char buf[4];
int pw_size;
if ( len == -1 )
len = strlen( s );
if ( attrib & XI_ATR_PASSWORD )
{
buf[0] = ( char ) xi_get_pref( XI_PREF_PASSWORD_CHAR );
buf[1] = '\0';
pw_size = XinFontTextWidthGet( font, buf, 1 );
return ( pw_size * len );
}
else
return ( XinFontTextWidthGet( font, s, len ) );
}
static void
xi_draw_mnemonic_line( XinWindow win, XinFont * font, char *buf, char mnemonic, int mnemonic_instance, int horizontal,
int vertical )
{
char *bufp;
int left,
right;
if ( !mnemonic )
return;
if ( mnemonic_instance == 0 )
mnemonic_instance = 1;
for ( bufp = buf; *bufp != '\0'; ++bufp )
{
if ( *bufp == mnemonic )
{
--mnemonic_instance;
if ( !mnemonic_instance )
{
XinPen pen;
XinDrawTools dt;
XinPoint p1,
p2;
XinWindowDrawToolsGet( win, &dt );
left = XinFontTextWidthGet( font, buf, ( int ) ( bufp - buf ) );
right = XinFontTextWidthGet( font, buf, ( int ) ( bufp - buf + 1 ) );
pen = black_cpen;
pen.fore_color = dt.text_fore_color;
XinWindowPenSet( win, &pen );
XinWindowDrawModeSet( win, XinDrawModeCopy );
p1.h = horizontal + left;
p1.v = vertical + 1;
xi_move_to( win, p1 );
p2.h = horizontal + right;
p2.v = p1.v;
xi_draw_line( win, p2 );
return;
}
}
}
}
void
xi_draw_clipped_text( XinWindow win, XinFont * font, char *s, XinRect * bound_rctp,
XinRect * clip_rctp, unsigned long attrib, BOOLEAN set_the_cpen,
int rule_and_space, int str_len, char mnemonic, short mnemonic_instance, int *bline )
{
int ascent,
descent,
leading,
wid;
char *buf;
int baseline;
XinRect tmp_rct;
if ( !( attrib & XI_ATR_VISIBLE ) )
return;
XinWindowFontMap( win, font );
XinFontMetricsGet( font, &leading, &ascent, &descent );
tmp_rct = *clip_rctp;
tmp_rct.bottom = tmp_rct.bottom - BORDER_WIDTH;
xi_set_clip( win, &tmp_rct );
NOREF( set_the_cpen );
/* TODO ????? if (set_the_cpen) XinWindowPenSet(win, &black_cpen); */
buf = xi_get_text_string( s, attrib );
#if XIWS == XIWS_WM
NOREF( rule_and_space );
baseline = bound_rctp->top + 8;
#else
if ( attrib & XI_ATR_VCENTER )
baseline = bound_rctp->top + leading + ascent + rule_and_space +
( bound_rctp->bottom - bound_rctp->top - leading - ascent - descent ) / 2 - 1;
else
baseline = bound_rctp->top + leading + ascent + rule_and_space - 1;
#endif
if ( bline )
*bline = baseline;
if ( attrib & XI_ATR_RJUST )
{
wid = XinFontTextWidthGet( font, buf, -1 );
xi_draw_text( win, font, bound_rctp->right - wid, baseline, buf, str_len );
xi_draw_mnemonic_line( win, font, buf, mnemonic, mnemonic_instance, bound_rctp->right - wid,
baseline );
}
else
{
if ( attrib & XI_ATR_HCENTER )
{
int x;
wid = XinFontTextWidthGet( font, buf, str_len );
x = ( bound_rctp->left + bound_rctp->right ) / 2 - wid / 2;
if ( x < bound_rctp->left )
x = bound_rctp->left;
xi_draw_text( win, font, x, baseline, buf, str_len );
xi_draw_mnemonic_line( win, font, buf, mnemonic, mnemonic_instance, x, baseline );
}
else
{
xi_draw_text( win, font, bound_rctp->left, baseline, buf, str_len );
xi_draw_mnemonic_line( win, font, buf, mnemonic, mnemonic_instance, bound_rctp->left, baseline );
}
}
xi_set_clip( win, ( XinRect * ) NULL );
}
void
xi_draw_text_attrib( XinWindow win, XinFont * font, int x, int y, char *s,
int len, unsigned long attrib )
{
char *buf;
NOREF( len );
if ( !( attrib & XI_ATR_VISIBLE ) )
return;
buf = xi_get_text_string( s, attrib );
xi_draw_text( win, font, x, y, buf, -1 );
}
void
xi_draw_3d_rect( XinWindow win, XinRect * rctp, BOOLEAN well, int height,
XinColor color_light, XinColor color_ctrl, XinColor color_dark )
{
XinRect rct;
XinPoint pnt,
pnt2;
XinPen cpen;
XinBrush cbrush;
if ( !color_light )
{
color_light = xi_get_pref( XI_PREF_COLOR_LIGHT );
color_ctrl = xi_get_pref( XI_PREF_COLOR_CTRL );
color_dark = xi_get_pref( XI_PREF_COLOR_DARK );
}
cpen = black_cpen;
rct = *rctp;
XinWindowDrawModeSet( win, XinDrawModeCopy );
/* draw upper left lines */
cpen.fore_color = well ? color_dark : color_light;
XinWindowPenSet( win, &cpen );
pnt.h = rct.left;
pnt.v = rct.top;
xi_move_to( win, pnt );
pnt2.h = rct.left;
pnt2.v = rct.bottom - 1;
xi_draw_line( win, pnt2 );
xi_move_to( win, pnt );
pnt2.h = rct.right - 1;
pnt2.v = rct.top;
xi_draw_line( win, pnt2 );
if ( height == 2 )
{
pnt.h++;
pnt.v++;
xi_move_to( win, pnt );
pnt2.h = pnt.h;
pnt2.v = rct.bottom - 2;
xi_draw_line( win, pnt2 );
xi_move_to( win, pnt );
pnt2.h = rct.right - 2;
pnt2.v = pnt.v;
xi_draw_line( win, pnt2 );
}
/* draw lower right lines */
cpen.fore_color = well ? color_light : color_dark;
XinWindowPenSet( win, &cpen );
pnt.h = rct.left;
pnt.v = rct.bottom - 1;
xi_move_to( win, pnt );
pnt2.h = rct.right - 1;
pnt2.v = pnt.v;
xi_draw_line( win, pnt2 );
pnt.h = rct.right - 1;
pnt.v = rct.top;
xi_move_to( win, pnt );
pnt2.h = pnt.h;
pnt2.v = rct.bottom;
xi_draw_line( win, pnt2 );
if ( height == 2 )
{
pnt.h = rct.left + 1;
pnt.v = rct.bottom - 2;;
xi_move_to( win, pnt );
pnt2.h = rct.right - 1;
pnt2.v = pnt.v;
xi_draw_line( win, pnt2 );
pnt.h = rct.right - 2;
pnt.v = rct.top + 1;
xi_move_to( win, pnt );
pnt2.h = pnt.h;
pnt2.v = rct.bottom;
xi_draw_line( win, pnt2 );
}
XinWindowPenSet( win, &hollow_cpen );
cbrush = white_cbrush;
cbrush.fore_color = color_ctrl;
XinWindowBrushSet( win, &cbrush );
if ( height == 2 )
{
rct.top += 2;
rct.left += 2;
rct.bottom -= 2;
rct.right -= 2;
}
else
{
rct.top++;
rct.left++;
rct.bottom--;
rct.right--;
}
xi_draw_rect( win, &rct );
}
void
xi_draw_shaded_rect( XinWindow win, XinRect * rctp, BOOLEAN well, int height,
XinColor color_light, XinColor color_ctrl, XinColor color_dark )
{
XinRect rct;
XinPoint pnt,
pnt2;
XinPen cpen;
XinBrush cbrush;
if ( !color_light )
{
color_light = xi_get_pref( XI_PREF_COLOR_LIGHT );
color_ctrl = xi_get_pref( XI_PREF_COLOR_CTRL );
color_dark = xi_get_pref( XI_PREF_COLOR_DARK );
}
cpen = black_cpen;
rct = *rctp;
XinWindowDrawModeSet( win, XinDrawModeCopy );
/* draw upper left lines */
cpen.fore_color = well ? color_dark : color_light;
XinWindowPenSet( win, &cpen );
pnt.h = rct.left;
pnt.v = rct.top;
xi_move_to( win, pnt );
pnt2.h = rct.left;
pnt2.v = rct.bottom - 1;
xi_draw_line( win, pnt2 );
xi_move_to( win, pnt );
pnt2.h = rct.right - 1;
pnt2.v = rct.top;
xi_draw_line( win, pnt2 );
if ( height == 2 )
{
pnt.h++;
pnt.v++;
xi_move_to( win, pnt );
pnt2.h = pnt.h;
pnt2.v = rct.bottom - 2;
xi_draw_line( win, pnt2 );
xi_move_to( win, pnt );
pnt2.h = rct.right - 2;
pnt2.v = pnt.v;
xi_draw_line( win, pnt2 );
}
/* draw lower right lines */
cpen.fore_color = well ? color_light : color_dark;
XinWindowPenSet( win, &cpen );
pnt.h = rct.left;
pnt.v = rct.bottom - 1;
xi_move_to( win, pnt );
pnt2.h = rct.right - 1;
pnt2.v = pnt.v;
xi_draw_line( win, pnt2 );
pnt.h = rct.right - 1;
pnt.v = rct.top;
xi_move_to( win, pnt );
pnt2.h = pnt.h;
pnt2.v = rct.bottom;
xi_draw_line( win, pnt2 );
if ( height == 2 )
{
pnt.h = rct.left + 1;
pnt.v = rct.bottom - 2;;
xi_move_to( win, pnt );
pnt2.h = rct.right - 1;
pnt2.v = pnt.v;
xi_draw_line( win, pnt2 );
pnt.h = rct.right - 2;
pnt.v = rct.top + 1;
xi_move_to( win, pnt );
pnt2.h = pnt.h;
pnt2.v = rct.bottom;
xi_draw_line( win, pnt2 );
}
XinWindowPenSet( win, &hollow_cpen );
cbrush = white_cbrush;
cbrush.fore_color = color_ctrl;
XinWindowBrushSet( win, &cbrush );
if ( height == 2 )
{
rct.top += 2;
rct.left += 2;
rct.bottom -= 2;
rct.right -= 2;
}
else
{
rct.top++;
rct.left++;
rct.bottom--;
rct.right--;
}
XinWindowShadedRectDraw(win, &rct);
}
void
xi_draw_checkmark( XinWindow win, XinRect * rctp )
{
XinWindowCheckMarkDraw( win, rctp );
}
void
xi_draw_3d_line( XinWindow win, XinPoint pnt1, XinPoint pnt2, BOOLEAN well )
{
XinColor color_light,
color_dark;
XinPoint pnt1x,
pnt2x;
XinPen cpen;
color_light = xi_get_pref( XI_PREF_COLOR_LIGHT );
color_dark = xi_get_pref( XI_PREF_COLOR_DARK );
cpen = black_cpen;
XinWindowDrawModeSet( win, XinDrawModeCopy );
cpen.fore_color = well ? color_dark : color_light;
XinWindowPenSet( win, &cpen );
xi_move_to( win, pnt1 );
xi_draw_line( win, pnt2 );
pnt1x = pnt1;
pnt2x = pnt2;
if ( pnt1x.v == pnt2x.v )
{
pnt1x.v++;
pnt2x.v++;
}
else
{
pnt1x.h++;
pnt2x.h++;
}
cpen.fore_color = well ? color_light : color_dark;
XinWindowPenSet( win, &cpen );
xi_move_to( win, pnt1x );
xi_draw_line( win, pnt2x );
}
void
xi_draw_thick_rect( XinWindow win, XinRect * rctp, int width )
{
XinRect mrct;
int i;
mrct = *rctp;
for ( i = 0; i < width; ++i )
{
xi_draw_rect( win, &mrct );
mrct.top++;
mrct.left++;
mrct.bottom--;
mrct.right--;
}
}
void
xi_draw_diamond( XinWindow win, XinRect * rctp, BOOLEAN well, BOOLEAN black, BOOLEAN fill,
XinColor color )
{
XinPoint pnt1,
pnt2;
int half_width,
width;
XinRect rct;
XinColor color_light,
color_ctrl,
color_dark;
XinPen cpen;
rct = *rctp;
width = ( rct.right - rct.left ) / 2;
width = width * 2 + 1;
half_width = width / 2 + 1;
rct.right = rct.left + width;
rct.bottom = rct.top + width;
color_light = xi_get_pref( XI_PREF_COLOR_LIGHT );
color_ctrl = xi_get_pref( XI_PREF_COLOR_CTRL );
color_dark = xi_get_pref( XI_PREF_COLOR_DARK );
cpen = black_cpen;
cpen.fore_color = well ? color_dark : color_light;
if ( black )
cpen.fore_color = XI_COLOR_BLACK;
if ( color )
cpen.fore_color = color;
XinWindowPenSet( win, &cpen );
XinWindowDrawModeSet( win, XinDrawModeCopy );
/* upper left */
pnt1.h = rct.left;
pnt1.v = rct.top + half_width;
xi_move_to( win, pnt1 );
pnt2.h = rct.left + half_width;
pnt2.v = rct.top;
xi_draw_line( win, pnt2 );
/* lower left */
pnt1.h = rct.left;
pnt1.v = rct.top + half_width - 1;
xi_move_to( win, pnt1 );
pnt2.h = rct.left + half_width - 1;
pnt2.v = rct.bottom - 1;
xi_draw_line( win, pnt2 );
cpen.fore_color = well ? color_light : color_dark;
if ( black )
cpen.fore_color = XI_COLOR_BLACK;
if ( color )
cpen.fore_color = color;
XinWindowPenSet( win, &cpen );
/* upper right */
pnt1.h = rct.left + half_width;
pnt1.v = rct.top + 1;
xi_move_to( win, pnt1 );
pnt2.h = rct.right;
pnt2.v = rct.top + half_width;
xi_draw_line( win, pnt2 );
/* lower right */
pnt1.h = rct.left + half_width - 1;
pnt1.v = rct.bottom;
xi_move_to( win, pnt1 );
pnt2.h = rct.right;
pnt2.v = rct.top + half_width - 1;
xi_draw_line( win, pnt2 );
if ( fill )
{
int h,
v1,
v2,
hwm1;
XinPoint pnt1,
pnt2;
v1 = rct.top + half_width - 1;
v2 = rct.top + half_width;
cpen.fore_color = color_ctrl;
XinWindowPenSet( win, &cpen );
hwm1 = rct.left + half_width - 1;
for ( h = rct.left + 1; h <= rct.right - 2; ++h )
{
pnt1.h = h;
pnt1.v = v1;
xi_move_to( win, pnt1 );
pnt2.h = h;
pnt2.v = v2;
xi_draw_line( win, pnt2 );
if ( h < hwm1 )
{
v1--;
v2++;
}
else
{
v1++;
v2--;
}
}
}
}
void
xi_draw_3d_diamond( XinWindow win, XinRect * rctp, BOOLEAN well, BOOLEAN black, int height,
XinColor color )
{
XinRect rct;
int i;
rct = *rctp;
for ( i = 0; i < height; ++i )
{
xi_draw_diamond( win, &rct, well, black, ( BOOLEAN ) ( i == height - 1 ), color );
rct.top++;
rct.left++;
rct.bottom--;
rct.right--;
if ( rct.top > rct.bottom || rct.left > rct.right )
break;
}
}
#ifdef NEED_MEMMOVE
char *
memmove( register char *d, register char *s, long n )
{
char *dst = d;
/* remove when MEDIUM goes away */
if ( d < s )
while ( n-- > 0 )
*d++ = *s++;
else
{
d += ( int ) n - 1;
s += ( int ) n - 1;
while ( n-- > 0 )
*d-- = *s--;
}
return dst;
}
#endif
#if XIWS != XIWS_WM
void
dbg_rct( char *tag, XinRect * rct )
{
char buf[100];
sprintf( buf,
"%s: top %d left %d bottom %d right %d", tag, rct->top, rct->left,
rct->bottom, rct->right );
xi_dbg( buf );
}
#endif
void
xi_set_cur_window( XinWindow win )
{
cur_window = win;
cur_itf = xi_get_itf( win );
if ( cur_itf )
{
cur_delta_x = cur_itf->v.itf->delta_x;
cur_delta_y = cur_itf->v.itf->delta_y;
}
else
{
cur_delta_x = 0;
cur_delta_y = 0;
}
}
void
xi_dbg( char *buf )
{
XinDebugPrintf( buf );
}
void
xi_even_fu( int *f )
{
*f = ( *f * XI_FU_MULTIPLE + XI_FU_MULTIPLE / 2 ) / XI_FU_MULTIPLE;
}
void
xi_even_fu_pnt( XinPoint * p )
{
p->h = ( p->h * XI_FU_MULTIPLE + XI_FU_MULTIPLE / 2 ) / XI_FU_MULTIPLE;
p->v = ( p->v * XI_FU_MULTIPLE + XI_FU_MULTIPLE / 2 ) / XI_FU_MULTIPLE;
}
int
xi_get_fu_width( XI_OBJ * itf )
{
if ( itf )
return itf->v.itf->fu_width;
else
return xi_get_fu_width_font( xi_get_system_font( ) );
}
int
xi_get_fu_height( XI_OBJ * itf )
{
if ( itf )
return itf->v.itf->fu_height;
else
return xi_get_fu_height_font( xi_get_system_font( ) );
}
int
xi_get_fu_width_font( XinFont * font )
{
int leading,
ascent,
descent,
char_width;
xi_get_font_metrics_font( font, &leading, &ascent, &descent, &char_width );
return char_width;
}
int
xi_get_fu_height_font( XinFont * font )
{
int leading,
ascent,
descent,
char_width;
int height;
xi_get_font_metrics_font( font, &leading, &ascent, &descent, &char_width );
height = leading + ascent + descent + STX_VERT_FUDGE;
return height;
}
void
xi_fu_to_pu_font( XinFont * font, XinPoint * pnts, int nbr_pnts )
{
int leading,
ascent,
descent,
char_width;
int height;
xi_get_font_metrics_font( font, &leading, &ascent, &descent, &char_width );
height = leading + ascent + descent + STX_VERT_FUDGE;
while ( nbr_pnts != 0 )
{
pnts->v = ( short ) ( ( ( long ) pnts->v * ( long ) height ) / ( long ) XI_FU_MULTIPLE );
pnts->h = ( short ) ( ( ( long ) pnts->h * ( long ) char_width ) / ( long ) XI_FU_MULTIPLE );
pnts++;
nbr_pnts--;
}
}
BOOLEAN
font_compare( XinFont * f1, XinFont * f2 )
{
return XinFontCompare( f1, f2 );
}
void
xi_get_font_metrics_font( XinFont * font, int *leading,
int *ascent, int *descent, int *char_width )
{
FONT_INFO* fi;
int i;
XinWindow win = (XinWindow)0L;
BOOLEAN close_win = FALSE;
XinRect rct;
for ( i = 0, fi = font_info; i < font_info_cnt; ++i, ++fi )
{
if ( font_compare( fi->font, font ) )
{
*leading = fi->leading;
*ascent = fi->ascent;
*descent = fi->descent;
*char_width = fi->char_width;
return;
}
}
++font_info_cnt;
if ( font_info )
font_info = ( FONT_INFO * ) xi_tree_realloc( font_info, sizeof( FONT_INFO ) * font_info_cnt );
else
font_info = ( FONT_INFO * ) xi_tree_malloc( sizeof( FONT_INFO ) * font_info_cnt, ( void * ) NULL );
fi = &font_info[font_info_cnt - 1];
XinFontCopy( &fi->font, font );
if ( !XinFontIsMapped( fi->font ) )
{
rct.top = -200;
rct.left = -200;
rct.bottom = -100;
rct.right = -100;
{
XinWindowDef Def;
MEMCLEAR( Def );
Def.type = XinWindowTypeDocument;
Def.border_style = XinBorderFixed;
Def.p_rect = &rct;
Def.title = "";
Def.vertical_scroll_bar = FALSE;
Def.horizontal_scroll_bar = FALSE;
Def.close_button = FALSE;
Def.visible = FALSE;
Def.enabled = FALSE;
Def.parent = XinWindowTaskGet( );
win = XinWindowCreate( &Def );
}
close_win = TRUE;
XinWindowFontMap( win, font );
}
{
int tl,
ta,
td;
XinFontMetricsGet( font, &tl, &ta, &td );
fi->leading = tl;
fi->ascent = ta;
fi->descent = td;
}
fi->char_width = XinFontTextWidthGet( font,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
-1 ) / 52;
if ( close_win )
{
XinFontUnmap( font ); /* RGM: Font unmap hack */
XinWindowDestroy( win );
}
*leading = fi->leading;
*ascent = fi->ascent;
*descent = fi->descent;
*char_width = fi->char_width;
}
/********************************************************************/
/* FUNCTIONS THAT NEED TRANSPOSING */
static void
ppnt_to_vpnt( XinWindow win, XinPoint * pnt )
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
itf = xi_get_itf( win );
if ( itf )
{
itf_data = itf->v.itf;
pnt->h += itf_data->delta_x;
pnt->v += itf_data->delta_y;
}
}
static void
vpnt_to_ppnt( XinWindow win, XinPoint * pnt )
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
itf = xi_get_itf( win );
if ( itf )
{
itf_data = itf->v.itf;
pnt->h -= itf_data->delta_x;
pnt->v -= itf_data->delta_y;
}
}
static void
vrct_to_prct( XinWindow win, XinRect * rct )
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
itf = xi_get_itf( win );
if ( itf )
{
itf_data = itf->v.itf;
rct->left -= itf_data->delta_x;
rct->right -= itf_data->delta_x;
rct->top -= itf_data->delta_y;
rct->bottom -= itf_data->delta_y;
}
}
static void
move_controls( XI_OBJ * xi_obj )
{
XI_OBJ **objlist;
int n;
XinRect rct;
switch ( xi_obj->type )
{
case XIT_ITF:
if ( !xi_obj->v.itf->half_baked )
XinWindowPaintForce( xi_obj->v.itf->xin_win );
break;
#ifdef XI_USE_TX_SUPPORT
case XIT_FIELD:
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
xi_tx_edit_move( xi_obj );
break;
#endif
case XIT_LIST:
{
XI_LIST_DATA *list_data;
XI_ITF_DATA *itf_data;
itf_data = xi_obj->itf->v.itf;
list_data = xi_obj->v.list;
if ( list_data->sb_win )
{
xi_get_sb_rect( xi_obj, &rct );
xi_offset_rect( &rct, -itf_data->delta_x, -itf_data->delta_y );
XinWindowRectSet( list_data->sb_win, &rct );
}
if ( list_data->hsb_win )
{
xi_get_hsb_rect( xi_obj, &rct );
xi_offset_rect( &rct, -itf_data->delta_x, -itf_data->delta_y );
XinWindowRectSet( list_data->hsb_win, &rct );
}
break;
}
case XIT_BTN:
{
XinRect rct;
XI_ITF_DATA *itf_data;
XI_BTN_DATA *btn_data;
btn_data = xi_obj->v.btn;
if ( btn_data->btnctl )
{
itf_data = xi_obj->itf->v.itf;
rct = btn_data->rct;
xi_offset_rect( &rct, -itf_data->delta_x, -itf_data->delta_y );
XinWindowRectSet( btn_data->btnctl, &rct );
}
break;
}
default:
break;
}
objlist = xi_get_member_list( xi_obj, &n );
for ( ; n > 0; n--, objlist++ )
move_controls( *objlist );
if ( xi_obj->type == XIT_ITF )
xi_set_clip( xi_obj->v.itf->xin_win, NULL );
}
void
xi_adjust_sb_vir_itf( XinWindow win, XI_OBJ * itf )
{
XinRect rct;
XI_ITF_DATA *itf_data;
itf_data = itf->v.itf;
XinWindowRectGet( win, &rct );
itf_data->win_xi_pnt.v = rct.bottom - rct.top;
itf_data->win_xi_pnt.h = rct.right - rct.left;
xi_pu_to_fu( itf, &itf_data->win_xi_pnt, 1 );
xi_even_fu_pnt( &itf_data->win_xi_pnt );
if ( itf_data->win_xi_pnt.h + itf_data->phys_xi_pnt.h >
itf_data->max_xi_pnt.h ||
itf_data->win_xi_pnt.v + itf_data->phys_xi_pnt.v >
itf_data->max_xi_pnt.v )
{
XinPoint p;
int old_delta_x,
old_delta_y;
if ( itf_data->win_xi_pnt.h + itf_data->phys_xi_pnt.h >
itf_data->max_xi_pnt.h )
itf_data->phys_xi_pnt.h = itf_data->max_xi_pnt.h -
itf_data->win_xi_pnt.h;
if ( itf_data->phys_xi_pnt.h < 0 )
itf_data->phys_xi_pnt.h = 0;
if ( itf_data->win_xi_pnt.v + itf_data->phys_xi_pnt.v >
itf_data->max_xi_pnt.v )
itf_data->phys_xi_pnt.v = itf_data->max_xi_pnt.v -
itf_data->win_xi_pnt.v;
if ( itf_data->phys_xi_pnt.v < 0 )
itf_data->phys_xi_pnt.v = 0;
p.h = itf_data->phys_xi_pnt.h;
p.v = itf_data->phys_xi_pnt.v;
xi_fu_to_pu( itf, &p, 1 );
cur_delta_x = p.h;
cur_delta_y = p.v;
old_delta_x = itf_data->delta_x;
old_delta_y = itf_data->delta_y;
itf_data->delta_x = cur_delta_x;
itf_data->delta_y = cur_delta_y;
xi_caret_suspend( win );
if ( old_delta_x != cur_delta_x || old_delta_y != cur_delta_y )
xi_invalidate_rect( win, NULL );
move_controls( itf );
xi_caret_restore( win );
}
set_sb_positions( itf );
}
BOOLEAN
xi_eh( XinWindow win, XinEvent * ep )
{
switch ( ep->type )
{
case XinEventPaint:
update_pending = FALSE;
break;
case XinEventCharacter:
if ( update_pending && ( ep->v.character.ch == XI_KEY_UP || ep->v.character.ch == XI_KEY_DOWN ) )
return FALSE;
break;
case XinEventResize:
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
XinRect rct;
itf = xi_get_itf( win );
if ( !itf )
break;
itf_data = itf->v.itf;
if ( itf_data->size_font_to_win )
{
XinRect old_win_rct;
int bottom,
right;
XinFont *itf_font;
XinWindowRectGet( win, &rct );
old_win_rct = itf->v.itf->original_win_rct;
bottom = old_win_rct.bottom;
right = old_win_rct.right;
itf_font = itf_data->font;
if ( itf_font )
{
int point_size,
point_size2;
point_size = itf->v.itf->original_font_size;
point_size = ( point_size * rct.bottom + bottom / 2 ) / bottom;
point_size2 = itf->v.itf->original_font_size;
point_size2 = ( point_size2 * rct.right + right / 2 ) / right;
XinFontSizeSet( itf_font, point_size2 - 1 );
recalc_metrics( itf );
xi_invalidate_rect( xi_get_window( itf ), NULL );
}
break;
}
if ( itf_data->virtual_itf )
xi_adjust_sb_vir_itf( win, itf );
break;
}
case XinEventMouseDown:
case XinEventMouseUp:
case XinEventMouseDouble:
case XinEventMouseMove:
ppnt_to_vpnt( win, &ep->v.mouse.where );
break;
case XinEventHScroll:
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
int delta_x = 0,
old,
d;
itf = xi_get_itf( win );
if ( !itf )
break;
itf_data = itf->v.itf;
if ( !itf_data->virtual_itf )
break;
switch ( ep->v.scroll.action )
{
case XinScrollBarActionLineUp:
delta_x = -4 * XI_FU_MULTIPLE;
break;
case XinScrollBarActionLineDown:
delta_x = 4 * XI_FU_MULTIPLE;
break;
case XinScrollBarActionPageUp:
delta_x = -10 * XI_FU_MULTIPLE;
break;
case XinScrollBarActionPageDown:
delta_x = 10 * XI_FU_MULTIPLE;
break;
case XinScrollBarActionThumb:
{
int oldp,
newp;
oldp = itf_data->phys_xi_pnt.h;
newp = ( int ) ( ( long ) ep->v.scroll.position *
( ( long ) itf_data->max_xi_pnt.h -
( long ) itf_data->win_xi_pnt.h ) / 100L );
xi_even_fu( &newp );
delta_x = newp - oldp;
break;
}
case XinScrollBarActionThumbTrack:
delta_x = 0;
break;
default:
break;
}
old = itf_data->phys_xi_pnt.h;
itf_data->phys_xi_pnt.h += delta_x;
itf_data->phys_xi_pnt.h =
min( itf_data->phys_xi_pnt.h, itf_data->max_xi_pnt.h -
itf_data->win_xi_pnt.h );
itf_data->phys_xi_pnt.h =
max( itf_data->phys_xi_pnt.h, 0 );
d = itf_data->phys_xi_pnt.h - old;
/* d is now the delta in form units */
if ( d )
{
XinRect client_rct;
XinPoint pnt;
XinWindowPaintForce( win );
XinWindowRectGet( win, &client_rct );
pnt.h = itf_data->phys_xi_pnt.h;
xi_fu_to_pu( itf, &pnt, 1 );
cur_delta_x = pnt.h;
pnt.h = d;
xi_fu_to_pu( itf, &pnt, 1 );
xi_caret_suspend( win );
do_vir_pan_event( itf, pnt.h, 0, TRUE );
itf_data->delta_x += pnt.h;
XinWindowRectScroll( win, &client_rct, -pnt.h, 0 );
set_sb_positions( itf );
move_controls( itf );
do_vir_pan_event( itf, pnt.h, 0, FALSE );
xi_caret_restore( win );
}
break;
}
case XinEventVScroll:
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
int delta_y = 0,
old,
d;
itf = xi_get_itf( win );
if ( !itf )
break;
itf_data = itf->v.itf;
if ( !itf_data->virtual_itf )
break;
switch ( ep->v.scroll.action )
{
case XinScrollBarActionLineUp:
delta_y = -XI_FU_MULTIPLE;
break;
case XinScrollBarActionLineDown:
delta_y = XI_FU_MULTIPLE;
break;
case XinScrollBarActionPageUp:
delta_y = -10 * XI_FU_MULTIPLE;
break;
case XinScrollBarActionPageDown:
delta_y = 10 * XI_FU_MULTIPLE;
break;
case XinScrollBarActionThumb:
{
int oldp,
newp;
oldp = itf_data->phys_xi_pnt.v;
newp = ( int ) ( ( long ) ep->v.scroll.position *
( ( long ) itf_data->max_xi_pnt.v -
( long ) itf_data->win_xi_pnt.v ) / 100L );
xi_even_fu( &newp );
delta_y = newp - oldp;
break;
}
case XinScrollBarActionThumbTrack:
delta_y = 0;
break;
default:
break;
}
old = itf_data->phys_xi_pnt.v;
itf_data->phys_xi_pnt.v += delta_y;
itf_data->phys_xi_pnt.v =
min( itf_data->phys_xi_pnt.v, itf_data->max_xi_pnt.v -
itf_data->win_xi_pnt.v );
itf_data->phys_xi_pnt.v =
max( itf_data->phys_xi_pnt.v, 0 );
d = itf_data->phys_xi_pnt.v - old;
if ( d )
{
XinRect client_rct;
XinPoint pnt;
XinWindowPaintForce( win );
XinWindowRectGet( win, &client_rct );
pnt.v = itf_data->phys_xi_pnt.v;
xi_fu_to_pu( itf, &pnt, 1 );
cur_delta_y = pnt.v;
pnt.v = d;
xi_fu_to_pu( itf, &pnt, 1 );
xi_caret_suspend( win );
do_vir_pan_event( itf, 0, pnt.v, TRUE );
itf_data->delta_y += pnt.v;
XinWindowRectScroll( win, &client_rct, 0, -pnt.v );
set_sb_positions( itf );
move_controls( itf );
do_vir_pan_event( itf, 0, pnt.v, FALSE );
xi_caret_restore( win );
}
break;
}
default:
break;
}
return TRUE;
}
void
xi_vir_pan( XI_OBJ * itf, int delta_x, int delta_y )
{
XinRect cr;
XinWindow win;
XI_ITF_DATA *itf_data;
XinPoint pf,
p;
int old;
pf.h = delta_x;
pf.v = delta_y;
itf_data = itf->v.itf;
win = xi_get_window( itf );
XinWindowRectGet( win, &cr );
XinWindowPaintForce( win );
/* clip y delta to appropriate bounding */
old = itf_data->phys_xi_pnt.v;
itf_data->phys_xi_pnt.v += pf.v;
itf_data->phys_xi_pnt.v =
min( itf_data->phys_xi_pnt.v, itf_data->max_xi_pnt.v -
itf_data->win_xi_pnt.v );
if ( itf_data->phys_xi_pnt.v < 0 )
itf_data->phys_xi_pnt.v = 0;
pf.v = itf_data->phys_xi_pnt.v - old;
/* clip x delta to appropriate bounding */
old = itf_data->phys_xi_pnt.h;
itf_data->phys_xi_pnt.h += pf.h;
itf_data->phys_xi_pnt.h =
min( itf_data->phys_xi_pnt.h, itf_data->max_xi_pnt.h -
itf_data->win_xi_pnt.h );
if ( itf_data->phys_xi_pnt.h < 0 )
itf_data->phys_xi_pnt.h = 0;
pf.h = itf_data->phys_xi_pnt.h - old;
/* convert to pixel coordinates */
p = pf;
xi_fu_to_pu( itf, &p, 1 );
/* add to current delta x and y */
cur_delta_y += p.v;
cur_delta_x += p.h;
/* do the virtual pan */
xi_caret_suspend( win );
do_vir_pan_event( itf, p.h, p.v, TRUE );
itf_data->delta_y = cur_delta_y;
itf_data->delta_x = cur_delta_x;
XinWindowRectScroll( win, &cr, -p.h, -p.v );
set_sb_positions( itf );
move_controls( itf );
do_vir_pan_event( itf, p.h, p.v, FALSE );
xi_caret_restore( win );
}
void
xi_make_obj_visible( XI_OBJ * xi_obj )
{
XinRect or,
cr,
cr2;
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
XinWindow win;
int dt,
db,
dl,
dr,
dh,
dv;
XinPoint p,
pf,
pp;
int pref_h,
pref_v;
switch ( xi_obj->type )
{
case XIT_ITF:
case XIT_GROUP:
case XIT_FORM:
case XIT_LIST:
case XIT_COLUMN:
case XIT_CONTAINER:
return;
default:
break;
}
pref_h = ( int ) xi_get_pref( XI_PREF_VIR_SP_H );
pref_v = ( int ) xi_get_pref( XI_PREF_VIR_SP_V );
itf = xi_obj->itf;
itf_data = itf->v.itf;
win = xi_get_window( itf );
xi_set_cur_window( win );
XinWindowRectGet( win, &cr );
pp.v = itf_data->max_xi_pnt.v;
pp.h = itf_data->max_xi_pnt.h;
xi_fu_to_pu( xi_obj->itf, &pp, 1 );
xi_get_rect( xi_obj, &or );
or.top -= pref_v;
if ( or.top < 0 )
or.top = 0;
or.bottom += pref_v;
if ( or.bottom > pp.v )
or.bottom = pp.v;
or.left -= pref_h;
if ( or.left < 0 )
or.left = 0;
or.right += pref_h;
if ( or.right > pp.h )
or.right = pp.h;
cr2 = cr;
cr2.left += itf_data->delta_x;
cr2.right += itf_data->delta_x;
cr2.top += itf_data->delta_y;
cr2.bottom += itf_data->delta_y;
dr = or.right - cr2.right; /* positive if not ok */
dr = max( 0, dr );
dr = min( dr, pp.h );
db = or.bottom - cr2.bottom; /* positive if not ok */
db = max( 0, db );
db = min( db, pp.v );
dl = cr2.left - or.left; /* positive if not ok */
dl = max( 0, dl );
dt = cr2.top - or.top; /* positive if not ok */
dt = max( 0, dt );
if ( dl && dr )
dr = 0;
if ( db && dt )
db = 0;
if ( dl )
dh = -dl;
else
dh = dr;
if ( dt )
dv = -dt;
else
dv = db;
p.h = dh;
p.v = dv;
xi_pu_to_fu( xi_obj->itf, &p, 1 );
xi_even_fu_pnt( &p );
pf = p;
xi_fu_to_pu( xi_obj->itf, &p, 1 );
if ( p.h || p.v )
{
XinWindowPaintForce( win );
itf_data->phys_xi_pnt.v += pf.v;
itf_data->phys_xi_pnt.h += pf.h;
cur_delta_y += p.v;
cur_delta_x += p.h;
xi_caret_suspend( win );
do_vir_pan_event( itf, p.h, p.v, TRUE );
itf_data->delta_y = cur_delta_y;
itf_data->delta_x = cur_delta_x;
XinWindowRectScroll( win, &cr, -p.h, -p.v );
set_sb_positions( itf );
move_controls( itf );
do_vir_pan_event( itf, p.h, p.v, FALSE );
xi_caret_restore( win );
}
}
void
xi_scroll_rect( XinWindow win, XinRect * rctp, int dh, int dv )
{
XinRect r;
xi_set_cur_window( win );
r = *rctp;
vrct_to_prct( win, &r );
if (dh == 0 && dv == 0)
update_pending = FALSE;
else
update_pending = TRUE;
XinWindowRectScroll( win, &r, dh, dv );
}
static void
xi_caret_suspend( XinWindow win )
{
XI_ITF_DATA *itf_data;
itf_data = xi_get_itf( win )->v.itf;
if ( itf_data->caret_is_on )
{
XinWindowCaretOff( win );
}
}
static void
xi_caret_restore( XinWindow win )
{
XI_ITF_DATA *itf_data;
XinPoint p;
XinDrawTools dt;
itf_data = xi_get_itf( win )->v.itf;
if ( itf_data->caret_is_on )
{
int x,
y;
XinRect local_clip;
p.h = itf_data->caret_x;
p.v = itf_data->caret_y;
vpnt_to_ppnt( win, &p );
x = p.h;
y = p.v;
local_clip = itf_data->caret_clip;
vrct_to_prct( win, &local_clip );
XinWindowDrawToolsGet( win, &dt );
XinWindowCaretOn( win, x, y, itf_data->caret_height, dt.text_back_color,
&local_clip );
}
}
void
xi_invalidate_rect( XinWindow win, XinRect * rct )
{
XinRect r,
cr,
dr;
if ( rct != NULL && ( rct->top >= rct->bottom || rct->left >= rct->right ) )
return;
if ( !rct )
{
XinWindowRectInvalidate( win, NULL );
return;
}
r = *rct;
vrct_to_prct( win, &r );
XinWindowRectGet( win, &cr );
if ( xi_rect_intersect( &dr, &r, &cr ) )
{
update_pending = TRUE;
XinWindowRectInvalidate( win, &r );
}
}
BOOLEAN
xi_XinWindowPaintNeeds( XinWindow win, XinRect * rct )
{
XinRect r;
r = *rct;
vrct_to_prct( win, &r );
return XinWindowPaintNeeds( win, &r );
}
void
xi_draw_icon( XinWindow win, int x, int y, int rid, XinColor fore_color,
XinColor back_color )
{
if ( rid )
{
XinPoint p;
xi_set_cur_window( win );
p.h = x;
p.v = y;
vpnt_to_ppnt( win, &p );
XinWindowIconDraw( win, p.h, p.v, rid, fore_color, back_color );
}
}
#if XIWS == XIWS_WM
static void
adjust_point( short *p )
{
*p = ( ( *p + 4 ) / 8 ) * 8;
}
#endif
void
xi_draw_rect( XinWindow win, XinRect * rctp )
{
if ( rctp->top >= rctp->bottom || rctp->left >= rctp->right )
return;
{
XinRect r;
#if XIWS == XIWS_WM
XinDrawTools ct;
r = *rctp;
adjust_point( &r.top );
adjust_point( &r.left );
adjust_point( &r.bottom );
adjust_point( &r.right );
xi_set_cur_window( win );
vrct_to_prct( win, &r );
XinWindowDrawToolsGet( win, &ct );
if ( ct.mode == XinDrawModeXor && !xi_is_rect_empty( &r ) )
ct.brush.color = XI_COLOR_BLACK;
if ( ct.brush.pat == XinPatternHollow )
ct.brush.color = ct.back_color;
XinWindowDrawToolsSet( win, &ct );
XinWindowRectDraw( win, &r );
#else
r = *rctp;
xi_set_cur_window( win );
vrct_to_prct( win, &r );
XinWindowRectDraw( win, &r );
#endif
}
}
void
xi_draw_roundrect( XinWindow win, XinRect * rctp, int rh, int rv )
{
if ( rctp->top >= rctp->bottom || rctp->left >= rctp->right )
return;
{
XinRect r;
#if XIWS == XIWS_WM
XinDrawTools ct;
r = *rctp;
adjust_point( &r.top );
adjust_point( &r.left );
adjust_point( &r.bottom );
adjust_point( &r.right );
xi_set_cur_window( win );
vrct_to_prct( win, &r );
XinWindowDrawToolsGet( win, &ct );
if ( ct.mode == XinDrawModeXor && !xi_is_rect_empty( &r ) )
ct.brush.color = XI_COLOR_BLACK;
if ( ct.brush.pat == XinPatternHollow )
ct.brush.color = ct.back_color;
XinWindowDrawToolsSet( win, &ct );
XinWindowRoundRectDraw( win, &r, radius, radius );
#else
r = *rctp;
xi_set_cur_window( win );
vrct_to_prct( win, &r );
XinWindowRoundRectDraw( win, &r, rh, rv );
#endif
}
}
void
xi_move_to( XinWindow win, XinPoint pnt )
{
xi_set_cur_window( win );
vpnt_to_ppnt( win, &pnt );
XinWindowLineMoveTo( win, &pnt );
}
void
xi_draw_line( XinWindow win, XinPoint pnt )
{
xi_set_cur_window( win );
vpnt_to_ppnt( win, &pnt );
XinWindowLineDraw( win, &pnt );
}
static BOOLEAN
xi_is_rect_empty( XinRect * r )
{
BOOLEAN h_empty = ( r->left >= r->right );
BOOLEAN v_empty = ( r->top >= r->bottom );
return h_empty || v_empty;
}
BOOLEAN
xi_rect_intersect( XinRect * rctp, XinRect * rctp1, XinRect * rctp2 )
{
XinRect r,
r2,
*rpnt;
if ( rctp == NULL )
rpnt = &r;
else
rpnt = rctp;
rpnt->left = max( rctp1->left, rctp2->left );
rpnt->top = max( rctp1->top, rctp2->top );
rpnt->right = min( rctp1->right, rctp2->right );
rpnt->bottom = min( rctp1->bottom, rctp2->bottom );
r2 = *rpnt;
return !xi_is_rect_empty( &r2 );
}
/* Functions moved from XI.C because MPW cannot have too much code in one module. */
void
xi_menu_enable( XI_OBJ * itf, int tag, BOOLEAN enable )
{
XI_OBJ *xi_obj;
XinWindow win;
win = xi_get_window( itf );
XinWindowMenuItemEnable( win, ( short ) tag, enable );
xi_obj = xi_get_obj( itf, tag );
if ( xi_obj != NULL && xi_obj->type == XIT_BTN )
{
if ( enable )
xi_set_attrib( xi_obj, xi_get_attrib( xi_obj ) | XI_ATR_ENABLED );
else
xi_set_attrib( xi_obj, xi_get_attrib( xi_obj ) & ~XI_ATR_ENABLED );
}
}
void
xi_set_bitmap( XI_OBJ* xi_obj, XI_BITMAP* bitmap )
{
switch ( xi_obj->type )
{
case XIT_CELL:
if ( !xi_obj->v.cell.is_vert_scrolled )
lm_set_bitmap( xi_obj->parent->v.list->lm, bitmap,
xi_obj->v.cell.row, xi_obj->v.cell.column );
break;
case XIT_BTN:
{
XI_BTN_DATA *bd;
XI_BITMAP* new_bitmap;
bd = xi_obj->v.btn;
new_bitmap = xi_bitmap_copy( bitmap );
xi_bitmap_destroy( bd->up_bitmap );
bd->up_bitmap = new_bitmap;
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &bd->rct );
break;
}
case XIT_COLUMN:
lm_set_column_bitmap( xi_obj->parent->v.list->lm, bitmap, xi_obj->cid );
break;
default:
XinError( 20088, XinSeverityFatal, 0L );
break;
}
}
void
xi_set_down_bitmap( XI_OBJ * xi_obj, XI_BITMAP * bitmap )
{
switch ( xi_obj->type )
{
case XIT_BTN:
{
XI_BTN_DATA *bd;
XI_BITMAP* new_bitmap;
bd = xi_obj->v.btn;
new_bitmap = xi_bitmap_copy( bitmap );
xi_bitmap_destroy( bd->down_bitmap );
bd->down_bitmap = new_bitmap;
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &bd->rct );
break;
}
default:
XinError( 20088, XinSeverityFatal, 0L );
break;
}
}
void
xi_set_icon( XI_OBJ * xi_obj, int icon_rid, int down_icon_rid )
{
switch ( xi_obj->type )
{
case XIT_CELL:
if ( !xi_obj->v.cell.is_vert_scrolled )
lm_set_icon( xi_obj->parent->v.list->lm, icon_rid,
xi_obj->v.cell.row, xi_obj->v.cell.column );
break;
case XIT_BTN:
{
XI_BTN_DATA *bd;
bd = xi_obj->v.btn;
bd->up_icon_rid = icon_rid;
bd->down_icon_rid = down_icon_rid;
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &bd->rct );
break;
}
case XIT_COLUMN:
{
lm_set_column_icon( xi_obj->parent->v.list->lm, icon_rid, xi_obj->cid );
break;
}
default:
XinError( 20088, XinSeverityFatal, 0L );
break;
}
}
XinRect *
xi_get_xi_rct( XI_OBJ * xi_obj, XinRect * xi_rct )
{
int fu_width,
fu_height;
fu_width = xi_get_fu_width( xi_obj );
fu_height = xi_get_fu_height( xi_obj );
switch ( xi_obj->type )
{
case XIT_ITF:
{
XinRect r;
XinWindowRectGet( xi_get_window( xi_obj ), &r );
xi_rct->top = 0;
xi_rct->left = 0;
xi_rct->bottom = ( r.bottom / fu_height ) * XI_FU_MULTIPLE;
xi_rct->right = ( r.right / fu_width ) * XI_FU_MULTIPLE;
return xi_rct;
}
default:
return NULL;
}
}
static void
recalc_metrics( XI_OBJ * xi_obj )
{
int i;
switch ( xi_obj->type )
{
case XIT_ITF:
{
XI_ITF_DATA *itf_data;
itf_data = xi_obj->v.itf;
/* recalculate fu_width and fu_height */
itf_data->fu_height = xi_get_fu_height_font( itf_data->font );
itf_data->fu_width = xi_get_fu_width_font( itf_data->font );
break;
}
case XIT_TEXT:
{
XI_TEXT_DATA *text_data;
text_data = xi_obj->v.text;
text_data->rct = text_data->xi_rct;
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & text_data->rct, 2 );
break;
}
case XIT_RECT:
{
XI_RECT_DATA *rect_data;
rect_data = xi_obj->v.rect;
rect_data->rct = rect_data->xi_rct;
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & rect_data->rct, 2 );
break;
}
case XIT_LINE:
{
XI_LINE_DATA *line_data;
line_data = xi_obj->v.line;
line_data->pnt1 = line_data->xi_pnt1;
line_data->pnt2 = line_data->xi_pnt2;
xi_fu_to_pu( xi_obj->itf, &line_data->pnt1, 1 );
xi_fu_to_pu( xi_obj->itf, &line_data->pnt2, 1 );
break;
}
case XIT_LIST:
lm_recalc_metrics( xi_obj->v.list->lm );
/* TODO recalc sbb_rct, sb_rct, hsb_rct */
break;
case XIT_COLUMN:
break;
case XIT_FIELD:
{
XI_FIELD_DATA *field_data;
int btn_dim_x,
btn_dim_x2,
fu_width,
fu_height,
edit_height,
btn_space;
XinWindow itf_win;
STX_DATA *stxp;
int leading,
ascent,
descent,
font_height;
field_data = xi_obj->v.field;
stxp = ( STX_DATA * ) field_data->stx;
if ( !field_data->font_set )
stxp->font = xi_obj->itf->v.itf->font;
itf_win = xi_get_window( xi_obj->itf );
fu_width = xi_get_fu_width( xi_obj->itf );
fu_height = xi_get_fu_height( xi_obj->itf );
XinWindowFontMap( itf_win, stxp->font );
XinFontMetricsGet( stxp->font, &leading, &ascent, &descent );
font_height = ascent + leading + descent;
edit_height = font_height + ( 2 * EDIT_BORDER_WIDTH_Y ) +
( 2 * EDIT_BORDER_SPACE_Y );
if ( field_data->xi_rct.top || field_data->xi_rct.left ||
field_data->xi_rct.bottom || field_data->xi_rct.right )
{
stxp->rct = field_data->xi_rct;
if ( ( stxp->rct.bottom - stxp->rct.top ) <=
XI_FU_MULTIPLE )
{
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & stxp->rct, 2 );
stxp->rct.bottom = stxp->rct.top + edit_height;
}
else
{
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & stxp->rct, 2 );
stxp->rct.bottom -= BORDER_SPACE_Y;
/* TODO move text edit object */
}
}
else
{
XinPoint p;
XinRect rct;
p = field_data->xi_pnt;
xi_fu_to_pu( xi_obj->itf, &p, 1 );
rct.left = p.h;
rct.top = p.v;
rct.right = p.h + ( field_data->field_width / XI_FU_MULTIPLE ) * fu_width +
2 * BORDER_WIDTH_X + 2 * BORDER_SPACE_X;
rct.bottom = p.v + edit_height;
stxp->rct = rct;
}
btn_dim_x = ( XI_FU_MULTIPLE * fu_height ) / fu_width;
/* btn_dim_x is actual width of button */
#if XIWS != XIWS_WM
/* make buttons 70% wide as high */
btn_dim_x = ( int ) ( ( long ) btn_dim_x * 83L / 100L );
#endif
btn_space = btn_dim_x / 6;
/* btn_dim_x2 is the button width + space, rounded up to the next even
* form unit */
btn_dim_x2 = btn_dim_x + btn_space;
btn_dim_x2 = ( ( btn_dim_x2 + XI_FU_MULTIPLE ) / XI_FU_MULTIPLE ) * XI_FU_MULTIPLE;
if ( !( field_data->xi_rct.top || field_data->xi_rct.bottom ||
field_data->xi_rct.left || field_data->xi_rct.right ) )
{
if ( field_data->button )
{
int leading,
ascent,
descent,
font_height;
XinWindowFontMap( itf_win, stxp->font );
XinFontMetricsGet( stxp->font, &leading, &ascent, &descent );
font_height = ascent + leading + descent;
edit_height = font_height + ( 2 * EDIT_BORDER_WIDTH_Y ) +
( 2 * EDIT_BORDER_SPACE_Y );
field_data->btn_rct.top = field_data->xi_pnt.v;
if ( field_data->button_on_left )
{
field_data->btn_rct.left = field_data->xi_pnt.h;
field_data->btn_rct.right =
field_data->btn_rct.left + btn_dim_x;
}
else
{
#if XIWS == XIWS_WM
BOOLEAN b;
STX_DATA *stxp;
stxp = ( STX_DATA * ) field_data->stx;
b = ( BOOLEAN ) ( stxp->attrib & XI_ATR_BORDER );
field_data->btn_rct.left = stxp->rct.left +
field_data->field_width + ( b ? 24 : 8 );
field_data->btn_rct.right =
field_data->btn_rct.left + 8;
#endif
#if XIWS != XIWS_WM
field_data->btn_rct.right = field_data->xi_pnt.h +
field_data->field_width + btn_dim_x2;
field_data->btn_rct.right = ( ( field_data->btn_rct.right + XI_FU_MULTIPLE )
/ XI_FU_MULTIPLE ) * XI_FU_MULTIPLE;
field_data->btn_rct.left = field_data->btn_rct.right
- btn_dim_x;
#endif
}
}
}
else
{
if ( field_data->button )
{
field_data->btn_rct = field_data->xi_rct;
if ( field_data->button_on_left )
{
field_data->btn_rct.right =
field_data->btn_rct.left + btn_dim_x2;
}
else
{
field_data->btn_rct.left =
field_data->btn_rct.right;
field_data->btn_rct.right += btn_dim_x2;
}
}
}
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & field_data->btn_rct, 2 );
field_data->btn_rct.bottom = field_data->btn_rct.top +
edit_height;
if ( field_data->xi_pnt.h || field_data->xi_pnt.v )
{
field_data->rct.top = field_data->xi_pnt.v;
field_data->rct.left = field_data->xi_pnt.h;
field_data->rct.right = field_data->rct.left +
field_data->field_width;
field_data->rct.bottom = field_data->rct.top +
XI_FU_MULTIPLE;
}
else
field_data->rct = field_data->xi_rct;
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & field_data->rct, 2 );
break;
}
case XIT_BTN:
{
XI_BTN_DATA *btn_data;
if ( xi_obj->parent->type != XIT_CONTAINER )
{
btn_data = xi_obj->v.btn;
btn_data->rct = btn_data->xi_rct;
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & btn_data->rct, 2 );
}
break;
}
case XIT_CONTAINER:
{
XI_CONTAINER_DATA *container_data;
XinPoint p;
int i,
max_len,
len;
XI_OBJ *child;
XI_BTN_TYPE btn_type;
container_data = xi_obj->v.container;
container_data->rct = container_data->xi_rct;
xi_fu_to_pu( xi_obj->itf, ( XinPoint * ) & container_data->rct, 2 );
p.v = container_data->btn_height;
p.h = container_data->btn_width;
xi_fu_to_pu( xi_obj->itf, &p, 1 );
container_data->pix_height = p.v;
container_data->pix_width = p.h;
max_len = 0;
for ( i = 0; i < xi_obj->nbr_children; ++i )
{
child = xi_obj->children[i];
if ( ( len = ( int ) strlen( child->v.btn->text ) ) > max_len )
max_len = len;
}
btn_type = xi_obj->children[0]->v.btn->type;
xi_container_rect_calc( xi_obj, max_len, btn_type );
for ( i = 0; i < xi_obj->nbr_children; ++i )
xi_button_rect_calc( xi_obj->children[i], i );
break;
}
default:
break;
}
for ( i = 0; i < xi_obj->nbr_children; ++i )
recalc_metrics( xi_obj->children[i] );
}
void
xi_set_obj_font( XI_OBJ * xi_obj, XinFont * font )
{
switch ( xi_obj->type )
{
case XIT_ITF:
{
XI_ITF_DATA *itf_data;
itf_data = xi_obj->v.itf;
if ( itf_data->font )
XinFontDestroy( itf_data->font );
if ( font )
XinFontCopy( &itf_data->font, font );
else
itf_data->font = NULL;
recalc_metrics( xi_obj );
xi_invalidate_rect( xi_get_window( xi_obj ), NULL );
break;
}
case XIT_BTN:
{
XinRect rct;
if ( xi_obj->v.btn->font != NULL )
XinFontDestroy( xi_obj->v.btn->font );
XinFontCopy( &xi_obj->v.btn->font, font );
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
break;
}
case XIT_TEXT:
{
XinRect rct;
if ( xi_obj->v.text->font != NULL )
XinFontDestroy( xi_obj->v.text->font );
XinFontCopy( &xi_obj->v.text->font, font );
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
break;
}
case XIT_FIELD:
{
XinRect rct;
stx_set_font( xi_obj->v.field->stx, font );
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
break;
}
case XIT_COLUMN:
{
XI_OBJ *list;
list = xi_obj->parent;
lm_set_font( list->v.list->lm, LM_COLUMN, xi_obj_to_idx( xi_obj ),
0, font );
break;
}
case XIT_CELL:
if ( !xi_obj->v.cell.is_vert_scrolled )
{
XI_OBJ *list;
XinRect rct;
list = xi_obj->parent;
lm_set_font( list->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column, font );
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
}
break;
default:
break;
}
}
void
xi_set_obj_font_id( XI_OBJ * xi_obj, void *font_id )
{
#ifdef XI_USE_XVT
XinFont *font = XinFontXvtConvert( font_id );
xi_set_obj_font( xi_obj, font );
XinFontDestroy( font );
#endif
}
XI_CELL_SPEC *
xi_get_cell_selection( XI_OBJ * list, int *nbr_cellsp )
{
int r,
c,
nbr_rows,
nbr_columns,
nbr_cells,
cnt;
XI_OBJ cell_obj,
row_obj;
XI_LIST_DATA *list_data;
XI_OBJ **members;
int nbr_members;
members = xi_get_member_list( list, &nbr_members );
xi_get_list_info( list, &nbr_rows );
nbr_columns = list->nbr_children;
nbr_cells = 0;
for ( r = 0; r < nbr_rows; ++r )
for ( c = 0; c < nbr_columns; ++c )
{
XI_MAKE_CELL( &cell_obj, list, ( unsigned char ) r, ( unsigned char ) c );
XI_MAKE_ROW( &row_obj, list, ( unsigned char ) r );
if ( ( xi_get_attrib( &cell_obj ) & XI_ATR_SELECTED ) ||
( xi_get_attrib( members[c] ) & XI_ATR_SELECTED ) ||
( xi_get_attrib( &row_obj ) & XI_ATR_SELECTED ) )
++nbr_cells;
}
*nbr_cellsp = nbr_cells;
list_data = list->v.list;
if ( list_data->cell_spec )
list_data->cell_spec = ( XI_CELL_SPEC * ) xi_tree_realloc( list_data->cell_spec,
( size_t ) nbr_cells * sizeof( XI_CELL_SPEC ) );
else
list_data->cell_spec = ( XI_CELL_SPEC * ) xi_tree_malloc(
( size_t ) nbr_cells * sizeof( XI_CELL_SPEC ), list_data );
cnt = 0;
for ( r = 0; r < nbr_rows; ++r )
for ( c = 0; c < nbr_columns; ++c )
{
XI_MAKE_CELL( &cell_obj, list, ( unsigned char ) r, ( unsigned char ) c );
XI_MAKE_ROW( &row_obj, list, ( unsigned char ) r );
if ( ( xi_get_attrib( &cell_obj ) & XI_ATR_SELECTED ) ||
( xi_get_attrib( members[c] ) & XI_ATR_SELECTED ) ||
( xi_get_attrib( &row_obj ) & XI_ATR_SELECTED ) )
{
list_data->cell_spec[cnt].row = r;
list_data->cell_spec[cnt].column = c;
++cnt;
}
}
return list_data->cell_spec;
}
BOOLEAN
xi_is_checked( XI_OBJ * xi_obj )
{
BOOLEAN retval = FALSE;
if ( xi_obj->type == XIT_BTN )
retval = xi_obj->v.btn->checked;
return retval;
}
void
xi_check( XI_OBJ * xi_obj, BOOLEAN check )
{
XinWindow win;
static BOOLEAN inside = FALSE;
XI_BTN_DATA *btn;
if ( check != 0 && check != 1 )
check = 1;
if ( !xi_get_native_controls( xi_obj ) )
if ( xi_is_checked( xi_obj ) == check )
return;
win = xi_obj->itf->v.itf->xin_win;
btn = xi_obj->v.btn;
xi_obj->v.btn->checked = check;
if ( !xi_get_native_controls( xi_obj ) )
{
switch ( btn->type )
{
case XIBT_BUTTON:
xi_invalidate_rect( win, &btn->rct );
break;
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
case XIBT_RADIOBTN:
case XIBT_CHECKBOX:
case XIBT_TABBTN:
{
BOOLEAN enabled,
visible,
focus;
unsigned long attrib;
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 );
if ( btn->drawable || ( btn->type == XIBT_TABBTN && !check ) )
{
XinRect temp = btn->rct;
if ( btn->type == XIBT_TABBTN )
temp.bottom++;
xi_invalidate_rect( win, &temp );
} else
xi_draw_button( xi_obj, &btn->rct, enabled, visible, focus,
btn->down, btn->dflt, btn->checked, TRUE, FALSE );
break;
}
}
}
#ifdef XI_USE_XVT
else
{
switch ( btn->type )
{
case XIBT_CHECKBOX:
XinWindowCheckBox( btn->btnctl, check );
break;
case XIBT_RADIOBTN:
case XIBT_TABBTN:
{
XinWindow wins[MAX_RADIO_BUTTONS];
//XI_BTN_TYPE type;
XI_OBJ *parent;
//type = xi_obj->v.btn->type;
parent = xi_obj->parent;
if ( parent->type == XIT_CONTAINER /* &&
( type == XIBT_RADIOBTN || type == XIBT_TABBTN ) */)
{
if (check)
{
int i;
if ( parent->nbr_children > MAX_RADIO_BUTTONS )
XinError( 20089, XinSeverityFatal, 0L );
for ( i = 0; i < parent->nbr_children; ++i )
wins[i] = parent->children[i]->v.btn->btnctl;
XinWindowCheckRadioButton( btn->btnctl, wins,
parent->nbr_children );
}
//return;
}
else
{
XinWindowCheckBox( btn->btnctl, check );
return;
}
break;
}
default:
break;
}
}
#endif
if ( !inside && xi_obj->parent->type == XIT_CONTAINER &&
( xi_obj->v.btn->type == XIBT_RADIOBTN ||
xi_obj->v.btn->type == XIBT_TABBTN ||
xi_obj->v.btn->type == XIBT_BUTTON_RADIOBTN ) )
{
XI_OBJ **child;
XI_OBJ *parent;
int i;
inside = TRUE;
parent = xi_obj->parent;
child = parent->children;
for ( i = 0, child = parent->children; i < parent->nbr_children;
++i, ++child )
if ( *child != xi_obj )
if ( xi_is_checked( *child ) )
xi_check( *child, FALSE );
inside = FALSE;
}
}
int
xi_obj_to_idx( XI_OBJ * xi_obj )
{
int column_idx;
XI_OBJ **objp;
int n;
n = xi_obj->parent->nbr_children;
objp = xi_obj->parent->children;
for ( column_idx = 0; column_idx < n; objp++, ++column_idx )
{
if ( ( *objp ) == xi_obj )
break;
}
return column_idx;
}
void
xi_set_update_obj( XI_OBJ * xi_obj )
{
/* Check to be sure that the object is visible */
if ( xi_obj != NULL )
{
XinRect obj_r;
XinRect client_r;
XI_OBJ *itf;
itf = xi_obj->itf;
xi_get_rect( xi_obj, &obj_r );
XinWindowRectGet( itf->v.itf->xin_win, &client_r );
XinRectIntersect( &obj_r, &obj_r, &client_r );
if ( XinRectEmpty( &obj_r ) )
xi_obj = NULL;
itf->v.itf->update_obj = xi_obj;
}
}
int
xi_get_visible_rows( XI_OBJ * xi_obj, int *first_vis, int *last_vis )
{
return lm_get_visible_rows( xi_obj->v.list->lm, first_vis, last_vis );
}
void
xi_set_row_height( XI_OBJ * xi_obj, int height )
{
XI_OBJ *list;
list = xi_obj->parent;
lm_set_row_height( list->v.list->lm, xi_obj->v.row, height, TRUE, 0, FALSE );
}
#if 0
long
xi_long_time( void )
{
#if XVT_OS == XVT_OS_DOS
struct time t;
long l;
gettime( &t );
l = t.ti_hund +
t.ti_sec * 100 +
t.ti_min * 6000 +
t.ti_hour * 360000L;
return l;
#endif
}
#endif
void
xi_set_color( XI_OBJ * xi_obj, XI_COLOR_PART part, XinColor color )
{
XinRect rct;
BOOLEAN changed;
changed = FALSE;
switch ( xi_obj->type )
{
case XIT_FIELD:
{
STX_DATA *stxp;
stxp = ( STX_DATA * ) xi_obj->v.field->stx;
switch ( part )
{
case XIC_ENABLED:
changed = ( stxp->enabled_color != color );
stxp->enabled_color = color;
break;
case XIC_BACK:
changed = ( stxp->back_color != color );
stxp->back_color = color;
break;
case XIC_HILIGHT:
changed = ( stxp->hilight_color != color );
stxp->hilight_color = color;
break;
case XIC_ACTIVE:
changed = ( stxp->active_color != color );
stxp->active_color = color;
break;
case XIC_ACTIVE_BACK:
changed = ( stxp->active_back_color != color );
stxp->active_back_color = color;
break;
case XIC_SHADOW:
changed = ( stxp->shadow_color != color );
stxp->shadow_color = color;
break;
case XIC_DISABLED:
changed = ( stxp->disabled_color != color );
stxp->disabled_color = color;
break;
case XIC_DISABLED_BACK:
changed = ( stxp->disabled_back_color != color );
stxp->disabled_back_color = color;
break;
default:
break;
}
if ( changed )
stx_update_colors( xi_obj->v.field->stx );
break;
}
case XIT_CELL:
if ( !xi_obj->v.cell.is_vert_scrolled )
{
LM_CELL_DATA *cell_data;
XI_OBJ *list_obj;
LM_DATA *lmp;
int row = xi_obj->v.cell.row;
int col = xi_obj->v.cell.column;
list_obj = xi_obj->parent;
lmp = ( LM_DATA * ) list_obj->v.list->lm;
cell_data = &lmp->cell_data[row][col];
switch ( part )
{
case XIC_ENABLED:
changed = ( cell_data->color != color );
cell_data->color = color;
break;
case XIC_BACK:
changed = ( cell_data->back_color != color );
cell_data->back_color = color;
break;
default:
break;
}
}
break;
case XIT_ROW:
if ( part == XIC_ENABLED )
lm_set_color( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row,
0, FALSE, color, FALSE );
changed = TRUE;
break;
case XIT_TEXT:
{
XI_TEXT_DATA *xi_td;
xi_td = ( XI_TEXT_DATA * ) xi_obj->v.text;
switch ( part )
{
case XIC_FORE:
case XIC_ENABLED:
changed = ( xi_td->fore_color != color );
xi_td->fore_color = color;
break;
case XIC_BACK:
changed = ( xi_td->back_color != color );
xi_td->back_color = color;
break;
default:
break;
}
break;
}
case XIT_LINE:
{
XI_LINE_DATA *xi_ld;
xi_ld = ( XI_LINE_DATA * ) xi_obj->v.line;
switch ( part )
{
case XIC_FORE:
case XIC_ENABLED:
changed = ( xi_ld->fore_color != color );
xi_ld->fore_color = color;
break;
case XIC_BACK:
changed = ( xi_ld->back_color != color );
xi_ld->back_color = color;
break;
default:
break;
}
break;
}
case XIT_RECT:
{
XI_RECT_DATA *xi_rd;
xi_rd = ( XI_RECT_DATA * ) xi_obj->v.rect;
switch ( part )
{
case XIC_FORE:
case XIC_ENABLED:
changed = ( xi_rd->fore_color != color );
xi_rd->fore_color = color;
break;
case XIC_BACK:
changed = ( xi_rd->back_color != color );
xi_rd->back_color = color;
break;
case XIC_HILIGHT:
changed = ( xi_rd->hilight_color != color );
xi_rd->hilight_color = color;
break;
case XIC_SHADOW:
changed = ( xi_rd->shadow_color != color );
xi_rd->shadow_color = color;
break;
default:
break;
}
break;
}
case XIT_ITF:
{
XI_ITF_DATA *xi_id;
xi_id = ( XI_ITF_DATA * ) xi_obj->v.itf;
if ( part == XIC_BACK )
changed = ( xi_id->back_color != color );
xi_id->back_color = color;
break;
}
case XIT_LIST:
{
LM_DATA *lmp;
lmp = ( LM_DATA * ) xi_obj->v.list->lm;
switch ( part )
{
case XIC_ENABLED:
changed = ( lmp->enabled_color != color );
lmp->enabled_color = color;
break;
case XIC_BACK:
changed = ( lmp->back_color != color );
lmp->back_color = color;
break;
case XIC_ACTIVE:
changed = ( lmp->active_color != color );
lmp->active_color = color;
break;
case XIC_ACTIVE_BACK:
changed = ( lmp->active_back_color != color );
lmp->active_back_color = color;
break;
case XIC_DISABLED:
changed = ( lmp->disabled_color != color );
lmp->disabled_color = color;
break;
case XIC_DISABLED_BACK:
changed = ( lmp->disabled_back_color != color );
lmp->disabled_back_color = color;
break;
case XIC_WHITE_SPACE:
changed = ( lmp->white_space_color != color );
lmp->white_space_color = color;
break;
default:
break;
}
break;
}
default:
break;
}
if ( changed )
{
if ( xi_obj->type == XIT_ITF )
{
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
}
else if ( ( xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE ) != 0 )
{
xi_get_rect( xi_obj, &rct );
/* Returned rectangle does not cause an update for a line. Adjust the
* coordinates so it does. */
if ( xi_obj->type == XIT_LINE )
{
rct.top = rct.top - 1;
rct.bottom = rct.bottom + 1;
}
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
}
}
}
void
xi_cell_request( XI_OBJ * xi_obj )
{
switch ( xi_obj->type )
{
case XIT_LIST:
lm_cell_request( xi_obj->v.list->lm, LM_LIST, 0, 0 );
break;
case XIT_COLUMN:
lm_cell_request( xi_obj->parent->v.list->lm, LM_COLUMN, xi_obj_to_idx( xi_obj ), 0 );
break;
case XIT_ROW:
lm_cell_request( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row, 0 );
break;
case XIT_CELL:
if ( !xi_obj->v.cell.is_vert_scrolled )
lm_cell_request( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column );
break;
default:
break;
}
}
void
xi_get_visible_columns( XI_OBJ * xi_obj, int *first_vis, int *last_vis )
{
lm_get_visible_columns( xi_obj->v.list->lm, first_vis, last_vis );
}
void
xi_set_list_size( XI_OBJ * xi_obj, int height, int width )
{
lm_set_list_size( xi_obj->v.list->lm, height, width );
}
/*---------------------------------------------------------------------
function: xi_container_rect_calc
cnt_obj: container object
max_text_len: longest button text (only used for XI_STACK_HORIZONTAL)
btn_type type of buttons in container
process: Calculate the container size & button positioning parameters
---------------------------------------------------------------------*/
static void
calc_horizontal_stack( XI_OBJ * itf, XI_CONTAINER_DATA * container,
XI_BTN_TYPE btn_type, int max_text_len )
{
int btn_width,
max_width,
horz_spacing,
btn_height = 0;
long horz_form_unit;
long vert_form_unit;
BOOLEAN center = FALSE;
XinRect container_rect;
container_rect = container->rct;
btn_width = max_text_len;
#if XIWS == XIWS_MAC
btn_width *= ( XI_FU_MULTIPLE + 2 );
#elif XIWS == XIWS_WIN
if ( xi_get_pref( XI_PREF_NATIVE_CTRLS ) )
btn_width *= ( XI_FU_MULTIPLE + 2 );
else
btn_width *= XI_FU_MULTIPLE;
#else
btn_width *= XI_FU_MULTIPLE;
#endif
horz_form_unit = xi_get_fu_width( itf );
vert_form_unit = xi_get_fu_height( itf );
btn_width += ( int ) xi_get_pref( XI_PREF_BUTTON_PAD );
#if 0
/* old tabs */
if ( btn_type == XIBT_TABBTN )
btn_width += ( int ) xi_get_pref( XI_PREF_BUTTON_PAD ) / 2;
#endif
/* convert to pixels */
btn_width = ( int ) ( ( btn_width * horz_form_unit ) / XI_FU_MULTIPLE );
if ( container->packed || btn_type == XIBT_TABBTN )
horz_spacing = 0;
else if ( ( horz_spacing = ( int ) xi_get_pref( XI_PREF_HORZ_PIXEL_SPACING ) )
== 0 )
horz_spacing = ( short ) ( ( xi_get_pref( XI_PREF_HORZ_SPACING )
* horz_form_unit ) / XI_FU_MULTIPLE );
/* If pix_width is larger, use it */
if ( container->pix_width > btn_width )
btn_width = container->pix_width;
/* figure out if maximum width is too wide, and if so, truncate */
max_width = ( ( container_rect.right - container_rect.left ) -
( container->nbr_buttons - 1 ) * horz_spacing ) / container->nbr_buttons;
if ( btn_width > max_width )
btn_width = max_width;
switch ( btn_type )
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
if ( container->pix_height )
btn_height = container->pix_height;
else
btn_height = ( int ) ( ( xi_get_pref( XI_PREF_BUTTON_HEIGHT ) * vert_form_unit )
/ XI_FU_MULTIPLE );
center = TRUE;
break;
case XIBT_TABBTN:
btn_height = container_rect.bottom - container_rect.top;
center = FALSE;
break;
case XIBT_CHECKBOX:
case XIBT_RADIOBTN:
btn_height = ( int ) vert_form_unit;
center = TRUE;
break;
}
if ( center == TRUE )
{
container_rect.top += ( container_rect.bottom - container_rect.top
- btn_height ) / 2;
container_rect.bottom = container_rect.top + btn_height;
}
container->rct = container_rect;
container->nbr_across = container->nbr_buttons;
container->nbr_down = 1;
container->pix_width = btn_width;
container->pix_height = btn_height;
container->step_across = btn_width + horz_spacing;
container->step_down = 0;
}
static void
calc_vertical_stack( XI_OBJ * itf, XI_CONTAINER_DATA * container,
XI_BTN_TYPE btn_type )
{
int btn_height,
max_height,
top_ofst = 0,
vert_spacing = 0;
XinRect container_rect;
long vert_form_unit;
vert_form_unit = xi_get_fu_height( itf );
container_rect = container->rct;
switch ( 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 )
* vert_form_unit ) / XI_FU_MULTIPLE );
top_ofst = vert_spacing / 2;
break;
case XIBT_CHECKBOX:
case XIBT_RADIOBTN:
vert_spacing = 0;
top_ofst = 0;
break;
default:
break;
}
if ( container->pix_height )
btn_height = container->pix_height;
else
btn_height = ( int ) ( ( xi_get_pref( XI_PREF_BUTTON_HEIGHT ) * vert_form_unit )
/ XI_FU_MULTIPLE );
max_height = ( container_rect.bottom - container_rect.top - top_ofst
- ( ( container->nbr_buttons - 1 ) * vert_spacing ) ) / container->nbr_buttons;
switch ( btn_type )
{
case XIBT_CHECKBOX:
case XIBT_RADIOBTN:
btn_height = ( int ) vert_form_unit;
break;
default:
break;
}
if ( btn_height > max_height )
btn_height = max_height;
if ( btn_height < vert_form_unit )
XinError( 20014, XinSeverityFatal, 0L );
container_rect.top += top_ofst;
container->rct = container_rect;
container->nbr_across = 1;
container->nbr_down = container->nbr_buttons;
if ( container->pix_width == 0 )
container->pix_width = container->rct.right - container->rct.left;
container->pix_height = btn_height;
container->step_across = 0;
container->step_down = btn_height + vert_spacing;
}
static void
calc_grid( XI_OBJ * itf, XI_CONTAINER_DATA * container )
{
int hz_pix_space,
vt_pix_space,
slack;
XinPoint pnt;
XinRect container_rect;
container_rect = container->rct;
if ( !( ( container->btn_width > 0 ) || ( container->btn_height > 0 ) ) )
XinError( 30208, XinSeverityFatal, 0L );
if ( container->pix_height == 0 || container->pix_width == 0 )
{
pnt.v = container->btn_height;
pnt.h = container->btn_width;
xi_fu_to_pu( itf, &pnt, 1 );
if ( ( pnt.v == 0 ) || ( pnt.h == 0 ) )
{
/* make it so that pnt.h and pnt.v are the same */
if ( pnt.v == 0 )
pnt.v = pnt.h;
if ( pnt.h == 0 )
pnt.h = pnt.v;
}
container->pix_height = pnt.v;
container->pix_width = pnt.h;
}
if ( container->pix_height > container_rect.bottom - container_rect.top )
XinError( 20032, XinSeverityFatal, 0L );
if ( container->pix_width > container_rect.right - container_rect.left )
XinError( 20033, XinSeverityFatal, 0L );
pnt.v = XI_FU_MULTIPLE;
xi_fu_to_pu( itf, &pnt, 1 );
if ( ( container->pix_height < pnt.v ) )
XinError( 20034, XinSeverityFatal, 0L );
if ( container->packed == TRUE )
{
/* note that if not native, the space is NEGATIVE */
vt_pix_space = ( ( BOOLEAN ) xi_get_pref( XI_PREF_NATIVE_CTRLS ) )
? 0 : -( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH );
hz_pix_space = vt_pix_space;
}
else
{
pnt.v = ( int ) xi_get_pref( XI_PREF_VERT_SPACING );
pnt.h = ( int ) xi_get_pref( XI_PREF_HORZ_SPACING );
xi_fu_to_pu( itf, &pnt, 1 );
vt_pix_space = pnt.v;
hz_pix_space = pnt.h;
}
container->step_down = container->pix_height + vt_pix_space;
container->step_across = container->pix_width + hz_pix_space;
if ( container->orientation == XI_GRID_HORIZONTAL )
{
container->nbr_across = ( container_rect.right - container_rect.left
+ hz_pix_space ) / container->step_across;
container->nbr_down = 1 + ( container->nbr_buttons - 1 )
/ container->nbr_across;
slack = ( container_rect.bottom - container_rect.top + vt_pix_space )
- ( container->nbr_down * container->step_down );
}
else
{
container->nbr_down = ( container_rect.bottom - container_rect.top
+ vt_pix_space ) / container->step_down;
container->nbr_across = 1 + ( container->nbr_buttons - 1 )
/ container->nbr_down;
slack = ( container_rect.right - container_rect.left + hz_pix_space )
- ( container->nbr_across * container->step_across );
}
if ( slack < 0 )
XinError( 20035, XinSeverityFatal, 0L );
}
void
xi_container_rect_calc( XI_OBJ * cnt_obj, int max_text_len,
XI_BTN_TYPE btn_type )
{
XI_CONTAINER_DATA *container;
container = cnt_obj->v.container;
if ( container->rct.left == 0 && container->rct.top == 0
&& container->rct.bottom == 0 && container->rct.right == 0 )
{
XinRect rect;
rect = container->xi_rct;
xi_fu_to_pu( cnt_obj->itf, ( XinPoint * ) & rect, 2 );
container->rct = rect;
}
switch ( container->orientation )
{
case XI_STACK_HORIZONTAL:
calc_horizontal_stack( cnt_obj->itf, container, btn_type, max_text_len );
break;
case XI_STACK_VERTICAL:
calc_vertical_stack( cnt_obj->itf, container, btn_type );
break;
case XI_GRID_HORIZONTAL:
case XI_GRID_VERTICAL:
calc_grid( cnt_obj->itf, container );
break;
}
}
/*---------------------------------------------------------------------
function: xi_button_rect_calc
btn_obj: Button object (with data structure complete except for rct)
sequence: button sequence within parent (used for contained buttons only)
process: Calculate the button rectangle size, either from the
container information or the xi rectangle.
---------------------------------------------------------------------*/
void
xi_button_rect_calc( XI_OBJ * btn_obj, int sequence )
{
XinRect rct;
BOOLEAN packed = FALSE; /* button has no dflt or focus rects */
if ( btn_obj->parent->type == XIT_CONTAINER )
{
int row,
col;
XI_CONTAINER_DATA *cdata;
cdata = btn_obj->parent->v.container;
switch ( cdata->orientation )
{
case XI_STACK_HORIZONTAL:
row = 0;
col = sequence;
packed = FALSE;
break;
case XI_STACK_VERTICAL:
row = sequence;
col = 0;
packed = FALSE;
break;
case XI_GRID_HORIZONTAL:
row = sequence / cdata->nbr_across;
col = sequence - row * cdata->nbr_across;
packed = cdata->packed;
break;
case XI_GRID_VERTICAL:
col = sequence / cdata->nbr_down;
row = sequence - col * cdata->nbr_down;
packed = cdata->packed;
break;
default:
row = col = 0;
break;
}
rct.top = cdata->rct.top + row * cdata->step_down;
rct.left = cdata->rct.left + col * cdata->step_across;
rct.bottom = rct.top + cdata->pix_height;
rct.right = rct.left + cdata->pix_width;
}
else
{
rct = btn_obj->v.btn->rct;
if ( rct.left == 0 && rct.top == 0 && rct.bottom == 0 && rct.right == 0 )
{
rct = btn_obj->v.btn->xi_rct;
xi_fu_to_pu( btn_obj->itf, ( XinPoint * ) & rct, 2 );
}
if ( rct.top == rct.bottom )
{
/* use default height */
rct.bottom = rct.top + ( int ) xi_get_pref( XI_PREF_BUTTON_HEIGHT );
}
packed = FALSE;
}
btn_obj->v.btn->rct = rct;
btn_obj->v.btn->packed = packed;
}
/*---------------------------------------------------------------------
function: xi_container_reorient
cnt_obj: The EXISTING container object
cnt_def: A revised definition of the container:
XI_RCT xi_rct; new rectangle, if empty, use old
XI_CONTAINER_ORIENTATION orientation; new value
int tab_cid; NOT USED
short btn_width; for grids, new value in form units
short btn_height; for grids, new value in form units
BOOLEAN packed; new value
process: change the container position, orientation, etc.
---------------------------------------------------------------------*/
void
xi_container_reorient( XI_OBJ * cnt_obj, XI_CONTAINER_DEF * cnt_def )
{
int i,
len,
max_len;
XI_CONTAINER_DATA *cdata;
if ( cnt_obj->type != XIT_CONTAINER )
XinError( 20036, XinSeverityFatal, 0L );
cdata = cnt_obj->v.container;
xi_invalidate_rect( xi_get_window( cnt_obj->itf ), &cdata->rct );
if ( ( cnt_def->xi_rct.bottom > cnt_def->xi_rct.top )
|| ( cnt_def->xi_rct.right > cnt_def->xi_rct.left ) )
cdata->xi_rct = cnt_def->xi_rct;
cdata->rct = cnt_def->pixel_rect;
cdata->orientation = cnt_def->orientation;
cdata->btn_height = cnt_def->btn_height;
cdata->btn_width = cnt_def->btn_width;
cdata->packed = cnt_def->packed;
max_len = 0;
for ( i = 0; i < cnt_obj->nbr_children; ++i )
{
if ( ( len = ( int ) strlen( cnt_obj->children[i]->v.btn->text ) ) > max_len )
max_len = len;
}
xi_container_rect_calc( cnt_obj, max_len, cnt_obj->children[0]->v.btn->type );
for ( i = 0; i < cnt_obj->nbr_children; ++i )
{
xi_button_rect_calc( cnt_obj->children[i], i );
}
xi_invalidate_rect( xi_get_window( cnt_obj->itf ), &cdata->rct );
}
/*--------------------------------------------------------------------------*/
/* xi_def_get_font */
/*--------------------------------------------------------------------------*/
XinFont *
xi_def_get_font( XI_OBJ_DEF * obj_def )
{
XinFont *font = NULL;
if ( !obj_def )
{
XinFontCopy( &font, xi_get_system_font( ) );
return font;
}
switch ( obj_def->type )
{
case XIT_FIELD:
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
{
XinFontCopy( &font, obj_def->v.field->font );
}
#ifdef XI_USE_XVT
else
{
if ( obj_def->v.field->font_id != NULL )
font = XinFontXvtConvert( obj_def->v.field->font_id );
}
#endif
break;
case XIT_TEXT:
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
{
XinFontCopy( &font, obj_def->v.text->font );
}
#ifdef XI_USE_XVT
else
{
if ( obj_def->v.text->font_id != NULL )
font = XinFontXvtConvert( obj_def->v.text->font_id );
}
#endif
break;
case XIT_LIST:
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
{
XinFontCopy( &font, obj_def->v.list->font );
}
#ifdef XI_USE_XVT
else
{
if ( obj_def->v.list->font_id != NULL )
font = XinFontXvtConvert( obj_def->v.list->font_id );
}
#endif
break;
case XIT_ITF:
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
{
XinFontCopy( &font, obj_def->v.itf->font );
}
#ifdef XI_USE_XVT
else
{
if ( obj_def->v.itf->font_id != NULL )
font = XinFontXvtConvert( obj_def->v.itf->font_id );
}
#endif
break;
default:
break;
}
if ( font != NULL )
return font;
return xi_def_get_font( obj_def->parent );
}
/*--------------------------------------------------------------------------*/
/* xi_get_xil_pref */
/*--------------------------------------------------------------------------*/
BOOLEAN
xi_get_xil_pref( XI_OBJ * obj )
{
assert( obj->type == XIT_ITF );
if ( obj->v.itf->use_xil_win )
return TRUE;
return ( BOOLEAN ) xi_get_pref( XI_PREF_XIL );
}
BOOLEAN
xi_def_get_xil_pref( XI_OBJ_DEF * obj_def )
{
if ( obj_def != 0 )
{
assert( obj_def->type == XIT_ITF );
if ( obj_def->v.itf->use_xil_win )
return TRUE;
}
return ( BOOLEAN ) xi_get_pref( XI_PREF_XIL );
}
BOOLEAN
xi_pt_in_rect( XinRect * rct, XinPoint pnt )
{
return ( pnt.h >= rct->left &&
pnt.h < rct->right &&
pnt.v >= rct->top &&
pnt.v < rct->bottom );
}
void
xi_draw_text( XinWindow win, XinFont * font, int x, int y, char *string, int len )
{
xi_set_cur_window( win );
x -= cur_delta_x;
y -= cur_delta_y;
#if XIWS == XIWS_WM
y -= 8;
{
DRAW_CTOOLS ct;
XinWindowDrawToolsGet( win, &ct );
if ( ct.mode == M_XOR )
XinWindowDrawModeSet( win, M_COPY );
}
#endif
XinWindowTextDraw( win, font, x, y, string, len );
}
void
xi_caret_on( XinWindow win, int x, int y, int height, XinRect * clip_rect )
{
XI_ITF_DATA *itf_data;
XinPoint p;
XinRect local_clip;
XinDrawTools dt;
itf_data = xi_get_itf( win )->v.itf;
#ifdef XI_USE_TX_SUPPORT
if ( itf_data->caret_is_on )
{
XinWindowCaretOff( win );
}
#endif
itf_data->caret_x = x;
itf_data->caret_y = y;
itf_data->caret_height = height;
itf_data->caret_is_on = TRUE;
itf_data->caret_clip = *clip_rect;
p.h = x;
p.v = y;
vpnt_to_ppnt( win, &p );
x = p.h;
y = p.v;
local_clip = *clip_rect;
vrct_to_prct( win, &local_clip );
XinWindowDrawToolsGet( win, &dt );
XinWindowCaretOn( win, x, y, height, dt.text_back_color, &local_clip );
}
void
xi_set_clip( XinWindow win, XinRect * rctp )
{
XinRect r;
if ( rctp )
{
r = *rctp;
vrct_to_prct( win, &r );
if ( r.right <= r.left )
r.right = r.left + 1;
if ( r.top > r.bottom )
r.top = r.bottom;
XinWindowClipSet( win, &r );
}
else
XinWindowClipSet( win, NULL );
}
char *
xi_get_text_string( char *src, unsigned long attrib )
{
static char buf[256] = { 0 };
int len = strlen( src );
len = min( len, sizeof( buf ) - 1 );
if ( attrib & XI_ATR_PASSWORD )
memset( buf, ( char ) xi_get_pref( XI_PREF_PASSWORD_CHAR ), len );
else
gstrncpy( buf, src, len );
buf[len] = '\0';
return buf;
}
BOOLEAN
xi_cr_is_ok( XI_OBJ * xi_obj )
{
if ( xi_obj == NULL )
return FALSE;
switch ( xi_obj->type )
{
case XIT_FIELD:
return stx_cr_is_ok( xi_obj->v.field->stx );
case XIT_CELL:
return lm_cr_is_ok( xi_obj->parent->v.list->lm, xi_obj->v.cell.row, xi_obj->v.cell.column,
xi_obj->v.cell.is_vert_scrolled );
case XIT_BTN:
return TRUE;
default:
return FALSE;
}
}
void
xi_draw_dotted_rect( XinWindow win, XinRect * rctp )
{
/* Commented by Guy: do not remove
XinPoint p1,
p2,
p3,
p4;
p1.v = rctp->top + 1;
for ( p1.h = rctp->left + 1; p1.h < rctp->right - 1; p1.h += 2 )
{
p2 = p1;
++p2.h;
xi_move_to( win, p1 );
xi_draw_line( win, p2 );
p3 = p1;
p3.v = rctp->bottom - 1;
p4 = p3;
++p4.h;
xi_move_to( win, p3 );
xi_draw_line( win, p4 );
}
p1.h = rctp->left;
for ( p1.v = rctp->top + 2; p1.v < rctp->bottom - 1; p1.v += 2 )
{
p2 = p1;
++p2.v;
xi_move_to( win, p1 );
xi_draw_line( win, p2 );
p3 = p1;
p3.h = rctp->right - 1;
p4 = p3;
++p4.v;
xi_move_to( win, p3 );
xi_draw_line( win, p4 );
}
*/
XinWindowDottedRectDraw(win, rctp);
}
BOOLEAN
xi_focus_obj_is_cell_button( XI_OBJ * focus_obj )
{
if ( focus_obj->type != XIT_CELL )
return FALSE;
return lm_is_button_full_cell( focus_obj->parent->v.list->lm, focus_obj->v.cell.row,
focus_obj->v.cell.column );
}
void
xi_draw_foc_and_dflt_if_necessary( XI_OBJ * focus_obj, XI_OBJ * next_obj )
{
int focus_obj_cr_ok,
next_obj_cr_ok;
focus_obj_cr_ok = xi_cr_is_ok( focus_obj );
next_obj_cr_ok = xi_cr_is_ok( next_obj );
if ( focus_obj_cr_ok != next_obj_cr_ok )
xi_draw_foc_and_dflt( focus_obj->itf );
}
BOOLEAN
xi_get_native_controls( XI_OBJ * obj )
{
if ( obj != NULL && obj->type == XIT_BTN )
{
switch ( obj->v.btn->draw_as )
{
case XIBT_EMULATED:
return FALSE;
case XIBT_NATIVE:
return TRUE;
default:
break;
}
}
return ( BOOLEAN ) xi_get_pref( XI_PREF_NATIVE_CTRLS );
}
#ifdef XI_USE_TX_SUPPORT
void
xi_caret_off( XinWindow win )
{
XI_ITF_DATA *itf_data;
itf_data = xi_get_itf( win )->v.itf;
if ( itf_data->caret_is_on )
{
itf_data->caret_is_on = FALSE;
XinWindowCaretOff( win );
}
}
#endif
BOOLEAN
xi_get_obj_by_pointer( XI_OBJ * parent, XI_OBJ * target )
{
XI_OBJ **objlist;
int n;
if ( parent == target )
return ( TRUE );
switch ( parent->type )
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
return ( FALSE );
default:
break;
}
/* search in child list */
objlist = xi_get_member_list( parent, &n );
for ( ; n > 0; n--, objlist++ )
{
/* call recursively for generality in future versions */
if ( xi_get_obj_by_pointer( *objlist, target ))
return ( TRUE );
}
return ( FALSE );
}
BOOLEAN
xi_is_obj( XI_OBJ* obj, XI_OBJ* itf )
{
/*
if (!xi_is_itf( itf ))
return FALSE;
return xi_get_obj_by_pointer( itf, obj );
*/
return xi_is_itf(itf) && xi_get_obj_by_pointer(itf, obj);
}