xkbevd.c revision db17cd6d
176910425Smrg/* $Xorg: xkbevd.c,v 1.4 2000/08/17 19:54:49 cpqbld Exp $ */ 276910425Smrg/************************************************************ 376910425Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 476910425Smrg 576910425Smrg Permission to use, copy, modify, and distribute this 676910425Smrg software and its documentation for any purpose and without 776910425Smrg fee is hereby granted, provided that the above copyright 876910425Smrg notice appear in all copies and that both that copyright 976910425Smrg notice and this permission notice appear in supporting 1076910425Smrg documentation, and that the name of Silicon Graphics not be 1176910425Smrg used in advertising or publicity pertaining to distribution 1276910425Smrg of the software without specific prior written permission. 1376910425Smrg Silicon Graphics makes no representation about the suitability 1476910425Smrg of this software for any purpose. It is provided "as is" 1576910425Smrg without any express or implied warranty. 1676910425Smrg 1776910425Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1876910425Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1976910425Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 2076910425Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2176910425Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2276910425Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2376910425Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2476910425Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 2576910425Smrg 2676910425Smrg ********************************************************/ 2776910425Smrg/* $XFree86: xc/programs/xkbevd/xkbevd.c,v 3.8 2001/01/17 23:46:09 dawes Exp $ */ 2876910425Smrg 2976910425Smrg#define DEBUG_VAR xkbevdDebug 3076910425Smrg#include <X11/Xosdefs.h> 3176910425Smrg#include <stdlib.h> 3276910425Smrg#include "xkbevd.h" 3376910425Smrg 3476910425Smrg 3576910425Smrg#define lowbit(x) ((x) & (-(x))) 3676910425Smrg 3776910425Smrg/***====================================================================***/ 3876910425Smrg 3976910425Smrg#ifndef DFLT_XKBEVD_CONFIG 4076910425Smrg#define DFLT_XKBEVD_CONFIG "%s/.xkb/xkbevd.cf" 4176910425Smrg#endif /* DFLT_XKBEVD_CONFIG */ 4276910425Smrg 4376910425Smrg#ifndef DFLT_XKB_CONFIG_ROOT 4476910425Smrg#define DFLT_XKB_CONFIG_ROOT "/usr/X11R6/lib/xkb" 4576910425Smrg#endif 4676910425Smrg 4776910425Smrg#ifndef DFLT_SYS_XKBEVD_CONFIG 4876910425Smrg#define DFLT_SYS_XKBEVD_CONFIG "%s/xkbevd.cf" 4976910425Smrg#endif /* DFLT_SYS_XKBEVD_CONFIG */ 5076910425Smrg 5176910425Smrg#ifndef DFLT_SOUND_CMD 5276910425Smrg#define DFLT_SOUND_CMD "/usr/sbin/sfplay -q" 5376910425Smrg#endif /* DFLT_SOUND_CMD */ 5476910425Smrg 5576910425Smrg#ifndef DFLT_SOUND_DIR 5676910425Smrg#define DFLT_SOUND_DIR "/usr/share/data/sounds/prosonus/" 5776910425Smrg#endif /* DFLT_SOUND_DIR */ 5876910425Smrg 5976910425Smrg/***====================================================================***/ 6076910425Smrg 61db17cd6dSmrgstatic char * dpyName= NULL; 6276910425SmrgDisplay * dpy= NULL; 63db17cd6dSmrgstatic char * cfgFileName= NULL; 6476910425Smrgint xkbOpcode= 0; 6576910425Smrgint xkbEventCode= 0; 6676910425SmrgBool detectableRepeat= False; 6776910425Smrg 68db17cd6dSmrgstatic 6976910425SmrgCfgEntryPtr config= NULL; 70db17cd6dSmrgstatic 7176910425Smrgunsigned long eventMask= 0; 7276910425Smrg 73db17cd6dSmrgstatic Bool synch= False; 74db17cd6dSmrgstatic int verbose= 0; 75db17cd6dSmrgstatic Bool background= False; 7676910425Smrg 77db17cd6dSmrgstatic char * soundCmd= NULL; 78db17cd6dSmrgstatic char * soundDir= NULL; 7976910425Smrg 8076910425SmrgXkbDescPtr xkb= NULL; 8176910425Smrg 8276910425Smrg/***====================================================================***/ 8376910425Smrg 8476910425Smrg#define M(m) fprintf(stderr,(m)) 8576910425Smrg#define M1(m,a) fprintf(stderr,(m),(a)) 8676910425Smrg 8776910425Smrgstatic void 8876910425SmrgUsage(int argc, char *argv[]) 8976910425Smrg{ 9076910425Smrg M1("Usage: %s [options]...\n",argv[0]); 9176910425Smrg M("Legal options:\n"); 9276910425Smrg M("-?,-help Print this message\n"); 9376910425Smrg M("-cfg <file> Specify a config file\n"); 9476910425Smrg M("-sc <cmd> Specify the command to play sounds\n"); 9576910425Smrg M("-sd <dir> Specify the root directory for sound files\n"); 9676910425Smrg M("-d[isplay] <dpy> Specify the display to watch\n"); 9776910425Smrg M("-bg Run in background\n"); 9876910425Smrg M("-synch Force synchronization\n"); 9976910425Smrg M("-v Print verbose messages\n"); 10076910425Smrg return; 10176910425Smrg} 10276910425Smrg 10376910425Smrg/***====================================================================***/ 10476910425Smrg 10576910425Smrgstatic Bool 10676910425SmrgparseArgs(int argc, char *argv[]) 10776910425Smrg{ 10876910425Smrgregister int i; 10976910425Smrg 11076910425Smrg for (i=1;i<argc;i++) { 11176910425Smrg if (strcmp(argv[i],"-bg")==0) { 11276910425Smrg background= True; 11376910425Smrg } 11476910425Smrg else if (strcmp(argv[i],"-cfg")==0) { 11576910425Smrg if (i>=(argc-1)) { 11676910425Smrg uError("No configuration file specified on command line\n"); 11776910425Smrg uAction("Trailing %s argument ignored\n",argv[i]); 11876910425Smrg } 11976910425Smrg else { 12076910425Smrg char *name= argv[++i]; 12176910425Smrg if (cfgFileName!=NULL) { 12276910425Smrg if (uStringEqual(cfgFileName,name)) 12376910425Smrg uWarning("Config file \"%s\" specified twice!\n"); 12476910425Smrg else { 12576910425Smrg uWarning("Multiple config files on command line\n"); 12676910425Smrg uAction("Using \"%s\", ignoring \"%s\"\n",name, 12776910425Smrg cfgFileName); 12876910425Smrg } 12976910425Smrg } 13076910425Smrg cfgFileName= name; 13176910425Smrg } 13276910425Smrg } 13376910425Smrg else if ((strcmp(argv[i],"-d")==0)||(strcmp(argv[i],"-display")==0)) { 13476910425Smrg if (i>=(argc-1)) { 13576910425Smrg uError("No display specified on command line\n"); 13676910425Smrg uAction("Trailing %s argument ignored\n",argv[i]); 13776910425Smrg } 13876910425Smrg else { 13976910425Smrg char *name= argv[++i]; 14076910425Smrg if (dpyName!=NULL) { 14176910425Smrg if (uStringEqual(dpyName,name)) 14276910425Smrg uWarning("Display \"%s\" specified twice!\n"); 14376910425Smrg else { 14476910425Smrg uWarning("Multiple displays on command line\n"); 14576910425Smrg uAction("Using \"%s\", ignoring \"%s\"\n",name, 14676910425Smrg dpyName); 14776910425Smrg } 14876910425Smrg } 14976910425Smrg dpyName= name; 15076910425Smrg } 15176910425Smrg } 15276910425Smrg else if (strcmp(argv[i],"-sc")==0) { 15376910425Smrg if (i>=(argc-1)) { 15476910425Smrg uError("No sound command specified on command line\n"); 15576910425Smrg uAction("Trailing %s argument ignored\n",argv[i]); 15676910425Smrg } 15776910425Smrg else { 15876910425Smrg char *name= argv[++i]; 15976910425Smrg if (soundCmd!=NULL) { 16076910425Smrg if (uStringEqual(soundCmd,name)) 16176910425Smrg uWarning("Sound command \"%s\" specified twice!\n"); 16276910425Smrg else { 16376910425Smrg uWarning("Multiple sound commands on command line\n"); 16476910425Smrg uAction("Using \"%s\", ignoring \"%s\"\n",name, 16576910425Smrg soundCmd); 16676910425Smrg } 16776910425Smrg } 16876910425Smrg soundCmd= name; 16976910425Smrg } 17076910425Smrg } 17176910425Smrg else if (strcmp(argv[i],"-sd")==0) { 17276910425Smrg if (i>=(argc-1)) { 17376910425Smrg uError("No sound directory specified on command line\n"); 17476910425Smrg uAction("Trailing %s argument ignored\n",argv[i]); 17576910425Smrg } 17676910425Smrg else { 17776910425Smrg char *name= argv[++i]; 17876910425Smrg if (soundDir!=NULL) { 17976910425Smrg if (uStringEqual(soundDir,name)) 18076910425Smrg uWarning("Sound directory \"%s\" specified twice!\n"); 18176910425Smrg else { 18276910425Smrg uWarning("Multiple sound dirs on command line\n"); 18376910425Smrg uAction("Using \"%s\", ignoring \"%s\"\n",name, 18476910425Smrg soundDir); 18576910425Smrg } 18676910425Smrg } 18776910425Smrg soundDir= name; 18876910425Smrg } 18976910425Smrg } 19076910425Smrg else if ((strcmp(argv[i],"-synch")==0)||(strcmp(argv[i],"-s")==0)) { 19176910425Smrg synch= True; 19276910425Smrg } 19376910425Smrg else if (strcmp(argv[i],"-v")==0) { 19476910425Smrg verbose++; 19576910425Smrg } 19676910425Smrg else if ((strcmp(argv[i],"-?")==0)||(strcmp(argv[i],"-help")==0)) { 19776910425Smrg Usage(argc,argv); 19876910425Smrg exit(0); 19976910425Smrg } 20076910425Smrg else { 20176910425Smrg uError("Unknown flag \"%s\" on command line\n",argv[i]); 20276910425Smrg Usage(argc,argv); 20376910425Smrg return False; 20476910425Smrg } 20576910425Smrg } 206db17cd6dSmrg if (background == False) { 207db17cd6dSmrg eventMask = XkbAllEventsMask; 208db17cd6dSmrg verbose++; 209db17cd6dSmrg } 210db17cd6dSmrg 21176910425Smrg return True; 21276910425Smrg} 21376910425Smrg 21476910425Smrgstatic Display * 21576910425SmrgGetDisplay(char *program, char *dpyName, int *opcodeRtrn, int *evBaseRtrn) 21676910425Smrg{ 21776910425Smrgint mjr,mnr,error; 21876910425SmrgDisplay *dpy; 21976910425Smrg 22076910425Smrg mjr= XkbMajorVersion; 22176910425Smrg mnr= XkbMinorVersion; 22276910425Smrg dpy= XkbOpenDisplay(dpyName,evBaseRtrn,NULL,&mjr,&mnr,&error); 22376910425Smrg if (dpy==NULL) { 22476910425Smrg switch (error) { 22576910425Smrg case XkbOD_BadLibraryVersion: 22676910425Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 22776910425Smrg program,XkbMajorVersion,XkbMinorVersion); 22876910425Smrg uError("X library supports incompatible version %d.%02d\n", 22976910425Smrg mjr,mnr); 23076910425Smrg break; 23176910425Smrg case XkbOD_ConnectionRefused: 23276910425Smrg uError("Cannot open display \"%s\"\n",dpyName); 23376910425Smrg break; 23476910425Smrg case XkbOD_NonXkbServer: 23576910425Smrg uError("XKB extension not present on %s\n",dpyName); 23676910425Smrg break; 23776910425Smrg case XkbOD_BadServerVersion: 23876910425Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 23976910425Smrg program,XkbMajorVersion,XkbMinorVersion); 24076910425Smrg uError("Server %s uses incompatible version %d.%02d\n", 24176910425Smrg dpyName,mjr,mnr); 24276910425Smrg break; 24376910425Smrg default: 24476910425Smrg uInternalError("Unknown error %d from XkbOpenDisplay\n",error); 24576910425Smrg } 24676910425Smrg } 24776910425Smrg else if (synch) 24876910425Smrg XSynchronize(dpy,True); 24976910425Smrg if (opcodeRtrn) 25076910425Smrg XkbQueryExtension(dpy,opcodeRtrn,evBaseRtrn,NULL,&mjr,&mnr); 25176910425Smrg return dpy; 25276910425Smrg} 25376910425Smrg 25476910425Smrg/***====================================================================***/ 25576910425Smrg 25676910425Smrgvoid 25776910425SmrgInterpretConfigs(CfgEntryPtr cfg) 25876910425Smrg{ 25976910425Smrgchar * name; 26076910425Smrgunsigned priv= 0; 26176910425Smrg 26276910425Smrg config= cfg; 26376910425Smrg while (cfg!=NULL) { 26476910425Smrg name= cfg->name.str; 26576910425Smrg if (cfg->entry_type==VariableDef) { 26676910425Smrg if (uStrCaseEqual(name,"sounddirectory")|| 26776910425Smrg uStrCaseEqual(name,"sounddir")) { 26876910425Smrg if (soundDir==NULL) { 26976910425Smrg soundDir= cfg->action.text; 27076910425Smrg cfg->name.str= NULL; 27176910425Smrg cfg->action.text= NULL; 27276910425Smrg } 27376910425Smrg } 27476910425Smrg else if (uStrCaseEqual(name,"soundcommand")|| 27576910425Smrg uStrCaseEqual(name,"soundcmd")) { 27676910425Smrg if (soundCmd==NULL) { 27776910425Smrg soundCmd= cfg->action.text; 27876910425Smrg cfg->name.str= NULL; 27976910425Smrg cfg->action.text= NULL; 28076910425Smrg } 28176910425Smrg } 28276910425Smrg else { 28376910425Smrg uWarning("Assignment to unknown variable \"%s\"\n",cfg->name); 28476910425Smrg uAction("Ignored\n"); 28576910425Smrg } 28676910425Smrg } 28776910425Smrg else if (cfg->entry_type==EventDef) switch (cfg->event_type) { 28876910425Smrg case XkbBellNotify: 28976910425Smrg if (name!=NULL) cfg->name.atom= XInternAtom(dpy,name,False); 29076910425Smrg else cfg->name.atom= None; 29176910425Smrg if (name) uFree(name); 29276910425Smrg break; 29376910425Smrg case XkbAccessXNotify: 29476910425Smrg priv= 0; 29576910425Smrg if (name==NULL) 29676910425Smrg priv= XkbAllNewKeyboardEventsMask; 29776910425Smrg else if (uStrCaseEqual(name,"skpress")) 29876910425Smrg priv= XkbAXN_SKPressMask; 29976910425Smrg else if (uStrCaseEqual(name,"skaccept")) 30076910425Smrg priv= XkbAXN_SKAcceptMask; 30176910425Smrg else if (uStrCaseEqual(name,"skreject")) 30276910425Smrg priv= XkbAXN_SKRejectMask; 30376910425Smrg else if (uStrCaseEqual(name,"skrelease")) 30476910425Smrg priv= XkbAXN_SKReleaseMask; 30576910425Smrg else if (uStrCaseEqual(name,"bkaccept")) 30676910425Smrg priv= XkbAXN_BKAcceptMask; 30776910425Smrg else if (uStrCaseEqual(name,"bkreject")) 30876910425Smrg priv= XkbAXN_BKRejectMask; 30976910425Smrg else if (uStrCaseEqual(name,"warning")) 31076910425Smrg priv= XkbAXN_AXKWarningMask; 31176910425Smrg if (name) uFree(name); 31276910425Smrg cfg->name.priv= priv; 31376910425Smrg break; 31476910425Smrg case XkbActionMessage: 31576910425Smrg /* nothing to do */ 31676910425Smrg break; 31776910425Smrg } 31876910425Smrg eventMask|= (1L<<cfg->event_type); 31976910425Smrg cfg= cfg->next; 32076910425Smrg } 32176910425Smrg while ((config)&&(config->entry_type!=EventDef)) { 32276910425Smrg CfgEntryPtr next; 32376910425Smrg if (config->name.str) uFree(config->name.str); 32476910425Smrg if (config->action.text) uFree(config->action.text); 32576910425Smrg config->name.str= NULL; 32676910425Smrg config->action.text= NULL; 32776910425Smrg next= config->next; 32876910425Smrg uFree(config); 32976910425Smrg config= next; 33076910425Smrg } 33176910425Smrg cfg= config; 33276910425Smrg while ((cfg!=NULL)&&(cfg->next!=NULL)) { 33376910425Smrg CfgEntryPtr next; 33476910425Smrg next= cfg->next; 33576910425Smrg if (next->entry_type!=EventDef) { 33676910425Smrg if (next->name.str) uFree(config->name.str); 33776910425Smrg if (next->action.text) uFree(config->action.text); 33876910425Smrg next->name.str= NULL; 33976910425Smrg next->action.text= NULL; 34076910425Smrg cfg->next= next->next; 34176910425Smrg next->next= NULL; 34276910425Smrg uFree(next); 34376910425Smrg } 34476910425Smrg else cfg= next; 34576910425Smrg } 34676910425Smrg return; 34776910425Smrg} 34876910425Smrg 34976910425Smrgstatic CfgEntryPtr 35076910425SmrgFindMatchingConfig(XkbEvent *ev) 35176910425Smrg{ 35276910425SmrgCfgEntryPtr cfg,dflt; 35376910425Smrg 35476910425Smrg dflt= NULL; 35576910425Smrg for (cfg= config;(cfg!=NULL);cfg=cfg->next) { 35676910425Smrg if ((ev->type!=xkbEventCode)||(cfg->event_type!=ev->any.xkb_type)) 35776910425Smrg continue; 35876910425Smrg switch (ev->any.xkb_type) { 35976910425Smrg case XkbBellNotify: 36076910425Smrg if (ev->bell.name==cfg->name.atom) 36176910425Smrg return cfg; 36276910425Smrg else if ((cfg->name.atom==None)&&(dflt==NULL)) 36376910425Smrg dflt= cfg; 36476910425Smrg break; 36576910425Smrg case XkbAccessXNotify: 36676910425Smrg if (cfg->name.priv&(1L<<ev->accessx.detail)) 36776910425Smrg return cfg; 36876910425Smrg break; 36976910425Smrg case XkbActionMessage: 37076910425Smrg if (cfg->name.str==NULL) 37176910425Smrg dflt= cfg; 37276910425Smrg else if (strncmp(cfg->name.str,ev->message.message, 37376910425Smrg XkbActionMessageLength)==0) 37476910425Smrg return cfg; 37576910425Smrg break; 37676910425Smrg default: 37776910425Smrg uInternalError("Can't handle type %d XKB events yet, Sorry.\n"); 37876910425Smrg break; 37976910425Smrg } 38076910425Smrg } 38176910425Smrg return dflt; 38276910425Smrg} 38376910425Smrg 38476910425Smrgstatic Bool 38576910425SmrgProcessMatchingConfig(XkbEvent *ev) 38676910425Smrg{ 38776910425SmrgCfgEntryPtr cfg; 38876910425Smrgchar buf[1024],*cmd; 38976910425Smrgint ok; 39076910425Smrg 39176910425Smrg cfg= FindMatchingConfig(ev); 392db17cd6dSmrg if (!cfg) { 393db17cd6dSmrg if (verbose) 394db17cd6dSmrg PrintXkbEvent(stdout,ev); 39576910425Smrg return False; 396db17cd6dSmrg } 39776910425Smrg if (cfg->action.type==UnknownAction) { 39876910425Smrg if (cfg->action.text==NULL) 39976910425Smrg cfg->action.type= NoAction; 40076910425Smrg else if (cfg->action.text[0]=='!') { 40176910425Smrg char *tmp; 40276910425Smrg cfg->action.type= ShellAction; 40376910425Smrg tmp= uStringDup(&cfg->action.text[1]); 40476910425Smrg uFree(cfg->action.text); 40576910425Smrg cfg->action.text= tmp; 40676910425Smrg } 40776910425Smrg else cfg->action.type= SoundAction; 40876910425Smrg } 40976910425Smrg switch (cfg->action.type) { 41076910425Smrg case NoAction: 41176910425Smrg return True; 41276910425Smrg case EchoAction: 41376910425Smrg if (cfg->action.text!=NULL) { 414db17cd6dSmrg sprintf(buf,"%s",cfg->action.text); 41576910425Smrg cmd= SubstituteEventArgs(buf,ev); 41676910425Smrg printf("%s",cmd); 41776910425Smrg } 41876910425Smrg return True; 41976910425Smrg case PrintEvAction: 42076910425Smrg PrintXkbEvent(stdout,ev); 42176910425Smrg return True; 42276910425Smrg case ShellAction: 42376910425Smrg if (cfg->action.text==NULL) { 42476910425Smrg uWarning("Empty shell command!\n"); 42576910425Smrg uAction("Ignored\n"); 42676910425Smrg return True; 42776910425Smrg } 42876910425Smrg cmd= cfg->action.text; 42976910425Smrg break; 43076910425Smrg case SoundAction: 43176910425Smrg if (cfg->action.text==NULL) { 43276910425Smrg uWarning("Empty sound command!\n"); 43376910425Smrg uAction("Ignored\n"); 43476910425Smrg return True; 43576910425Smrg } 43676910425Smrg sprintf(buf,"%s %s%s",soundCmd,soundDir,cfg->action.text); 43776910425Smrg cmd= buf; 43876910425Smrg break; 43976910425Smrg default: 44076910425Smrg uInternalError("Unknown error action type %d\n",cfg->action.type); 44176910425Smrg return False; 44276910425Smrg } 44376910425Smrg cmd= SubstituteEventArgs(cmd,ev); 44476910425Smrg if (verbose) 44576910425Smrg uInformation("Executing shell command \"%s\"\n",cmd); 44676910425Smrg ok= (system(cmd)==0); 44776910425Smrg return ok; 44876910425Smrg} 44976910425Smrg 45076910425Smrg/***====================================================================***/ 45176910425Smrg 45276910425Smrgint 45376910425Smrgmain(int argc, char *argv[]) 45476910425Smrg{ 45576910425SmrgFILE * file; 45676910425Smrgstatic char buf[1024]; 45776910425SmrgXkbEvent ev; 45876910425SmrgBool ok; 45976910425Smrg 46076910425Smrg 46176910425Smrg yyin = stdin; 46276910425Smrg uSetEntryFile(NullString); 46376910425Smrg uSetDebugFile(NullString); 46476910425Smrg uSetErrorFile(NullString); 46576910425Smrg 46676910425Smrg if (!parseArgs(argc,argv)) 46776910425Smrg exit(1); 46876910425Smrg file= NULL; 46976910425Smrg XkbInitAtoms(NULL); 47076910425Smrg if (cfgFileName==NULL) { 47176910425Smrg char *home; 47276910425Smrg home= (char *)getenv("HOME"); 47376910425Smrg sprintf(buf,DFLT_XKBEVD_CONFIG,(home?home:"")); 47476910425Smrg cfgFileName= buf; 47576910425Smrg } 47676910425Smrg if (uStringEqual(cfgFileName,"-")) { 47776910425Smrg static char *in= "stdin"; 47876910425Smrg file= stdin; 47976910425Smrg cfgFileName= in; 48076910425Smrg } 48176910425Smrg else { 48276910425Smrg file= fopen(cfgFileName,"r"); 48376910425Smrg if (file==NULL) { /* no personal config, try for a system one */ 48476910425Smrg if (cfgFileName!=buf) { /* user specified a file. bail */ 48576910425Smrg uError("Can't open config file \"%s\n",cfgFileName); 48676910425Smrg uAction("Exiting\n"); 48776910425Smrg exit(1); 48876910425Smrg } 48976910425Smrg sprintf(buf,DFLT_SYS_XKBEVD_CONFIG,DFLT_XKB_CONFIG_ROOT); 49076910425Smrg file= fopen(cfgFileName,"r"); 491db17cd6dSmrg if (file==NULL && !eventMask) { 49276910425Smrg if (verbose) { 49376910425Smrg uError("Couldn't find a config file anywhere\n"); 49476910425Smrg uAction("Exiting\n"); 49576910425Smrg exit(1); 49676910425Smrg } 49776910425Smrg exit(0); 49876910425Smrg } 49976910425Smrg } 50076910425Smrg } 50176910425Smrg 50276910425Smrg if (background) { 50376910425Smrg if (fork()!=0) { 50476910425Smrg if (verbose) 50576910425Smrg uInformation("Running in the background\n"); 50676910425Smrg exit(0); 50776910425Smrg } 50876910425Smrg } 50976910425Smrg dpy= GetDisplay(argv[0],dpyName,&xkbOpcode,&xkbEventCode); 51076910425Smrg if (!dpy) 51176910425Smrg goto BAILOUT; 51276910425Smrg ok= True; 51376910425Smrg setScanState(cfgFileName,1); 51476910425Smrg CFGParseFile(file); 515db17cd6dSmrg if (!config && !eventMask) { 51676910425Smrg uError("No configuration specified in \"%s\"\n",cfgFileName); 51776910425Smrg goto BAILOUT; 51876910425Smrg } 51976910425Smrg if (eventMask==0) { 52076910425Smrg uError("No events to watch in \"%s\"\n",cfgFileName); 52176910425Smrg goto BAILOUT; 52276910425Smrg } 52376910425Smrg if (!XkbSelectEvents(dpy,XkbUseCoreKbd,eventMask,eventMask)) { 52476910425Smrg uError("Couldn't select desired XKB events\n"); 52576910425Smrg goto BAILOUT; 52676910425Smrg } 52776910425Smrg xkb= XkbGetKeyboard(dpy,XkbGBN_AllComponentsMask,XkbUseCoreKbd); 52876910425Smrg if (eventMask&XkbBellNotifyMask) { 52976910425Smrg unsigned ctrls,vals; 53076910425Smrg if (verbose) 53176910425Smrg uInformation("Temporarily disabling the audible bell\n"); 53276910425Smrg if (!XkbChangeEnabledControls(dpy,XkbUseCoreKbd,XkbAudibleBellMask,0)) { 53376910425Smrg uError("Couldn't disable audible bell\n"); 53476910425Smrg goto BAILOUT; 53576910425Smrg } 53676910425Smrg ctrls= vals= XkbAudibleBellMask; 53776910425Smrg if (!XkbSetAutoResetControls(dpy,XkbAudibleBellMask,&ctrls,&vals)) { 53876910425Smrg uWarning("Couldn't configure audible bell to reset on exit\n"); 53976910425Smrg uAction("Audible bell might remain off\n"); 54076910425Smrg } 54176910425Smrg } 54276910425Smrg if (soundCmd==NULL) soundCmd= DFLT_SOUND_CMD; 54376910425Smrg if (soundDir==NULL) soundDir= DFLT_SOUND_DIR; 54476910425Smrg XkbStdBellEvent(dpy,None,0,XkbBI_ImAlive); 54576910425Smrg while (1) { 54676910425Smrg XNextEvent(dpy,&ev.core); 54776910425Smrg if ((!ProcessMatchingConfig(&ev))&&(ev.type==xkbEventCode)&& 54876910425Smrg (ev.any.xkb_type==XkbBellNotify)) { 54976910425Smrg XkbForceDeviceBell(dpy,ev.bell.device, 55076910425Smrg ev.bell.bell_class,ev.bell.bell_id, 55176910425Smrg ev.bell.percent); 55276910425Smrg } 55376910425Smrg } 55476910425Smrg 55576910425Smrg XCloseDisplay(dpy); 55676910425Smrg return (ok==0); 55776910425SmrgBAILOUT: 55876910425Smrg uAction("Exiting\n"); 55976910425Smrg if (dpy!=NULL) 56076910425Smrg XCloseDisplay(dpy); 56176910425Smrg exit(1); 56276910425Smrg} 563