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