TMparse.c revision 362b94d5
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 85362b94d5Smrg#ifdef REFCNT_TRANSLATIONS 86362b94d5Smrg#define CACHED XtCacheAll | XtCacheRefCount 87444c061aSmrg#else 88362b94d5Smrg#define CACHED XtCacheAll 89362b94d5Smrg#endif 90362b94d5Smrg#else 91362b94d5Smrg#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 10272af6995Smrgstatic _Xconst char *XtNtranslationParseError = "translationParseError"; 103444c061aSmrg 104362b94d5Smrgtypedef int EventType; 105444c061aSmrg 10672af6995Smrg#define PARSE_PROC_DECL String, Opaque, EventPtr, Boolean* 10772af6995Smrg 108362b94d5Smrgtypedef String(*ParseProc) (String /* str; */ , 109362b94d5Smrg Opaque /* closure; */ , 110362b94d5Smrg EventPtr /* event; */ , 111362b94d5Smrg Boolean * /* error */ ); 112444c061aSmrg 113362b94d5Smrgtypedef TMShortCard Value; 114362b94d5Smrgtypedef void (*ModifierProc) (Value, LateBindingsPtr *, Boolean, Value *); 115444c061aSmrg 116444c061aSmrgtypedef struct _ModifierRec { 1178584976cSmrg const char *name; 118362b94d5Smrg XrmQuark signature; 119444c061aSmrg ModifierProc modifierParseProc; 120362b94d5Smrg Value value; 121444c061aSmrg} ModifierRec, *ModifierKeys; 122444c061aSmrg 123444c061aSmrgtypedef struct _EventKey { 124362b94d5Smrg const char *event; 125362b94d5Smrg XrmQuark signature; 126362b94d5Smrg EventType eventType; 127362b94d5Smrg ParseProc parseDetail; 128362b94d5Smrg Opaque closure; 129362b94d5Smrg} EventKey, *EventKeys; 130444c061aSmrg 131444c061aSmrgtypedef struct { 132362b94d5Smrg const char *name; 133362b94d5Smrg XrmQuark signature; 134362b94d5Smrg Value value; 135444c061aSmrg} NameValueRec, *NameValueTable; 136444c061aSmrg 137362b94d5Smrgstatic void ParseModImmed(Value, LateBindingsPtr *, Boolean, Value *); 138362b94d5Smrgstatic void ParseModSym(Value, LateBindingsPtr *, Boolean, Value *); 139444c061aSmrgstatic String PanicModeRecovery(String); 140444c061aSmrgstatic String CheckForPoundSign(String, _XtTranslateOp, _XtTranslateOp *); 141444c061aSmrgstatic KeySym StringToKeySym(String, Boolean *); 142362b94d5Smrg/* *INDENT-OFF* */ 143444c061aSmrgstatic ModifierRec modifiers[] = { 144362b94d5Smrg {"Shift", 0, ParseModImmed, ShiftMask}, 145362b94d5Smrg {"Lock", 0, ParseModImmed, LockMask}, 146362b94d5Smrg {"Ctrl", 0, ParseModImmed, ControlMask}, 147362b94d5Smrg {"Mod1", 0, ParseModImmed, Mod1Mask}, 148362b94d5Smrg {"Mod2", 0, ParseModImmed, Mod2Mask}, 149362b94d5Smrg {"Mod3", 0, ParseModImmed, Mod3Mask}, 150362b94d5Smrg {"Mod4", 0, ParseModImmed, Mod4Mask}, 151362b94d5Smrg {"Mod5", 0, ParseModImmed, Mod5Mask}, 152362b94d5Smrg {"Meta", 0, ParseModSym, XK_Meta_L}, 153362b94d5Smrg {"m", 0, ParseModSym, XK_Meta_L}, 154362b94d5Smrg {"h", 0, ParseModSym, XK_Hyper_L}, 155362b94d5Smrg {"su", 0, ParseModSym, XK_Super_L}, 156362b94d5Smrg {"a", 0, ParseModSym, XK_Alt_L}, 157362b94d5Smrg {"Hyper", 0, ParseModSym, XK_Hyper_L}, 158362b94d5Smrg {"Super", 0, ParseModSym, XK_Super_L}, 159362b94d5Smrg {"Alt", 0, ParseModSym, XK_Alt_L}, 160362b94d5Smrg {"Button1", 0, ParseModImmed, Button1Mask}, 161362b94d5Smrg {"Button2", 0, ParseModImmed, Button2Mask}, 162362b94d5Smrg {"Button3", 0, ParseModImmed, Button3Mask}, 163362b94d5Smrg {"Button4", 0, ParseModImmed, Button4Mask}, 164362b94d5Smrg {"Button5", 0, ParseModImmed, Button5Mask}, 165362b94d5Smrg {"c", 0, ParseModImmed, ControlMask}, 166362b94d5Smrg {"s", 0, ParseModImmed, ShiftMask}, 167362b94d5Smrg {"l", 0, ParseModImmed, LockMask}, 168444c061aSmrg}; 169444c061aSmrg 170444c061aSmrgstatic NameValueRec buttonNames[] = { 171362b94d5Smrg {"Button1", 0, Button1}, 172362b94d5Smrg {"Button2", 0, Button2}, 173362b94d5Smrg {"Button3", 0, Button3}, 174362b94d5Smrg {"Button4", 0, Button4}, 175362b94d5Smrg {"Button5", 0, Button5}, 176362b94d5Smrg {NULL, NULLQUARK, 0}, 177444c061aSmrg}; 178444c061aSmrg 179444c061aSmrgstatic NameValueRec motionDetails[] = { 180362b94d5Smrg {"Normal", 0, NotifyNormal}, 181362b94d5Smrg {"Hint", 0, NotifyHint}, 182362b94d5Smrg {NULL, NULLQUARK, 0}, 183444c061aSmrg}; 184444c061aSmrg 185444c061aSmrgstatic NameValueRec notifyModes[] = { 186362b94d5Smrg {"Normal", 0, NotifyNormal}, 187362b94d5Smrg {"Grab", 0, NotifyGrab}, 188362b94d5Smrg {"Ungrab", 0, NotifyUngrab}, 189362b94d5Smrg {"WhileGrabbed", 0, NotifyWhileGrabbed}, 190362b94d5Smrg {NULL, NULLQUARK, 0}, 191444c061aSmrg}; 192444c061aSmrg 193444c061aSmrg#if 0 194444c061aSmrgstatic NameValueRec notifyDetail[] = { 195362b94d5Smrg {"Ancestor", 0, NotifyAncestor}, 196362b94d5Smrg {"Virtual", 0, NotifyVirtual}, 197362b94d5Smrg {"Inferior", 0, NotifyInferior}, 198362b94d5Smrg {"Nonlinear", 0, NotifyNonlinear}, 199362b94d5Smrg {"NonlinearVirtual", 0, NotifyNonlinearVirtual}, 200362b94d5Smrg {"Pointer", 0, NotifyPointer}, 201362b94d5Smrg {"PointerRoot", 0, NotifyPointerRoot}, 202362b94d5Smrg {"DetailNone", 0, NotifyDetailNone}, 203362b94d5Smrg {NULL, NULLQUARK, 0}, 204444c061aSmrg}; 205444c061aSmrg 206444c061aSmrgstatic NameValueRec visibilityNotify[] = { 207362b94d5Smrg {"Unobscured", 0, VisibilityUnobscured}, 208362b94d5Smrg {"PartiallyObscured", 0, VisibilityPartiallyObscured}, 209362b94d5Smrg {"FullyObscured", 0, VisibilityFullyObscured}, 210362b94d5Smrg {NULL, NULLQUARK, 0}, 211444c061aSmrg}; 212444c061aSmrg 213444c061aSmrgstatic NameValueRec circulation[] = { 214362b94d5Smrg {"OnTop", 0, PlaceOnTop}, 215362b94d5Smrg {"OnBottom", 0, PlaceOnBottom}, 216362b94d5Smrg {NULL, NULLQUARK, 0}, 217444c061aSmrg}; 218444c061aSmrg 219444c061aSmrgstatic NameValueRec propertyChanged[] = { 220362b94d5Smrg {"NewValue", 0, PropertyNewValue}, 221362b94d5Smrg {"Delete", 0, PropertyDelete}, 222362b94d5Smrg {NULL, NULLQUARK, 0}, 223444c061aSmrg}; 224444c061aSmrg#endif /*0*/ 225444c061aSmrg 226444c061aSmrgstatic NameValueRec mappingNotify[] = { 227362b94d5Smrg {"Modifier", 0, MappingModifier}, 228362b94d5Smrg {"Keyboard", 0, MappingKeyboard}, 229362b94d5Smrg {"Pointer", 0, MappingPointer}, 230362b94d5Smrg {NULL, NULLQUARK, 0}, 231444c061aSmrg}; 232362b94d5Smrg/* *INDENT-ON* */ 233444c061aSmrg 23472af6995Smrgstatic String ParseKeySym(PARSE_PROC_DECL); 23572af6995Smrgstatic String ParseKeyAndModifiers(PARSE_PROC_DECL); 23672af6995Smrgstatic String ParseTable(PARSE_PROC_DECL); 23772af6995Smrgstatic String ParseImmed(PARSE_PROC_DECL); 23872af6995Smrgstatic String ParseAddModifier(PARSE_PROC_DECL); 23972af6995Smrgstatic String ParseNone(PARSE_PROC_DECL); 24072af6995Smrgstatic String ParseAtom(PARSE_PROC_DECL); 241444c061aSmrg 242362b94d5Smrg/* *INDENT-OFF* */ 243444c061aSmrgstatic EventKey events[] = { 244444c061aSmrg 245362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 246444c061aSmrg 247362b94d5Smrg{"KeyPress", NULLQUARK, KeyPress, ParseKeySym, NULL}, 248362b94d5Smrg{"Key", NULLQUARK, KeyPress, ParseKeySym, NULL}, 249362b94d5Smrg{"KeyDown", NULLQUARK, KeyPress, ParseKeySym, NULL}, 250362b94d5Smrg{"Ctrl", NULLQUARK, KeyPress, ParseKeyAndModifiers, (Opaque)ControlMask}, 251362b94d5Smrg{"Shift", NULLQUARK, KeyPress, ParseKeyAndModifiers, (Opaque)ShiftMask}, 252362b94d5Smrg{"Meta", NULLQUARK, KeyPress, ParseKeyAndModifiers, (Opaque)NULL}, 253362b94d5Smrg{"KeyUp", NULLQUARK, KeyRelease, ParseKeySym, NULL}, 254362b94d5Smrg{"KeyRelease", NULLQUARK, KeyRelease, ParseKeySym, NULL}, 255444c061aSmrg 256362b94d5Smrg{"ButtonPress", NULLQUARK, ButtonPress, ParseTable, (Opaque)buttonNames}, 257362b94d5Smrg{"BtnDown", NULLQUARK, ButtonPress, ParseTable, (Opaque)buttonNames}, 258362b94d5Smrg{"Btn1Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button1}, 259362b94d5Smrg{"Btn2Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button2}, 260362b94d5Smrg{"Btn3Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button3}, 261362b94d5Smrg{"Btn4Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button4}, 262362b94d5Smrg{"Btn5Down", NULLQUARK, ButtonPress, ParseImmed, (Opaque)Button5}, 263444c061aSmrg 264362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 265444c061aSmrg 266362b94d5Smrg{"ButtonRelease", NULLQUARK, ButtonRelease, ParseTable, (Opaque)buttonNames}, 267362b94d5Smrg{"BtnUp", NULLQUARK, ButtonRelease, ParseTable, (Opaque)buttonNames}, 268362b94d5Smrg{"Btn1Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button1}, 269362b94d5Smrg{"Btn2Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button2}, 270362b94d5Smrg{"Btn3Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button3}, 271362b94d5Smrg{"Btn4Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button4}, 272362b94d5Smrg{"Btn5Up", NULLQUARK, ButtonRelease, ParseImmed, (Opaque)Button5}, 273444c061aSmrg 274362b94d5Smrg{"MotionNotify", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 275362b94d5Smrg{"PtrMoved", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 276362b94d5Smrg{"Motion", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 277362b94d5Smrg{"MouseMoved", NULLQUARK, MotionNotify, ParseTable, (Opaque)motionDetails}, 278362b94d5Smrg{"BtnMotion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)AnyButtonMask}, 279362b94d5Smrg{"Btn1Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button1Mask}, 280362b94d5Smrg{"Btn2Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button2Mask}, 281362b94d5Smrg{"Btn3Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button3Mask}, 282362b94d5Smrg{"Btn4Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button4Mask}, 283362b94d5Smrg{"Btn5Motion", NULLQUARK, MotionNotify, ParseAddModifier, (Opaque)Button5Mask}, 284444c061aSmrg 285362b94d5Smrg{"EnterNotify", NULLQUARK, EnterNotify, ParseTable, (Opaque)notifyModes}, 286362b94d5Smrg{"Enter", NULLQUARK, EnterNotify, ParseTable, (Opaque)notifyModes}, 287362b94d5Smrg{"EnterWindow", NULLQUARK, EnterNotify, ParseTable, (Opaque)notifyModes}, 288444c061aSmrg 289362b94d5Smrg{"LeaveNotify", NULLQUARK, LeaveNotify, ParseTable, (Opaque)notifyModes}, 290362b94d5Smrg{"LeaveWindow", NULLQUARK, LeaveNotify, ParseTable, (Opaque)notifyModes}, 291362b94d5Smrg{"Leave", NULLQUARK, LeaveNotify, ParseTable, (Opaque)notifyModes}, 292444c061aSmrg 293362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 294444c061aSmrg 295362b94d5Smrg{"FocusIn", NULLQUARK, FocusIn, ParseTable, (Opaque)notifyModes}, 296444c061aSmrg 297362b94d5Smrg{"FocusOut", NULLQUARK, FocusOut, ParseTable, (Opaque)notifyModes}, 298444c061aSmrg 299362b94d5Smrg{"KeymapNotify", NULLQUARK, KeymapNotify, ParseNone, NULL}, 300362b94d5Smrg{"Keymap", NULLQUARK, KeymapNotify, ParseNone, NULL}, 301444c061aSmrg 302362b94d5Smrg{"Expose", NULLQUARK, Expose, ParseNone, NULL}, 303444c061aSmrg 304362b94d5Smrg{"GraphicsExpose", NULLQUARK, GraphicsExpose, ParseNone, NULL}, 305362b94d5Smrg{"GrExp", NULLQUARK, GraphicsExpose, ParseNone, NULL}, 306444c061aSmrg 307362b94d5Smrg{"NoExpose", NULLQUARK, NoExpose, ParseNone, NULL}, 308362b94d5Smrg{"NoExp", NULLQUARK, NoExpose, ParseNone, NULL}, 309444c061aSmrg 310362b94d5Smrg{"VisibilityNotify",NULLQUARK, VisibilityNotify,ParseNone, NULL}, 311362b94d5Smrg{"Visible", NULLQUARK, VisibilityNotify,ParseNone, NULL}, 312444c061aSmrg 313362b94d5Smrg{"CreateNotify", NULLQUARK, CreateNotify, ParseNone, NULL}, 314362b94d5Smrg{"Create", NULLQUARK, CreateNotify, ParseNone, NULL}, 315444c061aSmrg 316362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 317444c061aSmrg 318362b94d5Smrg{"DestroyNotify", NULLQUARK, DestroyNotify, ParseNone, NULL}, 319362b94d5Smrg{"Destroy", NULLQUARK, DestroyNotify, ParseNone, NULL}, 320444c061aSmrg 321362b94d5Smrg{"UnmapNotify", NULLQUARK, UnmapNotify, ParseNone, NULL}, 322362b94d5Smrg{"Unmap", NULLQUARK, UnmapNotify, ParseNone, NULL}, 323444c061aSmrg 324362b94d5Smrg{"MapNotify", NULLQUARK, MapNotify, ParseNone, NULL}, 325362b94d5Smrg{"Map", NULLQUARK, MapNotify, ParseNone, NULL}, 326444c061aSmrg 327362b94d5Smrg{"MapRequest", NULLQUARK, MapRequest, ParseNone, NULL}, 328362b94d5Smrg{"MapReq", NULLQUARK, MapRequest, ParseNone, NULL}, 329444c061aSmrg 330362b94d5Smrg{"ReparentNotify", NULLQUARK, ReparentNotify, ParseNone, NULL}, 331362b94d5Smrg{"Reparent", NULLQUARK, ReparentNotify, ParseNone, NULL}, 332444c061aSmrg 333362b94d5Smrg{"ConfigureNotify", NULLQUARK, ConfigureNotify, ParseNone, NULL}, 334362b94d5Smrg{"Configure", NULLQUARK, ConfigureNotify, ParseNone, NULL}, 335444c061aSmrg 336362b94d5Smrg{"ConfigureRequest",NULLQUARK, ConfigureRequest,ParseNone, NULL}, 337362b94d5Smrg{"ConfigureReq", NULLQUARK, ConfigureRequest,ParseNone, NULL}, 338444c061aSmrg 339362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 340444c061aSmrg 341362b94d5Smrg{"GravityNotify", NULLQUARK, GravityNotify, ParseNone, NULL}, 342362b94d5Smrg{"Grav", NULLQUARK, GravityNotify, ParseNone, NULL}, 343444c061aSmrg 344362b94d5Smrg{"ResizeRequest", NULLQUARK, ResizeRequest, ParseNone, NULL}, 345362b94d5Smrg{"ResReq", NULLQUARK, ResizeRequest, ParseNone, NULL}, 346444c061aSmrg 347362b94d5Smrg{"CirculateNotify", NULLQUARK, CirculateNotify, ParseNone, NULL}, 348362b94d5Smrg{"Circ", NULLQUARK, CirculateNotify, ParseNone, NULL}, 349444c061aSmrg 350362b94d5Smrg{"CirculateRequest",NULLQUARK, CirculateRequest,ParseNone, NULL}, 351362b94d5Smrg{"CircReq", NULLQUARK, CirculateRequest,ParseNone, NULL}, 352444c061aSmrg 353362b94d5Smrg{"PropertyNotify", NULLQUARK, PropertyNotify, ParseAtom, NULL}, 354362b94d5Smrg{"Prop", NULLQUARK, PropertyNotify, ParseAtom, NULL}, 355444c061aSmrg 356362b94d5Smrg{"SelectionClear", NULLQUARK, SelectionClear, ParseAtom, NULL}, 357362b94d5Smrg{"SelClr", NULLQUARK, SelectionClear, ParseAtom, NULL}, 358444c061aSmrg 359362b94d5Smrg{"SelectionRequest",NULLQUARK, SelectionRequest,ParseAtom, NULL}, 360362b94d5Smrg{"SelReq", NULLQUARK, SelectionRequest,ParseAtom, NULL}, 361444c061aSmrg 362362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 363444c061aSmrg 364362b94d5Smrg{"SelectionNotify", NULLQUARK, SelectionNotify, ParseAtom, NULL}, 365362b94d5Smrg{"Select", NULLQUARK, SelectionNotify, ParseAtom, NULL}, 366444c061aSmrg 367362b94d5Smrg{"ColormapNotify", NULLQUARK, ColormapNotify, ParseNone, NULL}, 368362b94d5Smrg{"Clrmap", NULLQUARK, ColormapNotify, ParseNone, NULL}, 369444c061aSmrg 370362b94d5Smrg{"ClientMessage", NULLQUARK, ClientMessage, ParseAtom, NULL}, 371362b94d5Smrg{"Message", NULLQUARK, ClientMessage, ParseAtom, NULL}, 372444c061aSmrg 373362b94d5Smrg{"MappingNotify", NULLQUARK, MappingNotify, ParseTable, (Opaque)mappingNotify}, 374362b94d5Smrg{"Mapping", NULLQUARK, MappingNotify, ParseTable, (Opaque)mappingNotify}, 375444c061aSmrg 376444c061aSmrg#ifdef DEBUG 377444c061aSmrg# ifdef notdef 378362b94d5Smrg{"Timer", NULLQUARK, _XtTimerEventType, ParseNone, NULL}, 379362b94d5Smrg{"EventTimer", NULLQUARK, _XtEventTimerEventType, ParseNone,NULL}, 3801bd39548Schristos# endif /* notdef */ 381444c061aSmrg#endif /* DEBUG */ 382444c061aSmrg 383362b94d5Smrg/* Event Name, Quark, Event Type, Detail Parser, Closure */ 384444c061aSmrg 385444c061aSmrg}; 386362b94d5Smrg/* *INDENT-ON* */ 387444c061aSmrg 388444c061aSmrg#define IsNewline(str) ((str) == '\n') 389444c061aSmrg 390444c061aSmrg#define ScanFor(str, ch) \ 391444c061aSmrg while ((*(str) != (ch)) && (*(str) != '\0') && !IsNewline(*(str))) (str)++ 392444c061aSmrg 393444c061aSmrg#define ScanNumeric(str) while ('0' <= *(str) && *(str) <= '9') (str)++ 394444c061aSmrg 395444c061aSmrg#define ScanAlphanumeric(str) \ 396444c061aSmrg while (('A' <= *(str) && *(str) <= 'Z') || \ 397444c061aSmrg ('a' <= *(str) && *(str) <= 'z') || \ 398444c061aSmrg ('0' <= *(str) && *(str) <= '9')) (str)++ 399444c061aSmrg 400444c061aSmrg#define ScanWhitespace(str) \ 401444c061aSmrg while (*(str) == ' ' || *(str) == '\t') (str)++ 402444c061aSmrg 403444c061aSmrgstatic Boolean initialized = FALSE; 404444c061aSmrgstatic XrmQuark QMeta; 405444c061aSmrgstatic XrmQuark QCtrl; 406444c061aSmrgstatic XrmQuark QNone; 407444c061aSmrgstatic XrmQuark QAny; 408444c061aSmrg 409362b94d5Smrgstatic void 410362b94d5SmrgFreeEventSeq(EventSeqPtr eventSeq) 411444c061aSmrg{ 412444c061aSmrg register EventSeqPtr evs = eventSeq; 413444c061aSmrg 414444c061aSmrg while (evs != NULL) { 415362b94d5Smrg evs->state = (StatePtr) evs; 416362b94d5Smrg if (evs->next != NULL && evs->next->state == (StatePtr) evs->next) 417362b94d5Smrg evs->next = NULL; 418362b94d5Smrg evs = evs->next; 419444c061aSmrg } 420444c061aSmrg 421444c061aSmrg evs = eventSeq; 422444c061aSmrg while (evs != NULL) { 423362b94d5Smrg register EventPtr event = evs; 424362b94d5Smrg 425362b94d5Smrg evs = evs->next; 426362b94d5Smrg if (evs == event) 427362b94d5Smrg evs = NULL; 428362b94d5Smrg XtFree((char *) event); 429444c061aSmrg } 430444c061aSmrg} 431444c061aSmrg 432362b94d5Smrgstatic void 433362b94d5SmrgCompileNameValueTable(NameValueTable table) 434444c061aSmrg{ 435444c061aSmrg register int i; 436444c061aSmrg 437362b94d5Smrg for (i = 0; table[i].name; i++) 438444c061aSmrg table[i].signature = XrmPermStringToQuark(table[i].name); 439444c061aSmrg} 440444c061aSmrg 441362b94d5Smrgstatic int 442362b94d5SmrgOrderEvents(_Xconst void *a, _Xconst void *b) 443444c061aSmrg{ 444362b94d5Smrg return ((((_Xconst EventKey *) a)->signature < 445362b94d5Smrg ((_Xconst EventKey *) b)->signature) ? -1 : 1); 446444c061aSmrg} 447444c061aSmrg 448362b94d5Smrgstatic void 449362b94d5SmrgCompile_XtEventTable(EventKeys table, Cardinal count) 450444c061aSmrg{ 451444c061aSmrg register int i; 452444c061aSmrg register EventKeys entry = table; 453444c061aSmrg 454362b94d5Smrg for (i = (int) count; --i >= 0; entry++) 455362b94d5Smrg entry->signature = XrmPermStringToQuark(entry->event); 456444c061aSmrg qsort(table, count, sizeof(EventKey), OrderEvents); 457444c061aSmrg} 458444c061aSmrg 459362b94d5Smrgstatic int 460362b94d5SmrgOrderModifiers(_Xconst void *a, _Xconst void *b) 461444c061aSmrg{ 462362b94d5Smrg return ((((_Xconst ModifierRec *) a)->signature < 463362b94d5Smrg ((_Xconst ModifierRec *) b)->signature) ? -1 : 1); 464444c061aSmrg} 465444c061aSmrg 466362b94d5Smrgstatic void 467362b94d5SmrgCompile_XtModifierTable(ModifierKeys table, Cardinal count) 468444c061aSmrg{ 469444c061aSmrg register int i; 470444c061aSmrg register ModifierKeys entry = table; 471444c061aSmrg 472362b94d5Smrg for (i = (int) count; --i >= 0; entry++) 473362b94d5Smrg entry->signature = XrmPermStringToQuark(entry->name); 474444c061aSmrg qsort(table, count, sizeof(ModifierRec), OrderModifiers); 475444c061aSmrg} 476444c061aSmrg 477362b94d5Smrgstatic String 478362b94d5SmrgPanicModeRecovery(String str) 479444c061aSmrg{ 480362b94d5Smrg ScanFor(str, '\n'); 481362b94d5Smrg if (*str == '\n') 482362b94d5Smrg str++; 483362b94d5Smrg return str; 484444c061aSmrg 485444c061aSmrg} 486444c061aSmrg 487362b94d5Smrgstatic void 488362b94d5SmrgSyntax(_Xconst char *str0, _Xconst char *str1) 489444c061aSmrg{ 490444c061aSmrg Cardinal num_params = 2; 491444c061aSmrg String params[2]; 492444c061aSmrg 49372af6995Smrg params[0] = (String) str0; 49472af6995Smrg params[1] = (String) str1; 495362b94d5Smrg XtWarningMsg(XtNtranslationParseError, "parseError", XtCXtToolkitError, 496362b94d5Smrg "translation table syntax error: %s %s", params, &num_params); 497444c061aSmrg} 498444c061aSmrg 499362b94d5Smrgstatic Cardinal 500362b94d5SmrgLookupTMEventType(String eventStr, Boolean *error) 501444c061aSmrg{ 502362b94d5Smrg register int i = 0, left, right; 503362b94d5Smrg register XrmQuark signature; 504362b94d5Smrg static int previous = 0; 505444c061aSmrg 506444c061aSmrg LOCK_PROCESS; 507444c061aSmrg if ((signature = StringToQuark(eventStr)) == events[previous].signature) { 508362b94d5Smrg UNLOCK_PROCESS; 509362b94d5Smrg return (Cardinal) previous; 510444c061aSmrg } 511444c061aSmrg 512444c061aSmrg left = 0; 513444c061aSmrg right = XtNumber(events) - 1; 514444c061aSmrg while (left <= right) { 515362b94d5Smrg i = (left + right) >> 1; 516362b94d5Smrg if (signature < events[i].signature) 517362b94d5Smrg right = i - 1; 518362b94d5Smrg else if (signature > events[i].signature) 519362b94d5Smrg left = i + 1; 520362b94d5Smrg else { 521362b94d5Smrg previous = i; 522362b94d5Smrg UNLOCK_PROCESS; 523362b94d5Smrg return (Cardinal) i; 524362b94d5Smrg } 525362b94d5Smrg } 526362b94d5Smrg 527362b94d5Smrg Syntax("Unknown event type : ", eventStr); 528444c061aSmrg *error = TRUE; 529444c061aSmrg UNLOCK_PROCESS; 530444c061aSmrg return (Cardinal) i; 531444c061aSmrg} 532444c061aSmrg 533362b94d5Smrgstatic void 534362b94d5SmrgStoreLateBindings(KeySym keysymL, 535362b94d5Smrg Boolean notL, 536362b94d5Smrg KeySym keysymR, 537362b94d5Smrg Boolean notR, 538362b94d5Smrg LateBindingsPtr *lateBindings) 539444c061aSmrg{ 540444c061aSmrg LateBindingsPtr temp; 54172af6995Smrg 542362b94d5Smrg if (lateBindings != NULL) { 543362b94d5Smrg Boolean pair = FALSE; 544362b94d5Smrg unsigned long count; 545362b94d5Smrg unsigned long number; 54672af6995Smrg 547444c061aSmrg temp = *lateBindings; 548444c061aSmrg if (temp != NULL) { 549362b94d5Smrg for (count = 0; temp[count].keysym; count++) { 550362b94d5Smrg /*EMPTY*/ 551362b94d5Smrg } 552444c061aSmrg } 553362b94d5Smrg else 554362b94d5Smrg count = 0; 555362b94d5Smrg if (!keysymR) { 556362b94d5Smrg number = 1; 557362b94d5Smrg pair = FALSE; 558362b94d5Smrg } 559362b94d5Smrg else { 560362b94d5Smrg number = 2; 561362b94d5Smrg pair = TRUE; 562444c061aSmrg } 563444c061aSmrg 564362b94d5Smrg temp = (LateBindingsPtr) XtRealloc((char *) temp, 565362b94d5Smrg (unsigned) ((count + number + 566362b94d5Smrg 1) * 567362b94d5Smrg sizeof(LateBindings))); 568444c061aSmrg *lateBindings = temp; 56972af6995Smrg XtSetBit(temp[count].knot, notL); 57072af6995Smrg XtSetBit(temp[count].pair, pair); 571362b94d5Smrg if (count == 0) 572362b94d5Smrg temp[count].ref_count = 1; 573444c061aSmrg temp[count++].keysym = keysymL; 574362b94d5Smrg if (keysymR) { 57572af6995Smrg XtSetBit(temp[count].knot, notR); 576444c061aSmrg temp[count].pair = FALSE; 577362b94d5Smrg temp[count].ref_count = 0; 578444c061aSmrg temp[count++].keysym = keysymR; 579444c061aSmrg } 580444c061aSmrg temp[count].knot = temp[count].pair = FALSE; 581444c061aSmrg temp[count].ref_count = 0; 582444c061aSmrg temp[count].keysym = 0; 583444c061aSmrg } 584444c061aSmrg} 585444c061aSmrg 586362b94d5Smrgstatic void 587362b94d5Smrg_XtParseKeysymMod(String name, 588362b94d5Smrg LateBindingsPtr *lateBindings, 589362b94d5Smrg Boolean notFlag, 590362b94d5Smrg Value *valueP, 591362b94d5Smrg Boolean *error) 592444c061aSmrg{ 593444c061aSmrg KeySym keySym; 594362b94d5Smrg 595444c061aSmrg keySym = StringToKeySym(name, error); 596444c061aSmrg *valueP = 0; 597444c061aSmrg if (keySym != NoSymbol) { 598362b94d5Smrg StoreLateBindings(keySym, notFlag, (KeySym) NULL, FALSE, lateBindings); 599444c061aSmrg } 600444c061aSmrg} 601444c061aSmrg 602362b94d5Smrgstatic Boolean 603362b94d5Smrg_XtLookupModifier(XrmQuark signature, 604362b94d5Smrg LateBindingsPtr *lateBindings, 605362b94d5Smrg Boolean notFlag, 606362b94d5Smrg Value *valueP, 607362b94d5Smrg Bool constMask) 608444c061aSmrg{ 60972af6995Smrg int left, right; 610444c061aSmrg static int previous = 0; 611444c061aSmrg 612444c061aSmrg LOCK_PROCESS; 613444c061aSmrg if (signature == modifiers[previous].signature) { 614362b94d5Smrg if (constMask) 615362b94d5Smrg *valueP = modifiers[previous].value; 616362b94d5Smrg else /* if (modifiers[previous].modifierParseProc) always true */ 617362b94d5Smrg (*modifiers[previous].modifierParseProc) 618362b94d5Smrg (modifiers[previous].value, lateBindings, notFlag, valueP); 619362b94d5Smrg UNLOCK_PROCESS; 620362b94d5Smrg return TRUE; 621444c061aSmrg } 622444c061aSmrg 623444c061aSmrg left = 0; 624444c061aSmrg right = XtNumber(modifiers) - 1; 625444c061aSmrg while (left <= right) { 626362b94d5Smrg int i = (left + right) >> 1; 627362b94d5Smrg 628362b94d5Smrg if (signature < modifiers[i].signature) 629362b94d5Smrg right = i - 1; 630362b94d5Smrg else if (signature > modifiers[i].signature) 631362b94d5Smrg left = i + 1; 632362b94d5Smrg else { 633362b94d5Smrg previous = i; 634362b94d5Smrg if (constMask) 635362b94d5Smrg *valueP = modifiers[i].value; 636362b94d5Smrg else /* if (modifiers[i].modifierParseProc) always true */ 637362b94d5Smrg (*modifiers[i].modifierParseProc) 638362b94d5Smrg (modifiers[i].value, lateBindings, notFlag, valueP); 639362b94d5Smrg UNLOCK_PROCESS; 640362b94d5Smrg return TRUE; 641362b94d5Smrg } 642444c061aSmrg } 643444c061aSmrg UNLOCK_PROCESS; 644444c061aSmrg return FALSE; 645444c061aSmrg} 646444c061aSmrg 647362b94d5Smrgstatic String 648362b94d5SmrgScanIdent(register String str) 649444c061aSmrg{ 650444c061aSmrg ScanAlphanumeric(str); 651362b94d5Smrg while (('A' <= *str && *str <= 'Z') 652362b94d5Smrg || ('a' <= *str && *str <= 'z') 653362b94d5Smrg || ('0' <= *str && *str <= '9') 654362b94d5Smrg || (*str == '-') 655362b94d5Smrg || (*str == '_') 656362b94d5Smrg || (*str == '$') 657362b94d5Smrg ) 658362b94d5Smrg str++; 659444c061aSmrg return str; 660444c061aSmrg} 661444c061aSmrg 662362b94d5Smrgstatic String 663362b94d5SmrgFetchModifierToken(String str, XrmQuark *token_return) 664444c061aSmrg{ 665444c061aSmrg String start = str; 666444c061aSmrg 667444c061aSmrg if (*str == '$') { 668444c061aSmrg *token_return = QMeta; 669444c061aSmrg str++; 670362b94d5Smrg } 671362b94d5Smrg else if (*str == '^') { 672444c061aSmrg *token_return = QCtrl; 673444c061aSmrg str++; 674362b94d5Smrg } 675362b94d5Smrg else { 676362b94d5Smrg str = ScanIdent(str); 677362b94d5Smrg if (start != str) { 678362b94d5Smrg char modStrbuf[100]; 679362b94d5Smrg char *modStr; 680362b94d5Smrg 681362b94d5Smrg modStr = XtStackAlloc((size_t) (str - start + 1), modStrbuf); 682362b94d5Smrg if (modStr == NULL) 683362b94d5Smrg _XtAllocError(NULL); 684362b94d5Smrg (void) memmove(modStr, start, (size_t) (str - start)); 685362b94d5Smrg modStr[str - start] = '\0'; 686362b94d5Smrg *token_return = XrmStringToQuark(modStr); 687362b94d5Smrg XtStackFree(modStr, modStrbuf); 688362b94d5Smrg } 689444c061aSmrg } 690444c061aSmrg return str; 691444c061aSmrg} 692444c061aSmrg 693362b94d5Smrgstatic String 694362b94d5SmrgParseModifiers(register String str, EventPtr event, Boolean *error) 695444c061aSmrg{ 696444c061aSmrg register String start; 697444c061aSmrg Boolean notFlag, exclusive, keysymAsMod; 698444c061aSmrg Value maskBit; 69972af6995Smrg XrmQuark Qmod = QNone; 700444c061aSmrg 701444c061aSmrg ScanWhitespace(str); 702444c061aSmrg start = str; 703444c061aSmrg str = FetchModifierToken(str, &Qmod); 704444c061aSmrg exclusive = FALSE; 705444c061aSmrg if (start != str) { 706362b94d5Smrg if (Qmod == QNone) { 707362b94d5Smrg event->event.modifierMask = (unsigned long) (~0); 708362b94d5Smrg event->event.modifiers = 0; 709362b94d5Smrg ScanWhitespace(str); 710362b94d5Smrg return str; 711444c061aSmrg } 712362b94d5Smrg else if (Qmod == QAny) { /*backward compatability */ 713362b94d5Smrg event->event.modifierMask = 0; 714362b94d5Smrg event->event.modifiers = AnyModifier; 715362b94d5Smrg ScanWhitespace(str); 716362b94d5Smrg return str; 717444c061aSmrg } 718362b94d5Smrg str = start; /*if plain modifier, reset to beginning */ 719444c061aSmrg } 720362b94d5Smrg else 721362b94d5Smrg while (*str == '!' || *str == ':') { 722362b94d5Smrg if (*str == '!') { 723362b94d5Smrg exclusive = TRUE; 724362b94d5Smrg str++; 725362b94d5Smrg ScanWhitespace(str); 726362b94d5Smrg } 727362b94d5Smrg if (*str == ':') { 728362b94d5Smrg event->event.standard = TRUE; 729362b94d5Smrg str++; 730362b94d5Smrg ScanWhitespace(str); 731362b94d5Smrg } 732362b94d5Smrg } 733444c061aSmrg 734444c061aSmrg while (*str != '<') { 735444c061aSmrg if (*str == '~') { 736362b94d5Smrg notFlag = TRUE; 737362b94d5Smrg str++; 738362b94d5Smrg } 739362b94d5Smrg else 740362b94d5Smrg notFlag = FALSE; 741444c061aSmrg if (*str == '@') { 742444c061aSmrg keysymAsMod = TRUE; 743444c061aSmrg str++; 744444c061aSmrg } 745362b94d5Smrg else 746362b94d5Smrg keysymAsMod = FALSE; 747362b94d5Smrg start = str; 748444c061aSmrg str = FetchModifierToken(str, &Qmod); 749444c061aSmrg if (start == str) { 750362b94d5Smrg Syntax("Modifier or '<' expected", ""); 751362b94d5Smrg *error = TRUE; 752362b94d5Smrg return PanicModeRecovery(str); 753362b94d5Smrg } 754362b94d5Smrg if (keysymAsMod) { 755362b94d5Smrg _XtParseKeysymMod(XrmQuarkToString(Qmod), 756362b94d5Smrg &event->event.lateModifiers, 757362b94d5Smrg notFlag, &maskBit, error); 758362b94d5Smrg if (*error) 759362b94d5Smrg return PanicModeRecovery(str); 760362b94d5Smrg 761362b94d5Smrg } 762362b94d5Smrg else if (!_XtLookupModifier(Qmod, &event->event.lateModifiers, 763362b94d5Smrg notFlag, &maskBit, FALSE)) { 764362b94d5Smrg Syntax("Unknown modifier name: ", XrmQuarkToString(Qmod)); 765444c061aSmrg *error = TRUE; 766444c061aSmrg return PanicModeRecovery(str); 767444c061aSmrg } 768444c061aSmrg event->event.modifierMask |= maskBit; 769362b94d5Smrg if (notFlag) 770362b94d5Smrg event->event.modifiers = 771362b94d5Smrg (event->event.modifiers & (TMLongCard) (~maskBit)); 772362b94d5Smrg else 773362b94d5Smrg event->event.modifiers |= maskBit; 774444c061aSmrg ScanWhitespace(str); 775444c061aSmrg } 776362b94d5Smrg if (exclusive) 777362b94d5Smrg event->event.modifierMask = (unsigned long) (~0); 778444c061aSmrg return str; 779444c061aSmrg} 780444c061aSmrg 781362b94d5Smrgstatic String 782362b94d5SmrgParseXtEventType(register String str, 783362b94d5Smrg EventPtr event, 784362b94d5Smrg Cardinal *tmEventP, 785362b94d5Smrg Boolean *error) 786444c061aSmrg{ 787444c061aSmrg String start = str; 788444c061aSmrg char eventTypeStrbuf[100]; 789362b94d5Smrg char *eventTypeStr; 790444c061aSmrg 791444c061aSmrg ScanAlphanumeric(str); 792362b94d5Smrg eventTypeStr = XtStackAlloc((size_t) (str - start + 1), eventTypeStrbuf); 793362b94d5Smrg if (eventTypeStr == NULL) 794362b94d5Smrg _XtAllocError(NULL); 795362b94d5Smrg (void) memmove(eventTypeStr, start, (size_t) (str - start)); 796362b94d5Smrg eventTypeStr[str - start] = '\0'; 797362b94d5Smrg *tmEventP = LookupTMEventType(eventTypeStr, error); 798362b94d5Smrg XtStackFree(eventTypeStr, eventTypeStrbuf); 799444c061aSmrg if (*error) 800444c061aSmrg return PanicModeRecovery(str); 80172af6995Smrg event->event.eventType = (TMLongCard) events[*tmEventP].eventType; 802444c061aSmrg return str; 803444c061aSmrg} 804444c061aSmrg 805362b94d5Smrgstatic unsigned long 806362b94d5SmrgStrToHex(String str) 807444c061aSmrg{ 808362b94d5Smrg register char c; 809362b94d5Smrg register unsigned long val = 0; 810444c061aSmrg 811444c061aSmrg while ((c = *str)) { 812362b94d5Smrg if ('0' <= c && c <= '9') 813362b94d5Smrg val = (unsigned long) (val * 16 + (unsigned long) c - '0'); 814362b94d5Smrg else if ('a' <= c && c <= 'z') 815362b94d5Smrg val = (unsigned long) (val * 16 + (unsigned long) c - 'a' + 10); 816362b94d5Smrg else if ('A' <= c && c <= 'Z') 817362b94d5Smrg val = (unsigned long) (val * 16 + (unsigned long) c - 'A' + 10); 818362b94d5Smrg else 819362b94d5Smrg return 0; 820362b94d5Smrg str++; 821444c061aSmrg } 822444c061aSmrg 823444c061aSmrg return val; 824444c061aSmrg} 825444c061aSmrg 826362b94d5Smrgstatic unsigned long 827362b94d5SmrgStrToOct(String str) 828444c061aSmrg{ 829444c061aSmrg register char c; 830362b94d5Smrg register unsigned long val = 0; 831444c061aSmrg 832444c061aSmrg while ((c = *str)) { 833362b94d5Smrg if ('0' <= c && c <= '7') 834362b94d5Smrg val = val * 8 + (unsigned long) c - '0'; 835362b94d5Smrg else 836362b94d5Smrg return 0; 837362b94d5Smrg str++; 838444c061aSmrg } 839444c061aSmrg 840444c061aSmrg return val; 841444c061aSmrg} 842444c061aSmrg 843362b94d5Smrgstatic unsigned long 844362b94d5SmrgStrToNum(String str) 845444c061aSmrg{ 846444c061aSmrg register char c; 847444c061aSmrg register unsigned long val = 0; 848444c061aSmrg 849444c061aSmrg if (*str == '0') { 850362b94d5Smrg str++; 851362b94d5Smrg if (*str == 'x' || *str == 'X') 852362b94d5Smrg return StrToHex(++str); 853362b94d5Smrg else 854362b94d5Smrg return StrToOct(str); 855444c061aSmrg } 856444c061aSmrg 857444c061aSmrg while ((c = *str)) { 858362b94d5Smrg if ('0' <= c && c <= '9') 859362b94d5Smrg val = val * 10 + (unsigned long) c - '0'; 860362b94d5Smrg else 861362b94d5Smrg return 0; 862362b94d5Smrg str++; 863444c061aSmrg } 864444c061aSmrg 865444c061aSmrg return val; 866444c061aSmrg} 867444c061aSmrg 868362b94d5Smrgstatic KeySym 869362b94d5SmrgStringToKeySym(String str, Boolean *error) 870444c061aSmrg{ 871444c061aSmrg KeySym k; 872444c061aSmrg 873362b94d5Smrg if (str == NULL || *str == '\0') 874362b94d5Smrg return (KeySym) 0; 875444c061aSmrg 876444c061aSmrg#ifndef NOTASCII 877444c061aSmrg /* special case single character ASCII, for speed */ 878362b94d5Smrg if (*(str + 1) == '\0') { 879362b94d5Smrg if (' ' <= *str && *str <= '~') 880362b94d5Smrg return (KeySym) (XK_space + (*str - ' ')); 881444c061aSmrg } 882444c061aSmrg#endif 883444c061aSmrg 884362b94d5Smrg if ('0' <= *str && *str <= '9') 885362b94d5Smrg return (KeySym) StrToNum(str); 886444c061aSmrg k = XStringToKeysym(str); 887362b94d5Smrg if (k != NoSymbol) 888362b94d5Smrg return k; 889444c061aSmrg 890444c061aSmrg#ifdef NOTASCII 891444c061aSmrg /* fall-back case to preserve backwards compatibility; no-one 892444c061aSmrg * should be relying upon this! 893444c061aSmrg */ 894362b94d5Smrg if (*(str + 1) == '\0') 895362b94d5Smrg return (KeySym) * str; 896444c061aSmrg#endif 897444c061aSmrg 898444c061aSmrg Syntax("Unknown keysym name: ", str); 899444c061aSmrg *error = TRUE; 900444c061aSmrg return NoSymbol; 901444c061aSmrg} 902362b94d5Smrg 903362b94d5Smrgstatic void 904362b94d5SmrgParseModImmed(Value value, 905362b94d5Smrg LateBindingsPtr *lateBindings _X_UNUSED, 906362b94d5Smrg Boolean notFlag _X_UNUSED, 907362b94d5Smrg Value *valueP) 908444c061aSmrg{ 909444c061aSmrg *valueP = value; 910444c061aSmrg} 911444c061aSmrg 912362b94d5Smrg/* is only valid with keysyms that have an _L and _R in their name; 913362b94d5Smrg * and ignores keysym lookup errors (i.e. assumes only valid keysyms) 914362b94d5Smrg */ 915362b94d5Smrgstatic void 916362b94d5SmrgParseModSym(Value value, 917362b94d5Smrg LateBindingsPtr *lateBindings, Boolean notFlag, Value *valueP) 918444c061aSmrg{ 919362b94d5Smrg register KeySym keysymL = (KeySym) value; 920362b94d5Smrg register KeySym keysymR = keysymL + 1; /* valid for supported keysyms */ 921362b94d5Smrg 922362b94d5Smrg StoreLateBindings(keysymL, notFlag, keysymR, notFlag, lateBindings); 923444c061aSmrg *valueP = 0; 924444c061aSmrg} 925444c061aSmrg 926444c061aSmrg#ifdef sparc 927444c061aSmrg/* 928444c061aSmrg * The stupid optimizer in SunOS 4.0.3 and below generates bogus code that 929444c061aSmrg * causes the value of the most recently used variable to be returned instead 930444c061aSmrg * of the value passed in. 931444c061aSmrg */ 932444c061aSmrgstatic String stupid_optimizer_kludge; 933362b94d5Smrg 934444c061aSmrg#define BROKEN_OPTIMIZER_HACK(val) stupid_optimizer_kludge = (val) 935444c061aSmrg#else 936444c061aSmrg#define BROKEN_OPTIMIZER_HACK(val) val 937444c061aSmrg#endif 938444c061aSmrg 939362b94d5Smrgstatic String 940362b94d5SmrgParseImmed(register String str, 941362b94d5Smrg register Opaque closure, 942362b94d5Smrg register EventPtr event, 943362b94d5Smrg Boolean *error _X_UNUSED) 944444c061aSmrg{ 945362b94d5Smrg event->event.eventCode = (unsigned long) closure; 94672af6995Smrg event->event.eventCodeMask = (unsigned long) (~0UL); 947444c061aSmrg 948444c061aSmrg return BROKEN_OPTIMIZER_HACK(str); 949444c061aSmrg} 950444c061aSmrg 951362b94d5Smrgstatic String 952362b94d5SmrgParseAddModifier(register String str, 953362b94d5Smrg register Opaque closure, 954362b94d5Smrg register EventPtr event, 955362b94d5Smrg Boolean *error _X_UNUSED) 956444c061aSmrg{ 957362b94d5Smrg register unsigned long modval = (unsigned long) closure; 958362b94d5Smrg 959444c061aSmrg event->event.modifiers |= modval; 960362b94d5Smrg if (modval != AnyButtonMask) /* AnyButtonMask is don't-care mask */ 961362b94d5Smrg event->event.modifierMask |= modval; 962444c061aSmrg 963444c061aSmrg return BROKEN_OPTIMIZER_HACK(str); 964444c061aSmrg} 965444c061aSmrg 966362b94d5Smrgstatic String 967362b94d5SmrgParseKeyAndModifiers(String str, 968362b94d5Smrg Opaque closure, 969362b94d5Smrg EventPtr event, 970362b94d5Smrg Boolean *error) 971444c061aSmrg{ 972362b94d5Smrg str = ParseKeySym(str, closure, event, error); 973444c061aSmrg if ((unsigned long) closure == 0) { 974362b94d5Smrg Value metaMask; /* unused */ 975362b94d5Smrg 976362b94d5Smrg (void) _XtLookupModifier(QMeta, &event->event.lateModifiers, FALSE, 977362b94d5Smrg &metaMask, FALSE); 978362b94d5Smrg } 979362b94d5Smrg else { 980362b94d5Smrg event->event.modifiers |= (unsigned long) closure; 981362b94d5Smrg event->event.modifierMask |= (unsigned long) closure; 982444c061aSmrg } 983444c061aSmrg return str; 984444c061aSmrg} 985444c061aSmrg 986362b94d5Smrgstatic String 987362b94d5SmrgParseKeySym(register String str, 988362b94d5Smrg Opaque closure _X_UNUSED, 989362b94d5Smrg EventPtr event, 990362b94d5Smrg Boolean *error) 991444c061aSmrg{ 99272af6995Smrg String start; 993444c061aSmrg char keySymNamebuf[100]; 994362b94d5Smrg char *keySymName = NULL; 995444c061aSmrg 996444c061aSmrg ScanWhitespace(str); 997444c061aSmrg 998444c061aSmrg if (*str == '\\') { 999362b94d5Smrg keySymName = keySymNamebuf; 1000362b94d5Smrg str++; 1001362b94d5Smrg keySymName[0] = *str; 1002362b94d5Smrg if (*str != '\0' && !IsNewline(*str)) 1003362b94d5Smrg str++; 1004362b94d5Smrg keySymName[1] = '\0'; 1005362b94d5Smrg event->event.eventCode = StringToKeySym(keySymName, error); 1006362b94d5Smrg event->event.eventCodeMask = (unsigned long) (~0L); 1007362b94d5Smrg } 1008362b94d5Smrg else if (*str == ',' || *str == ':' || 1009444c061aSmrg /* allow leftparen to be single char symbol, 1010444c061aSmrg * for backwards compatibility 1011444c061aSmrg */ 1012362b94d5Smrg (*str == '(' && *(str + 1) >= '0' && *(str + 1) <= '9')) { 1013362b94d5Smrg keySymName = keySymNamebuf; /* just so we can stackfree it later */ 1014362b94d5Smrg /* no detail */ 1015362b94d5Smrg event->event.eventCode = 0L; 1016444c061aSmrg event->event.eventCodeMask = 0L; 1017362b94d5Smrg } 1018362b94d5Smrg else { 1019362b94d5Smrg start = str; 1020362b94d5Smrg while (*str != ',' 1021362b94d5Smrg && *str != ':' && *str != ' ' && *str != '\t' && !IsNewline(*str) 1022362b94d5Smrg && (*str != '(' || *(str + 1) <= '0' || *(str + 1) >= '9') 1023362b94d5Smrg && *str != '\0') 1024362b94d5Smrg str++; 1025362b94d5Smrg keySymName = XtStackAlloc((size_t) (str - start + 1), keySymNamebuf); 1026362b94d5Smrg (void) memmove(keySymName, start, (size_t) (str - start)); 1027362b94d5Smrg keySymName[str - start] = '\0'; 1028362b94d5Smrg event->event.eventCode = StringToKeySym(keySymName, error); 1029362b94d5Smrg event->event.eventCodeMask = (unsigned long) (~0L); 1030444c061aSmrg } 103172af6995Smrg if (*error && keySymName) { 1032362b94d5Smrg /* We never get here when keySymName hasn't been allocated */ 1033362b94d5Smrg if (keySymName[0] == '<') { 1034362b94d5Smrg /* special case for common error */ 1035362b94d5Smrg XtWarningMsg(XtNtranslationParseError, "missingComma", 1036362b94d5Smrg XtCXtToolkitError, 1037362b94d5Smrg "... possibly due to missing ',' in event sequence.", 1038362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 1039362b94d5Smrg } 1040362b94d5Smrg XtStackFree(keySymName, keySymNamebuf); 1041362b94d5Smrg return PanicModeRecovery(str); 1042444c061aSmrg } 1043444c061aSmrg if (event->event.standard) 1044362b94d5Smrg event->event.matchEvent = _XtMatchUsingStandardMods; 1045444c061aSmrg else 1046362b94d5Smrg event->event.matchEvent = _XtMatchUsingDontCareMods; 1047444c061aSmrg 1048362b94d5Smrg XtStackFree(keySymName, keySymNamebuf); 1049444c061aSmrg 1050444c061aSmrg return str; 1051444c061aSmrg} 1052444c061aSmrg 1053362b94d5Smrgstatic String 1054362b94d5SmrgParseTable(register String str, Opaque closure, EventPtr event, Boolean *error) 1055444c061aSmrg{ 1056444c061aSmrg register String start = str; 1057444c061aSmrg register XrmQuark signature; 1058444c061aSmrg NameValueTable table = (NameValueTable) closure; 1059444c061aSmrg char tableSymName[100]; 1060444c061aSmrg 1061444c061aSmrg event->event.eventCode = 0L; 1062444c061aSmrg ScanAlphanumeric(str); 1063362b94d5Smrg if (str == start) { 1064362b94d5Smrg event->event.eventCodeMask = 0L; 1065362b94d5Smrg return str; 1066362b94d5Smrg } 1067362b94d5Smrg if (str - start >= 99) { 1068362b94d5Smrg Syntax("Invalid Detail Type (string is too long).", ""); 1069362b94d5Smrg *error = TRUE; 1070362b94d5Smrg return str; 1071362b94d5Smrg } 1072362b94d5Smrg (void) memmove(tableSymName, start, (size_t) (str - start)); 1073362b94d5Smrg tableSymName[str - start] = '\0'; 1074444c061aSmrg signature = StringToQuark(tableSymName); 1075444c061aSmrg for (; table->signature != NULLQUARK; table++) 1076362b94d5Smrg if (table->signature == signature) { 1077362b94d5Smrg event->event.eventCode = table->value; 1078362b94d5Smrg event->event.eventCodeMask = (unsigned long) (~0L); 1079362b94d5Smrg return str; 1080362b94d5Smrg } 1081444c061aSmrg 1082444c061aSmrg Syntax("Unknown Detail Type: ", tableSymName); 1083444c061aSmrg *error = TRUE; 1084444c061aSmrg return PanicModeRecovery(str); 1085444c061aSmrg} 1086444c061aSmrg 1087362b94d5Smrgstatic String 1088362b94d5SmrgParseNone(String str, 1089362b94d5Smrg Opaque closure _X_UNUSED, 1090362b94d5Smrg EventPtr event, 1091362b94d5Smrg Boolean *error _X_UNUSED) 1092444c061aSmrg{ 1093444c061aSmrg event->event.eventCode = 0; 1094444c061aSmrg event->event.eventCodeMask = 0; 1095444c061aSmrg 1096444c061aSmrg return BROKEN_OPTIMIZER_HACK(str); 1097444c061aSmrg} 1098444c061aSmrg 1099362b94d5Smrgstatic String 1100362b94d5SmrgParseAtom(String str, Opaque closure _X_UNUSED, EventPtr event, Boolean *error) 1101444c061aSmrg{ 1102444c061aSmrg ScanWhitespace(str); 1103444c061aSmrg 1104444c061aSmrg if (*str == ',' || *str == ':') { 1105362b94d5Smrg /* no detail */ 1106362b94d5Smrg event->event.eventCode = 0L; 1107444c061aSmrg event->event.eventCodeMask = 0L; 1108362b94d5Smrg } 1109362b94d5Smrg else { 1110362b94d5Smrg String start; 1111362b94d5Smrg char atomName[1000]; 1112362b94d5Smrg 1113362b94d5Smrg start = str; 1114362b94d5Smrg while (*str != ',' 1115362b94d5Smrg && *str != ':' && *str != ' ' && *str != '\t' && !IsNewline(*str) 1116362b94d5Smrg && *str != '\0') 1117362b94d5Smrg str++; 1118362b94d5Smrg if (str - start >= 999) { 1119362b94d5Smrg Syntax("Atom name must be less than 1000 characters long.", ""); 1120362b94d5Smrg *error = TRUE; 1121362b94d5Smrg return str; 1122362b94d5Smrg } 1123362b94d5Smrg (void) memmove(atomName, start, (size_t) (str - start)); 1124362b94d5Smrg atomName[str - start] = '\0'; 1125362b94d5Smrg event->event.eventCode = (TMLongCard) XrmStringToQuark(atomName); 1126362b94d5Smrg event->event.matchEvent = _XtMatchAtom; 1127444c061aSmrg } 1128444c061aSmrg return str; 1129444c061aSmrg} 1130444c061aSmrg 1131444c061aSmrgstatic ModifierMask buttonModifierMasks[] = { 1132444c061aSmrg 0, Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask 1133444c061aSmrg}; 1134362b94d5Smrg 1135444c061aSmrgstatic String ParseRepeat(String, int *, Boolean *, Boolean *); 1136444c061aSmrg 1137362b94d5Smrgstatic String 1138362b94d5SmrgParseEvent(register String str, 1139362b94d5Smrg EventPtr event, int *reps, 1140362b94d5Smrg Boolean *plus, 1141362b94d5Smrg Boolean *error) 1142444c061aSmrg{ 1143362b94d5Smrg Cardinal tmEvent; 1144444c061aSmrg 1145362b94d5Smrg str = ParseModifiers(str, event, error); 1146362b94d5Smrg if (*error) 1147362b94d5Smrg return str; 1148444c061aSmrg if (*str != '<') { 1149362b94d5Smrg Syntax("Missing '<' while parsing event type.", ""); 1150362b94d5Smrg *error = TRUE; 1151362b94d5Smrg return PanicModeRecovery(str); 1152362b94d5Smrg } 1153362b94d5Smrg else 1154362b94d5Smrg str++; 1155362b94d5Smrg str = ParseXtEventType(str, event, &tmEvent, error); 1156362b94d5Smrg if (*error) 1157362b94d5Smrg return str; 1158362b94d5Smrg if (*str != '>') { 1159362b94d5Smrg Syntax("Missing '>' while parsing event type", ""); 1160362b94d5Smrg *error = TRUE; 1161362b94d5Smrg return PanicModeRecovery(str); 1162362b94d5Smrg } 1163362b94d5Smrg else 1164362b94d5Smrg str++; 1165444c061aSmrg if (*str == '(') { 1166362b94d5Smrg str = ParseRepeat(str, reps, plus, error); 1167362b94d5Smrg if (*error) 1168362b94d5Smrg return str; 1169444c061aSmrg } 1170362b94d5Smrg str = 1171362b94d5Smrg (*(events[tmEvent].parseDetail)) (str, events[tmEvent].closure, event, 1172362b94d5Smrg error); 1173362b94d5Smrg if (*error) 1174362b94d5Smrg return str; 1175444c061aSmrg 1176444c061aSmrg/* gross hack! ||| this kludge is related to the X11 protocol deficiency w.r.t. 1177444c061aSmrg * modifiers in grabs. 1178444c061aSmrg */ 1179444c061aSmrg if ((event->event.eventType == ButtonRelease) 1180362b94d5Smrg && (event->event.modifiers | event->event.modifierMask) /* any */ 1181362b94d5Smrg &&(event->event.modifiers != AnyModifier)) { 1182362b94d5Smrg event->event.modifiers = (event->event.modifiers 1183362b94d5Smrg | (TMLongCard) buttonModifierMasks[event-> 1184362b94d5Smrg event. 1185362b94d5Smrg eventCode]); 1186362b94d5Smrg /* the button that is going up will always be in the modifiers... */ 1187444c061aSmrg } 1188444c061aSmrg 1189444c061aSmrg return str; 1190444c061aSmrg} 1191444c061aSmrg 1192362b94d5Smrgstatic String 1193362b94d5SmrgParseQuotedStringEvent(register String str, 1194362b94d5Smrg register EventPtr event, 1195362b94d5Smrg Boolean *error) 1196444c061aSmrg{ 1197444c061aSmrg Value metaMask; 1198362b94d5Smrg char s[2]; 1199444c061aSmrg 1200362b94d5Smrg if (*str == '^') { 1201362b94d5Smrg str++; 1202362b94d5Smrg event->event.modifiers = ControlMask; 1203362b94d5Smrg } 1204362b94d5Smrg else if (*str == '$') { 1205362b94d5Smrg str++; 1206362b94d5Smrg (void) _XtLookupModifier(QMeta, &event->event.lateModifiers, FALSE, 1207362b94d5Smrg &metaMask, FALSE); 1208444c061aSmrg } 1209444c061aSmrg if (*str == '\\') 1210362b94d5Smrg str++; 1211444c061aSmrg s[0] = *str; 1212444c061aSmrg s[1] = '\0'; 1213362b94d5Smrg if (*str != '\0' && !IsNewline(*str)) 1214362b94d5Smrg str++; 1215444c061aSmrg event->event.eventType = KeyPress; 1216444c061aSmrg event->event.eventCode = StringToKeySym(s, error); 1217362b94d5Smrg if (*error) 1218362b94d5Smrg return PanicModeRecovery(str); 121972af6995Smrg event->event.eventCodeMask = (unsigned long) (~0L); 1220444c061aSmrg event->event.matchEvent = _XtMatchUsingStandardMods; 1221444c061aSmrg event->event.standard = TRUE; 1222444c061aSmrg 1223444c061aSmrg return str; 1224444c061aSmrg} 1225444c061aSmrg 1226444c061aSmrgstatic EventSeqRec timerEventRec = { 1227444c061aSmrg {0, 0, NULL, _XtEventTimerEventType, 0L, 0L, NULL, False}, 1228444c061aSmrg /* (StatePtr) -1 */ NULL, 1229444c061aSmrg NULL, 1230444c061aSmrg NULL 1231444c061aSmrg}; 1232444c061aSmrg 1233362b94d5Smrgstatic void 1234362b94d5SmrgRepeatDown(EventPtr *eventP, int reps, ActionPtr **actionsP) 1235444c061aSmrg{ 1236444c061aSmrg EventRec upEventRec; 1237444c061aSmrg register EventPtr event, downEvent; 1238444c061aSmrg EventPtr upEvent = &upEventRec; 1239444c061aSmrg register int i; 1240444c061aSmrg 1241444c061aSmrg downEvent = event = *eventP; 1242444c061aSmrg *upEvent = *downEvent; 1243444c061aSmrg upEvent->event.eventType = ((event->event.eventType == ButtonPress) ? 1244362b94d5Smrg ButtonRelease : KeyRelease); 1245444c061aSmrg if ((upEvent->event.eventType == ButtonRelease) 1246362b94d5Smrg && (upEvent->event.modifiers != AnyModifier) 1247444c061aSmrg && (upEvent->event.modifiers | upEvent->event.modifierMask)) 1248362b94d5Smrg upEvent->event.modifiers = (upEvent->event.modifiers 1249362b94d5Smrg | (TMLongCard) buttonModifierMasks[event-> 1250362b94d5Smrg event. 1251362b94d5Smrg eventCode]); 1252444c061aSmrg 1253444c061aSmrg if (event->event.lateModifiers) 1254362b94d5Smrg event->event.lateModifiers->ref_count = 1255362b94d5Smrg (unsigned short) (event->event.lateModifiers->ref_count + 1256362b94d5Smrg (reps - 1) * 2); 1257444c061aSmrg 1258362b94d5Smrg for (i = 1; i < reps; i++) { 1259444c061aSmrg 1260362b94d5Smrg /* up */ 1261362b94d5Smrg event->next = XtNew(EventSeqRec); 1262362b94d5Smrg event = event->next; 1263362b94d5Smrg *event = *upEvent; 1264444c061aSmrg 1265362b94d5Smrg /* timer */ 1266362b94d5Smrg event->next = XtNew(EventSeqRec); 1267362b94d5Smrg event = event->next; 1268362b94d5Smrg *event = timerEventRec; 1269444c061aSmrg 1270362b94d5Smrg /* down */ 1271362b94d5Smrg event->next = XtNew(EventSeqRec); 1272362b94d5Smrg event = event->next; 1273362b94d5Smrg *event = *downEvent; 1274444c061aSmrg 1275444c061aSmrg } 1276444c061aSmrg 1277444c061aSmrg event->next = NULL; 1278444c061aSmrg *eventP = event; 1279444c061aSmrg *actionsP = &event->actions; 1280444c061aSmrg} 1281444c061aSmrg 1282362b94d5Smrgstatic void 1283362b94d5SmrgRepeatDownPlus(EventPtr *eventP, int reps, ActionPtr **actionsP) 1284444c061aSmrg{ 1285444c061aSmrg EventRec upEventRec; 1286444c061aSmrg register EventPtr event, downEvent, lastDownEvent = NULL; 1287444c061aSmrg EventPtr upEvent = &upEventRec; 1288444c061aSmrg register int i; 1289444c061aSmrg 1290444c061aSmrg downEvent = event = *eventP; 1291444c061aSmrg *upEvent = *downEvent; 1292444c061aSmrg upEvent->event.eventType = ((event->event.eventType == ButtonPress) ? 1293362b94d5Smrg ButtonRelease : KeyRelease); 1294444c061aSmrg if ((upEvent->event.eventType == ButtonRelease) 1295362b94d5Smrg && (upEvent->event.modifiers != AnyModifier) 1296444c061aSmrg && (upEvent->event.modifiers | upEvent->event.modifierMask)) 1297362b94d5Smrg upEvent->event.modifiers = (upEvent->event.modifiers 1298362b94d5Smrg | (TMLongCard) buttonModifierMasks[event-> 1299362b94d5Smrg event. 1300362b94d5Smrg eventCode]); 1301444c061aSmrg 1302444c061aSmrg if (event->event.lateModifiers) 1303362b94d5Smrg event->event.lateModifiers->ref_count = 1304362b94d5Smrg (unsigned short) (event->event.lateModifiers->ref_count + reps * 2 - 1305362b94d5Smrg 1); 1306444c061aSmrg 1307362b94d5Smrg for (i = 0; i < reps; i++) { 1308444c061aSmrg 1309362b94d5Smrg if (i > 0) { 1310362b94d5Smrg /* down */ 1311362b94d5Smrg event->next = XtNew(EventSeqRec); 1312362b94d5Smrg event = event->next; 1313362b94d5Smrg *event = *downEvent; 1314362b94d5Smrg } 1315362b94d5Smrg lastDownEvent = event; 1316444c061aSmrg 1317362b94d5Smrg /* up */ 1318362b94d5Smrg event->next = XtNew(EventSeqRec); 1319362b94d5Smrg event = event->next; 1320362b94d5Smrg *event = *upEvent; 1321444c061aSmrg 1322362b94d5Smrg /* timer */ 1323362b94d5Smrg event->next = XtNew(EventSeqRec); 1324362b94d5Smrg event = event->next; 1325362b94d5Smrg *event = timerEventRec; 1326444c061aSmrg 1327444c061aSmrg } 1328444c061aSmrg 1329444c061aSmrg event->next = lastDownEvent; 1330444c061aSmrg *eventP = event; 1331444c061aSmrg *actionsP = &lastDownEvent->actions; 1332444c061aSmrg} 1333444c061aSmrg 1334362b94d5Smrgstatic void 1335362b94d5SmrgRepeatUp(EventPtr *eventP, int reps, ActionPtr **actionsP) 1336444c061aSmrg{ 1337444c061aSmrg EventRec upEventRec; 1338444c061aSmrg register EventPtr event, downEvent; 1339444c061aSmrg EventPtr upEvent = &upEventRec; 1340444c061aSmrg register int i; 1341444c061aSmrg 1342444c061aSmrg /* the event currently sitting in *eventP is an "up" event */ 1343444c061aSmrg /* we want to make it a "down" event followed by an "up" event, */ 1344444c061aSmrg /* so that sequence matching on the "state" side works correctly. */ 1345444c061aSmrg 1346444c061aSmrg downEvent = event = *eventP; 1347444c061aSmrg *upEvent = *downEvent; 1348444c061aSmrg downEvent->event.eventType = ((event->event.eventType == ButtonRelease) ? 1349362b94d5Smrg ButtonPress : KeyPress); 1350444c061aSmrg if ((downEvent->event.eventType == ButtonPress) 1351362b94d5Smrg && (downEvent->event.modifiers != AnyModifier) 1352444c061aSmrg && (downEvent->event.modifiers | downEvent->event.modifierMask)) 1353362b94d5Smrg downEvent->event.modifiers = (downEvent->event.modifiers 1354362b94d5Smrg & 1355362b94d5Smrg (TMLongCard) (~buttonModifierMasks 1356362b94d5Smrg [event->event.eventCode])); 1357444c061aSmrg 1358444c061aSmrg if (event->event.lateModifiers) 1359362b94d5Smrg event->event.lateModifiers->ref_count = 1360362b94d5Smrg (unsigned short) (event->event.lateModifiers->ref_count + reps * 2 - 1361362b94d5Smrg 1); 1362444c061aSmrg 1363444c061aSmrg /* up */ 1364444c061aSmrg event->next = XtNew(EventSeqRec); 1365444c061aSmrg event = event->next; 1366444c061aSmrg *event = *upEvent; 1367444c061aSmrg 1368362b94d5Smrg for (i = 1; i < reps; i++) { 1369444c061aSmrg 1370362b94d5Smrg /* timer */ 1371362b94d5Smrg event->next = XtNew(EventSeqRec); 1372362b94d5Smrg event = event->next; 1373362b94d5Smrg *event = timerEventRec; 1374444c061aSmrg 1375362b94d5Smrg /* down */ 1376362b94d5Smrg event->next = XtNew(EventSeqRec); 1377362b94d5Smrg event = event->next; 1378362b94d5Smrg *event = *downEvent; 1379444c061aSmrg 1380362b94d5Smrg /* up */ 1381362b94d5Smrg event->next = XtNew(EventSeqRec); 1382362b94d5Smrg event = event->next; 1383362b94d5Smrg *event = *upEvent; 1384444c061aSmrg 1385362b94d5Smrg } 1386444c061aSmrg 1387444c061aSmrg event->next = NULL; 1388444c061aSmrg *eventP = event; 1389444c061aSmrg *actionsP = &event->actions; 1390444c061aSmrg} 1391444c061aSmrg 1392362b94d5Smrgstatic void 1393362b94d5SmrgRepeatUpPlus(EventPtr *eventP, int reps, ActionPtr **actionsP) 1394444c061aSmrg{ 1395444c061aSmrg EventRec upEventRec; 1396444c061aSmrg register EventPtr event, downEvent, lastUpEvent = NULL; 1397444c061aSmrg EventPtr upEvent = &upEventRec; 1398444c061aSmrg register int i; 1399444c061aSmrg 1400444c061aSmrg /* the event currently sitting in *eventP is an "up" event */ 1401444c061aSmrg /* we want to make it a "down" event followed by an "up" event, */ 1402444c061aSmrg /* so that sequence matching on the "state" side works correctly. */ 1403444c061aSmrg 1404444c061aSmrg downEvent = event = *eventP; 1405444c061aSmrg *upEvent = *downEvent; 1406444c061aSmrg downEvent->event.eventType = ((event->event.eventType == ButtonRelease) ? 1407362b94d5Smrg ButtonPress : KeyPress); 1408444c061aSmrg if ((downEvent->event.eventType == ButtonPress) 1409362b94d5Smrg && (downEvent->event.modifiers != AnyModifier) 1410444c061aSmrg && (downEvent->event.modifiers | downEvent->event.modifierMask)) 1411362b94d5Smrg downEvent->event.modifiers = (downEvent->event.modifiers 1412362b94d5Smrg & 1413362b94d5Smrg (TMLongCard) (~buttonModifierMasks 1414362b94d5Smrg [event->event.eventCode])); 1415444c061aSmrg 1416444c061aSmrg if (event->event.lateModifiers) 1417362b94d5Smrg event->event.lateModifiers->ref_count = 1418362b94d5Smrg (unsigned short) (event->event.lateModifiers->ref_count + reps * 2); 1419444c061aSmrg 1420362b94d5Smrg for (i = 0; i < reps; i++) { 1421444c061aSmrg 1422362b94d5Smrg /* up */ 1423362b94d5Smrg event->next = XtNew(EventSeqRec); 1424362b94d5Smrg lastUpEvent = event = event->next; 1425362b94d5Smrg *event = *upEvent; 1426444c061aSmrg 1427362b94d5Smrg /* timer */ 1428362b94d5Smrg event->next = XtNew(EventSeqRec); 1429362b94d5Smrg event = event->next; 1430362b94d5Smrg *event = timerEventRec; 1431444c061aSmrg 1432362b94d5Smrg /* down */ 1433362b94d5Smrg event->next = XtNew(EventSeqRec); 1434444c061aSmrg event = event->next; 1435362b94d5Smrg *event = *downEvent; 1436444c061aSmrg 1437362b94d5Smrg } 1438444c061aSmrg 1439444c061aSmrg event->next = lastUpEvent; 1440444c061aSmrg *eventP = event; 1441444c061aSmrg *actionsP = &lastUpEvent->actions; 1442444c061aSmrg} 1443444c061aSmrg 1444362b94d5Smrgstatic void 1445362b94d5SmrgRepeatOther(EventPtr *eventP, int reps, ActionPtr **actionsP) 1446444c061aSmrg{ 1447444c061aSmrg register EventPtr event, tempEvent; 1448444c061aSmrg register int i; 1449444c061aSmrg 1450444c061aSmrg tempEvent = event = *eventP; 1451444c061aSmrg 1452444c061aSmrg if (event->event.lateModifiers) 1453362b94d5Smrg event->event.lateModifiers->ref_count = 1454362b94d5Smrg (unsigned short) (event->event.lateModifiers->ref_count + reps - 1); 1455444c061aSmrg 1456362b94d5Smrg for (i = 1; i < reps; i++) { 1457362b94d5Smrg event->next = XtNew(EventSeqRec); 1458362b94d5Smrg event = event->next; 1459362b94d5Smrg *event = *tempEvent; 1460444c061aSmrg } 1461444c061aSmrg 1462444c061aSmrg *eventP = event; 1463444c061aSmrg *actionsP = &event->actions; 1464444c061aSmrg} 1465444c061aSmrg 1466362b94d5Smrgstatic void 1467362b94d5SmrgRepeatOtherPlus(EventPtr *eventP, int reps, ActionPtr **actionsP) 1468444c061aSmrg{ 1469444c061aSmrg register EventPtr event, tempEvent; 1470444c061aSmrg register int i; 1471444c061aSmrg 1472444c061aSmrg tempEvent = event = *eventP; 1473444c061aSmrg 1474444c061aSmrg if (event->event.lateModifiers) 1475362b94d5Smrg event->event.lateModifiers->ref_count = 1476362b94d5Smrg (unsigned short) (event->event.lateModifiers->ref_count + reps - 1); 1477444c061aSmrg 1478362b94d5Smrg for (i = 1; i < reps; i++) { 1479362b94d5Smrg event->next = XtNew(EventSeqRec); 1480362b94d5Smrg event = event->next; 1481362b94d5Smrg *event = *tempEvent; 1482444c061aSmrg } 1483444c061aSmrg 1484444c061aSmrg event->next = event; 1485444c061aSmrg *eventP = event; 1486444c061aSmrg *actionsP = &event->actions; 1487444c061aSmrg} 1488444c061aSmrg 1489362b94d5Smrgstatic void 1490362b94d5SmrgRepeatEvent(EventPtr *eventP, int reps, Boolean plus, ActionPtr **actionsP) 1491444c061aSmrg{ 1492444c061aSmrg switch ((*eventP)->event.eventType) { 1493444c061aSmrg 1494362b94d5Smrg case ButtonPress: 1495362b94d5Smrg case KeyPress: 1496362b94d5Smrg if (plus) 1497362b94d5Smrg RepeatDownPlus(eventP, reps, actionsP); 1498362b94d5Smrg else 1499362b94d5Smrg RepeatDown(eventP, reps, actionsP); 1500362b94d5Smrg break; 1501362b94d5Smrg 1502362b94d5Smrg case ButtonRelease: 1503362b94d5Smrg case KeyRelease: 1504362b94d5Smrg if (plus) 1505362b94d5Smrg RepeatUpPlus(eventP, reps, actionsP); 1506362b94d5Smrg else 1507362b94d5Smrg RepeatUp(eventP, reps, actionsP); 1508362b94d5Smrg break; 1509362b94d5Smrg 1510362b94d5Smrg default: 1511362b94d5Smrg if (plus) 1512362b94d5Smrg RepeatOtherPlus(eventP, reps, actionsP); 1513362b94d5Smrg else 1514362b94d5Smrg RepeatOther(eventP, reps, actionsP); 1515444c061aSmrg } 1516444c061aSmrg} 1517444c061aSmrg 1518362b94d5Smrgstatic String 1519362b94d5SmrgParseRepeat(register String str, int *reps, Boolean *plus, Boolean *error) 1520444c061aSmrg{ 1521444c061aSmrg 1522444c061aSmrg /*** Parse the repetitions, for double click etc... ***/ 1523362b94d5Smrg if (*str != '(' || 1524362b94d5Smrg !(isdigit((unsigned char) str[1]) || str[1] == '+' || str[1] == ')')) 1525362b94d5Smrg return str; 1526444c061aSmrg str++; 1527362b94d5Smrg if (isdigit((unsigned char) *str)) { 1528362b94d5Smrg String start = str; 1529362b94d5Smrg char repStr[7]; 1530362b94d5Smrg size_t len; 1531362b94d5Smrg 1532362b94d5Smrg ScanNumeric(str); 1533362b94d5Smrg len = (size_t) (str - start); 1534362b94d5Smrg if (len < sizeof repStr) { 1535362b94d5Smrg (void) memmove(repStr, start, len); 1536362b94d5Smrg repStr[len] = '\0'; 1537362b94d5Smrg *reps = (int) StrToNum(repStr); 1538362b94d5Smrg } 1539362b94d5Smrg else { 1540362b94d5Smrg Syntax("Repeat count too large.", ""); 1541362b94d5Smrg *error = TRUE; 1542362b94d5Smrg return str; 1543362b94d5Smrg } 1544444c061aSmrg } 1545444c061aSmrg if (*reps == 0) { 1546362b94d5Smrg Syntax("Missing repeat count.", ""); 1547362b94d5Smrg *error = True; 1548362b94d5Smrg return str; 1549444c061aSmrg } 1550444c061aSmrg 1551444c061aSmrg if (*str == '+') { 1552362b94d5Smrg *plus = TRUE; 1553362b94d5Smrg str++; 1554444c061aSmrg } 1555444c061aSmrg if (*str == ')') 1556362b94d5Smrg str++; 1557444c061aSmrg else { 1558362b94d5Smrg Syntax("Missing ')'.", ""); 1559362b94d5Smrg *error = TRUE; 1560444c061aSmrg } 1561444c061aSmrg 1562444c061aSmrg return str; 1563444c061aSmrg} 1564444c061aSmrg 1565444c061aSmrg/*********************************************************************** 1566444c061aSmrg * ParseEventSeq 1567444c061aSmrg * Parses the left hand side of a translation table production 1568444c061aSmrg * up to, and consuming the ":". 1569444c061aSmrg * Takes a pointer to a char* (where to start parsing) and returns an 1570444c061aSmrg * event seq (in a passed in variable), having updated the String 1571444c061aSmrg **********************************************************************/ 1572444c061aSmrg 1573362b94d5Smrgstatic String 1574362b94d5SmrgParseEventSeq(register String str, 1575362b94d5Smrg EventSeqPtr *eventSeqP, 1576362b94d5Smrg ActionPtr ** actionsP, 1577362b94d5Smrg Boolean *error) 1578444c061aSmrg{ 1579444c061aSmrg EventSeqPtr *nextEvent = eventSeqP; 1580444c061aSmrg 1581444c061aSmrg *eventSeqP = NULL; 1582444c061aSmrg 1583362b94d5Smrg while (*str != '\0' && !IsNewline(*str)) { 1584362b94d5Smrg static Event nullEvent = 1585362b94d5Smrg { 0, 0, NULL, 0, 0L, 0L, _XtRegularMatch, FALSE }; 1586362b94d5Smrg EventPtr event; 1587444c061aSmrg 1588362b94d5Smrg ScanWhitespace(str); 1589444c061aSmrg 1590362b94d5Smrg if (*str == '"') { 1591362b94d5Smrg str++; 1592362b94d5Smrg while (*str != '"' && *str != '\0' && !IsNewline(*str)) { 1593444c061aSmrg event = XtNew(EventRec); 1594444c061aSmrg event->event = nullEvent; 1595444c061aSmrg event->state = /* (StatePtr) -1 */ NULL; 1596444c061aSmrg event->next = NULL; 1597444c061aSmrg event->actions = NULL; 1598362b94d5Smrg str = ParseQuotedStringEvent(str, event, error); 1599362b94d5Smrg if (*error) { 1600362b94d5Smrg XtWarningMsg(XtNtranslationParseError, "nonLatin1", 1601362b94d5Smrg XtCXtToolkitError, 1602362b94d5Smrg "... probably due to non-Latin1 character in quoted string", 1603362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 1604362b94d5Smrg XtFree((char *) event); 1605362b94d5Smrg return PanicModeRecovery(str); 1606362b94d5Smrg } 1607362b94d5Smrg *nextEvent = event; 1608362b94d5Smrg *actionsP = &event->actions; 1609362b94d5Smrg nextEvent = &event->next; 1610362b94d5Smrg } 1611362b94d5Smrg if (*str != '"') { 1612362b94d5Smrg Syntax("Missing '\"'.", ""); 1613444c061aSmrg *error = TRUE; 1614444c061aSmrg return PanicModeRecovery(str); 1615362b94d5Smrg } 1616362b94d5Smrg else 1617362b94d5Smrg str++; 1618362b94d5Smrg } 1619362b94d5Smrg else { 1620362b94d5Smrg int reps = 0; 1621362b94d5Smrg Boolean plus = FALSE; 1622444c061aSmrg 1623444c061aSmrg event = XtNew(EventRec); 1624444c061aSmrg event->event = nullEvent; 1625444c061aSmrg event->state = /* (StatePtr) -1 */ NULL; 1626444c061aSmrg event->next = NULL; 1627444c061aSmrg event->actions = NULL; 1628444c061aSmrg 1629362b94d5Smrg str = ParseEvent(str, event, &reps, &plus, error); 1630362b94d5Smrg if (*error) 1631362b94d5Smrg return str; 1632362b94d5Smrg *nextEvent = event; 1633362b94d5Smrg *actionsP = &event->actions; 1634362b94d5Smrg if (reps > 1 || plus) 1635362b94d5Smrg RepeatEvent(&event, reps, plus, actionsP); 1636362b94d5Smrg nextEvent = &event->next; 1637362b94d5Smrg } 1638362b94d5Smrg ScanWhitespace(str); 1639362b94d5Smrg if (*str == ':') 1640362b94d5Smrg break; 1641444c061aSmrg else { 1642444c061aSmrg if (*str != ',') { 1643362b94d5Smrg Syntax("',' or ':' expected while parsing event sequence.", ""); 1644444c061aSmrg *error = TRUE; 1645444c061aSmrg return PanicModeRecovery(str); 1646362b94d5Smrg } 1647362b94d5Smrg else 1648362b94d5Smrg str++; 1649444c061aSmrg } 1650444c061aSmrg } 1651444c061aSmrg 1652444c061aSmrg if (*str != ':') { 1653362b94d5Smrg Syntax("Missing ':'after event sequence.", ""); 1654444c061aSmrg *error = TRUE; 1655444c061aSmrg return PanicModeRecovery(str); 1656362b94d5Smrg } 1657362b94d5Smrg else 1658362b94d5Smrg str++; 1659444c061aSmrg 1660444c061aSmrg return str; 1661444c061aSmrg} 1662444c061aSmrg 1663362b94d5Smrgstatic String 1664362b94d5SmrgParseActionProc(register String str, XrmQuark *actionProcNameP, Boolean *error) 1665444c061aSmrg{ 1666444c061aSmrg register String start = str; 1667444c061aSmrg char procName[200]; 1668444c061aSmrg 1669444c061aSmrg str = ScanIdent(str); 1670362b94d5Smrg if (str - start >= 199) { 1671362b94d5Smrg Syntax("Action procedure name is longer than 199 chars", ""); 1672362b94d5Smrg *error = TRUE; 1673362b94d5Smrg return str; 1674362b94d5Smrg } 1675362b94d5Smrg (void) memmove(procName, start, (size_t) (str - start)); 1676362b94d5Smrg procName[str - start] = '\0'; 1677362b94d5Smrg *actionProcNameP = XrmStringToQuark(procName); 1678444c061aSmrg return str; 1679444c061aSmrg} 1680444c061aSmrg 1681362b94d5Smrgstatic String 1682362b94d5SmrgParseString(register String str, _XtString *strP) 1683444c061aSmrg{ 1684444c061aSmrg register String start; 1685444c061aSmrg 1686444c061aSmrg if (*str == '"') { 1687362b94d5Smrg register unsigned prev_len, len; 1688362b94d5Smrg 1689362b94d5Smrg str++; 1690362b94d5Smrg start = str; 1691362b94d5Smrg *strP = NULL; 1692362b94d5Smrg prev_len = 0; 1693362b94d5Smrg 1694362b94d5Smrg while (*str != '"' && *str != '\0') { 1695362b94d5Smrg /* \" produces double quote embedded in a quoted parameter 1696362b94d5Smrg * \\" produces backslash as last character of a quoted parameter 1697362b94d5Smrg */ 1698362b94d5Smrg if (*str == '\\' && 1699362b94d5Smrg (*(str + 1) == '"' || 1700362b94d5Smrg (*(str + 1) == '\\' && *(str + 2) == '"'))) { 1701362b94d5Smrg len = (unsigned) (prev_len + (str - start + 2)); 1702362b94d5Smrg *strP = XtRealloc(*strP, len); 1703362b94d5Smrg (void) memmove(*strP + prev_len, start, (size_t) (str - start)); 1704362b94d5Smrg prev_len = len - 1; 1705362b94d5Smrg str++; 1706362b94d5Smrg (*strP)[prev_len - 1] = *str; 1707362b94d5Smrg (*strP)[prev_len] = '\0'; 1708362b94d5Smrg start = str + 1; 1709362b94d5Smrg } 1710362b94d5Smrg str++; 1711362b94d5Smrg } 1712362b94d5Smrg len = (unsigned) (prev_len + (str - start + 1)); 1713362b94d5Smrg *strP = XtRealloc(*strP, len); 1714362b94d5Smrg (void) memmove(*strP + prev_len, start, (size_t) (str - start)); 1715362b94d5Smrg (*strP)[len - 1] = '\0'; 1716362b94d5Smrg if (*str == '"') 1717362b94d5Smrg str++; 1718362b94d5Smrg else 1719362b94d5Smrg XtWarningMsg(XtNtranslationParseError, "parseString", 1720362b94d5Smrg XtCXtToolkitError, "Missing '\"'.", 1721362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 1722362b94d5Smrg } 1723362b94d5Smrg else { 1724362b94d5Smrg /* scan non-quoted string, stop on whitespace, ',' or ')' */ 1725362b94d5Smrg start = str; 1726362b94d5Smrg while (*str != ' ' 1727362b94d5Smrg && *str != '\t' && *str != ',' && *str != ')' && !IsNewline(*str) 1728362b94d5Smrg && *str != '\0') 1729362b94d5Smrg str++; 1730362b94d5Smrg *strP = __XtMalloc((unsigned) (str - start + 1)); 1731362b94d5Smrg (void) memmove(*strP, start, (size_t) (str - start)); 1732362b94d5Smrg (*strP)[str - start] = '\0'; 1733444c061aSmrg } 1734444c061aSmrg return str; 1735444c061aSmrg} 1736444c061aSmrg 1737362b94d5Smrgstatic String 1738362b94d5SmrgParseParamSeq(register String str, String **paramSeqP, Cardinal *paramNumP) 1739444c061aSmrg{ 1740444c061aSmrg typedef struct _ParamRec *ParamPtr; 1741444c061aSmrg typedef struct _ParamRec { 1742362b94d5Smrg ParamPtr next; 1743362b94d5Smrg String param; 1744444c061aSmrg } ParamRec; 1745444c061aSmrg 1746444c061aSmrg ParamPtr params = NULL; 174772af6995Smrg Cardinal num_params = 0; 1748444c061aSmrg 1749444c061aSmrg ScanWhitespace(str); 1750444c061aSmrg while (*str != ')' && *str != '\0' && !IsNewline(*str)) { 1751362b94d5Smrg _XtString newStr; 1752362b94d5Smrg 1753362b94d5Smrg str = ParseString(str, &newStr); 1754362b94d5Smrg if (newStr != NULL) { 1755362b94d5Smrg ParamPtr temp = (ParamRec *) 1756362b94d5Smrg ALLOCATE_LOCAL((unsigned) sizeof(ParamRec)); 1757362b94d5Smrg 1758362b94d5Smrg if (temp == NULL) 1759362b94d5Smrg _XtAllocError(NULL); 1760362b94d5Smrg 1761362b94d5Smrg num_params++; 1762362b94d5Smrg temp->next = params; 1763362b94d5Smrg params = temp; 1764362b94d5Smrg temp->param = newStr; 1765362b94d5Smrg ScanWhitespace(str); 1766362b94d5Smrg if (*str == ',') { 1767362b94d5Smrg str++; 1768362b94d5Smrg ScanWhitespace(str); 1769362b94d5Smrg } 1770362b94d5Smrg } 1771444c061aSmrg } 1772444c061aSmrg 1773444c061aSmrg if (num_params != 0) { 1774362b94d5Smrg String *paramP = (String *) 1775362b94d5Smrg __XtMalloc((Cardinal) ((num_params + 1) * sizeof(String))); 1776362b94d5Smrg Cardinal i; 1777362b94d5Smrg 1778362b94d5Smrg *paramSeqP = paramP; 1779362b94d5Smrg *paramNumP = num_params; 1780362b94d5Smrg paramP += num_params; /* list is LIFO right now */ 1781362b94d5Smrg *paramP-- = NULL; 1782362b94d5Smrg for (i = 0; i < num_params; i++) { 1783362b94d5Smrg ParamPtr next = params->next; 1784362b94d5Smrg 1785362b94d5Smrg *paramP-- = params->param; 1786362b94d5Smrg DEALLOCATE_LOCAL((char *) params); 1787362b94d5Smrg params = next; 1788362b94d5Smrg } 1789362b94d5Smrg } 1790362b94d5Smrg else { 1791362b94d5Smrg *paramSeqP = NULL; 1792362b94d5Smrg *paramNumP = 0; 1793444c061aSmrg } 1794444c061aSmrg 1795444c061aSmrg return str; 1796444c061aSmrg} 1797444c061aSmrg 1798362b94d5Smrgstatic String 1799362b94d5SmrgParseAction(String str, ActionPtr actionP, XrmQuark *quarkP, Boolean *error) 1800444c061aSmrg{ 1801444c061aSmrg str = ParseActionProc(str, quarkP, error); 1802362b94d5Smrg if (*error) 1803362b94d5Smrg return str; 1804444c061aSmrg 1805444c061aSmrg if (*str == '(') { 1806362b94d5Smrg str++; 1807362b94d5Smrg str = ParseParamSeq(str, &actionP->params, &actionP->num_params); 1808362b94d5Smrg } 1809362b94d5Smrg else { 1810362b94d5Smrg Syntax("Missing '(' while parsing action sequence", ""); 1811444c061aSmrg *error = TRUE; 1812444c061aSmrg return str; 1813444c061aSmrg } 1814362b94d5Smrg if (*str == ')') 1815362b94d5Smrg str++; 1816362b94d5Smrg else { 1817362b94d5Smrg Syntax("Missing ')' while parsing action sequence", ""); 1818444c061aSmrg *error = TRUE; 1819444c061aSmrg return str; 1820444c061aSmrg } 1821444c061aSmrg return str; 1822444c061aSmrg} 1823444c061aSmrg 1824362b94d5Smrgstatic String 1825362b94d5SmrgParseActionSeq(TMParseStateTree parseTree, 1826362b94d5Smrg String str, 1827362b94d5Smrg ActionPtr *actionsP, 1828362b94d5Smrg Boolean *error) 1829444c061aSmrg{ 183072af6995Smrg ActionPtr *nextActionP; 183172af6995Smrg 183272af6995Smrg if ((nextActionP = actionsP) != NULL) 1833362b94d5Smrg *actionsP = NULL; 1834444c061aSmrg 1835444c061aSmrg while (*str != '\0' && !IsNewline(*str)) { 1836362b94d5Smrg register ActionPtr action; 1837362b94d5Smrg XrmQuark quark = NULLQUARK; 1838444c061aSmrg 1839362b94d5Smrg action = XtNew(ActionRec); 1840444c061aSmrg action->params = NULL; 1841444c061aSmrg action->num_params = 0; 1842444c061aSmrg action->next = NULL; 1843444c061aSmrg 1844362b94d5Smrg str = ParseAction(str, action, &quark, error); 1845362b94d5Smrg if (*error) { 1846362b94d5Smrg XtFree((char *) action); 1847362b94d5Smrg return PanicModeRecovery(str); 1848362b94d5Smrg } 1849444c061aSmrg 1850362b94d5Smrg action->idx = _XtGetQuarkIndex(parseTree, quark); 1851362b94d5Smrg ScanWhitespace(str); 1852362b94d5Smrg if (nextActionP) { 1853362b94d5Smrg *nextActionP = action; 1854362b94d5Smrg nextActionP = &action->next; 1855362b94d5Smrg } 1856444c061aSmrg } 1857362b94d5Smrg if (IsNewline(*str)) 1858362b94d5Smrg str++; 1859444c061aSmrg ScanWhitespace(str); 1860444c061aSmrg return str; 1861444c061aSmrg} 1862444c061aSmrg 1863362b94d5Smrgstatic void 1864362b94d5SmrgShowProduction(String currentProduction) 1865444c061aSmrg{ 1866444c061aSmrg Cardinal num_params = 1; 1867444c061aSmrg String params[1]; 1868444c061aSmrg size_t len; 1869444c061aSmrg char *eol, *production, productionbuf[500]; 1870444c061aSmrg 18718584976cSmrg eol = strchr(currentProduction, '\n'); 1872362b94d5Smrg if (eol) 1873362b94d5Smrg len = (size_t) (eol - currentProduction); 1874362b94d5Smrg else 1875362b94d5Smrg len = strlen(currentProduction); 1876362b94d5Smrg production = XtStackAlloc(len + 1, productionbuf); 1877362b94d5Smrg if (production == NULL) 1878362b94d5Smrg _XtAllocError(NULL); 1879444c061aSmrg (void) memmove(production, currentProduction, len); 1880444c061aSmrg production[len] = '\0'; 1881444c061aSmrg 1882444c061aSmrg params[0] = production; 1883444c061aSmrg XtWarningMsg(XtNtranslationParseError, "showLine", XtCXtToolkitError, 1884362b94d5Smrg "... found while parsing '%s'", params, &num_params); 1885444c061aSmrg 1886362b94d5Smrg XtStackFree(production, productionbuf); 1887444c061aSmrg} 1888444c061aSmrg 1889444c061aSmrg/*********************************************************************** 1890444c061aSmrg * ParseTranslationTableProduction 1891444c061aSmrg * Parses one line of event bindings. 1892444c061aSmrg ***********************************************************************/ 1893444c061aSmrg 1894362b94d5Smrgstatic String 1895362b94d5SmrgParseTranslationTableProduction(TMParseStateTree parseTree, 1896362b94d5Smrg register String str, 1897362b94d5Smrg Boolean *error) 1898444c061aSmrg{ 1899362b94d5Smrg EventSeqPtr eventSeq = NULL; 1900362b94d5Smrg ActionPtr *actionsP; 1901362b94d5Smrg String production = str; 1902444c061aSmrg 19032265a131Smrg actionsP = NULL; 190472af6995Smrg str = ParseEventSeq(str, &eventSeq, &actionsP, error); 1905444c061aSmrg if (*error == TRUE) { 1906362b94d5Smrg ShowProduction(production); 1907362b94d5Smrg } 1908362b94d5Smrg else { 1909362b94d5Smrg ScanWhitespace(str); 1910362b94d5Smrg str = ParseActionSeq(parseTree, str, actionsP, error); 1911362b94d5Smrg if (*error == TRUE) { 1912362b94d5Smrg ShowProduction(production); 1913362b94d5Smrg } 1914362b94d5Smrg else { 1915362b94d5Smrg _XtAddEventSeqToStateTree(eventSeq, parseTree); 1916362b94d5Smrg } 1917444c061aSmrg } 1918444c061aSmrg FreeEventSeq(eventSeq); 1919444c061aSmrg return (str); 1920444c061aSmrg} 1921444c061aSmrg 1922362b94d5Smrgstatic String 1923362b94d5SmrgCheckForPoundSign(String str, 1924362b94d5Smrg _XtTranslateOp defaultOp, 1925362b94d5Smrg _XtTranslateOp *actualOpRtn) 1926444c061aSmrg{ 1927444c061aSmrg _XtTranslateOp opType; 1928444c061aSmrg 1929444c061aSmrg opType = defaultOp; 1930444c061aSmrg ScanWhitespace(str); 193172af6995Smrg 1932444c061aSmrg if (*str == '#') { 1933362b94d5Smrg String start; 1934362b94d5Smrg char operation[20]; 1935362b94d5Smrg int len; 1936362b94d5Smrg 1937362b94d5Smrg str++; 1938362b94d5Smrg start = str; 1939362b94d5Smrg str = ScanIdent(str); 1940362b94d5Smrg len = MIN(19, (int) (str - start)); 1941362b94d5Smrg (void) memmove(operation, start, (size_t) len); 1942362b94d5Smrg operation[len] = '\0'; 1943362b94d5Smrg if (!strcmp(operation, "replace")) 1944362b94d5Smrg opType = XtTableReplace; 1945362b94d5Smrg else if (!strcmp(operation, "augment")) 1946362b94d5Smrg opType = XtTableAugment; 1947362b94d5Smrg else if (!strcmp(operation, "override")) 1948362b94d5Smrg opType = XtTableOverride; 1949362b94d5Smrg ScanWhitespace(str); 1950362b94d5Smrg if (IsNewline(*str)) { 1951362b94d5Smrg str++; 1952362b94d5Smrg ScanWhitespace(str); 1953362b94d5Smrg } 1954444c061aSmrg } 1955444c061aSmrg *actualOpRtn = opType; 1956444c061aSmrg return str; 1957444c061aSmrg} 1958444c061aSmrg 1959362b94d5Smrgstatic XtTranslations 1960362b94d5SmrgParseTranslationTable(String source, 1961362b94d5Smrg Boolean isAccelerator, 1962362b94d5Smrg _XtTranslateOp defaultOp, 1963362b94d5Smrg Boolean *error) 1964444c061aSmrg{ 1965362b94d5Smrg XtTranslations xlations; 1966362b94d5Smrg TMStateTree stateTrees[8]; 1967362b94d5Smrg TMParseStateTreeRec parseTreeRec, *parseTree = &parseTreeRec; 1968362b94d5Smrg XrmQuark stackQuarks[200]; 1969362b94d5Smrg TMBranchHeadRec stackBranchHeads[200]; 1970362b94d5Smrg StatePtr stackComplexBranchHeads[200]; 1971362b94d5Smrg _XtTranslateOp actualOp; 1972444c061aSmrg 1973444c061aSmrg if (source == NULL) 1974362b94d5Smrg return (XtTranslations) NULL; 1975444c061aSmrg 1976444c061aSmrg source = CheckForPoundSign(source, defaultOp, &actualOp); 1977444c061aSmrg if (isAccelerator && actualOp == XtTableReplace) 1978362b94d5Smrg actualOp = defaultOp; 1979444c061aSmrg 1980444c061aSmrg parseTree->isSimple = TRUE; 1981444c061aSmrg parseTree->mappingNotifyInterest = FALSE; 198272af6995Smrg XtSetBit(parseTree->isAccelerator, isAccelerator); 1983444c061aSmrg parseTree->isStackBranchHeads = 1984362b94d5Smrg parseTree->isStackQuarks = parseTree->isStackComplexBranchHeads = TRUE; 1985444c061aSmrg 1986444c061aSmrg parseTree->numQuarks = 1987362b94d5Smrg parseTree->numBranchHeads = parseTree->numComplexBranchHeads = 0; 1988444c061aSmrg 1989444c061aSmrg parseTree->quarkTblSize = 1990362b94d5Smrg parseTree->branchHeadTblSize = 1991362b94d5Smrg parseTree->complexBranchHeadTblSize = 200; 1992444c061aSmrg 1993444c061aSmrg parseTree->quarkTbl = stackQuarks; 1994444c061aSmrg parseTree->branchHeadTbl = stackBranchHeads; 1995444c061aSmrg parseTree->complexBranchHeadTbl = stackComplexBranchHeads; 1996444c061aSmrg 1997444c061aSmrg while (source != NULL && *source != '\0') { 1998362b94d5Smrg source = ParseTranslationTableProduction(parseTree, source, error); 1999362b94d5Smrg if (*error == TRUE) 2000362b94d5Smrg break; 2001444c061aSmrg } 2002444c061aSmrg stateTrees[0] = _XtParseTreeToStateTree(parseTree); 2003444c061aSmrg 2004444c061aSmrg if (!parseTree->isStackQuarks) 2005362b94d5Smrg XtFree((char *) parseTree->quarkTbl); 2006444c061aSmrg if (!parseTree->isStackBranchHeads) 2007362b94d5Smrg XtFree((char *) parseTree->branchHeadTbl); 2008444c061aSmrg if (!parseTree->isStackComplexBranchHeads) 2009362b94d5Smrg XtFree((char *) parseTree->complexBranchHeadTbl); 2010444c061aSmrg 2011444c061aSmrg xlations = _XtCreateXlations(stateTrees, 1, NULL, NULL); 201272af6995Smrg xlations->operation = (unsigned char) actualOp; 2013444c061aSmrg 2014444c061aSmrg#ifdef notdef 2015444c061aSmrg XtFree(stateTrees); 2016362b94d5Smrg#endif /* notdef */ 2017444c061aSmrg return xlations; 2018444c061aSmrg} 2019444c061aSmrg 2020444c061aSmrg/*** public procedures ***/ 2021444c061aSmrg 2022362b94d5SmrgBoolean 2023362b94d5SmrgXtCvtStringToAcceleratorTable(Display *dpy, 2024362b94d5Smrg XrmValuePtr args _X_UNUSED, 2025362b94d5Smrg Cardinal *num_args, 2026362b94d5Smrg XrmValuePtr from, 2027362b94d5Smrg XrmValuePtr to, 2028362b94d5Smrg XtPointer *closure _X_UNUSED) 2029444c061aSmrg{ 2030444c061aSmrg String str; 2031444c061aSmrg Boolean error = FALSE; 2032444c061aSmrg 2033444c061aSmrg if (*num_args != 0) 2034444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2035362b94d5Smrg "wrongParameters", "cvtStringToAcceleratorTable", 2036362b94d5Smrg XtCXtToolkitError, 2037362b94d5Smrg "String to AcceleratorTable conversion needs no extra arguments", 2038362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2039362b94d5Smrg str = (String) (from->addr); 2040444c061aSmrg if (str == NULL) { 2041444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2042362b94d5Smrg "badParameters", "cvtStringToAcceleratorTable", 2043362b94d5Smrg XtCXtToolkitError, 2044362b94d5Smrg "String to AcceleratorTable conversion needs string", 2045362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2046362b94d5Smrg return FALSE; 2047444c061aSmrg } 2048444c061aSmrg if (to->addr != NULL) { 2049362b94d5Smrg if (to->size < sizeof(XtAccelerators)) { 2050362b94d5Smrg to->size = sizeof(XtAccelerators); 2051362b94d5Smrg return FALSE; 2052362b94d5Smrg } 2053362b94d5Smrg *(XtAccelerators *) to->addr = 2054362b94d5Smrg (XtAccelerators) ParseTranslationTable(str, TRUE, XtTableAugment, 2055362b94d5Smrg &error); 2056444c061aSmrg } 2057444c061aSmrg else { 2058362b94d5Smrg static XtAccelerators staticStateTable; 2059362b94d5Smrg 2060362b94d5Smrg staticStateTable = 2061362b94d5Smrg (XtAccelerators) ParseTranslationTable(str, TRUE, XtTableAugment, 2062362b94d5Smrg &error); 2063362b94d5Smrg to->addr = (XPointer) &staticStateTable; 2064362b94d5Smrg to->size = sizeof(XtAccelerators); 2065444c061aSmrg } 2066444c061aSmrg if (error == TRUE) 2067444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2068362b94d5Smrg "parseError", "cvtStringToAcceleratorTable", 2069362b94d5Smrg XtCXtToolkitError, 2070362b94d5Smrg "String to AcceleratorTable conversion encountered errors", 2071362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2072444c061aSmrg return (error != TRUE); 2073444c061aSmrg} 2074444c061aSmrg 2075444c061aSmrgBoolean 2076362b94d5SmrgXtCvtStringToTranslationTable(Display *dpy, 2077362b94d5Smrg XrmValuePtr args _X_UNUSED, 2078362b94d5Smrg Cardinal *num_args, 2079362b94d5Smrg XrmValuePtr from, 2080362b94d5Smrg XrmValuePtr to, 2081362b94d5Smrg XtPointer *closure_ret _X_UNUSED) 2082444c061aSmrg{ 2083444c061aSmrg String str; 2084444c061aSmrg Boolean error = FALSE; 2085444c061aSmrg 2086444c061aSmrg if (*num_args != 0) 2087362b94d5Smrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2088362b94d5Smrg "wrongParameters", "cvtStringToTranslationTable", 2089362b94d5Smrg XtCXtToolkitError, 2090362b94d5Smrg "String to TranslationTable conversion needs no extra arguments", 2091362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2092362b94d5Smrg str = (String) (from->addr); 2093444c061aSmrg if (str == NULL) { 2094444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2095362b94d5Smrg "badParameters", "cvtStringToTranslation", 2096362b94d5Smrg XtCXtToolkitError, 2097362b94d5Smrg "String to TranslationTable conversion needs string", 2098362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2099362b94d5Smrg return FALSE; 2100444c061aSmrg } 2101444c061aSmrg if (to->addr != NULL) { 2102362b94d5Smrg if (to->size < sizeof(XtTranslations)) { 2103362b94d5Smrg to->size = sizeof(XtTranslations); 2104362b94d5Smrg return FALSE; 2105362b94d5Smrg } 2106362b94d5Smrg *(XtTranslations *) to->addr = 2107362b94d5Smrg ParseTranslationTable(str, FALSE, XtTableReplace, &error); 2108444c061aSmrg } 2109444c061aSmrg else { 2110362b94d5Smrg static XtTranslations staticStateTable; 2111362b94d5Smrg 2112362b94d5Smrg staticStateTable = 2113362b94d5Smrg ParseTranslationTable(str, FALSE, XtTableReplace, &error); 2114362b94d5Smrg to->addr = (XPointer) &staticStateTable; 2115362b94d5Smrg to->size = sizeof(XtTranslations); 2116444c061aSmrg } 2117444c061aSmrg if (error == TRUE) 2118444c061aSmrg XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 2119362b94d5Smrg "parseError", "cvtStringToTranslationTable", 2120362b94d5Smrg XtCXtToolkitError, 2121362b94d5Smrg "String to TranslationTable conversion encountered errors", 2122362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2123444c061aSmrg return (error != TRUE); 2124444c061aSmrg} 2125444c061aSmrg 2126444c061aSmrg/* 2127444c061aSmrg * Parses a user's or applications translation table 2128444c061aSmrg */ 2129362b94d5SmrgXtAccelerators 2130362b94d5SmrgXtParseAcceleratorTable(_Xconst char *source) 2131444c061aSmrg{ 2132444c061aSmrg Boolean error = FALSE; 2133444c061aSmrg XtAccelerators ret = 2134362b94d5Smrg (XtAccelerators) ParseTranslationTable(source, TRUE, XtTableAugment, 2135362b94d5Smrg &error); 2136362b94d5Smrg 2137444c061aSmrg if (error == TRUE) 2138362b94d5Smrg XtWarningMsg("parseError", "cvtStringToAcceleratorTable", 2139362b94d5Smrg XtCXtToolkitError, 2140362b94d5Smrg "String to AcceleratorTable conversion encountered errors", 2141362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2142444c061aSmrg return ret; 2143444c061aSmrg} 2144444c061aSmrg 2145362b94d5SmrgXtTranslations 2146362b94d5SmrgXtParseTranslationTable(_Xconst char *source) 2147444c061aSmrg{ 2148444c061aSmrg Boolean error = FALSE; 2149362b94d5Smrg XtTranslations ret = 2150362b94d5Smrg ParseTranslationTable(source, FALSE, XtTableReplace, &error); 2151444c061aSmrg if (error == TRUE) 2152362b94d5Smrg XtWarningMsg("parseError", 2153362b94d5Smrg "cvtStringToTranslationTable", XtCXtToolkitError, 2154362b94d5Smrg "String to TranslationTable conversion encountered errors", 2155362b94d5Smrg (String *) NULL, (Cardinal *) NULL); 2156444c061aSmrg return ret; 2157444c061aSmrg} 2158444c061aSmrg 2159362b94d5Smrgvoid 2160362b94d5Smrg_XtTranslateInitialize(void) 2161444c061aSmrg{ 2162444c061aSmrg LOCK_PROCESS; 2163444c061aSmrg if (initialized) { 2164362b94d5Smrg XtWarningMsg("translationError", "xtTranslateInitialize", 2165362b94d5Smrg XtCXtToolkitError, 2166362b94d5Smrg "Initializing Translation manager twice.", (String *) NULL, 2167362b94d5Smrg (Cardinal *) NULL); 2168362b94d5Smrg UNLOCK_PROCESS; 2169362b94d5Smrg return; 2170444c061aSmrg } 2171444c061aSmrg 2172444c061aSmrg initialized = TRUE; 2173444c061aSmrg UNLOCK_PROCESS; 2174444c061aSmrg QMeta = XrmPermStringToQuark("Meta"); 2175444c061aSmrg QCtrl = XrmPermStringToQuark("Ctrl"); 2176444c061aSmrg QNone = XrmPermStringToQuark("None"); 2177362b94d5Smrg QAny = XrmPermStringToQuark("Any"); 2178444c061aSmrg 2179362b94d5Smrg Compile_XtEventTable(events, XtNumber(events)); 2180362b94d5Smrg Compile_XtModifierTable(modifiers, XtNumber(modifiers)); 2181362b94d5Smrg CompileNameValueTable(buttonNames); 2182362b94d5Smrg CompileNameValueTable(notifyModes); 2183362b94d5Smrg CompileNameValueTable(motionDetails); 2184444c061aSmrg#if 0 2185362b94d5Smrg CompileNameValueTable(notifyDetail); 2186362b94d5Smrg CompileNameValueTable(visibilityNotify); 2187362b94d5Smrg CompileNameValueTable(circulation); 2188362b94d5Smrg CompileNameValueTable(propertyChanged); 2189444c061aSmrg#endif 2190362b94d5Smrg CompileNameValueTable(mappingNotify); 2191444c061aSmrg} 2192444c061aSmrg 2193362b94d5Smrgvoid 2194362b94d5Smrg_XtAddTMConverters(ConverterTable table) 2195444c061aSmrg{ 2196362b94d5Smrg _XtTableAddConverter(table, 2197362b94d5Smrg _XtQString, 2198362b94d5Smrg XrmPermStringToQuark(XtRTranslationTable), 2199362b94d5Smrg XtCvtStringToTranslationTable, (XtConvertArgList) NULL, 2200362b94d5Smrg (Cardinal) 0, True, CACHED, _XtFreeTranslations, True); 2201362b94d5Smrg _XtTableAddConverter(table, _XtQString, 2202362b94d5Smrg XrmPermStringToQuark(XtRAcceleratorTable), 2203362b94d5Smrg XtCvtStringToAcceleratorTable, (XtConvertArgList) NULL, 2204362b94d5Smrg (Cardinal) 0, True, CACHED, _XtFreeTranslations, True); 2205362b94d5Smrg _XtTableAddConverter(table, 2206362b94d5Smrg XrmPermStringToQuark(_XtRStateTablePair), 2207362b94d5Smrg XrmPermStringToQuark(XtRTranslationTable), 2208362b94d5Smrg _XtCvtMergeTranslations, (XtConvertArgList) NULL, 2209362b94d5Smrg (Cardinal) 0, True, CACHED, _XtFreeTranslations, True); 2210444c061aSmrg} 2211