1 ////////////////////////////////////////////////////////////////////////////////
3 static void xfixsel (void) {
4 if (lastSelStr
!= NULL
) {
5 XSetSelectionOwner(xw
.dpy
, XA_PRIMARY
, xw
.win
, CurrentTime
);
6 XSetSelectionOwner(xw
.dpy
, XA_CLIPBOARD
, xw
.win
, CurrentTime
);
8 if (XGetSelectionOwner(xw
.dpy
, XA_PRIMARY
) == xw
.win
) XSetSelectionOwner(xw
.dpy
, XA_PRIMARY
, None
, CurrentTime
);
9 if (XGetSelectionOwner(xw
.dpy
, XA_CLIPBOARD
) == xw
.win
) XSetSelectionOwner(xw
.dpy
, XA_CLIPBOARD
, None
, CurrentTime
);
15 static void xevtcbselclear (XEvent
*e
) {
16 k8t_selClear(curterm
);
20 static void xevtcbselnotify (XEvent
*e
) {
21 unsigned long nitems
, ofs
, rem
;
25 XSelectionEvent
*se
= (XSelectionEvent
*)e
;
31 if (curterm
== NULL
|| K8T_DATA(curterm
)->cmdline
.cmdMode
== K8T_CMDMODE_MESSAGE
) return;
32 #ifdef PASTE_SELECTION_DEBUG
36 fprintf(stderr
, "selnotify!\n");
38 name
= se
->selection
!= None
? XGetAtomName(se
->display
, se
->selection
) : NULL
;
39 fprintf(stderr
, " selection: [%s]\n", name
);
40 if (name
!= NULL
) XFree(name
);
42 name
= se
->target
!= None
? XGetAtomName(se
->display
, se
->target
) : NULL
;
43 fprintf(stderr
, " target: [%s]\n", name
);
44 if (name
!= NULL
) XFree(name
);
46 name
= se
->property
!= None
? XGetAtomName(se
->display
, se
->property
) : NULL
;
47 fprintf(stderr
, " property: [%s]\n", name
);
48 if (name
!= NULL
) XFree(name
);
52 if (se
->property
!= XA_VT_SELECTION
) return;
54 #ifdef PASTE_SELECTION_DEBUG
56 fprintf(stderr
, "selection:\n");
57 fprintf(stderr
, " primary: %d\n", se
->selection
== XA_PRIMARY
);
58 fprintf(stderr
, " secondary: %d\n", se
->selection
== XA_SECONDARY
);
59 fprintf(stderr
, " clipboard: %d\n", se
->selection
== XA_CLIPBOARD
);
60 fprintf(stderr
, " vtsel: %d\n", se
->selection
== XA_VT_SELECTION
);
61 fprintf(stderr
, "target:\n");
62 fprintf(stderr
, " primary: %d\n", se
->target
== XA_PRIMARY
);
63 fprintf(stderr
, " secondary: %d\n", se
->target
== XA_SECONDARY
);
64 fprintf(stderr
, " clipboard: %d\n", se
->target
== XA_CLIPBOARD
);
65 fprintf(stderr
, " vtsel: %d\n", se
->target
== XA_VT_SELECTION
);
68 if (se
->target
== XA_UTF8
) {
70 } else if (se
->target
== XA_STRING
) {
72 } else if (se
->target
== XA_TARGETS
) {
73 Atom rqtype
= None
, *targ
;
75 if (XGetWindowProperty(xw
.dpy
, xw
.win
, se
->property
, 0, 65536, False
, XA_ATOM
, &type
, &format
, &nitems
, &rem
, &data
)) {
76 //fprintf(stderr, "no targets\n");
79 for (targ
= (Atom
*)data
; nitems
> 0; --nitems
, ++targ
) {
80 #ifdef PASTE_SELECTION_DEBUG
81 fprintf(stderr
, " TGT: [%s]\n", XGetAtomName(se
->display
, *targ
));
83 if (*targ
== XA_UTF8
) rqtype
= XA_UTF8
;
84 else if (*targ
== XA_STRING
&& rqtype
== None
) rqtype
= XA_STRING
;
88 if (rqtype
!= None
) XConvertSelection(xw
.dpy
, se
->selection
, rqtype
, XA_VT_SELECTION
, xw
.win
, CurrentTime
);
99 if (XGetWindowProperty(xw
.dpy
, xw
.win
, se
->property
, ofs
, BUFSIZ
/4, False
, AnyPropertyType
, &type
, &format
, &nitems
, &rem
, &data
)) {
100 fprintf(stderr
, "Clipboard allocation failed\n");
103 //fprintf(stderr, "nitems=%d; format=%d; rem=%d\n", (int)nitems, format, (int)rem);
104 blen
= nitems
*format
/8;
107 int newsz
= blen
*4+64;
109 if (ucbufsize
< newsz
) {
110 char *n
= realloc(ucbuf
, newsz
);
112 if (n
== NULL
) { XFree(data
); break; }
117 blen
= loc2utf(ucbuf
, (const char *)data
, blen
);
123 if (K8T_DATA(curterm
)->cmdline
.cmdMode
!= K8T_CMDMODE_NONE
) {
124 tcmdput(curterm
, &K8T_DATA(curterm
)->cmdline
, str
, blen
);
126 if (nitems
*format
/8 > 0 && !wasbrk
&& K8T_ISSET(curterm
, K8T_MODE_BRACPASTE
)) {
128 k8t_ttyWriteStrNoEnc(curterm
, "\x1b[200~");
130 k8t_ttyWrite(curterm
, str
, blen
);
133 /* number of 32-bit chunks returned */
134 ofs
+= nitems
*format
/32;
137 if (wasbrk
) k8t_ttyWriteStrNoEnc(curterm
, "\x1b[201~");
138 if (ucbuf
!= NULL
) free(ucbuf
);
142 static void selpaste (K8Term
*term
, Atom which
) {
143 if (term
== NULL
) return;
144 if (XGetSelectionOwner(xw
.dpy
, which
) == None
) return;
145 //XConvertSelection(xw.dpy, which, term->sel.xtarget, XA_VT_SELECTION, xw.win, CurrentTime);
146 XConvertSelection(xw
.dpy
, which
, XA_TARGETS
, XA_VT_SELECTION
, xw
.win
, CurrentTime
);
148 if (which == XA_PRIMARY) selpaste(XA_SECONDARY);
149 else if (which == XA_SECONDARY) selpaste(XA_CLIPBOARD);
154 static void xevtcbselrequest (XEvent
*e
) {
155 XSelectionRequestEvent
*xsre
;
158 if (lastSelStr
== NULL
) return;
159 xsre
= (XSelectionRequestEvent
*)e
;
160 xev
.type
= SelectionNotify
;
161 xev
.requestor
= xsre
->requestor
;
162 xev
.selection
= xsre
->selection
;
163 xev
.target
= xsre
->target
;
164 xev
.time
= xsre
->time
;
167 if (xsre
->target
== XA_TARGETS
) {
168 /* respond with the supported type */
169 Atom tlist
[3] = {XA_UTF8
, XA_STRING
, XA_TARGETS
};
171 XChangeProperty(xsre
->display
, xsre
->requestor
, xsre
->property
, XA_ATOM
, 32, PropModeReplace
, (uint8_t *)tlist
, 3);
172 xev
.property
= xsre
->property
;
173 } else if (xsre
->target
== XA_UTF8
&& lastSelStr
!= NULL
) {
174 XChangeProperty(xsre
->display
, xsre
->requestor
, xsre
->property
, XA_UTF8
, 8, PropModeReplace
, (uint8_t *)lastSelStr
, strlen(lastSelStr
));
175 xev
.property
= xsre
->property
;
176 } else if (xsre
->target
== XA_STRING
&& lastSelStr
!= NULL
) {
177 char *s
= malloc(strlen(lastSelStr
)*4+8);
180 int len
= utf2loc(s
, lastSelStr
, strlen(lastSelStr
));
182 XChangeProperty(xsre
->display
, xsre
->requestor
, xsre
->property
, XA_STRING
, 8, PropModeReplace
, (uint8_t *)s
, len
);
183 xev
.property
= xsre
->property
;
187 /* all done, send a notification to the listener */
188 if (!XSendEvent(xsre
->display
, xsre
->requestor
, True
, 0, (XEvent
*)&xev
)) fprintf(stderr
, "Error sending SelectionNotify event\n");