aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-10-11 02:47:43 +0000
committerrsc <devnull@localhost>2003-10-11 02:47:43 +0000
commit161060a46346fa0beeb48b55ed28b2cd330bc4e8 (patch)
treeddcba6ab6af148fefd7667f494485ebc3675fa3f /src
parent4af386f434d5ca3de733951d4f73dd134e879cc2 (diff)
downloadplan9port-161060a46346fa0beeb48b55ed28b2cd330bc4e8.tar.gz
plan9port-161060a46346fa0beeb48b55ed28b2cd330bc4e8.tar.bz2
plan9port-161060a46346fa0beeb48b55ed28b2cd330bc4e8.zip
Lots of X fixes.
Diffstat (limited to 'src')
-rw-r--r--src/libdraw/Makefile1
-rw-r--r--src/libdraw/arith.c2
-rw-r--r--src/libdraw/devdraw.c35
-rw-r--r--src/libdraw/md-line.c2
-rw-r--r--src/libdraw/openfont.c4
-rw-r--r--src/libdraw/subfontname.c4
-rw-r--r--src/libdraw/unix.c2
-rw-r--r--src/libdraw/x11-alloc.c15
-rw-r--r--src/libdraw/x11-draw.c2
-rw-r--r--src/libdraw/x11-init.c60
-rw-r--r--src/libdraw/x11-itrans.c126
-rw-r--r--src/libdraw/x11-keyboard.c2
-rw-r--r--src/libdraw/x11-memdraw.h4
-rw-r--r--src/libdraw/x11-mouse.c9
14 files changed, 237 insertions, 31 deletions
diff --git a/src/libdraw/Makefile b/src/libdraw/Makefile
index 8013efa5..807b8e74 100644
--- a/src/libdraw/Makefile
+++ b/src/libdraw/Makefile
@@ -99,6 +99,7 @@ OFILES=\
x11-mouse.$O\
x11-pixelbits.$O\
x11-unload.$O\
+ x11-wsys.$O\
devdraw.$O\
unix.$O\
diff --git a/src/libdraw/arith.c b/src/libdraw/arith.c
index 41b30620..1b19fc1c 100644
--- a/src/libdraw/arith.c
+++ b/src/libdraw/arith.c
@@ -167,8 +167,6 @@ drawld2chan[] = {
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
setalpha(u32int color, uchar alpha)
{
diff --git a/src/libdraw/devdraw.c b/src/libdraw/devdraw.c
index b0036385..f4749867 100644
--- a/src/libdraw/devdraw.c
+++ b/src/libdraw/devdraw.c
@@ -138,6 +138,7 @@ void
_initdisplaymemimage(Display *d, Memimage *m)
{
screenimage = m;
+ m->screenref = 1;
client0 = mallocz(sizeof(Client), 1);
if(client0 == nil){
fprint(2, "initdraw: allocating client0: out of memory");
@@ -165,7 +166,16 @@ _drawreplacescreenimage(Memimage *m)
* about the resize through external means, so all we
* need to do is this assignment.
*/
+ Memimage *om;
+
+ qlock(&sdraw.lk);
+ om = screenimage;
screenimage = m;
+ m->screenref = 1;
+ if(om && --om->screenref == 0){
+ _freememimage(om);
+ }
+ qunlock(&sdraw.lk);
}
static
@@ -399,6 +409,8 @@ drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
d->name = 0;
d->vers = 0;
d->image = i;
+ if(i->screenref)
+ ++i->screenref;
d->nfchar = 0;
d->fchar = 0;
d->fromname = 0;
@@ -534,11 +546,9 @@ drawfreedimage(DImage *dimage)
drawfreedimage(dimage->fromname);
goto Return;
}
- //if(dimage->image == screenimage) /* don't free the display */
- // goto Return;
ds = dimage->dscreen;
+ l = dimage->image;
if(ds){
- l = dimage->image;
if(l->data == screenimage->data)
addflush(l->layer->screenr);
if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
@@ -549,8 +559,12 @@ drawfreedimage(DImage *dimage)
else
memlfree(l);
drawfreedscreen(ds);
- }else
- freememimage(dimage->image);
+ }else{
+ if(l->screenref==0)
+ freememimage(l);
+ else if(--l->screenref==0)
+ _freememimage(l);
+ }
Return:
free(dimage->fchar);
free(dimage);
@@ -732,6 +746,7 @@ _drawmsgread(Display *d, void *a, int n)
{
int inbuf;
+ qlock(&sdraw.lk);
inbuf = d->obufp - d->obuf;
if(n > inbuf)
n = inbuf;
@@ -740,6 +755,7 @@ _drawmsgread(Display *d, void *a, int n)
if(inbuf)
memmove(d->obuf, d->obufp-inbuf, inbuf);
d->obufp = d->obuf+inbuf;
+ qunlock(&sdraw.lk);
return n;
}
@@ -776,6 +792,7 @@ _drawmsgwrite(Display *d, void *v, int n)
Refreshfn reffn;
Refx *refx;
+ qlock(&sdraw.lk);
d->obufp = d->obuf;
a = v;
m = 0;
@@ -1516,6 +1533,7 @@ _drawmsgwrite(Display *d, void *v, int n)
continue;
}
}
+ qunlock(&sdraw.lk);
return oldn - n;
Enodrawimage:
@@ -1527,9 +1545,11 @@ Enodrawscreen:
Eshortdraw:
err = "short draw message";
goto error;
+/*
Eshortread:
err = "draw read too short";
goto error;
+*/
Eimageexists:
err = "image id in use";
goto error;
@@ -1551,6 +1571,7 @@ Enotfont:
Eindex:
err = "character index out of range";
goto error;
+/*
Enoclient:
err = "no such draw client";
goto error;
@@ -1560,6 +1581,7 @@ Edepth:
Enameused:
err = "image name in use";
goto error;
+*/
Enoname:
err = "no image with that name";
goto error;
@@ -1580,7 +1602,8 @@ Ebadarg:
goto error;
error:
- drawerror(display, err);
+ werrstr("%s", err);
+ qunlock(&sdraw.lk);
return -1;
}
diff --git a/src/libdraw/md-line.c b/src/libdraw/md-line.c
index 632e8238..7053c171 100644
--- a/src/libdraw/md-line.c
+++ b/src/libdraw/md-line.c
@@ -10,6 +10,7 @@ enum
Arrow3 = 3,
};
+/*
static
int
lmin(int a, int b)
@@ -18,6 +19,7 @@ lmin(int a, int b)
return a;
return b;
}
+*/
static
int
diff --git a/src/libdraw/openfont.c b/src/libdraw/openfont.c
index dc16e379..e9fa3f84 100644
--- a/src/libdraw/openfont.c
+++ b/src/libdraw/openfont.c
@@ -2,6 +2,8 @@
#include <libc.h>
#include <draw.h>
+extern vlong _drawflength(int);
+
Font*
openfont(Display *d, char *name)
{
@@ -13,7 +15,7 @@ openfont(Display *d, char *name)
if(fd < 0)
return 0;
- n = flength(fd);
+ n = _drawflength(fd);
buf = malloc(n+1);
if(buf == 0){
close(fd);
diff --git a/src/libdraw/subfontname.c b/src/libdraw/subfontname.c
index bcb4e3a1..bf397cb5 100644
--- a/src/libdraw/subfontname.c
+++ b/src/libdraw/subfontname.c
@@ -29,7 +29,9 @@ subfontname(char *cfname, char *fname, int maxdepth)
if(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 */
snprint(tmp2, sizeof tmp2, "%s.%d", t, i);
if(access(tmp2, AREAD) == 0)
diff --git a/src/libdraw/unix.c b/src/libdraw/unix.c
index 2203b087..491bc66c 100644
--- a/src/libdraw/unix.c
+++ b/src/libdraw/unix.c
@@ -5,7 +5,7 @@
#include <draw.h>
vlong
-flength(int fd)
+_drawflength(int fd)
{
struct stat s;
diff --git a/src/libdraw/x11-alloc.c b/src/libdraw/x11-alloc.c
index 19475c74..458efc61 100644
--- a/src/libdraw/x11-alloc.c
+++ b/src/libdraw/x11-alloc.c
@@ -37,20 +37,21 @@ xallocmemimage(Rectangle r, u32int chan, int pixmap)
}
/*
- * Allocate backing store. What we call a 32-bit image
- * the X server calls a 24-bit image.
+ * Allocate backing store.
*/
- d = m->depth;
+ if(chan == GREY1)
+ d = 1;
+ else
+ d = _x.depth;
if(pixmap != PMundef)
xm->pixmap = pixmap;
else
- xm->pixmap = XCreatePixmap(_x.display, _x.drawable,
- Dx(r), Dy(r), d==32 ? 24 : d);
+ xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d);
/*
* We want to align pixels on word boundaries.
*/
- if(d == 24)
+ if(m->depth == 24)
offset = r.min.x&3;
else
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.
*/
- 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),
32, m->width*sizeof(u32int));
if(xi == nil){
diff --git a/src/libdraw/x11-draw.c b/src/libdraw/x11-draw.c
index ee91791d..97438740 100644
--- a/src/libdraw/x11-draw.c
+++ b/src/libdraw/x11-draw.c
@@ -17,7 +17,6 @@ void
memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
Memimage *mask, Point mp, int op)
{
- int drew;
Memdrawparam *par;
if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil)
@@ -116,6 +115,7 @@ xdraw(Memdrawparam *par)
}
}else{
/* this doesn't work on rob's mac? */
+ return 0;
gc = _x.gcsimplesrc;
if(dst->chan == CMAP8 && _x.usetable)
sdval = _x.tox11[sdval];
diff --git a/src/libdraw/x11-init.c b/src/libdraw/x11-init.c
index 85543e83..28f6ae40 100644
--- a/src/libdraw/x11-init.c
+++ b/src/libdraw/x11-init.c
@@ -71,7 +71,7 @@ getimage0(Display *d)
fprint(2, "cannot read screen info: %r\n");
abort();
}
-
+
n = _drawmsgread(d, info, sizeof info);
if(n != 12*12){
fprint(2, "short screen info\n");
@@ -113,8 +113,8 @@ xerror(XDisplay *d, XErrorEvent *e)
{
char buf[200];
- print("X error: error_code=%d, request_code=%d, minor=%d\n",
- e->error_code, e->request_code, e->minor_code);
+ print("X error: error_code=%d, request_code=%d, minor=%d disp=%p\n",
+ e->error_code, e->request_code, e->minor_code, d);
XGetErrorText(d, e->error_code, buf, sizeof buf);
print("%s\n", buf);
return 0;
@@ -179,6 +179,13 @@ xattach(char *label)
_x.usetable = 1;
}
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)
|| XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){
_x.vis = xvi.visual;
@@ -227,6 +234,9 @@ xattach(char *label)
case 8:
_x.chan = CMAP8;
break;
+ case 15:
+ _x.chan = RGB15;
+ break;
case 16: /* how to tell RGB15? */
_x.chan = RGB16;
break;
@@ -264,7 +274,7 @@ xattach(char *label)
memset(&attr, 0, sizeof attr);
attr.colormap = _x.cmap;
- attr.background_pixel = 0;
+ attr.background_pixel = ~0;
attr.border_pixel = 0;
_x.drawable = XCreateWindow(
_x.display, /* display */
@@ -274,7 +284,7 @@ xattach(char *label)
Dx(r), /* width */
Dy(r), /* height */
0, /* border width */
- _x.depth, /* depth */
+ DefaultDepthOfScreen(xscreen), /* depth */
InputOutput, /* class */
_x.vis, /* visual */
/* valuemask */
@@ -328,6 +338,7 @@ xattach(char *label)
*/
_x.screenr = r;
_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);
/*
@@ -354,18 +365,22 @@ xattach(char *label)
XFlush(_x.display);
/*
- * Lots of display connections for various threads.
+ * Lots of display connections for various procs.
*/
_x.kbdcon = XOpenDisplay(NULL);
_x.mousecon = 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.white = xscreen->white_pixel;
return _x.screenimage;
err0:
+fprint(2, "%r\n");
/*
* Should do a better job of cleaning up here.
*/
@@ -551,6 +566,14 @@ setupcmap(XWindow w)
void
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)
return;
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;
Rectangle r;
+ qlock(&_x.screenlock);
+ if(_x.screenpm != _x.nextscreenpm){
+ qunlock(&_x.screenlock);
+ return;
+ }
xe = (XExposeEvent*)e;
r.min.x = xe->x;
r.min.y = xe->y;
@@ -571,17 +599,29 @@ xexpose(XEvent *e, XDisplay *xd)
r.max.y = xe->y+xe->height;
XCopyArea(xd, _x.screenpm, _x.drawable, _x.gccopy, 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
xconfigure(XEvent *e, XDisplay *xd)
{
+ Rectangle r;
XConfigureEvent *xe = (XConfigureEvent*)e;
if(xe->width == Dx(_x.screenr) && xe->height == Dy(_x.screenr))
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;
}
@@ -598,7 +638,9 @@ xreplacescreenimage(void)
pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth);
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;
_drawreplacescreenimage(m);
return 1;
diff --git a/src/libdraw/x11-itrans.c b/src/libdraw/x11-itrans.c
index 49ee3fbb..35fd31ea 100644
--- a/src/libdraw/x11-itrans.c
+++ b/src/libdraw/x11-itrans.c
@@ -256,3 +256,129 @@ xsetcursor(Cursor *c)
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);
+}
+
diff --git a/src/libdraw/x11-keyboard.c b/src/libdraw/x11-keyboard.c
index 188e52bf..92b57814 100644
--- a/src/libdraw/x11-keyboard.c
+++ b/src/libdraw/x11-keyboard.c
@@ -41,8 +41,8 @@ _ioproc(void *arg)
kc = arg;
threadsetname("kbdproc");
kc->pid = getpid();
+ XSelectInput(_x.kbdcon, _x.drawable, KeyPressMask);
for(;;){
- XSelectInput(_x.kbdcon, _x.drawable, KeyPressMask);
XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent);
switch(xevent.type){
case KeyPress:
diff --git a/src/libdraw/x11-memdraw.h b/src/libdraw/x11-memdraw.h
index 9fffe34e..514926da 100644
--- a/src/libdraw/x11-memdraw.h
+++ b/src/libdraw/x11-memdraw.h
@@ -54,7 +54,9 @@ struct Xprivate {
XDisplay *mousecon;
Rectangle newscreenr;
Memimage* screenimage;
+ QLock screenlock;
XDrawable screenpm;
+ XDrawable nextscreenpm;
Rectangle screenr;
XDisplay *snarfcon;
int toplan9[256];
@@ -73,11 +75,13 @@ extern void xfillcolor(Memimage*, Rectangle, u32int);
extern void xfreexdata(Memimage*);
extern XImage *xgetxdata(Memimage*, Rectangle);
extern void xputxdata(Memimage*, Rectangle);
+extern void _initdisplaymemimage(Display*, Memimage*);
struct Mouse;
extern int xtoplan9mouse(XEvent*, struct Mouse*);
extern int xtoplan9kbd(XEvent*);
extern void xexpose(XEvent*, XDisplay*);
+extern int xselect(XEvent*, XDisplay*);
extern int xconfigure(XEvent*, XDisplay*);
extern void flushmemscreen(Rectangle);
extern void xmoveto(Point);
diff --git a/src/libdraw/x11-mouse.c b/src/libdraw/x11-mouse.c
index c6a26851..6b5b3922 100644
--- a/src/libdraw/x11-mouse.c
+++ b/src/libdraw/x11-mouse.c
@@ -48,6 +48,7 @@ void
_ioproc(void *arg)
{
int one;
+ ulong mask;
Mouse m;
Mousectl *mc;
XEvent xevent;
@@ -57,9 +58,10 @@ _ioproc(void *arg)
threadsetname("mouseproc");
memset(&m, 0, sizeof m);
mc->pid = getpid();
+ mask = MouseMask|ExposureMask|StructureNotifyMask;
+ XSelectInput(_x.mousecon, _x.drawable, mask);
for(;;){
- XSelectInput(_x.mousecon, _x.drawable, MouseMask|ExposureMask|StructureNotifyMask);
- XWindowEvent(_x.mousecon, _x.drawable, MouseMask|ExposureMask|StructureNotifyMask, &xevent);
+ XNextEvent(_x.mousecon, &xevent);
switch(xevent.type){
case Expose:
xexpose(&xevent, _x.mousecon);
@@ -68,6 +70,9 @@ _ioproc(void *arg)
if(xconfigure(&xevent, _x.mousecon))
nbsend(mc->resizec, &one);
continue;
+ case SelectionRequest:
+ xselect(&xevent, _x.mousecon);
+ continue;
case ButtonPress:
case ButtonRelease:
case MotionNotify: