add: XFree(x_modifier_keymap);
context: x_reset_modifier_mapping (Display *display){  int modifier_index, modifier_key, column, mkpm;  int warned_about_overlapping_modifiers = 0;  int warned_about_predefined_modifiers  = 0;  int warned_about_duplicate_modifiers   = 0;  int meta_bit  = 0;  int hyper_bit = 0;  int super_bit = 0;  int alt_bit   = 0;  int mode_bit  = 0;  XModifierKeymap *x_modifier_keymap = XGetModifierMapping (display);#define modwarn(name,old,other)						    \  wwarning ("%s (0x%x) generates %s, which is generated by %s.\n\n",        \		  name, code, index_to_name (old), other),		    \  warned_about_overlapping_modifiers = 1#define modbarf(name,other)						    \  wwarning ("%s (0x%x) generates %s, which is nonsensical.\n\n",            \		  name, code, other),					    \  warned_about_predefined_modifiers = 1#define check_modifier(name,mask)					    \  if ((1<<modifier_index) != mask)					    \    wwarning ("%s (0x%x) generates %s, which is nonsensical.\n\n",          \		    name, code, index_to_name (modifier_index)),	    \    warned_about_predefined_modifiers = 1#define store_modifier(name,old)					   \  if (old && old != modifier_index)					   \    wwarning ("%s (0x%x) generates both %s and %s, which is nonsensical.\n\n",\		    name, code, index_to_name (old),			   \		    index_to_name (modifier_index)),			   \    warned_about_duplicate_modifiers = 1;				   \  if (modifier_index == ShiftMapIndex) modbarf (name,"ModShift");	   \  else if (modifier_index == LockMapIndex) modbarf (name,"ModLock");	   \  else if (modifier_index == ControlMapIndex) modbarf (name,"ModControl"); \  else if (sym == XK_Mode_switch)					   \    mode_bit = modifier_index; /* Mode_switch is special, see below... */  \  else if (modifier_index == meta_bit && old != meta_bit)		   \    modwarn (name, meta_bit, "Meta");					   \  else if (modifier_index == super_bit && old != super_bit)		   \    modwarn (name, super_bit, "Super");					   \  else if (modifier_index == hyper_bit && old != hyper_bit)		   \    modwarn (name, hyper_bit, "Hyper");					   \  else if (modifier_index == alt_bit && old != alt_bit)			   \    modwarn (name, alt_bit, "Alt");					   \  else									   \    old = modifier_index;  mkpm = x_modifier_keymap->max_keypermod;  for (modifier_index = 0; modifier_index < 8; modifier_index++)    for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {      KeySym last_sym = 0;      for (column = 0; column < 4; column += 2) {	KeyCode code = x_modifier_keymap->modifiermap[modifier_index * mkpm							  + modifier_key];	KeySym sym = (code ? XKeycodeToKeysym (display, code, column) : 0);	if (sym == last_sym) continue;	last_sym = sym;	switch (sym) {	case XK_Mode_switch:store_modifier ("Mode_switch", mode_bit); break;	case XK_Meta_L:     store_modifier ("Meta_L", meta_bit); break;	case XK_Meta_R:     store_modifier ("Meta_R", meta_bit); break;	case XK_Super_L:    store_modifier ("Super_L", super_bit); break;	case XK_Super_R:    store_modifier ("Super_R", super_bit); break;	case XK_Hyper_L:    store_modifier ("Hyper_L", hyper_bit); break;	case XK_Hyper_R:    store_modifier ("Hyper_R", hyper_bit); break;	case XK_Alt_L:      store_modifier ("Alt_L", alt_bit); break;	case XK_Alt_R:      store_modifier ("Alt_R", alt_bit); break;	case XK_Control_L:  check_modifier ("Control_L", ControlMask); break;	case XK_Control_R:  check_modifier ("Control_R", ControlMask); break;	case XK_Shift_L:    check_modifier ("Shift_L", ShiftMask); break;	case XK_Shift_R:    check_modifier ("Shift_R", ShiftMask); break;	case XK_Shift_Lock: check_modifier ("Shift_Lock", LockMask); break;	case XK_Caps_Lock:  check_modifier ("Caps_Lock", LockMask); break;	/* It probably doesn't make any sense for a modifier bit to be	   assigned to a key that is not one of the above, but OpenWindows	   assigns modifier bits to a couple of random function keys for	   no reason that I can discern, so printing a warning here would	   be annoying. */	}      }    }#undef store_modifier#undef check_modifier#undef modwarn#undef modbarf  /* If there was no Meta key, then try using the Alt key instead.     If there is both a Meta key and an Alt key, then the Alt key     is not disturbed and remains an Alt key. */  if (! meta_bit && alt_bit)    meta_bit = alt_bit, alt_bit = 0;  /* mode_bit overrides everything, since it's processed down inside of     XLookupString() instead of by us.  If Meta and Mode_switch both     generate the same modifier bit (which is an error), then we don't     interpret that bit as Meta, because we can't make XLookupString()     not interpret it as Mode_switch; and interpreting it as both would     be totally wrong. */  if (mode_bit)    {      const char *warn = 0;      if      (mode_bit == meta_bit)  warn = "Meta",  meta_bit  = 0;      else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;      else if (mode_bit == super_bit) warn = "Super", super_bit = 0;      else if (mode_bit == alt_bit)   warn = "Alt",   alt_bit   = 0;      if (warn)	{	  wwarning	    ("%s is being used for both Mode_switch and %s.\n\n",	     index_to_name (mode_bit), warn),	    warned_about_overlapping_modifiers = 1;	}    }  MetaMask   = (meta_bit   ? (1 << meta_bit)  : 0);  HyperMask  = (hyper_bit  ? (1 << hyper_bit) : 0);  SuperMask  = (super_bit  ? (1 << super_bit) : 0);  AltMask    = (alt_bit    ? (1 << alt_bit)   : 0);  ModeMask   = (mode_bit   ? (1 << mode_bit)  : 0); /* unused */#if 0  if (warned_about_overlapping_modifiers)    wwarning ("\n""	Two distinct modifier keys (such as Meta and Hyper) cannot generate\n""	the same modifier bit, because Emacs won't be able to tell which\n""	modifier was actually held down when some other key is pressed.  It\n""	won't be able to tell Meta-x and Hyper-x apart, for example.  Change\n""	one of these keys to use some other modifier bit.  If you intend for\n""	these keys to have the same behavior, then change them to have the\n""	same keysym as well as the same modifier bit.\n");  if (warned_about_predefined_modifiers)    wwarning ("\n""	The semantics of the modifier bits ModShift, ModLock, and ModControl\n""	are predefined.  It does not make sense to assign ModControl to any\n""	keysym other than Control_L or Control_R, or to assign any modifier\n""	bits to the \"control\" keysyms other than ModControl.  You can't\n""	turn a \"control\" key into a \"meta\" key (or vice versa) by simply\n""	assigning the key a different modifier bit.  You must also make that\n""	key generate an appropriate keysym (Control_L, Meta_L, etc).\n");  /* No need to say anything more for warned_about_duplicate_modifiers. */  if (warned_about_overlapping_modifiers || warned_about_predefined_modifiers)    wwarning ("\n""	The meanings of the modifier bits Mod1 through Mod5 are determined\n""	by the keysyms used to control those bits.  Mod1 does NOT always\n""	mean Meta, although some non-ICCCM-compliant programs assume that.\n");#endif}