campo-sirio/xi/xiutils.c

4344 lines
108 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 "xiextend.h"
#include "xi.h"
#include "xiutils.h"
#include "xitext.h"
#include "xistx.h"
#include "xilm.h"
#if XIWS == WINWS
#include "dos.h"
#endif
#if XVT_OS == XVT_OS_CTOS
#define STX_VERT_FUDGE ((npctos_env == CHSERVICE) ? 0 : 6)
#define BORDER_WIDTH ((npctos_env == CHSERVICE) ? 8 : 2)
#define EDIT_BORDER_WIDTH_Y ((npctos_env == CHSERVICE) ? 0 : 1)
#define EDIT_BORDER_SPACE_Y ((npctos_env == CHSERVICE) ? 0 : 1)
#define BORDER_WIDTH_X ((npctos_env == CHSERVICE) ? 8 : 1)
#define BORDER_WIDTH_Y ((npctos_env == CHSERVICE) ? 0 : 1)
#define BORDER_SPACE_X ((npctos_env == CHSERVICE) ? 0 : 1)
#define BORDER_SPACE_Y ((npctos_env == CHSERVICE) ? 0 : 1)
#else
#if XIWS == WMWS
#define STX_VERT_FUDGE 0
#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
#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
#endif
#define MAX_RADIO_BUTTONS 30
CBRUSH ltgray_cbrush = {
PAT_SOLID, COLOR_LTGRAY };
CBRUSH gray_cbrush = {
PAT_SOLID, COLOR_GRAY };
CBRUSH hollow_cbrush = {
PAT_HOLLOW, COLOR_WHITE };
FONT_OBJ xi_sysfont;
#if (XIWS != GRWS) || (XVT_CC != XVT_CC_MS70)
CPEN hollow_cpen = {
0, PAT_HOLLOW, P_SOLID, COLOR_WHITE };
CPEN black_cpen = {
1, PAT_SOLID, P_SOLID, COLOR_BLACK };
CPEN rubber_cpen = {
1, PAT_RUBBER, P_DASH, COLOR_BLACK };
CBRUSH white_cbrush = {
PAT_SOLID, COLOR_WHITE };
#endif
/* added following lines for 386 port of dgr */
#if XIWS == GRWS
CPEN hollow_cpen = {
0, PAT_HOLLOW, P_SOLID, COLOR_WHITE };
CPEN black_cpen = {
1, PAT_SOLID, P_SOLID, COLOR_BLACK };
CPEN rubber_cpen = {
1, PAT_RUBBER, P_DASH, COLOR_BLACK };
CBRUSH white_cbrush = {
PAT_SOLID, COLOR_WHITE };
#endif
static WINDOW 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 */
K_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 */
#if XVT_OS == XVT_OS_CTOS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
12, /* 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 */
24, /* XI_PREF_ITF_MIN_TOP */
8, /* XI_PREF_ITF_MIN_LEFT */
FALSE, /* XI_PREF_XIL */
FALSE, /* XI_PREF_ASSERT_ON_NULL_CID */
#else
#if XIWS == WMWS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
COLOR_GRAY, /* XI_PREF_COLOR_DARK */
TRUE, /* 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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#elif XIWS == PMWS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#elif XIWS == GRWS
2, /* XI_PREF_COLUMN_OFFSET */
0, /* XI_PREF_SB_OFFSET */
12, /* XI_PREF_SB_WIDTH */
12, /* 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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
COLOR_GRAY, /* XI_PREF_COLOR_DARK */
FALSE, /* 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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
COLOR_GRAY, /* XI_PREF_COLOR_DISABLED */
#elif XIWS == MACWS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#elif XIWS == XOLWS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_GRAY, /* XI_PREF_COLOR_CTRL */
COLOR_DKGRAY, /* XI_PREF_COLOR_DARK */
FALSE, /* 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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#elif XIWS == MTFWS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#elif XIWS == WINWS
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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
COLOR_GRAY, /* XI_PREF_COLOR_DARK */
FALSE, /* XI_PREF_OPTIMIZE_CELL_REQUESTS */
1, /* XI_PREF_CARET_WIDTH */
500, /* XI_PREF_TRIPLE_CLICK_TIME */
K_DOWN | XI_MOD_CONTROL, /* 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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#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 */
COLOR_WHITE, /* XI_PREF_COLOR_LIGHT */
COLOR_LTGRAY, /* XI_PREF_COLOR_CTRL */
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 */
K_F3, /* XI_PREF_ITF_TAB_CHAR */
K_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 */
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 */
#endif
#endif
};
RCT big_clip = {
0, 0, 10000, 10000 };
static void xi_caret_suspend(WINDOW win);
static void xi_caret_restore(WINDOW win);
#if XIWS == WMWS
void
xi_fix_color(COLOR *color)
{
if (*color == COLOR_BLACK)
*color = COLOR_WHITE;
else
if (*color == COLOR_WHITE)
*color = COLOR_BLACK;
}
#endif
char *
tgstrncpy(char *dst, char *src, int n)
{
gstrncpy(dst, src, n);
dst[n - 1] = '\0';
return(dst);
}
char *
gstrncpy(char *dst, char *src, int n)
{
char *p = dst;
while (n > 0 && *src != 0)
{
*p++ = *src++;
n--;
}
if (n != 0)
*p++ = '\0';
return(dst);
}
void
order_ints(int *ip1, int *ip2)
{
int temp;
if (*ip1 > *ip2)
{
temp = *ip1;
*ip1 = *ip2;
*ip2 = temp;
}
}
RCT *
xi_inflate_rect(RCT *rct, int amount)
{
rct->bottom += amount;
rct->right += amount;
rct->left -= amount;
rct->top -= amount;
return(rct);
}
static void
xi_offset_rect(RCT *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);
}
}
XVT_FNTID
xi_create_copy_font_id(XI_OBJ *itf, XVT_FNTID font_id, XVT_FNTID old_font_id)
{
int i, j;
XVT_FNTID copy_font_id;
XI_ITF_DATA *itf_data;
BOOLEAN found = FALSE;
itf_data = itf->v.itf;
if (old_font_id)
{
for (i = 0; i < itf_data->nbr_font_ids; ++i)
{
if (itf_data->font_ids[i] == old_font_id)
{
found = TRUE;
break;
}
}
if (found)
{
if (font_compare(old_font_id, itf_data->font_ids[i]))
return old_font_id;
xvt_font_destroy(font_id);
if (i < itf_data->nbr_font_ids)
{
for (j = i; j < itf_data->nbr_font_ids - 1; ++j)
itf_data->font_ids[j] = itf_data->font_ids[j + 1];
itf_data->nbr_font_ids--;
xi_realloc_array((void **)&itf_data->font_ids, itf_data->nbr_font_ids,
sizeof(XVT_FNTID), itf_data);
}
}
}
copy_font_id = xvt_font_create();
xvt_font_copy(copy_font_id, font_id, (unsigned long)XVT_FA_ALL);
itf_data->nbr_font_ids++;
xi_realloc_array((void **)&itf_data->font_ids, itf_data->nbr_font_ids,
sizeof(XVT_FNTID), itf_data);
itf_data->font_ids[itf_data->nbr_font_ids - 1] = copy_font_id;
return copy_font_id;
}
void
xi_free_font_id(XI_OBJ *itf, XVT_FNTID font_id)
{
XI_ITF_DATA *itf_data;
int i, j;
itf_data = itf->v.itf;
for (i = 0; i < itf_data->nbr_font_ids; ++i)
if (itf_data->font_ids[i] == font_id)
break;
xvt_font_destroy(font_id);
if (i < itf_data->nbr_font_ids)
{
for (j = i; j < itf_data->nbr_font_ids - 1; ++j)
itf_data->font_ids[j] = itf_data->font_ids[j + 1];
itf_data->nbr_font_ids--;
xi_realloc_array((void **)&itf_data->font_ids, itf_data->nbr_font_ids,
sizeof(XVT_FNTID), itf_data);
}
}
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;
WINDOW 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;
xvt_sbar_set_pos(win, VSCROLL, 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;
xvt_sbar_set_pos(win, HSCROLL, ps);
}
void
xi_get_hsb_rect(XI_OBJ *xi_obj, RCT *rctp)
{
XI_LIST_DATA *list_data;
LM_DATA *lmp;
RCT rct1, rct3;
XI_OBJ * *members;
int nbr_members;
#if (XIWS == WINWS) || (XIWS == GRWS)
RCT 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 == WINWS) || (XIWS == GRWS)
if (list_data->hsb_win)
xvt_vobj_get_client_rect(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 XI_IS_NOT_CH
CTOS_IS_PM;
rct3.top = rct1.bottom - 1;
rct3.right = lmp->rct.left + lmp->pixel_width + 2 * BORDER_WIDTH;
CTOS_END;
#endif
#if XI_IS_CH
CTOS_IS_CH;
rct3.top = rct1.bottom;
rct3.right = lmp->rct.left + lmp->pixel_width;
CTOS_END;
#endif
rct3.bottom = rct3.top + (int)xi_get_pref(XI_PREF_SB_HEIGHT);
#if (XIWS == WINWS) || (XIWS == GRWS)
if (list_data->hsb_win)
rct3.bottom = rct3.top + r.bottom;
#endif
*rctp = rct3;
list_data->hsb_rct = rct3;
list_data->have_hsb_rct = TRUE;
}
void
xi_get_sb_rect(XI_OBJ *xi_obj, RCT *rctp)
{
RCT rct;
int offset, width;
XI_LIST_DATA *list_data;
LM_DATA *lmp;
#if (XIWS == WINWS) || (XIWS == GRWS)
RCT 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 == WINWS) || (XIWS == GRWS)
if (list_data->sb_win)
xvt_vobj_get_client_rect(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 XI_IS_NOT_CH
CTOS_IS_PM;
if (list_data->width)
rct.left = rct.left + lmp->pixel_width + offset + 2 * BORDER_WIDTH - 1;
else
rct.left = rct.right + offset - 1;
CTOS_END;
#endif
#if XI_IS_CH
CTOS_IS_CH;
if (list_data->width)
rct.left = rct.left + lmp->pixel_width + offset;
else
rct.left = rct.right + offset;
CTOS_END;
#endif
rct.right = rct.left + width;
#if (XIWS == WINWS) || (XIWS == GRWS)
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 == WINWS) || (XIWS == GRWS)
if (list_data->sb_win)
list_data->sbb_rct.right = list_data->sbb_rct.left + r.right;
#endif
#if XI_IS_CH
CTOS_IS_CH;
rct.top = lm_data->pix_row1_top;
CTOS_END;
#endif
#if XI_IS_NOT_CH
CTOS_IS_PM;
rct.top = list_data->sbb_rct.bottom;
CTOS_END;
#endif
}
*rctp = rct;
list_data->sb_rct = rct;
list_data->have_sb_rct = TRUE;
}
void
xi_move_list_scroll_bar(XI_OBJ *xi_obj)
{
RCT rct;
WINDOW win = xi_obj->itf->v.itf->xvt_win;
WINDOW 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->xvt_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)
xvt_vobj_move(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)
{
RCT rct;
WINDOW 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)
xvt_vobj_move(hsb_win, &rct);
}
BOOLEAN
xi_half_baked(WINDOW win)
{
XI_OBJ *itf;
itf = xi_get_itf(win);
if (itf)
return itf->v.itf->half_baked;
return FALSE;
}
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()
{
#if XIWS == MTFWS
clean_primesel();
#endif
xvt_font_destroy(xi_sysfont);
}
long
xi_get_pref(XI_PREF_TYPE pref_type)
{
long pref;
pref = xi_preferences[pref_type];
#if XVT_OS == XVT_OS_CTOS
CTOS_IS_CH;
switch (pref_type)
{
case XI_PREF_COLUMN_OFFSET:
pref = 0;
break;
case XI_PREF_SB_OFFSET:
pref = 0;
break;
case XI_PREF_SB_WIDTH:
pref = 8;
break;
case XI_PREF_SB_HEIGHT:
pref = 8;
break;
case XI_PREF_BUTTON_HEIGHT:
pref = 24;
break;
case XI_PREF_BUTTON_PAD:
pref = 32;
break;
case XI_PREF_HORZ_SPACING:
pref = 16;
break;
case XI_PREF_VERT_SPACING:
pref = 0;
break;
case XI_PREF_VERT_PIXEL_SPACING:
case XI_PREF_HORZ_PIXEL_SPACING:
pref = 0;
break;
case XI_PREF_ITF_MIN_TOP:
pref = 16;
break;
}
CTOS_END;
#endif
return pref;
}
void xi_set_pref(XI_PREF_TYPE preftype, long value)
{
xi_preferences[preftype] = value;
}
void
xi_set_font_id(XVT_FNTID font_id)
{
font_set = TRUE;
xi_sysfont = xvt_font_create();
xvt_font_copy(xi_sysfont, font_id, (unsigned long)XVT_FA_ALL);
}
void
xi_init_sysvals(void)
{
static RCT rct =
{
-1000,
-1000,
-900,
-900
};
WINDOW win;
int ascent, descent, leading, height;
if (! font_set)
{
xi_sysfont = xvt_font_create();
xvt_font_set_family(xi_sysfont, XVT_FFN_HELVETICA);
xvt_font_set_size(xi_sysfont, 9);
}
/*
Determine height and average width of chosen font.
We do this by creating an invisible window and selecting the font
into it and getting its metrics.
*/
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
xvt_font_map(xi_sysfont, win);
xvt_dwin_set_font(win, xi_sysfont);
xvt_font_get_metrics(xi_sysfont, &leading, &ascent, &descent);
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,
xi_xvt_get_text_width(win,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", -1) / 52);
xi_set_sysval(XI_SV_SYSFONT_HEIGHT, height);
xvt_vobj_destroy(win);
}
/*
xi_get_enclosing_rect - get the enclosing rectangle of two other rectangles.
ENTRY - src1, src2 are the rects of interest.
EXIT - dst is set to the enclosing rect and returned.
If is OK for dst to equal one of the sources.
*/
RCT *
xi_get_enclosing_rect(RCT *dst, RCT *src1, RCT *src2)
{
RCT rct;
rct.top = min(src1->top, src2->top);
rct.left = min(src1->left, src2->left);
rct.bottom = max(src1->bottom, src2->bottom);
rct.right = max(src1->right, src2->right);
*dst = rct;
return(dst);
}
void
xi_fu_to_pu(XI_OBJ *itf, PNT *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, PNT *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(WINDOW win, 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] = XI_PASSWORD_CHAR;
buf[1] = '\0';
pw_size = xi_xvt_get_text_width(win, buf, 1);
return (pw_size * len);
}
else
return(xi_xvt_get_text_width(win, s, len));
}
void
xi_draw_clipped_text(WINDOW win, char *s, RCT *bound_rctp,
RCT *clip_rctp, unsigned long attrib, BOOLEAN set_the_cpen,
int rule_and_space, int str_len)
{
int ascent, descent, leading, wid;
char buf[256];
int len;
int baseline;
RCT tmp_rct;
if (! (attrib & XI_ATR_VISIBLE))
return;
xi_get_font_metrics(win, &leading, &ascent, &descent);
tmp_rct = *clip_rctp;
/* Adjust bottom so border is not overwritten */
tmp_rct.bottom = tmp_rct.bottom - BORDER_WIDTH;
xi_set_clip(win, &tmp_rct);
NOREF( set_the_cpen );
/*
TODO ?????
if (set_the_cpen)
xi_set_cpen(win, &black_cpen);
*/
len = strlen(s);
len = min(len, sizeof(buf) - 1);
if (attrib & XI_ATR_PASSWORD)
memset(buf, XI_PASSWORD_CHAR, len);
else
gstrncpy(buf, s, len);
buf[len] = '\0';
#if XI_IS_CH
CTOS_IS_CH;
NOREF(rule_and_space);
baseline = bound_rctp->top + 8;
CTOS_END;
#endif
#if XI_IS_NOT_CH
CTOS_IS_PM;
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;
CTOS_END;
#endif
if (attrib & XI_ATR_RJUST)
{
wid = xi_xvt_get_text_width(win, buf, -1);
xi_draw_text(win, bound_rctp->right - wid, baseline, buf, str_len);
}
else
{
if (attrib & XI_ATR_HCENTER)
{
int x;
wid = xi_xvt_get_text_width(win, 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, x, baseline, buf, str_len);
}
else
xi_draw_text(win, bound_rctp->left, baseline, buf, str_len);
}
xi_set_clip(win, (RCT *)NULL);
}
void
xi_draw_text_attrib(WINDOW win, int x, int y, char *s, int len, unsigned long attrib)
{
char buf[256];
if (! (attrib & XI_ATR_VISIBLE))
return;
if (len == -1)
len = strlen(s);
len = min(len, sizeof(buf) - 1);
if (attrib & XI_ATR_PASSWORD)
memset(buf, XI_PASSWORD_CHAR, len);
else
gstrncpy(buf, s, len);
buf[len] = '\0';
#if 0
#if XIWS == PMWS
/* Nasty hack for OS2, because OS2 doesn't draw LTGRAY rectangles
correctly, but does if you draw opaque spaces with LTGRAY
back color */
#define BUFSZ 200
{
char s[BUFSZ], *sp;
int i;
for (i = 0, sp = s; i < BUFSZ; ++i, ++sp)
*sp = ' ';
s[BUFSZ - 1] = '\0';
xi_draw_text(win, x, y, s, -1);
}
#endif
#endif
xi_draw_text(win, x, y, buf, -1);
}
void
xi_draw_3d_rect(WINDOW win, RCT *rctp, BOOLEAN well, int height, COLOR color_light, COLOR color_ctrl, COLOR color_dark)
{
RCT rct;
PNT pnt, pnt2;
CPEN cpen;
CBRUSH 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;
xi_set_draw_mode(win, M_COPY);
/* draw upper left lines */
cpen.color = well ? color_dark : color_light;
xi_set_cpen(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.color = well ? color_light : color_dark;
xi_set_cpen(win, &cpen);
pnt.h = rct.left;
pnt.v = rct.bottom - 1;
xi_move_to(win, pnt);
pnt2.h = rct.right;
pnt2.v = pnt.v;
xi_draw_line(win, pnt2);
if (height == 2)
{
pnt.h++;
pnt.v--;
xi_move_to(win, pnt);
pnt2.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--;
pnt.v++;
xi_move_to(win, pnt);
pnt2.h = pnt.h;
pnt2.v = rct.bottom;
xi_draw_line(win, pnt2);
}
xi_set_cpen(win, &hollow_cpen);
cbrush = white_cbrush;
cbrush.color = color_ctrl;
xi_set_cbrush(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--;
}
#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, rctp->left, rctp->top, " ", -1);
}
#endif
xi_draw_rect(win, &rct);
}
void
xi_draw_3d_line(WINDOW win, PNT pnt1, PNT pnt2, BOOLEAN well)
{
COLOR color_light, color_dark;
PNT pnt1x, pnt2x;
CPEN cpen;
color_light = xi_get_pref(XI_PREF_COLOR_LIGHT);
color_dark = xi_get_pref(XI_PREF_COLOR_DARK);
cpen = black_cpen;
xi_set_draw_mode(win, M_COPY);
cpen.color = well ? color_dark : color_light;
xi_set_cpen(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.color = well ? color_light : color_dark;
xi_set_cpen(win, &cpen);
xi_move_to(win, pnt1x);
xi_draw_line(win, pnt2x);
}
void
xi_draw_thick_rect(WINDOW win, RCT *rctp, int width)
{
RCT 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(WINDOW win, RCT *rctp, BOOLEAN well, BOOLEAN black, BOOLEAN fill,
COLOR color)
{
PNT pnt1, pnt2;
int half_width, width;
RCT rct;
COLOR color_light, color_ctrl, color_dark;
CPEN 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.color = well ? color_dark : color_light;
if (black)
cpen.color = COLOR_BLACK;
if (color)
cpen.color = color;
xi_set_cpen(win, &cpen);
xi_set_draw_mode(win, M_COPY);
/* 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.color = well ? color_light : color_dark;
if (black)
cpen.color = COLOR_BLACK;
if (color)
cpen.color = color;
xi_set_cpen(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;
PNT pnt1, pnt2;
v1 = rct.top + half_width - 1;
v2 = rct.top + half_width;
cpen.color = color_ctrl;
xi_set_cpen(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(WINDOW win, RCT *rctp, BOOLEAN well, BOOLEAN black, int height,
COLOR color)
{
RCT 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;
}
}
char *
gmemmove(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;
}
#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 != WMWS
void
dbg_rct(char *tag, RCT *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_get_font_metrics(WINDOW win, int *leadingp, int *ascentp, int *descentp)
{
xvt_dwin_get_font_metrics(win, leadingp, ascentp, descentp);
#if XVTWS == WINWS
if (*leadingp == 0)
{
*leadingp = 2;
*ascentp -= 2;
}
#endif
}
void
xi_set_xvt_font(WINDOW win, FONT_OBJ *fontp, BOOLEAN scale)
{
NOREF(scale);
/* xvt_font_map(*fontp, win); this causes GPF in XVT, even though it is valid */
xvt_dwin_set_font(win, *fontp);
}
void
xi_set_cur_window(WINDOW 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_set_draw_ctools(WINDOW win, DRAW_CTOOLS *ct)
{
xvt_dwin_set_draw_ctools(win, ct);
#if XIWS == WMWS
{
DRAW_CTOOLS lct;
lct = *ct;
xi_fix_color(&lct.pen.color);
xi_fix_color(&lct.brush.color);
xi_fix_color(&lct.back_color);
xi_fix_color(&lct.fore_color);
xvt_dwin_set_draw_ctools(win, &lct);
}
#else
xvt_dwin_set_draw_ctools(win, ct);
#endif
}
void
xi_set_draw_mode(WINDOW win, DRAW_MODE mode)
{
xvt_dwin_set_draw_mode(win, mode);
}
void
xi_set_cbrush(WINDOW win, CBRUSH *cbrush)
{
#if XIWS == WMWS
{
CBRUSH lcbrush;
lcbrush = *cbrush;
xi_fix_color(&lcbrush.color);
xvt_dwin_set_cbrush(win, &lcbrush);
}
#else
xvt_dwin_set_cbrush(win, cbrush);
#endif
}
void
xi_set_cpen(WINDOW win, CPEN *cpen)
{
#if XIWS == WMWS
{
CPEN lcpen;
lcpen = *cpen;
xi_fix_color(&lcpen.color);
xvt_dwin_set_cpen(win, &lcpen);
}
#else
xvt_dwin_set_cpen(win, cpen);
#endif
}
void
xi_set_xvt_back_color(WINDOW win, COLOR color)
{
#if XIWS == WMWS
xi_fix_color(&color);
#endif
xvt_dwin_set_back_color(win, color);
}
void
xi_set_xvt_fore_color(WINDOW win, COLOR color)
{
xvt_dwin_set_fore_color(win, color);
}
DRAW_CTOOLS *
xi_get_draw_ctools(WINDOW win, DRAW_CTOOLS *ct)
{
return xvt_dwin_get_draw_ctools(win, ct);
}
void
xi_dbg(char *buf)
{
xvt_debug_printf(buf);
}
WINDOW xi_new_child_window(RCT *rctp, char *title, WIN_TYPE t,
BOOLEAN ctl_size, BOOLEAN ctl_vscroll, BOOLEAN ctl_hscroll,
BOOLEAN ctl_close, BOOLEAN ctl_iconized, BOOLEAN ctl_iconizable,
WINDOW parent, long app_data, short reserve1,
long reserve2, BOOLEAN visible, BOOLEAN enabled, int menu_bar_rid)
{
long flags;
WINDOW win;
NOREF(reserve1);
NOREF(reserve2);
if (! parent)
#if (XIWS != XOLWS)
parent = TASK_WIN;
#else
parent = SCREEN_WIN;
#endif
flags = (ctl_size ? WSF_SIZE : 0) |
(ctl_close ? WSF_CLOSE : 0) |
(ctl_iconized ? WSF_ICONIZED : 0) |
(ctl_iconizable ? WSF_ICONIZABLE : 0) |
(ctl_hscroll ? WSF_HSCROLL : 0) |
(ctl_vscroll ? WSF_VSCROLL : 0) |
(visible ? 0 : WSF_INVISIBLE) |
(enabled ? 0 : WSF_DISABLED) |
(menu_bar_rid ? 0 : WSF_NO_MENUBAR);
win = xvt_win_create(t, rctp, title, menu_bar_rid, parent, flags, EM_ALL,
(EVENT_HANDLER)xi_event, app_data);
xvt_errmsg_sig_if(!(win), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20090",
20090, "xvt_win_create returned NULL");
xvt_vobj_set_attr(NULL_WIN, ATTR_SUPPRESS_UPDATE_CHECK, (long)TRUE);
return win;
}
void
xi_terminate(void)
{
xvt_app_destroy();
}
int
xi_xvt_get_text_width(WINDOW win, char *string, int len)
{
return xvt_dwin_get_text_width(win, string, len);
}
void xi_even_fu(int *f)
{
*f = (*f * XI_FU_MULTIPLE + XI_FU_MULTIPLE / 2) / XI_FU_MULTIPLE;
}
void xi_even_fu_pnt(PNT *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_sysfont);
}
int
xi_get_fu_height(XI_OBJ *itf)
{
if (itf)
return itf->v.itf->fu_height;
else
return xi_get_fu_height_font(&xi_sysfont);
}
int
xi_get_fu_width_font(FONT_OBJ *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(FONT_OBJ *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(FONT_OBJ *font, PNT *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--;
}
}
#define FONT_ATTR_SIZE 256 /* family or native_desc size */
/*
The following font comparison routine is not general
purpose, it does not properly handle the case where one
of the compared fonts has the native descriptor and the
other one does not.
This does not matter in case of xi, where we compare
if an (unmapped) font matches an already mapped one,
and thus native descriptor is only important when
both fonts have it set.
*/
BOOLEAN font_compare ( XVT_FNTID f1, XVT_FNTID f2 ) {
char buf1[FONT_ATTR_SIZE];
char buf2[FONT_ATTR_SIZE];
if (f1 == f2)
return TRUE;
/* If both font have valid native descs, compare those */
if ( xvt_font_get_native_desc(f1, buf1, FONT_ATTR_SIZE) &&
xvt_font_get_native_desc(f2, buf2, FONT_ATTR_SIZE)) {
if ( *buf1 && *buf2 )
return ( strncmp(buf1, buf2, FONT_ATTR_SIZE ) == 0 );
}
/* If one of the fonts lacks nd, compare portable attrs */
if ( xvt_font_get_style(f1) != xvt_font_get_style(f2) )
return FALSE;
if ( xvt_font_get_size (f1) != xvt_font_get_size (f2) )
return FALSE;
if ( !xvt_font_get_family( f1, buf1, FONT_ATTR_SIZE ))
return FALSE;
if ( !xvt_font_get_family( f2, buf2, FONT_ATTR_SIZE ))
return FALSE;
return ( strncmp(buf1, buf2, FONT_ATTR_SIZE ) == 0 );
}
void
xi_get_font_metrics_font(FONT_OBJ *font, int *leading,
int *ascent, int *descent, int *char_width)
{
typedef struct
{
XVT_FNTID font_id;
int leading;
int ascent;
int descent;
int char_width;
} FONT_INFO;
static FONT_INFO *font_info, *fi;
static int font_info_cnt = 0;
int i;
WINDOW win;
BOOLEAN close_win = FALSE;
for (i = 0, fi = font_info; i < font_info_cnt; ++i, ++fi)
{
if (font_compare(fi->font_id, *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];
fi->font_id = xvt_font_create();
xvt_font_copy(fi->font_id, *font, (unsigned long)XVT_FA_ALL);
/* Remove this code because we can't assume that a window with focus is
drawable - it could be a dialog. Create a dummy window in all cases.
win = xvt_scr_get_focus_vobj();
if (! win || win == TASK_WIN)
*/
{
RCT rct;
rct.top = -200;
rct.left = -200;
rct.bottom = -100;
rct.right = -100;
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
close_win = TRUE;
}
xi_set_xvt_font(win, font, FALSE);
{
int tl, ta, td;
xi_get_font_metrics(win, &tl, &ta, &td);
fi->leading = tl;
fi->ascent = ta;
fi->descent = td;
}
fi->char_width = xi_xvt_get_text_width(win, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", -
1) / 52;
if (close_win)
xvt_vobj_destroy(win);
*leading = fi->leading;
*ascent = fi->ascent;
*descent = fi->descent;
*char_width = fi->char_width;
}
/********************************************************************/
/* FUNCTIONS THAT NEED TRANSPOSING */
static void
ppnt_to_vpnt(WINDOW win, PNT *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(WINDOW win, PNT *pnt)
{
XI_ITF_DATA *itf_data;
itf_data = (xi_get_itf(win))->v.itf;
pnt->h -= itf_data->delta_x;
pnt->v -= itf_data->delta_y;
}
#define VPNT_TO_PPNT(pp) \
(pp)->h -= cur_delta_x; \
(pp)->v -= cur_delta_y;
static void
vrct_to_prct(WINDOW win, RCT *rct)
{
XI_ITF_DATA *itf_data;
itf_data = (xi_get_itf(win))->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;
}
#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;
static void move_tx_edit( XI_OBJ* xi_obj )
{
TXEDIT text_edit;
XI_ITF_DATA* itf_data;
RCT rect;
RCT new_rect;
WINDOW window;
text_edit = xi_get_txedit( xi_obj );
if (text_edit == BAD_TXEDIT)
return;
window = xvt_tx_get_win( text_edit );
itf_data = xi_obj->itf->v.itf;
xvt_tx_get_rect( text_edit , &rect);
stx_get_inside_rect( xi_obj->v.field->stx, &new_rect );
xi_offset_rect(&new_rect, itf_data->delta_x, itf_data->delta_y);
xvt_tx_move(text_edit, &new_rect );
xi_inflate_rect(&new_rect, 1);
xvt_dwin_invalidate_rect(window, &new_rect);
xi_inflate_rect(&rect, 1);
xvt_dwin_invalidate_rect(window, &rect);
}
static void move_xvt_controls(XI_OBJ *xi_obj )
{
XI_OBJ * *objlist;
int n;
RCT rct;
switch (xi_obj->type)
{
case XIT_ITF:
if (! xi_obj->v.itf->half_baked)
xvt_dwin_update(xi_obj->v.itf->xvt_win);
break;
case XIT_FIELD:
move_tx_edit( xi_obj );
break;
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);
xvt_vobj_move(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);
xvt_vobj_move(list_data->hsb_win, &rct);
}
break;
}
case XIT_BTN:
{
RCT 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);
xvt_vobj_move(btn_data->btnctl, &rct);
}
break;
}
}
objlist = xi_get_member_list(xi_obj, &n);
for (; n > 0; n--, objlist++)
move_xvt_controls(*objlist );
if (xi_obj->type == XIT_ITF)
xi_set_clip(xi_obj->v.itf->xvt_win, NULL);
}
void
xi_adjust_sb_vir_itf(WINDOW win, XI_OBJ *itf)
{
RCT rct;
XI_ITF_DATA *itf_data;
itf_data = itf->v.itf;
xvt_vobj_get_client_rect(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)
{
PNT 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)
xvt_dwin_invalidate_rect(win, NULL);
move_xvt_controls( itf );
xi_caret_restore(win);
}
set_sb_positions(itf);
}
BOOLEAN
xi_eh(WINDOW win, EVENT *ep)
{
switch (ep->type)
{
case E_UPDATE:
update_pending = FALSE;
xi_set_cur_window(win);
break;
case E_CHAR:
if (update_pending && (ep->v.chr.ch == K_UP || ep->v.chr.ch == K_DOWN))
return FALSE;
break;
case E_SIZE:
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
RCT rct;
itf = xi_get_itf(win);
if (! itf)
break;
itf_data = itf->v.itf;
if (itf_data->size_font_to_win)
{
RCT old_win_rct;
int bottom, right;
XVT_FNTID *itf_font_id;
xvt_vobj_get_client_rect(win, &rct);
old_win_rct = itf->v.itf->original_win_rct;
bottom = old_win_rct.bottom;
right = old_win_rct.right;
itf_font_id = itf_data->font;
if (itf_font_id)
{
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;
xvt_font_set_size(*itf_font_id, point_size2 - 1);
xi_set_obj_font_id(itf, *itf_font_id);
}
break;
}
if (itf_data->virtual_itf)
xi_adjust_sb_vir_itf(win, itf);
break;
}
case E_MOUSE_DOWN:
case E_MOUSE_UP:
case E_MOUSE_DBL:
case E_MOUSE_MOVE:
ppnt_to_vpnt(win, &ep->v.mouse.where);
break;
case E_HSCROLL:
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
int delta_x, 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.what)
{
case SC_LINE_UP:
delta_x = -4 * XI_FU_MULTIPLE;
break;
case SC_LINE_DOWN:
delta_x = 4 * XI_FU_MULTIPLE;
break;
case SC_PAGE_UP:
delta_x = -10 * XI_FU_MULTIPLE;
break;
case SC_PAGE_DOWN:
delta_x = 10 * XI_FU_MULTIPLE;
break;
case SC_THUMB:
{
int oldp, newp;
oldp = itf_data->phys_xi_pnt.h;
newp = (int)((long)ep->v.scroll.pos *
((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 SC_THUMBTRACK:
delta_x = 0;
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)
{
RCT client_rct;
PNT pnt;
xvt_dwin_update(win);
xvt_vobj_get_client_rect(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;
#if XIWS == WMWS
/*
Hack for *VERY* nasty bug in XVT/CH - need to call
xvt_dwin_set_clip twice, to make XVT/CH have no clipping region
for xvt_dwin_scroll_rect.
*/
{
RCT rct;
rct = client_rct;
xi_inflate_rect(&rct, 120);
xi_set_clip(win, &rct);
xi_set_clip(win, NULL);
}
#endif
xvt_dwin_scroll_rect(win, &client_rct, -pnt.h, 0);
set_sb_positions(itf);
move_xvt_controls(itf );
do_vir_pan_event(itf, pnt.h, 0, FALSE);
xi_caret_restore(win);
}
break;
}
case E_VSCROLL:
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
int delta_y, 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.what)
{
case SC_LINE_UP:
delta_y = -XI_FU_MULTIPLE;
break;
case SC_LINE_DOWN:
delta_y = XI_FU_MULTIPLE;
break;
case SC_PAGE_UP:
delta_y = -10 * XI_FU_MULTIPLE;
break;
case SC_PAGE_DOWN:
delta_y = 10 * XI_FU_MULTIPLE;
break;
case SC_THUMB:
{
int oldp, newp;
oldp = itf_data->phys_xi_pnt.v;
newp = (int)((long)ep->v.scroll.pos *
((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 SC_THUMBTRACK:
delta_y = 0;
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)
{
RCT client_rct;
PNT pnt;
xvt_dwin_update(win);
xvt_vobj_get_client_rect(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;
#if XIWS == WMWS
{
RCT rct;
rct = client_rct;
rct.bottom += 24;
xi_set_clip(win, &rct);
xi_set_clip(win, NULL);
}
#endif
xvt_dwin_scroll_rect(win, &client_rct, 0, -pnt.v);
set_sb_positions(itf);
move_xvt_controls(itf );
do_vir_pan_event(itf, 0, pnt.v, FALSE);
xi_caret_restore(win);
}
break;
}
}
return TRUE;
}
void
xi_vir_pan(XI_OBJ *itf, int delta_x, int delta_y)
{
RCT cr;
WINDOW win;
XI_ITF_DATA *itf_data;
PNT pf, p;
int old;
pf.h = delta_x;
pf.v = delta_y;
itf_data = itf->v.itf;
win = xi_get_window(itf);
xvt_vobj_get_client_rect(win, &cr);
xvt_dwin_update(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;
#if XIWS == WMWS
{
RCT rct;
rct = cr;
rct.bottom += 24;
xi_set_clip(win, &cr);
xi_set_clip(win, NULL);
}
#endif
xvt_dwin_scroll_rect(win, &cr, -p.h, -p.v);
set_sb_positions(itf);
move_xvt_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)
{
RCT or, cr, cr2;
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
WINDOW win;
int dt, db, dl, dr, dh, dv;
PNT 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;
}
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);
xvt_vobj_get_client_rect(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)
{
xvt_dwin_update(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;
#if XIWS == WMWS
{
RCT rct;
xvt_vobj_get_client_rect(win, &rct);
rct.bottom += 24;
xi_set_clip(win, &rct);
xi_set_clip(win, NULL);
}
#endif
xvt_dwin_scroll_rect(win, &cr, -p.h, -p.v);
set_sb_positions(itf);
move_xvt_controls(itf);
do_vir_pan_event(itf, p.h, p.v, FALSE);
xi_caret_restore(win);
}
}
WINDOW
xi_new_control(RCT *lrctp, char *title, WIN_TYPE t, WINDOW parent,
BOOLEAN visible, int id, char *templat)
{
long ctl_flags;
RCT r;
r = *lrctp;
vrct_to_prct(parent, &r);
NOREF(templat);
ctl_flags = (visible ? 0 : CTL_FLAG_INVISIBLE);
return xvt_ctl_create(t, &r, title, parent, ctl_flags, 0L, id);
}
void
xi_scroll_rect(WINDOW win, RCT *rctp, int dh, int dv)
{
RCT r;
xi_set_cur_window(win);
r = *rctp;
VRCT_TO_PRCT(&r);
update_pending = TRUE;
#if 0
{
HWND hwnd;
RECT rect;
rect.left = r.left;
rect.top = r.top;
rect.right = r.right;
rect.bottom = r.bottom;
hwnd = xvt_vobj_get_attr(win, ATTR_NATIVE_WINDOW);
ScrollWindow(hwnd, dh, dv, &rect, &rect);
}
#endif
#if XIWS == WMWS
NOREF(dh);
NOREF(dv);
xvt_dwin_invalidate_rect(win, &r);
#else
xvt_dwin_set_clip(win, &r);
xvt_dwin_scroll_rect(win, &r, dh, dv);
#endif
}
void
xi_draw_text(WINDOW win, int x, int y, char *string, int len)
{
xi_set_cur_window(win);
x -= cur_delta_x;
y -= cur_delta_y;
#if XIWS == WMWS
y -= 8;
{
DRAW_CTOOLS ct;
xvt_dwin_get_draw_ctools(win, &ct);
if (ct.mode == M_XOR)
xvt_dwin_set_draw_mode(win, M_COPY);
}
#endif
xvt_dwin_draw_text(win, x, y, string, len);
}
void
xi_set_clip(WINDOW win, RCT *rctp)
{
RCT 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;
xvt_dwin_set_clip(win, &r);
}
else
xvt_dwin_set_clip(win, NULL);
}
void
xi_caret_on(WINDOW win, int x, int y, int height)
{
XI_ITF_DATA *itf_data;
PNT p;
itf_data = xi_get_itf(win)->v.itf;
if (itf_data->caret_is_on)
{
xvt_win_set_caret_visible(win, FALSE );
}
xvt_win_set_caret_size(win, (int)xi_get_pref(XI_PREF_CARET_WIDTH), height);
itf_data->caret_x = x;
itf_data->caret_y = y;
itf_data->caret_height = height;
itf_data->caret_is_on = TRUE;
p.h = x;
p.v = y;
vpnt_to_ppnt(win, &p);
x = p.h;
y = p.v;
xvt_win_set_caret_pos(win, p);
xvt_win_set_caret_visible(win, TRUE);
}
void
xi_caret_off(WINDOW 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;
#if XVTWS == WINWS
{ PNT _p; _p.h = -100; _p.v = -100;
xvt_win_set_caret_pos(win, _p);
xvt_win_set_caret_visible(win, TRUE); };
#endif
xvt_win_set_caret_visible(win, FALSE );
}
}
static void
xi_caret_suspend(WINDOW win)
{
XI_ITF_DATA *itf_data;
itf_data = xi_get_itf(win)->v.itf;
if (itf_data->caret_is_on)
{
xvt_win_set_caret_visible(win, FALSE );
}
}
static void
xi_caret_restore(WINDOW win)
{
XI_ITF_DATA *itf_data;
PNT p;
itf_data = xi_get_itf(win)->v.itf;
if (itf_data->caret_is_on)
{
int leading, ascent, descent, x, y;
p.h = itf_data->caret_x;
p.v = itf_data->caret_y;
/* This patches a bug in the caret position in XVT/WIN */
#if XIWS == WINWS
xvt_dwin_get_font_metrics( win, &leading, &ascent, &descent );
p.v -= itf_data->caret_height - (leading + ascent + descent );
#endif
vpnt_to_ppnt(win, &p);
x = p.h;
y = p.v;
#if XIWS == GRWS
++x;
#endif
{ PNT _p; _p.h = x; _p.v = y;
xvt_win_set_caret_pos(win, _p);
xvt_win_set_caret_visible(win, TRUE); };
xvt_win_set_caret_size(win, (int)xi_get_pref(XI_PREF_CARET_WIDTH), itf_data->caret_height);
}
}
#if XI_IS_CH
void
xi_coalesce_invalidates(XI_OBJ *itf, BOOLEAN coalesce)
{
XI_ITF_DATA *itf_data;
CTOS_IS_CH;
itf_data = itf->v.itf;
if (coalesce)
{
if (! itf_data->coalescing)
{
itf_data->inv_rct.top = SHRT_MAX;
itf_data->inv_rct.left = SHRT_MAX;
itf_data->inv_rct.bottom = 0;
itf_data->inv_rct.right = 0;
itf_data->invalidated = FALSE;
}
++itf_data->coalescing;
}
else
{
--itf_data->coalescing;
if (! itf_data->coalescing && itf_data->invalidated)
xvt_dwin_invalidate_rect(itf_data->xvt_win, &itf_data->inv_rct);
}
CTOS_END;
}
#endif
void
xi_invalidate_rect(WINDOW win, RCT *rct)
{
RCT r, cr, dr;
#if XI_IS_CH
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
#endif
if (rct != NULL && (rct->top >= rct->bottom || rct->left >= rct->right))
return;
#if XI_IS_CH
CTOS_IS_CH;
itf = xi_get_itf(win);
if (itf)
{
itf_data = itf->v.itf;
if (itf_data->coalescing)
{
itf_data->invalidated = TRUE;
xi_get_enclosing_rect(&itf_data->inv_rct, &itf_data->inv_rct, rct);
return;
}
}
CTOS_END;
#endif
if (! rct)
{
xvt_dwin_invalidate_rect(win, NULL);
return;
}
r = *rct;
vrct_to_prct(win, &r);
xvt_vobj_get_client_rect(win, &cr);
if (xi_rect_intersect(&dr, &r, &cr))
{
update_pending = TRUE;
xvt_dwin_invalidate_rect(win, &r);
}
}
BOOLEAN xi_needs_update(WINDOW win, RCT *rct)
{
RCT r;
r = *rct;
vrct_to_prct(win, &r);
return xvt_dwin_is_update_needed(win, &r);
}
void
xi_draw_icon(WINDOW win, int x, int y, int rid, COLOR fore_color,
COLOR back_color)
{
#if XIWS == PMWS
DRAW_CTOOLS save_ctools;
#endif
#if XVTWS == WMWS
NOREF(x);
NOREF(y);
NOREF(rid);
#endif
NOREF(fore_color);
NOREF(back_color);
xi_set_cur_window(win);
#if XI_IS_CH
return;
#else
x -= cur_delta_x;
y -= cur_delta_y;
#if (XIWS == MTFWS) || (XIWS == MACWS)
if (fore_color)
xvt_dwin_set_fore_color(win, fore_color);
if (back_color)
xvt_dwin_set_back_color(win, back_color);
#endif
#if XIWS == PMWS
{
DRAW_CTOOLS new_ctools;
new_ctools.pen.width = 1;
new_ctools.pen.color = COLOR_BLACK;
new_ctools.pen.pat = PAT_SOLID;
new_ctools.pen.style = P_SOLID;
new_ctools.brush.pat = PAT_SOLID;
new_ctools.brush.color = COLOR_BLACK;
new_ctools.mode = M_COPY;
new_ctools.opaque_text = TRUE;
new_ctools.fore_color = fore_color;
new_ctools.back_color = back_color;
xvt_dwin_get_draw_ctools(win, &save_ctools);
xvt_dwin_set_draw_ctools(win, &new_ctools);
{
RCT r;
r.top = y;
r.left = x;
r.bottom = y + 1;
r.right = x + 1;
xvt_dwin_draw_rect(win, &r);
}
}
#endif
if (rid)
xvt_dwin_draw_icon(win, x, y, rid);
#if XIWS == PMWS
xvt_dwin_set_draw_ctools(win, &save_ctools);
#endif
#endif
}
#if XIWS == WMWS
static void
adjust_point(short *p)
{
*p = ((*p + 4) / 8) * 8;
}
#endif
void
xi_draw_rect(WINDOW win, RCT *rctp)
{
if (rctp->top >= rctp->bottom || rctp->left >= rctp->right)
return;
{
#if XVT_OS == XVT_OS_CTOS
{
RCT r;
xi_set_cur_window(win);
CTOS_IS_CH;
r = *rctp;
VRCT_TO_PRCT(&r);
draw_rect(&r);
CTOS_END;
}
{
RCT rct;
DRAW_CTOOLS ct;
RCT r;
xi_set_cur_window(win);
CTOS_IS_PM;
r = *rctp;
VRCT_TO_PRCT(&r);
xi_get_draw_ctools(win, &ct);
rct = r;
if (ct.mode == M_XOR || ct.brush.pat == PAT_SOLID)
xvt_dwin_draw_rect(win, &rct);
else
{
rct.top++;
rct.right--;
xvt_dwin_draw_rect(win, &rct);
}
CTOS_END;
}
#else /* XVT_OS_CTOS */
#if XIWS == WMWS
DRAW_CTOOLS ct;
RCT r;
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(&r);
xi_get_draw_ctools(win, &ct);
if (ct.mode == M_XOR && ! xvt_rect_is_empty(&r))
ct.brush.color = COLOR_BLACK;
if (ct.brush.pat == PAT_HOLLOW)
ct.brush.color = ct.back_color;
xvt_dwin_set_draw_ctools(win, &ct);
xvt_dwin_draw_rect(win, &r);
#else /* WMWS */
/************************************* XM *****************************/
#if (XIWS == MTFWS) || (XIWS == PMWS) || (XIWS == XOLWS)
RCT rct;
DRAW_CTOOLS ct;
#endif /* (XIWS == MTFWS) || (XIWS == PMWS) || (XIWS == XOLWS) */
RCT r;
r = *rctp;
xi_set_cur_window(win);
VRCT_TO_PRCT(&r);
#if (XIWS == MTFWS) || (XIWS == XOLWS)
xi_get_draw_ctools(win, &ct);
rct = r;
if (ct.mode == M_XOR || ct.brush.pat == PAT_SOLID)
xvt_dwin_draw_rect(win, &rct);
else
{
xvt_dwin_draw_rect(win, &rct);
}
#endif /* MTFWS || XOLWS */
/************************************* PM *****************************/
#if XIWS == PMWS
xi_get_draw_ctools(win, &ct);
rct = r;
if (ct.mode == M_XOR || ct.brush.pat == PAT_SOLID)
xvt_dwin_draw_rect(win, &rct);
else
{
xvt_dwin_draw_rect(win, &rct);
}
#endif /* PMWS */
#if (XIWS != MTFWS) && (XIWS != PMWS) && (XIWS != XOLWS)
xvt_dwin_draw_rect(win, &r);
#endif /* MTFWS || PMWS || XOLWS */
#endif /* WMWS */
#endif /* XVT_OS_CTOS */
}
}
static PNT move_to_pnt;
void
xi_move_to(WINDOW win, PNT pnt)
{
NOREF(win);
VPNT_TO_PPNT(&pnt);
move_to_pnt = pnt;
}
void
xi_draw_line(WINDOW win, PNT pnt)
{
PNT mpnt, mtp;
xi_set_cur_window(win);
VPNT_TO_PPNT(&pnt);
mpnt = pnt;
mtp = move_to_pnt;
if (mtp.v != mpnt.v && mtp.h != mpnt.h)
{
if (mtp.h > mpnt.h)
{
PNT tpnt;
tpnt = mtp;
mtp = mpnt;
mpnt = tpnt;
}
#if XI_IS_PM
CTOS_IS_PM;
if (mtp.v > mpnt.v)
{
mtp.v--;
mpnt.h--;
}
else
{
mpnt.v--;
mpnt.h--;
}
CTOS_END;
#endif
#if XIWS == MACWS
if (mtp.v > mpnt.v)
{
mpnt.h--;
mpnt.v++;
}
else
{
mtp.v++;
mpnt.h--;
}
mtp.v--;
mpnt.v--;
#endif
#if XIWS == WINWS
if (mtp.v > mpnt.v)
{
mpnt.v--;
mtp.v--;
}
#endif
#if XIWS == GRWS
if (mtp.v > mpnt.v)
{
mtp.v--;
mpnt.h--;
}
else
{
mpnt.v--;
mpnt.h--;
}
#endif
#if (XIWS == MTFWS) || (XIWS == XOLWS)
if (mtp.v > mpnt.v)
{
mpnt.h--;
mtp.v--;
}
else
{
mpnt.h--;
mpnt.v--;
}
#endif
xvt_dwin_draw_set_pos(win, mtp);
xvt_dwin_draw_line(win, mpnt);
}
else
{
#if (XVT_OS == XVT_OS_CTOS)
CTOS_IS_PM;
move_to_pnt.v++;
mpnt.v++;
if (move_to_pnt.v == mpnt.v)
--mpnt.h;
if (move_to_pnt.h == mpnt.h)
--mpnt.v;
CTOS_END;
#else
#if (XIWS == MACWS) || (XIWS == MTFWS) || (XIWS == PMWS) || (XIWS == GRWS) || (XIWS == XOLWS)
if (move_to_pnt.v == mpnt.v)
--mpnt.h;
if (move_to_pnt.h == mpnt.h)
--mpnt.v;
#endif
#endif
xvt_dwin_draw_set_pos(win, move_to_pnt);
xvt_dwin_draw_line(win, mpnt);
}
}
BOOLEAN
xi_rect_intersect(RCT *rctp, RCT *rctp1, RCT *rctp2)
{
RCT 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 !xvt_rect_is_empty(&r2);
}
void
xi_trap_mouse(WINDOW win)
{
xvt_win_trap_pointer(win);
}
void
xi_release_mouse(void)
{
xvt_win_release_pointer();
}
/* 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;
WINDOW win;
win = xi_get_window(itf);
xvt_menu_set_item_enabled(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_icon(XI_OBJ *xi_obj, int icon_rid, int down_icon_rid)
{
NOREF(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->xvt_win, &bd->rct);
break;
}
default:
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20088",
20088, "xi_set_icon: Invalid object");
break;
}
}
XI_RCT *
xi_get_xi_rct(XI_OBJ *xi_obj, XI_RCT *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:
{
RCT r;
xvt_vobj_get_client_rect(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, (PNT *)&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, (PNT *)&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;
WINDOW 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);
xi_set_xvt_font(itf_win, &stxp->font, FALSE);
xi_get_font_metrics(itf_win, &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, (PNT *)&stxp->rct, 2);
stxp->rct.bottom = stxp->rct.top + edit_height;
}
else
{
xi_fu_to_pu(xi_obj->itf, (PNT *)&stxp->rct, 2);
stxp->rct.bottom -= BORDER_SPACE_Y;
/* TODO move text edit object */
}
}
else
{
PNT p;
RCT rct;
short rct_r, rct_b;
p = field_data->xi_pnt;
xi_fu_to_pu(xi_obj->itf, &p, 1);
rct_r = p.h + (field_data->field_width / XI_FU_MULTIPLE)
* fu_width + 2 * BORDER_WIDTH_X + 2 * BORDER_SPACE_X;
rct_b = p.v + edit_height;
xvt_rect_set(&rct, p.h, p.v, rct_r, rct_b);
stxp->rct = rct;
}
btn_dim_x = (XI_FU_MULTIPLE * fu_height) / fu_width;
/* btn_dim_x is actual width of button */
#if XI_IS_NOT_CH
CTOS_IS_PM;
/* make buttons 70% wide as high */
btn_dim_x = (int)((long)btn_dim_x * 83L / 100L);
CTOS_END;
#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;
xi_set_xvt_font(itf_win, &stxp->font, FALSE);
xi_get_font_metrics(itf_win, &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 XI_IS_CH
BOOLEAN b;
STX_DATA *stxp;
CTOS_IS_CH;
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;
CTOS_END;
#endif
#if XI_IS_NOT_CH
/* TODO problem with this code */
/* TODO Need a boolean - place button next to field */
/* TODO Need to handle correctly if use a button on a field with xi_rct
specified */
CTOS_IS_PM;
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;
CTOS_END;
#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, (PNT *)&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, (PNT *)&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, (PNT *)&btn_data->rct, 2);
}
break;
}
case XIT_CONTAINER:
{
XI_CONTAINER_DATA *container_data;
PNT 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, (PNT *)&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;
}
}
for (i = 0; i < xi_obj->nbr_children; ++i)
recalc_metrics(xi_obj->children[i]);
}
void
xi_set_obj_font_id(XI_OBJ *xi_obj, XVT_FNTID font_id)
{
XVT_FNTID font2;
font2 = xi_create_copy_font_id(xi_obj->itf, font_id, 0);
switch (xi_obj->type)
{
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, &font2);
break;
}
case XIT_CELL:
if (!xi_obj->v.cell.is_vert_scrolled)
{
XI_OBJ *list;
RCT rct;
list = xi_obj->parent;
lm_set_font( list->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column, &font2 );
xi_get_rect(xi_obj, &rct);
xi_invalidate_rect(xi_get_window(xi_obj->itf), &rct);
}
break;
}
}
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)
{
WINDOW win;
static BOOLEAN inside = FALSE;
XI_BTN_DATA *btn;
if (check != 0 && check != 1)
check = 1;
if (! xi_get_pref(XI_PREF_NATIVE_CTRLS))
if (xi_is_checked(xi_obj) == check)
return;
win = xi_obj->itf->v.itf->xvt_win;
btn = xi_obj->v.btn;
xi_obj->v.btn->checked = check;
if (! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS))
{
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)
xi_invalidate_rect(win, &btn->rct);
else
xi_draw_button(xi_obj, &btn->rct, btn->text,
btn->down_icon_rid, btn->up_icon_rid,
btn->disabled_icon_rid, enabled,
visible, focus, btn->down, btn->dflt, btn->checked,
TRUE);
break;
}
}
}
else
{
switch (btn->type)
{
case XIBT_CHECKBOX:
xvt_ctl_set_checked(btn->btnctl, check);
break;
case XIBT_RADIOBTN:
case XIBT_TABBTN:
{
WINDOW 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))
{
int i;
xvt_errmsg_sig_if(!(parent->nbr_children <= MAX_RADIO_BUTTONS),
NULL_WIN, SEV_FATAL, ERR_ASSERT_4, "20089",
20089, "Too many radio buttons in a container");
for (i = 0; i < parent->nbr_children; ++i)
wins[i] = parent->children[i]->v.btn->btnctl;
xvt_ctl_check_radio_button(btn->btnctl, wins,
parent->nbr_children);
return;
}
if (type == XIBT_RADIOBTN || type == XIBT_TABBTN)
{
xvt_ctl_set_checked(btn->btnctl, check);
return;
}
break;
}
}
}
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)
{
XI_OBJ *itf;
itf = xi_obj->itf;
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, COLOR color)
{
RCT 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;
}
break;
}
case XIT_CELL:
if (!xi_obj->v.cell.is_vert_scrolled)
{
LM_CELL_DATA *lmcdp;
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;
lmcdp = &lmp->cell_data[row][col];
switch (part)
{
case XIC_ENABLED:
changed = (lmcdp->color != color);
lmcdp->color = color;
break;
case XIC_BACK:
changed = (lmcdp->back_color != color);
lmcdp->back_color = color;
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_BTN:
{
XI_BTN_DATA *xi_bd;
xi_bd = (XI_BTN_DATA*)xi_obj->v.btn;
switch (part)
{
case XIC_FORE:
case XIC_ENABLED:
changed = (xi_bd->fore_color != color);
xi_bd->fore_color = color;
}
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;
}
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;
}
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;
}
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;
}
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;
}
}
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;
long horz_form_unit;
long vert_form_unit;
BOOLEAN center;
XI_RCT container_rect;
container_rect = container->rct;
btn_width = max_text_len;
#if XIWS == MACWS
btn_width *= (XI_FU_MULTIPLE + 2);
#else
#if XIWS == WINWS
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
#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 ( btn_type == XIBT_TABBTN )
btn_width += (int)xi_get_pref(XI_PREF_BUTTON_PAD) / 2;
/* convert to pixels */
btn_width = (int)((btn_width * horz_form_unit)/XI_FU_MULTIPLE);
if (container->packed)
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);
/* 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:
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, vert_spacing;
XI_RCT 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;
}
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;
}
if (btn_height > max_height)
btn_height = max_height;
xvt_errmsg_sig_if(!( btn_height >= vert_form_unit), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20014", 20014,
"Not enough room in container for buttons");
container_rect.top += top_ofst;
container->rct = container_rect;
container->nbr_across = 1;
container->nbr_down = container->nbr_buttons;
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;
PNT pnt;
XI_RCT container_rect;
container_rect = container->rct;
xvt_errmsg_sig_if(!((container->btn_width > 0)||(container->btn_height > 0)),
NULL_WIN, SEV_FATAL, ERR_ASSERT_4, "20039", 20039,
"width or height required with grid");
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;
xvt_errmsg_sig_if(!( container->pix_height <= container_rect.bottom - container_rect.top),
NULL_WIN, SEV_FATAL, ERR_ASSERT_4, "20032",
20032, "button height exceeds container height");
xvt_errmsg_sig_if(!(container->pix_width <= container_rect.right - container_rect.left),
NULL_WIN, SEV_FATAL, ERR_ASSERT_4, "20033",
20033, "button width exceeds container width");
pnt.v = XI_FU_MULTIPLE;
xi_fu_to_pu(itf, &pnt, 1);
xvt_errmsg_sig_if(!((container->pix_height >= pnt.v)), NULL_WIN,
SEV_FATAL, ERR_ASSERT_4, "20034", 20034,
"height must be at least 8 form units");
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);
}
xvt_errmsg_sig_if(!(slack >= 0), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20035",
20035, "Buttons won't fit in container");
}
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)
{
XI_RCT rect;
rect = container->xi_rct;
xi_fu_to_pu(cnt_obj->itf, (PNT *)&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)
{
RCT rct;
BOOLEAN packed; /* 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;
}
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, (PNT *)&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;
xvt_errmsg_sig_if(!(cnt_obj->type == XIT_CONTAINER), NULL_WIN, SEV_FATAL,
ERR_ASSERT_4, "20036", 20036,
"xi_container_reorient() passed wrong object type");
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 */
/*--------------------------------------------------------------------------*/
FONT_OBJ* xi_def_get_font( XI_OBJ_DEF* obj_def )
{
FONT_OBJ* font = NULL;
if (!obj_def)
return &xi_sysfont;
switch (obj_def->type)
{
case XIT_FIELD:
if (obj_def->v.field->font_id)
font = &obj_def->v.field->font_id;
break;
case XIT_TEXT:
if (obj_def->v.text->font_id)
font = &obj_def->v.text->font_id;
break;
case XIT_LIST:
if (obj_def->v.list->font_id)
font = &obj_def->v.list->font_id;
break;
case XIT_ITF:
if (obj_def->v.itf->font_id)
font = &obj_def->v.itf->font_id;
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 )
{
/* Determine if the passed object is the interface */
if (xi_is_itf(obj))
{
/* If the local variable is set use XIL coordinates */
if (obj->v.itf->use_xil_win) return TRUE;
/* If the PREF is set use XIL coordinates */
if ((BOOLEAN)xi_get_pref(XI_PREF_XIL)) return TRUE;
/* The interface was not passed in so use the PREF */
}else
if ((BOOLEAN)xi_get_pref(XI_PREF_XIL)) return TRUE;
return FALSE;
}