nanogui: NanoX changes


Previous by date: 13 Nov 2000 23:00:40 -0000 Re: Microwindows on SuperH, KIM,KYOUNG-IL (HP-Cupertino,ex1)
Next by date: 13 Nov 2000 23:00:40 -0000 Using the keycode driver, peter.igelaus.com.au
Previous in thread:
Next in thread: 13 Nov 2000 23:00:40 -0000 Re: NanoX changes, Greg Haerr

Subject: NanoX changes
From: ####@####.####
Date: 13 Nov 2000 23:00:40 -0000
Message-Id: <Pine.LNX.4.10.10011140928350.5039-600000@helios.devel.igelaus.com.au>

Good morning everyone,
	Here is diffs/files for what I have been working on wrt nanox.

The file "kbd_keycode.c" is a keymode level keyboard driver (AKA medium
raw) for Linux based machines. It converts keycodes to ascii with the help
of the large table in the "qwerty.h" file. I've done it this way so if
people have different keyboard mappings they can make there own include
file. (use the "showkey -k" command to get the keycodes).

The file "keycode.diff" patches the Makefile in the drivers directory to
allow for building of the keycode driver. It also patches the nano-X.h file
in the include directory to map a GR_MODIFIER_SPECIAL to MWKEY_MOD2. This
was done so my app (Mozilla) could get function keys etc. 

The file "srvevent.diff" does two things, firstly it sends keyup events
when we release a key (when using the keycode keyboard driver) and
secondly, it makes the subwid ALWAYS points to the window that the mouse
pointer was in. I did this so I could implement drag and drop between
Mozilla windows. It also, IMHO, is what it should be, because if you read
the comments in the nano-X.h it says subwid = window the pointer was in.

A bit about the driver: It is a hack of the tty driver with not much
changed. Currently it breaks Gregs ideas for keystroke events, but I did
it this way to minimize impact on other code. The function in the driver
only returns the character, and the modifiers. The order of precidence
(excuse my spelling if it is wrong) for modifiers is NUMLOCK is preferred
over all others for the keypad (I do not do the ALT + 3 nums from the
keypad). CTRL over SHIFT over CAPS. Alt is a special one, it prepends an
escape character "0x1b" to the character. I felt that this is not needed
as an application can determine if ALT is down via the modifiers. WRT
CTRL+key, I found that X does not return the CTRL+key ascii code, but
rather sets the CTRL modifier and return the PLAIN ascii code. I have done
the same.

The format of the keymap table: The first three lines of the file are the
keycodes for the CAPSLOCK SCROLLLOCK and NUMLOCK (the driver uses these to
determine when these are set). The struct is mainly for clarity of what
the keymap table holds. The nex line contains the table. Each line
represents a mapping for one keycode. Each line is made up of the
following entries. PLAIN ASCII, SHIFT ASCII, CAPS ASCII, MODIFIER KEY
FLAG, SPECIAL KEY VALUE.

I think if you read the code, you should be able to work out what it does.


srvclip2.diff patches the srvclip2.c file in nanox directory. This causes
a windows regions to be clipped by child windows of that window. This
prevents screen flicker when we have windows upon windows. Now only those
areas visible (ie, not clipped by parnet windows, not clipped by other
windows and not clipped by child windows) are included in the visible
region.

From Peter Hartshorn

--- /work/tmp/microwin/src/nanox/srvevent.c	Thu Nov  2 18:06:13 2000
+++ nanox/srvevent.c	Thu Nov  9 12:16:20 2000
@@ -167,6 +167,7 @@
 	unsigned char	ch;		/* latest character */
 	int		modifiers;	/* latest modifiers */
 	int		keystatus;	/* latest keyboard status */
+	int		keyup;		/* check for keyup */
 
 	/* Read the latest keyboard status: */
 	keystatus = GdReadKeyboard(&ch, &modifiers);
@@ -178,13 +179,20 @@
 		modifiers = 0;
 	}
 
