    785:    static void HandleSelectionEvents(
    786:        Widget widget,
    787:        XtPointer closure,
    788:        XEvent *event,
    789:        Boolean *cont)
    790:    {
    791:        Select ctx;
    792:        XSelectionEvent ev;
    793:        Atom target;
    794:        int count;
    795:        Boolean writeback = FALSE;
    796:
    797:        ctx = (Select) closure;
    798:        switch (event->type) {
    799:          case SelectionClear:
    800:        /* if this event is not for the selection we registered for,
    801:         * don't do anything */
    802:        if (ctx->selection != event->xselectionclear.selection ||
    803:            ctx->serial > event->xselectionclear.serial)
    804:            break;
    805:        (void) LoseSelection(ctx, widget, event->xselectionclear.selection,
    806:                event->xselectionclear.time);
    807:        break;
    808:          case SelectionRequest:
    809:        /* if this event is not for the selection we registered for,
    810:         * don't do anything */
    811:        if (ctx->selection != event->xselectionrequest.selection)
    812:            break;
    813:        ev.type = SelectionNotify;
    814:        ev.display = event->xselectionrequest.display;
    815:        ev.requestor = event->xselectionrequest.requestor;
    816:        ev.selection = event->xselectionrequest.selection;
    817:        ev.time = event->xselectionrequest.time;
    818:        ev.target = event->xselectionrequest.target;
    819:        if (event->xselectionrequest.property == None) /* obsolete requestor */
    820:           event->xselectionrequest.property = event->xselectionrequest.target;
    821:        if (ctx->widget != widget || ctx->was_disowned
    822:           || ((event->xselectionrequest.time != CurrentTime)
    823:                && (event->xselectionrequest.time < ctx->time))) {
    824:            ev.property = None;
    825:            StartProtectedSection(ev.display, ev.requestor);
    826:                } else {
    827:           if (ev.target == ctx->prop_list->indirect_atom) {
    828:              IndirectPair *p;
    829:              int format;
    830:              unsigned long bytesafter, length;
    831:              unsigned char *value;
    832:              ev.property = event->xselectionrequest.property;
    833:              StartProtectedSection(ev.display, ev.requestor);
    834:              (void) XGetWindowProperty(ev.display, ev.requestor,
    835:                event->xselectionrequest.property, 0L, 1000000,
    836:                False,(Atom)AnyPropertyType, &target, &format, &length,
    837:                &bytesafter, &value);
    838:              count = BYTELENGTH(length, format) / sizeof(IndirectPair);
    839:              for (p = (IndirectPair *)value; count; p++, count--) {
    840:              EndProtectedSection(ctx->dpy);
    841:              if (!GetConversion(ctx, (XSelectionRequestEvent*)event,
    842:                         p->target, p->property, widget)) {
    843:
    844:                p->target = None;
    845:                writeback = TRUE;
    846:                StartProtectedSection(ctx->dpy, ev.requestor);
    847:              }
    848:              }
    849:              if (writeback)
    850:            XChangeProperty(ev.display, ev.requestor,
    851:                event->xselectionrequest.property, target,
    852:                format, PropModeReplace, value, (int)length);
    853:              XFree((char *)value);
    854:          } else /* not multiple */ {
    855:               if (GetConversion(ctx, (XSelectionRequestEvent*)event,
    856:                     event->xselectionrequest.target,
    857:                     event->xselectionrequest.property,
    858:                     widget))
    859:               ev.property = event->xselectionrequest.property;
    860:               else {
    861:               ev.property = None;
    862:               StartProtectedSection(ctx->dpy, ev.requestor);
    863:               }
    864:           }
    865:          }
    866:          (void) XSendEvent(ctx->dpy, ev.requestor, False, (unsigned long)NULL,
    867:               (XEvent *) &ev);
    868:
    869:          EndProtectedSection(ctx->dpy);
    870:
    871:          break;
    872:        }
    873:    }