nanogui: Input event insertion from user apps


Previous by date: 16 May 2000 15:09:36 -0000 FLTK, Jean-Nicolas Pouliot
Next by date: 16 May 2000 15:09:36 -0000 [Nano-X] Compile with c++, Murphy Chen
Previous in thread:
Next in thread: 16 May 2000 15:09:36 -0000 Re: Input event insertion from user apps, Greg Haerr

Subject: Input event insertion from user apps
From: Morten Rolland ####@####.####
Date: 16 May 2000 15:09:36 -0000
Message-Id: <39217290.FD999147@screenmedia.no>

Hello all,

   In the (seemingly) neverending effort to improve nano-X and
the engine/drivers, we (Screen Media) have now identified what
is probably an improvement of the flexibility of input
handeling in nano-X and better features/specs for the API.
The essense of this patch is important to us, at least.

Here goes:

   We need a separate process to handle input from mouse and
keyboard.  There are several reasons; the on-screen keyboard
will deliver keyboard input outside of the linux console or
X11 system, so we need a way to feed this information directly
to nano-X.
   When implementing this code, we realised that our rapidly
changing touch driver could also be moved to the input driver
and thus make it less of a hassle to integrate it with new
versions of nano-X (the driver is very hardware centric, and
based on strange hardware and probably has no place in
mainstream Nano-X).
   When patching this part of Nano-X, we also took the liberty
to change the KEYSTROKE event structure to handle extended
character sets better, e.g. unicode.  A great deal of thought
went into trying to make it as backward compatible as possible
(but not binary compatible), full featured in terms of Unicode
support and easy to use.  I will appreciate any comments on
the proposal.  I will describe the patch in the following.

The following variables are now defined in the GR_EVENT_KEYSTROKE
event structure (others with same semantic as before not listed):

  GR_UNICODE uch;         /* 32-bit Unicode keystroke */
  unsigned int special;   /* Special keys */
  GR_CHAR ch;             /* 8-bit keystroke */
  unsigned char content;  /* What variables are valid */

OK, this seems complicated but will actually help application
developers a lot.  This is how it works:

When a keystroke event is delivered, it may contain different
kinds of information, depending on what key in what situation
was pressed.  The 'content' variable is a bit-field indicating
which of the other variables are valid, and what they contain.
The content variable indicates if the event contains:

   GR_KEYSTROKE_CONTENT_8BIT_PROPER
   GR_KEYSTROKE_CONTENT_8BIT_CTRLSEQ
   GR_KEYSTROKE_CONTENT_UNICODE_PROPER
   GR_KEYSTROKE_CONTENT_UNICODE_CTRLSEQ
   GR_KEYSTROKE_CONTENT_SPECIAL

Each of the variables 'ch' (8BIT) and 'uch' (UNICODE, 32-bit)
are either 'proper' in the sense that it is a real character,
or recognized as a control or escape sequence.  If they are
recognized as control sequences by nano-X or whoever delivered
the events to nano-X, the 'special' variable may hold a value
identifying a common key or switch or whatever that is
identified as "special" (like function keys, arrows etc.)

The reason for distinguishing between control and proper
characters would be for the benefit of applications:  Some
applications like terminal emulators may want to get the
data from the keyboard "as is", e.g. does not care if they
are proper or control sequences, while other applications
may want nano-X to decode function keys for them, while yet
others may only be interested in proper 8-bit keys.

The only backward compatibility problem that I have identified
arises when a key is pressed that has a unicode value, but no
8-bit value:  The content variable should indicate that there is
no valid 8-bit character, but an application that does not test
the content variable will read a '?' character (or other) to
indicate a "strange" character.

This is how we would like to handle the problem of unicode
input support, and I think it is a clean way to do it.  The
reason why we have not used "very high" unicode values for
the function keys and arrow keys etc. and instead uses the
'special' variable is so that we can produce an event that
says:

      1) Special key "NUMERIC-KEYBOARD-4" pressed
      2) ASCII key "4" pressed
      4) Unicode key "4" pressed

And programs that don't need the detailed information can make
use of the less detailed information automatically, e.g. test
for special keys first; none that we care about, ok then check
unicode or ascii depending on needs.

