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