Initial revision
[wmaker-crm.git] / WINGs / selection.c
blob0515ca62c146322337a8125f3bd30e0a78078e6f
3 #include <stdlib.h>
5 #include <X11/Xatom.h>
7 #include "WINGsP.h"
9 #if 0
11 typedef struct W_SelectionHandler {
12 WMWidget *widget;
13 Atom selection;
14 void *clientData;
15 WMSelectionProc *proc;
16 WMHandlerID timerID;
17 W_SelectionHandler *next;
18 W_SelectionHandler *prev;
19 } W_SelectionHandler;
20 #endif
22 #define SELECTION_TIMEOUT 2000
23 #define MAX_PROPERTY_SIZE 10*1024
24 #if 0
27 void
28 WMWriteSelectionToClipboard(WMSelection *selection)
33 WMSelection*
34 WMCreateSelectionWithData(WMData *data, Atom type)
38 #endif
40 #if 0
42 #define MAX_PROPERTY_SIZE 100*1024
45 static void
46 handleSelectionEvent(XEvent *event, void *data)
48 W_SelectionHandler *handler = (W_SelectionHandler*)data;
49 char *data = NULL;
50 Atom type;
51 int format, result;
52 unsigned long numItems, bytesAfter;
53 WMScreen *scr = WMWidgetScreen(handler->widget);
55 WMDeleteTimerHandler(handler->timerID);
57 if (handler->next)
58 handler->next->prev = handler->prev;
59 if (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,
66 handler->selection);
67 char *form = XGetAtomName(event->xselection.display, handler->type);
68 wwarning("error retrieving selection %s with form %s\n", name, form);
69 if (name)
70 XFree(name);
71 if (form)
72 XFree(form);
73 free(handler);
74 return;
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) {
82 if (data)
83 XFree(data);
84 free(handler);
85 return;
87 if (bytesAfter!=0) {
88 wwarning("data in selection is too large");
89 if (data)
90 XFree(data);
91 free(handler);
92 return;
94 if (type == XA_STRING || type == scr->compoundTextAtom) {
95 if (format!=8) {
96 wwarning("string in selection has format %i, which is invalid",
97 format);
98 if (data)
99 XFree(data);
100 free(handler);
101 return;
103 (*handler->proc)();
108 static void
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);
116 if (handler->next)
117 handler->next->prev = handler->prev;
118 if (handler->prev)
119 handler->prev->next = handler->next;
120 if (handler == WMWidgetScreen(handler->widget)->selectionHandlerList)
121 WMWidgetScreen(handler->widget)->selectionHandlerList = handler->next;
126 void
127 WMGetSelection(WMWidget *widget, Atom selection, Atom type, Atom property,
128 WMSelectionProc *proc, void *clientData, Time time)
130 WMScreen *scr = WMWidgetScreen(widget);
131 void *data;
132 Atom rtype;
133 int bits;
134 unsigned long len, bytes;
135 unsigned char *data;
136 int buffer = -1;
138 switch (selection) {
139 case XA_CUT_BUFFER0:
140 buffer = 0;
141 break;
142 case XA_CUT_BUFFER1:
143 buffer = 1;
144 break;
145 case XA_CUT_BUFFER2:
146 buffer = 2;
147 break;
148 case XA_CUT_BUFFER3:
149 buffer = 3;
150 break;
151 case XA_CUT_BUFFER4:
152 buffer = 4;
153 break;
154 case XA_CUT_BUFFER5:
155 buffer = 5;
156 break;
157 case XA_CUT_BUFFER6:
158 buffer = 6;
159 break;
160 case XA_CUT_BUFFER7:
161 buffer = 7;
162 break;
164 if (buffer >= 0) {
165 char *data;
166 int size;
168 data = XFetchBuffer(scr->display, &size, buffer);
170 } else {
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);
198 #endif
202 static void
203 timeoutHandler(void *data)
205 *(int*)data = 1;
209 char*
210 W_GetTextSelection(WMScreen *scr, Atom selection)
212 int buffer = -1;
214 switch (selection) {
215 case XA_CUT_BUFFER0:
216 buffer = 0;
217 break;
218 case XA_CUT_BUFFER1:
219 buffer = 1;
220 break;
221 case XA_CUT_BUFFER2:
222 buffer = 2;
223 break;
224 case XA_CUT_BUFFER3:
225 buffer = 3;
226 break;
227 case XA_CUT_BUFFER4:
228 buffer = 4;
229 break;
230 case XA_CUT_BUFFER5:
231 buffer = 5;
232 break;
233 case XA_CUT_BUFFER6:
234 buffer = 6;
235 break;
236 case XA_CUT_BUFFER7:
237 buffer = 7;
238 break;
240 if (buffer >= 0) {
241 char *data;
242 int size;
244 data = XFetchBuffer(scr->display, &size, buffer);
246 return data;
247 } else {
248 unsigned char *data;
249 int bits;
250 Atom rtype;
251 unsigned long len, bytes;
252 WMHandlerID timer;
253 int timeout = 0;
254 XEvent ev;
256 XDeleteProperty(scr->display, scr->groupLeader, scr->clipboardAtom);
257 XConvertSelection(scr->display, selection, XA_STRING,
258 scr->clipboardAtom, scr->groupLeader,
259 scr->lastEventTime);
261 timer = WMAddTimerHandler(1000, timeoutHandler, &timeout);
263 while (!XCheckTypedWindowEvent(scr->display, scr->groupLeader,
264 SelectionNotify, &ev) && !timeout);
266 if (!timeout) {
267 WMDeleteTimerHandler(timer);
268 } else {
269 wwarning("selection retrieval timed out");
270 return NULL;
273 /* nobody owns the selection */
274 if (ev.xselection.property == None) {
275 return NULL;
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) {
282 return NULL;
284 if (rtype!=XA_STRING || bits!=8) {
285 wwarning("invalid data in text selection");
286 if (data)
287 XFree(data);
288 return NULL;
290 return data;