	function keydefs_init(control,case_sensitive)
	implicit none
c
c Initialize key structure
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
c#
	record /control/ control
	logical case_sensitive		!:i: is table case_sensitive
	logical keydefs_init		!:f: the result
c
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	integer*4 istat
c
	record /keydefs_key/ key
	record /keydefs_function/ function
c
c Get some memory
c
c	control.use_mouse = cli$present('use_mouse')
	call get_vm(control,sizeof(keytable),p_keytable,
     1              control.zone_general,.false.,'KEYTABLE')
	keytable.magic = magic_keytable
	control.key_table = p_keytable
c
c Create a vm zone, for functions /keys
c
	call init_vm(control,keytable.vm_zone,0,'KEYTABLE',.false.)
c
c Setup default mappings, this alse defines all dix_function keys
c
	call dix_util_init_table(keytable.functions,sizeof(function))
	call dix_util_init_table(keytable.keys,sizeof(key))
	keytable.case_sensitive = case_sensitive
c
c Get the default keys
c
	call keydefs_default(control,keytable)
c
	keytable.cur_state = ' '
	istat = 1
	keydefs_init = istat
	return
	end
	options /exte
	subroutine keydefs_default(control,keytable)
	implicit none
c
c Setup default mapping, and also define all dix_function keys
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	record /keytable/ keytable	!:io: the keytable
	integer*4 control
c#
	include '($smgdef)'
c
c init nkey
c
c
c First define all keys
c
	call keydefs_def(keytable,'key_up'        ,key_up,control)
	call keydefs_def(keytable,'key_down'      ,key_down,control)
	call keydefs_def(keytable,'key_left'      ,key_left,control)
	call keydefs_def(keytable,'key_right'     ,key_right,control)
	call keydefs_def(keytable,'key_prev'      ,key_prev,control)
	call keydefs_def(keytable,'key_next'      ,key_next,control)
	call keydefs_def(keytable,'key_top'       ,key_top,control)
	call keydefs_def(keytable,'key_bot'       ,key_bot,control)
	call keydefs_def(keytable,'key_find'      ,key_find,control)
	call keydefs_def(keytable,'key_find1'     ,key_find1,control)
	call keydefs_def(keytable,'key_menu'      ,key_menu,control)
	call keydefs_def(keytable,'key_next_window',key_next_window,control)
	call keydefs_def(keytable,'key_prev_window',key_prev_window,control)
	call keydefs_def(keytable,'key_contdis'   ,key_contdis,control)
	call keydefs_def(keytable,'key_save'      ,key_save,control)
	call keydefs_def(keytable,'key_select'    ,key_select,control)
c
	call keydefs_def(keytable,'key_do'        ,key_do,control)
c	call keydefs_def(keytable,'key_show_field',key_show_field,control)
	call keydefs_def(keytable,'key_help'      ,key_help,control)
c
c line editting functions
c
	call keydefs_def(keytable,'key_toggle'    ,key_toggle,control)
	call keydefs_def(keytable,'key_last'      ,key_last,control)
	call keydefs_def(keytable,'key_first'     ,key_first,control)
	call keydefs_def(keytable,'key_enter'     ,key_enter,control)
	call keydefs_def(keytable,'key_erase'     ,key_erase,control)
	call keydefs_def(keytable,'key_next_line' ,key_next_line,control)
	call keydefs_def(keytable,'key_delete_line',key_delete_line,control)
	call keydefs_def(keytable,'key_undelete_line',key_undelete_line,control)
	call keydefs_def(keytable,'key_delete_word',key_delete_word,control)
	call keydefs_def(keytable,'key_undelete_word',key_undelete_word,control)
	call keydefs_def(keytable,'key_delete_char',key_delete_char,control)
	call keydefs_def(keytable,'key_undelete_char',key_undelete_char,control)
c
	call keydefs_def(keytable,'key_cancel'    ,key_cancel,control)
	call keydefs_def(keytable,'key_set_forw'  ,key_set_forw,control)
	call keydefs_def(keytable,'key_bot'       ,key_bot,control)
	call keydefs_def(keytable,'key_set_backw' ,key_set_backw,control)
	call keydefs_def(keytable,'key_dispall'   ,key_dispall,control)
	call keydefs_def(keytable,'key_erase'     ,key_erase,control)
	call keydefs_def(keytable,'key_remove'    ,key_remove,control)
	call keydefs_def(keytable,'key_editdes'   ,key_editdes,control)
	call keydefs_def(keytable,'key_fileinfo'  ,key_fileinfo,control)
c
	call keydefs_def(keytable,'key_repaint'   ,key_repaint,control)
	call keydefs_def(keytable,'key_getfields' ,key_getfields,control)
	call keydefs_def(keytable,'key_print'     ,key_print,control)
	call keydefs_def(keytable,'key_viewvfc'   ,key_viewvfc,control)
	call keydefs_def(keytable,'key_page'      ,key_page,control)
	call keydefs_def(keytable,'key_swap_num'  ,key_swap_num,control)
	call keydefs_def(keytable,'key_byte'      ,key_byte,control)
	call keydefs_def(keytable,'key_word'      ,key_word,control)
	call keydefs_def(keytable,'key_long'      ,key_long,control)
	call keydefs_def(keytable,'key_compres'   ,key_compres,control)
	call keydefs_def(keytable,'key_displ_hex' ,key_display_hex,control)
	call keydefs_def(keytable,'key_hexdec_offs',key_hexdeco,control)
	call keydefs_def(keytable,'key_newreclen' ,key_newreclen,control)
	call keydefs_def(keytable,'key_viewdes'   ,key_viewdes,control)
	call keydefs_def(keytable,'key_repaint'   ,key_repaint,control)
	call keydefs_def(keytable,'key_viewdesc'  ,key_viewdesc,control)
	call keydefs_def(keytable,'key_displ_bin'  ,key_display_binary,control)
	call keydefs_def(keytable,'key_displ_oct'  ,key_display_octal,control)
	call keydefs_def(keytable,'key_displ_dec'  ,key_display_decimal,control)
