#include <lib9.h>#include <draw.h>#include <cursor.h>#include "dat.h"#include "fns.h" static void addmouse(Mousebuf*, Mouse, int);static void matchmouse(Mousebuf*, Reqbuf*);static void replymouse(Mousebuf*, void*); voidreadmouse(Window *w, void* r){ Mousebuf *mouse; Reqbuf *mousereqs; mouse = &w->mouse; mousereqs = &w->mousereqs; addreq(mousereqs, r); // fprint(2, "mouse unstall\n"); mouse->stall = 0; matchmouse(mouse, mousereqs);} voidwritemouse(Window *w, Mouse m, int resized){ Mousebuf *mouse; Reqbuf *mousereqs; mouse = &w->mouse; mousereqs = &w->mousereqs; addmouse(mouse, m, resized); matchmouse(mouse, mousereqs);} staticvoidaddmouse(Mousebuf *mouse, Mouse m, int resized){ int p; if(!mouse->open || mouse->stall) return; mouse->m[mouse->wi] = m; if(resized){ p = mouse->wi - 1; if(p < 0) p = nelem(mouse->m) - 1; mouse->m[mouse->wi] = mouse->m[p]; mouse->resized = 1; } mouse->wi++; if(mouse->wi == nelem(mouse->m)) mouse->wi = 0; if(mouse->wi == mouse->ri){ mouse->stall = 1; mouse->ri = 0; mouse->wi = 1; mouse->m[0] = m; /* fprint(2, "mouse stall\n"); */ }} staticvoidreplymouse(Mousebuf *mouse, void *r){ int n, resized; char buf[50], c; Mouse m; m = mouse->m[mouse->ri]; resized = mouse->resized; c = 'm'; if(mouse->resized) c = 'r'; n = sprint(buf, "%c%11d %11d %11d %11ld ", c, m.xy.x, m.xy.y, m.buttons, m.msec); buf[n] = '\0'; ixprread(r, buf); mouse->resized = 0;} staticvoidmatchmouse(Mousebuf *mouse, Reqbuf *mousereqs){ while(mouse->ri != mouse->wi && mousereqs->ri != mousereqs->wi){ replymouse(mouse, nextreq(mousereqs)); mouse->ri++; if(mouse->ri == nelem(mouse->m)) mouse->ri = 0; }} static intrevbyte(int b){ int r; r = 0; r |= (b&0x01) << 7; r |= (b&0x02) << 5; r |= (b&0x04) << 3; r |= (b&0x08) << 1; r |= (b&0x10) >> 1; r |= (b&0x20) >> 3; r |= (b&0x40) >> 5; r |= (b&0x80) >> 7; return r;} staticvoiddrawwincursor(Window *win, Drawcursor* c){ uchar *bs, *bc, *ps, *pm; int i, j, w, h, bpl; if(c->data == nil){ if(win->cursor.h != 0) win->cursor.h = 0; xsetcursor(win); return; } h = (c->maxy-c->miny)/2; /* image, then mask */ if(h > CursorSize) h = CursorSize; bpl = bytesperline(Rect(c->minx, c->miny, c->maxx, c->maxy), 1); w = bpl; if(w > CursorSize/8) w = CursorSize/8; ps = win->cursor.src; pm = win->cursor.mask; bc = c->data; bs = c->data + h*bpl; for(i = 0; i < h; i++){ for(j = 0; j < bpl && j < w; j++) { *ps++ = revbyte(bs[j]); *pm++ = revbyte(bs[j] | bc[j]); } bs += bpl; bc += bpl; } win->cursor.h = h; win->cursor.w = w*8; win->cursor.hotx = c->hotx; win->cursor.hoty = c->hoty; xsetcursor(win);} staticintinfernocursorwrite(Window *w, char *buf, int n){ uchar *p; Drawcursor c; p = buf; /* TO DO: perhaps interpret data as an Image */ /* * hotx[4] hoty[4] dx[4] dy[4] clr[dx/8 * dy/2] set[dx/8 * dy/2] * dx must be a multiple of 8; dy must be a multiple of 2. */ if(n < 8) return -1; c.hotx = BGLONG(p+0*4); c.hoty = BGLONG(p+1*4); c.minx = 0; c.miny = 0; c.maxx = BGLONG(p+2*4); c.maxy = BGLONG(p+3*4); if(c.maxx%8 != 0 || c.maxy%2 != 0 || n-4*4 != (c.maxx/8 * c.maxy)) return -1; c.data = p + 4*4; drawwincursor(w, &c); return 0;} staticintplan9cursorwrite(Window *w, char *buf, int n){ uchar *p; Drawcursor c; p = buf; /* * offsetx[4] offsety[4] clr[2*16] set[2*16] */ if(n < 2*4+2*2*16) return -1; c.hotx = BGLONG(p+0*4); c.hoty = BGLONG(p+1*4); c.minx = 0; c.miny = 0; c.maxx = 16; c.maxy = 32; c.data = p + 2*4; drawwincursor(w, &c); return 0;} intcursorwrite(Window *w, char *buf, int n){ if(infernocursorwrite(w, buf, n) < 0 && plan9cursorwrite(w, buf, n) < 0){ w->cursor.h = 0; xsetcursor(w); } return 0;}
#include <lib9.h>
#include <draw.h>
#include <cursor.h>
#include "dat.h"
#include "fns.h"
static void addmouse(Mousebuf*, Mouse, int);
static void matchmouse(Mousebuf*, Reqbuf*);
static void replymouse(Mousebuf*, void*);
void
readmouse(Window *w, void* r)
{
Mousebuf *mouse;
Reqbuf *mousereqs;
mouse = &w->mouse;
mousereqs = &w->mousereqs;
addreq(mousereqs, r);
// fprint(2, "mouse unstall\n");
mouse->stall = 0;
matchmouse(mouse, mousereqs);
}
void
writemouse(Window *w, Mouse m, int resized)
{
Mousebuf *mouse;
Reqbuf *mousereqs;
mouse = &w->mouse;
mousereqs = &w->mousereqs;
addmouse(mouse, m, resized);
matchmouse(mouse, mousereqs);
}
static
void
addmouse(Mousebuf *mouse, Mouse m, int resized)
{
int p;
if(!mouse->open || mouse->stall)
return;
mouse->m[mouse->wi] = m;
if(resized){
p = mouse->wi - 1;
if(p < 0)
p = nelem(mouse->m) - 1;
mouse->m[mouse->wi] = mouse->m[p];
mouse->resized = 1;
}
mouse->wi++;
if(mouse->wi == nelem(mouse->m))
mouse->wi = 0;
if(mouse->wi == mouse->ri){
mouse->stall = 1;
mouse->ri = 0;
mouse->wi = 1;
mouse->m[0] = m;
/* fprint(2, "mouse stall\n"); */
}
}
static
void
replymouse(Mousebuf *mouse, void *r)
{
int n, resized;
char buf[50], c;
Mouse m;
m = mouse->m[mouse->ri];
resized = mouse->resized;
c = 'm';
if(mouse->resized)
c = 'r';
n = sprint(buf, "%c%11d %11d %11d %11ld ", c, m.xy.x, m.xy.y, m.buttons, m.msec);
buf[n] = '\0';
ixprread(r, buf);
mouse->resized = 0;
}
static
void
matchmouse(Mousebuf *mouse, Reqbuf *mousereqs)
{
while(mouse->ri != mouse->wi && mousereqs->ri != mousereqs->wi){
replymouse(mouse, nextreq(mousereqs));
mouse->ri++;
if(mouse->ri == nelem(mouse->m))
mouse->ri = 0;
}
}
static int
revbyte(int b)
{
int r;
r = 0;
r |= (b&0x01) << 7;
r |= (b&0x02) << 5;
r |= (b&0x04) << 3;
r |= (b&0x08) << 1;
r |= (b&0x10) >> 1;
r |= (b&0x20) >> 3;
r |= (b&0x40) >> 5;
r |= (b&0x80) >> 7;
return r;
}
static
void
drawwincursor(Window *win, Drawcursor* c)
{
uchar *bs, *bc, *ps, *pm;
int i, j, w, h, bpl;
if(c->data == nil){
if(win->cursor.h != 0)
win->cursor.h = 0;
xsetcursor(win);
return;
}
h = (c->maxy-c->miny)/2; /* image, then mask */
if(h > CursorSize)
h = CursorSize;
bpl = bytesperline(Rect(c->minx, c->miny, c->maxx, c->maxy), 1);
w = bpl;
if(w > CursorSize/8)
w = CursorSize/8;
ps = win->cursor.src;
pm = win->cursor.mask;
bc = c->data;
bs = c->data + h*bpl;
for(i = 0; i < h; i++){
for(j = 0; j < bpl && j < w; j++) {
*ps++ = revbyte(bs[j]);
*pm++ = revbyte(bs[j] | bc[j]);
}
bs += bpl;
bc += bpl;
}
win->cursor.h = h;
win->cursor.w = w*8;
win->cursor.hotx = c->hotx;
win->cursor.hoty = c->hoty;
xsetcursor(win);
}
static
int
infernocursorwrite(Window *w, char *buf, int n)
{
uchar *p;
Drawcursor c;
p = buf;
/* TO DO: perhaps interpret data as an Image */
/*
* hotx[4] hoty[4] dx[4] dy[4] clr[dx/8 * dy/2] set[dx/8 * dy/2]
* dx must be a multiple of 8; dy must be a multiple of 2.
*/
if(n < 8)
return -1;
c.hotx = BGLONG(p+0*4);
c.hoty = BGLONG(p+1*4);
c.minx = 0;
c.miny = 0;
c.maxx = BGLONG(p+2*4);
c.maxy = BGLONG(p+3*4);
if(c.maxx%8 != 0 || c.maxy%2 != 0 || n-4*4 != (c.maxx/8 * c.maxy))
return -1;
c.data = p + 4*4;
drawwincursor(w, &c);
return 0;
}
static
int
plan9cursorwrite(Window *w, char *buf, int n)
{
uchar *p;
Drawcursor c;
p = buf;
/*
* offsetx[4] offsety[4] clr[2*16] set[2*16]
*/
if(n < 2*4+2*2*16)
return -1;
c.hotx = BGLONG(p+0*4);
c.hoty = BGLONG(p+1*4);
c.minx = 0;
c.miny = 0;
c.maxx = 16;
c.maxy = 32;
c.data = p + 2*4;
drawwincursor(w, &c);
return 0;
}
int
cursorwrite(Window *w, char *buf, int n)
{
if(infernocursorwrite(w, buf, n) < 0 &&
plan9cursorwrite(w, buf, n) < 0){
w->cursor.h = 0;
xsetcursor(w);
}
return 0;
}