Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtpdmd / mailbox.c
1 /******************************************************************************
2  ******************************************************************************
3  **
4  ** File:         mailbox.c
5  ** RCS:          $XConsortium: mailbox.c /main/2 1996/07/18 15:26:34 drk $
6  **
7  ** Description:
8  **
9  ** (c) Copyright 1995, 1996, Hewlett-Packard Company, all rights reserved.
10  **
11  ******************************************************************************
12  *****************************************************************************/
13
14 #define MAILBOX_DOT_C
15
16 #include "dtpdmdP.h"
17 #include <setjmp.h>
18 #include <locale.h>
19 #include <unistd.h>
20
21
22 /******************************************************************************
23  *
24  * Setup a child service record per the selection request.
25  */
26 void mbox_initialize( XEvent *report, XpPdmServiceRec *rec )
27 {
28     Display *testdpy;
29     char    buf[1024];
30
31     Display *selection_display;
32     Window   requestor;
33     Atom     prop_atom;
34     unsigned long tafter;
35
36     XTextProperty  text_prop;
37     char           **list;
38     int            list_cnt;
39
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;
45
46     rec->mbox_flag          = False;    /* still need to complete mbox */
47 }
48
49 /******************************************************************************
50  *
51  * mbox_build()
52  *
53  * Build a window per requestor to serve as a mailbox for
54  * that requestor.
55  *
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.
59  */
60 void mbox_build( XpPdmServiceRec *rec )
61 {
62     int tscreen;
63
64     tscreen = DefaultScreen( rec->selection_display );
65
66     rec->mbox_window = XCreateSimpleWindow( rec->selection_display,
67                                   DefaultRootWindow( rec->selection_display ),
68                                   0, 0, 1, 1, 1,
69                                   BlackPixel(rec->selection_display, tscreen),
70                                   WhitePixel(rec->selection_display, tscreen) );
71 }
72
73
74 /******************************************************************************
75  *
76  * mbox_reply()
77  *
78  * Reply to the SelectionRequest.
79  */
80 void mbox_reply( XpPdmServiceRec *rec )
81 {
82     XEvent reply;
83     Status status;
84     FILE   *errlog;
85     long   now;
86
87     Atom    tmpa;
88
89
90     XChangeProperty( rec->selection_display, rec->requestor,
91                      rec->prop_atom, XA_WINDOW,
92                      32, PropModeReplace,
93                      (unsigned char *) &(rec->mbox_window),
94                      1 );
95
96     /*
97      * Send a SelectionNotify event, which will conclude the
98      * selection handshake.
99      */
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;
106
107     status = XSendEvent( rec->selection_display, rec->requestor, True, 0, &reply );
108 }
109
110
111 /******************************************************************************
112  *
113  * mbox_receive()
114  *
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.
118  */
119 void mbox_receive( XpPdmServiceRec *rec, XEvent *report )
120 {
121     XClientMessageEvent *cme;
122     Xauth *c;                   /* shorthand pointer */
123     int maxgrab;
124     char *tptr;
125
126     cme = (XClientMessageEvent *) report;
127
128     if ( cme -> format == 16 ) {
129         /*
130          * Only the cookie header packet would be format 16.
131          */
132         rec->cookie_state = cme->data.s[0];
133
134         if (rec->cookie_state == 0) {
135             /*
136              * Terminating cookie.
137              */
138             rec->mbox_flag = True;              /* all done */
139             XDestroyWindow( rec->selection_display, rec->mbox_window );
140             rec->mbox_window = (Window) NULL;
141             return;
142         }
143
144         if ( rec->cookie_cnt ) {
145             rec->cookie_cnt++;
146             rec->cookies = (Xauth **) Xrealloc( (char *) rec->cookies,
147                                            sizeof(Xauth *) * rec->cookie_cnt );
148         }
149         else {
150             rec->cookie_cnt++;
151             rec->cookies = (Xauth **) Xmalloc( sizeof(Xauth *) );
152         }
153
154         rec->cookies[rec->cookie_cnt-1] = (Xauth *) Xmalloc( sizeof(Xauth) );
155
156         c = rec->cookies[rec->cookie_cnt-1];
157
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];
163
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 );
168
169         rec->in_sofar = 0;
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 );
173
174     }
175     else if ( cme -> format == 8 ) {
176         /*
177          * A cookie crumb has come in.
178          */
179         c = rec->cookies[rec->cookie_cnt-1];
180
181         maxgrab = rec->in_expected - rec->in_sofar;
182         if ( maxgrab > 20 ) maxgrab = 20;
183
184         memcpy( (char *) &(rec->in_buf[rec->in_sofar]), cme->data.b, maxgrab );
185
186         rec->in_sofar += maxgrab;
187
188         if ( rec->in_sofar == rec->in_expected ) {
189             tptr = rec->in_buf;
190
191             memcpy( c->address, tptr, c->address_length );
192             tptr += c->address_length;
193
194             memcpy( c->number, tptr, c->number_length);
195             tptr += c->number_length;
196
197             memcpy( c->name, tptr, c->name_length );
198             tptr += c->name_length;
199
200             memcpy( c->data, tptr, c->data_length );
201
202             Xfree( rec->in_buf ); rec->in_buf = (char *) NULL;
203
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;
208                 return;
209             }
210         }
211     }
212 }