Bug Summary

File:Paned.c
Location:line 1125, column 2
Description:Dereference of null pointer

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1988, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28 All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46******************************************************************/
47
48/*
49 * Updated and significantly modified from the Athena VPaned Widget.
50 *
51 * Date: March 1, 1989
52 *
53 * By: Chris D. Peterson
54 * MIT X Consortium
55 * kit@expo.lcs.mit.edu
56 */
57
58#ifdef HAVE_CONFIG_H1
59#include <config.h>
60#endif
61#include <X11/IntrinsicP.h>
62#include <X11/cursorfont.h>
63#include <X11/StringDefs.h>
64#include <X11/Xmu/CharSet.h>
65#include <X11/Xmu/Converters.h>
66#include <X11/Xmu/Misc.h>
67#include <X11/Xaw/Grip.h>
68#include <X11/Xaw/PanedP.h>
69#include <X11/Xaw/XawImP.h>
70#include <X11/Xaw/XawInit.h>
71#include "Private.h"
72
73typedef enum {
74 UpLeftPane = 'U',
75 LowRightPane = 'L',
76 ThisBorderOnly = 'T',
77 AnyPane = 'A'
78} Direction;
79
80#define NO_INDEX-100 -100
81#define IS_GRIP((void*)0) NULL((void*)0)
82
83#define PaneInfo(w)((Pane)(w)->core.constraints) ((Pane)(w)->core.constraints)
84#define HasGrip(w)(((Pane)(w)->core.constraints)->grip != ((void*)0)) (PaneInfo(w)((Pane)(w)->core.constraints)->grip != NULL((void*)0))
85#define IsPane(w)((w)->core.widget_class != gripWidgetClass) ((w)->core.widget_class != gripWidgetClass)
86#define PaneIndex(w)(((Pane)(w)->core.constraints)->position) (PaneInfo(w)((Pane)(w)->core.constraints)->position)
87#define IsVert(w)((w)->paned.orientation == XtorientVertical) ((w)->paned.orientation == XtorientVertical)
88
89#define ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
\
90for ((childP) = (pw)->composite.children; \
91 (childP) < (pw)->composite.children + (pw)->paned.num_panes; \
92 (childP)++)
93
94#define ForAllChildren(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->composite.num_children; (
childP)++)
\
95for ((childP) = (pw)->composite.children; \
96 (childP) < (pw)->composite.children + (pw)->composite.num_children; \
97 (childP)++)
98
99#define PaneSize(paned, vertical)((vertical) ? (((RectObj)paned)->rectangle.height) : (((RectObj
)paned)->rectangle.width))
\
100 ((vertical) ? XtHeight(paned)(((RectObj)paned)->rectangle.height) : XtWidth(paned)(((RectObj)paned)->rectangle.width))
101
102#define GetRequestInfo(geo, vertical)((vertical) ? (geo)->height : (geo)->width) \
103 ((vertical) ? (geo)->height : (geo)->width)
104
105#define SatisfiesRule1(pane, shrink)(((shrink) && ((pane)->size != (pane)->min)) ||
(!(shrink) && ((pane)->size != (pane)->max)))
\
106 (((shrink) && ((pane)->size != (pane)->min)) \
107 || (!(shrink) && ((pane)->size != (pane)->max)))
108
109#define SatisfiesRule2(pane)(!(pane)->skip_adjust || (pane)->paned_adjusted_me) \
110 (!(pane)->skip_adjust || (pane)->paned_adjusted_me)
111
112#define SatisfiesRule3(pane, shrink)((pane)->paned_adjusted_me && (((shrink) &&
((int)(pane)->wp_size <= (pane)->size)) || (!(shrink
) && ((int)(pane)->wp_size >= (pane)->size))
))
\
113 ((pane)->paned_adjusted_me \
114 && (((shrink) && ((int)(pane)->wp_size <= (pane)->size)) \
115 || (!(shrink) && ((int)(pane)->wp_size >= (pane)->size))))
116
117
118/*
119 * Class Methods
120 */
121static void XawPanedClassInitialize(void);
122static void XawPanedChangeManaged(Widget);
123static void XawPanedDeleteChild(Widget);
124static void XawPanedDestroy(Widget);
125static XtGeometryResult XawPanedGeometryManager(Widget, XtWidgetGeometry*,
126 XtWidgetGeometry*);
127static void XawPanedInitialize(Widget, Widget, ArgList, Cardinal*);
128static void XawPanedInsertChild(Widget);
129static Boolean XawPanedPaneSetValues(Widget, Widget, Widget,
130 ArgList, Cardinal*);
131static void XawPanedRealize(Widget, Mask*, XSetWindowAttributes*);
132static void XawPanedRedisplay(Widget, XEvent*, Region);
133static void XawPanedResize(Widget);
134static Boolean XawPanedSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
135
136/*
137 * Prototypes
138 */
139static void _DrawInternalBorders(PanedWidget, GC);
140static void _DrawRect(PanedWidget, GC, int, int, unsigned int, unsigned int);
141static void _DrawTrackLines(PanedWidget, Boolint);
142static void AdjustPanedSize(PanedWidget, unsigned int, XtGeometryResult*,
143 Dimension*, Dimension*);
144static void ChangeAllGripCursors(PanedWidget);
145static Pane ChoosePaneToResize(PanedWidget, int, Direction, Boolint);
146static void ClearPaneStack(PanedWidget);
147static void CommitGripAdjustment(PanedWidget);
148static void CreateGrip(Widget);
149static int GetEventLocation(PanedWidget, XEvent*);
150static void GetGCs(Widget);
151static void GetPaneStack(PanedWidget, Boolint, Pane*, int*);
152static void HandleGrip(Widget, XtPointer, XtPointer);
153static void LoopAndRefigureChildren(PanedWidget, int, Direction, int*);
154static void ManageAndUnmanageGrips(PanedWidget);
155static void MoveGripAdjustment(PanedWidget, Widget, Direction, int);
156static Boolint PopPaneStack(PanedWidget);
157static void PushPaneStack(PanedWidget, Pane);
158static void RefigureLocations(PanedWidget, int, Direction);
159static void RefigureLocationsAndCommit(Widget);
160static void ReleaseGCs(Widget);
161static void ResortChildren(PanedWidget);
162static void SetChildrenPrefSizes(PanedWidget, unsigned int);
163static void StartGripAdjustment(PanedWidget, Widget, Direction);
164
165/*
166 * Initialization
167 */
168static char defGripTranslations[] =
169"<Btn1Down>:" "GripAction(Start,UpLeftPane)\n"
170"<Btn2Down>:" "GripAction(Start,ThisBorderOnly)\n"
171"<Btn3Down>:" "GripAction(Start,LowRightPane)\n"
172"<Btn1Motion>:" "GripAction(Move,UpLeft)\n"
173"<Btn2Motion>:" "GripAction(Move,ThisBorder)\n"
174"<Btn3Motion>:" "GripAction(Move,LowRight)\n"
175"Any<BtnUp>:" "GripAction(Commit)\n"
176;
177
178#define offset(field) XtOffsetOf(PanedRec, paned.field)__builtin_offsetof(PanedRec, paned.field)
179static XtResource resources[] = {
180 {
181 XtNinternalBorderColor"internalBorderColor",
182 XtCBorderColor((char*)&XtStrings[928]),
183 XtRPixel((char*)&XtStrings[1754]),
184 sizeof(Pixel),
185 offset(internal_bp),
186 XtRString((char*)&XtStrings[1797]),
187 (XtPointer)XtDefaultForeground"XtDefaultForeground"
188 },
189 {
190 XtNinternalBorderWidth"internalBorderWidth",
191 XtCBorderWidth((char*)&XtStrings[940]),
192 XtRDimension((char*)&XtStrings[1618]),
193 sizeof(Dimension),
194 offset(internal_bw),
195 XtRImmediate((char*)&XtStrings[1695]),
196 (XtPointer)1
197 },
198 {
199 XtNgripIndent"gripIndent",
200 XtCGripIndent"GripIndent",
201 XtRPosition((char*)&XtStrings[1775]),
202 sizeof(Position),
203 offset(grip_indent),
204 XtRImmediate((char*)&XtStrings[1695]),
205 (XtPointer)10
206 },
207 {
208 XtNrefigureMode"refigureMode",
209 XtCBoolean((char*)&XtStrings[920]),
210 XtRBoolean((char*)&XtStrings[1561]),
211 sizeof(Boolean),
212 offset(refiguremode),
213 XtRImmediate((char*)&XtStrings[1695]),
214 (XtPointer)True1
215 },
216 {
217 XtNgripTranslations"gripTranslations",
218 XtCTranslations((char*)&XtStrings[1484]),
219 XtRTranslationTable((char*)&XtStrings[1841]),
220 sizeof(XtTranslations),
221 offset(grip_translations),
222 XtRString((char*)&XtStrings[1797]),
223 (XtPointer)defGripTranslations
224 },
225 {
226 XtNorientation((char*)&XtStrings[505]),
227 XtCOrientation((char*)&XtStrings[1206]),
228 XtROrientation((char*)&XtStrings[1742]),
229 sizeof(XtOrientation),
230 offset(orientation),
231 XtRImmediate((char*)&XtStrings[1695]),
232 (XtPointer)XtorientVertical
233 },
234 {
235 XtNcursor"cursor",
236 XtCCursor((char*)&XtStrings[976]),
237 XtRCursor((char*)&XtStrings[1611]),
238 sizeof(Cursor),
239 offset(cursor),
240 XtRImmediate((char*)&XtStrings[1695]),
241 NULL((void*)0)
242 },
243 {
244 XtNgripCursor"gripCursor",
245 XtCCursor((char*)&XtStrings[976]),
246 XtRCursor((char*)&XtStrings[1611]),
247 sizeof(Cursor),
248 offset(grip_cursor),
249 XtRImmediate((char*)&XtStrings[1695]),
250 NULL((void*)0)
251 },
252 {
253 XtNverticalGripCursor"verticalGripCursor",
254 XtCCursor((char*)&XtStrings[976]),
255 XtRCursor((char*)&XtStrings[1611]),
256 sizeof(Cursor),
257 offset(v_grip_cursor),
258 XtRString((char*)&XtStrings[1797]),
259 "sb_v_double_arrow"
260 },
261 {
262 XtNhorizontalGripCursor"horizontalGripCursor",
263 XtCCursor((char*)&XtStrings[976]),
264 XtRCursor((char*)&XtStrings[1611]),
265 sizeof(Cursor),
266 offset(h_grip_cursor),
267 XtRString((char*)&XtStrings[1797]),
268 "sb_h_double_arrow"
269 },
270 {
271 XtNbetweenCursor"betweenCursor",
272 XtCCursor((char*)&XtStrings[976]),
273 XtRCursor((char*)&XtStrings[1611]),
274 sizeof(Cursor),
275 offset(adjust_this_cursor),
276 XtRString((char*)&XtStrings[1797]),
277 NULL((void*)0)
278 },
279 {
280 XtNverticalBetweenCursor"verticalBetweenCursor",
281 XtCCursor((char*)&XtStrings[976]),
282 XtRCursor((char*)&XtStrings[1611]),
283 sizeof(Cursor),
284 offset(v_adjust_this_cursor),
285 XtRString((char*)&XtStrings[1797]),
286 "sb_left_arrow"
287 },
288 {
289 XtNhorizontalBetweenCursor"horizontalBetweenCursor",
290 XtCCursor((char*)&XtStrings[976]),
291 XtRCursor((char*)&XtStrings[1611]),
292 sizeof(Cursor),
293 offset(h_adjust_this_cursor),
294 XtRString((char*)&XtStrings[1797]),
295 "sb_up_arrow"
296 },
297 {
298 XtNupperCursor"upperCursor",
299 XtCCursor((char*)&XtStrings[976]),
300 XtRCursor((char*)&XtStrings[1611]),
301 sizeof(Cursor),
302 offset(adjust_upper_cursor),
303 XtRString((char*)&XtStrings[1797]),
304 "sb_up_arrow"
305 },
306 {
307 XtNlowerCursor"lowerCursor",
308 XtCCursor((char*)&XtStrings[976]),
309 XtRCursor((char*)&XtStrings[1611]),
310 sizeof(Cursor),
311 offset(adjust_lower_cursor),
312 XtRString((char*)&XtStrings[1797]),
313 "sb_down_arrow"
314 },
315 {
316 XtNleftCursor"leftCursor",
317 XtCCursor((char*)&XtStrings[976]),
318 XtRCursor((char*)&XtStrings[1611]),
319 sizeof(Cursor),
320 offset(adjust_left_cursor),
321 XtRString((char*)&XtStrings[1797]),
322 "sb_left_arrow"
323 },
324 {
325 XtNrightCursor"rightCursor",
326 XtCCursor((char*)&XtStrings[976]),
327 XtRCursor((char*)&XtStrings[1611]),
328 sizeof(Cursor),
329 offset(adjust_right_cursor),
330 XtRString((char*)&XtStrings[1797]),
331 "sb_right_arrow"
332 },
333};
334#undef offset
335
336#define offset(field) XtOffsetOf(PanedConstraintsRec, paned.field)__builtin_offsetof(PanedConstraintsRec, paned.field)
337static XtResource subresources[] = {
338 {
339 XtNallowResize"allowResize",
340 XtCBoolean((char*)&XtStrings[920]),
341 XtRBoolean((char*)&XtStrings[1561]),
342 sizeof(Boolean),
343 offset(allow_resize),
344 XtRImmediate((char*)&XtStrings[1695]),
345 (XtPointer)False0
346 },
347 {
348 XtNposition"position",
349 XtCPosition((char*)&XtStrings[1235]),
350 XtRInt((char*)&XtStrings[1718]),
351 sizeof(int),
352 offset(position),
353 XtRImmediate((char*)&XtStrings[1695]),
354 (XtPointer)0
355 },
356 {
357 XtNmin"min",
358 XtCMin"Min",
359 XtRDimension((char*)&XtStrings[1618]),
360 sizeof(Dimension),
361 offset(min),
362 XtRImmediate((char*)&XtStrings[1695]),
363 (XtPointer)PANED_GRIP_SIZE0
364 },
365 {
366 XtNmax"max",
367 XtCMax"Max",
368 XtRDimension((char*)&XtStrings[1618]),
369 sizeof(Dimension),
370 offset(max),
371 XtRImmediate((char*)&XtStrings[1695]),
372 (XtPointer)~0
373 },
374 {
375 XtNpreferredPaneSize"preferredPaneSize",
376 XtCPreferredPaneSize"PreferredPaneSize",
377 XtRDimension((char*)&XtStrings[1618]),
378 sizeof(Dimension),
379 offset(preferred_size),
380 XtRImmediate((char*)&XtStrings[1695]),
381 (XtPointer)PANED_ASK_CHILD0
382 },
383 {
384 XtNresizeToPreferred"resizeToPreferred",
385 XtCBoolean((char*)&XtStrings[920]),
386 XtRBoolean((char*)&XtStrings[1561]),
387 sizeof(Boolean),
388 offset(resize_to_pref),
389 XtRImmediate((char*)&XtStrings[1695]),
390 (XtPointer)False0
391 },
392 {
393 XtNskipAdjust"skipAdjust",
394 XtCBoolean((char*)&XtStrings[920]),
395 XtRBoolean((char*)&XtStrings[1561]),
396 sizeof(Boolean),
397 offset(skip_adjust),
398 XtRImmediate((char*)&XtStrings[1695]),
399 (XtPointer)False0
400 },
401 {
402 XtNshowGrip"showGrip",
403 XtCShowGrip"ShowGrip",
404 XtRBoolean((char*)&XtStrings[1561]),
405 sizeof(Boolean),
406 offset(show_grip),
407 XtRImmediate((char*)&XtStrings[1695]),
408 (XtPointer)True1
409 },
410};
411#undef offset
412
413#define SuperClass((ConstraintWidgetClass)&constraintClassRec) ((ConstraintWidgetClass)&constraintClassRec)
414
415PanedClassRec panedClassRec = {
416 /* core */
417 {
418 (WidgetClass)SuperClass((ConstraintWidgetClass)&constraintClassRec), /* superclass */
419 "Paned", /* class name */
420 sizeof(PanedRec), /* size */
421 XawPanedClassInitialize, /* class_initialize */
422 NULL((void*)0), /* class_part init */
423 False0, /* class_inited */
424 XawPanedInitialize, /* initialize */
425 NULL((void*)0), /* initialize_hook */
426 XawPanedRealize, /* realize */
427 NULL((void*)0), /* actions */
428 0, /* num_actions */
429 resources, /* resources */
430 XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), /* num_resources */
431 NULLQUARK((XrmQuark) 0), /* xrm_class */
432 True1, /* compress_motion */
433 True1, /* compress_exposure */
434 True1, /* compress_enterleave */
435 False0, /* visible_interest */
436 XawPanedDestroy, /* destroy */
437 XawPanedResize, /* resize */
438 XawPanedRedisplay, /* expose */
439 XawPanedSetValues, /* set_values */
440 NULL((void*)0), /* set_values_hook */
441 XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit), /* set_values_almost */
442 NULL((void*)0), /* get_values_hook */
443 NULL((void*)0), /* accept_focus */
444 XtVersion(11 * 1000 + 6), /* version */
445 NULL((void*)0), /* callback_private */
446 NULL((void*)0), /* tm_table */
447 XtInheritQueryGeometry((XtGeometryHandler) _XtInherit), /* query_geometry */
448 XtInheritDisplayAccelerator((XtStringProc) _XtInherit), /* display_accelerator */
449 NULL((void*)0), /* extension */
450 },
451 /* composite */
452 {
453 XawPanedGeometryManager, /* geometry_manager */
454 XawPanedChangeManaged, /* change_managed */
455 XawPanedInsertChild, /* insert_child */
456 XawPanedDeleteChild, /* delete_child */
457 NULL((void*)0), /* extension */
458 },
459 /* constraint */
460 {
461 subresources, /* subresources */
462 XtNumber(subresources)((Cardinal) (sizeof(subresources) / sizeof(subresources[0]))), /* subresource_count */
463 sizeof(PanedConstraintsRec), /* constraint_size */
464 NULL((void*)0), /* initialize */
465 NULL((void*)0), /* destroy */
466 XawPanedPaneSetValues, /* set_values */
467 NULL((void*)0), /* extension */
468 },
469};
470
471WidgetClass panedWidgetClass = (WidgetClass)&panedClassRec;
472WidgetClass vPanedWidgetClass = (WidgetClass)&panedClassRec;
473
474/*
475 * Implementation
476 */
477/* Function:
478 * AdjustPanedSize
479 *
480 * Parameters:
481 * pw - paned widget to adjust
482 * off_size - new off_size to use
483 * result_ret - result of query (return)
484 * on_size_ret - new on_size (return)
485 * off_size_ret - new off_size (return)
486 *
487 * Description:
488 * Adjusts the size of the pane.
489 *
490 * Returns:
491 * amount of change in size
492 */
493static void
494AdjustPanedSize(PanedWidget pw, unsigned int off_size,
495 XtGeometryResult *result_ret,
496 Dimension *on_size_ret, Dimension *off_size_ret)
497{
498 Dimension old_size = PaneSize((Widget)pw, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)(Widget)pw)->rectangle.height) : (((RectObj)(Widget)pw)->
rectangle.width))
;
499 Dimension newsize = 0;
500 Widget *childP;
501 XtWidgetGeometry request, reply;
502
503 request.request_mode = CWWidth(1<<2) | CWHeight(1<<3);
504
505 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
506 int size = Max(PaneInfo(*childP)->size, (int)PaneInfo(*childP)->min)(((((Pane)(*childP)->core.constraints)->size) > ((int
)((Pane)(*childP)->core.constraints)->min)) ? (((Pane)(
*childP)->core.constraints)->size) : ((int)((Pane)(*childP
)->core.constraints)->min))
;
507
508 AssignMin(size, (int)PaneInfo(*childP)->max){if (((int)((Pane)(*childP)->core.constraints)->max) <
(size)) size = ((int)((Pane)(*childP)->core.constraints)->
max);}
;
509 newsize += size + pw->paned.internal_bw;
510 }
511 newsize -= pw->paned.internal_bw;
512
513 if (newsize < 1)
514 newsize = 1;
515
516 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical)) {
517 request.width = off_size;
518 request.height = newsize;
519 }
520 else {
521 request.width = newsize;
522 request.height = off_size;
523 }
524
525 if (result_ret != NULL((void*)0)) {
526 request.request_mode |= XtCWQueryOnly(1 << 7);
527
528 *result_ret = XtMakeGeometryRequest((Widget)pw, &request, &reply);
529 _XawImCallVendorShellExtResize((Widget)pw);
530
531 if (newsize == old_size || *result_ret == XtGeometryNo) {
532 *on_size_ret = old_size;
533 *off_size_ret = off_size;
534 return;
535 }
536 if (*result_ret != XtGeometryAlmost) {
537 *on_size_ret = GetRequestInfo(&request, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (&request
)->height : (&request)->width)
;
538 *off_size_ret = GetRequestInfo(&request, !IsVert(pw))((!((pw)->paned.orientation == XtorientVertical)) ? (&
request)->height : (&request)->width)
;
539 return;
540 }
541 *on_size_ret = GetRequestInfo(&reply, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (&reply
)->height : (&reply)->width)
;
542 *off_size_ret = GetRequestInfo(&reply, !IsVert(pw))((!((pw)->paned.orientation == XtorientVertical)) ? (&
reply)->height : (&reply)->width)
;
543 return;
544 }
545
546 if (newsize == old_size)
547 return;
548
549 if (XtMakeGeometryRequest((Widget)pw, &request, &reply) == XtGeometryAlmost)
550 XtMakeGeometryRequest((Widget)pw, &reply, &request);
551}
552
553/*
554 * Function:
555 * ChoosePaneToResize.
556 *
557 * Parameters:
558 * pw - paned widget
559 * paneindex - index of the current pane
560 * dir - direction to search first
561 * shrink - True if we need to shrink a pane, False otherwise
562 *
563 * Description:
564 * This function chooses a pane to resize.
565 * They are chosen using the following rules:
566 *
567 * 1) size < max && size > min
568 * 2) skip adjust == False
569 * 3) widget not its prefered height
570 * && this change will bring it closer
571 * && The user has not resized this pane.
572 *
573 * If no widgets are found that fits all the rules then
574 * rule #3 is broken.
575 * If there are still no widgets found than
576 * rule #2 is broken.
577 * Rule #1 is never broken.
578 * If no widgets are found then NULL is returned.
579 *
580 * Returns:
581 * pane to resize or NULL
582 */
583static Pane
584ChoosePaneToResize(PanedWidget pw, int paneindex, Direction dir, Boolint shrink)
585{
586 Widget *childP;
587 int rules = 3;
588 Direction _dir = dir;
589 int _index = paneindex;
590
591 if (paneindex == NO_INDEX-100 || dir == AnyPane) { /* Use defaults */
592 _dir = LowRightPane; /* Go up - really */
593 _index = pw->paned.num_panes - 1; /* Start the last pane, and work
594 backwards */
595 }
596 childP = pw->composite.children + _index;
597
598 /*CONSTCOND*/
599 while(True1) {
600 Pane pane = PaneInfo(*childP)((Pane)(*childP)->core.constraints);
601
602 if ((rules < 3 || SatisfiesRule3(pane, shrink)((pane)->paned_adjusted_me && (((shrink) &&
((int)(pane)->wp_size <= (pane)->size)) || (!(shrink
) && ((int)(pane)->wp_size >= (pane)->size))
))
)
603 && (rules < 2 || SatisfiesRule2(pane)(!(pane)->skip_adjust || (pane)->paned_adjusted_me))
604 && SatisfiesRule1(pane, shrink)(((shrink) && ((pane)->size != (pane)->min)) ||
(!(shrink) && ((pane)->size != (pane)->max)))
605 && (paneindex != PaneIndex(*childP)(((Pane)(*childP)->core.constraints)->position) || dir == AnyPane))
606 return (pane);
607
608 /*
609 * This is counter-intuitive, but if we are resizing the pane
610 * above the grip we want to choose a pane below the grip to lose,
611 * and visa-versa
612 */
613 if (_dir == LowRightPane)
614 --childP;
615 else
616 ++childP;
617
618 /*
619 * If we have come to and edge then reduce the rule set, and try again
620 * If we are reduced the rules to none, then return NULL
621 */
622 if ((childP - pw->composite.children) < 0 ||
623 (childP - pw->composite.children) >= pw->paned.num_panes) {
624 if (--rules < 1) /* less strict rules */
625 return (NULL((void*)0));
626 childP = pw->composite.children + _index;
627 }
628 }
629}
630
631/*
632 * Function:
633 * LoopAndRefigureChildren
634 *
635 * Parameters:
636 * pw - paned widget
637 * paneindex - number of the pane border we are moving
638 * dir - pane to move (either UpLeftPane or LowRightPane)
639 * sizeused - current amount of space used (used and returned)
640 *
641 * Description:
642 * If we are resizing either the UpleftPane or LowRight Pane loop
643 * through all the children to see if any will allow us to resize them.
644 */
645static void
646LoopAndRefigureChildren(PanedWidget pw, int paneindex, Direction dir,
647 int *sizeused)
648{
649 int pane_size = (int)PaneSize((Widget)pw, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)(Widget)pw)->rectangle.height) : (((RectObj)(Widget)pw)->
rectangle.width))
;
650 Boolean shrink = (*sizeused > pane_size);
651
652 if (dir == LowRightPane)
653 paneindex++;
654
655 /* While all panes do not fit properly */
656 while (*sizeused != pane_size) {
657 /*
658 * Choose a pane to resize
659 * First look on the Pane Stack, and then go hunting for another one
660 * If we fail to find a pane to resize then give up
661 */
662 Pane pane;
663 int start_size;
664 Dimension old;
665 Boolean rule3_ok = False0, from_stack = True1;
666
667 GetPaneStack(pw, shrink, &pane, &start_size);
668 if (pane == NULL((void*)0)) {
669 pane = ChoosePaneToResize(pw, paneindex, dir, shrink);
670 if (pane == NULL((void*)0))
671 return; /* no one to resize, give up */
672
673 rule3_ok = SatisfiesRule3(pane, shrink)((pane)->paned_adjusted_me && (((shrink) &&
((int)(pane)->wp_size <= (pane)->size)) || (!(shrink
) && ((int)(pane)->wp_size >= (pane)->size))
))
;
674 from_stack = False0;
675 PushPaneStack(pw, pane);
676 }
677
678 /*
679 * Try to resize this pane so that all panes will fit, take min and max
680 * into account
681 */
682 old = pane->size;
683 pane->size += pane_size - *sizeused;
684
685 if (from_stack) {
686 if (shrink) {
687 AssignMax(pane->size, start_size){if ((start_size) > (pane->size)) pane->size = (start_size
);}
;
688 } /* don't remove these braces */
689 else
690 AssignMin(pane->size, start_size){if ((start_size) < (pane->size)) pane->size = (start_size
);}
;
691
692 if (pane->size == start_size)
693 (void)PopPaneStack(pw);
694 }
695 else if (rule3_ok) {
696 if (shrink) {
697 AssignMax(pane->size, (int)pane->wp_size){if (((int)pane->wp_size) > (pane->size)) pane->size
= ((int)pane->wp_size);}
;
698 } /* don't remove these braces */
699 else
700 AssignMin(pane->size, (int)pane->wp_size){if (((int)pane->wp_size) < (pane->size)) pane->size
= ((int)pane->wp_size);}
;
701 }
702
703 pane->paned_adjusted_me = pane->size != pane->wp_size;
704 AssignMax(pane->size, (int)pane->min){if (((int)pane->min) > (pane->size)) pane->size =
((int)pane->min);}
;
705 AssignMin(pane->size, (int)pane->max){if (((int)pane->max) < (pane->size)) pane->size =
((int)pane->max);}
;
706 *sizeused += (pane->size - old);
707 }
708}
709
710/*
711 * Function:
712 * RefigureLocations
713 *
714 * Parameters:
715 * pw - paned widget
716 * paneindex - child to start refiguring at
717 * dir - direction to move from child
718 *
719 * Description:
720 * Refigures all locations of children.
721 * There are special arguments to paneindex and dir, they are:
722 * paneindex - NO_INDEX.
723 * dir - AnyPane.
724 *
725 * If either of these is true then all panes may be resized and
726 * the choosing of panes procedes in reverse order starting with the
727 * last child.
728 */
729static void
730RefigureLocations(PanedWidget pw, int paneindex, Direction dir)
731{
732 Widget *childP;
733 int pane_size = (int)PaneSize((Widget)pw, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)(Widget)pw)->rectangle.height) : (((RectObj)(Widget)pw)->
rectangle.width))
;
734 int sizeused = 0;
735 Position loc = 0;
736
737 if (pw->paned.num_panes == 0 || !pw->paned.refiguremode)
738 return;
739
740 /*
741 * Get an initial estimate of the size we will use
742 */
743 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
744 Pane pane = PaneInfo(*childP)((Pane)(*childP)->core.constraints);
745
746 AssignMax(pane->size, (int) pane->min){if (((int) pane->min) > (pane->size)) pane->size
= ((int) pane->min);}
;
747 AssignMin(pane->size, (int) pane->max){if (((int) pane->max) < (pane->size)) pane->size
= ((int) pane->max);}
;
748 sizeused += (int)pane->size + (int)pw->paned.internal_bw;
749 }
750 sizeused -= (int)pw->paned.internal_bw;
751
752 if (dir != ThisBorderOnly && sizeused != pane_size)
753 LoopAndRefigureChildren(pw, paneindex, dir, &sizeused);
754
755 /*
756 * If we still are not the right size, then tell the pane that
757 * wanted to resize that it can't
758 */
759 if (paneindex != NO_INDEX-100 && dir != AnyPane) {
760 Pane pane = PaneInfo(*(pw->composite.children + paneindex))((Pane)(*(pw->composite.children + paneindex))->core.constraints
)
;
761 Dimension old = pane->size;
762
763 pane->size += pane_size - sizeused;
764 AssignMax(pane->size, (int) pane->min){if (((int) pane->min) > (pane->size)) pane->size
= ((int) pane->min);}
;
765 AssignMin(pane->size, (int) pane->max){if (((int) pane->max) < (pane->size)) pane->size
= ((int) pane->max);}
;
766 sizeused += pane->size - old;
767 }
768
769 /*
770 * It is possible that the panes will not fit inside the vpaned widget, but
771 * we have tried out best
772 *
773 * Assign each pane a location
774 */
775 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
776 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->delta = loc;
777 loc += PaneInfo(*childP)((Pane)(*childP)->core.constraints)->size + pw->paned.internal_bw;
778 }
779}
780
781/*
782 * Function:
783 * CommitNewLocations
784 *
785 * Parameters:
786 * pw - paned widget
787 *
788 * Description:
789 * Commits all of the previously figured locations.
790 */
791static void
792CommitNewLocations(PanedWidget pw)
793{
794 Widget *childP;
795 XWindowChanges changes;
796
797 changes.stack_mode = Above0;
798
799 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
800 Pane pane = PaneInfo(*childP)((Pane)(*childP)->core.constraints);
801 Widget grip = pane->grip; /* may be NULL */
802
803 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical)) {
804 XtMoveWidget(*childP, (Position) 0, pane->delta);
805 XtResizeWidget(*childP, XtWidth(pw)(((RectObj)pw)->rectangle.width), pane->size, 0);
806
807 if (HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
) { /* Move and Display the Grip */
808 changes.x = XtWidth(pw)(((RectObj)pw)->rectangle.width) - pw->paned.grip_indent -
809 XtWidth(grip)(((RectObj)grip)->rectangle.width) - (XtBorderWidth(grip)(((RectObj)grip)->rectangle.border_width) << 1);
810 changes.y = XtY(*childP)(((RectObj)*childP)->rectangle.y) + XtHeight(*childP)(((RectObj)*childP)->rectangle.height) -
811 (XtHeight(grip)(((RectObj)grip)->rectangle.height) >> 1) - XtBorderWidth(grip)(((RectObj)grip)->rectangle.border_width) +
812 (pw->paned.internal_bw >> 1);
813 }
814 }
815 else {
816 XtMoveWidget(*childP, pane->delta, 0);
817 XtResizeWidget(*childP, pane->size, XtHeight(pw)(((RectObj)pw)->rectangle.height), 0);
818
819 if (HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
) { /* Move and Display the Grip */
820 changes.x = XtX(*childP)(((RectObj)*childP)->rectangle.x) + XtWidth(*childP)(((RectObj)*childP)->rectangle.width) -
821 (XtWidth(grip)(((RectObj)grip)->rectangle.width) >> 1) - XtBorderWidth(grip)(((RectObj)grip)->rectangle.border_width) +
822 (pw->paned.internal_bw >> 1);
823 changes.y = XtHeight(pw)(((RectObj)pw)->rectangle.height) - pw->paned.grip_indent -
824 XtHeight(grip)(((RectObj)grip)->rectangle.height) - (XtBorderWidth(grip)(((RectObj)grip)->rectangle.border_width) << 1);
825 }
826 }
827
828 /*
829 * This should match XtMoveWidget, except that we're also insuring the
830 * grip is Raised in the same request
831 */
832
833 if (HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
) {
834 XtX(grip)(((RectObj)grip)->rectangle.x) = changes.x;
835 XtY(grip)(((RectObj)grip)->rectangle.y) = changes.y;
836
837 if (XtIsRealized(pane->grip)(XtWindowOfObject(pane->grip) != 0L))
838 XConfigureWindow(XtDisplay(pane->grip)(((pane->grip)->core.screen)->display), XtWindow(pane->grip)((pane->grip)->core.window),
839 CWX(1<<0) | CWY(1<<1) | CWStackMode(1<<6), &changes);
840 }
841 }
842 ClearPaneStack(pw);
843}
844
845/*
846 * Function:
847 * RefigureLocationsAndCommit
848 *
849 * Parameters:
850 * pw - paned widget
851 *
852 * Description:
853 * Refigures all locations in a paned widget and commits them immediately.
854 *
855 * This function does nothing if any of the following are true.
856 * o refiguremode is false.
857 * o The widget is unrealized.
858 * o There are no panes is the paned widget.
859 */
860static void
861RefigureLocationsAndCommit(Widget w)
862{
863 PanedWidget pw = (PanedWidget)w;
864
865 if (pw->paned.refiguremode && XtIsRealized(w)(XtWindowOfObject(w) != 0L) && pw->paned.num_panes > 0) {
866 RefigureLocations(pw, NO_INDEX-100, AnyPane);
867 CommitNewLocations(pw);
868 }
869}
870
871/*
872 * Function:
873 * _DrawRect
874 *
875 * Parameters:
876 * pw - paned widget
877 * gc - gc to used for the draw
878 * on_olc - location of upper left corner of rect
879 * off_loc - ""
880 * on_size - size of rectangle
881 * off_size - ""
882 *
883 * Description:
884 * Draws a rectangle in the proper orientation.
885 */
886static void
887_DrawRect(PanedWidget pw, GC gc, int on_loc, int off_loc,
888 unsigned int on_size, unsigned int off_size)
889{
890 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical))
891 XFillRectangle(XtDisplay((Widget)pw)((((Widget)pw)->core.screen)->display), XtWindow((Widget)pw)(((Widget)pw)->core.window), gc,
892 off_loc, on_loc, off_size, on_size);
893 else
894 XFillRectangle(XtDisplay((Widget)pw)((((Widget)pw)->core.screen)->display), XtWindow((Widget)pw)(((Widget)pw)->core.window), gc,
895 on_loc, off_loc, on_size, off_size);
896}
897
898/*
899 * Function:
900 * _DrawInternalBorders
901 *
902 * Parameters:
903 * pw - paned widget
904 * gc - GC to use to draw the borders
905 *
906 * Description:
907 * Draws the internal borders into the paned widget.
908 */
909static void
910_DrawInternalBorders(PanedWidget pw, GC gc)
911{
912 Widget *childP;
913 int on_loc, off_loc;
914 unsigned int on_size, off_size;
915
916 /*
917 * This is an optimization. Do not paint the internal borders if
918 * they are the same color as the background
919 */
920 if (pw->core.background_pixel == pw->paned.internal_bp)
921 return;
922
923 off_loc = 0;
924 off_size = (unsigned int) PaneSize((Widget)pw, !IsVert(pw))((!((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)(Widget)pw)->rectangle.height) : (((RectObj)(Widget)pw)->
rectangle.width))
;
925 on_size = (unsigned int)pw->paned.internal_bw;
926
927 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
928 on_loc = IsVert(pw)((pw)->paned.orientation == XtorientVertical) ? XtY(*childP)(((RectObj)*childP)->rectangle.y) : XtX(*childP)(((RectObj)*childP)->rectangle.x);
929 on_loc -= (int)on_size;
930
931 _DrawRect(pw, gc, on_loc, off_loc, on_size, off_size);
932 }
933}
934
935#define DrawInternalBorders(pw)_DrawInternalBorders((pw), (pw)->paned.normgc) \
936 _DrawInternalBorders((pw), (pw)->paned.normgc)
937#define EraseInternalBorders(pw)_DrawInternalBorders((pw), (pw)->paned.invgc) \
938 _DrawInternalBorders((pw), (pw)->paned.invgc)
939/*
940 * Function Name:
941 * _DrawTrackLines
942 *
943 * Parameters:
944 * pw - Paned widget
945 * erase - if True then just erase track lines, else draw them in
946 *
947 * Description:
948 * Draws the lines that animate the pane borders when the grips are moved.
949 */
950static void
951_DrawTrackLines(PanedWidget pw, Boolint erase)
952{
953 Widget *childP;
954 Pane pane;
955 int on_loc, off_loc;
956 unsigned int on_size, off_size;
957
958 off_loc = 0;
959 off_size = PaneSize((Widget)pw, !IsVert(pw))((!((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)(Widget)pw)->rectangle.height) : (((RectObj)(Widget)pw)->
rectangle.width))
;
960
961 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
962 pane = PaneInfo(*childP)((Pane)(*childP)->core.constraints);
963 if (erase || pane->olddelta != pane->delta) {
964 on_size = pw->paned.internal_bw;
965 if (!erase) {
966 on_loc = PaneInfo(*childP)((Pane)(*childP)->core.constraints)->olddelta - (int) on_size;
967 _DrawRect(pw, pw->paned.flipgc,
968 on_loc, off_loc, on_size, off_size);
969 }
970
971 on_loc = PaneInfo(*childP)((Pane)(*childP)->core.constraints)->delta - (int)on_size;
972
973 _DrawRect(pw, pw->paned.flipgc,
974 on_loc, off_loc, on_size, off_size);
975
976 pane->olddelta = pane->delta;
977 }
978 }
979}
980
981#define DrawTrackLines(pw)_DrawTrackLines((pw), 0); _DrawTrackLines((pw), False0);
982#define EraseTrackLines(pw)_DrawTrackLines((pw), 1); _DrawTrackLines((pw), True1);
983/*
984 * Function:
985 * GetEventLocation
986 *
987 * Parameters:
988 * pw - the paned widget
989 * event - pointer to an event
990 *
991 * Description:
992 * Converts and event to an x and y location.
993 *
994 * Returns:
995 * if this is a vertical pane then (y) else (x)
996 */
997static int
998GetEventLocation(PanedWidget pw, XEvent *event)
999{
1000 int x, y;
1001
1002 switch (event->xany.type) {
1003 case ButtonPress4:
1004 case ButtonRelease5:
1005 x = event->xbutton.x_root;
1006 y = event->xbutton.y_root;
1007 break;
1008 case KeyPress2:
1009 case KeyRelease3:
1010 x = event->xkey.x_root;
1011 y = event->xkey.y_root;
1012 break;
1013 case MotionNotify6:
1014 x = event->xmotion.x_root;
1015 y = event->xmotion.y_root;
1016 break;
1017 default:
1018 x = pw->paned.start_loc;
1019 y = pw->paned.start_loc;
1020 }
1021
1022 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical))
1023 return (y);
1024
1025 return (x);
1026}
1027
1028/*
1029 * Function:
1030 * StartGripAdjustment
1031 *
1032 * Parameters:
1033 * pw - paned widget
1034 * grip - grip widget selected
1035 * dir - direction that we are to be moving
1036 *
1037 * Description:
1038 * Starts the grip adjustment procedure.
1039 */
1040static void
1041StartGripAdjustment(PanedWidget pw, Widget grip, Direction dir)
1042{
1043 Widget *childP;
1044 Cursor cursor;
1045
1046 pw->paned.whichadd = pw->paned.whichsub = NULL((void*)0);
1047
1048 if (dir == ThisBorderOnly || dir == UpLeftPane)
1049 pw->paned.whichadd = pw->composite.children[PaneIndex(grip)(((Pane)(grip)->core.constraints)->position)];
1050 if (dir == ThisBorderOnly || dir == LowRightPane)
1051 pw->paned.whichsub = pw->composite.children[PaneIndex(grip)(((Pane)(grip)->core.constraints)->position) + 1];
1052
1053 /*
1054 * Change the cursor
1055 */
1056 if (XtIsRealized(grip)(XtWindowOfObject(grip) != 0L)) {
1057 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical)) {
1058 if (dir == UpLeftPane)
1059 cursor = pw->paned.adjust_upper_cursor;
1060 else if (dir == LowRightPane)
1061 cursor = pw->paned.adjust_lower_cursor;
1062 else {
1063 if (pw->paned.adjust_this_cursor == None0L)
1064 cursor = pw->paned.v_adjust_this_cursor;
1065 else
1066 cursor = pw->paned.adjust_this_cursor;
1067 }
1068 }
1069 else {
1070 if (dir == UpLeftPane)
1071 cursor = pw->paned.adjust_left_cursor;
1072 else if (dir == LowRightPane)
1073 cursor = pw->paned.adjust_right_cursor;
1074 else {
1075 if (pw->paned.adjust_this_cursor == None0L)
1076 cursor = pw->paned.h_adjust_this_cursor;
1077 else
1078 cursor = pw->paned.adjust_this_cursor;
1079 }
1080 }
1081
1082 XDefineCursor(XtDisplay(grip)(((grip)->core.screen)->display), XtWindow(grip)((grip)->core.window), cursor);
1083 }
1084
1085 EraseInternalBorders(pw)_DrawInternalBorders((pw), (pw)->paned.invgc);
1086 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
1087 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->olddelta = -99;
1088
1089 EraseTrackLines(pw)_DrawTrackLines((pw), 1);;
1090}
1091
1092/*
1093 * Function:
1094 * MoveGripAdjustment
1095 *
1096 * Parameters:
1097 * pw - paned widget
1098 * grip - grip that we are moving
1099 * dir - direction the pane we are interested is w.r.t the grip
1100 * loc - location of pointer in proper direction
1101 *
1102 * Description:
1103 * This routine moves all panes around when a grip is moved.
1104 */
1105static void
1106MoveGripAdjustment(PanedWidget pw, Widget grip, Direction dir, int loc)
1107{
1108 int diff, add_size = 0, sub_size = 0;
1109
1110 diff = loc - pw->paned.start_loc;
1111
1112 if (pw->paned.whichadd)
1
Taking false branch
1113 add_size = PaneSize(pw->paned.whichadd, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)pw->paned.whichadd)->rectangle.height) : (((RectObj)pw
->paned.whichadd)->rectangle.width))
+ diff;
1114
1115 if (pw->paned.whichsub)
2
Taking false branch
1116 sub_size = PaneSize(pw->paned.whichsub, IsVert(pw))((((pw)->paned.orientation == XtorientVertical)) ? (((RectObj
)pw->paned.whichsub)->rectangle.height) : (((RectObj)pw
->paned.whichsub)->rectangle.width))
- diff;
1117
1118 /*
1119 * If moving this border only then do not allow either of the borders
1120 * to go beyond the min or max size allowed
1121 */
1122 if (dir == ThisBorderOnly) {
3
Assuming 'dir' is equal to ThisBorderOnly
4
Taking true branch
1123 int old_add_size = add_size, old_sub_size;
1124
1125 AssignMax(add_size, (int)PaneInfo(pw->paned.whichadd)->min){if (((int)((Pane)(pw->paned.whichadd)->core.constraints
)->min) > (add_size)) add_size = ((int)((Pane)(pw->paned
.whichadd)->core.constraints)->min);}
;
5
Within the expansion of the macro 'AssignMax':
a
Dereference of null pointer
1126 AssignMin(add_size, (int)PaneInfo(pw->paned.whichadd)->max){if (((int)((Pane)(pw->paned.whichadd)->core.constraints
)->max) < (add_size)) add_size = ((int)((Pane)(pw->paned
.whichadd)->core.constraints)->max);}
;
1127 if (add_size != old_add_size)
1128 sub_size += old_add_size - add_size;
1129
1130 old_sub_size = sub_size;
1131 AssignMax(sub_size, (int)PaneInfo(pw->paned.whichsub)->min){if (((int)((Pane)(pw->paned.whichsub)->core.constraints
)->min) > (sub_size)) sub_size = ((int)((Pane)(pw->paned
.whichsub)->core.constraints)->min);}
;
1132 AssignMin(sub_size, (int)PaneInfo(pw->paned.whichsub)->max){if (((int)((Pane)(pw->paned.whichsub)->core.constraints
)->max) < (sub_size)) sub_size = ((int)((Pane)(pw->paned
.whichsub)->core.constraints)->max);}
;
1133 if (sub_size != old_sub_size)
1134 return; /* Abort to current sizes */
1135 }
1136
1137 if (add_size != 0)
1138 PaneInfo(pw->paned.whichadd)((Pane)(pw->paned.whichadd)->core.constraints)->size = add_size;
1139 if (sub_size != 0)
1140 PaneInfo(pw->paned.whichsub)((Pane)(pw->paned.whichsub)->core.constraints)->size = sub_size;
1141 RefigureLocations(pw, PaneIndex(grip)(((Pane)(grip)->core.constraints)->position), dir);
1142 DrawTrackLines(pw)_DrawTrackLines((pw), 0);;
1143}
1144
1145/*
1146 * Function:
1147 * CommitGripAdjustment
1148 *
1149 * Parameters:
1150 * pw - paned widget
1151 *
1152 * Description:
1153 * Commits the grip adjustment.
1154 */
1155static void
1156CommitGripAdjustment(PanedWidget pw)
1157{
1158 EraseTrackLines(pw)_DrawTrackLines((pw), 1);;
1159 CommitNewLocations(pw);
1160 DrawInternalBorders(pw)_DrawInternalBorders((pw), (pw)->paned.normgc);
1161
1162 /*
1163 * Since the user selected this size then use it as the preferred size
1164 */
1165 if (pw->paned.whichadd) {
1166 Pane pane = PaneInfo(pw->paned.whichadd)((Pane)(pw->paned.whichadd)->core.constraints);
1167
1168 pane->wp_size = pane->size;
1169 }
1170 if (pw->paned.whichsub) {
1171 Pane pane = PaneInfo(pw->paned.whichsub)((Pane)(pw->paned.whichsub)->core.constraints);
1172
1173 pane->wp_size = pane->size;
1174 }
1175}
1176
1177/*
1178 * Function:
1179 * HandleGrip
1180 *
1181 * Parameters:
1182 * grip - grip widget that has been moved
1183 * temp - (not used)
1184 * call_data - data passed to us from the grip widget
1185 *
1186 * Description:
1187 * Handles the grip manipulations.
1188 */
1189/*ARGSUSED*/
1190static void
1191HandleGrip(Widget grip, XtPointer temp, XtPointer callData)
1192{
1193 XawGripCallData call_data = (XawGripCallData)callData;
1194 PanedWidget pw = (PanedWidget) XtParent(grip)((grip)->core.parent);
1195 int loc;
1196 char action_type[2], direction[2];
1197 Cursor cursor;
1198 Arg arglist[1];
1199
1200 if (call_data->num_params)
1201 XmuNCopyISOLatin1Uppered(action_type, call_data->params[0],
1202 sizeof(action_type));
1203
1204 if (call_data->num_params == 0
1205 || (action_type[0] == 'C' && call_data->num_params != 1)
1206 || (action_type[0] != 'C' && call_data->num_params != 2))
1207 XtAppError(XtWidgetToApplicationContext(grip),
1208 "Paned GripAction has been passed incorrect parameters.");
1209
1210 loc = GetEventLocation(pw, (XEvent *)call_data->event);
1211
1212 if (action_type[0] != 'C')
1213 XmuNCopyISOLatin1Uppered(direction, call_data->params[1],
1214 sizeof(direction));
1215
1216 switch (action_type[0]) {
1217 case 'S': /* Start adjustment */
1218 pw->paned.resize_children_to_pref = False0;
1219 StartGripAdjustment(pw, grip, (Direction)direction[0]);
1220 pw->paned.start_loc = loc;
1221 break;
1222 case 'M':
1223 MoveGripAdjustment(pw, grip, (Direction)direction[0], loc);
1224 break;
1225 case 'C':
1226 XtSetArg(arglist[0], XtNcursor, &cursor)((void)( (arglist[0]).name = ("cursor"), (arglist[0]).value =
(XtArgVal)(&cursor) ))
;
1227 XtGetValues(grip, arglist, 1);
1228 XDefineCursor(XtDisplay(grip)(((grip)->core.screen)->display), XtWindow(grip)((grip)->core.window), cursor);
1229 CommitGripAdjustment(pw);
1230 break;
1231 default:
1232 XtAppError(XtWidgetToApplicationContext(grip),
1233 "Paned GripAction(); 1st parameter invalid");
1234 break;
1235 }
1236}
1237
1238/*
1239 * Function:
1240 * ResortChildren
1241 *
1242 * Arguments:
1243 * pw - paned widget
1244 *
1245 * Description:
1246 * Resorts the children so that all managed children are first.
1247 */
1248static void
1249ResortChildren(PanedWidget pw)
1250{
1251 Widget *unmanagedP, *childP;
1252
1253 unmanagedP = NULL((void*)0);
1254 ForAllChildren(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->composite.num_children; (
childP)++)
{
1255 if (!IsPane(*childP)((*childP)->core.widget_class != gripWidgetClass) || !XtIsManaged(*childP)) {
1256 /*
1257 * We only keep track of the first unmanaged pane
1258 */
1259 if (unmanagedP == NULL((void*)0))
1260 unmanagedP = childP;
1261 }
1262 else { /* must be a managed pane */
1263 /*
1264 * If an earlier widget was not a managed pane, then swap
1265 */
1266 if (unmanagedP != NULL((void*)0)) {
1267 Widget child = *unmanagedP;
1268
1269 *unmanagedP = *childP;
1270 *childP = child;
1271 childP = unmanagedP; /* easiest to just back-track */
1272 unmanagedP = NULL((void*)0); /* in case there is another managed */
1273 }
1274 }
1275 }
1276}
1277
1278/*
1279 * Function:
1280 * ManageAndUnmanageGrips
1281 *
1282 * Parameters:
1283 * pw - paned widget
1284 *
1285 * Description:
1286 * This function manages and unmanages the grips so that
1287 * the managed state of each grip matches that of its pane.
1288 */
1289static void
1290ManageAndUnmanageGrips(PanedWidget pw)
1291{
1292 WidgetList managed_grips, unmanaged_grips;
1293 Widget *managedP, *unmanagedP, *childP;
1294 Cardinal alloc_size;
1295
1296 alloc_size = sizeof(Widget) * (pw->composite.num_children >> 1);
1297 managedP = managed_grips = (WidgetList)XtMalloc(alloc_size);
1298 unmanagedP = unmanaged_grips = (WidgetList)XtMalloc(alloc_size);
1299
1300 ForAllChildren(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->composite.num_children; (
childP)++)
1301 if (IsPane(*childP)((*childP)->core.widget_class != gripWidgetClass) && HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
) {
1302 if (XtIsManaged(*childP))
1303 *managedP++ = PaneInfo(*childP)((Pane)(*childP)->core.constraints)->grip;
1304 else
1305 *unmanagedP++ = PaneInfo(*childP)((Pane)(*childP)->core.constraints)->grip;
1306 }
1307
1308 if (managedP != managed_grips) {
1309 *unmanagedP++ = *--managedP; /* Last grip is never managed */
1310 XtManageChildren(managed_grips, managedP - managed_grips);
1311 }
1312
1313 if (unmanagedP != unmanaged_grips)
1314 XtUnmanageChildren(unmanaged_grips, unmanagedP - unmanaged_grips);
1315
1316 XtFree((char *)managed_grips);
1317 XtFree((char *)unmanaged_grips);
1318}
1319
1320/*
1321 * Function:
1322 * CreateGrip
1323 *
1324 * Parameters:
1325 * child - child that wants a grip to be created for it
1326 *
1327 * Description:
1328 * Creates a grip widget.
1329 */
1330static void
1331CreateGrip(Widget child)
1332{
1333 PanedWidget pw = (PanedWidget)XtParent(child)((child)->core.parent);
1334 Arg arglist[2];
1335 Cardinal num_args = 0;
1336 Cursor cursor;
1337
1338 XtSetArg(arglist[num_args], XtNtranslations, pw->paned.grip_translations)((void)( (arglist[num_args]).name = (((char*)&XtStrings[802
])), (arglist[num_args]).value = (XtArgVal)(pw->paned.grip_translations
) ))
;
1339 num_args++;
1340 if ((cursor = pw->paned.grip_cursor) == None0L) {
1341 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical))
1342 cursor = pw->paned.v_grip_cursor;
1343 else
1344 cursor = pw->paned.h_grip_cursor;
1345 }
1346
1347 XtSetArg(arglist[num_args], XtNcursor, cursor)((void)( (arglist[num_args]).name = ("cursor"), (arglist[num_args
]).value = (XtArgVal)(cursor) ))
;
1348 num_args++;
1349 PaneInfo(child)((Pane)(child)->core.constraints)->grip = XtCreateWidget("grip", gripWidgetClass, (Widget)pw,
1350 arglist, num_args);
1351
1352 XtAddCallback(PaneInfo(child)((Pane)(child)->core.constraints)->grip, XtNcallback((char*)&XtStrings[136]),
1353 HandleGrip, (XtPointer)child);
1354}
1355
1356/*
1357 * Function:
1358 * GetGCs
1359 *
1360 * Parameters:
1361 * w - paned widget
1362 */
1363static void
1364GetGCs(Widget w)
1365{
1366 PanedWidget pw = (PanedWidget)w;
1367 XtGCMask valuemask;
1368 XGCValues values;
1369
1370 /*
1371 * Draw pane borders in internal border color
1372 */
1373 values.foreground = pw->paned.internal_bp;
1374 valuemask = GCForeground(1L<<2);
1375 pw->paned.normgc = XtGetGC(w, valuemask, &values);
1376
1377 /*
1378 * Erase pane borders with background color
1379 */
1380 values.foreground = pw->core.background_pixel;
1381 valuemask = GCForeground(1L<<2);
1382 pw->paned.invgc = XtGetGC(w, valuemask, &values);
1383
1384 /*
1385 * Draw Track lines (animate pane borders) in
1386 * internal border color ^ bg color
1387 */
1388 values.function = GXinvert0xa;
1389 values.plane_mask = pw->paned.internal_bp ^ pw->core.background_pixel;
1390 values.subwindow_mode = IncludeInferiors1;
1391 valuemask = GCPlaneMask(1L<<1) | GCFunction(1L<<0) | GCSubwindowMode(1L<<15);
1392 pw->paned.flipgc = XtGetGC(w, valuemask, &values);
1393}
1394
1395/*
1396 * Function:
1397 * SetChildrenPrefSizes
1398 *
1399 * Parameters:
1400 * pw - paned widget
1401 *
1402 * Description:
1403 * Sets the preferred sizes of the children.
1404 */
1405static void
1406SetChildrenPrefSizes(PanedWidget pw, unsigned int off_size)
1407{
1408 Widget *childP;
1409 Boolean vert = IsVert(pw)((pw)->paned.orientation == XtorientVertical);
1410 XtWidgetGeometry request, reply;
1411
1412 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
1413 if (pw->paned.resize_children_to_pref || PaneInfo(*childP)((Pane)(*childP)->core.constraints)->size == 0 ||
1414 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->resize_to_pref) {
1415 if (PaneInfo(*childP)((Pane)(*childP)->core.constraints)->preferred_size != PANED_ASK_CHILD0)
1416 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->wp_size = PaneInfo(*childP)((Pane)(*childP)->core.constraints)->preferred_size;
1417 else {
1418 if(vert) {
1419 request.request_mode = CWWidth(1<<2);
1420 request.width = off_size;
1421 }
1422 else {
1423 request.request_mode = CWHeight(1<<3);
1424 request.height = off_size;
1425 }
1426
1427 if ((XtQueryGeometry(*childP, &request, &reply)
1428 == XtGeometryAlmost)
1429 && (reply.request_mode = (vert ? CWHeight(1<<3) : CWWidth(1<<2))))
1430 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->wp_size = GetRequestInfo(&reply, vert)((vert) ? (&reply)->height : (&reply)->width);
1431 else
1432 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->wp_size = PaneSize(*childP, vert)((vert) ? (((RectObj)*childP)->rectangle.height) : (((RectObj
)*childP)->rectangle.width))
;
1433 }
1434
1435 PaneInfo(*childP)((Pane)(*childP)->core.constraints)->size = PaneInfo(*childP)((Pane)(*childP)->core.constraints)->wp_size;
1436 }
1437}
1438
1439/*
1440 * Function:
1441 * ChangeAllGripCursors
1442 *
1443 * Parameters:
1444 * pw - paned widget
1445 *
1446 * Description:
1447 * Changes all the grip cursors.
1448 */
1449static void
1450ChangeAllGripCursors(PanedWidget pw)
1451{
1452 Widget *childP;
1453
1454 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
1455 Arg arglist[1];
1456 Cursor cursor;
1457
1458 if ((cursor = pw->paned.grip_cursor) == None0L) {
1459 if (IsVert(pw)((pw)->paned.orientation == XtorientVertical))
1460 cursor = pw->paned.v_grip_cursor;
1461 else
1462 cursor = pw->paned.h_grip_cursor;
1463 }
1464
1465 if (HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
) {
1466 XtSetArg(arglist[0], XtNcursor, cursor)((void)( (arglist[0]).name = ("cursor"), (arglist[0]).value =
(XtArgVal)(cursor) ))
;
1467 XtSetValues(PaneInfo(*childP)((Pane)(*childP)->core.constraints)->grip, arglist, 1);
1468 }
1469 }
1470}
1471
1472/*
1473 * Function:
1474 * PushPaneStack
1475 *
1476 * Parameters:
1477 * pw - paned widget
1478 * pane - pane that we are pushing
1479 *
1480 * Description:
1481 * Pushes a value onto the pane stack.
1482 */
1483static void
1484PushPaneStack(PanedWidget pw, Pane pane)
1485{
1486 PaneStack *stack = (PaneStack *)XtMalloc(sizeof(PaneStack));
1487
1488 stack->next = pw->paned.stack;
1489 stack->pane = pane;
1490 stack->start_size = pane->size;
1491
1492 pw->paned.stack = stack;
1493}
1494
1495/*
1496 * Function:
1497 * GetPaneStack
1498 *
1499 * Parameters:
1500 * pw - paned widget
1501 * shrink - True if we want to shrink this pane, False otherwise
1502 * pane - pane that we are popping (return)
1503 * start_size - size that this pane started at (return)
1504 *
1505 * Description:
1506 * Gets the top value from the pane stack.
1507 */
1508static void
1509GetPaneStack(PanedWidget pw, Boolint shrink, Pane *pane, int *start_size)
1510{
1511 if (pw->paned.stack == NULL((void*)0)) {
1512 *pane = NULL((void*)0);
1513 return;
1514 }
1515
1516 *pane = pw->paned.stack->pane;
1517 *start_size = pw->paned.stack->start_size;
1518
1519 if (shrink != ((*pane)->size > *start_size))
1520 *pane = NULL((void*)0);
1521}
1522
1523/*
1524 * Function:
1525 * PopPaneStack
1526 *
1527 * Parameters:
1528 * pw - paned widget
1529 *
1530 * Description:
1531 * Pops the top item off the pane stack.
1532 *
1533 * Returns: True if this is not the last element on the stack
1534 */
1535static Boolint
1536PopPaneStack(PanedWidget pw)
1537{
1538 PaneStack *stack = pw->paned.stack;
1539
1540 if (stack == NULL((void*)0))
1541 return (False0);
1542
1543 pw->paned.stack = stack->next;
1544 XtFree((char *)stack);
1545
1546 if (pw->paned.stack == NULL((void*)0))
1547 return (False0);
1548
1549 return (True1);
1550}
1551
1552/*
1553 * Function:
1554 * ClearPaneStack
1555 *
1556 * Parameters:
1557 * pw - paned widget
1558 *
1559 * Description:
1560 * Removes all entries from the pane stack.
1561 */
1562static void
1563ClearPaneStack(PanedWidget pw)
1564{
1565 while(PopPaneStack(pw))
1566 ;
1567}
1568
1569static void
1570XawPanedClassInitialize(void)
1571{
1572 XawInitializeWidgetSet();
1573 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtROrientation((char*)&XtStrings[1742]), XmuCvtStringToOrientation,
1574 NULL((void*)0), 0);
1575 XtSetTypeConverter(XtROrientation((char*)&XtStrings[1742]), XtRString((char*)&XtStrings[1797]), XmuCvtOrientationToString,
1576 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
1577}
1578
1579/* The Geometry Manager only allows changes after Realize if
1580 * allow_resize is True in the constraints record.
1581 *
1582 * For vertically paned widgets:
1583 *
1584 * It only allows height changes, but offers the requested height
1585 * as a compromise if both width and height changes were requested.
1586 *
1587 * For horizontal widgets the converse is true.
1588 * As all good Geometry Managers should, we will return No if the
1589 * request will have no effect; i.e. when the requestor is already
1590 * of the desired geometry.
1591 */
1592static XtGeometryResult
1593XawPanedGeometryManager(Widget w, XtWidgetGeometry *request,
1594 XtWidgetGeometry *reply)
1595{
1596 PanedWidget pw = (PanedWidget)XtParent(w)((w)->core.parent);
1597 XtGeometryMask mask = request->request_mode;
1598 Dimension old_size, old_wpsize, old_paned_size;
1599 Pane pane = PaneInfo(w)((Pane)(w)->core.constraints);
1600 Boolean vert = IsVert(pw)((pw)->paned.orientation == XtorientVertical);
1601 Dimension on_size, off_size;
1602 XtGeometryResult result;
1603 Boolean almost = False0;
1604
1605 /*
1606 * If any of the following is true, disallow the geometry change
1607 *
1608 * o The paned widget is realized and allow_resize is false for the pane
1609 * o The child did not ask to change the on_size
1610 * o The request is not a width or height request
1611 * o The requested size is the same as the current size
1612 */
1613
1614 if ((XtIsRealized((Widget)pw)(XtWindowOfObject((Widget)pw) != 0L) && !pane->allow_resize)
1615 || !(mask & (vert ? CWHeight(1<<3) : CWWidth(1<<2)))
1616 ||(mask & ~(CWWidth(1<<2) | CWHeight(1<<3)))
1617 || GetRequestInfo(request, vert)((vert) ? (request)->height : (request)->width) == PaneSize(w, vert)((vert) ? (((RectObj)w)->rectangle.height) : (((RectObj)w)
->rectangle.width))
)
1618 return (XtGeometryNo);
1619
1620 old_paned_size = PaneSize((Widget)pw, vert)((vert) ? (((RectObj)(Widget)pw)->rectangle.height) : (((RectObj
)(Widget)pw)->rectangle.width))
;
1621 old_wpsize = pane->wp_size;
1622 old_size = pane->size;
1623
1624 pane->wp_size = pane->size = GetRequestInfo(request, vert)((vert) ? (request)->height : (request)->width);
1625
1626 AdjustPanedSize(pw, PaneSize((Widget)pw, !vert)((!vert) ? (((RectObj)(Widget)pw)->rectangle.height) : (((
RectObj)(Widget)pw)->rectangle.width))
, &result, &on_size,
1627 &off_size);
1628
1629 /*
1630 * Fool the Refigure Locations proc to thinking that we are
1631 * a different on_size
1632 */
1633
1634 if (result != XtGeometryNo) {
1635 if (vert)
1636 XtHeight(pw)(((RectObj)pw)->rectangle.height) = on_size;
1637 else
1638 XtWidth(pw)(((RectObj)pw)->rectangle.width) = on_size;
1639 }
1640
1641 RefigureLocations(pw, PaneIndex(w)(((Pane)(w)->core.constraints)->position), AnyPane);
1642
1643 /*
1644 * Set up reply struct and reset core on_size
1645 */
1646 if (vert) {
1647 XtHeight(pw)(((RectObj)pw)->rectangle.height) = old_paned_size;
1648 reply->height = pane->size;
1649 reply->width = off_size;
1650 }
1651 else {
1652 XtWidth(pw)(((RectObj)pw)->rectangle.width) = old_paned_size;
1653 reply->height = off_size;
1654 reply->width = pane->size;
1655 }
1656
1657 /*
1658 * IF either of the following is true
1659 *
1660 * o There was a "off_size" request and the new "off_size" is different
1661 * from that requested
1662 * o There was no "off_size" request and the new "off_size" is different
1663 *
1664 * o The "on_size" we will allow is different from that requested
1665 *
1666 * THEN: set almost
1667 */
1668 if (!((vert ? CWWidth(1<<2) : CWHeight(1<<3)) & mask)) {
1669 if (vert)
1670 request->width = XtWidth(w)(((RectObj)w)->rectangle.width);
1671 else
1672 request->height = XtHeight(w)(((RectObj)w)->rectangle.height);
1673 }
1674
1675 almost = GetRequestInfo(request, !vert)((!vert) ? (request)->height : (request)->width) != GetRequestInfo(reply, !vert)((!vert) ? (reply)->height : (reply)->width);
1676 almost |= (GetRequestInfo(request, vert)((vert) ? (request)->height : (request)->width) != GetRequestInfo(reply, vert)((vert) ? (reply)->height : (reply)->width));
1677
1678 if ((mask & XtCWQueryOnly(1 << 7)) || almost) {
1679 pane->wp_size = old_wpsize;
1680 pane->size = old_size;
1681 RefigureLocations(pw, PaneIndex(w)(((Pane)(w)->core.constraints)->position), AnyPane);
1682 reply->request_mode = CWWidth(1<<2) | CWHeight(1<<3);
1683 if (almost)
1684 return (XtGeometryAlmost);
1685 }
1686 else {
1687 AdjustPanedSize(pw, PaneSize((Widget) pw, !vert)((!vert) ? (((RectObj)(Widget) pw)->rectangle.height) : ((
(RectObj)(Widget) pw)->rectangle.width))
, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1688 CommitNewLocations(pw); /* layout already refigured */
1689 }
1690
1691 return (XtGeometryDone);
1692}
1693
1694/*ARGSUSED*/
1695static void
1696XawPanedInitialize(Widget request, Widget cnew,
1697 ArgList args, Cardinal *num_args)
1698{
1699 PanedWidget pw = (PanedWidget)cnew;
1700
1701 GetGCs((Widget)pw);
1702
1703 pw->paned.recursively_called = False0;
1704 pw->paned.stack = NULL((void*)0);
1705 pw->paned.resize_children_to_pref = True1;
1706 pw->paned.num_panes = 0;
1707}
1708
1709static void
1710XawPanedRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
1711{
1712 PanedWidget pw = (PanedWidget)w;
1713 Widget *childP;
1714
1715 if ((attributes->cursor = pw->paned.cursor) != None0L)
1716 *valueMask |= CWCursor(1L<<14);
1717
1718 (*SuperClass((ConstraintWidgetClass)&constraintClassRec)->core_class.realize)(w, valueMask, attributes);
1719
1720 /*
1721 * Before we commit the new locations we need to realize all the panes and
1722 * their grips
1723 */
1724 ForAllPanes(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->paned.num_panes; (childP)
++)
{
1725 XtRealizeWidget(*childP);
1726 if (HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
)
1727 XtRealizeWidget(PaneInfo(*childP)((Pane)(*childP)->core.constraints)->grip);
1728 }
1729
1730 RefigureLocationsAndCommit(w);
1731 pw->paned.resize_children_to_pref = False0;
1732}
1733
1734static void
1735XawPanedDestroy(Widget w)
1736{
1737 ReleaseGCs(w);
1738}
1739
1740static void
1741ReleaseGCs(Widget w)
1742{
1743 PanedWidget pw = (PanedWidget)w;
1744
1745 XtReleaseGC(w, pw->paned.normgc);
1746 XtReleaseGC(w, pw->paned.invgc);
1747 XtReleaseGC(w, pw->paned.flipgc);
1748}
1749
1750static void
1751XawPanedInsertChild(Widget w)
1752{
1753 Pane pane = PaneInfo(w)((Pane)(w)->core.constraints);
1754
1755 /* insert the child widget in the composite children list with the
1756 superclass insert_child routine
1757 */
1758 (*SuperClass((ConstraintWidgetClass)&constraintClassRec)->composite_class.insert_child)(w);
1759
1760 if (!IsPane(w)((w)->core.widget_class != gripWidgetClass))
1761 return;
1762
1763 if (pane->show_grip == True1) {
1764 CreateGrip(w);
1765 if (pane->min == PANED_GRIP_SIZE0)
1766 pane->min = PaneSize(pane->grip, IsVert((PanedWidget)XtParent(w)))(((((PanedWidget)((w)->core.parent))->paned.orientation
== XtorientVertical)) ? (((RectObj)pane->grip)->rectangle
.height) : (((RectObj)pane->grip)->rectangle.width))
;
1767 }
1768 else {
1769 if (pane->min == PANED_GRIP_SIZE0)
1770 pane->min = 1;
1771 pane->grip = NULL((void*)0);
1772 }
1773
1774 pane->size = 0;
1775 pane->paned_adjusted_me = False0;
1776}
1777
1778static void
1779XawPanedDeleteChild(Widget w)
1780{
1781 /* remove the subwidget info and destroy the grip */
1782 if (IsPane(w)((w)->core.widget_class != gripWidgetClass) && HasGrip(w)(((Pane)(w)->core.constraints)->grip != ((void*)0)))
1783 XtDestroyWidget(PaneInfo(w)((Pane)(w)->core.constraints)->grip);
1784
1785 /* delete the child widget in the composite children list with the
1786 superclass delete_child routine
1787 */
1788 (*SuperClass((ConstraintWidgetClass)&constraintClassRec)->composite_class.delete_child)(w);
1789}
1790
1791static void
1792XawPanedChangeManaged(Widget w)
1793{
1794 PanedWidget pw = (PanedWidget)w;
1795 Boolean vert = IsVert(pw)((pw)->paned.orientation == XtorientVertical);
1796 Dimension size;
1797 Widget *childP;
1798
1799 if (pw->paned.recursively_called++)
1800 return;
1801
1802 /*
1803 * If the size is zero then set it to the size of the widest or tallest pane
1804 */
1805
1806 if ((size = PaneSize((Widget)pw, !vert)((!vert) ? (((RectObj)(Widget)pw)->rectangle.height) : (((
RectObj)(Widget)pw)->rectangle.width))
) == 0) {
1807 size = 1;
1808 ForAllChildren(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->composite.num_children; (
childP)++)
1809 if (XtIsManaged(*childP) && (PaneSize(*childP, !vert)((!vert) ? (((RectObj)*childP)->rectangle.height) : (((RectObj
)*childP)->rectangle.width))
> size))
1810 size = PaneSize(*childP, !vert)((!vert) ? (((RectObj)*childP)->rectangle.height) : (((RectObj
)*childP)->rectangle.width))
;
1811 }
1812
1813 ManageAndUnmanageGrips(pw);
1814 pw->paned.recursively_called = False0;
1815 ResortChildren(pw);
1816
1817 pw->paned.num_panes = 0;
1818 ForAllChildren(pw, childP)for ((childP) = (pw)->composite.children; (childP) < (pw
)->composite.children + (pw)->composite.num_children; (
childP)++)
1819 if (IsPane(*childP)((*childP)->core.widget_class != gripWidgetClass)) {
1820 if (XtIsManaged(*childP)) {
1821 Pane pane = PaneInfo(*childP)((Pane)(*childP)->core.constraints);
1822
1823 if (HasGrip(*childP)(((Pane)(*childP)->core.constraints)->grip != ((void*)0
))
)
1824 PaneInfo(pane->grip)((Pane)(pane->grip)->core.constraints)->position = pw->paned.num_panes;
1825 pane->position = pw->paned.num_panes; /* TEMPORY -CDP 3/89 */
1826 pw->paned.num_panes++;
1827 }
1828 else
1829 break; /* This list is already sorted */
1830 }
1831
1832 SetChildrenPrefSizes((PanedWidget) w, size);
1833
1834 /*
1835 * ForAllPanes can now be used
1836 */
1837 if (PaneSize((Widget) pw, vert)((vert) ? (((RectObj)(Widget) pw)->rectangle.height) : (((
RectObj)(Widget) pw)->rectangle.width))
== 0)
1838 AdjustPanedSize(pw, size, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1839
1840 if (XtIsRealized((Widget)pw)(XtWindowOfObject((Widget)pw) != 0L))
1841 RefigureLocationsAndCommit((Widget)pw);
1842}
1843
1844static void
1845XawPanedResize(Widget w)
1846{
1847 SetChildrenPrefSizes((PanedWidget)w,
1848 PaneSize(w, !IsVert((PanedWidget)w))((!(((PanedWidget)w)->paned.orientation == XtorientVertical
)) ? (((RectObj)w)->rectangle.height) : (((RectObj)w)->
rectangle.width))
);
1849 RefigureLocationsAndCommit(w);
1850}
1851
1852/*ARGSUSED*/
1853static void
1854XawPanedRedisplay(Widget w, XEvent *event, Region region)
1855{
1856 DrawInternalBorders((PanedWidget)w)_DrawInternalBorders(((PanedWidget)w), ((PanedWidget)w)->paned
.normgc)
;
1857}
1858
1859/*ARGSUSED*/
1860static Boolean
1861XawPanedSetValues(Widget old, Widget request, Widget cnew,
1862 ArgList args, Cardinal *num_args)
1863{
1864 PanedWidget old_pw = (PanedWidget)old;
1865 PanedWidget new_pw = (PanedWidget)cnew;
1866 Boolean redisplay = False0;
1867
1868 if ((old_pw->paned.cursor != new_pw->paned.cursor) && XtIsRealized(cnew)(XtWindowOfObject(cnew) != 0L))
1869 XDefineCursor(XtDisplay(cnew)(((cnew)->core.screen)->display), XtWindow(cnew)((cnew)->core.window), new_pw->paned.cursor);
1870
1871 if (old_pw->paned.internal_bp != new_pw->paned.internal_bp ||
1872 old_pw->core.background_pixel != new_pw->core.background_pixel) {
1873 ReleaseGCs(old);
1874 GetGCs(cnew);
1875 redisplay = True1;
1876 }
1877
1878 if (old_pw->paned.grip_cursor != new_pw->paned.grip_cursor ||
1879 old_pw->paned.v_grip_cursor != new_pw->paned.v_grip_cursor ||
1880 old_pw->paned.h_grip_cursor != new_pw->paned.h_grip_cursor)
1881 ChangeAllGripCursors(new_pw);
1882
1883 if (IsVert(old_pw)((old_pw)->paned.orientation == XtorientVertical) != IsVert(new_pw)((new_pw)->paned.orientation == XtorientVertical)) {
1884 /*
1885 * We are fooling the paned widget into thinking that is needs to
1886 * fully refigure everything, which is what we want
1887 */
1888 if (IsVert(new_pw)((new_pw)->paned.orientation == XtorientVertical))
1889 XtWidth(new_pw)(((RectObj)new_pw)->rectangle.width) = 0;
1890 else
1891 XtHeight(new_pw)(((RectObj)new_pw)->rectangle.height) = 0;
1892
1893 new_pw->paned.resize_children_to_pref = True1;
1894 XawPanedChangeManaged(cnew); /* Seems weird, but does the right thing */
1895 new_pw->paned.resize_children_to_pref = False0;
1896 if (new_pw->paned.grip_cursor == None0L)
1897 ChangeAllGripCursors(new_pw);
1898 return (True1);
1899 }
1900
1901 if (old_pw->paned.internal_bw != new_pw->paned.internal_bw) {
1902 AdjustPanedSize(new_pw, PaneSize(cnew, !IsVert(old_pw))((!((old_pw)->paned.orientation == XtorientVertical)) ? ((
(RectObj)cnew)->rectangle.height) : (((RectObj)cnew)->rectangle
.width))
,
1903 NULL((void*)0), NULL((void*)0), NULL((void*)0));
1904 RefigureLocationsAndCommit(cnew);
1905 return (True1); /* We have done a full configuration, return */
1906 }
1907
1908 if (old_pw->paned.grip_indent != new_pw->paned.grip_indent &&
1909 XtIsRealized(cnew)(XtWindowOfObject(cnew) != 0L)) {
1910 CommitNewLocations(new_pw);
1911 redisplay = True1;
1912 }
1913
1914 return (redisplay);
1915}
1916
1917/*ARGSUSED*/
1918static Boolean
1919XawPanedPaneSetValues(Widget old, Widget request, Widget cnew,
1920 ArgList args, Cardinal *num_args)
1921{
1922 Pane old_pane = PaneInfo(old)((Pane)(old)->core.constraints);
1923 Pane new_pane = PaneInfo(cnew)((Pane)(cnew)->core.constraints);
1924 Boolean redisplay = False0;
1925
1926 /* Check for new min and max */
1927 if (old_pane->min != new_pane->min || old_pane->max != new_pane->max)
1928 XawPanedSetMinMax(cnew, (int)new_pane->min, (int)new_pane->max);
1929
1930 /* Check for change in XtNshowGrip */
1931 if (old_pane->show_grip != new_pane->show_grip) {
1932 if (new_pane->show_grip == True1) {
1933 CreateGrip(cnew);
1934 if (XtIsRealized(XtParent(cnew))(XtWindowOfObject(((cnew)->core.parent)) != 0L)) {
1935 if (XtIsManaged(cnew)) /* if paned is unrealized this will
1936 happen automatically at realize time
1937 */
1938 XtManageChild(PaneInfo(cnew)((Pane)(cnew)->core.constraints)->grip); /* manage the grip */
1939 XtRealizeWidget(PaneInfo(cnew)((Pane)(cnew)->core.constraints)->grip); /* realize the grip */
1940 CommitNewLocations((PanedWidget)XtParent(cnew)((cnew)->core.parent));
1941 }
1942 }
1943 else if (HasGrip(old)(((Pane)(old)->core.constraints)->grip != ((void*)0))) {
1944 XtDestroyWidget(old_pane->grip);
1945 new_pane->grip = NULL((void*)0);
1946 redisplay = True1;
1947 }
1948 }
1949
1950 return (redisplay);
1951}
1952
1953/*
1954 * Public routines
1955 */
1956/*
1957 * Function:
1958 * XawPanedSetMinMax
1959 *
1960 * Parameters:
1961 * widget - widget that is a child of the Paned widget
1962 * min - new min and max size for the pane
1963 * max - ""
1964 *
1965 * Description:
1966 * Sets the min and max size for a pane.
1967 */
1968void
1969XawPanedSetMinMax(Widget widget, int min, int max)
1970{
1971 Pane pane = PaneInfo(widget)((Pane)(widget)->core.constraints);
1972
1973 pane->min = min;
1974 pane->max = max;
1975 RefigureLocationsAndCommit(widget->core.parent);
1976}
1977
1978/*
1979 * Function:
1980 * XawPanedGetMinMax
1981 *
1982 * Parameters:
1983 * widget - widget that is a child of the Paned widget
1984 * min - current min and max size for the pane (return)
1985 * max - ""
1986 *
1987 * Description:
1988 * Gets the min and max size for a pane.
1989 */
1990void
1991XawPanedGetMinMax(Widget widget, int *min, int *max)
1992{
1993 Pane pane = PaneInfo(widget)((Pane)(widget)->core.constraints);
1994
1995 *min = pane->min;
1996 *max = pane->max;
1997}
1998
1999/*
2000 * Function:
2001 * XawPanedSetRefigureMode
2002 *
2003 * Parameters:
2004 * w - paned widget
2005 * mode - if False then inhibit refigure
2006 *
2007 * Description:
2008 * Allows a flag to be set the will inhibit
2009 * the paned widgets relayout routine.
2010 */
2011void
2012XawPanedSetRefigureMode(Widget w,
2013#if NeedWidePrototypes0
2014 int mode
2015#else
2016 Boolean mode
2017#endif
2018)
2019{
2020 ((PanedWidget)w)->paned.refiguremode = mode;
2021 RefigureLocationsAndCommit(w);
2022}
2023
2024/*
2025 * Function:
2026 * XawPanedGetNumSub
2027 *
2028 * Parameters:
2029 * w - paned widget
2030 *
2031 * Description:
2032 * Returns the number of panes in the paned widget.
2033 * Returns:
2034 * the number of panes in the paned widget
2035 */
2036int
2037XawPanedGetNumSub(Widget w)
2038{
2039 return (((PanedWidget)w)->paned.num_panes);
2040}
2041
2042/*
2043 * Function:
2044 * XawPanedAllowResize
2045 *
2046 * Parameters:
2047 * widget - child of the paned widget
2048 *
2049 * Description:
2050 * Allows a flag to be set that determines if the paned
2051 * widget will allow geometry requests from this child.
2052 */
2053void
2054XawPanedAllowResize(Widget widget,
2055#if NeedWidePrototypes0
2056 int allow_resize
2057#else
2058 Boolean allow_resize
2059#endif
2060)
2061{
2062 PaneInfo(widget)((Pane)(widget)->core.constraints)->allow_resize = allow_resize;
2063}