extensions.c revision 34f90d55
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	"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        .type = FS_Reply,
206        .sequenceNumber = client->sequence,
207        .length = SIZEOF(fsQueryExtensionReply) >> 2,
208        .major_opcode = 0
209    };
210    int         i,
211                j;
212
213    REQUEST(fsQueryExtensionReq);
214
215    REQUEST_AT_LEAST_SIZE(fsQueryExtensionReq);
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        .type = FS_Reply,
253        .nExtensions = NumExtensions,
254        .sequenceNumber = client->sequence,
255        .length = SIZEOF(fsListExtensionsReply) >> 2
256    };
257    char       *bufptr,
258               *buffer = NULL;
259    int         total_length = 0;
260
261    REQUEST(fsListExtensionsReq);
262    REQUEST_SIZE_MATCH(fsListExtensionsReq);
263
264    if (NumExtensions) {
265	int         i,
266	            j;
267
268	for (i = 0; i < NumExtensions; i++) {
269	    total_length += strlen(extensions[i]->name) + 1;
270	    reply.nExtensions += extensions[i]->num_aliases;
271	    for (j = extensions[i]->num_aliases; --j >= 0;)
272		total_length += strlen(extensions[i]->aliases[j]) + 1;
273	}
274	reply.length += (total_length + 3) >> 2;
275	buffer = bufptr = (char *) ALLOCATE_LOCAL(total_length);
276	if (!buffer) {
277	    SendErrToClient(client, FSBadAlloc, NULL);
278	    return FSBadAlloc;
279	}
280	for (i = 0; i < NumExtensions; i++) {
281	    int         len;
282
283	    *bufptr++ = len = strlen(extensions[i]->name);
284	    memmove( bufptr, extensions[i]->name, len);
285	    bufptr += len;
286	    for (j = extensions[i]->num_aliases; --j >= 0;) {
287		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
288		memmove( bufptr, extensions[i]->aliases[j], len);
289		bufptr += len;
290	    }
291	}
292    }
293    WriteReplyToClient(client, SIZEOF(fsListExtensionsReply), &reply);
294    if (total_length) {
295	WriteToClient(client, total_length, buffer);
296	DEALLOCATE_LOCAL(buffer);
297    }
298    return client->noClientException;
299}
300