TMparse.c revision 697b1baf
1444c061aSmrg/* $Xorg: TMparse.c,v 1.6 2001/02/09 02:03:58 xorgcvs Exp $ */ 2444c061aSmrg 3444c061aSmrg/*********************************************************** 4697b1bafSmrgCopyright 1993 Sun Microsystems, Inc. All rights reserved. 5697b1bafSmrg 6697b1bafSmrgPermission is hereby granted, free of charge, to any person obtaining a 7697b1bafSmrgcopy of this software and associated documentation files (the "Software"), 8697b1bafSmrgto deal in the Software without restriction, including without limitation 9697b1bafSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense, 10697b1bafSmrgand/or sell copies of the Software, and to permit persons to whom the 11697b1bafSmrgSoftware is furnished to do so, subject to the following conditions: 12697b1bafSmrg 13697b1bafSmrgThe above copyright notice and this permission notice (including the next 14697b1bafSmrgparagraph) shall be included in all copies or substantial portions of the 15697b1bafSmrgSoftware. 16697b1bafSmrg 17697b1bafSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18697b1bafSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19697b1bafSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20697b1bafSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21697b1bafSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22697b1bafSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23697b1bafSmrgDEALINGS IN THE SOFTWARE. 24697b1bafSmrg 25697b1bafSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 26444c061aSmrg 27444c061aSmrg All Rights Reserved 28444c061aSmrg 29444c061aSmrgPermission to use, copy, modify, and distribute this software and its 30444c061aSmrgdocumentation for any purpose and without fee is hereby granted, 31444c061aSmrgprovided that the above copyright notice appear in all copies and that 32444c061aSmrgboth that copyright notice and this permission notice appear in 33697b1bafSmrgsupporting documentation, and that the name of Digital not be 34444c061aSmrgused in advertising or publicity pertaining to distribution of the 35444c061aSmrgsoftware without specific, written prior permission. 36444c061aSmrg 37444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43444c061aSmrgSOFTWARE. 44444c061aSmrg 45444c061aSmrg******************************************************************/ 46444c061aSmrg/* $XFree86: xc/lib/Xt/TMparse.c,v 3.10tsi Exp $ */ 47444c061aSmrg 48444c061aSmrg/* 49444c061aSmrg 50444c061aSmrgCopyright 1987, 1988, 1998 The Open Group 51444c061aSmrg 52444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its 53444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that 54444c061aSmrgthe above copyright notice appear in all copies and that both that 55444c061aSmrgcopyright notice and this permission notice appear in supporting 56444c061aSmrgdocumentation. 57444c061aSmrg 58444c061aSmrgThe above copyright notice and this permission notice shall be included in 59444c061aSmrgall copies or substantial portions of the Software. 60444c061aSmrg 61444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 65444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 66444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 67444c061aSmrg 68444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be 69444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings 70444c061aSmrgin this Software without prior written authorization from The Open Group. 71444c061aSmrg 72444c061aSmrg*/ 73444c061aSmrg 74444c061aSmrg#ifdef HAVE_CONFIG_H 75444c061aSmrg#include <config.h> 76444c061aSmrg#endif 77444c061aSmrg#include "IntrinsicI.h" 78444c061aSmrg#include "StringDefs.h" 79444c061aSmrg#include <ctype.h> 80444c061aSmrg#include <stdlib.h> 81444c061aSmrg#ifndef NOTASCII 82444c061aSmrg#define XK_LATIN1 83444c061aSmrg#endif 84444c061aSmrg#define XK_MISCELLANY 85444c061aSmrg#include <X11/keysymdef.h> 86444c061aSmrg 87444c061aSmrg#ifdef CACHE_TRANSLATIONS 88444c061aSmrg# ifdef REFCNT_TRANSLATIONS 89444c061aSmrg# define CACHED XtCacheAll | XtCacheRefCount 90444c061aSmrg# else 91444c061aSmrg# define CACHED XtCacheAll 92444c061aSmrg# endif 93444c061aSmrg#else 94444c061aSmrg# define CACHED XtCacheNone 95444c061aSmrg#endif 96444c061aSmrg 97444c061aSmrg#ifndef MAX 98444c061aSmrg#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 99444c061aSmrg#endif 100444c061aSmrg 101444c061aSmrg#ifndef MIN 102444c061aSmrg#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 103444c061aSmrg#endif 104444c061aSmrg 105444c061aSmrgstatic String XtNtranslationParseError = "translationParseError"; 106444c061aSmrg 107444c061aSmrgtypedef int EventType; 108444c061aSmrg 109444c061aSmrgtypedef String (*ParseProc)( 110444c061aSmrg String /* str; */, 111444c061aSmrg Opaque /* closure; */, 112444c061aSmrg EventPtr /* event; */, 113444c061aSmrg Boolean* /* error */); 114444c061aSmrg 115444c061aSmrgtypedef TMShortCard Value; 116444c061aSmrgtypedef void (*ModifierProc)(Value, LateBindingsPtr*, Boolean, Value*); 117444c061aSmrg 118444c061aSmrgtypedef struct _ModifierRec { 119444c061aSmrg char* name; 120444c061aSmrg XrmQuark signature; 121444c061aSmrg ModifierProc modifierParseProc; 122444c061aSmrg Value value; 123444c061aSmrg} ModifierRec, *ModifierKeys; 124444c061aSmrg 125444c061aSmrgtypedef struct _EventKey { 126444c061aSmrg char *event; 127444c061aSmrg XrmQuark signature; 128444c061aSmrg EventType eventType; 129444c061aSmrg ParseProc parseDetail; 130444c061aSmrg Opaque closure; 131444c061aSmrg}EventKey, *EventKeys; 132444c061aSmrg 133444c061aSmrgtypedef struct { 134444c061aSmrg char *name; 135444c061aSmrg XrmQuark signature; 136444c061aSmrg Value value; 137444c061aSmrg} NameValueRec, *NameValueTable; 138444c061aSmrg 139444c061aSmrgstatic void ParseModImmed(Value, LateBindingsPtr*, Boolean, Value*); 140444c061aSmrgstatic void ParseModSym(Value, LateBindingsPtr*, Boolean, Value*); 141444c061aSmrgstatic String PanicModeRecovery(String); 142444c061aSmrgstatic String CheckForPoundSign(String, _XtTranslateOp, _XtTranslateOp *); 143444c061aSmrgstatic KeySym StringToKeySym(String, Boolean *); 144444c061aSmrgstatic ModifierRec modifiers[] = { 145444c061aSmrg {"Shift", 0, ParseModImmed,ShiftMask}, 146444c061aSmrg {"Lock", 0, ParseModImmed,LockMask}, 147444c061aSmrg {"Ctrl", 0, ParseModImmed,ControlMask}, 148444c061aSmrg {"Mod1", 0, ParseModImmed,Mod1Mask}, 149444c061aSmrg {"Mod2", 0, ParseModImmed,Mod2Mask}, 150444c061aSmrg {"Mod3", 0, ParseModImmed,Mod3Mask}, 151444c061aSmrg {"Mod4", 0, ParseModImmed,Mod4Mask}, 152444c061aSmrg {"Mod5", 0, ParseModImmed,Mod5Mask}, 153444c061aSmrg {"Meta", 0, ParseModSym, XK_Meta_L}, 154444c061aSmrg {"m", 0, ParseModSym, XK_Meta_L}, 155444c061aSmrg {"h", 0, ParseModSym, XK_Hyper_L}, 156444c061aSmrg {"su", 0, ParseModSym, XK_Super_L}, 157444c061aSmrg {"a", 0, ParseModSym, XK_Alt_L}, 158444c061aSmrg {"Hyper", 0, ParseModSym, XK_Hyper_L}, 159444c061aSmrg {"Super", 0, ParseModSym, XK_Super_L}, 160444c061aSmrg {"Alt", 0, ParseModSym, XK_Alt_L}, 161444c061aSmrg {"Button1", 0, ParseModImmed,Button1Mask}, 162444c061aSmrg {"Button2", 0, ParseModImmed,Button2Mask}, 163444c061aSmrg {"Button3", 0, ParseModImmed,Button3Mask}, 164444c061aSmrg {"Button4", 0, ParseModImmed,Button4Mask}, 165444c061aSmrg {"Button5", 0, ParseModImmed,Button5Mask}, 166444c061aSmrg {"c", 0, ParseModImmed,ControlMask}, 167444c061aSmrg {"s", 0, ParseModImmed,ShiftMask}, 168444c061aSmrg {"l", 0, ParseModImmed,LockMask}, 169444c061aSmrg}; 170444c061aSmrg 171444c061aSmrgstatic NameValueRec buttonNames[] = { 172444c061aSmrg {"Button1", 0, Button1}, 173444c061aSmrg {"Button2", 0, Button2}, 174444c061aSmrg {"Button3", 0, Button3}, 175444c061aSmrg {"Button4", 0, Button4}, 176444c061aSmrg {"Button5", 0, Button5}, 177444c061aSmrg {NULL, NULLQUARK, 0}, 178444c061aSmrg}; 179444c061aSmrg 180444c061aSmrgstatic NameValueRec motionDetails[] = { 181444c061aSmrg {"Normal", 0, NotifyNormal}, 182444c061aSmrg {"Hint", 0, NotifyHint}, 183444c061aSmrg {NULL, NULLQUARK, 0}, 184444c061aSmrg}; 185444c061aSmrg 186444c061aSmrgstatic NameValueRec notifyModes[] = { 187444c061aSmrg {"Normal", 0, NotifyNormal}, 188444c061aSmrg {"Grab", 0, NotifyGrab}, 189444c061aSmrg {"Ungrab", 0, NotifyUngrab}, 190444c061aSmrg {"WhileGrabbed", 0, NotifyWhileGrabbed}, 191444c061aSmrg {NULL, NULLQUARK, 0}, 192444c061aSmrg}; 193444c061aSmrg 194444c061aSmrg#if 0 195444c061aSmrgstatic NameValueRec notifyDetail[] = { 196444c061aSmrg {"Ancestor", 0, NotifyAncestor}, 197444c061aSmrg {"Virtual", 0, NotifyVirtual}, 198444c061aSmrg {"Inferior", 0, NotifyInferior}, 199444c061aSmrg {"Nonlinear", 0, NotifyNonlinear}, 200444c061aSmrg {"NonlinearVirtual", 0, NotifyNonlinearVirtual}, 201444c061aSmrg {"Pointer", 0, NotifyPointer}, 202444c061aSmrg {"PointerRoot", 0, NotifyPointerRoot}, 203444c061aSmrg {"DetailNone", 0, NotifyDetailNone}, 204444c061aSmrg {NULL, NULLQUARK, 0}, 205444c061aSmrg}; 206444c061aSmrg 207444c061aSmrgstatic NameValueRec visibilityNotify[] = { 208444c061aSmrg {"Unobscured", 0, VisibilityUnobscured}, 209444c061aSmrg {"PartiallyObscured", 0, VisibilityPartiallyObscured}, 210444c061aSmrg {"FullyObscured", 0, VisibilityFullyObscured}, 211444c061aSmrg {NULL, NULLQUARK, 0}, 212444c061aSmrg}; 213444c061aSmrg 214444c061aSmrgstatic NameValueRec circulation[] = { 215444c061aSmrg {"OnTop", 0, PlaceOnTop}, 216444c061aSmrg {"OnBottom", 0, PlaceOnBottom}, 217444c061aSmrg {NULL, NULLQUARK, 0}, 218444c061aSmrg}; 219444c061aSmrg 220444c061aSmrgstatic NameValueRec propertyChanged[] = { 221444c061aSmrg {"NewValue", 0, PropertyNewValue}, 222444c061aSmrg {"Delete", 0, PropertyDelete}, 223444c061aSmrg {NULL, NULLQUARK, 0}, 224444c061aSmrg}; 225444c061aSmrg#endif /*0*/ 226444c061aSmrg 227444c061aSmrgstatic NameValueRec mappingNotify[] = { 228444c061aSmrg {"Modifier", 0, MappingModifier}, 229444c061aSmrg {"Keyboard", 0, MappingKeyboard}, 230444c061aSmrg {"Pointer", 0, MappingPointer}, 231444c061aSmrg {NULL, NULLQUARK, 0}, 232444c061aSmrg}; 233444c061aSmrg 234444c061aSmrgstatic String ParseKeySym(String, Opaque, EventPtr, Boolean*); 235444c061aSmrgstatic String ParseKeyAndModifiers(String, Opaque, EventPtr, Boolean*); 236444c061aSmrgstatic String ParseTable(String, Opaque, EventPtr, Boolean*); 237444c061aSmrgstatic String ParseImmed(String, Opaque, EventPtr, Boolean*); 238444c061aSmrgstatic String ParseAddModifier(String, Opaque, EventPtr, Boolean*); 239444c061aSmrgstatic String ParseNone(String, Opaque, EventPtr, Boolean*); 240444c061aSmrgstatic String ParseAtom(String, Opaque, EventPtr, Boolean*); 241444c061aSmrg 242444c061aSmrgstatic EventKey events[] = { 243444c061aSmrg 244444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 245444c061aSmrg 246444c061aSmrg{"KeyPress", NULLQUARK, KeyPress, ParseKeySym, NULL}, 247444c061aSmrg{"Key", NULLQUARK, KeyPress, ParseKeySym, NULL}, 248444c061aSmrg{"KeyDown", NULLQUARK, KeyPress, ParseKeySym, NULL}, 249444c061aSmrg{"Ctrl", NULLQUARK, KeyPress, ParseKeyAndModifiers,(Opaque)ControlMask}, 250444c061aSmrg{"Shift", NULLQUARK, KeyPress, ParseKeyAndModifiers,(Opaque)ShiftMask}, 251444c061aSmrg{"Meta", NULLQUARK, KeyPress, ParseKeyAndModifiers,(Opaque)NULL}, 252444c061aSmrg{"KeyUp", NULLQUARK, KeyRelease, ParseKeySym, NULL}, 253444c061aSmrg{"KeyRelease", NULLQUARK, KeyRelease, ParseKeySym, NULL}, 254444c061aSmrg 255444c061aSmrg{"ButtonPress", NULLQUARK, ButtonPress, ParseTable,(Opaque)buttonNames}, 256444c061aSmrg{"BtnDown", NULLQUARK, ButtonPress, ParseTable,(Opaque)buttonNames}, 257444c061aSmrg{"Btn1Down", NULLQUARK, ButtonPress, ParseImmed,(Opaque)Button1}, 258444c061aSmrg{"Btn2Down", NULLQUARK, ButtonPress, ParseImmed,(Opaque)Button2}, 259444c061aSmrg{"Btn3Down", NULLQUARK, ButtonPress, ParseImmed,(Opaque)Button3}, 260444c061aSmrg{"Btn4Down", NULLQUARK, ButtonPress, ParseImmed,(Opaque)Button4}, 261444c061aSmrg{"Btn5Down", NULLQUARK, ButtonPress, ParseImmed,(Opaque)Button5}, 262444c061aSmrg 263444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 264444c061aSmrg 265444c061aSmrg{"ButtonRelease", NULLQUARK, ButtonRelease, ParseTable,(Opaque)buttonNames}, 266444c061aSmrg{"BtnUp", NULLQUARK, ButtonRelease, ParseTable,(Opaque)buttonNames}, 267444c061aSmrg{"Btn1Up", NULLQUARK, ButtonRelease, ParseImmed,(Opaque)Button1}, 268444c061aSmrg{"Btn2Up", NULLQUARK, ButtonRelease, ParseImmed,(Opaque)Button2}, 269444c061aSmrg{"Btn3Up", NULLQUARK, ButtonRelease, ParseImmed,(Opaque)Button3}, 270444c061aSmrg{"Btn4Up", NULLQUARK, ButtonRelease, ParseImmed,(Opaque)Button4}, 271444c061aSmrg{"Btn5Up", NULLQUARK, ButtonRelease, ParseImmed,(Opaque)Button5}, 272444c061aSmrg 273444c061aSmrg{"MotionNotify", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 274444c061aSmrg{"PtrMoved", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 275444c061aSmrg{"Motion", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 276444c061aSmrg{"MouseMoved", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 277444c061aSmrg{"BtnMotion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)AnyButtonMask}, 278444c061aSmrg{"Btn1Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button1Mask}, 279444c061aSmrg{"Btn2Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button2Mask}, 280444c061aSmrg{"Btn3Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button3Mask}, 281444c061aSmrg{"Btn4Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button4Mask}, 282444c061aSmrg{"Btn5Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button5Mask}, 283444c061aSmrg 284444c061aSmrg{"EnterNotify", NULLQUARK, EnterNotify, ParseTable,(Opaque)notifyModes}, 285444c061aSmrg{"Enter", NULLQUARK, EnterNotify, ParseTable,(Opaque)notifyModes}, 286444c061aSmrg{"EnterWindow", NULLQUARK, EnterNotify, ParseTable,(Opaque)notifyModes}, 287444c061aSmrg 288444c061aSmrg{"LeaveNotify", NULLQUARK, LeaveNotify, ParseTable,(Opaque)notifyModes}, 289444c061aSmrg{"LeaveWindow", NULLQUARK, LeaveNotify, ParseTable,(Opaque)notifyModes}, 290444c061aSmrg{"Leave", NULLQUARK, LeaveNotify, ParseTable,(Opaque)notifyModes}, 291444c061aSmrg 292444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 293444c061aSmrg 294444c061aSmrg{"FocusIn", NULLQUARK, FocusIn, ParseTable,(Opaque)notifyModes}, 295444c061aSmrg 296444c061aSmrg{"FocusOut", NULLQUARK, FocusOut, ParseTable,(Opaque)notifyModes}, 297444c061aSmrg 298444c061aSmrg{"KeymapNotify", NULLQUARK, KeymapNotify, ParseNone, NULL}, 299444c061aSmrg{"Keymap", NULLQUARK, KeymapNotify, ParseNone, NULL}, 300444c061aSmrg 301444c061aSmrg{"Expose", NULLQUARK, Expose, ParseNone, NULL}, 302444c061aSmrg 303444c061aSmrg{"GraphicsExpose", NULLQUARK, GraphicsExpose, ParseNone, NULL}, 304444c061aSmrg{"GrExp", NULLQUARK, GraphicsExpose, ParseNone, NULL}, 305444c061aSmrg 306444c061aSmrg{"NoExpose", NULLQUARK, NoExpose, ParseNone, NULL}, 307444c061aSmrg{"NoExp", NULLQUARK, NoExpose, ParseNone, NULL}, 308444c061aSmrg 309444c061aSmrg{"VisibilityNotify",NULLQUARK, VisibilityNotify,ParseNone, NULL}, 310444c061aSmrg{"Visible", NULLQUARK, VisibilityNotify,ParseNone, NULL}, 311444c061aSmrg 312444c061aSmrg{"CreateNotify", NULLQUARK, CreateNotify, ParseNone, NULL}, 313444c061aSmrg{"Create", NULLQUARK, CreateNotify, ParseNone, NULL}, 314444c061aSmrg 315444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 316444c061aSmrg 317444c061aSmrg{"DestroyNotify", NULLQUARK, DestroyNotify, ParseNone, NULL}, 318444c061aSmrg{"Destroy", NULLQUARK, DestroyNotify, ParseNone, NULL}, 319444c061aSmrg 320444c061aSmrg{"UnmapNotify", NULLQUARK, UnmapNotify, ParseNone, NULL}, 321444c061aSmrg{"Unmap", NULLQUARK, UnmapNotify, ParseNone, NULL}, 322444c061aSmrg 323444c061aSmrg{"MapNotify", NULLQUARK, MapNotify, ParseNone, NULL}, 324444c061aSmrg{"Map", NULLQUARK, MapNotify, ParseNone, NULL}, 325444c061aSmrg 326444c061aSmrg{"MapRequest", NULLQUARK, MapRequest, ParseNone, NULL}, 327444c061aSmrg{"MapReq", NULLQUARK, MapRequest, ParseNone, NULL}, 328444c061aSmrg 329444c061aSmrg{"ReparentNotify", NULLQUARK, ReparentNotify, ParseNone, NULL}, 330444c061aSmrg{"Reparent", NULLQUARK, ReparentNotify, ParseNone, NULL}, 331444c061aSmrg 332444c061aSmrg{"ConfigureNotify", NULLQUARK, ConfigureNotify, ParseNone, NULL}, 333444c061aSmrg{"Configure", NULLQUARK, ConfigureNotify, ParseNone, NULL}, 334444c061aSmrg 335444c061aSmrg{"ConfigureRequest",NULLQUARK, ConfigureRequest,ParseNone, NULL}, 336444c061aSmrg{"ConfigureReq", NULLQUARK, ConfigureRequest,ParseNone, NULL}, 337444c061aSmrg 338444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 339444c061aSmrg 340444c061aSmrg{"GravityNotify", NULLQUARK, GravityNotify, ParseNone, NULL}, 341444c061aSmrg{"Grav", NULLQUARK, GravityNotify, ParseNone, NULL}, 342444c061aSmrg 343444c061aSmrg{"ResizeRequest", NULLQUARK, ResizeRequest, ParseNone, NULL}, 344444c061aSmrg{"ResReq", NULLQUARK, ResizeRequest, ParseNone, NULL}, 345444c061aSmrg 346444c061aSmrg{"CirculateNotify", NULLQUARK, CirculateNotify, ParseNone, NULL}, 347444c061aSmrg{"Circ", NULLQUARK, CirculateNotify, ParseNone, NULL}, 348444c061aSmrg 349444c061aSmrg{"CirculateRequest",NULLQUARK, CirculateRequest,ParseNone, NULL}, 350444c061aSmrg{"CircReq", NULLQUARK, CirculateRequest,ParseNone, NULL}, 351444c061aSmrg 352444c061aSmrg{"PropertyNotify", NULLQUARK, PropertyNotify, ParseAtom, NULL}, 353444c061aSmrg{"Prop", NULLQUARK, PropertyNotify, ParseAtom, NULL}, 354444c061aSmrg 355444c061aSmrg{"SelectionClear", NULLQUARK, SelectionClear, ParseAtom, NULL}, 356444c061aSmrg{"SelClr", NULLQUARK, SelectionClear, ParseAtom, NULL}, 357444c061aSmrg 358444c061aSmrg{"SelectionRequest",NULLQUARK, SelectionRequest,ParseAtom, NULL}, 359444c061aSmrg{"SelReq", NULLQUARK, SelectionRequest,ParseAtom, NULL}, 360444c061aSmrg 361444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 362444c061aSmrg 363444c061aSmrg{"SelectionNotify", NULLQUARK, SelectionNotify, ParseAtom, NULL}, 364444c061aSmrg{"Select", NULLQUARK, SelectionNotify, ParseAtom, NULL}, 365444c061aSmrg 366444c061aSmrg{"ColormapNotify", NULLQUARK, ColormapNotify, ParseNone, NULL}, 367444c061aSmrg{"Clrmap", NULLQUARK, ColormapNotify, ParseNone, NULL}, 368444c061aSmrg 369444c061aSmrg{"ClientMessage", NULLQUARK, ClientMessage, ParseAtom, NULL}, 370444c061aSmrg{"Message", NULLQUARK, ClientMessage, ParseAtom, NULL}, 371444c061aSmrg 372444c061aSmrg{"MappingNotify", NULLQUARK, MappingNotify, ParseTable, (Opaque)mappingNotify}, 373444c061aSmrg{"Mapping", NULLQUARK, MappingNotify, ParseTable, (Opaque)mappingNotify}, 374444c061aSmrg 375444c061aSmrg#ifdef DEBUG 376444c061aSmrg# ifdef notdef 377444c061aSmrg{"Timer", NULLQUARK, _XtTimerEventType,ParseNone, NULL}, 378444c061aSmrg{"EventTimer", NULLQUARK, _XtEventTimerEventType,ParseNone,NULL}, 3791bd39548Schristos# endif /* notdef */ 380444c061aSmrg#endif /* DEBUG */ 381444c061aSmrg 382444c061aSmrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 383444c061aSmrg 384444c061aSmrg}; 385444c061aSmrg 386444c061aSmrg#ifndef __UNIXOS2__ 387444c061aSmrg#define IsNewline(str) ((str) == '\n') 388444c061aSmrg#else 389444c061aSmrg#define IsNewline(str) ((str) == '\n' || (str) == '\r') 390444c061aSmrg#endif 391444c061aSmrg 392444c061aSmrg#define ScanFor(str, ch) \ 393444c061aSmrg while ((*(str) != (ch)) && (*(str) != '\0') && !IsNewline(*(str))) (str)++ 394444c061aSmrg 395444c061aSmrg#define ScanNumeric(str) while ('0' <= *(str) && *(str) <= '9') (str)++ 396444c061aSmrg 397444c061aSmrg#define ScanAlphanumeric(str) \ 398444c061aSmrg while (('A' <= *(str) && *(str) <= 'Z') || \ 399444c061aSmrg ('a' <= *(str) && *(str) <= 'z') || \ 400444c061aSmrg ('0' <= *(str) && *(str) <= '9')) (str)++ 401444c061aSmrg 402444c061aSmrg#ifndef __UNIXOS2__ 403444c061aSmrg#define ScanWhitespace(str) \ 404444c061aSmrg while (*(str) == ' ' || *(str) == '\t') (str)++ 405444c061aSmrg#else 406444c061aSmrg#define ScanWhitespace(str) \ 407444c061aSmrg while (*(str) == ' ' || *(str) == '\t' || *(str) == '\r') (str)++ 408444c061aSmrg#endif 409444c061aSmrg 410444c061aSmrgstatic Boolean initialized = FALSE; 411444c061aSmrgstatic XrmQuark QMeta; 412444c061aSmrgstatic XrmQuark QCtrl; 413444c061aSmrgstatic XrmQuark QNone; 414444c061aSmrgstatic XrmQuark QAny; 415444c061aSmrg 416444c061aSmrgstatic void FreeEventSeq( 417444c061aSmrg EventSeqPtr eventSeq) 418444c061aSmrg{ 419444c061aSmrg register EventSeqPtr evs = eventSeq; 420444c061aSmrg 421444c061aSmrg while (evs != NULL) { 422444c061aSmrg evs->state = (StatePtr) evs; 423444c061aSmrg if (evs->next != NULL 424444c061aSmrg && evs->next->state == (StatePtr) evs->next) 425444c061aSmrg evs->next = NULL; 426444c061aSmrg evs = evs->next; 427444c061aSmrg } 428444c061aSmrg 429444c061aSmrg evs = eventSeq; 430444c061aSmrg while (evs != NULL) { 431444c061aSmrg register EventPtr event = evs; 432444c061aSmrg evs = evs->next; 433444c061aSmrg if (evs == event) evs = NULL; 434444c061aSmrg XtFree((char *)event); 435444c061aSmrg } 436444c061aSmrg} 437444c061aSmrg 438444c061aSmrgstatic void CompileNameValueTable( 439444c061aSmrg NameValueTable table) 440444c061aSmrg{ 441444c061aSmrg register int i; 442444c061aSmrg 443444c061aSmrg for (i=0; table[i].name; i++) 444444c061aSmrg table[i].signature = XrmPermStringToQuark(table[i].name); 445444c061aSmrg} 446444c061aSmrg 447444c061aSmrgstatic int OrderEvents(_Xconst void *a, _Xconst void *b) 448444c061aSmrg{ 449444c061aSmrg return ((((_Xconst EventKey *)a)->signature < 450444c061aSmrg ((_Xconst EventKey *)b)->signature) ? -1 : 1); 451444c061aSmrg} 452444c061aSmrg 453444c061aSmrgstatic void Compile_XtEventTable( 454444c061aSmrg EventKeys table, 455444c061aSmrg Cardinal count) 456444c061aSmrg{ 457444c061aSmrg register int i; 458444c061aSmrg register EventKeys entry = table; 459444c061aSmrg 460444c061aSmrg for (i=count; --i >= 0; entry++) 461444c061aSmrg entry->signature = XrmPermStringToQuark(entry->event); 462444c061aSmrg qsort(table, count, sizeof(EventKey), OrderEvents); 463444c061aSmrg} 464444c061aSmrg 465444c061aSmrgstatic int OrderModifiers(_Xconst void *a, _Xconst void *b) 466444c061aSmrg{ 467444c061aSmrg return ((((_Xconst ModifierRec *)a)->signature < 468444c061aSmrg ((_Xconst ModifierRec *)b)->signature) ? -1 : 1); 469444c061aSmrg} 470444c061aSmrg 471444c061aSmrgstatic void Compile_XtModifierTable( 472444c061aSmrg ModifierKeys table, 473444c061aSmrg Cardinal count) 474444c061aSmrg{ 475444c061aSmrg register int i; 476444c061aSmrg register ModifierKeys entry = table; 477444c061aSmrg 478444c061aSmrg for (i=count; --i >= 0; entry++) 479444c061aSmrg entry->signature = XrmPermStringToQuark(entry->name); 480444c061aSmrg qsort(table, count, sizeof(ModifierRec), OrderModifiers); 481444c061aSmrg} 482444c061aSmrg 483444c061aSmrgstatic String PanicModeRecovery( 484444c061aSmrg String str) 485444c061aSmrg{ 486444c061aSmrg ScanFor(str,'\n'); 487444c061aSmrg if (*str == '\n') str++; 488444c061aSmrg return str; 489444c061aSmrg 490444c061aSmrg} 491444c061aSmrg 492444c061aSmrg 493444c061aSmrgstatic void Syntax( 494444c061aSmrg String str0,String str1) 495444c061aSmrg{ 496444c061aSmrg Cardinal num_params = 2; 497444c061aSmrg String params[2]; 498444c061aSmrg 499444c061aSmrg params[0] = str0; 500444c061aSmrg params[1] = str1; 501444c061aSmrg XtWarningMsg(XtNtranslationParseError,"parseError",XtCXtToolkitError, 502444c061aSmrg "translation table syntax error: %s %s",params,&num_params); 503444c061aSmrg} 504444c061aSmrg 505444c061aSmrg 506444c061aSmrg 507444c061aSmrgstatic Cardinal LookupTMEventType( 508444c061aSmrg String eventStr, 509444c061aSmrg Boolean *error) 510444c061aSmrg{ 511444c061aSmrg register int i = 0, left, right; 512444c061aSmrg register XrmQuark signature; 513444c061aSmrg static int previous = 0; 514444c061aSmrg 515444c061aSmrg LOCK_PROCESS; 516444c061aSmrg if ((signature = StringToQuark(eventStr)) == events[previous].signature) { 517444c061aSmrg UNLOCK_PROCESS; 518444c061aSmrg return (Cardinal) previous; 519444c061aSmrg } 520444c061aSmrg 521444c061aSmrg left = 0; 522444c061aSmrg right = XtNumber(events) - 1; 523444c061aSmrg while (left <= right) { 524444c061aSmrg i = (left + right) >> 1; 525444c061aSmrg if (signature < events[i].signature) 526444c061aSmrg right = i - 1; 527444c061aSmrg else if (signature > events[i].signature) 528444c061aSmrg left = i + 1; 529444c061aSmrg else { 530444c061aSmrg previous = i; 531444c061aSmrg UNLOCK_PROCESS; 532444c061aSmrg return (Cardinal) i; 533444c061aSmrg } 534444c061aSmrg } 535444c061aSmrg 536444c061aSmrg Syntax("Unknown event type : ",eventStr); 537444c061aSmrg *error = TRUE; 538444c061aSmrg UNLOCK_PROCESS; 539444c061aSmrg return (Cardinal) i; 540444c061aSmrg} 541444c061aSmrg 542444c061aSmrgstatic void StoreLateBindings( 543444c061aSmrg KeySym keysymL, 544444c061aSmrg Boolean notL, 545444c061aSmrg KeySym keysymR, 546444c061aSmrg Boolean notR, 547444c061aSmrg LateBindingsPtr* lateBindings) 548444c061aSmrg{ 549444c061aSmrg LateBindingsPtr temp; 550444c061aSmrg Boolean pair = FALSE; 551444c061aSmrg unsigned long count,number; 552444c061aSmrg if (lateBindings != NULL){ 553444c061aSmrg temp = *lateBindings; 554444c061aSmrg if (temp != NULL) { 555444c061aSmrg for (count = 0; temp[count].keysym; count++){/*EMPTY*/} 556444c061aSmrg } 557444c061aSmrg else count = 0; 558444c061aSmrg if (! keysymR){ 559444c061aSmrg number = 1;pair = FALSE; 560444c061aSmrg } else{ 561444c061aSmrg number = 2;pair = TRUE; 562444c061aSmrg } 563444c061aSmrg 564444c061aSmrg temp = (LateBindingsPtr)XtRealloc((char *)temp, 565444c061aSmrg (unsigned)((count+number+1) * sizeof(LateBindings)) ); 566444c061aSmrg *lateBindings = temp; 567444c061aSmrg temp[count].knot = notL; 568444c061aSmrg temp[count].pair = pair; 569444c061aSmrg if (count == 0) 570444c061aSmrg temp[count].ref_count = 1; 571444c061aSmrg temp[count++].keysym = keysymL; 572444c061aSmrg if (keysymR){ 573444c061aSmrg temp[count].knot = notR; 574444c061aSmrg temp[count].pair = FALSE; 575444c061aSmrg temp[count].ref_count = 0; 576444c061aSmrg temp[count++].keysym = keysymR; 577444c061aSmrg } 578444c061aSmrg temp[count].knot = temp[count].pair = FALSE; 579444c061aSmrg temp[count].ref_count = 0; 580444c061aSmrg temp[count].keysym = 0; 581444c061aSmrg } 582444c061aSmrg} 583444c061aSmrg 584444c061aSmrgstatic void _XtParseKeysymMod( 585444c061aSmrg String name, 586444c061aSmrg LateBindingsPtr* lateBindings, 587444c061aSmrg Boolean notFlag, 588444c061aSmrg Value *valueP, 589444c061aSmrg Boolean *error) 590444c061aSmrg{ 591444c061aSmrg KeySym keySym; 592444c061aSmrg keySym = StringToKeySym(name, error); 593444c061aSmrg *valueP = 0; 594444c061aSmrg if (keySym != NoSymbol) { 595444c061aSmrg StoreLateBindings(keySym,notFlag,(KeySym) NULL,FALSE,lateBindings); 596444c061aSmrg } 597444c061aSmrg} 598444c061aSmrg 599444c061aSmrgstatic Boolean _XtLookupModifier( 600444c061aSmrg XrmQuark signature, 601444c061aSmrg LateBindingsPtr* lateBindings, 602444c061aSmrg Boolean notFlag, 603444c061aSmrg Value *valueP, 604444c061aSmrg Bool constMask) 605444c061aSmrg{ 606444c061aSmrg register int i, left, right; 607444c061aSmrg static int previous = 0; 608444c061aSmrg 609444c061aSmrg LOCK_PROCESS; 610444c061aSmrg if (signature == modifiers[previous].signature) { 611444c061aSmrg if (constMask) *valueP = modifiers[previous].value; 612444c061aSmrg else /* if (modifiers[previous].modifierParseProc) always true */ 613444c061aSmrg (*modifiers[previous].modifierParseProc) 614444c061aSmrg (modifiers[previous].value, lateBindings, notFlag, valueP); 615444c061aSmrg UNLOCK_PROCESS; 616444c061aSmrg return TRUE; 617444c061aSmrg } 618444c061aSmrg 619444c061aSmrg left = 0; 620444c061aSmrg right = XtNumber(modifiers) - 1; 621444c061aSmrg while (left <= right) { 622444c061aSmrg i = (left + right) >> 1; 623444c061aSmrg if (signature < modifiers[i].signature) 624444c061aSmrg right = i - 1; 625444c061aSmrg else if (signature > modifiers[i].signature) 626444c061aSmrg left = i + 1; 627444c061aSmrg else { 628444c061aSmrg previous = i; 629444c061aSmrg if (constMask) *valueP = modifiers[i].value; 630444c061aSmrg else /* if (modifiers[i].modifierParseProc) always true */ 631444c061aSmrg (*modifiers[i].modifierParseProc) 632444c061aSmrg (modifiers[i].value, lateBindings, notFlag, valueP); 633444c061aSmrg UNLOCK_PROCESS; 634444c061aSmrg return TRUE; 635444c061aSmrg } 636444c061aSmrg } 637444c061aSmrg UNLOCK_PROCESS; 638444c061aSmrg return FALSE; 639444c061aSmrg} 640444c061aSmrg 641444c061aSmrg 642444c061aSmrgstatic String ScanIdent( 643444c061aSmrg register String str) 644444c061aSmrg{ 645444c061aSmrg ScanAlphanumeric(str); 646444c061aSmrg while ( 647444c061aSmrg ('A' <= *str && *str <= 'Z') 648444c061aSmrg || ('a' <= *str && *str <= 'z') 649444c061aSmrg || ('0' <= *str && *str <= '9') 650444c061aSmrg || (*str == '-') 651444c061aSmrg || (*str == '_') 652444c061aSmrg || (*str == '$') 653444c061aSmrg ) str++; 654444c061aSmrg return str; 655444c061aSmrg} 656444c061aSmrg 657444c061aSmrgstatic String FetchModifierToken( 658444c061aSmrg String str, 659444c061aSmrg XrmQuark *token_return) 660444c061aSmrg{ 661444c061aSmrg String start = str; 662444c061aSmrg 663444c061aSmrg if (*str == '$') { 664444c061aSmrg *token_return = QMeta; 665444c061aSmrg str++; 666444c061aSmrg return str; 667444c061aSmrg } 668444c061aSmrg if (*str == '^') { 669444c061aSmrg *token_return = QCtrl; 670444c061aSmrg str++; 671444c061aSmrg return str; 672444c061aSmrg } 673444c061aSmrg str = ScanIdent(str); 674444c061aSmrg if (start != str) { 675444c061aSmrg char modStrbuf[100]; 676444c061aSmrg char* modStr; 677444c061aSmrg 678444c061aSmrg modStr = XtStackAlloc ((size_t)(str - start + 1), modStrbuf); 679444c061aSmrg if (modStr == NULL) _XtAllocError (NULL); 680444c061aSmrg (void) memmove(modStr, start, str-start); 681444c061aSmrg modStr[str-start] = '\0'; 682444c061aSmrg *token_return = XrmStringToQuark(modStr); 683444c061aSmrg XtStackFree (modStr, modStrbuf); 684444c061aSmrg return str; 685444c061aSmrg } 686444c061aSmrg return str; 687444c061aSmrg} 688444c061aSmrg 689444c061aSmrgstatic String ParseModifiers( 690444c061aSmrg register String str, 691444c061aSmrg EventPtr event, 692444c061aSmrg Boolean* error) 693444c061aSmrg{ 694444c061aSmrg register String start; 695444c061aSmrg Boolean notFlag, exclusive, keysymAsMod; 696444c061aSmrg Value maskBit; 697444c061aSmrg XrmQuark Qmod; 698444c061aSmrg 699444c061aSmrg ScanWhitespace(str); 700444c061aSmrg start = str; 701444c061aSmrg str = FetchModifierToken(str, &Qmod); 702444c061aSmrg exclusive = FALSE; 703444c061aSmrg if (start != str) { 704444c061aSmrg if (Qmod == QNone) { 705444c061aSmrg event->event.modifierMask = ~0; 706444c061aSmrg event->event.modifiers = 0; 707444c061aSmrg ScanWhitespace(str); 708444c061aSmrg return str; 709444c061aSmrg } else if (Qmod == QAny) { /*backward compatability*/ 710444c061aSmrg event->event.modifierMask = 0; 711444c061aSmrg event->event.modifiers = AnyModifier; 712444c061aSmrg ScanWhitespace(str); 713444c061aSmrg return str; 714444c061aSmrg } 715444c061aSmrg str = start; /*if plain modifier, reset to beginning */ 716444c061aSmrg } 717444c061aSmrg else while (*str == '!' || *str == ':') { 718444c061aSmrg if (*str == '!') { 719444c061aSmrg exclusive = TRUE; 720444c061aSmrg str++; 721444c061aSmrg ScanWhitespace(str); 722444c061aSmrg } 723444c061aSmrg if (*str == ':') { 724444c061aSmrg event->event.standard = TRUE; 725444c061aSmrg str++; 726444c061aSmrg ScanWhitespace(str); 727444c061aSmrg } 728444c061aSmrg } 729444c061aSmrg 730444c061aSmrg while (*str != '<') { 731444c061aSmrg if (*str == '~') { 732444c061aSmrg notFlag = TRUE; 733444c061aSmrg str++; 734444c061aSmrg } else 735444c061aSmrg notFlag = FALSE; 736444c061aSmrg if (*str == '@') { 737444c061aSmrg keysymAsMod = TRUE; 738444c061aSmrg str++; 739444c061aSmrg } 740444c061aSmrg else keysymAsMod = FALSE; 741444c061aSmrg start = str; 742444c061aSmrg str = FetchModifierToken(str, &Qmod); 743444c061aSmrg if (start == str) { 744444c061aSmrg Syntax("Modifier or '<' expected",""); 745444c061aSmrg *error = TRUE; 746444c061aSmrg return PanicModeRecovery(str); 747444c061aSmrg } 748444c061aSmrg if (keysymAsMod) { 749444c061aSmrg _XtParseKeysymMod(XrmQuarkToString(Qmod), 750444c061aSmrg &event->event.lateModifiers, 751444c061aSmrg notFlag,&maskBit, error); 752444c061aSmrg if (*error) 753444c061aSmrg return PanicModeRecovery(str); 754444c061aSmrg 755444c061aSmrg } else 756444c061aSmrg if (!_XtLookupModifier(Qmod, &event->event.lateModifiers, 757444c061aSmrg notFlag, &maskBit, FALSE)) { 758444c061aSmrg Syntax("Unknown modifier name: ", XrmQuarkToString(Qmod)); 759444c061aSmrg *error = TRUE; 760444c061aSmrg return PanicModeRecovery(str); 761444c061aSmrg } 762444c061aSmrg event->event.modifierMask |= maskBit; 763444c061aSmrg if (notFlag) event->event.modifiers &= ~maskBit; 764444c061aSmrg else event->event.modifiers |= maskBit; 765444c061aSmrg ScanWhitespace(str); 766444c061aSmrg } 767444c061aSmrg if (exclusive) event->event.modifierMask = ~0; 768444c061aSmrg return str; 769444c061aSmrg} 770444c061aSmrg 771444c061aSmrgstatic String ParseXtEventType( 772444c061aSmrg register String str, 773444c061aSmrg EventPtr event, 774444c061aSmrg Cardinal *tmEventP, 775444c061aSmrg Boolean* error) 776444c061aSmrg{ 777444c061aSmrg String start = str; 778444c061aSmrg char eventTypeStrbuf[100]; 779444c061aSmrg char* eventTypeStr; 780444c061aSmrg 781444c061aSmrg ScanAlphanumeric(str); 782444c061aSmrg eventTypeStr = XtStackAlloc ((size_t)(str - start + 1), eventTypeStrbuf); 783444c061aSmrg if (eventTypeStr == NULL) _XtAllocError (NULL); 784444c061aSmrg (void) memmove(eventTypeStr, start, str-start); 785444c061aSmrg eventTypeStr[str-start] = '\0'; 786444c061aSmrg *tmEventP = LookupTMEventType(eventTypeStr,error); 787444c061aSmrg XtStackFree (eventTypeStr, eventTypeStrbuf); 788444c061aSmrg if (*error) 789444c061aSmrg return PanicModeRecovery(str); 790444c061aSmrg event->event.eventType = events[*tmEventP].eventType; 791444c061aSmrg return str; 792444c061aSmrg} 793444c061aSmrg 794444c061aSmrgstatic unsigned long StrToHex( 795444c061aSmrg String str) 796444c061aSmrg{ 797444c061aSmrg register char c; 798444c061aSmrg register unsigned long val = 0; 799444c061aSmrg 800444c061aSmrg while ((c = *str)) { 801444c061aSmrg if ('0' <= c && c <= '9') val = val*16+c-'0'; 802444c061aSmrg else if ('a' <= c && c <= 'z') val = val*16+c-'a'+10; 803444c061aSmrg else if ('A' <= c && c <= 'Z') val = val*16+c-'A'+10; 804444c061aSmrg else return 0; 805444c061aSmrg str++; 806444c061aSmrg } 807444c061aSmrg 808444c061aSmrg return val; 809444c061aSmrg} 810444c061aSmrg 811444c061aSmrgstatic unsigned long StrToOct( 812444c061aSmrg String str) 813444c061aSmrg{ 814444c061aSmrg register char c; 815444c061aSmrg register unsigned long val = 0; 816444c061aSmrg 817444c061aSmrg while ((c = *str)) { 818444c061aSmrg if ('0' <= c && c <= '7') val = val*8+c-'0'; else return 0; 819444c061aSmrg str++; 820444c061aSmrg } 821444c061aSmrg 822444c061aSmrg return val; 823444c061aSmrg} 824444c061aSmrg 825444c061aSmrgstatic unsigned long StrToNum( 826444c061aSmrg String str) 827444c061aSmrg{ 828444c061aSmrg register char c; 829444c061aSmrg register unsigned long val = 0; 830444c061aSmrg 831444c061aSmrg if (*str == '0') { 832444c061aSmrg str++; 833444c061aSmrg if (*str == 'x' || *str == 'X') return StrToHex(++str); 834444c061aSmrg else return StrToOct(str); 835444c061aSmrg } 836444c061aSmrg 837444c061aSmrg while ((c = *str)) { 838444c061aSmrg if ('0' <= c && c <= '9') val = val*10+c-'0'; 839444c061aSmrg else return 0; 840444c061aSmrg str++; 841444c061aSmrg } 842444c061aSmrg 843444c061aSmrg return val; 844444c061aSmrg} 845444c061aSmrg 846444c061aSmrgstatic KeySym StringToKeySym( 847444c061aSmrg String str, 848444c061aSmrg Boolean *error) 849444c061aSmrg{ 850444c061aSmrg KeySym k; 851444c061aSmrg 852444c061aSmrg if (str == NULL || *str == '\0') return (KeySym) 0; 853444c061aSmrg 854444c061aSmrg#ifndef NOTASCII 855444c061aSmrg /* special case single character ASCII, for speed */ 856444c061aSmrg if (*(str+1) == '\0') { 857444c061aSmrg if (' ' <= *str && *str <= '~') return XK_space + (*str - ' '); 858444c061aSmrg } 859444c061aSmrg#endif 860444c061aSmrg 861444c061aSmrg if ('0' <= *str && *str <= '9') return (KeySym) StrToNum(str); 862444c061aSmrg k = XStringToKeysym(str); 863444c061aSmrg if (k != NoSymbol) return k; 864444c061aSmrg 865444c061aSmrg#ifdef NOTASCII 866444c061aSmrg /* fall-back case to preserve backwards compatibility; no-one 867444c061aSmrg * should be relying upon this! 868444c061aSmrg */ 869444c061aSmrg if (*(str+1) == '\0') return (KeySym) *str; 870444c061aSmrg#endif 871444c061aSmrg 872444c061aSmrg Syntax("Unknown keysym name: ", str); 873444c061aSmrg *error = TRUE; 874444c061aSmrg return NoSymbol; 875444c061aSmrg} 876444c061aSmrg/* ARGSUSED */ 877444c061aSmrgstatic void ParseModImmed( 878444c061aSmrg Value value, 879444c061aSmrg LateBindingsPtr* lateBindings, 880444c061aSmrg Boolean notFlag, 881444c061aSmrg Value* valueP) 882444c061aSmrg{ 883444c061aSmrg *valueP = value; 884444c061aSmrg} 885444c061aSmrg 886444c061aSmrg /* is only valid with keysyms that have an _L and _R in their name; 887444c061aSmrg * and ignores keysym lookup errors (i.e. assumes only valid keysyms) 888444c061aSmrg */ 889444c061aSmrgstatic void ParseModSym( 890444c061aSmrg Value value, 891444c061aSmrg LateBindingsPtr* lateBindings, 892444c061aSmrg Boolean notFlag, 893444c061aSmrg Value* valueP) 894444c061aSmrg{ 895444c061aSmrg register KeySym keysymL = (KeySym)value; 896444c061aSmrg register KeySym keysymR = keysymL + 1; /* valid for supported keysyms */ 897444c061aSmrg StoreLateBindings(keysymL,notFlag,keysymR,notFlag,lateBindings); 898444c061aSmrg *valueP = 0; 899444c061aSmrg} 900444c061aSmrg 901444c061aSmrg#ifdef sparc 902444c061aSmrg/* 903444c061aSmrg * The stupid optimizer in SunOS 4.0.3 and below generates bogus code that 904444c061aSmrg * causes the value of the most recently used variable to be returned instead 905444c061aSmrg * of the value passed in. 906444c061aSmrg */ 907444c061aSmrgstatic String stupid_optimizer_kludge; 908444c061aSmrg#define BROKEN_OPTIMIZER_HACK(val) stupid_optimizer_kludge = (val) 909444c061aSmrg#else 910444c061aSmrg#define BROKEN_OPTIMIZER_HACK(val) val 911444c061aSmrg#endif 912444c061aSmrg 913444c061aSmrg/* ARGSUSED */ 914444c061aSmrgstatic String ParseImmed( 915444c061aSmrg register String str, 916444c061aSmrg register Opaque closure, 917444c061aSmrg register EventPtr event, 918444c061aSmrg Boolean* error) 919444c061aSmrg{ 920444c061aSmrg event->event.eventCode = (unsigned long)closure; 921444c061aSmrg event->event.eventCodeMask = ~0UL; 922444c061aSmrg 923444c061aSmrg return BROKEN_OPTIMIZER_HACK(str); 924444c061aSmrg} 925444c061aSmrg 926444c061aSmrg/* ARGSUSED */ 927444c061aSmrgstatic String ParseAddModifier( 928444c061aSmrg register String str, 929444c061aSmrg register Opaque closure, 930444c061aSmrg register EventPtr event, 931444c061aSmrg Boolean* error) 932444c061aSmrg{ 933444c061aSmrg register unsigned long modval = (unsigned long)closure; 934444c061aSmrg event->event.modifiers |= modval; 935444c061aSmrg if (modval != AnyButtonMask) /* AnyButtonMask is don't-care mask */ 936444c061aSmrg event->event.modifierMask |= modval; 937444c061aSmrg 938444c061aSmrg return BROKEN_OPTIMIZER_HACK(str); 939444c061aSmrg} 940444c061aSmrg 941444c061aSmrg 942444c061aSmrgstatic String ParseKeyAndModifiers( 943444c061aSmrg String str, 944444c061aSmrg Opaque closure, 945444c061aSmrg EventPtr event, 946444c061aSmrg Boolean* error) 947444c061aSmrg{ 948444c061aSmrg str = ParseKeySym(str, closure, event,error); 949444c061aSmrg if ((unsigned long) closure == 0) { 950444c061aSmrg Value metaMask; /* unused */ 951444c061aSmrg (void) _XtLookupModifier(QMeta, &event->event.lateModifiers, FALSE, 952444c061aSmrg &metaMask, FALSE); 953444c061aSmrg } else { 954444c061aSmrg event->event.modifiers |= (unsigned long) closure; 955444c061aSmrg event->event.modifierMask |= (unsigned long) closure; 956444c061aSmrg } 957444c061aSmrg return str; 958444c061aSmrg} 959444c061aSmrg 960444c061aSmrg/*ARGSUSED*/ 961444c061aSmrgstatic String ParseKeySym( 962444c061aSmrg register String str, 963444c061aSmrg Opaque closure, 964444c061aSmrg EventPtr event, 965444c061aSmrg Boolean* error) 966444c061aSmrg{ 967444c061aSmrg char *start; 968444c061aSmrg char keySymNamebuf[100]; 969444c061aSmrg char* keySymName; 970444c061aSmrg 971444c061aSmrg ScanWhitespace(str); 972444c061aSmrg 973444c061aSmrg if (*str == '\\') { 974444c061aSmrg keySymName = keySymNamebuf; 975444c061aSmrg str++; 976444c061aSmrg keySymName[0] = *str; 977444c061aSmrg if (*str != '\0' && !IsNewline(*str)) str++; 978444c061aSmrg keySymName[1] = '\0'; 979444c061aSmrg event->event.eventCode = StringToKeySym(keySymName, error); 980444c061aSmrg event->event.eventCodeMask = ~0L; 981444c061aSmrg } else if (*str == ',' || *str == ':' || 982444c061aSmrg /* allow leftparen to be single char symbol, 983444c061aSmrg * for backwards compatibility 984444c061aSmrg */ 985444c061aSmrg (*str == '(' && *(str+1) >= '0' && *(str+1) <= '9')) { 986444c061aSmrg keySymName = keySymNamebuf; /* just so we can stackfree it later */ 987444c061aSmrg /* no detail */ 988444c061aSmrg event->event.eventCode = 0L; 989444c061aSmrg event->event.eventCodeMask = 0L; 990444c061aSmrg } else { 991444c061aSmrg start = str; 992444c061aSmrg while ( 993444c061aSmrg *str != ',' 994444c061aSmrg && *str != ':' 995444c061aSmrg && *str != ' ' 996444c061aSmrg && *str != '\t' 997444c061aSmrg && !IsNewline(*str) 998444c061aSmrg && (*str != '(' || *(str+1) <= '0' || *(str+1) >= '9') 999444c061aSmrg && *str != '\0') str++; 1000444c061aSmrg keySymName = XtStackAlloc ((size_t)(str - start + 1), keySymNamebuf); 1001444c061aSmrg (void) memmove(keySymName, start, str-start); 1002444c061aSmrg keySymName[str-start] = '\0'; 1003444c061aSmrg event->event.eventCode = StringToKeySym(keySymName, error); 1004444c061aSmrg event->event.eventCodeMask = ~0L; 1005444c061aSmrg } 1006444c061aSmrg if (*error) { 1007444c061aSmrg /* We never get here when keySymName hasn't been allocated */ 1008444c061aSmrg if (keySymName[0] == '<') { 1009444c061aSmrg /* special case for common error */ 1010444c061aSmrg XtWarningMsg(XtNtranslationParseError, "missingComma", 1011444c061aSmrg XtCXtToolkitError, 1012444c061aSmrg "... possibly due to missing ',' in event sequence.", 1013444c061aSmrg (String*)NULL, (Cardinal*)NULL); 1014444c061aSmrg } 1015444c061aSmrg XtStackFree (keySymName, keySymNamebuf); 1016444c061aSmrg return PanicModeRecovery(str); 1017444c061aSmrg } 1018444c061aSmrg if (event->event.standard) 1019444c061aSmrg event->event.matchEvent = _XtMatchUsingStandardMods; 1020444c061aSmrg else 1021444c061aSmrg event->event.matchEvent = _XtMatchUsingDontCareMods; 1022444c061aSmrg 1023444c061aSmrg XtStackFree (keySymName, keySymNamebuf); 1024444c061aSmrg 1025444c061aSmrg return str; 1026444c061aSmrg} 1027444c061aSmrg 1028444c061aSmrgstatic String ParseTable( 1029444c061aSmrg register String str, 1030444c061aSmrg Opaque closure, 1031444c061aSmrg EventPtr event, 1032444c061aSmrg Boolean* error) 1033444c061aSmrg{ 1034444c061aSmrg register String start = str; 1035444c061aSmrg register XrmQuark signature; 1036444c061aSmrg NameValueTable table = (NameValueTable) closure; 1037444c061aSmrg char tableSymName[100]; 1038444c061aSmrg 1039444c061aSmrg event->event.eventCode = 0L; 1040444c061aSmrg ScanAlphanumeric(str); 1041444c061aSmrg if (str == start) {event->event.eventCodeMask = 0L; return str; } 1042444c061aSmrg if (str-start >= 99) { 1043444c061aSmrg Syntax("Invalid Detail Type (string is too long).", ""); 1044444c061aSmrg *error = TRUE; 1045444c061aSmrg return str; 1046444c061aSmrg } 1047444c061aSmrg (void) memmove(tableSymName, start, str-start); 1048444c061aSmrg tableSymName[str-start] = '\0'; 1049444c061aSmrg signature = StringToQuark(tableSymName); 1050444c061aSmrg for (; table->signature != NULLQUARK; table++) 1051444c061aSmrg if (table->signature == signature) { 1052444c061aSmrg event->event.eventCode = table->value; 1053444c061aSmrg event->event.eventCodeMask = ~0L; 1054444c061aSmrg return str; 1055444c061aSmrg } 1056444c061aSmrg 1057444c061aSmrg Syntax("Unknown Detail Type: ", tableSymName); 1058444c061aSmrg *error = TRUE; 1059444c061aSmrg return PanicModeRecovery(str); 1060444c061aSmrg} 1061444c061aSmrg 1062444c061aSmrg/*ARGSUSED*/ 1063444c061aSmrgstatic String ParseNone( 1064444c061aSmrg String str, 1065444c061aSmrg Opaque closure, 1066444c061aSmrg EventPtr event, 1067444c061aSmrg Boolean* error) 1068444c061aSmrg{ 1069444c061aSmrg event->event.eventCode = 0; 1070444c061aSmrg event->event.eventCodeMask = 0; 1071444c061aSmrg 1072444c061aSmrg return BROKEN_OPTIMIZER_HACK(str); 1073444c061aSmrg} 1074444c061aSmrg 1075444c061aSmrg/*ARGSUSED*/ 1076444c061aSmrgstatic String ParseAtom( 1077444c061aSmrg String str, 1078444c061aSmrg Opaque closure, 1079444c061aSmrg EventPtr event, 1080444c061aSmrg Boolean* error) 1081444c061aSmrg{ 1082444c061aSmrg ScanWhitespace(str); 1083444c061aSmrg 1084444c061aSmrg if (*str == ',' || *str == ':') { 1085444c061aSmrg /* no detail */ 1086444c061aSmrg event->event.eventCode = 0L; 1087444c061aSmrg event->event.eventCodeMask = 0L; 1088444c061aSmrg } else { 1089444c061aSmrg char *start, atomName[1000]; 1090444c061aSmrg start = str; 1091444c061aSmrg while ( 1092444c061aSmrg *str != ',' 1093444c061aSmrg && *str != ':' 1094444c061aSmrg && *str != ' ' 1095444c061aSmrg && *str != '\t' 1096444c061aSmrg && !IsNewline(*str) 1097444c061aSmrg && *str != '\0') str++; 1098444c061aSmrg if (str-start >= 999) { 1099444c061aSmrg Syntax( "Atom name must be less than 1000 characters long.", "" ); 1100444c061aSmrg *error = TRUE; 1101444c061aSmrg return str; 1102444c061aSmrg } 1103444c061aSmrg (void) memmove(atomName, start, str-start); 1104444c061aSmrg atomName[str-start] = '\0'; 1105444c061aSmrg event->event.eventCode = XrmStringToQuark(atomName); 1106444c061aSmrg event->event.matchEvent = _XtMatchAtom; 1107444c061aSmrg } 1108444c061aSmrg return str; 1109444c061aSmrg} 1110444c061aSmrg 1111444c061aSmrgstatic ModifierMask buttonModifierMasks[] = { 1112444c061aSmrg 0, Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask 1113444c061aSmrg}; 1114444c061aSmrgstatic String ParseRepeat(String, int *, Boolean *, Boolean *); 1115444c061aSmrg 1116444c061aSmrgstatic String ParseEvent( 1117444c061aSmrg register String str, 1118444c061aSmrg EventPtr event, 1119444c061aSmrg int* reps, 1120444c061aSmrg Boolean* plus, 1121444c061aSmrg Boolean* error) 1122444c061aSmrg{ 1123444c061aSmrg Cardinal tmEvent; 1124444c061aSmrg 1125444c061aSmrg str = ParseModifiers(str, event,error); 1126444c061aSmrg if (*error) return str; 1127444c061aSmrg if (*str != '<') { 1128444c061aSmrg Syntax("Missing '<' while parsing event type.",""); 1129444c061aSmrg *error = TRUE; 1130444c061aSmrg return PanicModeRecovery(str); 1131444c061aSmrg } 1132444c061aSmrg else str++; 1133444c061aSmrg str = ParseXtEventType(str, event, &tmEvent,error); 1134444c061aSmrg if (*error) return str; 1135444c061aSmrg if (*str != '>'){ 1136444c061aSmrg Syntax("Missing '>' while parsing event type",""); 1137444c061aSmrg *error = TRUE; 1138444c061aSmrg return PanicModeRecovery(str); 1139444c061aSmrg } 1140444c061aSmrg else str++; 1141444c061aSmrg if (*str == '(') { 1142444c061aSmrg str = ParseRepeat(str, reps, plus, error); 1143444c061aSmrg if (*error) return str; 1144444c061aSmrg } 1145444c061aSmrg str = (*(events[tmEvent].parseDetail))( 1146444c061aSmrg str, events[tmEvent].closure, event,error); 1147444c061aSmrg if (*error) return str; 1148444c061aSmrg 1149444c061aSmrg/* gross hack! ||| this kludge is related to the X11 protocol deficiency w.r.t. 1150444c061aSmrg * modifiers in grabs. 1151444c061aSmrg */ 1152444c061aSmrg if ((event->event.eventType == ButtonRelease) 1153444c061aSmrg && (event->event.modifiers | event->event.modifierMask) /* any */ 1154444c061aSmrg && (event->event.modifiers != AnyModifier)) 1155444c061aSmrg { 1156444c061aSmrg event->event.modifiers 1157444c061aSmrg |= buttonModifierMasks[event->event.eventCode]; 1158444c061aSmrg /* the button that is going up will always be in the modifiers... */ 1159444c061aSmrg } 1160444c061aSmrg 1161444c061aSmrg return str; 1162444c061aSmrg} 1163444c061aSmrg 1164444c061aSmrgstatic String ParseQuotedStringEvent( 1165444c061aSmrg register String str, 1166444c061aSmrg register EventPtr event, 1167444c061aSmrg Boolean *error) 1168444c061aSmrg{ 1169444c061aSmrg Value metaMask; 1170444c061aSmrg char s[2]; 1171444c061aSmrg 1172444c061aSmrg if (*str=='^') { 1173444c061aSmrg str++; 1174444c061aSmrg event->event.modifiers = ControlMask; 1175444c061aSmrg } else if (*str == '$') { 1176444c061aSmrg str++; 1177444c061aSmrg (void) _XtLookupModifier(QMeta, &event->event.lateModifiers, FALSE, 1178444c061aSmrg &metaMask, FALSE); 1179444c061aSmrg } 1180444c061aSmrg if (*str == '\\') 1181444c061aSmrg str++; 1182444c061aSmrg s[0] = *str; 1183444c061aSmrg s[1] = '\0'; 1184444c061aSmrg if (*str != '\0' && !IsNewline(*str)) str++; 1185444c061aSmrg event->event.eventType = KeyPress; 1186444c061aSmrg event->event.eventCode = StringToKeySym(s, error); 1187444c061aSmrg if (*error) return PanicModeRecovery(str); 1188444c061aSmrg event->event.eventCodeMask = ~0L; 1189444c061aSmrg event->event.matchEvent = _XtMatchUsingStandardMods; 1190444c061aSmrg event->event.standard = TRUE; 1191444c061aSmrg 1192444c061aSmrg return str; 1193444c061aSmrg} 1194444c061aSmrg 1195444c061aSmrg 1196444c061aSmrgstatic EventSeqRec timerEventRec = { 1197444c061aSmrg {0, 0, NULL, _XtEventTimerEventType, 0L, 0L, NULL, False}, 1198444c061aSmrg /* (StatePtr) -1 */ NULL, 1199444c061aSmrg NULL, 1200444c061aSmrg NULL 1201444c061aSmrg}; 1202444c061aSmrg 1203444c061aSmrgstatic void RepeatDown( 1204444c061aSmrg EventPtr *eventP, 1205444c061aSmrg int reps, 1206444c061aSmrg ActionPtr **actionsP) 1207444c061aSmrg{ 1208444c061aSmrg EventRec upEventRec; 1209444c061aSmrg register EventPtr event, downEvent; 1210444c061aSmrg EventPtr upEvent = &upEventRec; 1211444c061aSmrg register int i; 1212444c061aSmrg 1213444c061aSmrg downEvent = event = *eventP; 1214444c061aSmrg *upEvent = *downEvent; 1215444c061aSmrg upEvent->event.eventType = ((event->event.eventType == ButtonPress) ? 1216444c061aSmrg ButtonRelease : KeyRelease); 1217444c061aSmrg if ((upEvent->event.eventType == ButtonRelease) 1218444c061aSmrg && (upEvent->event.modifiers != AnyModifier) 1219444c061aSmrg && (upEvent->event.modifiers | upEvent->event.modifierMask)) 1220444c061aSmrg upEvent->event.modifiers 1221444c061aSmrg |= buttonModifierMasks[event->event.eventCode]; 1222444c061aSmrg 1223444c061aSmrg if (event->event.lateModifiers) 1224444c061aSmrg event->event.lateModifiers->ref_count += (reps - 1) * 2; 1225444c061aSmrg 1226444c061aSmrg for (i=1; i<reps; i++) { 1227444c061aSmrg 1228444c061aSmrg /* up */ 1229444c061aSmrg event->next = XtNew(EventSeqRec); 1230444c061aSmrg event = event->next; 1231444c061aSmrg *event = *upEvent; 1232444c061aSmrg 1233444c061aSmrg /* timer */ 1234444c061aSmrg event->next = XtNew(EventSeqRec); 1235444c061aSmrg event = event->next; 1236444c061aSmrg *event = timerEventRec; 1237444c061aSmrg 1238444c061aSmrg /* down */ 1239444c061aSmrg event->next = XtNew(EventSeqRec); 1240444c061aSmrg event = event->next; 1241444c061aSmrg *event = *downEvent; 1242444c061aSmrg 1243444c061aSmrg } 1244444c061aSmrg 1245444c061aSmrg event->next = NULL; 1246444c061aSmrg *eventP = event; 1247444c061aSmrg *actionsP = &event->actions; 1248444c061aSmrg} 1249444c061aSmrg 1250444c061aSmrgstatic void RepeatDownPlus( 1251444c061aSmrg EventPtr *eventP, 1252444c061aSmrg int reps, 1253444c061aSmrg ActionPtr **actionsP) 1254444c061aSmrg{ 1255444c061aSmrg EventRec upEventRec; 1256444c061aSmrg register EventPtr event, downEvent, lastDownEvent = NULL; 1257444c061aSmrg EventPtr upEvent = &upEventRec; 1258444c061aSmrg register int i; 1259444c061aSmrg 1260444c061aSmrg downEvent = event = *eventP; 1261444c061aSmrg *upEvent = *downEvent; 1262444c061aSmrg upEvent->event.eventType = ((event->event.eventType == ButtonPress) ? 1263444c061aSmrg ButtonRelease : KeyRelease); 1264444c061aSmrg if ((upEvent->event.eventType == ButtonRelease) 1265444c061aSmrg && (upEvent->event.modifiers != AnyModifier) 1266444c061aSmrg && (upEvent->event.modifiers | upEvent->event.modifierMask)) 1267444c061aSmrg upEvent->event.modifiers 1268444c061aSmrg |= buttonModifierMasks[event->event.eventCode]; 1269444c061aSmrg 1270444c061aSmrg if (event->event.lateModifiers) 1271444c061aSmrg event->event.lateModifiers->ref_count += reps * 2 - 1; 1272444c061aSmrg 1273444c061aSmrg for (i=0; i<reps; i++) { 1274444c061aSmrg 1275444c061aSmrg if (i > 0) { 1276444c061aSmrg /* down */ 1277444c061aSmrg event->next = XtNew(EventSeqRec); 1278444c061aSmrg event = event->next; 1279444c061aSmrg *event = *downEvent; 1280444c061aSmrg } 1281444c061aSmrg lastDownEvent = event; 1282444c061aSmrg 1283444c061aSmrg /* up */ 1284444c061aSmrg event->next = XtNew(EventSeqRec); 1285444c061aSmrg event = event->next; 1286444c061aSmrg *event = *upEvent; 1287444c061aSmrg 1288444c061aSmrg /* timer */ 1289444c061aSmrg event->next = XtNew(EventSeqRec); 1290444c061aSmrg event = event->next; 1291444c061aSmrg *event = timerEventRec; 1292444c061aSmrg 1293444c061aSmrg } 1294444c061aSmrg 1295444c061aSmrg event->next = lastDownEvent; 1296444c061aSmrg *eventP = event; 1297444c061aSmrg *actionsP = &lastDownEvent->actions; 1298444c061aSmrg} 1299444c061aSmrg 1300444c061aSmrgstatic void RepeatUp( 1301444c061aSmrg EventPtr *eventP, 1302444c061aSmrg int reps, 1303444c061aSmrg ActionPtr **actionsP) 1304444c061aSmrg{ 1305444c061aSmrg EventRec upEventRec; 1306444c061aSmrg register EventPtr event, downEvent; 1307444c061aSmrg EventPtr upEvent = &upEventRec; 1308444c061aSmrg register int i; 1309444c061aSmrg 1310444c061aSmrg /* the event currently sitting in *eventP is an "up" event */ 1311444c061aSmrg /* we want to make it a "down" event followed by an "up" event, */ 1312444c061aSmrg /* so that sequence matching on the "state" side works correctly. */ 1313444c061aSmrg 1314444c061aSmrg downEvent = event = *eventP; 1315444c061aSmrg *upEvent = *downEvent; 1316444c061aSmrg downEvent->event.eventType = ((event->event.eventType == ButtonRelease) ? 1317444c061aSmrg ButtonPress : KeyPress); 1318444c061aSmrg if ((downEvent->event.eventType == ButtonPress) 1319444c061aSmrg && (downEvent->event.modifiers != AnyModifier) 1320444c061aSmrg && (downEvent->event.modifiers | downEvent->event.modifierMask)) 1321444c061aSmrg downEvent->event.modifiers 1322444c061aSmrg &= ~buttonModifierMasks[event->event.eventCode]; 1323444c061aSmrg 1324444c061aSmrg if (event->event.lateModifiers) 1325444c061aSmrg event->event.lateModifiers->ref_count += reps * 2 - 1; 1326444c061aSmrg 1327444c061aSmrg /* up */ 1328444c061aSmrg event->next = XtNew(EventSeqRec); 1329444c061aSmrg event = event->next; 1330444c061aSmrg *event = *upEvent; 1331444c061aSmrg 1332444c061aSmrg for (i=1; i<reps; i++) { 1333444c061aSmrg 1334444c061aSmrg /* timer */ 1335444c061aSmrg event->next = XtNew(EventSeqRec); 1336444c061aSmrg event = event->next; 1337444c061aSmrg *event = timerEventRec; 1338444c061aSmrg 1339444c061aSmrg /* down */ 1340444c061aSmrg event->next = XtNew(EventSeqRec); 1341444c061aSmrg event = event->next; 1342444c061aSmrg *event = *downEvent; 1343444c061aSmrg 1344444c061aSmrg /* up */ 1345444c061aSmrg event->next = XtNew(EventSeqRec); 1346444c061aSmrg event = event->next; 1347444c061aSmrg *event = *upEvent; 1348444c061aSmrg 1349444c061aSmrg } 1350444c061aSmrg 1351444c061aSmrg event->next = NULL; 1352444c061aSmrg *eventP = event; 1353444c061aSmrg *actionsP = &event->actions; 1354444c061aSmrg} 1355444c061aSmrg 1356444c061aSmrgstatic void RepeatUpPlus( 1357444c061aSmrg EventPtr *eventP, 1358444c061aSmrg int reps, 1359444c061aSmrg ActionPtr **actionsP) 1360444c061aSmrg{ 1361444c061aSmrg EventRec upEventRec; 1362444c061aSmrg register EventPtr event, downEvent, lastUpEvent = NULL; 1363444c061aSmrg EventPtr upEvent = &upEventRec; 1364444c061aSmrg register int i; 1365444c061aSmrg 1366444c061aSmrg /* the event currently sitting in *eventP is an "up" event */ 1367444c061aSmrg /* we want to make it a "down" event followed by an "up" event, */ 1368444c061aSmrg /* so that sequence matching on the "state" side works correctly. */ 1369444c061aSmrg 1370444c061aSmrg downEvent = event = *eventP; 1371444c061aSmrg *upEvent = *downEvent; 1372444c061aSmrg downEvent->event.eventType = ((event->event.eventType == ButtonRelease) ? 1373444c061aSmrg ButtonPress : KeyPress); 1374444c061aSmrg if ((downEvent->event.eventType == ButtonPress) 1375444c061aSmrg && (downEvent->event.modifiers != AnyModifier) 1376444c061aSmrg && (downEvent->event.modifiers | downEvent->event.modifierMask)) 1377444c061aSmrg downEvent->event.modifiers 1378444c061aSmrg &= ~buttonModifierMasks[event->event.eventCode]; 1379444c061aSmrg 1380444c061aSmrg if (event->event.lateModifiers) 1381444c061aSmrg event->event.lateModifiers->ref_count += reps * 2; 1382444c061aSmrg 1383444c061aSmrg for (i=0; i<reps; i++) { 1384444c061aSmrg 1385444c061aSmrg /* up */ 1386444c061aSmrg event->next = XtNew(EventSeqRec); 1387444c061aSmrg lastUpEvent = event = event->next; 1388444c061aSmrg *event = *upEvent; 1389444c061aSmrg 1390444c061aSmrg /* timer */ 1391444c061aSmrg event->next = XtNew(EventSeqRec); 1392444c061aSmrg event = event->next; 1393444c061aSmrg *event = timerEventRec; 1394444c061aSmrg 1395444c061aSmrg /* down */ 1396444c061aSmrg event->next = XtNew(EventSeqRec); 1397444c061aSmrg event = event->next; 1398444c061aSmrg *event = *downEvent; 1399444c061aSmrg 1400444c061aSmrg } 1401444c061aSmrg 1402444c061aSmrg event->next = lastUpEvent; 1403444c061aSmrg *eventP = event; 1404444c061aSmrg *actionsP = &lastUpEvent->actions; 1405444c061aSmrg} 1406444c061aSmrg 1407444c061aSmrgstatic void RepeatOther( 1408444c061aSmrg EventPtr *eventP, 1409444c061aSmrg int reps, 1410444c061aSmrg ActionPtr **actionsP) 1411444c061aSmrg{ 1412444c061aSmrg register EventPtr event, tempEvent; 1413444c061aSmrg register int i; 1414444c061aSmrg 1415444c061aSmrg tempEvent = event = *eventP; 1416444c061aSmrg 1417444c061aSmrg if (event->event.lateModifiers) 1418444c061aSmrg event->event.lateModifiers->ref_count += reps - 1; 1419444c061aSmrg 1420444c061aSmrg for (i=1; i<reps; i++) { 1421444c061aSmrg event->next = XtNew(EventSeqRec); 1422444c061aSmrg event = event->next; 1423444c061aSmrg *event = *tempEvent; 1424444c061aSmrg } 1425444c061aSmrg 1426444c061aSmrg *eventP = event; 1427444c061aSmrg *actionsP = &event->actions; 1428444c061aSmrg} 1429444c061aSmrg 1430444c061aSmrgstatic void RepeatOtherPlus( 1431444c061aSmrg EventPtr *eventP, 1432444c061aSmrg int reps, 1433444c061aSmrg ActionPtr **actionsP) 1434444c061aSmrg{ 1435444c061aSmrg register EventPtr event, tempEvent; 1436444c061aSmrg register int i; 1437444c061aSmrg 1438444c061aSmrg tempEvent = event = *eventP; 1439444c061aSmrg 1440444c061aSmrg if (event->event.lateModifiers) 1441444c061aSmrg event->event.lateModifiers->ref_count += reps - 1; 1442444c061aSmrg 1443444c061aSmrg for (i=1; i<reps; i++) { 1444444c061aSmrg event->next = XtNew(EventSeqRec); 1445444c061aSmrg event = event->next; 1446444c061aSmrg *event = *tempEvent; 1447444c061aSmrg } 1448444c061aSmrg 1449444c061aSmrg event->next = event; 1450444c061aSmrg *eventP = event; 1451444c061aSmrg *actionsP = &event->actions; 1452444c061aSmrg} 1453444c061aSmrg 1454444c061aSmrgstatic void RepeatEvent( 1455444c061aSmrg EventPtr *eventP, 1456444c061aSmrg int reps, 1457444c061aSmrg Boolean plus, 1458444c061aSmrg ActionPtr **actionsP) 1459444c061aSmrg{ 1460444c061aSmrg switch ((*eventP)->event.eventType) { 1461444c061aSmrg 1462444c061aSmrg case ButtonPress: 1463444c061aSmrg case KeyPress: 1464444c061aSmrg if (plus) RepeatDownPlus(eventP, reps, actionsP); 1465444c061aSmrg else RepeatDown(eventP, reps, actionsP); 1466444c061aSmrg break; 1467444c061aSmrg 1468444c061aSmrg case ButtonRelease: 1469444c061aSmrg case KeyRelease: 1470444c061aSmrg if (plus) RepeatUpPlus(eventP, reps, actionsP); 1471444c061aSmrg else RepeatUp(eventP, reps, actionsP); 1472444c061aSmrg break; 1473444c061aSmrg 1474444c061aSmrg default: 1475444c061aSmrg if (plus) RepeatOtherPlus(eventP, reps, actionsP); 1476444c061aSmrg else RepeatOther(eventP, reps, actionsP); 1477444c061aSmrg } 1478444c061aSmrg} 1479444c061aSmrg 1480444c061aSmrgstatic String ParseRepeat( 1481444c061aSmrg register String str, 1482444c061aSmrg int *reps, 1483444c061aSmrg Boolean *plus, Boolean *error) 1484444c061aSmrg{ 1485444c061aSmrg 1486444c061aSmrg /*** Parse the repetitions, for double click etc... ***/ 1487444c061aSmrg if (*str != '(' || !(isdigit(str[1]) || str[1] == '+' || str[1] == ')')) 1488444c061aSmrg return str; 1489444c061aSmrg str++; 1490444c061aSmrg if (isdigit(*str)) { 1491444c061aSmrg String start = str; 1492444c061aSmrg char repStr[7]; 1493444c061aSmrg size_t len; 1494444c061aSmrg 1495444c061aSmrg ScanNumeric(str); 1496444c061aSmrg len = (str - start); 1497444c061aSmrg if (len < sizeof repStr) { 1498444c061aSmrg (void) memmove(repStr, start, len); 1499444c061aSmrg repStr[len] = '\0'; 1500444c061aSmrg *reps = StrToNum(repStr); 1501444c061aSmrg } else { 1502444c061aSmrg Syntax("Repeat count too large.", ""); 1503444c061aSmrg *error = TRUE; 1504444c061aSmrg return str; 1505444c061aSmrg } 1506444c061aSmrg } 1507444c061aSmrg if (*reps == 0) { 1508444c061aSmrg Syntax("Missing repeat count.",""); 1509444c061aSmrg *error = True; 1510444c061aSmrg return str; 1511444c061aSmrg } 1512444c061aSmrg 1513444c061aSmrg if (*str == '+') { 1514444c061aSmrg *plus = TRUE; 1515444c061aSmrg str++; 1516444c061aSmrg } 1517444c061aSmrg if (*str == ')') 1518444c061aSmrg str++; 1519444c061aSmrg else { 1520444c061aSmrg Syntax("Missing ')'.",""); 1521444c061aSmrg *error = TRUE; 1522444c061aSmrg } 1523444c061aSmrg 1524444c061aSmrg return str; 1525444c061aSmrg} 1526444c061aSmrg 1527444c061aSmrg/*********************************************************************** 1528444c061aSmrg * ParseEventSeq 1529444c061aSmrg * Parses the left hand side of a translation table production 1530444c061aSmrg * up to, and consuming the ":". 1531444c061aSmrg * Takes a pointer to a char* (where to start parsing) and returns an 1532444c061aSmrg * event seq (in a passed in variable), having updated the String 1533444c061aSmrg **********************************************************************/ 1534444c061aSmrg 1535444c061aSmrgstatic String ParseEventSeq( 1536444c061aSmrg register String str, 1537444c061aSmrg EventSeqPtr *eventSeqP, 1538444c061aSmrg ActionPtr **actionsP, 1539444c061aSmrg Boolean *error) 1540444c061aSmrg{ 1541444c061aSmrg EventSeqPtr *nextEvent = eventSeqP; 1542444c061aSmrg 1543444c061aSmrg *eventSeqP = NULL; 1544444c061aSmrg 1545444c061aSmrg while ( *str != '\0' && !IsNewline(*str)) { 1546444c061aSmrg static Event nullEvent = 15472265a131Smrg {0, 0,NULL, 0, 0L, 0L,_XtRegularMatch,FALSE}; 1548444c061aSmrg EventPtr event; 1549444c061aSmrg 1550444c061aSmrg ScanWhitespace(str); 1551444c061aSmrg 1552444c061aSmrg if (*str == '"') { 1553444c061aSmrg str++; 1554444c061aSmrg while (*str != '"' && *str != '\0' && !IsNewline(*str)) { 1555444c061aSmrg event = XtNew(EventRec); 1556444c061aSmrg event->event = nullEvent; 1557444c061aSmrg event->state = /* (StatePtr) -1 */ NULL; 1558444c061aSmrg event->next = NULL; 1559444c061aSmrg event->actions = NULL; 1560444c061aSmrg str = ParseQuotedStringEvent(str, event,error); 1561444c061aSmrg if (*error) { 1562444c061aSmrg XtWarningMsg(XtNtranslationParseError, "nonLatin1", 1563444c061aSmrg XtCXtToolkitError, 1564444c061aSmrg "... probably due to non-Latin1 character in quoted string", 1565444c061aSmrg (String*)NULL, (Cardinal*)NULL); 1566444c061aSmrg return PanicModeRecovery(str); 1567444c061aSmrg } 1568444c061aSmrg *nextEvent = event; 1569444c061aSmrg *actionsP = &event->actions; 1570444c061aSmrg nextEvent = &event->next; 1571444c061aSmrg } 1572444c061aSmrg if (*str != '"') { 1573444c061aSmrg Syntax("Missing '\"'.",""); 1574444c061aSmrg *error = TRUE; 1575444c061aSmrg return PanicModeRecovery(str); 1576444c061aSmrg } 1577444c061aSmrg else str++; 1578444c061aSmrg } else { 1579444c061aSmrg int reps = 0; 1580444c061aSmrg Boolean plus = FALSE; 1581444c061aSmrg 1582444c061aSmrg event = XtNew(EventRec); 1583444c061aSmrg event->event = nullEvent; 1584444c061aSmrg event->state = /* (StatePtr) -1 */ NULL; 1585444c061aSmrg event->next = NULL; 1586444c061aSmrg event->actions = NULL; 1587444c061aSmrg 1588444c061aSmrg str = ParseEvent(str, event, &reps, &plus, error); 1589444c061aSmrg if (*error) return str; 1590444c061aSmrg *nextEvent = event; 1591444c061aSmrg *actionsP = &event->actions; 1592444c061aSmrg if (reps > 1 || plus) 1593444c061aSmrg RepeatEvent(&event, reps, plus, actionsP); 1594444c061aSmrg nextEvent = &event->next; 1595444c061aSmrg } 1596444c061aSmrg ScanWhitespace(str); 1597444c061aSmrg if (*str == ':') break; 1598444c061aSmrg else { 1599444c061aSmrg if (*str != ',') { 1600444c061aSmrg Syntax("',' or ':' expected while parsing event sequence.",""); 1601444c061aSmrg *error = TRUE; 1602444c061aSmrg return PanicModeRecovery(str); 1603444c061aSmrg } else str++; 1604444c061aSmrg } 1605444c061aSmrg } 1606444c061aSmrg 1607444c061aSmrg if (*str != ':') { 1608444c061aSmrg Syntax("Missing ':'after event sequence.",""); 1609444c061aSmrg *error = TRUE; 1610444c061aSmrg return PanicModeRecovery(str); 1611444c061aSmrg } else str++; 1612444c061aSmrg 1613444c061aSmrg return str; 1614444c061aSmrg} 1615444c061aSmrg 1616444c061aSmrg 1617444c061aSmrgstatic String ParseActionProc( 1618444c061aSmrg register String str, 1619444c061aSmrg XrmQuark *actionProcNameP, 1620444c061aSmrg Boolean *error) 1621444c061aSmrg{ 1622444c061aSmrg register String start = str; 1623444c061aSmrg char procName[200]; 1624444c061aSmrg 1625444c061aSmrg str = ScanIdent(str); 1626444c061aSmrg if (str-start >= 199) { 1627444c061aSmrg Syntax("Action procedure name is longer than 199 chars",""); 1628444c061aSmrg *error = TRUE; 1629444c061aSmrg return str; 1630444c061aSmrg } 1631444c061aSmrg (void) memmove(procName, start, str-start); 1632444c061aSmrg procName[str-start] = '\0'; 1633444c061aSmrg *actionProcNameP = XrmStringToQuark( procName ); 1634444c061aSmrg return str; 1635444c061aSmrg} 1636444c061aSmrg 1637444c061aSmrg 1638444c061aSmrgstatic String ParseString( 1639444c061aSmrg register String str, 1640444c061aSmrg String *strP) 1641444c061aSmrg{ 1642444c061aSmrg register String start; 1643444c061aSmrg 1644444c061aSmrg if (*str == '"') { 1645444c061aSmrg register unsigned prev_len, len; 1646444c061aSmrg str++; 1647444c061aSmrg start = str; 1648444c061aSmrg *strP = NULL; 1649444c061aSmrg prev_len = 0; 1650444c061aSmrg 1651444c061aSmrg while (*str != '"' && *str != '\0') { 1652444c061aSmrg /* \" produces double quote embedded in a quoted parameter 1653444c061aSmrg * \\" produces backslash as last character of a quoted parameter 1654444c061aSmrg */ 1655444c061aSmrg if (*str == '\\' && 1656444c061aSmrg (*(str+1) == '"' || (*(str+1) == '\\' && *(str+2) == '"'))) { 1657444c061aSmrg len = prev_len + (str-start+2); 1658444c061aSmrg *strP = XtRealloc(*strP, len); 1659444c061aSmrg (void) memmove(*strP + prev_len, start, str-start); 1660444c061aSmrg prev_len = len-1; 1661444c061aSmrg str++; 1662444c061aSmrg (*strP)[prev_len-1] = *str; 1663444c061aSmrg (*strP)[prev_len] = '\0'; 1664444c061aSmrg start = str+1; 1665444c061aSmrg } 1666444c061aSmrg str++; 1667444c061aSmrg } 1668444c061aSmrg len = prev_len + (str-start+1); 1669444c061aSmrg *strP = XtRealloc(*strP, len); 1670444c061aSmrg (void) memmove( *strP + prev_len, start, str-start); 1671444c061aSmrg (*strP)[len-1] = '\0'; 1672444c061aSmrg if (*str == '"') str++; else 1673444c061aSmrg XtWarningMsg(XtNtranslationParseError,"parseString", 1674444c061aSmrg XtCXtToolkitError,"Missing '\"'.", 1675444c061aSmrg (String *)NULL, (Cardinal *)NULL); 1676444c061aSmrg } else { 1677444c061aSmrg /* scan non-quoted string, stop on whitespace, ',' or ')' */ 1678444c061aSmrg start = str; 1679444c061aSmrg while (*str != ' ' 1680444c061aSmrg && *str != '\t' 1681444c061aSmrg && *str != ',' 1682444c061aSmrg && *str != ')' 1683444c061aSmrg && !IsNewline(*str) 1684444c061aSmrg && *str != '\0') str++; 1685444c061aSmrg *strP = __XtMalloc((unsigned)(str-start+1)); 1686444c061aSmrg (void) memmove(*strP, start, str-start); 1687444c061aSmrg (*strP)[str-start] = '\0'; 1688444c061aSmrg } 1689444c061aSmrg return str; 1690444c061aSmrg} 1691444c061aSmrg 1692444c061aSmrg 1693444c061aSmrgstatic String ParseParamSeq( 1694444c061aSmrg register String str, 1695444c061aSmrg String **paramSeqP, 1696444c061aSmrg Cardinal *paramNumP) 1697444c061aSmrg{ 1698444c061aSmrg typedef struct _ParamRec *ParamPtr; 1699444c061aSmrg typedef struct _ParamRec { 1700444c061aSmrg ParamPtr next; 1701444c061aSmrg String param; 1702444c061aSmrg } ParamRec; 1703444c061aSmrg 1704444c061aSmrg ParamPtr params = NULL; 1705444c061aSmrg register Cardinal num_params = 0; 1706444c061aSmrg register Cardinal i; 1707444c061aSmrg 1708444c061aSmrg ScanWhitespace(str); 1709444c061aSmrg while (*str != ')' && *str != '\0' && !IsNewline(*str)) { 1710444c061aSmrg String newStr; 1711444c061aSmrg str = ParseString(str, &newStr); 1712444c061aSmrg if (newStr != NULL) { 1713444c061aSmrg ParamPtr temp = (ParamRec*) 1714444c061aSmrg ALLOCATE_LOCAL( (unsigned)sizeof(ParamRec) ); 1715444c061aSmrg if (temp == NULL) _XtAllocError (NULL); 1716444c061aSmrg 1717444c061aSmrg num_params++; 1718444c061aSmrg temp->next = params; 1719444c061aSmrg params = temp; 1720444c061aSmrg temp->param = newStr; 1721444c061aSmrg ScanWhitespace(str); 1722444c061aSmrg if (*str == ',') { 1723444c061aSmrg str++; 1724444c061aSmrg ScanWhitespace(str); 1725444c061aSmrg } 1726444c061aSmrg } 1727444c061aSmrg } 1728444c061aSmrg 1729444c061aSmrg if (num_params != 0) { 1730444c061aSmrg String *paramP = (String *) 1731444c061aSmrg __XtMalloc( (unsigned)(num_params+1) * sizeof(String) ); 1732444c061aSmrg *paramSeqP = paramP; 1733444c061aSmrg *paramNumP = num_params; 1734444c061aSmrg paramP += num_params; /* list is LIFO right now */ 1735444c061aSmrg *paramP-- = NULL; 1736444c061aSmrg for (i=0; i < num_params; i++) { 1737444c061aSmrg ParamPtr next = params->next; 1738444c061aSmrg *paramP-- = params->param; 1739444c061aSmrg DEALLOCATE_LOCAL( (char *)params ); 1740444c061aSmrg params = next; 1741444c061aSmrg } 1742444c061aSmrg } else { 1743444c061aSmrg *paramSeqP = NULL; 1744444c061aSmrg *paramNumP = 0; 1745444c061aSmrg } 1746444c061aSmrg 1747444c061aSmrg return str; 1748444c061aSmrg} 1749444c061aSmrg 1750444c061aSmrgstatic String ParseAction( 1751444c061aSmrg String str, 1752444c061aSmrg ActionPtr actionP, 1753444c061aSmrg XrmQuark* quarkP, 1754444c061aSmrg Boolean* error) 1755444c061aSmrg{ 1756444c061aSmrg str = ParseActionProc(str, quarkP, error); 1757444c061aSmrg if (*error) return str; 1758444c061aSmrg 1759444c061aSmrg if (*str == '(') { 1760444c061aSmrg str++; 1761444c061aSmrg str = ParseParamSeq(str, &actionP->params, &actionP->num_params); 1762444c061aSmrg } else { 1763444c061aSmrg Syntax("Missing '(' while parsing action sequence",""); 1764444c061aSmrg *error = TRUE; 1765444c061aSmrg return str; 1766444c061aSmrg } 1767444c061aSmrg if (*str == ')') str++; 1768444c061aSmrg else{ 1769444c061aSmrg Syntax("Missing ')' while parsing action sequence",""); 1770444c061aSmrg *error = TRUE; 1771444c061aSmrg return str; 1772444c061aSmrg } 1773444c061aSmrg return str; 1774444c061aSmrg} 1775444c061aSmrg 1776444c061aSmrg 1777444c061aSmrgstatic String ParseActionSeq( 1778444c061aSmrg TMParseStateTree parseTree, 1779444c061aSmrg String str, 1780444c061aSmrg ActionPtr *actionsP, 1781444c061aSmrg Boolean *error) 1782444c061aSmrg{ 1783444c061aSmrg ActionPtr *nextActionP = actionsP; 1784444c061aSmrg 1785444c061aSmrg *actionsP = NULL; 1786444c061aSmrg while (*str != '\0' && !IsNewline(*str)) { 1787444c061aSmrg register ActionPtr action; 1788444c061aSmrg XrmQuark quark; 1789444c061aSmrg 1790444c061aSmrg action = XtNew(ActionRec); 1791444c061aSmrg action->params = NULL; 1792444c061aSmrg action->num_params = 0; 1793444c061aSmrg action->next = NULL; 1794444c061aSmrg 1795444c061aSmrg str = ParseAction(str, action, &quark, error); 1796444c061aSmrg if (*error) return PanicModeRecovery(str); 1797444c061aSmrg 1798444c061aSmrg action->idx = _XtGetQuarkIndex(parseTree, quark); 1799444c061aSmrg ScanWhitespace(str); 1800444c061aSmrg *nextActionP = action; 1801444c061aSmrg nextActionP = &action->next; 1802444c061aSmrg } 1803444c061aSmrg if (IsNewline(*str)) str++; 1804444c061aSmrg ScanWhitespace(str); 1805444c061aSmrg return str; 1806444c061aSmrg} 1807444c061aSmrg 1808444c061aSmrg 1809444c061aSmrgstatic void ShowProduction( 1810444c061aSmrg String currentProduction) 1811444c061aSmrg{ 1812444c061aSmrg Cardinal num_params = 1; 1813444c061aSmrg String params[1]; 1814444c061aSmrg size_t len; 1815444c061aSmrg char *eol, *production, productionbuf[500]; 1816444c061aSmrg 1817444c061aSmrg#ifdef __UNIXOS2__ 1818444c061aSmrg eol = strchr(currentProduction, '\r'); 1819444c061aSmrg if (!eol) /* try '\n' as well below */ 1820444c061aSmrg#endif 1821444c061aSmrg eol = strchr(currentProduction, '\n'); 1822444c061aSmrg if (eol) len = eol - currentProduction; 1823444c061aSmrg else len = strlen (currentProduction); 1824444c061aSmrg production = XtStackAlloc (len + 1, productionbuf); 1825444c061aSmrg if (production == NULL) _XtAllocError (NULL); 1826444c061aSmrg (void) memmove(production, currentProduction, len); 1827444c061aSmrg production[len] = '\0'; 1828444c061aSmrg 1829444c061aSmrg params[0] = production; 1830444c061aSmrg XtWarningMsg(XtNtranslationParseError, "showLine", XtCXtToolkitError, 1831444c061aSmrg "... found while parsing '%s'", params, &num_params); 1832444c061aSmrg 1833444c061aSmrg XtStackFree (production, productionbuf); 1834444c061aSmrg} 1835444c061aSmrg 1836444c061aSmrg/*********************************************************************** 1837444c061aSmrg * ParseTranslationTableProduction 1838444c061aSmrg * Parses one line of event bindings. 1839444c061aSmrg ***********************************************************************/ 1840444c061aSmrg 1841444c061aSmrgstatic String ParseTranslationTableProduction( 1842444c061aSmrg TMParseStateTree parseTree, 1843444c061aSmrg register String str, 1844444c061aSmrg Boolean* error) 1845444c061aSmrg{ 1846444c061aSmrg EventSeqPtr eventSeq = NULL; 1847444c061aSmrg ActionPtr *actionsP; 1848444c061aSmrg String production = str; 1849444c061aSmrg 18502265a131Smrg actionsP = NULL; 1851444c061aSmrg str = ParseEventSeq(str, &eventSeq, &actionsP,error); 1852444c061aSmrg if (*error == TRUE) { 1853444c061aSmrg ShowProduction(production); 1854444c061aSmrg FreeEventSeq(eventSeq); 1855444c061aSmrg return (str); 1856444c061aSmrg } 1857444c061aSmrg ScanWhitespace(str); 1858444c061aSmrg str = ParseActionSeq(parseTree, str, actionsP, error); 1859444c061aSmrg if (*error == TRUE) { 1860444c061aSmrg ShowProduction(production); 1861444c061aSmrg FreeEventSeq(eventSeq); 1862444c061aSmrg return (str); 1863444c061aSmrg } 1864444c061aSmrg 1865444c061aSmrg _XtAddEventSeqToStateTree(eventSeq, parseTree); 1866444c061aSmrg FreeEventSeq(eventSeq); 1867444c061aSmrg return (str); 1868444c061aSmrg} 1869444c061aSmrg 1870444c061aSmrgstatic String CheckForPoundSign( 1871444c061aSmrg String str, 1872444c061aSmrg _XtTranslateOp defaultOp, 1873444c061aSmrg _XtTranslateOp *actualOpRtn) 1874444c061aSmrg{ 1875444c061aSmrg String start; 1876444c061aSmrg char operation[20]; 1877444c061aSmrg _XtTranslateOp opType; 1878444c061aSmrg 1879444c061aSmrg opType = defaultOp; 1880444c061aSmrg ScanWhitespace(str); 1881444c061aSmrg if (*str == '#') { 1882444c061aSmrg int len; 1883444c061aSmrg str++; 1884444c061aSmrg start = str; 1885444c061aSmrg str = ScanIdent(str); 1886444c061aSmrg len = MIN(19, str-start); 1887444c061aSmrg (void) memmove(operation, start, len); 1888444c061aSmrg operation[len] = '\0'; 1889444c061aSmrg if (!strcmp(operation,"replace")) 1890444c061aSmrg opType = XtTableReplace; 1891444c061aSmrg else if (!strcmp(operation,"augment")) 1892444c061aSmrg opType = XtTableAugment; 1893444c061aSmrg else if (!strcmp(operation,"override")) 1894444c061aSmrg opType = XtTableOverride; 1895444c061aSmrg ScanWhitespace(str); 1896444c061aSmrg if (IsNewline(*str)) { 1897444c061aSmrg str++; 1898444c061aSmrg ScanWhitespace(str); 1899444c061aSmrg } 1900444c061aSmrg } 1901444c061aSmrg *actualOpRtn = opType; 1902444c061aSmrg return str; 1903444c061aSmrg} 1904444c061aSmrg 1905444c061aSmrgstatic XtTranslations ParseTranslationTable( 1906444c061aSmrg String source, 1907444c061aSmrg Boolean isAccelerator, 1908444c061aSmrg _XtTranslateOp defaultOp, 1909444c061aSmrg Boolean* error) 1910444c061aSmrg{ 1911444c061aSmrg XtTranslations xlations; 1912444c061aSmrg TMStateTree stateTrees[8]; 1913444c061aSmrg TMParseStateTreeRec parseTreeRec, *parseTree = &parseTreeRec; 1914444c061aSmrg XrmQuark stackQuarks[200]; 1915444c061aSmrg TMBranchHeadRec stackBranchHeads[200]; 1916444c061aSmrg StatePtr stackComplexBranchHeads[200]; 1917444c061aSmrg _XtTranslateOp actualOp; 1918444c061aSmrg 1919444c061aSmrg if (source == NULL) 1920444c061aSmrg return (XtTranslations)NULL; 1921444c061aSmrg 1922444c061aSmrg source = CheckForPoundSign(source, defaultOp, &actualOp); 1923444c061aSmrg if (isAccelerator && actualOp == XtTableReplace) 1924444c061aSmrg actualOp = defaultOp; 1925444c061aSmrg 1926444c061aSmrg parseTree->isSimple = TRUE; 1927444c061aSmrg parseTree->mappingNotifyInterest = FALSE; 1928444c061aSmrg parseTree->isAccelerator = isAccelerator; 1929444c061aSmrg parseTree->isStackBranchHeads = 1930444c061aSmrg parseTree->isStackQuarks = 1931444c061aSmrg parseTree->isStackComplexBranchHeads = TRUE; 1932444c061aSmrg 1933444c061aSmrg parseTree->numQuarks = 1934444c061aSmrg parseTree->numBranchHeads = 1935444c061aSmrg parseTree->numComplexBranchHeads = 0; 1936444c061aSmrg 1937444c061aSmrg parseTree->quarkTblSize = 1938444c061aSmrg parseTree->branchHeadTblSize = 1939444c061aSmrg parseTree->complexBranchHeadTblSize = 200; 1940444c061aSmrg 1941444c061aSmrg parseTree->quarkTbl = stackQuarks; 1942444c061aSmrg parseTree->branchHeadTbl = stackBranchHeads; 1943444c061aSmrg parseTree->complexBranchHeadTbl = stackComplexBranchHeads; 1944444c061aSmrg 1945444c061aSmrg while (source != NULL && *source != '\0') { 1946444c061aSmrg source = ParseTranslationTableProduction(parseTree, source, error); 1947444c061aSmrg if (*error == TRUE) break; 1948444c061aSmrg } 1949444c061aSmrg stateTrees[0] = _XtParseTreeToStateTree(parseTree); 1950444c061aSmrg 1951444c061aSmrg if (!parseTree->isStackQuarks) 1952444c061aSmrg XtFree((char *)parseTree->quarkTbl); 1953444c061aSmrg if (!parseTree->isStackBranchHeads) 1954444c061aSmrg XtFree((char *)parseTree->branchHeadTbl); 1955444c061aSmrg if (!parseTree->isStackComplexBranchHeads) 1956444c061aSmrg XtFree((char *)parseTree->complexBranchHeadTbl); 1957444c061aSmrg 1958444c061aSmrg xlations = _XtCreateXlations(stateTrees, 1, NULL, NULL); 1959444c061aSmrg xlations->operation = actualOp; 1960444c061aSmrg 1961444c061aSmrg#ifdef notdef 1962444c061aSmrg XtFree(stateTrees); 1963444c061aSmrg#endif /* notdef */ 1964444c061aSmrg return xlations; 1965444c061aSmrg} 1966444c061aSmrg 1967444c061aSmrg/*** public procedures ***/ 1968444c061aSmrg 1969444c061aSmrg/*ARGSUSED*/ 1970444c061aSmrgBoolean XtCvtStringToAcceleratorTable( 1971444c061aSmrg Display* dpy, 1972444c061aSmrg XrmValuePtr args, 1973444c061aSmrg Cardinal *num_args, 1974444c061aSmrg XrmValuePtr from, 1975444c061aSmrg XrmValuePtr to, 1976444c061aSmrg XtPointer *closure) 1977444c061aSmrg{ 1978444c061aSmrg String str; 1979444c061aSmrg Boolean error = FALSE; 1980444c061aSmrg 1981444c061aSmrg if (*num_args != 0) 1982444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 1983444c061aSmrg "wrongParameters","cvtStringToAcceleratorTable",XtCXtToolkitError, 1984444c061aSmrg "String to AcceleratorTable conversion needs no extra arguments", 1985444c061aSmrg (String *)NULL, (Cardinal *)NULL); 1986444c061aSmrg str = (String)(from->addr); 1987444c061aSmrg if (str == NULL) { 1988444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 1989444c061aSmrg "badParameters","cvtStringToAcceleratorTable",XtCXtToolkitError, 1990444c061aSmrg "String to AcceleratorTable conversion needs string", 1991444c061aSmrg (String *)NULL, (Cardinal *)NULL); 1992444c061aSmrg return FALSE; 1993444c061aSmrg } 1994444c061aSmrg if (to->addr != NULL) { 1995444c061aSmrg if (to->size < sizeof(XtAccelerators)) { 1996444c061aSmrg to->size = sizeof(XtAccelerators); 1997444c061aSmrg return FALSE; 1998444c061aSmrg } 1999444c061aSmrg *(XtAccelerators*)to->addr = 2000444c061aSmrg (XtAccelerators) ParseTranslationTable(str, TRUE, XtTableAugment, &error); 2001444c061aSmrg } 2002444c061aSmrg else { 2003444c061aSmrg static XtAccelerators staticStateTable; 2004444c061aSmrg staticStateTable = 2005444c061aSmrg (XtAccelerators) ParseTranslationTable(str, TRUE, XtTableAugment, &error); 2006444c061aSmrg to->addr = (XPointer) &staticStateTable; 2007444c061aSmrg to->size = sizeof(XtAccelerators); 2008444c061aSmrg } 2009444c061aSmrg if (error == TRUE) 2010444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2011444c061aSmrg "parseError","cvtStringToAcceleratorTable",XtCXtToolkitError, 2012444c061aSmrg "String to AcceleratorTable conversion encountered errors", 2013444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2014444c061aSmrg return (error != TRUE); 2015444c061aSmrg} 2016444c061aSmrg 2017444c061aSmrg 2018444c061aSmrg/*ARGSUSED*/ 2019444c061aSmrgBoolean 2020444c061aSmrgXtCvtStringToTranslationTable( 2021444c061aSmrg Display *dpy, 2022444c061aSmrg XrmValuePtr args, 2023444c061aSmrg Cardinal *num_args, 2024444c061aSmrg XrmValuePtr from, 2025444c061aSmrg XrmValuePtr to, 2026444c061aSmrg XtPointer *closure_ret) 2027444c061aSmrg{ 2028444c061aSmrg String str; 2029444c061aSmrg Boolean error = FALSE; 2030444c061aSmrg 2031444c061aSmrg if (*num_args != 0) 2032444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2033444c061aSmrg "wrongParameters","cvtStringToTranslationTable",XtCXtToolkitError, 2034444c061aSmrg "String to TranslationTable conversion needs no extra arguments", 2035444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2036444c061aSmrg str = (String)(from->addr); 2037444c061aSmrg if (str == NULL) { 2038444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2039444c061aSmrg "badParameters","cvtStringToTranslation",XtCXtToolkitError, 2040444c061aSmrg "String to TranslationTable conversion needs string", 2041444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2042444c061aSmrg return FALSE; 2043444c061aSmrg } 2044444c061aSmrg if (to->addr != NULL) { 2045444c061aSmrg if (to->size < sizeof(XtTranslations)) { 2046444c061aSmrg to->size = sizeof(XtTranslations); 2047444c061aSmrg return FALSE; 2048444c061aSmrg } 2049444c061aSmrg *(XtTranslations*)to->addr = 2050444c061aSmrg ParseTranslationTable(str, FALSE, XtTableReplace, &error); 2051444c061aSmrg } 2052444c061aSmrg else { 2053444c061aSmrg static XtTranslations staticStateTable; 2054444c061aSmrg staticStateTable = 2055444c061aSmrg ParseTranslationTable(str, FALSE, XtTableReplace, &error); 2056444c061aSmrg to->addr = (XPointer) &staticStateTable; 2057444c061aSmrg to->size = sizeof(XtTranslations); 2058444c061aSmrg } 2059444c061aSmrg if (error == TRUE) 2060444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2061444c061aSmrg "parseError","cvtStringToTranslationTable",XtCXtToolkitError, 2062444c061aSmrg "String to TranslationTable conversion encountered errors", 2063444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2064444c061aSmrg return (error != TRUE); 2065444c061aSmrg} 2066444c061aSmrg 2067444c061aSmrg 2068444c061aSmrg/* 2069444c061aSmrg * Parses a user's or applications translation table 2070444c061aSmrg */ 2071444c061aSmrgXtAccelerators XtParseAcceleratorTable( 2072444c061aSmrg _Xconst char* source) 2073444c061aSmrg{ 2074444c061aSmrg Boolean error = FALSE; 2075444c061aSmrg XtAccelerators ret = 2076444c061aSmrg (XtAccelerators) ParseTranslationTable ((char *)source, TRUE, XtTableAugment, &error); 2077444c061aSmrg if (error == TRUE) 2078444c061aSmrg XtWarningMsg ("parseError", "cvtStringToAcceleratorTable", 2079444c061aSmrg XtCXtToolkitError, 2080444c061aSmrg "String to AcceleratorTable conversion encountered errors", 2081444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2082444c061aSmrg return ret; 2083444c061aSmrg} 2084444c061aSmrg 2085444c061aSmrgXtTranslations XtParseTranslationTable( 2086444c061aSmrg _Xconst char* source) 2087444c061aSmrg{ 2088444c061aSmrg Boolean error = FALSE; 2089444c061aSmrg XtTranslations ret = ParseTranslationTable((char *)source, FALSE, XtTableReplace, &error); 2090444c061aSmrg if (error == TRUE) 2091444c061aSmrg XtWarningMsg ("parseError", 2092444c061aSmrg "cvtStringToTranslationTable", XtCXtToolkitError, 2093444c061aSmrg "String to TranslationTable conversion encountered errors", 2094444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2095444c061aSmrg return ret; 2096444c061aSmrg} 2097444c061aSmrg 2098444c061aSmrgvoid _XtTranslateInitialize(void) 2099444c061aSmrg{ 2100444c061aSmrg LOCK_PROCESS; 2101444c061aSmrg if (initialized) { 2102444c061aSmrg XtWarningMsg("translationError","xtTranslateInitialize", 2103444c061aSmrg XtCXtToolkitError,"Initializing Translation manager twice.", 2104444c061aSmrg (String *)NULL, (Cardinal *)NULL); 2105444c061aSmrg UNLOCK_PROCESS; 2106444c061aSmrg return; 2107444c061aSmrg } 2108444c061aSmrg 2109444c061aSmrg initialized = TRUE; 2110444c061aSmrg UNLOCK_PROCESS; 2111444c061aSmrg QMeta = XrmPermStringToQuark("Meta"); 2112444c061aSmrg QCtrl = XrmPermStringToQuark("Ctrl"); 2113444c061aSmrg QNone = XrmPermStringToQuark("None"); 2114444c061aSmrg QAny = XrmPermStringToQuark("Any"); 2115444c061aSmrg 2116444c061aSmrg Compile_XtEventTable( events, XtNumber(events) ); 2117444c061aSmrg Compile_XtModifierTable( modifiers, XtNumber(modifiers) ); 2118444c061aSmrg CompileNameValueTable( buttonNames ); 2119444c061aSmrg CompileNameValueTable( notifyModes ); 2120444c061aSmrg CompileNameValueTable( motionDetails ); 2121444c061aSmrg#if 0 2122444c061aSmrg CompileNameValueTable( notifyDetail ); 2123444c061aSmrg CompileNameValueTable( visibilityNotify ); 2124444c061aSmrg CompileNameValueTable( circulation ); 2125444c061aSmrg CompileNameValueTable( propertyChanged ); 2126444c061aSmrg#endif 2127444c061aSmrg CompileNameValueTable( mappingNotify ); 2128444c061aSmrg} 2129444c061aSmrg 2130444c061aSmrgvoid _XtAddTMConverters( 2131444c061aSmrg ConverterTable table) 2132444c061aSmrg{ 2133444c061aSmrg _XtTableAddConverter(table, 2134444c061aSmrg _XtQString, 2135444c061aSmrg XrmPermStringToQuark(XtRTranslationTable), 2136444c061aSmrg XtCvtStringToTranslationTable, (XtConvertArgList) NULL, 2137444c061aSmrg (Cardinal)0, True, CACHED, _XtFreeTranslations, True); 2138444c061aSmrg _XtTableAddConverter(table, _XtQString, 2139444c061aSmrg XrmPermStringToQuark(XtRAcceleratorTable), 2140444c061aSmrg XtCvtStringToAcceleratorTable, (XtConvertArgList) NULL, 2141444c061aSmrg (Cardinal)0, True, CACHED, _XtFreeTranslations, True); 2142444c061aSmrg _XtTableAddConverter(table, 2143444c061aSmrg XrmPermStringToQuark( _XtRStateTablePair ), 2144444c061aSmrg XrmPermStringToQuark(XtRTranslationTable), 2145444c061aSmrg _XtCvtMergeTranslations, (XtConvertArgList) NULL, 2146444c061aSmrg (Cardinal)0, True, CACHED, _XtFreeTranslations, True); 2147444c061aSmrg} 2148