1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 /************************************************************
26 * INCLUDE FILES
27 *************************************************************/
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <X11/IntrinsicP.h>
31
32 #include "XmI.h"
33 #include <Xm/XmP.h>
34 #include <Xm/PrimitiveP.h>
35 #include <Xm/GadgetP.h>
36 #include <Xm/ExtP.h>
37
38 /************************************************************
39 * TYPEDEFS AND DEFINES
40 *************************************************************/
41
42 typedef struct _PixmapCache {
43 Screen *screen;
44 Pixmap pixmap;
45 Pixel foreground, background;
46 unsigned int depth;
47 int ref_count;
48 struct _PixmapCache *next;
49 } CacheEntry;
50
51 /************************************************************
52 * MACROS
53 *************************************************************/
54
55 /************************************************************
56 * GLOBAL DECLARATIONS
57 *************************************************************/
58
59
60
61 String xm_std_filter[] = { XmNx, XmNy, XmNwidth, XmNheight,
62 XmNdestroyCallback, XmNsensitive, XmNuserData,
63 XmNnavigationType, NULL };
64
65 String xm_std_constraint_filter[] = { XmNx, XmNy, XmNwidth, XmNheight,
66 XmNdestroyCallback, XmNsensitive, XmNuserData,
67 XmNnavigationType, XmNbottomAttachment,
68 XmNbottomOffset, XmNbottomPosition, XmNbottomWidget,
69 XmNbottomAttachment, XmNtopAttachment,
70 XmNleftOffset, XmNleftPosition, XmNleftWidget,
71 XmNtopOffset, XmNtopPosition, XmNtopWidget,
72 XmNrightOffset, XmNrightPosition, XmNrightWidget,
73 XmNrightAttachment, XmNleftAttachment,
74 XmNallowResize, XmNpaneMinimum, XmNshowSash,
75 XmNpaneMaximum, XmNpreferredPaneSize,
76 XmNresizeToPreferred, XmNskipAdjust,
77 XmNdFieldPrefHeight, XmNdFieldMaxHeight,
78 XmNdFieldPrefWidth, XmNdFieldMaxWidth,
79 XmNdFieldMinHeight, XmNdFieldMinWidth,
80 /* CR03683 */ XmNpixmapWidth, XmNpixmapHeight,
81 NULL };
82
83 /************************************************************
84 * EXTERNAL DECLARATIONS
85 *************************************************************/
86
87 /************************************************************
88 * STATIC DECLARATIONS
89 *************************************************************/
90
91 static CacheEntry *pixmapCache = NULL;
92
93 /************************************************************
94 * GLOBAL CODE
95 *************************************************************/
96
97 /* Function Name: _XmRequestNewSize
98 * Description: Asks our parent for a new size.
99 * Arguments: w - the data request tree widget.
100 * query_only - only ask what would happen, don't
101 * change anything.
102 * width, height - size to request.
103 * r_width, r_height - allowed size.
104 * Returns: none.
105 */
106
107 XtGeometryResult
_XmRequestNewSize(Widget w,Boolean query_only,Dimension width,Dimension height,Dimension * r_width,Dimension * r_height)108 _XmRequestNewSize(Widget w, Boolean query_only,
109 Dimension width, Dimension height,
110 Dimension * r_width, Dimension * r_height)
111 {
112 XtGeometryResult ret_val;
113 XtWidgetGeometry request, result;
114
115 request.width = width;
116 request.height = height;
117 request.request_mode = CWWidth | CWHeight;
118
119 if (query_only)
120 request.request_mode |= XtCWQueryOnly;
121
122 ret_val = XtMakeGeometryRequest(w, &request, &result);
123
124 if (ret_val == XtGeometryAlmost) {
125 if (!query_only)
126 ret_val = XtMakeGeometryRequest(w, &result, NULL);
127
128 *r_width = result.width;
129 *r_height = result.height;
130 }
131 else if (ret_val == XtGeometryYes) {
132 *r_width = request.width;
133 *r_height = request.height;
134 }
135 else {
136 *r_width = w->core.width;
137 *r_height = w->core.height;
138 }
139
140 return(ret_val);
141 }
142
143 /* Function Name: _XmHWQuery
144 * Description: Handles much of the generic height and width query
145 * geometry processing.
146 * Arguments: w - the widget to process.
147 * intended, preferred - The values from the real query
148 * procedure. It is assumed
149 * that preferred is already
150 * filled with the correct desired
151 * size.
152 * Returns: an XtGeometryResult.
153 */
154
155 XtGeometryResult
_XmHWQuery(Widget w,XtWidgetGeometry * intended,XtWidgetGeometry * preferred)156 _XmHWQuery(Widget w, XtWidgetGeometry * intended, XtWidgetGeometry * preferred)
157 {
158 if (intended == NULL) {
159 if ((preferred->width == w->core.width) &&
160 (preferred->height == w->core.height))
161 {
162 return(XtGeometryNo);
163 }
164 }
165 else {
166 if ((intended->request_mode & CWWidth) &&
167 (intended->request_mode & CWHeight))
168 {
169 if ((intended->width == preferred->width) &&
170 (intended->height == preferred->height))
171 {
172 return(XtGeometryYes);
173 }
174 else {
175 return(XtGeometryNo);
176 }
177 }
178 }
179
180 preferred->request_mode = CWWidth | CWHeight;
181 return(XtGeometryAlmost);
182 }
183
184 /* Function Name: _XmGadgetWarning
185 * Description: Checks to see if this is a gadget. If it is then
186 * print out a warning, and return True.
187 * Arguments: w - the widget to check.
188 * Returns: True if this object is a gadget.
189 */
190
191 Boolean
_XmGadgetWarning(Widget w)192 _XmGadgetWarning(Widget w)
193 {
194 if (!XtIsRectObj(w) || XtIsWidget(w))
195 return(False);
196
197 XmeWarning(XtParent(w), XmNnoGadgetSupportMsg);
198
199 return(True);
200 }
201
202 /* Function Name: _XmGetFocus
203 * Description: Gets the XmFocus.
204 * Arguments: w - the icon button widget.
205 * event - the event that caused this action.
206 * params, num_params - action routine parameters.
207 * Returns: none.
208 */
209
210 /* ARGSUSED */
211 void
_XmGetFocus(Widget w,XEvent * event,String * params,Cardinal * num_params)212 _XmGetFocus(Widget w, XEvent * event, String * params, Cardinal * num_params)
213 {
214 #ifdef VMS
215 if (XtIsRealized(w))
216 #endif
217 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
218 }
219
220 /* Function Name: _XmFilterArgs
221 * Description: Filters certain resources out of an argument list.
222 * Arguments: args, num_args - the input argument list.
223 * filter - the list of resources (by name) to remove.
224 * RETURNED filtered_args, num_filtered_args - new filtered list.
225 * Returns: none.
226 *
227 * NOTE The caller of this function is responsible for freeing "filtered_args"
228 * with XtFree() when it is no longer in use.
229 */
230
231 void
_XmFilterArgs(ArgList args,Cardinal num_args,String * filter,ArgList * filtered_args,Cardinal * num_filtered_args)232 _XmFilterArgs(ArgList args, Cardinal num_args, String *filter,
233 ArgList *filtered_args, Cardinal *num_filtered_args)
234 {
235 ArgList fargs = (ArgList) XtMalloc(sizeof(Arg) * num_args);
236 register int i;
237 String *ptr;
238
239 *filtered_args = fargs;
240 *num_filtered_args = 0;
241 for (i = 0; i < num_args; i++) {
242 Boolean match = False;
243 for (ptr = filter; *ptr != NULL; ptr++) {
244 if (streq(*ptr, args[i].name)) {
245 match = True;
246 break;
247 }
248 }
249 if (!match) {
250 *fargs++ = args[i];
251 (*num_filtered_args)++;
252 }
253 }
254 }
255
256 /* Function Name: _XmSetValuesOnChildren
257 * Description: Calls setvalues on all children of this widget,
258 * and then recurses.
259 * Arguments: w - the widget to set.
260 * args, num_args - arguments to set.
261 * Returns: none.
262 */
263
264 void
_XmSetValuesOnChildren(Widget w,ArgList args,Cardinal num_args)265 _XmSetValuesOnChildren(Widget w, ArgList args, Cardinal num_args)
266 {
267 Widget *childP;
268
269 if (!XtIsSubclass(w, compositeWidgetClass))
270 return;
271
272 ForAllChildren((CompositeWidget) w, childP) {
273 XtSetValues(*childP, args, num_args);
274 _XmSetValuesOnChildren(*childP, args, num_args);
275 }
276 }
277
278 /* Function Name: _XmUtilIsSubclassByNameQ
279 * Description: Determines whether this is a subclass of the named
280 * class.
281 * Arguments: w - the widget to check.
282 * nameq - a quarkified name for the class to check.
283 * Returns: True if this is a subclass.
284 */
285
286 Boolean
_XmUtilIsSubclassByNameQ(Widget w,XrmQuark nameq)287 _XmUtilIsSubclassByNameQ(Widget w, XrmQuark nameq)
288 {
289 WidgetClass class;
290
291 Boolean returnValue = False;
292
293 _XmProcessLock();
294 for (class = XtClass(w) ;
295 class != NULL ;
296 class = class->core_class.superclass)
297 {
298 if (nameq == XrmStringToQuark(class->core_class.class_name))
299 {
300 returnValue = True;
301 break;
302 }
303 }
304 _XmProcessUnlock();
305
306 return(returnValue);
307 }
308
309 /* Function Name: _XmGetMBStringFromXmString
310 * Description: Given an Xm String, returns an MB string
311 * Arguments: xmstr - an Xm String.
312 * Returns: A multi byte string.
313 */
314
315 String
_XmGetMBStringFromXmString(XmString xmstr)316 _XmGetMBStringFromXmString(XmString xmstr)
317 {
318 String text;
319 XmStringContext context; /* context for conversion */
320 char *newText; /* new text string */
321 XmStringCharSet charset; /* dummy */
322 XmStringDirection direction; /* dummy */
323 XmStringComponentType u_tag; /* is newline */
324 int length; /* length of string */
325 unsigned short u_length; /* bogus length */
326 unsigned char *u_value; /* bogus value */
327 XmStringComponentType type; /* type */
328 Boolean done, separator; /* done with it */
329
330 if ( !XmStringInitContext(&context, xmstr) )
331 {
332 XmStringFree(xmstr);
333 return(NULL);
334 }
335
336 /*
337 * First path to get length.
338 */
339 length = 0;
340 if ( XmStringPeekNextComponent(context) == XmSTRING_COMPONENT_UNKNOWN ) {
341 XmStringFree(xmstr);
342 XmStringFreeContext(context);
343 return(NULL);
344 }
345
346 done = False;
347 while( !done )
348 {
349 newText = NULL; /* By source code inspection I have */
350 charset = NULL; /* Determined that this will make sure */
351 u_value = NULL; /* that no memory is leaked (I hope). */
352
353 type = XmStringGetNextComponent( context, &newText, &charset,
354 &direction, &u_tag, &u_length, &u_value );
355
356 switch( type )
357 {
358 case XmSTRING_COMPONENT_TEXT:
359 case XmSTRING_COMPONENT_LOCALE_TEXT:
360 length += strlen( newText );
361 break;
362 case XmSTRING_COMPONENT_SEPARATOR:
363 length += 1;
364 break;
365 case XmSTRING_COMPONENT_USER_BEGIN:
366 case XmSTRING_COMPONENT_USER_END:
367 case XmSTRING_COMPONENT_CHARSET:
368 case XmSTRING_COMPONENT_DIRECTION:
369 break;
370 case XmSTRING_COMPONENT_END:
371 default:
372 done = True;
373 }
374
375 XtFree((XtPointer) newText);
376 XtFree((XtPointer) charset);
377 XtFree((XtPointer) u_value);
378 }
379
380 /*
381 * If XmStringGetNextComponent() fails on the current xmstring,
382 * try by using XmStringGetNextSegment(). AIX 4.3.2 currently
383 * fails to obtain the compound string from
384 * XmStringGetNextComponent. (Change Reguest: CR03841)
385 */
386
387 if(length == 0) {
388 while ( XmStringGetNextSegment(context, &newText, &charset,
389 &direction, &separator) ) {
390
391 length = strlen(newText);
392 if (separator == True) {
393 length += 1; ;
394 }
395
396 text = XtMalloc( length + 1 );
397 text[0] = '\0';
398 strcat(text, newText);
399
400 if (separator == True) {
401 strcat(text, "\n");
402 }
403
404 XtFree(newText);
405 XmStringFreeContext(context);
406
407 return (text);
408 }
409 }
410
411 /*
412 * Failed to obtain any compound string, return with NULL pointer.
413 */
414 if(length == 0) return(NULL);
415
416 XmStringFreeContext( context );
417 text = XtMalloc( length + 1 );
418 text[0] = '\0';
419
420 /*
421 * Fill in the string.
422 */
423 XmStringInitContext(&context, xmstr);
424
425 done = False;
426 while( !done )
427 {
428 newText = NULL; /* By source code inspection I have */
429 charset = NULL; /* Determined that this will make sure */
430 u_value = NULL; /* that no memory is leaked (I hope). */
431
432 type = XmStringGetNextComponent( context, &newText, &charset,
433 &direction, &u_tag, &u_length, &u_value );
434 switch( type )
435 {
436 case XmSTRING_COMPONENT_TEXT:
437 case XmSTRING_COMPONENT_LOCALE_TEXT:
438 strcat(text, newText);
439 break;
440 case XmSTRING_COMPONENT_SEPARATOR:
441 strcat(text, "\n");
442 break;
443 case XmSTRING_COMPONENT_USER_BEGIN:
444 case XmSTRING_COMPONENT_USER_END:
445 case XmSTRING_COMPONENT_CHARSET:
446 case XmSTRING_COMPONENT_DIRECTION:
447 break;
448 case XmSTRING_COMPONENT_END:
449 default:
450 done = True;
451 }
452
453 XtFree((XtPointer) newText);
454 XtFree((XtPointer) charset);
455 XtFree((XtPointer) u_value);
456 }
457
458 XmStringFreeContext(context);
459 return(text);
460 }
461
462 /* Function Name: _XiWoveWidget
463 * Description: Wrapper for XtMoveWidget to deal with Motif1.2
464 * drag N drop.
465 * Arguments: w - The widget to change
466 * x, y - The new location for this widget.
467 * Returns: none.
468 */
469
470 void
_XmMoveWidget(Widget w,Position x,Position y)471 _XmMoveWidget(Widget w, Position x, Position y)
472 {
473 XmDropSiteStartUpdate(w);
474 XtMoveWidget(w, x, y);
475 XmDropSiteEndUpdate(w);
476 }
477
478 /* Function Name: _XmResizeWidget
479 * Description: Wrapper for XtResizeWidget to deal with Motif1.2
480 * drag N drop.
481 * Arguments: w - The widget to change
482 * width, height, bw - The new size for the widget.
483 * Returns: none.
484 */
485
486 void
_XmResizeWidget(Widget w,Dimension width,Dimension height,Dimension bw)487 _XmResizeWidget(Widget w, Dimension width, Dimension height, Dimension bw)
488 {
489 XmDropSiteStartUpdate(w);
490 XtResizeWidget(w, width, height, bw);
491 XmDropSiteEndUpdate(w);
492 }
493
494 /* Function Name: _XmConfigureWidget
495 * Description: Wrapper for XtConfigureWidget to deal with Motif1.2
496 * drag N drop.
497 * Arguments: w - The widget to change
498 * x, y - The new location for this widget.
499 * width, height, bw - The new size for the widget.
500 * Returns: none.
501 */
502
503 void
_XmConfigureWidget(Widget w,Position x,Position y,Dimension width,Dimension height,Dimension bw)504 _XmConfigureWidget(Widget w, Position x, Position y,
505 Dimension width, Dimension height, Dimension bw)
506 {
507 /* 0x0 will sometimes result in a BadValue Error for X_ConfigureWindow */
508 if (height < 1) height = 1;
509 if (width < 1) width = 1;
510
511 XmDropSiteStartUpdate(w);
512 XtConfigureWidget(w, x, y, width, height, bw);
513 XmDropSiteEndUpdate(w);
514
515 }
516
517 /************************************************************
518 *
519 * This code is taken from the MIT X Consortium's Xmu
520 * Utility Library.
521 *
522 ************************************************************/
523
524 #define XK_LATIN1
525 #include <X11/keysymdef.h>
526
527 /*
528 * ISO Latin-1 case conversion routine
529 */
530
531 /*
532 * Function:
533 * XmCompareISOLatin1(first, second)
534 * Description:
535 * Compares two ISO Latin 1 strings to determine if they are equivalent.
536 * Case is not considered for the comparison.
537 * Input:
538 * first : char * - the first ISO Latin 1 String
539 * second : char * - the second ISO Latin 1 String
540 * Output:
541 * int - (-1) -> first < second
542 * ( 0) -> first == second
543 * ( 1) -> first > second
544 */
545 int
546 #ifndef _NO_PROTO
XmCompareISOLatin1(char * first,char * second)547 XmCompareISOLatin1(char *first, char *second)
548 #else
549 XmCompareISOLatin1(first, second)
550 char *first, *second;
551 #endif
552 {
553 register unsigned char *ap, *bp;
554
555 for (ap = (unsigned char *) first, bp = (unsigned char *) second;
556 *ap && *bp; ap++, bp++) {
557 register unsigned char a, b;
558
559 if ((a = *ap) != (b = *bp)) {
560 /* try lowercasing and try again */
561
562 if ((a >= XK_A) && (a <= XK_Z))
563 a += (XK_a - XK_A);
564 else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
565 a += (XK_agrave - XK_Agrave);
566 else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
567 a += (XK_oslash - XK_Ooblique);
568
569 if ((b >= XK_A) && (b <= XK_Z))
570 b += (XK_a - XK_A);
571 else if ((b >= XK_Agrave) && (b <= XK_Odiaeresis))
572 b += (XK_agrave - XK_Agrave);
573 else if ((b >= XK_Ooblique) && (b <= XK_Thorn))
574 b += (XK_oslash - XK_Ooblique);
575
576 if (a != b) break;
577 }
578 }
579 return (((int) *bp) - ((int) *ap));
580 }
581
582 void
XmCopyISOLatin1Lowered(dst,src)583 XmCopyISOLatin1Lowered(dst, src)
584 char *dst, *src;
585 {
586 register unsigned char *dest, *source;
587
588 for (dest = (unsigned char *)dst, source = (unsigned char *)src;
589 *source;
590 source++, dest++)
591 {
592 if ((*source >= XK_A) && (*source <= XK_Z))
593 *dest = *source + (XK_a - XK_A);
594 else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis))
595 *dest = *source + (XK_agrave - XK_Agrave);
596 else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn))
597 *dest = *source + (XK_oslash - XK_Ooblique);
598 else
599 *dest = *source;
600 }
601 *dest = '\0';
602 }
603
604 /*
605 * Creates a stippled pixmap of specified depth
606 * caches these so that multiple requests share the pixmap
607 */
608
609 #define pixmap_width 2
610 #define pixmap_height 2
611
612 Pixmap
XiCreateStippledPixmap(Screen * screen,Pixel fore,Pixel back,unsigned int depth)613 XiCreateStippledPixmap(Screen *screen,
614 Pixel fore, Pixel back, unsigned int depth)
615 {
616 register Display *display = DisplayOfScreen(screen);
617 CacheEntry *cachePtr;
618 Pixmap stippled_pixmap;
619 static unsigned char pixmap_bits[] = {
620 0x02, 0x01,
621 };
622
623 /* see if we already have a pixmap suitable for this screen */
624 for (cachePtr = pixmapCache; cachePtr; cachePtr = cachePtr->next) {
625 if (cachePtr->screen == screen && cachePtr->foreground == fore &&
626 cachePtr->background == back && cachePtr->depth == depth)
627 return( cachePtr->ref_count++, cachePtr->pixmap );
628 }
629
630 stippled_pixmap = XCreatePixmapFromBitmapData (display,
631 RootWindowOfScreen(screen), (char *)pixmap_bits,
632 pixmap_width, pixmap_height, fore, back, depth);
633
634 /* and insert it at the head of the cache */
635 cachePtr = XtNew(CacheEntry);
636 cachePtr->screen = screen;
637 cachePtr->foreground = fore;
638 cachePtr->background = back;
639 cachePtr->depth = depth;
640 cachePtr->pixmap = stippled_pixmap;
641 cachePtr->ref_count = 1;
642
643 _XmProcessLock();
644 cachePtr->next = pixmapCache;
645 pixmapCache = cachePtr;
646 _XmProcessUnlock();
647 return( stippled_pixmap );
648 }
649
650 void
XiReleaseStippledPixmap(Screen * screen,Pixmap pixmap)651 XiReleaseStippledPixmap(Screen *screen, Pixmap pixmap)
652 {
653 register Display *display = DisplayOfScreen(screen);
654 CacheEntry *cachePtr, **prevP;
655
656 _XmProcessLock();
657 for (prevP = &pixmapCache, cachePtr = pixmapCache; cachePtr;)
658 {
659 if (cachePtr->screen == screen && cachePtr->pixmap == pixmap)
660 {
661 if (--cachePtr->ref_count == 0)
662 {
663 XFreePixmap( display, pixmap );
664 *prevP = cachePtr->next;
665 XtFree( (char*)cachePtr );
666 break;
667 }
668 }
669 prevP = &cachePtr->next;
670 cachePtr = *prevP;
671 }
672 _XmProcessUnlock();
673 }
674
675 /*
676 * Function:
677 * XmCompareXtWidgetGeometryToWidget(geom, widget)
678 * Description:
679 * This function compares an XtWidgetGeometry structure to the
680 * actual values contained in a widget.
681 * Input:
682 * geom : XtWidgetGeometry* - the geometry to test against the widget
683 * widget : Widget - the widget to use in the comparison
684 * Output:
685 * Boolean - True if the geometry fits the specified widget, else False
686 */
687 Boolean
XmCompareXtWidgetGeometryToWidget(XtWidgetGeometry * geom,Widget widget)688 XmCompareXtWidgetGeometryToWidget(XtWidgetGeometry *geom, Widget widget)
689 {
690 Boolean returnValue = True;
691
692 _XmProcessLock();
693 if( (geom->request_mode & CWX && geom->x != widget->core.x) ||
694 (geom->request_mode & CWY && geom->y != widget->core.y) ||
695 (geom->request_mode & CWWidth && geom->width != XtHeight(widget)) ||
696 (geom->request_mode & CWHeight && geom->height != XtHeight(widget)) ||
697 (geom->request_mode & CWBorderWidth && geom->border_width != widget->core.border_width) )
698 {
699 returnValue = False;
700 }
701 _XmProcessUnlock();
702 return( returnValue );
703 }
704
705 /*
706 * Function:
707 * XmCompareXtWidgetGeometry(geom1, geom2)
708 * Description:
709 * Compares to XtWidgetGeometry structures to check for equality.
710 * Input:
711 * geom1 : XtWidgetGeometry* - geometry to compare
712 * geom2 : XtWidgetGeometry* - geometry to compare
713 * Output:
714 * Boolean - True if both the request_mode and values match, else False
715 */
716 Boolean
XmCompareXtWidgetGeometry(XtWidgetGeometry * geom1,XtWidgetGeometry * geom2)717 XmCompareXtWidgetGeometry(XtWidgetGeometry *geom1, XtWidgetGeometry *geom2)
718 {
719 if( geom1->request_mode != geom2->request_mode )
720 return( False );
721
722 if( (geom1->request_mode & CWX && (geom1->x != geom2->x)) ||
723 (geom1->request_mode & CWY && (geom1->y != geom2->y)) ||
724 (geom1->request_mode & CWWidth && (geom1->width != geom2->width)) ||
725 (geom1->request_mode & CWHeight && (geom1->height != geom2->height)) ||
726 (geom1->request_mode & CWBorderWidth && (geom1->border_width != geom2->border_width)) ||
727 (geom1->request_mode & CWSibling && (geom1->sibling != geom2->sibling)) ||
728 (geom1->request_mode & CWStackMode && (geom1->stack_mode != geom2->stack_mode)) )
729 return( False );
730
731 return( True );
732 }
733
734 /************************************************************
735 *
736 * Static functions
737 *
738 ************************************************************/
739
740 #include <Xm/XmP.h>
741
742 /*************************************************************************/
743 /* The following code is snipped directly from OSF Motif 1.2.4 */
744 /* DEC did not compile this correctly (ALIGN_SUBCLASS_PARTS was not def- */
745 /* ined) on all versions of Motif for Digital Unix. We include it here */
746 /* to get correct behavior. */
747 /*************************************************************************/
748 /* and now there's a fix added; refer to OSF contact number 24617 for
749 ** details
750 */
751 /* And rewritten to support manual alignment. HP/UX aligns doubles to
752 ** 8 bytes, but everthing else to 4. There is NO WAY to discover at
753 ** runtime whether or not a structure contains doubles. It cannot be
754 ** done, period; thus, the OSF mechanism won't work for PA-RISC
755 ** processors. We get around that by specifying an extra flag (see
756 ** XiResolvePartOffsets64) saying "align my subpart (only) to 8
757 ** bytes". This is needed in EPak only for the XiPanner widget.
758 ** Note, this mechanism does NOT work for subclasses of 8-byte-aligned
759 ** subparts. We'd need to provide a "copy my parents offset array"
760 ** flag for that. Since EPak doesn't need it, we don't. Beware...
761 */
762
763 #define ALIGN_SUBCLASS_PARTS
764
765 #ifdef ALIGN_SUBCLASS_PARTS
766 #define _ALIGN(size) (((size) + (sizeof(double)-1)) & ~(sizeof(double)-1))
767 #else
768 #define _ALIGN(size) (size)
769 #endif
770
771 /*
772 * FIX for 5178: remove dependency on Xt private data
773 */
774 static Boolean
IsSubclassOf(WidgetClass wc,WidgetClass sc)775 IsSubclassOf(
776 WidgetClass wc,
777 WidgetClass sc)
778 {
779 WidgetClass p = wc;
780
781 _XmProcessLock();
782 for(; (p) && (p != sc); p = p->core_class.superclass);
783 _XmProcessUnlock();
784
785 return (p == sc);
786 }
787
788
789 #define XtIsConstraintClass(wc) IsSubclassOf(wc, constraintWidgetClass)
790 /*
791 * end FIX for 5178.
792 */
793
794 void
_XiResolveAllPartOffsets(WidgetClass w_class,XmOffsetPtr * offset,XmOffsetPtr * constraint_offset,Boolean align64)795 _XiResolveAllPartOffsets(
796 WidgetClass w_class,
797 XmOffsetPtr *offset,
798 XmOffsetPtr *constraint_offset,
799 Boolean align64)
800 {
801 WidgetClass c, super = w_class->core_class.superclass;
802 ConstraintWidgetClass cc = NULL, scc = NULL;
803 int i, classcount = 0;
804 XmPartResource *pr;
805
806 Boolean do_align = False;
807
808 _XmProcessLock();
809 if (sizeof(int) != sizeof(void*))
810 do_align = True;
811
812 /*
813 * Set up constraint class pointers
814 */
815 if (XtIsConstraintClass(super))
816 {
817 cc = (ConstraintWidgetClass)w_class;
818 scc = (ConstraintWidgetClass)super;
819 }
820
821 /*
822 * Update the part size value (initially, it is the size of this part)
823 */
824
825 if (do_align)
826 {
827 w_class->core_class.widget_size =
828 w_class->core_class.widget_size
829 + _ALIGN(super->core_class.widget_size);
830 w_class->core_class.widget_size =
831 _ALIGN(w_class->core_class.widget_size);
832 }
833 else
834 {
835 w_class->core_class.widget_size =
836 w_class->core_class.widget_size + super->core_class.widget_size;
837 }
838
839 /*
840 * Another nasty hack. Just plain old DON'T allow the size to be
841 * a multiple of anything smaller than 4. This causes bus errors on
842 * most platforms when the constraint record is appended (by Xt)
843 * to the widget struct. Just round up.
844 * The do_align flag above does the same thing, but only on 8 byte
845 * boundaries on 64 bit systems. All of this code desperately
846 * needs to be re-written.
847 */
848 if(w_class->core_class.widget_size & 3) {
849 int size = w_class->core_class.widget_size;
850 w_class->core_class.widget_size = 4 * ((size / 4) + 1);
851 }
852
853 if (cc && scc)
854 {
855 if (do_align)
856 {
857 cc->constraint_class.constraint_size =
858 cc->constraint_class.constraint_size
859 + _ALIGN(scc->constraint_class.constraint_size);
860 cc->constraint_class.constraint_size =
861 _ALIGN(cc->constraint_class.constraint_size);
862 }
863 else
864 cc->constraint_class.constraint_size =
865 cc->constraint_class.constraint_size +
866 scc->constraint_class.constraint_size;
867 }
868
869 /*
870 * Count the number of superclasses and allocate the offset record(s)
871 */
872 for (c = w_class; c != NULL; c = c->core_class.superclass) classcount++;
873
874 *offset = (XmOffsetPtr) XtMalloc(classcount * sizeof(XmOffset));
875 if (cc)
876 *constraint_offset = (XmOffsetPtr) XtMalloc(classcount
877 * sizeof(XmOffset));
878 else
879 if(constraint_offset != NULL) *constraint_offset = NULL;
880
881 /*
882 * Fill in the offset table(s) with the offset of all parts
883 */
884 for (i = classcount-1, c = super; i > 0; c = c->core_class.superclass, i--)
885 {
886 /*
887 * The do_align flag is true iff _all_ subparts must be 8-byte
888 * aligned (e.g. on an Alpha).
889 *
890 * align64 is true only if the _current_ widget part must be
891 * 8-byte aligned (e.g. subparts containing doubles on HP/UX)
892 */
893 if (do_align ||
894 (c == super && align64))
895 (*offset)[i] = (long)_ALIGN((c->core_class.widget_size));
896 else
897 (*offset)[i] = (long)(c->core_class.widget_size);
898 }
899
900 (*offset)[0] = 0;
901
902 if (constraint_offset != NULL && *constraint_offset != NULL) {
903 for (i = classcount-1, scc = (ConstraintWidgetClass) super; i > 0;
904 scc = (ConstraintWidgetClass)(scc->core_class.superclass), i--)
905 if (XtIsConstraintClass((WidgetClass)scc))
906 {
907 if (do_align)
908 (*constraint_offset)[i] =
909 (long)_ALIGN((scc->constraint_class.constraint_size));
910 else
911 (*constraint_offset)[i] =
912 (long)(scc->constraint_class.constraint_size);
913 }
914 else
915 (*constraint_offset)[i] = 0;
916
917 (*constraint_offset)[0] = 0;
918 }
919
920 /*
921 * Update the resource list(s) offsets in place
922 */
923 for (i = 0; i < w_class->core_class.num_resources; i++)
924 {
925 pr = (XmPartResource *) &w_class->core_class.resources[i];
926
927 /* The next line updates this in place--be careful */
928
929 w_class->core_class.resources[i].resource_offset =
930 XmGetPartOffset(pr, offset);
931 }
932
933 if (cc)
934 for (i = 0; i < cc->constraint_class.num_resources; i++)
935 {
936 pr = (XmPartResource *) &cc->constraint_class.resources[i];
937
938 /* The next line updates this in place--be careful */
939
940 cc->constraint_class.resources[i].resource_offset =
941 XmGetPartOffset(pr, constraint_offset);
942 }
943 _XmProcessUnlock();
944 }
945
946 void
XiResolveAllPartOffsets(WidgetClass w_class,XmOffsetPtr * offset,XmOffsetPtr * constraint_offset)947 XiResolveAllPartOffsets(
948 WidgetClass w_class,
949 XmOffsetPtr *offset,
950 XmOffsetPtr *constraint_offset )
951 {
952 _XiResolveAllPartOffsets( w_class, offset, constraint_offset, False );
953 }
954
955 void
XmResolveAllPartOffsets64(WidgetClass w_class,XmOffsetPtr * offset,XmOffsetPtr * constraint_offset)956 XmResolveAllPartOffsets64(
957 WidgetClass w_class,
958 XmOffsetPtr *offset,
959 XmOffsetPtr *constraint_offset )
960 {
961 #ifdef XM_ALIGN_64
962 _XiResolveAllPartOffsets( w_class, offset, constraint_offset, True );
963 #else
964 _XiResolveAllPartOffsets( w_class, offset, constraint_offset, False );
965 #endif
966 }
967
968
969 /* -------------------------------------------------------------------------- */
970
971
972
973
974 /************************************************************************
975 *
976 * The border highlighting and unhighlighting routines.
977 *
978 * These routines were originally in Primitive.c but not used anywhere.
979 *
980 ************************************************************************/
981
982 void
_XmExtHighlightBorder(Widget w)983 _XmExtHighlightBorder(Widget w )
984 {
985 XtWidgetProc border_highlight;
986 if(XmIsPrimitive(w))
987 {
988 _XmProcessLock();
989 border_highlight = xmPrimitiveClassRec.primitive_class.border_highlight;
990 _XmProcessUnlock();
991
992 (*border_highlight) (w);
993 }
994 else
995 {
996 if(XmIsGadget(w))
997 {
998 _XmProcessLock();
999 border_highlight = xmGadgetClassRec.gadget_class.border_highlight;
1000 _XmProcessUnlock();
1001
1002 (*border_highlight) (w);
1003 }
1004 }
1005 return ;
1006 }
1007
1008
1009 void
_XmExtUnhighlightBorder(Widget w)1010 _XmExtUnhighlightBorder(Widget w)
1011 {
1012 XtWidgetProc border_unhighlight;
1013
1014 if( XmIsPrimitive(w))
1015 {
1016 _XmProcessLock();
1017 border_unhighlight = xmPrimitiveClassRec.primitive_class.border_unhighlight;
1018 _XmProcessUnlock();
1019 (*border_unhighlight)(w) ;
1020 }
1021 else
1022 {
1023 if(XmIsGadget(w))
1024 {
1025 _XmProcessLock();
1026 border_unhighlight = xmGadgetClassRec.gadget_class.border_unhighlight;
1027 _XmProcessUnlock();
1028 (*border_unhighlight)(w);
1029 }
1030 }
1031 return ;
1032 }
1033