[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
X Selection
If anyone wants to try out X selections apply the following patch and
add "-DSELECTION" to the DEFS in the Makefile. I don't know if I'm going
to keep the old method around. In particular I'd like to know if it
solves the SCO cut and paste problems.
Dennis Payne
dulsi@identicalsoftware.com
--- WeXterm.h.orig Thu Nov 18 22:06:05 1999
+++ WeXterm.h Thu Dec 16 20:43:25 1999
@@ -33,11 +33,12 @@
Window window;
GC gc;
XFontStruct *font;
- Atom delete_atom, protocol_atom;
+ Atom delete_atom, protocol_atom, selection_atom, text_atom, property_atom;
int font_height, font_width;
int altmask;
int colors[16];
WpeMouseShape shape_list[2];
+ char *selection;
} WpeXStruct;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *\
--- WeXterm.c.orig Thu Nov 18 22:06:05 1999
+++ WeXterm.c Thu Dec 16 20:43:25 1999
@@ -458,6 +458,10 @@
atom_num + 1);
WpeFree(new_atom_list);
+ WpeXInfo.selection_atom = XInternAtom(WpeXInfo.display, "PRIMARY", False);
+ WpeXInfo.text_atom = XInternAtom(WpeXInfo.display, "STRING", False);
+ WpeXInfo.property_atom = XInternAtom(WpeXInfo.display, "GTK_SELECTION", False);
+ WpeXInfo.selection = NULL;
WpeXGCSetup();
XMapWindow(WpeXInfo.display, WpeXInfo.window);
--- we_xterm.c.orig Thu Nov 18 22:06:05 1999
+++ we_xterm.c Thu Dec 16 20:43:32 1999
@@ -435,15 +435,17 @@
KeySym keysym;
XComposeStatus compose;
unsigned char buffer[BUFSIZE];
- int root_x, root_y, x, y, charcount;
+ int charcount;
unsigned int key_b;
XSizeHints size_hints;
expose_report = (XExposeEvent *)&report;
while (XCheckMaskEvent(WpeXInfo.display, KeyPressMask | ButtonPressMask |
ExposureMask | StructureNotifyMask, &report) == True)
- { switch(report.type)
- { case Expose:
+ {
+ switch(report.type)
+ {
+ case Expose:
/* Reason for +2 : Assumes extra character on either side. */
e_refresh_area(expose_report->x/WpeXInfo.font_width,
expose_report->y/WpeXInfo.font_height,
@@ -453,36 +455,34 @@
e_refresh();
break;
case ConfigureNotify:
- { size_hints.width = (report.xconfigure.width / WpeXInfo.font_width) * WpeXInfo.font_width;
+ size_hints.width = (report.xconfigure.width / WpeXInfo.font_width) * WpeXInfo.font_width;
size_hints.height = (report.xconfigure.height / WpeXInfo.font_height) * WpeXInfo.font_height;
if(size_hints.width != MAXSCOL * WpeXInfo.font_width ||
size_hints.height != MAXSLNS * WpeXInfo.font_height)
- { extern struct EXT h_error;
+ {
+ extern struct EXT h_error;
MAXSCOL = size_hints.width / WpeXInfo.font_width;
MAXSLNS = size_hints.height / WpeXInfo.font_height;
e_x_repaint_desk(h_error.cn->f[h_error.cn->mxedt]);
}
- }
- while (XCheckMaskEvent(WpeXInfo.display,
- StructureNotifyMask, &report) == True);
break;
case KeyPress:
- charcount = XLookupString(&report.xkey, buffer, BUFSIZE,
- &keysym, &compose);
+ charcount = XLookupString(&report.xkey, buffer, BUFSIZE, &keysym, &compose);
if(charcount == 1 && *buffer == CtrlC) return(CtrlC);
break;
case ButtonPress:
- if(!pic) break;
- XQueryPointer(WpeXInfo.display, WpeXInfo.window, &tmp_root, &tmp_win,
- &root_x, &root_y, &x, &y, &key_b);
+ if (!pic)
+ break;
+ key_b = report.xbutton.state;
if(report.xbutton.button == 1)
- { e_mouse.k = (key_b & ShiftMask) ? 3 : 0 +
+ {
+ e_mouse.k = (key_b & ShiftMask) ? 3 : 0 +
(key_b & ControlMask) ? 4 : 0 +
(key_b & WpeXInfo.altmask) ? 8 : 0;
e_mouse.x = report.xbutton.x/WpeXInfo.font_width;
e_mouse.y = report.xbutton.y/WpeXInfo.font_height;
- if(e_mouse.x > (pic->e.x + pic->a.x - 10)/2
- && e_mouse.x < (pic->e.x + pic->a.x + 6)/2 )
+ if (e_mouse.x > (pic->e.x + pic->a.x - 10)/2 &&
+ e_mouse.x < (pic->e.x + pic->a.x + 6)/2 )
return(CtrlC);
}
break;
@@ -495,7 +495,7 @@
{
Window tmp_win, tmp_root;
XEvent report;
- XExposeEvent *expose_report;
+ XSelectionEvent se;
KeySym keysym;
XComposeStatus compose;
int charcount;
@@ -504,13 +504,13 @@
unsigned int key_b;
XSizeHints size_hints;
- expose_report = (XExposeEvent *)&report;
e_refresh();
XQueryPointer(WpeXInfo.display, WpeXInfo.window, &tmp_root, &tmp_win,
&root_x, &root_y, &x, &y, &key_b);
if(key_b & (Button1Mask | Button2Mask | Button3Mask))
- { e_mouse.x = x/WpeXInfo.font_width;
+ {
+ e_mouse.x = x / WpeXInfo.font_width;
e_mouse.y = y/WpeXInfo.font_height;
c = 0;
if(key_b & Button1Mask) c |= 1;
@@ -519,76 +519,79 @@
return(-c);
}
- while(1) {
-
+ while (1)
+ {
XNextEvent(WpeXInfo.display, &report);
switch(report.type)
- { case Expose:
- do {
+ {
+ case Expose:
+ do
+ {
/* Reason for +2 : Assumes extra character on either side. */
- e_refresh_area(expose_report->x/WpeXInfo.font_width,
- expose_report->y/WpeXInfo.font_height,
- expose_report->width/WpeXInfo.font_width+2,
- expose_report->height/WpeXInfo.font_height+2);
- }
- while (XCheckMaskEvent(WpeXInfo.display,
- ExposureMask, &report) == True);
+ e_refresh_area(report.xexpose.x / WpeXInfo.font_width,
+ report.xexpose.y / WpeXInfo.font_height,
+ report.xexpose.width / WpeXInfo.font_width + 2,
+ report.xexpose.height / WpeXInfo.font_height + 2);
+ } while (XCheckMaskEvent(WpeXInfo.display, ExposureMask, &report) == True);
e_refresh();
break;
case ConfigureNotify:
- { size_hints.width = (report.xconfigure.width / WpeXInfo.font_width) * WpeXInfo.font_width;
+ size_hints.width = (report.xconfigure.width / WpeXInfo.font_width) * WpeXInfo.font_width;
size_hints.height = (report.xconfigure.height / WpeXInfo.font_height) * WpeXInfo.font_height;
if(size_hints.width != MAXSCOL * WpeXInfo.font_width ||
size_hints.height != MAXSLNS * WpeXInfo.font_height)
- { extern struct EXT h_error;
+ {
+ extern struct EXT h_error;
MAXSCOL = size_hints.width / WpeXInfo.font_width;
MAXSLNS = size_hints.height / WpeXInfo.font_height;
e_x_repaint_desk(h_error.cn->f[h_error.cn->mxedt]);
}
- }
- while (XCheckMaskEvent(WpeXInfo.display,
- StructureNotifyMask, &report) == True);
break;
case ClientMessage:
- if(report.xclient.message_type == WpeXInfo.protocol_atom
- && ((report.xclient.format == 8
- && report.xclient.data.b[0] == WpeXInfo.delete_atom)
- || (report.xclient.format == 16
- && report.xclient.data.s[0] == WpeXInfo.delete_atom)
- || (report.xclient.format == 32
- && report.xclient.data.l[0] == WpeXInfo.delete_atom)))
- { extern struct EXT h_error;
+ if (report.xclient.message_type == WpeXInfo.protocol_atom &&
+ ((report.xclient.format == 8 &&
+ report.xclient.data.b[0] == WpeXInfo.delete_atom) ||
+ (report.xclient.format == 16 &&
+ report.xclient.data.s[0] == WpeXInfo.delete_atom) ||
+ (report.xclient.format == 32 &&
+ report.xclient.data.l[0] == WpeXInfo.delete_atom)))
+ {
+ extern struct EXT h_error;
e_quit(h_error.cn->f[h_error.cn->mxedt]);
}
break;
case KeyPress:
- charcount = XLookupString(&report.xkey, buffer, BUFSIZE,
- &keysym, &compose);
+ charcount = XLookupString(&report.xkey, buffer, BUFSIZE, &keysym,
+ &compose);
+ key_b = report.xkey.state;
if(charcount == 1)
{
- XQueryPointer(WpeXInfo.display, WpeXInfo.window, &tmp_root, &tmp_win,
- &root_x, &root_y, &x, &y, &key_b);
if(*buffer == 127)
- { if(key_b & ControlMask) return(CENTF);
- else if(key_b & ShiftMask) return(ShiftDel);
- else if(key_b & WpeXInfo.altmask) return(AltDel);
- else return(ENTF);
+ {
+ if (key_b & ControlMask)
+ return(CENTF);
+ else if (key_b & ShiftMask)
+ return(ShiftDel);
+ else if (key_b & WpeXInfo.altmask)
+ return(AltDel);
+ else
+ return(ENTF);
}
if((key_b & ShiftMask) && (*buffer == '\t'))
return(WPE_BTAB);
if(key_b & WpeXInfo.altmask)
- c = e_tast_sim(key_b & ShiftMask ?
- toupper(*buffer) : *buffer);
- else return(*buffer);
+ c = e_tast_sim(key_b & ShiftMask ? toupper(*buffer) : *buffer);
+ else
+ return(*buffer);
}
else
- { c = 0;
- XQueryPointer(WpeXInfo.display, WpeXInfo.window, &tmp_root, &tmp_win,
- &root_x, &root_y, &x, &y, &key_b);
+ {
+ c = 0;
if(key_b & ControlMask)
- { if(keysym == XK_Left) c = CCLE;
+ {
+ if (keysym == XK_Left) c = CCLE;
else if(keysym == XK_Right) c = CCRI;
else if(keysym == XK_Home) c = CPS1;
else if(keysym == XK_End) c = CEND;
@@ -657,13 +662,14 @@
}
}
if(c != 0)
- { if(key_b & ShiftMask) c = c + 512;
+ {
+ if (key_b & ShiftMask)
+ c = c + 512;
return(c);
}
break;
case ButtonPress:
- XQueryPointer(WpeXInfo.display, WpeXInfo.window, &tmp_root, &tmp_win,
- &root_x, &root_y, &x, &y, &key_b);
+ key_b = report.xbutton.state;
e_mouse.k = (key_b & ShiftMask) ? 3 : 0 +
(key_b & ControlMask) ? 4 : 0 +
(key_b & WpeXInfo.altmask) ? 8 : 0;
@@ -674,9 +680,40 @@
if(report.xbutton.button == 2) c |= 2;
if(report.xbutton.button == 3) c |= 4;
return(-c);
+ case SelectionRequest:
+ if (WpeXInfo.selection)
+ {
+ se.type = SelectionNotify;
+ se.display = report.xselectionrequest.display;
+ se.requestor = report.xselectionrequest.requestor;
+ se.selection = report.xselectionrequest.selection;
+ se.time = report.xselectionrequest.time;
+ se.target = report.xselectionrequest.target;
+ if (report.xselectionrequest.property == None)
+ report.xselectionrequest.property = report.xselectionrequest.target;
+ /* Xt asks for TARGETS. Should probably support that. */
+ if (report.xselectionrequest.target == WpeXInfo.text_atom)
+ {
+ se.property = report.xselectionrequest.property;
+ XChangeProperty(se.display, se.requestor, se.property, se.target, 8,
+ PropModeReplace, WpeXInfo.selection, strlen(WpeXInfo.selection));
+ }
+ else
+ se.property = None;
+ XSendEvent(WpeXInfo.display, se.requestor, False, 0, (XEvent *)&se);
+ }
+ break;
+ case SelectionClear:
+ if (WpeXInfo.selection)
+ {
+ WpeFree(WpeXInfo.selection);
+ WpeXInfo.selection = NULL;
+ }
+ break;
default:
break;
- } }
+ }
+ }
return(0);
}
@@ -688,7 +725,7 @@
XComposeStatus compose;
int charcount;
unsigned char buffer[BUFSIZE];
- int c, root_x, root_y, x, y;
+ int c;
unsigned int key_b;
e_refresh();
@@ -697,8 +734,8 @@
return(0);
if(report.type == ButtonPress)
- { XQueryPointer(WpeXInfo.display, WpeXInfo.window, &tmp_root, &tmp_win,
- &root_x, &root_y, &x, &y, &key_b);
+ {
+ key_b = report.xbutton.state;
e_mouse.k = (key_b & ShiftMask) ? 3 : 0;
e_mouse.x = report.xbutton.x/WpeXInfo.font_width;
e_mouse.y = report.xbutton.y/WpeXInfo.font_height;
@@ -709,7 +746,8 @@
return(-c);
}
else
- { charcount = XLookupString(&report.xkey, buffer, BUFSIZE,
+ {
+ charcount = XLookupString(&report.xkey, buffer, BUFSIZE,
&keysym, &compose);
if(charcount == 1) return(*buffer);
else return(0);
@@ -881,7 +918,11 @@
BUFFER *b0 = f->ed->f[0]->b;
SCHIRM *s0 = f->ed->f[0]->s;
int i, j, k, n;
- char *str;
+ unsigned char *str;
+ XEvent report;
+ Atom type;
+ int format;
+ long nitems, bytes_left;
for(i = 1; i < b0->mxlines; i++)
FREE(b0->bf[i].s);
@@ -889,29 +930,62 @@
*(b0->bf[0].s) = WPE_WR;
*(b0->bf[0].s+1) = '\0';
b0->bf[0].len = 0;
+#if SELECTION
+ if (WpeXInfo.selection)
+ {
+ str = WpeStrdup(WpeXInfo.selection);
+ n = strlen(str);
+ }
+ else
+ {
+ /* Should check for errors especially failure to send SelectionNotify */
+ XConvertSelection(WpeXInfo.display, WpeXInfo.selection_atom,
+ WpeXInfo.text_atom, WpeXInfo.property_atom, WpeXInfo.window, CurrentTime);
+ while (!XCheckTypedEvent(WpeXInfo.display, SelectionNotify, &report))
+ ;
+ if (WpeXInfo.property_atom == None)
+ return 0;
+ XGetWindowProperty(WpeXInfo.display, WpeXInfo.window, WpeXInfo.property_atom,
+ 0, 1000000, FALSE, WpeXInfo.text_atom, &type, &format, &nitems, &bytes_left,
+ &str);
+ n = strlen(str);
+ }
+#else
str = XFetchBytes(WpeXInfo.display, &n);
+#endif
for(i = k = 0; i < n; i++, k++)
- { for(j = 0; i < n && str[i] != '\n' && j < b0->mx.x-1; j++, i++)
+ {
+ for (j = 0; i < n && str[i] != '\n' && j < b0->mx.x-1; j++, i++)
b0->bf[k].s[j] = str[i];
if(i < n)
- { e_new_line(k+1, b0);
+ {
+ e_new_line(k+1, b0);
if(str[i] == '\n')
- { b0->bf[k].s[j] = WPE_WR;
+ {
+ b0->bf[k].s[j] = WPE_WR;
b0->bf[k].nrc = j+1;
}
- else b0->bf[k].nrc = j;
+ else
+ b0->bf[k].nrc = j;
b0->bf[k].s[j+1] = '\0';
b0->bf[k].len = j;
}
else
- { b0->bf[k].s[j] = '\0';
+ {
+ b0->bf[k].s[j] = '\0';
b0->bf[k].nrc = b0->bf[k].len = j;
}
}
s0->mark_begin.x = s0->mark_begin.y = 0;
s0->mark_end.y = b0->mxlines-1;
s0->mark_end.x = b0->bf[b0->mxlines-1].len;
- return(0);
+#if SELECTION
+ if (WpeXInfo.selection)
+ WpeFree(str);
+ else
+#endif
+ XFree(str);
+ return 0;
}
int e_x_copy_X_buffer(FENSTER *f)
@@ -926,9 +1000,15 @@
BUFFER *b0 = f->ed->f[0]->b;
SCHIRM *s0 = f->ed->f[0]->s;
int i, j, n;
- char *str;
e_edt_copy(f);
+#if SELECTION
+ if (WpeXInfo.selection)
+ {
+ WpeFree(WpeXInfo.selection);
+ WpeXInfo.selection = NULL;
+ }
+#endif
if ((s0->mark_end.y == 0 && s0->mark_end.x == 0) ||
s0->mark_end.y < s0->mark_begin.y)
return(0);
@@ -937,24 +1017,40 @@
if (s0->mark_end.x < s0->mark_begin.x)
return(0);
n = s0->mark_end.x - s0->mark_begin.x;
+#if SELECTION
+ WpeXInfo.selection = WpeMalloc(n + 1);
+ strncpy(WpeXInfo.selection, b0->bf[s0->mark_begin.y].s+s0->mark_begin.x,
+ n);
+ WpeXInfo.selection[n] = 0;
+ XSetSelectionOwner(WpeXInfo.display, WpeXInfo.selection_atom,
+ WpeXInfo.window, CurrentTime);
+#else
XStoreBytes(WpeXInfo.display, b0->bf[s0->mark_begin.y].s+s0->mark_begin.x,
n);
+#endif
return(0);
}
- str = MALLOC(b0->bf[s0->mark_begin.y].nrc * sizeof(char));
+ WpeXInfo.selection = WpeMalloc(b0->bf[s0->mark_begin.y].nrc * sizeof(char));
for (n = 0, j = s0->mark_begin.x; j < b0->bf[s0->mark_begin.y].nrc; j++, n++)
- str[n] = b0->bf[s0->mark_begin.y].s[j];
+ WpeXInfo.selection[n] = b0->bf[s0->mark_begin.y].s[j];
for (i = s0->mark_begin.y+1; i < s0->mark_end.y; i++)
{
- str = REALLOC(str, (n + b0->bf[i].nrc)*sizeof(char));
+ WpeXInfo.selection = WpeRealloc(WpeXInfo.selection, (n + b0->bf[i].nrc)*sizeof(char));
for (j = 0; j < b0->bf[i].nrc; j++, n++)
- str[n] = b0->bf[i].s[j];
+ WpeXInfo.selection[n] = b0->bf[i].s[j];
}
- str = REALLOC(str, (n + s0->mark_end.x)*sizeof(char));
+ WpeXInfo.selection = WpeRealloc(WpeXInfo.selection, (n + s0->mark_end.x + 1)*sizeof(char));
for (j = 0; j < s0->mark_end.x; j++, n++)
- str[n] = b0->bf[i].s[j];
- XStoreBytes(WpeXInfo.display, str, n);
- FREE(str);
+ WpeXInfo.selection[n] = b0->bf[i].s[j];
+ WpeXInfo.selection[n] = 0;
+#if SELECTION
+ XSetSelectionOwner(WpeXInfo.display, WpeXInfo.selection_atom,
+ WpeXInfo.window, CurrentTime);
+#else
+ XStoreBytes(WpeXInfo.display, WpeXInfo.selection, n);
+ WpeFree(WpeXInfo.selection);
+ WpeXInfo.selection = NULL;
+#endif
return(0);
}