File: | TMaction.c |
Location: | line 162, column 23 |
Description: | Value stored to 'stateTree' during its initialization is never read |
1 | /*LINTLIBRARY*/ |
2 | |
3 | /*********************************************************** |
4 | Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. |
5 | |
6 | Permission is hereby granted, free of charge, to any person obtaining a |
7 | copy of this software and associated documentation files (the "Software"), |
8 | to deal in the Software without restriction, including without limitation |
9 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
10 | and/or sell copies of the Software, and to permit persons to whom the |
11 | Software is furnished to do so, subject to the following conditions: |
12 | |
13 | The above copyright notice and this permission notice (including the next |
14 | paragraph) shall be included in all copies or substantial portions of the |
15 | Software. |
16 | |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | DEALINGS IN THE SOFTWARE. |
24 | |
25 | Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. |
26 | |
27 | All Rights Reserved |
28 | |
29 | Permission to use, copy, modify, and distribute this software and its |
30 | documentation for any purpose and without fee is hereby granted, |
31 | provided that the above copyright notice appear in all copies and that |
32 | both that copyright notice and this permission notice appear in |
33 | supporting documentation, and that the name of Digital not be |
34 | used in advertising or publicity pertaining to distribution of the |
35 | software without specific, written prior permission. |
36 | |
37 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
38 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
39 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
40 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
41 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
42 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
43 | SOFTWARE. |
44 | |
45 | ******************************************************************/ |
46 | |
47 | /* |
48 | |
49 | Copyright 1987, 1988, 1998 The Open Group |
50 | |
51 | Permission to use, copy, modify, distribute, and sell this software and its |
52 | documentation for any purpose is hereby granted without fee, provided that |
53 | the above copyright notice appear in all copies and that both that |
54 | copyright notice and this permission notice appear in supporting |
55 | documentation. |
56 | |
57 | The above copyright notice and this permission notice shall be included in |
58 | all copies or substantial portions of the Software. |
59 | |
60 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
61 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
62 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
63 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
64 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
65 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
66 | |
67 | Except as contained in this notice, the name of The Open Group shall not be |
68 | used in advertising or otherwise to promote the sale, use or other dealings |
69 | in this Software without prior written authorization from The Open Group. |
70 | |
71 | */ |
72 | |
73 | /* TMaction.c -- maintains the state table of actions for the translation |
74 | * manager. |
75 | */ |
76 | |
77 | #ifdef HAVE_CONFIG_H1 |
78 | #include <config.h> |
79 | #endif |
80 | #include "IntrinsicI.h" |
81 | #include "StringDefs.h" |
82 | |
83 | #if defined(__STDC__1) && !defined(NORCONST) |
84 | #define RConstconst const |
85 | #else |
86 | #define RConstconst /**/ |
87 | #endif |
88 | |
89 | static String XtNtranslationError = "translationError"; |
90 | |
91 | typedef struct _CompiledAction{ |
92 | XrmQuark signature; |
93 | XtActionProc proc; |
94 | }CompiledAction, *CompiledActionTable; |
95 | |
96 | |
97 | #define GetClassActions(wc)((wc->core_class.actions) ? (((TMClassCache)wc->core_class .actions)->actions) : ((void*)0)) \ |
98 | ((wc->core_class.actions) \ |
99 | ? (((TMClassCache)wc->core_class.actions)->actions) \ |
100 | : NULL((void*)0)) |
101 | |
102 | static CompiledActionTable CompileActionTable( |
103 | register RConstconst struct _XtActionsRec *actions, |
104 | register Cardinal count, /* may be 0 */ |
105 | Boolean stat, /* if False, copy before compiling in place */ |
106 | Boolean perm) /* if False, use XrmStringToQuark */ |
107 | { |
108 | register CompiledActionTable cActions; |
109 | register int i; |
110 | CompiledAction hold; |
111 | CompiledActionTable cTableHold; |
112 | XrmQuark (*func)(_Xconstconst char*); |
113 | |
114 | if (!count) |
115 | return (CompiledActionTable) NULL((void*)0); |
116 | func = (perm ? XrmPermStringToQuark : XrmStringToQuark); |
117 | |
118 | if (! stat) { |
119 | cTableHold = cActions = (CompiledActionTable) |
120 | __XtMalloc(count * sizeof(CompiledAction)); |
121 | |
122 | for (i=count; --i >= 0; cActions++, actions++) { |
123 | cActions->proc = actions->proc; |
124 | cActions->signature = (*func)(actions->string); |
125 | } |
126 | } else { |
127 | cTableHold = (CompiledActionTable) actions; |
128 | |
129 | for (i=count; --i >= 0; actions++) |
130 | ((CompiledActionTable) actions)->signature = |
131 | (*func)(actions->string); |
132 | } |
133 | cActions = cTableHold; |
134 | |
135 | /* Insertion sort. Whatever sort is used, it must be stable. */ |
136 | for (i=1; (Cardinal) i <= count - 1; i++) { |
137 | register Cardinal j; |
138 | hold = cActions[i]; |
139 | j = i; |
140 | while (j && cActions[j-1].signature > hold.signature) { |
141 | cActions[j] = cActions[j-1]; |
142 | j--; |
143 | } |
144 | cActions[j] = hold; |
145 | } |
146 | |
147 | return cActions; |
148 | } |
149 | |
150 | |
151 | typedef struct _ActionListRec *ActionList; |
152 | typedef struct _ActionListRec { |
153 | ActionList next; |
154 | CompiledActionTable table; |
155 | TMShortCard count; |
156 | } ActionListRec; |
157 | |
158 | static void ReportUnboundActions( |
159 | XtTranslations xlations, |
160 | TMBindData bindData) |
161 | { |
162 | TMSimpleStateTree stateTree = (TMSimpleStateTree)xlations->stateTreeTbl[0]; |
Value stored to 'stateTree' during its initialization is never read | |
163 | Cardinal num_unbound = 0; |
164 | Cardinal num_params = 1; |
165 | char* message; |
166 | char messagebuf[1000]; |
167 | String params[1]; |
168 | register Cardinal num_chars = 0; |
169 | register Cardinal i, j; |
170 | XtActionProc *procs; |
171 | |
172 | for (i=0; i < xlations->numStateTrees; i++) { |
173 | if (bindData->simple.isComplex) |
174 | procs = TMGetComplexBindEntry(bindData, i)((TMComplexBindProcs)&(((TMComplexBindData)bindData)-> bindTbl[i]))->procs; |
175 | else |
176 | procs = TMGetSimpleBindEntry(bindData, i)((TMSimpleBindProcs)&(((TMSimpleBindData)bindData)->bindTbl [i]))->procs; |
177 | |
178 | stateTree = (TMSimpleStateTree)xlations->stateTreeTbl[i]; |
179 | for (j=0; j < stateTree->numQuarks; j++) { |
180 | if (procs[j] == NULL((void*)0)) { |
181 | String s = XrmQuarkToString(stateTree->quarkTbl[j]); |
182 | if (num_unbound != 0) |
183 | num_chars += 2; |
184 | num_chars += strlen(s); |
185 | num_unbound++; |
186 | } |
187 | } |
188 | } |
189 | if (num_unbound == 0) |
190 | return; |
191 | message = XtStackAlloc (num_chars + 1, messagebuf)((num_chars + 1) <= sizeof(messagebuf) ? (XtPointer)(messagebuf ) : XtMalloc((unsigned)(num_chars + 1))); |
192 | if (message != NULL((void*)0)) { |
193 | *message = '\0'; |
194 | num_unbound = 0; |
195 | stateTree = (TMSimpleStateTree)xlations->stateTreeTbl[0]; |
196 | for (i=0; i < xlations->numStateTrees; i++) { |
197 | if (bindData->simple.isComplex) |
198 | procs = TMGetComplexBindEntry(bindData, i)((TMComplexBindProcs)&(((TMComplexBindData)bindData)-> bindTbl[i]))->procs; |
199 | else |
200 | procs = TMGetSimpleBindEntry(bindData, i)((TMSimpleBindProcs)&(((TMSimpleBindData)bindData)->bindTbl [i]))->procs; |
201 | |
202 | stateTree = (TMSimpleStateTree)xlations->stateTreeTbl[i]; |
203 | for (j=0; j < stateTree->numQuarks; j++) { |
204 | if (procs[j] == NULL((void*)0)) { |
205 | String s = XrmQuarkToString(stateTree->quarkTbl[j]); |
206 | if (num_unbound != 0) |
207 | (void) strcat(message, ", "); |
208 | (void) strcat(message, s); |
209 | num_unbound++; |
210 | } |
211 | } |
212 | } |
213 | message[num_chars] = '\0'; |
214 | params[0] = message; |
215 | XtWarningMsg(XtNtranslationError,"unboundActions",XtCXtToolkitError, |
216 | "Actions not found: %s", |
217 | params, &num_params); |
218 | XtStackFree (message, messagebuf){ if ((message) != ((XtPointer)(messagebuf))) XtFree(message) ; }; |
219 | } |
220 | } |
221 | |
222 | |
223 | static CompiledAction *SearchActionTable( |
224 | XrmQuark signature, |
225 | CompiledActionTable actionTable, |
226 | Cardinal numActions) |
227 | { |
228 | register int i, left, right; |
229 | |
230 | left = 0; |
231 | right = numActions - 1; |
232 | while (left <= right) { |
233 | i = (left + right) >> 1; |
234 | if (signature < actionTable[i].signature) |
235 | right = i - 1; |
236 | else if (signature > actionTable[i].signature) |
237 | left = i + 1; |
238 | else { |
239 | while (i && actionTable[i - 1].signature == signature) |
240 | i--; |
241 | return &actionTable[i]; |
242 | } |
243 | } |
244 | return (CompiledAction *) NULL((void*)0); |
245 | } |
246 | |
247 | static int BindActions( |
248 | TMSimpleStateTree stateTree, |
249 | XtActionProc *procs, |
250 | CompiledActionTable compiledActionTable, |
251 | TMShortCard numActions, |
252 | Cardinal *ndxP) |
253 | { |
254 | register int unbound = stateTree->numQuarks - *ndxP; |
255 | CompiledAction* action; |
256 | register Cardinal ndx; |
257 | register Boolean savedNdx = False0; |
258 | |
259 | for (ndx = *ndxP; ndx < stateTree->numQuarks; ndx++) { |
260 | if (procs[ndx] == NULL((void*)0)) { |
261 | /* attempt to bind it */ |
262 | XrmQuark q = stateTree->quarkTbl[ndx]; |
263 | |
264 | action = SearchActionTable(q, compiledActionTable, numActions); |
265 | if (action) { |
266 | procs[ndx] = action->proc; |
267 | unbound--; |
268 | } else if (!savedNdx) { |
269 | *ndxP= ndx; |
270 | savedNdx = True1; |
271 | } |
272 | } else { |
273 | /* already bound, leave it alone */ |
274 | unbound--; |
275 | } |
276 | } |
277 | return unbound; |
278 | } |
279 | |
280 | typedef struct _TMBindCacheStatusRec{ |
281 | unsigned int boundInClass:1; |
282 | unsigned int boundInHierarchy:1; |
283 | unsigned int boundInContext:1; |
284 | unsigned int notFullyBound:1; |
285 | unsigned int refCount:28; |
286 | }TMBindCacheStatusRec, *TMBindCacheStatus; |
287 | |
288 | typedef struct _TMBindCacheRec{ |
289 | struct _TMBindCacheRec *next; |
290 | TMBindCacheStatusRec status; |
291 | TMStateTree stateTree; |
292 | #ifdef TRACE_TM |
293 | WidgetClass widgetClass; |
294 | #endif /* TRACE_TM */ |
295 | XtActionProc procs[1]; /* variable length */ |
296 | }TMBindCacheRec, *TMBindCache; |
297 | |
298 | typedef struct _TMClassCacheRec { |
299 | CompiledActionTable actions; |
300 | TMBindCacheRec *bindCache; |
301 | }TMClassCacheRec, *TMClassCache; |
302 | |
303 | #define IsPureClassBind(bc)(bc->status.boundInClass && !(bc->status.boundInHierarchy || bc->status.boundInContext || bc->status.notFullyBound )) \ |
304 | (bc->status.boundInClass && \ |
305 | !(bc->status.boundInHierarchy || \ |
306 | bc->status.boundInContext || \ |
307 | bc->status.notFullyBound)) |
308 | |
309 | #define GetClassCache(w)((TMClassCache)w->core.widget_class->core_class.actions ) \ |
310 | ((TMClassCache)w->core.widget_class->core_class.actions) |
311 | |
312 | |
313 | static int BindProcs( |
314 | Widget widget, |
315 | TMSimpleStateTree stateTree, |
316 | XtActionProc *procs, |
317 | TMBindCacheStatus bindStatus) |
318 | { |
319 | register WidgetClass class; |
320 | register ActionList actionList; |
321 | int unbound = -1, newUnbound = -1; |
322 | Cardinal ndx = 0; |
323 | Widget w = widget; |
324 | |
325 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
326 | do { |
327 | class = w->core.widget_class; |
328 | do { |
329 | if (class->core_class.actions != NULL((void*)0)) |
330 | unbound = |
331 | BindActions(stateTree, |
332 | procs, |
333 | GetClassActions(class)((class->core_class.actions) ? (((TMClassCache)class->core_class .actions)->actions) : ((void*)0)), |
334 | class->core_class.num_actions, |
335 | &ndx); |
336 | class = class->core_class.superclass; |
337 | } while (unbound != 0 && class != NULL((void*)0)); |
338 | if (unbound < (int)stateTree->numQuarks) |
339 | bindStatus->boundInClass = True1; |
340 | else |
341 | bindStatus->boundInClass = False0; |
342 | if (newUnbound == -1) |
343 | newUnbound = unbound; |
344 | w = XtParent(w)((w)->core.parent); |
345 | } while (unbound != 0 && w != NULL((void*)0)); |
346 | |
347 | if (newUnbound > unbound) |
348 | bindStatus->boundInHierarchy = True1; |
349 | else |
350 | bindStatus->boundInHierarchy = False0; |
351 | |
352 | if (unbound) { |
353 | XtAppContext app = XtWidgetToApplicationContext(widget); |
354 | newUnbound = unbound; |
355 | for (actionList = app->action_table; |
356 | unbound != 0 && actionList != NULL((void*)0); |
357 | actionList = actionList->next) { |
358 | unbound = BindActions(stateTree, |
359 | procs, |
360 | actionList->table, |
361 | actionList->count, |
362 | &ndx); |
363 | } |
364 | if (newUnbound > unbound) |
365 | bindStatus->boundInContext = True1; |
366 | else |
367 | bindStatus->boundInContext = False0; |
368 | |
369 | } else { |
370 | bindStatus->boundInContext = False0; |
371 | } |
372 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
373 | return unbound; |
374 | } |
375 | |
376 | static XtActionProc *TryBindCache( |
377 | Widget widget, |
378 | TMStateTree stateTree) |
379 | { |
380 | TMClassCache classCache; |
381 | |
382 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
383 | classCache = GetClassCache(widget)((TMClassCache)widget->core.widget_class->core_class.actions ); |
384 | |
385 | if (classCache == NULL((void*)0)) |
386 | { |
387 | WidgetClass wc = XtClass(widget)((widget)->core.widget_class); |
388 | |
389 | wc->core_class.actions = (XtActionList) |
390 | _XtInitializeActionData(NULL((void*)0), 0, True1); |
391 | } |
392 | else |
393 | { |
394 | TMBindCache bindCache = |
395 | (TMBindCache)(classCache->bindCache); |
396 | for (; bindCache; bindCache = bindCache->next) |
397 | { |
398 | if (IsPureClassBind(bindCache)(bindCache->status.boundInClass && !(bindCache-> status.boundInHierarchy || bindCache->status.boundInContext || bindCache->status.notFullyBound)) && |
399 | (stateTree == bindCache->stateTree)) |
400 | { |
401 | bindCache->status.refCount++; |
402 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
403 | return &bindCache->procs[0]; |
404 | } |
405 | } |
406 | } |
407 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
408 | return NULL((void*)0); |
409 | } |
410 | |
411 | |
412 | |
413 | /* |
414 | * The class record actions field will point to the bind cache header |
415 | * after this call is made out of coreClassPartInit. |
416 | */ |
417 | XtPointer _XtInitializeActionData( |
418 | register struct _XtActionsRec *actions, |
419 | register Cardinal count, |
420 | _XtBooleanBoolean inPlace) |
421 | { |
422 | TMClassCache classCache; |
423 | |
424 | classCache = XtNew(TMClassCacheRec)((TMClassCacheRec *) XtMalloc((unsigned) sizeof(TMClassCacheRec ))); |
425 | classCache->actions = CompileActionTable(actions, count, inPlace, True1); |
426 | classCache->bindCache = NULL((void*)0); |
427 | return (XtPointer)classCache; |
428 | } |
429 | |
430 | |
431 | #define TM_BIND_CACHE_REALLOC2 2 |
432 | |
433 | static XtActionProc *EnterBindCache( |
434 | Widget w, |
435 | TMSimpleStateTree stateTree, |
436 | XtActionProc *procs, |
437 | TMBindCacheStatus bindStatus) |
438 | { |
439 | TMClassCache classCache; |
440 | TMBindCache* bindCachePtr; |
441 | TMShortCard procsSize; |
442 | TMBindCache bindCache; |
443 | |
444 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
445 | classCache = GetClassCache(w)((TMClassCache)w->core.widget_class->core_class.actions ); |
446 | bindCachePtr = &classCache->bindCache; |
447 | procsSize = stateTree->numQuarks * sizeof(XtActionProc); |
448 | |
449 | for (bindCache = *bindCachePtr; |
450 | (*bindCachePtr); |
451 | bindCachePtr = &(*bindCachePtr)->next, bindCache = *bindCachePtr) |
452 | { |
453 | TMBindCacheStatus cacheStatus = &bindCache->status; |
454 | |
455 | if ((bindStatus->boundInClass == cacheStatus->boundInClass) && |
456 | (bindStatus->boundInHierarchy == cacheStatus->boundInHierarchy) && |
457 | (bindStatus->boundInContext == cacheStatus->boundInContext) && |
458 | (bindCache->stateTree == (TMStateTree)stateTree) && |
459 | !XtMemcmp(&bindCache->procs[0], procs, procsSize)memcmp((char *) (&bindCache->procs[0]), (char *) (procs ), (int) (procsSize))) |
460 | { |
461 | bindCache->status.refCount++; |
462 | break; |
463 | } |
464 | } |
465 | if (*bindCachePtr == NULL((void*)0)) |
466 | { |
467 | *bindCachePtr = |
468 | bindCache = (TMBindCache) |
469 | __XtMalloc(sizeof(TMBindCacheRec) + |
470 | (procsSize - sizeof(XtActionProc))); |
471 | bindCache->next = NULL((void*)0); |
472 | bindCache->status = *bindStatus; |
473 | bindCache->status.refCount = 1; |
474 | bindCache->stateTree = (TMStateTree)stateTree; |
475 | #ifdef TRACE_TM |
476 | bindCache->widgetClass = XtClass(w)((w)->core.widget_class); |
477 | if (_XtGlobalTM.numBindCache == _XtGlobalTM.bindCacheTblSize) |
478 | { |
479 | _XtGlobalTM.bindCacheTblSize += 16; |
480 | _XtGlobalTM.bindCacheTbl = (TMBindCache *) |
481 | XtRealloc((char *)_XtGlobalTM.bindCacheTbl, |
482 | ((_XtGlobalTM.bindCacheTblSize) * |
483 | sizeof(TMBindCache))); |
484 | } |
485 | _XtGlobalTM.bindCacheTbl[_XtGlobalTM.numBindCache++] = bindCache; |
486 | #endif /* TRACE_TM */ |
487 | XtMemmove((XtPointer)&bindCache->procs[0],if ((char *)((XtPointer)&bindCache->procs[0]) != (char *)((XtPointer)procs)) { (void) memcpy((char *) ((XtPointer)& bindCache->procs[0]), (char *) ((XtPointer)procs), (int) ( procsSize)); } |
488 | (XtPointer)procs, procsSize)if ((char *)((XtPointer)&bindCache->procs[0]) != (char *)((XtPointer)procs)) { (void) memcpy((char *) ((XtPointer)& bindCache->procs[0]), (char *) ((XtPointer)procs), (int) ( procsSize)); }; |
489 | } |
490 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
491 | return &bindCache->procs[0]; |
492 | } |
493 | |
494 | static void RemoveFromBindCache( |
495 | Widget w, |
496 | XtActionProc *procs) |
497 | { |
498 | TMClassCache classCache; |
499 | TMBindCache* bindCachePtr; |
500 | TMBindCache bindCache; |
501 | XtAppContext app = XtWidgetToApplicationContext (w); |
502 | |
503 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
504 | classCache = GetClassCache(w)((TMClassCache)w->core.widget_class->core_class.actions ); |
505 | bindCachePtr = (TMBindCache *)&classCache->bindCache; |
506 | |
507 | for (bindCache = *bindCachePtr; |
508 | *bindCachePtr; |
509 | bindCachePtr = &(*bindCachePtr)->next, bindCache = *bindCachePtr) |
510 | { |
511 | if (&bindCache->procs[0] == procs) |
512 | { |
513 | if (--bindCache->status.refCount == 0) |
514 | { |
515 | #ifdef TRACE_TM |
516 | TMShortCard j; |
517 | Boolean found = False0; |
518 | TMBindCache *tbl = _XtGlobalTM.bindCacheTbl; |
519 | |
520 | for (j = 0; j < _XtGlobalTM.numBindCache; j++) { |
521 | if (found) |
522 | tbl[j-1] = tbl[j]; |
523 | if (tbl[j] == bindCache) |
524 | found = True1; |
525 | } |
526 | if (!found) |
527 | XtWarning("where's the action ??? "); |
528 | else |
529 | _XtGlobalTM.numBindCache--; |
530 | #endif /* TRACE_TM */ |
531 | *bindCachePtr = bindCache->next; |
532 | bindCache->next = app->free_bindings; |
533 | app->free_bindings = bindCache; |
534 | } |
535 | break; |
536 | } |
537 | } |
538 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
539 | } |
540 | |
541 | /* ARGSUSED */ |
542 | static void RemoveAccelerators( |
543 | Widget widget, |
544 | XtPointer closure, XtPointer data) |
545 | { |
546 | Widget destination = (Widget)closure; |
547 | TMComplexBindProcs bindProcs; |
548 | XtTranslations stackXlations[16]; |
549 | XtTranslations *xlationsList, destXlations; |
550 | TMShortCard i, numXlations = 0; |
551 | |
552 | if ((destXlations = destination->core.tm.translations) == NULL((void*)0)) { |
553 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), |
554 | XtNtranslationError,"nullTable",XtCXtToolkitError, |
555 | "Can't remove accelerators from NULL table", |
556 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
557 | return; |
558 | } |
559 | |
560 | xlationsList = (XtTranslations *) |
561 | XtStackAlloc((destXlations->numStateTrees * sizeof(XtTranslations)),(((destXlations->numStateTrees * sizeof(XtTranslations))) <= sizeof(stackXlations) ? (XtPointer)(stackXlations) : XtMalloc ((unsigned)((destXlations->numStateTrees * sizeof(XtTranslations ))))) |
562 | stackXlations)(((destXlations->numStateTrees * sizeof(XtTranslations))) <= sizeof(stackXlations) ? (XtPointer)(stackXlations) : XtMalloc ((unsigned)((destXlations->numStateTrees * sizeof(XtTranslations ))))); |
563 | |
564 | for (i = 0, bindProcs = TMGetComplexBindEntry(destination->core.tm.proc_table, i)((TMComplexBindProcs)&(((TMComplexBindData)destination-> core.tm.proc_table)->bindTbl[i])); |
565 | i < destXlations->numStateTrees; |
566 | i++, bindProcs++) { |
567 | if (bindProcs->widget == widget) { |
568 | /* |
569 | * if it's being destroyed don't do all the work |
570 | */ |
571 | if (destination->core.being_destroyed) { |
572 | bindProcs->procs = NULL((void*)0); |
573 | } |
574 | else |
575 | xlationsList[numXlations] = bindProcs->aXlations; |
576 | numXlations++; |
577 | } |
578 | } |
579 | |
580 | if (numXlations == 0) |
581 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), |
582 | XtNtranslationError,"nullTable",XtCXtToolkitError, |
583 | "Tried to remove nonexistent accelerators", |
584 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
585 | else { |
586 | if (!destination->core.being_destroyed) |
587 | for (i = 0; i < numXlations; i++) |
588 | _XtUnmergeTranslations(destination, xlationsList[i]); |
589 | } |
590 | XtStackFree((char *)xlationsList, stackXlations){ if (((char *)xlationsList) != ((XtPointer)(stackXlations))) XtFree((char *)xlationsList); }; |
591 | } |
592 | |
593 | void _XtBindActions( |
594 | Widget widget, |
595 | XtTM tm) |
596 | { |
597 | XtTranslations xlations = tm->translations; |
598 | TMSimpleStateTree stateTree; |
599 | int globalUnbound = 0; |
600 | Cardinal i; |
601 | TMBindData bindData = (TMBindData)tm->proc_table; |
602 | TMSimpleBindProcs simpleBindProcs = NULL((void*)0); |
603 | TMComplexBindProcs complexBindProcs = NULL((void*)0); |
604 | XtActionProc *newProcs; |
605 | Widget bindWidget; |
606 | |
607 | if ((xlations == NULL((void*)0)) || widget->core.being_destroyed) |
608 | return; |
609 | |
610 | stateTree = (TMSimpleStateTree)xlations->stateTreeTbl[0]; |
611 | |
612 | for (i = 0; i < xlations->numStateTrees; i++) |
613 | { |
614 | stateTree = (TMSimpleStateTree)xlations->stateTreeTbl[i]; |
615 | if (bindData->simple.isComplex) { |
616 | complexBindProcs = TMGetComplexBindEntry(bindData, i)((TMComplexBindProcs)&(((TMComplexBindData)bindData)-> bindTbl[i])); |
617 | if (complexBindProcs->widget) { |
618 | bindWidget = complexBindProcs->widget; |
619 | |
620 | if (bindWidget->core.destroy_callbacks != NULL((void*)0)) |
621 | _XtAddCallbackOnce((InternalCallbackList *) |
622 | &bindWidget->core.destroy_callbacks, |
623 | RemoveAccelerators, |
624 | (XtPointer)widget); |
625 | else |
626 | _XtAddCallback((InternalCallbackList *) |
627 | &bindWidget->core.destroy_callbacks, |
628 | RemoveAccelerators, |
629 | (XtPointer)widget); |
630 | } |
631 | else |
632 | bindWidget = widget; |
633 | } |
634 | else { |
635 | simpleBindProcs = TMGetSimpleBindEntry(bindData, i)((TMSimpleBindProcs)&(((TMSimpleBindData)bindData)->bindTbl [i])); |
636 | bindWidget = widget; |
637 | } |
638 | if ((newProcs = |
639 | TryBindCache(bindWidget,(TMStateTree)stateTree)) == NULL((void*)0)) |
640 | { |
641 | XtActionProc *procs, stackProcs[256]; |
642 | int localUnbound; |
643 | TMBindCacheStatusRec bcStatusRec; |
644 | |
645 | procs = (XtActionProc *) |
646 | XtStackAlloc(stateTree->numQuarks * sizeof(XtActionProc),((stateTree->numQuarks * sizeof(XtActionProc)) <= sizeof (stackProcs) ? (XtPointer)(stackProcs) : XtMalloc((unsigned)( stateTree->numQuarks * sizeof(XtActionProc)))) |
647 | stackProcs)((stateTree->numQuarks * sizeof(XtActionProc)) <= sizeof (stackProcs) ? (XtPointer)(stackProcs) : XtMalloc((unsigned)( stateTree->numQuarks * sizeof(XtActionProc)))); |
648 | XtBZero((XtPointer)procs,memset((char *) ((XtPointer)procs),0,(int) (stateTree->numQuarks * sizeof(XtActionProc))) |
649 | stateTree->numQuarks * sizeof(XtActionProc))memset((char *) ((XtPointer)procs),0,(int) (stateTree->numQuarks * sizeof(XtActionProc))); |
650 | |
651 | localUnbound = BindProcs(bindWidget, |
652 | stateTree, |
653 | procs, |
654 | &bcStatusRec); |
655 | |
656 | if (localUnbound) |
657 | bcStatusRec.notFullyBound = True1; |
658 | else |
659 | bcStatusRec.notFullyBound = False0; |
660 | |
661 | newProcs = |
662 | EnterBindCache(bindWidget, |
663 | stateTree, |
664 | procs, |
665 | &bcStatusRec); |
666 | XtStackFree((XtPointer)procs, (XtPointer)stackProcs){ if (((XtPointer)procs) != ((XtPointer)((XtPointer)stackProcs ))) XtFree((XtPointer)procs); }; |
667 | globalUnbound += localUnbound; |
668 | } |
669 | if (bindData->simple.isComplex) |
670 | complexBindProcs->procs = newProcs; |
671 | else |
672 | simpleBindProcs->procs = newProcs; |
673 | } |
674 | if (globalUnbound) |
675 | ReportUnboundActions(xlations, |
676 | (TMBindData)tm->proc_table); |
677 | } |
678 | |
679 | |
680 | void _XtUnbindActions( |
681 | Widget widget, |
682 | XtTranslations xlations, |
683 | TMBindData bindData) |
684 | { |
685 | Cardinal i; |
686 | Widget bindWidget; |
687 | XtActionProc *procs; |
688 | |
689 | if ((xlations == NULL((void*)0)) || !XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L)) return; |
690 | |
691 | for (i = 0; i < xlations->numStateTrees; i++) { |
692 | if (bindData->simple.isComplex) { |
693 | TMComplexBindProcs complexBindProcs; |
694 | |
695 | complexBindProcs = TMGetComplexBindEntry(bindData, i)((TMComplexBindProcs)&(((TMComplexBindData)bindData)-> bindTbl[i])); |
696 | |
697 | if (complexBindProcs->widget) { |
698 | /* |
699 | * check for this being an accelerator binding whose |
700 | * source is gone ( set by RemoveAccelerators) |
701 | */ |
702 | if (complexBindProcs->procs == NULL((void*)0)) |
703 | continue; |
704 | |
705 | XtRemoveCallback(complexBindProcs->widget, |
706 | XtNdestroyCallback((char*)&XtStrings[169]), |
707 | RemoveAccelerators, |
708 | (XtPointer)widget); |
709 | bindWidget = complexBindProcs->widget; |
710 | } |
711 | else |
712 | bindWidget = widget; |
713 | procs = complexBindProcs->procs; |
714 | complexBindProcs->procs = NULL((void*)0); |
715 | } |
716 | else { |
717 | TMSimpleBindProcs simpleBindProcs; |
718 | simpleBindProcs = TMGetSimpleBindEntry(bindData,i)((TMSimpleBindProcs)&(((TMSimpleBindData)bindData)->bindTbl [i])); |
719 | procs = simpleBindProcs->procs; |
720 | simpleBindProcs->procs = NULL((void*)0); |
721 | bindWidget = widget; |
722 | } |
723 | RemoveFromBindCache(bindWidget, procs); |
724 | } |
725 | } |
726 | |
727 | #ifdef notdef |
728 | void _XtRemoveBindProcsByIndex( |
729 | Widget w, |
730 | TMBindData bindData, |
731 | TMShortCard ndx) |
732 | { |
733 | TMShortCard i = ndx; |
734 | TMBindProcs bindProcs = (TMBindProcs)&bindData->bindTbl[0]; |
735 | |
736 | RemoveFromBindCache(bindProcs->widget ? bindProcs->widget : w, |
737 | bindProcs[i].procs); |
738 | |
739 | for (; i < bindData->bindTblSize; i++) |
740 | bindProcs[i] = bindProcs[i+1]; |
741 | } |
742 | #endif /* notdef */ |
743 | |
744 | /* |
745 | * used to free all copied action tables, called from DestroyAppContext |
746 | */ |
747 | void _XtFreeActions( |
748 | ActionList actions) |
749 | { |
750 | ActionList curr, next; |
751 | |
752 | for (curr = actions; curr;) { |
753 | next = curr->next; |
754 | XtFree((char *)curr->table); |
755 | XtFree((char *)curr); |
756 | curr = next; |
757 | } |
758 | } |
759 | |
760 | void XtAddActions( |
761 | XtActionList actions, |
762 | Cardinal num_actions) |
763 | { |
764 | XtAppAddActions(_XtDefaultAppContext(), actions, num_actions); |
765 | } |
766 | |
767 | void XtAppAddActions( |
768 | XtAppContext app, |
769 | XtActionList actions, |
770 | Cardinal num_actions) |
771 | { |
772 | register ActionList rec; |
773 | |
774 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
775 | rec = XtNew(ActionListRec)((ActionListRec *) XtMalloc((unsigned) sizeof(ActionListRec)) ); |
776 | rec->next = app->action_table; |
777 | app->action_table = rec; |
778 | rec->table = CompileActionTable(actions, num_actions, False0, False0); |
779 | rec->count = num_actions; |
780 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
781 | } |
782 | |
783 | void XtGetActionList( |
784 | WidgetClass widget_class, |
785 | XtActionList* actions_return, |
786 | Cardinal* num_actions_return) |
787 | { |
788 | XtActionList list; |
789 | CompiledActionTable table; |
790 | int i; |
791 | |
792 | *actions_return = NULL((void*)0); |
793 | *num_actions_return = 0; |
794 | |
795 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
796 | if (! widget_class->core_class.class_inited) { |
797 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
798 | return; |
799 | } |
800 | if (! (widget_class->core_class.class_inited & WidgetClassFlag0x04)) { |
801 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
802 | return; |
803 | } |
804 | *num_actions_return = widget_class->core_class.num_actions; |
805 | if (*num_actions_return) { |
806 | list = *actions_return = (XtActionList) |
807 | __XtMalloc(*num_actions_return * sizeof(XtActionsRec)); |
808 | table = GetClassActions(widget_class)((widget_class->core_class.actions) ? (((TMClassCache)widget_class ->core_class.actions)->actions) : ((void*)0)); |
809 | if (table != NULL((void*)0)) { |
810 | for (i= (*num_actions_return); --i >= 0; list++, table++) { |
811 | list->string = XrmQuarkToString(table->signature); |
812 | list->proc = table->proc; |
813 | } |
814 | } |
815 | } |
816 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
817 | } |
818 | |
819 | /*********************************************************************** |
820 | * |
821 | * Pop-up and Grab stuff |
822 | * |
823 | ***********************************************************************/ |
824 | |
825 | static Widget _XtFindPopup( |
826 | Widget widget, |
827 | String name) |
828 | { |
829 | register Cardinal i; |
830 | register XrmQuark q; |
831 | register Widget w; |
832 | |
833 | q = XrmStringToQuark(name); |
834 | |
835 | for (w=widget; w != NULL((void*)0); w=w->core.parent) |
836 | for (i=0; i<w->core.num_popups; i++) |
837 | if (w->core.popup_list[i]->core.xrm_name == q) |
838 | return w->core.popup_list[i]; |
839 | |
840 | return NULL((void*)0); |
841 | } |
842 | |
843 | void XtMenuPopupAction( |
844 | Widget widget, |
845 | XEvent *event, |
846 | String *params, |
847 | Cardinal *num_params) |
848 | { |
849 | Boolean spring_loaded; |
850 | register Widget popup_shell; |
851 | XtAppContext app = XtWidgetToApplicationContext(widget); |
852 | |
853 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
854 | if (*num_params != 1) { |
855 | XtAppWarningMsg(app, |
856 | "invalidParameters","xtMenuPopupAction",XtCXtToolkitError, |
857 | "MenuPopup wants exactly one argument", |
858 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
859 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
860 | return; |
861 | } |
862 | |
863 | if (event->type == ButtonPress4) |
864 | spring_loaded = True1; |
865 | else if (event->type == KeyPress2 || event->type == EnterNotify7) |
866 | spring_loaded = False0; |
867 | else { |
868 | XtAppWarningMsg(app, |
869 | "invalidPopup","unsupportedOperation",XtCXtToolkitError, |
870 | "Pop-up menu creation is only supported on ButtonPress, KeyPress or EnterNotify events.", |
871 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
872 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
873 | return; |
874 | } |
875 | |
876 | popup_shell = _XtFindPopup(widget, params[0]); |
877 | if (popup_shell == NULL((void*)0)) { |
878 | XtAppWarningMsg(app, |
879 | "invalidPopup","xtMenuPopup",XtCXtToolkitError, |
880 | "Can't find popup widget \"%s\" in XtMenuPopup", |
881 | params, num_params); |
882 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
883 | return; |
884 | } |
885 | |
886 | if (spring_loaded) _XtPopup(popup_shell, XtGrabExclusive, TRUE1); |
887 | else _XtPopup(popup_shell, XtGrabNonexclusive, FALSE0); |
888 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
889 | } |
890 | |
891 | |
892 | /*ARGSUSED*/ |
893 | static void _XtMenuPopdownAction( |
894 | Widget widget, |
895 | XEvent *event, |
896 | String *params, |
897 | Cardinal *num_params) |
898 | { |
899 | Widget popup_shell; |
900 | |
901 | if (*num_params == 0) { |
902 | XtPopdown(widget); |
903 | } else if (*num_params == 1) { |
904 | popup_shell = _XtFindPopup(widget, params[0]); |
905 | if (popup_shell == NULL((void*)0)) { |
906 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), |
907 | "invalidPopup","xtMenuPopdown",XtCXtToolkitError, |
908 | "Can't find popup widget \"%s\" in XtMenuPopdown", |
909 | params, num_params); |
910 | return; |
911 | } |
912 | XtPopdown(popup_shell); |
913 | } else { |
914 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), |
915 | "invalidParameters","xtMenuPopdown",XtCXtToolkitError, |
916 | "XtMenuPopdown called with num_params != 0 or 1", |
917 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
918 | } |
919 | } |
920 | |
921 | static XtActionsRec RConstconst tmActions[] = { |
922 | {"XtMenuPopup", XtMenuPopupAction}, |
923 | {"XtMenuPopdown", _XtMenuPopdownAction}, |
924 | {"MenuPopup", XtMenuPopupAction}, /* old & obsolete */ |
925 | {"MenuPopdown", _XtMenuPopdownAction}, /* ditto */ |
926 | #ifndef NO_MIT_HACKS |
927 | {"XtDisplayTranslations", _XtDisplayTranslations}, |
928 | {"XtDisplayAccelerators", _XtDisplayAccelerators}, |
929 | {"XtDisplayInstalledAccelerators", _XtDisplayInstalledAccelerators}, |
930 | #endif |
931 | }; |
932 | |
933 | |
934 | void _XtPopupInitialize( |
935 | XtAppContext app) |
936 | { |
937 | register ActionList rec; |
938 | |
939 | /* |
940 | * The _XtGlobalTM.newMatchSemantics flag determines whether |
941 | * we support old or new matching |
942 | * behavior. This is mainly an issue of whether subsequent lhs will |
943 | * get pushed up in the match table if a lhs containing thier initial |
944 | * sequence has already been encountered. Currently inited to False; |
945 | */ |
946 | #ifdef NEW_TM |
947 | _XtGlobalTM.newMatchSemantics = True1; |
948 | #else |
949 | _XtGlobalTM.newMatchSemantics = False0; |
950 | #endif |
951 | |
952 | rec = XtNew(ActionListRec)((ActionListRec *) XtMalloc((unsigned) sizeof(ActionListRec)) ); |
953 | rec->next = app->action_table; |
954 | app->action_table = rec; |
955 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
956 | rec->table = CompileActionTable(tmActions, XtNumber(tmActions)((Cardinal) (sizeof(tmActions) / sizeof(tmActions[0]))), False0, |
957 | True1); |
958 | rec->count = XtNumber(tmActions)((Cardinal) (sizeof(tmActions) / sizeof(tmActions[0]))); |
959 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
960 | _XtGrabInitialize(app); |
961 | } |
962 | |
963 | |
964 | void XtCallActionProc( |
965 | Widget widget, |
966 | _Xconstconst char* action, |
967 | XEvent *event, |
968 | String *params, |
969 | Cardinal num_params) |
970 | { |
971 | CompiledAction* actionP; |
972 | XrmQuark q = XrmStringToQuark(action); |
973 | Widget w = widget; |
974 | XtAppContext app = XtWidgetToApplicationContext(widget); |
975 | ActionList actionList; |
976 | Cardinal i; |
977 | |
978 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
979 | XtCheckSubclass(widget, coreWidgetClass, |
980 | "XtCallActionProc first argument is not a subclass of Core"); |
981 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
982 | do { |
983 | WidgetClass class = XtClass(w)((w)->core.widget_class); |
984 | do { |
985 | if ((actionP = GetClassActions(class)((class->core_class.actions) ? (((TMClassCache)class->core_class .actions)->actions) : ((void*)0))) != NULL((void*)0)) |
986 | for (i = 0; |
987 | i < class->core_class.num_actions; |
988 | i++, actionP++) { |
989 | |
990 | if (actionP->signature == q) { |
991 | ActionHook hook = app->action_hook_list; |
992 | while (hook != NULL((void*)0)) { |
993 | (*hook->proc)( widget, |
994 | hook->closure, |
995 | (String)action, |
996 | event, |
997 | params, |
998 | &num_params |
999 | ); |
1000 | hook= hook->next; |
1001 | } |
1002 | (*(actionP->proc)) |
1003 | (widget, event, params, &num_params); |
1004 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1005 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1006 | return; |
1007 | } |
1008 | } |
1009 | class = class->core_class.superclass; |
1010 | } while (class != NULL((void*)0)); |
1011 | w = XtParent(w)((w)->core.parent); |
1012 | } while (w != NULL((void*)0)); |
1013 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1014 | |
1015 | for (actionList = app->action_table; |
1016 | actionList != NULL((void*)0); |
1017 | actionList = actionList->next) { |
1018 | |
1019 | for (i = 0, actionP = actionList->table; |
1020 | i < actionList->count; |
1021 | i++, actionP++) { |
1022 | if (actionP->signature == q) { |
1023 | ActionHook hook = app->action_hook_list; |
1024 | while (hook != NULL((void*)0)) { |
1025 | (*hook->proc)( widget, |
1026 | hook->closure, |
1027 | (String)action, |
1028 | event, |
1029 | params, |
1030 | &num_params |
1031 | ); |
1032 | hook= hook->next; |
1033 | } |
1034 | (*(actionP->proc)) |
1035 | (widget, event, params, &num_params); |
1036 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1037 | return; |
1038 | } |
1039 | } |
1040 | |
1041 | } |
1042 | |
1043 | { |
1044 | String params[2]; |
1045 | Cardinal num_params = 2; |
1046 | params[0] = (String)action; |
1047 | params[1] = XtName(widget); |
1048 | XtAppWarningMsg(app, |
1049 | "noActionProc", "xtCallActionProc", XtCXtToolkitError, |
1050 | "No action proc named \"%s\" is registered for widget \"%s\"", |
1051 | params, &num_params |
1052 | ); |
1053 | } |
1054 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1055 | } |
1056 | |
1057 | void _XtDoFreeBindings( |
1058 | XtAppContext app) |
1059 | { |
1060 | TMBindCache bcp; |
1061 | |
1062 | while (app->free_bindings) { |
1063 | bcp = app->free_bindings->next; |
1064 | XtFree ((char *) app->free_bindings); |
1065 | app->free_bindings = bcp; |
1066 | } |
1067 | } |