|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T X
Length: 8946 (0x22f2)
Types: TextFile
Names: »XKeyBind.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/Xlib/XKeyBind.c«
#include <X/mit-copyright.h>
/* $Header: XKeyBind.c,v 10.12 86/07/21 15:27:14 wesommer Rel $ */
/* Copyright 1985, Massachusetts Institute of Technology */
#include "XlibInternal.h"
#include <sys/file.h>
#include <sys/stat.h>
#include "Xkeymap.h"
#include "Xkeyboard.h"
#include <stdio.h>
#include <strings.h>
#define EMPTY_ENTRY LeftMask
/* if the "metabits" field of a runtime table entry contains this,
it's an empty entry */
static KeyMapElt *keymap = NULL;
static Bool inited = FALSE;
static ExtensionHeader *ext_begin, *ext_end;
/* Runtime table: contains multiple-byte character bindings defined
at runtime with XRebindCode */
typedef struct {
unsigned char keycode;
unsigned char metabits;
short length;
char *value;
} RuntimeTableEntry;
static RuntimeTableEntry
*rt_begin, /* first entry of runtime table */
*rt_end, /* this and all succeeding entries are empty */
*rt_buf_end;/* points beyond end of allocated storage for table */
#define RT_INITIAL_SIZE 100 /* initial size of runtime table */
#define RT_INCREMENT 40 /* size to grow by if expanded */
XUseKeymap(filename)
char *filename;
{
int file = -1;
int filesize;
unsigned char magic;
struct stat filestat;
file = open (filename, O_RDONLY, 0);
if (file < 0) {
return(0); /* no keymap file found */
}
fstat (file, &filestat);
filesize = filestat.st_size - 1; /* first byte is magic number */
if (filesize < 256*sizeof(KeyMapElt)) {
fprintf (stderr, "Keymap file %s is too small\n", filename);
close (file);
free (filename);
return;
}
read (file, &magic, 1);
if (magic != X_KEYMAP_MAGIC) {
fprintf (stderr,
"Keymap file %s doesn't begin with the proper magic number\n",
filename);
close (file);
return(0);
}
keymap = (KeyMapElt *) malloc (filesize);
if (!keymap) {
close (file);
return(0); /* couldn't malloc; just act like there isn't a keymap */
}
read (file, (char *) keymap, filesize);
ext_begin = (ExtensionHeader *) (keymap + 256);
ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
if (!rt_begin)
_XIOError (_XlibCurrentDisplay);
rt_end = rt_begin;
rt_buf_end = rt_begin + RT_INITIAL_SIZE;
close (file);
inited = TRUE;
return(1);
}
static Initialize() {
int file;
int filesize;
unsigned char magic;
struct stat filestat;
char *getenv();
char *filename;
char *home = getenv ("HOME");
inited = TRUE;
if (home) {
int homelen = strlen (home);
char *keymapstr = "/.Xkeymap";
int keymapstrlen = strlen (keymapstr);
filename = malloc (homelen + keymapstrlen + 1);
strncpy (filename, home, homelen+1);
strncat (filename, keymapstr, keymapstrlen);
file = open (filename, O_RDONLY, 0);
if (file < 0) {
free (filename);
return; /* no keymap file found */
}
}
else
return; /* no home directory to find keymap file in! */
fstat (file, &filestat);
filesize = filestat.st_size - 1; /* first byte is magic number */
if (filesize < 256*sizeof(KeyMapElt)) {
fprintf (stderr, "Keymap file %s is too small\n", filename);
close (file);
free (filename);
return;
}
read (file, &magic, 1);
if (magic != X_KEYMAP_MAGIC) {
fprintf (stderr,
"Keymap file %s doesn't begin with the proper magic number\n",
filename);
close (file);
free (filename);
return;
}
keymap = (KeyMapElt *) malloc (filesize);
if (!keymap) {
close (file);
free (filename);
return; /* couldn't malloc; just act like there isn't a keymap */
}
read (file, (char *) keymap, filesize);
ext_begin = (ExtensionHeader *) (keymap + 256);
ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
if (!rt_begin)
_XIOError (_XlibCurrentDisplay);
rt_end = rt_begin;
rt_buf_end = rt_begin + RT_INITIAL_SIZE;
free (filename);
close (file);
}
/* this routine is used when initialization failed to find a
valid keymap file */
static char *BackstopLookupMapping (event, nbytes)
XKeyPressedEvent *event;
int *nbytes;
{
int detail = event->detail;
register int keycode = detail & ValueMask;
extern KeyMapEntry StdMap[];
static char c;
short s; /* needed to distinguish a real character (e.g. \0377) from -1 */
s = StdMap [keycode] [KeyState(detail)];
c = s;
if ((detail & ShiftLockMask) && (c >= 'a') && (c <= 'z'))
c += ('A' - 'a');
if (IsTypewriterKey(keycode)
|| keycode == KC_ESC || keycode == KC_BS || keycode == KC_LF)
*nbytes = (s == -1 ? 0 : 1);
else
*nbytes = 0;
return (&c);
}
char *XLookupMapping (event, nbytes)
XKeyPressedEvent *event;
int *nbytes;
{
int detail = event->detail;
unsigned int metabits = FullKeyState (detail);
unsigned int key = detail & ValueMask;
register unsigned char *the_char;
if (!inited)
Initialize();
if (!keymap)
return (BackstopLookupMapping (event, nbytes));
the_char = &keymap [key] [metabits];
switch (*the_char) {
case UNBOUND: {
*nbytes = 0;
return (NULL);
}
case EXTENSION_BOUND: {
register ExtensionHeader *this;
for (this = ext_begin; this < ext_end; NextExtension(this))
if ((key == this->keycode)
&& ((metabits == this->metabits) || (this->metabits == DontCareMetaBits))) {
*nbytes = this->length;
return ((char *)this + ExtensionHeaderSize);
}
/* if we get here, no match was found in the table extension */
*nbytes = 0;
return (NULL);
}
case RUNTIME_TABLE_BOUND: {
register RuntimeTableEntry *entry;
for (entry = rt_begin; entry < rt_end; entry++)
if ((key == entry->keycode)
&& ((metabits == entry->metabits) || (entry->metabits == DontCareMetaBits))) {
*nbytes = entry->length;
return (entry->value);
}
/* if we get here, no match was found in the runtime table */
*nbytes = 0;
return (NULL);
}
default: {
*nbytes = 1;
return ((char *)the_char);
}
}
}
XRebindCode (keycode, metabits, str, nbytes)
unsigned int keycode, metabits;
char *str;
int nbytes;
{
unsigned char *table_char;
metabits = FullKeyState (metabits); /* shift meta bits to rightmost four bits */
if (!inited)
Initialize();
if (!keymap)
return; /* no keymap file; what else can I do? */
table_char = &keymap [keycode] [metabits];
if (nbytes == 0) {
if (*table_char == RUNTIME_TABLE_BOUND)
Unbind (keycode, metabits);
*table_char = UNBOUND;
return;
}
if ((nbytes == 1) && SingleCharBound (*str)) {
if (*table_char == RUNTIME_TABLE_BOUND)
Unbind (keycode, metabits);
*table_char = *str;
return;
}
/* the new binding is either multi-character, or one of the
three reserved special characters */
if (*table_char == RUNTIME_TABLE_BOUND) {
/* entry is already in table; just change its binding */
register RuntimeTableEntry *entry;
for (entry = rt_begin; entry < rt_end; entry++)
if (keycode == entry->keycode && metabits == entry->metabits) {
entry->value = str;
entry->length = nbytes;
return;
}
/* if we get here, entry wasn't found in table; shouldn't
* ever happen! Not much to do but fall through to
* the following code. */
}
/* new binding must go in a new entry in the table */
*table_char = RUNTIME_TABLE_BOUND;
if (rt_end < rt_buf_end) {
rt_end->keycode = keycode;
rt_end->metabits = metabits;
rt_end->value = str;
rt_end++->length = nbytes;
return;
}
/* no room at end of table; look for holes in middle */
{
register RuntimeTableEntry *entry;
for (entry = rt_begin; entry < rt_end; entry++)
if (entry->metabits == EMPTY_ENTRY) {
entry->keycode = keycode;
entry->metabits = metabits;
entry->value = str;
entry->length = nbytes;
return;
}
}
/* no room in table at all. Must expand it. */
{
int rt_length = rt_end - rt_begin;
rt_begin = (RuntimeTableEntry *) realloc ((char *)rt_begin, (rt_length+RT_INCREMENT)*sizeof (RuntimeTableEntry));
rt_end = rt_begin + rt_length;
rt_buf_end = rt_end + RT_INCREMENT;
rt_end->keycode = keycode;
rt_end->metabits = metabits;
rt_end->value = str;
rt_end++->length = nbytes;
}
}
static Unbind (keycode, metabits)
unsigned int keycode, metabits;
{
register RuntimeTableEntry *entry;
for (entry = rt_begin; entry < rt_end; entry++)
if (keycode == entry->keycode && metabits == entry->metabits) {
entry->metabits = EMPTY_ENTRY;
return;
}
}