diff options
Diffstat (limited to 'libXt/src/Intrinsic.c')
-rw-r--r-- | libXt/src/Intrinsic.c | 3219 |
1 files changed, 1608 insertions, 1611 deletions
diff --git a/libXt/src/Intrinsic.c b/libXt/src/Intrinsic.c index a25e2216e..727f7493d 100644 --- a/libXt/src/Intrinsic.c +++ b/libXt/src/Intrinsic.c @@ -1,1611 +1,1608 @@ -/* $Xorg: Intrinsic.c,v 1.4 2001/02/09 02:03:55 xorgcvs Exp $ */ - -/*********************************************************** -Copyright 1993 Sun Microsystems, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ -/* $XFree86: xc/lib/Xt/Intrinsic.c,v 3.22 2003/01/12 03:55:46 tsi Exp $ */ - -/* - -Copyright 1987, 1988, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ - -#define INTRINSIC_C - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "IntrinsicI.h" -#include "VarargsI.h" /* for geoTattler */ -#ifndef NO_IDENTIFY_WINDOWS -#include <X11/Xatom.h> -#endif -#ifndef VMS -#include <sys/stat.h> -#endif /* VMS */ - -#include <stdlib.h> - -String XtCXtToolkitError = "XtToolkitError"; - -Boolean XtIsSubclass( - Widget widget, - WidgetClass widgetClass) -{ - register WidgetClass w; - Boolean retval = FALSE; - WIDGET_TO_APPCON(widget); - - LOCK_APP(app); - LOCK_PROCESS; - for (w = widget->core.widget_class; w != NULL; w = w->core_class.superclass) - if (w == widgetClass) { - retval = TRUE; - break; - } - UNLOCK_PROCESS; - UNLOCK_APP(app); - return retval; -} /* XtIsSubclass */ - - -Boolean _XtCheckSubclassFlag( - Widget object, - _XtXtEnum flag) -{ - Boolean retval; - - LOCK_PROCESS; - if (object->core.widget_class->core_class.class_inited & flag) - retval = TRUE; - else - retval = FALSE; - UNLOCK_PROCESS; - return retval; -} /*_XtVerifySubclass */ - - -Boolean _XtIsSubclassOf( - Widget object, - WidgetClass widgetClass, - WidgetClass superClass, - _XtXtEnum flag) -{ - LOCK_PROCESS; - if (!(object->core.widget_class->core_class.class_inited & flag)) { - UNLOCK_PROCESS; - return False; - } else { - register WidgetClass c = object->core.widget_class; - while (c != superClass) { - if (c == widgetClass) { - UNLOCK_PROCESS; - return True; - } - c = c->core_class.superclass; - } - UNLOCK_PROCESS; - return False; - } -} /*_XtIsSubclassOf */ - - -XtPointer XtGetClassExtension( - WidgetClass object_class, - Cardinal byte_offset, - XrmQuark type, - long version, - Cardinal record_size) -{ - ObjectClassExtension ext; - LOCK_PROCESS; - - ext = *(ObjectClassExtension *)((char *)object_class + byte_offset); - while (ext && (ext->record_type != type || ext->version < version - || ext->record_size < record_size)) { - ext = (ObjectClassExtension) ext->next_extension; - } - - UNLOCK_PROCESS; - return (XtPointer) ext; -} - - -static void ComputeWindowAttributes( - Widget widget, - XtValueMask *value_mask, - XSetWindowAttributes *values) -{ - XtExposeProc expose; - - *value_mask = CWEventMask | CWColormap; - (*values).event_mask = XtBuildEventMask(widget); - (*values).colormap = widget->core.colormap; - if (widget->core.background_pixmap != XtUnspecifiedPixmap) { - *value_mask |= CWBackPixmap; - (*values).background_pixmap = widget->core.background_pixmap; - } else { - *value_mask |= CWBackPixel; - (*values).background_pixel = widget->core.background_pixel; - } - if (widget->core.border_pixmap != XtUnspecifiedPixmap) { - *value_mask |= CWBorderPixmap; - (*values).border_pixmap = widget->core.border_pixmap; - } else { - *value_mask |= CWBorderPixel; - (*values).border_pixel = widget->core.border_pixel; - } - LOCK_PROCESS; - expose = widget->core.widget_class->core_class.expose; - UNLOCK_PROCESS; - if (expose == (XtExposeProc) NULL) { - /* Try to avoid redisplay upon resize by making bit_gravity the same - as the default win_gravity */ - *value_mask |= CWBitGravity; - (*values).bit_gravity = NorthWestGravity; - } -} /* ComputeWindowAttributes */ - -static void CallChangeManaged( - register Widget widget) -{ - register Cardinal i; - XtWidgetProc change_managed; - register WidgetList children; - int managed_children = 0; - - register CompositePtr cpPtr; - register CompositePartPtr clPtr; - - if (XtIsComposite (widget)) { - cpPtr = (CompositePtr)&((CompositeWidget) widget)->composite; - clPtr = (CompositePartPtr)&((CompositeWidgetClass) - widget->core.widget_class)->composite_class; - } else return; - - children = cpPtr->children; - LOCK_PROCESS; - change_managed = clPtr->change_managed; - UNLOCK_PROCESS; - - /* CallChangeManaged for all children */ - for (i = cpPtr->num_children; i != 0; --i) { - CallChangeManaged (children[i-1]); - if (XtIsManaged(children[i-1])) managed_children++; - } - - if (change_managed != NULL && managed_children != 0) { - CALLGEOTAT(_XtGeoTrace(widget,"Call \"%s\"[%d,%d]'s changemanaged\n", - XtName(widget), - widget->core.width, widget->core.height)); - (*change_managed) (widget); - } -} /* CallChangeManaged */ - - -static void MapChildren( - CompositePart *cwp) -{ - Cardinal i; - WidgetList children; - register Widget child; - - children = cwp->children; - for (i = 0; i < cwp->num_children; i++) { - child = children[i]; - if (XtIsWidget (child)){ - if (child->core.managed && child->core.mapped_when_managed) { - XtMapWidget (children[i]); - } - } - } -} /* MapChildren */ - - -static Boolean ShouldMapAllChildren( - CompositePart *cwp) -{ - Cardinal i; - WidgetList children; - register Widget child; - - children = cwp->children; - for (i = 0; i < cwp->num_children; i++) { - child = children[i]; - if (XtIsWidget(child)) { - if (XtIsRealized(child) && (! (child->core.managed - && child->core.mapped_when_managed))){ - return False; - } - } - } - - return True; -} /* ShouldMapAllChildren */ - - -static void RealizeWidget( - Widget widget) -{ - XtValueMask value_mask; - XSetWindowAttributes values; - XtRealizeProc realize; - Window window; - Display* display; - String class_name; - Widget hookobj; - - if (!XtIsWidget(widget) || XtIsRealized(widget)) return; - display = XtDisplay(widget); - _XtInstallTranslations(widget); - - ComputeWindowAttributes (widget, &value_mask, &values); - LOCK_PROCESS; - realize = widget->core.widget_class->core_class.realize; - class_name = widget->core.widget_class->core_class.class_name; - UNLOCK_PROCESS; - if (realize == NULL) - XtAppErrorMsg(XtWidgetToApplicationContext(widget), - "invalidProcedure","realizeProc",XtCXtToolkitError, - "No realize class procedure defined", - (String *)NULL, (Cardinal *)NULL); - else { - CALLGEOTAT(_XtGeoTrace(widget,"Call \"%s\"[%d,%d]'s realize proc\n", - XtName(widget), - widget->core.width, widget->core.height)); - (*realize) (widget, &value_mask, &values); - } - window = XtWindow(widget); - hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); - if (XtHasCallbacks(hookobj,XtNchangeHook) == XtCallbackHasSome) { - XtChangeHookDataRec call_data; - - call_data.type = XtHrealizeWidget; - call_data.widget = widget; - XtCallCallbackList(hookobj, - ((HookObject)hookobj)->hooks.changehook_callbacks, - (XtPointer)&call_data); - } -#ifndef NO_IDENTIFY_WINDOWS - if (_XtGetPerDisplay(display)->appContext->identify_windows) { - int len_nm, len_cl; - char *s; - - len_nm = widget->core.name ? strlen(widget->core.name) : 0; - len_cl = strlen(class_name); - s = __XtMalloc((unsigned) (len_nm + len_cl + 2)); - s[0] = '\0'; - if (len_nm) - strcpy(s, widget->core.name); - strcpy(s + len_nm + 1, class_name); - XChangeProperty(display, window, - XInternAtom(display, "_MIT_OBJ_CLASS", - False), - XA_STRING, 8, PropModeReplace, (unsigned char *) s, - len_nm + len_cl + 2); - XtFree(s); - } -#endif -#ifdef notdef - _XtRegisterAsyncHandlers(widget); -#endif - /* (re)register any grabs extant in the translations */ - _XtRegisterGrabs(widget); - /* reregister any grabs added with XtGrab{Button,Key} */ - _XtRegisterPassiveGrabs(widget); - XtRegisterDrawable (display, window, widget); - _XtExtensionSelect(widget); - - if (XtIsComposite (widget)) { - Cardinal i; - CompositePart *cwp = &(((CompositeWidget)widget)->composite); - WidgetList children = cwp->children; - /* Realize all children */ - for (i = cwp->num_children; i != 0; --i) { - RealizeWidget (children[i-1]); - } - /* Map children that are managed and mapped_when_managed */ - - if (cwp->num_children != 0) { - if (ShouldMapAllChildren(cwp)) { - XMapSubwindows (display, window); - } else { - MapChildren(cwp); - } - } - } - - /* If this is the application's popup shell, map it */ - if (widget->core.parent == NULL && widget->core.mapped_when_managed) { - XtMapWidget (widget); - } -} /* RealizeWidget */ - -void XtRealizeWidget ( - Widget widget) -{ - WIDGET_TO_APPCON(widget); - - LOCK_APP(app); - if (XtIsRealized (widget)) { - UNLOCK_APP(app); - return; - } - CallChangeManaged(widget); - RealizeWidget(widget); - UNLOCK_APP(app); -} /* XtRealizeWidget */ - - -static void UnrealizeWidget( - Widget widget) -{ - CompositeWidget cw; - Cardinal i; - WidgetList children; - - if (!XtIsWidget(widget) || !XtIsRealized(widget)) return; - - /* If this is the application's popup shell, unmap it? */ - /* no, the window is being destroyed */ - - /* Recurse on children */ - if (XtIsComposite (widget)) { - cw = (CompositeWidget) widget; - children = cw->composite.children; - /* Unrealize all children */ - for (i = cw->composite.num_children; i != 0; --i) { - UnrealizeWidget (children[i-1]); - } - /* Unmap children that are managed and mapped_when_managed? */ - /* No, it's ok to be managed and unrealized as long as your parent */ - /* is unrealized. XtUnrealize widget makes sure the "top" widget */ - /* is unmanaged, we can ignore all descendents */ - } - - if (XtHasCallbacks(widget, XtNunrealizeCallback) == XtCallbackHasSome) - XtCallCallbacks(widget, XtNunrealizeCallback, NULL); - - /* Unregister window */ - XtUnregisterDrawable(XtDisplay(widget), XtWindow(widget)); - - /* Remove Event Handlers */ - /* remove grabs. Happens automatically when window is destroyed. */ - - /* Destroy X Window, done at outer level with one request */ - widget->core.window = None; - - /* Removing the event handler here saves having to keep track if - * the translation table is changed while the widget is unrealized. - */ - _XtRemoveTranslations(widget); -} /* UnrealizeWidget */ - - -void XtUnrealizeWidget ( - Widget widget) -{ - Window window; - Widget hookobj; - WIDGET_TO_APPCON(widget); - - LOCK_APP(app); - window = XtWindow(widget); - if (! XtIsRealized (widget)) { - UNLOCK_APP(app); - return; - } - if (widget->core.managed && widget->core.parent != NULL) - XtUnmanageChild(widget); - UnrealizeWidget(widget); - if (window != None) - XDestroyWindow(XtDisplay(widget), window); - hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); - if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { - XtChangeHookDataRec call_data; - - call_data.type = XtHunrealizeWidget; - call_data.widget = widget; - XtCallCallbackList(hookobj, - ((HookObject)hookobj)->hooks.changehook_callbacks, - (XtPointer)&call_data); - } - UNLOCK_APP(app); -} /* XtUnrealizeWidget */ - - -void XtCreateWindow( - Widget widget, - unsigned int window_class, - Visual *visual, - XtValueMask value_mask, - XSetWindowAttributes *attributes) -{ - XtAppContext app = XtWidgetToApplicationContext(widget); - - LOCK_APP(app); - if (widget->core.window == None) { - if (widget->core.width == 0 || widget->core.height == 0) { - Cardinal count = 1; - XtAppErrorMsg(app, - "invalidDimension", "xtCreateWindow", XtCXtToolkitError, - "Widget %s has zero width and/or height", - &widget->core.name, &count); - } - widget->core.window = - XCreateWindow ( - XtDisplay (widget), - (widget->core.parent ? - widget->core.parent->core.window : - widget->core.screen->root), - (int)widget->core.x, (int)widget->core.y, - (unsigned)widget->core.width, (unsigned)widget->core.height, - (unsigned)widget->core.border_width, (int) widget->core.depth, - window_class, visual, value_mask, attributes); - } - UNLOCK_APP(app); -} /* XtCreateWindow */ - - -/* ---------------- XtNameToWidget ----------------- */ - -static Widget NameListToWidget( - Widget root, - XrmNameList names, - XrmBindingList bindings, - int in_depth, int *out_depth, int *found_depth); - -typedef Widget (*NameMatchProc)(XrmNameList, - XrmBindingList, - WidgetList, Cardinal, int, int *, int *); - -static Widget MatchExactChildren( - XrmNameList names, - XrmBindingList bindings, - register WidgetList children, - register Cardinal num, - int in_depth, int *out_depth, int *found_depth) -{ - register Cardinal i; - register XrmName name = *names; - Widget w, result = NULL; - int d, min = 10000; - - for (i = 0; i < num; i++) { - if (name == children[i]->core.xrm_name) { - w = NameListToWidget(children[i], &names[1], &bindings[1], - in_depth+1, &d, found_depth); - if (w != NULL && d < min) {result = w; min = d;} - } - } - *out_depth = min; - return result; -} - -static Widget MatchWildChildren( - XrmNameList names, - XrmBindingList bindings, - register WidgetList children, - register Cardinal num, - int in_depth, int *out_depth, int *found_depth) -{ - register Cardinal i; - Widget w, result = NULL; - int d, min = 10000; - - for (i = 0; i < num; i++) { - w = NameListToWidget(children[i], names, bindings, - in_depth+1, &d, found_depth); - if (w != NULL && d < min) {result = w; min = d;} - } - *out_depth = min; - return result; -} - -static Widget SearchChildren( - Widget root, - XrmNameList names, - XrmBindingList bindings, - NameMatchProc matchproc, - int in_depth, int *out_depth, int *found_depth) -{ - Widget w1 = NULL, w2; - int d1, d2; - - if (XtIsComposite(root)) { - w1 = (*matchproc)(names, bindings, - ((CompositeWidget) root)->composite.children, - ((CompositeWidget) root)->composite.num_children, - in_depth, &d1, found_depth); - } else d1 = 10000; - w2 = (*matchproc)(names, bindings, root->core.popup_list, - root->core.num_popups, in_depth, &d2, found_depth); - *out_depth = (d1 < d2 ? d1 : d2); - return (d1 < d2 ? w1 : w2); -} - -static Widget NameListToWidget( - register Widget root, - XrmNameList names, - XrmBindingList bindings, - int in_depth, int *out_depth, int *found_depth) -{ - Widget w1, w2; - int d1, d2; - - if (in_depth >= *found_depth) { - *out_depth = 10000; - return NULL; - } - - if (names[0] == NULLQUARK) { - *out_depth = *found_depth = in_depth; - return root; - } - - if (! XtIsWidget(root)) { - *out_depth = 10000; - return NULL; - } - - if (*bindings == XrmBindTightly) { - return SearchChildren(root, names, bindings, MatchExactChildren, - in_depth, out_depth, found_depth); - - } else { /* XrmBindLoosely */ - w1 = SearchChildren(root, names, bindings, MatchExactChildren, - in_depth, &d1, found_depth); - w2 = SearchChildren(root, names, bindings, MatchWildChildren, - in_depth, &d2, found_depth); - *out_depth = (d1 < d2 ? d1 : d2); - return (d1 < d2 ? w1 : w2); - } -} /* NameListToWidget */ - -Widget XtNameToWidget( - Widget root, - _Xconst char* name) -{ - XrmName *names; - XrmBinding *bindings; - int len, depth, found = 10000; - Widget result; - WIDGET_TO_APPCON(root); - - len = strlen(name); - if (len == 0) return NULL; - - LOCK_APP(app); - names = (XrmName *) ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmName)); - bindings = (XrmBinding *) - ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmBinding)); - if (names == NULL || bindings == NULL) _XtAllocError(NULL); - - XrmStringToBindingQuarkList(name, bindings, names); - if (names[0] == NULLQUARK) { - DEALLOCATE_LOCAL((char *) bindings); - DEALLOCATE_LOCAL((char *) names); - UNLOCK_APP(app); - return NULL; - } - - result = NameListToWidget(root, names, bindings, 0, &depth, &found); - - DEALLOCATE_LOCAL((char *) bindings); - DEALLOCATE_LOCAL((char *) names); - UNLOCK_APP(app); - return result; -} /* XtNameToWidget */ - -/* Define user versions of intrinsics macros */ - -#undef XtDisplayOfObject -Display *XtDisplayOfObject( - Widget object) -{ - /* Attempts to LockApp() here will generate endless recursive loops */ - if (XtIsSubclass(object, hookObjectClass)) - return DisplayOfScreen(((HookObject)object)->hooks.screen); - return XtDisplay(XtIsWidget(object) ? object : _XtWindowedAncestor(object)); -} - -#undef XtDisplay -Display *XtDisplay( - Widget widget) -{ - /* Attempts to LockApp() here will generate endless recursive loops */ - return DisplayOfScreen(widget->core.screen); -} - -#undef XtScreenOfObject -Screen *XtScreenOfObject( - Widget object) -{ - /* Attempts to LockApp() here will generate endless recursive loops */ - if (XtIsSubclass(object, hookObjectClass)) - return ((HookObject)object)->hooks.screen; - return XtScreen(XtIsWidget(object) ? object : _XtWindowedAncestor(object)); -} - -#undef XtScreen -Screen *XtScreen( - Widget widget) -{ - /* Attempts to LockApp() here will generate endless recursive loops */ - return widget->core.screen; -} - -#undef XtWindowOfObject -Window XtWindowOfObject( - Widget object) -{ - return XtWindow(XtIsWidget(object) ? object : _XtWindowedAncestor(object)); -} - - -#undef XtWindow -Window XtWindow( - Widget widget) -{ - return widget->core.window; -} - -#undef XtSuperclass -WidgetClass XtSuperclass( - Widget widget) -{ - WidgetClass retval; - - LOCK_PROCESS; - retval = XtClass(widget)->core_class.superclass; - UNLOCK_PROCESS; - return retval; -} - -#undef XtClass -WidgetClass XtClass( - Widget widget) -{ - WidgetClass retval; - - LOCK_PROCESS; - retval = widget->core.widget_class; - UNLOCK_PROCESS; - return retval; -} - -#undef XtIsManaged -Boolean XtIsManaged( - Widget object) -{ - Boolean retval; - WIDGET_TO_APPCON(object); - - LOCK_APP(app); - if (XtIsRectObj(object)) - retval = object->core.managed; - else - retval = False; - UNLOCK_APP(app); - return retval; -} - -#undef XtIsRealized -Boolean XtIsRealized ( - Widget object) -{ - Boolean retval; - WIDGET_TO_APPCON(object); - - LOCK_APP(app); - retval = XtWindowOfObject(object) != None; - UNLOCK_APP(app); - return retval; -} /* XtIsRealized */ - -#undef XtIsSensitive -Boolean XtIsSensitive( - Widget object) -{ - Boolean retval; - WIDGET_TO_APPCON(object); - - LOCK_APP(app); - if (XtIsRectObj(object)) - retval = object->core.sensitive && object->core.ancestor_sensitive; - else - retval = False; - UNLOCK_APP(app); - return retval; -} - -/* - * Internal routine; must be called only after XtIsWidget returns false - */ -Widget _XtWindowedAncestor( - register Widget object) -{ - Widget obj = object; - for (object = XtParent(object); object && !XtIsWidget(object);) - object = XtParent(object); - - if (object == NULL) { - String params = XtName(obj); - Cardinal num_params = 1; - XtErrorMsg("noWidgetAncestor", "windowedAncestor", XtCXtToolkitError, - "Object \"%s\" does not have windowed ancestor", - ¶ms, &num_params); - } - - return object; -} - -#undef XtParent -Widget XtParent( - Widget widget) -{ - /* Attempts to LockApp() here will generate endless recursive loops */ - return widget->core.parent; -} - -#undef XtName -String XtName( - Widget object) -{ - /* Attempts to LockApp() here will generate endless recursive loops */ - return XrmQuarkToString(object->core.xrm_name); -} - - -Boolean XtIsObject( - Widget object) -{ - WidgetClass wc; - String class_name; - - /* perform basic sanity checks */ - if (object->core.self != object || object->core.xrm_name == NULLQUARK) - return False; - - LOCK_PROCESS; - wc = object->core.widget_class; - if (wc->core_class.class_name == NULL || - wc->core_class.xrm_class == NULLQUARK || - (class_name = XrmClassToString(wc->core_class.xrm_class)) == NULL || - strcmp(wc->core_class.class_name, class_name) != 0) { - UNLOCK_PROCESS; - return False; - } - UNLOCK_PROCESS; - - if (XtIsWidget(object)) { - if (object->core.name == NULL || - (class_name = XrmNameToString(object->core.xrm_name)) == NULL || - strcmp(object->core.name, class_name) != 0) - return False; - } - return True; -} - -#if defined(WIN32) -static int access_file ( - char* path, - char* pathbuf, - int len_pathbuf, - char** pathret) -{ - if (access (path, F_OK) == 0) { - if (strlen (path) < len_pathbuf) - *pathret = pathbuf; - else - *pathret = XtMalloc (strlen (path)); - if (*pathret) { - strcpy (*pathret, path); - return 1; - } - } - return 0; -} - -static int AccessFile ( - char* path, - char* pathbuf, - int len_pathbuf, - char** pathret) -{ - unsigned long drives; - int i, len; - char* drive; - char buf[MAX_PATH]; - char* bufp; - - /* just try the "raw" name first and see if it works */ - if (access_file (path, pathbuf, len_pathbuf, pathret)) - return 1; - -#if defined(WIN32) && defined(__MINGW32__) - /* don't try others */ - return 0; -#endif - - /* try the places set in the environment */ - drive = getenv ("_XBASEDRIVE"); -#ifdef __UNIXOS2__ - if (!drive) - drive = getenv ("X11ROOT"); -#endif - if (!drive) - drive = "C:"; - len = strlen (drive) + strlen (path); - bufp = XtStackAlloc (len + 1, buf); - strcpy (bufp, drive); - strcat (bufp, path); - if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { - XtStackFree (bufp, buf); - return 1; - } - -#ifndef __UNIXOS2__ - /* one last place to look */ - drive = getenv ("HOMEDRIVE"); - if (drive) { - len = strlen (drive) + strlen (path); - bufp = XtStackAlloc (len + 1, buf); - strcpy (bufp, drive); - strcat (bufp, path); - if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { - XtStackFree (bufp, buf); - return 1; - } - } - - /* does OS/2 (with or with gcc-emx) have getdrives()? */ - /* tried everywhere else, go fishing */ - drives = _getdrives (); -#define C_DRIVE ('C' - 'A') -#define Z_DRIVE ('Z' - 'A') - for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ - if ((1 << i) & drives) { - len = 2 + strlen (path); - bufp = XtStackAlloc (len + 1, buf); - *bufp = 'A' + i; - *(bufp + 1) = ':'; - *(bufp + 2) = '\0'; - strcat (bufp, path); - if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { - XtStackFree (bufp, buf); - return 1; - } - } - } -#endif - return 0; -} -#endif - -static Boolean TestFile( - String path) -{ -#ifndef VMS - int ret = 0; - struct stat status; -#if defined(WIN32) - char buf[MAX_PATH]; - char* bufp; - int len; - UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); - - if (AccessFile (path, buf, MAX_PATH, &bufp)) - path = bufp; - - (void) SetErrorMode (olderror); -#endif - ret = (access(path, R_OK) == 0 && /* exists and is readable */ - stat(path, &status) == 0 && /* get the status */ -#ifndef X_NOT_POSIX - S_ISDIR(status.st_mode) == 0); /* not a directory */ -#else - (status.st_mode & S_IFMT) != S_IFDIR); /* not a directory */ -#endif /* X_NOT_POSIX else */ - return ret; -#else /* VMS */ - return TRUE; /* Who knows what to do here? */ -#endif /* VMS */ -} - -/* return of TRUE = resolved string fit, FALSE = didn't fit. Not - null-terminated and not collapsed if it didn't fit */ - -static Boolean Resolve( - register _Xconst char *source, /* The source string */ - register int len, /* The length in bytes of *source */ - Substitution sub, /* Array of string values to substitute */ - Cardinal num, /* Number of substitution entries */ - char *buf, /* Where to put the resolved string; */ - char collapse) /* Character to collapse */ -{ - register int bytesLeft = PATH_MAX; - register char* bp = buf; -#ifndef DONT_COLLAPSE - Boolean atBeginning = TRUE; - Boolean prevIsCollapse = FALSE; - -#define PUT(ch) \ - { \ - if (--bytesLeft == 0) return FALSE; \ - if (prevIsCollapse) \ - if ((*bp = ch) != collapse) { \ - prevIsCollapse = FALSE; \ - bp++; \ - } \ - else bytesLeft++; \ - else if ((*bp++ = ch) == collapse && !atBeginning) \ - prevIsCollapse = TRUE; \ - } -#else /* DONT_COLLAPSE */ - -#define PUT(ch) \ - { \ - if (--bytesLeft == 0) return FALSE; \ - *bp++ = ch; \ - } -#endif /* DONT_COLLAPSE */ -#define escape '%' - - while (len--) { -#ifndef DONT_COLLAPSE - if (*source == collapse) { - PUT(*source); - source++; - continue; - } - else -#endif /* DONT_COLLAPSE */ - if (*source != escape) { - PUT(*source); - } - else { - source++; - if (len-- == 0) { - PUT(escape); - break; - } - - if (*source == ':' || *source == escape) - PUT(*source) - else { - /* Match the character against the match array */ - register Cardinal j; - - for (j = 0; j < num && sub[j].match != *source; j++) {} - - /* Substitute the substitution string */ - - if (j >= num) PUT(*source) - else if (sub[j].substitution != NULL) { - char *sp = sub[j].substitution; - while (*sp) { - PUT(*sp); - sp++; - } - } - } - } - source++; -#ifndef DONT_COLLAPSE - atBeginning = FALSE; -#endif /* DONT_COLLAPSE */ - } - PUT('\0'); - - return TRUE; -#undef PUT -#undef escape -} - - -String XtFindFile( - _Xconst char* path, - Substitution substitutions, - Cardinal num_substitutions, - XtFilePredicate predicate) -{ - char *buf, *buf1, *buf2, *colon; - int len; - Boolean firstTime = TRUE; - - buf = buf1 = __XtMalloc((unsigned)PATH_MAX); - buf2 = __XtMalloc((unsigned)PATH_MAX); - - if (predicate == NULL) predicate = TestFile; - - while (1) { - colon = (String)path; - /* skip leading colons */ - while (*colon) { - if (*colon != ':') break; - colon++; - path++; - } - /* now look for an un-escaped colon */ - for ( ; *colon ; colon++) { - if (*colon == '%' && *(path+1)) { - colon++; /* bump it an extra time to skip %. */ - continue; - } - if (*colon == ':') -#ifdef __UNIXOS2__ - if (colon > (path+1)) -#endif - break; - } - len = colon - path; - if (Resolve(path, len, substitutions, num_substitutions, - buf, '/')) { - if (firstTime || strcmp(buf1,buf2) != 0) { -#ifdef __UNIXOS2__ - { - char *bufx = (char*)__XOS2RedirRoot(buf); - strcpy(buf,bufx); - } -#endif -#ifdef XNL_DEBUG - printf("Testing file %s\n", buf); -#endif /* XNL_DEBUG */ - /* Check out the file */ - if ((*predicate) (buf)) { - /* We've found it, return it */ -#ifdef XNL_DEBUG - printf("File found.\n"); -#endif /* XNL_DEBUG */ - if (buf == buf1) XtFree(buf2); - else XtFree(buf1); - return buf; - } - if (buf == buf1) - buf = buf2; - else - buf = buf1; - firstTime = FALSE; - } - } - - /* Nope...any more paths? */ - - if (*colon == '\0') break; - path = colon+1; - } - - /* No file found */ - - XtFree(buf1); - XtFree(buf2); - return NULL; -} - - -/* The implementation of this routine is operating system dependent */ -/* Should match the code in Xlib _XlcMapOSLocaleName */ - -static char *ExtractLocaleName( - String lang) -{ - -#if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) || defined(__UNIXOS2__) || defined (linux) -# ifdef hpux -/* - * We need to discriminated between HPUX 9 and HPUX 10. The equivalent - * code in Xlib in SetLocale.c does include locale.h via X11/Xlocale.h. - */ -# include <locale.h> -# ifndef _LastCategory - /* HPUX 9 and earlier */ -# define SKIPCOUNT 2 -# define STARTCHAR ':' -# define ENDCHAR ';' -# else - /* HPUX 10 */ -# define ENDCHAR ' ' -# endif -# else -# ifdef ultrix -# define SKIPCOUNT 2 -# define STARTCHAR '\001' -# define ENDCHAR '\001' -# else -# if defined(WIN32) || defined(__UNIXOS2__) -# define SKIPCOUNT 1 -# define STARTCHAR '=' -# define ENDCHAR ';' -# define WHITEFILL -# else -# if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4)) -# define STARTCHAR ' ' -# define ENDCHAR ' ' -# else -# if defined(linux) -# define STARTSTR "LC_CTYPE=" -# define ENDCHAR ';' -# else -# if !defined(sun) || defined(SVR4) -# define STARTCHAR '/' -# define ENDCHAR '/' -# endif -# endif -# endif -# endif -# endif -# endif - - char *start; - char *end; - int len; -# ifdef SKIPCOUNT - int n; -# endif - static char* buf = NULL; - - start = lang; -# ifdef SKIPCOUNT - for (n = SKIPCOUNT; - --n >= 0 && start && (start = strchr (start, STARTCHAR)); - start++) - ; - if (!start) - start = lang; -# endif -# ifdef STARTCHAR - if (start && (start = strchr (start, STARTCHAR))) -# elif defined (STARTSTR) - if (start && (start = strstr (start,STARTSTR))) -# endif - { -# ifdef STARTCHAR - start++; -# elif defined (STARTSTR) - start += strlen(STARTSTR); -# endif - - if ((end = strchr (start, ENDCHAR))) { - len = end - start; - if (buf != NULL) XtFree (buf); - buf = XtMalloc (len + 1); - if (buf == NULL) return NULL; - strncpy(buf, start, len); - *(buf + len) = '\0'; -# ifdef WHITEFILL - for (start = buf; start = strchr(start, ' '); ) - *start++ = '-'; -# endif - return buf; - } else /* if no ENDCHAR is found we are at the end of the line */ - return start; - } -# ifdef WHITEFILL - if (strchr(lang, ' ')) { - if (buf != NULL) XtFree (buf); - else buf = XtMalloc (strlen (lang) + 1); - if (buf == NULL) return NULL; - strcpy(buf, lang); - for (start = buf; start = strchr(start, ' '); ) - *start++ = '-'; - return buf; - } -# endif -# undef STARTCHAR -# undef ENDCHAR -# undef WHITEFILL -#endif - - return lang; -} - -static void FillInLangSubs( - Substitution subs, - XtPerDisplay pd) -{ - int len; - char *string, *p1, *p2, *p3; - char **rest; - char *ch; - - if (pd->language == NULL || - (pd->language != NULL && pd->language[0] == '\0')) { - subs[0].substitution = subs[1].substitution = - subs[2].substitution = subs[3].substitution = NULL; - return; - } - - string = ExtractLocaleName(pd->language); - - if (string == NULL || - (string != NULL && string[0] == '\0')) { - subs[0].substitution = subs[1].substitution = - subs[2].substitution = subs[3].substitution = NULL; - return; - } - - len = strlen(string) + 1; - subs[0].substitution = string; - p1 = subs[1].substitution = __XtMalloc((Cardinal) 3*len); - p2 = subs[2].substitution = subs[1].substitution + len; - p3 = subs[3].substitution = subs[2].substitution + len; - - /* Everything up to the first "_" goes into p1. From "_" to "." in - p2. The rest in p3. If no delimiters, all goes into p1. We - assume p1, p2, and p3 are large enough. */ - - *p1 = *p2 = *p3 = '\0'; - - ch = strchr(string, '_'); - if (ch != NULL) { - len = ch - string; - (void) strncpy(p1, string, len); - p1[len] = '\0'; - string = ch + 1; - rest = &p2; - } else rest = &p1; - - /* Rest points to where we put the first part */ - - ch = strchr(string, '.'); - if (ch != NULL) { - len = ch - string; - strncpy(*rest, string, len); - (*rest)[len] = '\0'; - (void) strcpy(p3, ch+1); - } else (void) strcpy(*rest, string); -} - -/* - * default path used if environment variable XFILESEARCHPATH - * is not defined. Also substitued for %D. - * The exact value should be documented in the implementation - * notes for any Xt implementation. - */ -static char *implementation_default_path(void) -{ -#if defined(WIN32) - static char xfilesearchpath[] = ":"; - - return xfilesearchpath; -#elif defined(__UNIXOS2__) - /* if you know how to pass % thru the compiler let me know */ - static char xfilesearchpath[] = XFILESEARCHPATHDEFAULT; - static Bool fixed; - char *ch; - - if (!fixed) { - for (ch = xfilesearchpath; ch = strchr(ch, ';'); ch++) - *ch = '%'; - fixed = True; - } - return xfilesearchpath; -#else - return XFILESEARCHPATHDEFAULT; -#endif -} - - -static SubstitutionRec defaultSubs[] = { - {'N', NULL}, - {'T', NULL}, - {'S', NULL}, - {'C', NULL}, - {'L', NULL}, - {'l', NULL}, - {'t', NULL}, - {'c', NULL} -}; - - -String XtResolvePathname( - Display *dpy, - _Xconst char* type, - _Xconst char* filename, - _Xconst char* suffix, - _Xconst char* path, - Substitution substitutions, - Cardinal num_substitutions, - XtFilePredicate predicate) -{ - XtPerDisplay pd; - static char *defaultPath = NULL; - char *impl_default = implementation_default_path(); - int idef_len = strlen(impl_default); - char *massagedPath; - int bytesAllocd, bytesLeft; - char *ch, *result; - Substitution merged_substitutions; - XrmRepresentation db_type; - XrmValue value; - XrmName name_list[3]; - XrmClass class_list[3]; - Boolean pathMallocd = False; - - LOCK_PROCESS; - pd = _XtGetPerDisplay(dpy); - if (path == NULL) { -#ifndef VMS - if (defaultPath == NULL) { - defaultPath = getenv("XFILESEARCHPATH"); - if (defaultPath == NULL) - defaultPath = impl_default; - } - path = defaultPath; -#endif /* VMS */ - } - - if (path == NULL) - path = ""; /* NULL would kill us later */ - - if (filename == NULL) { - filename = XrmClassToString(pd->class); - } - - bytesAllocd = bytesLeft = 1000; - massagedPath = ALLOCATE_LOCAL(bytesAllocd); - if (massagedPath == NULL) _XtAllocError(NULL); - - if (path[0] == ':') { - strcpy(massagedPath, "%N%S"); - ch = &massagedPath[4]; - bytesLeft -= 4; - } else ch = massagedPath; - - /* Insert %N%S between adjacent colons - * and default path for %D. - * Default path should not have any adjacent colons of its own. - */ - - while (*path != '\0') { - if (bytesLeft < idef_len) { - int bytesUsed = bytesAllocd - bytesLeft; - char *new; - bytesAllocd +=1000; - new = __XtMalloc((Cardinal) bytesAllocd); - strncpy( new, massagedPath, bytesUsed ); - ch = new + bytesUsed; - if (pathMallocd) - XtFree(massagedPath); - else - DEALLOCATE_LOCAL(massagedPath); - pathMallocd = True; - massagedPath = new; - bytesLeft = bytesAllocd - bytesUsed; - } - if (*path == '%' && *(path+1) == ':') { - *ch++ = '%'; - *ch++ = ':'; - path += 2; - bytesLeft -= 2; - continue; - } - if (*path == ':' && *(path+1) == ':') { - strcpy(ch, ":%N%S:"); - ch += 6; - bytesLeft -= 6; - while (*path == ':') path++; - continue; - } - if (*path == '%' && *(path+1) == 'D') { - strcpy(ch, impl_default); - ch += idef_len; - bytesLeft -= idef_len; - path += 2; - continue; - } - *ch++ = *path++; - bytesLeft--; - } - *ch = '\0'; -#ifdef XNL_DEBUG - printf("Massaged path: %s\n", massagedPath); -#endif /* XNL_DEBUG */ - - if (num_substitutions == 0) - merged_substitutions = defaultSubs; - else { - int i = XtNumber(defaultSubs); - Substitution sub, def; - merged_substitutions = sub = (Substitution) - ALLOCATE_LOCAL((unsigned)(num_substitutions+i)*sizeof(SubstitutionRec)); - if (sub == NULL) _XtAllocError(NULL); - for (def = defaultSubs; i--; sub++, def++) sub->match = def->match; - for (i = num_substitutions; i--; ) *sub++ = *substitutions++; - } - merged_substitutions[0].substitution = (String)filename; - merged_substitutions[1].substitution = (String)type; - merged_substitutions[2].substitution = (String)suffix; - name_list[0] = pd->name; - name_list[1] = XrmPermStringToQuark("customization"); - name_list[2] = NULLQUARK; - class_list[0] = pd->class; - class_list[1] = XrmPermStringToQuark("Customization"); - class_list[2] = NULLQUARK; - if (XrmQGetResource(XrmGetDatabase(dpy), name_list, class_list, - &db_type, &value) && - db_type == _XtQString) - merged_substitutions[3].substitution = (char *)value.addr; - else - merged_substitutions[3].substitution = NULL; - FillInLangSubs(&merged_substitutions[4], pd); - - result = XtFindFile(massagedPath, merged_substitutions, - num_substitutions + XtNumber(defaultSubs), - predicate); - - if (merged_substitutions[5].substitution != NULL) - XtFree( (XtPointer)merged_substitutions[5].substitution ); - - if (merged_substitutions != defaultSubs) - DEALLOCATE_LOCAL(merged_substitutions); - - if (pathMallocd) - XtFree(massagedPath); - else - DEALLOCATE_LOCAL(massagedPath); - - UNLOCK_PROCESS; - return result; -} - - -Boolean XtCallAcceptFocus( - Widget widget, - Time *time) -{ - XtAcceptFocusProc ac; - Boolean retval; - WIDGET_TO_APPCON(widget); - - LOCK_APP(app); - LOCK_PROCESS; - ac = XtClass(widget)->core_class.accept_focus; - UNLOCK_PROCESS; - - if (ac != NULL) - retval = (*ac) (widget, time); - else - retval = FALSE; - UNLOCK_APP(app); - return retval; -} - -#ifdef XT_GEO_TATTLER -/************************************************************************** - GeoTattler: This is used to debug Geometry management in Xt. - - It uses a pseudo resource XtNgeotattler. - - E.G. if those lines are found in the resource database: - - myapp*draw.XmScale.geoTattler: ON - *XmScrollBar.geoTattler:ON - *XmRowColumn.exit_button.geoTattler:ON - - then: - - all the XmScale children of the widget named draw, - all the XmScrollBars, - the widget named exit_button in any XmRowColumn - - will return True to the function IsTattled(), and will generate - outlined trace to stdout. - -*************************************************************************/ - -#define XtNgeoTattler "geoTattler" -#define XtCGeoTattler "GeoTattler" - -typedef struct { Boolean geo_tattler ;} GeoDataRec ; - -static XtResource geo_resources[] = { - { XtNgeoTattler, XtCGeoTattler, XtRBoolean, sizeof(Boolean), - XtOffsetOf(GeoDataRec, geo_tattler), - XtRImmediate, (XtPointer) False } -}; - -/************************************************************************ - This function uses XtGetSubresources to find out if a widget - needs to be geo-spied by the caller. */ -static Boolean IsTattled (Widget widget) -{ - GeoDataRec geo_data ; - - XtGetSubresources(widget, (XtPointer)&geo_data, - (String)NULL, (String)NULL, - geo_resources, XtNumber(geo_resources), - NULL, 0); - - return geo_data.geo_tattler; - -} /* IsTattled */ - -static int n_tab = 0 ; /* not MT for now */ - -void -_XtGeoTab (int direction) /* +1 or -1 */ -{ - n_tab += direction ; -} - - -void -_XtGeoTrace (Widget widget, ...) -{ - va_list args; - char *fmt; - int i ; - if (IsTattled(widget)) { - va_start(args, widget); - fmt = va_arg(args, char *); - for (i=0; i<n_tab; i++) printf(" "); - (void) vprintf(fmt, args); - va_end(args); - } -} - -#endif /* XT_GEO_TATTLER */ - +/***********************************************************
+Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+
+Copyright 1987, 1988, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#define INTRINSIC_C
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "IntrinsicI.h"
+#include "VarargsI.h" /* for geoTattler */
+#ifndef NO_IDENTIFY_WINDOWS
+#include <X11/Xatom.h>
+#endif
+#ifndef VMS
+#include <sys/stat.h>
+#endif /* VMS */
+
+#include <stdlib.h>
+
+String XtCXtToolkitError = "XtToolkitError";
+
+Boolean XtIsSubclass(
+ Widget widget,
+ WidgetClass widgetClass)
+{
+ register WidgetClass w;
+ Boolean retval = FALSE;
+ WIDGET_TO_APPCON(widget);
+
+ LOCK_APP(app);
+ LOCK_PROCESS;
+ for (w = widget->core.widget_class; w != NULL; w = w->core_class.superclass)
+ if (w == widgetClass) {
+ retval = TRUE;
+ break;
+ }
+ UNLOCK_PROCESS;
+ UNLOCK_APP(app);
+ return retval;
+} /* XtIsSubclass */
+
+
+Boolean _XtCheckSubclassFlag(
+ Widget object,
+ _XtXtEnum flag)
+{
+ Boolean retval;
+
+ LOCK_PROCESS;
+ if (object->core.widget_class->core_class.class_inited & flag)
+ retval = TRUE;
+ else
+ retval = FALSE;
+ UNLOCK_PROCESS;
+ return retval;
+} /*_XtVerifySubclass */
+
+
+Boolean _XtIsSubclassOf(
+ Widget object,
+ WidgetClass widgetClass,
+ WidgetClass superClass,
+ _XtXtEnum flag)
+{
+ LOCK_PROCESS;
+ if (!(object->core.widget_class->core_class.class_inited & flag)) {
+ UNLOCK_PROCESS;
+ return False;
+ } else {
+ register WidgetClass c = object->core.widget_class;
+ while (c != superClass) {
+ if (c == widgetClass) {
+ UNLOCK_PROCESS;
+ return True;
+ }
+ c = c->core_class.superclass;
+ }
+ UNLOCK_PROCESS;
+ return False;
+ }
+} /*_XtIsSubclassOf */
+
+
+XtPointer XtGetClassExtension(
+ WidgetClass object_class,
+ Cardinal byte_offset,
+ XrmQuark type,
+ long version,
+ Cardinal record_size)
+{
+ ObjectClassExtension ext;
+ LOCK_PROCESS;
+
+ ext = *(ObjectClassExtension *)((char *)object_class + byte_offset);
+ while (ext && (ext->record_type != type || ext->version < version
+ || ext->record_size < record_size)) {
+ ext = (ObjectClassExtension) ext->next_extension;
+ }
+
+ UNLOCK_PROCESS;
+ return (XtPointer) ext;
+}
+
+
+static void ComputeWindowAttributes(
+ Widget widget,
+ XtValueMask *value_mask,
+ XSetWindowAttributes *values)
+{
+ XtExposeProc expose;
+
+ *value_mask = CWEventMask | CWColormap;
+ (*values).event_mask = XtBuildEventMask(widget);
+ (*values).colormap = widget->core.colormap;
+ if (widget->core.background_pixmap != XtUnspecifiedPixmap) {
+ *value_mask |= CWBackPixmap;
+ (*values).background_pixmap = widget->core.background_pixmap;
+ } else {
+ *value_mask |= CWBackPixel;
+ (*values).background_pixel = widget->core.background_pixel;
+ }
+ if (widget->core.border_pixmap != XtUnspecifiedPixmap) {
+ *value_mask |= CWBorderPixmap;
+ (*values).border_pixmap = widget->core.border_pixmap;
+ } else {
+ *value_mask |= CWBorderPixel;
+ (*values).border_pixel = widget->core.border_pixel;
+ }
+ LOCK_PROCESS;
+ expose = widget->core.widget_class->core_class.expose;
+ UNLOCK_PROCESS;
+ if (expose == (XtExposeProc) NULL) {
+ /* Try to avoid redisplay upon resize by making bit_gravity the same
+ as the default win_gravity */
+ *value_mask |= CWBitGravity;
+ (*values).bit_gravity = NorthWestGravity;
+ }
+} /* ComputeWindowAttributes */
+
+static void CallChangeManaged(
+ register Widget widget)
+{
+ register Cardinal i;
+ XtWidgetProc change_managed;
+ register WidgetList children;
+ int managed_children = 0;
+
+ register CompositePtr cpPtr;
+ register CompositePartPtr clPtr;
+
+ if (XtIsComposite (widget)) {
+ cpPtr = (CompositePtr)&((CompositeWidget) widget)->composite;
+ clPtr = (CompositePartPtr)&((CompositeWidgetClass)
+ widget->core.widget_class)->composite_class;
+ } else return;
+
+ children = cpPtr->children;
+ LOCK_PROCESS;
+ change_managed = clPtr->change_managed;
+ UNLOCK_PROCESS;
+
+ /* CallChangeManaged for all children */
+ for (i = cpPtr->num_children; i != 0; --i) {
+ CallChangeManaged (children[i-1]);
+ if (XtIsManaged(children[i-1])) managed_children++;
+ }
+
+ if (change_managed != NULL && managed_children != 0) {
+ CALLGEOTAT(_XtGeoTrace(widget,"Call \"%s\"[%d,%d]'s changemanaged\n",
+ XtName(widget),
+ widget->core.width, widget->core.height));
+ (*change_managed) (widget);
+ }
+} /* CallChangeManaged */
+
+
+static void MapChildren(
+ CompositePart *cwp)
+{
+ Cardinal i;
+ WidgetList children;
+ register Widget child;
+
+ children = cwp->children;
+ for (i = 0; i < cwp->num_children; i++) {
+ child = children[i];
+ if (XtIsWidget (child)){
+ if (child->core.managed && child->core.mapped_when_managed) {
+ XtMapWidget (children[i]);
+ }
+ }
+ }
+} /* MapChildren */
+
+
+static Boolean ShouldMapAllChildren(
+ CompositePart *cwp)
+{
+ Cardinal i;
+ WidgetList children;
+ register Widget child;
+
+ children = cwp->children;
+ for (i = 0; i < cwp->num_children; i++) {
+ child = children[i];
+ if (XtIsWidget(child)) {
+ if (XtIsRealized(child) && (! (child->core.managed
+ && child->core.mapped_when_managed))){
+ return False;
+ }
+ }
+ }
+
+ return True;
+} /* ShouldMapAllChildren */
+
+
+static void RealizeWidget(
+ Widget widget)
+{
+ XtValueMask value_mask;
+ XSetWindowAttributes values;
+ XtRealizeProc realize;
+ Window window;
+ Display* display;
+ String class_name;
+ Widget hookobj;
+
+ if (!XtIsWidget(widget) || XtIsRealized(widget)) return;
+ display = XtDisplay(widget);
+ _XtInstallTranslations(widget);
+
+ ComputeWindowAttributes (widget, &value_mask, &values);
+ LOCK_PROCESS;
+ realize = widget->core.widget_class->core_class.realize;
+ class_name = widget->core.widget_class->core_class.class_name;
+ UNLOCK_PROCESS;
+ if (realize == NULL)
+ XtAppErrorMsg(XtWidgetToApplicationContext(widget),
+ "invalidProcedure","realizeProc",XtCXtToolkitError,
+ "No realize class procedure defined",
+ (String *)NULL, (Cardinal *)NULL);
+ else {
+ CALLGEOTAT(_XtGeoTrace(widget,"Call \"%s\"[%d,%d]'s realize proc\n",
+ XtName(widget),
+ widget->core.width, widget->core.height));
+ (*realize) (widget, &value_mask, &values);
+ }
+ window = XtWindow(widget);
+ hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
+ if (XtHasCallbacks(hookobj,XtNchangeHook) == XtCallbackHasSome) {
+ XtChangeHookDataRec call_data;
+
+ call_data.type = XtHrealizeWidget;
+ call_data.widget = widget;
+ XtCallCallbackList(hookobj,
+ ((HookObject)hookobj)->hooks.changehook_callbacks,
+ (XtPointer)&call_data);
+ }
+#ifndef NO_IDENTIFY_WINDOWS
+ if (_XtGetPerDisplay(display)->appContext->identify_windows) {
+ int len_nm, len_cl;
+ char *s;
+
+ len_nm = widget->core.name ? strlen(widget->core.name) : 0;
+ len_cl = strlen(class_name);
+ s = __XtMalloc((unsigned) (len_nm + len_cl + 2));
+ s[0] = '\0';
+ if (len_nm)
+ strcpy(s, widget->core.name);
+ strcpy(s + len_nm + 1, class_name);
+ XChangeProperty(display, window,
+ XInternAtom(display, "_MIT_OBJ_CLASS",
+ False),
+ XA_STRING, 8, PropModeReplace, (unsigned char *) s,
+ len_nm + len_cl + 2);
+ XtFree(s);
+ }
+#endif
+#ifdef notdef
+ _XtRegisterAsyncHandlers(widget);
+#endif
+ /* (re)register any grabs extant in the translations */
+ _XtRegisterGrabs(widget);
+ /* reregister any grabs added with XtGrab{Button,Key} */
+ _XtRegisterPassiveGrabs(widget);
+ XtRegisterDrawable (display, window, widget);
+ _XtExtensionSelect(widget);
+
+ if (XtIsComposite (widget)) {
+ Cardinal i;
+ CompositePart *cwp = &(((CompositeWidget)widget)->composite);
+ WidgetList children = cwp->children;
+ /* Realize all children */
+ for (i = cwp->num_children; i != 0; --i) {
+ RealizeWidget (children[i-1]);
+ }
+ /* Map children that are managed and mapped_when_managed */
+
+ if (cwp->num_children != 0) {
+ if (ShouldMapAllChildren(cwp)) {
+ XMapSubwindows (display, window);
+ } else {
+ MapChildren(cwp);
+ }
+ }
+ }
+
+ /* If this is the application's popup shell, map it */
+ if (widget->core.parent == NULL && widget->core.mapped_when_managed) {
+ XtMapWidget (widget);
+ }
+} /* RealizeWidget */
+
+void XtRealizeWidget (
+ Widget widget)
+{
+ WIDGET_TO_APPCON(widget);
+
+ LOCK_APP(app);
+ if (XtIsRealized (widget)) {
+ UNLOCK_APP(app);
+ return;
+ }
+ CallChangeManaged(widget);
+ RealizeWidget(widget);
+ UNLOCK_APP(app);
+} /* XtRealizeWidget */
+
+
+static void UnrealizeWidget(
+ Widget widget)
+{
+ CompositeWidget cw;
+ Cardinal i;
+ WidgetList children;
+
+ if (!XtIsWidget(widget) || !XtIsRealized(widget)) return;
+
+ /* If this is the application's popup shell, unmap it? */
+ /* no, the window is being destroyed */
+
+ /* Recurse on children */
+ if (XtIsComposite (widget)) {
+ cw = (CompositeWidget) widget;
+ children = cw->composite.children;
+ /* Unrealize all children */
+ for (i = cw->composite.num_children; i != 0; --i) {
+ UnrealizeWidget (children[i-1]);
+ }
+ /* Unmap children that are managed and mapped_when_managed? */
+ /* No, it's ok to be managed and unrealized as long as your parent */
+ /* is unrealized. XtUnrealize widget makes sure the "top" widget */
+ /* is unmanaged, we can ignore all descendents */
+ }
+
+ if (XtHasCallbacks(widget, XtNunrealizeCallback) == XtCallbackHasSome)
+ XtCallCallbacks(widget, XtNunrealizeCallback, NULL);
+
+ /* Unregister window */
+ XtUnregisterDrawable(XtDisplay(widget), XtWindow(widget));
+
+ /* Remove Event Handlers */
+ /* remove grabs. Happens automatically when window is destroyed. */
+
+ /* Destroy X Window, done at outer level with one request */
+ widget->core.window = None;
+
+ /* Removing the event handler here saves having to keep track if
+ * the translation table is changed while the widget is unrealized.
+ */
+ _XtRemoveTranslations(widget);
+} /* UnrealizeWidget */
+
+
+void XtUnrealizeWidget (
+ Widget widget)
+{
+ Window window;
+ Widget hookobj;
+ WIDGET_TO_APPCON(widget);
+
+ LOCK_APP(app);
+ window = XtWindow(widget);
+ if (! XtIsRealized (widget)) {
+ UNLOCK_APP(app);
+ return;
+ }
+ if (widget->core.managed && widget->core.parent != NULL)
+ XtUnmanageChild(widget);
+ UnrealizeWidget(widget);
+ if (window != None)
+ XDestroyWindow(XtDisplay(widget), window);
+ hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
+ if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
+ XtChangeHookDataRec call_data;
+
+ call_data.type = XtHunrealizeWidget;
+ call_data.widget = widget;
+ XtCallCallbackList(hookobj,
+ ((HookObject)hookobj)->hooks.changehook_callbacks,
+ (XtPointer)&call_data);
+ }
+ UNLOCK_APP(app);
+} /* XtUnrealizeWidget */
+
+
+void XtCreateWindow(
+ Widget widget,
+ unsigned int window_class,
+ Visual *visual,
+ XtValueMask value_mask,
+ XSetWindowAttributes *attributes)
+{
+ XtAppContext app = XtWidgetToApplicationContext(widget);
+
+ LOCK_APP(app);
+ if (widget->core.window == None) {
+ if (widget->core.width == 0 || widget->core.height == 0) {
+ Cardinal count = 1;
+ XtAppErrorMsg(app,
+ "invalidDimension", "xtCreateWindow", XtCXtToolkitError,
+ "Widget %s has zero width and/or height",
+ &widget->core.name, &count);
+ }
+ widget->core.window =
+ XCreateWindow (
+ XtDisplay (widget),
+ (widget->core.parent ?
+ widget->core.parent->core.window :
+ widget->core.screen->root),
+ (int)widget->core.x, (int)widget->core.y,
+ (unsigned)widget->core.width, (unsigned)widget->core.height,
+ (unsigned)widget->core.border_width, (int) widget->core.depth,
+ window_class, visual, value_mask, attributes);
+ }
+ UNLOCK_APP(app);
+} /* XtCreateWindow */
+
+
+/* ---------------- XtNameToWidget ----------------- */
+
+static Widget NameListToWidget(
+ Widget root,
+ XrmNameList names,
+ XrmBindingList bindings,
+ int in_depth, int *out_depth, int *found_depth);
+
+typedef Widget (*NameMatchProc)(XrmNameList,
+ XrmBindingList,
+ WidgetList, Cardinal, int, int *, int *);
+
+static Widget MatchExactChildren(
+ XrmNameList names,
+ XrmBindingList bindings,
+ register WidgetList children,
+ register Cardinal num,
+ int in_depth, int *out_depth, int *found_depth)
+{
+ register Cardinal i;
+ register XrmName name = *names;
+ Widget w, result = NULL;
+ int d, min = 10000;
+
+ for (i = 0; i < num; i++) {
+ if (name == children[i]->core.xrm_name) {
+ w = NameListToWidget(children[i], &names[1], &bindings[1],
+ in_depth+1, &d, found_depth);
+ if (w != NULL && d < min) {result = w; min = d;}
+ }
+ }
+ *out_depth = min;
+ return result;
+}
+
+static Widget MatchWildChildren(
+ XrmNameList names,
+ XrmBindingList bindings,
+ register WidgetList children,
+ register Cardinal num,
+ int in_depth, int *out_depth, int *found_depth)
+{
+ register Cardinal i;
+ Widget w, result = NULL;
+ int d, min = 10000;
+
+ for (i = 0; i < num; i++) {
+ w = NameListToWidget(children[i], names, bindings,
+ in_depth+1, &d, found_depth);
+ if (w != NULL && d < min) {result = w; min = d;}
+ }
+ *out_depth = min;
+ return result;
+}
+
+static Widget SearchChildren(
+ Widget root,
+ XrmNameList names,
+ XrmBindingList bindings,
+ NameMatchProc matchproc,
+ int in_depth, int *out_depth, int *found_depth)
+{
+ Widget w1 = NULL, w2;
+ int d1, d2;
+
+ if (XtIsComposite(root)) {
+ w1 = (*matchproc)(names, bindings,
+ ((CompositeWidget) root)->composite.children,
+ ((CompositeWidget) root)->composite.num_children,
+ in_depth, &d1, found_depth);
+ } else d1 = 10000;
+ w2 = (*matchproc)(names, bindings, root->core.popup_list,
+ root->core.num_popups, in_depth, &d2, found_depth);
+ *out_depth = (d1 < d2 ? d1 : d2);
+ return (d1 < d2 ? w1 : w2);
+}
+
+static Widget NameListToWidget(
+ register Widget root,
+ XrmNameList names,
+ XrmBindingList bindings,
+ int in_depth, int *out_depth, int *found_depth)
+{
+ Widget w1, w2;
+ int d1, d2;
+
+ if (in_depth >= *found_depth) {
+ *out_depth = 10000;
+ return NULL;
+ }
+
+ if (names[0] == NULLQUARK) {
+ *out_depth = *found_depth = in_depth;
+ return root;
+ }
+
+ if (! XtIsWidget(root)) {
+ *out_depth = 10000;
+ return NULL;
+ }
+
+ if (*bindings == XrmBindTightly) {
+ return SearchChildren(root, names, bindings, MatchExactChildren,
+ in_depth, out_depth, found_depth);
+
+ } else { /* XrmBindLoosely */
+ w1 = SearchChildren(root, names, bindings, MatchExactChildren,
+ in_depth, &d1, found_depth);
+ w2 = SearchChildren(root, names, bindings, MatchWildChildren,
+ in_depth, &d2, found_depth);
+ *out_depth = (d1 < d2 ? d1 : d2);
+ return (d1 < d2 ? w1 : w2);
+ }
+} /* NameListToWidget */
+
+Widget XtNameToWidget(
+ Widget root,
+ _Xconst char* name)
+{
+ XrmName *names;
+ XrmBinding *bindings;
+ int len, depth, found = 10000;
+ Widget result;
+ WIDGET_TO_APPCON(root);
+
+ len = strlen(name);
+ if (len == 0) return NULL;
+
+ LOCK_APP(app);
+ names = (XrmName *) ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmName));
+ bindings = (XrmBinding *)
+ ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmBinding));
+ if (names == NULL || bindings == NULL) _XtAllocError(NULL);
+
+ XrmStringToBindingQuarkList(name, bindings, names);
+ if (names[0] == NULLQUARK) {
+ DEALLOCATE_LOCAL((char *) bindings);
+ DEALLOCATE_LOCAL((char *) names);
+ UNLOCK_APP(app);
+ return NULL;
+ }
+
+ result = NameListToWidget(root, names, bindings, 0, &depth, &found);
+
+ DEALLOCATE_LOCAL((char *) bindings);
+ DEALLOCATE_LOCAL((char *) names);
+ UNLOCK_APP(app);
+ return result;
+} /* XtNameToWidget */
+
+/* Define user versions of intrinsics macros */
+
+#undef XtDisplayOfObject
+Display *XtDisplayOfObject(
+ Widget object)
+{
+ /* Attempts to LockApp() here will generate endless recursive loops */
+ if (XtIsSubclass(object, hookObjectClass))
+ return DisplayOfScreen(((HookObject)object)->hooks.screen);
+ return XtDisplay(XtIsWidget(object) ? object : _XtWindowedAncestor(object));
+}
+
+#undef XtDisplay
+Display *XtDisplay(
+ Widget widget)
+{
+ /* Attempts to LockApp() here will generate endless recursive loops */
+ return DisplayOfScreen(widget->core.screen);
+}
+
+#undef XtScreenOfObject
+Screen *XtScreenOfObject(
+ Widget object)
+{
+ /* Attempts to LockApp() here will generate endless recursive loops */
+ if (XtIsSubclass(object, hookObjectClass))
+ return ((HookObject)object)->hooks.screen;
+ return XtScreen(XtIsWidget(object) ? object : _XtWindowedAncestor(object));
+}
+
+#undef XtScreen
+Screen *XtScreen(
+ Widget widget)
+{
+ /* Attempts to LockApp() here will generate endless recursive loops */
+ return widget->core.screen;
+}
+
+#undef XtWindowOfObject
+Window XtWindowOfObject(
+ Widget object)
+{
+ return XtWindow(XtIsWidget(object) ? object : _XtWindowedAncestor(object));
+}
+
+
+#undef XtWindow
+Window XtWindow(
+ Widget widget)
+{
+ return widget->core.window;
+}
+
+#undef XtSuperclass
+WidgetClass XtSuperclass(
+ Widget widget)
+{
+ WidgetClass retval;
+
+ LOCK_PROCESS;
+ retval = XtClass(widget)->core_class.superclass;
+ UNLOCK_PROCESS;
+ return retval;
+}
+
+#undef XtClass
+WidgetClass XtClass(
+ Widget widget)
+{
+ WidgetClass retval;
+
+ LOCK_PROCESS;
+ retval = widget->core.widget_class;
+ UNLOCK_PROCESS;
+ return retval;
+}
+
+#undef XtIsManaged
+Boolean XtIsManaged(
+ Widget object)
+{
+ Boolean retval;
+ WIDGET_TO_APPCON(object);
+
+ LOCK_APP(app);
+ if (XtIsRectObj(object))
+ retval = object->core.managed;
+ else
+ retval = False;
+ UNLOCK_APP(app);
+ return retval;
+}
+
+#undef XtIsRealized
+Boolean XtIsRealized (
+ Widget object)
+{
+ Boolean retval;
+ WIDGET_TO_APPCON(object);
+
+ LOCK_APP(app);
+ retval = XtWindowOfObject(object) != None;
+ UNLOCK_APP(app);
+ return retval;
+} /* XtIsRealized */
+
+#undef XtIsSensitive
+Boolean XtIsSensitive(
+ Widget object)
+{
+ Boolean retval;
+ WIDGET_TO_APPCON(object);
+
+ LOCK_APP(app);
+ if (XtIsRectObj(object))
+ retval = object->core.sensitive && object->core.ancestor_sensitive;
+ else
+ retval = False;
+ UNLOCK_APP(app);
+ return retval;
+}
+
+/*
+ * Internal routine; must be called only after XtIsWidget returns false
+ */
+Widget _XtWindowedAncestor(
+ register Widget object)
+{
+ Widget obj = object;
+ for (object = XtParent(object); object && !XtIsWidget(object);)
+ object = XtParent(object);
+
+ if (object == NULL) {
+ String params = XtName(obj);
+ Cardinal num_params = 1;
+ XtErrorMsg("noWidgetAncestor", "windowedAncestor", XtCXtToolkitError,
+ "Object \"%s\" does not have windowed ancestor",
+ ¶ms, &num_params);
+ }
+
+ return object;
+}
+
+#undef XtParent
+Widget XtParent(
+ Widget widget)
+{
+ /* Attempts to LockApp() here will generate endless recursive loops */
+ return widget->core.parent;
+}
+
+#undef XtName
+String XtName(
+ Widget object)
+{
+ /* Attempts to LockApp() here will generate endless recursive loops */
+ return XrmQuarkToString(object->core.xrm_name);
+}
+
+
+Boolean XtIsObject(
+ Widget object)
+{
+ WidgetClass wc;
+ String class_name;
+
+ /* perform basic sanity checks */
+ if (object->core.self != object || object->core.xrm_name == NULLQUARK)
+ return False;
+
+ LOCK_PROCESS;
+ wc = object->core.widget_class;
+ if (wc->core_class.class_name == NULL ||
+ wc->core_class.xrm_class == NULLQUARK ||
+ (class_name = XrmClassToString(wc->core_class.xrm_class)) == NULL ||
+ strcmp(wc->core_class.class_name, class_name) != 0) {
+ UNLOCK_PROCESS;
+ return False;
+ }
+ UNLOCK_PROCESS;
+
+ if (XtIsWidget(object)) {
+ if (object->core.name == NULL ||
+ (class_name = XrmNameToString(object->core.xrm_name)) == NULL ||
+ strcmp(object->core.name, class_name) != 0)
+ return False;
+ }
+ return True;
+}
+
+#if defined(WIN32)
+static int access_file (
+ char* path,
+ char* pathbuf,
+ int len_pathbuf,
+ char** pathret)
+{
+ if (access (path, F_OK) == 0) {
+ if (strlen (path) < len_pathbuf)
+ *pathret = pathbuf;
+ else
+ *pathret = XtMalloc (strlen (path));
+ if (*pathret) {
+ strcpy (*pathret, path);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int AccessFile (
+ char* path,
+ char* pathbuf,
+ int len_pathbuf,
+ char** pathret)
+{
+ unsigned long drives;
+ int i, len;
+ char* drive;
+ char buf[MAX_PATH];
+ char* bufp;
+
+ /* just try the "raw" name first and see if it works */
+ if (access_file (path, pathbuf, len_pathbuf, pathret))
+ return 1;
+
+#if defined(WIN32) && defined(__MINGW32__)
+ /* don't try others */
+ return 0;
+#endif
+
+ /* try the places set in the environment */
+ drive = getenv ("_XBASEDRIVE");
+#ifdef __UNIXOS2__
+ if (!drive)
+ drive = getenv ("X11ROOT");
+#endif
+ if (!drive)
+ drive = "C:";
+ len = strlen (drive) + strlen (path);
+ bufp = XtStackAlloc (len + 1, buf);
+ strcpy (bufp, drive);
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ XtStackFree (bufp, buf);
+ return 1;
+ }
+
+#ifndef __UNIXOS2__
+ /* one last place to look */
+ drive = getenv ("HOMEDRIVE");
+ if (drive) {
+ len = strlen (drive) + strlen (path);
+ bufp = XtStackAlloc (len + 1, buf);
+ strcpy (bufp, drive);
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ XtStackFree (bufp, buf);
+ return 1;
+ }
+ }
+
+ /* does OS/2 (with or with gcc-emx) have getdrives()? */
+ /* tried everywhere else, go fishing */
+ drives = _getdrives ();
+#define C_DRIVE ('C' - 'A')
+#define Z_DRIVE ('Z' - 'A')
+ for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */
+ if ((1 << i) & drives) {
+ len = 2 + strlen (path);
+ bufp = XtStackAlloc (len + 1, buf);
+ *bufp = 'A' + i;
+ *(bufp + 1) = ':';
+ *(bufp + 2) = '\0';
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ XtStackFree (bufp, buf);
+ return 1;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+#endif
+
+static Boolean TestFile(
+ String path)
+{
+#ifndef VMS
+ int ret = 0;
+ struct stat status;
+#if defined(WIN32)
+ char buf[MAX_PATH];
+ char* bufp;
+ int len;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ path = bufp;
+
+ (void) SetErrorMode (olderror);
+#endif
+ ret = (access(path, R_OK) == 0 && /* exists and is readable */
+ stat(path, &status) == 0 && /* get the status */
+#ifndef X_NOT_POSIX
+ S_ISDIR(status.st_mode) == 0); /* not a directory */
+#else
+ (status.st_mode & S_IFMT) != S_IFDIR); /* not a directory */
+#endif /* X_NOT_POSIX else */
+ return ret;
+#else /* VMS */
+ return TRUE; /* Who knows what to do here? */
+#endif /* VMS */
+}
+
+/* return of TRUE = resolved string fit, FALSE = didn't fit. Not
+ null-terminated and not collapsed if it didn't fit */
+
+static Boolean Resolve(
+ register _Xconst char *source, /* The source string */
+ register int len, /* The length in bytes of *source */
+ Substitution sub, /* Array of string values to substitute */
+ Cardinal num, /* Number of substitution entries */
+ char *buf, /* Where to put the resolved string; */
+ char collapse) /* Character to collapse */
+{
+ register int bytesLeft = PATH_MAX;
+ register char* bp = buf;
+#ifndef DONT_COLLAPSE
+ Boolean atBeginning = TRUE;
+ Boolean prevIsCollapse = FALSE;
+
+#define PUT(ch) \
+ { \
+ if (--bytesLeft == 0) return FALSE; \
+ if (prevIsCollapse) \
+ if ((*bp = ch) != collapse) { \
+ prevIsCollapse = FALSE; \
+ bp++; \
+ } \
+ else bytesLeft++; \
+ else if ((*bp++ = ch) == collapse && !atBeginning) \
+ prevIsCollapse = TRUE; \
+ }
+#else /* DONT_COLLAPSE */
+
+#define PUT(ch) \
+ { \
+ if (--bytesLeft == 0) return FALSE; \
+ *bp++ = ch; \
+ }
+#endif /* DONT_COLLAPSE */
+#define escape '%'
+
+ while (len--) {
+#ifndef DONT_COLLAPSE
+ if (*source == collapse) {
+ PUT(*source);
+ source++;
+ continue;
+ }
+ else
+#endif /* DONT_COLLAPSE */
+ if (*source != escape) {
+ PUT(*source);
+ }
+ else {
+ source++;
+ if (len-- == 0) {
+ PUT(escape);
+ break;
+ }
+
+ if (*source == ':' || *source == escape)
+ PUT(*source)
+ else {
+ /* Match the character against the match array */
+ register Cardinal j;
+
+ for (j = 0; j < num && sub[j].match != *source; j++) {}
+
+ /* Substitute the substitution string */
+
+ if (j >= num) PUT(*source)
+ else if (sub[j].substitution != NULL) {
+ char *sp = sub[j].substitution;
+ while (*sp) {
+ PUT(*sp);
+ sp++;
+ }
+ }
+ }
+ }
+ source++;
+#ifndef DONT_COLLAPSE
+ atBeginning = FALSE;
+#endif /* DONT_COLLAPSE */
+ }
+ PUT('\0');
+
+ return TRUE;
+#undef PUT
+#undef escape
+}
+
+
+String XtFindFile(
+ _Xconst char* path,
+ Substitution substitutions,
+ Cardinal num_substitutions,
+ XtFilePredicate predicate)
+{
+ char *buf, *buf1, *buf2, *colon;
+ int len;
+ Boolean firstTime = TRUE;
+
+ buf = buf1 = __XtMalloc((unsigned)PATH_MAX);
+ buf2 = __XtMalloc((unsigned)PATH_MAX);
+
+ if (predicate == NULL) predicate = TestFile;
+
+ while (1) {
+ colon = (String)path;
+ /* skip leading colons */
+ while (*colon) {
+ if (*colon != ':') break;
+ colon++;
+ path++;
+ }
+ /* now look for an un-escaped colon */
+ for ( ; *colon ; colon++) {
+ if (*colon == '%' && *(path+1)) {
+ colon++; /* bump it an extra time to skip %. */
+ continue;
+ }
+ if (*colon == ':')
+#ifdef __UNIXOS2__
+ if (colon > (path+1))
+#endif
+ break;
+ }
+ len = colon - path;
+ if (Resolve(path, len, substitutions, num_substitutions,
+ buf, '/')) {
+ if (firstTime || strcmp(buf1,buf2) != 0) {
+#ifdef __UNIXOS2__
+ {
+ char *bufx = (char*)__XOS2RedirRoot(buf);
+ strcpy(buf,bufx);
+ }
+#endif
+#ifdef XNL_DEBUG
+ printf("Testing file %s\n", buf);
+#endif /* XNL_DEBUG */
+ /* Check out the file */
+ if ((*predicate) (buf)) {
+ /* We've found it, return it */
+#ifdef XNL_DEBUG
+ printf("File found.\n");
+#endif /* XNL_DEBUG */
+ if (buf == buf1) XtFree(buf2);
+ else XtFree(buf1);
+ return buf;
+ }
+ if (buf == buf1)
+ buf = buf2;
+ else
+ buf = buf1;
+ firstTime = FALSE;
+ }
+ }
+
+ /* Nope...any more paths? */
+
+ if (*colon == '\0') break;
+ path = colon+1;
+ }
+
+ /* No file found */
+
+ XtFree(buf1);
+ XtFree(buf2);
+ return NULL;
+}
+
+
+/* The implementation of this routine is operating system dependent */
+/* Should match the code in Xlib _XlcMapOSLocaleName */
+
+static char *ExtractLocaleName(
+ String lang)
+{
+
+#if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) || defined(__UNIXOS2__) || defined (linux)
+# ifdef hpux
+/*
+ * We need to discriminated between HPUX 9 and HPUX 10. The equivalent
+ * code in Xlib in SetLocale.c does include locale.h via X11/Xlocale.h.
+ */
+# include <locale.h>
+# ifndef _LastCategory
+ /* HPUX 9 and earlier */
+# define SKIPCOUNT 2
+# define STARTCHAR ':'
+# define ENDCHAR ';'
+# else
+ /* HPUX 10 */
+# define ENDCHAR ' '
+# endif
+# else
+# ifdef ultrix
+# define SKIPCOUNT 2
+# define STARTCHAR '\001'
+# define ENDCHAR '\001'
+# else
+# if defined(WIN32) || defined(__UNIXOS2__)
+# define SKIPCOUNT 1
+# define STARTCHAR '='
+# define ENDCHAR ';'
+# define WHITEFILL
+# else
+# if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4))
+# define STARTCHAR ' '
+# define ENDCHAR ' '
+# else
+# if defined(linux)
+# define STARTSTR "LC_CTYPE="
+# define ENDCHAR ';'
+# else
+# if !defined(sun) || defined(SVR4)
+# define STARTCHAR '/'
+# define ENDCHAR '/'
+# endif
+# endif
+# endif
+# endif
+# endif
+# endif
+
+ char *start;
+ char *end;
+ int len;
+# ifdef SKIPCOUNT
+ int n;
+# endif
+ static char* buf = NULL;
+
+ start = lang;
+# ifdef SKIPCOUNT
+ for (n = SKIPCOUNT;
+ --n >= 0 && start && (start = strchr (start, STARTCHAR));
+ start++)
+ ;
+ if (!start)
+ start = lang;
+# endif
+# ifdef STARTCHAR
+ if (start && (start = strchr (start, STARTCHAR)))
+# elif defined (STARTSTR)
+ if (start && (start = strstr (start,STARTSTR)))
+# endif
+ {
+# ifdef STARTCHAR
+ start++;
+# elif defined (STARTSTR)
+ start += strlen(STARTSTR);
+# endif
+
+ if ((end = strchr (start, ENDCHAR))) {
+ len = end - start;
+ if (buf != NULL) XtFree (buf);
+ buf = XtMalloc (len + 1);
+ if (buf == NULL) return NULL;
+ strncpy(buf, start, len);
+ *(buf + len) = '\0';
+# ifdef WHITEFILL
+ for (start = buf; start = strchr(start, ' '); )
+ *start++ = '-';
+# endif
+ return buf;
+ } else /* if no ENDCHAR is found we are at the end of the line */
+ return start;
+ }
+# ifdef WHITEFILL
+ if (strchr(lang, ' ')) {
+ if (buf != NULL) XtFree (buf);
+ else buf = XtMalloc (strlen (lang) + 1);
+ if (buf == NULL) return NULL;
+ strcpy(buf, lang);
+ for (start = buf; start = strchr(start, ' '); )
+ *start++ = '-';
+ return buf;
+ }
+# endif
+# undef STARTCHAR
+# undef ENDCHAR
+# undef WHITEFILL
+#endif
+
+ return lang;
+}
+
+static void FillInLangSubs(
+ Substitution subs,
+ XtPerDisplay pd)
+{
+ int len;
+ char *string, *p1, *p2, *p3;
+ char **rest;
+ char *ch;
+
+ if (pd->language == NULL ||
+ (pd->language != NULL && pd->language[0] == '\0')) {
+ subs[0].substitution = subs[1].substitution =
+ subs[2].substitution = subs[3].substitution = NULL;
+ return;
+ }
+
+ string = ExtractLocaleName(pd->language);
+
+ if (string == NULL ||
+ (string != NULL && string[0] == '\0')) {
+ subs[0].substitution = subs[1].substitution =
+ subs[2].substitution = subs[3].substitution = NULL;
+ return;
+ }
+
+ len = strlen(string) + 1;
+ subs[0].substitution = string;
+ p1 = subs[1].substitution = __XtMalloc((Cardinal) 3*len);
+ p2 = subs[2].substitution = subs[1].substitution + len;
+ p3 = subs[3].substitution = subs[2].substitution + len;
+
+ /* Everything up to the first "_" goes into p1. From "_" to "." in
+ p2. The rest in p3. If no delimiters, all goes into p1. We
+ assume p1, p2, and p3 are large enough. */
+
+ *p1 = *p2 = *p3 = '\0';
+
+ ch = strchr(string, '_');
+ if (ch != NULL) {
+ len = ch - string;
+ (void) strncpy(p1, string, len);
+ p1[len] = '\0';
+ string = ch + 1;
+ rest = &p2;
+ } else rest = &p1;
+
+ /* Rest points to where we put the first part */
+
+ ch = strchr(string, '.');
+ if (ch != NULL) {
+ len = ch - string;
+ strncpy(*rest, string, len);
+ (*rest)[len] = '\0';
+ (void) strcpy(p3, ch+1);
+ } else (void) strcpy(*rest, string);
+}
+
+/*
+ * default path used if environment variable XFILESEARCHPATH
+ * is not defined. Also substitued for %D.
+ * The exact value should be documented in the implementation
+ * notes for any Xt implementation.
+ */
+static char *implementation_default_path(void)
+{
+#if defined(WIN32)
+ static char xfilesearchpath[] = ":";
+
+ return xfilesearchpath;
+#elif defined(__UNIXOS2__)
+ /* if you know how to pass % thru the compiler let me know */
+ static char xfilesearchpath[] = XFILESEARCHPATHDEFAULT;
+ static Bool fixed;
+ char *ch;
+
+ if (!fixed) {
+ for (ch = xfilesearchpath; ch = strchr(ch, ';'); ch++)
+ *ch = '%';
+ fixed = True;
+ }
+ return xfilesearchpath;
+#else
+ return XFILESEARCHPATHDEFAULT;
+#endif
+}
+
+
+static SubstitutionRec defaultSubs[] = {
+ {'N', NULL},
+ {'T', NULL},
+ {'S', NULL},
+ {'C', NULL},
+ {'L', NULL},
+ {'l', NULL},
+ {'t', NULL},
+ {'c', NULL}
+};
+
+
+String XtResolvePathname(
+ Display *dpy,
+ _Xconst char* type,
+ _Xconst char* filename,
+ _Xconst char* suffix,
+ _Xconst char* path,
+ Substitution substitutions,
+ Cardinal num_substitutions,
+ XtFilePredicate predicate)
+{
+ XtPerDisplay pd;
+ static char *defaultPath = NULL;
+ char *impl_default = implementation_default_path();
+ int idef_len = strlen(impl_default);
+ char *massagedPath;
+ int bytesAllocd, bytesLeft;
+ char *ch, *result;
+ Substitution merged_substitutions;
+ XrmRepresentation db_type;
+ XrmValue value;
+ XrmName name_list[3];
+ XrmClass class_list[3];
+ Boolean pathMallocd = False;
+
+ LOCK_PROCESS;
+ pd = _XtGetPerDisplay(dpy);
+ if (path == NULL) {
+#ifndef VMS
+ if (defaultPath == NULL) {
+ defaultPath = getenv("XFILESEARCHPATH");
+ if (defaultPath == NULL)
+ defaultPath = impl_default;
+ }
+ path = defaultPath;
+#endif /* VMS */
+ }
+
+ if (path == NULL)
+ path = ""; /* NULL would kill us later */
+
+ if (filename == NULL) {
+ filename = XrmClassToString(pd->class);
+ }
+
+ bytesAllocd = bytesLeft = 1000;
+ massagedPath = ALLOCATE_LOCAL(bytesAllocd);
+ if (massagedPath == NULL) _XtAllocError(NULL);
+
+ if (path[0] == ':') {
+ strcpy(massagedPath, "%N%S");
+ ch = &massagedPath[4];
+ bytesLeft -= 4;
+ } else ch = massagedPath;
+
+ /* Insert %N%S between adjacent colons
+ * and default path for %D.
+ * Default path should not have any adjacent colons of its own.
+ */
+
+ while (*path != '\0') {
+ if (bytesLeft < idef_len) {
+ int bytesUsed = bytesAllocd - bytesLeft;
+ char *new;
+ bytesAllocd +=1000;
+ new = __XtMalloc((Cardinal) bytesAllocd);
+ strncpy( new, massagedPath, bytesUsed );
+ ch = new + bytesUsed;
+ if (pathMallocd)
+ XtFree(massagedPath);
+ else
+ DEALLOCATE_LOCAL(massagedPath);
+ pathMallocd = True;
+ massagedPath = new;
+ bytesLeft = bytesAllocd - bytesUsed;
+ }
+ if (*path == '%' && *(path+1) == ':') {
+ *ch++ = '%';
+ *ch++ = ':';
+ path += 2;
+ bytesLeft -= 2;
+ continue;
+ }
+ if (*path == ':' && *(path+1) == ':') {
+ strcpy(ch, ":%N%S:");
+ ch += 6;
+ bytesLeft -= 6;
+ while (*path == ':') path++;
+ continue;
+ }
+ if (*path == '%' && *(path+1) == 'D') {
+ strcpy(ch, impl_default);
+ ch += idef_len;
+ bytesLeft -= idef_len;
+ path += 2;
+ continue;
+ }
+ *ch++ = *path++;
+ bytesLeft--;
+ }
+ *ch = '\0';
+#ifdef XNL_DEBUG
+ printf("Massaged path: %s\n", massagedPath);
+#endif /* XNL_DEBUG */
+
+ if (num_substitutions == 0)
+ merged_substitutions = defaultSubs;
+ else {
+ int i = XtNumber(defaultSubs);
+ Substitution sub, def;
+ merged_substitutions = sub = (Substitution)
+ ALLOCATE_LOCAL((unsigned)(num_substitutions+i)*sizeof(SubstitutionRec));
+ if (sub == NULL) _XtAllocError(NULL);
+ for (def = defaultSubs; i--; sub++, def++) sub->match = def->match;
+ for (i = num_substitutions; i--; ) *sub++ = *substitutions++;
+ }
+ merged_substitutions[0].substitution = (String)filename;
+ merged_substitutions[1].substitution = (String)type;
+ merged_substitutions[2].substitution = (String)suffix;
+ name_list[0] = pd->name;
+ name_list[1] = XrmPermStringToQuark("customization");
+ name_list[2] = NULLQUARK;
+ class_list[0] = pd->class;
+ class_list[1] = XrmPermStringToQuark("Customization");
+ class_list[2] = NULLQUARK;
+ if (XrmQGetResource(XrmGetDatabase(dpy), name_list, class_list,
+ &db_type, &value) &&
+ db_type == _XtQString)
+ merged_substitutions[3].substitution = (char *)value.addr;
+ else
+ merged_substitutions[3].substitution = NULL;
+ FillInLangSubs(&merged_substitutions[4], pd);
+
+ result = XtFindFile(massagedPath, merged_substitutions,
+ num_substitutions + XtNumber(defaultSubs),
+ predicate);
+
+ if (merged_substitutions[5].substitution != NULL)
+ XtFree( (XtPointer)merged_substitutions[5].substitution );
+
+ if (merged_substitutions != defaultSubs)
+ DEALLOCATE_LOCAL(merged_substitutions);
+
+ if (pathMallocd)
+ XtFree(massagedPath);
+ else
+ DEALLOCATE_LOCAL(massagedPath);
+
+ UNLOCK_PROCESS;
+ return result;
+}
+
+
+Boolean XtCallAcceptFocus(
+ Widget widget,
+ Time *time)
+{
+ XtAcceptFocusProc ac;
+ Boolean retval;
+ WIDGET_TO_APPCON(widget);
+
+ LOCK_APP(app);
+ LOCK_PROCESS;
+ ac = XtClass(widget)->core_class.accept_focus;
+ UNLOCK_PROCESS;
+
+ if (ac != NULL)
+ retval = (*ac) (widget, time);
+ else
+ retval = FALSE;
+ UNLOCK_APP(app);
+ return retval;
+}
+
+#ifdef XT_GEO_TATTLER
+/**************************************************************************
+ GeoTattler: This is used to debug Geometry management in Xt.
+
+ It uses a pseudo resource XtNgeotattler.
+
+ E.G. if those lines are found in the resource database:
+
+ myapp*draw.XmScale.geoTattler: ON
+ *XmScrollBar.geoTattler:ON
+ *XmRowColumn.exit_button.geoTattler:ON
+
+ then:
+
+ all the XmScale children of the widget named draw,
+ all the XmScrollBars,
+ the widget named exit_button in any XmRowColumn
+
+ will return True to the function IsTattled(), and will generate
+ outlined trace to stdout.
+
+*************************************************************************/
+
+#define XtNgeoTattler "geoTattler"
+#define XtCGeoTattler "GeoTattler"
+
+typedef struct { Boolean geo_tattler ;} GeoDataRec ;
+
+static XtResource geo_resources[] = {
+ { XtNgeoTattler, XtCGeoTattler, XtRBoolean, sizeof(Boolean),
+ XtOffsetOf(GeoDataRec, geo_tattler),
+ XtRImmediate, (XtPointer) False }
+};
+
+/************************************************************************
+ This function uses XtGetSubresources to find out if a widget
+ needs to be geo-spied by the caller. */
+static Boolean IsTattled (Widget widget)
+{
+ GeoDataRec geo_data ;
+
+ XtGetSubresources(widget, (XtPointer)&geo_data,
+ (String)NULL, (String)NULL,
+ geo_resources, XtNumber(geo_resources),
+ NULL, 0);
+
+ return geo_data.geo_tattler;
+
+} /* IsTattled */
+
+static int n_tab = 0 ; /* not MT for now */
+
+void
+_XtGeoTab (int direction) /* +1 or -1 */
+{
+ n_tab += direction ;
+}
+
+
+void
+_XtGeoTrace (Widget widget, ...)
+{
+ va_list args;
+ char *fmt;
+ int i ;
+ if (IsTattled(widget)) {
+ va_start(args, widget);
+ fmt = va_arg(args, char *);
+ for (i=0; i<n_tab; i++) printf(" ");
+ (void) vprintf(fmt, args);
+ va_end(args);
+ }
+}
+
+#endif /* XT_GEO_TATTLER */
+
|