1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is the Microline Widget Library, originally made available under the NPL by Neuron Data <http://www.neurondata.com>.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * In addition, as a special exception to the GNU GPL, the copyright holders
38 * give permission to link the code of this program with the Motif and Open
39 * Motif libraries (or with modified versions of these that use the same
40 * license), and distribute linked combinations including the two. You
41 * must obey the GNU General Public License in all respects for all of
42 * the code used other than linking with Motif/Open Motif. If you modify
43 * this file, you may extend this exception to your version of the file,
44 * but you are not obligated to do so. If you do not wish to do so,
45 * delete this exception statement from your version.
47 * ***** END LICENSE BLOCK ***** */
51 #include <Xm/LabelP.h>
52 #include <Xm/DrawnBP.h>
53 #include <Xm/MessageB.h>
54 #include <Xm/Protocols.h>
55 #include <Xm/AtomMgr.h>
57 #include <Xm/VendorE.h>
59 #include <Xm/VendorS.h>
61 #include <Xm/BulletinB.h>
62 #include <Xm/MenuShell.h>
68 int fprintf(FILE *, char *, ...);
71 static void XmLDrawnBDestroyCB(Widget w
, XtPointer clientData
, XtPointer
);
72 static void XmLDrawnBDrawCB(Widget
, XtPointer
, XtPointer
);
73 static void XmLDrawnBDrawStringCB(Widget
, XtPointer
, XtPointer
);
74 static int XmLDrawCalc(Widget w
, Dimension width
, Dimension height
,
75 unsigned char alignment
, XRectangle
*rect
, XRectangle
*clipRect
,
77 static void XmLFontGetAverageWidth(XFontStruct
*fs
, short *width
);
78 static void XmLMessageBoxResponse(Widget
, XtPointer
, XtPointer
);
79 static void XmLMessageBoxWMDelete(Widget
, XtPointer
, XtPointer
);
80 static void XmLSortFunc(char *lvec
, char *rvec
);
84 char _autonumber
, _growFast
;
90 XmLArrayNew(char autonumber
,
95 array
= (XmLArray
)malloc(sizeof(struct _XmLArrayRec
));
99 array
->_autonumber
= autonumber
;
100 array
->_growFast
= growFast
;
105 XmLArrayFree(XmLArray array
)
108 free((char *)array
->_items
);
113 XmLArrayAdd(XmLArray array
,
122 if (pos
< 0 || pos
> array
->_count
)
124 if (array
->_count
+ count
>= array
->_size
)
126 if (array
->_growFast
)
129 array
->_size
= count
+ 256;
131 array
->_size
= (array
->_count
+ count
) * 2;
134 array
->_size
= array
->_count
+ count
;
135 items
= (void **)malloc(sizeof(void *) * array
->_size
);
138 for (i
= 0; i
< array
->_count
; i
++)
139 items
[i
] = array
->_items
[i
];
140 free((char *)array
->_items
);
142 array
->_items
= items
;
144 for (i
= array
->_count
+ count
- 1; i
>= pos
+ count
; i
--)
146 array
->_items
[i
] = array
->_items
[i
- count
];
147 if (array
->_autonumber
)
148 ((XmLArrayItem
*)array
->_items
[i
])->pos
= i
;
150 for (i
= pos
; i
< pos
+ count
; i
++)
151 array
->_items
[i
] = 0;
152 array
->_count
+= count
;
156 XmLArrayDel(XmLArray array
,
162 if (pos
< 0 || pos
+ count
> array
->_count
)
164 for (i
= pos
; i
< array
->_count
- count
; i
++)
166 array
->_items
[i
] = array
->_items
[i
+ count
];
167 if (array
->_autonumber
)
168 ((XmLArrayItem
*)array
->_items
[i
])->pos
= i
;
170 array
->_count
-= count
;
174 free((char *)array
->_items
);
182 XmLArraySet(XmLArray array
,
186 if (pos
< 0 || pos
>= array
->_count
)
188 if (array
->_items
[pos
])
189 fprintf(stderr
, "XmLArraySet: warning: overwriting pointer\n");
190 array
->_items
[pos
] = item
;
191 if (array
->_autonumber
)
192 ((XmLArrayItem
*)array
->_items
[pos
])->pos
= pos
;
197 XmLArrayGet(XmLArray array
,
200 if (pos
< 0 || pos
>= array
->_count
)
202 return array
->_items
[pos
];
206 XmLArrayGetCount(XmLArray array
)
208 return array
->_count
;
212 XmLArrayMove(XmLArray array
,
222 if (newPos
< 0 || newPos
+ count
> array
->_count
)
224 if (pos
< 0 || pos
+ count
> array
->_count
)
228 /* copy items to move */
229 items
= (void **)malloc(sizeof(void *) * count
);
230 for (i
= 0; i
< count
; i
++)
231 items
[i
] = array
->_items
[pos
+ i
];
232 /* move real items around */
234 for (i
= pos
+ count
- 1; i
>= newPos
+ count
; i
--)
236 array
->_items
[i
] = array
->_items
[i
- count
];
237 if (array
->_autonumber
)
238 ((XmLArrayItem
*)array
->_items
[i
])->pos
= i
;
241 for (i
= pos
; i
< newPos
; i
++)
243 array
->_items
[i
] = array
->_items
[i
+ count
];
244 if (array
->_autonumber
)
245 ((XmLArrayItem
*)array
->_items
[i
])->pos
= i
;
247 /* move items copy back */
248 for (i
= 0; i
< count
; i
++)
250 array
->_items
[newPos
+ i
] = items
[i
];
251 if (array
->_autonumber
)
252 ((XmLArrayItem
*)array
->_items
[newPos
+ i
])->pos
= newPos
+ i
;
259 XmLArrayReorder(XmLArray array
,
269 if (pos
< 0 || pos
+ count
> array
->_count
)
271 for (i
= 0; i
< count
; i
++)
273 if (newPositions
[i
] < pos
|| newPositions
[i
] >= pos
+ count
)
276 items
= (void **)malloc(sizeof(void *) * count
);
277 for (i
= 0; i
< count
; i
++)
278 items
[i
] = array
->_items
[newPositions
[i
]];
279 for (i
= 0; i
< count
; i
++)
281 array
->_items
[pos
+ i
] = items
[i
];
282 if (array
->_autonumber
)
283 ((XmLArrayItem
*)array
->_items
[pos
+ i
])->pos
= pos
+ i
;
290 XmLArraySort(XmLArray array
,
291 XmLArrayCompareFunc compare
,
298 if (pos
< 0 || pos
+ count
> array
->_count
)
300 XmLSort(&array
->_items
[pos
], count
, sizeof(void *),
301 (XmLSortCompareFunc
)compare
, userData
);
302 if (array
->_autonumber
)
303 for (i
= pos
; i
< pos
+ count
; i
++)
304 ((XmLArrayItem
*)array
->_items
[i
])->pos
= i
;
310 XmLCvtStringToUChar(Display
*dpy
,
312 XmLStringToUCharMap
*map
,
317 int i
, /*num,*/ valid
;
319 from
= (char *)fromVal
->addr
;
324 if (!strcmp(from
, map
[i
].name
))
333 XtDisplayStringConversionWarning(dpy
, from
, resname
);
340 if (toVal
->size
< sizeof(unsigned char))
342 toVal
->size
= sizeof(unsigned char);
345 *(unsigned char *)(toVal
->addr
) = map
[i
].value
;
348 toVal
->addr
= (caddr_t
)&map
[i
].value
;
349 toVal
->size
= sizeof(unsigned char);
354 XmLDateDaysInMonth(int m
,
357 static int d
[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
359 if (m
< 1 || m
> 12 || y
< 1753 || y
> 9999)
361 if (m
== 2 && (!((y
% 4) && (y
% 100)) || !(y
% 400)))
366 /* Calculation from Communications Of The ACM, Vol 6, No 8, p 444 */
367 /* sun is 0, sat is 6 */
369 XmLDateWeekDay(int m
,
375 if (m
< 1 || m
> 12 || d
< 1 || d
> XmLDateDaysInMonth(m
, y
) ||
376 y
< 1753 || y
> 9999)
387 jd
= (146097 * j1
) / 4 + (1461 * j2
) / 4 + (153 * m
+ 2) / 5 +
397 XFontStruct
*fontStruct
;
401 XmLDrawnButtonSetType(Widget w
,
406 XmDrawnButtonWidget b
;
411 Dimension width
, height
, dim
;
412 Dimension highlightThickness
, shadowThickness
;
413 Dimension marginWidth
, marginHeight
;
414 Dimension marginTop
, marginBottom
, marginLeft
, marginRight
;
416 if (!XtIsSubclass(w
, xmDrawnButtonWidgetClass
))
418 XmLWarning(w
, "DrawnButtonSetType() - not an XmDrawnButton");
422 XmNpushButtonEnabled
, True
,
424 XtRemoveAllCallbacks(w
, XmNexposeCallback
);
425 XtRemoveAllCallbacks(w
, XmNresizeCallback
);
426 if (drawnType
== XmDRAWNB_STRING
&& drawnDir
== XmDRAWNB_RIGHT
)
429 XmNlabelType
, XmSTRING
,
433 b
= (XmDrawnButtonWidget
)w
;
434 dd
= (XmLDrawnBData
*)malloc(sizeof(XmLDrawnBData
));
435 dd
->type
= drawnType
;
438 if (dd
->type
== XmDRAWNB_STRING
)
441 XmNlabelString
, &str
,
442 XmNfontList
, &fontlist
,
443 XmNhighlightThickness
, &highlightThickness
,
444 XmNshadowThickness
, &shadowThickness
,
445 XmNmarginHeight
, &marginHeight
,
446 XmNmarginWidth
, &marginWidth
,
447 XmNmarginTop
, &marginTop
,
448 XmNmarginBottom
, &marginBottom
,
449 XmNmarginLeft
, &marginLeft
,
450 XmNmarginRight
, &marginRight
,
452 if (!str
&& XtName(w
))
453 str
= XmStringCreateSimple(XtName(w
));
455 str
= XmStringCreateSimple("");
456 XmStringExtent(fontlist
, str
, &width
, &height
);
458 if (drawnDir
== XmDRAWNB_UP
|| drawnDir
== XmDRAWNB_DOWN
)
464 height
+= (highlightThickness
+ shadowThickness
+
465 marginHeight
) * 2 + marginTop
+ marginBottom
;
466 width
+= (highlightThickness
+ shadowThickness
+
467 marginWidth
) * 2 + marginLeft
+ marginRight
;
468 /* change to pixmap type so label string isnt drawn */
470 XmNlabelType
, XmPIXMAP
,
476 XtAddCallback(w
, XmNexposeCallback
, XmLDrawnBDrawStringCB
,
478 XtAddCallback(w
, XmNresizeCallback
, XmLDrawnBDrawStringCB
,
484 values
.foreground
= b
->primitive
.foreground
;
485 dd
->gc
= XtGetGC(w
, mask
, &values
);
486 XtAddCallback(w
, XmNexposeCallback
, XmLDrawnBDrawCB
, (XtPointer
)dd
);
487 XtAddCallback(w
, XmNresizeCallback
, XmLDrawnBDrawCB
, (XtPointer
)dd
);
489 XtAddCallback(w
, XmNdestroyCallback
, XmLDrawnBDestroyCB
, (XtPointer
)dd
);
493 XmLDrawnBDestroyCB(Widget w
,
494 XtPointer clientData
,
499 dd
= (XmLDrawnBData
*)clientData
;
500 if (dd
->type
== XmDRAWNB_STRING
)
504 XFreeGC(XtDisplay(w
), dd
->gc
);
505 XFreeFont(XtDisplay(w
), dd
->fontStruct
);
509 XtReleaseGC(w
, dd
->gc
);
514 XmLDrawnBDrawStringCB(Widget w
,
515 XtPointer clientData
,
521 XmStringDirection stringDir
;
522 unsigned char drawDir
, alignment
;
523 int width
, height
, xoff
, yoff
, drawWidth
;
525 Dimension highlightThickness
;
526 Dimension shadowThickness
, marginWidth
, marginHeight
;
527 Dimension marginLeft
, marginRight
, marginTop
, marginBottom
;
529 if (!XtIsRealized(w
))
531 dd
= (XmLDrawnBData
*)clientData
;
533 XmNlabelString
, &str
,
535 if (!str
&& XtName(w
))
536 str
= XmStringCreateSimple(XtName(w
));
541 XmNfontList
, &fontlist
,
542 XmNalignment
, &alignment
,
543 XmNhighlightThickness
, &highlightThickness
,
544 XmNshadowThickness
, &shadowThickness
,
545 XmNmarginWidth
, &marginWidth
,
546 XmNmarginHeight
, &marginHeight
,
547 XmNmarginLeft
, &marginLeft
,
548 XmNmarginRight
, &marginRight
,
549 XmNmarginTop
, &marginTop
,
550 XmNmarginBottom
, &marginBottom
,
552 xoff
= highlightThickness
+ shadowThickness
+ marginLeft
+ marginWidth
;
553 yoff
= highlightThickness
+ shadowThickness
+ marginTop
+ marginHeight
;
554 width
= XtWidth(w
) - xoff
- xoff
+ marginLeft
- marginRight
;
555 height
= XtHeight(w
) - yoff
- yoff
+ marginTop
- marginBottom
;
556 if (XmIsManager(XtParent(w
)))
557 XtVaGetValues(XtParent(w
),
558 XmNstringDirection
, &stringDir
,
561 stringDir
= XmSTRING_DIRECTION_L_TO_R
;
565 drawDir
= XmSTRING_LEFT
;
568 drawDir
= XmSTRING_UP
;
571 drawDir
= XmSTRING_DOWN
;
574 drawDir
= XmSTRING_RIGHT
;
577 if (drawDir
== XmSTRING_LEFT
|| drawDir
== XmSTRING_RIGHT
)
583 dd
->gc
= XCreateGC(XtDisplay(w
), XtWindow(w
), 0, NULL
);
584 dd
->fontStruct
= XLoadQueryFont(XtDisplay(w
), "fixed");
587 XmLWarning(w
, "DrawnBDrawString() - FATAL can't load fixed font");
590 XSetFont(XtDisplay(w
), dd
->gc
, dd
->fontStruct
->fid
);
592 XSetForeground(XtDisplay(w
), dd
->gc
, fg
);
593 XmLStringDrawDirection(XtDisplay(w
), XtWindow(w
), fontlist
,
594 str
, dd
->gc
, xoff
, yoff
, drawWidth
, alignment
, stringDir
, drawDir
);
599 XmLDrawnBDrawCB(Widget w
,
600 XtPointer clientData
,
604 XmDrawnButtonWidget b
;
605 /* unsigned char drawDir;*/
606 /* unsigned char alignment;*/
615 int avgx
, avgy
, xoff
, yoff
, st
;
617 if (!XtIsRealized(w
))
619 dd
= (XmLDrawnBData
*)clientData
;
623 b
= (XmDrawnButtonWidget
)w
;
626 st
= b
->primitive
.shadow_thickness
;
627 i
= st
* 2 + b
->primitive
.highlight_thickness
* 2;
628 /* calculate max dimension */
630 if (md
> ((int)XtHeight(w
) - i
))
631 md
= XtHeight(w
) - i
;
634 xoff
= ((int)XtWidth(w
) - md
) / 2;
635 yoff
= ((int)XtHeight(w
) - md
) / 2;
640 case XmDRAWNB_SMALLARROW
:
644 p
[0][1].y
= md
- md
/ 4;
645 p
[0][2].x
= md
- md
/ 4;
653 p
[0][1].y
= md
- md
/ 6;
654 p
[0][2].x
= md
- md
/ 6;
658 case XmDRAWNB_ARROWLINE
:
662 p
[0][1].y
= md
- md
/ 5;
663 p
[0][2].x
= md
- md
/ 5;
666 p
[1][0].x
= md
- md
/ 5 + 1;
668 p
[1][1].x
= md
- md
/ 5 + 1;
669 p
[1][1].y
= md
- md
/ 5;
670 p
[1][2].x
= md
- md
/ 10;
671 p
[1][2].y
= md
- md
/ 5;
672 p
[1][3].x
= md
- md
/ 10;
676 case XmDRAWNB_DOUBLEARROW
:
677 /* odd major dimensions can give jagged lines */
683 p
[0][1].y
= md
- md
/ 10;
687 p
[1][0].x
= md
- md
/ 2;
689 p
[1][1].x
= md
- md
/ 2;
690 p
[1][1].y
= md
- md
/ 10;
691 p
[1][2].x
= md
- md
/ 10;
695 case XmDRAWNB_SQUARE
:
699 p
[0][1].y
= md
- md
/ 3;
700 p
[0][2].x
= md
- md
/ 3;
701 p
[0][2].y
= md
- md
/ 3;
702 p
[0][3].x
= md
- md
/ 3;
706 case XmDRAWNB_DOUBLEBAR
:
710 p
[0][1].y
= md
- md
/ 4;
711 p
[0][2].x
= md
/ 2 - md
/ 10;
712 p
[0][2].y
= md
- md
/ 4;
713 p
[0][3].x
= md
/ 2 - md
/ 10;
716 p
[1][0].x
= md
- md
/ 3;
718 p
[1][1].x
= md
- md
/ 3;
719 p
[1][1].y
= md
- md
/ 4;
720 p
[1][2].x
= md
- md
/ 2 + md
/ 10;
721 p
[1][2].y
= md
- md
/ 4;
722 p
[1][3].x
= md
- md
/ 2 + md
/ 10;
727 for (i
= 0; i
< 2; i
++)
731 for (j
= 0; j
< np
[i
]; j
++)
736 /* points unchanged */
739 p
[i
][j
].x
= md
- p
[i
][j
].x
- 1;
743 p
[i
][j
].x
= p
[i
][j
].y
;
744 p
[i
][j
].y
= md
- temp
;
748 p
[i
][j
].x
= p
[i
][j
].y
;
761 XFillPolygon(dpy
, win
, gc
, p
[i
], np
[i
], Nonconvex
, CoordModeOrigin
);
762 p
[i
][np
[i
]].x
= p
[i
][0].x
;
763 p
[i
][np
[i
]].y
= p
[i
][0].y
;
764 for (j
= 0; j
< np
[i
]; j
++)
768 seg
.x2
= p
[i
][j
+ 1].x
;
769 seg
.y2
= p
[i
][j
+ 1].y
;
770 if ((seg
.x1
<= avgx
&& seg
.x2
<= avgx
) ||
771 (seg
.y1
<= avgy
&& seg
.y2
<= avgy
))
772 XDrawSegments(dpy
, win
,
773 b
->primitive
.bottom_shadow_GC
, &seg
, 1);
775 XDrawSegments(dpy
, win
,
776 b
->primitive
.top_shadow_GC
, &seg
, 1);
781 #define XmLDrawNODRAW 0
782 #define XmLDrawNOCLIP 1
783 #define XmLDrawCLIPPED 2
786 XmLDrawCalc(Widget w
,
789 unsigned char alignment
,
791 XRectangle
*clipRect
,
795 if (rect
->width
<= 4 || rect
->height
<= 4 ||
796 clipRect
->width
< 3 || clipRect
->height
< 3 ||
799 XmLRectIntersect(rect
, clipRect
) == XmLRectOutside
)
800 return XmLDrawNODRAW
;
801 if (alignment
== XmALIGNMENT_TOP_LEFT
||
802 alignment
== XmALIGNMENT_LEFT
||
803 alignment
== XmALIGNMENT_BOTTOM_LEFT
)
805 else if (alignment
== XmALIGNMENT_TOP
||
806 alignment
== XmALIGNMENT_CENTER
||
807 alignment
== XmALIGNMENT_BOTTOM
)
808 *x
= rect
->x
+ ((int)rect
->width
- (int)width
) / 2;
810 *x
= rect
->x
+ rect
->width
- width
- 2;
811 if (alignment
== XmALIGNMENT_TOP
||
812 alignment
== XmALIGNMENT_TOP_LEFT
||
813 alignment
== XmALIGNMENT_TOP_RIGHT
)
815 else if (alignment
== XmALIGNMENT_LEFT
||
816 alignment
== XmALIGNMENT_CENTER
||
817 alignment
== XmALIGNMENT_RIGHT
)
818 *y
= rect
->y
+ ((int)rect
->height
- (int)height
) / 2;
820 *y
= rect
->y
+ rect
->height
- height
- 2;
821 if (clipRect
->x
== rect
->x
&&
822 clipRect
->y
== rect
->y
&&
823 clipRect
->width
== rect
->width
&&
824 clipRect
->height
== rect
->height
&&
825 (int)width
+ 4 <= (int)clipRect
->width
&&
826 (int)height
+ 4 <= (int)clipRect
->height
)
827 return XmLDrawNOCLIP
;
828 return XmLDrawCLIPPED
;
832 XmLDrawToggle(Widget w
,
835 unsigned char alignment
,
837 Pixel backgroundColor
,
842 XRectangle
*clipRect
)
847 int x
, y
, cx
[3], cy
[4], drawType
;
849 drawType
= XmLDrawCalc(w
, size
, size
, alignment
, rect
, clipRect
, &x
, &y
);
850 if (size
< 3 || drawType
== XmLDrawNODRAW
)
854 if (drawType
== XmLDrawCLIPPED
)
855 XSetClipRectangles(dpy
, gc
, 0, 0, clipRect
, 1, Unsorted
);
857 XSetForeground(dpy
, gc
, backgroundColor
);
858 XFillRectangle(dpy
, win
, gc
, x
, y
, size
, size
);
860 XSetForeground(dpy
, gc
, topColor
);
862 point
[0].y
= y
+ size
- 1;
865 point
[2].x
= x
+ size
- 1;
867 XDrawLines(dpy
, win
, gc
, point
, 3, CoordModeOrigin
);
868 point
[1].x
= x
+ size
- 1;
869 point
[1].y
= y
+ size
- 1;
870 XSetForeground(dpy
, gc
, bottomColor
);
871 XDrawLines(dpy
, win
, gc
, point
, 3, CoordModeOrigin
);
876 cx
[1] = x
+ (((int)size
- 3) / 3) + 1;
877 cx
[2] = x
+ size
- 2;
879 cy
[1] = y
+ (((int)size
- 3) / 2) + 1;
880 cy
[2] = y
+ ((((int)size
- 3) * 2) / 3) + 1;
881 cy
[3] = y
+ size
- 2;
890 point
[4].x
= point
[0].x
;
891 point
[4].y
= point
[0].y
;
892 XSetForeground(dpy
, gc
, checkColor
);
893 XFillPolygon(dpy
, win
, gc
, point
, 4, Nonconvex
, CoordModeOrigin
);
894 XDrawLines(dpy
, win
, gc
, point
, 5, CoordModeOrigin
);
896 if (drawType
== XmLDrawCLIPPED
)
897 XSetClipMask(dpy
, gc
, None
);
901 XmLRectIntersect(XRectangle
*r1
,
904 if (!r1
->width
|| !r1
->height
|| !r2
->width
|| !r2
->height
)
905 return XmLRectOutside
;
906 if (r1
->x
+ (int)r1
->width
- 1 < r2
->x
||
907 r1
->x
> r2
->x
+ (int)r2
->width
- 1 ||
908 r1
->y
+ (int)r1
->height
- 1 < r2
->y
||
909 r1
->y
> r2
->y
+ (int)r2
->height
- 1)
910 return XmLRectOutside
;
911 if (r1
->x
>= r2
->x
&&
912 r1
->x
+ (int)r1
->width
<= r2
->x
+ (int)r2
->width
&&
914 r1
->y
+ (int)r1
->height
<= r2
->y
+ (int)r2
->height
)
915 return XmLRectInside
; /* r1 inside r2 */
916 return XmLRectPartial
;
921 XmLFontListCopyDefault(Widget widget
)
925 XmFontList fontList
, fl
;
928 parent
= XtParent(widget
);
932 if (XmIsVendorShell(parent
) || XmIsMenuShell(parent
))
933 XtVaGetValues(parent
, XmNdefaultFontList
, &fl
, NULL
);
934 else if (XmIsBulletinBoard(parent
))
935 XtVaGetValues(parent
, XmNbuttonFontList
, &fl
, NULL
);
938 fontList
= XmFontListCopy(fl
);
942 parent
= XtParent(parent
);
946 font
= XLoadQueryFont(XtDisplay(widget
), "fixed");
949 "FontListCopyDefault() - FATAL ERROR - can't load fixed font");
950 fontList
= XmFontListCreate(font
, XmSTRING_DEFAULT_CHARSET
);
956 XmLFontListGetDimensions(XmFontList fontList
,
959 Boolean useAverageWidth
)
961 XmStringCharSet charset
;
962 XmFontContext context
;
966 /* --- begin code to work around Motif 1.x internal bug */
968 XmFontList nextFontList
;
970 } XmFontListContextRec
;
973 XmStringCharSet unused
;
975 XmFontList nextFontList
;
980 if (XmFontListInitFontContext(&context
, fontList
))
985 /* --- begin code to work around Motif internal bug */
986 /* --- this code must be removed for Motif 2.0 */
987 nextFontList
= ((XmFontListContextRec
*)context
)->nextFontList
;
990 if (!((XmFontListRec
*)nextFontList
)->font
)
992 /* --- end Motif workaround code */
994 if (XmFontListGetNextFont(context
, &charset
, &fs
) == False
)
997 if (useAverageWidth
== True
)
998 XmLFontGetAverageWidth(fs
, &w
);
1000 w
= fs
->max_bounds
.width
;
1001 h
= fs
->max_bounds
.ascent
+ fs
->max_bounds
.descent
;
1007 XmFontListFreeFontContext(context
);
1012 XmLFontGetAverageWidth(XFontStruct
*fs
,
1021 mm
= fs
->max_char_or_byte2
- fs
->min_char_or_byte2
+ 1;
1022 for (r
= fs
->min_byte1
; r
<= fs
->max_byte1
; r
++)
1023 for (c
= fs
->min_char_or_byte2
; c
<= fs
->max_char_or_byte2
; c
++)
1027 i
= ((r
- fs
->min_byte1
) * mm
) + (c
- fs
->min_char_or_byte2
);
1028 cs
= &fs
->per_char
[i
];
1037 aw
= fs
->min_bounds
.width
;
1043 void XmLInitialize(void)
1045 static int first
= 1;
1052 fprintf(stderr
, "XmL: This is an evalation version of the Microline\n");
1053 fprintf(stderr
, "XmL: Widget Library. Some features are disabled.\n");
1059 fprintf(stderr
, "XmL: Error: This version of the library will only");
1060 fprintf(stderr
, "XmL: work with JAVA.\n");
1067 XmLMessageBox(Widget w
,
1072 Widget dialog
, shell
;
1074 XtAppContext context
;
1075 XmString str
, titleStr
;
1077 Atom WM_DELETE_WINDOW
;
1079 str
= XmStringCreateLtoR(string
, XmSTRING_DEFAULT_CHARSET
);
1080 XtSetArg(args
[0], XmNmessageString
, str
);
1081 XtSetArg(args
[1], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
);
1082 shell
= XmLShellOfWidget(w
);
1084 XtVaGetValues(shell
, XmNtitle
, &shellTitle
, NULL
);
1085 if (shell
&& shellTitle
)
1086 titleStr
= XmStringCreateLtoR(shellTitle
,
1087 XmSTRING_DEFAULT_CHARSET
);
1089 titleStr
= XmStringCreateSimple("Notice");
1090 XtSetArg(args
[2], XmNdialogTitle
, titleStr
);
1092 dialog
= XmCreateMessageDialog(XtParent(w
), "popup", args
, 3);
1094 dialog
= XmCreateQuestionDialog(XtParent(w
), "popup", args
, 3);
1095 WM_DELETE_WINDOW
= XmInternAtom(XtDisplay(w
), "WM_DELETE_WINDOW",
1097 XmAddWMProtocolCallback(shell
, WM_DELETE_WINDOW
, XmLMessageBoxWMDelete
,
1100 XmStringFree(titleStr
);
1101 XtAddCallback(dialog
, XmNokCallback
, XmLMessageBoxResponse
,
1102 (XtPointer
)&status
);
1105 XtUnmanageChild(XmMessageBoxGetChild(dialog
,
1106 XmDIALOG_CANCEL_BUTTON
));
1107 XtUnmanageChild(XmMessageBoxGetChild(dialog
,
1108 XmDIALOG_HELP_BUTTON
));
1112 XtAddCallback(dialog
, XmNcancelCallback
, XmLMessageBoxResponse
,
1113 (XtPointer
)&status
);
1114 XtAddCallback(dialog
, XmNhelpCallback
, XmLMessageBoxResponse
,
1115 (XtPointer
)&status
);
1117 XtManageChild(dialog
);
1119 context
= XtWidgetToApplicationContext(w
);
1120 while (!status
|| XtAppPending(context
))
1121 XtAppProcessEvent(context
, XtIMAll
);
1122 XtDestroyWidget(dialog
);
1127 XmLMessageBoxWMDelete(Widget w
,
1128 XtPointer clientData
,
1131 int *status
= (int *)clientData
;
1136 XmLMessageBoxResponse(Widget w
,
1137 XtPointer clientData
,
1140 int *status
= (int *)clientData
;
1141 XmAnyCallbackStruct
*reason
;
1143 reason
= (XmAnyCallbackStruct
*)callData
;
1144 switch (reason
->reason
)
1159 XmLPixmapDraw(Widget w
,
1164 unsigned char alignment
,
1167 XRectangle
*clipRect
)
1171 int px
, py
, x
, y
, width
, height
, drawType
;
1173 if (pixmap
== XmUNSPECIFIED_PIXMAP
)
1177 width
= pixmapWidth
;
1178 height
= pixmapHeight
;
1179 if (!width
|| !height
)
1181 alignment
= XmALIGNMENT_TOP_LEFT
;
1182 width
= clipRect
->width
- 4;
1183 height
= clipRect
->height
- 4;
1185 drawType
= XmLDrawCalc(w
, width
, height
, alignment
,
1186 rect
, clipRect
, &x
, &y
);
1187 if (drawType
== XmLDrawNODRAW
)
1192 if (clipRect
->y
> y
&& clipRect
->y
< y
+ height
- 1)
1194 py
= clipRect
->y
- y
;
1199 if (clipRect
->y
+ (int)clipRect
->height
- 1 >= y
&&
1200 clipRect
->y
+ (int)clipRect
->height
- 1 <= y
+ height
- 1)
1201 height
= clipRect
->y
+ clipRect
->height
- y
;
1203 if (clipRect
->x
> x
&& clipRect
->x
< x
+ width
- 1)
1205 px
= clipRect
->x
- x
;
1210 if (clipRect
->x
+ (int)clipRect
->width
- 1 >= x
&&
1211 clipRect
->x
+ (int)clipRect
->width
- 1 <= x
+ width
- 1)
1212 width
= clipRect
->x
+ clipRect
->width
- x
;
1214 if (pixmask
!= XmUNSPECIFIED_PIXMAP
)
1216 XSetClipMask(dpy
, gc
, pixmask
);
1217 XSetClipOrigin(dpy
, gc
, x
- px
, y
- py
);
1219 XSetGraphicsExposures(dpy
, gc
, False
);
1220 XCopyArea(dpy
, pixmap
, win
, gc
, px
, py
, width
, height
, x
, y
);
1221 XSetGraphicsExposures(dpy
, gc
, True
);
1222 if (pixmask
!= XmUNSPECIFIED_PIXMAP
)
1224 XSetClipMask(dpy
, gc
, None
);
1225 XSetClipOrigin(dpy
, gc
, 0, 0);
1230 XmLShellOfWidget(Widget w
)
1236 if (XtIsSubclass(w
, shellWidgetClass
))
1242 static XmLSortCompareFunc XmLSortCompare
;
1243 static int XmLSortEleSize
;
1244 static void *XmLSortUserData
;
1249 unsigned int itemSize
,
1250 XmLSortCompareFunc compare
,
1253 XmLSortCompareFunc oldCompare
;
1261 /* for sorts within a sort compare function, we must
1262 save any global sort variables on the local stack
1263 and restore them when finished */
1264 oldCompare
= XmLSortCompare
;
1265 oldEleSize
= XmLSortEleSize
;
1266 oldUserData
= XmLSortUserData
;
1267 XmLSortCompare
= compare
;
1268 XmLSortEleSize
= itemSize
;
1269 XmLSortUserData
= userData
;
1271 lvec
= (char *)base
;
1272 rvec
= lvec
+ (numItems
- 1) * itemSize
;
1273 XmLSortFunc(lvec
, rvec
);
1275 XmLSortCompare
= oldCompare
;
1276 XmLSortEleSize
= oldEleSize
;
1277 XmLSortUserData
= oldUserData
;
1280 #define SWAP(p1, p2) \
1286 for (zi = 0; zi < XmLSortEleSize; zi++) \
1289 (p1)[zi] = (p2)[zi]; \
1296 XmLSortFunc(char *lvec
,
1300 char *nlvec
, *nrvec
, *pvec
;
1303 i
= (*XmLSortCompare
)(XmLSortUserData
, lvec
, rvec
);
1306 if (rvec
== lvec
+ XmLSortEleSize
)
1313 /* find mid of three items */
1314 pvec
= lvec
+ ((rvec
- lvec
) / (XmLSortEleSize
* 2)) * XmLSortEleSize
;
1317 i
= (*XmLSortCompare
)(XmLSortUserData
, lvec
, pvec
);
1325 i
= (*XmLSortCompare
)(XmLSortUserData
, rvec
, pvec
);
1333 pvec
= lvec
+ XmLSortEleSize
;
1336 i
= (*XmLSortCompare
)(XmLSortUserData
, lvec
, pvec
);
1346 pvec
+= XmLSortEleSize
;
1350 /* partition the set */
1357 else if (pvec
== nlvec
)
1360 while ((*XmLSortCompare
)(XmLSortUserData
, nlvec
, pvec
) < 0)
1361 nlvec
+= XmLSortEleSize
;
1362 while ((*XmLSortCompare
)(XmLSortUserData
, nrvec
, pvec
) >= 0)
1363 nrvec
-= XmLSortEleSize
;
1368 /* sort partitioned sets */
1369 if (lvec
< nlvec
- XmLSortEleSize
)
1370 XmLSortFunc(lvec
, nlvec
- XmLSortEleSize
);
1379 XmLStringDraw(Widget w
,
1381 XmStringDirection stringDir
,
1382 XmFontList fontList
,
1383 unsigned char alignment
,
1386 XRectangle
*clipRect
)
1390 Dimension width
, height
;
1392 unsigned char strAlignment
;
1398 XmStringExtent(fontList
, string
, &width
, &height
);
1399 drawType
= XmLDrawCalc(w
, width
, height
, alignment
,
1400 rect
, clipRect
, &x
, &y
);
1401 if (drawType
== XmLDrawNODRAW
)
1404 if (alignment
== XmALIGNMENT_LEFT
||
1405 alignment
== XmALIGNMENT_TOP_LEFT
||
1406 alignment
== XmALIGNMENT_BOTTOM_LEFT
)
1407 strAlignment
= XmALIGNMENT_BEGINNING
;
1408 else if (alignment
== XmALIGNMENT_CENTER
||
1409 alignment
== XmALIGNMENT_TOP
||
1410 alignment
== XmALIGNMENT_BOTTOM
)
1411 if (width
<= rect
->width
- 4)
1412 strAlignment
= XmALIGNMENT_CENTER
;
1414 strAlignment
= XmALIGNMENT_BEGINNING
;
1416 strAlignment
= XmALIGNMENT_END
;
1417 /* XmStringDraw clipping doesnt work in all cases
1418 so we use a clip region for clipping */
1419 if (drawType
== XmLDrawCLIPPED
)
1420 XSetClipRectangles(dpy
, gc
, 0, 0, clipRect
, 1, Unsorted
);
1421 XmStringDraw(dpy
, win
, fontList
, string
, gc
,
1422 x
, y
, rect
->width
- 4, strAlignment
, stringDir
, clipRect
);
1423 if (drawType
== XmLDrawCLIPPED
)
1424 XSetClipMask(dpy
, gc
, None
);
1428 XmLStringDrawDirection(Display
*dpy
,
1430 XmFontList fontlist
,
1436 unsigned char alignment
,
1437 unsigned char layout_direction
,
1438 unsigned char drawing_direction
)
1441 XFontStruct
*fontStruct
;
1442 XImage
*sourceImage
, *destImage
;
1445 /* int sourceWidth, sourceHeight;*/
1446 int destWidth
, destHeight
;
1447 int stringWidth
, stringHeight
;
1448 int i
, j
, bytesPerLine
;
1452 screen
= DefaultScreenOfDisplay(dpy
);
1453 XmStringExtent(fontlist
, string
, &dW
, &dH
);
1454 stringWidth
= (int)dW
;
1455 stringHeight
= (int)dH
;
1456 if (!stringWidth
|| !stringHeight
)
1459 /* draw string into 1 bit deep pixmap */
1460 pixmap
= XCreatePixmap(dpy
, win
, stringWidth
, stringHeight
, 1);
1461 pixmapGC
= XCreateGC(dpy
, pixmap
, 0, NULL
);
1462 fontStruct
= XLoadQueryFont(dpy
, "fixed");
1465 fprintf(stderr
, "XmLStringDrawDirection: error - ");
1466 fprintf(stderr
, "can't load fixed font\n");
1469 XSetFont(dpy
, pixmapGC
, fontStruct
->fid
);
1470 XSetBackground(dpy
, pixmapGC
, 0L);
1471 XSetForeground(dpy
, pixmapGC
, 0L);
1472 XFillRectangle(dpy
, pixmap
, pixmapGC
, 0, 0, stringWidth
, stringHeight
);
1473 XSetForeground(dpy
, pixmapGC
, 1L);
1474 XmStringDraw(dpy
, pixmap
, fontlist
, string
, pixmapGC
, 0, 0, stringWidth
,
1475 XmALIGNMENT_BEGINNING
, layout_direction
, 0);
1476 XFreeFont(dpy
, fontStruct
);
1478 /* copy 1 bit deep pixmap into source image */
1479 sourceImage
= XGetImage(dpy
, pixmap
, 0, 0, stringWidth
, stringHeight
,
1481 XFreePixmap(dpy
, pixmap
);
1483 /* draw rotated text into destination image */
1484 if (drawing_direction
== XmSTRING_UP
|| drawing_direction
== XmSTRING_DOWN
)
1486 destWidth
= stringHeight
;
1487 destHeight
= stringWidth
;
1491 destWidth
= stringWidth
;
1492 destHeight
= stringHeight
;
1494 bytesPerLine
= (destWidth
- 1) / 8 + 1;
1495 data
= (char *)malloc(bytesPerLine
* destHeight
);
1496 destImage
= XCreateImage(dpy
, DefaultVisualOfScreen(screen
),
1497 1, XYBitmap
, 0, data
, destWidth
, destHeight
, 8, 0);
1498 for (i
= 0; i
< stringWidth
; i
++)
1499 for (j
= 0; j
< stringHeight
; j
++)
1501 if (drawing_direction
== XmSTRING_UP
)
1502 XPutPixel(destImage
, j
, i
,
1503 XGetPixel(sourceImage
, stringWidth
- i
- 1, j
));
1504 else if (drawing_direction
== XmSTRING_DOWN
)
1505 XPutPixel(destImage
, stringHeight
- j
- 1, stringWidth
- i
- 1,
1506 XGetPixel(sourceImage
, stringWidth
- i
- 1, j
));
1507 else if (drawing_direction
== XmSTRING_LEFT
)
1508 XPutPixel(destImage
, i
, stringHeight
- j
- 1,
1509 XGetPixel(sourceImage
, stringWidth
- i
- 1, j
));
1511 XPutPixel(destImage
, i
, j
,
1512 XGetPixel(sourceImage
, i
, j
));
1514 XDestroyImage(sourceImage
);
1516 /* copy rotated image into 1 bit deep pixmap */
1517 pixmap
= XCreatePixmap(dpy
, win
, destWidth
, destHeight
, 1);
1518 XPutImage(dpy
, pixmap
, pixmapGC
, destImage
, 0, 0, 0, 0,
1519 destWidth
, destHeight
);
1520 XDestroyImage(destImage
);
1521 XFreeGC(dpy
, pixmapGC
);
1523 /* adjust position for alignment */
1524 if (drawing_direction
== XmSTRING_UP
|| drawing_direction
== XmSTRING_DOWN
)
1526 if (alignment
== XmALIGNMENT_BEGINNING
)
1528 else if (alignment
== XmALIGNMENT_CENTER
)
1529 y
+= width
/ 2 - stringWidth
/ 2;
1530 else if (alignment
== XmALIGNMENT_END
)
1531 y
+= (int)width
- stringWidth
;
1535 if (alignment
== XmALIGNMENT_BEGINNING
)
1537 else if (alignment
== XmALIGNMENT_CENTER
)
1538 x
+= width
/ 2 - stringWidth
/ 2;
1539 else if (alignment
== XmALIGNMENT_END
)
1540 x
+= (int)width
- stringWidth
;
1543 /* draw the pixmap as a stipple in the window */
1544 XSetStipple(dpy
, gc
, pixmap
);
1545 XSetFillStyle(dpy
, gc
, FillStippled
);
1546 XSetTSOrigin(dpy
, gc
, x
% destWidth
, y
% destHeight
);
1547 XFillRectangle(dpy
, win
, gc
, x
, y
, destWidth
, destHeight
);
1548 XFreePixmap(dpy
, pixmap
);
1549 XSetFillStyle(dpy
, gc
, FillSolid
);
1553 XmLWarning(Widget w
,
1557 char s
[512], *cname
, *name
;
1560 app
= XtWidgetToApplicationContext(w
);
1565 cname
= c
->core_class
.class_name
;
1567 cname
= "[No Class]";
1568 sprintf(s
, "%s: %s: %s\n", cname
, name
, msg
);
1569 XtAppWarning(app
, s
);