guy f8c1ec663e Trasformata a catena funzione
da xi_set_text(XI_OBJ* obj, char* text)
a  xi_set_text(XI_OBJ* obj, const char* text)


git-svn-id: svn://10.65.10.50/branches/R_10_00@23125 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-07-10 14:56:20 +00:00

4443 lines
124 KiB
C
Executable File
Raw Blame History

/*******************************************************************************
* 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 "xitext.h"
#include "xistx.h"
#include "xilm.h"
#include "xilmst.h"
#include "xiutils.h"
#include "xi_int.h"
#if XIWS == XIWS_XM
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#endif
#define MAXPIX 6000
#define VRCT_TO_PRCT( rp ) \
( rp )->left -= cur_delta_x; \
( rp )->right -= cur_delta_x; \
( rp )->top -= cur_delta_y; \
( rp )->bottom -= cur_delta_y;
/* ERROR CODES 20000-20089 */
BOOLEAN xi_false = FALSE;
void xi_finish_interface_create( XinWindow win );
extern XI_OBJ *xi_creating_itf;
static int xi_send_event( XI_OBJ * xi_obj, XinEvent * ep, BOOLEAN do_subtree );
#ifndef NO_PRIMARY_SELECTION
#if XIWS == XIWS_XM
static XI_OBJ *rp_xi_obj = NULL;
static void
receive_primesel( Widget widget, XtPointer data, Atom * selection,
Atom * type, XtPointer value, unsigned long *length, int *format )
{
char *s;
XinWindow win;
char *p;
/* printf("receive_primesel: ENTERED, widget %d, selection %d, type %d\n",
* widget, *selection, *type); */
/* printf(" length %d, format %d\n", length,
* *format); */
/* check if request for primary selection was successful */
if ( *selection != XA_PRIMARY || *type != XA_STRING || *format != 8 )
{
/* printf("receive_primesel: get primary selection failed\n"); */
return;
}
/* allocate space and fill in text from selection value */
s = XinMemoryAlloc( *length + 1 );
/* Assertion for out of memory? */
strncpy( s, ( char * ) value, *length );
s[*length] = '\0';
/* printf("receive_primesel: primary selection text = '%s'\n", s); */
XtFree( ( char * ) value ); /* this must be freed with XtFree */
/* xvt_dm_post_note("Text from Primary selection is '%s'", s); */
if ( rp_xi_obj )
{
win = xi_get_window( rp_xi_obj );
rp_xi_obj = NULL;
for ( p = s; *p != '\0'; ++p )
{
XinEvent ev;
MEMCLEAR( ev );
ev.type = XinEventCharacter;
ev.v.character.ch = ( unsigned char ) *p;
xi_event( win, &ev );
XinWindowPaintForce( win );
}
}
XinMemoryFree( s );
}
static void
get_primary_selection( XI_OBJ * itf, XinWindow win )
{
Widget widget;
rp_xi_obj = itf;
/* printf("get_primary_selection: ENTERED, win %d\n", win); */
/* request PRIMARY selection */
if ( rp_xi_obj) {
widget = ( Widget ) XinWindowWidgetGet( win );
XtGetSelectionValue( widget, XA_PRIMARY, XA_STRING, receive_primesel, NULL,
XtLastTimestampProcessed( XtDisplay( widget ) ) );
}
/* printf("get_primary_selection: returning\n"); */
}
#endif
#endif
BOOLEAN
call_cb( XI_OBJ * itf, XI_EVENT * xiev )
{
XI_ITF_DATA *itf_data;
itf_data = itf->v.itf;
itf_data->in_callback++;
XinCoalesceInvalidates( itf_data->xin_win, TRUE );
( *itf_data->xi_eh ) ( ( struct _xi_obj * ) itf, xiev );
#ifdef WINRUNNER
xir_record( itf, xiev );
#endif
if ( xi_is_itf( itf ) )
{
XinCoalesceInvalidates( itf_data->xin_win, FALSE );
itf_data->in_callback--;
if ( itf_data->in_callback == 0 && itf_data->closing )
{
itf_data->closing = FALSE;
xi_close_window_internal( itf );
return FALSE;
}
}
return TRUE;
}
static long
event_to_longchar( XinEvent * ep )
{
long c = ep->v.character.ch;
if ( ep->v.character.control )
c |= XI_MOD_CONTROL;
if ( ep->v.character.shift )
c |= XI_MOD_SHIFT;
if ( ep->v.character.alt )
c |= XI_MOD_ALT;
return ( c );
}
void
xi_column_set_pixel_width( XI_OBJ * column, int width )
{
int i;
XI_LIST_DATA *list;
LM_DATA *lm_data;
list = column->parent->v.list;
lm_data = ( LM_DATA * ) list->lm;
if ( column->type != XIT_COLUMN )
XinError( 20010, XinSeverityFatal, 0L );
lm_column_set_pixel_width( list->lm, xi_obj_to_idx( column ), width );
if ( list->sb_win && ( !list->width ) )
xi_move_list_scroll_bar( column->parent );
i = xi_obj_to_idx( column );
if ( i < lm_data->fixed_columns && list->hsb_win )
xi_move_list_hscroll_bar( column->parent );
}
void
xi_set_column_width( XI_OBJ * column, int width )
{
int width_in_chars;
if ( xi_get_xil_pref( column->itf ) )
width_in_chars = width;
else
width_in_chars = width / XI_FU_MULTIPLE;
xi_column_set_pixel_width( column, width_in_chars
* ( ( LM_DATA * ) column->parent->v.list->lm )
->pix_char_width );
}
static XI_OBJ *
xi_get_default( XI_OBJ * obj )
{
XI_OBJ **objlist;
XI_OBJ *temp;
int n;
temp = obj->itf->v.itf->focus_obj;
if ( temp != NULL && temp->type == XIT_BTN )
return temp;
if ( obj->type == XIT_BTN && obj->v.btn->dflt )
return obj;
switch ( obj->type )
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
return NULL;
default:
break;
}
/* search in child list */
objlist = xi_get_member_list( obj, &n );
for ( ; n > 0; n--, objlist++ )
{
/* call recursively for generality in future versions */
if ( ( temp = xi_get_default( *objlist ) ) != NULL )
return temp;
}
return NULL;
}
static XI_OBJ *
xi_get_cancel( XI_OBJ * obj )
{
XI_OBJ **objlist;
XI_OBJ *temp;
int n;
if ( obj->type == XIT_BTN && obj->v.btn->cancel )
return obj;
switch ( obj->type )
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
return NULL;
default:
break;
}
/* search in child list */
objlist = xi_get_member_list( obj, &n );
for ( ; n > 0; n--, objlist++ )
{
/* call recursively for generality in future versions */
if ( ( temp = xi_get_cancel( *objlist ) ) != NULL )
return temp;
}
return NULL;
}
XI_OBJ *
xi_get_obj_from_mnemonic( XI_OBJ * obj, char ch )
{
XI_OBJ **objlist;
XI_OBJ *temp;
int n;
if ( obj->type == XIT_BTN && toupper( obj->v.btn->mnemonic ) == toupper( ch ) )
return obj;
if ( obj->type == XIT_FIELD && toupper( obj->v.field->mnemonic ) == toupper( ch ) )
return obj;
switch ( obj->type )
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
return NULL;
default:
break;
}
/* search in child list */
objlist = xi_get_member_list( obj, &n );
for ( ; n > 0; n--, objlist++ )
{
/* call recursively for generality in future versions */
if ( ( temp = xi_get_obj_from_mnemonic( *objlist, ch ) ) != NULL )
return temp;
}
return NULL;
}
void
xi_hscroll_internal( XI_OBJ * xi_obj, int nbr_lines, int pos )
{
XI_OBJ *itf;
XI_OBJ *focus;
LM lm = xi_obj->v.list->lm;
itf = xi_obj->parent;
focus = xi_get_focus( itf );
if ( focus && focus->parent == xi_obj )
{
if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
{
lm_hscroll( lm, nbr_lines, pos );
}
else
{
if ( xi_move_focus( itf ) )
lm_hscroll( lm, nbr_lines, pos );
}
}
else
lm_hscroll( lm, nbr_lines, pos );
}
void
xi_hscroll( XI_OBJ * xi_obj, int nbr_lines )
{
xi_hscroll_internal( xi_obj, nbr_lines, 0 );
}
static void
control_event_hscroll( XI_OBJ * xi_obj, int nbr_lines, int pos )
{
XI_LIST_DATA *list_data;
XI_OBJ *other_list;
list_data = xi_obj->v.list;
xi_hscroll_internal( xi_obj, nbr_lines, pos );
if ( list_data->horz_sync_list &&
!list_data->scrolling_in_progress )
{
list_data->scrolling_in_progress = TRUE;
other_list = xi_get_obj( xi_obj->itf, list_data->horz_sync_list );
if ( other_list )
xi_hscroll_internal( other_list, nbr_lines, pos );
list_data->scrolling_in_progress = FALSE;
}
}
void
xi_control_event_scroll( XI_OBJ * xi_obj, int nbr_lines, int percent,
BOOLEAN same_cell )
{
XI_LIST_DATA *list_data;
XI_OBJ *other_list;
list_data = xi_obj->v.list;
xi_scroll_internal( xi_obj, nbr_lines, percent, same_cell );
if ( list_data->vert_sync_list &&
!list_data->scrolling_in_progress )
{
list_data->scrolling_in_progress = TRUE;
other_list = xi_get_obj( xi_obj->itf,
list_data->vert_sync_list );
if ( other_list )
xi_scroll_internal( other_list, nbr_lines, percent, same_cell );
list_data->scrolling_in_progress = FALSE;
}
}
static void
control_event( XI_OBJ * itf, XinWindow win, XinEvent * ep )
{
XI_ITF_DATA *itf_data;
XI_OBJ *xi_obj;
itf_data = itf->v.itf;
win = itf_data->xin_win;
if ( ep->v.control.control_id == XI_MULTILINE_SCROLLBAR_CID )
{
XI_TEXT *text;
text = xi_text_focus_get( itf_data->xin_win );
if ( text && xi_text_editing_is( text ) )
xi_text_event( text, ep, FALSE, NULL );
return;
}
if ( ( xi_obj = xi_get_obj( itf, ep->v.control.control_id ) ) != NULL )
{
switch ( xi_obj->type )
{
case XIT_FIELD:
{
XI_TEXT *text;
text = stx_xi_text_get( xi_obj->v.field->stx );
if ( text ) /* && xi_text_editing_is( text ) ) */
xi_text_event( text, ep, FALSE, NULL );
return;
}
case XIT_BTN:
{
XI_EVENT xiev;
XinWindow front_win = XinWindowFocusGet( );
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
call_cb( itf, &xiev );
if ( xi_is_itf( itf ) && xi_is_window( win )
&& xi_get_focus( itf ) != xi_obj )
{
if ( win )
XinWindowFrontSet( win );
if ( front_win != win && front_win )
XinWindowFrontSet( front_win );
}
break;
}
case XIT_LIST:
{
switch ( ep->v.control.ctrl_info.v.scroll.action )
{
case XinScrollBarActionLineUp:
xi_control_event_scroll( xi_obj, -1, 0, TRUE );
break;
case XinScrollBarActionLineDown:
xi_control_event_scroll( xi_obj, 1, 0, TRUE );
break;
case XinScrollBarActionPageUp:
xi_control_event_scroll( xi_obj, XI_SCROLL_PGUP, 0, TRUE );
break;
case XinScrollBarActionPageDown:
xi_control_event_scroll( xi_obj, XI_SCROLL_PGDOWN, 0, TRUE );
break;
case XinScrollBarActionThumb:
case XinScrollBarActionThumbTrack:
if (ep->v.control.ctrl_info.v.scroll.action == XinScrollBarActionThumbTrack &&
xi_obj->v.list->scroll_on_thumb_track != TRUE)
break;
{
int percent = ep->v.control.ctrl_info.v.scroll.position;
if ( XinScrollBarProportionGet( ep->v.control.ctrl_info.win,
XinScrollBarTypeEither ) + percent == 100 )
xi_control_event_scroll( xi_obj, XI_SCROLL_LAST, 0, TRUE );
else
xi_control_event_scroll( xi_obj, XI_SCROLL_FIRST, percent, TRUE );
break;
}
default:
break;
}
break;
}
default:
break;
}
}
if ( xi_is_itf( itf ) &&
( xi_obj = xi_get_obj( itf, ep->v.control.control_id - HSCROLL_CID_CONST ) ) != NULL )
{
switch ( xi_obj->type )
{
case XIT_LIST:
switch ( ep->v.control.ctrl_info.v.scroll.action )
{
case XinScrollBarActionLineUp:
control_event_hscroll( xi_obj, -1, 0 );
break;
case XinScrollBarActionLineDown:
control_event_hscroll( xi_obj, 1, 0 );
break;
case XinScrollBarActionPageUp:
control_event_hscroll( xi_obj, XI_SCROLL_PGUP, 0 );
break;
case XinScrollBarActionPageDown:
control_event_hscroll( xi_obj, XI_SCROLL_PGDOWN, 0 );
break;
case XinScrollBarActionThumb:
case XinScrollBarActionThumbTrack:
if (ep->v.control.ctrl_info.v.scroll.action == XinScrollBarActionThumbTrack &&
xi_obj->v.list->scroll_on_thumb_track != TRUE)
break;
{
int prop;
int rng1,
rng2;
int pos;
prop = XinScrollBarProportionGet( ep->v.control.ctrl_info.win,
XinScrollBarTypeEither );
XinScrollBarRangeGet( ep->v.control.ctrl_info.win, XinScrollBarTypeEither,
&rng1, &rng2 );
pos = ( rng2 - rng1 - prop ) ?
( int ) ( ep->v.control.ctrl_info.v.scroll.position * 100L / ( rng2 - rng1 - prop ) ) : 0;
control_event_hscroll( xi_obj, XI_SCROLL_FIRST, pos );
break;
}
default:
break;
}
break;
default:
break;
}
}
}
void
xi_set_trap_obj( XI_OBJ * xi_obj )
{
XI_OBJ *itf;
XI_ITF_DATA *itf_data;
itf = xi_obj->itf;
itf_data = itf->v.itf;
itf_data->trap_obj = xi_obj;
itf_data->trap_explicit = TRUE;
}
static void
destroy_controls( XI_OBJ * xi_obj )
{
XI_OBJ **objp;
int i;
switch ( xi_obj->type )
{
case XIT_LIST:
if ( xi_obj->v.list->font )
XinFontDestroy( xi_obj->v.list->font );
lm_cleanup( xi_obj->v.list->lm );
break;
case XIT_FIELD:
if ( xi_obj->v.field->font_set )
stx_destroy_font( xi_obj->v.field->stx );
break;
case XIT_TEXT:
if ( xi_obj->v.text->font )
XinFontDestroy( xi_obj->v.text->font );
break;
case XIT_ITF:
if ( xi_obj->v.itf->font )
XinFontDestroy( xi_obj->v.itf->font );
break;
case XIT_BTN:
xi_bitmap_destroy( xi_obj->v.btn->up_bitmap );
xi_bitmap_destroy( xi_obj->v.btn->down_bitmap );
xi_bitmap_destroy( xi_obj->v.btn->disabled_bitmap );
break;
default:
break;
}
objp = xi_obj->children;
for ( i = xi_obj->nbr_children; i > 0; i--, objp++ )
destroy_controls( *objp );
}
static void
copy_to_clip( XI_OBJ * focus_obj )
{
int b,
e;
char *buff;
xi_get_sel( focus_obj, &b, &e );
if ( b != e )
{
long len;
len = e - b;
buff = xi_get_text( focus_obj, NULL, 0 );
XinClipboardPut( XinClipboardFormatText, len, &buff[b] );
}
}
static void
update_menus( void )
{
BOOLEAN paste_enable;
BOOLEAN cut_or_copy_enable = FALSE;
XI_OBJ *itf;
XI_ITF_DATA *itfdata;
XinWindow win;
win = XinWindowFocusGet( );
if ( win == XI_NULL_WINDOW || !xi_is_window( win ) )
return;
itf = xi_get_itf( win );
itfdata = itf->v.itf;
if ( itfdata->menu_win != XI_NULL_WINDOW )
win = itfdata->menu_win;
if ( itfdata->edit_menu )
{
XI_OBJ *focus_obj;
paste_enable = XinClipboardFormatAvail( XinClipboardFormatText );
XinWindowMenuItemEnable( win, XI_MENU_EDIT_PASTE, paste_enable );
focus_obj = xi_get_focus( itf );
if ( ( focus_obj && ( focus_obj->type == XIT_CELL ) ) ||
( focus_obj && ( focus_obj->type == XIT_FIELD ) ) )
{
int s,
e;
xi_get_sel( focus_obj, &s, &e );
if ( s != e )
cut_or_copy_enable = TRUE;
}
if ( paste_enable != itfdata->paste_enable )
{
XinWindowMenuItemEnable( win, XI_MENU_EDIT_PASTE, paste_enable );
itfdata->paste_enable = paste_enable;
}
if ( cut_or_copy_enable != itfdata->cut_or_copy_enable )
{
XinWindowMenuItemEnable( win, XI_MENU_EDIT_CUT, cut_or_copy_enable );
XinWindowMenuItemEnable( win, XI_MENU_EDIT_COPY, cut_or_copy_enable );
XinWindowMenuItemEnable( win, XI_MENU_EDIT_CLEAR, cut_or_copy_enable );
itfdata->cut_or_copy_enable = cut_or_copy_enable;
}
}
}
static void
do_edit_menu( XI_OBJ * itf, XinEvent * ep )
{
XI_OBJ *focus_obj;
unsigned long attrib = 0L;
focus_obj = xi_get_focus( itf );
if ( focus_obj && focus_obj->type != XIT_ITF )
{
switch ( focus_obj->type )
{
case XIT_FIELD:
attrib = xi_get_attrib( focus_obj );
break;
case XIT_CELL:
{
XI_OBJ *list;
XI_OBJ *column;
XI_OBJ **members;
int col_nbr,
nbr_members;
list = focus_obj->parent;
members = xi_get_member_list( list, &nbr_members );
col_nbr = focus_obj->v.cell.column;
column = members[col_nbr];
attrib = xi_get_attrib( column );
break;
}
default:
break;
}
if ( attrib & XI_ATR_EDITMENU )
{
int b, e;
switch ( ep->v.menu_command.tag )
{
case XI_MENU_EDIT_CUT:
copy_to_clip( focus_obj );
/* fall through */
case XI_MENU_EDIT_CLEAR:
xi_get_sel( focus_obj, &b, &e );
#if 1 // #ifdef XVAGA
if ( b == e )
{
e++;
xi_set_sel( focus_obj, b, e );
}
#endif
if ( b != e )
{
XinEvent ev;
MEMCLEAR( ev );
ev.type = XinEventCharacter;
ev.v.character.ch = XI_KEY_DEL;
xi_event( xi_get_window( itf ), &ev );
}
update_menus( );
break;
case XI_MENU_EDIT_COPY:
copy_to_clip( focus_obj );
update_menus( );
break;
case XI_MENU_EDIT_PASTE:
#ifdef XI_USE_TX_SUPPORT
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
if ( focus_obj->type == XIT_FIELD )
if ( xi_is_txedit( focus_obj ) )
if ( xi_get_pref( XI_PREF_MULTILINE_QUICK_PASTE ) )
break;
#endif
{
char *cb,
*p;
long size;
if ( ( cb = XinClipboardGet( XinClipboardFormatText, &size ) ) != NULL )
{
XinWindow win;
win = xi_get_window( itf );
itf->v.itf->pasting = TRUE;
p = cb;
if ( ( focus_obj->type == XIT_FIELD || focus_obj->type == XIT_CELL ) &&
xi_get_pref( XI_PREF_MULTILINE_QUICK_PASTE ) )
{
XI_TEXT *text;
text = xi_text_focus_get( win );
if ( text )
if ( text->multi_line )
{
xi_text_paste_internal( text, p );
itf->v.itf->pasting = FALSE;
XinMemoryFree( cb );
break;
}
}
/* Che programmatore cazzone!
while ( size-- > 0 )
{
XinEvent ev;
MEMCLEAR( ev );
ev.type = XinEventCharacter;
ev.v.character.ch = ( unsigned char ) *p++;
xi_event( win, &ev );
XinWindowPaintForce( win );
}
*/
if (size) // Molto meglio cosi!
{
XinEvent ev;
MEMCLEAR( ev );
ev.type = XinEventCharacter;
while ( size-- > 0 )
{
ev.v.character.ch = ( unsigned char ) *p++;
xi_event( win, &ev );
}
}
itf->v.itf->pasting = FALSE;
XinMemoryFree( cb );
}
}
update_menus( );
break;
}
}
}
}
/*
count the number of children of xi_obj that have rectangles that will be completely
filled in when the child is drawn.
*/
static int
count_children( XI_OBJ * xi_obj )
{
int idx;
int count = 0;
XI_OBJ **child;
for ( idx = 0, child = xi_obj->children; idx < xi_obj->nbr_children; ++idx, ++child )
{
XI_OBJ_TYPE type = ( *child )->type;
if ( xi_get_attrib( *child ) & XI_ATR_VISIBLE )
{
/* do not count groups, lines, static texts, or columns, nor their
* children */
if ( type != XIT_GROUP && type != XIT_LINE && type != XIT_TEXT && type != XIT_COLUMN )
{
/* count the children of containers, forms, and the interface, but not
* containers, forms, and interfaces */
if ( ( *child )->type != XIT_LIST && ( *child )->children )
count += count_children( *child );
if ( type != XIT_CONTAINER &&
type != XIT_FORM &&
type != XIT_ITF &&
type != XIT_TEXT &&
type != XIT_BTN &&
type != XIT_FIELD )
++count;
}
}
}
return count;
}
static void
add_rects( XI_OBJ * xi_obj, XinRect * ra, int *ra_count )
{
int idx;
XI_OBJ **child;
for ( idx = 0, child = xi_obj->children; idx < xi_obj->nbr_children; ++idx, ++child )
{
XI_OBJ_TYPE type = ( *child )->type;
if ( xi_get_attrib( *child ) & XI_ATR_VISIBLE )
{
/* do not add rects for groups, lines, static texts, or columns, nor
* their children */
if ( type != XIT_GROUP && type != XIT_LINE && type != XIT_TEXT && type != XIT_COLUMN )
{
/* add rects for the children of containers, forms, and the interface,
* but not containers, forms, and interfaces */
if ( ( *child )->type != XIT_LIST && ( *child )->children )
add_rects( *child, ra, ra_count );
if ( type != XIT_CONTAINER &&
type != XIT_FORM &&
type != XIT_ITF &&
type != XIT_TEXT &&
type != XIT_BTN &&
type != XIT_FIELD )
{
xi_get_rect( ( *child ), &ra[*ra_count] );
++*ra_count;
}
}
}
}
}
#if XIWS == XIWS_PM
static int _Optlink
#else
static int
#endif
compare( const void *arg1, const void *arg2 )
{
if ( *( int * ) arg1 == *( int * ) arg2 )
return 0;
if ( *( int * ) arg1 < *( int * ) arg2 )
return -1;
return 1;
}
static int
elim_dups( int *int_array, int int_count )
{
int index = 0;
int top = int_count - 1;
int *iap = int_array;
while ( index < top )
{
if ( *iap == *( iap + 1 ) )
{
if ( top > index )
memmove( iap + 1, iap + 2, ( top - index - 1 ) * sizeof( int ) );
--top;
}
else
{
++index;
++iap;
}
}
return top;
}
static void
draw_all_rects( XI_OBJ * itf )
{
XinRect *ra,
*rap;
XI_ITF_DATA *itf_data;
int count;
int cur_delta_x,
cur_delta_y;
int num_rects;
int ra_count;
int *hml,
*hmlp;
int hml_count,
hml_top;
int *vml,
*vmlp;
int vml_count,
vml_top;
int int_count;
int rect_count;
XinRect client_rect;
XinWindow win = xi_get_window( itf );
XI_BITMAP *bitmap;
itf_data = itf->v.itf;
bitmap = itf_data->bitmap;
cur_delta_x = itf_data->delta_x;
cur_delta_y = itf_data->delta_y;
num_rects = count_children( itf );
XinWindowRectGet( win, &client_rect );
if ( !num_rects )
{
if ( bitmap != NULL )
xi_bitmap_draw( bitmap, win, &client_rect, NULL, TRUE );
else
XinWindowRectDraw( win, &client_rect );
return;
}
ra = xi_tree_malloc( sizeof( XinRect ) * num_rects, itf );
ra_count = 0;
add_rects( itf, ra, &ra_count );
int_count = num_rects * 2 + 2;
/* hml is an acronym for horizontal mathmatical lines */
/* vml is an acronym for vertical mathmatical lines */
hml = xi_tree_malloc( sizeof( int ) * int_count, itf );
vml = xi_tree_malloc( sizeof( int ) * int_count, itf );
hmlp = hml;
vmlp = vml;
*hmlp = 0;
++hmlp;
*vmlp = 0;
++vmlp;
*hmlp = 9999;
++hmlp;
*vmlp = 9999;
++vmlp;
for ( count = 0, rap = ra; count < num_rects; ++count, ++rap )
{
*hmlp = rap->left;
++hmlp;
*hmlp = rap->right;
++hmlp;
*vmlp = rap->top;
++vmlp;
*vmlp = rap->bottom;
++vmlp;
}
qsort( ( void * ) hml, ( size_t ) int_count, sizeof( int ), compare );
qsort( ( void * ) vml, ( size_t ) int_count, sizeof( int ), compare );
hml_top = elim_dups( hml, int_count );
vml_top = elim_dups( vml, int_count );
for ( hml_count = 0, hmlp = hml; hml_count < hml_top; ++hml_count, ++hmlp )
{
for ( vml_count = 0, vmlp = vml; vml_count < vml_top; ++vml_count, ++vmlp )
{
/* use static for rect and new_rect, to allow the compiler to generate
* more efficient code */
static XinRect rect;
rect.left = *hmlp;
rect.right = *( hmlp + 1 );
rect.top = *vmlp;
rect.bottom = *( vmlp + 1 );
for ( rect_count = 0, rap = ra; rect_count < ra_count; ++rect_count, ++rap )
{
static XinRect new_rect;
new_rect = *rap;
if ( new_rect.top < rect.top )
new_rect.top = rect.top;
if ( new_rect.left < rect.left )
new_rect.left = rect.left;
if ( new_rect.bottom > rect.bottom )
new_rect.bottom = rect.bottom;
if ( new_rect.right > rect.right )
new_rect.right = rect.right;
/* if the intersection is not empty, then skip this rectangle */
if ( new_rect.bottom > new_rect.top && new_rect.right > new_rect.left )
break;
}
/* if we made it through all rectangles, then no rectangle intersected,
* and we should draw rect */
if ( ra_count && rect_count == ra_count )
{
rect.left -= cur_delta_x;
rect.right -= cur_delta_x;
rect.top -= cur_delta_y;
rect.bottom -= cur_delta_y;
if ( bitmap != NULL )
xi_bitmap_draw( bitmap, win, &client_rect, &rect, TRUE );
else
XinWindowRectDraw( win, &rect );
}
}
}
xi_tree_free( ra );
xi_tree_free( hml );
xi_tree_free( vml );
}
static void
draw_background( XI_OBJ * itf )
{
XI_ITF_DATA *itf_data = itf->v.itf;
XinWindow win = itf_data->xin_win;
if ( itf_data->back_color )
{
XinDrawTools t;
XinBrush cbrush;
XinWindowDrawToolsNormalGet( &t );
XinWindowDrawToolsSet( win, &t );
XinWindowPenSet( win, &hollow_cpen );
cbrush.pattern = XinBrushSolid;
cbrush.fore_color = itf_data->back_color;
XinWindowBrushSet( win, &cbrush );
xi_set_clip( win, NULL );
draw_all_rects( itf );
}
else if ( itf_data->bitmap != NULL )
{
xi_set_clip( win, NULL );
draw_all_rects( itf );
}
}
static void
do_post_event( XI_OBJ * itf, XinEvent * ep )
{
XI_EVENT xiev;
if ( xi_is_itf( itf ) )
{
MEMCLEAR( xiev );
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
{
xiev.type = XIE_XIN_POST_EVENT;
xiev.v.xin_event = *ep;
}
#ifdef XI_USE_XVT
else
{
if ( ep->type != XinEventCharacter || !ep->v.character.alt )
{
xiev.type = XIE_XVT_POST_EVENT;
XinXvtEventGet( &xiev.v.xvte );
}
}
#endif
xiev.refused = FALSE;
if ( !call_cb( itf, &xiev ) )
return;
}
}
/* ------------------------------------------------------------------------ */
/* get_text_ctools */
/* ------------------------------------------------------------------------ */
static XinDrawTools *
get_text_ctools( XI_ITF_DATA * itf_data, XinDrawTools * ct, XinFont ** p_font )
{
XinWindowDrawToolsNormalGet( ct );
ct->pen.fore_color = ct->text_fore_color = XI_COLOR_BLACK;
ct->opaque_text = FALSE;
if ( itf_data->font )
*p_font = itf_data->font;
else
*p_font = xi_get_system_font( );
return ( ct );
}
/* ------------------------------------------------------------------------ */
/* xi_draw_obj */
/* ------------------------------------------------------------------------ */
static void
xi_draw_obj( XI_OBJ * xi_obj )
{
XinWindow win;
XI_ITF_DATA *itf_data;
itf_data = xi_obj->itf->v.itf;
win = itf_data->xin_win;
switch ( xi_obj->type )
{
case XIT_TEXT:
{
XI_TEXT_DATA *text;
XinDrawTools ct;
XinFont *font;
text = xi_obj->v.text;
get_text_ctools( itf_data, &ct, &font );
ct.text_back_color = itf_data->back_color;
ct.text_fore_color = XI_COLOR_BLACK;
if ( text->fore_color )
ct.text_fore_color = text->fore_color;
if ( text->back_color )
{
ct.opaque_text = TRUE;
ct.text_back_color = text->back_color;
}
XinWindowDrawToolsSet( win, &ct );
if ( text->font )
font = text->font;
if ( ( text->attrib & XI_ATR_ENABLED ) )
XinWindowColorTextForeSet( win, ct.text_fore_color );
else
XinWindowColorTextForeSet( win,
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
XinWindowColorTextBackSet( win, ct.text_back_color );
xi_draw_clipped_text( win, font, text->text, &text->rct, &text->rct,
text->attrib | XI_ATR_VCENTER, FALSE, 0, -1,
text->mnemonic, text->mnemonic_instance, NULL );
break;
}
case XIT_LINE:
{
XI_LINE_DATA *line;
XinPoint pnt1,
pnt2;
XinWindowClipSet( win, NULL );
line = xi_obj->v.line;
if ( line->attrib & XI_ATR_VISIBLE )
{
pnt1 = line->pnt1;
pnt2 = line->pnt2;
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
xi_draw_3d_line( win, pnt1, pnt2, line->well );
else
{
XinPen cpen;
cpen = black_cpen;
if ( line->fore_color )
cpen.fore_color = line->fore_color;
XinWindowPenSet( win, &cpen );
if ( line->back_color )
XinWindowColorTextBackSet( win, line->back_color );
xi_move_to( win, pnt1 );
xi_draw_line( win, pnt2 );
}
}
break;
}
case XIT_RECT:
{
XI_RECT_DATA *rect;
XinRect rct;
XinWindowClipSet( win, NULL );
rect = xi_obj->v.rect;
if ( rect->attrib & XI_ATR_VISIBLE )
{
rct = rect->rct;
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
{
xi_draw_3d_rect( win, &rct, rect->well, 1,
rect->hilight_color, rect->back_color,
rect->shadow_color );
if ( rect->ridge )
{
xi_inflate_rect( &rct, -1 );
xi_draw_3d_rect( win, &rct, ( BOOLEAN ) ( !rect->well ), 1,
rect->hilight_color, rect->back_color,
rect->shadow_color );
}
}
else
{
XinPen cpen = black_cpen;
XinBrush cbrush = white_cbrush;
if ( rect->fore_color )
cpen.fore_color = rect->fore_color;
if ( rect->back_color )
cbrush.fore_color = rect->back_color;
XinWindowBrushSet( win, &cbrush );
if ( rect->ridge )
{
XinWindowPenSet( win, &hollow_cpen );
xi_draw_rect( win, &rct );
XinWindowPenSet( win, &cpen );
xi_draw_roundrect( win, &rct, 4, 4 );
}
else
{
XinWindowPenSet( win, &cpen );
xi_draw_rect( win, &rct );
}
}
if ( rect->bitmap != NULL )
{
xi_inflate_rect( &rct, -1 );
xi_bitmap_draw( rect->bitmap, win, &rct, NULL, FALSE );
}
}
break;
}
default:
break;
}
}
/* ------------------------------------------------------------------------ */
/* xi_draw_field_button */
/* ------------------------------------------------------------------------ */
void
xi_draw_field_button( XI_OBJ * xi_obj )
{
XI_FIELD_DATA *fd;
unsigned long attrib;
STX_DATA *stxd;
const XinColor color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
const XinColor color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
const XinColor color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
const int button_depth = 1;
#if XIWS != XIWS_WM
XinRect cr, r;
#endif
XinWindow win;
attrib = xi_get_attrib( xi_obj );
if ( !( attrib & XI_ATR_VISIBLE ) )
return;
fd = xi_obj->v.field;
stxd = ( STX_DATA * ) fd->stx;
win = xi_obj->itf->v.itf->xin_win;
XinWindowDrawModeSet( win, XinDrawModeCopy );
xi_set_clip( win, NULL );
#if XIWS != XIWS_WM
r = fd->btn_rct;
xi_inflate_rect( &r, -1 );
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
xi_draw_shaded_rect(win, &r, fd->down, button_depth, color_light, color_ctrl, color_dark);
else
{
XinWindowBrushSet( win, &white_cbrush );
XinWindowPenSet( win, &hollow_cpen );
xi_draw_rect( win, &r );
}
cr = r;
xi_inflate_rect( &cr, -button_depth );
xi_set_clip( win, &cr );
if ( fd->button_bitmap != NULL )
xi_bitmap_draw( fd->button_bitmap, win, &cr, &cr, FALSE );
else
{
XinColor color = ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) ? color_ctrl : xi_get_pref( XI_PREF_COLOR_CTRL );
// Guy was here: center icon in button
int x = (r.left+r.right-XinMetricGet(XinMetricIconWidth))/2; // x = r.left + 3;
int y = (r.top+r.bottom-XinMetricGet(XinMetricIconHeight))/2; // y = r.top + 2;
int icon_rid = fd->icon_rid;
if ( icon_rid == 0 )
icon_rid = ( int ) xi_get_pref( XI_PREF_COMBO_ICON );
if ( fd->down )
xi_draw_icon( win, x, y + 1, icon_rid, XI_COLOR_BLACK, color );
else
xi_draw_icon( win, x, y, icon_rid, XI_COLOR_BLACK, color );
}
xi_set_clip( win, NULL );
XinWindowPenSet( win, &black_cpen );
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_rect( win, &fd->btn_rct );
#endif
#if XIWS == XIWS_WM
NOREF( stxd );
{
XinBrush black_cbrush;
black_cbrush = white_cbrush;
black_cbrush.fore_color = XI_COLOR_BLACK;
xi_set_clip( win, NULL );
XinWindowPenSet( win, &hollow_cpen );
XinWindowBrushSet( win, &black_cbrush );
xi_draw_rect( win, &fd->btn_rct );
}
#endif
}
/* ------------------------------------------------------------------------ */
/* field_event */
/* ------------------------------------------------------------------------ */
static void
field_event( XI_OBJ * xi_obj, XinEvent * ep )
{
XI_FIELD_DATA *field_data;
XinRect rct;
field_data = xi_obj->v.field;
rct = field_data->btn_rct;
switch ( ep->type )
{
case XinEventCharacter:
if ( field_data->button )
{
long button_key;
BOOLEAN shift,
control,
alt;
button_key = xi_get_pref( XI_PREF_BUTTON_KEY );
shift = ( BOOLEAN ) ( ( button_key & XI_MOD_SHIFT ) != 0 );
control = ( BOOLEAN ) ( ( button_key & XI_MOD_CONTROL ) != 0 );
alt = ( BOOLEAN ) ( ( button_key & XI_MOD_ALT ) != 0 );
button_key &= 0xffffffL;
if ( button_key == ep->v.character.ch &&
shift == ep->v.character.shift &&
control == ep->v.character.control &&
alt == ep->v.character.alt )
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb( itf, &xiev );
}
}
break;
case XinEventPaint:
if ( field_data->button )
xi_draw_field_button( xi_obj );
break;
case XinEventMouseDown:
{
unsigned long attrib;
attrib = stx_get_attrib( xi_obj->v.field->stx );
attrib &= ( XI_ATR_ENABLED | XI_ATR_VISIBLE );
if ( field_data->button &&
attrib == ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
{
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
{
field_data->down = TRUE;
field_data->down_in_btn = TRUE;
xi_draw_field_button( xi_obj );
xi_set_trap_obj( xi_obj );
XinWindowMouseTrap( xi_obj->itf->v.itf->xin_win, TRUE );
}
}
break;
}
case XinEventMouseMove:
if ( field_data->button && field_data->down_in_btn )
{
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) && !field_data->down )
{
field_data->down = TRUE;
xi_draw_field_button( xi_obj );
}
if ( !xi_pt_in_rect( &rct, ep->v.mouse.where ) && field_data->down )
{
field_data->down = FALSE;
xi_draw_field_button( xi_obj );
}
}
break;
case XinEventMouseUp:
if ( field_data->button && field_data->down_in_btn )
{
XinWindowMouseRelease( );
if ( field_data->down )
{
field_data->down = FALSE;
xi_draw_field_button( xi_obj );
}
field_data->down_in_btn = FALSE;
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
{
if ( xi_move_focus( xi_obj ) )
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb( itf, &xiev );
}
}
}
break;
default:
break;
}
}
void
xi_draw_foc_and_dflt( XI_OBJ * xi_obj )
{
XI_OBJ *dflt_obj,
*foc_obj;
XI_BTN_DATA *bd;
BOOLEAN enabled;
BOOLEAN visible;
BOOLEAN focus;
BOOLEAN dflt;
unsigned long attrib;
if ( xi_get_native_controls( xi_obj ) )
return;
dflt_obj = xi_get_default( xi_obj );
if ( dflt_obj )
{
bd = dflt_obj->v.btn;
attrib = xi_get_attrib( dflt_obj );
enabled = ( ( attrib & XI_ATR_ENABLED ) != 0 );
visible = ( ( attrib & XI_ATR_VISIBLE ) != 0 );
focus = ( xi_get_focus( dflt_obj->itf ) == dflt_obj );
dflt = bd->dflt;
xi_draw_button( dflt_obj, &bd->rct, enabled,
visible, focus, bd->down, dflt, bd->checked, FALSE, TRUE );
}
foc_obj = xi_get_focus( xi_obj );
if ( foc_obj && foc_obj->type == XIT_BTN && foc_obj != dflt_obj )
{
bd = foc_obj->v.btn;
attrib = xi_get_attrib( foc_obj );
enabled = ( ( attrib & XI_ATR_ENABLED ) != 0 );
visible = ( ( attrib & XI_ATR_VISIBLE ) != 0 );
focus = TRUE;
dflt = bd->dflt;
xi_draw_button( foc_obj, &bd->rct, enabled,
visible, focus, bd->down, dflt, bd->checked, FALSE, TRUE );
}
}
/* ------------------------------------------------------------------------ */
/* form_event */
/* ------------------------------------------------------------------------ */
static BOOLEAN
form_event( XI_OBJ * xi_obj, XinEvent * ep )
{
BOOLEAN retval = FALSE;
XI_OBJ *focus_obj = xi_obj->itf->v.itf->focus_obj;
XI_OBJ *itf = xi_obj->itf;
BOOLEAN focus_is_cell = (focus_obj != NULL && focus_obj->type == XIT_CELL);
switch ( ep->type )
{
case XinEventMenuCommand:
/* TODO -- navigation */
break;
case XinEventCharacter:
{
long c = event_to_longchar( ep );
XI_OBJ *next_obj = NULL;
/* navigation character event */
if ( ( c == '\r' || c == '\n' ) && xi_obj->itf->v.itf->tab_on_enter
&& xi_obj->type != XIT_BTN )
c = xi_get_pref( XI_PREF_FORM_TAB_CHAR );
if ( c == xi_get_pref( XI_PREF_FORM_TAB_CHAR ) || c == XI_KEY_DOWN )
{
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_FORM_TAB, c );
}
else if ( c == xi_get_pref( XI_PREF_FORM_BACKTAB_CHAR ) ||
c == XI_KEY_UP )
{
next_obj = focus_obj;
do
{
next_obj = xi_find_next_obj( next_obj, XI_NEXT_FORM_BACKTAB, c );
} while ( next_obj != NULL && next_obj != focus_obj &&
( next_obj->type == XIT_FORM || next_obj->type == XIT_CONTAINER ) );
}
if ( next_obj != NULL )
{
xi_move_focus_internal( next_obj, TRUE, TRUE,
( ( c == xi_get_pref( XI_PREF_FORM_TAB_CHAR ) ) || ( c == XI_KEY_DOWN ) ) ? 1 : 2 );
retval = TRUE;
}
if ( next_obj && (focus_is_cell || xi_is_obj( focus_obj, itf )) )
xi_draw_foc_and_dflt_if_necessary( focus_obj, next_obj );
break;
}
default:
break;
}
return retval;
}
/* ------------------------------------------------------------------------ */
/* invalidate_button_rect */
/* ------------------------------------------------------------------------ */
static BOOLEAN
invalidate_button_rect( XI_OBJ * xi_obj, XI_BTN_DATA * bd, XinRect * rct )
{
// if (( bd->type == XIBT_BUTTON || bd->type == XIBT_BUTTON_CHECKBOX ||
// bd->type == XIBT_RADIOBTN ) && bd->drawable || bd->type == XIBT_TABBTN)
if ((( bd->type == XIBT_BUTTON || bd->type == XIBT_BUTTON_CHECKBOX ||
bd->type == XIBT_RADIOBTN ) && bd->drawable) || bd->type == XIBT_TABBTN)
{
XinRect r;
XinWindow win;
r = *rct;
xi_inflate_rect( &r, -4 );
win = xi_get_window( xi_obj->itf );
xi_invalidate_rect( win, &r );
XinWindowPaintForce( win );
return TRUE;
}
return FALSE;
}
/* ------------------------------------------------------------------------ */
/* btn_event */
/* ------------------------------------------------------------------------ */
static BOOLEAN
btn_event( XI_OBJ * xi_obj, XinEvent * ep )
{
BOOLEAN enabled;
BOOLEAN visible;
BOOLEAN focus;
BOOLEAN dflt;
BOOLEAN send_to_form = TRUE;
BOOLEAN ret_val;
XinRect rct;
unsigned long attrib;
XI_BTN_DATA *bd;
if ( !xi_get_native_controls( xi_obj ) )
{
attrib = xi_get_attrib( xi_obj );
enabled = ( ( attrib & XI_ATR_ENABLED ) != 0 );
visible = ( ( attrib & XI_ATR_VISIBLE ) != 0 );
focus = ( xi_get_focus( xi_obj->itf ) == xi_obj );
bd = xi_obj->v.btn;
dflt = bd->dflt;
rct = bd->rct;
switch ( ep->type )
{
case XinEventTimer:
return FALSE;
case XinEventCharacter:
if ( ep->v.character.ch == ' ' && focus )
{
XI_EVENT xiev;
XI_OBJ *itf;
int obj_cid;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
obj_cid = xi_obj->cid;
call_cb( itf, &xiev );
if ( !xi_is_itf( itf ) || xi_get_obj( itf, obj_cid ) == NULL )
send_to_form = FALSE;
}
break;
case XinEventPaint:
xi_draw_button( xi_obj, &rct, enabled,
visible, focus, bd->down, dflt, bd->checked, FALSE, TRUE );
break;
case XinEventMouseDouble:
if ( !xi_get_pref( XI_PREF_DBL_PRESSES_BUTTON ) )
break;
/* else fall through */
case XinEventMouseDown:
{
XinRect hit_rct;
if ( ( enabled == FALSE ) || ( visible == FALSE ) )
break;
hit_rct = rct;
if ( bd->packed == TRUE )
xi_inflate_rect( &hit_rct,
-( ( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH ) ) );
if ( xi_pt_in_rect( &hit_rct, ep->v.mouse.where ) )
{
bd->down = TRUE;
bd->down_in_btn = TRUE;
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
xi_draw_button( xi_obj, &rct, enabled, visible, focus, bd->down,
dflt, bd->checked, FALSE, FALSE );
xi_set_trap_obj( xi_obj );
XinWindowMouseTrap( xi_get_window( xi_obj->itf ), TRUE );
}
break;
}
case XinEventMouseMove:
if ( bd->down_in_btn )
{
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) && !bd->down )
{
bd->down = TRUE;
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
xi_draw_button( xi_obj, &rct, enabled, visible, focus, bd->down,
dflt, bd->checked, FALSE, FALSE );
}
else if ( !xi_pt_in_rect( &rct, ep->v.mouse.where ) &&
bd->down )
{
bd->down = FALSE;
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
xi_draw_button( xi_obj, &rct,
enabled, visible, focus, bd->down, dflt,
bd->checked, FALSE, FALSE );
}
}
break;
case XinEventMouseUp:
if ( bd->down_in_btn )
{
bd->down_in_btn = FALSE;
if ( bd->down )
{
bd->down = FALSE;
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
xi_draw_button( xi_obj, &rct,
enabled, visible, focus, bd->down, dflt,
bd->checked, FALSE, FALSE );
}
XinWindowMouseRelease( );
if ( ep->type == XinEventMouseUp &&
xi_pt_in_rect( &rct, ep->v.mouse.where ) )
{
XI_EVENT xiev;
XI_OBJ *itf;
int obj_cid;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
obj_cid = xi_obj->cid;
call_cb( itf, &xiev );
if ( !xi_is_itf( itf ) || xi_get_obj( itf, obj_cid ) == NULL )
send_to_form = FALSE;
}
}
break;
default:
break;
}
}
ret_val = TRUE;
if ( send_to_form )
ret_val = form_event( xi_obj, ep );
return ret_val;
}
/* ------------------------------------------------------------------------ */
/* draw_list_button */
/* ------------------------------------------------------------------------ */
#define P_OFFSET 3
static void
draw_list_button( XinWindow win, XinRect * rct, BOOLEAN down )
{
#if XIWS != XIWS_WM
int x,
y,
plus_width,
plus_height;
XinPoint p;
XinRect r;
BOOLEAN x2;
r = *rct;
xi_set_clip( win, NULL ); // XI forgot this!
XinWindowPenSet( win, &black_cpen );
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_rect( win, &r );
xi_inflate_rect(&r, -1);
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
{
const XinColor color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
const XinColor color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
const XinColor color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
xi_draw_shaded_rect(win, &r, down, 2, color_light, color_ctrl, color_dark);
}
else
{
XinWindowBrushSet( win, &white_cbrush );
xi_draw_rect( win, &r );
}
p.h = rct->left;
p.v = rct->top - 1;
XinWindowPenSet( win, &black_cpen );
xi_move_to( win, p );
p.h = rct->right;
xi_draw_line( win, p );
plus_width = r.right - r.left;
plus_height = plus_width + 4;
x = r.left + plus_width / 2;
y = r.top + plus_height / 2;
x2 = !( ( r.right + r.left ) % 2 );
if ( x2 )
x--;
y--;
XinWindowPenSet( win, &black_cpen );
/* draw vertical lines */
p.h = x;
p.v = r.top + P_OFFSET + down;
xi_move_to( win, p );
p.v = r.top + plus_height - P_OFFSET + down;
xi_draw_line( win, p );
p.h = x + 1;
p.v = r.top + P_OFFSET + down;
xi_move_to( win, p );
p.v = r.top + plus_height - P_OFFSET + down;
xi_draw_line( win, p );
/* draw horizontal lines */
p.v = y + down;
p.h = r.left + P_OFFSET;
xi_move_to( win, p );
p.h = r.left + plus_width - P_OFFSET;
xi_draw_line( win, p );
p.v = y + down + 1;
p.h = r.left + P_OFFSET;
xi_move_to( win, p );
p.h = r.left + plus_width - P_OFFSET;
xi_draw_line( win, p );
#else
NOREF( rct );
NOREF( down );
NOREF( win );
#endif
}
/* ------------------------------------------------------------------------ */
/* list_event */
/* ------------------------------------------------------------------------ */
static void
list_event( XI_OBJ * xi_obj, XinEvent * ep )
{
XI_LIST_DATA *list_data;
XinRect rct;
LM_DATA *lmp;
list_data = xi_obj->v.list;
lmp = ( LM_DATA * ) list_data->lm;
if ( lmp->attrib & XI_ATR_VISIBLE )
{
rct = list_data->sbb_rct;
switch ( ep->type )
{
case XinEventPaint:
if ( list_data->scroll_bar_button )
draw_list_button( lmp->win, &rct, list_data->down );
break;
case XinEventMouseDown:
if ( list_data->scroll_bar_button )
{
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
{
list_data->down = TRUE;
list_data->down_in_btn = TRUE;
draw_list_button( lmp->win, &rct, TRUE );
xi_set_trap_obj( xi_obj );
XinWindowMouseTrap( xi_obj->itf->v.itf->xin_win, TRUE );
}
}
break;
case XinEventMouseMove:
if ( list_data->scroll_bar_button && list_data->down_in_btn )
{
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) && !list_data->down )
{
list_data->down = TRUE;
draw_list_button( lmp->win, &rct, TRUE );
}
if ( !xi_pt_in_rect( &rct, ep->v.mouse.where ) && list_data->down )
{
list_data->down = FALSE;
draw_list_button( lmp->win, &rct, FALSE );
}
}
break;
case XinEventMouseUp:
if ( list_data->scroll_bar_button && list_data->down_in_btn )
{
XinWindowMouseRelease( );
if ( list_data->down )
{
list_data->down = FALSE;
draw_list_button( lmp->win, &rct, FALSE );
}
list_data->down_in_btn = FALSE;
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = xi_obj;
itf = xi_obj->itf;
call_cb( itf, &xiev );
}
}
break;
default:
break;
}
}
}
/* ------------------------------------------------------------------------ */
/* itf_event */
/* ------------------------------------------------------------------------ */
static BOOLEAN
itf_event( XI_OBJ * xi_obj, XinEvent * ep )
{
BOOLEAN retval = FALSE;
XI_ITF_DATA *itf_data;
XI_OBJ *focus_obj;
itf_data = xi_obj->itf->v.itf;
focus_obj = itf_data->focus_obj;
switch ( ep->type )
{
case XinEventMenuCommand:
/* TODO -- navigation */
break;
case XinEventResize:
if ( itf_data->bitmap != NULL
&& xi_bitmap_draw_all_on_resize( itf_data->bitmap ) )
XinWindowRectInvalidate( xi_get_window( xi_obj ), NULL );
break;
case XinEventCharacter:
{
long c = event_to_longchar( ep );
XI_OBJ *next_obj = NULL;
if ( focus_obj->itf != xi_obj )
XinError( 20030, XinSeverityFatal, 0L );
/* navigation character event */
if ( c == xi_get_pref( XI_PREF_ITF_TAB_CHAR ) )
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_ITF_TAB, c );
else if ( c == xi_get_pref( XI_PREF_ITF_BACKTAB_CHAR ) )
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_ITF_BACKTAB,
c );
else if ( c == xi_get_pref( XI_PREF_FORM_TAB_CHAR ) &&
focus_obj->type == XIT_ITF )
next_obj = xi_search_itf( focus_obj, XI_SEARCH_FOR_FOCUSABLE,
0 );
if ( c == '\r' || c == '\n' )
{
XI_OBJ *dflt_obj;
dflt_obj = xi_get_default( xi_obj->itf );
if ( dflt_obj && ( xi_get_attrib( dflt_obj ) & ( XI_ATR_ENABLED
| XI_ATR_VISIBLE ) ) == ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = dflt_obj;
itf = xi_obj->itf;
call_cb( itf, &xiev );
retval = TRUE;
}
}
if ( c == '\033' )
{
XI_OBJ *cancel_obj;
cancel_obj = xi_get_cancel( xi_obj->itf );
if ( cancel_obj && ( xi_get_attrib( cancel_obj ) & ( XI_ATR_ENABLED
| XI_ATR_VISIBLE ) ) == ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = cancel_obj;
itf = xi_obj->itf;
call_cb( itf, &xiev );
retval = TRUE;
}
}
if ( ep->v.character.alt )
{
XI_OBJ *obj;
obj = xi_get_obj_from_mnemonic( xi_obj->itf, ( char ) ep->v.character.ch );
if ( obj )
{
switch ( obj->type )
{
case XIT_BTN:
{
XI_EVENT xiev;
XI_OBJ *itf;
MEMCLEAR( xiev );
xiev.type = XIE_BUTTON;
xiev.v.xi_obj = obj;
itf = xi_obj->itf;
call_cb( itf, &xiev );
ep->v.character.consumed = TRUE;
break;
}
case XIT_FIELD:
xi_move_focus( obj );
ep->v.character.consumed = TRUE;
break;
default:
break;
}
}
}
if ( next_obj != NULL )
{
xi_move_focus_internal( next_obj, TRUE, FALSE, 0 );
retval = TRUE;
}
/* if the last focus was a button, and the current focus is not, or if
* the last focus was not a button, and the current focus is, then draw
* the default button, followed by the focus button. */
if ( xi_is_itf( xi_obj ) )
{
xi_draw_foc_and_dflt_if_necessary( focus_obj, next_obj );
}
break;
}
default:
break;
}
return ( retval );
}
/* ------------------------------------------------------------------------ */
/* draw_rectangles */
/* ------------------------------------------------------------------------ */
static void
draw_rectangles( XI_OBJ* itf )
{
int num, num_members, num_rects, sorted_rects, rect_num;
XI_OBJ** objlist;
XI_OBJ** cur_obj;
XI_OBJ** rect_list;
/* Count the rectangles in the interface */
objlist = xi_get_member_list( itf, &num_members );
num_rects = 0;
for ( num = 0, cur_obj = objlist; num < num_members; num++, cur_obj++ )
if ( (*cur_obj)->type == XIT_RECT )
num_rects++;
if ( num_rects == 0 )
return;
/* Sort rectangles into proper drawing order */
rect_list = (XI_OBJ**)xi_tree_malloc( num_rects * sizeof(XI_OBJ*), NULL );
sorted_rects = 0;
for ( num = 0, cur_obj = objlist; num < num_members; num++, cur_obj++ )
if ( (*cur_obj)->type == XIT_RECT )
{
for ( rect_num = 0; rect_num < sorted_rects; rect_num++ )
{
XinRect intersect;
XinRect* sort_rect = &rect_list[ rect_num ]->v.rect->rct;
XinRectIntersect( &intersect, sort_rect, &(*cur_obj)->v.rect->rct );
if ( intersect.top == sort_rect->top && intersect.bottom == sort_rect->bottom
&& intersect.left == sort_rect->left && intersect.right == sort_rect->right )
break;
}
if ( rect_num == sorted_rects )
rect_list[ sorted_rects++ ] = *cur_obj;
else
{
memmove( rect_list + rect_num + 1, rect_list + rect_num,
( sorted_rects - rect_num ) * sizeof(XI_OBJ*) );
rect_list[ rect_num ] = *cur_obj;
sorted_rects++;
}
}
/* Draw rectangles in sorted order */
for ( num = 0; num < num_rects; num++ )
xi_draw_obj( rect_list[ num ] );
}
/* ------------------------------------------------------------------------ */
/* xi_send_event */
/* ------------------------------------------------------------------------ */
static int
xi_send_event( XI_OBJ * xi_obj, XinEvent * ep, BOOLEAN do_subtree )
{
int n;
XI_OBJ **objlist;
BOOLEAN send_to_parent = FALSE;
int retval = 0;
switch ( xi_obj->type )
{
case XIT_TEXT:
case XIT_LINE:
if ( ep->type == XinEventPaint )
xi_draw_obj( xi_obj );
break;
case XIT_FIELD:
field_event( xi_obj, ep );
retval = stx_event( xi_obj->v.field->stx, ep );
send_to_parent = !retval;
/* don't send any character events (for navigation to the parent if
* pasting */
if ( ep->type == XinEventCharacter && xi_obj->itf->v.itf->pasting )
send_to_parent = FALSE;
break;
case XIT_CONTAINER:
send_to_parent = TRUE;
break;
case XIT_FORM:
send_to_parent = !form_event( xi_obj, ep );
break;
case XIT_BTN:
send_to_parent = !btn_event( xi_obj, ep );
break;
case XIT_LIST:
{
XI_OBJ *itf;
itf = xi_obj->itf;
if ( xi_obj->itf->v.itf->update_obj )
{
lm_event( itf, xi_obj->v.list->lm, ep );
send_to_parent = FALSE;
do_subtree = FALSE;
}
else
{
list_event( xi_obj, ep );
retval = lm_event( itf, xi_obj->v.list->lm, ep );
send_to_parent = !retval;
/* Don't broadcast events to columns */
do_subtree = FALSE;
}
if ( xi_is_itf( itf ) )
if ( xi_obj->itf->v.itf->pasting )
send_to_parent = FALSE;
break;
}
case XIT_ITF:
itf_event( xi_obj, ep );
break;
case XIT_CELL:
/* Send events to list as there is no handler for individual cells */
send_to_parent = TRUE;
break;
case XIT_COLUMN:
default:
/* ignored */
break;
}
if ( do_subtree && xi_obj->type != XIT_GROUP )
{
int retval;
XI_OBJ *itf = xi_obj->itf;
if ( xi_obj->type == XIT_ITF && ep->type == XinEventPaint )
draw_rectangles( xi_obj );
/* loop over sub-objects */
objlist = xi_get_member_list( xi_obj, &n );
for ( ; n > 0; n--, objlist++ )
{
retval = xi_send_event( *objlist, ep, do_subtree );
if (!xi_is_itf( itf ))
return retval;
/* after everything else is drawn, then if focus is on a button, draw it,
* and if there is a default button, draw it. */
if ( retval )
{
if ( xi_obj->type == XIT_ITF && ep->type == XinEventPaint )
xi_draw_foc_and_dflt( xi_obj );
return retval;
}
}
if ( xi_obj->type == XIT_ITF && ep->type == XinEventPaint )
xi_draw_foc_and_dflt( xi_obj );
}
if ( send_to_parent )
{
retval = xi_send_event( xi_obj->parent, ep, FALSE );
return retval;
}
return retval;
}
void
xi_event( XinWindow win, XinEvent * ep )
{
XI_OBJ *itf;
XI_EVENT xiev;
XI_ITF_DATA *itf_data;
BOOLEAN retval;
XinCursor new_cursor;
if ( win == XI_NULL_WINDOW )
win = XinWindowFocusGet( );
if ( win == XI_NULL_WINDOW )
return;
if ( ( itf = xi_get_itf( win ) ) == NULL )
{
if ( ep->type == XinEventCreate && xi_creating_itf != NULL )
{
xi_finish_interface_create( win );
xi_creating_itf = NULL;
if ( ( itf = xi_get_itf( win ) ) == NULL )
return;
if ( itf->v.itf->dequeue == XI_DEQUEUE_INIT && itf->v.itf->modal_wait )
{
xi_dequeue( );
itf->v.itf->dequeue = XI_DEQUEUE_COMPLETE;
}
}
else
return;
}
itf_data = itf->v.itf;
MEMCLEAR( xiev );
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
{
xiev.type = XIE_XIN_EVENT;
xiev.v.xin_event = *ep;
}
#ifdef XI_USE_XVT
else
{
xiev.type = XIE_XVT_EVENT;
XinXvtEventGet( &xiev.v.xvte );
}
#endif
xiev.refused = FALSE;
if ( !call_cb( itf, &xiev ) )
return;
if ( xiev.refused )
return;
/* RGM: Do we need to allow the event to change with R3 support? */
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
*ep = xiev.v.xin_event;
if ( ep->type == XinEventMouseUp )
XinWindowMouseRelease( );
if ( !xi_eh( win, ep ) )
return;
if ( itf_data->dequeue == XI_DEQUEUE_CALL && !itf_data->modal_wait )
{
xi_dequeue( );
itf_data->dequeue = XI_DEQUEUE_COMPLETE;
if (itf_data->needs_update)
XinWindowRectInvalidate( itf_data->xin_win, NULL );
}
MEMCLEAR( xiev );
switch ( ep->type )
{
case XinEventTimer:
{
xi_send_event( itf, ep, TRUE );
break;
}
case XinEventPaint:
{
if ( itf_data->dequeue != XI_DEQUEUE_COMPLETE )
{
itf_data->needs_update = TRUE;
do_post_event( itf, ep );
return;
}
if ( itf_data->update_obj )
{
xi_send_event( itf_data->update_obj, ep, FALSE );
itf_data->update_obj = NULL;
}
else
{
itf->v.itf->half_baked = FALSE;
draw_background( itf );
xi_send_event( itf, ep, TRUE );
}
break;
}
case XinEventMouseDown:
case XinEventMouseDouble:
{
XI_OBJ *itf2;
itf2 = itf;
itf_data->mouse_is_down = TRUE;
xi_send_event( itf, ep, TRUE );
if ( xi_is_itf( itf2 ) )
if ( !itf_data->trap_explicit )
itf_data->trap_obj = itf_data->focus_obj;
break;
}
case XinEventCharacter:
if ( ep->v.character.ch == XI_KEY_BTAB )
ep->v.character.shift = FALSE;
if ( itf_data->focus_obj != NULL )
xi_send_event( itf_data->focus_obj, ep, FALSE );
update_menus( );
break;
case XinEventResize:
xi_send_event( itf, ep, TRUE );
break;
case XinEventMouseUp:
#ifndef NO_PRIMARY_SELECTION
#if XIWS == XIWS_XM
if ( ep->v.mouse.button == 2 )
get_primary_selection( itf, win );
#endif
#endif
itf_data->mouse_is_down = FALSE;
if ( xi_get_drag_list_obj( ) )
lm_event( itf, xi_get_drag_list_obj( )->v.list->lm, ep );
else if ( itf_data->trap_obj != NULL )
xi_send_event( itf_data->trap_obj, ep, FALSE );
if ( xi_is_itf( itf ) )
{
itf_data->trap_obj = NULL;
itf_data->trap_explicit = FALSE;
update_menus( );
}
break;
case XinEventMouseMove:
if ( xi_get_drag_list_obj( ) )
lm_event( itf, xi_get_drag_list_obj( )->v.list->lm, ep );
else if ( itf_data->trap_obj != NULL )
xi_send_event( itf_data->trap_obj, ep, FALSE );
else
{
if ( !itf_data->mouse_is_down )
{
retval = xi_send_event( itf, ep, TRUE );
switch ( retval )
{
case 0:
new_cursor = XI_CURSOR_ARROW;
break;
case 1:
new_cursor = XI_CURSOR_IBEAM;
break;
case 2:
new_cursor = ( XinCursor) xi_get_pref( XI_PREF_SIZE_CURSOR_RID );
break;
case 3:
new_cursor = ( XinCursor ) xi_get_pref( XI_PREF_HAND_CURSOR_RID );
break;
case 4:
new_cursor = XI_CURSOR_CROSS;
break;
case 5:
new_cursor = XI_CURSOR_ARROW;
break;
case 6:
new_cursor =
( XinCursor ) xi_get_pref( XI_PREF_VSIZE_CURSOR_RID );
break;
default:
new_cursor = XI_CURSOR_ARROW;
break;
}
if ( itf_data->cursor != new_cursor && !itf_data->cursor_override )
{
XinWindowCursorSet( itf_data->xin_win, new_cursor );
itf_data->cursor = new_cursor;
}
}
}
break;
case XinEventMenuCommand:
{
XinWindow win;
xiev.v.cmd.tag = ep->v.menu_command.tag;
xiev.v.cmd.shift = ep->v.menu_command.shift;
xiev.v.cmd.control = ep->v.menu_command.control;
xiev.type = XIE_COMMAND;
win = itf_data->xin_win;
call_cb( itf, &xiev );
if ( xi_is_window( win ) )
if ( itf_data->focus_obj != NULL )
xi_send_event( itf_data->focus_obj, ep, FALSE );
}
if ( xi_is_itf( itf ) )
do_edit_menu( itf, ep );
break;
case XinEventFocus:
update_menus( );
break;
case XinEventDestroy:
{
itf->v.itf->in_event_destroy = TRUE;
destroy_controls( itf );
#ifdef XI_USE_TX_SUPPORT
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
xi_xvt_tx_event( win, ep );
#endif
xiev.type = XIE_CLEANUP;
xiev.v.xi_obj = itf;
call_cb( itf, &xiev );
xi_remove_window_from_list( win );
/* free the whole interface tree */
xi_tree_free( ( char * ) itf );
break;
}
case XinEventCloseButton:
xiev.type = XIE_CLOSE;
xiev.v.xi_obj = itf;
call_cb( itf, &xiev );
if ( xi_is_itf( itf ) && !xiev.refused )
xi_delete( itf );
break;
case XinEventQuit:
if ( ep->v.quit.query )
XinAppQuitOk( );
else
XinAppTerminate( );
break;
case XinEventHScroll:
case XinEventVScroll:
/* handle XinEventHScroll, etc if list is using window scroll bars */
break;
case XinEventControl:
control_event( itf, win, ep );
update_menus( );
break;
case XinEventHelp:
{
XI_OBJ *focus = xi_get_focus( itf );
if (focus != NULL && focus->help_key != NULL)
XinNativeHelp( win, focus->help_key );
else if ( itf->help_key != NULL )
XinNativeHelp( win, itf->help_key );
break;
}
default:
break;
}
if ( ep->type == XinEventPaint )
{
/* send XVT event */
MEMCLEAR( xiev );
xiev.type = XIE_UPDATE;
xiev.v.xin_event = *ep;
xiev.refused = FALSE;
call_cb( itf, &xiev );
xi_set_clip( xi_get_window( itf ), NULL );
}
do_post_event( itf, ep );
}
long
xi_get_app_data( XI_OBJ * xi_obj )
{
return ( xi_obj->app_data );
}
long
xi_get_app_data2( XI_OBJ * xi_obj )
{
return ( xi_obj->app_data2 );
}
unsigned long
xi_get_attrib( XI_OBJ * xi_obj )
{
switch ( xi_obj->type )
{
case XIT_COLUMN:
return ( lm_get_attrib( xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx( xi_obj ), 0, FALSE ) );
case XIT_LIST:
return ( lm_get_attrib( xi_obj->v.list->lm, LM_LIST, 0, 0, FALSE ) );
case XIT_ROW:
return ( lm_get_attrib( xi_obj->parent->v.list->lm, LM_ROW,
xi_obj->v.row, 0, FALSE ) );
case XIT_CELL:
return ( lm_get_attrib( xi_obj->parent->v.list->lm, LM_CELL,
xi_obj->v.cell.row, xi_obj->v.cell.column,
xi_obj->v.cell.is_vert_scrolled ) );
case XIT_BTN:
return ( xi_obj->v.btn->attrib );
case XIT_CONTAINER:
/* pretend that containers have attributes, and that they are always
* visible and enabled */
return XI_ATR_ENABLED | XI_ATR_VISIBLE;
case XIT_FORM:
return ( xi_obj->v.form->attrib );
case XIT_FIELD:
return ( stx_get_attrib( xi_obj->v.field->stx ) );
case XIT_TEXT:
return ( xi_obj->v.text->attrib );
case XIT_LINE:
return ( xi_obj->v.line->attrib );
case XIT_RECT:
return ( xi_obj->v.rect->attrib );
case XIT_GROUP:
return 0L;
default:
XinError( 20018, XinSeverityFatal, 0L );
}
return 0L;
}
XI_OBJ *
xi_get_focus( XI_OBJ * itf )
{
XinWindow win;
if ( itf != NULL )
return ( itf->v.itf->focus_obj );
else if ( ( win = XinWindowFocusGet( ) ) == XI_NULL_WINDOW )
return ( NULL );
else if ( xi_is_window( win ) )
{
XI_OBJ *itf;
itf = xi_get_itf( win );
return ( itf->v.itf->focus_obj );
}
else
return ( NULL );
}
long *
xi_get_list_info( XI_OBJ * xi_obj, int *nbr_recs )
{
if ( xi_obj->type != XIT_LIST )
XinError( 20020, XinSeverityFatal, 0L );
return lm_get_list_info( xi_obj->v.list->lm, nbr_recs );
}
XI_OBJ **
xi_get_member_list( XI_OBJ * xi_obj, int *nbr_members )
{
int i;
XI_OBJ *obj;
XI_GROUP_DATA *groupdata;
if ( xi_obj->type == XIT_GROUP )
{
groupdata = xi_obj->v.group;
if ( groupdata->objlist != NULL )
xi_tree_free( groupdata->objlist );
groupdata->objlist =
( XI_OBJ * * ) xi_tree_malloc( sizeof( XI_OBJ * ) * groupdata->nbr_cids, xi_obj );
*nbr_members = 0;
for ( i = 0; i < groupdata->nbr_cids; i++ )
{
obj = xi_get_obj( xi_obj->itf, groupdata->cidlist[i] );
if ( obj != NULL )
{
groupdata->objlist[*nbr_members] = obj;
( *nbr_members )++;
}
}
return ( groupdata->objlist );
}
else
{
*nbr_members = xi_obj->nbr_children;
return ( xi_obj->children );
}
}
/*
xi_get_obj: retrieve an XI_OBJ from the interface tree given its cid.
Although externally documented to work only on XIT_ITF,
this will start searching at any point in the interface tree.
xi_get_obj will ignore NULL objects so it can be used in the middle
of creating an interface tree.
*/
XI_OBJ *
xi_get_obj( XI_OBJ * obj, int cid )
{
XI_OBJ **objlist;
XI_OBJ *temp;
int n;
if ( obj->cid == cid )
return ( obj );
switch ( obj->type )
{
case XIT_GROUP:
case XIT_CELL:
case XIT_ROW:
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_ASSERT_ON_NULL_CID ) )
XinError( 30207, XinSeverityFatal, 0L );
return ( NULL );
default:
break;
}
/* search in child list */
objlist = xi_get_member_list( obj, &n );
for ( ; n > 0; n--, objlist++ )
{
/* call recursively for generality in future versions */
if ( ( temp = xi_get_obj( *objlist, cid ) ) != NULL )
return ( temp );
}
return ( NULL );
}
XinRect *
xi_get_rect( XI_OBJ * xi_obj, XinRect * rctp )
{
return xi_get_rect_internal( xi_obj, rctp, NULL, NULL );
}
XinRect *
xi_get_rect_internal( XI_OBJ * xi_obj, XinRect * rctp, XinRect * old_win_rct, XinRect * new_win_rct )
{
XI_OBJ **objp;
XinRect rct;
int i,
n;
switch ( xi_obj->type )
{
case XIT_CONTAINER:
*rctp = xi_obj->v.container->rct;
break;
case XIT_BTN:
*rctp = xi_obj->v.btn->rct;
break;
case XIT_COLUMN:
lm_get_rect( xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx( xi_obj ), rctp );
break;
case XIT_ROW:
if ( xi_obj->v.row_data.is_vert_scrolled )
memset( ( char * ) rctp, 0, sizeof( *rctp ) );
else
{
lm_get_rect( xi_obj->parent->v.list->lm, LM_ROW,
xi_obj->v.row, rctp );
}
break;
case XIT_LIST:
lm_get_rect( xi_obj->v.list->lm, LM_LIST, 0, rctp );
if ( xi_obj->v.list->scroll_bar )
{
xi_get_sb_rect( xi_obj, &rct );
rctp->right = rct.right;
}
if ( xi_obj->v.list->width )
{
xi_get_hsb_rect( xi_obj, &rct );
rctp->bottom = rct.bottom;
}
if ( old_win_rct )
{
rctp->bottom = ( int ) ( ( long ) rctp->bottom * new_win_rct->bottom / old_win_rct->bottom );
rctp->right = ( int ) ( ( long ) rctp->right * new_win_rct->right / old_win_rct->right );
}
break;
case XIT_ITF:
case XIT_FORM:
{
BOOLEAN first_rect = TRUE;
objp = xi_obj->children;
n = xi_obj->nbr_children;
for ( i = 0; i < n; objp++, i++ )
{
if ( xi_get_rect_internal( *objp, &rct, old_win_rct, new_win_rct ) != NULL )
{
if ( first_rect )
{
first_rect = FALSE;
*rctp = rct;
}
else
XinRectEnclose( rctp, &rct, rctp );
}
}
break;
}
case XIT_FIELD:
{
XI_FIELD_DATA *fd;
fd = xi_obj->v.field;
stx_get_rect( fd->stx, rctp );
if ( fd->button )
{
if ( fd->button_on_left )
rctp->left = fd->btn_rct.left;
else
rctp->right = fd->btn_rct.right;
}
break;
}
case XIT_TEXT:
*rctp = xi_obj->v.text->rct;
break;
case XIT_RECT:
*rctp = xi_obj->v.rect->rct;
break;
case XIT_LINE:
{
XI_LINE_DATA *line;
line = xi_obj->v.line;
rctp->top = min( line->pnt1.v, line->pnt2.v );
rctp->bottom = max( line->pnt1.v, line->pnt2.v );
rctp->left = min( line->pnt1.h, line->pnt2.h );
rctp->right = max( line->pnt1.h, line->pnt2.h );
break;
}
case XIT_GROUP:
/* bounding rect is undefined */
return ( NULL );
case XIT_CELL:
{
XI_OBJ row;
XI_OBJ *col;
XI_OBJ **members;
int nbr_members;
int row_nbr,
col_nbr;
XinRect row_rct,
col_rct;
if ( xi_obj->v.cell.is_vert_scrolled )
memset( ( char * ) rctp, 0, sizeof( *rctp ) );
else
{
row_nbr = xi_obj->v.cell.row;
col_nbr = xi_obj->v.cell.column;
XI_MAKE_ROW( &row, xi_obj->parent, row_nbr );
xi_get_rect_internal( &row, &row_rct, old_win_rct, new_win_rct );
members = xi_get_member_list( xi_obj->parent, &nbr_members );
col = members[col_nbr];
xi_get_rect_internal( col, &col_rct, old_win_rct, new_win_rct );
xi_rect_intersect( rctp, &row_rct, &col_rct );
}
break;
}
default:
XinError( 20021, XinSeverityFatal, 0L );
}
return ( rctp );
}
void
xi_set_rect_internal( XI_OBJ * xi_obj, XinRect * rctp )
{
switch ( xi_obj->type )
{
case XIT_CONTAINER:
{
xi_container_set_rect_internal( xi_obj, rctp );
break;
}
case XIT_BTN:
xi_obj->v.btn->rct = *rctp;
break;
case XIT_LIST:
lm_set_rect( xi_obj->v.list->lm, rctp );
break;
case XIT_FIELD:
{
xi_field_set_rect_internal( xi_obj, rctp );
break;
}
case XIT_TEXT:
xi_obj->v.text->rct = *rctp;
break;
case XIT_RECT:
xi_obj->v.rect->rct = *rctp;
break;
case XIT_LINE:
{
/* We generate a point which is the change between old and new. */
XI_LINE_DATA *line;
XinPoint point;
line = xi_obj->v.line;
point.v = min( line->pnt1.v, line->pnt2.v );
point.v = rctp->top - point.v;
point.h = min( line->pnt1.h, line->pnt2.h );
point.h = rctp->left - point.h;
line->pnt1.v += point.v;
line->pnt1.h += point.h;
line->pnt2.v += point.v;
line->pnt2.h += point.h;
break;
}
default:
XinError( 20032, XinSeverityFatal, 0L );
}
}
void
xi_set_rect( XI_OBJ * xi_obj, XinRect * rctp, BOOLEAN do_invalidates )
{
XinRect old_rect;
XinWindow win = 0L;
if (do_invalidates)
{
win = xi_get_window( xi_obj );
xi_get_rect_internal( xi_obj, &old_rect, NULL, NULL );
XinWindowRectInvalidate( win, &old_rect );
}
xi_set_rect_internal( xi_obj, rctp );
if (do_invalidates)
{
xi_get_rect_internal( xi_obj, &old_rect, NULL, NULL );
XinWindowRectInvalidate( win, &old_rect );
}
}
void
xi_get_sel( XI_OBJ * xi_obj, int *selstart, int *selstop )
{
XI_OBJ *focus_obj;
BOOLEAN is_focus;
focus_obj = xi_get_focus( xi_obj->itf );
/* check if the passed object is the focus object */
if ( focus_obj == NULL )
is_focus = FALSE; /* no focus */
else if ( focus_obj == xi_obj )
is_focus = TRUE; /* object is the focus object */
else if ( focus_obj->type != XIT_CELL || xi_obj->type != XIT_CELL )
is_focus = FALSE; /* objects are not both cells */
else /* both objects are temporary cell objects */
is_focus = ( xi_obj->v.cell.row == focus_obj->v.cell.row
&& xi_obj->v.cell.column == focus_obj->v.cell.column );
/* it's the focus if the row & column are */
/* the same */
if ( !is_focus )
{
/* selection is only valid for focus object */
*selstart = *selstop = 0;
return;
}
switch ( xi_obj->type )
{
case XIT_CELL:
if ( focus_obj->v.cell.is_vert_scrolled )
lm_focus_cell_selection_get( ( LM_DATA * ) xi_obj->parent->v.list->lm, selstart, selstop );
else
lm_get_sel( xi_obj->parent->v.list->lm, selstart, selstop );
break;
case XIT_FIELD:
stx_get_sel( xi_obj->v.field->stx, selstart, selstop );
break;
case XIT_COLUMN:
case XIT_ITF:
case XIT_LIST:
case XIT_ROW:
case XIT_BTN:
case XIT_FORM:
case XIT_GROUP:
case XIT_TEXT:
XinError( 20022, XinSeverityFatal, 0L );
break;
default:
break;
}
}
char *
xi_get_text( XI_OBJ * xi_obj, char *s, int len )
{
char *b;
b = NULL;
switch ( xi_obj->type )
{
case XIT_CELL:
b = lm_get_text( xi_obj->parent->v.list->lm, s, len,
xi_obj->v.cell.row, xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled );
break;
case XIT_COLUMN:
b = lm_get_text( xi_obj->parent->v.list->lm, s, len,
LM_HEADING_TEXT, xi_obj_to_idx( xi_obj ), FALSE );
break;
case XIT_ITF:
b = XinWindowTitleGet( xi_obj->v.itf->xin_win );
break;
case XIT_ROW:
XinError( 20023, XinSeverityFatal, 0L );
case XIT_BTN:
b = xi_obj->v.btn->text;
break;
case XIT_FIELD:
b = stx_get_text( xi_obj->v.field->stx, s, len );
break;
case XIT_TEXT:
{
XI_TEXT_DATA *text_data;
text_data = xi_obj->v.text;
b = text_data->text;
}
break;
case XIT_LIST:
case XIT_GROUP:
case XIT_FORM:
if ( s )
*s = '\0';
break;
default:
break;
}
if ( s && b )
tstrncpy( s, b, len );
return b;
}
XinWindow
xi_get_window( XI_OBJ * xi_obj )
{
return ( xi_obj->itf->v.itf->xin_win );
}
/*-------------------------------------------------------------------------
function: xi_scroll_rec
xi_obj: list object to scroll. Must be a list object.
rec: first record to go to
color: color of row
attrib: attribute of row
-------------------------------------------------------------------------*/
int
xi_scroll_rec( XI_OBJ * xi_obj, long rec, XinColor color, unsigned long attrib, int row_height )
{
LM_SCROLL_ARG arg;
if ( xi_obj->type != XIT_LIST )
XinError( 20024, XinSeverityFatal, 0L );
xi_obj->v.list->done_initial_xi_scroll = TRUE;
MEMCLEAR( arg );
arg.lm = xi_obj->v.list->lm;
/* arg.nbr_lines = 0; arg.percent = 0; arg.same_cell = 0; */
arg.rec = rec;
arg.have_rec = TRUE;
arg.color = color;
arg.attrib = attrib;
arg.row_height = row_height;
arg.rec_at_top = TRUE;
return lm_scroll( &arg );
}
/*
typedef struct _xi_scroll_record_arg
{
XI_OBJ* xi_obj;
long record;
COLOR row_color;
unsigned long attrib;
int row_height;
BOOLEAN rec_at_top;
} XI_SCROLL_RECORD_ARG;
*/
int
xi_scroll_record( XI_SCROLL_RECORD_ARG * arg )
{
LM_SCROLL_ARG lm_scroll_arg;
XI_OBJ *xi_obj = arg->xi_obj;
xi_obj->v.list->done_initial_xi_scroll = TRUE;
MEMCLEAR( lm_scroll_arg );
lm_scroll_arg.lm = xi_obj->v.list->lm;
/* lm_scroll_arg.nbr_lines = 0; lm_scroll_arg.percent = 0;
* lm_scroll_arg.same_cell = 0; */
lm_scroll_arg.rec = arg->record;
lm_scroll_arg.have_rec = TRUE;
lm_scroll_arg.color = arg->row_color;
lm_scroll_arg.attrib = arg->attrib;
lm_scroll_arg.row_height = arg->row_height;
lm_scroll_arg.rec_at_top = arg->rec_at_top;
return lm_scroll( &lm_scroll_arg );
}
/*-------------------------------------------------------------------------
function: xi_scroll_internal
xi_obj: list object to scroll. Must be a list object.
nbr_lines: nbr of lines to scroll, may be positive or negative, may be set
to XI_SCROLL_FIRST, XI_SCROLL_LAST, XI_SCROLL_PGUP, or XI_SCROLL_PGDN
percent: passed with XI_SCROLL_FIRST event
same_cell: sometimes the focus goes back onto the same cell. In other cases,
for instance, XI_SCROLL_FIRST, XI_SCROLL_LAST, XI_SCROLL_PGUP, and
XI_SCROLL_PGDN, we don't want to put the focus back on the same cell,
but instead, want to put the focus on the first or last fully visible
row.
invalidate: indicates whether to invalidate the list. This is only set to FALSE when xi_scroll_internal is
called when the interface is created.
-------------------------------------------------------------------------*/
int
xi_scroll_internal( XI_OBJ * xi_obj, int nbr_lines, int percent,
BOOLEAN same_cell )
{
LM_SCROLL_ARG arg;
if ( xi_obj->type != XIT_LIST )
XinError( 20037, XinSeverityFatal, 0L );
xi_obj->v.list->done_initial_xi_scroll = TRUE;
MEMCLEAR( arg );
arg.lm = xi_obj->v.list->lm;
arg.nbr_lines = nbr_lines;
arg.percent = percent;
arg.same_cell = same_cell;
arg.rec_at_top = TRUE;
/* arg.rec = 0; arg.have_rec = FALSE; arg.color = 0L; arg.attrib = 0L;
* arg.row_height = 0; */
return lm_scroll( &arg );
}
BOOLEAN
xi_delete_row( XI_OBJ * xi_obj )
{
int row;
XI_OBJ *list_obj;
BOOLEAN rv;
if ( xi_obj->type != XIT_ROW )
XinError( 20025, XinSeverityFatal, 0L );
list_obj = xi_obj->parent;
row = xi_obj->v.row;
rv = lm_delete_row( list_obj->v.list->lm, row );
return rv;
}
BOOLEAN
xi_insert_row( XI_OBJ * list, int row )
{
BOOLEAN rv;
if ( list->type != XIT_LIST )
XinError( 20026, XinSeverityFatal, 0L );
rv = lm_insert_row( list->v.list->lm, row );
return rv;
}
int
xi_scroll( XI_OBJ * xi_obj, int nbr_lines )
{
return ( xi_scroll_internal( xi_obj, nbr_lines, 0, ( BOOLEAN ) ( nbr_lines < 1000 ) ) );
}
int
xi_scroll_percent( XI_OBJ * xi_obj, int percent )
{
return ( xi_scroll_internal( xi_obj, XI_SCROLL_FIRST, percent, FALSE ) );
}
void
xi_set_app_data( XI_OBJ * xi_obj, long app_data )
{
xi_obj->app_data = app_data;
}
void
xi_set_app_data2( XI_OBJ * xi_obj, long app_data )
{
xi_obj->app_data2 = app_data;
}
void
xi_set_fore_color( XI_OBJ * xi_obj, XinColor color )
{
XinRect rct;
switch ( xi_obj->type )
{
case XIT_ROW:
lm_set_color( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row,
0, FALSE, color, FALSE );
break;
case XIT_CELL:
{
LM_DATA *lmp = LMP( xi_obj->parent->v.list->lm );
int idx = xi_obj->v.cell.row;
int idx2 = xi_obj->v.cell.column;
BOOLEAN do_redraw = ( lmp->cell_data[idx][idx2].color != color );
lm_set_color( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled, color,
FALSE );
if ( do_redraw )
{
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
}
break;
}
default:
break;
}
}
void
xi_set_attrib( XI_OBJ * xi_obj, unsigned long attrib )
{
int n;
XI_OBJ **objlist;
unsigned long attrib_diff;
XinWindow win = xi_obj->itf->v.itf->xin_win;
attrib_diff = xi_get_attrib( xi_obj ) ^ attrib;
if ( !( attrib & XI_ATR_VISIBLE ) )
{
XI_OBJ *focus_obj,
*next_obj;
focus_obj = xi_get_focus( xi_obj->itf );
if ( focus_obj == xi_obj ||
( focus_obj != NULL && focus_obj->type == XIT_CELL && focus_obj->parent == xi_obj ) )
{
if ( xi_obj->itf->v.itf->moving_focus )
return;
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_ITF_TAB,
XI_PREF_ITF_TAB_CHAR );
if ( next_obj == focus_obj || ( focus_obj->type == XIT_CELL && focus_obj->parent == next_obj ) )
next_obj = next_obj->itf;
xi_move_focus( next_obj );
}
}
switch ( xi_obj->type )
{
case XIT_BTN:
if ( !xi_get_native_controls( xi_obj ) )
{
XI_BTN_DATA *bd;
XinRect r;
bd = xi_obj->v.btn;
r = bd->rct;
if ( bd->type == XIBT_TABBTN )
r.bottom += 2;
xi_invalidate_rect( win, &r );
}
else
{
if ( attrib_diff & XI_ATR_VISIBLE )
{
XinWindow btn_win;
btn_win = xi_obj->v.btn->btnctl;
XinWindowShow( btn_win, ( BOOLEAN ) ( ( attrib & XI_ATR_VISIBLE )
!= 0 ) );
xi_invalidate_rect( win, &xi_obj->v.btn->rct );
}
if ( attrib_diff & XI_ATR_ENABLED )
XinWindowEnable( xi_obj->v.btn->btnctl,
( BOOLEAN ) ( ( attrib & XI_ATR_ENABLED ) != 0 ) );
}
xi_obj->v.btn->attrib = attrib;
break;
case XIT_FORM:
/* loop over sub-objects */
objlist = xi_get_member_list( xi_obj, &n );
for ( ; n > 0; n--, objlist++ )
xi_set_attrib( *objlist, attrib );
break;
case XIT_FIELD:
{
XinRect rct;
XI_FIELD_DATA *fd;
stx_set_attrib( xi_obj->v.field->stx, attrib );
fd = xi_obj->v.field;
rct = fd->rct;
if ( fd->button )
if ( !fd->button_on_left )
rct.right = fd->btn_rct.right;
xi_invalidate_rect( win, &rct );
break;
}
case XIT_GROUP:
/* it is not clear how to get the proper behaviour here */
break;
case XIT_LINE:
{
XinRect rct;
XI_LINE_DATA *ld;
ld = xi_obj->v.line;
rct.top = min( ld->pnt1.v, ld->pnt2.v );
rct.bottom = max( ld->pnt1.v, ld->pnt2.v );
rct.left = min( ld->pnt1.h, ld->pnt2.h );
rct.right = max( ld->pnt1.h, ld->pnt2.h );
--rct.top;
rct.bottom += 3;
--rct.left;
rct.right += 3;
xi_obj->v.line->attrib = attrib;
xi_invalidate_rect( win, &rct );
break;
}
case XIT_RECT:
xi_obj->v.rect->attrib = attrib;
xi_invalidate_rect( win, &xi_obj->v.rect->rct );
break;
case XIT_TEXT:
xi_obj->v.text->attrib = attrib;
xi_invalidate_rect( win, &xi_obj->v.text->rct );
break;
case XIT_ITF:
/* it is not clear how to get the proper behaviour here */
break;
case XIT_COLUMN:
lm_set_attrib( xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx( xi_obj ), 0, FALSE, attrib, FALSE );
break;
case XIT_LIST:
{
XI_LIST_DATA *ld;
ld = xi_obj->v.list;
if ( attrib & XI_ATR_VISIBLE && !ld->done_initial_xi_scroll )
{
ld->done_initial_xi_scroll = TRUE;
xi_scroll_internal( xi_obj, XI_SCROLL_FIRST, ld->start_percent, FALSE );
}
lm_set_attrib( ld->lm, LM_LIST, 0, 0, FALSE, attrib, FALSE );
if ( ld->sb_win )
{
XinWindowShow( ld->sb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_VISIBLE ) != 0 ) );
XinWindowEnable( ld->sb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_ENABLED ) != 0 ) );
}
if ( ld->hsb_win )
{
XinWindowShow( ld->hsb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_VISIBLE ) != 0 ) );
XinWindowEnable( ld->hsb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_ENABLED ) != 0 ) );
}
break;
}
case XIT_ROW:
lm_set_attrib( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row, 0, FALSE,
attrib, FALSE );
break;
case XIT_CELL:
lm_set_attrib( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
attrib, FALSE );
break;
default:
XinError( 20027, XinSeverityFatal, 0L );
break;
}
}
void
xi_set_bufsize( XI_OBJ * xi_obj, int size )
{
XI_OBJ **objp;
int i;
switch ( xi_obj->type )
{
case XIT_FIELD:
stx_set_bufsize( xi_obj->v.field->stx, ( short ) size );
break;
case XIT_COLUMN:
lm_set_buf_size( xi_obj->parent->v.list->lm, LM_COLUMN,
xi_obj_to_idx( xi_obj ), size );
break;
case XIT_LIST:
case XIT_FORM:
objp = xi_obj->children;
for ( i = xi_obj->nbr_children; i > 0; i--, objp++ )
xi_set_bufsize( *objp, size );
break;
default:
break;
}
}
void
xi_set_sel( XI_OBJ * xi_obj, int selstart, int selstop )
{
switch ( xi_obj->type )
{
case XIT_CELL:
xi_set_focus( xi_obj );
lm_set_sel( xi_obj->parent->v.list->lm, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
selstart, selstop );
break;
case XIT_FIELD:
xi_set_focus( xi_obj );
stx_set_sel( xi_obj->v.field->stx, selstart, selstop );
break;
case XIT_BTN:
case XIT_FORM:
case XIT_GROUP:
case XIT_TEXT:
case XIT_COLUMN:
case XIT_ITF:
case XIT_LIST:
case XIT_ROW:
XinError( 20028, XinSeverityFatal, 0L );
break;
default:
break;
}
}
void
xi_set_text( XI_OBJ * xi_obj, const char *s )
{
BOOLEAN ddd;
BOOLEAN do_compare = TRUE;
if ( xi_obj == xi_obj->itf->v.itf->focus_obj )
xi_obj->itf->v.itf->chg_flag = FALSE;
if (xi_obj->type == XIT_CELL)
{
XI_OBJ *list = xi_obj->parent;
int row = xi_obj->v.cell.row;
int column = xi_obj->v.cell.column;
LM_DATA *lmp = LMP(list->v.list->lm);
LM_CELL_DATA col_data = lmp->cell_data[row][column];
if (!col_data.valid_data)
do_compare = FALSE;
}
if (do_compare)
{
const size_t buf_size = 256;
char *buf = (char*)XinMemoryAlloc( buf_size );
int cmp = 0;
xi_get_text( xi_obj, buf, buf_size );
cmp = strcmp( s, buf );
XinMemoryFree( buf );
if (!cmp)
return;
}
ddd = !xi_get_native_controls( xi_obj );
switch ( xi_obj->type )
{
case XIT_BTN:
{
XI_BTN_DATA *btn;
btn = xi_obj->v.btn;
btn->text = ( char * ) xi_tree_realloc( btn->text, strlen( s ) + 1 );
strcpy( btn->text, s );
if ( ddd )
{
if ( ( xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE ) != 0 )
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &btn->rct );
}
else
XinWindowTitleSet( btn->btnctl, s );
break;
}
case XIT_CELL:
lm_set_text( xi_obj->parent->v.list->lm, s, xi_obj->v.cell.row,
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled );
break;
case XIT_COLUMN:
lm_set_text( xi_obj->parent->v.list->lm, s, LM_HEADING_TEXT,
xi_obj_to_idx( xi_obj ), FALSE );
break;
case XIT_FIELD:
{
/* XinRect rct; */
stx_set_text( xi_obj->v.field->stx, s );
/* TODO change approach, simply draw text xi_get_rect(xi_obj, &rct);
* xi_invalidate_rect(xi_obj->itf->v.itf->xin_win, &rct); */
break;
}
case XIT_ITF:
XinWindowTitleSet( xi_obj->v.itf->xin_win, s );
break;
case XIT_ROW:
XinError( 20029, XinSeverityFatal, 0L );
case XIT_TEXT:
{
XI_TEXT_DATA *text_data;
XinRect rct;
text_data = xi_obj->v.text;
text_data->text = ( char * ) xi_tree_realloc( text_data->text, strlen( s ) + 1 );
strcpy( text_data->text, s );
if ( ( xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE ) != 0 )
{
xi_get_rect( xi_obj, &rct );
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &rct );
}
break;
}
case XIT_GROUP:
case XIT_FORM:
case XIT_LIST:
break;
default:
break;
}
}
void
xi_set_override_cursor( XI_OBJ* itf, XinCursor cursor, BOOLEAN flag )
{
itf->v.itf->cursor_override = flag;
if ( xi_is_itf( itf ) && flag && itf->v.itf->cursor != cursor )
{
XinWindowCursorSet( itf->v.itf->xin_win, cursor );
itf->v.itf->cursor = cursor;
}
}
XinColor
xi_get_underlying_color( XI_OBJ * itf, XinPoint point )
{
XinColor back_color = itf->v.itf->back_color;
int num, num_members;
XI_OBJ** objlist;
XI_OBJ** cur_obj;
XinRect* back_rect = NULL;
objlist = xi_get_member_list( itf, &num_members );
/* Determine if the point is contained on any rectangles in the itf */
for ( num = 0, cur_obj = objlist; num < num_members; num++, cur_obj++ )
if ( (*cur_obj)->type == XIT_RECT )
{
XinRect intersect;
XinRect* cur_rct = &(*cur_obj)->v.rect->rct;
if (XinRectPointContained( cur_rct, &point ) )
{
if ( back_rect != NULL )
{
XinRectIntersect( &intersect, back_rect, cur_rct );
if ( intersect.top == cur_rct->top
&& intersect.bottom == cur_rct->bottom
&& intersect.left == cur_rct->left
&& intersect.right == cur_rct->right )
{
if ( (*cur_obj)->v.rect->back_color != 0 )
{
back_color = (*cur_obj)->v.rect->back_color;
back_rect = &(*cur_obj)->v.rect->rct;
}
}
}
else
{
if ( (*cur_obj)->v.rect->back_color != 0 )
{
back_color = (*cur_obj)->v.rect->back_color;
back_rect = &(*cur_obj)->v.rect->rct;
}
}
}
}
return back_color;
}
void
xi_draw_button( XI_OBJ * xi_obj, XinRect * rct,
BOOLEAN enabled, BOOLEAN visible, BOOLEAN focus, BOOLEAN down,
BOOLEAN dflt, BOOLEAN checked, BOOLEAN box_only, BOOLEAN draw_border )
{
XI_BTN_DATA *bd;
XinColor fore_color;
XinColor border_color;
XinPen fore_cp;
XinWindow win;
XI_OBJ *itf;
XI_ITF_DATA *id;
int leading,
ascent,
descent;
XI_OBJ *focus_obj;
XinColor color_light = 0L;
XinColor color_ctrl = 0L;
XinColor color_dark = 0L;
if ( !visible )
return;
itf = xi_obj->itf;
id = itf->v.itf;
if ( id->half_baked )
return;
win = xi_get_window( itf );
xi_set_clip( win, NULL );
bd = xi_obj->v.btn;
fore_color = XI_COLOR_BLACK;
if (bd->type == XIBT_BUTTON)
{
color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
}
fore_cp = black_cpen;
if ( bd->fore_color )
{
fore_cp.fore_color = bd->fore_color;
fore_color = bd->fore_color;
}
switch ( bd->type )
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
{
int bline = -1;
XinRect r;
XinPen back_pen;
BOOLEAN cr_ok;
XinPoint pnt;
XinColor underlying_color;
pnt.h = rct->left;
pnt.v = rct->top;
underlying_color = xi_get_underlying_color ( itf, pnt );
r = *rct;
back_pen = black_cpen;
back_pen.fore_color = underlying_color;
XinWindowPenSet( win, &back_pen );
XinWindowBrushSet( win, &hollow_cbrush );
if ( draw_border )
xi_draw_rect( win, &r );
xi_inflate_rect( &r, -1 );
xi_draw_rect( win, &r );
r = *rct;
if ( xi_obj->v.btn->packed == TRUE )
{
int grid_width = ( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH );
xi_inflate_rect( &r, -grid_width );
}
else
{
XI_BTN_TYPE bt;
bt = xi_obj->v.btn->type;
if ( bt == XIBT_BUTTON || bt == XIBT_BUTTON_CHECKBOX ||
bt == XIBT_BUTTON_RADIOBTN )
xi_inflate_rect( &r, -1 ); // Was -3
}
XinWindowDrawModeSet( win, XinDrawModeCopy );
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
xi_draw_shaded_rect( win, &r, ( BOOLEAN ) ( down || bd->checked ), 2, color_light, color_ctrl, color_dark );
else
xi_draw_3d_rect( win, &r, ( BOOLEAN ) ( down || bd->checked ), 2, color_light, color_ctrl, color_dark );
if ( bd->up_icon_rid )
{
int x,
y;
XinRect r2;
x = r.left + 2 + bd->icon_x;
y = r.top + 2 + bd->icon_y;
r2 = r;
xi_inflate_rect( &r2, -2 );
xi_set_clip( win, &r2 );
if ( down || bd->checked) // Guy added bd->checked
xi_draw_icon( win, x, y + 1, bd->down_icon_rid, XI_COLOR_BLACK,
color_ctrl );
else
{
if ( enabled || !bd->disabled_icon_rid )
xi_draw_icon( win, x, y, bd->up_icon_rid, XI_COLOR_BLACK,
color_ctrl );
else
xi_draw_icon( win, x, y, bd->disabled_icon_rid, XI_COLOR_BLACK,
color_ctrl );
}
xi_set_clip( win, NULL );
}
else if ( bd->up_bitmap != NULL )
{
XinRect r2;
r2 = r;
xi_inflate_rect( &r2, -2 );
if ( down )
xi_bitmap_draw( bd->down_bitmap, win, &r2, &r2, FALSE );
else if ( enabled || bd->disabled_bitmap == NULL )
xi_bitmap_draw( bd->up_bitmap, win, &r2, &r2, FALSE );
else
xi_bitmap_draw( bd->disabled_bitmap, win, &r2, &r2, FALSE );
xi_set_clip( win, NULL );
}
else
{
unsigned long attrib;
XinRect text_rect;
// XinColor color;
XinFont *fontp;
attrib = XI_ATR_VCENTER | XI_ATR_HCENTER | XI_ATR_VISIBLE;
if ( enabled )
XinWindowColorTextForeSet( win, fore_color );
else
XinWindowColorTextForeSet( win,
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
text_rect = r;
if ( down )
{
text_rect.top += 2;
text_rect.left += 2;
}
fontp = xi_obj->v.btn->font;
if ( fontp == NULL )
fontp = xi_obj->itf->v.itf->font;
if ( fontp == NULL )
fontp = xi_get_system_font( );
XinWindowColorTextBackSet( win, color_ctrl );
XinWindowTextOpaqueSet( win, FALSE );
XinWindowFontMap( win, fontp );
XinFontMetricsGet( fontp, &leading, &ascent, &descent );
xi_draw_clipped_text( win, fontp, bd->text, &text_rect, &text_rect, attrib, FALSE, 0, -1,
bd->mnemonic, bd->mnemonic_instance, &bline );
}
/* draw the solid line around the button that shows that it will be
* pressed if the user presses cr */
focus_obj = xi_get_focus( itf );
cr_ok = FALSE;
if ( focus_obj && focus_obj->type != XIT_BTN && !xi_cr_is_ok( focus_obj ) )
cr_ok = TRUE;
if ( ( dflt && cr_ok ) || focus )
border_color = XI_COLOR_BLACK;
else
border_color = underlying_color;
if ( draw_border )
{
XinRect rct2;
XinPen pen;
rct2 = r;
xi_inflate_rect( &rct2, 1 );
pen.width = 1;
pen.fore_color = border_color;
pen.pattern = XinPenSolid;
XinWindowPenSet( win, &pen );
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_rect( win, &rct2 );
}
/* draw the dashed line inside the button that shows focus */
if ( focus && bd->up_icon_rid == 0 && bd->up_bitmap == NULL )
{
XinRect rct2;
/*
int middle;
int font_height;
int font_top;
*/
XinPen pen;
rct2 = r;
xi_inflate_rect( &rct2, -3 );
/* middle = ( rct2.top + rct2.bottom ) / 2;
font_height = ascent + descent + leading;
font_top = middle - font_height / 2;
rct2.top = middle - font_height / 2 - 3;
rct2.bottom = font_top + font_height + 2;
if ( bline != -1 )
rct2.bottom = bline + descent + 2;
rct2.top = max( rct2.top, r.top + 3 );
rct2.bottom = min( rct2.bottom, r.bottom ); */
pen.width = 1;
pen.fore_color = XI_COLOR_BLACK;
pen.pattern = XinPenSolid;
XinWindowPenSet( win, &pen );
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_dotted_rect( win, &rct2 );
}
break;
}
case XIBT_RADIOBTN:
{
XinRect rbrct,
rct2;
unsigned long attrib;
XinRect text_rect;
XinColor color;
rbrct = *rct;
rbrct.bottom -= 4;
rct2 = rbrct;
rct2.right = rct2.left + ( rct2.bottom - rct2.top );
XinWindowDrawModeSet( win, XinDrawModeCopy );
XinWindowPenSet( win, &hollow_cpen );
if ( id->back_color && !box_only )
{
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_rect( win, rct );
}
xi_draw_3d_diamond( win, &rct2, checked, down, down ? 2 : 1,
down ? bd->fore_color : 0L );
if ( checked )
{
XinRect rct;
rct = rct2;
rct.top += 4;
rct.left += 4;
rct.bottom -= 4;
rct.right -= 4;
xi_draw_3d_diamond( win, &rct, FALSE, TRUE, rct.right - rct.left,
enabled ? bd->fore_color : xi_get_pref( XI_PREF_COLOR_DISABLED ) );
}
if ( !box_only )
{
XinPen cpen;
XinFont *fontp;
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
if ( enabled )
XinWindowColorTextForeSet( win, fore_color );
else
XinWindowColorTextForeSet( win,
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
text_rect = *rct;
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 2;
fontp = xi_obj->v.btn->font;
if ( fontp == NULL )
fontp = xi_obj->itf->v.itf->font;
if ( fontp == NULL )
fontp = xi_get_system_font( );
color = ( XinColor ) xi_get_pref( XI_PREF_COLOR_CTRL );
XinWindowColorTextBackSet( win, color );
XinWindowTextOpaqueSet( win, FALSE );
XinWindowFontMap( win, fontp );
xi_draw_clipped_text( win, fontp, bd->text, &text_rect, &text_rect, attrib, FALSE, 0, -1,
bd->mnemonic, bd->mnemonic_instance, NULL );
if ( focus )
{
cpen = black_cpen;
cpen.pattern = XinPenSolid;
XinWindowPenSet( win, &cpen );
XinWindowBrushSet( win, &hollow_cbrush );
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
xi_draw_dotted_rect( win, &text_rect );
}
else
{
/*
if ( id->back_color )
{
cpen = black_cpen;
cpen.fore_color = id->back_color;
XinWindowPenSet( win, &cpen );
XinWindowBrushSet( win, &hollow_cbrush );
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
xi_draw_rect( win, &text_rect );
}
*/
}
}
break;
}
case XIBT_TABBTN:
{
XinRect tab_rect,
rect;
XinBrush back_brush;
XinPen highlight_pen;
XinPen shadow_pen;
BOOLEAN checked_is_to_right;
BOOLEAN checked_is_to_left;
int index,
baseline;
XinFont *fontp;
unsigned long attrib;
back_brush.pattern = XinBrushSolid;
back_brush.fore_color = ( XinColor ) xi_get_pref( XI_PREF_COLOR_CTRL );
XinWindowBrushSet( win, &back_brush );
xi_set_clip( win, NULL );
XinWindowDrawModeSet( win, XinDrawModeCopy );
XinWindowPenSet( win, &hollow_cpen );
highlight_pen = black_cpen;
highlight_pen.fore_color = xi_get_pref( XI_PREF_COLOR_LIGHT );
shadow_pen = black_cpen;
shadow_pen.fore_color = xi_get_pref( XI_PREF_COLOR_DARK );
index = xi_obj_to_idx( xi_obj );
if ( index < xi_obj->parent->nbr_children - 1 )
checked_is_to_right = xi_obj->parent->children[index + 1]->v.btn->checked;
else
checked_is_to_right = FALSE;
if ( index > 0 )
checked_is_to_left = xi_obj->parent->children[index - 1]->v.btn->checked;
else
checked_is_to_left = FALSE;
tab_rect = *rct;
++tab_rect.bottom;
if ( xi_obj->v.btn->checked )
{
XinPoint p1,
p2;
{
XinRect temp = tab_rect;
temp.top++;
temp.left++;
xi_draw_rect( win, &temp );
}
XinWindowPenSet( win, &highlight_pen );
/* left line */
p1.h = tab_rect.left;
p1.v = tab_rect.bottom - 1;
xi_move_to( win, p1 );
p2.h = tab_rect.left;
p2.v = tab_rect.top + 2;
xi_draw_line( win, p2 );
/* diagonal line from left edge to top */
p1.h = tab_rect.left;
p1.v = tab_rect.top + 3;
xi_move_to( win, p1 );
p2.h = tab_rect.left + 3;
p2.v = tab_rect.top;
xi_draw_line( win, p2 );
/* top line */
p1.h = tab_rect.left + 2;
p1.v = tab_rect.top;
xi_move_to( win, p1 );
p2.h = tab_rect.right - 2;
p2.v = tab_rect.top;
xi_draw_line( win, p2 );
/* shadow and black lines on right */
XinWindowPenSet( win, &shadow_pen );
p1.h = tab_rect.right - 2;
p1.v = tab_rect.top;
xi_move_to( win, p1 );
p2.h = tab_rect.right - 2;
p2.v = tab_rect.bottom;
xi_draw_line( win, p2 );
XinWindowPenSet( win, &black_cpen );
p1.h = tab_rect.right - 1;
p1.v = tab_rect.top + 1;
xi_move_to( win, p1 );
p2.h = tab_rect.right - 1;
p2.v = tab_rect.bottom;
xi_draw_line( win, p2 );
}
else
{
XinPoint p1,
p2;
{
XinRect temp = tab_rect;
temp.top += 4;
if ( !checked_is_to_left )
temp.left++;
xi_draw_rect( win, &temp );
}
XinWindowPenSet( win, &highlight_pen );
/* draw line on left edge of tab */
if ( !checked_is_to_left )
{
p1.h = tab_rect.left;
p1.v = tab_rect.bottom - 2;
xi_move_to( win, p1 );
p2.h = tab_rect.left;
p2.v = tab_rect.top + 4;
xi_draw_line( win, p2 );
}
/* diagonal line from left edge to top */
if ( checked_is_to_left )
{
p1.h = tab_rect.left;
p1.v = tab_rect.top + 5;
xi_move_to( win, p1 );
p2.h = tab_rect.left + 2;
p2.v = tab_rect.top + 3;
xi_draw_line( win, p2 );
}
else
{
p1.h = tab_rect.left;
p1.v = tab_rect.top + 6;
xi_move_to( win, p1 );
p2.h = tab_rect.left + 3;
p2.v = tab_rect.top + 3;
xi_draw_line( win, p2 );
}
/* top line */
p1.h = tab_rect.left + 2;
p1.v = tab_rect.top + 3;
xi_move_to( win, p1 );
p2.h = tab_rect.right - 2;
p2.v = tab_rect.top + 3;
xi_draw_line( win, p2 );
/* shadow line on right */
XinWindowPenSet( win, &shadow_pen );
p1.h = tab_rect.right - 2;
p1.v = tab_rect.top + 3;
xi_move_to( win, p1 );
p2.h = tab_rect.right - 2;
p2.v = tab_rect.bottom - 2;
xi_draw_line( win, p2 );
/* black line on right */
if ( !checked_is_to_right )
{
XinWindowPenSet( win, &black_cpen );
p1.h = tab_rect.right - 1;
p1.v = tab_rect.top + 4;
xi_move_to( win, p1 );
p2.h = tab_rect.right - 1;
p2.v = tab_rect.bottom - 2;
xi_draw_line( win, p2 );
}
XinWindowPenSet( win, &highlight_pen );
p1.h = tab_rect.left;
p1.v = tab_rect.bottom - 1;
xi_move_to( win, p1 );
p2.h = tab_rect.right;
p2.v = tab_rect.bottom - 1;
xi_draw_line( win, p2 );
}
fontp = xi_obj->v.btn->font;
if ( !fontp )
fontp = xi_obj->itf->v.itf->font;
if ( !fontp )
fontp = xi_get_system_font( );
if ( checked )
{
XinFont *font;
XinFontCopy( &font, fontp );
XinFontBoldSet( font, TRUE );
fontp = font;
}
XinWindowFontMap( win, fontp );
XinFontMetricsGet( fontp, &leading, &ascent, &descent );
attrib = XI_ATR_HCENTER | XI_ATR_VCENTER | XI_ATR_VISIBLE;
rect = tab_rect;
++rect.left;
rect.right -= 2;
rect.top += 3;
if ( enabled )
XinWindowColorTextForeSet( win, fore_cp.fore_color );
else
XinWindowColorTextForeSet( win, ( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
XinWindowTextOpaqueSet( win, FALSE );
xi_draw_clipped_text( win, fontp, bd->text, &rect, &rect, attrib, FALSE, 0, -1,
bd->mnemonic, bd->mnemonic_instance, NULL );
#if XIWS == XIWS_WM
NOREF( rule_and_space );
baseline = rect.top + 8;
#else
baseline = rect.top + leading + ascent +
( rect.bottom - rect.top - leading - ascent - descent ) / 2 - 1;
#endif
if ( focus )
{
rect.top = baseline - leading - ascent;
rect.bottom = baseline + descent - 1;
++rect.left;
--rect.right;
XinWindowPenSet( win, &black_cpen );
xi_draw_dotted_rect( win, &rect );
}
break;
}
case XIBT_CHECKBOX:
{
XinRect cbrct,
rct2;
unsigned long attrib;
XinRect text_rect;
XinColor color;
cbrct = *rct;
cbrct.bottom -= 4;
rct2 = cbrct;
rct2.right = rct2.left + ( rct2.bottom - rct2.top );
XinWindowDrawModeSet( win, XinDrawModeCopy );
XinWindowPenSet( win, &hollow_cpen );
if ( id->back_color && !box_only )
{
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_rect( win, rct );
}
if ( down )
{
XinWindowPenSet( win, &fore_cp );
XinWindowBrushSet( win, &hollow_cbrush );
xi_draw_thick_rect( win, &rct2, 2 );
}
else
{
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
xi_draw_shaded_rect( win, &rct2, down, 1, 0L, 0L, 0L );
else
xi_draw_3d_rect( win, &rct2, down, 1, 0L, 0L, 0L );
}
if ( !enabled )
fore_cp.fore_color = xi_get_pref( XI_PREF_COLOR_DISABLED );
if ( checked )
{
XinPoint pnt1,
pnt2;
XinWindowPenSet( win, &fore_cp );
pnt1.h = rct2.left + 2;
pnt1.v = rct2.bottom - 7;
xi_move_to( win, pnt1 );
pnt2.h = pnt1.h;
pnt2.v = pnt1.v + 5;
xi_draw_line( win, pnt2 );
pnt1.h++;
pnt1.v--;
xi_move_to( win, pnt1 );
pnt2.h++;
xi_draw_line( win, pnt2 );
pnt1.h++;
pnt1.v = rct2.bottom - 5;
pnt2 = pnt1;
pnt2.v += 2;
while ( pnt1.v >= ( rct2.top + 3 ) && pnt1.h <= ( rct2.right - 4 ) )
{
xi_move_to( win, pnt1 );
xi_draw_line( win, pnt2 );
pnt1.h++;
pnt1.v--;
pnt2.h++;
pnt2.v--;
}
pnt1.v++;
xi_move_to( win, pnt1 );
xi_draw_line( win, pnt2 );
/* Sarebbe bello ma ... non <20> trasparente
XinRect rct3 = rct2;
xi_inflate_rect(&rct3, -2);
xi_draw_checkmark(win, &rct3);
*/
}
if ( !box_only )
{
XinFont *fontp;
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
if ( enabled )
XinWindowColorTextForeSet( win, fore_color );
else
XinWindowColorTextForeSet( win,
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
text_rect = *rct;
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 2;
fontp = xi_obj->v.btn->font;
if ( !fontp )
fontp = xi_obj->itf->v.itf->font;
if ( fontp == NULL )
fontp = xi_get_system_font( );
color = ( XinColor ) xi_get_pref( XI_PREF_COLOR_CTRL );
XinWindowColorTextBackSet( win, color );
XinWindowTextOpaqueSet( win, FALSE );
XinWindowFontMap( win, fontp );
xi_draw_clipped_text( win, fontp, bd->text, &text_rect, &text_rect, attrib, FALSE, 0, -1,
bd->mnemonic, bd->mnemonic_instance, NULL );
xi_set_clip( win, NULL );
if ( focus )
{
XinPen cpen;
cpen = black_cpen;
XinWindowPenSet( win, &cpen );
XinWindowBrushSet( win, &hollow_cbrush );
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
xi_draw_dotted_rect( win, &text_rect );
}
else
{
/*
if ( id->back_color )
{
XinPen cpen;
cpen = black_cpen;
cpen.fore_color = id->back_color;
XinWindowPenSet( win, &cpen );
XinWindowBrushSet( win, &hollow_cbrush );
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
xi_draw_rect( win, &text_rect );
}
*/
}
}
break;
}
}
}
/* -------------------------------------------------------------------------*/
/* xi_set_fixed_columns */
/* -------------------------------------------------------------------------*/
void
xi_set_fixed_columns( XI_OBJ * list, int new_fixed_count )
{
if ( list->type != XIT_LIST )
XinError( 20031, XinSeverityFatal, 0L );
lm_set_fixed_columns( list->v.list->lm, new_fixed_count );
}
/* -------------------------------------------------------------------------*/
/* xi_get_fixed_columns */
/* -------------------------------------------------------------------------*/
int
xi_get_fixed_columns( XI_OBJ * list )
{
if ( list->type != XIT_LIST )
XinError( 20038, XinSeverityFatal, 0L );
return lm_get_fixed_columns( list->v.list->lm );
}
/* -------------------------------------------------------------------------*/
/* xi_get_handle */
/* -------------------------------------------------------------------------*/
long
xi_get_handle( XI_OBJ * list, XI_OBJ * child )
{
LM_DATA *lm_data;
if ( list->type != XIT_LIST )
return -1L;
lm_data = ( LM_DATA * ) list->v.list->lm;
switch ( child->type )
{
case XIT_ROW:
{
int row = child->v.row;
if ( child->v.row_data.is_vert_scrolled )
return lm_focus_rec_get( lm_data );
if ( row >= 0 && row < lm_data->nbr_realized_rows )
return lm_data->recs[row];
break;
}
case XIT_CELL:
{
int row;
if ( child->v.cell.is_vert_scrolled )
return lm_focus_rec_get( lm_data );
row = child->v.cell.row;
if ( row >= 0 && row < lm_data->nbr_realized_rows )
return lm_data->recs[row];
break;
}
default:
break;
}
return -1L;
}
/* -------------------------------------------------------------------------*/
/* xi_field_calc_height_font */
/* -------------------------------------------------------------------------*/
int
xi_field_calc_height_font( XinFont * font )
{
if ( font == 0 )
font = xi_get_system_font( );
return xi_get_fu_height_font( font );
}
/* -------------------------------------------------------------------------*/
/* xi_button_calc_height_font */
/* -------------------------------------------------------------------------*/
int
xi_button_calc_height_font( XinFont * font )
{
return xi_field_calc_height_font( font );
}
/* -------------------------------------------------------------------------*/
/* xi_field_calc_width_font */
/* -------------------------------------------------------------------------*/
int
xi_field_calc_width_font( XinFont * font, char *string )
{
int result;
XinWindow win;
XinRect rct = {-1000, -1000, -900, -900};
XinFont *calc_font;
if ( font )
calc_font = font;
else
calc_font = xi_get_system_font( );
{
XinWindowDef Def;
MEMCLEAR( Def );
Def.type = XinWindowTypeDocument;
Def.border_style = XinBorderFixed;
Def.p_rect = &rct;
Def.title = "";
win = XinWindowCreate( &Def );
}
XinWindowFontMap( win, calc_font );
result = XinFontTextWidthGet( calc_font, string, -1 ) + 4;
XinFontUnmap( calc_font ); /* RGM: Unmap hack */
XinWindowDestroy( win );
return result;
}
/* -------------------------------------------------------------------------*/
/* xi_list_def_get_rows */
/* -------------------------------------------------------------------------*/
int
xi_list_def_get_rows( XI_OBJ_DEF * list_def )
{
int pix_row_spacing,
height,
pix_row1_top,
title_height;
if ( list_def->v.list->one_row_list )
return 1;
lm_get_vertical_metrics( list_def, &pix_row1_top, &pix_row_spacing, &height,
&title_height );
return height / pix_row_spacing;
}
/* -------------------------------------------------------------------------*/
/* xi_list_def_get_height */
/* -------------------------------------------------------------------------*/
int
xi_list_def_get_client_height( XI_OBJ_DEF * list_def, int rows )
{
int pix_row_spacing,
height,
pix_row1_top,
title_height;
lm_get_vertical_metrics( list_def, &pix_row1_top, &pix_row_spacing, &height,
&title_height );
return title_height + rows * pix_row_spacing + ( BORDER_WIDTH - RULE_WIDTH_H );
}
/* -------------------------------------------------------------------------*/
/* xi_list_def_get_height */
/* -------------------------------------------------------------------------*/
int
xi_list_def_get_outer_height( XI_OBJ_DEF * list_def, int rows )
{
int result;
result = xi_list_def_get_client_height( list_def, rows );
return result + ( int ) xi_get_pref( XI_PREF_SB_HEIGHT );
}
/* -------------------------------------------------------------------------*/
/* button_get_horz_padding */
/* -------------------------------------------------------------------------*/
static int
button_get_horz_padding( int type, int height, BOOLEAN packed )
{
switch ( type )
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
if ( packed )
return ( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH ) * 2;
return 6;
case XIBT_RADIOBTN:
return height + height / 2 - 6;
case XIBT_TABBTN:
return height + 4;
case XIBT_CHECKBOX:
return height + height / 2 - 6;
}
return 0;
}
/* -------------------------------------------------------------------------*/
/* xi_button_calc_height */
/* -------------------------------------------------------------------------*/
int
xi_button_calc_pixel_height( int height )
{
return height + 6;
}
/* -------------------------------------------------------------------------*/
/* xi_button_calc_height */
/* -------------------------------------------------------------------------*/
int
xi_button_calc_pixel_width( int width )
{
return width + 6;
}
/* -------------------------------------------------------------------------*/
/* xi_button_def_get_width */
/* -------------------------------------------------------------------------*/
int
xi_button_def_get_width( XI_OBJ_DEF * obj_def )
{
XinFont *font;
XinRect rct = {-1000, -1000, -900, -900};
XinWindow win;
int width;
XI_BTN_DEF *button;
if ( obj_def->type != XIT_BTN )
return 0;
font = xi_def_get_font( obj_def );
{
XinWindowDef Def;
MEMCLEAR( Def );
Def.type = XinWindowTypeDocument;
Def.border_style = XinBorderFixed;
Def.p_rect = &rct;
Def.title = "";
win = XinWindowCreate( &Def );
}
XinWindowFontMap( win, font );
button = obj_def->v.btn;
width = XinFontTextWidthGet( font, button->text, -1 );
width += button_get_horz_padding( button->type, xi_get_fu_height_font( font ),
FALSE );
XinFontDestroy( font );
XinWindowDestroy( win );
return width;
}
/* -------------------------------------------------------------------------*/
/* xi_container_def_get_btn_width */
/* -------------------------------------------------------------------------*/
int
xi_container_def_get_btn_width( XI_OBJ_DEF * obj_def )
{
int i;
XinFont *font;
XinRect rct = {-1000, -1000, -900, -900};
XinWindow win;
int max_width;
XI_CONTAINER_DEF *container;
BOOLEAN packed;
if ( obj_def->type != XIT_CONTAINER || obj_def->nbr_children <= 0 )
return 0;
font = xi_def_get_font( obj_def );
max_width = 0;
{
XinWindowDef Def;
MEMCLEAR( Def );
Def.type = XinWindowTypeDocument;
Def.border_style = XinBorderFixed;
Def.p_rect = &rct;
Def.title = "";
win = XinWindowCreate( &Def );
}
XinWindowFontMap( win, font );
for ( i = 0; i < obj_def->nbr_children; ++i )
{
XI_BTN_DEF *button;
int width;
button = obj_def->children[i]->v.btn;
width = XinFontTextWidthGet( font, button->text, -1 );
max_width = max( width, max_width );
}
container = obj_def->v.container;
packed = ( ( container->orientation == XI_GRID_HORIZONTAL
|| container->orientation == XI_GRID_VERTICAL )
&& container->packed );
max_width += button_get_horz_padding( obj_def->children[0]->v.btn->type,
xi_get_fu_height_font( font ),
packed );
XinFontDestroy( font );
XinWindowDestroy( win );
return max_width;
}
/* -------------------------------------------------------------------------*/
/* xi_container_def_get_width */
/* -------------------------------------------------------------------------*/
int
xi_container_def_get_width( XI_OBJ_DEF * obj_def )
{
XI_CONTAINER_DEF *container;
container = obj_def->v.container;
switch ( container->orientation )
{
case XI_STACK_HORIZONTAL:
{
int horz_spacing;
if ( container->packed )
horz_spacing = 0;
else if ( ( horz_spacing = ( int ) xi_get_pref( XI_PREF_HORZ_PIXEL_SPACING ) )
== 0 )
{
XinFont *font;
font = xi_def_get_font( obj_def );
horz_spacing = ( short ) ( ( xi_get_pref( XI_PREF_HORZ_SPACING )
* xi_get_fu_width_font( font ) ) / XI_FU_MULTIPLE );
XinFontDestroy( font );
}
return xi_container_def_get_btn_width( obj_def ) * obj_def->nbr_children +
( obj_def->nbr_children - 1 ) * horz_spacing;
}
case XI_STACK_VERTICAL:
return xi_container_def_get_btn_width( obj_def );
default:
break;
}
return 0;
}
/* -------------------------------------------------------------------------*/
/* xi_container_def_get_height */
/* -------------------------------------------------------------------------*/
int
xi_container_def_get_height( XI_OBJ_DEF * obj_def )
{
XI_CONTAINER_DEF *container;
XinFont *font;
int height;
int vert_spacing;
int top_offset;
if ( obj_def->nbr_children == 0 )
return 0;
container = obj_def->v.container;
font = xi_def_get_font( obj_def );
height = xi_button_calc_height_font( font );
XinFontDestroy( font );
if ( container->orientation == XI_STACK_HORIZONTAL )
return height;
if ( container->orientation != XI_STACK_VERTICAL )
return 0;
switch ( obj_def->children[0]->v.btn->type )
{
case XIBT_BUTTON:
case XIBT_BUTTON_CHECKBOX:
case XIBT_BUTTON_RADIOBTN:
case XIBT_TABBTN:
if ( container->packed )
vert_spacing = 0;
else if ( ( vert_spacing = ( int ) xi_get_pref( XI_PREF_VERT_PIXEL_SPACING ) )
== 0 )
vert_spacing = ( int ) ( ( xi_get_pref( XI_PREF_VERT_SPACING )
* height ) / XI_FU_MULTIPLE );
top_offset = vert_spacing / 2;
break;
case XIBT_CHECKBOX:
case XIBT_RADIOBTN:
vert_spacing = 0;
top_offset = 0;
break;
default:
vert_spacing = 0;
top_offset = 0;
break;
}
return height * obj_def->nbr_children + vert_spacing
* ( obj_def->nbr_children - 1 ) + top_offset;
}
void
xi_force_focus_cell_visible( XI_OBJ * list )
{
int row,
column;
BOOLEAN v_scrolled;
LM_FOCUS_CELL_VISIBLE_FORCE_ARGS args;
LM_DATA *lmp = ( LM_DATA * ) list->v.list->lm;
lm_focus_cell_get( lmp, &row, &column, &v_scrolled );
MEMCLEAR( args );
args.lmp = ( LM_DATA * ) list->v.list->lm;
args.row = row;
args.column = column;
args.vert_scrolled = v_scrolled;
lm_focus_cell_visible_force( &args );
}
BOOLEAN
xi_cell_data_valid( XI_OBJ * cell )
{
XI_OBJ * list = cell->parent;
LM_DATA *lmp = ( LM_DATA * ) list->v.list->lm;
if (lmp->nbr_realized_rows <= cell->v.cell.row ||
lmp->nbr_columns <= cell->v.cell.column)
return FALSE;
return lmp->cell_data[cell->v.cell.row][cell->v.cell.column].valid_data;
}