c
	call keydefs_def(keytable,'key_swap_dis'  ,key_swap_dis,control)
	call keydefs_def(keytable,'key_abort'     ,key_abort,control)
	call keydefs_def(keytable,'key_delete'    ,key_delete,control)
	call keydefs_def(keytable,'key_nextdes'   ,key_nextdes,control)
	call keydefs_def(keytable,'key_prevdes'   ,key_prevdes,control)
	call keydefs_def(keytable,'key_dirdes'    ,key_dirdes,control)
	call keydefs_def(keytable,'key_restore'   ,key_restore,control)
	call keydefs_def(keytable,'key_ask_key'   ,key_ask_key,control)
	call keydefs_def(keytable,'key_next_rec'  ,key_next_rec,control)
	call keydefs_def(keytable,'key_prev_rec'  ,key_prev_rec,control)
	call keydefs_def(keytable,'key_put'       ,key_put,control)
	call keydefs_def(keytable,'key_find_rec'  ,key_find_rec,control)
	call keydefs_def(keytable,'key_find_rec1' ,key_find_rec1,control)
	call keydefs_def(keytable,'key_next_file' ,key_next_file,control)
	call keydefs_def(keytable,'key_prev_file' ,key_prev_file,control)
	call keydefs_def(keytable,'key_dir_file'  ,key_dir_file,control)
	call keydefs_def(keytable,'key_exit'      ,key_exit,control)
	call keydefs_def(keytable,'key_modechange',key_modechange,control)
	call keydefs_def(keytable,'key_follow_link',key_follow_link,control)
	call keydefs_def(keytable,'key_back_link' ,key_back_link,control)
	call keydefs_def(keytable,'key_ch_width',  key_ch_width,control)
	call keydefs_def(keytable,'key_mouse_toggle',
     1                                             key_mouse_toggle,control)
	call keydefs_def(keytable,'key_change_disp',
     1                                             key_change_disp,control)
c
	call keydefs_def(keytable,'mouse_left',key_mouse_left,control)
	call keydefs_def(keytable,'mouse_middle',key_mouse_middle,control)
	call keydefs_def(keytable,'mouse_right',key_mouse_right,control)
c
c And define all keys+mapping
c
c Map two gold keys 
c
	call keydefs_map(smg$k_trm_pf1,        ' ',0,keytable,'gold',
     1                  control,' ')
	call keydefs_map(smg$k_trm_pf4        ,' ',0,keytable,'blue',
     1                  control,' ')
c
c Map the delete line for the  EDIT_DESCRIPTION screen
c
	call keydefs_map(smg$k_trm_pf4 ,' ',key_delete_line,keytable,' ',
     1                  control,'EDIT')
	call keydefs_map(smg$k_trm_pf4 ,'GOLD',key_undelete_line,keytable,' ',
     1                  control,'EDIT')
	call keydefs_map(smg$k_trm_f20         ,' ',0,keytable,'blue',
     1                  control,'EDIT')
c
	call keydefs_map(smg$k_trm_up,         ' ',key_up,   keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_down,       ' ',key_down, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_left,       ' ',key_left, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_right,      ' ',key_right,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_prev_screen,' ',key_prev, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_up,         'GOLD', key_prev,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_next_screen,' ',key_next, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_down,       'GOLD', key_next, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_prev_screen,'GOLD', key_top, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_next_screen,'GOLD', key_bot, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp8        ,' ', key_page,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_pf3        ,' ',key_find, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_pf3        ,'GOLD',key_find1, keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ht         ,' ',key_next_window,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ht         ,'GOLD',key_prev_window,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f8         ,' ',key_contdis,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f9         ,' ',key_save,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_do         ,' ',key_do   ,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_help       ,' ',key_help,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp0       ,' ',key_next_line,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_minus     ,'GOLD',key_undelete_word,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_minus     ,' ',key_delete_word,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_comma     ,' ',key_delete_char,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_comma     ,'GOLD',key_undelete_char,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_pf2        ,' ',key_help,keytable,' ',
     1                  control,' ')
c
c line editting functions
c
	call keydefs_map(smg$k_trm_ctrla      ,' ',key_toggle,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f14        ,' ',key_toggle,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f14        ,'GOLD',key_modechange,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_right      ,'GOLD',key_last,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrle      ,' ',key_last,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlh      ,' ',key_first,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_left      ,'GOLD',key_first,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f12        ,' ',key_first,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_cr         ,' ',key_enter,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_enter      ,' ',key_enter,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlx      ,' ',key_erase,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f13        ,' ',key_erase,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_lf         ,' ',key_erase,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlc      ,' ',key_cancel,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp4        ,' ',key_set_forw,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp4  ,'GOLD',key_set_forw,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp5   ,' ',key_set_backw,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp5   ,'GOLD',key_set_backw,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_select     ,' ',key_select,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_period     ,' ',key_select,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_s,'GOLD',key_dispall,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_delete     ,' ',key_delete,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_e,'GOLD',key_editdes,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_f,'GOLD',key_fileinfo,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_m,'GOLD',key_menu,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_m,'BLUE',key_mouse_toggle,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_z,'GOLD',key_follow_link,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_z,'BLUE',key_back_link,keytable,' ',
     1                  control,' ')
