extensions.c revision ce6676db
1/*
2 * font server extensions
3 */
4/*
5
6Copyright 1990, 1991, 1998  The Open Group
7
8Permission to use, copy, modify, distribute, and sell this software and its
9documentation for any purpose is hereby granted without fee, provided that
10the above copyright notice appear in all copies and that both that
11copyright notice and this permission notice appear in supporting
12documentation.
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of The Open Group shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in this Software without prior written authorization from The Open Group.
27
28 * Copyright 1990, 1991 Network Computing Devices;
29 * Portions Copyright 1987 by Digital Equipment Corporation
30 *
31 * Permission to use, copy, modify, distribute, and sell this software and
32 * its documentation for any purpose is hereby granted without fee, provided
33 * that the above copyright notice appear in all copies and that both that
34 * copyright notice and this permission notice appear in supporting
35 * documentation, and that the names of Network Computing Devices, or Digital
36 * not be used in advertising or publicity pertaining to distribution
37 * of the software without specific, written prior permission.
38 *
39 * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
40 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
41 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
42 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
43 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
44 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
45 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
46 * THIS SOFTWARE.
47 */
48
49#include	"xfs-config.h"
50
51#include	<X11/fonts/FSproto.h>
52#include	"misc.h"
53#include	"clientstr.h"
54#include	"extentst.h"
55#include	"difs.h"
56#include	"dispatch.h"
57
58#define	EXTENSION_BASE	128
59#define	EXTENSION_EVENT_BASE	64
60#define	LAST_EVENT	128
61#define	LAST_ERROR	255
62
63static ExtensionEntry **extensions = (ExtensionEntry **) NULL;
64
65static int  lastEvent = EXTENSION_EVENT_BASE;
66static int  lastError = FirstExtensionError;
67static int  NumExtensions = 0;
68
69
70ExtensionEntry *
71AddExtension(
72    char       *name,
73    int         num_events,
74    int         num_errors,
75    int         (*main_proc) (ClientPtr),
76    int         (*smain_proc) (ClientPtr),
77    void        (*closedown_proc) (struct _ExtensionEntry *),
78    unsigned short (*minorop_proc) (ClientPtr))
79{
80    int         i;
81    ExtensionEntry *ext,
82              **newexts;
83
84    if (!main_proc || !smain_proc || !closedown_proc || !minorop_proc)
85	return ((ExtensionEntry *) 0);
86    if ((lastEvent + num_events > LAST_EVENT) ||
87	    (unsigned) (lastError + num_errors > LAST_ERROR))
88	return ((ExtensionEntry *) 0);
89    ext = (ExtensionEntry *) fsalloc(sizeof(ExtensionEntry));
90    if (!ext)
91	return ((ExtensionEntry *) 0);
92    ext->name = (char *) fsalloc(strlen(name) + 1);
93    ext->num_aliases = 0;
94    ext->aliases = (char **) NULL;
95    if (!ext->name) {
96	fsfree(ext);
97	return ((ExtensionEntry *) 0);
98    }
99    strcpy(ext->name, name);
100    i = NumExtensions;
101    newexts = (ExtensionEntry **) fsrealloc(extensions,
102					 (i + 1) * sizeof(ExtensionEntry *));
103    if (!newexts) {
104	fsfree(ext->name);
105	fsfree(ext);
106	return ((ExtensionEntry *) 0);
107    }
108    NumExtensions++;
109    extensions = newexts;
110    extensions[i] = ext;
111    ext->index = i;
112    ext->base = i + EXTENSION_BASE;
113    ext->CloseDown = closedown_proc;
114    ext->MinorOpcode = minorop_proc;
115    ProcVector[i + EXTENSION_BASE] = main_proc;
116    SwappedProcVector[i + EXTENSION_BASE] = smain_proc;
117    if (num_events) {
118	ext->eventBase = lastEvent;
119	ext->eventLast = lastEvent + num_events;
120	lastEvent += num_events;
121    } else {
122	ext->eventBase = 0;
123	ext->eventLast = 0;
124    }
125    if (num_errors) {
126	ext->errorBase = lastError;
127	ext->errorLast = lastError + num_errors;
128	lastError += num_errors;
129    } else {
130	ext->errorBase = 0;
131	ext->errorLast = 0;
132    }
133    return ext;
134}
135
136Bool
137AddExtensionAlias(char *alias, ExtensionEntry *ext)
138{
139    char       *name;
140    char      **aliases;
141
142    aliases = (char **) fsrealloc(ext->aliases,
143				  (ext->num_aliases + 1) * sizeof(char *));
144    if (!aliases)
145	return FALSE;
146    ext->aliases = aliases;
147    name = (char *) fsalloc(strlen(alias) + 1);
148    if (!name)
149	return FALSE;
150    strcpy(name, alias);
151    ext->aliases[ext->num_aliases++] = name;
152    return TRUE;
153}
154
155unsigned short
156StandardMinorOpcode(ClientPtr client)
157{
158    return ((fsReq *) client->requestBuffer)->data;
159}
160
161unsigned short
162MinorOpcodeOfRequest(ClientPtr client)
163{
164    unsigned char major;
165
166    major = ((fsReq *) client->requestBuffer)->reqType;
167    if (major < EXTENSION_BASE)
168	return 0;
169    major -= EXTENSION_BASE;
170    if (major >= NumExtensions)
171	return 0;
172    return (*extensions[major]->MinorOpcode) (client);
173}
174
175void
176CloseDownExtensions(void)
177{
178    int         i,
179                j;
180
181    for (i = NumExtensions - 1; i >= 0; i--) {
182	(*extensions[i]->CloseDown) (extensions[i]);
183	NumExtensions = i;
184	fsfree(extensions[i]->name);
185	for (j = extensions[i]->num_aliases; --j >= 0;)
186	    fsfree(extensions[i]->aliases[j]);
187	fsfree(extensions[i]->aliases);
188	fsfree(extensions[i]);
189    }
190    fsfree(extensions);
191    extensions = (ExtensionEntry **) NULL;
192    lastEvent = EXTENSION_EVENT_BASE;
193    lastError = FirstExtensionError;
194}
195
196void
197InitExtensions(void)
198{
199}
200
201int
202ProcQueryExtension(ClientPtr client)
203{
204    fsQueryExtensionReply reply;
205    int         i,
206                j;
207
208    REQUEST(fsQueryExtensionReq);
209
210    REQUEST_AT_LEAST_SIZE(fsQueryExtensionReq);
211
212    reply.type = FS_Reply;
213    reply.length = SIZEOF(fsQueryExtensionReply) >> 2;
214    reply.major_opcode = 0;
215    reply.sequenceNumber = client->sequence;
216
217    if (!NumExtensions) {
218	reply.present = fsFalse;
219    } else {
220	for (i = 0; i < NumExtensions; i++) {
221	    if ((strlen(extensions[i]->name) == stuff->nbytes) &&
222		    !strncmp((char *) &stuff[1], extensions[i]->name,
223			     (int) stuff->nbytes))
224		break;
225	    for (j = extensions[i]->num_aliases; --j >= 0;) {
226		if ((strlen(extensions[i]->aliases[j]) == stuff->nbytes) &&
227		      !strncmp((char *) &stuff[1], extensions[i]->aliases[j],
228			       (int) stuff->nbytes))
229		    break;
230	    }
231	    if (j >= 0)
232		break;
233	}
234	if (i == NumExtensions) {
235	    reply.present = fsFalse;
236	} else {
237	    reply.present = fsTrue;
238	    reply.major_opcode = extensions[i]->base;
239	    reply.first_event = extensions[i]->eventBase;
240	    reply.first_error = extensions[i]->errorBase;
241	}
242
243    }
244    WriteReplyToClient(client, SIZEOF(fsQueryExtensionReply), &reply);
245    return client->noClientException;
246}
247
248int
249ProcListExtensions(ClientPtr client)
250{
251    fsListExtensionsReply reply;
252    char       *bufptr,
253               *buffer;
254    int         total_length = 0;
255
256    REQUEST(fsListExtensionsReq);
257    REQUEST_SIZE_MATCH(fsListExtensionsReq);
258
259    reply.type = FS_Reply;
260    reply.nExtensions = NumExtensions;
261    reply.length = SIZEOF(fsListExtensionsReply) >> 2;
262    reply.sequenceNumber = client->sequence;
263    buffer = NULL;
264
265    if (NumExtensions) {
266	int         i,
267	            j;
268
269	for (i = 0; i < NumExtensions; i++) {
270	    total_length += strlen(extensions[i]->name) + 1;
271	    reply.nExtensions += extensions[i]->num_aliases;
272	    for (j = extensions[i]->num_aliases; --j >= 0;)
273		total_length += strlen(extensions[i]->aliases[j]) + 1;
274	}
275	reply.length += (total_length + 3) >> 2;
276	buffer = bufptr = (char *) ALLOCATE_LOCAL(total_length);
277	if (!buffer) {
278	    SendErrToClient(client, FSBadAlloc, NULL);
279	    return FSBadAlloc;
280	}
281	for (i = 0; i < NumExtensions; i++) {
282	    int         len;
283
284	    *bufptr++ = len = strlen(extensions[i]->name);
285	    memmove( bufptr, extensions[i]->name, len);
286	    bufptr += len;
287	    for (j = extensions[i]->num_aliases; --j >= 0;) {
288		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
289		memmove( bufptr, extensions[i]->aliases[j], len);
290		bufptr += len;
291	    }
292	}
293    }
294    WriteReplyToClient(client, SIZEOF(fsListExtensionsReply), &reply);
295    if (total_length) {
296	WriteToClient(client, total_length, buffer);
297	DEALLOCATE_LOCAL(buffer);
298    }
299    return client->noClientException;
300}
301