~foura/libacme

ref: f56267814566dddb3d995e2ca067d73d71a4937f libacme/event.c -rw-r--r-- 1.7 KiB
f5626781 — james palmer awincat: fix sucide. we want an 8k buffer not a int sized buffer 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>

#include "acme.h"

static int
aeventgetnum(Biobuf *bio)
{
	int c, n;
	
	n = 0;
	while('0' <= (c = Bgetc(bio)) && c <= '9')
		n = n*10+(c-'0');
	if(c != ' ') {
		werrstr("event number syntax: %c", c);
		return -1;
	}
	
	return n;
}

static int
aeventgetdata(Biobuf *bio, AEvent *ev)
{
	int i, runes, len;
	Rune r;
	
	len = 0;
	runes = aeventgetnum(bio);
	for(i = 0; i < runes; i++) {
		if((r = Bgetrune(bio)) == -1)
			break;
		len += runetochar(ev->text + len, &r);
	}
	
	ev->text[len] = '\0';
	return len;
}

static int
aeventnext(Biobuf *bio, AEvent *ev)
{
	int flags;
	
	flags = 0;
	
Again:
	ev->origin = Bgetc(bio);
	ev->type = Bgetc(bio);
	ev->q0 = aeventgetnum(bio);
	ev->q1 = aeventgetnum(bio);
	ev->flags = aeventgetnum(bio);
	ev->ntext = aeventgetdata(bio, ev);
	if(Bgetc(bio) != '\n') {
		werrstr("unterminated mesage");
		return -1;
	}
	
	if(ev->flags & 0x2) {
		ev->p = ev->q0;
		flags = ev->flags;
		goto Again;
	}
	
	ev->flags |= flags;
	return ev->origin;
}

static void
aeventproc(void *aux)
{
	AWin *w;
	Channel *c;
	Biobuf bio;
	AEvent ev;
	
	w = aux;
	c = w->eventc;
	Binit(&bio, w->eventfd, OREAD);
	
	while(aeventnext(&bio, &ev)) {
		if(send(c, &ev) < 0) {
			Bterm(&bio);
			exits(nil);
		}
	}
}

Channel *
aeventlisten(AWin *w)
{
	if(w->eventc)
		return w->eventc;
		
	w->eventc = chancreate(sizeof(AEvent), 0);
	proccreate(aeventproc, w, 4096);
	
	return w->eventc;
}

void
aeventstop(AWin *w)
{
	if(w->eventc) {
		chanclose(w->eventc);
		w->eventc = nil;
	}
}

void
aeventsend(AWin *w, AEvent *ev)
{
	if(ev->flags & 0x2)
		fprint(w->eventfd, "%c%c%d %d\n", ev->origin, ev->type, ev->p, ev->p);
	else
		fprint(w->eventfd, "%c%c%d %d\n", ev->origin, ev->type, ev->q0, ev->q1);
}