CVS: rdesktop proto.h,1.75,1.76 types.h,1.25,1.26 xkeymap.c,1.70,1.71 xwin.c,1.191,1.192

Peter Åstrand <[email protected]>
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19744

Modified Files:
	proto.h types.h xkeymap.c xwin.c 
Log Message:
Implemented support for keyboard "sequences", which makes it possible to send multiple scancodes to the RDP server in response to one X11 keyboard event.

Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.75
retrieving revision 1.76
diff -C2 -d -r1.75 -r1.76
*** proto.h	2 Aug 2005 09:43:56 -0000	1.75
--- proto.h	2 Aug 2005 15:07:26 -0000	1.76
***************
*** 170,173 ****
--- 170,175 ----
  BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed);
  key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
+ void xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,
+ 		       BOOL pressed);
  uint16 xkeymap_translate_button(unsigned int button);
  char *get_ksname(uint32 keysym);

Index: types.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/types.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -d -r1.25 -r1.26
*** types.h	8 Mar 2005 00:43:10 -0000	1.25
--- types.h	2 Aug 2005 15:07:34 -0000	1.26
***************
*** 111,116 ****
--- 111,120 ----
  typedef struct _key_translation
  {
+ 	/* For normal scancode translations */
  	uint8 scancode;
  	uint16 modifiers;
+ 	/* For sequences. If keysym is nonzero, the fields above are not used. */
+ 	uint32 seq_keysym;	/* Really KeySym */
+ 	struct _key_translation *next;
  }
  key_translation;

Index: xkeymap.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xkeymap.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -C2 -d -r1.70 -r1.71
*** xkeymap.c	7 Jun 2005 11:21:53 -0000	1.70
--- xkeymap.c	2 Aug 2005 15:07:34 -0000	1.71
***************
*** 48,52 ****
  
  static BOOL keymap_loaded;
! static key_translation keymap[KEYMAP_SIZE];
  static int min_keycode;
  static uint16 remote_modifier_state = 0;
--- 48,52 ----
  
  static BOOL keymap_loaded;
! static key_translation *keymap[KEYMAP_SIZE];
  static int min_keycode;
  static uint16 remote_modifier_state = 0;
***************
*** 59,62 ****
--- 59,63 ----
  {
  	KeySym keysym;
+ 	key_translation *tr;
  
  	keysym = XStringToKeysym(keyname);
***************
*** 70,79 ****
  		   "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
  
! 	keymap[keysym & KEYMAP_MASK].scancode = scancode;
! 	keymap[keysym & KEYMAP_MASK].modifiers = modifiers;
  
  	return;
  }
  
  
  static BOOL
--- 71,143 ----
  		   "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
  
! 	tr = (key_translation *) xmalloc(sizeof(key_translation));
! 	memset(tr, 0, sizeof(key_translation));
! 	tr->scancode = scancode;
! 	tr->modifiers = modifiers;
! 	keymap[keysym & KEYMAP_MASK] = tr;
  
  	return;
  }
  
+ static void
+ add_sequence(char *rest, char *mapname)
+ {
+ 	KeySym keysym;
+ 	key_translation *tr, **prev_next;
+ 	size_t chars;
+ 	char keyname[KEYMAP_MAX_LINE_LENGTH];
+ 
+ 	/* Skip over whitespace after the sequence keyword */
+ 	chars = strspn(rest, " \t");
+ 	rest += chars;
+ 
+ 	/* Fetch the keysym name */
+ 	chars = strcspn(rest, " \t\0");
+ 	STRNCPY(keyname, rest, chars + 1);
+ 	rest += chars;
+ 
+ 	keysym = XStringToKeysym(keyname);
+ 	if (keysym == NoSymbol)
+ 	{
+ 		DEBUG_KBD(("Bad keysym \"%s\" in keymap %s (ignoring line)\n", keyname, mapname));
+ 		return;
+ 	}
+ 
+ 
+ 	DEBUG_KBD(("Adding sequence for keysym (0x%lx, %s) -> ", keysym, keyname));
+ 
+ 	prev_next = &keymap[keysym & KEYMAP_MASK];
+ 
+ 	while (*rest)
+ 	{
+ 		/* Skip whitespace */
+ 		chars = strspn(rest, " \t");
+ 		rest += chars;
+ 
+ 		/* Fetch the keysym name */
+ 		chars = strcspn(rest, " \t\0");
+ 		STRNCPY(keyname, rest, chars + 1);
+ 		rest += chars;
+ 
+ 		keysym = XStringToKeysym(keyname);
+ 		if (keysym == NoSymbol)
+ 		{
+ 			DEBUG_KBD(("Bad keysym \"%s\" in keymap %s (ignoring line)\n", keyname,
+ 				   mapname));
+ 			return;
+ 		}
+ 
+ 		/* Allocate space for key_translation structure */
+ 		tr = (key_translation *) xmalloc(sizeof(key_translation));
+ 		memset(tr, 0, sizeof(key_translation));
+ 		*prev_next = tr;
+ 		prev_next = &tr->next;
+ 		tr->seq_keysym = keysym;
+ 
+ 		DEBUG_KBD(("0x%x, ", (unsigned int) keysym));
+ 	}
+ 	DEBUG_KBD(("\n"));
+ }
+ 
  
  static BOOL
