Add drawsetlabel(Display*, char*).

Turn window destruction into "hangup" note.
Fix (?) snarf buffer management.
Add latin1 keyboard translation.
This commit is contained in:
rsc 2003-11-23 18:15:43 +00:00
parent 986b36bccd
commit 16a7096669
9 changed files with 407 additions and 36 deletions

View file

@ -11,8 +11,8 @@
#include <keyboard.h>
#include "x11-memdraw.h"
int
xtoplan9kbd(XEvent *e)
static int
_xtoplan9kbd(XEvent *e)
{
int ind, k, md;
@ -117,16 +117,82 @@ xtoplan9kbd(XEvent *e)
return k;
}
static Rune*
xtoplan9latin1(XEvent *e)
{
static Rune k[10];
static int alting, nk;
int n;
int r;
r = _xtoplan9kbd(e);
if(r < 0)
return nil;
if(alting){
k[nk++] = r;
n = _latin1(k, nk);
if(n > 0){
alting = 0;
k[0] = n;
k[1] = 0;
return k;
}
if(n == -1){
alting = 0;
k[nk] = 0;
return k;
}
/* n < -1, need more input */
return nil;
}else if(r == Kalt){
alting = 1;
nk = 0;
return nil;
}else{
k[0] = r;
k[1] = 0;
return k;
}
}
int
xtoplan9mouse(XEvent *e, Mouse *m)
xtoplan9kbd(XEvent *e)
{
static Rune *r;
if(e == (XEvent*)-1){
assert(r);
r--;
return 0;
}
if(e)
r = xtoplan9latin1(e);
if(r && *r)
return *r++;
return -1;
}
int
xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m)
{
int s;
XButtonEvent *be;
XMotionEvent *me;
if(_x.putsnarf != _x.assertsnarf){
_x.assertsnarf = _x.putsnarf;
XSetSelectionOwner(_x.mousecon, XA_PRIMARY, _x.drawable, CurrentTime);
if(_x.clipboard != None)
XSetSelectionOwner(_x.mousecon, _x.clipboard, _x.drawable, CurrentTime);
XFlush(xd);
}
switch(e->type){
case ButtonPress:
be = (XButtonEvent*)e;
/* Fake message, just sent to make us announce snarf. */
if(be->send_event && be->state==~0 && be->button==~0)
return -1;
/* BUG? on mac need to inherit these from elsewhere? */
m->xy.x = be->x;
m->xy.y = be->y;
@ -265,34 +331,55 @@ char*
xgetsnarf(XDisplay *xd)
{
uchar *data, *xdata;
Atom type;
Atom clipboard, type, prop;
ulong len, lastlen, dummy;
int fmt, i;
XWindow w;
qlock(&clip.lk);
/*
* Is there a primary selection (highlighted text in an xterm)?
*/
clipboard = XA_PRIMARY;
w = XGetSelectionOwner(xd, XA_PRIMARY);
if(w == _x.drawable){
mine:
data = (uchar*)strdup(clip.buf);
goto out;
}
/*
* If not, is there a clipboard selection?
*/
if(w == None && _x.clipboard != None){
clipboard = _x.clipboard;
w = XGetSelectionOwner(xd, _x.clipboard);
if(w == _x.drawable)
goto mine;
}
/*
* If not, give up.
*/
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.
* come, and we have no way to time out. Instead, we will clear
* local property #1, request our buddy to fill it in for us, and poll
* until he's done or we get tired of waiting.
*/
XChangeProperty(xd, _x.drawable, XA_PRIMARY, XA_STRING, 8, PropModeReplace, (uchar*)"", 0);
XConvertSelection(xd, XA_PRIMARY, XA_STRING, None, _x.drawable, CurrentTime);
prop = 1;
XChangeProperty(xd, _x.drawable, prop, XA_STRING, 8, PropModeReplace, (uchar*)"", 0);
XConvertSelection(xd, clipboard, XA_STRING, prop, _x.drawable, CurrentTime);
XFlush(xd);
lastlen = 0;
for(i=0; i<30; i++){
for(i=0; i<10 || (lastlen!=0 && i<30); i++){
usleep(100*1000);
XGetWindowProperty(xd, _x.drawable, XA_STRING, 0, 0, 0, AnyPropertyType,
XGetWindowProperty(xd, _x.drawable, prop, 0, 0, 0, AnyPropertyType,
&type, &fmt, &dummy, &len, &data);
if(lastlen == len && len > 0)
break;
@ -304,7 +391,7 @@ xgetsnarf(XDisplay *xd)
}
/* get the property */
data = nil;
XGetWindowProperty(xd, _x.drawable, XA_STRING, 0, SnarfSize/4, 0,
XGetWindowProperty(xd, _x.drawable, prop, 0, SnarfSize/sizeof(ulong), 0,
AnyPropertyType, &type, &fmt, &len, &dummy, &xdata);
if(type != XA_STRING || len == 0){
if(xdata)
@ -325,16 +412,25 @@ out:
void
xputsnarf(XDisplay *xd, char *data)
{
XButtonEvent e;
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);
/* leave note for mouse proc to assert selection ownership */
_x.putsnarf++;
/* send mouse a fake event so snarf is announced */
memset(&e, 0, sizeof e);
e.type = ButtonPress;
e.window = _x.drawable;
e.state = ~0;
e.button = ~0;
XSendEvent(xd, _x.drawable, True, ButtonPressMask, (XEvent*)&e);
XFlush(xd);
qunlock(&clip.lk);
}