summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Carbonneaux2014-08-29 13:23:30 -0400
committerQuentin Carbonneaux2014-08-29 13:23:30 -0400
commit46f7bf9ee38212d481754d0c7d8d2c6d36ed1c09 (patch)
treede2fa58b533bd4dc08031911341667ff27926fd7
parentd1e58cb2608044a0146299e0988fc3119ee58197 (diff)
burry old directory in history
-rw-r--r--old/buf.c255
-rw-r--r--old/win-efficient.c356
-rw-r--r--old/win-scroll-halfclean.c461
-rw-r--r--old/win-ugly.c30
-rw-r--r--old/win.c-1454
-rw-r--r--old/win.c-2449
-rw-r--r--old/xmess/.comfile1
-rw-r--r--old/xmess/gui.h102
-rw-r--r--old/xmess/win.c401
-rw-r--r--old/xmess/win.h30
-rwxr-xr-xold/xmess/x11bin27160 -> 0 bytes
-rw-r--r--old/xmess/x11.c357
-rw-r--r--old/xmess/x11.obin9664 -> 0 bytes
13 files changed, 0 insertions, 2896 deletions
diff --git a/old/buf.c b/old/buf.c
deleted file mode 100644
index 5d7afda..0000000
--- a/old/buf.c
+++ /dev/null
@@ -1,255 +0,0 @@
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "buf.h"
-#include "unicode.h"
-
-static Rune *hend(Page *);
-static void ins(Buf *, unsigned, Rune);
-static void move(Rune *, Rune *, unsigned);
-static Page *newpage(void);
-static Page *page(Buf *, unsigned *);
-static void setnl(Page *);
-
-Buf *
-buf_new(char path[])
-{
- Buf *b;
-
- b = malloc(sizeof *b);
- if (!b)
- return 0;
- snprintf(b->path, PathLen, "%s", path);
- b->p = newpage();
- b->last = 0;
- return b;
-}
-
-/* buf_ins_utf8 - Insert raw utf8 encoded text in buffer [b]
- * at position [pos]. The number of bytes processed is returned.
- */
-int
-buf_ins_utf8(Buf *b, unsigned pos, unsigned char *data, int len)
-{
- Rune r;
- int rd, total;
-
- total = 0;
- while ((rd = utf8_decode_rune(&r, data, len))) {
- ins(b, pos++, r);
- data += rd;
- len -= rd;
- total += rd;
- }
- return total;
-}
-
-unsigned
-buf_read(Buf *b, unsigned off, Rune *rs, unsigned len)
-{
- unsigned n, m;
- Page *p;
-
- if (len == 0)
- return 0;
-
- p = page(b, &off);
-
- if (off >= p->len) {
- if (p->n) {
- p = p->n;
- off = 0;
- } else
- return 0;
- }
-
- n = 0;
- do {
- m = p->hbeg - p->buf;
- if (off < m) {
- if (m - off > len - n)
- m = len - n;
- else
- m -= off;
- move(rs+n, p->buf+off, m);
- off += m;
- n += m;
- } else {
- off -= m; // offset after hole
- m = p->len - m;
- if (m - off > len - n)
- m = len - n;
- else
- m -= off;
- move(rs+n, hend(p)+off, m);
- n += m;
- if (p->n) {
- p = p->n;
- off = 0;
- } else
- return n;
- }
- } while (n < len);
-
- return n;
-}
-
-Rune
-buf_get(Buf *b, unsigned pos)
-{
- Rune r;
-
- r = NORUNE;
- buf_read(b, pos, &r, 1);
- return r;
-}
-
-/* static functions */
-
-/* hend - Get a pointer on the end of the hole in page [p].
- */
-static Rune *
-hend(Page *p)
-{
- return p->hbeg + (PageLen - p->len);
-}
-
-/* ins - Insert a rune in the buffer [b] at position [pos].
- */
-static void
-ins(Buf *b, unsigned pos, Rune r)
-{
- Page *p;
- unsigned off;
- long int shft;
-
- off = pos;
- p = page(b, &off);
-
- if (p->len == PageLen) { /* bad luck, grow a page */
- Page *q;
- enum { l = PageLen/2 };
-
- q = newpage();
- q->n = p->n;
- p->n = q;
-
- move(q->buf, &p->buf[l], PageLen-l);
- q->hbeg = q->buf + PageLen-l;
- q->len = PageLen-l;
-
- p->hbeg = p->buf + l;
- p->len = l;
-
- setnl(p);
- setnl(q);
- ins(b, pos, r);
- return;
- }
-
- shft = off - (p->hbeg - p->buf);
- if (shft) {
- if (shft>0)
- move(p->hbeg, hend(p), shft);
- else
- move(hend(p) + shft, p->hbeg + shft, -shft);
-
- p->hbeg += shft;
- }
-
- /* there we go */
- *p->hbeg++ = r;
- p->len++;
- if (r == '\n')
- p->nl++;
-}
-
-/* move - Move some runes in an array, works like
- * memmove the zones must not overlap.
- */
-static void
-move(Rune *dest, Rune *from, unsigned cnt)
-{
- memmove(dest, from, cnt * sizeof(Rune));
-}
-
-static Page *
-newpage(void)
-{
- Page *p;
-
- p = malloc(sizeof *p);
- assert(p);
- p->hbeg = p->buf;
- p->len = 0;
- p->nl = 0;
- p->n = 0;
- return p;
-}
-
-/* page - Get a page containing the [*ppos]'th position.
- * *ppos is also modified to represent the offset in the
- * page.
- */
-static Page *
-page(Buf *b, unsigned *ppos)
-{
- Page *p;
- unsigned off, pos;
-
- pos = *ppos;
- if (b->last) {
- if (pos < b->lastbeg) {
- off = 0;
- p = b->p;
- }
- else if (pos > b->lastbeg + b->last->len) {
- off = b->lastbeg;
- p = b->last;
- }
- else {
- *ppos -= b->lastbeg;
- return b->last;
- }
- } else {
- off = 0;
- p = b->p;
- }
-
- for (; p->n; p=p->n) {
- if (pos >= off && pos <= off + p->len)
- break;
- off += p->len;
- }
-
- b->lastbeg = off;
- b->last = p;
-
- pos -= off;
- if (pos > p->len)
- pos = p->len;
- *ppos = pos;
- return p;
-}
-
-/* setnl - Update the line count of a page.
- */
-static void
-setnl(Page *p)
-{
- Rune *r;
- int cnt;
-
- cnt = 0;
- for (r = p->buf; r < p->hbeg; r++)
- if (*r == '\n')
- cnt++;
-
- for (r = hend(p); r < &p->buf[PageLen]; r++)
- if (*r == '\n')
- cnt++;
-
- p->nl = cnt;
-}
diff --git a/old/win-efficient.c b/old/win-efficient.c
deleted file mode 100644
index 80bdb80..0000000
--- a/old/win-efficient.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*% clang -DWIN_TEST -Wall -g -I/usr/include/freetype2 -lX11 -lXft obj/unicode.o obj/buf.o obj/x11.o % -o #
- *
- * Windowing module
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-#include "win.h"
-
-enum {
- Draw = 1,
- Line = 2,
-};
-
-static void put(W *w, int flags);
-
-static W wins[MaxWins];
-static int nwins;
-static struct gui *g;
-static GFont font;
-static int fwidth, fheight;
-
-/* win_init - initialize the module using [gui] as a
- * graphical backed.
- */
-void
-win_init(struct gui *gui)
-{
- g = gui;
-
- g->init();
- g->getfont(&font);
-
- /* the gui module does not give a way to access the screen
- * dimension, instead, the first event generated will always
- * be a GResize, so we can adjust these dummy values with
- * win_resize_frame
- */
- fwidth = fheight = 10;
-}
-
-/* win_new - insert a new window if possible and
- * return it. In case of error (more than MaxWins
- * windows), 0 is returned.
- */
-W *
-win_new(Buf *b)
-{
- if (nwins!=0)
- return 0;
-
- memset(&wins[nwins], 0, sizeof(W));
- wins[nwins].b = b;
- wins[nwins].gw = g->newwin(0, 0, fwidth, fheight);
- wins[nwins].frac = FScale;
-
- nwins = 1;
- return &wins[0];
-}
-
-/* win_delete - delete a window created by win_new.
- */
-void
-win_delete(W *w)
-{
- assert(w >= wins);
- assert(w < wins+nwins);
- nwins = 0;
-}
-
-/* win_resize_frame - called when the whole frame
- * is resized.
- */
-void
-win_resize_frame(int w, int h)
-{
- GColor white = { 255, 255, 255 };
- int x, ww;
- W *pw;
-
- if (w!=0 && h!=0) {
- fwidth = w;
- fheight = h;
- }
-
- for (x=0, pw=wins; pw-wins<nwins; pw++) {
- ww = (fwidth * pw->frac) / FScale;
- g->movewin(pw->gw, x, 0, ww, fheight);
- g->drawrect(pw->gw, 0, 0, ww, fheight, white);
- put(pw, Draw);
- g->putwin(pw->gw);
- x += ww;
- }
-}
-
-/* win_redraw_frame - redraw the whole frame.
- */
-void
-win_redraw_frame(void)
-{
- win_resize_frame(0, 0);
-}
-
-/* win_scroll - scroll the window by [n] lines.
- * If [n] is negative it will scroll backwards.
- * The number of lines scrolled must not be
- * bigger than the number of lines currently on
- * the screen.
- */
-void
-win_scroll(W *w, int n)
-{
- int top;
- unsigned off, bol;
- W wscratch;
-
- if (w->nls == 0 || n == 0)
- return;
-
- assert(n < 0 || n <= w->nls);
-
- wscratch.b = w->b;
- wscratch.gw = w->gw;
-
- if (n<0) {
- off = w->loff[0];
-
- do {
- if (off == 0)
- break;
-
- bol = buf_bol(w->b, off-1);
- wscratch.loff[0] = bol;
- put(&wscratch, Line);
-
- top = wscratch.nls - 1;
- do {
- off = wscratch.loff[top--];
- if (off < w->loff[0])
- ++n;
- } while (off >= w->loff[0] || (top>=0 && n<0));
- } while (n<0);
- } else
- off = w->loff[n];
-
- w->loff[0] = off;
- put(w, 0); /* update line offsets */
-
- if (w->cl == -1) { /* fix the cursor position */
- if (n>0)
- w->coff = w->loff[0];
- else
- w->coff = w->loff[w->nls-1];
- }
-}
-
-/* static functions */
-
-
-/* this function tries to factor calls to the pretty expensive
- * [drawtext] function of the gui module, we basically try to aggregate
- * all potential calls into one. Sometimes it is necessary to flush,
- * for instance when the are displaying a new line or when a tabulation
- * has to be printed. Tabs are treated specially because they have
- * a width the drawtext function does not know a priori.
- *
- * Calling this function with [r == NORUNE] will force a flush.
- *
- * Before using this I called drawtext for each char, on a big screen
- * the slowdown was significative.
- */
-static void
-draw(GWin *gw, Rune r, int x, int y, int rw, int cu)
-{
- static int fragx = -1, fragy, cx = -1, cy, cw;
- static Rune frag[MaxWidth], *p = frag;
- int flush;
- GColor color = { .blue = 255 },
- xor = { .x = 1 };
-
- flush = 0;
-
- if (r != NORUNE && fragx == -1) {
- fragx = x;
- fragy = y;
- }
-
- if (r != NORUNE && y == fragy) {
- if (cu) {
- cx = x;
- cy = y-font.ascent;
- cw = rw;
- }
-
- if (r != '\t') {
- assert(p-frag < MaxWidth);
- *p++ = r;
- } else
- flush = 1;
- } else
- flush = 1;
-
- /* we flush the current fragment if one
- * of the following conditions is met
- * - the current rune is a tab
- * - the current rune is a NORUNE (signaling eof)
- * - the rune's y is different from the fragment's y
- * (signaling a newline)
- */
- if (flush) {
-#if 0
- printf("flushing: fragx = %d\n"
- " fragy = %d\n"
- " r = %u\n"
- " len = %zd\n",
- fragx, fragy, r, p-frag);
-#endif
- if (fragx == -1)
- return;
-
- g->drawtext(gw, frag, p-frag, fragx, fragy, color);
- if (cx != -1)
- g->drawrect(gw, cx, cy, cw, font.height, xor);
-
- fragx = cx = -1;
- p = frag;
-
- if (r != NORUNE && r != '\n' && fragy != y)
- /* push r on frag with a recursive call */
- draw(gw, r, x, y, rw, cu);
- }
-}
-
-static void
-put(W *w, int flags)
-{
- unsigned off, i, nl;
- int rw, x, y, lnum;
- Rune r;
- GWin *gw;
-
- off = w->loff[0];
- gw = w->gw;
- x = 0;
- y = font.ascent;
- lnum = 0;
- w->loff[lnum++] = off;
- w->cl = -1;
-
- for (i=0; y < gw->h || (flags & Line); i++) {
- r = buf_get(w->b, off+i);
- if (r == NORUNE) {
- lnum++;
- break;
- }
-
-
- if (r == '\t') {
- rw = TabWidth * font.width;
- rw -= x % (TabWidth * font.width);
- } else {
- nl = 0;
- if (r != '\n') {
- if (unicode_rune_width(r) == 0)
- continue;
- rw = g->textwidth(&r, 1);
- if (x+rw > gw->w)
- nl = off+i;
- } else if ((flags & Line) == 0) {
- nl = off+i+1;
- rw = 0;
- } else {
- lnum++;
- break;
- }
-
- if (nl) {
- y += font.height;
- x = 0;
- if (lnum < MaxLines)
- w->loff[lnum++] = nl;
- else {
- /* should use a ring buffer... */
- assert(lnum == MaxLines);
- memmove(w->loff, w->loff+1,
- (MaxLines-1) * sizeof(int));
- w->loff[MaxLines-1] = nl;
- }
- }
- }
-
- if (w->coff == off+i)
- w->cl = lnum;
- if ((flags & Draw)
- draw(gw, r, x, y, rw, w->coff == off+i);
-
- x += rw;
- }
-
- if (flags & Draw)
- draw(gw, NORUNE, 0, 0, 0, 0);
- w->nls = lnum - 1;
-}
-
-#ifdef WIN_TEST
-/* test */
-
-#include <stdlib.h>
-
-void die(char *m) { exit(1); }
-
-int main(void)
-{
- GEvent e;
- Buf *b;
- W *w;
- unsigned char s[] =
- "je suis\n"
- "\tQuentin\n"
- "tab\ttest\n"
- "une longue longue longue longue longue longue longue longue longue longue longue longue longue ligne\n"
- "un peu d'unicode: ä æ ç\n"
- "et voila!\n";
-
- b = buf_new("*");
- win_init(&gui_x11);
- w = win_new(b);
-
- for (int i=0; i<20; i++)
- buf_ins_utf8(b, 0, s, sizeof s - 1);
-
- do {
- g->nextevent(&e);
- if (e.type == GResize)
- win_resize_frame(e.resize.width, e.resize.height);
- if (e.type == GKey) {
- switch (e.key) {
- case 'l': w->coff++; break;
- case 'h': w->coff--; break;
- case 'e'-'a' + 1: win_scroll(w, 1); break;
- case 'y'-'a' + 1: win_scroll(w, -1); break;
- default: continue;
- }
- win_redraw_frame();
- }
- } while (e.type != GKey || e.key != 'q');
-
- g->fini();
- return 0;
-}
-
-#endif
diff --git a/old/win-scroll-halfclean.c b/old/win-scroll-halfclean.c
deleted file mode 100644
index 390b9c5..0000000
--- a/old/win-scroll-halfclean.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*% clang -DWIN_TEST -Wall -g -I/usr/include/freetype2 -lX11 -lXft obj/unicode.o obj/buf.o obj/x11.o % -o #
- *
- * Windowing module
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-#include "win.h"
-
-enum CursorPos { Top, Bot };
-enum Focus { FocusBol, FocusEol, FocusCu };
-
-enum { RingSize = 32 };
-struct lineinfo {
- int beg, len; /* begining and len of the sl ring buffer */
- unsigned sl[RingSize]; /* ring buffer of screen line offsets */
- int cul; /* cursor line in sl */
-};
-
-static void pushrune(GWin *gw, Rune r, int x, int y, int w, int cu);
-static void draw(W *w);
-static unsigned lineinfo(W *w, unsigned off, struct lineinfo *li, enum Focus f);
-
-static W wins[MaxWins];
-static int nwins;
-static struct gui *g;
-static GFont font;
-static int fwidth, fheight;
-
-/* win_init - initialize the module using [gui] as a
- * graphical backed.
- */
-void
-win_init(struct gui *gui)
-{
- g = gui;
-
- g->init();
- g->getfont(&font);
-
- /* the gui module does not give a way to access the screen
- * dimension, instead, the first event generated will always
- * be a GResize, so we can adjust these dummy values with
- * win_resize_frame
- */
- fwidth = fheight = 10;
-}
-
-/* win_new - insert a new window if possible and
- * return it. In case of error (more than MaxWins
- * windows), 0 is returned.
- */
-W *
-win_new(Buf *b)
-{
- if (nwins!=0)
- return 0;
-
- memset(&wins[nwins], 0, sizeof(W));
- wins[nwins].b = b;
- wins[nwins].gw = g->newwin(0, 0, fwidth, fheight);
- wins[nwins].vfrac = FScale;
-
- nwins = 1;
- return &wins[0];
-}
-
-/* win_delete - delete a window created by win_new.
- */
-void
-win_delete(W *w)
-{
- assert(w >= wins);
- assert(w < wins+nwins);
- nwins = 0;
-}
-
-/* win_resize_frame - called when the whole frame
- * is resized.
- */
-void
-win_resize_frame(int w, int h)
-{
- GColor white = { 255, 255, 255 };
- int x, ww;
- W *pw;
-
- if (w!=0 && h!=0) {
- fwidth = w;
- fheight = h;
- }
-
- for (x=0, pw=wins; pw-wins<nwins; pw++) {
- pw->height = fheight;
- ww = (fwidth * pw->vfrac) / FScale;
- g->movewin(pw->gw, x, 0, ww, fheight);
- g->drawrect(pw->gw, 0, 0, ww, fheight, white);
- draw(pw);
- g->putwin(pw->gw);
- x += ww;
- }
-}
-
-/* win_redraw_frame - redraw the whole frame.
- */
-void
-win_redraw_frame()
-{
- win_resize_frame(0, 0);
-}
-
-/* win_scroll - scroll the window by [n] lines.
- * If [n] is negative it will scroll backwards.
- * The algorithm is guaranteed to work properly
- * when RingSize is larger than the number of
- * lines on a screen. In any cases, it should
- * not crash.
- */
-void
-win_scroll(W *w, int n)
-{
-
- struct lineinfo li;
- unsigned start, bol, eol;
- int dir;
-
- if (n == 0)
- return;
-
- dir = n;
- li.cul = -1;
-
- if (n < 0) {
- start = w->start;
- do {
- int top;
-
- if (start == 0)
- /* already at the top */
- break;
- bol = buf_bol(w->b, start-1);
-
- li.beg = li.len = 0;
- lineinfo(w, bol, &li, FocusEol);
- top = li.len - 1;
- for (; n<0; top--) {
- if (top < 0) {
- /* move to prev line */
- start = bol;
- n++;
- break;
- }
- start = li.sl[(li.beg + top) % RingSize];
- if (start < w->start)
- n++;
- }
- } while (n<0);
- w->start = start;
- } else {
- start = w->start;
- do {
- int top;
-
- li.beg = li.len = 0;
- eol = lineinfo(w, start, &li, FocusBol);
- top = 0;
- for (; n>0; top++, n--) {
- if (top >= li.len) {
- /* move to next line */
- start = eol;
- n--;
- break;
- }
- start = li.sl[(li.beg + top) % RingSize];
- }
- } while (n>0);
- w->start = start;
- }
-}
-
-/* win_show_cursor - find the cursor in [w] and adjust
- * the text view so that the cursor is displayed on the
- * screen. Depending on [where], the cursor will be
- * displayed at the top or at the bottom of the screen.
- */
-void
-win_show_cursor(W *w, enum CursorPos where)
-{
- // XXX implement me
-}
-
-/* static functions */
-
-typedef int (*LineFn)(void *data, unsigned off, Rune r, int x, int rw, int sl);
-
-static unsigned
-line(W *w, unsigned off, LineFn f, void *data)
-{
- Rune r;
- int l, x, rw;
-
- x = 0;
- l = 0;
-
- for (;; off++) {
- r = buf_get(w->b, off);
- if (r == NORUNE)
- break;
- if (r == '\n') {
- off++;
- break;
- }
-
- if (r == '\t') {
- int tw;
-
- tw = TabWidth * font.width;
- rw = tw - x % tw;
- } else
- rw = g->textwidth(&r, 1);
-
- if (x+rw > w->gw->w)
- if (x != 0) { /* force progress */
- x = 0;
- l++;
- }
-
- if (!f(data, off, r, x, rw, l)) {
- off++;
- break;
- }
-
- x += rw;
- }
-
- return off;
-}
-
-/* aggregate all calls to [drawtext] into batches, it
- * will flush if the current character is \n or \t.
- */
-static void
-pushrune(GWin *gw, Rune r, int x, int y, int w, int cu)
-{
- static int fragx = -1, fragy, cx = -1, cy, cw;
- static Rune frag[MaxWidth], *p = frag;
- GColor color = { .blue = 255 },
- xor = { .x = 1 };
-
- assert(r == '\n' || fragx == -1 || y == fragy);
-
- if (fragx == -1) {
- fragx = x;
- fragy = y;
- }
-
- if (cu) {
- cx = x;
- cy = y - font.ascent;
- cw = w;
- }
-
- if (r == '\t' || r == '\n') {
-#if 0
- printf("flushing: fragx = %d\n"
- " fragy = %d\n"
- " r = %u\n"
- " len = %td\n",
- fragx, fragy, r, p-frag);
-#endif
- assert(fragx != -1);
- g->drawtext(gw, frag, p-frag, fragx, fragy, color);
- if (cx != -1)
- g->drawrect(gw, cx, cy, cw, font.height, xor);
-
- fragx = cx = -1;
- p = frag;
- return;
- }
-
- assert(p-frag < MaxWidth);
- *p++ = r;
-}
-
-struct dstatus {
- W *w;
- int begl, curl;
- unsigned stop;
-};
-
-/* to be called as a LineFn by the [line] function */
-static int
-drawfn(void *data, unsigned off, Rune r, int x, int rw, int sl)
-{
- int y;
- struct dstatus *ds = data;
-
- y = (ds->begl + sl) * font.height + font.ascent;
- if (y > ds->w->height) {
- ds->stop = off;
- return 0;
- }
-
- if (ds->curl != sl) { /* need a flush, we changed screen line */
- assert(x == 0);
- pushrune(ds->w->gw, '\n', 0, 0, 0, 0);
- ds->curl = sl;
- }
-
- pushrune(ds->w->gw, r, x, y, rw, off == ds->w->cu);
- return 1;
-}
-
-static void
-draw(W *w)
-{
- unsigned boff, eoff;
- struct dstatus ds;
-
- ds.w = w;
- ds.begl = 0;
- ds.curl = 0;
- ds.stop = -1;
- eoff = w->start;
-
- do {
- boff = eoff;
- eoff = line(w, boff, drawfn, &ds);
- pushrune(w->gw, '\n', 0, 0, 0, 0); /* flush */
- ds.begl += ds.curl + 1;
- } while (ds.stop == -1u && eoff != boff);
-
- if (eoff == boff)
- w->stop = eoff;
- else
- w->stop = ds.stop;
-}
-
-static void
-pushoff(struct lineinfo *li, unsigned off)
-{
- assert(li->len <= RingSize);
-
- if (li->len == RingSize) {
- li->sl[li->beg] = off;
- li->beg++;
- li->beg %= RingSize;
- if (li->cul != -1)
- li->cul--;
- } else {
- int n;
-
- n = (li->beg + li->len) % RingSize;
- li->sl[n] = off;
- li->len++;
- }
-}
-
-struct lstatus {
- enum Focus f;
- unsigned cu;
- struct lineinfo *li;
- int curl;
-};
-
-static int
-lineinfofn(void *data, unsigned off,
- __attribute__((unused)) Rune r,
- __attribute__((unused)) int x,
- __attribute__((unused)) int rw,
- int sl)
-{
- struct lstatus *ls = data;
-
- if (ls->curl != sl) {
- assert(ls->curl == sl-1);
-
- if (ls->f == FocusEol
- || (ls->f == FocusBol && ls->li->len < RingSize)
- || (ls->f == FocusCu && ls->li->cul == -1))
- pushoff(ls->li, off);
-
- ls->curl = sl;
- }
-
- if (ls->f == FocusCu && off == ls->cu)
- ls->li->cul = ls->li->len - 1;
-
- return 1;
-}
-
-/* the api is not yet perfect: we should be able to specify
- * a maximum offset that makes lineinfofn return 0 to block
- * the line function
- */
-static unsigned
-lineinfo(W *w, unsigned off, struct lineinfo *li, enum Focus f)
-{
- struct lstatus ls;
-
- ls.f = f;
- ls.cu = w->cu;
- ls.li = li;
- ls.curl = 0;
-
- return line(w, off, lineinfofn, &ls);
-}
-
-#ifdef WIN_TEST
-/* test */
-
-#include <stdlib.h>
-
-void die(char *m) { exit(1); }
-
-int main()
-{
- GEvent e;
- Buf *b;
- W *w;
- enum CursorPos cpos;
- unsigned char s[] =
- "je suis\n"
- "\tQuentin\n"
- "tab\ttest\n"
- "une longue longue longue longue longue longue longue longue longue longue longue longue longue ligne\n"
- "un peu d'unicode: ä æ ç\n"
- "et voila!\n";
-
- b = buf_new("*");
- win_init(&gui_x11);
- w = win_new(b);
-
- for (int i=0; i<20; i++)
- buf_ins_utf8(b, 0, s, sizeof s - 1);
-
- do {
- g->nextevent(&e);
- if (e.type == GResize)
- win_resize_frame(e.resize.width, e.resize.height);
- if (e.type == GKey) {
- switch (e.key) {
- case 'l': ++w->cu; cpos = Bot; break;
- case 'h': --w->cu; cpos = Top; break;
- case 'e'-'a' + 1: win_scroll(w, 1); break;
- case 'y'-'a' + 1: win_scroll(w, -1); break;
- default: continue;
- }
- win_redraw_frame();
- }
- } while (e.type != GKey || e.key != 'q');
-
- g->fini();
- return 0;
-}
-
-#endif
diff --git a/old/win-ugly.c b/old/win-ugly.c
deleted file mode 100644
index ea37ef5..0000000
--- a/old/win-ugly.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef WIN_H
-#define WIN_H
-
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-
-enum {
- FScale = 16384, /* fixed point scale */
- TabWidth = 8, /* tabulation width */
- MaxLines = 1000, /* max number of lines on screen */
- MaxWidth = 500, /* max width of the screen */
-};
-
-typedef struct w W;
-struct w {
- unsigned start, stop; /* offset of the first/last character displayed */
- unsigned coff; /* cursor offset */
- int cl; /* cursor line (on screen) */
- int nls; /* number of displayed lines on screen */
- int vfrac, height; /* vertical fraction and height of the window */
- Buf *b; /* underlying buffer object */
- GWin *gw; /* graphical window associated */
-};
-
-void win_init(struct gui *g);
-W *win_new(Buf *b);
-void win_resize_frame(int w, int h);
-
-#endif /* ndef WIN_H */
diff --git a/old/win.c-1 b/old/win.c-1
deleted file mode 100644
index 004b39b..0000000
--- a/old/win.c-1
+++ /dev/null
@@ -1,454 +0,0 @@
-/*% clang -DWIN_TEST -Wall -g -I/usr/include/freetype2 -lX11 -lXft obj/unicode.o obj/buf.o obj/x11.o % -o #
- *
- * Windowing module
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-#include "win.h"
-
-enum CursorPos { Top, Bot };
-
-enum { RingSize = 2 }; /* bigger is (a bit) faster */
-_Static_assert(RingSize >= 2, "RingSize must be at least 2");
-
-struct lineinfo {
- int beg, len; /* begining and len of the sl ring buffer */
- unsigned sl[RingSize]; /* ring buffer of screen line offsets */
-};
-
-static void draw(W *w);
-static void lineinfo(W *w, unsigned off, unsigned lim, struct lineinfo *li);
-
-static W wins[MaxWins];
-static int nwins;
-static struct gui *g;
-static GFont font;
-static int fwidth, fheight;
-
-/* win_init - initialize the module using [gui] as a
- * graphical backed.
- */
-void
-win_init(struct gui *gui)
-{
- g = gui;
-
- g->init();
- g->getfont(&font);
-
- /* the gui module does not give a way to access the screen
- * dimension, instead, the first event generated will always
- * be a GResize, so we can adjust these dummy values with
- * win_resize_frame
- */
- fwidth = fheight = 10;
-}
-
-/* win_new - insert a new window if possible and
- * return it. In case of error (more than MaxWins
- * windows), 0 is returned.
- */
-W *
-win_new(Buf *b)
-{
- if (nwins!=0)
- return 0;
-
- memset(&wins[nwins], 0, sizeof(W));
- wins[nwins].b = b;
- wins[nwins].gw = g->newwin(0, 0, fwidth, fheight);
- wins[nwins].vfrac = FScale;
-
- nwins = 1;
- return &wins[0];
-}
-
-/* win_delete - delete a window created by win_new.
- */
-void
-win_delete(W *w)
-{
- assert(w >= wins);
- assert(w < wins+nwins);
- nwins = 0;
-}
-
-/* win_resize_frame - called when the whole frame
- * is resized.
- */
-void
-win_resize_frame(int w, int h)
-{
- GColor white = { 255, 255, 255 };
- int x, ww;
- W *pw;
-
- if (w!=0 && h!=0) {
- fwidth = w;
- fheight = h;
- }
-
- for (x=0, pw=wins; pw-wins<nwins; pw++) {
- pw->height = fheight;
- ww = (fwidth * pw->vfrac) / FScale;
- g->movewin(pw->gw, x, 0, ww, fheight);
- g->drawrect(pw->gw, 0, 0, ww, fheight, white);
- draw(pw);
- g->putwin(pw->gw);
- x += ww;
- }
-}
-
-/* win_redraw_frame - redraw the whole frame.
- */
-void
-win_redraw_frame()
-{
- win_resize_frame(0, 0);
-}
-
-/* win_scroll - scroll the window by [n] lines.
- * If [n] is negative it will scroll backwards.
- */
-void
-win_scroll(W *w, int n)
-{
-
- struct lineinfo li;
- unsigned start, bol;
- int dir;
-
- if (n == 0)
- return;
-
- dir = n;
-
- if (n < 0) {
- start = w->start;
- do {
- int top;
-
- if (start == 0)
- /* already at the top */
- break;
- bol = buf_bol(w->b, start-1);
-
- li.beg = li.len = 0;
- lineinfo(w, bol, start-1, &li);
- top = li.len - 2;
- assert(top >= 0);
- for (; n<0 && top>=0; top--, n++) {
- start = li.sl[(li.beg + top) % RingSize];
- assert(start < w->start);
- }
- } while (n<0);
- w->start = start;
- } else {
- start = w->start;
- do {
- int top;
-
- li.beg = li.len = 0;
- lineinfo(w, start, -1, &li);
- top = 1;
- assert(top < li.len);
- for (; n>0 && top<li.len; top++, n--) {
- start = li.sl[(li.beg + top) % RingSize];
- assert(start > w->start);
- }
- } while (n>0);
- w->start = start;
- }
-}
-
-/* win_show_cursor - find the cursor in [w] and adjust
- * the text view so that the cursor is displayed on the
- * screen. Depending on [where], the cursor will be
- * displayed at the top or at the bottom of the screen.
- */
-void
-win_show_cursor(W *w, enum CursorPos where)
-{
- struct lineinfo li;
- unsigned bol;
-
- bol = buf_bol(w->b, w->cu);
- li.beg = li.len = 0;
- lineinfo(w, bol, w->cu, &li);
- assert(li.len >= 2);
- w->start = li.sl[(li.beg + li.len-2) % RingSize];
- if (where == Bot)
- win_scroll(w, -w->height/font.height + 1);
-}
-
-/* static functions */
-
-typedef int (*LineFn)(void *data, unsigned off, Rune r, int x, int rw, int sl);
-
-static unsigned
-line(W *w, unsigned off, LineFn f, void *data)
-{
- Rune r;
- int l, x, rw;
-
- x = 0;
- l = 0;
-
- for (;; off++) {
- r = buf_get(w->b, off);
- if (r == NORUNE)
- break;
- if (r == '\n') {
- off++;
- break;
- }
-
- if (r == '\t') {
- int tw;
-
- tw = TabWidth * font.width;
- rw = tw - x % tw;
- } else
- rw = g->textwidth(&r, 1);
-
- if (x+rw > w->gw->w)
- if (x != 0) { /* force progress */
- x = 0;
- l++;
- }
-
- if (!f(data, off, r, x, rw, l))
- break;
-
- x += rw;
- }
-
- return off;
-}
-
-/* aggregate all calls to [drawtext] into batches, it
- * will flush if the current character is \n or \t.
- */
-static void
-pushrune(GWin *gw, Rune r, int x, int y, int w, int cu)
-{
- static int fragx = -1, fragy, cx = -1, cy, cw;
- static Rune frag[MaxWidth], *p = frag;
- GColor color = { .blue = 255 },
- xor = { .x = 1 };
-
- assert(r == '\n' || fragx == -1 || y == fragy);
-
- if (fragx == -1) {
- fragx = x;
- fragy = y;
- }
-
- if (cu) {
- cx = x;
- cy = y - font.ascent;
- cw = w;
- }
-
- if (r == '\t' || r == '\n') {
-#if 0
- printf("flushing: fragx = %d\n"
- " fragy = %d\n"
- " r = %u\n"
- " len = %td\n"
- " frag = '",
- fragx, fragy, r, p-frag);
- for (int i=0; i<p-frag; i++)
- printf("%c", (char)frag[i]);
- printf("'\n");
-#endif
- assert(fragx != -1);
- g->drawtext(gw, frag, p-frag, fragx, fragy, color);
- if (cx != -1)
- g->drawrect(gw, cx, cy, cw, font.height, xor);
-
- fragx = cx = -1;
- p = frag;
- return;
- }
-
- assert(p-frag < MaxWidth);
- *p++ = r;
-}
-
-struct dstatus {
- W *w;
- int begl, curl;
-};
-
-/* to be called as a LineFn by the [line] function */
-static int
-drawfn(void *data, unsigned off, Rune r, int x, int rw, int sl)
-{
- int y;
- struct dstatus *ds = data;
-
- y = (ds->begl + sl) * font.height + font.ascent;
- if (y + font.descent > ds->w->height)
- return 0;
-
- if (ds->curl != sl) { /* need a flush, we changed screen line */
- assert(x == 0);
- ds->curl = sl;
- pushrune(ds->w->gw, '\n', 0, 0, 0, 0);
- }
-
- pushrune(ds->w->gw, r, x, y, rw, off == ds->w->cu);
- return 1;
-}
-
-static void
-draw(W *w)
-{
- int nls;
- unsigned off;
- struct dstatus ds;
-
- ds.w = w;
- ds.begl = 0;
- ds.curl = 0;
- off = w->start;
- nls = w->height/font.height;
-
- do {
- off = line(w, off, drawfn, &ds);
- pushrune(w->gw, '\n', 0, 0, 0, 0); /* flush */
- ds.begl += ds.curl + 1;
- ds.curl = 0;
- } while (ds.begl < nls);
-
- w->stop = off;
-}
-
-static int
-pushoff(struct lineinfo *li, unsigned off, int overwrite)
-{
- assert(li->len <= RingSize);
-
- if (li->len == RingSize) {
- if (!overwrite)
- return 0;
- li->sl[li->beg] = off;
- li->beg++;
- li->beg %= RingSize;
- } else {
- int n;
-
- n = (li->beg + li->len) % RingSize;
- li->sl[n] = off;
- li->len++;
- }
- return 1;
-}
-
-struct lstatus {
- unsigned lim;
- struct lineinfo *li;
- int curl;
-};
-
-static int
-lineinfofn(void *data, unsigned off,
- __attribute__((unused)) Rune r,
- __attribute__((unused)) int x,
- __attribute__((unused)) int rw,
- int sl)
-{
- struct lstatus *ls = data;
-
- if (off > ls->lim)
- return 0;
-
- if (ls->curl != sl) {
- assert(ls->curl == sl-1);
- ls->curl = sl;
- return pushoff(ls->li, off, ls->lim != -1u);
- }
-
- return 1;
-}
-
-/* if [lim == -1] the lineinfo will only contain information
- * about the first RingSize screen lines
- */
-static void
-lineinfo(W *w, unsigned off, unsigned lim, struct lineinfo *li)
-{
- struct lstatus ls;
-
- assert(RingSize >= 2);
-
- ls.lim = lim;
- ls.li = li;
- ls.curl = 0;
-
- pushoff(li, off, lim != -1u);
- off = line(w, off, lineinfofn, &ls);
- pushoff(li, off, lim != -1u);
-}
-
-#ifdef WIN_TEST
-/* test */
-
-#include <stdlib.h>
-
-void die(char *m) { exit(1); }
-
-int main()
-{
- GEvent e;
- Buf *b;
- W *w;
- enum CursorPos cpos;
- unsigned char s[] =
- "je suis\n"
- "\tQuentin\n"
- "tab\ttest\n"
- "une longue longue longue longue longue longue longue longue longue longue longue longue longue ligne\n"
- "un peu d'unicode: ä æ ç\n"
- "et voila!\n\n";
-
- b = buf_new("*");
- win_init(&gui_x11);
- w = win_new(b);
-
- for (int i=0; i<20; i++)
- buf_ins_utf8(b, 0, s, sizeof s - 1);
-
- do {
- g->nextevent(&e);
- if (e.type == GResize)
- win_resize_frame(e.resize.width, e.resize.height);
- if (e.type == GKey) {
- switch (e.key) {
- case 'l': ++w->cu; cpos = Bot; break;
- case 'h': --w->cu; cpos = Top; break;
- case 'e'-'a' + 1: win_scroll(w, 1); break;
- case 'y'-'a' + 1: win_scroll(w, -1); break;
- default: continue;
- }
- win_redraw_frame();
- if (e.key == 'l' || e.key == 'h')
- if (w->cu < w->start || w->cu >= w->stop) {
- win_show_cursor(w, cpos);
- win_redraw_frame();
- }
-
- }
- } while (e.type != GKey || e.key != 'q');
-
- g->fini();
- return 0;
-}
-
-#endif
diff --git a/old/win.c-2 b/old/win.c-2
deleted file mode 100644
index bc6d712..0000000
--- a/old/win.c-2
+++ /dev/null
@@ -1,449 +0,0 @@
-/*% clang -DWIN_TEST -Wall -g $(pkg-config --libs x11 xft) obj/{unicode,buf,x11}.o % -o #
- *
- * Windowing module
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "tools.h"
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-#include "win.h"
-
-enum {
- RingSize = 2, /* bigger is (a bit) faster */
-};
-static_assert(RingSize >= 2, "too small");
-
-struct lineinfo {
- int beg, len;
- unsigned sl[RingSize]; /* screen line offsets */
-};
-
-static void draw(W *w);
-static void lineinfo(W *w, unsigned off, unsigned lim, struct lineinfo *li);
-
-static W wins[MaxWins];
-static int nwins;
-static struct gui *g;
-static GFont font;
-static int fwidth, fheight;
-
-/* win_init - Initialize the module using [gui] as a
- * graphical backed.
- */
-void
-win_init(struct gui *gui)
-{
- g = gui;
-
- g->init();
- g->getfont(&font);
-
- /* the gui module does not give a way to access the screen
- * dimension, instead, the first event generated will always
- * be a GResize, so we can adjust these dummy values with
- * win_resize_frame
- */
- fwidth = fheight = 10;
-}
-
-/* win_new - Insert a new window if possible and
- * return it. In case of error (more than MaxWins
- * windows), 0 is returned.
- */
-W *
-win_new(Buf *b)
-{
- if (nwins!=0)
- return 0;
-
- memset(&wins[nwins], 0, sizeof(W));
- wins[nwins].b = b;
- wins[nwins].gw = g->newwin(0, 0, fwidth, fheight);
- wins[nwins].vfrac = FScale;
-
- nwins = 1;
- return &wins[0];
-}
-
-/* win_delete - Delete a window created by win_new.
- */
-void
-win_delete(W *w)
-{
- assert(w >= wins);
- assert(w < wins+nwins);
- nwins = 0;
-}
-
-/* win_resize_frame - Called when the whole frame
- * is resized.
- */
-void
-win_resize_frame(int w, int h)
-{
- GColor white = { 255, 255, 255 };
- int x, ww;
- W *pw;
-
- if (w!=0 && h!=0) {
- fwidth = w;
- fheight = h;
- }
-
- for (x=0, pw=wins; pw-wins<nwins; pw++) {
- pw->height = fheight;
- ww = (fwidth * pw->vfrac) / FScale;
- g->movewin(pw->gw, x, 0, ww, fheight);
- g->drawrect(pw->gw, 0, 0, ww, fheight, white);
- draw(pw);
- g->putwin(pw->gw);
- x += ww;
- }
-}
-
-/* win_redraw_frame - Redraw the whole frame.
- */
-void
-win_redraw_frame()
-{
- win_resize_frame(0, 0);
-}
-
-/* win_scroll - Scroll the window by [n] lines.
- * If [n] is negative it will scroll backwards.
- */
-void
-win_scroll(W *w, int n)
-{
-
- struct lineinfo li;
- unsigned start, bol;
- int dir;
-
- if (n == 0)
- return;
-
- dir = n; // XXX this is for cursor handling, do we do this here?
-
- if (n < 0) {
- start = w->start;
- do {
- int top;
-
- if (start == 0)
- /* already at the top */
- break;
- bol = buf_bol(w->b, start-1);
-
- li.beg = li.len = 0;
- lineinfo(w, bol, start-1, &li);
- top = li.len - 2;
- assert(top >= 0);
- for (; n<0 && top>=0; top--, n++) {
- start = li.sl[(li.beg + top) % RingSize];
- assert(start < w->start);
- }
- } while (n<0);
- w->start = start;
- } else {
- start = w->start;
- do {
- int top;
-
- li.beg = li.len = 0;
- lineinfo(w, start, -1, &li);
- top = 1;
- assert(top < li.len);
- for (; n>0 && top<li.len; top++, n--) {
- start = li.sl[(li.beg + top) % RingSize];
- assert(start > w->start
- || buf_get(w->b, w->start) == '\n'); // change this to test size XXX
- }
- } while (n>0);
- w->start = start;
- }
-}
-
-/* win_show_cursor - Find the cursor in [w] and adjust
- * the text view so that the cursor is displayed on the
- * screen. Depending on [where], the cursor will be
- * displayed at the top or at the bottom of the screen.
- */
-void
-win_show_cursor(W *w, enum CursorLoc where)
-{
- struct lineinfo li;
- unsigned bol;
-
- bol = buf_bol(w->b, w->cu);
- li.beg = li.len = 0;
- lineinfo(w, bol, w->cu, &li);
- assert(li.len >= 2);
- w->start = li.sl[(li.beg + li.len-2) % RingSize];
- if (where == CBot)
- win_scroll(w, -w->height/font.height + 1);
-}
-
-/* static functions */
-
-typedef int LineFn(void *data, unsigned off, Rune r, int x, int rw, int sl);
-
-static unsigned
-line(W *w, unsigned off, LineFn f, void *data)
-{
- Rune r;
- int l, x, rw;
-
- r = 0;
- l = 0;
- x = 0;
-
- for (; r != '\n'; x+=rw, off++) {
- r = buf_get(w->b, off);
-
- if (r == '\t') {
- int tw;
-
- tw = TabWidth * font.width;
- rw = tw - x % tw;
- } else if (r == '\n') {
- rw = 0;
- } else
- rw = g->textwidth(&r, 1);
-
- if (x+rw > w->gw->w)
- if (x != 0) { /* force progress */
- x = 0;
- l++;
- }
-
- if (!f(data, off, r, x, rw, l))
- break;
- }
-
- return off;
-}
-
-/* aggregate all calls to [drawtext] into batches, it
- * will flush if the current character is \n or \t.
- */
-static void
-pushrune(GWin *gw, Rune r, int x, int y, int w, int cu)
-{
- static int fragx = -1, fragy, cx = -1, cy, cw;
- static Rune frag[MaxWidth], *p = frag;
- GColor color = { .blue = 255 },
- xor = { .x = 1 };
-
- assert(r == '\n' || fragx == -1 || y == fragy);
-
- if (fragx == -1) {
- fragx = x;
- fragy = y;
- }
-
- if (cu) {
- cx = x;
- cy = y - font.ascent;
- cw = w ? w : 4;
- }
-
- if (r == '\t' || r == '\n') {
-#if 0
- printf("flushing: fragx = %d\n"
- " fragy = %d\n"
- " r = %u\n"
- " len = %td\n"
- " frag = '",
- fragx, fragy, r, p-frag);
- for (int i=0; i<p-frag; i++)
- printf("%c", (char)frag[i]);
- printf("'\n");
-#endif
- assert(fragx != -1);
- g->drawtext(gw, frag, p-frag, fragx, fragy, color);
- if (cx != -1)
- g->drawrect(gw, cx, cy, cw, font.height, xor);
-
- fragx = cx = -1;
- p = frag;
- return;
- }
-
- assert(p-frag < MaxWidth);
- *p++ = r;
-}
-
-struct dstatus {
- W *w;
- int begl, curl;
-};
-
-static int
-drawfn(void *data, unsigned off, Rune r, int x, int rw, int sl)
-{
- int y;
- struct dstatus *ds = data;
-
- y = (ds->begl + sl) * font.height + font.ascent;
-
- if (ds->curl != sl) { /* need a flush, we changed screen line */
- assert(x == 0);
- ds->curl = sl;
- pushrune(ds->w->gw, '\n', 0, 0, 0, 0);
- if (y + font.descent > ds->w->height)
- return 0;
- }
-
- pushrune(ds->w->gw, r, x, y, rw, off == ds->w->cu);
- return 1;
-}
-
-static void
-draw(W *w)
-{
- int nls;
- unsigned off;
- struct dstatus ds;
-
- ds.w = w;
- ds.begl = 0;
- ds.curl = 0;
- off = w->start;
- nls = w->height/font.height;
-
- do {
- off = line(w, off, drawfn, &ds);
- ds.begl += ds.curl + 1;
- ds.curl = 0;
- } while (ds.begl < nls);
-
- w->stop = off;
-}
-
-static int
-pushoff(struct lineinfo *li, unsigned off, int overwrite)
-{
- assert(li->len <= RingSize);
-
- if (li->len == RingSize) {
- if (!overwrite)
- return 0;
- li->sl[li->beg] = off;
- li->beg++;
- li->beg %= RingSize;
- } else {
- int n;
-
- n = (li->beg + li->len) % RingSize;
- li->sl[n] = off;
- li->len++;
- }
- return 1;
-}
-
-struct lstatus {
- unsigned lim;
- struct lineinfo *li;
- int curl;
-};
-
-static int
-lineinfofn(void *data, unsigned off, Rune r, int x, int rw, int sl)
-{
- struct lstatus *ls = data;
-
- unused(r);
- unused(x);
- unused(rw);
-
- if (off > ls->lim)
- return 0;
-
- if (ls->curl != sl) {
- assert(ls->curl == sl-1);
- ls->curl = sl;
- return pushoff(ls->li, off, ls->lim != -1u);
- }
-
- return 1;
-}
-
-/* if [lim == -1] the lineinfo will only contain information
- * about the first RingSize screen lines
- */
-static void
-lineinfo(W *w, unsigned off, unsigned lim, struct lineinfo *li)
-{
- struct lstatus ls;
-
- assert(RingSize >= 2);
-
- ls.lim = lim;
- ls.li = li;
- ls.curl = 0;
-
- pushoff(li, off, lim != -1u);
- off = line(w, off, lineinfofn, &ls);
- pushoff(li, off, lim != -1u);
-}
-
-#ifdef WIN_TEST
-/* test */
-
-#include <stdlib.h>
-
-void die(char *m) { exit(1); }
-
-int main()
-{
- GEvent e;
- Buf *b;
- W *w;
- enum culoc cloc;
- unsigned char s[] =
- "je suis\n"
- "\tQcar\n"
- "tab\ttest\n"
- "une longue longue longue longue longue longue longue longue longue longue longue longue longue ligne\n"
- "un peu d'unicode: ä æ ç\n"
- "et voila!\n\n";
-
- b = buf_new("*");
- win_init(&gui_x11);
- w = win_new(b);
-
- for (int i=0; i<5; i++)
- buf_ins_utf8(b, 0, s, sizeof s - 1);
-
- do {
- g->nextevent(&e);
- if (e.type == GResize)
- win_resize_frame(e.resize.width, e.resize.height);
- if (e.type == GKey) {
- switch (e.key) {
- case 'l': ++w->cu; cloc = CBot; break;
- case 'h': --w->cu; cloc = CTop; break;
- case 'e'-'a' + 1: win_scroll(w, 1); break;
- case 'y'-'a' + 1: win_scroll(w, -1); break;
- default: continue;
- }
- win_redraw_frame();
- if (e.key == 'l' || e.key == 'h')
- if (w->cu < w->start || w->cu >= w->stop) {
- win_show_cursor(w, cloc);
- win_redraw_frame();
- }
-
- }
- } while (e.type != GKey || e.key != 'q');
-
- g->fini();
- return 0;
-}
-
-#endif
diff --git a/old/xmess/.comfile b/old/xmess/.comfile
deleted file mode 100644
index b103278..0000000
--- a/old/xmess/.comfile
+++ /dev/null
@@ -1 +0,0 @@
-win.c
diff --git a/old/xmess/gui.h b/old/xmess/gui.h
deleted file mode 100644
index d1abe04..0000000
--- a/old/xmess/gui.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef GUI_H
-#define GUI_H
-/* GUI module definition */
-
-#include "unicode.h"
-
-typedef struct gcolor GColor;
-typedef struct gfont GFont;
-typedef struct gwin GWin;
-typedef struct gevent GEvent;
-
-enum {
- MaxWins = 9,
-};
-
-struct gcolor {
- unsigned char red;
- unsigned char green;
- unsigned char blue;
- unsigned char x;
-};
-
-struct gfont {
- void *data;
- int ascent;
- int descent;
- int width;
- int height;
-};
-
-struct gwin {
- int x, y;
- int w, h;
-};
-
-struct gevent {
- enum {
- GResize,
- GKey,
- GButPress,
- GButRelease,
- } type;
-
- union {
- struct {
- int width;
- int height;
- } resize;
- Rune key;
- enum {
- GBLeft,
- GBMiddle,
- GBRight,
- GBWheelUp,
- GBWheelDown,
- } button;
- };
-};
-
-enum {
- GKEsc = 0x1b,
-
- GKF1 = 0xe001, /* unicode private use area */
- GKF2,
- GKF3,
- GKF4,
- GKF5,
- GKF6,
- GKF7,
- GKF8,
- GKF9,
- GKF10,
- GKF11,
- GKF12,
- GKLeft,
- GKRight,
- GKUp,
- GKDown,
- GKPageUp,
- GKPageDown,
- GKBackspace,
-};
-
-struct gui {
- void (*init)(void);
- void (*fini)(void);
- void (*getfont)(GFont *fret);
- GWin *(*newwin)(int x, int y, int w, int h);
- void (*movewin)(GWin *gw, int x, int y, int w, int h);
- void (*delwin)(GWin *gw);
- void (*drawtext)(GWin *gw, Rune *str, int len,
- int x, int y, GColor color);
- void (*drawrect)(GWin *gw, int x, int y, int w, int h, GColor c);
- void (*putwin)(GWin *gw);
- int (*textwidth)(Rune *str, int len);
- void (*nextevent)(GEvent *eret);
-};
-
-/* Available gui modules */
-extern struct gui gui_x11;
-
-#endif /* ndef GUI_H */
diff --git a/old/xmess/win.c b/old/xmess/win.c
deleted file mode 100644
index b56ad77..0000000
--- a/old/xmess/win.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*% clang -DWIN_TEST -Wall -g -I/usr/include/freetype2 -lX11 -lXft obj/unicode.o obj/buf.o obj/x11.o % -o #
- *
- * Windowing module
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-#include "win.h"
-
-enum CursorPos {
- Top,
- Bot,
-};
-
-enum {
- Draw = 1,
- Line = 2,
- BLine = 4 | Line,
- ELine = 8 | Line,
- CLine = 16 | Line,
-};
-
-static void put(W *w, int flags);
-
-static W wins[MaxWins];
-static int nwins;
-static struct gui *g;
-static GFont font;
-static int fwidth, fheight;
-
-/* win_init - initialize the module using [gui] as a
- * graphical backed.
- */
-void
-win_init(struct gui *gui)
-{
- g = gui;
-
- g->init();
- g->getfont(&font);
-
- /* the gui module does not give a way to access the screen
- * dimension, instead, the first event generated will always
- * be a GResize, so we can adjust these dummy values with
- * win_resize_frame
- */
- fwidth = fheight = 10;
-}
-
-/* win_new - insert a new window if possible and
- * return it. In case of error (more than MaxWins
- * windows), 0 is returned.
- */
-W *
-win_new(Buf *b)
-{
- if (nwins!=0)
- return 0;
-
- memset(&wins[nwins], 0, sizeof(W));
- wins[nwins].b = b;
- wins[nwins].gw = g->newwin(0, 0, fwidth, fheight);
- wins[nwins].vfrac = FScale;
-
- nwins = 1;
- return &wins[0];
-}
-
-/* win_delete - delete a window created by win_new.
- */
-void
-win_delete(W *w)
-{
- assert(w >= wins);
- assert(w < wins+nwins);
- nwins = 0;
-}
-
-/* win_resize_frame - called when the whole frame
- * is resized.
- */
-void
-win_resize_frame(int w, int h)
-{
- GColor white = { 255, 255, 255 };
- int x, ww;
- W *pw;
-
- if (w!=0 && h!=0) {
- fwidth = w;
- fheight = h;
- }
-
- for (x=0, pw=wins; pw-wins<nwins; pw++) {
- pw->height = fheight / font.height;
- ww = (fwidth * pw->vfrac) / FScale;
- g->movewin(pw->gw, x, 0, ww, fheight);
- g->drawrect(pw->gw, 0, 0, ww, fheight, white);
- put(pw, Draw);
- g->putwin(pw->gw);
- x += ww;
- }
-}
-
-/* win_redraw_frame - redraw the whole frame.
- */
-void
-win_redraw_frame(void)
-{
- win_resize_frame(0, 0);
-}
-
-/* win_scroll - scroll the window by [n] lines.
- * If [n] is negative it will scroll backwards.
- * The number of lines scrolled must not be
- * bigger than the number of lines currently on
- * the screen.
- */
-void
-win_scroll(W *w, int n)
-{
- int top;
- unsigned off, bol;
- W wscratch;
-
- if (w->nls == 0 || n == 0)
- return;
-
- assert(n < 0 || n <= w->nls);
-
- wscratch.b = w->b;
- wscratch.gw = w->gw;
-
- if (n<0) {
- off = w->loff[0];
-
- do {
- if (off == 0)
- break;
-
- bol = buf_bol(w->b, off-1);
- wscratch.loff[0] = bol;
- put(&wscratch, ELine);
-
- top = wscratch.nls - 1;
- do {
- off = wscratch.loff[top--];
- if (off < w->loff[0])
- ++n;
- } while (off >= w->loff[0] || (top>=0 && n<0));
- } while (n<0);
- } else
- off = w->loff[n];
-
- w->loff[0] = off;
- put(w, 0); /* update line offsets */
-
- if (w->cl == -1) { /* fix the cursor position */
- if (n>0)
- w->cl = 0;
- else
- w->cl = w->nls-1;
- w->coff = w->loff[w->cl];
- }
-}
-
-/* win_show_cursor - find the cursor in [w] and adjust
- * the text view so that the cursor is displayed on the
- * screen. Depending on [where], the cursor will be
- * displayed at the top or at the bottom of the screen.
- */
-void
-win_show_cursor(W *w, enum CursorPos where)
-{
- unsigned bol;
- W wscratch;
-
- wscratch.b = w->b;
- wscratch.gw = w->gw;
- wscratch.coff = w->coff;
-
- bol = buf_bol(w->b, w->coff);
- wscratch.loff[0] = bol;
-
- put(&wscratch, CLine); /* find cursor line */
- assert(wscratch.cl < wscratch.nls);
- assert(wscratch.cl >= 0);
-
- w->loff[0] = wscratch.loff[wscratch.cl];
-
- put(w, 0);
- if (where == Bot)
- win_scroll(w, -w->height + 1);
-}
-
-/* static functions */
-
-
-/* this function tries to factor calls to the pretty expensive
- * [drawtext] function of the gui module, we basically try to aggregate
- * all potential calls into one. Sometimes it is necessary to flush,
- * for instance when the are displaying a new line or when a tabulation
- * has to be printed. Tabs are treated specially because they have
- * a width the drawtext function does not know a priori.
- *
- * Calling this function with [r == NORUNE] will force a flush.
- *
- * Before using this I called drawtext for each char, on a big screen
- * the slowdown was significative.
- */
-static void
-draw(GWin *gw, Rune r, int x, int y, int rw, int cu)
-{
- static int fragx = -1, fragy, cx = -1, cy, cw;
- static Rune frag[MaxWidth], *p = frag;
- int flush;
- GColor color = { .blue = 255 },
- xor = { .x = 1 };
-
- flush = 0;
-
- if (r != NORUNE && fragx == -1) {
- fragx = x;
- fragy = y;
- }
-
- if (r != NORUNE && y == fragy) {
- if (cu) {
- cx = x;
- cy = y-font.ascent;
- cw = rw;
- }
-
- if (r != '\t') {
- assert(p-frag < MaxWidth);
- *p++ = r;
- } else
- flush = 1;
- } else
- flush = 1;
-
- /* we flush the current fragment if one
- * of the following conditions is met
- * - the current rune is a tab
- * - the current rune is a NORUNE (signaling eof)
- * - the rune's y is different from the fragment's y
- * (signaling a newline)
- */
- if (flush) {
-#if 0
- printf("flushing: fragx = %d\n"
- " fragy = %d\n"
- " r = %u\n"
- " len = %zd\n",
- fragx, fragy, r, p-frag);
-#endif
- if (fragx == -1)
- return;
-
- g->drawtext(gw, frag, p-frag, fragx, fragy, color);
- if (cx != -1)
- g->drawrect(gw, cx, cy, cw, font.height, xor);
-
- fragx = cx = -1;
- p = frag;
-
- if (r != NORUNE && r != '\n' && fragy != y)
- /* push r on frag with a recursive call */
- draw(gw, r, x, y, rw, cu);
- }
-}
-
-static void
-put(W *w, int flags)
-{
- unsigned off, i, nl;
- int rw, x, y, lnum;
- Rune r;
- GWin *gw;
-
- off = w->loff[0];
- gw = w->gw;
- x = 0;
- y = font.ascent;
- lnum = 0;
- w->loff[lnum++] = off;
- w->cl = -1;
-
- for (i=0; y < gw->h || (flags & Line); i++) {
- r = buf_get(w->b, off+i);
- if (r == NORUNE) {
- lnum++;
- break;
- }
-
- if (w->coff == off+i)
- w->cl = lnum - 1;
-
- if (r == '\t') {
- rw = TabWidth * font.width;
- rw -= x % (TabWidth * font.width);
- } else {
- nl = 0;
- if (r != '\n') {
- if (unicode_rune_width(r) == 0)
- continue;
- rw = g->textwidth(&r, 1);
- if (x+rw > gw->w)
- nl = off+i;
- } else if ((flags & Line) == 0) {
- nl = off+i+1;
- rw = 0;
- } else {
- lnum++;
- break;
- }
-
- if (nl) {
- y += font.height;
- x = 0;
- if (lnum < MaxLines)
- w->loff[lnum++] = nl;
- else if ((flags & ELine)
- || ((flags & CLine) && w->cl == -1)) {
- /* should use a ring buffer... */
- assert(lnum == MaxLines);
- memmove(w->loff, w->loff+1,
- (MaxLines-1) * sizeof(int));
- w->loff[MaxLines-1] = nl;
- }
- }
- }
-
- if (flags & Draw)
- draw(gw, r, x, y, rw, w->coff == off+i);
-
- x += rw;
- }
-
- if (flags & Draw)
- draw(gw, NORUNE, 0, 0, 0, 0);
- w->nls = lnum - 1;
-}
-
-#ifdef WIN_TEST
-/* test */
-
-#include <stdlib.h>
-
-void die(char *m) { exit(1); }
-
-int main(void)
-{
- GEvent e;
- Buf *b;
- W *w;
- enum CursorPos cpos;
- unsigned char s[] =
- "je suis\n"
- "\t\tQuentin\n"
- "tab\ttest\n"
- "une longue longue longue longue longue longue longue longue longue longue longue longue longue ligne\n"
- "un peu d'unicode: ä æ ç\n"
- "et voila!\n";
-
- b = buf_new("*");
- win_init(&gui_x11);
- w = win_new(b);
-
- for (int i=0; i<20; i++)
- buf_ins_utf8(b, 0, s, sizeof s - 1);
-
- do {
- g->nextevent(&e);
- if (e.type == GResize)
- win_resize_frame(e.resize.width, e.resize.height);
- if (e.type == GKey) {
- switch (e.key) {
- case 'l': ++w->coff; cpos = Bot; break;
- case 'h': --w->coff; cpos = Top; break;
- case 'e'-'a' + 1: win_scroll(w, 1); break;
- case 'y'-'a' + 1: win_scroll(w, -1); break;
- default: continue;
- }
- win_redraw_frame();
- if (w->cl == -1) {
- win_show_cursor(w, cpos);
- win_redraw_frame();
- }
- }
- } while (e.type != GKey || e.key != 'q');
-
- g->fini();
- return 0;
-}
-
-#endif
diff --git a/old/xmess/win.h b/old/xmess/win.h
deleted file mode 100644
index 296b5ce..0000000
--- a/old/xmess/win.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef WIN_H
-#define WIN_H
-
-#include "unicode.h"
-#include "buf.h"
-#include "gui.h"
-
-enum {
- FScale = 16384, /* fixed point scale */
- TabWidth = 8, /* tabulation width */
- MaxLines = 1000, /* max number of lines on screen */
- MaxWidth = 500, /* max width of the screen */
-};
-
-typedef struct w W;
-struct w {
- unsigned loff[MaxLines];
- unsigned coff;
- int cl;
- int nls;
- int vfrac, height;
- Buf *b;
- GWin *gw;
-};
-
-void win_init(struct gui *g);
-W *win_new(Buf *b);
-void win_resize_frame(int w, int h);
-
-#endif /* ndef WIN_H */
diff --git a/old/xmess/x11 b/old/xmess/x11
deleted file mode 100755
index 383049a..0000000
--- a/old/xmess/x11
+++ /dev/null
Binary files differ
diff --git a/old/xmess/x11.c b/old/xmess/x11.c
deleted file mode 100644
index eda0047..0000000
--- a/old/xmess/x11.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* A GUI module for X11 */
-
-#include <assert.h>
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xft/Xft.h>
-
-#include "gui.h"
-
-void die(char *);
-
-#define FONTNAME "DejaVu Sans Mono:pixelsize=12"
-
-enum {
- Width = 640,
- Height = 480,
-};
-
-typedef struct xwin XWin;
-struct xwin {
- GWin gw;
- Pixmap p;
- XftDraw *xft;
- int used;
-};
-
-static Display *d;
-static Visual *visual;
-static Colormap cmap;
-static unsigned int depth;
-static int screen;
-static GC gc;
-static XftFont *font;
-static Window win;
-static int w, h;
-static XWin wins[MaxWins];
-
-static void
-init(void)
-{
- XWindowAttributes wa;
- XSetWindowAttributes swa;
- XGCValues gcv;
- Window root;
- XConfigureEvent ce;
-
- d = XOpenDisplay(0);
- if (!d)
- die("cannot open display");
- root = DefaultRootWindow(d);
- XGetWindowAttributes(d, root, &wa);
- visual = wa.visual;
- cmap = wa.colormap;
- screen = DefaultScreen(d);
- depth = DefaultDepth(d, screen);
-
- /* create the main window */
- win = XCreateSimpleWindow(d, root, 0, 0, Width, Height, 0, 0,
- WhitePixel(d, screen));
- swa.backing_store = WhenMapped;
- swa.bit_gravity = NorthWestGravity;
- XChangeWindowAttributes(d, win, CWBackingStore|CWBitGravity, &swa);
- XStoreName(d, win, "ED");
- XSelectInput(d, win, StructureNotifyMask|ButtonPressMask|KeyPressMask|ExposureMask);
-
- /* simulate an initial resize and map the window */
- ce.type = ConfigureNotify;
- ce.width = Width;
- ce.height = Height;
- XSendEvent(d, win, False, StructureNotifyMask, (XEvent *)&ce);
- XMapWindow(d, win);
-
- /* allocate font */
- font = XftFontOpenName(d, screen, FONTNAME);
- if (!font)
- die("cannot open default font");
-
- /* initialize gc */
- gcv.foreground = WhitePixel(d, screen);
- gcv.graphics_exposures = False;
- gc = XCreateGC(d, win, GCForeground|GCGraphicsExposures, &gcv);
-}
-
-static void
-fini(void)
-{
- XCloseDisplay(d);
-}
-
-static void
-getfont(GFont *ret)
-{
- ret->data = font;
- ret->ascent = font->ascent;
- ret->descent = font->descent;
- ret->width = font->max_advance_width;
- ret->height = font->height;
-}
-
-static void
-movewin(GWin *gw, int x, int y, int w, int h)
-{
- XWin *xw;
-
- gw->x = x;
- gw->y = y;
- if (gw->w == w & gw->h == h)
- return;
-
- xw = (XWin *)gw;
- gw->w = w;
- gw->h = h;
- if (xw->xft) {
- XftDrawDestroy(xw->xft);
- XFreePixmap(d, xw->p);
- }
-
- xw->p = XCreatePixmap(d, win, w, h, depth);
- xw->xft = XftDrawCreate(d, xw->p, visual, cmap);
- XFillRectangle(d, xw->p, gc, 0, 0, w, h);
-}
-
-static GWin *
-newwin(int x, int y, int w, int h)
-{
- int i;
- XWin *xw;
-
- assert(w != 0 || h != 0);
-
- xw = 0;
- for (i=0; i<MaxWins; i++) {
- if (wins[i].used)
- continue;
- xw = &wins[i];
- break;
- }
- if (!xw)
- return 0;
-
- xw->used = 1;
- xw->gw.w = 0;
- xw->gw.h = 0;
- xw->xft = NULL;
- movewin((GWin *)xw, x, y, w, h);
- return (GWin *)xw;
-}
-
-static void
-delwin(GWin *gw)
-{
- XWin *xw;
-
- xw = (XWin *)gw;
- XftDrawDestroy(xw->xft);
- XFreePixmap(d, xw->p);
- xw->used = 0;
-}
-
-static void
-xftcolor(XftColor *xc, GColor c)
-{
- xc->color.red = c.red << 8;
- xc->color.green = c.green << 8;
- xc->color.blue = c.blue << 8;
- xc->color.alpha = 65535;
- XftColorAllocValue(d, visual, cmap, &xc->color, xc);
-}
-
-static void
-drawtext(GWin *gw, Rune *str, int len, int x, int y, GColor c)
-{
- XftColor col;
- XWin *xw;
-
- xw = (XWin *)gw;
- xftcolor(&col, c);
- XftDrawString32(xw->xft, &col, font, x, y, (FcChar32 *)str, len);
-}
-
-static void
-drawrect(GWin *gw, int x, int y, int w, int h, GColor c)
-{
- XWin *xw;
-
- xw = (XWin *)gw;
- if (c.x) {
- XGCValues gcv;
- GC gc;
-
- gcv.foreground = WhitePixel(d, screen);
- gcv.function = GXxor;
- gc = XCreateGC(d, xw->p, GCFunction|GCForeground, &gcv);
- XFillRectangle(d, xw->p, gc, x, y, w, h);
- XFreeGC(d, gc);
- } else {
- XftColor col;
-
- xftcolor(&col, c);
- XftDrawRect(xw->xft, &col, x, y, w, h);
- }
-}
-
-static void
-putwin(GWin *gw)
-{
- XWin *xw;
-
- xw = (XWin *)gw;
- XCopyArea(d, xw->p, win, gc, 0, 0, gw->w, gw->h, gw->x, gw->y);
-}
-
-static int
-textwidth(Rune *str, int len)
-{
- XGlyphInfo gi;
-
- XftTextExtents32(d, font, (FcChar32 *)str, len, &gi);
- return gi.xOff;
-}
-
-static void
-nextevent(GEvent *gev)
-{
- XEvent e;
-
- do {
- XNextEvent(d, &e);
- switch (e.type) {
-
- case Expose:
- {
- XWin *w;
-
- /* we could suck all exposes here */
- for (w=wins; w-wins<MaxWins; w++) {
- if (!w->used)
- continue;
- putwin((GWin *)w);
- }
- continue;
- }
-
- case ConfigureNotify:
- if (e.xconfigure.width == w)
- if (e.xconfigure.height == h)
- continue;
-
- w = e.xconfigure.width;
- h = e.xconfigure.height;
-
- gev->type = GResize;
- gev->resize.width = w;
- gev->resize.height = h;
- break;
-
- case ButtonPress:
- case ButtonRelease:
- if (e.type == ButtonPress)
- gev->type = GButPress;
- else
- gev->type = GButRelease;
- switch (e.xbutton.button) {
- case Button1:
- gev->button = GBLeft;
- break;
- case Button2:
- gev->button = GBMiddle;
- break;
- case Button3:
- gev->button = GBRight;
- break;
- case Button4:
- gev->button = GBWheelUp;
- break;
- case Button5:
- gev->button = GBWheelDown;
- break;
- default:
- continue;
- }
- break;
-
- case KeyPress:
- {
- int len;
- char buf[8];
- KeySym key;
-
- gev->type = GKey;
- len = XLookupString(&e.xkey, buf, 8, &key, 0);
- switch (key) {
- case XK_F1:
- case XK_F2:
- case XK_F3:
- case XK_F4:
- case XK_F5:
- case XK_F6:
- case XK_F7:
- case XK_F8:
- case XK_F9:
- case XK_F10:
- case XK_F11:
- case XK_F12:
- gev->key = GKF1 + (key - XK_F1);
- break;
- case XK_Up:
- gev->key = GKUp;
- break;
- case XK_Down:
- gev->key = GKDown;
- break;
- case XK_Left:
- gev->key = GKLeft;
- break;
- case XK_Right:
- gev->key = GKRight;
- break;
- case XK_Prior:
- gev->key = GKPageUp;
- break;
- case XK_Next:
- gev->key = GKPageDown;
- break;
- case XK_BackSpace:
- gev->key = GKBackspace;
- break;
- default:
- if (len == 0)
- continue;
- gev->key = buf[0];
- break;
- }
- break;
- }
-
- default:
- continue;
- }
- return;
- } while (1);
-}
-
-struct gui gui_x11 = {
- .init = init,
- .fini = fini,
- .getfont = getfont,
- .newwin = newwin,
- .movewin = movewin,
- .delwin = delwin,
- .drawtext = drawtext,
- .drawrect = drawrect,
- .putwin = putwin,
- .textwidth = textwidth,
- .nextevent = nextevent,
-};
diff --git a/old/xmess/x11.o b/old/xmess/x11.o
deleted file mode 100644
index 5408196..0000000
--- a/old/xmess/x11.o
+++ /dev/null
Binary files differ