1/************************************************************ 2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25 ********************************************************/ 26 27#include "xkbevd.h" 28 29/***====================================================================***/ 30 31static char * 32AppendBellNotifyArg(char *sink, const char *arg, const XkbEvent *ev) 33{ 34 if (uStringEqual(arg, "device") || uStringEqual(arg, "D")) 35 sprintf(sink, "%d", ev->bell.device); 36 else if (uStringEqual(arg, "volume") || uStringEqual(arg, "v")) 37 sprintf(sink, "%d", ev->bell.percent); 38 else if (uStringEqual(arg, "pitch") || uStringEqual(arg, "p")) 39 sprintf(sink, "%d", ev->bell.pitch); 40 else if (uStringEqual(arg, "duration") || uStringEqual(arg, "d")) 41 sprintf(sink, "%d", ev->bell.duration); 42 else if (uStringEqual(arg, "class") || uStringEqual(arg, "c")) 43 sprintf(sink, "%d", ev->bell.bell_class); 44 else if (uStringEqual(arg, "id") || uStringEqual(arg, "i")) 45 sprintf(sink, "%d", ev->bell.bell_id); 46 else if (uStringEqual(arg, "window") || uStringEqual(arg, "w")) 47 sprintf(sink, "0x%x", (unsigned int) ev->bell.window); 48 else if (uStringEqual(arg, "name") || uStringEqual(arg, "n")) 49 sprintf(sink, "%s", XkbAtomText(dpy, ev->bell.name, XkbMessage)); 50 return sink; 51} 52 53static char * 54AppendAccessXNotifyArg(char *sink, const char *arg, const XkbEvent *ev) 55{ 56 if (uStringEqual(arg, "device") || uStringEqual(arg, "D")) 57 sprintf(sink, "%d", ev->accessx.device); 58 else if (uStringEqual(arg, "detail") || uStringEqual(arg, "d")) { 59 sprintf(sink, "%s", 60 XkbAccessXDetailText(ev->accessx.detail, XkbMessage)); 61 } 62 else if (uStringEqual(arg, "keycode") || uStringEqual(arg, "key") || 63 uStringEqual(arg, "k")) 64 sprintf(sink, "%d", ev->accessx.keycode); 65 else if (uStringEqual(arg, "skdelay") || uStringEqual(arg, "s")) 66 sprintf(sink, "%d", ev->accessx.sk_delay); 67 else if (uStringEqual(arg, "bkdelay") || uStringEqual(arg, "b")) 68 sprintf(sink, "%d", ev->accessx.debounce_delay); 69 return sink; 70} 71 72static char * 73AppendActionMessageArg(char *sink, const char *arg, const XkbEvent *ev) 74{ 75 if (uStringEqual(arg, "device") || uStringEqual(arg, "D")) 76 sprintf(sink, "%d", ev->message.device); 77 else if (uStringEqual(arg, "message") || uStringEqual(arg, "m")) 78 sprintf(sink, "%s", ev->message.message); 79 else if (uStringEqual(arg, "keycode") || uStringEqual(arg, "key") || 80 uStringEqual(arg, "k")) 81 sprintf(sink, "%d", ev->message.keycode); 82 else if (uStringEqual(arg, "press") || uStringEqual(arg, "p")) 83 sprintf(sink, "%s", (ev->message.press ? "press" : "release")); 84 else if (uStringEqual(arg, "event") || uStringEqual(arg, "e")) 85 sprintf(sink, "%s", 86 (ev->message.key_event_follows ? "event" : "no_event")); 87 return sink; 88} 89 90static char * 91AppendEventArg(char *sink, const char *arg, const XkbEvent *ev) 92{ 93 switch (ev->any.xkb_type) { 94 case XkbBellNotify: 95 sink = AppendBellNotifyArg(sink, arg, ev); 96 break; 97 case XkbAccessXNotify: 98 sink = AppendAccessXNotifyArg(sink, arg, ev); 99 break; 100 case XkbActionMessage: 101 sink = AppendActionMessageArg(sink, arg, ev); 102 break; 103 default: 104 return sink; 105 } 106 sink += strlen(sink); 107 return sink; 108} 109 110static void 111CopyEventArg(char **sink_inout, const char **source_inout, const XkbEvent *ev) 112{ 113 char buf[1024]; 114 const char *source; 115 char *sink; 116 char *arg; 117 118 arg = buf; 119 source = *source_inout; 120 sink = *sink_inout; 121 if (*source == '$') { 122 *sink++ = '$'; 123 source++; 124 *sink++ = '\0'; 125 *sink_inout = sink; 126 *source_inout = source; 127 return; 128 } 129 else if (*source == '(') { 130 source++; 131 while ((*source != ')') && (*source != '\0')) { 132 *arg++ = *source++; 133 } 134 if (*source == '\0') { 135 *sink++ = '$'; 136 *sink++ = '\0'; 137 *sink_inout = sink; 138 return; 139 } 140 source++; 141 *arg++ = '\0'; 142 arg = buf; 143 } 144 else { 145 arg[0] = *source++; 146 arg[1] = '\0'; 147 } 148 sink = AppendEventArg(sink, arg, ev); 149 *sink_inout = sink; 150 *source_inout = source; 151 return; 152} 153 154const char * 155SubstituteEventArgs(const char *cmd, const XkbEvent *ev) 156{ 157 static char buf[1024]; 158 const char *source; 159 char *sink; 160 161 if (strchr(cmd, '$') == NULL) 162 return cmd; 163 buf[0] = '\0'; 164 sink = buf; 165 source = cmd; 166 while (*source != '\0') { 167 if (*source == '$') { 168 source++; 169 CopyEventArg(&sink, &source, ev); 170 } 171 *sink++ = *source++; 172 } 173 return buf; 174} 175