Files : Aggiunto il simbolo wxGTK per Linux git-svn-id: svn://10.65.10.50/trunk@12157 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			5291 lines
		
	
	
		
			161 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			5291 lines
		
	
	
		
			161 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*******************************************************************************
 | 
						|
*  Copyright 1991-1996 by ORCA Software, Inc.                                  *
 | 
						|
*                                                                              *
 | 
						|
*  All rights reserved.  May not be reproduced or distributed, in printed or   *
 | 
						|
*  electronic form, without permission of ORCA Software, Inc.  May not be      *
 | 
						|
*  distributed as object code, separately or linked with other object modules, *
 | 
						|
*  without permission.                                                         *
 | 
						|
*******************************************************************************/
 | 
						|
 | 
						|
#define XI_INTERNAL
 | 
						|
#include "xi.h"
 | 
						|
#include "xitext.h"
 | 
						|
#include "xilm.h"
 | 
						|
#include "xilmst.h"
 | 
						|
#include "xiutils.h"
 | 
						|
#include "xidisply.h"
 | 
						|
#include "xi_int.h"
 | 
						|
#include <limits.h>
 | 
						|
 | 
						|
#define REALIZED_ROWS_GRANULE 4
 | 
						|
#define REC_AT_TOP 1
 | 
						|
#define REC_AT_BOTTOM 0
 | 
						|
#define CELL_VERTICAL_MARGIN (RULE_Y_OFFSET_TOP + RULE_Y_OFFSET_BOTTOM + 2)
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:                   lm_allocate_rec_info
 | 
						|
lmp:                        current lmp
 | 
						|
