2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /******************************************************************************
24 ******************************************************************************
27 ** RCS: $XConsortium: mailbox.c /main/2 1996/07/18 15:26:34 drk $
31 ** (c) Copyright 1995, 1996, Hewlett-Packard Company, all rights reserved.
33 ******************************************************************************
34 *****************************************************************************/
44 /******************************************************************************
46 * Setup a child service record per the selection request.
48 void mbox_initialize( XEvent *report, XpPdmServiceRec *rec )
53 Display *selection_display;
58 XTextProperty text_prop;
62 rec->selection_display = report->xselectionrequest.display;
63 rec->requestor = report->xselectionrequest.requestor;
64 rec->prop_atom = report->xselectionrequest.property;
65 rec->selection = report->xselectionrequest.selection;
66 rec->time = report->xselectionrequest.time;
68 rec->mbox_flag = False; /* still need to complete mbox */
71 /******************************************************************************
75 * Build a window per requestor to serve as a mailbox for
78 * note: a possible optimization is to have a window or two cached
79 * that could quickly be assigned as a mailbox. When all the mail
80 * is sent, the window could be released back to the cache.
82 void mbox_build( XpPdmServiceRec *rec )
86 tscreen = DefaultScreen( rec->selection_display );
88 rec->mbox_window = XCreateSimpleWindow( rec->selection_display,
89 DefaultRootWindow( rec->selection_display ),
91 BlackPixel(rec->selection_display, tscreen),
92 WhitePixel(rec->selection_display, tscreen) );
96 /******************************************************************************
100 * Reply to the SelectionRequest.
102 void mbox_reply( XpPdmServiceRec *rec )
112 XChangeProperty( rec->selection_display, rec->requestor,
113 rec->prop_atom, XA_WINDOW,
115 (unsigned char *) &(rec->mbox_window),
119 * Send a SelectionNotify event, which will conclude the
120 * selection handshake.
122 reply.xselection.type = SelectionNotify;
123 reply.xselection.requestor = rec->requestor;
124 reply.xselection.selection = rec->selection;
125 reply.xselection.target = g.pdm_mbox;
126 reply.xselection.property = rec->prop_atom;
127 reply.xselection.time = rec->time;
129 status = XSendEvent( rec->selection_display, rec->requestor, True, 0, &reply );
133 /******************************************************************************
137 * Pickup the mail pieces that come in, buffer until a complete
138 * cookie comes in, convert to Xauth format, and eventually mark
139 * the mailbox done when the last cookie is fully received.
141 void mbox_receive( XpPdmServiceRec *rec, XEvent *report )
143 XClientMessageEvent *cme;
144 Xauth *c; /* shorthand pointer */
148 cme = (XClientMessageEvent *) report;
150 if ( cme -> format == 16 ) {
152 * Only the cookie header packet would be format 16.
154 rec->cookie_state = cme->data.s[0];
156 if (rec->cookie_state == 0) {
158 * Terminating cookie.
160 rec->mbox_flag = True; /* all done */
161 XDestroyWindow( rec->selection_display, rec->mbox_window );
162 rec->mbox_window = (Window) NULL;
166 if ( rec->cookie_cnt ) {
168 rec->cookies = (Xauth **) Xrealloc( (char *) rec->cookies,
169 sizeof(Xauth *) * rec->cookie_cnt );
173 rec->cookies = (Xauth **) Xmalloc( sizeof(Xauth *) );
176 rec->cookies[rec->cookie_cnt-1] = (Xauth *) Xmalloc( sizeof(Xauth) );
178 c = rec->cookies[rec->cookie_cnt-1];
180 c->address_length = (unsigned short) cme->data.s[1];
181 c->number_length = (unsigned short) cme->data.s[2];
182 c->name_length = (unsigned short) cme->data.s[3];
183 c->data_length = (unsigned short) cme->data.s[4];
184 c->family = (unsigned short) cme->data.s[5];
186 c->address = Xmalloc( c->address_length );
187 c->number = Xmalloc( c->number_length );
188 c->name = Xmalloc( c->name_length );
189 c->data = Xmalloc( c->data_length );
192 rec->in_expected = c->address_length + c->number_length +
193 c->name_length + c->data_length;
194 rec->in_buf = (char *) Xmalloc( rec->in_expected );
197 else if ( cme -> format == 8 ) {
199 * A cookie crumb has come in.
201 c = rec->cookies[rec->cookie_cnt-1];
203 maxgrab = rec->in_expected - rec->in_sofar;
204 if ( maxgrab > 20 ) maxgrab = 20;
206 memcpy( (char *) &(rec->in_buf[rec->in_sofar]), cme->data.b, maxgrab );
208 rec->in_sofar += maxgrab;
210 if ( rec->in_sofar == rec->in_expected ) {
213 memcpy( c->address, tptr, c->address_length );
214 tptr += c->address_length;
216 memcpy( c->number, tptr, c->number_length);
217 tptr += c->number_length;
219 memcpy( c->name, tptr, c->name_length );
220 tptr += c->name_length;
222 memcpy( c->data, tptr, c->data_length );
224 Xfree( rec->in_buf ); rec->in_buf = (char *) NULL;
226 if (rec->cookie_state == 1) {
227 rec->mbox_flag = True; /* all done */
228 XDestroyWindow( rec->selection_display, rec->mbox_window );
229 rec->mbox_window = (Window) NULL;