/* * Copyright (c) 2002 David Parsons. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * * This product includes software developed by David Parsons * (orc@pell.chi.il.us) * * 4. My name may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY DAVID PARSONS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID * PARSONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /* * keypad() for BSD curses in libc 4.10.0 (ripped out of ndialog) */ #include "curses.h" #include "curses.ext" #include #include #include #include #include static struct { char *key; char **cap; int name; } keywewant[] = { { 0, &K0, KEY_F0 }, { 0, &K1, KEY_F1 }, { 0, &K2, KEY_F2 }, { 0, &K3, KEY_F3 }, { 0, &K4, KEY_F4 }, { 0, &K5, KEY_F5 }, { 0, &K6, KEY_F6 }, { 0, &K7, KEY_F7 }, { 0, &K8, KEY_F8 }, { 0, &K9, KEY_F9 }, { 0, &KD, KEY_DOWN }, { 0, &KL, KEY_LEFT }, { 0, &KR, KEY_RIGHT }, { 0, &KU, KEY_UP }, { "kN", 0, KEY_NPAGE }, { "kP", 0, KEY_PPAGE }, }; #define NR_K (sizeof keywewant/sizeof keywewant[0]) struct keymac { enum { FIN=0, TERM=1, MORE=2 } term; char c; union { struct keymac *next; int key; } u; } ; static int keypad_on = 0; static struct keymac *function_keys = 0; static int keylen_max = 0; static int keylen_min = 9999; #define KHBITS (8*sizeof(long)) static long key_hash[256/KHBITS]; /* * addmac() adds a function key to the macros table */ static struct keymac * addmac(int d, struct keymac *p, char *v, int key) { struct keymac *r; int sz = 0; unsigned char c; if (v == 0 || *v == 0) return p; # ifdef DEBUG fprintf(outf, "%*saddmac(%d,%x,%s,%d)\n", d, "", d, p, unctrl(*v), key); # endif if (p) { for (r = p; r->term; r++) { if (r->c == *v) { if (r->term == MORE) r->u.next = addmac(1+d, r->u.next, 1+v, key); return p; } sz++; } } else { r = p = calloc(3, sizeof p[0]); sz = 0; } if (d == 1) { c = *v; key_hash[c/KHBITS] |= 1<<(c%KHBITS); } r->c = *v; if (v[1]) { r->term = MORE; r->u.next = addmac(1+d, 0, 1+v, key); } else { r->term = TERM; r->u.key = key; if (d < keylen_min) keylen_min = d; if (d > keylen_max) keylen_max = d; } ++r; r->term = 0; return realloc(p, (sz+3)*sizeof p[0]); } int keypad(WINDOW * win, int on) { #if DEBUG fprintf(outf, "keypad(%x, %d)\n", win, on); #endif if (on) { setbuf(stdin, 0); if (KS) _puts(KS); } else if (KE) _puts(KE); keypad_on = on; return 1; } void __macros() { int i; function_keys = 0; /* FIX ME */ for (i=0; i < NR_K; i++) { function_keys = addmac(1,function_keys, keywewant[i].cap ? *(keywewant[i].cap) : getcap(keywewant[i].key), keywewant[i].name); } } int __llgetch() { int c, ct, rc, c2; fd_set fds; struct timeval tick; struct keymac *p; again: c = getchar(); if ( keypad_on && (key_hash[c/KHBITS] & 1<<(c%KHBITS)) ) { /* possible function key */ # ifdef DEBUG fprintf(outf, "__llgetch() - function leadin %s\n", unctrl(c)); # endif ct = 1; for (p = function_keys; p->term && p->c != c; p++) ; switch (p->term) { case FIN: goto again; case TERM: # ifdef DEBUG fprintf(outf, "__llgetch()[1] - return %d\n"< p->u.key); # endif return p->u.key; default: tick.tv_sec = 0; tick.tv_usec = 50000; break; } FD_ZERO(&fds); while (1) { FD_SET(0, &fds); rc = select(1, &fds, 0, 0, &tick); if (rc == 0 || !FD_ISSET(0, &fds)) { # ifdef DEBUG fprintf(outf, "__llgetch() timeout\n"); # endif break; } ct++; c2 = getchar(); # ifdef DEBUG fprintf(outf, "__llgetch() - next char %s\n", unctrl(c2)); # endif for (p = p->u.next; p->term && p->c != c2; p++) ; switch (p->term) { case FIN: goto again; case TERM: # ifdef DEBUG fprintf(outf, "__llgetch() -return %d\n", p->u.key); # endif return p->u.key; default: tick.tv_sec = 0; tick.tv_usec = 25000; break; } } } else if (c == erasechar()) return KEY_BACKSPACE; return c; }