Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/libdraw/mouse.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <draw.h>
4
#include <thread.h>
5
#include <cursor.h>
6
#include <mouse.h>
7
 
8
void
9
moveto(Mousectl *m, Point pt)
10
{
11
	fprint(m->mfd, "m%d %d", pt.x, pt.y);
12
	m->xy = pt;
13
}
14
 
15
void
16
closemouse(Mousectl *mc)
17
{
18
	if(mc == nil)
19
		return;
20
 
21
	postnote(PNPROC, mc->pid, "kill");
22
 
23
	do; while(nbrecv(mc->c, &mc->Mouse) > 0);
24
 
25
	close(mc->mfd);
26
	close(mc->cfd);
27
	free(mc->file);
28
	free(mc->c);
29
	free(mc->resizec);
30
	free(mc);
31
}
32
 
33
int
34
readmouse(Mousectl *mc)
35
{
36
	if(mc->image)
37
		flushimage(mc->image->display, 1);
38
	if(recv(mc->c, &mc->Mouse) < 0){
39
		fprint(2, "readmouse: %r\n");
40
		return -1;
41
	}
42
	return 0;
43
}
44
 
45
static
46
void
47
_ioproc(void *arg)
48
{
49
	int n, nerr, one;
50
	char buf[1+5*12];
51
	Mouse m;
52
	Mousectl *mc;
53
 
54
	mc = arg;
55
	threadsetname("mouseproc");
56
	one = 1;
57
	memset(&m, 0, sizeof m);
58
	mc->pid = getpid();
59
	nerr = 0;
60
	for(;;){
61
		n = read(mc->mfd, buf, sizeof buf);
62
		if(n != 1+4*12){
63
			yield();	/* if error is due to exiting, we'll exit here */
64
			fprint(2, "mouse: bad count %d not 49: %r\n", n);
65
			if(n<0 || ++nerr>10)
66
				threadexits("read error");
67
			continue;
68
		}
69
		nerr = 0;
70
		switch(buf[0]){
71
		case 'r':
72
			send(mc->resizec, &one);
73
			/* fall through */
74
		case 'm':
75
			m.xy.x = atoi(buf+1+0*12);
76
			m.xy.y = atoi(buf+1+1*12);
77
			m.buttons = atoi(buf+1+2*12);
78
			m.msec = atoi(buf+1+3*12);
79
			send(mc->c, &m);
80
			/*
81
			 * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
82
			 * This means that programs should receive into mc->Mouse (see readmouse() above) if
83
			 * they want full synchrony.
84
			 */
85
			mc->Mouse = m;
86
			break;
87
		}
88
	}
89
}
90
 
91
Mousectl*
92
initmouse(char *file, Image *i)
93
{
94
	Mousectl *mc;
95
	char *t, *sl;
96
 
97
	mc = mallocz(sizeof(Mousectl), 1);
98
	if(file == nil)
99
		file = "/dev/mouse";
100
	mc->file = strdup(file);
101
	mc->mfd = open(file, ORDWR|OCEXEC);
102
	if(mc->mfd<0 && strcmp(file, "/dev/mouse")==0){
103
		bind("#m", "/dev", MAFTER);
104
		mc->mfd = open(file, ORDWR|OCEXEC);
105
	}
106
	if(mc->mfd < 0){
107
		free(mc);
108
		return nil;
109
	}
110
	t = malloc(strlen(file)+16);
111
	if (t == nil) {
112
		close(mc->mfd);
113
		free(mc);
114
		return nil;
115
	}
116
	strcpy(t, file);
117
	sl = utfrrune(t, '/');
118
	if(sl)
119
		strcpy(sl, "/cursor");
120
	else
121
		strcpy(t, "/dev/cursor");
122
	mc->cfd = open(t, ORDWR|OCEXEC);
123
	free(t);
124
	mc->image = i;
125
	mc->c = chancreate(sizeof(Mouse), 0);
126
	mc->resizec = chancreate(sizeof(int), 2);
127
	proccreate(_ioproc, mc, 4096);
128
	return mc;
129
}
130
 
131
void
132
setcursor(Mousectl *mc, Cursor *c)
133
{
134
	char curs[2*4+2*2*16];
135
 
136
	if(c == nil)
137
		write(mc->cfd, curs, 0);
138
	else{
139
		BPLONG(curs+0*4, c->offset.x);
140
		BPLONG(curs+1*4, c->offset.y);
141
		memmove(curs+2*4, c->clr, 2*2*16);
142
		write(mc->cfd, curs, sizeof curs);
143
	}
144
}