DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T X

⟦dd0610092⟧ TextFile

    Length: 9290 (0x244a)
    Types: TextFile
    Names: »XKeyBind.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« 
        └─⟦2109abc41⟧ 
            └─ ⟦this⟧ »./X.V10R4/xterm/Xlib/XKeyBind.c« 

TextFile

#include <X/mit-copyright.h>

/* $Header: XKeyBind.c,v 10.8 86/02/01 15:35:46 tony 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>
#ifdef KEYBD
#include "Xdefault.h"
#endif KEYBD

#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 */

#ifdef KEYBD
char *keyboardtype = NULL;
#endif KEYBD

#define RT_INITIAL_SIZE 100  /* initial size of runtime table */
#define RT_INCREMENT 40  /* size to grow by if expanded */

static char *keymapfile = NULL;

/* Redefine the keymap file name and uninitialize the key map... */

void
XResetKeymapFile(str)
    char *str;
{
    if (!str || !*str)
	keymapfile = NULL;
    else {
	keymapfile = malloc(strlen(str) + 1);
	strcpy(keymapfile, str);
    }
    inited = FALSE;
}

static Initialize() {
    int file = -1;
    int filesize;
    unsigned char magic;
    struct stat filestat;
    char *getenv();
    char *filename = keymapfile;
    char *home;
#ifdef KEYBD
    char *kdefault = "default";
    char *keybddir = KEYBDDIR;
    char *keymapstr = "/.Xkeymap";
    int keymapstrlen = strlen(keymapstr);

    inited = TRUE;
    if(filename && (file = open(filename, O_RDONLY, 0)) < 0)
	free(filename);
    /*
     * Check the global char pointer keyboardtype.  If set, try to
     * open a file in KEYBDDIR with the same name.  If not, try the users
     * .Xkeymap file in his home directory.  If none, try the default
     * keymap in KEYBDDIR.
     */
    if (file < 0 && keyboardtype && *keyboardtype) {
	filename = malloc(strlen(keybddir) + strlen(keyboardtype) + 1);
	strcpy(filename, keybddir);
	strcat(filename, keyboardtype);
	if((file = open (filename, O_RDONLY, 0)) < 0)
	    free (filename);
    }
    if (file < 0 && (home = getenv("HOME")) && *home) {	/* try home */
	filename = malloc (strlen(home) + keymapstrlen + 1);
	strcpy (filename, home);
	strcat (filename, keymapstr);
	if((file = open (filename, O_RDONLY, 0)) < 0)
	    free (filename);
    }
    if (file < 0) {
	filename = malloc(strlen(keybddir) + strlen(kdefault) + 1);
	strcpy(filename, keybddir);
	strcat(filename, kdefault);
	file = open (filename, O_RDONLY, 0);
    }
#else KEYBD
    home = getenv ("HOME");
    inited = TRUE;
    if (home) {
	int homelen = strlen (home);
	char *keymapstr = "/.Xkeymap";
	int keymapstrlen = strlen (keymapstr);
	if(!filename) {
	    filename = malloc (homelen + keymapstrlen + 1);
	    strncpy (filename, home, homelen+1);
	    strncat (filename, keymapstr, keymapstrlen);
	}
	file = open (filename, O_RDONLY, 0);
	}
#endif KEYBD
    if (file < 0) {
	free (filename);
    	return;	    /* 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);
	free (filename);
      	return;
	}
    if(keymap)
	free((char *)keymap);
    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;
	    }
    }