[comp.windows.news] moving the mouse with arrow keys

bh@sgi.com (Bent Hagemark) (10/25/89)

Can anyone give me pointers (!) on how to make NeWS
respond to arrow key events by moving the mouse pointer?
I did something similar with X by writing a program
based on XGrabKey and XWarpPointer (hitting uparrow
moved the input focus to the window above).  Didn't
interfere with a concurrently running uwm if you
really did want move your hand over to the mouse,
move it, aim it, and move your hand back to the keyboard. :-)

Bent
bh@sgi.com

don@CS.UMD.EDU (Don Hopkins) (10/26/89)

    Date: 25 Oct 89 16:56:52 GMT
    From: sgi!shinobu!odin!sgi.com!bh@ucbvax.Berkeley.EDU  (Bent Hagemark)
    Subject: moving the mouse with arrow keys
    To: news-makers@brillig.umd.edu

    Can anyone give me pointers (!) on how to make NeWS
    respond to arrow key events by moving the mouse pointer?
    I did something similar with X by writing a program
    based on XGrabKey and XWarpPointer (hitting uparrow
    moved the input focus to the window above).  Didn't
    interfere with a concurrently running uwm if you
    really did want move your hand over to the mouse,
    move it, aim it, and move your hand back to the keyboard. :-)

    Bent
    bh@sgi.com

Here's a program I wrote to do what you describe on a Sun keyboard,
under NeWS 1.1.  You may have to change the key names if you have a
different kind of keyboard.  I haven't tested it under X11/NeWS, but
the principle is probably the same. I think you'd have to detect the
shift keys differently (my guess is that you could sending a message
to ClassKeyboard to look up the symbols of the key codes in the
event's KeyState array, before the case statement). Does anybody know
the "official" way to detect shift keys in X11/NeWS?

Things to do: Make the cursor keys autorepeat. Cursor position stack
for flipping between windows from the keyboard (push current position,
next position, last position, pop position). Make the cursor position
stack record mouse positions relative to the canvas under the cursor
(or the input focus canvas), so the right thing happens even after you
move windows around. Automatically bring the canvas (or its enclosing
frame) to the top when you warp the cursor into it. On the fly journal
macros (like emacs keyboard macros, that replay relative mouse motion,
clicks, and keystrokes) ... Who knows if it would be useful, but it
would be easy enough to try!

	-Don

%!
% Simulate mouse movement and clicks, with shifted keypad arrows
%
% Don Hopkins, University of Maryland Human Computer Interaction Lab
%
% Copyright (C) 1988 by Don Hopkins. All rights reserved.
% This program is provided for unrestricted use, provided that this 
% copyright message is preserved. There is no warranty, and no author 
% or distributer accepts responsibility for any damage caused by this 
% program. 
%
% Fake mouse movement:
%
%   Control: small step (1 point)
%   Shift: medium step (16 points)
%   Meta: big step (100 points)
%
%     R7  R8  R9
%     R10     R12
%     R13 R14 R15
%   
% Fake mouse clicks:
%
%   Control-R11: Left mouse click
%   Shift-R11: Middle mouse click
%   Meta-R11: Right mouse click
%
% Unshifted function keys are just send through.
%

systemdict begin

% Later:
% Express interest in function key UpTransitions some how, leave
% the Action field alone, and just send one event...

/fake-button { % event name => event
  1 index createevent copy		% event name event
  begin					% event name
    /Name exch def			% event
  currentdict end			% event FakeDownEvent
  dup createevent copy			% event FakeDownEvent FakeDownEvent
  sendevent				% event FakeDownEvent
  begin					% event
    /Action /UpTransition def
  currentdict end			% event FakeUpEvent
  sendevent				% event
} def


/push-button {
  true
  1 index /KeyState get {
    { /Control { pop /LeftMouseButton fake-button false exit }
      /Shift { pop /MiddleMouseButton fake-button false exit }
      /Meta { pop /RightMouseButton fake-button false exit }
    } case
  } forall
  { redistributeevent } if
} def

/move-mouse { % event dx dy => event
  gsave
    framebuffer setcanvas
    2 index begin
      /Name /MouseDragged def
      YLocation add /YLocation exch def
      XLocation add /XLocation exch def
      XLocation YLocation setcursorlocation
    currentdict end sendevent
  grestore
} def

/mouse-small-step 1 def
/mouse-medium-step 16 def
/mouse-big-step 100 def

/push-mouse { % event x y => event
  true
  3 index /KeyState get {
    { /Control { pop
        mouse-small-step mul exch mouse-small-step mul exch
	move-mouse false exit }
      /Shift { pop
        mouse-medium-step mul exch mouse-medium-step mul exch
	move-mouse false exit }
      /Meta { pop
        mouse-big-step mul exch mouse-big-step mul exch
	move-mouse false exit }
    } case
  } forall
  { pop pop redistributeevent } if
} def

/FunctionR7 {
  -1 1 push-mouse
} bindkey

/FunctionR8 {
  0 1 push-mouse
} bindkey

/FunctionR9 {
  1 1 push-mouse
} bindkey

/FunctionR10 {
  -1 0 push-mouse
} bindkey

/FunctionR12 {
  1 0 push-mouse
} bindkey

/FunctionR13 {
  -1 -1 push-mouse
} bindkey

/FunctionR14 {
  0 -1 push-mouse
} bindkey

/FunctionR15 {
  1 -1 push-mouse
} bindkey

/FunctionR11 {
  push-button
} bindkey

end % systemdict