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