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