home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / dix / extension.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-03  |  9.7 KB  |  379 lines

  1. /***********************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24. /* $XConsortium: extension.c,v 1.48 89/07/03 19:51:28 rws Exp $ */
  25.  
  26. #include "X.h"
  27. #define NEED_REPLIES
  28. #include "Xproto.h"
  29. #include "misc.h"
  30. #include "dixstruct.h"
  31. #include "extnsionst.h"
  32. #include "gcstruct.h"
  33. #include "scrnintstr.h"
  34.  
  35. #define EXTENSION_BASE  128
  36. #define EXTENSION_EVENT_BASE  64
  37. #define LAST_EVENT  128
  38. #define LAST_ERROR 255
  39.  
  40. ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
  41.  
  42. static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
  43. extern int (* ProcVector[]) ();
  44. extern int (* SwappedProcVector[]) ();
  45. extern void (* ReplySwapVector[256]) ();
  46. extern void WriteEventsToClient();
  47.  
  48. int lastEvent = EXTENSION_EVENT_BASE;
  49. static int lastError = FirstExtensionError;
  50. static int NumExtensions = 0;
  51.  
  52. ExtensionEntry *AddExtension(name, NumEvents, NumErrors, MainProc, 
  53.                   SwappedMainProc, CloseDownProc, MinorOpcodeProc)
  54.     char *name;
  55.     int NumEvents;
  56.     int NumErrors;
  57.     int (* MainProc)();
  58.     int (* SwappedMainProc)();
  59.     void (* CloseDownProc)();
  60.     unsigned short (* MinorOpcodeProc)();
  61. {
  62.     int i;
  63.     register ExtensionEntry *ext, **newexts;
  64.  
  65.     if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
  66.         return((ExtensionEntry *) NULL);
  67.     if ((lastEvent + NumEvents > LAST_EVENT) || 
  68.             (unsigned)(lastError + NumErrors > LAST_ERROR))
  69.         return((ExtensionEntry *) NULL);
  70.  
  71.     ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
  72.     if (!ext)
  73.     return((ExtensionEntry *) NULL);
  74.     ext->name = (char *)xalloc(strlen(name) + 1);
  75.     ext->num_aliases = 0;
  76.     ext->aliases = (char **)NULL;
  77.     if (!ext->name)
  78.     {
  79.     xfree(ext);
  80.     return((ExtensionEntry *) NULL);
  81.     }
  82.     strcpy(ext->name,  name);
  83.     i = NumExtensions;
  84.     newexts = (ExtensionEntry **) xrealloc(extensions,
  85.                        (i + 1) * sizeof(ExtensionEntry *));
  86.     if (!newexts)
  87.     {
  88.     xfree(ext->name);
  89.     xfree(ext);
  90.     return((ExtensionEntry *) NULL);
  91.     }
  92.     NumExtensions++;
  93.     extensions = newexts;
  94.     extensions[i] = ext;
  95.     ext->index = i;
  96.     ext->base = i + EXTENSION_BASE;
  97.     ext->CloseDown = CloseDownProc;
  98.     ext->MinorOpcode = MinorOpcodeProc;
  99.     ProcVector[i + EXTENSION_BASE] = MainProc;
  100.     SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
  101.     if (NumEvents)
  102.     {
  103.         ext->eventBase = lastEvent;
  104.     ext->eventLast = lastEvent + NumEvents;
  105.     lastEvent += NumEvents;
  106.     }
  107.     else
  108.     {
  109.         ext->eventBase = 0;
  110.         ext->eventLast = 0;
  111.     }
  112.     if (NumErrors)
  113.     {
  114.         ext->errorBase = lastError;
  115.     ext->errorLast = lastError + NumErrors;
  116.     lastError += NumErrors;
  117.     }
  118.     else
  119.     {
  120.         ext->errorBase = 0;
  121.         ext->errorLast = 0;
  122.     }
  123.     return(ext);
  124. }
  125.  
  126. Bool AddExtensionAlias(alias, ext)
  127.     char *alias;
  128.     ExtensionEntry *ext;
  129. {
  130.     char *name;
  131.     char **aliases;
  132.  
  133.     aliases = (char **)xrealloc(ext->aliases,
  134.                 (ext->num_aliases + 1) * sizeof(char *));
  135.     if (!aliases)
  136.     return FALSE;
  137.     ext->aliases = aliases;
  138.     name = (char *)xalloc(strlen(alias) + 1);
  139.     if (!name)
  140.     return FALSE;
  141.     strcpy(name,  alias);
  142.     ext->aliases[ext->num_aliases] = name;
  143.     ext->num_aliases++;
  144.     return TRUE;
  145. }
  146.  
  147. unsigned short
  148. StandardMinorOpcode(client)
  149.     ClientPtr client;
  150. {
  151.     return ((xReq *)client->requestBuffer)->data;
  152. }
  153.  
  154. unsigned short
  155. MinorOpcodeOfRequest(client)
  156.     ClientPtr client;
  157. {
  158.     unsigned char major;
  159.  
  160.     major = ((xReq *)client->requestBuffer)->reqType;
  161.     if (major < EXTENSION_BASE)
  162.     return 0;
  163.     major -= EXTENSION_BASE;
  164.     if (major >= NumExtensions)
  165.     return 0;
  166.     return (*extensions[major]->MinorOpcode)(client);
  167. }
  168.  
  169. CloseDownExtensions()
  170. {
  171.     register int i,j;
  172.  
  173.     for (i = NumExtensions - 1; i >= 0; i--)
  174.     {
  175.     (* extensions[i]->CloseDown)(extensions[i]);
  176.     NumExtensions = i;
  177.     xfree(extensions[i]->name);
  178.     for (j = extensions[i]->num_aliases; --j >= 0;)
  179.         xfree(extensions[i]->aliases[j]);
  180.     xfree(extensions[i]->aliases);
  181.     xfree(extensions[i]);
  182.     }
  183.     xfree(extensions);
  184.     extensions = (ExtensionEntry **)NULL;
  185.     lastEvent = EXTENSION_EVENT_BASE;
  186.     lastError = FirstExtensionError;
  187.     for (i=0; i<MAXSCREENS; i++)
  188.     {
  189.     register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
  190.  
  191.     while (spentry->num)
  192.     {
  193.         spentry->num--;
  194.         xfree(spentry->procList[spentry->num].name);
  195.     }
  196.     xfree(spentry->procList);
  197.     spentry->procList = (ProcEntryPtr)NULL;
  198.     }
  199. }
  200.  
  201.  
  202.  
  203. int
  204. ProcQueryExtension(client)
  205.     ClientPtr client;
  206. {
  207.     xQueryExtensionReply reply;
  208.     int i, j;
  209.     REQUEST(xQueryExtensionReq);
  210.  
  211.     REQUEST_AT_LEAST_SIZE(xQueryExtensionReq);
  212.     
  213.     reply.type = X_Reply;
  214.     reply.length = 0;
  215.     reply.major_opcode = 0;
  216.     reply.sequenceNumber = client->sequence;
  217.  
  218.     if ( ! NumExtensions )
  219.         reply.present = xFalse;
  220.     else
  221.     {
  222.         for (i=0; i<NumExtensions; i++)
  223.     {
  224.             if ((strlen(extensions[i]->name) == stuff->nbytes) &&
  225.                  !strncmp((char *)&stuff[1], extensions[i]->name,
  226.               (int)stuff->nbytes))
  227.                  break;
  228.         for (j = extensions[i]->num_aliases; --j >= 0;)
  229.         {
  230.         if ((strlen(extensions[i]->aliases[j]) == stuff->nbytes) &&
  231.              !strncmp((char *)&stuff[1], extensions[i]->aliases[j],
  232.                   (int)stuff->nbytes))
  233.              break;
  234.         }
  235.         if (j >= 0) break;
  236.     }
  237.         if (i == NumExtensions)
  238.             reply.present = xFalse;
  239.         else
  240.         {            
  241.             reply.present = xTrue;
  242.         reply.major_opcode = extensions[i]->base;
  243.         reply.first_event = extensions[i]->eventBase;
  244.         reply.first_error = extensions[i]->errorBase;
  245.     }
  246.     }
  247.     WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
  248.     return(client->noClientException);
  249. }
  250.  
  251. int
  252. ProcListExtensions(client)
  253.     ClientPtr client;
  254. {
  255.     xListExtensionsReply reply;
  256.     char *bufptr, *buffer;
  257.     int total_length = 0;
  258.  
  259.     REQUEST(xReq);
  260.     REQUEST_SIZE_MATCH(xReq);
  261.  
  262.     reply.type = X_Reply;
  263.     reply.nExtensions = NumExtensions;
  264.     reply.length = 0;
  265.     reply.sequenceNumber = client->sequence;
  266.     buffer = NULL;
  267.  
  268.     if ( NumExtensions )
  269.     {
  270.         register int i, j;
  271.  
  272.         for (i=0;  i<NumExtensions; i++)
  273.     {
  274.         total_length += strlen(extensions[i]->name) + 1;
  275.         reply.nExtensions += extensions[i]->num_aliases;
  276.         for (j = extensions[i]->num_aliases; --j >= 0;)
  277.         total_length += strlen(extensions[i]->aliases[j]) + 1;
  278.     }
  279.         reply.length = (total_length + 3) >> 2;
  280.     buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
  281.     if (!buffer)
  282.         return(BadAlloc);
  283.         for (i=0;  i<NumExtensions; i++)
  284.         {
  285.         int len;
  286.             *bufptr++ = len = strlen(extensions[i]->name);
  287.         bcopy(extensions[i]->name, bufptr,  len);
  288.         bufptr += len;
  289.         for (j = extensions[i]->num_aliases; --j >= 0;)
  290.         {
  291.         *bufptr++ = len = strlen(extensions[i]->aliases[j]);
  292.         bcopy(extensions[i]->aliases[j], bufptr,  len);
  293.         bufptr += len;
  294.         }
  295.     }
  296.     }
  297.     WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
  298.     if (reply.length)
  299.     {
  300.         WriteToClient(client, total_length, buffer);
  301.         DEALLOCATE_LOCAL(buffer);
  302.     }
  303.     return(client->noClientException);
  304. }
  305.  
  306.  
  307. ExtensionLookupProc 
  308. LookupProc(name, pGC)
  309.     char *name;
  310.     GCPtr pGC;
  311. {
  312.     register int i;
  313.     register ScreenProcEntry *spentry;
  314.     spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
  315.     if (spentry->num)    
  316.     {
  317.         for (i = 0; i < spentry->num; i++)
  318.             if (strcmp(name, spentry->procList[i].name) == 0)
  319.                 return(spentry->procList[i].proc);
  320.     }
  321.     return (ExtensionLookupProc)NULL;
  322. }
  323.  
  324. Bool
  325. RegisterProc(name, pGC, proc)
  326.     char *name;
  327.     GC *pGC;
  328.     ExtensionLookupProc proc;
  329. {
  330.     return RegisterScreenProc(name, pGC->pScreen, proc);
  331. }
  332.  
  333. Bool
  334. RegisterScreenProc(name, pScreen, proc)
  335.     char *name;
  336.     ScreenPtr pScreen;
  337.     ExtensionLookupProc proc;
  338. {
  339.     register ScreenProcEntry *spentry;
  340.     register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
  341.     char *newname;
  342.     int i;
  343.  
  344.     spentry = &AuxillaryScreenProcs[pScreen->myNum];
  345.     /* first replace duplicates */
  346.     if (spentry->num)
  347.     {
  348.         for (i = 0; i < spentry->num; i++)
  349.             if (strcmp(name, spentry->procList[i].name) == 0)
  350.         {
  351.                 procEntry = &spentry->procList[i];
  352.         break;
  353.         }
  354.     }
  355.     if (procEntry)
  356.         procEntry->proc = proc;
  357.     else
  358.     {
  359.     newname = (char *)xalloc(strlen(name)+1);
  360.     if (!newname)
  361.         return FALSE;
  362.     procEntry = (ProcEntryPtr)
  363.                 xrealloc(spentry->procList,
  364.                      sizeof(ProcEntryRec) * (spentry->num+1));
  365.     if (!procEntry)
  366.     {
  367.         xfree(newname);
  368.         return FALSE;
  369.     }
  370.     spentry->procList = procEntry;
  371.         procEntry += spentry->num;
  372.         procEntry->name = newname;
  373.         strcpy(newname, name);
  374.         procEntry->proc = proc;
  375.         spentry->num++;        
  376.     }
  377.     return TRUE;
  378. }
  379.