Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / selection.c
dissimilarity index 95%
index 2f95548..ce93d22 100644 (file)
-
-
-#include <stdlib.h>
-
-#include <X11/Xatom.h>
-
-#include "WINGsP.h"
-
-#define MAX_PROPERTY_SIZE 8*1024
-
-
-char *WMSelectionOwnerDidChangeNotification = "WMSelectionOwnerDidChange";
-
-
-typedef struct SelectionHandler {
-    WMView *view;
-    Atom selection;
-    Time timestamp;
-    WMSelectionProcs procs;
-    void *data;
-
-    struct {
-        unsigned delete_pending:1;
-        unsigned done_pending:1;
-    } flags;
-} SelectionHandler;
-
-
-typedef struct SelectionCallback {
-    WMView *view;
-    Atom selection;
-    Atom target;
-    Time timestamp;
-    WMSelectionCallback *callback;
-    void *data;
-
-    struct {
-        unsigned delete_pending:1;
-        unsigned done_pending:1;
-    } flags;
-} SelectionCallback;
-
-
-
-static WMArray *selCallbacks = NULL;
-
-static WMArray *selHandlers = NULL;
-
-static Bool gotXError = False;
-
-
-
-
-void
-WMDeleteSelectionHandler(WMView *view, Atom selection, Time timestamp)
-{
-    SelectionHandler *handler;
-    Display *dpy = W_VIEW_SCREEN(view)->display;
-    Window win = W_VIEW_DRAWABLE(view);
-    WMArrayIterator iter;
-
-    if (!selHandlers)
-        return;
-
-    /*//printf("deleting selection handler for %d", win);*/
-
-    WM_ITERATE_ARRAY(selHandlers, handler, iter) {
-        if (handler->view == view
-            && (handler->selection == selection || selection == None)
-            && (handler->timestamp == timestamp || timestamp == CurrentTime)) {
-
-            if (handler->flags.done_pending) {
-                handler->flags.delete_pending = 1;
-                /*//puts(": postponed because still pending");*/
-                return;
-            }
-            /*//printf(": found & removed");*/
-            WMRemoveFromArray(selHandlers, handler);
-            break;
-        }
-    }
-
-    /*//printf("\n");*/
-
-    XGrabServer(dpy);
-    if (XGetSelectionOwner(dpy, selection) == win) {
-        XSetSelectionOwner(dpy, selection, None, timestamp);
-    }
-    XUngrabServer(dpy);
-}
-
-
-
-void
-WMDeleteSelectionCallback(WMView *view, Atom selection, Time timestamp)
-{
-    SelectionCallback *handler;
-    WMArrayIterator iter;
-
-    if (!selCallbacks)
-        return;
-
-    WM_ITERATE_ARRAY(selCallbacks, handler, iter) {
-        if (handler->view == view
-            && (handler->selection == selection || selection == None)
-            && (handler->timestamp == timestamp || timestamp == CurrentTime)) {
-
-            if (handler->flags.done_pending) {
-                handler->flags.delete_pending = 1;
-                return;
-            }
-            WMRemoveFromArray(selCallbacks, handler);
-            break;
-        }
-    }
-}
-
-
-static int
-handleXError(Display *dpy, XErrorEvent *ev)
-{
-    gotXError = True;
-
-    return 1;
-}
-
-
-static Bool
-writeSelection(Display *dpy, Window requestor, Atom property, Atom type,
-               WMData *data)
-{
-    static void *oldHandler;
-    int format, bpi;
-
-    format = WMGetDataFormat(data);
-    if (format == 0)
-        format = 8;
-
-    bpi = format/8;
-
-    /* printf("write to %x: %s\n", requestor, XGetAtomName(dpy, property)); */
-
-    oldHandler = XSetErrorHandler(handleXError);
-
-    gotXError = False;
-
-    XChangeProperty(dpy, requestor, property, type, format, PropModeReplace,
-                    WMDataBytes(data), WMGetDataLength(data)/bpi);
-
-    XFlush(dpy);
-
-    XSetErrorHandler(oldHandler);
-
-    return !gotXError;
-}
-
-
-static void
-notifySelection(XEvent *event, Atom prop)
-{
-    XEvent ev;
-
-    /* printf("event to %x\n", event->xselectionrequest.requestor); */
-
-    ev.xselection.type = SelectionNotify;
-    ev.xselection.serial = 0;
-    ev.xselection.send_event = True;
-    ev.xselection.display = event->xselectionrequest.display;
-    ev.xselection.requestor = event->xselectionrequest.requestor;
-    ev.xselection.target = event->xselectionrequest.target;
-    ev.xselection.selection = event->xselectionrequest.selection;
-    ev.xselection.property = prop;
-    ev.xselection.time = event->xselectionrequest.time;
-
-    XSendEvent(event->xany.display, event->xselectionrequest.requestor,
-               False, 0, &ev);
-    XFlush(event->xany.display);
-}
-
-
-static void
-handleRequestEvent(XEvent *event)
-{
-    SelectionHandler *handler;
-    WMArrayIterator iter;
-    WMArray *copy;
-    Bool handledRequest;
-
-    WM_ITERATE_ARRAY(selHandlers, handler, iter) {
-
-        switch (event->type) {
-        case SelectionClear:
-            if (W_VIEW_DRAWABLE(handler->view)
-                != event->xselectionclear.window) {
-                break;
-            }
-
-            handler->flags.done_pending = 1;
-            if (handler->procs.selectionLost)
-                handler->procs.selectionLost(handler->view,
-                                             handler->selection,
-                                             handler->data);
-            handler->flags.done_pending = 0;
-            handler->flags.delete_pending = 1;
-            break;
-
-        case SelectionRequest:
-            if (W_VIEW_DRAWABLE(handler->view)!=event->xselectionrequest.owner) {
-                break;
-            }
-
-            if (handler->procs.convertSelection != NULL
-                && handler->selection == event->xselectionrequest.selection) {
-                Atom atom;
-                WMData *data;
-                Atom prop;
-
-                /* they're requesting for something old.. maybe another handler
-                 * can handle it */
-                if (event->xselectionrequest.time < handler->timestamp
-                    && event->xselectionrequest.time != CurrentTime) {
-                    break;
-                }
-
-                handledRequest = False;
-
-                handler->flags.done_pending = 1;
-
-                data = handler->procs.convertSelection(handler->view,
-                                                       handler->selection,
-                                                       event->xselectionrequest.target,
-                                                       handler->data,
-                                                       &atom);
-
-                prop = event->xselectionrequest.property;
-                /* obsolete clients that don't set the property field */
-                if (prop == None)
-                    prop = event->xselectionrequest.target;
-
-                if (data) {
-                    if (writeSelection(event->xselectionrequest.display,
-                                       event->xselectionrequest.requestor,
-                                       prop, atom, data)) {
-                        handledRequest = True;
-                    }
-                    WMReleaseData(data);
-                }
-
-                notifySelection(event, (handledRequest==True ? prop : None));
-
-                if (handler->procs.selectionDone != NULL) {
-                    handler->procs.selectionDone(handler->view,
-                                                 handler->selection,
-                                                 event->xselectionrequest.target,
-                                                 handler->data);
-                }
-
-                handler->flags.done_pending = 0;
-            }
-            break;
-        }
-    }
-
-    /* delete handlers */
-    copy = WMDuplicateArray(selHandlers);
-    WM_ITERATE_ARRAY(copy, handler, iter) {
-        if (handler && handler->flags.delete_pending) {
-            WMDeleteSelectionHandler(handler->view, handler->selection,
-                                     handler->timestamp);
-        }
-    }
-    WMFreeArray(copy);
-}
-
-
-static WMData*
-getSelectionData(Display *dpy, Window win, Atom where)
-{
-    WMData *wdata;
-    unsigned char *data;
-    Atom rtype;
-    int bits, bpi;
-    unsigned long len, bytes;
-
-
-    if (XGetWindowProperty(dpy, win, where, 0, MAX_PROPERTY_SIZE,
-                           False, AnyPropertyType, &rtype, &bits, &len,
-                           &bytes, &data)!=Success) {
-        return NULL;
-    }
-
-    bpi = bits/8;
-
-    wdata = WMCreateDataWithBytesNoCopy(data, len*bpi, (WMFreeDataProc*)XFree);
-    WMSetDataFormat(wdata, bits);
-
-    return wdata;
-}
-
-
-static void
-handleNotifyEvent(XEvent *event)
-{
-    SelectionCallback *handler;
-    WMArrayIterator iter;
-    WMArray *copy;
-    WMData *data;
-
-    WM_ITERATE_ARRAY(selCallbacks, handler, iter) {
-
-        if (W_VIEW_DRAWABLE(handler->view) != event->xselection.requestor
-            || handler->selection != event->xselection.selection) {
-            continue;
-        }
-        handler->flags.done_pending = 1;
-
-        if (event->xselection.property == None) {
-            data = NULL;
-        } else {
-            data = getSelectionData(event->xselection.display,
-                                    event->xselection.requestor,
-                                    event->xselection.property);
-        }
-
-        (*handler->callback)(handler->view, handler->selection,
-                             handler->target, handler->timestamp,
-                             handler->data, data);
-
-        if (data != NULL) {
-            WMReleaseData(data);
-        }
-        handler->flags.done_pending = 0;
-        handler->flags.delete_pending = 1;
-    }
-
-    /* delete callbacks */
-    copy = WMDuplicateArray(selCallbacks);
-    WM_ITERATE_ARRAY(copy, handler, iter) {
-        if (handler && handler->flags.delete_pending) {
-            WMDeleteSelectionCallback(handler->view, handler->selection,
-                                      handler->timestamp);
-        }
-    }
-    WMFreeArray(copy);
-}
-
-
-
-void
-W_HandleSelectionEvent(XEvent *event)
-{
-    /*//printf("%d received selection ", event->xany.window);*/
-    /*//switch(event->type) {
-     case SelectionNotify:
-     puts("notify"); break;
-     case SelectionRequest:
-     puts("request"); break;
-     case SelectionClear:
-     puts("clear"); break;
-     default:
-     puts("unknown"); break;
-     }*/
-
-    if (event->type == SelectionNotify) {
-        handleNotifyEvent(event);
-    } else {
-        handleRequestEvent(event);
-    }
-}
-
-
-
-Bool
-WMCreateSelectionHandler(WMView *view, Atom selection, Time timestamp,
-                         WMSelectionProcs *procs, void *cdata)
-{
-    SelectionHandler *handler;
-    Display *dpy = W_VIEW_SCREEN(view)->display;
-
-    XSetSelectionOwner(dpy, selection, W_VIEW_DRAWABLE(view), timestamp);
-    if (XGetSelectionOwner(dpy, selection) != W_VIEW_DRAWABLE(view)) {
-        return False;
-    }
-
-    WMPostNotificationName(WMSelectionOwnerDidChangeNotification,
-                           (void*)selection, (void*)view);
-
-    /*//printf("created selection handler for %d\n", W_VIEW_DRAWABLE(view));*/
-
-    handler = wmalloc(sizeof(SelectionHandler));
-
-    handler->view = view;
-    handler->selection = selection;
-    handler->timestamp = timestamp;
-    handler->procs = *procs;
-    handler->data = cdata;
-    memset(&handler->flags, 0, sizeof(handler->flags));
-
-    if (selHandlers == NULL) {
-        selHandlers = WMCreateArrayWithDestructor(4, wfree);
-    }
-
-    WMAddToArray(selHandlers, handler);
-
-    return True;
-}
-
-
-
-Bool
-WMRequestSelection(WMView *view, Atom selection, Atom target, Time timestamp,
-                   WMSelectionCallback *callback, void *cdata)
-{
-    SelectionCallback *handler;
-
-    if (XGetSelectionOwner(W_VIEW_SCREEN(view)->display, selection) == None)
-        return False;
-
-    if (!XConvertSelection(W_VIEW_SCREEN(view)->display, selection, target,
-                           W_VIEW_SCREEN(view)->clipboardAtom,
-                           W_VIEW_DRAWABLE(view), timestamp)) {
-        return False;
-    }
-
-    handler = wmalloc(sizeof(SelectionCallback));
-
-    handler->view = view;
-    handler->selection = selection;
-    handler->target = target;
-    handler->timestamp = timestamp;
-    handler->callback = callback;
-    handler->data = cdata;
-    memset(&handler->flags, 0, sizeof(handler->flags));
-
-    if (selCallbacks == NULL) {
-        selCallbacks = WMCreateArrayWithDestructor(4, wfree);
-    }
-
-    WMAddToArray(selCallbacks, handler);
-
-    return True;
-}
-
+
+#include <stdlib.h>
+
+#include <X11/Xatom.h>
+
+#include "WINGsP.h"
+
+#define MAX_PROPERTY_SIZE 8*1024
+
+char *WMSelectionOwnerDidChangeNotification = "WMSelectionOwnerDidChange";
+
+typedef struct SelectionHandler {
+       WMView *view;
+       Atom selection;
+       Time timestamp;
+       WMSelectionProcs procs;
+       void *data;
+
+       struct {
+               unsigned delete_pending:1;
+               unsigned done_pending:1;
+       } flags;
+} SelectionHandler;
+
+typedef struct SelectionCallback {
+       WMView *view;
+       Atom selection;
+       Atom target;
+       Time timestamp;
+       WMSelectionCallback *callback;
+       void *data;
+
+       struct {
+               unsigned delete_pending:1;
+               unsigned done_pending:1;
+       } flags;
+} SelectionCallback;
+
+static WMArray *selCallbacks = NULL;
+
+static WMArray *selHandlers = NULL;
+
+static Bool gotXError = False;
+
+void WMDeleteSelectionHandler(WMView * view, Atom selection, Time timestamp)
+{
+       SelectionHandler *handler;
+       Display *dpy = W_VIEW_SCREEN(view)->display;
+       Window win = W_VIEW_DRAWABLE(view);
+       WMArrayIterator iter;
+
+       if (!selHandlers)
+               return;
+
+       /*//printf("deleting selection handler for %d", win); */
+
+       WM_ITERATE_ARRAY(selHandlers, handler, iter) {
+               if (handler->view == view && (handler->selection == selection || selection == None)
+                   && (handler->timestamp == timestamp || timestamp == CurrentTime)) {
+
+                       if (handler->flags.done_pending) {
+                               handler->flags.delete_pending = 1;
+                               /*//puts(": postponed because still pending"); */
+                               return;
+                       }
+                       /*//printf(": found & removed"); */
+                       WMRemoveFromArray(selHandlers, handler);
+                       break;
+               }
+       }
+
+       /*//printf("\n"); */
+
+       XGrabServer(dpy);
+       if (XGetSelectionOwner(dpy, selection) == win) {
+               XSetSelectionOwner(dpy, selection, None, timestamp);
+       }
+       XUngrabServer(dpy);
+}
+
+void WMDeleteSelectionCallback(WMView * view, Atom selection, Time timestamp)
+{
+       SelectionCallback *handler;
+       WMArrayIterator iter;
+
+       if (!selCallbacks)
+               return;
+
+       WM_ITERATE_ARRAY(selCallbacks, handler, iter) {
+               if (handler->view == view && (handler->selection == selection || selection == None)
+                   && (handler->timestamp == timestamp || timestamp == CurrentTime)) {
+
+                       if (handler->flags.done_pending) {
+                               handler->flags.delete_pending = 1;
+                               return;
+                       }
+                       WMRemoveFromArray(selCallbacks, handler);
+                       break;
+               }
+       }
+}
+
+static int handleXError(Display * dpy, XErrorEvent * ev)
+{
+       gotXError = True;
+
+       return 1;
+}
+
+static Bool writeSelection(Display * dpy, Window requestor, Atom property, Atom type, WMData * data)
+{
+       static void *oldHandler;
+       int format, bpi;
+
+       format = WMGetDataFormat(data);
+       if (format == 0)
+               format = 8;
+
+       bpi = format / 8;
+
+       /* printf("write to %x: %s\n", requestor, XGetAtomName(dpy, property)); */
+
+       oldHandler = XSetErrorHandler(handleXError);
+
+       gotXError = False;
+
+       XChangeProperty(dpy, requestor, property, type, format, PropModeReplace,
+                       WMDataBytes(data), WMGetDataLength(data) / bpi);
+
+       XFlush(dpy);
+
+       XSetErrorHandler(oldHandler);
+
+       return !gotXError;
+}
+
+static void notifySelection(XEvent * event, Atom prop)
+{
+       XEvent ev;
+
+       /* printf("event to %x\n", event->xselectionrequest.requestor); */
+
+       ev.xselection.type = SelectionNotify;
+       ev.xselection.serial = 0;
+       ev.xselection.send_event = True;
+       ev.xselection.display = event->xselectionrequest.display;
+       ev.xselection.requestor = event->xselectionrequest.requestor;
+       ev.xselection.target = event->xselectionrequest.target;
+       ev.xselection.selection = event->xselectionrequest.selection;
+       ev.xselection.property = prop;
+       ev.xselection.time = event->xselectionrequest.time;
+
+       XSendEvent(event->xany.display, event->xselectionrequest.requestor, False, 0, &ev);
+       XFlush(event->xany.display);
+}
+
+static void handleRequestEvent(XEvent * event)
+{
+       SelectionHandler *handler;
+       WMArrayIterator iter;
+       WMArray *copy;
+       Bool handledRequest;
+
+       WM_ITERATE_ARRAY(selHandlers, handler, iter) {
+
+               switch (event->type) {
+               case SelectionClear:
+                       if (W_VIEW_DRAWABLE(handler->view)
+                           != event->xselectionclear.window) {
+                               break;
+                       }
+
+                       handler->flags.done_pending = 1;
+                       if (handler->procs.selectionLost)
+                               handler->procs.selectionLost(handler->view, handler->selection, handler->data);
+                       handler->flags.done_pending = 0;
+                       handler->flags.delete_pending = 1;
+                       break;
+
+               case SelectionRequest:
+                       if (W_VIEW_DRAWABLE(handler->view) != event->xselectionrequest.owner) {
+                               break;
+                       }
+
+                       if (handler->procs.convertSelection != NULL
+                           && handler->selection == event->xselectionrequest.selection) {
+                               Atom atom;
+                               WMData *data;
+                               Atom prop;
+
+                               /* they're requesting for something old.. maybe another handler
+                                * can handle it */
+                               if (event->xselectionrequest.time < handler->timestamp
+                                   && event->xselectionrequest.time != CurrentTime) {
+                                       break;
+                               }
+
+                               handledRequest = False;
+
+                               handler->flags.done_pending = 1;
+
+                               data = handler->procs.convertSelection(handler->view,
+                                                                      handler->selection,
+                                                                      event->xselectionrequest.target,
+                                                                      handler->data, &atom);
+
+                               prop = event->xselectionrequest.property;
+                               /* obsolete clients that don't set the property field */
+                               if (prop == None)
+                                       prop = event->xselectionrequest.target;
+
+                               if (data) {
+                                       if (writeSelection(event->xselectionrequest.display,
+                                                          event->xselectionrequest.requestor, prop, atom, data)) {
+                                               handledRequest = True;
+                                       }
+                                       WMReleaseData(data);
+                               }
+
+                               notifySelection(event, (handledRequest == True ? prop : None));
+
+                               if (handler->procs.selectionDone != NULL) {
+                                       handler->procs.selectionDone(handler->view,
+                                                                    handler->selection,
+                                                                    event->xselectionrequest.target,
+                                                                    handler->data);
+                               }
+
+                               handler->flags.done_pending = 0;
+                       }
+                       break;
+               }
+       }
+
+       /* delete handlers */
+       copy = WMDuplicateArray(selHandlers);
+       WM_ITERATE_ARRAY(copy, handler, iter) {
+               if (handler && handler->flags.delete_pending) {
+                       WMDeleteSelectionHandler(handler->view, handler->selection, handler->timestamp);
+               }
+       }
+       WMFreeArray(copy);
+}
+
+static WMData *getSelectionData(Display * dpy, Window win, Atom where)
+{
+       WMData *wdata;
+       unsigned char *data;
+       Atom rtype;
+       int bits, bpi;
+       unsigned long len, bytes;
+
+       if (XGetWindowProperty(dpy, win, where, 0, MAX_PROPERTY_SIZE,
+                              False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) != Success) {
+               return NULL;
+       }
+
+       bpi = bits / 8;
+
+       wdata = WMCreateDataWithBytesNoCopy(data, len * bpi, (WMFreeDataProc *) XFree);
+       WMSetDataFormat(wdata, bits);
+
+       return wdata;
+}
+
+static void handleNotifyEvent(XEvent * event)
+{
+       SelectionCallback *handler;
+       WMArrayIterator iter;
+       WMArray *copy;
+       WMData *data;
+
+       WM_ITERATE_ARRAY(selCallbacks, handler, iter) {
+
+               if (W_VIEW_DRAWABLE(handler->view) != event->xselection.requestor
+                   || handler->selection != event->xselection.selection) {
+                       continue;
+               }
+               handler->flags.done_pending = 1;
+
+               if (event->xselection.property == None) {
+                       data = NULL;
+               } else {
+                       data = getSelectionData(event->xselection.display,
+                                               event->xselection.requestor, event->xselection.property);
+               }
+
+               (*handler->callback) (handler->view, handler->selection,
+                                     handler->target, handler->timestamp, handler->data, data);
+
+               if (data != NULL) {
+                       WMReleaseData(data);
+               }
+               handler->flags.done_pending = 0;
+               handler->flags.delete_pending = 1;
+       }
+
+       /* delete callbacks */
+       copy = WMDuplicateArray(selCallbacks);
+       WM_ITERATE_ARRAY(copy, handler, iter) {
+               if (handler && handler->flags.delete_pending) {
+                       WMDeleteSelectionCallback(handler->view, handler->selection, handler->timestamp);
+               }
+       }
+       WMFreeArray(copy);
+}
+
+void W_HandleSelectionEvent(XEvent * event)
+{
+       /*//printf("%d received selection ", event->xany.window); */
+       /*//switch(event->type) {
+          case SelectionNotify:
+          puts("notify"); break;
+          case SelectionRequest:
+          puts("request"); break;
+          case SelectionClear:
+          puts("clear"); break;
+          default:
+          puts("unknown"); break;
+          } */
+
+       if (event->type == SelectionNotify) {
+               handleNotifyEvent(event);
+       } else {
+               handleRequestEvent(event);
+       }
+}
+
+Bool WMCreateSelectionHandler(WMView * view, Atom selection, Time timestamp, WMSelectionProcs * procs, void *cdata)
+{
+       SelectionHandler *handler;
+       Display *dpy = W_VIEW_SCREEN(view)->display;
+
+       XSetSelectionOwner(dpy, selection, W_VIEW_DRAWABLE(view), timestamp);
+       if (XGetSelectionOwner(dpy, selection) != W_VIEW_DRAWABLE(view)) {
+               return False;
+       }
+
+       WMPostNotificationName(WMSelectionOwnerDidChangeNotification, (void *)selection, (void *)view);
+
+       /*//printf("created selection handler for %d\n", W_VIEW_DRAWABLE(view)); */
+
+       handler = wmalloc(sizeof(SelectionHandler));
+
+       handler->view = view;
+       handler->selection = selection;
+       handler->timestamp = timestamp;
+       handler->procs = *procs;
+       handler->data = cdata;
+       memset(&handler->flags, 0, sizeof(handler->flags));
+
+       if (selHandlers == NULL) {
+               selHandlers = WMCreateArrayWithDestructor(4, wfree);
+       }
+
+       WMAddToArray(selHandlers, handler);
+
+       return True;
+}
+
+Bool
+WMRequestSelection(WMView * view, Atom selection, Atom target, Time timestamp,
+                  WMSelectionCallback * callback, void *cdata)
+{
+       SelectionCallback *handler;
+
+       if (XGetSelectionOwner(W_VIEW_SCREEN(view)->display, selection) == None)
+               return False;
+
+       if (!XConvertSelection(W_VIEW_SCREEN(view)->display, selection, target,
+                              W_VIEW_SCREEN(view)->clipboardAtom, W_VIEW_DRAWABLE(view), timestamp)) {
+               return False;
+       }
+
+       handler = wmalloc(sizeof(SelectionCallback));
+
+       handler->view = view;
+       handler->selection = selection;
+       handler->target = target;
+       handler->timestamp = timestamp;
+       handler->callback = callback;
+       handler->data = cdata;
+       memset(&handler->flags, 0, sizeof(handler->flags));
+
+       if (selCallbacks == NULL) {
+               selCallbacks = WMCreateArrayWithDestructor(4, wfree);
+       }
+
+       WMAddToArray(selCallbacks, handler);
+
+       return True;
+}