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