c
	call keydefs_map(smg$k_trm_ctrlr      ,' ',key_repaint,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlw      ,' ',key_repaint,keytable,' ',
     1                  control,' ')
	
	call keydefs_map(smg$k_trm_uppercase_g,'GOLD', key_getfields,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_p,'GOLD',key_print,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_y,'GOLD', key_viewvfc,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_o,'GOLD', key_swap_num,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_o,'BLUE', key_display_octal,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f20        ,' ',key_swap_num,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_b,'GOLD', key_byte,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_b,'BLUE', key_display_binary,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_w,'GOLD', key_word,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_w,'BLUE', key_ch_width,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_l,'GOLD', key_long,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_c,'GOLD', key_compres,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_c,'BLUE', key_change_disp,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_h,'BLUE', key_display_hex,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_h,'GOLD', key_hexdeco,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_t,'GOLD', key_newreclen,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_v,'GOLD', key_viewdes,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_v,'BLUE', key_viewdesc,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlw,      'GOLD', key_repaint,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlr,      'GOLD', key_repaint,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_a,'GOLD', key_swap_dis,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f19        ,' ',key_swap_dis,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_do         ,'GOLD' ,key_abort,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_remove     ,' ',key_remove,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp6        ,' ',key_remove,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_r,'GOLD', key_remove,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_x,'GOLD', key_nextdes,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_x,'BLUE', key_prevdes,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_d,'GOLD', key_dirdes,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_d,'BLUE', key_display_decimal,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f9         ,'GOLD', key_restore,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f17        ,' ',key_ask_key,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_k,'GOLD',key_ask_key,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f18        ,' ',key_next_rec,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f18        ,'GOLD',key_prev_rec,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_n,'GOLD',key_next_rec,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_n,'BLUE',key_prev_rec,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_insert_here,' ',key_put,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_kp6        ,'GOLD',key_put,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_i,'GOLD', key_put,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_find       ,' ',key_find_rec,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_find       ,'GOLD', key_find_rec1,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_j,'GOLD', key_next_file,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_j,'BLUE', key_prev_file,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_uppercase_q,'GOLD', key_dir_file,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_f10        ,' ',key_exit,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_ctrlz      ,' ',key_exit,keytable,' ',
     1                  control,' ')
c
c Map mouse keys
c
	call keydefs_map(smg$k_trm_first_down ,' ',key_mouse_left,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_second_down,' ',key_mouse_middle,keytable,' ',
     1                  control,' ')
	call keydefs_map(smg$k_trm_third_down ,' ',key_mouse_right,keytable,' ',
     1                  control,' ')
 
c
	return
	end
c
	subroutine keydefs_def(keytable,function_name,function_nr,control)
	implicit none
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
c
	record /keytable/ keytable	!:io: the keytable
	character*(*) function_name 	!:i: the name of the dix_function
	integer*4 function_nr		!:i: the funcion number
	record /control/ control
c#
	integer*4 nk
	integer*4 dix_util_get_len
	character*(max_short_line_length) line
c
	record /keydefs_function/ function
c
	function.magic = magic_keydefs_func
	if(keytable.case_sensitive) then
	  function.function_name = function_name
	else
	  call str$upcase(function.function_name,function_name)
	endif
        function.nk_name  = dix_util_get_len(function_name)
	function.function = function_nr
c
c Now insert the table
c 
	call dix_util_insert_table(control,
     1         keytable.functions,function,100,	!100 key defined?
     1         keytable.vm_zone,'FUNCTION')
c
	call sys$fao('!SL',nk,line,%val(function.function))
