00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "mit-copyright.h"
00010
00011
00012
00013
00014 #ifndef X_DISPLAY_MISSING
00015
00016 #include <X11/Xlib.h>
00017 #include <X11/Xproto.h>
00018 #include <X11/Xatom.h>
00019 #include "new_string.h"
00020 #include "xselect.h"
00021
00022 extern char *getSelectedText();
00023
00024 static Time ownership_start = CurrentTime;
00025 static Time ownership_end = CurrentTime;
00026 Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW;
00027 static Atom JA_TARGETS, JA_MULTIPLE, JA_TIMESTAMP, JA_ATOM_PAIR;
00028
00029 static struct _JAtom {
00030 Atom *patom;
00031 char *name;
00032 } JAtom[] = {
00033 {
00034 &XA_WM_PROTOCOLS, "WM_PROTOCOLS"
00035 },
00036 {
00037 &XA_WM_DELETE_WINDOW, "WM_DELETE_WINDOW"
00038 },
00039 {
00040 &JA_TARGETS, "TARGETS"
00041 },
00042 {
00043 &JA_MULTIPLE, "MULTIPLE"
00044 },
00045 {
00046 &JA_TIMESTAMP, "TIMESTAMP"
00047 },
00048 {
00049 &JA_ATOM_PAIR, "ATOM_PAIR"
00050 }
00051 };
00052 #define NumJAtoms (sizeof(JAtom)/sizeof(struct _JAtom))
00053
00054
00055
00056 static void
00057 xselNotify(dpy, selreq, property)
00058 Display *dpy;
00059 XSelectionRequestEvent *selreq;
00060 Atom property;
00061 {
00062 XSelectionEvent ev;
00063
00064 ev.type = SelectionNotify;
00065 ev.requestor = selreq->requestor;
00066 ev.selection = selreq->selection;
00067 ev.target = selreq->target;
00068 ev.property = property;
00069 ev.time = selreq->time;
00070
00071 XSendEvent(dpy, ev.requestor, False, 0, (XEvent *) & ev);
00072 }
00073
00074
00075 static Atom *pRequestAtoms[] = {
00076 &JA_TARGETS, &JA_MULTIPLE, &JA_TIMESTAMP, NULL
00077 };
00078 static Atom RequestAtoms[] = {
00079 None, None, None, XA_STRING
00080 };
00081 #define NumRequestAtoms (sizeof(RequestAtoms)/sizeof(Atom))
00082 #define PROP(prop,targ) ((prop)!=None?(prop):(targ))
00083 #define ChangeProp(type,format,data,size) \
00084 XChangeProperty(dpy,w,PROP(property,target),(type),(format), \
00085 PropModeReplace, (unsigned char *) (data),(size))
00086
00087 static void
00088 xselSetProperties(dpy, w, property, target, selreq)
00089 Display *dpy;
00090 Window w;
00091 Atom property, target;
00092 XSelectionRequestEvent *selreq;
00093 {
00094 if (target == JA_TARGETS) {
00095
00096 ChangeProp(XA_ATOM, 32, RequestAtoms, NumRequestAtoms);
00097 XSync(dpy, 0);
00098 }
00099 else if (target == JA_MULTIPLE) {
00100 Atom atype;
00101 int aformat;
00102 Atom *alist;
00103 unsigned long alistsize, i;
00104
00105 XGetWindowProperty(dpy, w, property, 0L, 0L, False, JA_ATOM_PAIR, &atype,
00106 &aformat, &i, &alistsize, (unsigned char **) &alist);
00107
00108 if (alistsize)
00109 XGetWindowProperty(dpy, w, property, 0L, alistsize / sizeof(Atom), False,
00110 JA_ATOM_PAIR, &atype, &aformat, &alistsize, &i,
00111 (unsigned char **) &alist);
00112
00113 alistsize /= (sizeof(Atom) / 4);
00114 for (i = 0; i < alistsize; i += 2)
00115 xselSetProperties(dpy, w, alist[i + 1], alist[i], selreq);
00116
00117 XFree((char *) alist);
00118 }
00119 else if (target == JA_TIMESTAMP) {
00120 ChangeProp(XA_INTEGER, 32, &ownership_start, 1);
00121 XSync(dpy, 0);
00122 }
00123 else if (target == XA_STRING) {
00124 char *selected;
00125
00126 if ((selected = getSelectedText())) {
00127 ChangeProp(XA_STRING, 8, selected, string_Length(selected));
00128 }
00129 else {
00130
00131
00132
00133
00134
00135 ChangeProp(XA_STRING, 8, "", 0);
00136 }
00137 XSync(dpy, 0);
00138 }
00139
00140 xselNotify(dpy, selreq, property);
00141 }
00142
00143
00144
00145 void
00146 xicccmInitAtoms(dpy)
00147 Display *dpy;
00148 {
00149 int i;
00150
00151 for (i = 0; i < NumJAtoms; i++)
00152 *(JAtom[i].patom) = XInternAtom(dpy, JAtom[i].name, False);
00153 for (i = 0; i < NumRequestAtoms; i++)
00154 if (pRequestAtoms[i])
00155 RequestAtoms[i] = *(pRequestAtoms[i]);
00156 }
00157
00158 int
00159 xselGetOwnership(dpy, w, time)
00160 Display *dpy;
00161 Window w;
00162 Time time;
00163 {
00164 int temp;
00165
00166 XSetSelectionOwner(dpy, XA_PRIMARY, w, time);
00167 temp = (w == XGetSelectionOwner(dpy, XA_PRIMARY));
00168
00169 if (temp)
00170 ownership_start = time;
00171
00172 return (temp);
00173 }
00174
00175
00176 int
00177 xselProcessSelection(dpy, w, event)
00178 Display *dpy;
00179 Window w;
00180 XEvent *event;
00181 {
00182 XSelectionRequestEvent *selreq = &(event->xselectionrequest);
00183
00184 if ((ownership_start == CurrentTime) ||
00185 (((selreq->time != CurrentTime) &&
00186 (selreq->time < ownership_start)) ||
00187 ((ownership_end != CurrentTime) &&
00188 (ownership_end > ownership_start) &&
00189 (selreq->time > ownership_end))))
00190 xselNotify(dpy, selreq, None);
00191 else
00192 xselSetProperties(dpy, selreq->requestor, selreq->property, selreq->target,
00193 selreq);
00194
00195 return (1);
00196 }
00197
00198 void
00199 xselOwnershipLost(time)
00200 Time time;
00201 {
00202 ownership_end = time;
00203 }
00204
00205
00206 void
00207 xselGiveUpOwnership(dpy, w)
00208 Display *dpy;
00209 Window w;
00210 {
00211 XSetSelectionOwner(dpy, XA_PRIMARY, None, ownership_start);
00212
00213 ownership_end = ownership_start;
00214
00215 }
00216
00217 #endif