Bug Summary

File:src/Display.c
Location:line 122, column 6
Description:Access to field 'count' results in a dereference of a null pointer (loaded from variable 'app')

Annotated Source Code

1/***********************************************************
2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3
4Permission is hereby granted, free of charge, to any person obtaining a
5copy of this software and associated documentation files (the "Software"),
6to deal in the Software without restriction, including without limitation
7the rights to use, copy, modify, merge, publish, distribute, sublicense,
8and/or sell copies of the Software, and to permit persons to whom the
9Software is furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice (including the next
12paragraph) shall be included in all copies or substantial portions of the
13Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21DEALINGS IN THE SOFTWARE.
22
23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24
25 All Rights Reserved
26
27Permission to use, copy, modify, and distribute this software and its
28documentation for any purpose and without fee is hereby granted,
29provided that the above copyright notice appear in all copies and that
30both that copyright notice and this permission notice appear in
31supporting documentation, and that the name of Digital not be
32used in advertising or publicity pertaining to distribution of the
33software without specific, written prior permission.
34
35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41SOFTWARE.
42
43******************************************************************/
44
45/*
46
47Copyright 1987, 1988, 1998 The Open Group
48
49Permission to use, copy, modify, distribute, and sell this software and its
50documentation for any purpose is hereby granted without fee, provided that
51the above copyright notice appear in all copies and that both that
52copyright notice and this permission notice appear in supporting
53documentation.
54
55The above copyright notice and this permission notice shall be included in
56all copies or substantial portions of the Software.
57
58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
65Except as contained in this notice, the name of The Open Group shall not be
66used in advertising or otherwise to promote the sale, use or other dealings
67in this Software without prior written authorization from The Open Group.
68
69*/
70
71#ifdef HAVE_CONFIG_H1
72#include <config.h>
73#endif
74#include "IntrinsicI.h"
75#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
76#include "ResConfigP.h"
77#endif
78
79#include <stdlib.h>
80
81#ifdef XTHREADS1
82void (*_XtProcessLock)(void) = NULL((void*)0);
83void (*_XtProcessUnlock)(void) = NULL((void*)0);
84void (*_XtInitAppLock)(XtAppContext) = NULL((void*)0);
85#endif
86
87static String XtNnoPerDisplay = "noPerDisplay";
88
89ProcessContext _XtGetProcessContext(void)
90{
91 static ProcessContextRec processContextRec = {
92 (XtAppContext)NULL((void*)0),
93 (XtAppContext)NULL((void*)0),
94 (ConverterTable)NULL((void*)0),
95 {(XtLanguageProc)NULL((void*)0), (XtPointer)NULL((void*)0)}
96 };
97
98 return &processContextRec;
99}
100
101
102XtAppContext _XtDefaultAppContext(void)
103{
104 ProcessContext process = _XtGetProcessContext();
105 XtAppContext app;
106
107 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
108 if (process->defaultAppContext == NULL((void*)0)) {
109 process->defaultAppContext = XtCreateApplicationContext();
110 }
111 app = process->defaultAppContext;
112 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
113 return app;
114}
115
116static void AddToAppContext(
117 Display *d,
118 XtAppContext app)
119{
120#define DISPLAYS_TO_ADD 4
121
122 if (app->count >= app->max) {
6
Access to field 'count' results in a dereference of a null pointer (loaded from variable 'app')
123 app->max += DISPLAYS_TO_ADD;
124 app->list = (Display **) XtRealloc((char *)app->list,
125 (unsigned) app->max * sizeof(Display *));
126 }
127
128 app->list[app->count++] = d;
129 app->rebuild_fdlist = TRUE1;
130#ifndef USE_POLL1
131 if (ConnectionNumber(d)(((_XPrivDisplay)(d))->fd) + 1 > app->fds.nfds) {
132 app->fds.nfds = ConnectionNumber(d)(((_XPrivDisplay)(d))->fd) + 1;
133 }
134#else
135 app->fds.nfds++;
136#endif
137#undef DISPLAYS_TO_ADD
138}
139
140static void XtDeleteFromAppContext(
141 Display *d,
142 register XtAppContext app)
143{
144 register int i;
145
146 for (i = 0; i < app->count; i++) if (app->list[i] == d) break;
147
148 if (i < app->count) {
149 if (i <= app->last && app->last > 0) app->last--;
150 for (i++; i < app->count; i++) app->list[i-1] = app->list[i];
151 app->count--;
152 }
153 app->rebuild_fdlist = TRUE1;
154#ifndef USE_POLL1
155 if ((ConnectionNumber(d)(((_XPrivDisplay)(d))->fd) + 1) == app->fds.nfds)
156 app->fds.nfds--;
157 else /* Unnecessary, just to be fool-proof */
158 FD_CLR(ConnectionNumber(d), &app->fds.rmask)do { int __fd = ((((_XPrivDisplay)(d))->fd)); ((&app->
fds.rmask)->fds_bits[(unsigned long)__fd/(sizeof(__int32_t
) * 8)] &= ~((__int32_t)(1<<((unsigned long)__fd % (
sizeof(__int32_t) * 8))))); } while(0)
;
159#else
160 app->fds.nfds--;
161#endif
162}
163
164static XtPerDisplay NewPerDisplay(
165 Display *dpy)
166{
167 PerDisplayTablePtr pd;
168
169 pd = XtNew(PerDisplayTable)((PerDisplayTable *) XtMalloc((unsigned) sizeof(PerDisplayTable
)))
;
170 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
171 pd->dpy = dpy;
172 pd->next = _XtperDisplayList;
173 _XtperDisplayList = pd;
174 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
175 return &(pd->perDpy);
176}
177
178static XtPerDisplay InitPerDisplay(
179 Display *dpy,
180 XtAppContext app,
181 _Xconstconst char * name,
182 _Xconstconst char * classname)
183{
184 XtPerDisplay pd;
185
186 AddToAppContext(dpy, app);
4
Passing null pointer value via 2nd parameter 'app'
5
Calling 'AddToAppContext'
187
188 pd = NewPerDisplay(dpy);
189 _XtHeapInit(&pd->heap);
190 pd->destroy_callbacks = NULL((void*)0);
191 pd->region = XCreateRegion();
192 pd->case_cvt = NULL((void*)0);
193 pd->defaultKeycodeTranslator = XtTranslateKey;
194 pd->keysyms_serial = 0;
195 pd->keysyms = NULL((void*)0);
196 XDisplayKeycodes(dpy, &pd->min_keycode, &pd->max_keycode);
197 pd->modKeysyms = NULL((void*)0);
198 pd->modsToKeysyms = NULL((void*)0);
199 pd->appContext = app;
200 pd->name = XrmStringToName(name)XrmStringToQuark(name);
201 pd->class = XrmStringToClass(classname)XrmStringToQuark(classname);
202 pd->being_destroyed = False0;
203 pd->GClist = NULL((void*)0);
204 pd->pixmap_tab = NULL((void*)0);
205 pd->language = NULL((void*)0);
206 pd->rv = False0;
207 pd->last_event.xany.serial = 0;
208 pd->last_timestamp = 0;
209 _XtAllocTMContext(pd);
210 pd->mapping_callbacks = NULL((void*)0);
211
212 pd->pdi.grabList = NULL((void*)0);
213 pd->pdi.trace = NULL((void*)0);
214 pd->pdi.traceDepth = 0;
215 pd->pdi.traceMax = 0;
216 pd->pdi.focusWidget = NULL((void*)0);
217 pd->pdi.activatingKey = 0;
218 pd->pdi.keyboard.grabType = XtNoServerGrab;
219 pd->pdi.pointer.grabType = XtNoServerGrab;
220 _XtAllocWWTable(pd);
221 pd->per_screen_db = (XrmDatabase *)__XtCalloc(ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens),
222 sizeof(XrmDatabase));
223 pd->cmd_db = (XrmDatabase)NULL((void*)0);
224 pd->server_db = (XrmDatabase)NULL((void*)0);
225 pd->dispatcher_list = NULL((void*)0);
226 pd->ext_select_list = NULL((void*)0);
227 pd->ext_select_count = 0;
228 pd->hook_object = NULL((void*)0);
229#if 0
230 pd->hook_object = _XtCreate("hooks", "Hooks", hookObjectClass,
231 (Widget)NULL((void*)0), (Screen*)DefaultScreenOfDisplay(dpy)(&((_XPrivDisplay)(dpy))->screens[(((_XPrivDisplay)(dpy
))->default_screen)])
,
232 (ArgList)NULL((void*)0), 0, (XtTypedArgList)NULL((void*)0), 0,
233 (ConstraintWidgetClass)NULL((void*)0));
234#endif
235
236#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
237 pd->rcm_init = XInternAtom (dpy, RCM_INIT"Custom Init", 0);
238 pd->rcm_data = XInternAtom (dpy, RCM_DATA"Custom Data", 0);
239#endif
240
241 return pd;
242}
243
244Display *XtOpenDisplay(
245 XtAppContext app,
246 _Xconstconst char* displayName,
247 _Xconstconst char* applName,
248 _Xconstconst char* className,
249 XrmOptionDescRec *urlist,
250 Cardinal num_urs,
251 int *argc,
252 String *argv)
253{
254 Display *d;
255 XrmDatabase db = NULL((void*)0);
256 XtPerDisplay pd;
257 String language = NULL((void*)0);
258
259 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
260 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
261 /* parse the command line for name, display, and/or language */
262 db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv,
263 (String *)&applName,
264 (String *)(displayName ? NULL((void*)0) : &displayName),
265 (app->process->globalLangProcRec.proc ?
266 &language : NULL((void*)0)));
267 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
268 d = XOpenDisplay(displayName);
269
270 if (! applName && !(applName = getenv("RESOURCE_NAME"))) {
271 if (*argc > 0 && argv[0] && *argv[0]) {
272#ifdef WIN32
273 char *ptr = strrchr(argv[0], '\\');
274#else
275 char *ptr = strrchr(argv[0], '/');
276#endif
277
278 if (ptr) applName = ++ptr;
279 else applName = argv[0];
280 } else
281 applName = "main";
282 }
283
284 if (d) {
285 pd = InitPerDisplay(d, app, applName, className);
286 pd->language = language;
287 _XtDisplayInitialize(d, pd, applName, urlist, num_urs, argc, argv);
288 } else {
289 int len;
290 displayName = XDisplayName(displayName);
291 len = strlen (displayName);
292 app->display_name_tried = (String) __XtMalloc (len + 1);
293 strncpy ((char*) app->display_name_tried, displayName, len + 1)__builtin___strncpy_chk ((char*) app->display_name_tried, displayName
, len + 1, __builtin_object_size ((char*) app->display_name_tried
, 2 > 1 ? 1 : 0))
;
294 app->display_name_tried[len] = '\0';
295 }
296 if (db) XrmDestroyDatabase(db);
297 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
298 return d;
299}
300
301Display *
302_XtAppInit(
303 XtAppContext * app_context_return,
304 String application_class,
305 XrmOptionDescRec *options,
306 Cardinal num_options,
307 int *argc_in_out,
308 String **argv_in_out,
309 String * fallback_resources)
310{
311 String *saved_argv;
312 int i;
313 Display *dpy;
314
315/*
316 * Save away argv and argc so we can set the properties later
317 */
318
319 saved_argv = (String *)
320 __XtMalloc( (Cardinal)((*argc_in_out + 1) * sizeof(String)) );
321
322 for (i = 0 ; i < *argc_in_out ; i++) saved_argv[i] = (*argv_in_out)[i];
323 saved_argv[i] = NULL((void*)0); /* NULL terminate that sucker. */
324
325
326 *app_context_return = XtCreateApplicationContext();
327
328 LOCK_APP((*app_context_return))if((*app_context_return) && (*app_context_return)->
lock)(*(*app_context_return)->lock)((*app_context_return))
;
329 if (fallback_resources) /* save a procedure call */
330 XtAppSetFallbackResources(*app_context_return, fallback_resources);
331
332 dpy = XtOpenDisplay(*app_context_return, (String) NULL((void*)0), NULL((void*)0),
333 application_class,
334 options, num_options, argc_in_out, *argv_in_out);
335
336 if (!dpy) {
337 String param = (*app_context_return)->display_name_tried;
338 Cardinal param_count = 1;
339 XtErrorMsg("invalidDisplay","xtInitialize",XtCXtToolkitError,
340 "Can't open display: %s", &param, &param_count);
341 XtFree((char *) (*app_context_return)->display_name_tried);
342 }
343 *argv_in_out = saved_argv;
344 UNLOCK_APP((*app_context_return))if((*app_context_return) && (*app_context_return)->
unlock)(*(*app_context_return)->unlock)((*app_context_return
))
;
345 return dpy;
346}
347
348void
349XtDisplayInitialize(
350 XtAppContext app,
351 Display *dpy,
352 _Xconstconst char* name,
353 _Xconstconst char* classname,
354 XrmOptionDescRec *urlist,
355 Cardinal num_urs,
356 int *argc,
357 String *argv
358 )
359{
360 XtPerDisplay pd;
361 XrmDatabase db = NULL((void*)0);
362
363 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
1
Within the expansion of the macro 'LOCK_APP':
a
Assuming pointer value is null
364 pd = InitPerDisplay(dpy, app, name, classname);
2
Passing null pointer value via 2nd parameter 'app'
3
Calling 'InitPerDisplay'
365 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
366 if (app->process->globalLangProcRec.proc)
367 /* pre-parse the command line for the language resource */
368 db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, NULL((void*)0), NULL((void*)0),
369 &pd->language);
370 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
371 _XtDisplayInitialize(dpy, pd, name, urlist, num_urs, argc, argv);
372 if (db) XrmDestroyDatabase(db);
373 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
374}
375
376XtAppContext XtCreateApplicationContext(void)
377{
378 XtAppContext app = XtNew(XtAppStruct)((XtAppStruct *) XtMalloc((unsigned) sizeof(XtAppStruct)));
379#ifdef XTHREADS1
380 app->lock_info = NULL((void*)0);
381 app->lock = NULL((void*)0);
382 app->unlock = NULL((void*)0);
383 app->yield_lock = NULL((void*)0);
384 app->restore_lock = NULL((void*)0);
385 app->free_lock = NULL((void*)0);
386#endif
387 INIT_APP_LOCK(app)if(_XtInitAppLock) (*_XtInitAppLock)(app);
388 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
389 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
390 app->process = _XtGetProcessContext();
391 app->next = app->process->appContextList;
392 app->process->appContextList = app;
393 app->langProcRec.proc = app->process->globalLangProcRec.proc;
394 app->langProcRec.closure = app->process->globalLangProcRec.closure;
395 app->destroy_callbacks = NULL((void*)0);
396 app->list = NULL((void*)0);
397 app->count = app->max = app->last = 0;
398 app->timerQueue = NULL((void*)0);
399 app->workQueue = NULL((void*)0);
400 app->signalQueue = NULL((void*)0);
401 app->input_list = NULL((void*)0);
402 app->outstandingQueue = NULL((void*)0);
403 app->errorDB = NULL((void*)0);
404 _XtSetDefaultErrorHandlers(&app->errorMsgHandler,
405 &app->warningMsgHandler, &app->errorHandler,
406 &app->warningHandler);
407 app->action_table = NULL((void*)0);
408 _XtSetDefaultSelectionTimeout(&app->selectionTimeout);
409 _XtSetDefaultConverterTable(&app->converterTable);
410 app->sync = app->being_destroyed = app->error_inited = FALSE0;
411 app->in_phase2_destroy = NULL((void*)0);
412#ifndef USE_POLL1
413 FD_ZERO(&app->fds.rmask)__builtin_bzero(&app->fds.rmask, sizeof(*(&app->
fds.rmask)))
;
414 FD_ZERO(&app->fds.wmask)__builtin_bzero(&app->fds.wmask, sizeof(*(&app->
fds.wmask)))
;
415 FD_ZERO(&app->fds.emask)__builtin_bzero(&app->fds.emask, sizeof(*(&app->
fds.emask)))
;
416#endif
417 app->fds.nfds = 0;
418 app->input_count = app->input_max = 0;
419 _XtHeapInit(&app->heap);
420 app->fallback_resources = NULL((void*)0);
421 _XtPopupInitialize(app);
422 app->action_hook_list = NULL((void*)0);
423 app->block_hook_list = NULL((void*)0);
424 app->destroy_list_size = app->destroy_count = app->dispatch_level = 0;
425 app->destroy_list = NULL((void*)0);
426#ifndef NO_IDENTIFY_WINDOWS
427 app->identify_windows = False0;
428#endif
429 app->free_bindings = NULL((void*)0);
430 app->display_name_tried = NULL((void*)0);
431 app->dpy_destroy_count = 0;
432 app->dpy_destroy_list = NULL((void*)0);
433 app->exit_flag = FALSE0;
434 app->rebuild_fdlist = TRUE1;
435 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
436 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
437 return app;
438}
439
440void XtAppSetExitFlag (
441 XtAppContext app)
442{
443 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
444 app->exit_flag = TRUE1;
445 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
446}
447
448Boolean XtAppGetExitFlag (
449 XtAppContext app)
450{
451 Boolean retval;
452 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
453 retval = app->exit_flag;
454 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
455 return retval;
456}
457
458static void DestroyAppContext(XtAppContext app)
459{
460 XtAppContext* prev_app;
461
462 prev_app = &app->process->appContextList;
463 while (app->count-- > 0) XtCloseDisplay(app->list[app->count]);
464 if (app->list != NULL((void*)0)) XtFree((char *)app->list);
465 _XtFreeConverterTable(app->converterTable);
466 _XtCacheFlushTag(app, (XtPointer)&app->heap);
467 _XtFreeActions(app->action_table);
468 if (app->destroy_callbacks != NULL((void*)0)) {
469 XtCallCallbackList((Widget) NULL((void*)0),
470 (XtCallbackList)app->destroy_callbacks,
471 (XtPointer)app);
472 _XtRemoveAllCallbacks(&app->destroy_callbacks);
473 }
474 while (app->timerQueue) XtRemoveTimeOut((XtIntervalId)app->timerQueue);
475 while (app->workQueue) XtRemoveWorkProc((XtWorkProcId)app->workQueue);
476 while (app->signalQueue) XtRemoveSignal((XtSignalId)app->signalQueue);
477 if (app->input_list) _XtRemoveAllInputs(app);
478 XtFree((char*)app->destroy_list);
479 _XtHeapFree(&app->heap);
480 while (*prev_app != app) prev_app = &(*prev_app)->next;
481 *prev_app = app->next;
482 if (app->process->defaultAppContext == app)
483 app->process->defaultAppContext = NULL((void*)0);
484 if (app->free_bindings) _XtDoFreeBindings (app);
485 FREE_APP_LOCK(app)if(app && app->free_lock)(*app->free_lock)(app);
486 XtFree((char *)app);
487}
488
489static XtAppContext* appDestroyList = NULL((void*)0);
490int _XtAppDestroyCount = 0;
491
492void XtDestroyApplicationContext(XtAppContext app)
493{
494 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
495 if (app->being_destroyed) {
496 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
497 return;
498 }
499
500 if (_XtSafeToDestroy(app)((app)->dispatch_level == 0)) {
501 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
502 DestroyAppContext(app);
503 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
504 } else {
505 app->being_destroyed = TRUE1;
506 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
507 _XtAppDestroyCount++;
508 appDestroyList =
509 (XtAppContext *) XtRealloc((char *) appDestroyList,
510 (unsigned) (_XtAppDestroyCount * sizeof(XtAppContext)));
511 appDestroyList[_XtAppDestroyCount-1] = app;
512 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
513 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
514 }
515}
516
517void _XtDestroyAppContexts(void)
518{
519 int i,ii;
520 XtAppContext apps[8];
521 XtAppContext* pApps;
522
523 pApps = XtStackAlloc (sizeof (XtAppContext) * _XtAppDestroyCount, apps)((sizeof (XtAppContext) * _XtAppDestroyCount) <= sizeof(apps
) ? (XtPointer)(apps) : XtMalloc((unsigned)(sizeof (XtAppContext
) * _XtAppDestroyCount)))
;
524
525 for (i = ii = 0; i < _XtAppDestroyCount; i++) {
526 if (_XtSafeToDestroy(appDestroyList[i])((appDestroyList[i])->dispatch_level == 0))
527 DestroyAppContext(appDestroyList[i]);
528 else
529 pApps[ii++] = appDestroyList[i];
530 }
531 _XtAppDestroyCount = ii;
532 if (_XtAppDestroyCount == 0) {
533 XtFree((char *) appDestroyList);
534 appDestroyList = NULL((void*)0);
535 } else {
536 for (i = 0; i < ii; i++)
537 appDestroyList[i] = pApps[i];
538 }
539 XtStackFree ((XtPointer) pApps, apps){ if (((XtPointer) pApps) != ((XtPointer)(apps))) XtFree((XtPointer
) pApps); }
;
540}
541
542XrmDatabase XtDatabase(Display *dpy)
543{
544 XrmDatabase retval;
545 DPY_TO_APPCON(dpy)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext
(dpy): ((void*)0))
;
546
547 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
548 retval = XrmGetDatabase(dpy);
549 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
550 return retval;
551}
552
553PerDisplayTablePtr _XtperDisplayList = NULL((void*)0);
554
555XtPerDisplay _XtSortPerDisplayList(Display *dpy)
556{
557 register PerDisplayTablePtr pd, opd = NULL((void*)0);
558
559 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
560 for (pd = _XtperDisplayList;
561 pd != NULL((void*)0) && pd->dpy != dpy;
562 pd = pd->next) {
563 opd = pd;
564 }
565
566 if (pd == NULL((void*)0)) {
567 XtErrorMsg(XtNnoPerDisplay, "getPerDisplay", XtCXtToolkitError,
568 "Couldn't find per display information",
569 (String *) NULL((void*)0), (Cardinal *)NULL((void*)0));
570 }
571
572 if (pd != _XtperDisplayList) { /* move it to the front */
573 /* opd points to the previous one... */
574
575 opd->next = pd->next;
576 pd->next = _XtperDisplayList;
577 _XtperDisplayList = pd;
578 }
579 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
580 return &(pd->perDpy);
581}
582
583XtAppContext XtDisplayToApplicationContext(Display *dpy)
584{
585 XtAppContext retval;
586
587 retval = _XtGetPerDisplay(dpy)->appContext;
588 return retval;
589}
590
591static void CloseDisplay(Display *dpy)
592{
593 register XtPerDisplay xtpd;
594 register PerDisplayTablePtr pd, opd = NULL((void*)0);
595 XrmDatabase db;
596 int i;
597
598 XtDestroyWidget(XtHooksOfDisplay(dpy));
599
600 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
601 for (pd = _XtperDisplayList;
602 pd != NULL((void*)0) && pd->dpy != dpy;
603 pd = pd->next){
604 opd = pd;
605 }
606
607 if (pd == NULL((void*)0)) {
608 XtErrorMsg(XtNnoPerDisplay, "closeDisplay", XtCXtToolkitError,
609 "Couldn't find per display information",
610 (String *) NULL((void*)0), (Cardinal *)NULL((void*)0));
611 }
612
613 if (pd == _XtperDisplayList) _XtperDisplayList = pd->next;
614 else opd->next = pd->next;
615
616 xtpd = &(pd->perDpy);
617
618 if (xtpd != NULL((void*)0)) {
619 if (xtpd->destroy_callbacks != NULL((void*)0)) {
620 XtCallCallbackList((Widget) NULL((void*)0),
621 (XtCallbackList)xtpd->destroy_callbacks,
622 (XtPointer)xtpd);
623 _XtRemoveAllCallbacks(&xtpd->destroy_callbacks);
624 }
625 if (xtpd->mapping_callbacks != NULL((void*)0))
626 _XtRemoveAllCallbacks(&xtpd->mapping_callbacks);
627 XtDeleteFromAppContext(dpy, xtpd->appContext);
628 if (xtpd->keysyms)
629 XFree((char *) xtpd->keysyms);
630 XtFree((char *) xtpd->modKeysyms);
631 XtFree((char *) xtpd->modsToKeysyms);
632 xtpd->keysyms_per_keycode = 0;
633 xtpd->being_destroyed = FALSE0;
634 xtpd->keysyms = NULL((void*)0);
635 xtpd->modKeysyms = NULL((void*)0);
636 xtpd->modsToKeysyms = NULL((void*)0);
637 XDestroyRegion(xtpd->region);
638 _XtCacheFlushTag(xtpd->appContext, (XtPointer)&xtpd->heap);
639 _XtGClistFree(dpy, xtpd);
640 XtFree((char*)xtpd->pdi.trace);
641 _XtHeapFree(&xtpd->heap);
642 _XtFreeWWTable(xtpd);
643 xtpd->per_screen_db[DefaultScreen(dpy)(((_XPrivDisplay)(dpy))->default_screen)] = (XrmDatabase)NULL((void*)0);
644 for (i = ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens); --i >= 0; ) {
645 db = xtpd->per_screen_db[i];
646 if (db)
647 XrmDestroyDatabase(db);
648 }
649 XtFree((char *)xtpd->per_screen_db);
650 if ((db = XrmGetDatabase(dpy)))
651 XrmDestroyDatabase(db);
652 if (xtpd->cmd_db)
653 XrmDestroyDatabase(xtpd->cmd_db);
654 if (xtpd->server_db)
655 XrmDestroyDatabase(xtpd->server_db);
656 XtFree(xtpd->language);
657 if (xtpd->dispatcher_list != NULL((void*)0))
658 XtFree((char *) xtpd->dispatcher_list);
659 if (xtpd->ext_select_list != NULL((void*)0))
660 XtFree((char *) xtpd->ext_select_list);
661 }
662 XtFree((char*)pd);
663 XrmSetDatabase(dpy, (XrmDatabase)NULL((void*)0));
664 XCloseDisplay(dpy);
665 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
666}
667
668void XtCloseDisplay(Display *dpy)
669{
670 XtPerDisplay pd;
671 XtAppContext app = XtDisplayToApplicationContext(dpy);
672
673 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
674 pd = _XtGetPerDisplay(dpy);
675 if (pd->being_destroyed) {
676 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
677 return;
678 }
679
680 if (_XtSafeToDestroy(app)((app)->dispatch_level == 0)) CloseDisplay(dpy);
681 else {
682 pd->being_destroyed = TRUE1;
683 app->dpy_destroy_count++;
684 app->dpy_destroy_list = (Display **)
685 XtRealloc((char *) app->dpy_destroy_list,
686 (unsigned) (app->dpy_destroy_count * sizeof(Display *)));
687 app->dpy_destroy_list[app->dpy_destroy_count-1] = dpy;
688 }
689 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
690}
691
692void _XtCloseDisplays(XtAppContext app)
693{
694 int i;
695
696 LOCK_APP(app)if(app && app->lock)(*app->lock)(app);
697 for (i = 0; i < app->dpy_destroy_count; i++) {
698 CloseDisplay(app->dpy_destroy_list[i]);
699 }
700 app->dpy_destroy_count = 0;
701 XtFree((char *) app->dpy_destroy_list);
702 app->dpy_destroy_list = NULL((void*)0);
703 UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app);
704}
705
706XtAppContext XtWidgetToApplicationContext(Widget w)
707{
708 XtAppContext retval;
709
710 retval = _XtGetPerDisplay(XtDisplayOfObject(w)((((Object)(w))->object.widget_class->core_class.class_inited
& 0x04) ? (w)->core.screen->display : _XtIsHookObject
(w) ? ((HookObject)(w))->hooks.screen->display : _XtWindowedAncestor
(w)->core.screen->display)
)->appContext;
711 return retval;
712}
713
714
715void XtGetApplicationNameAndClass(
716 Display *dpy,
717 String *name_return,
718 String *class_return)
719{
720 XtPerDisplay pd;
721
722 pd = _XtGetPerDisplay(dpy);
723 *name_return = XrmQuarkToString(pd->name);
724 *class_return = XrmQuarkToString(pd->class);
725}
726
727XtPerDisplay _XtGetPerDisplay (Display* display)
728{
729 XtPerDisplay retval;
730
731 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
732 retval = ((_XtperDisplayList != NULL((void*)0) &&
733 _XtperDisplayList->dpy == display)
734 ? &_XtperDisplayList->perDpy
735 : _XtSortPerDisplayList(display));
736 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
737 return retval;
738}
739
740XtPerDisplayInputRec* _XtGetPerDisplayInput(Display* display)
741{
742 XtPerDisplayInputRec* retval;
743 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
744 retval = ((_XtperDisplayList != NULL((void*)0) &&
745 _XtperDisplayList->dpy == display)
746 ? &_XtperDisplayList->perDpy.pdi
747 : &_XtSortPerDisplayList(display)->pdi);
748 UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)();
749 return retval;
750}
751
752void XtGetDisplays(
753 XtAppContext app_context,
754 Display*** dpy_return,
755 Cardinal* num_dpy_return)
756{
757 int ii;
758 LOCK_APP(app_context)if(app_context && app_context->lock)(*app_context->
lock)(app_context)
;
759 *num_dpy_return = app_context->count;
760 *dpy_return = (Display**)__XtMalloc(app_context->count * sizeof(Display*));
761 for (ii = 0; ii < app_context->count; ii++)
762 (*dpy_return)[ii] = app_context->list[ii];
763 UNLOCK_APP(app_context)if(app_context && app_context->unlock)(*app_context
->unlock)(app_context)
;
764}