The backspace is a good example of this, its special code
will (should) uniquely identify it as "Backspace", while the
8-bit (proper) character could be ^H.

The API changes to get this implemented is the introduction
of two new functions, both using a single protocol structure
that ships the data of the event to the Nano-X server.  The
prototypes are:

void GrInjectPointerEvent(MWCOORD x, MWCOORD y,
                          int button, int visible);
void GrInjectKeyboardEvent(GR_UNICODE uch, GR_CHAR ch, int modif,
                           int special, unsigned char content);

The "visible" flag to GrInjectPointerEvent indicates if the pointer
should be visible or not; make it visible when pointer is mouse,
don't show it for touch screens.  This will be detected and
handeled on the fly in our "input server" that will also take
input from a mouse (and a standard keyboard) in addition to
touch panel and on-screen keyboard for characters.

I'm not sure if I have implemented the "visible" functionality
correctly, though; it works for me with the NULL-kbd driver, but
it seems to use a reference count system that I don't understand.
Is this for applications to decide visibility?

Also, the linux console escape sequences are not decoded like I
describe in this mail, as I want to hear your opinions first.
I have a fully working standalone program that implements the
escape sequence detection for all keys on my Linux system that
I can port as a followup to this first effort to redefine the
API if I get the GA.

This got long again, I hope some of you followed me through it
and would care to comment if I have missed anything.  The patch
is attached, it is against 0.88pre6b - I have not looked at
pre7 yet - let me know if it doesn't patch cleanly and I'll
fix it.

At the end of this mail I inlclude a relevant section from
the nano-X.h file.

NOTE: One thing to keep in mind is the modifiers and the
KEY_UP event which seems to me is not used now for the
tty driver.

Best Regards,
Morten Rolland, Screen Media

PS: I put in some comments in srvnet.c so that all the function
pointers have a comment with its protocol number - usefull when
debugging incompatible nano-X servers and clients...:-/

PPS: The nano-X binary and shared library should have some sort
identification string that is recognised by 'ident' and produce
the proper nano-X version.

PPPS: When a client first connects to the nano-X server, the
client should tell the server what version it is, and the
server should make a quick compare or table lookup and report
if the two versions are compatible, so the client can give
errors or warnings as appropriate.  I have had a little too
many versions lying around, each one designed for a different
purpose.... Not the average situation I guess but nice all the
same.  Anyway, this is for later.

--------

/* Event for a keystroke typed for the window with has focus. */
typedef struct {
  GR_EVENT_TYPE type;		/* event type */
  GR_WINDOW_ID wid;		/* window id event delived to */
  GR_WINDOW_ID subwid;		/* sub-window id (pointer was in) */
  GR_COORD rootx;		/* root window x coordinate */
  GR_COORD rooty;		/* root window y coordinate */
  GR_COORD x;			/* window x coordinate of mouse */
  GR_COORD y;			/* window y coordinate of mouse */
  int buttons;			/* current state of buttons */
  int modifiers;		/* modifiers (SHIFT, CTRL, etc) */
  GR_UNICODE uch;		/* 32-bit Unicode keystroke */
  unsigned int special;		/* Special keys */
  GR_CHAR ch;			/* 8-bit keystroke */
  unsigned char content;	/* What variables are valid */
} GR_EVENT_KEYSTROKE;

/* These are the bits of the GR_EVENT_KEYSTROKE variable 'content' */

#define GR_KEYSTROKE_CONTENT_8BIT_PROPER	0x01
#define GR_KEYSTROKE_CONTENT_8BIT_CTRLSEQ	0x02
#define GR_KEYSTROKE_CONTENT_UNICODE_PROPER	0x04
#define GR_KEYSTROKE_CONTENT_UNICODE_CTRLSEQ	0x08
#define GR_KEYSTROKE_CONTENT_SPECIAL		0x10

