aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--st.c210
1 files changed, 181 insertions, 29 deletions
diff --git a/st.c b/st.c
index 64a37e1..a203c72 100644
--- a/st.c
+++ b/st.c
@@ -1,5 +1,160 @@
1/* See LICENSE for licence details. */ 1/* See LICENSE for licence details. */
2#include "st.h" 2/* See LICENSE for licence details. */
3#define _XOPEN_SOURCE
4#include <ctype.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <locale.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <signal.h>
13#include <sys/ioctl.h>
14#include <sys/select.h>
15#include <sys/stat.h>
16#include <sys/types.h>
17#include <sys/wait.h>
18#include <unistd.h>
19#include <X11/Xlib.h>
20#include <X11/keysym.h>
21#include <X11/Xutil.h>
22
23#define TNAME "st"
24
25/* Arbitrary sizes */
26#define ESCSIZ 256
27#define ESCARG 16
28
29#define SERRNO strerror(errno)
30#define MIN(a, b) ((a) < (b) ? (a) : (b))
31#define MAX(a, b) ((a) < (b) ? (b) : (a))
32#define LEN(a) (sizeof(a) / sizeof(a[0]))
33#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
34#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
35#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
36
37/* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */
38enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 };
39enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload };
40enum { CRset=1 , CRupdate=2 };
41enum { TMwrap=1 , TMinsert=2, TMaltcharset };
42enum { SCupdate, SCredraw };
43
44typedef int Color;
45
46typedef struct {
47 KeySym k;
48 char s[ESCSIZ];
49} Key;
50
51typedef struct {
52 char c; /* character code */
53 char mode; /* attribute flags */
54 Color fg; /* foreground */
55 Color bg; /* background */
56 char state; /* state flag */
57} Glyph;
58
59typedef Glyph* Line;
60
61typedef struct {
62 Glyph attr; /* current char attributes */
63 char hidden;
64 int x;
65 int y;
66} TCursor;
67
68/* Escape sequence structs */
69/* ESC <pre> [[ [<priv>] <arg> [;]] <mode>] */
70typedef struct {
71 char buf[ESCSIZ+1]; /* raw string */
72 int len; /* raw string length */
73 char pre;
74 char priv;
75 int arg[ESCARG+1];
76 int narg; /* nb of args */
77 char mode;
78} Escseq;
79
80/* Internal representation of the screen */
81typedef struct {
82 int row; /* nb row */
83 int col; /* nb col */
84 Line* line; /* screen */
85 TCursor c; /* cursor */
86 int top; /* top scroll limit */
87 int bot; /* bottom scroll limit */
88 int mode; /* terminal mode */
89} Term;
90
91/* Purely graphic info */
92typedef struct {
93 Display* dis;
94 Window win;
95 int scr;
96 int w; /* window width */
97 int h; /* window height */
98 int ch; /* char height */
99 int cw; /* char width */
100} XWindow;
101
102#include "config.h"
103
104/* Drawing Context */
105typedef struct {
106 unsigned long col[LEN(colorname)];
107 XFontStruct* font;
108 GC gc;
109} DC;
110
111void die(const char *errstr, ...);
112void draw(int);
113void execsh(void);
114void sigchld(int);
115char* kmap(KeySym);
116void kpress(XKeyEvent *);
117void resize(XEvent *);
118void run(void);
119
120int escaddc(char);
121int escfinal(char);
122void escdump(void);
123void eschandle(void);
124void escparse(void);
125void escreset(void);
126
127void tclearregion(int, int, int, int);
128void tcpos(int);
129void tcursor(int);
130void tdeletechar(int);
131void tdeleteline(int);
132void tdump(void);
133void tinsertblank(int);
134void tinsertblankline(int);
135void tmoveto(int, int);
136void tnew(int, int);
137void tnewline(void);
138void tputc(char);
139void tputs(char*, int);
140void tresize(int, int);
141void tscroll(void);
142void tsetattr(int*, int);
143void tsetchar(char);
144void tsetscroll(int, int);
145
146void ttynew(void);
147void ttyread(void);
148void ttyresize(int, int);
149void ttywrite(char *, size_t);
150
151unsigned long xgetcol(const char *);
152void xclear(int, int, int, int);
153void xcursor(int);
154void xdrawc(int, int, Glyph);
155void xinit(void);
156void xscroll(void);
157
3 158
4/* Globals */ 159/* Globals */
5DC dc; 160DC dc;
@@ -725,11 +880,11 @@ xinit(void) {
725 xw.dis = XOpenDisplay(NULL); 880 xw.dis = XOpenDisplay(NULL);
726 xw.scr = XDefaultScreen(xw.dis); 881 xw.scr = XDefaultScreen(xw.dis);
727 if(!xw.dis) 882 if(!xw.dis)
728 die("can not open display"); 883 die("Can't open display\n");
729 884
730 /* font */ 885 /* font */
731 if(!(dc.font = XLoadQueryFont(xw.dis, FONT))) 886 if(!(dc.font = XLoadQueryFont(xw.dis, FONT)))
732 die("can not find font " FONT); 887 die("Can't load font %s\n", FONT);
733 888
734 xw.cw = dc.font->max_bounds.rbearing - dc.font->min_bounds.lbearing; 889 xw.cw = dc.font->max_bounds.rbearing - dc.font->min_bounds.lbearing;
735 xw.ch = dc.font->ascent + dc.font->descent + LINESPACE; 890 xw.ch = dc.font->ascent + dc.font->descent + LINESPACE;
@@ -834,6 +989,15 @@ draw(int redraw_all) {
834 xcursor(CSdraw); 989 xcursor(CSdraw);
835} 990}
836 991
992char*
993kmap(KeySym k) {
994 int i;
995 for(i = 0; i < LEN(key); i++)
996 if(key[i].k == k)
997 return (char*)key[i].s;
998 return NULL;
999}
1000
837void 1001void
838kpress(XKeyEvent *e) { 1002kpress(XKeyEvent *e) {
839 KeySym ksym; 1003 KeySym ksym;
@@ -841,39 +1005,28 @@ kpress(XKeyEvent *e) {
841 int len; 1005 int len;
842 int meta; 1006 int meta;
843 int shift; 1007 int shift;
1008 char* skmap;
844 1009
845 meta = e->state & Mod1Mask; 1010 meta = e->state & Mod1Mask;
846 shift = e->state & ShiftMask; 1011 shift = e->state & ShiftMask;
847 len = XLookupString(e, buf, sizeof(buf), &ksym, NULL); 1012 len = XLookupString(e, buf, sizeof(buf), &ksym, NULL);
848 if(len > 0) { 1013 if(skmap = kmap(ksym))
1014 ttywrite(skmap, strlen(skmap));
1015 else if(len > 0) {
849 buf[sizeof(buf)-1] = '\0'; 1016 buf[sizeof(buf)-1] = '\0';
850 if(meta && len == 1) 1017 if(meta && len == 1)
851 ttywrite("\033", 1); 1018 ttywrite("\033", 1);
852 ttywrite(buf, len); 1019 ttywrite(buf, len);
853 return; 1020 } else
854 } 1021 switch(ksym) {
855 switch(ksym) { 1022 case XK_Insert:
856 default: 1023 if(shift)
857 fprintf(stderr, "errkey: %d\n", (int)ksym); 1024 /* XXX: paste X clipboard */;
858 break; 1025 break;
859 case XK_Up: 1026 default:
860 case XK_Down: 1027 fprintf(stderr, "errkey: %d\n", (int)ksym);
861 case XK_Left: 1028 break;
862 case XK_Right: 1029 }
863 sprintf(buf, "\033[%c", "DACB"[ksym - XK_Left]);
864 ttywrite(buf, 3);
865 break;
866 case XK_Delete: ttywrite(KEYDELETE, sizeof(KEYDELETE)-1); break;
867 case XK_Home: ttywrite(KEYHOME, sizeof(KEYHOME)-1); break;
868 case XK_End: ttywrite(KEYEND, sizeof(KEYEND) -1); break;
869 case XK_Prior: ttywrite(KEYPREV, sizeof(KEYPREV)-1); break;
870 case XK_Next: ttywrite(KEYNEXT, sizeof(KEYNEXT)-1); break;
871 case XK_Insert:
872 /* XXX: paste X clipboard */
873 if(shift)
874 ;
875 break;
876 }
877} 1030}
878 1031
879void 1032void
@@ -891,7 +1044,6 @@ resize(XEvent *e) {
891 } 1044 }
892} 1045}
893 1046
894
895void 1047void
896run(void) { 1048run(void) {
897 int ret; 1049 int ret;