diff options
-rw-r--r-- | config.h | 3 | ||||
-rw-r--r-- | st.c | 173 |
2 files changed, 126 insertions, 50 deletions
@@ -1,7 +1,8 @@ | |||
1 | #define SHELL "/bin/bash" | 1 | #define SHELL "/bin/bash" |
2 | #define TAB 8 | 2 | #define TAB 8 |
3 | 3 | ||
4 | #define FONT "fixed" | 4 | #define FONT "6x13" |
5 | #define BOLDFONT FONT"bold" | ||
5 | #define BORDER 3 | 6 | #define BORDER 3 |
6 | #define LINESPACE 0 /* additional pixel between each line */ | 7 | #define LINESPACE 0 /* additional pixel between each line */ |
7 | 8 | ||
@@ -57,7 +57,6 @@ typedef Glyph* Line; | |||
57 | 57 | ||
58 | typedef struct { | 58 | typedef struct { |
59 | Glyph attr; /* current char attributes */ | 59 | Glyph attr; /* current char attributes */ |
60 | char hidden; | ||
61 | int x; | 60 | int x; |
62 | int y; | 61 | int y; |
63 | } TCursor; | 62 | } TCursor; |
@@ -79,6 +78,7 @@ typedef struct { | |||
79 | int col; /* nb col */ | 78 | int col; /* nb col */ |
80 | Line* line; /* screen */ | 79 | Line* line; /* screen */ |
81 | TCursor c; /* cursor */ | 80 | TCursor c; /* cursor */ |
81 | char hidec; | ||
82 | int top; /* top scroll limit */ | 82 | int top; /* top scroll limit */ |
83 | int bot; /* bottom scroll limit */ | 83 | int bot; /* bottom scroll limit */ |
84 | int mode; /* terminal mode flags */ | 84 | int mode; /* terminal mode flags */ |
@@ -109,6 +109,7 @@ typedef struct { | |||
109 | typedef struct { | 109 | typedef struct { |
110 | unsigned long col[LEN(colorname)]; | 110 | unsigned long col[LEN(colorname)]; |
111 | XFontStruct* font; | 111 | XFontStruct* font; |
112 | XFontStruct* bfont; | ||
112 | GC gc; | 113 | GC gc; |
113 | } DC; | 114 | } DC; |
114 | 115 | ||
@@ -135,8 +136,11 @@ static void tnew(int, int); | |||
135 | static void tnewline(void); | 136 | static void tnewline(void); |
136 | static void tputc(char); | 137 | static void tputc(char); |
137 | static void tputs(char*, int); | 138 | static void tputs(char*, int); |
139 | static void treset(void); | ||
138 | static void tresize(int, int); | 140 | static void tresize(int, int); |
139 | static void tscroll(void); | 141 | static void tscroll(void); |
142 | static void tscrollup(int); | ||
143 | static void tscrolldown(int); | ||
140 | static void tsetattr(int*, int); | 144 | static void tsetattr(int*, int); |
141 | static void tsetchar(char); | 145 | static void tsetchar(char); |
142 | static void tsetscroll(int, int); | 146 | static void tsetscroll(int, int); |
@@ -149,12 +153,11 @@ static void ttywrite(const char *, size_t); | |||
149 | static unsigned long xgetcol(const char *); | 153 | static unsigned long xgetcol(const char *); |
150 | static void xclear(int, int, int, int); | 154 | static void xclear(int, int, int, int); |
151 | static void xcursor(int); | 155 | static void xcursor(int); |
152 | static void xdrawc(int, int, Glyph); | ||
153 | static void xinit(void); | 156 | static void xinit(void); |
154 | static void xscroll(void); | 157 | static void xscroll(void); |
155 | 158 | ||
156 | static void expose(XEvent *); | 159 | static void expose(XEvent *); |
157 | static char * kmap(KeySym); | 160 | static char* kmap(KeySym); |
158 | static void kpress(XEvent *); | 161 | static void kpress(XEvent *); |
159 | static void resize(XEvent *); | 162 | static void resize(XEvent *); |
160 | 163 | ||
@@ -313,6 +316,18 @@ tcursor(int mode) { | |||
313 | } | 316 | } |
314 | 317 | ||
315 | void | 318 | void |
319 | treset(void) { | ||
320 | term.c.attr.mode = ATTR_NULL; | ||
321 | term.c.attr.fg = DefaultFG; | ||
322 | term.c.attr.bg = DefaultBG; | ||
323 | term.c.x = term.c.y = 0; | ||
324 | term.hidec = 0; | ||
325 | term.top = 0, term.bot = term.row - 1; | ||
326 | term.mode = MODE_WRAP; | ||
327 | tclearregion(0, 0, term.col-1, term.row-1); | ||
328 | } | ||
329 | |||
330 | void | ||
316 | tnew(int col, int row) { /* screen size */ | 331 | tnew(int col, int row) { /* screen size */ |
317 | term.row = row, term.col = col; | 332 | term.row = row, term.col = col; |
318 | term.top = 0, term.bot = term.row - 1; | 333 | term.top = 0, term.bot = term.row - 1; |
@@ -323,17 +338,19 @@ tnew(int col, int row) { /* screen size */ | |||
323 | term.c.attr.fg = DefaultFG; | 338 | term.c.attr.fg = DefaultFG; |
324 | term.c.attr.bg = DefaultBG; | 339 | term.c.attr.bg = DefaultBG; |
325 | term.c.x = term.c.y = 0; | 340 | term.c.x = term.c.y = 0; |
326 | term.c.hidden = 0; | 341 | term.hidec = 0; |
327 | /* allocate screen */ | 342 | /* allocate screen */ |
328 | term.line = calloc(term.row, sizeof(Line)); | 343 | term.line = calloc(term.row, sizeof(Line)); |
329 | for(row = 0 ; row < term.row; row++) | 344 | for(row = 0 ; row < term.row; row++) |
330 | term.line[row] = calloc(term.col, sizeof(Glyph)); | 345 | term.line[row] = calloc(term.col, sizeof(Glyph)); |
331 | } | 346 | } |
332 | 347 | ||
348 | /* TODO: Replace with scrollup/scolldown */ | ||
333 | void | 349 | void |
334 | tscroll(void) { | 350 | tscroll(void) { |
335 | Line temp = term.line[term.top]; | 351 | Line temp = term.line[term.top]; |
336 | int i; | 352 | int i; |
353 | /* No dirty flag to set because of xscroll */ | ||
337 | /* X stuff _before_ the line swapping (results in wrong line index) */ | 354 | /* X stuff _before_ the line swapping (results in wrong line index) */ |
338 | xscroll(); | 355 | xscroll(); |
339 | for(i = term.top; i < term.bot; i++) | 356 | for(i = term.top; i < term.bot; i++) |
@@ -343,6 +360,41 @@ tscroll(void) { | |||
343 | } | 360 | } |
344 | 361 | ||
345 | void | 362 | void |
363 | tscrolldown (int n) { | ||
364 | int i; | ||
365 | Line temp; | ||
366 | |||
367 | /* TODO: set dirty flag or scroll with some X func */ | ||
368 | LIMIT(n, 0, term.bot-term.top+1); | ||
369 | |||
370 | for(i = 0; i < n; i++) | ||
371 | memset(term.line[term.bot-i], 0, term.col*sizeof(Glyph)); | ||
372 | |||
373 | for(i = term.bot; i >= term.top+n; i--) { | ||
374 | temp = term.line[i]; | ||
375 | term.line[i] = term.line[i-n]; | ||
376 | term.line[i-n] = temp; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | void | ||
381 | tscrollup (int n) { | ||
382 | int i; | ||
383 | Line temp; | ||
384 | LIMIT(n, 0, term.bot-term.top+1); | ||
385 | |||
386 | /* TODO: set dirty flag or scroll with some X func */ | ||
387 | for(i = 0; i < n; i++) | ||
388 | memset(term.line[term.top+i], 0, term.col*sizeof(Glyph)); | ||
389 | |||
390 | for(i = term.top; i <= term.bot-n; i++) { | ||
391 | temp = term.line[i]; | ||
392 | term.line[i] = term.line[i+n]; | ||
393 | term.line[i+n] = temp; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | void | ||
346 | tnewline(void) { | 398 | tnewline(void) { |
347 | int y = term.c.y + 1; | 399 | int y = term.c.y + 1; |
348 | if(y > term.bot) | 400 | if(y > term.bot) |
@@ -420,17 +472,20 @@ tsetchar(char c) { | |||
420 | 472 | ||
421 | void | 473 | void |
422 | tclearregion(int x1, int y1, int x2, int y2) { | 474 | tclearregion(int x1, int y1, int x2, int y2) { |
423 | int x, y; | 475 | int y, temp; |
476 | |||
477 | if(x1 > x2) | ||
478 | temp = x1, x1 = x2, x2 = temp; | ||
479 | if(y1 > y2) | ||
480 | temp = y1, y1 = y2, y2 = temp; | ||
424 | 481 | ||
425 | LIMIT(x1, 0, term.col-1); | 482 | LIMIT(x1, 0, term.col-1); |
426 | LIMIT(x2, 0, term.col-1); | 483 | LIMIT(x2, 0, term.col-1); |
427 | LIMIT(y1, 0, term.row-1); | 484 | LIMIT(y1, 0, term.row-1); |
428 | LIMIT(y2, 0, term.row-1); | 485 | LIMIT(y2, 0, term.row-1); |
429 | 486 | ||
430 | /* XXX: could be optimized */ | 487 | for(y = y1; y <= y2; y++) |
431 | for(x = x1; x <= x2; x++) | 488 | memset(&term.line[y][x1], 0, sizeof(Glyph)*(x2-x1+1)); |
432 | for(y = y1; y <= y2; y++) | ||
433 | memset(&term.line[y][x], 0, sizeof(Glyph)); | ||
434 | 489 | ||
435 | xclear(x1, y1, x2, y2); | 490 | xclear(x1, y1, x2, y2); |
436 | } | 491 | } |
@@ -542,9 +597,6 @@ tsetattr(int *attr, int l) { | |||
542 | case 7: | 597 | case 7: |
543 | term.c.attr.mode |= ATTR_REVERSE; | 598 | term.c.attr.mode |= ATTR_REVERSE; |
544 | break; | 599 | break; |
545 | case 8: | ||
546 | term.c.hidden = CURSOR_HIDE; | ||
547 | break; | ||
548 | case 22: | 600 | case 22: |
549 | term.c.attr.mode &= ~ATTR_BOLD; | 601 | term.c.attr.mode &= ~ATTR_BOLD; |
550 | break; | 602 | break; |
@@ -565,6 +617,8 @@ tsetattr(int *attr, int l) { | |||
565 | term.c.attr.fg = attr[i] - 30; | 617 | term.c.attr.fg = attr[i] - 30; |
566 | else if(BETWEEN(attr[i], 40, 47)) | 618 | else if(BETWEEN(attr[i], 40, 47)) |
567 | term.c.attr.bg = attr[i] - 40; | 619 | term.c.attr.bg = attr[i] - 40; |
620 | else | ||
621 | fprintf(stderr, "erresc: gfx attr %d unkown\n", attr[i]); | ||
568 | break; | 622 | break; |
569 | } | 623 | } |
570 | } | 624 | } |
@@ -590,7 +644,7 @@ csihandle(void) { | |||
590 | switch(escseq.mode) { | 644 | switch(escseq.mode) { |
591 | default: | 645 | default: |
592 | unknown: | 646 | unknown: |
593 | printf("erresc: unknown sequence -- "); | 647 | printf("erresc: unknown csi "); |
594 | csidump(); | 648 | csidump(); |
595 | /* die(""); */ | 649 | /* die(""); */ |
596 | break; | 650 | break; |
@@ -665,7 +719,14 @@ csihandle(void) { | |||
665 | break; | 719 | break; |
666 | } | 720 | } |
667 | break; | 721 | break; |
668 | case 'S': /* XXX: SU -- Scroll <n> line up (faked) */ | 722 | case 'S': /* SU -- Scroll <n> line up */ |
723 | DEFAULT(escseq.arg[0], 1); | ||
724 | tscrollup(escseq.arg[0]); | ||
725 | break; | ||
726 | case 'T': /* SD -- Scroll <n> line down */ | ||
727 | DEFAULT(escseq.arg[0], 1); | ||
728 | tscrolldown(escseq.arg[0]); | ||
729 | break; | ||
669 | case 'L': /* IL -- Insert <n> blank lines */ | 730 | case 'L': /* IL -- Insert <n> blank lines */ |
670 | DEFAULT(escseq.arg[0], 1); | 731 | DEFAULT(escseq.arg[0], 1); |
671 | tinsertblankline(escseq.arg[0]); | 732 | tinsertblankline(escseq.arg[0]); |
@@ -682,7 +743,7 @@ csihandle(void) { | |||
682 | case 12: /* att610 -- Stop blinking cursor (IGNORED) */ | 743 | case 12: /* att610 -- Stop blinking cursor (IGNORED) */ |
683 | break; | 744 | break; |
684 | case 25: | 745 | case 25: |
685 | term.c.hidden = 1; | 746 | term.hidec = 1; |
686 | break; | 747 | break; |
687 | case 1048: /* XXX: no alt. screen to erase/save */ | 748 | case 1048: /* XXX: no alt. screen to erase/save */ |
688 | case 1049: | 749 | case 1049: |
@@ -731,7 +792,7 @@ csihandle(void) { | |||
731 | case 12: /* att610 -- Start blinking cursor (IGNORED) */ | 792 | case 12: /* att610 -- Start blinking cursor (IGNORED) */ |
732 | break; | 793 | break; |
733 | case 25: | 794 | case 25: |
734 | term.c.hidden = 0; | 795 | term.hidec = 0; |
735 | break; | 796 | break; |
736 | case 1048: | 797 | case 1048: |
737 | case 1049: /* XXX: no alt. screen to erase/save */ | 798 | case 1049: /* XXX: no alt. screen to erase/save */ |
@@ -866,11 +927,15 @@ tputc(char c) { | |||
866 | break; | 927 | break; |
867 | case 'M': /* RI -- Reverse index */ | 928 | case 'M': /* RI -- Reverse index */ |
868 | if(term.c.y == term.top) | 929 | if(term.c.y == term.top) |
869 | tinsertblankline(1); | 930 | tscrolldown(1); |
870 | else | 931 | else |
871 | tmoveto(term.c.x, term.c.y-1); | 932 | tmoveto(term.c.x, term.c.y-1); |
872 | term.esc = 0; | 933 | term.esc = 0; |
873 | break; | 934 | break; |
935 | case 'c': /* RIS -- Reset to inital state */ | ||
936 | treset(); | ||
937 | term.esc = 0; | ||
938 | break; | ||
874 | case '=': /* DECPAM */ | 939 | case '=': /* DECPAM */ |
875 | term.mode |= MODE_APPKEYPAD; | 940 | term.mode |= MODE_APPKEYPAD; |
876 | term.esc = 0; | 941 | term.esc = 0; |
@@ -888,7 +953,7 @@ tputc(char c) { | |||
888 | term.esc = 0; | 953 | term.esc = 0; |
889 | break; | 954 | break; |
890 | default: | 955 | default: |
891 | fprintf(stderr, "erresc: unknown sequence ESC %02X '%c'\n", c, isprint(c)?c:'.'); | 956 | fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", c, isprint(c)?c:'.'); |
892 | term.esc = 0; | 957 | term.esc = 0; |
893 | } | 958 | } |
894 | } | 959 | } |
@@ -991,8 +1056,6 @@ xscroll(void) { | |||
991 | 1056 | ||
992 | void | 1057 | void |
993 | xinit(void) { | 1058 | xinit(void) { |
994 | XGCValues values; | ||
995 | unsigned long valuemask; | ||
996 | XClassHint chint; | 1059 | XClassHint chint; |
997 | XWMHints wmhint; | 1060 | XWMHints wmhint; |
998 | XSizeHints shint; | 1061 | XSizeHints shint; |
@@ -1005,9 +1068,10 @@ xinit(void) { | |||
1005 | die("Can't open display\n"); | 1068 | die("Can't open display\n"); |
1006 | 1069 | ||
1007 | /* font */ | 1070 | /* font */ |
1008 | if(!(dc.font = XLoadQueryFont(xw.dis, FONT))) | 1071 | if(!(dc.font = XLoadQueryFont(xw.dis, FONT)) || !(dc.bfont = XLoadQueryFont(xw.dis, BOLDFONT))) |
1009 | die("Can't load font %s\n", FONT); | 1072 | die("Can't load font %s\n", dc.font ? BOLDFONT : FONT); |
1010 | 1073 | ||
1074 | /* XXX: Assuming same size for bold font */ | ||
1011 | xw.cw = dc.font->max_bounds.rbearing - dc.font->min_bounds.lbearing; | 1075 | xw.cw = dc.font->max_bounds.rbearing - dc.font->min_bounds.lbearing; |
1012 | xw.ch = dc.font->ascent + dc.font->descent + LINESPACE; | 1076 | xw.ch = dc.font->ascent + dc.font->descent + LINESPACE; |
1013 | 1077 | ||
@@ -1027,10 +1091,7 @@ xinit(void) { | |||
1027 | dc.col[DefaultBG], | 1091 | dc.col[DefaultBG], |
1028 | dc.col[DefaultBG]); | 1092 | dc.col[DefaultBG]); |
1029 | /* gc */ | 1093 | /* gc */ |
1030 | values.foreground = XWhitePixel(xw.dis, xw.scr); | 1094 | dc.gc = XCreateGC(xw.dis, xw.win, 0, NULL); |
1031 | values.font = dc.font->fid; | ||
1032 | valuemask = GCForeground | GCFont; | ||
1033 | dc.gc = XCreateGC(xw.dis, xw.win, valuemask, &values); | ||
1034 | XMapWindow(xw.dis, xw.win); | 1095 | XMapWindow(xw.dis, xw.win); |
1035 | /* wm stuff */ | 1096 | /* wm stuff */ |
1036 | chint.res_name = TNAME, chint.res_class = TNAME; | 1097 | chint.res_name = TNAME, chint.res_class = TNAME; |
@@ -1060,7 +1121,8 @@ xdraws(char *s, Glyph base, int x, int y, int len) { | |||
1060 | if(base.mode & ATTR_GFX) | 1121 | if(base.mode & ATTR_GFX) |
1061 | for(i = 0; i < len; i++) | 1122 | for(i = 0; i < len; i++) |
1062 | s[i] = gfx[s[i]]; | 1123 | s[i] = gfx[s[i]]; |
1063 | 1124 | ||
1125 | XSetFont(xw.dis, dc.gc, base.mode & ATTR_BOLD ? dc.bfont->fid : dc.font->fid); | ||
1064 | XDrawImageString(xw.dis, xw.win, dc.gc, winx, winy, s, len); | 1126 | XDrawImageString(xw.dis, xw.win, dc.gc, winx, winy, s, len); |
1065 | 1127 | ||
1066 | if(base.mode & ATTR_UNDERLINE) | 1128 | if(base.mode & ATTR_UNDERLINE) |
@@ -1068,22 +1130,6 @@ xdraws(char *s, Glyph base, int x, int y, int len) { | |||
1068 | } | 1130 | } |
1069 | 1131 | ||
1070 | void | 1132 | void |
1071 | xdrawc(int x, int y, Glyph g) { | ||
1072 | XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch }; | ||
1073 | unsigned long xfg, xbg; | ||
1074 | |||
1075 | /* reverse video */ | ||
1076 | if(g.mode & ATTR_REVERSE) | ||
1077 | xfg = dc.col[g.bg], xbg = dc.col[g.fg]; | ||
1078 | else | ||
1079 | xfg = dc.col[g.fg], xbg = dc.col[g.bg]; | ||
1080 | /* background */ | ||
1081 | XSetBackground(xw.dis, dc.gc, xbg); | ||
1082 | XSetForeground(xw.dis, dc.gc, xfg); | ||
1083 | XDrawImageString(xw.dis, xw.win, dc.gc, r.x, r.y+dc.font->ascent, &g.c, 1); | ||
1084 | } | ||
1085 | |||
1086 | void | ||
1087 | xcursor(int mode) { | 1133 | xcursor(int mode) { |
1088 | static int oldx = 0; | 1134 | static int oldx = 0; |
1089 | static int oldy = 0; | 1135 | static int oldy = 0; |
@@ -1094,24 +1140,54 @@ xcursor(int mode) { | |||
1094 | 1140 | ||
1095 | if(term.line[term.c.y][term.c.x].state & GLYPH_SET) | 1141 | if(term.line[term.c.y][term.c.x].state & GLYPH_SET) |
1096 | g.c = term.line[term.c.y][term.c.x].c; | 1142 | g.c = term.line[term.c.y][term.c.x].c; |
1143 | |||
1097 | /* remove the old cursor */ | 1144 | /* remove the old cursor */ |
1098 | if(term.line[oldy][oldx].state & GLYPH_SET) | 1145 | if(term.line[oldy][oldx].state & GLYPH_SET) |
1099 | xdrawc(oldx, oldy, term.line[oldy][oldx]); | 1146 | xdraws(&term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, oldy, 1); |
1100 | else | 1147 | else |
1101 | xclear(oldx, oldy, oldx, oldy); | 1148 | xclear(oldx, oldy, oldx, oldy); |
1149 | |||
1102 | /* draw the new one */ | 1150 | /* draw the new one */ |
1103 | if(mode == CURSOR_DRAW) { | 1151 | if(mode == CURSOR_DRAW) { |
1104 | xdrawc(term.c.x, term.c.y, g); | 1152 | xdraws(&g.c, g, term.c.x, term.c.y, 1); |
1105 | oldx = term.c.x, oldy = term.c.y; | 1153 | oldx = term.c.x, oldy = term.c.y; |
1106 | } | 1154 | } |
1107 | } | 1155 | } |
1108 | 1156 | ||
1157 | |||
1158 | #ifdef DEBUG | ||
1159 | /* basic drawing routines */ | ||
1160 | void | ||
1161 | xdrawc(int x, int y, Glyph g) { | ||
1162 | XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch }; | ||
1163 | XSetBackground(xw.dis, dc.gc, dc.col[g.bg]); | ||
1164 | XSetForeground(xw.dis, dc.gc, dc.col[g.fg]); | ||
1165 | XSetFont(xw.dis, dc.gc, g.mode & ATTR_BOLD ? dc.bfont->fid : dc.font->fid); | ||
1166 | XDrawImageString(xw.dis, xw.win, dc.gc, r.x, r.y+dc.font->ascent, &g.c, 1); | ||
1167 | } | ||
1168 | |||
1169 | void | ||
1170 | draw_(int dummy) { | ||
1171 | int x, y; | ||
1172 | |||
1173 | xclear(0, 0, term.col-1, term.row-1); | ||
1174 | for(y = 0; y < term.row; y++) | ||
1175 | for(x = 0; x < term.col; x++) | ||
1176 | if(term.line[y][x].state & GLYPH_SET) | ||
1177 | xdrawc(x, y, term.line[y][x]); | ||
1178 | |||
1179 | if(!term.hidec) | ||
1180 | xcursor(CURSOR_DRAW); | ||
1181 | } | ||
1182 | #endif | ||
1183 | |||
1109 | void | 1184 | void |
1110 | draw(int redraw_all) { | 1185 | draw(int redraw_all) { |
1111 | int i, x, y, ox; | 1186 | int i, x, y, ox; |
1112 | Glyph base, new; | 1187 | Glyph base, new; |
1113 | char buf[DRAW_BUF_SIZ]; | 1188 | char buf[DRAW_BUF_SIZ]; |
1114 | 1189 | ||
1190 | /* XXX: optimize with GLYPH_DIRTY hint */ | ||
1115 | for(y = 0; y < term.row; y++) { | 1191 | for(y = 0; y < term.row; y++) { |
1116 | base = term.line[y][0]; | 1192 | base = term.line[y][0]; |
1117 | i = ox = 0; | 1193 | i = ox = 0; |
@@ -1129,8 +1205,7 @@ draw(int redraw_all) { | |||
1129 | } | 1205 | } |
1130 | xdraws(buf, base, ox, y, i); | 1206 | xdraws(buf, base, ox, y, i); |
1131 | } | 1207 | } |
1132 | if(!term.c.hidden) | 1208 | xcursor(term.hidec ? CURSOR_HIDE : CURSOR_DRAW); |
1133 | xcursor(CURSOR_DRAW); | ||
1134 | } | 1209 | } |
1135 | 1210 | ||
1136 | void | 1211 | void |
@@ -1179,7 +1254,7 @@ kpress(XEvent *ev) { | |||
1179 | break; | 1254 | break; |
1180 | case XK_Insert: | 1255 | case XK_Insert: |
1181 | if(shift) | 1256 | if(shift) |
1182 | /* XXX: paste X clipboard */; | 1257 | draw(1), puts("draw!")/* XXX: paste X clipboard */; |
1183 | break; | 1258 | break; |
1184 | default: | 1259 | default: |
1185 | fprintf(stderr, "errkey: %d\n", (int)ksym); | 1260 | fprintf(stderr, "errkey: %d\n", (int)ksym); |