/*
 * The idea is to mark every keystroke event with what kind of
 * information is available in the event.  For instance, when the
 * user presses a function key, like F10 and then 'A' on the Linux
 * console, the following sequence of events should be generated:
 *
 *                          Time ====>
 *
 * ch                       ESC    [      2      1      ~      A
 * uch                      27     91     50     49     126    65
 * special                  0      0      0      0      10     0
 * content/8BIT_PROPER      0      0      0      0      0      1
 * content/8BIT_CTRLSEQ     1      1      1      1      1      0
 * content/UNICODE_PROPER   0      0      0      0      0      1
 * content/UNICODE_CTRLSEQ  1      1      1      1      1      0
 * content/SPECIAL          0      0      0      0      1      0
 *
 * special=0: GR_SPECIAL_KEY_NOSPECIAL
 * special=10: GR_SPECIAL_KEY_F10
 *
 * As can be seen here, an application that does not test the 'content'
 * variable will receive a stream of characters on the 8-bit 'ch'
 * variable.  However, when a unicode character with no 8-bit equivalent
 * is typed, we will have ch='?' and content/8BIT_PROPER = 0.
 *
 * E.g. an application that does not test the content variable may
 * produce spurious '?' for unicode characters and escape sequences
 * for function keys.
 *
 * The allready decoded and easily available information should
 * enchourage application programmers to put some simple logic into
 * programs to handle keyboard events properly (e.g. ignore a
 * key event if it is not 8-bit proper or is part of a control
 * sequence if only 8-bit characters are supported).
 */

/* These are the bits of the GR_EVENT_KEYSTROKE variable 'special' */
#define GR_SPECIAL_KEY_NOSPECIAL	0
#define GR_SPECIAL_KEY_F1		1
#define GR_SPECIAL_KEY_F2		2
#define GR_SPECIAL_KEY_F3		3
#define GR_SPECIAL_KEY_F4		4
#define GR_SPECIAL_KEY_F5		5
#define GR_SPECIAL_KEY_F6		6
#define GR_SPECIAL_KEY_F7		7
#define GR_SPECIAL_KEY_F8		8
#define GR_SPECIAL_KEY_F9		9
#define GR_SPECIAL_KEY_F10		10
#define GR_SPECIAL_KEY_F11		11
#define GR_SPECIAL_KEY_F12		12

#define GR_SPECIAL_KEY_NUM0		48
#define GR_SPECIAL_KEY_NUM1		49
#define GR_SPECIAL_KEY_NUM2		50
#define GR_SPECIAL_KEY_NUM3		51
#define GR_SPECIAL_KEY_NUM4		52
#define GR_SPECIAL_KEY_NUM5		53
#define GR_SPECIAL_KEY_NUM6		54
#define GR_SPECIAL_KEY_NUM7		55
#define GR_SPECIAL_KEY_NUM8		56
#define GR_SPECIAL_KEY_NUM9		57

#define GR_SPECIAL_KEY_NUM_PERIOD	64
#define GR_SPECIAL_KEY_NUM_ENTER	65
#define GR_SPECIAL_KEY_NUM_PLUSS	66
#define GR_SPECIAL_KEY_NUM_MINUS	67
#define GR_SPECIAL_KEY_NUM_STAR		68
#define GR_SPECIAL_KEY_NUM_SLASH	69

#define GR_SPECIAL_KEY_ESC		96
#define GR_SPECIAL_KEY_TAB		97
#define GR_SPECIAL_KEY_INSERT		98
#define GR_SPECIAL_KEY_DELETE		99
#define GR_SPECIAL_KEY_BACKSPACE	100
#define GR_SPECIAL_KEY_PAGEUP		101
#define GR_SPECIAL_KEY_PAGEDOWN		102
#define GR_SPECIAL_KEY_HOME		103
#define GR_SPECIAL_KEY_END		104
#define GR_SPECIAL_KEY_ARROW_LEFT	105
#define GR_SPECIAL_KEY_ARROW_RIGHT	106
#define GR_SPECIAL_KEY_ARROW_UP		107
#define GR_SPECIAL_KEY_ARROW_DOWN	108

[Content type application/octet-stream not shown. Download]

Previous by date: 16 May 2000 15:09:36 -0000 FLTK, Jean-Nicolas Pouliot
Next by date: 16 May 2000 15:09:36 -0000 [Nano-X] Compile with c++, Murphy Chen
Previous in thread:
Next in thread: 16 May 2000 15:09:36 -0000 Re: Input event insertion from user apps, Greg Haerr


Powered by ezmlm-browse 0.20.