428
+ − 1 /* Defines some widget utility functions.
+ − 2 Copyright (C) 1992 Lucid, Inc.
+ − 3
+ − 4 This file is part of the Lucid Widget Library.
+ − 5
+ − 6 The Lucid Widget Library is free software; you can redistribute it and/or
+ − 7 modify it under the terms of the GNU General Public License as published by
+ − 8 the Free Software Foundation; either version 1, or (at your option)
+ − 9 any later version.
+ − 10
+ − 11 The Lucid Widget Library is distributed in the hope that it will be useful,
+ − 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ − 14 GNU General Public License for more details.
+ − 15
+ − 16 You should have received a copy of the GNU General Public License
+ − 17 along with XEmacs; see the file COPYING. If not, write to
+ − 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 19 Boston, MA 02111-1307, USA. */
+ − 20
+ − 21 #include <config.h>
+ − 22 #include <stdlib.h>
+ − 23 #include <string.h>
+ − 24 #include <memory.h>
+ − 25 #ifdef HAVE_UNISTD_H
+ − 26 #include <unistd.h>
+ − 27 #endif
+ − 28
+ − 29 #include <X11/Xatom.h>
+ − 30 #include <X11/IntrinsicP.h>
+ − 31 #include <X11/ObjectP.h>
+ − 32 #include "lwlib-utils.h"
+ − 33
+ − 34 void
+ − 35 destroy_all_children (Widget widget)
+ − 36 {
+ − 37 Widget* children;
+ − 38 unsigned int number;
+ − 39 int i;
+ − 40
+ − 41 children = XtCompositeChildren (widget, &number);
+ − 42 if (children)
+ − 43 {
+ − 44 /* Unmanage all children and destroy them. They will only be
+ − 45 * really destroyed when we get out of DispatchEvent. */
487
+ − 46 for (i = 0; i < (int) number; i++)
428
+ − 47 {
+ − 48 Widget child = children [i];
+ − 49 if (!child->core.being_destroyed)
+ − 50 {
+ − 51 XtUnmanageChild (child);
+ − 52 XtDestroyWidget (child);
+ − 53 }
+ − 54 }
+ − 55 XtFree ((char *) children);
+ − 56 }
+ − 57 }
+ − 58
+ − 59 /* Redisplay the contents of the widget, without first clearing it. */
+ − 60 void
+ − 61 XtNoClearRefreshWidget (Widget widget)
+ − 62 {
+ − 63 XEvent event;
+ − 64 XExposeEvent* ev = &event.xexpose;
+ − 65
+ − 66 ev->type = Expose;
+ − 67 ev->serial = 0;
+ − 68 ev->send_event = 0;
+ − 69 ev->display = XtDisplay (widget);
+ − 70 ev->window = XtWindow (widget);
+ − 71 ev->x = 0;
+ − 72 ev->y = 0;
+ − 73 ev->width = widget->core.width;
+ − 74 ev->height = widget->core.height;
+ − 75 ev->count = 0;
+ − 76
+ − 77 (*widget->core.widget_class->core_class.expose)
+ − 78 (widget, &event, (Region)NULL);
+ − 79 }
+ − 80
+ − 81
+ − 82 /*
+ − 83 * Apply a function to all the subwidgets of a given widget recursively.
+ − 84 */
+ − 85 void
+ − 86 XtApplyToWidgets (Widget w, XtApplyToWidgetsProc proc, XtPointer arg)
+ − 87 {
+ − 88 if (XtIsComposite (w))
+ − 89 {
+ − 90 CompositeWidget cw = (CompositeWidget) w;
+ − 91 /* We have to copy the children list before mapping over it, because
+ − 92 the procedure might add/delete elements, which would lose badly. */
+ − 93 int nkids = cw->composite.num_children;
+ − 94 Widget *kids = (Widget *) malloc (sizeof (Widget) * nkids);
+ − 95 int i;
+ − 96 memcpy (kids, cw->composite.children, sizeof (Widget) * nkids);
+ − 97 for (i = 0; i < nkids; i++)
+ − 98 /* This prevent us from using gadgets, why is it here? */
+ − 99 /* if (XtIsWidget (kids [i])) */
+ − 100 {
+ − 101 /* do the kiddies first in case we're destroying */
+ − 102 XtApplyToWidgets (kids [i], proc, arg);
+ − 103 proc (kids [i], arg);
+ − 104 }
+ − 105 free (kids);
+ − 106 }
+ − 107 }
+ − 108
+ − 109
+ − 110 /*
+ − 111 * Apply a function to all the subwidgets of a given widget recursively.
+ − 112 * Stop as soon as the function returns non NULL and returns this as a value.
+ − 113 */
+ − 114 void *
+ − 115 XtApplyUntilToWidgets (Widget w, XtApplyUntilToWidgetsProc proc, XtPointer arg)
+ − 116 {
+ − 117 void* result;
+ − 118 if (XtIsComposite (w))
+ − 119 {
+ − 120 CompositeWidget cw = (CompositeWidget)w;
+ − 121 int i;
647
+ − 122 for (i = 0; i < (int) cw->composite.num_children; i++)
+ − 123 if (XtIsWidget (cw->composite.children[i]))
+ − 124 {
+ − 125 result = proc (cw->composite.children[i], arg);
+ − 126 if (result)
+ − 127 return result;
+ − 128 result = XtApplyUntilToWidgets (cw->composite.children[i], proc,
+ − 129 arg);
+ − 130 if (result)
+ − 131 return result;
+ − 132 }
428
+ − 133 }
+ − 134 return NULL;
+ − 135 }
+ − 136
+ − 137
+ − 138 /*
+ − 139 * Returns a copy of the list of all children of a composite widget
+ − 140 */
+ − 141 Widget *
+ − 142 XtCompositeChildren (Widget widget, unsigned int* number)
+ − 143 {
+ − 144 CompositeWidget cw = (CompositeWidget)widget;
+ − 145 Widget* result;
+ − 146 int n;
+ − 147 int i;
+ − 148
+ − 149 if (!XtIsComposite (widget))
+ − 150 {
+ − 151 *number = 0;
+ − 152 return NULL;
+ − 153 }
+ − 154 n = cw->composite.num_children;
+ − 155 result = (Widget*)XtMalloc (n * sizeof (Widget));
+ − 156 *number = n;
+ − 157 for (i = 0; i < n; i++)
+ − 158 result [i] = cw->composite.children [i];
+ − 159 return result;
+ − 160 }
+ − 161
+ − 162 Boolean
+ − 163 XtWidgetBeingDestroyedP (Widget widget)
+ − 164 {
+ − 165 return widget->core.being_destroyed;
+ − 166 }
+ − 167
+ − 168 void
+ − 169 XtSafelyDestroyWidget (Widget widget)
+ − 170 {
+ − 171 #if 0
+ − 172
+ − 173 /* this requires IntrinsicI.h (actually, InitialI.h) */
+ − 174
+ − 175 XtAppContext app = XtWidgetToApplicationContext(widget);
+ − 176
+ − 177 if (app->dispatch_level == 0)
+ − 178 {
+ − 179 app->dispatch_level = 1;
+ − 180 XtDestroyWidget (widget);
+ − 181 /* generates an event so that the event loop will be called */
+ − 182 XChangeProperty (XtDisplay (widget), XtWindow (widget),
+ − 183 XA_STRING, XA_STRING, 32, PropModeAppend, NULL, 0);
+ − 184 app->dispatch_level = 0;
+ − 185 }
+ − 186 else
+ − 187 XtDestroyWidget (widget);
+ − 188
+ − 189 #else
+ − 190 abort ();
+ − 191 #endif
+ − 192 }