1 /******************************************************************************
2 ******************************************************************************
5 ** RCS: $XConsortium: mailbox.c /main/2 1996/07/18 15:26:34 drk $
9 ** (c) Copyright 1995, 1996, Hewlett-Packard Company, all rights reserved.
11 ******************************************************************************
12 *****************************************************************************/
22 /******************************************************************************
24 * Setup a child service record per the selection request.
26 void mbox_initialize( XEvent *report, XpPdmServiceRec *rec )
31 Display *selection_display;
36 XTextProperty text_prop;
40 rec->selection_display = report->xselectionrequest.display;
41 rec->requestor = report->xselectionrequest.requestor;
42 rec->prop_atom = report->xselectionrequest.property;
43 rec->selection = report->xselectionrequest.selection;
44 rec->time = report->xselectionrequest.time;
46 rec->mbox_flag = False; /* still need to complete mbox */
49 /******************************************************************************
53 * Build a window per requestor to serve as a mailbox for
56 * note: a possible optimization is to have a window or two cached
57 * that could quickly be assigned as a mailbox. When all the mail
58 * is sent, the window could be released back to the cache.
60 void mbox_build( XpPdmServiceRec *rec )
64 tscreen = DefaultScreen( rec->selection_display );
66 rec->mbox_window = XCreateSimpleWindow( rec->selection_display,
67 DefaultRootWindow( rec->selection_display ),
69 BlackPixel(rec->selection_display, tscreen),
70 WhitePixel(rec->selection_display, tscreen) );
74 /******************************************************************************
78 * Reply to the SelectionRequest.
80 void mbox_reply( XpPdmServiceRec *rec )
90 XChangeProperty( rec->selection_display, rec->requestor,
91 rec->prop_atom, XA_WINDOW,
93 (unsigned char *) &(rec->mbox_window),
97 * Send a SelectionNotify event, which will conclude the
98 * selection handshake.
100 reply.xselection.type = SelectionNotify;
101 reply.xselection.requestor = rec->requestor;
102 reply.xselection.selection = rec->selection;
103 reply.xselection.target = g.pdm_mbox;
104 reply.xselection.property = rec->prop_atom;
105 reply.xselection.time = rec->time;
107 status = XSendEvent( rec->selection_display, rec->requestor, True, 0, &reply );
111 /******************************************************************************
115 * Pickup the mail pieces that come in, buffer until a complete
116 * cookie comes in, convert to Xauth format, and eventually mark
117 * the mailbox done when the last cookie is fully received.
119 void mbox_receive( XpPdmServiceRec *rec, XEvent *report )
121 XClientMessageEvent *cme;
122 Xauth *c; /* shorthand pointer */
126 cme = (XClientMessageEvent *) report;
128 if ( cme -> format == 16 ) {
130 * Only the cookie header packet would be format 16.
132 rec->cookie_state = cme->data.s[0];
134 if (rec->cookie_state == 0) {
136 * Terminating cookie.
138 rec->mbox_flag = True; /* all done */
139 XDestroyWindow( rec->selection_display, rec->mbox_window );
140 rec->mbox_window = (Window) NULL;
144 if ( rec->cookie_cnt ) {
146 rec->cookies = (Xauth **) Xrealloc( (char *) rec->cookies,
147 sizeof(Xauth *) * rec->cookie_cnt );
151 rec->cookies = (Xauth **) Xmalloc( sizeof(Xauth *) );
154 rec->cookies[rec->cookie_cnt-1] = (Xauth *) Xmalloc( sizeof(Xauth) );
156 c = rec->cookies[rec->cookie_cnt-1];
158 c->address_length = (unsigned short) cme->data.s[1];
159 c->number_length = (unsigned short) cme->data.s[2];
160 c->name_length = (unsigned short) cme->data.s[3];
161 c->data_length = (unsigned short) cme->data.s[4];
162 c->family = (unsigned short) cme->data.s[5];
164 c->address = Xmalloc( c->address_length );
165 c->number = Xmalloc( c->number_length );
166 c->name = Xmalloc( c->name_length );
167 c->data = Xmalloc( c->data_length );
170 rec->in_expected = c->address_length + c->number_length +
171 c->name_length + c->data_length;
172 rec->in_buf = (char *) Xmalloc( rec->in_expected );
175 else if ( cme -> format == 8 ) {
177 * A cookie crumb has come in.
179 c = rec->cookies[rec->cookie_cnt-1];
181 maxgrab = rec->in_expected - rec->in_sofar;
182 if ( maxgrab > 20 ) maxgrab = 20;
184 memcpy( (char *) &(rec->in_buf[rec->in_sofar]), cme->data.b, maxgrab );
186 rec->in_sofar += maxgrab;
188 if ( rec->in_sofar == rec->in_expected ) {
191 memcpy( c->address, tptr, c->address_length );
192 tptr += c->address_length;
194 memcpy( c->number, tptr, c->number_length);
195 tptr += c->number_length;
197 memcpy( c->name, tptr, c->name_length );
198 tptr += c->name_length;
200 memcpy( c->data, tptr, c->data_length );
202 Xfree( rec->in_buf ); rec->in_buf = (char *) NULL;
204 if (rec->cookie_state == 1) {
205 rec->mbox_flag = True; /* all done */
206 XDestroyWindow( rec->selection_display, rec->mbox_window );
207 rec->mbox_window = (Window) NULL;