***************
*** 151,154 ****
--- 215,225 ----
  		}
  
+ 		/* sequence */
+ 		if (strncmp(line, "sequence", 8) == 0)
+ 		{
+ 			add_sequence(line + 8, mapname);
+ 			continue;
+ 		}
+ 
  		/* Comment */
  		if (line[0] == '#')
***************
*** 392,455 ****
  xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
  {
! 	key_translation tr = { 0, 0 };
! 
! 	tr = keymap[keysym & KEYMAP_MASK];
! 
! 	if (tr.modifiers & MapInhibitMask)
! 	{
! 		DEBUG_KBD(("Inhibiting key\n"));
! 		tr.scancode = 0;
! 		return tr;
! 	}
  
! 	if (tr.modifiers & MapLocalStateMask)
  	{
! 		/* The modifiers to send for this key should be obtained
! 		   from the local state. Currently, only shift is implemented. */
! 		if (state & ShiftMask)
  		{
! 			tr.modifiers = MapLeftShiftMask;
  		}
  	}
! 
! 	if ((tr.modifiers & MapLeftShiftMask) && ((remote_modifier_state & MapLeftCtrlMask)
! 						  || (remote_modifier_state & MapRightCtrlMask))
! 	    && get_key_state(state, XK_Caps_Lock))
  	{
! 		DEBUG_KBD(("CapsLock + Ctrl pressed, releasing LeftShift\n"));
! 		tr.modifiers ^= MapLeftShiftMask;
! 	}
  
! 	if (tr.scancode != 0)
! 	{
! 		DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
! 			   tr.scancode, tr.modifiers));
! 		return tr;
  	}
  
! 	if (keymap_loaded)
! 		warning("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));
  
! 	/* not in keymap, try to interpret the raw scancode */
! 	if (((int) keycode >= min_keycode) && (keycode <= 0x60))
  	{
! 		tr.scancode = keycode - min_keycode;
  
! 		/* The modifiers to send for this key should be
! 		   obtained from the local state. Currently, only
! 		   shift is implemented. */
! 		if (state & ShiftMask)
  		{
! 			tr.modifiers = MapLeftShiftMask;
  		}
! 
! 		DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
  	}
! 	else
  	{
! 		DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
  	}
- 
- 	return tr;
  }
  
