2 * ion/ioncore/selection.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
16 #include <libextl/extl.h>
19 static char *selection_data
=NULL
;
20 static int selection_length
;
21 static bool continuation_set
=FALSE
;
22 static ExtlFn continuation
;
24 #define CLIPATOM(X) XA_PRIMARY
26 static Atom
XA_COMPOUND_TEXT(Display
*unused
)
31 a
=XInternAtom(ioncore_g
.dpy
, "COMPOUND_TEXT", False
);
37 void ioncore_handle_selection_request(XSelectionRequestEvent
*ev
)
46 if(selection_data
==NULL
|| ev
->property
==None
)
51 if(!ioncore_g
.use_mb
&& ev
->target
==XA_STRING
){
52 Status st
=XStringListToTextProperty((char **)p
, 1, &prop
);
54 }else if(ioncore_g
.use_mb
){
55 XICCEncodingStyle style
;
57 if(ev
->target
==XA_STRING
){
60 }else if(ev
->target
==XA_COMPOUND_TEXT(ioncore_g
.dpy
)){
61 style
=XCompoundTextStyle
;
66 int st
=XmbTextListToTextProperty(ioncore_g
.dpy
, (char **)p
, 1,
73 XSetTextProperty(ioncore_g
.dpy
, ev
->requestor
, &prop
, ev
->property
);
74 sev
.property
=ev
->property
;
79 sev
.type
=SelectionNotify
;
80 sev
.requestor
=ev
->requestor
;
81 sev
.selection
=ev
->selection
;
82 sev
.target
=ev
->target
;
84 XSendEvent(ioncore_g
.dpy
, ev
->requestor
, False
, 0L, (XEvent
*)&sev
);
88 static void ins(Window win
, const char *str
, int n
)
90 if(!continuation_set
){
91 WWindow
*wwin
=XWINDOW_REGION_OF_T(win
, WWindow
);
93 window_insstr(wwin
, str
, n
);
95 char *tmp
=scopyn(str
, n
);
97 extl_call(continuation
, "s", NULL
, tmp
);
104 static void insert_selection(Window win
, Atom prop
)
106 char **p
=xwindow_get_text_property(win
, prop
, NULL
);
108 ins(win
, p
[0], strlen(p
[0]));
114 void ioncore_handle_selection(XSelectionEvent
*ev
)
116 Atom prop
=ev
->property
;
117 Window win
=ev
->requestor
;
120 insert_selection(win
, prop
);
121 XDeleteProperty(ioncore_g
.dpy
, win
, prop
);
124 if(continuation_set
){
125 extl_unref_fn(continuation
);
126 continuation_set
=FALSE
;
131 void ioncore_clear_selection()
133 if(selection_data
!=NULL
){
134 free(selection_data
);
140 void ioncore_set_selection_n(const char *p
, int n
)
142 if(selection_data
!=NULL
)
143 free(selection_data
);
145 selection_data
=ALLOC_N(char, n
+1);
147 if(selection_data
==NULL
)
150 memcpy(selection_data
, p
, n
);
151 selection_data
[n
]='\0';
154 XSetSelectionOwner(ioncore_g
.dpy
, CLIPATOM(ioncore_g
.dpy
),
155 DefaultRootWindow(ioncore_g
.dpy
),
161 * Set primary selection and cutbuffer0 to \var{p}.
164 void ioncore_set_selection(const char *p
)
167 ioncore_clear_selection();
169 ioncore_set_selection_n(p
, strlen(p
));
173 void ioncore_request_selection_for(Window win
)
177 if(continuation_set
){
178 extl_unref_fn(continuation
);
179 continuation_set
=FALSE
;
183 a
=XA_COMPOUND_TEXT(ioncore_g
.dpy
);
185 XConvertSelection(ioncore_g
.dpy
, CLIPATOM(ioncore_g
.dpy
), a
,
186 ioncore_g
.atom_selection
, win
, CurrentTime
);
191 * Request (string) selection. The function \var{fn} will be called
192 * with the selection when and if it is received.
195 void ioncore_request_selection(ExtlFn fn
)
197 assert(ioncore_g
.rootwins
!=NULL
);
198 ioncore_request_selection_for(ioncore_g
.rootwins
->dummy_win
);
199 continuation
=extl_ref_fn(fn
);
200 continuation_set
=TRUE
;