Link with C++ linker
[oweals/cde.git] / cde / programs / dtpdmd / mailbox.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /******************************************************************************
24  ******************************************************************************
25  **
26  ** File:         mailbox.c
27  ** RCS:          $XConsortium: mailbox.c /main/2 1996/07/18 15:26:34 drk $
28  **
29  ** Description:
30  **
31  ** (c) Copyright 1995, 1996, Hewlett-Packard Company, all rights reserved.
32  **
33  ******************************************************************************
34  *****************************************************************************/
35
36 #define MAILBOX_DOT_C
37
38 #include "dtpdmdP.h"
39 #include <setjmp.h>
40 #include <locale.h>
41 #include <unistd.h>
42
43
44 /******************************************************************************
45  *
46  * Setup a child service record per the selection request.
47  */
48 void mbox_initialize( XEvent *report, XpPdmServiceRec *rec )
49 {
50     Display *testdpy;
51     char    buf[1024];
52
53     Display *selection_display;
54     Window   requestor;
55     Atom     prop_atom;
56     unsigned long tafter;
57
58     XTextProperty  text_prop;
59     char           **list;
60     int            list_cnt;
61
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;
67
68     rec->mbox_flag          = False;    /* still need to complete mbox */
69 }
70
71 /******************************************************************************
72  *
73  * mbox_build()
74  *
75  * Build a window per requestor to serve as a mailbox for
76  * that requestor.
77  *
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.
81  */
82 void mbox_build( XpPdmServiceRec *rec )
83 {
84     int tscreen;
85
86     tscreen = DefaultScreen( rec->selection_display );
87
88     rec->mbox_window = XCreateSimpleWindow( rec->selection_display,
89                                   DefaultRootWindow( rec->selection_display ),
90                                   0, 0, 1, 1, 1,
91                                   BlackPixel(rec->selection_display, tscreen),
92                                   WhitePixel(rec->selection_display, tscreen) );
93 }
94
95
96 /******************************************************************************
97  *
98  * mbox_reply()
99  *
100  * Reply to the SelectionRequest.
101  */
102 void mbox_reply( XpPdmServiceRec *rec )
103 {
104     XEvent reply;
105     Status status;
106     FILE   *errlog;
107     long   now;
108
109     Atom    tmpa;
110
111
112     XChangeProperty( rec->selection_display, rec->requestor,
113                      rec->prop_atom, XA_WINDOW,
114                      32, PropModeReplace,
115                      (unsigned char *) &(rec->mbox_window),
116                      1 );
117
118     /*
119      * Send a SelectionNotify event, which will conclude the
120      * selection handshake.
121      */
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;
128
129     status = XSendEvent( rec->selection_display, rec->requestor, True, 0, &reply );
130 }
131
132
133 /******************************************************************************
134  *
135  * mbox_receive()
136  *
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.
140  */
141 void mbox_receive( XpPdmServiceRec *rec, XEvent *report )
142 {
143     XClientMessageEvent *cme;
144     Xauth *c;                   /* shorthand pointer */
145     int maxgrab;
146     char *tptr;
147
148     cme = (XClientMessageEvent *) report;
149
150     if ( cme -> format == 16 ) {
151         /*
152          * Only the cookie header packet would be format 16.
153          */
154         rec->cookie_state = cme->data.s[0];
155
156         if (rec->cookie_state == 0) {
157             /*
158              * Terminating cookie.
159              */
160             rec->mbox_flag = True;              /* all done */
161             XDestroyWindow( rec->selection_display, rec->mbox_window );
162             rec->mbox_window = (Window) NULL;
163             return;
164         }
165
166         if ( rec->cookie_cnt ) {
167             rec->cookie_cnt++;
168             rec->cookies = (Xauth **) Xrealloc( (char *) rec->cookies,
169                                            sizeof(Xauth *) * rec->cookie_cnt );
170         }
171         else {
172             rec->cookie_cnt++;
173             rec->cookies = (Xauth **) Xmalloc( sizeof(Xauth *) );
174         }
175
176         rec->cookies[rec->cookie_cnt-1] = (Xauth *) Xmalloc( sizeof(Xauth) );
177
178         c = rec->cookies[rec->cookie_cnt-1];
179
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];
185
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 );
190
191         rec->in_sofar = 0;
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 );
195
196     }
197     else if ( cme -> format == 8 ) {
198         /*
199          * A cookie crumb has come in.
200          */
201         c = rec->cookies[rec->cookie_cnt-1];
202
203         maxgrab = rec->in_expected - rec->in_sofar;
204         if ( maxgrab > 20 ) maxgrab = 20;
205
206         memcpy( (char *) &(rec->in_buf[rec->in_sofar]), cme->data.b, maxgrab );
207
208         rec->in_sofar += maxgrab;
209
210         if ( rec->in_sofar == rec->in_expected ) {
211             tptr = rec->in_buf;
212
213             memcpy( c->address, tptr, c->address_length );
214             tptr += c->address_length;
215
216             memcpy( c->number, tptr, c->number_length);
217             tptr += c->number_length;
218
219             memcpy( c->name, tptr, c->name_length );
220             tptr += c->name_length;
221
222             memcpy( c->data, tptr, c->data_length );
223
224             Xfree( rec->in_buf ); rec->in_buf = (char *) NULL;
225
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;
230                 return;
231             }
232         }
233     }
234 }