Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Configurable keymapping

  • Loading branch information...
commit 62617ffc09802a764bcf2f396aa55ab8832e98dd 1 parent 8ee9802
ec429 authored
View
1  .gitignore
@@ -5,5 +5,6 @@ quirc
*.tar.gz
*.tgz
genconfig
+genkeymap
version.h
View
17 Makefile
@@ -60,10 +60,10 @@ buffer.h: config.h version.h
config.o: config.c config.h names.h bits.h colour.h text.h version.h
-config.c: config_check.c config_def.c config_need.c config_rcread.c config_pargs.c config_help.c
+config.c: config_check.c config_def.c config_need.c config_rcread.c config_pargs.c config_help.c keymap.c
touch config.c
-config.h: config_globals.h version.h
+config.h: config_globals.h version.h keymod.h
touch config.h
config_%: config.cdl genconfig
@@ -71,7 +71,10 @@ config_%: config.cdl genconfig
genconfig: genconfig.c
-input.o: input.c input.h ttyesc.h names.h buffer.h irc.h bits.h
+input.h: keymod.h
+ touch input.h
+
+input.o: input.c input.h ttyesc.h names.h buffer.h irc.h bits.h config.h
input.c: config_set.c
touch input.c
@@ -83,6 +86,14 @@ script.o: script.c script.h bits.h buffer.h
c_init.c: colour.d c_init.awk
$(AWK) -f c_init.awk colour.d > c_init.c
+genkeymap: genkeymap.c
+
+keymod.h: keys genkeymap
+ ./genkeymap h < keys > $@ || (rm $@ && false)
+
+keymap.c: keys genkeymap
+ ./genkeymap c < keys > $@ || (rm $@ && false)
+
FORCE:
version.h: FORCE
./gitversion
View
37 README
@@ -1,13 +1,13 @@
****** quIRC: readme ******
-** quIRC is a simple terminal-based IRC (Internet Relay Chat) client. It is
-written in C. **
+** quIRC is a lightweight terminal-based IRC client. It is written in C. **
***** Contents *****
* Further_Help
* Commands
* Configuration
* Input_Controls
* Other_Controls
+ * Keymapping
* Tab_strip
* Troubleshooting
***** Further Help *****
@@ -116,11 +116,13 @@ the channel (or nick if current tab is a private messaging tab).
Sorts the tab list into an intuitive order (grouping channels after their
parent servers; maintaining the order of the servers and of each server's
channels).
+ //[msg]
+ Sends /msg to the channel.
***** Configuration *****
quIRC can be configured through an "rc file" as follows. (For a compact
reference table see config_ref.htm)
-In your home directory (/home/username), create a file called ".quirc", and
-open it in your editor.
+In your home directory (/home/username), create a folder called ".quirc", a
+file within that folder called "rc", and open it in your editor.
In this file you can set servers, nick and channels to automatically use:
nick global-nickname
ignore -options global-ignore
@@ -254,8 +256,27 @@ These are based, broadly, on bash's controls.
Ctrl-left
Ctrl-right
Change tab.
- Alt-[#], where [#] is a number key
- Equivalent to /tab [#]
+ F1 through F12
+ Equivalent to /tab #, except that F12 is /tab 0.
+***** Keymapping *****
+quIRC's mapping of function and other special keys defaults to a VT100 mapping,
+such as used by xterm and rxvt. However, this mapping can be changed with a
+file /home/username/.quirc/keys.
+To change key mappings, add lines of the form MODNAME hex. The MODNAMEs
+expected are those which appear in the "keys" file in the quIRC source
+directory; at present, these are:
+BS, UP, DOWN, LEFT, RIGHT, HOME, END, DELETE, PGUP, PGDN, CUP, AUP, CDOWN,
+ADOWN, CLEFT, ALEFT, CRIGHT, ARIGHT, CHOME, AHOME, CEND, AEND, CPGUP, APGUP,
+CPGDN, APGDN, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, and F12.
+The prefix 'C' refers to Ctrl, and 'A' to Alt.
+If, for instance, your terminal sends Ctrl-Left as ^[OD, you would add the
+following line:
+CLEFT 1b4f44
+Similarly, if your terminal sends backspace as ^H, you would add:
+BS 08
+You can find out what sequences your terminal sends for various keys by running
+a hex-dump program such as xxd or hd, pressing the key, and noting the output.
+(You will usually need to press first the key, then enter/return, then ^D)
***** Tab strip *****
The strip of tabs along the bottom of the screen has various indicators.
The parens bracketing the name tell you what kind of tab it is:
@@ -285,3 +306,7 @@ turns yellow.
positioning). For details see your terminal emulator's documentation; it
is known that xterm works out-of-the-box, and that PuTTY has an option to
enable VT100 support.
+ The control keys/cursor keys/function keys don't do anything!
+ This probably means your terminal isn't sending VT100 (ANSI) escape
+ sequences, but rather some other set of sequences. See the section
+ "Keymapping", above.
View
94 config.c
@@ -8,6 +8,100 @@
#include "config.h"
+#include "keymap.c"
+
+void loadkeys(FILE *fp)
+{
+ if(!fp) return;
+ while(!feof(fp))
+ {
+ char *line=fgetl(fp);
+ if(line)
+ {
+ if((*line)&&(*line!='#'))
+ {
+ keymod new;
+ new.name=strtok(line, " \t");
+ char *mod=strtok(NULL, " \t");
+ if(!mod)
+ {
+ char msg[32+strlen(new.name)];
+ sprintf(msg, "keys: missing mod in %s", new.name);
+ asb_failsafe(c_err, msg);
+ free(line);
+ continue;
+ }
+ off_t o=strlen(mod);
+ if(o&1)
+ {
+ char msg[32+strlen(new.name)];
+ sprintf(msg, "keys: odd mod length in %s", new.name);
+ asb_failsafe(c_err, msg);
+ free(line);
+ continue;
+ }
+ new.mod=malloc((o>>1)+1);
+ if(!new.mod)
+ {
+ char msg[32+strlen(new.name)];
+ sprintf(msg, "keys: malloc failure in %s", new.name);
+ asb_failsafe(c_err, msg);
+ free(line);
+ continue;
+ }
+ bool cont=false;
+ for(int i=0;i<o;i+=2)
+ {
+ if(!(isxdigit(mod[i])&&isxdigit(mod[i+1])))
+ {
+ char msg[32+strlen(new.name)];
+ sprintf(msg, "keys: bad mod (not hex) in %s", new.name);
+ asb_failsafe(c_err, msg);
+ free(line);
+ cont=true;
+ break;
+ }
+ char buf[3];buf[0]=mod[i];buf[1]=mod[i+1];buf[2]=0;
+ unsigned int c;
+ if(sscanf(buf, "%x", &c)!=1)
+ {
+ char msg[32+strlen(new.name)];
+ sprintf(msg, "keys: sscanf failed in %s", new.name);
+ asb_failsafe(c_err, msg);
+ free(line);
+ cont=true;
+ break;
+ }
+ new.mod[i>>1]=c;
+ }
+ if(cont) continue;
+ new.mod[o>>1]=0;
+ bool match=false;
+ for(int i=0;i<nkeys;i++)
+ {
+ if(strcmp(new.name, kmap[i].name)==0)
+ {
+ free(kmap[i].mod);
+ kmap[i].mod=strdup(new.mod);
+ match=true;
+ }
+ }
+ if(!match)
+ {
+ char msg[32+strlen(new.name)];
+ sprintf(msg, "keys: unrecognised name %s", new.name);
+ asb_failsafe(c_err, msg);
+ }
+ free(new.mod);
+ }
+ free(line);
+ }
+ else
+ break;
+ }
+ return;
+}
+
#include "config_check.c"
int def_config(void)
View
5 config.h
@@ -39,6 +39,7 @@ servlist;
#include "text.h"
#include "version.h"
#include "buffer.h"
+#include "keymod.h"
// global settings & state
#include "config_globals.h"
@@ -47,7 +48,11 @@ char *username, *fname, *nick, *portno;
servlist *servs;
name *igns;
char *version;
+int nkeys;
+keymod *kmap;
+int initkeys(void);
+void loadkeys(FILE *);
int conf_check(void); // writes diagnostics to start-buffer
int def_config(void); // set these to their defaults
int rcread(FILE *rcfp); // read & parse the rc file.
View
19 distMakefile
@@ -8,7 +8,7 @@ PREFIX ?= /usr/local
LIBS := ttyraw.o ttyesc.o irc.o bits.o colour.o buffer.o names.o config.o input.o
INCLUDE := ttyraw.h ttyesc.h irc.h bits.h colour.h buffer.h names.h config.h input.h quirc.h version.h
-all: quirc
+all: quirc doc
install: all
install -D -m0755 quirc $(PREFIX)/bin/quirc
@@ -59,10 +59,10 @@ buffer.h: config.h version.h
config.o: config.c config.h names.h bits.h colour.h text.h version.h
-config.c: config_check.c config_def.c config_need.c config_rcread.c config_pargs.c config_help.c
+config.c: config_check.c config_def.c config_need.c config_rcread.c config_pargs.c config_help.c keymap.c
touch config.c
-config.h: config_globals.h version.h
+config.h: config_globals.h version.h keymod.h
touch config.h
config_%: config.cdl genconfig
@@ -70,7 +70,10 @@ config_%: config.cdl genconfig
genconfig: genconfig.c
-input.o: input.c input.h ttyesc.h names.h buffer.h irc.h bits.h
+input.h: keymod.h
+ touch input.h
+
+input.o: input.c input.h ttyesc.h names.h buffer.h irc.h bits.h config.h
input.c: config_set.c
touch input.c
@@ -82,3 +85,11 @@ script.o: script.c script.h bits.h buffer.h
c_init.c: colour.d c_init.awk
$(AWK) -f c_init.awk colour.d > c_init.c
+genkeymap: genkeymap.c
+
+keymod.h: keys genkeymap
+ ./genkeymap h < keys > $@ || (rm $@ && false)
+
+keymap.c: keys genkeymap
+ ./genkeymap c < keys > $@ || (rm $@ && false)
+
View
172 genkeymap.c
@@ -0,0 +1,172 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef struct
+{
+ char *name;
+ char *mod;
+}
+keymod;
+
+char * fgetl(FILE *); // gets a line of string data; returns a malloc-like pointer
+void init_char(char **buf, int *l, int *i); // initialises a string buffer in heap. *buf becomes a malloc-like pointer
+void append_char(char **buf, int *l, int *i, char c); // adds a character to a string buffer in heap (and realloc()s if needed)
+
+int main(int argc, char **argv)
+{
+ if(argc!=2)
+ {
+ fprintf(stderr, "Usage: genkeymap {c|h}\n");
+ return(EXIT_FAILURE);
+ }
+ int mode=0;
+ if(strcmp(argv[1], "c")==0)
+ mode=1;
+ else if(strcmp(argv[1], "h")==0)
+ mode=2;
+ if(!mode)
+ {
+ fprintf(stderr, "Usage: genkeymap {c|h}\n");
+ return(EXIT_FAILURE);
+ }
+ int nkeys=0;
+ keymod *keys=NULL;
+ while(!feof(stdin))
+ {
+ char *line=fgetl(stdin);
+ if(line)
+ {
+ if((*line)&&(*line!='#'))
+ {
+ keymod new;
+ new.name=strdup(strtok(line, " \t"));
+ char *mod=strtok(NULL, "");
+ off_t o=strlen(mod);
+ if(o&1)
+ {
+ fprintf(stderr, "genkeymap: bad line (o&1) %s\t%s\n", new.name, mod);
+ return(EXIT_FAILURE);
+ }
+ new.mod=malloc((o>>1)+1);
+ for(int i=0;i<o;i+=2)
+ {
+ if(!(isxdigit(mod[i])&&isxdigit(mod[i+1])))
+ {
+ fprintf(stderr, "genkeymap: bad line (not hex) %s\t%s\n", new.name, mod);
+ return(EXIT_FAILURE);
+ }
+ char buf[3];buf[0]=mod[i];buf[1]=mod[i+1];buf[2]=0;
+ unsigned int c;
+ if(sscanf(buf, "%x", &c)!=1)
+ {
+ fprintf(stderr, "genkeymap: bad line (sscanf) %s\t%s\n", new.name, mod);
+ return(EXIT_FAILURE);
+ }
+ new.mod[i>>1]=c;
+ }
+ new.mod[o>>1]=0;
+ int n=nkeys++;
+ (keys=realloc(keys, nkeys*sizeof(keymod)))[n]=new;
+ }
+ free(line);
+ }
+ else
+ break;
+ }
+ switch(mode)
+ {
+ case 1:
+ printf("#include <stdbool.h>\n\n");
+ printf("int initkeys(void)\n{\n");
+ printf("\tnkeys=%d;\n", nkeys);
+ printf("\tkmap=malloc(nkeys*sizeof(keymod));\n");
+ printf("\tif(!kmap) return(1);\n");
+ for(int i=0;i<nkeys;i++)
+ {
+ printf("\tkmap[%d].name=\"%s\";\n", i, keys[i].name);
+ printf("\tkmap[%d].mod=malloc(%d);\n", i, strlen(keys[i].mod)+1);
+ for(unsigned int j=0;j<=strlen(keys[i].mod);j++)
+ {
+ printf("\tkmap[%d].mod[%d]=%hhd;\n", i, j, keys[i].mod[j]);
+ }
+ }
+ printf("\treturn(0);\n");
+ printf("}\n");
+ break;
+ case 2:
+ printf("#pragma once\n\ntypedef struct\n{\n\tconst char *name;\n\tchar *mod;\n}\nkeymod;\n\n");
+ for(int i=0;i<nkeys;i++)
+ {
+ printf("#define KEY_%s\t%d\n", keys[i].name, i);
+ }
+ printf("#define KEY_F(n)\t((int[12]){");
+ for(int i=1;i<12;i++)
+ {
+ printf("KEY_F%d,", i);
+ }
+ printf("}[n])\n");
+ break;
+ }
+ return(0);
+}
+
+char * fgetl(FILE *fp)
+{
+ char * lout;
+ int l,i;
+ init_char(&lout, &l, &i);
+ signed int c;
+ while(!feof(fp))
+ {
+ c=fgetc(fp);
+ if((c==EOF)||(c=='\n'))
+ break;
+ if(c!=0)
+ {
+ append_char(&lout, &l, &i, c);
+ }
+ }
+ return(lout);
+}
+
+void append_char(char **buf, int *l, int *i, char c)
+{
+ if(!((c==0)||(c==EOF)))
+ {
+ if(*buf)
+ {
+ (*buf)[(*i)++]=c;
+ }
+ else
+ {
+ init_char(buf, l, i);
+ append_char(buf, l, i, c);
+ }
+ char *nbuf=*buf;
+ if((*i)>=(*l))
+ {
+ *l=*i*2;
+ nbuf=(char *)realloc(*buf, *l);
+ }
+ if(nbuf)
+ {
+ *buf=nbuf;
+ (*buf)[*i]=0;
+ }
+ else
+ {
+ free(*buf);
+ init_char(buf, l, i);
+ }
+ }
+}
+
+void init_char(char **buf, int *l, int *i)
+{
+ *l=80;
+ *buf=(char *)malloc(*l);
+ (*buf)[0]=0;
+ *i=0;
+}
View
507 input.c
@@ -10,19 +10,52 @@
int inputchar(iline *inp, int *state)
{
- printf("\010\010\010" CLA);
+ //printf("\010\010\010" CLA);
int c=getchar();
if((c==0)||(c==EOF)) // stdin is set to non-blocking, so this may happen
return(0);
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, c);
+ char *seq;int sl,si,mod=-1;
+ init_char(&seq, &sl, &si);
+ bool match=true;
+ while(match&&(mod<0))
+ {
+ append_char(&seq, &sl, &si, c);
+ match=false;
+ for(int i=0;i<nkeys;i++)
+ {
+ if(strncmp(seq, kmap[i].mod, si)==0)
+ {
+ if(kmap[i].mod[si]==0)
+ {
+ mod=i;
+ break;
+ }
+ else
+ {
+ match=true;
+ }
+ }
+ }
+ if(match&&(mod<0))
+ {
+ c=getchar();
+ if((c==0)||(c==EOF))
+ {
+ match=false;
+ }
+ }
+ }
+ if(mod<0)
+ {
+ while(si>1) ungetc(seq[--si], stdin);
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, seq[0]);
+ }
+ free(seq);
if(c!='\t')
ttab=false;
- if(strchr("\010\177", c)) // various backspace-type characters
- {
- back_ichar(&inp->left);
+ if(mod==KEY_BS) // backspace
back_ichar(&inp->left);
- }
- else if(c<32) // this also stomps on the newline
+ else if((mod<0) && (c<32)) // this also stomps on the newline
{
back_ichar(&inp->left);
if(c==1) // C-a ~= home
@@ -144,276 +177,266 @@ int inputchar(iline *inp, int *state)
n_free(found);
}
}
- if(c=='\033') // escape sequence
+ else if(mod>=0)
{
- if(getchar()=='\133') // 1b 5b
+ bool gone=false;
+ for(int n=1;n<12;n++)
{
- unsigned char d=getchar();
- switch(d)
+ if(mod==KEY_F(n))
{
- case 'A': // ^[[A
- case 'B':; // ^[[B
- bool gone=false;
- if(d=='A') // Up
- {
- int old=bufs[cbuf].input.scroll;
- bufs[cbuf].input.scroll=min(bufs[cbuf].input.scroll+1, bufs[cbuf].input.filled?bufs[cbuf].input.nlines-1:bufs[cbuf].input.ptr);
- if(old!=bufs[cbuf].input.scroll) gone=true;
- if(gone&&!old)
- {
- if(inp->left.i||inp->right.i)
- {
- char out[inp->left.i+inp->right.i+1];
- sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
- addtoibuf(&bufs[cbuf].input, out);
- bufs[cbuf].input.scroll=2;
- }
- }
- }
- else // d=='B' // Down
- {
- gone=true;
- if(!bufs[cbuf].input.scroll)
- {
- if(inp->left.i||inp->right.i)
- {
- char out[inp->left.i+inp->right.i+1];
- sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
- addtoibuf(&bufs[cbuf].input, out);
- bufs[cbuf].input.scroll=0;
- }
- }
- bufs[cbuf].input.scroll=max(bufs[cbuf].input.scroll-1, 0);
- }
- if(gone&&(bufs[cbuf].input.ptr||bufs[cbuf].input.filled))
- {
- if(bufs[cbuf].input.scroll)
- {
- char *ln=bufs[cbuf].input.line[(bufs[cbuf].input.ptr+bufs[cbuf].input.nlines-bufs[cbuf].input.scroll)%bufs[cbuf].input.nlines];
- if(ln)
- {
- ifree(inp);
- inp->left.data=strdup(ln);inp->left.i=strlen(inp->left.data);inp->left.l=0;
- }
- }
- else
- {
- ifree(inp);
- }
- }
- break;
- case 'C': // ^[[C // Right
- if(inp->right.data && *inp->right.data)
+ cbuf=min(n%12, nbufs-1);
+ if(force_redraw<3) redraw_buffer();
+ }
+ }
+ if(mod==KEY_UP) // Up
+ {
+ int old=bufs[cbuf].input.scroll;
+ bufs[cbuf].input.scroll=min(bufs[cbuf].input.scroll+1, bufs[cbuf].input.filled?bufs[cbuf].input.nlines-1:bufs[cbuf].input.ptr);
+ if(old!=bufs[cbuf].input.scroll) gone=true;
+ if(gone&&!old)
+ {
+ if(inp->left.i||inp->right.i)
+ {
+ char out[inp->left.i+inp->right.i+1];
+ sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
+ addtoibuf(&bufs[cbuf].input, out);
+ bufs[cbuf].input.scroll=2;
+ }
+ }
+ }
+ else if(mod==KEY_DOWN) // Down
+ {
+ gone=true;
+ if(!bufs[cbuf].input.scroll)
+ {
+ if(inp->left.i||inp->right.i)
+ {
+ char out[inp->left.i+inp->right.i+1];
+ sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
+ addtoibuf(&bufs[cbuf].input, out);
+ bufs[cbuf].input.scroll=0;
+ }
+ }
+ bufs[cbuf].input.scroll=max(bufs[cbuf].input.scroll-1, 0);
+ }
+ if(gone&&(bufs[cbuf].input.ptr||bufs[cbuf].input.filled))
+ {
+ if(bufs[cbuf].input.scroll)
+ {
+ char *ln=bufs[cbuf].input.line[(bufs[cbuf].input.ptr+bufs[cbuf].input.nlines-bufs[cbuf].input.scroll)%bufs[cbuf].input.nlines];
+ if(ln)
+ {
+ ifree(inp);
+ inp->left.data=strdup(ln);inp->left.i=strlen(inp->left.data);inp->left.l=0;
+ }
+ }
+ else
+ {
+ ifree(inp);
+ }
+ }
+ else if(mod==KEY_RIGHT)
+ {
+ if(inp->right.data && *inp->right.data)
+ {
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, inp->right.data[0]);
+ char *nr=strdup(inp->right.data+1);
+ free(inp->right.data);
+ inp->right.data=nr;
+ inp->right.i--;
+ inp->right.l=0;
+ }
+ }
+ else if(mod==KEY_LEFT)
+ {
+ if(inp->left.i)
+ {
+ unsigned char e=back_ichar(&inp->left);
+ if(e)
+ {
+ char *nr=(char *)malloc(inp->right.i+2);
+ *nr=e;
+ if(inp->right.data)
{
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, inp->right.data[0]);
- char *nr=strdup(inp->right.data+1);
+ strcpy(nr+1, inp->right.data);
free(inp->right.data);
- inp->right.data=nr;
- inp->right.i--;
- inp->right.l=0;
}
- break;
- case 'D': // ^[[D // Left
- if(inp->left.i)
+ else
{
- unsigned char e=back_ichar(&inp->left);
- if(e)
- {
- char *nr=(char *)malloc(inp->right.i+2);
- *nr=e;
- if(inp->right.data)
- {
- strcpy(nr+1, inp->right.data);
- free(inp->right.data);
- }
- else
- {
- nr[1]=0;
- }
- inp->right.data=nr;
- inp->right.i++;
- inp->right.l=inp->right.i+1;
- }
+ nr[1]=0;
}
- break;
- case 'H': // ^[[H // Home
- i_home(inp);
- break;
- case 'F': // ^[[F // End
- i_end(inp);
- break;
- case '3': // take another
- if(getchar()=='~') // delete
+ inp->right.data=nr;
+ inp->right.i++;
+ inp->right.l=inp->right.i+1;
+ }
+ }
+ }
+ else if(mod==KEY_HOME)
+ i_home(inp);
+ else if(mod==KEY_END)
+ i_end(inp);
+ else if(mod==KEY_DELETE)
+ {
+ if(inp->right.data && inp->right.i)
+ {
+ char *nr=strdup(inp->right.data+1);
+ free(inp->right.data);
+ inp->right.data=nr;
+ inp->right.l=inp->right.i--;
+ }
+ }
+ else if(mod==KEY_CPGUP)
+ {
+ bufs[cbuf].ascroll-=height-(tsb?3:2);
+ if(force_redraw<3) redraw_buffer();
+ }
+ else if(mod==KEY_CPGDN)
+ {
+ bufs[cbuf].ascroll+=height-(tsb?3:2);
+ if(force_redraw<3) redraw_buffer();
+ }
+ else
+ {
+ bool gone=false;
+ if(mod==KEY_PGUP)
+ {
+ int old=bufs[cbuf].input.scroll;
+ bufs[cbuf].input.scroll=min(bufs[cbuf].input.scroll+10, bufs[cbuf].input.filled?bufs[cbuf].input.nlines-1:bufs[cbuf].input.ptr);
+ if(old!=bufs[cbuf].input.scroll) gone=true;
+ if(gone&&!old)
+ {
+ if(inp->left.i||inp->right.i)
{
- if(inp->right.data && inp->right.i)
- {
- char *nr=strdup(inp->right.data+1);
- free(inp->right.data);
- inp->right.data=nr;
- inp->right.l=inp->right.i--;
- }
+ char out[inp->left.i+inp->right.i+1];
+ sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
+ addtoibuf(&bufs[cbuf].input, out);
+ bufs[cbuf].input.scroll=2;
}
- break;
- case '5': // ^[[5
- case '6': // ^[[6
+ }
+ }
+ else if(mod==KEY_PGDN)
+ {
+ gone=true;
+ if(!bufs[cbuf].input.scroll)
{
- unsigned char e=getchar();
- switch(e)
+ if(inp->left.i||inp->right.i)
{
- case ';':
- if(getchar()=='5')
- {
- if(getchar()=='~')
- {
- if(d=='5') // C-PgUp
- {
- bufs[cbuf].ascroll-=height-(tsb?3:2);
- if(force_redraw<3) redraw_buffer();
- }
- else // d=='6' // C-PgDn
- {
- bufs[cbuf].ascroll+=height-(tsb?3:2);
- if(force_redraw<3) redraw_buffer();
- }
- }
- }
- break;
- case '~':;
- bool gone=false;
- if(d=='5') // PgUp
- {
- int old=bufs[cbuf].input.scroll;
- bufs[cbuf].input.scroll=min(bufs[cbuf].input.scroll+10, bufs[cbuf].input.filled?bufs[cbuf].input.nlines-1:bufs[cbuf].input.ptr);
- if(old!=bufs[cbuf].input.scroll) gone=true;
- if(gone&&!old)
- {
- if(inp->left.i||inp->right.i)
- {
- char out[inp->left.i+inp->right.i+1];
- sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
- addtoibuf(&bufs[cbuf].input, out);
- bufs[cbuf].input.scroll=2;
- }
- }
- }
- else // d=='6' // PgDn
- {
- gone=true;
- if(!bufs[cbuf].input.scroll)
- {
- if(inp->left.i||inp->right.i)
- {
- char out[inp->left.i+inp->right.i+1];
- sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
- addtoibuf(&bufs[cbuf].input, out);
- bufs[cbuf].input.scroll=0;
- }
- }
- bufs[cbuf].input.scroll=max(bufs[cbuf].input.scroll-10, 0);
- }
- if(gone&&(bufs[cbuf].input.ptr||bufs[cbuf].input.filled))
- {
- if(bufs[cbuf].input.scroll)
- {
- char *ln=bufs[cbuf].input.line[(bufs[cbuf].input.ptr+bufs[cbuf].input.nlines-bufs[cbuf].input.scroll)%bufs[cbuf].input.nlines];
- if(ln)
- {
- ifree(inp);
- inp->left.data=strdup(ln);inp->left.i=strlen(inp->left.data);inp->left.l=0;
- }
- }
- else
- {
- ifree(inp);
- }
- }
- break;
+ char out[inp->left.i+inp->right.i+1];
+ sprintf(out, "%s%s", inp->left.data?inp->left.data:"", inp->right.data?inp->right.data:"");
+ addtoibuf(&bufs[cbuf].input, out);
+ bufs[cbuf].input.scroll=0;
}
}
- break;
- case '1': // ^[[1
- if(getchar()==';')
+ bufs[cbuf].input.scroll=max(bufs[cbuf].input.scroll-10, 0);
+ }
+ if(gone&&(bufs[cbuf].input.ptr||bufs[cbuf].input.filled))
+ {
+ if(bufs[cbuf].input.scroll)
+ {
+ char *ln=bufs[cbuf].input.line[(bufs[cbuf].input.ptr+bufs[cbuf].input.nlines-bufs[cbuf].input.scroll)%bufs[cbuf].input.nlines];
+ if(ln)
{
- unsigned char e=getchar();
- if((e=='5')||(e=='3')) // 3 is Alt- instead of C-
- {
- switch(getchar())
- {
- case 'D': // C-left
- cbuf=max(cbuf-1, 0);
- if(force_redraw<3) redraw_buffer();
- break;
- case 'C': // C-right
- cbuf=min(cbuf+1, nbufs-1);
- if(force_redraw<3) redraw_buffer();
- break;
- case 'A': // C-up
- bufs[cbuf].ascroll--;
- if(force_redraw<3) redraw_buffer();
- break;
- case 'B': // C-down
- bufs[cbuf].ascroll++;
- if(force_redraw<3) redraw_buffer();
- break;
- case 'F': // C-end
- bufs[cbuf].scroll=bufs[cbuf].ptr;
- bufs[cbuf].ascroll=0;
- if(force_redraw<3) redraw_buffer();
- break;
- case 'H': // C-home
- bufs[cbuf].scroll=bufs[cbuf].filled?(bufs[cbuf].ptr+1)%bufs[cbuf].nlines:0;
- bufs[cbuf].ascroll=0;
- if(force_redraw<3) redraw_buffer();
- break;
- }
-
- }
+ ifree(inp);
+ inp->left.data=strdup(ln);inp->left.i=strlen(inp->left.data);inp->left.l=0;
}
- break;
+ }
+ else
+ {
+ ifree(inp);
+ }
}
- }
- }
- if((c&0xe0)==0xc0) // 110xxxxx -> 2 bytes of UTF-8
- {
- if(c==0xc2) // c2 bN = alt-N (for N in 0...9)
- {
- int d=getchar();
- if((d&0xf0)==0xb0)
+ else if((mod==KEY_CLEFT)||(mod==KEY_ALEFT))
{
- cbuf=min(max(d&0x0f, 0), nbufs-1);
+ cbuf=max(cbuf-1, 0);
if(force_redraw<3) redraw_buffer();
- back_ichar(&inp->left);
}
- else
+ else if((mod==KEY_CRIGHT)||(mod==KEY_ARIGHT))
{
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, d);
+ cbuf=min(cbuf+1, nbufs-1);
+ if(force_redraw<3) redraw_buffer();
+ }
+ else if((mod==KEY_CUP)||(mod==KEY_AUP))
+ {
+ bufs[cbuf].ascroll--;
+ if(force_redraw<3) redraw_buffer();
+ }
+ else if((mod==KEY_CDOWN)||(mod==KEY_ADOWN))
+ {
+ bufs[cbuf].ascroll++;
+ if(force_redraw<3) redraw_buffer();
+ }
+ else if((mod==KEY_CHOME)||(mod==KEY_AHOME))
+ {
+ bufs[cbuf].scroll=bufs[cbuf].filled?(bufs[cbuf].ptr+1)%bufs[cbuf].nlines:0;
+ bufs[cbuf].ascroll=0;
+ if(force_redraw<3) redraw_buffer();
+ }
+ else if((mod==KEY_CEND)||(mod==KEY_AEND))
+ {
+ bufs[cbuf].scroll=bufs[cbuf].ptr;
+ bufs[cbuf].ascroll=0;
+ if(force_redraw<3) redraw_buffer();
}
}
+ }
+ else if((c&0xe0)==0xc0) // 110xxxxx -> 2 bytes of UTF-8
+ {
+ int d=getchar();
+ if(d&&(d!=EOF)&&((d&0xc0)==0x80)) // 10xxxxxx - UTF middlebyte
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, d);
else
- {
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, getchar());
- }
+ ungetc(d, stdin);
}
- if((c&0xf0)==0xe0) // 1110xxxx -> 3 bytes of UTF-8
+ else if((c&0xf0)==0xe0) // 1110xxxx -> 3 bytes of UTF-8
{
int d=getchar();
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, d);
- if((d&0xc0)==0x80) // 10xxxxxx - UTF middlebyte
+ if(d&&(d!=EOF)&&((d&0xc0)==0x80)) // 10xxxxxx - UTF middlebyte
{
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, getchar());
+ int e=getchar();
+ if(e&&(e!=EOF)&&((e&0xc0)==0x80)) // 10xxxxxx - UTF middlebyte
+ {
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, d);
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, e);
+ }
+ else
+ {
+ ungetc(e, stdin);
+ ungetc(d, stdin);
+ }
}
+ else
+ ungetc(d, stdin);
}
- if((c&0xf8)==0xf0) // 11110xxx -> 4 bytes of UTF-8
+ else if((c&0xf8)==0xf0) // 11110xxx -> 4 bytes of UTF-8
{
int d=getchar();
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, d);
- if((d&0xc0)==0x80) // 10xxxxxx - UTF middlebyte, so get another
+ if(d&&(d!=EOF)&&((d&0xc0)==0x80)) // 10xxxxxx - UTF middlebyte
{
int e=getchar();
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, e);
- if((e&0xc0)==0x80) // 10xxxxxx - UTF middlebyte, so get another
- append_char(&inp->left.data, &inp->left.l, &inp->left.i, getchar());
+ if(e&&(e!=EOF)&&((e&0xc0)==0x80)) // 10xxxxxx - UTF middlebyte
+ {
+ int f=getchar();
+ if(f&&(f!=EOF)&&((f&0xc0)==0x80)) // 10xxxxxx - UTF middlebyte
+ {
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, d);
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, e);
+ append_char(&inp->left.data, &inp->left.l, &inp->left.i, f);
+ }
+ else
+ {
+ ungetc(f, stdin);
+ ungetc(e, stdin);
+ ungetc(d, stdin);
+ }
+ }
+ else
+ {
+ ungetc(e, stdin);
+ ungetc(d, stdin);
+ }
}
+ else
+ ungetc(d, stdin);
}
if(c=='\n')
{
View
8 input.h
@@ -1,9 +1,9 @@
#pragma once
/*
- quIRC - simple terminal-based IRC client
- Copyright (C) 2010-11 Edward Cree
-
+ quIRC - simple terminal-based IRC client
+ Copyright (C) 2010-11 Edward Cree
+
See quirc.c for license information
input: handle input routines
*/
@@ -44,6 +44,8 @@ ibuffer;
#include "buffer.h"
#include "irc.h"
#include "bits.h"
+#include "config.h"
+#include "keymod.h"
bool ttab;
View
302 keymap.c
@@ -0,0 +1,302 @@
+#include <stdbool.h>
+
+int initkeys(void)
+{
+ nkeys=38;
+ kmap=malloc(nkeys*sizeof(keymod));
+ if(!kmap) return(1);
+ kmap[0].name="BS";
+ kmap[0].mod=malloc(2);
+ kmap[0].mod[0]=127;
+ kmap[0].mod[1]=0;
+ kmap[1].name="UP";
+ kmap[1].mod=malloc(4);
+ kmap[1].mod[0]=27;
+ kmap[1].mod[1]=91;
+ kmap[1].mod[2]=65;
+ kmap[1].mod[3]=0;
+ kmap[2].name="DOWN";
+ kmap[2].mod=malloc(4);
+ kmap[2].mod[0]=27;
+ kmap[2].mod[1]=91;
+ kmap[2].mod[2]=66;
+ kmap[2].mod[3]=0;
+ kmap[3].name="LEFT";
+ kmap[3].mod=malloc(4);
+ kmap[3].mod[0]=27;
+ kmap[3].mod[1]=91;
+ kmap[3].mod[2]=68;
+ kmap[3].mod[3]=0;
+ kmap[4].name="RIGHT";
+ kmap[4].mod=malloc(4);
+ kmap[4].mod[0]=27;
+ kmap[4].mod[1]=91;
+ kmap[4].mod[2]=67;
+ kmap[4].mod[3]=0;
+ kmap[5].name="HOME";
+ kmap[5].mod=malloc(4);
+ kmap[5].mod[0]=27;
+ kmap[5].mod[1]=91;
+ kmap[5].mod[2]=72;
+ kmap[5].mod[3]=0;
+ kmap[6].name="END";
+ kmap[6].mod=malloc(4);
+ kmap[6].mod[0]=27;
+ kmap[6].mod[1]=91;
+ kmap[6].mod[2]=70;
+ kmap[6].mod[3]=0;
+ kmap[7].name="DELETE";
+ kmap[7].mod=malloc(5);
+ kmap[7].mod[0]=27;
+ kmap[7].mod[1]=91;
+ kmap[7].mod[2]=51;
+ kmap[7].mod[3]=126;
+ kmap[7].mod[4]=0;
+ kmap[8].name="PGUP";
+ kmap[8].mod=malloc(5);
+ kmap[8].mod[0]=27;
+ kmap[8].mod[1]=91;
+ kmap[8].mod[2]=53;
+ kmap[8].mod[3]=126;
+ kmap[8].mod[4]=0;
+ kmap[9].name="PGDN";
+ kmap[9].mod=malloc(5);
+ kmap[9].mod[0]=27;
+ kmap[9].mod[1]=91;
+ kmap[9].mod[2]=54;
+ kmap[9].mod[3]=126;
+ kmap[9].mod[4]=0;
+ kmap[10].name="CUP";
+ kmap[10].mod=malloc(7);
+ kmap[10].mod[0]=27;
+ kmap[10].mod[1]=91;
+ kmap[10].mod[2]=49;
+ kmap[10].mod[3]=59;
+ kmap[10].mod[4]=53;
+ kmap[10].mod[5]=65;
+ kmap[10].mod[6]=0;
+ kmap[11].name="AUP";
+ kmap[11].mod=malloc(7);
+ kmap[11].mod[0]=27;
+ kmap[11].mod[1]=91;
+ kmap[11].mod[2]=49;
+ kmap[11].mod[3]=59;
+ kmap[11].mod[4]=51;
+ kmap[11].mod[5]=65;
+ kmap[11].mod[6]=0;
+ kmap[12].name="CDOWN";
+ kmap[12].mod=malloc(7);
+ kmap[12].mod[0]=27;
+ kmap[12].mod[1]=91;
+ kmap[12].mod[2]=49;
+ kmap[12].mod[3]=59;
+ kmap[12].mod[4]=53;
+ kmap[12].mod[5]=66;
+ kmap[12].mod[6]=0;
+ kmap[13].name="ADOWN";
+ kmap[13].mod=malloc(7);
+ kmap[13].mod[0]=27;
+ kmap[13].mod[1]=91;
+ kmap[13].mod[2]=49;
+ kmap[13].mod[3]=59;
+ kmap[13].mod[4]=51;
+ kmap[13].mod[5]=66;
+ kmap[13].mod[6]=0;
+ kmap[14].name="CLEFT";
+ kmap[14].mod=malloc(7);
+ kmap[14].mod[0]=27;
+ kmap[14].mod[1]=91;
+ kmap[14].mod[2]=49;
+ kmap[14].mod[3]=59;
+ kmap[14].mod[4]=53;
+ kmap[14].mod[5]=68;
+ kmap[14].mod[6]=0;
+ kmap[15].name="ALEFT";
+ kmap[15].mod=malloc(7);
+ kmap[15].mod[0]=27;
+ kmap[15].mod[1]=91;
+ kmap[15].mod[2]=49;
+ kmap[15].mod[3]=59;
+ kmap[15].mod[4]=51;
+ kmap[15].mod[5]=68;
+ kmap[15].mod[6]=0;
+ kmap[16].name="CRIGHT";
+ kmap[16].mod=malloc(7);
+ kmap[16].mod[0]=27;
+ kmap[16].mod[1]=91;
+ kmap[16].mod[2]=49;
+ kmap[16].mod[3]=59;
+ kmap[16].mod[4]=53;
+ kmap[16].mod[5]=67;
+ kmap[16].mod[6]=0;
+ kmap[17].name="ARIGHT";
+ kmap[17].mod=malloc(7);
+ kmap[17].mod[0]=27;
+ kmap[17].mod[1]=91;
+ kmap[17].mod[2]=49;
+ kmap[17].mod[3]=59;
+ kmap[17].mod[4]=51;
+ kmap[17].mod[5]=67;
+ kmap[17].mod[6]=0;
+ kmap[18].name="CHOME";
+ kmap[18].mod=malloc(7);
+ kmap[18].mod[0]=27;
+ kmap[18].mod[1]=91;
+ kmap[18].mod[2]=49;
+ kmap[18].mod[3]=59;
+ kmap[18].mod[4]=53;
+ kmap[18].mod[5]=72;
+ kmap[18].mod[6]=0;
+ kmap[19].name="AHOME";
+ kmap[19].mod=malloc(7);
+ kmap[19].mod[0]=27;
+ kmap[19].mod[1]=91;
+ kmap[19].mod[2]=49;
+ kmap[19].mod[3]=59;
+ kmap[19].mod[4]=51;
+ kmap[19].mod[5]=72;
+ kmap[19].mod[6]=0;
+ kmap[20].name="CEND";
+ kmap[20].mod=malloc(7);
+ kmap[20].mod[0]=27;
+ kmap[20].mod[1]=91;
+ kmap[20].mod[2]=49;
+ kmap[20].mod[3]=59;
+ kmap[20].mod[4]=53;
+ kmap[20].mod[5]=70;
+ kmap[20].mod[6]=0;
+ kmap[21].name="AEND";
+ kmap[21].mod=malloc(7);
+ kmap[21].mod[0]=27;
+ kmap[21].mod[1]=91;
+ kmap[21].mod[2]=49;
+ kmap[21].mod[3]=59;
+ kmap[21].mod[4]=51;
+ kmap[21].mod[5]=70;
+ kmap[21].mod[6]=0;
+ kmap[22].name="CPGUP";
+ kmap[22].mod=malloc(7);
+ kmap[22].mod[0]=27;
+ kmap[22].mod[1]=91;
+ kmap[22].mod[2]=53;
+ kmap[22].mod[3]=59;
+ kmap[22].mod[4]=53;
+ kmap[22].mod[5]=126;
+ kmap[22].mod[6]=0;
+ kmap[23].name="APGUP";
+ kmap[23].mod=malloc(7);
+ kmap[23].mod[0]=27;
+ kmap[23].mod[1]=91;
+ kmap[23].mod[2]=53;
+ kmap[23].mod[3]=59;
+ kmap[23].mod[4]=51;
+ kmap[23].mod[5]=126;
+ kmap[23].mod[6]=0;
+ kmap[24].name="CPGDN";
+ kmap[24].mod=malloc(7);
+ kmap[24].mod[0]=27;
+ kmap[24].mod[1]=91;
+ kmap[24].mod[2]=54;
+ kmap[24].mod[3]=59;
+ kmap[24].mod[4]=53;
+ kmap[24].mod[5]=126;
+ kmap[24].mod[6]=0;
+ kmap[25].name="APGDN";
+ kmap[25].mod=malloc(7);
+ kmap[25].mod[0]=27;
+ kmap[25].mod[1]=91;
+ kmap[25].mod[2]=54;
+ kmap[25].mod[3]=59;
+ kmap[25].mod[4]=51;
+ kmap[25].mod[5]=126;
+ kmap[25].mod[6]=0;
+ kmap[26].name="F1";
+ kmap[26].mod=malloc(4);
+ kmap[26].mod[0]=27;
+ kmap[26].mod[1]=79;
+ kmap[26].mod[2]=80;
+ kmap[26].mod[3]=0;
+ kmap[27].name="F2";
+ kmap[27].mod=malloc(4);
+ kmap[27].mod[0]=27;
+ kmap[27].mod[1]=79;
+ kmap[27].mod[2]=81;
+ kmap[27].mod[3]=0;
+ kmap[28].name="F3";
+ kmap[28].mod=malloc(4);
+ kmap[28].mod[0]=27;
+ kmap[28].mod[1]=79;
+ kmap[28].mod[2]=82;
+ kmap[28].mod[3]=0;
+ kmap[29].name="F4";
+ kmap[29].mod=malloc(4);
+ kmap[29].mod[0]=27;
+ kmap[29].mod[1]=79;
+ kmap[29].mod[2]=83;
+ kmap[29].mod[3]=0;
+ kmap[30].name="F5";
+ kmap[30].mod=malloc(6);
+ kmap[30].mod[0]=27;
+ kmap[30].mod[1]=91;
+ kmap[30].mod[2]=49;
+ kmap[30].mod[3]=53;
+ kmap[30].mod[4]=126;
+ kmap[30].mod[5]=0;
+ kmap[31].name="F6";
+ kmap[31].mod=malloc(6);
+ kmap[31].mod[0]=27;
+ kmap[31].mod[1]=91;
+ kmap[31].mod[2]=49;
+ kmap[31].mod[3]=55;
+ kmap[31].mod[4]=126;
+ kmap[31].mod[5]=0;
+ kmap[32].name="F7";
+ kmap[32].mod=malloc(6);
+ kmap[32].mod[0]=27;
+ kmap[32].mod[1]=91;
+ kmap[32].mod[2]=49;
+ kmap[32].mod[3]=56;
+ kmap[32].mod[4]=126;
+ kmap[32].mod[5]=0;
+ kmap[33].name="F8";
+ kmap[33].mod=malloc(6);
+ kmap[33].mod[0]=27;
+ kmap[33].mod[1]=91;
+ kmap[33].mod[2]=49;
+ kmap[33].mod[3]=57;
+ kmap[33].mod[4]=126;
+ kmap[33].mod[5]=0;
+ kmap[34].name="F9";
+ kmap[34].mod=malloc(6);
+ kmap[34].mod[0]=27;
+ kmap[34].mod[1]=91;
+ kmap[34].mod[2]=50;
+ kmap[34].mod[3]=48;
+ kmap[34].mod[4]=126;
+ kmap[34].mod[5]=0;
+ kmap[35].name="F10";
+ kmap[35].mod=malloc(6);
+ kmap[35].mod[0]=27;
+ kmap[35].mod[1]=91;
+ kmap[35].mod[2]=50;
+ kmap[35].mod[3]=49;
+ kmap[35].mod[4]=126;
+ kmap[35].mod[5]=0;
+ kmap[36].name="F11";
+ kmap[36].mod=malloc(6);
+ kmap[36].mod[0]=27;
+ kmap[36].mod[1]=91;
+ kmap[36].mod[2]=50;
+ kmap[36].mod[3]=51;
+ kmap[36].mod[4]=126;
+ kmap[36].mod[5]=0;
+ kmap[37].name="F12";
+ kmap[37].mod=malloc(6);
+ kmap[37].mod[0]=27;
+ kmap[37].mod[1]=91;
+ kmap[37].mod[2]=50;
+ kmap[37].mod[3]=52;
+ kmap[37].mod[4]=126;
+ kmap[37].mod[5]=0;
+ return(0);
+}
View
48 keymod.h
@@ -0,0 +1,48 @@
+#pragma once
+
+typedef struct
+{
+ const char *name;
+ char *mod;
+}
+keymod;
+
+#define KEY_BS 0
+#define KEY_UP 1
+#define KEY_DOWN 2
+#define KEY_LEFT 3
+#define KEY_RIGHT 4
+#define KEY_HOME 5
+#define KEY_END 6
+#define KEY_DELETE 7
+#define KEY_PGUP 8
+#define KEY_PGDN 9
+#define KEY_CUP 10
+#define KEY_AUP 11
+#define KEY_CDOWN 12
+#define KEY_ADOWN 13
+#define KEY_CLEFT 14
+#define KEY_ALEFT 15
+#define KEY_CRIGHT 16
+#define KEY_ARIGHT 17
+#define KEY_CHOME 18
+#define KEY_AHOME 19
+#define KEY_CEND 20
+#define KEY_AEND 21
+#define KEY_CPGUP 22
+#define KEY_APGUP 23
+#define KEY_CPGDN 24
+#define KEY_APGDN 25
+#define KEY_F1 26
+#define KEY_F2 27
+#define KEY_F3 28
+#define KEY_F4 29
+#define KEY_F5 30
+#define KEY_F6 31
+#define KEY_F7 32
+#define KEY_F8 33
+#define KEY_F9 34
+#define KEY_F10 35
+#define KEY_F11 36
+#define KEY_F12 37
+#define KEY_F(n) ((int[12]){KEY_F1,KEY_F2,KEY_F3,KEY_F4,KEY_F5,KEY_F6,KEY_F7,KEY_F8,KEY_F9,KEY_F10,KEY_F11,}[n])
View
38 keys
@@ -0,0 +1,38 @@
+BS 7f
+UP 1b5b41
+DOWN 1b5b42
+LEFT 1b5b44
+RIGHT 1b5b43
+HOME 1b5b48
+END 1b5b46
+DELETE 1b5b337e
+PGUP 1b5b357e
+PGDN 1b5b367e
+CUP 1b5b313b3541
+AUP 1b5b313b3341
+CDOWN 1b5b313b3542
+ADOWN 1b5b313b3342
+CLEFT 1b5b313b3544
+ALEFT 1b5b313b3344
+CRIGHT 1b5b313b3543
+ARIGHT 1b5b313b3343
+CHOME 1b5b313b3548
+AHOME 1b5b313b3348
+CEND 1b5b313b3546
+AEND 1b5b313b3346
+CPGUP 1b5b353b357e
+APGUP 1b5b353b337e
+CPGDN 1b5b363b357e
+APGDN 1b5b363b337e
+F1 1b4f50
+F2 1b4f51
+F3 1b4f52
+F4 1b4f53
+F5 1b5b31357e
+F6 1b5b31377e
+F7 1b5b31387e
+F8 1b5b31397e
+F9 1b5b32307e
+F10 1b5b32317e
+F11 1b5b32337e
+F12 1b5b32347e
View
15 quirc.c
@@ -53,7 +53,13 @@ int main(int argc, char *argv[])
asb_failsafe(c_status, msg);
}
}
- if(c_init()!=0) // should be impossible
+ if(initkeys())
+ {
+ fprintf(stderr, "Failed to initialise keymapping\n");
+ push_buffer();
+ return(1);
+ }
+ if(c_init()) // should be impossible
{
fprintf(stderr, "Failed to initialise colours\n");
push_buffer();
@@ -111,7 +117,12 @@ int main(int argc, char *argv[])
{
asb_failsafe(c_status, "no config file found. Install one at ~/.quirc/rc");
}
-
+ FILE *keyfp=fopen("keys", "r");
+ if(keyfp)
+ {
+ loadkeys(keyfp);
+ fclose(keyfp);
+ }
signed int e=pargs(argc, argv);
if(e>=0)
{
View
25 readme.htm
@@ -11,7 +11,7 @@
<body>
<div id="title">
<h1>quIRC: readme</h1>
-<h5>quIRC is a simple terminal-based IRC (Internet Relay Chat) client. It is written in C.</h5>
+<h5>quIRC is a lightweight terminal-based <acronym title="Internet Relay Chat">IRC</acronym> client. It is written in C.</h5>
</div><!--#title-->
<div id="contents">
<h2>Contents</h2>
@@ -21,6 +21,7 @@
<li><a href="#configuration">Configuration</a></li>
<li><a href="#inputcontrols">Input Controls</a></li>
<li><a href="#othercontrols">Other Controls</a></li>
+<li><a href="#keymapping">Keymapping</a></li>
<li><a href="#tabstrip">Tab strip</a></li>
<li><a href="#trouble">Troubleshooting</a></li>
</ul>
@@ -122,7 +123,7 @@
<div id="configuration">
<h2>Configuration</h2>
<p>quIRC can be configured through an &quot;rc file&quot; as follows. (For a compact reference table see <a href="config_ref.htm">config_ref.htm</a>)</p>
-<p>In your home directory (/home/username), create a file called &quot;.quirc&quot;, and open it in your editor.</p>
+<p>In your home directory (/home/<em>username</em>), create a folder called &quot;.quirc&quot;, a file within that folder called &quot;rc&quot;, and open it in your editor.</p>
<p>In this file you can set servers, nick and channels to automatically use:<br />
<tt>nick <em>global-nickname</em></tt><br />
<tt>ignore -<em>options</em> <em>global-ignore</em></tt><br />
@@ -241,10 +242,22 @@
<dt>Ctrl-left</dt>
<dt>Ctrl-right</dt>
<dd>Change tab.</dd>
-<dt>Alt-<em>[#]</em>, where <em>[#]</em> is a number key</dt>
- <dd>Equivalent to <small>/tab <em>[#]</em></small></dd>
+<dt>F1 through F12</dt>
+ <dd>Equivalent to <small>/tab <em>#</em></small>, except that F12 is /tab 0.</dd>
</dl>
-</div><!--#scrollcontrols-->
+</div><!--#othercontrols-->
+<div id="keymapping">
+<h2>Keymapping</h2>
+<p>quIRC's mapping of function and other special keys defaults to a VT100 mapping, such as used by <small>xterm</small> and <small>rxvt</small>. However, this mapping can be changed with a file <small>/home/<em>username</em>/.quirc/keys</small>.</p>
+<p>To change key mappings, add lines of the form <small><em>MODNAME</em> <em>hex</em></small>. The <em>MODNAME</em>s expected are those which appear in the &quot;<small>keys</small>&quot; file in the quIRC source directory; at present, these are:<br />
+<small>BS</small>, <small>UP</small>, <small>DOWN</small>, <small>LEFT</small>, <small>RIGHT</small>, <small>HOME</small>, <small>END</small>, <small>DELETE</small>, <small>PGUP</small>, <small>PGDN</small>, <small>CUP</small>, <small>AUP</small>, <small>CDOWN</small>, <small>ADOWN</small>, <small>CLEFT</small>, <small>ALEFT</small>, <small>CRIGHT</small>, <small>ARIGHT</small>, <small>CHOME</small>, <small>AHOME</small>, <small>CEND</small>, <small>AEND</small>, <small>CPGUP</small>, <small>APGUP</small>, <small>CPGDN</small>, <small>APGDN</small>, <small>F1</small>, <small>F2</small>, <small>F3</small>, <small>F4</small>, <small>F5</small>, <small>F6</small>, <small>F7</small>, <small>F8</small>, <small>F9</small>, <small>F10</small>, <small>F11</small>, and <small>F12</small>.<br />
+The prefix &apos;C&apos; refers to Ctrl, and &apos;A&apos; to Alt.</p>
+<p>If, for instance, your terminal sends Ctrl-Left as ^[OD, you would add the following line:<br />
+<tt>CLEFT 1b4f44</tt><br />
+Similarly, if your terminal sends backspace as ^H, you would add:<br />
+<tt>BS 08</tt></p>
+<p>You can find out what sequences your terminal sends for various keys by running a hex-dump program such as <small>xxd</small> or <small>hd</small>, pressing the key, and noting the output. <em>(You will usually need to press first the key, then enter/return, then ^D)</em></p>
+</div><!--#keymapping-->
<div id="tabstrip">
<h2>Tab strip</h2>
<p>The strip of tabs along the bottom of the screen has various indicators.</p>
@@ -263,6 +276,8 @@
<dl>
<dt>I get several copies of the status line scrolling up my screen!</dt>
<dd><p>One possible cause of this is that your terminal size is not what quIRC thinks it is. You may need to /set height and width, or export the environment variables $LINES and $COLUMNS from your shell (typically you would also add this to your shell's .rc file), or as a last resort resize your terminal to 80x24.</p><p>Another possibility is that your terminal emulator isn't recognising VT100 escape sequences (which quIRC uses heavily for eg. cursor positioning). For details see your terminal emulator's documentation; it is known that xterm works out-of-the-box, and that PuTTY has an option to enable VT100 support.</p></dd>
+<dt>The control keys/cursor keys/function keys don't do anything!</dt>
+<dd><p>This probably means your terminal isn't sending VT100 (ANSI) escape sequences, but rather some other set of sequences. See the section &quot;<a href="#keymapping">Keymapping</a>&quot;, above.</p></dd>
</dl>
</div><!--#trouble-->
</body>
Please sign in to comment.
Something went wrong with that request. Please try again.