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:    }