c
	call dix_main_print_debug(control,debug_keys,'Defined function '//
     1        function.function_name//' with value '//line(1:nk))
	return
	end
	function keydefs_map(smgkey,if_state,function,keytable,
     1                       set_state,control,context)
	implicit none
c
c Map a (gold,debug)-smgkey to a dix_function
c if function = 0, this is a state-key, state_key will be the name of the state
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
c
	integer*4 smgkey           	!:i: smg terminator
	character*(*) if_state 		!:i: gold state
	integer*4 function		!:o: function result
	record /keytable/ keytable	!:i: the keytable
	character*(*) set_state		!:i: gold state
	record /control/ control	!:i: control block
	character*(*) context		!:i: context (screen)
	logical keydefs_map		!:f: function result
c#
	integer*4 smgkeyok,nk,idx,imap
	integer*4 keydefs_chmap
	character*(max_short_line_length) idxasc
	character*(max_symbol_name_length) smgname
	character*(max_line_length) line
c
	integer*4 dix_util_get_len
	integer*4 keydefs_keycode_to_name
	external dix_msg_statdash
	external dix_msg_statempt
	external dix_msg_statfunc
	external dix_msg_smgerrnu
	external dix_msg_funcnotf
	external dix_msg_toomank
c
	record /keydefs_function/ functions(*)
	pointer (p_functions,functions)
c
	record /keydefs_key/ keys(*)
	pointer (p_keys,keys)
c
	record /keydefs_key/ key
c
c Make sure all uppercase, so lowercase_u = uppercase_u
c
	smgkeyok = keydefs_chmap(smgkey,keytable)
	p_functions = keytable.functions.address
	p_keys      = keytable.keys.address
c
	keydefs_map = .false.
c
c If state-Key (dix_function=0) specified, see if not mapped to state key
c
	if(.not. keydefs_keycode_to_name(smgkeyok,smgname)) then
	  call dix_message(control,dix_msg_smgerrnu,%val(smgkey))
	  goto 90
	endif
c
	if(index(if_state,'-') .ne. 0) then
	  call dix_message(control,dix_msg_statdash,if_state)
	  goto 90
	endif
	if(index(set_state,'-') .ne. 0) then
	  call dix_message(control,dix_msg_statdash,set_state)
	  goto 90
	endif
	if(function .eq. 0 .and. set_state .eq. ' ') then
	  call dix_message(control,dix_msg_statempt,smgname)
	  goto 90
	endif
	if(function .ne. 0 .and. set_state .ne. ' ') then
	  call dix_message(control,dix_msg_statfunc,smgname)
	  goto 90
	endif
c
c Try to locate the function, not for statedefs
c
	if(function .ne. 0) then
	  do imap=1,keytable.functions.count
	    if(functions(imap).function .eq. function) goto 20
	  end do
	  call dix_message(control,dix_msg_funcnotf,smgname)
	  goto 90
	else
	  imap = 0
	endif
c
c Try to find this key for anything else, if so override
c
20	do idx=1,keytable.keys.count
	  if(keys(idx).key .eq. smgkey .and. 
     1       keys(idx).if_state .eq. if_state .and.
     1       keys(idx).context  .eq. context) then
	    key = keys(idx)	!get this data
	    goto 30		!redefinition
	  endif
	end do
c
c Not found, so add to table
c
	idx = 0
c
c Add (or redefine key)
c
30	key.key          = smgkeyok
	if(keytable.case_sensitive) then
	  key.if_state   = if_state
	else
	  call str$upcase(key.if_state,if_state)
	endif
	key.nk_if        = dix_util_get_len(if_state)
	if(keytable.case_sensitive) then
	  key.set_state  = set_state
	else
	  call str$upcase(key.set_state,set_state)
	endif
	key.nk_set       = dix_util_get_len(set_state)
c
c Nu wat aanpassingen voor de pc toetsen borden
c
	key.keyname      = smgname
	key.nk_name      = dix_util_get_len(smgname)
	key.function_idx = imap
	key.context      = context
	key.nk_context   = dix_util_get_len(context)
	key.magic        = magic_keydefs_key
c
c Now if idx >0 , just replace the key def
c  else insert a new one
c
	if(idx .ne. 0) then
	  keys(idx) = key
	else
	  call dix_util_insert_table(control,
     1         keytable.keys,key,125,
     1         keytable.vm_zone,'KEYDEF')
	  p_keys = keytable.keys.address	!may have changed
	  idx = keytable.keys.count
	endif
c
c If debug, tell user what we did
c
	if((control.debug .and. debug_keys) .ne. 0) then
	  call keydefs_to_text(keytable,idx,line,nk,context,control)
	  write(idxasc,'(i3)') idx
	  if(function .eq. 0) then
	    call dix_main_print_debug(control,debug_keys,
     1       'Mapped at idx '//idxasc(1:3)//' '//
     1       line(1:nk)//' to state '//key.set_state//
     1       ' ctx '//key.context)
	  else
	    call dix_main_print_debug(control,debug_keys,
     1       'Mapped at idx '//idxasc(1:3)//' '//
     1       line(1:nk)//' to function '//
     1       functions(imap).function_name//
     1       ' ctx '//key.context)
	  endif
	endif	  
	keydefs_map = .true.
90	return
	end
	function keydefs_chmap(smgkey,keytable)
	implicit none
c
c Make sure all lowerkeys are mapped to upperkeys
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	integer*4 smgkey
	record /keytable/ keytable
	integer*4 keydefs_chmap
c#
c
	include '($smgdef)'
c
	if(keytable.case_sensitive) then
	  keydefs_chmap = smgkey
	else
	  if(smgkey .ge. smg$k_trm_lowercase_a .and. 
     1       smgkey .le. smg$k_trm_lowercase_z) then
	    keydefs_chmap = smgkey-smg$k_trm_lowercase_a+smg$k_trm_uppercase_a
	  else
	    keydefs_chmap = smgkey
	  endif
	endif
	return
	end
	function keydefs_function_name_to_code(name,function,key_ptr)
	implicit none
c 
c Translate the dix_function name to a number
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	character*(*) name
	integer*4 function
	integer*4 key_ptr
	integer*4 keydefs_function_name_to_code
c#
	record /keytable/ keytable
	pointer (p_keytable,keytable)	
c
	record /keydefs_function/ functions(*)
	pointer (p_functions,functions)
c
	integer*4 k
	integer*4 str$case_blind_compare
c
	p_keytable = key_ptr
	p_functions = keytable.functions.address
	keydefs_function_name_to_code = .false.
c
	do k=1,keytable.functions.count
	  if(str$case_blind_compare(functions(k).function_name,name)
     1             .eq. 0) then
	    keydefs_function_name_to_code = .true.
	    function = functions(k).function
	    goto 90
	  endif
	end do
90	return
	end	
	function keydefs_get_map(function,control,nk_keys,keynames,context)
	implicit none
c
c Deliver a< comma-separated list of keys mapped to the function
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	integer*4 function   		!:i: the function wanted
	record /control/ control	!:i: the control block
	integer*4 nk_keys		!:o: Length of keynames
	character*(*) keynames		!:o: the names
	character*(*) context		!:i: the context
	integer*4 keydefs_get_map
c#
	record /keytable/ keytable
	pointer (p_keytable,keytable)	
c
	record /keydefs_function/ functions(*)
	pointer (p_functions,functions)
c
	record /keydefs_key/ keys(*)
	pointer (p_keys,keys)
c
	integer*4 k,nk,idx,phase
	character*(max_line_length) line
	integer*4 keydefs_match_context
c
	p_keytable = control.key_table
c
	p_functions = keytable.functions.address
	p_keys = keytable.keys.address
c
	nk_keys  = 0
	keynames = ' '
	keydefs_get_map = .false.
c
c first get the index of the function
c
	do idx=1,keytable.functions.count
	  if(functions(idx).function .eq. function) goto 10
	end do
	goto 90
c
10	do phase=1,2
	  do k=1,keytable.keys.count
	    if(keys(k).function_idx .eq. idx) then
	      if(keydefs_match_context(phase,context,keys(k))) then
	        keydefs_get_map = .true.
	        call keydefs_to_text(keytable,k,line,nk,context,control)
	        call dix_append(nk_keys,keynames,line(1:nk))
	        call dix_append(nk_keys,keynames,',')
	      endif
	    end if
	  end do
	end do
	if(nk_keys .gt. 0) then
	  keynames(nk_keys:nk_keys) = ' '
	  nk_keys = nk_keys - 1
	end if
90	return
	end
	function keydefs_get_key(key_table,keyb_id,function,control,
     1                           row,col,context)
	implicit none
c
c This function reads keys via smg-keyboard
c and maps them the DIX-Functions. State-keys are handled in this function
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	include '($smgdef)'
	include '($smgmsg)'
	include '($tt2def)'
c
	integer*4 key_table     	!:i: Key table address
	integer*4 keyb_id		!:i: smg-keyboard id
	integer*4 function	        !:o: wanted key, return smgkey if not found
					!    0 is illegal state-construct
	record /control/ control	!:i: control block
	integer*4 row			!:o: row where mouse clicked
	integer*4 col			!:o: col where mouse clicked
	character*(*) context		!:i: the context where the key is typed
	logical*4 keydefs_get_key	!:f: function result of smg$read_keystroke
c#
	integer*4 istat,k,l,smgkey,newsmgkey,phase
	logical*4 is_appl_keypad
c
	integer*4 smg$read_locator
	integer*4 smg$read_keystroke
	integer*4 keydefs_chmap
	integer*4 keydefs_match_context
c
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	record /smgdef/ keyboard_info_block
c
	record /keydefs_function/ functions(*)
	pointer (p_functions,functions)
c
	record /keydefs_key/ keys(*)
	pointer (p_keys,keys)
c
c
	if(key_table .ne. 0) then
	  p_keytable = key_table		!set pointer
	  keytable.cur_state = ' '
	  p_keys      = keytable.keys.address
	  p_functions = keytable.functions.address
	endif
	row = 0
	col = 0
c
c We need the keypad to be in application mode
c get the current value
c
	call smg$get_keyboard_attributes(keyb_id,keyboard_info_block,
     1                    smg$c_keyboard_info_block)
	is_appl_keypad = (keyboard_info_block.smg$l_devdepend2 .and. 
     1                    tt2$m_app_keypad) .ne. 0
c
10	if(.not. is_appl_keypad) call smg$set_keypad_mode(keyb_id,
     1                             smg$m_keypad_application)
11	if(control.use_mouse) then
	  istat = smg$read_locator(keyb_id,row,col,smgkey)
	else
	  istat = smg$read_keystroke(keyb_id,smgkey)
	endif
c
c Ignore EOF status
c If the user hits ^Z, 
c  smg routines return the ^z character with istat=1
c The next time the SMG routines are called they return
c  istat = SMG$_EOF
c
	if(istat .eq. smg$_eof) istat = 1
c
	if(smgkey .eq. smg$k_trm_first_up .or. 
     1     smgkey .eq. smg$k_trm_second_up .or.
     1     smgkey .eq. smg$k_trm_third_up) then
c
c Ingnore mouse_up keys, the mouse_down are processed
c
	  goto 11
	endif
	if(.not. is_appl_keypad) call smg$set_keypad_mode(keyb_id,0)
	if(key_table .eq. 0) then
	  function = smgkey
	  goto 90
	endif
	if(istat) then
c
	  newsmgkey = keydefs_chmap(smgkey,keytable)
	  do phase=1,2
c
c Loop twice around all keys.
c  The first time  : check if the key has the right context
c  the second time : Check only for blank context keys (valid everywhere)
c
	    do k=1,keytable.keys.count
	      if(.not. keydefs_match_context(phase,context,keys(k))) goto 45
	      if(keys(k).key .eq. newsmgkey .and.
     1          (keys(k).if_state .eq. keytable.cur_state .or.
     1           (keytable.cur_state .ne. ' ' .and. 
     1            keys(k).set_state.eq. keytable.cur_state)))then
	        call dix_main_print_debug(control,debug_keys,
     1                'Found  '//keys(k).keyname)
	        call dix_main_print_debug(control,debug_keys,
     1                '    state  '//keys(k).set_state)
	        call dix_main_print_debug(control,debug_keys,
     1                '    mapped to ') !//keys(k).function_idx)
c
c Got a match, now check if this key is a state-key
c
	        if(keys(k).set_state .ne. ' ') then
c
c This is a state-key, now set istate and read next char
c
	          keytable.cur_state = keys(k).set_state
	          goto 10
	        endif
	        l        = keys(k).function_idx
	        function = functions(l).function
	        call dix_main_print_debug(control,debug_keys,
     1           ' Result key '//functions(l).function_name)
	        goto 90
	      endif       !got key
45	    end do        !do k=1,n_key
	  end do	!do phase=1,2
	endif		!smg$read_keystroke
	if(keytable.cur_state .eq. ' ') then
c
c return the key
c
	  function = smgkey
	else
c
c return a 0, could not find set_key
c
	  function = 0
	endif
90	keydefs_get_key = istat
	return
	end	
	function keydefs_add_key(control,smgname,if_state,set_state,
     1                             funcname,context)
	implicit none
c
c Define a key
c if function = "" then a state key, (state "state" will be defined)
c if function <>"" then define a key to a function (possible "stat"ed)
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	record /control/ control
	character*(*) smgname
	character*(*) if_state
	character*(*) set_state
	character*(*) funcname
	character*(*) context
	logical keydefs_add_key
c#
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	integer*4 smgkey,function,nk
c
	integer*4 keydefs_keyname_to_code
	integer*4 keydefs_function_name_to_code
	external dix_msg_smgerrna
	external dix_msg_funcerr
c
c Define a key /state=state dix_function
c
	p_keytable = control.key_table
	keydefs_add_key = .false.
 	if(.not. keydefs_keyname_to_code(smgname,smgkey)) then
	  nk = index(smgname,' ')-1
	  call dix_message(control,dix_msg_smgerrna,smgname(1:nk))
	else
	  if(funcname .ne. ' ' .and. .not. 
     1            keydefs_function_name_to_code(funcname,
     1             function,control.key_table)) then
	    nk = index(funcname,' ')-1
	    call dix_message(control,dix_msg_funcerr,funcname(1:nk))
	  else
	    call keydefs_map(smgkey,if_state,function,keytable,
     1              set_state,control,context)
	    keydefs_add_key = .true.
	  endif
	endif
	return
	end
	function keydefs_del_key(control,smgname,if_state,context)
	implicit none
c
c Delete a key
c if smgname = empty, delete all keys
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	record /control/ control
	character*(*) smgname
	character*(*) if_state
	character*(*) context
	logical keydefs_del_key
c#
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	integer*4 k,l
	external dix_msg_keyfnotf
c
	record /keydefs_key/ keys(*)
	pointer (p_keys,keys)
c
c Deletion of key/function/all
c
	p_keytable = control.key_table
	p_keys     = keytable.keys.address
c
	if(smgname .eq. ' ') then
	  keytable.keys.count = 0
	else	  
	  do k=1,keytable.keys.count
	    if(keys(k).keyname .eq. smgname .and.
     1         keys(k).if_state .eq. if_state .and.
     1         keys(k).if_state .eq. context) goto 20
	  end do
	  call dix_message(control,dix_msg_keyfnotf,smgname,if_state,context)
	  goto 90
20	  call dix_main_print_debug(control,debug_keys,
     1       'Deleted key '//keys(k).keyname)
	  do l=k+1,keytable.keys.count
	    keys(l-1) = keys(l)
	  end do
	  keytable.keys.count = keytable.keys.count - 1
	endif
90	keydefs_del_key = .true.
	return
	end
	function keydefs_keycode_to_name(smgkey,smgname)
	implicit none
	include '($smgdef)'
c
	integer*4 smgkey
	character*(*) smgname
	logical*4 keydefs_keycode_to_name
c#
	logical*4 smg$keycode_to_name
	integer*4 istat
c
	istat = 1
c
c Function check some special keys
c
	if(smgkey .eq. smg$k_trm_delete) then
	  smgname = 'DELETE'
	  goto 90
	elseif(smgkey .eq. smg$k_trm_first_down) then
	  smgname = 'LEFT_MOUSE'
	  goto 90
	elseif(smgkey .eq. smg$k_trm_second_down) then
	  smgname = 'MIDDLE_MOUSE'
	  goto 90
	elseif(smgkey .eq. smg$k_trm_third_down) then
	  smgname = 'RIGHT_MOUSE'
	  goto 90
	endif
	istat = smg$keycode_to_name(smgkey,smgname) 
	if(istat) then
c
c make some keys more readable
c
	  if(smgname .eq. 'E1') then
	    smgname = 'Find'
	  elseif(smgname .eq. 'E2') then
	    smgname = 'Insert_Here'
	  elseif(smgname .eq. 'E3') then
	    smgname = 'Remove'
	  elseif(smgname .eq. 'E4') then
	    smgname = 'Select'
	  elseif(smgname .eq. 'E5') then
	    smgname = 'Prev_Screen'
	  elseif(smgname .eq. 'E6') then
	    smgname = 'Next_Screen'
	  elseif(smgname .eq. 'CTRLM') then
	    smgname = 'Return'
	  elseif(smgname .eq. 'CTRLI') then
	    smgname = 'TAB'
	  endif
	else
	  smgname = 'Unknown?'
	endif
90	keydefs_keycode_to_name = istat
	return
	end
	function keydefs_keyname_to_code(smgname,smgkey)
	implicit none
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
	include '($smgdef)'
	character*(*) smgname
	integer*4 smgkey
	logical*4 keydefs_keyname_to_code
c
	integer*4 istat,nk
	logical*4 smg$name_to_keycode
	integer*4 dix_util_get_len
c#
	character*(keydefs_name_size) name
c
	call str$upcase(name,smgname )
	if(name(1:10) .eq. 'UPPERCASE_') then
	  name = name(11:11)
	elseif(name(1:10) .eq. 'LOWERCASE_') then
	  name = char(ichar(name(11:11)) - ichar('A') + ichar('a')) 
	elseif(name .eq. 'RETURN') then
	  name = 'CTRLM'
	elseif(name .eq. 'LF') then
	  name = 'CTRLJ'
	elseif(name .eq. 'TAB') then
	  name = 'CTRLI'
	elseif(name .eq. 'HT') then
	  name = 'CTRLI'
	elseif(name .eq. 'CR') then
	  name = 'CTRLM'
	elseif(name .eq. 'LF') then
	  name = 'CTRLJ'
	elseif(name .eq. 'DELETE') then
	  smgkey = smg$k_trm_delete
	  istat = 1
	  goto 90
	endif
	nk = dix_util_get_len(name)
	istat = smg$name_to_keycode(name(1:nk),smgkey) 
90	keydefs_keyname_to_code = istat
	return
	end
	subroutine keydefs_to_text(keytable,idx,line,nk,context,control)
	implicit none
c
c Translate the key on idx to text
c if if_state is set, prefix the key by its set_state key
c Beware , there may be more than one key containing the set-state
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
c
	record /keytable/ keytable
	integer*4 idx	                !:i: key
	character*(*) line              !:o: name(s)
	integer*4 nk			!:o: length of the name(s)
	character*(*) context		!:i: the context (Screen)
	record /control/ control	!:i: the control block
c#
c
	record /keydefs_key/ keys(*)
	pointer (p_keys,keys)
	character*(keydefs_name_size) keyname
c
	integer*4 l,nk_s,nk_k
c
	p_keys      = keytable.keys.address
c
	nk     = 0
	if(keys(idx).if_state .ne. ' ') then
c
c Go through all keys with a set_state thiskeys if_state
c
	  do l=1,keytable.keys.count
	    if(keys(l).set_state .eq. keys(idx).if_state .and.
     1         keys(l).context .eq. context) then
	      call dix_keydef_check_kb(control,keys(l).keyname,
     1                 keyname,nk_s)
	      line(nk+1:) = keyname(1:nk_s)//'-'
	      nk = nk + nk_s + 1
	      call dix_keydef_check_kb(control,keys(idx).keyname,
     1                 keyname,nk_k)
	      line(nk+1:) = keyname(1:nk_k)//','
	      nk = nk + nk_k + 1
	    endif
	  end do
c
c If not yet found, try if there is a general state key (for all displays)
c
	  if(nk .eq. 0) then
	    do l=1,keytable.keys.count
	      if(keys(l).set_state .eq. keys(idx).if_state .and.
     1         keys(l).context .eq.' ') then
	        call dix_keydef_check_kb(control,keys(l).keyname,
     1                    keyname,nk_s)
	        line(nk+1:) = keyname(1:nk_s)//'-'
	        nk = nk + nk_s + 1
	        call dix_keydef_check_kb(control,keys(idx).keyname,
     1                    keyname,nk_k)
	        line(nk+1:) = keyname(1:nk_k)//','
	        nk = nk + nk_k + 1
	      endif
	    end do
	  endif
c
c Do not understand?
c
	  if(nk .eq. 0) then
	    nk_s = keys(idx).nk_if
	    call dix_keydef_check_kb(control,keys(idx).keyname,
     1                    keyname,nk_k)
	    line = '?'//keys(idx).if_state(1:nk_s)//'-'//keyname(1:nk_s)
	    nk = 1 + nk_s + nk_k + 2
	  else
c
c Remove the trailing ,
c
	    nk = nk - 1
	  endif
	else
c
c No if state, just contains the keyname
c
	  call dix_keydef_check_kb(control,keys(idx).keyname,line,nk)
	end if
	return
	end
	subroutine keydefs_dump(control,fnam,context,mask)
	implicit none
c
	include 'dix_def.inc'		
	include 'dix_keydefs.inc'
	record /control/ control
	character*(*) fnam              !:i: the name of the output file
	character*(*) context           !:i: screen context
	character*(*) mask		!:i: keyname mask
c#
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	character*(max_line_length) line
	integer*4 nk,k,function,lun,phase,nkf,namlen
	integer*4 dix_util_match_string_wild
c
	record /keydefs_function/ functions(*)
	pointer (p_functions,functions)
c
	p_keytable  = control.key_table
	p_functions = keytable.functions.address
c
	call lib$get_lun(lun)
	open(lun,file=fnam,status='new',carriagecontrol='list',err=80)
c
	namlen = 0
	do phase=1,2
	  do k=1,keytable.functions.count
	    function = functions(k).function
	    call keydefs_get_map(function,control,nk,line,context)
	    nkf = functions(k).nk_name
	    if(dix_util_match_string_wild(
     1                   functions(k).function_name(1:nkf),
     1                   mask,.false.,wildcard_flag_standard)) then
	      if(phase .eq. 1) then
	        namlen = max(namlen,nkf)
	      else
 	        write(lun,1000) functions(k).function_name(1:namlen),
     1            line(1:nk)
1000	        format(a,'>',a)
	      endif
	    endif
	  enddo
	end do
	close(lun)
	goto 90
80	write(*,*) 'Could not open file ',fnam
90	call lib$free_lun(lun)
	return
	end
	function keydefs_match_context(phase,context,key)
	implicit none
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
c
	integer*4 phase
	character*(*) context
	record /keydefs_key/ key
	integer*4 keydefs_match_context
c
	integer*4 nk
	integer*4 dix_util_get_len
	integer*4 dix_util_match_string_wild
c
	keydefs_match_context = .true.
c
	if(phase .eq. 1) then
c
c If context blank : match always
c
c	  if(context .eq. ' ') goto 90
c
c context not blank, now compare
c
	  nk = dix_util_get_len(context)
	  if(dix_util_match_String_wild(key.context(1:key.nk_context),
     1           context(1:nk),.false.,wildcard_flag_standard)) goto 90
	else
c
c Phase 2, if context=blank, we already had a match, so skip now
c
c	  if(context .ne. ' ') then	  	  
c
c If context <> blank, match if key-context=blank (match always)
c
	    if(key.context .eq. ' ') goto 90
c	  endif
	endif
	keydefs_match_context = .false.
90	return
	end
        subroutine dix_keydefs_show_vm(control,fi)
        implicit none
c
c SHow VM used for Symbols
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
        record /control/ control        !:i: control structure
        logical fi                      !:i: flag
c#
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	p_keytable = control.key_table
c
        call dix_util_show_vm1(control,keytable.vm_zone,fi,0)
        return
	end
	subroutine keydefs_function_to_name(control,function,name,nk)
	implicit none
c
	include 'dix_def.inc'
	include 'dix_keydefs.inc'
c
c Transform a function to a name
c
	record /control/ control
	integer*4 function	!:i: the funciton required
	character*(*) name      !:o: the name
	integer*4 nk            !:o: length of the name
c
	record /keytable/ keytable
	pointer (p_keytable,keytable)
c
	record /keydefs_function/ functions(*)
	pointer (p_functions,functions)
c
	integer*4 k
c
	p_keytable = control.key_table
c
	p_functions = keytable.functions.address
c
	do k=1,keytable.functions.count
	  if(functions(k).function .eq. function) then
	    name = functions(k).function_name
	    nk   = functions(k).nk_name
	    goto 90
	  endif
	end do
90	return
	end
	subroutine dix_keydef_check_kb(control,keynamei,keynameo,nk)
	implicit none
c
c FOr pc/laptop's keys are named differently
c  make a (as good as possible) name translation
c
	include 'dix_def.inc'
	record /control/ control	!:i: control block
	character*(*) keynamei		!:i: input keyname
	character*(*) keynameo		!:o: output keyname
	integer*4 nk			!:o: length of keynameo
c
	integer*4 dix_util_get_len
c
c Assume Normal
c
	keynameo = keynamei
c
	if(control.keyboard .eq. keyboard_pc .or. 
     1     control.keyboard .eq. keyboard_laptop) then
c
c COmmon pc/laptop
c
	  if(keynamei .eq. 'F13')   keynameo = 'S+F3'
	  if(keynamei .eq. 'F14')   keynameo = 'S+F4'
	  if(keynamei .eq. 'HELP')  keynameo = 'S+F5'
	  if(keynamei .eq. 'DO' )   keynameo = 'S+F6'
	  if(keynamei .eq. 'F17')   keynameo = 'S+F7'
	  if(keynamei .eq. 'F18')   keynameo = 'S+F8'
	  if(keynamei .eq. 'F19')   keynameo = 'S+F9'
	  if(keynamei .eq. 'F20')   keynameo = 'S+F10'
	  if(keynamei .eq. 'Find')  keynameo = 'Home'
	  if(keynamei .eq. 'Select')keynameo = 'END'
	  if(keynamei .eq. 'Next_Screen') keynameo = 'PageDown'
	  if(keynamei .eq. 'Prev_Screen') keynameo = 'PageUp'
	endif
	if(control.keyboard .eq. keyboard_pc) then
c
c Specific pc
c
	  if(keynamei .eq. 'PF1')keynameo = 'Numlock'
	  if(keynamei .eq. 'PF2')keynameo = 'KPSlash'
	  if(keynamei .eq. 'PF3')keynameo = 'KPAsterix'
	  if(keynamei .eq. 'PF4')keynameo = 'KPMinus'
	elseif(control.keyboard .eq. keyboard_laptop) then
c
c Need the laptop keys for pf1..pf4??
c
	  if(keynamei .eq. 'PF1')keynameo = 'Numlock'
	  if(keynamei .eq. 'PF2')keynameo = 'KPSlash'
	  if(keynamei .eq. 'PF3')keynameo = 'KPAsterix'
	  if(keynamei .eq. 'PF4')keynameo = 'KPMinus'
	endif
	nk = dix_util_get_len(keynameo)
	return
	end
