home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / XKBMAlloc.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  32KB  |  1,099 lines

  1. /* $XConsortium: XKBMAlloc.c /main/7 1996/03/01 14:29:44 kaleb $ */
  2. /* $XFree86: xc/lib/X11/XKBMAlloc.c,v 3.7.4.1 1998/10/04 13:36:22 hohndel Exp $ */
  3. /************************************************************
  4. Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
  5.  
  6. Permission to use, copy, modify, and distribute this
  7. software and its documentation for any purpose and without
  8. fee is hereby granted, provided that the above copyright
  9. notice appear in all copies and that both that copyright
  10. notice and this permission notice appear in supporting
  11. documentation, and that the name of Silicon Graphics not be 
  12. used in advertising or publicity pertaining to distribution 
  13. of the software without specific prior written permission.
  14. Silicon Graphics makes no representation about the suitability 
  15. of this software for any purpose. It is provided "as is"
  16. without any express or implied warranty.
  17.  
  18. SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
  19. SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
  20. AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
  21. GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
  22. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
  23. DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
  24. OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  25. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  
  27. ********************************************************/
  28.  
  29. #ifndef XKB_IN_SERVER
  30.  
  31. #include <stdio.h>
  32. #define NEED_REPLIES
  33. #define NEED_EVENTS
  34. #include "Xlib_private.h"
  35. #include <X11/extensions/XKBproto.h>
  36. #include <X11/keysym.h>
  37. #include "XKBlibint.h"
  38.  
  39. #else 
  40.  
  41. #include <stdio.h>
  42. #include "X.h"
  43. #define    NEED_EVENTS
  44. #define    NEED_REPLIES
  45. #include "Xproto.h"
  46. #include "misc.h"
  47. #include "inputstr.h"
  48. #include <X11/keysym.h>
  49. #define    XKBSRV_NEED_FILE_FUNCS
  50. #include "XKBsrv.h"
  51.  
  52. #endif /* XKB_IN_SERVER */
  53.  
  54. /***====================================================================***/
  55.  
  56. Status
  57. #if NeedFunctionPrototypes
  58. XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
  59. #else
  60. XkbAllocClientMap(xkb,which,nTotalTypes)
  61.     XkbDescPtr        xkb;
  62.     unsigned        which;
  63.     unsigned        nTotalTypes;
  64. #endif
  65. {
  66.     DBUG_ENTER("XkbAllocClientMap")
  67.     register int    i;
  68.     XkbClientMapPtr map;
  69.  
  70.     if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
  71.     DBUG_RETURN(BadValue);
  72.     if ((which&XkbKeySymsMask)&&
  73.     ((!XkbIsLegalKeycode(xkb->min_key_code))||
  74.      (!XkbIsLegalKeycode(xkb->max_key_code))||
  75.      (xkb->max_key_code<xkb->min_key_code))) {
  76. #ifdef DEBUG
  77. fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n",
  78.                 xkb->min_key_code,xkb->max_key_code);
  79. #endif
  80.     DBUG_RETURN(BadValue);
  81.     }
  82.  
  83.     if (xkb->map==NULL) {
  84.     map= _XkbTypedCalloc(1,XkbClientMapRec);
  85.     if (map==NULL)
  86.         DBUG_RETURN(BadAlloc);
  87.     xkb->map= map;
  88.     }
  89.     else map= xkb->map;
  90.  
  91.     if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
  92.     if (map->types==NULL) {
  93.         map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec);
  94.         if (map->types==NULL)
  95.         DBUG_RETURN(BadAlloc);
  96.         map->num_types= 0;
  97.         map->size_types= nTotalTypes;
  98.     }
  99.     else if (map->size_types<nTotalTypes) {
  100.         XkbKeyTypeRec *prev_types = map->types;
  101.  
  102.         map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec);
  103.         if (map->types==NULL) {
  104.         _XkbFree(prev_types);
  105.         map->num_types= map->size_types= 0;
  106.         DBUG_RETURN(BadAlloc);
  107.         }
  108.         map->size_types= nTotalTypes;
  109.         bzero(&map->types[map->num_types], 
  110.           ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
  111.     }
  112.     }
  113.     if (which&XkbKeySymsMask) {
  114.     int nKeys= XkbNumKeys(xkb);
  115.     if (map->syms==NULL) {
  116.         map->size_syms= (nKeys*15)/10;
  117.         map->syms= _XkbTypedCalloc(map->size_syms,KeySym);
  118.         if (!map->syms) {
  119.         map->size_syms= 0;
  120.         DBUG_RETURN(BadAlloc);
  121.         }
  122.         map->num_syms= 1;
  123.         map->syms[0]= NoSymbol;
  124.     }
  125.     if (map->key_sym_map==NULL) {
  126.         i= xkb->max_key_code+1;
  127.         map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec);
  128.         if (map->key_sym_map==NULL)
  129.         DBUG_RETURN(BadAlloc);
  130.     }
  131.     }
  132.     if (which&XkbModifierMapMask) {
  133.     if ((!XkbIsLegalKeycode(xkb->min_key_code))||
  134.         (!XkbIsLegalKeycode(xkb->max_key_code))||
  135.         (xkb->max_key_code<xkb->min_key_code))
  136.         DBUG_RETURN(BadMatch);
  137.     if (map->modmap==NULL) {
  138.         i= xkb->max_key_code+1;
  139.         map->modmap= _XkbTypedCalloc(i,unsigned char);
  140.         if (map->modmap==NULL)
  141.         DBUG_RETURN(BadAlloc);
  142.     }
  143.     }
  144.     DBUG_RETURN(Success);
  145. }
  146.  
  147. Status
  148. #if NeedFunctionPrototypes
  149. XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
  150. #else
  151. XkbAllocServerMap(xkb,which,nNewActions)
  152.     XkbDescPtr        xkb;
  153.     unsigned        which;
  154.     unsigned        nNewActions;
  155. #endif
  156. {
  157.     DBUG_ENTER("XkbAllocServerMap")
  158.     register int    i;
  159.     XkbServerMapPtr map;
  160.  
  161.     if (xkb==NULL)
  162.     DBUG_RETURN(BadMatch);
  163.     if (xkb->server==NULL) {
  164.     map= _XkbTypedCalloc(1,XkbServerMapRec);
  165.     if (map==NULL)
  166.         DBUG_RETURN(BadAlloc);
  167.     for (i=0;i<XkbNumVirtualMods;i++) {
  168.         map->vmods[i]= XkbNoModifierMask;
  169.     }
  170.     xkb->server= map;
  171.     }
  172.     else map= xkb->server;
  173.     if (which&XkbExplicitComponentsMask) {
  174.     if ((!XkbIsLegalKeycode(xkb->min_key_code))||
  175.         (!XkbIsLegalKeycode(xkb->max_key_code))||
  176.         (xkb->max_key_code<xkb->min_key_code))
  177.         DBUG_RETURN(BadMatch);
  178.     if (map->explicit==NULL) {
  179.         i= xkb->max_key_code+1;
  180.         map->explicit= _XkbTypedCalloc(i,unsigned char);
  181.         if (map->explicit==NULL)
  182.         DBUG_RETURN(BadAlloc);
  183.     }
  184.     }
  185.     if (which&XkbKeyActionsMask) {
  186.     if ((!XkbIsLegalKeycode(xkb->min_key_code))||
  187.         (!XkbIsLegalKeycode(xkb->max_key_code))||
  188.         (xkb->max_key_code<xkb->min_key_code))
  189.         DBUG_RETURN(BadMatch);
  190.         if (nNewActions<1)
  191.         nNewActions= 1;
  192.     if (map->acts==NULL) {
  193.         map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction);
  194.         if (map->acts==NULL)
  195.         DBUG_RETURN(BadAlloc);
  196.         map->num_acts= 1;
  197.         map->size_acts= nNewActions+1;
  198.     }
  199.     else if ((map->size_acts-map->num_acts)<nNewActions) {
  200.         unsigned need;
  201.         XkbAction *prev_acts = map->acts;
  202.         need= map->num_acts+nNewActions;
  203.         map->acts= _XkbTypedRealloc(map->acts,need,XkbAction);
  204.         if (map->acts==NULL) {
  205.         _XkbFree(prev_acts);
  206.             map->num_acts= map->size_acts= 0;
  207.             DBUG_RETURN(BadAlloc);
  208.         }
  209.         map->size_acts= need;
  210.         bzero(&map->acts[map->num_acts], 
  211.             ((map->size_acts-map->num_acts)*sizeof(XkbAction)));
  212.     }
  213.     if (map->key_acts==NULL) {
  214.         i= xkb->max_key_code+1;
  215.         map->key_acts= _XkbTypedCalloc(i,unsigned short);
  216.         if (map->key_acts==NULL)
  217.         DBUG_RETURN(BadAlloc);
  218.     }
  219.     }
  220.     if (which&XkbKeyBehaviorsMask) {
  221.     if ((!XkbIsLegalKeycode(xkb->min_key_code))||
  222.         (!XkbIsLegalKeycode(xkb->max_key_code))||
  223.         (xkb->max_key_code<xkb->min_key_code))
  224.         DBUG_RETURN(BadMatch);
  225.     if (map->behaviors==NULL) {
  226.         i= xkb->max_key_code+1;
  227.         map->behaviors= _XkbTypedCalloc(i,XkbBehavior);
  228.         if (map->behaviors==NULL)
  229.         DBUG_RETURN(BadAlloc);
  230.     }
  231.     }
  232.     if (which&XkbVirtualModMapMask) {
  233.     if ((!XkbIsLegalKeycode(xkb->min_key_code))||
  234.         (!XkbIsLegalKeycode(xkb->max_key_code))||
  235.         (xkb->max_key_code<xkb->min_key_code))
  236.         DBUG_RETURN(BadMatch);
  237.     if (map->vmodmap==NULL) {
  238.         i= xkb->max_key_code+1;
  239.         map->vmodmap= _XkbTypedCalloc(i,unsigned short);
  240.         if (map->vmodmap==NULL)
  241.         DBUG_RETURN(BadAlloc);
  242.     }
  243.     }
  244.     DBUG_RETURN(Success);
  245. }
  246.  
  247. /***====================================================================***/
  248.  
  249. Status
  250. #if NeedFunctionPrototypes
  251. XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
  252. #else
  253. XkbCopyKeyType(from,into)
  254.     XkbKeyTypePtr    from;
  255.     XkbKeyTypePtr    into;
  256. #endif
  257. {
  258.     DBUG_ENTER("XkbCopyKeyType")
  259.     if ((!from)||(!into))
  260.     DBUG_RETURN(BadMatch);
  261.     if (into->map) {
  262.     _XkbFree(into->map);
  263.     into->map= NULL;
  264.     }
  265.     if (into->preserve) {
  266.     _XkbFree(into->preserve);
  267.     into->preserve= NULL;
  268.     }
  269.     if (into->level_names) {
  270.     _XkbFree(into->level_names);
  271.     into->level_names= NULL;
  272.     }
  273.     *into= *from;
  274.     if ((from->map)&&(into->map_count>0)) {
  275.     into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec);
  276.     if (!into->map)
  277.         DBUG_RETURN(BadAlloc);
  278.     memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
  279.     }
  280.     if ((from->preserve)&&(into->map_count>0)) {
  281.     into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec);
  282.     if (!into->preserve)
  283.         DBUG_RETURN(BadAlloc);
  284.     memcpy(into->preserve,from->preserve,
  285.                 into->map_count*sizeof(XkbModsRec));
  286.     }
  287.     if ((from->level_names)&&(into->num_levels>0)) {
  288.     into->level_names= _XkbTypedCalloc(into->num_levels,Atom);
  289.     if (!into->level_names)
  290.         DBUG_RETURN(BadAlloc);
  291.     memcpy(into->level_names,from->level_names,
  292.                  into->num_levels*sizeof(Atom));
  293.     }
  294.     DBUG_RETURN(Success);
  295. }
  296.  
  297. Status
  298. #if NeedFunctionPrototypes
  299. XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
  300. #else
  301. XkbCopyKeyTypes(from,into,num_types)
  302.     XkbKeyTypePtr    from;
  303.     XkbKeyTypePtr    into;
  304.     int            num_types;
  305. #endif
  306. {
  307.     DBUG_ENTER("XkbCopyKeyTypes")
  308.     register int i,rtrn;
  309.  
  310.     if ((!from)||(!into)||(num_types<0))
  311.     DBUG_RETURN(BadMatch);
  312.     for (i=0;i<num_types;i++) {
  313.     if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
  314.         DBUG_RETURN(rtrn);
  315.     }
  316.     DBUG_RETURN(Success);
  317. }
  318.  
  319. XkbKeyTypePtr
  320. #if NeedFunctionPrototypes
  321. XkbAddKeyType(    XkbDescPtr    xkb,
  322.         Atom         name,
  323.         int         map_count,
  324.         Bool         want_preserve,
  325.         int        num_lvls)
  326. #else
  327. XkbAddKeyType(xkb,name,map_count,want_preserve,num_lvls)
  328.     XkbDescPtr    xkb;
  329.     Atom    name;
  330.     int        map_count;
  331.     Bool    want_preserve;
  332.     int        num_lvls;
  333. #endif
  334. {
  335.     DBUG_ENTER("XkbAddKeyType")
  336.     register int     i;
  337.     unsigned    tmp;
  338.     XkbKeyTypePtr    type;
  339.     XkbClientMapPtr    map;
  340.  
  341.     if ((!xkb)||(num_lvls<1))
  342.     DBUG_RETURN(NULL);
  343.     map= xkb->map;
  344.     if ((map)&&(map->types)) {
  345.     for (i=0;i<map->num_types;i++) {
  346.         if (map->types[i].name==name) {
  347.         Status status;
  348.         status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls);
  349.         DBUG_RETURN(status==Success?&map->types[i]:NULL);
  350.         }
  351.     }
  352.     }
  353.     if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) {
  354.     tmp= XkbNumRequiredTypes+1;
  355.     if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success)
  356.         DBUG_RETURN(NULL);
  357.     tmp= 0;
  358.     if (map->num_types<=XkbKeypadIndex)
  359.         tmp|= XkbKeypadMask;
  360.     if (map->num_types<=XkbAlphabeticIndex)
  361.         tmp|= XkbAlphabeticMask;
  362.     if (map->num_types<=XkbTwoLevelIndex)
  363.         tmp|= XkbTwoLevelMask;
  364.     if (map->num_types<=XkbOneLevelIndex)
  365.         tmp|= XkbOneLevelMask;
  366.     if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) {
  367.         for (i=0;i<map->num_types;i++) {
  368.         Status status;
  369.         if (map->types[i].name!=name)
  370.             continue;
  371.         status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls);
  372.         DBUG_RETURN(status==Success?&map->types[i]:NULL);
  373.         }
  374.     }
  375.     }
  376.     if ((map->num_types<=map->size_types)&&
  377.     (XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) {
  378.     DBUG_RETURN(NULL);
  379.     }
  380.     type= &map->types[map->num_types];
  381.     map->num_types++;
  382.     bzero((char *)type,sizeof(XkbKeyTypeRec));
  383.     type->num_levels=    num_lvls;
  384.     type->map_count=    map_count;
  385.     type->name=        name;
  386.     if (map_count>0) {
  387.     type->map=    _XkbTypedCalloc(map_count,XkbKTMapEntryRec);
  388.     if (!type->map) {
  389.         map->num_types--;
  390.         DBUG_RETURN(NULL);
  391.     }
  392.     if (want_preserve) {
  393.         type->preserve=    _XkbTypedCalloc(map_count,XkbModsRec);
  394.         if (!type->preserve) {
  395.         _XkbFree(type->map);
  396.         map->num_types--;
  397.         DBUG_RETURN(NULL);
  398.         }
  399.     }
  400.     }
  401.     DBUG_RETURN(type);
  402. }
  403.  
  404. Status
  405. #if NeedFunctionPrototypes
  406. XkbResizeKeyType(    XkbDescPtr    xkb,
  407.             int        type_ndx,
  408.             int        map_count,
  409.             Bool        want_preserve,
  410.             int        new_num_lvls)
  411. #else
  412. XkbResizeKeyType(xkb,type_ndx,map_count,want_preserve,new_num_lvls)
  413.     XkbDescPtr        xkb;
  414.     int            type_ndx;
  415.     int            map_count;
  416.     Bool        want_preserve;
  417.     int            new_num_lvls;
  418. #endif
  419. {
  420.     DBUG_ENTER("XkbResizeKeyType")
  421.     XkbKeyTypePtr    type;
  422.     KeyCode        matchingKeys[XkbMaxKeyCount],nMatchingKeys;
  423.  
  424.     if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
  425.                                 (new_num_lvls<1))
  426.     DBUG_RETURN(BadValue);
  427.     switch (type_ndx) {
  428.     case XkbOneLevelIndex:
  429.         if (new_num_lvls!=1)
  430.         DBUG_RETURN(BadMatch);
  431.         break;
  432.     case XkbTwoLevelIndex:
  433.     case XkbAlphabeticIndex:
  434.     case XkbKeypadIndex:
  435.         if (new_num_lvls!=2)
  436.         DBUG_RETURN(BadMatch);
  437.         break;
  438.     }
  439.     type= &xkb->map->types[type_ndx];
  440.     if (map_count==0) {
  441.     if (type->map!=NULL)
  442.         _XkbFree(type->map);
  443.     type->map= NULL;
  444.     if (type->preserve!=NULL)
  445.         _XkbFree(type->preserve);
  446.     type->preserve= NULL;
  447.     type->map_count= 0;
  448.     }
  449.     else {
  450.     XkbKTMapEntryRec *prev_map = type->map;
  451.  
  452.     if ((map_count>type->map_count)||(type->map==NULL))
  453.         type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec);
  454.     if (!type->map) {
  455.         if (prev_map) 
  456.         _XkbFree(prev_map);
  457.         DBUG_RETURN(BadAlloc);
  458.     }
  459.     if (want_preserve) {
  460.         XkbModsRec *prev_preserve = type->preserve;
  461.  
  462.         if ((map_count>type->map_count)||(type->preserve==NULL)) {
  463.         type->preserve= _XkbTypedRealloc(type->preserve,map_count,
  464.                                      XkbModsRec);
  465.         }
  466.         if (!type->preserve) {
  467.         if (prev_preserve) 
  468.             _XkbFree(prev_preserve);
  469.         DBUG_RETURN(BadAlloc);
  470.         }
  471.     }
  472.     else if (type->preserve!=NULL) {
  473.         _XkbFree(type->preserve);
  474.         type->preserve= NULL;
  475.     }
  476.     type->map_count= map_count;
  477.     }
  478.  
  479.     if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
  480.     Atom * prev_level_names = type->level_names;
  481.  
  482.     type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom);
  483.     if (!type->level_names) {
  484.         if (prev_level_names) 
  485.         _XkbFree(prev_level_names);
  486.         DBUG_RETURN(BadAlloc);
  487.     }
  488.     }
  489.     /*
  490.      * Here's the theory:
  491.      *    If the width of the type changed, we might have to resize the symbol
  492.      * maps for any keys that use the type for one or more groups.  This is
  493.      * expensive, so we'll try to cull out any keys that are obviously okay:
  494.      * In any case:
  495.      *    - keys that have a group width <= the old width are okay (because
  496.      *      they could not possibly have been associated with the old type)
  497.      * If the key type increased in size:
  498.      *    - keys that already have a group width >= to the new width are okay
  499.      *    + keys that have a group width >= the old width but < the new width
  500.      *      might have to be enlarged.
  501.      * If the key type decreased in size:
  502.      *    - keys that have a group width > the old width don't have to be
  503.      *      resized (because they must have some other wider type associated 
  504.      *      with some group).
  505.      *    + keys that have a group width == the old width might have to be
  506.      *      shrunk.
  507.      * The possibilities marked with '+' require us to examine the key types
  508.      * associated with each group for the key.
  509.      */
  510.     bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
  511.     nMatchingKeys= 0;
  512.     if (new_num_lvls>type->num_levels) {
  513.     int             nTotal;
  514.     KeySym    *        newSyms;
  515.     int            width,match,nResize;
  516.     register int        i,g,nSyms;
  517.  
  518.     nResize= 0;
  519.     for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
  520.         width= XkbKeyGroupsWidth(xkb,i);
  521.         if (width<type->num_levels)
  522.         continue;
  523.         for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
  524.         if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
  525.             matchingKeys[nMatchingKeys++]= i;
  526.             match= 1;
  527.         }
  528.         }
  529.         if ((!match)||(width>=new_num_lvls))
  530.         nTotal+= XkbKeyNumSyms(xkb,i);
  531.         else {
  532.         nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
  533.         nResize++;
  534.         }
  535.     }
  536.     if (nResize>0) {
  537.         int nextMatch;
  538.         xkb->map->size_syms= (nTotal*12)/10;
  539.         newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym);
  540.         if (newSyms==NULL)
  541.         DBUG_RETURN(BadAlloc);
  542.         nextMatch= 0;
  543.         nSyms= 1;
  544.         for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
  545.         if (matchingKeys[nextMatch]==i) {
  546.             KeySym *pOld;
  547.             nextMatch++;
  548.             width= XkbKeyGroupsWidth(xkb,i);
  549.             pOld= XkbKeySymsPtr(xkb,i);
  550.             for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
  551.             memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
  552.                             width*sizeof(KeySym));
  553.             }
  554.             xkb->map->key_sym_map[i].offset= nSyms;
  555.             nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
  556.         }
  557.         else {
  558.             memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
  559.                     XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
  560.             xkb->map->key_sym_map[i].offset= nSyms;
  561.             nSyms+= XkbKeyNumSyms(xkb,i);
  562.         }
  563.         }
  564.         type->num_levels= new_num_lvls;
  565.         _XkbFree(xkb->map->syms);
  566.         xkb->map->syms= newSyms;
  567.         xkb->map->num_syms= nSyms;
  568.         DBUG_RETURN(Success);
  569.     }
  570.     }
  571.     else if (new_num_lvls<type->num_levels) {
  572.     int         width,match;
  573.     register int    g,i;
  574.     for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
  575.         width= XkbKeyGroupsWidth(xkb,i);
  576.         if (width<type->num_levels)
  577.         continue;
  578.         for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
  579.         if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
  580.             matchingKeys[nMatchingKeys++]= i;
  581.             match= 1;
  582.         }
  583.         }
  584.     }
  585.     }
  586.     if (nMatchingKeys>0) {
  587.     int         key,firstClear;
  588.     register int    i,g;
  589.     if (new_num_lvls>type->num_levels)
  590.          firstClear= type->num_levels;
  591.     else firstClear= new_num_lvls;
  592.     for (i=0;i<nMatchingKeys;i++) {
  593.         KeySym *    pSyms;
  594.         int        width,nClear;
  595.  
  596.         key= matchingKeys[i];
  597.         width= XkbKeyGroupsWidth(xkb,key);
  598.         nClear= width-firstClear;
  599.         pSyms= XkbKeySymsPtr(xkb,key);
  600.         for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
  601.         if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
  602.             if (nClear>0)
  603.             bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
  604.         }
  605.         }
  606.     }
  607.     }
  608.     type->num_levels= new_num_lvls;
  609.     DBUG_RETURN(Success);
  610. }
  611.  
  612. KeySym *
  613. #if NeedFunctionPrototypes
  614. XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
  615. #else
  616. XkbResizeKeySyms(xkb,key,needed)
  617.     XkbDescPtr    xkb;
  618.     int     key;
  619.     int     needed;
  620. #endif
  621. {
  622.     DBUG_ENTER("XkbResizeKeySyms")
  623.     register int i,nSyms,nKeySyms;
  624.     unsigned nOldSyms;
  625.     KeySym    *newSyms, result;
  626.  
  627.     if (needed==0) {
  628.     xkb->map->key_sym_map[key].offset= 0;
  629.     result = xkb->map->syms;
  630.     DBUG_RETURN(result);
  631.     }
  632.     nOldSyms= XkbKeyNumSyms(xkb,key);
  633.     if (nOldSyms>=(unsigned)needed) {
  634.     result = XkbKeySymsPtr(xkb,key);
  635.     DBUG_RETURN(result);
  636.     }
  637.     if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
  638.     if (nOldSyms>0) {
  639.         memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
  640.                         nOldSyms*sizeof(KeySym));
  641.     }
  642.     if ((needed-nOldSyms)>0) {
  643.         bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
  644.                     (needed-nOldSyms)*sizeof(KeySym));
  645.     }
  646.     xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
  647.     xkb->map->num_syms+= needed;
  648.     result = &xkb->map->syms[xkb->map->key_sym_map[key].offset];
  649.     DBUG_RETURN(result);
  650.     }
  651.     xkb->map->size_syms+= (needed>32?needed:32);
  652.     newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym);
  653.     if (newSyms==NULL)
  654.     DBUG_RETURN(NULL);
  655.     newSyms[0]= NoSymbol;
  656.     nSyms = 1;
  657.     for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
  658.     int nCopy;
  659.  
  660.     nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
  661.     if ((nKeySyms==0)&&(i!=key))
  662.         continue;
  663.     if (i==key)
  664.         nKeySyms= needed;
  665.     if (nCopy!=0)
  666.        memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
  667.     if (nKeySyms>nCopy)
  668.         bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
  669.     xkb->map->key_sym_map[i].offset = nSyms;
  670.     nSyms+= nKeySyms;
  671.     }
  672.     _XkbFree(xkb->map->syms);
  673.     xkb->map->syms = newSyms;
  674.     xkb->map->num_syms = nSyms;
  675.     result = &xkb->map->syms[xkb->map->key_sym_map[key].offset];
  676.     DBUG_RETURN(result);
  677. }
  678.  
  679. static unsigned
  680. #if NeedFunctionPrototypes
  681. _ExtendRange(    unsigned int     old_flags,
  682.         unsigned int    flag,
  683.         KeyCode        newKC,
  684.         KeyCode *    old_min,
  685.         unsigned char *    old_num)
  686. #else
  687. _ExtendRange(old_flags,flag,newKC,old_min,old_num)
  688.     unsigned int    old_flags;
  689.     unsigned int    flag;
  690.     KeyCode        newKC;
  691.     KeyCode *        old_min;
  692.     unsigned char *    old_num;
  693. #endif
  694. {
  695.     DBUG_ENTER("_ExtendRange")
  696.     if ((old_flags&flag)==0) {
  697.     old_flags|= flag;
  698.     *old_min= newKC;
  699.     *old_num= 1;
  700.     }
  701.     else {
  702.     int    last= (*old_min)+(*old_num)-1;
  703.     if (newKC<*old_min) {
  704.         *old_min= newKC;
  705.         *old_num= (last-newKC)+1;
  706.     }
  707.     else if (newKC>last) {
  708.         *old_num= (newKC-(*old_min))+1;
  709.     }
  710.     }
  711.     DBUG_RETURN(old_flags);
  712. }
  713.  
  714. Status
  715. #if NeedFunctionPrototypes
  716. XkbChangeKeycodeRange(    XkbDescPtr    xkb,
  717.             int         minKC,
  718.             int         maxKC,
  719.             XkbChangesPtr    changes)
  720. #else
  721. XkbChangeKeycodeRange(xkb,minKC,maxKC,changes)
  722.     XkbDescPtr        xkb;
  723.     int         minKC;
  724.     int         maxKC;
  725.     XkbChangesPtr    changes;
  726. #endif
  727. {
  728.     DBUG_ENTER("XkbChangeKeycodeRange")
  729.     int    tmp;
  730.  
  731.     if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
  732.     DBUG_RETURN(BadValue);
  733.     if (minKC>maxKC)
  734.     DBUG_RETURN(BadMatch);
  735.     if (minKC<xkb->min_key_code) {
  736.     if (changes)
  737.         changes->map.min_key_code= minKC;
  738.     tmp= xkb->min_key_code-minKC;
  739.     if (xkb->map)  {
  740.         if (xkb->map->key_sym_map) {
  741.         bzero((char *)&xkb->map->key_sym_map[minKC],
  742.                     tmp*sizeof(XkbSymMapRec));
  743.         if (changes) {
  744.             changes->map.changed= _ExtendRange(changes->map.changed,
  745.                             XkbKeySymsMask,minKC,
  746.                             &changes->map.first_key_sym,
  747.                             &changes->map.num_key_syms);
  748.         }
  749.         }
  750.         if (xkb->map->modmap) {
  751.         bzero((char *)&xkb->map->modmap[minKC],tmp);
  752.         if (changes) {
  753.             changes->map.changed= _ExtendRange(changes->map.changed,
  754.                             XkbModifierMapMask,minKC,
  755.                             &changes->map.first_modmap_key,
  756.                             &changes->map.num_modmap_keys);
  757.         }
  758.         }
  759.     }
  760.     if (xkb->server) {
  761.         if (xkb->server->behaviors) {
  762.         bzero((char *)&xkb->server->behaviors[minKC],
  763.                         tmp*sizeof(XkbBehavior));
  764.         if (changes) {
  765.             changes->map.changed= _ExtendRange(changes->map.changed,
  766.                         XkbKeyBehaviorsMask,minKC,
  767.                         &changes->map.first_key_behavior,
  768.                         &changes->map.num_key_behaviors);
  769.         }
  770.         }
  771.         if (xkb->server->key_acts) {
  772.         bzero((char *)&xkb->server->key_acts[minKC],
  773.                         tmp*sizeof(unsigned short));
  774.         if (changes) {
  775.             changes->map.changed= _ExtendRange(changes->map.changed,
  776.                         XkbKeyActionsMask,minKC,
  777.                         &changes->map.first_key_act,
  778.                         &changes->map.num_key_acts);
  779.         }
  780.         }
  781.         if (xkb->server->vmodmap) {
  782.         bzero((char *)&xkb->server->vmodmap[minKC],
  783.                         tmp*sizeof(unsigned short));
  784.         if (changes) {
  785.             changes->map.changed= _ExtendRange(changes->map.changed,
  786.                         XkbVirtualModMapMask,minKC,
  787.                         &changes->map.first_modmap_key,
  788.                         &changes->map.num_vmodmap_keys);
  789.         }
  790.         }
  791.     }
  792.     if ((xkb->names)&&(xkb->names->keys)) {
  793.         bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
  794.         if (changes) {
  795.         changes->names.changed= _ExtendRange(changes->names.changed,
  796.                     XkbKeyNamesMask,minKC,
  797.                     &changes->names.first_key,
  798.                         &changes->names.num_keys);
  799.         }
  800.     }
  801.     xkb->min_key_code= minKC;
  802.     }
  803.     if (maxKC>xkb->max_key_code) {
  804.     if (changes)
  805.         changes->map.max_key_code= maxKC;
  806.     tmp= maxKC-xkb->max_key_code;
  807.     if (xkb->map)  {
  808.         if (xkb->map->key_sym_map) {
  809.         XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
  810.  
  811.         xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map,
  812.                         (maxKC+1),XkbSymMapRec);
  813.         if (!xkb->map->key_sym_map) {
  814.             _XkbFree(prev_key_sym_map);
  815.             DBUG_RETURN(BadAlloc);
  816.         }
  817.         bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
  818.                     tmp*sizeof(XkbSymMapRec));
  819.         if (changes) {
  820.             changes->map.changed= _ExtendRange(changes->map.changed,
  821.                             XkbKeySymsMask,maxKC,
  822.                             &changes->map.first_key_sym,
  823.                             &changes->map.num_key_syms);
  824.         }
  825.         }
  826.         if (xkb->map->modmap) {
  827.         unsigned char *prev_modmap = xkb->map->modmap;
  828.  
  829.         xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap,
  830.                         (maxKC+1),unsigned char);
  831.         if (!xkb->map->modmap) {
  832.             _XkbFree(prev_modmap);
  833.             DBUG_RETURN(BadAlloc);
  834.         }
  835.         bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
  836.         if (changes) {
  837.             changes->map.changed= _ExtendRange(changes->map.changed,
  838.                             XkbModifierMapMask,maxKC,
  839.                             &changes->map.first_modmap_key,
  840.                             &changes->map.num_modmap_keys);
  841.         }
  842.         }
  843.     }
  844.     if (xkb->server) {
  845.         if (xkb->server->behaviors) {
  846.         XkbBehavior *prev_behaviors = xkb->server->behaviors;
  847.  
  848.         xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors,
  849.                         (maxKC+1),XkbBehavior);
  850.         if (!xkb->server->behaviors) {
  851.             _XkbFree(prev_behaviors);
  852.             DBUG_RETURN(BadAlloc);
  853.         }
  854.         bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
  855.                         tmp*sizeof(XkbBehavior));
  856.         if (changes) {
  857.             changes->map.changed= _ExtendRange(changes->map.changed,
  858.                         XkbKeyBehaviorsMask,maxKC,
  859.                         &changes->map.first_key_behavior,
  860.                         &changes->map.num_key_behaviors);
  861.         }
  862.         }
  863.         if (xkb->server->key_acts) {
  864.         unsigned short *prev_key_acts = xkb->server->key_acts;
  865.  
  866.         xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts,
  867.                         (maxKC+1),unsigned short);
  868.         if (!xkb->server->key_acts) {
  869.             _XkbFree(prev_key_acts);
  870.             DBUG_RETURN(BadAlloc);
  871.         }
  872.         bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
  873.                         tmp*sizeof(unsigned short));
  874.         if (changes) {
  875.             changes->map.changed= _ExtendRange(changes->map.changed,
  876.                         XkbKeyActionsMask,maxKC,
  877.                         &changes->map.first_key_act,
  878.                         &changes->map.num_key_acts);
  879.         }
  880.         }
  881.         if (xkb->server->vmodmap) {
  882.         unsigned short *prev_vmodmap = xkb->server->vmodmap;
  883.  
  884.         xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap,
  885.                         (maxKC+1),unsigned short);
  886.         if (!xkb->server->vmodmap) {
  887.             _XkbFree(prev_vmodmap);
  888.             DBUG_RETURN(BadAlloc);
  889.         }
  890.         bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
  891.                         tmp*sizeof(unsigned short));
  892.         if (changes) {
  893.             changes->map.changed= _ExtendRange(changes->map.changed,
  894.                         XkbVirtualModMapMask,maxKC,
  895.                         &changes->map.first_modmap_key,
  896.                         &changes->map.num_vmodmap_keys);
  897.         }
  898.         }
  899.     }
  900.     if ((xkb->names)&&(xkb->names->keys)) {
  901.         XkbKeyNameRec *prev_keys = xkb->names->keys;
  902.  
  903.         xkb->names->keys= _XkbTypedRealloc(xkb->names->keys,
  904.                             (maxKC+1),XkbKeyNameRec);
  905.         if (!xkb->names->keys) {
  906.         _XkbFree(prev_keys);
  907.         DBUG_RETURN(BadAlloc);
  908.         }
  909.         bzero((char *)&xkb->names->keys[xkb->max_key_code],
  910.                             tmp*sizeof(XkbKeyNameRec));
  911.         if (changes) {
  912.         changes->names.changed= _ExtendRange(changes->names.changed,
  913.                     XkbKeyNamesMask,maxKC,
  914.                     &changes->names.first_key,
  915.                         &changes->names.num_keys);
  916.         }
  917.     }
  918.     xkb->max_key_code= maxKC;
  919.     }
  920.     DBUG_RETURN(Success);
  921. }
  922.  
  923. XkbAction *
  924. #if NeedFunctionPrototypes
  925. XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
  926. #else
  927. XkbResizeKeyActions(xkb,key,needed)
  928.     XkbDescPtr    xkb;
  929.     int     key;
  930.     int     needed;
  931. #endif
  932. {
  933.     DBUG_ENTER("XkbResizeKeyActions")
  934.     register int i,nActs;
  935.     XkbAction *newActs, *result;
  936.  
  937.     if (needed==0) {
  938.     xkb->server->key_acts[key]= 0;
  939.     DBUG_RETURN(NULL);
  940.     }
  941.     if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) {
  942.     result = XkbKeyActionsPtr(xkb,key);
  943.     DBUG_RETURN(result);
  944.     }
  945.     if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
  946.     xkb->server->key_acts[key]= xkb->server->num_acts;
  947.     xkb->server->num_acts+= needed;
  948.     result = &xkb->server->acts[xkb->server->key_acts[key]];
  949.     DBUG_RETURN(result);
  950.     }
  951.     xkb->server->size_acts= xkb->server->num_acts+needed+8;
  952.     newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction);
  953.     if (newActs==NULL)
  954.     DBUG_RETURN(NULL);
  955.     newActs[0].type = XkbSA_NoAction;
  956.     nActs = 1;
  957.     for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
  958.     int nKeyActs,nCopy;
  959.  
  960.     if ((xkb->server->key_acts[i]==0)&&(i!=key))
  961.         continue;
  962.  
  963.     nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
  964.     if (i==key) {
  965.         nKeyActs= needed;
  966.         if (needed<nCopy)
  967.         nCopy= needed;
  968.     }
  969.  
  970.     if (nCopy>0)
  971.         memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
  972.                         nCopy*sizeof(XkbAction));
  973.     if (nCopy<nKeyActs)
  974.         bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
  975.     xkb->server->key_acts[i]= nActs;
  976.     nActs+= nKeyActs;
  977.     }
  978.     _XkbFree(xkb->server->acts);
  979.     xkb->server->acts = newActs;
  980.     xkb->server->num_acts= nActs;
  981.     result = &xkb->server->acts[xkb->server->key_acts[key]];
  982.     DBUG_RETURN(result);
  983. }
  984.  
  985. void
  986. #if NeedFunctionPrototypes
  987. XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
  988. #else
  989. XkbFreeClientMap(xkb,what,freeMap)
  990.     XkbDescPtr    xkb;
  991.     unsigned    what;
  992.     Bool    freeMap;
  993. #endif
  994. {
  995.     DBUG_ENTER("XkbFreeClientMap")
  996.     XkbClientMapPtr    map;
  997.  
  998.     if ((xkb==NULL)||(xkb->map==NULL))
  999.     DBUG_VOID_RETURN;
  1000.     if (freeMap)
  1001.     what= XkbAllClientInfoMask;
  1002.     map= xkb->map;
  1003.     if (what&XkbKeyTypesMask) {
  1004.     if (map->types!=NULL) {
  1005.         if (map->num_types>0) {
  1006.         register int     i;
  1007.         XkbKeyTypePtr    type;
  1008.         for (i=0,type=map->types;i<map->num_types;i++,type++) {
  1009.             if (type->map!=NULL) {
  1010.             _XkbFree(type->map);
  1011.             type->map= NULL;
  1012.             }
  1013.             if (type->preserve!=NULL) {
  1014.             _XkbFree(type->preserve);
  1015.             type->preserve= NULL;
  1016.             }
  1017.             type->map_count= 0;
  1018.             if (type->level_names!=NULL) {
  1019.             _XkbFree(type->level_names);
  1020.             type->level_names= NULL;
  1021.             }
  1022.         }
  1023.         }
  1024.         _XkbFree(map->types);
  1025.         map->num_types= map->size_types= 0;
  1026.         map->types= NULL;
  1027.     }
  1028.     }
  1029.     if (what&XkbKeySymsMask) {
  1030.     if (map->key_sym_map!=NULL) {
  1031.         _XkbFree(map->key_sym_map);
  1032.         map->key_sym_map= NULL;
  1033.     }
  1034.     if (map->syms!=NULL) {
  1035.         _XkbFree(map->syms);
  1036.         map->size_syms= map->num_syms= 0;
  1037.         map->syms= NULL;
  1038.     }
  1039.     }
  1040.     if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
  1041.     _XkbFree(map->modmap);
  1042.     map->modmap= NULL;
  1043.     }
  1044.     if (freeMap) {
  1045.     _XkbFree(xkb->map);
  1046.     xkb->map= NULL;
  1047.     }
  1048.     DBUG_VOID_RETURN;
  1049. }
  1050.  
  1051. void
  1052. #if NeedFunctionPrototypes
  1053. XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
  1054. #else
  1055. XkbFreeServerMap(xkb,what,freeMap)
  1056.     XkbDescPtr    xkb;
  1057.     unsigned    what;
  1058.     Bool    freeMap;
  1059. #endif
  1060. {
  1061.     DBUG_ENTER("XkbFreeServerMap")
  1062.     XkbServerMapPtr    map;
  1063.  
  1064.     if ((xkb==NULL)||(xkb->server==NULL))
  1065.     DBUG_VOID_RETURN;
  1066.     if (freeMap)
  1067.     what= XkbAllServerInfoMask;
  1068.     map= xkb->server;
  1069.     if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
  1070.     _XkbFree(map->explicit);
  1071.     map->explicit= NULL;
  1072.     }
  1073.     if (what&XkbKeyActionsMask) {
  1074.     if (map->key_acts!=NULL) {
  1075.         _XkbFree(map->key_acts);
  1076.         map->key_acts= NULL;
  1077.     }
  1078.     if (map->acts!=NULL) {
  1079.         _XkbFree(map->acts);
  1080.         map->num_acts= map->size_acts= 0;
  1081.         map->acts= NULL;
  1082.     }
  1083.     }
  1084.     if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
  1085.     _XkbFree(map->behaviors);
  1086.     map->behaviors= NULL;
  1087.     }
  1088.     if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
  1089.     _XkbFree(map->vmodmap);
  1090.     map->vmodmap= NULL;
  1091.     }
  1092.  
  1093.     if (freeMap) {
  1094.     _XkbFree(xkb->server);
  1095.     xkb->server= NULL;
  1096.     }
  1097.     DBUG_VOID_RETURN;
  1098. }
  1099.