Lots of X fixes.
This commit is contained in:
parent
4af386f434
commit
161060a463
14 changed files with 237 additions and 31 deletions
|
|
@ -99,6 +99,7 @@ OFILES=\
|
||||||
x11-mouse.$O\
|
x11-mouse.$O\
|
||||||
x11-pixelbits.$O\
|
x11-pixelbits.$O\
|
||||||
x11-unload.$O\
|
x11-unload.$O\
|
||||||
|
x11-wsys.$O\
|
||||||
devdraw.$O\
|
devdraw.$O\
|
||||||
unix.$O\
|
unix.$O\
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,6 @@ drawld2chan[] = {
|
||||||
CMAP8,
|
CMAP8,
|
||||||
};
|
};
|
||||||
|
|
||||||
int log2[] = { -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, 4 /* BUG */, -1, -1, -1, -1, -1, -1, -1, 5 };
|
|
||||||
|
|
||||||
u32int
|
u32int
|
||||||
setalpha(u32int color, uchar alpha)
|
setalpha(u32int color, uchar alpha)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ void
|
||||||
_initdisplaymemimage(Display *d, Memimage *m)
|
_initdisplaymemimage(Display *d, Memimage *m)
|
||||||
{
|
{
|
||||||
screenimage = m;
|
screenimage = m;
|
||||||
|
m->screenref = 1;
|
||||||
client0 = mallocz(sizeof(Client), 1);
|
client0 = mallocz(sizeof(Client), 1);
|
||||||
if(client0 == nil){
|
if(client0 == nil){
|
||||||
fprint(2, "initdraw: allocating client0: out of memory");
|
fprint(2, "initdraw: allocating client0: out of memory");
|
||||||
|
|
@ -165,7 +166,16 @@ _drawreplacescreenimage(Memimage *m)
|
||||||
* about the resize through external means, so all we
|
* about the resize through external means, so all we
|
||||||
* need to do is this assignment.
|
* need to do is this assignment.
|
||||||
*/
|
*/
|
||||||
|
Memimage *om;
|
||||||
|
|
||||||
|
qlock(&sdraw.lk);
|
||||||
|
om = screenimage;
|
||||||
screenimage = m;
|
screenimage = m;
|
||||||
|
m->screenref = 1;
|
||||||
|
if(om && --om->screenref == 0){
|
||||||
|
_freememimage(om);
|
||||||
|
}
|
||||||
|
qunlock(&sdraw.lk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -399,6 +409,8 @@ drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
|
||||||
d->name = 0;
|
d->name = 0;
|
||||||
d->vers = 0;
|
d->vers = 0;
|
||||||
d->image = i;
|
d->image = i;
|
||||||
|
if(i->screenref)
|
||||||
|
++i->screenref;
|
||||||
d->nfchar = 0;
|
d->nfchar = 0;
|
||||||
d->fchar = 0;
|
d->fchar = 0;
|
||||||
d->fromname = 0;
|
d->fromname = 0;
|
||||||
|
|
@ -534,11 +546,9 @@ drawfreedimage(DImage *dimage)
|
||||||
drawfreedimage(dimage->fromname);
|
drawfreedimage(dimage->fromname);
|
||||||
goto Return;
|
goto Return;
|
||||||
}
|
}
|
||||||
//if(dimage->image == screenimage) /* don't free the display */
|
|
||||||
// goto Return;
|
|
||||||
ds = dimage->dscreen;
|
ds = dimage->dscreen;
|
||||||
|
l = dimage->image;
|
||||||
if(ds){
|
if(ds){
|
||||||
l = dimage->image;
|
|
||||||
if(l->data == screenimage->data)
|
if(l->data == screenimage->data)
|
||||||
addflush(l->layer->screenr);
|
addflush(l->layer->screenr);
|
||||||
if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
|
if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
|
||||||
|
|
@ -549,8 +559,12 @@ drawfreedimage(DImage *dimage)
|
||||||
else
|
else
|
||||||
memlfree(l);
|
memlfree(l);
|
||||||
drawfreedscreen(ds);
|
drawfreedscreen(ds);
|
||||||
}else
|
}else{
|
||||||
freememimage(dimage->image);
|
if(l->screenref==0)
|
||||||
|
freememimage(l);
|
||||||
|
else if(--l->screenref==0)
|
||||||
|
_freememimage(l);
|
||||||
|
}
|
||||||
Return:
|
Return:
|
||||||
free(dimage->fchar);
|
free(dimage->fchar);
|
||||||
free(dimage);
|
free(dimage);
|
||||||
|
|
@ -732,6 +746,7 @@ _drawmsgread(Display *d, void *a, int n)
|
||||||
{
|
{
|
||||||
int inbuf;
|
int inbuf;
|
||||||
|
|
||||||
|
qlock(&sdraw.lk);
|
||||||
inbuf = d->obufp - d->obuf;
|
inbuf = d->obufp - d->obuf;
|
||||||
if(n > inbuf)
|
if(n > inbuf)
|
||||||
n = inbuf;
|
n = inbuf;
|
||||||
|
|
@ -740,6 +755,7 @@ _drawmsgread(Display *d, void *a, int n)
|
||||||
if(inbuf)
|
if(inbuf)
|
||||||
memmove(d->obuf, d->obufp-inbuf, inbuf);
|
memmove(d->obuf, d->obufp-inbuf, inbuf);
|
||||||
d->obufp = d->obuf+inbuf;
|
d->obufp = d->obuf+inbuf;
|
||||||
|
qunlock(&sdraw.lk);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -776,6 +792,7 @@ _drawmsgwrite(Display *d, void *v, int n)
|
||||||
Refreshfn reffn;
|
Refreshfn reffn;
|
||||||
Refx *refx;
|
Refx *refx;
|
||||||
|
|
||||||
|
qlock(&sdraw.lk);
|
||||||
d->obufp = d->obuf;
|
d->obufp = d->obuf;
|
||||||
a = v;
|
a = v;
|
||||||
m = 0;
|
m = 0;
|
||||||
|
|
@ -1516,6 +1533,7 @@ _drawmsgwrite(Display *d, void *v, int n)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
qunlock(&sdraw.lk);
|
||||||
return oldn - n;
|
return oldn - n;
|
||||||
|
|
||||||
Enodrawimage:
|
Enodrawimage:
|
||||||
|
|
@ -1527,9 +1545,11 @@ Enodrawscreen:
|
||||||
Eshortdraw:
|
Eshortdraw:
|
||||||
err = "short draw message";
|
err = "short draw message";
|
||||||
goto error;
|
goto error;
|
||||||
|
/*
|
||||||
Eshortread:
|
Eshortread:
|
||||||
err = "draw read too short";
|
err = "draw read too short";
|
||||||
goto error;
|
goto error;
|
||||||
|
*/
|
||||||
Eimageexists:
|
Eimageexists:
|
||||||
err = "image id in use";
|
err = "image id in use";
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1551,6 +1571,7 @@ Enotfont:
|
||||||
Eindex:
|
Eindex:
|
||||||
err = "character index out of range";
|
err = "character index out of range";
|
||||||
goto error;
|
goto error;
|
||||||
|
/*
|
||||||
Enoclient:
|
Enoclient:
|
||||||
err = "no such draw client";
|
err = "no such draw client";
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1560,6 +1581,7 @@ Edepth:
|
||||||
Enameused:
|
Enameused:
|
||||||
err = "image name in use";
|
err = "image name in use";
|
||||||
goto error;
|
goto error;
|
||||||
|
*/
|
||||||
Enoname:
|
Enoname:
|
||||||
err = "no image with that name";
|
err = "no image with that name";
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1580,7 +1602,8 @@ Ebadarg:
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
drawerror(display, err);
|
werrstr("%s", err);
|
||||||
|
qunlock(&sdraw.lk);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ enum
|
||||||
Arrow3 = 3,
|
Arrow3 = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
lmin(int a, int b)
|
lmin(int a, int b)
|
||||||
|
|
@ -18,6 +19,7 @@ lmin(int a, int b)
|
||||||
return a;
|
return a;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <draw.h>
|
#include <draw.h>
|
||||||
|
|
||||||
|
extern vlong _drawflength(int);
|
||||||
|
|
||||||
Font*
|
Font*
|
||||||
openfont(Display *d, char *name)
|
openfont(Display *d, char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -13,7 +15,7 @@ openfont(Display *d, char *name)
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
n = flength(fd);
|
n = _drawflength(fd);
|
||||||
buf = malloc(n+1);
|
buf = malloc(n+1);
|
||||||
if(buf == 0){
|
if(buf == 0){
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ subfontname(char *cfname, char *fname, int maxdepth)
|
||||||
if(maxdepth > 8)
|
if(maxdepth > 8)
|
||||||
maxdepth = 8;
|
maxdepth = 8;
|
||||||
|
|
||||||
for(i=log2[maxdepth]; i>=0; i--){
|
for(i=3; i>=0; i--){
|
||||||
|
if((1<<i) > maxdepth)
|
||||||
|
continue;
|
||||||
/* try i-bit grey */
|
/* try i-bit grey */
|
||||||
snprint(tmp2, sizeof tmp2, "%s.%d", t, i);
|
snprint(tmp2, sizeof tmp2, "%s.%d", t, i);
|
||||||
if(access(tmp2, AREAD) == 0)
|
if(access(tmp2, AREAD) == 0)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include <draw.h>
|
#include <draw.h>
|
||||||
|
|
||||||
vlong
|
vlong
|
||||||
flength(int fd)
|
_drawflength(int fd)
|
||||||
{
|
{
|
||||||
struct stat s;
|
struct stat s;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,20 +37,21 @@ xallocmemimage(Rectangle r, u32int chan, int pixmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate backing store. What we call a 32-bit image
|
* Allocate backing store.
|
||||||
* the X server calls a 24-bit image.
|
|
||||||
*/
|
*/
|
||||||
d = m->depth;
|
if(chan == GREY1)
|
||||||
|
d = 1;
|
||||||
|
else
|
||||||
|
d = _x.depth;
|
||||||
if(pixmap != PMundef)
|
if(pixmap != PMundef)
|
||||||
xm->pixmap = pixmap;
|
xm->pixmap = pixmap;
|
||||||
else
|
else
|
||||||
xm->pixmap = XCreatePixmap(_x.display, _x.drawable,
|
xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d);
|
||||||
Dx(r), Dy(r), d==32 ? 24 : d);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to align pixels on word boundaries.
|
* We want to align pixels on word boundaries.
|
||||||
*/
|
*/
|
||||||
if(d == 24)
|
if(m->depth == 24)
|
||||||
offset = r.min.x&3;
|
offset = r.min.x&3;
|
||||||
else
|
else
|
||||||
offset = r.min.x&(31/m->depth);
|
offset = r.min.x&(31/m->depth);
|
||||||
|
|
@ -60,7 +61,7 @@ xallocmemimage(Rectangle r, u32int chan, int pixmap)
|
||||||
/*
|
/*
|
||||||
* Wrap our data in an XImage structure.
|
* Wrap our data in an XImage structure.
|
||||||
*/
|
*/
|
||||||
xi = XCreateImage(_x.display, _x.vis, d==32 ? 24 : d,
|
xi = XCreateImage(_x.display, _x.vis, d,
|
||||||
ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r),
|
ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r),
|
||||||
32, m->width*sizeof(u32int));
|
32, m->width*sizeof(u32int));
|
||||||
if(xi == nil){
|
if(xi == nil){
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ void
|
||||||
memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
|
memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
|
||||||
Memimage *mask, Point mp, int op)
|
Memimage *mask, Point mp, int op)
|
||||||
{
|
{
|
||||||
int drew;
|
|
||||||
Memdrawparam *par;
|
Memdrawparam *par;
|
||||||
|
|
||||||
if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil)
|
if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil)
|
||||||
|
|
@ -116,6 +115,7 @@ xdraw(Memdrawparam *par)
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
/* this doesn't work on rob's mac? */
|
/* this doesn't work on rob's mac? */
|
||||||
|
return 0;
|
||||||
gc = _x.gcsimplesrc;
|
gc = _x.gcsimplesrc;
|
||||||
if(dst->chan == CMAP8 && _x.usetable)
|
if(dst->chan == CMAP8 && _x.usetable)
|
||||||
sdval = _x.tox11[sdval];
|
sdval = _x.tox11[sdval];
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ getimage0(Display *d)
|
||||||
fprint(2, "cannot read screen info: %r\n");
|
fprint(2, "cannot read screen info: %r\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
n = _drawmsgread(d, info, sizeof info);
|
n = _drawmsgread(d, info, sizeof info);
|
||||||
if(n != 12*12){
|
if(n != 12*12){
|
||||||
fprint(2, "short screen info\n");
|
fprint(2, "short screen info\n");
|
||||||
|
|
@ -113,8 +113,8 @@ xerror(XDisplay *d, XErrorEvent *e)
|
||||||
{
|
{
|
||||||
char buf[200];
|
char buf[200];
|
||||||
|
|
||||||
print("X error: error_code=%d, request_code=%d, minor=%d\n",
|
print("X error: error_code=%d, request_code=%d, minor=%d disp=%p\n",
|
||||||
e->error_code, e->request_code, e->minor_code);
|
e->error_code, e->request_code, e->minor_code, d);
|
||||||
XGetErrorText(d, e->error_code, buf, sizeof buf);
|
XGetErrorText(d, e->error_code, buf, sizeof buf);
|
||||||
print("%s\n", buf);
|
print("%s\n", buf);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -179,6 +179,13 @@ xattach(char *label)
|
||||||
_x.usetable = 1;
|
_x.usetable = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if(XMatchVisualInfo(_x.display, xrootid, 15, TrueColor, &xvi)
|
||||||
|
|| XMatchVisualInfo(_x.display, xrootid, 15, DirectColor, &xvi)){
|
||||||
|
_x.vis = xvi.visual;
|
||||||
|
_x.depth = 15;
|
||||||
|
_x.usetable = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
if(XMatchVisualInfo(_x.display, xrootid, 24, TrueColor, &xvi)
|
if(XMatchVisualInfo(_x.display, xrootid, 24, TrueColor, &xvi)
|
||||||
|| XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){
|
|| XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){
|
||||||
_x.vis = xvi.visual;
|
_x.vis = xvi.visual;
|
||||||
|
|
@ -227,6 +234,9 @@ xattach(char *label)
|
||||||
case 8:
|
case 8:
|
||||||
_x.chan = CMAP8;
|
_x.chan = CMAP8;
|
||||||
break;
|
break;
|
||||||
|
case 15:
|
||||||
|
_x.chan = RGB15;
|
||||||
|
break;
|
||||||
case 16: /* how to tell RGB15? */
|
case 16: /* how to tell RGB15? */
|
||||||
_x.chan = RGB16;
|
_x.chan = RGB16;
|
||||||
break;
|
break;
|
||||||
|
|
@ -264,7 +274,7 @@ xattach(char *label)
|
||||||
|
|
||||||
memset(&attr, 0, sizeof attr);
|
memset(&attr, 0, sizeof attr);
|
||||||
attr.colormap = _x.cmap;
|
attr.colormap = _x.cmap;
|
||||||
attr.background_pixel = 0;
|
attr.background_pixel = ~0;
|
||||||
attr.border_pixel = 0;
|
attr.border_pixel = 0;
|
||||||
_x.drawable = XCreateWindow(
|
_x.drawable = XCreateWindow(
|
||||||
_x.display, /* display */
|
_x.display, /* display */
|
||||||
|
|
@ -274,7 +284,7 @@ xattach(char *label)
|
||||||
Dx(r), /* width */
|
Dx(r), /* width */
|
||||||
Dy(r), /* height */
|
Dy(r), /* height */
|
||||||
0, /* border width */
|
0, /* border width */
|
||||||
_x.depth, /* depth */
|
DefaultDepthOfScreen(xscreen), /* depth */
|
||||||
InputOutput, /* class */
|
InputOutput, /* class */
|
||||||
_x.vis, /* visual */
|
_x.vis, /* visual */
|
||||||
/* valuemask */
|
/* valuemask */
|
||||||
|
|
@ -328,6 +338,7 @@ xattach(char *label)
|
||||||
*/
|
*/
|
||||||
_x.screenr = r;
|
_x.screenr = r;
|
||||||
_x.screenpm = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth);
|
_x.screenpm = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth);
|
||||||
|
_x.nextscreenpm = _x.screenpm;
|
||||||
_x.screenimage = xallocmemimage(r, _x.chan, _x.screenpm);
|
_x.screenimage = xallocmemimage(r, _x.chan, _x.screenpm);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -354,18 +365,22 @@ xattach(char *label)
|
||||||
XFlush(_x.display);
|
XFlush(_x.display);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lots of display connections for various threads.
|
* Lots of display connections for various procs.
|
||||||
*/
|
*/
|
||||||
_x.kbdcon = XOpenDisplay(NULL);
|
_x.kbdcon = XOpenDisplay(NULL);
|
||||||
_x.mousecon = XOpenDisplay(NULL);
|
_x.mousecon = XOpenDisplay(NULL);
|
||||||
_x.snarfcon = XOpenDisplay(NULL);
|
_x.snarfcon = XOpenDisplay(NULL);
|
||||||
|
|
||||||
|
if(0) fprint(2, "x: display=%p kbd=%p mouse=%p snarf=%p\n",
|
||||||
|
_x.display, _x.kbdcon, _x.mousecon, _x.snarfcon);
|
||||||
|
|
||||||
_x.black = xscreen->black_pixel;
|
_x.black = xscreen->black_pixel;
|
||||||
_x.white = xscreen->white_pixel;
|
_x.white = xscreen->white_pixel;
|
||||||
|
|
||||||
return _x.screenimage;
|
return _x.screenimage;
|
||||||
|
|
||||||
err0:
|
err0:
|
||||||
|
fprint(2, "%r\n");
|
||||||
/*
|
/*
|
||||||
* Should do a better job of cleaning up here.
|
* Should do a better job of cleaning up here.
|
||||||
*/
|
*/
|
||||||
|
|
@ -551,6 +566,14 @@ setupcmap(XWindow w)
|
||||||
void
|
void
|
||||||
flushmemscreen(Rectangle r)
|
flushmemscreen(Rectangle r)
|
||||||
{
|
{
|
||||||
|
if(_x.nextscreenpm != _x.screenpm){
|
||||||
|
qlock(&_x.screenlock);
|
||||||
|
XSync(_x.display, False);
|
||||||
|
XFreePixmap(_x.display, _x.screenpm);
|
||||||
|
_x.screenpm = _x.nextscreenpm;
|
||||||
|
qunlock(&_x.screenlock);
|
||||||
|
}
|
||||||
|
|
||||||
if(r.min.x >= r.max.x || r.min.y >= r.max.y)
|
if(r.min.x >= r.max.x || r.min.y >= r.max.y)
|
||||||
return;
|
return;
|
||||||
XCopyArea(_x.display, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y,
|
XCopyArea(_x.display, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y,
|
||||||
|
|
@ -564,6 +587,11 @@ xexpose(XEvent *e, XDisplay *xd)
|
||||||
XExposeEvent *xe;
|
XExposeEvent *xe;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
|
||||||
|
qlock(&_x.screenlock);
|
||||||
|
if(_x.screenpm != _x.nextscreenpm){
|
||||||
|
qunlock(&_x.screenlock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
xe = (XExposeEvent*)e;
|
xe = (XExposeEvent*)e;
|
||||||
r.min.x = xe->x;
|
r.min.x = xe->x;
|
||||||
r.min.y = xe->y;
|
r.min.y = xe->y;
|
||||||
|
|
@ -571,17 +599,29 @@ xexpose(XEvent *e, XDisplay *xd)
|
||||||
r.max.y = xe->y+xe->height;
|
r.max.y = xe->y+xe->height;
|
||||||
XCopyArea(xd, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y,
|
XCopyArea(xd, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y,
|
||||||
Dx(r), Dy(r), r.min.x, r.min.y);
|
Dx(r), Dy(r), r.min.x, r.min.y);
|
||||||
XFlush(xd);
|
XSync(xd, False);
|
||||||
|
qunlock(&_x.screenlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xconfigure(XEvent *e, XDisplay *xd)
|
xconfigure(XEvent *e, XDisplay *xd)
|
||||||
{
|
{
|
||||||
|
Rectangle r;
|
||||||
XConfigureEvent *xe = (XConfigureEvent*)e;
|
XConfigureEvent *xe = (XConfigureEvent*)e;
|
||||||
|
|
||||||
if(xe->width == Dx(_x.screenr) && xe->height == Dy(_x.screenr))
|
if(xe->width == Dx(_x.screenr) && xe->height == Dy(_x.screenr))
|
||||||
return 0;
|
return 0;
|
||||||
_x.newscreenr = Rect(0, 0, xe->width, xe->height);
|
if(xe->width==0 || xe->height==0)
|
||||||
|
fprint(2, "ignoring resize to %dx%d\n", xe->width, xe->height);
|
||||||
|
r = Rect(0, 0, xe->width, xe->height);
|
||||||
|
qlock(&_x.screenlock);
|
||||||
|
if(_x.screenpm != _x.nextscreenpm){
|
||||||
|
XCopyArea(xd, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y,
|
||||||
|
Dx(r), Dy(r), r.min.x, r.min.y);
|
||||||
|
XSync(xd, False);
|
||||||
|
}
|
||||||
|
qunlock(&_x.screenlock);
|
||||||
|
_x.newscreenr = r;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -598,7 +638,9 @@ xreplacescreenimage(void)
|
||||||
|
|
||||||
pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth);
|
pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth);
|
||||||
m = xallocmemimage(r, _x.chan, pixmap);
|
m = xallocmemimage(r, _x.chan, pixmap);
|
||||||
_x.screenpm = pixmap;
|
if(_x.nextscreenpm != _x.screenpm)
|
||||||
|
XFreePixmap(_x.display, _x.nextscreenpm);
|
||||||
|
_x.nextscreenpm = pixmap;
|
||||||
_x.screenr = r;
|
_x.screenr = r;
|
||||||
_drawreplacescreenimage(m);
|
_drawreplacescreenimage(m);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -256,3 +256,129 @@ xsetcursor(Cursor *c)
|
||||||
XFlush(_x.display);
|
XFlush(_x.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char buf[SnarfSize];
|
||||||
|
QLock lk;
|
||||||
|
} clip;
|
||||||
|
|
||||||
|
char*
|
||||||
|
xgetsnarf(XDisplay *xd)
|
||||||
|
{
|
||||||
|
uchar *data, *xdata;
|
||||||
|
Atom type;
|
||||||
|
ulong len, lastlen, dummy;
|
||||||
|
int fmt, i;
|
||||||
|
XWindow w;
|
||||||
|
|
||||||
|
qlock(&clip.lk);
|
||||||
|
w = XGetSelectionOwner(xd, XA_PRIMARY);
|
||||||
|
if(w == _x.drawable){
|
||||||
|
data = (uchar*)strdup(clip.buf);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if(w == None){
|
||||||
|
data = nil;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We should be waiting for SelectionNotify here, but it might never
|
||||||
|
* come, and we have no way to time out. Instead, we will zero the
|
||||||
|
* property, request our buddy to fill it in for us, and wait until
|
||||||
|
* he's done.
|
||||||
|
*/
|
||||||
|
XChangeProperty(xd, _x.drawable, XA_PRIMARY, XA_STRING, 8, PropModeReplace, (uchar*)"", 0);
|
||||||
|
XConvertSelection(xd, XA_PRIMARY, XA_STRING, None, _x.drawable, CurrentTime);
|
||||||
|
XFlush(xd);
|
||||||
|
lastlen = 0;
|
||||||
|
for(i=0; i<30; i++){
|
||||||
|
usleep(100*1000);
|
||||||
|
XGetWindowProperty(xd, _x.drawable, XA_STRING, 0, 0, 0, AnyPropertyType,
|
||||||
|
&type, &fmt, &dummy, &len, &data);
|
||||||
|
if(lastlen == len && len > 0)
|
||||||
|
break;
|
||||||
|
lastlen = len;
|
||||||
|
}
|
||||||
|
if(i == 30){
|
||||||
|
data = nil;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* get the property */
|
||||||
|
data = nil;
|
||||||
|
XGetWindowProperty(xd, _x.drawable, XA_STRING, 0, SnarfSize/4, 0,
|
||||||
|
AnyPropertyType, &type, &fmt, &len, &dummy, &xdata);
|
||||||
|
if(type != XA_STRING || len == 0){
|
||||||
|
if(xdata)
|
||||||
|
XFree(xdata);
|
||||||
|
data = nil;
|
||||||
|
}else{
|
||||||
|
if(xdata){
|
||||||
|
data = strdup((char*)xdata);
|
||||||
|
XFree(xdata);
|
||||||
|
}else
|
||||||
|
data = nil;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
qunlock(&clip.lk);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xputsnarf(XDisplay *xd, char *data)
|
||||||
|
{
|
||||||
|
if(strlen(data) >= SnarfSize)
|
||||||
|
return;
|
||||||
|
qlock(&clip.lk);
|
||||||
|
strcpy(clip.buf, data);
|
||||||
|
/*
|
||||||
|
* BUG: This is wrong. Instead, we should send an event to the
|
||||||
|
* mouse connection telling it to call XSetSelectionOwner.
|
||||||
|
*/
|
||||||
|
XSetSelectionOwner(_x.mousecon, XA_PRIMARY, _x.drawable, CurrentTime);
|
||||||
|
XFlush(xd);
|
||||||
|
qunlock(&clip.lk);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xselect(XEvent *e, XDisplay *xd)
|
||||||
|
{
|
||||||
|
XEvent r;
|
||||||
|
XSelectionRequestEvent *xe;
|
||||||
|
|
||||||
|
memset(&r, 0, sizeof r);
|
||||||
|
xe = (XSelectionRequestEvent*)e;
|
||||||
|
if(1 || xe->target == XA_STRING){
|
||||||
|
qlock(&clip.lk);
|
||||||
|
XChangeProperty(xd, xe->requestor, xe->property, XA_STRING, 8,
|
||||||
|
PropModeReplace, (uchar*)clip.buf, strlen(clip.buf)+1);
|
||||||
|
qunlock(&clip.lk);
|
||||||
|
r.xselection.property = xe->property;
|
||||||
|
}else{
|
||||||
|
fprint(2, "asked for a %d\n", xe->target);
|
||||||
|
r.xselection.property = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.xselection.display = xe->display;
|
||||||
|
/* r.xselection.property filled above */
|
||||||
|
r.xselection.target = xe->target;
|
||||||
|
r.xselection.type = SelectionNotify;
|
||||||
|
r.xselection.requestor = xe->requestor;
|
||||||
|
r.xselection.time = xe->time;
|
||||||
|
r.xselection.send_event = True;
|
||||||
|
r.xselection.selection = xe->selection;
|
||||||
|
XSendEvent(xd, xe->requestor, False, 0, &r);
|
||||||
|
XFlush(xd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putsnarf(char *data)
|
||||||
|
{
|
||||||
|
xputsnarf(_x.snarfcon, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
getsnarf(void)
|
||||||
|
{
|
||||||
|
return xgetsnarf(_x.snarfcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ _ioproc(void *arg)
|
||||||
kc = arg;
|
kc = arg;
|
||||||
threadsetname("kbdproc");
|
threadsetname("kbdproc");
|
||||||
kc->pid = getpid();
|
kc->pid = getpid();
|
||||||
|
XSelectInput(_x.kbdcon, _x.drawable, KeyPressMask);
|
||||||
for(;;){
|
for(;;){
|
||||||
XSelectInput(_x.kbdcon, _x.drawable, KeyPressMask);
|
|
||||||
XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent);
|
XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent);
|
||||||
switch(xevent.type){
|
switch(xevent.type){
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,9 @@ struct Xprivate {
|
||||||
XDisplay *mousecon;
|
XDisplay *mousecon;
|
||||||
Rectangle newscreenr;
|
Rectangle newscreenr;
|
||||||
Memimage* screenimage;
|
Memimage* screenimage;
|
||||||
|
QLock screenlock;
|
||||||
XDrawable screenpm;
|
XDrawable screenpm;
|
||||||
|
XDrawable nextscreenpm;
|
||||||
Rectangle screenr;
|
Rectangle screenr;
|
||||||
XDisplay *snarfcon;
|
XDisplay *snarfcon;
|
||||||
int toplan9[256];
|
int toplan9[256];
|
||||||
|
|
@ -73,11 +75,13 @@ extern void xfillcolor(Memimage*, Rectangle, u32int);
|
||||||
extern void xfreexdata(Memimage*);
|
extern void xfreexdata(Memimage*);
|
||||||
extern XImage *xgetxdata(Memimage*, Rectangle);
|
extern XImage *xgetxdata(Memimage*, Rectangle);
|
||||||
extern void xputxdata(Memimage*, Rectangle);
|
extern void xputxdata(Memimage*, Rectangle);
|
||||||
|
extern void _initdisplaymemimage(Display*, Memimage*);
|
||||||
|
|
||||||
struct Mouse;
|
struct Mouse;
|
||||||
extern int xtoplan9mouse(XEvent*, struct Mouse*);
|
extern int xtoplan9mouse(XEvent*, struct Mouse*);
|
||||||
extern int xtoplan9kbd(XEvent*);
|
extern int xtoplan9kbd(XEvent*);
|
||||||
extern void xexpose(XEvent*, XDisplay*);
|
extern void xexpose(XEvent*, XDisplay*);
|
||||||
|
extern int xselect(XEvent*, XDisplay*);
|
||||||
extern int xconfigure(XEvent*, XDisplay*);
|
extern int xconfigure(XEvent*, XDisplay*);
|
||||||
extern void flushmemscreen(Rectangle);
|
extern void flushmemscreen(Rectangle);
|
||||||
extern void xmoveto(Point);
|
extern void xmoveto(Point);
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ void
|
||||||
_ioproc(void *arg)
|
_ioproc(void *arg)
|
||||||
{
|
{
|
||||||
int one;
|
int one;
|
||||||
|
ulong mask;
|
||||||
Mouse m;
|
Mouse m;
|
||||||
Mousectl *mc;
|
Mousectl *mc;
|
||||||
XEvent xevent;
|
XEvent xevent;
|
||||||
|
|
@ -57,9 +58,10 @@ _ioproc(void *arg)
|
||||||
threadsetname("mouseproc");
|
threadsetname("mouseproc");
|
||||||
memset(&m, 0, sizeof m);
|
memset(&m, 0, sizeof m);
|
||||||
mc->pid = getpid();
|
mc->pid = getpid();
|
||||||
|
mask = MouseMask|ExposureMask|StructureNotifyMask;
|
||||||
|
XSelectInput(_x.mousecon, _x.drawable, mask);
|
||||||
for(;;){
|
for(;;){
|
||||||
XSelectInput(_x.mousecon, _x.drawable, MouseMask|ExposureMask|StructureNotifyMask);
|
XNextEvent(_x.mousecon, &xevent);
|
||||||
XWindowEvent(_x.mousecon, _x.drawable, MouseMask|ExposureMask|StructureNotifyMask, &xevent);
|
|
||||||
switch(xevent.type){
|
switch(xevent.type){
|
||||||
case Expose:
|
case Expose:
|
||||||
xexpose(&xevent, _x.mousecon);
|
xexpose(&xevent, _x.mousecon);
|
||||||
|
|
@ -68,6 +70,9 @@ _ioproc(void *arg)
|
||||||
if(xconfigure(&xevent, _x.mousecon))
|
if(xconfigure(&xevent, _x.mousecon))
|
||||||
nbsend(mc->resizec, &one);
|
nbsend(mc->resizec, &one);
|
||||||
continue;
|
continue;
|
||||||
|
case SelectionRequest:
|
||||||
|
xselect(&xevent, _x.mousecon);
|
||||||
|
continue;
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue