11 typedef struct W_SelectionHandler
{
15 WMSelectionProc
*proc
;
17 W_SelectionHandler
*next
;
18 W_SelectionHandler
*prev
;
22 #define SELECTION_TIMEOUT 2000
23 #define MAX_PROPERTY_SIZE 10*1024
28 WMWriteSelectionToClipboard(WMSelection
*selection
)
34 WMCreateSelectionWithData(WMData
*data
, Atom type
)
42 #define MAX_PROPERTY_SIZE 100*1024
46 handleSelectionEvent(XEvent
*event
, void *data
)
48 W_SelectionHandler
*handler
= (W_SelectionHandler
*)data
;
52 unsigned long numItems
, bytesAfter
;
53 WMScreen
*scr
= WMWidgetScreen(handler
->widget
);
55 WMDeleteTimerHandler(handler
->timerID
);
58 handler
->next
->prev
= handler
->prev
;
60 handler
->prev
->next
= handler
->next
;
61 if (handler
== WMWidgetScreen(handler
->widget
)->selectionHandlerList
)
62 WMWidgetScreen(handler
->widget
)->selectionHandlerList
= handler
->next
;
64 if (event
->xselection
.property
== None
) {
65 char *name
= XGetAtomName(event
->xselection
.display
,
67 char *form
= XGetAtomName(event
->xselection
.display
, handler
->type
);
68 wwarning("error retrieving selection %s with form %s\n", name
, form
);
77 if (XGetWindowProperty(event
->xselection
.display
,
78 event
->xselection
.requestor
, handler
->property
,
79 0, MAX_PROPERTY_SIZE
, False
, AnyPropertyType
,
80 &type
, &format
, &numItems
, &bytesAfter
,
81 &data
) != Success
|| type
== None
) {
88 wwarning("data in selection is too large");
94 if (type
== XA_STRING
|| type
== scr
->compoundTextAtom
) {
96 wwarning("string in selection has format %i, which is invalid",
109 timeoutHandler(void *data
)
111 W_SelectionHandler
*handler
= (W_SelectionHandler
*)data
;
113 wwarning("selection timed out");
114 WMDeleteEventHandler(WMWidgetView(handler
->widget
), SelectionNotifyMask
,
115 handleSelectionEvent
, data
);
117 handler
->next
->prev
= handler
->prev
;
119 handler
->prev
->next
= handler
->next
;
120 if (handler
== WMWidgetScreen(handler
->widget
)->selectionHandlerList
)
121 WMWidgetScreen(handler
->widget
)->selectionHandlerList
= handler
->next
;
127 WMGetSelection(WMWidget
*widget
, Atom selection
, Atom type
, Atom property
,
128 WMSelectionProc
*proc
, void *clientData
, Time time
)
130 WMScreen
*scr
= WMWidgetScreen(widget
);
134 unsigned long len
, bytes
;
168 data
= XFetchBuffer(scr
->display
, &size
, buffer
);
171 W_SelectionHandler
*handler
;
173 XDeleteProperty(scr
->display
, WMWidgetXID(widget
), selection
);
174 XConvertSelection(scr
->display
, selection
, type
, property
,
175 WMWidgetXID(widget
), time
);
177 handler
= wmalloc(sizeof(W_SelectionHandler
));
178 handler
->widget
= widget
;
179 handler
->selection
= selection
;
180 handler
->type
= type
;
181 handler
->property
= property
;
182 handler
->clientData
= clientData
;
183 handler
->proc
= proc
;
184 handler
->timerID
= WMAddTimerHandler(SELECTION_TIMEOUT
,
185 timeoutHandler
, handler
);
187 handler
->next
= scr
->selectionHandlerList
;
188 handler
->prev
= NULL
;
189 if (scr
->selectionHandlerList
)
190 scr
->selectionHandlerList
->prev
= handler
;
191 scr
->selectionHandlerList
= handler
;
193 WMCreateEventHandler(WMWidgetView(widget
), SelectionNotifyMask
,
194 handleSelectionEvent
, handler
);
203 timeoutHandler(void *data
)
210 W_GetTextSelection(WMScreen
*scr
, Atom selection
)
244 data
= XFetchBuffer(scr
->display
, &size
, buffer
);
251 unsigned long len
, bytes
;
256 XDeleteProperty(scr
->display
, scr
->groupLeader
, scr
->clipboardAtom
);
257 XConvertSelection(scr
->display
, selection
, XA_STRING
,
258 scr
->clipboardAtom
, scr
->groupLeader
,
261 timer
= WMAddTimerHandler(1000, timeoutHandler
, &timeout
);
263 while (!XCheckTypedWindowEvent(scr
->display
, scr
->groupLeader
,
264 SelectionNotify
, &ev
) && !timeout
);
267 WMDeleteTimerHandler(timer
);
269 wwarning("selection retrieval timed out");
273 /* nobody owns the selection */
274 if (ev
.xselection
.property
== None
) {
278 if (XGetWindowProperty(scr
->display
, scr
->groupLeader
,
279 scr
->clipboardAtom
, 0, MAX_PROPERTY_SIZE
,
280 False
, XA_STRING
, &rtype
, &bits
, &len
,
281 &bytes
, &data
)!=Success
) {
284 if (rtype
!=XA_STRING
|| bits
!=8) {
285 wwarning("invalid data in text selection");