static PyObject * virtkey_get_layouts(PyObject * self, PyObject *args) { int inout = 20; int i=0; virtkey * cvirt = (virtkey *)self; XkbComponentNamesRec names; XkbComponentNamesPtr namesPtr = &names; namesPtr->keymap = "*"; XkbComponentListPtr components = XkbListComponents(cvirt->display, XkbUseCoreKbd,namesPtr,&inout); PyObject *tuple = PyTuple_New(components->num_keymaps); for(; i<components->num_keymaps; i++){ char *name = strdup(components->keymaps[i].name); //no error checking version of set_item because tuple is empty. PyTuple_SET_ITEM(tuple, i, PyString_FromString(name)); } XkbFreeComponentList(components); return tuple; }
XkbComponentListPtr XkbListComponents( Display * dpy, unsigned deviceSpec, XkbComponentNamesPtr ptrns, int * max_inout) { register xkbListComponentsReq* req; xkbListComponentsReply rep; XkbInfoPtr xkbi; XkbComponentListPtr list; XkbReadBufferRec buf; int left; char * str; int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen; if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) || (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || (ptrns==NULL) || (max_inout==NULL)) return NULL; xkbi= dpy->xkb_info; LockDisplay(dpy); GetReq(kbListComponents, req); req->reqType = xkbi->codes->major_opcode; req->xkbReqType = X_kbListComponents; req->deviceSpec = deviceSpec; req->maxNames = *max_inout; mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; if (ptrns->keymap) mapLen= (int)strlen(ptrns->keymap); if (ptrns->keycodes) codesLen= (int)strlen(ptrns->keycodes); if (ptrns->types) typesLen= (int)strlen(ptrns->types); if (ptrns->compat) compatLen= (int)strlen(ptrns->compat); if (ptrns->symbols) symsLen= (int)strlen(ptrns->symbols); if (ptrns->geometry) geomLen= (int)strlen(ptrns->geometry); if (mapLen>255) mapLen= 255; if (codesLen>255) codesLen= 255; if (typesLen>255) typesLen= 255; if (compatLen>255) compatLen= 255; if (symsLen>255) symsLen= 255; if (geomLen>255) geomLen= 255; len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6; len= XkbPaddedSize(len); req->length+= len/4; BufAlloc(char *,str,len); *str++= mapLen; if (mapLen>0) { memcpy(str,ptrns->keymap,mapLen); str+= mapLen; } *str++= codesLen; if (codesLen>0) { memcpy(str,ptrns->keycodes,codesLen); str+= codesLen; } *str++= typesLen; if (typesLen>0) { memcpy(str,ptrns->types,typesLen); str+= typesLen; } *str++= compatLen; if (compatLen>0) { memcpy(str,ptrns->compat,compatLen); str+= compatLen; } *str++= symsLen; if (symsLen>0) { memcpy(str,ptrns->symbols,symsLen); str+= symsLen; } *str++= geomLen; if (geomLen>0) { memcpy(str,ptrns->geometry,geomLen); str+= geomLen; } if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) goto BAILOUT; extraLen= (int)rep.length*4; *max_inout= rep.extra; if (extraLen==0) { /* no matches, but we don't want to report a failure */ list= _XkbTypedCalloc(1,XkbComponentListRec); UnlockDisplay(dpy); SyncHandle(); return list; } if (_XkbInitReadBuffer(dpy,&buf,extraLen)) { Status status; status= Success; list= _XkbTypedCalloc(1,XkbComponentListRec); if (!list) { _XkbFreeReadBuffer(&buf); goto BAILOUT; } list->num_keymaps= rep.nKeymaps; list->num_keycodes= rep.nKeycodes; list->num_types= rep.nTypes; list->num_compat= rep.nCompatMaps; list->num_symbols= rep.nSymbols; list->num_geometry= rep.nGeometries; if ((status==Success)&&(list->num_keymaps>0)) list->keymaps= _ReadListing(&buf,list->num_keymaps,&status); if ((status==Success)&&(list->num_keycodes>0)) list->keycodes= _ReadListing(&buf,list->num_keycodes,&status); if ((status==Success)&&(list->num_types>0)) list->types= _ReadListing(&buf,list->num_types,&status); if ((status==Success)&&(list->num_compat>0)) list->compat= _ReadListing(&buf,list->num_compat,&status); if ((status==Success)&&(list->num_symbols>0)) list->symbols= _ReadListing(&buf,list->num_symbols,&status); if ((status==Success)&&(list->num_geometry>0)) list->geometry= _ReadListing(&buf,list->num_geometry,&status); left= _XkbFreeReadBuffer(&buf); if ((status!=Success)||(buf.error)||(left>2)) { XkbFreeComponentList(list); goto BAILOUT; } UnlockDisplay(dpy); SyncHandle(); return list; } BAILOUT: UnlockDisplay(dpy); SyncHandle(); return NULL; }