1706f2543Smrg/************************************************************ 2706f2543SmrgCopyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 3706f2543Smrg 4706f2543SmrgPermission to use, copy, modify, and distribute this 5706f2543Smrgsoftware and its documentation for any purpose and without 6706f2543Smrgfee is hereby granted, provided that the above copyright 7706f2543Smrgnotice appear in all copies and that both that copyright 8706f2543Smrgnotice and this permission notice appear in supporting 9706f2543Smrgdocumentation, and that the name of Silicon Graphics not be 10706f2543Smrgused in advertising or publicity pertaining to distribution 11706f2543Smrgof the software without specific prior written permission. 12706f2543SmrgSilicon Graphics makes no representation about the suitability 13706f2543Smrgof this software for any purpose. It is provided "as is" 14706f2543Smrgwithout any express or implied warranty. 15706f2543Smrg 16706f2543SmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17706f2543SmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18706f2543SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19706f2543SmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20706f2543SmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543SmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22706f2543SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23706f2543SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg 25706f2543Smrg********************************************************/ 26706f2543Smrg 27706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 28706f2543Smrg#include <dix-config.h> 29706f2543Smrg#endif 30706f2543Smrg 31706f2543Smrg#include <stdio.h> 32706f2543Smrg#include <ctype.h> 33706f2543Smrg#include <X11/X.h> 34706f2543Smrg#include <X11/Xos.h> 35706f2543Smrg#include <X11/Xproto.h> 36706f2543Smrg#include <X11/keysym.h> 37706f2543Smrg#include <X11/extensions/XKM.h> 38706f2543Smrg#include "inputstr.h" 39706f2543Smrg#include "scrnintstr.h" 40706f2543Smrg#include "windowstr.h" 41706f2543Smrg#define XKBSRV_NEED_FILE_FUNCS 42706f2543Smrg#include <xkbsrv.h> 43706f2543Smrg#include <X11/extensions/XI.h> 44706f2543Smrg 45706f2543Smrg#ifdef WIN32 46706f2543Smrg/* from ddxLoad.c */ 47706f2543Smrgextern const char* Win32TempDir(); 48706f2543Smrgextern int Win32System(const char *cmdline); 49706f2543Smrg#undef System 50706f2543Smrg#define System Win32System 51706f2543Smrg 52706f2543Smrg#define W32_tmparg " '%s'" 53706f2543Smrg#define W32_tmpfile ,tmpname 54706f2543Smrg#define W32_tmplen strlen(tmpname)+3 55706f2543Smrg#else 56706f2543Smrg#define W32_tmparg 57706f2543Smrg#define W32_tmpfile 58706f2543Smrg#define W32_tmplen 0 59706f2543Smrg#endif 60706f2543Smrg 61706f2543Smrg/***====================================================================***/ 62706f2543Smrg 63706f2543Smrgstatic char *componentDirs[_XkbListNumComponents] = { 64706f2543Smrg "keycodes", "types", "compat", "symbols", "geometry" 65706f2543Smrg}; 66706f2543Smrg 67706f2543Smrg/***====================================================================***/ 68706f2543Smrg 69706f2543Smrgstatic Status 70706f2543Smrg_AddListComponent( XkbSrvListInfoPtr list, 71706f2543Smrg int what, 72706f2543Smrg unsigned flags, 73706f2543Smrg char * str, 74706f2543Smrg ClientPtr client) 75706f2543Smrg{ 76706f2543Smrgint slen,wlen; 77706f2543Smrgunsigned char * wire8; 78706f2543Smrgunsigned short *wire16; 79706f2543Smrgchar * tmp; 80706f2543Smrg 81706f2543Smrg if (list->nTotal>=list->maxRtrn) { 82706f2543Smrg list->nTotal++; 83706f2543Smrg return Success; 84706f2543Smrg } 85706f2543Smrg tmp= strchr(str,')'); 86706f2543Smrg if ((tmp==NULL)&&((tmp=strchr(str,'('))==NULL)) { 87706f2543Smrg slen= strlen(str); 88706f2543Smrg while ((slen>0) && isspace(str[slen-1])) { 89706f2543Smrg slen--; 90706f2543Smrg } 91706f2543Smrg } 92706f2543Smrg else { 93706f2543Smrg slen= (tmp-str+1); 94706f2543Smrg } 95706f2543Smrg wlen= (((slen+1)/2)*2)+4; /* four bytes for flags and length, pad to */ 96706f2543Smrg /* 2-byte boundary */ 97706f2543Smrg if ((list->szPool-list->nPool)<wlen) { 98706f2543Smrg if (wlen>1024) list->szPool+= XkbPaddedSize(wlen*2); 99706f2543Smrg else list->szPool+= 1024; 100706f2543Smrg list->pool= realloc(list->pool, list->szPool * sizeof(char)); 101706f2543Smrg if (!list->pool) 102706f2543Smrg return BadAlloc; 103706f2543Smrg } 104706f2543Smrg wire16= (unsigned short *)&list->pool[list->nPool]; 105706f2543Smrg wire8= (unsigned char *)&wire16[2]; 106706f2543Smrg wire16[0]= flags; 107706f2543Smrg wire16[1]= slen; 108706f2543Smrg memcpy(wire8,str,slen); 109706f2543Smrg if (client->swapped) { 110706f2543Smrg register int n; 111706f2543Smrg swaps(&wire16[0],n); 112706f2543Smrg swaps(&wire16[1],n); 113706f2543Smrg } 114706f2543Smrg list->nPool+= wlen; 115706f2543Smrg list->nFound[what]++; 116706f2543Smrg list->nTotal++; 117706f2543Smrg return Success; 118706f2543Smrg} 119706f2543Smrg 120706f2543Smrg/***====================================================================***/ 121706f2543Smrgstatic Status 122706f2543SmrgXkbDDXListComponent( DeviceIntPtr dev, 123706f2543Smrg int what, 124706f2543Smrg XkbSrvListInfoPtr list, 125706f2543Smrg ClientPtr client) 126706f2543Smrg{ 127706f2543Smrgchar *file,*map,*tmp,*buf=NULL; 128706f2543SmrgFILE *in; 129706f2543SmrgStatus status; 130706f2543Smrgint rval; 131706f2543SmrgBool haveDir; 132706f2543Smrg#ifdef WIN32 133706f2543Smrgchar tmpname[PATH_MAX]; 134706f2543Smrg#endif 135706f2543Smrg 136706f2543Smrg if ((list->pattern[what]==NULL)||(list->pattern[what][0]=='\0')) 137706f2543Smrg return Success; 138706f2543Smrg file= list->pattern[what]; 139706f2543Smrg map= strrchr(file,'('); 140706f2543Smrg if (map!=NULL) { 141706f2543Smrg char *tmp; 142706f2543Smrg map++; 143706f2543Smrg tmp= strrchr(map,')'); 144706f2543Smrg if ((tmp==NULL)||(tmp[1]!='\0')) { 145706f2543Smrg /* illegal pattern. No error, but no match */ 146706f2543Smrg return Success; 147706f2543Smrg } 148706f2543Smrg } 149706f2543Smrg 150706f2543Smrg in= NULL; 151706f2543Smrg haveDir= TRUE; 152706f2543Smrg#ifdef WIN32 153706f2543Smrg strcpy(tmpname, Win32TempDir()); 154706f2543Smrg strcat(tmpname, "\\xkb_XXXXXX"); 155706f2543Smrg (void) mktemp(tmpname); 156706f2543Smrg#endif 157706f2543Smrg if (XkbBaseDirectory!=NULL) { 158706f2543Smrg if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) { 159706f2543Smrg if (asprintf(&buf, "%s/%s.dir", XkbBaseDirectory, 160706f2543Smrg componentDirs[what]) == -1) 161706f2543Smrg buf = NULL; 162706f2543Smrg else 163706f2543Smrg in = fopen(buf,"r"); 164706f2543Smrg } 165706f2543Smrg if (!in) { 166706f2543Smrg haveDir= FALSE; 167706f2543Smrg free(buf); 168706f2543Smrg if (asprintf 169706f2543Smrg (&buf, 170706f2543Smrg "'%s/xkbcomp' '-R%s/%s' -w %ld -l -vlfhpR '%s'" W32_tmparg, 171706f2543Smrg XkbBinDirectory, XkbBaseDirectory, componentDirs[what], 172706f2543Smrg (long) ((xkbDebugFlags < 2) ? 1 : 173706f2543Smrg ((xkbDebugFlags > 10) ? 10 : xkbDebugFlags)), 174706f2543Smrg file W32_tmpfile 175706f2543Smrg ) == -1) 176706f2543Smrg buf = NULL; 177706f2543Smrg } 178706f2543Smrg } 179706f2543Smrg else { 180706f2543Smrg if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) { 181706f2543Smrg if (asprintf(&buf, "%s.dir", componentDirs[what]) == -1) 182706f2543Smrg buf = NULL; 183706f2543Smrg else 184706f2543Smrg in = fopen(buf,"r"); 185706f2543Smrg } 186706f2543Smrg if (!in) { 187706f2543Smrg haveDir= FALSE; 188706f2543Smrg free(buf); 189706f2543Smrg if (asprintf 190706f2543Smrg (&buf, 191706f2543Smrg "xkbcomp -R%s -w %ld -l -vlfhpR '%s'" W32_tmparg, 192706f2543Smrg componentDirs[what], 193706f2543Smrg (long) ((xkbDebugFlags < 2) ? 1 : 194706f2543Smrg ((xkbDebugFlags > 10) ? 10 : xkbDebugFlags)), 195706f2543Smrg file W32_tmpfile 196706f2543Smrg ) == -1) 197706f2543Smrg buf = NULL; 198706f2543Smrg } 199706f2543Smrg } 200706f2543Smrg status= Success; 201706f2543Smrg if (!haveDir) 202706f2543Smrg { 203706f2543Smrg#ifndef WIN32 204706f2543Smrg in= Popen(buf,"r"); 205706f2543Smrg#else 206706f2543Smrg if (xkbDebugFlags) 207706f2543Smrg DebugF("[xkb] xkbList executes: %s\n",buf); 208706f2543Smrg if (System(buf) < 0) 209706f2543Smrg ErrorF("[xkb] Could not invoke keymap compiler\n"); 210706f2543Smrg else 211706f2543Smrg in= fopen(tmpname, "r"); 212706f2543Smrg#endif 213706f2543Smrg } 214706f2543Smrg if (!in) 215706f2543Smrg { 216706f2543Smrg free(buf); 217706f2543Smrg#ifdef WIN32 218706f2543Smrg unlink(tmpname); 219706f2543Smrg#endif 220706f2543Smrg return BadImplementation; 221706f2543Smrg } 222706f2543Smrg list->nFound[what]= 0; 223706f2543Smrg free(buf); 224706f2543Smrg buf = malloc(PATH_MAX * sizeof(char)); 225706f2543Smrg if (!buf) { 226706f2543Smrg fclose(in); 227706f2543Smrg return BadAlloc; 228706f2543Smrg } 229706f2543Smrg while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) { 230706f2543Smrg unsigned flags; 231706f2543Smrg register unsigned int i; 232706f2543Smrg if (*tmp=='#') /* comment, skip it */ 233706f2543Smrg continue; 234706f2543Smrg if (!strncmp(tmp, "Warning:", 8) || !strncmp(tmp, " ", 8)) 235706f2543Smrg /* skip warnings too */ 236706f2543Smrg continue; 237706f2543Smrg flags= 0; 238706f2543Smrg /* each line in the listing is supposed to start with two */ 239706f2543Smrg /* groups of eight characters, which specify the general */ 240706f2543Smrg /* flags and the flags that are specific to the component */ 241706f2543Smrg /* if they're missing, fail with BadImplementation */ 242706f2543Smrg for (i=0;(i<8)&&(status==Success);i++) { /* read the general flags */ 243706f2543Smrg if (isalpha(*tmp)) flags|= (1L<<i); 244706f2543Smrg else if (*tmp!='-') status= BadImplementation; 245706f2543Smrg tmp++; 246706f2543Smrg } 247706f2543Smrg if (status != Success) break; 248706f2543Smrg if (!isspace(*tmp)) { 249706f2543Smrg status= BadImplementation; 250706f2543Smrg break; 251706f2543Smrg } 252706f2543Smrg else tmp++; 253706f2543Smrg for (i=0;(i<8)&&(status==Success);i++) { /* read the component flags */ 254706f2543Smrg if (isalpha(*tmp)) flags|= (1L<<(i+8)); 255706f2543Smrg else if (*tmp!='-') status= BadImplementation; 256706f2543Smrg tmp++; 257706f2543Smrg } 258706f2543Smrg if (status != Success) break; 259706f2543Smrg if (isspace(*tmp)) { 260706f2543Smrg while (isspace(*tmp)) { 261706f2543Smrg tmp++; 262706f2543Smrg } 263706f2543Smrg } 264706f2543Smrg else { 265706f2543Smrg status= BadImplementation; 266706f2543Smrg break; 267706f2543Smrg } 268706f2543Smrg status= _AddListComponent(list,what,flags,tmp,client); 269706f2543Smrg } 270706f2543Smrg#ifndef WIN32 271706f2543Smrg if (haveDir) 272706f2543Smrg fclose(in); 273706f2543Smrg else if ((rval=Pclose(in))!=0) { 274706f2543Smrg if (xkbDebugFlags) 275706f2543Smrg ErrorF("[xkb] xkbcomp returned exit code %d\n",rval); 276706f2543Smrg } 277706f2543Smrg#else 278706f2543Smrg fclose(in); 279706f2543Smrg unlink(tmpname); 280706f2543Smrg#endif 281706f2543Smrg free(buf); 282706f2543Smrg return status; 283706f2543Smrg} 284706f2543Smrg 285706f2543Smrg/***====================================================================***/ 286706f2543Smrg 287706f2543Smrg/* ARGSUSED */ 288706f2543SmrgStatus 289706f2543SmrgXkbDDXList(DeviceIntPtr dev,XkbSrvListInfoPtr list,ClientPtr client) 290706f2543Smrg{ 291706f2543SmrgStatus status; 292706f2543Smrg 293706f2543Smrg status= XkbDDXListComponent(dev,_XkbListKeycodes,list,client); 294706f2543Smrg if (status==Success) 295706f2543Smrg status= XkbDDXListComponent(dev,_XkbListTypes,list,client); 296706f2543Smrg if (status==Success) 297706f2543Smrg status= XkbDDXListComponent(dev,_XkbListCompat,list,client); 298706f2543Smrg if (status==Success) 299706f2543Smrg status= XkbDDXListComponent(dev,_XkbListSymbols,list,client); 300706f2543Smrg if (status==Success) 301706f2543Smrg status= XkbDDXListComponent(dev,_XkbListGeometry,list,client); 302706f2543Smrg return status; 303706f2543Smrg} 304