XKBList.c revision e9fcaa8a
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_MAP_READERS 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 31#include "Xlibint.h" 32#include <X11/extensions/XKBproto.h> 33#include "XKBlibint.h" 34 35/***====================================================================***/ 36 37static void 38_FreeComponentNames(int num,XkbComponentNamePtr names) 39{ 40int i; 41XkbComponentNamePtr tmp; 42 43 if ((num<1)||(names==NULL)) 44 return; 45 for (i=0,tmp=names;i<num;i++,tmp++) { 46 if (tmp->name) { 47 _XkbFree(tmp->name); 48 tmp->name= NULL; 49 } 50 } 51 _XkbFree(names); 52 return; 53} 54 55/***====================================================================***/ 56 57static XkbComponentNamePtr 58_ReadListing(XkbReadBufferPtr buf,int count,Status *status_rtrn) 59{ 60XkbComponentNamePtr first,this; 61register int i; 62CARD16 * flags; 63int slen,wlen; 64char * str; 65 66 if (count<1) 67 return NULL; 68 first= _XkbTypedCalloc(count,XkbComponentNameRec); 69 if (!first) 70 return NULL; 71 for (this=first,i=0;i<count;i++,this++) { 72 flags= (CARD16 *)_XkbGetReadBufferPtr(buf,2*sizeof(CARD16)); 73 if (!flags) 74 goto BAILOUT; 75 this->flags= flags[0]; 76 slen= flags[1]; 77 wlen= ((slen+1)/2)*2; /* pad to 2 byte boundary */ 78 this->name= _XkbTypedCalloc(slen+1,char); 79 if (!this->name) 80 goto BAILOUT; 81 str= (char *)_XkbGetReadBufferPtr(buf,wlen); 82 memcpy(this->name,str,slen); 83 } 84 return first; 85BAILOUT: 86 *status_rtrn= BadAlloc; 87 _FreeComponentNames(i,first); 88 return NULL; 89} 90 91/***====================================================================***/ 92 93XkbComponentListPtr 94XkbListComponents( Display * dpy, 95 unsigned deviceSpec, 96 XkbComponentNamesPtr ptrns, 97 int * max_inout) 98{ 99register xkbListComponentsReq* req; 100xkbListComponentsReply rep; 101XkbInfoPtr xkbi; 102XkbComponentListPtr list; 103XkbReadBufferRec buf; 104int left; 105char * str; 106int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen; 107 108 if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) || 109 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || 110 (ptrns==NULL) || (max_inout==NULL)) 111 return NULL; 112 113 xkbi= dpy->xkb_info; 114 LockDisplay(dpy); 115 GetReq(kbListComponents, req); 116 req->reqType = xkbi->codes->major_opcode; 117 req->xkbReqType = X_kbListComponents; 118 req->deviceSpec = deviceSpec; 119 req->maxNames = *max_inout; 120 121 mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; 122 if (ptrns->keymap) 123 mapLen= (int)strlen(ptrns->keymap); 124 if (ptrns->keycodes) 125 codesLen= (int)strlen(ptrns->keycodes); 126 if (ptrns->types) 127 typesLen= (int)strlen(ptrns->types); 128 if (ptrns->compat) 129 compatLen= (int)strlen(ptrns->compat); 130 if (ptrns->symbols) 131 symsLen= (int)strlen(ptrns->symbols); 132 if (ptrns->geometry) 133 geomLen= (int)strlen(ptrns->geometry); 134 if (mapLen>255) mapLen= 255; 135 if (codesLen>255) codesLen= 255; 136 if (typesLen>255) typesLen= 255; 137 if (compatLen>255) compatLen= 255; 138 if (symsLen>255) symsLen= 255; 139 if (geomLen>255) geomLen= 255; 140 141 len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6; 142 len= XkbPaddedSize(len); 143 req->length+= len/4; 144 BufAlloc(char *,str,len); 145 *str++= mapLen; 146 if (mapLen>0) { 147 memcpy(str,ptrns->keymap,mapLen); 148 str+= mapLen; 149 } 150 *str++= codesLen; 151 if (codesLen>0) { 152 memcpy(str,ptrns->keycodes,codesLen); 153 str+= codesLen; 154 } 155 *str++= typesLen; 156 if (typesLen>0) { 157 memcpy(str,ptrns->types,typesLen); 158 str+= typesLen; 159 } 160 *str++= compatLen; 161 if (compatLen>0) { 162 memcpy(str,ptrns->compat,compatLen); 163 str+= compatLen; 164 } 165 *str++= symsLen; 166 if (symsLen>0) { 167 memcpy(str,ptrns->symbols,symsLen); 168 str+= symsLen; 169 } 170 *str++= geomLen; 171 if (geomLen>0) { 172 memcpy(str,ptrns->geometry,geomLen); 173 str+= geomLen; 174 } 175 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) 176 goto BAILOUT; 177 extraLen= (int)rep.length*4; 178 *max_inout= rep.extra; 179 if (extraLen==0) { /* no matches, but we don't want to report a failure */ 180 list= _XkbTypedCalloc(1,XkbComponentListRec); 181 UnlockDisplay(dpy); 182 SyncHandle(); 183 return list; 184 } 185 if (_XkbInitReadBuffer(dpy,&buf,extraLen)) { 186 Status status; 187 188 status= Success; 189 list= _XkbTypedCalloc(1,XkbComponentListRec); 190 if (!list) { 191 _XkbFreeReadBuffer(&buf); 192 goto BAILOUT; 193 } 194 list->num_keymaps= rep.nKeymaps; 195 list->num_keycodes= rep.nKeycodes; 196 list->num_types= rep.nTypes; 197 list->num_compat= rep.nCompatMaps; 198 list->num_symbols= rep.nSymbols; 199 list->num_geometry= rep.nGeometries; 200 if ((status==Success)&&(list->num_keymaps>0)) 201 list->keymaps= _ReadListing(&buf,list->num_keymaps,&status); 202 if ((status==Success)&&(list->num_keycodes>0)) 203 list->keycodes= _ReadListing(&buf,list->num_keycodes,&status); 204 if ((status==Success)&&(list->num_types>0)) 205 list->types= _ReadListing(&buf,list->num_types,&status); 206 if ((status==Success)&&(list->num_compat>0)) 207 list->compat= _ReadListing(&buf,list->num_compat,&status); 208 if ((status==Success)&&(list->num_symbols>0)) 209 list->symbols= _ReadListing(&buf,list->num_symbols,&status); 210 if ((status==Success)&&(list->num_geometry>0)) 211 list->geometry= _ReadListing(&buf,list->num_geometry,&status); 212 left= _XkbFreeReadBuffer(&buf); 213 if ((status!=Success)||(buf.error)||(left>2)) { 214 XkbFreeComponentList(list); 215 goto BAILOUT; 216 } 217 UnlockDisplay(dpy); 218 SyncHandle(); 219 return list; 220 } 221BAILOUT: 222 UnlockDisplay(dpy); 223 SyncHandle(); 224 return NULL; 225} 226 227void 228XkbFreeComponentList(XkbComponentListPtr list) 229{ 230 if (list) { 231 if (list->keymaps) 232 _FreeComponentNames(list->num_keymaps,list->keymaps); 233 if (list->keycodes) 234 _FreeComponentNames(list->num_keycodes,list->keycodes); 235 if (list->types) 236 _FreeComponentNames(list->num_types,list->types); 237 if (list->compat) 238 _FreeComponentNames(list->num_compat,list->compat); 239 if (list->symbols) 240 _FreeComponentNames(list->num_symbols,list->symbols); 241 if (list->geometry) 242 _FreeComponentNames(list->num_geometry,list->geometry); 243 bzero((char *)list,sizeof(XkbComponentListRec)); 244 _XkbFree(list); 245 } 246 return; 247} 248