+	keyup = 0;
+	if ((ch & 0x80) != 0) {
+		keyup = 1;
+		ch &= 0x7f;
+	}
+
 	if(keystatus < 0) {
 		if(keystatus == -2)	/* special case for ESC pressed*/
 			GsTerminate();
 		GsError(GR_ERROR_KEYBOARD_ERROR, 0);
 		return FALSE;
 	} else if(keystatus) {		/* Deliver events as appropriate: */	
-		GsDeliverKeyboardEvent(0, GR_EVENT_TYPE_KEY_DOWN,
+		GsDeliverKeyboardEvent(0, keyup ? GR_EVENT_TYPE_KEY_UP :
+				       GR_EVENT_TYPE_KEY_DOWN,
 				       ch, ch, modifiers,
 				       GR_SPECIAL_KEY_NOSPECIAL,
 				       GR_KEYSTROKE_CONTENT_8BIT_PROPER
@@ -286,8 +294,10 @@
 	if (grabbuttonwp) {
 		while ((wp != rootwp) && (wp != grabbuttonwp))
 			wp = wp->parent;
+#if 0
 		if (wp != grabbuttonwp)
 			subwid = grabbuttonwp->id;
+#endif
 		wp = grabbuttonwp;
 	}
 
@@ -383,8 +393,10 @@
 	if (grabbuttonwp) {
 		while ((wp != rootwp) && (wp != grabbuttonwp))
 			wp = wp->parent;
+#if 0
 		if (wp != grabbuttonwp)
 			subwid = grabbuttonwp->id;
+#endif
 		wp = grabbuttonwp;
 	}
 

--- /work/tmp/microwin/src/nanox/srvclip2.c	Tue Oct  3 16:26:02 2000
+++ nanox/srvclip2.c	Tue Oct 31 11:00:55 2000
@@ -133,8 +133,23 @@
 if(pwp == rootwp)
 break;
 	}
-
 	wp = tmpwp;
+
+	sibwp = wp->children;
+	while (sibwp) {
+		if (!(sibwp->unmapcount || !sibwp->output)) {
+			bs = sibwp->bordersize;
+			minx = sibwp->x - bs;
+			miny = sibwp->y - bs;
+			maxx = sibwp->x + sibwp->width + bs;
+			maxy = sibwp->y + sibwp->height + bs;
+
+			GdSetRectRegion(r, minx, miny, maxx, maxy);
+			GdSubtractRegion(vis, vis, r);
+		}
+		sibwp = sibwp->siblings;
+	}
+
 	/*
 	 * Intersect with user region, if set.
 	 */

Only in include/: CVS
diff -u /work/tmp/microwin/src/include/nano-X.h include/nano-X.h
--- /work/tmp/microwin/src/include/nano-X.h	Wed Nov  1 08:17:55 2000
+++ include/nano-X.h	Thu Nov  9 12:29:12 2000
@@ -126,6 +126,7 @@
 
 #define GR_MODIFIER_NUMLOCK     MWKEY_MOD2      /* Numlock = Mod 1 */
 #define	GR_MODIFIER_META	MWKEY_MOD1      /* meta or alt */
+#define GR_MODIFIER_SPECIAL	MWKEY_MOD2	/* special key */
 #define GR_MODIFIER_SCROLLLOCK  MWKEY_MOD5      /* Scroll lock */
 #define	GR_MODIFIER_ANY		MWKEY_ANY	/* any modifier */
 
--- /work/tmp/microwin/src/drivers/Makefile	Tue Oct 10 13:32:46 2000
+++ drivers/Makefile	Wed Nov  8 14:21:54 2000
@@ -197,6 +197,10 @@
 OBJS += kbd_tty.o
 endif
 
+ifeq ($(KEYCODEKBD), Y)
+OBJS += kbd_keycode.o
+endif
+
 ifeq ($(ARCH), FREEBSD-X86)
 #OBJS += kbd_fbsd.o
 OBJS += kbd_tty.o

const unsigned char capslockcode = 0x3a;
const unsigned char scrolllockcode = 0x46;
const unsigned char numlockcode = 0x45;
struct mwKeyMap {
	unsigned char ASCII;	/* ASCII with no modifiers */
	unsigned char sASCII;	/* ASCII with shift */
	unsigned char cASCII;	/* ASCII with caps */
	unsigned char nASCII;	/* ASCII with numlock */
	unsigned char modifier; /* modifier key flag */
	unsigned char spval;	/* value of special keys */
};

const struct mwKeyMap keymap[] = {
	{0x1b,	0x1b,	0x1b,	0x0,	0x0,	0x0}, /* 1 */
	{0x31,	0x21,	0x31,	0x0,	0x0, 	0x0}, /* 2 */
	{0x32,	0x40,	0x32,	0x0,	0x0, 	0x0}, /* 3 */
	{0x33,	0x23,	0x33,	0x0,	0x0, 	0x0}, /* 4 */
	{0x34,	0x24,	0x34,	0x0,	0x0, 	0x0}, /* 5 */
	{0x35,	0x25,	0x35,	0x0,	0x0, 	0x0}, /* 6 */
	{0x36,	0x5e,	0x36,	0x0,	0x0, 	0x0}, /* 7 */
	{0x37,	0x26,	0x37,	0x0,	0x0, 	0x0}, /* 8 */
	{0x38,	0x2a,	0x38,	0x0,	0x0, 	0x0}, /* 9 */
	{0x39,	0x28,	0x39,	0x0,	0x0, 	0x0}, /* 10 */
	{0x30,	0x29,	0x30,	0x0,	0x0, 	0x0}, /* 11 */
	{0x2d,	0x5f,	0x2d,	0x0,	0x0, 	0x0}, /* 12 */
	{0x3d,	0x2b,	0x3d,	0x0,	0x0, 	0x0}, /* 13 */
	{0x7f,	0x7f,	0x7f,	0x0,	0x0, 	0x0}, /* 14 */
	{0x09,	0x09,	0x09,	0x0,	0x0, 	0x0}, /* 15 */
	{0x71,	0x51,	0x51,	0x0,	0x0, 	0x0}, /* 16 */
	{0x77,	0x57,	0x57,	0x0,	0x0, 	0x0}, /* 17 */
	{0x65,	0x45,	0x45,	0x0,	0x0, 	0x0}, /* 18 */
	{0x72,	0x52,	0x52,	0x0,	0x0, 	0x0}, /* 19 */
	{0x74,	0x54,	0x54,	0x0,	0x0, 	0x0}, /* 20 */
	{0x79,	0x59,	0x59,	0x0,	0x0, 	0x0}, /* 21 */
	{0x75,	0x55,	0x55,	0x0,	0x0, 	0x0}, /* 22 */
	{0x69,	0x49,	0x49,	0x0,	0x0, 	0x0}, /* 23 */
	{0x6f,	0x4f,	0x4f,	0x0,	0x0, 	0x0}, /* 24 */
	{0x70,	0x50,	0x50,	0x0,	0x0, 	0x0}, /* 25 */
	{0x5b,	0x7b,	0x5b,	0x0,	0x0, 	0x0}, /* 26 */
	{0x5d,	0x7d,	0x5d,	0x0,	0x0, 	0x0}, /* 27 */
	{0x0d,	0x0d,	0x0d,	0x0,	0x0, 	0x0}, /* 28 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x04,	0x0}, /* 29 */
	{0x61,	0x41,	0x41,	0x0,	0x0, 	0x0}, /* 30 */
	{0x73,	0x53,	0x53,	0x0,	0x0, 	0x0}, /* 31 */
	{0x64,	0x44,	0x44,	0x0,	0x0, 	0x0}, /* 32 */
	{0x66,	0x46,	0x46,	0x0,	0x0, 	0x0}, /* 33 */
	{0x67,	0x47,	0x47,	0x0,	0x0, 	0x0}, /* 34 */
	{0x68,	0x48,	0x48,	0x0,	0x0, 	0x0}, /* 35 */
	{0x6a,	0x4a,	0x4a,	0x0,	0x0, 	0x0}, /* 36 */
	{0x6b,	0x4b,	0x4b,	0x0,	0x0, 	0x0}, /* 37 */
	{0x6c,	0x4c,	0x4c,	0x0,	0x0, 	0x0}, /* 38 */
	{0x3b,	0x3a,	0x3b,	0x0,	0x0, 	0x0}, /* 39 */
	{0x27,	0x22,	0x27,	0x0,	0x0, 	0x0}, /* 40 */
	{0x60,	0x7e,	0x60,	0x0,	0x0, 	0x0}, /* 41 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x01,	0x0}, /* 42 */
	{0x5c,	0x7c,	0x7c,	0x0,	0x0, 	0x0}, /* 43 */
	{0x7a,	0x5a,	0x5a,	0x0,	0x0, 	0x0}, /* 44 */
	{0x78,	0x58,	0x58,	0x0,	0x0, 	0x0}, /* 45 */
	{0x63,	0x43,	0x43,	0x0,	0x0, 	0x0}, /* 46 */
	{0x76,	0x56,	0x56,	0x0,	0x0, 	0x0}, /* 47 */
	{0x62,	0x42,	0x42,	0x0,	0x0, 	0x0}, /* 48 */
	{0x6e,	0x4e,	0x4e,	0x0,	0x0, 	0x0}, /* 49 */
	{0x6d,	0x4d,	0x4d,	0x0,	0x0, 	0x0}, /* 50 */
	{0x2c,	0x3c,	0x3c,	0x0,	0x0, 	0x0}, /* 51 */
	{0x2e,	0x3e,	0x3e,	0x0,	0x0, 	0x0}, /* 52 */
	{0x2f,	0x3f,	0x3f,	0x0,	0x0, 	0x0}, /* 53 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x01,	0x0}, /* 54 */
	{0x2a,	0x2a,	0x2a,	0x2a,	0x0, 	0x0}, /* 55 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x08,	0x0}, /* 56 */
	{0x20,	0x20,	0x20,	0x0,	0x0, 	0x0}, /* 57 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 58 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x01}, /* 59 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x02}, /* 60 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x03}, /* 61 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x04}, /* 62 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x05}, /* 63 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x06}, /* 64 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x07}, /* 65 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x08}, /* 66 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x09}, /* 67 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x0a}, /* 68 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x02,	0x0}, /* 69 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 70 */
	{0x0,	0x0,	0x0,	0x37,	0x10, 	0x67}, /* 71 */
	{0x0,	0x0,	0x0,	0x38,	0x10, 	0x6b}, /* 72 */
	{0x0,	0x0,	0x0,	0x39,	0x10, 	0x65}, /* 73 */
	{0x20,	0x20,	0x20,	0x20,	0x0, 	0x0}, /* 74 */
	{0x0,	0x0,	0x0,	0x34,	0x10, 	0x69}, /* 75 */
	{0x0,	0x0,	0x0,	0x35,	0x0, 	0x0}, /* 76 */
	{0x0,	0x0,	0x0,	0x36,	0x10, 	0x6a}, /* 77 */
	{0x2b, 	0x2b,	0x2b,	0x2b,	0x0, 	0x0}, /* 78 */
	{0x0,	0x0,	0x0,	0x31,	0x10, 	0x68}, /* 79 */
	{0x0,	0x0,	0x0,	0x32,	0x10, 	0x6c}, /* 80 */
	{0x0,	0x0,	0x0,	0x33,	0x10, 	0x66}, /* 81 */
	{0x0,	0x0,	0x0,	0x30,	0x10, 	0x62}, /* 82 */
	{0x0,	0x0,	0x0,	0x2e,	0x10, 	0x63}, /* 83 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 84 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 85 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 86 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x0b}, /* 87 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x0c}, /* 88 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 89 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 90 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 91 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 92 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 93 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 94 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 95 */
	{0x0d,	0x0d,	0x0d,	0x0,	0x0, 	0x0}, /* 96 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x04,	0x0}, /* 97 */
	{0x2f,	0x2f,	0x2f,	0x2f,	0x0, 	0x0}, /* 98 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x0d}, /* 99 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x08,	0x0}, /* 100 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 101 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x67}, /* 102 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x6b}, /* 103 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x65}, /* 104 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x69}, /* 105 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x6a}, /* 106 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x68}, /* 107 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x6c}, /* 108 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x66}, /* 109 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x62}, /* 110 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x63}, /* 111 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 112 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 113 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 114 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 115 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 116 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 117 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 118 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x18}, /* 119 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 120 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 121 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 122 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 123 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0, 	0x0}, /* 124 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x19}, /* 125 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x1a}, /* 126 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x10,	0x1b}, /* 127 */
	{0x0, 	0x0, 	0x0, 	0x0, 	0x0,	0x0} /* 128 */
};

/*
 * Copyright (c) 1999 Greg Haerr ####@####.####
 * Copyright (c) 1991 David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * /dev/tty KEYCODE Keyboard Driver
 */
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include "device.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <sysexits.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
#include <sys/ioctl.h>

#include <qwerty.h>

#if ELKS
#define	KEYBOARD	"/dev/tty1"	/* keyboard associated with screen*/
#else
#define	KEYBOARD	"/dev/tty"	/* keyboard associated with screen*/
#endif

static int  KEYCODE_Open(KBDDEVICE *pkd);
static void KEYCODE_Close(void);
static void KEYCODE_GetModifierInfo(int *modifiers);
static int  KEYCODE_Read(MWUCHAR *buf, int *modifiers);
static int  KEYCODE_Poll(void);

KBDDEVICE kbddev = {
	KEYCODE_Open,
	KEYCODE_Close,
	KEYCODE_GetModifierInfo,
	KEYCODE_Read,
#if _MINIX
	KEYCODE_Poll,
#else
	NULL
#endif
};

static	int		fd;		/* file descriptor for keyboard */
static	struct termios	old;		/* original terminal modes */
static  int		oldkbdmode;	/* original keyboard mode */
static  unsigned char	mods;		/* modifier keys */
static  unsigned char   ledflags;       /* current state of led flags */
static	unsigned char	oldledflags;	/* original led flags */
static	unsigned char	oldledstate;	/* original led state (lights) */ 

/*
 * Open the keyboard.
 * This is real simple, we just use a special file handle
 * that allows non-blocking I/O, and put the terminal into
 * character mode.
 */
static int
KEYCODE_Open(KBDDEVICE *pkd)
{
	struct termios	new;	/* new terminal modes */

	mods = 0;

	fd = open(KEYBOARD, O_NONBLOCK);
	if (fd < 0)
		return -1;

	if (tcgetattr(fd, &old) < 0)
		goto err;

	if (ioctl(fd, KDGKBMODE, &oldkbdmode))
		goto err;

	if (ioctl(fd, KDGETLED, &oldledstate))
		goto err;

	if (ioctl(fd, KDGKBLED, &oldledflags))
		goto err;

	new = old;
	new.c_lflag &= ~(ECHO | ICANON | ISIG);
	new.c_iflag = 0;
	new.c_cc[VMIN] = 1;
	new.c_cc[VTIME] = 1;

	if(tcsetattr(fd, TCSAFLUSH, &new) < 0)
		goto err;

        if (ioctl(fd, KDSKBMODE, K_MEDIUMRAW))
		goto err;

	ledflags = 0;

	if (ioctl(fd, KDSKBLED, ledflags))
		goto err;

	if (ioctl(fd, KDSETLED, ledflags))
		goto err;

	return fd;

err:
	close(fd);
	fd = 0;
	return -1;
}

/*
 * Close the keyboard.
 * This resets the terminal modes.
 */
static void
KEYCODE_Close(void)
{
	ioctl(fd, KDSETLED, oldledstate);
	ioctl(fd, KDSKBLED, oldledflags);
	ioctl(fd, KDSKBMODE, oldkbdmode);
	tcsetattr(fd, TCSANOW, &old);
	close(fd);
	fd = 0;
}

/*
 * Return the possible modifiers for the keyboard.
 */
static  void
KEYCODE_GetModifierInfo(int *modifiers)
{
	*modifiers = mods;
}

void SetLeds(unsigned char changedState)
{
	unsigned char scroll, caps, num;
	unsigned char state;

	ioctl(fd, KDGKBLED, &state);

	scroll = ((state & K_SCROLLLOCK) != 0);
	caps = ((state & K_CAPSLOCK) != 0);
	num = ((state & K_NUMLOCK) != 0);

	if ((changedState & K_SCROLLLOCK) != 0)
		scroll = (scroll == 0);
	if ((changedState & K_CAPSLOCK) != 0)
		caps = (caps == 0);
	if ((changedState & K_NUMLOCK) != 0)
		num = (num == 0);

	ledflags = (scroll + (caps<<1) + (num<<2));

	ioctl(fd, KDSETLED, (scroll + (num<<1) + (caps<<2)));
	ioctl(fd, KDSKBLED, (scroll + (caps<<1) + (num<<2)));
}

/*
 * This reads one keystroke from the keyboard, and the current state of
 * the mode keys (ALT, SHIFT, CTRL).  Returns -1 on error, 0 if no data
 * is ready, and 1 if data was read.  This is a non-blocking call.
 */
static int
KEYCODE_Read(MWUCHAR *buf, int *modifiers)
{
	int	cc;			/* characters read */
	unsigned char	ch;		/* character read */
	unsigned char	check_modifier;	/* modifier check */
	int	keyup;			/* check if key press or release */

	cc = read(fd, &ch, 1);

	if ((cc < 0) && (errno != EINTR) && (errno != EAGAIN)) {
		return -1;
	}
	if (cc == 0)
		return 0;

	keyup = 0;
	if ((ch & 0x80) != 0)
		keyup = 1;

	if ((ch == capslockcode) || (ch == scrolllockcode) ||
	    (ch == numlockcode)) {
		SetLeds((ch == scrolllockcode) +
			((ch == capslockcode)<<1) +
			((ch == numlockcode)<<2));
	}

	*buf = 0;
	if ((ledflags & K_NUMLOCK) != 0)
		*buf = keymap[((int)ch-1) & 0x7f].nASCII;
	if (*buf == 0) {
		if ((ledflags & K_CAPSLOCK) != 0)
			*buf = keymap[((int)ch-1) & 0x7f].cASCII;
		if ((mods & 1) != 0)
			*buf = keymap[((int)ch-1) & 0x7f].sASCII;
	}
	if (*buf == 0)
		*buf = keymap[((int)ch-1) & 0x7f].ASCII;

	if (*buf == 0) {
		check_modifier = keymap[((int)ch-1) & 0x7f].modifier;
		if (check_modifier == 0x10)
			*buf = keymap[((int)ch-1) & 0x7f].spval;
		if (check_modifier != 0) {
			if (keyup)
				mods &= ~check_modifier;
			else
				mods |= check_modifier;
		} else
			return 0;
	}

	*buf |= (keyup<<7);
	*modifiers = mods;

	if(*buf == 0x1b)
		return -2;		/* special case ESC*/
	if ((*buf == 0x70) && ((mods & 0x04) != 0)) {
		GdCaptureScreen("file");
		return 0;
	}
	return 1;
}

static int
KEYCODE_Poll(void)
{
	return 1;	/* used by _MINIX only*/
}

Previous by date: 13 Nov 2000 23:00:40 -0000 Re: Microwindows on SuperH, KIM,KYOUNG-IL (HP-Cupertino,ex1)
Next by date: 13 Nov 2000 23:00:40 -0000 Using the keycode driver, peter.igelaus.com.au
Previous in thread:
Next in thread: 13 Nov 2000 23:00:40 -0000 Re: NanoX changes, Greg Haerr


Powered by ezmlm-browse 0.20.