--- 463,576 ----
  xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
  {
! 	key_translation tr = { 0, 0, 0, 0 };
! 	key_translation *ptr;
  
! 	ptr = keymap[keysym & KEYMAP_MASK];
! 	if (ptr)
  	{
! 		tr = *ptr;
! 		if (tr.seq_keysym == 0)	/* Normal scancode translation */
  		{
! 			if (tr.modifiers & MapInhibitMask)
! 			{
! 				DEBUG_KBD(("Inhibiting key\n"));
! 				tr.scancode = 0;
! 				return tr;
! 			}
! 
! 			if (tr.modifiers & MapLocalStateMask)
! 			{
! 				/* The modifiers to send for this key should be obtained
! 				   from the local state. Currently, only shift is implemented. */
! 				if (state & ShiftMask)
! 				{
! 					tr.modifiers = MapLeftShiftMask;
! 				}
! 			}
! 
! 			if ((tr.modifiers & MapLeftShiftMask)
! 			    && ((remote_modifier_state & MapLeftCtrlMask)
! 				|| (remote_modifier_state & MapRightCtrlMask))
! 			    && get_key_state(state, XK_Caps_Lock))
! 			{
! 				DEBUG_KBD(("CapsLock + Ctrl pressed, releasing LeftShift\n"));
! 				tr.modifiers ^= MapLeftShiftMask;
! 			}
! 
! 			DEBUG_KBD(("Found scancode translation, scancode=0x%x, modifiers=0x%x\n",
! 				   tr.scancode, tr.modifiers));
  		}
  	}
! 	else
  	{
! 		if (keymap_loaded)
! 			warning("No translation for (keysym 0x%lx, %s)\n", keysym,
! 				get_ksname(keysym));
  
! 		/* not in keymap, try to interpret the raw scancode */
! 		if (((int) keycode >= min_keycode) && (keycode <= 0x60))
! 		{
! 			tr.scancode = keycode - min_keycode;
! 
! 			/* The modifiers to send for this key should be
! 			   obtained from the local state. Currently, only
! 			   shift is implemented. */
! 			if (state & ShiftMask)
! 			{
! 				tr.modifiers = MapLeftShiftMask;
! 			}
! 
! 			DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
! 		}
! 		else
! 		{
! 			DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
! 		}
  	}
  
! 	return tr;
! }
  
! void
! xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,
! 		  BOOL pressed)
! {
! 	key_translation tr, *ptr;
! 	tr = xkeymap_translate_key(keysym, keycode, state);
! 
! 	if (tr.seq_keysym == 0)
  	{
! 		/* Scancode translation */
! 		if (tr.scancode == 0)
! 			return;
  
! 		if (pressed)
  		{
! 			save_remote_modifiers(tr.scancode);
! 			ensure_remote_modifiers(ev_time, tr);
! 			rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
! 			restore_remote_modifiers(ev_time, tr.scancode);
  		}
! 		else
! 		{
! 			rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
! 		}
! 		return;
  	}
! 
! 	/* Sequence, only on key down */
! 	if (pressed)
  	{
! 		ptr = &tr;
! 		do
! 		{
! 			DEBUG_KBD(("Handling sequence element, keysym=0x%x\n",
! 				   (unsigned int) ptr->seq_keysym));
! 			xkeymap_send_keys(ptr->seq_keysym, keycode, state, ev_time, True);
! 			xkeymap_send_keys(ptr->seq_keysym, keycode, state, ev_time, False);
! 			ptr = ptr->next;
! 		}
! 		while (ptr);
  	}
  }
  

Index: xwin.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v
retrieving revision 1.191
retrieving revision 1.192
diff -C2 -d -r1.191 -r1.192
*** xwin.c	20 May 2005 22:09:32 -0000	1.191
--- xwin.c	2 Aug 2005 15:07:35 -0000	1.192
***************
*** 1351,1355 ****
  	uint16 button, flags;
  	uint32 ev_time;
- 	key_translation tr;
  	char str[256];
  	Status status;
--- 1351,1354 ----
***************
*** 1404,1408 ****
  				}
  
! 				DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
  					   get_ksname(keysym)));
  
--- 1403,1407 ----
  				}
  
! 				DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
  					   get_ksname(keysym)));
  
***************
*** 1411,1425 ****
  					break;
  
! 				tr = xkeymap_translate_key(keysym,
! 							   xevent.xkey.keycode, xevent.xkey.state);
! 
! 				if (tr.scancode == 0)
! 					break;
! 
! 				save_remote_modifiers(tr.scancode);
! 				ensure_remote_modifiers(ev_time, tr);
! 				rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
! 				restore_remote_modifiers(ev_time, tr.scancode);
! 
  				break;
  
--- 1410,1415 ----
  					break;
  
! 				xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
! 						  ev_time, True);
  				break;
  
***************
*** 1429,1433 ****
  					      sizeof(str), &keysym, NULL);
  
! 				DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
  					   get_ksname(keysym)));
  
--- 1419,1423 ----
  					      sizeof(str), &keysym, NULL);
  
! 				DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
  					   get_ksname(keysym)));
  
***************
*** 1436,1446 ****
  					break;
  
! 				tr = xkeymap_translate_key(keysym,
! 							   xevent.xkey.keycode, xevent.xkey.state);
! 
! 				if (tr.scancode == 0)
! 					break;
! 
! 				rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
  				break;
  
--- 1426,1431 ----
  					break;
  
! 				xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
! 						  ev_time, False);
  				break;
  



-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.