[gnu.emacs.bug] x-get-mouse-event

steve@HPLSG.HP.COM (Steve Greenbaum) (09/22/89)

Hello,

Function x-get-mouse-event in file x11fns.c in 18.55 has an "Fcond" that
should be "Fcons":

	Vx_mouse_abs_pos = Fcond (tempx, Fcons (tempy, Qnil));
                               ^

There are a few more problems.  One is an inconsistency with
x-proc-mouse-event in the way the meta bit is coded.  The most serious problem
results from this piece of code:

	if (NULL (arg))
		while (!XXm_queue_num)
		      sleep(1);
	/*** ??? Surely you don't mean to busy wait??? */


I don't know the details of emacs' interrupt handling, but exercising this
code, done with "(x-get-mouse-event nil)", hangs emacs.  The button handling
in x11term.c does increment XXm_queue_num, but it acts as if it is not getting
called.  Perhaps It is relevant that I am running HPUX 6.5 on an HP 9000/370.

I changed sleep to Fsit_for, which works ok if no keypress occurs between the
call to x-get-mouse-event (with nil) and the mouse click.  But if you press a
key before clicking the mouse, it hangs.

Below in my version of x-get-mouse-event, and below that is a a diff of my
x11fns.c with the 18.55's (I call it x11fns.c-dist).

++++++++++++++++++++ New version of x-get-mouse-event ++++++++++++++++++++++++

DEFUN ("x-get-mouse-event", Fx_get_mouse_event, Sx_get_mouse_event,
  1, 1, 0,
  "Get next mouse event out of mouse event buffer (com-letter (x y)).\n\
ARG non-nil means return nil immediately if no pending event;\n\
otherwise, wait for an event.")
  (arg)
     Lisp_Object arg;
{
	XEvent event;
	register char com_letter;
	register char key_mask;

	register Lisp_Object tempx;
	register Lisp_Object tempy;
	
	check_xterm ();

	if (NULL (arg))
		while (!XXm_queue_num)
		      /* Bug: if a non-mouse event (from keyboard) occurs */
		      /* before the mouse event, this hangs. */
		      Fsit_for(1, Qnil);   /* This always hangs: sleep(1); */
	/*** ??? Surely you don't mean to busy wait??? */

	if (XXm_queue_num) {
		event = *XXm_queue[XXm_queue_out];
		free (XXm_queue[XXm_queue_out]);
		XXm_queue_out = (XXm_queue_out + 1) % XMOUSEBUFSIZE;
		XXm_queue_num--;
		com_letter = 3-(event.xbutton.button & 3);
		key_mask = (event.xbutton.state & 15) << 4;
		/* Report meta in 2 bit, not in 8 bit.  */
		if (key_mask & 0x80)
		  {
		    key_mask |= 0x20;
		    key_mask &= ~0x80;
		  }
		com_letter |= key_mask;
		if (event.type == ButtonRelease)
			com_letter |= 0x04;
		XSET (tempx, Lisp_Int,
		      min (screen_width-1,
			   max (0, (event.xbutton.x-XXInternalBorder)/
				XXfontw)));
		XSET (tempy, Lisp_Int,
		      min (screen_height-1,
			   max (0, (event.xbutton.y-XXInternalBorder)/
				XXfonth)));
		Vx_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil));
		XSET (tempx, Lisp_Int, event.xbutton.x_root);
		XSET (tempy, Lisp_Int, event.xbutton.y_root);
		Vx_mouse_abs_pos = Fcons (tempx, Fcons (tempy, Qnil));
		Vx_mouse_item = make_number (com_letter);
		return Fcons (com_letter, Fcons (Vx_mouse_pos, Qnil));
	}
	return Qnil;
}

++++++++++++++++++ diff -c x11fns.c x11fns.c-dist +++++++++++++++++++++++++++

*** x11fns.c	Thu Sep 21 09:05:14 1989
--- x11fns.c-dist	Thu Sep 21 08:28:53 1989
***************
*** 610,618 ****
  
  	if (NULL (arg))
  		while (!XXm_queue_num)
! 		      /* Bug: if a non-mouse event (from keyboard) occurs */
! 		      /* before the mouse event, this hangs. */
! 		      Fsit_for(1, Qnil);   /* This always hangs: sleep(1); */
  	/*** ??? Surely you don't mean to busy wait??? */
  
  	if (XXm_queue_num) {
--- 610,616 ----
  
  	if (NULL (arg))
  		while (!XXm_queue_num)
! 			sleep(1);
  	/*** ??? Surely you don't mean to busy wait??? */
  
  	if (XXm_queue_num) {
***************
*** 622,633 ****
  		XXm_queue_num--;
  		com_letter = 3-(event.xbutton.button & 3);
  		key_mask = (event.xbutton.state & 15) << 4;
- 		/* Report meta in 2 bit, not in 8 bit.  */
- 		if (key_mask & 0x80)
- 		  {
- 		    key_mask |= 0x20;
- 		    key_mask &= ~0x80;
- 		  }
  		com_letter |= key_mask;
  		if (event.type == ButtonRelease)
  			com_letter |= 0x04;
--- 620,625 ----
***************
*** 642,649 ****
  		Vx_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil));
  		XSET (tempx, Lisp_Int, event.xbutton.x_root);
  		XSET (tempy, Lisp_Int, event.xbutton.y_root);
! 		Vx_mouse_abs_pos = Fcons (tempx, Fcons (tempy, Qnil));
! 		Vx_mouse_item = make_number (com_letter);
  		return Fcons (com_letter, Fcons (Vx_mouse_pos, Qnil));
  	}
  	return Qnil;
--- 634,640 ----
  		Vx_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil));
  		XSET (tempx, Lisp_Int, event.xbutton.x_root);
  		XSET (tempy, Lisp_Int, event.xbutton.y_root);
! 		Vx_mouse_abs_pos = Fcond (tempx, Fcons (tempy, Qnil));
  		return Fcons (com_letter, Fcons (Vx_mouse_pos, Qnil));
  	}
  	return Qnil;

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Thanks,
	-Steve

  Steve Greenbaum
  HP Labs
  3500 Deer Creek Road
  Palo Alto, CA  94304
  (415) 857-5181
  greenbaum@hplabs.hp.com