realized_rows_array_len:    number of realized rows in the realized rows array
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_allocate_rec_info( LM_DATA * lmp, int realized_rows_array_len )
 | 
						|
{
 | 
						|
  int old_len = lmp->realized_rows_array_len;
 | 
						|
  int i;
 | 
						|
 | 
						|
  lmp->realized_rows_array_len = realized_rows_array_len;
 | 
						|
 | 
						|
  /* recs */
 | 
						|
  if ( lmp->recs )
 | 
						|
  {
 | 
						|
    lmp->recs = ( long * ) xi_tree_realloc( lmp->recs, sizeof( long ) * realized_rows_array_len );
 | 
						|
    for ( i = old_len; i < realized_rows_array_len; ++i )
 | 
						|
      lmp->recs[i] = 0L;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    lmp->recs = ( long * ) xi_tree_malloc( sizeof( long ) * realized_rows_array_len, lmp );
 | 
						|
 | 
						|
  /* pix_offsets */
 | 
						|
  if ( lmp->pix_offsets )
 | 
						|
    lmp->pix_offsets = ( int * ) xi_tree_realloc( lmp->pix_offsets,
 | 
						|
                                    sizeof( int ) * realized_rows_array_len );
 | 
						|
  else
 | 
						|
    lmp->pix_offsets = ( int * ) xi_tree_malloc( sizeof( int ) * realized_rows_array_len, lmp );
 | 
						|
 | 
						|
  /* pix_heights */
 | 
						|
  if ( lmp->pix_heights )
 | 
						|
    lmp->pix_heights = ( int * ) xi_tree_realloc( lmp->pix_heights,
 | 
						|
                                    sizeof( int ) * realized_rows_array_len );
 | 
						|
  else
 | 
						|
    lmp->pix_heights = ( int * ) xi_tree_malloc( sizeof( int ) * realized_rows_array_len, lmp );
 | 
						|
 | 
						|
  /* set_heights */
 | 
						|
  if ( lmp->set_heights )
 | 
						|
    lmp->set_heights = ( short * ) xi_tree_realloc( lmp->set_heights,
 | 
						|
                                    sizeof( int ) * realized_rows_array_len );
 | 
						|
  else
 | 
						|
    lmp->set_heights = ( short * ) xi_tree_malloc( sizeof( int ) * realized_rows_array_len, lmp );
 | 
						|
 | 
						|
  /* row_attribs */
 | 
						|
  if ( lmp->row_attribs )
 | 
						|
  {
 | 
						|
    lmp->row_attribs = ( unsigned long * ) xi_tree_realloc( lmp->row_attribs,
 | 
						|
                          sizeof( unsigned long ) * realized_rows_array_len );
 | 
						|
    for ( i = old_len; i < realized_rows_array_len; ++i )
 | 
						|
      lmp->row_attribs[i] = LM_ROW_ATR_ENABLED;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    lmp->row_attribs = ( unsigned long * ) xi_tree_malloc( sizeof( unsigned long ) * realized_rows_array_len,
 | 
						|
                                                          lmp );
 | 
						|
 | 
						|
  /* row_colors */
 | 
						|
  if ( lmp->row_colors )
 | 
						|
  {
 | 
						|
    lmp->row_colors = ( XinColor * ) xi_tree_realloc( lmp->row_colors,
 | 
						|
                              sizeof( XinColor ) * realized_rows_array_len );
 | 
						|
    for ( i = old_len; i < realized_rows_array_len; ++i )
 | 
						|
      lmp->row_colors[i] = 0L;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    lmp->row_colors = ( XinColor * ) xi_tree_malloc( sizeof( XinColor ) * realized_rows_array_len,
 | 
						|
                                                    lmp );
 | 
						|
 | 
						|
  /* cell_data */
 | 
						|
  if ( lmp->cell_data )
 | 
						|
  {
 | 
						|
    /* cell data destructor */
 | 
						|
    for ( i = realized_rows_array_len; i < old_len; ++i )
 | 
						|
      xi_tree_free( lmp->cell_data[i] );
 | 
						|
    lmp->cell_data = ( LM_CELL_DATA ** ) xi_tree_realloc( lmp->cell_data,
 | 
						|
                        sizeof( LM_CELL_DATA * ) * realized_rows_array_len );
 | 
						|
    for ( i = old_len; i < realized_rows_array_len; ++i )
 | 
						|
      lmp->cell_data[i] = ( LM_CELL_DATA * ) xi_tree_malloc(
 | 
						|
                    ( lmp->nbr_columns + 1 ) * sizeof( LM_CELL_DATA ), lmp );
 | 
						|
  }
 | 
						|
  else
 | 
						|
    lmp->cell_data = ( LM_CELL_DATA ** ) xi_tree_malloc(
 | 
						|
                    sizeof( LM_CELL_DATA * ) * realized_rows_array_len, lmp );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_create
 | 
						|
win:        window in which to put list
 | 
						|
lm_def:     list definition
 | 
						|
parent:     tree memory parent
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
LM
 | 
						|
lm_create( XinWindow win, LM_DEF * lm_def, void *parent )
 | 
						|
{
 | 
						|
  LM_DATA *lmp;
 | 
						|
  int i,
 | 
						|
  font_height,
 | 
						|
  leading,
 | 
						|
  ascent,
 | 
						|
  descent,
 | 
						|
  mch,
 | 
						|
  realized_rows_array_len;
 | 
						|
 | 
						|
  lmp = LMP( xi_tree_malloc( sizeof( LM_DATA ), parent ) );
 | 
						|
  lmp->focus_state = ( LM_FOCUS_STATE * ) xi_tree_malloc( sizeof( LM_FOCUS_STATE ), lmp );
 | 
						|
  lmp->focus_state->where = LM_FOCUS_NOWHERE;
 | 
						|
  lmp->cid = lm_def->cid;
 | 
						|
  lmp->list_obj = lm_def->list_obj;
 | 
						|
  lmp->itf_obj = lm_def->itf_obj;
 | 
						|
  lmp->win = win;
 | 
						|
  lmp->font = lm_def->font;
 | 
						|
  lmp->is_list_font = lm_def->is_list_font;
 | 
						|
  lmp->back_color = lm_def->back_color;
 | 
						|
  lmp->enabled_color = lm_def->enabled_color;
 | 
						|
  lmp->disabled_color = lm_def->disabled_color;
 | 
						|
  lmp->disabled_back_color = lm_def->disabled_back_color;
 | 
						|
  lmp->active_color = lm_def->active_color;
 | 
						|
  lmp->active_back_color = lm_def->active_back_color;
 | 
						|
  lmp->white_space_color = lm_def->white_space_color;
 | 
						|
  lmp->rule_color = lm_def->rule_color;
 | 
						|
  lmp->attrib = lm_def->attrib;
 | 
						|
  lmp->lm_cb = lm_def->lm_cb;
 | 
						|
  lmp->no_heading = lm_def->no_heading;
 | 
						|
  lmp->sizable_columns = lm_def->sizable_columns;
 | 
						|
  lmp->movable_columns = lm_def->movable_columns;
 | 
						|
  lmp->fixed_columns = lm_def->fixed_columns;
 | 
						|
  lmp->resize_with_window = lm_def->resize_with_window;
 | 
						|
  lmp->horz_sync_list = lm_def->horz_sync_list;
 | 
						|
  lmp->vert_sync_list = lm_def->vert_sync_list;
 | 
						|
  lmp->row_focus_border = lm_def->row_focus_border;
 | 
						|
  lmp->row_focus_border_color = lm_def->row_focus_border_color;
 | 
						|
  lmp->single_select = lm_def->single_select;
 | 
						|
  lmp->pixel_width = lm_def->pixel_width;
 | 
						|
  lmp->pixel_height = lm_def->pixel_height;
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  lmp->min_cell_height = 0;
 | 
						|
  lmp->min_heading_height = lm_def->min_heading_height;
 | 
						|
#else
 | 
						|
  lmp->min_cell_height = lm_def->min_cell_height;
 | 
						|
  lmp->min_heading_height = lm_def->min_heading_height;
 | 
						|
#endif
 | 
						|
  lmp->no_horz_lines = lm_def->no_horz_lines;
 | 
						|
  lmp->no_vert_lines = lm_def->no_vert_lines;
 | 
						|
  lmp->first_vis = lmp->fixed_columns;
 | 
						|
  lmp->drop_and_delete = lm_def->drop_and_delete;
 | 
						|
  lmp->select_cells = lm_def->select_cells;
 | 
						|
  lmp->get_all_records = lm_def->get_all_records;
 | 
						|
  lmp->retain_back_color_on_select = lm_def->retain_back_color_on_select;
 | 
						|
  lmp->drag_and_drop_rows = lm_def->drag_and_drop_rows;
 | 
						|
  lmp->drag_rows_autoscroll = lm_def->drag_rows_autoscroll;
 | 
						|
  lmp->button_on_cell_focus = lm_def->button_on_cell_focus;
 | 
						|
  lmp->position_by_typing_cid = lm_def->position_by_typing_cid;
 | 
						|
  lmp->max_lines_in_cell = lm_def->max_lines_in_cell;
 | 
						|
  if ( !lmp->max_lines_in_cell )
 | 
						|
    lmp->max_lines_in_cell =
 | 
						|
            ( int ) xi_get_pref( XI_PREF_DEFAULT_MAX_LINES_IN_CELL );
 | 
						|
  XinWindowFontMap( win, lm_def->font );
 | 
						|
  XinFontMetricsGet( lm_def->font, &leading, &ascent, &descent );
 | 
						|
  lmp->cur_font = lm_def->font;
 | 
						|
  lmp->leading = leading;
 | 
						|
  lmp->ascent = ascent;
 | 
						|
  lmp->descent = descent;
 | 
						|
  font_height = lmp->ascent + lmp->leading + lmp->descent;
 | 
						|
 | 
						|
  /* we add two to the following line so that there is room in the cell for the
 | 
						|
  * row focus border */
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  lmp->pix_cell_height = font_height;
 | 
						|
#else
 | 
						|
  lmp->pix_cell_height = font_height + CELL_VERTICAL_MARGIN;
 | 
						|
#endif
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  mch = 8;
 | 
						|
#else
 | 
						|
  mch = lm_def->min_cell_height;
 | 
						|
#endif
 | 
						|
  lmp->pix_cell_height = max( lmp->pix_cell_height, mch );
 | 
						|
  lmp->pix_row_spacing = lmp->pix_cell_height + RULE_WIDTH_H;
 | 
						|
  lmp->pix_top = lm_def->pnt.v;
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  lmp->pix_hdr_bottom = lm_def->pnt.v + lmp->leading + lmp->ascent +
 | 
						|
          lmp->descent + BORDER_WIDTH +
 | 
						|
          RULE_Y_OFFSET_BOTTOM + RULE_Y_OFFSET_TOP;
 | 
						|
  lmp->pix_hdr_bottom = max( lmp->pix_hdr_bottom, ( lm_def->pnt.v
 | 
						|
                                + lmp->min_heading_height - BORDER_WIDTH ) );
 | 
						|
#else
 | 
						|
  lmp->pix_hdr_bottom = lm_def->pnt.v + lmp->leading + lmp->ascent +
 | 
						|
          lmp->descent + BORDER_WIDTH + RULE_Y_OFFSET_BOTTOM + RULE_Y_OFFSET_TOP + 1;
 | 
						|
  lmp->pix_hdr_bottom = max( lmp->pix_hdr_bottom, ( lm_def->pnt.v + lmp->min_heading_height ) );
 | 
						|
#endif
 | 
						|
  if ( lmp->no_heading )
 | 
						|
    lmp->pix_row1_top = lm_def->pnt.v + BORDER_WIDTH;
 | 
						|
  else
 | 
						|
    lmp->pix_row1_top = lmp->pix_hdr_bottom + BORDER_WIDTH;
 | 
						|
  lmp->pix_char_width = lm_def->pix_char_width;
 | 
						|
  lmp->nbr_columns = 0;
 | 
						|
  lmp->lm_column_data = NULL;
 | 
						|
 | 
						|
  /* compute number of rows */
 | 
						|
  lmp->nbr_rows = lm_def->nbr_rows;
 | 
						|
  if ( lm_def->nbr_rows )
 | 
						|
    lmp->nbr_rows = lm_def->nbr_rows;
 | 
						|
  else
 | 
						|
    lmp->nbr_rows = ( lm_def->pixel_height - ( lmp->pix_row1_top - lm_def->pnt.v )
 | 
						|
                      - BORDER_WIDTH ) / lmp->pix_row_spacing;
 | 
						|
  if ( lm_def->one_row_list )
 | 
						|
  {
 | 
						|
    lmp->nbr_rows = 1;
 | 
						|
    lm_def->resize_with_window = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  lmp->rct.left = lm_def->pnt.h;
 | 
						|
  lmp->rct.top = lm_def->pnt.v;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  lmp->rct.right = lm_def->pnt.h + 2 * BORDER_WIDTH;
 | 
						|
  if ( lm_def->resize_with_window )
 | 
						|
    lmp->rct.bottom = lm_def->pnt.v + lm_def->pixel_height;
 | 
						|
  else
 | 
						|
    lmp->rct.bottom = lmp->pix_row1_top + lmp->nbr_rows * lmp->pix_row_spacing +
 | 
						|
            ( BORDER_WIDTH - RULE_WIDTH_H );
 | 
						|
#else
 | 
						|
  lmp->rct.right = lm_def->pnt.h + BORDER_WIDTH;
 | 
						|
  if ( lm_def->resize_with_window )
 | 
						|
    lmp->rct.bottom = lm_def->pnt.v + lm_def->pixel_height;
 | 
						|
  else
 | 
						|
    lmp->rct.bottom = lmp->pix_row1_top + lmp->nbr_rows * lmp->pix_row_spacing
 | 
						|
            + BORDER_WIDTH;
 | 
						|
#endif
 | 
						|
  lmp->vir_left = lmp->rct.left + BORDER_WIDTH;
 | 
						|
  lmp->vir_right = lmp->vir_left + lmp->pixel_width;
 | 
						|
 | 
						|
  realized_rows_array_len = lm_def->realized_rows_array_len;
 | 
						|
  if ( !realized_rows_array_len )
 | 
						|
    realized_rows_array_len = lmp->nbr_rows + 1;
 | 
						|
  lm_allocate_rec_info( lmp, realized_rows_array_len );
 | 
						|
 | 
						|
  /* calculate mathematical list rectangle */
 | 
						|
  lmp->mlr.top = lmp->pix_row1_top;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  lmp->mlr.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
  lmp->mlr.left = lmp->rct.left + BORDER_WIDTH;
 | 
						|
  lmp->mlr.right = lmp->rct.right - BORDER_WIDTH;
 | 
						|
#else
 | 
						|
  if ( lmp->pixel_width )
 | 
						|
    lmp->mlr.bottom = lmp->rct.bottom;
 | 
						|
  else
 | 
						|
    lmp->mlr.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
  lmp->mlr.left = lmp->rct.left;
 | 
						|
  lmp->mlr.right = lmp->rct.right;
 | 
						|
#endif
 | 
						|
  lmp->mlr_height = lmp->mlr.bottom - lmp->mlr.top;
 | 
						|
 | 
						|
  for ( i = 0; i < lmp->realized_rows_array_len; ++i )
 | 
						|
  {
 | 
						|
    lmp->cell_data[i] = ( LM_CELL_DATA * ) xi_tree_malloc(
 | 
						|
                            lmp->nbr_columns * sizeof( LM_CELL_DATA ), lmp );
 | 
						|
    lmp->row_attribs[i] = LM_ROW_ATR_ENABLED;
 | 
						|
  }
 | 
						|
 | 
						|
  return ( ( LM ) ( long ) lmp );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_do_rec_event
 | 
						|
lmp:        current lmp
 | 
						|
row:        row to do event on
 | 
						|
type:       XI_EVENT_TYPE
 | 
						|
notes:      In this case, row is not really a row.  It is an index into the
 | 
						|
      realized rows array.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_do_rec_event( LM_DATA * lmp, int row, XI_EVENT_TYPE type )
 | 
						|
{
 | 
						|
  LM_CELL_DATA *cell_data;
 | 
						|
  int i;
 | 
						|
 | 
						|
  if ( type == XIE_REC_FREE )
 | 
						|
  {
 | 
						|
    if ( lmp->recs[row] != lm_focus_rec_get( lmp ) )
 | 
						|
      do_lm_cb( ( LM ) lmp, LM_CB_REC_FREE, row, 0, NULL, NULL, 0 );
 | 
						|
    cell_data = lmp->cell_data[row];
 | 
						|
    /* cell_data_destruct */
 | 
						|
    for ( i = 0; i < lmp->nbr_columns; ++i, ++cell_data )
 | 
						|
    {
 | 
						|
      if ( cell_data->font )
 | 
						|
        XinFontDestroy( cell_data->font );
 | 
						|
      xi_bitmap_destroy( cell_data->bitmap );
 | 
						|
      xi_bitmap_destroy( cell_data->button_bitmap );
 | 
						|
      if ( cell_data->xi_text )
 | 
						|
        xi_text_destruct( cell_data->xi_text );
 | 
						|
      memset( ( char * ) cell_data, '\0', sizeof( LM_CELL_DATA ) );
 | 
						|
    }
 | 
						|
    lmp->recs[row] = 0L;
 | 
						|
    /* we technically do not need to do the following lines.  it just keeps the
 | 
						|
    * data structures clean. */
 | 
						|
    lmp->pix_heights[row] = 0;
 | 
						|
    lmp->set_heights[row] = FALSE;
 | 
						|
    lmp->pix_offsets[row] = 0;
 | 
						|
    lmp->row_attribs[row] = 0L;
 | 
						|
    lmp->row_colors[row] = 0L;
 | 
						|
  }
 | 
						|
  /* cell_data_construct */
 | 
						|
  if ( type == XIE_REC_ALLOCATE )
 | 
						|
  {
 | 
						|
    do_lm_cb( ( LM ) lmp, LM_CB_REC_ALLOCATE, row, 0, NULL, NULL, 0 );
 | 
						|
    cell_data = lmp->cell_data[row];
 | 
						|
    for ( i = 0; i < lmp->nbr_columns; ++i, ++cell_data )
 | 
						|
    {
 | 
						|
      memset( ( char * ) cell_data, '\0', sizeof( LM_CELL_DATA ) );
 | 
						|
      lm_xi_text_construct( lmp, row, i );
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_row_copy
 | 
						|
lmp:        current lmp
 | 
						|
source_row: row from which to copy
 | 
						|
dest_row:   destination row
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_row_copy( LM_DATA * lmp, int source_row, int dest_row )
 | 
						|
{
 | 
						|
  int idx;
 | 
						|
  LM_CELL_DATA *dest_cell_data,
 | 
						|
  *source_cell_data;
 | 
						|
 | 
						|
  lmp->recs[dest_row] = lmp->recs[source_row];
 | 
						|
  lmp->pix_heights[dest_row] = lmp->pix_heights[source_row];
 | 
						|
  lmp->set_heights[dest_row] = lmp->set_heights[source_row];
 | 
						|
  lmp->pix_offsets[dest_row] = lmp->pix_offsets[source_row];
 | 
						|
  lmp->row_attribs[dest_row] = lmp->row_attribs[source_row];
 | 
						|
  lmp->row_colors[dest_row] = lmp->row_colors[source_row];
 | 
						|
  for ( idx = 0,
 | 
						|
        dest_cell_data = lmp->cell_data[dest_row],
 | 
						|
        source_cell_data = lmp->cell_data[source_row];
 | 
						|
        idx < lmp->nbr_columns;
 | 
						|
        ++idx,
 | 
						|
        ++dest_cell_data,
 | 
						|
        ++source_cell_data )
 | 
						|
  {
 | 
						|
    *dest_cell_data = *source_cell_data;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   init_row
 | 
						|
lmp:        current lmp
 | 
						|
row:        row to init
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
init_row( LM_DATA * lmp, int row )
 | 
						|
{
 | 
						|
  int idx;
 | 
						|
  LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
  lmp->recs[row] = 0L;
 | 
						|
  lmp->pix_heights[row] = 0;
 | 
						|
  lmp->set_heights[row] = 0;
 | 
						|
  lmp->pix_offsets[row] = 0;
 | 
						|
  lmp->row_attribs[row] = LM_ROW_ATR_ENABLED;
 | 
						|
  lmp->row_colors[row] = 0;
 | 
						|
  for ( idx = 0,
 | 
						|
        cell_data = lmp->cell_data[row];
 | 
						|
        idx < lmp->nbr_columns;
 | 
						|
        ++idx,
 | 
						|
        ++cell_data )
 | 
						|
  {
 | 
						|
    memset( ( char * ) cell_data, '\0', sizeof( LM_CELL_DATA ) );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   make_rec_available
 | 
						|
lmp:        current lmp
 | 
						|
top:        record to become available is at the top of the realized_row array,
 | 
						|
            else the record to become available is at the bottom of the realized
 | 
						|
            row array.
 | 
						|
allocate_rec:   if TRUE, then send XIE_REC_ALLOCATE event
 | 
						|
notes:      if, in order to get a record at the bottom of the realized row array,
 | 
						|
              we must discard a record at the beginning of the rrr array, then
 | 
						|
              we must change lmp->rrr_offset.
 | 
						|
            whenever we make a record be available, make sure that we free
 | 
						|
              fonts in cell_data.
 | 
						|
            Also, clear cell_data.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
make_rec_available( LM_DATA * lmp, BOOLEAN top, BOOLEAN allocate_rec,
 | 
						|
                    BOOLEAN doing_scroll_first )
 | 
						|
{
 | 
						|
  int cnt;
 | 
						|
 | 
						|
  if ( top )
 | 
						|
  {
 | 
						|
    int idx;
 | 
						|
 | 
						|
    if ( !lmp->get_all_records )
 | 
						|
    {
 | 
						|
      int nbr_to_free;
 | 
						|
 | 
						|
      nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
      if ( nbr_to_free > 0 )
 | 
						|
      {
 | 
						|
        /* free as many records at the end of the list as possible */
 | 
						|
        for ( idx = lmp->last_fully_vis + 2; idx < lmp->nbr_realized_rows;
 | 
						|
              ++idx )
 | 
						|
          lm_do_rec_event( lmp, idx, XIE_REC_FREE );
 | 
						|
        lmp->nbr_realized_rows -= nbr_to_free;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( lmp->nbr_realized_rows >= lmp->realized_rows_array_len )
 | 
						|
        lm_allocate_rec_info( lmp, lmp->realized_rows_array_len + 1 );
 | 
						|
 | 
						|
      /* copy all the records, making room at the beginning of the realized_row
 | 
						|
      * array */
 | 
						|
      ++lmp->nbr_realized_rows;
 | 
						|
      for ( idx = lmp->nbr_realized_rows - 1;
 | 
						|
            idx > 0; --idx )
 | 
						|
        lm_row_copy( lmp, idx - 1, idx );
 | 
						|
      lm_adjust_rows( lmp, 1 );
 | 
						|
      init_row( lmp, 0 );
 | 
						|
      if ( allocate_rec )
 | 
						|
        lm_do_rec_event( lmp, 0, XIE_REC_ALLOCATE );
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if ( !lmp->get_all_records || doing_scroll_first )
 | 
						|
    {
 | 
						|
      /* free as many records at the beginning of the list as possible */
 | 
						|
      cnt = lmp->first_fully_vis - 2;
 | 
						|
      if ( cnt > 0 )
 | 
						|
      {
 | 
						|
        int idx,
 | 
						|
        jidx;
 | 
						|
 | 
						|
        for ( idx = 0; idx < cnt; ++idx )
 | 
						|
        {
 | 
						|
          lmp->rrr_offset += lmp->pix_heights[idx];
 | 
						|
          lm_do_rec_event( lmp, idx, XIE_REC_FREE );
 | 
						|
        }
 | 
						|
 | 
						|
        lmp->nbr_realized_rows -= cnt;
 | 
						|
 | 
						|
        /* copy all the records, making room at the end of the realized row
 | 
						|
        * array */
 | 
						|
        for ( idx = cnt, jidx = 0;
 | 
						|
              jidx < lmp->nbr_realized_rows;
 | 
						|
              ++idx, ++jidx )
 | 
						|
          lm_row_copy( lmp, idx, idx - cnt );
 | 
						|
        lm_adjust_rows( lmp, -cnt );
 | 
						|
      }
 | 
						|
      if ( lmp->nbr_realized_rows >= lmp->realized_rows_array_len )
 | 
						|
        lm_allocate_rec_info( lmp, lmp->realized_rows_array_len + 1 );
 | 
						|
      ++lmp->nbr_realized_rows;
 | 
						|
      init_row( lmp, lmp->nbr_realized_rows - 1 );
 | 
						|
      if ( allocate_rec )
 | 
						|
        lm_do_rec_event( lmp, lmp->nbr_realized_rows - 1, XIE_REC_ALLOCATE );
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   get_next_rec
 | 
						|
lmp:        current lmp
 | 
						|
returns:    TRUE if next record was available
 | 
						|
            FALSE if not
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static BOOLEAN
 | 
						|
get_next_rec( LM_DATA * lmp, BOOLEAN doing_scroll_first )
 | 
						|
{
 | 
						|
  int idx,
 | 
						|
  row_height;
 | 
						|
 | 
						|
  make_rec_available( lmp, REC_AT_BOTTOM, TRUE, doing_scroll_first );
 | 
						|
  idx = lmp->nbr_realized_rows - 1;
 | 
						|
  if ( do_lm_cb_get( ( LM ) lmp, LM_CB_GET_NEXT,
 | 
						|
              &lmp->recs[idx - 1], &lmp->recs[idx], 0, &lmp->row_colors[idx],
 | 
						|
                    &lmp->row_attribs[idx], &row_height ) )
 | 
						|
  {
 | 
						|
    lm_do_rec_event( lmp, lmp->nbr_realized_rows - 1, XIE_REC_FREE );
 | 
						|
    --lmp->nbr_realized_rows;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( row_height )
 | 
						|
  {
 | 
						|
    lmp->pix_heights[idx] = row_height;
 | 
						|
    lmp->set_heights[idx] = TRUE;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    lmp->pix_heights[idx] = 0;
 | 
						|
    lmp->set_heights[idx] = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  lm_invalidate_rows_internal( ( LM ) lmp, idx, idx, FALSE, -1, TRUE );
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   get_previous_rec
 | 
						|
lmp:        current lmp
 | 
						|
returns:    TRUE if previous record was available
 | 
						|
      FALSE if not
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static BOOLEAN
 | 
						|
get_previous_rec( LM_DATA * lmp )
 | 
						|
{
 | 
						|
  int row_height,
 | 
						|
  cnt;
 | 
						|
 | 
						|
  make_rec_available( lmp, REC_AT_TOP, TRUE, FALSE );
 | 
						|
  if ( do_lm_cb_get( ( LM ) lmp, LM_CB_GET_PREV,
 | 
						|
                    &lmp->recs[1], &lmp->recs[0], 0, &lmp->row_colors[0],
 | 
						|
                    &lmp->row_attribs[0], &row_height ) )
 | 
						|
  {
 | 
						|
    lm_do_rec_event( lmp, 0, XIE_REC_FREE );
 | 
						|
    for ( cnt = 0; cnt < lmp->nbr_realized_rows - 1; ++cnt )
 | 
						|
      lm_row_copy( lmp, cnt + 1, cnt );
 | 
						|
    lm_adjust_rows( lmp, -1 );
 | 
						|
    --lmp->nbr_realized_rows;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  if ( row_height )
 | 
						|
  {
 | 
						|
    lmp->pix_heights[0] = row_height;
 | 
						|
    lmp->set_heights[0] = TRUE;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    lmp->pix_heights[0] = 0;
 | 
						|
    lmp->set_heights[0] = FALSE;
 | 
						|
  }
 | 
						|
  lm_invalidate_rows_internal( ( LM ) lmp, 0, 0, FALSE, -1, TRUE );
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   calculate_cell_height
 | 
						|
lmp:        current lmp
 | 
						|
row:        row number of cell to calculate
 | 
						|
column:     column number of cell to calculate
 | 
						|
returns:    height of cell in pixels
 | 
						|
notes:      this function does not need to take into consideration the
 | 
						|
            variable fixed_row_height.  This function is only used by
 | 
						|
            lm_calculate_row_height, and will only be called if
 | 
						|
            fixed_row_height is false.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static int
 | 
						|
calculate_cell_height( LM_DATA * lmp, int row, int column )
 | 
						|
{
 | 
						|
  int pix_height;               /* pix_height does include the width of the
 | 
						|
                                * rules */
 | 
						|
  int nbr_lines;
 | 
						|
  LM_CELL_DATA *cell_data;
 | 
						|
  LM_COLUMN_DATA *lm_column_data;
 | 
						|
 | 
						|
  cell_data = &lmp->cell_data[row][column];
 | 
						|
  lm_column_data = lmp->lm_column_data[column];
 | 
						|
  if ( !cell_data->font_height )
 | 
						|
  {
 | 
						|
    XinFont *font;
 | 
						|
    int leading,
 | 
						|
    ascent,
 | 
						|
    descent,
 | 
						|
    char_width;
 | 
						|
 | 
						|
    if ( lm_column_data->wrap_text && !cell_data->valid_data )
 | 
						|
      do_lm_cb_text( lmp, row, column, TRUE );
 | 
						|
    if ( cell_data->font )
 | 
						|
      font = cell_data->font;
 | 
						|
    else
 | 
						|
      font = lmp->font;
 | 
						|
    xi_get_font_metrics_font( font, &leading, &ascent, &descent, &char_width );
 | 
						|
    cell_data->font_height = leading + ascent + descent;
 | 
						|
  }
 | 
						|
  if ( lm_column_data->wrap_text )
 | 
						|
  {
 | 
						|
    int pix_spacing;
 | 
						|
    BOOLEAN is_editing;
 | 
						|
    int ip1,
 | 
						|
    ip2,
 | 
						|
    start_ip;
 | 
						|
 | 
						|
    if ( !cell_data->valid_data )
 | 
						|
      do_lm_cb_text( lmp, row, column, TRUE );
 | 
						|
    is_editing = xi_text_editing_is( cell_data->xi_text );
 | 
						|
    if ( is_editing )
 | 
						|
      xi_text_selection_get_internal( cell_data->xi_text, &ip1, &ip2, &start_ip );
 | 
						|
    xi_text_initialized_set( cell_data->xi_text, FALSE );
 | 
						|
    pix_spacing = lm_column_data->pix_width -
 | 
						|
            ( cell_data->button ? lmp->pix_row_spacing : 0 );
 | 
						|
    xi_text_pix_width_set( cell_data->xi_text, pix_spacing );
 | 
						|
    if ( is_editing )
 | 
						|
      xi_text_selection_set_internal( cell_data->xi_text, ip1, ip2, start_ip, FALSE, FALSE );
 | 
						|
    nbr_lines = min( xi_text_nbr_lines_get( cell_data->xi_text ), lmp->max_lines_in_cell );
 | 
						|
  }
 | 
						|
  else
 | 
						|
    nbr_lines = 1;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  pix_height = nbr_lines * cell_data->font_height + CELL_VERTICAL_MARGIN
 | 
						|
          + RULE_WIDTH_H;
 | 
						|
#else
 | 
						|
  pix_height = nbr_lines * cell_data->font_height;
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( lm_focus_state_get( lmp ) == LM_FOCUS_VERTICALLY_SCROLLED )
 | 
						|
  {
 | 
						|
    int focus_row,
 | 
						|
    focus_column;
 | 
						|
    BOOLEAN v_scrolled;
 | 
						|
 | 
						|
    lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
    if ( focus_column == column && lmp->recs[row] == lmp->focus_state->focus_rec )
 | 
						|
      pix_height = lmp->focus_state->focus_rec_height;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  pix_height = max( pix_height, lmp->pix_row_spacing );
 | 
						|
  return pix_height;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_calculate_row_height
 | 
						|
lmp:        current lmp
 | 
						|
row:        row number to calculate
 | 
						|
returns:    height of row in pixels
 | 
						|
notes:      if fixed_row_height is TRUE, then the calculation is easy.
 | 
						|
            if fixed_row_height is FALSE, then the calculation must take
 | 
						|
            word wrap into consideration, etc.
 | 
						|
            row height includes the height of the horizontal rule below
 | 
						|
            the row.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
int
 | 
						|
lm_calculate_row_height( LM_DATA * lmp, int row )
 | 
						|
{
 | 
						|
  int pix_height;
 | 
						|
 | 
						|
  if ( lmp->fixed_row_height )
 | 
						|
    pix_height = lmp->pix_row_spacing;
 | 
						|
  else if ( lmp->set_heights[row] )
 | 
						|
    pix_height = lmp->pix_heights[row];
 | 
						|
  else
 | 
						|
  {
 | 
						|
    int cnt;
 | 
						|
    int cell_height;
 | 
						|
 | 
						|
    pix_height = 0;
 | 
						|
    for ( cnt = 0; cnt < lmp->nbr_columns; ++cnt )
 | 
						|
    {
 | 
						|
      cell_height = calculate_cell_height( lmp, row, cnt );
 | 
						|
      pix_height = max( pix_height, cell_height );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if ( pix_height > lmp->mlr_height )
 | 
						|
    pix_height = lmp->mlr_height;
 | 
						|
  return pix_height;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   calculate_visibles
 | 
						|
lmp:        current lmp
 | 
						|
process:    calculates lmp->first_fully_vis
 | 
						|
            calculates lmp->last_fully_vis
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
calculate_visibles( LM_DATA * lmp )
 | 
						|
{
 | 
						|
  int i,
 | 
						|
  idx;
 | 
						|
  int *pix_offsetsp;
 | 
						|
  int *pix_heightsp;
 | 
						|
  BOOLEAN have_first;
 | 
						|
 | 
						|
  have_first = FALSE;
 | 
						|
  lmp->first_fully_vis = 0;
 | 
						|
  lmp->last_fully_vis = 0;
 | 
						|
  for ( i = 0,
 | 
						|
        pix_offsetsp = &lmp->pix_offsets[i],
 | 
						|
        pix_heightsp = &lmp->pix_heights[i];
 | 
						|
        i < lmp->nbr_realized_rows;
 | 
						|
        ++i, ++pix_offsetsp, ++pix_heightsp )
 | 
						|
  {
 | 
						|
    if ( !have_first && *pix_offsetsp >= ( -lmp->rrr_offset ) )
 | 
						|
    {
 | 
						|
      have_first = TRUE;
 | 
						|
      lmp->first_fully_vis = i;
 | 
						|
    }
 | 
						|
    /* should be <, because we are dealing with mathematical rects, but we
 | 
						|
    * don't care if the rule is not on the list. pix_offsetp + *pix_heightsp
 | 
						|
    * is the mathematical rect of the row, in rrr terms. lmp->rrr_offset +
 | 
						|
    * lmp->mlr_height is the mathematical rect of the list, in rrr terms. */
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
    if ( *pix_offsetsp + *pix_heightsp + lmp->rrr_offset <= lmp->mlr_height )
 | 
						|
      lmp->last_fully_vis = i;
 | 
						|
#else
 | 
						|
    if ( *pix_offsetsp + *pix_heightsp - 1 + lmp->rrr_offset <= lmp->mlr_height )
 | 
						|
      lmp->last_fully_vis = i;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
  if ( lmp->nbr_realized_rows )
 | 
						|
  {
 | 
						|
    idx = lmp->nbr_realized_rows - 1;
 | 
						|
    lmp->rrr_bottom = lmp->pix_offsets[idx] + lmp->pix_heights[idx];
 | 
						|
  }
 | 
						|
  else
 | 
						|
    lmp->rrr_bottom = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   calculate_pix_offsets
 | 
						|
lmp:        current lmp
 | 
						|
process:    calculates the lmp->pix_offsets array
 | 
						|
      calculates lmp->first_fully_vis
 | 
						|
      calculates lmp->last_fully_vis
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
calculate_pix_offsets( LM_DATA * lmp, BOOLEAN draw_changes )
 | 
						|
{
 | 
						|
  int i,
 | 
						|
  cur_pix,
 | 
						|
  idx;
 | 
						|
  int *pix_offsetsp;
 | 
						|
  int *pix_heightsp;
 | 
						|
  BOOLEAN have_first;
 | 
						|
 | 
						|
  cur_pix = 0;
 | 
						|
  have_first = FALSE;
 | 
						|
  for ( i = 0,
 | 
						|
        pix_offsetsp = &lmp->pix_offsets[i],
 | 
						|
        pix_heightsp = &lmp->pix_heights[i];
 | 
						|
        i < lmp->nbr_realized_rows;
 | 
						|
        ++i, ++pix_offsetsp, ++pix_heightsp )
 | 
						|
  {
 | 
						|
    int new_height;
 | 
						|
 | 
						|
    new_height = lm_calculate_row_height( lmp, i );
 | 
						|
    if ( draw_changes &&
 | 
						|
        ( *pix_offsetsp != cur_pix || *pix_heightsp != new_height ) )
 | 
						|
    {
 | 
						|
      XinRect rect;
 | 
						|
 | 
						|
      lm_get_row_rect( &rect, ( LM ) lmp, i );
 | 
						|
      lm_invalidate_rect( lmp, &rect, FALSE );
 | 
						|
      rect.top = cur_pix;
 | 
						|
      rect.bottom = cur_pix + new_height;
 | 
						|
      lm_invalidate_rect( lmp, &rect, FALSE );
 | 
						|
    }
 | 
						|
    *pix_offsetsp = cur_pix;
 | 
						|
    *pix_heightsp = new_height;
 | 
						|
    if ( !have_first && cur_pix >= ( -lmp->rrr_offset ) )
 | 
						|
    {
 | 
						|
      have_first = TRUE;
 | 
						|
      lmp->first_fully_vis = i;
 | 
						|
    }
 | 
						|
    cur_pix += new_height;
 | 
						|
    /* should be <=, because we are dealing with mathematical rects, but we
 | 
						|
    * don't care if the rule is not on the list. pix_offsetp + *pix_heightsp
 | 
						|
    * is the mathematical rect of the row, in rrr terms. lmp->rrr_offset +
 | 
						|
    * lmp->mlr_height is the mathematical rect of the list, in rrr terms. */
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
    if ( cur_pix + lmp->rrr_offset <= lmp->mlr_height )
 | 
						|
      lmp->last_fully_vis = i;
 | 
						|
#else
 | 
						|
    if ( cur_pix - 1 + lmp->rrr_offset <= lmp->mlr_height )
 | 
						|
      lmp->last_fully_vis = i;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
  if ( lmp->nbr_realized_rows )
 | 
						|
  {
 | 
						|
    idx = lmp->nbr_realized_rows - 1;
 | 
						|
    lmp->rrr_bottom = lmp->pix_offsets[idx] + lmp->pix_heights[idx];
 | 
						|
  }
 | 
						|
  else
 | 
						|
    lmp->rrr_bottom = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   make_rrr_room_pix
 | 
						|
lmp:        current lmp
 | 
						|
pixels:     number of additional pixels desired in realized row rect
 | 
						|
            pixels may be negative, in which case, the desired pixels
 | 
						|
              are above the realized row rect
 | 
						|
            pixels may be positive, in which case, the desired pixels
 | 
						|
              are below the realized row rect
 | 
						|
returns:    recs read
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
int
 | 
						|
lm_make_rrr_room_pix( LM_DATA * lmp, int pixels, BOOLEAN do_redraw )
 | 
						|
{
 | 
						|
  int recs_read = 0;
 | 
						|
  int idx;
 | 
						|
 | 
						|
  if ( lmp->nbr_realized_rows == 0 || lmp->nbr_columns == 0 )
 | 
						|
  {
 | 
						|
    lmp->rrr_bottom = 0;
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  idx = lmp->nbr_realized_rows - 1;
 | 
						|
  lmp->rrr_bottom = lmp->pix_offsets[idx] + lmp->pix_heights[idx];
 | 
						|
 | 
						|
  if ( pixels == 0 )
 | 
						|
  return recs_read;
 | 
						|
 | 
						|
  if ( pixels < 0 )
 | 
						|
  {
 | 
						|
    while ( TRUE )
 | 
						|
  {
 | 
						|
      if ( pixels >= lmp->rrr_offset )
 | 
						|
        return recs_read;
 | 
						|
      if ( get_previous_rec( lmp ) )
 | 
						|
      {
 | 
						|
        int row_height;
 | 
						|
 | 
						|
        row_height = lm_calculate_row_height( lmp, 0 );
 | 
						|
        lmp->rrr_offset -= row_height;
 | 
						|
        calculate_pix_offsets( lmp, do_redraw );
 | 
						|
        calculate_visibles( lmp );
 | 
						|
        ++recs_read;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        return recs_read;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    while ( TRUE )
 | 
						|
    {
 | 
						|
      if ( lmp->rrr_bottom - lmp->mlr_height + lmp->rrr_offset >= pixels )
 | 
						|
        return recs_read;
 | 
						|
      if ( lmp->get_all_records )
 | 
						|
        return recs_read;
 | 
						|
      if ( get_next_rec( lmp, FALSE ) )
 | 
						|
      {
 | 
						|
        calculate_pix_offsets( lmp, do_redraw );
 | 
						|
        calculate_visibles( lmp );
 | 
						|
        ++recs_read;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        return recs_read;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   make_rrr_room_rows
 | 
						|
lmp:        current lmp
 | 
						|
nbr_rows:   nbr of rows to scroll
 | 
						|
returns:    pixels to scroll
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static int
 | 
						|
make_rrr_room_rows( LM_DATA * lmp, int *rows, BOOLEAN do_redraw )
 | 
						|
{
 | 
						|
  int nbr_rows = *rows;
 | 
						|
 | 
						|
  if ( nbr_rows < 0 )
 | 
						|
  {
 | 
						|
    /* convert nbr_rows to positive, for ease of programming */
 | 
						|
    nbr_rows = -nbr_rows;
 | 
						|
    while ( TRUE )
 | 
						|
    {
 | 
						|
      if ( !nbr_rows )
 | 
						|
      {
 | 
						|
        *rows = 0;
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
      if ( lmp->first_fully_vis - nbr_rows >= 0 )
 | 
						|
      {
 | 
						|
        int pixels;
 | 
						|
 | 
						|
        pixels = -( lmp->pix_offsets[lmp->first_fully_vis] -
 | 
						|
                    lmp->pix_offsets[lmp->first_fully_vis - nbr_rows] );
 | 
						|
        lmp->update_rows_at_top = nbr_rows;
 | 
						|
        *rows = nbr_rows;
 | 
						|
        return pixels;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if ( !lmp->get_all_records && get_previous_rec( lmp ) )
 | 
						|
        {
 | 
						|
          lmp->pix_heights[0] = lm_calculate_row_height( lmp, 0 );
 | 
						|
          lmp->rrr_offset -= lmp->pix_heights[0];
 | 
						|
          calculate_pix_offsets( lmp, do_redraw );
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          calculate_pix_offsets( lmp, do_redraw );
 | 
						|
          nbr_rows = lmp->first_fully_vis;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    BOOLEAN get_next_accepted = TRUE;
 | 
						|
    int pixels;
 | 
						|
 | 
						|
    pixels = lmp->pix_offsets[lmp->first_fully_vis + nbr_rows] -
 | 
						|
            lmp->pix_offsets[lmp->first_fully_vis];
 | 
						|
    while ( TRUE )
 | 
						|
    {
 | 
						|
      int delta_avail;
 | 
						|
 | 
						|
      if ( !nbr_rows )
 | 
						|
      {
 | 
						|
        *rows = 0;
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
      /* if get_all_records is true, then we never need to get more records if
 | 
						|
      * there is a row beyond the last partially visible row, then we don't
 | 
						|
      * need to get more records if a get next has been refused, then we have
 | 
						|
      * all the records that we are going to get */
 | 
						|
      if ( lmp->get_all_records ||
 | 
						|
          lmp->last_fully_vis + 1 + nbr_rows < lmp->nbr_realized_rows ||
 | 
						|
          !get_next_accepted )
 | 
						|
      {
 | 
						|
        delta_avail = lmp->pix_offsets[lmp->nbr_realized_rows - 1] +
 | 
						|
                lmp->pix_heights[lmp->nbr_realized_rows - 1] +
 | 
						|
                lmp->rrr_offset - lmp->mlr_height;
 | 
						|
        if ( lmp->get_all_records || pixels <= delta_avail || !get_next_accepted )
 | 
						|
        {
 | 
						|
          int nrows,
 | 
						|
          cnt,
 | 
						|
          pcnt;
 | 
						|
 | 
						|
          for ( nrows = 0, cnt = lmp->last_fully_vis + 1, pcnt = 0;
 | 
						|
                pcnt < pixels && cnt < lmp->nbr_realized_rows;
 | 
						|
                ++nrows, ++cnt, pcnt += lmp->pix_heights[cnt] )
 | 
						|
            ;
 | 
						|
          lmp->update_rows_at_bottom = nrows;
 | 
						|
          *rows = nbr_rows;
 | 
						|
          return pixels;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if ( !lmp->get_all_records
 | 
						|
          && ( get_next_accepted = get_next_rec( lmp, FALSE ) ) != 0 )
 | 
						|
        calculate_pix_offsets( lmp, do_redraw );
 | 
						|
      else
 | 
						|
      {
 | 
						|
        calculate_pix_offsets( lmp, do_redraw );
 | 
						|
        nbr_rows = lmp->nbr_realized_rows - 1 - lmp->last_fully_vis;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
make_room_rows( LM_DATA * lm_data, int rows, BOOLEAN do_draw )
 | 
						|
{
 | 
						|
  return make_rrr_room_rows( lm_data, &rows, do_draw );
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   do_scroll_bar
 | 
						|
itf:        current itf
 | 
						|
listdata:   list_data
 | 
						|
list:       list
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
do_scroll_bar( XI_LIST_DATA * listdata )
 | 
						|
{
 | 
						|
  LM_DATA *lmp;
 | 
						|
 | 
						|
  if ( listdata->scroll_bar )
 | 
						|
  {
 | 
						|
    lmp = ( LM_DATA * ) listdata->lm;
 | 
						|
    if ( lmp->get_all_records )
 | 
						|
    {
 | 
						|
      int top,
 | 
						|
      prop;
 | 
						|
 | 
						|
      if ( lmp->rrr_offset == 0 && lmp->rrr_bottom < lmp->mlr_height )
 | 
						|
      {
 | 
						|
        top = 0;
 | 
						|
        prop = 100;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        top = ( int ) ( -lmp->rrr_offset * 100L / lmp->rrr_bottom );
 | 
						|
        if ( lmp->mlr_height - lmp->rrr_offset >= lmp->rrr_bottom - 1 )
 | 
						|
          prop = 100 - top;
 | 
						|
        else
 | 
						|
          prop = ( int ) ( lmp->mlr_height * 100L / lmp->rrr_bottom );
 | 
						|
      }
 | 
						|
      prop = max( 0, min( 100, prop ) );
 | 
						|
      XinScrollBarSet( listdata->sb_win, XinScrollBarTypeEither, 0, 100,
 | 
						|
                      prop, top );
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      int percent1 = 0;
 | 
						|
      int percent2 = 100;
 | 
						|
      int prop = 100;
 | 
						|
 | 
						|
      if ( lmp->nbr_realized_rows > 1 )
 | 
						|
      {
 | 
						|
        do_lm_cb( listdata->lm, LM_CB_GET_PERCENT, lmp->first_fully_vis,
 | 
						|
                  0, NULL, &percent1, 0 );
 | 
						|
        do_lm_cb( listdata->lm, LM_CB_GET_PERCENT, lmp->last_fully_vis,
 | 
						|
                  0, NULL, &percent2, 0 );
 | 
						|
	      prop = min(100, max( 1, ( percent2 - percent1 ) ) );
 | 
						|
#if XIWS == XIWS_WXGTK
 | 
						|
				const int act_pos = XinScrollBarPositionGet( listdata->sb_win, XinScrollBarTypeEither );
 | 
						|
				if (act_pos >= percent1 && act_pos <= percent2)
 | 
						|
					percent1 = -1;
 | 
						|
#endif
 | 
						|
      }
 | 
						|
#if XIWS != XIWS_WXGTK
 | 
						|
			else
 | 
						|
      	prop = min(100, max( 1, ( percent2 - percent1 ) ) );
 | 
						|
#endif
 | 
						|
      XinScrollBarSet( listdata->sb_win, XinScrollBarTypeEither, 0,
 | 
						|
                      100, prop, percent1 );
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:       lm_remove_all_rows
 | 
						|
lm:             current lm
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
 | 
						|
void
 | 
						|
lm_remove_all_rows( LM_DATA * lmp, BOOLEAN delete_focus )
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  LM_CB_DATA lm_cb_data;
 | 
						|
 | 
						|
  if ( lm_focus_rec_get( lmp ) && delete_focus )
 | 
						|
  {
 | 
						|
    int idx;
 | 
						|
    BOOLEAN found = FALSE;
 | 
						|
 | 
						|
    for ( idx = 0; idx < lmp->nbr_realized_rows; ++idx )
 | 
						|
    {
 | 
						|
      if ( lm_focus_rec_get( lmp ) == lmp->recs[idx] )
 | 
						|
      {
 | 
						|
        found = TRUE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if ( !found )
 | 
						|
    {
 | 
						|
      lm_cb_data.lm = ( LM ) lmp;
 | 
						|
      lm_cb_data.cb_type = LM_CB_REC_FREE;
 | 
						|
      lm_cb_data.cid = lmp->cid;
 | 
						|
      lm_cb_data.win = lmp->win;
 | 
						|
      lm_cb_data.v.rec_free.record = lm_focus_rec_get( lmp );
 | 
						|
      ( *lmp->lm_cb ) ( &lm_cb_data );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for ( i = 0; i < lmp->nbr_realized_rows; ++i )
 | 
						|
    lm_do_rec_event( lmp, i, XIE_REC_FREE );
 | 
						|
 | 
						|
  lmp->nbr_realized_rows = 0;
 | 
						|
  lmp->rrr_bottom = 0;
 | 
						|
  lmp->rrr_offset = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
lm_row_has_focus( LM_DATA * lmp, int row, BOOLEAN is_vert_scrolled )
 | 
						|
{
 | 
						|
  XI_ITF_DATA *itf;
 | 
						|
  XI_OBJ *focus_obj;
 | 
						|
  XI_CELL_DATA *cd;
 | 
						|
 | 
						|
#if 0
 | 
						|
  if ( lmp->txt_is_invisible && !lmp->horizontally_scrolling_list )
 | 
						|
    return FALSE;
 | 
						|
#endif
 | 
						|
  itf = lmp->itf_obj->v.itf;
 | 
						|
  focus_obj = itf->focus_obj;
 | 
						|
  if ( focus_obj != NULL && focus_obj->parent == lmp->list_obj &&
 | 
						|
      focus_obj->type == XIT_CELL )
 | 
						|
  {
 | 
						|
    cd = &focus_obj->v.cell;
 | 
						|
    return ( cd->row == row && cd->is_vert_scrolled == is_vert_scrolled );
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:       fill_previous
 | 
						|
returns:        # of records read
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static int
 | 
						|
fill_previous( LM_DATA * lmp )
 | 
						|
{
 | 
						|
  int *pix_heights,
 | 
						|
  *pix_offsets;
 | 
						|
  int offset,
 | 
						|
  height;
 | 
						|
  int i;
 | 
						|
  int result = 0;
 | 
						|
 | 
						|
  while ( TRUE )
 | 
						|
  {
 | 
						|
 | 
						|
    if ( !get_previous_rec( lmp ) )
 | 
						|
      break;
 | 
						|
    result++;
 | 
						|
    /* recalculate the heights and offsets of every row */
 | 
						|
    lmp->pix_heights[0] = lm_calculate_row_height( lmp, 0 );
 | 
						|
    offset = 0;
 | 
						|
    for ( i = 0, pix_heights = &lmp->pix_heights[0],
 | 
						|
          pix_offsets = &lmp->pix_offsets[0];
 | 
						|
          i < lmp->nbr_realized_rows;
 | 
						|
          ++i, ++pix_heights, ++pix_offsets )
 | 
						|
    {
 | 
						|
      *pix_offsets = offset;
 | 
						|
      offset += *pix_heights;
 | 
						|
    }
 | 
						|
 | 
						|
    calculate_visibles( lmp );
 | 
						|
 | 
						|
    /* if we finally have enough rows to display the entire list
 | 
						|
    *
 | 
						|
    * note: we subtract 1 from the space necessary because it is not necessary to
 | 
						|
    * create space for the pixel at the bottom of the last row. */
 | 
						|
    height = lmp->pix_heights[lmp->nbr_realized_rows - 1];
 | 
						|
    if ( !height )
 | 
						|
      height = lmp->pix_row_spacing;
 | 
						|
    if ( !lmp->get_all_records &&
 | 
						|
        ( lmp->pix_offsets[lmp->nbr_realized_rows - 1] +
 | 
						|
          height - 1
 | 
						|
          >= lmp->mlr_height ) )
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  calculate_pix_offsets( lmp, FALSE );
 | 
						|
 | 
						|
  lmp->rrr_bottom = lmp->pix_offsets[lmp->nbr_realized_rows - 1]
 | 
						|
          + lmp->pix_heights[lmp->nbr_realized_rows - 1];
 | 
						|
  /* subtract 1 from rrr_bottom because of the pixel at the bottom of the last
 | 
						|
  * row. */
 | 
						|
  lmp->rrr_offset = lmp->mlr_height - ( lmp->rrr_bottom - 1 );
 | 
						|
  lmp->rrr_offset = min( 0, lmp->rrr_offset );
 | 
						|
 | 
						|
  /* although we have adjusted pix_offsets, and pix_heights, it is still
 | 
						|
  * necessary to calculate the first and last fully visible rows */
 | 
						|
  calculate_visibles( lmp );
 | 
						|
 | 
						|
  /* if the page down does not make the first row editable, then scroll the
 | 
						|
  * exact amount to make it editable */
 | 
						|
  if ( -lmp->rrr_offset !=
 | 
						|
      lmp->pix_offsets[lmp->first_fully_vis] )
 | 
						|
  {
 | 
						|
    lmp->rrr_offset = -lmp->pix_offsets[lmp->first_fully_vis];
 | 
						|
    calculate_visibles( lmp );
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*/
 | 
						|
/*           data structure for passing around lm_scroll functions         */
 | 
						|
/*-------------------------------------------------------------------------*/
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
  int nbr_lines;
 | 
						|
  int percent;
 | 
						|
  long rec;
 | 
						|
  BOOLEAN have_rec;
 | 
						|
  XinColor color;
 | 
						|
  unsigned long attrib;
 | 
						|
  int row_height_arg;
 | 
						|
  int scroll_type;
 | 
						|
  int pix_overlap;
 | 
						|
  int nbr_pixels;
 | 
						|
  XinRect focus_cell_rct;
 | 
						|
  BOOLEAN have_pixels;
 | 
						|
  BOOLEAN list_had_focus;
 | 
						|
  BOOLEAN is_first_or_last;
 | 
						|
  int focus_row;
 | 
						|
  int focus_column;
 | 
						|
  BOOLEAN v_scrolled;
 | 
						|
  int pixels_scrolled;
 | 
						|
} lm_scroll_data;
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*/
 | 
						|
/*  lm_scroll_data_construct                                               */
 | 
						|
/*-------------------------------------------------------------------------*/
 | 
						|
 | 
						|
static void
 | 
						|
lm_scroll_data_construct( LM_DATA * lmp, lm_scroll_data * data,
 | 
						|
                          LM_SCROLL_ARG * arg )
 | 
						|
{
 | 
						|
  int pref_overlap;
 | 
						|
 | 
						|
  data->nbr_lines = arg->nbr_lines;
 | 
						|
  data->percent = arg->percent;
 | 
						|
  data->rec = arg->rec;
 | 
						|
  data->have_rec = arg->have_rec;
 | 
						|
  data->color = arg->color;
 | 
						|
  data->attrib = arg->attrib;
 | 
						|
  data->row_height_arg = arg->row_height;
 | 
						|
  data->have_pixels = FALSE;
 | 
						|
  data->list_had_focus = FALSE;
 | 
						|
  data->is_first_or_last = FALSE;
 | 
						|
  if ( arg->nbr_lines == XI_SCROLL_FIRST && arg->percent == 100 )
 | 
						|
    data->nbr_lines = XI_SCROLL_LAST;
 | 
						|
  if ( !lmp->nbr_realized_rows )
 | 
						|
    data->nbr_lines = XI_SCROLL_FIRST;
 | 
						|
  if ( arg->have_rec )
 | 
						|
  {
 | 
						|
    if ( arg->rec_at_top )
 | 
						|
      data->nbr_lines = XI_SCROLL_FIRST;
 | 
						|
    else
 | 
						|
      data->nbr_lines = XI_SCROLL_LAST;
 | 
						|
  }
 | 
						|
  data->scroll_type = data->nbr_lines;
 | 
						|
  pref_overlap = ( int ) xi_get_pref( XI_PREF_OVERLAP );
 | 
						|
  data->pix_overlap = pref_overlap * lmp->pix_row_spacing;
 | 
						|
  data->pixels_scrolled = 0;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*/
 | 
						|
/*  lm_scroll_remove focus                                                 */
 | 
						|
/*-------------------------------------------------------------------------*/
 | 
						|
 | 
						|
static BOOLEAN
 | 
						|
lm_scroll_remove_focus( LM_DATA * lmp, lm_scroll_data * data,
 | 
						|
                        XI_OBJ * old_focus_obj )
 | 
						|
{
 | 
						|
  /* remove the focus from the list being scrolled */
 | 
						|
  if ( lm_focus_list_has( lmp ) )
 | 
						|
  {
 | 
						|
    data->list_had_focus = TRUE;
 | 
						|
    lm_focus_cell_get( lmp, &data->focus_row, &data->focus_column,
 | 
						|
                      &data->v_scrolled );
 | 
						|
    if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | 
						|
    {
 | 
						|
      if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | 
						|
      {
 | 
						|
        lm_focus_cell_invis_make( lmp );
 | 
						|
        switch ( data->nbr_lines )
 | 
						|
        {
 | 
						|
          case XI_SCROLL_FIRST:
 | 
						|
            lm_focus_rec_is_above_set( lmp, FALSE );
 | 
						|
          case XI_SCROLL_LAST:
 | 
						|
            lm_focus_rec_is_above_set( lmp, TRUE );
 | 
						|
            break;
 | 
						|
          case XI_SCROLL_PGUP:
 | 
						|
            lm_focus_rec_is_above_set( lmp, FALSE );
 | 
						|
            break;
 | 
						|
          case XI_SCROLL_PGDOWN:
 | 
						|
            lm_focus_rec_is_above_set( lmp, TRUE );
 | 
						|
            break;
 | 
						|
          default:
 | 
						|
            lm_focus_rec_is_above_set( lmp, ( BOOLEAN ) ( data->nbr_lines > 0 ) );
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      xi_get_rect( old_focus_obj, &data->focus_cell_rct );
 | 
						|
      if ( !xi_move_focus( lmp->itf_obj ) )
 | 
						|
        return FALSE;
 | 
						|
      if (data->nbr_lines == XI_SCROLL_FIRST || data->nbr_lines == XI_SCROLL_LAST)
 | 
						|
      { /* The old data went away, so the old focus location is no longer valid. */
 | 
						|
        lmp->list_obj->v.list->focus_cell->v.cell.row = 0;
 | 
						|
        lmp->list_obj->v.list->focus_cell->v.cell.column = 0;
 | 
						|
        lmp->list_obj->v.list->focus_cell->v.cell.is_vert_scrolled = FALSE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*  lm_scroll_calc_lines                                                    */
 | 
						|
/*  if nbr_lines is not an integral, and instead is one of XI_SCROLL_FIRST, */
 | 
						|
/*  XI_SCROLL_LAST, XI_SCROLL_PGUP, or XI_SCROLL_PGDOWN, then calculate     */
 | 
						|
/*  the number of lines.                                                    */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static void
 | 
						|
lm_scroll_calc_lines( LM_DATA * lmp, lm_scroll_data * data )
 | 
						|
{
 | 
						|
  switch ( data->nbr_lines )
 | 
						|
  {
 | 
						|
case XI_SCROLL_FIRST:
 | 
						|
case XI_SCROLL_LAST:
 | 
						|
      data->is_first_or_last = TRUE;
 | 
						|
      break;
 | 
						|
    case XI_SCROLL_PGUP:
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
      data->nbr_pixels = -( lmp->mlr_height - data->pix_overlap );
 | 
						|
#else
 | 
						|
      data->nbr_pixels = -( lmp->mlr_height - data->pix_overlap + 1 );
 | 
						|
#endif
 | 
						|
      data->have_pixels = TRUE;
 | 
						|
      break;
 | 
						|
    case XI_SCROLL_PGDOWN:
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
      data->nbr_pixels = lmp->mlr_height - data->pix_overlap;
 | 
						|
#else
 | 
						|
      data->nbr_pixels = lmp->mlr_height - data->pix_overlap + 1;
 | 
						|
#endif
 | 
						|
      data->have_pixels = TRUE;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_get_initial_rec                                              */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static BOOLEAN
 | 
						|
lm_scroll_get_initial_rec( LM_DATA * lmp, lm_scroll_data * data,
 | 
						|
                          int record_location, LM_CB_TYPE event_type )
 | 
						|
{
 | 
						|
  int row_height;
 | 
						|
  BOOLEAN refused;
 | 
						|
 | 
						|
  /* first, get rid of all rows, except the focus row */
 | 
						|
  lm_remove_all_rows( lmp, FALSE );
 | 
						|
  make_rec_available( lmp, ( BOOLEAN ) record_location, ( BOOLEAN ) ! data->have_rec, TRUE );
 | 
						|
  if ( data->have_rec )
 | 
						|
  {
 | 
						|
    LM_CELL_DATA *cell_data;
 | 
						|
    int i;
 | 
						|
 | 
						|
    lmp->recs[0] = data->rec;
 | 
						|
    lmp->row_colors[0] = data->color;
 | 
						|
    lmp->row_attribs[0] = data->attrib;
 | 
						|
    row_height = data->row_height_arg;
 | 
						|
    refused = FALSE;
 | 
						|
    /* cell_data_construct */
 | 
						|
    cell_data = lmp->cell_data[0];
 | 
						|
    for ( i = 0; i < lmp->nbr_columns; ++i, ++cell_data )
 | 
						|
    {
 | 
						|
      memset( ( char * ) cell_data, '\0', sizeof( LM_CELL_DATA ) );
 | 
						|
      lm_xi_text_construct( lmp, 0, i );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    refused = do_lm_cb_get( ( LM ) lmp, event_type, &lmp->recs[0], &lmp->recs[0],
 | 
						|
                            data->percent, &lmp->row_colors[0],
 | 
						|
                            &lmp->row_attribs[0], &row_height );
 | 
						|
    if ( refused )
 | 
						|
    {
 | 
						|
      lm_do_rec_event( lmp, lmp->nbr_realized_rows - 1, XIE_REC_FREE );
 | 
						|
      --lmp->nbr_realized_rows;
 | 
						|
      calculate_visibles( lmp );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if ( !refused )
 | 
						|
  {
 | 
						|
    if ( row_height )
 | 
						|
    {
 | 
						|
      lmp->pix_heights[0] = row_height;
 | 
						|
      lmp->set_heights[0] = TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      lmp->pix_heights[0] = 0;
 | 
						|
      lmp->set_heights[0] = FALSE;
 | 
						|
    }
 | 
						|
    lmp->pix_offsets[0] = 0;
 | 
						|
    lmp->pix_heights[0] = lm_calculate_row_height( lmp, 0 );
 | 
						|
    lm_invalidate_rows_internal( ( LM ) lmp, 0, 0, FALSE, -1, TRUE );
 | 
						|
  }
 | 
						|
  return !refused;
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_fill_forward                                                 */
 | 
						|
/*   returns # of records read if fill previous called, otherwise 0         */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
 | 
						|
static int
 | 
						|
lm_scroll_fill_forward( LM_DATA * lmp, BOOLEAN have_rec )
 | 
						|
{
 | 
						|
  BOOLEAN refused;
 | 
						|
 | 
						|
  while ( TRUE )
 | 
						|
  {
 | 
						|
    int idx;
 | 
						|
 | 
						|
    refused = !get_next_rec( lmp, TRUE );
 | 
						|
    if ( refused )
 | 
						|
      break;
 | 
						|
    idx = lmp->nbr_realized_rows - 1;
 | 
						|
    lmp->pix_heights[idx] = lm_calculate_row_height( lmp, idx );
 | 
						|
    if ( idx > 0 )
 | 
						|
      lmp->pix_offsets[idx] = lmp->pix_offsets[idx - 1]
 | 
						|
              + lmp->pix_heights[idx - 1];
 | 
						|
    else
 | 
						|
      lmp->pix_offsets[idx] = 0;
 | 
						|
 | 
						|
    /* if we finally have enough rows to display the entire list */
 | 
						|
    if ( !lmp->get_all_records && ( lmp->pix_offsets[idx] + lmp->pix_heights[idx]
 | 
						|
                                    >= lmp->mlr_height ) )
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  /* although we have adjusted pix_offsets, and pix_heights, it is still
 | 
						|
  * necessary to calculate the first and last fully visible rows */
 | 
						|
  calculate_visibles( lmp );
 | 
						|
 | 
						|
  /* If we have the first record and the list is not full, try getting previous
 | 
						|
  * records. */
 | 
						|
  if ( have_rec && refused )
 | 
						|
    return fill_previous( lmp );
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_first                                                        */
 | 
						|
/*   returns row # of first record requested - i.e. for xi_scroll_rec, the  */
 | 
						|
/*   row # of the new record.  for scroll first with a percentage, the      */
 | 
						|
/*   row # of that percentage.  Normally 0, but with back-fill, can be      */
 | 
						|
/*   a positive number.                                                     */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static int
 | 
						|
lm_scroll_first( LM_DATA * lmp, lm_scroll_data * data )
 | 
						|
{
 | 
						|
  int result = 0;
 | 
						|
 | 
						|
  if ( lmp->get_all_records && lmp->nbr_realized_rows > 0 )
 | 
						|
  {
 | 
						|
    /* have_rec */
 | 
						|
    lmp->rrr_offset = -( int ) ( ( long ) lmp->rrr_bottom * data->percent / 100 );
 | 
						|
    calculate_visibles( lmp );
 | 
						|
    lmp->rrr_offset = -lmp->pix_offsets[lmp->first_fully_vis];
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if ( lm_scroll_get_initial_rec( lmp, data, REC_AT_BOTTOM, LM_CB_GET_FIRST ) )
 | 
						|
      result = lm_scroll_fill_forward( lmp, data->have_rec );
 | 
						|
    if ( !lmp->get_all_records )
 | 
						|
    {
 | 
						|
      int nbr_to_free,
 | 
						|
      cnt,
 | 
						|
      idx;
 | 
						|
 | 
						|
      nbr_to_free = lmp->first_fully_vis - 1;
 | 
						|
      if ( nbr_to_free > 0 )
 | 
						|
      {
 | 
						|
        for ( cnt = 0; cnt < nbr_to_free; cnt++ )
 | 
						|
        {
 | 
						|
          lmp->rrr_offset += lmp->pix_heights[cnt];
 | 
						|
          lm_do_rec_event( lmp, cnt, XIE_REC_FREE );
 | 
						|
        }
 | 
						|
 | 
						|
        for ( idx = nbr_to_free; idx < lmp->nbr_realized_rows; ++idx )
 | 
						|
          lm_row_copy( lmp, idx, idx - nbr_to_free );
 | 
						|
        result -= nbr_to_free;
 | 
						|
        lm_adjust_rows( lmp, -nbr_to_free );
 | 
						|
        lmp->nbr_realized_rows -= nbr_to_free;
 | 
						|
      }
 | 
						|
      /* free any unnecessary records at the end of the list */
 | 
						|
      nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
      for ( idx = lmp->nbr_realized_rows - nbr_to_free, cnt = 0;
 | 
						|
            cnt < nbr_to_free; idx++, cnt++ )
 | 
						|
        lm_do_rec_event( lmp, idx, XIE_REC_FREE );
 | 
						|
      lmp->nbr_realized_rows -= cnt;
 | 
						|
      calculate_pix_offsets( lmp, FALSE );
 | 
						|
      {
 | 
						|
        XI_OBJ *focus_obj;
 | 
						|
 | 
						|
        focus_obj = lmp->itf_obj->v.itf->focus_obj;
 | 
						|
        if ( focus_obj && focus_obj->cid == lmp->cid )
 | 
						|
        {
 | 
						|
          if ( focus_obj && focus_obj->type == XIT_CELL )
 | 
						|
          {
 | 
						|
            focus_obj->v.cell.is_vert_scrolled = TRUE;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_last                                                         */
 | 
						|
/*   returns row # of requested row                                         */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static int
 | 
						|
lm_scroll_last( LM_DATA * lmp, lm_scroll_data * data )
 | 
						|
{                               /* scroll last */
 | 
						|
  int result = 0;
 | 
						|
 | 
						|
  if ( lmp->get_all_records )
 | 
						|
  {
 | 
						|
    if ( lmp->rrr_bottom < lmp->mlr_height )
 | 
						|
      lmp->rrr_offset = 0;
 | 
						|
    else
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
      lmp->rrr_offset = lmp->mlr_height - lmp->rrr_bottom;
 | 
						|
#else
 | 
						|
      lmp->rrr_offset = lmp->mlr_height - lmp->rrr_bottom + 1;
 | 
						|
#endif
 | 
						|
    calculate_visibles( lmp );
 | 
						|
 | 
						|
    /* if the page up does not make the first row editable, then scroll the
 | 
						|
    * exact amount to make it editable */
 | 
						|
    if ( -lmp->rrr_offset !=
 | 
						|
        lmp->pix_offsets[lmp->first_fully_vis] )
 | 
						|
    {
 | 
						|
      int p;
 | 
						|
 | 
						|
      p = lmp->pix_offsets[lmp->first_fully_vis] +
 | 
						|
              lmp->rrr_offset;
 | 
						|
      data->nbr_pixels += p;
 | 
						|
      lmp->rrr_offset -= p;
 | 
						|
      calculate_visibles( lmp );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    data->percent = 0;
 | 
						|
    if ( lm_scroll_get_initial_rec( lmp, data, REC_AT_TOP, LM_CB_GET_LAST ) )
 | 
						|
    {
 | 
						|
      result = fill_previous( lmp );
 | 
						|
      /* get one record after the last record, so that there will not be a gray
 | 
						|
      * space below the last record, unless there are no more records. */
 | 
						|
      get_next_rec( lmp, FALSE );
 | 
						|
      calculate_pix_offsets( lmp, FALSE );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_calc_pixels                                                  */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static void
 | 
						|
lm_scroll_calc_pixels( LM_DATA * lmp, lm_scroll_data * data )
 | 
						|
{
 | 
						|
  /* calculate the max number of pixels that we should scroll */
 | 
						|
  if ( data->nbr_pixels < 0 )
 | 
						|
  {
 | 
						|
    int p;
 | 
						|
 | 
						|
    data->nbr_pixels = max( data->nbr_pixels, lmp->rrr_offset );
 | 
						|
    lmp->rrr_offset -= data->nbr_pixels;
 | 
						|
    calculate_visibles( lmp );
 | 
						|
 | 
						|
    /* if the page up does not make the first row editable, then scroll the
 | 
						|
    * exact amount to make it editable */
 | 
						|
    if ( -lmp->rrr_offset !=
 | 
						|
        lmp->pix_offsets[lmp->first_fully_vis] )
 | 
						|
    {
 | 
						|
      p = lmp->pix_offsets[lmp->first_fully_vis - 1] +
 | 
						|
              lmp->rrr_offset;
 | 
						|
      data->nbr_pixels += p;
 | 
						|
      lmp->rrr_offset -= p;
 | 
						|
      calculate_visibles( lmp );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    int p;
 | 
						|
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
 | 
						|
    /* following line puts row coming onto the list at the bottom of the list
 | 
						|
    * completly on the list.  new behavior is to have the row at the top of
 | 
						|
    * the list to always be completely on the list. nbr_pixels =
 | 
						|
    * min(nbr_pixels, lmp->rrr_bottom - lmp->mlr_height + lmp->rrr_offset); */
 | 
						|
    data->nbr_pixels = max( data->nbr_pixels, 0 );
 | 
						|
    lmp->rrr_offset -= data->nbr_pixels;
 | 
						|
    calculate_visibles( lmp );
 | 
						|
 | 
						|
    /* if the page down does not make the first row editable, then scroll the
 | 
						|
    * exact amount to make it editable */
 | 
						|
    if ( -lmp->rrr_offset !=
 | 
						|
        lmp->pix_offsets[lmp->first_fully_vis] )
 | 
						|
    {
 | 
						|
      p = lmp->pix_offsets[lmp->first_fully_vis - 1] +
 | 
						|
              lmp->rrr_offset;
 | 
						|
      data->nbr_pixels += p;
 | 
						|
      lmp->rrr_offset -= p;
 | 
						|
      calculate_visibles( lmp );
 | 
						|
    }
 | 
						|
 | 
						|
    /* if the page down leaves too much room at the bottom, then make more rows
 | 
						|
    * visible. */
 | 
						|
    while ( TRUE )
 | 
						|
    {
 | 
						|
      int h,
 | 
						|
      pix_left;
 | 
						|
 | 
						|
      if ( lmp->first_fully_vis == 0 )
 | 
						|
        break;
 | 
						|
      h = lmp->pix_heights[lmp->first_fully_vis - 1];
 | 
						|
      /* Add 1 to pix_left (pixels left in mlr), because it is ok for the pixel
 | 
						|
      * required for the rule at the bottom of the row to fall below the
 | 
						|
      * visible portion of the list. */
 | 
						|
      pix_left = -( lmp->pix_offsets[lmp->nbr_realized_rows - 1] +
 | 
						|
                    lmp->pix_heights[lmp->nbr_realized_rows - 1] +
 | 
						|
                    lmp->rrr_offset - lmp->mlr_height ) + 1;
 | 
						|
      if ( pix_left < h )
 | 
						|
        break;
 | 
						|
      data->nbr_pixels -= h;
 | 
						|
      lmp->rrr_offset += h;
 | 
						|
      calculate_visibles( lmp );
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_scroll_rct
 | 
						|
lmp:        current lmp
 | 
						|
r:          pointer to rectangle to be filled in
 | 
						|
returns:    r
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
XinRect *
 | 
						|
lm_get_scroll_rct( LM_DATA * lmp, XinRect * r )
 | 
						|
{
 | 
						|
  *r = lmp->mlr;
 | 
						|
  if ( lmp->pixel_width )
 | 
						|
    r->right = r->left + lmp->pixel_width + BORDER_WIDTH - 1;
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_middle                                                       */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static int
 | 
						|
lm_scroll_middle( LM_DATA * lmp, lm_scroll_data * data,
 | 
						|
                  BOOLEAN invalidate )
 | 
						|
{
 | 
						|
  int recs_read;
 | 
						|
 | 
						|
  recs_read = 0;
 | 
						|
  if ( data->have_pixels )
 | 
						|
    recs_read = lm_make_rrr_room_pix( lmp, data->nbr_pixels, FALSE );
 | 
						|
  else if ( data->nbr_lines )
 | 
						|
  {
 | 
						|
    recs_read = data->nbr_lines;
 | 
						|
    data->nbr_pixels = make_rrr_room_rows( lmp, &recs_read, FALSE );
 | 
						|
  }
 | 
						|
  lm_scroll_calc_pixels( lmp, data );
 | 
						|
  if ( !lmp->get_all_records )
 | 
						|
  {
 | 
						|
    int nbr_to_free,
 | 
						|
    cnt,
 | 
						|
    idx;
 | 
						|
 | 
						|
    nbr_to_free = lmp->first_fully_vis;
 | 
						|
    if ( nbr_to_free )
 | 
						|
    {
 | 
						|
      for ( cnt = 0; cnt < nbr_to_free; cnt++ )
 | 
						|
      {
 | 
						|
        lmp->rrr_offset += lmp->pix_heights[cnt];
 | 
						|
        lm_do_rec_event( lmp, cnt, XIE_REC_FREE );
 | 
						|
      }
 | 
						|
 | 
						|
      for ( cnt = nbr_to_free; cnt < lmp->nbr_realized_rows; ++cnt )
 | 
						|
        lm_row_copy( lmp, cnt, cnt - nbr_to_free );
 | 
						|
      lm_adjust_rows( lmp, -nbr_to_free );
 | 
						|
      lmp->nbr_realized_rows -= nbr_to_free;
 | 
						|
    }
 | 
						|
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
    /* free any unnecessary records at the end of the list */
 | 
						|
    nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
    for ( idx = lmp->nbr_realized_rows - nbr_to_free, cnt = 0;
 | 
						|
          cnt < nbr_to_free;
 | 
						|
          idx++, cnt++ )
 | 
						|
      lm_do_rec_event( lmp, idx, XIE_REC_FREE );
 | 
						|
    lmp->nbr_realized_rows -= cnt;
 | 
						|
 | 
						|
    for ( idx = lmp->nbr_realized_rows;
 | 
						|
          idx < lmp->realized_rows_array_len;
 | 
						|
          ++idx )
 | 
						|
      init_row( lmp, idx );
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
  }
 | 
						|
 | 
						|
  if ( invalidate )
 | 
						|
  {
 | 
						|
    XinRect r;
 | 
						|
 | 
						|
    lm_get_scroll_rct( lmp, &r );
 | 
						|
    xi_set_clip( lmp->win, NULL );
 | 
						|
    if ( data->nbr_pixels )
 | 
						|
    {
 | 
						|
      XinWindowPaintForce( lmp->win );
 | 
						|
      xi_set_update_obj( lmp->list_obj );
 | 
						|
      lmp->update_cells_only = TRUE;
 | 
						|
      xi_scroll_rect( lmp->win, &r, 0, -data->nbr_pixels );
 | 
						|
      data->pixels_scrolled = data->nbr_pixels;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return recs_read;
 | 
						|
}
 | 
						|
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
/*   lm_scroll_replace_focus                                                */
 | 
						|
/*------------------------------------------------------------------------- */
 | 
						|
static void
 | 
						|
lm_scroll_replace_focus( LM_DATA * lmp, lm_scroll_data * data,
 | 
						|
                        XI_OBJ * old_focus_obj, BOOLEAN same_cell )
 | 
						|
{
 | 
						|
  /* put the focus back */
 | 
						|
  if ( data->list_had_focus )
 | 
						|
  {
 | 
						|
    if ( old_focus_obj->type == XIT_CELL )
 | 
						|
    {
 | 
						|
      if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | 
						|
        lm_focus_cell_visible_attempt( lmp );
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if ( same_cell )
 | 
						|
        {
 | 
						|
          int col = old_focus_obj->v.cell.column;
 | 
						|
          int row,
 | 
						|
          t,
 | 
						|
          b;
 | 
						|
          int max_intersect,
 | 
						|
          intersect_row;
 | 
						|
          XI_OBJ cell;
 | 
						|
          XinRect cell_rct;
 | 
						|
          int tr;
 | 
						|
 | 
						|
          max_intersect = 0;
 | 
						|
          intersect_row = -1;
 | 
						|
          tr = min( lmp->nbr_realized_rows, lmp->last_fully_vis + 1 );
 | 
						|
          for ( row = lmp->first_fully_vis; row < tr; ++row )
 | 
						|
          {
 | 
						|
            XI_MAKE_CELL( &cell, lmp->list_obj, ( unsigned char ) row,
 | 
						|
                          ( unsigned char ) col );
 | 
						|
            xi_get_rect( &cell, &cell_rct );
 | 
						|
            t = max( cell_rct.top, data->focus_cell_rct.top );
 | 
						|
            b = min( cell_rct.bottom, data->focus_cell_rct.bottom );
 | 
						|
            if ( ( b - t ) > max_intersect )
 | 
						|
            {
 | 
						|
              max_intersect = b - t;
 | 
						|
              intersect_row = row;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          if ( intersect_row != -1 )
 | 
						|
          {
 | 
						|
            XI_MAKE_CELL( &cell, lmp->list_obj, ( unsigned char ) intersect_row,
 | 
						|
                          ( unsigned char ) col );
 | 
						|
            xi_move_focus( &cell );
 | 
						|
          }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          switch ( data->scroll_type )
 | 
						|
          {
 | 
						|
            case XI_SCROLL_FIRST:
 | 
						|
            case XI_SCROLL_PGUP:
 | 
						|
              data->focus_row = lmp->first_fully_vis;
 | 
						|
              break;
 | 
						|
            case XI_SCROLL_LAST:
 | 
						|
            case XI_SCROLL_PGDOWN:
 | 
						|
              data->focus_row = lmp->last_fully_vis;
 | 
						|
              break;
 | 
						|
            default:
 | 
						|
              data->focus_row = clip( data->focus_row, lmp->first_fully_vis,
 | 
						|
                                      lmp->last_fully_vis );
 | 
						|
              break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
      xi_move_focus( old_focus_obj );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:       lm_scroll
 | 
						|
lm:             current lm
 | 
						|
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.
 | 
						|
rec:            if have_rec is TRUE, then use rec for the first record, and don't do get first
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
int
 | 
						|
lm_scroll( LM_SCROLL_ARG * arg )
 | 
						|
{
 | 
						|
  lm_scroll_data data;
 | 
						|
  int result = 0;
 | 
						|
  XI_OBJ *old_focus_obj;
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) arg->lm;
 | 
						|
  XI_OBJ *itf = lmp->itf_obj;
 | 
						|
  BOOLEAN invalidate = !itf->v.itf->half_baked;
 | 
						|
  BOOLEAN v_scrolled,
 | 
						|
  focus;
 | 
						|
  int new_row_height;
 | 
						|
  int row,
 | 
						|
  column;
 | 
						|
 | 
						|
  if ( ( xi_get_attrib( lmp->list_obj ) & XI_ATR_VISIBLE ) == 0 )
 | 
						|
    invalidate = FALSE;
 | 
						|
  lm_scroll_data_construct( lmp, &data, arg );
 | 
						|
  /* If the focus is on the first row, and scrolling up, or the focus is on the
 | 
						|
  * last row and scrolling down, return 0. */
 | 
						|
  if ( lmp->get_all_records )
 | 
						|
  {
 | 
						|
    if ( lmp->first_fully_vis == 0 && data.nbr_lines < 0 )
 | 
						|
      return 0;
 | 
						|
    if ( lmp->last_fully_vis == lmp->nbr_realized_rows &&
 | 
						|
        data.nbr_lines > 0 && data.nbr_lines < XI_SCROLL_PGUP )
 | 
						|
      return 0;
 | 
						|
  }
 | 
						|
  if ( !lmp->itf_obj->v.itf->half_baked && invalidate )
 | 
						|
    XinWindowPaintForce( lmp->win );
 | 
						|
  old_focus_obj = itf->v.itf->focus_obj;
 | 
						|
  if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | 
						|
  {
 | 
						|
    focus = lm_focus_cell_get( lmp, &row, &column, &v_scrolled );
 | 
						|
    if ( focus && !v_scrolled )
 | 
						|
    {
 | 
						|
      new_row_height = lm_calculate_row_height( lmp, row );
 | 
						|
      if ( new_row_height != lmp->pix_heights[row] )
 | 
						|
        lm_set_row_height( ( LM ) lmp, row, new_row_height, FALSE, 0, FALSE );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if ( !lm_scroll_remove_focus( lmp, &data, old_focus_obj ) )
 | 
						|
    return 0;
 | 
						|
  lm_scroll_calc_lines( lmp, &data );
 | 
						|
  if ( data.is_first_or_last )
 | 
						|
  {
 | 
						|
    if ( data.nbr_lines == XI_SCROLL_FIRST )
 | 
						|
      result = lm_scroll_first( lmp, &data );
 | 
						|
    else
 | 
						|
      result = lm_scroll_last( lmp, &data );
 | 
						|
    if ( invalidate )
 | 
						|
    {
 | 
						|
      XinRect r;
 | 
						|
 | 
						|
      xi_invalidate_rect( lmp->win, lm_get_scroll_rct( lmp, &r ) );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    result = lm_scroll_middle( lmp, &data, invalidate );
 | 
						|
    arg->pixels_scrolled = data.pixels_scrolled;
 | 
						|
  }
 | 
						|
 | 
						|
  lm_scroll_replace_focus( lmp, &data, old_focus_obj, arg->same_cell );
 | 
						|
  if ( lmp->row_focus_border && lmp->nbr_realized_rows > 0 )
 | 
						|
  {
 | 
						|
    int focus_row,
 | 
						|
    focus_column;
 | 
						|
    BOOLEAN is_vert_scrolled;
 | 
						|
    BOOLEAN is_hscrolled;
 | 
						|
    BOOLEAN is_vis;
 | 
						|
 | 
						|
    lm_focus_cell_get( lmp, &focus_row, &focus_column, &is_vert_scrolled );
 | 
						|
    is_vis = lm_focus_cell_is_visible( lmp, &is_hscrolled );
 | 
						|
    if ( ( is_vis || is_hscrolled ) && !is_vert_scrolled )
 | 
						|
    {
 | 
						|
      lm_redraw_row( lmp, focus_row, FALSE );
 | 
						|
      if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | 
						|
        set_focus_cell_rct( lmp, focus_row, focus_column, FALSE );
 | 
						|
    }                           /* is vis */
 | 
						|
  }                             /* focus border */
 | 
						|
  do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
  if ( invalidate )
 | 
						|
    XinWindowPaintForce( lmp->win );
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_text
 | 
						|
lm:         current lm
 | 
						|
s:          string to set
 | 
						|
row:
 | 
						|
column:
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_text( LM lm, char *s, int row, int column, BOOLEAN v_scrolled )
 | 
						|
{
 | 
						|
  BOOLEAN was_suspended = FALSE;
 | 
						|
  BOOLEAN preserve_focus_text;
 | 
						|
  LM_COLUMN_DATA *lmcd;
 | 
						|
  XinRect rct;
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  lmcd = lmp->lm_column_data[column];
 | 
						|
  if ( row == LM_HEADING_TEXT )
 | 
						|
  {
 | 
						|
    lmcd->heading_text = ( char * ) xi_tree_realloc( lmcd->heading_text, strlen( s ) + 1 );
 | 
						|
    strcpy( lmcd->heading_text, s );
 | 
						|
    lm_get_cell_rect( &rct, lm, 1, column, FALSE, TRUE );
 | 
						|
    rct.top = lmp->pix_hdr_bottom -
 | 
						|
            max( lmp->pix_cell_height, lmp->min_heading_height + 2 * BORDER_WIDTH );
 | 
						|
    rct.bottom = lmp->pix_hdr_bottom;
 | 
						|
    if ( ( lmp->attrib & LM_ATR_VISIBLE ) != 0 )
 | 
						|
      xi_invalidate_rect( lmp->win, &rct );
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    int new_row_height;
 | 
						|
    LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
    cell_data = &lmp->cell_data[row][column];
 | 
						|
    preserve_focus_text = FALSE;
 | 
						|
    if ( lm_focus_cell_has( lmp, row, column, v_scrolled ) && lmp->itf_obj->v.itf->chg_flag )
 | 
						|
    {
 | 
						|
      was_suspended = TRUE;
 | 
						|
      lm_focus_cell_invis_make( lmp );
 | 
						|
      preserve_focus_text = TRUE;
 | 
						|
    }
 | 
						|
    /* If the cell has focus the XI_TEXT string needs updated */
 | 
						|
    if ( lm_focus_cell_has( lmp, row, column, v_scrolled ) )
 | 
						|
    {
 | 
						|
      xi_text_set( cell_data->xi_text, s );
 | 
						|
    }
 | 
						|
    else if ( !v_scrolled )
 | 
						|
      xi_text_set( cell_data->xi_text, s );
 | 
						|
    if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | 
						|
      lm_focus_cell_text_set( lmp, preserve_focus_text, s, row, column, v_scrolled );
 | 
						|
    if ( !v_scrolled )
 | 
						|
    {
 | 
						|
      new_row_height = lm_calculate_row_height( lmp, row );
 | 
						|
      if ( new_row_height != lmp->pix_heights[row] )
 | 
						|
        lm_set_row_height( lm, row, new_row_height, FALSE, 0, FALSE );
 | 
						|
      if ( LMP( lm )->attrib & XI_ATR_VISIBLE && LMP( lm )->cell_data[row][column].valid_data )
 | 
						|
        redraw_cell( lm, row, column, FALSE );
 | 
						|
    }
 | 
						|
    if ( was_suspended )
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   next cell
 | 
						|
lm:         current lm
 | 
						|
c:          character causing the focus to change
 | 
						|
next_row:   int pointer to be filled in with next row
 | 
						|
next_col:   int pointer to be filled in with next column
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
next_cell( LM lm, int c, int *next_row, int *next_col, BOOLEAN v_scrolled )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  switch ( c )
 | 
						|
  {
 | 
						|
    case XI_KEY_BTAB:
 | 
						|
      --*next_col;
 | 
						|
      if ( *next_col < 0 )
 | 
						|
      {
 | 
						|
        *next_col = lmp->nbr_columns - 1;
 | 
						|
        if ( ( lmp->attrib & LM_ATR_TABWRAP ) )
 | 
						|
          --* next_row;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case '\t':
 | 
						|
      ++*next_col;
 | 
						|
      if ( *next_col >= lmp->nbr_columns )
 | 
						|
      {
 | 
						|
        *next_col = 0;
 | 
						|
        if ( ( lmp->attrib & LM_ATR_TABWRAP ) )
 | 
						|
        {
 | 
						|
          if ( *next_row == 255 && v_scrolled )
 | 
						|
            *next_row = 0;
 | 
						|
          else
 | 
						|
            ++* next_row;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case XI_KEY_UP:
 | 
						|
      --*next_row;
 | 
						|
      break;
 | 
						|
    case XI_KEY_DOWN:
 | 
						|
      if ( *next_row == 255 && v_scrolled )
 | 
						|
        *next_row = 0;
 | 
						|
      else
 | 
						|
        ++* next_row;
 | 
						|
      break;
 | 
						|
    case XI_KEY_WLEFT:
 | 
						|
    case XI_KEY_LEFT:
 | 
						|
      --*next_col;
 | 
						|
      if ( *next_col < 0 )
 | 
						|
        *next_col = lmp->nbr_columns - 1;
 | 
						|
      break;
 | 
						|
    case XI_KEY_WRIGHT:
 | 
						|
    case XI_KEY_RIGHT:
 | 
						|
      ++*next_col;
 | 
						|
      if ( *next_col >= lmp->nbr_columns )
 | 
						|
        *next_col = 0;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   do_lm_cb
 | 
						|
lm:         current lm
 | 
						|
cb_reason:  one of LM_CB_CHAR, LM_CB_CHANGE, LM_CB_FOCUS, LM_CB_REC_ALLOCATE,
 | 
						|
        LM_CB_REC_FREE
 | 
						|
row:        relevent row
 | 
						|
column:     relevent column
 | 
						|
ep:         xvt event that caused the LM event, used to pass on shift and control
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
BOOLEAN
 | 
						|
do_lm_cb( LM lm, LM_CB_TYPE cb_reason, int row, int column, XinEvent * ep, int *percent, int pixels )
 | 
						|
{
 | 
						|
  LM_CB_DATA lm_cb_data;
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  lm_cb_data.lm = lm;
 | 
						|
  lm_cb_data.cb_type = cb_reason;
 | 
						|
  lm_cb_data.cid = lmp->cid;
 | 
						|
  lm_cb_data.win = lmp->win;
 | 
						|
  lm_cb_data.row = ( unsigned char ) row;
 | 
						|
  lm_cb_data.column = ( unsigned char ) column;
 | 
						|
  switch ( cb_reason )
 | 
						|
  {
 | 
						|
    case LM_CB_REC_ALLOCATE:
 | 
						|
      lm_cb_data.v.rec_allocate.record = lmp->recs[row];
 | 
						|
      if ( lm_cb_data.v.rec_allocate.record )
 | 
						|
        return FALSE;
 | 
						|
      break;
 | 
						|
    case LM_CB_REC_FREE:
 | 
						|
      lm_cb_data.v.rec_free.record = lmp->recs[row];
 | 
						|
      if ( lmp->have_last_rec && lm_cb_data.v.rec_free.record == lmp->last_rec )
 | 
						|
        lmp->have_last_rec = FALSE;
 | 
						|
      if ( !lm_cb_data.v.rec_allocate.record )
 | 
						|
        return FALSE;
 | 
						|
      break;
 | 
						|
    case LM_CB_CHAR:
 | 
						|
      lm_cb_data.v.chr.ch = ep->v.character.ch;
 | 
						|
      lm_cb_data.v.chr.shift = ep->v.character.shift;
 | 
						|
      lm_cb_data.v.chr.control = ep->v.character.control;
 | 
						|
      lm_cb_data.v.chr.alt = ep->v.character.alt;
 | 
						|
      lm_cb_data.v.chr.is_paste = FALSE;
 | 
						|
      lm_cb_data.v.chr.refused = FALSE;
 | 
						|
      break;
 | 
						|
    case LM_CB_CELL_BTN:
 | 
						|
      if ( ep->type == XinEventCharacter )
 | 
						|
      {
 | 
						|
        lm_cb_data.v.cell_btn.shift = ep->v.character.shift;
 | 
						|
        lm_cb_data.v.cell_btn.control = ep->v.character.control;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        lm_cb_data.v.cell_btn.shift = ep->v.mouse.shift;
 | 
						|
        lm_cb_data.v.cell_btn.control = ep->v.mouse.control;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case LM_CB_GET_PERCENT:
 | 
						|
      lm_cb_data.v.get_percent.record = lmp->recs[row];
 | 
						|
      break;
 | 
						|
    case LM_CB_ROW_SIZE:
 | 
						|
      lm_cb_data.v.row_size.new_row_height = pixels;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      lm_cb_data.v.refused = FALSE;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  ( *lmp->lm_cb ) ( &lm_cb_data );
 | 
						|
  /* retval = FALSE if event refused */
 | 
						|
  switch ( cb_reason )
 | 
						|
  {
 | 
						|
    case LM_CB_REC_ALLOCATE:
 | 
						|
      lmp->recs[row] = lm_cb_data.v.rec_allocate.record;
 | 
						|
      return FALSE;
 | 
						|
    case LM_CB_REC_FREE:
 | 
						|
      lmp->recs[row] = 0L;
 | 
						|
      return FALSE;
 | 
						|
    case LM_CB_CHAR:
 | 
						|
      if ( !lm_cb_data.v.chr.refused )
 | 
						|
        ep->v.character.ch = lm_cb_data.v.chr.ch;
 | 
						|
      return ( !lm_cb_data.v.chr.refused );
 | 
						|
    case LM_CB_GET_PERCENT:
 | 
						|
      *percent = lm_cb_data.v.get_percent.percent;
 | 
						|
      return FALSE;
 | 
						|
    case LM_CB_ROW_SIZE:
 | 
						|
      return ( !lm_cb_data.v.row_size.refused );
 | 
						|
    default:
 | 
						|
      return ( !lm_cb_data.v.refused );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   do_lm_cb_get
 | 
						|
lm:         current lm
 | 
						|
cb_reason:  one of LM_CB_GET_FIRST, LM_CB_GET_LAST, LM_CB_GET_NEXT,
 | 
						|
        LM_CB_GET_PREV
 | 
						|
spec_rec:
 | 
						|
data_rec:
 | 
						|
percent:
 | 
						|
returns:    TRUE if event refused
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
BOOLEAN
 | 
						|
do_lm_cb_get( LM lm, LM_CB_TYPE cb_reason, long *spec_rec,
 | 
						|
              long *data_rec, int percent, XinColor * color,
 | 
						|
              unsigned long *attrib, int *row_height )
 | 
						|
{
 | 
						|
  LM_CB_DATA lm_cb_data;
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  lm_cb_data.lm = lm;
 | 
						|
  lm_cb_data.cb_type = cb_reason;
 | 
						|
  lm_cb_data.cid = lmp->cid;
 | 
						|
  lm_cb_data.win = lmp->win;
 | 
						|
  lm_cb_data.v.rec_request.spec_rec = *spec_rec;
 | 
						|
  lm_cb_data.v.rec_request.data_rec = *data_rec;
 | 
						|
  lm_cb_data.v.rec_request.percent = percent;
 | 
						|
  lm_cb_data.v.rec_request.color = *color;
 | 
						|
  lm_cb_data.v.rec_request.attrib = *attrib;
 | 
						|
  lm_cb_data.v.rec_request.refused = FALSE;
 | 
						|
  ( *lmp->lm_cb ) ( &lm_cb_data );
 | 
						|
  if ( cb_reason == LM_CB_GET_NEXT && lm_cb_data.v.rec_request.refused )
 | 
						|
  {
 | 
						|
    lmp->have_last_rec = TRUE;
 | 
						|
    lmp->last_rec = lm_cb_data.v.rec_request.spec_rec;
 | 
						|
  }
 | 
						|
  if ( !lm_cb_data.v.rec_request.refused )
 | 
						|
  {
 | 
						|
    if ( cb_reason == LM_CB_GET_LAST )
 | 
						|
    {
 | 
						|
      lmp->have_last_rec = TRUE;
 | 
						|
      lmp->last_rec = lm_cb_data.v.rec_request.data_rec;
 | 
						|
    }
 | 
						|
    *data_rec = lm_cb_data.v.rec_request.data_rec;
 | 
						|
    *color = lm_cb_data.v.rec_request.color;
 | 
						|
    *attrib = lm_cb_data.v.rec_request.attrib;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
    *row_height = lm_cb_data.v.rec_request.row_height;
 | 
						|
#else
 | 
						|
    *row_height = 0;
 | 
						|
#endif
 | 
						|
    if ( lm_cb_data.v.rec_request.has_focus
 | 
						|
        && xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | 
						|
    {
 | 
						|
      if ( lm_focus_rec_get( lmp ) )
 | 
						|
      {
 | 
						|
        lm_cb_data.lm = ( LM ) lmp;
 | 
						|
        lm_cb_data.cb_type = LM_CB_REC_FREE;
 | 
						|
        lm_cb_data.cid = lmp->cid;
 | 
						|
        lm_cb_data.win = lmp->win;
 | 
						|
        lm_cb_data.v.rec_free.record = lm_focus_rec_get( lmp );
 | 
						|
        ( *lmp->lm_cb ) ( &lm_cb_data );
 | 
						|
      }
 | 
						|
      lm_focus_rec_set( lmp, *data_rec );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return lm_cb_data.v.rec_request.refused;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
calculate_next_cell( LM_DATA * lmp, int *next_row, int *next_col,
 | 
						|
                    BOOLEAN * use_key, int ch, BOOLEAN * off_top,
 | 
						|
                    BOOLEAN * off_bottom )
 | 
						|
{
 | 
						|
  BOOLEAN keep_looking;
 | 
						|
  int focus_row,
 | 
						|
  focus_column;
 | 
						|
  BOOLEAN v_scrolled;
 | 
						|
 | 
						|
  keep_looking = *use_key;
 | 
						|
  lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
  *next_row = focus_row;
 | 
						|
  *next_col = focus_column;
 | 
						|
  while ( keep_looking )
 | 
						|
  {
 | 
						|
    next_cell( ( LM ) lmp, ch, next_row, next_col, v_scrolled );
 | 
						|
    if ( *next_row < 0 )
 | 
						|
    {
 | 
						|
      /* off top logic */
 | 
						|
      if ( lmp->get_all_records )
 | 
						|
      {
 | 
						|
        *use_key = FALSE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        keep_looking = FALSE;
 | 
						|
        *off_top = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else if ( *next_row >= lmp->nbr_realized_rows )
 | 
						|
    {
 | 
						|
      /* off bottom logic */
 | 
						|
      if ( lmp->get_all_records )
 | 
						|
      {
 | 
						|
        *use_key = FALSE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        keep_looking = FALSE;
 | 
						|
        *off_bottom = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
      cell_data = &lmp->cell_data[*next_row][*next_col];
 | 
						|
 | 
						|
      if ( !cell_data->valid_data )
 | 
						|
        do_lm_cb_text( lmp, *next_row, *next_col, TRUE );
 | 
						|
      if ( CELL_IS_ENABLED( lmp, *next_row, *next_col )
 | 
						|
          && !CELL_IS_SELECTABLE( lmp, *next_row, *next_col )
 | 
						|
          && lmp->cell_data[*next_row][*next_col].icon_rid == 0
 | 
						|
          && lmp->cell_data[*next_row][*next_col].bitmap == NULL )
 | 
						|
 | 
						|
        /* found a valid cell */
 | 
						|
        keep_looking = FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
lm_adjust_rows( LM_DATA * lmp, int delta )
 | 
						|
{
 | 
						|
  XI_OBJ *focus_obj;
 | 
						|
 | 
						|
  focus_obj = lmp->itf_obj->v.itf->focus_obj;
 | 
						|
  if ( focus_obj && focus_obj->cid == lmp->cid )
 | 
						|
  {
 | 
						|
    if ( focus_obj && focus_obj->type == XIT_CELL )
 | 
						|
    {
 | 
						|
      if ( (int)focus_obj->v.cell.row + delta < 0 )
 | 
						|
      {
 | 
						|
        focus_obj->v.cell.is_vert_scrolled = TRUE;
 | 
						|
        focus_obj->v.cell.row += delta;
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      focus_obj->v.cell.row += delta;
 | 
						|
      if ( !focus_obj->v.cell.is_vert_scrolled
 | 
						|
        && ( long ) focus_obj->v.cell.row >= ( long ) lmp->nbr_realized_rows )
 | 
						|
        focus_obj->v.cell.is_vert_scrolled = TRUE;
 | 
						|
    }
 | 
						|
    if ( focus_obj && focus_obj->type == XIT_ROW )
 | 
						|
      focus_obj->v.row += delta;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   navigate_char_event
 | 
						|
lm:         current lm
 | 
						|
ep:         xvt event
 | 
						|
returns:    TRUE if key was used.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
BOOLEAN
 | 
						|
navigate_char_event( LM lm, XinEvent * ep )
 | 
						|
{
 | 
						|
  BOOLEAN use_key = FALSE;
 | 
						|
  BOOLEAN off_top = FALSE;
 | 
						|
  BOOLEAN off_bottom = FALSE;
 | 
						|
  BOOLEAN should_redraw = TRUE;
 | 
						|
  int next_row,
 | 
						|
  next_col,
 | 
						|
  row_inc,
 | 
						|
  col_inc;
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  short c = ep->v.character.ch;
 | 
						|
 | 
						|
  if ( !lm_focus_list_has( lmp ) )
 | 
						|
    return FALSE;
 | 
						|
  if ( ( c == '\r' || c == '\n' ) && lmp->itf_obj->v.itf->tab_on_enter)
 | 
						|
  {
 | 
						|
    int row, col;
 | 
						|
    BOOLEAN is_vert_scrolled;
 | 
						|
 | 
						|
    lm_focus_cell_get( lmp, &row, &col, &is_vert_scrolled );
 | 
						|
    if (!lmp->lm_column_data[col]->cr_ok)
 | 
						|
    {
 | 
						|
      c = (short)xi_get_pref( XI_PREF_FORM_TAB_CHAR );
 | 
						|
      ep->v.character.ch = c;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  switch ( c )
 | 
						|
  {
 | 
						|
    case '\t':
 | 
						|
    case XI_KEY_BTAB:
 | 
						|
    case XI_KEY_UP:
 | 
						|
    case XI_KEY_DOWN:
 | 
						|
    case XI_KEY_PREV:
 | 
						|
    case XI_KEY_NEXT:
 | 
						|
      use_key = TRUE;
 | 
						|
      break;
 | 
						|
    case XI_KEY_WRIGHT:
 | 
						|
    case XI_KEY_WLEFT:
 | 
						|
    case XI_KEY_LEFT:
 | 
						|
    case XI_KEY_RIGHT:
 | 
						|
      if ( ( lmp->attrib & LM_ATR_NAVIGATE ) || ep->v.character.control )
 | 
						|
        use_key = TRUE;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  switch ( c )
 | 
						|
  {
 | 
						|
    case XI_KEY_UP:
 | 
						|
    case XI_KEY_DOWN:
 | 
						|
    case XI_KEY_PREV:
 | 
						|
    case XI_KEY_NEXT:
 | 
						|
    {
 | 
						|
      if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | 
						|
      {
 | 
						|
        XI_TEXT *text = xi_text_focus_get( lmp->win );
 | 
						|
 | 
						|
        if ( text != 0 && text->multi_line && !ep->v.character.control
 | 
						|
            && !( lmp->attrib & LM_ATR_NAVIGATE ) )
 | 
						|
          return FALSE;
 | 
						|
      }
 | 
						|
      switch ( c )
 | 
						|
      {
 | 
						|
        case XI_KEY_PREV:
 | 
						|
          xi_control_event_scroll( lmp->list_obj, XI_SCROLL_PGUP, 0, TRUE );
 | 
						|
          return TRUE;
 | 
						|
        case XI_KEY_NEXT:
 | 
						|
          xi_control_event_scroll( lmp->list_obj, XI_SCROLL_PGDOWN, 0, TRUE );
 | 
						|
          return TRUE;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    case XI_KEY_WRIGHT:
 | 
						|
    case XI_KEY_WLEFT:
 | 
						|
    case XI_KEY_LEFT:
 | 
						|
    case XI_KEY_RIGHT:
 | 
						|
      if ( !use_key )
 | 
						|
        return FALSE;
 | 
						|
  }
 | 
						|
  calculate_next_cell( lmp, &next_row, &next_col,
 | 
						|
                      &use_key, c, &off_top, &off_bottom );
 | 
						|
  if ( use_key )
 | 
						|
  {
 | 
						|
    XI_LIST_DATA *list_data;
 | 
						|
 | 
						|
    list_data = lmp->list_obj->v.list;
 | 
						|
    if ( off_top || off_bottom )
 | 
						|
    {
 | 
						|
      int old_row_height,
 | 
						|
      focus_row,
 | 
						|
      focus_column;
 | 
						|
      BOOLEAN v_scrolled;
 | 
						|
      BOOLEAN do_redraw;
 | 
						|
 | 
						|
      lm_focus_cell_invis_make( lmp );
 | 
						|
      lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
      old_row_height = lmp->pix_heights[focus_row];
 | 
						|
      do_redraw = ( lm_calculate_row_height( lmp, focus_row ) != old_row_height );
 | 
						|
      if ( off_top )
 | 
						|
        make_room_rows( lmp, -1, do_redraw );
 | 
						|
      else
 | 
						|
        make_room_rows( lmp, 1, do_redraw );
 | 
						|
      /* calculate next cell again, because the desired next cell may have
 | 
						|
      * changed. */
 | 
						|
      calculate_next_cell( lmp, &next_row, &next_col, &use_key, c,
 | 
						|
                          &off_top, &off_bottom );
 | 
						|
      lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
      row_inc = next_row - focus_row;
 | 
						|
      col_inc = next_col - focus_column;
 | 
						|
      next_row = focus_row + row_inc;
 | 
						|
      if ( next_row >= lmp->nbr_realized_rows )
 | 
						|
        next_row = lmp->nbr_realized_rows - 1;
 | 
						|
      if ( next_row < 0 )
 | 
						|
        next_row = 0;
 | 
						|
      next_col = focus_column + col_inc;
 | 
						|
 | 
						|
      while ( TRUE )
 | 
						|
      {
 | 
						|
        LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
        cell_data = &lmp->cell_data[next_row][next_col];
 | 
						|
 | 
						|
        if ( !cell_data->valid_data )
 | 
						|
          do_lm_cb_text( lmp, next_row, next_col, TRUE );
 | 
						|
        if ( CELL_IS_ENABLED( lmp, next_row, next_col )
 | 
						|
            && !CELL_IS_SELECTABLE( lmp, next_row, next_col )
 | 
						|
            && lmp->cell_data[next_row][next_col].icon_rid == 0
 | 
						|
            && lmp->cell_data[next_row][next_col].bitmap == NULL )
 | 
						|
          break;
 | 
						|
        next_cell( lm, off_bottom ? '\t' :
 | 
						|
                  XI_KEY_BTAB, &next_row, &next_col, v_scrolled );
 | 
						|
      }
 | 
						|
      if ( list_data->vert_sync_list &&
 | 
						|
          !list_data->scrolling_in_progress )
 | 
						|
      {
 | 
						|
        XI_OBJ *other_list;
 | 
						|
 | 
						|
        list_data->scrolling_in_progress = TRUE;
 | 
						|
        other_list = xi_get_obj( lmp->itf_obj,
 | 
						|
                                list_data->vert_sync_list );
 | 
						|
        if ( other_list )
 | 
						|
          xi_scroll( other_list, off_top ? -1 : 1 );
 | 
						|
        XinWindowPaintForce( lmp->win );
 | 
						|
        list_data->scrolling_in_progress = FALSE;
 | 
						|
      }
 | 
						|
      XinWindowPaintForce( lmp->win );
 | 
						|
      lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
      if ( focus_row > lmp->last_fully_vis )
 | 
						|
      {
 | 
						|
        LM_FOCUS_CELL_VISIBLE_FORCE_ARGS args;
 | 
						|
 | 
						|
        MEMCLEAR( args );
 | 
						|
        args.lmp = lmp;
 | 
						|
        args.row = focus_row;
 | 
						|
        args.column = focus_column;
 | 
						|
        args.vert_scrolled = v_scrolled;
 | 
						|
        lm_focus_cell_visible_force( &args );
 | 
						|
        lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
        next_row = focus_row;
 | 
						|
        calculate_pix_offsets( lmp, FALSE );
 | 
						|
      }
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
    }
 | 
						|
 | 
						|
    else if ( next_row < lmp->first_fully_vis || next_row > lmp->last_fully_vis )
 | 
						|
    {
 | 
						|
      if ( list_data->vert_sync_list &&
 | 
						|
          !list_data->scrolling_in_progress )
 | 
						|
      {
 | 
						|
        XI_OBJ *other_list;
 | 
						|
 | 
						|
        list_data->scrolling_in_progress = TRUE;
 | 
						|
        other_list = xi_get_obj( lmp->itf_obj,
 | 
						|
                                list_data->vert_sync_list );
 | 
						|
        if ( other_list )
 | 
						|
          xi_scroll( other_list,
 | 
						|
                    next_row < lmp->first_fully_vis ? -1 : 1 );
 | 
						|
        XinWindowPaintForce( lmp->win );
 | 
						|
        list_data->scrolling_in_progress = FALSE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ( next_row < lmp->first_fully_vis )
 | 
						|
    {
 | 
						|
      int delta,
 | 
						|
      idx2,
 | 
						|
      pix2,
 | 
						|
      old_pix,
 | 
						|
      cnt,
 | 
						|
      height;
 | 
						|
      XinRect tmp_rct;
 | 
						|
 | 
						|
      if ( lmp->first_fully_vis == 0 )
 | 
						|
        return use_key;
 | 
						|
      lm_focus_cell_invis_make( lmp );
 | 
						|
      idx2 = lmp->first_fully_vis - 1;
 | 
						|
      pix2 = lmp->pix_offsets[idx2];
 | 
						|
      old_pix = -lmp->rrr_offset;
 | 
						|
      delta = old_pix - pix2;
 | 
						|
      lmp->rrr_offset += delta;
 | 
						|
      calculate_pix_offsets( lmp, FALSE );
 | 
						|
      if ( !lmp->itf_obj->v.itf->half_baked )
 | 
						|
        XinWindowPaintForce( lmp->win );
 | 
						|
      xi_set_update_obj( lmp->list_obj );
 | 
						|
      lm_get_scroll_rct( lmp, &tmp_rct );
 | 
						|
 | 
						|
      /* calculate lmp->update_rows_at_top to speed up scrolling the list */
 | 
						|
      height = delta;
 | 
						|
      for ( cnt = 0; cnt < lmp->nbr_realized_rows && height > 0; ++cnt )
 | 
						|
        height -= lmp->pix_heights[cnt];
 | 
						|
      lmp->update_rows_at_top = cnt;
 | 
						|
 | 
						|
      xi_scroll_rect( lmp->win, &tmp_rct, 0, delta );
 | 
						|
      do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
      should_redraw = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if ( next_row > lmp->last_fully_vis )
 | 
						|
    {
 | 
						|
      int delta,
 | 
						|
      delta2,
 | 
						|
      diff,
 | 
						|
      cnt,
 | 
						|
      height,
 | 
						|
      first,
 | 
						|
      old_row_height,
 | 
						|
      focus_row;
 | 
						|
      int idx,
 | 
						|
      missing;
 | 
						|
      int focus_column,
 | 
						|
      new_row_height;
 | 
						|
      BOOLEAN v_scrolled;
 | 
						|
      XinRect tmp_rct;
 | 
						|
 | 
						|
      if ( lmp->last_fully_vis >= lmp->nbr_realized_rows )
 | 
						|
        return use_key;
 | 
						|
      lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
      old_row_height = lmp->pix_heights[focus_row];
 | 
						|
      lm_focus_cell_invis_make( lmp );
 | 
						|
      delta = lmp->pix_heights[lmp->first_fully_vis];
 | 
						|
      lm_make_rrr_room_pix( lmp, delta, TRUE );
 | 
						|
      idx = lmp->last_fully_vis + 1;
 | 
						|
      missing = lmp->mlr_height - ( lmp->pix_offsets[idx] + lmp->pix_heights[idx] );
 | 
						|
      if ( lmp->last_fully_vis + 1 < lmp->nbr_realized_rows )
 | 
						|
        delta = max( delta, missing );
 | 
						|
      lmp->rrr_offset -= delta;
 | 
						|
      calculate_pix_offsets( lmp, TRUE );
 | 
						|
      calculate_visibles( lmp );
 | 
						|
      if ( -lmp->rrr_offset != lmp->pix_offsets[lmp->first_fully_vis] )
 | 
						|
      {
 | 
						|
        delta2 = lmp->pix_offsets[lmp->first_fully_vis] +
 | 
						|
                lmp->rrr_offset;
 | 
						|
        lmp->rrr_offset -= delta2;
 | 
						|
        calculate_pix_offsets( lmp, FALSE );
 | 
						|
        calculate_visibles( lmp );
 | 
						|
        delta += delta2;
 | 
						|
      }
 | 
						|
      diff = lmp->pix_offsets[lmp->nbr_realized_rows - 1] +
 | 
						|
              lmp->pix_heights[lmp->nbr_realized_rows - 1] -
 | 
						|
              lmp->mlr_height + lmp->rrr_offset;
 | 
						|
      if ( !lmp->itf_obj->v.itf->half_baked )
 | 
						|
        XinWindowPaintForce( lmp->win );
 | 
						|
      if ( diff < 0 )
 | 
						|
        lm_make_rrr_room_pix( lmp, -diff, FALSE );
 | 
						|
      xi_set_update_obj( lmp->list_obj );
 | 
						|
      lm_get_scroll_rct( lmp, &tmp_rct );
 | 
						|
 | 
						|
      /* calculate lmp->update_rows_at_bottom to speed up scrolling the list */
 | 
						|
      height = lmp->mlr.bottom - lmp->mlr.top - delta;
 | 
						|
      for ( cnt = 0; cnt < lmp->nbr_realized_rows && height > 0; ++cnt )
 | 
						|
        height -= lmp->pix_heights[cnt];
 | 
						|
      first = cnt - 1;
 | 
						|
      height += delta;
 | 
						|
      for ( ; height > 0; ++cnt )
 | 
						|
        height -= lmp->pix_heights[cnt];
 | 
						|
      lmp->update_rows_at_bottom = cnt - first;
 | 
						|
 | 
						|
      /* scroll the list */
 | 
						|
      xi_scroll_rect( lmp->win, &tmp_rct, 0, -delta );
 | 
						|
      do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
 | 
						|
      /* if the row height changed, then we need to redraw the row */
 | 
						|
      lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
      new_row_height = lmp->pix_heights[focus_row];
 | 
						|
      if ( new_row_height != old_row_height )
 | 
						|
      {
 | 
						|
        lm_redraw_row( lmp, focus_row, FALSE );
 | 
						|
        calculate_pix_offsets( lmp, TRUE );
 | 
						|
      }
 | 
						|
      should_redraw = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if ( !lmp->get_all_records )
 | 
						|
    {
 | 
						|
      int nbr_to_free,
 | 
						|
      cnt,
 | 
						|
      i,
 | 
						|
      idx;
 | 
						|
 | 
						|
      nbr_to_free = lmp->first_fully_vis;
 | 
						|
      if ( nbr_to_free > 0 )
 | 
						|
      {
 | 
						|
        int rheight;
 | 
						|
 | 
						|
        rheight = 0;
 | 
						|
        for ( cnt = 0; cnt < nbr_to_free; cnt++ )
 | 
						|
        {
 | 
						|
          lmp->rrr_offset += lmp->pix_heights[cnt];
 | 
						|
          rheight += lmp->pix_heights[cnt];
 | 
						|
          lm_do_rec_event( lmp, cnt, XIE_REC_FREE );
 | 
						|
        }
 | 
						|
 | 
						|
        for ( idx = nbr_to_free; idx < lmp->nbr_realized_rows; ++idx )
 | 
						|
          lm_row_copy( lmp, idx, idx - nbr_to_free );
 | 
						|
        lm_adjust_rows( lmp, -nbr_to_free );
 | 
						|
 | 
						|
        /* calculate next cell again, because the desired next cell may have
 | 
						|
        * changed. */
 | 
						|
        calculate_next_cell( lmp, &next_row, &next_col,
 | 
						|
                            &use_key, c, &off_top, &off_bottom );
 | 
						|
        lmp->nbr_realized_rows -= cnt;
 | 
						|
        calculate_pix_offsets( lmp, should_redraw );
 | 
						|
        calculate_visibles( lmp );
 | 
						|
        lm_make_rrr_room_pix( lmp, rheight, TRUE );
 | 
						|
        calculate_pix_offsets( lmp, should_redraw );
 | 
						|
        calculate_visibles( lmp );
 | 
						|
      }
 | 
						|
 | 
						|
      /* free any unnecessary records at the end of the list */
 | 
						|
      nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
      if ( nbr_to_free > 0 )
 | 
						|
      {
 | 
						|
        for ( i = lmp->nbr_realized_rows - nbr_to_free, cnt = 0; cnt < nbr_to_free;
 | 
						|
              i++, cnt++ )
 | 
						|
          lm_do_rec_event( lmp, i, XIE_REC_FREE );
 | 
						|
        lmp->nbr_realized_rows -= cnt;
 | 
						|
      }
 | 
						|
 | 
						|
      calculate_pix_offsets( lmp, should_redraw );
 | 
						|
 | 
						|
      lm_make_rrr_room_pix( lmp, 0, FALSE );
 | 
						|
    }
 | 
						|
    do_lm_cb( lm, LM_CB_FOCUS, next_row, next_col, NULL, NULL, 0 );
 | 
						|
    lm_focus_cell_visible_attempt( lmp );
 | 
						|
  }
 | 
						|
  return use_key;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_insert_row
 | 
						|
lm:         current lm
 | 
						|
row:        row to insert
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
BOOLEAN
 | 
						|
lm_insert_row( LM lm, int row )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  if ( lmp->get_all_records )
 | 
						|
    XinError( 20919, XinSeverityFatal, 0L );
 | 
						|
  if ( xi_move_focus( lmp->itf_obj ) )
 | 
						|
  {
 | 
						|
    if ( row > 0 && lmp->nbr_realized_rows )
 | 
						|
    {
 | 
						|
      int idx = 0,
 | 
						|
      row_height,
 | 
						|
      pix;
 | 
						|
      XinRect r,
 | 
						|
      row_rect;
 | 
						|
      BOOLEAN is_visible;
 | 
						|
 | 
						|
      row = min( row, lmp->nbr_realized_rows );
 | 
						|
 | 
						|
      pix = lmp->pix_offsets[row - 1] + lmp->pix_heights[row - 1]
 | 
						|
              + 1;
 | 
						|
      is_visible = ( pix <= lmp->mlr_height - lmp->rrr_offset );
 | 
						|
 | 
						|
      if ( is_visible || lmp->get_all_records )
 | 
						|
      {
 | 
						|
        LM_CELL_DATA *cell_data;
 | 
						|
        int i;
 | 
						|
 | 
						|
        make_rec_available( lmp, REC_AT_BOTTOM, FALSE, FALSE );
 | 
						|
        for ( i = lmp->nbr_realized_rows - 2; i >= row; i-- )
 | 
						|
          lm_row_copy( lmp, i, i + 1 );
 | 
						|
        idx = row;
 | 
						|
        /* cell_data_construct */
 | 
						|
        cell_data = lmp->cell_data[idx];
 | 
						|
        for ( i = 0; i < lmp->nbr_columns; ++i, ++cell_data )
 | 
						|
        {
 | 
						|
          memset( ( char * ) cell_data, '\0', sizeof( LM_CELL_DATA ) );
 | 
						|
          lm_xi_text_construct( lmp, idx, i );
 | 
						|
        }
 | 
						|
        lmp->recs[idx] = 0L;
 | 
						|
        lm_do_rec_event( lmp, idx, XIE_REC_ALLOCATE );
 | 
						|
        if ( do_lm_cb_get( ( LM ) lmp, LM_CB_GET_NEXT,
 | 
						|
              &lmp->recs[idx - 1], &lmp->recs[idx], 0, &lmp->row_colors[idx],
 | 
						|
                          &lmp->row_attribs[idx], &row_height ) )
 | 
						|
        {
 | 
						|
          lm_do_rec_event( lmp, lmp->nbr_realized_rows - 1, XIE_REC_FREE );
 | 
						|
          for ( i = row; i < lmp->nbr_realized_rows - 2; ++i )
 | 
						|
            lm_row_copy( lmp, i + 1, i );
 | 
						|
          --lmp->nbr_realized_rows;
 | 
						|
          return FALSE;
 | 
						|
        }
 | 
						|
        if ( row_height )
 | 
						|
        {
 | 
						|
          lmp->pix_heights[idx] = row_height;
 | 
						|
          lmp->set_heights[idx] = TRUE;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          lmp->pix_heights[idx] = lm_calculate_row_height( lmp, idx );
 | 
						|
          lmp->set_heights[idx] = FALSE;
 | 
						|
        }
 | 
						|
 | 
						|
        lm_invalidate_rows_internal( ( LM ) lmp, idx, idx, FALSE, -1, TRUE );
 | 
						|
      }
 | 
						|
 | 
						|
      if ( is_visible )
 | 
						|
      {
 | 
						|
        lm_get_scroll_rct( lmp, &r );
 | 
						|
        row_height = lm_calculate_row_height( lmp, idx );
 | 
						|
        calculate_pix_offsets( lmp, FALSE );
 | 
						|
        lm_get_rect( lm, LM_ROW, idx, &row_rect );
 | 
						|
        r.top = row_rect.top;
 | 
						|
        xi_scroll_rect( lmp->win, &r, 0, row_height );
 | 
						|
      }
 | 
						|
      do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      int idx,
 | 
						|
      row_height,
 | 
						|
      cnt;
 | 
						|
      XinRect r;
 | 
						|
      BOOLEAN need_first = !lmp->nbr_realized_rows;
 | 
						|
 | 
						|
      make_rec_available( lmp, REC_AT_TOP, TRUE, FALSE );
 | 
						|
      idx = 0;
 | 
						|
      if ( do_lm_cb_get( ( LM ) lmp, need_first ? LM_CB_GET_FIRST : LM_CB_GET_PREV,
 | 
						|
              &lmp->recs[idx + 1], &lmp->recs[idx], 0, &lmp->row_colors[idx],
 | 
						|
                        &lmp->row_attribs[idx], &row_height ) )
 | 
						|
      {
 | 
						|
        lm_do_rec_event( lmp, 0, XIE_REC_FREE );
 | 
						|
        for ( cnt = 1; cnt < lmp->nbr_realized_rows; ++cnt )
 | 
						|
          lm_row_copy( lmp, cnt, cnt - 1 );
 | 
						|
        --lmp->nbr_realized_rows;
 | 
						|
        return FALSE;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( row_height )
 | 
						|
      {
 | 
						|
        lmp->pix_heights[idx] = row_height;
 | 
						|
        lmp->set_heights[idx] = TRUE;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        lmp->pix_heights[idx] = lm_calculate_row_height( lmp, idx );
 | 
						|
        lmp->set_heights[idx] = FALSE;
 | 
						|
      }
 | 
						|
      lm_invalidate_rows_internal( ( LM ) lmp, idx, idx, FALSE, -1, TRUE );
 | 
						|
      lm_get_scroll_rct( lmp, &r );
 | 
						|
      row_height = lm_calculate_row_height( lmp, idx );
 | 
						|
      calculate_pix_offsets( lmp, FALSE );
 | 
						|
      xi_scroll_rect( lmp->win, &r, 0, row_height );
 | 
						|
      do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_delete_row
 | 
						|
lm:         current lm
 | 
						|
row:        row to delete
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
BOOLEAN
 | 
						|
lm_delete_row( LM lm, int row )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  if ( lmp->get_all_records )
 | 
						|
    XinError( 20920, XinSeverityFatal, 0L );
 | 
						|
  if ( xi_move_focus( lmp->itf_obj ) )
 | 
						|
  {
 | 
						|
    int pix_height,
 | 
						|
    i;
 | 
						|
    int recs_read;
 | 
						|
    XinRect r,
 | 
						|
    row_rct;
 | 
						|
 | 
						|
    pix_height = lmp->pix_heights[row];
 | 
						|
    lm_get_rect( lm, LM_ROW, row, &row_rct );
 | 
						|
    lm_do_rec_event( lmp, row, XIE_REC_FREE );
 | 
						|
    for ( i = row + 1; i < lmp->nbr_realized_rows; i++ )
 | 
						|
      lm_row_copy( lmp, i, i - 1 );
 | 
						|
    lmp->recs[--lmp->nbr_realized_rows] = 0;
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
    recs_read = lm_make_rrr_room_pix( lmp, pix_height, FALSE );
 | 
						|
    pix_height = max( pix_height, 0 );
 | 
						|
    lm_get_scroll_rct( lmp, &r );
 | 
						|
    r.top = max( r.top, row_rct.top );
 | 
						|
    if ( recs_read )
 | 
						|
      xi_invalidate_rect( lmp->win, &r );
 | 
						|
    else
 | 
						|
      xi_scroll_rect( lmp->win, &r, 0, -pix_height );
 | 
						|
    XinWindowPaintForce( lmp->win );
 | 
						|
    do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_row_height
 | 
						|
lm:         current lm
 | 
						|
row:        row to set
 | 
						|
height:     height
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_row_height( LM lm, int row, int height, BOOLEAN set_height,
 | 
						|
                  int old_height, BOOLEAN only_update )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
  int idx = row;
 | 
						|
  int old_row_height,
 | 
						|
  delta;
 | 
						|
  XinRect r,
 | 
						|
  r2;
 | 
						|
 | 
						|
  if ( !lmp->itf_obj->v.itf->half_baked )
 | 
						|
    XinWindowPaintForce( lmp->win );
 | 
						|
  if ( only_update )
 | 
						|
    old_row_height = old_height;
 | 
						|
  else
 | 
						|
  {
 | 
						|
    old_row_height = lmp->pix_heights[idx];
 | 
						|
    lmp->pix_heights[idx] = height;
 | 
						|
    lmp->set_heights[idx] = set_height;
 | 
						|
  }
 | 
						|
  calculate_pix_offsets( lmp, FALSE );
 | 
						|
 | 
						|
  /* Adjust row information */
 | 
						|
  if ( !lmp->get_all_records )
 | 
						|
  {
 | 
						|
    if ( height < old_row_height )
 | 
						|
      lm_make_rrr_room_pix( lmp, 0, FALSE );
 | 
						|
    else
 | 
						|
    {                           /* Free rows at bottom */
 | 
						|
      int i,
 | 
						|
      cnt;
 | 
						|
      int nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
 | 
						|
      for ( i = lmp->nbr_realized_rows - nbr_to_free,
 | 
						|
            cnt = 0; cnt < nbr_to_free; i++, cnt++ )
 | 
						|
        lm_do_rec_event( lmp, i, XIE_REC_FREE );
 | 
						|
      if ( nbr_to_free > 0 )
 | 
						|
        lmp->nbr_realized_rows -= nbr_to_free;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  lm_get_scroll_rct( lmp, &r );
 | 
						|
  if ( row < lmp->nbr_realized_rows - 1 )
 | 
						|
  {
 | 
						|
    r.top = lmp->pix_offsets[idx + 1] + lmp->rrr_offset + lmp->mlr.top;
 | 
						|
    delta = height - old_row_height;
 | 
						|
    if ( r.top < r.bottom )
 | 
						|
      xi_scroll_rect( lmp->win, &r, 0, delta );
 | 
						|
  }
 | 
						|
  lm_get_rect( lm, LM_ROW, row, &r );
 | 
						|
  if ( row == lmp->nbr_realized_rows - 1 )
 | 
						|
  {
 | 
						|
    r2 = r;
 | 
						|
    r2.top = r2.bottom;
 | 
						|
    r2.bottom = lmp->mlr.bottom;
 | 
						|
    if ( r2.top < r2.bottom )
 | 
						|
      xi_invalidate_rect( lmp->win, &r2 );
 | 
						|
  }
 | 
						|
  xi_invalidate_rect( lmp->win, &r );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_list_size
 | 
						|
lm:         current lm
 | 
						|
height:     new height
 | 
						|
width:      new width
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_list_size( LM lm, int height, int width )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
  XinRect vert_scrollbar_rect;
 | 
						|
  XinRect horz_scrollbar_rect;
 | 
						|
  XinRect ir,
 | 
						|
  old_rct;
 | 
						|
  int old_height;
 | 
						|
  int col_offset;
 | 
						|
  int max_row_height;
 | 
						|
  int row_height;
 | 
						|
  int heading_height;
 | 
						|
  int i;
 | 
						|
  int row,
 | 
						|
  col;
 | 
						|
  XI_LIST_DATA *list_data;
 | 
						|
  int nbr_to_free,
 | 
						|
  cnt;
 | 
						|
 | 
						|
  list_data = lmp->list_obj->v.list;
 | 
						|
  xi_get_rect( lmp->list_obj, &old_rct );
 | 
						|
  col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | 
						|
  xi_get_hsb_rect( lmp->list_obj, &horz_scrollbar_rect );
 | 
						|
  xi_get_sb_rect( lmp->list_obj, &vert_scrollbar_rect );
 | 
						|
 | 
						|
  /* calculate minumum height */
 | 
						|
  if ( !list_data->one_row_list )
 | 
						|
  {
 | 
						|
    {
 | 
						|
      int leading;
 | 
						|
      int ascent;
 | 
						|
      int descent;
 | 
						|
      int char_width;
 | 
						|
      int font_height;
 | 
						|
 | 
						|
      xi_get_font_metrics_font( lmp->font, &leading, &ascent, &descent,
 | 
						|
                                &char_width );
 | 
						|
      font_height = leading + ascent + descent;
 | 
						|
      max_row_height = lmp->max_lines_in_cell * font_height + RULE_Y_OFFSET_TOP
 | 
						|
              + RULE_Y_OFFSET_BOTTOM + RULE_WIDTH_H;
 | 
						|
    }
 | 
						|
    for ( i = 0; i < lmp->nbr_realized_rows; ++i )
 | 
						|
    {
 | 
						|
      row_height = lmp->pix_heights[i];
 | 
						|
      max_row_height = max( row_height, max_row_height );
 | 
						|
    }
 | 
						|
    heading_height = ( lmp->pix_row1_top - lmp->rct.top ) + BORDER_WIDTH;
 | 
						|
    i = max_row_height + heading_height + ( horz_scrollbar_rect.bottom
 | 
						|
                                            - horz_scrollbar_rect.top );
 | 
						|
    height = max( height, i );
 | 
						|
 | 
						|
    /* calculate new list metrics */
 | 
						|
    lmp->pixel_height = height;
 | 
						|
    lmp->rct.bottom = lmp->rct.top + height
 | 
						|
            - ( ( list_data->hsb_win ) ? ( horz_scrollbar_rect.bottom
 | 
						|
                                          - horz_scrollbar_rect.top - 1 )
 | 
						|
                : 0 );
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
    lmp->mlr.bottom = lmp->rct.bottom;
 | 
						|
#else
 | 
						|
    lmp->mlr.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
#endif
 | 
						|
    old_height = lmp->mlr_height;
 | 
						|
    lmp->mlr_height = lmp->mlr.bottom - lmp->mlr.top;
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
    if ( !lmp->get_all_records )
 | 
						|
    {
 | 
						|
      /* fill in with more records */
 | 
						|
      if ( old_height < lmp->mlr_height )
 | 
						|
        lm_make_rrr_room_pix( lmp, lmp->mlr_height - old_height, FALSE );
 | 
						|
    }
 | 
						|
 | 
						|
    calculate_visibles( lmp );
 | 
						|
  }
 | 
						|
 | 
						|
  if ( width && lmp->pixel_width )
 | 
						|
  {
 | 
						|
    int i,
 | 
						|
    min_width,
 | 
						|
    max_col_width;
 | 
						|
 | 
						|
    max_col_width = 0;
 | 
						|
    for ( i = lmp->fixed_columns; i < lmp->nbr_columns; ++i )
 | 
						|
      max_col_width = max( lmp->lm_column_data[i]->pix_width, max_col_width );
 | 
						|
    max_col_width += BORDER_WIDTH;
 | 
						|
    min_width = ( lmp->vir_left - lmp->rct.left ) + max_col_width
 | 
						|
            + ( vert_scrollbar_rect.right - vert_scrollbar_rect.left )
 | 
						|
            + BORDER_WIDTH + 2 * col_offset;
 | 
						|
    if ( list_data->sb_win )
 | 
						|
      min_width += ( vert_scrollbar_rect.right
 | 
						|
                    - vert_scrollbar_rect.left );
 | 
						|
    width = max( min_width, width );
 | 
						|
 | 
						|
    lmp->pixel_width = width - ( 2 * BORDER_WIDTH );
 | 
						|
    if ( list_data->sb_win )
 | 
						|
      lmp->pixel_width -= ( vert_scrollbar_rect.right
 | 
						|
                            - vert_scrollbar_rect.left - 1 );
 | 
						|
    lmp->vir_right = lmp->rct.left + lmp->pixel_width + BORDER_WIDTH;
 | 
						|
  }
 | 
						|
 | 
						|
  /* move scroll bars */
 | 
						|
  list_data->have_sb_rct = FALSE;
 | 
						|
  list_data->have_hsb_rct = FALSE;
 | 
						|
  xi_move_list_scroll_bar( lmp->list_obj );
 | 
						|
  xi_move_list_hscroll_bar( lmp->list_obj );
 | 
						|
  lm_set_hscroll_range( lm );
 | 
						|
  lm_set_hscroll_bar( lm );
 | 
						|
 | 
						|
  ir = lmp->rct;
 | 
						|
  xi_get_hsb_rect( lmp->list_obj, &horz_scrollbar_rect );
 | 
						|
  ir.bottom = horz_scrollbar_rect.bottom + BORDER_WIDTH;
 | 
						|
  xi_get_sb_rect( lmp->list_obj, &vert_scrollbar_rect );
 | 
						|
  ir.right = vert_scrollbar_rect.right + BORDER_WIDTH;
 | 
						|
  ir.right = max( ir.right, old_rct.right );
 | 
						|
  ir.bottom = max( ir.bottom, old_rct.bottom );
 | 
						|
  xi_invalidate_rect( lmp->win, &ir );
 | 
						|
 | 
						|
  do_scroll_bar( lmp->list_obj->v.list );
 | 
						|
 | 
						|
  if ( width && lmp->pixel_width )
 | 
						|
  {
 | 
						|
    /* calculate visible columns */
 | 
						|
    i = lm_get_left_most_far_right_col( lmp, lmp->nbr_columns );
 | 
						|
    if ( i < lmp->first_vis )
 | 
						|
    {
 | 
						|
      XinWindowPaintForce( lmp->win );
 | 
						|
      lm_hscroll( lm, lmp->first_vis - i, 0 );
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      lm_calc_last_vis( lmp );
 | 
						|
      lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if ( !lmp->get_all_records )
 | 
						|
  {
 | 
						|
    /* free any unnecessary records at the end of the list */
 | 
						|
    nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
    for ( i = lmp->nbr_realized_rows - nbr_to_free, cnt = 0; cnt < nbr_to_free;
 | 
						|
          i++, cnt++ )
 | 
						|
      lm_do_rec_event( lmp, i, XIE_REC_FREE );
 | 
						|
    lmp->nbr_realized_rows -= cnt;
 | 
						|
    calculate_visibles( lmp );
 | 
						|
  }
 | 
						|
 | 
						|
  for ( col = 0; col < lmp->nbr_columns; ++col )
 | 
						|
  {
 | 
						|
    for ( row = 0; row < lmp->nbr_realized_rows; ++row )
 | 
						|
    {
 | 
						|
      LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
      cell_data = &lmp->cell_data[row][col];
 | 
						|
      if ( cell_data->xi_text )
 | 
						|
      {
 | 
						|
        XinRect r;
 | 
						|
 | 
						|
        r = lmp->mlr;
 | 
						|
        if ( lmp->pixel_width )
 | 
						|
          r.right = r.left + lmp->pixel_width;
 | 
						|
        xi_text_clip_set( cell_data->xi_text, &r );
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
calc_lmp_rct_right( LM_DATA * lmp )
 | 
						|
{
 | 
						|
  /* TODO for XINCH mode, need to duplicate algorythm in lm_create */
 | 
						|
  /* single-column lists do not have a vertical rule seperating columns */
 | 
						|
  if ( lmp->nbr_columns == 0 )
 | 
						|
    lmp->rct.right = lmp->rct.left + 2 * BORDER_WIDTH;
 | 
						|
  else
 | 
						|
  {
 | 
						|
    LM_COLUMN_DATA *cell_data = lmp->lm_column_data[lmp->nbr_columns - 1];
 | 
						|
 | 
						|
    lmp->rct.right = lmp->rct.left + cell_data->x_pix_pos + cell_data->pix_width + 2 * BORDER_WIDTH +
 | 
						|
            ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | 
						|
  }
 | 
						|
  lmp->mlr.right = lmp->rct.right - BORDER_WIDTH;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
lm_recalc_metrics( LM lm )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
  int leading,
 | 
						|
  ascent,
 | 
						|
  descent,
 | 
						|
  font_height,
 | 
						|
  mch,
 | 
						|
  i;
 | 
						|
  XinWindow win;
 | 
						|
  LM_COLUMN_DATA **cell_data;
 | 
						|
  int old_char_width;
 | 
						|
  XI_LIST_DATA *list_data;
 | 
						|
  XinPoint pnt;
 | 
						|
  XinRect rct;
 | 
						|
 | 
						|
  list_data = lmp->list_obj->v.list;
 | 
						|
  pnt = list_data->xi_pnt;
 | 
						|
  xi_fu_to_pu( lmp->itf_obj, &pnt, 1 );
 | 
						|
  lmp->rct.top = pnt.v;
 | 
						|
  lmp->rct.left = pnt.h;
 | 
						|
 | 
						|
  if ( !lmp->resize_with_window )
 | 
						|
  {
 | 
						|
    lmp->pixel_width = list_data->width *
 | 
						|
            xi_get_fu_width( lmp->itf_obj ) / XI_FU_MULTIPLE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( !lmp->is_list_font )
 | 
						|
    lmp->font = lmp->itf_obj->v.itf->font;
 | 
						|
  if (!lmp->font)
 | 
						|
    lmp->font = xi_get_system_font();
 | 
						|
  win = lmp->win;
 | 
						|
  XinWindowFontMap( win, lmp->font );
 | 
						|
  XinFontMetricsGet( lmp->font, &leading, &ascent, &descent );
 | 
						|
  lmp->leading = leading;
 | 
						|
  lmp->ascent = ascent;
 | 
						|
  lmp->descent = descent;
 | 
						|
  font_height = lmp->ascent + lmp->leading + lmp->descent;
 | 
						|
  lmp->pix_cell_height = font_height + ( RULE_Y_OFFSET_TOP +
 | 
						|
                                        RULE_Y_OFFSET_BOTTOM );
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  mch = 8;
 | 
						|
#else
 | 
						|
  mch = lmp->min_cell_height;
 | 
						|
#endif
 | 
						|
  lmp->pix_cell_height = max( lmp->pix_cell_height, mch );
 | 
						|
  lmp->pix_row_spacing = lmp->pix_cell_height + RULE_WIDTH_H;
 | 
						|
  lmp->pix_top = lmp->rct.top;
 | 
						|
  lmp->pix_hdr_bottom = lmp->rct.top + lmp->leading + lmp->ascent +
 | 
						|
          lmp->descent + BORDER_WIDTH +
 | 
						|
          RULE_Y_OFFSET_BOTTOM + RULE_Y_OFFSET_TOP + 1;
 | 
						|
  lmp->pix_hdr_bottom = max( lmp->pix_hdr_bottom,
 | 
						|
              ( lmp->rct.top + lmp->min_heading_height + 2 * BORDER_WIDTH ) );
 | 
						|
  if ( lmp->no_heading )
 | 
						|
    lmp->pix_row1_top = lmp->rct.top + BORDER_WIDTH;
 | 
						|
  else
 | 
						|
    lmp->pix_row1_top = lmp->pix_hdr_bottom + BORDER_WIDTH;
 | 
						|
 | 
						|
  old_char_width = lmp->pix_char_width;
 | 
						|
  lmp->pix_char_width = xi_get_fu_width( lmp->itf_obj );
 | 
						|
  calculate_pix_offsets( lmp, FALSE );
 | 
						|
 | 
						|
  for ( i = 0, cell_data = lmp->lm_column_data; i < lmp->nbr_columns; ++i, ++cell_data )
 | 
						|
    ( *cell_data )->pix_width = ( *cell_data )->pix_width * lmp->pix_char_width /
 | 
						|
            old_char_width;
 | 
						|
 | 
						|
  for ( i = 0; i < lmp->nbr_columns; ++i )
 | 
						|
    calc_x_pix_pos( lm, lmp->lm_column_data[i], i );
 | 
						|
 | 
						|
  calc_lmp_rct_right( lmp );
 | 
						|
 | 
						|
  if ( !lmp->resize_with_window )
 | 
						|
  {
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
    lmp->rct.bottom = lmp->pix_row1_top + lmp->nbr_rows * lmp->pix_row_spacing +
 | 
						|
            ( BORDER_WIDTH - RULE_WIDTH_H );
 | 
						|
#else
 | 
						|
    lmp->rct.bottom = lmp->pix_row1_top + lmp->nbr_rows * lmp->pix_row_spacing
 | 
						|
            + BORDER_WIDTH;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  if ( lmp->fixed_columns >= lmp->nbr_columns )
 | 
						|
    lmp->delta_x = 0;
 | 
						|
  else
 | 
						|
    lmp->delta_x = lmp->lm_column_data[lmp->first_vis]->x_pix_pos -
 | 
						|
            lmp->lm_column_data[lmp->fixed_columns]->x_pix_pos;
 | 
						|
 | 
						|
  lmp->mlr.top = lmp->pix_row1_top;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  lmp->mlr.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
#else
 | 
						|
  if ( lmp->pixel_width )
 | 
						|
    lmp->mlr.bottom = lmp->rct.bottom;
 | 
						|
  else
 | 
						|
    lmp->mlr.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
#endif
 | 
						|
  lmp->mlr_height = lmp->mlr.bottom - lmp->mlr.top;
 | 
						|
 | 
						|
  if ( lmp->rrr_bottom < lmp->mlr_height )
 | 
						|
    lm_make_rrr_room_pix( lmp, lmp->mlr_height - lmp->rrr_bottom, FALSE );
 | 
						|
 | 
						|
  {
 | 
						|
    XinRect vert_scrollbar_rect;
 | 
						|
    xi_get_sb_rect( lmp->list_obj, &vert_scrollbar_rect );
 | 
						|
    if ( list_data->sb_win )
 | 
						|
      lmp->pixel_width -= ( vert_scrollbar_rect.right
 | 
						|
                            - vert_scrollbar_rect.left - 1 );
 | 
						|
    lmp->pixel_width = max( lmp->pixel_width, 0 );
 | 
						|
    lmp->vir_right = lmp->rct.left + lmp->pixel_width + BORDER_WIDTH;
 | 
						|
  }
 | 
						|
 | 
						|
  list_data->have_sb_rct = FALSE;
 | 
						|
  list_data->have_hsb_rct = FALSE;
 | 
						|
 | 
						|
  xi_get_sb_rect( lmp->list_obj, &rct );
 | 
						|
  xi_offset_rect( &rct, -lmp->list_obj->itf->v.itf->delta_x,
 | 
						|
                  -lmp->list_obj->itf->v.itf->delta_y );
 | 
						|
  if ( list_data->sb_win )
 | 
						|
    XinWindowRectSet( list_data->sb_win, &rct );
 | 
						|
 | 
						|
  xi_get_hsb_rect( lmp->list_obj, &rct );
 | 
						|
  xi_offset_rect( &rct, -lmp->list_obj->itf->v.itf->delta_x,
 | 
						|
                  -lmp->list_obj->itf->v.itf->delta_y );
 | 
						|
  if ( list_data->hsb_win )
 | 
						|
    XinWindowRectSet( list_data->hsb_win, &rct );
 | 
						|
 | 
						|
  lm_calc_last_vis( lmp );
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
lm_text_scrolling( XI_OBJ * xi_obj )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) xi_obj->v.list->lm;
 | 
						|
 | 
						|
  lmp->text_scrolling = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
lm_set_hscroll_range( LM lm )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
  int hscroll_width,
 | 
						|
  fixed_width,
 | 
						|
  cnt;
 | 
						|
  XinRect mlr;
 | 
						|
  XI_LIST_DATA *listdata;
 | 
						|
 | 
						|
  if ( lmp->list_obj->nbr_children <= 0 )
 | 
						|
    return;
 | 
						|
 | 
						|
  listdata = lmp->list_obj->v.list;
 | 
						|
  lm_get_scroll_rct( lmp, &mlr );
 | 
						|
  if ( lmp->pixel_width )
 | 
						|
  {
 | 
						|
    int prop;
 | 
						|
 | 
						|
    hscroll_width = 0;
 | 
						|
    fixed_width = 0;
 | 
						|
    for ( cnt = lmp->fixed_columns; cnt < lmp->nbr_columns; ++cnt )
 | 
						|
      hscroll_width += lmp->lm_column_data[cnt]->pix_width + lm_get_col_spacing(  );
 | 
						|
    for ( cnt = 0; cnt < lmp->fixed_columns; ++cnt )
 | 
						|
      fixed_width += lmp->lm_column_data[cnt]->pix_width + lm_get_col_spacing(  );
 | 
						|
    prop = mlr.right - mlr.left - fixed_width - BORDER_WIDTH;
 | 
						|
    prop = min( prop, hscroll_width );
 | 
						|
    prop = max( prop, 0 );
 | 
						|
    XinScrollBarSet( listdata->hsb_win, XinScrollBarTypeEither, 0,
 | 
						|
                    hscroll_width, prop, 0 );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_column_set_pixel_width
 | 
						|
lm:         current lm
 | 
						|
idx:        column number
 | 
						|
width:      in pixels
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_column_set_pixel_width( LM lm, int idx, int width )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
  LM_COLUMN_DATA *column;
 | 
						|
  XinRect invalid_rct,
 | 
						|
  old_rct;
 | 
						|
  int i,
 | 
						|
  old_width,
 | 
						|
  new_row_height,
 | 
						|
  cnt;
 | 
						|
 | 
						|
  old_rct = lmp->rct;
 | 
						|
  column = lmp->lm_column_data[idx];
 | 
						|
  old_width = column->pix_width;
 | 
						|
  column->width = width / lmp->pix_char_width;
 | 
						|
  column->pix_width = width;
 | 
						|
  for ( i = idx + 1; i < lmp->nbr_columns; ++i )
 | 
						|
    calc_x_pix_pos( lm, lmp->lm_column_data[i], i );
 | 
						|
 | 
						|
  /* adjust bounding rectangle */
 | 
						|
  calc_lmp_rct_right( lmp );
 | 
						|
  if ( idx < lmp->fixed_columns )
 | 
						|
    lmp->vir_left += column->pix_width - old_width;
 | 
						|
 | 
						|
  /* The x_pix_pos of the first visible column may have changed so recalculate
 | 
						|
  * delta_x */
 | 
						|
  if ( lmp->fixed_columns >= lmp->nbr_columns )
 | 
						|
    lmp->delta_x = 0;
 | 
						|
  else
 | 
						|
    lmp->delta_x = lmp->lm_column_data[lmp->first_vis]->x_pix_pos -
 | 
						|
            lmp->lm_column_data[lmp->fixed_columns]->x_pix_pos;
 | 
						|
 | 
						|
  invalid_rct = lmp->rct;
 | 
						|
  invalid_rct.left = column->x_pix_pos;
 | 
						|
  invalid_rct.right = max( invalid_rct.right, old_rct.right );
 | 
						|
  if ( lmp->pixel_width )
 | 
						|
    invalid_rct.right = lmp->rct.left + lmp->pixel_width + 2 * BORDER_WIDTH;
 | 
						|
  lmp->list_obj->v.list->have_sb_rct = FALSE;
 | 
						|
  lmp->list_obj->v.list->have_hsb_rct = FALSE;
 | 
						|
  lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
  lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
  lm_calc_last_vis( lmp );
 | 
						|
 | 
						|
  if ( column->wrap_text )
 | 
						|
  {
 | 
						|
    int first_fully_vis = lmp->first_fully_vis;
 | 
						|
    int last_row = lmp->nbr_realized_rows - 1;
 | 
						|
    int height;
 | 
						|
 | 
						|
    for ( cnt = 0; cnt < lmp->nbr_realized_rows; ++cnt )
 | 
						|
    {
 | 
						|
      int old_row_height;
 | 
						|
 | 
						|
      old_row_height = lmp->pix_heights[cnt];
 | 
						|
      new_row_height = lm_calculate_row_height( lmp, cnt );
 | 
						|
      lmp->pix_heights[cnt] = new_row_height;
 | 
						|
      if ( old_row_height != new_row_height )
 | 
						|
        invalid_rct.left = lmp->rct.left;
 | 
						|
    }
 | 
						|
    calculate_pix_offsets( lmp, FALSE );
 | 
						|
    height = lmp->pix_offsets[last_row] + lmp->pix_heights[last_row] -
 | 
						|
            lmp->pix_offsets[first_fully_vis];
 | 
						|
    if ( height < lmp->mlr_height )
 | 
						|
      lm_make_rrr_room_pix( lmp, lmp->mlr_height - height, FALSE );
 | 
						|
    if ( !lmp->get_all_records )
 | 
						|
    {
 | 
						|
      int nbr_to_free;
 | 
						|
 | 
						|
      /* free any unnecessary records at the end of the list */
 | 
						|
      nbr_to_free = lmp->nbr_realized_rows - ( lmp->last_fully_vis + 2 );
 | 
						|
      for ( i = lmp->nbr_realized_rows - nbr_to_free, cnt = 0;
 | 
						|
            cnt < nbr_to_free;
 | 
						|
            i++, cnt++ )
 | 
						|
        lm_do_rec_event( lmp, i, XIE_REC_FREE );
 | 
						|
      lmp->nbr_realized_rows -= cnt;
 | 
						|
      calculate_visibles( lmp );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  lm_invalidate_rect2( lmp, &invalid_rct, TRUE );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_column_width
 | 
						|
lm:         current lm
 | 
						|
idx:        column number
 | 
						|
width:      in characters
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_column_width( LM lm, int idx, int width )
 | 
						|
{
 | 
						|
  lm_column_set_pixel_width( lm, idx,
 | 
						|
                            width * ( ( LM_DATA * ) lm )->pix_char_width );
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_visible_columns
 | 
						|
lm:         current lm
 | 
						|
first_vis:
 | 
						|
last_vis:
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_get_visible_columns( LM lm, int *first_vis, int *last_vis )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
 | 
						|
  *first_vis = lmp->first_vis;
 | 
						|
  *last_vis = lmp->last_vis;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_list_info
 | 
						|
lm:         current lm
 | 
						|
nbr_recs:   number of records
 | 
						|
returns:    array of record handles
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
long *
 | 
						|
lm_get_list_info( LM lm, int *nbr_recs )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
 | 
						|
  *nbr_recs = lmp->nbr_realized_rows;
 | 
						|
  return &lmp->recs[0];
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_cell_request
 | 
						|
lm:         current lm
 | 
						|
lm_part:    may be LM_LIST, LM_ROW, LM_COLUMN, or LM_CELL ??
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_cell_request( LM lm, LM_PART lm_part, int idx1, int idx2 )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  BOOLEAN redraw;
 | 
						|
 | 
						|
  redraw = ( BOOLEAN ) ( lmp->attrib & ( LM_ATR_VISIBLE ) );
 | 
						|
  lm_focus_cell_invis_make( lmp );
 | 
						|
  switch ( lm_part )
 | 
						|
  {
 | 
						|
    case LM_LIST:
 | 
						|
      lm_invalidate_rows_internal( lm, 0, lmp->nbr_realized_rows - 1, redraw, -1,
 | 
						|
                                  FALSE );
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
      return;
 | 
						|
    case LM_ROW:
 | 
						|
      lm_invalidate_rows_internal( lm, idx1, idx1, redraw, -1, FALSE );
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
      return;
 | 
						|
    case LM_COLUMN:
 | 
						|
      lm_invalidate_rows_internal( lm, 0, lmp->nbr_realized_rows - 1, redraw, idx1,
 | 
						|
                                  FALSE );
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
      return;
 | 
						|
    case LM_CELL:
 | 
						|
      lm_invalidate_rows_internal( lm, idx1, idx1, redraw, idx2, FALSE );
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
      return;
 | 
						|
  }
 | 
						|
  XinError( 20918, XinSeverityFatal, 0L );
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_visible_rows
 | 
						|
  ------------------------------------------------------------------------- */
 | 
						|
int
 | 
						|
lm_get_visible_rows( LM lm, int *first_vis, int *last_vis )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = ( LM_DATA * ) lm;
 | 
						|
 | 
						|
  if ( first_vis )
 | 
						|
    *first_vis = lmp->first_fully_vis;
 | 
						|
  if ( last_vis )
 | 
						|
    *last_vis = lmp->last_fully_vis;
 | 
						|
  if ( !lmp->nbr_realized_rows )
 | 
						|
    return 0;
 | 
						|
  else
 | 
						|
    return lmp->last_fully_vis - lmp->first_fully_vis + 1;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_list_obj
 | 
						|
lm:         current lm
 | 
						|
returns:    XI_OBJ * for list
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
XI_OBJ *
 | 
						|
lm_get_list_obj( LM lm )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  return ( lmp->list_obj );
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_buf_size_internal
 | 
						|
lm:         current lm
 | 
						|
part:       must be LM_COLUMN
 | 
						|
idx:        column number
 | 
						|
size:       the new buffer size
 | 
						|
redraw:     if TRUE, then redraw the cell
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
lm_set_buf_size_internal( LM lm, LM_PART part, int idx, int size, BOOLEAN redraw )
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  LM_COLUMN_DATA *lmcd;
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  if ( part != LM_COLUMN )
 | 
						|
    XinError( 20917, XinSeverityFatal, 0L );
 | 
						|
  lmcd = lmp->lm_column_data[idx];
 | 
						|
  lmcd->text_size = size;
 | 
						|
 | 
						|
  if ( ! lmcd->var_len_text )
 | 
						|
  {
 | 
						|
    for ( i = 0; i < lmp->nbr_realized_rows; i++ )
 | 
						|
    {
 | 
						|
      LM_CELL_DATA *cell_data = &lmp->cell_data[i][idx];
 | 
						|
 | 
						|
      xi_text_buffer_size_set( cell_data->xi_text, size );
 | 
						|
      if ( redraw && i < lmp->nbr_realized_rows )
 | 
						|
        redraw_cell( lm, i, idx, FALSE );
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_buf_size
 | 
						|
lm:         current lm
 | 
						|
part:       must be LM_COLUMN
 | 
						|
idx:        column number
 | 
						|
size:       the new buffer size
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_buf_size( LM lm, LM_PART part, int idx, int size )
 | 
						|
{
 | 
						|
  lm_set_buf_size_internal( lm, part, idx, size, TRUE );
 | 
						|
}
 | 
						|
 | 
						|
/* ------------------------------------------------------------------------ */
 | 
						|
/* adjust_focus_for_column_delete                                           */
 | 
						|
/* if the focus is on a column after the deleted column, adjust the focus   */
 | 
						|
/* objects.                                                                 */
 | 
						|
/* if the focus is on the deleted column, move the focus to the next        */
 | 
						|
/* column, previous column, or interface.                                   */
 | 
						|
/* ------------------------------------------------------------------------ */
 | 
						|
 | 
						|
static BOOLEAN
 | 
						|
adjust_focus_for_column_delete( LM_DATA * lmp, int column_nbr,
 | 
						|
                              BOOLEAN adjust_focus_column )
 | 
						|
{
 | 
						|
  XI_OBJ *focus_obj;
 | 
						|
 | 
						|
  focus_obj = lmp->itf_obj->v.itf->focus_obj;
 | 
						|
  if ( focus_obj == NULL || focus_obj->parent != lmp->list_obj
 | 
						|
      || focus_obj->type != XIT_CELL )
 | 
						|
    return TRUE;
 | 
						|
 | 
						|
  if ( focus_obj->v.cell.column == column_nbr )
 | 
						|
  {
 | 
						|
    XI_OBJ new_cell;
 | 
						|
    int row, col;
 | 
						|
    BOOLEAN temp;
 | 
						|
 | 
						|
    temp = TRUE;
 | 
						|
    calculate_next_cell( lmp, &row, &col, &temp, '\t', &temp, &temp );
 | 
						|
    if ( row != focus_obj->v.cell.row )
 | 
						|
    {
 | 
						|
      temp = TRUE;
 | 
						|
      calculate_next_cell( lmp, &row, &col, &temp, XI_KEY_BTAB, &temp, &temp );
 | 
						|
    }
 | 
						|
    if ( row == focus_obj->v.cell.row )
 | 
						|
    {
 | 
						|
      XI_MAKE_CELL( &new_cell, lmp->list_obj, row, col );
 | 
						|
      if ( !xi_move_focus( &new_cell ) )
 | 
						|
        return FALSE;
 | 
						|
      if ( adjust_focus_column &&
 | 
						|
          ( int ) focus_obj->v.cell.column > ( int ) column_nbr )
 | 
						|
      {
 | 
						|
        focus_obj = lmp->itf_obj->v.itf->focus_obj;
 | 
						|
        focus_obj->v.cell.column--;
 | 
						|
      }
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
    return xi_move_focus( lmp->itf_obj );
 | 
						|
  }
 | 
						|
  if ( adjust_focus_column &&
 | 
						|
      ( int ) focus_obj->v.cell.column > ( int ) column_nbr )
 | 
						|
    focus_obj->v.cell.column--;
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_delete_column
 | 
						|
lm:         current lm
 | 
						|
column_nbr: column to delete
 | 
						|
adjust_hscrolling: if TRUE, then make more horizontal columns visible
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_delete_column( LM lm, int column_nbr, BOOLEAN adjust_hscrolling )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  LM_COLUMN_DATA *lmcd;
 | 
						|
  XinRect invalid_rct,
 | 
						|
  old_rct;
 | 
						|
  int i,
 | 
						|
  old_width,
 | 
						|
  old_left,
 | 
						|
  col_spacing;
 | 
						|
  int old_x_pix_pos;
 | 
						|
  LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
  if ( !adjust_focus_for_column_delete( lmp, column_nbr, TRUE ) )
 | 
						|
    return;
 | 
						|
  col_spacing = lm_get_col_spacing(  );
 | 
						|
  if ( column_nbr >= lmp->nbr_columns )
 | 
						|
    XinError( 20915, XinSeverityFatal, 0L );
 | 
						|
  old_rct = lmp->rct;
 | 
						|
  lmcd = lmp->lm_column_data[column_nbr];
 | 
						|
  if ( lmcd->font )
 | 
						|
    XinFontDestroy( lmcd->font );
 | 
						|
  xi_bitmap_destroy( lmcd->bitmap );
 | 
						|
  old_left = lmcd->x_pix_pos - lmp->delta_x;
 | 
						|
  old_x_pix_pos = lmcd->x_pix_pos;
 | 
						|
  old_width = lmcd->pix_width;
 | 
						|
  xi_tree_free( lmp->lm_column_data[column_nbr] );
 | 
						|
 | 
						|
  /* cell_data_destruct */
 | 
						|
  for ( i = 0; i < lmp->nbr_realized_rows; ++i )
 | 
						|
  {
 | 
						|
    cell_data = &( lmp->cell_data[i][column_nbr] );
 | 
						|
    if ( cell_data->font )
 | 
						|
      XinFontDestroy( cell_data->font );
 | 
						|
    xi_bitmap_destroy( cell_data->bitmap );
 | 
						|
    xi_bitmap_destroy( cell_data->button_bitmap );
 | 
						|
    if ( cell_data->xi_text )
 | 
						|
      xi_text_destruct( cell_data->xi_text );
 | 
						|
  }
 | 
						|
 | 
						|
  for ( i = 0; i < lmp->realized_rows_array_len; ++i )
 | 
						|
  {
 | 
						|
    int j;
 | 
						|
 | 
						|
    for ( j = column_nbr; j < lmp->nbr_columns - 1; ++j )
 | 
						|
      lmp->cell_data[i][j] = lmp->cell_data[i][j + 1];
 | 
						|
    lmp->cell_data[i] = ( LM_CELL_DATA * ) xi_tree_realloc( lmp->cell_data[i],
 | 
						|
                          ( lmp->nbr_columns - 1 ) * sizeof( LM_CELL_DATA ) );
 | 
						|
  }
 | 
						|
 | 
						|
  for ( i = column_nbr; i < lmp->nbr_columns - 1; ++i )
 | 
						|
    lmp->lm_column_data[i] = lmp->lm_column_data[i + 1];
 | 
						|
  --lmp->nbr_columns;
 | 
						|
  { /* Check focus cell, to see if it is now out of range */
 | 
						|
    XI_OBJ* focus_cell;
 | 
						|
 | 
						|
    focus_cell = lmp->list_obj->v.list->focus_cell;
 | 
						|
    if ( (int)focus_cell->v.cell.column >= lmp->nbr_columns )
 | 
						|
      focus_cell->v.cell.column = lmp->nbr_columns - 1;
 | 
						|
  }
 | 
						|
 | 
						|
  for ( i = column_nbr; i < lmp->nbr_columns; ++i )
 | 
						|
    calc_x_pix_pos( lm, lmp->lm_column_data[i], i );
 | 
						|
 | 
						|
  calc_lmp_rct_right( lmp );
 | 
						|
 | 
						|
  /* adjust left border of horizontal virtual space */
 | 
						|
  if ( column_nbr < lmp->fixed_columns )
 | 
						|
    lmp->vir_left -= ( old_width + col_spacing );
 | 
						|
 | 
						|
 | 
						|
  /* if the column is invisible */
 | 
						|
  calculate_pix_offsets( lmp, TRUE );
 | 
						|
  if ( column_nbr >= lmp->fixed_columns && old_x_pix_pos < lmp->delta_x )
 | 
						|
  {
 | 
						|
    lmp->delta_x -= ( old_width + lm_get_col_spacing(  ) );
 | 
						|
    --lmp->first_vis;
 | 
						|
    lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
    lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if ( column_nbr < lmp->fixed_columns )
 | 
						|
    {
 | 
						|
      --lmp->first_vis;
 | 
						|
      --lmp->fixed_columns;
 | 
						|
      lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
      lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
    }
 | 
						|
 | 
						|
    invalid_rct = lmp->rct;
 | 
						|
    invalid_rct.left = old_left;
 | 
						|
    invalid_rct.right = max( invalid_rct.right, old_rct.right );
 | 
						|
    if ( lmp->pixel_width )
 | 
						|
      invalid_rct.right = lmp->rct.left + lmp->pixel_width + BORDER_WIDTH;
 | 
						|
 | 
						|
    /* if we add the following two lines in, it prevents flashing of the top
 | 
						|
    * and bottom borders when moving columns, however, the top and bottom
 | 
						|
    * borders need to get invalidated invalid_rct.top += BORDER_WIDTH;
 | 
						|
    * invalid_rct.bottom -= BORDER_WIDTH; */
 | 
						|
 | 
						|
    lm_invalidate_rect2( lmp, &invalid_rct, FALSE );
 | 
						|
    lmp->list_obj->v.list->have_sb_rct = FALSE;
 | 
						|
    lmp->list_obj->v.list->have_hsb_rct = FALSE;
 | 
						|
 | 
						|
    i = lm_get_left_most_far_right_col( lmp, lmp->nbr_columns );
 | 
						|
    /* All columns have been deleted */
 | 
						|
    if ( i == 0 )
 | 
						|
    {
 | 
						|
      lmp->delta_x = 0;
 | 
						|
      lmp->last_vis = lmp->first_vis = i;
 | 
						|
      lm_calc_last_vis( lmp );
 | 
						|
      lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if ( lmp->first_vis >= lmp->nbr_columns )
 | 
						|
    {
 | 
						|
      XinRect r;
 | 
						|
 | 
						|
      XinWindowPaintForce( lmp->win );
 | 
						|
      if ( i < lmp->nbr_columns )
 | 
						|
        lmp->delta_x = lmp->lm_column_data[i]->x_pix_pos - lmp->vir_left;
 | 
						|
      else
 | 
						|
        lmp->delta_x = 0;
 | 
						|
      xi_set_update_obj( lmp->list_obj );
 | 
						|
      lmp->last_vis = lmp->first_vis = i;
 | 
						|
      lm_calc_last_vis( lmp );
 | 
						|
      r.left = lmp->vir_left;
 | 
						|
      r.right = lmp->vir_right;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
      r.top = lmp->rct.top + BORDER_WIDTH;
 | 
						|
      r.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
#else
 | 
						|
      r.top = lmp->rct.top;
 | 
						|
      r.bottom = lmp->rct.bottom;
 | 
						|
#endif
 | 
						|
      xi_invalidate_rect( lmp->win, &r );
 | 
						|
      XinWindowPaintForce( lmp->win );
 | 
						|
      lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if ( i < lmp->first_vis && adjust_hscrolling )
 | 
						|
      {
 | 
						|
        XinWindowPaintForce( lmp->win );
 | 
						|
        lm_hscroll( lm, i - lmp->first_vis, 0 );
 | 
						|
        lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
        lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        lm_calc_last_vis( lmp );
 | 
						|
        lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
        lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
TODO this function will change.  pix_row_spacing will no longer be used.
 | 
						|
instead, min_row_height, and absolute_height will be used.
 | 
						|
*/
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
  lm_get_vertical_metrics
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_get_vertical_metrics( XI_OBJ_DEF * obj_def, int *first_row_y,
 | 
						|
                        int *row_spacing, int *client_height,
 | 
						|
                        int *title_height )
 | 
						|
{
 | 
						|
  XI_LIST_DEF *list_def;
 | 
						|
  XI_OBJ_DEF *itf_def;
 | 
						|
  int leading,
 | 
						|
  ascent,
 | 
						|
  descent,
 | 
						|
  char_width,
 | 
						|
  font_height,
 | 
						|
  pix_cell_height,
 | 
						|
  pix_hdr_bottom,
 | 
						|
  min_cell_height;
 | 
						|
  XinPoint p;
 | 
						|
  XinFont *fontp = NULL;
 | 
						|
 | 
						|
  list_def = obj_def->v.list;
 | 
						|
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  itf_def = obj_def->parent;
 | 
						|
  if ( itf_def && itf_def->v.itf->font )
 | 
						|
    fontp = itf_def->v.itf->font;
 | 
						|
  if ( list_def->font )
 | 
						|
    xi_get_font_metrics_font( list_def->font, &leading, &ascent,
 | 
						|
                              &descent, &char_width );
 | 
						|
  else if ( fontp )
 | 
						|
    xi_get_font_metrics_font( fontp, &leading, &ascent, &descent,
 | 
						|
                              &char_width );
 | 
						|
  else
 | 
						|
    xi_get_font_metrics_font( xi_get_system_font(  ), &leading,
 | 
						|
                              &ascent, &descent, &char_width );
 | 
						|
#else
 | 
						|
  leading = 0;
 | 
						|
  ascent = 8;
 | 
						|
  descent = 0;
 | 
						|
#endif
 | 
						|
  font_height = ascent + leading + descent;
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  min_cell_height = 8;
 | 
						|
  pix_cell_height = font_height;
 | 
						|
#else
 | 
						|
  min_cell_height = list_def->min_cell_height;
 | 
						|
  pix_cell_height = font_height + CELL_VERTICAL_MARGIN;
 | 
						|
#endif
 | 
						|
  pix_cell_height = max( pix_cell_height, min_cell_height );
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
  *row_spacing = pix_cell_height;
 | 
						|
#else
 | 
						|
  *row_spacing = pix_cell_height + RULE_WIDTH_H;
 | 
						|
#endif
 | 
						|
  itf_def = obj_def->parent;
 | 
						|
  if ( itf_def && itf_def->v.itf->font )
 | 
						|
    fontp = itf_def->v.itf->font;
 | 
						|
  if ( xi_def_get_xil_pref( itf_def ) )
 | 
						|
  {
 | 
						|
    p = list_def->xi_pnt;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    p = list_def->pixel_origin;
 | 
						|
    if ( !p.v && !p.h )
 | 
						|
    {
 | 
						|
      p = list_def->xi_pnt;
 | 
						|
      if ( list_def->font )
 | 
						|
        xi_fu_to_pu_font( list_def->font, &p, 1 );
 | 
						|
      else if ( fontp )
 | 
						|
        xi_fu_to_pu_font( fontp, &p, 1 );
 | 
						|
      else
 | 
						|
        xi_fu_to_pu_font( xi_get_system_font(  ), &p, 1 );
 | 
						|
    }
 | 
						|
  }
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  pix_hdr_bottom = p.v + leading + ascent + descent + BORDER_WIDTH
 | 
						|
          + RULE_Y_OFFSET_BOTTOM + RULE_Y_OFFSET_TOP + 1;
 | 
						|
  pix_hdr_bottom = max( pix_hdr_bottom, p.v + list_def->min_heading_height
 | 
						|
                        + BORDER_WIDTH );
 | 
						|
#else
 | 
						|
  pix_hdr_bottom = p.v + leading + ascent + descent + BORDER_WIDTH;
 | 
						|
  pix_hdr_bottom = max( pix_hdr_bottom, p.v + list_def->min_heading_height );
 | 
						|
#endif
 | 
						|
  if ( list_def->no_heading )
 | 
						|
  {
 | 
						|
    int first_row_y_pos = p.v + BORDER_WIDTH;
 | 
						|
 | 
						|
    *first_row_y = first_row_y_pos;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    *first_row_y = pix_hdr_bottom + BORDER_WIDTH;
 | 
						|
  }
 | 
						|
  if ( xi_def_get_xil_pref( itf_def ) )
 | 
						|
  {
 | 
						|
    *client_height = list_def->height;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if ( list_def->pixel_height )
 | 
						|
      *client_height = list_def->pixel_height;
 | 
						|
    else
 | 
						|
    {
 | 
						|
      int height;
 | 
						|
 | 
						|
      if ( list_def->font )
 | 
						|
        height = xi_get_fu_height_font( list_def->font );
 | 
						|
      else if ( fontp )
 | 
						|
        height = xi_get_fu_height_font( fontp );
 | 
						|
      else
 | 
						|
        height = xi_get_fu_height_font( xi_get_system_font(  ) );
 | 
						|
      *client_height = list_def->height * height / XI_FU_MULTIPLE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  *title_height = *first_row_y - p.v;
 | 
						|
  *client_height -= *title_height + BORDER_WIDTH;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:       lm_get_metrics
 | 
						|
lm_def:         definition of a list
 | 
						|
hborder:        to be filled in with the horizontal border width
 | 
						|
column_div:     to be filled in with the column spacing in pixels
 | 
						|
list_bottom:    bottom of the list, in pixels
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_get_metrics( XI_OBJ_DEF * obj_def, int *hborder, int *column_div,
 | 
						|
                int *list_bottom )
 | 
						|
{
 | 
						|
  if ( hborder != NULL )
 | 
						|
    *hborder = BORDER_WIDTH;
 | 
						|
  if ( column_div != NULL )
 | 
						|
    *column_div = lm_get_col_spacing(  );
 | 
						|
  if ( obj_def->v.list )
 | 
						|
  {
 | 
						|
    int pix_row_spacing,
 | 
						|
    nbr_rows,
 | 
						|
    height,
 | 
						|
    pix_row1_top,
 | 
						|
    title_height;
 | 
						|
 | 
						|
    lm_get_vertical_metrics( obj_def, &pix_row1_top, &pix_row_spacing,
 | 
						|
                            &height, &title_height );
 | 
						|
    if ( obj_def->v.list->one_row_list )
 | 
						|
      nbr_rows = 1;
 | 
						|
    else
 | 
						|
      nbr_rows = height / pix_row_spacing;
 | 
						|
#if XIWS == XIWS_WM
 | 
						|
    *list_bottom = pix_row1_top + nbr_rows * pix_row_spacing + BORDER_WIDTH;
 | 
						|
#else
 | 
						|
    *list_bottom = pix_row1_top + nbr_rows * pix_row_spacing
 | 
						|
            + ( BORDER_WIDTH - RULE_WIDTH_H );
 | 
						|
#endif
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_hscroll_bar
 | 
						|
lm:         current lm
 | 
						|
notes:      Calculate the percentage for the horizontal scroll bar, and set the
 | 
						|
        thumb position on the horizontal scroll bar.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_hscroll_bar( LM lm )
 | 
						|
{
 | 
						|
  XI_OBJ *list_obj;
 | 
						|
  int p;
 | 
						|
  LM_DATA *lmp;
 | 
						|
  int rng1,
 | 
						|
  rng2;
 | 
						|
  int prop;
 | 
						|
 | 
						|
  lmp = ( LM_DATA * ) lm;
 | 
						|
  list_obj = lmp->list_obj;
 | 
						|
  if ( list_obj->v.list->hsb_win )
 | 
						|
  {
 | 
						|
    XinScrollBarRangeGet( list_obj->v.list->hsb_win, XinScrollBarTypeEither,
 | 
						|
                          &rng1, &rng2 );
 | 
						|
    prop = XinScrollBarProportionGet( list_obj->v.list->hsb_win, XinScrollBarTypeEither );
 | 
						|
    p = lmp->delta_x;
 | 
						|
    if ( p > rng2 - prop )
 | 
						|
      p = rng2 - prop;
 | 
						|
    XinScrollBarPositionSet( list_obj->v.list->hsb_win, XinScrollBarTypeEither,
 | 
						|
                            p );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:           lm_create_column
 | 
						|
lcdef:              column definition
 | 
						|
not_creating_list:  if TRUE, do all of the cell requests for the column
 | 
						|
in_hscrolling:    if TRUE, and if on border between fixed and scrolling columns
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_create_column( LM lm, LM_COLUMN_DEF * lcdef, BOOLEAN not_creating_list,
 | 
						|
                  BOOLEAN in_hscrolling )
 | 
						|
{
 | 
						|
  LM_COLUMN_DATA *lcdata;
 | 
						|
  LM_COLUMN_DATA **column_data;
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  XinRect rct_to_invalidate;
 | 
						|
  int i;
 | 
						|
  int position,
 | 
						|
  col_spacing;
 | 
						|
  int focus_row,
 | 
						|
  focus_column;
 | 
						|
  BOOLEAN made_invis = FALSE;
 | 
						|
 | 
						|
  col_spacing = lm_get_col_spacing(  );
 | 
						|
  position = min( lcdef->position, lmp->nbr_columns );
 | 
						|
  if ( lm_focus_list_has( lmp ) )
 | 
						|
  {
 | 
						|
    BOOLEAN v_scrolled;
 | 
						|
 | 
						|
    lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | 
						|
    if ( focus_column >= position )
 | 
						|
      ++focus_column;
 | 
						|
    lm_focus_cell_set( lmp, focus_row, focus_column, v_scrolled );
 | 
						|
    if ( lm_focus_state_get( lmp ) != LM_FOCUS_VISIBLE )
 | 
						|
    {
 | 
						|
      lm_focus_cell_invis_make( lmp );
 | 
						|
      made_invis = TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  lcdata = ( LM_COLUMN_DATA * ) xi_tree_malloc( sizeof( LM_COLUMN_DATA ),
 | 
						|
                                                ( char * ) lm );
 | 
						|
  lcdata->attrib = lcdef->attrib;
 | 
						|
/*
 | 
						|
  lcdata->pix_width = lcdef->width * lmp->pix_char_width;
 | 
						|
  lcdata->width = lcdef->width;
 | 
						|
*/
 | 
						|
  lcdata->pix_width = lcdef->pix_width;
 | 
						|
  lcdata->width = lcdef->pix_width / lmp->pix_char_width;
 | 
						|
  calc_x_pix_pos( lm, lcdata, position );
 | 
						|
  lcdata->text_size = lcdef->text_size;
 | 
						|
  lcdata->center_heading = lcdef->center_heading;
 | 
						|
  lcdata->heading_well = lcdef->heading_well;
 | 
						|
  lcdata->heading_platform = lcdef->heading_platform;
 | 
						|
  lcdata->column_well = lcdef->column_well;
 | 
						|
  lcdata->column_platform = lcdef->column_platform;
 | 
						|
  lcdata->heading_text = ( char * ) xi_tree_malloc(
 | 
						|
                          strlen( lcdef->heading_text ) + 1, ( char * ) lm );
 | 
						|
  strcpy( lcdata->heading_text, lcdef->heading_text );
 | 
						|
  if ( lcdef->font )
 | 
						|
    lcdata->font = lcdef->font;
 | 
						|
  lcdata->icon_rid = lcdef->icon_rid;
 | 
						|
  lcdata->icon_x = lcdef->icon_x;
 | 
						|
  lcdata->icon_y = lcdef->icon_y;
 | 
						|
  lcdata->bitmap = lcdef->bitmap;
 | 
						|
  lcdata->size_rows = lcdef->size_rows;
 | 
						|
  lcdata->suppress_update_heading = lcdef->suppress_update_heading;
 | 
						|
  lcdata->suppress_update_cells = lcdef->suppress_update_cells;
 | 
						|
  lcdata->vertical_align_center = lcdef->vertical_align_center;
 | 
						|
  lcdata->vertical_align_bottom = lcdef->vertical_align_bottom;
 | 
						|
  lcdata->wrap_text = lcdef->wrap_text;
 | 
						|
  lcdata->wrap_text_scrollbar = lcdef->wrap_text_scrollbar;
 | 
						|
  lcdata->cr_ok = lcdef->cr_ok;
 | 
						|
  lcdata->var_len_text = lcdef->var_len_text;
 | 
						|
  lcdata->auto_tab = lcdef->auto_tab;
 | 
						|
  lcdata->icon_mode = lcdef->icon_mode;
 | 
						|
 | 
						|
  /* allocate new columns */
 | 
						|
  column_data = lmp->lm_column_data =
 | 
						|
          ( LM_COLUMN_DATA * * ) xi_tree_realloc2(
 | 
						|
                                              ( char * ) lmp->lm_column_data,
 | 
						|
                        sizeof( LM_COLUMN_DATA * ) * ( lmp->nbr_columns + 1 ),
 | 
						|
                                                  ( char * ) lm );
 | 
						|
 | 
						|
  /* move column pointers around in the column list */
 | 
						|
  for ( i = lmp->nbr_columns; i > position; i-- )
 | 
						|
  {
 | 
						|
    column_data[i] = column_data[i - 1];
 | 
						|
    column_data[i]->x_pix_pos += lcdata->pix_width + col_spacing;
 | 
						|
  }
 | 
						|
  column_data[position] = lcdata;
 | 
						|
 | 
						|
  lmp->nbr_columns++;
 | 
						|
 | 
						|
  /* create space for cell data */
 | 
						|
  /* cell_data_construct */
 | 
						|
  for ( i = 0; i < lmp->realized_rows_array_len; i++ )
 | 
						|
  {
 | 
						|
    int j;
 | 
						|
 | 
						|
    lmp->cell_data[i] = ( LM_CELL_DATA * ) xi_tree_realloc( lmp->cell_data[i],
 | 
						|
                          ( lmp->nbr_columns + 1 ) * sizeof( LM_CELL_DATA ) );
 | 
						|
    for ( j = lmp->nbr_columns; j > position; j-- )
 | 
						|
      lmp->cell_data[i][j] = lmp->cell_data[i][j - 1];
 | 
						|
    memset( ( char * ) &lmp->cell_data[i][position], '\0',
 | 
						|
            sizeof( LM_CELL_DATA ) );
 | 
						|
  }
 | 
						|
 | 
						|
  if ( not_creating_list )
 | 
						|
  {
 | 
						|
    for ( i = 0; i < lmp->nbr_realized_rows; ++i )
 | 
						|
      lm_xi_text_construct( lmp, i, position );
 | 
						|
  }
 | 
						|
 | 
						|
  if ( ( not_creating_list ) && ( position < lmp->fixed_columns ) )
 | 
						|
  {
 | 
						|
    lmp->first_vis++;
 | 
						|
    lmp->fixed_columns++;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( not_creating_list && ( !in_hscrolling ) && position == lmp->fixed_columns )
 | 
						|
  {
 | 
						|
    lmp->first_vis++;
 | 
						|
    lmp->fixed_columns++;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( lmp->first_vis < lmp->fixed_columns &&
 | 
						|
      lmp->nbr_columns > lmp->fixed_columns )
 | 
						|
    lmp->first_vis = lmp->fixed_columns;
 | 
						|
 | 
						|
  /* adjust bounding rectangle */
 | 
						|
  calc_lmp_rct_right( lmp );
 | 
						|
 | 
						|
  /* calculate the left boundary of the virtual space for the list */
 | 
						|
  lmp->vir_left = lmp->rct.left + BORDER_WIDTH;
 | 
						|
  for ( i = 0; i < min( lmp->nbr_columns, lmp->fixed_columns ); ++i )
 | 
						|
  {
 | 
						|
    lmp->vir_left += lmp->lm_column_data[i]->pix_width;
 | 
						|
    lmp->vir_left += col_spacing;
 | 
						|
  }
 | 
						|
  if ( not_creating_list )
 | 
						|
  {
 | 
						|
    lm_invalidate_rows_internal( lm, 0, INT_MAX, FALSE, position, TRUE );
 | 
						|
    calculate_pix_offsets( lmp, TRUE );
 | 
						|
  }
 | 
						|
  if ( position >= lmp->fixed_columns && column_data[position]->x_pix_pos < lmp->delta_x )
 | 
						|
  {
 | 
						|
    lmp->delta_x += ( column_data[position]->pix_width + lm_get_col_spacing(  ) );
 | 
						|
    ++lmp->first_vis;
 | 
						|
    lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
    lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    /* invalidate changed rectangle */
 | 
						|
    lm_get_list_rct( lmp, &rct_to_invalidate );
 | 
						|
 | 
						|
    /* if we add the following two lines in, it prevents flashing of the top
 | 
						|
    * and bottom borders when moving columns, however, the top and bottom
 | 
						|
    * borders need to get invalidated rct_to_invalidate.top += BORDER_WIDTH;
 | 
						|
    * rct_to_invalidate.bottom -= BORDER_WIDTH; */
 | 
						|
 | 
						|
    rct_to_invalidate.left = lcdata->x_pix_pos;
 | 
						|
    lm_adj_h( lmp, &rct_to_invalidate.left );
 | 
						|
    if ( rct_to_invalidate.bottom > rct_to_invalidate.top &&
 | 
						|
        rct_to_invalidate.right > rct_to_invalidate.left )
 | 
						|
      lm_invalidate_rect2( lmp, &rct_to_invalidate, FALSE );
 | 
						|
  }
 | 
						|
  lm_calc_last_vis( lmp );
 | 
						|
  lmp->list_obj->v.list->have_sb_rct = FALSE;
 | 
						|
  if ( not_creating_list && lmp->list_obj->v.list->hsb_win )
 | 
						|
  {
 | 
						|
    XinRect rct;
 | 
						|
 | 
						|
    lmp->list_obj->v.list->have_hsb_rct = FALSE;
 | 
						|
    lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
    lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
    xi_get_hsb_rect( lmp->list_obj, &rct );
 | 
						|
    xi_offset_rect( &rct, -lmp->list_obj->itf->v.itf->delta_x,
 | 
						|
                    -lmp->list_obj->itf->v.itf->delta_y );
 | 
						|
    XinWindowRectSet( lmp->list_obj->v.list->hsb_win, &rct );
 | 
						|
  }
 | 
						|
  if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | 
						|
  {
 | 
						|
    if ( not_creating_list && made_invis )
 | 
						|
      lm_focus_cell_visible_attempt( lmp );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   do_lm_cb_column
 | 
						|
lm:         current lm
 | 
						|
cb_reason:  one of LM_CB_COL_DELETE, LM_CB_COL_MOVE, LM_CB_COL_SIZE
 | 
						|
col_nbr:    column being deleted, moved, or re-sized
 | 
						|
new_col_nbr:    new column number on LM_CB_COL_MOVE
 | 
						|
new_col_width:  new column width on LM_CB_COL_SIZE
 | 
						|
new_col_pixel_width:  new column pixel width on LM_CB_COL_SIZE
 | 
						|
in_fixed: if TRUE, then column is being moved to fixed portion of list
 | 
						|
returns:    TRUE if event refused
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static BOOLEAN
 | 
						|
do_lm_cb_column( LM lm, LM_CB_TYPE cb_reason, int col_nbr,
 | 
						|
                int new_col_nbr, int new_col_width, int new_col_pixel_width,
 | 
						|
                BOOLEAN in_fixed )
 | 
						|
{
 | 
						|
  LM_CB_DATA lm_cb_data;
 | 
						|
 | 
						|
  lm_cb_data.lm = lm;
 | 
						|
  lm_cb_data.cb_type = cb_reason;
 | 
						|
  lm_cb_data.cid = LMP( lm )->cid;
 | 
						|
  lm_cb_data.win = LMP( lm )->win;
 | 
						|
  lm_cb_data.column = ( unsigned char ) col_nbr;
 | 
						|
  lm_cb_data.v.column.new_col_nbr = new_col_nbr;
 | 
						|
  lm_cb_data.v.column.in_fixed = in_fixed;
 | 
						|
  lm_cb_data.v.column.new_col_width = new_col_width;
 | 
						|
  lm_cb_data.v.column.new_col_pixel_width = new_col_pixel_width;
 | 
						|
  lm_cb_data.v.column.refused = FALSE;
 | 
						|
  ( *LMP( lm )->lm_cb ) ( &lm_cb_data );
 | 
						|
  return ( lm_cb_data.v.column.refused );
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   get_rubber_rect
 | 
						|
lmp:        current lmp
 | 
						|
rctp:       rectangle to be filled in
 | 
						|
x:          current mouse x position
 | 
						|
y:          current mouse y position
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
get_rubber_rect( LM_DATA * lmp, XinRect * rctp, int x, int y,
 | 
						|
                BOOLEAN last_in_hscrolling )
 | 
						|
{
 | 
						|
  XinRect rct;
 | 
						|
 | 
						|
  if ( lmp->moving_column )
 | 
						|
  {
 | 
						|
    int col,
 | 
						|
    delta_x,
 | 
						|
    delta_y;
 | 
						|
 | 
						|
    col = lmp->column_being_moved;
 | 
						|
    /* lm_get_cell_rect returns the exact physical rectangle of the cell - not
 | 
						|
    * shifted to the right or to the left. */
 | 
						|
    lm_get_cell_rect( &rct, ( LM ) lmp, 1, col, FALSE, TRUE );
 | 
						|
    rct.top = lmp->pix_top + BORDER_WIDTH;
 | 
						|
    rct.bottom = lmp->pix_hdr_bottom;
 | 
						|
    delta_x = x - lmp->org_x;
 | 
						|
    if ( lmp->down_in_hscrolling && !last_in_hscrolling )
 | 
						|
      delta_x += lmp->delta_x;
 | 
						|
    if ( !lmp->down_in_hscrolling && last_in_hscrolling )
 | 
						|
      delta_x -= lmp->delta_x;
 | 
						|
    delta_y = y - lmp->org_y;
 | 
						|
    rct.left += delta_x;
 | 
						|
    rct.right += delta_x;
 | 
						|
    rct.top += delta_y;
 | 
						|
    rct.bottom += delta_y;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    lm_get_rect( ( LM ) lmp, LM_LIST, 0, &rct );
 | 
						|
    rct.top = y;
 | 
						|
    rct.bottom = rct.top + lmp->drag_row_height;
 | 
						|
    rct.right += x - rct.left;
 | 
						|
    rct.left = x;
 | 
						|
  }
 | 
						|
  *rctp = rct;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   rubber_rect
 | 
						|
lmp:        current lmp
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
rubber_rect( LM_DATA * lmp )
 | 
						|
{
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  XinRect rct;
 | 
						|
  XinDrawTools new_ctools;
 | 
						|
  XinWindow win = lmp->win;
 | 
						|
 | 
						|
  if ( lmp->last_itf )
 | 
						|
    win = xi_get_window( lmp->last_itf );
 | 
						|
 | 
						|
  XinWindowDrawToolsNormalGet( &new_ctools );
 | 
						|
  XinWindowDrawToolsSet( win, &new_ctools );
 | 
						|
  XinWindowPenSet( win, &rubber_cpen );
 | 
						|
  XinWindowBrushSet( win, &hollow_cbrush );
 | 
						|
  XinWindowDrawModeSet( win, XinDrawModeXor );
 | 
						|
  xi_set_clip( win, NULL );
 | 
						|
  get_rubber_rect( lmp, &rct, lmp->last_x, lmp->last_y, lmp->last_in_hscrolling );
 | 
						|
  xi_draw_rect( win, &rct );
 | 
						|
#else
 | 
						|
  NOREF( lmp );
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_move_event
 | 
						|
lmp:        current lmp
 | 
						|
ep:         xvt event
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
#define XI_AUTOSCROLL_COUNT 8   /* Number of move events before autoscroll
 | 
						|
                                * occurs */
 | 
						|
#define XI_AUTOSCROLL_FAST  50  /* Number of pixels to get to fast autoscroll */
 | 
						|
 | 
						|
void
 | 
						|
lm_move_event( LM_DATA * lmp, XinEvent * ep )
 | 
						|
{
 | 
						|
  XinPoint where;
 | 
						|
  int col_offset;
 | 
						|
 | 
						|
  col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | 
						|
  where = ep->v.mouse.where;
 | 
						|
  switch ( ep->type )
 | 
						|
  {
 | 
						|
    case XinEventMouseDown:
 | 
						|
    case XinEventMouseDouble:
 | 
						|
      lmp->last_x = where.h;
 | 
						|
      lmp->org_x = lmp->last_x;
 | 
						|
      lmp->last_y = where.v;
 | 
						|
      lmp->org_y = lmp->last_y;
 | 
						|
      lmp->last_in_hscrolling = lmp->in_hscrolling;
 | 
						|
      rubber_rect( lmp );
 | 
						|
      break;
 | 
						|
    case XinEventMouseMove:
 | 
						|
      {
 | 
						|
        static int autoscroll_count = 0;
 | 
						|
        BOOLEAN scrolled = FALSE;
 | 
						|
 | 
						|
        if ( lmp->pixel_width != 0 )
 | 
						|
        {                       /* Check for autoscroll */
 | 
						|
          if ( where.h - lmp->delta_x > lmp->vir_right )
 | 
						|
          {
 | 
						|
            if ( where.h - lmp->delta_x > lmp->vir_right + XI_AUTOSCROLL_FAST
 | 
						|
                || ++autoscroll_count >= XI_AUTOSCROLL_COUNT )
 | 
						|
            {
 | 
						|
              autoscroll_count = 0;
 | 
						|
              rubber_rect( lmp );
 | 
						|
              lm_hscroll( ( LM ) lmp, 1, 0 );
 | 
						|
              scrolled = TRUE;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else if ( where.h < lmp->vir_left )
 | 
						|
          {
 | 
						|
            if ( where.h < lmp->vir_left - XI_AUTOSCROLL_FAST
 | 
						|
                || ++autoscroll_count >= XI_AUTOSCROLL_COUNT )
 | 
						|
            {
 | 
						|
              autoscroll_count = 0;
 | 
						|
              rubber_rect( lmp );
 | 
						|
              lm_hscroll( ( LM ) lmp, -1, 0 );
 | 
						|
              scrolled = TRUE;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
        else
 | 
						|
          autoscroll_count = 0;
 | 
						|
        if ( scrolled || where.h != lmp->last_x || where.v != lmp->last_y )
 | 
						|
        {
 | 
						|
          if ( !scrolled )
 | 
						|
            rubber_rect( lmp );
 | 
						|
          lmp->last_x = where.h;
 | 
						|
          lmp->last_y = where.v;
 | 
						|
          lmp->last_in_hscrolling = lmp->in_hscrolling;
 | 
						|
          rubber_rect( lmp );
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    case XinEventMouseUp:
 | 
						|
      {
 | 
						|
        int column;
 | 
						|
        XI_OBJ *list_obj,
 | 
						|
        **members;
 | 
						|
        int nbr_members,
 | 
						|
        col_cnt,
 | 
						|
        temp1,
 | 
						|
        temp2,
 | 
						|
        dist1,
 | 
						|
        dist2,
 | 
						|
        min_dist,
 | 
						|
        position;
 | 
						|
        XinRect rct;
 | 
						|
        XinPoint where;
 | 
						|
 | 
						|
        where = ep->v.mouse.where;
 | 
						|
        rubber_rect( lmp );
 | 
						|
        column = lmp->column_being_moved;
 | 
						|
        list_obj = lmp->list_obj;
 | 
						|
        if ( list_obj )
 | 
						|
          get_rubber_rect( lmp, &rct, where.h, where.v, lmp->in_hscrolling );
 | 
						|
        if ( lmp->drop_and_delete &&
 | 
						|
            ( rct.bottom < ( lmp->pix_top - 8 ) ||
 | 
						|
              rct.top > ( lmp->pix_row1_top + 8 ) ) )
 | 
						|
        {
 | 
						|
          /* If the focus is in the column to be deleted, we will move focus as if
 | 
						|
            the tab key had been pressed before deleting the col.  This is so the
 | 
						|
            Bridge doesn't try to reference a deleted column object in the
 | 
						|
            OFF_CELL event. */
 | 
						|
          XI_OBJ *old_focus;
 | 
						|
          BOOLEAN deleteable = TRUE;
 | 
						|
          BOOLEAN return_focus = FALSE;
 | 
						|
 | 
						|
          old_focus = lmp->itf_obj->v.itf->focus_obj;
 | 
						|
          if (old_focus->type == XIT_CELL && old_focus->parent == lmp->list_obj
 | 
						|
              && old_focus->v.cell.column == column)
 | 
						|
          {
 | 
						|
            if (adjust_focus_for_column_delete( lmp, column, FALSE ))
 | 
						|
              return_focus = TRUE;
 | 
						|
            else
 | 
						|
              deleteable = FALSE;
 | 
						|
          }
 | 
						|
          if (deleteable && do_lm_cb_column( ( long ) lmp, LM_CB_COL_DELETE, column,
 | 
						|
                                0, 0, 0, FALSE ) == FALSE )
 | 
						|
          {
 | 
						|
            members = xi_get_member_list( list_obj, &nbr_members );
 | 
						|
            xi_delete( members[column] );
 | 
						|
            lm_set_hscroll_range( ( LM ) lmp );
 | 
						|
            lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
          } else if (return_focus)
 | 
						|
            xi_move_focus( old_focus );
 | 
						|
        }
 | 
						|
        if ( where.v > lmp->pix_top && where.v < lmp->pix_row1_top &&
 | 
						|
            where.h >= lmp->rct.left )
 | 
						|
        {
 | 
						|
          BOOLEAN in_hscrolling,
 | 
						|
          old_in_hscrolling;
 | 
						|
 | 
						|
          /* determine where to move the column, if anywhere */
 | 
						|
          in_hscrolling = FALSE;
 | 
						|
          old_in_hscrolling = ( column >= lmp->fixed_columns );
 | 
						|
          min_dist = INT_MAX;
 | 
						|
          position = 0;
 | 
						|
          for ( col_cnt = 0; col_cnt < lmp->nbr_columns; col_cnt++ )
 | 
						|
          {
 | 
						|
            LM_COLUMN_DATA *column_data;
 | 
						|
 | 
						|
            if ( col_cnt >= lmp->fixed_columns &&
 | 
						|
                col_cnt < lmp->first_vis )
 | 
						|
              continue;
 | 
						|
            column_data = lmp->lm_column_data[col_cnt];
 | 
						|
            temp1 = column_data->x_pix_pos;
 | 
						|
            temp2 = temp1 + 2 * col_offset + column_data->pix_width;
 | 
						|
            dist1 = abs( temp1 - where.h );
 | 
						|
            dist2 = abs( temp2 - where.h );
 | 
						|
            if ( dist1 < min_dist )
 | 
						|
            {
 | 
						|
              position = col_cnt;
 | 
						|
              min_dist = dist1;
 | 
						|
            }
 | 
						|
            if ( dist2 < min_dist )
 | 
						|
            {
 | 
						|
              position = col_cnt + 1;
 | 
						|
              min_dist = dist2;
 | 
						|
            }
 | 
						|
            if ( col_cnt == lmp->fixed_columns )
 | 
						|
            {
 | 
						|
              if ( where.h < column_data->x_pix_pos )
 | 
						|
                in_hscrolling = FALSE;
 | 
						|
              else
 | 
						|
                in_hscrolling = TRUE;
 | 
						|
            }
 | 
						|
          }
 | 
						|
 | 
						|
          /* if we need to move the column, then move it */
 | 
						|
          if ( position < column || position > column + 1 ||
 | 
						|
              position == lmp->fixed_columns )
 | 
						|
          {
 | 
						|
            if ( column == position && position == lmp->fixed_columns &&
 | 
						|
                in_hscrolling && ( !old_in_hscrolling ) )
 | 
						|
              position -= 1;
 | 
						|
            else if ( position > column )
 | 
						|
              position -= 1;
 | 
						|
 | 
						|
            /* if there is only one fixed column left, then don't move it */
 | 
						|
            if ( column != 0 || lmp->fixed_columns != 1 )
 | 
						|
            {
 | 
						|
              int widest_remaining,
 | 
						|
              col_width,
 | 
						|
              width_remaining,
 | 
						|
              new_fixed_width,
 | 
						|
              cnt;
 | 
						|
              BOOLEAN do_move = TRUE;
 | 
						|
              LM_COLUMN_DATA *column_data,
 | 
						|
              *cell_data2;
 | 
						|
              XinRect r;
 | 
						|
 | 
						|
              if ( lmp->fixed_columns < lmp->nbr_columns )
 | 
						|
              {
 | 
						|
                /* if there is not room in the horizontal scrolling portion of
 | 
						|
                * the list for the widest column remaining in the horizontal
 | 
						|
                * scrolling portion of the list, then don't move the column */
 | 
						|
                widest_remaining = 0;
 | 
						|
                for ( cnt = lmp->fixed_columns; cnt < lmp->nbr_columns;
 | 
						|
                      ++cnt )
 | 
						|
                {
 | 
						|
                  if ( cnt == column )
 | 
						|
                    continue;
 | 
						|
                  column_data = lmp->lm_column_data[cnt];
 | 
						|
                  col_width = column_data->pix_width + 2 * col_offset;
 | 
						|
                  if ( col_width > widest_remaining )
 | 
						|
                    widest_remaining = col_width;
 | 
						|
                }
 | 
						|
                column_data = lmp->lm_column_data[lmp->fixed_columns];
 | 
						|
                cell_data2 = lmp->lm_column_data[column];
 | 
						|
                new_fixed_width = column_data->x_pix_pos;
 | 
						|
                if ( position < lmp->fixed_columns || !in_hscrolling )
 | 
						|
                  new_fixed_width += cell_data2->pix_width + 2 * col_offset;
 | 
						|
                if ( column < lmp->fixed_columns )
 | 
						|
                  new_fixed_width -= cell_data2->pix_width + 2 * col_offset;
 | 
						|
                lm_get_list_rct( lmp, &r );
 | 
						|
                width_remaining = r.right - r.left - new_fixed_width;
 | 
						|
                if ( widest_remaining > width_remaining )
 | 
						|
                  do_move = FALSE;
 | 
						|
              }
 | 
						|
 | 
						|
              if ( do_move )
 | 
						|
              {
 | 
						|
                BOOLEAN in_fixed = !in_hscrolling;
 | 
						|
 | 
						|
                if ( position > lmp->fixed_columns )
 | 
						|
                  in_fixed = FALSE;
 | 
						|
                if ( do_lm_cb_column( ( long ) lmp, LM_CB_COL_MOVE, column,
 | 
						|
                                      position, 0, 0, in_fixed ) == FALSE )
 | 
						|
                {
 | 
						|
                  members = xi_get_member_list( list_obj, &nbr_members );
 | 
						|
                  xi_move_column_internal( members[column], position,
 | 
						|
                                          in_hscrolling );
 | 
						|
                  lm_calc_last_vis( lmp );
 | 
						|
                  lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
                }
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
        lm_focus_cell_visible_attempt( lmp );
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_drag_rect
 | 
						|
lmp:        current lmp
 | 
						|
prct:       returns rectangle where row or "after-all" events will be
 | 
						|
            generated
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
#define DROP_AFTER_MARGIN 10
 | 
						|
 | 
						|
static void
 | 
						|
lm_get_drag_rect( LM_DATA * lmp, XinRect * prct )
 | 
						|
{
 | 
						|
  lm_get_rect( ( LM ) lmp, LM_LIST, 0, prct );
 | 
						|
  if ( lmp->nbr_rows == 0 || ( lmp->have_last_rec
 | 
						|
                        && lmp->recs[lmp->last_fully_vis] == lmp->last_rec ) )
 | 
						|
  {
 | 
						|
    if ( lmp->pixel_width != 0 )
 | 
						|
    {
 | 
						|
      XinRect hsb_rct;
 | 
						|
 | 
						|
      xi_get_hsb_rect( lmp->list_obj, &hsb_rct );
 | 
						|
      prct->bottom = hsb_rct.bottom;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      prct->bottom += DROP_AFTER_MARGIN;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_get_no_event_rect
 | 
						|
lmp:        current lmp
 | 
						|
prct:       returns rectangle where no drag event will be generated
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
lm_get_no_event_rect( LM_DATA * lmp, XinRect * prct )
 | 
						|
{
 | 
						|
  lm_get_rect( ( LM ) lmp, LM_LIST, 0, prct );
 | 
						|
  if ( lmp->list_obj->v.list->sb_win )
 | 
						|
  {
 | 
						|
    XinRect rct;
 | 
						|
 | 
						|
    xi_get_sb_rect( lmp->list_obj, &rct );
 | 
						|
    prct->right = rct.right;
 | 
						|
  }
 | 
						|
  if ( lmp->pixel_width != 0 && ( !lmp->have_last_rec
 | 
						|
                        || lmp->recs[lmp->last_fully_vis] != lmp->last_rec ) )
 | 
						|
  {
 | 
						|
    XinRect rct;
 | 
						|
 | 
						|
    xi_get_hsb_rect( lmp->list_obj, &rct );
 | 
						|
    prct->bottom = rct.bottom;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_check_interface
 | 
						|
itf:        current interface
 | 
						|
where:      current mouse position, will be translated if new interface
 | 
						|
            is returned
 | 
						|
returns:    new interface, or NULL if no change
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static XI_OBJ *
 | 
						|
lm_check_interface( XI_OBJ * itf, XinPoint * where )
 | 
						|
{
 | 
						|
  XinRect rct;
 | 
						|
  XinWindow win;
 | 
						|
 | 
						|
  win = xi_get_window( itf );
 | 
						|
  XinWindowRectGet( win, &rct );
 | 
						|
  if ( !XinRectPointContained( &rct, where ) )
 | 
						|
  {
 | 
						|
    XinRect temp;
 | 
						|
    XinPoint pt;
 | 
						|
    XI_OBJ *new_itf;
 | 
						|
 | 
						|
    temp.top = temp.bottom = where->v;
 | 
						|
    temp.left = temp.right = where->h;
 | 
						|
    XinWindowRectTranslate( win, XinWindowTaskGet(  ), &temp );
 | 
						|
    pt.v = temp.top;
 | 
						|
    pt.h = temp.left;
 | 
						|
    new_itf = xi_get_itf_containing( &pt );
 | 
						|
    if ( new_itf == itf )
 | 
						|
      itf = NULL;
 | 
						|
    else
 | 
						|
      itf = new_itf;
 | 
						|
    if ( itf != NULL )
 | 
						|
    {
 | 
						|
      win = xi_get_window( itf );
 | 
						|
      XinWindowRectTranslate( XinWindowTaskGet(  ), win, &temp );
 | 
						|
      where->v = temp.top;
 | 
						|
      where->h = temp.left;
 | 
						|
      XinWindowMouseRelease(  );
 | 
						|
      XinWindowFrontSet( win );
 | 
						|
      XinWindowPaintForce( win );
 | 
						|
      XinWindowMouseTrap( win, TRUE );
 | 
						|
    }
 | 
						|
    return itf;
 | 
						|
  }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_drag_row_hit_test
 | 
						|
lmp:        current lmp
 | 
						|
itf:        current interface
 | 
						|
where:      current mouse position, will be translated if new interface
 | 
						|
            is returned
 | 
						|
returns:    new interface, or NULL if no change
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static BOOLEAN
 | 
						|
lm_drag_row_hit_test( LM_DATA * lmp, XinPoint * where, int *rowp )
 | 
						|
{
 | 
						|
  int tmp_v,
 | 
						|
  i,
 | 
						|
  first,
 | 
						|
  last;
 | 
						|
  int *pix_offsetsp;
 | 
						|
  int *pix_heightsp;
 | 
						|
 | 
						|
  /* figure out what row the mouse is in */
 | 
						|
  tmp_v = where->v - lmp->mlr.top - lmp->rrr_offset;
 | 
						|
  first = max( lmp->first_fully_vis - 1, 0 );
 | 
						|
  last = min( lmp->last_fully_vis + 1, lmp->nbr_realized_rows - 1 );
 | 
						|
  for ( i = first,
 | 
						|
        pix_offsetsp = &lmp->pix_offsets[i],
 | 
						|
        pix_heightsp = &lmp->pix_heights[i];
 | 
						|
        i <= last; ++i, ++pix_offsetsp, ++pix_heightsp )
 | 
						|
  {
 | 
						|
    if ( tmp_v >= *pix_offsetsp && tmp_v < ( *pix_offsetsp + *pix_heightsp ) )
 | 
						|
    {
 | 
						|
      *rowp = i;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ( i <= last );
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_drag_row_event
 | 
						|
itf:        interface where event actually occured
 | 
						|
lmp:        current lmp
 | 
						|
ep:         xin event
 | 
						|
oevp:       orginal xin event
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_drag_row_event( XI_OBJ * itf, LM_DATA * lmp, XinEvent * ep, XinEvent * oevp )
 | 
						|
{
 | 
						|
  XinPoint where;
 | 
						|
 | 
						|
  where = oevp->v.mouse.where;
 | 
						|
  switch ( ep->type )
 | 
						|
  {
 | 
						|
    case XinEventMouseMove:
 | 
						|
      {
 | 
						|
        static int autoscroll_count = 0;
 | 
						|
        BOOLEAN scrolled = FALSE;
 | 
						|
        XI_OBJ *new_itf;
 | 
						|
 | 
						|
        if ( !lmp->dragging_row )
 | 
						|
        {
 | 
						|
          lmp->dragging_row = TRUE;
 | 
						|
          lmp->last_itf = itf;
 | 
						|
          lmp->last_x = where.h;
 | 
						|
          lmp->org_x = lmp->last_x;
 | 
						|
          lmp->last_y = where.v;
 | 
						|
          lmp->org_y = lmp->last_y;
 | 
						|
          lmp->last_in_hscrolling = lmp->in_hscrolling;
 | 
						|
          xi_set_drag_list_obj( lmp->list_obj );
 | 
						|
          rubber_rect( lmp );
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        new_itf = lm_check_interface( itf, &where );
 | 
						|
 | 
						|
        if ( new_itf == NULL && lmp->itf_obj == itf && lmp->drag_rows_autoscroll )
 | 
						|
        {                       /* Test for autoscroll */
 | 
						|
          XinRect list_rct;
 | 
						|
 | 
						|
          lm_get_rect( ( LM ) lmp, LM_LIST, 0, &list_rct );
 | 
						|
          list_rct.top = lmp->pix_row1_top;
 | 
						|
          if ( where.v > list_rct.bottom )
 | 
						|
          {
 | 
						|
            if ( where.v > list_rct.bottom + XI_AUTOSCROLL_FAST
 | 
						|
                || ++autoscroll_count >= XI_AUTOSCROLL_COUNT )
 | 
						|
            {
 | 
						|
              LM_SCROLL_ARG arg;
 | 
						|
 | 
						|
              autoscroll_count = 0;
 | 
						|
              rubber_rect( lmp );
 | 
						|
              MEMCLEAR( arg );
 | 
						|
              arg.lm = ( LM ) lmp;
 | 
						|
              arg.nbr_lines = 1;
 | 
						|
              arg.percent = 0;
 | 
						|
              arg.same_cell = TRUE;
 | 
						|
              arg.rec_at_top = TRUE;
 | 
						|
              lm_scroll( &arg );
 | 
						|
              scrolled = TRUE;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else if ( where.v < list_rct.top )
 | 
						|
          {
 | 
						|
            if ( where.v < list_rct.top - XI_AUTOSCROLL_FAST
 | 
						|
                || ++autoscroll_count >= XI_AUTOSCROLL_COUNT )
 | 
						|
            {
 | 
						|
              LM_SCROLL_ARG arg;
 | 
						|
 | 
						|
              autoscroll_count = 0;
 | 
						|
              rubber_rect( lmp );
 | 
						|
              MEMCLEAR( arg );
 | 
						|
              arg.lm = ( LM ) lmp;
 | 
						|
              arg.nbr_lines = -1;
 | 
						|
              arg.percent = 0;
 | 
						|
              arg.same_cell = TRUE;
 | 
						|
              arg.rec_at_top = TRUE;
 | 
						|
              lm_scroll( &arg );
 | 
						|
              scrolled = TRUE;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else
 | 
						|
            autoscroll_count = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( scrolled || where.h != lmp->last_x || where.v != lmp->last_y )
 | 
						|
        {
 | 
						|
          if ( !scrolled )
 | 
						|
            rubber_rect( lmp );
 | 
						|
          if ( new_itf != NULL )
 | 
						|
            lmp->last_itf = new_itf;
 | 
						|
          lmp->last_x = where.h;
 | 
						|
          lmp->last_y = where.v;
 | 
						|
          lmp->last_in_hscrolling = lmp->in_hscrolling;
 | 
						|
          rubber_rect( lmp );
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    case XinEventMouseUp:
 | 
						|
      {
 | 
						|
        int obj_num;
 | 
						|
        XI_OBJ **objlist;
 | 
						|
        XI_OBJ *dest_list;
 | 
						|
        LM_DATA *dest_lmp;
 | 
						|
 | 
						|
        rubber_rect( lmp );
 | 
						|
        lmp->last_itf = NULL;
 | 
						|
        lmp->dragging_row = FALSE;
 | 
						|
        xi_set_drag_list_obj( NULL );
 | 
						|
 | 
						|
        /* Check to see if window changed */
 | 
						|
        {
 | 
						|
          XI_OBJ *new_itf;
 | 
						|
 | 
						|
          new_itf = lm_check_interface( itf, &where );
 | 
						|
          if ( new_itf != NULL )
 | 
						|
            itf = new_itf;
 | 
						|
        }
 | 
						|
 | 
						|
        /* Find list object in current position */
 | 
						|
        dest_list = lmp->list_obj;
 | 
						|
        objlist = xi_get_member_list( itf, &obj_num );
 | 
						|
        for ( ; obj_num > 0; obj_num--, objlist++ )
 | 
						|
          if ( ( *objlist )->type == XIT_LIST )
 | 
						|
          {
 | 
						|
            XinRect rct;
 | 
						|
 | 
						|
            lm_get_drag_rect( ( LM_DATA * ) ( *objlist )->v.list->lm, &rct );
 | 
						|
            if ( XinRectPointContained( &rct, &where ) )
 | 
						|
            {
 | 
						|
              dest_list = *objlist;
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        dest_lmp = ( LM_DATA * ) dest_list->v.list->lm;
 | 
						|
 | 
						|
        /* Match coordinates to window */
 | 
						|
        if ( dest_lmp->itf_obj != itf )
 | 
						|
        {
 | 
						|
          XinRect temp;
 | 
						|
 | 
						|
          temp.top = temp.bottom = where.v;
 | 
						|
          temp.left = temp.right = where.h;
 | 
						|
          XinWindowRectTranslate( xi_get_window( itf ), xi_get_window( lmp->itf_obj ), &temp );
 | 
						|
          where.v = temp.top;
 | 
						|
          where.h = temp.left;
 | 
						|
        }
 | 
						|
 | 
						|
        {                       /* Generate drop rows event */
 | 
						|
          int row;
 | 
						|
          int column = 0;
 | 
						|
          LM_CB_DATA lm_cb_data;
 | 
						|
          XinRect list_rct;
 | 
						|
 | 
						|
          lm_cb_data.v.drop_row.src_rec = lmp->rec_being_moved;
 | 
						|
          lm_cb_data.v.drop_row.after_all_rows = FALSE;
 | 
						|
          lm_cb_data.v.drop_row.delete_row = FALSE;
 | 
						|
          lm_cb_data.rec = 0;
 | 
						|
          lm_get_drag_rect( dest_lmp, &list_rct );
 | 
						|
          if ( !XinRectPointContained( &list_rct, &where ) )
 | 
						|
          {
 | 
						|
            lm_get_no_event_rect( dest_lmp, &list_rct );
 | 
						|
            if ( XinRectPointContained( &list_rct, &where ) )
 | 
						|
              break;
 | 
						|
            row = column = 0;
 | 
						|
            lm_cb_data.v.drop_row.delete_row = TRUE;
 | 
						|
          }
 | 
						|
          else
 | 
						|
          {
 | 
						|
            if ( where.v < dest_lmp->pix_row1_top )
 | 
						|
              break;
 | 
						|
            if ( lm_drag_row_hit_test( dest_lmp, &where, &row ) )
 | 
						|
              lm_cb_data.rec = dest_lmp->recs[row];
 | 
						|
            else
 | 
						|
              lm_cb_data.v.drop_row.after_all_rows = TRUE;
 | 
						|
          }
 | 
						|
          lm_cb_data.lm = ( LM ) dest_lmp;
 | 
						|
          lm_cb_data.cb_type = LM_CB_DROP_ROW;
 | 
						|
          lm_cb_data.cid = lmp->cid;
 | 
						|
          lm_cb_data.win = lmp->win;
 | 
						|
          lm_cb_data.row = ( unsigned char ) row;
 | 
						|
          lm_cb_data.column = ( unsigned char ) column;
 | 
						|
          lm_cb_data.v.drop_row.shift = ep->v.mouse.shift;
 | 
						|
          lm_cb_data.v.drop_row.control = ep->v.mouse.control;
 | 
						|
          lm_cb_data.v.drop_row.src_list = lmp->list_obj;
 | 
						|
          ( *lmp->lm_cb ) ( &lm_cb_data );
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   calc_x
 | 
						|
lmp:        current lmp
 | 
						|
ep:         xvt event
 | 
						|
returns:    Calculates and returns the X pixel position of the rubber band line.
 | 
						|
      Used only when sizing columns.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static int
 | 
						|
calc_x( LM_DATA * lmp, XinEvent * ep )
 | 
						|
{
 | 
						|
  int column = lmp->column_being_sized;
 | 
						|
  int temp,
 | 
						|
  temp2,
 | 
						|
  widest_remaining;
 | 
						|
  int min_width_in_pix = 16;
 | 
						|
  int col_offset;
 | 
						|
 | 
						|
  col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | 
						|
 | 
						|
  /* temp is the min width position of the column, relative to the left edge of
 | 
						|
  * the list. */
 | 
						|
  temp = lmp->lm_column_data[column]->x_pix_pos + col_offset +
 | 
						|
          min_width_in_pix;
 | 
						|
  if ( lmp->lm_column_data[column]->wrap_text_scrollbar )
 | 
						|
    temp += (int)XinMetricGet( XinMetricVerticalScrollBarWidth );
 | 
						|
  temp = max( ep->v.mouse.where.h, temp );
 | 
						|
  widest_remaining = 0;
 | 
						|
  if ( lmp->pixel_width )
 | 
						|
  {
 | 
						|
    int col_offset,
 | 
						|
    col_width,
 | 
						|
    cnt;
 | 
						|
    LM_COLUMN_DATA *column_data;
 | 
						|
 | 
						|
    col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | 
						|
    if ( column < lmp->fixed_columns )
 | 
						|
    {
 | 
						|
      /* figure out the widest column in the horizontal scrolling portion of
 | 
						|
      * the list */
 | 
						|
      for ( cnt = lmp->fixed_columns; cnt < lmp->nbr_columns; ++cnt )
 | 
						|
      {
 | 
						|
        column_data = lmp->lm_column_data[cnt];
 | 
						|
        col_width = column_data->pix_width + 2 * col_offset;
 | 
						|
        if ( col_width > widest_remaining )
 | 
						|
          widest_remaining = col_width;
 | 
						|
      }
 | 
						|
      /* add the widths of all of the columns to the right of this column in
 | 
						|
      * the fixed portion of the list */
 | 
						|
      temp2 = 0;
 | 
						|
      for ( cnt = column + 1; cnt < lmp->fixed_columns; ++cnt )
 | 
						|
      {
 | 
						|
        column_data = lmp->lm_column_data[cnt];
 | 
						|
        col_width = column_data->pix_width + 2 * col_offset;
 | 
						|
        temp2 += col_width;
 | 
						|
      }
 | 
						|
      temp = min( ( lmp->pixel_width - widest_remaining - temp2 ) - BORDER_WIDTH,
 | 
						|
                  temp );
 | 
						|
    }
 | 
						|
    else
 | 
						|
      temp = min( ( lmp->pixel_width + lmp->delta_x ) - BORDER_WIDTH, temp );
 | 
						|
  }
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   rubber_x
 | 
						|
lmp:        current lmp
 | 
						|
x:          draw a rubber line at position x
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
rubber_x( LM_DATA * lmp, int x )
 | 
						|
{
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  int top,
 | 
						|
  bottom;
 | 
						|
  XinDrawTools new_ctools;
 | 
						|
  XinPoint pnt;
 | 
						|
  XinWindow win = lmp->win;
 | 
						|
 | 
						|
  top = lmp->pix_top;
 | 
						|
  bottom = lmp->mlr.bottom;
 | 
						|
  XinWindowDrawToolsNormalGet( &new_ctools );
 | 
						|
  XinWindowDrawToolsSet( win, &new_ctools );
 | 
						|
  XinWindowPenSet( win, &rubber_cpen );
 | 
						|
  XinWindowDrawModeSet( win, XinDrawModeXor );
 | 
						|
  xi_set_clip( win, NULL );
 | 
						|
  pnt.h = x;
 | 
						|
  pnt.v = top;
 | 
						|
  if ( !lmp->down_in_hscrolling )
 | 
						|
    pnt.h += lmp->rct.left;
 | 
						|
  lm_move_to( lmp, pnt, FALSE, lmp->down_in_hscrolling );
 | 
						|
  pnt.v = bottom;
 | 
						|
  lm_draw_line( lmp, pnt, FALSE, lmp->down_in_hscrolling );
 | 
						|
#else
 | 
						|
  NOREF( lmp );
 | 
						|
  NOREF( x );
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_size_event
 | 
						|
lmp:        current lmp
 | 
						|
ep:         xvt event
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_size_event( LM_DATA * lmp, XinEvent * ep )
 | 
						|
{
 | 
						|
  int x;
 | 
						|
 | 
						|
  switch ( ep->type )
 | 
						|
  {
 | 
						|
    case XinEventMouseDown:
 | 
						|
    case XinEventMouseDouble:
 | 
						|
      x = calc_x( lmp, ep );
 | 
						|
      lmp->last_x = x;
 | 
						|
      rubber_x( lmp, x );
 | 
						|
      break;
 | 
						|
    case XinEventMouseMove:
 | 
						|
      x = calc_x( lmp, ep );
 | 
						|
      rubber_x( lmp, lmp->last_x );
 | 
						|
      lmp->last_x = x;
 | 
						|
      rubber_x( lmp, x );
 | 
						|
      break;
 | 
						|
    case XinEventMouseUp:
 | 
						|
      {
 | 
						|
        int col_offset;
 | 
						|
        int column;
 | 
						|
        int temp;
 | 
						|
        int width_in_chars;
 | 
						|
        int pixel_width;
 | 
						|
        XI_OBJ *list_obj,
 | 
						|
        **members;
 | 
						|
        int nbr_members;
 | 
						|
        int char_width;
 | 
						|
        LM_COLUMN_DATA *lm_column_data;
 | 
						|
 | 
						|
        col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | 
						|
        x = calc_x( lmp, ep );
 | 
						|
        rubber_x( lmp, lmp->last_x );
 | 
						|
        column = lmp->column_being_sized;
 | 
						|
        lm_column_data = lmp->lm_column_data[column];
 | 
						|
        temp = lm_column_data->x_pix_pos + col_offset;
 | 
						|
        pixel_width = ( x - temp ) - col_offset;
 | 
						|
        width_in_chars = ( int ) ( pixel_width / ( long ) xi_get_fu_width( lmp->itf_obj ) );
 | 
						|
        list_obj = lmp->list_obj;
 | 
						|
 | 
						|
        char_width = width_in_chars * XI_FU_MULTIPLE;
 | 
						|
        if ( xi_get_xil_pref( list_obj->itf ) )
 | 
						|
          char_width = width_in_chars;
 | 
						|
 | 
						|
        if ( do_lm_cb_column( ( long ) lmp, LM_CB_COL_SIZE, column,
 | 
						|
                              0, char_width, pixel_width, FALSE ) == FALSE )
 | 
						|
        {
 | 
						|
          int i;
 | 
						|
 | 
						|
          members = xi_get_member_list( list_obj, &nbr_members );
 | 
						|
          xi_column_set_pixel_width( members[column], pixel_width );
 | 
						|
          i = lm_get_left_most_far_right_col( lmp, lmp->nbr_columns );
 | 
						|
          if ( i < lmp->first_vis )
 | 
						|
          {
 | 
						|
            XinWindowPaintForce( lmp->win );
 | 
						|
            lm_hscroll( ( LM ) lmp, lmp->first_vis - i, 0 );
 | 
						|
          }
 | 
						|
          else
 | 
						|
          {
 | 
						|
            lm_calc_last_vis( lmp );
 | 
						|
            lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
          }
 | 
						|
        }
 | 
						|
        lm_focus_cell_visible_attempt( lmp );
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_bitmap
 | 
						|
lm:         current lm
 | 
						|
bitmap:     bitmap object
 | 
						|
row:
 | 
						|
column:
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_bitmap( LM lm, XI_BITMAP* bitmap, int row, int column )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  lmp->cell_data[row][column].bitmap = xi_bitmap_copy( bitmap );
 | 
						|
  if ( LMP( lm )->attrib & XI_ATR_VISIBLE )
 | 
						|
    redraw_cell( lm, row, column, FALSE );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_icon
 | 
						|
lm:         current lm
 | 
						|
icon_rid:   icon resource id
 | 
						|
row:
 | 
						|
column:
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_icon( LM lm, int icon_rid, int row, int column )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  lmp->cell_data[row][column].icon_rid = icon_rid;
 | 
						|
  if ( LMP( lm )->attrib & XI_ATR_VISIBLE )
 | 
						|
    redraw_cell( lm, row, column, FALSE );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_column_bitmap
 | 
						|
lm:         current lm
 | 
						|
bitmap:     bitmap object
 | 
						|
cid:        cid of the column to set
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_column_bitmap( LM lm, XI_BITMAP* bitmap, int cid )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  XI_OBJ *list = lmp->list_obj;
 | 
						|
  int column;
 | 
						|
 | 
						|
  for ( column = 0; column < list->nbr_children; column++ )
 | 
						|
  {
 | 
						|
    if ( list->children[column]->cid == cid )
 | 
						|
    {
 | 
						|
      XinRect rect;
 | 
						|
 | 
						|
      lmp->lm_column_data[column]->bitmap = xi_bitmap_copy( bitmap );
 | 
						|
      lm_get_rect( lm, LM_COLUMN, column, &rect );
 | 
						|
      xi_invalidate_rect( lmp->win, &rect );
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_column_icon
 | 
						|
lm:         current lm
 | 
						|
icon_rid:   icon resource id
 | 
						|
cid:        cid of the column to set
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_column_icon( LM lm, int icon_rid, int cid )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  XI_OBJ *list = lmp->list_obj;
 | 
						|
  int column;
 | 
						|
 | 
						|
  for ( column = 0; column < list->nbr_children; column++ )
 | 
						|
  {
 | 
						|
    if ( list->children[column]->cid == cid )
 | 
						|
    {
 | 
						|
      XinRect rect;
 | 
						|
 | 
						|
      lmp->lm_column_data[column]->icon_rid = icon_rid;
 | 
						|
      lm_get_rect( lm, LM_COLUMN, column, &rect );
 | 
						|
      xi_invalidate_rect( lmp->win, &rect );
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   lm_set_sel
 | 
						|
lm:         current lm
 | 
						|
row:        row
 | 
						|
column:     column
 | 
						|
c1:         starting position in selection
 | 
						|
c2:         ending position
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_set_sel( LM lm, int row, int column, BOOLEAN v_scrolled, int c1, int c2 )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  if ( !lm_focus_list_has( lmp ) )
 | 
						|
  {
 | 
						|
    lm_focus_cell_set( lmp, row, column, FALSE );
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    int focus_row,
 | 
						|
    focus_column;
 | 
						|
    BOOLEAN is_v_scrolled;
 | 
						|
 | 
						|
    lm_focus_cell_get( lmp, &focus_row, &focus_column, &is_v_scrolled );
 | 
						|
    if ( focus_row != row || focus_column != column || v_scrolled != is_v_scrolled )
 | 
						|
      lm_focus_cell_set( lmp, row, column, FALSE );
 | 
						|
  }
 | 
						|
  if ( v_scrolled )
 | 
						|
  {
 | 
						|
    lm_focus_cell_selection_set( lmp, c1, c2 );
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    XI_TEXT *text;
 | 
						|
 | 
						|
    text = xi_text_focus_get( lmp->win );
 | 
						|
    if ( text )
 | 
						|
      xi_text_selection_set( text, c1, c2 );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:   scroll_list
 | 
						|
lmp:        current lmp
 | 
						|
left_col:
 | 
						|
right_col:
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
static void
 | 
						|
scroll_list( LM_DATA * lmp, int new_first_col )
 | 
						|
{
 | 
						|
  XinRect r;
 | 
						|
  int new_pos;
 | 
						|
  int dist;
 | 
						|
 | 
						|
  new_pos = lmp->lm_column_data[new_first_col]->x_pix_pos
 | 
						|
          - lmp->lm_column_data[lmp->fixed_columns]->x_pix_pos;
 | 
						|
  if ( new_pos == lmp->delta_x )
 | 
						|
  {
 | 
						|
    if ( lmp->nbr_columns == lmp->fixed_columns )
 | 
						|
      lmp->delta_x = 0;
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  dist = new_pos - lmp->delta_x;
 | 
						|
  lmp->delta_x += dist;
 | 
						|
  r.left = lmp->vir_left;
 | 
						|
  r.right = lmp->vir_right;
 | 
						|
#if XIWS != XIWS_WM
 | 
						|
  r.top = lmp->rct.top + BORDER_WIDTH;
 | 
						|
  r.bottom = lmp->rct.bottom - BORDER_WIDTH;
 | 
						|
#else
 | 
						|
  r.top = lmp->rct.top;
 | 
						|
  r.bottom = lmp->rct.bottom;
 | 
						|
#endif
 | 
						|
  if ( !lmp->itf_obj->v.itf->half_baked )
 | 
						|
    XinWindowPaintForce( lmp->win );
 | 
						|
  xi_set_update_obj( lmp->list_obj );
 | 
						|
  lmp->last_vis = lmp->first_vis;
 | 
						|
  lm_calc_last_vis( lmp );
 | 
						|
  xi_scroll_rect( lmp->win, &r, -dist, 0 );
 | 
						|
 | 
						|
  if ( !lmp->itf_obj->v.itf->half_baked )
 | 
						|
    XinWindowPaintForce( lmp->win );
 | 
						|
  lm_set_hscroll_bar( ( LM ) lmp );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------
 | 
						|
function:       lm_hscroll
 | 
						|
lm:             current lm
 | 
						|
nbr_columns:    number of columns to scroll
 | 
						|
pos:            if set, pos is a percentage based on where the thumb was dropped.
 | 
						|
-------------------------------------------------------------------------*/
 | 
						|
void
 | 
						|
lm_hscroll( LM lm, int nbr_columns, int pos )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  int last_vis,
 | 
						|
  lmfrc,
 | 
						|
  starting_column;
 | 
						|
 | 
						|
  XinWindowPaintForce( lmp->win );
 | 
						|
  if ( lmp->nbr_columns == 0 )
 | 
						|
    return;
 | 
						|
  lmfrc = lm_get_left_most_far_right_col( LMP( lm ), lmp->nbr_columns );
 | 
						|
  last_vis = min( lmp->last_vis, lmp->nbr_columns - 1 );
 | 
						|
  if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | 
						|
    lm_focus_cell_invis_make( lmp );
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if ( !lmp->itf_obj->v.itf->moving_focus )
 | 
						|
      if ( !xi_move_focus( lmp->itf_obj ) )
 | 
						|
        return;
 | 
						|
  }
 | 
						|
  if ( nbr_columns == XI_SCROLL_FIRST )
 | 
						|
  {
 | 
						|
    starting_column = lmfrc;
 | 
						|
    if ( starting_column )
 | 
						|
    {
 | 
						|
      starting_column = starting_column - lmp->fixed_columns;
 | 
						|
      starting_column = ( int ) ( ( ( long ) pos * ( long ) starting_column ) /
 | 
						|
                                  ( long ) 100 );
 | 
						|
    }
 | 
						|
    starting_column += lmp->fixed_columns;
 | 
						|
    lmp->first_vis = starting_column;
 | 
						|
    lmp->first_vis = min( lmp->first_vis, lmp->nbr_columns - 1 );
 | 
						|
    scroll_list( lmp, lmp->first_vis );
 | 
						|
    lm_focus_cell_visible_attempt( lmp );
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if ( nbr_columns == XI_SCROLL_PGDOWN )
 | 
						|
  {
 | 
						|
    starting_column = min( last_vis + 1, lmfrc );
 | 
						|
    starting_column = min( starting_column, lmp->nbr_columns - 1 );
 | 
						|
    lmp->first_vis = starting_column;
 | 
						|
    lmp->first_vis = min( lmp->first_vis, lmp->nbr_columns - 1 );
 | 
						|
    scroll_list( lmp, lmp->first_vis );
 | 
						|
    lm_focus_cell_visible_attempt( lmp );
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if ( nbr_columns == XI_SCROLL_PGUP )
 | 
						|
  {
 | 
						|
    starting_column = lm_get_left_most_far_right_col( lmp, lmp->first_vis );
 | 
						|
    starting_column = min( starting_column, lmp->nbr_columns - 1 );
 | 
						|
    lmp->first_vis = starting_column;
 | 
						|
    lmp->first_vis = min( lmp->first_vis, lmp->nbr_columns - 1 );
 | 
						|
    scroll_list( lmp, lmp->first_vis );
 | 
						|
    lm_focus_cell_visible_attempt( lmp );
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  lmp->first_vis += nbr_columns;
 | 
						|
  if ( nbr_columns > 0 )
 | 
						|
  {
 | 
						|
    lmp->first_vis = min( lmp->first_vis, lm_get_left_most_far_right_col( lmp, lmp->nbr_columns ) );
 | 
						|
    lmp->first_vis = min( lmp->first_vis, lmp->nbr_columns - 1 );
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    lmp->first_vis = max( lmp->first_vis, lmp->fixed_columns );
 | 
						|
    lmp->first_vis = min( lmp->first_vis, lmp->nbr_columns - 1 );
 | 
						|
  }
 | 
						|
  scroll_list( lmp, lmp->first_vis );
 | 
						|
  lm_focus_cell_visible_attempt( lmp );
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
lm_calculate_pix_offsets( LM lm )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
 | 
						|
  calculate_pix_offsets( lmp, TRUE );
 | 
						|
  lm_make_rrr_room_pix( lmp, 0, FALSE );
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
lm_cr_is_ok( LM lm, int row, int col, BOOLEAN v_scrolled )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  LM_COLUMN_DATA *lm_column_data;
 | 
						|
  LM_CELL_DATA *cell_data;
 | 
						|
 | 
						|
  lm_column_data = lmp->lm_column_data[col];
 | 
						|
  if ( lm_column_data->cr_ok )
 | 
						|
    return TRUE;
 | 
						|
  if ( v_scrolled )
 | 
						|
  {
 | 
						|
    if ( lm_focus_cell_is_button_full_cell( lmp ) )
 | 
						|
      return TRUE;
 | 
						|
    else
 | 
						|
      return FALSE;
 | 
						|
  }
 | 
						|
  cell_data = &lmp->cell_data[row][col];
 | 
						|
  if ( cell_data->button_full_cell )
 | 
						|
    return TRUE;
 | 
						|
  else
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
lm_is_button_full_cell( LM lm, int row, int col )
 | 
						|
{
 | 
						|
  LM_DATA *lmp = LMP( lm );
 | 
						|
  LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | 
						|
 | 
						|
  return cell_data->button_full_cell;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
lm_set_rect( LM lm, XinRect *rect )
 | 
						|
{
 | 
						|
  LM_DATA *lmp;
 | 
						|
  XinRect fu_rect;
 | 
						|
 | 
						|
  lmp = (LM_DATA*)lm;
 | 
						|
 | 
						|
  fu_rect = *rect;
 | 
						|
  fu_rect.right -= 2 * BORDER_WIDTH;
 | 
						|
  if (lmp->list_obj->v.list->hsb_win)
 | 
						|
  {
 | 
						|
    XinRect hsb_rect;
 | 
						|
    xi_get_hsb_rect( lmp->list_obj, & hsb_rect );
 | 
						|
    fu_rect.bottom += hsb_rect.bottom - hsb_rect.top;
 | 
						|
  }
 | 
						|
  xi_pu_to_fu( lmp->itf_obj, (XinPoint*)&fu_rect, 2 );
 | 
						|
  lmp->list_obj->v.list->xi_pnt = *(XinPoint*)&fu_rect;
 | 
						|
  if (lmp->list_obj->v.list->height != 0)
 | 
						|
    lmp->list_obj->v.list->height = fu_rect.bottom - fu_rect.top;
 | 
						|
  if (lmp->list_obj->v.list->width != 0 )
 | 
						|
    lmp->list_obj->v.list->width = fu_rect.right - fu_rect.left;
 | 
						|
 | 
						|
  /* TODO - lm_recalc_metrics gets the proper height for the list not including
 | 
						|
    the hsb, then puts the hsb inside that rect instead of below it.  Therefore,
 | 
						|
    the first time you resize, the list gets shorter by a scrollbar height, and
 | 
						|
    thereafter it doesn't change. */
 | 
						|
  lm_recalc_metrics( lm );
 | 
						|
 | 
						|
}
 |