XEmacs 21.2-b1
[chise/xemacs-chise.git.1] / lwlib / lwlib-utils.c
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 /* Redisplay the contents of the widget, without first clearing it. */
35 void
36 XtNoClearRefreshWidget (Widget widget)
37 {
38   XEvent event;
39   XExposeEvent* ev = &event.xexpose;
40
41   ev->type = Expose;
42   ev->serial = 0;
43   ev->send_event = 0;
44   ev->display = XtDisplay (widget);
45   ev->window = XtWindow (widget);
46   ev->x = 0;
47   ev->y = 0;
48   ev->width  = widget->core.width;
49   ev->height = widget->core.height;
50   ev->count = 0;
51
52   (*widget->core.widget_class->core_class.expose)
53     (widget, &event, (Region)NULL);
54 }
55
56
57 /* 
58  * Apply a function to all the subwidgets of a given widget recursively.
59 */
60 void
61 XtApplyToWidgets (Widget w, XtApplyToWidgetsProc proc, XtPointer arg)
62 {
63   if (XtIsComposite (w))
64     {
65       CompositeWidget cw = (CompositeWidget) w;
66       /* We have to copy the children list before mapping over it, because
67          the procedure might add/delete elements, which would lose badly. */
68       int nkids = cw->composite.num_children;
69       Widget *kids = (Widget *) malloc (sizeof (Widget) * nkids);
70       int i;
71       memcpy (kids, cw->composite.children, sizeof (Widget) * nkids);
72       for (i = 0; i < nkids; i++)
73 /* This prevent us from using gadgets, why is it here? */
74 /*      if (XtIsWidget (kids [i])) */
75           {
76             /* do the kiddies first in case we're destroying */
77             XtApplyToWidgets (kids [i], proc, arg);
78             proc (kids [i], arg);
79           }
80       free (kids);
81     }
82 }
83
84
85 /*
86  * Apply a function to all the subwidgets of a given widget recursively.
87  * Stop as soon as the function returns non NULL and returns this as a value.
88  */
89 void *
90 XtApplyUntilToWidgets (Widget w, XtApplyUntilToWidgetsProc proc, XtPointer arg)
91 {
92   void* result;
93   if (XtIsComposite (w))
94     {
95       CompositeWidget cw = (CompositeWidget)w;
96       int i;
97       for (i = 0; i < cw->composite.num_children; i++)
98         if (XtIsWidget (cw->composite.children [i])){
99           result = proc (cw->composite.children [i], arg);
100           if (result)
101             return result;
102           result = XtApplyUntilToWidgets (cw->composite.children [i], proc,
103                                           arg);
104           if (result)
105             return result;
106         }
107     }
108   return NULL;
109 }
110
111
112 /*
113  * Returns a copy of the list of all children of a composite widget
114  */
115 Widget *
116 XtCompositeChildren (Widget widget, unsigned int* number)
117 {
118   CompositeWidget cw = (CompositeWidget)widget;
119   Widget* result;
120   int n;
121   int i;
122
123   if (!XtIsComposite (widget))
124     {
125       *number = 0;
126       return NULL;
127     }
128   n = cw->composite.num_children;
129   result = (Widget*)XtMalloc (n * sizeof (Widget));
130   *number = n;
131   for (i = 0; i < n; i++)
132     result [i] = cw->composite.children [i];
133   return result;
134 }
135
136 Boolean
137 XtWidgetBeingDestroyedP (Widget widget)
138 {
139   return widget->core.being_destroyed;
140 }
141
142 void
143 XtSafelyDestroyWidget (Widget widget)
144 {
145 #if 0
146
147   /* this requires IntrinsicI.h (actually, InitialI.h) */
148
149   XtAppContext app = XtWidgetToApplicationContext(widget);
150
151   if (app->dispatch_level == 0)
152     {
153       app->dispatch_level = 1;
154       XtDestroyWidget (widget);
155       /* generates an event so that the event loop will be called */
156       XChangeProperty (XtDisplay (widget), XtWindow (widget),
157                        XA_STRING, XA_STRING, 32, PropModeAppend, NULL, 0);
158       app->dispatch_level = 0;
159     }
160   else
161     XtDestroyWidget (widget);
162   
163 #else
164   abort ();
165 #endif
166 }