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
;
121 insert_selection(win
, prop
);
122 XDeleteProperty(ioncore_g
.dpy
, win
, prop
);
125 if(continuation_set
){
126 extl_unref_fn(continuation
);
127 continuation_set
=FALSE
;
132 void ioncore_clear_selection()
134 if(selection_data
!=NULL
){
135 free(selection_data
);
141 void ioncore_set_selection_n(const char *p
, int n
)
143 if(selection_data
!=NULL
)
144 free(selection_data
);
146 selection_data
=ALLOC_N(char, n
+1);
148 if(selection_data
==NULL
)
151 memcpy(selection_data
, p
, n
);
152 selection_data
[n
]='\0';
155 XSetSelectionOwner(ioncore_g
.dpy
, CLIPATOM(ioncore_g
.dpy
),
156 DefaultRootWindow(ioncore_g
.dpy
),
162 * Set primary selection and cutbuffer0 to \var{p}.
165 void ioncore_set_selection(const char *p
)
168 ioncore_clear_selection();
170 ioncore_set_selection_n(p
, strlen(p
));
174 void ioncore_request_selection_for(Window win
)
178 if(continuation_set
){
179 extl_unref_fn(continuation
);
180 continuation_set
=FALSE
;
184 a
=XA_COMPOUND_TEXT(ioncore_g
.dpy
);
186 XConvertSelection(ioncore_g
.dpy
, CLIPATOM(ioncore_g
.dpy
), a
,
187 ioncore_g
.atom_selection
, win
, CurrentTime
);
192 * Request (string) selection. The function \var{fn} will be called
193 * with the selection when and if it is received.
196 void ioncore_request_selection(ExtlFn fn
)
198 assert(ioncore_g
.rootwins
!=NULL
);
199 ioncore_request_selection_for(ioncore_g
.rootwins
->dummy_win
);
200 continuation
=extl_ref_fn(fn
);
201 continuation_set
=TRUE
;