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