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