XKBList.c revision 61b2299d
1/* $Xorg: XKBList.c,v 1.3 2000/08/17 19:45:02 cpqbld Exp $ */ 2/************************************************************ 3Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 4 5Permission to use, copy, modify, and distribute this 6software and its documentation for any purpose and without 7fee is hereby granted, provided that the above copyright 8notice appear in all copies and that both that copyright 9notice and this permission notice appear in supporting 10documentation, and that the name of Silicon Graphics not be 11used in advertising or publicity pertaining to distribution 12of the software without specific prior written permission. 13Silicon Graphics makes no representation about the suitability 14of this software for any purpose. It is provided "as is" 15without any express or implied warranty. 16 17SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26********************************************************/ 27/* $XFree86$ */ 28 29#define NEED_REPLIES 30#define NEED_EVENTS 31#define NEED_MAP_READERS 32#ifdef HAVE_CONFIG_H 33#include <config.h> 34#endif 35#include "Xlibint.h" 36#include <X11/extensions/XKBproto.h> 37#include "XKBlibint.h" 38 39/***====================================================================***/ 40 41static void 42_FreeComponentNames(int num,XkbComponentNamePtr names) 43{ 44int i; 45XkbComponentNamePtr tmp; 46 47 if ((num<1)||(names==NULL)) 48 return; 49 for (i=0,tmp=names;i<num;i++,tmp++) { 50 if (tmp->name) { 51 _XkbFree(tmp->name); 52 tmp->name= NULL; 53 } 54 } 55 _XkbFree(names); 56 return; 57} 58 59/***====================================================================***/ 60 61static XkbComponentNamePtr 62_ReadListing(XkbReadBufferPtr buf,int count,Status *status_rtrn) 63{ 64XkbComponentNamePtr first,this; 65register int i; 66CARD16 * flags; 67int slen,wlen; 68char * str; 69 70 if (count<1) 71 return NULL; 72 first= _XkbTypedCalloc(count,XkbComponentNameRec); 73 if (!first) 74 return NULL; 75 for (this=first,i=0;i<count;i++,this++) { 76 flags= (CARD16 *)_XkbGetReadBufferPtr(buf,2*sizeof(CARD16)); 77 if (!flags) 78 goto BAILOUT; 79 this->flags= flags[0]; 80 slen= flags[1]; 81 wlen= ((slen+1)/2)*2; /* pad to 2 byte boundary */ 82 this->name= _XkbTypedCalloc(slen+1,char); 83 if (!this->name) 84 goto BAILOUT; 85 str= (char *)_XkbGetReadBufferPtr(buf,wlen); 86 memcpy(this->name,str,slen); 87 } 88 return first; 89BAILOUT: 90 *status_rtrn= BadAlloc; 91 _FreeComponentNames(i,first); 92 return NULL; 93} 94 95/***====================================================================***/ 96 97XkbComponentListPtr 98XkbListComponents( Display * dpy, 99 unsigned deviceSpec, 100 XkbComponentNamesPtr ptrns, 101 int * max_inout) 102{ 103register xkbListComponentsReq* req; 104xkbListComponentsReply rep; 105XkbInfoPtr xkbi; 106XkbComponentListPtr list; 107XkbReadBufferRec buf; 108int left; 109char * str; 110int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen; 111 112 if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) || 113 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || 114 (ptrns==NULL) || (max_inout==NULL)) 115 return NULL; 116 117 xkbi= dpy->xkb_info; 118 LockDisplay(dpy); 119 GetReq(kbListComponents, req); 120 req->reqType = xkbi->codes->major_opcode; 121 req->xkbReqType = X_kbListComponents; 122 req->deviceSpec = deviceSpec; 123 req->maxNames = *max_inout; 124 125 mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; 126 if (ptrns->keymap) 127 mapLen= (int)strlen(ptrns->keymap); 128 if (ptrns->keycodes) 129 codesLen= (int)strlen(ptrns->keycodes); 130 if (ptrns->types) 131 typesLen= (int)strlen(ptrns->types); 132 if (ptrns->compat) 133 compatLen= (int)strlen(ptrns->compat); 134 if (ptrns->symbols) 135 symsLen= (int)strlen(ptrns->symbols); 136 if (ptrns->geometry) 137 geomLen= (int)strlen(ptrns->geometry); 138 if (mapLen>255) mapLen= 255; 139 if (codesLen>255) codesLen= 255; 140 if (typesLen>255) typesLen= 255; 141 if (compatLen>255) compatLen= 255; 142 if (symsLen>255) symsLen= 255; 143 if (geomLen>255) geomLen= 255; 144 145 len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6; 146 len= XkbPaddedSize(len); 147 req->length+= len/4; 148 BufAlloc(char *,str,len); 149 *str++= mapLen; 150 if (mapLen>0) { 151 memcpy(str,ptrns->keymap,mapLen); 152 str+= mapLen; 153 } 154 *str++= codesLen; 155 if (codesLen>0) { 156 memcpy(str,ptrns->keycodes,codesLen); 157 str+= codesLen; 158 } 159 *str++= typesLen; 160 if (typesLen>0) { 161 memcpy(str,ptrns->types,typesLen); 162 str+= typesLen; 163 } 164 *str++= compatLen; 165 if (compatLen>0) { 166 memcpy(str,ptrns->compat,compatLen); 167 str+= compatLen; 168 } 169 *str++= symsLen; 170 if (symsLen>0) { 171 memcpy(str,ptrns->symbols,symsLen); 172 str+= symsLen; 173 } 174 *str++= geomLen; 175 if (geomLen>0) { 176 memcpy(str,ptrns->geometry,geomLen); 177 str+= geomLen; 178 } 179 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) 180 goto BAILOUT; 181 extraLen= (int)rep.length*4; 182 *max_inout= rep.extra; 183 if (extraLen==0) { /* no matches, but we don't want to report a failure */ 184 list= _XkbTypedCalloc(1,XkbComponentListRec); 185 UnlockDisplay(dpy); 186 SyncHandle(); 187 return list; 188 } 189 if (_XkbInitReadBuffer(dpy,&buf,extraLen)) { 190 Status status; 191 192 status= Success; 193 list= _XkbTypedCalloc(1,XkbComponentListRec); 194 if (!list) { 195 _XkbFreeReadBuffer(&buf); 196 goto BAILOUT; 197 } 198 list->num_keymaps= rep.nKeymaps; 199 list->num_keycodes= rep.nKeycodes; 200 list->num_types= rep.nTypes; 201 list->num_compat= rep.nCompatMaps; 202 list->num_symbols= rep.nSymbols; 203 list->num_geometry= rep.nGeometries; 204 if ((status==Success)&&(list->num_keymaps>0)) 205 list->keymaps= _ReadListing(&buf,list->num_keymaps,&status); 206 if ((status==Success)&&(list->num_keycodes>0)) 207 list->keycodes= _ReadListing(&buf,list->num_keycodes,&status); 208 if ((status==Success)&&(list->num_types>0)) 209 list->types= _ReadListing(&buf,list->num_types,&status); 210 if ((status==Success)&&(list->num_compat>0)) 211 list->compat= _ReadListing(&buf,list->num_compat,&status); 212 if ((status==Success)&&(list->num_symbols>0)) 213 list->symbols= _ReadListing(&buf,list->num_symbols,&status); 214 if ((status==Success)&&(list->num_geometry>0)) 215 list->geometry= _ReadListing(&buf,list->num_geometry,&status); 216 left= _XkbFreeReadBuffer(&buf); 217 if ((status!=Success)||(buf.error)||(left>2)) { 218 XkbFreeComponentList(list); 219 goto BAILOUT; 220 } 221 UnlockDisplay(dpy); 222 SyncHandle(); 223 return list; 224 } 225BAILOUT: 226 UnlockDisplay(dpy); 227 SyncHandle(); 228 return NULL; 229} 230 231void 232XkbFreeComponentList(XkbComponentListPtr list) 233{ 234 if (list) { 235 if (list->keymaps) 236 _FreeComponentNames(list->num_keymaps,list->keymaps); 237 if (list->keycodes) 238 _FreeComponentNames(list->num_keycodes,list->keycodes); 239 if (list->types) 240 _FreeComponentNames(list->num_types,list->types); 241 if (list->compat) 242 _FreeComponentNames(list->num_compat,list->compat); 243 if (list->symbols) 244 _FreeComponentNames(list->num_symbols,list->symbols); 245 if (list->geometry) 246 _FreeComponentNames(list->num_geometry,list->geometry); 247 bzero((char *)list,sizeof(XkbComponentListRec)); 248 _XkbFree(list); 249 } 250 return; 251} 252